diff options
1342 files changed, 132813 insertions, 2583 deletions
diff --git a/.gitignore b/.gitignore index 2ad104214e..faec15b3de 100644 --- a/.gitignore +++ b/.gitignore @@ -196,3 +196,10 @@ ScummVM.includes #Ignore MS Visual C++ temporary files/subdirectories (except create_project.bat) dists/msvc*/** !dists/msvc*/create_project.bat + +#Ignore bison debug output +*.output + +#Ignore Xcode output/project files +out/ +scummvm.xcodeproj diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..0c88ec8f24 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,39 @@ +language: + - cpp + +sudo: false + +addons: + apt: + packages: + - g++ make + - libsdl1.2-dev + - libjpeg62-turbo-dev + - libmpeg2-4-dev + - libogg-dev + - libvorbis-dev + - libflac-dev + - libmad0-dev + - libpng-dev + - libtheora-dev + - libfaad-dev + - libfluidsynth-dev + - libfreetype6-dev + - zlib1g-dev + +branches: + only: + - master + +compiler: + - gcc + - clang + +os: + - linux + +script: + - ./configure --enable-all-engines + - make -j 2 + - make test + - make devtools @@ -26,6 +26,15 @@ For a more comprehensive changelog of the latest experimental code, see: Gob: - Fixed graphical issues in Gobliiins (EGA version). + Kyra: + - Updated Italian EOB1 translation. + + Mohawk: + - Fixed visual glitches in the Spanish version of Myst. + - Changed the cancel button in the options dialog of Riven not to save the settings. + - Riven savegames created by ScummVM are now loadable in the original game. + - Fixed missing mouse cursor in Myst after loading a savegame while the intro is playing. + SCI: - Fixed a missing dialog line in QfG3 which awards the player with 3 additional points. This is a bug in the original game interpreter. Due to this bug, @@ -35,8 +44,7 @@ For a more comprehensive changelog of the latest experimental code, see: interacting with the armor in room 37 (main house, downstairs). This bug is also present in the original game. - Fixed auto-saving in the fan-made Cascade Quest. - - Fixed a bug in Conquests of the Longbow: The Adventures of Robin Hood that caused - the game to crash while wandering through the Sherwood Forest. + - Fixed a game bug in the Conquests of Longbow scripts that could cause crashes in Sherwood Forest. - Added a detection entry for the ImagiNation Network (INN) demo. SCUMM: @@ -45,16 +53,12 @@ For a more comprehensive changelog of the latest experimental code, see: in Green Tentacle's room turned on. - Improved timing and pathfinding in Maniac Mansion (C64 and Apple II versions) - Mohawk: - - Fixed visual glitches in the Spanish version of Myst. - - Changed the cancel button in the options dialog of Riven not to save the settings. - - Riven savegames created by ScummVM are now loadable in the original game. - WAGE: - Closed memory leak. Windows port: - Fixed taskbar support on Windows 10 onwards. + - Fixed keymapping for non-QWERTY keyboards. 1.8.1 (2016-05-25) New ports: @@ -1929,4 +1933,3 @@ For a more comprehensive changelog of the latest experimental code, see: 0.0.1 (2001-10-08) - Initial version. - diff --git a/audio/decoders/qdm2.cpp b/audio/decoders/qdm2.cpp index 97d73b3a03..a2f4326152 100644 --- a/audio/decoders/qdm2.cpp +++ b/audio/decoders/qdm2.cpp @@ -1498,7 +1498,7 @@ void QDM2Stream::fill_coding_method_array(sb_int8_array tone_level_idx, sb_int8_ return; if (!superblocktype_2_3) { warning("QDM2 This case is untested, no samples available"); - for (ch = 0; ch < nb_channels; ch++) + for (ch = 0; ch < nb_channels; ch++) { for (sb = 0; sb < 30; sb++) { for (j = 1; j < 63; j++) { // The loop only iterates to 63 so the code doesn't overflow the buffer add1 = tone_level_idx[ch][sb][j] - 10; @@ -1527,67 +1527,73 @@ void QDM2Stream::fill_coding_method_array(sb_int8_array tone_level_idx, sb_int8_ } tone_level_idx_temp[ch][sb][0] = tone_level_idx_temp[ch][sb][1]; } - acc = 0; - for (ch = 0; ch < nb_channels; ch++) - for (sb = 0; sb < 30; sb++) - for (j = 0; j < 64; j++) - acc += tone_level_idx_temp[ch][sb][j]; - - multres = 0x66666667 * (acc * 10); - esp_40 = (multres >> 32) / 8 + ((multres & 0xffffffff) >> 31); - for (ch = 0; ch < nb_channels; ch++) - for (sb = 0; sb < 30; sb++) - for (j = 0; j < 64; j++) { - comp = tone_level_idx_temp[ch][sb][j]* esp_40 * 10; - if (comp < 0) - comp += 0xff; - comp /= 256; // signed shift - switch(sb) { - case 0: - if (comp < 30) - comp = 30; - comp += 15; - break; - case 1: - if (comp < 24) - comp = 24; - comp += 10; - break; - case 2: - case 3: - case 4: - if (comp < 16) - comp = 16; - } - if (comp <= 5) - tmp = 0; - else if (comp <= 10) - tmp = 10; - else if (comp <= 16) - tmp = 16; - else if (comp <= 24) - tmp = -1; - else - tmp = 0; - coding_method[ch][sb][j] = ((tmp & 0xfffa) + 30 )& 0xff; - } + } + acc = 0; + for (ch = 0; ch < nb_channels; ch++) for (sb = 0; sb < 30; sb++) - fix_coding_method_array(sb, nb_channels, coding_method); - for (ch = 0; ch < nb_channels; ch++) - for (sb = 0; sb < 30; sb++) - for (j = 0; j < 64; j++) - if (sb >= 10) { - if (coding_method[ch][sb][j] < 10) - coding_method[ch][sb][j] = 10; + for (j = 0; j < 64; j++) + acc += tone_level_idx_temp[ch][sb][j]; + + multres = 0x66666667 * (acc * 10); + esp_40 = (multres >> 32) / 8 + ((multres & 0xffffffff) >> 31); + for (ch = 0; ch < nb_channels; ch++) { + for (sb = 0; sb < 30; sb++) { + for (j = 0; j < 64; j++) { + comp = tone_level_idx_temp[ch][sb][j]* esp_40 * 10; + if (comp < 0) + comp += 0xff; + comp /= 256; // signed shift + switch(sb) { + case 0: + if (comp < 30) + comp = 30; + comp += 15; + break; + case 1: + if (comp < 24) + comp = 24; + comp += 10; + break; + case 2: + case 3: + case 4: + if (comp < 16) + comp = 16; + } + if (comp <= 5) + tmp = 0; + else if (comp <= 10) + tmp = 10; + else if (comp <= 16) + tmp = 16; + else if (comp <= 24) + tmp = -1; + else + tmp = 0; + coding_method[ch][sb][j] = ((tmp & 0xfffa) + 30 )& 0xff; + } + } + } + for (sb = 0; sb < 30; sb++) + fix_coding_method_array(sb, nb_channels, coding_method); + for (ch = 0; ch < nb_channels; ch++) { + for (sb = 0; sb < 30; sb++) { + for (j = 0; j < 64; j++) { + if (sb >= 10) { + if (coding_method[ch][sb][j] < 10) + coding_method[ch][sb][j] = 10; + } else { + if (sb >= 2) { + if (coding_method[ch][sb][j] < 16) + coding_method[ch][sb][j] = 16; } else { - if (sb >= 2) { - if (coding_method[ch][sb][j] < 16) - coding_method[ch][sb][j] = 16; - } else { - if (coding_method[ch][sb][j] < 30) - coding_method[ch][sb][j] = 30; - } + if (coding_method[ch][sb][j] < 30) + coding_method[ch][sb][j] = 30; } + } + } + } + } } else { // superblocktype_2_3 != 0 for (ch = 0; ch < nb_channels; ch++) for (sb = 0; sb < 30; sb++) @@ -1658,8 +1664,8 @@ void QDM2Stream::synthfilt_build_sb_samples(Common::BitStream *gb, int length, i if ((length - gb->pos()) >= 10) { if (zero_encoding) { for (k = 0; k < 5; k++) { - if ((j + 2 * k) >= 128) - break; + if ((j + 2 * k) >= 128) + break; samples[2 * k] = gb->getBit() ? dequant_1bit[joined_stereo][2 * gb->getBit()] : 0; } } else { diff --git a/audio/decoders/wave.h b/audio/decoders/wave.h index a7fb76978c..aaf4a01a3f 100644 --- a/audio/decoders/wave.h +++ b/audio/decoders/wave.h @@ -38,6 +38,7 @@ * - sherlock * - sword1 * - sword2 + * - titanic * - tony * - tucker * - wintermute diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp index 00e2f25cbc..acc1ff5dce 100644 --- a/backends/events/sdl/sdl-events.cpp +++ b/backends/events/sdl/sdl-events.cpp @@ -517,15 +517,17 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) { SDLModToOSystemKeyFlags(SDL_GetModState(), event); + SDLKey sdlKeycode = obtainKeycode(ev.key.keysym); + // Handle scroll lock as a key modifier - if (ev.key.keysym.sym == SDLK_SCROLLOCK) + if (sdlKeycode == SDLK_SCROLLOCK) _scrollLock = !_scrollLock; if (_scrollLock) event.kbd.flags |= Common::KBD_SCRL; // Ctrl-m toggles mouse capture - if (event.kbd.hasFlags(Common::KBD_CTRL) && ev.key.keysym.sym == 'm') { + if (event.kbd.hasFlags(Common::KBD_CTRL) && sdlKeycode == 'm') { if (_graphicsManager) { _graphicsManager->getWindow()->toggleMouseGrab(); } @@ -534,26 +536,26 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) { #if defined(MACOSX) // On Macintosh, Cmd-Q quits - if ((ev.key.keysym.mod & KMOD_META) && ev.key.keysym.sym == 'q') { + if ((ev.key.keysym.mod & KMOD_META) && sdlKeycode == 'q') { event.type = Common::EVENT_QUIT; return true; } #elif defined(POSIX) // On other *nix systems, Control-Q quits - if ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym == 'q') { + if ((ev.key.keysym.mod & KMOD_CTRL) && sdlKeycode == 'q') { event.type = Common::EVENT_QUIT; return true; } #else // Ctrl-z quits - if ((event.kbd.hasFlags(Common::KBD_CTRL) && ev.key.keysym.sym == 'z')) { + if ((event.kbd.hasFlags(Common::KBD_CTRL) && sdlKeycode == 'z')) { event.type = Common::EVENT_QUIT; return true; } #ifdef WIN32 // On Windows, also use the default Alt-F4 quit combination - if ((ev.key.keysym.mod & KMOD_ALT) && ev.key.keysym.sym == SDLK_F4) { + if ((ev.key.keysym.mod & KMOD_ALT) && sdlKeycode == SDLK_F4) { event.type = Common::EVENT_QUIT; return true; } @@ -561,7 +563,7 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) { #endif // Ctrl-u toggles mute - if ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym == 'u') { + if ((ev.key.keysym.mod & KMOD_CTRL) && sdlKeycode == 'u') { event.type = Common::EVENT_MUTE; return true; } @@ -570,8 +572,8 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) { return true; event.type = Common::EVENT_KEYDOWN; - event.kbd.keycode = SDLToOSystemKeycode(ev.key.keysym.sym); - event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, obtainUnicode(ev.key.keysym)); + event.kbd.keycode = SDLToOSystemKeycode(sdlKeycode); + event.kbd.ascii = mapKey(sdlKeycode, (SDLMod)ev.key.keysym.mod, obtainUnicode(ev.key.keysym)); return true; } @@ -580,6 +582,7 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) { if (remapKey(ev, event)) return true; + SDLKey sdlKeycode = obtainKeycode(ev.key.keysym); SDLMod mod = SDL_GetModState(); // Check if this is an event handled by handleKeyDown(), and stop if it is @@ -587,21 +590,21 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) { // Check if the Ctrl key is down, so that we can trap cases where the // user has the Ctrl key down, and has just released a special key if (mod & KMOD_CTRL) { - if (ev.key.keysym.sym == 'm' || // Ctrl-m toggles mouse capture + if (sdlKeycode == 'm' || // Ctrl-m toggles mouse capture #if defined(MACOSX) // Meta - Q, handled below #elif defined(POSIX) - ev.key.keysym.sym == 'q' || // On other *nix systems, Control-Q quits + sdlKeycode == 'q' || // On other *nix systems, Control-Q quits #else - ev.key.keysym.sym == 'z' || // Ctrl-z quit + sdlKeycode == 'z' || // Ctrl-z quit #endif - ev.key.keysym.sym == 'u') // Ctrl-u toggles mute + sdlKeycode == 'u') // Ctrl-u toggles mute return false; } // Same for other keys (Meta and Alt) #if defined(MACOSX) - if ((mod & KMOD_META) && ev.key.keysym.sym == 'q') + if ((mod & KMOD_META) && sdlKeycode == 'q') return false; // On Macintosh, Cmd-Q quits #endif @@ -609,8 +612,8 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) { // continue normally event.type = Common::EVENT_KEYUP; - event.kbd.keycode = SDLToOSystemKeycode(ev.key.keysym.sym); - event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, 0); + event.kbd.keycode = SDLToOSystemKeycode(sdlKeycode); + event.kbd.ascii = mapKey(sdlKeycode, (SDLMod)ev.key.keysym.mod, 0); // Ctrl-Alt-<key> will change the GFX mode SDLModToOSystemKeyFlags(mod, event); @@ -868,6 +871,44 @@ bool SdlEventSource::handleResizeEvent(Common::Event &event, int w, int h) { return false; } +SDLKey SdlEventSource::obtainKeycode(const SDL_keysym keySym) { +#if !SDL_VERSION_ATLEAST(2, 0, 0) && defined(WIN32) && !defined(_WIN32_WCE) + // WORKAROUND: SDL 1.2 on Windows does not use the user configured keyboard layout, + // resulting in "keySym.sym" values to always be those expected for an US keyboard. + // For example, SDL returns SDLK_Q when pressing the 'A' key on an AZERTY keyboard. + // This defeats the purpose of keycodes which is to be able to refer to a key without + // knowing where it is physically located. + // We work around this issue by querying the currently active Windows keyboard layout + // using the scancode provided by SDL. + + if (keySym.sym >= SDLK_0 && keySym.sym <= SDLK_9) { + // The keycode returned by SDL is kept for the number keys. + // Querying the keyboard layout for those would return the base key values + // for AZERTY keyboards, which are not numbers. For example, SDLK_1 would + // map to SDLK_AMPERSAND. This is theoretically correct but practically unhelpful, + // because it makes it impossible to handle key combinations such as "ctrl-1". + return keySym.sym; + } + + int vk = MapVirtualKey(keySym.scancode, MAPVK_VSC_TO_VK); + if (vk) { + int ch = (MapVirtualKey(vk, MAPVK_VK_TO_CHAR) & 0x7FFF); + // The top bit of the result of MapVirtualKey with MAPVK_VSC_TO_VK signals + // a dead key was pressed. In that case we keep the value of the accent alone. + if (ch) { + if (ch >= 'A' && ch <= 'Z') { + // Windows returns uppercase ASCII whereas SDL expects lowercase + return (SDLKey)(SDLK_a + (ch - 'A')); + } else { + return (SDLKey)ch; + } + } + } +#endif + + return keySym.sym; +} + uint32 SdlEventSource::obtainUnicode(const SDL_keysym keySym) { #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_Event events[2]; diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h index caa60c1354..7e590aed3c 100644 --- a/backends/events/sdl/sdl-events.h +++ b/backends/events/sdl/sdl-events.h @@ -148,6 +148,11 @@ protected: */ uint32 obtainUnicode(const SDL_keysym keySym); + /** + * Extracts the keycode for the specified key sym. + */ + SDLKey obtainKeycode(const SDL_keysym keySym); + #if SDL_VERSION_ATLEAST(2, 0, 0) /** * Whether _fakeKeyUp contains an event we need to send. diff --git a/backends/platform/dc/vmsave.cpp b/backends/platform/dc/vmsave.cpp index 75fc1ed0df..d896ba1299 100644 --- a/backends/platform/dc/vmsave.cpp +++ b/backends/platform/dc/vmsave.cpp @@ -269,15 +269,16 @@ public: class OutVMSave : public Common::OutSaveFile { private: char *buffer; - int pos, size, committed; + int _pos, size, committed; char filename[16]; bool iofailed; public: uint32 write(const void *buf, uint32 cnt); + virtual int32 pos() const { return _pos; } OutVMSave(const char *_filename) - : pos(0), committed(-1), iofailed(false) + : _pos(0), committed(-1), iofailed(false) { strncpy(filename, _filename, 16); buffer = new char[size = MAX_SAVE_SIZE]; @@ -320,14 +321,14 @@ void OutVMSave::finalize() extern const char *gGameName; extern Icon icon; - if (committed >= pos) + if (committed >= _pos) return; char *data = buffer; - int len = pos; + int len = _pos; vmsaveResult r = writeSaveGame(gGameName, data, len, filename, icon); - committed = pos; + committed = _pos; if (r != VMSAVE_OK) iofailed = true; displaySaveResult(r); @@ -386,13 +387,13 @@ bool InVMSave::seek(int32 offs, int whence) uint32 OutVMSave::write(const void *buf, uint32 cnt) { int nbyt = cnt; - if (pos + nbyt > size) { - cnt = (size - pos); + if (_pos + nbyt > size) { + cnt = (size - _pos); nbyt = cnt; } if (nbyt) - memcpy(buffer + pos, buf, nbyt); - pos += nbyt; + memcpy(buffer + _pos, buf, nbyt); + _pos += nbyt; return cnt; } diff --git a/backends/platform/n64/framfs_save_manager.h b/backends/platform/n64/framfs_save_manager.h index a066854aab..9bd4ee579e 100644 --- a/backends/platform/n64/framfs_save_manager.h +++ b/backends/platform/n64/framfs_save_manager.h @@ -71,6 +71,9 @@ private: public: uint32 write(const void *buf, uint32 cnt); + virtual int32 pos() const { + return framfs_tell(fd); + } OutFRAMSave(const char *_filename) : fd(NULL) { fd = framfs_open(_filename, "w"); diff --git a/backends/platform/n64/pakfs_save_manager.h b/backends/platform/n64/pakfs_save_manager.h index ec66c80b73..0c08f0c506 100644 --- a/backends/platform/n64/pakfs_save_manager.h +++ b/backends/platform/n64/pakfs_save_manager.h @@ -72,6 +72,10 @@ private: public: uint32 write(const void *buf, uint32 cnt); + virtual int32 pos() const { + return pakfs_tell(fd); + } + OutPAKSave(const char *_filename) : fd(NULL) { fd = pakfs_open(_filename, "w"); } diff --git a/backends/platform/sdl/posix/posix.cpp b/backends/platform/sdl/posix/posix.cpp index e2a642b288..0d5f39736a 100644 --- a/backends/platform/sdl/posix/posix.cpp +++ b/backends/platform/sdl/posix/posix.cpp @@ -141,6 +141,24 @@ Common::String OSystem_POSIX::getDefaultConfigFileName() { return configFile; } +void OSystem_POSIX::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { +#ifdef DATA_PATH + const char *snap = getenv("SNAP"); + if (snap) { + Common::String dataPath = Common::String(snap) + DATA_PATH; + Common::FSNode dataNode(dataPath); + if (dataNode.exists() && dataNode.isDirectory()) { + // This is the same priority which is used for the data path (below), + // but we insert this one first, so it will be searched first. + s.add(dataPath, new Common::FSDirectory(dataNode, 4), priority); + } + } +#endif + + // For now, we always add the data path, just in case SNAP doesn't make sense. + OSystem_SDL::addSysArchivesToSearchSet(s, priority); +} + Common::WriteStream *OSystem_POSIX::createLogFile() { // Start out by resetting _logFilePath, so that in case // of a failure, we know that no log file is open. diff --git a/backends/platform/sdl/posix/posix.h b/backends/platform/sdl/posix/posix.h index 0514d30191..050463c273 100644 --- a/backends/platform/sdl/posix/posix.h +++ b/backends/platform/sdl/posix/posix.h @@ -38,6 +38,8 @@ public: virtual void init(); virtual void initBackend(); + virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0); + protected: /** * Base string for creating the default path and filename for the diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index c55753194b..dca6891fef 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -492,6 +492,14 @@ AudioCDManager *OSystem_SDL::createAudioCDManager() { #endif } +Common::SaveFileManager *OSystem_SDL::getSavefileManager() { +#ifdef ENABLE_EVENTRECORDER + return g_eventRec.getSaveManager(_savefileManager); +#else + return _savefileManager; +#endif +} + #ifdef USE_OPENGL const OSystem::GraphicsMode *OSystem_SDL::getSupportedGraphicsModes() const { diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index c93c8308a7..1fe670c5c3 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -76,6 +76,7 @@ public: virtual void getTimeAndDate(TimeDate &td) const; virtual Audio::Mixer *getMixer(); virtual Common::TimerManager *getTimerManager(); + virtual Common::SaveFileManager *getSavefileManager(); protected: bool _inited; diff --git a/common/file.cpp b/common/file.cpp index 16e6a0df1a..4d9c630076 100644 --- a/common/file.cpp +++ b/common/file.cpp @@ -202,4 +202,6 @@ bool DumpFile::flush() { return _handle->flush(); } +int32 DumpFile::pos() const { return _handle->pos(); } + } // End of namespace Common diff --git a/common/file.h b/common/file.h index c055acc57d..3d174834e9 100644 --- a/common/file.h +++ b/common/file.h @@ -161,6 +161,8 @@ public: virtual uint32 write(const void *dataPtr, uint32 dataSize); virtual bool flush(); + + virtual int32 pos() const; }; } // End of namespace Common diff --git a/common/gui_options.h b/common/gui_options.h index ec3eccd161..d17f45cac1 100644 --- a/common/gui_options.h +++ b/common/gui_options.h @@ -68,7 +68,7 @@ #define GUIO_GAMEOPTIONS6 "\055" #define GUIO_GAMEOPTIONS7 "\056" #define GUIO_GAMEOPTIONS8 "\057" -#define GUIO_GAMEOPTIONS9 "\058" +#define GUIO_GAMEOPTIONS9 "\060" #define GUIO0() (GUIO_NONE) #define GUIO1(a) (a) diff --git a/common/memstream.h b/common/memstream.h index 94407f5cc9..59d5f15b1a 100644 --- a/common/memstream.h +++ b/common/memstream.h @@ -111,7 +111,7 @@ public: return dataSize; } - uint32 pos() const { return _pos; } + int32 pos() const { return _pos; } uint32 size() const { return _bufSize; } virtual bool err() const { return _err; } @@ -201,7 +201,7 @@ public: return dataSize; } - uint32 pos() const { return _pos; } + int32 pos() const { return _pos; } uint32 size() const { return _size; } byte *getData() { return _data; } diff --git a/common/recorderfile.cpp b/common/recorderfile.cpp index 04802aa0c8..71f8272b44 100644 --- a/common/recorderfile.cpp +++ b/common/recorderfile.cpp @@ -30,8 +30,6 @@ #include "graphics/surface.h" #include "graphics/scaler.h" -#ifdef ENABLE_EVENTRECORDER - #define RECORD_VERSION 1 namespace Common { @@ -716,5 +714,3 @@ void PlaybackFile::checkRecordedMD5() { } - -#endif // ENABLE_EVENTRECORDER diff --git a/common/scummsys.h b/common/scummsys.h index eb5ff24a42..959c67a404 100644 --- a/common/scummsys.h +++ b/common/scummsys.h @@ -219,10 +219,6 @@ #include "config.h" #endif -// Now we need to adjust some settings when running tests -#ifdef COMPILING_TESTS -#undef ENABLE_EVENTRECORDER -#endif // In the following we configure various targets, in particular those // which can't use our "configure" tool and hence don't use config.h. diff --git a/common/stream.cpp b/common/stream.cpp index 45060b9db5..a8446a9086 100644 --- a/common/stream.cpp +++ b/common/stream.cpp @@ -500,6 +500,8 @@ public: virtual bool flush() { return flushBuffer(); } + virtual int32 pos() const { return _pos; } + }; } // End of anonymous namespace diff --git a/common/stream.h b/common/stream.h index abe5192b70..c6c300fa97 100644 --- a/common/stream.h +++ b/common/stream.h @@ -103,6 +103,14 @@ public: flush(); } + /** + * Obtains the current value of the stream position indicator of the + * stream. + * + * @return the current position indicator, or -1 if an error occurred. + */ + virtual int32 pos() const = 0; + // The remaining methods all have default implementations; subclasses // need not (and should not) overload them. diff --git a/common/system.cpp b/common/system.cpp index 53f28cafa1..131a7d2580 100644 --- a/common/system.cpp +++ b/common/system.cpp @@ -30,9 +30,6 @@ #include "common/taskbar.h" #include "common/updates.h" #include "common/textconsole.h" -#ifdef ENABLE_EVENTRECORDER -#include "gui/EventRecorder.h" -#endif #include "backends/audiocd/default/default-audiocd.h" #include "backends/fs/fs-factory.h" @@ -161,9 +158,5 @@ Common::TimerManager *OSystem::getTimerManager() { } Common::SaveFileManager *OSystem::getSavefileManager() { -#ifdef ENABLE_EVENTRECORDER - return g_eventRec.getSaveManager(_savefileManager); -#else return _savefileManager; -#endif } diff --git a/common/system.h b/common/system.h index 8896554f76..6d185d3075 100644 --- a/common/system.h +++ b/common/system.h @@ -1090,7 +1090,7 @@ public: * and other modifiable persistent game data. For more information, * refer to the SaveFileManager documentation. */ - Common::SaveFileManager *getSavefileManager(); + virtual Common::SaveFileManager *getSavefileManager(); #if defined(USE_TASKBAR) /** diff --git a/common/util.cpp b/common/util.cpp index 8e0a2fd61f..62a1baf6ac 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -28,6 +28,7 @@ #define FORBIDDEN_SYMBOL_EXCEPTION_isspace #define FORBIDDEN_SYMBOL_EXCEPTION_isupper #define FORBIDDEN_SYMBOL_EXCEPTION_isprint +#define FORBIDDEN_SYMBOL_EXCEPTION_ispunct #include "common/util.h" @@ -150,4 +151,10 @@ bool isPrint(int c) { ENSURE_ASCII_CHAR(c); return isprint((byte)c); } + +bool isPunct(int c) { + ENSURE_ASCII_CHAR(c); + return ispunct((byte)c); +} + } // End of namespace Common diff --git a/common/util.h b/common/util.h index f51aa00925..1f635f3654 100644 --- a/common/util.h +++ b/common/util.h @@ -177,6 +177,17 @@ bool isUpper(int c); * @return true if the character is printable, false otherwise. */ bool isPrint(int c); + + +/** + * Test whether the given character is a punctuation character, + * (i.e not alphanumeric. + * + * @param c the character to test + * @return true if the character is punctuation, false otherwise. + */ +bool isPunct(int c); + } // End of namespace Common #endif diff --git a/common/zlib.cpp b/common/zlib.cpp index c22ea1e660..39130beb4e 100644 --- a/common/zlib.cpp +++ b/common/zlib.cpp @@ -316,6 +316,7 @@ protected: ScopedPtr<WriteStream> _wrapped; z_stream _stream; int _zlibErr; + uint32 _pos; void processData(int flushType) { // This function is called by both write() and finalize(). @@ -333,7 +334,7 @@ protected: } public: - GZipWriteStream(WriteStream *w) : _wrapped(w), _stream() { + GZipWriteStream(WriteStream *w) : _wrapped(w), _stream(), _pos(0) { assert(w != 0); // Adding 16 to windowBits indicates to zlib that it is supposed to @@ -403,8 +404,11 @@ public: // ... and flush it to disk processData(Z_NO_FLUSH); + _pos += dataSize - _stream.avail_in; return dataSize - _stream.avail_in; } + + virtual int32 pos() const { return _pos; } }; #endif // USE_ZLIB diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp index 294eadf92b..b2461a74bb 100644 --- a/devtools/create_kyradat/create_kyradat.cpp +++ b/devtools/create_kyradat/create_kyradat.cpp @@ -45,7 +45,7 @@ enum { - kKyraDatVersion = 88 + kKyraDatVersion = 89 }; const ExtractFilename extractFilenames[] = { diff --git a/devtools/create_kyradat/resources/eob1_dos_italian.h b/devtools/create_kyradat/resources/eob1_dos_italian.h index 680e197b57..2f6baf561e 100644 --- a/devtools/create_kyradat/resources/eob1_dos_italian.h +++ b/devtools/create_kyradat/resources/eob1_dos_italian.h @@ -95,10 +95,10 @@ static const char *const kEoB1ChargenAlignmentStringsDOSItalian[9] = { "CAOTICO BUONO", "LEGALE NEUTRALE", "NEUTRALE PURO", - "CAOTICO NEUT.", + "CAOTICO NEUTRALE", "LEGALE MALVAGIO", - "NEUTRALE MALV.", - "CAOTICO MALV." + "NEUTRALE MALVAGIO", + "CAOTICO MALVAGIO" }; static const StringListProvider kEoB1ChargenAlignmentStringsDOSItalianProvider = { ARRAYSIZE(kEoB1ChargenAlignmentStringsDOSItalian), kEoB1ChargenAlignmentStringsDOSItalian }; @@ -285,7 +285,7 @@ static const char *const kEoB1MagicObjectStringsDOSItalian[5] = { "Pergamena del Chierico", "Anello", "Pozione", - "bacchetta" + "Bacchetta" }; static const StringListProvider kEoB1MagicObjectStringsDOSItalianProvider = { ARRAYSIZE(kEoB1MagicObjectStringsDOSItalian), kEoB1MagicObjectStringsDOSItalian }; @@ -573,7 +573,7 @@ static const StringListProvider kEoB1CharGuiStringsWp1DOSItalianProvider = { ARR static const char *const kEoB1CharGuiStringsWrDOSItalian[4] = { "FUORI", - "PORTATA", + "TIRO", "NESSUNA", "MUNIZIONE" }; @@ -592,7 +592,7 @@ static const char *const kEoB1CharGuiStringsSt1DOSItalian[6] = { static const StringListProvider kEoB1CharGuiStringsSt1DOSItalianProvider = { ARRAYSIZE(kEoB1CharGuiStringsSt1DOSItalian), kEoB1CharGuiStringsSt1DOSItalian }; static const char *const kEoB1CharGuiStringsInDOSItalian[4] = { - "INFO PERSONAGGIO", + "INFO EROE", "CLASSE ARMATURA", "ESP", "LIV" @@ -674,12 +674,12 @@ static const StringListProvider kEoB1MageSpellsListDOSItalianProvider = { ARRAYS static const char *const kEoB1ClericSpellsListDOSItalian[25] = { "", "Benedizione", - "Cura Fer.L.", - "Causa Fer.L.", + "Cura Ferite L.", + "Causa Ferite L.", "Individua Magico", - "Protez.Male", + "Protezione dal Male", "Aiuto", - "Lama Fiammegg.", + "Lama Fiammeggiante", "Blocca Persone", "Rallenta Veleno", "Creare Cibo", @@ -687,13 +687,13 @@ static const char *const kEoB1ClericSpellsListDOSItalian[25] = { "Paramenti Magici", "Preghiera", "Rimuovi Paralisi", - "Cura Fer.G.", - "Causa Fer.G.", - "Neutral.Veleni", - "Protez.Male 3m", - "Protez.Fulmine", - "Cura Fer.C.", - "Causa Fer.C.", + "Cura Ferite G.", + "Causa Ferite G.", + "Neutralizza Veleni", + "Protezione Male 3m", + "Protezione Fulmine", + "Cura Ferite C.", + "Causa Ferite C.", "Colonna di Fuoco", "Rianimare Morti", "Imposizione Mani" diff --git a/devtools/create_project/cmake.cpp b/devtools/create_project/cmake.cpp index 53450d1997..1423e686be 100644 --- a/devtools/create_project/cmake.cpp +++ b/devtools/create_project/cmake.cpp @@ -26,6 +26,7 @@ #include <algorithm> #include <cstring> #include <fstream> +#include <iterator> namespace CreateProjectTool { @@ -120,7 +121,7 @@ void CMakeProvider::writeEngines(const BuildSetup &setup, std::ofstream &workspa } std::string engineName; - std::transform(i->name.begin(), i->name.end(), back_inserter(engineName), toupper); + std::transform(i->name.begin(), i->name.end(), std::back_inserter(engineName), toupper); workspace << " " << engineName; } @@ -135,7 +136,7 @@ void CMakeProvider::writeSubEngines(const BuildSetup &setup, std::ofstream &work } std::string engineName; - std::transform(i->name.begin(), i->name.end(), back_inserter(engineName), toupper); + std::transform(i->name.begin(), i->name.end(), std::back_inserter(engineName), toupper); workspace << "set(SUB_ENGINES_" << engineName; for (StringList::const_iterator j = i->subEngines.begin(), subEnd = i->subEngines.end(); j != subEnd; ++j) { @@ -143,7 +144,7 @@ void CMakeProvider::writeSubEngines(const BuildSetup &setup, std::ofstream &work if (!subEngine.enable) continue; std::string subEngineName; - std::transform(j->begin(), j->end(), back_inserter(subEngineName), toupper); + std::transform(j->begin(), j->end(), std::back_inserter(subEngineName), toupper); workspace << " " << subEngineName; } @@ -165,7 +166,7 @@ void CMakeProvider::createProjectFile(const std::string &name, const std::string project << "add_executable(" << name << "\n"; } else { std::string engineName; - std::transform(name.begin(), name.end(), back_inserter(engineName), toupper); + std::transform(name.begin(), name.end(), std::back_inserter(engineName), toupper); project << "if (ENABLE_" << engineName << ")\n"; project << "add_library(" << name << "\n"; diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp index 7e2cad0901..8841eaa73d 100644 --- a/devtools/create_project/create_project.cpp +++ b/devtools/create_project/create_project.cpp @@ -524,6 +524,8 @@ int main(int argc, char *argv[]) { // 4355 ('this' : used in base member initializer list) // only disabled for specific engines where it is used in a safe way // + // 4373 (previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers) + // // 4510 ('class' : default constructor could not be generated) // // 4511 ('class' : copy constructor could not be generated) @@ -573,6 +575,8 @@ int main(int argc, char *argv[]) { projectWarnings["m4"].push_back("4355"); + projectWarnings["sci"].push_back("4373"); + if (msvcVersion == 9) provider = new CreateProjectTool::VisualStudioProvider(globalWarnings, projectWarnings, msvcVersion); else diff --git a/devtools/create_project/msvc10/create_project.vcxproj b/devtools/create_project/msvc10/create_project.vcxproj index 80dfd5e8d3..700c4bb283 100644 --- a/devtools/create_project/msvc10/create_project.vcxproj +++ b/devtools/create_project/msvc10/create_project.vcxproj @@ -95,6 +95,7 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> </PreBuildEvent> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="..\cmake.cpp" /> <ClCompile Include="..\codeblocks.cpp" /> <ClCompile Include="..\create_project.cpp" /> <ClCompile Include="..\msbuild.cpp" /> @@ -103,6 +104,7 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> <ClCompile Include="..\xcode.cpp" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\cmake.h" /> <ClInclude Include="..\codeblocks.h" /> <ClInclude Include="..\config.h" /> <ClInclude Include="..\create_project.h" /> diff --git a/devtools/create_project/msvc11/create_project.vcxproj b/devtools/create_project/msvc11/create_project.vcxproj index 8bbd25e9ba..09392a43e3 100644 --- a/devtools/create_project/msvc11/create_project.vcxproj +++ b/devtools/create_project/msvc11/create_project.vcxproj @@ -101,6 +101,7 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> </PreBuildEvent> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="..\cmake.cpp" /> <ClCompile Include="..\codeblocks.cpp" /> <ClCompile Include="..\create_project.cpp" /> <ClCompile Include="..\msbuild.cpp" /> @@ -109,6 +110,7 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> <ClCompile Include="..\xcode.cpp" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\cmake.h" /> <ClInclude Include="..\codeblocks.h" /> <ClInclude Include="..\config.h" /> <ClInclude Include="..\create_project.h" /> diff --git a/devtools/create_project/msvc12/create_project.vcxproj b/devtools/create_project/msvc12/create_project.vcxproj index 6da1556547..3b38972e51 100644 --- a/devtools/create_project/msvc12/create_project.vcxproj +++ b/devtools/create_project/msvc12/create_project.vcxproj @@ -102,6 +102,7 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> </PreBuildEvent> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="..\cmake.cpp" /> <ClCompile Include="..\codeblocks.cpp" /> <ClCompile Include="..\create_project.cpp" /> <ClCompile Include="..\msbuild.cpp" /> @@ -110,6 +111,7 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> <ClCompile Include="..\xcode.cpp" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\cmake.h" /> <ClInclude Include="..\codeblocks.h" /> <ClInclude Include="..\config.h" /> <ClInclude Include="..\create_project.h" /> diff --git a/devtools/create_project/msvc14/create_project.vcxproj b/devtools/create_project/msvc14/create_project.vcxproj index 3c0345f49c..839c834bb8 100644 --- a/devtools/create_project/msvc14/create_project.vcxproj +++ b/devtools/create_project/msvc14/create_project.vcxproj @@ -192,6 +192,7 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> </PreBuildEvent> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="..\cmake.cpp" /> <ClCompile Include="..\codeblocks.cpp" /> <ClCompile Include="..\create_project.cpp" /> <ClCompile Include="..\msbuild.cpp" /> @@ -200,6 +201,7 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> <ClCompile Include="..\xcode.cpp" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\cmake.h" /> <ClInclude Include="..\codeblocks.h" /> <ClInclude Include="..\config.h" /> <ClInclude Include="..\create_project.h" /> diff --git a/devtools/create_project/msvc9/create_project.vcproj b/devtools/create_project/msvc9/create_project.vcproj index dc914248fb..eaa72099cc 100644 --- a/devtools/create_project/msvc9/create_project.vcproj +++ b/devtools/create_project/msvc9/create_project.vcproj @@ -170,6 +170,10 @@ > </File> <File + RelativePath="..\cmake.cpp" + > + </File> + <File RelativePath="..\codeblocks.cpp" > </File> @@ -200,6 +204,10 @@ > </File> <File + RelativePath="..\cmake.h" + > + </File> + <File RelativePath="..\codeblocks.h" > </File> diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp index bfe7f522f0..62969d1436 100644 --- a/devtools/create_project/xcode.cpp +++ b/devtools/create_project/xcode.cpp @@ -106,9 +106,9 @@ bool targetIsIOS(const std::string &targetName) { bool shouldSkipFileForTarget(const std::string &fileID, const std::string &targetName, const std::string &fileName) { // Rules: // - if the parent directory is "backends/platform/ios7", the file belongs to the iOS target. - // - if the parent directory is "/sdl", the file belongs to the OS X target. + // - if the parent directory is "/sdl", the file belongs to the macOS target. // - if the file has a suffix, like "_osx", or "_ios", the file belongs to one of the target. - // - if the file is an OS X icon file (icns), it belongs to the OS X target. + // - if the file is an macOS icon file (icns), it belongs to the macOS target. std::string name, ext; splitFilename(fileName, name, ext); if (targetIsIOS(targetName)) { @@ -136,10 +136,14 @@ bool shouldSkipFileForTarget(const std::string &fileID, const std::string &targe if (fileID.length() > 12 && fileID.substr(fileID.length() - 12) == "/browser.cpp") { return true; } - // OS X target: we skip all files with the "_ios" suffix + // macOS target: we skip all files with the "_ios" suffix if (name.length() > 4 && name.substr(name.length() - 4) == "_ios") { return true; } + // macOS target: we skip all files with the "ios7_" prefix + if (name.length() > 5 && name.substr(0, 5) == "ios7_") { + return true; + } // parent directory const std::string directory = fileID.substr(0, fileID.length() - fileName.length()); static const std::string iphone_directory = "backends/platform/ios7"; @@ -293,7 +297,7 @@ void XcodeProvider::createWorkspace(const BuildSetup &setup) { // Setup global objects setupDefines(setup); _targets.push_back(PROJECT_DESCRIPTION "-iOS"); - _targets.push_back(PROJECT_DESCRIPTION "-OS X"); + _targets.push_back(PROJECT_DESCRIPTION "-macOS"); setupCopyFilesBuildPhase(); setupFrameworksBuildPhase(setup); setupNativeTarget(); @@ -407,7 +411,7 @@ void XcodeProvider::setupCopyFilesBuildPhase() { #define DEF_LOCALLIB_STATIC_PATH(path,lib,absolute) properties[lib".a"] = FileProperty("archive.ar", lib ".a", path, (absolute ? "\"<absolute>\"" : "\"<group>\"")); \ ADD_SETTING_ORDER_NOVALUE(children, getHash(lib".a"), lib".a", fwOrder++); -#define DEF_LOCALLIB_STATIC(lib) DEF_LOCALLIB_STATIC_PATH("/opt/local/lib/" lib ".a", lib, true) +#define DEF_LOCALLIB_STATIC(lib) DEF_LOCALLIB_STATIC_PATH("/usr/local/lib/" lib ".a", lib, true) /** @@ -443,7 +447,6 @@ void XcodeProvider::setupFrameworksBuildPhase(const BuildSetup &setup) { DEF_SYSFRAMEWORK("IOKit"); DEF_SYSFRAMEWORK("OpenGLES"); DEF_SYSFRAMEWORK("QuartzCore"); - DEF_SYSFRAMEWORK("QuickTime"); DEF_SYSFRAMEWORK("UIKit"); DEF_SYSTBD("libiconv"); @@ -543,7 +546,7 @@ void XcodeProvider::setupFrameworksBuildPhase(const BuildSetup &setup) { _frameworksBuildPhase.add(framework_iPhone); ////////////////////////////////////////////////////////////////////////// - // ScummVM-OS X + // ScummVM-macOS Object *framework_OSX = new Object(this, "PBXFrameworksBuildPhase_" + _targets[OSX_TARGET], "PBXFrameworksBuildPhase", "PBXFrameworksBuildPhase", "", "Frameworks"); framework_OSX->addProperty("buildActionMask", "2147483647", "", kSettingsNoValue); @@ -558,7 +561,6 @@ void XcodeProvider::setupFrameworksBuildPhase(const BuildSetup &setup) { frameworks_osx.push_back("CoreFoundation.framework"); frameworks_osx.push_back("Foundation.framework"); frameworks_osx.push_back("AudioToolbox.framework"); - frameworks_osx.push_back("QuickTime.framework"); frameworks_osx.push_back("CoreMIDI.framework"); frameworks_osx.push_back("CoreAudio.framework"); frameworks_osx.push_back("QuartzCore.framework"); @@ -776,8 +778,8 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) { Property scummvm_Debug; ADD_SETTING(scummvm_Debug, "ALWAYS_SEARCH_USER_PATHS", "NO"); ADD_SETTING_QUOTE(scummvm_Debug, "USER_HEADER_SEARCH_PATHS", "$(SRCROOT) $(SRCROOT)/engines"); - ADD_SETTING_QUOTE(scummvm_Debug, "CODE_SIGN_IDENTITY", "Don't Code Sign"); - ADD_SETTING_QUOTE_VAR(scummvm_Debug, "CODE_SIGN_IDENTITY[sdk=iphoneos*]", "Don't Code Sign"); + ADD_SETTING_QUOTE(scummvm_Debug, "CODE_SIGN_IDENTITY", ""); + ADD_SETTING_QUOTE_VAR(scummvm_Debug, "CODE_SIGN_IDENTITY[sdk=iphoneos*]", ""); ADD_SETTING_QUOTE(scummvm_Debug, "FRAMEWORK_SEARCH_PATHS", ""); ADD_SETTING(scummvm_Debug, "GCC_C_LANGUAGE_STANDARD", "c99"); ADD_SETTING(scummvm_Debug, "GCC_ENABLE_CPP_EXCEPTIONS", "NO"); @@ -791,8 +793,6 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) { REMOVE_DEFINE(scummvm_defines, "IPHONE_SANDBOXED"); REMOVE_DEFINE(scummvm_defines, "SDL_BACKEND"); ADD_SETTING_LIST(scummvm_Debug, "GCC_PREPROCESSOR_DEFINITIONS", scummvm_defines, kSettingsNoQuote | kSettingsAsList, 5); - ADD_SETTING(scummvm_Debug, "GCC_THUMB_SUPPORT", "NO"); - ADD_SETTING(scummvm_Debug, "GCC_USE_GCC3_PFE_SUPPORT", "NO"); ADD_SETTING(scummvm_Debug, "GCC_WARN_ABOUT_RETURN_TYPE", "YES"); ADD_SETTING(scummvm_Debug, "GCC_WARN_UNUSED_VARIABLE", "YES"); ValueList scummvm_HeaderPaths; @@ -804,7 +804,6 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) { ADD_SETTING(scummvm_Debug, "ONLY_ACTIVE_ARCH", "YES"); ADD_SETTING_QUOTE(scummvm_Debug, "OTHER_CFLAGS", ""); ADD_SETTING_QUOTE(scummvm_Debug, "OTHER_LDFLAGS", "-lz"); - ADD_SETTING(scummvm_Debug, "PREBINDING", "NO"); ADD_SETTING(scummvm_Debug, "ENABLE_TESTABILITY", "YES"); scummvm_Debug_Object->addProperty("name", "Debug", "", kSettingsNoValue); @@ -834,7 +833,6 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) { Property iPhone_Debug; ADD_SETTING_QUOTE(iPhone_Debug, "CODE_SIGN_IDENTITY", "iPhone Developer"); ADD_SETTING_QUOTE_VAR(iPhone_Debug, "CODE_SIGN_IDENTITY[sdk=iphoneos*]", "iPhone Developer"); - ADD_SETTING(iPhone_Debug, "COMPRESS_PNG_FILES", "NO"); ADD_SETTING(iPhone_Debug, "COPY_PHASE_STRIP", "NO"); ADD_SETTING_QUOTE(iPhone_Debug, "DEBUG_INFORMATION_FORMAT", "dwarf"); ValueList iPhone_FrameworkSearchPaths; @@ -843,13 +841,11 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) { ADD_SETTING_LIST(iPhone_Debug, "FRAMEWORK_SEARCH_PATHS", iPhone_FrameworkSearchPaths, kSettingsAsList, 5); ADD_SETTING(iPhone_Debug, "GCC_DYNAMIC_NO_PIC", "NO"); ADD_SETTING(iPhone_Debug, "GCC_ENABLE_CPP_EXCEPTIONS", "NO"); - ADD_SETTING(iPhone_Debug, "GCC_ENABLE_FIX_AND_CONTINUE", "NO"); ADD_SETTING(iPhone_Debug, "GCC_OPTIMIZATION_LEVEL", "0"); ADD_SETTING(iPhone_Debug, "GCC_PRECOMPILE_PREFIX_HEADER", "NO"); ADD_SETTING(iPhone_Debug, "GCC_WARN_64_TO_32_BIT_CONVERSION", "NO"); ADD_SETTING(iPhone_Debug, "WARNING_CFLAGS", "-Wno-multichar"); ADD_SETTING_QUOTE(iPhone_Debug, "GCC_PREFIX_HEADER", ""); - ADD_SETTING(iPhone_Debug, "GCC_THUMB_SUPPORT", "NO"); ADD_SETTING(iPhone_Debug, "GCC_UNROLL_LOOPS", "YES"); ValueList iPhone_HeaderSearchPaths; iPhone_HeaderSearchPaths.push_back("$(SRCROOT)/engines/"); @@ -863,7 +859,6 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) { iPhone_LibPaths.push_back("\"" + projectOutputDirectory + "/lib\""); ADD_SETTING_LIST(iPhone_Debug, "LIBRARY_SEARCH_PATHS", iPhone_LibPaths, kSettingsAsList, 5); ADD_SETTING(iPhone_Debug, "ONLY_ACTIVE_ARCH", "YES"); - ADD_SETTING(iPhone_Debug, "PREBINDING", "NO"); ADD_SETTING(iPhone_Debug, "PRODUCT_NAME", PROJECT_NAME); ADD_SETTING(iPhone_Debug, "PRODUCT_BUNDLE_IDENTIFIER", "\"org.scummvm.${PRODUCT_NAME}\""); ADD_SETTING(iPhone_Debug, "IPHONEOS_DEPLOYMENT_TARGET", "7.1"); @@ -900,15 +895,14 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) { _buildConfiguration.add(iPhone_Release_Object); /**************************************** - * ScummVM - OS X Target + * ScummVM - macOS Target ****************************************/ // Debug - Object *scummvmOSX_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-OSX_Debug", _targets[OSX_TARGET] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Debug"); + Object *scummvmOSX_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-OSX_Debug", _targets[OSX_TARGET] /* ScummVM-macOS */, "XCBuildConfiguration", "PBXNativeTarget", "Debug"); Property scummvmOSX_Debug; ADD_SETTING(scummvmOSX_Debug, "COMBINE_HIDPI_IMAGES", "YES"); ADD_SETTING(scummvmOSX_Debug, "SDKROOT", "macosx"); - ADD_SETTING(scummvmOSX_Debug, "COMPRESS_PNG_FILES", "NO"); ADD_SETTING(scummvmOSX_Debug, "COPY_PHASE_STRIP", "NO"); ADD_SETTING_QUOTE(scummvmOSX_Debug, "DEBUG_INFORMATION_FORMAT", "dwarf"); ADD_SETTING_QUOTE(scummvmOSX_Debug, "FRAMEWORK_SEARCH_PATHS", ""); @@ -916,7 +910,6 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) { ADD_SETTING(scummvmOSX_Debug, "GCC_ENABLE_CPP_EXCEPTIONS", "NO"); ADD_SETTING(scummvmOSX_Debug, "GCC_ENABLE_CPP_RTTI", "YES"); ADD_SETTING(scummvmOSX_Debug, "GCC_DYNAMIC_NO_PIC", "NO"); - ADD_SETTING(scummvmOSX_Debug, "GCC_ENABLE_FIX_AND_CONTINUE", "NO"); ADD_SETTING(scummvmOSX_Debug, "GCC_OPTIMIZATION_LEVEL", "0"); ADD_SETTING(scummvmOSX_Debug, "GCC_PRECOMPILE_PREFIX_HEADER", "NO"); ADD_SETTING_QUOTE(scummvmOSX_Debug, "GCC_PREFIX_HEADER", ""); @@ -928,22 +921,21 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) { ADD_SETTING_QUOTE(scummvmOSX_Debug, "GCC_VERSION", ""); ValueList scummvmOSX_HeaderPaths; if (setup.useSDL2) { - scummvmOSX_HeaderPaths.push_back("/opt/local/include/SDL2"); + scummvmOSX_HeaderPaths.push_back("/usr/local/include/SDL2"); } else { - scummvmOSX_HeaderPaths.push_back("/opt/local/include/SDL"); + scummvmOSX_HeaderPaths.push_back("/usr/local/include/SDL"); } - scummvmOSX_HeaderPaths.push_back("/opt/local/include"); - scummvmOSX_HeaderPaths.push_back("/opt/local/include/freetype2"); + scummvmOSX_HeaderPaths.push_back("/usr/local/include"); + scummvmOSX_HeaderPaths.push_back("/usr/local/include/freetype2"); scummvmOSX_HeaderPaths.push_back("include/"); scummvmOSX_HeaderPaths.push_back("$(SRCROOT)/engines/"); scummvmOSX_HeaderPaths.push_back("$(SRCROOT)"); ADD_SETTING_LIST(scummvmOSX_Debug, "HEADER_SEARCH_PATHS", scummvmOSX_HeaderPaths, kSettingsQuoteVariable | kSettingsAsList, 5); ADD_SETTING_QUOTE(scummvmOSX_Debug, "INFOPLIST_FILE", "$(SRCROOT)/dists/macosx/Info.plist"); ValueList scummvmOSX_LibPaths; - scummvmOSX_LibPaths.push_back("/sw/lib"); - scummvmOSX_LibPaths.push_back("/opt/local/lib"); + scummvmOSX_LibPaths.push_back("/usr/local/lib"); scummvmOSX_LibPaths.push_back("\"$(inherited)\""); - scummvmOSX_LibPaths.push_back("\"\\\\\\\"$(SRCROOT)/lib\\\\\\\"\""); // mmmh, all those slashes, it's almost Christmas \o/ + scummvmOSX_LibPaths.push_back("\"\\\"$(SRCROOT)/lib\\\"\""); ADD_SETTING_LIST(scummvmOSX_Debug, "LIBRARY_SEARCH_PATHS", scummvmOSX_LibPaths, kSettingsNoQuote | kSettingsAsList, 5); ADD_SETTING_QUOTE(scummvmOSX_Debug, "OTHER_CFLAGS", ""); ValueList scummvmOSX_LdFlags; @@ -965,14 +957,13 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) { } scummvmOSX_LdFlags.push_back("-lz"); ADD_SETTING_LIST(scummvmOSX_Debug, "OTHER_LDFLAGS", scummvmOSX_LdFlags, kSettingsAsList, 5); - ADD_SETTING(scummvmOSX_Debug, "PREBINDING", "NO"); ADD_SETTING(scummvmOSX_Debug, "PRODUCT_NAME", PROJECT_NAME); scummvmOSX_Debug_Object->addProperty("name", "Debug", "", kSettingsNoValue); scummvmOSX_Debug_Object->_properties["buildSettings"] = scummvmOSX_Debug; // Release - Object *scummvmOSX_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-OSX_Release", _targets[OSX_TARGET] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Release"); + Object *scummvmOSX_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-OSX_Release", _targets[OSX_TARGET] /* ScummVM-macOS */, "XCBuildConfiguration", "PBXNativeTarget", "Release"); Property scummvmOSX_Release(scummvmOSX_Debug); ADD_SETTING(scummvmOSX_Release, "COPY_PHASE_STRIP", "YES"); REMOVE_SETTING(scummvmOSX_Release, "GCC_DYNAMIC_NO_PIC"); @@ -1031,7 +1022,7 @@ void XcodeProvider::setupAdditionalSources(std::string targetName, Property &fil void XcodeProvider::setupDefines(const BuildSetup &setup) { for (StringList::const_iterator i = setup.defines.begin(); i != setup.defines.end(); ++i) { - if (*i == "HAVE_NASM") // Not supported on Mac (TODO: change how it's handled in main class or add it only in MSVC/CodeBlocks providers?) + if (*i == "USE_NASM" || *i == "USE_FLUIDSYNTH") // Not supported on Mac continue; ADD_DEFINE(_defines, *i); @@ -1042,6 +1033,7 @@ void XcodeProvider::setupDefines(const BuildSetup &setup) { REMOVE_DEFINE(_defines, "IPHONE_IOS7"); REMOVE_DEFINE(_defines, "IPHONE_SANDBOXED"); REMOVE_DEFINE(_defines, "SDL_BACKEND"); + ADD_DEFINE(_defines, "USE_TEXT_CONSOLE_FOR_DEBUGGER"); ADD_DEFINE(_defines, "CONFIG_H"); ADD_DEFINE(_defines, "UNIX"); ADD_DEFINE(_defines, "SCUMMVM"); diff --git a/devtools/create_titanic/create_titanic_dat.cpp b/devtools/create_titanic/create_titanic_dat.cpp new file mode 100644 index 0000000000..72c7f1ef46 --- /dev/null +++ b/devtools/create_titanic/create_titanic_dat.cpp @@ -0,0 +1,759 @@ +/* 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. + * + */ + + // Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +// HACK to allow building with the SDL backend on MinGW +// see bug #1800764 "TOOLS: MinGW tools building broken" +#ifdef main +#undef main +#endif // main + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "common/language.h" +#include "common/rect.h" +#include "winexe_pe.h" +#include "file.h" +#include "script_preresponses.h" +#include "script_quotes.h" +#include "script_responses.h" +#include "script_ranges.h" +#include "script_states.h" +#include "tag_maps.h" + +/** + * Format of the access.dat file that will be created: + * 4 Bytes - Magic string 'SVTN' to identify valid data file + * 2 bytes - Version number + * + * Following is a series of index entries with the following fields: + * 4 bytes - offset in file of entry + * 4 bytes - size of entry in the file + * ASCIIZ - name of the resource + */ + +#define VERSION_NUMBER 1 +#define HEADER_SIZE 0xD00 + +Common::File inputFile, outputFile; +Common::PEResources res; +uint headerOffset = 6; +uint dataOffset = HEADER_SIZE; +#define SEGMENT_OFFSET 0x401C00 + +const int FILE_DIFF = 0x401C00; + +static const char *const ITEM_NAMES[46] = { + "LeftArmWith", "LeftArmWithout", "RightArmWith", "RightArmWithout", "BridgeRed", + "BridgeYellow", "BridgeBlue", "BridgeGreen", "Parrot", "CentralCore", "BrainGreen", + "BrainYellow", "BrainRed", "BrainBlue", "ChickenGreasy", "ChickenPlain", "ChickenPurple", + "ChickenRed", "ChickenYellow", "CrushedTV", "Ear", "Ear1", "Eyeball", "Eyeball1", + "Feather", "Lemon", "GlassEmpty", "GlassPurple", "GlassRed", "GlassYellow", "Hammer", + "Hose", "HoseEnd", "LiftHead", "LongStick", "Magazine", "Mouth", "MusicKey", "Napkin", + "Nose", "Perch", "PhonoCylinder", "PhonoCylinder1", "PhonoCylinder2", "PhonoCylinder3", + "Photo" +}; + +static const char *const ITEM_DESCRIPTIONS[46] = { + "The Maitre d'Bot's left arm holding a key", "The Maitre d'Bot's left arm", + "The Maitre d'Bot's right arm holding Titania's auditory center", + "The Maitre d'Bot's right arm", "Red Fuse", "Yellow Fuse", "Blue Fuse", + "Green Fuse", "The Parrot", "Titania's central intelligence core", + "Titania's auditory center", "Titania's olfactory center", + "Titania's speech center", "Titania's vision center", "rather greasy chicken", + "very plain chicken", "chicken smeared with starling pur$e", + "chicken covered with tomato sauce", "chicken coated in mustard sauce", + "A crushed television set", "Titania's ear", "Titania's ear", "Titania's eye", + "Titania's eye", "A parrot feather", "A nice fat juicy lemon", + "An empty beer glass", "A beer glass containing pur$ed flock of starlings", + "A beer glass containing tomato sauce", "A beer glass containing mustard sauce", + "A hammer", "A hose", "The other end of a hose", "The LiftBot's head", + "A rather long stick", "A magazine", "Titania's mouth", "A key", + "A super-absorbent napkin", "Titania's nose", "A perch", "A phonograph cylinder", + "A phonograph cylinder", "A phonograph cylinder", "A phonograph cylinder", + "A photograph" +}; + +static const char *const ITEM_IDS[40] = { + "MaitreD Left Arm", "MaitreD Right Arm", "OlfactoryCentre", "AuditoryCentre", + "SpeechCentre", "VisionCentre", "CentralCore", "Perch", "SeasonBridge", + "FanBridge", "BeamBridge", "ChickenBridge", "CarryParrot", "Chicken", + "CrushedTV", "Feathers", "Lemon", "BeerGlass", "BigHammer", "Ear1", "Ear 2", + "Eye1", "Eye2", "Mouth", "Nose", "NoseSpare", "Hose", "DeadHoseSpare", + "HoseEnd", "DeadHoseEndSpare", "BrokenLiftbotHead", "LongStick", "Magazine", + "Napkin", "Phonograph Cylinder", "Phonograph Cylinder 1", "Phonograph Cylinder 2", + "Phonograph Cylinder 3", "Photograph", "Music System Key" +}; + +static const char *const ROOM_NAMES[34] = { + "1stClassLobby", "1stClassRestaurant", "1stClassState", + "2ndClassLobby", "secClassState", "Arboretum", "FrozenArboretum", + "Bar", "BilgeRoom", "BilgeRoomWith", "BottomOfWell", "Bridge", + "CreatorsChamber", "CreatorsChamberOn", "Dome", "Home", "Lift", + "EmbLobby", "MoonEmbLobby", "MusicRoomLobby", "MusicRoom", + "ParrotLobby", "Pellerator", "PromenadeDeck", "SculptureChamber", + "SecClassLittleLift", "ServiceElevator", "SGTLeisure", "SGTLittleLift", + "SgtLobby", "SGTState", "Titania", "TopOfWell", "PlayersRoom" +}; + +struct NumberEntry { + const char *_text; + int _value; + uint _flags; +}; + +const NumberEntry NUMBERS[76] = { + { "a", 1, 3 }, + { "and", 0, 1 }, + { "negative", 0, 10 }, + { "minus", 0, 10 }, + { "below zeor", 0, 8 }, + { "degrees below zero", 0, 8 }, + { "nil", 0, 2 }, + { "zero", 0, 2 }, + { "one", 1, 0x12 }, + { "two", 2, 0x12 }, + { "three", 3, 0x12 }, + { "four", 4, 0x12 }, + { "five", 5, 0x12 }, + { "six", 6, 0x12 }, + { "seven", 7, 0x12 }, + { "eight", 8, 0x12 }, + { "nine", 9, 0x12 }, + { "0", 0, 2 }, + { "1", 1, 2 }, + { "2", 2, 2 }, + { "3", 3, 2 }, + { "4", 4, 2 }, + { "5", 5, 2 }, + { "6", 6, 2 }, + { "7", 7, 2 }, + { "8", 8, 2 }, + { "9", 9, 2 }, + { "first", 1, 2 }, + { "second", 2, 2 }, + { "third", 3, 2 }, + { "fourth", 4, 2 }, + { "fifth", 5, 2 }, + { "sixth", 6, 2 }, + { "seventh", 7, 2 }, + { "eighth", 8, 2 }, + { "ninth", 9, 2 }, + { "ten", 10, 2 }, + { "eleven", 11, 2 }, + { "twelve", 12, 2 }, + { "thirteen", 13, 2 }, + { "fourteen", 14, 2 }, + { "fifteen", 15, 2 }, + { "sixteen", 16, 2 }, + { "seventeen", 17, 2 }, + { "eighteen", 18, 2 }, + { "nineteen", 19, 2 }, + { "tenth", 10, 2 }, + { "eleventh", 11, 2 }, + { "twelfth", 12, 2 }, + { "thirteenth", 13, 2 }, + { "fourteenth", 14, 2 }, + { "fifteenth", 15, 2 }, + { "sixteenth", 16, 2 }, + { "seventeenth", 17, 2 }, + { "eighteenth", 18, 2 }, + { "nineteenth", 19, 2 }, + { "twenty", 20, 0x12 }, + { "thirty", 30, 0x12 }, + { "forty", 40, 0x12 }, + { "fourty", 40, 0x12 }, + { "fifty", 50, 0x12 }, + { "sixty", 60, 0x12 }, + { "seventy", 70, 0x12 }, + { "eighty", 80, 0x12 }, + { "ninety", 90, 0x12 }, + { "twentieth", 20, 2 }, + { "thirtieth", 30, 2 }, + { "fortieth", 40, 2 }, + { "fiftieth", 50, 2 }, + { "sixtieth", 60, 2 }, + { "seventieth", 70, 2 }, + { "eightieth", 80, 2 }, + { "ninetieth", 90, 2 }, + { "hundred", 100, 4 }, + { "hundredth", 100, 6 } +}; + +struct CommonPhrase { + const char *_str; + uint _dialogueId; + uint _roomNum; + uint _val1; +}; + +static const CommonPhrase BELLBOT_COMMON_PHRASES[] = { + { "what is wrong with her", 0x30FF9, 0x7B, 0 }, + { "what is wrong with titania", 0x30FF9, 0x7B, 0 }, + { "something for the weekend", 0x30D8B, 0x00, 0 }, + { "other food", 0x30E1D, 0x00, 3 }, + { "different food", 0x30E1D, 0x00, 3 }, + { "alternative food", 0x30E1D, 0x00, 3 }, + { "decent food", 0x30E1D, 0x00, 3 }, + { "nice food", 0x30E1D, 0x00, 3 }, + { "nicer food", 0x30E1D, 0x00, 3 }, + { "make me happy", 0x31011, 0x00, 0 }, + { "cheer me up", 0x31011, 0x00, 0 }, + { "help me if im unhappy", 0x31011, 0x00, 0 }, + { "i obtain a better room", 0x30E8A, 0x00, 3 }, + { "i obtain a better room", 0x30E8A, 0x00, 2 }, + { "i get a better room", 0x30E8A, 0x00, 3 }, + { "i get a better room", 0x30E8A, 0x00, 2 }, + { "i want a better room", 0x30E8A, 0x00, 3 }, + { "i want a better room", 0x30E8A, 0x00, 2 }, + { "i understood", 0x30D75, 0x6D, 0 }, + { "i knew", 0x30D75, 0x6D, 0 }, + { "i know", 0x30D75, 0x6D, 0 }, + { "not stupid", 0x30D75, 0x6D, 0 }, + { "cheeky", 0x30D75, 0x6D, 0 }, + { "not help", 0x30D6F, 0x6D, 0 }, + { "not helpful", 0x30D6F, 0x6D, 0 }, + { "dont help", 0x30D6F, 0x6D, 0 }, + { "no help", 0x30D6F, 0x6D, 0 }, + { "sorry", 0x30D76, 0x6D, 0 }, + { "not mean that", 0x30D76, 0x6D, 0 }, + { "didnt mean that", 0x30D76, 0x6D, 0 }, + { "apologise", 0x30D76, 0x6D, 0 }, + { "play golf", 0x313B6, 0x00, 0 }, + { "is not the captain meant to go down with the ship", 0x31482, 0x00, 0 }, + { "is not the captain supposed to go down with the ship", 0x31482, 0x00, 0 }, + { "sauce sticks to the chicken", 0x3156B, 0x00, 0 }, + { "sauce gets stuck to the chicken", 0x3156B, 0x00, 0 }, + { nullptr, 0, 0, 0 } +}; + + +void NORETURN_PRE error(const char *s, ...) { + printf("%s\n", s); + exit(1); +} + +void writeEntryHeader(const char *name, uint offset, uint size) { + assert(headerOffset < HEADER_SIZE); + outputFile.seek(headerOffset); + outputFile.writeLong(offset); + outputFile.writeLong(size); + outputFile.writeString(name); + + headerOffset += 8 + strlen(name) + 1; +} + +void writeFinalEntryHeader() { + assert(headerOffset <= (HEADER_SIZE - 8)); + outputFile.seek(headerOffset); + outputFile.writeLong(0); + outputFile.writeLong(0); +} + +void writeStringArray(const char *name, uint offset, int count) { + outputFile.seek(dataOffset); + + inputFile.seek(offset); + uint *offsets = new uint[count]; + for (int idx = 0; idx < count; ++idx) + offsets[idx] = inputFile.readLong(); + + // Iterate through reading each string + for (int idx = 0; idx < count; ++idx) { + if (offsets[idx]) { + inputFile.seek(offsets[idx] - SEGMENT_OFFSET); + outputFile.writeString(inputFile); + } else { + outputFile.writeString(""); + } + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader(name, dataOffset, size); + dataOffset += size; + + delete[] offsets; +} + +void writeStringArray(const char *name, const char *const *strings, int count) { + outputFile.seek(dataOffset); + + // Iterate through writing each string + for (int idx = 0; idx < count; ++idx) { + outputFile.writeString(strings[idx]); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader(name, dataOffset, size); + dataOffset += size; +} + +Common::WinResourceID getResId(uint id) { + return Common::WinResourceID(id); +} + +Common::WinResourceID getResId(const char *id) { + if (!strcmp(id, "Bitmap")) + return Common::WinResourceID(2); + + return Common::WinResourceID(id); +} + +void writeResource(const char *name, Common::File *file) { + outputFile.seek(dataOffset); + outputFile.write(*file, file->size()); + + writeEntryHeader(name, dataOffset, file->size()); + dataOffset += file->size(); + delete file; +} + +void writeResource(const char *sectionStr, uint32 resId) { + char nameBuffer[256]; + sprintf(nameBuffer, "%s/%u", sectionStr, resId); + + Common::File *file = res.getResource(getResId(sectionStr), resId); + assert(file); + writeResource(nameBuffer, file); +} + +void writeResource(const char *sectionStr, const char *resId) { + char nameBuffer[256]; + sprintf(nameBuffer, "%s/%s", sectionStr, resId); + + Common::File *file = res.getResource(getResId(sectionStr), + Common::WinResourceID(resId)); + assert(file); + writeResource(nameBuffer, file); +} + +void writeBitmap(const char *name, Common::File *file) { + outputFile.seek(dataOffset); + + // Write out the necessary bitmap header so that the ScummVM + // BMP decoder can properly handle decoding the bitmaps + outputFile.write("BM", 2); + outputFile.writeLong(file->size() + 14); // Filesize + outputFile.writeLong(0); // res1 & res2 + outputFile.writeLong(0x436); // image offset + + outputFile.write(*file, file->size() + 14); + + writeEntryHeader(name, dataOffset, file->size() + 14); + dataOffset += file->size() + 14; + delete file; +} + +void writeBitmap(const char *sectionStr, const char *resId) { + char nameBuffer[256]; + sprintf(nameBuffer, "%s/%s", sectionStr, resId); + + Common::File *file = res.getResource(getResId(sectionStr), + Common::WinResourceID(resId)); + assert(file); + writeBitmap(nameBuffer, file); +} + +void writeBitmap(const char *sectionStr, uint32 resId) { + char nameBuffer[256]; + sprintf(nameBuffer, "%s/%u", sectionStr, resId); + + Common::File *file = res.getResource(getResId(sectionStr), + Common::WinResourceID(resId)); + assert(file); + writeBitmap(nameBuffer, file); +} + +void writeNumbers() { + outputFile.seek(dataOffset); + + // Iterate through writing each string + for (int idx = 0; idx < 76; ++idx) { + outputFile.writeString(NUMBERS[idx]._text); + outputFile.writeLong(NUMBERS[idx]._value); + outputFile.writeLong(NUMBERS[idx]._flags); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader("TEXT/NUMBERS", dataOffset, size); + dataOffset += size; +} + +void writeString(uint offset) { + inputFile.seek(offset - FILE_DIFF); + char c; + do { + c = inputFile.readByte(); + outputFile.writeByte(c); + } while (c); +} + +void writeResponseTree() { + outputFile.seek(dataOffset); + + inputFile.seek(0x619500 - FILE_DIFF); + char buffer[32]; + inputFile.read(buffer, 32); + if (strcmp(buffer, "ReadInt(): No number to read")) { + printf("Could not find tree data at expected position\n"); + exit(1); + } + + for (int idx = 0; idx < 1022; ++idx) { + inputFile.seek(0x619520 - FILE_DIFF + idx * 8); + uint id = inputFile.readLong(); + uint offset = inputFile.readLong(); + + outputFile.writeLong(id); + if (!id) { + // An end of list id + } else if (offset >= 0x619520 && offset <= 0x61B510) { + // Offset to another table + outputFile.writeByte(0); + outputFile.writeLong((offset - 0x619520) / 8); + } else { + // Offset to ASCIIZ string + outputFile.writeByte(1); + writeString(offset); + } + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader("TEXT/TREE", dataOffset, size); + dataOffset += size; +} + +void writeSentenceEntries(const char *name, uint tableOffset) { + outputFile.seek(dataOffset); + + uint v1, v2, v4, v9, v11, v12, v13; + uint offset3, offset5, offset6, offset7, offset8, offset10; + + for (uint idx = 0; ; ++idx) { + inputFile.seek(tableOffset - FILE_DIFF + idx * 0x34); + v1 = inputFile.readLong(); + if (!v1) + // Reached end of list + break; + + // Read data fields + v2 = inputFile.readLong(); + offset3 = inputFile.readLong(); + v4 = inputFile.readLong(); + offset5 = inputFile.readLong(); + offset6 = inputFile.readLong(); + offset7 = inputFile.readLong(); + offset8 = inputFile.readLong(); + v9 = inputFile.readLong(); + offset10 = inputFile.readLong(); + v11 = inputFile.readLong(); + v12 = inputFile.readLong(); + v13 = inputFile.readLong(); + + outputFile.writeLong(v1); + outputFile.writeLong(v2); + writeString(offset3); + outputFile.writeLong(v1); + writeString(offset5); + writeString(offset6); + writeString(offset7); + writeString(offset8); + outputFile.writeLong(v9); + writeString(offset10); + outputFile.writeLong(v11); + outputFile.writeLong(v12); + outputFile.writeLong(v13); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader(name, dataOffset, size); + dataOffset += size; +} + +void writeWords(const char *name, uint tableOffset, int recordCount = 2) { + outputFile.seek(dataOffset); + int recordSize = recordCount * 4; + + uint val, strOffset; + for (uint idx = 0; ; ++idx) { + inputFile.seek(tableOffset - FILE_DIFF + idx * recordSize); + val = inputFile.readLong(); + strOffset = inputFile.readLong(); + + if (!val) + // Reached end of list + break; + + outputFile.writeLong(val); + writeString(strOffset); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader(name, dataOffset, size); + dataOffset += size; +} + +void writeSentenceMappings(const char *name, uint offset, int numValues) { + inputFile.seek(offset - FILE_DIFF); + outputFile.seek(dataOffset); + + uint id; + while ((id = inputFile.readLong()) != 0) { + outputFile.writeLong(id); + + for (int ctr = 0; ctr < numValues; ++ctr) + outputFile.writeLong(inputFile.readLong()); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader(name, dataOffset, size); + dataOffset += size; +} + +void writeStarfieldPoints() { + outputFile.seek(dataOffset); + + inputFile.seek(0x59DE4C - FILE_DIFF); + uint size = 876 * 12; + + outputFile.write(inputFile, size); + writeEntryHeader("STARFIELD/POINTS", dataOffset, size); + dataOffset += size; +} + +void writeStarfieldPoints2() { + outputFile.seek(dataOffset); + + for (int rootCtr = 0; rootCtr < 80; ++rootCtr) { + inputFile.seek(0x5A2F28 - FILE_DIFF + rootCtr * 8); + uint offset = inputFile.readUint32LE(); + uint count = inputFile.readUint32LE(); + + outputFile.writeLong(count); + inputFile.seek(offset - FILE_DIFF); + outputFile.write(inputFile, count * 4 * 4); + } + + uint size = outputFile.size() - dataOffset; + outputFile.write(inputFile, size); + writeEntryHeader("STARFIELD/POINTS2", dataOffset, size); + dataOffset += size; +} + +void writePhrases(const char *name, const CommonPhrase *phrases) { + for (uint idx = 0; phrases->_str; ++idx, ++phrases) { + outputFile.seek(dataOffset + idx * 4); + outputFile.writeString(phrases->_str); + outputFile.writeLong(phrases->_dialogueId); + outputFile.writeLong(phrases->_roomNum); + outputFile.writeLong(phrases->_val1); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader("Phrases/Bellbot", dataOffset, size); + dataOffset += size; +} + +void writeHeader() { + // Write out magic string + const char *MAGIC_STR = "SVTN"; + outputFile.write(MAGIC_STR, 4); + + // Write out version number + outputFile.writeWord(VERSION_NUMBER); +} + +void writeData() { + writeBitmap("Bitmap", "BACKDROP"); + writeBitmap("Bitmap", "EVILTWIN"); + writeBitmap("Bitmap", "RESTORED"); + writeBitmap("Bitmap", "RESTOREF"); + writeBitmap("Bitmap", "RESTOREU"); + writeBitmap("Bitmap", "STARTD"); + writeBitmap("Bitmap", "STARTF"); + writeBitmap("Bitmap", "STARTU"); + writeBitmap("Bitmap", "TITANIC"); + writeBitmap("Bitmap", 133); + writeBitmap("Bitmap", 164); + writeBitmap("Bitmap", 165); + + writeResource("STFONT", 149); + writeResource("STFONT", 151); + writeResource("STFONT", 152); + writeResource("STFONT", 153); + + writeResource("STARFIELD", 132); + writeStarfieldPoints(); + writeStarfieldPoints2(); + + writeResource("TEXT", "STVOCAB.TXT"); + writeResource("TEXT", "JRQUOTES.TXT"); + writeResource("TEXT", 155); + + writeStringArray("TEXT/ITEM_DESCRIPTIONS", ITEM_DESCRIPTIONS, 46); + writeStringArray("TEXT/ITEM_NAMES", ITEM_NAMES, 46); + writeStringArray("TEXT/ITEM_IDS", ITEM_IDS, 40); + writeStringArray("TEXT/ROOM_NAMES", ROOM_NAMES, 34); + + writeStringArray("TEXT/PHRASES", 0x21B7C8, 376); + writeStringArray("TEXT/REPLACEMENTS1", 0x21BDB0, 218); + writeStringArray("TEXT/REPLACEMENTS2", 0x21C120, 1576); + writeStringArray("TEXT/REPLACEMENTS3", 0x21D9C8, 82); + writeStringArray("TEXT/PRONOUNS", 0x22F718, 15); + + writeSentenceEntries("Sentences/Default", 0x5C0130); + writeSentenceEntries("Sentences/Barbot", 0x5ABE60); + writeSentenceEntries("Sentences/Barbot2", 0x5BD4E8); + writeSentenceEntries("Sentences/Bellbot", 0x5C2230); + writeSentenceEntries("Sentences/Bellbot/1", 0x5D1670); + writeSentenceEntries("Sentences/Bellbot/2", 0x5D1A80); + writeSentenceEntries("Sentences/Bellbot/3", 0x5D1AE8); + writeSentenceEntries("Sentences/Bellbot/4", 0x5D1B88); + writeSentenceEntries("Sentences/Bellbot/5", 0x5D2A60); + writeSentenceEntries("Sentences/Bellbot/6", 0x5D2CD0); + writeSentenceEntries("Sentences/Bellbot/7", 0x5D3488); + writeSentenceEntries("Sentences/Bellbot/8", 0x5D3900); + writeSentenceEntries("Sentences/Bellbot/9", 0x5D3968); + writeSentenceEntries("Sentences/Bellbot/10", 0x5D4668); + writeSentenceEntries("Sentences/Bellbot/11", 0x5D47A0); + writeSentenceEntries("Sentences/Bellbot/12", 0x5D4EC0); + writeSentenceEntries("Sentences/Bellbot/13", 0x5D5100); + writeSentenceEntries("Sentences/Bellbot/14", 0x5D5370); + writeSentenceEntries("Sentences/Bellbot/15", 0x5D5548); + writeSentenceEntries("Sentences/Bellbot/16", 0x5D56B8); + writeSentenceEntries("Sentences/Bellbot/17", 0x5D57C0); + writeSentenceEntries("Sentences/Bellbot/18", 0x5D5B38); + writeSentenceEntries("Sentences/Bellbot/19", 0x5D61B8); + + writeSentenceEntries("Sentences/Deskbot", 0x5DCD10); + writeSentenceEntries("Sentences/Deskbot/2", 0x5E8E18); + writeSentenceEntries("Sentences/Deskbot/3", 0x5E8BA8); + + writeSentenceEntries("Sentences/Doorbot", 0x5EC110); + writeSentenceEntries("Sentences/Doorbot/2", 0x5FD930); + writeSentenceEntries("Sentences/Doorbot/100", 0x5FD930); + writeSentenceEntries("Sentences/Doorbot/101", 0x5FE668); + writeSentenceEntries("Sentences/Doorbot/102", 0x5FDD40); + writeSentenceEntries("Sentences/Doorbot/107", 0x5FFF08); + writeSentenceEntries("Sentences/Doorbot/110", 0x5FE3C0); + writeSentenceEntries("Sentences/Doorbot/111", 0x5FF0C8); + writeSentenceEntries("Sentences/Doorbot/124", 0x5FF780); + writeSentenceEntries("Sentences/Doorbot/129", 0x5FFAC0); + writeSentenceEntries("Sentences/Doorbot/131", 0x5FFC30); + writeSentenceEntries("Sentences/Doorbot/132", 0x6000E0); + + writeSentenceEntries("Sentences/Liftbot", 0x6026B0); + writeSentenceEntries("Sentences/MaitreD", 0x60CFD8); + writeSentenceEntries("Sentences/MaitreD/1", 0x614288); + writeSentenceEntries("Sentences/Parrot", 0x615858); + writeSentenceEntries("Sentences/SuccUBus", 0x616698); + writeSentenceMappings("Mappings/Barbot", 0x5B28A0, 8); + writeSentenceMappings("Mappings/Bellbot", 0x5CD830, 1); + writeSentenceMappings("Mappings/Deskbot", 0x5E2BB8, 4); + writeSentenceMappings("Mappings/Doorbot", 0x5F7950, 4); + writeSentenceMappings("Mappings/Liftbot", 0x608660, 4); + writeSentenceMappings("Mappings/MaitreD", 0x6125C8, 1); + writeSentenceMappings("Mappings/Parrot", 0x615B68, 1); + writeSentenceMappings("Mappings/SuccUBus", 0x6189F0, 1); + writeWords("Words/Barbot", 0x5BE2E0); + writeWords("Words/Bellbot", 0x5D8230); + writeWords("Words/Deskbot", 0x5EAAA8); + writeWords("Words/Doorbot", 0x601098, 3); + writeWords("Words/Liftbot", 0x60C788); + writePhrases("Phrases/Bellbot", BELLBOT_COMMON_PHRASES); + + writeResponseTree(); + writeNumbers(); + writeAllScriptQuotes(); + writeAllScriptResponses(); + writeAllScriptRanges(); + writeAllTagMappings(); + writeAllUpdateStates(); + writeAllScriptPreResponses(); +} + +void createScriptMap() { + Common::File inFile; + char line[80]; + char c[2]; + c[0] = c[1] = '\0'; + int counter = 0; + + inFile.open("d:\\temp\\map.txt"); + printf("static const TagMapping xxxx_ID_MAP[] = {\n"); + + do { + strcpy(line, ""); + + while (!inFile.eof()) { + c[0] = inFile.readByte(); + if (c[0] == '\n') + c[0] = ' '; + else if (c[0] == '\r') + continue; + strcat(line, c); + if (inFile.eof() || strlen(line) == (2 * 9)) + break; + } + + int v1, v2; + sscanf(line, "%x %x", &v1, &v2); + + if (counter != 0 && (counter % 3) == 0) + printf("\r\n"); + if ((counter % 3) == 0) + printf("\t"); + + printf("{ 0x%.5x, 0x%.5x }, ", v1, v2); + ++counter; + } while (!inFile.eof()); + + printf("};\r\n"); + inFile.close(); +} + +int main(int argc, char *argv[]) { + if (argc != 3) { + printf("Format: %s ST.exe titanic.dat\n", argv[0]); + exit(0); + } + + if (!inputFile.open(argv[1])) { + error("Could not open input file"); + } + res.loadFromEXE(argv[1]); + + if (!outputFile.open(argv[2], Common::kFileWriteMode)) { + error("Could not open output file"); + } + + writeHeader(); + writeData(); + writeFinalEntryHeader(); + + inputFile.close(); + outputFile.close(); + return 0; +} diff --git a/devtools/create_titanic/file.h b/devtools/create_titanic/file.h new file mode 100644 index 0000000000..4580e83b19 --- /dev/null +++ b/devtools/create_titanic/file.h @@ -0,0 +1,215 @@ +/* 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 __FILE_H__ +#define __FILE_H__ + +#include <stdio.h> +#include <stdlib.h> + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/scummsys.h" +#include "common/endian.h" +#include "common/algorithm.h" + +namespace Common { + +enum AccessMode { + kFileReadMode = 1, + kFileWriteMode = 2 +}; + +class File { +private: + ::FILE *_f; + const byte *_memPtr; + size_t _offset, _size; +public: + File() : _f(nullptr), _memPtr(nullptr), _offset(0), _size(0) {} + + bool open(const char *filename, AccessMode mode = kFileReadMode) { + _memPtr = nullptr; + _f = fopen(filename, (mode == kFileReadMode) ? "rb" : "wb+"); + return (_f != NULL); + } + bool open(const byte *data, uint size) { + close(); + _f = nullptr; + _memPtr = data; + _size = size; + return true; + } + + void close() { + if (_f) + fclose(_f); + _f = nullptr; + delete[] _memPtr; + _memPtr = nullptr; + } + int seek(int offset, int whence = SEEK_SET) { + if (_f) + return fseek(_f, offset, whence); + + switch (whence) { + case SEEK_SET: + _offset = offset; + break; + case SEEK_CUR: + _offset += offset; + break; + case SEEK_END: + _offset = _size + offset; + break; + default: + break; + } + + return _offset; + } + void skip(int offset) { + if (_f) + fseek(_f, offset, SEEK_CUR); + else + _offset += offset; + } + long read(void *buffer, size_t len) { + if (_f) + return fread(buffer, 1, len, _f); + + uint bytesToRead = CLIP(len, (size_t)0, _size - _offset); + memcpy(buffer, &_memPtr[_offset], bytesToRead); + _offset += bytesToRead; + return bytesToRead; + } + void write(const void *buffer, size_t len) { + assert(_f); + fwrite(buffer, 1, len, _f); + } + void write(File &src, size_t len) { + for (size_t idx = 0; idx < len; ++idx) + writeByte(src.readByte()); + } + byte readByte() { + byte v; + read(&v, sizeof(byte)); + return v; + } + uint16 readWord() { + uint16 v; + read(&v, sizeof(uint16)); + return FROM_LE_16(v); + } + uint readLong() { + uint v; + read(&v, sizeof(uint)); + return FROM_LE_32(v); + } + + uint readUint16BE() { + uint16 v; + read(&v, sizeof(uint16)); + return FROM_BE_16(v); + } + uint readUint16LE() { + uint16 v; + read(&v, sizeof(uint16)); + return FROM_LE_16(v); + } + uint readUint32BE() { + uint32 v; + read(&v, sizeof(uint32)); + return FROM_BE_32(v); + } + uint readUint32LE() { + uint32 v; + read(&v, sizeof(uint32)); + return FROM_LE_32(v); + } + + void writeByte(byte v) { + write(&v, sizeof(byte)); + } + void writeByte(byte v, int len) { + byte *b = new byte[len]; + memset(b, v, len); + write(b, len); + delete[] b; + } + void writeWord(uint16 v) { + uint16 vTemp = TO_LE_16(v); + write(&vTemp, sizeof(uint16)); + } + void writeLong(uint v) { + uint vTemp = TO_LE_32(v); + write(&vTemp, sizeof(uint)); + } + void writeString(const char *msg) { + if (!msg) { + writeByte(0); + } else { + do { + writeByte(*msg); + } while (*msg++); + } + } + void writeString(File &src) { + char c; + do { + c = src.readByte(); + writeByte(c); + } while (c); + } + uint pos() const { + if (_f) + return ftell(_f); + else + return _offset; + } + uint size() const { + if (_f) { + uint currentPos = pos(); + fseek(_f, 0, SEEK_END); + uint result = pos(); + fseek(_f, currentPos, SEEK_SET); + return result; + } else if (_memPtr) { + return _size; + } else { + return 0; + } + } + bool eof() const { + if (_f) + return feof(_f) != 0; + else if (_memPtr) + return _offset >= _size; + return false; + } +}; + +} + +extern Common::File inputFile, outputFile; + +#endif diff --git a/devtools/create_titanic/hash-str.h b/devtools/create_titanic/hash-str.h new file mode 100644 index 0000000000..b9f6d503f8 --- /dev/null +++ b/devtools/create_titanic/hash-str.h @@ -0,0 +1,86 @@ +/* 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 COMMON_HASH_STR_H +#define COMMON_HASH_STR_H + +#include "hashmap.h" +#include "str.h" + +namespace Common { + +uint hashit(const char *str); +uint hashit_lower(const char *str); // Generate a hash based on the lowercase version of the string +inline uint hashit(const String &str) { return hashit(str.c_str()); } +inline uint hashit_lower(const String &str) { return hashit_lower(str.c_str()); } + + +// FIXME: The following functors obviously are not consistently named + +struct CaseSensitiveString_EqualTo { + bool operator()(const String& x, const String& y) const { return x.equals(y); } +}; + +struct CaseSensitiveString_Hash { + uint operator()(const String& x) const { return hashit(x.c_str()); } +}; + + +struct IgnoreCase_EqualTo { + bool operator()(const String& x, const String& y) const { return x.equalsIgnoreCase(y); } +}; + +struct IgnoreCase_Hash { + uint operator()(const String& x) const { return hashit_lower(x.c_str()); } +}; + + + +// Specalization of the Hash functor for String objects. +// We do case sensitve hashing here, because that is what +// the default EqualTo is compatible with. If one wants to use +// case insensitve hashing, then only because one wants to use +// IgnoreCase_EqualTo, and then one has to specify a custom +// hash anyway. +template<> +struct Hash<String> { + uint operator()(const String& s) const { + return hashit(s.c_str()); + } +}; + +template<> +struct Hash<const char *> { + uint operator()(const char *s) const { + return hashit(s); + } +}; + +// String map -- by default case insensitive +typedef HashMap<String, String, IgnoreCase_Hash, IgnoreCase_EqualTo> StringMap; + + + +} // End of namespace Common + + +#endif diff --git a/devtools/create_titanic/hashmap.cpp b/devtools/create_titanic/hashmap.cpp new file mode 100644 index 0000000000..99840993ce --- /dev/null +++ b/devtools/create_titanic/hashmap.cpp @@ -0,0 +1,109 @@ +/* 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. + * + */ + +// The hash map (associative array) implementation in this file is +// based on the PyDict implementation of CPython. The erase() method +// is based on example code in the Wikipedia article on Hash tables. + +#include "common/hashmap.h" + +namespace Common { + +// Hash function for strings, taken from CPython. +uint hashit(const char *p) { + uint hash = *p << 7; + byte c; + int size = 0; + while ((c = *p++)) { + hash = (1000003 * hash) ^ c; + size++; + } + return hash ^ size; +} + +// Like hashit, but converts every char to lowercase before hashing. +uint hashit_lower(const char *p) { + uint hash = tolower(*p) << 7; + byte c; + int size = 0; + while ((c = *p++)) { + hash = (1000003 * hash) ^ tolower(c); + size++; + } + return hash ^ size; +} + +#ifdef DEBUG_HASH_COLLISIONS +static double + g_collisions = 0, + g_dummyHits = 0, + g_lookups = 0, + g_collPerLook = 0, + g_capacity = 0, + g_size = 0; +static int g_max_capacity = 0, g_max_size = 0; +static int g_totalHashmaps = 0; +static int g_stats[4] = {0,0,0,0}; + +void updateHashCollisionStats(int collisions, int dummyHits, int lookups, int arrsize, int nele) { + g_collisions += collisions; + g_lookups += lookups; + g_dummyHits += dummyHits; + if (lookups) + g_collPerLook += (double)collisions / (double)lookups; + g_capacity += arrsize; + g_size += nele; + g_totalHashmaps++; + + if (3*nele <= 2*8) + g_stats[0]++; + if (3*nele <= 2*16) + g_stats[1]++; + if (3*nele <= 2*32) + g_stats[2]++; + if (3*nele <= 2*64) + g_stats[3]++; + + g_max_capacity = MAX(g_max_capacity, arrsize); + g_max_size = MAX(g_max_size, nele); + + debug("%d hashmaps: colls %.1f; dummies hit %.1f, lookups %.1f; ratio %.3f%%; size %f (max: %d); capacity %f (max: %d)", + g_totalHashmaps, + g_collisions / g_totalHashmaps, + g_dummyHits / g_totalHashmaps, + g_lookups / g_totalHashmaps, + 100 * g_collPerLook / g_totalHashmaps, + g_size / g_totalHashmaps, g_max_size, + g_capacity / g_totalHashmaps, g_max_capacity); + debug(" %d less than %d; %d less than %d; %d less than %d; %d less than %d", + g_stats[0], 2*8/3, + g_stats[1],2*16/3, + g_stats[2],2*32/3, + g_stats[3],2*64/3); + + // TODO: + // * Should record the maximal size of the map during its lifetime, not that at its death + // * Should do some statistics: how many maps are less than 2/3*8, 2/3*16, 2/3*32, ... +} +#endif + +} // End of namespace Common diff --git a/devtools/create_titanic/hashmap.h b/devtools/create_titanic/hashmap.h new file mode 100644 index 0000000000..c8691aeb42 --- /dev/null +++ b/devtools/create_titanic/hashmap.h @@ -0,0 +1,637 @@ +/* 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. + * + */ + +// The hash map (associative array) implementation in this file is +// based on the PyDict implementation of CPython. + +#ifndef COMMON_HASHMAP_H +#define COMMON_HASHMAP_H + +/** + * @def DEBUG_HASH_COLLISIONS + * Enable the following #define if you want to check how many collisions the + * code produces (many collisions indicate either a bad hash function, or a + * hash table that is too small). + */ +//#define DEBUG_HASH_COLLISIONS + +/** + * @def USE_HASHMAP_MEMORY_POOL + * Enable the following define to let HashMaps use a memory pool for the + nodes they contain. * This increases memory usage, but also can improve + speed quite a bit. + */ +#define USE_HASHMAP_MEMORY_POOL + + +#include "common/func.h" + +#ifdef DEBUG_HASH_COLLISIONS +#include "common/debug.h" +#endif + +#ifdef USE_HASHMAP_MEMORY_POOL +#include "memorypool.h" +#endif + + + +namespace Common { + +// The sgi IRIX MIPSpro Compiler has difficulties with nested templates. +// This and the other __sgi conditionals below work around these problems. +// The Intel C++ Compiler suffers from the same problems. +#if (defined(__sgi) && !defined(__GNUC__)) || defined(__INTEL_COMPILER) +template<class T> class IteratorImpl; +#endif + + +/** + * HashMap<Key,Val> maps objects of type Key to objects of type Val. + * For each used Key type, we need an "size_type hashit(Key,size_type)" function + * that computes a hash for the given Key object and returns it as an + * an integer from 0 to hashsize-1, and also an "equality functor". + * that returns true if if its two arguments are to be considered + * equal. Also, we assume that "=" works on Val objects for assignment. + * + * If aa is an HashMap<Key,Val>, then space is allocated each time aa[key] is + * referenced, for a new key. If the object is const, then an assertion is + * triggered instead. Hence if you are not sure whether a key is contained in + * the map, use contains() first to check for its presence. + */ +template<class Key, class Val, class HashFunc = Hash<Key>, class EqualFunc = EqualTo<Key> > +class HashMap { +public: + typedef uint size_type; + +private: + + typedef HashMap<Key, Val, HashFunc, EqualFunc> HM_t; + + struct Node { + const Key _key; + Val _value; + explicit Node(const Key &key) : _key(key), _value() {} + Node() : _key(), _value() {} + }; + + enum { + HASHMAP_PERTURB_SHIFT = 5, + HASHMAP_MIN_CAPACITY = 16, + + // The quotient of the next two constants controls how much the + // internal storage of the hashmap may fill up before being + // increased automatically. + // Note: the quotient of these two must be between and different + // from 0 and 1. + HASHMAP_LOADFACTOR_NUMERATOR = 2, + HASHMAP_LOADFACTOR_DENOMINATOR = 3, + + HASHMAP_MEMORYPOOL_SIZE = HASHMAP_MIN_CAPACITY * HASHMAP_LOADFACTOR_NUMERATOR / HASHMAP_LOADFACTOR_DENOMINATOR + }; + +#ifdef USE_HASHMAP_MEMORY_POOL + ObjectPool<Node, HASHMAP_MEMORYPOOL_SIZE> _nodePool; +#endif + + Node **_storage; ///< hashtable of size arrsize. + size_type _mask; ///< Capacity of the HashMap minus one; must be a power of two of minus one + size_type _size; + size_type _deleted; ///< Number of deleted elements (_dummyNodes) + + HashFunc _hash; + EqualFunc _equal; + + /** Default value, returned by the const getVal. */ + const Val _defaultVal; + + /** Dummy node, used as marker for erased objects. */ + #define HASHMAP_DUMMY_NODE ((Node *)1) + +#ifdef DEBUG_HASH_COLLISIONS + mutable int _collisions, _lookups, _dummyHits; +#endif + + Node *allocNode(const Key &key) { +#ifdef USE_HASHMAP_MEMORY_POOL + return new (_nodePool) Node(key); +#else + return new Node(key); +#endif + } + + void freeNode(Node *node) { + if (node && node != HASHMAP_DUMMY_NODE) +#ifdef USE_HASHMAP_MEMORY_POOL + _nodePool.deleteChunk(node); +#else + delete node; +#endif + } + + void assign(const HM_t &map); + size_type lookup(const Key &key) const; + size_type lookupAndCreateIfMissing(const Key &key); + void expandStorage(size_type newCapacity); + +#if !defined(__sgi) || defined(__GNUC__) + template<class T> friend class IteratorImpl; +#endif + + /** + * Simple HashMap iterator implementation. + */ + template<class NodeType> + class IteratorImpl { + friend class HashMap; +#if (defined(__sgi) && !defined(__GNUC__)) || defined(__INTEL_COMPILER) + template<class T> friend class Common::IteratorImpl; +#else + template<class T> friend class IteratorImpl; +#endif + protected: + typedef const HashMap hashmap_t; + + size_type _idx; + hashmap_t *_hashmap; + + protected: + IteratorImpl(size_type idx, hashmap_t *hashmap) : _idx(idx), _hashmap(hashmap) {} + + NodeType *deref() const { + assert(_hashmap != 0); + assert(_idx <= _hashmap->_mask); + Node *node = _hashmap->_storage[_idx]; + assert(node != 0); + assert(node != HASHMAP_DUMMY_NODE); + return node; + } + + public: + IteratorImpl() : _idx(0), _hashmap(0) {} + template<class T> + IteratorImpl(const IteratorImpl<T> &c) : _idx(c._idx), _hashmap(c._hashmap) {} + + NodeType &operator*() const { return *deref(); } + NodeType *operator->() const { return deref(); } + + bool operator==(const IteratorImpl &iter) const { return _idx == iter._idx && _hashmap == iter._hashmap; } + bool operator!=(const IteratorImpl &iter) const { return !(*this == iter); } + + IteratorImpl &operator++() { + assert(_hashmap); + do { + _idx++; + } while (_idx <= _hashmap->_mask && (_hashmap->_storage[_idx] == 0 || _hashmap->_storage[_idx] == HASHMAP_DUMMY_NODE)); + if (_idx > _hashmap->_mask) + _idx = (size_type)-1; + + return *this; + } + + IteratorImpl operator++(int) { + IteratorImpl old = *this; + operator ++(); + return old; + } + }; + +public: + typedef IteratorImpl<Node> iterator; + typedef IteratorImpl<const Node> const_iterator; + + HashMap(); + HashMap(const HM_t &map); + ~HashMap(); + + HM_t &operator=(const HM_t &map) { + if (this == &map) + return *this; + + // Remove the previous content and ... + clear(); + delete[] _storage; + // ... copy the new stuff. + assign(map); + return *this; + } + + bool contains(const Key &key) const; + + Val &operator[](const Key &key); + const Val &operator[](const Key &key) const; + + Val &getVal(const Key &key); + const Val &getVal(const Key &key) const; + const Val &getVal(const Key &key, const Val &defaultVal) const; + void setVal(const Key &key, const Val &val); + + void clear(bool shrinkArray = 0); + + void erase(iterator entry); + void erase(const Key &key); + + size_type size() const { return _size; } + + iterator begin() { + // Find and return the first non-empty entry + for (size_type ctr = 0; ctr <= _mask; ++ctr) { + if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE) + return iterator(ctr, this); + } + return end(); + } + iterator end() { + return iterator((size_type)-1, this); + } + + const_iterator begin() const { + // Find and return the first non-empty entry + for (size_type ctr = 0; ctr <= _mask; ++ctr) { + if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE) + return const_iterator(ctr, this); + } + return end(); + } + const_iterator end() const { + return const_iterator((size_type)-1, this); + } + + iterator find(const Key &key) { + size_type ctr = lookup(key); + if (_storage[ctr]) + return iterator(ctr, this); + return end(); + } + + const_iterator find(const Key &key) const { + size_type ctr = lookup(key); + if (_storage[ctr]) + return const_iterator(ctr, this); + return end(); + } + + // TODO: insert() method? + + bool empty() const { + return (_size == 0); + } +}; + +//------------------------------------------------------- +// HashMap functions + +/** + * Base constructor, creates an empty hashmap. + */ +template<class Key, class Val, class HashFunc, class EqualFunc> +HashMap<Key, Val, HashFunc, EqualFunc>::HashMap() +// +// We have to skip _defaultVal() on PS2 to avoid gcc 3.2.2 ICE +// +#ifdef __PLAYSTATION2__ + { +#else + : _defaultVal() { +#endif + _mask = HASHMAP_MIN_CAPACITY - 1; + _storage = new Node *[HASHMAP_MIN_CAPACITY]; + assert(_storage != NULL); + memset(_storage, 0, HASHMAP_MIN_CAPACITY * sizeof(Node *)); + + _size = 0; + _deleted = 0; + +#ifdef DEBUG_HASH_COLLISIONS + _collisions = 0; + _lookups = 0; + _dummyHits = 0; +#endif +} + +/** + * Copy constructor, creates a full copy of the given hashmap. + * We must provide a custom copy constructor as we use pointers + * to heap buffers for the internal storage. + */ +template<class Key, class Val, class HashFunc, class EqualFunc> +HashMap<Key, Val, HashFunc, EqualFunc>::HashMap(const HM_t &map) : + _defaultVal() { +#ifdef DEBUG_HASH_COLLISIONS + _collisions = 0; + _lookups = 0; + _dummyHits = 0; +#endif + assign(map); +} + +/** + * Destructor, frees all used memory. + */ +template<class Key, class Val, class HashFunc, class EqualFunc> +HashMap<Key, Val, HashFunc, EqualFunc>::~HashMap() { + for (size_type ctr = 0; ctr <= _mask; ++ctr) + freeNode(_storage[ctr]); + + delete[] _storage; +#ifdef DEBUG_HASH_COLLISIONS + extern void updateHashCollisionStats(int, int, int, int, int); + updateHashCollisionStats(_collisions, _dummyHits, _lookups, _mask+1, _size); +#endif +} + +/** + * Internal method for assigning the content of another HashMap + * to this one. + * + * @note We do *not* deallocate the previous storage here -- the caller is + * responsible for doing that! + */ +template<class Key, class Val, class HashFunc, class EqualFunc> +void HashMap<Key, Val, HashFunc, EqualFunc>::assign(const HM_t &map) { + _mask = map._mask; + _storage = new Node *[_mask+1]; + assert(_storage != NULL); + memset(_storage, 0, (_mask+1) * sizeof(Node *)); + + // Simply clone the map given to us, one by one. + _size = 0; + _deleted = 0; + for (size_type ctr = 0; ctr <= _mask; ++ctr) { + if (map._storage[ctr] == HASHMAP_DUMMY_NODE) { + _storage[ctr] = HASHMAP_DUMMY_NODE; + _deleted++; + } else if (map._storage[ctr] != NULL) { + _storage[ctr] = allocNode(map._storage[ctr]->_key); + _storage[ctr]->_value = map._storage[ctr]->_value; + _size++; + } + } + // Perform a sanity check (to help track down hashmap corruption) + assert(_size == map._size); + assert(_deleted == map._deleted); +} + + +template<class Key, class Val, class HashFunc, class EqualFunc> +void HashMap<Key, Val, HashFunc, EqualFunc>::clear(bool shrinkArray) { + for (size_type ctr = 0; ctr <= _mask; ++ctr) { + freeNode(_storage[ctr]); + _storage[ctr] = NULL; + } + +#ifdef USE_HASHMAP_MEMORY_POOL + _nodePool.freeUnusedPages(); +#endif + + if (shrinkArray && _mask >= HASHMAP_MIN_CAPACITY) { + delete[] _storage; + + _mask = HASHMAP_MIN_CAPACITY; + _storage = new Node *[HASHMAP_MIN_CAPACITY]; + assert(_storage != NULL); + memset(_storage, 0, HASHMAP_MIN_CAPACITY * sizeof(Node *)); + } + + _size = 0; + _deleted = 0; +} + +template<class Key, class Val, class HashFunc, class EqualFunc> +void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(size_type newCapacity) { + assert(newCapacity > _mask+1); + +#ifndef NDEBUG + const size_type old_size = _size; +#endif + const size_type old_mask = _mask; + Node **old_storage = _storage; + + // allocate a new array + _size = 0; + _deleted = 0; + _mask = newCapacity - 1; + _storage = new Node *[newCapacity]; + assert(_storage != NULL); + memset(_storage, 0, newCapacity * sizeof(Node *)); + + // rehash all the old elements + for (size_type ctr = 0; ctr <= old_mask; ++ctr) { + if (old_storage[ctr] == NULL || old_storage[ctr] == HASHMAP_DUMMY_NODE) + continue; + + // Insert the element from the old table into the new table. + // Since we know that no key exists twice in the old table, we + // can do this slightly better than by calling lookup, since we + // don't have to call _equal(). + const size_type hash = _hash(old_storage[ctr]->_key); + size_type idx = hash & _mask; + for (size_type perturb = hash; _storage[idx] != NULL && _storage[idx] != HASHMAP_DUMMY_NODE; perturb >>= HASHMAP_PERTURB_SHIFT) { + idx = (5 * idx + perturb + 1) & _mask; + } + + _storage[idx] = old_storage[ctr]; + _size++; + } + + // Perform a sanity check: Old number of elements should match the new one! + // This check will fail if some previous operation corrupted this hashmap. + assert(_size == old_size); + + delete[] old_storage; + + return; +} + +template<class Key, class Val, class HashFunc, class EqualFunc> +typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, HashFunc, EqualFunc>::lookup(const Key &key) const { + const size_type hash = _hash(key); + size_type ctr = hash & _mask; + for (size_type perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) { + if (_storage[ctr] == NULL) + break; + if (_storage[ctr] == HASHMAP_DUMMY_NODE) { +#ifdef DEBUG_HASH_COLLISIONS + _dummyHits++; +#endif + } else if (_equal(_storage[ctr]->_key, key)) + break; + + ctr = (5 * ctr + perturb + 1) & _mask; + +#ifdef DEBUG_HASH_COLLISIONS + _collisions++; +#endif + } + +#ifdef DEBUG_HASH_COLLISIONS + _lookups++; + debug("collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d", + _collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups), + (const void *)this, _mask+1, _size); +#endif + + return ctr; +} + +template<class Key, class Val, class HashFunc, class EqualFunc> +typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key &key) { + const size_type hash = _hash(key); + size_type ctr = hash & _mask; + const size_type NONE_FOUND = _mask + 1; + size_type first_free = NONE_FOUND; + bool found = false; + for (size_type perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) { + if (_storage[ctr] == NULL) + break; + if (_storage[ctr] == HASHMAP_DUMMY_NODE) { +#ifdef DEBUG_HASH_COLLISIONS + _dummyHits++; +#endif + if (first_free != _mask + 1) + first_free = ctr; + } else if (_equal(_storage[ctr]->_key, key)) { + found = true; + break; + } + + ctr = (5 * ctr + perturb + 1) & _mask; + +#ifdef DEBUG_HASH_COLLISIONS + _collisions++; +#endif + } + +#ifdef DEBUG_HASH_COLLISIONS + _lookups++; + debug("collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d", + _collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups), + (const void *)this, _mask+1, _size); +#endif + + if (!found && first_free != _mask + 1) + ctr = first_free; + + if (!found) { + if (_storage[ctr]) + _deleted--; + _storage[ctr] = allocNode(key); + assert(_storage[ctr] != NULL); + _size++; + + // Keep the load factor below a certain threshold. + // Deleted nodes are also counted + size_type capacity = _mask + 1; + if ((_size + _deleted) * HASHMAP_LOADFACTOR_DENOMINATOR > + capacity * HASHMAP_LOADFACTOR_NUMERATOR) { + capacity = capacity < 500 ? (capacity * 4) : (capacity * 2); + expandStorage(capacity); + ctr = lookup(key); + assert(_storage[ctr] != NULL); + } + } + + return ctr; +} + + +template<class Key, class Val, class HashFunc, class EqualFunc> +bool HashMap<Key, Val, HashFunc, EqualFunc>::contains(const Key &key) const { + size_type ctr = lookup(key); + return (_storage[ctr] != NULL); +} + +template<class Key, class Val, class HashFunc, class EqualFunc> +Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) { + return getVal(key); +} + +template<class Key, class Val, class HashFunc, class EqualFunc> +const Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) const { + return getVal(key); +} + +template<class Key, class Val, class HashFunc, class EqualFunc> +Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) { + size_type ctr = lookupAndCreateIfMissing(key); + assert(_storage[ctr] != NULL); + return _storage[ctr]->_value; +} + +template<class Key, class Val, class HashFunc, class EqualFunc> +const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) const { + return getVal(key, _defaultVal); +} + +template<class Key, class Val, class HashFunc, class EqualFunc> +const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key, const Val &defaultVal) const { + size_type ctr = lookup(key); + if (_storage[ctr] != NULL) + return _storage[ctr]->_value; + else + return defaultVal; +} + +template<class Key, class Val, class HashFunc, class EqualFunc> +void HashMap<Key, Val, HashFunc, EqualFunc>::setVal(const Key &key, const Val &val) { + size_type ctr = lookupAndCreateIfMissing(key); + assert(_storage[ctr] != NULL); + _storage[ctr]->_value = val; +} + +template<class Key, class Val, class HashFunc, class EqualFunc> +void HashMap<Key, Val, HashFunc, EqualFunc>::erase(iterator entry) { + // Check whether we have a valid iterator + assert(entry._hashmap == this); + const size_type ctr = entry._idx; + assert(ctr <= _mask); + Node * const node = _storage[ctr]; + assert(node != NULL); + assert(node != HASHMAP_DUMMY_NODE); + + // If we remove a key, we replace it with a dummy node. + freeNode(node); + _storage[ctr] = HASHMAP_DUMMY_NODE; + _size--; + _deleted++; +} + +template<class Key, class Val, class HashFunc, class EqualFunc> +void HashMap<Key, Val, HashFunc, EqualFunc>::erase(const Key &key) { + + size_type ctr = lookup(key); + if (_storage[ctr] == NULL) + return; + + // If we remove a key, we replace it with a dummy node. + freeNode(_storage[ctr]); + _storage[ctr] = HASHMAP_DUMMY_NODE; + _size--; + _deleted++; + return; +} + +#undef HASHMAP_DUMMY_NODE + +} // End of namespace Common + +#endif diff --git a/devtools/create_titanic/memorypool.cpp b/devtools/create_titanic/memorypool.cpp new file mode 100644 index 0000000000..13c640b6ad --- /dev/null +++ b/devtools/create_titanic/memorypool.cpp @@ -0,0 +1,182 @@ +/* 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 "memorypool.h" +#include "common/util.h" + +namespace Common { + +enum { + INITIAL_CHUNKS_PER_PAGE = 8 +}; + +static size_t adjustChunkSize(size_t chunkSize) { + // You must at least fit the pointer in the node (technically unneeded considering the next rounding statement) + chunkSize = MAX(chunkSize, sizeof(void *)); + // There might be an alignment problem on some platforms when trying to load a void* on a non natural boundary + // so we round to the next sizeof(void *) + chunkSize = (chunkSize + sizeof(void *) - 1) & (~(sizeof(void *) - 1)); + + return chunkSize; +} + + +MemoryPool::MemoryPool(size_t chunkSize) + : _chunkSize(adjustChunkSize(chunkSize)) { + + _next = NULL; + + _chunksPerPage = INITIAL_CHUNKS_PER_PAGE; +} + +MemoryPool::~MemoryPool() { +#if 0 + freeUnusedPages(); + if (!_pages.empty()) + warning("Memory leak found in pool"); +#endif + + for (size_t i = 0; i < _pages.size(); ++i) + ::free(_pages[i].start); +} + +void MemoryPool::allocPage() { + Page page; + + // Allocate a new page + page.numChunks = _chunksPerPage; + assert(page.numChunks * _chunkSize < 16*1024*1024); // Refuse to allocate pages bigger than 16 MB + + page.start = ::malloc(page.numChunks * _chunkSize); + assert(page.start); + _pages.push_back(page); + + + // Next time, we'll allocate a page twice as big as this one. + _chunksPerPage *= 2; + + // Add the page to the pool of free chunk + addPageToPool(page); +} + +void MemoryPool::addPageToPool(const Page &page) { + // Add all chunks of the new page to the linked list (pool) of free chunks + void *current = page.start; + for (size_t i = 1; i < page.numChunks; ++i) { + void *next = (byte *)current + _chunkSize; + *(void **)current = next; + + current = next; + } + + // Last chunk points to the old _next + *(void **)current = _next; + + // From now on, the first free chunk is the first chunk of the new page + _next = page.start; +} + +void *MemoryPool::allocChunk() { + // No free chunks left? Allocate a new page + if (!_next) + allocPage(); + + assert(_next); + void *result = _next; + _next = *(void **)result; + return result; +} + +void MemoryPool::freeChunk(void *ptr) { + // Add the chunk back to (the start of) the list of free chunks + *(void **)ptr = _next; + _next = ptr; +} + +// Technically not compliant C++ to compare unrelated pointers. In practice... +bool MemoryPool::isPointerInPage(void *ptr, const Page &page) { + return (ptr >= page.start) && (ptr < (char *)page.start + page.numChunks * _chunkSize); +} + +void MemoryPool::freeUnusedPages() { + //std::sort(_pages.begin(), _pages.end()); + Array<size_t> numberOfFreeChunksPerPage; + numberOfFreeChunksPerPage.resize(_pages.size()); + for (size_t i = 0; i < numberOfFreeChunksPerPage.size(); ++i) { + numberOfFreeChunksPerPage[i] = 0; + } + + // Compute for each page how many chunks in it are still in use. + void *iterator = _next; + while (iterator) { + // TODO: This should be a binary search (requiring us to keep _pages sorted) + for (size_t i = 0; i < _pages.size(); ++i) { + if (isPointerInPage(iterator, _pages[i])) { + ++numberOfFreeChunksPerPage[i]; + break; + } + } + + iterator = *(void **)iterator; + } + + // Free all pages which are not in use. + size_t freedPagesCount = 0; + for (size_t i = 0; i < _pages.size(); ++i) { + if (numberOfFreeChunksPerPage[i] == _pages[i].numChunks) { + // Remove all chunks of this page from the list of free chunks + void **iter2 = &_next; + while (*iter2) { + if (isPointerInPage(*iter2, _pages[i])) + *iter2 = **(void ***)iter2; + else + iter2 = *(void ***)iter2; + } + + ::free(_pages[i].start); + ++freedPagesCount; + _pages[i].start = NULL; + } + } + +// debug("freed %d pages out of %d", (int)freedPagesCount, (int)_pages.size()); + + // Remove all now unused pages + size_t newSize = 0; + for (size_t i = 0; i < _pages.size(); ++i) { + if (_pages[i].start != NULL) { + if (newSize != i) + _pages[newSize] = _pages[i]; + ++newSize; + } + } + _pages.resize(newSize); + + // Reset _chunksPerPage + _chunksPerPage = INITIAL_CHUNKS_PER_PAGE; + for (size_t i = 0; i < _pages.size(); ++i) { + if (_chunksPerPage < _pages[i].numChunks) + _chunksPerPage = _pages[i].numChunks; + } +} + +} // End of namespace Common diff --git a/devtools/create_titanic/memorypool.h b/devtools/create_titanic/memorypool.h new file mode 100644 index 0000000000..c8a8fc7a53 --- /dev/null +++ b/devtools/create_titanic/memorypool.h @@ -0,0 +1,162 @@ +/* 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 COMMON_MEMORYPOOL_H +#define COMMON_MEMORYPOOL_H + +#include "common/array.h" + + +namespace Common { + +/** + * This class provides a pool of memory 'chunks' of identical size. + * The size of a chunk is determined when creating the memory pool. + * + * Using a memory pool may yield better performance and memory usage + * when allocating and deallocating many memory blocks of equal size. + * E.g. the Common::String class uses a memory pool for the refCount + * variables (each the size of an int) it allocates for each string + * instance. + */ +class MemoryPool { +protected: + MemoryPool(const MemoryPool&); + MemoryPool& operator=(const MemoryPool&); + + struct Page { + void *start; + size_t numChunks; + }; + + const size_t _chunkSize; + Array<Page> _pages; + void *_next; + size_t _chunksPerPage; + + void allocPage(); + void addPageToPool(const Page &page); + bool isPointerInPage(void *ptr, const Page &page); + +public: + /** + * Constructor for a memory pool with the given chunk size. + * @param chunkSize the chunk size of this memory pool + */ + explicit MemoryPool(size_t chunkSize); + ~MemoryPool(); + + /** + * Allocate a new chunk from the memory pool. + */ + void *allocChunk(); + /** + * Return a chunk to the memory pool. The given pointer must have + * been obtained from calling the allocChunk() method of the very + * same MemoryPool instance. Passing any other pointer (e.g. to + * a chunk from another MemoryPool, or a malloc'ed memory block) + * will lead to undefined behavior and may result in a crash (if + * you are lucky) or in silent data corruption. + */ + void freeChunk(void *ptr); + + /** + * Perform garbage collection. The memory pool stores all the + * chunks it manages in memory 'pages' obtained via the classic + * memory allocation APIs (i.e. malloc/free). Ordinarily, once + * a page has been allocated, it won't be released again during + * the life time of the memory pool. The exception is when this + * method is called. + */ + void freeUnusedPages(); + + /** + * Return the chunk size used by this memory pool. + */ + size_t getChunkSize() const { return _chunkSize; } +}; + +/** + * This is a memory pool which already contains in itself some storage + * space for a fixed number of chunks. Thus if the memory pool is only + * lightly used, no malloc() calls have to be made at all. + */ +template<size_t CHUNK_SIZE, size_t NUM_INTERNAL_CHUNKS = 32> +class FixedSizeMemoryPool : public MemoryPool { +private: + enum { + REAL_CHUNK_SIZE = (CHUNK_SIZE + sizeof(void *) - 1) & (~(sizeof(void *) - 1)) + }; + + byte _storage[NUM_INTERNAL_CHUNKS * REAL_CHUNK_SIZE]; +public: + FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) { + assert(REAL_CHUNK_SIZE == _chunkSize); + // Insert some static storage + Page internalPage = { _storage, NUM_INTERNAL_CHUNKS }; + addPageToPool(internalPage); + } +}; + +// Ensure NUM_INTERNAL_CHUNKS == 0 results in a compile error +template<size_t CHUNK_SIZE> +class FixedSizeMemoryPool<CHUNK_SIZE,0> : public MemoryPool { +public: + FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) {} +}; + +/** + * A memory pool for C++ objects. + */ +template<class T, size_t NUM_INTERNAL_CHUNKS = 32> +class ObjectPool : public FixedSizeMemoryPool<sizeof(T), NUM_INTERNAL_CHUNKS> { +public: + /** + * Return the memory chunk used as storage for the given object back + * to the pool, after calling its destructor. + */ + void deleteChunk(T *ptr) { + ptr->~T(); + this->freeChunk(ptr); + } +}; + +} // End of namespace Common + +/** + * A custom placement new operator, using an arbitrary MemoryPool. + * + * This *should* work with all C++ implementations, but may not. + * + * For details on using placement new for custom allocators, see e.g. + * <http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14> + */ +inline void *operator new(size_t nbytes, Common::MemoryPool &pool) { + assert(nbytes <= pool.getChunkSize()); + return pool.allocChunk(); +} + +inline void operator delete(void *p, Common::MemoryPool &pool) { + pool.freeChunk(p); +} + +#endif diff --git a/devtools/create_titanic/module.mk b/devtools/create_titanic/module.mk new file mode 100644 index 0000000000..9f77866d45 --- /dev/null +++ b/devtools/create_titanic/module.mk @@ -0,0 +1,22 @@ + +MODULE := devtools/create_titanic + +MODULE_OBJS := \ + create_titanic_dat.o \ + hashmap.o \ + memorypool.o \ + script_preresponses.o \ + script_quotes.o \ + script_ranges.o \ + script_responses.o \ + script_states.o \ + str.o \ + tag_maps.o \ + winexe.o \ + winexe_pe.o + +# Set the name of the executable +TOOL_EXECUTABLE := create_titanic + +# Include common rules +include $(srcdir)/rules.mk diff --git a/devtools/create_titanic/script_preresponses.cpp b/devtools/create_titanic/script_preresponses.cpp new file mode 100644 index 0000000000..d906015296 --- /dev/null +++ b/devtools/create_titanic/script_preresponses.cpp @@ -0,0 +1,156 @@ +/* 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. + * + */ + + // Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +// HACK to allow building with the SDL backend on MinGW +// see bug #1800764 "TOOLS: MinGW tools building broken" +#ifdef main +#undef main +#endif // main + +#include "file.h" +#include "script_preresponses.h" + +static const PreResponse BARBOT_PRERESPONSES[] = { + { 0x0000CA02, 0x0003D102 }, + { 0x0000CA68, 0x0003D102 }, + { 0x0000C9DA, 0x0003D102 }, + { 0x0000CA6A, 0x0003D103 }, + { 0x0000C922, 0x0003D099 }, + { 0x0000C97C, 0x0003D099 }, + { 0x0000CA0B, 0x0003D099 }, + { 0x0000CA72, 0x0003D099 }, + { 0x0000CA0E, 0x0003D107 }, + { 0x0000CA73, 0x0003D107 }, + { 0x0000CA12, 0x0003D108 }, + { 0x0000CA1C, 0x0003D10E }, + { 0x0000CA83, 0x0003D10E }, + { 0x0000CA1F, 0x0003D110 }, + { 0x0000CA86, 0x0003D110 }, + { 0x0000CA23, 0x0003D112 }, + { 0x0000CA8A, 0x0003D112 }, + { 0x0000CA92, 0x0003D122 }, + { 0x0000CA30, 0x0003D116 }, + { 0x0000CA96, 0x0003D116 }, + { 0x0000CA36, 0x0003D117 }, + { 0x0000C9FC, 0x0003D117 }, + { 0x0000CA9B, 0x0003D117 }, + { 0x0000CA63, 0x0003D117 }, + { 0x0000CA38, 0x0003D11B }, + { 0x0000CA15, 0x0003D109 }, + { 0x0000CA7B, 0x0003D109 }, + { 0x0000CA2E, 0x0003D115 }, + { 0x0000CA94, 0x0003D115 }, + { 0x0000CA5C, 0x0003D115 }, + { 0x0000CA21, 0x0003D111 }, + { 0x0000CA88, 0x0003D111 }, + { 0x0000CA2A, 0x0003D114 }, + { 0x0000CA28, 0x0003D119 }, + { 0x0000CA8E, 0x0003D119 }, + { 0x0000CA17, 0x0003D10B }, + { 0x0000CA7D, 0x0003D10B }, + { 0x0000CA4C, 0x0003D10B }, + { 0x0000CA06, 0x0003D105 }, + { 0x0000CA6C, 0x0003D105 }, + { 0x0000CA0A, 0x0003D106 }, + { 0x0000CA70, 0x0003D106 }, + { 0x0000CA19, 0x0003D10C }, + { 0x0000CA7F, 0x0003D10C }, + { 0x0000C9FF, 0x0003D101 }, + { 0x0000CA65, 0x0003D101 }, + { 0x00000000, 0x00000000 } +}; + +static const PreResponse BELLBOT_PRERESPONSES[] = { + { 0x000052DC, 0x00030D40 }, + { 0x000054E9, 0x00030D40 }, + { 0x000054EC, 0x00030D40 }, + { 0x000054F0, 0x00030D40 }, + { 0x0000532C, 0x00031625 }, + { 0x00005330, 0x00031625 }, + { 0x00005368, 0x00031625 }, + { 0x00005369, 0x00031625 }, + { 0x0000536A, 0x00031625 }, + { 0x0000536B, 0x00031625 }, + { 0x0000536C, 0x00031625 }, + { 0x0000536D, 0x00031625 }, + { 0x000053A4, 0x00031625 }, + { 0x0000558A, 0x00031625 }, + { 0x00005485, 0x00031625 }, + { 0x00004EE7, 0x00031625 }, + { 0x00004EE8, 0x00031625 }, + { 0x0000530A, 0x00031625 }, + { 0x0000530B, 0x00031625 }, + { 0x000053F6, 0x00031625 }, + { 0x000053F7, 0x00031625 }, + { 0x000053F8, 0x00031625 }, + { 0x000053F9, 0x00031625 }, + { 0x000053FA, 0x00031625 }, + { 0x000053FB, 0x00031625 }, + { 0x000053FC, 0x00031625 }, + { 0x000053FD, 0x00031625 }, + { 0x0000556B, 0x00031041 }, + { 0x00005499, 0x00030D40 }, + { 0x000053E9, 0x00030E01 }, + { 0x000053EB, 0x00030E01 }, + { 0x000053EC, 0x00030E01 }, + { 0x000053ED, 0x00030E01 }, + { 0x000053EE, 0x00030E01 }, + { 0x000053EF, 0x00030E01 }, + { 0x000053F0, 0x00030E01 }, + { 0x000053F1, 0x00030E01 }, + { 0x000053F2, 0x00030E01 }, + { 0x000053EA, 0x00030E01 }, + { 0x00005441, 0x00030F00 }, + { 0x00005444, 0x00030F00 }, + { 0x00005445, 0x00030F00 }, + { 0x00005443, 0x00030F00 }, + { 0x00005446, 0x00030F00 }, + { 0x00005447, 0x00030F00 }, + { 0x00005448, 0x00030F00 }, + { 0x00005449, 0x00030F00 }, + { 0x0000544A, 0x00030F00 }, + { 0x0000544B, 0x00030F00 }, + { 0x00005442, 0x00030F00 }, + { 0x0000527C, 0x000315C8 }, + { 0x00000000, 0x00000000 } +}; + +void writeScriptPreResponses(const char *name, const PreResponse *states) { + outputFile.seek(dataOffset); + + for (; states->_src; ++states) { + outputFile.writeLong(states->_src); + outputFile.writeLong(states->_dest); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader(name, dataOffset, size); + dataOffset += size; +} + +void writeAllScriptPreResponses() { + writeScriptPreResponses("PreResponses/Barbot", BARBOT_PRERESPONSES); + writeScriptPreResponses("PreResponses/Bellbot", BELLBOT_PRERESPONSES); +}
\ No newline at end of file diff --git a/devtools/create_titanic/script_preresponses.h b/devtools/create_titanic/script_preresponses.h new file mode 100644 index 0000000000..b4377be1c7 --- /dev/null +++ b/devtools/create_titanic/script_preresponses.h @@ -0,0 +1,37 @@ +/* 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 COMMON_SCRIPT_PRERESPONSES_H +#define COMMON_SCRIPT_PRERESPONSES_H + +#include "common/scummsys.h" + +struct PreResponse { + uint _src; + uint _dest; +}; + +extern void writeAllScriptPreResponses(); +extern void writeEntryHeader(const char *name, uint offset, uint size); +extern uint dataOffset; + +#endif diff --git a/devtools/create_titanic/script_quotes.cpp b/devtools/create_titanic/script_quotes.cpp new file mode 100644 index 0000000000..7e4838c338 --- /dev/null +++ b/devtools/create_titanic/script_quotes.cpp @@ -0,0 +1,457 @@ +/* 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. + * + */ + + // Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +// HACK to allow building with the SDL backend on MinGW +// see bug #1800764 "TOOLS: MinGW tools building broken" +#ifdef main +#undef main +#endif // main + +#include "file.h" +#include "script_quotes.h" + +static const ScriptQuote BARBOT_QUOTES[] = { + { 0x00000008, 0x00000000, 0x0003D372 }, + { 0x00000007, 0x00000000, 0x0003D72B }, + { 0x00000004, 0x00000000, 0x0003D722 }, + { 0x00000006, 0x00000000, 0x0003D264 }, + { 0x00000005, 0x00000000, 0x0003D72F }, + { 0x00000001, 0x00000032, 0x00000001 }, + { 0x00000002, 0x00000032, 0x00000001 }, + { 0x00000003, 0x00000032, 0x00000001 }, + { 0x00000010, 0x54524156, 0x0003D2B1 }, + { 0x00000010, 0x0000003C, 0x00000000 }, + { 0x00000011, 0x00000000, 0x0003D484 }, + { 0x00000015, 0x00000032, 0x0003D2B2 }, + { 0x00000012, 0x00000042, 0x0003D499 }, + { 0x00000013, 0x00000021, 0x0003D31E }, + { 0x0000001D, 0x00000021, 0x0003D31E }, + { 0x00000014, 0x00000042, 0x0003D49E }, + { 0x00000016, 0x0000003C, 0x0003D2B6 }, + { 0x00000017, 0x00000028, 0x0003D2B5 }, + { 0x00000018, 0x00000000, 0x0003D35E }, + { 0x00000019, 0x00000000, 0x0003D35E }, + { 0x0000001A, 0x0000003C, 0x0003D38B }, + { 0x0000001B, 0x00000000, 0x0003D2F8 }, + { 0x00000009, 0x00000019, 0x0003D326 }, + { 0x0000000A, 0x00000019, 0x0003D314 }, + { 0x0000000B, 0x00000028, 0x0003D311 }, + { 0x0000001E, 0x00000000, 0x0003D6F2 }, + { 0x0000001F, 0x00000000, 0x0003D26C }, + { 0x0000000C, 0x00000000, 0x0003D2F4 }, + { 0x0000000D, 0x00000000, 0x0003D2F4 }, + { 0x0000000E, 0x00000000, 0x0003D2F4 }, + { 0x0000000F, 0x00000000, 0x0003D2F4 }, + { 0x00000020, 0x00000019, 0x0003D389 }, + { 0x00000021, 0x0000000F, 0x0003D29C }, + { 0x00000022, 0x0000000F, 0x0003D494 }, + { 0x0000001C, 0x00000032, 0x00000000 }, + { 0x00000023, 0x00000000, 0x0003D7F8 }, + { 0x00000024, 0x00000000, 0x0003D7F9 }, + { 0x00000031, 0x00000000, 0x0003D722 }, + { 0x00000032, 0x00000000, 0x0003D722 }, + { 0x00000033, 0x00000000, 0x0003D372 }, + { 0x00000034, 0x00000000, 0x0003D323 }, + { 0x0000003E, 0x00000000, 0x0003D163 }, + { 0x0000003F, 0x00000000, 0x0003D163 }, + { 0x00000040, 0x00000000, 0x0003D163 }, + { 0x00000041, 0x00000000, 0x0003D691 }, + { 0x00000000, 0x00000000, 0x00000000 } +}; + +static const ScriptQuote BELLBOT_QUOTES[] = { + { 0x00000008, 0x00000000, 0x00031116 }, + { 0x00000007, 0x00000000, 0x00031447 }, + { 0x00000006, 0x00000000, 0x000310F9 }, + { 0x00000005, 0x00000000, 0x000313A1 }, + { 0x00000001, 0x56424144, 0x000313D7 }, + { 0x00000001, 0x52554445, 0x000313D7 }, + { 0x00000001, 0x5052534E, 0x00041EB3 }, + { 0x00000001, 0x424F5953, 0x00041EB3 }, + { 0x00000001, 0x4749524C, 0x00041EB3 }, + { 0x00000001, 0x464F4F44, 0x00041EB3 }, + { 0x00000001, 0x00000032, 0x00041EB1 }, + { 0x0000001C, 0x00000032, 0x00041EB0 }, + { 0x00000010, 0x54524156, 0x000313C6 }, + { 0x00000010, 0x0000003C, 0x00041EB0 }, + { 0x00000011, 0x00000000, 0x0003139E }, + { 0x00000015, 0x00000032, 0x0003139F }, + { 0x00000012, 0x00000042, 0x000313A0 }, + { 0x00000013, 0x00000021, 0x000313A7 }, + { 0x0000001D, 0x00000021, 0x000313A7 }, + { 0x00000014, 0x00000042, 0x000313A4 }, + { 0x0000001B, 0x00000000, 0x0003139B }, + { 0x0000001E, 0x00000000, 0x000313A2 }, + { 0x0000001F, 0x00000000, 0x00030DC0 }, + { 0x0000000C, 0x00000000, 0x000313A9 }, + { 0x0000000D, 0x00000000, 0x000313A9 }, + { 0x0000000E, 0x00000000, 0x000313A8 }, + { 0x0000000F, 0x00000000, 0x000313A8 }, + { 0x00000020, 0x00000019, 0x000313AB }, + { 0x00000021, 0x0000000F, 0x000313AC }, + { 0x00000023, 0x00000000, 0x00031337 }, + { 0x00000024, 0x00000000, 0x0003135A }, + { 0x00000025, 0x00000000, 0x000311AB }, + { 0x00000026, 0x00000000, 0x0003112E }, + { 0x00000030, 0x00000000, 0x0003106C }, + { 0x00000027, 0x424F5953, 0x0003140C }, + { 0x00000027, 0x4749524C, 0x0003140D }, + { 0x00000027, 0x00000000, 0x0003140D }, + { 0x00000028, 0x00000000, 0x00031404 }, + { 0x00000029, 0x00000000, 0x00031405 }, + { 0x0000002A, 0x00000000, 0x00031406 }, + { 0x0000002B, 0x00000000, 0x00031407 }, + { 0x0000002C, 0x00000000, 0x00031408 }, + { 0x0000002D, 0x00000000, 0x00031409 }, + { 0x0000002E, 0x424F5953, 0x0003140A }, + { 0x0000002E, 0x4749524C, 0x0003140B }, + { 0x0000002E, 0x00000000, 0x0003140B }, + { 0x00000032, 0x00000000, 0x000313D6 }, + { 0x00000033, 0x00000000, 0x000313D7 }, + { 0x00000034, 0x00000000, 0x000313D8 }, + { 0x00000035, 0x00000000, 0x0003113D }, + { 0x00000036, 0x00000000, 0x00030DCB }, + { 0x00000031, 0x00000000, 0x00030DB5 }, + { 0x00000037, 0x00000000, 0x000313DD }, + { 0x00000038, 0x00000000, 0x00030EE4 }, + { 0x00000039, 0x00000000, 0x0003160B }, + { 0x0000003A, 0x00000000, 0x000310C4 }, + { 0x0000003B, 0x00000000, 0x000310C5 }, + { 0x0000003C, 0x00000000, 0x0003121C }, + { 0x0000003D, 0x00000000, 0x00031623 }, + { 0x0000003F, 0x00000000, 0x00030D99 }, + { 0x0000003E, 0x00000000, 0x00030D99 }, + { 0x00000040, 0x00000000, 0x000315CE }, + { 0x00000041, 0x00000000, 0x000315DC }, + { 0x00000042, 0x00000000, 0x00031478 }, + { 0x00000043, 0x00000000, 0x00030FC8 }, + { 0x00000044, 0x00000000, 0x0003106D }, + { 0x00000054, 0x00000000, 0x00031514 }, + { 0x00000055, 0x00000000, 0x00031515 }, + { 0x00000056, 0x00000000, 0x000315CF }, + { 0x0000005A, 0x00000000, 0x000310F9 }, + { 0x00000058, 0x00000000, 0x000315DF }, + { 0x0000005B, 0x00000000, 0x00031620 }, + { 0x0000005C, 0x00000000, 0x0003134B }, + { 0x00000059, 0x00000000, 0x0003150F }, + { 0x00000057, 0x00000000, 0x00030D58 }, + { 0x00000045, 0x0000000A, 0x000310C3 }, + { 0x00000046, 0x00000000, 0x00030EAD }, + { 0x00000000, 0x00000000, 0x00000000 } +}; + +static const ScriptQuote DESKBOT_QUOTES[] = { + { 0x00000008, 0x00000000, 0x0003ACD0 }, + { 0x00000007, 0x00000000, 0x0003ACDC }, + { 0x00000006, 0x00000000, 0x0003ABF9 }, + { 0x00000005, 0x00000000, 0x0003AD04 }, + { 0x00000001, 0x56424144, 0x0003AE27 }, + { 0x00000001, 0x52554445, 0x0003AE27 }, + { 0x00000001, 0x5052534E, 0x00041EB3 }, + { 0x00000001, 0x464F4F44, 0x00041EB3 }, + { 0x00000001, 0x00000032, 0x00041EB1 }, + { 0x00000002, 0x56424144, 0x0003AE27 }, + { 0x00000002, 0x52554445, 0x0003AE27 }, + { 0x00000002, 0x5052534E, 0x00041EB3 }, + { 0x00000002, 0x464F4F44, 0x00041EB3 }, + { 0x00000002, 0x00000032, 0x00041EB1 }, + { 0x00000003, 0x56424144, 0x0003AE0E }, + { 0x00000003, 0x52554445, 0x0003AE0E }, + { 0x00000003, 0x5052534E, 0x00041EB3 }, + { 0x00000003, 0x464F4F44, 0x00041EB3 }, + { 0x00000003, 0x00000032, 0x00041EB1 }, + { 0x00000010, 0x54524156, 0x0003ACFE }, + { 0x00000010, 0x0000003C, 0x00041EB0 }, + { 0x00000011, 0x00000000, 0x0003ABF9 }, + { 0x00000015, 0x00000032, 0x0003AC70 }, + { 0x00000012, 0x00000042, 0x0003AC7E }, + { 0x00000013, 0x00000021, 0x0003AC70 }, + { 0x0000001D, 0x00000021, 0x0003AC09 }, + { 0x00000014, 0x00000042, 0x0003AE07 }, + { 0x0000001B, 0x00000000, 0x00041EB2 }, + { 0x0000001E, 0x00000000, 0x0003ACC1 }, + { 0x0000001F, 0x00000000, 0x0003AC3E }, + { 0x0000000C, 0x00000000, 0x0003AE4C }, + { 0x0000000D, 0x00000000, 0x0003AE4C }, + { 0x0000000E, 0x00000000, 0x0003AE4B }, + { 0x0000000F, 0x00000000, 0x0003AE4B }, + { 0x00000020, 0x00000019, 0x0003AE24 }, + { 0x00000021, 0x0000000F, 0x0003AE10 }, + { 0x0000001C, 0x00000032, 0x00041EB0 }, + { 0x00000023, 0x00000000, 0x0003AC46 }, + { 0x00000024, 0x00000000, 0x0003AE1F }, + { 0x00000025, 0x00000000, 0x0003AE14 }, + { 0x00000026, 0x00000000, 0x0003AC7B }, + { 0x00000030, 0x00000000, 0x0003AE3D }, + { 0x00000027, 0x424F5953, 0x0003AE5D }, + { 0x00000027, 0x4749524C, 0x0003AE5E }, + { 0x00000027, 0x00000000, 0x0003AE5C }, + { 0x00000028, 0x00000000, 0x0003AE5B }, + { 0x00000029, 0x00000000, 0x0003AE58 }, + { 0x0000002A, 0x00000000, 0x0003AE59 }, + { 0x0000002B, 0x00000000, 0x0003AE5A }, + { 0x0000002C, 0x00000000, 0x0003AE57 }, + { 0x0000002D, 0x00000000, 0x0003AE5C }, + { 0x0000002E, 0x424F5953, 0x0003AE5A }, + { 0x0000002E, 0x4749524C, 0x0003AE5A }, + { 0x0000002E, 0x00000000, 0x0003AE5A }, + { 0x00000032, 0x00000000, 0x0003AE0E }, + { 0x00000033, 0x00000000, 0x0003AE27 }, + { 0x00000034, 0x00000000, 0x0003AE24 }, + { 0x00000035, 0x00000000, 0x0003AE3E }, + { 0x00000037, 0x00000000, 0x0003AE26 }, + { 0x00000038, 0x00000000, 0x0003AEC0 }, + { 0x00000039, 0x00000000, 0x0003AEC1 }, + { 0x0000003A, 0x00000000, 0x0003AC7F }, + { 0x0000003B, 0x00000000, 0x0003ADD5 }, + { 0x0000003C, 0x00000000, 0x0003AEC5 }, + { 0x0000003D, 0x00000000, 0x0003AEC9 }, + { 0x0000003F, 0x00000000, 0x0003ABC5 }, + { 0x0000003E, 0x00000000, 0x0003ABC5 }, + { 0x00000040, 0x00000000, 0x0003AFB0 }, + { 0x00000041, 0x00000000, 0x0003AFDC }, + { 0x00000042, 0x00000000, 0x0003AFB5 }, + { 0x00000043, 0x00000000, 0x0003AFDD }, + { 0x00000044, 0x00000000, 0x0003AFDD }, + { 0x00000045, 0x0000000A, 0x0003AC7E }, + { 0x00000046, 0x00000000, 0x0003AF6E }, + { 0x00000000, 0x00000000, 0x00000000 } +}; + +static const ScriptQuote DOORBOT_QUOTES[] = { + { 0x00000008, 0x00000000, 0x00035F14 }, + { 0x00000007, 0x00000000, 0x00035F6F }, + { 0x00000004, 0x00000000, 0x000360BF }, + { 0x00000006, 0x00000000, 0x000360AF }, + { 0x00000005, 0x00000000, 0x000360BC }, + { 0x00000001, 0x56424144, 0x000360C0 }, + { 0x00000001, 0x52554445, 0x000360C0 }, + { 0x00000001, 0x5052534E, 0x00000003 }, + { 0x00000001, 0x464F4F44, 0x00000003 }, + { 0x00000001, 0x00000032, 0x00000001 }, + { 0x00000002, 0x56424144, 0x000360C0 }, + { 0x00000002, 0x52554445, 0x000360C0 }, + { 0x00000002, 0x5052534E, 0x00000003 }, + { 0x00000002, 0x464F4F44, 0x00000003 }, + { 0x00000002, 0x00000032, 0x00000001 }, + { 0x00000003, 0x56424144, 0x000360C0 }, + { 0x00000003, 0x52554445, 0x000360C0 }, + { 0x00000003, 0x5052534E, 0x00000003 }, + { 0x00000003, 0x464F4F44, 0x00000003 }, + { 0x00000003, 0x00000032, 0x00000001 }, + { 0x00000010, 0x54524156, 0x00035F6A }, + { 0x00000010, 0x0000003C, 0x00000000 }, + { 0x00000011, 0x00000000, 0x0003604F }, + { 0x00000015, 0x00000032, 0x00036046 }, + { 0x00000012, 0x00000042, 0x00036057 }, + { 0x00000013, 0x00000021, 0x00035FC8 }, + { 0x0000001D, 0x00000021, 0x00035FC8 }, + { 0x00000014, 0x00000042, 0x00036059 }, + { 0x00000016, 0x0000003C, 0x00035F6E }, + { 0x00000017, 0x00000028, 0x00035F6D }, + { 0x00000018, 0x00000000, 0x00035F68 }, + { 0x00000019, 0x00000000, 0x00035F68 }, + { 0x0000001A, 0x0000003C, 0x00035F67 }, + { 0x0000001B, 0x00000000, 0x00035FA0 }, + { 0x00000009, 0x00000019, 0x00035FD3 }, + { 0x0000000A, 0x00000019, 0x00036051 }, + { 0x0000000B, 0x00000028, 0x00035FC4 }, + { 0x0000001E, 0x00000000, 0x00035F5C }, + { 0x0000001F, 0x00000000, 0x00035F5C }, + { 0x0000000C, 0x00000000, 0x00035F9D }, + { 0x0000000D, 0x00000000, 0x00035F9D }, + { 0x0000000E, 0x00000000, 0x00035F9C }, + { 0x0000000F, 0x00000000, 0x00035F9C }, + { 0x00000020, 0x00000019, 0x00035FFF }, + { 0x00000021, 0x0000000F, 0x00035F59 }, + { 0x00000022, 0x0000000F, 0x00036055 }, + { 0x0000001C, 0x00000032, 0x00000000 }, + { 0x00000023, 0x00000000, 0x000360C3 }, + { 0x00000024, 0x00000000, 0x00035F5B }, + { 0x00000025, 0x00000000, 0x00035EFE }, + { 0x00000026, 0x00000000, 0x00035F03 }, + { 0x0000002C, 0x00000000, 0x000360C0 }, + { 0x0000002D, 0x00000000, 0x000360C0 }, + { 0x00000030, 0x00000000, 0x00035F42 }, + { 0x00000031, 0x00000000, 0x000360BF }, + { 0x00000032, 0x00000000, 0x000360BF }, + { 0x00000033, 0x00000000, 0x000360C0 }, + { 0x00000034, 0x00000000, 0x00035FC9 }, + { 0x00000035, 0x00000000, 0x00035E8B }, + { 0x00000036, 0x00000000, 0x00035DFA }, + { 0x00000037, 0x00000000, 0x000363AB }, + { 0x00000038, 0x00000000, 0x00035F0F }, + { 0x0000003C, 0x00000000, 0x00036379 }, + { 0x0000003E, 0x00000000, 0x00036262 }, + { 0x0000003F, 0x00000000, 0x00036262 }, + { 0x00000040, 0x00000000, 0x00036271 }, + { 0x00000041, 0x00000000, 0x0003626C }, + { 0x00000042, 0x00000000, 0x0003625D }, + { 0x00000043, 0x00000000, 0x0003649B }, + { 0x00000044, 0x00000000, 0x0003649B }, + { 0x00000046, 0x00000000, 0x00036035 }, + { 0x00000000, 0x00000000, 0x00000000 } +}; + +static const ScriptQuote LIFTBOT_QUOTES[] = { + { 0x00000008, 0x00000000, 0x00033655 }, + { 0x00000007, 0x00000000, 0x000335A0 }, + { 0x00000006, 0x00000000, 0x0003368B }, + { 0x00000005, 0x00000028, 0x00033693 }, + { 0x00000001, 0x56424144, 0x00033695 }, + { 0x00000001, 0x52554445, 0x00033695 }, + { 0x00000001, 0x5052534E, 0x00000003 }, + { 0x00000001, 0x464F4F44, 0x00000003 }, + { 0x00000001, 0x00000032, 0x00000001 }, + { 0x00000002, 0x56424144, 0x00033695 }, + { 0x00000002, 0x52554445, 0x00033695 }, + { 0x00000002, 0x5052534E, 0x00000003 }, + { 0x00000002, 0x464F4F44, 0x00000003 }, + { 0x00000002, 0x00000032, 0x00000001 }, + { 0x00000003, 0x56424144, 0x00033695 }, + { 0x00000003, 0x52554445, 0x00033695 }, + { 0x00000003, 0x5052534E, 0x00000003 }, + { 0x00000003, 0x464F4F44, 0x00000003 }, + { 0x00000003, 0x00000032, 0x00000001 }, + { 0x00000010, 0x54524156, 0x000335A4 }, + { 0x00000010, 0x0000003C, 0x00000000 }, + { 0x00000011, 0x00000000, 0x0003367B }, + { 0x00000015, 0x00000032, 0x000335A1 }, + { 0x00000012, 0x00000042, 0x00033672 }, + { 0x00000013, 0x00000021, 0x00033679 }, + { 0x0000001D, 0x00000021, 0x00033679 }, + { 0x00000014, 0x00000042, 0x00033688 }, + { 0x00000016, 0x0000003C, 0x000335A4 }, + { 0x00000017, 0x00000028, 0x00033689 }, + { 0x00000018, 0x00000000, 0x00033670 }, + { 0x00000019, 0x00000000, 0x000335A0 }, + { 0x0000001A, 0x0000003C, 0x0003368F }, + { 0x0000001B, 0x00000000, 0x00033695 }, + { 0x00000009, 0x00000019, 0x000335A2 }, + { 0x0000000A, 0x00000019, 0x000335A6 }, + { 0x0000000B, 0x00000028, 0x00033668 }, + { 0x0000001E, 0x00000000, 0x00033691 }, + { 0x0000001F, 0x00000000, 0x00033691 }, + { 0x0000000C, 0x00000014, 0x00033666 }, + { 0x0000000D, 0x00000014, 0x00033666 }, + { 0x0000000E, 0x00000014, 0x0003367A }, + { 0x0000000F, 0x00000014, 0x0003367A }, + { 0x00000020, 0x00000019, 0x0003367C }, + { 0x00000021, 0x0000000F, 0x00033690 }, + { 0x00000022, 0x0000000F, 0x00033682 }, + { 0x0000001C, 0x00000032, 0x00000000 }, + { 0x00000023, 0x00000000, 0x00033698 }, + { 0x00000024, 0x00000000, 0x00033699 }, + { 0x00000031, 0x00000000, 0x00033694 }, + { 0x00000032, 0x00000000, 0x00033694 }, + { 0x00000033, 0x00000000, 0x00033695 }, + { 0x00000034, 0x00000000, 0x0003369F }, + { 0x00000035, 0x00000000, 0x000336A0 }, + { 0x00000036, 0x00000000, 0x00033585 }, + { 0x0000003E, 0x00000000, 0x0003380D }, + { 0x0000003F, 0x00000000, 0x0003380D }, + { 0x00000040, 0x00000000, 0x0003380D }, + { 0x00000041, 0x00000000, 0x000337E7 }, + { 0x00000042, 0x00000000, 0x00033711 }, + { 0x00000000, 0x00000000, 0x00000000 } +}; + +static const ScriptQuote MAITRED_QUOTES[] = { + { 0x00000008, 0x00000000, 0x0003F967 }, + { 0x00000007, 0x00000000, 0x0003F995 }, + { 0x00000006, 0x00000000, 0x0003F833 }, + { 0x00000005, 0x00000000, 0x0003F95B }, + { 0x00000001, 0x56424144, 0x0003F847 }, + { 0x00000001, 0x52554445, 0x0003F847 }, + { 0x00000001, 0x5052534E, 0x00041EB3 }, + { 0x00000001, 0x464F4F44, 0x0003FB88 }, + { 0x00000001, 0x00000032, 0x00041EB1 }, + { 0x00000010, 0x54524156, 0x0003F9FA }, + { 0x00000010, 0x0000003C, 0x00041EB0 }, + { 0x00000011, 0x00000000, 0x0003F967 }, + { 0x00000015, 0x00000032, 0x0003F83D }, + { 0x00000012, 0x00000042, 0x0003F83D }, + { 0x00000013, 0x00000021, 0x0003F95B }, + { 0x0000001D, 0x00000021, 0x0003F971 }, + { 0x00000014, 0x00000042, 0x0003F96C }, + { 0x0000001B, 0x00000000, 0x0003F95B }, + { 0x0000001E, 0x00000000, 0x0003FA3C }, + { 0x0000001F, 0x00000000, 0x0003F991 }, + { 0x0000000C, 0x00000000, 0x0003F9C9 }, + { 0x0000000D, 0x00000000, 0x0003F9C9 }, + { 0x0000000E, 0x00000000, 0x0003F9C9 }, + { 0x0000000F, 0x00000000, 0x0003F9C9 }, + { 0x00000020, 0x00000019, 0x0003F847 }, + { 0x00000021, 0x0000000F, 0x0003FA22 }, + { 0x00000037, 0x00000000, 0x0003FA9C }, + { 0x0000003C, 0x00000000, 0x0003FAA0 }, + { 0x00000047, 0x00000000, 0x0003FAA1 }, + { 0x0000003F, 0x00000000, 0x0003FABD }, + { 0x0000003E, 0x00000000, 0x0003FABD }, + { 0x00000040, 0x00000000, 0x0003FABB }, + { 0x00000041, 0x00000000, 0x0003FABB }, + { 0x00000042, 0x00000000, 0x0003FABC }, + { 0x00000048, 0x00000000, 0x0003FB45 }, + { 0x00000049, 0x00000000, 0x0003FB48 }, + { 0x0000004A, 0x00000000, 0x0003FB52 }, + { 0x0000004B, 0x00000000, 0x0003FB4A }, + { 0x0000004C, 0x00000000, 0x0003FB47 }, + { 0x0000004D, 0x00000000, 0x0003FB49 }, + { 0x0000004E, 0x00000000, 0x0003FB53 }, + { 0x0000004F, 0x00000000, 0x0003FB4C }, + { 0x00000050, 0x00000000, 0x0003FB4E }, + { 0x00000051, 0x00000000, 0x0003FB50 }, + { 0x00000052, 0x00000000, 0x0003FB75 }, + { 0x00000053, 0x00000000, 0x0003F9A8 }, + { 0x00000000, 0x00000000, 0x00000000 } +}; + +void writeScriptQuotes(const char *name, const ScriptQuote *quotes, + uint tag1, uint tag2, uint rangeStart, uint rangeEnd) { + outputFile.seek(dataOffset); + outputFile.writeLong(tag1); + outputFile.writeLong(tag2); + outputFile.writeLong(rangeStart); + outputFile.writeLong(rangeEnd); + + for (; quotes->_index; ++quotes) { + outputFile.writeLong(quotes->_index); + outputFile.writeLong(quotes->_tagId); + outputFile.writeLong(quotes->_dialogueId); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader(name, dataOffset, size); + dataOffset += size; +} + +void writeAllScriptQuotes() { + writeScriptQuotes("Quotes/Barbot", BARBOT_QUOTES, 221376, 221375, 0, 999); + writeScriptQuotes("Quotes/Bellbot", BELLBOT_QUOTES, 201687, 201686, 270000, 270500); + writeScriptQuotes("Quotes/Deskbot", DESKBOT_QUOTES, 241191, 241166, 270000, 270500); + writeScriptQuotes("Quotes/Doorbot", DOORBOT_QUOTES, 221376, 221375, 0, 999); + writeScriptQuotes("Quotes/Liftbot", LIFTBOT_QUOTES, 210581, 210580, 0, 999); + writeScriptQuotes("Quotes/MaitreD", MAITRED_QUOTES, 260167, 260147, 270000, 270500); +}
\ No newline at end of file diff --git a/devtools/create_titanic/script_quotes.h b/devtools/create_titanic/script_quotes.h new file mode 100644 index 0000000000..5b4f25c3c8 --- /dev/null +++ b/devtools/create_titanic/script_quotes.h @@ -0,0 +1,38 @@ +/* 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 COMMON_SCRIPT_QUOTES_H +#define COMMON_SCRIPT_QUOTES_H + +#include "common/scummsys.h" + +struct ScriptQuote { + uint _index; + uint _tagId; + uint _dialogueId; +}; + +extern void writeAllScriptQuotes(); +extern void writeEntryHeader(const char *name, uint offset, uint size); +extern uint dataOffset; + +#endif diff --git a/devtools/create_titanic/script_ranges.cpp b/devtools/create_titanic/script_ranges.cpp new file mode 100644 index 0000000000..6ac8092e3a --- /dev/null +++ b/devtools/create_titanic/script_ranges.cpp @@ -0,0 +1,1804 @@ +/* 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. + * + */ + + // Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +// HACK to allow building with the SDL backend on MinGW +// see bug #1800764 "TOOLS: MinGW tools building broken" +#ifdef main +#undef main +#endif // main + +#include "file.h" +#include "script_ranges.h" + +const uint BARBOT_RANGE1[] = { 250062, 250064, 250065, 250066, 250067, 250068, 250069, 250070, 250071, 250063, 0 }; +const uint BARBOT_RANGE2[] = { 250200, 250201, 250202, 250203, 250204, 250205, 250206, 250207, 0 }; +const uint BARBOT_RANGE3[] = { 250160, 250161, 250162, 250163, 0 }; +const uint BARBOT_RANGE4[] = { 250175, 250176, 250177, 250178, 250179, 250180, 250181, 250182, 250183, 0 }; +const uint BARBOT_RANGE5[] = { 250114, 250004, 0 }; +const uint BARBOT_RANGE6[] = { 250042, 250009, 250010, 250011, 251692, 251693, 251694, 0 }; +const uint BARBOT_RANGE7[] = { 250012, 250111, 0 }; +const uint BARBOT_RANGE8[] = { 250013, 250119, 0 }; +const uint BARBOT_RANGE9[] = { 250027, 250126, 250055, 0 }; +const uint BARBOT_RANGE10[] = { 250032, 250130, 0 }; +const uint BARBOT_RANGE11[] = { 250038, 250134, 0 }; +const uint BARBOT_RANGE12[] = { 250039, 250135, 250050, 0 }; +const uint BARBOT_RANGE13[] = { 250016, 250120, 250136, 250145, 250143, 0 }; +const uint BARBOT_RANGE14[] = { 250040, 250138, 250139, 0 }; +const uint BARBOT_RANGE15[] = { 250037, 250133, 250617, 0 }; +const uint BARBOT_RANGE16[] = { 250031, 250129, 0 }; +const uint BARBOT_RANGE17[] = { 250036, 250132, 0 }; +const uint BARBOT_RANGE18[] = { 250035, 250137, 0 }; +const uint BARBOT_RANGE19[] = { 250021, 250123, 0 }; +const uint BARBOT_RANGE20[] = { 250006, 250117, 0 }; +const uint BARBOT_RANGE21[] = { 250024, 250124, 0 }; +const uint BARBOT_RANGE22[] = { 250002, 250113, 0 }; +const uint BARBOT_RANGE23[] = { 250152, 250153, 250079, 250194, 250149, 250151, 250150, +250208, 250209, 250157, 250195, 250076, 250156, 250074, +250075, 250080, 250192, 250109, 250159, 250110, 250148, +250053, 250155, 250197, 250072, 250077, 250001, 250154, +250196, 250198, 250199, 250158, 250073, 0 }; +const uint BARBOT_RANGE24[] = { 251831, 251832, 251833, 251834, 251835, 250617, 0 }; +const uint BARBOT_RANGE25[] = { 250033, 251838, 0 }; +const uint BARBOT_RANGE26[] = { 250014, 251827, 251781, 250617, 0 }; +const uint BARBOT_RANGE27[] = { 251855, 251856, 0 }; +const uint BARBOT_RANGE28[] = { 251852, 251853, 0 }; +const uint BARBOT_RANGE29[] = { 251250, 251261, 251272, 251277, 251278, 251279, 251280, +251281, 251282, 251251, 251252, 251253, 251254, 251255, +251256, 251257, 251258, 251259, 251260, 251262, 251263, +251264, 251265, 251266, 251267, 251268, 251269, 251270, +251271, 251273, 251274, 251275, 251276, 0 }; +const uint BARBOT_RANGE30[] = { 251283, 251284, 251285, 251286, 0 }; +const uint BARBOT_RANGE31[] = { 250527, 250530, 250531, 250532, 250533, 250534, 250535, +250536, 250537, 250528, 250529, 0 }; +const uint BARBOT_RANGE32[] = { 250593, 250594, 0 }; +const uint BARBOT_RANGE33[] = { 250263, 250264, 250265, 250266, 0 }; +const uint BARBOT_RANGE34[] = { 250227, 250228, 250229, 250230, 0 }; +const uint BARBOT_RANGE35[] = { 250239, 250240, 250241, 250242, 250243, 0 }; +const uint BARBOT_RANGE36[] = { 250507, 250222, 250678, 250588, 0 }; +const uint BARBOT_RANGE37[] = { 250365, 250366, 250367, 250368, 0 }; +const uint BARBOT_RANGE38[] = { 250936, 250937, 250938, 0 }; +const uint BARBOT_RANGE39[] = { 250610, 250611, 0 }; +const uint BARBOT_RANGE40[] = { 250082, 250093, 250102, 250104, 250105, 250106, 250107, +250108, 250091, 250092, 250094, 250095, 250096, 250097, +250098, 250099, 250100, 250101, 251700, 251701, 251702, +251703, 251704, 251862, 250617, 250268, 250272, 0 }; +const uint BARBOT_RANGE41[] = { 250584, 250585, 0 }; +const uint BARBOT_RANGE42[] = { 250579, 251142, 0 }; +const uint BARBOT_RANGE43[] = { 250577, 250578, 0 }; +const uint BARBOT_RANGE44[] = { 250244, 250245, 250246, 250247, 250248, 250249, 250250, +250251, 250252, 250253, 250254, 250255, 250256, 250257, +250258, 250259, 250260, 250261, 250262, 0 }; +const uint BARBOT_RANGE45[] = { 250286, 250288, 250289, 250290, 250291, 250292, 250293, +250294, 250295, 250287, 0 }; +const uint BARBOT_RANGE46[] = { 250296, 250299, 250300, 250301, 250302, 250303, 250304, +250305, 250306, 250297, 250298, 0 }; +const uint BARBOT_RANGE47[] = { 250307, 250309, 250310, 250311, 250312, 250313, 250314, +250315, 250316, 0 }; +const uint BARBOT_RANGE48[] = { 251682, 251683, 251684, 251685, 251686, 251687, 251688, +251689, 250756, 250757, 250758, 250759, 0 }; +const uint BARBOT_RANGE49[] = { 250738, 250742, 250743, 250744, 250745, 250746, 250747, +250748, 250749, 250739, 250740, 250741, 0 }; +const uint BARBOT_RANGE50[] = { 250659, 250660, 250661, 250379, 0 }; +const uint BARBOT_RANGE51[] = { 251761, 251762, 251763, 251764, 0 }; +const uint BARBOT_RANGE52[] = { 251754, 251755, 251756, 251757, 251758, 251759, 0 }; +const uint BARBOT_RANGE53[] = { 250482, 250504, 250424, 250463, 250466, 250467, 250468, +250478, 250501, 250502, 250503, 250506, 250413, 251014, +250614, 250756, 250758, 250759, 250223, 250737, 250658, +251027, 250633, 250935, 250237, 251618, 0 }; +const uint BARBOT_RANGE54[] = { 250504, 250434, 250436, 250466, 250467, 250468, 250469, +250470, 250472, 250501, 250502, 250503, 250505, 250413, +251681, 250756, 250758, 250759, 250223, 251027, 250633, +250935, 250237, 251618, 250371, 0 }; +const uint BARBOT_RANGE55[] = { 250952, 250953, 0 }; +const uint BARBOT_RANGE56[] = { 251777, 250951, 0 }; +const uint BARBOT_RANGE57[] = { 251871, 251877, 251878, 251879, 251880, 251883, 251884, +251872, 251873, 0 }; +const uint BARBOT_RANGE58[] = { 250228, 250236, 250258, 250259, 250378, 250465, 250536, +251016, 251048, 251068, 0 }; +const uint BARBOT_RANGE59[] = { 250141, 250378, 251048, 0 }; +const uint BARBOT_RANGE60[] = { 251621, 251622, 251623, 251624, 251625, 251626, 0 }; +const uint BARBOT_RANGE61[] = { 251650, 251651, 0 }; +const uint BARBOT_RANGE62[] = { 251305, 251306, 251307, 251308, 0 }; +const uint BARBOT_RANGE63[] = { 251836, 251890, 251891, 251892, 0 }; +const uint BARBOT_RANGE64[] = { 250760, 251246, 251156, 251335, 251510, 251059, 251097, +251136, 250374, 250375, 250376, 250377, 251015, 251016, +251017, 251018, 0 }; +const uint BARBOT_RANGE65[] = { 250899, 250906, 250948, 250713, 250690, 0 }; +const uint BARBOT_RANGE66[] = { 250906, 250948, 250713, 250899, 250690, 0 }; +const uint BARBOT_RANGE67[] = { 250949, 250713, 250711, 250152, 250153, 250690, 250906, 0 }; +const uint BARBOT_RANGE68[] = { 251815, 250711, 0 }; +const uint BARBOT_RANGE69[] = { 251829, 250711, 0 }; +const uint BARBOT_RANGE70[] = { 251779, 250712, 0 }; + +#define BARBOT_RANGE_COUNT 70 +const ScriptRange BARBOT_RANGES[70] = { + { 250062, BARBOT_RANGE1, false, false }, + { 250200, BARBOT_RANGE2, false, false }, + { 250160, BARBOT_RANGE3, false, false }, + { 250175, BARBOT_RANGE4, false, false }, + { 250004, BARBOT_RANGE5, false, false }, + { 250042, BARBOT_RANGE6, true, false }, + { 250012, BARBOT_RANGE7, false, false }, + { 250013, BARBOT_RANGE8, false, false }, + { 250027, BARBOT_RANGE9, false, false }, + { 250032, BARBOT_RANGE10, false, false }, + { 250038, BARBOT_RANGE11, false, false }, + { 250039, BARBOT_RANGE12, false, false }, + { 250016, BARBOT_RANGE13, false, false }, + { 250040, BARBOT_RANGE14, false, false }, + { 250037, BARBOT_RANGE15, false, false }, + { 250031, BARBOT_RANGE16, false, false }, + { 250036, BARBOT_RANGE17, false, false }, + { 250035, BARBOT_RANGE18, false, false }, + { 250021, BARBOT_RANGE19, false, false }, + { 250006, BARBOT_RANGE20, false, false }, + + { 250024, BARBOT_RANGE21, false, false }, + { 250002, BARBOT_RANGE22, false, false }, + { 250210, BARBOT_RANGE23, false, false }, + { 251831, BARBOT_RANGE24, false, false }, + { 250033, BARBOT_RANGE25, false, false }, + { 250014, BARBOT_RANGE26, false, false }, + { 251855, BARBOT_RANGE27, false, false }, + { 251852, BARBOT_RANGE28, false, false }, + { 251250, BARBOT_RANGE29, false, false }, + { 251283, BARBOT_RANGE30, false, false }, + { 250527, BARBOT_RANGE31, false, false }, + { 250593, BARBOT_RANGE32, false, false }, + { 250263, BARBOT_RANGE33, false, false }, + { 250227, BARBOT_RANGE34, false, false }, + { 250239, BARBOT_RANGE35, false, false }, + { 250507, BARBOT_RANGE36, false, false }, + { 250365, BARBOT_RANGE37, false, false }, + { 250936, BARBOT_RANGE38, false, false }, + { 250610, BARBOT_RANGE39, false, false }, + { 250082, BARBOT_RANGE40, true, false }, + + { 250584, BARBOT_RANGE41, false, false }, + { 250579, BARBOT_RANGE42, false, false }, + { 250577, BARBOT_RANGE43, false, false }, + { 250244, BARBOT_RANGE44, true, false }, + { 250286, BARBOT_RANGE45, true, false }, + { 250296, BARBOT_RANGE46, true, false }, + { 250307, BARBOT_RANGE47, true, false }, + { 251682, BARBOT_RANGE48, true, false }, + { 250738, BARBOT_RANGE49, true, false }, + { 250659, BARBOT_RANGE50, true, false }, + { 251761, BARBOT_RANGE51, false, false }, + { 251754, BARBOT_RANGE52, false, false }, + { 251896, BARBOT_RANGE53, true, false }, + { 251897, BARBOT_RANGE54, true, false }, + { 250952, BARBOT_RANGE55, false, false }, + { 251777, BARBOT_RANGE56, false, false }, + { 251871, BARBOT_RANGE57, true, false }, + { 250140, BARBOT_RANGE58, true, false }, + { 250141, BARBOT_RANGE59, false, false }, + { 251621, BARBOT_RANGE60, false, false }, + + { 251650, BARBOT_RANGE61, false, false }, + { 251305, BARBOT_RANGE62, false, false }, + { 251836, BARBOT_RANGE63, false, false }, + { 251018, BARBOT_RANGE64, true, false }, + { 250899, BARBOT_RANGE65, false, false }, + { 250899, BARBOT_RANGE66, false, false }, + { 251899, BARBOT_RANGE67, false, false }, + { 251815, BARBOT_RANGE68, false, false }, + { 251829, BARBOT_RANGE69, false, false }, + { 251779, BARBOT_RANGE70, false, false } +}; + +const uint BELLBOT_RANGE1[] = { 200059, 200637, 0 }; +const uint BELLBOT_RANGE2[] = { 200001, 200002, 200003, 200004, 200005, 200006, 0 }; +const uint BELLBOT_RANGE3[] = { 200020, 200021, 202117, 202118, 0 }; +const uint BELLBOT_RANGE4[] = { 200023, 200024, 200025, 0 }; +const uint BELLBOT_RANGE5[] = { 200029, 0 }; +const uint BELLBOT_RANGE6[] = { 200034, 200035, 0 }; +const uint BELLBOT_RANGE7[] = { 200038, 200039, 0 }; +const uint BELLBOT_RANGE8[] = { 200061, 200062, 200063, 200064, 200065, 200066, 200201, 200202, 200203, 200204, + 200205, 0 }; +const uint BELLBOT_RANGE9[] = { 200068, 200069, 200070, 200071, 200072, 0 }; +const uint BELLBOT_RANGE10[] = { 200076, 200077, 0 }; + +const uint BELLBOT_RANGE11[] = { 200079, 200080, 200081, 200082, 200083, 200084, 0 }; +const uint BELLBOT_RANGE12[] = { 200119, 200120, 200121, 200122, 200123, 200124, 200125, 200126, 0 }; +const uint BELLBOT_RANGE13[] = { 200134, 200135, 0 }; +const uint BELLBOT_RANGE14[] = { 200141, 200149, 200150, 200151, 200152, 200153, 200154, 200155, 200156, 200142, +200143, 200144, 200145, 200147, 200148, 0 }; +const uint BELLBOT_RANGE15[] = { 200158, 200168, 200169, 200170, 200171, 200172, 200173, 200174, 200175, 200159, +200160, 200161, 200162, 200146, 200163, 200164, 200165, 200166, 200167, 0 }; +const uint BELLBOT_RANGE16[] = { + 200177, 200182, 200183, 200184, 200185, 200186, 200187, 200188, 200189, 200191, + 200178, 200179, 200180, 200181, 0 +}; +const uint BELLBOT_RANGE17[] = { 200194, 200195, 200196, 200197, 200198, 200199, 0 }; +const uint BELLBOT_RANGE18[] = { 200201, 200202, 200203, 200204, 200205, 200078, 0 }; +const uint BELLBOT_RANGE19[] = { 200236, 200237, 200238, 200239, 200240, 0 }; +const uint BELLBOT_RANGE20[] = { 200244, 200245, 200246, 200247, 200248, 0 }; + +const uint BELLBOT_RANGE21[] = { 200262, 200263, 200264, 200265, 200266, 200267, 200268, 200269, 200270, 200271, 0 }; +const uint BELLBOT_RANGE22[] = { 200280, 200281, 200282, 0 }; +const uint BELLBOT_RANGE23[] = { 200284, 200285, 200286, 200287, 200288, 200289, 0 }; +const uint BELLBOT_RANGE24[] = { 200291, 200292, 202254, 0 }; +const uint BELLBOT_RANGE25[] = { 200294, 200295, 200296, 200297, 200298, 200299, 200300, 200301, 200481, 200481, +200481, 0 }; +const uint BELLBOT_RANGE26[] = { 200307, 200308, 200309, 0 }; +const uint BELLBOT_RANGE27[] = { 200312, 200313, 0 }; +const uint BELLBOT_RANGE28[] = { 200324, 200325, 200326, 200327, 200328, 0 }; +const uint BELLBOT_RANGE29[] = { 200331, 200332, 200722, 200723, 0 }; +const uint BELLBOT_RANGE30[] = { 200337, 200338, 200339, 200340, 200341, 200342, 200343, 200344, 200345, 200346, 0 }; + +const uint BELLBOT_RANGE31[] = { 200351, 200352, 200353, 200354, 200355, 200356, 200357, 200358, 0 }; +const uint BELLBOT_RANGE32[] = { 200360, 200361, 0 }; +const uint BELLBOT_RANGE33[] = { 200363, 200364, 0 }; +const uint BELLBOT_RANGE34[] = { 200371, 200372, 200373, 0 }; +const uint BELLBOT_RANGE35[] = { 200375, 200376, 0 }; +const uint BELLBOT_RANGE36[] = { 200394, 200395, 200396, 0 }; +const uint BELLBOT_RANGE37[] = { 200406, 200407, 0 }; +const uint BELLBOT_RANGE38[] = { 200414, 200415, 0 }; +const uint BELLBOT_RANGE39[] = { 200423, 200424, 0 }; +const uint BELLBOT_RANGE40[] = { 200433, 200434, 200435, 0 }; + +const uint BELLBOT_RANGE41[] = { 200437, 200440, 200441, 200442, 200443, 200444, 200445, 200446, 200447, 200438, +200439, 0 }; +const uint BELLBOT_RANGE42[] = { 200449, 200450, 200451, 200452, 200453, 200454, 0 }; +const uint BELLBOT_RANGE43[] = { 200456, 200457, 200458, 0 }; +const uint BELLBOT_RANGE44[] = { + 201036, 201037, 200997, 200998, 200999, 201000, 201009, 201010, 200482, 200483, + 200484, 200485, 200486, 200487, 200488, 200489, 200490, 200691, 202215, 200666, + 200665, 200375, 200788, 200687, 200985, 200986, 201011, 201021, 0 +}; +const uint BELLBOT_RANGE45[] = { 200497, 200498, 200499, 200500, 200501, 200502, 200503, 0 }; +const uint BELLBOT_RANGE46[] = { 200508, 200509, 200510, 202219, 0 }; +const uint BELLBOT_RANGE47[] = { 200517, 200518, 200519, 200520, 200521, 200522, 200523, 200524, 0 }; +const uint BELLBOT_RANGE48[] = { 200529, 200530, 200531, 0 }; +const uint BELLBOT_RANGE49[] = { 200540, 200541, 0 }; +const uint BELLBOT_RANGE50[] = { 200558, 200559, 200560, 200561, 0 }; + +const uint BELLBOT_RANGE51[] = { 200563, 200564, 200565, 200566, 200567, 200568, 200569, 0 }; +const uint BELLBOT_RANGE52[] = { 200572, 200573, 200574, 0 }; +const uint BELLBOT_RANGE53[] = { 200584, 200586, 200587, 200588, 200589, 0 }; +const uint BELLBOT_RANGE54[] = { 200591, 200592, 200593, 0 }; +const uint BELLBOT_RANGE55[] = { 200602, 200603, 200604, 0 }; +const uint BELLBOT_RANGE56[] = { 200606, 200607, 0 }; +const uint BELLBOT_RANGE57[] = { 200619, 200620, 200621, 200622, 200623, 200624, 200625, 200626, 0 }; +const uint BELLBOT_RANGE58[] = { 200636, 200637, 0 }; +const uint BELLBOT_RANGE59[] = { 200672, 200671, 0 }; +const uint BELLBOT_RANGE60[] = { 200679, 201977, 0 }; + +const uint BELLBOT_RANGE61[] = { 200687, 200688, 200689, 200690, 200691, 200692, 0 }; +const uint BELLBOT_RANGE62[] = { 200699, 200700, 0 }; +const uint BELLBOT_RANGE63[] = { 200705, 200706, 200707, 0 }; +const uint BELLBOT_RANGE64[] = { 200711, 200712, 200713, 0 }; +const uint BELLBOT_RANGE65[] = { 200717, 200718, 0 }; +const uint BELLBOT_RANGE66[] = { 200724, 200725, 200726, 200727, 200728, 0 }; +const uint BELLBOT_RANGE67[] = { 200734, 200735, 200736, 0 }; +const uint BELLBOT_RANGE68[] = { 200749, 200750, 200751, 200752, 200753, 200481, 200481, 200481, 0 }; +const uint BELLBOT_RANGE69[] = { 200758, 200759, 0 }; +const uint BELLBOT_RANGE70[] = { 200774, 200775, 200776, 201820, 0 }; + +const uint BELLBOT_RANGE71[] = { 200778, 200779, 200780, 200781, 200481, 200481, 0 }; +const uint BELLBOT_RANGE72[] = { 200783, 200784, 200785, 200786, 200787, 200481, 200481, 0 }; +const uint BELLBOT_RANGE73[] = { 200800, 200801, 200802, 200803, 200804, 200805, 200806, 200807, 200808, 200809, + 200481, 200481, 0 }; +const uint BELLBOT_RANGE74[] = { 200815, 200816, 200481, 0 }; +const uint BELLBOT_RANGE75[] = { 200827, 200828, 200829, 200481, 0 }; +const uint BELLBOT_RANGE76[] = { 200867, 200868, 200869, 200481, 0 }; +const uint BELLBOT_RANGE77[] = { 200875, 200876, 0 }; +const uint BELLBOT_RANGE78[] = { 200878, 200879, 200880, 200481, 0 }; +const uint BELLBOT_RANGE79[] = { 200889, 200890, 200891, 200481, 0 }; +const uint BELLBOT_RANGE80[] = { 200893, 200894, 200895, 200896, 200897, 200898, 200481, 0 }; + +const uint BELLBOT_RANGE81[] = { 200400, 200399, 0 }; +const uint BELLBOT_RANGE82[] = { 200114, 200115, 0 }; +const uint BELLBOT_RANGE83[] = { 200660, 200659, 0 }; +const uint BELLBOT_RANGE84[] = { 200303, 200304, 0 }; +const uint BELLBOT_RANGE85[] = { 200837, 200838, 0 }; +const uint BELLBOT_RANGE86[] = { 200790, 200791, 0 }; +const uint BELLBOT_RANGE87[] = { 200771, 200772, 0 }; +const uint BELLBOT_RANGE88[] = { 200137, 200138, 0 }; +const uint BELLBOT_RANGE89[] = { 200548, 200551, 200555, 200549, 200547, 200553, 200552, 200545, 200550, 200554, +200546, 200556, 0 }; +const uint BELLBOT_RANGE90[] = { + 200906, 200907, 200908, 200909, 200910, 200911, 200912, 200913, 200914, 200915, + 200916, 200917, 200918, 200919, 200922, 200923, 200924, 200925, 200926, 200927, + 200928, 200929, 200930, 0 +}; + +const uint BELLBOT_RANGE91[] = { + 200931, 200932, 200933, 200934, 200935, 200936, 200937, 200938, 200939, 200940, + 200941, 200942, 200943, 200944, 200947, 200948, 200949, 200950, 200951, 200952, + 200953, 200954, 200955, 200956, 200957, 200958, 200959, 200960, 200962, 200965, + 200966, 201028, 201029, 201030, 201033, 202051, 0 +}; +const uint BELLBOT_RANGE92[] = { + 200967, 200968, 200969, 200970, 200971, 200972, 200973, 200974, 200975, 200976, + 200977, 200978, 200979, 200980, 200981, 200982, 200983, 200984, 200985, 200986, + 200987, 200988, 200989, 201036, 201037, 0 +}; +const uint BELLBOT_RANGE93[] = { 200991, 200992, 200993, 200994, 200995, 200996, 201001, 201002, 201003, 201004, +201007, 0 }; +const uint BELLBOT_RANGE94[] = { 200997, 200998, 200999, 201000, 201009, 201010, 0 }; +const uint BELLBOT_RANGE95[] = { 201014, 201015, 201016, 201017, 201018, 201019, 201020, 201023, 201024, 0 }; +const uint BELLBOT_RANGE96[] = { 201025, 201026, 201027, 0 }; +const uint BELLBOT_RANGE97[] = { 201044, 201045, 201046, 201047, 0 }; +const uint BELLBOT_RANGE98[] = { 201048, 201051, 201059, 201063, 201065, 201068, 201069, 200236, 200237, 200238, +200239, 201882, 0 }; +const uint BELLBOT_RANGE99[] = { 201060, 201061, 201062, 0 }; +const uint BELLBOT_RANGE100[] = { 201053, 201054, 0 }; + +const uint BELLBOT_RANGE101[] = { 201055, 201056, 201057, 201058, 0 }; +const uint BELLBOT_RANGE102[] = { 201073, 201074, 201075, 0 }; +const uint BELLBOT_RANGE103[] = { 202158, 201076, 201077, 201078, 202159, 0 }; +const uint BELLBOT_RANGE104[] = { 201079, 201080, 201081, 201082, 201087, 201088, 0 }; +const uint BELLBOT_RANGE105[] = { 201084, 201085, 0 }; +const uint BELLBOT_RANGE106[] = { 201090, 201091, 201092, 201093, 201094, 201095, 201096, 201097, 0 }; +const uint BELLBOT_RANGE107[] = { 201098, 201099, 201100, 201101, 201102, 201105, 201106, 201107, 201108, 0 }; +const uint BELLBOT_RANGE108[] = { + 201111, 201112, 201113, 201114, 201115, 201116, 201117, 201118, 201119, 201120, + 201121, 201122, 201123, 201124, 201125, 201126, 201127, 201128, 201130, 201131, + 201132, 201133, 0 +}; +const uint BELLBOT_RANGE109[] = { 201134, 201136, 201137, 201138, 0 }; +const uint BELLBOT_RANGE110[] = { 201139, 201140, 201141, 201142, 201143, 201144, 201145, 201146, 201147, 201148, 0 }; + +const uint BELLBOT_RANGE111[] = { 201149, 201150, 201151, 201152, 201153, 201154, 201155, 201156, 201157, 0 }; +const uint BELLBOT_RANGE112[] = { 201158, 201159, 201160, 201161, 201162, 201163, 201164, 201165, 201166, 0 }; +const uint BELLBOT_RANGE113[] = { + 201170, 201171, 201172, 201173, 201174, 201175, 201176, 201177, 201178, 201179, + 201180, 201181, 201182, 201183, 201184, 201185, 201186, 201187, 201188, 201189, + 201190, 201191, 201192, 201193, 201194, 201195, 201196, 201197, 201198, 201199, + 201200, 201201, 201202, 201203, 201204, 201205, 201206, 201207, 201208, 201209, + 201210, 201211, 201212, 201213, 201214, 201215, 0 +}; +const uint BELLBOT_RANGE114[] = { 201170, 0 }; +const uint BELLBOT_RANGE115[] = { 201239, 201240, 201241, 0 }; +const uint BELLBOT_RANGE116[] = { 201242, 201243, 0 }; +const uint BELLBOT_RANGE117[] = { 201245, 201246, 201247, 201248, 0 }; +const uint BELLBOT_RANGE118[] = { 201249, 201250, 201251, 201252, 0 }; +const uint BELLBOT_RANGE119[] = { 201253, 201254, 201255, 0 }; +const uint BELLBOT_RANGE120[] = { 201258, 201259, 202138, 201260, 202139, 201261, 202138, 0 }; + +const uint BELLBOT_RANGE121[] = { 201265, 201266, 201267, 201268, 0 }; +const uint BELLBOT_RANGE122[] = { 201310, 201312, 0 }; +const uint BELLBOT_RANGE123[] = { 201313, 201314, 201315, 201316, 201317, 201318, 201319, 201320, 201321, 0 }; +const uint BELLBOT_RANGE124[] = { 201340, 201342, 0 }; +const uint BELLBOT_RANGE125[] = { 201344, 201432, 0 }; +const uint BELLBOT_RANGE126[] = { 201345, 201458, 0 }; +const uint BELLBOT_RANGE127[] = { 201346, 201484, 0 }; +const uint BELLBOT_RANGE128[] = { 201444, 0 }; +const uint BELLBOT_RANGE129[] = { 201348, 201406, 201456, 0 }; +const uint BELLBOT_RANGE130[] = { 201350, 201351, 0 }; + +const uint BELLBOT_RANGE131[] = { 201398, 201352, 201429, 0 }; +const uint BELLBOT_RANGE132[] = { 201354, 201460, 0 }; +const uint BELLBOT_RANGE133[] = { 201355, 201465, 0 }; +const uint BELLBOT_RANGE134[] = { 201356, 201415, 0 }; +const uint BELLBOT_RANGE135[] = { 201357, 201358, 0 }; +const uint BELLBOT_RANGE136[] = { 201359, 201410, 0 }; +const uint BELLBOT_RANGE137[] = { 201360, 201477, 0 }; +const uint BELLBOT_RANGE138[] = { 201361, 201422, 0 }; +const uint BELLBOT_RANGE139[] = { 201362, 201481, 0 }; +const uint BELLBOT_RANGE140[] = { 201363, 201364, 201440, 0 }; + +const uint BELLBOT_RANGE141[] = { 201365, 201366, 0 }; +const uint BELLBOT_RANGE142[] = { 201367, 201390, 0 }; +const uint BELLBOT_RANGE143[] = { 201368, 201461, 0 }; +const uint BELLBOT_RANGE144[] = { 201370, 201419, 0 }; +const uint BELLBOT_RANGE145[] = { 201371, 201462, 0 }; +const uint BELLBOT_RANGE146[] = { 201372, 201423, 201453, 0 }; +const uint BELLBOT_RANGE147[] = { 201374, 201443, 0 }; +const uint BELLBOT_RANGE148[] = { 201376, 201420, 0 }; +const uint BELLBOT_RANGE149[] = { 201377, 201409, 0 }; +const uint BELLBOT_RANGE150[] = { 201378, 201434, 0 }; + +const uint BELLBOT_RANGE151[] = { 201380, 201381, 0 }; +const uint BELLBOT_RANGE152[] = { 201382, 201396, 201414, 201446, 201463, 0 }; +const uint BELLBOT_RANGE153[] = { 201383, 201413, 0 }; +const uint BELLBOT_RANGE154[] = { 201401, 201402, 0 }; +const uint BELLBOT_RANGE155[] = { 201438, 201439, 0 }; +const uint BELLBOT_RANGE156[] = { 201493, 201494, 201495, 201496, 201497, 201498, 201499, 201500, 0 }; +const uint BELLBOT_RANGE157[] = { 201502, 201503, 201504, 201505, 201506, 201507, 201508, 201509, 0 }; +const uint BELLBOT_RANGE158[] = { 201513, 201514, 201515, 201516, 201517, 201518, 201519, 201520, 0 }; +const uint BELLBOT_RANGE159[] = { 201628, 201629, 0 }; +const uint BELLBOT_RANGE160[] = { 201640, 201641, 0 }; + +const uint BELLBOT_RANGE161[] = { 201663, 201664, 0 }; +const uint BELLBOT_RANGE162[] = { 201031, 201032, 0 }; +const uint BELLBOT_RANGE163[] = { 201442, 0 }; +const uint BELLBOT_RANGE164[] = { 201384, 201442, 0 }; +const uint BELLBOT_RANGE165[] = { + 200451, 200452, 200056, 200057, 200228, 201686, 201687, 201688, 201025, 201028, + 201029, 201030, 201033, 201051, 201060, 201061, 201086, 201703, 201315, 201316, + 201497, 201533, 201529, 201525, 201537, 201543, 201546, 201547, 201550, 201559, + 201565, 201573, 201580, 201584, 201594, 201595, 201596, 201597, 201598, 201599, + 201602, 201601, 201605, 201607, 201620, 201625, 201639, 201684, 0 }; +const uint BELLBOT_RANGE166[] = { 200083, 200084, 201335, 0 }; +const uint BELLBOT_RANGE167[] = { 200951, 200952, 200953, 200956, 201029, 200660, 201003, 201060, 201066, 201111, +201115, 0 }; +const uint BELLBOT_RANGE168[] = { 200109, 200110, 0 }; +const uint BELLBOT_RANGE169[] = { 200864, 200865, 0 }; +const uint BELLBOT_RANGE170[] = { 200090, 200091, 0 }; + +const uint BELLBOT_RANGE171[] = { 200675, 200676, 0 }; +const uint BELLBOT_RANGE172[] = { + 201979, 201980, 201981, 201982, 201983, 200442, 200238, 200236, 201098, 201101, + 201102, 201105, 201108, 201270, 201510, 0 +}; +const uint BELLBOT_RANGE173[] = { 202134, 202135, 202136, 202137, 202138, 202139, 0 }; +const uint BELLBOT_RANGE174[] = { 202276, 202232, 200858, 202276, 202276, 202276, 0 }; +const uint BELLBOT_RANGE175[] = { 202214, 202215, 200845, 0 }; +const uint BELLBOT_RANGE176[] = { 201852, 201853, 0 }; +const uint BELLBOT_RANGE177[] = { 202017, 202018, 0 }; +const uint BELLBOT_RANGE178[] = { 202023, 202024, 0 }; +const uint BELLBOT_RANGE179[] = { 202028, 202029, 0 }; +const uint BELLBOT_RANGE180[] = { 202031, 202032, 202033, 202034, 0 }; + +const uint BELLBOT_RANGE181[] = { 202036, 202037, 0 }; +const uint BELLBOT_RANGE182[] = { 202039, 202040, 202041, 0 }; +const uint BELLBOT_RANGE183[] = { 201810, 201811, 0 }; +const uint BELLBOT_RANGE184[] = { 201817, 201818, 201819, 0 }; +const uint BELLBOT_RANGE185[] = { 201823, 201824, 201825, 201826, 201827, 0 }; +const uint BELLBOT_RANGE186[] = { 201829, 201830, 201831, 0 }; +const uint BELLBOT_RANGE187[] = { 201833, 201834, 201838, 200273, 201840, 0 }; +const uint BELLBOT_RANGE188[] = { 201836, 201837, 201838, 0 }; +const uint BELLBOT_RANGE189[] = { 201842, 201843, 0 }; +const uint BELLBOT_RANGE190[] = { 201845, 201846, 0 }; + +const uint BELLBOT_RANGE191[] = { 201860, 201861, 201862, 201867, 201866, 0 }; +const uint BELLBOT_RANGE192[] = { 201866, 201867, 0 }; +const uint BELLBOT_RANGE193[] = { 201871, 201872, 201873, 201874, 0 }; +const uint BELLBOT_RANGE194[] = { 201878, 201879, 0 }; +const uint BELLBOT_RANGE195[] = { 201907, 201908, 201909, 201910, 0 }; +const uint BELLBOT_RANGE196[] = { 201917, 201918, 201919, 201920, 0 }; +const uint BELLBOT_RANGE197[] = { 201925, 201926, 201927, 201808, 0 }; +const uint BELLBOT_RANGE198[] = { 201931, 201932, 201810, 201811, 0 }; +const uint BELLBOT_RANGE199[] = { 201989, 201990, 0 }; +const uint BELLBOT_RANGE200[] = { 202049, 202050, 0 }; + +const uint BELLBOT_RANGE201[] = { 202053, 202054, 0 }; +const uint BELLBOT_RANGE202[] = { 202057, 202058, 202068, 200274, 0 }; +const uint BELLBOT_RANGE203[] = { 202060, 202061, 202062, 202063, 202064, 0 }; +const uint BELLBOT_RANGE204[] = { 202093, 202094, 200275, 202095, 0 }; +const uint BELLBOT_RANGE205[] = { 202097, 202098, 202099, 202100, 202101, 0 }; +const uint BELLBOT_RANGE206[] = { 202104, 202105, 202106, 0 }; +const uint BELLBOT_RANGE207[] = { 202112, 202113, 202114, 200277, 0 }; +const uint BELLBOT_RANGE208[] = { 200020, 200021, 202117, 202118, 200276, 0 }; +const uint BELLBOT_RANGE209[] = { 202120, 202121, 202122, 202123, 202124, 202125, 202126, 0 }; +const uint BELLBOT_RANGE210[] = { 202128, 202129, 202130, 0 }; + +const uint BELLBOT_RANGE211[] = { 202146, 202147, 202148, 201116, 0 }; +const uint BELLBOT_RANGE212[] = { 202151, 202152, 202153, 202154, 202155, 0 }; +const uint BELLBOT_RANGE213[] = { 202163, 202164, 200325, 202023, 202024, 202189, 0 }; +const uint BELLBOT_RANGE214[] = { 202166, 202167, 202168, 0 }; +const uint BELLBOT_RANGE215[] = { 202172, 202173, 0 }; +const uint BELLBOT_RANGE216[] = { 202176, 202177, 0 }; +const uint BELLBOT_RANGE217[] = { 202186, 202187, 0 }; +const uint BELLBOT_RANGE218[] = { 202192, 202193, 0 }; +const uint BELLBOT_RANGE219[] = { 202195, 202196, 202197, 202198, 202199, 202200, 0 }; +const uint BELLBOT_RANGE220[] = { 202158, 202159, 201076, 201077, 201078, 0 }; + +const uint BELLBOT_RANGE221[] = { 200849, 202001, 0 }; +const uint BELLBOT_RANGE222[] = { 202000, 200844, 0 }; +const uint BELLBOT_RANGE223[] = { 201915, 200272, 0 }; +const uint BELLBOT_RANGE224[] = { 200239, 201049, 201063, 201089, 201113, 202150, 201062, 0 }; +const uint BELLBOT_RANGE225[] = { 201984, 201985, 201049, 201065, 201068, 0 }; +const uint BELLBOT_RANGE226[] = { 200001, 200003, 200004, 200005, 200121, 200122, 200351, 200352, 200353, 200354, +200355, 200356, 200357, 200358, 202174, 201085, 200510, 202261, 0 }; +const uint BELLBOT_RANGE227[] = { 202134, 202135, 202136, 202137, 202138, 202139, 200352, 200358, 201084, 0 }; +const uint BELLBOT_RANGE228[] = { 200444, 200081, 200082, 200083, 200084, 200923, 201331, 201343, 202109, 0 }; +const uint BELLBOT_RANGE229[] = { 200280, 200080, 200287, 200922, 201337, 201338, 201339, 201908, 201909, 0 }; +const uint BELLBOT_RANGE230[] = { 201324, 200917, 200281, 200282, 200727, 200924, 200926, 0 }; + +const uint BELLBOT_RANGE231[] = { 201323, 200925, 200927, 200928, 200919, 200906, 201333, 202176, 202178, 202177, +201987, 201989, 201990, 0 }; +const uint BELLBOT_RANGE232[] = { + 200916, 200915, 200918, 200907, 200908, 200909, 200910, 200911, 200912, 200913, + 201325, 201326, 201327, 201328, 201329, 201330, 201332, 201334, 201335, 201336, + 201340, 201341, 201342, 201833, 201834, 0 +}; +const uint BELLBOT_RANGE233[] = { + 200125, 200205, 200264, 200419, 200440, 200443, 200445, 200446, 200447, 200438, + 200420, 200620, 200621, 200622, 200624, 200669, 200771, 200787, 200093, 201026, + 201047, 201088, 201271, 201086, 200664, 2006642, 0 }; +const uint BELLBOT_RANGE234[] = { 200729, 0 }; +const uint BELLBOT_RANGE235[] = { 200252, 200766, 201105, 201106, 201107, 201108, 0 }; +const uint BELLBOT_RANGE236[] = { 202220, 200537, 0 }; +const uint BELLBOT_RANGE237[] = { 202230, 202144, 0 }; +const uint BELLBOT_RANGE238[] = { 202019, 202018, 202017, 201049, 201050, 200891, 201043, 201521, 0 }; +const uint BELLBOT_RANGE239[] = { 200476, 202203, 0 }; +const uint BELLBOT_RANGE240[] = { 200475, 201856, 0 }; + +#define BELLBOT_RANGE_COUNT 283 +static ScriptRange BELLBOT_RANGES[283] = { + { 200058, BELLBOT_RANGE1, false, false }, + { 200000, BELLBOT_RANGE2, true, false }, + { 200019, BELLBOT_RANGE3, true, false }, + { 200022, BELLBOT_RANGE4, true, false }, + { 200027, BELLBOT_RANGE5, false, false }, + { 200033, BELLBOT_RANGE6, false, false }, + { 200037, BELLBOT_RANGE7, false, false }, + { 200060, BELLBOT_RANGE8, true, false }, + { 200067, BELLBOT_RANGE9, true, false }, + { 200075, BELLBOT_RANGE10, false, false }, + + { 200078, BELLBOT_RANGE11, false, false }, + { 200118, BELLBOT_RANGE12, false, false }, + { 200133, BELLBOT_RANGE13, false, false }, + { 200140, BELLBOT_RANGE14, true, false }, + { 200157, BELLBOT_RANGE15, true, false }, + { 200176, BELLBOT_RANGE16, true, false }, + { 200193, BELLBOT_RANGE17, true, false }, + { 200200, BELLBOT_RANGE18, false, false }, + { 200235, BELLBOT_RANGE19, false, false }, + { 200243, BELLBOT_RANGE20, false, false }, + + { 200261, BELLBOT_RANGE21, false, false }, + { 200279, BELLBOT_RANGE22, false, false }, + { 200283, BELLBOT_RANGE23, false, false }, + { 200290, BELLBOT_RANGE24, true, false }, + { 200293, BELLBOT_RANGE25, false, false }, + { 200306, BELLBOT_RANGE26, false, false }, + { 200311, BELLBOT_RANGE27, false, false }, + { 200323, BELLBOT_RANGE28, false, false }, + { 200330, BELLBOT_RANGE29, true, false }, + { 200336, BELLBOT_RANGE30, false, false }, + + { 200350, BELLBOT_RANGE31, false, false }, + { 200359, BELLBOT_RANGE32, false, false }, + { 200362, BELLBOT_RANGE33, false, false }, + { 200370, BELLBOT_RANGE34, false, false }, + { 200374, BELLBOT_RANGE35, false, false }, + { 200393, BELLBOT_RANGE36, false, false }, + { 200405, BELLBOT_RANGE37, false, false }, + { 200413, BELLBOT_RANGE38, false, false }, + { 200422, BELLBOT_RANGE39, false, false }, + { 200432, BELLBOT_RANGE40, true, false }, + + { 200436, BELLBOT_RANGE41, true, false }, + { 200448, BELLBOT_RANGE42, true, false }, + { 200455, BELLBOT_RANGE43, false, false }, + { 200481, BELLBOT_RANGE44, true, false }, + { 200496, BELLBOT_RANGE45, false, false }, + { 200507, BELLBOT_RANGE46, true, false }, + { 200516, BELLBOT_RANGE47, true, false }, + { 200528, BELLBOT_RANGE48, true, false }, + { 200539, BELLBOT_RANGE49, true, false }, + { 200557, BELLBOT_RANGE50, true, false }, + + { 200562, BELLBOT_RANGE51, true, false }, + { 200571, BELLBOT_RANGE52, true, false }, + { 200585, BELLBOT_RANGE53, true, false }, + { 200590, BELLBOT_RANGE54, true, false }, + { 200601, BELLBOT_RANGE55, true, false }, + { 200605, BELLBOT_RANGE56, true, false }, + { 200617, BELLBOT_RANGE57, true, false }, + { 200635, BELLBOT_RANGE58, false, false }, + { 200670, BELLBOT_RANGE59, false, false }, + { 200677, BELLBOT_RANGE60, true, false }, + + { 200686, BELLBOT_RANGE61, false, false }, + { 200698, BELLBOT_RANGE62, false, false }, + { 200704, BELLBOT_RANGE63, false, false }, + { 200710, BELLBOT_RANGE64, true, false }, + { 200716, BELLBOT_RANGE65, false, false }, + { 200723, BELLBOT_RANGE66, true, false }, + { 200733, BELLBOT_RANGE67, false, false }, + { 200748, BELLBOT_RANGE68, true, false }, + { 200757, BELLBOT_RANGE69, false, false }, + { 200773, BELLBOT_RANGE70, true, false }, + + { 200777, BELLBOT_RANGE71, true, false }, + { 200782, BELLBOT_RANGE72, true, false }, + { 200799, BELLBOT_RANGE73, true, false }, + { 200814, BELLBOT_RANGE74, true, false }, + { 200826, BELLBOT_RANGE75, true, false }, + { 200866, BELLBOT_RANGE76, true, false }, + { 200874, BELLBOT_RANGE77, false, false }, + { 200877, BELLBOT_RANGE78, true, false }, + { 200888, BELLBOT_RANGE79, true, false }, + { 200892, BELLBOT_RANGE80, true, false }, + + { 200398, BELLBOT_RANGE81, false, false }, + { 200113, BELLBOT_RANGE82, false, false }, + { 200658, BELLBOT_RANGE83, false, false }, + { 200302, BELLBOT_RANGE84, false, false }, + { 200836, BELLBOT_RANGE85, false, false }, + { 200789, BELLBOT_RANGE86, false, false }, + { 200770, BELLBOT_RANGE87, false, false }, + { 200136, BELLBOT_RANGE88, false, false }, + { 200544, BELLBOT_RANGE89, false, false }, + { 201685, BELLBOT_RANGE90, false, false }, + + { 201686, BELLBOT_RANGE91, true, false }, + { 201687, BELLBOT_RANGE92, true, false }, + { 201688, BELLBOT_RANGE93, true, false }, + { 201689, BELLBOT_RANGE94, false, false }, + { 201690, BELLBOT_RANGE95, false, false }, + { 201691, BELLBOT_RANGE96, false, false }, + { 201692, BELLBOT_RANGE97, true, false }, + { 201693, BELLBOT_RANGE98, true, false }, + { 201694, BELLBOT_RANGE99, false, false }, + { 201695, BELLBOT_RANGE100, true, false }, + + { 201696, BELLBOT_RANGE101, true, false }, + { 201697, BELLBOT_RANGE102, true, false }, + { 201698, BELLBOT_RANGE103, false, false }, + { 201699, BELLBOT_RANGE104, true, false }, + { 201700, BELLBOT_RANGE105, true, false }, + { 201701, BELLBOT_RANGE106, false, false }, + { 201702, BELLBOT_RANGE107, false, false }, + { 201703, BELLBOT_RANGE108, true, false }, + { 201704, BELLBOT_RANGE109, true, false }, + { 201705, BELLBOT_RANGE110, true, false }, + + { 201706, BELLBOT_RANGE111, true, false }, + { 201707, BELLBOT_RANGE112, true, false }, + { 201708, BELLBOT_RANGE113, false, false }, + + { 201709, BELLBOT_RANGE114, false, false }, + { 201710, BELLBOT_RANGE114, false, false }, + { 201711, BELLBOT_RANGE114, false, false }, + { 201712, BELLBOT_RANGE114, false, false }, + { 201713, BELLBOT_RANGE114, false, false }, + { 201714, BELLBOT_RANGE114, false, false }, + { 201715, BELLBOT_RANGE114, false, false }, + { 201716, BELLBOT_RANGE114, false, false }, + { 201717, BELLBOT_RANGE114, false, false }, + { 201718, BELLBOT_RANGE114, false, false }, + { 201719, BELLBOT_RANGE114, false, false }, + { 201720, BELLBOT_RANGE114, false, false }, + { 201721, BELLBOT_RANGE114, false, false }, + { 201722, BELLBOT_RANGE114, false, false }, + { 201723, BELLBOT_RANGE114, false, false }, + { 201724, BELLBOT_RANGE114, false, false }, + { 201725, BELLBOT_RANGE114, false, false }, + { 201726, BELLBOT_RANGE114, false, false }, + { 201727, BELLBOT_RANGE114, false, false }, + { 201728, BELLBOT_RANGE114, false, false }, + { 201729, BELLBOT_RANGE114, false, false }, + { 201730, BELLBOT_RANGE114, false, false }, + { 201731, BELLBOT_RANGE114, false, false }, + { 201732, BELLBOT_RANGE114, false, false }, + { 201733, BELLBOT_RANGE114, false, false }, + { 201735, BELLBOT_RANGE114, false, false }, + { 201736, BELLBOT_RANGE114, false, false }, + { 201737, BELLBOT_RANGE114, false, false }, + { 201738, BELLBOT_RANGE114, false, false }, + { 201739, BELLBOT_RANGE114, false, false }, + { 201740, BELLBOT_RANGE114, false, false }, + { 201741, BELLBOT_RANGE114, false, false }, + { 201743, BELLBOT_RANGE114, false, false }, + { 201744, BELLBOT_RANGE114, false, false }, + { 201745, BELLBOT_RANGE114, false, false }, + { 201746, BELLBOT_RANGE114, false, false }, + { 201747, BELLBOT_RANGE114, false, false }, + { 201748, BELLBOT_RANGE114, false, false }, + { 201749, BELLBOT_RANGE114, false, false }, + { 201750, BELLBOT_RANGE114, false, false }, + { 201751, BELLBOT_RANGE114, false, false }, + { 201752, BELLBOT_RANGE114, false, false }, + { 201753, BELLBOT_RANGE114, false, false }, + { 201754, BELLBOT_RANGE114, false, false }, + + { 201755, BELLBOT_RANGE115, true, false }, + { 201756, BELLBOT_RANGE116, true, false }, + { 201757, BELLBOT_RANGE117, true, false }, + { 201758, BELLBOT_RANGE118, true, false }, + { 201759, BELLBOT_RANGE119, true, false }, + { 201760, BELLBOT_RANGE120, false, false }, + + { 201761, BELLBOT_RANGE121, true, false }, + { 201762, BELLBOT_RANGE122, true, false }, + { 201763, BELLBOT_RANGE123, true, false }, + { 201764, BELLBOT_RANGE124, false, false }, + { 201765, BELLBOT_RANGE125, false, false }, + { 201766, BELLBOT_RANGE126, false, false }, + { 201767, BELLBOT_RANGE127, false, false }, + { 201768, BELLBOT_RANGE128, false, false }, + { 201769, BELLBOT_RANGE129, false, false }, + { 201770, BELLBOT_RANGE130, false, false }, + + { 201771, BELLBOT_RANGE131, true, false }, + { 201772, BELLBOT_RANGE132, false, false }, + { 201773, BELLBOT_RANGE133, false, false }, + { 201774, BELLBOT_RANGE134, false, false }, + { 201775, BELLBOT_RANGE135, false, false }, + { 201776, BELLBOT_RANGE136, false, false }, + { 201777, BELLBOT_RANGE137, false, false }, + { 201778, BELLBOT_RANGE138, false, false }, + { 201779, BELLBOT_RANGE139, false, false }, + { 201780, BELLBOT_RANGE140, false, false }, + + { 201781, BELLBOT_RANGE141, false, false }, + { 201782, BELLBOT_RANGE142, false, false }, + { 201783, BELLBOT_RANGE143, false, false }, + { 201784, BELLBOT_RANGE144, false, false }, + { 201785, BELLBOT_RANGE145, false, false }, + { 201786, BELLBOT_RANGE146, false, false }, + { 201787, BELLBOT_RANGE147, false, false }, + { 201788, BELLBOT_RANGE148, false, false }, + { 201789, BELLBOT_RANGE149, false, false }, + { 201790, BELLBOT_RANGE150, false, false }, + + { 201791, BELLBOT_RANGE151, false, false }, + { 201792, BELLBOT_RANGE152, false, false }, + { 201793, BELLBOT_RANGE153, false, false }, + { 201794, BELLBOT_RANGE154, false, false }, + { 201795, BELLBOT_RANGE155, false, false }, + { 201796, BELLBOT_RANGE156, true, false }, + { 201797, BELLBOT_RANGE157, false, false }, + { 201798, BELLBOT_RANGE158, false, false }, + { 201799, BELLBOT_RANGE159, false, false }, + { 201800, BELLBOT_RANGE160, false, false }, + + { 201801, BELLBOT_RANGE161, false, false }, + { 201802, BELLBOT_RANGE162, false, false }, + { 201803, BELLBOT_RANGE163, false, false }, + { 201804, BELLBOT_RANGE164, true, false }, + { 201805, BELLBOT_RANGE165, true, false }, + { 201806, BELLBOT_RANGE166, true, false }, + { 201807, BELLBOT_RANGE167, true, false }, + { 200108, BELLBOT_RANGE168, false, false }, + { 200863, BELLBOT_RANGE169, false, false }, + { 200089, BELLBOT_RANGE170, false, false }, + + { 200674, BELLBOT_RANGE171, false, false }, + { 201978, BELLBOT_RANGE172, true, false }, + { 202133, BELLBOT_RANGE173, true, false }, + { 202231, BELLBOT_RANGE174, true, false }, + { 202213, BELLBOT_RANGE175, true, false }, + { 201851, BELLBOT_RANGE176, true, false }, + { 202016, BELLBOT_RANGE177, false, false }, + { 202022, BELLBOT_RANGE178, false, false }, + { 202027, BELLBOT_RANGE179, false, false }, + { 202030, BELLBOT_RANGE180, true, false }, + + { 202035, BELLBOT_RANGE181, false, false }, + { 202038, BELLBOT_RANGE182, false, false }, + { 201809, BELLBOT_RANGE183, true, false }, + { 201816, BELLBOT_RANGE184, true, false }, + { 201822, BELLBOT_RANGE185, false, false }, + { 201828, BELLBOT_RANGE186, true, false }, + { 201832, BELLBOT_RANGE187, true, false }, + { 201835, BELLBOT_RANGE188, true, false }, + { 201841, BELLBOT_RANGE189, true, false }, + { 201844, BELLBOT_RANGE190, true, false }, + + { 201859, BELLBOT_RANGE191, true, false }, + { 201865, BELLBOT_RANGE192, true, false }, + { 201870, BELLBOT_RANGE193, false, false }, + { 201877, BELLBOT_RANGE194, false, false }, + { 201906, BELLBOT_RANGE195, true, false }, + { 201916, BELLBOT_RANGE196, true, false }, + { 201924, BELLBOT_RANGE197, true, false }, + { 201930, BELLBOT_RANGE198, true, false }, + { 201988, BELLBOT_RANGE199, true, false }, + { 202048, BELLBOT_RANGE200, true, false }, + + { 202052, BELLBOT_RANGE201, true, false }, + { 202056, BELLBOT_RANGE202, true, false }, + { 202059, BELLBOT_RANGE203, true, false }, + { 202092, BELLBOT_RANGE204, true, false }, + { 202096, BELLBOT_RANGE205, false, false }, + { 202103, BELLBOT_RANGE206, true, false }, + { 202111, BELLBOT_RANGE207, true, false }, + { 202116, BELLBOT_RANGE208, true, true }, + { 202119, BELLBOT_RANGE209, true, false }, + { 202127, BELLBOT_RANGE210, true, false }, + + { 202145, BELLBOT_RANGE211, true, false }, + { 202150, BELLBOT_RANGE212, true, false }, + { 202162, BELLBOT_RANGE213, true, false }, + { 202165, BELLBOT_RANGE214, true, false }, + { 202171, BELLBOT_RANGE215, true, false }, + { 202175, BELLBOT_RANGE216, false, false }, + { 202185, BELLBOT_RANGE217, false, false }, + { 202191, BELLBOT_RANGE218, false, false }, + { 202194, BELLBOT_RANGE219, false, false }, + { 202157, BELLBOT_RANGE220, false, false }, + + { 202256, BELLBOT_RANGE221, true, false }, + { 202255, BELLBOT_RANGE222, true, false }, + { 202257, BELLBOT_RANGE223, true, false }, + { 202258, BELLBOT_RANGE224, true, false }, + { 202259, BELLBOT_RANGE225, true, false }, + { 202260, BELLBOT_RANGE226, true, false }, + { 202261, BELLBOT_RANGE227, true, false }, + { 202262, BELLBOT_RANGE228, true, false }, + { 202263, BELLBOT_RANGE229, true, false }, + { 202264, BELLBOT_RANGE230, true, false }, + + { 202265, BELLBOT_RANGE231, true, false }, + { 202266, BELLBOT_RANGE232, true, false }, + { 202267, BELLBOT_RANGE233, true, false }, + { 202268, BELLBOT_RANGE234, true, false }, + { 202269, BELLBOT_RANGE235, true, false }, + { 202270, BELLBOT_RANGE236, true, false }, + { 202271, BELLBOT_RANGE237, true, false }, + { 202272, BELLBOT_RANGE238, true, false }, + { 202273, BELLBOT_RANGE239, true, false }, + { 202274, BELLBOT_RANGE240, true, false } +}; + +const uint DESKBOT_RANGE1[] = { 240002, 240003, 240006, 240007, 0 }; +const uint DESKBOT_RANGE2[] = { 240008, 240009, 240010, 240011, 240012, 240013, 240004, 240005, 0 }; +const uint DESKBOT_RANGE3[] = { 240336, 240337, 240338, 240339, 240340, 240341, 240342, 240343, 240344, 0 }; +const uint DESKBOT_RANGE4[] = { 240345, 240346, 240347, 0 }; +const uint DESKBOT_RANGE5[] = { 240348, 240349, 240350, 0 }; +const uint DESKBOT_RANGE6[] = { 240351, 240352, 240353, 0 }; +const uint DESKBOT_RANGE7[] = { 240355, 240356, 240357, 0 }; +const uint DESKBOT_RANGE8[] = { 240359, 240360, 240361, 0 }; +const uint DESKBOT_RANGE9[] = { 240362, 240363, 240364, 240365, 240366, 240367, 0 }; +const uint DESKBOT_RANGE10[] = { 240368, 240369, 240370, 240371, 0 }; + +const uint DESKBOT_RANGE11[] = { 240372, 240373, 240374, 0 }; +const uint DESKBOT_RANGE12[] = { 240375, 240376, 240377, 0 }; +const uint DESKBOT_RANGE13[] = { 240378, 240379, 240380, 0 }; +const uint DESKBOT_RANGE14[] = { 240381, 240382, 240383, 240384, 0 }; +const uint DESKBOT_RANGE15[] = { 240385, 240386, 240387, 0 }; +const uint DESKBOT_RANGE16[] = { 240388, 240389, 240390, 0 }; +const uint DESKBOT_RANGE17[] = { 240391, 240392, 240393, 0 }; +const uint DESKBOT_RANGE18[] = { 240394, 240395, 240396, 240397, 0 }; +const uint DESKBOT_RANGE19[] = { 240399, 0 }; +const uint DESKBOT_RANGE20[] = { 240401, 240402, 240403, 0 }; + +const uint DESKBOT_RANGE21[] = { 240404, 240405, 240406, 0 }; +const uint DESKBOT_RANGE22[] = { 240407, 240408, 240409, 240900, 240410, 240411, 240412, 240900, 241671, 241672, +241673, 241671, 241672, 241673, 241671, 241672, 241673, 0 }; +const uint DESKBOT_RANGE23[] = { 240421, 240422, 0 }; +const uint DESKBOT_RANGE24[] = { 240451, 240424, 240425, 240426, 240452, 240455, 240456, 240457, 240458, 240459, 240460, 0 }; +const uint DESKBOT_RANGE25[] = { 240451, 240424, 240425, 240426, 240452, 240455, 240456, 240457, 240458, 0 }; +const uint DESKBOT_RANGE26[] = { 240428, 240429, 240430, 0 }; +const uint DESKBOT_RANGE27[] = { 240431, 240432, 0 }; +const uint DESKBOT_RANGE28[] = { 240435, 240436, 240437, 240438, 240439, 0 }; +const uint DESKBOT_RANGE29[] = { 240440, 240441, 240442, 240443, 240444, 0 }; +const uint DESKBOT_RANGE30[] = { 240451, 240452, 0 }; + +const uint DESKBOT_RANGE31[] = { 240455, 240456, 240457, 240458, 240459, 240460, 0 }; +const uint DESKBOT_RANGE32[] = { 240461, 240462, 240463, 240464, 240977, 240978, 240979, 240980, 240804, 240806, + 240807, 240808, 0 }; +const uint DESKBOT_RANGE33[] = { 241742, 241743, 241744, 241745, 241746, 241747, 241748, 240954, 0 }; +const uint DESKBOT_RANGE34[] = { 240480, 240481, 240482, 0 }; +const uint DESKBOT_RANGE35[] = { 241117, 241515, 0 }; +const uint DESKBOT_RANGE36[] = { 240486, 241585, 240487, 241585, 240488, 241585, 0 }; +const uint DESKBOT_RANGE37[] = { 240490, 240491, 0 }; +const uint DESKBOT_RANGE38[] = { 240496, 240507, 240518, 240529, 240540, 240542, 240543, 240544, 240545, 240497, + 240498, 240499, 240500, 240501, 240502, 240503, 240504, 240505, 240506, 240508, + 240509, 240510, 240511, 240512, 240513, 240514, 240515, 240516, 240517, 240519, + 240520, 240521, 240522, 240523, 240524, 240525, 240526, 240527, 240528, 240530, + 240531, 240532, 240533, 240534, 240535, 240536, 240537, 240538, 240539, 240541, 0 }; +const uint DESKBOT_RANGE39[] = { 240587, 240588, 0 }; +const uint DESKBOT_RANGE40[] = { 240589, 240590, 240591, 241652, 0 }; + +const uint DESKBOT_RANGE41[] = { 240592, 240593, 240594, 241653, 0 }; +const uint DESKBOT_RANGE42[] = { 240595, 240596, 0 }; +const uint DESKBOT_RANGE43[] = { 240597, 240598, 0 }; +const uint DESKBOT_RANGE44[] = { 240602, 240613, 240622, 240623, 240624, 240627, 240603, 240606, 240609, 0 }; +const uint DESKBOT_RANGE45[] = { 240629, 240630, 240354, 0 }; +const uint DESKBOT_RANGE46[] = { 240635, 240636, 240637, 0 }; +const uint DESKBOT_RANGE47[] = { + 240640, 240656, 240667, 240678, 240689, 240699, 240710, 240721, 240732, 240641, + 240647, 240648, 240649, 240650, 240651, 240652, 240653, 240654, 240655, 240657, + 240658, 240659, 240660, 240661, 240662, 240663, 240664, 240665, 240666, 240668, + 240669, 240670, 240671, 240672, 240673, 240674, 240675, 240676, 240677, 240679, + 240680, 240681, 240682, 240683, 240684, 240685, 240686, 240687, 240688, 240690, + 240691, 240692, 240693, 240694, 240695, 240696, 240697, 240698, 240700, 240701, + 240702, 240703, 240704, 240705, 240706, 240707, 240708, 240709, 240711, 240712, + 240713, 240714, 240715, 240716, 240717, 240718, 240719, 240720, 240722, 240723, + 240724, 240725, 240726, 240727, 240728, 240729, 240730, 240731, 240733, 240734, + 240735, 240736, 240737, 240738, 240739, 240740, 240741, 240742, 240642, 240643, + 240644, 240645, 240646, 0 +}; +const uint DESKBOT_RANGE48[] = { 240758, 240759, 240760, 0 }; +const uint DESKBOT_RANGE49[] = { 240761, 240762, 240764, 240766, 0 }; +const uint DESKBOT_RANGE50[] = { 240335, 240776, 240778, 240779, 240780, 240781, 0 }; + +const uint DESKBOT_RANGE51[] = { 240335, 240776, 240777, 240778, 240779, 240780, 240781, 0 }; +const uint DESKBOT_RANGE52[] = { 240782, 240783, 240834, 240592, 240589, 240768, 240770, 240771, 240769, 240772, +240773, 240590, 240593, 240595, 240587, 240597, 240591, 240594, 240596, 240588, +240598, 241120, 240675, 241124, 0 }; +const uint DESKBOT_RANGE53[] = { 240787, 240788, 240789, 240790, 240791, 241635, 0 }; +const uint DESKBOT_RANGE54[] = { 240792, 240793, 240794, 240795, 240796, 240797, 241635, 0 }; +const uint DESKBOT_RANGE55[] = { 240798, 240799, 240800, 241635, 0 }; +const uint DESKBOT_RANGE56[] = { 240804, 240806, 240807, 240808, 0 }; +const uint DESKBOT_RANGE57[] = { 240809, 240820, 240822, 240823, 240824, 240825, 240826, 240827, 240828, 240829, +240810, 240811, 240812, 240813, 240814, 240815, 240816, 240817, 240818, 240819, +240821, 0 }; +const uint DESKBOT_RANGE58[] = { 240835, 240836, 240837, 240838, 240839, 240840, 0 }; +const uint DESKBOT_RANGE59[] = { 240861, 240862, 240863, 0 }; +const uint DESKBOT_RANGE60[] = { 240881, 240883, 240884, 240885, 240886, 240887, 240888, 240889, 240890, 240882, 0 }; + +const uint DESKBOT_RANGE61[] = { 240894, 240895, 240896, 240897, 240898, 240899, 240900, 240901, 240902, 0 }; +const uint DESKBOT_RANGE62[] = { 240904, 240905, 240906, 240907, 240908, 241342, 0 }; +const uint DESKBOT_RANGE63[] = { 240911, 240922, 240930, 240932, 240933, 240934, 240935, 240936, 240937, 240912, + 240913, 240914, 240915, 240916, 240917, 240918, 240919, 240920, 240921, 240923, + 240931, 240925, 240926, 240927, 240928, 240929, 0 +}; +const uint DESKBOT_RANGE64[] = { 240948, 240949, 240950, 240951, 0 }; +const uint DESKBOT_RANGE65[] = { 240959, 240960, 240961, 240962, 0 }; +const uint DESKBOT_RANGE66[] = { 240965, 240966, 0 }; +const uint DESKBOT_RANGE67[] = { 240972, 240973, 240974, 0 }; +const uint DESKBOT_RANGE68[] = { 240977, 240978, 240979, 240980, 0 }; +const uint DESKBOT_RANGE69[] = { 240982, 240983, 240984, 240985, 0 }; +const uint DESKBOT_RANGE70[] = { 240988, 240989, 240990, 240991, 0 }; + +const uint DESKBOT_RANGE71[] = { 240992, 240994, 240995, 240996, 240997, 240998, 241000, 241001, 0 }; +const uint DESKBOT_RANGE72[] = { 241002, 241004, 241005, 241006, 241007, 241008, 241009, 241010, 241011, 241003, 0 }; +const uint DESKBOT_RANGE73[] = { + 241012, 241023, 241034, 241045, 241050, 241051, 241052, 241053, 241054, 241013, + 241014, 241015, 241016, 241017, 241018, 241019, 241020, 241021, 241022, 241024, + 241025, 241026, 241027, 241028, 241029, 241030, 241031, 241032, 241033, 241035, + 241036, 241037, 241038, 241039, 241040, 241041, 241042, 241043, 241044, 241046, + 241047, 241048, 241049, 0 +}; +const uint DESKBOT_RANGE74[] = { 241055, 241057, 241058, 241059, 241060, 241061, 241062, 241063, 241064, 241056, 0 }; +const uint DESKBOT_RANGE75[] = { 241078, 241079, 241080, 241081, 241082, 241083, 241084, 241085, 0 }; +const uint DESKBOT_RANGE76[] = { 241091, 241092, 241093, 241094, 241095, 0 }; +const uint DESKBOT_RANGE77[] = { 241103, 241104, 241105, 241106, 241107, 0 }; +const uint DESKBOT_RANGE78[] = { + 241132, 241127, 241133, 241140, 241151, 241152, 241153, 241154, 241155, 241156, + 241157, 241128, 241129, 241130, 241131, 241136, 241137, 241138, 241139, 241141, + 241142, 241143, 241144, 241145, 241146, 241147, 241148, 241149, 241150, 0 +}; +const uint DESKBOT_RANGE79[] = { 240404, 241099, 0 }; +const uint DESKBOT_RANGE80[] = { 241125, 241124, 241125, 241125, 240649, 240729, 241686, 241680, 241738, 0 }; + +const uint DESKBOT_RANGE81[] = { 241096, 241112, 240727, 241679, 241738, 0 }; +const uint DESKBOT_RANGE82[] = { 240833, 240845, 241464, 241465, 241674, 241738, 0 }; +const uint DESKBOT_RANGE83[] = { 240726, 241684, 241738, 0 }; +const uint DESKBOT_RANGE84[] = { 240728, 240728, 240728, 240644, 240953, 240728, 240601, 240728, 241075, 240728, +240952, 240728, 240600, 241120, 241683, 241738, 241738, 241738, 0 }; +const uint DESKBOT_RANGE85[] = { 240730, 241738, 0 }; +const uint DESKBOT_RANGE86[] = { 240008, 240009, 240010, 240011, 240012, 240013, 240004, 240005, 0 }; +const uint DESKBOT_RANGE87[] = { 240677, 240680, 240766, 241109, 240633, 240747, 240940, 241187, 241120, 240665, +240669, 240620, 0 }; +const uint DESKBOT_RANGE88[] = { + 240948, 240602, 240613, 240622, 240624, 240625, 240626, 240627, 240603, 240605, + 240607, 240609, 240610, 241150, 240925, 240882, 240864, 241072, 240942, 240867, + 241096, 240971, 240785, 240868, 240833, 240955, 241077, 240877, 240754, 241163, + 241071, 241161, 240871, 241114, 240963, 240956, 240750, 240958, 240851, 240866, + 241100, 240941, 241115, 241088, 240628, 240846, 240857, 241164, 241165, 240954, + 241087, 240869, 240784, 240637, 240700, 240701, 240704, 240929, 240716, 240717, + 240720, 240689, 240732, 240648, 240653, 240664, 240676, 0 +}; +const uint DESKBOT_RANGE89[] = { 241012, 0 }; +const uint DESKBOT_RANGE90[] = { 240775, 240419, 240701, 240642, 240802, 240891, 241110, 241568, 241569, 241570, 241571, 0 }; + +const uint DESKBOT_RANGE91[] = { 241338, 240831, 0 }; +const uint DESKBOT_RANGE92[] = { 240416, 241343, 0 }; +const uint DESKBOT_RANGE93[] = { 241577, 241578, 241579, 241580, 241581, 241582, 0 }; +const uint DESKBOT_RANGE94[] = { 241383, 241586, 0 }; +const uint DESKBOT_RANGE95[] = { 241446, 241447, 241448, 0 }; +const uint DESKBOT_RANGE96[] = { 241443, 241444, 241445, 0 }; +const uint DESKBOT_RANGE97[] = { 241116, 241365, 0 }; +const uint DESKBOT_RANGE98[] = { + 241522, 241523, 241524, 241525, 241526, 241527, 241528, 241529, 241530, 241531, + 241532, 241533, 241534, 241535, 241536, 241537, 241538, 241539, 241540, 241541, + 241542, 241543, 241544, 241545, 241546, 241547, 241548, 241549, 241550, 241551, + 241552, 241553, 241554, 0 +}; +const uint DESKBOT_RANGE99[] = { 241341, 241634, 0 }; +const uint DESKBOT_RANGE100[] = { 241449, 241635, 241450, 241635, 0 }; + +const uint DESKBOT_RANGE101[] = { 241638, 241639, 241640, 241654, 241655, 241643, 0 }; +const uint DESKBOT_RANGE102[] = { 241702, 241703, 241704, 0 }; +const uint DESKBOT_RANGE103[] = { 240465, 241641, 0 }; +const uint DESKBOT_RANGE104[] = { 241371, 241111, 0 }; + +#define DESKBOT_RANGE_COUNT 146 +const ScriptRange DESKBOT_RANGES[146] = { + { 240546, DESKBOT_RANGE1, false, false }, + { 240547, DESKBOT_RANGE2, false, false }, + { 240548, DESKBOT_RANGE3, false, false }, + { 240549, DESKBOT_RANGE4, false, false }, + { 240550, DESKBOT_RANGE5, false, false }, + { 240551, DESKBOT_RANGE6, false, false }, + { 240552, DESKBOT_RANGE7, false, false }, + { 240553, DESKBOT_RANGE8, false, false }, + { 240554, DESKBOT_RANGE9, false, false }, + { 240555, DESKBOT_RANGE10, false, false }, + + { 240556, DESKBOT_RANGE11, false, false }, + { 240557, DESKBOT_RANGE12, false, false }, + { 240558, DESKBOT_RANGE13, false, false }, + { 240559, DESKBOT_RANGE14, false, false }, + { 240560, DESKBOT_RANGE15, false, false }, + { 240561, DESKBOT_RANGE16, false, false }, + { 240562, DESKBOT_RANGE17, false, false }, + { 240563, DESKBOT_RANGE18, false, false }, + { 240564, DESKBOT_RANGE19, false, false }, + { 240565, DESKBOT_RANGE20, false, false }, + + { 240566, DESKBOT_RANGE21, false, false }, + { 240567, DESKBOT_RANGE22, true, false }, + { 240568, DESKBOT_RANGE23, false, false }, + { 240569, DESKBOT_RANGE24, false, false }, + { 240570, DESKBOT_RANGE25, false, false }, + { 240571, DESKBOT_RANGE26, false, false }, + { 240572, DESKBOT_RANGE27, false, false }, + { 240573, DESKBOT_RANGE28, true, false }, + { 240574, DESKBOT_RANGE29, false, false }, + { 240575, DESKBOT_RANGE30, false, false }, + + { 240576, DESKBOT_RANGE31, false, false }, + { 240577, DESKBOT_RANGE32, true, false }, + { 240578, DESKBOT_RANGE33, true, false }, + { 240579, DESKBOT_RANGE34, false, false }, + { 240580, DESKBOT_RANGE35, true, false }, + { 240581, DESKBOT_RANGE36, false, false }, + { 240582, DESKBOT_RANGE37, false, false }, + { 240583, DESKBOT_RANGE38, false, false }, + { 241167, DESKBOT_RANGE39, false, false }, + { 241168, DESKBOT_RANGE40, true, false }, + + { 241169, DESKBOT_RANGE41, true, false }, + { 241170, DESKBOT_RANGE42, false, false }, + { 241171, DESKBOT_RANGE43, false, false }, + { 241172, DESKBOT_RANGE44, false, false }, + { 241173, DESKBOT_RANGE45, false, false }, + { 241174, DESKBOT_RANGE46, false, false }, + { 241175, DESKBOT_RANGE47, false, false }, + { 241176, DESKBOT_RANGE48, false, false }, + { 241177, DESKBOT_RANGE49, false, false }, + { 241178, DESKBOT_RANGE50, true, false }, + + { 241179, DESKBOT_RANGE51, true, false }, + { 241180, DESKBOT_RANGE52, true, false }, + { 241181, DESKBOT_RANGE53, true, false }, + { 241182, DESKBOT_RANGE54, true, false }, + { 241183, DESKBOT_RANGE55, true, false }, + { 241184, DESKBOT_RANGE56, true, false }, + { 241185, DESKBOT_RANGE57, false, false }, + { 241186, DESKBOT_RANGE58, false, false }, + { 241187, DESKBOT_RANGE59, false, false }, + { 241188, DESKBOT_RANGE60, true, false }, + + { 241189, DESKBOT_RANGE61, false, false }, + { 241190, DESKBOT_RANGE62, true, false }, + { 241191, DESKBOT_RANGE63, true, false }, + { 241192, DESKBOT_RANGE64, false, false }, + { 241193, DESKBOT_RANGE65, false, false }, + { 241194, DESKBOT_RANGE66, false, false }, + { 241195, DESKBOT_RANGE67, false, false }, + { 241196, DESKBOT_RANGE68, false, false }, + { 241197, DESKBOT_RANGE69, true, false }, + { 241198, DESKBOT_RANGE70, true, false }, + + { 241199, DESKBOT_RANGE71, false, false }, + { 241200, DESKBOT_RANGE72, false, false }, + { 241201, DESKBOT_RANGE73, false, false }, + { 241202, DESKBOT_RANGE74, false, false }, + { 241203, DESKBOT_RANGE75, false, false }, + { 241204, DESKBOT_RANGE76, false, false }, + { 241205, DESKBOT_RANGE77, false, false }, + { 241166, DESKBOT_RANGE78, false, false }, + { 241206, DESKBOT_RANGE79, false, false }, + { 241207, DESKBOT_RANGE80, true, false }, + + { 241208, DESKBOT_RANGE81, true, false }, + { 241209, DESKBOT_RANGE82, true, false }, + { 241210, DESKBOT_RANGE83, true, false }, + { 241211, DESKBOT_RANGE84, true, false }, + { 241212, DESKBOT_RANGE85, true, false }, + { 241213, DESKBOT_RANGE86, true, false }, + { 241214, DESKBOT_RANGE87, true, false }, + { 241215, DESKBOT_RANGE88, true, false }, + + { 241217, DESKBOT_RANGE89, false, false }, + { 241218, DESKBOT_RANGE89, false, false }, + { 241219, DESKBOT_RANGE89, false, false }, + { 241220, DESKBOT_RANGE89, false, false }, + { 241221, DESKBOT_RANGE89, false, false }, + { 241222, DESKBOT_RANGE89, false, false }, + { 241223, DESKBOT_RANGE89, false, false }, + { 241224, DESKBOT_RANGE89, false, false }, + { 241225, DESKBOT_RANGE89, false, false }, + { 241226, DESKBOT_RANGE89, false, false }, + { 241227, DESKBOT_RANGE89, false, false }, + { 241228, DESKBOT_RANGE89, false, false }, + { 241229, DESKBOT_RANGE89, false, false }, + { 241230, DESKBOT_RANGE89, false, false }, + { 241231, DESKBOT_RANGE89, false, false }, + { 241232, DESKBOT_RANGE89, false, false }, + { 241233, DESKBOT_RANGE89, false, false }, + { 241234, DESKBOT_RANGE89, false, false }, + { 241235, DESKBOT_RANGE89, false, false }, + { 241236, DESKBOT_RANGE89, false, false }, + { 241237, DESKBOT_RANGE89, false, false }, + { 241238, DESKBOT_RANGE89, false, false }, + { 241239, DESKBOT_RANGE89, false, false }, + { 241240, DESKBOT_RANGE89, false, false }, + { 241241, DESKBOT_RANGE89, false, false }, + { 241242, DESKBOT_RANGE89, false, false }, + { 241243, DESKBOT_RANGE89, false, false }, + { 241244, DESKBOT_RANGE89, false, false }, + { 241245, DESKBOT_RANGE89, false, false }, + { 241246, DESKBOT_RANGE89, false, false }, + { 241247, DESKBOT_RANGE89, false, false }, + { 241248, DESKBOT_RANGE89, false, false }, + { 241249, DESKBOT_RANGE89, false, false }, + { 241250, DESKBOT_RANGE89, false, false }, + { 241251, DESKBOT_RANGE89, false, false }, + { 241252, DESKBOT_RANGE89, false, false }, + { 241253, DESKBOT_RANGE89, false, false }, + { 241254, DESKBOT_RANGE89, false, false }, + { 241255, DESKBOT_RANGE89, false, false }, + { 241256, DESKBOT_RANGE89, false, false }, + { 241257, DESKBOT_RANGE89, false, false }, + { 241258, DESKBOT_RANGE89, false, false }, + { 241259, DESKBOT_RANGE89, false, false }, + + { 241216, DESKBOT_RANGE90, true, false }, + { 241625, DESKBOT_RANGE91, false, false }, + { 241626, DESKBOT_RANGE92, true, false }, + { 241627, DESKBOT_RANGE93, false, false }, + { 241628, DESKBOT_RANGE94, true, false }, + { 241629, DESKBOT_RANGE95, true, false }, + { 241630, DESKBOT_RANGE96, true, false }, + { 241631, DESKBOT_RANGE97, true, false }, + { 241632, DESKBOT_RANGE98, true, false }, + { 241633, DESKBOT_RANGE99, true, false }, + { 241634, DESKBOT_RANGE100, true, false }, + + { 241738, DESKBOT_RANGE101, true, false }, + { 241739, DESKBOT_RANGE102, true, false }, + { 241740, DESKBOT_RANGE103, true, false }, + { 241741, DESKBOT_RANGE104, true, false } +}; + +const uint DOORBOT_RANGE1[] = { 220075, 220078, 220080, 220081, 220082, 220083, 220084, 0 }; +const uint DOORBOT_RANGE2[] = { 220077, 220079, 220076, 0 }; +const uint DOORBOT_RANGE3[] = { + 220008, 220009, 220010, 220011, 220012, 220013, 220014, + 220015, 220016, 221053, 221054, 221055, 221056, 221057, + 221058, 221059, 221060, 221061, 0 +}; +const uint DOORBOT_RANGE4[] = { + 221062, 221063, 221064, 221065, 221066, 221067, 221068, + 221069, 221070, 221071, 221072, 221073, 221074, 221075, + 221076, 221077, 221078, 221079, 221080, 221081, 221082, + 0 +}; +const uint DOORBOT_RANGE5[] = { 220737, 220738, 220739, 220740, 0 }; +const uint DOORBOT_RANGE6[] = { 220759, 220760, 220761, 0 }; +const uint DOORBOT_RANGE7[] = { 220771, 220772, 220773, 220774, 220775, 0 }; +const uint DOORBOT_RANGE8[] = { 220792, 220793, 220794, 220795, 220796, 220797, 220798, 0 }; +const uint DOORBOT_RANGE9[] = { 220017, 220018, 220019, 220020, 220833, 0 }; +const uint DOORBOT_RANGE10[] = { 220035, 220036, 220038, 0 }; + +const uint DOORBOT_RANGE11[] = { 220093, 220094, 220095, 0 }; +const uint DOORBOT_RANGE12[] = { 220109, 220117, 0 }; +const uint DOORBOT_RANGE13[] = { 220837, 220838, 220839, 0 }; +const uint DOORBOT_RANGE14[] = { 220849, 220850, 220851, 220852, 0 }; +const uint DOORBOT_RANGE15[] = { 220858, 220860, 0 }; +const uint DOORBOT_RANGE16[] = { 221043, 221045, 221046, 221047, 221048, 221049, 221050, + 221051, 221052, 221044, 0 }; +const uint DOORBOT_RANGE17[] = { 221140, 221141, 221142, 221143, 221144, 221145, 221146, + 221147, 0 }; +const uint DOORBOT_RANGE18[] = { 220885, 220886, 220887, 220888, 220890, 220883, 220884, + 220889, 0 }; +const uint DOORBOT_RANGE19[] = { + 221356, 221364, 221365, 221366, 221129, 221367, 221368, + 221132, 221369, 221357, 221359, 221363, 220902, 0 +}; +const uint DOORBOT_RANGE20[] = { 221129, 221130, 221131, 221132, 221133, 221136, 221137, + 221138, 0 }; +const uint DOORBOT_RANGE21[] = { 221157, 221165, 221166, 221167, 221130, 221168, 221169, + 221132, 221170, 221171, 221158, 220910, 0 }; +const uint DOORBOT_RANGE22[] = { 221356, 221364, 221366, 221129, 221368, 221132, 221369, + 221357, 221359, 221363, 220902, 220919, 220911, 220936, + 220942, 220946, 220988, 0 +}; +const uint DOORBOT_RANGE23[] = { + 221157, 221165, 221166, 221167, 221130, 221168, 221169, + 221132, 221170, 221171, 221158, 220910, 220911, 220929, + 220944, 220948, 220909, 0 +}; +const uint DOORBOT_RANGE24[] = { 220980, 220981, 220982, 220984, 220956, 220931, 220926, + 220916, 220914, 220913, 220974, 220952, 0 }; +const uint DOORBOT_RANGE25[] = { 220873, 220874, 220875, 220876, 220877, 0 }; +const uint DOORBOT_RANGE26[] = { 221242, 221243, 221244, 221242, 221243, 221244, 221251, 0 }; +const uint DOORBOT_RANGE27[] = { 221245, 221246, 221247, 221248, 221249, 221250, 0 }; +const uint DOORBOT_RANGE28[] = { 221777, 221780, 0 }; +const uint DOORBOT_RANGE29[] = { 221966, 221967, 0 }; +const uint DOORBOT_RANGE30[] = { 220986, 222096, 222099, 222102, 0 }; +const uint DOORBOT_RANGE31[] = { 222193, 222197, 222198, 222199, 222200, 222201, 222202, + 222203, 222204, 222194, 222195, 222196, 0 }; +const uint DOORBOT_RANGE32[] = { 221927, 221931, 0 }; +const uint DOORBOT_RANGE33[] = { 221945, 221948, 0 }; +const uint DOORBOT_RANGE34[] = { 222004, 222001, 0 }; +const uint DOORBOT_RANGE35[] = { 222259, 222262, 222265, 222268, 222271, 222274, 222277, + 222280, 222283, 222254, 222257, 0 }; +const uint DOORBOT_RANGE36[] = { 221364, 221365, 221360, 221252, 220952, 220916, 220996, + 220924, 220926, 220931, 220956, 220967, 220968, 220980, + 220981, 220982, 220984, 220988, 0 }; +const uint DOORBOT_RANGE37[] = { + 221166, 221252, 220984, 220952, 220996, 220916, 220926, + 220931, 220948, 220965, 220967, 220980, 220981, 220982, + 220983, 220988, 220903, 221019, 221355, 0 }; +const uint DOORBOT_RANGE38[] = { 222248, 220081, 220082, 220083, 220084, 0 }; +const uint DOORBOT_RANGE39[] = { 221095, 222202, 222239, 221758, 221759, 221762, 221763, + 221766, 221767, 221768, 0 }; + +#define DOORBOT_RANGE_COUNT 39 +const ScriptRange DOORBOT_RANGES[39] = { + { 220074, DOORBOT_RANGE1, false, false }, + { 221381, DOORBOT_RANGE2, false, false }, + { 220000, DOORBOT_RANGE3, true, false }, + { 221380, DOORBOT_RANGE4, true, false }, + { 220736, DOORBOT_RANGE5, false, false }, + { 220759, DOORBOT_RANGE6, false, false }, + { 220771, DOORBOT_RANGE7, false, false }, + { 220792, DOORBOT_RANGE8, false, false }, + { 220017, DOORBOT_RANGE9, false, false }, + { 220037, DOORBOT_RANGE10, false, false }, + + { 220093, DOORBOT_RANGE11, false, false }, + { 220109, DOORBOT_RANGE12, false, false }, + { 220837, DOORBOT_RANGE13, false, false }, + { 220849, DOORBOT_RANGE14, false, false }, + { 220858, DOORBOT_RANGE15, false, false }, + { 221043, DOORBOT_RANGE16, false, false }, + { 221140, DOORBOT_RANGE17, false, false }, + { 220883, DOORBOT_RANGE18, false, false }, + { 221375, DOORBOT_RANGE19, true, false }, + { 221129, DOORBOT_RANGE20, true, false }, + + { 221376, DOORBOT_RANGE21, true, false }, + { 221377, DOORBOT_RANGE22, true, false }, + { 221378, DOORBOT_RANGE23, true, false }, + { 221379, DOORBOT_RANGE24, true, false }, + { 220873, DOORBOT_RANGE25, false, false }, + { 221242, DOORBOT_RANGE26, false, false }, + { 221245, DOORBOT_RANGE27, false, false }, + { 221777, DOORBOT_RANGE28, false, false }, + { 221966, DOORBOT_RANGE29, false, false }, + { 220986, DOORBOT_RANGE30, false, false }, + + { 222193, DOORBOT_RANGE31, false, false }, + { 221927, DOORBOT_RANGE32, false, false }, + { 221948, DOORBOT_RANGE33, false, true }, + { 222000, DOORBOT_RANGE34, false, false }, + { 222259, DOORBOT_RANGE35, false, false }, + { 222415, DOORBOT_RANGE36, true, false }, + { 222416, DOORBOT_RANGE37, true, false }, + { 222248, DOORBOT_RANGE38, false, false }, + { 221095, DOORBOT_RANGE39, true, false } +}; + +const uint LIFTBOT_RANGE1[] = { 210028, 210034, 210039, 210044, 210049, 210054, 0 }; +const uint LIFTBOT_RANGE2[] = { 210321, 210322, 210323, 210324, 210792, 210794, 210796, 210793, 210795, 210797, 0 }; +const uint LIFTBOT_RANGE3[] = { + 210572, 210568, 210338, 210341, 210355, 210419, 210430, 210441, 210460, 210463, + 210464, 210475, 210477, 210496, 210497, 210503, 210357, 210359, 210372, 210382, + 210388, 210393, 210394, 210400, 210415, 0 +}; +const uint LIFTBOT_RANGE4[] = { + 210568, 210342, 210555, 210551, 210534, 210557, 210334, 210474, 210504, 210505, + 210517, 210358, 210359, 210360, 210376, 210378, 210379, 210382, 210396, 210398, + 210402, 0 +}; +const uint LIFTBOT_RANGE5[] = { + 210572, 210568, 210397, 210408, 210419, 210430, 210441, 210460, 210463, 210464, + 210475, 210477, 210496, 210497, 210503, 210357, 210359, 210372, 210382, 210388, + 210393, 210394, 210400, 210415, 0 +}; +const uint LIFTBOT_RANGE6[] = { + 210555, 210551, 210534, 210557, 210334, 210474, 210504, 210505, 210517, 210358, + 210359, 210360, 210376, 210378, 210379, 210382, 210396, 210398, 210402, 0 +}; +const uint LIFTBOT_RANGE7[] = { 210344, 210447, 210529, 210530, 210351, 210356, 210378, 0 }; +const uint LIFTBOT_RANGE8[] = { 210512, 210513, 210345, 0 }; +const uint LIFTBOT_RANGE9[] = { 210847, 210848, 210153, 0 }; +const uint LIFTBOT_RANGE10[] = { 210846, 210153, 0 }; + +const uint LIFTBOT_RANGE11[] = { 210595, 210601, 210602, 210603, 210604, 210605, 210606, 210607, 210608, 210596, + 210597, 210598, 210599, 210600, 0 }; +const uint LIFTBOT_RANGE12[] = { 210489, 210570, 210610, 210610, 210610, 210610, 210610, 0 }; +const uint LIFTBOT_RANGE13[] = { 210819, 210822, 210823, 210824, 210825, 210827, 210828, 210829, 210820, 210821, + 210965, 210969, 210965, 210969, 0 }; +const uint LIFTBOT_RANGE14[] = { 210869, 210870, 210871, 210872, 210873, 0 }; +const uint LIFTBOT_RANGE15[] = { 210875, 210876, 210877, 210878, 210879, 0 }; +const uint LIFTBOT_RANGE16[] = { 210866, 210867, 0 }; +const uint LIFTBOT_RANGE17[] = { 210853, 210854, 0 }; +const uint LIFTBOT_RANGE18[] = { 210858, 210859, 0 }; +const uint LIFTBOT_RANGE19[] = { 210860, 210861, 210862, 210863, 210864, 210865, 0 }; +const uint LIFTBOT_RANGE20[] = { 210771, 210914, 0 }; + +const uint LIFTBOT_RANGE21[] = { 210764, 210765, 210766, 210767, 210768, 210769, 210770, 0 }; +const uint LIFTBOT_RANGE22[] = { 210607, 210799, 210800, 210801, 210802, 210815, 210890, 210892, 0 }; +const uint LIFTBOT_RANGE23[] = { 210355, 210359, 210376, 210388, 210416, 210568, 210551, 0 }; +const uint LIFTBOT_RANGE24[] = { 210511, 210522, 210382, 210383, 210392, 210337, 210546, 210576, 0 }; +const uint LIFTBOT_RANGE25[] = { 210775, 210777, 210778, 210779, 210780, 210781, 210782, 210783, 210784, 210776, + 210459, 210789, 210790, 210791, 0 }; +const uint LIFTBOT_RANGE26[] = { 210780, 210781, 210782, 210783, 210784, 210780, 210781, 210782, 210783, 210784, + 210789, 210790, 210791, 0 }; +const uint LIFTBOT_RANGE27[] = { 210440, 210442, 0 }; +const uint LIFTBOT_RANGE28[] = { 210906, 210907, 210908, 210909, 210910, 210911, 210912, 0 }; +const uint LIFTBOT_RANGE29[] = { 210901, 210902, 210903, 210904, 210905, 0 }; +const uint LIFTBOT_RANGE30[] = { 210970, 210971, 210974, 210975, 210976, 210977, 210978, 210979, 210980, 210981, + 210972, 210973, 0 }; + +const uint LIFTBOT_RANGE31[] = { 210830, 210831, 210832, 210833, 210834, 210835, 210836, 210837, 0 }; +const uint LIFTBOT_RANGE32[] = { 210692, 210695, 210696, 210697, 210698, 210699, 210700, 210701, 210702, 210693, 210694, 0 }; +const uint LIFTBOT_RANGE33[] = { 210915, 210916, 210917, 0 }; +const uint LIFTBOT_RANGE34[] = { 210688, 210689, 210690, 0 }; +const uint LIFTBOT_RANGE35[] = { 210946, 210947, 210948, 210949, 210950, 210951, 210952, 210953, 210954, 0 }; +const uint LIFTBOT_RANGE36[] = { 210923, 210924, 0 }; +const uint LIFTBOT_RANGE37[] = { 210925, 210926, 210927, 210928, 210929, 210930, 210931, 210932, 210933, 0 }; +const uint LIFTBOT_RANGE38[] = { 210413, 210799, 210800, 210801, 210802, 210888, 210889, 210890, 210891, 210892, 0 }; +const uint LIFTBOT_RANGE39[] = { 210682, 210684, 210028, 210034, 210683, 210039, 210685, 210044, 210049, 210686, + 210054, 0 }; + +#define LIFTBOT_RANGE_COUNT 39 +const ScriptRange LIFTBOT_RANGES[39] = { + { 210033, LIFTBOT_RANGE1, false, false }, + { 210321, LIFTBOT_RANGE2, true, false }, + { 210580, LIFTBOT_RANGE3, true, false }, + { 210581, LIFTBOT_RANGE4, true, false }, + { 210582, LIFTBOT_RANGE5, true, false }, + { 210583, LIFTBOT_RANGE6, true, false }, + { 210584, LIFTBOT_RANGE7, true, false }, + { 210585, LIFTBOT_RANGE8, true, false }, + { 210586, LIFTBOT_RANGE9, false, false }, + { 210587, LIFTBOT_RANGE10, false, false }, + + { 210588, LIFTBOT_RANGE11, true, false }, + { 210589, LIFTBOT_RANGE12, true, false }, + { 210590, LIFTBOT_RANGE13, true, false }, + { 210869, LIFTBOT_RANGE14, false, false }, + { 210875, LIFTBOT_RANGE15, false, false }, + { 210866, LIFTBOT_RANGE16, false, false }, + { 210853, LIFTBOT_RANGE17, false, false }, + { 210858, LIFTBOT_RANGE18, false, false }, + { 210860, LIFTBOT_RANGE19, false, false }, + { 210771, LIFTBOT_RANGE20, false, false }, + + { 210764, LIFTBOT_RANGE21, false, false }, + { 210958, LIFTBOT_RANGE22, true, false }, + { 210591, LIFTBOT_RANGE23, true, false }, + { 210592, LIFTBOT_RANGE24, true, false }, + { 210594, LIFTBOT_RANGE25, true, false }, + { 210593, LIFTBOT_RANGE26, true, false }, + { 210440, LIFTBOT_RANGE27, false, false }, + { 210906, LIFTBOT_RANGE28, true, false }, + { 210901, LIFTBOT_RANGE29, true, false }, + { 210970, LIFTBOT_RANGE30, false, false }, + + { 210830, LIFTBOT_RANGE31, true, false }, + { 210692, LIFTBOT_RANGE32, false, false }, + { 210915, LIFTBOT_RANGE33, false, false }, + { 210688, LIFTBOT_RANGE34, false, false }, + { 210946, LIFTBOT_RANGE35, true, false }, + { 210923, LIFTBOT_RANGE36, false, false }, + { 210925, LIFTBOT_RANGE37, true, false }, + { 210413, LIFTBOT_RANGE38, true, false }, + { 210682, LIFTBOT_RANGE39, false, false } +}; + +const uint MAITRED_RANGE1[] = { 260009, 260010, 260011, 260012, 0 }; +const uint MAITRED_RANGE2[] = { + 260043, 260013, 260044, 260014, 260017, 260015, 260016, 260040, 260042, 260019, + 260029, 260021, 260018, 260020, 260022, 260023, 260041, 260028, 260045, 260031, + 260032, 260033, 260030, 260046, 260034, 260039, 0 +}; +const uint MAITRED_RANGE3[] = { + 260013, 260014, 260029, 260040, 260041, 260042, 260043, 260044, 260045, 260046, + 260015, 260016, 260017, 260018, 260019, 260020, 260021, 260022, 260023, 260028, + 260030, 260031, 260032, 260033, 260034, 260035, 260039, 0 +}; +const uint MAITRED_RANGE4[] = { + 260013, 260014, 260029, 260040, 260041, 260042, 260043, 260044, 260045, 260046, + 260015, 260016, 260017, 260018, 260019, 260020, 260021, 260022, 260023, 260025, + 260028, 260030, 260031, 260032, 260033, 260034, 260036, 260039, 0 +}; +const uint MAITRED_RANGE5[] = { + 260013, 260014, 260029, 260040, 260041, 260042, 260043, 260044, 260045, 260046, + 260015, 260016, 260017, 260018, 260019, 260020, 260021, 260022, 260023, 260026, + 260028, 260030, 260031, 260032, 260033, 260034, 260037, 260039, 0 +}; +const uint MAITRED_RANGE6[] = { + 260013, 260014, 260029, 260040, 260041, 260042, 260043, 260044, 260045, 260046, + 260015, 260016, 260017, 260018, 260019, 260020, 260021, 260022, 260023, 260027, + 260028, 260030, 260031, 260032, 260033, 260034, 260038, 260039, 0 +}; +const uint MAITRED_RANGE7[] = { 260048, 260049, 260050, 0 }; +const uint MAITRED_RANGE8[] = { 260054, 260055, 260056, 260057, 260058, 260059, 260060, 0 }; +const uint MAITRED_RANGE9[] = { 260061, 260062, 0 }; +const uint MAITRED_RANGE10[] = { 260064, 260065, 260066, 0 }; +const uint MAITRED_RANGE11[] = { 260068, 260110, 260069, 260070, 260075, 261010, 260181, 260076, 0 }; +const uint MAITRED_RANGE12[] = { 260068, 260110, 260069, 260070, 260075, 261010, 260181, 260076, 0 }; +const uint MAITRED_RANGE13[] = { 260068, 260110, 260069, 260071, 260075, 261010, 260181, 260076, 0 }; +const uint MAITRED_RANGE14[] = { 260068, 260110, 260069, 260072, 260075, 261010, 260181, 260076, 0 }; +const uint MAITRED_RANGE15[] = { 260068, 260110, 260069, 260073, 260075, 261010, 260181, 260076, 0 }; +const uint MAITRED_RANGE16[] = { 260068, 260110, 260069, 260074, 260075, 261010, 260181, 260076, 0 }; +const uint MAITRED_RANGE17[] = { 260078, 260079, 260080, 0 }; +const uint MAITRED_RANGE18[] = { 260081, 260082, 260083, 260084, 260085, 0 }; +const uint MAITRED_RANGE19[] = { 260103, 260104, 260105, 0 }; +const uint MAITRED_RANGE20[] = { 260092, 260093, 260088, 260090, 0 }; +const uint MAITRED_RANGE21[] = { + 260132, 260133, 260134, 260135, 260136, 260137, 260138, 260139, 260140, 260141, + 260142, 260143, 260144, 260145, 260146, 260147, 260148, 260149, 260150, 260151, + 260152, 260153, 260154, 260155, 260156, 0 +}; +const uint MAITRED_RANGE22[] = { + 260158, 260159, 260160, 260161, 260162, 260163, 260164, 260165, 260166, 260167, + 260168, 260169, 260170, 260171, 260172, 260173, 260174, 260175, 260176, 260177, + 260178, 260179, 260180, 0 +}; +const uint MAITRED_RANGE23[] = { 260185, 260186, 260187, 260188, 0 }; +const uint MAITRED_RANGE24[] = { 260191, 260192, 260193, 0 }; +const uint MAITRED_RANGE25[] = { 260203, 260204, 0 }; +const uint MAITRED_RANGE26[] = { 260217, 260218, 260219, 260220, 0 }; +const uint MAITRED_RANGE27[] = { 260263, 260264, 260265, 260427, 260053, 0 }; +const uint MAITRED_RANGE28[] = { 260266, 260267, 260268, 0 }; +const uint MAITRED_RANGE29[] = { 260274, 260278, 260287, 260288, 0 }; +const uint MAITRED_RANGE30[] = { 260275, 260276, 260281, 260283, 260289, 260361, 0 }; +const uint MAITRED_RANGE31[] = { 260277, 260280, 260284, 260286, 260359, 0 }; +const uint MAITRED_RANGE32[] = { 260279, 260285, 0 }; +const uint MAITRED_RANGE33[] = { 260275, 260276, 260281, 260283, 260289, 260361, 0 }; +const uint MAITRED_RANGE34[] = { 260282, 260360, 0 }; +const uint MAITRED_RANGE35[] = { 260432, 260306, 0 }; +const uint MAITRED_RANGE36[] = { 260319, 260320, 260321, 0 }; +const uint MAITRED_RANGE37[] = { 260322, 260485, 0 }; +const uint MAITRED_RANGE38[] = { 260324, 260325, 0 }; +const uint MAITRED_RANGE39[] = { 260326, 260327, 0 }; +const uint MAITRED_RANGE40[] = { 260338, 260339, 260340, 260341, 260342, 260343, 0 }; +const uint MAITRED_RANGE41[] = { + 260054, 260055, 260056, 260057, 260058, 260059, 260345, 260346, 260347, 260348, + 260349, 260350, 260351, 260352, 260353, 260354, 260355, 260356, 260357, 260358, 0 +}; +const uint MAITRED_RANGE42[] = { 260369, 260370, 0 }; +const uint MAITRED_RANGE43[] = { 260207, 260375, 260767, 0 }; +const uint MAITRED_RANGE44[] = { 260381, 260382, 260383, 260384, 260385, 0 }; +const uint MAITRED_RANGE45[] = { 260389, 260390, 260391, 260392, 260393, 260394, 260395, 260396, 260397, 260398, 0 }; +const uint MAITRED_RANGE46[] = { 260403, 260404, 260763, 0 }; +const uint MAITRED_RANGE47[] = { 260424, 260425, 260426, 0 }; +const uint MAITRED_RANGE48[] = { 260450, 260451, 0 }; +const uint MAITRED_RANGE49[] = { 260521, 260501, 0 }; +const uint MAITRED_RANGE50[] = { 260526, 260429, 0 }; +const uint MAITRED_RANGE51[] = { 260527, 260430, 0 }; +const uint MAITRED_RANGE52[] = { 260528, 260431, 0 }; +const uint MAITRED_RANGE53[] = { 260567, 260568, 0 }; +const uint MAITRED_RANGE54[] = { 260495, 260496, 0 }; +const uint MAITRED_RANGE55[] = { 260511, 260512, 0 }; +const uint MAITRED_RANGE56[] = { 260573, 260572, 0 }; +const uint MAITRED_RANGE57[] = { 260595, 260596, 260597, 260598, 260599, 260600, 0 }; +const uint MAITRED_RANGE58[] = { 260620, 260621, 0 }; +const uint MAITRED_RANGE59[] = { 260623, 260630, 260636, 0 }; +const uint MAITRED_RANGE60[] = { 260215, 260690, 260223, 260691, 0 }; +const uint MAITRED_RANGE61[] = { 260000, 260212, 0 }; +const uint MAITRED_RANGE62[] = { 260213, 260252, 0 }; +const uint MAITRED_RANGE63[] = { + 260700, 260701, 260702, 260703, 260704, 260705, 260706, 260707, 260708, 260709, + 260710, 260711, 260712, 260713, 260714, 260715, 260716, 260717, 260718, 260719, + 260720, 260721, 260731, 260732, 260733, 260734, 260735, 260736, 260737, 260738, + 260739, 260740, 260741, 260742, 260743, 260744, 260745, 260746, 260747, 260748, + 260749, 260750, 260751, 260752, 260753, 260754, 260755, 260756, 260757, 260758, + 260759, 260760, 0 +}; +const uint MAITRED_RANGE64[] = { 260723, 260724, 260725, 260726, 260727, 260728, 260729, 260730, 0 }; +const uint MAITRED_RANGE65[] = { 260765, 260766, 0 }; +const uint MAITRED_RANGE66[] = { 260770, 260771, 0 }; +const uint MAITRED_RANGE67[] = { 260773, 260774, 260775, 260776, 260271, 0 }; +const uint MAITRED_RANGE68[] = { 260801, 260802, 0 }; +const uint MAITRED_RANGE69[] = { 260804, 260805, 260806, 260807, 260808, 0 }; +const uint MAITRED_RANGE70[] = { 260810, 260811, 0 }; +const uint MAITRED_RANGE71[] = { 260813, 260814, 260815, 0 }; +const uint MAITRED_RANGE72[] = { 260818, 260819, 0 }; +const uint MAITRED_RANGE73[] = { 260844, 260845, 260846, 260847, 260848, 0 }; +const uint MAITRED_RANGE74[] = { 260857, 260858, 260859, 0 }; +const uint MAITRED_RANGE75[] = { 260861, 260862, 0 }; +const uint MAITRED_RANGE76[] = { 260864, 260865, 260866, 260867, 260868, 260869, 260870, 260871, 260872, 0 }; +const uint MAITRED_RANGE77[] = { 260876, 260877, 260878, 260879, 0 }; +const uint MAITRED_RANGE78[] = { 260881, 260882, 260883, 260884, 0 }; +const uint MAITRED_RANGE79[] = { 260899, 260900, 260901, 260902, 260903, 260904, 260905, 260906, 260907, 260908, +260909, 260910, 260911, 260912, 0 }; +const uint MAITRED_RANGE80[] = { 260914, 260915, 0 }; +const uint MAITRED_RANGE81[] = { 260917, 260918, 260919, 0 }; +const uint MAITRED_RANGE82[] = { 260921, 260922, 260923, 260924, 260925, 260926, 260927, 260928, 260929, 260930, + 260931, 0 }; +const uint MAITRED_RANGE83[] = { 260933, 260946, 0 }; +const uint MAITRED_RANGE84[] = { 260935, 260947, 0 }; +const uint MAITRED_RANGE85[] = { 260939, 260948, 0 }; +const uint MAITRED_RANGE86[] = { 260941, 260949, 0 }; +const uint MAITRED_RANGE87[] = { 260943, 260950, 0 }; +const uint MAITRED_RANGE88[] = { 260945, 260951, 0 }; +const uint MAITRED_RANGE89[] = { 260953, 260954, 260955, 0 }; +const uint MAITRED_RANGE90[] = { 260957, 260958, 0 }; +const uint MAITRED_RANGE91[] = { 260962, 260963, 260964, 260965, 0 }; +const uint MAITRED_RANGE92[] = { 260967, 260968, 260969, 260970, 260971, 260972, 260973, 0 }; +const uint MAITRED_RANGE93[] = { 260982, 260983, 260984, 0 }; +const uint MAITRED_RANGE94[] = { 260993, 260994, 260995, 0 }; +const uint MAITRED_RANGE95[] = { 261013, 261014, 261015, 0 }; +const uint MAITRED_RANGE96[] = { 260798, 260211, 0 }; +const uint MAITRED_RANGE97[] = { 260790, 260416, 260417, 0 }; + +#define MAITRED_RANGE_COUNT 97 +const ScriptRange MAITRED_RANGES[97] = { + { 260112, MAITRED_RANGE1, true, false }, + { 260131, MAITRED_RANGE2, false, false }, + { 260113, MAITRED_RANGE3, true, false }, + { 260114, MAITRED_RANGE4, true, false }, + { 260115, MAITRED_RANGE5, true, false }, + { 260116, MAITRED_RANGE6, true, false }, + { 260117, MAITRED_RANGE7, false, false }, + { 260118, MAITRED_RANGE8, true, false }, + { 260120, MAITRED_RANGE9, false, false }, + { 260119, MAITRED_RANGE10, false, false }, + + { 260121, MAITRED_RANGE11, false, false }, + { 260122, MAITRED_RANGE12, false, false }, + { 260123, MAITRED_RANGE13, false, false }, + { 260124, MAITRED_RANGE14, false, false }, + { 260125, MAITRED_RANGE15, false, false }, + { 260126, MAITRED_RANGE16, false, false }, + { 260127, MAITRED_RANGE17, false, false }, + { 260128, MAITRED_RANGE18, true, false }, + { 260129, MAITRED_RANGE19, false, false }, + { 260130, MAITRED_RANGE20, false, false }, + + { 260674, MAITRED_RANGE21, true, false }, + { 260675, MAITRED_RANGE22, true, false }, + { 260676, MAITRED_RANGE23, false, false }, + { 260677, MAITRED_RANGE24, false, false }, + { 260678, MAITRED_RANGE25, false, false }, + { 260679, MAITRED_RANGE26, false, false }, + { 260680, MAITRED_RANGE27, true, false }, + { 260681, MAITRED_RANGE28, false, false }, + { 260682, MAITRED_RANGE29, true, false }, + { 260644, MAITRED_RANGE30, true, false }, + + { 260645, MAITRED_RANGE31, true, false }, + { 260646, MAITRED_RANGE32, true, false }, + { 260647, MAITRED_RANGE33, true, false }, + { 260648, MAITRED_RANGE34, true, false }, + { 260649, MAITRED_RANGE35, true, false }, + { 260650, MAITRED_RANGE36, false, false }, + { 260651, MAITRED_RANGE37, false, false }, + { 260652, MAITRED_RANGE38, false, false }, + { 260653, MAITRED_RANGE39, false, false }, + { 260654, MAITRED_RANGE40, true, false }, + + { 260655, MAITRED_RANGE41, true, false }, + { 260656, MAITRED_RANGE42, false, false }, + { 260657, MAITRED_RANGE43, true, false }, + { 260658, MAITRED_RANGE44, false, false }, + { 260659, MAITRED_RANGE45, false, false }, + { 260660, MAITRED_RANGE46, true, false }, + { 260661, MAITRED_RANGE47, false, false }, + { 260662, MAITRED_RANGE48, false, false }, + { 260663, MAITRED_RANGE49, false, false }, + { 260664, MAITRED_RANGE50, false, false }, + + { 260665, MAITRED_RANGE51, false, false }, + { 260666, MAITRED_RANGE52, false, false }, + { 260667, MAITRED_RANGE53, false, false }, + { 260668, MAITRED_RANGE54, false, false }, + { 260669, MAITRED_RANGE55, false, false }, + { 260670, MAITRED_RANGE56, false, false }, + { 260671, MAITRED_RANGE57, false, false }, + { 260672, MAITRED_RANGE58, false, false }, + { 260673, MAITRED_RANGE59, false, false }, + { 260683, MAITRED_RANGE60, false, false }, + + { 260684, MAITRED_RANGE61, false, false }, + { 260685, MAITRED_RANGE62, false, false }, + { 260699, MAITRED_RANGE63, true, false }, + { 260722, MAITRED_RANGE64, true, false }, + { 260764, MAITRED_RANGE65, true, false }, + { 260769, MAITRED_RANGE66, true, false }, + { 260772, MAITRED_RANGE67, true, false }, + { 260800, MAITRED_RANGE68, true, false }, + { 260803, MAITRED_RANGE69, true, false }, + { 260809, MAITRED_RANGE70, true, false }, + + { 260812, MAITRED_RANGE71, true, false }, + { 260817, MAITRED_RANGE72, true, false }, + { 260843, MAITRED_RANGE73, true, false }, + { 260856, MAITRED_RANGE74, true, false }, + { 260860, MAITRED_RANGE75, true, false }, + { 260863, MAITRED_RANGE76, true, false }, + { 260875, MAITRED_RANGE77, true, false }, + { 260880, MAITRED_RANGE78, true, false }, + { 260898, MAITRED_RANGE79, true, false }, + { 260913, MAITRED_RANGE80, true, false }, + + { 260916, MAITRED_RANGE81, true, false }, + { 260920, MAITRED_RANGE82, true, false }, + { 260932, MAITRED_RANGE83, true, false }, + { 260934, MAITRED_RANGE84, true, false }, + { 260938, MAITRED_RANGE85, true, false }, + { 260940, MAITRED_RANGE86, true, false }, + { 260942, MAITRED_RANGE87, true, false }, + { 260944, MAITRED_RANGE88, true, false }, + { 260952, MAITRED_RANGE89, true, false }, + { 260956, MAITRED_RANGE90, true, false }, + + { 260961, MAITRED_RANGE91, true, false }, + { 260966, MAITRED_RANGE92, true, false }, + { 260981, MAITRED_RANGE93, false, false }, + { 260992, MAITRED_RANGE94, true, false }, + { 261012, MAITRED_RANGE95, true, false }, + { 261016, MAITRED_RANGE96, true, false }, + { 261017, MAITRED_RANGE97, true, false } +}; + +const uint PARROT_RANGE1[] = { 280171, 280172, 280173, 280174, 280175, 280176, 280153, 280154, 280155, 0 }; +const uint PARROT_RANGE2[] = { 280004, 280005, 280006, 280007, 280008, 280009, 280010, 280011, 280012, 0 }; +const uint PARROT_RANGE3[] = { 280000, 280001, 280002, 0 }; +const uint PARROT_RANGE4[] = { 280161, 280162, 280163, 280164, 280165, 0 }; +const uint PARROT_RANGE5[] = { 280156, 280157, 0 }; +const uint PARROT_RANGE6[] = { 280158, 280159, 280160, 0 }; +const uint PARROT_RANGE7[] = { 280166, 280167, 280168, 0 }; +const uint PARROT_RANGE8[] = { 280179, 280180, 280181, 0 }; +const uint PARROT_RANGE9[] = { 280086, 280087, 280088, 280089, 280090, 280091, 0 }; +const uint PARROT_RANGE10[] = { 280153, 280154, 280155, 0 }; +const uint PARROT_RANGE11[] = { 280043, 280044, 280045, 280046, 280047, 280048, 280049, 280050, 280051, 280052, 0 }; +const uint PARROT_RANGE12[] = { 280014, 280015, 280016, 0 }; +const uint PARROT_RANGE13[] = { 280217, 280039, 280040, 280041, 280042, 0 }; +const uint PARROT_RANGE14[] = { 280119, 280120, 280121, 280122, 280028, 280029, 280030, 280031, 280116, 280117, + 280118, 0 }; +const uint PARROT_RANGE15[] = { 280028, 280029, 280030, 280031, 0 }; +const uint PARROT_RANGE16[] = { 280123, 280124, 280125, 280126, 280127, 280128, 0 }; +const uint PARROT_RANGE17[] = { 280129, 280130, 280131, 280132, 280133, 280134, 280135, 280136, 280137, 280138, 0 }; +const uint PARROT_RANGE18[] = { 280035, 280036, 280037, 280038, 0 }; +const uint PARROT_RANGE19[] = { 280094, 280095, 280096, 280097, 280098, 280099, 280100, 280101, 280102, 280103, + 280104, 0 }; +const uint PARROT_RANGE20[] = { 280078, 280079, 280080, 280081, 280082, 280083, 280084, 0 }; +const uint PARROT_RANGE21[] = { 280067, 280068, 0 }; +const uint PARROT_RANGE22[] = { 280139, 280140, 280141, 0 }; +const uint PARROT_RANGE23[] = { 280017, 280018, 280019, 280020, 280021, 280022, 280023, 280024, 280025, 280026, + 280027, 0 }; +const uint PARROT_RANGE24[] = { 280065, 280143, 280142, 280190, 280144, 280066, 280145, 280146, 280147, 0 }; +const uint PARROT_RANGE25[] = { 280148, 280062, 280063, 0 }; +const uint PARROT_RANGE26[] = { 280071, 280072, 280073, 280074, 280075, 280076, 280077, 0 }; +const uint PARROT_RANGE27[] = { 280218, 280219, 0 }; +const uint PARROT_RANGE28[] = { 280057, 280058, 280059, 280060, 280061, 0 }; +const uint PARROT_RANGE29[] = { 280196, 280197, 280198, 280199, 280200, 0 }; +const uint PARROT_RANGE30[] = { 280202, 280203, 280204, 280205, 0 }; +const uint PARROT_RANGE31[] = { 280193, 280194, 280195, 0 }; +const uint PARROT_RANGE32[] = { 280149, 280069, 280070, 0 }; +const uint PARROT_RANGE33[] = { 280222, 280223, 280224, 280225, 280226, 280227, 280228, 280229, 280230, 280231, + 280232, 280233, 280234, 0 }; +const uint PARROT_RANGE34[] = { 280268, 280269, 280270, 280271, 280272, 280273, 280274, 0 }; + +#define PARROT_RANGE_COUNT 34 +const ScriptRange PARROT_RANGES[34] = { + { 280235, PARROT_RANGE1, true, false }, + { 280236, PARROT_RANGE2, false, false }, + { 280237, PARROT_RANGE3, false, false }, + { 280238, PARROT_RANGE4, false, false }, + { 280239, PARROT_RANGE5, false, false }, + { 280240, PARROT_RANGE6, false, false }, + { 280241, PARROT_RANGE7, false, false }, + { 280242, PARROT_RANGE8, false, false }, + { 280243, PARROT_RANGE9, false, false }, + { 280244, PARROT_RANGE10, false, false }, + + { 280245, PARROT_RANGE11, false, false }, + { 280246, PARROT_RANGE12, false, false }, + { 280247, PARROT_RANGE13, false, false }, + { 280248, PARROT_RANGE14, false, false }, + { 280249, PARROT_RANGE15, false, false }, + { 280250, PARROT_RANGE16, false, false }, + { 280251, PARROT_RANGE17, false, false }, + { 280252, PARROT_RANGE18, false, false }, + { 280253, PARROT_RANGE19, false, false }, + { 280254, PARROT_RANGE20, false, false }, + + { 280255, PARROT_RANGE21, false, false }, + { 280256, PARROT_RANGE22, false, false }, + { 280257, PARROT_RANGE23, true, false }, + { 280258, PARROT_RANGE24, false, true }, + { 280259, PARROT_RANGE25, false, false }, + { 280260, PARROT_RANGE26, false, false }, + { 280261, PARROT_RANGE27, false, false }, + { 280262, PARROT_RANGE28, false, false }, + { 280263, PARROT_RANGE29, false, false }, + { 280264, PARROT_RANGE30, false, false }, + + { 280265, PARROT_RANGE31, false, false }, + { 280266, PARROT_RANGE32, false, false }, + { 280222, PARROT_RANGE33, true, false }, + { 280267, PARROT_RANGE34, true, false } +}; + +const uint SUCCUBUS_RANGE1[] = { 230001, 230149, 230078, 230002, 230033, 230067, 230003, 230079, 230034, 230055, + 230080, 230081, 230064, 230035, 0 }; +const uint SUCCUBUS_RANGE2[] = { 230005, 230085, 230006, 230091, 0 }; +const uint SUCCUBUS_RANGE3[] = { 230009, 230010, 230011, 0 }; +const uint SUCCUBUS_RANGE4[] = { 230030, 230031, 230032, 230033, 230034, 230035, 230036, 230037, 230038, 230142, + 230097, 0 }; +const uint SUCCUBUS_RANGE5[] = { 230100, 230101, 230102, 230104, 230105, 230113, 0 }; +const uint SUCCUBUS_RANGE6[] = { 230106, 230107, 230108, 230109, 230110, 0 }; +const uint SUCCUBUS_RANGE7[] = { 230119, 230120, 0 }; +const uint SUCCUBUS_RANGE8[] = { 230150, 230152, 230153, 230151, 0 }; +const uint SUCCUBUS_RANGE9[] = { 230154, 230155, 0 }; +const uint SUCCUBUS_RANGE10[] = { 230163, 230164, 230167, 230165, 230166, 230168, 0 }; +const uint SUCCUBUS_RANGE11[] = { 230123, 230124, 230126, 230127, 230128, 230129, 230130, 230131, 0 }; +const uint SUCCUBUS_RANGE12[] = { 230117, 230115, 0 }; +const uint SUCCUBUS_RANGE13[] = { 230179, 230180, 230057, 230181, 230068, 230182, 230118, 230048, 230058, 0 }; +const uint SUCCUBUS_RANGE14[] = { 230191, 230192, 230193, 230194, 0 }; +const uint SUCCUBUS_RANGE15[] = { 230239, 230240, 230241, 0 }; +const uint SUCCUBUS_RANGE16[] = { 230200, 230201, 230202, 230203, 230204, 230205, 230206, 0 }; +const uint SUCCUBUS_RANGE17[] = { 230122, 230073, 230074, 230075, 230076, 230077, 0 }; +const uint SUCCUBUS_RANGE18[] = { 230103, 230114, 230125, 230136, 230147, 230158, 230169, 230079, 230080, 230081, + 230082, 0 }; +const uint SUCCUBUS_RANGE19[] = { 230207, 230072, 0 }; + +#define SUCCUBUS_RANGE_COUNT 19 +const ScriptRange SUCCUBUS_RANGES[19] = { + { 230001, SUCCUBUS_RANGE1, false, false }, + { 230005, SUCCUBUS_RANGE2, false, false }, + { 230009, SUCCUBUS_RANGE3, false, false }, + { 230030, SUCCUBUS_RANGE4, false, false }, + { 230244, SUCCUBUS_RANGE5, false, false }, + { 230106, SUCCUBUS_RANGE6, false, false }, + { 230119, SUCCUBUS_RANGE7, false, false }, + { 230150, SUCCUBUS_RANGE8, false, false }, + { 230154, SUCCUBUS_RANGE9, false, false }, + { 230163, SUCCUBUS_RANGE10, false, false }, + + { 230123, SUCCUBUS_RANGE11, false, false }, + { 230117, SUCCUBUS_RANGE12, false, false }, + { 230179, SUCCUBUS_RANGE13, false, false }, + { 230191, SUCCUBUS_RANGE14, false, false }, + { 230239, SUCCUBUS_RANGE15, false, false }, + { 230200, SUCCUBUS_RANGE16, false, false }, + { 230122, SUCCUBUS_RANGE17, false, false }, + { 230103, SUCCUBUS_RANGE18, false, false }, + { 230207, SUCCUBUS_RANGE19, false, false } +}; + +void writeScriptRange(const char *name, const ScriptRange *ranges, int count) { + outputFile.seek(dataOffset); + + for (int idx = 0; idx < count; ++idx) { + outputFile.writeLong(ranges[idx]._id); + outputFile.writeByte(ranges[idx]._isRandom); + outputFile.writeByte(ranges[idx]._isSequential); + + const uint *v = ranges[idx]._array; + do { + outputFile.writeLong(*v); + } while (*v++ != 0); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader(name, dataOffset, size); + dataOffset += size; +} + +void writeAllScriptRanges() { + writeScriptRange("Ranges/Barbot", BARBOT_RANGES, BARBOT_RANGE_COUNT); + writeScriptRange("Ranges/Bellbot", BELLBOT_RANGES, BELLBOT_RANGE_COUNT); + writeScriptRange("Ranges/Deskbot", DESKBOT_RANGES, DESKBOT_RANGE_COUNT); + writeScriptRange("Ranges/Doorbot", DOORBOT_RANGES, DOORBOT_RANGE_COUNT); + writeScriptRange("Ranges/Liftbot", LIFTBOT_RANGES, LIFTBOT_RANGE_COUNT); + writeScriptRange("Ranges/MaitreD", MAITRED_RANGES, MAITRED_RANGE_COUNT); + writeScriptRange("Ranges/Parrot", PARROT_RANGES, PARROT_RANGE_COUNT); + writeScriptRange("Ranges/SuccUBus", SUCCUBUS_RANGES, SUCCUBUS_RANGE_COUNT); +}
\ No newline at end of file diff --git a/devtools/create_titanic/script_ranges.h b/devtools/create_titanic/script_ranges.h new file mode 100644 index 0000000000..3013a32139 --- /dev/null +++ b/devtools/create_titanic/script_ranges.h @@ -0,0 +1,39 @@ +/* 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 COMMON_SCRIPT_RANGES_H +#define COMMON_SCRIPT_RANGES_H + +#include "common/scummsys.h" + +struct ScriptRange { + uint _id; + const uint *_array; + bool _isRandom; + bool _isSequential; +}; + +extern void writeAllScriptRanges(); +extern void writeEntryHeader(const char *name, uint offset, uint size); +extern uint dataOffset; + +#endif diff --git a/devtools/create_titanic/script_responses.cpp b/devtools/create_titanic/script_responses.cpp new file mode 100644 index 0000000000..30d0c7f1bd --- /dev/null +++ b/devtools/create_titanic/script_responses.cpp @@ -0,0 +1,629 @@ +/* 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. + * + */ + + // Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +// HACK to allow building with the SDL backend on MinGW +// see bug #1800764 "TOOLS: MinGW tools building broken" +#ifdef main +#undef main +#endif // main + +#include "file.h" +#include "script_responses.h" + +static const int DESKBOT_RESPONSES[128][5] = { + { MKTAG('P', 'K', 'U', 'P'), 240573, 0, 0, 0 }, + { MKTAG('S', 'E', 'X', '1'), 240573, 0, 0, 0 }, + { MKTAG('D', 'E', 'S', '1'), 240354, 0, 0, 0 }, + { MKTAG('D', 'E', 'S', '2'), 240547, 0, 0, 0 }, + { MKTAG('S', 'W', 'E', 'R'), 240578, 0, 0, 0 }, + { MKTAG('B', 'Y', 'Z', 'A'), 241173, 0, 0, 0 }, + { MKTAG('S', 'A', 'S', 'S'), 240986, 0, 0, 0 }, + { MKTAG('S', 'U', 'M', 'S'), 240453, 0, 0, 0 }, + { MKTAG('F', 'O', 'O', 'D'), 240849, 0, 0, 0 }, + { MKTAG('J', 'F', 'O', 'D'), 240849, 0, 0, 0 }, + { MKTAG('C', 'H', 'S', 'E'), 240849, 0, 0, 0 }, + { MKTAG('A', 'C', 'T', 'R'), 240654, 0, 0, 0 }, + { MKTAG('A', 'C', 'T', 'S'), 240655, 0, 0, 0 }, + { MKTAG('M', 'U', 'S', 'I'), 240681, 241621, 0, 0 }, + { MKTAG('S', 'O', 'N', 'G'), 240681, 241621, 0, 0 }, + { MKTAG('S', 'O', 'A', 'P'), 240681, 0, 0, 0 }, + { MKTAG('T', 'V', 'S', 'H'), 240681, 0, 0, 0 }, + { MKTAG('A', 'R', 'T', 'I'), 240657, 0, 0, 0 }, + { MKTAG('A', 'U', 'T', 'H'), 240657, 0, 0, 0 }, + { MKTAG('C', 'O', 'M', 'D'), 240657, 240785, 0, 0 }, + { MKTAG('C', 'O', 'O', 'K'), 240657, 0, 0, 0 }, + { MKTAG('C', 'O', 'P', 'S'), 240657, 0, 0, 0 }, + { MKTAG('H', 'E', 'R', 'O'), 240657, 0, 0, 0 }, + { MKTAG('H', 'O', 'S', 'T'), 240657, 0, 0, 0 }, + { MKTAG('P', 'T', 'I', 'C'), 240657, 0, 0, 0 }, + { MKTAG('S', 'C', 'I', 'T'), 240657, 0, 0, 0 }, + { MKTAG('E', 'A', 'R', 'T'), 240728, 0, 0, 0 }, + { MKTAG('P', 'L', 'A', 'N'), 240728, 0, 0, 0 }, + { MKTAG('F', 'I', 'L', 'M'), 240939, 0, 0, 0 }, + { MKTAG('F', 'I', 'S', 'H'), 240437, 0, 0, 0 }, + { MKTAG('H', 'H', 'G', 'Q'), 241065, 240453, 0, 0 }, + { MKTAG('L', 'I', 'Q', 'D'), 241167, 0, 0, 0 }, + { MKTAG('P', 'H', 'I', 'L'), 240607, 0, 0, 0 }, + { MKTAG('S', 'I', 'C', 'K'), 241170, 0, 0, 0 }, + { MKTAG('T', 'W', 'A', 'T'), 240975, 0, 0, 0 }, + { MKTAG('H', 'A', 'H', 'A'), 240785, 0, 0, 0 }, + { MKTAG('S', 'C', 'I', 'T'), 240968, 241617, 0, 0 }, + { MKTAG('S', 'C', 'I', 'E'), 240967, 241616, 0, 0 }, + { MKTAG('S', 'L', 'O', 'W'), 241614, 0, 0, 0 }, + { MKTAG('T', 'H', 'R', 'T'), 240760, 241615, 0, 0 }, + { MKTAG('T', 'D', 'V', 'P'), 241161, 241618, 0, 0 }, + { MKTAG('T', 'I', 'T', 'A'), 241619, 0, 0, 0 }, + { MKTAG('C', 'S', 'P', 'Y'), 241620, 0, 0, 0 }, + { MKTAG('M', 'I', 'N', 'S'), 241621, 0, 0, 0 }, + { MKTAG('M', 'C', 'P', 'Y'), 241622, 0, 0, 0 }, + { MKTAG('D', 'N', 'C', 'E'), 241623, 0, 0, 0 }, + { MKTAG('N', 'A', 'U', 'T'), 241624, 0, 0, 0 }, + { MKTAG('A', 'D', 'V', 'T'), 240939, 241622, 0, 0 }, + { MKTAG('A', 'N', 'S', 'W'), 240453, 0, 0, 0 }, + { MKTAG('A', 'R', 'T', 'Y'), 240658, 0, 0, 0 }, + { MKTAG('B', 'A', 'R', '1'), 240491, 0, 0, 0 }, + { MKTAG('B', 'A', 'R', '3'), 240610, 0, 0, 0 }, + { MKTAG('B', 'A', 'R', 'K'), 240768, 0, 0, 0 }, + { MKTAG('B', 'A', 'R', 'U'), 240768, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '1'), 240940, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '2'), 240591, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '3'), 240775, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '4'), 240558, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '5'), 240336, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '6'), 240759, 240760, 0, 0 }, + { MKTAG('B', 'E', 'L', '7'), 240726, 0, 0, 0 }, + { MKTAG('B', 'L', 'F', '1'), 241652, 0, 0, 0 }, + { MKTAG('B', 'L', 'F', '2'), 240939, 0, 0, 0 }, + { MKTAG('B', 'L', 'P', '1'), 240654, 0, 0, 0 }, + { MKTAG('B', 'L', 'P', '2'), 240654, 0, 0, 0 }, + { MKTAG('B', 'L', 'P', '3'), 240654, 0, 0, 0 }, + { MKTAG('B', 'L', 'P', '4'), 240655, 0, 0, 0 }, + { MKTAG('B', 'L', 'R', '1'), 240654, 0, 0, 0 }, + { MKTAG('B', 'L', 'R', '2'), 240655, 0, 0, 0 }, + { MKTAG('B', 'L', 'T', '1'), 240718, 0, 0, 0 }, + { MKTAG('B', 'L', 'T', '2'), 240681, 0, 0, 0 }, + { MKTAG('B', 'L', 'T', '3'), 240655, 0, 0, 0 }, + { MKTAG('B', 'L', 'T', '4'), 240664, 0, 0, 0 }, + { MKTAG('B', 'L', 'T', '5'), 240681, 0, 0, 0 }, + { MKTAG('B', 'O', 'D', 'Y'), 240596, 0, 0, 0 }, + { MKTAG('B', 'O', 'Y', 'S'), 240654, 0, 0, 0 }, + { MKTAG('B', 'R', 'N', 'D'), 240939, 241622, 0, 0 }, + { MKTAG('C', 'L', 'U', 'B'), 241675, 240681, 241623, 0 }, + { MKTAG('C', 'M', 'N', 'T'), 240849, 0, 0, 0 }, + { MKTAG('C', 'R', 'I', 'M'), 241096, 240725, 240729, 0 }, + { MKTAG('D', 'C', 'T', 'R'), 240681, 0, 0, 0 }, + { MKTAG('D', 'O', 'R', '2'), 241405, 241404, 241403, 241402 }, + { MKTAG('D', 'R', 'U', 'G'), 240922, 240931, 0, 0 }, + { MKTAG('F', 'A', 'M', 'E'), 240726, 0, 0, 0 }, + { MKTAG('F', 'A', 'S', 'H'), 241172, 0, 0, 0 }, + { MKTAG('F', 'A', 'U', 'N'), 240939, 0, 0, 0 }, + { MKTAG('F', 'L', 'O', 'R'), 240825, 0, 0, 0 }, + { MKTAG('F', 'U', 'L', 'N'), 240864, 241072, 0, 0 }, + { MKTAG('G', 'I', 'R', 'L'), 240655, 0, 0, 0 }, + { MKTAG('H', 'B', 'B', 'Y'), 241144, 0, 0, 0 }, + { MKTAG('H', 'H', 'L', 'D'), 241144, 0, 0, 0 }, + { MKTAG('H', 'O', 'M', 'E'), 240844, 240626, 0, 0 }, + { MKTAG('I', 'S', 'H', 'E'), 240731, 0, 0, 0 }, + { MKTAG('J', 'N', 'A', 'M'), 240785, 0, 0, 0 }, + { MKTAG('J', 'O', 'K', 'E'), 240785, 0, 0, 0 }, + { MKTAG('K', 'N', 'O', 'B'), 240657, 0, 0, 0 }, + { MKTAG('K', 'P', 'L', 'C'), 240844, 240626, 0, 0 }, + { MKTAG('L', 'I', 'F', '3'), 240722, 0, 0, 0 }, + { MKTAG('L', 'I', 'T', 'E'), 240785, 0, 0, 0 }, + { MKTAG('L', 'I', 'T', 'R'), 241404, 241405, 241403, 241406 }, + { MKTAG('M', 'A', 'D', '1'), 241124, 240971, 241615, 0 }, + { MKTAG('M', 'A', 'D', '4'), 241341, 0, 0, 0 }, + { MKTAG('M', 'A', 'D', '6'), 240860, 241114, 0, 0 }, + { MKTAG('M', 'A', 'G', 'S'), 241404, 241405, 241403, 241407 }, + { MKTAG('M', 'L', 'T', 'Y'), 240718, 240719, 0, 0 }, + { MKTAG('N', 'I', 'K', 'E'), 241622, 0, 0, 0 }, + { MKTAG('N', 'I', 'K', 'N'), 240785, 0, 0, 0 }, + { MKTAG('N', 'P', 'L', 'C'), 240844, 240626, 0, 0 }, + { MKTAG('O', 'R', 'D', '1'), 240695, 0, 0, 0 }, + { MKTAG('O', 'R', 'D', '2'), 240744, 240650, 0, 0 }, + { MKTAG('O', 'R', 'D', '3'), 240647, 0, 0, 0 }, + { MKTAG('O', 'R', 'D', '4'), 240647, 0, 0, 0 }, + { MKTAG('O', 'R', 'D', '5'), 241191, 0, 0, 0 }, + { MKTAG('P', 'G', 'R', 'P'), 240681, 0, 0, 0 }, + { MKTAG('P', 'L', 'A', 'C'), 240728, 0, 0, 0 }, + { MKTAG('R', 'C', 'K', 'T'), 241070, 241161, 0, 0 }, + { MKTAG('S', 'F', 'S', 'F'), 241172, 0, 0, 0 }, + { MKTAG('S', 'P', 'R', 'T'), 241172, 0, 0, 0 }, + { MKTAG('S', 'U', 'C', '1'), 240467, 0, 0, 0 }, + { MKTAG('T', 'E', 'A', 'M'), 241172, 0, 0, 0 }, + { MKTAG('T', 'L', 'A', ' '), 240727, 240658, 0, 0 }, + { MKTAG('T', 'O', 'Y', 'S'), 240607, 240606, 0, 0 }, + { MKTAG('T', 'R', 'A', '2'), 240611, 0, 0, 0 }, + { MKTAG('T', 'R', 'A', '3'), 240611, 0, 0, 0 }, + { MKTAG('W', 'E', 'A', 'P'), 240939, 0, 0, 0 }, + { MKTAG('W', 'E', 'A', 'T'), 241093, 241094, 241095, 0 }, + { MKTAG('W', 'T', 'H', 'R'), 241093, 241094, 241095, 0 }, + { MKTAG('W', 'W', 'E', 'B'), 241172, 0, 0, 0 } +}; + +static const int BELLBOT_RESPONSES[130][5] = { + { MKTAG('A', 'C', 'T', 'R'), 200505, 0, 0, 0 }, + { MKTAG('A', 'C', 'T', 'S'), 200505, 0, 0, 0 }, + { MKTAG('F', 'A', 'M', 'E'), 200532, 200585, 0, 0 }, + { MKTAG('A', 'D', 'V', 'T'), 200506, 0, 0, 0 }, + { MKTAG('L', 'I', 'Q', 'D'), 200507, 200527, 0, 0 }, + { MKTAG('F', 'A', 'U', 'N'), 200511, 0, 0, 0 }, + { MKTAG('H', 'B', 'B', 'Y'), 200514, 0, 0, 0 }, + { MKTAG('N', 'I', 'K', 'E'), 200514, 0, 0, 0 }, + { MKTAG('B', 'R', 'N', 'D'), 200514, 0, 0, 0 }, + { MKTAG('P', 'G', 'R', 'P'), 200514, 0, 0, 0 }, + { MKTAG('R', 'C', 'K', 'T'), 200514, 0, 0, 0 }, + { MKTAG('D', 'R', 'U', 'G'), 200528, 0, 0, 0 }, + { MKTAG('F', 'A', 'S', 'H'), 200533, 0, 0, 0 }, + { MKTAG('T', 'O', 'Y', 'S'), 200533, 0, 0, 0 }, + { MKTAG('F', 'O', 'O', 'D'), 202270, 0, 0, 0 }, + { MKTAG('J', 'F', 'O', 'D'), 202270, 0, 0, 0 }, + { MKTAG('A', 'R', 'T', 'I'), 200538, 0, 0, 0 }, + { MKTAG('A', 'R', 'T', 'Y'), 200538, 0, 0, 0 }, + { MKTAG('L', 'I', 'T', 'R'), 200538, 0, 0, 0 }, + { MKTAG('C', 'R', 'I', 'M'), 200538, 0, 0, 0 }, + { MKTAG('C', 'S', 'P', 'Y'), 200538, 0, 0, 0 }, + { MKTAG('W', 'E', 'A', 'T'), 200538, 0, 0, 0 }, + { MKTAG('M', 'U', 'S', 'I'), 200539, 0, 0, 0 }, + { MKTAG('S', 'O', 'N', 'G'), 200539, 0, 0, 0 }, + { MKTAG('F', 'I', 'L', 'M'), 200534, 0, 0, 0 }, + { MKTAG('B', 'L', 'F', '1'), 200535, 0, 0, 0 }, + { MKTAG('B', 'L', 'F', '2'), 200536, 0, 0, 0 }, + { MKTAG('M', 'A', 'G', 'S'), 200542, 0, 0, 0 }, + { MKTAG('P', 'H', 'I', 'L'), 200557, 0, 0, 0 }, + { MKTAG('P', 'L', 'A', 'N'), 200562, 0, 0, 0 }, + { MKTAG('E', 'A', 'R', 'T'), 200562, 202252, 0, 0 }, + { MKTAG('P', 'L', 'A', 'C'), 200562, 202252, 0, 0 }, + { MKTAG('F', 'L', 'O', 'R'), 200570, 0, 0, 0 }, + { MKTAG('P', 'T', 'I', 'C'), 200571, 0, 0, 0 }, + { MKTAG('B', 'L', 'P', '1'), 200577, 0, 0, 0 }, + { MKTAG('B', 'L', 'P', '2'), 200575, 0, 0, 0 }, + { MKTAG('B', 'L', 'P', '3'), 200576, 0, 0, 0 }, + { MKTAG('B', 'L', 'P', '4'), 200578, 0, 0, 0 }, + { MKTAG('K', 'N', 'O', 'B'), 200579, 0, 0, 0 }, + { MKTAG('B', 'L', 'R', '1'), 200580, 0, 0, 0 }, + { MKTAG('B', 'L', 'R', '2'), 200581, 0, 0, 0 }, + { MKTAG('S', 'E', 'X', '1'), 200582, 0, 0, 0 }, + { MKTAG('S', 'P', 'R', 'T'), 200584, 0, 0, 0 }, + { MKTAG('T', 'E', 'A', 'M'), 200584, 0, 0, 0 }, + { MKTAG('H', 'E', 'R', 'O'), 200585, 0, 0, 0 }, + { MKTAG('T', 'W', 'A', 'T'), 200588, 0, 0, 0 }, + { MKTAG('S', 'W', 'E', 'R'), 200590, 200336, 0, 0 }, + { MKTAG('T', 'R', 'A', '2'), 200594, 0, 0, 0 }, + { MKTAG('T', 'R', 'A', '3'), 200594, 0, 0, 0 }, + { MKTAG('T', 'V', 'S', 'H'), 200595, 0, 0, 0 }, + { MKTAG('S', 'O', 'A', 'P'), 200595, 0, 0, 0 }, + { MKTAG('C', 'O', 'M', 'D'), 200595, 0, 0, 0 }, + { MKTAG('C', 'O', 'O', 'K'), 200595, 0, 0, 0 }, + { MKTAG('C', 'O', 'P', 'S'), 200595, 0, 0, 0 }, + { MKTAG('D', 'C', 'T', 'R'), 200595, 0, 0, 0 }, + { MKTAG('S', 'F', 'S', 'F'), 200595, 0, 0, 0 }, + { MKTAG('H', 'O', 'S', 'T'), 200595, 0, 0, 0 }, + { MKTAG('B', 'L', 'T', '1'), 200596, 0, 0, 0 }, + { MKTAG('B', 'L', 'T', '2'), 200597, 0, 0, 0 }, + { MKTAG('B', 'L', 'T', '3'), 200598, 0, 0, 0 }, + { MKTAG('B', 'L', 'T', '4'), 200599, 0, 0, 0 }, + { MKTAG('B', 'L', 'T', '5'), 200600, 0, 0, 0 }, + { MKTAG('W', 'E', 'A', 'P'), 200601, 0, 0, 0 }, + { MKTAG('A', 'U', 'T', 'H'), 200605, 0, 0, 0 }, + { MKTAG('H', 'H', 'L', 'D'), 200536, 0, 0, 0 }, + { MKTAG('W', 'W', 'E', 'B'), 200608, 0, 0, 0 }, + { MKTAG('M', 'L', 'T', 'Y'), 200608, 0, 0, 0 }, + { MKTAG('P', 'K', 'U', 'P'), 200067, 0, 0, 0 }, + { MKTAG('S', 'U', 'C', '1'), 200067, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '1'), 200684, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '2'), 200887, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '3'), 200610, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '4'), 200015, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '5'), 200043, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '6'), 200333, 0, 0, 0 }, + { MKTAG('B', 'E', 'L', '7'), 200884, 0, 0, 0 }, + { MKTAG('H', 'H', 'G', 'Q'), 200516, 0, 0, 0 }, + { MKTAG('C', 'H', 'A', 'N'), 200961, 0, 0, 0 }, + { MKTAG('B', 'Y', 'Z', 'A'), 201271, 0, 0, 0 }, + { MKTAG('F', 'I', 'S', 'H'), 201242, 0, 0, 0 }, + { MKTAG('S', 'A', 'S', 'S'), 201256, 0, 0, 0 }, + { MKTAG('S', 'I', 'C', 'K'), 201704, 0, 0, 0 }, + { MKTAG('N', 'H', 'R', 'O'), 201704, 0, 0, 0 }, + { MKTAG('S', 'C', 'I', 'E'), 201675, 0, 0, 0 }, + { MKTAG('S', 'C', 'I', 'T'), 201676, 0, 0, 0 }, + { MKTAG('T', 'D', 'V', 'P'), 200490, 0, 0, 0 }, + { MKTAG('H', 'A', 'H', 'A'), 200950, 0, 0, 0 }, + { MKTAG('S', 'U', 'C', '1'), 200582, 0, 0, 0 }, + { MKTAG('T', 'L', 'A', ' '), 201243, 0, 0, 0 }, + { MKTAG('J', 'O', 'K', 'E'), 201244, 0, 0, 0 }, + { MKTAG('C', 'H', 'S', 'E'), 202270, 0, 0, 0 }, + { MKTAG('C', 'L', 'U', 'B'), 201654, 0, 0, 0 }, + { MKTAG('S', 'L', 'O', 'W'), 201877, 0, 0, 0 }, + { MKTAG('T', 'H', 'R', 'T'), 201238, 201269, 201982, 200336 }, + { MKTAG('A', 'N', 'S', 'W'), 200139, 0, 0, 0 }, + { MKTAG('B', 'A', 'R', '1'), 202051, 200473, 200229, 0 }, + { MKTAG('B', 'A', 'R', 'K'), 200510, 201326, 0, 0 }, + { MKTAG('B', 'A', 'R', 'U'), 200510, 201326, 0, 0 }, + { MKTAG('B', 'O', 'D', 'Y'), 201704, 0, 0, 0 }, + { MKTAG('C', 'M', 'N', 'T'), 202270, 0, 0, 0 }, + { MKTAG('D', 'E', 'S', '2'), 201529, 0, 0, 0 }, + { MKTAG('D', 'N', 'C', 'E'), 200952, 200953, 200960, 0 }, + { MKTAG('D', 'O', 'R', '2'), 200372, 0, 0, 0 }, + { MKTAG('F', 'U', 'L', 'N'), 202035, 202044, 0, 0 }, + { MKTAG('H', 'O', 'M', 'E'), 202252, 0, 0, 0 }, + { MKTAG('I', 'S', 'H', 'E'), 201609, 0, 0, 0 }, + { MKTAG('J', 'N', 'A', 'M'), 202035, 0, 0, 0 }, + { MKTAG('L', 'I', 'F', '1'), 201704, 0, 0, 0 }, + { MKTAG('L', 'I', 'F', '2'), 201704, 0, 0, 0 }, + { MKTAG('L', 'I', 'F', '3'), 201704, 0, 0, 0 }, + { MKTAG('M', 'A', 'D', '1'), 201238, 0, 0, 0 }, + { MKTAG('M', 'A', 'D', '4'), 200292, 0, 0, 0 }, + { MKTAG('M', 'A', 'D', '5'), 200140, 0, 0, 0 }, + { MKTAG('M', 'A', 'D', '6'), 200968, 0, 0, 0 }, + { MKTAG('M', 'C', 'P', 'Y'), 200514, 0, 0, 0 }, + { MKTAG('M', 'I', 'N', 'S'), 200541, 0, 0, 0 }, + { MKTAG('N', 'A', 'U', 'T'), 200529, 0, 0, 0 }, + { MKTAG('N', 'O', 'N', 'O'), 200127, 0, 0, 0 }, + { MKTAG('N', 'P', 'L', 'C'), 200234, 201625, 0, 0 }, + { MKTAG('O', 'R', 'D', '1'), 200473, 0, 0, 0 }, + { MKTAG('O', 'R', 'D', '2'), 200473, 0, 0, 0 }, + { MKTAG('O', 'R', 'D', '3'), 200473, 0, 0, 0 }, + { MKTAG('O', 'R', 'D', '4'), 200473, 0, 0, 0 }, + { MKTAG('O', 'R', 'D', '5'), 200473, 0, 0, 0 }, + { MKTAG('S', 'U', 'C', '2'), 200024, 0, 0, 0 }, + { MKTAG('S', 'U', 'M', 'S'), 200139, 0, 0, 0 }, + { MKTAG('T', 'I', 'T', 'A'), 200606, 0, 0, 0 }, + { MKTAG('W', 'T', 'H', 'R'), 201094, 201097, 201092, 0 }, + { MKTAG('Y', 'E', 'S', 'S'), 201525, 201529, 0, 0 }, +}; + +const int BARBOT_RESPONSES[93][2] = { + { MKTAG('S', 'L', 'O', 'W'), 0x3D09E }, + { MKTAG('T', 'H', 'R', 'T'), 0x3D0B1 }, + { MKTAG('A', 'C', 'T', 'R'), 0x3D77F }, + { MKTAG('A', 'C', 'T', 'S'), 0x3D780 }, + { MKTAG('A', 'D', 'V', 'T'), 0x3D781 }, + { MKTAG('A', 'R', 'T', 'I'), 0x3D782 }, + { MKTAG('A', 'R', 'T', 'Y'), 0x3D783 }, + { MKTAG('A', 'U', 'T', 'H'), 0x3D784 }, + { MKTAG('B', 'A', 'R', 'K'), 0x3D786 }, + { MKTAG('B', 'A', 'R', 'U'), 0x3D786 }, + { MKTAG('B', 'O', 'Y', 'S'), 0x3D239 }, + { MKTAG('G', 'I', 'R', 'L'), 0x3D23A }, + { MKTAG('B', 'R', 'N', 'D'), 0x3D787 }, + { MKTAG('C', 'H', 'S', 'E'), 0x3D788 }, + { MKTAG('C', 'O', 'M', 'D'), 0x3D789 }, + { MKTAG('C', 'O', 'O', 'K'), 0x3D78A }, + { MKTAG('C', 'O', 'P', 'S'), 0x3D78B }, + { MKTAG('C', 'R', 'I', 'M'), 0x3D78C }, + { MKTAG('C', 'S', 'P', 'Y'), 0x3D78D }, + { MKTAG('D', 'C', 'T', 'R'), 0x3D78E }, + { MKTAG('D', 'N', 'C', 'E'), 0x3D78F }, + { MKTAG('D', 'R', 'U', 'G'), 0x3D790 }, + { MKTAG('E', 'A', 'R', 'T'), 0x3D791 }, + { MKTAG('E', 'M', 'O', 'T'), 0x3D792 }, + { MKTAG('F', 'A', 'M', 'E'), 0x3D793 }, + { MKTAG('A', 'S', 'H', '1'), 0x3D794 }, + { MKTAG('A', 'S', 'H', '2'), 0x3D795 }, + { MKTAG('F', 'A', 'U', 'N'), 0x3D796 }, + { MKTAG('F', 'I', 'L', 'M'), 0x3D797 }, + { MKTAG('F', 'I', 'S', 'H'), 0x3D798 }, + { MKTAG('F', 'L', 'O', 'R'), 0x3D799 }, + { MKTAG('F', 'O', 'O', 'D'), 0x3D79A }, + { MKTAG('J', 'F', 'O', 'D'), 0x3D79A }, + { MKTAG('H', 'B', 'B', 'Y'), 0x3D79B }, + { MKTAG('H', 'E', 'R', 'O'), 0x3D79C }, + { MKTAG('H', 'H', 'L', 'D'), 0x3D79D }, + { MKTAG('H', 'O', 'M', 'E'), 0x3D79E }, + { MKTAG('H', 'O', 'S', 'T'), 0x3D79F }, + { MKTAG('K', 'N', 'O', 'B'), 0x3D7A0 }, + { MKTAG('L', 'I', 'Q', 'D'), 0x3D7A1 }, + { MKTAG('L', 'I', 'T', 'R'), 0x3D7A2 }, + { MKTAG('M', 'A', 'G', 'S'), 0x3D7A3 }, + { MKTAG('M', 'C', 'P', 'Y'), 0x3D7A4 }, + { MKTAG('M', 'I', 'N', 'S'), 0x3D7A5 }, + { MKTAG('M', 'L', 'T', 'Y'), 0x3D7A6 }, + { MKTAG('M', 'U', 'S', 'I'), 0x3D7A7 }, + { MKTAG('N', 'A', 'U', 'T'), 0x3D7A8 }, + { MKTAG('P', 'G', 'R', 'P'), 0x3D7A9 }, + { MKTAG('P', 'H', 'I', 'L'), 0x3D7AA }, + { MKTAG('P', 'K', 'U', 'P'), 0x3D7AB }, + { MKTAG('P', 'L', 'A', 'N'), 0x3D7AC }, + { MKTAG('B', 'L', 'P', '1'), 0x3D7AD }, + { MKTAG('B', 'L', 'P', '2'), 0x3D7AD }, + { MKTAG('P', 'T', 'I', 'C'), 0x3D7AD }, + { MKTAG('R', 'C', 'K', 'T'), 0x3D7AE }, + { MKTAG('S', 'C', 'I', 'E'), 0x3D7AF }, + { MKTAG('S', 'C', 'I', 'T'), 0x3D7B0 }, + { MKTAG('S', 'E', 'X', '1'), 0x3D7B1 }, + { MKTAG('S', 'F', 'S', 'F'), 0x3D7B2 }, + { MKTAG('S', 'O', 'A', 'P'), 0x3D7B4 }, + { MKTAG('S', 'O', 'N', 'G'), 0x3D7B5 }, + { MKTAG('S', 'P', 'R', 'T'), 0x3D7B6 }, + { MKTAG('S', 'W', 'E', 'R'), 0x3D7B7 }, + { MKTAG('T', 'D', 'V', 'P'), 0x3D7BC }, + { MKTAG('T', 'E', 'A', 'M'), 0x3D7BD }, + { MKTAG('T', 'I', 'T', 'A'), 0x3D7BF }, + { MKTAG('T', 'L', 'A', ' '), 0x3D7C0 }, + { MKTAG('T', 'O', 'Y', 'S'), 0x3D7C1 }, + { MKTAG('T', 'R', 'A', '2'), 0x3D7C2 }, + { MKTAG('T', 'R', 'A', '3'), 0x3D7C3 }, + { MKTAG('T', 'V', 'S', 'H'), 0x3D7C4 }, + { MKTAG('W', 'E', 'A', 'P'), 0x3D7C5 }, + { MKTAG('W', 'E', 'A', 'T'), 0x3D7C6 }, + { MKTAG('W', 'W', 'E', 'B'), 0x3D7C7 }, + { MKTAG('I', 'S', 'H', 'E'), 0x3D221 }, + { MKTAG('L', 'I', 'T', 'E'), 0x3D31B }, + { MKTAG('B', 'Y', 'Z', 'A'), 0x3D448 }, + { MKTAG('W', 'T', 'H', 'R'), 0x3D6E5 }, + { MKTAG('N', 'P', 'L', 'C'), 0x3D231 }, + { MKTAG('B', 'A', 'R', '1'), 0x3D095 }, + { MKTAG('B', 'A', 'R', '2'), 0x3D107 }, + { MKTAG('B', 'A', 'R', '3'), 0x3D09D }, + { MKTAG('M', 'P', 'O', 'P'), 0x3D0D3 }, + { MKTAG('J', 'O', 'K', 'E'), 0x3D5A9 }, + { MKTAG('J', 'N', 'A', 'M'), 0x3D5A9 }, + { MKTAG('N', 'I', 'B', '1'), 0x3D128 }, + { MKTAG('N', 'I', 'B', '2'), 0x3D0DC }, + { MKTAG('N', 'I', 'B', '3'), 0x3D345 }, + { MKTAG('N', 'I', 'B', '4'), 0x3D125 }, + { MKTAG('N', 'I', 'B', '5'), 0x3D369 }, + { MKTAG('N', 'I', 'B', '6'), 0x3D444 }, + { MKTAG('B', 'A', 'R', '4'), 0x3D0DF }, + { MKTAG('F', 'U', 'L', 'N'), 0x3D32C } +}; + +const int DOORBOT_RESPONSES[101][2] = { + { MKTAG('W', 'E', 'A', 'T'), 0x2E29 }, + { MKTAG('T', 'W', 'A', 'T'), 0x2E29 }, + { MKTAG('B', 'A', 'R', 'M'), 0x2E29 }, + { MKTAG('B', 'A', 'R', 'U'), 0x2E29 }, + { MKTAG('B', 'A', 'R', 'K'), 0x2E29 }, + { MKTAG('B', 'Y', 'Z', 'A'), 0x274E }, + { MKTAG('S', 'I', 'C', 'K'), 0x28AC }, + { MKTAG('B', 'O', 'D', 'Y'), 0x28AC }, + { MKTAG('N', 'H', 'R', 'O'), 0x28A8 }, + { MKTAG('N', 'P', 'L', 'C'), 0x28A7 }, + { MKTAG('H', 'O', 'M', 'E'), 0x28A7 }, + { MKTAG('S', 'C', 'I', 'E'), 0x28A9 }, + { MKTAG('P', 'T', 'I', 'C'), 0x2E42 }, + { MKTAG('P', 'G', 'R', 'P'), 0x2E42 }, + { MKTAG('B', 'L', 'P', '1'), 0x2E42 }, + { MKTAG('B', 'L', 'P', '2'), 0x2E42 }, + { MKTAG('B', 'L', 'P', '3'), 0x2E42 }, + { MKTAG('B', 'L', 'P', '4'), 0x2E42 }, + { MKTAG('B', 'L', 'F', '1'), 0x2E3C }, + { MKTAG('B', 'L', 'F', '2'), 0x2E3C }, + { MKTAG('B', 'L', 'R', '1'), 0x2E42 }, + { MKTAG('B', 'L', 'T', '1'), 0x2E56 }, + { MKTAG('B', 'L', 'T', '2'), 0x2E48 }, + { MKTAG('B', 'L', 'T', '3'), 0x2E55 }, + { MKTAG('B', 'L', 'T', '4'), 0x2E56 }, + { MKTAG('B', 'L', 'T', '5'), 0x2E56 }, + { MKTAG('S', 'W', 'E', 'R'), 0x2E4E }, + { MKTAG('S', 'O', 'N', 'G'), 0x2E49 }, + { MKTAG('L', 'I', 'T', 'R'), 0x2E40 }, + { MKTAG('A', 'R', 'T', 'I'), 0x2E1F }, + { MKTAG('N', 'I', 'K', 'E'), 0x2E22 }, + { MKTAG('E', 'M', 'O', 'T'), 0x2E38 }, + { MKTAG('D', 'R', 'U', 'G'), 0x2E36 }, + { MKTAG('E', 'A', 'R', 'T'), 0x2E37 }, + { MKTAG('F', 'A', 'M', 'E'), 0x2E39 }, + { MKTAG('F', 'A', 'U', 'N'), 0x2E3B }, + { MKTAG('F', 'I', 'S', 'H'), 0x2E3B }, + { MKTAG('F', 'L', 'O', 'R'), 0x2E3D }, + { MKTAG('F', 'O', 'O', 'D'), 0x2E3E }, + { MKTAG('J', 'F', 'O', 'D'), 0x2E3E }, + { MKTAG('H', 'B', 'B', 'Y'), 0x2E3F }, + { MKTAG('H', 'E', 'R', 'O'), 0x2E4D }, + { MKTAG('H', 'O', 'S', 'T'), 0x2E55 }, + { MKTAG('L', 'I', 'Q', 'D'), 0x2E35 }, + { MKTAG('M', 'A', 'G', 'S'), 0x2E40 }, + { MKTAG('P', 'H', 'I', 'L'), 0x2E44 }, + { MKTAG('P', 'K', 'U', 'P'), 0x2E24 }, + { MKTAG('P', 'L', 'A', 'N'), 0x2E45 }, + { MKTAG('R', 'C', 'K', 'T'), 0x2E4A }, + { MKTAG('S', 'E', 'X', '1'), 0x2E47 }, + { MKTAG('S', 'U', 'C', '1'), 0x2E47 }, + { MKTAG('S', 'O', 'A', 'P'), 0x2E48 }, + { MKTAG('T', 'O', 'Y', 'S'), 0x2E50 }, + { MKTAG('H', 'H', 'L', 'D'), 0x2E50 }, + { MKTAG('A', 'C', 'T', 'R'), 0x2E1B }, + { MKTAG('A', 'C', 'T', 'S'), 0x2E1C }, + { MKTAG('A', 'D', 'V', 'T'), 0x2E1D }, + { MKTAG('B', 'R', 'N', 'D'), 0x2E21 }, + { MKTAG('B', 'R', 'N', '2'), 0x2E22 }, + { MKTAG('B', 'R', 'N', '3'), 0x2E23 }, + { MKTAG('F', 'A', 'S', 'H'), 0x2E3A }, + { MKTAG('F', 'I', 'L', 'M'), 0x2E3C }, + { MKTAG('K', 'N', 'O', 'B'), 0x2E42 }, + { MKTAG('M', 'U', 'S', 'I'), 0x2E43 }, + { MKTAG('S', 'F', 'S', 'F'), 0x2E46 }, + { MKTAG('S', 'P', 'R', 'T'), 0x2E4B }, + { MKTAG('T', 'E', 'A', 'M'), 0x2E4C }, + { MKTAG('T', 'R', 'A', 'V'), 0x2E52 }, + { MKTAG('T', 'V', 'S', 'H'), 0x2E56 }, + { MKTAG('W', 'E', 'A', 'P'), 0x2E57 }, + { MKTAG('W', 'W', 'E', 'B'), 0x2E58 }, + { MKTAG('A', 'R', 'T', 'Y'), 0x2E1E }, + { MKTAG('C', 'O', 'M', 'D'), 0x2E25 }, + { MKTAG('C', 'O', 'O', 'K'), 0x2E26 }, + { MKTAG('C', 'O', 'P', 'S'), 0x2E27 }, + { MKTAG('C', 'R', 'I', 'M'), 0x2E28 }, + { MKTAG('D', 'C', 'T', 'R'), 0x2E29 }, + { MKTAG('A', 'U', 'T', 'H'), 0x2E29 }, + { MKTAG('M', 'L', 'T', 'Y'), 0x2E41 }, + { MKTAG('S', 'A', 'S', 'S'), 0x28C3 }, + { MKTAG('B', 'O', 'Y', 'S'), 0x2768 }, + { MKTAG('G', 'I', 'R', 'L'), 0x2769 }, + { MKTAG('T', 'D', 'V', 'P'), 0x277D }, + { MKTAG('I', 'S', 'H', 'E'), 0x27B6 }, + { MKTAG('J', 'O', 'K', 'E'), 0x29FF }, + { MKTAG('J', 'N', 'A', 'M'), 0x29FF }, + { MKTAG('S', 'L', 'O', 'W'), 0x2823 }, + { MKTAG('T', 'H', 'R', 'T'), 0x2823 }, + { MKTAG('D', 'O', 'R', '2'), 0x2BC0 }, + { MKTAG('M', 'P', 'O', 'P'), 0x2BC0 }, + { MKTAG('C', 'L', 'U', 'B'), 0x2E39 }, + { MKTAG('C', 'O', 'L', 'R'), 0x2776 }, + { MKTAG('D', 'N', 'C', 'E'), 0x2931 }, + { MKTAG('M', 'C', 'P', 'Y'), 0x276B }, + { MKTAG('M', 'I', 'N', 'S'), 0x2E43 }, + { MKTAG('P', 'L', 'A', 'C'), 0x2E37 }, + { MKTAG('T', 'I', 'T', 'A'), 0x2E40 }, + { MKTAG('T', 'L', 'A', ' '), 0x277D }, + { MKTAG('H', 'A', 'H', 'A'), 0x27A8 }, + { MKTAG('F', 'U', 'L', 'N'), 0x2B15 }, + { MKTAG('B', 'A', 'R', '1'), 0x2E35 } +}; + +const int LIFTBOT_RESPONSES[34][2] = { + { MKTAG('L', 'I', 'F', '1'), 0x33453 }, + { MKTAG('L', 'I', 'F', '2'), 0x3345D }, + { MKTAG('L', 'I', 'F', '3'), 0x3354E }, + { MKTAG('L', 'I', 'F', '4'), 0x3374B }, + { MKTAG('I', 'S', 'H', 'E'), 0x335F7 }, + { MKTAG('J', 'O', 'K', 'E'), 0x3374B }, + { MKTAG('J', 'N', 'A', 'M'), 0x3374B }, + { MKTAG('S', 'L', 'O', 'W'), 0x337B5 }, + { MKTAG('T', 'H', 'R', 'T'), 0x337BB }, + { MKTAG('S', 'C', 'I', 'E'), 0x337B2 }, + { MKTAG('S', 'C', 'I', 'T'), 0x337B4 }, + { MKTAG('T', 'D', 'V', 'P'), 0x337BA }, + { MKTAG('T', 'I', 'T', 'A'), 0x337C0 }, + { MKTAG('C', 'S', 'P', 'Y'), 0x337A5 }, + { MKTAG('M', 'U', 'S', 'I'), 0x337AA }, + { MKTAG('M', 'C', 'P', 'Y'), 0x337A9 }, + { MKTAG('D', 'N', 'C', 'E'), 0x337A7 }, + { MKTAG('N', 'A', 'U', 'T'), 0x337AC }, + { MKTAG('T', 'L', 'A', ' '), 0x337C1 }, + { MKTAG('S', 'U', 'M', 'S'), 0x33598 }, + { MKTAG('O', 'R', 'D', '1'), 0x33776 }, + { MKTAG('O', 'R', 'D', '2'), 0x33779 }, + { MKTAG('O', 'R', 'D', '3'), 0x3377A }, + { MKTAG('O', 'R', 'D', '4'), 0x3377B }, + { MKTAG('O', 'R', 'D', '5'), 0x3377C }, + { MKTAG('O', 'R', 'D', '6'), 0x3377D }, + { MKTAG('O', 'R', 'D', '7'), 0x3377E }, + { MKTAG('L', 'I', 'Q', 'D'), 0x337FC }, + { MKTAG('F', 'O', 'O', 'D'), 0x337FD }, + { MKTAG('J', 'F', 'O', 'D'), 0x337FD }, + { MKTAG('W', 'E', 'A', 'T'), 0x337E3 }, + { MKTAG('S', 'I', 'C', 'K'), 0x336A1 }, + { MKTAG('B', 'O', 'D', 'Y'), 0x33624 }, + { MKTAG('B', 'Y', 'Z', 'A'), 0x33617 } +}; + +const int MAITRED_RESPONSES[74][2] = { + { MKTAG('M', 'A', 'D', '1'), 0x3F7E2 }, + { MKTAG('M', 'A', 'D', '2'), 0x3F916 }, + { MKTAG('M', 'A', 'D', '3'), 0x3F931 }, + { MKTAG('M', 'A', 'D', '4'), 0x3F936 }, + { MKTAG('M', 'A', 'D', '5'), 0x3F938 }, + { MKTAG('M', 'A', 'D', '6'), 0x3F943 }, + { MKTAG('M', 'A', 'D', '7'), 0x3F947 }, + { MKTAG('M', 'A', 'D', '8'), 0x3F945 }, + { MKTAG('M', 'A', 'D', '9'), 0x3F946 }, + { MKTAG('M', 'D', '1', '0'), 0x3F9F5 }, + { MKTAG('M', 'D', '1', '1'), 0x3F982 }, + { MKTAG('J', 'F', 'O', 'D'), 0x3F930 }, + { MKTAG('C', 'M', 'N', 'T'), 0x3F937 }, + { MKTAG('H', 'A', 'H', 'A'), 0x3FA47 }, + { MKTAG('S', 'U', 'M', 'S'), 0x3F9FE }, + { MKTAG('A', 'N', 'S', 'W'), 0x3F90B }, + { MKTAG('M', 'U', 'S', 'I'), 0x3FA35 }, + { MKTAG('S', 'O', 'N', 'G'), 0x3FA35 }, + { MKTAG('A', 'C', 'T', 'R'), 0x3F9B6 }, + { MKTAG('A', 'C', 'T', 'S'), 0x3F9B7 }, + { MKTAG('A', 'R', 'T', 'I'), 0x3F9CE }, + { MKTAG('A', 'R', 'T', 'Y'), 0x3F9CE }, + { MKTAG('A', 'U', 'T', 'H'), 0x3FAB6 }, + { MKTAG('C', 'O', 'M', 'D'), 0x3F963 }, + { MKTAG('C', 'O', 'P', 'S'), 0x3F9F8 }, + { MKTAG('C', 'R', 'I', 'M'), 0x3F9F8 }, + { MKTAG('C', 'S', 'P', 'Y'), 0x3F965 }, + { MKTAG('D', 'C', 'T', 'R'), 0x3F9B6 }, + { MKTAG('D', 'R', 'U', 'G'), 0x3F96F }, + { MKTAG('E', 'A', 'R', 'T'), 0x3F9E3 }, + { MKTAG('E', 'M', 'O', 'T'), 0x3FA29 }, + { MKTAG('F', 'A', 'M', 'E'), 0x3FAB6 }, + { MKTAG('F', 'A', 'S', 'H'), 0x3F8EA }, + { MKTAG('F', 'A', 'U', 'N'), 0x3F969 }, + { MKTAG('F', 'I', 'L', 'M'), 0x3F9CE }, + { MKTAG('F', 'L', 'O', 'R'), 0x3F9A3 }, + { MKTAG('H', 'B', 'B', 'Y'), 0x3F987 }, + { MKTAG('H', 'E', 'R', 'O'), 0x3F8DA }, + { MKTAG('H', 'H', 'G', 'Q'), 0x3F96B }, + { MKTAG('H', 'H', 'L', 'D'), 0x3FA2B }, + { MKTAG('H', 'O', 'S', 'T'), 0x3F9E1 }, + { MKTAG('K', 'N', 'O', 'B'), 0x3F9E1 }, + { MKTAG('L', 'I', 'Q', 'D'), 0x3F91C }, + { MKTAG('L', 'I', 'T', 'R'), 0x3F9CE }, + { MKTAG('M', 'A', 'G', 'S'), 0x3F912 }, + { MKTAG('M', 'L', 'T', 'Y'), 0x3F9F7 }, + { MKTAG('P', 'G', 'R', 'P'), 0x3F8D0 }, + { MKTAG('P', 'H', 'I', 'L'), 0x3F8E9 }, + { MKTAG('P', 'K', 'U', 'P'), 0x3F9FB }, + { MKTAG('P', 'L', 'A', 'C'), 0x3FA22 }, + { MKTAG('P', 'T', 'I', 'C'), 0x3F8D0 }, + { MKTAG('R', 'C', 'K', 'T'), 0x3F9A3 }, + { MKTAG('S', 'C', 'I', 'E'), 0x3F968 }, + { MKTAG('S', 'C', 'I', 'T'), 0x3F9E2 }, + { MKTAG('S', 'E', 'X', '1'), 0x3F9C9 }, + { MKTAG('S', 'F', 'S', 'F'), 0x3F988 }, + { MKTAG('S', 'O', 'A', 'P'), 0x3FA3C }, + { MKTAG('S', 'P', 'R', 'T'), 0x3FAB6 }, + { MKTAG('S', 'W', 'E', 'R'), 0x3F96B }, + { MKTAG('T', 'E', 'A', 'M'), 0x3F9B8 }, + { MKTAG('T', 'O', 'Y', 'S'), 0x3F96D }, + { MKTAG('T', 'V', 'S', 'H'), 0x3F9CE }, + { MKTAG('W', 'E', 'A', 'P'), 0x3F9D8 }, + { MKTAG('W', 'W', 'E', 'B'), 0x3F987 }, + { MKTAG('B', 'Y', 'Z', 'A'), 0x3F9A5 }, + { MKTAG('T', 'W', 'A', 'T'), 0x3F96F }, + { MKTAG('M', 'C', 'P', 'Y'), 0x3F9B9 }, + { MKTAG('T', 'H', 'R', 'T'), 0x3FB15 }, + { MKTAG('T', 'D', 'V', 'P'), 0x3FB17 }, + { MKTAG('T', 'I', 'T', 'A'), 0x3FB18 }, + { MKTAG('M', 'I', 'N', 'S'), 0x3FB19 }, + { MKTAG('D', 'N', 'C', 'E'), 0x3FB1A }, + { MKTAG('N', 'A', 'U', 'T'), 0x3FB1B }, + { MKTAG('T', 'L', 'A', ' '), 0x3FB1C } +}; + +void writeScriptResponses(const char *name, const int *tags, uint count, int valuesPerTag) { + outputFile.seek(dataOffset); + + for (int idx = 0; idx < count * (valuesPerTag + 1); ++idx, ++tags) + outputFile.writeLong(*tags); + + writeEntryHeader(name, dataOffset, count * (valuesPerTag + 1) * 4); + dataOffset += count * (valuesPerTag + 1) * 4; +} + +void writeAllScriptResponses() { + writeScriptResponses("Responses/Barbot", &BARBOT_RESPONSES[0][0], 93, 1); + writeScriptResponses("Responses/Bellbot", &BELLBOT_RESPONSES[0][0], 130, 4); + writeScriptResponses("Responses/Deskbot", &DESKBOT_RESPONSES[0][0], 128, 4); + writeScriptResponses("Responses/Doorbot", &DOORBOT_RESPONSES[0][0], 101, 1); + writeScriptResponses("Responses/Liftbot", &LIFTBOT_RESPONSES[0][0], 34, 1); + writeScriptResponses("Responses/MaitreD", &MAITRED_RESPONSES[0][0], 74, 1); +}
\ No newline at end of file diff --git a/devtools/create_titanic/script_responses.h b/devtools/create_titanic/script_responses.h new file mode 100644 index 0000000000..ca927e0ccd --- /dev/null +++ b/devtools/create_titanic/script_responses.h @@ -0,0 +1,32 @@ +/* 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 COMMON_SCRIPT_TAGS_H +#define COMMON_SCRIPT_TAGS_H + +#include "common/scummsys.h" + +extern void writeAllScriptResponses(); +extern void writeEntryHeader(const char *name, uint offset, uint size); +extern uint dataOffset; + +#endif diff --git a/devtools/create_titanic/script_states.cpp b/devtools/create_titanic/script_states.cpp new file mode 100644 index 0000000000..81157441e4 --- /dev/null +++ b/devtools/create_titanic/script_states.cpp @@ -0,0 +1,548 @@ +/* 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. + * + */ + + // Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +// HACK to allow building with the SDL backend on MinGW +// see bug #1800764 "TOOLS: MinGW tools building broken" +#ifdef main +#undef main +#endif // main + +#include "file.h" +#include "script_states.h" + +static const UpdateState12 BARBOT_STATES[] = { + { 0x0003AB24, 0x00000005, 0x00 }, + { 0x0003AD33, 0x00000005, 0x00 }, + { 0x0003AB40, 0x00000008, 0x00 }, + { 0x0003AC6A, 0x00000008, 0x00 }, + { 0x0003AB3E, 0x00000006, 0x00 }, + { 0x0003AB3D, 0x00000006, 0x00 }, + { 0x0003AB41, 0x00000007, 0x00 }, + { 0x0003AB69, 0x00000008, 0x00 }, + { 0x0003AE6D, 0x0000004E, 0x00 }, + { 0x0003AC69, 0x0000004E, 0x00 }, + { 0x0003AE6E, 0x0000004F, 0x00 }, + { 0x0003AE6F, 0x00000051, 0x00 }, + { 0x0003AE70, 0x00000051, 0x00 }, + { 0x0003AE71, 0x00000051, 0x00 }, + { 0x0003AE72, 0x00000051, 0x00 }, + { 0x0003AE73, 0x00000051, 0x00 }, + { 0x0003AE74, 0x00000051, 0x00 }, + { 0x0003AE75, 0x00000051, 0x00 }, + { 0x0003AE76, 0x00000051, 0x00 }, + { 0x0003AE77, 0x00000051, 0x00 }, + { 0x0003AEB8, 0x00000051, 0x00 }, + { 0x0003AB20, 0x00000009, 0x00 }, + { 0x0003AB14, 0x0000000A, 0x00 }, + { 0x0003AB15, 0x0000000B, 0x00 }, + { 0x0003AB16, 0x0000000C, 0x00 }, + { 0x0003AB63, 0x0000000D, 0x00 }, + { 0x0003AB64, 0x0000000D, 0x00 }, + { 0x0003AB44, 0x00000001, 0x00 }, + { 0x0003AB43, 0x00000001, 0x0B }, + { 0x0003AB2A, 0x00000002, 0x00 }, + { 0x0003AB4A, 0x00000003, 0x0B }, + { 0x0003AB4C, 0x00000003, 0x0B }, + { 0x0003AB65, 0x00000004, 0x00 }, + { 0x0003AB2F, 0x0000000E, 0x00 }, + { 0x0003AB30, 0x0000000F, 0x00 }, + { 0x0003AB17, 0x00000010, 0x0B }, + { 0x0003AB18, 0x00000010, 0x0B }, + { 0x0003AAE3, 0x0000003E, 0x00 }, + { 0x0003AAE4, 0x0000003E, 0x00 }, + { 0x0003AAE5, 0x0000003E, 0x00 }, + { 0x0003AB0F, 0x00000011, 0x00 }, + { 0x0003AB11, 0x00000012, 0x00 }, + { 0x0003AB12, 0x00000013, 0x00 }, + { 0x0003AB13, 0x00000014, 0x00 }, + { 0x0003AADC, 0x00000019, 0x00 }, + { 0x0003AADD, 0x0000001A, 0x00 }, + { 0x0003AADE, 0x0000001B, 0x00 }, + { 0x0003AAFD, 0x00000015, 0x00 }, + { 0x0003AAFE, 0x00000016, 0x00 }, + { 0x0003AAFF, 0x00000017, 0x00 }, + { 0x0003AB00, 0x00000018, 0x00 }, + { 0x0003AAF4, 0x0000001C, 0x00 }, + { 0x0003AAF5, 0x0000001D, 0x00 }, + { 0x0003AAF6, 0x0000001E, 0x00 }, + { 0x0003AAD9, 0x0000001F, 0x00 }, + { 0x0003AADA, 0x00000020, 0x00 }, + { 0x0003AADB, 0x00000021, 0x00 }, + { 0x0003AAF7, 0x00000022, 0x00 }, + { 0x0003AAF8, 0x00000023, 0x00 }, + { 0x0003AAF9, 0x00000024, 0x00 }, + { 0x0003AB04, 0x0000002C, 0x00 }, + { 0x0003AB05, 0x0000002D, 0x00 }, + { 0x0003AB06, 0x0000002E, 0x00 }, + { 0x0003AADF, 0x00000029, 0x00 }, + { 0x0003AAE0, 0x0000002A, 0x00 }, + { 0x0003AAE1, 0x0000002B, 0x00 }, + { 0x0003AB07, 0x00000038, 0x00 }, + { 0x0003AB08, 0x00000039, 0x00 }, + { 0x0003AB09, 0x0000003A, 0x00 }, + { 0x0003AB01, 0x0000003B, 0x00 }, + { 0x0003AB02, 0x0000003C, 0x00 }, + { 0x0003AB03, 0x0000003D, 0x00 }, + { 0x0003AAF0, 0x00000025, 0x00 }, + { 0x0003AAF1, 0x00000026, 0x00 }, + { 0x0003AAF2, 0x00000027, 0x00 }, + { 0x0003AAF3, 0x00000028, 0x00 }, + { 0x0003AB0A, 0x0000002F, 0x00 }, + { 0x0003AB0B, 0x00000030, 0x00 }, + { 0x0003AB0C, 0x00000031, 0x00 }, + { 0x0003AB0D, 0x00000032, 0x00 }, + { 0x0003AAEA, 0x00000033, 0x00 }, + { 0x0003AAEB, 0x00000034, 0x00 }, + { 0x0003AAEC, 0x00000035, 0x00 }, + { 0x0003AAED, 0x00000036, 0x00 }, + { 0x0003AAEE, 0x00000037, 0x00 }, + { 0x0003ACC3, 0x0000003F, 0x00 }, + { 0x0003ACC4, 0x00000040, 0x00 }, + { 0x0003ACC5, 0x00000041, 0x00 }, + { 0x0003ACC6, 0x00000042, 0x00 }, + { 0x0003ACC7, 0x00000043, 0x00 }, + { 0x0003ACC8, 0x00000044, 0x00 }, + { 0x0003ADCF, 0x00000045, 0x00 }, + { 0x0003ADD0, 0x00000046, 0x00 }, + { 0x0003ADD1, 0x00000047, 0x00 }, + { 0x0003ADD2, 0x00000048, 0x00 }, + { 0x0003ADD3, 0x00000049, 0x00 }, + { 0x0003ACA4, 0x0000004A, 0x00 }, + { 0x0003ACA7, 0x0000004B, 0x00 }, + { 0x0003ADD5, 0x0000004C, 0x00 }, + { 0x0003AC7E, 0x0000004C, 0x00 }, + { 0x0003ABF9, 0x0000004C, 0x00 }, + { 0x0003AD14, 0x0000004C, 0x00 }, + { 0x0003AD15, 0x0000004C, 0x00 }, + { 0x0003AD10, 0x0000004C, 0x00 }, + { 0x0003AD17, 0x0000004C, 0x00 }, + { 0x0003AD21, 0x0000004C, 0x00 }, + { 0x0003AD2F, 0x0000004C, 0x00 }, + { 0x0003AC7F, 0x0000004D, 0x00 }, + { 0x0003AEBA, 0x00000052, 0x0E }, + { 0x0003AED5, 0x00000053, 0x00 }, + { 0x0003B034, 0x00000054, 0x00 }, + { 0x0003B037, 0x00000054, 0x00 }, + { 0x0003B036, 0x00000055, 0x00 }, + { 0x0003B035, 0x00000055, 0x00 }, + { 0x0003B02D, 0x00000055, 0x00 }, + { 0x0003B02F, 0x00000055, 0x00 }, + { 0x0003B02E, 0x00000056, 0x00 }, + { 0x0003B031, 0x00000056, 0x00 }, + { 0x0003B033, 0x00000056, 0x00 }, + { 0x0003B032, 0x00000057, 0x00 }, + { 0x0003B023, 0x00000057, 0x00 }, + { 0x0003B025, 0x00000057, 0x00 }, + { 0x0003B024, 0x00000058, 0x00 }, + { 0x0003B017, 0x00000058, 0x00 }, + { 0x0003B01C, 0x00000058, 0x00 }, + { 0x0003B01A, 0x00000059, 0x00 }, + { 0x0003B01B, 0x0000005A, 0x00 }, + { 0x0003B018, 0x0000005B, 0x00 }, + { 0x0003B019, 0x0000005D, 0x00 }, + { 0x0003B01D, 0x0000005D, 0x00 }, + { 0x0003B01E, 0x0000005D, 0x00 }, + { 0x0003B01F, 0x0000005D, 0x00 }, + { 0x0003B026, 0x0000005D, 0x00 }, + { 0x0003B027, 0x0000005D, 0x00 }, + { 0x0003B028, 0x0000005D, 0x00 }, + { 0x0003B029, 0x0000005D, 0x00 }, + { 0x0003B030, 0x0000005D, 0x00 }, + { 0x0003B02A, 0x0000005E, 0x00 }, + { 0x0003ABF7, 0x0000005F, 0x00 }, + { 0x0003AF6A, 0x00000060, 0x00 }, + { 0x0003AEC6, 0x00000061, 0x00 }, + { 0x00000000, 0x00000000, 0x00 } +}; + +static const UpdateState8 BELLBOT_STATES[] = { + { 0x00031070, 0x00000001 }, { 0x0003107B, 0x00000002 }, { 0x0003107E, 0x00000003 }, + { 0x0003104F, 0x00000004 }, { 0x00030F23, 0x00000005 }, { 0x00030F2A, 0x00000006 }, + { 0x00030F31, 0x00000007 }, { 0x00030F32, 0x00000007 }, { 0x00030F33, 0x00000007 }, + { 0x00030F34, 0x00000007 }, { 0x00030F35, 0x00000007 }, { 0x00030F36, 0x00000007 }, + { 0x00030F37, 0x00000008 }, { 0x00030F2E, 0x00000009 }, { 0x00030E78, 0x0000000A }, + { 0x00030E42, 0x0000000C }, { 0x00030E0C, 0x0000000D }, { 0x00030E9C, 0x0000000E }, + { 0x00030DC1, 0x0000000F }, { 0x00030DC2, 0x00000010 }, { 0x00030D6B, 0x00000011 }, + { 0x00030D6C, 0x00000011 }, { 0x00030E1D, 0x00000012 }, { 0x00030E1E, 0x00000013 }, + { 0x00030E3B, 0x00000014 }, { 0x00030EBA, 0x00000015 }, { 0x00031086, 0x00000016 }, + { 0x000310A4, 0x00000017 }, { 0x00031058, 0x00000018 }, { 0x00031059, 0x00000019 }, + { 0x00030E3F, 0x0000001A }, { 0x00030EBC, 0x0000001B }, { 0x00030E9B, 0x0000001C }, + { 0x00030E32, 0x0000001D }, { 0x00030E76, 0x0000001E }, { 0x00031060, 0x0000001F }, + { 0x00031065, 0x00000020 }, { 0x00031075, 0x00000021 }, { 0x00031077, 0x00000022 }, + { 0x00031041, 0x00000023 }, { 0x00031038, 0x00000024 }, { 0x00030FAB, 0x00000025 }, + { 0x00030FAF, 0x00000026 }, { 0x00030FB1, 0x00000027 }, { 0x00030FB8, 0x00000028 }, + { 0x00030FB2, 0x00000029 }, { 0x00030FC1, 0x0000002A }, { 0x00030FC2, 0x0000002B }, + { 0x00030FA4, 0x0000002C }, { 0x00030FA5, 0x0000002D }, { 0x00030FA7, 0x0000002E }, + { 0x00030FA8, 0x0000002C }, { 0x00030FA6, 0x0000002C }, { 0x00030EAD, 0x0000002F }, + { 0x00030EAE, 0x00000030 }, { 0x00030ED6, 0x00000031 }, { 0x00030ED7, 0x00000032 }, + { 0x00030ED8, 0x00000033 }, { 0x000310A9, 0x00000034 }, { 0x00030F4C, 0x00000035 }, + { 0x00030DA7, 0x00000036 }, { 0x00030D9F, 0x00000037 }, { 0x00030FC8, 0x00000038 }, + { 0x00030FC9, 0x00000039 }, { 0x00030FCF, 0x0000003A }, { 0x00030FCA, 0x0000003B }, + { 0x00030FCB, 0x0000003C }, { 0x00030FCC, 0x0000003D }, { 0x00030E41, 0x0000003E }, + { 0x00030E12, 0x0000003F }, { 0x00030D72, 0x00000040 }, { 0x00030D76, 0x00000041 }, + { 0x00030D78, 0x00000042 }, { 0x00030D79, 0x00000043 }, { 0x000310AE, 0x00000044 }, + { 0x0003112C, 0x00000044 }, { 0x00031132, 0x00000045 }, { 0x00031133, 0x00000046 }, + { 0x00031134, 0x00000047 }, { 0x000310D7, 0x00000048 }, { 0x0003113C, 0x00000049 }, + { 0x0003113E, 0x0000004A }, { 0x0003113D, 0x0000004A }, { 0x00031146, 0x0000004B }, + { 0x00031149, 0x0000004C }, { 0x0003114A, 0x0000004D }, { 0x0003114E, 0x0000004E }, + { 0x00031151, 0x0000004E }, { 0x0003114F, 0x0000004E }, { 0x00031152, 0x0000004E }, + { 0x0003115B, 0x0000004F }, { 0x00031163, 0x00000050 }, { 0x00031164, 0x00000051 }, + { 0x00031165, 0x00000051 }, { 0x00031166, 0x00000051 }, { 0x00031167, 0x00000052 }, + { 0x0003117A, 0x00000053 }, { 0x0003149A, 0x00000054 }, { 0x00031454, 0x00000055 }, + { 0x0003157B, 0x00000056 }, { 0x00031177, 0x00000057 }, { 0x00031171, 0x00000057 }, + { 0x0003117A, 0x00000057 }, { 0x00031507, 0x00000057 }, { 0x0003159D, 0x00000058 }, + { 0x000315DD, 0x00000059 }, { 0x00031147, 0x0000005A }, { 0x00031148, 0x0000005A }, + { 0x00000000, 0x00000000 } +}; + +static const UpdateState12 DESKBOT_STATES[] = { + { 0x0003AB24, 0x00000005, 0x00 }, + { 0x0003AD33, 0x00000005, 0x00 }, + { 0x0003AB40, 0x00000008, 0x00 }, + { 0x0003AC6A, 0x00000008, 0x00 }, + { 0x0003AB3E, 0x00000006, 0x00 }, + { 0x0003AB3D, 0x00000006, 0x00 }, + { 0x0003AB41, 0x00000007, 0x00 }, + { 0x0003AB69, 0x00000008, 0x00 }, + { 0x0003AE6D, 0x0000004E, 0x00 }, + { 0x0003AC69, 0x0000004E, 0x00 }, + { 0x0003AE6E, 0x0000004F, 0x00 }, + { 0x0003AE6F, 0x00000051, 0x00 }, + { 0x0003AE70, 0x00000051, 0x00 }, + { 0x0003AE71, 0x00000051, 0x00 }, + { 0x0003AE72, 0x00000051, 0x00 }, + { 0x0003AE73, 0x00000051, 0x00 }, + { 0x0003AE74, 0x00000051, 0x00 }, + { 0x0003AE75, 0x00000051, 0x00 }, + { 0x0003AE76, 0x00000051, 0x00 }, + { 0x0003AE77, 0x00000051, 0x00 }, + { 0x0003AEB8, 0x00000051, 0x00 }, + { 0x0003AB20, 0x00000009, 0x00 }, + { 0x0003AB14, 0x0000000A, 0x00 }, + { 0x0003AB15, 0x0000000B, 0x00 }, + { 0x0003AB16, 0x0000000C, 0x00 }, + { 0x0003AB63, 0x0000000D, 0x00 }, + { 0x0003AB64, 0x0000000D, 0x00 }, + { 0x0003AB44, 0x00000001, 0x00 }, + { 0x0003AB43, 0x00000001, 0x0B }, + { 0x0003AB2A, 0x00000002, 0x00 }, + { 0x0003AB4A, 0x00000003, 0x0B }, + { 0x0003AB4C, 0x00000003, 0x0B }, + { 0x0003AB65, 0x00000004, 0x00 }, + { 0x0003AB2F, 0x0000000E, 0x00 }, + { 0x0003AB30, 0x0000000F, 0x00 }, + { 0x0003AB17, 0x00000010, 0x0B }, + { 0x0003AB18, 0x00000010, 0x0B }, + { 0x0003AAE3, 0x0000003E, 0x00 }, + { 0x0003AAE4, 0x0000003E, 0x00 }, + { 0x0003AAE5, 0x0000003E, 0x00 }, + { 0x0003AB0F, 0x00000011, 0x00 }, + { 0x0003AB11, 0x00000012, 0x00 }, + { 0x0003AB12, 0x00000013, 0x00 }, + { 0x0003AB13, 0x00000014, 0x00 }, + { 0x0003AADC, 0x00000019, 0x00 }, + { 0x0003AADD, 0x0000001A, 0x00 }, + { 0x0003AADE, 0x0000001B, 0x00 }, + { 0x0003AAFD, 0x00000015, 0x00 }, + { 0x0003AAFE, 0x00000016, 0x00 }, + { 0x0003AAFF, 0x00000017, 0x00 }, + { 0x0003AB00, 0x00000018, 0x00 }, + { 0x0003AAF4, 0x0000001C, 0x00 }, + { 0x0003AAF5, 0x0000001D, 0x00 }, + { 0x0003AAF6, 0x0000001E, 0x00 }, + { 0x0003AAD9, 0x0000001F, 0x00 }, + { 0x0003AADA, 0x00000020, 0x00 }, + { 0x0003AADB, 0x00000021, 0x00 }, + { 0x0003AAF7, 0x00000022, 0x00 }, + { 0x0003AAF8, 0x00000023, 0x00 }, + { 0x0003AAF9, 0x00000024, 0x00 }, + { 0x0003AB04, 0x0000002C, 0x00 }, + { 0x0003AB05, 0x0000002D, 0x00 }, + { 0x0003AB06, 0x0000002E, 0x00 }, + { 0x0003AADF, 0x00000029, 0x00 }, + { 0x0003AAE0, 0x0000002A, 0x00 }, + { 0x0003AAE1, 0x0000002B, 0x00 }, + { 0x0003AB07, 0x00000038, 0x00 }, + { 0x0003AB08, 0x00000039, 0x00 }, + { 0x0003AB09, 0x0000003A, 0x00 }, + { 0x0003AB01, 0x0000003B, 0x00 }, + { 0x0003AB02, 0x0000003C, 0x00 }, + { 0x0003AB03, 0x0000003D, 0x00 }, + { 0x0003AAF0, 0x00000025, 0x00 }, + { 0x0003AAF1, 0x00000026, 0x00 }, + { 0x0003AAF2, 0x00000027, 0x00 }, + { 0x0003AAF3, 0x00000028, 0x00 }, + { 0x0003AB0A, 0x0000002F, 0x00 }, + { 0x0003AB0B, 0x00000030, 0x00 }, + { 0x0003AB0C, 0x00000031, 0x00 }, + { 0x0003AB0D, 0x00000032, 0x00 }, + { 0x0003AAEA, 0x00000033, 0x00 }, + { 0x0003AAEB, 0x00000034, 0x00 }, + { 0x0003AAEC, 0x00000035, 0x00 }, + { 0x0003AAED, 0x00000036, 0x00 }, + { 0x0003AAEE, 0x00000037, 0x00 }, + { 0x0003ACC3, 0x0000003F, 0x00 }, + { 0x0003ACC4, 0x00000040, 0x00 }, + { 0x0003ACC5, 0x00000041, 0x00 }, + { 0x0003ACC6, 0x00000042, 0x00 }, + { 0x0003ACC7, 0x00000043, 0x00 }, + { 0x0003ACC8, 0x00000044, 0x00 }, + { 0x0003ADCF, 0x00000045, 0x00 }, + { 0x0003ADD0, 0x00000046, 0x00 }, + { 0x0003ADD1, 0x00000047, 0x00 }, + { 0x0003ADD2, 0x00000048, 0x00 }, + { 0x0003ADD3, 0x00000049, 0x00 }, + { 0x0003ACA4, 0x0000004A, 0x00 }, + { 0x0003ACA7, 0x0000004B, 0x00 }, + { 0x0003ADD5, 0x0000004C, 0x00 }, + { 0x0003AC7E, 0x0000004C, 0x00 }, + { 0x0003ABF9, 0x0000004C, 0x00 }, + { 0x0003AD14, 0x0000004C, 0x00 }, + { 0x0003AD15, 0x0000004C, 0x00 }, + { 0x0003AD10, 0x0000004C, 0x00 }, + { 0x0003AD17, 0x0000004C, 0x00 }, + { 0x0003AD21, 0x0000004C, 0x00 }, + { 0x0003AD2F, 0x0000004C, 0x00 }, + { 0x0003AC7F, 0x0000004D, 0x00 }, + { 0x0003AEBA, 0x00000052, 0x0E }, + { 0x0003AED5, 0x00000053, 0x00 }, + { 0x0003B034, 0x00000054, 0x00 }, + { 0x0003B037, 0x00000054, 0x00 }, + { 0x0003B036, 0x00000055, 0x00 }, + { 0x0003B035, 0x00000055, 0x00 }, + { 0x0003B02D, 0x00000055, 0x00 }, + { 0x0003B02F, 0x00000055, 0x00 }, + { 0x0003B02E, 0x00000056, 0x00 }, + { 0x0003B031, 0x00000056, 0x00 }, + { 0x0003B033, 0x00000056, 0x00 }, + { 0x0003B032, 0x00000057, 0x00 }, + { 0x0003B023, 0x00000057, 0x00 }, + { 0x0003B025, 0x00000057, 0x00 }, + { 0x0003B024, 0x00000058, 0x00 }, + { 0x0003B017, 0x00000058, 0x00 }, + { 0x0003B01C, 0x00000058, 0x00 }, + { 0x0003B01A, 0x00000059, 0x00 }, + { 0x0003B01B, 0x0000005A, 0x00 }, + { 0x0003B018, 0x0000005B, 0x00 }, + { 0x0003B019, 0x0000005D, 0x00 }, + { 0x0003B01D, 0x0000005D, 0x00 }, + { 0x0003B01E, 0x0000005D, 0x00 }, + { 0x0003B01F, 0x0000005D, 0x00 }, + { 0x0003B026, 0x0000005D, 0x00 }, + { 0x0003B027, 0x0000005D, 0x00 }, + { 0x0003B028, 0x0000005D, 0x00 }, + { 0x0003B029, 0x0000005D, 0x00 }, + { 0x0003B030, 0x0000005D, 0x00 }, + { 0x0003B02A, 0x0000005E, 0x00 }, + { 0x0003ABF7, 0x0000005F, 0x00 }, + { 0x0003AF6A, 0x00000060, 0x00 }, + { 0x0003AEC6, 0x00000061, 0x00 }, + { 0x00000000, 0x00000000, 0x00 } +}; + +static const UpdateState12 DOORBOT_STATES[] = { + { 0x00035BD0, 0x00000004, 0x06 }, + { 0x00035BE7, 0x00000005, 0x00 }, + { 0x00035BED, 0x00000006, 0x0A }, + { 0x00035E41, 0x0000000C, 0x0A }, + { 0x00035F9D, 0x0000000F, 0x00 }, + { 0x00035F81, 0x00000010, 0x00 }, + { 0x00035F82, 0x00000010, 0x00 }, + { 0x00035F83, 0x00000010, 0x00 }, + { 0x00035F84, 0x00000010, 0x00 }, + { 0x00035F85, 0x00000010, 0x00 }, + { 0x00035FC5, 0x00000011, 0x00 }, + { 0x00035B6C, 0x00000021, 0x02 }, + { 0x00035B6D, 0x00000022, 0x02 }, + { 0x00035FCD, 0x00000012, 0x00 }, + { 0x00035EF0, 0x00000020, 0x00 }, + { 0x00035EF1, 0x00000020, 0x00 }, + { 0x00035F0A, 0x00000020, 0x00 }, + { 0x000362B0, 0x00000013, 0x00 }, + { 0x000362B1, 0x00000013, 0x00 }, + { 0x000362B2, 0x00000013, 0x00 }, + { 0x000362B3, 0x00000013, 0x00 }, + { 0x000362B4, 0x00000013, 0x00 }, + { 0x000362B5, 0x00000013, 0x00 }, + { 0x000362B9, 0x00000013, 0x00 }, + { 0x000362BB, 0x00000013, 0x00 }, + { 0x000362BA, 0x00000013, 0x00 }, + { 0x000362BC, 0x00000013, 0x00 }, + { 0x000362B8, 0x00000013, 0x00 }, + { 0x000362BD, 0x00000013, 0x00 }, + { 0x000362BE, 0x00000013, 0x00 }, + { 0x000362BF, 0x00000013, 0x00 }, + { 0x000362C0, 0x00000013, 0x00 }, + { 0x000362C1, 0x00000013, 0x00 }, + { 0x000362C2, 0x00000013, 0x00 }, + { 0x000362B6, 0x00000014, 0x00 }, + { 0x00035F8A, 0x00000015, 0x00 }, + { 0x00036407, 0x00000016, 0x00 }, + { 0x0003640C, 0x00000016, 0x00 }, + { 0x0003641A, 0x00000016, 0x00 }, + { 0x00036420, 0x00000016, 0x00 }, + { 0x00036421, 0x00000016, 0x00 }, + { 0x00036422, 0x00000016, 0x00 }, + { 0x00036408, 0x00000016, 0x00 }, + { 0x0003640A, 0x00000016, 0x00 }, + { 0x0003640B, 0x00000016, 0x00 }, + { 0x0003640D, 0x00000018, 0x00 }, + { 0x00036415, 0x00000016, 0x00 }, + { 0x00036416, 0x00000016, 0x00 }, + { 0x00036417, 0x00000016, 0x00 }, + { 0x00036418, 0x00000016, 0x00 }, + { 0x00036419, 0x00000016, 0x00 }, + { 0x0003640E, 0x00000016, 0x00 }, + { 0x0003640F, 0x00000016, 0x00 }, + { 0x00036410, 0x00000016, 0x00 }, + { 0x00036411, 0x00000019, 0x00 }, + { 0x00036412, 0x0000001A, 0x00 }, + { 0x0003641B, 0x00000016, 0x00 }, + { 0x0003641C, 0x00000016, 0x00 }, + { 0x0003641D, 0x00000016, 0x00 }, + { 0x0003641F, 0x00000016, 0x00 }, + { 0x00035FF6, 0x0000001B, 0x00 }, + { 0x00035FF7, 0x0000001C, 0x00 }, + { 0x00035FF8, 0x0000001D, 0x00 }, + { 0x00035FF9, 0x0000001E, 0x00 }, + { 0x0003627F, 0x00000023, 0x00 }, + { 0x00036280, 0x00000024, 0x00 }, + { 0x00036281, 0x00000025, 0x00 }, + { 0x00036282, 0x00000025, 0x00 }, + { 0x00036457, 0x00000026, 0x00 }, + { 0x00000000, 0x00000000, 0x00 } +}; + +static const UpdateState8 LIFTBOT_STATES[] = { + { 0x000335D6, 0x00000004 }, + { 0x000337A7, 0x00000005 }, + { 0x00033781, 0x00000006 }, + { 0x0003381A, 0x00000009 }, + { 0x0003381B, 0x00000009 }, + { 0x0003381E, 0x00000009 }, + { 0x0003381F, 0x00000009 }, + { 0x00033820, 0x00000009 }, + { 0x00033821, 0x00000009 }, + { 0x00033822, 0x00000009 }, + { 0x00033823, 0x00000009 }, + { 0x00033824, 0x00000009 }, + { 0x00033825, 0x00000009 }, + { 0x0003381C, 0x00000009 }, + { 0x0003381D, 0x00000009 }, + { 0x00000000, 0x00000000 } +}; + +static const UpdateState8 MAITRED_STATES[] = { + { 0x0003F7D4, 0x00000002 }, + { 0x0003F808, 0x00000003 }, + { 0x0003F809, 0x00000009 }, + { 0x0003F7F9, 0x00000009 }, + { 0x0003F7D2, 0x00000009 }, + { 0x0003F7F6, 0x00000004 }, + { 0x0003F7D3, 0x00000005 }, + { 0x0003F800, 0x00000006 }, + { 0x0003F801, 0x00000007 }, + { 0x0003F7FC, 0x00000008 }, + { 0x0003F7FD, 0x00000008 }, + { 0x0003F7F8, 0x00000008 }, + { 0x0003F7FA, 0x00000008 }, + { 0x0003F7F1, 0x0000000A }, + { 0x0003F7F2, 0x0000000A }, + { 0x0003F7F3, 0x0000000A }, + { 0x0003F7F4, 0x0000000A }, + { 0x0003F7F5, 0x0000000A }, + { 0x0003F877, 0x0000000B }, + { 0x0003FA55, 0x0000000C }, + { 0x0003F863, 0x0000000C }, + { 0x0003F864, 0x0000000C }, + { 0x0003F865, 0x0000000C }, + { 0x0003F866, 0x0000000D }, + { 0x0003F867, 0x0000000E }, + { 0x0003F86E, 0x0000000E }, + { 0x0003F868, 0x0000000F }, + { 0x0003F869, 0x0000000C }, + { 0x0003F870, 0x00000010 }, + { 0x0003F87C, 0x00000011 }, + { 0x0003F87D, 0x00000011 }, + { 0x0003F886, 0x00000012 }, + { 0x0003F889, 0x00000013 }, + { 0x0003F88A, 0x00000014 }, + { 0x0003F88B, 0x00000015 }, + { 0x0003F88C, 0x00000015 }, + { 0x0003F88D, 0x00000016 }, + { 0x0003F88E, 0x00000016 }, + { 0x0003F895, 0x00000016 }, + { 0x0003F893, 0x00000017 }, + { 0x0003F89A, 0x00000018 }, + { 0x0003F875, 0x00000019 }, + { 0x0003F89C, 0x00000019 }, + { 0x0003F8A3, 0x00000019 }, + { 0x0003F8A2, 0x00000019 }, + { 0x0003F89D, 0x0000001A }, + { 0x0003F89E, 0x0000001A }, + { 0x0003F89F, 0x0000001A }, + { 0x0003F8A5, 0x0000001B }, + { 0x0003F921, 0x0000001C }, + { 0x0003F922, 0x0000001C }, + { 0x0003FA56, 0x0000001E }, + { 0x00000000, 0x00000000 } +}; + +void writeUpdateStates(const char *name, const UpdateState8 *states) { + outputFile.seek(dataOffset); + + for (; states->_src; ++states) { + outputFile.writeLong(states->_src); + outputFile.writeLong(states->_dest); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader(name, dataOffset, size); + dataOffset += size; +} + +void writeUpdateStates(const char *name, const UpdateState12 *states) { + outputFile.seek(dataOffset); + + for (; states->_newId; ++states) { + outputFile.writeLong(states->_newId); + outputFile.writeLong(states->_newValue); + outputFile.writeLong(states->_idMatch); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader(name, dataOffset, size); + dataOffset += size; +} + +void writeAllUpdateStates() { + writeUpdateStates("States/Barbot", BARBOT_STATES); + writeUpdateStates("States/Bellbot", BELLBOT_STATES); + writeUpdateStates("States/Deskbot", DESKBOT_STATES); + writeUpdateStates("States/Doorbot", DOORBOT_STATES); + writeUpdateStates("States/Liftbot", LIFTBOT_STATES); + writeUpdateStates("States/MaitreD", MAITRED_STATES); + +}
\ No newline at end of file diff --git a/devtools/create_titanic/script_states.h b/devtools/create_titanic/script_states.h new file mode 100644 index 0000000000..27dfe22ed4 --- /dev/null +++ b/devtools/create_titanic/script_states.h @@ -0,0 +1,43 @@ +/* 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 COMMON_SCRIPT_STATES_H +#define COMMON_SCRIPT_STATES_H + +#include "common/scummsys.h" + +struct UpdateState12 { + uint _newId; + uint _newValue; + uint _idMatch; +}; + +struct UpdateState8 { + uint _src; + uint _dest; +}; + +extern void writeAllUpdateStates(); +extern void writeEntryHeader(const char *name, uint offset, uint size); +extern uint dataOffset; + +#endif diff --git a/devtools/create_titanic/str.cpp b/devtools/create_titanic/str.cpp new file mode 100644 index 0000000000..6aa66d0d20 --- /dev/null +++ b/devtools/create_titanic/str.cpp @@ -0,0 +1,786 @@ +/* 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/hash-str.h" +#include "common/list.h" +#include "memorypool.h" +#include "common/str.h" +#include "common/util.h" + +namespace Common { + +MemoryPool *g_refCountPool = 0; // FIXME: This is never freed right now + +static uint32 computeCapacity(uint32 len) { + // By default, for the capacity we use the next multiple of 32 + return ((len + 32 - 1) & ~0x1F); +} + +String::String(const char *str) : _size(0), _str(_storage) { + if (str == 0) { + _storage[0] = 0; + _size = 0; + } else + initWithCStr(str, strlen(str)); +} + +String::String(const char *str, uint32 len) : _size(0), _str(_storage) { + initWithCStr(str, len); +} + +String::String(const char *beginP, const char *endP) : _size(0), _str(_storage) { + assert(endP >= beginP); + initWithCStr(beginP, endP - beginP); +} + +void String::initWithCStr(const char *str, uint32 len) { + assert(str); + + // Init _storage member explicitly (ie. without calling its constructor) + // for GCC 2.95.x compatibility (see also tracker item #1602879). + _storage[0] = 0; + + _size = len; + + if (len >= _builtinCapacity) { + // Not enough internal storage, so allocate more + _extern._capacity = computeCapacity(len+1); + _extern._refCount = 0; + _str = new char[_extern._capacity]; + assert(_str != 0); + } + + // Copy the string into the storage area + memmove(_str, str, len); + _str[len] = 0; +} + +String::String(const String &str) + : _size(str._size) { + if (str.isStorageIntern()) { + // String in internal storage: just copy it + memcpy(_storage, str._storage, _builtinCapacity); + _str = _storage; + } else { + // String in external storage: use refcount mechanism + str.incRefCount(); + _extern._refCount = str._extern._refCount; + _extern._capacity = str._extern._capacity; + _str = str._str; + } + assert(_str != 0); +} + +String::String(char c) + : _size(0), _str(_storage) { + + _storage[0] = c; + _storage[1] = 0; + + _size = (c == 0) ? 0 : 1; +} + +String::~String() { + decRefCount(_extern._refCount); +} + +void String::makeUnique() { + ensureCapacity(_size, true); +} + +/** + * Ensure that enough storage is available to store at least new_size + * characters plus a null byte. In addition, if we currently share + * the storage with another string, unshare it, so that we can safely + * write to the storage. + */ +void String::ensureCapacity(uint32 new_size, bool keep_old) { + bool isShared; + uint32 curCapacity, newCapacity; + char *newStorage; + int *oldRefCount = _extern._refCount; + + if (isStorageIntern()) { + isShared = false; + curCapacity = _builtinCapacity; + } else { + isShared = (oldRefCount && *oldRefCount > 1); + curCapacity = _extern._capacity; + } + + // Special case: If there is enough space, and we do not share + // the storage, then there is nothing to do. + if (!isShared && new_size < curCapacity) + return; + + if (isShared && new_size < _builtinCapacity) { + // We share the storage, but there is enough internal storage: Use that. + newStorage = _storage; + newCapacity = _builtinCapacity; + } else { + // We need to allocate storage on the heap! + + // Compute a suitable new capacity limit + // If the current capacity is sufficient we use the same capacity + if (new_size < curCapacity) + newCapacity = curCapacity; + else + newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1)); + + // Allocate new storage + newStorage = new char[newCapacity]; + assert(newStorage); + } + + // Copy old data if needed, elsewise reset the new storage. + if (keep_old) { + assert(_size < newCapacity); + memcpy(newStorage, _str, _size + 1); + } else { + _size = 0; + newStorage[0] = 0; + } + + // Release hold on the old storage ... + decRefCount(oldRefCount); + + // ... in favor of the new storage + _str = newStorage; + + if (!isStorageIntern()) { + // Set the ref count & capacity if we use an external storage. + // It is important to do this *after* copying any old content, + // else we would override data that has not yet been copied! + _extern._refCount = 0; + _extern._capacity = newCapacity; + } +} + +void String::incRefCount() const { + assert(!isStorageIntern()); + if (_extern._refCount == 0) { + if (g_refCountPool == 0) { + g_refCountPool = new MemoryPool(sizeof(int)); + assert(g_refCountPool); + } + + _extern._refCount = (int *)g_refCountPool->allocChunk(); + *_extern._refCount = 2; + } else { + ++(*_extern._refCount); + } +} + +void String::decRefCount(int *oldRefCount) { + if (isStorageIntern()) + return; + + if (oldRefCount) { + --(*oldRefCount); + } + if (!oldRefCount || *oldRefCount <= 0) { + // The ref count reached zero, so we free the string storage + // and the ref count storage. + if (oldRefCount) { + assert(g_refCountPool); + g_refCountPool->freeChunk(oldRefCount); + } + delete[] _str; + + // Even though _str points to a freed memory block now, + // we do not change its value, because any code that calls + // decRefCount will have to do this afterwards anyway. + } +} + +String &String::operator=(const char *str) { + uint32 len = strlen(str); + ensureCapacity(len, false); + _size = len; + memmove(_str, str, len + 1); + return *this; +} + +String &String::operator=(const String &str) { + if (&str == this) + return *this; + + if (str.isStorageIntern()) { + decRefCount(_extern._refCount); + _size = str._size; + _str = _storage; + memcpy(_str, str._str, _size + 1); + } else { + str.incRefCount(); + decRefCount(_extern._refCount); + + _extern._refCount = str._extern._refCount; + _extern._capacity = str._extern._capacity; + _size = str._size; + _str = str._str; + } + + return *this; +} + +String &String::operator=(char c) { + decRefCount(_extern._refCount); + _str = _storage; + + _str[0] = c; + _str[1] = 0; + + _size = (c == 0) ? 0 : 1; + return *this; +} + +String &String::operator+=(const char *str) { + if (_str <= str && str <= _str + _size) + return operator+=(String(str)); + + int len = strlen(str); + if (len > 0) { + ensureCapacity(_size + len, true); + + memcpy(_str + _size, str, len + 1); + _size += len; + } + return *this; +} + +String &String::operator+=(const String &str) { + if (&str == this) + return operator+=(String(str)); + + int len = str._size; + if (len > 0) { + ensureCapacity(_size + len, true); + + memcpy(_str + _size, str._str, len + 1); + _size += len; + } + return *this; +} + +String &String::operator+=(char c) { + ensureCapacity(_size + 1, true); + + _str[_size++] = c; + _str[_size] = 0; + + return *this; +} + +bool String::hasPrefix(const String &x) const { + return hasPrefix(x.c_str()); +} + +bool String::hasPrefix(const char *x) const { + assert(x != 0); + // Compare x with the start of _str. + const char *y = c_str(); + while (*x && *x == *y) { + ++x; + ++y; + } + // It's a prefix, if and only if all letters in x are 'used up' before + // _str ends. + return *x == 0; +} + +bool String::hasSuffix(const String &x) const { + return hasSuffix(x.c_str()); +} + +bool String::hasSuffix(const char *x) const { + assert(x != 0); + // Compare x with the end of _str. + const uint32 x_size = strlen(x); + if (x_size > _size) + return false; + const char *y = c_str() + _size - x_size; + while (*x && *x == *y) { + ++x; + ++y; + } + // It's a suffix, if and only if all letters in x are 'used up' before + // _str ends. + return *x == 0; +} + +bool String::contains(const String &x) const { + return strstr(c_str(), x.c_str()) != NULL; +} + +bool String::contains(const char *x) const { + assert(x != 0); + return strstr(c_str(), x) != NULL; +} + +bool String::contains(char x) const { + return strchr(c_str(), x) != NULL; +} + +void String::deleteLastChar() { + if (_size > 0) + deleteChar(_size - 1); +} + +void String::deleteChar(uint32 p) { + assert(p < _size); + + makeUnique(); + while (p++ < _size) + _str[p - 1] = _str[p]; + _size--; +} + +void String::erase(uint32 p, uint32 len) { + assert(p < _size); + + makeUnique(); + // If len == npos or p + len is over the end, remove all the way to the end + if (len == npos || p + len >= _size) { + // Delete char at p as well. So _size = (p - 1) + 1 + _size = p; + // Null terminate + _str[_size] = 0; + return; + } + + for ( ; p + len <= _size; p++) { + _str[p] = _str[p + len]; + } + _size -= len; +} + +void String::clear() { + decRefCount(_extern._refCount); + + _size = 0; + _str = _storage; + _storage[0] = 0; +} + +void String::setChar(char c, uint32 p) { + assert(p < _size); + + makeUnique(); + _str[p] = c; +} + +void String::insertChar(char c, uint32 p) { + assert(p <= _size); + + ensureCapacity(_size + 1, true); + _size++; + for (uint32 i = _size; i > p; --i) + _str[i] = _str[i - 1]; + _str[p] = c; +} + +void String::toLowercase() { + makeUnique(); + for (uint32 i = 0; i < _size; ++i) + _str[i] = tolower(_str[i]); +} + +void String::toUppercase() { + makeUnique(); + for (uint32 i = 0; i < _size; ++i) + _str[i] = toupper(_str[i]); +} + +uint String::hash() const { + return hashit(c_str()); +} + +// static +String String::format(const char *fmt, ...) { + String output; + + va_list va; + va_start(va, fmt); + output = String::vformat(fmt, va); + va_end(va); + + return output; +} + +// static +String String::vformat(const char *fmt, va_list args) { + String output; + assert(output.isStorageIntern()); + + va_list va; + scumm_va_copy(va, args); + int len = vsnprintf(output._str, _builtinCapacity, fmt, va); + va_end(va); + + if (len == -1 || len == _builtinCapacity - 1) { + // MSVC and IRIX don't return the size the full string would take up. + // MSVC returns -1, IRIX returns the number of characters actually written, + // which is at the most the size of the buffer minus one, as the string is + // truncated to fit. + + // We assume MSVC failed to output the correct, null-terminated string + // if the return value is either -1 or size. + // For IRIX, because we lack a better mechanism, we assume failure + // if the return value equals size - 1. + // The downside to this is that whenever we try to format a string where the + // size is 1 below the built-in capacity, the size is needlessly increased. + + // Try increasing the size of the string until it fits. + int size = _builtinCapacity; + do { + size *= 2; + output.ensureCapacity(size - 1, false); + assert(!output.isStorageIntern()); + size = output._extern._capacity; + + scumm_va_copy(va, args); + len = vsnprintf(output._str, size, fmt, va); + va_end(va); + } while (len == -1 || len >= size - 1); + output._size = len; + } else if (len < (int)_builtinCapacity) { + // vsnprintf succeeded + output._size = len; + } else { + // vsnprintf didn't have enough space, so grow buffer + output.ensureCapacity(len, false); + scumm_va_copy(va, args); + int len2 = vsnprintf(output._str, len+1, fmt, va); + va_end(va); + assert(len == len2); + output._size = len2; + } + + return output; +} + + +#pragma mark - + +bool String::operator==(const String &x) const { + return equals(x); +} + +bool String::operator==(const char *x) const { + assert(x != 0); + return equals(x); +} + +bool String::operator!=(const String &x) const { + return !equals(x); +} + +bool String::operator !=(const char *x) const { + assert(x != 0); + return !equals(x); +} + +bool String::operator<(const String &x) const { + return compareTo(x) < 0; +} + +bool String::operator<=(const String &x) const { + return compareTo(x) <= 0; +} + +bool String::operator>(const String &x) const { + return compareTo(x) > 0; +} + +bool String::operator>=(const String &x) const { + return compareTo(x) >= 0; +} + +#pragma mark - + +bool operator==(const char* y, const String &x) { + return (x == y); +} + +bool operator!=(const char* y, const String &x) { + return x != y; +} + +#pragma mark - + +bool String::equals(const String &x) const { + return (0 == compareTo(x)); +} + +bool String::equals(const char *x) const { + assert(x != 0); + return (0 == compareTo(x)); +} + +bool String::equalsIgnoreCase(const String &x) const { + return (0 == compareToIgnoreCase(x)); +} + +bool String::equalsIgnoreCase(const char *x) const { + assert(x != 0); + return (0 == compareToIgnoreCase(x)); +} + +int String::compareTo(const String &x) const { + return compareTo(x.c_str()); +} + +int String::compareTo(const char *x) const { + assert(x != 0); + return strcmp(c_str(), x); +} + +int String::compareToIgnoreCase(const String &x) const { + return compareToIgnoreCase(x.c_str()); +} + +int String::compareToIgnoreCase(const char *x) const { + assert(x != 0); + return scumm_stricmp(c_str(), x); +} + +#pragma mark - + +String operator+(const String &x, const String &y) { + String temp(x); + temp += y; + return temp; +} + +String operator+(const char *x, const String &y) { + String temp(x); + temp += y; + return temp; +} + +String operator+(const String &x, const char *y) { + String temp(x); + temp += y; + return temp; +} + +String operator+(char x, const String &y) { + String temp(x); + temp += y; + return temp; +} + +String operator+(const String &x, char y) { + String temp(x); + temp += y; + return temp; +} + +String lastPathComponent(const String &path, const char sep) { + const char *str = path.c_str(); + const char *last = str + path.size(); + + // Skip over trailing slashes + while (last > str && *(last-1) == sep) + --last; + + // Path consisted of only slashes -> return empty string + if (last == str) + return String(); + + // Now scan the whole component + const char *first = last - 1; + while (first > str && *first != sep) + --first; + + if (*first == sep) + first++; + + return String(first, last); +} + +String normalizePath(const String &path, const char sep) { + if (path.empty()) + return path; + + const char *cur = path.c_str(); + String result; + + // If there is a leading slash, preserve that: + if (*cur == sep) { + result += sep; + // Skip over multiple leading slashes, so "//" equals "/" + while (*cur == sep) + ++cur; + } + + // Scan for path components till the end of the String + List<String> comps; + while (*cur != 0) { + const char *start = cur; + + // Scan till the next path separator resp. the end of the string + while (*cur != sep && *cur != 0) + cur++; + + const String component(start, cur); + + if (component.empty() || component == ".") { + // Skip empty components and dot components + } else if (!comps.empty() && component == ".." && comps.back() != "..") { + // If stack is non-empty and top is not "..", remove top + comps.pop_back(); + } else { + // Add the component to the stack + comps.push_back(component); + } + + // Skip over separator chars + while (*cur == sep) + cur++; + } + + // Finally, assemble all components back into a path + while (!comps.empty()) { + result += comps.front(); + comps.pop_front(); + if (!comps.empty()) + result += sep; + } + + return result; +} + +size_t strlcpy(char *dst, const char *src, size_t size) { + // Our backup of the source's start, we need this + // to calculate the source's length. + const char * const srcStart = src; + + // In case a non-empty size was specified we + // copy over (size - 1) bytes at max. + if (size != 0) { + // Copy over (size - 1) bytes at max. + while (--size != 0) { + if ((*dst++ = *src) == 0) + break; + ++src; + } + + // In case the source string was longer than the + // destination, we need to add a terminating + // zero. + if (size == 0) + *dst = 0; + } + + // Move to the terminating zero of the source + // string, we need this to determine the length + // of the source string. + while (*src) + ++src; + + // Return the source string's length. + return src - srcStart; +} + +size_t strlcat(char *dst, const char *src, size_t size) { + // In case the destination buffer does not contain + // space for at least 1 character, we will just + // return the source string's length. + if (size == 0) + return strlen(src); + + // Our backup of the source's start, we need this + // to calculate the source's length. + const char * const srcStart = src; + + // Our backup of the destination's start, we need + // this to calculate the destination's length. + const char * const dstStart = dst; + + // Search the end of the destination, but do not + // move past the terminating zero. + while (size-- != 0 && *dst != 0) + ++dst; + + // Calculate the destination's length; + const size_t dstLength = dst - dstStart; + + // In case we reached the end of the destination + // buffer before we had a chance to append any + // characters we will just return the destination + // length plus the source string's length. + if (size == 0) + return dstLength + strlen(srcStart); + + // Copy over all of the source that fits + // the destination buffer. We also need + // to take the terminating zero we will + // add into consideration. + while (size-- != 0 && *src != 0) + *dst++ = *src++; + *dst = 0; + + // Move to the terminating zero of the source + // string, we need this to determine the length + // of the source string. + while (*src) + ++src; + + // Return the total length of the result string + return dstLength + (src - srcStart); +} + +} // End of namespace Common + +// Portable implementation of stricmp / strcasecmp / strcmpi. +// TODO: Rename this to Common::strcasecmp +int scumm_stricmp(const char *s1, const char *s2) { + byte l1, l2; + do { + // Don't use ++ inside tolower, in case the macro uses its + // arguments more than once. + l1 = (byte)*s1++; + l1 = tolower(l1); + l2 = (byte)*s2++; + l2 = tolower(l2); + } while (l1 == l2 && l1 != 0); + return l1 - l2; +} + +// Portable implementation of strnicmp / strncasecmp / strncmpi. +// TODO: Rename this to Common::strncasecmp +int scumm_strnicmp(const char *s1, const char *s2, uint n) { + byte l1, l2; + do { + if (n-- == 0) + return 0; // no difference found so far -> signal equality + + // Don't use ++ inside tolower, in case the macro uses its + // arguments more than once. + l1 = (byte)*s1++; + l1 = tolower(l1); + l2 = (byte)*s2++; + l2 = tolower(l2); + } while (l1 == l2 && l1 != 0); + return l1 - l2; +} diff --git a/devtools/create_titanic/str.h b/devtools/create_titanic/str.h new file mode 100644 index 0000000000..2f954dcfca --- /dev/null +++ b/devtools/create_titanic/str.h @@ -0,0 +1,386 @@ +/* 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 COMMON_STRING_H +#define COMMON_STRING_H + +#include "common/scummsys.h" + +#include <stdarg.h> + +namespace Common { + +/** + * Simple string class for ScummVM. Provides automatic storage managment, + * and overloads several operators in a 'natural' fashion, mimicking + * the std::string class. Even provides simple iterators. + * + * This class tries to avoid allocating lots of small blocks on the heap, + * since that is inefficient on several platforms supported by ScummVM. + * Instead, small strings are stored 'inside' the string object (i.e. on + * the stack, for stack allocated objects), and only for strings exceeding + * a certain length do we allocate a buffer on the heap. + * + * The presence of \0 characters in the string will cause undefined + * behavior in some operations. + */ +class String { +public: + static const uint32 npos = 0xFFFFFFFF; +protected: + /** + * The size of the internal storage. Increasing this means less heap + * allocations are needed, at the cost of more stack memory usage, + * and of course lots of wasted memory. Empirically, 90% or more of + * all String instances are less than 32 chars long. If a platform + * is very short on stack space, it would be possible to lower this. + * A value of 24 still seems acceptable, though considerably worse, + * while 16 seems to be the lowest you want to go... Anything lower + * than 8 makes no sense, since that's the size of member _extern + * (on 32 bit machines; 12 bytes on systems with 64bit pointers). + */ + static const uint32 _builtinCapacity = 32 - sizeof(uint32) - sizeof(char *); + + /** + * Length of the string. Stored to avoid having to call strlen + * a lot. Yes, we limit ourselves to strings shorter than 4GB -- + * on purpose :-). + */ + uint32 _size; + + /** + * Pointer to the actual string storage. Either points to _storage, + * or to a block allocated on the heap via malloc. + */ + char *_str; + + + union { + /** + * Internal string storage. + */ + char _storage[_builtinCapacity]; + /** + * External string storage data -- the refcounter, and the + * capacity of the string _str points to. + */ + struct { + mutable int *_refCount; + uint32 _capacity; + } _extern; + }; + + inline bool isStorageIntern() const { + return _str == _storage; + } + +public: + /** Construct a new empty string. */ + String() : _size(0), _str(_storage) { _storage[0] = 0; } + + /** Construct a new string from the given NULL-terminated C string. */ + String(const char *str); + + /** Construct a new string containing exactly len characters read from address str. */ + String(const char *str, uint32 len); + + /** Construct a new string containing the characters between beginP (including) and endP (excluding). */ + String(const char *beginP, const char *endP); + + /** Construct a copy of the given string. */ + String(const String &str); + + /** Construct a string consisting of the given character. */ + explicit String(char c); + + ~String(); + + String &operator=(const char *str); + String &operator=(const String &str); + String &operator=(char c); + String &operator+=(const char *str); + String &operator+=(const String &str); + String &operator+=(char c); + + bool operator==(const String &x) const; + bool operator==(const char *x) const; + bool operator!=(const String &x) const; + bool operator!=(const char *x) const; + + bool operator<(const String &x) const; + bool operator<=(const String &x) const; + bool operator>(const String &x) const; + bool operator>=(const String &x) const; + + bool equals(const String &x) const; + bool equalsIgnoreCase(const String &x) const; + int compareTo(const String &x) const; // strcmp clone + int compareToIgnoreCase(const String &x) const; // stricmp clone + + bool equals(const char *x) const; + bool equalsIgnoreCase(const char *x) const; + int compareTo(const char *x) const; // strcmp clone + int compareToIgnoreCase(const char *x) const; // stricmp clone + + bool hasSuffix(const String &x) const; + bool hasSuffix(const char *x) const; + + bool hasPrefix(const String &x) const; + bool hasPrefix(const char *x) const; + + bool contains(const String &x) const; + bool contains(const char *x) const; + bool contains(char x) const; + + inline const char *c_str() const { return _str; } + inline uint size() const { return _size; } + + inline bool empty() const { return (_size == 0); } + char firstChar() const { return (_size > 0) ? _str[0] : 0; } + char lastChar() const { return (_size > 0) ? _str[_size - 1] : 0; } + + char operator[](int idx) const { + assert(_str && idx >= 0 && idx < (int)_size); + return _str[idx]; + } + + /** Remove the last character from the string. */ + void deleteLastChar(); + + /** Remove the character at position p from the string. */ + void deleteChar(uint32 p); + + /** Remove all characters from position p to the p + len. If len = String::npos, removes all characters to the end */ + void erase(uint32 p, uint32 len = npos); + + /** Set character c at position p, replacing the previous character there. */ + void setChar(char c, uint32 p); + + /** Insert character c before position p. */ + void insertChar(char c, uint32 p); + + /** Clears the string, making it empty. */ + void clear(); + + /** Convert all characters in the string to lowercase. */ + void toLowercase(); + + /** Convert all characters in the string to uppercase. */ + void toUppercase(); + + /** + * Removes trailing and leading whitespaces. Uses isspace() to decide + * what is whitespace and what not. + */ + void trim(); + + uint hash() const; + + /** + * Print formatted data into a String object. Similar to sprintf, + * except that it stores the result in (variably sized) String + * instead of a fixed size buffer. + */ + static String format(const char *fmt, ...) GCC_PRINTF(1,2); + + /** + * Print formatted data into a String object. Similar to vsprintf, + * except that it stores the result in (variably sized) String + * instead of a fixed size buffer. + */ + static String vformat(const char *fmt, va_list args); + +public: + typedef char value_type; + /** + * Unsigned version of the underlying type. This can be used to cast + * individual string characters to bigger integer types without sign + * extension happening. + */ + typedef unsigned char unsigned_type; + typedef char * iterator; + typedef const char * const_iterator; + + iterator begin() { + // Since the user could potentially + // change the string via the returned + // iterator we have to assure we are + // pointing to a unique storage. + makeUnique(); + + return _str; + } + + iterator end() { + return begin() + size(); + } + + const_iterator begin() const { + return _str; + } + + const_iterator end() const { + return begin() + size(); + } + +protected: + void makeUnique(); + void ensureCapacity(uint32 new_size, bool keep_old); + void incRefCount() const; + void decRefCount(int *oldRefCount); + void initWithCStr(const char *str, uint32 len); +}; + +// Append two strings to form a new (temp) string +String operator+(const String &x, const String &y); + +String operator+(const char *x, const String &y); +String operator+(const String &x, const char *y); + +String operator+(const String &x, char y); +String operator+(char x, const String &y); + +// Some useful additional comparison operators for Strings +bool operator==(const char *x, const String &y); +bool operator!=(const char *x, const String &y); + +// Utility functions to remove leading and trailing whitespaces +extern char *ltrim(char *t); +extern char *rtrim(char *t); +extern char *trim(char *t); + + +/** + * Returns the last component of a given path. + * + * Examples: + * /foo/bar.txt would return 'bar.txt' + * /foo/bar/ would return 'bar' + * /foo/./bar// would return 'bar' + * + * @param path the path of which we want to know the last component + * @param sep character used to separate path components + * @return The last component of the path. + */ +String lastPathComponent(const String &path, const char sep); + +/** + * Normalize a given path to a canonical form. In particular: + * - trailing separators are removed: /foo/bar/ -> /foo/bar + * - double separators (= empty components) are removed: /foo//bar -> /foo/bar + * - dot components are removed: /foo/./bar -> /foo/bar + * + * @todo remove double dot components: /foo/baz/../bar -> /foo/bar + * + * @param path the path to normalize + * @param sep the separator token (usually '/' on Unix-style systems, or '\\' on Windows based stuff) + * @return the normalized path + */ +String normalizePath(const String &path, const char sep); + + +/** + * Simple DOS-style pattern matching function (understands * and ? like used in DOS). + * Taken from exult/files/listfiles.cc + * + * Token meaning: + * "*": any character, any amount of times. + * "?": any character, only once. + * "#": any decimal digit, only once. + * + * Example strings/patterns: + * String: monkey.s01 Pattern: monkey.s?? => true + * String: monkey.s101 Pattern: monkey.s?? => false + * String: monkey.s99 Pattern: monkey.s?1 => false + * String: monkey.s101 Pattern: monkey.s* => true + * String: monkey.s99 Pattern: monkey.s*1 => false + * String: monkey.s01 Pattern: monkey.s## => true + * String: monkey.s01 Pattern: monkey.### => false + * + * @param str Text to be matched against the given pattern. + * @param pat Glob pattern. + * @param ignoreCase Whether to ignore the case when doing pattern match + * @param pathMode Whether to use path mode, i.e., whether slashes must be matched explicitly. + * + * @return true if str matches the pattern, false otherwise. + */ +bool matchString(const char *str, const char *pat, bool ignoreCase = false, bool pathMode = false); + + +/** + * Take a 32 bit value and turn it into a four character string, where each of + * the four bytes is turned into one character. Most significant byte is printed + * first. + */ +String tag2string(uint32 tag); + +/** + * Copy up to size - 1 characters from src to dst and also zero terminate the + * result. Note that src must be a zero terminated string. + * + * In case size is zero this function just returns the length of the source + * string. + * + * @note This is modeled after OpenBSD's strlcpy. See the manpage here: + * http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy + * + * @param dst The destination buffer. + * @param src The source string. + * @param size The size of the destination buffer. + * @return The length of the (non-truncated) result, i.e. strlen(src). + */ +size_t strlcpy(char *dst, const char *src, size_t size); + +/** + * Append the string src to the string dst. Note that both src and dst must be + * zero terminated. The result will be zero terminated. At most + * "size - strlen(dst) - 1" bytes will be appended. + * + * In case the dst string does not contain a zero within the first "size" bytes + * the dst string will not be changed and size + strlen(src) is returned. + * + * @note This is modeled after OpenBSD's strlcat. See the manpage here: + * http://www.openbsd.org/cgi-bin/man.cgi?query=strlcat + * + * @param dst The string the source string should be appended to. + * @param src The source string. + * @param size The (total) size of the destination buffer. + * @return The length of the (non-truncated) result. That is + * strlen(dst) + strlen(src). In case strlen(dst) > size + * size + strlen(src) is returned. + */ +size_t strlcat(char *dst, const char *src, size_t size); + +/** + * Convenience wrapper for tag2string which "returns" a C string. + * Note: It is *NOT* safe to do anything with the return value other than directly + * copying or printing it. + */ +#define tag2str(x) Common::tag2string(x).c_str() + + +} // End of namespace Common + +extern int scumm_stricmp(const char *s1, const char *s2); +extern int scumm_strnicmp(const char *s1, const char *s2, uint n); + +#endif diff --git a/devtools/create_titanic/tag_maps.cpp b/devtools/create_titanic/tag_maps.cpp new file mode 100644 index 0000000000..d3640f8404 --- /dev/null +++ b/devtools/create_titanic/tag_maps.cpp @@ -0,0 +1,391 @@ +/* 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. + * + */ + + // Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +// HACK to allow building with the SDL backend on MinGW +// see bug #1800764 "TOOLS: MinGW tools building broken" +#ifdef main +#undef main +#endif // main + +#include "file.h" +#include "tag_maps.h" + +#define BARBOT_COUNT 250 +static const TagMapping BARBOT_MAP[250] = { + { 0x46cd0, 0x3d21e }, { 0x46ce2, 0x3d23b }, { 0x46ced, 0x3d246 }, + { 0x46cf8, 0x3d251 }, { 0x46d03, 0x3d25c }, { 0x46d0e, 0x3d267 }, + { 0x46d19, 0x3d272 }, { 0x46d24, 0x3d27d }, { 0x46d2f, 0x3d288 }, + { 0x46cd1, 0x3d21f }, { 0x46cd9, 0x3d22a }, { 0x46cda, 0x3d233 }, + { 0x46cdb, 0x3d234 }, { 0x46cdc, 0x3d235 }, { 0x46cdd, 0x3d236 }, + { 0x46cde, 0x3d237 }, { 0x46cdf, 0x3d238 }, { 0x46ce0, 0x3d239 }, + { 0x46ce1, 0x3d23a }, { 0x46ce3, 0x3d23c }, { 0x46ce4, 0x3d23d }, + { 0x46ce5, 0x3d23e }, { 0x46ce6, 0x3d23f }, { 0x46ce7, 0x3d240 }, + { 0x46ce8, 0x3d241 }, { 0x46ce9, 0x3d242 }, { 0x46cea, 0x3d243 }, + { 0x46ceb, 0x3d244 }, { 0x46cec, 0x3d245 }, { 0x46cee, 0x3d26b }, + { 0x46cef, 0x3d247 }, { 0x46cf0, 0x3d248 }, { 0x46cf1, 0x3d249 }, + { 0x46cf2, 0x3d24a }, { 0x46cf3, 0x3d24b }, { 0x46cf4, 0x3d24c }, + { 0x46cf5, 0x3d24d }, { 0x46cf6, 0x3d24e }, { 0x46cf7, 0x3d24f }, + { 0x46cf9, 0x3d250 }, { 0x46cfa, 0x3d252 }, { 0x46cfb, 0x3d253 }, + { 0x46cfc, 0x3d254 }, { 0x46cfd, 0x3d255 }, { 0x46cfe, 0x3d256 }, + { 0x46cff, 0x3d257 }, { 0x46d00, 0x3d258 }, { 0x46d01, 0x3d259 }, + { 0x46d02, 0x3d25a }, { 0x46d04, 0x3d25b }, { 0x46d05, 0x3d25d }, + { 0x46d06, 0x3d25e }, { 0x46d07, 0x3d25f }, { 0x46d08, 0x3d260 }, + { 0x46d09, 0x3d26f }, { 0x46d0a, 0x3d270 }, { 0x46d0b, 0x3d271 }, + { 0x46d0c, 0x3d273 }, { 0x46d0d, 0x3d274 }, { 0x46d0f, 0x3d275 }, + { 0x46d10, 0x3d276 }, { 0x46d11, 0x3d277 }, { 0x46d12, 0x3d278 }, + { 0x46d13, 0x3d279 }, { 0x46d14, 0x3d27a }, { 0x46d15, 0x3d27b }, + { 0x46d16, 0x3d27c }, { 0x46d17, 0x3d27e }, { 0x46d18, 0x3d27f }, + { 0x46d1a, 0x3d280 }, { 0x46d1b, 0x3d281 }, { 0x46d1c, 0x3d282 }, + { 0x46d1d, 0x3d283 }, { 0x46d1e, 0x3d284 }, { 0x46d1f, 0x3d285 }, + { 0x46d20, 0x3d286 }, { 0x46d21, 0x3d287 }, { 0x46d22, 0x3d289 }, + { 0x46d23, 0x3d28a }, { 0x46d25, 0x3d28b }, { 0x46d26, 0x3d28c }, + { 0x46d27, 0x3d28d }, { 0x46d28, 0x3d28e }, { 0x46d29, 0x3d28f }, + { 0x46d2a, 0x3d290 }, { 0x46d2b, 0x3d291 }, { 0x46d2c, 0x3d292 }, + { 0x46d2d, 0x3d220 }, { 0x46d2e, 0x3d221 }, { 0x46d30, 0x3d222 }, + { 0x46d31, 0x3d223 }, { 0x46d32, 0x3d224 }, { 0x46d33, 0x3d225 }, + { 0x46d34, 0x3d226 }, { 0x46d35, 0x3d227 }, { 0x46d36, 0x3d228 }, + { 0x46d37, 0x3d229 }, { 0x46d38, 0x3d22b }, { 0x46d39, 0x3d22c }, + { 0x46cd2, 0x3d22d }, { 0x46cd3, 0x3d22e }, { 0x46cd5, 0x3d22f }, + { 0x46cd6, 0x3d230 }, { 0x46cd7, 0x3d231 }, { 0x46cd8, 0x3d232 }, + { 0x46d3a, 0x3d768 }, { 0x46d3b, 0x3d372 }, { 0x46d47, 0x3d43c }, + { 0x46d48, 0x3d7ce }, { 0x46d49, 0x3d7cf }, { 0x46d4a, 0x3d6f1 }, + { 0x46d4b, 0x3d77c }, { 0x46d4c, 0x3d49d }, { 0x46d4d, 0x3d77c }, + { 0x46d4e, 0x3d0b5 }, { 0x46d4f, 0x3d177 }, { 0x46d50, 0x3d2d7 }, + { 0x46d51, 0x3d77c }, { 0x46d52, 0x3d77c }, { 0x46d53, 0x3d30b }, + { 0x46d55, 0x3d706 }, { 0x46d56, 0x3d704 }, { 0x46d57, 0x3d77c }, + { 0x46d54, 0x3d0a0 }, { 0x46d58, 0x3d722 }, { 0x46d5a, 0x3d44a }, + { 0x46d5b, 0x3d452 }, { 0x46d5c, 0x3d469 }, { 0x46d5d, 0x3d475 }, + { 0x46d5e, 0x3d476 }, { 0x46d5f, 0x3d477 }, { 0x46d60, 0x3d478 }, + { 0x46d61, 0x3d479 }, { 0x46d62, 0x3d47a }, { 0x46d63, 0x3d44b }, + { 0x46d64, 0x3d44c }, { 0x46d65, 0x3d44d }, { 0x46d66, 0x3d44e }, + { 0x46d67, 0x3d44f }, { 0x46d68, 0x3d450 }, { 0x46d69, 0x3d451 }, + { 0x46d6a, 0x3d453 }, { 0x46d6b, 0x3d460 }, { 0x46d6c, 0x3d462 }, + { 0x46d6d, 0x3d463 }, { 0x46d6e, 0x3d464 }, { 0x46d6f, 0x3d465 }, + { 0x46d70, 0x3d466 }, { 0x46d71, 0x3d467 }, { 0x46d72, 0x3d468 }, + { 0x46d73, 0x3d454 }, { 0x46d74, 0x3d455 }, { 0x46d75, 0x3d456 }, + { 0x46d76, 0x3d457 }, { 0x46d77, 0x3d458 }, { 0x46d78, 0x3d459 }, + { 0x46d79, 0x3d45a }, { 0x46d7a, 0x3d45b }, { 0x46d7b, 0x3d45c }, + { 0x46d7c, 0x3d45f }, { 0x46d7d, 0x3d461 }, { 0x46d7e, 0x3d46a }, + { 0x46d7f, 0x3d46d }, { 0x46d80, 0x3d46e }, { 0x46d81, 0x3d46f }, + { 0x46d82, 0x3d470 }, { 0x46d83, 0x3d471 }, { 0x46d84, 0x3d472 }, + { 0x46d85, 0x3d473 }, { 0x46d86, 0x3d474 }, { 0x46d87, 0x3d46b }, + { 0x46d88, 0x3d75d }, { 0x46d89, 0x3d75e }, { 0x46d8a, 0x3d75f }, + { 0x46d8b, 0x3d760 }, { 0x46d8c, 0x3d761 }, { 0x46d8d, 0x3d762 }, + { 0x46d8e, 0x3d763 }, { 0x46d8f, 0x3d766 }, { 0x46d90, 0x3d767 }, + { 0x46d91, 0x3d77c }, { 0x46d92, 0x3d768 }, { 0x46d93, 0x3d765 }, + { 0x46d94, 0x3d769 }, { 0x46d95, 0x3d770 }, { 0x46d96, 0x3d775 }, + { 0x46d97, 0x3d776 }, { 0x46d98, 0x3d777 }, { 0x46d99, 0x3d778 }, + { 0x46d9a, 0x3d779 }, { 0x46d9b, 0x3d77a }, { 0x46d9c, 0x3d77b }, + { 0x46d9d, 0x3d764 }, { 0x46d9e, 0x3d739 }, { 0x46d9f, 0x3d73a }, + { 0x46da0, 0x3d73b }, { 0x46da1, 0x3d73c }, { 0x46da2, 0x3d73d }, + { 0x46da3, 0x3d73e }, { 0x46da4, 0x3d742 }, { 0x46da5, 0x3d744 }, + { 0x46da6, 0x3d743 }, { 0x46da7, 0x3d745 }, { 0x46da8, 0x3d741 }, + { 0x46da9, 0x3d746 }, { 0x46daa, 0x3d747 }, { 0x46dab, 0x3d748 }, + { 0x46dac, 0x3d749 }, { 0x46dad, 0x3d74a }, { 0x46dae, 0x3d74b }, + { 0x46daf, 0x3d73f }, { 0x46db0, 0x3d771 }, { 0x46db1, 0x3d74c }, + { 0x46db2, 0x3d74d }, { 0x46db3, 0x3d74e }, { 0x46db4, 0x3d74f }, + { 0x46db5, 0x3d750 }, { 0x46db6, 0x3d751 }, { 0x46db7, 0x3d753 }, + { 0x46db8, 0x3d755 }, { 0x46db9, 0x3d754 }, { 0x46dba, 0x3d756 }, + { 0x46dbb, 0x3d752 }, { 0x46dbc, 0x3d757 }, { 0x46dbd, 0x3d758 }, + { 0x46dbe, 0x3d759 }, { 0x46dbf, 0x3d75a }, { 0x46dc0, 0x3d75b }, + { 0x46dc1, 0x3d75c }, { 0x46dc2, 0x3d4a7 }, { 0x46dc3, 0x3d2bf }, + { 0x46dc4, 0x3d6fa }, { 0x46dc5, 0x3d6f9 }, { 0x46dc6, 0x3d6fb }, + { 0x46dc7, 0x3d6f5 }, { 0x46dc8, 0x3d6fc }, { 0x46dc9, 0x3d6ff }, + { 0x46dca, 0x3d2ab }, { 0x46dcb, 0x3d715 }, { 0x46dcc, 0x3d710 }, + { 0x46dcd, 0x3d70c }, { 0x46dce, 0x3d712 }, { 0x46dcf, 0x3d70f }, + { 0x46dd0, 0x3d717 }, { 0x46dd1, 0x3d716 }, { 0x46dd2, 0x3d285 }, + { 0x46dd3, 0x3d269 }, { 0x46dd4, 0x3d2f8 }, { 0x46dd5, 0x0c421 }, + { 0x46dd6, 0x0c3fc } +}; + +#define BELLBOT_COUNT 108 +static const TagMapping BELLBOT_MAP[108] = { + { 0x46cd0, 0x31331 }, { 0x46ce2, 0x31332 }, { 0x46ced, 0x31333 }, + { 0x46cf8, 0x31334 }, { 0x46d03, 0x31335 }, { 0x46d0e, 0x31336 }, + { 0x46d19, 0x31337 }, { 0x46d24, 0x31338 }, { 0x46d2f, 0x31339 }, + { 0x46cd1, 0x3133a }, { 0x46cd9, 0x3133b }, { 0x46cda, 0x3133c }, + { 0x46cdb, 0x3133d }, { 0x46cdc, 0x3133e }, { 0x46cdd, 0x3133f }, + { 0x46cde, 0x31340 }, { 0x46cdf, 0x31341 }, { 0x46ce0, 0x31342 }, + { 0x46ce1, 0x31343 }, { 0x46ce3, 0x31344 }, { 0x46ce4, 0x31345 }, + { 0x46ce5, 0x31346 }, { 0x46ce6, 0x31347 }, { 0x46ce7, 0x31348 }, + { 0x46ce8, 0x31349 }, { 0x46ce9, 0x3134a }, { 0x46cea, 0x3134b }, + { 0x46ceb, 0x3134c }, { 0x46cec, 0x3134d }, { 0x46cee, 0x3134e }, + { 0x46cef, 0x3134f }, { 0x46cf0, 0x31350 }, { 0x46cf1, 0x31351 }, + { 0x46cf2, 0x31352 }, { 0x46cf3, 0x31353 }, { 0x46cf4, 0x31354 }, + { 0x46cf5, 0x31355 }, { 0x46cf6, 0x31356 }, { 0x46cf7, 0x31357 }, + { 0x46cf9, 0x31358 }, { 0x46cfa, 0x31359 }, { 0x46cfb, 0x3135a }, + { 0x46cfc, 0x3135b }, { 0x46cfd, 0x3135c }, { 0x46cfe, 0x3135d }, + { 0x46cff, 0x3135e }, { 0x46d00, 0x3135f }, { 0x46d01, 0x31360 }, + { 0x46d02, 0x31361 }, { 0x46d04, 0x31362 }, { 0x46d05, 0x31363 }, + { 0x46d06, 0x31364 }, { 0x46d07, 0x31365 }, { 0x46d08, 0x31366 }, + { 0x46d09, 0x31367 }, { 0x46d0a, 0x31368 }, { 0x46d0b, 0x31369 }, + { 0x46d0c, 0x3136a }, { 0x46d0d, 0x3136b }, { 0x46d0f, 0x3136c }, + { 0x46d10, 0x3136d }, { 0x46d11, 0x3136e }, { 0x46d12, 0x3136f }, + { 0x46d13, 0x31370 }, { 0x46d14, 0x31371 }, { 0x46d15, 0x31372 }, + { 0x46d16, 0x31373 }, { 0x46d17, 0x31374 }, { 0x46d18, 0x31375 }, + { 0x46d1a, 0x31376 }, { 0x46d1b, 0x31377 }, { 0x46d1c, 0x31378 }, + { 0x46d1d, 0x31379 }, { 0x46d1e, 0x3137a }, { 0x46d1f, 0x3137b }, + { 0x46d20, 0x3137c }, { 0x46d21, 0x3137d }, { 0x46d22, 0x3137e }, + { 0x46d23, 0x3137f }, { 0x46d25, 0x31380 }, { 0x46d26, 0x31381 }, + { 0x46d27, 0x31382 }, { 0x46d28, 0x31383 }, { 0x46d29, 0x31384 }, + { 0x46d2a, 0x31385 }, { 0x46d2b, 0x31386 }, { 0x46d2c, 0x31387 }, + { 0x46d2d, 0x31388 }, { 0x46d2e, 0x31389 }, { 0x46d30, 0x3138a }, + { 0x46d31, 0x3138b }, { 0x46d32, 0x3138c }, { 0x46d33, 0x3138d }, + { 0x46d34, 0x3138e }, { 0x46d35, 0x3138f }, { 0x46d36, 0x31390 }, + { 0x46d37, 0x31391 }, { 0x46d38, 0x31392 }, { 0x46d39, 0x31393 }, + { 0x46cd2, 0x31394 }, { 0x46cd3, 0x31395 }, { 0x46cd4, 0x31396 }, + { 0x46cd5, 0x31397 }, { 0x46cd6, 0x31398 }, { 0x46cd7, 0x31399 }, + { 0x46cd8, 0x3139a }, { 0x46d3b, 0x313d7 }, { 0x46d58, 0x313d6 } +}; + +#define DESKBOT_COUNT 108 +static const TagMapping DESKBOT_MAP[108] = { + { 0x46cd0, 0x3ac00 }, { 0x46ce2, 0x3ac10 }, { 0x46ced, 0x3ac1b }, + { 0x46cf8, 0x3ac26 }, { 0x46d03, 0x3ac31 }, { 0x46d0e, 0x3ac3b }, + { 0x46d19, 0x3ac46 }, { 0x46d24, 0x3ac51 }, { 0x46d2f, 0x3ac5c }, + { 0x46cd1, 0x3ac01 }, { 0x46cd9, 0x3ac07 }, { 0x46cda, 0x3ac08 }, + { 0x46cdb, 0x3ac09 }, { 0x46cdc, 0x3ac0a }, { 0x46cdd, 0x3ac0b }, + { 0x46cde, 0x3ac0c }, { 0x46cdf, 0x3ac0d }, { 0x46ce0, 0x3ac0e }, + { 0x46ce1, 0x3ac0f }, { 0x46ce3, 0x3ac11 }, { 0x46ce4, 0x3ac12 }, + { 0x46ce5, 0x3ac13 }, { 0x46ce6, 0x3ac15 }, { 0x46ce7, 0x3ac16 }, + { 0x46ce8, 0x3ac17 }, { 0x46ce9, 0x3ac18 }, { 0x46cea, 0x3ac19 }, + { 0x46ceb, 0x3ac1a }, { 0x46cec, 0x3ac1c }, { 0x46cee, 0x3abf2 }, + { 0x46cef, 0x3ac1d }, { 0x46cf0, 0x3ac1e }, { 0x46cf1, 0x3ac1f }, + { 0x46cf2, 0x3ac20 }, { 0x46cf3, 0x3ac21 }, { 0x46cf4, 0x3ac22 }, + { 0x46cf5, 0x3ac23 }, { 0x46cf6, 0x3ac24 }, { 0x46cf7, 0x3ac25 }, + { 0x46cf9, 0x3ac27 }, { 0x46cfa, 0x3ac28 }, { 0x46cfb, 0x3ac29 }, + { 0x46cfc, 0x3ac2a }, { 0x46cfd, 0x3ac2b }, { 0x46cfe, 0x3ac2c }, + { 0x46cff, 0x3ac2d }, { 0x46d00, 0x3ac2e }, { 0x46d01, 0x3ac2f }, + { 0x46d02, 0x3ac30 }, { 0x46d04, 0x3ac32 }, { 0x46d05, 0x3ac33 }, + { 0x46d06, 0x3ac34 }, { 0x46d07, 0x3ac35 }, { 0x46d08, 0x3ac36 }, + { 0x46d09, 0x3acd2 }, { 0x46d0a, 0x3ac37 }, { 0x46d0b, 0x3ac38 }, + { 0x46d0c, 0x3ac39 }, { 0x46d0d, 0x3ac3a }, { 0x46d0f, 0x3ac3c }, + { 0x46d10, 0x3ac3d }, { 0x46d11, 0x3ac3e }, { 0x46d12, 0x3ac3f }, + { 0x46d13, 0x3ac40 }, { 0x46d14, 0x3ac41 }, { 0x46d15, 0x3ac42 }, + { 0x46d16, 0x3ac43 }, { 0x46d17, 0x3ac44 }, { 0x46d18, 0x3ac45 }, + { 0x46d1a, 0x3ac47 }, { 0x46d1b, 0x3ac48 }, { 0x46d1c, 0x3ac49 }, + { 0x46d1d, 0x3ac4a }, { 0x46d1e, 0x3ac4b }, { 0x46d1f, 0x3ac4c }, + { 0x46d20, 0x3ac4d }, { 0x46d21, 0x3ac4e }, { 0x46d22, 0x3ac4f }, + { 0x46d23, 0x3ac50 }, { 0x46d25, 0x3ac52 }, { 0x46d26, 0x3ac53 }, + { 0x46d27, 0x3ac54 }, { 0x46d28, 0x3ac55 }, { 0x46d29, 0x3ac56 }, + { 0x46d2a, 0x3ac57 }, { 0x46d2b, 0x3ac58 }, { 0x46d2c, 0x3ac59 }, + { 0x46d2d, 0x3ac5a }, { 0x46d2e, 0x3ac5b }, { 0x46d30, 0x3ac5d }, + { 0x46d31, 0x3ac5e }, { 0x46d32, 0x3ac5f }, { 0x46d33, 0x3ac60 }, + { 0x46d34, 0x3ac61 }, { 0x46d35, 0x3ac62 }, { 0x46d36, 0x3ac63 }, + { 0x46d37, 0x3ac64 }, { 0x46d38, 0x3ac65 }, { 0x46d39, 0x3ac66 }, + { 0x46cd2, 0x3ac02 }, { 0x46cd3, 0x3ac03 }, { 0x46cd4, 0x3ac04 }, + { 0x46cd5, 0x3ac05 }, { 0x46cd6, 0x3ac06 }, { 0x46d3b, 0x3ae27 }, + { 0x46d58, 0x3ae0e }, { 0x46dd2, 0x3aebc }, { 0x46dd6, 0x3aebd } +}; + +#define DOORBOT_COUNT 240 +static const TagMapping DOORBOT_MAP[240] = { + { 0x46cd1, 0x35ee6 }, { 0x46cd2, 0x35ee7 }, { 0x46cd3, 0x35ee8 }, + { 0x46cd4, 0x35ee9 }, { 0x46cd5, 0x35eea }, { 0x46cd6, 0x35eeb }, + { 0x46cd7, 0x35eec }, { 0x46cd8, 0x35eed }, { 0x46cd9, 0x35eee }, + { 0x46cda, 0x35eef }, { 0x46cdb, 0x35ef0 }, { 0x46cdc, 0x35ef1 }, + { 0x46cdd, 0x35ef2 }, { 0x46cde, 0x35ef3 }, { 0x46cdf, 0x35ef4 }, + { 0x46ce0, 0x35ef5 }, { 0x46ce1, 0x35ef6 }, { 0x46ce2, 0x35ef7 }, + { 0x46ce3, 0x35ef8 }, { 0x46ce4, 0x35ef9 }, { 0x46ce5, 0x35efa }, + { 0x46ce6, 0x35efb }, { 0x46ce7, 0x35efc }, { 0x46ce8, 0x35efd }, + { 0x46ce9, 0x35efe }, { 0x46cea, 0x35eff }, { 0x46ceb, 0x35f00 }, + { 0x46cec, 0x35f01 }, { 0x46ced, 0x35f02 }, { 0x46cee, 0x35f03 }, + { 0x46cef, 0x35f04 }, { 0x46cf0, 0x35f05 }, { 0x46cf1, 0x35f06 }, + { 0x46cf2, 0x35f07 }, { 0x46cf3, 0x35f08 }, { 0x46cf4, 0x35f09 }, + { 0x46cf5, 0x35f0a }, { 0x46cf6, 0x35f0b }, { 0x46cf7, 0x35f0c }, + { 0x46cf8, 0x35f0d }, { 0x46cf9, 0x35f0e }, { 0x46cfa, 0x35f0f }, + { 0x46cfb, 0x35f10 }, { 0x46cfc, 0x35f11 }, { 0x46cfd, 0x35f12 }, + { 0x46cfe, 0x35f13 }, { 0x46cff, 0x35f14 }, { 0x46d00, 0x35f15 }, + { 0x46d01, 0x35f16 }, { 0x46d02, 0x35f17 }, { 0x46d03, 0x35f18 }, + { 0x46d04, 0x35f19 }, { 0x46d05, 0x35f1a }, { 0x46d06, 0x35f1b }, + { 0x46d07, 0x35f1c }, { 0x46d08, 0x35f1d }, { 0x46d09, 0x35f1e }, + { 0x46d0a, 0x35f1f }, { 0x46d0b, 0x35f20 }, { 0x46d0c, 0x35f21 }, + { 0x46d0d, 0x35f22 }, { 0x46d0e, 0x35f23 }, { 0x46d0f, 0x35f24 }, + { 0x46d10, 0x35f25 }, { 0x46d11, 0x35f26 }, { 0x46d12, 0x35f27 }, + { 0x46d13, 0x35f28 }, { 0x46d14, 0x35f29 }, { 0x46d15, 0x35f2a }, + { 0x46d16, 0x35f2b }, { 0x46d17, 0x35f2c }, { 0x46d18, 0x35f2d }, + { 0x46d19, 0x35f2e }, { 0x46d1a, 0x35f2f }, { 0x46d1b, 0x35f30 }, + { 0x46d1c, 0x35f31 }, { 0x46d1d, 0x35f32 }, { 0x46d1e, 0x35f33 }, + { 0x46d1f, 0x35f34 }, { 0x46d20, 0x35f35 }, { 0x46d21, 0x35f36 }, + { 0x46d22, 0x35f37 }, { 0x46d23, 0x35f38 }, { 0x46d24, 0x35f39 }, + { 0x46d25, 0x35f3a }, { 0x46d26, 0x35f3b }, { 0x46d27, 0x35f3c }, + { 0x46d28, 0x35f3d }, { 0x46d29, 0x35f3e }, { 0x46d2a, 0x35f3f }, + { 0x46d2b, 0x35f40 }, { 0x46d2c, 0x35f41 }, { 0x46d2d, 0x35f42 }, + { 0x46d2e, 0x35f43 }, { 0x46d2f, 0x35f44 }, { 0x46d30, 0x35f45 }, + { 0x46d31, 0x35f46 }, { 0x46d32, 0x35f47 }, { 0x46d33, 0x35f48 }, + { 0x46d34, 0x35f49 }, { 0x46d35, 0x35f4a }, { 0x46d36, 0x35f4b }, + { 0x46d37, 0x35f4c }, { 0x46d38, 0x35f4d }, { 0x46d39, 0x35f4e }, + { 0x46d3a, 0x35bf5 }, { 0x46d3b, 0x360c0 }, { 0x46d3d, 0x36027 }, + { 0x46d3e, 0x36028 }, { 0x46d3f, 0x36029 }, { 0x46d40, 0x3602a }, + { 0x46d41, 0x3602e }, { 0x46d42, 0x3602f }, { 0x46d43, 0x36030 }, + { 0x46d44, 0x36031 }, { 0x46d45, 0x3602c }, { 0x46d46, 0x3602d }, + { 0x46d47, 0x36227 }, { 0x46d48, 0x36084 }, { 0x46d49, 0x36085 }, + { 0x46d4a, 0x36467 }, { 0x46d4b, 0x36457 }, { 0x46d4c, 0x36457 }, + { 0x46d4d, 0x36457 }, { 0x46d4e, 0x3646d }, { 0x46d4f, 0x36457 }, + { 0x46d50, 0x36470 }, { 0x46d51, 0x36457 }, { 0x46d52, 0x36457 }, + { 0x46d53, 0x36457 }, { 0x46d55, 0x360a3 }, { 0x46d56, 0x3634c }, + { 0x46d57, 0x36457 }, { 0x46d54, 0x36457 }, { 0x46d58, 0x360bf }, + { 0x46d5a, 0x36407 }, { 0x46d5b, 0x3640c }, { 0x46d5c, 0x3641a }, + { 0x46d5d, 0x36420 }, { 0x46d5e, 0x36421 }, { 0x46d5f, 0x36422 }, + { 0x46d60, 0x36423 }, { 0x46d61, 0x36424 }, { 0x46d66, 0x36408 }, + { 0x46d67, 0x36409 }, { 0x46d68, 0x3640a }, { 0x46d69, 0x3640b }, + { 0x46d6a, 0x3640d }, { 0x46d6e, 0x36415 }, { 0x46d6f, 0x36416 }, + { 0x46d70, 0x36417 }, { 0x46d71, 0x36418 }, { 0x46d72, 0x36419 }, + { 0x46d73, 0x3640e }, { 0x46d74, 0x3640f }, { 0x46d75, 0x36410 }, + { 0x46d76, 0x36411 }, { 0x46d77, 0x36412 }, { 0x46d7e, 0x3641b }, + { 0x46d7f, 0x3641c }, { 0x46d80, 0x3641d }, { 0x46d81, 0x3641e }, + { 0x46d82, 0x3641f }, { 0x46d88, 0x362d4 }, { 0x46d89, 0x362db }, + { 0x46d8a, 0x362e2 }, { 0x46d8b, 0x362e3 }, { 0x46d8c, 0x362e7 }, + { 0x46d8d, 0x362eb }, { 0x46d8e, 0x362f2 }, { 0x46d8f, 0x362f5 }, + { 0x46d90, 0x36305 }, { 0x46d91, 0x36457 }, { 0x46d92, 0x36309 }, + { 0x46d93, 0x362f4 }, { 0x46d94, 0x3630a }, { 0x46d96, 0x36318 }, + { 0x46d97, 0x36319 }, { 0x46d98, 0x36326 }, { 0x46d99, 0x36327 }, + { 0x46d9a, 0x3632e }, { 0x46d9b, 0x3632f }, { 0x46d9c, 0x36330 }, + { 0x46d9d, 0x362f3 }, { 0x46d9e, 0x362b0 }, { 0x46d9f, 0x362b1 }, + { 0x46da0, 0x362b2 }, { 0x46da1, 0x362b3 }, { 0x46da2, 0x362b4 }, + { 0x46da3, 0x362b5 }, { 0x46da4, 0x362b9 }, { 0x46da5, 0x362bb }, + { 0x46da6, 0x362ba }, { 0x46da7, 0x362bc }, { 0x46da8, 0x362b8 }, + { 0x46da9, 0x362bd }, { 0x46daa, 0x362be }, { 0x46dab, 0x362bf }, + { 0x46dac, 0x362c0 }, { 0x46dad, 0x362c1 }, { 0x46dae, 0x362c2 }, + { 0x46daf, 0x362b6 }, { 0x46db0, 0x36314 }, { 0x46db1, 0x362c3 }, + { 0x46db2, 0x362c4 }, { 0x46db3, 0x362c5 }, { 0x46db4, 0x362c6 }, + { 0x46db5, 0x362c7 }, { 0x46db6, 0x362c8 }, { 0x46db7, 0x362ca }, + { 0x46db8, 0x362cc }, { 0x46db9, 0x362cb }, { 0x46dba, 0x362cd }, + { 0x46dbb, 0x362c9 }, { 0x46dbc, 0x362ce }, { 0x46dbd, 0x362cf }, + { 0x46dbe, 0x362d0 }, { 0x46dbf, 0x362d1 }, { 0x46dc0, 0x362d2 }, + { 0x46dc1, 0x362d3 }, { 0x46dc2, 0x3637c }, { 0x46dc3, 0x3627c }, + { 0x46dc4, 0x36497 }, { 0x46dc5, 0x36493 }, { 0x46dc6, 0x3647f }, + { 0x46dc7, 0x3647c }, { 0x46dc8, 0x36482 }, { 0x46dc9, 0x3648a }, + { 0x46dca, 0x3649b }, { 0x46dcb, 0x364b6 }, { 0x46dcc, 0x364aa }, + { 0x46dcd, 0x364a1 }, { 0x46dce, 0x364b0 }, { 0x46dcf, 0x364a7 }, + { 0x46dd1, 0x364b9 }, { 0x46dd2, 0x36370 }, { 0x46dd3, 0x363ab }, + { 0x46dd4, 0x36404 }, { 0x46dd5, 0x362ab }, { 0x46dd6, 0x3636d } +}; + +#define LIFTBOT_COUNT 118 +static const TagMapping LIFTBOT_MAP[118] = { + { 0x46cd1, 0x335b5 }, { 0x46cd2, 0x33603 }, { 0x46cd3, 0x33604 }, + { 0x46cd4, 0x33605 }, { 0x46cd5, 0x33606 }, { 0x46cd6, 0x33607 }, + { 0x46cd7, 0x33608 }, { 0x46cd8, 0x33607 }, { 0x46cd9, 0x335b6 }, + { 0x46cda, 0x335b7 }, { 0x46cdb, 0x335b8 }, { 0x46cdc, 0x335b9 }, + { 0x46cdd, 0x335ba }, { 0x46cde, 0x335bb }, { 0x46cdf, 0x335bc }, + { 0x46ce0, 0x335bd }, { 0x46ce1, 0x335bf }, { 0x46ce2, 0x335ac }, + { 0x46ce3, 0x335c0 }, { 0x46ce4, 0x335c1 }, { 0x46ce5, 0x335c2 }, + { 0x46ce6, 0x335c4 }, { 0x46ce7, 0x335c5 }, { 0x46ce8, 0x335c6 }, + { 0x46ce9, 0x335c7 }, { 0x46cea, 0x335c8 }, { 0x46ceb, 0x335ca }, + { 0x46cec, 0x335cb }, { 0x46ced, 0x335ad }, { 0x46cee, 0x335cc }, + { 0x46cef, 0x335ce }, { 0x46cf0, 0x335d0 }, { 0x46cf1, 0x335d1 }, + { 0x46cf2, 0x335d2 }, { 0x46cf3, 0x335d4 }, { 0x46cf4, 0x335d5 }, + { 0x46cf5, 0x335d6 }, { 0x46cf6, 0x335d7 }, { 0x46cf7, 0x335d8 }, + { 0x46cf8, 0x335ae }, { 0x46cf9, 0x335d9 }, { 0x46cfa, 0x335db }, + { 0x46cfb, 0x335de }, { 0x46cfc, 0x335df }, { 0x46cfd, 0x335e0 }, + { 0x46cfe, 0x335e1 }, { 0x46cff, 0x335e2 }, { 0x46d00, 0x335e3 }, + { 0x46d01, 0x335e4 }, { 0x46d02, 0x335e5 }, { 0x46d03, 0x335af }, + { 0x46d04, 0x335e6 }, { 0x46d05, 0x335e7 }, { 0x46d06, 0x335ea }, + { 0x46d07, 0x335eb }, { 0x46d08, 0x335ec }, { 0x46d09, 0x3364a }, + { 0x46d0a, 0x3364b }, { 0x46d0b, 0x3364c }, { 0x46d0c, 0x3364d }, + { 0x46d0d, 0x3364e }, { 0x46d0e, 0x335b0 }, { 0x46d0f, 0x33650 }, + { 0x46d10, 0x33651 }, { 0x46d11, 0x33652 }, { 0x46d12, 0x33653 }, + { 0x46d13, 0x33654 }, { 0x46d14, 0x33656 }, { 0x46d15, 0x33657 }, + { 0x46d16, 0x33658 }, { 0x46d17, 0x33659 }, { 0x46d18, 0x3365b }, + { 0x46d19, 0x335b1 }, { 0x46d1a, 0x3365c }, { 0x46d1b, 0x3365d }, + { 0x46d1c, 0x3365e }, { 0x46d1d, 0x3365f }, { 0x46d1e, 0x33660 }, + { 0x46d1f, 0x33661 }, { 0x46d20, 0x33662 }, { 0x46d21, 0x33663 }, + { 0x46d22, 0x335a9 }, { 0x46d23, 0x335aa }, { 0x46d24, 0x335b2 }, + { 0x46d25, 0x335ed }, { 0x46d26, 0x335ee }, { 0x46d27, 0x335ef }, + { 0x46d28, 0x335f0 }, { 0x46d29, 0x335f1 }, { 0x46d2a, 0x335f2 }, + { 0x46d2b, 0x335f4 }, { 0x46d2c, 0x335f5 }, { 0x46d2d, 0x335f6 }, + { 0x46d2e, 0x335f7 }, { 0x46d2f, 0x335b4 }, { 0x46d30, 0x335f8 }, + { 0x46d31, 0x335f9 }, { 0x46d32, 0x335fa }, { 0x46d33, 0x335fb }, + { 0x46d34, 0x335fc }, { 0x46d35, 0x335fd }, { 0x46d36, 0x335ff }, + { 0x46d37, 0x33600 }, { 0x46d38, 0x33601 }, { 0x46d39, 0x33602 }, + { 0x46d3a, 0x3380f }, { 0x46d3b, 0x33695 }, { 0x46d47, 0x07536 }, + { 0x46d4a, 0x3360c }, { 0x46d4e, 0x337fc }, { 0x46d50, 0x337fd }, + { 0x46d56, 0x33800 }, { 0x46d58, 0x33694 }, { 0x46dc2, 0x337f3 }, + { 0x46dc6, 0x337fb }, { 0x46dc7, 0x337f9 }, { 0x46dca, 0x33802 }, + { 0x46dd3, 0x33775 } +}; + +#define MAITRED_COUNT 108 +static const TagMapping MAITRED_MAP[] = { + { 0x46cd0, 0x3f94c }, { 0x46ce2, 0x3f9a6 }, { 0x46ced, 0x3f9a7 }, + { 0x46cf8, 0x3f9a8 }, { 0x46d03, 0x3f9a9 }, { 0x46d0e, 0x3f9aa }, + { 0x46d19, 0x3f9ab }, { 0x46d24, 0x3f9ac }, { 0x46d2f, 0x3f9ad }, + { 0x46cd1, 0x3f9ae }, { 0x46cd9, 0x3f9af }, { 0x46cda, 0x3f9b0 }, + { 0x46cdb, 0x3f9b1 }, { 0x46cdc, 0x3f9b2 }, { 0x46cdd, 0x3f9b3 }, + { 0x46cde, 0x3f9b4 }, { 0x46cdf, 0x3f9b5 }, { 0x46ce0, 0x3f9b6 }, + { 0x46ce1, 0x3f9b7 }, { 0x46ce3, 0x3f9b8 }, { 0x46ce4, 0x3f9b9 }, + { 0x46ce5, 0x3f9ba }, { 0x46ce6, 0x3f9bb }, { 0x46ce7, 0x3f9bc }, + { 0x46ce8, 0x3f9bd }, { 0x46ce9, 0x3f9be }, { 0x46cea, 0x3f9bf }, + { 0x46ceb, 0x3f9c0 }, { 0x46cec, 0x3f9c1 }, { 0x46cee, 0x3f9c2 }, + { 0x46cef, 0x3f9c3 }, { 0x46cf0, 0x3f9c4 }, { 0x46cf1, 0x3f9c5 }, + { 0x46cf2, 0x3f9c6 }, { 0x46cf3, 0x3f9c7 }, { 0x46cf4, 0x3f9c8 }, + { 0x46cf5, 0x3f9c9 }, { 0x46cf6, 0x3f9ca }, { 0x46cf7, 0x3f9cb }, + { 0x46cf9, 0x3f9cc }, { 0x46cfa, 0x3f9cd }, { 0x46cfb, 0x3f9ce }, + { 0x46cfc, 0x3f9cf }, { 0x46cfd, 0x3f9d0 }, { 0x46cfe, 0x3f9d1 }, + { 0x46cff, 0x3f9d2 }, { 0x46d00, 0x3f9d3 }, { 0x46d01, 0x3f9d4 }, + { 0x46d02, 0x3f9d5 }, { 0x46d04, 0x3f9d6 }, { 0x46d05, 0x3f9d7 }, + { 0x46d06, 0x3f9d9 }, { 0x46d07, 0x3f9da }, { 0x46d08, 0x3f9db }, + { 0x46d09, 0x3f98a }, { 0x46d0a, 0x3f98b }, { 0x46d0b, 0x3f98c }, + { 0x46d0c, 0x3f98d }, { 0x46d0d, 0x3f98e }, { 0x46d0f, 0x3f98f }, + { 0x46d10, 0x3f991 }, { 0x46d11, 0x3f992 }, { 0x46d12, 0x3f993 }, + { 0x46d13, 0x3f994 }, { 0x46d14, 0x3f996 }, { 0x46d15, 0x3f997 }, + { 0x46d16, 0x3f998 }, { 0x46d17, 0x3f999 }, { 0x46d18, 0x3f99a }, + { 0x46d1a, 0x3f99b }, { 0x46d1b, 0x3f99c }, { 0x46d1c, 0x3f99d }, + { 0x46d1d, 0x3f99e }, { 0x46d1e, 0x3f99f }, { 0x46d1f, 0x3f9a1 }, + { 0x46d20, 0x3f9a2 }, { 0x46d21, 0x3f9a3 }, { 0x46d22, 0x3f9a4 }, + { 0x46d23, 0x3f9a5 }, { 0x46d25, 0x3f9dd }, { 0x46d26, 0x3f9de }, + { 0x46d27, 0x3f9df }, { 0x46d28, 0x3f9e0 }, { 0x46d29, 0x3f9e1 }, + { 0x46d2a, 0x3f9e2 }, { 0x46d2b, 0x3f9e3 }, { 0x46d2c, 0x3f9e4 }, + { 0x46d2d, 0x3f9e5 }, { 0x46d2e, 0x3f9e6 }, { 0x46d30, 0x3f9e7 }, + { 0x46d31, 0x3f9e8 }, { 0x46d32, 0x3f9e9 }, { 0x46d33, 0x3f9ea }, + { 0x46d34, 0x3f9eb }, { 0x46d35, 0x3f9ec }, { 0x46d36, 0x3f9ed }, + { 0x46d37, 0x3f9ee }, { 0x46d38, 0x3f9ef }, { 0x46d39, 0x3f9f0 }, + { 0x46cd2, 0x3f9f1 }, { 0x46cd3, 0x3f9f2 }, { 0x46cd4, 0x3f9f3 }, + { 0x46cd5, 0x3f9f9 }, { 0x46cd6, 0x3f9fa }, { 0x46cd7, 0x3f9fb }, + { 0x46cd8, 0x3f9fc }, { 0x46d3b, 0x3f853 }, { 0x46d58, 0x3f83c } +}; + +void writeTagMappings(const char *name, const TagMapping *map, int count) { + outputFile.seek(dataOffset); + + for (int idx = 0; idx < count; ++idx, ++map) { + outputFile.writeLong(map->_src); + outputFile.writeLong(map->_dest); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader(name, dataOffset, size); + dataOffset += size; +} + +void writeAllTagMappings() { + writeTagMappings("TagMap/Barbot", BARBOT_MAP, BARBOT_COUNT); + writeTagMappings("TagMap/Bellbot", BELLBOT_MAP, BELLBOT_COUNT); + writeTagMappings("TagMap/Deskbot", DESKBOT_MAP, DESKBOT_COUNT); + writeTagMappings("TagMap/Doorbot", DOORBOT_MAP, DOORBOT_COUNT); + writeTagMappings("TagMap/Liftbot", LIFTBOT_MAP, LIFTBOT_COUNT); + writeTagMappings("TagMap/MaitreD", MAITRED_MAP, MAITRED_COUNT); +}
\ No newline at end of file diff --git a/devtools/create_titanic/tag_maps.h b/devtools/create_titanic/tag_maps.h new file mode 100644 index 0000000000..33dd8e648c --- /dev/null +++ b/devtools/create_titanic/tag_maps.h @@ -0,0 +1,37 @@ +/* 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 COMMON_TAG_MAPS_H +#define COMMON_TAG_MAPS_H + +#include "common/scummsys.h" + +struct TagMapping { + uint _src; + uint _dest; +}; + +extern void writeAllTagMappings(); +extern void writeEntryHeader(const char *name, uint offset, uint size); +extern uint dataOffset; + +#endif diff --git a/devtools/create_titanic/winexe.cpp b/devtools/create_titanic/winexe.cpp new file mode 100644 index 0000000000..c23bd84a89 --- /dev/null +++ b/devtools/create_titanic/winexe.cpp @@ -0,0 +1,83 @@ +/* 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. + * + */ + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "str.h" +#include "winexe.h" + +namespace Common { + +WinResourceID &WinResourceID::operator=(const String &x) { + _name = x; + _idType = kIDTypeString; + return *this; +} + +WinResourceID &WinResourceID::operator=(uint32 x) { + _id = x; + _idType = kIDTypeNumerical; + return *this; +} + +bool WinResourceID::operator==(const String &x) const { + return _idType == kIDTypeString && _name.equalsIgnoreCase(x); +} + +bool WinResourceID::operator==(const uint32 &x) const { + return _idType == kIDTypeNumerical && _id == x; +} + +bool WinResourceID::operator==(const WinResourceID &x) const { + if (_idType != x._idType) + return false; + if (_idType == kIDTypeString) + return _name.equalsIgnoreCase(x._name); + if (_idType == kIDTypeNumerical) + return _id == x._id; + return true; +} + +String WinResourceID::getString() const { + if (_idType != kIDTypeString) + return ""; + + return _name; +} + +uint32 WinResourceID::getID() const { + if (_idType != kIDTypeNumerical) + return 0xffffffff; + + return _id; +} + +String WinResourceID::toString() const { + if (_idType == kIDTypeString) + return _name; + else if (_idType == kIDTypeNumerical) + return String::format("0x%08x", _id); + + return ""; +} + +} // End of namespace Common diff --git a/devtools/create_titanic/winexe.h b/devtools/create_titanic/winexe.h new file mode 100644 index 0000000000..da99c769be --- /dev/null +++ b/devtools/create_titanic/winexe.h @@ -0,0 +1,70 @@ +/* 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 COMMON_WINEXE_H +#define COMMON_WINEXE_H + +#include "hash-str.h" +#include "str.h" + +namespace Common { + +class WinResourceID { +public: + WinResourceID() { _idType = kIDTypeNull; } + WinResourceID(String x) { _idType = kIDTypeString; _name = x; } + WinResourceID(uint32 x) { _idType = kIDTypeNumerical; _id = x; } + + WinResourceID &operator=(const String &x); + WinResourceID &operator=(uint32 x); + + bool operator==(const String &x) const; + bool operator==(const uint32 &x) const; + bool operator==(const WinResourceID &x) const; + + String getString() const; + uint32 getID() const; + String toString() const; + +private: + /** An ID Type. */ + enum IDType { + kIDTypeNull, ///< No type set + kIDTypeNumerical, ///< A numerical ID. + kIDTypeString ///< A string ID. + } _idType; + + String _name; ///< The resource's string ID. + uint32 _id; ///< The resource's numerical ID. +}; + +struct WinResourceID_Hash { + uint operator()(const WinResourceID &id) const { return hashit(id.toString()); } +}; + +struct WinResourceID_EqualTo { + bool operator()(const WinResourceID &id1, const WinResourceID &id2) const { return id1 == id2; } +}; + +} // End of namespace Common + +#endif diff --git a/devtools/create_titanic/winexe_pe.cpp b/devtools/create_titanic/winexe_pe.cpp new file mode 100644 index 0000000000..16ad16ab63 --- /dev/null +++ b/devtools/create_titanic/winexe_pe.cpp @@ -0,0 +1,260 @@ +/* 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. + * + */ + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "file.h" +#include "str.h" +#include "winexe_pe.h" +#include "common/array.h" +#include "common/endian.h" + +namespace Common { + +PEResources::PEResources() { + _exe = 0; +} + +PEResources::~PEResources() { + clear(); +} + +void PEResources::clear() { + _sections.clear(); + _resources.clear(); + delete _exe; _exe = 0; +} + +bool PEResources::loadFromEXE(const String &fileName) { + if (fileName.empty()) + return false; + + File *file = new File(); + + if (!file->open(fileName.c_str())) { + delete file; + return false; + } + + return loadFromEXE(file); +} + +bool PEResources::loadFromEXE(File *stream) { + clear(); + + if (!stream) + return false; + + if (stream->readUint16BE() != MKTAG16('M', 'Z')) + return false; + + stream->skip(58); + + uint32 peOffset = stream->readUint32LE(); + + if (!peOffset || peOffset >= (uint32)stream->size()) + return false; + + stream->seek(peOffset); + + if (stream->readUint32BE() != MKTAG('P','E',0,0)) + return false; + + stream->skip(2); + uint16 sectionCount = stream->readUint16LE(); + stream->skip(12); + uint16 optionalHeaderSize = stream->readUint16LE(); + stream->skip(optionalHeaderSize + 2); + + // Read in all the sections + for (uint16 i = 0; i < sectionCount; i++) { + char sectionName[9]; + stream->read(sectionName, 8); + sectionName[8] = 0; + + Section section; + stream->skip(4); + section.virtualAddress = stream->readUint32LE(); + section.size = stream->readUint32LE(); + section.offset = stream->readUint32LE(); + stream->skip(16); + + _sections[sectionName] = section; + } + + // Currently, we require loading a resource section + if (!_sections.contains(".rsrc")) { + clear(); + return false; + } + + _exe = stream; + + Section &resSection = _sections[".rsrc"]; + parseResourceLevel(resSection, resSection.offset, 0); + + return true; +} + +void PEResources::parseResourceLevel(Section §ion, uint32 offset, int level) { + _exe->seek(offset + 12); + + uint16 namedEntryCount = _exe->readUint16LE(); + uint16 intEntryCount = _exe->readUint16LE(); + + for (uint32 i = 0; i < (uint32)(namedEntryCount + intEntryCount); i++) { + uint32 value = _exe->readUint32LE(); + + WinResourceID id; + + if (value & 0x80000000) { + value &= 0x7fffffff; + + uint32 startPos = _exe->pos(); + _exe->seek(section.offset + (value & 0x7fffffff)); + + // Read in the name, truncating from unicode to ascii + String name; + uint16 nameLength = _exe->readUint16LE(); + while (nameLength--) + name += (char)(_exe->readUint16LE() & 0xff); + + _exe->seek(startPos); + + id = name; + } else { + id = value; + } + + uint32 nextOffset = _exe->readUint32LE(); + uint32 lastOffset = _exe->pos(); + + if (level == 0) + _curType = id; + else if (level == 1) + _curName = id; + else if (level == 2) + _curLang = id; + + if (level < 2) { + // Time to dive down further + parseResourceLevel(section, section.offset + (nextOffset & 0x7fffffff), level + 1); + } else { + _exe->seek(section.offset + nextOffset); + + Resource resource; + resource.offset = _exe->readUint32LE() + section.offset - section.virtualAddress; + resource.size = _exe->readUint32LE(); + + _resources[_curType][_curName][_curLang] = resource; + } + + _exe->seek(lastOffset); + } +} + +const Array<WinResourceID> PEResources::getTypeList() const { + Array<WinResourceID> array; + + if (!_exe) + return array; + + for (TypeMap::const_iterator it = _resources.begin(); it != _resources.end(); it++) + array.push_back(it->_key); + + return array; +} + +const Array<WinResourceID> PEResources::getNameList(const WinResourceID &type) const { + Array<WinResourceID> array; + + if (!_exe || !_resources.contains(type)) + return array; + + const NameMap &nameMap = _resources[type]; + + for (NameMap::const_iterator it = nameMap.begin(); it != nameMap.end(); it++) + array.push_back(it->_key); + + return array; +} + +const Array<WinResourceID> PEResources::getLangList(const WinResourceID &type, const WinResourceID &name) const { + Array<WinResourceID> array; + + if (!_exe || !_resources.contains(type)) + return array; + + const NameMap &nameMap = _resources[type]; + + if (!nameMap.contains(name)) + return array; + + const LangMap &langMap = nameMap[name]; + + for (LangMap::const_iterator it = langMap.begin(); it != langMap.end(); it++) + array.push_back(it->_key); + + return array; +} + +File *PEResources::getResource(const WinResourceID &type, const WinResourceID &name) { + Array<WinResourceID> langList = getLangList(type, name); + + if (langList.empty()) + return 0; + + const Resource &resource = _resources[type][name][langList[0]]; + byte *data = (byte *)malloc(resource.size); + _exe->seek(resource.offset); + _exe->read(data, resource.size); + + File *file = new File(); + file->open(data, resource.size); + return file; +} + +File *PEResources::getResource(const WinResourceID &type, const WinResourceID &name, const WinResourceID &lang) { + if (!_exe || !_resources.contains(type)) + return 0; + + const NameMap &nameMap = _resources[type]; + + if (!nameMap.contains(name)) + return 0; + + const LangMap &langMap = nameMap[name]; + + if (!langMap.contains(lang)) + return 0; + + const Resource &resource = langMap[lang]; + byte *data = (byte *)malloc(resource.size); + _exe->seek(resource.offset); + _exe->read(data, resource.size); + + File *file = new File(); + file->open(data, resource.size); + return file; +} + +} // End of namespace Common diff --git a/devtools/create_titanic/winexe_pe.h b/devtools/create_titanic/winexe_pe.h new file mode 100644 index 0000000000..49e29b7a56 --- /dev/null +++ b/devtools/create_titanic/winexe_pe.h @@ -0,0 +1,120 @@ +/* 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 COMMON_WINEXE_PE_H +#define COMMON_WINEXE_PE_H + +#include "file.h" +#include "hash-str.h" +#include "hashmap.h" +#include "str.h" +#include "winexe.h" + +namespace Common { + +template<class T> class Array; +class SeekableReadStream; + +/** The default Windows PE resources. */ +enum PEResourceType { + kPECursor = 0x01, + kPEBitmap = 0x02, + kPEIcon = 0x03, + kPEMenu = 0x04, + kPEDialog = 0x05, + kPEString = 0x06, + kPEFontDir = 0x07, + kPEFont = 0x08, + kPEAccelerator = 0x09, + kPERCData = 0x0A, + kPEMessageTable = 0x0B, + kPEGroupCursor = 0x0C, + kPEGroupIcon = 0x0E, + kPEVersion = 0x10, + kPEDlgInclude = 0x11, + kPEPlugPlay = 0x13, + kPEVXD = 0x14, + kPEAniCursor = 0x15, + kPEAniIcon = 0x16 +}; + +/** + * A class able to load resources from a Windows Portable Executable, such + * as cursors, bitmaps, and sounds. + */ +class PEResources { +public: + PEResources(); + ~PEResources(); + + /** Clear all information. */ + void clear(); + + /** Load from an EXE file. */ + bool loadFromEXE(const String &fileName); + + bool loadFromEXE(File *stream); + + /** Return a list of resource types. */ + const Array<WinResourceID> getTypeList() const; + + /** Return a list of names for a given type. */ + const Array<WinResourceID> getNameList(const WinResourceID &type) const; + + /** Return a list of languages for a given type and name. */ + const Array<WinResourceID> getLangList(const WinResourceID &type, const WinResourceID &name) const; + + /** Return a stream to the specified resource, taking the first language found (or 0 if non-existent). */ + File *getResource(const WinResourceID &type, const WinResourceID &name); + + /** Return a stream to the specified resource (or 0 if non-existent). */ + File *getResource(const WinResourceID &type, const WinResourceID &name, const WinResourceID &lang); + +private: + struct Section { + uint32 virtualAddress; + uint32 size; + uint32 offset; + }; + + HashMap<String, Section, IgnoreCase_Hash, IgnoreCase_EqualTo> _sections; + + File *_exe; + + void parseResourceLevel(Section §ion, uint32 offset, int level); + WinResourceID _curType, _curName, _curLang; + + struct Resource { + uint32 offset; + uint32 size; + }; + + typedef HashMap<WinResourceID, Resource, WinResourceID_Hash, WinResourceID_EqualTo> LangMap; + typedef HashMap<WinResourceID, LangMap, WinResourceID_Hash, WinResourceID_EqualTo> NameMap; + typedef HashMap<WinResourceID, NameMap, WinResourceID_Hash, WinResourceID_EqualTo> TypeMap; + + TypeMap _resources; +}; + +} // End of namespace Common + +#endif diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat Binary files differindex d49d107f6f..4dcfb0c380 100644 --- a/dists/engine-data/kyra.dat +++ b/dists/engine-data/kyra.dat diff --git a/dists/scummvm.appdata.xml b/dists/scummvm.appdata.xml new file mode 100644 index 0000000000..e9185cd2a6 --- /dev/null +++ b/dists/scummvm.appdata.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<component type="desktop"> + <id>scummvm.desktop</id> + <metadata_license>CC0-1.0</metadata_license> + <project_license>GPL-2.0+</project_license> + <name>ScummVM</name> + <summary>Interpreter for several adventure games</summary> + <description> + <p> + ScummVM is an interpreter that will play graphic adventure games written + for LucasArts' SCUMM virtual machine (such as Day of the Tentacle and + Monkey Island), Sierra's AGI adventures (such as early King's Quest and + Space Quest games), Adventure Soft's Simon the Sorcerer 1, 2 and Feeble Files, + Revolution Software's Beneath a Steel Sky and Broken Sword 1, 2 and 2.5, + Interactive Binary Illusions' Flight of the Amazon Queen, + Coktel Vision's Gobliiins, Wyrmkeep's Inherit the Earth, Westwood's + Legend of Kyrandia, and various others. + </p> + </description> + <screenshots> + <screenshot type="default"> + <image>http://wiki.scummvm.org/images/f/f8/Launcherwithgames.png</image> + <caption>ScummVM Launcher</caption> + </screenshot> + </screenshots> + <url type="homepage">https://www.scummvm.org</url> + <updatecontact>scummvm-devel@lists.sourceforge.net</updatecontact> +</component> diff --git a/dists/win32/ScummVM.iss b/dists/win32/ScummVM.iss index 817cc5aeef..740b30d071 100644 --- a/dists/win32/ScummVM.iss +++ b/dists/win32/ScummVM.iss @@ -1,5 +1,5 @@ [Setup] -AppCopyright=2014 +AppCopyright=2016 AppName=ScummVM AppVerName=ScummVM Git AppPublisher=The ScummVM Team @@ -51,7 +51,7 @@ Name: {group}\Copying.LGPL; Filename: {app}\COPYING.LGPL.txt; WorkingDir: {app}; Name: {group}\Copyright; Filename: {app}\COPYRIGHT.txt; WorkingDir: {app}; Comment: COPYRIGHT; Flags: createonlyiffileexists ;NEWS Name: {group}\News; Filename: {app}\NEWS.txt; WorkingDir: {app}; Comment: NEWS; Flags: createonlyiffileexists; Languages: not de -Name: {group}\Neues; Filename: {app}\Neues.txt; WorkingDir: {app}; Comment: Neues; Flags: createonlyiffileexists; Languages: de +Name: {group}\Neues; Filename: {app}\NEUES.txt; WorkingDir: {app}; Comment: NEUES; Flags: createonlyiffileexists; Languages: de ;QUICKSTART Name: {group}\Schnellstart; Filename: {app}\Schnellstart.txt; WorkingDir: {app}; Comment: Schnellstart; Flags: createonlyiffileexists; Languages: de Name: {group}\InicioRapido; Filename: {app}\InicioRapido.txt; WorkingDir: {app}; Comment: InicioRapido; Flags: createonlyiffileexists; Languages: es @@ -62,7 +62,7 @@ Name: {group}\Snabbstart; Filename: {app}\Snabbstart.txt; WorkingDir: {app}; Com ;README Name: {group}\Readme; Filename: {app}\README.txt; WorkingDir: {app}; Comment: README; Flags: createonlyiffileexists; Languages: not (cz or de or se) Name: {group}\PrectiMe; Filename: {app}\PrectiMe.txt; WorkingDir: {app}; Comment: PrectiMe; Flags: createonlyiffileexists; Languages: cz -Name: {group}\Liesmich; Filename: {app}\Liesmich.txt; WorkingDir: {app}; Comment: Liesmich; Flags: createonlyiffileexists; Languages: de +Name: {group}\Liesmich; Filename: {app}\LIESMICH.txt; WorkingDir: {app}; Comment: LIESMICH; Flags: createonlyiffileexists; Languages: de Name: {group}\LasMig; Filename: {app}\LasMig.txt; WorkingDir: {app}; Comment: LasMig; Flags: createonlyiffileexists; Languages: se Name: {group}\Saved Games\Migrate Saved Games; Filename: {app}\migration.bat; WorkingDir: {app}; Comment: Migrate Saved Games; IconIndex: 0; MinVersion: 0, 1 @@ -90,7 +90,7 @@ Source: COPYING.LGPL.txt; DestDir: {app}; Flags: ignoreversion Source: COPYRIGHT.txt; DestDir: {app}; Flags: ignoreversion ;NEWS Source: NEWS.txt; DestDir: {app}; Flags: ignoreversion; Languages: not de -Source: doc/de/Neues.txt; DestDir: {app}; Flags: ignoreversion; Languages: de +Source: doc/de/NEUES.txt; DestDir: {app}; Flags: ignoreversion; Languages: de ;QUICKSTART Source: doc/de/Schnellstart.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: de Source: doc/es/InicioRapido.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: es @@ -101,7 +101,7 @@ Source: doc/se/Snabbstart.txt; DestDir: {app}; Flags: ignoreversion isreadme; La ;README Source: README.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: not (cz or de or se) Source: doc/cz/PrectiMe.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: cz -Source: doc/de/Liesmich.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: de +Source: doc/de/LIESMICH.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: de Source: doc/se/LasMig.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: se Source: README-SDL.txt; DestDir: {app}; Flags: ignoreversion Source: scummvm.exe; DestDir: {app}; Flags: ignoreversion diff --git a/doc/de/Liesmich b/doc/de/LIESMICH index 84eb6b53fd..84eb6b53fd 100644 --- a/doc/de/Liesmich +++ b/doc/de/LIESMICH diff --git a/doc/de/Neues b/doc/de/NEUES index 6870accf40..6d5763daa3 100644 --- a/doc/de/Neues +++ b/doc/de/NEUES @@ -8,6 +8,9 @@ Programmcodes finden Sie auf Englisch unter: - UnterstĂźtzung fĂźr Myst: Masterpiece Edition hinzugefĂźgt. - UnterstĂźtzung fĂźr U.F.O.s./Gnap: Der Schurke aus dem All hinzugefĂźgt. + Allgemein: + - Probleme mit dem MS ADPCM-Decoder behoben. + AGI: - UnterstĂźtzung fĂźr Hercules-Darstellung (GrĂźn + Bernstein) hinzugefĂźgt. - UnterstĂźtzung fĂźr hochauflĂśsende Hercules-Schriftart hinzugefĂźgt @@ -16,13 +19,50 @@ Programmcodes finden Sie auf Englisch unter: Diese Funktion war im originalen Interpreter nur im Hercules-Darstellungsmodus verfĂźgbar. + Beneath a Steel Sky: + - Fehlerhafte Animation fĂźr Officer Blunt behoben, die dafĂźr sorgte, dass das + Spiel nicht komplett durchgespielt werden konnte, da eine weitere Interaktion mit + diesem Charakter nicht mĂśglich war. + + Gob: + - Grafikfehler in Gobliiins (EGA-Version) behoben. + + Kyra: + - Italienische Ăbersetzung von EOB1 aktualisiert. + + Mohawk: + - Grafikfehler in der spanischen Version von Myst behoben. + - Der "Abbrechen"-Button im Optionen-Dialog von Riven speichert die Einstellungen nicht mehr. + - Spielstände in Riven, die von ScummVM erstellt wurden, kĂśnnen nun im Originalspiel geladen + werden. + - In Myst wurde der Mauszeiger nicht angezeigt, wenn ein Spielstand geladen wurde, während + das Intro läuft. Dieser Fehler wurde behoben. + SCI: - Fehlende Dialogzeile in QfG3 hinzugefĂźgt, die mit drei zusätzlichen Punkten belohnt wird. Diese Dialogzeile fehlt im Originalspiel, weshalb es bislang unmĂśglich war, die maximale Punktzahl im Spiel zu erreichen. + - Fehler in "Space Quest 1" behoben, der Probleme mit dem Spinnenroboter verursachte. + - Fehler in "Laura Bow: The Colonel's Bequest" behoben, der einen Absturz verursachte, + wenn mit der RĂźstung in Raum 37 (Haupthaus, Untergeschoss) interagiert wird. Dieser + Fehler existiert auch im Originalspiel. + - Automatisches Speichern im Fan-Spiel "Cascade Quest" repariert. + - Fehler in "Conquest of the Longbow: The Adventures of Robin Hood" behoben, der einen + Absturz verursacht, wenn sich der Spieler durch den Sherwood Forest bewegt. + - Erkennungseintrag fĂźr die Demo-Version des "ImagiNation Network (INN)" hinzugefĂźgt. + + SCUMM: + - Fehlende Ăbersetzungen in den "Beenden"- und "Neustart"-Dialogen in "Pyjama Sam 1" behoben. + - Grafikfehler in DOTT behoben, die auftraten, wenn ein Spielstand geladen wurde, in dem + die Stereoanlage in GrĂźntentakels Zimmer eingeschaltet ist. + - Timing und Wegfindung in "Maniac Mansion (C64- und Apple II-Version)" verbessert. + + WAGE: + - Speicherleck geschlossen. Windows-Portierung: - Taskleisten-Integration unter Windows 10 und hĂśher repariert. + - Tastenbelegung fĂźr Tastaturen korrigiert, die keine QWERTY-Tastaturen sind. 1.8.1 (25.05.2016) Neue Portierungen: diff --git a/engines/access/access.cpp b/engines/access/access.cpp index 6f91bd76dd..ea2144459d 100644 --- a/engines/access/access.cpp +++ b/engines/access/access.cpp @@ -34,6 +34,12 @@ namespace Access { AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc) : _gameDescription(gameDesc), Engine(syst), _randomSource("Access"), _useItem(_flags[99]), _startup(_flags[170]), _manScaleOff(_flags[172]) { + // Set up debug channels + DebugMan.addDebugChannel(kDebugPath, "path", "Pathfinding debug level"); + DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts"); + DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling"); + DebugMan.addDebugChannel(kDebugSound, "sound", "Sound and Music handling"); + _aboutBox = nullptr; _animation = nullptr; _bubbleBox = nullptr; @@ -151,12 +157,6 @@ void AccessEngine::setVGA() { } void AccessEngine::initialize() { - // Set up debug channels - DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); - DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts"); - DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling"); - DebugMan.addDebugChannel(kDebugSound, "sound", "Sound and Music handling"); - if (isCD()) { const Common::FSNode gameDataDir(ConfMan.get("path")); // The CD version contains two versions of the game. diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp index b6af54962e..83181c9847 100644 --- a/engines/adl/adl.cpp +++ b/engines/adl/adl.cpp @@ -520,6 +520,8 @@ void AdlEngine::dropItem(byte noun) { } Common::Error AdlEngine::run() { + initGraphics(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, true); + _console = new Console(this); _speaker = new Speaker(); _display = new Display(); diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp index 12405e7c5e..6a85f98cf0 100644 --- a/engines/adl/detection.cpp +++ b/engines/adl/detection.cpp @@ -32,13 +32,15 @@ namespace Adl { -#define GAMEOPTION_COLOR GUIO_GAMEOPTIONS1 -#define GAMEOPTION_SCANLINES GUIO_GAMEOPTIONS2 -#define GAMEOPTION_MONO GUIO_GAMEOPTIONS3 +// Mystery House was designed for monochrome display, so we default to +// monochrome mode there. All the other games default to color mode. +#define GAMEOPTION_COLOR_DEFAULT_OFF GUIO_GAMEOPTIONS1 +#define GAMEOPTION_SCANLINES GUIO_GAMEOPTIONS2 +#define GAMEOPTION_COLOR_DEFAULT_ON GUIO_GAMEOPTIONS3 static const ADExtraGuiOptionsMap optionsList[] = { { - GAMEOPTION_COLOR, + GAMEOPTION_COLOR_DEFAULT_OFF, { _s("Color mode"), _s("Use color graphics"), @@ -48,7 +50,7 @@ static const ADExtraGuiOptionsMap optionsList[] = { }, { - GAMEOPTION_MONO, + GAMEOPTION_COLOR_DEFAULT_ON, { _s("Color mode"), _s("Use color graphics"), @@ -89,9 +91,9 @@ static const AdlGameDescription gameDescriptions[] = { AD_LISTEND }, Common::EN_ANY, - Common::kPlatformApple2GS, // FIXME + Common::kPlatformApple2, ADGF_UNSTABLE, - GUIO2(GAMEOPTION_COLOR, GAMEOPTION_SCANLINES) + GUIO2(GAMEOPTION_COLOR_DEFAULT_OFF, GAMEOPTION_SCANLINES) }, GAME_TYPE_HIRES1 }, @@ -103,9 +105,9 @@ static const AdlGameDescription gameDescriptions[] = { AD_LISTEND }, Common::EN_ANY, - Common::kPlatformApple2GS, // FIXME + Common::kPlatformApple2, ADGF_UNSTABLE, - GUIO2(GAMEOPTION_COLOR, GAMEOPTION_SCANLINES) + GUIO2(GAMEOPTION_COLOR_DEFAULT_OFF, GAMEOPTION_SCANLINES) }, GAME_TYPE_HIRES1 }, @@ -117,9 +119,9 @@ static const AdlGameDescription gameDescriptions[] = { AD_LISTEND }, Common::EN_ANY, - Common::kPlatformApple2GS, // FIXME + Common::kPlatformApple2, ADGF_UNSTABLE, - GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES) + GUIO2(GAMEOPTION_COLOR_DEFAULT_ON, GAMEOPTION_SCANLINES) }, GAME_TYPE_HIRES2 }, @@ -131,9 +133,9 @@ static const AdlGameDescription gameDescriptions[] = { AD_LISTEND }, Common::EN_ANY, - Common::kPlatformApple2GS, // FIXME + Common::kPlatformApple2, ADGF_UNSTABLE, - GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES) + GUIO2(GAMEOPTION_COLOR_DEFAULT_ON, GAMEOPTION_SCANLINES) }, GAME_TYPE_HIRES0 }, @@ -148,9 +150,9 @@ static const AdlGameDescription gameDescriptions[] = { AD_LISTEND }, Common::EN_ANY, - Common::kPlatformApple2GS, // FIXME + Common::kPlatformApple2, ADGF_UNSTABLE, - GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES) + GUIO2(GAMEOPTION_COLOR_DEFAULT_ON, GAMEOPTION_SCANLINES) }, GAME_TYPE_HIRES6 }, diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp index b7f6eb9923..d05257792c 100644 --- a/engines/adl/display.cpp +++ b/engines/adl/display.cpp @@ -109,8 +109,6 @@ Display::Display() : _cursorPos(0), _showCursor(false) { - initGraphics(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, true); - _monochrome = !ConfMan.getBool("color"); _scanlines = ConfMan.getBool("scanlines"); @@ -135,6 +133,8 @@ Display::Display() : _textBufSurface->create(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, Graphics::PixelFormat::createFormatCLUT8()); createFont(); + + _startMillis = g_system->getMillis(); } Display::~Display() { @@ -489,7 +489,11 @@ void Display::updateTextSurface() { r.translate(((c & 0x3f) % 16) * 7 * 2, (c & 0x3f) / 16 * 8 * 2); if (!(c & 0x80)) { - if (!(c & 0x40) || ((g_system->getMillis() / 270) & 1)) + // Blink text. We subtract _startMillis to make this compatible + // with the event recorder, which returns offsetted values on + // playback. + const uint32 millisPassed = g_system->getMillis() - _startMillis; + if (!(c & 0x40) || ((millisPassed / 270) & 1)) r.translate(0, 4 * 8 * 2); } diff --git a/engines/adl/display.h b/engines/adl/display.h index bc27b7cb6b..e761e63f2e 100644 --- a/engines/adl/display.h +++ b/engines/adl/display.h @@ -102,6 +102,7 @@ private: Graphics::Surface *_font; uint _cursorPos; bool _showCursor; + uint32 _startMillis; }; } // End of namespace Adl diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp index d2f088dcd8..414fe49eb6 100644 --- a/engines/cine/cine.cpp +++ b/engines/cine/cine.cpp @@ -49,13 +49,14 @@ CineEngine::CineEngine(OSystem *syst, const CINEGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _rnd("cine") { - // Setup mixer - syncSoundSettings(); - DebugMan.addDebugChannel(kCineDebugScript, "Script", "Script debug level"); DebugMan.addDebugChannel(kCineDebugPart, "Part", "Part debug level"); DebugMan.addDebugChannel(kCineDebugSound, "Sound", "Sound debug level"); DebugMan.addDebugChannel(kCineDebugCollision, "Collision", "Collision debug level"); + + // Setup mixer + syncSoundSettings(); + _console = new CineConsole(this); g_cine = this; diff --git a/engines/director/configure.engine b/engines/director/configure.engine new file mode 100644 index 0000000000..41f9a6249d --- /dev/null +++ b/engines/director/configure.engine @@ -0,0 +1,3 @@ +# This file is included from the main "configure" script +# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] +add_engine director "Macromedia Director" no diff --git a/engines/director/detection.cpp b/engines/director/detection.cpp new file mode 100644 index 0000000000..1f2e970539 --- /dev/null +++ b/engines/director/detection.cpp @@ -0,0 +1,252 @@ +/* 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 "base/plugins.h" + +#include "engines/advancedDetector.h" +#include "common/savefile.h" +#include "common/system.h" +#include "common/textconsole.h" + +#include "director/director.h" + +namespace Director { + +struct DirectorGameDescription { + ADGameDescription desc; + + DirectorGameID gameID; + uint16 version; +}; + +DirectorGameID DirectorEngine::getGameID() const { + return _gameDescription->gameID; +} + +Common::Platform DirectorEngine::getPlatform() const { + return _gameDescription->desc.platform; +} + +uint16 DirectorEngine::getVersion() const { + return _gameDescription->version; +} + +Common::Language DirectorEngine::getLanguage() const { + return _gameDescription->desc.language; +} + +Common::String DirectorEngine::getEXEName() const { + return _gameDescription->desc.filesDescriptions[0].fileName; +} + +bool DirectorEngine::hasFeature(EngineFeature f) const { + return + (f == kSupportsRTL); +} + +} // End of Namespace Director + +static const PlainGameDescriptor directorGames[] = { + { "director", "Macromedia Director Game" }, + { "directortest", "Macromedia Director Test Target" }, + { "theapartment", "The Apartment, D3 interactive demo" }, + { "gundam0079", "Gundam 0079: The War for Earth" }, + { "jewels", "Jewels of the Oracle" }, + { "jman", "The Journeyman Project" }, + { "majestic", "Majestic Part I: Alien Encounter" }, + { "melements", "Masters of the Elements" }, + { "spyclub", "Spy Club" }, + { "amber", "AMBER: Journeys Beyond"}, + { "vvvampire", "Victor Vector & Yondo: The Vampire's Coffin"}, + { "vvdinosaur", "Victor Vector & Yondo: The Last Dinosaur Egg"}, + { "warlock", "Spaceship Warlock"}, + { 0, 0 } +}; + +#include "director/detection_tables.h" + +static const char *directoryGlobs[] = { + "install", + 0 +}; + +class DirectorMetaEngine : public AdvancedMetaEngine { +public: + DirectorMetaEngine() : AdvancedMetaEngine(Director::gameDescriptions, sizeof(Director::DirectorGameDescription), directorGames) { + _singleId = "director"; + _maxScanDepth = 2, + _directoryGlobs = directoryGlobs; + } + + virtual const char *getName() const { + return "Macromedia Director"; + } + + virtual const char *getOriginalCopyright() const { + return "Macromedia Director (C) Macromedia"; + } + + const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const; + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; +}; + +bool DirectorMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { + const Director::DirectorGameDescription *gd = (const Director::DirectorGameDescription *)desc; + + if (gd) + *engine = new Director::DirectorEngine(syst, gd); + + return (gd != 0); +} + +static Director::DirectorGameDescription s_fallbackDesc = { + { + "director", + "", + AD_ENTRY1(0, 0), + Common::UNK_LANG, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO0() + }, + Director::GID_GENERIC, + 0 +}; + +static char s_fallbackFileNameBuffer[51]; + +const ADGameDescription *DirectorMetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { + // TODO: Handle Mac fallback + + // reset fallback description + Director::DirectorGameDescription *desc = &s_fallbackDesc; + desc->desc.gameId = "director"; + desc->desc.extra = ""; + desc->desc.language = Common::UNK_LANG; + desc->desc.flags = ADGF_NO_FLAGS; + desc->desc.platform = Common::kPlatformWindows; + desc->desc.guiOptions = GUIO0(); + desc->desc.filesDescriptions[0].fileName = 0; + desc->version = 0; + desc->gameID = Director::GID_GENERIC; + + for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { + if (file->isDirectory()) + continue; + + Common::String fileName = file->getName(); + fileName.toLowercase(); + if (!fileName.hasSuffix(".exe")) + continue; + + SearchMan.clear(); + SearchMan.addDirectory(file->getParent().getName(), file->getParent()); + + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(file->getName()); + + if (!stream) + continue; + + stream->seek(-4, SEEK_END); + + uint32 offset = stream->readUint32LE(); + + if (stream->eos() || offset == 0 || offset >= (uint32)(stream->size() - 4)) { + delete stream; + continue; + } + + stream->seek(offset); + + uint32 tag = stream->readUint32LE(); + + switch (tag) { + case MKTAG('3', '9', 'J', 'P'): + desc->version = 4; + break; + case MKTAG('P', 'J', '9', '5'): + desc->version = 5; + break; + case MKTAG('P', 'J', '0', '0'): + desc->version = 7; + break; + default: + // Prior to version 4, there was no tag here. So we'll use a bit of a + // heuristic to detect. The first field is the entry count, of which + // there should only be one. + if ((tag & 0xFFFF) != 1) { + delete stream; + continue; + } + + stream->skip(3); + + uint32 mmmSize = stream->readUint32LE(); + + if (stream->eos() || mmmSize == 0) { + delete stream; + continue; + } + + byte fileNameSize = stream->readByte(); + + if (stream->eos()) { + delete stream; + continue; + } + + stream->skip(fileNameSize); + byte directoryNameSize = stream->readByte(); + + if (stream->eos()) { + delete stream; + continue; + } + + stream->skip(directoryNameSize); + + if (stream->pos() != stream->size() - 4) { + delete stream; + continue; + } + + // Assume v3 at this point (for now at least) + desc->version = 3; + } + + strncpy(s_fallbackFileNameBuffer, fileName.c_str(), 50); + s_fallbackFileNameBuffer[50] = '\0'; + desc->desc.filesDescriptions[0].fileName = s_fallbackFileNameBuffer; + + warning("Director fallback detection D%d", desc->version); + + return (ADGameDescription *)desc; + } + + return 0; +} + +#if PLUGIN_ENABLED_DYNAMIC(DIRECTOR) + REGISTER_PLUGIN_DYNAMIC(DIRECTOR, PLUGIN_TYPE_ENGINE, DirectorMetaEngine); +#else + REGISTER_PLUGIN_STATIC(DIRECTOR, PLUGIN_TYPE_ENGINE, DirectorMetaEngine); +#endif diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h new file mode 100644 index 0000000000..65eff50fc9 --- /dev/null +++ b/engines/director/detection_tables.h @@ -0,0 +1,469 @@ +/* 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 DIRECTOR_DETECTION_TABLES_H +#define DIRECTOR_DETECTION_TABLES_H + +namespace Director { + +static const DirectorGameDescription gameDescriptions[] = { + { + { + "directortest", + "", + AD_ENTRY1("lingotests.lingo", 0), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_TEST, + 3 + }, + + { + { + "theapartment", + "", + AD_ENTRY1s("Main Menu", "9e838fe1a6af7992d656ca325e38dee5", 47911), + Common::EN_ANY, + Common::kPlatformMacintosh, + ADGF_MACRESFORK, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 3 + }, + + { + { + "gundam0079", + "", + AD_ENTRY1("Gundam0079.exe", "1a7acbba10a7246ba58c1d53fc7203f5"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 5 + }, + + { + { + "gundam0079", + "", + AD_ENTRY1("Gundam0079", "4c38a51a21a1ad231f218c4786ff771d"), + Common::EN_ANY, + Common::kPlatformMacintosh, + ADGF_MACRESFORK, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 5 + }, + + { + { + "jewels", + "", + AD_ENTRY1("JEWELS.EXE", "bb6d81471d166088260090472c6c3a87"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 4 + }, + + { + { + "jewels", + "", + AD_ENTRY1("Jewels.exe", "c1a2e8b7e41fa204009324a9c7db1030"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 7 + }, + + { + { + "jewels", + "Two-Minute Demo", + AD_ENTRY1("DEMO.EXE", "ebee52d3c4280674c600177df5b09da0"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_DEMO, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 4 + }, + + // Note: There are four versions of the binary included on the disc. + // 5.6, 6, and 9 Meg variants all exist too. + { + { + "jewels", + "", + AD_ENTRY1("Jewels 11 Meg", "339c89a148c4ff2c5c815c62ac006325"), + Common::EN_ANY, + Common::kPlatformMacintosh, + ADGF_MACRESFORK, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 4 + }, + + { + { + "jewels", + "Two-Minute Demo", + AD_ENTRY1("Two-Minute Demo", "01be45e7241194dad07938e7059b88e3"), + Common::EN_ANY, + Common::kPlatformMacintosh, + ADGF_MACRESFORK | ADGF_DEMO, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 4 + }, + + { + { + "jewels", + "", + AD_ENTRY1("Jewels of the Oracle", "fa52f0136cde568a46249ce74f01a324"), + Common::EN_ANY, + Common::kPlatformMacintosh, + ADGF_MACRESFORK, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 7 + }, + + { + { + "jewels", + "Demo", + AD_ENTRY1("JEWELS.EXE", "abcc448c035e88d4edb4a29034fd1e34"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS | ADGF_DEMO, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 4 + }, + + { + { + "jman", + "", + AD_ENTRY1s("JMAN.EXE", "7c8230a804abf9353b05627a675b5ffb", 375282), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 3 + }, + + { + { + "jman", + "", + AD_ENTRY1s("JMDEMO.EXE", "7c8230a804abf9353b05627a675b5ffb", 375305), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_DEMO, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 3 + }, + + { + { + "jman", + "", + AD_ENTRY1("JOURNEY.EXE", "65d06b5fef155a2473434571aff5bc29"), + Common::JA_JPN, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 3 + }, + + { + { + "jman", + "Turbo!", + AD_ENTRY1("JMP Turbo\xE2\x84\xA2", "cc3321069072b90f091f220bba16e4d4"), // Trademark symbol (UTF-8) + Common::EN_ANY, + Common::kPlatformMacintosh, + ADGF_MACRESFORK, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 4 + }, + + { + { + "majestic", + "", + AD_ENTRY1("MAJESTIC.EXE", "624267f70253e5327981003a6fc0aeba"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 4 + }, + + { + { + // Masters of the Elements - English (from rootfather) + // Developed by IJsfontein, published by Tivola + // File version of MVM.EXE is 6.0.2.32 + // The game disc is a hybrid CD-ROM containing both the Windows and the Macintosh release. + + "melements", "", + { + {"CHECK.DXR", 0, "c31ee30eebd24a8cf31691fc9926daa4", 901820}, + {"MVM.EXE", 0, 0, 2565921}, + AD_LISTEND + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 5 + }, + + { + { + // Masters of the Elements - English (from rootfather) + + "melements", "", + { + {"check.dxr", 0, "36f42340e819d1532c850880afe16581", 898206}, + {"Masters of the Elements", 0, 0, 1034962}, + AD_LISTEND + }, + Common::EN_ANY, + Common::kPlatformMacintosh, + ADGF_MACRESFORK, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 5 + }, + + { + { + // Masters of the Elements - German (from rootfather) + // Released in Germany as "Meister Zufall und die Herrscher der Elemente" + // Developed by IJsfontein, published by Tivola + // File version of MVM.EXE is 6.0.2.32 + // The game disc is a hybrid CD-ROM containing both the Windows and the Macintosh release. + + "melements", "", + { + {"CHECK.DXR", 0, "d1cd0ed95b0e30597e0089bf3e5caf0f", 575414}, + {"MVM.EXE", 0, 0, 1512503}, + AD_LISTEND + }, + Common::DE_DEU, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 5 + }, + + { + { + // Masters of the Elements - German (from rootfather) + + "melements", "", + { + {"check.dxr", 0, "9c81934b7616ab077f44825b8afaa83e", 575426}, + {"Meister Zufall", 0, 0, 1034962}, + AD_LISTEND + }, + Common::DE_DEU, + Common::kPlatformMacintosh, + ADGF_MACRESFORK, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 5 + }, + + { + { + "spyclub", + "", + AD_ENTRY1("SPYCLUB.EXE", "65d06b5fef155a2473434571aff5bc29"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 3 + }, + + { + { + "amber", + "", + AD_ENTRY1("amber_jb.exe", "1a7acbba10a7246ba58c1d53fc7203f5"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 5 + }, + + { + { + "vvvampire", + "", + AD_ENTRY1("VAMPIRE.EXE", "88f4f7406f34ec36e751a64f7c76f2c4"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 3 + }, + + { + { + "vvvampire", + "", + AD_ENTRY1("The Vampire's Coffin", "d41d8cd98f00b204e9800998ecf8427e"), + Common::EN_ANY, + Common::kPlatformMacintosh, + ADGF_MACRESFORK, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 3 + }, + + { + { + "vvdinosaur", + "", + AD_ENTRY1("DINOSAUR.EXE", "4e6303630f4dd588e730d09241cf7e76"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 3 + }, + + { + { + "vvdinosaur", + "", + AD_ENTRY1("Start Game", "d41d8cd98f00b204e9800998ecf8427e"), + Common::EN_ANY, + Common::kPlatformMacintosh, + ADGF_MACRESFORK, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 3 + }, + + { + { + "warlock", + "", + AD_ENTRY1s("Spaceship Warlock.bin", "cfa68a1bc49251497ebde18e5fc9c217", 271107), + Common::EN_ANY, + Common::kPlatformMacintosh, + ADGF_MACRESFORK, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 2 + }, + + { + { + "warlock", + "", + AD_ENTRY1s("SSWARLCK.EXE", "65d06b5fef155a2473434571aff5bc29", 370867), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 2 + }, + + { + { + "warlock", + "", + AD_ENTRY1s("SSWDEMO.EXE", "65d06b5fef155a2473434571aff5bc29", 370934), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_DEMO, + GUIO1(GUIO_NOASPECT) + }, + GID_GENERIC, + 2 + }, + + { AD_TABLE_END_MARKER, GID_GENERIC, 0 } +}; + +} // End of Namespace Director + +#endif diff --git a/engines/director/dib.cpp b/engines/director/dib.cpp new file mode 100644 index 0000000000..8c54ba5363 --- /dev/null +++ b/engines/director/dib.cpp @@ -0,0 +1,111 @@ +/* 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 "director/dib.h" + +#include "common/stream.h" +#include "common/substream.h" +#include "common/textconsole.h" +#include "graphics/pixelformat.h" +#include "graphics/surface.h" +#include "graphics/palette.h" +#include "image/codecs/codec.h" +#include "common/util.h" +#include "common/debug.h" +#include "image/codecs/bmp_raw.h" +#include "common/system.h" + +namespace Director { + +DIBDecoder::DIBDecoder() { + _surface = 0; + _palette = 0; + _paletteColorCount = 0; + _codec = 0; +} + +DIBDecoder::~DIBDecoder() { + destroy(); +} + +void DIBDecoder::destroy() { + _surface = 0; + + delete[] _palette; + _palette = 0; + _paletteColorCount = 0; + + delete _codec; + _codec = 0; +} + +void DIBDecoder::loadPalette(Common::SeekableReadStream &stream) { + uint16 steps = stream.size() / 6; + uint16 index = (steps * 3) - 1; + _paletteColorCount = steps; + _palette = new byte[index]; + + for (uint8 i = 0; i < steps; i++) { + _palette[index - 2] = stream.readByte(); + stream.readByte(); + + _palette[index - 1] = stream.readByte(); + stream.readByte(); + + _palette[index] = stream.readByte(); + stream.readByte(); + index -= 3; + } +} + +bool DIBDecoder::loadStream(Common::SeekableReadStream &stream) { + uint32 headerSize = stream.readUint32LE(); + if (headerSize != 40) + return false; + + uint32 width = stream.readUint32LE(); + uint32 height = stream.readUint32LE(); + stream.readUint16LE(); // planes + uint16 bitsPerPixel = stream.readUint16LE(); + uint32 compression = stream.readUint32BE(); + uint32 imageSize = stream.readUint32LE(); + /* uint32 pixelsPerMeterX = */ stream.readUint32LE(); + /* uint32 pixelsPerMeterY = */ stream.readUint32LE(); + _paletteColorCount = stream.readUint32LE(); + /* uint32 colorsImportant = */ stream.readUint32LE(); + + _paletteColorCount = (_paletteColorCount == 0) ? 255: _paletteColorCount; + + uint16 imageRawSize = stream.size() - 40; + Common::SeekableSubReadStream subStream(&stream, 40, stream.size()); + + _codec = Image::createBitmapCodec(compression, width, height, bitsPerPixel); + + if (!_codec) + return false; + + _surface = _codec->decodeFrame(subStream); + + return true; +} + +} // End of namespace Director diff --git a/engines/director/dib.h b/engines/director/dib.h new file mode 100644 index 0000000000..e3763be2bf --- /dev/null +++ b/engines/director/dib.h @@ -0,0 +1,67 @@ +/* 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 DIRECTOR_DIB_H +#define DIRECTOR_DIB_H + +#include "common/scummsys.h" +#include "common/str.h" +#include "image/image_decoder.h" +#include "image/codecs/bmp_raw.h" + +namespace Common { +class SeekableReadStream; +} + +namespace Graphics { +struct Surface; +} + +namespace Image { +class Codec; +} + +namespace Director { + +class DIBDecoder : public Image::ImageDecoder { +public: + DIBDecoder(); + virtual ~DIBDecoder(); + + // ImageDecoder API + void destroy(); + virtual bool loadStream(Common::SeekableReadStream &stream); + virtual const Graphics::Surface *getSurface() const { return _surface; } + const byte *getPalette() const { return _palette; } + void loadPalette(Common::SeekableReadStream &stream); + uint16 getPaletteColorCount() const { return _paletteColorCount; } + +private: + Image::Codec *_codec; + const Graphics::Surface *_surface; + byte *_palette; + uint8 _paletteColorCount; +}; + +} // End of namespace Director + +#endif diff --git a/engines/director/director.cpp b/engines/director/director.cpp new file mode 100644 index 0000000000..469aeb80cb --- /dev/null +++ b/engines/director/director.cpp @@ -0,0 +1,368 @@ +/* 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 "audio/mixer.h" + +#include "common/config-manager.h" +#include "common/debug.h" +#include "common/scummsys.h" +#include "common/error.h" +#include "common/events.h" +#include "common/macresman.h" +#include "common/stream.h" +#include "common/system.h" +#include "common/textconsole.h" +#include "common/fs.h" + +#include "engines/util.h" + +#include "graphics/surface.h" +#include "graphics/macgui/macwindowmanager.h" + +#include "director/director.h" +#include "director/dib.h" +#include "director/resource.h" +#include "director/score.h" +#include "director/lingo/lingo.h" +#include "director/sound.h" + +namespace Director { + +DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), + _rnd("director") { + if (!_mixer->isReady()) + error("Sound initialization failed"); + + // Setup mixer + syncSoundSettings(); + + _sharedCasts = nullptr; + _sharedSound = nullptr; + _sharedBMP = nullptr; + _sharedSTXT = nullptr; + _sharedDIB = nullptr; + + _mainArchive = nullptr; + _macBinary = nullptr; + + _movies = nullptr; + + _wm = nullptr; + + const Common::FSNode gameDataDir(ConfMan.get("path")); + SearchMan.addSubDirectoryMatching(gameDataDir, "data"); + SearchMan.addSubDirectoryMatching(gameDataDir, "install"); +} + +DirectorEngine::~DirectorEngine() { + delete _sharedCasts; + delete _sharedSound; + delete _sharedBMP; + delete _sharedSTXT; + delete _sharedDIB; + delete _movies; + + delete _mainArchive; + delete _macBinary; + delete _soundManager; + delete _lingo; + delete _currentScore; + delete _currentPalette; +} + +Common::Error DirectorEngine::run() { + debug("Starting v%d Director game", getVersion()); + + //FIXME + _sharedMMM = "SHARDCST.MMM"; + + _currentPalette = nullptr; + + _macBinary = nullptr; + _soundManager = nullptr; + + _wm = new Graphics::MacWindowManager; + + _lingo = new Lingo(this); + _soundManager = new DirectorSound(); + + if (getGameID() == GID_TEST) { + _mainArchive = nullptr; + _currentScore = nullptr; + + _lingo->runTests(); + + return Common::kNoError; + } + + //FIXME + //_mainArchive = new RIFFArchive(); + //_mainArchive->openFile("bookshelf_example.mmm"); + + if (getPlatform() == Common::kPlatformWindows) + loadEXE(); + else + loadMac(); + + _currentScore = new Score(this); + debug(0, "Score name %s", _currentScore->getMacName().c_str()); + + _currentScore->loadArchive(); + _currentScore->startLoop(); + + return Common::kNoError; +} + +Common::HashMap<Common::String, Score *> DirectorEngine::loadMMMNames(Common::String folder) { + Common::FSNode directory(folder); + Common::FSList movies; + + Common::HashMap<Common::String, Score *> nameMap; + directory.getChildren(movies, Common::FSNode::kListFilesOnly); + + if (!movies.empty()) { + for (Common::FSList::const_iterator i = movies.begin(); i != movies.end(); ++i) { + if (i->getName() == _sharedMMM) { + loadSharedCastsFrom(i->getPath()); + continue; + } + + RIFFArchive *arc = new RIFFArchive(); + arc->openFile(i->getPath()); + Score *sc = new Score(this); + nameMap[sc->getMacName()] = sc; + } + } + + return nameMap; +} + +void DirectorEngine::loadEXE() { + Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(getEXEName()); + if (!exeStream) + error("Failed to open EXE '%s'", getEXEName().c_str()); + + _lingo->processEvent(kEventStart, 0); + + exeStream->seek(-4, SEEK_END); + exeStream->seek(exeStream->readUint32LE()); + + switch (getVersion()) { + case 3: + loadEXEv3(exeStream); + break; + case 4: + loadEXEv4(exeStream); + break; + case 5: + loadEXEv5(exeStream); + break; + case 7: + loadEXEv7(exeStream); + break; + default: + error("Unhandled Windows EXE version %d", getVersion()); + } +} + +void DirectorEngine::loadEXEv3(Common::SeekableReadStream *stream) { + uint16 entryCount = stream->readUint16LE(); + if (entryCount != 1) + error("Unhandled multiple entry v3 EXE"); + + stream->skip(5); // unknown + + stream->readUint32LE(); // Main MMM size + Common::String mmmFileName = readPascalString(*stream); + Common::String directoryName = readPascalString(*stream); + + debug("Main MMM: '%s'", mmmFileName.c_str()); + debug("Directory Name: '%s'", directoryName.c_str()); + + _mainArchive = new RIFFArchive(); + + if (!_mainArchive->openFile(mmmFileName)) + error("Could not open '%s'", mmmFileName.c_str()); + + delete stream; +} + +void DirectorEngine::loadEXEv4(Common::SeekableReadStream *stream) { + if (stream->readUint32BE() != MKTAG('P', 'J', '9', '3')) + error("Invalid projector tag found in v4 EXE"); + + uint32 rifxOffset = stream->readUint32LE(); + /* uint32 fontMapOffset = */ stream->readUint32LE(); + /* uint32 resourceForkOffset1 = */ stream->readUint32LE(); + /* uint32 resourceForkOffset2 = */ stream->readUint32LE(); + stream->readUint32LE(); // graphics DLL offset + stream->readUint32LE(); // sound DLL offset + /* uint32 rifxOffsetAlt = */ stream->readUint32LE(); // equivalent to rifxOffset + + loadEXERIFX(stream, rifxOffset); +} + +void DirectorEngine::loadEXEv5(Common::SeekableReadStream *stream) { + if (stream->readUint32LE() != MKTAG('P', 'J', '9', '5')) + error("Invalid projector tag found in v5 EXE"); + + uint32 rifxOffset = stream->readUint32LE(); + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + /* uint16 screenWidth = */ stream->readUint16LE(); + /* uint16 screenHeight = */ stream->readUint16LE(); + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + /* uint32 fontMapOffset = */ stream->readUint32LE(); + + loadEXERIFX(stream, rifxOffset); +} + +void DirectorEngine::loadEXEv7(Common::SeekableReadStream *stream) { + if (stream->readUint32LE() != MKTAG('P', 'J', '0', '0')) + error("Invalid projector tag found in v7 EXE"); + + uint32 rifxOffset = stream->readUint32LE(); + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + stream->readUint32LE(); // some DLL offset + + loadEXERIFX(stream, rifxOffset); +} + +void DirectorEngine::loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset) { + _mainArchive = new RIFXArchive(); + + if (!_mainArchive->openStream(stream, offset)) + error("Failed to load RIFX from EXE"); +} + +void DirectorEngine::loadMac() { + if (getVersion() < 4) { + // The data is part of the resource fork of the executable + _mainArchive = new MacArchive(); + + if (!_mainArchive->openFile(getEXEName())) + error("Failed to open Mac binary '%s'", getEXEName().c_str()); + } else { + // The RIFX is located in the data fork of the executable + _macBinary = new Common::MacResManager(); + + if (!_macBinary->open(getEXEName()) || !_macBinary->hasDataFork()) + error("Failed to open Mac binary '%s'", getEXEName().c_str()); + + Common::SeekableReadStream *dataFork = _macBinary->getDataFork(); + _mainArchive = new RIFXArchive(); + + // First we need to detect PPC vs. 68k + + uint32 tag = dataFork->readUint32BE(); + uint32 startOffset; + + if (SWAP_BYTES_32(tag) == MKTAG('P', 'J', '9', '3') || tag == MKTAG('P', 'J', '9', '5') || tag == MKTAG('P', 'J', '0', '0')) { + // PPC: The RIFX shares the data fork with the binary + startOffset = dataFork->readUint32BE(); + } else { + // 68k: The RIFX is the only thing in the data fork + startOffset = 0; + } + + if (!_mainArchive->openStream(dataFork, startOffset)) + error("Failed to load RIFX from Mac binary"); + } +} + +Common::String DirectorEngine::readPascalString(Common::SeekableReadStream &stream) { + byte length = stream.readByte(); + Common::String x; + + while (length--) + x += (char)stream.readByte(); + + return x; +} + +void DirectorEngine::setPalette(byte *palette, uint16 count) { + _currentPalette = palette; + _currentPaletteLength = count; +} + +void DirectorEngine::loadSharedCastsFrom(Common::String filename) { + Archive *shardcst; + + if (getVersion() < 4) { + shardcst = new RIFFArchive(); + } else { + shardcst = new RIFXArchive(); + } + + shardcst->openFile(filename); + + Score *castScore = new Score(this); + Common::SeekableSubReadStreamEndian *castStream = shardcst->getResource(MKTAG('V','W','C','R'), 1024); + + castScore->loadCastData(*castStream); + *_sharedCasts = castScore->_casts; + + Common::Array<uint16> dib = shardcst->getResourceIDList(MKTAG('D','I','B',' ')); + + if (dib.size() != 0) { + Common::Array<uint16>::iterator iterator; + for (iterator = dib.begin(); iterator != dib.end(); ++iterator) { + debug(3, "Shared DIB %d", *iterator); + _sharedDIB->setVal(*iterator, shardcst->getResource(MKTAG('D','I','B',' '), *iterator)); + } + } + + Common::Array<uint16> stxt = shardcst->getResourceIDList(MKTAG('S','T','X','T')); + + if (stxt.size() != 0) { + Common::Array<uint16>::iterator iterator; + for (iterator = stxt.begin(); iterator != stxt.end(); ++iterator) { + debug(3, "Shared STXT %d", *iterator); + _sharedSTXT->setVal(*iterator, shardcst->getResource(MKTAG('S','T','X','T'), *iterator)); + } + } + + Common::Array<uint16> bmp = shardcst->getResourceIDList(MKTAG('B','I','T','D')); + + if (bmp.size() != 0) { + Common::Array<uint16>::iterator iterator; + for (iterator = bmp.begin(); iterator != bmp.end(); ++iterator) { + _sharedBMP->setVal(*iterator, shardcst->getResource(MKTAG('B','I','T','D'), *iterator)); + } + } + + Common::Array<uint16> sound = shardcst->getResourceIDList(MKTAG('S','N','D',' ')); + + if (stxt.size() != 0) { + Common::Array<uint16>::iterator iterator; + for (iterator = sound.begin(); iterator != sound.end(); ++iterator) { + _sharedSound->setVal(*iterator, shardcst->getResource(MKTAG('S','N','D',' '), *iterator)); + } + } +} + +} // End of namespace Director diff --git a/engines/director/director.h b/engines/director/director.h new file mode 100644 index 0000000000..6208df2197 --- /dev/null +++ b/engines/director/director.h @@ -0,0 +1,122 @@ +/* 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 DIRECTOR_DIRECTOR_H +#define DIRECTOR_DIRECTOR_H + +#include "common/scummsys.h" +#include "common/random.h" +#include "common/substream.h" + +#include "common/str.h" +#include "common/hashmap.h" +#include "engines/engine.h" +#include "engines/director/sound.h" + +namespace Common { +class MacResManager; +} + +namespace Graphics { +class MacWindowManager; +} + +namespace Director { + +enum DirectorGameID { + GID_GENERIC, + GID_TEST +}; + +class Archive; +struct DirectorGameDescription; +class Lingo; +class Score; +struct Cast; + +class DirectorEngine : public ::Engine { +public: + DirectorEngine(OSystem *syst, const DirectorGameDescription *gameDesc); + ~DirectorEngine(); + + // Detection related functions + + DirectorGameID getGameID() const; + uint16 getVersion() const; + Common::Platform getPlatform() const; + Common::Language getLanguage() const; + Common::String getEXEName() const; + DirectorSound *getSoundManager() const { return _soundManager; } + Archive *getMainArchive() const { return _mainArchive; } + Lingo *getLingo() const { return _lingo; } + Score *getCurrentScore() const { return _currentScore; } + void setPalette(byte *palette, uint16 count); + bool hasFeature(EngineFeature f) const; + const byte *getPalette() const { return _currentPalette; } + uint16 getPaletteColorCount() const { return _currentPaletteLength; } + void loadSharedCastsFrom(Common::String filename); + Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedDIB() const { return _sharedDIB; } + Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedBMP() const { return _sharedBMP; } + Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedSTXT() const { return _sharedSTXT; } + Common::HashMap<int, Cast *> *getSharedCasts() const { return _sharedCasts; } + + Common::HashMap<Common::String, Score *> *_movies; + Score *_currentScore; + + Common::RandomSource _rnd; + Graphics::MacWindowManager *_wm; + +protected: + virtual Common::Error run(); + +private: + const DirectorGameDescription *_gameDescription; + + Common::HashMap<Common::String, Score *> loadMMMNames(Common::String folder); + void loadEXE(); + void loadEXEv3(Common::SeekableReadStream *stream); + void loadEXEv4(Common::SeekableReadStream *stream); + void loadEXEv5(Common::SeekableReadStream *stream); + void loadEXEv7(Common::SeekableReadStream *stream); + void loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset); + void loadMac(); + + Common::String readPascalString(Common::SeekableReadStream &stream); + + Common::String _sharedMMM; + Common::HashMap<int, Cast *> *_sharedCasts; + Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *_sharedDIB; + Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *_sharedSTXT; + Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *_sharedSound; + Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *_sharedBMP; + + Archive *_mainArchive; + Common::MacResManager *_macBinary; + DirectorSound *_soundManager; + byte *_currentPalette; + uint16 _currentPaletteLength; + Lingo *_lingo; +}; + +} // End of namespace Director + +#endif diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp new file mode 100644 index 0000000000..de829560f1 --- /dev/null +++ b/engines/director/lingo/lingo-builtins.cpp @@ -0,0 +1,717 @@ +/* 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 "engines/director/lingo/lingo.h" + +namespace Director { + +static struct BuiltinProto { + const char *name; + void (*func)(int); + int minArgs; + int maxArgs; + bool parens; +} builtins[] = { + // Math + { "abs", Lingo::b_abs, 1, 1, true }, // D2 + { "atan", Lingo::b_atan, 1, 1, true }, // D4 + { "cos", Lingo::b_cos, 1, 1, true }, // D4 + { "exp", Lingo::b_exp, 1, 1, true }, // D4 + { "float", Lingo::b_float, 1, 1, true }, // D4 + { "integer",Lingo::b_integer, 1, 1, true }, + { "log", Lingo::b_log, 1, 1, true }, // D4 + { "pi", Lingo::b_pi, 0, 0, true }, // D4 + { "power", Lingo::b_power, 2, 2, true }, // D4 + { "random", Lingo::b_random, 1, 1, true }, // D2 + { "sin", Lingo::b_sin, 1, 1, true }, + { "sqrt", Lingo::b_sqrt, 1, 1, true }, // D2 + { "tan", Lingo::b_tan, 1, 1, true }, // D4 + // String + { "chars", Lingo::b_chars, 3, 3, true }, // D2 + { "length", Lingo::b_length, 1, 1, true }, // D2 + { "string", Lingo::b_string, 1, 1, true }, // D2 + // Files + { "closeDA", Lingo::b_closeDA, 0, 0, false }, // D2 + { "closeResFile", Lingo::b_closeResFile, 0, 1, false }, // D2 + { "closeXlib", Lingo::b_closeXlib, 0, 1, false }, // D2 + // open // D2 + { "openDA", Lingo::b_openDA, 1, 1, false }, // D2 + { "openResFile", Lingo::b_openResFile, 1, 1, false }, // D2 + { "openXlib", Lingo::b_openXlib, 1, 1, false }, // D2 + { "showResFile", Lingo::b_showResFile, 0, 1, false }, // D2 + { "showXlib", Lingo::b_showXlib, 0, 1, false }, // D2 + // Control + { "continue", Lingo::b_continue, 0, 0, false }, // D2 + { "dontPassEvent", Lingo::b_dontPassEvent, 0, 0, false }, // D2 + { "delay", Lingo::b_delay, 1, 1, false }, // D2 + { "do", Lingo::b_do, 1, 1, false }, // D2 + { "nothing", Lingo::b_nothing, 0, 0, false }, // D2 + { "pause", Lingo::b_pause, 0, 0, false }, // D2 + // play // D2 + { "playAccel", Lingo::b_playAccel, -1,0, false }, // D2 + // play done // D2 + { "quit", Lingo::b_quit, 0, 0, false }, // D2 + { "restart", Lingo::b_restart, 0, 0, false }, // D2 + { "shutDown", Lingo::b_shutDown, 0, 0, false }, // D2 + { "startTimer", Lingo::b_startTimer, 0, 0, false }, // D2 + // when keyDown // D2 + // when mouseDown // D2 + // when mouseUp // D2 + // when timeOut // D2 + // Misc + { "alert", Lingo::b_alert, 1, 1, false }, // D2 + { "cursor", Lingo::b_cursor, 1, 1, false }, // D2 + { "printFrom", Lingo::b_printFrom, -1,0, false }, // D2 + { "ilk", Lingo::b_ilk, 1, 2, true }, // D4 + // put // D2 + // set // D2 + { "showGlobals", Lingo::b_showGlobals, 0, 0, false }, // D2 + { "showLocals", Lingo::b_showLocals, 0, 0, false }, // D2 + // Score + { "editableText", Lingo::b_editableText, 0, 0, false }, // D2 + // go // D2 + { "installMenu", Lingo::b_installMenu, 1, 1, false }, // D2 + { "moveableSprite", Lingo::b_moveableSprite,0, 0, false }, // D2 + { "puppetPalette", Lingo::b_puppetPalette, -1,0, false }, // D2 + { "puppetSound", Lingo::b_puppetSound, -1,0, false }, // D2 + { "puppetSprite", Lingo::b_puppetSprite, -1,0, false }, // D2 + { "puppetTempo", Lingo::b_puppetTempo, 1, 1, false }, // D2 + { "puppetTransition",Lingo::b_puppetTransition,-1,0, false },// D2 + { "spriteBox", Lingo::b_spriteBox, -1,0, false }, // D2 + { "updateStage", Lingo::b_updateStage, 0, 0, false }, // D2 + { "zoomBox", Lingo::b_zoomBox, -1,0, false }, // D2 + // Point + { "point", Lingo::b_point, 2, 2, true }, + // Sound + { "beep", Lingo::b_beep, 0, 1, false }, // D2 + { "mci", Lingo::b_mci, 1, 1, false }, + { "mciwait", Lingo::b_mciwait, 1, 1, false }, + // Constants + { "backspace", Lingo::b_backspace, 0, 0, false }, // D2 + { "empty", Lingo::b_empty, 0, 0, false }, // D2 + { "enter", Lingo::b_enter, 0, 0, false }, // D2 + { "false", Lingo::b_false, 0, 0, false }, // D2 + { "quote", Lingo::b_quote, 0, 0, false }, // D2 + { "return", Lingo::b_return, 0, 0, false }, // D2 + { "tab", Lingo::b_tab, 0, 0, false }, // D2 + { "true", Lingo::b_true, 0, 0, false }, // D2 + + { 0, 0, 0, 0, false } +}; + +void Lingo::initBuiltIns() { + for (BuiltinProto *blt = builtins; blt->name; blt++) { + Symbol *sym = new Symbol; + + sym->name = (char *)calloc(strlen(blt->name) + 1, 1); + Common::strlcpy(sym->name, blt->name, strlen(blt->name)); + sym->type = BLTIN; + sym->nargs = blt->minArgs; + sym->maxArgs = blt->maxArgs; + sym->parens = blt->parens; + sym->u.bltin = blt->func; + + _handlers[blt->name] = sym; + } +} + +void Lingo::printStubWithArglist(const char *funcname, int nargs) { + Common::String s(funcname); + + s += '('; + + for (int i = 0; i < nargs; i++) { + Datum d = _stack[_stack.size() - nargs + i]; + + d.toString(); + s += *d.u.s; + + if (i != nargs - 1) + s += ", "; + } + + s += ")"; + + warning("STUB: %s", s.c_str()); +} + +void Lingo::convertVOIDtoString(int arg, int nargs) { + if (_stack[_stack.size() - nargs + arg].type == VOID) { + if (_stack[_stack.size() - nargs + arg].u.s != NULL) + g_lingo->_stack[_stack.size() - nargs + arg].type = STRING; + else + warning("Incorrect convertVOIDtoString for arg %d of %d", arg, nargs); + } +} + +void Lingo::dropStack(int nargs) { + for (int i = 0; i < nargs; i++) + pop(); +} + + +/////////////////// +// Math +/////////////////// +void Lingo::b_abs(int nargs) { + Datum d = g_lingo->pop(); + + if (d.type == INT) + d.u.i = ABS(d.u.i); + else if (d.type == FLOAT) + d.u.f = ABS(d.u.f); + + g_lingo->push(d); +} + +void Lingo::b_atan(int nargs) { + Datum d = g_lingo->pop(); + d.toFloat(); + d.u.f = atan(d.u.f); + g_lingo->push(d); +} + +void Lingo::b_cos(int nargs) { + Datum d = g_lingo->pop(); + d.toFloat(); + d.u.f = cos(d.u.f); + g_lingo->push(d); +} + +void Lingo::b_exp(int nargs) { + Datum d = g_lingo->pop(); + d.toInt(); // Lingo uses int, so we're enforcing it + d.toFloat(); + d.u.f = exp(d.u.f); + g_lingo->push(d); +} + +void Lingo::b_float(int nargs) { + Datum d = g_lingo->pop(); + d.toFloat(); + g_lingo->push(d); +} + +void Lingo::b_integer(int nargs) { + Datum d = g_lingo->pop(); + d.toInt(); + g_lingo->push(d); +} + +void Lingo::b_log(int nargs) { + Datum d = g_lingo->pop(); + d.toFloat(); + d.u.f = log(d.u.f); + g_lingo->push(d); +} + +void Lingo::b_pi(int nargs) { + Datum d; + d.toFloat(); + d.u.f = M_PI; + g_lingo->push(d); +} + +void Lingo::b_power(int nargs) { + Datum d1 = g_lingo->pop(); + Datum d2 = g_lingo->pop(); + d1.toFloat(); + d2.toFloat(); + d1.u.f = pow(d2.u.f, d1.u.f); + g_lingo->push(d1); +} + +void Lingo::b_random(int nargs) { + Datum max = g_lingo->pop(); + Datum res; + + max.toInt(); + + res.u.i = g_lingo->_vm->_rnd.getRandomNumber(max.u.i); + res.type = INT; + + g_lingo->push(res); +} + +void Lingo::b_sin(int nargs) { + Datum d = g_lingo->pop(); + d.toFloat(); + d.u.f = sin(d.u.f); + g_lingo->push(d); +} + +void Lingo::b_sqrt(int nargs) { + Datum d = g_lingo->pop(); + d.toFloat(); + d.u.f = sqrt(d.u.f); + g_lingo->push(d); +} + +void Lingo::b_tan(int nargs) { + Datum d = g_lingo->pop(); + d.toFloat(); + d.u.f = tan(d.u.f); + g_lingo->push(d); +} + +/////////////////// +// String +/////////////////// +void Lingo::b_chars(int nargs) { + Datum to = g_lingo->pop(); + Datum from = g_lingo->pop(); + Datum s = g_lingo->pop(); + + if (s.type != STRING) + error("Incorrect type for 'chars' function: %s", s.type2str()); + + to.toInt(); + from.toInt(); + + int len = strlen(s.u.s->c_str()); + int f = MAX(0, MIN(len, from.u.i - 1)); + int t = MAX(0, MIN(len, to.u.i)); + + Common::String *res = new Common::String(&(s.u.s->c_str()[f]), &(s.u.s->c_str()[t])); + + delete s.u.s; + + s.u.s = res; + s.type = STRING; + g_lingo->push(s); +} + +void Lingo::b_length(int nargs) { + Datum d = g_lingo->pop(); + + if (d.type != STRING) + error("Incorrect type for 'length' function: %s", d.type2str()); + + int len = strlen(d.u.s->c_str()); + delete d.u.s; + + d.u.i = len; + d.type = INT; + g_lingo->push(d); +} + +void Lingo::b_string(int nargs) { + Datum d = g_lingo->pop(); + d.toString(); + g_lingo->push(d); +} + +/////////////////// +// Files +/////////////////// +void Lingo::b_closeDA(int nargs) { + warning("STUB: b_closeDA"); +} + +void Lingo::b_closeResFile(int nargs) { + Datum d = g_lingo->pop(); + + d.toString(); + + warning("STUB: b_closeResFile(%s)", d.u.s->c_str()); + + delete d.u.s; +} + +void Lingo::b_closeXlib(int nargs) { + Datum d = g_lingo->pop(); + + d.toString(); + + warning("STUB: b_closeXlib(%s)", d.u.s->c_str()); + + delete d.u.s; +} + +void Lingo::b_openDA(int nargs) { + Datum d = g_lingo->pop(); + + d.toString(); + + warning("STUB: b_openDA(%s)", d.u.s->c_str()); + + delete d.u.s; +} + +void Lingo::b_openResFile(int nargs) { + Datum d = g_lingo->pop(); + + d.toString(); + + warning("STUB: b_openResFile(%s)", d.u.s->c_str()); + + delete d.u.s; +} + +void Lingo::b_openXlib(int nargs) { + Datum d = g_lingo->pop(); + + d.toString(); + + warning("STUB: b_openXlib(%s)", d.u.s->c_str()); + + delete d.u.s; +} + +void Lingo::b_showResFile(int nargs) { + Datum d = g_lingo->pop(); + + d.toString(); + + warning("STUB: b_showResFile(%s)", d.u.s->c_str()); + + delete d.u.s; +} + +void Lingo::b_showXlib(int nargs) { + Datum d = g_lingo->pop(); + + d.toString(); + + warning("STUB: b_showXlib(%s)", d.u.s->c_str()); + + delete d.u.s; +} + +/////////////////// +// Control +/////////////////// +void Lingo::b_dontPassEvent(int nargs) { + warning("STUB: b_dontPassEvent"); +} + +void Lingo::b_continue(int nargs) { + warning("STUB: b_continue"); +} + +void Lingo::b_nothing(int nargs) { + warning("STUB: b_nothing"); +} + +void Lingo::b_delay(int nargs) { + Datum d = g_lingo->pop(); + d.toInt(); + warning("STUB: b_delay(%d)", d.u.i); +} + +void Lingo::b_do(int nargs) { + Datum d = g_lingo->pop(); + d.toString(); + warning("STUB: b_do(%s)", d.u.s->c_str()); +} + +void Lingo::b_pause(int nargs) { + warning("STUB: b_pause"); +} + +void Lingo::b_playAccel(int nargs) { + g_lingo->printStubWithArglist("b_playAccel", nargs); + + g_lingo->dropStack(nargs); +} + +void Lingo::b_printFrom(int nargs) { + g_lingo->printStubWithArglist("b_printFrom", nargs); + + g_lingo->dropStack(nargs); +} + +void Lingo::b_quit(int nargs) { + warning("STUB: b_quit"); +} + +void Lingo::b_restart(int nargs) { + warning("STUB: b_restart"); +} + +void Lingo::b_shutDown(int nargs) { + warning("STUB: b_shutDown"); +} + +void Lingo::b_startTimer(int nargs) { + warning("STUB: b_startTimer"); +} + + +/////////////////// +// Misc +/////////////////// +void Lingo::b_ilk(int nargs) { + Datum d = g_lingo->pop(); + d.u.i = d.type; + d.type = SYMBOL; + g_lingo->push(d); +} + +void Lingo::b_alert(int nargs) { + Datum d = g_lingo->pop(); + + d.toString(); + + warning("STUB: b_alert"); + + delete d.u.s; +} + +void Lingo::b_cursor(int nargs) { + Datum d = g_lingo->pop(); + d.toInt(); + warning("STUB: b_cursor(%d)", d.u.i); +} + +void Lingo::b_showGlobals(int nargs) { + warning("STUB: b_showGlobals"); +} + +void Lingo::b_showLocals(int nargs) { + warning("STUB: b_showLocals"); +} + + + +/////////////////// +// Score +/////////////////// +void Lingo::b_updateStage(int nargs) { + warning("STUB: b_updateStage"); +} + +void Lingo::b_editableText(int nargs) { + warning("STUB: b_editableText"); +} + +void Lingo::b_installMenu(int nargs) { + Datum d = g_lingo->pop(); + warning("STUB: b_installMenu(%d)", d.u.i); +} + +void Lingo::b_moveableSprite(int nargs) { + Datum d = g_lingo->pop(); + warning("STUB: b_moveableSprite(%d)", d.u.i); +} + +void Lingo::b_puppetPalette(int nargs) { + g_lingo->convertVOIDtoString(0, nargs); + + g_lingo->printStubWithArglist("b_puppetPalette", nargs); + + g_lingo->dropStack(nargs); +} + +void Lingo::b_puppetSound(int nargs) { + g_lingo->convertVOIDtoString(0, nargs); + + g_lingo->printStubWithArglist("b_puppetSound", nargs); + + g_lingo->dropStack(nargs); +} + +void Lingo::b_puppetSprite(int nargs) { + g_lingo->printStubWithArglist("b_puppetSprite", nargs); + + g_lingo->dropStack(nargs); +} + +void Lingo::b_puppetTempo(int nargs) { + Datum d = g_lingo->pop(); + warning("STUB: b_puppetTempo(%d)", d.u.i); +} + +void Lingo::b_puppetTransition(int nargs) { + g_lingo->printStubWithArglist("b_puppetTransition", nargs); + + g_lingo->dropStack(nargs); +} + +void Lingo::b_spriteBox(int nargs) { + g_lingo->printStubWithArglist("b_spriteBox", nargs); + + g_lingo->dropStack(nargs); +} + +void Lingo::b_zoomBox(int nargs) { + g_lingo->printStubWithArglist("b_zoomBox", nargs); + + g_lingo->dropStack(nargs); +} + + + +/////////////////// +// Point +/////////////////// +void Lingo::b_point(int nargs) { + Datum y = g_lingo->pop(); + Datum x = g_lingo->pop(); + Datum d; + + x.toFloat(); + y.toFloat(); + + d.u.arr = new FloatArray; + + d.u.arr->push_back(x.u.f); + d.u.arr->push_back(y.u.f); + d.type = POINT; + + g_lingo->push(d); +} + + +/////////////////// +// Sound +/////////////////// +void Lingo::b_beep(int nargs) { + Datum d = g_lingo->pop(); + warning("STUB: b_beep(%d)", d.u.i); +} + +void Lingo::b_mci(int nargs) { + Datum d = g_lingo->pop(); + + d.toString(); + + g_lingo->func_mci(*d.u.s); +} + +void Lingo::b_mciwait(int nargs) { + Datum d = g_lingo->pop(); + + d.toString(); + + g_lingo->func_mciwait(*d.u.s); +} + +/////////////////// +// Constants +/////////////////// +void Lingo::b_backspace(int nargs) { + Datum d; + + d.type = STRING; + d.u.s = new Common::String("\b"); + + g_lingo->push(d); +} + +void Lingo::b_empty(int nargs) { + Datum d; + + d.type = STRING; + d.u.s = new Common::String(""); + + g_lingo->push(d); +} + +void Lingo::b_enter(int nargs) { + Datum d; + + d.type = STRING; + d.u.s = new Common::String("\n"); + + g_lingo->push(d); +} + +void Lingo::b_false(int nargs) { + Datum d; + + d.type = INT; + d.u.i = 0; + + g_lingo->push(d); +} + +void Lingo::b_quote(int nargs) { + Datum d; + + d.type = STRING; + d.u.s = new Common::String("\""); + + g_lingo->push(d); +} + +void Lingo::b_return(int nargs) { + Datum d; + + d.type = STRING; + d.u.s = new Common::String("\r"); + + g_lingo->push(d); +} + +void Lingo::b_tab(int nargs) { + Datum d; + + d.type = STRING; + d.u.s = new Common::String("\t"); + + g_lingo->push(d); +} + +void Lingo::b_true(int nargs) { + Datum d; + + d.type = INT; + d.u.i = 1; + + g_lingo->push(d); +} + +/////////////////// +// Factory +/////////////////// +void Lingo::b_factory(int nargs) { + // This is intentionally empty +} + +void Lingo::factoryCall(Common::String &name, int nargs) { + Common::String s("factoryCall: "); + + s += name; + + convertVOIDtoString(0, nargs); + + printStubWithArglist(s.c_str(), nargs); + + Datum method = _stack[_stack.size() - nargs + 0]; + + s = name + "-" + *method.u.s; + + call(s, nargs); + + if (method.u.s->compareToIgnoreCase("mNew")) { + warning("Got mNew method"); + Datum d; + + d.type = OBJECT; + d.u.s = new Common::String(name); + + g_lingo->push(d); + } +} + +} // End of namespace Director diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp new file mode 100644 index 0000000000..646a9316c3 --- /dev/null +++ b/engines/director/lingo/lingo-code.cpp @@ -0,0 +1,851 @@ +/* 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. + * + */ + +// Heavily inspired by hoc +// Copyright (C) AT&T 1995 +// All Rights Reserved +// +// Permission to use, copy, modify, and distribute this software and +// its documentation for any purpose and without fee is hereby +// granted, provided that the above copyright notice appear in all +// copies and that both that the copyright notice and this +// permission notice and warranty disclaimer appear in supporting +// documentation, and that the name of AT&T or any of its entities +// not be used in advertising or publicity pertaining to +// distribution of the software without specific, written prior +// permission. +// +// AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +// IN NO EVENT SHALL AT&T OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +// SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +// IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +// THIS SOFTWARE. + +#include "engines/director/lingo/lingo.h" +#include "common/file.h" +#include "audio/decoders/wave.h" + +#include "director/lingo/lingo-gr.h" + +namespace Director { + +void Lingo::push(Datum d) { + _stack.push_back(d); +} + +void Lingo::pushVoid() { + Datum d; + d.u.s = NULL; + d.type = VOID; + push(d); +} + +Datum Lingo::pop(void) { + if (_stack.size() == 0) + error("stack underflow"); + + Datum ret = _stack.back(); + _stack.pop_back(); + + return ret; +} + +void Lingo::c_xpop() { + g_lingo->pop(); +} + +void Lingo::c_printtop(void) { + Datum d = g_lingo->pop(); + + switch (d.type) { + case VOID: + warning("Void, came from %s", d.u.s ? d.u.s->c_str() : "<>"); + break; + case INT: + warning("%d", d.u.i); + break; + case FLOAT: + warning(g_lingo->_floatPrecisionFormat.c_str(), d.u.f); + break; + case VAR: + if (!d.u.sym) { + warning("Inconsistent stack: var, val: %d", d.u.i); + } else { + if (d.u.sym->name) + warning("var: %s", d.u.sym->name); + else + warning("Nameless var. val: %d", d.u.sym->u.i); + } + break; + case STRING: + warning("%s", d.u.s->c_str()); + break; + case POINT: + warning("point(%d, %d)", (int)((*d.u.arr)[0]), (int)((*d.u.arr)[1])); + break; + case SYMBOL: + warning("%s", d.type2str(true)); + break; + default: + warning("--unknown--"); + } +} + +void Lingo::c_constpush() { + Datum d; + inst i = (*g_lingo->_currentScript)[g_lingo->_pc++]; + d.u.i = READ_UINT32(&i); + d.type = INT; + g_lingo->push(d); +} + +void Lingo::c_voidpush() { + Datum d; + d.u.s = NULL; + d.type = VOID; + g_lingo->push(d); +} + +void Lingo::c_fconstpush() { + Datum d; + inst i = (*g_lingo->_currentScript)[g_lingo->_pc]; + d.u.f = *((double *)&i); + d.type = FLOAT; + + g_lingo->_pc += g_lingo->calcCodeAlignment(sizeof(double)); + + g_lingo->push(d); +} + +void Lingo::c_stringpush() { + Datum d; + char *s = (char *)&(*g_lingo->_currentScript)[g_lingo->_pc]; + g_lingo->_pc += g_lingo->calcStringAlignment(s); + + d.u.s = new Common::String(s); + d.type = STRING; + g_lingo->push(d); +} + +void Lingo::c_varpush() { + char *name = (char *)&(*g_lingo->_currentScript)[g_lingo->_pc]; + Datum d; + + d.u.sym = g_lingo->lookupVar(name); + if (d.u.sym->type == CASTREF) { + d.type = INT; + int val = d.u.sym->u.i; + + delete d.u.sym; + + d.u.i = val; + } else { + d.type = VAR; + } + + g_lingo->_pc += g_lingo->calcStringAlignment(name); + + g_lingo->push(d); +} + +void Lingo::c_assign() { + Datum d1, d2; + d1 = g_lingo->pop(); + d2 = g_lingo->pop(); + + if (d1.type != VAR) { + warning("assignment to non-variable"); + return; + } + + if (d1.u.sym->type != INT && d1.u.sym->type != VOID && + d1.u.sym->type != FLOAT && d1.u.sym->type != STRING) { + warning("assignment to non-variable '%s'", d1.u.sym->name); + return; + } + + if ((d1.u.sym->type == STRING || d1.u.sym->type == VOID) && d1.u.sym->u.s) // Free memory if needed + delete d1.u.sym->u.s; + + if (d1.u.sym->type == POINT || d1.u.sym->type == RECT || d1.u.sym->type == ARRAY) + delete d1.u.sym->u.arr; + + if (d2.type == INT) { + d1.u.sym->u.i = d2.u.i; + } else if (d2.type == FLOAT) { + d1.u.sym->u.f = d2.u.f; + } else if (d2.type == STRING) { + d1.u.sym->u.s = new Common::String(*d2.u.s); + delete d2.u.s; + } else if (d2.type == POINT) { + d1.u.sym->u.arr = new FloatArray(*d2.u.arr); + delete d2.u.arr; + } else if (d2.type == SYMBOL) { + d1.u.sym->u.i = d2.u.i; + } else { + warning("c_assign: unhandled type: %s", d2.type2str()); + } + + d1.u.sym->type = d2.type; + + g_lingo->push(d1); +} + +bool Lingo::verify(Symbol *s) { + if (s->type != INT && s->type != VOID && s->type != FLOAT && s->type != STRING && s->type != POINT) { + warning("attempt to evaluate non-variable '%s'", s->name); + + return false; + } + + if (s->type == VOID) + warning("Variable used before assigning a value '%s'", s->name); + + return true; +} + +void Lingo::c_eval() { + g_lingo->c_varpush(); + + Datum d; + d = g_lingo->pop(); + + if (d.type != VAR) { // It could be cast ref + g_lingo->push(d); + return; + } + + if (!g_lingo->verify(d.u.sym)) + return; + + d.type = d.u.sym->type; + + if (d.u.sym->type == INT) + d.u.i = d.u.sym->u.i; + else if (d.u.sym->type == FLOAT) + d.u.f = d.u.sym->u.f; + else if (d.u.sym->type == STRING) + d.u.s = new Common::String(*d.u.sym->u.s); + else if (d.u.sym->type == POINT) + d.u.arr = d.u.sym->u.arr; + else if (d.u.sym->type == SYMBOL) + d.u.i = d.u.sym->u.i; + else if (d.u.sym->type == VOID) + d.u.s = new Common::String(d.u.sym->name); + else + warning("c_eval: unhandled type: %s", d.type2str()); + + g_lingo->push(d); +} + +void Lingo::c_theentitypush() { + inst e = (*g_lingo->_currentScript)[g_lingo->_pc++]; + inst f = (*g_lingo->_currentScript)[g_lingo->_pc++]; + Datum id = g_lingo->pop(); + + int entity = READ_UINT32(&e); + int field = READ_UINT32(&f); + + Datum d = g_lingo->getTheEntity(entity, id, field); + g_lingo->push(d); +} + +void Lingo::c_theentityassign() { + inst e = (*g_lingo->_currentScript)[g_lingo->_pc++]; + inst f = (*g_lingo->_currentScript)[g_lingo->_pc++]; + Datum id = g_lingo->pop(); + + int entity = READ_UINT32(&e); + int field = READ_UINT32(&f); + + Datum d = g_lingo->pop(); + g_lingo->setTheEntity(entity, id, field, d); + + g_lingo->push(d); // Dummy value +} + +void Lingo::c_swap() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + g_lingo->push(d2); + g_lingo->push(d1); +} + +void Lingo::c_add() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + if (g_lingo->alignTypes(d1, d2) == FLOAT) { + d1.u.f += d2.u.f; + } else { + d1.u.i += d2.u.i; + } + g_lingo->push(d1); +} + +void Lingo::c_sub() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + if (g_lingo->alignTypes(d1, d2) == FLOAT) { + d1.u.f -= d2.u.f; + } else { + d1.u.i -= d2.u.i; + } + g_lingo->push(d1); +} + +void Lingo::c_mul() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + if (g_lingo->alignTypes(d1, d2) == FLOAT) { + d1.u.f *= d2.u.f; + } else { + d1.u.i *= d2.u.i; + } + g_lingo->push(d1); +} + +void Lingo::c_div() { + Datum d2 = g_lingo->pop(); + + if ((d2.type == INT && d2.u.i == 0) || + (d2.type == FLOAT && d2.u.f == 0.0)) + error("division by zero"); + + Datum d1 = g_lingo->pop(); + + if (g_lingo->alignTypes(d1, d2) == FLOAT) { + d1.u.f /= d2.u.f; + } else { + d1.u.i /= d2.u.i; + } + g_lingo->push(d1); +} + +void Lingo::c_negate() { + Datum d = g_lingo->pop(); + + if (d.type == INT) + d.u.i = -d.u.i; + else if (d.type == FLOAT) + d.u.f = -d.u.f; + + g_lingo->push(d); +} + +void Lingo::c_ampersand() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + d1.toString(); + d2.toString(); + + *d1.u.s += *d2.u.s; + + delete d2.u.s; + + g_lingo->push(d1); +} + +void Lingo::c_concat() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + d1.toString(); + d2.toString(); + + *d1.u.s += " "; + *d1.u.s += *d2.u.s; + + delete d2.u.s; + + g_lingo->push(d1); +} + +void Lingo::c_contains() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + d1.toString(); + d2.toString(); + + Common::String *s1 = g_lingo->toLowercaseMac(d1.u.s); + Common::String *s2 = g_lingo->toLowercaseMac(d2.u.s); + + int res = s1->contains(*s2) ? 1 : 0; + + delete d1.u.s; + delete d2.u.s; + delete s1; + delete s2; + + d1.type = INT; + d1.u.i = res; + + g_lingo->push(d1); +} + +void Lingo::c_starts() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + d1.toString(); + d2.toString(); + + Common::String *s1 = g_lingo->toLowercaseMac(d1.u.s); + Common::String *s2 = g_lingo->toLowercaseMac(d2.u.s); + + int res = s1->hasPrefix(*s2) ? 1 : 0; + + delete d1.u.s; + delete d2.u.s; + delete s1; + delete s2; + + d1.type = INT; + d1.u.i = res; + + g_lingo->push(d1); +} + +void Lingo::c_intersects() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + warning("STUB: c_intersects: %d", d2.u.i); + + g_lingo->push(d1); +} + +void Lingo::c_within() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + warning("STUB: c_within: %d", d2.u.i); + + g_lingo->push(d1); +} + +void Lingo::c_and() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + d1.toInt(); + d2.toInt(); + + d1.u.i = (d1.u.i && d2.u.i) ? 1 : 0; + + g_lingo->push(d1); +} + +void Lingo::c_or() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + d1.toInt(); + d2.toInt(); + + d1.u.i = (d1.u.i || d2.u.i) ? 1 : 0; + + g_lingo->push(d1); +} + +void Lingo::c_not() { + Datum d = g_lingo->pop(); + + d.toInt(); + + d.u.i = ~d.u.i ? 1 : 0; + + g_lingo->push(d); +} + +void Lingo::c_eq() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + if (g_lingo->alignTypes(d1, d2) == FLOAT) { + d1.u.i = (d1.u.f == d2.u.f) ? 1 : 0; + d1.type = INT; + } else { + d1.u.i = (d1.u.i == d2.u.i) ? 1 : 0; + } + g_lingo->push(d1); +} + +void Lingo::c_neq() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + if (g_lingo->alignTypes(d1, d2) == FLOAT) { + d1.u.i = (d1.u.f != d2.u.f) ? 1 : 0; + d1.type = INT; + } else { + d1.u.i = (d1.u.i != d2.u.i) ? 1 : 0; + } + g_lingo->push(d1); +} + +void Lingo::c_gt() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + if (g_lingo->alignTypes(d1, d2) == FLOAT) { + d1.u.i = (d1.u.f > d2.u.f) ? 1 : 0; + d1.type = INT; + } else { + d1.u.i = (d1.u.i > d2.u.i) ? 1 : 0; + } + g_lingo->push(d1); +} + +void Lingo::c_lt() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + if (g_lingo->alignTypes(d1, d2) == FLOAT) { + d1.u.i = (d1.u.f < d2.u.f) ? 1 : 0; + d1.type = INT; + } else { + d1.u.i = (d1.u.i < d2.u.i) ? 1 : 0; + } + g_lingo->push(d1); +} + +void Lingo::c_ge() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + if (g_lingo->alignTypes(d1, d2) == FLOAT) { + d1.u.i = (d1.u.f >= d2.u.f) ? 1 : 0; + d1.type = INT; + } else { + d1.u.i = (d1.u.i >= d2.u.i) ? 1 : 0; + } + g_lingo->push(d1); +} + +void Lingo::c_le() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + if (g_lingo->alignTypes(d1, d2) == FLOAT) { + d1.u.i = (d1.u.f <= d2.u.f) ? 1 : 0; + d1.type = INT; + } else { + d1.u.i = (d1.u.i <= d2.u.i) ? 1 : 0; + } + g_lingo->push(d1); +} + +void Lingo::c_repeatwhilecode(void) { + Datum d; + int savepc = g_lingo->_pc; + + int body = READ_UINT32(&(*g_lingo->_currentScript)[savepc]); + int end = READ_UINT32(&(*g_lingo->_currentScript)[savepc + 1]); + + g_lingo->execute(savepc + 2); /* condition */ + d = g_lingo->pop(); + d.toInt(); + + while (d.u.i) { + g_lingo->execute(body); /* body */ + if (g_lingo->_returning) + break; + + g_lingo->execute(savepc + 2); /* condition */ + d = g_lingo->pop(); + d.toInt(); + } + + if (!g_lingo->_returning) + g_lingo->_pc = end; /* next stmt */ +} + +void Lingo::c_repeatwithcode(void) { + Datum d; + int savepc = g_lingo->_pc; + + int init = READ_UINT32(&(*g_lingo->_currentScript)[savepc]); + int finish = READ_UINT32(&(*g_lingo->_currentScript)[savepc + 1]); + int body = READ_UINT32(&(*g_lingo->_currentScript)[savepc + 2]); + int inc = (int32)READ_UINT32(&(*g_lingo->_currentScript)[savepc + 3]); + int end = READ_UINT32(&(*g_lingo->_currentScript)[savepc + 4]); + Common::String countername((char *)&(*g_lingo->_currentScript)[savepc + 5]); + Symbol *counter = g_lingo->lookupVar(countername.c_str()); + + if (counter->type == CASTREF) { + error("Cast ref used as index: %s", countername.c_str()); + } + + g_lingo->execute(init); /* condition */ + d = g_lingo->pop(); + d.toInt(); + counter->u.i = d.u.i; + counter->type = INT; + + while (true) { + g_lingo->execute(body); /* body */ + if (g_lingo->_returning) + break; + + counter->u.i += inc; + g_lingo->execute(finish); /* condition */ + d = g_lingo->pop(); + d.toInt(); + + if (counter->u.i == d.u.i + inc) + break; + } + + if (!g_lingo->_returning) + g_lingo->_pc = end; /* next stmt */ +} + +void Lingo::c_ifcode() { + Datum d; + int savepc = g_lingo->_pc; /* then part */ + + int then = READ_UINT32(&(*g_lingo->_currentScript)[savepc]); + int elsep = READ_UINT32(&(*g_lingo->_currentScript)[savepc + 1]); + int end = READ_UINT32(&(*g_lingo->_currentScript)[savepc + 2]); + int skipEnd = READ_UINT32(&(*g_lingo->_currentScript)[savepc + 3]); + + debug(8, "executing cond (have to %s end)", skipEnd ? "skip" : "execute"); + g_lingo->execute(savepc + 4); /* condition */ + + d = g_lingo->pop(); + + if (d.toInt()) { + debug(8, "executing then"); + g_lingo->execute(then); + } else if (elsep) { /* else part? */ + debug(8, "executing else"); + g_lingo->execute(elsep); + } + + if (!g_lingo->_returning && !skipEnd) { + g_lingo->_pc = end; /* next stmt */ + debug(8, "executing end"); + } else + debug(8, "Skipped end"); +} + +//************************ +// Built-in functions +//************************ +void Lingo::c_goto() { + Datum mode = g_lingo->pop(); + Datum frame, movie; + + if (mode.u.i == 2 || mode.u.i == 3) + movie = g_lingo->pop(); + + if (mode.u.i == 1 || mode.u.i == 3) + frame = g_lingo->pop(); + + g_lingo->func_goto(frame, movie); +} + +void Lingo::c_gotoloop() { + g_lingo->func_gotoloop(); +} + +void Lingo::c_gotonext() { + g_lingo->func_gotonext(); +} + +void Lingo::c_gotoprevious() { + g_lingo->func_gotoprevious(); +} + +void Lingo::c_play() { + Datum mode = g_lingo->pop(); + Datum frame, movie; + + if (mode.u.i == 2 || mode.u.i == 3) + movie = g_lingo->pop(); + + if (mode.u.i == 1 || mode.u.i == 3) + frame = g_lingo->pop(); + + if (frame.type == VOID) { + frame.u.s = new Common::String("<void>"); + frame.type = STRING; + } + frame.toString(); + + if (movie.type == VOID) { + movie.u.s = new Common::String("<void>"); + movie.type = STRING; + } + movie.toString(); + + warning("STUB: c_play(%s, %s)", frame.u.s->c_str(), movie.u.s->c_str()); +} + +void Lingo::c_playdone() { + warning("STUB: c_playdone()"); +} + +void Lingo::c_call() { + Common::String name((char *)&(*g_lingo->_currentScript)[g_lingo->_pc]); + g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str()); + + int nargs = READ_UINT32(&(*g_lingo->_currentScript)[g_lingo->_pc++]); + + g_lingo->call(name, nargs); +} + +void Lingo::call(Common::String &name, int nargs) { + bool drop = false; + + Symbol *sym; + + if (!g_lingo->_handlers.contains(name)) { + Symbol *s = g_lingo->lookupVar(name.c_str(), false); + if (s && s->type == OBJECT) { + debug(3, "Dereferencing object reference: %s to %s", name.c_str(), s->u.s->c_str()); + name = *s->u.s; + } + } + + if (!g_lingo->_handlers.contains(name)) { + warning("Call to undefined handler '%s'. Dropping %d stack items", name.c_str(), nargs); + drop = true; + } else { + sym = g_lingo->_handlers[name]; + + if (sym->type == BLTIN && sym->nargs != -1 && sym->nargs != nargs && sym->maxArgs != nargs) { + if (sym->nargs == sym->maxArgs) + warning("Incorrect number of arguments to handler '%s', expecting %d. Dropping %d stack items", name.c_str(), sym->nargs, nargs); + else + warning("Incorrect number of arguments to handler '%s', expecting %d or %d. Dropping %d stack items", name.c_str(), sym->nargs, sym->maxArgs, nargs); + + drop = true; + } + } + + if (drop) { + for (int i = 0; i < nargs; i++) + g_lingo->pop(); + + // Push dummy value + g_lingo->pushVoid(); + + return; + } + + if (sym->nargs != -1 && sym->nargs < nargs) { + warning("Incorrect number of arguments for function %s. Dropping extra %d", name.c_str(), nargs - sym->nargs); + for (int i = 0; i < nargs - sym->nargs; i++) + g_lingo->pop(); + } + + if (sym->type == BLTIN) { + if (sym->u.bltin == b_factory) + g_lingo->factoryCall(name, nargs); + else + (*sym->u.bltin)(nargs); + + return; + } + + for (int i = nargs; i < sym->nargs; i++) { + Datum d; + + d.u.s = NULL; + d.type = VOID; + g_lingo->push(d); + } + + CFrame *fp = new CFrame; + + fp->sp = sym; + fp->retpc = g_lingo->_pc; + fp->retscript = g_lingo->_currentScript; + fp->localvars = g_lingo->_localvars; + + // Create new set of local variables + g_lingo->_localvars = new SymbolHash; + + g_lingo->_callstack.push_back(fp); + + g_lingo->_currentScript = sym->u.defn; + g_lingo->execute(0); + + g_lingo->_returning = false; +} + +void Lingo::c_procret() { + if (!g_lingo->_callstack.size()) { + warning("Call stack underflow"); + g_lingo->_returning = true; + return; + } + + CFrame *fp = g_lingo->_callstack.back(); + + g_lingo->_currentScript = fp->retscript; + g_lingo->_pc = fp->retpc; + + g_lingo->cleanLocalVars(); + + // Restore local variables + g_lingo->_localvars = fp->localvars; + + delete fp; + + g_lingo->_returning = true; +} + +void Lingo::c_global() { + Common::String name((char *)&(*g_lingo->_currentScript)[g_lingo->_pc]); + + Symbol *s = g_lingo->lookupVar(name.c_str(), false); + if (s && !s->global) { + warning("Local variable %s declared as global", name.c_str()); + } + + s = g_lingo->lookupVar(name.c_str(), true, true); + s->global = true; + + g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str()); +} + +void Lingo::c_open() { + Datum d2 = g_lingo->pop(); + Datum d1 = g_lingo->pop(); + + d1.toString(); + d2.toString(); + + warning("STUB: c_open(%s, %s)", d1.u.s->c_str(), d2.u.s->c_str()); +} + +} diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp new file mode 100644 index 0000000000..bf96802bb7 --- /dev/null +++ b/engines/director/lingo/lingo-codegen.cpp @@ -0,0 +1,287 @@ +/* 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. + * + */ + +// Heavily inspired by hoc +// Copyright (C) AT&T 1995 +// All Rights Reserved +// +// Permission to use, copy, modify, and distribute this software and +// its documentation for any purpose and without fee is hereby +// granted, provided that the above copyright notice appear in all +// copies and that both that the copyright notice and this +// permission notice and warranty disclaimer appear in supporting +// documentation, and that the name of AT&T or any of its entities +// not be used in advertising or publicity pertaining to +// distribution of the software without specific, written prior +// permission. +// +// AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +// IN NO EVENT SHALL AT&T OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +// SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +// IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +// THIS SOFTWARE. + +#include "engines/director/lingo/lingo.h" +#include "common/file.h" +#include "audio/decoders/wave.h" + +#include "director/lingo/lingo-gr.h" + +namespace Director { + +void Lingo::execute(int pc) { + for(_pc = pc; (*_currentScript)[_pc] != STOP && !_returning;) { + + for (uint i = 0; i < _stack.size(); i++) { + debugN(5, "%d ", _stack[i].u.i); + } + debug(5, "%s", ""); + + _pc++; + (*((*_currentScript)[_pc - 1]))(); + } +} + +Symbol *Lingo::lookupVar(const char *name, bool create, bool putInGlobalList) { + Symbol *sym; + + // Looking for the cast member constants + if (_vm->getVersion() < 4) { // TODO: There could be a flag 'Allow Outdated Lingo' in Movie Info in D4 + if (strlen(name) == 3) { + if (tolower(name[0]) >= 'a' && tolower(name[0]) <= 'h' && + name[1] >= '1' && name[1] <= '8' && + name[2] >= '1' && name[2] <= '8') { + + if (!create) + error("Cast reference used in wrong context: %s", name); + + int val = (tolower(name[0]) - 'a') * 64 + (name[1] - '1') * 8 + (name[2] - '1') + 1; + sym = new Symbol; + + sym->type = CASTREF; + sym->u.i = val; + + return sym; + } + } + } + + if (!_localvars->contains(name)) { // Create variable if it was not defined + if (!create) + return NULL; + + sym = new Symbol; + sym->name = (char *)calloc(strlen(name) + 1, 1); + Common::strlcpy(sym->name, name, strlen(name) + 1); + sym->type = VOID; + sym->u.i = 0; + + (*_localvars)[name] = sym; + + if (putInGlobalList) { + sym->global = true; + _globalvars[name] = sym; + } + } else { + sym = (*_localvars)[name]; + + if (sym->global) + sym = _globalvars[name]; + } + + return sym; +} + +void Lingo::cleanLocalVars() { + // Clean up current scope local variables and clean up memory + for (SymbolHash::const_iterator h = _localvars->begin(); h != _localvars->end(); ++h) { + if (!h->_value->global) + delete h->_value; + } + delete g_lingo->_localvars; +} + +void Lingo::define(Common::String &name, int start, int nargs, Common::String *prefix) { + Symbol *sym; + + if (prefix) + name = *prefix + "-" + name; + + debug(3, "define(\"%s\", %d, %d, %d)", name.c_str(), start, _currentScript->size() - 1, nargs); + + if (!_handlers.contains(name)) { // Create variable if it was not defined + sym = new Symbol; + + sym->name = (char *)calloc(name.size() + 1, 1); + Common::strlcpy(sym->name, name.c_str(), name.size() + 1); + sym->type = HANDLER; + + _handlers[name] = sym; + } else { + sym = g_lingo->_handlers[name]; + + warning("Redefining handler '%s'", name.c_str()); + delete sym->u.defn; + } + + sym->u.defn = new ScriptData(&(*_currentScript)[start], _currentScript->size() - start + 1); + sym->nargs = nargs; +} + +int Lingo::codeString(const char *str) { + int numInsts = calcStringAlignment(str); + + // Where we copy the string over + int pos = _currentScript->size(); + + // Allocate needed space in script + for (int i = 0; i < numInsts; i++) + _currentScript->push_back(0); + + byte *dst = (byte *)&_currentScript->front() + pos * sizeof(inst); + + memcpy(dst, str, strlen(str) + 1); + + return _currentScript->size(); +} + +int Lingo::codeFloat(double f) { + int numInsts = calcCodeAlignment(sizeof(double)); + + // Where we copy the string over + int pos = _currentScript->size(); + + // Allocate needed space in script + for (int i = 0; i < numInsts; i++) + _currentScript->push_back(0); + + double *dst = (double *)((byte *)&_currentScript->front() + pos * sizeof(inst)); + + *dst = f; + + return _currentScript->size(); +} + +int Lingo::codeConst(int val) { + int res = g_lingo->code1(g_lingo->c_constpush); + inst i = 0; + WRITE_UINT32(&i, val); + g_lingo->code1(i); + + return res; +} + +void Lingo::codeArg(Common::String *s) { + _argstack.push_back(s); +} + +void Lingo::codeArgStore() { + while (true) { + if (_argstack.empty()) { + break; + } + + Common::String *arg = _argstack.back(); + _argstack.pop_back(); + + code1(c_varpush); + codeString(arg->c_str()); + code1(c_assign); + code1(c_xpop); + + delete arg; + } +} + +int Lingo::codeFunc(Common::String *s, int numpar) { + int ret = g_lingo->code1(g_lingo->c_call); + + if (s->equalsIgnoreCase("me")) { + if (!g_lingo->_currentFactory.empty()) { + g_lingo->codeString(g_lingo->_currentFactory.c_str()); + debug(2, "Repaced 'me' with %s", g_lingo->_currentFactory.c_str()); + } else { + warning("'me' out of factory method"); + g_lingo->codeString(s->c_str()); + } + } else { + g_lingo->codeString(s->c_str()); + } + + inst num = 0; + WRITE_UINT32(&num, numpar); + g_lingo->code1(num); + + return ret; +} + +void Lingo::codeLabel(int label) { + _labelstack.push_back(label); +} + +void Lingo::processIf(int elselabel, int endlabel) { + inst ielse1, iend; + int else1 = elselabel; + + WRITE_UINT32(&iend, endlabel); + + while (true) { + if (_labelstack.empty()) { + warning("Label stack underflow"); + break; + } + + int label = _labelstack.back(); + _labelstack.pop_back(); + + // This is beginning of our if() + if (!label) + break; + + WRITE_UINT32(&ielse1, else1); + (*_currentScript)[label + 2] = ielse1; /* elsepart */ + (*_currentScript)[label + 3] = iend; /* end, if cond fails */ + + else1 = label; + } +} + +void Lingo::codeFactory(Common::String &name) { + _currentFactory = name; + + Symbol *sym = new Symbol; + + sym->name = (char *)calloc(name.size() + 1, 1); + Common::strlcpy(sym->name, name.c_str(), name.size()); + sym->type = BLTIN; + sym->nargs = -1; + sym->maxArgs = 0; + sym->parens = true; + sym->u.bltin = g_lingo->b_factory; + + _handlers[name] = sym; +} + +} diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp new file mode 100644 index 0000000000..da2cd5f358 --- /dev/null +++ b/engines/director/lingo/lingo-funcs.cpp @@ -0,0 +1,235 @@ +/* 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. + * + */ + +// Heavily inspired by hoc +// Copyright (C) AT&T 1995 +// All Rights Reserved +// +// Permission to use, copy, modify, and distribute this software and +// its documentation for any purpose and without fee is hereby +// granted, provided that the above copyright notice appear in all +// copies and that both that the copyright notice and this +// permission notice and warranty disclaimer appear in supporting +// documentation, and that the name of AT&T or any of its entities +// not be used in advertising or publicity pertaining to +// distribution of the software without specific, written prior +// permission. +// +// AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +// IN NO EVENT SHALL AT&T OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +// SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +// IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +// THIS SOFTWARE. + +#include "engines/director/lingo/lingo.h" +#include "common/file.h" +#include "audio/decoders/wave.h" +#include "common/util.h" +#include "director/lingo/lingo-gr.h" + +namespace Director { + +enum MCITokenType { + kMCITokenNone, + + kMCITokenOpen, + kMCITokenWait, + kMCITokenPlay, + + kMCITokenType, + kMCITokenAlias, + kMCITokenBuffer, + kMCITokenFrom, + kMCITokenTo, + kMCITokenRepeat +}; + +struct MCIToken { + MCITokenType command; // Command this flag belongs to + MCITokenType flag; + const char *token; + int pos; // Position of parameter to store. 0 is always filename. Negative parameters mean boolean +} MCITokens[] = { + { kMCITokenNone, kMCITokenOpen, "open", 0 }, + { kMCITokenOpen, kMCITokenType, "type", 1 }, + { kMCITokenOpen, kMCITokenAlias, "alias", 2 }, + { kMCITokenOpen, kMCITokenBuffer, "buffer", 3 }, + + { kMCITokenNone, kMCITokenPlay, "play", 0 }, + { kMCITokenPlay, kMCITokenFrom, "from", 1 }, + { kMCITokenPlay, kMCITokenTo, "to", 2 }, + { kMCITokenPlay, kMCITokenRepeat, "repeat", -3 }, // This is boolean parameter + + { kMCITokenNone, kMCITokenWait, "wait", 0 }, + + { kMCITokenNone, kMCITokenNone, 0, 0 } +}; + +void Lingo::func_mci(Common::String &s) { + Common::String params[5]; + MCITokenType command = kMCITokenNone; + + s.trim(); + s.toLowercase(); + + MCITokenType state = kMCITokenNone; + Common::String token; + const char *ptr = s.c_str(); + int respos = -1; + + while (*ptr) { + while (*ptr && *ptr == ' ') + ptr++; + + token.clear(); + + while (*ptr && *ptr != ' ') + token += *ptr++; + + switch (state) { + case kMCITokenNone: + { + MCIToken *f = MCITokens; + + while (f->token) { + if (command == f->command && token == f->token) + break; + + f++; + } + + if (command == kMCITokenNone) { // We caught command + command = f->flag; // Switching to processing this command parameters + } else if (f->flag == kMCITokenNone) { // Unmatched token, storing as filename + if (!params[0].empty()) + warning("Duplicate filename in MCI command: %s -> %s", params[0].c_str(), token.c_str()); + params[0] = token; + } else { // This is normal parameter, storing next token to designated position + if (f->pos > 0) { // This is normal parameter + state = f->flag; + respos = f->pos; + } else { // This is boolean + params[-f->pos] = "true"; + state = kMCITokenNone; + } + } + break; + } + default: + params[respos] = token; + state = kMCITokenNone; + break; + } + } + + switch (command) { + case kMCITokenOpen: + { + warning("MCI open file: %s, type: %s, alias: %s buffer: %s", params[0].c_str(), params[1].c_str(), params[2].c_str(), params[3].c_str()); + + Common::File *file = new Common::File(); + + if (!file->open(params[0])) { + warning("Failed to open %s", params[0].c_str()); + delete file; + return; + } + + if (params[1] == "waveaudio") { + Audio::AudioStream *sound = Audio::makeWAVStream(file, DisposeAfterUse::YES); + _audioAliases[params[2]] = sound; + } else { + warning("Unhandled audio type %s", params[2].c_str()); + } + } + break; + case kMCITokenPlay: + { + warning("MCI play file: %s, from: %s, to: %s, repeat: %s", params[0].c_str(), params[1].c_str(), params[2].c_str(), params[3].c_str()); + + if (!_audioAliases.contains(params[0])) { + warning("Unknown alias %s", params[0].c_str()); + return; + } + + uint32 from = strtol(params[1].c_str(), 0, 10); + uint32 to = strtol(params[2].c_str(), 0, 10); + + _vm->getSoundManager()->playMCI(*_audioAliases[params[0]], from, to); + } + break; + default: + warning("Unhandled MCI command: %s", s.c_str()); + } +} + +void Lingo::func_mciwait(Common::String &s) { + warning("STUB: MCI wait file: %s", s.c_str()); +} + +void Lingo::func_goto(Datum &frame, Datum &movie) { + if (movie.type != VOID) { + movie.toString(); + + if (!_vm->_movies || !_vm->_movies->contains(*movie.u.s)) { + warning("Movie %s does not exist", movie.u.s->c_str()); + return; + } + + _vm->_currentScore = _vm->_movies->getVal(*movie.u.s); + _vm->_currentScore->loadArchive(); + } + + if (!_vm->_currentScore) { + warning("func_goto: No score is loaded"); + return; + } + + if (frame.type == VOID) + return; + + if (frame.type == STRING) { + _vm->_currentScore->setStartToLabel(*frame.u.s); + return; + } + + frame.toInt(); + + _vm->_currentScore->setCurrentFrame(frame.u.i); +} + +void Lingo::func_gotoloop() { + _vm->_currentScore->gotoloop(); +} + +void Lingo::func_gotonext() { + _vm->_currentScore->gotonext(); +} + +void Lingo::func_gotoprevious() { + _vm->_currentScore->gotoprevious(); +} + +} diff --git a/engines/director/lingo/lingo-gr.cpp b/engines/director/lingo/lingo-gr.cpp new file mode 100644 index 0000000000..63128058ed --- /dev/null +++ b/engines/director/lingo/lingo-gr.cpp @@ -0,0 +1,2749 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + 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, 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. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.3" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + UNARY = 258, + CASTREF = 259, + VOID = 260, + VAR = 261, + POINT = 262, + RECT = 263, + ARRAY = 264, + SYMBOL = 265, + OBJECT = 266, + INT = 267, + THEENTITY = 268, + THEENTITYWITHID = 269, + FLOAT = 270, + BLTIN = 271, + BLTINNOARGS = 272, + BLTINNOARGSORONE = 273, + BLTINONEARG = 274, + BLTINARGLIST = 275, + ID = 276, + STRING = 277, + HANDLER = 278, + tDOWN = 279, + tELSE = 280, + tNLELSIF = 281, + tEND = 282, + tEXIT = 283, + tFRAME = 284, + tGLOBAL = 285, + tGO = 286, + tIF = 287, + tINTO = 288, + tLOOP = 289, + tMACRO = 290, + tMOVIE = 291, + tNEXT = 292, + tOF = 293, + tPREVIOUS = 294, + tPUT = 295, + tREPEAT = 296, + tSET = 297, + tTHEN = 298, + tTO = 299, + tWHEN = 300, + tWITH = 301, + tWHILE = 302, + tNLELSE = 303, + tFACTORY = 304, + tMETHOD = 305, + tOPEN = 306, + tPLAY = 307, + tDONE = 308, + tPLAYACCEL = 309, + tGE = 310, + tLE = 311, + tGT = 312, + tLT = 313, + tEQ = 314, + tNEQ = 315, + tAND = 316, + tOR = 317, + tNOT = 318, + tCONCAT = 319, + tCONTAINS = 320, + tSTARTS = 321, + tSPRITE = 322, + tINTERSECTS = 323, + tWITHIN = 324 + }; +#endif +/* Tokens. */ +#define UNARY 258 +#define CASTREF 259 +#define VOID 260 +#define VAR 261 +#define POINT 262 +#define RECT 263 +#define ARRAY 264 +#define SYMBOL 265 +#define OBJECT 266 +#define INT 267 +#define THEENTITY 268 +#define THEENTITYWITHID 269 +#define FLOAT 270 +#define BLTIN 271 +#define BLTINNOARGS 272 +#define BLTINNOARGSORONE 273 +#define BLTINONEARG 274 +#define BLTINARGLIST 275 +#define ID 276 +#define STRING 277 +#define HANDLER 278 +#define tDOWN 279 +#define tELSE 280 +#define tNLELSIF 281 +#define tEND 282 +#define tEXIT 283 +#define tFRAME 284 +#define tGLOBAL 285 +#define tGO 286 +#define tIF 287 +#define tINTO 288 +#define tLOOP 289 +#define tMACRO 290 +#define tMOVIE 291 +#define tNEXT 292 +#define tOF 293 +#define tPREVIOUS 294 +#define tPUT 295 +#define tREPEAT 296 +#define tSET 297 +#define tTHEN 298 +#define tTO 299 +#define tWHEN 300 +#define tWITH 301 +#define tWHILE 302 +#define tNLELSE 303 +#define tFACTORY 304 +#define tMETHOD 305 +#define tOPEN 306 +#define tPLAY 307 +#define tDONE 308 +#define tPLAYACCEL 309 +#define tGE 310 +#define tLE 311 +#define tGT 312 +#define tLT 313 +#define tEQ 314 +#define tNEQ 315 +#define tAND 316 +#define tOR 317 +#define tNOT 318 +#define tCONCAT 319 +#define tCONTAINS 320 +#define tSTARTS 321 +#define tSPRITE 322 +#define tINTERSECTS 323 +#define tWITHIN 324 + + + + +/* Copy the first part of user declarations. */ +#line 49 "engines/director/lingo/lingo-gr.y" + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/hash-str.h" + +#include "director/lingo/lingo.h" +#include "director/lingo/lingo-gr.h" + +extern int yylex(); +extern int yyparse(); + +using namespace Director; +void yyerror(char *s) { + g_lingo->_hadError = true; + warning("%s at line %d col %d", s, g_lingo->_linenumber, g_lingo->_colnumber); +} + + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 69 "engines/director/lingo/lingo-gr.y" +{ + Common::String *s; + int i; + double f; + int e[2]; // Entity + field + int code; + int narg; /* number of arguments */ + Common::Array<double> *arr; +} +/* Line 193 of yacc.c. */ +#line 264 "engines/director/lingo/lingo-gr.cpp" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 216 of yacc.c. */ +#line 277 "engines/director/lingo/lingo-gr.cpp" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int i) +#else +static int +YYID (i) + int i; +#endif +{ + return i; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 87 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 921 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 83 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 35 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 124 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 259 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 324 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 76, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 75, 81, 2, + 77, 78, 73, 71, 82, 72, 2, 74, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 80, 70, 79, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 7, 9, 12, 14, 15, 17, 19, + 21, 23, 25, 30, 35, 40, 46, 51, 56, 62, + 64, 66, 68, 70, 79, 91, 104, 109, 118, 130, + 142, 149, 160, 171, 172, 176, 179, 181, 184, 186, + 193, 195, 201, 203, 207, 211, 214, 218, 220, 222, + 223, 224, 225, 228, 231, 233, 235, 237, 239, 244, + 246, 248, 251, 253, 257, 261, 265, 269, 273, 277, + 281, 285, 289, 293, 297, 300, 304, 308, 312, 316, + 319, 322, 326, 331, 336, 339, 341, 343, 345, 348, + 351, 354, 356, 359, 364, 367, 369, 373, 376, 379, + 382, 385, 389, 392, 395, 397, 401, 404, 407, 410, + 414, 417, 418, 427, 430, 431, 440, 441, 443, 447, + 452, 453, 457, 458, 460 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 84, 0, -1, 84, 85, 86, -1, 86, -1, 1, + 85, -1, 76, -1, -1, 111, -1, 105, -1, 116, + -1, 87, -1, 89, -1, 40, 104, 33, 21, -1, + 42, 21, 70, 104, -1, 42, 13, 70, 104, -1, + 42, 14, 104, 70, 104, -1, 42, 21, 44, 104, + -1, 42, 13, 44, 104, -1, 42, 14, 104, 44, + 104, -1, 104, -1, 105, -1, 88, -1, 90, -1, + 97, 77, 96, 78, 103, 102, 27, 41, -1, 98, + 70, 104, 102, 44, 104, 102, 103, 102, 27, 41, + -1, 98, 70, 104, 102, 24, 44, 104, 102, 103, + 102, 27, 41, -1, 45, 21, 43, 104, -1, 99, + 96, 43, 85, 103, 102, 27, 32, -1, 99, 96, + 43, 85, 103, 102, 48, 103, 102, 27, 32, -1, + 99, 96, 43, 85, 103, 102, 101, 92, 102, 27, + 32, -1, 99, 96, 43, 101, 88, 102, -1, 99, + 96, 43, 101, 88, 102, 48, 101, 88, 102, -1, + 99, 96, 43, 101, 88, 102, 93, 102, 91, 102, + -1, -1, 48, 101, 88, -1, 92, 95, -1, 95, + -1, 93, 94, -1, 94, -1, 100, 96, 43, 101, + 89, 102, -1, 93, -1, 100, 96, 43, 103, 102, + -1, 104, -1, 104, 70, 104, -1, 77, 96, 78, + -1, 41, 47, -1, 41, 46, 21, -1, 32, -1, + 26, -1, -1, -1, -1, 103, 85, -1, 103, 89, + -1, 12, -1, 15, -1, 22, -1, 17, -1, 21, + 77, 117, 78, -1, 21, -1, 13, -1, 14, 104, + -1, 87, -1, 104, 71, 104, -1, 104, 72, 104, + -1, 104, 73, 104, -1, 104, 74, 104, -1, 104, + 79, 104, -1, 104, 80, 104, -1, 104, 60, 104, + -1, 104, 55, 104, -1, 104, 56, 104, -1, 104, + 61, 104, -1, 104, 62, 104, -1, 63, 104, -1, + 104, 81, 104, -1, 104, 64, 104, -1, 104, 65, + 104, -1, 104, 66, 104, -1, 71, 104, -1, 72, + 104, -1, 77, 104, 78, -1, 67, 104, 68, 104, + -1, 67, 104, 69, 104, -1, 40, 104, -1, 107, + -1, 110, -1, 28, -1, 30, 106, -1, 19, 104, + -1, 18, 104, -1, 18, -1, 20, 117, -1, 51, + 104, 46, 104, -1, 51, 104, -1, 21, -1, 106, + 82, 21, -1, 31, 34, -1, 31, 37, -1, 31, + 39, -1, 31, 108, -1, 31, 108, 109, -1, 31, + 109, -1, 29, 104, -1, 104, -1, 38, 36, 104, + -1, 36, 104, -1, 52, 53, -1, 52, 108, -1, + 52, 108, 109, -1, 52, 109, -1, -1, 35, 21, + 112, 101, 114, 85, 115, 103, -1, 49, 21, -1, + -1, 50, 21, 113, 101, 114, 85, 115, 103, -1, + -1, 21, -1, 114, 82, 21, -1, 114, 85, 82, + 21, -1, -1, 21, 101, 117, -1, -1, 104, -1, + 117, 82, 104, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 103, 103, 104, 105, 108, 113, 114, 115, 116, + 117, 118, 121, 127, 133, 141, 149, 155, 163, 172, + 173, 175, 176, 181, 192, 208, 220, 225, 232, 241, + 250, 260, 270, 281, 282, 285, 286, 289, 290, 293, + 301, 302, 310, 311, 312, 314, 316, 322, 328, 335, + 337, 339, 340, 341, 344, 345, 348, 351, 355, 358, + 362, 369, 375, 376, 377, 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 399, 400, 401, 402, 404, 405, + 408, 411, 414, 415, 416, 419, 420, 431, 432, 433, + 434, 437, 440, 445, 446, 449, 450, 453, 454, 457, + 460, 490, 490, 496, 499, 499, 504, 505, 506, 507, + 509, 513, 521, 522, 523 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "UNARY", "CASTREF", "VOID", "VAR", + "POINT", "RECT", "ARRAY", "SYMBOL", "OBJECT", "INT", "THEENTITY", + "THEENTITYWITHID", "FLOAT", "BLTIN", "BLTINNOARGS", "BLTINNOARGSORONE", + "BLTINONEARG", "BLTINARGLIST", "ID", "STRING", "HANDLER", "tDOWN", + "tELSE", "tNLELSIF", "tEND", "tEXIT", "tFRAME", "tGLOBAL", "tGO", "tIF", + "tINTO", "tLOOP", "tMACRO", "tMOVIE", "tNEXT", "tOF", "tPREVIOUS", + "tPUT", "tREPEAT", "tSET", "tTHEN", "tTO", "tWHEN", "tWITH", "tWHILE", + "tNLELSE", "tFACTORY", "tMETHOD", "tOPEN", "tPLAY", "tDONE", + "tPLAYACCEL", "tGE", "tLE", "tGT", "tLT", "tEQ", "tNEQ", "tAND", "tOR", + "tNOT", "tCONCAT", "tCONTAINS", "tSTARTS", "tSPRITE", "tINTERSECTS", + "tWITHIN", "'='", "'+'", "'-'", "'*'", "'/'", "'%'", "'\\n'", "'('", + "')'", "'>'", "'<'", "'&'", "','", "$accept", "program", "nl", + "programline", "asgn", "stmtoneliner", "stmt", "ifstmt", + "elsestmtoneliner", "elseifstmt", "elseifstmtoneliner", + "elseifstmtoneliner1", "elseifstmt1", "cond", "repeatwhile", + "repeatwith", "if", "elseif", "begin", "end", "stmtlist", "expr", "func", + "globallist", "gotofunc", "gotoframe", "gotomovie", "playfunc", "defn", + "@1", "@2", "argdef", "argstore", "macro", "arglist", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 61, 43, 45, 42, 47, 37, 10, 40, 41, 62, + 60, 38, 44 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 83, 84, 84, 84, 85, 86, 86, 86, 86, + 86, 86, 87, 87, 87, 87, 87, 87, 87, 88, + 88, 89, 89, 89, 89, 89, 89, 90, 90, 90, + 90, 90, 90, 91, 91, 92, 92, 93, 93, 94, + 95, 95, 96, 96, 96, 97, 98, 99, 100, 101, + 102, 103, 103, 103, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 106, 106, 107, 107, 107, + 107, 107, 107, 108, 108, 109, 109, 110, 110, 110, + 110, 112, 111, 111, 113, 111, 114, 114, 114, 114, + 115, 116, 117, 117, 117 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 3, 1, 2, 1, 0, 1, 1, 1, + 1, 1, 4, 4, 4, 5, 4, 4, 5, 1, + 1, 1, 1, 8, 11, 12, 4, 8, 11, 11, + 6, 10, 10, 0, 3, 2, 1, 2, 1, 6, + 1, 5, 1, 3, 3, 2, 3, 1, 1, 0, + 0, 0, 2, 2, 1, 1, 1, 1, 4, 1, + 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, + 2, 3, 4, 4, 2, 1, 1, 1, 2, 2, + 2, 1, 2, 4, 2, 1, 3, 2, 2, 2, + 2, 3, 2, 2, 1, 3, 2, 2, 2, 3, + 2, 0, 8, 2, 0, 8, 0, 1, 3, 4, + 0, 3, 0, 1, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 54, 60, 0, 55, 57, 91, 0, 122, + 49, 56, 87, 0, 0, 47, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 62, 21, 11, 22, 0, 0, 0, 19, + 8, 85, 86, 7, 9, 5, 4, 59, 0, 62, + 61, 90, 89, 123, 92, 122, 122, 95, 88, 0, + 97, 0, 98, 0, 99, 104, 100, 102, 111, 84, + 0, 45, 0, 0, 0, 0, 113, 114, 94, 107, + 108, 110, 74, 0, 79, 80, 0, 1, 6, 0, + 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 121, 0, 103, 106, 0, 101, 49, 0, + 46, 0, 0, 0, 0, 0, 0, 49, 0, 109, + 0, 0, 81, 2, 0, 50, 0, 0, 49, 0, + 70, 71, 69, 72, 73, 76, 77, 78, 63, 64, + 65, 66, 67, 68, 75, 124, 58, 96, 105, 116, + 12, 17, 14, 0, 0, 16, 13, 26, 116, 93, + 82, 83, 51, 0, 44, 51, 0, 43, 117, 0, + 18, 15, 0, 50, 0, 0, 50, 50, 20, 0, + 120, 120, 52, 53, 0, 0, 50, 49, 30, 118, + 0, 51, 51, 0, 50, 51, 0, 51, 0, 48, + 49, 50, 38, 0, 119, 112, 115, 23, 51, 50, + 27, 50, 50, 40, 36, 0, 0, 37, 33, 0, + 50, 0, 0, 35, 0, 0, 50, 49, 50, 49, + 0, 0, 0, 0, 49, 31, 0, 32, 0, 0, + 24, 28, 29, 50, 34, 50, 25, 41, 39 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 30, 192, 31, 49, 33, 193, 35, 238, 222, + 223, 212, 224, 92, 36, 37, 38, 213, 248, 173, + 183, 39, 188, 58, 41, 66, 67, 42, 43, 118, + 127, 179, 201, 44, 54 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -198 +static const yytype_int16 yypact[] = +{ + 243, -53, -198, -198, 385, -198, -198, 385, 385, 385, + 791, -198, -198, 18, 573, -198, 22, 385, 7, 6, + 26, 31, 36, 385, 613, 385, 385, 385, 385, 385, + 4, -198, 5, -198, -198, -198, -48, -8, 512, 769, + -198, -198, -198, -198, -198, -198, -198, -14, 385, -198, + 769, 769, 769, 769, -21, 385, 385, -198, -4, 385, + -198, 385, -198, 38, -198, 769, 8, -198, -198, 151, + 54, -198, -37, 385, -29, 39, -198, -198, 649, -198, + 8, -198, 840, 671, 840, 840, 720, -198, 341, 512, + 385, 512, 40, 747, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 151, + 385, -57, -21, 63, 769, 769, 385, -198, -198, 64, + -198, 385, 385, 627, 385, 385, 385, -198, 385, -198, + 385, 385, -198, -198, 9, 769, 14, 693, -53, 385, + 769, 769, 769, 769, 769, 769, 769, 769, 818, 818, + 840, 840, 769, 769, 769, 769, -198, -198, 769, 65, + -198, 769, 769, 385, 385, 769, 769, 769, 65, 769, + 769, 769, -198, -12, -198, -198, 529, 769, -198, -58, + 769, 769, -58, 402, 49, 385, 402, -198, -198, 73, + 13, 13, -198, -198, 71, 385, 769, -11, -17, -198, + 78, -198, -198, 60, 769, -198, 72, -198, 77, -198, + -198, 77, -198, 512, -198, 402, 402, -198, -198, 402, + -198, 402, 77, 77, -198, 512, 529, -198, 57, 67, + 402, 79, 80, -198, 81, 68, -198, -198, -198, -198, + 85, 74, 84, 87, -16, -198, 529, -198, 468, 76, + -198, -198, -198, 402, -198, -198, -198, -198, -198 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -198, -198, 12, 25, 2, -170, 0, -198, -198, -198, + -78, -197, -101, -61, -198, -198, -198, -186, -9, 113, + -167, 41, 3, -198, -198, 98, -7, -198, -198, -198, + -198, -45, -67, -198, 16 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -60 +static const yytype_int16 yytable[] = +{ + 34, 56, 32, 40, 87, -10, 187, 121, 186, 209, + -51, -51, 184, 46, 227, 124, 206, 81, 45, 72, + 73, 156, 225, 45, 189, 110, 227, 74, 134, 89, + 136, 210, 185, 122, 215, 216, 225, 207, 219, 57, + 221, 125, 88, 68, 61, 50, 63, 75, 51, 52, + 53, 230, 76, 70, 71, 65, 236, 77, 69, 117, + -51, 110, 90, 55, 78, 65, 82, 83, 84, 85, + 86, 111, 112, 129, 116, 120, 254, 253, 113, 93, + 45, -10, 126, 138, 157, 160, 178, 172, 34, 109, + 32, 40, 174, 195, 199, 200, 53, 53, 203, 214, + 114, 217, 115, 209, 220, 237, 241, 242, 243, 159, + 239, 244, 249, 133, 123, 250, 251, 256, 168, 252, + 211, 233, 80, 182, 202, 0, 0, 0, 0, 176, + 93, 135, 137, 0, 0, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 175, 155, 229, 0, 0, 0, 0, 158, 0, 0, + 0, 0, 161, 162, 235, 165, 166, 167, 0, 169, + 0, 170, 171, 0, 0, 0, 0, 0, 0, 0, + 177, 0, 0, 0, 119, 0, 0, 0, 208, 0, + 0, 190, 0, 0, 191, 0, 0, 0, 0, 0, + 0, 226, 0, 0, 180, 181, 94, 95, 0, 0, + 0, 96, 97, 98, 0, 99, 100, 101, 0, 0, + 0, 0, 102, 103, 104, 105, 196, 0, 246, 0, + 106, 107, 108, 0, 0, 0, 204, 0, 0, 0, + 0, 0, 0, -6, 1, 0, 0, 0, 255, 0, + 0, 0, 0, 0, 93, 2, 3, 4, 5, 0, + 6, 7, 8, 9, 10, 11, 93, 0, 0, 0, + 0, 12, 0, 13, 14, 15, 0, 0, 16, 0, + 0, 0, 0, 17, 18, 19, 0, 0, 20, 0, + 0, 0, 21, 22, 23, 24, 194, 0, 0, 197, + 198, 0, 0, 0, 0, 0, 25, 0, 0, 205, + 26, 0, 0, 0, 27, 28, 0, 218, 0, -6, + 29, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 231, 0, 232, 234, 0, 0, 0, 0, + 0, 0, 0, 240, 0, 0, 0, 0, 0, 245, + 0, 247, 0, 2, 3, 4, 5, 0, 6, 7, + 8, 9, 10, 11, 0, 0, 257, 0, 258, 12, + 0, 13, 14, 15, 0, 0, 16, 0, 0, 0, + 0, 17, 18, 19, 0, 0, 20, 0, 0, 0, + 21, 22, 23, 24, 0, 0, 0, 2, 3, 4, + 5, 0, 6, 0, 25, 0, 47, 11, 26, 0, + 0, 0, 27, 28, 2, 3, 4, 5, 29, 6, + 7, 8, 9, 47, 11, 48, 0, 19, 0, 0, + 12, 0, 13, 14, 15, 0, 0, 0, 0, 0, + 0, 0, 17, 18, 19, 0, 0, 20, 25, 0, + 0, 0, 26, 23, 24, 0, 27, 28, 0, 0, + 0, 0, 29, 0, 0, 25, 0, 0, 0, 26, + 0, 0, 0, 27, 28, 0, 0, 0, 45, 29, + 2, 3, 4, 5, 0, 6, 7, 8, 9, 47, + 11, 0, 0, 0, 0, 0, 12, 0, 13, 14, + 15, 0, 0, 0, 0, 0, 0, 0, 17, 18, + 19, 0, 0, 20, 0, 0, 0, 0, 0, 23, + 24, 0, 0, 0, 2, 3, 4, 5, 0, 6, + 0, 25, 0, 47, 11, 26, 0, 0, 0, 27, + 28, 2, 3, 4, 5, 29, 6, 7, 8, 9, + 47, 11, 48, 0, 19, 0, 0, 12, 0, 13, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 0, 19, 0, 0, 0, 25, 0, 0, 0, 26, + 23, 24, 0, 27, 28, 2, 3, 4, 5, 91, + 6, 0, 25, 0, 47, 11, 26, 0, 0, 0, + 27, 28, 59, 0, 0, 0, 29, 60, 0, 61, + 62, 63, 64, 48, 0, 19, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 3, 4, 5, 0, + 6, 0, 0, 0, 47, 11, 25, 0, 0, 0, + 26, 0, 59, 0, 27, 28, 0, 0, 0, 61, + 29, 63, 0, 48, 0, 19, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, + 0, 163, 0, 0, 0, 0, 25, 0, 0, 0, + 26, 0, 94, 95, 27, 28, 0, 96, 97, 98, + 29, 99, 100, 101, 0, 128, 0, 164, 102, 103, + 104, 105, 0, 0, 94, 95, 106, 107, 108, 96, + 97, 98, 0, 99, 100, 101, 0, 0, 0, 0, + 102, 103, 104, 105, 0, 0, 94, 95, 106, 107, + 108, 96, 97, 98, 0, 99, 100, 101, 0, 130, + 131, 0, 102, 103, 104, 105, 0, 0, 94, 95, + 106, 107, 108, 96, 97, 98, 0, 99, 100, 101, + 0, 0, 0, 139, 102, 103, 104, 105, 0, 0, + 0, 132, 106, 107, 108, 94, 95, 0, 0, 0, + 96, 97, 98, 0, 99, 100, 101, 0, 0, 0, + 0, 102, 103, 104, 105, 0, 0, 0, 132, 106, + 107, 108, 94, 95, 0, 0, 0, 96, 97, 98, + 0, 99, 100, 101, 0, 0, 0, 139, 102, 103, + 104, 105, 0, 0, 94, 95, 106, 107, 108, 96, + 97, 98, 0, 99, 100, 101, 0, 0, 0, 0, + 102, 103, 104, 105, 0, 0, -59, -59, 106, 107, + 108, -59, -59, -59, 0, -59, -59, -59, 0, 0, + 0, 0, 0, 0, -59, -59, 0, 0, 55, 0, + -59, -59, -59, 94, 95, 0, 0, 0, 96, 97, + 98, 0, 99, 100, 101, 0, 0, 0, 0, 0, + 0, 104, 105, 0, 0, 94, 95, 106, 107, 108, + 96, 97, 98, 0, 99, 100, 101, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, + 107, 108 +}; + +static const yytype_int16 yycheck[] = +{ + 0, 10, 0, 0, 0, 0, 176, 44, 175, 26, + 26, 27, 24, 1, 211, 44, 27, 24, 76, 13, + 14, 78, 208, 76, 82, 82, 223, 21, 89, 77, + 91, 48, 44, 70, 201, 202, 222, 48, 205, 21, + 207, 70, 30, 21, 36, 4, 38, 21, 7, 8, + 9, 218, 21, 46, 47, 14, 226, 21, 17, 66, + 76, 82, 70, 77, 23, 24, 25, 26, 27, 28, + 29, 55, 56, 80, 36, 21, 246, 244, 82, 38, + 76, 76, 43, 43, 21, 21, 21, 78, 88, 48, + 88, 88, 78, 44, 21, 82, 55, 56, 27, 21, + 59, 41, 61, 26, 32, 48, 27, 27, 27, 118, + 43, 43, 27, 88, 73, 41, 32, 41, 127, 32, + 198, 222, 24, 168, 191, -1, -1, -1, -1, 138, + 89, 90, 91, -1, -1, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 138, 110, 213, -1, -1, -1, -1, 116, -1, -1, + -1, -1, 121, 122, 225, 124, 125, 126, -1, 128, + -1, 130, 131, -1, -1, -1, -1, -1, -1, -1, + 139, -1, -1, -1, 33, -1, -1, -1, 197, -1, + -1, 179, -1, -1, 182, -1, -1, -1, -1, -1, + -1, 210, -1, -1, 163, 164, 55, 56, -1, -1, + -1, 60, 61, 62, -1, 64, 65, 66, -1, -1, + -1, -1, 71, 72, 73, 74, 185, -1, 237, -1, + 79, 80, 81, -1, -1, -1, 195, -1, -1, -1, + -1, -1, -1, 0, 1, -1, -1, -1, 248, -1, + -1, -1, -1, -1, 213, 12, 13, 14, 15, -1, + 17, 18, 19, 20, 21, 22, 225, -1, -1, -1, + -1, 28, -1, 30, 31, 32, -1, -1, 35, -1, + -1, -1, -1, 40, 41, 42, -1, -1, 45, -1, + -1, -1, 49, 50, 51, 52, 183, -1, -1, 186, + 187, -1, -1, -1, -1, -1, 63, -1, -1, 196, + 67, -1, -1, -1, 71, 72, -1, 204, -1, 76, + 77, -1, -1, -1, 211, -1, -1, -1, -1, -1, + -1, -1, 219, -1, 221, 222, -1, -1, -1, -1, + -1, -1, -1, 230, -1, -1, -1, -1, -1, 236, + -1, 238, -1, 12, 13, 14, 15, -1, 17, 18, + 19, 20, 21, 22, -1, -1, 253, -1, 255, 28, + -1, 30, 31, 32, -1, -1, 35, -1, -1, -1, + -1, 40, 41, 42, -1, -1, 45, -1, -1, -1, + 49, 50, 51, 52, -1, -1, -1, 12, 13, 14, + 15, -1, 17, -1, 63, -1, 21, 22, 67, -1, + -1, -1, 71, 72, 12, 13, 14, 15, 77, 17, + 18, 19, 20, 21, 22, 40, -1, 42, -1, -1, + 28, -1, 30, 31, 32, -1, -1, -1, -1, -1, + -1, -1, 40, 41, 42, -1, -1, 45, 63, -1, + -1, -1, 67, 51, 52, -1, 71, 72, -1, -1, + -1, -1, 77, -1, -1, 63, -1, -1, -1, 67, + -1, -1, -1, 71, 72, -1, -1, -1, 76, 77, + 12, 13, 14, 15, -1, 17, 18, 19, 20, 21, + 22, -1, -1, -1, -1, -1, 28, -1, 30, 31, + 32, -1, -1, -1, -1, -1, -1, -1, 40, 41, + 42, -1, -1, 45, -1, -1, -1, -1, -1, 51, + 52, -1, -1, -1, 12, 13, 14, 15, -1, 17, + -1, 63, -1, 21, 22, 67, -1, -1, -1, 71, + 72, 12, 13, 14, 15, 77, 17, 18, 19, 20, + 21, 22, 40, -1, 42, -1, -1, 28, -1, 30, + 31, -1, -1, -1, -1, -1, -1, -1, -1, 40, + -1, 42, -1, -1, -1, 63, -1, -1, -1, 67, + 51, 52, -1, 71, 72, 12, 13, 14, 15, 77, + 17, -1, 63, -1, 21, 22, 67, -1, -1, -1, + 71, 72, 29, -1, -1, -1, 77, 34, -1, 36, + 37, 38, 39, 40, -1, 42, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12, 13, 14, 15, -1, + 17, -1, -1, -1, 21, 22, 63, -1, -1, -1, + 67, -1, 29, -1, 71, 72, -1, -1, -1, 36, + 77, 38, -1, 40, -1, 42, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 53, -1, -1, -1, + -1, 44, -1, -1, -1, -1, 63, -1, -1, -1, + 67, -1, 55, 56, 71, 72, -1, 60, 61, 62, + 77, 64, 65, 66, -1, 46, -1, 70, 71, 72, + 73, 74, -1, -1, 55, 56, 79, 80, 81, 60, + 61, 62, -1, 64, 65, 66, -1, -1, -1, -1, + 71, 72, 73, 74, -1, -1, 55, 56, 79, 80, + 81, 60, 61, 62, -1, 64, 65, 66, -1, 68, + 69, -1, 71, 72, 73, 74, -1, -1, 55, 56, + 79, 80, 81, 60, 61, 62, -1, 64, 65, 66, + -1, -1, -1, 70, 71, 72, 73, 74, -1, -1, + -1, 78, 79, 80, 81, 55, 56, -1, -1, -1, + 60, 61, 62, -1, 64, 65, 66, -1, -1, -1, + -1, 71, 72, 73, 74, -1, -1, -1, 78, 79, + 80, 81, 55, 56, -1, -1, -1, 60, 61, 62, + -1, 64, 65, 66, -1, -1, -1, 70, 71, 72, + 73, 74, -1, -1, 55, 56, 79, 80, 81, 60, + 61, 62, -1, 64, 65, 66, -1, -1, -1, -1, + 71, 72, 73, 74, -1, -1, 55, 56, 79, 80, + 81, 60, 61, 62, -1, 64, 65, 66, -1, -1, + -1, -1, -1, -1, 73, 74, -1, -1, 77, -1, + 79, 80, 81, 55, 56, -1, -1, -1, 60, 61, + 62, -1, 64, 65, 66, -1, -1, -1, -1, -1, + -1, 73, 74, -1, -1, 55, 56, 79, 80, 81, + 60, 61, 62, -1, 64, 65, 66, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 79, + 80, 81 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 1, 12, 13, 14, 15, 17, 18, 19, 20, + 21, 22, 28, 30, 31, 32, 35, 40, 41, 42, + 45, 49, 50, 51, 52, 63, 67, 71, 72, 77, + 84, 86, 87, 88, 89, 90, 97, 98, 99, 104, + 105, 107, 110, 111, 116, 76, 85, 21, 40, 87, + 104, 104, 104, 104, 117, 77, 101, 21, 106, 29, + 34, 36, 37, 38, 39, 104, 108, 109, 21, 104, + 46, 47, 13, 14, 21, 21, 21, 21, 104, 53, + 108, 109, 104, 104, 104, 104, 104, 0, 85, 77, + 70, 77, 96, 104, 55, 56, 60, 61, 62, 64, + 65, 66, 71, 72, 73, 74, 79, 80, 81, 104, + 82, 117, 117, 82, 104, 104, 36, 109, 112, 33, + 21, 44, 70, 104, 44, 70, 43, 113, 46, 109, + 68, 69, 78, 86, 96, 104, 96, 104, 43, 70, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 78, 21, 104, 101, + 21, 104, 104, 44, 70, 104, 104, 104, 101, 104, + 104, 104, 78, 102, 78, 85, 101, 104, 21, 114, + 104, 104, 114, 103, 24, 44, 103, 88, 105, 82, + 85, 85, 85, 89, 102, 44, 104, 102, 102, 21, + 82, 115, 115, 27, 104, 102, 27, 48, 101, 26, + 48, 93, 94, 100, 21, 103, 103, 41, 102, 103, + 32, 103, 92, 93, 95, 100, 101, 94, 102, 96, + 103, 102, 102, 95, 102, 96, 88, 48, 91, 43, + 102, 27, 27, 27, 43, 102, 101, 102, 101, 27, + 41, 32, 32, 103, 88, 89, 41, 102, 102 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +#else +static void +yy_stack_print (bottom, top) + yytype_int16 *bottom; + yytype_int16 *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + fprintf (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + fprintf (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The look-ahead symbol. */ +int yychar; + +/* The semantic value of the look-ahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + int yystate; + int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss = yyssa; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp; + + + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + look-ahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to look-ahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a look-ahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 4: +#line 105 "engines/director/lingo/lingo-gr.y" + { yyerrok; ;} + break; + + case 5: +#line 108 "engines/director/lingo/lingo-gr.y" + { + g_lingo->_linenumber++; + g_lingo->_colnumber = 1; + ;} + break; + + case 10: +#line 117 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_xpop); ;} + break; + + case 12: +#line 121 "engines/director/lingo/lingo-gr.y" + { + g_lingo->code1(g_lingo->c_varpush); + g_lingo->codeString((yyvsp[(4) - (4)].s)->c_str()); + g_lingo->code1(g_lingo->c_assign); + (yyval.code) = (yyvsp[(2) - (4)].code); + delete (yyvsp[(4) - (4)].s); ;} + break; + + case 13: +#line 127 "engines/director/lingo/lingo-gr.y" + { + g_lingo->code1(g_lingo->c_varpush); + g_lingo->codeString((yyvsp[(2) - (4)].s)->c_str()); + g_lingo->code1(g_lingo->c_assign); + (yyval.code) = (yyvsp[(4) - (4)].code); + delete (yyvsp[(2) - (4)].s); ;} + break; + + case 14: +#line 133 "engines/director/lingo/lingo-gr.y" + { + g_lingo->codeConst(0); // Put dummy id + g_lingo->code1(g_lingo->c_theentityassign); + inst e = 0, f = 0; + WRITE_UINT32(&e, (yyvsp[(2) - (4)].e)[0]); + WRITE_UINT32(&f, (yyvsp[(2) - (4)].e)[1]); + g_lingo->code2(e, f); + (yyval.code) = (yyvsp[(4) - (4)].code); ;} + break; + + case 15: +#line 141 "engines/director/lingo/lingo-gr.y" + { + g_lingo->code1(g_lingo->c_swap); + g_lingo->code1(g_lingo->c_theentityassign); + inst e = 0, f = 0; + WRITE_UINT32(&e, (yyvsp[(2) - (5)].e)[0]); + WRITE_UINT32(&f, (yyvsp[(2) - (5)].e)[1]); + g_lingo->code2(e, f); + (yyval.code) = (yyvsp[(5) - (5)].code); ;} + break; + + case 16: +#line 149 "engines/director/lingo/lingo-gr.y" + { + g_lingo->code1(g_lingo->c_varpush); + g_lingo->codeString((yyvsp[(2) - (4)].s)->c_str()); + g_lingo->code1(g_lingo->c_assign); + (yyval.code) = (yyvsp[(4) - (4)].code); + delete (yyvsp[(2) - (4)].s); ;} + break; + + case 17: +#line 155 "engines/director/lingo/lingo-gr.y" + { + g_lingo->codeConst(0); // Put dummy id + g_lingo->code1(g_lingo->c_theentityassign); + inst e = 0, f = 0; + WRITE_UINT32(&e, (yyvsp[(2) - (4)].e)[0]); + WRITE_UINT32(&f, (yyvsp[(2) - (4)].e)[1]); + g_lingo->code2(e, f); + (yyval.code) = (yyvsp[(4) - (4)].code); ;} + break; + + case 18: +#line 163 "engines/director/lingo/lingo-gr.y" + { + g_lingo->code1(g_lingo->c_swap); + g_lingo->code1(g_lingo->c_theentityassign); + inst e = 0, f = 0; + WRITE_UINT32(&e, (yyvsp[(2) - (5)].e)[0]); + WRITE_UINT32(&f, (yyvsp[(2) - (5)].e)[1]); + g_lingo->code2(e, f); + (yyval.code) = (yyvsp[(5) - (5)].code); ;} + break; + + case 19: +#line 172 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_xpop); ;} + break; + + case 23: +#line 181 "engines/director/lingo/lingo-gr.y" + { + inst body = 0, end = 0; + WRITE_UINT32(&body, (yyvsp[(5) - (8)].code)); + WRITE_UINT32(&end, (yyvsp[(6) - (8)].code)); + (*g_lingo->_currentScript)[(yyvsp[(1) - (8)].code) + 1] = body; /* body of loop */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (8)].code) + 2] = end; ;} + break; + + case 24: +#line 192 "engines/director/lingo/lingo-gr.y" + { + inst init = 0, finish = 0, body = 0, end = 0, inc = 0; + WRITE_UINT32(&init, (yyvsp[(3) - (11)].code)); + WRITE_UINT32(&finish, (yyvsp[(6) - (11)].code)); + WRITE_UINT32(&body, (yyvsp[(8) - (11)].code)); + WRITE_UINT32(&end, (yyvsp[(9) - (11)].code)); + WRITE_UINT32(&inc, 1); + (*g_lingo->_currentScript)[(yyvsp[(1) - (11)].code) + 1] = init; /* initial count value */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (11)].code) + 2] = finish;/* final count value */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (11)].code) + 3] = body; /* body of loop */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (11)].code) + 4] = inc; /* increment */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (11)].code) + 5] = end; ;} + break; + + case 25: +#line 208 "engines/director/lingo/lingo-gr.y" + { + inst init = 0, finish = 0, body = 0, end = 0, inc = 0; + WRITE_UINT32(&init, (yyvsp[(3) - (12)].code)); + WRITE_UINT32(&finish, (yyvsp[(7) - (12)].code)); + WRITE_UINT32(&body, (yyvsp[(9) - (12)].code)); + WRITE_UINT32(&end, (yyvsp[(10) - (12)].code)); + WRITE_UINT32(&inc, -1); + (*g_lingo->_currentScript)[(yyvsp[(1) - (12)].code) + 1] = init; /* initial count value */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (12)].code) + 2] = finish;/* final count value */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (12)].code) + 3] = body; /* body of loop */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (12)].code) + 4] = inc; /* increment */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (12)].code) + 5] = end; ;} + break; + + case 26: +#line 220 "engines/director/lingo/lingo-gr.y" + { + g_lingo->code1(g_lingo->c_ifcode); + ;} + break; + + case 27: +#line 225 "engines/director/lingo/lingo-gr.y" + { + inst then = 0, end = 0; + WRITE_UINT32(&then, (yyvsp[(5) - (8)].code)); + WRITE_UINT32(&end, (yyvsp[(6) - (8)].code)); + (*g_lingo->_currentScript)[(yyvsp[(1) - (8)].code) + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (8)].code) + 3] = end; /* end, if cond fails */ + g_lingo->processIf(0, 0); ;} + break; + + case 28: +#line 232 "engines/director/lingo/lingo-gr.y" + { + inst then = 0, else1 = 0, end = 0; + WRITE_UINT32(&then, (yyvsp[(5) - (11)].code)); + WRITE_UINT32(&else1, (yyvsp[(8) - (11)].code)); + WRITE_UINT32(&end, (yyvsp[(9) - (11)].code)); + (*g_lingo->_currentScript)[(yyvsp[(1) - (11)].code) + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (11)].code) + 2] = else1; /* elsepart */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (11)].code) + 3] = end; /* end, if cond fails */ + g_lingo->processIf(0, 0); ;} + break; + + case 29: +#line 241 "engines/director/lingo/lingo-gr.y" + { + inst then = 0, else1 = 0, end = 0; + WRITE_UINT32(&then, (yyvsp[(5) - (11)].code)); + WRITE_UINT32(&else1, (yyvsp[(7) - (11)].code)); + WRITE_UINT32(&end, (yyvsp[(9) - (11)].code)); + (*g_lingo->_currentScript)[(yyvsp[(1) - (11)].code) + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (11)].code) + 2] = else1; /* elsepart */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (11)].code) + 3] = end; /* end, if cond fails */ + g_lingo->processIf(0, (yyvsp[(9) - (11)].code)); ;} + break; + + case 30: +#line 250 "engines/director/lingo/lingo-gr.y" + { + inst then = 0, else1 = 0, end = 0; + WRITE_UINT32(&then, (yyvsp[(4) - (6)].code)); + WRITE_UINT32(&else1, 0); + WRITE_UINT32(&end, (yyvsp[(6) - (6)].code)); + (*g_lingo->_currentScript)[(yyvsp[(1) - (6)].code) + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (6)].code) + 2] = else1; /* elsepart */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (6)].code) + 3] = end; /* end, if cond fails */ + + g_lingo->processIf(0, 0); ;} + break; + + case 31: +#line 260 "engines/director/lingo/lingo-gr.y" + { + inst then = 0, else1 = 0, end = 0; + WRITE_UINT32(&then, (yyvsp[(4) - (10)].code)); + WRITE_UINT32(&else1, (yyvsp[(8) - (10)].code)); + WRITE_UINT32(&end, (yyvsp[(10) - (10)].code)); + (*g_lingo->_currentScript)[(yyvsp[(1) - (10)].code) + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (10)].code) + 2] = else1; /* elsepart */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (10)].code) + 3] = end; /* end, if cond fails */ + + g_lingo->processIf(0, 0); ;} + break; + + case 32: +#line 270 "engines/director/lingo/lingo-gr.y" + { + inst then = 0, else1 = 0, end = 0; + WRITE_UINT32(&then, (yyvsp[(4) - (10)].code)); + WRITE_UINT32(&else1, (yyvsp[(6) - (10)].code)); + WRITE_UINT32(&end, (yyvsp[(10) - (10)].code)); + (*g_lingo->_currentScript)[(yyvsp[(1) - (10)].code) + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (10)].code) + 2] = else1; /* elsepart */ + (*g_lingo->_currentScript)[(yyvsp[(1) - (10)].code) + 3] = end; /* end, if cond fails */ + + g_lingo->processIf(0, (yyvsp[(10) - (10)].code)); ;} + break; + + case 33: +#line 281 "engines/director/lingo/lingo-gr.y" + { (yyval.code) = 0; ;} + break; + + case 34: +#line 282 "engines/director/lingo/lingo-gr.y" + { (yyval.code) = (yyvsp[(2) - (3)].code); ;} + break; + + case 39: +#line 293 "engines/director/lingo/lingo-gr.y" + { + inst then = 0; + WRITE_UINT32(&then, (yyvsp[(4) - (6)].code)); + (*g_lingo->_currentScript)[(yyvsp[(1) - (6)].code) + 1] = then; /* thenpart */ + + g_lingo->codeLabel((yyvsp[(1) - (6)].code)); ;} + break; + + case 41: +#line 302 "engines/director/lingo/lingo-gr.y" + { + inst then = 0; + WRITE_UINT32(&then, (yyvsp[(4) - (5)].code)); + (*g_lingo->_currentScript)[(yyvsp[(1) - (5)].code) + 1] = then; /* thenpart */ + + g_lingo->codeLabel((yyvsp[(1) - (5)].code)); ;} + break; + + case 42: +#line 310 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(STOP); ;} + break; + + case 43: +#line 311 "engines/director/lingo/lingo-gr.y" + { g_lingo->code2(g_lingo->c_eq, STOP); ;} + break; + + case 45: +#line 314 "engines/director/lingo/lingo-gr.y" + { (yyval.code) = g_lingo->code3(g_lingo->c_repeatwhilecode, STOP, STOP); ;} + break; + + case 46: +#line 316 "engines/director/lingo/lingo-gr.y" + { + (yyval.code) = g_lingo->code3(g_lingo->c_repeatwithcode, STOP, STOP); + g_lingo->code3(STOP, STOP, STOP); + g_lingo->codeString((yyvsp[(3) - (3)].s)->c_str()); + delete (yyvsp[(3) - (3)].s); ;} + break; + + case 47: +#line 322 "engines/director/lingo/lingo-gr.y" + { + (yyval.code) = g_lingo->code1(g_lingo->c_ifcode); + g_lingo->code3(STOP, STOP, STOP); + g_lingo->code1(0); // Do not skip end + g_lingo->codeLabel(0); ;} + break; + + case 48: +#line 328 "engines/director/lingo/lingo-gr.y" + { + inst skipEnd; + WRITE_UINT32(&skipEnd, 1); // We have to skip end to avoid multiple executions + (yyval.code) = g_lingo->code1(g_lingo->c_ifcode); + g_lingo->code3(STOP, STOP, STOP); + g_lingo->code1(skipEnd); ;} + break; + + case 49: +#line 335 "engines/director/lingo/lingo-gr.y" + { (yyval.code) = g_lingo->_currentScript->size(); ;} + break; + + case 50: +#line 337 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(STOP); (yyval.code) = g_lingo->_currentScript->size(); ;} + break; + + case 51: +#line 339 "engines/director/lingo/lingo-gr.y" + { (yyval.code) = g_lingo->_currentScript->size(); ;} + break; + + case 54: +#line 344 "engines/director/lingo/lingo-gr.y" + { (yyval.code) = g_lingo->codeConst((yyvsp[(1) - (1)].i)); ;} + break; + + case 55: +#line 345 "engines/director/lingo/lingo-gr.y" + { + (yyval.code) = g_lingo->code1(g_lingo->c_fconstpush); + g_lingo->codeFloat((yyvsp[(1) - (1)].f)); ;} + break; + + case 56: +#line 348 "engines/director/lingo/lingo-gr.y" + { + (yyval.code) = g_lingo->code1(g_lingo->c_stringpush); + g_lingo->codeString((yyvsp[(1) - (1)].s)->c_str()); ;} + break; + + case 57: +#line 351 "engines/director/lingo/lingo-gr.y" + { + (yyval.code) = g_lingo->code1(g_lingo->_handlers[*(yyvsp[(1) - (1)].s)]->u.func); + g_lingo->codeConst(0); // Put dummy value + delete (yyvsp[(1) - (1)].s); ;} + break; + + case 58: +#line 355 "engines/director/lingo/lingo-gr.y" + { + (yyval.code) = g_lingo->codeFunc((yyvsp[(1) - (4)].s), (yyvsp[(3) - (4)].narg)); + delete (yyvsp[(1) - (4)].s); ;} + break; + + case 59: +#line 358 "engines/director/lingo/lingo-gr.y" + { + (yyval.code) = g_lingo->code1(g_lingo->c_eval); + g_lingo->codeString((yyvsp[(1) - (1)].s)->c_str()); + delete (yyvsp[(1) - (1)].s); ;} + break; + + case 60: +#line 362 "engines/director/lingo/lingo-gr.y" + { + (yyval.code) = g_lingo->codeConst(0); // Put dummy id + g_lingo->code1(g_lingo->c_theentitypush); + inst e = 0, f = 0; + WRITE_UINT32(&e, (yyvsp[(1) - (1)].e)[0]); + WRITE_UINT32(&f, (yyvsp[(1) - (1)].e)[1]); + g_lingo->code2(e, f); ;} + break; + + case 61: +#line 369 "engines/director/lingo/lingo-gr.y" + { + (yyval.code) = g_lingo->code1(g_lingo->c_theentitypush); + inst e = 0, f = 0; + WRITE_UINT32(&e, (yyvsp[(1) - (2)].e)[0]); + WRITE_UINT32(&f, (yyvsp[(1) - (2)].e)[1]); + g_lingo->code2(e, f); ;} + break; + + case 63: +#line 376 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_add); ;} + break; + + case 64: +#line 377 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_sub); ;} + break; + + case 65: +#line 378 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_mul); ;} + break; + + case 66: +#line 379 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_div); ;} + break; + + case 67: +#line 380 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_gt); ;} + break; + + case 68: +#line 381 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_lt); ;} + break; + + case 69: +#line 382 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_neq); ;} + break; + + case 70: +#line 383 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_ge); ;} + break; + + case 71: +#line 384 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_le); ;} + break; + + case 72: +#line 385 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_and); ;} + break; + + case 73: +#line 386 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_or); ;} + break; + + case 74: +#line 387 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_not); ;} + break; + + case 75: +#line 388 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_ampersand); ;} + break; + + case 76: +#line 389 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_concat); ;} + break; + + case 77: +#line 390 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_contains); ;} + break; + + case 78: +#line 391 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_starts); ;} + break; + + case 79: +#line 392 "engines/director/lingo/lingo-gr.y" + { (yyval.code) = (yyvsp[(2) - (2)].code); ;} + break; + + case 80: +#line 393 "engines/director/lingo/lingo-gr.y" + { (yyval.code) = (yyvsp[(2) - (2)].code); g_lingo->code1(g_lingo->c_negate); ;} + break; + + case 81: +#line 394 "engines/director/lingo/lingo-gr.y" + { (yyval.code) = (yyvsp[(2) - (3)].code); ;} + break; + + case 82: +#line 395 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_intersects); ;} + break; + + case 83: +#line 396 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_within); ;} + break; + + case 84: +#line 399 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_printtop); ;} + break; + + case 87: +#line 402 "engines/director/lingo/lingo-gr.y" + { g_lingo->codeConst(0); // Push fake value on stack + g_lingo->code1(g_lingo->c_procret); ;} + break; + + case 89: +#line 405 "engines/director/lingo/lingo-gr.y" + { + g_lingo->code1(g_lingo->_handlers[*(yyvsp[(1) - (2)].s)]->u.func); + delete (yyvsp[(1) - (2)].s); ;} + break; + + case 90: +#line 408 "engines/director/lingo/lingo-gr.y" + { + g_lingo->code1(g_lingo->_handlers[*(yyvsp[(1) - (2)].s)]->u.func); + delete (yyvsp[(1) - (2)].s); ;} + break; + + case 91: +#line 411 "engines/director/lingo/lingo-gr.y" + { + g_lingo->code2(g_lingo->c_voidpush, g_lingo->_handlers[*(yyvsp[(1) - (1)].s)]->u.func); + delete (yyvsp[(1) - (1)].s); ;} + break; + + case 92: +#line 414 "engines/director/lingo/lingo-gr.y" + { g_lingo->codeFunc((yyvsp[(1) - (2)].s), (yyvsp[(2) - (2)].narg)); ;} + break; + + case 93: +#line 415 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_open); ;} + break; + + case 94: +#line 416 "engines/director/lingo/lingo-gr.y" + { g_lingo->code2(g_lingo->c_voidpush, g_lingo->c_open); ;} + break; + + case 95: +#line 419 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_global); g_lingo->codeString((yyvsp[(1) - (1)].s)->c_str()); delete (yyvsp[(1) - (1)].s); ;} + break; + + case 96: +#line 420 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_global); g_lingo->codeString((yyvsp[(3) - (3)].s)->c_str()); delete (yyvsp[(3) - (3)].s); ;} + break; + + case 97: +#line 431 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_gotoloop); ;} + break; + + case 98: +#line 432 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_gotonext); ;} + break; + + case 99: +#line 433 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_gotoprevious); ;} + break; + + case 100: +#line 434 "engines/director/lingo/lingo-gr.y" + { + g_lingo->codeConst(1); + g_lingo->code1(g_lingo->c_goto); ;} + break; + + case 101: +#line 437 "engines/director/lingo/lingo-gr.y" + { + g_lingo->codeConst(3); + g_lingo->code1(g_lingo->c_goto); ;} + break; + + case 102: +#line 440 "engines/director/lingo/lingo-gr.y" + { + g_lingo->codeConst(2); + g_lingo->code1(g_lingo->c_goto); ;} + break; + + case 107: +#line 453 "engines/director/lingo/lingo-gr.y" + { g_lingo->code1(g_lingo->c_playdone); ;} + break; + + case 108: +#line 454 "engines/director/lingo/lingo-gr.y" + { + g_lingo->codeConst(1); + g_lingo->code1(g_lingo->c_play); ;} + break; + + case 109: +#line 457 "engines/director/lingo/lingo-gr.y" + { + g_lingo->codeConst(3); + g_lingo->code1(g_lingo->c_play); ;} + break; + + case 110: +#line 460 "engines/director/lingo/lingo-gr.y" + { + g_lingo->codeConst(2); + g_lingo->code1(g_lingo->c_play); ;} + break; + + case 111: +#line 490 "engines/director/lingo/lingo-gr.y" + { g_lingo->_indef = true; g_lingo->_currentFactory.clear(); ;} + break; + + case 112: +#line 491 "engines/director/lingo/lingo-gr.y" + { + g_lingo->codeConst(0); // Push fake value on stack + g_lingo->code1(g_lingo->c_procret); + g_lingo->define(*(yyvsp[(2) - (8)].s), (yyvsp[(4) - (8)].code), (yyvsp[(5) - (8)].narg)); + g_lingo->_indef = false; ;} + break; + + case 113: +#line 496 "engines/director/lingo/lingo-gr.y" + { + g_lingo->codeFactory(*(yyvsp[(2) - (2)].s)); + ;} + break; + + case 114: +#line 499 "engines/director/lingo/lingo-gr.y" + { g_lingo->_indef = true; ;} + break; + + case 115: +#line 500 "engines/director/lingo/lingo-gr.y" + { + g_lingo->code1(STOP); + g_lingo->define(*(yyvsp[(2) - (8)].s), (yyvsp[(4) - (8)].code), (yyvsp[(5) - (8)].narg) + 1, &g_lingo->_currentFactory); + g_lingo->_indef = false; ;} + break; + + case 116: +#line 504 "engines/director/lingo/lingo-gr.y" + { (yyval.narg) = 0; ;} + break; + + case 117: +#line 505 "engines/director/lingo/lingo-gr.y" + { g_lingo->codeArg((yyvsp[(1) - (1)].s)); (yyval.narg) = 1; ;} + break; + + case 118: +#line 506 "engines/director/lingo/lingo-gr.y" + { g_lingo->codeArg((yyvsp[(3) - (3)].s)); (yyval.narg) = (yyvsp[(1) - (3)].narg) + 1; ;} + break; + + case 119: +#line 507 "engines/director/lingo/lingo-gr.y" + { g_lingo->codeArg((yyvsp[(4) - (4)].s)); (yyval.narg) = (yyvsp[(1) - (4)].narg) + 1; ;} + break; + + case 120: +#line 509 "engines/director/lingo/lingo-gr.y" + { g_lingo->codeArgStore(); ;} + break; + + case 121: +#line 513 "engines/director/lingo/lingo-gr.y" + { + g_lingo->code1(g_lingo->c_call); + g_lingo->codeString((yyvsp[(1) - (3)].s)->c_str()); + inst numpar = 0; + WRITE_UINT32(&numpar, (yyvsp[(3) - (3)].narg)); + g_lingo->code1(numpar); ;} + break; + + case 122: +#line 521 "engines/director/lingo/lingo-gr.y" + { (yyval.narg) = 0; ;} + break; + + case 123: +#line 522 "engines/director/lingo/lingo-gr.y" + { (yyval.narg) = 1; ;} + break; + + case 124: +#line 523 "engines/director/lingo/lingo-gr.y" + { (yyval.narg) = (yyvsp[(1) - (3)].narg) + 1; ;} + break; + + +/* Line 1267 of yacc.c. */ +#line 2534 "engines/director/lingo/lingo-gr.cpp" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +#line 526 "engines/director/lingo/lingo-gr.y" + + diff --git a/engines/director/lingo/lingo-gr.h b/engines/director/lingo/lingo-gr.h new file mode 100644 index 0000000000..49bd8b5c08 --- /dev/null +++ b/engines/director/lingo/lingo-gr.h @@ -0,0 +1,204 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + 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, 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. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + UNARY = 258, + CASTREF = 259, + VOID = 260, + VAR = 261, + POINT = 262, + RECT = 263, + ARRAY = 264, + SYMBOL = 265, + OBJECT = 266, + INT = 267, + THEENTITY = 268, + THEENTITYWITHID = 269, + FLOAT = 270, + BLTIN = 271, + BLTINNOARGS = 272, + BLTINNOARGSORONE = 273, + BLTINONEARG = 274, + BLTINARGLIST = 275, + ID = 276, + STRING = 277, + HANDLER = 278, + tDOWN = 279, + tELSE = 280, + tNLELSIF = 281, + tEND = 282, + tEXIT = 283, + tFRAME = 284, + tGLOBAL = 285, + tGO = 286, + tIF = 287, + tINTO = 288, + tLOOP = 289, + tMACRO = 290, + tMOVIE = 291, + tNEXT = 292, + tOF = 293, + tPREVIOUS = 294, + tPUT = 295, + tREPEAT = 296, + tSET = 297, + tTHEN = 298, + tTO = 299, + tWHEN = 300, + tWITH = 301, + tWHILE = 302, + tNLELSE = 303, + tFACTORY = 304, + tMETHOD = 305, + tOPEN = 306, + tPLAY = 307, + tDONE = 308, + tPLAYACCEL = 309, + tGE = 310, + tLE = 311, + tGT = 312, + tLT = 313, + tEQ = 314, + tNEQ = 315, + tAND = 316, + tOR = 317, + tNOT = 318, + tCONCAT = 319, + tCONTAINS = 320, + tSTARTS = 321, + tSPRITE = 322, + tINTERSECTS = 323, + tWITHIN = 324 + }; +#endif +/* Tokens. */ +#define UNARY 258 +#define CASTREF 259 +#define VOID 260 +#define VAR 261 +#define POINT 262 +#define RECT 263 +#define ARRAY 264 +#define SYMBOL 265 +#define OBJECT 266 +#define INT 267 +#define THEENTITY 268 +#define THEENTITYWITHID 269 +#define FLOAT 270 +#define BLTIN 271 +#define BLTINNOARGS 272 +#define BLTINNOARGSORONE 273 +#define BLTINONEARG 274 +#define BLTINARGLIST 275 +#define ID 276 +#define STRING 277 +#define HANDLER 278 +#define tDOWN 279 +#define tELSE 280 +#define tNLELSIF 281 +#define tEND 282 +#define tEXIT 283 +#define tFRAME 284 +#define tGLOBAL 285 +#define tGO 286 +#define tIF 287 +#define tINTO 288 +#define tLOOP 289 +#define tMACRO 290 +#define tMOVIE 291 +#define tNEXT 292 +#define tOF 293 +#define tPREVIOUS 294 +#define tPUT 295 +#define tREPEAT 296 +#define tSET 297 +#define tTHEN 298 +#define tTO 299 +#define tWHEN 300 +#define tWITH 301 +#define tWHILE 302 +#define tNLELSE 303 +#define tFACTORY 304 +#define tMETHOD 305 +#define tOPEN 306 +#define tPLAY 307 +#define tDONE 308 +#define tPLAYACCEL 309 +#define tGE 310 +#define tLE 311 +#define tGT 312 +#define tLT 313 +#define tEQ 314 +#define tNEQ 315 +#define tAND 316 +#define tOR 317 +#define tNOT 318 +#define tCONCAT 319 +#define tCONTAINS 320 +#define tSTARTS 321 +#define tSPRITE 322 +#define tINTERSECTS 323 +#define tWITHIN 324 + + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 69 "engines/director/lingo/lingo-gr.y" +{ + Common::String *s; + int i; + double f; + int e[2]; // Entity + field + int code; + int narg; /* number of arguments */ + Common::Array<double> *arr; +} +/* Line 1529 of yacc.c. */ +#line 197 "engines/director/lingo/lingo-gr.hpp" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE yylval; + diff --git a/engines/director/lingo/lingo-gr.y b/engines/director/lingo/lingo-gr.y new file mode 100644 index 0000000000..ea66bc6fd9 --- /dev/null +++ b/engines/director/lingo/lingo-gr.y @@ -0,0 +1,526 @@ +/* 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. + * + */ + +// Heavily inspired by hoc +// Copyright (C) AT&T 1995 +// All Rights Reserved +// +// Permission to use, copy, modify, and distribute this software and +// its documentation for any purpose and without fee is hereby +// granted, provided that the above copyright notice appear in all +// copies and that both that the copyright notice and this +// permission notice and warranty disclaimer appear in supporting +// documentation, and that the name of AT&T or any of its entities +// not be used in advertising or publicity pertaining to +// distribution of the software without specific, written prior +// permission. +// +// AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +// IN NO EVENT SHALL AT&T OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +// SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +// IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +// THIS SOFTWARE. + + +%debug + +%{ +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/hash-str.h" + +#include "director/lingo/lingo.h" +#include "director/lingo/lingo-gr.h" + +extern int yylex(); +extern int yyparse(); + +using namespace Director; +void yyerror(char *s) { + g_lingo->_hadError = true; + warning("%s at line %d col %d", s, g_lingo->_linenumber, g_lingo->_colnumber); +} + + +%} + +%union { + Common::String *s; + int i; + double f; + int e[2]; // Entity + field + int code; + int narg; /* number of arguments */ + Common::Array<double> *arr; +} + +%token UNARY +%token CASTREF VOID VAR POINT RECT ARRAY SYMBOL OBJECT +%token<i> INT +%token<e> THEENTITY THEENTITYWITHID +%token<f> FLOAT +%token<s> BLTIN BLTINNOARGS BLTINNOARGSORONE BLTINONEARG BLTINARGLIST +%token<s> ID STRING HANDLER +%token tDOWN tELSE tNLELSIF tEND tEXIT tFRAME tGLOBAL tGO tIF tINTO tLOOP tMACRO +%token tMOVIE tNEXT tOF tPREVIOUS tPUT tREPEAT tSET tTHEN tTO tWHEN +%token tWITH tWHILE tNLELSE tFACTORY tMETHOD tOPEN tPLAY tDONE tPLAYACCEL +%token tGE tLE tGT tLT tEQ tNEQ tAND tOR tNOT +%token tCONCAT tCONTAINS tSTARTS +%token tSPRITE tINTERSECTS tWITHIN + +%type<code> asgn begin elseif elsestmtoneliner end expr if repeatwhile repeatwith stmtlist +%type<narg> argdef arglist + +%right '=' +%left '+' '-' +%left '*' '/' '%' +%right UNARY + +%% + +program: program nl programline + | programline + | error nl { yyerrok; } + ; + +nl: '\n' { + g_lingo->_linenumber++; + g_lingo->_colnumber = 1; + } + +programline: /* empty */ + | defn + | func + | macro + | asgn { g_lingo->code1(g_lingo->c_xpop); } + | stmt + ; + +asgn: tPUT expr tINTO ID { + g_lingo->code1(g_lingo->c_varpush); + g_lingo->codeString($4->c_str()); + g_lingo->code1(g_lingo->c_assign); + $$ = $2; + delete $4; } + | tSET ID '=' expr { + g_lingo->code1(g_lingo->c_varpush); + g_lingo->codeString($2->c_str()); + g_lingo->code1(g_lingo->c_assign); + $$ = $4; + delete $2; } + | tSET THEENTITY '=' expr { + g_lingo->codeConst(0); // Put dummy id + g_lingo->code1(g_lingo->c_theentityassign); + inst e = 0, f = 0; + WRITE_UINT32(&e, $2[0]); + WRITE_UINT32(&f, $2[1]); + g_lingo->code2(e, f); + $$ = $4; } + | tSET THEENTITYWITHID expr '=' expr { + g_lingo->code1(g_lingo->c_swap); + g_lingo->code1(g_lingo->c_theentityassign); + inst e = 0, f = 0; + WRITE_UINT32(&e, $2[0]); + WRITE_UINT32(&f, $2[1]); + g_lingo->code2(e, f); + $$ = $5; } + | tSET ID tTO expr { + g_lingo->code1(g_lingo->c_varpush); + g_lingo->codeString($2->c_str()); + g_lingo->code1(g_lingo->c_assign); + $$ = $4; + delete $2; } + | tSET THEENTITY tTO expr { + g_lingo->codeConst(0); // Put dummy id + g_lingo->code1(g_lingo->c_theentityassign); + inst e = 0, f = 0; + WRITE_UINT32(&e, $2[0]); + WRITE_UINT32(&f, $2[1]); + g_lingo->code2(e, f); + $$ = $4; } + | tSET THEENTITYWITHID expr tTO expr { + g_lingo->code1(g_lingo->c_swap); + g_lingo->code1(g_lingo->c_theentityassign); + inst e = 0, f = 0; + WRITE_UINT32(&e, $2[0]); + WRITE_UINT32(&f, $2[1]); + g_lingo->code2(e, f); + $$ = $5; } + ; +stmtoneliner: expr { g_lingo->code1(g_lingo->c_xpop); } + | func + ; +stmt: stmtoneliner + | ifstmt + // repeat while (expression = TRUE) + // statements + // end repeat + // + | repeatwhile '(' cond ')' stmtlist end tEND tREPEAT { + inst body = 0, end = 0; + WRITE_UINT32(&body, $5); + WRITE_UINT32(&end, $6); + (*g_lingo->_currentScript)[$1 + 1] = body; /* body of loop */ + (*g_lingo->_currentScript)[$1 + 2] = end; } /* end, if cond fails */ + ; + // repeat with index = start to end + // statements + // end repeat + // + | repeatwith '=' expr end tTO expr end stmtlist end tEND tREPEAT { + inst init = 0, finish = 0, body = 0, end = 0, inc = 0; + WRITE_UINT32(&init, $3); + WRITE_UINT32(&finish, $6); + WRITE_UINT32(&body, $8); + WRITE_UINT32(&end, $9); + WRITE_UINT32(&inc, 1); + (*g_lingo->_currentScript)[$1 + 1] = init; /* initial count value */ + (*g_lingo->_currentScript)[$1 + 2] = finish;/* final count value */ + (*g_lingo->_currentScript)[$1 + 3] = body; /* body of loop */ + (*g_lingo->_currentScript)[$1 + 4] = inc; /* increment */ + (*g_lingo->_currentScript)[$1 + 5] = end; } /* end, if cond fails */ + // repeat with index = high down to low + // statements + // end repeat + // + | repeatwith '=' expr end tDOWN tTO expr end stmtlist end tEND tREPEAT { + inst init = 0, finish = 0, body = 0, end = 0, inc = 0; + WRITE_UINT32(&init, $3); + WRITE_UINT32(&finish, $7); + WRITE_UINT32(&body, $9); + WRITE_UINT32(&end, $10); + WRITE_UINT32(&inc, -1); + (*g_lingo->_currentScript)[$1 + 1] = init; /* initial count value */ + (*g_lingo->_currentScript)[$1 + 2] = finish;/* final count value */ + (*g_lingo->_currentScript)[$1 + 3] = body; /* body of loop */ + (*g_lingo->_currentScript)[$1 + 4] = inc; /* increment */ + (*g_lingo->_currentScript)[$1 + 5] = end; } /* end, if cond fails */ + | tWHEN ID tTHEN expr { + g_lingo->code1(g_lingo->c_ifcode); + } + ; + +ifstmt: if cond tTHEN nl stmtlist end tEND tIF { + inst then = 0, end = 0; + WRITE_UINT32(&then, $5); + WRITE_UINT32(&end, $6); + (*g_lingo->_currentScript)[$1 + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[$1 + 3] = end; /* end, if cond fails */ + g_lingo->processIf(0, 0); } + | if cond tTHEN nl stmtlist end tNLELSE stmtlist end tEND tIF { + inst then = 0, else1 = 0, end = 0; + WRITE_UINT32(&then, $5); + WRITE_UINT32(&else1, $8); + WRITE_UINT32(&end, $9); + (*g_lingo->_currentScript)[$1 + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[$1 + 2] = else1; /* elsepart */ + (*g_lingo->_currentScript)[$1 + 3] = end; /* end, if cond fails */ + g_lingo->processIf(0, 0); } + | if cond tTHEN nl stmtlist end begin elseifstmt end tEND tIF { + inst then = 0, else1 = 0, end = 0; + WRITE_UINT32(&then, $5); + WRITE_UINT32(&else1, $7); + WRITE_UINT32(&end, $9); + (*g_lingo->_currentScript)[$1 + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[$1 + 2] = else1; /* elsepart */ + (*g_lingo->_currentScript)[$1 + 3] = end; /* end, if cond fails */ + g_lingo->processIf(0, $9); } + | if cond tTHEN begin stmtoneliner end { + inst then = 0, else1 = 0, end = 0; + WRITE_UINT32(&then, $4); + WRITE_UINT32(&else1, 0); + WRITE_UINT32(&end, $6); + (*g_lingo->_currentScript)[$1 + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[$1 + 2] = else1; /* elsepart */ + (*g_lingo->_currentScript)[$1 + 3] = end; /* end, if cond fails */ + + g_lingo->processIf(0, 0); } + | if cond tTHEN begin stmtoneliner end tNLELSE begin stmtoneliner end { + inst then = 0, else1 = 0, end = 0; + WRITE_UINT32(&then, $4); + WRITE_UINT32(&else1, $8); + WRITE_UINT32(&end, $10); + (*g_lingo->_currentScript)[$1 + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[$1 + 2] = else1; /* elsepart */ + (*g_lingo->_currentScript)[$1 + 3] = end; /* end, if cond fails */ + + g_lingo->processIf(0, 0); } + | if cond tTHEN begin stmtoneliner end elseifstmtoneliner end elsestmtoneliner end { + inst then = 0, else1 = 0, end = 0; + WRITE_UINT32(&then, $4); + WRITE_UINT32(&else1, $6); + WRITE_UINT32(&end, $10); + (*g_lingo->_currentScript)[$1 + 1] = then; /* thenpart */ + (*g_lingo->_currentScript)[$1 + 2] = else1; /* elsepart */ + (*g_lingo->_currentScript)[$1 + 3] = end; /* end, if cond fails */ + + g_lingo->processIf(0, $10); } + ; +elsestmtoneliner: /* nothing */ { $$ = 0; } + | tNLELSE begin stmtoneliner { $$ = $2; } + ; + +elseifstmt: elseifstmt elseifstmt1 + | elseifstmt1 + ; + +elseifstmtoneliner: elseifstmtoneliner elseifstmtoneliner1 + | elseifstmtoneliner1 + ; + +elseifstmtoneliner1: elseif cond tTHEN begin stmt end { + inst then = 0; + WRITE_UINT32(&then, $4); + (*g_lingo->_currentScript)[$1 + 1] = then; /* thenpart */ + + g_lingo->codeLabel($1); } + ; + +elseifstmt1: elseifstmtoneliner + | elseif cond tTHEN stmtlist end { + inst then = 0; + WRITE_UINT32(&then, $4); + (*g_lingo->_currentScript)[$1 + 1] = then; /* thenpart */ + + g_lingo->codeLabel($1); } + ; + +cond: expr { g_lingo->code1(STOP); } + | expr '=' expr { g_lingo->code2(g_lingo->c_eq, STOP); } + | '(' cond ')' + ; +repeatwhile: tREPEAT tWHILE { $$ = g_lingo->code3(g_lingo->c_repeatwhilecode, STOP, STOP); } + ; +repeatwith: tREPEAT tWITH ID { + $$ = g_lingo->code3(g_lingo->c_repeatwithcode, STOP, STOP); + g_lingo->code3(STOP, STOP, STOP); + g_lingo->codeString($3->c_str()); + delete $3; } + ; +if: tIF { + $$ = g_lingo->code1(g_lingo->c_ifcode); + g_lingo->code3(STOP, STOP, STOP); + g_lingo->code1(0); // Do not skip end + g_lingo->codeLabel(0); } // Mark beginning of the if() statement + ; +elseif: tNLELSIF { + inst skipEnd; + WRITE_UINT32(&skipEnd, 1); // We have to skip end to avoid multiple executions + $$ = g_lingo->code1(g_lingo->c_ifcode); + g_lingo->code3(STOP, STOP, STOP); + g_lingo->code1(skipEnd); } + ; +begin: /* nothing */ { $$ = g_lingo->_currentScript->size(); } + ; +end: /* nothing */ { g_lingo->code1(STOP); $$ = g_lingo->_currentScript->size(); } + ; +stmtlist: /* nothing */ { $$ = g_lingo->_currentScript->size(); } + | stmtlist nl + | stmtlist stmt + ; + +expr: INT { $$ = g_lingo->codeConst($1); } + | FLOAT { + $$ = g_lingo->code1(g_lingo->c_fconstpush); + g_lingo->codeFloat($1); } + | STRING { + $$ = g_lingo->code1(g_lingo->c_stringpush); + g_lingo->codeString($1->c_str()); } + | BLTINNOARGS { + $$ = g_lingo->code1(g_lingo->_handlers[*$1]->u.func); + g_lingo->codeConst(0); // Put dummy value + delete $1; } + | ID '(' arglist ')' { + $$ = g_lingo->codeFunc($1, $3); + delete $1; } + | ID { + $$ = g_lingo->code1(g_lingo->c_eval); + g_lingo->codeString($1->c_str()); + delete $1; } + | THEENTITY { + $$ = g_lingo->codeConst(0); // Put dummy id + g_lingo->code1(g_lingo->c_theentitypush); + inst e = 0, f = 0; + WRITE_UINT32(&e, $1[0]); + WRITE_UINT32(&f, $1[1]); + g_lingo->code2(e, f); } + | THEENTITYWITHID expr { + $$ = g_lingo->code1(g_lingo->c_theentitypush); + inst e = 0, f = 0; + WRITE_UINT32(&e, $1[0]); + WRITE_UINT32(&f, $1[1]); + g_lingo->code2(e, f); } + | asgn + | expr '+' expr { g_lingo->code1(g_lingo->c_add); } + | expr '-' expr { g_lingo->code1(g_lingo->c_sub); } + | expr '*' expr { g_lingo->code1(g_lingo->c_mul); } + | expr '/' expr { g_lingo->code1(g_lingo->c_div); } + | expr '>' expr { g_lingo->code1(g_lingo->c_gt); } + | expr '<' expr { g_lingo->code1(g_lingo->c_lt); } + | expr tNEQ expr { g_lingo->code1(g_lingo->c_neq); } + | expr tGE expr { g_lingo->code1(g_lingo->c_ge); } + | expr tLE expr { g_lingo->code1(g_lingo->c_le); } + | expr tAND expr { g_lingo->code1(g_lingo->c_and); } + | expr tOR expr { g_lingo->code1(g_lingo->c_or); } + | tNOT expr %prec UNARY { g_lingo->code1(g_lingo->c_not); } + | expr '&' expr { g_lingo->code1(g_lingo->c_ampersand); } + | expr tCONCAT expr { g_lingo->code1(g_lingo->c_concat); } + | expr tCONTAINS expr { g_lingo->code1(g_lingo->c_contains); } + | expr tSTARTS expr { g_lingo->code1(g_lingo->c_starts); } + | '+' expr %prec UNARY { $$ = $2; } + | '-' expr %prec UNARY { $$ = $2; g_lingo->code1(g_lingo->c_negate); } + | '(' expr ')' { $$ = $2; } + | tSPRITE expr tINTERSECTS expr { g_lingo->code1(g_lingo->c_intersects); } + | tSPRITE expr tWITHIN expr { g_lingo->code1(g_lingo->c_within); } + ; + +func: tPUT expr { g_lingo->code1(g_lingo->c_printtop); } + | gotofunc + | playfunc + | tEXIT { g_lingo->codeConst(0); // Push fake value on stack + g_lingo->code1(g_lingo->c_procret); } + | tGLOBAL globallist + | BLTINONEARG expr { + g_lingo->code1(g_lingo->_handlers[*$1]->u.func); + delete $1; } + | BLTINNOARGSORONE expr { + g_lingo->code1(g_lingo->_handlers[*$1]->u.func); + delete $1; } + | BLTINNOARGSORONE { + g_lingo->code2(g_lingo->c_voidpush, g_lingo->_handlers[*$1]->u.func); + delete $1; } + | BLTINARGLIST arglist { g_lingo->codeFunc($1, $2); } + | tOPEN expr tWITH expr { g_lingo->code1(g_lingo->c_open); } + | tOPEN expr { g_lingo->code2(g_lingo->c_voidpush, g_lingo->c_open); } + ; + +globallist: ID { g_lingo->code1(g_lingo->c_global); g_lingo->codeString($1->c_str()); delete $1; } + | globallist ',' ID { g_lingo->code1(g_lingo->c_global); g_lingo->codeString($3->c_str()); delete $3; } + ; + +// go {to} {frame} whichFrame {of movie whichMovie} +// go {to} {frame "Open23" of} movie whichMovie +// go loop +// go next +// go previous +// go to {frame} whichFrame {of movie whichMovie} +// go to {frame whichFrame of} movie whichMovie + +gotofunc: tGO tLOOP { g_lingo->code1(g_lingo->c_gotoloop); } + | tGO tNEXT { g_lingo->code1(g_lingo->c_gotonext); } + | tGO tPREVIOUS { g_lingo->code1(g_lingo->c_gotoprevious); } + | tGO gotoframe { + g_lingo->codeConst(1); + g_lingo->code1(g_lingo->c_goto); } + | tGO gotoframe gotomovie { + g_lingo->codeConst(3); + g_lingo->code1(g_lingo->c_goto); } + | tGO gotomovie { + g_lingo->codeConst(2); + g_lingo->code1(g_lingo->c_goto); } + ; + +gotoframe: tFRAME expr + | expr + ; + +gotomovie: tOF tMOVIE expr + | tMOVIE expr + ; + +playfunc: tPLAY tDONE { g_lingo->code1(g_lingo->c_playdone); } + | tPLAY gotoframe { + g_lingo->codeConst(1); + g_lingo->code1(g_lingo->c_play); } + | tPLAY gotoframe gotomovie { + g_lingo->codeConst(3); + g_lingo->code1(g_lingo->c_play); } + | tPLAY gotomovie { + g_lingo->codeConst(2); + g_lingo->code1(g_lingo->c_play); } + ; + +// macro +// +// Special Note The macro keyword is retained in Director 3.0 to maintain compatibility +// with scripts developed under Version 2.0. When writing new scripts, or editing old +// scripts, you should use handlers instead of macros. (Handlers are defined with the on keyword.) +// +// Syntax: +// +// -- [comment] +// macro macroName [argument1] [, argument2] +// [, argument3] +// [statement1] +// [statement2] +// +// Keyword. Defines a macro. A macro is a multiple-line script defined +// in the Text window. Macros can accept arguments (inputs) and +// optionally return a result. Macros can call other macros and can be +// called from any other script or factory. +// +// The first line of a castmember in the Text window that contains a macro must be +// a comment (--). You can define more than one macro in a given text castmember. +// The macro definition ends where the next macro (or factory) begins. +// +// See also: +// on keyword +defn: tMACRO ID { g_lingo->_indef = true; g_lingo->_currentFactory.clear(); } + begin argdef nl argstore stmtlist { + g_lingo->codeConst(0); // Push fake value on stack + g_lingo->code1(g_lingo->c_procret); + g_lingo->define(*$2, $4, $5); + g_lingo->_indef = false; } + | tFACTORY ID { + g_lingo->codeFactory(*$2); + } + | tMETHOD ID { g_lingo->_indef = true; } + begin argdef nl argstore stmtlist { + g_lingo->code1(STOP); + g_lingo->define(*$2, $4, $5 + 1, &g_lingo->_currentFactory); + g_lingo->_indef = false; } ; +argdef: /* nothing */ { $$ = 0; } + | ID { g_lingo->codeArg($1); $$ = 1; } + | argdef ',' ID { g_lingo->codeArg($3); $$ = $1 + 1; } + | argdef nl ',' ID { g_lingo->codeArg($4); $$ = $1 + 1; } + ; +argstore: /* nothing */ { g_lingo->codeArgStore(); } + ; + + +macro: ID begin arglist { + g_lingo->code1(g_lingo->c_call); + g_lingo->codeString($1->c_str()); + inst numpar = 0; + WRITE_UINT32(&numpar, $3); + g_lingo->code1(numpar); } + ; + +arglist: /* nothing */ { $$ = 0; } + | expr { $$ = 1; } + | arglist ',' expr { $$ = $1 + 1; } + ; + +%% diff --git a/engines/director/lingo/lingo-lex.cpp b/engines/director/lingo/lingo-lex.cpp new file mode 100644 index 0000000000..5fbd8d8653 --- /dev/null +++ b/engines/director/lingo/lingo-lex.cpp @@ -0,0 +1,2348 @@ +#line 2 "engines/director/lingo/lingo-lex.cpp" + +#line 4 "engines/director/lingo/lingo-lex.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +typedef uint64_t flex_uint64_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (yy_size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 56 +#define YY_END_OF_BUFFER 57 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[191] = + { 0, + 0, 0, 57, 55, 3, 53, 53, 55, 55, 52, + 52, 52, 51, 52, 52, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 2, 2, 3, 53, 0, 0, 0, 0, + 0, 54, 48, 1, 50, 51, 47, 45, 46, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 18, + 8, 49, 49, 49, 49, 49, 49, 49, 27, 49, + 29, 49, 49, 49, 49, 49, 49, 49, 49, 39, + 49, 49, 2, 2, 0, 1, 50, 4, 49, 49, + 49, 49, 12, 49, 49, 49, 49, 0, 49, 49, + + 49, 49, 49, 49, 26, 49, 49, 49, 32, 49, + 34, 49, 49, 49, 49, 49, 49, 0, 49, 6, + 7, 11, 14, 49, 49, 49, 0, 49, 20, 21, + 49, 49, 49, 25, 28, 30, 49, 49, 49, 49, + 0, 38, 43, 49, 41, 10, 49, 49, 15, 49, + 17, 49, 22, 49, 24, 49, 49, 49, 49, 37, + 44, 49, 0, 49, 49, 16, 49, 23, 49, 33, + 40, 35, 0, 42, 0, 49, 13, 49, 49, 0, + 9, 5, 49, 31, 0, 49, 0, 19, 36, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 5, 1, 6, 1, 1, 7, 8, 1, 7, + 7, 7, 7, 7, 9, 10, 7, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 7, 1, 12, + 13, 14, 1, 1, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 24, 25, 26, 27, 28, 29, + 24, 30, 31, 32, 33, 34, 35, 36, 37, 24, + 1, 1, 1, 7, 38, 1, 39, 40, 41, 42, + + 43, 44, 45, 46, 47, 24, 24, 48, 49, 50, + 51, 52, 24, 53, 54, 55, 56, 57, 58, 59, + 60, 24, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[61] = + { 0, + 1, 2, 3, 3, 2, 1, 1, 1, 1, 1, + 4, 1, 1, 1, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 + } ; + +static yyconst flex_int16_t yy_base[196] = + { 0, + 0, 59, 203, 452, 63, 67, 71, 75, 167, 452, + 157, 154, 52, 68, 143, 56, 0, 56, 57, 67, + 72, 68, 68, 69, 85, 102, 102, 104, 80, 119, + 113, 120, 173, 177, 181, 452, 185, 189, 193, 102, + 99, 452, 452, 0, 80, 129, 452, 452, 452, 0, + 91, 120, 165, 118, 126, 146, 184, 187, 171, 96, + 0, 172, 177, 189, 178, 177, 178, 184, 0, 188, + 0, 202, 199, 188, 192, 192, 199, 220, 219, 0, + 226, 208, 251, 262, 217, 0, 78, 0, 219, 227, + 230, 239, 0, 228, 229, 242, 256, 273, 257, 250, + + 251, 255, 263, 256, 0, 262, 253, 258, 0, 274, + 0, 271, 267, 304, 271, 274, 273, 284, 299, 0, + 0, 0, 0, 279, 297, 308, 297, 296, 0, 0, + 301, 304, 314, 0, 0, 0, 311, 320, 305, 307, + 156, 0, 0, 322, 319, 341, 321, 320, 0, 326, + 452, 322, 0, 327, 0, 328, 329, 344, 336, 370, + 0, 343, 375, 344, 341, 0, 345, 0, 348, 0, + 0, 0, 380, 0, 363, 355, 0, 372, 360, 372, + 452, 0, 363, 0, 394, 366, 398, 0, 400, 452, + 431, 433, 438, 442, 446 + + } ; + +static yyconst flex_int16_t yy_def[196] = + { 0, + 190, 1, 190, 190, 190, 190, 190, 190, 191, 190, + 190, 190, 190, 190, 190, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 190, 190, 190, 190, 190, 190, 190, 190, + 191, 190, 190, 193, 190, 190, 190, 190, 190, 192, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 190, 190, 190, 193, 190, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 190, 192, 192, + + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 190, 192, 192, + 192, 192, 192, 192, 192, 192, 190, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 194, 192, 192, 192, 192, 190, 192, 192, 192, 192, + 190, 192, 192, 192, 192, 192, 192, 192, 192, 194, + 192, 192, 190, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 190, 192, 190, 192, 192, 192, 192, 190, + 190, 192, 192, 192, 190, 192, 195, 192, 195, 0, + 190, 190, 190, 190, 190 + + } ; + +static yyconst flex_int16_t yy_nxt[513] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 4, + 13, 14, 10, 15, 16, 17, 18, 19, 20, 21, + 22, 17, 23, 17, 24, 25, 26, 27, 28, 29, + 30, 31, 17, 17, 32, 17, 17, 17, 16, 17, + 18, 19, 20, 21, 22, 17, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 17, 17, 32, 17, 17, + 33, 45, 46, 34, 35, 36, 36, 37, 38, 39, + 39, 38, 38, 39, 39, 38, 37, 36, 36, 37, + 47, 48, 51, 52, 53, 40, 57, 61, 87, 40, + 87, 54, 59, 55, 62, 60, 63, 98, 75, 64, + + 98, 58, 56, 65, 42, 51, 52, 53, 88, 40, + 57, 61, 66, 40, 54, 59, 55, 62, 60, 63, + 67, 69, 75, 64, 58, 56, 85, 65, 72, 68, + 70, 71, 88, 73, 79, 66, 74, 76, 45, 46, + 80, 81, 82, 93, 67, 69, 89, 77, 92, 85, + 78, 72, 68, 70, 71, 49, 73, 141, 79, 74, + 141, 76, 44, 80, 43, 81, 82, 93, 94, 89, + 77, 92, 42, 78, 83, 36, 36, 84, 84, 36, + 36, 84, 35, 36, 36, 37, 37, 36, 36, 37, + 38, 90, 94, 38, 38, 39, 39, 38, 97, 91, + + 95, 96, 190, 99, 100, 101, 106, 40, 190, 102, + 103, 40, 190, 104, 90, 105, 107, 108, 190, 109, + 110, 97, 91, 111, 95, 96, 99, 100, 112, 101, + 106, 40, 102, 103, 113, 40, 104, 114, 105, 117, + 107, 108, 109, 110, 115, 120, 111, 118, 116, 190, + 119, 112, 83, 36, 36, 84, 121, 122, 113, 123, + 124, 114, 117, 84, 36, 36, 84, 125, 115, 120, + 118, 126, 116, 119, 98, 128, 132, 98, 130, 121, + 131, 122, 123, 124, 129, 133, 190, 134, 135, 136, + 125, 137, 138, 139, 145, 126, 140, 143, 144, 128, + + 132, 130, 146, 131, 127, 141, 148, 129, 141, 133, + 134, 135, 136, 147, 137, 149, 138, 139, 145, 140, + 143, 144, 150, 190, 151, 152, 146, 127, 153, 148, + 142, 154, 155, 156, 157, 190, 158, 147, 159, 149, + 161, 162, 163, 164, 168, 163, 150, 151, 152, 165, + 166, 153, 167, 142, 154, 169, 155, 156, 157, 158, + 170, 159, 171, 178, 161, 162, 172, 164, 168, 174, + 176, 173, 165, 166, 173, 167, 163, 177, 169, 163, + 179, 173, 181, 170, 173, 182, 171, 178, 183, 172, + 184, 185, 174, 176, 186, 187, 188, 175, 187, 187, + + 177, 190, 187, 179, 190, 190, 181, 180, 182, 190, + 190, 190, 183, 184, 190, 185, 190, 186, 190, 188, + 190, 175, 190, 190, 190, 190, 190, 190, 190, 190, + 180, 41, 41, 190, 41, 41, 50, 50, 86, 86, + 190, 86, 86, 160, 190, 190, 160, 189, 190, 190, + 189, 3, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190 + } ; + +static yyconst flex_int16_t yy_chk[513] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 13, 13, 2, 5, 5, 5, 5, 6, 6, + 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 14, 14, 16, 18, 19, 6, 21, 23, 87, 7, + 45, 20, 22, 20, 23, 22, 24, 60, 29, 25, + + 60, 21, 20, 25, 41, 16, 18, 19, 51, 6, + 21, 23, 25, 7, 20, 22, 20, 23, 22, 24, + 26, 27, 29, 25, 21, 20, 40, 25, 28, 26, + 27, 27, 51, 28, 31, 25, 28, 30, 46, 46, + 31, 32, 32, 55, 26, 27, 52, 30, 54, 40, + 30, 28, 26, 27, 27, 15, 28, 141, 31, 28, + 141, 30, 12, 31, 11, 32, 32, 55, 56, 52, + 30, 54, 9, 30, 33, 33, 33, 33, 34, 34, + 34, 34, 35, 35, 35, 35, 37, 37, 37, 37, + 38, 53, 56, 38, 39, 39, 39, 39, 59, 53, + + 57, 58, 3, 62, 63, 64, 70, 38, 0, 65, + 66, 39, 0, 67, 53, 68, 72, 73, 0, 74, + 75, 59, 53, 76, 57, 58, 62, 63, 77, 64, + 70, 38, 65, 66, 78, 39, 67, 79, 68, 82, + 72, 73, 74, 75, 81, 90, 76, 85, 81, 0, + 89, 77, 83, 83, 83, 83, 91, 92, 78, 94, + 95, 79, 82, 84, 84, 84, 84, 96, 81, 90, + 85, 97, 81, 89, 98, 99, 102, 98, 100, 91, + 101, 92, 94, 95, 99, 103, 0, 104, 106, 107, + 96, 108, 110, 112, 117, 97, 113, 115, 116, 99, + + 102, 100, 118, 101, 98, 114, 124, 99, 114, 103, + 104, 106, 107, 119, 108, 125, 110, 112, 117, 113, + 115, 116, 126, 0, 127, 128, 118, 98, 131, 124, + 114, 132, 133, 137, 138, 0, 139, 119, 140, 125, + 144, 145, 146, 147, 154, 146, 126, 127, 128, 148, + 150, 131, 152, 114, 132, 156, 133, 137, 138, 139, + 157, 140, 158, 167, 144, 145, 159, 147, 154, 162, + 164, 160, 148, 150, 160, 152, 163, 165, 156, 163, + 169, 173, 175, 157, 173, 176, 158, 167, 178, 159, + 179, 180, 162, 164, 183, 185, 186, 163, 185, 187, + + 165, 189, 187, 169, 189, 0, 175, 173, 176, 0, + 0, 0, 178, 179, 0, 180, 0, 183, 0, 186, + 0, 163, 0, 0, 0, 0, 0, 0, 0, 0, + 173, 191, 191, 0, 191, 191, 192, 192, 193, 193, + 0, 193, 193, 194, 0, 0, 194, 195, 0, 0, + 195, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "engines/director/lingo/lingo-lex.l" +/* 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. + * + */ +#line 25 "engines/director/lingo/lingo-lex.l" + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/str.h" + +#include "director/lingo/lingo.h" +#include "director/lingo/lingo-gr.h" + +using namespace Director; + +int yyparse(); +static void count() { + g_lingo->_colnumber += strlen(yytext); +} + +#if defined(__PLAYSTATION2__) || defined(_MSC_VER) +// Stub for missing function +int isatty(int fileno) { return 0; } +#endif + +#ifdef _MSC_VER +#define YY_NO_UNISTD_H +#endif + +static void countnl() { + char *p = yytext; + + while(*p == '\n' || *p == '\r') + p++; + + g_lingo->_linenumber++; + g_lingo->_colnumber = strlen(p); +} + +#line 688 "engines/director/lingo/lingo-lex.cpp" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include <unistd.h> +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (void ); + +int yyget_debug (void ); + +void yyset_debug (int debug_flag ); + +YY_EXTRA_TYPE yyget_extra (void ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in (void ); + +void yyset_in (FILE * in_str ); + +FILE *yyget_out (void ); + +void yyset_out (FILE * out_str ); + +yy_size_t yyget_leng (void ); + +char *yyget_text (void ); + +int yyget_lineno (void ); + +void yyset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + yy_size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + if ( yyleng > 0 ) \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ + (yytext[yyleng - 1] == '\n'); \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 69 "engines/director/lingo/lingo-lex.l" + + +#line 876 "engines/director/lingo/lingo-lex.cpp" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); + yy_current_state += YY_AT_BOL(); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 191 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 452 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 71 "engines/director/lingo/lingo-lex.l" + + YY_BREAK +case 2: +YY_RULE_SETUP +#line 72 "engines/director/lingo/lingo-lex.l" +{ count(); } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 73 "engines/director/lingo/lingo-lex.l" +{ count(); return ' '; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 75 "engines/director/lingo/lingo-lex.l" +{ count(); return tAND; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 76 "engines/director/lingo/lingo-lex.l" +{ count(); return tCONTAINS; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 77 "engines/director/lingo/lingo-lex.l" +{ count(); return tDONE; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 78 "engines/director/lingo/lingo-lex.l" +{ count(); return tDOWN; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 79 "engines/director/lingo/lingo-lex.l" +{ count(); return tIF; } + YY_BREAK +case 9: +/* rule 9 can match eol */ +YY_RULE_SETUP +#line 80 "engines/director/lingo/lingo-lex.l" +{ countnl(); return tNLELSIF; } + YY_BREAK +case 10: +/* rule 10 can match eol */ +YY_RULE_SETUP +#line 81 "engines/director/lingo/lingo-lex.l" +{ countnl(); return tNLELSE; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 82 "engines/director/lingo/lingo-lex.l" +{ count(); return tELSE; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 83 "engines/director/lingo/lingo-lex.l" +{ count(); return tEND; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 84 "engines/director/lingo/lingo-lex.l" +{ count(); return tFACTORY; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 85 "engines/director/lingo/lingo-lex.l" +{ count(); return tEXIT; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 86 "engines/director/lingo/lingo-lex.l" +{ count(); return tFRAME; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 87 "engines/director/lingo/lingo-lex.l" +{ count(); return tGLOBAL; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 88 "engines/director/lingo/lingo-lex.l" +{ count(); return tGO; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 89 "engines/director/lingo/lingo-lex.l" +{ count(); return tGO; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 90 "engines/director/lingo/lingo-lex.l" +{ count(); return tINTERSECTS; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 91 "engines/director/lingo/lingo-lex.l" +{ count(); return tINTO; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 92 "engines/director/lingo/lingo-lex.l" +{ count(); return tLOOP; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 93 "engines/director/lingo/lingo-lex.l" +{ count(); return tMACRO; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 94 "engines/director/lingo/lingo-lex.l" +{ count(); return tMETHOD; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 95 "engines/director/lingo/lingo-lex.l" +{ count(); return tMOVIE; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 96 "engines/director/lingo/lingo-lex.l" +{ count(); return tNEXT; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 97 "engines/director/lingo/lingo-lex.l" +{ count(); return tNOT; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 98 "engines/director/lingo/lingo-lex.l" +{ count(); return tOF; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 99 "engines/director/lingo/lingo-lex.l" +{ count(); return tOPEN; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 100 "engines/director/lingo/lingo-lex.l" +{ count(); return tOR; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 101 "engines/director/lingo/lingo-lex.l" +{ count(); return tPLAY; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 102 "engines/director/lingo/lingo-lex.l" +{ count(); return tPREVIOUS; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 103 "engines/director/lingo/lingo-lex.l" +{ count(); return tPUT; } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 104 "engines/director/lingo/lingo-lex.l" +{ count(); return tREPEAT; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 105 "engines/director/lingo/lingo-lex.l" +{ count(); return tSET; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 106 "engines/director/lingo/lingo-lex.l" +{ count(); return tSTARTS; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 107 "engines/director/lingo/lingo-lex.l" +{ + count(); + + const char *ptr = &yytext[4]; // Skip 'the ' + while (*ptr == ' ' || *ptr == '\t') + ptr++; + + Common::String field; + while (*ptr != ' ' && *ptr != '\t') + field += *ptr++; + + while (*ptr == ' ' || *ptr == '\t') + ptr++; + + ptr += 3; // Skip 'of ' + + while (*ptr == ' ' || *ptr == '\t') + ptr++; + + if (g_lingo->_theEntities.contains(ptr)) { + field = Common::String::format("%d%s", g_lingo->_theEntities[ptr]->entity, field.c_str()); + + if (!g_lingo->_theEntityFields.contains(field)) { + error("Unhandled the field %s", ptr); + } + + if (g_lingo->_theEntityFields[field]->entity != g_lingo->_theEntities[ptr]->entity) + error("Unsupported field '%s' for entity '%s'", field.c_str(), ptr); + + yylval.e[0] = g_lingo->_theEntities[ptr]->entity; + yylval.e[1] = g_lingo->_theEntityFields[field]->field; + + if (g_lingo->_theEntities[ptr]->hasId) + return THEENTITYWITHID; + else + return THEENTITY; + } + + warning("Unhandled the entity %s", ptr); + } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 147 "engines/director/lingo/lingo-lex.l" +{ + count(); + + const char *ptr = &yytext[4]; // Skip 'the ' + while (*ptr == ' ' || *ptr == '\t') + ptr++; + + if (g_lingo->_theEntities.contains(ptr)) { + yylval.e[0] = g_lingo->_theEntities[ptr]->entity; + yylval.e[1] = 0; // No field + + if (g_lingo->_theEntities[ptr]->hasId) + return THEENTITYWITHID; + else + return THEENTITY; + } + + warning("Unhandled the entity %s", ptr); + } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 166 "engines/director/lingo/lingo-lex.l" +{ count(); return tTHEN; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 167 "engines/director/lingo/lingo-lex.l" +{ count(); return tTO; } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 168 "engines/director/lingo/lingo-lex.l" +{ count(); return tSPRITE; } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 169 "engines/director/lingo/lingo-lex.l" +{ count(); return tWITH; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 170 "engines/director/lingo/lingo-lex.l" +{ count(); return tWITHIN; } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 171 "engines/director/lingo/lingo-lex.l" +{ count(); return tWHEN; } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 172 "engines/director/lingo/lingo-lex.l" +{ count(); return tWHILE; } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 174 "engines/director/lingo/lingo-lex.l" +{ count(); return tNEQ; } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 175 "engines/director/lingo/lingo-lex.l" +{ count(); return tGE; } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 176 "engines/director/lingo/lingo-lex.l" +{ count(); return tLE; } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 177 "engines/director/lingo/lingo-lex.l" +{ count(); return tCONCAT; } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 179 "engines/director/lingo/lingo-lex.l" +{ + count(); + yylval.s = new Common::String(yytext); + + if (g_lingo->_handlers.contains(yytext)) { + if (g_lingo->_handlers[yytext]->type == BLTIN && g_lingo->_handlers[yytext]->parens == false) { + if (g_lingo->_handlers[yytext]->nargs == 0) { + if (g_lingo->_handlers[yytext]->maxArgs == 0) + return BLTINNOARGS; + else if (g_lingo->_handlers[yytext]->maxArgs == 1) + return BLTINNOARGSORONE; + else + error("Incorrect setup for builtin: %s", yytext); + } else if (g_lingo->_handlers[yytext]->nargs == 1 && + g_lingo->_handlers[yytext]->maxArgs == 1) { + return BLTINONEARG; + } else if (g_lingo->_handlers[yytext]->nargs == -1) { + return BLTINARGLIST; + } else { + error("Incorrect setup for builtin: %s", yytext); + } + } + } + + return ID; + } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 205 "engines/director/lingo/lingo-lex.l" +{ count(); yylval.f = atof(yytext); return FLOAT; } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 206 "engines/director/lingo/lingo-lex.l" +{ count(); yylval.i = strtol(yytext, NULL, 10); return INT; } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 207 "engines/director/lingo/lingo-lex.l" +{ count(); return *yytext; } + YY_BREAK +case 53: +/* rule 53 can match eol */ +YY_RULE_SETUP +#line 208 "engines/director/lingo/lingo-lex.l" +{ return '\n'; } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 209 "engines/director/lingo/lingo-lex.l" +{ count(); yylval.s = new Common::String(&yytext[1]); yylval.s->deleteLastChar(); return STRING; } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 210 "engines/director/lingo/lingo-lex.l" + + YY_BREAK +case 56: +YY_RULE_SETUP +#line 212 "engines/director/lingo/lingo-lex.l" +ECHO; + YY_BREAK +#line 1325 "engines/director/lingo/lingo-lex.cpp" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + yy_current_state += YY_AT_BOL(); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 191 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 191 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 190); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register yy_size_t number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n, i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +yy_size_t yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 212 "engines/director/lingo/lingo-lex.l" + + + +extern int yydebug; + +namespace Director { + +int Lingo::parse(const char *code) { + YY_BUFFER_STATE bp; + + yydebug = 0; + + yy_delete_buffer(YY_CURRENT_BUFFER); + + bp = yy_scan_string(code); + yy_switch_to_buffer(bp); + yyparse(); + yy_delete_buffer(bp); + + return 0; +} + +} + diff --git a/engines/director/lingo/lingo-lex.l b/engines/director/lingo/lingo-lex.l new file mode 100644 index 0000000000..8c89a99764 --- /dev/null +++ b/engines/director/lingo/lingo-lex.l @@ -0,0 +1,233 @@ +/* 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. + * + */ + +%option noyywrap +%{ + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/str.h" + +#include "director/lingo/lingo.h" +#include "director/lingo/lingo-gr.h" + +using namespace Director; + +int yyparse(); +static void count() { + g_lingo->_colnumber += strlen(yytext); +} + +#if defined(__PLAYSTATION2__) || defined(_MSC_VER) +// Stub for missing function +int isatty(int fileno) { return 0; } +#endif + +#ifdef _MSC_VER +#define YY_NO_UNISTD_H +#endif + +static void countnl() { + char *p = yytext; + + while(*p == '\n' || *p == '\r') + p++; + + g_lingo->_linenumber++; + g_lingo->_colnumber = strlen(p); +} + +%} + +identifier [_[:alpha:]][_[:alnum:]]* +constfloat [[:digit:]]+\.[[:digit:]]* +constinteger [[:digit:]]+ +conststring \"[^\"\r\n]*\" +operator [-+*/%=^:,()><&] +newline [ \t]*[\n\r] +whitespace [\t ] + +%% + +--[^\r\n]* +^{whitespace}+ { count(); } +[\t]+ { count(); return ' '; } + +(?i:and) { count(); return tAND; } +(?i:contains) { count(); return tCONTAINS; } +(?i:done) { count(); return tDONE; } +(?i:down) { count(); return tDOWN; } +(?i:if) { count(); return tIF; } +(?i:[\n\r]+[\t ]*else[\t ]+if) { countnl(); return tNLELSIF; } +(?i:[\n\r]+[\t ]*else) { countnl(); return tNLELSE; } +(?i:else) { count(); return tELSE; } +(?i:end) { count(); return tEND; } +(?i:factory) { count(); return tFACTORY; } +(?i:exit) { count(); return tEXIT; } +(?i:frame) { count(); return tFRAME; } +(?i:global) { count(); return tGLOBAL; } +(?i:go[\t ]+to) { count(); return tGO; } +(?i:go) { count(); return tGO; } +(?i:intersects) { count(); return tINTERSECTS; } +(?i:into) { count(); return tINTO; } +(?i:loop) { count(); return tLOOP; } +(?i:macro) { count(); return tMACRO; } +(?i:method) { count(); return tMETHOD; } +(?i:movie) { count(); return tMOVIE; } +(?i:next) { count(); return tNEXT; } +(?i:not) { count(); return tNOT; } +(?i:of) { count(); return tOF; } +(?i:open) { count(); return tOPEN; } +(?i:or) { count(); return tOR; } +(?i:play) { count(); return tPLAY; } +(?i:previous) { count(); return tPREVIOUS; } +(?i:put) { count(); return tPUT; } +(?i:repeat) { count(); return tREPEAT; } +(?i:set) { count(); return tSET; } +(?i:starts) { count(); return tSTARTS; } +(?i:the[ \t]+[[:alpha:]]+[\t ]+of[\t ]+[[:alpha:]]+) { + count(); + + const char *ptr = &yytext[4]; // Skip 'the ' + while (*ptr == ' ' || *ptr == '\t') + ptr++; + + Common::String field; + while (*ptr != ' ' && *ptr != '\t') + field += *ptr++; + + while (*ptr == ' ' || *ptr == '\t') + ptr++; + + ptr += 3; // Skip 'of ' + + while (*ptr == ' ' || *ptr == '\t') + ptr++; + + if (g_lingo->_theEntities.contains(ptr)) { + field = Common::String::format("%d%s", g_lingo->_theEntities[ptr]->entity, field.c_str()); + + if (!g_lingo->_theEntityFields.contains(field)) { + error("Unhandled the field %s", ptr); + } + + if (g_lingo->_theEntityFields[field]->entity != g_lingo->_theEntities[ptr]->entity) + error("Unsupported field '%s' for entity '%s'", field.c_str(), ptr); + + yylval.e[0] = g_lingo->_theEntities[ptr]->entity; + yylval.e[1] = g_lingo->_theEntityFields[field]->field; + + if (g_lingo->_theEntities[ptr]->hasId) + return THEENTITYWITHID; + else + return THEENTITY; + } + + warning("Unhandled the entity %s", ptr); + } +(?i:the[ \t]+[[:alpha:]]+) { + count(); + + const char *ptr = &yytext[4]; // Skip 'the ' + while (*ptr == ' ' || *ptr == '\t') + ptr++; + + if (g_lingo->_theEntities.contains(ptr)) { + yylval.e[0] = g_lingo->_theEntities[ptr]->entity; + yylval.e[1] = 0; // No field + + if (g_lingo->_theEntities[ptr]->hasId) + return THEENTITYWITHID; + else + return THEENTITY; + } + + warning("Unhandled the entity %s", ptr); + } +(?i:then) { count(); return tTHEN; } +(?i:to) { count(); return tTO; } +(?i:sprite) { count(); return tSPRITE; } +(?i:with) { count(); return tWITH; } +(?i:within) { count(); return tWITHIN; } +(?i:when) { count(); return tWHEN; } +(?i:while) { count(); return tWHILE; } + +[<][>] { count(); return tNEQ; } +[>][=] { count(); return tGE; } +[<][=] { count(); return tLE; } +[&][&] { count(); return tCONCAT; } + +{identifier} { + count(); + yylval.s = new Common::String(yytext); + + if (g_lingo->_handlers.contains(yytext)) { + if (g_lingo->_handlers[yytext]->type == BLTIN && g_lingo->_handlers[yytext]->parens == false) { + if (g_lingo->_handlers[yytext]->nargs == 0) { + if (g_lingo->_handlers[yytext]->maxArgs == 0) + return BLTINNOARGS; + else if (g_lingo->_handlers[yytext]->maxArgs == 1) + return BLTINNOARGSORONE; + else + error("Incorrect setup for builtin: %s", yytext); + } else if (g_lingo->_handlers[yytext]->nargs == 1 && + g_lingo->_handlers[yytext]->maxArgs == 1) { + return BLTINONEARG; + } else if (g_lingo->_handlers[yytext]->nargs == -1) { + return BLTINARGLIST; + } else { + error("Incorrect setup for builtin: %s", yytext); + } + } + } + + return ID; + } +{constfloat} { count(); yylval.f = atof(yytext); return FLOAT; } +{constinteger} { count(); yylval.i = strtol(yytext, NULL, 10); return INT; } +{operator} { count(); return *yytext; } +{newline} { return '\n'; } +{conststring} { count(); yylval.s = new Common::String(&yytext[1]); yylval.s->deleteLastChar(); return STRING; } +. + +%% + +extern int yydebug; + +namespace Director { + +int Lingo::parse(const char *code) { + YY_BUFFER_STATE bp; + + yydebug = 0; + + yy_delete_buffer(YY_CURRENT_BUFFER); + + bp = yy_scan_string(code); + yy_switch_to_buffer(bp); + yyparse(); + yy_delete_buffer(bp); + + return 0; +} + +} diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp new file mode 100644 index 0000000000..3f4f9cc432 --- /dev/null +++ b/engines/director/lingo/lingo-the.cpp @@ -0,0 +1,603 @@ +/* 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 "engines/director/lingo/lingo.h" + +namespace Director { + +class Sprite; + +TheEntity entities[] = { + { kTheCast, "cast", true }, + { kTheClickOn, "clickOn", false }, + { kTheColorDepth, "colorDepth", false }, + { kTheColorQD, "colorQD", false }, + { kTheCommandDown, "commandDown", false }, + { kTheControlDown, "controlDown", false }, + { kTheDoubleClick, "doubleClick", false }, + { kTheExitLock, "exitlock", false }, + { kTheFloatPrecision, "floatPrecision", false }, + { kTheFrame, "frame", false }, + { kTheItemDelimiter, "itemDelimiter", false }, + { kTheKey, "key", false }, + { kTheKeyCode, "keycode", false }, + { kTheLastClick, "lastClick", false }, + { kTheLastEvent, "lastEvent", false }, + { kTheLastFrame, "lastFrame", false }, + { kTheMenu, "menu", true }, + { kTheMenus, "menus", false }, + { kTheMenuItem, "menuitem", true }, + { kTheMenuItems, "menuitems", false }, + { kTheMouseDown, "mouseDown", false }, + { kTheMouseDownScript, "mouseDownScript", false }, + { kTheMouseH, "mouseh", false }, + { kTheMouseUp, "mouseUp", false }, + { kTheMouseUpScript, "mouseUpScript", false }, + { kTheMouseV, "mousev", false }, + { kTheMovie, "movie", false }, + { kTheMultiSound, "multiSound", false }, + { kTheOptionDown, "optionDown", false }, + { kThePathName, "pathname", false }, + { kThePerFrameHook, "perframehook", false }, + { kThePreloadEventAbort,"preloadEventAbort",false }, + { kTheRightMouseDown, "rightMouseDown", false }, + { kTheRightMouseUp, "rightMouseUp", false }, + { kTheRomanLingo, "romanLingo", false }, + { kTheShiftDown, "shiftDown", false }, + { kTheSprite, "sprite", true }, + { kTheStage, "stage", false }, + { kTheStillDown, "stillDown", false }, + { kTheTicks, "ticks", false }, + { kTheTimeoutLength, "timeoutlength", false }, + { kTheTimer, "timer", false }, + { kTheWindow, "window", false }, + { kTheNOEntity, NULL, false } +}; + +TheEntityField fields[] = { + { kTheSprite, "backColor", kTheBackColor }, + { kTheSprite, "blend", kTheBlend }, + { kTheSprite, "bottom", kTheBottom }, + { kTheSprite, "castnum", kTheCastNum }, + { kTheSprite, "constraint", kTheConstraint }, + { kTheSprite, "cursor", kTheCursor }, + { kTheSprite, "editableText", kTheEditableText }, + { kTheSprite, "foreColor", kTheForeColor }, + { kTheSprite, "height", kTheHeight }, + { kTheSprite, "ink", kTheInk }, + { kTheSprite, "left", kTheLeft }, + { kTheSprite, "lineSize", kTheLineSize }, + { kTheSprite, "loch", kTheLocH }, + { kTheSprite, "locv", kTheLocV }, + { kTheSprite, "moveable", kTheMoveable }, + { kTheSprite, "movieRate", kTheMovieRate }, + { kTheSprite, "movieTime", kTheMovieTime }, + { kTheSprite, "right", kTheRight }, + { kTheSprite, "scriptNum", kTheScriptNum }, + { kTheSprite, "startTime", kTheStartTime }, + { kTheSprite, "stretch", kTheStrech }, + { kTheSprite, "stopTime", kTheStopTime }, + { kTheSprite, "top", kTheTop }, + { kTheSprite, "trails", kTheTrails }, + { kTheSprite, "type", kTheType }, + { kTheSprite, "visible", kTheVisible }, + { kTheSprite, "volume", kTheVolume }, + { kTheSprite, "width", kTheWidth }, + + // Common cast fields + { kTheCast, "castType", kTheCastType }, + { kTheCast, "filename", kTheFilename }, + { kTheCast, "height", kTheHeight }, + { kTheCast, "loaded", kTheLoaded }, + { kTheCast, "modified", kTheModified }, + { kTheCast, "name", kTheName }, + { kTheCast, "number", kTheNumber }, + { kTheCast, "rect", kTheRect }, + { kTheCast, "purgePriority",kThePurgePriority }, // 0 Never purge, 1 Purge Last, 2 Purge next, 2 Purge normal + { kTheCast, "scriptText", kTheScriptText }, + { kTheCast, "width", kTheWidth }, + + // Shape fields + { kTheCast, "backColor", kTheBackColor }, + { kTheCast, "foreColor", kTheForeColor }, + + // Digital video fields + { kTheCast, "controller", kTheController }, + { kTheCast, "directToStage",kTheDirectToStage }, + { kTheCast, "frameRate", kTheFrameRate }, + { kTheCast, "loop", kTheLoop }, + { kTheCast, "pausedAtStart",kThePausedAtStart }, + { kTheCast, "preload", kThePreload }, + { kTheCast, "sound", kTheSound }, // 0-1 off-on + + // Bitmap fields + { kTheCast, "depth", kTheDepth }, + { kTheCast, "regPoint", kTheRegPoint }, + { kTheCast, "palette", kThePalette }, + { kTheCast, "picture", kThePicture }, + + // TextCast fields + { kTheCast, "hilite", kTheHilite }, + { kTheCast, "size", kTheSize }, + { kTheCast, "text", kTheText }, + + { kTheWindow, "drawRect", kTheDrawRect }, + { kTheWindow, "filename", kTheFilename }, + { kTheWindow, "sourceRect", kTheSourceRect }, + { kTheWindow, "visible", kTheVisible }, + + { kTheMenuItem, "checkmark", kTheCheckMark }, + { kTheMenuItem, "enabled", kTheEnabled }, + { kTheMenuItem, "name", kTheName }, + { kTheMenuItem, "script", kTheScript }, + + { kTheMenu, "name", kTheName }, + + { kTheMenuItems,"number", kTheNumber }, + { kTheMenus, "number", kTheNumber }, + + { kTheNOEntity, NULL, kTheNOField } +}; + +void Lingo::initTheEntities() { + TheEntity *e = entities; + + while (e->entity != kTheNOEntity) { + _theEntities[e->name] = e; + e++; + } + + TheEntityField *f = fields; + + while (f->entity != kTheNOEntity) { + _theEntityFields[Common::String::format("%d%s", f->entity, f->name)] = f; + f++; + } +} + +void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) { + switch (entity) { + case kTheSprite: + setTheSprite(id, field, d); + break; + case kThePerFrameHook: + warning("STUB: setting the perframehook"); + break; + case kTheFloatPrecision: + _floatPrecision = d.toInt(); + _floatPrecision = MAX(0, MIN(_floatPrecision, 19)); // 0 to 19 + _floatPrecisionFormat = Common::String::format("%%.%df", _floatPrecision); + warning("set to %d: %s", _floatPrecision, _floatPrecisionFormat.c_str()); + break; + default: + warning("Unprocessed setting field %d of entity %d", field, entity); + } +} + +void Lingo::setTheSprite(Datum &id1, int field, Datum &d) { + int id = 0; + + if (id1.type == INT) { + id = id1.u.i; + } else { + warning("Unknown the sprite id type: %s", id1.type2str()); + return; + } + + d.toInt(); // Enforce Integer + + if (!_vm->_currentScore) { + warning("The sprite %d field %d setting over non-active score", id, field); + return; + } + + Sprite *sprite = _vm->_currentScore->getSpriteById(id); + + if (!sprite) + return; + + switch (field) { + case kTheCastNum: + if (_vm->_currentScore->_casts.contains(d.u.i)) { + sprite->_cast = _vm->_currentScore->_casts[d.u.i]; + sprite->_castId = d.u.i; + } + break; + case kTheWidth: + sprite->_width = d.u.i; + break; + case kTheHeight: + sprite->_height = d.u.i; + break; + case kTheTrails: + sprite->_trails = d.u.i; + break; + case kTheInk: + sprite->_ink = static_cast<InkType>(d.u.i); + break; + case kTheLocH: + sprite->_startPoint.x = d.u.i; + break; + case kTheLocV: + sprite->_startPoint.y = d.u.i; + break; + case kTheConstraint: + sprite->_constraint = d.u.i; + break; + case kTheMoveable: + sprite->_moveable = d.u.i; + break; + case kTheBackColor: + sprite->_backColor = d.u.i; + break; + case kTheForeColor: + sprite->_foreColor = d.u.i; + break; + case kTheLeft: + sprite->_left = d.u.i; + break; + case kTheRight: + sprite->_right = d.u.i; + break; + case kTheTop: + sprite->_top = d.u.i; + break; + case kTheBottom: + sprite->_bottom = d.u.i; + break; + case kTheBlend: + sprite->_blend = d.u.i; + break; + case kTheVisible: + sprite->_visible = (d.u.i == 0 ? false : true); + break; + case kTheType: + sprite->_type = static_cast<SpriteType>(d.u.i); + break; + case kTheMovieRate: + sprite->_movieRate = d.u.i; + break; + case kTheMovieTime: + sprite->_movieTime = d.u.i; + break; + case kTheStopTime: + sprite->_stopTime = d.u.i; + break; + case kTheStartTime: + sprite->_startTime = d.u.i; + break; + case kTheStretch: + sprite->_stretch = d.u.i; + break; + case kTheVolume: + sprite->_volume = d.u.i; + break; + case kTheLineSize: + sprite->_lineSize = d.u.i; + break; + case kTheEditableText: + sprite->_editableText = *d.toString(); + break; + default: + warning("Unprocessed setting field %d of sprite", field); + } +} + +Datum Lingo::getTheEntity(int entity, Datum &id, int field) { + Datum d; + + switch (entity) { + case kTheSprite: + d = getTheSprite(id, field); + break; + case kTheCast: + d = getTheCast(id, field); + case kThePerFrameHook: + warning("STUB: getting the perframehook"); + break; + case kTheFloatPrecision: + d.type = INT; + d.u.i = _floatPrecision; + break; + default: + warning("Unprocessed getting field %d of entity %d", field, entity); + d.type = VOID; + } + + return d; +} + +Datum Lingo::getTheSprite(Datum &id1, int field) { + Datum d; + int id = 0; + + if (id1.type == INT) { + id = id1.u.i; + } else { + warning("Unknown the sprite id type: %s", id1.type2str()); + return d; + } + + if (!_vm->_currentScore) { + warning("The sprite %d field %d setting over non-active score", id, field); + return d; + } + + Sprite *sprite = _vm->_currentScore->getSpriteById(id); + + if (!sprite) + return d; + + d.type = INT; + + switch (field) { + case kTheCastNum: + d.u.i = sprite->_castId; + break; + case kTheWidth: + d.u.i = sprite->_width; + break; + case kTheHeight: + d.u.i = sprite->_height; + break; + case kTheTrails: + d.u.i = sprite->_trails; + break; + case kTheInk: + d.u.i = sprite->_ink; + break; + case kTheLocH: + d.u.i = sprite->_startPoint.x; + break; + case kTheLocV: + d.u.i = sprite->_startPoint.y; + break; + case kTheConstraint: + d.u.i = sprite->_constraint; + break; + case kTheMoveable: + d.u.i = sprite->_moveable; + break; + case kTheBackColor: + d.u.i = sprite->_backColor; + break; + case kTheForeColor: + d.u.i = sprite->_foreColor; + break; + case kTheLeft: + d.u.i = sprite->_left; + break; + case kTheRight: + d.u.i = sprite->_right; + break; + case kTheBottom: + d.u.i = sprite->_bottom; + break; + case kTheTop: + d.u.i = sprite->_top; + break; + case kTheBlend: + d.u.i = sprite->_blend; + break; + case kTheVisible: + d.u.i = (sprite->_visible ? 1 : 0); + break; + case kTheType: + d.u.i = sprite->_type; + break; + case kTheMovieRate: + d.u.i = sprite->_movieRate; + break; + case kTheMovieTime: + d.u.i = sprite->_movieTime; + break; + case kTheStopTime: + d.u.i = sprite->_stopTime; + break; + case kTheStartTime: + d.u.i = sprite->_startTime; + break; + case kTheVolume: + d.u.i = sprite->_volume; + break; + case kTheStretch: + d.u.i = sprite->_stretch; + break; + case kTheLineSize: + d.u.i = sprite->_lineSize; + break; + case kTheEditableText: + d.toString(); + d.u.s = &sprite->_editableText; + break; + default: + warning("Unprocessed getting field %d of sprite", field); + d.type = VOID; + } + + return d; +} + +Datum Lingo::getTheCast(Datum &id1, int field) { + Datum d; + int id = 0; + + if (id1.type == INT) { + id = id1.u.i; + } else { + warning("Unknown the cast id type: %s", id1.type2str()); + return d; + } + + if (!_vm->_currentScore) { + warning("The cast %d field %d setting over non-active score", id, field); + return d; + } + + Cast *cast; + CastInfo *castInfo; + if (!_vm->_currentScore->_casts.contains(id)) { + if (field == kTheLoaded) { + d.type = INT; + d.u.i = 0; + } + + return d; + } else { + warning("The cast %d found", id); + return d; + } + cast = _vm->_currentScore->_casts[id]; + castInfo = _vm->_currentScore->_castsInfo[id]; + + d.type = INT; + + switch (field) { + case kTheCastType: + d.u.i = cast->type; + break; + case kTheFilename: + d.toString(); + d.u.s = &castInfo->fileName; + break; + case kTheName: + d.toString(); + d.u.s = &castInfo->name; + break; + case kTheScriptText: + d.toString(); + d.u.s = &castInfo->script; + break; + case kTheWidth: + d.u.i = cast->initialRect.width(); + break; + case kTheHeight: + d.u.i = cast->initialRect.height(); + break; + case kTheBackColor: + { + if (cast->type != kCastShape) { + warning("Field %d of cast %d not found", field, id); + d.type = VOID; + return d; + } + + ShapeCast *shape = static_cast<ShapeCast *>(_vm->_currentScore->_casts[id]); + d.u.i = shape->bgCol; + } + break; + case kTheForeColor: + { + if (cast->type != kCastShape) { + warning("Field %d of cast %d not found", field, id); + d.type = VOID; + return d; + } + + ShapeCast *shape = static_cast<ShapeCast *>(_vm->_currentScore->_casts[id]); + d.u.i = shape->fgCol; + } + break; + case kTheLoaded: + d.u.i = 1; //Not loaded handled above + break; + default: + warning("Unprocessed getting field %d of cast %d", field, id); + d.type = VOID; + //TODO find out about String fields + } + + return d; +} + +void Lingo::setTheCast(Datum &id1, int field, Datum &d) { + int id = 0; + + if (id1.type == INT) { + id = id1.u.i; + } else { + warning("Unknown the cast id type: %s", id1.type2str()); + return; + } + + if (!_vm->_currentScore) { + warning("The cast %d field %d setting over non-active score", id, field); + return; + } + + Cast *cast = _vm->_currentScore->_casts[id]; + CastInfo *castInfo = _vm->_currentScore->_castsInfo[id]; + + if (!cast) { + warning("The cast %d found", id); + return; + } + + switch (field) { + case kTheCastType: + cast->type = static_cast<CastType>(d.u.i); + cast->modified = 1; + break; + case kTheFilename: + castInfo->fileName = *d.u.s; + break; + case kTheName: + castInfo->name = *d.u.s; + break; + case kTheScriptText: + castInfo->script = *d.u.s; + break; + case kTheWidth: + cast->initialRect.setWidth(d.u.i); + cast->modified = 1; + break; + case kTheHeight: + cast->initialRect.setHeight(d.u.i); + cast->modified = 1; + break; + case kTheBackColor: + { + if (cast->type != kCastShape) { + warning("Field %d of cast %d not found", field, id); + } + ShapeCast *shape = static_cast<ShapeCast *>(_vm->_currentScore->_casts[id]); + shape->bgCol = d.u.i; + shape->modified = 1; + } + break; + case kTheForeColor: + { + if (cast->type != kCastShape) { + warning("Field %d of cast %d not found", field, id); + return; + } + ShapeCast *shape = static_cast<ShapeCast *>(_vm->_currentScore->_casts[id]); + shape->fgCol = d.u.i; + shape->modified = 1; + } + break; + default: + warning("Unprocessed getting field %d of cast %d", field, id); + } +} + +} // End of namespace Director diff --git a/engines/director/lingo/lingo-the.h b/engines/director/lingo/lingo-the.h new file mode 100644 index 0000000000..5fea4ba009 --- /dev/null +++ b/engines/director/lingo/lingo-the.h @@ -0,0 +1,153 @@ +/* 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 DIRECTOR_LINGO_LINGO_THE_H + #define DIRECTOR_LINGO_LINGO_THE_H + +namespace Director { + +enum TheEntityType { + kTheNOEntity = 0, + kTheFrame = 1, + kThePathName, + kTheMenu, + kTheMenuItem, + kTheMenuItems, + kTheMenus, + kTheMovie, + kTheMouseH, + kTheMouseV, + kTheMouseDownScript, + kTheMouseUpScript, + + kTheSprite, + kTheCast, + kThePerFrameHook, + kTheTicks, + kTheTimer, + kTheTimeoutLength, + kTheWindow, + + kTheClickOn, + kTheDoubleClick, + kTheLastClick, + kTheLastFrame, + kTheLastEvent, + kTheMouseDown, + kTheMouseUp, + kTheRightMouseUp, + kTheRightMouseDown, + kTheStillDown, + kTheKey, + kTheKeyCode, + kTheControlDown, + kTheCommandDown, + kTheShiftDown, + kTheOptionDown, + + kTheColorDepth, + kTheColorQD, + kTheExitLock, + kTheFloatPrecision, + kTheItemDelimiter, + kTheMultiSound, + kThePreloadEventAbort, + kTheRomanLingo, + kTheStage +}; + +enum TheFieldType { + kTheNOField = 0, + kTheCastNum = 1, + kTheCastType, + kTheCheckMark, + kTheController, + kTheCursor, + kTheDepth, + kTheDirectToStage, + kTheDrawRect, + kTheLocH, + kTheLocV, + kTheBackColor, + kTheBlend, + kTheBottom, + kTheConstraint, + kTheEditableText, + kTheEnabled, + kTheForeColor, + kTheFrameRate, + kTheFilename, + kTheHeight, + kTheHilite, + kTheInk, + kTheLeft, + kTheLineSize, + kTheLoop, + kTheLoaded, + kTheModified, + kTheMoveable, + kTheMovieRate, + kTheMovieTime, + kTheNumber, + kTheName, + kThePalette, + kThePausedAtStart, + kThePicture, + kThePreload, + kThePurgePriority, + kTheRect, + kTheRegPoint, + kTheRight, + kTheStopTime, + kTheStretch, + kTheStartTime, + kTheScript, + kTheScriptNum, + kTheScriptText, + kTheSize, + kTheStrech, + kTheSound, + kTheSourceRect, + kTheText, + kTheTop, + kTheTrails, + kTheType, + kTheVisible, + kTheVolume, + kTheWidth +}; + +struct TheEntity { + TheEntityType entity; + const char *name; + bool hasId; +}; + +struct TheEntityField { + TheEntityType entity; + const char *name; + TheFieldType field; +}; + +} // End of namespace Director + +#endif diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp new file mode 100644 index 0000000000..f3faf975fe --- /dev/null +++ b/engines/director/lingo/lingo.cpp @@ -0,0 +1,404 @@ +/* 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/str-array.h" + +#include "director/lingo/lingo.h" +#include "director/lingo/lingo-gr.h" + +namespace Director { + +Lingo *g_lingo; + +struct EventHandlerType { + LEvent handler; + const char *name; +} static const eventHanlerDescs[] = { + { kEventPrepareMovie, "prepareMovie" }, + { kEventStartMovie, "startMovie" }, + { kEventStopMovie, "stopMovie" }, + + { kEventNew, "newSprite" }, + { kEventBeginSprite, "beginSprite" }, + { kEventEndSprite, "endSprite" }, + + { kEventEnterFrame, "enterFrame" }, + { kEventPrepareFrame, "prepareFrame" }, + { kEventIdle, "idle" }, + { kEventStepFrame, "stepFrame"}, + { kEventExitFrame, "exitFrame" }, + + { kEventActivateWindow, "activateWindow" }, + { kEventDeactivateWindow, "deactivateWindow" }, + { kEventMoveWindow, "moveWindow" }, + { kEventResizeWindow, "resizeWindow" }, + { kEventOpenWindow, "openWindow" }, + { kEventCloseWindow, "closeWindow" }, + { kEventStart, "start" }, + + { kEventKeyUp, "keyUp" }, + { kEventKeyDown, "keyDown" }, + { kEventMouseUp, "mouseUp" }, + { kEventMouseDown, "mouseDown" }, + { kEventRightMouseDown, "rightMouseDown" }, + { kEventRightMouseUp, "rightMouseUp" }, + { kEventMouseEnter, "mouseEnter" }, + { kEventMouseLeave, "mouseLeave" }, + { kEventMouseUpOutSide, "mouseUpOutSide" }, + { kEventMouseWithin, "mouseWithin" }, + + { kEventNone, 0 }, +}; + +Symbol::Symbol() { + name = NULL; + type = VOID; + u.s = NULL; + nargs = 0; + maxArgs = 0; + parens = true; + global = false; +} + +Lingo::Lingo(DirectorEngine *vm) : _vm(vm) { + g_lingo = this; + + for (const EventHandlerType *t = &eventHanlerDescs[0]; t->handler != kEventNone; ++t) + _eventHandlerTypes[t->handler] = t->name; + + initBuiltIns(); + initTheEntities(); + + _currentScript = 0; + _currentScriptType = kMovieScript; + _pc = 0; + _returning = false; + _indef = false; + + _linenumber = _colnumber = 0; + + _hadError = false; + + _inFactory = false; + + _floatPrecision = 4; + _floatPrecisionFormat = "%.4f"; + + warning("Lingo Inited"); +} + +Lingo::~Lingo() { +} + +const char *Lingo::findNextDefinition(const char *s) { + const char *res = s; + + while (*res) { + while (*res && (*res == ' ' || *res == '\t' || *res == '\n')) + res++; + + if (!*res) + return NULL; + + if (!strncmp(res, "macro ", 6)) { + warning("See macro"); + return res; + } + + if (!strncmp(res, "factory ", 8)) { + warning("See factory"); + return res; + } + + if (!strncmp(res, "method ", 7)) { + warning("See method"); + return res; + } + + while (*res && *res != '\n') + res++; + } + + return NULL; +} + +void Lingo::addCode(const char *code, ScriptType type, uint16 id) { + debug(2, "Add code \"%s\" for type %d with id %d", code, type, id); + + if (_scripts[type].contains(id)) { + delete _scripts[type][id]; + } + + _currentScript = new ScriptData; + _currentScriptType = type; + _scripts[type][id] = _currentScript; + + _linenumber = _colnumber = 1; + _hadError = false; + + const char *begin, *end; + + // macros and factories have conflicting grammar. Thus we ease life for the parser. + if ((begin = findNextDefinition(code))) { + bool first = true; + + while ((end = findNextDefinition(begin + 1))) { + + if (first) { + begin = code; + first = false; + } + Common::String chunk(begin, end); + + if (chunk.hasPrefix("factory") || chunk.hasPrefix("method")) + _inFactory = true; + else if (chunk.hasPrefix("macro")) + _inFactory = false; + else + _inFactory = false; + + debug(2, "Code chunk:\n#####\n%s#####", chunk.c_str()); + + parse(chunk.c_str()); + + _currentScript->clear(); + + begin = end; + } + + _hadError = true; // HACK: This is for preventing test execution + + debug(2, "Code chunk:\n#####\n%s#####", begin); + parse(begin); + } else { + parse(code); + + code1(STOP); + } + + _inFactory = false; + + if (_currentScript->size() && !_hadError) + Common::hexdump((byte *)&_currentScript->front(), _currentScript->size() * sizeof(inst)); +} + +void Lingo::executeScript(ScriptType type, uint16 id) { + if (!_scripts[type].contains(id)) { + warning("Request to execute non-existant script type %d id %d", type, id); + return; + } + + debug(2, "Executing script type: %d, id: %d", type, id); + + _currentScript = _scripts[type][id]; + _pc = 0; + _returning = false; + + _localvars = new SymbolHash; + + execute(_pc); + + cleanLocalVars(); +} + +void Lingo::processEvent(LEvent event, int entityId) { + if (!_eventHandlerTypes.contains(event)) + error("processEvent: Unknown event %d for entity %d", event, entityId); + + debug(2, "processEvent(%s) for %d", _eventHandlerTypes[event], entityId); +} + +int Lingo::alignTypes(Datum &d1, Datum &d2) { + int opType = INT; + + if (d1.type == FLOAT || d2.type == FLOAT) { + opType = FLOAT; + d1.toFloat(); + d2.toFloat(); + } + + return opType; +} + +int Datum::toInt() { + switch (type) { + case INT: + // no-op + break; + case FLOAT: + u.i = (int)u.f; + type = INT; + break; + default: + warning("Incorrect operation toInt() for type: %s", type2str()); + } + + return u.i; +} + +double Datum::toFloat() { + switch (type) { + case INT: + u.f = (double)u.i; + type = FLOAT; + break; + case FLOAT: + // no-op + break; + default: + warning("Incorrect operation toFloat() for type: %s", type2str()); + } + + return u.f; +} + +Common::String *Datum::toString() { + Common::String *s = new Common::String; + switch (type) { + case INT: + *s = Common::String::format("%d", u.i); + break; + case FLOAT: + *s = Common::String::format(g_lingo->_floatPrecisionFormat.c_str(), u.f); + break; + case STRING: + delete s; + s = u.s; + break; + default: + warning("Incorrect operation toString() for type: %s", type2str()); + } + + u.s = s; + type = STRING; + + return u.s; +} + +const char *Datum::type2str(bool isk) { + static char res[20]; + + switch (isk ? u.i : type) { + case INT: + return isk ? "#integer" : "INT"; + case FLOAT: + return isk ? "#float" : "FLOAT"; + case STRING: + return isk ? "#string" : "STRING"; + case CASTREF: + return "CASTREF"; + case VOID: + return isk ? "#void" : "VOID"; + case POINT: + return isk ? "#point" : "POINT"; + case SYMBOL: + return isk ? "#symbol" : "SYMBOL"; + default: + snprintf(res, 20, "-- (%d) --", type); + return res; + } +} + +// This is table for built-in Macintosh font lowercasing. +// '.' means that the symbol should be not changed, rest +// of the symbols are stripping the diacritics +// The table starts from 0x80 +// +// TODO: Check it for correctness. +static char lowerCaseConvert[] = +"aacenoua" // 80 +"aaaaacee" // 88 +"eeiiiino" // 90 +"oooouuuu" // 98 +"........" // a0 +".......o" // a8 +"........" // b0 +".......o" // b8 +"........" // c0 +".. aao.." // c8 +"--.....y";// d0-d8 + +Common::String *Lingo::toLowercaseMac(Common::String *s) { + Common::String *res = new Common::String; + const unsigned char *p = (const unsigned char *)s->c_str(); + + while (*p) { + if (*p >= 0x80 && *p <= 0xd8) { + if (lowerCaseConvert[*p - 0x80] != '.') + *res += lowerCaseConvert[*p - 0x80]; + else + *res += *p; + } else if (*p < 0x80) { + *res += tolower(*p); + } else { + warning("Unacceptable symbol in toLowercaseMac: %c", *p); + + *res += *p; + } + p++; + } + + return res; +} + +void Lingo::runTests() { + Common::File inFile; + Common::ArchiveMemberList fsList; + SearchMan.listMatchingMembers(fsList, "*.lingo"); + Common::StringArray fileList; + + int counter = 1; + + for (Common::ArchiveMemberList::iterator it = fsList.begin(); it != fsList.end(); ++it) + fileList.push_back((*it)->getName()); + + Common::sort(fileList.begin(), fileList.end()); + + for (int i = 0; i < fileList.size(); i++) { + Common::SeekableReadStream *const stream = SearchMan.createReadStreamForMember(fileList[i]); + if (stream) { + uint size = stream->size(); + + char *script = (char *)calloc(size + 1, 1); + + stream->read(script, size); + + warning("Compiling file %s of size %d, id: %d", fileList[i].c_str(), size, counter); + + _hadError = false; + addCode(script, kMovieScript, counter); + + if (!_hadError) + executeScript(kMovieScript, counter); + else + warning("Skipping execution"); + + free(script); + + counter++; + } + + inFile.close(); + } +} + +} // End of namespace Director diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h new file mode 100644 index 0000000000..0d004a0045 --- /dev/null +++ b/engines/director/lingo/lingo.h @@ -0,0 +1,405 @@ +/* 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 DIRECTOR_LINGO_LINGO_H +#define DIRECTOR_LINGO_LINGO_H + +#include "common/debug.h" +#include "common/hashmap.h" +#include "common/hash-str.h" +#include "audio/audiostream.h" +#include "common/str.h" +#include "engines/director/director.h" +#include "engines/director/score.h" +#include "director/lingo/lingo-gr.h" +#include "director/lingo/lingo-the.h" + +namespace Director { + +enum LEvent { + kEventPrepareMovie, + kEventStartMovie, + kEventStopMovie, + + kEventNew, + kEventBeginSprite, + kEventEndSprite, + + kEventNone, + kEventEnterFrame, + kEventPrepareFrame, + kEventIdle, + kEventStepFrame, + kEventExitFrame, + + kEventActivateWindow, + kEventDeactivateWindow, + kEventMoveWindow, + kEventResizeWindow, + kEventOpenWindow, + kEventCloseWindow, + + kEventKeyUp, + kEventKeyDown, + kEventMouseUp, + kEventMouseDown, + kEventRightMouseUp, + kEventRightMouseDown, + kEventMouseEnter, + kEventMouseLeave, + kEventMouseUpOutSide, + kEventMouseWithin, + + kEventStart +}; + +typedef void (*inst)(void); +#define STOP (inst)0 + +typedef Common::Array<inst> ScriptData; +typedef Common::Array<double> FloatArray; + +struct Symbol { /* symbol table entry */ + char *name; + int type; + union { + int i; /* VAR */ + double f; /* FLOAT */ + ScriptData *defn; /* FUNCTION, PROCEDURE */ + void (*func)(); /* OPCODE */ + void (*bltin)(int); /* BUILTIN */ + Common::String *s; /* STRING */ + FloatArray *arr; /* ARRAY, POINT, RECT */ + } u; + int nargs; /* number of arguments */ + int maxArgs; /* maximal number of arguments, for builtins */ + bool parens; /* whether parens required or not, for builitins */ + + bool global; + + Symbol(); +}; + +struct Datum { /* interpreter stack type */ + int type; + + union { + int i; + double f; + Common::String *s; + Symbol *sym; + FloatArray *arr; /* ARRAY, POINT, RECT */ + } u; + + Datum() { u.sym = NULL; type = VOID; } + + double toFloat(); + int toInt(); + Common::String *toString(); + + const char *type2str(bool isk = false); +}; + +struct Builtin { + void (*func)(void); + int nargs; + + Builtin(void (*func1)(void), int nargs1) : func(func1), nargs(nargs1) {} +}; + +typedef Common::HashMap<int32, ScriptData *> ScriptHash; +typedef Common::Array<Datum> StackData; +typedef Common::HashMap<Common::String, Symbol *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SymbolHash; +typedef Common::HashMap<Common::String, Builtin *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> BuiltinHash; + +typedef Common::HashMap<Common::String, TheEntity *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> TheEntityHash; +typedef Common::HashMap<Common::String, TheEntityField *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> TheEntityFieldHash; + +struct CFrame { /* proc/func call stack frame */ + Symbol *sp; /* symbol table entry */ + int retpc; /* where to resume after return */ + ScriptData *retscript; /* which script to resume after return */ + SymbolHash *localvars; +}; + +class Lingo { +public: + Lingo(DirectorEngine *vm); + ~Lingo(); + + void addCode(const char *code, ScriptType type, uint16 id); + void executeScript(ScriptType type, uint16 id); + + void processEvent(LEvent event, int entityId); + + void initBuiltIns(); + void initTheEntities(); + + Common::String *toLowercaseMac(Common::String *s); + + void runTests(); + +private: + const char *findNextDefinition(const char *s); + +public: + void execute(int pc); + void pushContext(); + void popContext(); + Symbol *lookupVar(const char *name, bool create = true, bool putInGlobalList = false); + void cleanLocalVars(); + void define(Common::String &s, int start, int nargs, Common::String *prefix = NULL); + void processIf(int elselabel, int endlabel); + + int alignTypes(Datum &d1, Datum &d2); + + int code1(inst code) { _currentScript->push_back(code); return _currentScript->size() - 1; } + int code2(inst code_1, inst code_2) { int o = code1(code_1); code1(code_2); return o; } + int code3(inst code_1, inst code_2, inst code_3) { int o = code1(code_1); code1(code_2); code1(code_3); return o; } + int codeString(const char *s); + void codeLabel(int label); + int codeConst(int val); + + int calcStringAlignment(const char *s) { + return calcCodeAlignment(strlen(s) + 1); + } + int calcCodeAlignment(int l) { + int instLen = sizeof(inst); + return (l + instLen - 1) / instLen; + } + + void codeArg(Common::String *s); + void codeArgStore(); + int codeFunc(Common::String *s, int numpar); + int codeFloat(double f); + void codeFactory(Common::String &s); + + void pushVoid(); + + static void c_xpop(); + static void c_printtop(); + + static void c_add(); + static void c_sub(); + static void c_mul(); + static void c_div(); + static void c_negate(); + + static void c_and(); + static void c_or(); + static void c_not(); + + static void c_ampersand(); + static void c_concat(); + static void c_contains(); + static void c_starts(); + + static void c_intersects(); + static void c_within(); + + static void c_constpush(); + static void c_voidpush(); + static void c_fconstpush(); + static void c_stringpush(); + static void c_varpush(); + static void c_assign(); + bool verify(Symbol *s); + static void c_eval(); + + static void c_swap(); + + static void c_theentitypush(); + static void c_theentityassign(); + + static void c_repeatwhilecode(); + static void c_repeatwithcode(); + static void c_ifcode(); + static void c_eq(); + static void c_neq(); + static void c_gt(); + static void c_lt(); + static void c_ge(); + static void c_le(); + static void c_call(); + + void call(Common::String &name, int nargs); + + static void c_procret(); + + static void c_mci(); + static void c_mciwait(); + static void c_goto(); + static void c_gotoloop(); + static void c_gotonext(); + static void c_gotoprevious(); + static void c_global(); + + static void c_play(); + static void c_playdone(); + + static void c_open(); + + void printStubWithArglist(const char *funcname, int nargs); + void convertVOIDtoString(int arg, int nargs); + void dropStack(int nargs); + + static void b_abs(int nargs); + static void b_atan(int nargs); + static void b_chars(int nargs); + static void b_cos(int nargs); + static void b_exp(int nargs); + static void b_float(int nargs); + static void b_integer(int nargs); + static void b_length(int nargs); + static void b_log(int nargs); + static void b_pi(int nargs); + static void b_power(int nargs); + static void b_random(int nargs); + static void b_sin(int nargs); + static void b_sqrt(int nargs); + static void b_string(int nargs); + static void b_tan(int nargs); + + static void b_ilk(int nargs); + static void b_alert(int nargs); + static void b_cursor(int nargs); + static void b_printFrom(int nargs); + static void b_showGlobals(int nargs); + static void b_showLocals(int nargs); + + static void b_editableText(int nargs); + static void b_installMenu(int nargs); + static void b_updateStage(int nargs); + static void b_moveableSprite(int nargs); + static void b_puppetPalette(int nargs); + static void b_puppetSound(int nargs); + static void b_puppetSprite(int nargs); + static void b_puppetTempo(int nargs); + static void b_puppetTransition(int nargs); + static void b_spriteBox(int nargs); + static void b_zoomBox(int nargs); + + static void b_continue(int nargs); + static void b_dontPassEvent(int nargs); + static void b_delay(int nargs); + static void b_do(int nargs); + static void b_nothing(int nargs); + static void b_pause(int nargs); + static void b_playAccel(int nargs); + static void b_quit(int nargs); + static void b_restart(int nargs); + static void b_shutDown(int nargs); + static void b_startTimer(int nargs); + + static void b_closeDA(int nargs); + static void b_closeResFile(int nargs); + static void b_closeXlib(int nargs); + static void b_openDA(int nargs); + static void b_openResFile(int nargs); + static void b_openXlib(int nargs); + static void b_showResFile(int nargs); + static void b_showXlib(int nargs); + + static void b_point(int nargs); + + static void b_beep(int nargs); + static void b_mci(int nargs); + static void b_mciwait(int nargs); + + static void b_backspace(int nargs); + static void b_empty(int nargs); + static void b_enter(int nargs); + static void b_false(int nargs); + static void b_quote(int nargs); + static void b_return(int nargs); + static void b_tab(int nargs); + static void b_true(int nargs); + + static void b_factory(int nargs); + void factoryCall(Common::String &name, int nargs); + + void func_mci(Common::String &s); + void func_mciwait(Common::String &s); + void func_goto(Datum &frame, Datum &movie); + void func_gotoloop(); + void func_gotonext(); + void func_gotoprevious(); + +public: + void setTheEntity(int entity, Datum &id, int field, Datum &d); + void setTheSprite(Datum &id, int field, Datum &d); + void setTheCast(Datum &id, int field, Datum &d); + Datum getTheEntity(int entity, Datum &id, int field); + Datum getTheSprite(Datum &id, int field); + Datum getTheCast(Datum &id, int field); + +public: + ScriptData *_currentScript; + ScriptType _currentScriptType; + bool _returning; + bool _indef; + + Common::Array<CFrame *> _callstack; + Common::Array<Common::String *> _argstack; + TheEntityHash _theEntities; + TheEntityFieldHash _theEntityFields; + Common::Array<int> _labelstack; + + SymbolHash _handlers; + + int _linenumber; + int _colnumber; + + Common::String _floatPrecisionFormat; + + bool _hadError; + + bool _inFactory; + Common::String _currentFactory; + +private: + int parse(const char *code); + void push(Datum d); + Datum pop(void); + + Common::HashMap<uint32, const char *> _eventHandlerTypes; + Common::HashMap<Common::String, Audio::AudioStream *> _audioAliases; + + ScriptHash _scripts[kMaxScriptType + 1]; + + SymbolHash _globalvars; + SymbolHash *_localvars; + + int _pc; + + StackData _stack; + + DirectorEngine *_vm; + + int _floatPrecision; +}; + +extern Lingo *g_lingo; + +} // End of namespace Director + +#endif diff --git a/engines/director/lingo/tests/Lingo bytecode.html b/engines/director/lingo/tests/Lingo bytecode.html new file mode 100644 index 0000000000..1fcb4a31fc --- /dev/null +++ b/engines/director/lingo/tests/Lingo bytecode.html @@ -0,0 +1,2360 @@ +<!DOCTYPE html> +<!-- saved from url=(0054)http://fileformats.archiveteam.org/wiki/Lingo_bytecode --> +<html lang="en" dir="ltr" class="client-js gr__fileformats_archiveteam_org"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<title>Lingo bytecode - Just Solve the File Format Problem</title> + +<meta name="generator" content="MediaWiki 1.19.2"> +<link rel="shortcut icon" href="http://fileformats.archiveteam.org/favicon.ico"> +<link rel="search" type="application/opensearchdescription+xml" href="http://fileformats.archiveteam.org/opensearch_desc.php" title="Just Solve the File Format Problem (en)"> +<link rel="EditURI" type="application/rsd+xml" href="http://fileformats.archiveteam.org/api.php?action=rsd"> +<link rel="copyright" href="http://creativecommons.org/publicdomain/zero/1.0/"> +<link rel="alternate" type="application/atom+xml" title="Just Solve the File Format Problem Atom feed" href="http://fileformats.archiveteam.org/index.php?title=Special:RecentChanges&feed=atom"> +<link rel="stylesheet" href="./Lingo bytecode - Just Solve the File Format Problem_files/load.php"> +<style type="text/css" media="all">.js-messagebox{margin:1em 5%;padding:0.5em 2.5%;border:1px solid #ccc;background-color:#fcfcfc;font-size:0.8em}.js-messagebox .js-messagebox-group{margin:1px;padding:0.5em 2.5%;border-bottom:1px solid #ddd}.js-messagebox .js-messagebox-group:last-child{border-bottom:thin none transparent} + +/* cache key: justsolve:resourceloader:filter:minify-css:7:8b08bdc91c52a9ffba396dccfb5b473c */ + + +.mw-collapsible-toggle{float:right} li .mw-collapsible-toggle{float:none} .mw-collapsible-toggle-li{list-style:none} + +/* cache key: justsolve:resourceloader:filter:minify-css:7:4250852ed2349a0d4d0fc6509a3e7d4c */ +</style><meta name="ResourceLoaderDynamicStyles" content=""> +<style>a:lang(ar),a:lang(ckb),a:lang(fa),a:lang(kk-arab),a:lang(mzn),a:lang(ps),a:lang(ur){text-decoration:none}a.new,#quickbar a.new{color:#ba0000} + +/* cache key: justsolve:resourceloader:filter:minify-css:7:c88e2bcd56513749bec09a7e29cb3ffa */ +</style> + +<script src="./Lingo bytecode - Just Solve the File Format Problem_files/load(1).php"></script><script src="./Lingo bytecode - Just Solve the File Format Problem_files/load(2).php"></script> +<script>if(window.mw){ +mw.config.set({"wgCanonicalNamespace":"","wgCanonicalSpecialPageName":false,"wgNamespaceNumber":0,"wgPageName":"Lingo_bytecode","wgTitle":"Lingo bytecode","wgCurRevisionId":25053,"wgArticleId":6263,"wgIsArticle":true,"wgAction":"view","wgUserName":null,"wgUserGroups":["*"],"wgCategories":["File Formats","Electronic File Formats","Development","FormatInfo without extensions","FormatInfo without mimetypes"],"wgBreakFrames":false,"wgPageContentLanguage":"en","wgSeparatorTransformTable":["",""],"wgDigitTransformTable":["",""],"wgRelevantPageName":"Lingo_bytecode","wgRestrictionEdit":[],"wgRestrictionMove":[]}); +}</script><script>if(window.mw){ +mw.loader.implement("user.options",function($){mw.user.options.set({"ccmeonemails":0,"cols":80,"date":"default","diffonly":0,"disablemail":0,"disablesuggest":0,"editfont":"default","editondblclick":0,"editsection":1,"editsectiononrightclick":0,"enotifminoredits":0,"enotifrevealaddr":0,"enotifusertalkpages":1,"enotifwatchlistpages":0,"extendwatchlist":0,"externaldiff":0,"externaleditor":0,"fancysig":0,"forceeditsummary":0,"gender":"unknown","hideminor":0,"hidepatrolled":0,"highlightbroken":1,"imagesize":2,"justify":0,"math":1,"minordefault":0,"newpageshidepatrolled":0,"nocache":0,"noconvertlink":0,"norollbackdiff":0,"numberheadings":0,"previewonfirst":0,"previewontop":1,"quickbar":5,"rcdays":7,"rclimit":50,"rememberpassword":0,"rows":25,"searchlimit":20,"showhiddencats":0,"showjumplinks":1,"shownumberswatching":1,"showtoc":1,"showtoolbar":1,"skin":"vector","stubthreshold":0,"thumbsize":2,"underline":2,"uselivepreview":0,"usenewrc":0,"watchcreations":0,"watchdefault":0,"watchdeletion":0, +"watchlistdays":3,"watchlisthideanons":0,"watchlisthidebots":0,"watchlisthideliu":0,"watchlisthideminor":0,"watchlisthideown":0,"watchlisthidepatrolled":0,"watchmoves":0,"wllimit":250,"variant":"en","language":"en","searchNs0":true,"searchNs1":false,"searchNs2":false,"searchNs3":false,"searchNs4":false,"searchNs5":false,"searchNs6":false,"searchNs7":false,"searchNs8":false,"searchNs9":false,"searchNs10":false,"searchNs11":false,"searchNs12":false,"searchNs13":false,"searchNs14":false,"searchNs15":false});;},{},{});mw.loader.implement("user.tokens",function($){mw.user.tokens.set({"editToken":"+\\","watchToken":false});;},{},{}); + +/* cache key: justsolve:resourceloader:filter:minify-js:7:9983699ab6150ffa89a90653b2338ac8 */ +}</script> +<script>if(window.mw){ +mw.loader.load(["mediawiki.page.startup","mediawiki.legacy.wikibits","mediawiki.legacy.ajax"]); +}</script><script type="text/javascript" src="./Lingo bytecode - Just Solve the File Format Problem_files/load(3).php"></script> +<!--[if lt IE 7]><style type="text/css">body{behavior:url("/skins/vector/csshover.min.htc")}</style><![endif]--><meta name="chromesniffer" id="chromesniffer_meta" content="{"MediaWiki":-1,"jQuery":"1.7.1"}"><script type="text/javascript" src="chrome-extension://homgcnaoacgigpkkljjjekpignblkeae/detector.js"></script></head> +<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-Lingo_bytecode skin-vector action-view" data-gr-c-s-loaded="true"> + <div id="mw-page-base" class="noprint"></div> + <div id="mw-head-base" class="noprint"></div> + <!-- content --> + <div id="content" class="mw-body"> + <a id="top"></a> + <div id="mw-js-message" style="display:none;" class="js-messagebox"></div> + <!-- firstHeading --> + <h1 id="firstHeading" class="firstHeading"> + <span dir="auto">Lingo bytecode</span> + </h1> + <!-- /firstHeading --> + <!-- bodyContent --> + <div id="bodyContent"> + <!-- tagline --> + <div id="siteSub">From Just Solve the File Format Problem</div> + <!-- /tagline --> + <!-- subtitle --> + <div id="contentSub"></div> + <!-- /subtitle --> + <!-- jumpto --> + <div id="jump-to-nav" class="mw-jump"> + Jump to: <a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#mw-head">navigation</a>, + <a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#p-search">search</a> + </div> + <!-- /jumpto --> + <!-- bodycontent --> + <div id="mw-content-text" lang="en" dir="ltr" class="mw-content-ltr"><table class="infobox formatinfo" border="0" style="float: right; border: 1px solid #666666; max-width: 25%; overflow: hidden; background-color: #F8E0F7; padding: 0.25em; margin: 0.25em 1em;"> +<tbody><tr> +<th colspan="2"><a href="http://fileformats.archiveteam.org/wiki/File_Formats" title="File Formats">File Format</a></th> +</tr> + +<tr> +<th>Name</th> +<td>Lingo bytecode</td> +</tr> + + +<tr> +<th> Ontology +</th> +<td> +<ul><li> +<a href="http://fileformats.archiveteam.org/wiki/Electronic_File_Formats" title="Electronic File Formats">Electronic File Formats</a> +<ul><li> +<a href="http://fileformats.archiveteam.org/wiki/Development" title="Development">Development</a> +<ul><li> +<strong class="selflink">Lingo bytecode</strong> +</li></ul> +</li></ul> +</li></ul> +</td> +</tr> + + + +</tbody></table> +<p>This is a partial, work-in-progress examination of the bytecode created when Lingo code is compiled in Macromedia Director 4.0. It describes instructions for a stack-based virtual machine. This virtual machine is sometimes known as the IML, or Idealized Machine Layer. +</p><p>Each instruction is one, two or three bytes. +</p> +<ul><li> If the first byte is in the range 0x00-0x3F, then the full instruction is one byte. +</li><li> If the first byte is in the range 0x40-0x7F, then the full instruction is two bytes. +</li><li> If the first byte is in the range 0x80-0xFF, then the full instruction is three bytes. +</li></ul> +<p>Constant blobs like string literals are stored after the bytecode, and referred to by records that are six bytes long regardless of the actual length of the data. This means the first constant will be referred to as 0x00, the second constant as 0x06, the third as 0x0C, and so on. Integer literals over 32767 and floating-point number literals are also stored as constants. +</p><p>There is also a namelist for referring to external identifiers, stored separately from the bytecode. This is a simple array of strings. +</p> +<table id="toc" class="toc"><tbody><tr><td><div id="toctitle"><h2>Contents</h2><span class="toctoggle"> [<a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#" class="internal" id="togglelink">hide</a>] </span></div> +<ul> +<li class="toclevel-1 tocsection-1"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#One-Byte_Instructions"><span class="tocnumber">1</span> <span class="toctext">One-Byte Instructions</span></a></li> +<li class="toclevel-1 tocsection-2"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#Two-Byte_Instructions"><span class="tocnumber">2</span> <span class="toctext">Two-Byte Instructions</span></a></li> +<li class="toclevel-1 tocsection-3"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#Three_Byte_Instructions"><span class="tocnumber">3</span> <span class="toctext">Three Byte Instructions</span></a></li> +<li class="toclevel-1 tocsection-4"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#Syntactic_Sugar"><span class="tocnumber">4</span> <span class="toctext">Syntactic Sugar</span></a></li> +<li class="toclevel-1 tocsection-5"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#Lscr_bytecode-container_chunk_layout"><span class="tocnumber">5</span> <span class="toctext">Lscr bytecode-container chunk layout</span></a> +<ul> +<li class="toclevel-2 tocsection-6"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#Header"><span class="tocnumber">5.1</span> <span class="toctext">Header</span></a></li> +<li class="toclevel-2 tocsection-7"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#Function_Record"><span class="tocnumber">5.2</span> <span class="toctext">Function Record</span></a></li> +<li class="toclevel-2 tocsection-8"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#Bytecode_Trailer"><span class="tocnumber">5.3</span> <span class="toctext">Bytecode Trailer</span></a></li> +<li class="toclevel-2 tocsection-9"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#Constants"><span class="tocnumber">5.4</span> <span class="toctext">Constants</span></a></li> +</ul> +</li> +<li class="toclevel-1 tocsection-10"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#Projector_File_.28Windows.29"><span class="tocnumber">6</span> <span class="toctext">Projector File (Windows)</span></a> +<ul> +<li class="toclevel-2 tocsection-11"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#Director_3.0"><span class="tocnumber">6.1</span> <span class="toctext">Director 3.0</span></a></li> +<li class="toclevel-2 tocsection-12"><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#Director_4.0"><span class="tocnumber">6.2</span> <span class="toctext">Director 4.0</span></a></li> +</ul> +</li> +</ul> +</td></tr></tbody></table> +<h1> <span class="mw-headline" id="One-Byte_Instructions"> One-Byte Instructions </span></h1> +<table class="wikitable"> + +<tbody><tr> +<th> 01 +</th> +<td> <code>exit</code> +</td> +<td> +</td> +<td> +</td> +<td> Leave the current function immediately and return to its caller. Automatically added as the final step of a function. +</td></tr> +<tr> +<th> 02 +</th></tr> +<tr> +<th> 03 +</th> +<td> +<p><code>0</code> +</p><p><code>FALSE</code> +</p> +</td> +<td> +</td> +<td> +1 +</td> +<td> +<p>Push zero onto the stack. +</p> +</td></tr> +<tr> +<th> 04 +</th> +<td> <code>(a * b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, multiply them together and push the result. +</td></tr> +<tr> +<th> 05 +</th> +<td> <code>(a + b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, add them together and push the result. +</td></tr> +<tr> +<th> 06 +</th> +<td> <code>(a - b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, subtract the second from the first and push the result. +</td></tr> +<tr> +<th> 07 +</th> +<td> <code>(a / b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, divide the first by the second and push the result. +</td></tr> +<tr> +<th> 08 +</th> +<td> <code>(a mod b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, perform a modulo operation and push the result. +</td></tr> +<tr> +<th> 09 +</th> +<td> <code>(-a)</code> +</td> +<td> -1 +</td> +<td> +1 +</td> +<td> Pop one value from the stack, negate it and push the result. +</td></tr> +<tr> +<th> 0A +</th> +<td> <code>(a & b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, concatenate them and push the resulting string. +</td></tr> +<tr> +<th> 0B +</th> +<td> <code>(a && b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, concatenate them with one space character added in between, and push the resulting string. +</td></tr> +<tr> +<th> 0C +</th> +<td> <code>(a < b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, push 1 if the first is less than the second and 0 if not. +</td></tr> +<tr> +<th> 0D +</th> +<td> <code>(a <= b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, push 1 if the first is less than or equal to the second and 0 if not. +</td></tr> +<tr> +<th> 0E +</th> +<td> <code>(a <> b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, push 0 if the two values are the same and 1 if they are not. +</td></tr> +<tr> +<th> 0F +</th> +<td> <code>(a = b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, push 1 if the two values are the same and 0 if they are not. +</td></tr> +<tr> +<th> 10 +</th> +<td> <code>(a > b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, push 1 if the first is greater than the second and 0 if not. +</td></tr> +<tr> +<th> 11 +</th> +<td> <code>(a >= b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, push 1 if the first is greater than or equal to the sceond and 0 if not. +</td></tr> +<tr> +<th> 12 +</th> +<td> <code>(a and b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, push 1 if both are logically true and 0 if not. +</td></tr> +<tr> +<th> 13 +</th> +<td> <code>(a or b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two values from the stack, push 1 if either are logically true and 0 if not. +</td></tr> +<tr> +<th> 14 +</th> +<td> <code>(not a)</code> +</td> +<td> -1 +</td> +<td> +1 +</td> +<td> Pop one value from the stack, push 0 if it is logically true and 1 if not. +</td></tr> +<tr> +<th> 15 +</th> +<td> <code>(a contains b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> +<p>Pop two values from the stack, push 1 if the first is a string that contains the second and 0 if not. +</p><p>The text comparison is case-insensitive and ignores diacritic marks, e.g. "a" and "Ă
" are treated the same. +</p> +</td></tr> +<tr> +<th> 16 +</th> +<td> <code>(a starts b)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> +<p>Pop two values from the stack, push 1 if the first is a string that begins with second string and 0 if not. +</p><p>The text comparison is case-insensitive and ignores diacritic marks, e.g. "a" and "Ă
" are treated the same. +</p> +</td></tr> +<tr> +<th> 17 +</th> +<td> <code>(char a of c)</code> +<p><code>(char a to b of c)</code> +</p><p><code>(item 1 to 3 of someItems)</code> +</p> +</td> +<td> -9 +</td> +<td> +1 +</td> +<td> String slice/split operation. It takes nine arguments from the stack: +<table class="wikitable"> + +<tbody><tr> +<th> -9 +</th> +<td> First char position +</td></tr> +<tr> +<th> -8 +</th> +<td> Last char position +</td></tr> +<tr> +<th> -7 +</th> +<td> First word position +</td></tr> +<tr> +<th> -6 +</th> +<td> Last word position +</td></tr> +<tr> +<th> -5 +</th> +<td> First item position <i>(items separated by</i> <code>the itemDelimiter</code><i>, which is a comma by default)</i> +</td></tr> +<tr> +<th> -4 +</th> +<td> Last item position +</td></tr> +<tr> +<th> -3 +</th> +<td> First line position +</td></tr> +<tr> +<th> -2 +</th> +<td> Last line position +</td></tr> +<tr> +<th> -1 +</th> +<td> The string to slice +</td></tr></tbody></table> +<p>The positions used here are one-based, so zero is invalid as a position and is instead used to indicate unused parameters. Only one "first X position" can be set, the rest must be zero. The corresponding "last X position" may either be set too, or it can be zero, in which case the first position will also be used as the last. +</p> +</td></tr> +<tr> +<th> 18 +</th> +<td> <code>hilite word 1 of field 10</code> +</td> +<td> -9 +</td> +<td> +</td> +<td> Highlight (select) some text. The nine arguments taken from the stack are: +<table class="wikitable"> + +<tbody><tr> +<th> -9 +</th> +<td> First char position +</td></tr> +<tr> +<th> -8 +</th> +<td> Last char position +</td></tr> +<tr> +<th> -7 +</th> +<td> First word position +</td></tr> +<tr> +<th> -6 +</th> +<td> Last word position +</td></tr> +<tr> +<th> -5 +</th> +<td> First item position +</td></tr> +<tr> +<th> -4 +</th> +<td> Last item position +</td></tr> +<tr> +<th> -3 +</th> +<td> First line position +</td></tr> +<tr> +<th> -2 +</th> +<td> Last line position +</td></tr> +<tr> +<th> -1 +</th> +<td> Field number (cast ID) +</td></tr></tbody></table> +<p>The positions used here are one-based, so zero is invalid as a position and is instead used to indicate unused parameters. Only one "first X position" can be set, the rest must be zero. The corresponding "last X position" may either be set too, or it can be zero, in which case the first position will also be used as the last. +</p> +</td></tr> +<tr> +<th> 19 +</th> +<td> <code>(sprite 1 intersects 2)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two sprite IDs and push 1 if the bounding rectangles of the two sprites touch at all, or 0 if they do not. +</td></tr> +<tr> +<th> 1A +</th> +<td> <code>(sprite 1 within 2)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> Pop two sprite IDs and push 1 if the bounding rectangle of the first is entirely inside the bounding rectangle of the second, or 0 if not. +</td></tr> +<tr> +<th> 1B +</th> +<td> <code>(field 1)</code> +</td> +<td> -1 +</td> +<td> +1 +</td> +<td> Pop a cast ID (name or number), push the value of that cast member's <code>text</code> property. +</td></tr> +<tr> +<th> 1C +</th> +<td> <code>tell someObject to go to frame 1</code> +</td> +<td> -1 +</td> +<td> +</td> +<td> Pop an object from the stack and begin running subsequent bytecodes in the context of that object, until code 1D is encountered. +</td></tr> +<tr> +<th> 1D +</th> +<td> <code>tell someObject to go to frame 1</code> +</td> +<td> +</td> +<td> +</td> +<td> Marker for the end of a sequence of bytecodes started by 1C. Similar to 01 except for nested bytecode chunks instead of the main one. +</td></tr> +<tr> +<th> 1E +</th> +<td> +</td> +<td> -1 +</td> +<td> +1 +</td> +<td> Some kind of list transformation or check, seen used just before setting the actorList to []. More research is needed to know exactly what is happening there. +</td></tr> +<tr> +<th> 1F +</th> +<td> <code>[#key: value]</code> +</td> +<td> -1 +</td> +<td> +1 +</td> +<td> Pops a list that must be in the form [#symbol1, val1, #symbol2, val2 ...] to transform into [#symbol1: val1, #symbol2: val2 ...] +</td></tr></tbody></table> +<h1> <span class="mw-headline" id="Two-Byte_Instructions"> Two-Byte Instructions </span></h1> +<table class="wikitable"> + +<tbody><tr> +<th> 41 XX +</th> +<td> <code>1</code> .. <code>127</code> +</td> +<td> +</td> +<td> +1 +</td> +<td> Push integer of value XX, which must be between 1 and 127, inclusive. To push zero, use 03. To push larger integers, use 81 XX YY. +</td></tr> +<tr> +<th> 42 XX +</th> +<td> <code>a, b, c</code> +</td> +<td> -ďťżXX +</td> +<td> +1 +</td> +<td> Pop the specified number of values off the top of the stack, create an unparenthesized argument list containing them (i.e. for a call statement like <code>myFunction 1, 2, 3</code>), and push that to the stack. +</td></tr> +<tr> +<th> 43 XX +</th> +<td> <code>[a, b, c]</code> +</td> +<td> -ďťżXX +</td> +<td> +1 +</td> +<td> Pop the specified number of values off the top of the stack, create a list for them (which can also be used for a parenthesized call expression like <code>set result = myFunction(1, 2, 3)</code>), and push that to the stack. +</td></tr> +<tr> +<th> 44 XX +</th> +<td> +<p><code>"literal"</code> +</p><p><code>0.5</code> +</p><p><code>32768</code> +</p> +</td> +<td> +</td> +<td> +1 +</td> +<td> Push a constant from local constant records onto the stack. These records seem to be six bytes long (regardless of the actual size of the constant value), so pushing the first one is <code>44 00</code>, the second is <code>44 06</code>, the third is <code>44 0C</code>, etc. +</td></tr> +<tr> +<th> 45 XX +</th> +<td> <code>#symbol</code> +</td> +<td> +</td> +<td> +1 +</td> +<td> Push a symbol with a name from namelist[XX]. Note that the name will be stored as "name", not "#name". +</td></tr> +<tr> +<th> 46 XX +</th></tr> +<tr> +<th> 47 XX +</th></tr> +<tr> +<th> 48 XX +</th></tr> +<tr> +<th> 49 XX +</th> +<td> +<p><code>(someGlobal)</code> +</p><p><i>where previously declared:</i> +</p><p><code>global someGlobal</code> +</p> +</td> +<td> +</td> +<td> +1 +</td> +<td> Push the value of a global variable with a name from namelist[XX]. +</td></tr> +<tr> +<th> 4A XX +</th></tr> +<tr> +<th> 4B XX +</th> +<td> <code>(someParam)</code> +</td> +<td> +</td> +<td> +1 +</td> +<td> Push the value of a function call parameter. The parameter records seem to be 6 bytes long, so the first is pushed with 4B 00, the second with 4B 06, etc. +</td></tr> +<tr> +<th> 4C XX +</th> +<td> <code>(someLocal)</code> +</td> +<td> +</td> +<td> +1 +</td> +<td> Push the value of a local variable. The local variable records seem to be 6 bytes long, so the first is pushed with <code>4C 00</code>, the second with <code>4C 06</code>, etc. +</td></tr> +<tr> +<th> 4D XX +</th></tr> +<tr> +<th> 4E XX +</th></tr> + +<tr> +<th> 4F XX +</th> +<td> <code>set someGlobal = 0</code> +</td> +<td> -1 +</td> +<td> +</td> +<td> Pop one value and use it to set the global variable with name from namelist[XX]. +</td></tr> +<tr> +<th> 50 XX +</th></tr> +<tr> +<th> 51 XX +</th></tr> +<tr> +<th> 52 XX +</th> +<td> <code>set someLocal = 0</code> +</td> +<td> -1 +</td> +<td> +</td> +<td> Pop one value and use it to set a local variable. See code 4C 00 for a note about local variable records. +</td></tr> +<tr> +<th> 53 XX +</th></tr> +<tr> +<th> 54 XX +</th> +<td> <code>end repeat</code> +</td> +<td> +</td> +<td> +</td> +<td> Unconditional backwards jump by XX bytes, relative to the first byte of this instruction. +</td></tr> +<tr> +<th> 55 XX +</th></tr> +<tr> +<th> 56 XX +</th> +<td> <code>localFunction(1,2,3)</code> +</td> +<td> -1 +</td> +<td> +1 or +0 +</td> +<td> Call a function defined in this script with the name at namelist[XX]. The top value on the stack must be an argument list. If the argument list was created with code 43 XX, one return value will be pushed to the stack. If the argument list was created with code 42 XX, no return value will be pushed. +</td></tr> +<tr> +<th> 57 XX +</th> +<td> <code>someFunction 1,2,3</code> +<p><code>(someFunction(1,2,3))</code> +</p> +</td> +<td> -1 +</td> +<td> +1 OR +0 +</td> +<td> Call the external function with name from namelist[XX]. The top value on the stack must be an argument list. If the argument list was created with code 43 XX, one return value will be pushed to the stack. If the argument list was created with code 42 XX, no return value will be pushed. +</td></tr> +<tr> +<th> 58 XX +</th> +<td> <code>someObject(mSomeMethod, 1,2,3)</code> +</td> +<td> -2 +</td> +<td> +1 OR +0 +</td> +<td> Pop [argument list, call target] to make a method call. If the call target is a literal number, this indicates a local variable is the target. It must be divided by six to get the actual local variable number. The first argument of the argument list will be a symbol with the name of the method. Note: It is still unclear what difference the value of XX makes. It has been seen as 0x01 and 0x05. More research is needed to know more. (Possibly local variables vs. call parameters?) +</td></tr> +<tr> +<th> 59 16 +</th> +<td> <code>put "extra" into textVar</code> +</td> +<td> -1 +</td> +<td> +</td> +<td> (Not sure how the target value is specified, needs more research) +</td></tr> +<tr> +<th> 59 25 +</th> +<td> <code>put "extra" after textVar</code> +</td> +<td> -1 +</td> +<td> +</td> +<td> (See above) +</td></tr> +<tr> +<th> 59 35 +</th> +<td> <code>put "extra" before textVar</code> +</td> +<td> -1 +</td> +<td> +</td> +<td> (See above) +</td></tr> +<tr> +<th> 5A XX +</th></tr> +<tr> +<th> 5B 05 +</th> +<td> <code>delete word 3 of textVar</code> +</td> +<td> -1 +</td> +<td> +</td> +<td> (See above) +</td></tr> +<tr> +<th> 5C 00 +</th> +<td> +<p><code>(the abbr time)</code> +</p><p><code>(the short date)</code> +</p><p><code>(the last word in someText)</code> +</p> +</td> +<td> -1 OR -2 +</td> +<td> +1 +</td> +<td> +<p>If the top value is one of the following setting IDs, pop it from the stack, and push the current value of the setting: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 00 +</th> +<td> <code>the floatPrecision</code> +</td></tr> +<tr> +<th> 01 +</th> +<td> <code>the mouseDownScript</code> +</td></tr> +<tr> +<th> 02 +</th> +<td> <code>the mouseUpScript</code> +</td></tr> +<tr> +<th> 03 +</th> +<td> <code>the keyDownScript</code> +</td></tr> +<tr> +<th> 04 +</th> +<td> <code>the keyUpScript</code> +</td></tr> +<tr> +<th> 05 +</th> +<td> <code>the timeoutScript</code> +</td></tr></tbody></table> +<p>If the top value is a time-formatting ID, pop it from the stack, and push the current time formatted using it: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 06 +</th> +<td> <code>the short time</code> +</td> +<td> 1:09 AM +</td></tr> +<tr> +<th> 07 +</th> +<td> <code>the abbreviated time</code>, <code>the abbrev time</code>, <code>the abbr time</code> +</td> +<td> 1:09 AM +</td></tr> +<tr> +<th> 08 +</th> +<td> <code>the long time</code> +</td> +<td> 1:09:38 AM +</td></tr></tbody></table> +<p>If the top value is a date-formatting ID, pop it from the stack, and push the current date formatted using it: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 09 +</th> +<td> <code>the short date</code> +</td> +<td> 3/4/16 +</td></tr> +<tr> +<th> 0A +</th> +<td> <code>the abbreviated date</code>, <code>the abbrev date</code>, <code>the abbr date</code> +</td> +<td> Mon, Mar 14, 2016 +</td></tr> +<tr> +<th> 0B +</th> +<td> <code>the long date</code> +</td> +<td> Monday, March 14, 2016 +</td></tr></tbody></table> +<p>If the top value is a slice type ID, pop both it and the previous value from the stack. The previous value will be a string, slice the last "bit" of it according to the slice type, and push the sliced value: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 0C +</th> +<td> <code>the last char</code> +</td></tr> +<tr> +<th> 0D +</th> +<td> <code>the last word</code> +</td></tr> +<tr> +<th> 0E +</th> +<td> <code>the last item</code> +</td></tr> +<tr> +<th> 0F +</th> +<td> <code>the last line</code> +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5C 01 +</th> +<td> <code>(the number of chars in someText)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> +<p>Pop [text, stat ID] and push the stat value for the given text, using these stat IDs: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 01 +</th> +<td> chars +</td></tr> +<tr> +<th> 02 +</th> +<td> words +</td></tr> +<tr> +<th> 03 +</th> +<td> items <i>(separated by</i> <code>the itemDelimiter</code><i>, which is a comma by default)</i> +</td></tr> +<tr> +<th> 04 +</th> +<td> lines +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5C 02 +</th> +<td> <code>(the name of menu 1)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> +<p>Pop [menu ID, property ID] and push the value of the specified menu property, using these property IDs: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 01 +</th> +<td> <code>name</code> +</td></tr> +<tr> +<th> 02 +</th> +<td> <code>number of menuItems</code> +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5C 03 +</th> +<td> <code>(the name of menuItem 3 of menu 1)</code> +</td> +<td> -3 +</td> +<td> +1 +</td> +<td> +<p>Pop [item ID, menu ID, property ID] and push the value of the specified menu item property, using these property IDs: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 01 +</th> +<td> <code>name</code> +</td></tr> +<tr> +<th> 02 +</th> +<td> <code>checkMark</code> +</td></tr> +<tr> +<th> 03 +</th> +<td> <code>enabled</code> +</td></tr> +<tr> +<th> 04 +</th> +<td> <code>script</code> +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5C 04 +</th> +<td> <code>(the volume of sound 1)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> +<p>Pop [sound ID, property ID] and push the value of the specified sound property, using these property IDs: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 01 +</th> +<td> <code>volume</code> (0 to 255) +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5C 06 +</th> +<td> <code>(the cursor of sprite 3)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> +<p>Pop [sprite ID, property ID] and push the value of the specified sprite property, using these property IDs: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 01 +</th> +<td> <code>type</code> +</td></tr> +<tr> +<th> 02 +</th> +<td> <code>backColor</code> +</td></tr> +<tr> +<th> 03 +</th> +<td> <code>bottom</code> +</td></tr> +<tr> +<th> 04 +</th> +<td> <code>castNum</code> +</td></tr> +<tr> +<th> 05 +</th> +<td> <code>constraint</code> +</td></tr> +<tr> +<th> 06 +</th> +<td> <code>cursor</code> +</td></tr> +<tr> +<th> 07 +</th> +<td> <code>foreColor</code> +</td></tr> +<tr> +<th> 08 +</th> +<td> <code>height</code> +</td></tr> +<tr> +<th> 0A +</th> +<td> <code>ink</code> +</td></tr> +<tr> +<th> 0B +</th> +<td> <code>left</code> +</td></tr> +<tr> +<th> 0C +</th> +<td> <code>lineSize</code> +</td></tr> +<tr> +<th> 0D +</th> +<td> <code>locH</code> +</td></tr> +<tr> +<th> 0E +</th> +<td> <code>locV</code> +</td></tr> +<tr> +<th> 0F +</th> +<td> <code>movieRate</code> +</td></tr> +<tr> +<th> 10 +</th> +<td> <code>movieTime</code> +</td></tr> +<tr> +<th> 12 +</th> +<td> <code>puppet</code> +</td></tr> +<tr> +<th> 13 +</th> +<td> <code>right</code> +</td></tr> +<tr> +<th> 14 +</th> +<td> <code>startTime</code> +</td></tr> +<tr> +<th> 15 +</th> +<td> <code>stopTime</code> +</td></tr> +<tr> +<th> 16 +</th> +<td> <code>stretch</code> +</td></tr> +<tr> +<th> 17 +</th> +<td> <code>top</code> +</td></tr> +<tr> +<th> 18 +</th> +<td> <code>trails</code> +</td></tr> +<tr> +<th> 19 +</th> +<td> <code>visible</code> +</td></tr> +<tr> +<th> 1A +</th> +<td> <code>volume</code> (-256 to 256, <= 0 is silent) +</td></tr> +<tr> +<th> 1B +</th> +<td> <code>width</code> +</td></tr> +<tr> +<th> 1D +</th> +<td> <code>scriptNum</code> +</td></tr> +<tr> +<th> 1E +</th> +<td> <code>moveableSprite</code> +</td></tr> +<tr> +<th> 20 +</th> +<td> <code>scoreColor</code> +</td></tr></tbody></table> +<p>The values for <code>type</code> are: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 0 +</th> +<td> inactive +</td></tr> +<tr> +<th> 1 +</th> +<td> bitmap +</td></tr> +<tr> +<th> 2 +</th> +<td> rectangle +</td></tr> +<tr> +<th> 3 +</th> +<td> rounded rectangle +</td></tr> +<tr> +<th> 4 +</th> +<td> oval +</td></tr> +<tr> +<th> 5 +</th> +<td> line top-left to bottom-right +</td></tr> +<tr> +<th> 6 +</th> +<td> line bottom-left to top-right +</td></tr> +<tr> +<th> 7 +</th> +<td> text +</td></tr> +<tr> +<th> 8 +</th> +<td> button +</td></tr> +<tr> +<th> 9 +</th> +<td> checkbox +</td></tr> +<tr> +<th> 10 +</th> +<td> radio button +</td></tr> +<tr> +<th> 16 +</th> +<td> undetermined (try the castType of the associated cast member) +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5C 07 +</th> +<td> <code>(the exitLock)</code> +</td> +<td> -1 +</td> +<td> +1 +</td> +<td> +<p>Pop a setting ID from the stack and push its value, using these setting IDs: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 01 +</th> +<td> <code>the beepOn</code> +</td></tr> +<tr> +<th> 02 +</th> +<td> <code>the buttonStyle</code> +</td></tr> +<tr> +<th> 03 +</th> +<td> <code>the centerStage</code> +</td></tr> +<tr> +<th> 04 +</th> +<td> <code>the checkBoxAccess</code> +</td></tr> +<tr> +<th> 05 +</th> +<td> <code>the checkBoxType</code> +</td></tr> +<tr> +<th> 06 +</th> +<td> <code>the colorDepth</code> +</td></tr> +<tr> +<th> 08 +</th> +<td> <code>the exitLock</code> +</td></tr> +<tr> +<th> 09 +</th> +<td> <code>the fixStageSize</code> +</td></tr> +<tr> +<th> 13 +</th> +<td> <code>the timeoutLapsed</code> +</td></tr> +<tr> +<th> 17 +</th> +<td> <code>the selEnd</code> +</td></tr> +<tr> +<th> 18 +</th> +<td> <code>the selStart</code> +</td></tr> +<tr> +<th> 19 +</th> +<td> <code>the soundEnabled</code> +</td></tr> +<tr> +<th> 1A +</th> +<td> <code>the soundLevel</code> +</td></tr> +<tr> +<th> 1B +</th> +<td> <code>the stageColor</code> +</td></tr> +<tr> +<th> 1D +</th> +<td> <code>the stillDown</code> +</td></tr> +<tr> +<th> 1E +</th> +<td> <code>the timeoutKeyDown</code> +</td></tr> +<tr> +<th> 1F +</th> +<td> <code>the timeoutLength</code> +</td></tr> +<tr> +<th> 20 +</th> +<td> <code>the timeoutMouse</code> +</td></tr> +<tr> +<th> 21 +</th> +<td> <code>the timeoutPlay</code> +</td></tr> +<tr> +<th> 22 +</th> +<td> <code>the timer</code> +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5C 08 +</th> +<td> <code>(the number of castMembers)</code> +</td> +<td> -1 +</td> +<td> +1 +</td> +<td> +<p>Pop a stat ID from the stack and push the stat, using these stat IDs: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 01 +</th> +<td> <code>the perFrameHook</code> +</td></tr> +<tr> +<th> 02 +</th> +<td> <code>number of castMembers</code> +</td></tr> +<tr> +<th> 03 +</th> +<td> <code>number of menus</code> +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5C 09 +</th> +<td> +<p><code>(the picture of cast "bob")</code> +</p><p><code>(the name of cast 3)</code> +</p> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> +<p>Pop [cast ID, property ID] from the stack and push the value of the cast property, using these property IDs: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 01 +</th> +<td> <code>name</code> +</td></tr> +<tr> +<th> 02 +</th> +<td> <code>text</code> +</td></tr> +<tr> +<th> 08 +</th> +<td> <code>picture</code> +</td></tr> +<tr> +<th> 0A +</th> +<td> <code>number</code> +</td></tr> +<tr> +<th> 0B +</th> +<td> <code>size</code> +</td></tr> +<tr> +<th> 11 +</th> +<td> <code>foreColor</code> +</td></tr> +<tr> +<th> 12 +</th> +<td> <code>backColor</code> +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5C 0C +</th> +<td> <code>(the textSize of field 1)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> +<p>Pop [field ID, property ID] and push the value of the property for the given field according to these property IDs: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 03 +</th> +<td> <code>textStyle</code> +</td></tr> +<tr> +<th> 04 +</th> +<td> <code>textFont</code> +</td></tr> +<tr> +<th> 05 +</th> +<td> <code>textHeight</code> +</td></tr> +<tr> +<th> 06 +</th> +<td> <code>textAlign</code> +</td></tr> +<tr> +<th> 07 +</th> +<td> <code>textSize</code> +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5C 0D +</th> +<td> <code>(the sound of cast 5)</code> +</td> +<td> -2 +</td> +<td> +1 +</td> +<td> +<p>Pop [cast ID, property ID] and push the value of property for the given cast according to these property IDs: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 10 +</th> +<td> <code>sound</code> +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5D 00 +</th> +<td> <code>when keyDown then beep</code> +</td> +<td> -2 +</td> +<td> +</td> +<td> +<p>Pop [statement, eventID] and set the statement (Lingo source code in a text string) to run on the given event: +</p> +<table class="wikitable"> + +<tbody><tr> +<th> 01 +</th> +<td> <code>mouseDown</code> +</td></tr> +<tr> +<th> 02 +</th> +<td> <code>mouseUp</code> +</td></tr> +<tr> +<th> 03 +</th> +<td> <code>keyDown</code> +</td></tr> +<tr> +<th> 04 +</th> +<td> <code>keyUp</code> +</td></tr> +<tr> +<th> 05 +</th> +<td> <code>timeOut</code> +</td></tr></tbody></table> +</td></tr> +<tr> +<th> 5D 03 +</th> +<td> <code>set the enabled of menuItem 3 of menu 5 to FALSE</code> +</td> +<td> -4 +</td> +<td> +</td> +<td> Pop [menuItem ID, menu ID, new value, property ID] and set the menu item property. See the table for code 5C 03 for menu item property IDs. +</td></tr> +<tr> +<th> 5D 04 +</th> +<td> <code>set the volume of sound 3 to 255</code> +</td> +<td> -3 +</td> +<td> +</td> +<td> Pop [sound ID, new value, property ID] and set the menu item property. See the table for code 5C 04 for sound property IDs. +</td></tr> +<tr> +<th> 5D 06 +</th> +<td> <code>set the constraint of sprite 3 to 0</code> +</td> +<td> -3 +</td> +<td> +</td> +<td> Pop [sprite ID, new value, property ID] and set the sprite property. See the table for code 5C 06 for sprite property IDs. +</td></tr> +<tr> +<th> 5D 07 +</th> +<td> <code>set the exitLock to TRUE</code> +</td> +<td> -2 +</td> +<td> +</td> +<td> Pop [new value, setting ID] and change the relevant setting. See the table for code 5C 07 for setting IDs. +</td></tr> +<tr> +<th> 5D 09 +</th> +<td> <code>set the backColor of cast "bob" to 0</code> +</td> +<td> -3 +</td> +<td> +</td> +<td> Pop [cast ID, new value, property ID] and set the cast property. See the table for code 5C 09 for cast property IDs. +</td></tr> +<tr> +<th> 5D 0C +</th> +<td> <code>set the textAlign of field 3 to "right"</code> +</td> +<td> -3 +</td> +<td> +</td> +<td> Pop [field ID, new value, property ID] and set the field property. See the table for code 5C 0C for cast property IDs. +</td></tr> +<tr> +<th> 5D 0D +</th> +<td> <code>set the sound of cast 3 to TRUE</code> +</td> +<td> -3 +</td> +<td> +</td> +<td> Pop [cast ID, new value, property ID] and set the cast property. See the table for code 5C 0D for cast property IDs. +</td></tr> +<tr> +<th> 5E XX +</th></tr> +<tr> +<th> 5F XX +</th> +<td> <code>(the someProperty)</code> +</td> +<td> +</td> +<td> +1 +</td> +<td> Push the value of the contextual property with the name at namelist[XX]. +</td></tr> +<tr> +<th> 60 XX +</th> +<td> <code>set the someProperty to 0</code> +</td> +<td> -1 +</td> +<td> +</td> +<td> Pop a value and use it to set the contextual property with the name at namelist[XX]. +</td></tr> +<tr> +<th> 61 XX +</th> +<td> <code>(the someProperty of someVariable)</code> +</td> +<td> -1 +</td> +<td> +1 +</td> +<td> Pop a property-owning object from the stack, and push the value of this object's property with the name at namelist[XX]. +</td></tr> +<tr> +<th> 62 XX +</th> +<td> <code>set the someProperty of someVariable to 1</code> +</td> +<td> -2 +</td> +<td> +</td> +<td> Pop [property-owning object, new value] from the stack and set the property of the object with the name at namelist[XX]. +</td></tr> +<tr> +<th> 63 XX +</th> +<td> <code>tell someObject to go to frame 1</code> +</td> +<td> -1 +</td> +<td> +</td> +<td> Remote call: Similar to 57 XX except runs in the context of a <code>tell ... to</code> block. +</td></tr> +<tr> +<th> 64 XX +</th> +<td> +</td> +<td> +</td> +<td> +1 +</td> +<td> +<p>Push a copy of a value already on the stack, relative to the top where 00 is the top slot, 01 is one slot beneath the top, etc. +</p><p>This is used by the compiler when generating bytecode for the <code>repeat with i in list</code> block, to keep state in the loop without allocating new local variables. +</p> +</td></tr> +<tr> +<th> 65 XX +</th> +<td> +</td> +<td> -XX +</td> +<td> +</td> +<td> +<p>Pop and discard XX values from the top of the stack. +</p><p>This is used in the bytecode generated for a <code>repeat with i in list</code> block, to clean up at the end. +</p> +</td></tr> +<tr> +<th> 66 XX +</th> +<td> <code>(the pathName)</code> +</td> +<td> -1 +</td> +<td> +1 +</td> +<td> Pop an empty list and push the value of a read-only property named at namelist[XX]. +</td></tr></tbody></table> +<h1> <span class="mw-headline" id="Three_Byte_Instructions"> Three Byte Instructions </span></h1> +<table class="wikitable"> + +<tbody><tr> +<th> 81 XX YY +</th> +<td> <code>128</code> .. <code>32767</code> +</td> +<td> +</td> +<td> +1 +</td> +<td> Push the integer ((XX * 0x100) + YY). Larger integers and floats are pushed using constants. +</td></tr> +<tr> +<th> 82 XX YY +</th> +<td> <code>someFunc 1, 2, 3,</code> <i>(...)</i> <code>254, 255, 256, 257</code> +</td> +<td> -ďťż((XX * 0x100) + YY) +</td> +<td> +1 +</td> +<td> Pop ((XX * 0x100) + YY) values from the stack and push a no-return-value argument list object containing these values. Similar to code 42 XX, only necessary when there are more than 255 arguments in the list. +</td></tr> + +<tr> +<th> 83 XX YY +</th> +<td> <code>[1, 2, 3,</code> <i>(...)</i> <code>254, 255, 256, 257]</code> +</td> +<td> -ďťż((XX * 0x100) + YY) +</td> +<td> +1 +</td> +<td> Pop ((XX * 0x100) + YY) values from the stack and push a list object containing these values. Similar to code 43 XX, only necessary when there are more than 255 items in the list. +</td></tr> +<tr> +<th> 93 XX YY +</th> +<td> +<p><code>else</code> +</p><p><code>exit repeat</code> +</p><p><code>next repeat</code> +</p> +</td> +<td> +</td> +<td> +</td> +<td> Unconditional jump: Advance by ((XX * 0x100) + YY) bytes, relative to the first byte of this instruction (i.e. it may be 3 more than you are expecting) +<p>(<code>next repeat</code> jumps forward to <code>end repeat</code> instead of jumping back itself) +</p> +</td></tr> +<tr> +<th> 95 XX YY +</th> +<td> +<p><code>if somethingIsTrue then</code> +</p><p><code>repeat while somethingIsTrue</code> +</p> +</td> +<td> -1 +</td> +<td> +</td> +<td> Conditional jump: Pop a value, and if it is logically FALSE, advance by ((XX * 0x100) + YY) bytes, relative to the first byte of this instruction +</td></tr></tbody></table> +<h1> <span class="mw-headline" id="Syntactic_Sugar"> Syntactic Sugar </span></h1> +<p>Some functions get special syntax when written out in source code, but under the hood, the compiler just transforms it into more regular syntax. Here is a mapping that shows the equivalent in plain, generalized Lingo that gets used for the bytecode. +</p> +<table class="wikitable"> + +<tbody><tr> +<th> Specialized Syntax +</th> +<th> Generalized Syntax +</th></tr> +<tr> +<td><code>play frame 10 of movie "theMovie"</code> +</td> +<td><code>play 10, "theMovie"</code> +</td></tr> +<tr> +<td><code>play frame 10</code> +</td> +<td><code>play 10</code> +</td></tr> +<tr> +<td><code>play movie "theMovie"</code> +</td> +<td><code>play 1, "theMovie"</code> +</td></tr> +<tr> +<td><code>play done</code> +</td> +<td><code>play</code> +</td></tr> +<tr> +<td><pre>repeat with i = 15 to 20 + ... + +end repeat</pre> +</td> +<td><pre>set i = 15 +repeat while i <= 20 + ... + set i = i + 1 +end repeat</pre> +</td></tr> +<tr> +<td><pre>repeat with i = 15 down to 10 + ... + +end repeat</pre> +</td> +<td><pre>set i = 15 +repeat while i >= 10 + ... + set i = i - 1 +end repeat</pre> +</td></tr> +<tr> +<td><code>sound playFile 1, "Thunder"</code> +</td> +<td><code>sound #playFile, 1, "Thunder"</code> +</td></tr> +<tr> +<td><code>sound fadeIn 5</code> +</td> +<td><code>sound #fadeIn, 5</code> +</td></tr> +<tr> +<td><code>sound fadeIn 5, 10</code> +</td> +<td><code>sound #fadeIn, 5, 10</code> +</td></tr> +<tr> +<td><code>sound fadeOut 5</code> +</td> +<td><code>sound #fadeOut, 5</code> +</td></tr> +<tr> +<td><code>sound fadeOut 5, 10</code> +</td> +<td><code>sound #fadeOut, 5, 10</code> +</td></tr> +<tr> +<td><code>sound stop 1</code> +</td> +<td><code>sound #stop, 1</code> +</td></tr> +<tr> +<td><code>sound close 1</code> +</td> +<td><code>sound #close, 1</code> +</td></tr> +<tr> +<td><code>go to frame 10</code> +<p><code>go frame 10</code> +</p><p><code>go to 10</code> +</p> +</td> +<td><code>go 10</code> +</td></tr> +<tr> +<td><code>go to movie "theMovie"</code> +<p><code>go movie "theMovie"</code> +</p> +</td> +<td><code>go 1, "theMovie"</code> +</td></tr> +<tr> +<td><code>go to frame 10 of movie "theMovie"</code> +<p><code>go frame 10 of movie "theMovie"</code> +</p><p><code>go to 10 of movie "theMovie"</code> +</p><p><code>go 10 of movie "theMovie"</code> +</p> +</td> +<td><code>go 10, "theMovie"</code> +</td></tr> +<tr> +<td><code>go loop</code> +</td> +<td><code>go #loop</code> +</td></tr> +<tr> +<td><code>go next</code> +</td> +<td><code>go #next</code> +</td></tr> +<tr> +<td><code>go previous</code> +</td> +<td><code>go #previous</code> +</td></tr> +<tr> +<td><code>open "document" with "application"</code> +</td> +<td><code>open "document", "application"</code> +</td></tr> +<tr> +<td><code>set obj = GetObject()<br>obj(mSomeMethod, 1, 2, 3)</code> +</td> +<td><code>set obj = GetObject()<br>obj(#mSomeMethod, 1, 2, 3)</code> +</td></tr></tbody></table> +<h1> <span class="mw-headline" id="Lscr_bytecode-container_chunk_layout"> <code>Lscr</code> bytecode-container chunk layout </span></h1> +<h2> <span class="mw-headline" id="Header"> Header </span></h2> +<table class="wikitable"> + +<tbody><tr> +<td colspan="3">... +</td></tr> +<tr> +<th> $0040-$0041 +</th> +<td> uint16 +</td> +<td> Offset to the function records block +</td></tr> +<tr> +<td colspan="3">... +</td></tr> +<tr> +<th> $004E-$004F +</th> +<td> uint16 +</td> +<td> Number of constants +</td></tr> +<tr> +<td colspan="3">... +</td></tr> +<tr> +<th> $0048-$0049 +</th> +<td> uint16 +</td> +<td> Number of function records +</td></tr> +<tr> +<td colspan="3">... +</td></tr> +<tr> +<th> $0052-$0053 +</th> +<td> uint16 +</td> +<td> Offset to the constant records block +</td></tr> +<tr> +<td colspan="3">... +</td></tr> +<tr> +<th> $005A-$005B +</th> +<td> uint16 +</td> +<td> Base address for constant data +</td></tr></tbody></table> +<h2> <span class="mw-headline" id="Function_Record"> Function Record </span></h2> +<p>Each function record is 42 bytes long. +</p> +<table class="wikitable"> + +<tbody><tr> +<th> $0000-$0001 +</th> +<td> uint16 +</td> +<td> Namelist index for the function's name, or 0xFFFF if there is no name(?) +</td></tr> +<tr> +<th> $0002-$0003 +</th> +<td> uint16 +</td> +<td> Unknown +</td></tr> +<tr> +<th> $0004-$0007 +</th> +<td> uint32 +</td> +<td> Length of the function bytecode in bytes +</td></tr> +<tr> +<th> $0008-$000B +</th> +<td> uint32 +</td> +<td> Offset to the function bytecode +</td></tr> +<tr> +<th> $000C-$000D +</th> +<td> uint16 +</td> +<td> Number of arguments +</td></tr> +<tr> +<th> $000E-$0011 +</th> +<td> uint32 +</td> +<td> Unknown +</td></tr> +<tr> +<th> $0012-$0013 +</th> +<td> uint16 +</td> +<td> Number of local variables +</td></tr> +<tr> +<th> $0014-$0017 +</th> +<td> uint32 +</td> +<td> Unknown +</td></tr> +<tr> +<th> $0018-$0019 +</th> +<td> uint16 +</td> +<td> Count (C) +</td></tr> +<tr> +<th> $001A-$001D +</th> +<td> uint32 +</td> +<td> Unknown +</td></tr> +<tr> +<th> $001E-$0021 +</th> +<td> uint32 +</td> +<td> Unknown +</td></tr> +<tr> +<th> $0022-$0023 +</th> +<td> uint16 +</td> +<td> Unknown +</td></tr> +<tr> +<th> $0024-$0025 +</th> +<td> uint16 +</td> +<td> Count (D) +</td></tr> +<tr> +<th> $0026-$0029 +</th> +<td> uint32 +</td> +<td> Unknown +</td></tr></tbody></table> +<h2> <span class="mw-headline" id="Bytecode_Trailer"> Bytecode Trailer </span></h2> +<p>After the bytecode section for a function (determined using the offset and length fields from the function record), and then after an additional padding byte if there are an odd number of bytes in the bytecode, are the following values: +</p> +<ul><li> For each argument: uint16 namelist index for the argument's name +</li><li> For each local variable: uint16 namelist index for the variable's name +</li><li> Count (C) * uint16 +</li><li> Count (D) * uint8 +</li><li> A padding byte if Count (D) is an odd number +</li></ul> +<h2> <span class="mw-headline" id="Constants"> Constants </span></h2> +<p>Each constant record is six bytes long and has this format: +</p> +<ul><li> uint16: Value type ID +</li><li> uint32: Data address, relative to the base address given in the header +</li></ul> +<p>Here is how the value type IDs correspond to the data found at the given address: +</p> +<table class="wikitable"> +<tbody><tr> +<th> 01 +</th> +<td> Text string +</td> +<td> uint32 length (including null terminator) followed immediately by the character data +</td></tr> +<tr> +<th> 04 +</th> +<td> 32-bit unsigned integer +</td> +<td> "Data address" not an address, but the value itself +</td></tr> +<tr> +<th> 09 +</th> +<td> Floating point +</td> +<td> uint32 length followed by the floating point data. In practice, the length always seems to be 10, so the number is an 80-bit extended precision number. +</td></tr></tbody></table> +<h1> <span class="mw-headline" id="Projector_File_.28Windows.29"> Projector File (Windows) </span></h1> +<h2> <span class="mw-headline" id="Director_3.0"> Director 3.0 </span></h2> +<p>At the very end of the projector executable is a 32-bit little-endian file address. +</p><p>At this location is found: +</p> +<ul><li> 7 bytes: Not sure/more research needed +</li><li> uint32: Length of the RIFF block +</li><li> uint8: Length of the original RIFF file's name +</li><li> ASCII: Original RIFF file's name +</li><li> uint8: Length of the original RIFF file's parent folder +</li><li> ASCII: Original RIFF file's parent folder +</li><li> RIFF block +</li></ul> +<h2> <span class="mw-headline" id="Director_4.0"> Director 4.0 </span></h2> +<p>At the very end of the projector executable is a 32-bit little-endian file address. +</p><p>At this location is found: +</p> +<ul><li> ASCII "PJ93" +</li><li> The file address of the main RIFF data file +</li><li> Six further addresses for other embedded data (more research required to know more about these) +</li></ul> + +<!-- +NewPP limit report +Preprocessor node count: 196/1000000 +Post-expand include size: 1279/2097152 bytes +Template argument size: 338/2097152 bytes +Expensive parser function count: 0/100 +--> + +<!-- Saved in parser cache with key justsolve:pcache:idhash:6263-0!*!0!!en!*!* and timestamp 20160712223455 --> +</div> <!-- /bodycontent --> + <!-- printfooter --> + <div class="printfooter"> + Retrieved from "<a href="http://fileformats.archiveteam.org/index.php?title=Lingo_bytecode&oldid=25053">http://fileformats.archiveteam.org/index.php?title=Lingo_bytecode&oldid=25053</a>" </div> + <!-- /printfooter --> + <!-- catlinks --> + <div id="catlinks" class="catlinks"><div id="mw-normal-catlinks" class="mw-normal-catlinks"><a href="http://fileformats.archiveteam.org/wiki/Special:Categories" title="Special:Categories">Categories</a>: <ul><li><a href="http://fileformats.archiveteam.org/wiki/Category:File_Formats" title="Category:File Formats">File Formats</a></li><li><a href="http://fileformats.archiveteam.org/wiki/Category:Electronic_File_Formats" title="Category:Electronic File Formats">Electronic File Formats</a></li><li><a href="http://fileformats.archiveteam.org/wiki/Category:Development" title="Category:Development">Development</a></li></ul></div><div id="mw-hidden-catlinks" class="mw-hidden-catlinks mw-hidden-cats-hidden">Hidden categories: <ul><li><a href="http://fileformats.archiveteam.org/wiki/Category:FormatInfo_without_extensions" title="Category:FormatInfo without extensions">FormatInfo without extensions</a></li><li><a href="http://fileformats.archiveteam.org/wiki/Category:FormatInfo_without_mimetypes" title="Category:FormatInfo without mimetypes">FormatInfo without mimetypes</a></li></ul></div></div> <!-- /catlinks --> + <div class="visualClear"></div> + <!-- debughtml --> + <!-- /debughtml --> + </div> + <!-- /bodyContent --> + </div> + <!-- /content --> + <!-- header --> + <div id="mw-head" class="noprint"> + +<!-- 0 --> +<div id="p-personal" class=""> + <h5>Personal tools</h5> + <ul> + <li id="pt-login"><a href="http://fileformats.archiveteam.org/index.php?title=Special:UserLogin&returnto=Lingo+bytecode" title="You are encouraged to log in; however, it is not mandatory [ctrl-option-o]" accesskey="o">Log in / create account</a></li> + </ul> +</div> + +<!-- /0 --> + <div id="left-navigation"> + +<!-- 0 --> +<div id="p-namespaces" class="vectorTabs"> + <h5>Namespaces</h5> + <ul> + <li id="ca-nstab-main" class="selected"><span><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode" title="View the content page [ctrl-option-c]" accesskey="c">Page</a></span></li> + <li id="ca-talk" class="new"><span><a href="http://fileformats.archiveteam.org/index.php?title=Talk:Lingo_bytecode&action=edit&redlink=1" title="Discussion about the content page [ctrl-option-t]" accesskey="t">Discussion</a></span></li> + </ul> +</div> + +<!-- /0 --> + +<!-- 1 --> +<div id="p-variants" class="vectorMenu emptyPortlet"> + <h4> + </h4> + <h5><span>Variants</span><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#"></a></h5> + <div class="menu"> + <ul> + </ul> + </div> +</div> + +<!-- /1 --> + </div> + <div id="right-navigation"> + +<!-- 0 --> +<div id="p-views" class="vectorTabs"> + <h5>Views</h5> + <ul> + <li id="ca-view" class="selected"><span><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode">Read</a></span></li> + <li id="ca-viewsource"><span><a href="http://fileformats.archiveteam.org/index.php?title=Lingo_bytecode&action=edit" title="This page is protected. +You can view its source [ctrl-option-e]" accesskey="e">View source</a></span></li> + <li id="ca-history" class="collapsible"><span><a href="http://fileformats.archiveteam.org/index.php?title=Lingo_bytecode&action=history" title="Past revisions of this page [ctrl-option-h]" accesskey="h">View history</a></span></li> + </ul> +</div> + +<!-- /0 --> + +<!-- 1 --> +<div id="p-cactions" class="vectorMenu emptyPortlet"> + <h5><span>Actions</span><a href="http://fileformats.archiveteam.org/wiki/Lingo_bytecode#"></a></h5> + <div class="menu"> + <ul> + </ul> + </div> +</div> + +<!-- /1 --> + +<!-- 2 --> +<div id="p-search"> + <h5><label for="searchInput">Search</label></h5> + <form action="http://fileformats.archiveteam.org/index.php" id="searchform"> + <div> + <input type="search" name="search" title="Search Just Solve the File Format Problem [ctrl-option-f]" accesskey="f" id="searchInput"> <input type="submit" name="go" value="Go" title="Go to a page with this exact name if exists" id="searchGoButton" class="searchButton"> <input type="submit" name="fulltext" value="Search" title="Search the pages for this text" id="mw-searchButton" class="searchButton"> <input type="hidden" name="title" value="Special:Search"> + </div> + </form> +</div> + +<!-- /2 --> + </div> + </div> + <!-- /header --> + <!-- panel --> + <div id="mw-panel" class="noprint"> + <!-- logo --> + <div id="p-logo"><a style="background-image: url(/thumbsup.png);" href="http://fileformats.archiveteam.org/wiki/Main_Page" title="Visit the main page"></a></div> + <!-- /logo --> + +<!-- navigation --> +<div class="portal" id="p-navigation"> + <h5>Navigation</h5> + <div class="body"> + <ul> + <li id="n-mainpage-description"><a href="http://fileformats.archiveteam.org/wiki/Main_Page" title="Visit the main page [ctrl-option-z]" accesskey="z">Main page</a></li> + <li id="n-File-formats"><a href="http://fileformats.archiveteam.org/wiki/File_Formats">File formats</a></li> + <li id="n-Formats-by-extension"><a href="http://fileformats.archiveteam.org/wiki/Category:File_formats_by_extension">Formats by extension</a></li> + <li id="n-Still-more-extensions"><a href="http://fileformats.archiveteam.org/wiki/Category:File_Format_Extension">Still more extensions</a></li> + <li id="n-Software"><a href="http://fileformats.archiveteam.org/wiki/Software">Software</a></li> + <li id="n-Glossary"><a href="http://fileformats.archiveteam.org/wiki/Glossary">Glossary</a></li> + <li id="n-Library"><a href="http://fileformats.archiveteam.org/wiki/Library">Library</a></li> + <li id="n-Sources"><a href="http://fileformats.archiveteam.org/wiki/Sources">Sources</a></li> + <li id="n-Categories"><a href="http://fileformats.archiveteam.org/wiki/Category:Top_Level_Categories">Categories</a></li> + <li id="n-portal"><a href="http://fileformats.archiveteam.org/wiki/Just_Solve_the_File_Format_Problem:Community_portal" title="About the project, what you can do, where to find things">Community portal</a></li> + <li id="n-recentchanges"><a href="http://fileformats.archiveteam.org/wiki/Special:RecentChanges" title="A list of recent changes in the wiki [ctrl-option-r]" accesskey="r">Recent changes</a></li> + <li id="n-randompage"><a href="http://fileformats.archiveteam.org/wiki/Special:Random" title="Load a random page [ctrl-option-x]" accesskey="x">Random page</a></li> + </ul> + </div> +</div> + +<!-- /navigation --> + +<!-- SEARCH --> + +<!-- /SEARCH --> + +<!-- TOOLBOX --> +<div class="portal" id="p-tb"> + <h5>Toolbox</h5> + <div class="body"> + <ul> + <li id="t-whatlinkshere"><a href="http://fileformats.archiveteam.org/wiki/Special:WhatLinksHere/Lingo_bytecode" title="A list of all wiki pages that link here [ctrl-option-j]" accesskey="j">What links here</a></li> + <li id="t-recentchangeslinked"><a href="http://fileformats.archiveteam.org/wiki/Special:RecentChangesLinked/Lingo_bytecode" title="Recent changes in pages linked from this page [ctrl-option-k]" accesskey="k">Related changes</a></li> + <li id="t-specialpages"><a href="http://fileformats.archiveteam.org/wiki/Special:SpecialPages" title="A list of all special pages [ctrl-option-q]" accesskey="q">Special pages</a></li> + <li><a href="http://fileformats.archiveteam.org/index.php?title=Lingo_bytecode&printable=yes" rel="alternate">Printable version</a></li> + <li id="t-permalink"><a href="http://fileformats.archiveteam.org/index.php?title=Lingo_bytecode&oldid=25053" title="Permanent link to this revision of the page">Permanent link</a></li> + </ul> + </div> +</div> + +<!-- /TOOLBOX --> + +<!-- LANGUAGES --> + +<!-- /LANGUAGES --> + </div> + <!-- /panel --> + <!-- footer --> + <div id="footer"> + <ul id="footer-info"> + <li id="footer-info-lastmod"> This page was last modified on 17 March 2016, at 18:25.</li> + <li id="footer-info-viewcount">This page has been accessed 586 times.</li> + <li id="footer-info-copyright">Content is available under <a class="external" href="http://creativecommons.org/publicdomain/zero/1.0/">Creative Commons 0</a>.</li> + </ul> + <ul id="footer-places"> + <li id="footer-places-privacy"><a href="http://fileformats.archiveteam.org/wiki/Just_Solve_the_File_Format_Problem:Privacy_policy" title="Just Solve the File Format Problem:Privacy policy">Privacy policy</a></li> + <li id="footer-places-about"><a href="http://fileformats.archiveteam.org/wiki/Just_Solve_the_File_Format_Problem:About" title="Just Solve the File Format Problem:About">About Just Solve the File Format Problem</a></li> + <li id="footer-places-disclaimer"><a href="http://fileformats.archiveteam.org/wiki/Just_Solve_the_File_Format_Problem:General_disclaimer" title="Just Solve the File Format Problem:General disclaimer">Disclaimers</a></li> + </ul> + <ul id="footer-icons" class="noprint"> + <li id="footer-copyrightico"> + <a href="http://creativecommons.org/publicdomain/zero/1.0/"><img src="./Lingo bytecode - Just Solve the File Format Problem_files/cc-0.png" alt="Creative Commons 0" width="88" height="31"></a> + </li> + <li id="footer-poweredbyico"> + <a href="http://www.mediawiki.org/"><img src="./Lingo bytecode - Just Solve the File Format Problem_files/poweredby_mediawiki_88x31.png" alt="Powered by MediaWiki" width="88" height="31"></a> + </li> + </ul> + <div style="clear:both"></div> + </div> + <!-- /footer --> + <script src="./Lingo bytecode - Just Solve the File Format Problem_files/load(4).php"></script> +<script>if(window.mw){ +mw.loader.load(["mediawiki.user","mediawiki.page.ready"], null, true); +}</script><script src="./Lingo bytecode - Just Solve the File Format Problem_files/load(5).php" type="text/javascript"></script> +<!-- Served in 0.102 secs. --> + + +<script type="text/javascript" src="chrome-extension://cmjeonfdjdekpggjkoknhhkcifnaichh/src/rules.js"></script><script type="text/javascript" src="chrome-extension://cmjeonfdjdekpggjkoknhhkcifnaichh/src/inject.js"></script></body><span class="gr__tooltip"><span class="gr__tooltip-content"></span><i class="gr__tooltip-logo"></i><span class="gr__triangle"></span></span></html>
\ No newline at end of file diff --git a/engines/director/lingo/tests/builtin.lingo b/engines/director/lingo/tests/builtin.lingo new file mode 100644 index 0000000000..351efdb12c --- /dev/null +++ b/engines/director/lingo/tests/builtin.lingo @@ -0,0 +1,24 @@ +beep +beep 3 +alert "Hi" +alert "Hi" && "there" + +open "Hello" +open "Hello" with "Finder" +open "Hello" && "more" with "Finder" + +puppetPalette "Rainbow" +puppetPalette "System",30 +puppetPalette "custompal", 15,4 + +puppetSound "Air Lock Lock" +puppetSound 0 +puppetSound midiStart +puppetSound midiSong, 3 +puppetSound midisongPointer, 2, 120 + +puppetSprite 15, true + +puppetTempo 30 +puppetTransition 1 +puppetTransition 2,4,20 diff --git a/engines/director/lingo/tests/factory.lingo b/engines/director/lingo/tests/factory.lingo new file mode 100644 index 0000000000..388d2c3a51 --- /dev/null +++ b/engines/director/lingo/tests/factory.lingo @@ -0,0 +1,69 @@ +-- +macro AimGun2 +global aim1 +set aim1 = aim2(mNew) +-- +factory aim2 +method mNew + dontpassevent + global aim1 + when mousedown then aim1(fire) + when keydown then aim1(mExit) + set the locv of sprite 24 to 540 +method mMove x, y + set the locH of sprite 15 to x + set the locV of sprite 15 to y-250 +method mAtFrame + dontpassevent + me(mMove, the mouseH, the mouseV) +method fire + global fire1, targeth, targetv + set fire1 = fire2(mNew) + set the perframehook to fire1 + me(mDispose) +method mExit + set the perframehook to false + postfire + me(mDispose) +method mDispose + global aim1 + set aim1 = 1 + when keydown then nothing +-- +factory fire2 +method mNew + dontpassevent + when mousedown then nothing + set the castnum of sprite 14 to f15 +method mAtFrame + Global StartH, StartV, targetv, stepH, stepV, bcast + dontpassevent + set the castnum of sprite 14 to bcast + set the LocV of sprite 14 to (startV-stepV) + if sprite 14 intersects 10 and (startV-6) <= targetV then + set the castnum of sprite 14 to f16 + set the perframehook to false + me(hit) + exit + end if + if startV < targetV or bcast>g17 then + set the perframehook to false + set the locV of sprite 14 to 340 + aimgun2 + exit + end if + set startV to (startV-stepV) + set bcast = bcast + 1 +method hit + global KillLoc + set killloc to the loch of sprite 3 + go "Death" + set the locV of sprite 14 to 400 + aimgun2 +method mDispose + global fire1 + set fire1 = 0 +-- +macro KillIt2 +global KillLoc +set the locH of sprite 3 to KillLoc diff --git a/engines/director/lingo/tests/factory2.lingo b/engines/director/lingo/tests/factory2.lingo new file mode 100644 index 0000000000..a7b2317e17 --- /dev/null +++ b/engines/director/lingo/tests/factory2.lingo @@ -0,0 +1,4 @@ +global aim1 +AimGun2 + +aim1(mDispose) diff --git a/engines/director/lingo/tests/goto.lingo b/engines/director/lingo/tests/goto.lingo new file mode 100644 index 0000000000..854506e260 --- /dev/null +++ b/engines/director/lingo/tests/goto.lingo @@ -0,0 +1,26 @@ +go to frame "Open23" of movie "OpenCabin23" +go "CARDBACK" +go movie "BAR 1" +go to "Open23" of movie "OpenCabin23" +go to "Chair" + +set varframe to "VARFrame" +set varmovie to "VARMovie" + +go to frame 35 +go "label two" +go to movie "Chicago" +go to frame 23 of movie "Chicago" +go to frame "main loop" of movie "Basic With" +play frame varFrame of movie varMovie +go to marker(1) + +play frame 37 +play frame "label one" +play movie "Desert Scene" +play frame 23 of movie "Chicago" +play frame varframe of movie varmovie +play frame "main loop" of movie "Basic With" + +playAccel "Lungs.mma" +playAccel "Bolitas.mma", loop, clickStop, whatFits diff --git a/engines/director/lingo/tests/if.lingo b/engines/director/lingo/tests/if.lingo new file mode 100644 index 0000000000..8f1e2391e6 --- /dev/null +++ b/engines/director/lingo/tests/if.lingo @@ -0,0 +1,27 @@ +-- +set x = 1 +if x = 5 then exit +else put 10.0 + +repeat with x = 1 to 6 + if x = 3 then put 30 + else if x = 4 then put 40 + else if x = 5 then put 50 + else put 10.0 + if x = 1 then + put 1 + else if x = 2 then + put 1232.12345678901234 + put 2.2 + else if x = 3 then + put 3 + else if x = 4 then + put 4 + else if x = 5 then + put 5 + else if x = 6 then + put 6 + end if + if x = 4 then put 40 + else put 50 +end repeat diff --git a/engines/director/lingo/tests/ilk.lingo b/engines/director/lingo/tests/ilk.lingo new file mode 100644 index 0000000000..686d9a5118 --- /dev/null +++ b/engines/director/lingo/tests/ilk.lingo @@ -0,0 +1,7 @@ +put ilk(10) +put ilk(20.0) +put ilk("Macromedia") +put ilk(point(10, 20)) +put ilk(ilk(10)) +set x = point(10, 20) +put ilk(x) diff --git a/engines/director/lingo/tests/lingotests.lingo b/engines/director/lingo/tests/lingotests.lingo new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/engines/director/lingo/tests/lingotests.lingo diff --git a/engines/director/lingo/tests/loops.lingo b/engines/director/lingo/tests/loops.lingo new file mode 100644 index 0000000000..e4c5ccefc5 --- /dev/null +++ b/engines/director/lingo/tests/loops.lingo @@ -0,0 +1,22 @@ +set x = 5 +if x <= 5 then set x = 6 +if (x = 5) then +set x = 7 -- this is comment +else +set x = 8 +-- this is another comment +end if +put x +-- this is more comment +set y = 1 +repeat while (y < 5) +set y = y + 1 +put y +end repeat + +repeat with z = 10 to 15 +put z +end repeat +repeat with y = 5 down to 1 +put y +end repeat diff --git a/engines/director/lingo/tests/macros.lingo b/engines/director/lingo/tests/macros.lingo new file mode 100644 index 0000000000..7ffa557cb7 --- /dev/null +++ b/engines/director/lingo/tests/macros.lingo @@ -0,0 +1,42 @@ +-- +macro SHIPX +global x, y +set x = Random(5) +if x = 1 then +go "Zoom" +exit +end if +if x >1 then +set y = 10 +exit +end if +put 100 + +-- +macro ZIPX +set x = Random(5) +if x = 1 then +go "ZIP" +exit +end if +if x >1 then +put x +exit +end if + +-- +macro check par1, par2 +, par3 +if par1 = 3 then +put -3 +else +put 0 +end if +if par2 = 2 then +put 2 +else +put 0 +end if +put par1 +put par2 +put par3 diff --git a/engines/director/lingo/tests/macros2.lingo b/engines/director/lingo/tests/macros2.lingo new file mode 100644 index 0000000000..b587ae421c --- /dev/null +++ b/engines/director/lingo/tests/macros2.lingo @@ -0,0 +1,11 @@ +check(2, 3) +global x, y +set y = 8 +shipx +put x +zipx +put x +put y +check(1, 2, 3) +check 4, 5, 6 +check 7, 8 diff --git a/engines/director/lingo/tests/math.lingo b/engines/director/lingo/tests/math.lingo new file mode 100644 index 0000000000..6f8ecc374f --- /dev/null +++ b/engines/director/lingo/tests/math.lingo @@ -0,0 +1,22 @@ +if random(4) > 2 then put 1000 +set z = 5.5 +set z1 = 2 +set z2 = z / z1 +put z +put z1 +put z2 +put integer(z2) +put cos(z2) + +set x = 2 + 3 * (4 / 2) +put x + +put power(2, 8) +put power(2, 8, 0) +put power(2) +updatestage + +-- Type conversion +put (1024/4096)*100 -- 0 +put (1024/4096)*100.0 -- 0.0 +put ((1024*1.0)/4096)*100.0 -- 25.0 diff --git a/engines/director/lingo/tests/mci.lingo b/engines/director/lingo/tests/mci.lingo new file mode 100644 index 0000000000..04130bf907 --- /dev/null +++ b/engines/director/lingo/tests/mci.lingo @@ -0,0 +1,2 @@ +mci "open MM\T005045a.wav type WaveAudio alias T005045a" +mci "play T005045a from 22710 to 32872" diff --git a/engines/director/lingo/tests/point.lingo b/engines/director/lingo/tests/point.lingo new file mode 100644 index 0000000000..4e90ddb684 --- /dev/null +++ b/engines/director/lingo/tests/point.lingo @@ -0,0 +1,3 @@ +put point(10, 20) +set x = point(20,30) +put x diff --git a/engines/director/lingo/tests/strings.lingo b/engines/director/lingo/tests/strings.lingo new file mode 100644 index 0000000000..568eb74640 --- /dev/null +++ b/engines/director/lingo/tests/strings.lingo @@ -0,0 +1,13 @@ +set z = "foo bar baz" +set z1 = z & " meow" +set z1 = z1 && "woof" +put z +put z1 +put chars("Macromedia", 6, 6) +put chars("Macromedia", 6, 10) +put chars("Macromedia", -1, 15) +if z1 contains "MeÍW" then + put "Contains" +else + put "Doesn't contain" +end if diff --git a/engines/director/lingo/tests/the.lingo b/engines/director/lingo/tests/the.lingo new file mode 100644 index 0000000000..65c0d6ea5c --- /dev/null +++ b/engines/director/lingo/tests/the.lingo @@ -0,0 +1,6 @@ +put 1.0 / 3 +set the floatPrecision to 6 +put 1.0 / 3 +put the loch of sprite 4 +set the loch of sprite 5 to 10 +set the castnum of sprite 8 to the number of cast "A Blank Castmember" diff --git a/engines/director/module.mk b/engines/director/module.mk new file mode 100644 index 0000000000..2499528304 --- /dev/null +++ b/engines/director/module.mk @@ -0,0 +1,31 @@ +MODULE := engines/director + +MODULE_OBJS = \ + detection.o \ + dib.o \ + director.o \ + movie.o \ + resource.o \ + score.o \ + sound.o \ + lingo/lingo-gr.o \ + lingo/lingo.o \ + lingo/lingo-builtins.o \ + lingo/lingo-code.o \ + lingo/lingo-codegen.o \ + lingo/lingo-funcs.o \ + lingo/lingo-lex.o \ + lingo/lingo-the.o + +director-grammar: + flex -o engines/director/lingo/lingo-lex.cpp engines/director/lingo/lingo-lex.l + bison -dv -o engines/director/lingo/lingo-gr.cpp engines/director/lingo/lingo-gr.y + mv engines/director/lingo/lingo-gr.hpp engines/director/lingo/lingo-gr.h + +# This module can be built as a plugin +ifeq ($(ENABLE_DIRECTOR), DYNAMIC_PLUGIN) +PLUGIN := 1 +endif + +# Include common rules +include $(srcdir)/rules.mk diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp new file mode 100644 index 0000000000..3c34e2d432 --- /dev/null +++ b/engines/director/movie.cpp @@ -0,0 +1,66 @@ +/* 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. + * + * Additional copyright for this file: + * Copyright (C) 1995-1997 Presto Studios, Inc. + * + * 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 "video/qt_decoder.h" +#include "director/movie.h" +#include "director/score.h" +#include "common/debug.h" +#include "common/system.h" +namespace Director { + +Movie::Movie(Common::String fileName, DirectorEngine *vm) { + _vm = vm; + _currentVideo = new Video::QuickTimeDecoder(); + if (!_currentVideo->loadFile(fileName)) { + warning("Can not open file %s", fileName.c_str()); + return; + } +} + +void Movie::play(Common::Point dest) { + + _currentVideo->start(); + + uint16 width = _currentVideo->getWidth(); + uint16 height = _currentVideo->getHeight(); + + while (!_currentVideo->endOfVideo()) { + if (_currentVideo->needsUpdate()) { + const Graphics::Surface *frame = _currentVideo->decodeNextFrame(); + g_system->copyRectToScreen(frame->getPixels(), frame->pitch, dest.x, dest.y, width, height); + g_system->updateScreen(); + } + g_system->delayMillis(10); + _vm->getCurrentScore()->processEvents(); + } +} + +void Movie::stop() { + _currentVideo->stop(); +} + +Movie::~Movie() { + delete _currentVideo; +} + +} //End of namespace Director diff --git a/engines/director/movie.h b/engines/director/movie.h new file mode 100644 index 0000000000..e26d10a7c7 --- /dev/null +++ b/engines/director/movie.h @@ -0,0 +1,51 @@ +/* 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. + * + * Additional copyright for this file: + * Copyright (C) 1995-1997 Presto Studios, Inc. + * + * 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 DIRECTOR_MOVIE_H +#define DIRECTOR_MOVIE_H + +#include "common/str.h" +#include "common/rect.h" +#include "graphics/managed_surface.h" +#include "director/director.h" + +namespace Video { +class VideoDecoder; +} + +namespace Director { + +class Movie { +public: + Movie(Common::String fileName, DirectorEngine *vm); + ~Movie(); + void play(Common::Point dest); + void stop(); + +private: + Video::VideoDecoder *_currentVideo; + DirectorEngine *_vm; +}; +} //End of namespace Director + +#endif diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp new file mode 100644 index 0000000000..fdb0712cb9 --- /dev/null +++ b/engines/director/resource.cpp @@ -0,0 +1,440 @@ +/* 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 "director/resource.h" + +#include "common/debug.h" +#include "common/macresman.h" +#include "common/substream.h" +#include "common/util.h" +#include "common/textconsole.h" + +namespace Director { + +// Base Archive code + +Archive::Archive() { + _stream = 0; + _isBigEndian = true; +} + +Archive::~Archive() { + close(); +} + +bool Archive::openFile(const Common::String &fileName) { + Common::File *file = new Common::File(); + + if (!file->open(fileName)) { + delete file; + return false; + } + + if (!openStream(file)) { + close(); + return false; + } + + return true; +} + +void Archive::close() { + _types.clear(); + delete _stream; _stream = 0; +} + +bool Archive::hasResource(uint32 tag, uint16 id) const { + if (!_types.contains(tag)) + return false; + + return _types[tag].contains(id); +} + +bool Archive::hasResource(uint32 tag, const Common::String &resName) const { + if (!_types.contains(tag) || resName.empty()) + return false; + + const ResourceMap &resMap = _types[tag]; + + for (ResourceMap::const_iterator it = resMap.begin(); it != resMap.end(); it++) + if (it->_value.name.matchString(resName)) + return true; + + return false; +} + +Common::SeekableSubReadStreamEndian *Archive::getResource(uint32 tag, uint16 id) { + if (!_types.contains(tag)) + error("Archive does not contain '%s' %04x", tag2str(tag), id); + + const ResourceMap &resMap = _types[tag]; + + if (!resMap.contains(id)) + error("Archive does not contain '%s' %04x", tag2str(tag), id); + + const Resource &res = resMap[id]; + + return new Common::SeekableSubReadStreamEndian(_stream, res.offset, res.offset + res.size, _isBigEndian, DisposeAfterUse::NO); +} + +uint32 Archive::getOffset(uint32 tag, uint16 id) const { + if (!_types.contains(tag)) + error("Archive does not contain '%s' %04x", tag2str(tag), id); + + const ResourceMap &resMap = _types[tag]; + + if (!resMap.contains(id)) + error("Archive does not contain '%s' %04x", tag2str(tag), id); + + return resMap[id].offset; +} + +uint16 Archive::findResourceID(uint32 tag, const Common::String &resName) const { + if (!_types.contains(tag) || resName.empty()) + return 0xFFFF; + + const ResourceMap &resMap = _types[tag]; + + for (ResourceMap::const_iterator it = resMap.begin(); it != resMap.end(); it++) + if (it->_value.name.matchString(resName)) + return it->_key; + + return 0xFFFF; +} + +Common::String Archive::getName(uint32 tag, uint16 id) const { + if (!_types.contains(tag)) + error("Archive does not contain '%s' %04x", tag2str(tag), id); + + const ResourceMap &resMap = _types[tag]; + + if (!resMap.contains(id)) + error("Archive does not contain '%s' %04x", tag2str(tag), id); + + return resMap[id].name; +} + +Common::Array<uint32> Archive::getResourceTypeList() const { + Common::Array<uint32> typeList; + + for (TypeMap::const_iterator it = _types.begin(); it != _types.end(); it++) + typeList.push_back(it->_key); + + return typeList; +} + +Common::Array<uint16> Archive::getResourceIDList(uint32 type) const { + Common::Array<uint16> idList; + + if (!_types.contains(type)) + return idList; + + const ResourceMap &resMap = _types[type]; + + for (ResourceMap::const_iterator it = resMap.begin(); it != resMap.end(); it++) + idList.push_back(it->_key); + + return idList; +} + +uint32 Archive::convertTagToUppercase(uint32 tag) { + uint32 newTag = toupper(tag >> 24) << 24; + newTag |= toupper((tag >> 16) & 0xFF) << 16; + newTag |= toupper((tag >> 8) & 0xFF) << 8; + + return newTag | toupper(tag & 0xFF); +} + +// Mac Archive code + +MacArchive::MacArchive() : Archive(), _resFork(0) { +} + +MacArchive::~MacArchive() { + delete _resFork; +} + +void MacArchive::close() { + Archive::close(); + delete _resFork; + _resFork = 0; +} + +bool MacArchive::openFile(const Common::String &fileName) { + close(); + + _resFork = new Common::MacResManager(); + + if (!_resFork->open(fileName) || !_resFork->hasResFork()) { + close(); + return false; + } + + Common::MacResTagArray tagArray = _resFork->getResTagArray(); + + for (uint32 i = 0; i < tagArray.size(); i++) { + ResourceMap &resMap = _types[tagArray[i]]; + Common::MacResIDArray idArray = _resFork->getResIDArray(tagArray[i]); + + for (uint32 j = 0; j < idArray.size(); j++) { + Resource &res = resMap[idArray[j]]; + + res.offset = res.size = 0; // unused + res.name = _resFork->getResName(tagArray[i], idArray[j]); + debug(3, "Found MacArchive resource '%s' %d: %s", tag2str(tagArray[i]), idArray[j], res.name.c_str()); + } + } + + return true; +} + +bool MacArchive::openStream(Common::SeekableReadStream *stream, uint32 startOffset) { + // TODO: Add support for this (v4 Windows games) + return false; +} + +Common::SeekableSubReadStreamEndian *MacArchive::getResource(uint32 tag, uint16 id) { + assert(_resFork); + Common::SeekableReadStream *stream = _resFork->getResource(tag, id); + return new Common::SeekableSubReadStreamEndian(stream, 0, stream->size(), true, DisposeAfterUse::NO); +} + +// RIFF Archive code + +bool RIFFArchive::openStream(Common::SeekableReadStream *stream, uint32 startOffset) { + close(); + + stream->seek(startOffset); + + if (convertTagToUppercase(stream->readUint32BE()) != MKTAG('R', 'I', 'F', 'F')) + return false; + + stream->readUint32LE(); // size + + if (convertTagToUppercase(stream->readUint32BE()) != MKTAG('R', 'M', 'M', 'P')) + return false; + + if (convertTagToUppercase(stream->readUint32BE()) != MKTAG('C', 'F', 'T', 'C')) + return false; + + uint32 cftcSize = stream->readUint32LE(); + uint32 startPos = stream->pos(); + stream->readUint32LE(); // unknown (always 0?) + + while ((uint32)stream->pos() < startPos + cftcSize) { + uint32 tag = convertTagToUppercase(stream->readUint32BE()); + + uint32 size = stream->readUint32LE(); + uint32 id = stream->readUint32LE(); + uint32 offset = stream->readUint32LE(); + + if (tag == 0) + break; + + uint16 startResPos = stream->pos(); + stream->seek(offset + 12); + + Common::String name = ""; + byte nameSize = stream->readByte(); + + if (nameSize) { + for (uint8 i = 0; i < nameSize; i++) { + name += stream->readByte(); + } + } + + stream->seek(startResPos); + + debug(3, "Found RIFF resource '%s' %d: %d @ 0x%08x", tag2str(tag), id, size, offset); + + ResourceMap &resMap = _types[tag]; + Resource &res = resMap[id]; + res.offset = offset; + res.size = size; + res.name = name; + } + + _stream = stream; + return true; +} + +Common::SeekableSubReadStreamEndian *RIFFArchive::getResource(uint32 tag, uint16 id) { + if (!_types.contains(tag)) + error("Archive does not contain '%s' %04x", tag2str(tag), id); + + const ResourceMap &resMap = _types[tag]; + + if (!resMap.contains(id)) + error("Archive does not contain '%s' %04x", tag2str(tag), id); + + const Resource &res = resMap[id]; + + // Adjust to skip the resource header + uint32 offset = res.offset + 12; + uint32 size = res.size - 4; + // Skip the Pascal string + _stream->seek(offset); + byte stringSize = _stream->readByte(); // 1 for this byte + + offset += stringSize + 1; + size -= stringSize + 1; + + // Align to nearest word boundary + if (offset & 1) { + offset++; + size--; + } + + return new Common::SeekableSubReadStreamEndian(_stream, offset, offset + size, true, DisposeAfterUse::NO); +} + +// RIFX Archive code + +bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOffset) { + close(); + + stream->seek(startOffset); + + uint32 headerTag = stream->readUint32BE(); + + if (headerTag == MKTAG('R', 'I', 'F', 'X')) + _isBigEndian = true; + else if (SWAP_BYTES_32(headerTag) == MKTAG('R', 'I', 'F', 'X')) + _isBigEndian = false; + else + return false; + + Common::SeekableSubReadStreamEndian subStream(stream, startOffset + 4, stream->size(), _isBigEndian, DisposeAfterUse::NO); + + subStream.readUint32(); // size + + uint32 rifxType = subStream.readUint32(); + + if (rifxType != MKTAG('M', 'V', '9', '3') && rifxType != MKTAG('A', 'P', 'P', 'L')) + return false; + + if (subStream.readUint32() != MKTAG('i', 'm', 'a', 'p')) + return false; + + subStream.readUint32(); // imap length + subStream.readUint32(); // unknown + uint32 mmapOffset = subStream.readUint32() - startOffset - 4; + + subStream.seek(mmapOffset); + + if (subStream.readUint32() != MKTAG('m', 'm', 'a', 'p')) + return false; + + subStream.readUint32(); // mmap length + subStream.readUint16(); // unknown + subStream.readUint16(); // unknown + subStream.readUint32(); // resCount + empty entries + uint32 resCount = subStream.readUint32(); + subStream.skip(8); // all 0xFF + subStream.readUint32(); // unknown + + Common::Array<Resource> resources; + + // Need to look for these two resources + const Resource *keyRes = 0; + const Resource *casRes = 0; + + for (uint32 i = 0; i < resCount; i++) { + uint32 tag = subStream.readUint32(); + uint32 size = subStream.readUint32(); + uint32 offset = subStream.readUint32(); + /*uint16 flags = */ subStream.readUint16(); + /*uint16 unk1 = */ subStream.readUint16(); + /*uint32 unk2 = */ subStream.readUint32(); + + debug(3, "Found RIFX resource index %d: '%s', %d @ 0x%08x", i, tag2str(tag), size, offset); + + Resource res; + res.offset = offset; + res.size = size; + resources.push_back(res); + + // APPL is a special case; it has an embedded "normal" archive + if (rifxType == MKTAG('A', 'P', 'P', 'L') && tag == MKTAG('F', 'i', 'l', 'e')) + return openStream(stream, offset); + + // Looking for two types here + if (tag == MKTAG('K', 'E', 'Y', '*')) + keyRes = &resources[resources.size() - 1]; + else if (tag == MKTAG('C', 'A', 'S', '*')) + casRes = &resources[resources.size() - 1]; + } + + // We need to have found the 'File' resource already + if (rifxType == MKTAG('A', 'P', 'P', 'L')) { + warning("No 'File' resource present in APPL archive"); + return false; + } + + // A KEY* must be present + if (!keyRes) { + warning("No 'KEY*' resource present"); + return false; + } + + // Parse the CAS*, if present + Common::Array<uint32> casEntries; + if (casRes) { + Common::SeekableSubReadStreamEndian casStream(stream, casRes->offset + 8, casRes->offset + 8 + casRes->size, _isBigEndian, DisposeAfterUse::NO); + casEntries.resize(casRes->size / 4); + + for (uint32 i = 0; i < casEntries.size(); i++) + casEntries[i] = casStream.readUint32(); + } + + // Parse the KEY* + Common::SeekableSubReadStreamEndian keyStream(stream, keyRes->offset + 8, keyRes->offset + 8 + keyRes->size, _isBigEndian, DisposeAfterUse::NO); + /*uint16 unk1 = */ keyStream.readUint16(); + /*uint16 unk2 = */ keyStream.readUint16(); + /*uint32 unk3 = */ keyStream.readUint32(); + uint32 keyCount = keyStream.readUint32(); + + for (uint32 i = 0; i < keyCount; i++) { + uint32 index = keyStream.readUint32(); + uint32 id = keyStream.readUint32(); + uint32 resTag = keyStream.readUint32(); + + // Handle CAS*/CASt nonsense + if (resTag == MKTAG('C', 'A', 'S', 't')) { + for (uint32 j = 0; j < casEntries.size(); j++) { + if (casEntries[j] == index) { + id += j + 1; + break; + } + } + } + + const Resource &res = resources[index]; + debug(3, "Found RIFX resource: '%s' 0x%04x, %d @ 0x%08x", tag2str(resTag), id, res.size, res.offset); + _types[resTag][id] = res; + } + + _stream = stream; + return true; +} + +} // End of namespace Director diff --git a/engines/director/resource.h b/engines/director/resource.h new file mode 100644 index 0000000000..fda8b79d82 --- /dev/null +++ b/engines/director/resource.h @@ -0,0 +1,110 @@ +/* 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 DIRECTOR_RESOURCE_H +#define DIRECTOR_RESOURCE_H + +#include "common/scummsys.h" +#include "common/endian.h" +#include "common/func.h" +#include "common/hashmap.h" +#include "common/file.h" +#include "common/str.h" +#include "common/substream.h" + +namespace Common { +class MacResManager; +} + +namespace Director { + +// Completely ripped off of Mohawk's Archive code + +class Archive { +public: + Archive(); + virtual ~Archive(); + + virtual bool openFile(const Common::String &fileName); + virtual bool openStream(Common::SeekableReadStream *stream, uint32 offset = 0) = 0; + virtual void close(); + + bool isOpen() const { return _stream != 0; } + + bool hasResource(uint32 tag, uint16 id) const; + bool hasResource(uint32 tag, const Common::String &resName) const; + virtual Common::SeekableSubReadStreamEndian *getResource(uint32 tag, uint16 id); + uint32 getOffset(uint32 tag, uint16 id) const; + uint16 findResourceID(uint32 tag, const Common::String &resName) const; + Common::String getName(uint32 tag, uint16 id) const; + + Common::Array<uint32> getResourceTypeList() const; + Common::Array<uint16> getResourceIDList(uint32 type) const; + bool _isBigEndian; + static uint32 convertTagToUppercase(uint32 tag); + +protected: + Common::SeekableReadStream *_stream; + struct Resource { + uint32 offset; + uint32 size; + Common::String name; + }; + typedef Common::HashMap<uint16, Resource> ResourceMap; + typedef Common::HashMap<uint32, ResourceMap> TypeMap; + TypeMap _types; +}; + +class MacArchive : public Archive { +public: + MacArchive(); + ~MacArchive(); + + void close(); + bool openFile(const Common::String &fileName); + bool openStream(Common::SeekableReadStream *stream, uint32 startOffset = 0); + Common::SeekableSubReadStreamEndian *getResource(uint32 tag, uint16 id); + +private: + Common::MacResManager *_resFork; +}; + +class RIFFArchive : public Archive { +public: + RIFFArchive() : Archive() {} + ~RIFFArchive() {} + + bool openStream(Common::SeekableReadStream *stream, uint32 startOffset = 0); + Common::SeekableSubReadStreamEndian *getResource(uint32 tag, uint16 id); +}; + +class RIFXArchive : public Archive { +public: + RIFXArchive() : Archive(){ _isBigEndian = true; } + ~RIFXArchive() {} + + bool openStream(Common::SeekableReadStream *stream, uint32 startOffset = 0); +}; + +} // End of namespace Director + +#endif diff --git a/engines/director/score.cpp b/engines/director/score.cpp new file mode 100644 index 0000000000..6587270641 --- /dev/null +++ b/engines/director/score.cpp @@ -0,0 +1,1617 @@ +/* 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 "director/score.h" +#include "common/stream.h" +#include "common/debug.h" +#include "common/file.h" +#include "common/archive.h" +#include "common/config-manager.h" +#include "common/unzip.h" + +#include "common/system.h" +#include "director/dib.h" +#include "director/resource.h" +#include "director/lingo/lingo.h" +#include "director/sound.h" + +#include "graphics/palette.h" +#include "common/events.h" +#include "engines/util.h" +#include "graphics/managed_surface.h" +#include "graphics/macgui/macwindowmanager.h" +#include "image/bmp.h" +#include "graphics/fontman.h" +#include "graphics/fonts/bdf.h" + +namespace Director { + +static byte defaultPalette[768] = { + 0, 0, 0, 17, 17, 17, 34, 34, 34, 68, 68, 68, 85, 85, 85, 119, + 119, 119, 136, 136, 136, 170, 170, 170, 187, 187, 187, 221, 221, 221, 238, 238, + 238, 0, 0, 17, 0, 0, 34, 0, 0, 68, 0, 0, 85, 0, 0, 119, + 0, 0, 136, 0, 0, 170, 0, 0, 187, 0, 0, 221, 0, 0, 238, 0, + 17, 0, 0, 34, 0, 0, 68, 0, 0, 85, 0, 0, 119, 0, 0, 136, + 0, 0, 170, 0, 0, 187, 0, 0, 221, 0, 0, 238, 0, 17, 0, 0, + 34, 0, 0, 68, 0, 0, 85, 0, 0, 119, 0, 0, 136, 0, 0, 170, + 0, 0, 187, 0, 0, 221, 0, 0, 238, 0, 0, 0, 0, 51, 0, 0, + 102, 0, 0, 153, 0, 0, 204, 0, 0, 255, 0, 51, 0, 0, 51, 51, + 0, 51, 102, 0, 51, 153, 0, 51, 204, 0, 51, 255, 0, 102, 0, 0, + 102, 51, 0, 102, 102, 0, 102, 153, 0, 102, 204, 0, 102, 255, 0, 153, + 0, 0, 153, 51, 0, 153, 102, 0, 153, 153, 0, 153, 204, 0, 153, 255, + 0, 204, 0, 0, 204, 51, 0, 204, 102, 0, 204, 153, 0, 204, 204, 0, + 204, 255, 0, 255, 0, 0, 255, 51, 0, 255, 102, 0, 255, 153, 0, 255, + 204, 0, 255, 255, 51, 0, 0, 51, 0, 51, 51, 0, 102, 51, 0, 153, + 51, 0, 204, 51, 0, 255, 51, 51, 0, 51, 51, 51, 51, 51, 102, 51, + 51, 153, 51, 51, 204, 51, 51, 255, 51, 102, 0, 51, 102, 51, 51, 102, + 102, 51, 102, 153, 51, 102, 204, 51, 102, 255, 51, 153, 0, 51, 153, 51, + 51, 153, 102, 51, 153, 153, 51, 153, 204, 51, 153, 255, 51, 204, 0, 51, + 204, 51, 51, 204, 102, 51, 204, 153, 51, 204, 204, 51, 204, 255, 51, 255, + 0, 51, 255, 51, 51, 255, 102, 51, 255, 153, 51, 255, 204, 51, 255, 255, + 102, 0, 0, 102, 0, 51, 102, 0, 102, 102, 0, 153, 102, 0, 204, 102, + 0, 255, 102, 51, 0, 102, 51, 51, 102, 51, 102, 102, 51, 153, 102, 51, + 204, 102, 51, 255, 102, 102, 0, 102, 102, 51, 102, 102, 102, 102, 102, 153, + 102, 102, 204, 102, 102, 255, 102, 153, 0, 102, 153, 51, 102, 153, 102, 102, + 153, 153, 102, 153, 204, 102, 153, 255, 102, 204, 0, 102, 204, 51, 102, 204, + 102, 102, 204, 153, 102, 204, 204, 102, 204, 255, 102, 255, 0, 102, 255, 51, + 102, 255, 102, 102, 255, 153, 102, 255, 204, 102, 255, 255, 153, 0, 0, 153, + 0, 51, 153, 0, 102, 153, 0, 153, 153, 0, 204, 153, 0, 255, 153, 51, + 0, 153, 51, 51, 153, 51, 102, 153, 51, 153, 153, 51, 204, 153, 51, 255, + 153, 102, 0, 153, 102, 51, 153, 102, 102, 153, 102, 153, 153, 102, 204, 153, + 102, 255, 153, 153, 0, 153, 153, 51, 153, 153, 102, 153, 153, 153, 153, 153, + 204, 153, 153, 255, 153, 204, 0, 153, 204, 51, 153, 204, 102, 153, 204, 153, + 153, 204, 204, 153, 204, 255, 153, 255, 0, 153, 255, 51, 153, 255, 102, 153, + 255, 153, 153, 255, 204, 153, 255, 255, 204, 0, 0, 204, 0, 51, 204, 0, + 102, 204, 0, 153, 204, 0, 204, 204, 0, 255, 204, 51, 0, 204, 51, 51, + 204, 51, 102, 204, 51, 153, 204, 51, 204, 204, 51, 255, 204, 102, 0, 204, + 102, 51, 204, 102, 102, 204, 102, 153, 204, 102, 204, 204, 102, 255, 204, 153, + 0, 204, 153, 51, 204, 153, 102, 204, 153, 153, 204, 153, 204, 204, 153, 255, + 204, 204, 0, 204, 204, 51, 204, 204, 102, 204, 204, 153, 204, 204, 204, 204, + 204, 255, 204, 255, 0, 204, 255, 51, 204, 255, 102, 204, 255, 153, 204, 255, + 204, 204, 255, 255, 255, 0, 0, 255, 0, 51, 255, 0, 102, 255, 0, 153, + 255, 0, 204, 255, 0, 255, 255, 51, 0, 255, 51, 51, 255, 51, 102, 255, + 51, 153, 255, 51, 204, 255, 51, 255, 255, 102, 0, 255, 102, 51, 255, 102, + 102, 255, 102, 153, 255, 102, 204, 255, 102, 255, 255, 153, 0, 255, 153, 51, + 255, 153, 102, 255, 153, 153, 255, 153, 204, 255, 153, 255, 255, 204, 0, 255, + 204, 51, 255, 204, 102, 255, 204, 153, 255, 204, 204, 255, 204, 255, 255, 255, + 0, 255, 255, 51, 255, 255, 102, 255, 255, 153, 255, 255, 204, 255, 255, 255 }; + +Score::Score(DirectorEngine *vm) { + _vm = vm; + _surface = new Graphics::ManagedSurface; + _trailSurface = new Graphics::ManagedSurface; + _movieArchive = _vm->getMainArchive(); + _lingo = _vm->getLingo(); + _soundManager = _vm->getSoundManager(); + _lingo->processEvent(kEventPrepareMovie, 0); + _movieScriptCount = 0; + _labels = NULL; + + if (_movieArchive->hasResource(MKTAG('M','C','N','M'), 0)) { + _macName = _movieArchive->getName(MKTAG('M','C','N','M'), 0).c_str(); + } + + if (_movieArchive->hasResource(MKTAG('V','W','L','B'), 1024)) { + loadLabels(*_movieArchive->getResource(MKTAG('V','W','L','B'), 1024)); + } +} + +void Score::loadArchive() { + Common::Array<uint16> clutList = _movieArchive->getResourceIDList(MKTAG('C','L','U','T')); + + if (clutList.size() > 1) + warning("More than one palette was found (%d)", clutList.size()); + + if (clutList.size() == 0) { + warning("CLUT resource not found, using default Mac palette"); + g_system->getPaletteManager()->setPalette(defaultPalette, 0, 256); + _vm->setPalette(defaultPalette, 256); + } else { + Common::SeekableSubReadStreamEndian *pal = _movieArchive->getResource(MKTAG('C', 'L', 'U', 'T'), clutList[0]); + + loadPalette(*pal); + g_system->getPaletteManager()->setPalette(_vm->getPalette(), 0, _vm->getPaletteColorCount()); + } + + assert(_movieArchive->hasResource(MKTAG('V','W','S','C'), 1024)); + assert(_movieArchive->hasResource(MKTAG('V','W','C','F'), 1024)); + + loadFrames(*_movieArchive->getResource(MKTAG('V','W','S','C'), 1024)); + loadConfig(*_movieArchive->getResource(MKTAG('V','W','C','F'), 1024)); + + if (_vm->getVersion() < 4) { + assert(_movieArchive->hasResource(MKTAG('V','W','C','R'), 1024)); + loadCastData(*_movieArchive->getResource(MKTAG('V','W','C','R'), 1024)); + } + + if (_movieArchive->hasResource(MKTAG('V','W','A','C'), 1024)) { + loadActions(*_movieArchive->getResource(MKTAG('V','W','A','C'), 1024)); + } + + if (_movieArchive->hasResource(MKTAG('V','W','F','I'), 1024)) { + loadFileInfo(*_movieArchive->getResource(MKTAG('V','W','F','I'), 1024)); + } + + if (_movieArchive->hasResource(MKTAG('V','W','F','M'), 1024)) { + loadFontMap(*_movieArchive->getResource(MKTAG('V','W','F','M'), 1024)); + } + + Common::Array<uint16> vwci = _movieArchive->getResourceIDList(MKTAG('V','W','C','I')); + + if (vwci.size() > 0) { + Common::Array<uint16>::iterator iterator; + + for (iterator = vwci.begin(); iterator != vwci.end(); ++iterator) + loadCastInfo(*_movieArchive->getResource(MKTAG('V','W','C','I'), *iterator), *iterator); + } + + Common::Array<uint16> stxt = _movieArchive->getResourceIDList(MKTAG('S','T','X','T')); + + if (stxt.size() > 0) { + Common::Array<uint16>::iterator iterator; + + for (iterator = stxt.begin(); iterator != stxt.end(); ++iterator) { + loadScriptText(*_movieArchive->getResource(MKTAG('S','T','X','T'), *iterator)); + } + } +} + +Score::~Score() { + if (_surface) + _surface->free(); + + if (_trailSurface) + _trailSurface->free(); + + delete _surface; + delete _trailSurface; + + if (_movieArchive) + _movieArchive->close(); + + delete _surface; + delete _trailSurface; + + delete _font; + delete _movieArchive; + + delete _labels; +} + +void Score::loadPalette(Common::SeekableSubReadStreamEndian &stream) { + uint16 steps = stream.size() / 6; + uint16 index = (steps * 3) - 1; + uint16 _paletteColorCount = steps; + byte *_palette = new byte[index]; + + for (uint8 i = 0; i < steps; i++) { + _palette[index - 2] = stream.readByte(); + stream.readByte(); + + _palette[index - 1] = stream.readByte(); + stream.readByte(); + + _palette[index] = stream.readByte(); + stream.readByte(); + index -= 3; + } + _vm->setPalette(_palette, _paletteColorCount); +} + +void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) { + uint32 size = stream.readUint32(); + size -= 4; + + if (_vm->getVersion() > 3) { + stream.skip(16); + //Unknown, some bytes - constant (refer to contuinity). + } + + uint16 channelSize; + uint16 channelOffset; + + Frame *initial = new Frame(_vm); + _frames.push_back(initial); + + while (size != 0) { + uint16 frameSize = stream.readUint16(); + size -= frameSize; + frameSize -= 2; + Frame *frame = new Frame(*_frames.back()); + + while (frameSize != 0) { + if (_vm->getVersion() < 4) { + channelSize = stream.readByte() * 2; + channelOffset = stream.readByte() * 2; + frameSize -= channelSize + 2; + } else { + channelSize = stream.readByte(); + channelOffset = stream.readByte(); + frameSize -= channelSize + 4; + } + frame->readChannel(stream, channelOffset, channelSize); + + } + + _frames.push_back(frame); + } + + //remove initial frame + _frames.remove_at(0); +} + +void Score::loadConfig(Common::SeekableSubReadStreamEndian &stream) { + /*uint16 unk1 = */ stream.readUint16(); + /*ver1 = */ stream.readUint16(); + _movieRect = Score::readRect(stream); + + _castArrayStart = stream.readUint16(); + _castArrayEnd = stream.readUint16(); + _currentFrameRate = stream.readByte(); + stream.skip(9); + _stageColor = stream.readUint16(); +} + +void Score::readVersion(uint32 rid) { + _versionMinor = rid & 0xffff; + _versionMajor = rid >> 16; + + debug("Version: %d.%d", _versionMajor, _versionMinor); +} + +void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream) { + for (uint16 id = _castArrayStart; id <= _castArrayEnd; id++) { + byte size = stream.readByte(); + if (size == 0) + continue; + + uint8 castType = stream.readByte(); + + switch (castType) { + case kCastBitmap: + _casts[id] = new BitmapCast(stream); + _casts[id]->type = kCastBitmap; + break; + case kCastText: + _casts[id] = new TextCast(stream); + _casts[id]->type = kCastText; + break; + case kCastShape: + _casts[id] = new ShapeCast(stream); + _casts[id]->type = kCastShape; + break; + case kCastButton: + _casts[id] = new ButtonCast(stream); + _casts[id]->type = kCastButton; + break; + default: + warning("Unhandled cast type: %d", castType); + stream.skip(size - 1); + break; + } + } + + //Set cast pointers to sprites + for (uint16 i = 0; i < _frames.size(); i++) { + for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) { + byte castId = _frames[i]->_sprites[j]->_castId; + + if (_casts.contains(castId)) + _frames[i]->_sprites[j]->_cast = _casts.find(castId)->_value; + } + } +} + +void Score::loadLabels(Common::SeekableSubReadStreamEndian &stream) { + _labels = new Common::SortedArray<Label *>(compareLabels); + uint16 count = stream.readUint16() + 1; + uint16 offset = count * 4 + 2; + + uint16 frame = stream.readUint16(); + uint16 stringPos = stream.readUint16() + offset; + + for (uint16 i = 0; i < count; i++) { + uint16 nextFrame = stream.readUint16(); + uint16 nextStringPos = stream.readUint16() + offset; + uint16 streamPos = stream.pos(); + + stream.seek(stringPos); + Common::String label; + for (uint16 j = stringPos; j < nextStringPos; j++) { + label += stream.readByte(); + } + _labels->insert(new Label(label, frame)); + stream.seek(streamPos); + + frame = nextFrame; + stringPos = nextStringPos; + } + + Common::SortedArray<Label *>::iterator j; + + for (j = _labels->begin(); j != _labels->end(); ++j) { + debug("Frame %d, Label %s", (*j)->number, (*j)->name.c_str()); + } +} + +int Score::compareLabels(const void *a, const void *b) { + return ((const Label *)a)->number - ((const Label *)b)->number; +} + +void Score::loadActions(Common::SeekableSubReadStreamEndian &stream) { + uint16 count = stream.readUint16() + 1; + uint16 offset = count * 4 + 2; + + byte id = stream.readByte(); + /*byte subId = */ stream.readByte(); //I couldn't find how it used in continuity (except print). Frame actionId = 1 byte. + uint16 stringPos = stream.readUint16() + offset; + + for (uint16 i = 0; i < count; i++) { + uint16 nextId = stream.readByte(); + /*byte subId = */ stream.readByte(); + uint16 nextStringPos = stream.readUint16() + offset; + uint16 streamPos = stream.pos(); + + stream.seek(stringPos); + + for (uint16 j = stringPos; j < nextStringPos; j++) { + byte ch = stream.readByte(); + if (ch == 0x0d) { + ch = '\n'; + } + _actions[id] += ch; + } + + stream.seek(streamPos); + + id = nextId; + stringPos = nextStringPos; + + if (stringPos == stream.size()) + break; + } + + Common::HashMap<uint16, Common::String>::iterator j; + + if (ConfMan.getBool("dump_scripts")) + for (j = _actions.begin(); j != _actions.end(); ++j) { + if (!j->_value.empty()) + dumpScript(j->_value.c_str(), kFrameScript, j->_key); + } + + for (j = _actions.begin(); j != _actions.end(); ++j) + if (!j->_value.empty()) + _lingo->addCode(j->_value.c_str(), kFrameScript, j->_key); +} + +void Score::loadScriptText(Common::SeekableSubReadStreamEndian &stream) { + /*uint32 unk1 = */ stream.readUint32(); + uint32 strLen = stream.readUint32(); + /*uin32 dataLen = */ stream.readUint32(); + Common::String script; + + for (uint32 i = 0; i < strLen; i++) { + byte ch = stream.readByte(); + + if (ch == 0x0d) { + //in old Mac systems \r was the code for end-of-line instead. + ch = '\n'; + } + script += ch; + } + + if (!script.empty() && ConfMan.getBool("dump_scripts")) + dumpScript(script.c_str(), kMovieScript, _movieScriptCount); + + if (!script.empty()) + _lingo->addCode(script.c_str(), kMovieScript, _movieScriptCount); + + _movieScriptCount++; +} + +void Score::setStartToLabel(Common::String label) { + if (!_labels) { + warning("setStartToLabel: No labels set"); + return; + } + + Common::SortedArray<Label *>::iterator i; + + for (i = _labels->begin(); i != _labels->end(); ++i) { + if ((*i)->name == label) { + _currentFrame = (*i)->number; + return; + } + } + warning("Label %s not found", label.c_str()); +} + +void Score::dumpScript(const char *script, ScriptType type, uint16 id) { + Common::DumpFile out; + Common::String typeName; + char buf[256]; + + switch (type) { + case kFrameScript: + typeName = "frame"; + break; + case kMovieScript: + typeName = "movie"; + break; + case kSpriteScript: + typeName = "sprite"; + break; + } + + sprintf(buf, "./dumps/%s-%s-%d.txt", _macName.c_str(), typeName.c_str(), id); + + if (!out.open(buf)) { + warning("Can not open dump file %s", buf); + return; + } + + out.write(script, strlen(script)); + + out.flush(); + out.close(); +} + +void Score::loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id) { + uint32 entryType = 0; + Common::Array<Common::String> castStrings = loadStrings(stream, entryType); + CastInfo *ci = new CastInfo(); + + ci->script = castStrings[0]; + + if (!ci->script.empty() && ConfMan.getBool("dump_scripts")) + dumpScript(ci->script.c_str(), kSpriteScript, id); + + if (!ci->script.empty()) + _lingo->addCode(ci->script.c_str(), kSpriteScript, id); + + ci->name = getString(castStrings[1]); + ci->directory = getString(castStrings[2]); + ci->fileName = getString(castStrings[3]); + ci->type = castStrings[4]; + + _castsInfo[id] = ci; +} + +void Score::gotoloop() { + //This command has the playback head contonuously return to the first marker to to the left and then loop back. + //If no marker are to the left of the playback head, the playback head continues to the right. + Common::SortedArray<Label *>::iterator i; + + for (i = _labels->begin(); i != _labels->end(); ++i) { + if ((*i)->name == _currentLabel) { + _currentFrame = (*i)->number; + return; + } + } +} + +void Score::gotonext() { + Common::SortedArray<Label *>::iterator i; + + for (i = _labels->begin(); i != _labels->end(); ++i) { + if ((*i)->name == _currentLabel) { + if (i != _labels->end()) { + //return to the first marker to to the right + ++i; + _currentFrame = (*i)->number; + return; + } else { + //if no markers are to the right of the playback head, + //the playback head goes to the first marker to the left + _currentFrame = (*i)->number; + return; + } + } + } + //If there are not markers to the left, + //the playback head goes to frame 1, (Director frame array start from 1, engine from 0) + _currentFrame = 0; +} + +void Score::gotoprevious() { + //One label + if (_labels->begin() == _labels->end()) { + _currentFrame = (*_labels->begin())->number; + return; + } + + Common::SortedArray<Label *>::iterator previous = _labels->begin(); + Common::SortedArray<Label *>::iterator i = previous++; + + for (i = _labels->begin(); i != _labels->end(); ++i, ++previous) { + if ((*i)->name == _currentLabel) { + _currentFrame = (*previous)->number; + return; + } else { + _currentFrame = (*i)->number; + return; + } + } + _currentFrame = 0; +} + +Common::String Score::getString(Common::String str) { + if (str.size() == 0) { + return str; + } + + uint8 f = static_cast<uint8>(str.firstChar()); + + if (f == 0) { + return ""; + } + + str.deleteChar(0); + + if (str.lastChar() == '\x00') { + str.deleteLastChar(); + } + + return str; +} + +void Score::loadFileInfo(Common::SeekableSubReadStreamEndian &stream) { + Common::Array<Common::String> fileInfoStrings = loadStrings(stream, _flags); + _script = fileInfoStrings[0]; + + if (!_script.empty() && ConfMan.getBool("dump_scripts")) + dumpScript(_script.c_str(), kMovieScript, _movieScriptCount); + + if (!_script.empty()) + _lingo->addCode(_script.c_str(), kMovieScript, _movieScriptCount); + + _movieScriptCount++; + _changedBy = fileInfoStrings[1]; + _createdBy = fileInfoStrings[2]; + _directory = fileInfoStrings[3]; +} + +Common::Array<Common::String> Score::loadStrings(Common::SeekableSubReadStreamEndian &stream, uint32 &entryType, bool hasHeader) { + Common::Array<Common::String> strings; + uint32 offset = 0; + + if (hasHeader) { + offset = stream.readUint32(); + /*uint32 unk1 = */ stream.readUint32(); + /*uint32 unk2 = */ stream.readUint32(); + entryType = stream.readUint32(); + stream.seek(offset); + } + + uint16 count = stream.readUint16(); + offset += (count + 1) * 4 + 2; //positions info + uint16 count + uint32 startPos = stream.readUint32() + offset; + + for (uint16 i = 0; i < count; i++) { + Common::String entryString; + uint32 nextPos = stream.readUint32() + offset; + uint32 streamPos = stream.pos(); + + stream.seek(startPos); + + while (startPos != nextPos) { + entryString += stream.readByte(); + ++startPos; + } + + strings.push_back(entryString); + + stream.seek(streamPos); + startPos = nextPos; + } + + return strings; +} + +void Score::loadFontMap(Common::SeekableSubReadStreamEndian &stream) { + uint16 count = stream.readUint16(); + uint32 offset = (count * 2) + 2; + uint16 currentRawPosition = offset; + + for (uint16 i = 0; i < count; i++) { + uint16 id = stream.readUint16(); + uint32 positionInfo = stream.pos(); + + stream.seek(currentRawPosition); + + uint16 size = stream.readByte(); + Common::String font; + + for (uint16 k = 0; k < size; k++) { + font += stream.readByte(); + } + + _fontMap[id] = font; + debug(3, "Fontmap. ID %d Font %s", id, font.c_str()); + currentRawPosition = stream.pos(); + stream.seek(positionInfo); + } +} + +BitmapCast::BitmapCast(Common::SeekableSubReadStreamEndian &stream) { + /*byte flags = */ stream.readByte(); + uint16 someFlaggyThing = stream.readUint16(); + initialRect = Score::readRect(stream); + boundingRect = Score::readRect(stream); + regY = stream.readUint16(); + regX = stream.readUint16(); + + if (someFlaggyThing & 0x8000) { + /*uint16 unk1 =*/ stream.readUint16(); + /*uint16 unk2 =*/ stream.readUint16(); + } + modified = 0; +} + +TextCast::TextCast(Common::SeekableSubReadStreamEndian &stream) { + /*byte flags =*/ stream.readByte(); + borderSize = static_cast<SizeType>(stream.readByte()); + gutterSize = static_cast<SizeType>(stream.readByte()); + boxShadow = static_cast<SizeType>(stream.readByte()); + textType = static_cast<TextType>(stream.readByte()); + textAlign = static_cast<TextAlignType>(stream.readUint16()); + stream.skip(6); //palinfo + //for now, just supposition + fontId = stream.readUint32(); + + initialRect = Score::readRect(stream); + textShadow = static_cast<SizeType>(stream.readByte()); + byte flags = stream.readByte(); + if (flags & 0x1) + textFlags.push_back(kTextFlagEditable); + if (flags & 0x2) + textFlags.push_back(kTextFlagAutoTab); + if (flags & 0x4) + textFlags.push_back(kTextFlagDoNotWrap); + //again supposition + fontSize = stream.readUint16(); + modified = 0; +} + +ShapeCast::ShapeCast(Common::SeekableSubReadStreamEndian &stream) { + /*byte flags = */ stream.readByte(); + /*unk1 = */ stream.readByte(); + shapeType = static_cast<ShapeType>(stream.readByte()); + initialRect = Score::readRect(stream); + pattern = stream.readUint16BE(); + fgCol = stream.readByte(); + bgCol = stream.readByte(); + fillType = stream.readByte(); + lineThickness = stream.readByte(); + lineDirection = stream.readByte(); + modified = 0; +} + +Common::Rect Score::readRect(Common::SeekableSubReadStreamEndian &stream) { + Common::Rect *rect = new Common::Rect(); + rect->top = stream.readUint16(); + rect->left = stream.readUint16(); + rect->bottom = stream.readUint16(); + rect->right = stream.readUint16(); + + return *rect; +} + +void Score::startLoop() { + initGraphics(_movieRect.width(), _movieRect.height(), true); + + _surface->create(_movieRect.width(), _movieRect.height()); + _trailSurface->create(_movieRect.width(), _movieRect.height()); + + if (_stageColor == 0) + _trailSurface->clear(_vm->getPaletteColorCount() - 1); + else + _trailSurface->clear(_stageColor); + + _currentFrame = 0; + _stopPlay = false; + _nextFrameTime = 0; + + _lingo->processEvent(kEventStartMovie, 0); + _frames[_currentFrame]->prepareFrame(this); + + while (!_stopPlay && _currentFrame < _frames.size() - 2) { + update(); + processEvents(); + + g_system->updateScreen(); + g_system->delayMillis(10); + } +} + +void Score::update() { + if (g_system->getMillis() < _nextFrameTime) + return; + + _surface->clear(); + _surface->copyFrom(*_trailSurface); + + //Enter and exit from previous frame (Director 4) + _lingo->processEvent(kEventEnterFrame, _currentFrame); + _lingo->processEvent(kEventExitFrame, _currentFrame); + //TODO Director 6 - another order + + + //TODO Director 6 step: send beginSprite event to any sprites whose span begin in the upcoming frame + //for (uint16 i = 0; i < CHANNEL_COUNT; i++) { + // if (_frames[_currentFrame]->_sprites[i]->_enabled) + // _lingo->processEvent(kEventBeginSprite, i); + //} + + //TODO Director 6 step: send prepareFrame event to all sprites and the script channel in upcoming frame + //_lingo->processEvent(kEventPrepareFrame, _currentFrame); + _currentFrame++; + + Common::SortedArray<Label *>::iterator i; + for (i = _labels->begin(); i != _labels->end(); ++i) { + if ((*i)->number == _currentFrame) { + _currentLabel = (*i)->name; + } + } + + _frames[_currentFrame]->prepareFrame(this); + //Stage is drawn between the prepareFrame and enterFrame events (Lingo in a Nutshell) + + byte tempo = _frames[_currentFrame]->_tempo; + + if (tempo) { + if (tempo > 161) { + //Delay + _nextFrameTime = g_system->getMillis() + (256 - tempo) * 1000; + + return; + } else if (tempo <= 60) { + //FPS + _nextFrameTime = g_system->getMillis() + (float)tempo / 60 * 1000; + _currentFrameRate = tempo; + } else if (tempo >= 136) { + //TODO Wait for channel tempo - 135 + } else if (tempo == 128) { + //TODO Wait for Click/Key + } else if (tempo == 135) { + //Wait for sound channel 1 + while (_soundManager->isChannelActive(1)) { + processEvents(); + g_system->delayMillis(10); + } + } else if (tempo == 134) { + //Wait for sound channel 2 + while (_soundManager->isChannelActive(2)) { + processEvents(); + g_system->delayMillis(10); + } + } + } + _nextFrameTime = g_system->getMillis() + (float)_currentFrameRate / 60 * 1000; +} + +void Score::processEvents() { + if (_currentFrame > 0) + _lingo->processEvent(kEventIdle, _currentFrame - 1); + + Common::Event event; + + while (g_system->getEventManager()->pollEvent(event)) { + if (event.type == Common::EVENT_QUIT) + _stopPlay = true; + + if (event.type == Common::EVENT_LBUTTONDOWN) { + Common::Point pos = g_system->getEventManager()->getMousePos(); + + //TODO there is dont send frame id + _lingo->processEvent(kEventMouseDown, _frames[_currentFrame]->getSpriteIDFromPos(pos)); + } + + if (event.type == Common::EVENT_LBUTTONUP) { + Common::Point pos = g_system->getEventManager()->getMousePos(); + + _lingo->processEvent(kEventMouseUp, _frames[_currentFrame]->getSpriteIDFromPos(pos)); + } + } +} + +Sprite *Score::getSpriteById(uint16 id) { + if (_frames[_currentFrame]->_sprites[id]) { + return _frames[_currentFrame]->_sprites[id]; + } else { + warning("Sprite on frame %d width id %d not found", _currentFrame, id); + return nullptr; + } +} + +Frame::Frame(DirectorEngine *vm) { + _vm = vm; + _transDuration = 0; + _transType = kTransNone; + _transArea = 0; + _transChunkSize = 0; + _tempo = 0; + + _sound1 = 0; + _sound2 = 0; + _soundType1 = 0; + _soundType2 = 0; + + _actionId = 0; + _skipFrameFlag = 0; + _blend = 0; + + _sprites.resize(CHANNEL_COUNT); + + for (uint16 i = 0; i < _sprites.size(); i++) { + Sprite *sp = new Sprite(); + _sprites[i] = sp; + } +} + +Frame::Frame(const Frame &frame) { + _vm = frame._vm; + _actionId = frame._actionId; + _transArea = frame._transArea; + _transDuration = frame._transDuration; + _transType = frame._transType; + _transChunkSize = frame._transChunkSize; + _tempo = frame._tempo; + _sound1 = frame._sound1; + _sound2 = frame._sound2; + _soundType1 = frame._soundType1; + _soundType2 = frame._soundType2; + _skipFrameFlag = frame._skipFrameFlag; + _blend = frame._blend; + _palette = new PaletteInfo(); + + _sprites.resize(CHANNEL_COUNT); + + for (uint16 i = 0; i < CHANNEL_COUNT; i++) { + _sprites[i] = new Sprite(*frame._sprites[i]); + } +} + +Frame::~Frame() { + delete[] &_sprites; + delete[] &_drawRects; + delete _palette; +} + +void Frame::readChannel(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size) { + if (offset >= 32) { + if (size <= 16) + readSprite(stream, offset, size); + else { + //read > 1 sprites channel + while (size > 16) { + byte spritePosition = (offset - 32) / 16; + uint16 nextStart = (spritePosition + 1) * 16 + 32; + uint16 needSize = nextStart - offset; + readSprite(stream, offset, needSize); + offset += needSize; + size -= needSize; + } + readSprite(stream, offset, size); + } + } else { + readMainChannels(stream, offset, size); + } +} + +void Frame::readMainChannels(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size) { + uint16 finishPosition = offset + size; + + while (offset < finishPosition) { + switch(offset) { + case kScriptIdPosition: + _actionId = stream.readByte(); + offset++; + break; + case kSoundType1Position: + _soundType1 = stream.readByte(); + offset++; + break; + case kTransFlagsPosition: { + uint8 transFlags = stream.readByte(); + if (transFlags & 0x80) + _transArea = 1; + else + _transArea = 0; + _transDuration = transFlags & 0x7f; + offset++; + } + break; + case kTransChunkSizePosition: + _transChunkSize = stream.readByte(); + offset++; + break; + case kTempoPosition: + _tempo = stream.readByte(); + offset++; + break; + case kTransTypePosition: + _transType = static_cast<TransitionType>(stream.readByte()); + offset++; + break; + case kSound1Position: + _sound1 = stream.readUint16(); + offset+=2; + break; + case kSkipFrameFlagsPosition: + _skipFrameFlag = stream.readByte(); + offset++; + break; + case kBlendPosition: + _blend = stream.readByte(); + offset++; + break; + case kSound2Position: + _sound2 = stream.readUint16(); + offset += 2; + break; + case kSound2TypePosition: + _soundType2 = stream.readByte(); + offset += 1; + break; + case kPaletePosition: + if (stream.readUint16()) + readPaletteInfo(stream); + offset += 16; + default: + offset++; + stream.readByte(); + debug("Field Position %d, Finish Position %d", offset, finishPosition); + break; + } + } +} + +void Frame::readPaletteInfo(Common::SeekableSubReadStreamEndian &stream) { + _palette->firstColor = stream.readByte(); + _palette->lastColor = stream.readByte(); + _palette->flags = stream.readByte(); + _palette->speed = stream.readByte(); + _palette->frameCount = stream.readUint16(); + stream.skip(8); //unknown +} + +void Frame::readSprite(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size) { + uint16 spritePosition = (offset - 32) / 16; + uint16 spriteStart = spritePosition * 16 + 32; + + uint16 fieldPosition = offset - spriteStart; + uint16 finishPosition = fieldPosition + size; + + Sprite &sprite = *_sprites[spritePosition]; + + while (fieldPosition < finishPosition) { + switch (fieldPosition) { + case kSpritePositionUnk1: + /*byte x1 = */ stream.readByte(); + fieldPosition++; + break; + case kSpritePositionEnabled: + sprite._enabled = (stream.readByte() != 0); + fieldPosition++; + break; + case kSpritePositionUnk2: + /*byte x2 = */ stream.readUint16(); + fieldPosition += 2; + break; + case kSpritePositionFlags: + sprite._flags = stream.readUint16(); + sprite._ink = static_cast<InkType>(sprite._flags & 0x3f); + + if (sprite._flags & 0x40) + sprite._trails = 1; + else + sprite._trails = 0; + + fieldPosition += 2; + break; + case kSpritePositionCastId: + sprite._castId = stream.readUint16(); + fieldPosition += 2; + break; + case kSpritePositionY: + sprite._startPoint.y = stream.readUint16(); + fieldPosition += 2; + break; + case kSpritePositionX: + sprite._startPoint.x = stream.readUint16(); + fieldPosition += 2; + break; + case kSpritePositionWidth: + sprite._width = stream.readUint16(); + fieldPosition += 2; + break; + case kSpritePositionHeight: + sprite._height = stream.readUint16(); + fieldPosition += 2; + break; + default: + //end cycle, go to next sprite channel + readSprite(stream, spriteStart + 16, finishPosition - fieldPosition); + fieldPosition = finishPosition; + break; + } + } +} + +void Frame::prepareFrame(Score *score) { + renderSprites(*score->_surface, false); + renderSprites(*score->_trailSurface, true); + + if (_transType != 0) + //TODO Handle changing area case + playTransition(score); + + if (_sound1 != 0 || _sound2 != 0) { + playSoundChannel(); + } + + g_system->copyRectToScreen(score->_surface->getPixels(), score->_surface->pitch, 0, 0, score->_surface->getBounds().width(), score->_surface->getBounds().height()); +} + +void Frame::playSoundChannel() { + debug(0, "Sound2 %d", _sound2); + debug(0, "Sound1 %d", _sound1); +} + +void Frame::playTransition(Score *score) { + uint16 duration = _transDuration * 250; // _transDuration in 1/4 of sec + duration = (duration == 0 ? 250 : duration); // director support transition duration = 0, but animation play like value = 1, idk. + + if (_transChunkSize == 0) + _transChunkSize = 1; //equal 1 step + + uint16 stepDuration = duration / _transChunkSize; + uint16 steps = duration / stepDuration; + + switch (_transType) { + case kTransCoverDown: + { + uint16 stepSize = score->_movieRect.height() / steps; + Common::Rect r = score->_movieRect; + + for (uint16 i = 1; i < steps; i++) { + r.setHeight(stepSize * i); + + g_system->delayMillis(stepDuration); + score->processEvents(); + + g_system->copyRectToScreen(score->_surface->getPixels(), score->_surface->pitch, 0, 0, r.width(), r.height()); + g_system->updateScreen(); + } + } + break; + case kTransCoverUp: + { + uint16 stepSize = score->_movieRect.height() / steps; + Common::Rect r = score->_movieRect; + + for (uint16 i = 1; i < steps; i++) { + r.setHeight(stepSize * i); + + g_system->delayMillis(stepDuration); + score->processEvents(); + + g_system->copyRectToScreen(score->_surface->getPixels(), score->_surface->pitch, 0, score->_movieRect.height() - stepSize * i, r.width(), r.height()); + g_system->updateScreen(); + } + } + break; + case kTransCoverRight: { + uint16 stepSize = score->_movieRect.width() / steps; + Common::Rect r = score->_movieRect; + + for (uint16 i = 1; i < steps; i++) { + r.setWidth(stepSize * i); + + g_system->delayMillis(stepDuration); + score->processEvents(); + + g_system->copyRectToScreen(score->_surface->getPixels(), score->_surface->pitch, 0, 0, r.width(), r.height()); + g_system->updateScreen(); + } + } + break; + case kTransCoverLeft: { + uint16 stepSize = score->_movieRect.width() / steps; + Common::Rect r = score->_movieRect; + + for (uint16 i = 1; i < steps; i++) { + r.setWidth(stepSize * i); + + g_system->delayMillis(stepDuration); + score->processEvents(); + + g_system->copyRectToScreen(score->_surface->getPixels(), score->_surface->pitch, score->_movieRect.width() - stepSize * i, 0, r.width(), r.height()); + g_system->updateScreen(); + } + } + break; + case kTransCoverUpLeft: { + uint16 stepSize = score->_movieRect.width() / steps; + Common::Rect r = score->_movieRect; + + for (uint16 i = 1; i < steps; i++) { + r.setWidth(stepSize * i); + r.setHeight(stepSize * i); + + g_system->delayMillis(stepDuration); + score->processEvents(); + + g_system->copyRectToScreen(score->_surface->getPixels(), score->_surface->pitch, score->_movieRect.width() - stepSize * i, score->_movieRect.height() - stepSize * i, r.width(), r.height()); + g_system->updateScreen(); + } + } + break; + case kTransCoverUpRight: { + uint16 stepSize = score->_movieRect.width() / steps; + Common::Rect r = score->_movieRect; + + for (uint16 i = 1; i < steps; i++) { + r.setWidth(stepSize * i); + r.setHeight(stepSize * i); + + g_system->delayMillis(stepDuration); + score->processEvents(); + + g_system->copyRectToScreen(score->_surface->getPixels(), score->_surface->pitch, 0, score->_movieRect.height() - stepSize * i, r.width(), r.height()); + g_system->updateScreen(); + } + } + break; + case kTransCoverDownLeft: { + uint16 stepSize = score->_movieRect.width() / steps; + Common::Rect r = score->_movieRect; + + for (uint16 i = 1; i < steps; i++) { + r.setWidth(stepSize * i); + r.setHeight(stepSize * i); + + g_system->delayMillis(stepDuration); + score->processEvents(); + + g_system->copyRectToScreen(score->_surface->getPixels(), score->_surface->pitch, score->_movieRect.width() - stepSize * i, 0, r.width(), r.height()); + g_system->updateScreen(); + } + } + break; + case kTransCoverDownRight: { + uint16 stepSize = score->_movieRect.width() / steps; + Common::Rect r = score->_movieRect; + + for (uint16 i = 1; i < steps; i++) { + r.setWidth(stepSize * i); + r.setHeight(stepSize * i); + + g_system->delayMillis(stepDuration); + score->processEvents(); + + g_system->copyRectToScreen(score->_surface->getPixels(), score->_surface->pitch, 0, 0, r.width(), r.height()); + g_system->updateScreen(); + } + } + break; + default: + warning("Unhandled transition type %d %d %d", _transType, duration, _transChunkSize); + break; + + } +} + +void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) { + for (uint16 i = 0; i < CHANNEL_COUNT; i++) { + if (_sprites[i]->_enabled) { + if ((_sprites[i]->_trails == 0 && renderTrail) || (_sprites[i]->_trails == 1 && !renderTrail)) + continue; + + Cast *cast; + if (!_vm->_currentScore->_casts.contains(_sprites[i]->_castId)) { + if (!_vm->getSharedCasts()->contains(_sprites[i]->_castId)) { + warning("Cast id %d not found", _sprites[i]->_castId); + continue; + } else { + cast = _vm->getSharedCasts()->getVal(_sprites[i]->_castId); + } + } else { + cast = _vm->_currentScore->_casts[_sprites[i]->_castId]; + } + + if (cast->type == kCastText) { + renderText(surface, i); + continue; + } + + Image::ImageDecoder *img = getImageFrom(_sprites[i]->_castId); + + if (!img) { + warning("Image with id %d not found", _sprites[i]->_castId); + continue; + } + + if (!img->getSurface()) { + //TODO + //BMPDecoder doesnt cover all BITD resources (not all have first two bytes 'BM') + //Some BITD's first two bytes 0x6 0x0 + warning("Can not load image %d", _sprites[i]->_castId); + continue; + } + + uint32 regX = static_cast<BitmapCast *>(_sprites[i]->_cast)->regX; + uint32 regY = static_cast<BitmapCast *>(_sprites[i]->_cast)->regY; + uint32 rectLeft = static_cast<BitmapCast *>(_sprites[i]->_cast)->initialRect.left; + uint32 rectTop = static_cast<BitmapCast *>(_sprites[i]->_cast)->initialRect.top; + + int x = _sprites[i]->_startPoint.x - regX + rectLeft; + int y = _sprites[i]->_startPoint.y - regY + rectTop; + int height = _sprites[i]->_height; + int width = _sprites[i]->_width; + + Common::Rect drawRect = Common::Rect(x, y, x + width, y + height); + _drawRects.push_back(drawRect); + + switch (_sprites[i]->_ink) { + case kInkTypeCopy: + surface.blitFrom(*img->getSurface(), Common::Point(x, y)); + break; + case kInkTypeBackgndTrans: + drawBackgndTransSprite(surface, *img->getSurface(), drawRect); + break; + case kInkTypeMatte: + drawMatteSprite(surface, *img->getSurface(), drawRect); + break; + case kInkTypeGhost: + drawGhostSprite(surface, *img->getSurface(), drawRect); + break; + case kInkTypeReverse: + drawReverseSprite(surface, *img->getSurface(), drawRect); + break; + default: + warning("Unhandled ink type %d", _sprites[i]->_ink); + surface.blitFrom(*img->getSurface(), Common::Point(x, y)); + break; + } + } + } +} + +void Frame::renderButton(Graphics::ManagedSurface &surface, uint16 spriteId) { + renderText(surface, spriteId); + + uint16 castID = _sprites[spriteId]->_castId; + ButtonCast *button = static_cast<ButtonCast *>(_vm->_currentScore->_casts[castID]); + + uint32 rectLeft = button->initialRect.left; + uint32 rectTop = button->initialRect.top; + + int x = _sprites[spriteId]->_startPoint.x + rectLeft; + int y = _sprites[spriteId]->_startPoint.y + rectTop; + int height = _sprites[spriteId]->_height; + int width = _sprites[spriteId]->_width; + + switch (button->buttonType) { + case kTypeCheckBox: + //Magic numbers: checkbox square need to move left about 5px from text and 12px side size (d4) + surface.frameRect(Common::Rect(x - 17, y, x + 12, y + 12), 0); + break; + case kTypeButton: + surface.frameRect(Common::Rect(x, y, x + width, y + height), 0); + break; + case kTypeRadio: + warning("STUB: renderButton: kTypeRadio"); + break; + } +} + +Image::ImageDecoder *Frame::getImageFrom(uint16 spriteId) { + uint16 imgId = spriteId + 1024; + Image::ImageDecoder *img = NULL; + + if (_vm->_currentScore->getArchive()->hasResource(MKTAG('D', 'I', 'B', ' '), imgId)) { + img = new DIBDecoder(); + img->loadStream(*_vm->_currentScore->getArchive()->getResource(MKTAG('D', 'I', 'B', ' '), imgId)); + return img; + } + + if (_vm->getSharedDIB() != NULL && _vm->getSharedDIB()->contains(imgId)) { + img = new DIBDecoder(); + img->loadStream(*_vm->getSharedDIB()->getVal(imgId)); + return img; + } + + if (_vm->_currentScore->getArchive()->hasResource(MKTAG('B', 'I', 'T', 'D'), imgId)) { + img = new Image::BitmapDecoder(); + img->loadStream(*_vm->_currentScore->getArchive()->getResource(MKTAG('B', 'I', 'T', 'D'), imgId)); + return img; + } + + if (_vm->getSharedBMP() != NULL && _vm->getSharedBMP()->contains(imgId)) { + img = new Image::BitmapDecoder(); + img->loadStream(*_vm->getSharedBMP()->getVal(imgId)); + return img; + } + + warning("Image %d not found", spriteId); + return img; +} + + +void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteID) { + uint16 castID = _sprites[spriteID]->_castId; + + TextCast *textCast = static_cast<TextCast *>(_vm->_currentScore->_casts[castID]); + Common::SeekableSubReadStreamEndian *textStream; + + if (_vm->_currentScore->_movieArchive->hasResource(MKTAG('S','T','X','T'), castID + 1024)) { + textStream = _vm->_currentScore->_movieArchive->getResource(MKTAG('S','T','X','T'), castID + 1024); + } else { + textStream = _vm->getSharedSTXT()->getVal(spriteID + 1024); + } + /*uint32 unk1 = */ textStream->readUint32(); + uint32 strLen = textStream->readUint32(); + /*uin32 dataLen = */ textStream->readUint32(); + Common::String text; + + for (uint32 i = 0; i < strLen; i++) { + byte ch = textStream->readByte(); + if (ch == 0x0d) { + ch = '\n'; + } + text += ch; + } + + uint32 rectLeft = static_cast<TextCast *>(_sprites[spriteID]->_cast)->initialRect.left; + uint32 rectTop = static_cast<TextCast *>(_sprites[spriteID]->_cast)->initialRect.top; + + int x = _sprites[spriteID]->_startPoint.x + rectLeft; + int y = _sprites[spriteID]->_startPoint.y + rectTop; + int height = _sprites[spriteID]->_height; + int width = _sprites[spriteID]->_width; + + const char *fontName; + + if (_vm->_currentScore->_fontMap.contains(textCast->fontId)) { + fontName = _vm->_currentScore->_fontMap[textCast->fontId].c_str(); + } else if ((fontName = _vm->_wm->getFontName(textCast->fontId, textCast->fontSize)) == NULL) { + warning("Unknown font id %d, falling back to default", textCast->fontId); + fontName = _vm->_wm->getFontName(0, 12); + } + + const Graphics::Font *font = _vm->_wm->getFont(fontName, Graphics::FontManager::kBigGUIFont); + + font->drawString(&surface, text, x, y, width, 0); + + if (textCast->borderSize != kSizeNone) { + uint16 size = textCast->borderSize; + + //Indent from borders, measured in d4 + x -= 1; + y -= 4; + + height += 4; + width += 1; + + while (size) { + surface.frameRect(Common::Rect(x, y, x + height, y + width), 0); + x--; + y--; + height += 2; + width += 2; + size--; + } + } + + if (textCast->gutterSize != kSizeNone) { + x -= 1; + y -= 4; + + height += 4; + width += 1; + uint16 size = textCast->gutterSize; + + surface.frameRect(Common::Rect(x, y, x + height, y + width), 0); + + while (size) { + surface.drawLine(x + width, y, x + width, y + height, 0); + surface.drawLine(x, y + height, x + width, y + height, 0); + x++; + y++; + size--; + } + } +} + +void Frame::drawBackgndTransSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) { + uint8 skipColor = _vm->getPaletteColorCount() - 1; //FIXME is it always white (last entry in pallette) ? + + for (int ii = 0; ii < sprite.h; ii++) { + const byte *src = (const byte *)sprite.getBasePtr(0, ii); + byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + ii); + + for (int j = 0; j < drawRect.width(); j++) { + if (*src != skipColor) + *dst = *src; + + src++; + dst++; + } + } +} + +void Frame::drawGhostSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) { + uint8 skipColor = _vm->getPaletteColorCount() - 1; + for (int ii = 0; ii < sprite.h; ii++) { + const byte *src = (const byte *)sprite.getBasePtr(0, ii); + byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + ii); + + for (int j = 0; j < drawRect.width(); j++) { + if ((getSpriteIDFromPos(Common::Point(drawRect.left + j, drawRect.top + ii)) != 0) && (*src != skipColor)) + *dst = (_vm->getPaletteColorCount() - 1) - *src; //Oposite color + + src++; + dst++; + } + } +} + +void Frame::drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) { + uint8 skipColor = _vm->getPaletteColorCount() - 1; + for (int ii = 0; ii < sprite.h; ii++) { + const byte *src = (const byte *)sprite.getBasePtr(0, ii); + byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + ii); + + for (int j = 0; j < drawRect.width(); j++) { + if ((getSpriteIDFromPos(Common::Point(drawRect.left + j, drawRect.top + ii)) != 0)) + *dst = (_vm->getPaletteColorCount() - 1) - *src; + else if (*src != skipColor) + *dst = *src; + src++; + dst++; + } + } +} + +void Frame::drawMatteSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) { + //Like background trans, but all white pixels NOT ENCLOSED by coloured pixels are transparent + Graphics::Surface tmp; + tmp.copyFrom(sprite); + + // Searching white color in the corners + int whiteColor = -1; + + for (int corner = 0; corner < 4; corner++) { + int x = (corner & 0x1) ? tmp.w - 1 : 0; + int y = (corner & 0x2) ? tmp.h - 1 : 0; + + byte color = *(byte *)tmp.getBasePtr(x, y); + + if (_vm->getPalette()[color * 3 + 0] == 0xff && + _vm->getPalette()[color * 3 + 1] == 0xff && + _vm->getPalette()[color * 3 + 2] == 0xff) { + whiteColor = color; + break; + } + } + + if (whiteColor == -1) { + warning("No white color for Matte image"); + whiteColor = *(byte *)tmp.getBasePtr(0, 0); + } + + Graphics::FloodFill ff(&tmp, whiteColor, 0, true); + + for (int yy = 0; yy < tmp.h; yy++) { + ff.addSeed(0, yy); + ff.addSeed(tmp.w - 1, yy); + } + + for (int xx = 0; xx < tmp.w; xx++) { + ff.addSeed(xx, 0); + ff.addSeed(xx, tmp.h - 1); + } + ff.fillMask(); + + for (int yy = 0; yy < tmp.h; yy++) { + const byte *src = (const byte *)tmp.getBasePtr(0, yy); + const byte *mask = (const byte *)ff.getMask()->getBasePtr(0, yy); + byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + yy); + + for (int xx = 0; xx < drawRect.width(); xx++, src++, dst++, mask++) + if (*mask == 0) + *dst = *src; + } + + tmp.free(); +} + +uint16 Frame::getSpriteIDFromPos(Common::Point pos) { + //Find first from top to bottom + for (uint16 i = _drawRects.size() - 1; i > 0; i--) { + if (_drawRects[i].contains(pos)) + return i; + } + + return 0; +} + +Sprite::Sprite() { + _enabled = false; + _trails = 0; + _width = 0; + _ink = kInkTypeCopy; + _flags = 0; + _height = 0; + _castId = 0; + _constraint = 0; + _moveable = 0; + _castId = 0; + _backColor = 0; + _foreColor = 0; + _left = 0; + _right = 0; + _top = 0; + _bottom = 0; + _visible = false; + _movieRate = 0; + _movieTime = 0; + _startTime = 0; + _stopTime = 0; + _volume = 0; + _stretch = 0; + _type = kInactiveSprite; +} + +Sprite::Sprite(const Sprite &sprite) { + _enabled = sprite._enabled; + _castId = sprite._castId; + _flags = sprite._flags; + _trails = sprite._trails; + _ink = sprite._ink; + _width = sprite._width; + _height = sprite._height; + _startPoint.x = sprite._startPoint.x; + _startPoint.y = sprite._startPoint.y; + _backColor = sprite._backColor; + _foreColor = sprite._foreColor; + _left = sprite._left; + _right = sprite._right; + _top = sprite._top; + _bottom = sprite._bottom; + _visible = sprite._visible; + _movieRate = sprite._movieRate; + _movieTime = sprite._movieTime; + _stopTime = sprite._stopTime; + _volume = sprite._volume; + _stretch = sprite._stretch; + _type = sprite._type; +} + +Sprite::~Sprite() { + delete _cast; + delete &_startPoint; +} + +} //End of namespace Director diff --git a/engines/director/score.h b/engines/director/score.h new file mode 100644 index 0000000000..a7ca59b475 --- /dev/null +++ b/engines/director/score.h @@ -0,0 +1,455 @@ +/* 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 DIRECTOR_SCORE_H +#define DIRECTOR_SCORE_H + +#include "common/rect.h" +#include "common/stream.h" +#include "common/array.h" +#include "director/resource.h" +#include "graphics/managed_surface.h" +#include "common/str.h" +#include "image/image_decoder.h" +#include "graphics/font.h" + +namespace Director { + +class Lingo; +class DirectorSound; +class Score; +class DirectorEngine; + +#define CHANNEL_COUNT 24 + +enum CastType { + kCastBitmap = 1, + kCastFilmLoop, + kCastText, + kCastPalette, + kCastPicture, + kCastSound, + kCastButton, + kCastShape, + kCastMovie, + kCastDigitalVideo, + kCastScript +}; + +//Director v4 +enum SpriteType { + kInactiveSprite, //turns the sprite off + kBitmapSprite, + kRectangleSprite, + kRoundedRectangleSprite, + kOvalSprite, + kLineTopBottomSprite, //line from top left to bottom right + kLineBottomTopSprite, //line from bottom left to top right + kTextSprite, + kButtonSprite, + kCheckboxSprite, + kRadioButtonSprite, + kUndeterminedSprite = 16 //use castType property to examine the type of cast member associated with sprite +}; + +enum SpritePosition { + kSpritePositionUnk1 = 0, + kSpritePositionEnabled, + kSpritePositionUnk2, + kSpritePositionFlags = 4, + kSpritePositionCastId = 6, + kSpritePositionY = 8, + kSpritePositionX = 10, + kSpritePositionHeight = 12, + kSpritePositionWidth = 14 +}; + +enum MainChannelsPosition { + kScriptIdPosition = 0, + kSoundType1Position, + kTransFlagsPosition, + kTransChunkSizePosition, + kTempoPosition, + kTransTypePosition, + kSound1Position, + kSkipFrameFlagsPosition = 8, + kBlendPosition, + kSound2Position, + kSound2TypePosition = 11, + kPaletePosition = 15 +}; + +enum InkType { + kInkTypeCopy, + kInkTypeTransparent, + kInkTypeReverse, + kInkTypeGhost, + kInkTypeNotCopy, + kInkTypeNotTrans, + kInkTypeNotReverse, + kInkTypeNotGhost, + kInkTypeMatte, + kInkTypeMask, + //10-31 Not used (Lingo in a Nutshell) + kInkTypeBlend = 32, + kInkTypeAddPin, + kInkTypeAdd, + kInkTypeSubPin, + kInkTypeBackgndTrans, + kInkTypeLight, + kInkTypeSub, + kInkTypeDark +}; + +enum ScriptType { + kMovieScript = 0, + kSpriteScript = 1, + kFrameScript = 2, + kMaxScriptType = 2 +}; + +enum TransitionType { + kTransNone, + kTransWipeRight, + kTransWipeLeft, + kTransWipeDown, + kTransWipeUp, + kTransCenterOutHorizontal, + kTransEdgesInHorizontal, + kTransCenterOutVertical, + kTransEdgesInVertical, + kTransCenterOutSquare, + kTransEdgesInSquare, + kTransPushLeft, + kTransPushRight, + kTransPushDown, + kTransPushUp, + kTransRevealUp, + kTransRevealUpRight, + kTransRevealRight, + kTransRevealDown, + kTransRevealDownRight, + kTransRevealDownLeft, + kTransRevealLeft, + kTransRevealUpLeft, + kTransDissolvePixelsFast, + kTransDissolveBoxyRects, + kTransDissolveBoxySquares, + kTransDissolvePatterns, + kTransRandomRows, + kTransRandomColumns, + kTransCoverDown, + kTransCoverDownLeft, + kTransCoverDownRight, + kTransCoverLeft, + kTransCoverRight, + kTransCoverUp, + kTransCoverUpLeft, + kTransCoverUpRight, + kTransTypeVenitianBlind, + kTransTypeCheckerboard, + kTransTypeStripsBottomBuildLeft, + kTransTypeStripsBottomBuildRight, + kTransTypeStripsLeftBuildDown, + kTransTypeStripsLeftBuildUp, + kTransTypeStripsRightBuildDown, + kTransTypeStripsRightBuildUp, + kTransTypeStripsTopBuildLeft, + kTransTypeStripsTopBuildRight, + kTransZoomOpen, + kTransZoomClose, + kTransVerticalBinds, + kTransDissolveBitsTrans, + kTransDissolvePixels, + kTransDissolveBits +}; + +struct Cast { + CastType type; + Common::Rect initialRect; + byte modified; +}; + +struct BitmapCast : Cast { + BitmapCast(Common::SeekableSubReadStreamEndian &stream); + + Common::Rect boundingRect; + uint16 regX; + uint16 regY; + uint8 flags; +}; + +enum ShapeType { + kShapeRectangle, + kShapeRoundRect, + kShapeOval, + kShapeLine +}; + +struct ShapeCast : Cast { + ShapeCast(Common::SeekableSubReadStreamEndian &stream); + + ShapeType shapeType; + uint16 pattern; + byte fgCol; + byte bgCol; + byte fillType; + byte lineThickness; + byte lineDirection; +}; + +enum TextType { + kTextTypeAdjustToFit, + kTextTypeScrolling, + kTextTypeFixed +}; + +enum TextAlignType { + kTextAlignRight = -1, + kTextAlignLeft, + kTextAlignCenter +}; + +enum TextFlag { + kTextFlagEditable, + kTextFlagAutoTab, + kTextFlagDoNotWrap +}; + +enum SizeType { + kSizeNone, + kSizeSmallest, + kSizeSmall, + kSizeMedium, + kSizeLarge, + kSizeLargest +}; + +struct TextCast : Cast { + TextCast(Common::SeekableSubReadStreamEndian &stream); + + SizeType borderSize; + SizeType gutterSize; + SizeType boxShadow; + + uint32 fontId; + uint16 fontSize; + TextType textType; + TextAlignType textAlign; + SizeType textShadow; + Common::Array<TextFlag> textFlags; +}; + +enum ButtonType { + kTypeButton, + kTypeCheckBox, + kTypeRadio +}; + +struct ButtonCast : TextCast { + ButtonCast(Common::SeekableSubReadStreamEndian &stream) : TextCast(stream) { + buttonType = static_cast<ButtonType>(stream.readUint16BE()); + } + + ButtonType buttonType; +}; + +struct CastInfo { + Common::String script; + Common::String name; + Common::String directory; + Common::String fileName; + Common::String type; +}; + +struct PaletteInfo { + uint8 firstColor; + uint8 lastColor; + uint8 flags; + uint8 speed; + uint16 frameCount; +}; + +class Sprite { +public: + Sprite(); + Sprite(const Sprite &sprite); + ~Sprite(); + bool _enabled; + byte _castId; + InkType _ink; + uint16 _trails; + Cast *_cast; + uint16 _flags; + Common::Point _startPoint; + uint16 _width; + uint16 _height; + //TODO: default constraint = 0, if turned on, sprite is constrainted to the bounding rect + //As i know, constrainted != 0 only if sprite moveable + byte _constraint; + byte _moveable; + byte _backColor; + byte _foreColor; + uint16 _left; + uint16 _right; + uint16 _top; + uint16 _bottom; + byte _blend; + bool _visible; + SpriteType _type; + //Using in digital movie sprites + byte _movieRate; + uint16 _movieTime; + uint16 _startTime; + uint16 _stopTime; + byte _volume; + byte _stretch; + //Using in shape sprites + byte _lineSize; + //Using in text sprites + Common::String _editableText; +}; + +class Frame { +public: + Frame(DirectorEngine *vm); + Frame(const Frame &frame); + ~Frame(); + void readChannel(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size); + void prepareFrame(Score *score); + uint16 getSpriteIDFromPos(Common::Point pos); + +private: + void playTransition(Score *score); + void playSoundChannel(); + void renderSprites(Graphics::ManagedSurface &surface, bool renderTrail); + void renderText(Graphics::ManagedSurface &surface, uint16 spriteId); + void renderButton(Graphics::ManagedSurface &surface, uint16 spriteId); + void readPaletteInfo(Common::SeekableSubReadStreamEndian &stream); + void readSprite(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size); + void readMainChannels(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size); + Image::ImageDecoder *getImageFrom(uint16 spriteID); + void drawBackgndTransSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect); + void drawMatteSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect); + void drawGhostSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect); + void drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect); +public: + uint8 _actionId; + uint8 _transDuration; + uint8 _transArea; //1 - Whole Stage, 0 - Changing Area + uint8 _transChunkSize; + TransitionType _transType; + PaletteInfo *_palette; + uint8 _tempo; + + uint16 _sound1; + uint8 _soundType1; + uint16 _sound2; + uint8 _soundType2; + + uint8 _skipFrameFlag; + uint8 _blend; + Common::Array<Sprite *> _sprites; + Common::Array<Common::Rect > _drawRects; + DirectorEngine *_vm; +}; + +struct Label { + Common::String name; + uint16 number; + Label(Common::String name1, uint16 number1) { name = name1; number = number1; } +}; + +class Score { +public: + Score(DirectorEngine *vm); + ~Score(); + + static Common::Rect readRect(Common::SeekableSubReadStreamEndian &stream); + static int compareLabels(const void *a, const void *b); + void loadArchive(); + void setStartToLabel(Common::String label); + void gotoloop(); + void gotonext(); + void gotoprevious(); + void startLoop(); + void processEvents(); + Archive *getArchive() const { return _movieArchive; }; + void loadCastData(Common::SeekableSubReadStreamEndian &stream); + void setCurrentFrame(uint16 frameId) { _currentFrame = frameId; } + Common::String getMacName() const { return _macName; } + Sprite *getSpriteById(uint16 id); +private: + void update(); + void readVersion(uint32 rid); + void loadConfig(Common::SeekableSubReadStreamEndian &stream); + void loadPalette(Common::SeekableSubReadStreamEndian &stream); + void loadFrames(Common::SeekableSubReadStreamEndian &stream); + void loadLabels(Common::SeekableSubReadStreamEndian &stream); + void loadActions(Common::SeekableSubReadStreamEndian &stream); + void loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id); + void loadScriptText(Common::SeekableSubReadStreamEndian &stream); + void loadFileInfo(Common::SeekableSubReadStreamEndian &stream); + void loadFontMap(Common::SeekableSubReadStreamEndian &stream); + void dumpScript(const char *script, ScriptType type, uint16 id); + Common::String getString(Common::String str); + Common::Array<Common::String> loadStrings(Common::SeekableSubReadStreamEndian &stream, uint32 &entryType, bool hasHeader = true); + +public: + Common::Array<Frame *> _frames; + Common::HashMap<int, Cast *> _casts; + Common::HashMap<uint16, CastInfo *> _castsInfo; + Common::SortedArray<Label *> *_labels; + Common::HashMap<uint16, Common::String> _actions; + Common::HashMap<uint16, Common::String> _fontMap; + Graphics::ManagedSurface *_surface; + Graphics::ManagedSurface *_trailSurface; + Graphics::Font *_font; + Archive *_movieArchive; + Common::Rect _movieRect; + +private: + uint16 _versionMinor; + uint16 _versionMajor; + Common::String _macName; + Common::String _createdBy; + Common::String _changedBy; + Common::String _script; + Common::String _directory; + byte _currentFrameRate; + uint16 _castArrayStart; + uint16 _currentFrame; + Common::String _currentLabel; + uint32 _nextFrameTime; + uint32 _flags; + bool _stopPlay; + uint16 _castArrayEnd; + uint16 _movieScriptCount; + uint16 _stageColor; + Lingo *_lingo; + DirectorSound *_soundManager; + DirectorEngine *_vm; +}; + +} //End of namespace Director + +#endif diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp new file mode 100644 index 0000000000..5f6d435392 --- /dev/null +++ b/engines/director/sound.cpp @@ -0,0 +1,99 @@ +/* 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 "director/sound.h" +#include "audio/decoders/wave.h" +#include "common/file.h" +#include "audio/decoders/aiff.h" +#include "common/system.h" +#include "common/debug.h" + +namespace Director { + +DirectorSound::DirectorSound() { + _sound1 = new Audio::SoundHandle(); + _sound2 = new Audio::SoundHandle(); + _scriptSound = new Audio::SoundHandle(); + _mixer = g_system->getMixer(); +} + +void DirectorSound::playWAV(Common::String filename, uint8 soundChannel) { + Common::File *file = new Common::File(); + + if (!file->open(filename)) { + warning("Failed to open %s", filename.c_str()); + + delete file; + + return; + } + + Audio::RewindableAudioStream *sound = Audio::makeWAVStream(file, DisposeAfterUse::YES); + + if (soundChannel == 1) + _mixer->playStream(Audio::Mixer::kSFXSoundType, _sound1, sound); + else + _mixer->playStream(Audio::Mixer::kSFXSoundType, _sound2, sound); +} + +void DirectorSound::playAIFF(Common::String filename, uint8 soundChannel) { + Common::File *file = new Common::File(); + + if (!file->open(filename)) { + warning("Failed to open %s", filename.c_str()); + delete file; + return; + } + + Audio::RewindableAudioStream *sound = Audio::makeAIFFStream(file, DisposeAfterUse::YES); + + if (soundChannel == 1) + _mixer->playStream(Audio::Mixer::kSFXSoundType, _sound1, sound); + else + _mixer->playStream(Audio::Mixer::kSFXSoundType, _sound2, sound); +} + +void DirectorSound::playMCI(Audio::AudioStream &stream, uint32 from, uint32 to) { + Audio::SeekableAudioStream *seekStream = dynamic_cast<Audio::SeekableAudioStream *>(&stream); + Audio::SubSeekableAudioStream *subSeekStream = new Audio::SubSeekableAudioStream(seekStream, Audio::Timestamp(from, seekStream->getRate()), Audio::Timestamp(to, seekStream->getRate())); + + _mixer->playStream(Audio::Mixer::kSFXSoundType, _scriptSound, subSeekStream); +} + +bool DirectorSound::isChannelActive(uint8 channelID) { + if (channelID == 1) { + return _mixer->isSoundHandleActive(*_sound1); + } else if (channelID == 2) { + return _mixer->isSoundHandleActive(*_sound2); + } + + error("Incorrect sound channel"); + + return false; +} + +void DirectorSound::stopSound() { + _mixer->stopHandle(*_sound1); + _mixer->stopHandle(*_sound2); +} + +} //End of namespace Director diff --git a/engines/director/sound.h b/engines/director/sound.h new file mode 100644 index 0000000000..87a989c596 --- /dev/null +++ b/engines/director/sound.h @@ -0,0 +1,52 @@ +/* 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 "audio/audiostream.h" +#include "audio/mixer.h" +#include "common/str.h" + +#ifndef DIRECTOR_SOUND_H +#define DIRECTOR_SOUND_H + +namespace Director { + +class DirectorSound { + +private: + Audio::SoundHandle *_sound1; + Audio::SoundHandle *_sound2; + Audio::SoundHandle *_scriptSound; + Audio::Mixer *_mixer; + +public: + DirectorSound(); + + void playWAV(Common::String filename, uint8 channelID); + void playAIFF(Common::String filename, uint8 channelID); + void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to); + bool isChannelActive(uint8 channelID); + void stopSound(); +}; + +} // End of namespace Director + +#endif diff --git a/engines/draci/draci.cpp b/engines/draci/draci.cpp index b40d61a04f..e3a97bf59a 100644 --- a/engines/draci/draci.cpp +++ b/engines/draci/draci.cpp @@ -71,18 +71,6 @@ const uint kDubbingFrequency = 22050; DraciEngine::DraciEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst), _rnd("draci") { - - // Put your engine in a sane state, but do nothing big yet; - // in particular, do not load data from files; rather, if you - // need to do such things, do them from init(). - - // Do not initialize graphics here - - // However this is the place to specify all default directories - //const Common::FSNode gameDataDir(ConfMan.get("path")); - //SearchMan.addSubDirectoryMatching(gameDataDir, "sound"); - - // Here is the right place to set up the engine specific debug levels DebugMan.addDebugChannel(kDraciGeneralDebugLevel, "general", "Draci general debug info"); DebugMan.addDebugChannel(kDraciBytecodeDebugLevel, "bytecode", "GPL bytecode instructions"); DebugMan.addDebugChannel(kDraciArchiverDebugLevel, "archiver", "BAR archiver debug info"); diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp index 0514c6e889..a10403c0e1 100644 --- a/engines/dreamweb/dreamweb.cpp +++ b/engines/dreamweb/dreamweb.cpp @@ -46,12 +46,13 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam _roomDesc(kNumRoomTexts), _freeDesc(kNumFreeTexts), _personText(kNumPersonTexts) { + DebugMan.addDebugChannel(kDebugAnimation, "Animation", "Animation Debug Flag"); + DebugMan.addDebugChannel(kDebugSaveLoad, "SaveLoad", "Track Save/Load Function"); + _vSyncInterrupt = false; _console = 0; _sound = 0; - DebugMan.addDebugChannel(kDebugAnimation, "Animation", "Animation Debug Flag"); - DebugMan.addDebugChannel(kDebugSaveLoad, "SaveLoad", "Track Save/Load Function"); _speed = 1; _turbo = false; _oldMouseState = 0; diff --git a/engines/fullpipe/behavior.cpp b/engines/fullpipe/behavior.cpp index c90b2b07da..75b1c78143 100644 --- a/engines/fullpipe/behavior.cpp +++ b/engines/fullpipe/behavior.cpp @@ -83,7 +83,7 @@ void BehaviorManager::updateBehaviors() { if (!_isActive) return; - debug(4, "BehaviorManager::updateBehaviors()"); + debugC(4, kDebugAnimation, "BehaviorManager::updateBehaviors()"); for (uint i = 0; i < _behaviors.size(); i++) { BehaviorInfo *beh = _behaviors[i]; @@ -122,7 +122,7 @@ void BehaviorManager::updateBehaviors() { } void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorAnim *entry) { - debug(4, "BehaviorManager::updateBehavior() %d", entry->_movesCount); + debugC(4, kDebugAnimation, "BehaviorManager::updateBehavior() %d", entry->_movesCount); for (int i = 0; i < entry->_movesCount; i++) { BehaviorMove *bhi = entry->_behaviorMoves[i]; if (!(bhi->_flags & 1)) { @@ -144,7 +144,7 @@ void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorAnim *e } void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorAnim *bhe) { - debug(4, "BehaviorManager::updateStaticAniBehavior(%s)", transCyrillic((byte *)ani->_objectName)); + debugC(4, kDebugAnimation, "BehaviorManager::updateStaticAniBehavior(%s)", transCyrillic((byte *)ani->_objectName)); MessageQueue *mq = 0; @@ -236,7 +236,7 @@ void BehaviorInfo::clear() { } void BehaviorInfo::initAmbientBehavior(GameVar *var, Scene *sc) { - debug(4, "BehaviorInfo::initAmbientBehavior(%s)", transCyrillic((byte *)var->_varName)); + debugC(4, kDebugAnimation, "BehaviorInfo::initAmbientBehavior(%s)", transCyrillic((byte *)var->_varName)); clear(); _animsCount = 1; @@ -260,7 +260,7 @@ void BehaviorInfo::initAmbientBehavior(GameVar *var, Scene *sc) { } void BehaviorInfo::initObjectBehavior(GameVar *var, Scene *sc, StaticANIObject *ani) { - debug(4, "BehaviorInfo::initObjectBehavior(%s)", transCyrillic((byte *)var->_varName)); + debugC(4, kDebugAnimation, "BehaviorInfo::initObjectBehavior(%s)", transCyrillic((byte *)var->_varName)); clear(); diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp index c2aae9ba88..5f06d8ad79 100644 --- a/engines/fullpipe/fullpipe.cpp +++ b/engines/fullpipe/fullpipe.cpp @@ -24,6 +24,7 @@ #include "common/archive.h" #include "common/config-manager.h" +#include "common/debug-channels.h" #include "audio/mixer.h" #include "engines/util.h" @@ -47,6 +48,13 @@ FullpipeEngine *g_fp = 0; Vars *g_vars = 0; FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) { + DebugMan.addDebugChannel(kDebugPathfinding, "path", "Pathfinding"); + DebugMan.addDebugChannel(kDebugDrawing, "drawing", "Drawing"); + DebugMan.addDebugChannel(kDebugLoading, "loading", "Scene loading"); + DebugMan.addDebugChannel(kDebugAnimation, "animation", "Animation"); + DebugMan.addDebugChannel(kDebugMemory, "memory", "Memory management"); + DebugMan.addDebugChannel(kDebugEvents, "events", "Event handling"); + // Setup mixer if (!_mixer->isReady()) { warning("Sound initialization failed."); @@ -452,7 +460,7 @@ void FullpipeEngine::cleanup() { } void FullpipeEngine::updateScreen() { - debug(4, "FullpipeEngine::updateScreen()"); + debugC(4, kDebugDrawing, "FullpipeEngine::updateScreen()"); _mouseVirtX = _mouseScreenPos.x + _sceneRect.left; _mouseVirtY = _mouseScreenPos.y + _sceneRect.top; diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h index fba61aa13b..1c85536a9a 100644 --- a/engines/fullpipe/fullpipe.h +++ b/engines/fullpipe/fullpipe.h @@ -48,6 +48,15 @@ namespace Fullpipe { enum FullpipeGameFeatures { }; +enum AccessDebugChannels { + kDebugPathfinding = 1 << 0, + kDebugDrawing = 1 << 1, + kDebugLoading = 1 << 2, + kDebugAnimation = 1 << 3, + kDebugMemory = 1 << 4, + kDebugEvents = 1 << 5 +}; + class BehaviorManager; class BaseModalObject; class GameLoader; diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp index 3a0e262f82..1cd51036d0 100644 --- a/engines/fullpipe/gameloader.cpp +++ b/engines/fullpipe/gameloader.cpp @@ -110,10 +110,10 @@ GameLoader::~GameLoader() { } bool GameLoader::load(MfcArchive &file) { - debug(1, "GameLoader::load()"); + debugC(1, kDebugLoading, "GameLoader::load()"); _gameName = file.readPascalString(); - debug(1, "_gameName: %s", _gameName); + debugC(1, kDebugLoading, "_gameName: %s", _gameName); _gameProject = new GameProject(); @@ -126,13 +126,13 @@ bool GameLoader::load(MfcArchive &file) { } _gameName = file.readPascalString(); - debug(1, "_gameName: %s", _gameName); + debugC(1, kDebugLoading, "_gameName: %s", _gameName); _inventory.load(file); _interactionController->load(file); - debug(1, "sceneTag count: %d", _gameProject->_sceneTagList->size()); + debugC(1, kDebugLoading, "sceneTag count: %d", _gameProject->_sceneTagList->size()); _sc2array.resize(_gameProject->_sceneTagList->size()); @@ -142,7 +142,7 @@ bool GameLoader::load(MfcArchive &file) { snprintf(tmp, 11, "%04d.sc2", it->_sceneId); - debug(1, "sc: %s", tmp); + debugC(1, kDebugLoading, "sc: %s", tmp); _sc2array[i].loadFile((const char *)tmp); } @@ -152,7 +152,7 @@ bool GameLoader::load(MfcArchive &file) { _field_FA = file.readUint16LE(); _field_F8 = file.readUint16LE(); - debug(1, "_field_FA: %d\n_field_F8: %d", _field_FA, _field_F8); + debugC(1, kDebugLoading, "_field_FA: %d\n_field_F8: %d", _field_FA, _field_F8); _gameVar = (GameVar *)file.readClass(); @@ -357,7 +357,7 @@ bool preloadCallback(PreloadItem &pre, int flag) { } bool GameLoader::preloadScene(int sceneId, int entranceId) { - debug(0, "preloadScene(%d, %d), ", sceneId, entranceId); + debugC(0, kDebugLoading, "preloadScene(%d, %d), ", sceneId, entranceId); if (_preloadSceneId != sceneId || _preloadEntranceId != entranceId) { _preloadSceneId = sceneId; @@ -455,13 +455,13 @@ void GameLoader::applyPicAniInfos(Scene *sc, PicAniInfo **picAniInfo, int picAni if (picAniInfoCount <= 0) return; - debug(0, "GameLoader::applyPicAniInfos(sc, ptr, %d)", picAniInfoCount); + debugC(0, kDebugAnimation, "GameLoader::applyPicAniInfos(sc, ptr, %d)", picAniInfoCount); PictureObject *pict; StaticANIObject *ani; for (int i = 0; i < picAniInfoCount; i++) { - debug(7, "PicAniInfo: id: %d type: %d", picAniInfo[i]->objectId, picAniInfo[i]->type); + debugC(7, kDebugAnimation, "PicAniInfo: id: %d type: %d", picAniInfo[i]->objectId, picAniInfo[i]->type); if (picAniInfo[i]->type & 2) { pict = sc->getPictureObjectById(picAniInfo[i]->objectId, picAniInfo[i]->field_8); if (pict) { @@ -551,14 +551,14 @@ Sc2::Sc2() { } bool Sc2::load(MfcArchive &file) { - debug(5, "Sc2::load()"); + debugC(5, kDebugLoading, "Sc2::load()"); _sceneId = file.readUint16LE(); _motionController = (MotionController *)file.readClass(); _count1 = file.readUint32LE(); - debug(4, "count1: %d", _count1); + debugC(4, kDebugLoading, "count1: %d", _count1); if (_count1 > 0) { _data1 = (int32 *)malloc(_count1 * sizeof(int32)); @@ -570,7 +570,7 @@ bool Sc2::load(MfcArchive &file) { } _defPicAniInfosCount = file.readUint32LE(); - debug(4, "defPicAniInfos: %d", _defPicAniInfosCount); + debugC(4, kDebugLoading, "defPicAniInfos: %d", _defPicAniInfosCount); if (_defPicAniInfosCount > 0) { _defPicAniInfos = (PicAniInfo **)malloc(_defPicAniInfosCount * sizeof(PicAniInfo *)); @@ -587,7 +587,7 @@ bool Sc2::load(MfcArchive &file) { _picAniInfosCount = 0; _entranceDataCount = file.readUint32LE(); - debug(4, "_entranceData: %d", _entranceDataCount); + debugC(4, kDebugLoading, "_entranceData: %d", _entranceDataCount); if (_entranceDataCount > 0) { _entranceData = (EntranceInfo **)malloc(_entranceDataCount * sizeof(EntranceInfo *)); @@ -607,7 +607,7 @@ bool Sc2::load(MfcArchive &file) { } bool PreloadItems::load(MfcArchive &file) { - debug(5, "PreloadItems::load()"); + debugC(5, kDebugLoading, "PreloadItems::load()"); int count = file.readCount(); diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp index 42846850ca..dcd5c33740 100644 --- a/engines/fullpipe/gfx.cpp +++ b/engines/fullpipe/gfx.cpp @@ -58,7 +58,7 @@ Background::~Background() { } bool Background::load(MfcArchive &file) { - debug(5, "Background::load()"); + debugC(5, kDebugLoading, "Background::load()"); _bgname = file.readPascalString(); int count = file.readUint16LE(); @@ -80,7 +80,7 @@ bool Background::load(MfcArchive &file) { _bigPictureArray = (BigPicture ***)calloc(_bigPictureArray1Count, sizeof(BigPicture **)); - debug(6, "bigPictureArray[%d][%d]", _bigPictureArray1Count, _bigPictureArray2Count); + debugC(6, kDebugLoading, "bigPictureArray[%d][%d]", _bigPictureArray1Count, _bigPictureArray2Count); for (int i = 0; i < _bigPictureArray1Count; i++) { _bigPictureArray[i] = (BigPicture **)calloc(_bigPictureArray2Count, sizeof(BigPicture *)); @@ -137,7 +137,7 @@ PictureObject::PictureObject(PictureObject *src) : GameObject(src) { } bool PictureObject::load(MfcArchive &file, bool bigPicture) { - debug(5, "PictureObject::load()"); + debugC(5, kDebugLoading, "PictureObject::load()"); GameObject::load(file); if (bigPicture) @@ -282,7 +282,7 @@ GameObject::~GameObject() { } bool GameObject::load(MfcArchive &file) { - debug(5, "GameObject::load()"); + debugC(5, kDebugLoading, "GameObject::load()"); _okeyCode = 0; _flags = 0; _field_20 = 0; @@ -464,7 +464,7 @@ Picture::~Picture() { } void Picture::freePicture() { - debug(5, "Picture::freePicture(): file: %s", _memfilename); + debugC(5, kDebugMemory, "Picture::freePicture(): file: %s", _memfilename); if (_bitmap) { if (testFlags() && !_field_54) { @@ -492,7 +492,7 @@ void Picture::freePixelData() { } bool Picture::load(MfcArchive &file) { - debug(5, "Picture::load()"); + debugC(5, kDebugLoading, "Picture::load()"); MemoryObject::load(file); _x = file.readUint32LE(); @@ -526,7 +526,7 @@ bool Picture::load(MfcArchive &file) { getData(); - debug(5, "Picture::load: loaded <%s>", _memfilename); + debugC(5, kDebugLoading, "Picture::load: loaded <%s>", _memfilename); return true; } @@ -546,7 +546,7 @@ void Picture::setAOIDs() { } void Picture::init() { - debug(5, "Picture::init(), %s", _memfilename); + debugC(5, kDebugLoading, "Picture::init(), %s", _memfilename); MemoryObject::getData(); @@ -567,7 +567,7 @@ Common::Point *Picture::getDimensions(Common::Point *p) { void Picture::getDibInfo() { int off = _dataSize & ~0xf; - debug(9, "Picture::getDibInfo: _dataSize: %d", _dataSize); + debugC(9, kDebugLoading, "Picture::getDibInfo: _dataSize: %d", _dataSize); if (!_dataSize) { warning("Picture::getDibInfo(): Empty data size"); @@ -605,7 +605,7 @@ void Picture::draw(int x, int y, int style, int angle) { int x1 = x; int y1 = y; - debug(7, "Picture::draw(%d, %d, %d, %d) (%s)", x, y, style, angle, _memfilename); + debugC(7, kDebugDrawing, "Picture::draw(%d, %d, %d, %d) (%s)", x, y, style, angle, _memfilename); if (x != -1) x1 = x; @@ -620,7 +620,7 @@ void Picture::draw(int x, int y, int style, int angle) { return; if ((_alpha & 0xff) < 0xff) { - debug(7, "Picture:draw: alpha = %0x", _alpha); + debugC(7, kDebugDrawing, "Picture:draw: alpha = %0x", _alpha); } byte *pal = _paletteData; @@ -784,7 +784,7 @@ Bitmap::~Bitmap() { } void Bitmap::load(Common::ReadStream *s) { - debug(5, "Bitmap::load()"); + debugC(5, kDebugLoading, "Bitmap::load()"); _x = s->readUint32LE(); _y = s->readUint32LE(); @@ -795,8 +795,8 @@ void Bitmap::load(Common::ReadStream *s) { _dataSize = s->readUint32LE(); _flags = s->readUint32LE(); - debug(8, "Bitmap: x: %d y: %d w: %d h: %d dataSize: 0x%x", _x, _y, _width, _height, _dataSize); - debug(8, "Bitmap: type: %s (0x%04x) flags: 0x%x", Common::tag2string(_type).c_str(), _type, _flags); + debugC(8, kDebugLoading, "Bitmap: x: %d y: %d w: %d h: %d dataSize: 0x%x", _x, _y, _width, _height, _dataSize); + debugC(8, kDebugLoading, "Bitmap: type: %s (0x%04x) flags: 0x%x", Common::tag2string(_type).c_str(), _type, _flags); } bool Bitmap::isPixelHitAtPos(int x, int y) { @@ -821,7 +821,7 @@ void Bitmap::decode(int32 *palette) { } void Bitmap::putDib(int x, int y, int32 *palette, int alpha) { - debug(7, "Bitmap::putDib(%d, %d)", x, y); + debugC(7, kDebugDrawing, "Bitmap::putDib(%d, %d)", x, y); int x1 = x - g_fp->_sceneRect.left; int y1 = y - g_fp->_sceneRect.top; @@ -868,11 +868,11 @@ bool Bitmap::putDibRB(int32 *palette) { uint16 *srcPtr; if (!palette) { - debug(2, "Bitmap::putDibRB(): Both global and local palettes are empty"); + debugC(2, kDebugDrawing, "Bitmap::putDibRB(): Both global and local palettes are empty"); return false; } - debug(8, "Bitmap::putDibRB()"); + debugC(8, kDebugDrawing, "Bitmap::putDibRB()"); endy = _height - 1; @@ -1149,7 +1149,7 @@ void Bitmap::drawRotated(int x, int y, int angle, byte *palette, int alpha) { } bool BigPicture::load(MfcArchive &file) { - debug(5, "BigPicture::load()"); + debugC(5, kDebugLoading, "BigPicture::load()"); Picture::load(file); return true; @@ -1190,7 +1190,7 @@ Shadows::Shadows() { } bool Shadows::load(MfcArchive &file) { - debug(5, "Shadows::load()"); + debugC(5, kDebugLoading, "Shadows::load()"); _sceneId = file.readUint32LE(); _staticAniObjectId = file.readUint32LE(); _movementId = file.readUint32LE(); diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp index 4aac3485f4..484b1e150e 100644 --- a/engines/fullpipe/interaction.cpp +++ b/engines/fullpipe/interaction.cpp @@ -62,7 +62,7 @@ InteractionController::~InteractionController() { } bool InteractionController::load(MfcArchive &file) { - debug(5, "InteractionController::load()"); + debugC(5, kDebugLoading, "InteractionController::load()"); return _interactions.load(file); } @@ -143,6 +143,7 @@ bool InteractionController::handleInteraction(StaticANIObject *subj, GameObject obj->setPicAniInfo(&aniInfo); if (abs(xpos - subj->_ox) > 1 || abs(ypos - subj->_oy) > 1) { + debugC(0, kDebugPathfinding, "Calling doWalkTo() at [%d, %d]", xpos, ypos); mq = getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->doWalkTo(subj, xpos, ypos, 1, cinter->_staticsId2); if (mq) { dur = mq->calcDuration(subj); @@ -440,7 +441,7 @@ Interaction::~Interaction() { } bool Interaction::load(MfcArchive &file) { - debug(5, "Interaction::load()"); + debugC(5, kDebugLoading, "Interaction::load()"); _objectId1 = file.readUint16LE(); _objectId2 = file.readUint16LE(); @@ -531,7 +532,7 @@ bool Interaction::isOverlapping(StaticANIObject *subj, GameObject *obj) { } bool EntranceInfo::load(MfcArchive &file) { - debug(5, "EntranceInfo::load()"); + debugC(5, kDebugLoading, "EntranceInfo::load()"); _sceneId = file.readUint32LE(); _field_4 = file.readUint32LE(); diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp index f9b507c50b..aa229d55d7 100644 --- a/engines/fullpipe/inventory.cpp +++ b/engines/fullpipe/inventory.cpp @@ -35,7 +35,7 @@ Inventory::~Inventory() { } bool Inventory::load(MfcArchive &file) { - debug(5, "Inventory::load()"); + debugC(5, kDebugLoading, "Inventory::load()"); _sceneId = file.readUint16LE(); int numInvs = file.readUint32LE(); diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp index 4e791a3b27..c40af3b062 100644 --- a/engines/fullpipe/messagehandlers.cpp +++ b/engines/fullpipe/messagehandlers.cpp @@ -100,7 +100,7 @@ void global_messageHandler_KickMetal() { } int global_messageHandler1(ExCommand *cmd) { - debug(5, "global_messageHandler1: %d %d", cmd->_messageKind, cmd->_messageNum); + debugC(5, kDebugEvents, "global_messageHandler1: %d %d", cmd->_messageKind, cmd->_messageNum); if (cmd->_excFlags & 0x10000) { if (cmd->_messageNum == MV_MAN_TOLADDER) @@ -364,7 +364,7 @@ int global_messageHandler3(ExCommand *cmd) { case 17: switch (cmd->_messageNum) { case 61: - debug(0, "preload: { %d, %d },", cmd->_parentId, cmd->_keyCode); + debugC(0, kDebugEvents, "preload: { %d, %d },", cmd->_parentId, cmd->_keyCode); return g_fp->_gameLoader->preloadScene(cmd->_parentId, cmd->_keyCode); case 62: return g_fp->_gameLoader->gotoScene(cmd->_parentId, cmd->_keyCode); @@ -425,6 +425,7 @@ int global_messageHandler3(ExCommand *cmd) { if (g_fp->_msgX != cmd->_sceneClickX || g_fp->_msgY != cmd->_sceneClickY) { ani = g_fp->_currentScene->getStaticANIObject1ById(g_fp->_gameLoader->_field_FA, -1); if (!ani || (ani->isIdle() && !(ani->_flags & 0x80) && !(ani->_flags & 0x100))) { + debugC(0, kDebugPathfinding, "WWW 1"); result = startWalkTo(g_fp->_gameLoader->_field_FA, -1, cmd->_sceneClickX, cmd->_sceneClickY, 0); if (result) { ExCommand *ex = new ExCommand(g_fp->_gameLoader->_field_FA, 17, 64, 0, 0, 0, 1, 0, 0, 0); @@ -765,7 +766,7 @@ int MovGraph_messageHandler(ExCommand *cmd) { point.x = ani->_ox; point.y = ani->_oy; - double dst = gr->calcDistance(&point, (MovGraphLink *)(*i), 0); + double dst = gr->putToLink(&point, (MovGraphLink *)(*i), 0); if (dst >= 0.0 && dst < mindistance) { mindistance = dst; link = (MovGraphLink *)(*i); diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp index a7337b98ed..8652223ed1 100644 --- a/engines/fullpipe/messages.cpp +++ b/engines/fullpipe/messages.cpp @@ -57,7 +57,7 @@ ExCommand::ExCommand(int16 parentId, int messageKind, int messageNum, int x, int } bool ExCommand::load(MfcArchive &file) { - debug(5, "ExCommand::load()"); + debugC(5, kDebugLoading, "ExCommand::load()"); _parentId = file.readUint16LE(); _messageKind = file.readUint32LE(); @@ -247,7 +247,7 @@ ObjstateCommand::~ObjstateCommand() { } bool ObjstateCommand::load(MfcArchive &file) { - debug(5, "ObjStateCommand::load()"); + debugC(5, kDebugLoading, "ObjStateCommand::load()"); _objtype = kObjTypeObjstateCommand; @@ -341,7 +341,7 @@ MessageQueue::~MessageQueue() { } bool MessageQueue::load(MfcArchive &file) { - debug(5, "MessageQueue::load()"); + debugC(5, kDebugLoading, "MessageQueue::load()"); _dataId = file.readUint16LE(); diff --git a/engines/fullpipe/mgm.cpp b/engines/fullpipe/mgm.cpp index 1c8ca2a7b1..c9eeebb224 100644 --- a/engines/fullpipe/mgm.cpp +++ b/engines/fullpipe/mgm.cpp @@ -34,6 +34,8 @@ void MGM::clear() { } MessageQueue *MGM::genMQ(StaticANIObject *ani, int staticsIndex, int staticsId, int *resStatId, Common::Point **pointArr) { + debugC(4, kDebugPathfinding, "MGM::genMQ(*%d, %d, %d, res, point)", ani->_id, staticsIndex, staticsId); + int idx = getItemIndexById(ani->_id); if (idx == -1) @@ -130,6 +132,8 @@ MGMSubItem::MGMSubItem() { } void MGM::addItem(int objId) { + debugC(4, kDebugPathfinding, "MGM::addItem(%d)", objId); + if (getItemIndexById(objId) == -1) { MGMItem *item = new MGMItem(); @@ -145,6 +149,8 @@ void MGM::rebuildTables(int objId) { if (idx == -1) return; + debugC(3, kDebugPathfinding, "MGM::rebuildTables. (1) movements1 sz: %d movements2 sz: %d", _items[idx]->movements1.size(), _items[idx]->movements2.size()); + _items[idx]->subItems.clear(); _items[idx]->statics.clear(); _items[idx]->movements1.clear(); @@ -155,14 +161,20 @@ void MGM::rebuildTables(int objId) { if (!obj) return; + debugC(1, kDebugPathfinding, "WWW rebuild. idx: %d, size: %d", idx, obj->_staticsList.size() * obj->_staticsList.size()); for (uint i = 0; i < obj->_staticsList.size(); i++) { _items[idx]->statics.push_back((Statics *)obj->_staticsList[i]); - _items[idx]->subItems.push_back(new MGMSubItem); + for (uint j = 0; j < obj->_staticsList.size(); j++) // Yes, square + _items[idx]->subItems.push_back(new MGMSubItem); } - for (uint i = 0; i < obj->_movements.size(); i++) + for (uint i = 0; i < obj->_movements.size(); i++) { _items[idx]->movements1.push_back((Movement *)obj->_movements[i]); + _items[idx]->movements2.push_back(0); + } + + debugC(3, kDebugPathfinding, "MGM::rebuildTables. (2) movements1 sz: %d movements2 sz: %d", _items[idx]->movements1.size(), _items[idx]->movements2.size()); } int MGM::getItemIndexById(int objId) { @@ -174,6 +186,8 @@ int MGM::getItemIndexById(int objId) { } MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { + debugC(4, kDebugPathfinding, "MGM::genMovement(*%d)", mgminfo->ani ? mgminfo->ani->_id : -1); + if (!mgminfo->ani) return 0; @@ -214,12 +228,15 @@ MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { if (!mov) return 0; + int itemIdx = getItemIndexById(mgminfo->ani->_id); int subIdx = getStaticsIndexById(itemIdx, mgminfo->staticsId1); int st2idx = getStaticsIndexById(itemIdx, mov->_staticsObj1->_staticsId); int st1idx = getStaticsIndexById(itemIdx, mov->_staticsObj2->_staticsId); int subOffset = getStaticsIndexById(itemIdx, mgminfo->staticsId2); + debugC(3, kDebugPathfinding, "MGM::genMovement. (1) movements1 sz: %d movements2 sz: %d", _items[itemIdx]->movements1.size(), _items[itemIdx]->movements2.size()); + clearMovements2(itemIdx); recalcOffsets(itemIdx, subIdx, st2idx, 0, 1); clearMovements2(itemIdx); @@ -376,6 +393,8 @@ MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { mq->addExCommandToEnd(ex); + debugC(3, kDebugPathfinding, "MGM::genMovement. (2) movements1 sz: %d movements2 sz: %d", _items[itemIdx]->movements1.size(), _items[itemIdx]->movements2.size()); + return mq; } @@ -389,14 +408,16 @@ int MGM::countPhases(int idx, int subIdx, int endIdx, int flag) { if (subIdx < 0) break; - res += _items[idx]->subItems[subIdx + endIdx * _items[idx]->statics.size()]->movement->countPhasesWithFlag(-1, flag); + res += _items[idx]->subItems[subIdx + endIdx * _items[idx]->statics.size()]->movement->countPhasesWithFlag(0xffffffff, flag); - subIdx = _items[idx]->subItems[subIdx + 6 * endIdx * _items[idx]->statics.size()]->staticsIndex; + subIdx = _items[idx]->subItems[subIdx + endIdx * _items[idx]->statics.size()]->staticsIndex; } return res; } void MGM::updateAnimStatics(StaticANIObject *ani, int staticsId) { + debugC(4, kDebugPathfinding, "MGM::updateAnimStatics(*%d, %d)", ani->_id, staticsId); + if (getItemIndexById(ani->_id) == -1) return; @@ -425,6 +446,8 @@ void MGM::updateAnimStatics(StaticANIObject *ani, int staticsId) { } Common::Point *MGM::getPoint(Common::Point *point, int objectId, int staticsId1, int staticsId2) { + debugC(4, kDebugPathfinding, "MGM::getPoint([%d, %d], %d, %d, %d)", point->x, point->y, objectId, staticsId1, staticsId2); + int idx = getItemIndexById(objectId); if (idx == -1) { @@ -474,7 +497,7 @@ int MGM::getStaticsIndexById(int idx, int16 id) { return i; } - return 0; + return -1; } int MGM::getStaticsIndex(int idx, Statics *st) { @@ -486,79 +509,95 @@ int MGM::getStaticsIndex(int idx, Statics *st) { return i; } - return 0; + return -1; } void MGM::clearMovements2(int idx) { - _items[idx]->movements2.clear(); + debugC(2, kDebugPathfinding, "MGM::clearMovements2(%d)", idx); + + for (uint i = 0; i < _items[idx]->movements2.size(); i++) + _items[idx]->movements2[i] = 0; + + debugC(3, kDebugPathfinding, "MGM::clearMovements2. movements1 sz: %d movements2 sz: %d", _items[idx]->movements1.size(), _items[idx]->movements2.size()); } int MGM::recalcOffsets(int idx, int st1idx, int st2idx, bool flip, bool flop) { MGMItem *item = _items[idx]; int subIdx = st1idx + st2idx * item->statics.size(); + debugC(2, kDebugPathfinding, "MGM::recalcOffsets(%d, %d, %d, %d, %d)", idx, st1idx, st2idx, flip, flop); + if (st1idx == st2idx) { memset(&item->subItems[subIdx], 0, sizeof(item->subItems[subIdx])); return 0; } - if (item->subItems[subIdx]) + if (item->subItems[subIdx]->movement) return item->subItems[subIdx]->field_8; Common::Point point; + debugC(3, kDebugPathfinding, "MGM::recalcOffsets. movements1 sz: %d movements2 sz: %d", item->movements1.size(), item->movements2.size()); + for (uint i = 0; i < item->movements1.size(); i++) { Movement *mov = item->movements1[i]; if (mov->_staticsObj1 == item->statics[st1idx]) { - if (!item->movements2[i] && (!flop || mov->_field_50)) { - item->movements2[i] = 1; + if (item->movements2[i] || (flop && !mov->_field_50)) + continue; - int stidx = getStaticsIndex(idx, item->movements1[i]->_staticsObj2); - int recalc = recalcOffsets(idx, stidx, st2idx, flip, flop); - int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); - int newsz = sz + item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->field_C; + item->movements2[i] = 1; - if (recalc >= 0) { - if (!item->subItems[subIdx]->movement || item->subItems[subIdx]->field_8 > recalc + 1 || - (item->subItems[subIdx]->field_8 == recalc + 1 && item->subItems[subIdx]->field_C > newsz)) { - item->subItems[subIdx]->movement = mov; - item->subItems[subIdx]->staticsIndex = stidx; - item->subItems[subIdx]->field_8 = recalc + 1; - item->subItems[subIdx]->field_C = newsz; + int stidx = getStaticsIndex(idx, mov->_staticsObj2); + int recalc = recalcOffsets(idx, stidx, st2idx, flip, flop); + int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); + debugC(1, kDebugPathfinding, "MGM::recalcOffsets, want idx: %d, off: %d (%d + %d), sz: %d", idx, stidx + st2idx * _items[idx]->statics.size(), stidx, st2idx, item->subItems.size()); - mov->calcSomeXY(point, 0, -1); + int newsz = sz + item->subItems[stidx + st2idx * _items[idx]->statics.size()]->field_C; - item->subItems[subIdx]->x = item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->x + point.x; - item->subItems[subIdx]->y = item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->y + point.y; - } - } + if (recalc < 0) + continue; + + if (!item->subItems[subIdx]->movement || item->subItems[subIdx]->field_8 > recalc + 1 || + (item->subItems[subIdx]->field_8 == recalc + 1 && item->subItems[subIdx]->field_C > newsz)) { + item->subItems[subIdx]->movement = mov; + item->subItems[subIdx]->staticsIndex = stidx; + item->subItems[subIdx]->field_8 = recalc + 1; + item->subItems[subIdx]->field_C = newsz; + + mov->calcSomeXY(point, 0, -1); + + item->subItems[subIdx]->x = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->x + point.x; + item->subItems[subIdx]->y = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->y + point.y; } } else if (flip) { - if (mov->_staticsObj2 == item->statics[st1idx]) { - if (!item->movements2[i] && (!flop || mov->_field_50)) { - item->movements2[i] = 1; + if (mov->_staticsObj2 != item->statics[st1idx]) + continue; - int stidx = getStaticsIndex(idx, mov->_staticsObj1); - int recalc = recalcOffsets(idx, stidx, st2idx, flip, flop); + if (item->movements2[i] || (flop && !mov->_field_50)) + continue; - if (recalc >= 0) { - if (!item->subItems[subIdx]->movement || item->subItems[subIdx]->field_8 > recalc + 1) { - item->subItems[subIdx]->movement = mov; - item->subItems[subIdx]->staticsIndex = stidx; - item->subItems[subIdx]->field_8 = recalc + 1; + item->movements2[i] = 1; - int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); + int stidx = getStaticsIndex(idx, mov->_staticsObj1); + int recalc = recalcOffsets(idx, stidx, st2idx, flip, flop); - item->subItems[subIdx]->field_C = sz + item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->field_C; + if (recalc < 0) + continue; - mov->calcSomeXY(point, 0, -1); + if (!item->subItems[subIdx]->movement || item->subItems[subIdx]->field_8 > recalc + 1) { + item->subItems[subIdx]->movement = mov; + item->subItems[subIdx]->staticsIndex = stidx; + item->subItems[subIdx]->field_8 = recalc + 1; - item->subItems[subIdx]->x = item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->x - point.x; - item->subItems[subIdx]->y = item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->y - point.y; - } - } - } + int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); + + item->subItems[subIdx]->field_C = sz + item->subItems[stidx + st2idx * _items[idx]->statics.size()]->field_C; + + mov->calcSomeXY(point, 0, -1); + + item->subItems[subIdx]->x = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->x - point.x; + item->subItems[subIdx]->y = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->y - point.y; } } } @@ -570,12 +609,15 @@ int MGM::recalcOffsets(int idx, int st1idx, int st2idx, bool flip, bool flop) { } int MGM::refreshOffsets(int objectId, int idx1, int idx2) { + debugC(4, kDebugPathfinding, "MGM::refreshOffsets(%d, %d, %d)", objectId, idx1, idx2); + int idx = getItemIndexById(objectId); if (idx != -1) { int from = getStaticsIndexById(idx, idx1); int to = getStaticsIndexById(idx, idx2); + debugC(1, kDebugPathfinding, "WWW 6, want idx: %d, off: %d", idx, from + to * _items[idx]->statics.size()); MGMSubItem *sub = _items[idx]->subItems[from + to * _items[idx]->statics.size()]; if (sub->movement) { @@ -666,6 +708,8 @@ Common::Point *MGM::calcLength(Common::Point *pRes, Movement *mov, int x, int y, } ExCommand2 *MGM::buildExCommand2(Movement *mov, int objId, int x1, int y1, Common::Point *x2, Common::Point *y2, int len) { + debugC(2, kDebugPathfinding, "MGM::buildExCommand2(mov, %d, %d, %d, [%d, %d], [%d, %d], %d)", objId, x1, y1, x2->x, x2->y, y2->x, y2->y, len); + uint cnt; if (mov->_currMovement) diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp index baea2e28bd..fbfa602e62 100644 --- a/engines/fullpipe/motion.cpp +++ b/engines/fullpipe/motion.cpp @@ -32,7 +32,7 @@ namespace Fullpipe { bool MotionController::load(MfcArchive &file) { // Is originally empty file.readClass(); - debug(5, "MotionController::load()"); + debugC(5, kDebugLoading, "MotionController::load()"); return true; } @@ -42,6 +42,8 @@ void MotionController::enableLinks(const char *linkName, bool enable) { } MovGraphLink *MotionController::getLinkByName(const char *name) { + debugC(4, kDebugPathfinding, "MotionController::getLinkByName(%s)", name); + if (_objtype == kObjTypeMctlCompound) { MctlCompound *obj = (MctlCompound *)this; @@ -80,23 +82,23 @@ MovGraphLink *MotionController::getLinkByName(const char *name) { } bool MctlCompound::load(MfcArchive &file) { - debug(5, "MctlCompound::load()"); + debugC(5, kDebugLoading, "MctlCompound::load()"); int count = file.readUint32LE(); - debug(6, "MctlCompound::count = %d", count); + debugC(6, kDebugLoading, "MctlCompound::count = %d", count); for (int i = 0; i < count; i++) { - debug(6, "CompoundArray[%d]", i); + debugC(6, kDebugLoading, "CompoundArray[%d]", i); MctlItem *obj = new MctlItem(); obj->_motionControllerObj = (MotionController *)file.readClass(); int count1 = file.readUint32LE(); - debug(6, "ConnectionPoint::count: %d", count1); + debugC(6, kDebugLoading, "ConnectionPoint::count: %d", count1); for (int j = 0; j < count1; j++) { - debug(6, "ConnectionPoint[%d]", j); + debugC(6, kDebugLoading, "ConnectionPoint[%d]", j); MctlConnectionPoint *obj1 = (MctlConnectionPoint *)file.readClass(); obj->_connectionPoints.push_back(obj1); @@ -105,7 +107,7 @@ bool MctlCompound::load(MfcArchive &file) { obj->_field_20 = file.readUint32LE(); obj->_field_24 = file.readUint32LE(); - debug(6, "graphReact"); + debugC(6, kDebugLoading, "graphReact"); obj->_movGraphReactObj = (MovGraphReact *)file.readClass(); _motionControllers.push_back(obj); @@ -115,11 +117,15 @@ bool MctlCompound::load(MfcArchive &file) { } void MctlCompound::attachObject(StaticANIObject *obj) { + debugC(4, kDebugPathfinding, "MctlCompound::attachObject(*%d)", obj->_id); + for (uint i = 0; i < _motionControllers.size(); i++) _motionControllers[i]->_motionControllerObj->attachObject(obj); } int MctlCompound::detachObject(StaticANIObject *obj) { + debugC(4, kDebugPathfinding, "MctlCompound::detachObject(*%d)", obj->_id); + for (uint i = 0; i < _motionControllers.size(); i++) _motionControllers[i]->_motionControllerObj->detachObject(obj); @@ -130,6 +136,8 @@ void MctlCompound::initMovGraph2() { if (_objtype != kObjTypeMctlCompound) return; + debugC(4, kDebugPathfinding, "MctlCompound::initMovGraph2()"); + for (uint i = 0; i < _motionControllers.size(); i++) { if (_motionControllers[i]->_motionControllerObj->_objtype != kObjTypeMovGraph) continue; @@ -151,6 +159,8 @@ void MctlCompound::initMovGraph2() { } void MctlCompound::detachAllObjects() { + debugC(4, kDebugPathfinding, "MctlCompound::detachAllObjects()"); + for (uint i = 0; i < _motionControllers.size(); i++) _motionControllers[i]->_motionControllerObj->detachAllObjects(); } @@ -159,6 +169,8 @@ MessageQueue *MctlCompound::startMove(StaticANIObject *ani, int sourceX, int sou int idx = -1; int sourceIdx = -1; + debugC(4, kDebugPathfinding, "MctlCompound::startMove(*%d, %d, %d, %d, %d)", (ani ? ani->_id : -1), sourceX, sourceY, fuzzyMatch, staticsId); + if (!ani) return 0; @@ -186,6 +198,7 @@ MessageQueue *MctlCompound::startMove(StaticANIObject *ani, int sourceX, int sou if (sourceIdx == -1) return 0; + debugC(1, kDebugPathfinding, "WWW 2"); if (idx == sourceIdx) return _motionControllers[idx]->_motionControllerObj->startMove(ani, sourceX, sourceY, fuzzyMatch, staticsId); @@ -228,6 +241,8 @@ MessageQueue *MctlCompound::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int match1 = -1; int match2 = -1; + debugC(1, kDebugPathfinding, "MctlCompound::doWalkTo(*%d, %d, %d, %d, %d)", (subj ? subj->_id : -1), xpos, ypos, fuzzyMatch, staticsId); + if (!subj) return 0; @@ -327,6 +342,8 @@ int MctlLadder::collisionDetection(StaticANIObject *man) { } void MctlLadder::attachObject(StaticANIObject *obj) { + debugC(4, kDebugPathfinding, "MctlLadder::attachObject(*%d)", obj->_id); + if (findObjectPos(obj) < 0) { MctlLadderMovement *movement = new MctlLadderMovement; @@ -348,6 +365,8 @@ int MctlLadder::findObjectPos(StaticANIObject *obj) { } bool MctlLadder::initMovement(StaticANIObject *ani, MctlLadderMovement *movement) { + debugC(4, kDebugPathfinding, "MctlLadder::initMovement(*%d, ...)", ani->_id); + GameVar *v = g_fp->getGameLoaderGameVar()->getSubVarByName(ani->getName()); if (!v) @@ -392,6 +411,8 @@ bool MctlLadder::initMovement(StaticANIObject *ani, MctlLadderMovement *movement } void MctlLadder::detachAllObjects() { + debugC(4, kDebugPathfinding, "MctlLadder::detachAllObjects()"); + _mgm.clear(); for (uint i = 0; i < _ladmovements.size(); i++) { @@ -403,6 +424,8 @@ void MctlLadder::detachAllObjects() { } MessageQueue *MctlLadder::startMove(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { + debugC(4, kDebugPathfinding, "MctlLadder::startMove(*%d, %d, %d, %d, %d)", (subj ? subj->_id : -1), xpos, ypos, fuzzyMatch, staticsId); + MessageQueue *mq = doWalkTo(subj, xpos, ypos, fuzzyMatch, staticsId); if (mq) { @@ -414,6 +437,8 @@ MessageQueue *MctlLadder::startMove(StaticANIObject *subj, int xpos, int ypos, i } MessageQueue *MctlLadder::doWalkTo(StaticANIObject *ani, int xpos, int ypos, int fuzzyMatch, int staticsId) { + debugC(1, kDebugPathfinding, "MctlLadder::doWalkTo(*%d, %d, %d, %d, %d)", (ani ? ani->_id : -1), xpos, ypos, fuzzyMatch, staticsId); + int pos = findObjectPos(ani); if (pos < 0) @@ -707,11 +732,11 @@ void MovInfo1::clear() { } bool MctlCompoundArray::load(MfcArchive &file) { - debug(5, "MctlCompoundArray::load()"); + debugC(5, kDebugLoading, "MctlCompoundArray::load()"); int count = file.readUint32LE(); - debug(0, "MctlCompoundArray::count = %d", count); + debugC(0, kDebugLoading, "MctlCompoundArray::count = %d", count); assert(0); @@ -770,7 +795,7 @@ MovGraph::~MovGraph() { } bool MovGraph::load(MfcArchive &file) { - debug(5, "MovGraph::load()"); + debugC(5, kDebugLoading, "MovGraph::load()"); _links.load(file); _nodes.load(file); @@ -779,6 +804,8 @@ bool MovGraph::load(MfcArchive &file) { } void MovGraph::attachObject(StaticANIObject *obj) { + debugC(4, kDebugPathfinding, "MovGraph::attachObject(*%d)", obj->_id); + _mgm.clear(); _mgm.addItem(obj->_id); @@ -802,6 +829,8 @@ int MovGraph::detachObject(StaticANIObject *obj) { } void MovGraph::detachAllObjects() { + debugC(4, kDebugPathfinding, "MovGraph::detachAllObjects()"); + for (uint i = 0; i < _items.size(); i++) { _items[i]->free(); @@ -812,6 +841,8 @@ void MovGraph::detachAllObjects() { } Common::Array<MovItem *> *MovGraph::getPaths(StaticANIObject *ani, int x, int y, int flag1, int *rescount) { + debugC(4, kDebugPathfinding, "MovGraph::getPaths(*%d, %d, %d, %d, &rescount)", (ani ? ani->_id : -1), x, y, flag1); + *rescount = 0; if (_items.size() <= 0) @@ -878,6 +909,8 @@ bool MovGraph::setPosImmediate(StaticANIObject *obj, int x, int y) { } MessageQueue *MovGraph::startMove(StaticANIObject *ani, int xpos, int ypos, int fuzzyMatch, int staticsId) { + debugC(4, kDebugPathfinding, "MovGraph::startMove(*%d, %d, %d, %d, %d)", (ani ? ani->_id : -1), xpos, ypos, fuzzyMatch, staticsId); + if (!ani) { if (!_items.size()) return 0; @@ -955,6 +988,8 @@ void MovGraph::setSelFunc(MovArr *(*callback1)(StaticANIObject *ani, Common::Arr } bool MovGraph::resetPosition(StaticANIObject *ani, int flag) { + debugC(4, kDebugPathfinding, "MovGraph::resetPosition(*%d, %d)", (ani ? ani->_id : -1), flag); + int idx = getObjectIndex(ani); if (idx == -1) @@ -1017,6 +1052,8 @@ bool MovGraph::canDropInventory(StaticANIObject *ani, int x, int y) { } MessageQueue *MovGraph::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { + debugC(1, kDebugPathfinding, "MovGraph::doWalkTo(*%d, %d, %d, %d, %d)", (subj ? subj->_id : -1), xpos, ypos, fuzzyMatch, staticsId); + PicAniInfo picAniInfo; int ss; @@ -1095,6 +1132,8 @@ MessageQueue *MovGraph::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int } MessageQueue *MovGraph::sub1(StaticANIObject *ani, int x, int y, int stid, int x1, int y1, int stid2, int flag1) { + debugC(4, kDebugPathfinding, "MovGraph::sub1(*%d, %d, %d, %d, %d, %d, %d, %d)", (ani ? ani->_id : -1), x, y, stid, x1, y1, stid2, flag1); + PicAniInfo picinfo; ani->getPicAniInfo(&picinfo); @@ -1141,6 +1180,8 @@ MessageQueue *MovGraph::sub1(StaticANIObject *ani, int x, int y, int stid, int x } MessageQueue *MovGraph::makeWholeQueue(StaticANIObject *ani, MovArr *movarr, int staticsId) { + debugC(4, kDebugPathfinding, "MovGraph::makeWholeQueue(*%d, *, %d)", (ani ? ani->_id : -1), staticsId); + if (!movarr->_movStepCount) return 0; @@ -1227,6 +1268,8 @@ MessageQueue *MovGraph::makeWholeQueue(StaticANIObject *ani, MovArr *movarr, int } MessageQueue *MovGraph::method50(StaticANIObject *ani, MovArr *movarr, int staticsId) { + debugC(4, kDebugPathfinding, "MovGraph::method50(*%d, *, %d)", (ani ? ani->_id : -1), staticsId); + if (_items.size() == 0) return 0; @@ -1283,17 +1326,17 @@ MessageQueue *MovGraph::method50(StaticANIObject *ani, MovArr *movarr, int stati return mq; } -double MovGraph::calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch) { +double MovGraph::putToLink(Common::Point *point, MovGraphLink *link, int fuzzyMatch) { int n1x = link->_graphSrc->_x; int n1y = link->_graphSrc->_y; int n2x = link->_graphDst->_x; int n2y = link->_graphDst->_y; double dist1x = (double)(point->x - n1x); - double dist1y = (double)(n1y - point->y); + double dist1y = (double)(point->y - n1y); double dist2x = (double)(n2x - n1x); double dist2y = (double)(n2y - n1y); - double dist1 = sqrt(dist1y * dist1y + dist1x * dist1x); - double dist2 = ((double)(n1y - n2y) * dist1y + dist2x * dist1x) / link->_length / dist1; + double dist1 = sqrt(dist1x * dist1x + dist1y * dist1y); + double dist2 = (dist2y * dist1y + dist2x * dist1x) / link->_length / dist1; double distm = dist2 * dist1; double res = sqrt(1.0 - dist2 * dist2) * dist1; @@ -1320,6 +1363,8 @@ double MovGraph::calcDistance(Common::Point *point, MovGraphLink *link, int fuzz } void MovGraph::recalcLinkParams() { + debugC(4, kDebugPathfinding, "MovGraph::recalcLinkParams()"); + for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) { assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink); @@ -1332,6 +1377,8 @@ void MovGraph::recalcLinkParams() { } bool MovGraph::getNearestPoint(int unusedArg, Common::Point *p, MovArr *movarr) { + debugC(4, kDebugPathfinding, "MovGraph::getNearestPoint(...)"); + MovGraphLink *link = 0; double mindist = 1.0e20; int resx = 0, resy = 0; @@ -1395,6 +1442,8 @@ int MovGraph::getObjectIndex(StaticANIObject *ani) { } Common::Array<MovArr *> *MovGraph::getHitPoints(int x, int y, int *arrSize, int flag1, int flag2) { + debugC(4, kDebugPathfinding, "MovGraph::getHitPoints(...)"); + if (!_links.size()) { *arrSize = 0; @@ -1409,7 +1458,7 @@ Common::Array<MovArr *> *MovGraph::getHitPoints(int x, int y, int *arrSize, int if (flag1) { Common::Point point(x, y); - double dist = calcDistance(&point, lnk, 0); + double dist = putToLink(&point, lnk, 0); if (dist >= 0.0 && dist < 2.0) { movarr = new MovArr; @@ -1450,7 +1499,7 @@ Common::Array<MovArr *> *MovGraph::getHitPoints(int x, int y, int *arrSize, int movarr->_point.x = x; movarr->_point.y = y; - calcDistance(&movarr->_point, lnk, 0); + putToLink(&movarr->_point, lnk, 0); arr->push_back(movarr); } @@ -1465,6 +1514,8 @@ Common::Array<MovArr *> *MovGraph::getHitPoints(int x, int y, int *arrSize, int } void MovGraph::findAllPaths(MovGraphLink *lnk, MovGraphLink *lnk2, Common::Array<MovGraphLink *> &tempObList1, Common::Array<MovGraphLink *> &allPaths) { + debugC(4, kDebugPathfinding, "MovGraph::findAllPaths(...)"); + if (lnk == lnk2) { for (uint i = 0; i < tempObList1.size(); i++) allPaths.push_back(tempObList1[i]); @@ -1495,6 +1546,8 @@ void MovGraph::findAllPaths(MovGraphLink *lnk, MovGraphLink *lnk2, Common::Array // Returns a list of possible paths two points in graph space Common::Array<MovItem *> *MovGraph::getPaths(MovArr *currPos, MovArr *destPos, int *pathCount) { + debugC(4, kDebugPathfinding, "MovGraph::getPaths(...)"); + Common::Array<MovGraphLink *> tempObList1; Common::Array<MovGraphLink *> allPaths; @@ -1581,6 +1634,8 @@ bool MovGraph::getHitPoint(int idx, int x, int y, MovArr *arr, int a6) { } void MovGraph::setEnds(MovStep *step1, MovStep *step2) { + debugC(4, kDebugPathfinding, "MovGraph::setEnds(...)"); + if (step1->link->_graphSrc == step2->link->_graphDst) { step1->sfield_0 = 1; step2->sfield_0 = 1; @@ -1633,6 +1688,7 @@ int MovGraph2::getItemSubIndexByMGM(int index, StaticANIObject *ani) { int min = 0; for (int i = 0; i < 4; i++) { + debugC(1, kDebugPathfinding, "WWW 5"); int tmp = _mgm.refreshOffsets(ani->_id, ani->_statics->_staticsId, _items2[index]->_subItems[i]._staticsId1); if (tmp >= 0 && (minidx == -1 || tmp < min)) { @@ -1648,6 +1704,8 @@ int MovGraph2::getItemSubIndexByMGM(int index, StaticANIObject *ani) { } bool MovGraph2::initDirections(StaticANIObject *obj, MovGraph2Item *item) { + debugC(4, kDebugPathfinding, "MovGraph::initDirections(%d, ...)", obj->_id); + item->_obj = obj; item->_objectId = obj->_id; @@ -1777,6 +1835,8 @@ bool MovGraph2::initDirections(StaticANIObject *obj, MovGraph2Item *item) { } void MovGraph2::attachObject(StaticANIObject *obj) { + debugC(4, kDebugPathfinding, "MovGraph2::attachObject(*%d)", obj->_id); + MovGraph::attachObject(obj); int id = getItemIndexByGameObjectId(obj->_id); @@ -1795,6 +1855,8 @@ void MovGraph2::attachObject(StaticANIObject *obj) { } void MovGraph2::buildMovInfo1SubItems(MovInfo1 *movinfo, Common::Array<MovGraphLink *> *linkList, LinkInfo *lnkSrc, LinkInfo *lnkDst) { + debugC(4, kDebugPathfinding, "MovGraph2::buildMovInfo1SubItems(...)"); + MovInfo1Sub *elem; Common::Point point; Common::Rect rect; @@ -1904,6 +1966,8 @@ void MovGraph2::buildMovInfo1SubItems(MovInfo1 *movinfo, Common::Array<MovGraphL } MessageQueue *MovGraph2::buildMovInfo1MessageQueue(MovInfo1 *movInfo) { + debugC(4, kDebugPathfinding, "MovGraph2::buildMovInfo1MessageQueue(...)"); + MovInfo1 movinfo(movInfo); int curX = movInfo->pt1.x; @@ -2037,6 +2101,8 @@ int MovGraph2::detachObject(StaticANIObject *obj) { } void MovGraph2::detachAllObjects() { + debugC(4, kDebugPathfinding, "MovGraph2::detachAllObjects()"); + for (uint i = 0; i < _items2.size(); i++) delete _items2[i]; @@ -2044,12 +2110,15 @@ void MovGraph2::detachAllObjects() { } MessageQueue *MovGraph2::startMove(StaticANIObject *ani, int xpos, int ypos, int fuzzyMatch, int staticsId) { + debugC(4, kDebugPathfinding, "MovGraph2::startMove(*%d, %d, %d, %d, %d)", ani->_id, xpos, ypos, fuzzyMatch, staticsId); + if (!ani->isIdle()) return 0; if (ani->_flags & 0x100) return 0; + debugC(1, kDebugPathfinding, "WWW 3"); MessageQueue *mq = doWalkTo(ani, xpos, ypos, fuzzyMatch, staticsId); if (!mq) @@ -2091,7 +2160,7 @@ MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int PicAniInfo picAniInfo; Common::Point point; - debug(0, "MovGraph2::doWalkTo(%d, %d, %d, %d, %d)", obj->_id, xpos, ypos, fuzzyMatch, staticsId); + debugC(1, kDebugPathfinding, "MovGraph2::doWalkTo(%d, %d, %d, %d, %d)", obj->_id, xpos, ypos, fuzzyMatch, staticsId); int idx = getItemIndexByGameObjectId(obj->_id); @@ -2118,6 +2187,7 @@ MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int bool subMgm = false; if (idxsub == -1) { + debugC(1, kDebugPathfinding, "WWW 4"); idxsub = getItemSubIndexByMGM(idx, obj); subMgm = true; @@ -2223,7 +2293,7 @@ MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int Common::Array<MovGraphLink *> tempLinkList; double minPath = findMinPath(&linkInfoSource, &linkInfoDest, &tempLinkList); - debug(0, "MovGraph2::doWalkTo(): path: %g parts: %d", minPath, tempLinkList.size()); + debugC(0, kDebugPathfinding, "MovGraph2::doWalkTo(): path: %g parts: %d", minPath, tempLinkList.size()); if (minPath < 0.0 || ((linkInfoSource.node != linkInfoDest.node || !linkInfoSource.node) && !tempLinkList.size())) return 0; @@ -2261,7 +2331,7 @@ MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int movInfo1.distance2 = (int)(nod->_z + (dst1 * (double)dst / linkInfoDest.link->_length)); - calcDistance(&movInfo1.pt2, linkInfoDest.link, 1); + putToLink(&movInfo1.pt2, linkInfoDest.link, 1); dx1 = movInfo1.pt1.x; dy1 = movInfo1.pt1.y; @@ -2360,6 +2430,8 @@ int MovGraph2::getShortSide(MovGraphLink *lnk, int x, int y) { } int MovGraph2::findLink(Common::Array<MovGraphLink *> *linkList, int idx, Common::Rect *rect, Common::Point *point) { + debugC(4, kDebugPathfinding, "MovGraph2::findLink(...)"); + MovGraphNode *node1 = (*linkList)[idx]->_graphSrc; MovGraphNode *node2 = (*linkList)[idx]->_graphDst; MovGraphNode *node3 = node1; @@ -2407,6 +2479,8 @@ int MovGraph2::findLink(Common::Array<MovGraphLink *> *linkList, int idx, Common } MessageQueue *MovGraph2::genMovement(MovInfo1 *info) { + debugC(4, kDebugPathfinding, "MovGraph2::genMovement(...)"); + int mx1 = 0; int my1 = 0; @@ -2608,6 +2682,8 @@ MessageQueue *MovGraph2::genMovement(MovInfo1 *info) { } MovGraphLink *MovGraph2::findLink1(int x, int y, int idx, int fuzzyMatch) { + debugC(4, kDebugPathfinding, "MovGraph2::findLink1(...)"); + Common::Point point; MovGraphLink *res = 0; @@ -2619,7 +2695,7 @@ MovGraphLink *MovGraph2::findLink1(int x, int y, int idx, int fuzzyMatch) { if (fuzzyMatch) { point.x = x; point.y = y; - double dst = calcDistance(&point, lnk, 0); + double dst = putToLink(&point, lnk, 0); if (dst >= 0.0 && dst < 2.0) return lnk; @@ -2642,6 +2718,8 @@ MovGraphLink *MovGraph2::findLink1(int x, int y, int idx, int fuzzyMatch) { } MovGraphLink *MovGraph2::findLink2(int x, int y) { + debugC(4, kDebugPathfinding, "MovGraph2::findLink2(...)"); + double mindist = 1.0e20; MovGraphLink *res = 0; @@ -2684,6 +2762,8 @@ MovGraphLink *MovGraph2::findLink2(int x, int y) { } double MovGraph2::findMinPath(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Common::Array<MovGraphLink *> *listObj) { + debugC(4, kDebugPathfinding, "MovGraph2::findMinPath(...)"); + LinkInfo linkInfoWorkSource; if (linkInfoSource->link != linkInfoDest->link || linkInfoSource->node != linkInfoDest->node) { @@ -2796,22 +2876,22 @@ MovGraphLink::~MovGraphLink() { bool MovGraphLink::load(MfcArchive &file) { - debug(5, "MovGraphLink::load()"); + debugC(5, kDebugLoading, "MovGraphLink::load()"); _dwordArray1.load(file); _dwordArray2.load(file); _flags = file.readUint32LE(); - debug(8, "GraphNode1"); + debugC(8, kDebugLoading, "GraphNode1"); _graphSrc = (MovGraphNode *)file.readClass(); - debug(8, "GraphNode2"); + debugC(8, kDebugLoading, "GraphNode2"); _graphDst = (MovGraphNode *)file.readClass(); _length = file.readDouble(); _angle = file.readDouble(); - debug(8, "length: %g, angle: %g", _length, _angle); + debugC(8, kDebugLoading, "length: %g, angle: %g", _length, _angle); _movGraphReact = (MovGraphReact *)file.readClass(); _name = file.readPascalString(); @@ -2830,7 +2910,7 @@ void MovGraphLink::recalcLength() { } bool MovGraphNode::load(MfcArchive &file) { - debug(5, "MovGraphNode::load()"); + debugC(5, kDebugLoading, "MovGraphNode::load()"); _field_14 = file.readUint32LE(); _x = file.readUint32LE(); @@ -2850,7 +2930,7 @@ ReactParallel::ReactParallel() { } bool ReactParallel::load(MfcArchive &file) { - debug(5, "ReactParallel::load()"); + debugC(5, kDebugLoading, "ReactParallel::load()"); _x1 = file.readUint32LE(); _y1 = file.readUint32LE(); @@ -2908,7 +2988,7 @@ ReactPolygonal::~ReactPolygonal() { } bool ReactPolygonal::load(MfcArchive &file) { - debug(5, "ReactPolygonal::load()"); + debugC(5, kDebugLoading, "ReactPolygonal::load()"); _centerX = file.readUint32LE(); _centerY = file.readUint32LE(); diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h index b8c3ff1f43..41860e32d0 100644 --- a/engines/fullpipe/motion.h +++ b/engines/fullpipe/motion.h @@ -302,7 +302,7 @@ public: virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId); virtual MessageQueue *method50(StaticANIObject *ani, MovArr *movarr, int staticsId); - double calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch); + double putToLink(Common::Point *point, MovGraphLink *link, int fuzzyMatch); void recalcLinkParams(); bool getNearestPoint(int unusedArg, Common::Point *p, MovArr *movarr); MovGraphNode *calcOffset(int ox, int oy); diff --git a/engines/fullpipe/ngiarchive.cpp b/engines/fullpipe/ngiarchive.cpp index 132f4758d3..7d75dc2e78 100644 --- a/engines/fullpipe/ngiarchive.cpp +++ b/engines/fullpipe/ngiarchive.cpp @@ -93,11 +93,11 @@ NGIArchive::NGIArchive(const Common::String &filename) : _ngiFilename(filename) g_fp->_currArchive = this; - debug(0, "NGIArchive::NGIArchive(%s): Located %d files", filename.c_str(), _headers.size()); + debugC(0, kDebugLoading, "NGIArchive::NGIArchive(%s): Located %d files", filename.c_str(), _headers.size()); } NGIArchive::~NGIArchive() { - debug(0, "NGIArchive Destructor Called"); + debugC(0, kDebugLoading, "NGIArchive Destructor Called"); NgiHeadersMap::iterator it = _headers.begin(); for ( ; it != _headers.end(); ++it) { delete it->_value; diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp index 5a3fbe34b6..b47988d768 100644 --- a/engines/fullpipe/scene.cpp +++ b/engines/fullpipe/scene.cpp @@ -55,7 +55,7 @@ Scene *FullpipeEngine::accessScene(int sceneId) { } bool SceneTagList::load(MfcArchive &file) { - debug(5, "SceneTagList::load()"); + debugC(5, kDebugLoading, "SceneTagList::load()"); int numEntries = file.readUint16LE(); @@ -76,7 +76,7 @@ SceneTag::SceneTag() { } bool SceneTag::load(MfcArchive &file) { - debug(5, "SceneTag::load()"); + debugC(5, kDebugLoading, "SceneTag::load()"); _field_4 = 0; _scene = 0; @@ -85,7 +85,7 @@ bool SceneTag::load(MfcArchive &file) { _tag = file.readPascalString(); - debug(6, "sceneId: %d tag: %s", _sceneId, _tag); + debugC(6, kDebugLoading, "sceneId: %d tag: %s", _sceneId, _tag); return true; } @@ -157,7 +157,7 @@ Scene::~Scene() { } bool Scene::load(MfcArchive &file) { - debug(5, "Scene::load()"); + debugC(5, kDebugLoading, "Scene::load()"); Background::load(file); @@ -167,7 +167,7 @@ bool Scene::load(MfcArchive &file) { debug(0, "scene: <%s> %d", transCyrillic((byte *)_sceneName), _sceneId); int count = file.readUint16LE(); - debug(7, "scene.ani: %d", count); + debugC(7, kDebugLoading, "scene.ani: %d", count); for (int i = 0; i < count; i++) { int aniNum = file.readUint16LE(); @@ -189,7 +189,7 @@ bool Scene::load(MfcArchive &file) { } count = file.readUint16LE(); - debug(7, "scene.mq: %d", count); + debugC(7, kDebugLoading, "scene.mq: %d", count); for (int i = 0; i < count; i++) { int qNum = file.readUint16LE(); @@ -211,7 +211,7 @@ bool Scene::load(MfcArchive &file) { } count = file.readUint16LE(); - debug(7, "scene.fa: %d", count); + debugC(7, kDebugLoading, "scene.fa: %d", count); for (int i = 0; i < count; i++) { // There are no .FA files @@ -497,7 +497,7 @@ void Scene::objectList_sortByPriority(Common::Array<PictureObject *> &list, bool } void Scene::draw() { - debug(6, ">>>>> Scene::draw()"); + debugC(6, kDebugDrawing, ">>>>> Scene::draw()"); updateScrolling(); // Clean previous stuff @@ -640,7 +640,7 @@ int Scene::getPictureObjectIdAtPos(int x, int y) { } void Scene::update(int counterdiff) { - debug(6, "Scene::update(%d)", counterdiff); + debugC(6, kDebugDrawing, "Scene::update(%d)", counterdiff); for (uint i = 0; i < _staticANIObjectList2.size(); i++) _staticANIObjectList2[i]->update(counterdiff); @@ -654,7 +654,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) { g_fp->_globalPalette = _palette->_data; } - debug(1, "Scene::drawContent(>%d, <%d, %d)", minPri, maxPri, drawBg); + debugC(1, kDebugDrawing, "Scene::drawContent(>%d, <%d, %d)", minPri, maxPri, drawBg); if (_picObjList.size() > 2) { // We need to z-sort them objectList_sortByPriority(_picObjList, true); @@ -666,11 +666,11 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) { if (maxPri == -1) maxPri = 60000; - debug(1, "-> Scene::drawContent(>%d, <%d, %d)", minPri, maxPri, drawBg); + debugC(1, kDebugDrawing, "-> Scene::drawContent(>%d, <%d, %d)", minPri, maxPri, drawBg); Common::Point point; - debug(1, "_bigPict: %d objlist: %d", _bigPictureArray1Count, _picObjList.size()); + debugC(1, kDebugDrawing, "_bigPict: %d objlist: %d", _bigPictureArray1Count, _picObjList.size()); if (drawBg && _bigPictureArray1Count && _picObjList.size()) { @@ -679,11 +679,11 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) { int width = point.x; int height = point.y; - debug(8, "w: %d h:%d", width, height); + debugC(8, kDebugDrawing, "w: %d h:%d", width, height); ((PictureObject *)_picObjList[0])->getDimensions(&point); - debug(8, "w2: %d h2:%d", point.x, point.y); + debugC(8, kDebugDrawing, "w2: %d h2:%d", point.x, point.y); int bgStX = g_fp->_sceneRect.left % point.x; @@ -744,7 +744,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) { int objX = obj->_ox; int objY = obj->_oy; - debug(8, "obj: %d %d", objX, objY); + debugC(8, kDebugDrawing, "obj: %d %d", objX, objY); obj->getDimensions(&point); diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp index c82c2c414c..398e28d11b 100644 --- a/engines/fullpipe/sound.cpp +++ b/engines/fullpipe/sound.cpp @@ -44,7 +44,7 @@ SoundList::SoundList() { } bool SoundList::load(MfcArchive &file, char *fname) { - debug(5, "SoundList::load()"); + debugC(5, kDebugLoading, "SoundList::load()"); _soundItemsCount = file.readUint32LE(); _soundItems = (Sound **)calloc(_soundItemsCount, sizeof(Sound *)); @@ -107,7 +107,7 @@ Sound::~Sound() { } bool Sound::load(MfcArchive &file, NGIArchive *archive) { - debug(5, "Sound::load()"); + debugC(5, kDebugLoading, "Sound::load()"); MemoryObject::load(file); @@ -132,7 +132,7 @@ bool Sound::load(MfcArchive &file, NGIArchive *archive) { } void Sound::updateVolume() { - debug(3, "STUB Sound::updateVolume()"); + debug(9, "STUB Sound::updateVolume()"); } void Sound::setPanAndVolumeByStaticAni() { diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp index 141196c7d7..c95f6c67f3 100644 --- a/engines/fullpipe/stateloader.cpp +++ b/engines/fullpipe/stateloader.cpp @@ -112,7 +112,7 @@ GameProject::GameProject() { } bool GameProject::load(MfcArchive &file) { - debug(5, "GameProject::load()"); + debugC(5, kDebugLoading, "GameProject::load()"); _field_4 = 0; _headerFilename = 0; @@ -124,10 +124,10 @@ bool GameProject::load(MfcArchive &file) { _headerFilename = file.readPascalString(); - debug(1, "_gameProjectVersion = %d", g_fp->_gameProjectVersion); - debug(1, "_pictureScale = %d", g_fp->_pictureScale); - debug(1, "_scrollSpeed = %d", g_fp->_scrollSpeed); - debug(1, "_headerFilename = %s", _headerFilename); + debugC(1, kDebugLoading, "_gameProjectVersion = %d", g_fp->_gameProjectVersion); + debugC(1, kDebugLoading, "_pictureScale = %d", g_fp->_pictureScale); + debugC(1, kDebugLoading, "_scrollSpeed = %d", g_fp->_scrollSpeed); + debugC(1, kDebugLoading, "_headerFilename = %s", _headerFilename); _sceneTagList = new SceneTagList(); @@ -205,24 +205,24 @@ bool GameVar::load(MfcArchive &file) { _varName = file.readPascalString(); _varType = file.readUint32LE(); - debugN(6, "[%03d] ", file.getLevel()); + debugCN(6, kDebugLoading, "[%03d] ", file.getLevel()); for (int i = 0; i < file.getLevel(); i++) - debugN(6, " "); + debugCN(6, kDebugLoading, " "); - debugN(6, "<%s>: ", transCyrillic((byte *)_varName)); + debugCN(6, kDebugLoading, "<%s>: ", transCyrillic((byte *)_varName)); switch (_varType) { case 0: _value.intValue = file.readUint32LE(); - debug(6, "d --> %d", _value.intValue); + debugC(6, kDebugLoading, "d --> %d", _value.intValue); break; case 1: _value.intValue = file.readUint32LE(); // FIXME - debug(6, "f --> %f", _value.floatValue); + debugC(6, kDebugLoading, "f --> %f", _value.floatValue); break; case 2: _value.stringValue = file.readPascalString(); - debug(6, "s --> %s", _value.stringValue); + debugC(6, kDebugLoading, "s --> %s", _value.stringValue); break; default: error("Unknown var type: %d (0x%x)", _varType, _varType); @@ -342,7 +342,7 @@ GameVar *GameVar::getSubVarByIndex(int idx) { } bool PicAniInfo::load(MfcArchive &file) { - debug(5, "PicAniInfo::load()"); + debugC(5, kDebugLoading, "PicAniInfo::load()"); type = file.readUint32LE(); objectId = file.readUint16LE(); diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp index 36fbb73037..14245d5eaf 100644 --- a/engines/fullpipe/statics.cpp +++ b/engines/fullpipe/statics.cpp @@ -201,7 +201,7 @@ StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) { } bool StaticANIObject::load(MfcArchive &file) { - debug(5, "StaticANIObject::load()"); + debugC(5, kDebugLoading, "StaticANIObject::load()"); GameObject::load(file); @@ -215,7 +215,7 @@ bool StaticANIObject::load(MfcArchive &file) { } count = file.readUint16LE(); - debug(7, "Movements: %d", count); + debugC(7, kDebugLoading, "Movements: %d", count); for (int i = 0; i < count; i++) { int movNum = file.readUint16LE(); @@ -512,7 +512,7 @@ bool StaticANIObject::getPixelAtPos(int x, int y, int *pixel) { } void Movement::draw(bool flipFlag, int angle) { - debug(3, "Movement::draw(%d, %d)", flipFlag, angle); + debugC(3, kDebugDrawing, "Movement::draw(%d, %d)", flipFlag, angle); Common::Point point; @@ -594,7 +594,7 @@ void StaticANIObject::draw() { Common::Point point; Common::Rect rect; - debug(6, "StaticANIObject::draw() (%s) [%d] [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy); + debugC(6, kDebugDrawing, "StaticANIObject::draw() (%s) [%d] [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy); if (_shadowsOn && g_fp->_currentScene && g_fp->_currentScene->_shadows && (getCurrDimensions(point)->x != 1 || getCurrDimensions(point)->y != 1)) { @@ -654,7 +654,7 @@ void StaticANIObject::draw() { } void StaticANIObject::draw2() { - debug(6, "StatciANIObject::draw2(): id: (%s) %d [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy); + debugC(6, kDebugDrawing, "StatciANIObject::draw2(): id: (%s) %d [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy); if ((_flags & 4) && (_flags & 0x10)) { if (_movement) { @@ -779,7 +779,7 @@ Common::Point *StaticANIObject::getSomeXY(Common::Point &p) { void StaticANIObject::update(int counterdiff) { int mqid; - debug(6, "StaticANIObject::update() (%s) [%d] [%d, %d] fl: %x", transCyrillic((byte *)_objectName), _id, _ox, _oy, _flags); + debugC(6, kDebugAnimation, "StaticANIObject::update() (%s) [%d] [%d, %d] fl: %x", transCyrillic((byte *)_objectName), _id, _ox, _oy, _flags); if (_flags & 2) { _messageNum--; @@ -951,7 +951,7 @@ Common::Point *StaticANIObject::calcNextStep(Common::Point *pRes) { } void StaticANIObject::stopAnim_maybe() { - debug(6, "StaticANIObject::stopAnim_maybe()"); + debugC(6, kDebugAnimation, "StaticANIObject::stopAnim_maybe()"); if (!(_flags & 1)) return; @@ -1093,7 +1093,7 @@ void StaticANIObject::hide() { } void StaticANIObject::show1(int x, int y, int movId, int mqId) { - debug(6, "StaticANIObject::show1(%d, %d, %d, %d)", x, y, movId, mqId); + debugC(6, kDebugAnimation, "StaticANIObject::show1(%d, %d, %d, %d)", x, y, movId, mqId); if (_messageQueueId) return; @@ -1285,7 +1285,7 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase if (_flags & 0x80) return false; - debug(4, "StaticANIObject::startAnim(%d, %d, %d) (%s [%d]) [%d, %d]", movementId, messageQueueId, dynPhaseIdx, transCyrillic((byte *)_objectName), _id, _ox, _oy); + debugC(4, kDebugAnimation, "StaticANIObject::startAnim(%d, %d, %d) (%s [%d]) [%d, %d]", movementId, messageQueueId, dynPhaseIdx, transCyrillic((byte *)_objectName), _id, _ox, _oy); if (_messageQueueId) { updateGlobalMessageQueue(messageQueueId, _id); @@ -1444,14 +1444,14 @@ Statics::Statics(Statics *src, bool reverse) : DynamicPhase(src, reverse) { } bool Statics::load(MfcArchive &file) { - debug(5, "Statics::load()"); + debugC(5, kDebugLoading, "Statics::load()"); DynamicPhase::load(file); _staticsId = file.readUint16LE(); _staticsName = file.readPascalString(); - debug(7, "statics: <%s> id: %d (%x)", transCyrillic((byte *)_staticsName), _staticsId, _staticsId); + debugC(7, kDebugLoading, "statics: <%s> id: %d (%x)", transCyrillic((byte *)_staticsName), _staticsId, _staticsId); _picture = new Picture(); _picture->load(file); @@ -1670,7 +1670,7 @@ bool Movement::load(MfcArchive &file, StaticANIObject *ani) { int dynCount = file.readUint16LE(); - debug(7, "dynCount: %d _id: %d", dynCount, _id); + debugC(7, kDebugLoading, "dynCount: %d _id: %d", dynCount, _id); if (dynCount != 0xffff || _id == MV_MAN_TURN_LU) { _framePosOffsets = (Common::Point **)calloc(dynCount + 2, sizeof(Common::Point *)); @@ -1766,8 +1766,8 @@ Common::Point *Movement::calcSomeXY(Common::Point &p, int idx, int dynidx) { Common::Point point; _staticsObj1->getSomeXY(point); - int y1 = _my - point.y; int x1 = _mx - point.x; + int y1 = _my - point.y; setDynamicPhaseIndex(0); @@ -1826,7 +1826,7 @@ void Movement::initStatics(StaticANIObject *ani) { if (!_currMovement) return; - debug(7, "Movement::initStatics()"); + debugC(7, kDebugAnimation, "Movement::initStatics()"); _staticsObj2 = ani->addReverseStatics(_currMovement->_staticsObj2); _staticsObj1 = ani->addReverseStatics(_currMovement->_staticsObj1); @@ -1853,7 +1853,7 @@ void Movement::initStatics(StaticANIObject *ani) { } void Movement::updateCurrDynamicPhase() { - debug(7, "Movement::updateCurrDynamicPhase()"); + debugC(7, kDebugAnimation, "Movement::updateCurrDynamicPhase()"); if (_currMovement) { if (_currMovement->_dynamicPhases.size() == 0 || (uint)_currDynamicPhaseIndex >= _currMovement->_dynamicPhases.size()) @@ -1905,7 +1905,7 @@ int Movement::countPhasesWithFlag(int maxidx, int flag) { } void Movement::setDynamicPhaseIndex(int index) { - debug(7, "Movement::setDynamicPhaseIndex(%d)", index); + debugC(7, kDebugAnimation, "Movement::setDynamicPhaseIndex(%d)", index); while (_currDynamicPhaseIndex < index) gotoNextFrame(0, 0); @@ -1914,7 +1914,7 @@ void Movement::setDynamicPhaseIndex(int index) { } DynamicPhase *Movement::getDynamicPhaseByIndex(int idx) { - debug(7, "Movement::updateCurrDynamicPhase()"); + debugC(7, kDebugAnimation, "Movement::updateCurrDynamicPhase()"); if (_currMovement) { if (_currMovement->_dynamicPhases.size() == 0 || (uint)idx >= _currMovement->_dynamicPhases.size()) @@ -1973,7 +1973,7 @@ void Movement::removeFirstPhase() { } bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, int), void (*callback2)(int *)) { - debug(8, "Movement::gotoNextFrame()"); + debugC(8, kDebugAnimation, "Movement::gotoNextFrame()"); if (!callback2) { if (_currMovement) { @@ -2094,7 +2094,7 @@ bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, i } bool Movement::gotoPrevFrame() { - debug(8, "Movement::gotoPrevFrame()"); + debugC(8, kDebugAnimation, "Movement::gotoPrevFrame()"); if (!_currDynamicPhaseIndex) { gotoLastFrame(); @@ -2192,7 +2192,7 @@ DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) { _field_7E = 0; _rect = new Common::Rect(); - debug(1, "DynamicPhase::DynamicPhase(src, %d)", reverse); + debugC(1, kDebugAnimation, "DynamicPhase::DynamicPhase(src, %d)", reverse); if (reverse) { if (!src->_bitmap) @@ -2254,7 +2254,7 @@ DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) { } bool DynamicPhase::load(MfcArchive &file) { - debug(5, "DynamicPhase::load()"); + debugC(5, kDebugLoading, "DynamicPhase::load()"); StaticPhase::load(file); @@ -2290,7 +2290,7 @@ StaticPhase::~StaticPhase() { } bool StaticPhase::load(MfcArchive &file) { - debug(5, "StaticPhase::load()"); + debugC(5, kDebugLoading, "StaticPhase::load()"); Picture::load(file); diff --git a/engines/fullpipe/utils.cpp b/engines/fullpipe/utils.cpp index 0cc8bd83f4..a8e00468b5 100644 --- a/engines/fullpipe/utils.cpp +++ b/engines/fullpipe/utils.cpp @@ -45,13 +45,13 @@ bool CObject::loadFile(const char *fname) { } bool ObList::load(MfcArchive &file) { - debug(5, "ObList::load()"); + debugC(5, kDebugLoading, "ObList::load()"); int count = file.readCount(); - debug(9, "ObList::count: %d:", count); + debugC(9, kDebugLoading, "ObList::count: %d:", count); for (int i = 0; i < count; i++) { - debug(9, "ObList::[%d]", i); + debugC(9, kDebugLoading, "ObList::[%d]", i); CObject *t = file.readClass(); push_back(t); @@ -61,7 +61,7 @@ bool ObList::load(MfcArchive &file) { } bool ObArray::load(MfcArchive &file) { - debug(5, "ObArray::load()"); + debugC(5, kDebugLoading, "ObArray::load()"); int count = file.readCount(); resize(count); @@ -76,10 +76,10 @@ bool ObArray::load(MfcArchive &file) { } bool DWordArray::load(MfcArchive &file) { - debug(5, "DWordArray::load()"); + debugC(5, kDebugLoading, "DWordArray::load()"); int count = file.readCount(); - debug(9, "DWordArray::count: %d", count); + debugC(9, kDebugLoading, "DWordArray::count: %d", count); resize(count); @@ -104,7 +104,7 @@ char *MfcArchive::readPascalString(bool twoByte) { tmp = (char *)calloc(len + 1, 1); read(tmp, len); - debug(9, "readPascalString: %d <%s>", len, transCyrillic((byte *)tmp)); + debugC(9, kDebugLoading, "readPascalString: %d <%s>", len, transCyrillic((byte *)tmp)); return tmp; } @@ -128,7 +128,7 @@ MemoryObject::~MemoryObject() { } bool MemoryObject::load(MfcArchive &file) { - debug(5, "MemoryObject::load()"); + debugC(5, kDebugLoading, "MemoryObject::load()"); _memfilename = file.readPascalString(); if (char *p = strchr(_memfilename, '\\')) { @@ -147,7 +147,7 @@ bool MemoryObject::load(MfcArchive &file) { } void MemoryObject::loadFile(char *filename) { - debug(5, "MemoryObject::loadFile(<%s>)", filename); + debugC(5, kDebugLoading, "MemoryObject::loadFile(<%s>)", filename); if (!*filename) return; @@ -165,7 +165,7 @@ void MemoryObject::loadFile(char *filename) { _dataSize = s->size(); - debug(5, "Loading %s (%d bytes)", filename, _dataSize); + debugC(5, kDebugLoading, "Loading %s (%d bytes)", filename, _dataSize); _data = (byte *)calloc(_dataSize, 1); s->read(_data, _dataSize); @@ -194,7 +194,7 @@ byte *MemoryObject::loadData() { } void MemoryObject::freeData() { - debug(8, "MemoryObject::freeData(): file: %s", _memfilename); + debugC(8, kDebugMemory, "MemoryObject::freeData(): file: %s", _memfilename); if (_data) free(_data); @@ -222,12 +222,12 @@ MemoryObject2::~MemoryObject2() { } bool MemoryObject2::load(MfcArchive &file) { - debug(5, "MemoryObject2::load()"); + debugC(5, kDebugLoading, "MemoryObject2::load()"); MemoryObject::load(file); _mflags |= 1; - debug(5, "MemoryObject2::load: <%s>", _memfilename); + debugC(5, kDebugLoading, "MemoryObject2::load: <%s>", _memfilename); if (_memfilename && *_memfilename) { MemoryObject::loadFile(_memfilename); @@ -262,15 +262,11 @@ double MfcArchive::readDouble() { // http://randomascii.wordpress.com/2012/01/11/tricks-with-the-floating-point-format/ union { - struct { - int32 a; - int32 b; - } i; + byte b[8]; double d; } tmp; - tmp.i.a = readUint32LE(); - tmp.i.b = readUint32LE(); + read(&tmp.b, 8); return tmp.d; } @@ -381,15 +377,15 @@ CObject *MfcArchive::parseClass(bool *isCopyReturned) { uint obTag = readUint16LE(); - debug(7, "parseClass::obTag = %d (%04x) at 0x%08x", obTag, obTag, pos() - 2); + debugC(7, kDebugLoading, "parseClass::obTag = %d (%04x) at 0x%08x", obTag, obTag, pos() - 2); if (obTag == 0xffff) { int schema = readUint16LE(); - debug(7, "parseClass::schema = %d", schema); + debugC(7, kDebugLoading, "parseClass::schema = %d", schema); name = readPascalString(true); - debug(7, "parseClass::class <%s>", name); + debugC(7, kDebugLoading, "parseClass::class <%s>", name); if (!_classMap.contains(name)) { error("Unknown class in MfcArchive: <%s>", name); @@ -397,7 +393,7 @@ CObject *MfcArchive::parseClass(bool *isCopyReturned) { objectId = _classMap[name]; - debug(7, "tag: %d 0x%x (%x)", _objectMap.size() - 1, _objectMap.size() - 1, objectId); + debugC(7, kDebugLoading, "tag: %d 0x%x (%x)", _objectMap.size() - 1, _objectMap.size() - 1, objectId); res = createObject(objectId); _objectMap.push_back(res); @@ -411,7 +407,7 @@ CObject *MfcArchive::parseClass(bool *isCopyReturned) { if (_objectMap.size() < obTag) { error("Object index too big: %d at 0x%08x", obTag, pos() - 2); } - debug(7, "parseClass::obTag <%s>", lookupObjectId(_objectIdMap[obTag])); + debugC(7, kDebugLoading, "parseClass::obTag <%s>", lookupObjectId(_objectIdMap[obTag])); res = _objectMap[obTag]; @@ -424,7 +420,7 @@ CObject *MfcArchive::parseClass(bool *isCopyReturned) { error("Object index too big: %d at 0x%08x", obTag, pos() - 2); } - debug(7, "parseClass::obTag <%s>", lookupObjectId(_objectIdMap[obTag])); + debugC(7, kDebugLoading, "parseClass::obTag <%s>", lookupObjectId(_objectIdMap[obTag])); objectId = _objectIdMap[obTag]; @@ -447,7 +443,7 @@ char *genFileName(int superId, int sceneId, const char *ext) { snprintf(s, 255, "%04d.%s", sceneId, ext); } - debug(7, "genFileName: %s", s); + debugC(7, kDebugLoading, "genFileName: %s", s); return s; } diff --git a/engines/gnap/gnap.cpp b/engines/gnap/gnap.cpp index 6a03bf8eb0..809e711e4f 100644 --- a/engines/gnap/gnap.cpp +++ b/engines/gnap/gnap.cpp @@ -91,9 +91,10 @@ static const char *kSceneNames[] = { GnapEngine::GnapEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst), _gameDescription(gd) { - _random = new Common::RandomSource("gnap"); DebugMan.addDebugChannel(kDebugBasic, "basic", "Basic debug level"); + _random = new Common::RandomSource("gnap"); + Engine::syncSoundSettings(); _exe = nullptr; diff --git a/engines/gnap/scenes/group4.cpp b/engines/gnap/scenes/group4.cpp index f37be2c25d..814588d9ba 100644 --- a/engines/gnap/scenes/group4.cpp +++ b/engines/gnap/scenes/group4.cpp @@ -2691,7 +2691,7 @@ void Scene46::run() { case kHS46WalkArea1: if (gnap._actionStatus < 0) gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); - break; + break; } } diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index dfbff33c63..605f1ed5b9 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -115,6 +115,19 @@ void PauseDialog::handleKeyDown(Common::KeyState state) { GobEngine::GobEngine(OSystem *syst) : Engine(syst), _rnd("gob") { + DebugMan.addDebugChannel(kDebugFuncOp, "FuncOpcodes", "Script FuncOpcodes debug level"); + DebugMan.addDebugChannel(kDebugDrawOp, "DrawOpcodes", "Script DrawOpcodes debug level"); + DebugMan.addDebugChannel(kDebugGobOp, "GoblinOpcodes", "Script GoblinOpcodes debug level"); + DebugMan.addDebugChannel(kDebugSound, "Sound", "Sound output debug level"); + DebugMan.addDebugChannel(kDebugExpression, "Expression", "Expression parser debug level"); + DebugMan.addDebugChannel(kDebugGameFlow, "Gameflow", "Gameflow debug level"); + DebugMan.addDebugChannel(kDebugFileIO, "FileIO", "File Input/Output debug level"); + DebugMan.addDebugChannel(kDebugSaveLoad, "SaveLoad", "Saving/Loading debug level"); + DebugMan.addDebugChannel(kDebugGraphics, "Graphics", "Graphics debug level"); + DebugMan.addDebugChannel(kDebugVideo, "Video", "IMD/VMD video debug level"); + DebugMan.addDebugChannel(kDebugHotspots, "Hotspots", "Hotspots debug level"); + DebugMan.addDebugChannel(kDebugDemo, "Demo", "Demo script debug level"); + _sound = 0; _mult = 0; _game = 0; _global = 0; _dataIO = 0; _goblin = 0; _vidPlayer = 0; _init = 0; _inter = 0; @@ -136,19 +149,6 @@ GobEngine::GobEngine(OSystem *syst) : Engine(syst), _rnd("gob") { _copyProtection = ConfMan.getBool("copy_protection"); _console = new GobConsole(this); - - DebugMan.addDebugChannel(kDebugFuncOp, "FuncOpcodes", "Script FuncOpcodes debug level"); - DebugMan.addDebugChannel(kDebugDrawOp, "DrawOpcodes", "Script DrawOpcodes debug level"); - DebugMan.addDebugChannel(kDebugGobOp, "GoblinOpcodes", "Script GoblinOpcodes debug level"); - DebugMan.addDebugChannel(kDebugSound, "Sound", "Sound output debug level"); - DebugMan.addDebugChannel(kDebugExpression, "Expression", "Expression parser debug level"); - DebugMan.addDebugChannel(kDebugGameFlow, "Gameflow", "Gameflow debug level"); - DebugMan.addDebugChannel(kDebugFileIO, "FileIO", "File Input/Output debug level"); - DebugMan.addDebugChannel(kDebugSaveLoad, "SaveLoad", "Saving/Loading debug level"); - DebugMan.addDebugChannel(kDebugGraphics, "Graphics", "Graphics debug level"); - DebugMan.addDebugChannel(kDebugVideo, "Video", "IMD/VMD video debug level"); - DebugMan.addDebugChannel(kDebugHotspots, "Hotspots", "Hotspots debug level"); - DebugMan.addDebugChannel(kDebugDemo, "Demo", "Demo script debug level"); } GobEngine::~GobEngine() { diff --git a/engines/groovie/groovie.cpp b/engines/groovie/groovie.cpp index ac77ec3099..2ba4ed18ab 100644 --- a/engines/groovie/groovie.cpp +++ b/engines/groovie/groovie.cpp @@ -53,17 +53,6 @@ GroovieEngine::GroovieEngine(OSystem *syst, const GroovieGameDescription *gd) : _graphicsMan(NULL), _macResFork(NULL), _waitingForInput(false), _font(NULL), _spookyMode(false) { - // Adding the default directories - const Common::FSNode gameDataDir(ConfMan.get("path")); - SearchMan.addSubDirectoryMatching(gameDataDir, "groovie"); - SearchMan.addSubDirectoryMatching(gameDataDir, "media"); - SearchMan.addSubDirectoryMatching(gameDataDir, "system"); - SearchMan.addSubDirectoryMatching(gameDataDir, "MIDI"); - - _modeSpeed = kGroovieSpeedNormal; - if (ConfMan.hasKey("fast_movie_speed") && ConfMan.getBool("fast_movie_speed")) - _modeSpeed = kGroovieSpeedFast; - // Initialize the custom debug levels DebugMan.addDebugChannel(kDebugVideo, "Video", "Debug video and audio playback"); DebugMan.addDebugChannel(kDebugResource, "Resource", "Debug resource management"); @@ -75,6 +64,17 @@ GroovieEngine::GroovieEngine(OSystem *syst, const GroovieGameDescription *gd) : DebugMan.addDebugChannel(kDebugScriptvars, "Scriptvars", "Print out any change to script variables"); DebugMan.addDebugChannel(kDebugCell, "Cell", "Debug the cell game (in the microscope)"); DebugMan.addDebugChannel(kDebugFast, "Fast", "Play videos quickly, with no sound (unstable)"); + + // Adding the default directories + const Common::FSNode gameDataDir(ConfMan.get("path")); + SearchMan.addSubDirectoryMatching(gameDataDir, "groovie"); + SearchMan.addSubDirectoryMatching(gameDataDir, "media"); + SearchMan.addSubDirectoryMatching(gameDataDir, "system"); + SearchMan.addSubDirectoryMatching(gameDataDir, "MIDI"); + + _modeSpeed = kGroovieSpeedNormal; + if (ConfMan.hasKey("fast_movie_speed") && ConfMan.getBool("fast_movie_speed")) + _modeSpeed = kGroovieSpeedFast; } GroovieEngine::~GroovieEngine() { diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index e99321ddcb..65f31985d6 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -39,7 +39,7 @@ namespace Kyra { -#define RESFILE_VERSION 88 +#define RESFILE_VERSION 89 namespace { bool checkKyraDat(Common::SeekableReadStream *file) { diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp index 5776d813cf..414473bb82 100644 --- a/engines/mads/mads.cpp +++ b/engines/mads/mads.cpp @@ -38,6 +38,11 @@ namespace MADS { MADSEngine::MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc) : _gameDescription(gameDesc), Engine(syst), _randomSource("MADS") { + // Set up debug channels + DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); + DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts"); + DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling"); + // Initialize game/engine options _easyMouse = true; _invObjectsAnimated = true; @@ -78,11 +83,6 @@ MADSEngine::~MADSEngine() { } void MADSEngine::initialize() { - // Set up debug channels - DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); - DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts"); - DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling"); - // Initial sub-system engine references MSurface::setVm(this); MSprite::setVm(this); diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp index b17b6e93b8..79d5256c1c 100644 --- a/engines/mads/screen.cpp +++ b/engines/mads/screen.cpp @@ -671,7 +671,7 @@ void Screen::transition(ScreenTransition transitionType, bool surfaceFlag) { void Screen::panTransition(MSurface &newScreen, byte *palData, int entrySide, const Common::Point &srcPos, const Common::Point &destPos, - ThroughBlack throughBlack, bool setPalette, int numTicks) { + ThroughBlack throughBlack, bool setPalette_, int numTicks) { EventsManager &events = *_vm->_events; Palette &palette = *_vm->_palette; Common::Point size; @@ -693,7 +693,7 @@ void Screen::panTransition(MSurface &newScreen, byte *palData, int entrySide, startX = size.x - 1; deltaX = startX ? -1 : 1; - if (setPalette & !throughBlack) + if (setPalette_ & !throughBlack) palette.setFullPalette(palData); // TODO: Original uses a different frequency ticks counter. Need to @@ -731,7 +731,7 @@ void Screen::panTransition(MSurface &newScreen, byte *palData, int entrySide, g_system->delayMillis(1); } - if ((setPalette && !loop) || throughBlack == THROUGH_BLACK2) + if ((setPalette_ && !loop) || throughBlack == THROUGH_BLACK2) palette.setFullPalette(palData); } diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp index fd79e53b07..f08eee9677 100644 --- a/engines/mohawk/console.cpp +++ b/engines/mohawk/console.cpp @@ -42,6 +42,7 @@ #ifdef ENABLE_RIVEN #include "mohawk/riven.h" #include "mohawk/riven_external.h" +#include "mohawk/riven_sound.h" #endif namespace Mohawk { diff --git a/engines/mohawk/cstime.cpp b/engines/mohawk/cstime.cpp index 3b26378819..b2889be714 100644 --- a/engines/mohawk/cstime.cpp +++ b/engines/mohawk/cstime.cpp @@ -54,6 +54,7 @@ MohawkEngine_CSTime::MohawkEngine_CSTime(OSystem *syst, const MohawkGameDescript _console = 0; _gfx = 0; + _sound = 0; _cursor = 0; _interface = 0; _view = 0; @@ -66,6 +67,7 @@ MohawkEngine_CSTime::~MohawkEngine_CSTime() { delete _interface; delete _view; delete _console; + delete _sound; delete _gfx; delete _rnd; } @@ -75,6 +77,7 @@ Common::Error MohawkEngine_CSTime::run() { _console = new CSTimeConsole(this); _gfx = new CSTimeGraphics(this); + _sound = new Sound(this); _cursor = new DefaultCursorManager(this, ID_CURS); _interface = new CSTimeInterface(this); diff --git a/engines/mohawk/cstime.h b/engines/mohawk/cstime.h index bfb7daf945..393032aaa9 100644 --- a/engines/mohawk/cstime.h +++ b/engines/mohawk/cstime.h @@ -136,6 +136,7 @@ public: Common::RandomSource *_rnd; + Sound *_sound; CSTimeGraphics *_gfx; bool _needsUpdate; diff --git a/engines/mohawk/dialogs.cpp b/engines/mohawk/dialogs.cpp index 8c11e3a5e9..38be98dfec 100644 --- a/engines/mohawk/dialogs.cpp +++ b/engines/mohawk/dialogs.cpp @@ -92,7 +92,7 @@ enum { MohawkOptionsDialog::MohawkOptionsDialog(MohawkEngine *vm) : GUI::Dialog(0, 0, 360, 200), - _vm(vm) { + _vm(vm), _loadSlot(-1) { _loadButton = new GUI::ButtonWidget(this, 245, 25, 100, 25, _("~L~oad"), 0, kLoadCmd); _saveButton = new GUI::ButtonWidget(this, 245, 60, 100, 25, _("~S~ave"), 0, kSaveCmd); new GUI::ButtonWidget(this, 245, 95, 100, 25, _("~Q~uit"), 0, kQuitCmd); @@ -112,6 +112,7 @@ MohawkOptionsDialog::~MohawkOptionsDialog() { void MohawkOptionsDialog::open() { GUI::Dialog::open(); + _loadSlot = -1; _loadButton->setEnabled(_vm->canLoadGameStateCurrently()); _saveButton->setEnabled(_vm->canSaveGameStateCurrently()); } @@ -133,12 +134,14 @@ void MohawkOptionsDialog::save() { } void MohawkOptionsDialog::load() { - int slot = _loadDialog->runModalWithCurrentTarget(); + // Do not load the game state from insite the dialog loop to + // avoid mouse cursor glitches (see bug #7164). Instead store + // the slot to load and let the code exectuting the dialog do + // the load after the dialog finished running. + _loadSlot = _loadDialog->runModalWithCurrentTarget(); - if (slot >= 0) { - _vm->loadGameState(slot); + if (_loadSlot >= 0) close(); - } } void MohawkOptionsDialog::reflowLayout() { diff --git a/engines/mohawk/dialogs.h b/engines/mohawk/dialogs.h index 3cfb628f9d..99db641948 100644 --- a/engines/mohawk/dialogs.h +++ b/engines/mohawk/dialogs.h @@ -81,6 +81,8 @@ public: virtual void open() override; virtual void reflowLayout() override; virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) override; + + int getLoadSlot() const {return _loadSlot;} private: MohawkEngine *_vm; @@ -90,6 +92,8 @@ private: GUI::SaveLoadChooser *_loadDialog; GUI::SaveLoadChooser *_saveDialog; + + int _loadSlot; void save(); void load(); diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp index 5af8fac901..579e3792b3 100644 --- a/engines/mohawk/livingbooks.cpp +++ b/engines/mohawk/livingbooks.cpp @@ -144,6 +144,7 @@ MohawkEngine_LivingBooks::MohawkEngine_LivingBooks(OSystem *syst, const MohawkGa _rnd = new Common::RandomSource("livingbooks"); + _sound = NULL; _page = NULL; const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -158,6 +159,7 @@ MohawkEngine_LivingBooks::~MohawkEngine_LivingBooks() { destroyPage(); delete _console; + delete _sound; delete _gfx; delete _rnd; _bookInfoFile.clear(); @@ -182,6 +184,7 @@ Common::Error MohawkEngine_LivingBooks::run() { error("Could not find xRes/yRes variables"); _gfx = new LBGraphics(this, _screenWidth, _screenHeight); + _sound = new Sound(this); if (getGameType() != GType_LIVINGBOOKSV1) _cursor = new LivingBooksCursorManager_v2(); diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h index 1a265a1a02..cf67c1ee8e 100644 --- a/engines/mohawk/livingbooks.h +++ b/engines/mohawk/livingbooks.h @@ -714,6 +714,7 @@ public: Common::RandomSource *_rnd; + Sound *_sound; LBGraphics *_gfx; bool _needsRedraw, _needsUpdate; diff --git a/engines/mohawk/module.mk b/engines/mohawk/module.mk index 83e541e3e4..3fc118d2b6 100644 --- a/engines/mohawk/module.mk +++ b/engines/mohawk/module.mk @@ -57,6 +57,7 @@ MODULE_OBJS += \ riven_graphics.o \ riven_saveload.o \ riven_scripts.o \ + riven_sound.o \ riven_vars.o endif diff --git a/engines/mohawk/mohawk.cpp b/engines/mohawk/mohawk.cpp index d740d9479a..b38409f9f1 100644 --- a/engines/mohawk/mohawk.cpp +++ b/engines/mohawk/mohawk.cpp @@ -40,14 +40,12 @@ MohawkEngine::MohawkEngine(OSystem *syst, const MohawkGameDescription *gamedesc) // Setup mixer syncSoundSettings(); - _sound = 0; _video = 0; _pauseDialog = 0; _cursor = 0; } MohawkEngine::~MohawkEngine() { - delete _sound; delete _video; delete _pauseDialog; delete _cursor; @@ -58,7 +56,6 @@ MohawkEngine::~MohawkEngine() { } Common::Error MohawkEngine::run() { - _sound = new Sound(this); _video = new VideoManager(this); _pauseDialog = new PauseDialog(this, "The game is paused. Press any key to continue."); @@ -66,14 +63,12 @@ Common::Error MohawkEngine::run() { } void MohawkEngine::pauseEngineIntern(bool pause) { + Engine::pauseEngineIntern(pause); + if (pause) { _video->pauseVideos(); - _sound->pauseSound(); - _sound->pauseSLST(); } else { _video->resumeVideos(); - _sound->resumeSound(); - _sound->resumeSLST(); _system->updateScreen(); } } diff --git a/engines/mohawk/mohawk.h b/engines/mohawk/mohawk.h index ac91dca971..bc0d642bce 100644 --- a/engines/mohawk/mohawk.h +++ b/engines/mohawk/mohawk.h @@ -100,7 +100,6 @@ public: bool hasFeature(EngineFeature f) const; - Sound *_sound; VideoManager *_video; CursorManager *_cursor; diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp index 633b67f7e9..3c00c1e11b 100644 --- a/engines/mohawk/myst.cpp +++ b/engines/mohawk/myst.cpp @@ -75,6 +75,7 @@ MohawkEngine_Myst::MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription _curResource = -1; _hoverResource = nullptr; + _sound = nullptr; _gfx = nullptr; _console = nullptr; _scriptParser = nullptr; @@ -88,6 +89,7 @@ MohawkEngine_Myst::~MohawkEngine_Myst() { DebugMan.clearAllDebugChannels(); delete _gfx; + delete _sound; delete _console; delete _scriptParser; delete _gameState; @@ -220,6 +222,7 @@ Common::Error MohawkEngine_Myst::run() { MohawkEngine::run(); _gfx = new MystGraphics(this); + _sound = new Sound(this); _console = new MystConsole(this); _gameState = new MystGameState(this, _saveFileMan); _optionsDialog = new MystOptionsDialog(this); @@ -309,6 +312,8 @@ Common::Error MohawkEngine_Myst::run() { _canSafelySaveLoad = true; runDialog(*_optionsDialog); + if (_optionsDialog->getLoadSlot() >= 0) + loadGameState(_optionsDialog->getLoadSlot()); _canSafelySaveLoad = false; if (_needsPageDrop) { diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h index 0b249e5499..0491e853b6 100644 --- a/engines/mohawk/myst.h +++ b/engines/mohawk/myst.h @@ -200,6 +200,7 @@ public: bool _showResourceRects; + Sound *_sound; MystGraphics *_gfx; MystGameState *_gameState; MystScriptParser *_scriptParser; diff --git a/engines/mohawk/myst_state.cpp b/engines/mohawk/myst_state.cpp index 4324d6bde5..213a976413 100644 --- a/engines/mohawk/myst_state.cpp +++ b/engines/mohawk/myst_state.cpp @@ -120,6 +120,7 @@ bool MystGameState::load(int slot) { _vm->changeToStack(kIntroStack, 5, 0, 0); // Set our default cursor + _vm->_cursor->showCursor(); if (_globals.heldPage == 0 || _globals.heldPage > 13) _vm->setMainCursor(kDefaultMystCursor); else if (_globals.heldPage < 7) diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index aa168a38d8..b7c83c0ff8 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -34,8 +34,8 @@ #include "mohawk/riven_external.h" #include "mohawk/riven_graphics.h" #include "mohawk/riven_saveload.h" +#include "mohawk/riven_sound.h" #include "mohawk/dialogs.h" -#include "mohawk/sound.h" #include "mohawk/video.h" #include "mohawk/console.h" @@ -59,6 +59,7 @@ MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescriptio _curStack = kStackUnknown; _hotspots = nullptr; _gfx = nullptr; + _sound = nullptr; _externalScriptHandler = nullptr; _rnd = nullptr; _scriptMan = nullptr; @@ -92,6 +93,7 @@ MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescriptio } MohawkEngine_Riven::~MohawkEngine_Riven() { + delete _sound; delete _gfx; delete _console; delete _externalScriptHandler; @@ -123,6 +125,7 @@ Common::Error MohawkEngine_Riven::run() { SearchMan.add("arcriven.z", &_installerArchive, 0, false); _gfx = new RivenGraphics(this); + _sound = new RivenSoundManager(this); _console = new RivenConsole(this); _saveLoad = new RivenSaveLoad(this, _saveFileMan); _externalScriptHandler = new RivenExternal(this); @@ -199,6 +202,7 @@ Common::Error MohawkEngine_Riven::run() { void MohawkEngine_Riven::handleEvents() { // Update background running things checkTimer(); + _sound->updateSLST(); bool needsUpdate = _gfx->runScheduledWaterEffects(); needsUpdate |= _video->updateMovies(); @@ -258,6 +262,8 @@ void MohawkEngine_Riven::handleEvents() { break; case Common::KEYCODE_F5: runDialog(*_optionsDialog); + if (_optionsDialog->getLoadSlot() >= 0) + loadGameState(_optionsDialog->getLoadSlot()); updateZipMode(); break; case Common::KEYCODE_r: @@ -708,6 +714,7 @@ void MohawkEngine_Riven::delayAndUpdate(uint32 ms) { uint32 startTime = _system->getMillis(); while (_system->getMillis() < startTime + ms && !shouldQuit()) { + _sound->updateSLST(); bool needsUpdate = _gfx->runScheduledWaterEffects(); needsUpdate |= _video->updateMovies(); diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h index 3ea50bb38d..ce819ac970 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -41,6 +41,7 @@ class RivenExternal; class RivenConsole; class RivenSaveLoad; class RivenOptionsDialog; +class RivenSoundManager; // Riven Stack Types enum { @@ -121,6 +122,7 @@ public: MohawkEngine_Riven(OSystem *syst, const MohawkGameDescription *gamedesc); virtual ~MohawkEngine_Riven(); + RivenSoundManager *_sound; RivenGraphics *_gfx; RivenExternal *_externalScriptHandler; Common::RandomSource *_rnd; diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp index 00075039fe..125630445e 100644 --- a/engines/mohawk/riven_external.cpp +++ b/engines/mohawk/riven_external.cpp @@ -24,7 +24,7 @@ #include "mohawk/riven.h" #include "mohawk/riven_external.h" #include "mohawk/riven_graphics.h" -#include "mohawk/sound.h" +#include "mohawk/riven_sound.h" #include "mohawk/video.h" #include "gui/message.h" @@ -2429,7 +2429,7 @@ void RivenExternal::xtexterior300_telescopedown(uint16 argc, uint16 *argv) { // Play the sound of not being able to move _vm->_cursor->setCursor(kRivenHideCursor); _vm->_system->updateScreen(); - _vm->_sound->playSoundBlocking(13); + _vm->_sound->playSound(13); } } else { // We're not at the bottom, and we can move down again @@ -2463,7 +2463,7 @@ void RivenExternal::xtexterior300_telescopeup(uint16 argc, uint16 *argv) { // Play the sound of not being able to move _vm->_cursor->setCursor(kRivenHideCursor); _vm->_system->updateScreen(); - _vm->_sound->playSoundBlocking(13); + _vm->_sound->playSound(13); return; } diff --git a/engines/mohawk/riven_graphics.cpp b/engines/mohawk/riven_graphics.cpp index db22dde22d..b583bc9710 100644 --- a/engines/mohawk/riven_graphics.cpp +++ b/engines/mohawk/riven_graphics.cpp @@ -23,6 +23,7 @@ #include "mohawk/resource.h" #include "mohawk/riven.h" #include "mohawk/riven_graphics.h" +#include "mohawk/riven_sound.h" #include "common/system.h" #include "engines/util.h" @@ -111,6 +112,7 @@ void RivenGraphics::drawPLST(uint16 x) { void RivenGraphics::updateScreen(Common::Rect updateRect) { if (_updatesEnabled) { _vm->runUpdateScreenScript(); + _vm->_sound->triggerDrawSound(); if (_dirtyScreen) { _activatedPLSTs.clear(); diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp index caa235ec8b..3655452603 100644 --- a/engines/mohawk/riven_scripts.cpp +++ b/engines/mohawk/riven_scripts.cpp @@ -25,7 +25,7 @@ #include "mohawk/riven_external.h" #include "mohawk/riven_graphics.h" #include "mohawk/riven_scripts.h" -#include "mohawk/sound.h" +#include "mohawk/riven_sound.h" #include "mohawk/video.h" #include "common/memstream.h" @@ -309,54 +309,44 @@ void RivenScript::switchCard(uint16 op, uint16 argc, uint16 *argv) { // Command 3: play an SLST from the script void RivenScript::playScriptSLST(uint16 op, uint16 argc, uint16 *argv) { - SLSTRecord slstRecord; int offset = 0, j = 0; + uint16 soundCount = argv[offset++]; + SLSTRecord slstRecord; slstRecord.index = 0; // not set by the scripts, so we set it to 0 - slstRecord.sound_count = argv[0]; - slstRecord.sound_ids = new uint16[slstRecord.sound_count]; - - offset = slstRecord.sound_count; + slstRecord.soundIds.resize(soundCount); - for (j = 0; j < slstRecord.sound_count; j++) - slstRecord.sound_ids[j] = argv[offset++]; - slstRecord.fade_flags = argv[offset++]; + for (j = 0; j < soundCount; j++) + slstRecord.soundIds[j] = argv[offset++]; + slstRecord.fadeFlags = argv[offset++]; slstRecord.loop = argv[offset++]; - slstRecord.global_volume = argv[offset++]; + slstRecord.globalVolume = argv[offset++]; slstRecord.u0 = argv[offset++]; - slstRecord.u1 = argv[offset++]; + slstRecord.suspend = argv[offset++]; - slstRecord.volumes = new uint16[slstRecord.sound_count]; - slstRecord.balances = new int16[slstRecord.sound_count]; - slstRecord.u2 = new uint16[slstRecord.sound_count]; + slstRecord.volumes.resize(soundCount); + slstRecord.balances.resize(soundCount); + slstRecord.u2.resize(soundCount); - for (j = 0; j < slstRecord.sound_count; j++) + for (j = 0; j < soundCount; j++) slstRecord.volumes[j] = argv[offset++]; - for (j = 0; j < slstRecord.sound_count; j++) + for (j = 0; j < soundCount; j++) slstRecord.balances[j] = argv[offset++]; // negative = left, 0 = center, positive = right - for (j = 0; j < slstRecord.sound_count; j++) + for (j = 0; j < soundCount; j++) slstRecord.u2[j] = argv[offset++]; // Unknown // Play the requested sound list _vm->_sound->playSLST(slstRecord); - _vm->_activatedSLST = true; - - delete[] slstRecord.sound_ids; - delete[] slstRecord.volumes; - delete[] slstRecord.balances; - delete[] slstRecord.u2; } // Command 4: play local tWAV resource (twav_id, volume, block) void RivenScript::playSound(uint16 op, uint16 argc, uint16 *argv) { - byte volume = Sound::convertRivenVolume(argv[1]); + uint16 volume = argv[1]; + bool playOnDraw = argv[2] == 1; - if (argv[2] == 1) - _vm->_sound->playSoundBlocking(argv[0], volume); - else - _vm->_sound->playSound(argv[0], volume); + _vm->_sound->playSound(argv[0], volume, playOnDraw); } // Command 7: set variable value (variable, value) diff --git a/engines/mohawk/riven_sound.cpp b/engines/mohawk/riven_sound.cpp new file mode 100644 index 0000000000..dd45f94ad3 --- /dev/null +++ b/engines/mohawk/riven_sound.cpp @@ -0,0 +1,459 @@ +/* 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/debug.h" +#include "common/system.h" + +#include "audio/audiostream.h" + +#include "mohawk/riven_sound.h" +#include "mohawk/sound.h" + +namespace Mohawk { + +RivenSoundManager::RivenSoundManager(MohawkEngine *vm) : + _vm(vm), + _effect(nullptr), + _mainAmbientSoundId(-1), + _effectPlayOnDraw(false), + _nextFadeUpdate(0) { + +} + +RivenSoundManager::~RivenSoundManager() { + stopSound(); + stopAllSLST(false); +} + +Audio::RewindableAudioStream *RivenSoundManager::makeAudioStream(uint16 id) { + return makeMohawkWaveStream(_vm->getResource(ID_TWAV, id)); +} + +void RivenSoundManager::playSound(uint16 id, uint16 volume, bool playOnDraw) { + debug (0, "Playing sound %d", id); + + stopSound(); + + Audio::RewindableAudioStream *rewindStream = makeAudioStream(id); + if (!rewindStream) { + warning("Unable to play sound with id %d", id); + return; + } + + _effect = new RivenSound(_vm, rewindStream); + _effect->setVolume(volume); + + _effectPlayOnDraw = playOnDraw; + if (!playOnDraw) { + _effect->play(); + } +} + +void RivenSoundManager::playSLST(uint16 index, uint16 card) { + Common::SeekableReadStream *slstStream = _vm->getResource(ID_SLST, card); + + uint16 recordCount = slstStream->readUint16BE(); + + for (uint16 i = 0; i < recordCount; i++) { + SLSTRecord slstRecord; + slstRecord.index = slstStream->readUint16BE(); + + uint16 soundCount = slstStream->readUint16BE(); + slstRecord.soundIds.resize(soundCount); + + for (uint16 j = 0; j < soundCount; j++) + slstRecord.soundIds[j] = slstStream->readUint16BE(); + + slstRecord.fadeFlags = slstStream->readUint16BE(); + slstRecord.loop = slstStream->readUint16BE(); + slstRecord.globalVolume = slstStream->readUint16BE(); + slstRecord.u0 = slstStream->readUint16BE(); // Unknown + + if (slstRecord.u0 > 1) + warning("slstRecord.u0: %d non-boolean", slstRecord.u0); + + slstRecord.suspend = slstStream->readUint16BE(); + + if (slstRecord.suspend != 0) + warning("slstRecord.u1: %d non-zero", slstRecord.suspend); + + slstRecord.volumes.resize(soundCount); + slstRecord.balances.resize(soundCount); + slstRecord.u2.resize(soundCount); + + for (uint16 j = 0; j < soundCount; j++) + slstRecord.volumes[j] = slstStream->readUint16BE(); + + for (uint16 j = 0; j < soundCount; j++) + slstRecord.balances[j] = slstStream->readSint16BE(); // negative = left, 0 = center, positive = right + + for (uint16 j = 0; j < soundCount; j++) { + slstRecord.u2[j] = slstStream->readUint16BE(); // Unknown + + if (slstRecord.u2[j] != 255 && slstRecord.u2[j] != 256) + warning("slstRecord.u2[%d]: %d not 255 or 256", j, slstRecord.u2[j]); + } + + if (slstRecord.index == index) { + playSLST(slstRecord); + delete slstStream; + return; + } + } + + delete slstStream; + + // If we have no matching entries, we do nothing and just let + // the previous ambient sounds continue. +} + +void RivenSoundManager::playSLST(const SLSTRecord &slstRecord) { + if (slstRecord.soundIds.empty()) { + return; + } + + if (slstRecord.soundIds[0] == _mainAmbientSoundId) { + if (slstRecord.soundIds.size() > _ambientSounds.sounds.size()) { + addAmbientSounds(slstRecord); + } + setAmbientLooping(slstRecord.loop); + setTargetVolumes(slstRecord); + _ambientSounds.suspend = slstRecord.suspend; + if (slstRecord.suspend) { + freePreviousAmbientSounds(); + pauseAmbientSounds(); + applyTargetVolumes(); + } else { + playAmbientSounds(); + } + } else { + _mainAmbientSoundId = slstRecord.soundIds[0]; + freePreviousAmbientSounds(); + moveAmbientSoundsToPreviousSounds(); + addAmbientSounds(slstRecord); + setAmbientLooping(slstRecord.loop); + setTargetVolumes(slstRecord); + _ambientSounds.suspend = slstRecord.suspend; + if (slstRecord.suspend) { + freePreviousAmbientSounds(); + applyTargetVolumes(); + } else { + startFadingAmbientSounds(slstRecord.fadeFlags); + } + } +} + +void RivenSoundManager::stopAllSLST(bool fade) { + _mainAmbientSoundId = -1; + freePreviousAmbientSounds(); + moveAmbientSoundsToPreviousSounds(); + startFadingAmbientSounds(fade ? kFadeOutPreviousSounds : 0); +} + +void RivenSoundManager::stopSound() { + if (_effect) { + delete _effect; + } + _effect = nullptr; + _effectPlayOnDraw = false; +} + +void RivenSoundManager::addAmbientSounds(const SLSTRecord &record) { + if (record.soundIds.size() > _ambientSounds.sounds.size()) { + uint oldSize = _ambientSounds.sounds.size(); + + // Resize the list to the new size + _ambientSounds.sounds.resize(record.soundIds.size()); + + // Add new elements to the list + for (uint i = oldSize; i < _ambientSounds.sounds.size(); i++) { + Audio::RewindableAudioStream *stream = makeAudioStream(record.soundIds[i]); + + RivenSound *sound = new RivenSound(_vm, stream); + sound->setVolume(record.volumes[i]); + sound->setBalance(record.balances[i]); + + _ambientSounds.sounds[i].sound = sound; + _ambientSounds.sounds[i].targetVolume = record.volumes[i]; + _ambientSounds.sounds[i].targetBalance = record.balances[i]; + } + } +} + +void RivenSoundManager::setTargetVolumes(const SLSTRecord &record) { + for (uint i = 0; i < _ambientSounds.sounds.size(); i++) { + _ambientSounds.sounds[i].targetVolume = record.volumes[i] * record.globalVolume / 256; + _ambientSounds.sounds[i].targetBalance = record.balances[i]; + } + _ambientSounds.fading = true; +} + +void RivenSoundManager::freePreviousAmbientSounds() { + for (uint i = 0; i < _previousAmbientSounds.sounds.size(); i++) { + delete _previousAmbientSounds.sounds[i].sound; + } + _previousAmbientSounds = AmbientSoundList(); +} + +void RivenSoundManager::moveAmbientSoundsToPreviousSounds() { + _previousAmbientSounds = _ambientSounds; + _ambientSounds = AmbientSoundList(); +} + +void RivenSoundManager::applyTargetVolumes() { + for (uint i = 0; i < _ambientSounds.sounds.size(); i++) { + AmbientSound &ambientSound = _ambientSounds.sounds[i]; + RivenSound *sound = ambientSound.sound; + sound->setVolume(ambientSound.targetVolume); + sound->setBalance(ambientSound.targetBalance); + } + _ambientSounds.fading = false; +} + +void RivenSoundManager::startFadingAmbientSounds(uint16 flags) { + for (uint i = 0; i < _ambientSounds.sounds.size(); i++) { + AmbientSound &ambientSound = _ambientSounds.sounds[i]; + uint16 volume; + if (flags & kFadeInNewSounds) { + volume = 0; + } else { + volume = ambientSound.targetVolume; + } + ambientSound.sound->setVolume(volume); + } + _ambientSounds.fading = true; + playAmbientSounds(); + + if (!_previousAmbientSounds.sounds.empty()) { + if (flags) { + _previousAmbientSounds.fading = true; + } else { + freePreviousAmbientSounds(); + } + + for (uint i = 0; i < _previousAmbientSounds.sounds.size(); i++) { + AmbientSound &ambientSound = _previousAmbientSounds.sounds[i]; + if (flags & kFadeOutPreviousSounds) { + ambientSound.targetVolume = 0; + } else { + ambientSound.sound->setVolume(ambientSound.targetVolume); + } + } + } +} + +void RivenSoundManager::playAmbientSounds() { + for (uint i = 0; i < _ambientSounds.sounds.size(); i++) { + _ambientSounds.sounds[i].sound->play(); + } +} + +void RivenSoundManager::setAmbientLooping(bool loop) { + for (uint i = 0; i < _ambientSounds.sounds.size(); i++) { + _ambientSounds.sounds[i].sound->setLooping(loop); + } +} + +void RivenSoundManager::triggerDrawSound() { + if (_effectPlayOnDraw && _effect) { + _effect->play(); + } + _effectPlayOnDraw = false; +} + +void RivenSoundManager::pauseAmbientSounds() { + for (uint i = 0; i < _ambientSounds.sounds.size(); i++) { + _ambientSounds.sounds[i].sound->pause(); + } +} + +void RivenSoundManager::updateSLST() { + uint32 time = _vm->_system->getMillis(); + int32 delta = CLIP<int32>(time - _nextFadeUpdate, -50, 50); + if (_nextFadeUpdate == 0 || delta > 0) { + _nextFadeUpdate = time + 50 - delta; + + if (_ambientSounds.fading) { + fadeAmbientSoundList(_ambientSounds); + } + + if (_previousAmbientSounds.fading) { + fadeAmbientSoundList(_previousAmbientSounds); + } + + if (!_previousAmbientSounds.sounds.empty() && !_ambientSounds.fading && !_previousAmbientSounds.fading) { + freePreviousAmbientSounds(); + } + } +} + +void RivenSoundManager::fadeAmbientSoundList(AmbientSoundList &list) { + list.fading = false; + + for (uint i = 0; i < list.sounds.size(); i++) { + AmbientSound &ambientSound = list.sounds[i]; + list.fading |= fadeVolume(ambientSound); + list.fading |= fadeBalance(ambientSound); + } +} + +bool RivenSoundManager::fadeVolume(AmbientSound &ambientSound) { + uint16 volume = ambientSound.sound->getVolume(); + float delta = (ambientSound.targetVolume - volume) / 30.0f; + + if (ABS<float>(delta) < 0.01f) { + ambientSound.sound->setVolume(ambientSound.targetVolume); + return false; + } else { + // Make sure the increment is not zero once converted to an integer + if (delta > 0 && delta < 1) { + delta = 1; + } else if (delta < 0 && delta > -1) { + delta = -1; + } + + ambientSound.sound->setVolume(volume + delta); + return true; + } +} + +bool RivenSoundManager::fadeBalance(RivenSoundManager::AmbientSound &ambientSound) { + int16 balance = ambientSound.sound->getBalance(); + float delta = (ambientSound.targetBalance - balance) / 10.0f; + + if (ABS<float>(delta) < 0.01) { + ambientSound.sound->setBalance(ambientSound.targetBalance); + return false; + } else { + // Make sure the increment is not zero once converted to an integer + if (delta > 0 && delta < 1) { + delta = 1; + } else if (delta < 0 && delta > -1) { + delta = -1; + } + + ambientSound.sound->setBalance(balance + delta); + return true; + } +} + +RivenSound::RivenSound(MohawkEngine *vm, Audio::RewindableAudioStream *rewindStream) : + _vm(vm), + _volume(Audio::Mixer::kMaxChannelVolume), + _balance(0), + _looping(false), + _stream(rewindStream) { + +} + +bool RivenSound::isPlaying() const { + return _vm->_mixer->isSoundHandleActive(_handle); +} + +void RivenSound::pause() { + _vm->_mixer->pauseHandle(_handle, true); +} + +void RivenSound::setVolume(uint16 volume) { + _volume = volume; + if (isPlaying()) { + byte mixerVolume = convertVolume(volume); + _vm->_mixer->setChannelVolume(_handle, mixerVolume); + } +} + +void RivenSound::setBalance(int16 balance) { + _balance = balance; + if (isPlaying()) { + int8 mixerBalance = convertBalance(balance); + _vm->_mixer->setChannelBalance(_handle, mixerBalance); + } +} + +void RivenSound::setLooping(bool loop) { + if (isPlaying() && _looping != loop) { + warning("Changing loop state while a sound is playing is not implemented."); + } + _looping = loop; +} + +void RivenSound::play() { + if (isPlaying()) { + // If the sound is already playing, make sure it is not paused + _vm->_mixer->pauseHandle(_handle, false); + return; + } + + if (!_stream) { + warning("Trying to play a sound without a stream"); + return; + } + + Audio::AudioStream *playStream; + if (_looping) { + playStream = new Audio::LoopingAudioStream(_stream, 0); + } else { + playStream = _stream; + } + + int8 mixerBalance = convertBalance(_balance); + byte mixerVolume = convertVolume(_volume); + _vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, playStream, -1, mixerVolume, mixerBalance); + _stream = nullptr; +} + +byte RivenSound::convertVolume(uint16 volume) { + // The volume is a fixed point value in the Mohawk part of the original engine. + // It's not clear what happens when it is higher than one. + return (volume > 255) ? 255 : volume; +} + +int8 RivenSound::convertBalance(int16 balance) { + return (int8)(balance >> 8); +} + +RivenSound::~RivenSound() { + _vm->_mixer->stopHandle(_handle); + delete _stream; +} + +int16 RivenSound::getBalance() const { + return _balance; +} + +uint16 RivenSound::getVolume() const { + return _volume; +} + +RivenSoundManager::AmbientSound::AmbientSound() : + sound(nullptr), + targetVolume(0), + targetBalance(0) { + +} + +RivenSoundManager::AmbientSoundList::AmbientSoundList() : + fading(false), + suspend(false) { +} + +} // End of namespace Mohawk diff --git a/engines/mohawk/riven_sound.h b/engines/mohawk/riven_sound.h new file mode 100644 index 0000000000..f673d1ee3f --- /dev/null +++ b/engines/mohawk/riven_sound.h @@ -0,0 +1,197 @@ +/* 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 MOHAWK_RIVEN_SOUND_H +#define MOHAWK_RIVEN_SOUND_H + +#include "common/array.h" +#include "common/str.h" + +#include "audio/mixer.h" + +namespace Audio { +class RewindableAudioStream; +} + +namespace Mohawk { + +class MohawkEngine; +class RivenSound; + +/** + * Ambient sound list + */ +struct SLSTRecord { + uint16 index; + Common::Array<uint16> soundIds; + uint16 fadeFlags; + uint16 loop; + uint16 globalVolume; + uint16 u0; + uint16 suspend; + Common::Array<uint16> volumes; + Common::Array<int16> balances; + Common::Array<uint16> u2; +}; + +/** + * Sound manager for Riven + * + * The sound manager can play simulteaneously: + * - An effect sound + * - A list of ambient sounds + * + * The list of ambient sounds can be cross faded + * with the previously running ambient sounds. + */ +class RivenSoundManager { +public: + RivenSoundManager(MohawkEngine *vm); + ~RivenSoundManager(); + + /** + * Play an effect sound + * + * @param id Sound ID in the stack + * @param volume Playback volume, between 0 and 255 + * @param playOnDraw Start playing when the current card is drawn instead of immediatly + */ + void playSound(uint16 id, uint16 volume = 255, bool playOnDraw = false); + + /** Start playing the scheduled on-draw effect sound, if any. Called by the GraphicsManager. */ + void triggerDrawSound(); + + /** Stop playing the current effect sound, if any */ + void stopSound(); + + /** Start playing an ambient sound list */ + void playSLST(const SLSTRecord &slstRecord); + + /** Start playing an ambient sound list from a resource */ + void playSLST(uint16 index, uint16 card); + + /** Stop playing the current ambient sounds */ + void stopAllSLST(bool fade = false); + + /** Update the ambient sounds for fading. Called once per frame. */ + void updateSLST(); + +private: + struct AmbientSound { + RivenSound *sound; + uint16 targetVolume; + int16 targetBalance; + + AmbientSound(); + }; + + struct AmbientSoundList { + bool fading; + bool suspend; + Common::Array<AmbientSound> sounds; + + AmbientSoundList(); + }; + + enum FadeFlags { + kFadeOutPreviousSounds = 1, + kFadeInNewSounds = 2 + }; + + MohawkEngine *_vm; + + int16 _mainAmbientSoundId; + AmbientSoundList _ambientSounds; + AmbientSoundList _previousAmbientSounds; + uint32 _nextFadeUpdate; + + RivenSound *_effect; + bool _effectPlayOnDraw; + + Audio::RewindableAudioStream *makeAudioStream(uint16 id); + + // Ambient sound management + void addAmbientSounds(const SLSTRecord &record); + void playAmbientSounds(); + void pauseAmbientSounds(); + void moveAmbientSoundsToPreviousSounds(); + void freePreviousAmbientSounds(); + + // Ambient sound fading + void setTargetVolumes(const SLSTRecord &record); + void applyTargetVolumes(); + void startFadingAmbientSounds(uint16 flags); + void fadeAmbientSoundList(AmbientSoundList &list); + bool fadeVolume(AmbientSound &ambientSound); + bool fadeBalance(AmbientSound &ambientSound); + void setAmbientLooping(bool loop); +}; + +/** + * A sound used internally by the SoundManager + */ +class RivenSound { +public: + RivenSound(MohawkEngine *vm, Audio::RewindableAudioStream *rewindStream); + ~RivenSound(); + + /** Start playing the sound stream passed to the constructor */ + void play(); + + /** Is the sound currently playing ar paused? */ + bool isPlaying() const; + + /** Pause the playback, the play method resumes */ + void pause(); + + /** Get the current volume */ + uint16 getVolume() const; + + /** Change the playback volume */ + void setVolume(uint16 volume); + + /** Get the current balance */ + int16 getBalance() const; + + /** Change the balance */ + void setBalance(int16 balance); + + /** Set the sound to indefinitely loop. Must be called before startting the playback */ + void setLooping(bool loop); + +private: + static byte convertVolume(uint16 volume); + static int8 convertBalance(int16 balance); + + MohawkEngine *_vm; + + Audio::SoundHandle _handle; + Audio::RewindableAudioStream *_stream; + + uint16 _volume; + int16 _balance; + bool _looping; +}; + +} // End of namespace Mohawk + +#endif diff --git a/engines/mohawk/sound.cpp b/engines/mohawk/sound.cpp index 38cb0b3608..0711561068 100644 --- a/engines/mohawk/sound.cpp +++ b/engines/mohawk/sound.cpp @@ -37,6 +37,150 @@ namespace Mohawk { +Audio::RewindableAudioStream *makeMohawkWaveStream(Common::SeekableReadStream *stream, CueList *cueList) { + uint32 tag = 0; + ADPCMStatus adpcmStatus; + DataChunk dataChunk; + uint32 dataSize = 0; + + memset(&dataChunk, 0, sizeof(DataChunk)); + + if (stream->readUint32BE() != ID_MHWK) // MHWK tag again + error ("Could not find tag 'MHWK'"); + + stream->readUint32BE(); // Skip size + + if (stream->readUint32BE() != ID_WAVE) + error ("Could not find tag 'WAVE'"); + + while (!dataChunk.audioData) { + tag = stream->readUint32BE(); + + switch (tag) { + case ID_ADPC: + debug(2, "Found Tag ADPC"); + // ADPCM Sound Only + // + // This is useful for seeking in the stream, and is actually quite brilliant + // considering some of the other things Broderbund did with the engine. + // Only Riven and CSTime are known to use ADPCM audio and only CSTime + // actually requires this for seeking. On the other hand, it may be interesting + // to look at that one Riven sample that uses the cue points. + // + // Basically, the sample frame from the cue list is looked up here and then + // sets the starting sample and step index at the point specified. Quite + // an elegant/efficient system, really. + + adpcmStatus.size = stream->readUint32BE(); + adpcmStatus.itemCount = stream->readUint16BE(); + adpcmStatus.channels = stream->readUint16BE(); + adpcmStatus.statusItems = new ADPCMStatus::StatusItem[adpcmStatus.itemCount]; + + assert(adpcmStatus.channels <= 2); + + for (uint16 i = 0; i < adpcmStatus.itemCount; i++) { + adpcmStatus.statusItems[i].sampleFrame = stream->readUint32BE(); + + for (uint16 j = 0; j < adpcmStatus.channels; j++) { + adpcmStatus.statusItems[i].channelStatus[j].last = stream->readSint16BE(); + adpcmStatus.statusItems[i].channelStatus[j].stepIndex = stream->readUint16BE(); + } + } + + // TODO: Actually use this chunk. For now, just delete the status items... + delete[] adpcmStatus.statusItems; + break; + case ID_CUE: + debug(2, "Found Tag Cue#"); + // Cues are used for animation sync. There are a couple in Myst and + // Riven but are not used there at all. + + if (!cueList) { + uint32 size = stream->readUint32BE(); + stream->skip(size); + break; + } + + cueList->size = stream->readUint32BE(); + cueList->pointCount = stream->readUint16BE(); + + if (cueList->pointCount == 0) + debug(2, "Cue# chunk found with no points!"); + else + debug(2, "Cue# chunk found with %d point(s)!", cueList->pointCount); + + cueList->points.resize(cueList->pointCount); + for (uint16 i = 0; i < cueList->pointCount; i++) { + cueList->points[i].sampleFrame = stream->readUint32BE(); + + byte nameLength = stream->readByte(); + cueList->points[i].name.clear(); + for (byte j = 0; j < nameLength; j++) + cueList->points[i].name += stream->readByte(); + + // Realign to an even boundary + if (!(nameLength & 1)) + stream->readByte(); + + debug (3, "Cue# chunk point %d (frame %d): %s", i, cueList->points[i].sampleFrame, cueList->points[i].name.c_str()); + } + break; + case ID_DATA: + debug(2, "Found Tag DATA"); + // We subtract 20 from the actual chunk size, which is the total size + // of the chunk's header + dataSize = stream->readUint32BE() - 20; + dataChunk.sampleRate = stream->readUint16BE(); + dataChunk.sampleCount = stream->readUint32BE(); + dataChunk.bitsPerSample = stream->readByte(); + dataChunk.channels = stream->readByte(); + dataChunk.encoding = stream->readUint16BE(); + dataChunk.loopCount = stream->readUint16BE(); + dataChunk.loopStart = stream->readUint32BE(); + dataChunk.loopEnd = stream->readUint32BE(); + + // NOTE: We currently ignore all of the loop parameters here. Myst uses the + // loopCount variable but the loopStart and loopEnd are always 0 and the size of + // the sample. Myst ME doesn't use the Mohawk Sound format and just standard WAVE + // files and therefore does not contain any of this metadata and we have to specify + // whether or not to loop elsewhere. + + dataChunk.audioData = stream->readStream(dataSize); + break; + default: + error ("Unknown tag found in 'tWAV' chunk -- '%s'", tag2str(tag)); + } + } + + // makeMohawkWaveStream always takes control of the original stream + delete stream; + + // The sound in Myst uses raw unsigned 8-bit data + // The sound in the CD version of Riven is encoded in Intel DVI ADPCM + // The sound in the DVD version of Riven is encoded in MPEG-2 Layer II or Intel DVI ADPCM + if (dataChunk.encoding == kCodecRaw) { + byte flags = Audio::FLAG_UNSIGNED; + + if (dataChunk.channels == 2) + flags |= Audio::FLAG_STEREO; + + return Audio::makeRawStream(dataChunk.audioData, dataChunk.sampleRate, flags); + } else if (dataChunk.encoding == kCodecADPCM) { + uint32 blockAlign = dataChunk.channels * dataChunk.bitsPerSample / 8; + return Audio::makeADPCMStream(dataChunk.audioData, DisposeAfterUse::YES, dataSize, Audio::kADPCMDVI, dataChunk.sampleRate, dataChunk.channels, blockAlign); + } else if (dataChunk.encoding == kCodecMPEG2) { +#ifdef USE_MAD + return Audio::makeMP3Stream(dataChunk.audioData, DisposeAfterUse::YES); +#else + warning ("MAD library not included - unable to play MP2 audio"); +#endif + } else { + error ("Unknown Mohawk WAVE encoding %d", dataChunk.encoding); + } + + return nullptr; +} + Sound::Sound(MohawkEngine* vm) : _vm(vm) { _midiDriver = NULL; _midiParser = NULL; @@ -47,7 +191,6 @@ Sound::Sound(MohawkEngine* vm) : _vm(vm) { Sound::~Sound() { stopSound(); - stopAllSLST(); stopBackgroundMyst(); if (_midiParser) { @@ -234,300 +377,6 @@ void Sound::stopMidi() { _midiParser->unloadMusic(); } -byte Sound::convertRivenVolume(uint16 volume) { - return (volume == 256) ? 255 : volume; -} - -void Sound::playSLST(uint16 index, uint16 card) { - Common::SeekableReadStream *slstStream = _vm->getResource(ID_SLST, card); - SLSTRecord slstRecord; - uint16 recordCount = slstStream->readUint16BE(); - - for (uint16 i = 0; i < recordCount; i++) { - slstRecord.index = slstStream->readUint16BE(); - slstRecord.sound_count = slstStream->readUint16BE(); - slstRecord.sound_ids = new uint16[slstRecord.sound_count]; - - for (uint16 j = 0; j < slstRecord.sound_count; j++) - slstRecord.sound_ids[j] = slstStream->readUint16BE(); - - slstRecord.fade_flags = slstStream->readUint16BE(); - slstRecord.loop = slstStream->readUint16BE(); - slstRecord.global_volume = slstStream->readUint16BE(); - slstRecord.u0 = slstStream->readUint16BE(); // Unknown - - if (slstRecord.u0 > 1) - warning("slstRecord.u0: %d non-boolean", slstRecord.u0); - - slstRecord.u1 = slstStream->readUint16BE(); // Unknown - - if (slstRecord.u1 != 0) - warning("slstRecord.u1: %d non-zero", slstRecord.u1); - - slstRecord.volumes = new uint16[slstRecord.sound_count]; - slstRecord.balances = new int16[slstRecord.sound_count]; - slstRecord.u2 = new uint16[slstRecord.sound_count]; - - for (uint16 j = 0; j < slstRecord.sound_count; j++) - slstRecord.volumes[j] = slstStream->readUint16BE(); - - for (uint16 j = 0; j < slstRecord.sound_count; j++) - slstRecord.balances[j] = slstStream->readSint16BE(); // negative = left, 0 = center, positive = right - - for (uint16 j = 0; j < slstRecord.sound_count; j++) { - slstRecord.u2[j] = slstStream->readUint16BE(); // Unknown - - if (slstRecord.u2[j] != 255 && slstRecord.u2[j] != 256) - warning("slstRecord.u2[%d]: %d not 255 or 256", j, slstRecord.u2[j]); - } - - if (slstRecord.index == index) { - playSLST(slstRecord); - delete[] slstRecord.sound_ids; - delete[] slstRecord.volumes; - delete[] slstRecord.balances; - delete[] slstRecord.u2; - delete slstStream; - return; - } - - delete[] slstRecord.sound_ids; - delete[] slstRecord.volumes; - delete[] slstRecord.balances; - delete[] slstRecord.u2; - } - - delete slstStream; - - // If we have no matching entries, we do nothing and just let - // the previous ambient sounds continue. -} - -void Sound::playSLST(SLSTRecord slstRecord) { - // End old sounds - for (uint16 i = 0; i < _currentSLSTSounds.size(); i++) { - bool noLongerPlay = true; - for (uint16 j = 0; j < slstRecord.sound_count; j++) - if (_currentSLSTSounds[i].id == slstRecord.sound_ids[j]) - noLongerPlay = false; - if (noLongerPlay) - stopSLSTSound(i, (slstRecord.fade_flags & 1) != 0); - } - - // Start new sounds - for (uint16 i = 0; i < slstRecord.sound_count; i++) { - bool alreadyPlaying = false; - for (uint16 j = 0; j < _currentSLSTSounds.size(); j++) { - if (_currentSLSTSounds[j].id == slstRecord.sound_ids[i]) - alreadyPlaying = true; - } - if (!alreadyPlaying) { - playSLSTSound(slstRecord.sound_ids[i], - (slstRecord.fade_flags & (1 << 1)) != 0, - slstRecord.loop != 0, - slstRecord.volumes[i], - slstRecord.balances[i]); - } - } -} - -void Sound::stopAllSLST(bool fade) { - for (uint16 i = 0; i < _currentSLSTSounds.size(); i++) { - // TODO: Fade out, if requested - _vm->_mixer->stopHandle(*_currentSLSTSounds[i].handle); - delete _currentSLSTSounds[i].handle; - } - - _currentSLSTSounds.clear(); -} - -static int8 convertBalance(int16 balance) { - return (int8)(balance >> 8); -} - -void Sound::playSLSTSound(uint16 id, bool fade, bool loop, uint16 volume, int16 balance) { - // WORKAROUND: Some Riven SLST entries have a volume of 0, so we just ignore them. - if (volume == 0) - return; - - SLSTSndHandle sndHandle; - sndHandle.handle = new Audio::SoundHandle(); - sndHandle.id = id; - _currentSLSTSounds.push_back(sndHandle); - - Audio::RewindableAudioStream *rewindStream = makeMohawkWaveStream(_vm->getResource(ID_TWAV, id)); - - // Loop here if necessary - Audio::AudioStream *audStream = rewindStream; - if (loop) - audStream = Audio::makeLoopingAudioStream(rewindStream, 0); - - // TODO: Handle fading, possibly just raise the volume of the channel in increments? - - _vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, sndHandle.handle, audStream, -1, convertRivenVolume(volume), convertBalance(balance)); -} - -void Sound::stopSLSTSound(uint16 index, bool fade) { - // TODO: Fade out, if requested - _vm->_mixer->stopHandle(*_currentSLSTSounds[index].handle); - delete _currentSLSTSounds[index].handle; - _currentSLSTSounds.remove_at(index); -} - -void Sound::pauseSLST() { - for (uint16 i = 0; i < _currentSLSTSounds.size(); i++) - _vm->_mixer->pauseHandle(*_currentSLSTSounds[i].handle, true); -} - -void Sound::resumeSLST() { - for (uint16 i = 0; i < _currentSLSTSounds.size(); i++) - _vm->_mixer->pauseHandle(*_currentSLSTSounds[i].handle, false); -} - -Audio::RewindableAudioStream *Sound::makeMohawkWaveStream(Common::SeekableReadStream *stream, CueList *cueList) { - uint32 tag = 0; - ADPCMStatus adpcmStatus; - DataChunk dataChunk; - uint32 dataSize = 0; - - memset(&dataChunk, 0, sizeof(DataChunk)); - - if (stream->readUint32BE() != ID_MHWK) // MHWK tag again - error ("Could not find tag 'MHWK'"); - - stream->readUint32BE(); // Skip size - - if (stream->readUint32BE() != ID_WAVE) - error ("Could not find tag 'WAVE'"); - - while (!dataChunk.audioData) { - tag = stream->readUint32BE(); - - switch (tag) { - case ID_ADPC: - debug(2, "Found Tag ADPC"); - // ADPCM Sound Only - // - // This is useful for seeking in the stream, and is actually quite brilliant - // considering some of the other things Broderbund did with the engine. - // Only Riven and CSTime are known to use ADPCM audio and only CSTime - // actually requires this for seeking. On the other hand, it may be interesting - // to look at that one Riven sample that uses the cue points. - // - // Basically, the sample frame from the cue list is looked up here and then - // sets the starting sample and step index at the point specified. Quite - // an elegant/efficient system, really. - - adpcmStatus.size = stream->readUint32BE(); - adpcmStatus.itemCount = stream->readUint16BE(); - adpcmStatus.channels = stream->readUint16BE(); - adpcmStatus.statusItems = new ADPCMStatus::StatusItem[adpcmStatus.itemCount]; - - assert(adpcmStatus.channels <= 2); - - for (uint16 i = 0; i < adpcmStatus.itemCount; i++) { - adpcmStatus.statusItems[i].sampleFrame = stream->readUint32BE(); - - for (uint16 j = 0; j < adpcmStatus.channels; j++) { - adpcmStatus.statusItems[i].channelStatus[j].last = stream->readSint16BE(); - adpcmStatus.statusItems[i].channelStatus[j].stepIndex = stream->readUint16BE(); - } - } - - // TODO: Actually use this chunk. For now, just delete the status items... - delete[] adpcmStatus.statusItems; - break; - case ID_CUE: - debug(2, "Found Tag Cue#"); - // Cues are used for animation sync. There are a couple in Myst and - // Riven but are not used there at all. - - if (!cueList) { - uint32 size = stream->readUint32BE(); - stream->skip(size); - break; - } - - cueList->size = stream->readUint32BE(); - cueList->pointCount = stream->readUint16BE(); - - if (cueList->pointCount == 0) - debug(2, "Cue# chunk found with no points!"); - else - debug(2, "Cue# chunk found with %d point(s)!", cueList->pointCount); - - cueList->points.resize(cueList->pointCount); - for (uint16 i = 0; i < cueList->pointCount; i++) { - cueList->points[i].sampleFrame = stream->readUint32BE(); - - byte nameLength = stream->readByte(); - cueList->points[i].name.clear(); - for (byte j = 0; j < nameLength; j++) - cueList->points[i].name += stream->readByte(); - - // Realign to an even boundary - if (!(nameLength & 1)) - stream->readByte(); - - debug (3, "Cue# chunk point %d (frame %d): %s", i, cueList->points[i].sampleFrame, cueList->points[i].name.c_str()); - } - break; - case ID_DATA: - debug(2, "Found Tag DATA"); - // We subtract 20 from the actual chunk size, which is the total size - // of the chunk's header - dataSize = stream->readUint32BE() - 20; - dataChunk.sampleRate = stream->readUint16BE(); - dataChunk.sampleCount = stream->readUint32BE(); - dataChunk.bitsPerSample = stream->readByte(); - dataChunk.channels = stream->readByte(); - dataChunk.encoding = stream->readUint16BE(); - dataChunk.loopCount = stream->readUint16BE(); - dataChunk.loopStart = stream->readUint32BE(); - dataChunk.loopEnd = stream->readUint32BE(); - - // NOTE: We currently ignore all of the loop parameters here. Myst uses the - // loopCount variable but the loopStart and loopEnd are always 0 and the size of - // the sample. Myst ME doesn't use the Mohawk Sound format and just standard WAVE - // files and therefore does not contain any of this metadata and we have to specify - // whether or not to loop elsewhere. - - dataChunk.audioData = stream->readStream(dataSize); - break; - default: - error ("Unknown tag found in 'tWAV' chunk -- '%s'", tag2str(tag)); - } - } - - // makeMohawkWaveStream always takes control of the original stream - delete stream; - - // The sound in Myst uses raw unsigned 8-bit data - // The sound in the CD version of Riven is encoded in Intel DVI ADPCM - // The sound in the DVD version of Riven is encoded in MPEG-2 Layer II or Intel DVI ADPCM - if (dataChunk.encoding == kCodecRaw) { - byte flags = Audio::FLAG_UNSIGNED; - - if (dataChunk.channels == 2) - flags |= Audio::FLAG_STEREO; - - return Audio::makeRawStream(dataChunk.audioData, dataChunk.sampleRate, flags); - } else if (dataChunk.encoding == kCodecADPCM) { - uint32 blockAlign = dataChunk.channels * dataChunk.bitsPerSample / 8; - return Audio::makeADPCMStream(dataChunk.audioData, DisposeAfterUse::YES, dataSize, Audio::kADPCMDVI, dataChunk.sampleRate, dataChunk.channels, blockAlign); - } else if (dataChunk.encoding == kCodecMPEG2) { -#ifdef USE_MAD - return Audio::makeMP3Stream(dataChunk.audioData, DisposeAfterUse::YES); -#else - warning ("MAD library not included - unable to play MP2 audio"); -#endif - } else { - error ("Unknown Mohawk WAVE encoding %d", dataChunk.encoding); - } - - return NULL; -} - Audio::RewindableAudioStream *Sound::makeLivingBooksWaveStream_v1(Common::SeekableReadStream *stream) { uint16 header = stream->readUint16BE(); uint16 rate = 0; @@ -591,18 +440,6 @@ void Sound::stopSound(uint16 id) { } } -void Sound::pauseSound() { - for (uint32 i = 0; i < _handles.size(); i++) - if (_handles[i].type == kUsedHandle) - _vm->_mixer->pauseHandle(_handles[i].handle, true); -} - -void Sound::resumeSound() { - for (uint32 i = 0; i < _handles.size(); i++) - if (_handles[i].type == kUsedHandle) - _vm->_mixer->pauseHandle(_handles[i].handle, false); -} - bool Sound::isPlaying(uint16 id) { for (uint32 i = 0; i < _handles.size(); i++) if (_handles[i].type == kUsedHandle && _handles[i].id == id) diff --git a/engines/mohawk/sound.h b/engines/mohawk/sound.h index f09706e155..2b4b1ce091 100644 --- a/engines/mohawk/sound.h +++ b/engines/mohawk/sound.h @@ -42,20 +42,6 @@ namespace Mohawk { #define MAX_CHANNELS 2 // Can there be more than 2? -struct SLSTRecord { - uint16 index; - uint16 sound_count; - uint16 *sound_ids; - uint16 fade_flags; - uint16 loop; - uint16 global_volume; - uint16 u0; - uint16 u1; - uint16 *volumes; - int16 *balances; - uint16 *u2; -}; - enum SndHandleType { kFreeHandle, kUsedHandle @@ -68,11 +54,6 @@ struct SndHandle { uint16 id; }; -struct SLSTSndHandle { - Audio::SoundHandle *handle; - uint16 id; -}; - struct ADPCMStatus { // Holds ADPCM status data, but is irrelevant for us. uint32 size; uint16 itemCount; @@ -116,6 +97,8 @@ struct DataChunk { Common::SeekableReadStream *audioData; }; +Audio::RewindableAudioStream *makeMohawkWaveStream(Common::SeekableReadStream *stream, CueList *cueList = nullptr); + class MohawkEngine; class Sound { @@ -130,8 +113,6 @@ public: void stopMidi(); void stopSound(); void stopSound(uint16 id); - void pauseSound(); - void resumeSound(); bool isPlaying(uint16 id); bool isPlaying(); uint getNumSamplesPlayed(uint16 id); @@ -144,21 +125,12 @@ public: void stopBackgroundMyst(); void changeBackgroundVolumeMyst(uint16 vol); - // Riven-specific sound functions - void playSLST(uint16 index, uint16 card); - void playSLST(SLSTRecord slstRecord); - void pauseSLST(); - void resumeSLST(); - void stopAllSLST(bool fade = false); - static byte convertRivenVolume(uint16 volume); - private: MohawkEngine *_vm; MidiDriver *_midiDriver; MidiParser *_midiParser; byte *_midiData; - static Audio::RewindableAudioStream *makeMohawkWaveStream(Common::SeekableReadStream *stream, CueList *cueList = NULL); static Audio::RewindableAudioStream *makeLivingBooksWaveStream_v1(Common::SeekableReadStream *stream); void initMidi(); @@ -169,11 +141,6 @@ private: // Myst-specific SndHandle _mystBackgroundSound; - - // Riven-specific - void playSLSTSound(uint16 index, bool fade, bool loop, uint16 volume, int16 balance); - void stopSLSTSound(uint16 id, bool fade); - Common::Array<SLSTSndHandle> _currentSLSTSounds; }; } // End of namespace Mohawk diff --git a/engines/mortevielle/mortevielle.cpp b/engines/mortevielle/mortevielle.cpp index 81b2edb57d..4f0899deb4 100644 --- a/engines/mortevielle/mortevielle.cpp +++ b/engines/mortevielle/mortevielle.cpp @@ -48,6 +48,10 @@ MortevielleEngine *g_vm; MortevielleEngine::MortevielleEngine(OSystem *system, const MortevielleGameDescription *gameDesc): Engine(system), _gameDescription(gameDesc), _randomSource("mortevielle") { + // Set debug channels + DebugMan.addDebugChannel(kMortevielleCore, "core", "Core debugging"); + DebugMan.addDebugChannel(kMortevielleGraphics, "graphics", "Graphics debugging"); + g_vm = this; _debugger = new Debugger(this); _dialogManager = new DialogManager(this); @@ -244,10 +248,6 @@ Common::ErrorCode MortevielleEngine::initialize() { // Initialize graphics mode initGraphics(SCREEN_WIDTH, SCREEN_HEIGHT, true); - // Set debug channels - DebugMan.addDebugChannel(kMortevielleCore, "core", "Core debugging"); - DebugMan.addDebugChannel(kMortevielleGraphics, "graphics", "Graphics debugging"); - // Set up an intermediate screen surface _screenSurface->create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8()); diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 6898745858..3e67a1819a 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -2080,6 +2080,10 @@ bool Console::cmdPrintSegmentTable(int argc, const char **argv) { case SEG_TYPE_STRING: debugPrintf("T SCI32 strings (%d)", (*(StringTable *)mobj).entries_used); break; + + case SEG_TYPE_BITMAP: + debugPrintf("T SCI32 bitmaps (%d)", (*(BitmapTable *)mobj).entries_used); + break; #endif default: @@ -2214,6 +2218,9 @@ bool Console::segmentInfo(int nr) { case SEG_TYPE_ARRAY: debugPrintf("SCI32 arrays\n"); break; + case SEG_TYPE_BITMAP: + debugPrintf("SCI32 bitmaps\n"); + break; #endif default : @@ -2815,6 +2822,12 @@ bool Console::cmdViewReference(int argc, const char **argv) { hexDumpReg(array->getRawData(), array->getSize(), 4, 0, true); break; } + case SEG_TYPE_BITMAP: { + debugPrintf("SCI32 bitmap:\n"); + const SciBitmap *bitmap = _engine->_gamestate->_segMan->lookupBitmap(reg); + Common::hexdump((const byte *) bitmap->getRawData(), bitmap->getRawSize(), 16, 0); + break; + } #endif default: { const SegmentRef block = _engine->_gamestate->_segMan->dereference(reg); diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index 8691c37b3e..f5797dc106 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -108,6 +108,9 @@ static const PlainGameDescriptor s_sciGameTitles[] = { {"qfg4", "Quest for Glory IV: Shadows of Darkness"}, // floppy is SCI2, CD SCI2.1 // === SCI2.1 games ======================================================== {"hoyle5", "Hoyle Classic Games"}, + {"hoyle5bridge", "Hoyle Bridge"}, + {"hoyle5children", "Hoyle Children's Collection"}, + {"hoyle5solitaire", "Hoyle Solitaire"}, {"chest", "Inside the Chest"}, // aka Behind the Developer's Shield {"gk2", "The Beast Within: A Gabriel Knight Mystery"}, {"kq7", "King's Quest VII: The Princeless Bride"}, @@ -159,6 +162,9 @@ static const GameIdStrToEnum s_gameIdStrToEnum[] = { { "hoyle3", GID_HOYLE3 }, { "hoyle4", GID_HOYLE4 }, { "hoyle5", GID_HOYLE5 }, + { "hoyle5bridge", GID_HOYLE5 }, + { "hoyle5children", GID_HOYLE5 }, + { "hoyle5solitaire", GID_HOYLE5 }, { "iceman", GID_ICEMAN }, { "inndemo", GID_INNDEMO }, { "islandbrain", GID_ISLANDBRAIN }, diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h index f205609e20..de342a3afc 100644 --- a/engines/sci/detection_tables.h +++ b/engines/sci/detection_tables.h @@ -734,8 +734,9 @@ static const struct ADGameDescription SciGameDescriptions[] = { GAMEOPTION_PREFER_DIGITAL_SFX, \ GAMEOPTION_ORIGINAL_SAVELOAD, \ GAMEOPTION_FB01_MIDI) -#define GUIO_GK1_CD GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, \ +#define GUIO_GK1_CD GUIO4(GAMEOPTION_PREFER_DIGITAL_SFX, \ GAMEOPTION_ORIGINAL_SAVELOAD, \ + GAMEOPTION_HIGH_RESOLUTION_GRAPHICS, \ GAMEOPTION_FB01_MIDI) #define GUIO_GK1_MAC GUIO_GK1_FLOPPY @@ -1133,16 +1134,56 @@ static const struct ADGameDescription SciGameDescriptions[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, #ifdef ENABLE_SCI32 -#define GUIO_HOYLE5_DEMO GUIO3(GUIO_NOSPEECH, \ - GUIO_NOASPECT, \ - GAMEOPTION_ORIGINAL_SAVELOAD) +#define GUIO_HOYLE5 GUIO3(GUIO_NOSPEECH, \ + GUIO_NOASPECT, \ + GUIO_NOLAUNCHLOAD) // Hoyle 5 (Hoyle Classic Games) - Windows demo {"hoyle5", "Demo", { {"ressci.000", 0, "98a39ae535dd01714ac313f8ba925045", 7260363}, {"resmap.000", 0, "10267a1542a73d527e50f0340549088b", 4900}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_HOYLE5_DEMO }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_HOYLE5 }, + + // Hoyle 5 (Hoyle Classic Games) - Windows + {"hoyle5", "", { + {"resource.aud", 0, "cc4a7e21dc864ae21cf823e893c279ad", 257483406}, + {"ressci.000", 0, "55ae04012a73abc15b93debf60a7df71", 16909704}, + {"resmap.000", 0, "daf64a91344a7934fe4374765267c2af", 5767}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_HOYLE5 }, + + // Hoyle Bridge - Windows + {"hoyle5bridge", "", { + {"resource.aud", 0, "cc4a7e21dc864ae21cf823e893c279ad", 257585548}, + {"ressci.000", 0, "b83cba09229d3003df9e0c864843f962", 16842499}, + {"resmap.000", 0, "7b3e3030b0ad5f341053c18afce7d176", 5647}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_HOYLE5 }, + + // Hoyle Children's Collection - Windows + {"hoyle5children", "", { + {"resource.aud", 0, "cc4a7e21dc864ae21cf823e893c279ad", 257585548}, + {"ressci.000", 0, "fd1f7dbeebd4510cd37e171a72f2b6ad", 16824349}, + {"resmap.000", 0, "b0fe1bcc69596e10fe5caa11d0b55b23", 5671}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_HOYLE5 }, + + // Hoyle Solitaire (CD version) - Windows + {"hoyle5solitaire", "CD", { + {"resource.aud", 0, "d41d8cd98f00b204e9800998ecf8427e", 0}, + {"ressci.000", 0, "fa4eeb24b1fbf6f33739995360554485", 11628203}, + {"resmap.000", 0, "3f63df73a49800f080775d2a9ad0e949", 3079}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_HOYLE5 }, + + // Hoyle Solitaire (Hard Drive version) - Windows + {"hoyle5solitaire", "Hard Drive", { + {"resource.aud", 0, "d41d8cd98f00b204e9800998ecf8427e", 0}, + {"ressci.000", 0, "da180c67d54d4208c84a48fcd8709671", 8582335}, + {"resmap.000", 0, "e2feb47ab16f9e22a9b6a8580d1da3f0", 3055}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_HOYLE5 }, #endif // ENABLE_SCI32 @@ -3732,6 +3773,14 @@ static const struct ADGameDescription SciGameDescriptions[] = { AD_LISTEND}, Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO_QFG4_CD }, + // Quest for Glory 4 CD - English DOS/Windows (from jvprat) + // Executable scanning reports "2.100.002", VERSION file reports "1.0" + {"qfg4", "CD", { + {"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246}, + {"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO_QFG4_CD }, + #define GUIO_RAMA_DEMO GUIO5(GAMEOPTION_ENABLE_BLACK_LINED_VIDEO, \ GUIO_NOASPECT, \ GAMEOPTION_PREFER_DIGITAL_SFX, \ diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp index b229490570..6c1713bed9 100644 --- a/engines/sci/engine/gc.cpp +++ b/engines/sci/engine/gc.cpp @@ -143,22 +143,31 @@ AddrSet *findAllActiveReferences(EngineState *s) { const Common::Array<SegmentObj *> &heap = s->_segMan->getSegments(); uint heapSize = heap.size(); - // Init: Explicitly loaded scripts for (uint i = 1; i < heapSize; i++) { - if (heap[i] && heap[i]->getType() == SEG_TYPE_SCRIPT) { - Script *script = (Script *)heap[i]; + if (heap[i]) { + // Init: Explicitly loaded scripts + if (heap[i]->getType() == SEG_TYPE_SCRIPT) { + Script *script = (Script *)heap[i]; - if (script->getLockers()) { // Explicitly loaded? - wm.pushArray(script->listObjectReferences()); + if (script->getLockers()) { // Explicitly loaded? + wm.pushArray(script->listObjectReferences()); + } } - } - } #ifdef ENABLE_SCI32 - // Init: ScrollWindows - if (g_sci->_gfxControls32) - wm.pushArray(g_sci->_gfxControls32->listObjectReferences()); + // Init: Explicitly opted-out bitmaps + else if (heap[i]->getType() == SEG_TYPE_BITMAP) { + BitmapTable *bt = static_cast<BitmapTable *>(heap[i]); + + for (uint j = 0; j < bt->_table.size(); j++) { + if (bt->_table[j].data && bt->_table[j].data->getShouldGC() == false) { + wm.push(make_reg(i, j)); + } + } + } #endif + } + } debugC(kDebugLevelGC, "[GC] -- Finished explicitly loaded scripts, done with root set"); diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 2afb8b73d1..d764a88a0a 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -408,6 +408,7 @@ uint16 Kernel::findRegType(reg_t reg) { #ifdef ENABLE_SCI32 case SEG_TYPE_ARRAY: case SEG_TYPE_STRING: + case SEG_TYPE_BITMAP: #endif result |= SIG_TYPE_REFERENCE; break; diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 5ff4f932be..b02a7e545a 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -450,6 +450,17 @@ reg_t kPlayVMDShowCursor(EngineState *s, int argc, reg_t *argv); reg_t kPlayVMDSetBlackoutArea(EngineState *s, int argc, reg_t *argv); reg_t kPlayVMDRestrictPalette(EngineState *s, int argc, reg_t *argv); +reg_t kShowMovie32(EngineState *s, int argc, reg_t *argv); +reg_t kShowMovieWin(EngineState *s, int argc, reg_t *argv); +reg_t kShowMovieWinOpen(EngineState *s, int argc, reg_t *argv); +reg_t kShowMovieWinInit(EngineState *s, int argc, reg_t *argv); +reg_t kShowMovieWinPlay(EngineState *s, int argc, reg_t *argv); +reg_t kShowMovieWinClose(EngineState *s, int argc, reg_t *argv); +reg_t kShowMovieWinCue(EngineState *s, int argc, reg_t *argv); +reg_t kShowMovieWinGetDuration(EngineState *s, int argc, reg_t *argv); +reg_t kShowMovieWinPlayUntilEvent(EngineState *s, int argc, reg_t *argv); +reg_t kShowMovieWinInitDouble(EngineState *s, int argc, reg_t *argv); + reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv); reg_t kArray(EngineState *s, int argc, reg_t *argv); reg_t kListAt(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index 8a1176eed8..76c24b09e3 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -423,6 +423,27 @@ static const SciKernelMapSubEntry kList_subops[] = { SCI_SUBOPENTRY_TERMINATOR }; +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kShowMovieWin_subops[] = { + { SIG_SCI2, 0, MAP_CALL(ShowMovieWinOpen), "r", NULL }, + { SIG_SCI2, 1, MAP_CALL(ShowMovieWinInit), "ii(ii)", NULL }, + { SIG_SCI2, 2, MAP_CALL(ShowMovieWinPlay), "i", NULL }, + { SIG_SCI2, 6, MAP_CALL(ShowMovieWinClose), "", NULL }, + { SIG_SINCE_SCI21, 0, MAP_CALL(ShowMovieWinOpen), "ir", NULL }, + { SIG_SINCE_SCI21, 1, MAP_CALL(ShowMovieWinInit), "iii(ii)", NULL }, + { SIG_SINCE_SCI21, 2, MAP_CALL(ShowMovieWinPlay), "i(ii)(i)(i)", NULL }, + { SIG_SINCE_SCI21, 6, MAP_CALL(ShowMovieWinClose), "i", NULL }, + // Since movies are rendered within the graphics engine in ScummVM, + // it is not necessary to copy the palette from SCI to MCI, so this + // can be a no-op + { SIG_SINCE_SCI21, 7, MAP_EMPTY(ShowMovieWinSetPalette), "i", NULL }, + { SIG_SINCE_SCI21, 8, MAP_CALL(ShowMovieWinGetDuration), "i", NULL }, + { SIG_SINCE_SCI21, 11, MAP_CALL(ShowMovieWinCue), "ii", NULL }, + { SIG_SINCE_SCI21, 14, MAP_CALL(ShowMovieWinPlayUntilEvent), "i(i)", NULL }, + { SIG_SINCE_SCI21, 15, MAP_CALL(ShowMovieWinInitDouble), "iii", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + // There are a lot of subops to PlayVMD, but only a few of them are ever // actually used by games // version, subId, function-mapping, signature, workarounds @@ -688,7 +709,11 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(SetSynonyms), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(SetVideoMode), SIG_EVERYWHERE, "i", NULL, NULL }, { MAP_CALL(ShakeScreen), SIG_EVERYWHERE, "(i)(i)", NULL, NULL }, - { MAP_CALL(ShowMovie), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(ShowMovie), SIG_SCI16, SIGFOR_ALL, "(.*)", NULL, NULL }, +#ifdef ENABLE_SCI32 + { "ShowMovie", kShowMovie32, SIG_SCI32, SIGFOR_DOS, "ri(i)(i)", NULL, NULL }, + { "ShowMovie", kShowMovieWin, SIG_SCI32, SIGFOR_WIN, "(.*)", kShowMovieWin_subops, NULL }, +#endif { MAP_CALL(Show), SIG_EVERYWHERE, "i", NULL, NULL }, { MAP_CALL(SinDiv), SIG_EVERYWHERE, "ii", NULL, NULL }, { MAP_CALL(Sort), SIG_EVERYWHERE, "ooo", NULL, NULL }, @@ -772,7 +797,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(EditText), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(MakeSaveCatName), SIG_EVERYWHERE, "rr", NULL, NULL }, { MAP_CALL(MakeSaveFileName), SIG_EVERYWHERE, "rri", NULL, NULL }, - { MAP_CALL(SetScroll), SIG_EVERYWHERE, "oiiiii(i)", NULL, NULL }, + { MAP_CALL(SetScroll), SIG_EVERYWHERE, "oiiii(i)(i)", NULL, NULL }, { MAP_CALL(PalCycle), SIG_EVERYWHERE, "(.*)", kPalCycle_subops, NULL }, // SCI2 Empty functions @@ -820,10 +845,10 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(List), SIG_SINCE_SCI21, SIGFOR_ALL, "(.*)", kList_subops, NULL }, { MAP_CALL(MulDiv), SIG_EVERYWHERE, "iii", NULL, NULL }, { MAP_CALL(PlayVMD), SIG_EVERYWHERE, "(.*)", kPlayVMD_subops, NULL }, - { MAP_CALL(Robot), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_EMPTY(Robot), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_CALL(Save), SIG_EVERYWHERE, "i(.*)", kSave_subops, NULL }, { MAP_CALL(Text), SIG_SINCE_SCI21MID, SIGFOR_ALL, "i(.*)", kText_subops, NULL }, - { MAP_CALL(AddPicAt), SIG_EVERYWHERE, "oiii", NULL, NULL }, + { MAP_CALL(AddPicAt), SIG_EVERYWHERE, "oiii(i)(i)", NULL, NULL }, { MAP_CALL(GetWindowsOption), SIG_EVERYWHERE, "i", NULL, NULL }, { MAP_CALL(WinHelp), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_CALL(GetConfig), SIG_EVERYWHERE, "ro", NULL, NULL }, diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 4508a481a0..3bcadd143c 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -251,6 +251,25 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { return SIGNAL_REG; } + // Torin's autosave system checks for the presence of autosave.cat + // by opening it. Since we don't use .cat files, we instead check + // for autosave.000 or autosave.001. + // + // This has the added benefit of not detecting an SSCI autosave.cat + // accompanying SSCI autosave files that we wouldn't be able to load. + if (g_sci->getGameId() == GID_TORIN && name == "autosave.cat") { + Common::String pattern = g_sci->wrapFilename("autosave.###"); + Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); + bool exists = !saveFileMan->listSavefiles(pattern).empty(); + if (exists) { + // Dummy handle. Torin only checks if this is SIGNAL_REG, + // and calls kFileIOClose on it. + return make_reg(0, VIRTUALFILE_HANDLE_SCI32SAVE); + } else { + return SIGNAL_REG; + } + } + if (name.empty()) { // Happens many times during KQ1 (e.g. when typing something) debugC(kDebugLevelFile, "Attempted to open a file with an empty filename"); @@ -688,7 +707,7 @@ reg_t kSave(EngineState *s, int argc, reg_t *argv) { #endif reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { - Common::String game_id; + Common::String game_id = !argv[0].isNull() ? s->_segMan->getString(argv[0]) : ""; int16 virtualId = argv[1].toSint16(); int16 savegameId = -1; Common::String game_description; @@ -703,6 +722,13 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { return NULL_REG; } + // Torin has two sets of saves: autosave.### and torinsg.###, both with + // their own slots and .cat file. + // The autosave system uses autosave.000 and autosave.001. + // It also checks the presence of autosave.cat to determine if it should + // show the chapter selection menu on startup. (See kFileIOOpen.) + bool torinAutosave = g_sci->getGameId() == GID_TORIN && game_id == "Autosave"; + if (argv[0].isNull()) { // Direct call, from a patched Game::save if ((argv[1] != SIGNAL_REG) || (!argv[2].isNull())) @@ -722,9 +748,15 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { if (savegameId < 0) return NULL_REG; + } else if (torinAutosave) { + if (argv[2].isNull()) + error("kSaveGame: called with description being NULL"); + game_description = s->_segMan->getString(argv[2]); + savegameId = virtualId; + + debug(3, "kSaveGame(%s,%d,%s,%s) [Torin autosave]", game_id.c_str(), virtualId, game_description.c_str(), version.c_str()); } else { // Real call from script - game_id = s->_segMan->getString(argv[0]); if (argv[2].isNull()) error("kSaveGame: called with description being NULL"); game_description = s->_segMan->getString(argv[2]); @@ -798,6 +830,10 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); Common::OutSaveFile *out; + if (torinAutosave) { + filename = g_sci->wrapFilename(Common::String::format("autosave.%03d", savegameId)); + } + out = saveFileMan->openForSaving(filename); if (!out) { warning("Error opening savegame \"%s\" for writing", filename.c_str()); @@ -826,6 +862,10 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { debug(3, "kRestoreGame(%s,%d)", game_id.c_str(), savegameId); + + // See comment in kSaveGame + bool torinAutosave = g_sci->getGameId() == GID_TORIN && game_id == "Autosave"; + if (argv[0].isNull()) { // Direct call, either from launcher or from a patched Game::restore if (savegameId == -1) { @@ -841,7 +881,7 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { pausedMusic = true; } // don't adjust ID of the saved game, it's already correct - } else { + } else if (!torinAutosave) { if (g_sci->getGameId() == GID_JONES) { // Jones has one save slot only savegameId = 0; @@ -858,8 +898,9 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { s->r_acc = NULL_REG; // signals success Common::Array<SavegameDesc> saves; - listSavegames(saves); - if (findSavegame(saves, savegameId) == -1) { + if (!torinAutosave) + listSavegames(saves); + if (!torinAutosave && findSavegame(saves, savegameId) == -1) { s->r_acc = TRUE_REG; warning("Savegame ID %d not found", savegameId); } else { @@ -867,6 +908,10 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { Common::String filename = g_sci->getSavegameName(savegameId); Common::SeekableReadStream *in; + if (torinAutosave) { + filename = g_sci->wrapFilename(Common::String::format("autosave.%03d", savegameId)); + } + in = saveFileMan->openForLoading(filename); if (in) { // found a savegame file diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp index 9cfe53255b..e458109cc2 100644 --- a/engines/sci/engine/kgraphics32.cpp +++ b/engines/sci/engine/kgraphics32.cpp @@ -56,6 +56,7 @@ #include "sci/graphics/palette32.h" #include "sci/graphics/remap32.h" #include "sci/graphics/text32.h" +#include "sci/graphics/transitions32.h" #endif namespace Sci { @@ -123,8 +124,9 @@ reg_t kAddPicAt(EngineState *s, int argc, reg_t *argv) { int16 x = argv[2].toSint16(); int16 y = argv[3].toSint16(); bool mirrorX = argc > 4 ? argv[4].toSint16() : false; + bool deleteDuplicate = argc > 5 ? argv[5].toSint16() : true; - g_sci->_gfxFrameout->kernelAddPicAt(planeObj, pictureId, x, y, mirrorX); + g_sci->_gfxFrameout->kernelAddPicAt(planeObj, pictureId, x, y, mirrorX, deleteDuplicate); return s->r_acc; } @@ -139,7 +141,7 @@ reg_t kFrameOut(EngineState *s, int argc, reg_t *argv) { } reg_t kSetPalStyleRange(EngineState *s, int argc, reg_t *argv) { - g_sci->_gfxFrameout->kernelSetPalStyleRange(argv[0].toUint16(), argv[1].toUint16()); + g_sci->_gfxTransitions32->kernelSetPalStyleRange(argv[0].toUint16(), argv[1].toUint16()); return s->r_acc; } @@ -195,14 +197,14 @@ reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) { if (subop == 0) { TextAlign alignment = (TextAlign)readSelectorValue(segMan, object, SELECTOR(mode)); - return g_sci->_gfxText32->createFontBitmap(width, height, rect, text, foreColor, backColor, skipColor, fontId, alignment, borderColor, dimmed, true); + return g_sci->_gfxText32->createFontBitmap(width, height, rect, text, foreColor, backColor, skipColor, fontId, alignment, borderColor, dimmed, true, true); } else { CelInfo32 celInfo; celInfo.type = kCelTypeView; celInfo.resourceId = readSelectorValue(segMan, object, SELECTOR(view)); celInfo.loopNo = readSelectorValue(segMan, object, SELECTOR(loop)); celInfo.celNo = readSelectorValue(segMan, object, SELECTOR(cel)); - return g_sci->_gfxText32->createFontBitmap(celInfo, rect, text, foreColor, backColor, fontId, skipColor, borderColor, dimmed); + return g_sci->_gfxText32->createFontBitmap(celInfo, rect, text, foreColor, backColor, fontId, skipColor, borderColor, dimmed, true); } } @@ -310,7 +312,7 @@ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) { // NOTE: The order of planeObj and showStyle are reversed // because this is how SCI3 called the corresponding method // on the KernelMgr - g_sci->_gfxFrameout->kernelSetShowStyle(argc, planeObj, type, seconds, back, priority, animate, refFrame, pFadeArray, divisions, blackScreen); + g_sci->_gfxTransitions32->kernelSetShowStyle(argc, planeObj, type, seconds, back, priority, animate, refFrame, pFadeArray, divisions, blackScreen); return s->r_acc; } @@ -534,13 +536,14 @@ reg_t kBitmapCreate(EngineState *s, int argc, reg_t *argv) { int16 scaledHeight = argc > 5 ? argv[5].toSint16() : g_sci->_gfxText32->_scaledHeight; bool useRemap = argc > 6 ? argv[6].toSint16() : false; - BitmapResource bitmap(s->_segMan, width, height, skipColor, 0, 0, scaledWidth, scaledHeight, 0, useRemap); + reg_t bitmapId; + SciBitmap &bitmap = *s->_segMan->allocateBitmap(&bitmapId, width, height, skipColor, 0, 0, scaledWidth, scaledHeight, 0, useRemap, true); memset(bitmap.getPixels(), backColor, width * height); - return bitmap.getObject(); + return bitmapId; } reg_t kBitmapDestroy(EngineState *s, int argc, reg_t *argv) { - s->_segMan->freeHunkEntry(argv[0]); + s->_segMan->freeBitmap(argv[0]); return s->r_acc; } @@ -550,7 +553,7 @@ reg_t kBitmapDrawLine(EngineState *s, int argc, reg_t *argv) { } reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv) { - BitmapResource bitmap(argv[0]); + SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]); CelObjView view(argv[1].toUint16(), argv[2].toSint16(), argv[3].toSint16()); const int16 x = argc > 4 ? argv[4].toSint16() : 0; @@ -580,7 +583,7 @@ reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv) { reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) { // called e.g. from TextButton::createBitmap() in Torin's Passage, script 64894 - BitmapResource bitmap(argv[0]); + SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]); Common::String text = s->_segMan->getString(argv[1]); Common::Rect textRect( argv[2].toSint16(), @@ -604,10 +607,10 @@ reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) { // Then clips. But this seems stupid. textRect.clip(Common::Rect(bitmap.getWidth(), bitmap.getHeight())); - reg_t textBitmapObject = g_sci->_gfxText32->createFontBitmap(textRect.width(), textRect.height(), Common::Rect(textRect.width(), textRect.height()), text, foreColor, backColor, skipColor, fontId, alignment, borderColor, dimmed, false); + reg_t textBitmapObject = g_sci->_gfxText32->createFontBitmap(textRect.width(), textRect.height(), Common::Rect(textRect.width(), textRect.height()), text, foreColor, backColor, skipColor, fontId, alignment, borderColor, dimmed, false, false); CelObjMem textCel(textBitmapObject); textCel.draw(bitmap.getBuffer(), textRect, Common::Point(textRect.left, textRect.top), false); - s->_segMan->freeHunkEntry(textBitmapObject); + s->_segMan->freeBitmap(textBitmapObject); return s->r_acc; } @@ -615,7 +618,7 @@ reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) { reg_t kBitmapDrawColor(EngineState *s, int argc, reg_t *argv) { // called e.g. from TextView::init() and TextView::draw() in Torin's Passage, script 64890 - BitmapResource bitmap(argv[0]); + SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]); Common::Rect fillRect( argv[1].toSint16(), argv[2].toSint16(), @@ -640,7 +643,7 @@ reg_t kBitmapInvert(EngineState *s, int argc, reg_t *argv) { } reg_t kBitmapSetDisplace(EngineState *s, int argc, reg_t *argv) { - BitmapResource bitmap(argv[0]); + SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]); bitmap.setDisplace(Common::Point(argv[1].toSint16(), argv[2].toSint16())); return s->r_acc; } @@ -760,28 +763,19 @@ reg_t kDeleteLine(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } +// Used by LSL6hires intro (room 110) reg_t kSetScroll(EngineState *s, int argc, reg_t *argv) { - // Called in the intro of LSL6 hires (room 110) - // The end effect of this is the same as the old screen scroll transition - - // 7 parameters - reg_t planeObject = argv[0]; - //int16 x = argv[1].toSint16(); - //int16 y = argv[2].toSint16(); - uint16 pictureId = argv[3].toUint16(); - // param 4: int (0 in LSL6, probably scroll direction? The picture in LSL6 scrolls down) - // param 5: int (first call is 1, then the subsequent one is 0 in LSL6) - // param 6: optional int (0 in LSL6) - - // Set the new picture directly for now - //writeSelectorValue(s->_segMan, planeObject, SELECTOR(left), x); - //writeSelectorValue(s->_segMan, planeObject, SELECTOR(top), y); - writeSelectorValue(s->_segMan, planeObject, SELECTOR(picture), pictureId); - // and update our draw list - g_sci->_gfxFrameout->kernelUpdatePlane(planeObject); - - // TODO - return kStub(s, argc, argv); + const reg_t plane = argv[0]; + const int16 deltaX = argv[1].toSint16(); + const int16 deltaY = argv[2].toSint16(); + const GuiResourceId pictureId = argv[3].toUint16(); + const bool animate = argv[4].toUint16(); + // NOTE: speed was accepted as an argument, but then never actually used + // const int16 speed = argc > 5 ? (bool)argv[5].toSint16() : -1; + const bool mirrorX = argc > 6 ? (bool)argv[6].toUint16() : false; + + g_sci->_gfxTransitions32->kernelSetScroll(plane, deltaX, deltaY, pictureId, animate, mirrorX); + return s->r_acc; } // Used by SQ6, script 900, the datacorder reprogramming puzzle (from room 270) diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp index c0da2daaeb..53be26b37f 100644 --- a/engines/sci/engine/klists.cpp +++ b/engines/sci/engine/klists.cpp @@ -374,13 +374,21 @@ reg_t kFindKey(EngineState *s, int argc, reg_t *argv) { reg_t kDeleteKey(EngineState *s, int argc, reg_t *argv) { reg_t node_pos = kFindKey(s, 2, argv); - Node *n; List *list = s->_segMan->lookupList(argv[0]); if (node_pos.isNull()) return NULL_REG; // Signal failure - n = s->_segMan->lookupNode(node_pos); + Node *n = s->_segMan->lookupNode(node_pos); + +#ifdef ENABLE_SCI32 + for (int i = 1; i <= list->numRecursions; ++i) { + if (list->nextNodes[i] == node_pos) { + list->nextNodes[i] = n->succ; + } + } +#endif + if (list->first == node_pos) list->first = n->succ; if (list->last == node_pos) @@ -544,9 +552,18 @@ reg_t kListEachElementDo(EngineState *s, int argc, reg_t *argv) { ObjVarRef address; + ++list->numRecursions; + + if (list->numRecursions > ARRAYSIZE(list->nextNodes)) { + error("Too much recursion in kListEachElementDo"); + } + while (curNode) { - // We get the next node here as the current node might be gone after the invoke - reg_t nextNode = curNode->succ; + // We get the next node here as the current node might be deleted by the + // invoke. In the case that the next node is also deleted, kDeleteKey + // needs to be able to adjust the location of the next node, which is + // why it is stored on the list instead of on the stack + list->nextNodes[list->numRecursions] = curNode->succ; curObject = curNode->value; // First, check if the target selector is a variable @@ -561,9 +578,11 @@ reg_t kListEachElementDo(EngineState *s, int argc, reg_t *argv) { invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2); } - curNode = s->_segMan->lookupNode(nextNode); + curNode = s->_segMan->lookupNode(list->nextNodes[list->numRecursions]); } + --list->numRecursions; + return s->r_acc; } diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 0d6831139a..c99540967c 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -20,6 +20,7 @@ * */ +#include "common/config-manager.h" #include "common/system.h" #include "sci/sci.h" @@ -410,7 +411,13 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) { // Debug setting in LSL7, specifies the room to start from. s->_segMan->strcpy(data, ""); } else if (setting == "game") { - // Hoyle 5 Demo startup. + // Hoyle 5 startup, specifies the number of the game to start. + s->_segMan->strcpy(data, ""); + } else if (setting == "laptop") { + // Hoyle 5 startup. + s->_segMan->strcpy(data, ""); + } else if (setting == "jumpto") { + // Hoyle 5 startup. s->_segMan->strcpy(data, ""); } else { error("GetConfig: Unknown configuration setting %s", setting.c_str()); @@ -536,7 +543,7 @@ enum kSciPlatforms { enum kPlatformOps { kPlatformUnk0 = 0, kPlatformCDSpeed = 1, - kPlatformUnk2 = 2, + kPlatformColorDepth = 2, kPlatformCDCheck = 3, kPlatformGetPlatform = 4, kPlatformUnk5 = 5, @@ -557,11 +564,6 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv) { return NULL_REG; } - if (g_sci->forceHiresGraphics()) { - // force Windows platform, so that hires-graphics are enabled - isWindows = true; - } - uint16 operation = (argc == 0) ? 0 : argv[0].toUint16(); switch (operation) { @@ -569,9 +571,9 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv) { // TODO: Returns CD Speed? warning("STUB: kPlatform(CDSpeed)"); break; - case kPlatformUnk2: + case kPlatformColorDepth: // Always returns 2 - return make_reg(0, 2); + return make_reg(0, /* 256-color */ 2); case kPlatformCDCheck: // TODO: Some sort of CD check? warning("STUB: kPlatform(CDCheck)"); @@ -585,9 +587,9 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv) { return make_reg(0, (isWindows) ? kSciPlatformWindows : kSciPlatformDOS); case kPlatformUnk5: // This case needs to return the opposite of case 6 to get hires graphics - return make_reg(0, !isWindows); + return make_reg(0, !ConfMan.getBool("enable_high_resolution_graphics")); case kPlatformIsHiRes: - return make_reg(0, isWindows); + return make_reg(0, ConfMan.getBool("enable_high_resolution_graphics")); case kPlatformIsItWindows: return make_reg(0, isWindows); default: diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp index 1096e78cca..86d8a4b817 100644 --- a/engines/sci/engine/kvideo.cpp +++ b/engines/sci/engine/kvideo.cpp @@ -61,33 +61,15 @@ void playVideo(Video::VideoDecoder *videoDecoder, VideoState videoState) { uint16 screenWidth = g_sci->_gfxScreen->getDisplayWidth(); uint16 screenHeight = g_sci->_gfxScreen->getDisplayHeight(); - videoState.fileName.toLowercase(); - bool isVMD = videoState.fileName.hasSuffix(".vmd"); - - if (screenWidth == 640 && width <= 320 && height <= 240 && ((videoState.flags & kDoubled) || !isVMD)) { + if (screenWidth == 640 && width <= 320 && height <= 240) { width *= 2; height *= 2; pitch *= 2; scaleBuffer = new byte[width * height * bytesPerPixel]; } - uint16 x, y; - - // Sanity check... - if (videoState.x > 0 && videoState.y > 0 && isVMD) { - x = videoState.x; - y = videoState.y; - - if (x + width > screenWidth || y + height > screenHeight) { - // Happens in the Lighthouse demo - warning("VMD video won't fit on screen, centering it instead"); - x = (screenWidth - width) / 2; - y = (screenHeight - height) / 2; - } - } else { - x = (screenWidth - width) / 2; - y = (screenHeight - height) / 2; - } + uint16 x = (screenWidth - width) / 2; + uint16 y = (screenHeight - height) / 2; bool skipVideo = false; EngineState *s = g_sci->getEngineState(); @@ -181,16 +163,6 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) { // TODO: This appears to be some sort of subop. case 0 contains the string // for the video, so we'll just play it from there for now. -#ifdef ENABLE_SCI32 - if (getSciVersion() >= SCI_VERSION_2_1_EARLY) { - // SCI2.1 always has argv[0] as 1, the rest of the arguments seem to - // follow SCI1.1/2. - if (argv[0].toUint16() != 1) - error("SCI2.1 kShowMovie argv[0] not 1"); - argv++; - argc--; - } -#endif switch (argv[0].toUint16()) { case 0: { Common::String filename = s->_segMan->getString(argv[1]); @@ -230,7 +202,7 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) { // We also won't be copying the screen to the SCI screen... if (g_system->getScreenFormat().bytesPerPixel != 1) initGraphics(screenWidth, screenHeight, screenWidth > 320); - else { + else if (getSciVersion() < SCI_VERSION_2) { g_sci->_gfxScreen->kernelSyncWithFramebuffer(); g_sci->_gfxPalette16->kernelSyncScreenPalette(); } @@ -243,52 +215,102 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) { } #ifdef ENABLE_SCI32 +reg_t kShowMovie32(EngineState *s, int argc, reg_t *argv) { + Common::String fileName = s->_segMan->getString(argv[0]); + const int16 numTicks = argv[1].toSint16(); + const int16 x = argc > 3 ? argv[2].toSint16() : 0; + const int16 y = argc > 3 ? argv[3].toSint16() : 0; -reg_t kRobot(EngineState *s, int argc, reg_t *argv) { - int16 subop = argv[0].toUint16(); - - switch (subop) { - case 0: { // init - int id = argv[1].toUint16(); - reg_t obj = argv[2]; - int16 flag = argv[3].toSint16(); - int16 x = argv[4].toUint16(); - int16 y = argv[5].toUint16(); - warning("kRobot(init), id %d, obj %04x:%04x, flag %d, x=%d, y=%d", id, PRINT_REG(obj), flag, x, y); - g_sci->_robotDecoder->load(id); - g_sci->_robotDecoder->start(); - g_sci->_robotDecoder->setPos(x, y); - } - break; - case 1: // LSL6 hires (startup) - // TODO - return NULL_REG; // an integer is expected - case 4: { // start - we don't really have a use for this one - //int id = argv[1].toUint16(); - //warning("kRobot(start), id %d", id); - } - break; - case 7: // unknown, called e.g. by Phantasmagoria - warning("kRobot(%d)", subop); - break; - case 8: // sync - //if (true) { // debug: automatically skip all robot videos - if (g_sci->_robotDecoder->endOfVideo()) { - g_sci->_robotDecoder->close(); - // Signal the engine scripts that the video is done - writeSelector(s->_segMan, argv[1], SELECTOR(signal), SIGNAL_REG); - } else { - writeSelector(s->_segMan, argv[1], SELECTOR(signal), NULL_REG); - } - break; - default: - warning("kRobot(%d)", subop); - break; - } + g_sci->_video32->getSEQPlayer().play(fileName, numTicks, x, y); return s->r_acc; } +reg_t kShowMovieWin(EngineState *s, int argc, reg_t *argv) { + if (!s) + return make_reg(0, getSciVersion()); + error("not supposed to call this"); +} + +reg_t kShowMovieWinOpen(EngineState *s, int argc, reg_t *argv) { + // SCI2.1 adds a movie ID to the call, but the movie ID is broken, + // so just ignore it + if (getSciVersion() > SCI_VERSION_2) { + ++argv; + --argc; + } + + const Common::String fileName = s->_segMan->getString(argv[0]); + return make_reg(0, g_sci->_video32->getAVIPlayer().open(fileName)); +} + +reg_t kShowMovieWinInit(EngineState *s, int argc, reg_t *argv) { + // SCI2.1 adds a movie ID to the call, but the movie ID is broken, + // so just ignore it + if (getSciVersion() > SCI_VERSION_2) { + ++argv; + --argc; + } + + const int16 x = argv[0].toSint16(); + const int16 y = argv[1].toSint16(); + const int16 width = argc > 3 ? argv[2].toSint16() : 0; + const int16 height = argc > 3 ? argv[3].toSint16() : 0; + return make_reg(0, g_sci->_video32->getAVIPlayer().init1x(x, y, width, height)); +} + +reg_t kShowMovieWinPlay(EngineState *s, int argc, reg_t *argv) { + if (getSciVersion() == SCI_VERSION_2) { + AVIPlayer::EventFlags flags = (AVIPlayer::EventFlags)argv[0].toUint16(); + return make_reg(0, g_sci->_video32->getAVIPlayer().playUntilEvent(flags)); + } else { + // argv[0] is a broken movie ID + const int16 from = argc > 2 ? argv[1].toSint16() : 0; + const int16 to = argc > 2 ? argv[2].toSint16() : 0; + const int16 showStyle = argc > 3 ? argv[3].toSint16() : 0; + const bool cue = argc > 4 ? (bool)argv[4].toSint16() : false; + return make_reg(0, g_sci->_video32->getAVIPlayer().play(from, to, showStyle, cue)); + } +} + +reg_t kShowMovieWinClose(EngineState *s, int argc, reg_t *argv) { + return make_reg(0, g_sci->_video32->getAVIPlayer().close()); +} + +reg_t kShowMovieWinGetDuration(EngineState *s, int argc, reg_t *argv) { + return make_reg(0, g_sci->_video32->getAVIPlayer().getDuration()); +} + +reg_t kShowMovieWinCue(EngineState *s, int argc, reg_t *argv) { + // SCI2.1 adds a movie ID to the call, but the movie ID is broken, + // so just ignore it + if (getSciVersion() > SCI_VERSION_2) { + ++argv; + --argc; + } + + const uint16 frameNo = argv[0].toUint16(); + return make_reg(0, g_sci->_video32->getAVIPlayer().cue(frameNo)); +} + +reg_t kShowMovieWinPlayUntilEvent(EngineState *s, int argc, reg_t *argv) { + const int defaultFlags = + AVIPlayer::kEventFlagEnd | + AVIPlayer::kEventFlagEscapeKey; + + // argv[0] is the movie number, which is not used by this method + const AVIPlayer::EventFlags flags = (AVIPlayer::EventFlags)(argc > 1 ? argv[1].toUint16() : defaultFlags); + + return make_reg(0, g_sci->_video32->getAVIPlayer().playUntilEvent(flags)); +} + +reg_t kShowMovieWinInitDouble(EngineState *s, int argc, reg_t *argv) { + // argv[0] is a broken movie ID + const int16 x = argv[1].toSint16(); + const int16 y = argv[2].toSint16(); + return make_reg(0, g_sci->_video32->getAVIPlayer().init2x(x, y)); +} + reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) { if (!s) return make_reg(0, getSciVersion()); diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 31fb848a2c..c4d53a2dc9 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -158,6 +158,24 @@ void syncWithSerializer(Common::Serializer &s, SciString &obj) { obj.setValue(i, value); } } + +void syncWithSerializer(Common::Serializer &s, SciBitmap *&obj) { + bool hasEntry; + if (s.isSaving()) { + hasEntry = obj != nullptr; + } + s.syncAsByte(hasEntry); + + if (hasEntry) { + if (s.isLoading()) { + obj = new SciBitmap; + } + + obj->saveLoadWithSerializer(s); + } else { + obj = nullptr; + } +} #endif #pragma mark - @@ -273,6 +291,8 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { } else if (type == SEG_TYPE_STRING) { // Set the correct segment for SCI32 strings _stringSegId = i; + } else if (s.getVersion() >= 36 && type == SEG_TYPE_BITMAP) { + _bitmapSegId = i; #endif } @@ -402,6 +422,7 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) { #ifdef ENABLE_SCI32 if (getSciVersion() >= SCI_VERSION_2) { g_sci->_gfxPalette32->saveLoadWithSerializer(s); + g_sci->_gfxRemap32->saveLoadWithSerializer(s); } else #endif g_sci->_gfxPalette16->saveLoadWithSerializer(s); @@ -687,6 +708,31 @@ void StringTable::saveLoadWithSerializer(Common::Serializer &ser) { sync_Table<StringTable>(ser, *this); } + +void BitmapTable::saveLoadWithSerializer(Common::Serializer &ser) { + if (ser.getVersion() < 36) { + return; + } + + sync_Table(ser, *this); +} + +void SciBitmap::saveLoadWithSerializer(Common::Serializer &s) { + if (s.getVersion() < 36) { + return; + } + + s.syncAsByte(_gc); + s.syncAsUint32LE(_dataSize); + if (s.isLoading()) { + _data = (byte *)malloc(_dataSize); + } + s.syncBytes(_data, _dataSize); + + if (s.isLoading()) { + _buffer = Buffer(getWidth(), getHeight(), getPixels()); + } +} #endif void GfxPalette::palVarySaveLoadPalette(Common::Serializer &s, Palette *palette) { diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h index 43909accf2..c5c2bcef08 100644 --- a/engines/sci/engine/savegame.h +++ b/engines/sci/engine/savegame.h @@ -37,6 +37,7 @@ struct EngineState; * * Version - new/changed feature * ============================= + * 36 - SCI32 bitmap segment * 35 - SCI32 remap * 34 - SCI32 palettes, and store play time in ticks * 33 - new overridePriority flag in MusicEntry @@ -60,7 +61,7 @@ struct EngineState; */ enum { - CURRENT_SAVEGAME_VERSION = 35, + CURRENT_SAVEGAME_VERSION = 36, MINIMUM_SAVEGAME_VERSION = 14 }; diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 95e3cd15f9..608452983a 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -43,6 +43,7 @@ SegManager::SegManager(ResourceManager *resMan, ScriptPatcher *scriptPatcher) #ifdef ENABLE_SCI32 _arraysSegId = 0; _stringSegId = 0; + _bitmapSegId = 0; #endif createClassTable(); @@ -72,6 +73,7 @@ void SegManager::resetSegMan() { #ifdef ENABLE_SCI32 _arraysSegId = 0; _stringSegId = 0; + _bitmapSegId = 0; #endif // Reinitialize class table @@ -941,6 +943,59 @@ void SegManager::freeString(reg_t addr) { stringTable.freeEntry(addr.getOffset()); } +#pragma mark - +#pragma mark Bitmaps + +SciBitmap *SegManager::allocateBitmap(reg_t *addr, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 paletteSize, const bool remap, const bool gc) { + BitmapTable *table; + int offset; + + if (!_bitmapSegId) { + table = (BitmapTable *)allocSegment(new BitmapTable(), &(_bitmapSegId)); + } else { + table = (BitmapTable *)_heap[_bitmapSegId]; + } + + offset = table->allocEntry(); + + *addr = make_reg(_bitmapSegId, offset); + SciBitmap *bitmap = table->at(offset); + + if (bitmap == nullptr) { + *addr = NULL_REG; + } + + bitmap->create(width, height, skipColor, displaceX, displaceY, scaledWidth, scaledHeight, paletteSize, remap, gc); + + return bitmap; +} + +SciBitmap *SegManager::lookupBitmap(const reg_t addr) { + if (_heap[addr.getSegment()]->getType() != SEG_TYPE_BITMAP) + error("Attempt to use non-bitmap %04x:%04x as bitmap", PRINT_REG(addr)); + + BitmapTable &bitmapTable = *(BitmapTable *)_heap[addr.getSegment()]; + + if (!bitmapTable.isValidEntry(addr.getOffset())) + error("Attempt to use invalid entry %04x:%04x as bitmap", PRINT_REG(addr)); + + return (bitmapTable.at(addr.getOffset())); +} + +void SegManager::freeBitmap(const reg_t addr) { + if (_heap[addr.getSegment()]->getType() != SEG_TYPE_BITMAP) + error("Attempt to free non-bitmap %04x:%04x as bitmap", PRINT_REG(addr)); + + BitmapTable &bitmapTable = *(BitmapTable *)_heap[addr.getSegment()]; + + if (!bitmapTable.isValidEntry(addr.getOffset())) + error("Attempt to free invalid entry %04x:%04x as bitmap", PRINT_REG(addr)); + + bitmapTable.freeEntry(addr.getOffset()); +} + +#pragma mark - + #endif void SegManager::createClassTable() { diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 9da7e58770..acebecea97 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -29,6 +29,10 @@ #include "sci/engine/vm.h" #include "sci/engine/vm_types.h" #include "sci/engine/segment.h" +#ifdef ENABLE_SCI32 +// TODO: Baaaad? +#include "sci/graphics/celobj32.h" +#endif namespace Sci { @@ -433,10 +437,15 @@ public: SciArray<reg_t> *allocateArray(reg_t *addr); SciArray<reg_t> *lookupArray(reg_t addr); void freeArray(reg_t addr); + SciString *allocateString(reg_t *addr); SciString *lookupString(reg_t addr); void freeString(reg_t addr); SegmentId getStringSegmentId() { return _stringSegId; } + + SciBitmap *allocateBitmap(reg_t *addr, const int16 width, const int16 height, const uint8 skipColor = kDefaultSkipColor, const int16 displaceX = 0, const int16 displaceY = 0, const int16 scaledWidth = kLowResX, const int16 scaledHeight = kLowResY, const uint32 paletteSize = 0, const bool remap = false, const bool gc = true); + SciBitmap *lookupBitmap(reg_t addr); + void freeBitmap(reg_t addr); #endif const Common::Array<SegmentObj *> &getSegments() const { return _heap; } @@ -462,6 +471,7 @@ private: #ifdef ENABLE_SCI32 SegmentId _arraysSegId; SegmentId _stringSegId; + SegmentId _bitmapSegId; #endif public: diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index 2cff799f4b..7943946ee4 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -70,6 +70,9 @@ SegmentObj *SegmentObj::createSegmentObj(SegmentType type) { case SEG_TYPE_STRING: mem = new StringTable(); break; + case SEG_TYPE_BITMAP: + mem = new BitmapTable(); + break; #endif default: error("Unknown SegmentObj type %d", type); diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index 50c77d0538..97a6cb585f 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -71,6 +71,7 @@ enum SegmentType { #ifdef ENABLE_SCI32 SEG_TYPE_ARRAY = 11, SEG_TYPE_STRING = 12, + SEG_TYPE_BITMAP = 13, #endif SEG_TYPE_MAX // For sanity checking @@ -199,6 +200,21 @@ struct Node { struct List { reg_t first; reg_t last; + +#ifdef ENABLE_SCI32 + /** + * The next node for each level of recursion during iteration over this list + * by kListEachElementDo. + */ + reg_t nextNodes[10]; + + /** + * The current level of recursion of kListEachElementDo for this list. + */ + int numRecursions; + + List() : numRecursions(0) {} +#endif }; struct Hunk { @@ -519,6 +535,305 @@ struct StringTable : public SegmentObjTable<SciString> { SegmentRef dereference(reg_t pointer); }; +#pragma mark - +#pragma mark Bitmaps + +enum { + kDefaultSkipColor = 250 +}; + +#define BITMAP_PROPERTY(size, property, offset)\ +inline uint##size get##property() const {\ + return READ_SCI11ENDIAN_UINT##size(_data + (offset));\ +}\ +inline void set##property(uint##size value) {\ + WRITE_SCI11ENDIAN_UINT##size(_data + (offset), (value));\ +} + +struct BitmapTable; + +/** + * A convenience class for creating and modifying in-memory + * bitmaps. + */ +class SciBitmap : public Common::Serializable { + byte *_data; + int _dataSize; + Buffer _buffer; + bool _gc; + +public: + enum BitmapFlags { + kBitmapRemap = 2 + }; + + /** + * Gets the size of the bitmap header for the current + * engine version. + */ + static inline uint16 getBitmapHeaderSize() { + // TODO: These values are accurate for each engine, but there may be no reason + // to not simply just always use size 40, since SCI2.1mid does not seem to + // actually store any data above byte 40, and SCI2 did not allow bitmaps with + // scaling resolutions other than the default (320x200). Perhaps SCI3 used + // the extra bytes, or there is some reason why they tried to align the header + // size with other headers like pic headers? +// uint32 bitmapHeaderSize; +// if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) { +// bitmapHeaderSize = 46; +// } else if (getSciVersion() == SCI_VERSION_2_1_EARLY) { +// bitmapHeaderSize = 40; +// } else { +// bitmapHeaderSize = 36; +// } +// return bitmapHeaderSize; + return 46; + } + + /** + * Gets the byte size of a bitmap with the given width + * and height. + */ + static inline uint32 getBitmapSize(const uint16 width, const uint16 height) { + return width * height + getBitmapHeaderSize(); + } + + inline SciBitmap() : _data(nullptr), _dataSize(0), _gc(true) {} + + inline SciBitmap(const SciBitmap &other) { + _dataSize = other._dataSize; + _data = (byte *)malloc(other._dataSize); + memcpy(_data, other._data, other._dataSize); + if (_dataSize) { + _buffer = Buffer(getWidth(), getHeight(), getPixels()); + } + _gc = other._gc; + } + + inline ~SciBitmap() { + free(_data); + _data = nullptr; + _dataSize = 0; + } + + inline SciBitmap &operator=(const SciBitmap &other) { + if (this == &other) { + return *this; + } + + free(_data); + _dataSize = other._dataSize; + _data = (byte *)malloc(other._dataSize); + memcpy(_data, other._data, _dataSize); + if (_dataSize) { + _buffer = Buffer(getWidth(), getHeight(), getPixels()); + } + _gc = other._gc; + + return *this; + } + + /** + * Allocates and initialises a new bitmap. + */ + inline void create(const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 paletteSize, const bool remap, const bool gc) { + + _dataSize = getBitmapSize(width, height) + paletteSize; + _data = (byte *)realloc(_data, _dataSize); + _gc = gc; + + const uint16 bitmapHeaderSize = getBitmapHeaderSize(); + + setWidth(width); + setHeight(height); + setDisplace(Common::Point(displaceX, displaceY)); + setSkipColor(skipColor); + _data[9] = 0; + WRITE_SCI11ENDIAN_UINT16(_data + 10, 0); + setRemap(remap); + setDataSize(width * height); + WRITE_SCI11ENDIAN_UINT32(_data + 16, 0); + setHunkPaletteOffset(paletteSize > 0 ? (width * height) : 0); + setDataOffset(bitmapHeaderSize); + setUncompressedDataOffset(bitmapHeaderSize); + setControlOffset(0); + setScaledWidth(scaledWidth); + setScaledHeight(scaledHeight); + + _buffer = Buffer(getWidth(), getHeight(), getPixels()); + } + + inline int getRawSize() const { + return _dataSize; + } + + inline byte *getRawData() const { + return _data; + } + + inline Buffer &getBuffer() { + return _buffer; + } + + inline bool getShouldGC() const { + return _gc; + } + + inline void enableGC() { + _gc = true; + } + + inline void disableGC() { + _gc = false; + } + + BITMAP_PROPERTY(16, Width, 0); + BITMAP_PROPERTY(16, Height, 2); + + inline Common::Point getDisplace() const { + return Common::Point( + (int16)READ_SCI11ENDIAN_UINT16(_data + 4), + (int16)READ_SCI11ENDIAN_UINT16(_data + 6) + ); + } + + inline void setDisplace(const Common::Point &displace) { + WRITE_SCI11ENDIAN_UINT16(_data + 4, (uint16)displace.x); + WRITE_SCI11ENDIAN_UINT16(_data + 6, (uint16)displace.y); + } + + inline uint8 getSkipColor() const { + return _data[8]; + } + + inline void setSkipColor(const uint8 skipColor) { + _data[8] = skipColor; + } + + inline bool getRemap() const { + return READ_SCI11ENDIAN_UINT16(_data + 10) & kBitmapRemap; + } + + inline void setRemap(const bool remap) { + uint16 flags = READ_SCI11ENDIAN_UINT16(_data + 10); + if (remap) { + flags |= kBitmapRemap; + } else { + flags &= ~kBitmapRemap; + } + WRITE_SCI11ENDIAN_UINT16(_data + 10, flags); + } + + BITMAP_PROPERTY(32, DataSize, 12); + + inline uint32 getHunkPaletteOffset() const { + return READ_SCI11ENDIAN_UINT32(_data + 20); + } + + inline void setHunkPaletteOffset(uint32 hunkPaletteOffset) { + if (hunkPaletteOffset) { + hunkPaletteOffset += getBitmapHeaderSize(); + } + + WRITE_SCI11ENDIAN_UINT32(_data + 20, hunkPaletteOffset); + } + + BITMAP_PROPERTY(32, DataOffset, 24); + + // NOTE: This property is used as a "magic number" for + // validating that a block of memory is a valid bitmap, + // and so is always set to the size of the header. + BITMAP_PROPERTY(32, UncompressedDataOffset, 28); + + // NOTE: This property always seems to be zero + BITMAP_PROPERTY(32, ControlOffset, 32); + + inline uint16 getScaledWidth() const { + if (getDataOffset() >= 40) { + return READ_SCI11ENDIAN_UINT16(_data + 36); + } + + // SCI2 bitmaps did not have scaling ability + return 320; + } + + inline void setScaledWidth(uint16 scaledWidth) { + if (getDataOffset() >= 40) { + WRITE_SCI11ENDIAN_UINT16(_data + 36, scaledWidth); + } + } + + inline uint16 getScaledHeight() const { + if (getDataOffset() >= 40) { + return READ_SCI11ENDIAN_UINT16(_data + 38); + } + + // SCI2 bitmaps did not have scaling ability + return 200; + } + + inline void setScaledHeight(uint16 scaledHeight) { + if (getDataOffset() >= 40) { + WRITE_SCI11ENDIAN_UINT16(_data + 38, scaledHeight); + } + } + + inline byte *getPixels() { + return _data + getUncompressedDataOffset(); + } + + inline byte *getHunkPalette() { + if (getHunkPaletteOffset() == 0) { + return nullptr; + } + return _data + getHunkPaletteOffset(); + } + + virtual void saveLoadWithSerializer(Common::Serializer &ser); +}; + +struct BitmapTable : public SegmentObjTable<SciBitmap *> { + BitmapTable() : SegmentObjTable<SciBitmap *>(SEG_TYPE_BITMAP) {} + + virtual ~BitmapTable() { + for (uint i = 0; i < _table.size(); i++) { + if (isValidEntry(i)) { + freeEntryContents(i); + } + } + } + + int allocEntry() { + int offset = SegmentObjTable<SciBitmap *>::allocEntry(); + at(offset) = new SciBitmap; + return offset; + } + + void freeEntryContents(const int offset) { + delete at(offset); + at(offset) = nullptr; + } + + virtual void freeEntry(const int offset) override { + SegmentObjTable<SciBitmap *>::freeEntry(offset); + freeEntryContents(offset); + } + + virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) override { + freeEntry(sub_addr.getOffset()); + } + + SegmentRef dereference(reg_t pointer) { + SegmentRef ret; + ret.isRaw = true; + ret.maxSize = at(pointer.getOffset())->getRawSize(); + ret.raw = at(pointer.getOffset())->getRawData(); + return ret; + } + + void saveLoadWithSerializer(Common::Serializer &ser); +}; + #endif diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 3e12084ed6..548fd477bf 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -405,6 +405,21 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) { error("[VM] k%s[%x]: no subfunction ID parameter given", kernelCall.name, kernelCallNr); if (argv[0].isPointer()) error("[VM] k%s[%x]: given subfunction ID is actually a pointer", kernelCall.name, kernelCallNr); + +#ifdef ENABLE_SCI32 + // The Windows version of kShowMovie has subops, but the subop number + // is put in the second parameter in SCI2.1+, even though every other + // kcall with subops puts the subop in the first parameter. To allow use + // of the normal subops system, we swap the arguments so the subop + // number is in the usual place. + if (getSciVersion() > SCI_VERSION_2 && + g_sci->getPlatform() == Common::kPlatformWindows && + strcmp(kernelCall.name, "ShowMovie") == 0) { + assert(argc > 1); + SWAP(argv[0], argv[1]); + } +#endif + const uint16 subId = argv[0].toUint16(); // Skip over subfunction-id argc--; diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index 2a2540b470..9b3b329418 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -298,6 +298,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = { { GID_KQ6, -1, 907, 0, "tomato", "doVerb", NULL, 2, { WORKAROUND_FAKE, 0 } }, // when looking at the rotten tomato in the inventory - bug #5331 { GID_KQ6, -1, 928, 0, NULL, "startText", NULL, 0, { WORKAROUND_FAKE, 0 } }, // gets caused by Text+Audio support (see script patcher) { GID_KQ7, -1, 64996, 0, "User", "handleEvent", NULL, 1, { WORKAROUND_FAKE, 0 } }, // called when pushing a keyboard key + { GID_KQ7, 2450, 2450, 0, "exBridge", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // called when walking up to the throne in the cave in chapter 2 { GID_LAURABOW, 37, 0, 0, "CB1", "doit", NULL, 1, { WORKAROUND_FAKE, 0 } }, // when going up the stairs - bug #5084 { GID_LAURABOW, -1, 967, 0, "myIcon", "cycle", NULL, 1, { WORKAROUND_FAKE, 0 } }, // having any portrait conversation coming up - initial bug #4971 { GID_LAURABOW2, -1, 24, 0, "gcWin", "open", NULL, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu @@ -491,7 +492,7 @@ const SciWorkaroundEntry kDisplay_workarounds[] = { { GID_PQ2, 23, 23, 0, "rm23Script", "elements", sig_kDisplay_pq2_1, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the 2nd page of pate's file - 0x75 as id - bug #5223 { GID_QFG1, 11, 11, 0, "battle", "init", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: When entering battle, 0x75 as id { GID_SQ4, 397, 0, 0, "", "export 12", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // FLOPPY: when going into the computer store - bug #5227 - { GID_SQ4, 391, 391, 0, "doCatalog", "mode", sig_kDisplay_sq4_1, 0, { WORKAROUND_IGNORE, 0 } }, // CD: clicking on catalog in roboter sale - a parameter is an object + { GID_SQ4, 391, 391, 0, "doCatalog", "changeState", sig_kDisplay_sq4_1, 0, { WORKAROUND_IGNORE, 0 } }, // CD: clicking on catalog in roboter sale - a parameter is an object { GID_SQ4, 391, 391, 0, "choosePlug", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // CD: ordering connector in roboter sale - a parameter is an object SCI_WORKAROUNDENTRY_TERMINATOR }; diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp index 48de054a31..311684d595 100644 --- a/engines/sci/graphics/celobj32.cpp +++ b/engines/sci/graphics/celobj32.cpp @@ -685,10 +685,6 @@ void CelObj::render(Buffer &target, const Common::Rect &targetRect, const Common } } -void dummyFill(Buffer &target, const Common::Rect &targetRect) { - target.fillRect(targetRect, 250); -} - void CelObj::drawHzFlip(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { render<MAPPER_NoMap, SCALER_NoScale<true, READER_Compressed> >(target, targetRect, scaledPosition); } @@ -1092,7 +1088,7 @@ CelObjMem::CelObjMem(const reg_t bitmapObject) { _celHeaderOffset = 0; _transparent = true; - BitmapResource bitmap(bitmapObject); + SciBitmap &bitmap = *g_sci->getEngineState()->_segMan->lookupBitmap(bitmapObject); _width = bitmap.getWidth(); _height = bitmap.getHeight(); _displace = bitmap.getDisplace(); @@ -1108,7 +1104,7 @@ CelObjMem *CelObjMem::duplicate() const { } byte *CelObjMem::getResPointer() const { - return g_sci->getEngineState()->_segMan->getHunkPointer(_info.bitmap); + return g_sci->getEngineState()->_segMan->lookupBitmap(_info.bitmap)->getRawData(); } #pragma mark - diff --git a/engines/sci/graphics/controls32.cpp b/engines/sci/graphics/controls32.cpp index 6b91bb4679..7689655d1d 100644 --- a/engines/sci/graphics/controls32.cpp +++ b/engines/sci/graphics/controls32.cpp @@ -54,18 +54,6 @@ GfxControls32::~GfxControls32() { } #pragma mark - -#pragma mark Garbage collection - -Common::Array<reg_t> GfxControls32::listObjectReferences() { - Common::Array<reg_t> ret; - ScrollWindowMap::const_iterator it; - for (it = _scrollWindows.begin(); it != _scrollWindows.end(); ++it) - ret.push_back(it->_value->getBitmap()); - - return ret; -} - -#pragma mark - #pragma mark Text input control reg_t GfxControls32::kernelEditText(const reg_t controlObject) { @@ -115,7 +103,10 @@ reg_t GfxControls32::kernelEditText(const reg_t controlObject) { reg_t planeObj = readSelector(_segMan, controlObject, SELECTOR(plane)); Plane *sourcePlane = g_sci->_gfxFrameout->getVisiblePlanes().findByObject(planeObj); if (sourcePlane == nullptr) { - error("Could not find plane %04x:%04x", PRINT_REG(planeObj)); + sourcePlane = g_sci->_gfxFrameout->getPlanes().findByObject(planeObj); + if (sourcePlane == nullptr) { + error("Could not find plane %04x:%04x", PRINT_REG(planeObj)); + } } editorPlaneRect.translate(sourcePlane->_gameRect.left, sourcePlane->_gameRect.top); @@ -127,7 +118,7 @@ reg_t GfxControls32::kernelEditText(const reg_t controlObject) { if (titleObject.isNull()) { bool dimmed = readSelectorValue(_segMan, controlObject, SELECTOR(dimmed)); - editor.bitmap = _gfxText32->createFontBitmap(width, height, editor.textRect, editor.text, editor.foreColor, editor.backColor, editor.skipColor, editor.fontId, alignment, editor.borderColor, dimmed, true); + editor.bitmap = _gfxText32->createFontBitmap(width, height, editor.textRect, editor.text, editor.foreColor, editor.backColor, editor.skipColor, editor.fontId, alignment, editor.borderColor, dimmed, true, false); } else { error("Titled bitmaps are not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); } @@ -318,7 +309,7 @@ reg_t GfxControls32::kernelEditText(const reg_t controlObject) { g_sci->_gfxFrameout->frameOut(true); } - _segMan->freeHunkEntry(editor.bitmap); + _segMan->freeBitmap(editor.bitmap); if (textChanged) { editor.text.trim(); @@ -380,6 +371,7 @@ void GfxControls32::flashCursor(TextEditor &editor) { #pragma mark Scrollable window control ScrollWindow::ScrollWindow(SegManager *segMan, const Common::Rect &gameRect, const Common::Point &position, const reg_t plane, const uint8 defaultForeColor, const uint8 defaultBackColor, const GuiResourceId defaultFontId, const TextAlign defaultAlignment, const int16 defaultBorderColor, const uint16 maxNumEntries) : + _segMan(segMan), _gfxText32(segMan, g_sci->_gfxCache), _maxNumEntries(maxNumEntries), _firstVisibleChar(0), @@ -421,13 +413,13 @@ ScrollWindow::ScrollWindow(SegManager *segMan, const Common::Rect &gameRect, con } assert(bitmapRect.width() > 0 && bitmapRect.height() > 0); - _bitmap = _gfxText32.createFontBitmap(bitmapRect.width(), bitmapRect.height(), _textRect, "", _foreColor, _backColor, skipColor, _fontId, _alignment, _borderColor, false, false); + _bitmap = _gfxText32.createFontBitmap(bitmapRect.width(), bitmapRect.height(), _textRect, "", _foreColor, _backColor, skipColor, _fontId, _alignment, _borderColor, false, false, false); debugC(1, kDebugLevelGraphics, "New ScrollWindow: textRect size: %d x %d, bitmap: %04x:%04x", _textRect.width(), _textRect.height(), PRINT_REG(_bitmap)); } ScrollWindow::~ScrollWindow() { - // _gfxText32._bitmap will get GCed once ScrollWindow is gone. + _segMan->freeBitmap(_bitmap); // _screenItem will be deleted by GfxFrameout } diff --git a/engines/sci/graphics/controls32.h b/engines/sci/graphics/controls32.h index 460b0b5625..680c70d2d6 100644 --- a/engines/sci/graphics/controls32.h +++ b/engines/sci/graphics/controls32.h @@ -227,6 +227,8 @@ public: const reg_t getBitmap() const { return _bitmap; } private: + SegManager *_segMan; + typedef Common::Array<ScrollWindowEntry> EntriesList; /** @@ -418,11 +420,6 @@ private: GfxText32 *_gfxText32; #pragma mark - -#pragma mark Garbage collection -public: - Common::Array<reg_t> listObjectReferences(); - -#pragma mark - #pragma mark Text input control public: reg_t kernelEditText(const reg_t controlObject); diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index 7bb9a4f5cf..21ffb5f937 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -51,31 +51,19 @@ #include "sci/graphics/text32.h" #include "sci/graphics/frameout.h" #include "sci/video/robot_decoder.h" +#include "sci/graphics/transitions32.h" namespace Sci { -static int dissolveSequences[2][20] = { - /* SCI2.1early- */ { 3, 6, 12, 20, 48, 96, 184, 272, 576, 1280, 3232, 6912, 13568, 24576, 46080 }, - /* SCI2.1mid+ */ { 0, 0, 3, 6, 12, 20, 48, 96, 184, 272, 576, 1280, 3232, 6912, 13568, 24576, 46080, 73728, 132096, 466944 } -}; -static int16 divisionsDefaults[2][16] = { - /* SCI2.1early- */ { 1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 40, 40, 101, 101 }, - /* SCI2.1mid+ */ { 1, 20, 20, 20, 20, 10, 10, 10, 10, 20, 20, 6, 10, 101, 101, 2 } -}; -static int16 unknownCDefaults[2][16] = { - /* SCI2.1early- */ { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 0, 0, 0, 0 }, - /* SCI2.1mid+ */ { 0, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 0, 0, 7, 7, 0 } -}; - -GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, GfxScreen *screen, GfxPalette32 *palette) : - _isHiRes(false), +GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, GfxScreen *screen, GfxPalette32 *palette, GfxTransitions32 *transitions) : + _isHiRes(ConfMan.getBool("enable_high_resolution_graphics")), _palette(palette), _resMan(resMan), _screen(screen), _segMan(segMan), + _transitions(transitions), _benchmarkingFinished(false), _throttleFrameOut(true), - _showStyles(nullptr), _throttleState(0), // TODO: Stop using _gfxScreen _currentBuffer(screen->getDisplayWidth(), screen->getDisplayHeight(), nullptr), @@ -87,31 +75,9 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd _currentBuffer.setPixels(calloc(1, screen->getDisplayWidth() * screen->getDisplayHeight())); - for (int i = 0; i < 236; i += 2) { - _styleRanges[i] = 0; - _styleRanges[i + 1] = -1; - } - for (int i = 236; i < ARRAYSIZE(_styleRanges); ++i) { - _styleRanges[i] = 0; - } - - // TODO: Make hires detection work uniformly across all SCI engine - // versions (this flag is normally passed by SCI::MakeGraphicsMgr - // to the GraphicsMgr constructor depending upon video configuration, - // so should be handled upstream based on game configuration instead - // of here) - if (getSciVersion() >= SCI_VERSION_2_1_EARLY && _resMan->detectHires()) { - _isHiRes = true; - } - - if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { - _dissolveSequenceSeeds = dissolveSequences[0]; - _defaultDivisions = divisionsDefaults[0]; - _defaultUnknownC = unknownCDefaults[0]; - } else { - _dissolveSequenceSeeds = dissolveSequences[1]; - _defaultDivisions = divisionsDefaults[1]; - _defaultUnknownC = unknownCDefaults[1]; + // QFG4 is the only SCI32 game that doesn't have a high-resolution toggle + if (g_sci->getGameId() == GID_QFG4) { + _isHiRes = false; } switch (g_sci->getGameId()) { @@ -515,12 +481,12 @@ void GfxFrameout::updatePlane(Plane &plane) { #pragma mark - #pragma mark Pics -void GfxFrameout::kernelAddPicAt(const reg_t planeObject, const GuiResourceId pictureId, const int16 x, const int16 y, const bool mirrorX) { +void GfxFrameout::kernelAddPicAt(const reg_t planeObject, const GuiResourceId pictureId, const int16 x, const int16 y, const bool mirrorX, const bool deleteDuplicate) { Plane *plane = _planes.findByObject(planeObject); if (plane == nullptr) { error("kAddPicAt: Plane %04x:%04x not found", PRINT_REG(planeObject)); } - plane->addPic(pictureId, Common::Point(x, y), mirrorX); + plane->addPic(pictureId, Common::Point(x, y), mirrorX, deleteDuplicate); } #pragma mark - @@ -587,6 +553,115 @@ void GfxFrameout::frameOut(const bool shouldShowBits, const Common::Rect &eraseR // } } +void GfxFrameout::palMorphFrameOut(const int8 *styleRanges, PlaneShowStyle *showStyle) { + Palette sourcePalette(_palette->getNextPalette()); + alterVmap(sourcePalette, sourcePalette, -1, styleRanges); + + int16 prevRoom = g_sci->getEngineState()->variables[VAR_GLOBAL][12].toSint16(); + + Common::Rect rect(_screen->getDisplayWidth(), _screen->getDisplayHeight()); + _showList.add(rect); + showBits(); + + // NOTE: The original engine allocated these as static arrays of 100 + // pointers to ScreenItemList / RectList + ScreenItemListList screenItemLists; + EraseListList eraseLists; + + screenItemLists.resize(_planes.size()); + eraseLists.resize(_planes.size()); + + if (g_sci->_gfxRemap32->getRemapCount() > 0 && _remapOccurred) { + remapMarkRedraw(); + } + + calcLists(screenItemLists, eraseLists); + for (ScreenItemListList::iterator list = screenItemLists.begin(); list != screenItemLists.end(); ++list) { + list->sort(); + } + + for (ScreenItemListList::iterator list = screenItemLists.begin(); list != screenItemLists.end(); ++list) { + for (DrawList::iterator drawItem = list->begin(); drawItem != list->end(); ++drawItem) { + (*drawItem)->screenItem->getCelObj().submitPalette(); + } + } + + _remapOccurred = _palette->updateForFrame(); + _frameNowVisible = false; + + for (PlaneList::size_type i = 0; i < _planes.size(); ++i) { + drawEraseList(eraseLists[i], *_planes[i]); + drawScreenItemList(screenItemLists[i]); + } + + Palette nextPalette(_palette->getNextPalette()); + + if (prevRoom < 1000) { + for (int i = 0; i < ARRAYSIZE(sourcePalette.colors); ++i) { + if (styleRanges[i] == -1 || styleRanges[i] == 0) { + sourcePalette.colors[i] = nextPalette.colors[i]; + sourcePalette.colors[i].used = true; + } + } + } else { + for (int i = 0; i < ARRAYSIZE(sourcePalette.colors); ++i) { + if (styleRanges[i] == -1 || validZeroStyle(styleRanges[i], i)) { + sourcePalette.colors[i] = nextPalette.colors[i]; + sourcePalette.colors[i].used = true; + } + } + } + + _palette->submit(sourcePalette); + _palette->updateFFrame(); + _palette->updateHardware(); + alterVmap(nextPalette, sourcePalette, 1, _transitions->_styleRanges); + + if (showStyle && showStyle->type != kShowStyleMorph) { + _transitions->processEffects(*showStyle); + } else { + showBits(); + } + + _frameNowVisible = true; + + for (PlaneList::iterator plane = _planes.begin(); plane != _planes.end(); ++plane) { + (*plane)->_redrawAllCount = getScreenCount(); + } + + if (g_sci->_gfxRemap32->getRemapCount() > 0 && _remapOccurred) { + remapMarkRedraw(); + } + + calcLists(screenItemLists, eraseLists); + for (ScreenItemListList::iterator list = screenItemLists.begin(); list != screenItemLists.end(); ++list) { + list->sort(); + } + + for (ScreenItemListList::iterator list = screenItemLists.begin(); list != screenItemLists.end(); ++list) { + for (DrawList::iterator drawItem = list->begin(); drawItem != list->end(); ++drawItem) { + (*drawItem)->screenItem->getCelObj().submitPalette(); + } + } + + _remapOccurred = _palette->updateForFrame(); + // NOTE: During this second loop, `_frameNowVisible = false` is + // inside the next loop in SCI2.1mid + _frameNowVisible = false; + + for (PlaneList::size_type i = 0; i < _planes.size(); ++i) { + drawEraseList(eraseLists[i], *_planes[i]); + drawScreenItemList(screenItemLists[i]); + } + + _palette->submit(nextPalette); + _palette->updateFFrame(); + _palette->updateHardware(false); + showBits(); + + _frameNowVisible = true; +} + /** * Determines the parts of `r` that aren't overlapped by `other`. * Returns -1 if `r` and `other` have no intersection. @@ -1038,118 +1113,6 @@ void GfxFrameout::mergeToShowList(const Common::Rect &drawRect, RectList &showLi } } -void GfxFrameout::palMorphFrameOut(const int8 *styleRanges, const ShowStyleEntry *showStyle) { - Palette sourcePalette(_palette->getNextPalette()); - alterVmap(sourcePalette, sourcePalette, -1, styleRanges); - - int16 prevRoom = g_sci->getEngineState()->variables[VAR_GLOBAL][12].toSint16(); - - Common::Rect rect(_screen->getDisplayWidth(), _screen->getDisplayHeight()); - _showList.add(rect); - showBits(); - - // NOTE: The original engine allocated these as static arrays of 100 - // pointers to ScreenItemList / RectList - ScreenItemListList screenItemLists; - EraseListList eraseLists; - - screenItemLists.resize(_planes.size()); - eraseLists.resize(_planes.size()); - - if (g_sci->_gfxRemap32->getRemapCount() > 0 && _remapOccurred) { - remapMarkRedraw(); - } - - calcLists(screenItemLists, eraseLists); - for (ScreenItemListList::iterator list = screenItemLists.begin(); list != screenItemLists.end(); ++list) { - list->sort(); - } - - for (ScreenItemListList::iterator list = screenItemLists.begin(); list != screenItemLists.end(); ++list) { - for (DrawList::iterator drawItem = list->begin(); drawItem != list->end(); ++drawItem) { - (*drawItem)->screenItem->getCelObj().submitPalette(); - } - } - - _remapOccurred = _palette->updateForFrame(); - _frameNowVisible = false; - - for (PlaneList::size_type i = 0; i < _planes.size(); ++i) { - drawEraseList(eraseLists[i], *_planes[i]); - drawScreenItemList(screenItemLists[i]); - } - - Palette nextPalette(_palette->getNextPalette()); - - if (prevRoom < 1000) { - for (int i = 0; i < ARRAYSIZE(sourcePalette.colors); ++i) { - if (styleRanges[i] == -1 || styleRanges[i] == 0) { - sourcePalette.colors[i] = nextPalette.colors[i]; - sourcePalette.colors[i].used = true; - } - } - } else { - for (int i = 0; i < ARRAYSIZE(sourcePalette.colors); ++i) { - // TODO: Limiting range 72 to 103 is NOT present in every game - if (styleRanges[i] == -1 || (styleRanges[i] == 0 && i > 71 && i < 104)) { - sourcePalette.colors[i] = nextPalette.colors[i]; - sourcePalette.colors[i].used = true; - } - } - } - - _palette->submit(sourcePalette); - _palette->updateFFrame(); - _palette->updateHardware(); - alterVmap(nextPalette, sourcePalette, 1, _styleRanges); - - if (showStyle && showStyle->type != kShowStyleUnknown) { -// TODO: SCI2.1mid transition effects -// processEffects(); - warning("Transition %d not implemented!", showStyle->type); - } else { - showBits(); - } - - _frameNowVisible = true; - - for (PlaneList::iterator plane = _planes.begin(); plane != _planes.end(); ++plane) { - (*plane)->_redrawAllCount = getScreenCount(); - } - - if (g_sci->_gfxRemap32->getRemapCount() > 0 && _remapOccurred) { - remapMarkRedraw(); - } - - calcLists(screenItemLists, eraseLists); - for (ScreenItemListList::iterator list = screenItemLists.begin(); list != screenItemLists.end(); ++list) { - list->sort(); - } - - for (ScreenItemListList::iterator list = screenItemLists.begin(); list != screenItemLists.end(); ++list) { - for (DrawList::iterator drawItem = list->begin(); drawItem != list->end(); ++drawItem) { - (*drawItem)->screenItem->getCelObj().submitPalette(); - } - } - - _remapOccurred = _palette->updateForFrame(); - // NOTE: During this second loop, `_frameNowVisible = false` is - // inside the next loop in SCI2.1mid - _frameNowVisible = false; - - for (PlaneList::size_type i = 0; i < _planes.size(); ++i) { - drawEraseList(eraseLists[i], *_planes[i]); - drawScreenItemList(screenItemLists[i]); - } - - _palette->submit(nextPalette); - _palette->updateFFrame(); - _palette->updateHardware(false); - showBits(); - - _frameNowVisible = true; -} - void GfxFrameout::showBits() { for (RectList::const_iterator rect = _showList.begin(); rect != _showList.end(); ++rect) { Common::Rect rounded(**rect); @@ -1176,6 +1139,13 @@ void GfxFrameout::showBits() { byte *sourceBuffer = (byte *)_currentBuffer.getPixels() + rounded.top * _currentBuffer.screenWidth + rounded.left; + // TODO: Sometimes transition screen items generate zero-dimension + // show rectangles. Is this a bug? + if (rounded.width() == 0 || rounded.height() == 0) { + warning("Zero-dimension show rectangle ignored"); + continue; + } + g_system->copyRectToScreen(sourceBuffer, _currentBuffer.screenWidth, rounded.left, rounded.top, rounded.width(), rounded.height()); } @@ -1233,7 +1203,6 @@ void GfxFrameout::alterVmap(const Palette &palette1, const Palette &palette2, co } } - // NOTE: This is currBuffer->ptr in SCI engine byte *pixels = (byte *)_currentBuffer.getPixels(); for (int pixelIndex = 0, numPixels = _currentBuffer.screenWidth * _currentBuffer.screenHeight; pixelIndex < numPixels; ++pixelIndex) { @@ -1256,346 +1225,16 @@ void GfxFrameout::alterVmap(const Palette &palette1, const Palette &palette2, co } } -void GfxFrameout::kernelSetPalStyleRange(const uint8 fromColor, const uint8 toColor) { - if (toColor > fromColor) { - return; - } - - for (int i = fromColor; i < toColor; ++i) { - _styleRanges[i] = 0; - } -} - -inline ShowStyleEntry * GfxFrameout::findShowStyleForPlane(const reg_t planeObj) const { - ShowStyleEntry *entry = _showStyles; - while (entry != nullptr) { - if (entry->plane == planeObj) { - break; - } - entry = entry->next; - } - - return entry; -} - -inline ShowStyleEntry *GfxFrameout::deleteShowStyleInternal(ShowStyleEntry *const showStyle) { - ShowStyleEntry *lastEntry = nullptr; - - for (ShowStyleEntry *testEntry = _showStyles; testEntry != nullptr; testEntry = testEntry->next) { - if (testEntry == showStyle) { - break; - } - lastEntry = testEntry; - } - - if (lastEntry == nullptr) { - _showStyles = showStyle->next; - lastEntry = _showStyles; - } else { - lastEntry->next = showStyle->next; - } - - delete[] showStyle->fadeColorRanges; - delete showStyle; - - // TODO: Verify that this is the correct entry to return - // for the loop in processShowStyles to work correctly - return lastEntry; -} - -// TODO: 10-argument version is only in SCI3; argc checks are currently wrong for this version -// and need to be fixed in future -// TODO: SQ6 does not use 'priority' (exists since SCI2) or 'blackScreen' (exists since SCI3); -// check to see if other versions use or if they are just always ignored -void GfxFrameout::kernelSetShowStyle(const uint16 argc, const reg_t planeObj, const ShowStyleType type, const int16 seconds, const int16 back, const int16 priority, const int16 animate, const int16 frameOutNow, reg_t pFadeArray, int16 divisions, const int16 blackScreen) { - - bool hasDivisions = false; - bool hasFadeArray = false; - - // KQ7 2.0b uses a mismatched version of the Styler script (SCI2.1early script - // for SCI2.1mid engine), so the calls it makes to kSetShowStyle are wrong and - // put `divisions` where `pFadeArray` is supposed to be - if (getSciVersion() == SCI_VERSION_2_1_MIDDLE && g_sci->getGameId() == GID_KQ7) { - hasDivisions = argc > 7; - hasFadeArray = false; - divisions = argc > 7 ? pFadeArray.toSint16() : -1; - pFadeArray = NULL_REG; - } else if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { - hasDivisions = argc > 7; - hasFadeArray = false; - } else if (getSciVersion() < SCI_VERSION_3) { - hasDivisions = argc > 8; - hasFadeArray = argc > 7; - } else { - hasDivisions = argc > 9; - hasFadeArray = argc > 8; - } - - bool isFadeUp; - int16 color; - if (back != -1) { - isFadeUp = false; - color = back; - } else { - isFadeUp = true; - color = 0; - } - - if ((getSciVersion() < SCI_VERSION_2_1_MIDDLE && type == 15) || type > 15) { - error("Illegal show style %d for plane %04x:%04x", type, PRINT_REG(planeObj)); - } - - Plane *plane = _planes.findByObject(planeObj); - if (plane == nullptr) { - error("Plane %04x:%04x is not present in active planes list", PRINT_REG(planeObj)); - } - - bool createNewEntry = true; - ShowStyleEntry *entry = findShowStyleForPlane(planeObj); - if (entry != nullptr) { - // TODO: SCI2.1early has different criteria for show style reuse - bool useExisting = true; - - if (useExisting) { - useExisting = entry->divisions == (hasDivisions ? divisions : _defaultDivisions[type]) && entry->unknownC == _defaultUnknownC[type]; - } - - if (useExisting) { - createNewEntry = false; - isFadeUp = true; - entry->currentStep = 0; - } else { - isFadeUp = true; - color = entry->color; - deleteShowStyleInternal(entry/*, true*/); - entry = nullptr; - } - } - - if (type > 0) { - if (createNewEntry) { - entry = new ShowStyleEntry; - // NOTE: SCI2.1 engine tests if allocation returned a null pointer - // but then only avoids setting currentStep if this is so. Since - // this is a nonsensical approach, we do not do that here - entry->currentStep = 0; - entry->unknownC = _defaultUnknownC[type]; - entry->processed = false; - entry->divisions = hasDivisions ? divisions : _defaultDivisions[type]; - entry->plane = planeObj; - - entry->fadeColorRanges = nullptr; - if (hasFadeArray) { - // NOTE: SCI2.1mid engine does no check to verify that an array is - // successfully retrieved, and SegMan will cause a fatal error - // if we try to use a memory segment that is not an array - SciArray<reg_t> *table = _segMan->lookupArray(pFadeArray); - - uint32 rangeCount = table->getSize(); - entry->fadeColorRangesCount = rangeCount; - - // NOTE: SCI engine code always allocates memory even if the range - // table has no entries, but this does not really make sense, so - // we avoid the allocation call in this case - if (rangeCount > 0) { - entry->fadeColorRanges = new uint16[rangeCount]; - for (size_t i = 0; i < rangeCount; ++i) { - entry->fadeColorRanges[i] = table->getValue(i).toUint16(); - } - } - } else { - entry->fadeColorRangesCount = 0; - } - } - - // NOTE: The original engine had no nullptr check and would just crash - // if it got to here - if (entry == nullptr) { - error("Cannot edit non-existing ShowStyle entry"); - } - - entry->fadeUp = isFadeUp; - entry->color = color; - entry->nextTick = g_sci->getTickCount(); - entry->type = type; - entry->animate = animate; - entry->delay = (seconds * 60 + entry->divisions - 1) / entry->divisions; - - if (entry->delay == 0) { - if (entry->fadeColorRanges != nullptr) { - delete[] entry->fadeColorRanges; - } - delete entry; - error("ShowStyle has no duration"); - } - - if (frameOutNow) { - Common::Rect frameOutRect(0, 0); - frameOut(false, frameOutRect); - } - - if (createNewEntry) { - // TODO: Implement SCI2.1early and SCI3 - entry->next = _showStyles; - _showStyles = entry; - } - } -} - -// NOTE: Different version of SCI engine support different show styles -// SCI2 implements 0, 1/3/5/7/9, 2/4/6/8/10, 11, 12, 13, 14 -// SCI2.1 implements 0, 1/2/3/4/5/6/7/8/9/10/11/12/15, 13, 14 -// SCI3 implements 0, 1/3/5/7/9, 2/4/6/8/10, 11, 12/15, 13, 14 -// TODO: Sierra code needs to be replaced with code that uses the -// computed entry->delay property instead of just counting divisors, -// as the latter is machine-speed-dependent and leads to wrong -// transition speeds -void GfxFrameout::processShowStyles() { - uint32 now = g_sci->getTickCount(); - - bool continueProcessing; - - // TODO: Change to bool? Engine uses inc to set the value to true, - // but there does not seem to be any reason to actually count how - // many times it was set - int doFrameOut; - do { - continueProcessing = false; - doFrameOut = 0; - ShowStyleEntry *showStyle = _showStyles; - while (showStyle != nullptr) { - bool retval = false; - - if (!showStyle->animate) { - ++doFrameOut; - } - - if (showStyle->nextTick < now || !showStyle->animate) { - // TODO: Different versions of SCI use different processors! - // This is the SQ6/KQ7/SCI2.1mid table. - switch (showStyle->type) { - case kShowStyleNone: { - retval = processShowStyleNone(showStyle); - break; - } - case kShowStyleHShutterOut: - case kShowStyleVShutterOut: - case kShowStyleWipeLeft: - case kShowStyleWipeUp: - case kShowStyleIrisOut: - case kShowStyleHShutterIn: - case kShowStyleVShutterIn: - case kShowStyleWipeRight: - case kShowStyleWipeDown: - case kShowStyleIrisIn: - case kShowStyle11: - case kShowStyle12: - case kShowStyleUnknown: { - retval = processShowStyleMorph(showStyle); - break; - } - case kShowStyleFadeOut: { - retval = processShowStyleFade(-1, showStyle); - break; - } - case kShowStyleFadeIn: { - retval = processShowStyleFade(1, showStyle); - break; - } - } - } - - if (!retval) { - continueProcessing = true; - } - - if (retval && showStyle->processed) { - showStyle = deleteShowStyleInternal(showStyle); - } else { - showStyle = showStyle->next; - } - } - - if (doFrameOut) { - frameOut(true); - - // TODO: Transitions without the âanimateâ flag are too - // fast, but the throttle value is arbitrary. Someone on - // real hardware probably needs to test what the actual - // speed of these transitions should be - EngineState *state = g_sci->getEngineState(); - state->speedThrottler(33); - state->_throttleTrigger = true; - } - } while(continueProcessing && doFrameOut); -} - -bool GfxFrameout::processShowStyleNone(ShowStyleEntry *const showStyle) { - if (showStyle->fadeUp) { - _palette->setFade(100, 0, 255); - } else { - _palette->setFade(0, 0, 255); - } - - showStyle->processed = true; - return true; -} - -bool GfxFrameout::processShowStyleMorph(ShowStyleEntry *const showStyle) { - palMorphFrameOut(_styleRanges, showStyle); - showStyle->processed = true; - return true; -} - -// TODO: Normalise use of 'entry' vs 'showStyle' -bool GfxFrameout::processShowStyleFade(const int direction, ShowStyleEntry *const showStyle) { - bool unchanged = true; - if (showStyle->currentStep < showStyle->divisions) { - int percent; - if (direction <= 0) { - percent = showStyle->divisions - showStyle->currentStep - 1; - } else { - percent = showStyle->currentStep; - } - - percent *= 100; - percent /= showStyle->divisions - 1; - - if (showStyle->fadeColorRangesCount > 0) { - for (int i = 0, len = showStyle->fadeColorRangesCount; i < len; i += 2) { - _palette->setFade(percent, showStyle->fadeColorRanges[i], showStyle->fadeColorRanges[i + 1]); - } - } else { - _palette->setFade(percent, 0, 255); - } - - ++showStyle->currentStep; - showStyle->nextTick += showStyle->delay; - unchanged = false; - } - - if (showStyle->currentStep >= showStyle->divisions && unchanged) { - if (direction > 0) { - showStyle->processed = true; - } - - return true; - } - - return false; -} - void GfxFrameout::kernelFrameOut(const bool shouldShowBits) { - if (_showStyles != nullptr) { - processShowStyles(); + if (_transitions->hasShowStyles()) { + _transitions->processShowStyles(); } else if (_palMorphIsOn) { - palMorphFrameOut(_styleRanges, nullptr); + palMorphFrameOut(_transitions->_styleRanges, nullptr); _palMorphIsOn = false; } else { -// TODO: Window scroll -// if (g_PlaneScroll) { -// processScrolls(); -// } + if (_transitions->hasScrolls()) { + _transitions->processScrolls(); + } frameOut(shouldShowBits); } @@ -1607,10 +1246,10 @@ void GfxFrameout::throttle() { if (_throttleFrameOut) { uint8 throttleTime; if (_throttleState == 2) { - throttleTime = 17; + throttleTime = 16; _throttleState = 0; } else { - throttleTime = 16; + throttleTime = 17; ++_throttleState; } @@ -1619,6 +1258,14 @@ void GfxFrameout::throttle() { } } +void GfxFrameout::showRect(const Common::Rect &rect) { + if (!rect.isEmpty()) { + _showList.clear(); + _showList.add(rect); + showBits(); + } +} + #pragma mark - #pragma mark Mouse cursor diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index 99658ede6a..012ecf9e64 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -27,130 +27,13 @@ #include "sci/graphics/screen_item32.h" namespace Sci { -// TODO: Don't do this this way -int splitRects(Common::Rect r, const Common::Rect &other, Common::Rect(&outRects)[4]); - -// TODO: Verify display styles and adjust names appropriately for -// types 1 through 12 & 15 (others are correct) -// Names should be: -// * VShutterIn, VShutterOut -// * HShutterIn, HShutterOut -// * WipeLeft, WipeRight, WipeDown, WipeUp -// * PixelDissolve -// * ShutDown and Kill? (and Plain and Fade?) -enum ShowStyleType /* : uint8 */ { - kShowStyleNone = 0, - kShowStyleHShutterOut = 1, - kShowStyleHShutterIn = 2, - kShowStyleVShutterOut = 3, - kShowStyleVShutterIn = 4, - kShowStyleWipeLeft = 5, - kShowStyleWipeRight = 6, - kShowStyleWipeUp = 7, - kShowStyleWipeDown = 8, - kShowStyleIrisOut = 9, - kShowStyleIrisIn = 10, - kShowStyle11 = 11, - kShowStyle12 = 12, - kShowStyleFadeOut = 13, - kShowStyleFadeIn = 14, - // TODO: Only in SCI3 - kShowStyleUnknown = 15 -}; - -/** - * Show styles represent transitions applied to draw planes. - * One show style per plane can be active at a time. - */ -struct ShowStyleEntry { - /** - * The ID of the plane this show style belongs to. - * In SCI2.1mid (at least SQ6), per-plane transitions - * were removed and a single plane ID is used. - */ - reg_t plane; - - /** - * The type of the transition. - */ - ShowStyleType type; - - // TODO: This name is probably incorrect - bool fadeUp; - - /** - * The number of steps for the show style. - */ - int16 divisions; - - // NOTE: This property exists from SCI2 through at least - // SCI2.1mid but is never used in the actual processing - // of the styles? - int unknownC; - - /** - * The color used by transitions that draw CelObjColor - * screen items. -1 for transitions that do not draw - * screen items. - */ - int16 color; - - // TODO: Probably uint32 - // TODO: This field probably should be used in order to - // provide time-accurate processing of show styles. In the - // actual SCI engine (at least 2â2.1mid) it appears that - // style transitions are drawn âas fast as possibleâ, one - // step per loop, even though this delay field exists - int delay; - - // TODO: Probably bool, but never seems to be true? - int animate; - - /** - * The wall time at which the next step of the animation - * should execute. - */ - uint32 nextTick; - - /** - * During playback of the show style, the current step - * (out of divisions). - */ - int currentStep; - - /** - * The next show style. - */ - ShowStyleEntry *next; - - /** - * Whether or not this style has finished running and - * is ready for disposal. - */ - bool processed; - - // - // Engine specific properties for SCI2.1mid through SCI3 - // - - /** - * The number of entries in the fadeColorRanges array. - */ - uint8 fadeColorRangesCount; - - /** - * A pointer to an dynamically sized array of palette - * indexes, in the order [ fromColor, toColor, ... ]. - * Only colors within this range are transitioned. - */ - uint16 *fadeColorRanges; -}; - typedef Common::Array<DrawList> ScreenItemListList; typedef Common::Array<RectList> EraseListList; class GfxCoordAdjuster32; class GfxScreen; +class GfxTransitions32; +struct PlaneShowStyle; /** * Frameout class, kFrameout and relevant functions for SCI32 games. @@ -158,7 +41,6 @@ class GfxScreen; */ class GfxFrameout { private: - bool _isHiRes; GfxCoordAdjuster32 *_coordAdjuster; GfxPalette32 *_palette; ResourceManager *_resMan; @@ -166,7 +48,7 @@ private: SegManager *_segMan; public: - GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, GfxScreen *screen, GfxPalette32 *palette); + GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, GfxScreen *screen, GfxPalette32 *palette, GfxTransitions32 *transitions); ~GfxFrameout(); void clear(); @@ -284,40 +166,13 @@ public: #pragma mark - #pragma mark Pics public: - void kernelAddPicAt(const reg_t planeObject, const GuiResourceId pictureId, const int16 pictureX, const int16 pictureY, const bool mirrorX); - -#pragma mark - - - // TODO: Remap-related? - void kernelSetPalStyleRange(const uint8 fromColor, const uint8 toColor); - -#pragma mark - -#pragma mark Transitions -private: - int *_dissolveSequenceSeeds; - int16 *_defaultDivisions; - int16 *_defaultUnknownC; - - /** - * TODO: Documentation - */ - ShowStyleEntry *_showStyles; - - inline ShowStyleEntry *findShowStyleForPlane(const reg_t planeObj) const; - inline ShowStyleEntry *deleteShowStyleInternal(ShowStyleEntry *const showStyle); - void processShowStyles(); - bool processShowStyleNone(ShowStyleEntry *showStyle); - bool processShowStyleMorph(ShowStyleEntry *showStyle); - bool processShowStyleFade(const int direction, ShowStyleEntry *showStyle); - -public: - // NOTE: This signature is taken from SCI3 Phantasmagoria 2 - // and is valid for all implementations of SCI32 - void kernelSetShowStyle(const uint16 argc, const reg_t planeObj, const ShowStyleType type, const int16 seconds, const int16 direction, const int16 priority, const int16 animate, const int16 frameOutNow, reg_t pFadeArray, int16 divisions, const int16 blackScreen); + void kernelAddPicAt(const reg_t planeObject, const GuiResourceId pictureId, const int16 pictureX, const int16 pictureY, const bool mirrorX, const bool deleteDuplicate); #pragma mark - #pragma mark Rendering private: + GfxTransitions32 *_transitions; + /** * State tracker to provide more accurate 60fps * video throttling. @@ -325,11 +180,6 @@ private: uint8 _throttleState; /** - * TODO: Documentation - */ - int8 _styleRanges[256]; - - /** * The internal display pixel buffer. During frameOut, * this buffer is drawn into according to the draw and * erase rects calculated by `calcLists`, then drawn out @@ -428,17 +278,38 @@ private: void mergeToShowList(const Common::Rect &drawRect, RectList &showList, const int overdrawThreshold); /** - * TODO: Documentation - */ - void palMorphFrameOut(const int8 *styleRanges, const ShowStyleEntry *showStyle); - - /** * Writes the internal frame buffer out to hardware and * clears the show list. */ void showBits(); + /** + * Validates whether the given palette index in the + * style range should copy a color from the next + * palette to the source palette during a palette + * morph operation. + */ + inline bool validZeroStyle(const uint8 style, const int i) const { + if (style != 0) { + return false; + } + + // TODO: Cannot check Shivers or MGDX until those executables can be + // unwrapped + switch (g_sci->getGameId()) { + case GID_KQ7: + case GID_PHANTASMAGORIA: + case GID_SQ6: + return (i > 71 && i < 104); + break; + default: + return true; + } + } + public: + bool _isHiRes; + /** * Whether palMorphFrameOut should be used instead of * frameOut for rendering. Used by kMorphOn to @@ -467,6 +338,11 @@ public: void frameOut(const bool shouldShowBits, const Common::Rect &eraseRect = Common::Rect()); /** + * TODO: Documentation + */ + void palMorphFrameOut(const int8 *styleRanges, PlaneShowStyle *showStyle); + + /** * Modifies the raw pixel data for the next frame with * new palette indexes based on matched style ranges. */ @@ -484,6 +360,12 @@ public: return 1; }; + /** + * Draws a portion of the current screen buffer to + * hardware. Used to display show styles in SCI2.1mid+. + */ + void showRect(const Common::Rect &rect); + #pragma mark - #pragma mark Mouse cursor private: diff --git a/engines/sci/graphics/paint32.cpp b/engines/sci/graphics/paint32.cpp index 74eb1629d0..338b70901e 100644 --- a/engines/sci/graphics/paint32.cpp +++ b/engines/sci/graphics/paint32.cpp @@ -37,11 +37,12 @@ reg_t GfxPaint32::kernelAddLine(const reg_t planeObject, const Common::Point &st } Common::Rect gameRect; - BitmapResource bitmap = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect); + reg_t bitmapId = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect); + SciBitmap &bitmap = *_segMan->lookupBitmap(bitmapId); CelInfo32 celInfo; celInfo.type = kCelTypeMem; - celInfo.bitmap = bitmap.getObject(); + celInfo.bitmap = bitmapId; // SSCI stores the line color on `celInfo`, even though // this is not a `kCelTypeColor`, as a hack so that // `kUpdateLine` can get the originally used color @@ -59,10 +60,10 @@ reg_t GfxPaint32::kernelAddLine(const reg_t planeObject, const Common::Point &st void GfxPaint32::kernelUpdateLine(ScreenItem *screenItem, Plane *plane, const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, const uint16 pattern, const uint8 thickness) { Common::Rect gameRect; - BitmapResource bitmap = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect); + reg_t bitmapId = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect); - _segMan->freeHunkEntry(screenItem->_celInfo.bitmap); - screenItem->_celInfo.bitmap = bitmap.getObject(); + _segMan->freeBitmap(screenItem->_celInfo.bitmap); + screenItem->_celInfo.bitmap = bitmapId; screenItem->_celInfo.color = color; screenItem->_position = startPoint; screenItem->_priority = priority; @@ -80,7 +81,7 @@ void GfxPaint32::kernelDeleteLine(const reg_t screenItemObject, const reg_t plan return; } - _segMan->freeHunkEntry(screenItem->_celInfo.bitmap); + _segMan->freeBitmap(screenItem->_celInfo.bitmap); g_sci->_gfxFrameout->deleteScreenItem(*screenItem, *plane); } @@ -116,8 +117,8 @@ void GfxPaint32::plotter(int x, int y, int color, void *data) { } } -BitmapResource GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, uint16 pattern, uint8 thickness, Common::Rect &outRect) { - const uint8 skipColor = color != 250 ? 250 : 0; +reg_t GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, uint16 pattern, uint8 thickness, Common::Rect &outRect) { + const uint8 skipColor = color != kDefaultSkipColor ? kDefaultSkipColor : 0; // Thickness is expected to be 2n+1 thickness = ((MAX((uint8)1, thickness) - 1) | 1); @@ -128,7 +129,8 @@ BitmapResource GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const outRect.right = (startPoint.x > endPoint.x ? startPoint.x : endPoint.x) + halfThickness + 1; outRect.bottom = (startPoint.y > endPoint.y ? startPoint.y : endPoint.y) + halfThickness + 1; - BitmapResource bitmap(_segMan, outRect.width(), outRect.height(), skipColor, 0, 0, g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth, g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight, 0, false); + reg_t bitmapId; + SciBitmap &bitmap = *_segMan->allocateBitmap(&bitmapId, outRect.width(), outRect.height(), skipColor, 0, 0, g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth, g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight, 0, false, true); byte *pixels = bitmap.getPixels(); memset(pixels, skipColor, bitmap.getWidth() * bitmap.getHeight()); @@ -174,7 +176,7 @@ BitmapResource GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Graphics::drawThickLine2(drawRect.left, drawRect.top, drawRect.right, drawRect.bottom, thickness, color, plotter, &properties); } - return bitmap; + return bitmapId; } diff --git a/engines/sci/graphics/paint32.h b/engines/sci/graphics/paint32.h index 6d5a957fcd..3c3b7b4343 100644 --- a/engines/sci/graphics/paint32.h +++ b/engines/sci/graphics/paint32.h @@ -24,8 +24,8 @@ #define SCI_GRAPHICS_PAINT32_H namespace Sci { -class BitmapResource; class Plane; +class SciBitmap; class ScreenItem; class SegManager; @@ -54,7 +54,7 @@ public: private: typedef struct { - BitmapResource *bitmap; + SciBitmap *bitmap; bool pattern[16]; uint8 patternIndex; bool solid; @@ -64,7 +64,7 @@ private: static void plotter(int x, int y, int color, void *data); - BitmapResource makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, const uint16 pattern, const uint8 thickness, Common::Rect &outRect); + reg_t makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, const uint16 pattern, const uint8 thickness, Common::Rect &outRect); }; } // End of namespace Sci diff --git a/engines/sci/graphics/plane32.cpp b/engines/sci/graphics/plane32.cpp index aa629e4081..1cd88d667b 100644 --- a/engines/sci/graphics/plane32.cpp +++ b/engines/sci/graphics/plane32.cpp @@ -194,11 +194,12 @@ void Plane::addPicInternal(const GuiResourceId pictureId, const Common::Point *p _type = transparent ? kPlaneTypeTransparentPicture : kPlaneTypePicture; } -void Plane::addPic(const GuiResourceId pictureId, const Common::Point &position, const bool mirrorX) { - deletePic(pictureId); +GuiResourceId Plane::addPic(const GuiResourceId pictureId, const Common::Point &position, const bool mirrorX, const bool deleteDuplicate) { + if (deleteDuplicate) { + deletePic(pictureId); + } addPicInternal(pictureId, &position, mirrorX); - // NOTE: In SCI engine this method returned the pictureId of the - // plane, but this return value was never used + return _pictureId; } void Plane::changePic() { @@ -247,6 +248,8 @@ void Plane::deleteAllPics() { #pragma mark - #pragma mark Plane - Rendering +extern int splitRects(Common::Rect r, const Common::Rect &other, Common::Rect(&outRects)[4]); + void Plane::breakDrawListByPlanes(DrawList &drawList, const PlaneList &planeList) const { const int nextPlaneIndex = planeList.findIndexByObject(_object) + 1; const PlaneList::size_type planeCount = planeList.size(); diff --git a/engines/sci/graphics/plane32.h b/engines/sci/graphics/plane32.h index 3981a2b319..964d20ca12 100644 --- a/engines/sci/graphics/plane32.h +++ b/engines/sci/graphics/plane32.h @@ -336,14 +336,6 @@ private: /** * Marks all screen items to be deleted that are within - * this plane and match the given picture ID, then sets - * the picture ID of the plane to the new picture ID - * without adding any screen items. - */ - void deletePic(const GuiResourceId oldPictureId, const GuiResourceId newPictureId); - - /** - * Marks all screen items to be deleted that are within * this plane and are picture cels. */ void deleteAllPics(); @@ -355,7 +347,7 @@ public: * new picture resource to the plane at the given * position. */ - void addPic(const GuiResourceId pictureId, const Common::Point &position, const bool mirrorX); + GuiResourceId addPic(const GuiResourceId pictureId, const Common::Point &position, const bool mirrorX, const bool deleteDuplicate = true); /** * If the plane is a picture plane, re-adds all cels @@ -364,6 +356,14 @@ public: */ void changePic(); + /** + * Marks all screen items to be deleted that are within + * this plane and match the given picture ID, then sets + * the picture ID of the plane to the new picture ID + * without adding any screen items. + */ + void deletePic(const GuiResourceId oldPictureId, const GuiResourceId newPictureId); + #pragma mark - #pragma mark Plane - Rendering private: diff --git a/engines/sci/graphics/remap32.h b/engines/sci/graphics/remap32.h index 5f629d733e..1b9628c7be 100644 --- a/engines/sci/graphics/remap32.h +++ b/engines/sci/graphics/remap32.h @@ -325,7 +325,12 @@ public: */ inline bool remapEnabled(uint8 color) const { const uint8 index = _remapEndColor - color; - assert(index < _remaps.size()); + // At least KQ7 DOS uses remap colors that are outside the valid remap + // range; in these cases, just treat those pixels as skip pixels (which + // is how they would be treated in SSCI) + if (index >= _remaps.size()) { + return false; + } return (_remaps[index]._type != kRemapNone); } diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp index 277e6e93d0..f81d50946b 100644 --- a/engines/sci/graphics/text32.cpp +++ b/engines/sci/graphics/text32.cpp @@ -59,7 +59,7 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts) : } } -reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, const bool dimmed, const bool doScaling) { +reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, const bool dimmed, const bool doScaling, const bool gc) { _borderColor = borderColor; _text = text; @@ -96,8 +96,7 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect _textRect = Common::Rect(); } - BitmapResource bitmap(_segMan, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false); - _bitmap = bitmap.getObject(); + _segMan->allocateBitmap(&_bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc); erase(bitmapRect, false); @@ -109,7 +108,7 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect return _bitmap; } -reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed) { +reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, const bool gc) { _borderColor = borderColor; _text = text; _textRect = rect; @@ -135,8 +134,7 @@ reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect & _textRect = Common::Rect(); } - BitmapResource bitmap(_segMan, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false); - _bitmap = bitmap.getObject(); + SciBitmap &bitmap = *_segMan->allocateBitmap(&_bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc); // NOTE: The engine filled the bitmap pixels with 11 here, which is silly // because then it just erased the bitmap using the skip color. So we don't @@ -180,8 +178,8 @@ void GfxText32::setFont(const GuiResourceId fontId) { void GfxText32::drawFrame(const Common::Rect &rect, const int16 size, const uint8 color, const bool doScaling) { Common::Rect targetRect = doScaling ? scaleRect(rect) : rect; - byte *bitmap = _segMan->getHunkPointer(_bitmap); - byte *pixels = bitmap + READ_SCI11ENDIAN_UINT32(bitmap + 28) + rect.top * _width + rect.left; + SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap); + byte *pixels = bitmap.getPixels() + rect.top * _width + rect.left; // NOTE: Not fully disassembled, but this should be right int16 rectWidth = targetRect.width(); @@ -210,8 +208,8 @@ void GfxText32::drawFrame(const Common::Rect &rect, const int16 size, const uint } void GfxText32::drawChar(const char charIndex) { - byte *bitmap = _segMan->getHunkPointer(_bitmap); - byte *pixels = bitmap + READ_SCI11ENDIAN_UINT32(bitmap + 28); + SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap); + byte *pixels = bitmap.getPixels(); _font->drawToBuffer(charIndex, _drawPosition.y, _drawPosition.x, _foreColor, _dimmed, pixels, _width, _height); _drawPosition.x += _font->getCharWidth(charIndex); @@ -328,14 +326,14 @@ void GfxText32::drawText(const uint index, uint length) { } } -void GfxText32::invertRect(const reg_t bitmap, int16 bitmapStride, const Common::Rect &rect, const uint8 foreColor, const uint8 backColor, const bool doScaling) { +void GfxText32::invertRect(const reg_t bitmapId, int16 bitmapStride, const Common::Rect &rect, const uint8 foreColor, const uint8 backColor, const bool doScaling) { Common::Rect targetRect = rect; if (doScaling) { bitmapStride = bitmapStride * _scaledWidth / g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; targetRect = scaleRect(rect); } - byte *bitmapData = _segMan->getHunkPointer(bitmap); + SciBitmap &bitmap = *_segMan->lookupBitmap(bitmapId); // NOTE: SCI code is super weird here; it seems to be trying to look at the // entire size of the bitmap including the header, instead of just the pixel @@ -345,14 +343,14 @@ void GfxText32::invertRect(const reg_t bitmap, int16 bitmapStride, const Common: // function was never updated to match? Or maybe they exploit the // configurable stride length somewhere else to do stair stepping inverts... uint32 invertSize = targetRect.height() * bitmapStride + targetRect.width(); - uint32 bitmapSize = READ_SCI11ENDIAN_UINT32(bitmapData + 12); + uint32 bitmapSize = bitmap.getDataSize(); if (invertSize >= bitmapSize) { error("InvertRect too big: %u >= %u", invertSize, bitmapSize); } // NOTE: Actual engine just added the bitmap header size hardcoded here - byte *pixel = bitmapData + READ_SCI11ENDIAN_UINT32(bitmapData + 28) + bitmapStride * targetRect.top + targetRect.left; + byte *pixel = bitmap.getPixels() + bitmapStride * targetRect.top + targetRect.left; int16 stride = bitmapStride - targetRect.width(); int16 targetHeight = targetRect.height(); @@ -615,7 +613,7 @@ Common::Rect GfxText32::getTextSize(const Common::String &text, int16 maxWidth, void GfxText32::erase(const Common::Rect &rect, const bool doScaling) { Common::Rect targetRect = doScaling ? scaleRect(rect) : rect; - BitmapResource bitmap(_bitmap); + SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap); bitmap.getBuffer().fillRect(targetRect, _backColor); } @@ -652,7 +650,7 @@ int16 GfxText32::getTextCount(const Common::String &text, const uint index, cons } void GfxText32::scrollLine(const Common::String &lineText, int numLines, uint8 color, TextAlign align, GuiResourceId fontId, ScrollDirection dir) { - BitmapResource bmr(_bitmap); + SciBitmap &bmr = *_segMan->lookupBitmap(_bitmap); byte *pixels = bmr.getPixels(); int h = _font->getHeight(); diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h index a61760dd87..44bd48afd5 100644 --- a/engines/sci/graphics/text32.h +++ b/engines/sci/graphics/text32.h @@ -42,206 +42,6 @@ enum ScrollDirection { kScrollDown }; -enum BitmapFlags { - kBitmapRemap = 2 -}; - -#define BITMAP_PROPERTY(size, property, offset)\ -inline uint##size get##property() const {\ - return READ_SCI11ENDIAN_UINT##size(_bitmap + (offset));\ -}\ -inline void set##property(uint##size value) {\ - WRITE_SCI11ENDIAN_UINT##size(_bitmap + (offset), (value));\ -} - -/** - * A convenience class for creating and modifying in-memory - * bitmaps. - */ -class BitmapResource { - byte *_bitmap; - reg_t _object; - Buffer _buffer; - - /** - * Gets the size of the bitmap header for the current - * engine version. - */ - static inline uint16 getBitmapHeaderSize() { - // TODO: These values are accurate for each engine, but there may be no reason - // to not simply just always use size 40, since SCI2.1mid does not seem to - // actually store any data above byte 40, and SCI2 did not allow bitmaps with - // scaling resolutions other than the default (320x200). Perhaps SCI3 used - // the extra bytes, or there is some reason why they tried to align the header - // size with other headers like pic headers? -// uint32 bitmapHeaderSize; -// if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) { -// bitmapHeaderSize = 46; -// } else if (getSciVersion() == SCI_VERSION_2_1_EARLY) { -// bitmapHeaderSize = 40; -// } else { -// bitmapHeaderSize = 36; -// } -// return bitmapHeaderSize; - return 46; - } - - /** - * Gets the byte size of a bitmap with the given width - * and height. - */ - static inline uint32 getBitmapSize(const uint16 width, const uint16 height) { - return width * height + getBitmapHeaderSize(); - } - -public: - /** - * Create a bitmap resource for an existing bitmap. - * Ownership of the bitmap is retained by the caller. - */ - inline BitmapResource(reg_t bitmap) : - _bitmap(g_sci->getEngineState()->_segMan->getHunkPointer(bitmap)), - _object(bitmap) { - if (_bitmap == nullptr || getUncompressedDataOffset() != getBitmapHeaderSize()) { - error("Invalid Text bitmap %04x:%04x", PRINT_REG(bitmap)); - } - - _buffer = Buffer(getWidth(), getHeight(), getPixels()); - } - - /** - * Allocates and initialises a new bitmap in the given - * segment manager. - */ - inline BitmapResource(SegManager *segMan, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool remap) { - _object = segMan->allocateHunkEntry("Bitmap()", getBitmapSize(width, height)); - _bitmap = segMan->getHunkPointer(_object); - - const uint16 bitmapHeaderSize = getBitmapHeaderSize(); - - setWidth(width); - setHeight(height); - setDisplace(Common::Point(displaceX, displaceY)); - setSkipColor(skipColor); - _bitmap[9] = 0; - WRITE_SCI11ENDIAN_UINT16(_bitmap + 10, 0); - setRemap(remap); - setDataSize(width * height); - WRITE_SCI11ENDIAN_UINT32(_bitmap + 16, 0); - setHunkPaletteOffset(hunkPaletteOffset); - setDataOffset(bitmapHeaderSize); - setUncompressedDataOffset(bitmapHeaderSize); - setControlOffset(0); - setScaledWidth(scaledWidth); - setScaledHeight(scaledHeight); - - _buffer = Buffer(getWidth(), getHeight(), getPixels()); - } - - inline reg_t getObject() const { - return _object; - } - - inline Buffer &getBuffer() { - return _buffer; - } - - BITMAP_PROPERTY(16, Width, 0); - BITMAP_PROPERTY(16, Height, 2); - - inline Common::Point getDisplace() const { - return Common::Point( - (int16)READ_SCI11ENDIAN_UINT16(_bitmap + 4), - (int16)READ_SCI11ENDIAN_UINT16(_bitmap + 6) - ); - } - - inline void setDisplace(const Common::Point &displace) { - WRITE_SCI11ENDIAN_UINT16(_bitmap + 4, (uint16)displace.x); - WRITE_SCI11ENDIAN_UINT16(_bitmap + 6, (uint16)displace.y); - } - - inline uint8 getSkipColor() const { - return _bitmap[8]; - } - - inline void setSkipColor(const uint8 skipColor) { - _bitmap[8] = skipColor; - } - - inline bool getRemap() const { - return READ_SCI11ENDIAN_UINT16(_bitmap + 10) & kBitmapRemap; - } - - inline void setRemap(const bool remap) { - uint16 flags = READ_SCI11ENDIAN_UINT16(_bitmap + 10); - if (remap) { - flags |= kBitmapRemap; - } else { - flags &= ~kBitmapRemap; - } - WRITE_SCI11ENDIAN_UINT16(_bitmap + 10, flags); - } - - BITMAP_PROPERTY(32, DataSize, 12); - - inline uint32 getHunkPaletteOffset() const { - return READ_SCI11ENDIAN_UINT32(_bitmap + 20); - } - - inline void setHunkPaletteOffset(uint32 hunkPaletteOffset) { - if (hunkPaletteOffset) { - hunkPaletteOffset += getBitmapHeaderSize(); - } - - WRITE_SCI11ENDIAN_UINT32(_bitmap + 20, hunkPaletteOffset); - } - - BITMAP_PROPERTY(32, DataOffset, 24); - - // NOTE: This property is used as a "magic number" for - // validating that a block of memory is a valid bitmap, - // and so is always set to the size of the header. - BITMAP_PROPERTY(32, UncompressedDataOffset, 28); - - // NOTE: This property always seems to be zero - BITMAP_PROPERTY(32, ControlOffset, 32); - - inline uint16 getScaledWidth() const { - if (getDataOffset() >= 40) { - return READ_SCI11ENDIAN_UINT16(_bitmap + 36); - } - - // SCI2 bitmaps did not have scaling ability - return 320; - } - - inline void setScaledWidth(uint16 scaledWidth) { - if (getDataOffset() >= 40) { - WRITE_SCI11ENDIAN_UINT16(_bitmap + 36, scaledWidth); - } - } - - inline uint16 getScaledHeight() const { - if (getDataOffset() >= 40) { - return READ_SCI11ENDIAN_UINT16(_bitmap + 38); - } - - // SCI2 bitmaps did not have scaling ability - return 200; - } - - inline void setScaledHeight(uint16 scaledHeight) { - if (getDataOffset() >= 40) { - WRITE_SCI11ENDIAN_UINT16(_bitmap + 38, scaledHeight); - } - } - - inline byte *getPixels() { - return _bitmap + getUncompressedDataOffset(); - } -}; - class GfxFont; /** @@ -390,12 +190,12 @@ public: * Creates a plain font bitmap with a flat color * background. */ - reg_t createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, TextAlign alignment, const int16 borderColor, bool dimmed, const bool doScaling); + reg_t createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, TextAlign alignment, const int16 borderColor, bool dimmed, const bool doScaling, const bool gc); /** * Creates a font bitmap with a view background. */ - reg_t createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed); + reg_t createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, const bool gc); inline int scaleUpWidth(int value) const { const int scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; diff --git a/engines/sci/graphics/transitions32.cpp b/engines/sci/graphics/transitions32.cpp new file mode 100644 index 0000000000..bceb0fa84d --- /dev/null +++ b/engines/sci/graphics/transitions32.cpp @@ -0,0 +1,982 @@ +/* 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 "sci/engine/segment.h" +#include "sci/engine/seg_manager.h" +#include "sci/engine/state.h" +#include "sci/graphics/frameout.h" +#include "sci/graphics/palette32.h" +#include "sci/graphics/text32.h" +#include "sci/graphics/transitions32.h" +#include "sci/sci.h" + +namespace Sci { +static int dissolveSequences[2][20] = { + /* SCI2.1early- */ { 3, 6, 12, 20, 48, 96, 184, 272, 576, 1280, 3232, 6912, 13568, 24576, 46080 }, + /* SCI2.1mid+ */ { 0, 0, 3, 6, 12, 20, 48, 96, 184, 272, 576, 1280, 3232, 6912, 13568, 24576, 46080, 73728, 132096, 466944 } +}; +static int16 divisionsDefaults[2][16] = { + /* SCI2.1early- */ { 1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 40, 40, 101, 101 }, + /* SCI2.1mid+ */ { 1, 20, 20, 20, 20, 10, 10, 10, 10, 20, 20, 6, 10, 101, 101, 2 } +}; + +GfxTransitions32::GfxTransitions32(SegManager *segMan) : + _segMan(segMan), + _throttleState(0) { + for (int i = 0; i < 236; i += 2) { + _styleRanges[i] = 0; + _styleRanges[i + 1] = -1; + } + for (int i = 236; i < ARRAYSIZE(_styleRanges); ++i) { + _styleRanges[i] = 0; + } + + if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { + _dissolveSequenceSeeds = dissolveSequences[0]; + _defaultDivisions = divisionsDefaults[0]; + } else { + _dissolveSequenceSeeds = dissolveSequences[1]; + _defaultDivisions = divisionsDefaults[1]; + } +} + +GfxTransitions32::~GfxTransitions32() { + for (ShowStyleList::iterator it = _showStyles.begin(); + it != _showStyles.end(); + it = deleteShowStyle(it)); + _scrolls.clear(); +} + +void GfxTransitions32::throttle() { + uint8 throttleTime; + if (_throttleState == 2) { + throttleTime = 34; + _throttleState = 0; + } else { + throttleTime = 33; + ++_throttleState; + } + + g_sci->getEngineState()->speedThrottler(throttleTime); + g_sci->getEngineState()->_throttleTrigger = true; +} + +#pragma mark - +#pragma mark Show styles + +void GfxTransitions32::processShowStyles() { + uint32 now = g_sci->getTickCount(); + + bool continueProcessing; + bool doFrameOut; + do { + continueProcessing = false; + doFrameOut = false; + ShowStyleList::iterator showStyle = _showStyles.begin(); + while (showStyle != _showStyles.end()) { + bool finished = false; + + if (!showStyle->animate) { + doFrameOut = true; + } + + finished = processShowStyle(*showStyle, now); + + if (!finished) { + continueProcessing = true; + } + + if (finished && showStyle->processed) { + showStyle = deleteShowStyle(showStyle); + } else { + showStyle = ++showStyle; + } + } + + if (g_engine->shouldQuit()) { + return; + } + + if (doFrameOut) { + g_sci->_gfxFrameout->frameOut(true); + throttle(); + } + } while(continueProcessing && doFrameOut); +} + +void GfxTransitions32::processEffects(PlaneShowStyle &showStyle) { + switch(showStyle.type) { + case kShowStyleHShutterOut: + processHShutterOut(showStyle); + break; + case kShowStyleHShutterIn: + processHShutterIn(showStyle); + break; + case kShowStyleVShutterOut: + processVShutterOut(showStyle); + break; + case kShowStyleVShutterIn: + processVShutterIn(showStyle); + break; + case kShowStyleWipeLeft: + processWipeLeft(showStyle); + break; + case kShowStyleWipeRight: + processWipeRight(showStyle); + break; + case kShowStyleWipeUp: + processWipeUp(showStyle); + break; + case kShowStyleWipeDown: + processWipeDown(showStyle); + break; + case kShowStyleIrisOut: + processIrisOut(showStyle); + break; + case kShowStyleIrisIn: + processIrisIn(showStyle); + break; + case kShowStyleDissolveNoMorph: + case kShowStyleDissolve: + processPixelDissolve(showStyle); + break; + case kShowStyleNone: + case kShowStyleFadeOut: + case kShowStyleFadeIn: + case kShowStyleMorph: + break; + } +} + +// TODO: 10-argument version is only in SCI3; argc checks are currently wrong for this version +// and need to be fixed in future +void GfxTransitions32::kernelSetShowStyle(const uint16 argc, const reg_t planeObj, const ShowStyleType type, const int16 seconds, const int16 back, const int16 priority, const int16 animate, const int16 frameOutNow, reg_t pFadeArray, int16 divisions, const int16 blackScreen) { + + bool hasDivisions = false; + bool hasFadeArray = false; + + // KQ7 2.0b uses a mismatched version of the Styler script (SCI2.1early script + // for SCI2.1mid engine), so the calls it makes to kSetShowStyle are wrong and + // put `divisions` where `pFadeArray` is supposed to be + if (getSciVersion() == SCI_VERSION_2_1_MIDDLE && g_sci->getGameId() == GID_KQ7) { + hasDivisions = argc > 7; + hasFadeArray = false; + divisions = argc > 7 ? pFadeArray.toSint16() : -1; + pFadeArray = NULL_REG; + } else if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { + hasDivisions = argc > 7; + hasFadeArray = false; + } else if (getSciVersion() < SCI_VERSION_3) { + hasDivisions = argc > 8; + hasFadeArray = argc > 7; + } else { + hasDivisions = argc > 9; + hasFadeArray = argc > 8; + } + + bool isFadeUp; + int16 color; + if (back != -1) { + isFadeUp = false; + color = back; + } else { + isFadeUp = true; + color = 0; + } + + if ((getSciVersion() < SCI_VERSION_2_1_MIDDLE && g_sci->getGameId() != GID_KQ7 && type == 15) || type > 15) { + error("Illegal show style %d for plane %04x:%04x", type, PRINT_REG(planeObj)); + } + + Plane *plane = g_sci->_gfxFrameout->getPlanes().findByObject(planeObj); + if (plane == nullptr) { + error("Plane %04x:%04x is not present in active planes list", PRINT_REG(planeObj)); + } + + bool createNewEntry = true; + PlaneShowStyle *entry = findShowStyleForPlane(planeObj); + if (entry != nullptr) { + bool useExisting = true; + + if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { + useExisting = plane->_gameRect.width() == entry->width && plane->_gameRect.height() == entry->height; + } + + if (useExisting) { + useExisting = entry->divisions == (hasDivisions ? divisions : _defaultDivisions[type]); + } + + if (useExisting) { + createNewEntry = false; + isFadeUp = true; + entry->currentStep = 0; + } else { + isFadeUp = true; + color = entry->color; + deleteShowStyle(findIteratorForPlane(planeObj)); + entry = nullptr; + } + } + + if (type > 0) { + if (createNewEntry) { + entry = new PlaneShowStyle; + // NOTE: SCI2.1 engine tests if allocation returned a null pointer + // but then only avoids setting currentStep if this is so. Since + // this is a nonsensical approach, we do not do that here + entry->currentStep = 0; + entry->processed = false; + entry->divisions = hasDivisions ? divisions : _defaultDivisions[type]; + entry->plane = planeObj; + entry->fadeColorRangesCount = 0; + + if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { + // for pixel dissolve + entry->bitmap = NULL_REG; + entry->bitmapScreenItem = nullptr; + + // for wipe + entry->screenItems.clear(); + entry->width = plane->_gameRect.width(); + entry->height = plane->_gameRect.height(); + } else { + entry->fadeColorRanges = nullptr; + if (hasFadeArray) { + // NOTE: SCI2.1mid engine does no check to verify that an array is + // successfully retrieved, and SegMan will cause a fatal error + // if we try to use a memory segment that is not an array + SciArray<reg_t> *table = _segMan->lookupArray(pFadeArray); + + uint32 rangeCount = table->getSize(); + entry->fadeColorRangesCount = rangeCount; + + // NOTE: SCI engine code always allocates memory even if the range + // table has no entries, but this does not really make sense, so + // we avoid the allocation call in this case + if (rangeCount > 0) { + entry->fadeColorRanges = new uint16[rangeCount]; + for (size_t i = 0; i < rangeCount; ++i) { + entry->fadeColorRanges[i] = table->getValue(i).toUint16(); + } + } + } + } + } + + // NOTE: The original engine had no nullptr check and would just crash + // if it got to here + if (entry == nullptr) { + error("Cannot edit non-existing ShowStyle entry"); + } + + entry->fadeUp = isFadeUp; + entry->color = color; + entry->nextTick = g_sci->getTickCount(); + entry->type = type; + entry->animate = animate; + entry->delay = (seconds * 60 + entry->divisions - 1) / entry->divisions; + + if (entry->delay == 0) { + error("ShowStyle has no duration"); + } + + if (frameOutNow) { + // Creates a reference frame for the pixel dissolves to use + g_sci->_gfxFrameout->frameOut(false); + } + + if (createNewEntry) { + if (getSciVersion() <= SCI_VERSION_2_1_EARLY) { + switch (entry->type) { + case kShowStyleIrisOut: + case kShowStyleIrisIn: + configure21EarlyIris(*entry, priority); + break; + case kShowStyleDissolve: + configure21EarlyDissolve(*entry, priority, plane->_gameRect); + break; + default: + // do nothing + break; + } + } + + _showStyles.push_back(*entry); + delete entry; + } + } +} + +void GfxTransitions32::kernelSetPalStyleRange(const uint8 fromColor, const uint8 toColor) { + if (toColor > fromColor) { + return; + } + + for (int i = fromColor; i <= toColor; ++i) { + _styleRanges[i] = 0; + } +} + +PlaneShowStyle *GfxTransitions32::findShowStyleForPlane(const reg_t planeObj) { + for (ShowStyleList::iterator it = _showStyles.begin(); it != _showStyles.end(); ++it) { + if (it->plane == planeObj) { + return &*it; + } + } + + return nullptr; +} + +ShowStyleList::iterator GfxTransitions32::findIteratorForPlane(const reg_t planeObj) { + ShowStyleList::iterator it; + for (it = _showStyles.begin(); it != _showStyles.end(); ++it) { + if (it->plane == planeObj) { + break; + } + } + + return it; +} + +ShowStyleList::iterator GfxTransitions32::deleteShowStyle(const ShowStyleList::iterator &showStyle) { + switch (showStyle->type) { + case kShowStyleDissolveNoMorph: + case kShowStyleDissolve: + if (getSciVersion() <= SCI_VERSION_2_1_EARLY) { + _segMan->freeBitmap(showStyle->bitmap); + g_sci->_gfxFrameout->deleteScreenItem(*showStyle->bitmapScreenItem); + } + break; + case kShowStyleIrisOut: + case kShowStyleIrisIn: + if (getSciVersion() <= SCI_VERSION_2_1_EARLY) { + for (uint i = 0; i < showStyle->screenItems.size(); ++i) { + ScreenItem *screenItem = showStyle->screenItems[i]; + if (screenItem != nullptr) { + g_sci->_gfxFrameout->deleteScreenItem(*screenItem); + } + } + } + break; + case kShowStyleFadeIn: + case kShowStyleFadeOut: + if (getSciVersion() > SCI_VERSION_2_1_EARLY && showStyle->fadeColorRangesCount > 0) { + delete[] showStyle->fadeColorRanges; + } + break; + case kShowStyleNone: + case kShowStyleMorph: + // do nothing + break; + default: + error("Unknown delete transition type %d", showStyle->type); + } + + return _showStyles.erase(showStyle); +} + +void GfxTransitions32::configure21EarlyIris(PlaneShowStyle &showStyle, const int16 priority) { + showStyle.numEdges = 4; + const int numScreenItems = showStyle.numEdges * showStyle.divisions; + showStyle.screenItems.reserve(numScreenItems); + + CelInfo32 celInfo; + celInfo.type = kCelTypeColor; + celInfo.color = showStyle.color; + + const int width = showStyle.width; + const int height = showStyle.height; + const int divisions = showStyle.divisions; + + for (int i = 0; i < divisions; ++i) { + Common::Rect rect; + + // Top + rect.left = (width * i) / (2 * divisions); + rect.top = (height * i) / (2 * divisions); + rect.right = width - rect.left; + rect.bottom = (height + 1) * (i + 1) / (2 * divisions); + const int16 topTop = rect.top; + const int16 topBottom = rect.bottom; + + showStyle.screenItems.push_back(new ScreenItem(showStyle.plane, celInfo, rect)); + showStyle.screenItems.back()->_priority = priority; + showStyle.screenItems.back()->_fixedPriority = true; + + // Bottom + rect.top = height - rect.bottom; + rect.bottom = height - topTop; + const int16 bottomTop = rect.top; + + showStyle.screenItems.push_back(new ScreenItem(showStyle.plane, celInfo, rect)); + showStyle.screenItems.back()->_priority = priority; + showStyle.screenItems.back()->_fixedPriority = true; + + // Left + rect.top = topBottom; + rect.right = (width + 1) * (i + 1) / (2 * divisions); + rect.bottom = bottomTop; + const int16 leftLeft = rect.left; + + showStyle.screenItems.push_back(new ScreenItem(showStyle.plane, celInfo, rect)); + showStyle.screenItems.back()->_priority = priority; + showStyle.screenItems.back()->_fixedPriority = true; + + // Right + rect.left = width - rect.right; + rect.right = width - leftLeft; + + showStyle.screenItems.push_back(new ScreenItem(showStyle.plane, celInfo, rect)); + showStyle.screenItems.back()->_priority = priority; + showStyle.screenItems.back()->_fixedPriority = true; + } + + if (showStyle.fadeUp) { + for (int i = 0; i < numScreenItems; ++i) { + g_sci->_gfxFrameout->addScreenItem(*showStyle.screenItems[i]); + } + } +} + +void GfxTransitions32::configure21EarlyDissolve(PlaneShowStyle &showStyle, const int16 priority, const Common::Rect &gameRect) { + + reg_t bitmapId; + SciBitmap &bitmap = *_segMan->allocateBitmap(&bitmapId, showStyle.width, showStyle.height, kDefaultSkipColor, 0, 0, kLowResX, kLowResY, 0, false, false); + + showStyle.bitmap = bitmapId; + + const Buffer &source = g_sci->_gfxFrameout->getCurrentBuffer(); + Buffer target(showStyle.width, showStyle.height, bitmap.getPixels()); + + target.fillRect(Common::Rect(bitmap.getWidth(), bitmap.getHeight()), kDefaultSkipColor); + target.copyRectToSurface(source, 0, 0, gameRect); + + CelInfo32 celInfo; + celInfo.type = kCelTypeMem; + celInfo.bitmap = bitmapId; + + showStyle.bitmapScreenItem = new ScreenItem(showStyle.plane, celInfo, Common::Point(0, 0), ScaleInfo()); + showStyle.bitmapScreenItem->_priority = priority; + showStyle.bitmapScreenItem->_fixedPriority = true; + + g_sci->_gfxFrameout->addScreenItem(*showStyle.bitmapScreenItem); +} + +bool GfxTransitions32::processShowStyle(PlaneShowStyle &showStyle, uint32 now) { + if (showStyle.nextTick >= now && showStyle.animate) { + return false; + } + + switch (showStyle.type) { + default: + case kShowStyleNone: + return processNone(showStyle); + case kShowStyleHShutterOut: + case kShowStyleHShutterIn: + case kShowStyleVShutterOut: + case kShowStyleVShutterIn: + case kShowStyleWipeLeft: + case kShowStyleWipeRight: + case kShowStyleWipeUp: + case kShowStyleWipeDown: + case kShowStyleDissolveNoMorph: + case kShowStyleMorph: + return processMorph(showStyle); + case kShowStyleDissolve: + if (getSciVersion() > SCI_VERSION_2_1_EARLY) { + return processMorph(showStyle); + } else { + return processPixelDissolve(showStyle); + } + case kShowStyleIrisOut: + if (getSciVersion() > SCI_VERSION_2_1_EARLY) { + return processMorph(showStyle); + } else { + return processIrisOut(showStyle); + } + case kShowStyleIrisIn: + if (getSciVersion() > SCI_VERSION_2_1_EARLY) { + return processMorph(showStyle); + } else { + return processIrisIn(showStyle); + } + case kShowStyleFadeOut: + return processFade(-1, showStyle); + case kShowStyleFadeIn: + return processFade(1, showStyle); + } +} + +bool GfxTransitions32::processNone(PlaneShowStyle &showStyle) { + if (showStyle.fadeUp) { + g_sci->_gfxPalette32->setFade(100, 0, 255); + } else { + g_sci->_gfxPalette32->setFade(0, 0, 255); + } + + showStyle.processed = true; + return true; +} + +void GfxTransitions32::processHShutterOut(PlaneShowStyle &showStyle) { + error("HShutterOut is not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); +} + +void GfxTransitions32::processHShutterIn(PlaneShowStyle &showStyle) { + error("HShutterIn is not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); +} + +void GfxTransitions32::processVShutterOut(PlaneShowStyle &showStyle) { + error("VShutterOut is not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); +} + +void GfxTransitions32::processVShutterIn(PlaneShowStyle &showStyle) { + error("VShutterIn is not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); +} + +void GfxTransitions32::processWipeLeft(PlaneShowStyle &showStyle) { + error("WipeLeft is not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); +} + +void GfxTransitions32::processWipeRight(PlaneShowStyle &showStyle) { + error("WipeRight is not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); +} + +void GfxTransitions32::processWipeUp(PlaneShowStyle &showStyle) { + error("WipeUp is not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); +} + +void GfxTransitions32::processWipeDown(PlaneShowStyle &showStyle) { + error("WipeDown is not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); +} + +bool GfxTransitions32::processIrisOut(PlaneShowStyle &showStyle) { + if (getSciVersion() > SCI_VERSION_2_1_EARLY) { + error("IrisOut is not known to be used by any SCI2.1mid+ game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); + } + + return processWipe(-1, showStyle); +} + +bool GfxTransitions32::processIrisIn(PlaneShowStyle &showStyle) { + if (getSciVersion() > SCI_VERSION_2_1_EARLY) { + error("IrisIn is not known to be used by any SCI2.1mid+ game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); + } + + return processWipe(1, showStyle); +} + +void GfxTransitions32::processDissolveNoMorph(PlaneShowStyle &showStyle) { + error("DissolveNoMorph is not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); +} + +inline int bitWidth(int number) { + int width = 0; + while (number != 0) { + number >>= 1; + width += 1; + } + return width; +} + +bool GfxTransitions32::processPixelDissolve(PlaneShowStyle &showStyle) { + if (getSciVersion() > SCI_VERSION_2_1_EARLY) { + return processPixelDissolve21Mid(showStyle); + } else { + return processPixelDissolve21Early(showStyle); + } +} + +bool GfxTransitions32::processPixelDissolve21Early(PlaneShowStyle &showStyle) { + bool unchanged = true; + + SciBitmap &bitmap = *_segMan->lookupBitmap(showStyle.bitmap); + Buffer buffer(showStyle.width, showStyle.height, bitmap.getPixels()); + + uint32 numPixels = showStyle.width * showStyle.height; + uint32 numPixelsPerDivision = (numPixels + showStyle.divisions) / showStyle.divisions; + + uint32 index; + if (showStyle.currentStep == 0) { + int i = 0; + index = numPixels; + if (index != 1) { + for (;;) { + index >>= 1; + if (index == 1) { + break; + } + i++; + } + } + + showStyle.dissolveMask = _dissolveSequenceSeeds[i]; + index = 53427; + + showStyle.firstPixel = index; + showStyle.pixel = index; + } else { + index = showStyle.pixel; + for (;;) { + if (index & 1) { + index >>= 1; + index ^= showStyle.dissolveMask; + } else { + index >>= 1; + } + + if (index < numPixels) { + break; + } + } + + if (index == showStyle.firstPixel) { + index = 0; + } + } + + if (showStyle.currentStep < showStyle.divisions) { + for (uint32 i = 0; i < numPixelsPerDivision; ++i) { + *(byte *)buffer.getBasePtr(index % showStyle.width, index / showStyle.width) = showStyle.color; + + for (;;) { + if (index & 1) { + index >>= 1; + index ^= showStyle.dissolveMask; + } else { + index >>= 1; + } + + if (index < numPixels) { + break; + } + } + + if (index == showStyle.firstPixel) { + buffer.fillRect(Common::Rect(0, 0, showStyle.width, showStyle.height), showStyle.color); + break; + } + } + + showStyle.pixel = index; + showStyle.nextTick += showStyle.delay; + ++showStyle.currentStep; + unchanged = false; + if (showStyle.bitmapScreenItem->_created == 0) { + showStyle.bitmapScreenItem->_updated = g_sci->_gfxFrameout->getScreenCount(); + } + } + + if ((showStyle.currentStep >= showStyle.divisions) && unchanged) { + if (showStyle.fadeUp) { + showStyle.processed = true; + } + + return true; + } + + return false; +} + +bool GfxTransitions32::processPixelDissolve21Mid(PlaneShowStyle &showStyle) { + // SQ6 room 530 + + Plane* plane = g_sci->_gfxFrameout->getVisiblePlanes().findByObject(showStyle.plane); + const Common::Rect &screenRect = plane->_screenRect; + Common::Rect rect; + + const int planeWidth = screenRect.width(); + const int planeHeight = screenRect.height(); + const int divisions = showStyle.divisions; + const int width = planeWidth / divisions + ((planeWidth % divisions) ? 1 : 0); + const int height = planeHeight / divisions + ((planeHeight % divisions) ? 1 : 0); + + const uint32 mask = _dissolveSequenceSeeds[bitWidth(width * height - 1)]; + int seq = 1; + + uint iteration = 0; + const uint numIterationsPerTick = (width * height + divisions) / divisions; + + do { + int row = seq / width; + int col = seq % width; + + if (row < height) { + if (row == height && (planeHeight % divisions)) { + if (col == width && (planeWidth % divisions)) { + rect.left = col * divisions; + rect.top = row * divisions; + rect.right = col * divisions + (planeWidth % divisions); + rect.bottom = row * divisions + (planeHeight % divisions); + rect.clip(screenRect); + g_sci->_gfxFrameout->showRect(rect); + } else { + rect.left = col * divisions; + rect.top = row * divisions; + rect.right = col * divisions * 2; + rect.bottom = row * divisions + (planeHeight % divisions); + rect.clip(screenRect); + g_sci->_gfxFrameout->showRect(rect); + } + } else { + if (col == width && (planeWidth % divisions)) { + rect.left = col * divisions; + rect.top = row * divisions; + rect.right = col * divisions + (planeWidth % divisions) + 1; + rect.bottom = row * divisions * 2 + 1; + rect.clip(screenRect); + g_sci->_gfxFrameout->showRect(rect); + } else { + rect.left = col * divisions; + rect.top = row * divisions; + rect.right = col * divisions * 2 + 1; + rect.bottom = row * divisions * 2 + 1; + rect.clip(screenRect); + g_sci->_gfxFrameout->showRect(rect); + } + } + } + + if (seq & 1) { + seq = (seq >> 1) ^ mask; + } else { + seq >>= 1; + } + + if (++iteration == numIterationsPerTick) { + throttle(); + iteration = 0; + } + } while(seq != 1 && !g_engine->shouldQuit()); + + rect.left = screenRect.left; + rect.top = screenRect.top; + rect.right = divisions + screenRect.left; + rect.bottom = divisions + screenRect.bottom; + rect.clip(screenRect); + g_sci->_gfxFrameout->showRect(rect); + throttle(); + + g_sci->_gfxFrameout->showRect(screenRect); + return true; +} + +bool GfxTransitions32::processFade(const int8 direction, PlaneShowStyle &showStyle) { + bool unchanged = true; + if (showStyle.currentStep < showStyle.divisions) { + int percent; + if (direction <= 0) { + percent = showStyle.divisions - showStyle.currentStep - 1; + } else { + percent = showStyle.currentStep; + } + + percent *= 100; + percent /= showStyle.divisions - 1; + + if (showStyle.fadeColorRangesCount > 0) { + for (int i = 0, len = showStyle.fadeColorRangesCount; i < len; i += 2) { + g_sci->_gfxPalette32->setFade(percent, showStyle.fadeColorRanges[i], showStyle.fadeColorRanges[i + 1]); + } + } else { + g_sci->_gfxPalette32->setFade(percent, 0, 255); + } + + ++showStyle.currentStep; + showStyle.nextTick += showStyle.delay; + unchanged = false; + } + + if (showStyle.currentStep >= showStyle.divisions && unchanged) { + if (direction > 0) { + showStyle.processed = true; + } + + return true; + } + + return false; +} + +bool GfxTransitions32::processMorph(PlaneShowStyle &showStyle) { + g_sci->_gfxFrameout->palMorphFrameOut(_styleRanges, &showStyle); + showStyle.processed = true; + return true; +} + +bool GfxTransitions32::processWipe(const int8 direction, PlaneShowStyle &showStyle) { + bool unchanged = true; + if (showStyle.currentStep < showStyle.divisions) { + int index; + if (direction > 0) { + index = showStyle.currentStep; + } else { + index = showStyle.divisions - showStyle.currentStep - 1; + } + + index *= showStyle.numEdges; + for (int i = 0; i < showStyle.numEdges; ++i) { + ScreenItem *screenItem = showStyle.screenItems[index + i]; + if (showStyle.fadeUp) { + g_sci->_gfxFrameout->deleteScreenItem(*screenItem); + showStyle.screenItems[index + i] = nullptr; + } else { + g_sci->_gfxFrameout->addScreenItem(*screenItem); + } + } + + ++showStyle.currentStep; + showStyle.nextTick += showStyle.delay; + unchanged = false; + } + + if (showStyle.currentStep >= showStyle.divisions && unchanged) { + if (showStyle.fadeUp) { + showStyle.processed = true; + } + + return true; + } + + return false; +} + +#pragma mark - +#pragma mark Scrolls + +void GfxTransitions32::processScrolls() { + for (ScrollList::iterator it = _scrolls.begin(); it != _scrolls.end(); ) { + bool finished = processScroll(*it); + if (finished) { + it = _scrolls.erase(it); + } else { + ++it; + } + } + + throttle(); +} + +void GfxTransitions32::kernelSetScroll(const reg_t planeId, const int16 deltaX, const int16 deltaY, const GuiResourceId pictureId, const bool animate, const bool mirrorX) { + + for (ScrollList::const_iterator it = _scrolls.begin(); it != _scrolls.end(); ++it) { + if (it->plane == planeId) { + error("Scroll already exists on plane %04x:%04x", PRINT_REG(planeId)); + } + } + + if (!deltaX && !deltaY) { + error("kSetScroll: Scroll has no movement"); + } + + if (deltaX && deltaY) { + error("kSetScroll: Cannot scroll in two dimensions"); + } + + PlaneScroll *scroll = new PlaneScroll; + scroll->plane = planeId; + scroll->x = 0; + scroll->y = 0; + scroll->deltaX = deltaX; + scroll->deltaY = deltaY; + scroll->newPictureId = pictureId; + scroll->animate = animate; + scroll->startTick = g_sci->getTickCount(); + + Plane *plane = g_sci->_gfxFrameout->getPlanes().findByObject(planeId); + if (plane == nullptr) { + error("kSetScroll: Plane %04x:%04x not found", PRINT_REG(planeId)); + } + + Plane *visiblePlane = g_sci->_gfxFrameout->getPlanes().findByObject(planeId); + if (visiblePlane == nullptr) { + error("kSetScroll: Visible plane %04x:%04x not found", PRINT_REG(planeId)); + } + + const Common::Rect &gameRect = visiblePlane->_gameRect; + Common::Point picOrigin; + + if (deltaX) { + picOrigin.y = 0; + + if (deltaX > 0) { + scroll->x = picOrigin.x = -gameRect.width(); + } else { + scroll->x = picOrigin.x = gameRect.width(); + } + } else { + picOrigin.x = 0; + + if (deltaY > 0) { + scroll->y = picOrigin.y = -gameRect.height(); + } else { + scroll->y = picOrigin.y = gameRect.height(); + } + } + + scroll->oldPictureId = plane->addPic(pictureId, picOrigin, mirrorX); + + if (animate) { + _scrolls.push_front(*scroll); + } else { + bool finished = false; + while (!finished && !g_engine->shouldQuit()) { + finished = processScroll(*scroll); + g_sci->_gfxFrameout->frameOut(true); + throttle(); + } + delete scroll; + } +} + +bool GfxTransitions32::processScroll(PlaneScroll &scroll) { + bool finished = false; + uint32 now = g_sci->getTickCount(); + if (scroll.startTick >= now) { + return false; + } + + int deltaX = scroll.deltaX; + int deltaY = scroll.deltaY; + if (((scroll.x + deltaX) * scroll.y) <= 0) { + deltaX = -scroll.x; + } + if (((scroll.y + deltaY) * scroll.y) <= 0) { + deltaY = -scroll.y; + } + + scroll.x += deltaX; + scroll.y += deltaY; + + Plane *plane = g_sci->_gfxFrameout->getPlanes().findByObject(scroll.plane); + + if ((scroll.x == 0) && (scroll.y == 0)) { + plane->deletePic(scroll.oldPictureId, scroll.newPictureId); + finished = true; + } + + plane->scrollScreenItems(deltaX, deltaY, true); + + return finished; +} + +} // End of namespace Sci diff --git a/engines/sci/graphics/transitions32.h b/engines/sci/graphics/transitions32.h new file mode 100644 index 0000000000..3968378a3c --- /dev/null +++ b/engines/sci/graphics/transitions32.h @@ -0,0 +1,476 @@ +/* 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 SCI_GRAPHICS_TRANSITIONS32_H +#define SCI_GRAPHICS_TRANSITIONS32_H + +#include "common/list.h" +#include "common/scummsys.h" +#include "sci/engine/vm_types.h" + +namespace Sci { +enum ShowStyleType /* : uint8 */ { + kShowStyleNone = 0, + kShowStyleHShutterOut = 1, + kShowStyleHShutterIn = 2, + kShowStyleVShutterOut = 3, + kShowStyleVShutterIn = 4, + kShowStyleWipeLeft = 5, + kShowStyleWipeRight = 6, + kShowStyleWipeUp = 7, + kShowStyleWipeDown = 8, + kShowStyleIrisOut = 9, + kShowStyleIrisIn = 10, + kShowStyleDissolveNoMorph = 11, + kShowStyleDissolve = 12, + kShowStyleFadeOut = 13, + kShowStyleFadeIn = 14, + kShowStyleMorph = 15 +}; + +/** + * Show styles represent transitions applied to draw planes. + * One show style per plane can be active at a time. + */ +struct PlaneShowStyle { + /** + * The ID of the plane this show style belongs to. + * In SCI2.1mid (at least SQ6), per-plane transitions + * were removed and a single plane ID is used. + */ + reg_t plane; + + /** + * The type of the transition. + */ + ShowStyleType type; + + /** + * When true, the show style is an entry transition + * to a new room. When false, it is an exit + * transition away from an old room. + */ + bool fadeUp; + + /** + * The number of steps for the show style. + */ + int16 divisions; + + /** + * The color used by transitions that draw CelObjColor + * screen items. -1 for transitions that do not draw + * screen items. + */ + int16 color; + + // TODO: Probably uint32 + // TODO: This field probably should be used in order to + // provide time-accurate processing of show styles. In the + // actual SCI engine (at least 2â2.1mid) it appears that + // style transitions are drawn âas fast as possibleâ, one + // step per loop, even though this delay field exists + int delay; + + // TODO: Probably bool, but never seems to be true? + bool animate; + + /** + * The wall time at which the next step of the animation + * should execute. + */ + uint32 nextTick; + + /** + * During playback of the show style, the current step + * (out of divisions). + */ + int currentStep; + + /** + * Whether or not this style has finished running and + * is ready for disposal. + */ + bool processed; + + // + // Engine specific properties for SCI2.1early + // + + /** + * A list of screen items, each representing one + * block of a wipe transition. + */ + Common::Array<ScreenItem *> screenItems; + + /** + * For wipe transitions, the number of edges with a + * moving wipe (1, 2, or 4). + */ + uint8 numEdges; + + /** + * The dimensions of the plane, in game script + * coordinates. + */ + int16 width, height; + + /** + * For pixel dissolve transitions, the screen item + * used to render the transition. + */ + ScreenItem *bitmapScreenItem; + + /** + * For pixel dissolve transitions, the bitmap used + * to render the transition. + */ + reg_t bitmap; + + /** + * The bit mask used by pixel dissolve transitions. + */ + uint32 dissolveMask; + + /** + * The first pixel that was dissolved in a pixel + * dissolve transition. + */ + uint32 firstPixel; + + /** + * The last pixel that was dissolved. Once all + * pixels have been dissolved, `pixel` will once + * again equal `firstPixel`. + */ + uint32 pixel; + + // + // Engine specific properties for SCI2.1mid through SCI3 + // + + /** + * The number of entries in the fadeColorRanges array. + */ + uint8 fadeColorRangesCount; + + /** + * A pointer to an dynamically sized array of palette + * indexes, in the order [ fromColor, toColor, ... ]. + * Only colors within this range are transitioned. + */ + uint16 *fadeColorRanges; +}; + +/** + * PlaneScroll describes a transition between two different + * pictures within a single plane. + */ +struct PlaneScroll { + /** + * The ID of the plane to be scrolled. + */ + reg_t plane; + + /** + * The current position of the scroll. + */ + int16 x, y; + + /** + * The distance that should be scrolled. Only one of + * `deltaX` or `deltaY` may be set. + */ + int16 deltaX, deltaY; + + /** + * The pic that should be created and scrolled into + * view inside the plane. + */ + GuiResourceId newPictureId; + + /** + * The picture that should be scrolled out of view + * and deleted from the plane. + */ + GuiResourceId oldPictureId; + + /** + * If true, the scroll animation is interleaved + * with other updates to the graphics. If false, + * the scroll will be exclusively animated until + * it is finished. + */ + bool animate; + + /** + * The tick after which the animation will start. + */ + uint32 startTick; +}; + +typedef Common::List<PlaneShowStyle> ShowStyleList; +typedef Common::List<PlaneScroll> ScrollList; + +class GfxTransitions32 { +public: + GfxTransitions32(SegManager *_segMan); + ~GfxTransitions32(); +private: + SegManager *_segMan; + + /** + * Throttles transition playback to prevent + * transitions from being instant on fast + * computers. + */ + void throttle(); + int8 _throttleState; + +#pragma mark - +#pragma mark Show styles +public: + inline bool hasShowStyles() const { return !_showStyles.empty(); } + + /** + * Processes all active show styles in a loop + * until they are finished. + */ + void processShowStyles(); + + /** + * Processes show styles that are applied + * through `GfxFrameout::palMorphFrameOut`. + */ + void processEffects(PlaneShowStyle &showStyle); + + // NOTE: This signature is taken from SCI3 Phantasmagoria 2 + // and is valid for all implementations of SCI32 + void kernelSetShowStyle(const uint16 argc, const reg_t planeObj, const ShowStyleType type, const int16 seconds, const int16 direction, const int16 priority, const int16 animate, const int16 frameOutNow, reg_t pFadeArray, int16 divisions, const int16 blackScreen); + + /** + * Sets the range that will be used by + * `GfxFrameout::palMorphFrameOut` to alter + * palette entries. + */ + void kernelSetPalStyleRange(const uint8 fromColor, const uint8 toColor); + + /** + * A map of palette entries that can be morphed + * by the Morph show style. + */ + int8 _styleRanges[256]; + +private: + /** + * Default sequence values for pixel dissolve + * transition bit masks. + */ + int *_dissolveSequenceSeeds; + + /** + * Default values for `PlaneShowStyle::divisions` + * for the current SCI version. + */ + int16 *_defaultDivisions; + + /** + * The list of PlaneShowStyles that are + * currently active. + */ + ShowStyleList _showStyles; + + /** + * Finds a show style that applies to the given + * plane. + */ + PlaneShowStyle *findShowStyleForPlane(const reg_t planeObj); + + /** + * Finds the iterator for a show style that + * applies to the given plane. + */ + ShowStyleList::iterator findIteratorForPlane(const reg_t planeObj); + + /** + * Deletes the given PlaneShowStyle and returns + * the next PlaneShowStyle from the list of + * styles. + */ + ShowStyleList::iterator deleteShowStyle(const ShowStyleList::iterator &showStyle); + + /** + * Initializes the given PlaneShowStyle for an + * iris effect for SCI2 to 2.1early. + */ + void configure21EarlyIris(PlaneShowStyle &showStyle, const int16 priority); + + /** + * Initializes the given PlaneShowStyle for a + * pixel dissolve effect for SCI2 to 2.1early. + */ + void configure21EarlyDissolve(PlaneShowStyle &showStyle, const int16 priority, const Common::Rect &gameRect); + + /** + * Processes one tick of the given + * PlaneShowStyle. + */ + bool processShowStyle(PlaneShowStyle &showStyle, uint32 now); + + /** + * Performs an instant transition between two + * rooms. + */ + bool processNone(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders into a room + * with a horizontal shutter effect. + */ + void processHShutterOut(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders to black + * with a horizontal shutter effect. + */ + void processHShutterIn(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders into a room + * with a vertical shutter effect. + */ + void processVShutterOut(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders to black + * with a vertical shutter effect. + */ + void processVShutterIn(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders into a room + * with a wipe to the left. + */ + void processWipeLeft(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders to black + * with a wipe to the right. + */ + void processWipeRight(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders into a room + * with a wipe upwards. + */ + void processWipeUp(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders to black + * with a wipe downwards. + */ + void processWipeDown(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders into a room + * with an iris effect. + */ + bool processIrisOut(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders to black + * with an iris effect. + */ + bool processIrisIn(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders between + * rooms using a block dissolve effect. + */ + void processDissolveNoMorph(PlaneShowStyle &showStyle); + + /** + * Performs a transition that renders between + * rooms with a pixel dissolve effect. + */ + bool processPixelDissolve(PlaneShowStyle &showStyle); + + /** + * SCI2 to 2.1early implementation of pixel + * dissolve. + */ + bool processPixelDissolve21Early(PlaneShowStyle &showStyle); + + /** + * SCI2.1mid and later implementation of + * pixel dissolve. + */ + bool processPixelDissolve21Mid(PlaneShowStyle &showStyle); + + /** + * Performs a transition that fades to black + * between rooms. + */ + bool processFade(const int8 direction, PlaneShowStyle &showStyle); + + /** + * Morph transition calls back into the + * transition system's `processEffects` + * method, which then applies transitions + * other than None, Fade, or Morph. + */ + bool processMorph(PlaneShowStyle &showStyle); + + /** + * Performs a generic transition for any of + * the wipe/shutter/iris effects. + */ + bool processWipe(const int8 direction, PlaneShowStyle &showStyle); + +#pragma mark - +#pragma mark Scrolls +public: + inline bool hasScrolls() const { return !_scrolls.empty(); } + + /** + * Processes all active plane scrolls + * in a loop until they are finished. + */ + void processScrolls(); + + void kernelSetScroll(const reg_t plane, const int16 deltaX, const int16 deltaY, const GuiResourceId pictureId, const bool animate, const bool mirrorX); + +private: + /** + * A list of active plane scrolls. + */ + ScrollList _scrolls; + + /** + * Performs a scroll of the content of + * a plane. + */ + bool processScroll(PlaneScroll &scroll); +}; + +} // End of namespace Sci +#endif diff --git a/engines/sci/graphics/video32.cpp b/engines/sci/graphics/video32.cpp index dfddac1036..757d793c44 100644 --- a/engines/sci/graphics/video32.cpp +++ b/engines/sci/graphics/video32.cpp @@ -20,20 +20,477 @@ * */ -#include "audio/mixer.h" -#include "common/config-manager.h" -#include "sci/console.h" -#include "sci/event.h" -#include "sci/graphics/cursor.h" -#include "sci/graphics/frameout.h" -#include "sci/graphics/palette32.h" -#include "sci/graphics/text32.h" +#include "common/config-manager.h" // for ConfMan +#include "common/textconsole.h" // for warning, error +#include "common/util.h" // for ARRAYSIZE +#include "common/system.h" // for g_system +#include "engine.h" // for Engine, g_engine +#include "engines/util.h" // for initGraphics +#include "sci/console.h" // for Console +#include "sci/engine/state.h" // for EngineState +#include "sci/engine/vm_types.h" // for reg_t +#include "sci/event.h" // for SciEvent, EventManager, SCI_... +#include "sci/graphics/celobj32.h" // for CelInfo32, ::kLowResX, ::kLo... +#include "sci/graphics/cursor.h" // for GfxCursor +#include "sci/graphics/frameout.h" // for GfxFrameout +#include "sci/graphics/helpers.h" // for Color, Palette +#include "sci/graphics/palette32.h" // for GfxPalette32 +#include "sci/graphics/plane32.h" // for Plane, PlanePictureCodes::kP... +#include "sci/graphics/screen_item32.h" // for ScaleInfo, ScreenItem, Scale... +#include "sci/sci.h" // for SciEngine, g_sci, getSciVersion #include "sci/graphics/video32.h" -#include "sci/sci.h" -#include "video/coktel_decoder.h" +#include "sci/video/seq_decoder.h" // for SEQDecoder +#include "video/avi_decoder.h" // for AVIDecoder +#include "video/coktel_decoder.h" // for AdvancedVMDDecoder +namespace Graphics { struct Surface; } namespace Sci { +#pragma mark SEQPlayer + +SEQPlayer::SEQPlayer(SegManager *segMan) : + _segMan(segMan), + _decoder(nullptr), + _plane(nullptr), + _screenItem(nullptr) {} + +void SEQPlayer::play(const Common::String &fileName, const int16 numTicks, const int16 x, const int16 y) { + delete _decoder; + _decoder = new SEQDecoder(numTicks); + _decoder->loadFile(fileName); + + // NOTE: In the original engine, video was output directly to the hardware, + // bypassing the game's rendering engine. Instead of doing this, we use a + // mechanism that is very similar to that used by the VMD player, which + // allows the SEQ to be drawn into a bitmap ScreenItem and displayed using + // the normal graphics system. + _segMan->allocateBitmap(&_bitmap, _decoder->getWidth(), _decoder->getHeight(), kDefaultSkipColor, 0, 0, kLowResX, kLowResY, 0, false, false); + + CelInfo32 celInfo; + celInfo.type = kCelTypeMem; + celInfo.bitmap = _bitmap; + + _plane = new Plane(Common::Rect(kLowResX, kLowResY), kPlanePicColored); + g_sci->_gfxFrameout->addPlane(*_plane); + + // Normally we would use the x, y coordinates passed into the play function + // to position the screen item, but because the video frame bitmap is + // drawn in low-resolution coordinates, it gets automatically scaled up by + // the engine (pixel doubling with aspect ratio correction). As a result, + // the animation does not need the extra offsets from the game in order to + // be correctly positioned in the middle of the window, so we ignore them. + _screenItem = new ScreenItem(_plane->_object, celInfo, Common::Point(0, 0), ScaleInfo()); + g_sci->_gfxFrameout->addScreenItem(*_screenItem); + g_sci->_gfxFrameout->frameOut(true); + _decoder->start(); + + while (!g_engine->shouldQuit() && !_decoder->endOfVideo()) { + renderFrame(); + g_sci->getEngineState()->speedThrottler(_decoder->getTimeToNextFrame()); + g_sci->getEngineState()->_throttleTrigger = true; + } + + _segMan->freeBitmap(_screenItem->_celInfo.bitmap); + g_sci->_gfxFrameout->deletePlane(*_plane); + g_sci->_gfxFrameout->frameOut(true); + _screenItem = nullptr; + _plane = nullptr; +} + +void SEQPlayer::renderFrame() const { + const Graphics::Surface *surface = _decoder->decodeNextFrame(); + + SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap); + bitmap.getBuffer().copyRectToSurface(*surface, 0, 0, Common::Rect(surface->w, surface->h)); + + const bool dirtyPalette = _decoder->hasDirtyPalette(); + if (dirtyPalette) { + Palette palette; + const byte *rawPalette = _decoder->getPalette(); + for (int i = 0; i < ARRAYSIZE(palette.colors); ++i) { + palette.colors[i].r = *rawPalette++; + palette.colors[i].g = *rawPalette++; + palette.colors[i].b = *rawPalette++; + palette.colors[i].used = true; + } + + g_sci->_gfxPalette32->submit(palette); + } + + g_sci->_gfxFrameout->updateScreenItem(*_screenItem); + g_sci->getSciDebugger()->onFrame(); + g_sci->_gfxFrameout->frameOut(true); +} + +#pragma mark - +#pragma mark AVIPlayer + +AVIPlayer::AVIPlayer(SegManager *segMan, EventManager *eventMan) : + _segMan(segMan), + _eventMan(eventMan), + _decoder(new Video::AVIDecoder(Audio::Mixer::kSFXSoundType)), + _scaleBuffer(nullptr), + _plane(nullptr), + _screenItem(nullptr), + _status(kAVINotOpen) {} + +AVIPlayer::~AVIPlayer() { + close(); + delete _decoder; +} + +AVIPlayer::IOStatus AVIPlayer::open(const Common::String &fileName) { + if (_status != kAVINotOpen) { + close(); + } + + if (!_decoder->loadFile(fileName)) { + return kIOFileNotFound; + } + + _status = kAVIOpen; + return kIOSuccess; +} + +AVIPlayer::IOStatus AVIPlayer::init1x(const int16 x, const int16 y, int16 width, int16 height) { + if (_status == kAVINotOpen) { + return kIOFileNotFound; + } + + _pixelDouble = false; + + if (!width || !height) { + width = _decoder->getWidth(); + height = _decoder->getHeight(); + } else if (getSciVersion() == SCI_VERSION_2_1_EARLY && g_sci->getGameId() == GID_KQ7) { + // KQ7 1.51 provides an explicit width and height when it wants scaling, + // though the width and height it provides are not scaled + _pixelDouble = true; + width *= 2; + height *= 2; + } + + // QFG4CD gives non-multiple-of-2 values for width and height, + // which would normally be OK except the source video is a pixel bigger + // in each dimension + width = (width + 1) & ~1; + height = (height + 1) & ~1; + + _drawRect.left = x; + _drawRect.top = y; + _drawRect.right = x + width; + _drawRect.bottom = y + height; + + // SCI2.1mid uses init2x to draw a pixel-doubled AVI, but SCI2 has only the + // one play routine which automatically pixel-doubles in hi-res mode + if (getSciVersion() == SCI_VERSION_2) { + // This is somewhat of a hack; credits.avi from GK1 is not + // rendered correctly in SSCI because it is a 640x480 video, but the + // game script gives the wrong dimensions. Since this is the only + // high-resolution AVI ever used, just set the draw rectangle to draw + // the entire screen + if (_decoder->getWidth() > 320) { + _drawRect.left = 0; + _drawRect.top = 0; + _drawRect.right = 320; + _drawRect.bottom = 200; + } + + // In hi-res mode, video will be pixel doubled, so the origin (which + // corresponds to the correct position without pixel doubling) needs to + // be corrected + if (g_sci->_gfxFrameout->_isHiRes && _decoder->getWidth() <= 320) { + _drawRect.left /= 2; + _drawRect.top /= 2; + } + } + + init(); + + return kIOSuccess; +} + +AVIPlayer::IOStatus AVIPlayer::init2x(const int16 x, const int16 y) { + if (_status == kAVINotOpen) { + return kIOFileNotFound; + } + + _drawRect.left = x; + _drawRect.top = y; + _drawRect.right = x + _decoder->getWidth() * 2; + _drawRect.bottom = y + _decoder->getHeight() * 2; + + _pixelDouble = true; + init(); + + return kIOSuccess; +} + +void AVIPlayer::init() { + int16 xRes; + int16 yRes; + + bool useScreenDimensions = false; + if (g_sci->_gfxFrameout->_isHiRes && _decoder->getWidth() > 320) { + useScreenDimensions = true; + } + + // KQ7 1.51 gives video position in screen coordinates, not game + // coordinates, because in SSCI they are passed to Video for Windows, which + // renders as an overlay on the game video. Because we put the video into a + // ScreenItem instead of rendering directly to the hardware surface, the + // coordinates need to be converted to game script coordinates + if (g_sci->getGameId() == GID_KQ7 && getSciVersion() == SCI_VERSION_2_1_EARLY) { + useScreenDimensions = !_pixelDouble; + // This y-translation is arbitrary, based on what roughly centers the + // videos in the game window + _drawRect.translate(-_drawRect.left / 2, -_drawRect.top * 2 / 3); + } + + if (useScreenDimensions) { + xRes = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth; + yRes = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight; + } else { + xRes = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; + yRes = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; + } + + _plane = new Plane(_drawRect); + g_sci->_gfxFrameout->addPlane(*_plane); + + if (_decoder->getPixelFormat().bytesPerPixel == 1) { + _segMan->allocateBitmap(&_bitmap, _decoder->getWidth(), _decoder->getHeight(), kDefaultSkipColor, 0, 0, xRes, yRes, 0, false, false); + + CelInfo32 celInfo; + celInfo.type = kCelTypeMem; + celInfo.bitmap = _bitmap; + + _screenItem = new ScreenItem(_plane->_object, celInfo, Common::Point(_drawRect.left, _drawRect.top), ScaleInfo()); + g_sci->_gfxFrameout->addScreenItem(*_screenItem); + g_sci->_gfxFrameout->frameOut(true); + } else { + const Buffer ¤tBuffer = g_sci->_gfxFrameout->getCurrentBuffer(); + const Graphics::PixelFormat format = _decoder->getPixelFormat(); + initGraphics(currentBuffer.screenWidth, currentBuffer.screenHeight, g_sci->_gfxFrameout->_isHiRes, &format); + + if (_pixelDouble) { + const int16 width = _drawRect.width(); + const int16 height = _drawRect.height(); + _scaleBuffer = calloc(1, width * height * format.bytesPerPixel); + } + } +} + +AVIPlayer::IOStatus AVIPlayer::play(const int16 from, const int16 to, const int16, const bool async) { + if (_status == kAVINotOpen) { + return kIOFileNotFound; + } + + if (from >= 0 && to > 0 && from <= to) { + _decoder->seekToFrame(from); + _decoder->setEndFrame(to); + } + + if (!async) { + renderVideo(); + } else if (getSciVersion() == SCI_VERSION_2_1_EARLY) { + playUntilEvent((EventFlags)(kEventFlagEnd | kEventFlagEscapeKey)); + } else { + _status = kAVIPlaying; + } + + return kIOSuccess; +} + +void AVIPlayer::renderVideo() const { + _decoder->start(); + while (!g_engine->shouldQuit() && !_decoder->endOfVideo()) { + g_sci->getEngineState()->speedThrottler(_decoder->getTimeToNextFrame()); + g_sci->getEngineState()->_throttleTrigger = true; + if (_decoder->needsUpdate()) { + renderFrame(); + } + } +} + +AVIPlayer::IOStatus AVIPlayer::close() { + if (_status == kAVINotOpen) { + return kIOSuccess; + } + + free(_scaleBuffer); + _scaleBuffer = nullptr; + + if (_decoder->getPixelFormat().bytesPerPixel != 1) { + const bool isHiRes = g_sci->_gfxFrameout->_isHiRes; + const Buffer ¤tBuffer = g_sci->_gfxFrameout->getCurrentBuffer(); + const Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8(); + initGraphics(currentBuffer.screenWidth, currentBuffer.screenHeight, isHiRes, &format); + } + + _decoder->close(); + _status = kAVINotOpen; + g_sci->_gfxFrameout->deletePlane(*_plane); + _plane = nullptr; + _screenItem = nullptr; + return kIOSuccess; +} + +AVIPlayer::IOStatus AVIPlayer::cue(const uint16 frameNo) { + if (!_decoder->seekToFrame(frameNo)) { + return kIOSeekFailed; + } + + _status = kAVIPaused; + return kIOSuccess; +} + +uint16 AVIPlayer::getDuration() const { + if (_status == kAVINotOpen) { + return 0; + } + + return _decoder->getFrameCount(); +} + +void AVIPlayer::renderFrame() const { + const Graphics::Surface *surface = _decoder->decodeNextFrame(); + + if (surface->format.bytesPerPixel == 1) { + SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap); + if (surface->w > bitmap.getWidth() || surface->h > bitmap.getHeight()) { + warning("Attempted to draw a video frame larger than the destination bitmap"); + return; + } + + // KQ7 1.51 encodes videos with palette entry 0 as white, which makes + // the area around the video turn white too, since it is coded to use + // palette entry 0. This happens to work in the original game because + // the video is rendered by VfW, not in the engine itself. To fix this, + // we just modify the incoming pixel data from the video so if a pixel + // is using entry 0, we change it to use entry 255, which is guaranteed + // to always be white + if (getSciVersion() == SCI_VERSION_2_1_EARLY && g_sci->getGameId() == GID_KQ7) { + uint8 *target = bitmap.getPixels(); + uint8 *source = (uint8 *)surface->getPixels(); + uint8 *end = (uint8 *)surface->getPixels() + surface->w * surface->h; + + while (source != end) { + uint8 value = *source++; + *target++ = value == 0 ? 255 : value; + } + } else { + bitmap.getBuffer().copyRectToSurface(*surface, 0, 0, Common::Rect(surface->w, surface->h)); + } + + const bool dirtyPalette = _decoder->hasDirtyPalette(); + if (dirtyPalette) { + Palette palette; + const byte *rawPalette = _decoder->getPalette(); + for (int i = 0; i < ARRAYSIZE(palette.colors); ++i) { + palette.colors[i].r = *rawPalette++; + palette.colors[i].g = *rawPalette++; + palette.colors[i].b = *rawPalette++; + palette.colors[i].used = true; + } + + // Prevent KQ7 1.51 from setting entry 0 to white + palette.colors[0].used = false; + + g_sci->_gfxPalette32->submit(palette); + } + + g_sci->_gfxFrameout->updateScreenItem(*_screenItem); + g_sci->getSciDebugger()->onFrame(); + g_sci->_gfxFrameout->frameOut(true); + } else { + assert(surface->format.bytesPerPixel == 4); + + Common::Rect drawRect(_drawRect); + + if (_pixelDouble) { + const uint32 *source = (uint32 *)surface->getPixels(); + uint32 *target = (uint32 *)_scaleBuffer; + // target pitch here is in uint32s, not bytes + const uint16 pitch = surface->pitch / 2; + for (int y = 0; y < surface->h; ++y) { + for (int x = 0; x < surface->w; ++x) { + const uint32 value = *source++; + + target[0] = value; + target[1] = value; + target[pitch] = value; + target[pitch + 1] = value; + target += 2; + } + target += pitch; + } + + g_system->copyRectToScreen(_scaleBuffer, surface->pitch * 2, _drawRect.left, _drawRect.top, _drawRect.width(), _drawRect.height()); + } else { + const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth; + const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight; + const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; + const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; + + mulinc(drawRect, Ratio(screenWidth, scriptWidth), Ratio(screenHeight, scriptHeight)); + + g_system->copyRectToScreen(surface->getPixels(), surface->pitch, drawRect.left, drawRect.top, surface->w, surface->h); + } + } +} + +AVIPlayer::EventFlags AVIPlayer::playUntilEvent(EventFlags flags) { + _decoder->start(); + + EventFlags stopFlag = kEventFlagNone; + while (!g_engine->shouldQuit()) { + if (_decoder->endOfVideo()) { + stopFlag = kEventFlagEnd; + break; + } + + g_sci->getEngineState()->speedThrottler(_decoder->getTimeToNextFrame()); + g_sci->getEngineState()->_throttleTrigger = true; + if (_decoder->needsUpdate()) { + renderFrame(); + } + + SciEvent event = _eventMan->getSciEvent(SCI_EVENT_MOUSE_PRESS | SCI_EVENT_PEEK); + if ((flags & kEventFlagMouseDown) && event.type == SCI_EVENT_MOUSE_PRESS) { + stopFlag = kEventFlagMouseDown; + break; + } + + event = _eventMan->getSciEvent(SCI_EVENT_KEYBOARD | SCI_EVENT_PEEK); + if ((flags & kEventFlagEscapeKey) && event.type == SCI_EVENT_KEYBOARD) { + bool stop = false; + while ((event = _eventMan->getSciEvent(SCI_EVENT_KEYBOARD)), + event.type != SCI_EVENT_NONE) { + if (event.character == SCI_KEY_ESC) { + stop = true; + break; + } + } + + if (stop) { + stopFlag = kEventFlagEscapeKey; + break; + } + } + + // TODO: Hot rectangles + if ((flags & kEventFlagHotRectangle) /* && event.type == SCI_EVENT_HOT_RECTANGLE */) { + warning("Hot rectangles not implemented in VMD player"); + stopFlag = kEventFlagHotRectangle; + break; + } + } + + return stopFlag; +} + +#pragma mark - #pragma mark VMDPlayer VMDPlayer::VMDPlayer(SegManager *segMan, EventManager *eventMan) : @@ -117,6 +574,7 @@ VMDPlayer::IOStatus VMDPlayer::close() { if (!_planeIsOwned && _screenItem != nullptr) { g_sci->_gfxFrameout->deleteScreenItem(*_screenItem); + _segMan->freeBitmap(_screenItem->_celInfo.bitmap); _screenItem = nullptr; } else if (_plane != nullptr) { g_sci->_gfxFrameout->deletePlane(*_plane); @@ -231,14 +689,15 @@ VMDPlayer::EventFlags VMDPlayer::playUntilEvent(const EventFlags flags) { const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; - BitmapResource vmdBitmap(_segMan, vmdRect.width(), vmdRect.height(), 255, 0, 0, screenWidth, screenHeight, 0, false); + reg_t bitmapId; + SciBitmap &vmdBitmap = *_segMan->allocateBitmap(&bitmapId, vmdRect.width(), vmdRect.height(), 255, 0, 0, screenWidth, screenHeight, 0, false, false); if (screenWidth != scriptWidth || screenHeight != scriptHeight) { mulru(vmdRect, Ratio(scriptWidth, screenWidth), Ratio(scriptHeight, screenHeight), 1); } CelInfo32 vmdCelInfo; - vmdCelInfo.bitmap = vmdBitmap.getObject(); + vmdCelInfo.bitmap = bitmapId; _decoder->setSurfaceMemory(vmdBitmap.getPixels(), vmdBitmap.getWidth(), vmdBitmap.getHeight(), 1); if (_planeIsOwned) { @@ -348,6 +807,12 @@ void VMDPlayer::renderFrame() const { if (dirtyPalette) { Palette palette; palette.timestamp = g_sci->getTickCount(); + for (uint16 i = 0; i < _startColor; ++i) { + palette.colors[i].used = false; + } + for (uint16 i = _endColor; i < 256; ++i) { + palette.colors[i].used = false; + } if (_blackPalette) { for (uint16 i = _startColor; i <= _endColor; ++i) { palette.colors[i].r = palette.colors[i].g = palette.colors[i].b = 0; @@ -398,9 +863,12 @@ void VMDPlayer::fillPalette(Palette &palette) const { #pragma mark - #pragma mark VMDPlayer - Palette -void VMDPlayer::restrictPalette(const uint8 startColor, const uint8 endColor) { +void VMDPlayer::restrictPalette(const uint8 startColor, const int16 endColor) { _startColor = startColor; - _endColor = endColor; + // At least GK2 sends 256 as the end color, which is wrong, + // but works in the original engine as the storage size is 4 bytes + // and used values are clamped to 0-255 + _endColor = MIN((int16)255, endColor); } } // End of namespace Sci diff --git a/engines/sci/graphics/video32.h b/engines/sci/graphics/video32.h index cf863ba41d..0496f61d5d 100644 --- a/engines/sci/graphics/video32.h +++ b/engines/sci/graphics/video32.h @@ -23,16 +23,215 @@ #ifndef SCI_GRAPHICS_VIDEO32_H #define SCI_GRAPHICS_VIDEO32_H -namespace Video { class AdvancedVMDDecoder; } +#include "common/rect.h" // for Rect +#include "common/scummsys.h" // for int16, uint8, uint16, int32 +#include "common/str.h" // for String +#include "sci/engine/vm_types.h" // for reg_t + +namespace Video { +class AdvancedVMDDecoder; +class AVIDecoder; +} namespace Sci { +class EventManager; class Plane; class ScreenItem; class SegManager; +class SEQDecoder; +struct Palette; +#pragma mark SEQPlayer + +/** + * SEQPlayer is used to play SEQ animations. + * Used by DOS versions of GK1 and QFG4CD. + */ +class SEQPlayer { +public: + SEQPlayer(SegManager *segMan); + + /** + * Plays a SEQ animation with the given + * file name, with each frame being displayed + * for `numTicks` ticks. + */ + void play(const Common::String &fileName, const int16 numTicks, const int16 x, const int16 y); + +private: + SegManager *_segMan; + SEQDecoder *_decoder; + + /** + * The plane where the SEQ will be drawn. + */ + Plane *_plane; + + /** + * The screen item representing the SEQ surface. + */ + ScreenItem *_screenItem; + + /** + * The bitmap used to render video output. + */ + reg_t _bitmap; + + /** + * Renders a single frame of video. + */ + void renderFrame() const; +}; + +#pragma mark - +#pragma mark AVIPlayer + +/** + * AVIPlayer is used to play AVI videos. Used by + * Windows versions of GK1CD, KQ7, and QFG4CD. + */ +class AVIPlayer { +public: + enum IOStatus { + kIOSuccess = 0, + kIOFileNotFound = 2, + kIOSeekFailed = 12 + }; + + enum AVIStatus { + kAVINotOpen = 0, + kAVIOpen = 1, + kAVIPlaying = 2, + kAVIPaused = 3 + }; + + enum EventFlags { + kEventFlagNone = 0, + kEventFlagEnd = 1, + kEventFlagEscapeKey = 2, + kEventFlagMouseDown = 4, + kEventFlagHotRectangle = 8 + }; + + AVIPlayer(SegManager *segMan, EventManager *eventMan); + ~AVIPlayer(); + + /** + * Opens a stream to an AVI resource. + */ + IOStatus open(const Common::String &fileName); + + /** + * Initializes the AVI rendering parameters for the + * current AVI. This must be called after `open`. + */ + IOStatus init1x(const int16 x, const int16 y, const int16 width, const int16 height); + + /** + * Initializes the AVI rendering parameters for the + * current AVI, in pixel-doubling mode. This must + * be called after `open`. + */ + IOStatus init2x(const int16 x, const int16 y); + + /** + * Begins playback of the current AVI. + */ + IOStatus play(const int16 from, const int16 to, const int16 showStyle, const bool cue); + + /** + * Stops playback and closes the currently open AVI stream. + */ + IOStatus close(); + + /** + * Seeks the currently open AVI stream to the given frame. + */ + IOStatus cue(const uint16 frameNo); + + /** + * Returns the duration of the current video. + */ + uint16 getDuration() const; + + /** + * Plays the AVI until an event occurs (e.g. user + * presses escape, clicks, etc.). + */ + EventFlags playUntilEvent(const EventFlags flags); + +private: + typedef Common::HashMap<uint16, AVIStatus> StatusMap; + + SegManager *_segMan; + EventManager *_eventMan; + Video::AVIDecoder *_decoder; + + /** + * Playback status of the player. + */ + AVIStatus _status; + + /** + * The plane where the AVI will be drawn. + */ + Plane *_plane; + + /** + * The screen item representing the AVI surface, + * in 8bpp mode. In 24bpp mode, video is drawn + * directly to the screen. + */ + ScreenItem *_screenItem; + + /** + * The bitmap used to render video output in + * 8bpp mode. + */ + reg_t _bitmap; + + /** + * The rectangle where the video will be drawn, + * in game script coordinates. + */ + Common::Rect _drawRect; + + /** + * The scale buffer for pixel-doubled videos + * drawn in 24bpp mode. + */ + void *_scaleBuffer; + + /** + * In SCI2.1, whether or not the video should + * be pixel doubled for playback. + */ + bool _pixelDouble; + + /** + * Performs common initialisation for both + * scaled and unscaled videos. + */ + void init(); + + /** + * Renders video without event input until the + * video is complete. + */ + void renderVideo() const; + + /** + * Renders a single frame of video. + */ + void renderFrame() const; +}; + +#pragma mark - #pragma mark VMDPlayer /** * VMDPlayer is used to play VMD videos. + * Used by Phant1, GK2, PQ:SWAT, Shivers, SQ6, + * Torin, and Lighthouse. */ class VMDPlayer { public: @@ -233,7 +432,7 @@ public: * Restricts use of the system palette by VMD playback to * the given range of palette indexes. */ - void restrictPalette(const uint8 startColor, const uint8 endColor); + void restrictPalette(const uint8 startColor, const int16 endColor); private: /** @@ -297,14 +496,24 @@ private: bool _showCursor; }; +/** + * Video32 provides facilities for playing back + * video in SCI engine. + */ class Video32 { public: Video32(SegManager *segMan, EventManager *eventMan) : + _SEQPlayer(segMan), + _AVIPlayer(segMan, eventMan), _VMDPlayer(segMan, eventMan) {} + SEQPlayer &getSEQPlayer() { return _SEQPlayer; } + AVIPlayer &getAVIPlayer() { return _AVIPlayer; } VMDPlayer &getVMDPlayer() { return _VMDPlayer; } private: + SEQPlayer _SEQPlayer; + AVIPlayer _AVIPlayer; VMDPlayer _VMDPlayer; }; } // End of namespace Sci diff --git a/engines/sci/module.mk b/engines/sci/module.mk index 1511356747..18d97ea57e 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -91,6 +91,7 @@ MODULE_OBJS += \ graphics/remap32.o \ graphics/screen_item32.o \ graphics/text32.o \ + graphics/transitions32.o \ graphics/video32.o \ sound/audio32.o \ sound/decoders/sol.o \ diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 3e50fc1082..48278e35a7 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -1367,6 +1367,7 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType resource if (!file->open(source->getLocationName())) { warning("ResourceManager::processPatch(): failed to open %s", source->getLocationName().c_str()); delete source; + delete file; return; } fileStream = file; @@ -1376,6 +1377,7 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType resource if (fsize < 3) { debug("Patching %s failed - file too small", source->getLocationName().c_str()); delete source; + delete fileStream; return; } diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index f9481bb301..4c178b6ed7 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -69,6 +69,7 @@ #include "sci/graphics/palette32.h" #include "sci/graphics/remap32.h" #include "sci/graphics/text32.h" +#include "sci/graphics/transitions32.h" #include "sci/graphics/video32.h" #include "sci/sound/audio32.h" // TODO: Move this to video32 @@ -167,11 +168,16 @@ SciEngine::~SciEngine() { DebugMan.clearAllDebugChannels(); #ifdef ENABLE_SCI32 - delete _gfxPalette32; delete _gfxControls32; delete _gfxPaint32; delete _gfxText32; delete _robotDecoder; + // GfxFrameout and GfxPalette32 must be deleted after Video32 since + // destruction of screen items in the Video32 destructor relies on these + // components + delete _video32; + delete _gfxPalette32; + delete _gfxTransitions32; delete _gfxFrameout; delete _gfxRemap32; delete _audio32; @@ -708,6 +714,7 @@ void SciEngine::initGraphics() { _gfxPaint32 = 0; _gfxPalette32 = 0; _gfxRemap32 = 0; + _gfxTransitions32 = 0; #endif if (hasMacIconBar()) @@ -737,7 +744,8 @@ void SciEngine::initGraphics() { _gfxCompare = new GfxCompare(_gamestate->_segMan, _gfxCache, _gfxScreen, _gfxCoordAdjuster); _gfxPaint32 = new GfxPaint32(_gamestate->_segMan); _robotDecoder = new RobotDecoder(getPlatform() == Common::kPlatformMacintosh); - _gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxScreen, _gfxPalette32); + _gfxTransitions32 = new GfxTransitions32(_gamestate->_segMan); + _gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxScreen, _gfxPalette32, _gfxTransitions32); _gfxText32 = new GfxText32(_gamestate->_segMan, _gfxCache); _gfxControls32 = new GfxControls32(_gamestate->_segMan, _gfxCache, _gfxText32); _gfxFrameout->run(); diff --git a/engines/sci/sci.h b/engines/sci/sci.h index 0020d25b91..a42095259b 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -85,6 +85,7 @@ class RobotDecoder; class GfxFrameout; class Audio32; class Video32; +class GfxTransitions32; #endif // our engine debug levels @@ -377,6 +378,7 @@ public: Video32 *_video32; RobotDecoder *_robotDecoder; GfxFrameout *_gfxFrameout; // kFrameout and the like for 32-bit gfx + GfxTransitions32 *_gfxTransitions32; #endif AudioPlayer *_audio; diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp index 0cf8e3cb13..288b7c00f5 100644 --- a/engines/sci/sound/audio32.cpp +++ b/engines/sci/sound/audio32.cpp @@ -309,11 +309,6 @@ int Audio32::readBuffer(Audio::st_sample_t *buffer, const int numSamples) { continue; } - if (channel.vmd) { - // TODO: VMD audio into output buffer - continue; - } - Audio::st_volume_t leftVolume, rightVolume; if (channel.pan == -1 || !isStereo()) { @@ -605,7 +600,6 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool channel.resource = resource; channel.loop = loop; channel.robot = false; - channel.vmd = false; channel.fadeStartTick = 0; channel.soundNode = soundNode; channel.volume = volume < 0 || volume > kMaxVolume ? (int)kMaxVolume : volume; diff --git a/engines/sci/sound/audio32.h b/engines/sci/sound/audio32.h index b0c1ba1998..ac3176cc5a 100644 --- a/engines/sci/sound/audio32.h +++ b/engines/sci/sound/audio32.h @@ -123,12 +123,6 @@ struct AudioChannel { bool robot; /** - * Whether or not this channel contains a VMD audio - * track. - */ - bool vmd; - - /** * For digital sound effects, the related VM * Sound::nodePtr object for the sound. */ diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index a829ab22e6..423be448fe 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -48,7 +48,7 @@ Screen::Screen(SherlockEngine *vm) : BaseSurface(), _vm(vm), Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0); Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0); Common::fill(&_tMap[0], &_tMap[PALETTE_SIZE], 0); - + // Set up the initial font setFont(IS_SERRATED_SCALPEL ? 1 : 4); @@ -172,8 +172,8 @@ void Screen::restoreBackground(const Common::Rect &r) { _backBuffer.SHblitFrom(_backBuffer2, Common::Point(r.left, r.top), r); } -void Screen::slamArea(int16 xp, int16 yp, int16 width, int16 height) { - slamRect(Common::Rect(xp, yp, xp + width, yp + height)); +void Screen::slamArea(int16 xp, int16 yp, int16 width_, int16 height_) { + slamRect(Common::Rect(xp, yp, xp + width_, yp + height_)); } void Screen::slamRect(const Common::Rect &r) { @@ -204,11 +204,11 @@ void Screen::slamRect(const Common::Rect &r) { } } -void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp, - int16 *width, int16 *height) { +void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp, + int16 *width_, int16 *height_) { Common::Point imgPos = pt + frame->_offset; Common::Rect newBounds(imgPos.x, imgPos.y, imgPos.x + frame->_frame.w, imgPos.y + frame->_frame.h); - Common::Rect oldBounds(*xp, *yp, *xp + *width, *yp + *height); + Common::Rect oldBounds(*xp, *yp, *xp + *width_, *yp + *height_); if (!_flushScreen) { // See if the areas of the old and new overlap, and if so combine the areas @@ -228,16 +228,16 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, i *xp = newBounds.left; *yp = newBounds.top; - *width = newBounds.width(); - *height = newBounds.height(); + *width_ = newBounds.width(); + *height_ = newBounds.height(); } void Screen::flushScaleImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp, - int16 *width, int16 *height, int scaleVal) { + int16 *width_, int16 *height_, int scaleVal) { Common::Point imgPos(pt.x + frame->sDrawXOffset(scaleVal), pt.y + frame->sDrawYOffset(scaleVal)); - Common::Rect newBounds(imgPos.x, imgPos.y, imgPos.x + frame->sDrawXSize(scaleVal), + Common::Rect newBounds(imgPos.x, imgPos.y, imgPos.x + frame->sDrawXSize(scaleVal), imgPos.y + frame->sDrawYSize(scaleVal)); - Common::Rect oldBounds(*xp, *yp, *xp + *width, *yp + *height); + Common::Rect oldBounds(*xp, *yp, *xp + *width_, *yp + *height_); if (!_flushScreen) { // See if the areas of the old and new overlap, and if so combine the areas @@ -257,8 +257,8 @@ void Screen::flushScaleImage(ImageFrame *frame, const Common::Point &pt, int16 * *xp = newBounds.left; *yp = newBounds.top; - *width = newBounds.width(); - *height = newBounds.height(); + *width_ = newBounds.width(); + *height_ = newBounds.height(); } void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, Common::Rect &newBounds, int scaleVal) { @@ -292,15 +292,15 @@ void Screen::print(const Common::Point &pt, uint color, const char *formatStr, . // Figure out area to draw text in Common::Point pos = pt; - int width = stringWidth(str); + int width_ = stringWidth(str); pos.y--; // Font is always drawing one line higher if (!pos.x) // Center text horizontally - pos.x = (this->width() - width) / 2; + pos.x = (this->width() - width_) / 2; - Common::Rect textBounds(pos.x, pos.y, pos.x + width, pos.y + _fontHeight); + Common::Rect textBounds(pos.x, pos.y, pos.x + width_, pos.y + _fontHeight); if (textBounds.right > this->width()) - textBounds.moveTo(this->width() - width, textBounds.top); + textBounds.moveTo(this->width() - width_, textBounds.top); if (textBounds.bottom > this->height()) textBounds.moveTo(textBounds.left, this->height() - _fontHeight); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index e068ac481a..c6b38f78d7 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -30,6 +30,11 @@ namespace Sherlock { SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _randomSource("Sherlock") { + DebugMan.addDebugChannel(kDebugLevelScript, "scripts", "Script debug level"); + DebugMan.addDebugChannel(kDebugLevelAdLibDriver, "AdLib", "AdLib driver debugging"); + DebugMan.addDebugChannel(kDebugLevelMT32Driver, "MT32", "MT32 driver debugging"); + DebugMan.addDebugChannel(kDebugLevelMusic, "Music", "Music debugging"); + _animation = nullptr; _debugger = nullptr; _events = nullptr; @@ -74,11 +79,6 @@ SherlockEngine::~SherlockEngine() { } void SherlockEngine::initialize() { - DebugMan.addDebugChannel(kDebugLevelScript, "scripts", "Script debug level"); - DebugMan.addDebugChannel(kDebugLevelAdLibDriver, "AdLib", "AdLib driver debugging"); - DebugMan.addDebugChannel(kDebugLevelMT32Driver, "MT32", "MT32 driver debugging"); - DebugMan.addDebugChannel(kDebugLevelMusic, "Music", "Music debugging"); - Fonts::setVm(this); ImageFile::setVm(this); ImageFile3DO::setVm(this); diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp index 93bc001149..cca012630c 100644 --- a/engines/sherlock/surface.cpp +++ b/engines/sherlock/surface.cpp @@ -29,9 +29,9 @@ BaseSurface::BaseSurface() : Graphics::Screen(0, 0), Fonts() { free(); // Free the 0x0 surface allocated by Graphics::Screen } -BaseSurface::BaseSurface(int width, int height) : Graphics::Screen(width, height), +BaseSurface::BaseSurface(int width_, int height_) : Graphics::Screen(width_, height_), Fonts() { - create(width, height); + create(width_, height_); } void BaseSurface::writeString(const Common::String &str, const Common::Point &pt, uint overrideColor) { @@ -61,7 +61,7 @@ void BaseSurface::SHtransBlitFrom(const Graphics::Surface &src, const Common::Po Common::Rect srcRect(0, 0, src.w, src.h); Common::Rect destRect(pt.x, pt.y, pt.x + src.w * SCALE_THRESHOLD / scaleVal, pt.y + src.h * SCALE_THRESHOLD / scaleVal); - + Graphics::Screen::transBlitFrom(src, srcRect, destRect, TRANSPARENCY, flipped, overrideColor); } diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h index 401d9b648d..d55606ed82 100644 --- a/engines/sherlock/surface.h +++ b/engines/sherlock/surface.h @@ -121,7 +121,7 @@ protected: virtual void addDirtyRect(const Common::Rect &r) {} public: Surface() : BaseSurface() {} - Surface(int width, int height) : BaseSurface(width, height) {} + Surface(int width_, int height_) : BaseSurface(width_, height_) {} }; } // End of namespace Sherlock diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp index 44e81494f7..8ad177abbb 100644 --- a/engines/tinsel/tinsel.cpp +++ b/engines/tinsel/tinsel.cpp @@ -821,6 +821,12 @@ const char *const TinselEngine::_textFiles[][3] = { TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _random("tinsel"), _console(0), _sound(0), _midiMusic(0), _pcmMusic(0), _bmv(0) { + // Register debug flags + DebugMan.addDebugChannel(kTinselDebugAnimations, "animations", "Animations debugging"); + DebugMan.addDebugChannel(kTinselDebugActions, "actions", "Actions debugging"); + DebugMan.addDebugChannel(kTinselDebugSound, "sound", "Sound debugging"); + DebugMan.addDebugChannel(kTinselDebugMusic, "music", "Music debugging"); + _vm = this; _gameId = 0; @@ -828,12 +834,6 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc) _config = new Config(this); - // Register debug flags - DebugMan.addDebugChannel(kTinselDebugAnimations, "animations", "Animations debugging"); - DebugMan.addDebugChannel(kTinselDebugActions, "actions", "Actions debugging"); - DebugMan.addDebugChannel(kTinselDebugSound, "sound", "Sound debugging"); - DebugMan.addDebugChannel(kTinselDebugMusic, "music", "Music debugging"); - // Setup mixer syncSoundSettings(); diff --git a/engines/titanic/carry/arm.cpp b/engines/titanic/carry/arm.cpp new file mode 100644 index 0000000000..880c93d309 --- /dev/null +++ b/engines/titanic/carry/arm.cpp @@ -0,0 +1,213 @@ +/* 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 "titanic/carry/arm.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CArm, CCarry) + ON_MESSAGE(PuzzleSolvedMsg) + ON_MESSAGE(TranslateObjectMsg) + ON_MESSAGE(UseWithOtherMsg) + ON_MESSAGE(MouseDragStartMsg) + ON_MESSAGE(MaitreDHappyMsg) + ON_MESSAGE(PETGainedObjectMsg) + ON_MESSAGE(MouseDragMoveMsg) +END_MESSAGE_MAP() + +CArm::CArm() : CCarry(), _string6("Key"), + _field138(0), _field158(0), _field16C(3), _field170(0), + _armRect(220, 208, 409, 350) { +} + +void CArm::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string6, indent); + file->writeNumberLine(_field138, indent); + file->writeNumberLine(_hookedRect.left, indent); + file->writeNumberLine(_hookedRect.top, indent); + file->writeNumberLine(_hookedRect.right, indent); + file->writeNumberLine(_hookedRect.bottom, indent); + + file->writeQuotedLine(_string7, indent); + file->writeNumberLine(_field158, indent); + file->writeNumberLine(_armRect.left, indent); + file->writeNumberLine(_armRect.top, indent); + file->writeNumberLine(_armRect.right, indent); + file->writeNumberLine(_armRect.bottom, indent); + file->writeNumberLine(_field16C, indent); + file->writeNumberLine(_field170, indent); + + CCarry::save(file, indent); +} + +void CArm::load(SimpleFile *file) { + file->readNumber(); + _string6 = file->readString(); + _field138 = file->readNumber(); + _hookedRect.left = file->readNumber(); + _hookedRect.top = file->readNumber(); + _hookedRect.right = file->readNumber(); + _hookedRect.bottom = file->readNumber(); + + _string7 = file->readString(); + _field158 = file->readNumber(); + _armRect.left = file->readNumber(); + _armRect.top = file->readNumber(); + _armRect.right = file->readNumber(); + _armRect.bottom = file->readNumber(); + _field16C = file->readNumber(); + _field170 = file->readNumber(); + + CCarry::load(file); +} + +bool CArm::PuzzleSolvedMsg(CPuzzleSolvedMsg *msg) { + _field138 = 0; + _fieldE0 = 1; + + CString name = getName(); + if (name == "Arm1") { + CActMsg actMsg("LoseArm"); + actMsg.execute("MaitreD"); + CPuzzleSolvedMsg solvedMsg; + solvedMsg.execute("AuditoryCentre"); + } else if (name == "Arm2") { + CPuzzleSolvedMsg solvedMsg; + solvedMsg.execute("Key"); + } + + return true; +} + +bool CArm::TranslateObjectMsg(CTranslateObjectMsg *msg) { + Point newPos(_bounds.left - msg->_delta.x, _bounds.top - msg->_delta.y); + setPosition(newPos); + return true; +} + +bool CArm::UseWithOtherMsg(CUseWithOtherMsg *msg) { + if (_string6 != "None") { + CShowTextMsg textMsg("The arm is already holding something."); + textMsg.execute("PET"); + return false; + } else if (msg->_other->getName() == "GondolierLeftLever") { + CIsHookedOnMsg hookedMsg(_hookedRect, 0, getName()); + hookedMsg._rect.translate(_bounds.left, _bounds.top); + hookedMsg.execute("GondolierLeftLever"); + + if (hookedMsg._result) { + _string7 = "GondolierLeftLever"; + } else { + petAddToInventory(); + } + } else if (msg->_other->getName() == "GondolierRightLever") { + CIsHookedOnMsg hookedMsg(_hookedRect, 0, getName()); + hookedMsg._rect.translate(_bounds.left, _bounds.top); + hookedMsg.execute("GondolierRightLever"); + + if (hookedMsg._result) { + _string7 = "GondolierRightLever"; + } else { + petAddToInventory(); + } + } + + return true; +} + +bool CArm::MouseDragStartMsg(CMouseDragStartMsg *msg) { + if (!_fieldE0) { + CShowTextMsg textMsg("You can't get this."); + textMsg.execute("PET"); + } else if (checkStartDragging(msg)) { + _tempPos = msg->_mousePos - _bounds; + setPosition(msg->_mousePos - _tempPos); + + if (!_string7.empty()) { + CActMsg actMsg("Unhook"); + actMsg.execute(_string7); + _string7.clear(); + } + + loadFrame(_visibleFrame); + return true; + } + + return false; +} + +bool CArm::MaitreDHappyMsg(CMaitreDHappyMsg *msg) { + CGameObject *petItem; + if (find(getName(), &petItem, FIND_PET)) { + if (!_field158) + playSound("z#47.wav", 100, 0, 0); + if (_string6 == "Key" || _string6 == "AuditoryCentre") { + CGameObject *child = static_cast<CGameObject *>(getFirstChild()); + if (child) { + child->setVisible(true); + petAddToInventory(); + } + + _visibleFrame = _field170; + loadFrame(_visibleFrame); + _string6 = "None"; + petInvChange(); + } + } + + _field158 = 1; + _fieldE0 = 1; + return true; +} + +bool CArm::PETGainedObjectMsg(CPETGainedObjectMsg *msg) { + if (_field158) { + if (_string6 == "Key" || _string6 == "AuditoryCentre") { + CCarry *child = static_cast<CCarry *>(getFirstChild()); + if (child) { + _visibleFrame = _field170; + loadFrame(_visibleFrame); + child->setVisible(true); + child->petAddToInventory(); + } + + _string6 = "None"; + } + } + + return true; +} + +bool CArm::MouseDragMoveMsg(CMouseDragMoveMsg *msg) { + setPosition(msg->_mousePos - _tempPos); + + if (_string6 != "None" && compareViewNameTo("FrozenArboretum.Node 5.S")) { + loadFrame(_armRect.contains(msg->_mousePos) ? + _field16C : _visibleFrame); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/arm.h b/engines/titanic/carry/arm.h new file mode 100644 index 0000000000..fc8bba1f08 --- /dev/null +++ b/engines/titanic/carry/arm.h @@ -0,0 +1,68 @@ +/* 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 TITANIC_ARM_H +#define TITANIC_ARM_H + +#include "titanic/carry/carry.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/messages/pet_messages.h" + +namespace Titanic { + +class CArm : public CCarry { + DECLARE_MESSAGE_MAP; + bool PuzzleSolvedMsg(CPuzzleSolvedMsg *msg); + bool TranslateObjectMsg(CTranslateObjectMsg *msg); + bool UseWithOtherMsg(CUseWithOtherMsg *msg); + bool MouseDragStartMsg(CMouseDragStartMsg *msg); + bool MaitreDHappyMsg(CMaitreDHappyMsg *msg); + bool PETGainedObjectMsg(CPETGainedObjectMsg *msg); + bool MouseDragMoveMsg(CMouseDragMoveMsg *msg); +private: + CString _string6; + int _field138; + Rect _hookedRect; + CString _string7; + int _field158; + Rect _armRect; + int _field16C; + int _field170; +public: + CLASSDEF; + CArm(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ARM_H */ diff --git a/engines/titanic/carry/auditory_centre.cpp b/engines/titanic/carry/auditory_centre.cpp new file mode 100644 index 0000000000..0bda975a36 --- /dev/null +++ b/engines/titanic/carry/auditory_centre.cpp @@ -0,0 +1,47 @@ +/* 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 "titanic/carry/auditory_centre.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CAuditoryCentre, CBrain) + ON_MESSAGE(PuzzleSolvedMsg) +END_MESSAGE_MAP() + +void CAuditoryCentre::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CBrain::save(file, indent); +} + +void CAuditoryCentre::load(SimpleFile *file) { + file->readNumber(); + CBrain::load(file); +} + +bool CAuditoryCentre::PuzzleSolvedMsg(CPuzzleSolvedMsg *msg) { + _fieldE0 = 1; + setVisible(true); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/auditory_centre.h b/engines/titanic/carry/auditory_centre.h new file mode 100644 index 0000000000..6f24e86208 --- /dev/null +++ b/engines/titanic/carry/auditory_centre.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_AUDITORY_CENTRE_H +#define TITANIC_AUDITORY_CENTRE_H + +#include "titanic/carry/brain.h" + +namespace Titanic { + +class CAuditoryCentre : public CBrain { + DECLARE_MESSAGE_MAP; + bool PuzzleSolvedMsg(CPuzzleSolvedMsg *msg); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_AUDITORY_CENTRE_H */ diff --git a/engines/titanic/carry/bowl_ear.cpp b/engines/titanic/carry/bowl_ear.cpp new file mode 100644 index 0000000000..bb5172e580 --- /dev/null +++ b/engines/titanic/carry/bowl_ear.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/carry/bowl_ear.h" + +namespace Titanic { + +void CBowlEar::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CEar::save(file, indent); +} + +void CBowlEar::load(SimpleFile *file) { + file->readNumber(); + CEar::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/bowl_ear.h b/engines/titanic/carry/bowl_ear.h new file mode 100644 index 0000000000..4f2fbea478 --- /dev/null +++ b/engines/titanic/carry/bowl_ear.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_BOWL_EAR_H +#define TITANIC_BOWL_EAR_H + +#include "titanic/carry/ear.h" + +namespace Titanic { + +class CBowlEar : public CEar { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BOWL_EAR_H */ diff --git a/engines/titanic/carry/brain.cpp b/engines/titanic/carry/brain.cpp new file mode 100644 index 0000000000..8df0de9961 --- /dev/null +++ b/engines/titanic/carry/brain.cpp @@ -0,0 +1,134 @@ +/* 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 "titanic/carry/brain.h" +#include "titanic/game/brain_slot.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CBrain, CCarry) + ON_MESSAGE(UseWithOtherMsg) + ON_MESSAGE(VisibleMsg) + ON_MESSAGE(MouseDragStartMsg) + ON_MESSAGE(PassOnDragStartMsg) + ON_MESSAGE(PETGainedObjectMsg) +END_MESSAGE_MAP() + +CBrain::CBrain() : CCarry(), _field134(0), _field138(0) { +} + +void CBrain::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writePoint(_pos1, indent); + file->writeNumberLine(_field134, indent); + file->writeNumberLine(_field138, indent); + + CCarry::save(file, indent); +} + +void CBrain::load(SimpleFile *file) { + file->readNumber(); + _pos1 = file->readPoint(); + _field134 = file->readNumber(); + _field138 = file->readNumber(); + + CCarry::load(file); +} + +bool CBrain::UseWithOtherMsg(CUseWithOtherMsg *msg) { + CBrainSlot *slot = static_cast<CBrainSlot *>(msg->_other); + if (slot) { + if (slot->getName() == "CentralCore") { + setVisible(false); + petMoveToHiddenRoom(); + CAddHeadPieceMsg headpieceMsg(getName()); + headpieceMsg.execute("CentralCoreSlot"); + } + else if (!slot->_value1 && slot->getName() == "CentralCoreSlot") { + setVisible(false); + petMoveToHiddenRoom(); + CAddHeadPieceMsg headpieceMsg(getName()); + headpieceMsg.execute(msg->_other); + playSound("z#116.wav", 100, 0, 0); + setPosition(Point(0, 0)); + setVisible(false); + _field134 = 1; + } + + return true; + } + else { + return CCarry::UseWithOtherMsg(msg); + } +} + +bool CBrain::VisibleMsg(CVisibleMsg *msg) { + setVisible(msg->_visible); + return true; +} + +bool CBrain::MouseDragStartMsg(CMouseDragStartMsg *msg) { + if (!checkStartDragging(msg)) + return false; + + if (_field134) { + CTakeHeadPieceMsg headpieceMsg(getName()); + headpieceMsg.execute("TitaniaControl"); + + _field134 = 0; + setVisible(true); + moveToView(); + + setPosition(Point(msg->_mousePos.x - _bounds.width() / 2, + msg->_mousePos.y - _bounds.height() / 2)); + } + + return CCarry::MouseDragStartMsg(msg); +} + +bool CBrain::PassOnDragStartMsg(CPassOnDragStartMsg *msg) { + if (_field134) { + CTakeHeadPieceMsg headpieceMsg(getName()); + headpieceMsg.execute("TitaniaControl"); + _field134 = 0; + + setVisible(true); + moveToView(); + setPosition(Point(msg->_mousePos.x - _bounds.width() / 2, + msg->_mousePos.y - _bounds.height() / 2)); + } + + return CCarry::PassOnDragStartMsg(msg); +} + +bool CBrain::PETGainedObjectMsg(CPETGainedObjectMsg *msg) { + if (!_field138) { + if (getName() == "Perch") { + stateInc38(); + _field138 = 1; + } + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/brain.h b/engines/titanic/carry/brain.h new file mode 100644 index 0000000000..bcba161e27 --- /dev/null +++ b/engines/titanic/carry/brain.h @@ -0,0 +1,61 @@ +/* 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 TITANIC_BRAIN_H +#define TITANIC_BRAIN_H + +#include "titanic/carry/carry.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/messages/pet_messages.h" + +namespace Titanic { + +class CBrain : public CCarry { + DECLARE_MESSAGE_MAP; + bool UseWithOtherMsg(CUseWithOtherMsg *msg); + bool VisibleMsg(CVisibleMsg *msg); + bool MouseDragStartMsg(CMouseDragStartMsg *msg); + bool PassOnDragStartMsg(CPassOnDragStartMsg *msg); + bool PETGainedObjectMsg(CPETGainedObjectMsg *msg); +private: + Point _pos1; + int _field134; + int _field138; +public: + CLASSDEF; + CBrain(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BRAIN_H */ diff --git a/engines/titanic/carry/bridge_piece.cpp b/engines/titanic/carry/bridge_piece.cpp new file mode 100644 index 0000000000..fc845feff0 --- /dev/null +++ b/engines/titanic/carry/bridge_piece.cpp @@ -0,0 +1,95 @@ +/* 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 "titanic/carry/bridge_piece.h" +#include "titanic/game/ship_setting.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CBridgePiece, CCarry) + ON_MESSAGE(UseWithOtherMsg) + ON_MESSAGE(PassOnDragStartMsg) +END_MESSAGE_MAP() + +CBridgePiece::CBridgePiece() : CCarry(), _field140(0) { +} + +void CBridgePiece::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string6, indent); + file->writePoint(_pos3, indent); + file->writeNumberLine(_field140, indent); + + CCarry::save(file, indent); +} + +void CBridgePiece::load(SimpleFile *file) { + file->readNumber(); + _string6 = file->readString(); + _pos3 = file->readPoint(); + _field140 = file->readNumber(); + + CCarry::load(file); +} + +bool CBridgePiece::UseWithOtherMsg(CUseWithOtherMsg *msg) { + CShipSetting *shipSetting = static_cast<CShipSetting *>(msg->_other); + if (!shipSetting) { + return CCarry::UseWithOtherMsg(msg); + } else if (shipSetting->_string4 == "NULL") { + petAddToInventory(); + return true; + } else { + setVisible(false); + playSound("z#54.wav", 100, 0, 0); + setPosition(shipSetting->_pos1); + shipSetting->_string4 = getName(); + petMoveToHiddenRoom(); + + CAddHeadPieceMsg headpieceMsg(shipSetting->getName() == _string6 ? + "Enable" : "Disable"); + CSetFrameMsg frameMsg; + + CString name = getName(); + if (name == "ChickenBridge") { + frameMsg._frameNumber = 1; + } else if (name == "FanBridge") { + frameMsg._frameNumber = 2; + } else if (name == "SeasonBridge") { + frameMsg._frameNumber = 3; + } else if (name == "BeamBridge") { + frameMsg._frameNumber = 0; + } + + frameMsg.execute(shipSetting); + headpieceMsg.execute(shipSetting); + return true; + } +} + +bool CBridgePiece::PassOnDragStartMsg(CPassOnDragStartMsg *msg) { + setVisible(true); + moveToView(); + return CCarry::PassOnDragStartMsg(msg); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/bridge_piece.h b/engines/titanic/carry/bridge_piece.h new file mode 100644 index 0000000000..80a1cc98a8 --- /dev/null +++ b/engines/titanic/carry/bridge_piece.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_BRIDGE_PIECE_H +#define TITANIC_BRIDGE_PIECE_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CBridgePiece : public CCarry { + DECLARE_MESSAGE_MAP; + bool UseWithOtherMsg(CUseWithOtherMsg *msg); + bool PassOnDragStartMsg(CPassOnDragStartMsg *msg); +private: + CString _string6; + Point _pos3; + int _field140; +public: + CLASSDEF; + CBridgePiece(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BRIDGE_PIECE_H */ diff --git a/engines/titanic/carry/carry.cpp b/engines/titanic/carry/carry.cpp new file mode 100644 index 0000000000..75b3b6f35b --- /dev/null +++ b/engines/titanic/carry/carry.cpp @@ -0,0 +1,241 @@ +/* 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 "titanic/carry/carry.h" +#include "titanic/messages/messages.h" +#include "titanic/npcs/character.h" +#include "titanic/npcs/succubus.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CCarry, CGameObject) + ON_MESSAGE(MouseDragStartMsg) + ON_MESSAGE(MouseDragMoveMsg) + ON_MESSAGE(MouseDragEndMsg) + ON_MESSAGE(UseWithCharMsg) + ON_MESSAGE(LeaveViewMsg) + ON_MESSAGE(UseWithOtherMsg) + ON_MESSAGE(VisibleMsg) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(RemoveFromGameMsg) + ON_MESSAGE(MoveToStartPosMsg) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(PassOnDragStartMsg) +END_MESSAGE_MAP() + +CCarry::CCarry() : CGameObject(), _fieldDC(0), _fieldE0(1), + _field100(0), _field104(0), _field108(0), _field10C(0), + _itemFrame(0), _enterFrame(0), _enterFrameSet(false), _visibleFrame(0), + _string1("None"), + _fullViewName("NULL"), + _string3("That doesn't seem to do anything."), + _string4("It doesn't seem to want this.") { +} + +void CCarry::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + file->writePoint(_origPos, indent); + file->writeQuotedLine(_fullViewName, indent); + file->writeNumberLine(_fieldDC, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeQuotedLine(_string3, indent); + file->writeQuotedLine(_string4, indent); + file->writePoint(_tempPos, indent); + file->writeNumberLine(_field104, indent); + file->writeNumberLine(_field108, indent); + file->writeNumberLine(_field10C, indent); + file->writeNumberLine(_itemFrame, indent); + file->writeQuotedLine(_string5, indent); + file->writeNumberLine(_enterFrame, indent); + file->writeNumberLine(_enterFrameSet, indent); + file->writeNumberLine(_visibleFrame, indent); + + CGameObject::save(file, indent); +} + +void CCarry::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + _origPos = file->readPoint(); + _fullViewName = file->readString(); + _fieldDC = file->readNumber(); + _fieldE0 = file->readNumber(); + _string3 = file->readString(); + _string4 = file->readString(); + _tempPos = file->readPoint(); + _field104 = file->readNumber(); + _field108 = file->readNumber(); + _field10C = file->readNumber(); + _itemFrame = file->readNumber(); + _string5 = file->readString(); + _enterFrame = file->readNumber(); + _enterFrameSet = file->readNumber(); + _visibleFrame = file->readNumber(); + + CGameObject::load(file); +} + +bool CCarry::MouseDragStartMsg(CMouseDragStartMsg *msg) { + CString name = getName(); + + if (_fieldE0) { + if (_visible) { + CShowTextMsg textMsg("You can't get this."); + textMsg.execute("PET"); + } + } else { + if (checkStartDragging(msg)) { + CPassOnDragStartMsg startMsg(msg->_mousePos); + startMsg.execute(this); + return true; + } + } + + return false; +} + +bool CCarry::MouseDragMoveMsg(CMouseDragMoveMsg *msg) { + setPosition(msg->_mousePos - _tempPos); + return true; +} + +bool CCarry::MouseDragEndMsg(CMouseDragEndMsg *msg) { + if (msg->_dropTarget) { + if (msg->_dropTarget->isPet()) { + petAddToInventory(); + return true; + } + + CCharacter *npc = static_cast<CCharacter *>(msg->_dropTarget); + if (npc) { + CUseWithCharMsg charMsg(npc); + charMsg.execute(this, nullptr, 0); + return true; + } + + CDropObjectMsg dropMsg(this); + if (dropMsg.execute(msg->_dropTarget)) + return true; + + // Fall back on a use with other message + CUseWithOtherMsg otherMsg(msg->_dropTarget); + if (otherMsg.execute(this, nullptr, 0)) + return true; + } + + CString viewName = getViewFullName(); + if (viewName.empty() || msg->_mousePos.y >= 360) { + sleep(250); + petAddToInventory(); + } else { + setPosition(_origPos); + loadFrame(_itemFrame); + } + + return true; +} + +bool CCarry::UseWithCharMsg(CUseWithCharMsg *msg) { + CSuccUBus *succubus = static_cast<CSuccUBus *>(msg->_character); + if (succubus) { + CSubAcceptCCarryMsg carryMsg; + carryMsg._item = this; + carryMsg.execute(succubus); + } else { + CShowTextMsg textMsg(_string4); + textMsg.execute("PET"); + petAddToInventory(); + } + + return true; +} + +bool CCarry::LeaveViewMsg(CLeaveViewMsg *msg) { + return true; +} + +bool CCarry::UseWithOtherMsg(CUseWithOtherMsg *msg) { + CShowTextMsg textMsg(_string3); + textMsg.execute("PET"); + + _fullViewName = getViewFullName(); + if (_fullViewName.empty() || _bounds.top >= 360) { + sleep(250); + petAddToInventory(); + } else { + setPosition(_origPos); + } + + return true; +} + +bool CCarry::VisibleMsg(CVisibleMsg *msg) { + setVisible(msg->_visible); + if (msg->_visible && _visibleFrame != -1) + loadFrame(_visibleFrame); + + return true; +} + +bool CCarry::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + return true; +} + +bool CCarry::RemoveFromGameMsg(CRemoveFromGameMsg *msg) { + setPosition(Point(0, 0)); + setVisible(false); + + return true; +} + +bool CCarry::MoveToStartPosMsg(CMoveToStartPosMsg *msg) { + setPosition(_origPos); + return true; +} + +bool CCarry::EnterViewMsg(CEnterViewMsg *msg) { + if (!_enterFrameSet) { + loadFrame(_enterFrame); + _enterFrameSet = true; + } + + return true; +} + +bool CCarry::PassOnDragStartMsg(CPassOnDragStartMsg *msg) { + if (_visibleFrame != -1) + loadFrame(_visibleFrame); + + if (msg->_value3) { + _tempPos.x = _bounds.width() / 2; + _tempPos.y = _bounds.height() / 2; + } else { + _tempPos = msg->_mousePos - _bounds; + } + + setPosition(_tempPos - getMousePos()); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/carry.h b/engines/titanic/carry/carry.h new file mode 100644 index 0000000000..72f4024904 --- /dev/null +++ b/engines/titanic/carry/carry.h @@ -0,0 +1,81 @@ +/* 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 TITANIC_CARRY_H +#define TITANIC_CARRY_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +class CCarry : public CGameObject { + DECLARE_MESSAGE_MAP; + bool MouseDragStartMsg(CMouseDragStartMsg *msg); + bool MouseDragMoveMsg(CMouseDragMoveMsg *msg); + bool MouseDragEndMsg(CMouseDragEndMsg *msg); + bool UseWithCharMsg(CUseWithCharMsg *msg); + bool LeaveViewMsg(CLeaveViewMsg *msg); + bool UseWithOtherMsg(CUseWithOtherMsg *msg); + bool VisibleMsg(CVisibleMsg *msg); + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool RemoveFromGameMsg(CRemoveFromGameMsg *msg); + bool MoveToStartPosMsg(CMoveToStartPosMsg *msg); + bool EnterViewMsg(CEnterViewMsg *msg); + bool PassOnDragStartMsg(CPassOnDragStartMsg *msg); +protected: + CString _string1; + Point _origPos; + CString _fullViewName; + int _fieldDC; + int _fieldE0; + CString _string3; + CString _string4; + Point _tempPos; + int _field100; + int _field104; + int _field108; + int _field10C; + int _itemFrame; + CString _string5; + int _enterFrame; + bool _enterFrameSet; + int _visibleFrame; +public: + CLASSDEF; + CCarry(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CARRY_H */ diff --git a/engines/titanic/carry/carry_parrot.cpp b/engines/titanic/carry/carry_parrot.cpp new file mode 100644 index 0000000000..cf96204122 --- /dev/null +++ b/engines/titanic/carry/carry_parrot.cpp @@ -0,0 +1,237 @@ +/* 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 "titanic/carry/carry_parrot.h" +#include "titanic/core/project_item.h" +#include "titanic/core/room_item.h" +#include "titanic/game/cage.h" +#include "titanic/npcs/parrot.h" +#include "titanic/npcs/succubus.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CCarryParrot, CCarry) + ON_MESSAGE(PETGainedObjectMsg) + ON_MESSAGE(TimerMsg) + ON_MESSAGE(IsParrotPresentMsg) + ON_MESSAGE(LeaveViewMsg) + ON_MESSAGE(MouseDragEndMsg) + ON_MESSAGE(PassOnDragStartMsg) + ON_MESSAGE(PreEnterViewMsg) + ON_MESSAGE(UseWithCharMsg) + ON_MESSAGE(ActMsg) +END_MESSAGE_MAP() + +CCarryParrot::CCarryParrot() : CCarry(), _string6("PerchedParrot"), + _timerId(0), _field13C(0), _field140(false), _field144(10), + _field148(25), _field14C(0), _field150(8) { +} + +void CCarryParrot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string6, indent); + file->writeNumberLine(_timerId, indent); + file->writeNumberLine(_field13C, indent); + file->writeNumberLine(_field140, indent); + + CCarry::save(file, indent); +} + +void CCarryParrot::load(SimpleFile *file) { + file->readNumber(); + _string6 = file->readString(); + _timerId = file->readNumber(); + _field13C = file->readNumber(); + _field140 = file->readNumber(); + + CCarry::load(file); +} + +bool CCarryParrot::PETGainedObjectMsg(CPETGainedObjectMsg *msg) { + CParrot::_v4 = 4; + CActMsg actMsg("Shut"); + actMsg.execute("ParrotCage"); + + return true; +} + +bool CCarryParrot::TimerMsg(CTimerMsg *msg) { + if (CParrot::_v4 == 1 || CParrot::_v4 == 4) { + if (++_field13C >= 30) { + CActMsg actMsg("FreeParrot"); + actMsg.execute(this); + } + } + + return true; +} + +bool CCarryParrot::IsParrotPresentMsg(CIsParrotPresentMsg *msg) { + msg->_value = true; + return true; +} + +bool CCarryParrot::LeaveViewMsg(CLeaveViewMsg *msg) { + if (_visible) { + setVisible(false); + _fieldE0 = 0; + CParrot::_v4 = 2; + } + + return true; +} + +bool CCarryParrot::MouseDragEndMsg(CMouseDragEndMsg *msg) { + stopMovie(); + + if (msg->_mousePos.y >= 360) { + petAddToInventory(); + return true; + } + + if (compareViewNameTo("ParrotLobby.Node 1.N")) { + if (msg->_mousePos.x >= 75 && msg->_mousePos.x <= 565 && + !CParrot::_v2 && !CCage::_v2) { + setVisible(false); + _fieldE0 = 0; + CTreeItem *perchedParrot = findUnder(getRoot(), "PerchedParrot"); + detach(); + addUnder(perchedParrot); + sound8(true); + + CPutParrotBackMsg backMsg(msg->_mousePos.x); + backMsg.execute(perchedParrot); + } else { + setVisible(false); + _fieldE0 = 0; + CParrot::_v4 = 2; + playSound("z#475.wav", 100, 0, 0); + sound8(true); + moveUnder(findRoom()); + + CActMsg actMsg("Shut"); + actMsg.execute("ParrotCage"); + } + } else { + CCharacter *character = static_cast<CCharacter *>(msg->_dropTarget); + if (character) { + CUseWithCharMsg charMsg(character); + charMsg.execute(this, nullptr, 0); + } else { + setVisible(false); + _fieldE0 = 0; + playSound("z#475.wav", 100, 0, 0); + sound8(true); + moveUnder(findRoom()); + } + } + + return true; +} + +bool CCarryParrot::PassOnDragStartMsg(CPassOnDragStartMsg *msg) { + if (CParrot::_v4 != 3) { + moveToView(); + setPosition(Point(0, 0)); + setVisible(true); + playClip("Pick Up", 2); + playClip("Flapping", 1); + + stopTimer(_timerId); + _timerId = addTimer(1000, 1000); + + _field13C = 0; + CParrot::_v4 = 1; + msg->_value3 = 1; + + return CCarry::PassOnDragStartMsg(msg); + } + + CTrueTalkNPC *npc = static_cast<CTrueTalkNPC *>(getRoot()->findByName(_string6)); + if (npc) + startTalking(npc, 0x446BF); + + _fieldE0 = 0; + playSound("z#475.wav", 100, 0, 0); + moveUnder(findRoom()); + msg->_value4 = 1; + + return true; +} + +bool CCarryParrot::PreEnterViewMsg(CPreEnterViewMsg *msg) { + loadSurface(); + CCarryParrot *parrot = static_cast<CCarryParrot *>(getRoot()->findByName("CarryParrot")); + if (parrot) + parrot->_fieldE0 = 0; + + return true; +} + +bool CCarryParrot::UseWithCharMsg(CUseWithCharMsg *msg) { + CSuccUBus *succubus = static_cast<CSuccUBus *>(msg->_character); + if (succubus) + CParrot::_v4 = 3; + + return CCarry::UseWithCharMsg(msg); +} + +bool CCarryParrot::ActMsg(CActMsg *msg) { + if (msg->_action == "FreeParrot" && (CParrot::_v4 == 4 || CParrot::_v4 == 1)) { + CTrueTalkNPC *npc = static_cast<CTrueTalkNPC *>(getRoot()->findByName(_string6)); + if (npc) + startTalking(npc, 0x446BF); + + setVisible(false); + _fieldE0 = 0; + + if (CParrot::_v4 == 4) { + CActMsg actMsg("Shut"); + actMsg.execute("ParrotCage"); + } else { + playSound("z#475.wav", 100, 0, 0); + + if (!_field140) { + CCarry *feathers = static_cast<CCarry *>(getRoot()->findByName("Feathers")); + if (feathers) { + feathers->setVisible(true); + feathers->petAddToInventory(); + } + + _field140 = true; + } + + getPetControl()->removeFromInventory(this); + getPetControl()->setAreaChangeType(1); + moveUnder(getRoom()); + } + + CParrot::_v4 = 2; + stopTimer(_timerId); + _timerId = 0; + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/carry_parrot.h b/engines/titanic/carry/carry_parrot.h new file mode 100644 index 0000000000..2980f26d8a --- /dev/null +++ b/engines/titanic/carry/carry_parrot.h @@ -0,0 +1,70 @@ +/* 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 TITANIC_CARRY_PARROT_H +#define TITANIC_CARRY_PARROT_H + +#include "titanic/carry/carry.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/messages/pet_messages.h" + +namespace Titanic { + +class CCarryParrot : public CCarry { + DECLARE_MESSAGE_MAP; + bool PETGainedObjectMsg(CPETGainedObjectMsg *msg); + bool TimerMsg(CTimerMsg *msg); + bool IsParrotPresentMsg(CIsParrotPresentMsg *msg); + bool LeaveViewMsg(CLeaveViewMsg *msg); + bool MouseDragEndMsg(CMouseDragEndMsg *msg); + bool PassOnDragStartMsg(CPassOnDragStartMsg *msg); + bool PreEnterViewMsg(CPreEnterViewMsg *msg); + bool UseWithCharMsg(CUseWithCharMsg *msg); + bool ActMsg(CActMsg *msg); +private: + CString _string6; + int _timerId; + int _field13C; + bool _field140; + int _field144; + int _field148; + int _field14C; + int _field150; +public: + CLASSDEF; + CCarryParrot(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CARRY_PARROT_H */ diff --git a/engines/titanic/carry/central_core.cpp b/engines/titanic/carry/central_core.cpp new file mode 100644 index 0000000000..a50c95abbc --- /dev/null +++ b/engines/titanic/carry/central_core.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/carry/central_core.h" + +namespace Titanic { + +void CCentralCore::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CBrain::save(file, indent); +} + +void CCentralCore::load(SimpleFile *file) { + file->readNumber(); + CBrain::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/central_core.h b/engines/titanic/carry/central_core.h new file mode 100644 index 0000000000..9d7bef2c13 --- /dev/null +++ b/engines/titanic/carry/central_core.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_CENTRAL_CORE_H +#define TITANIC_CENTRAL_CORE_H + +#include "titanic/carry/brain.h" + +namespace Titanic { + +class CCentralCore : public CBrain { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CENTRAL_CORE_H */ diff --git a/engines/titanic/carry/chicken.cpp b/engines/titanic/carry/chicken.cpp new file mode 100644 index 0000000000..65404dc65d --- /dev/null +++ b/engines/titanic/carry/chicken.cpp @@ -0,0 +1,225 @@ +/* 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 "titanic/carry/chicken.h" +#include "titanic/game/sauce_dispensor.h" +#include "titanic/npcs/succubus.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CChicken, CCarry) + ON_MESSAGE(UseWithCharMsg) + ON_MESSAGE(ActMsg) + ON_MESSAGE(VisibleMsg) + ON_MESSAGE(TimerMsg) + ON_MESSAGE(PETGainedObjectMsg) + ON_MESSAGE(ParrotTriesChickenMsg) + ON_MESSAGE(MouseDragEndMsg) + ON_MESSAGE(PETObjectStateMsg) + ON_MESSAGE(PETLostObjectMsg) +END_MESSAGE_MAP() + +int CChicken::_v1; + +CChicken::CChicken() : CCarry(), _string6("None"), + _field12C(1), _field13C(0), _timerId(0) { +} + +void CChicken::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field12C, indent); + file->writeQuotedLine(_string6, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_field13C, indent); + file->writeNumberLine(_timerId, indent); + + CCarry::save(file, indent); +} + +void CChicken::load(SimpleFile *file) { + file->readNumber(); + _field12C = file->readNumber(); + _string6 = file->readString(); + _v1 = file->readNumber(); + _field13C = file->readNumber(); + _timerId = file->readNumber(); + + CCarry::load(file); +} + +bool CChicken::UseWithOtherMsg(CUseWithOtherMsg *msg) { + if (msg->_other->getName() == "Napkin") { + if (_field12C || _string6 == "None") { + CActMsg actMsg("Clean"); + actMsg.execute(this); + petAddToInventory(); + } else { + CShowTextMsg textMsg("The chicken is already clean."); + textMsg.execute("PET"); + } + + petAddToInventory(); + } else { + CSauceDispensor *dispensor = static_cast<CSauceDispensor *>(msg->_other); + if (!dispensor || _string6 == "None") { + return CCarry::UseWithOtherMsg(msg); + } else { + setVisible(false); + CUse use(this); + use.execute(msg->_other); + } + } + + return true; +} + +bool CChicken::UseWithCharMsg(CUseWithCharMsg *msg) { + CSuccUBus *succubus = static_cast<CSuccUBus *>(msg->_character); + if (succubus) { + setPosition(Point(330, 300)); + CSubAcceptCCarryMsg acceptMsg; + acceptMsg._item = this; + acceptMsg.execute(succubus); + } else { + petAddToInventory(); + } + + return true; +} + +bool CChicken::ActMsg(CActMsg *msg) { + if (msg->_action == "GoToPET") { + setVisible(true); + petAddToInventory(); + } else if (msg->_action == "Tomato") { + _string6 = "Tomato"; + loadFrame(4); + _visibleFrame = 4; + } else if (msg->_action == "Mustard") { + _string6 = "Mustard"; + loadFrame(5); + _visibleFrame = 5; + } else if (msg->_action == "Bird") { + _string6 = "Bird"; + loadFrame(2); + _visibleFrame = 2; + } else if (msg->_action == "None") { + setVisible(false); + } else if (msg->_action == "Clean") { + _string6 = "None"; + loadFrame(3); + _field12C = 0; + _visibleFrame = 3; + } + else if (msg->_action == "Dispense Chicken") { + _string6 = "None"; + _field13C = 0; + _field12C = 1; + loadFrame(1); + _visibleFrame = 1; + _v1 = 120; + } else if (msg->_action == "Hot") { + _v1 = 120; + } else if (msg->_action == "Eaten") { + setVisible(false); + petMoveToHiddenRoom(); + _field13C = 1; + } + + return true; +} + +bool CChicken::VisibleMsg(CVisibleMsg *msg) { + setVisible(msg->_visible); + if (msg->_visible) + loadFrame(_visibleFrame); + + return true; +} + +bool CChicken::TimerMsg(CTimerMsg *msg) { + CGameObject *obj = getMailManFirstObject(); + while (obj && obj->getName() != "Chicken") + obj = getMailManNextObject(obj); + + bool flag = false; + if (obj) { + flag = _v1; + } else if (_v1 > 0) { + --_v1; + flag = _v1; + } + + if (flag) { + petInvChange(); + stopTimer(_timerId); + } + + return true; +} + +bool CChicken::PETGainedObjectMsg(CPETGainedObjectMsg *msg) { + stopTimer(_timerId); + _timerId = addTimer(1000, 1000); + return true; +} + +bool CChicken::ParrotTriesChickenMsg(CParrotTriesChickenMsg *msg) { + if (_v1 > 0) + msg->_value1 = 1; + + if (_string6 == "Tomato") { + msg->_value2 = 1; + } else if (_string6 == "Mustard") { + msg->_value2 = 2; + } else if (_string6 == "Bird") { + msg->_value2 = 3; + } + + return true; +} + +bool CChicken::MouseDragEndMsg(CMouseDragEndMsg *msg) { + if (_field13C) + return true; + else + return CCarry::MouseDragEndMsg(msg); +} + +bool CChicken::PETObjectStateMsg(CPETObjectStateMsg *msg) { + if (_v1 > 0) + msg->_value = 2; + + return true; +} + +bool CChicken::PETLostObjectMsg(CPETLostObjectMsg *msg) { + if (compareViewNameTo("ParrotLobby.Node 1.N")) { + CActMsg actMsg("StartChickenDrag"); + actMsg.execute("PerchedParrot"); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/chicken.h b/engines/titanic/carry/chicken.h new file mode 100644 index 0000000000..65fe30fd81 --- /dev/null +++ b/engines/titanic/carry/chicken.h @@ -0,0 +1,68 @@ +/* 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 TITANIC_CHICKEN_H +#define TITANIC_CHICKEN_H + +#include "titanic/carry/carry.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/pet_messages.h" + +namespace Titanic { + +class CChicken : public CCarry { + DECLARE_MESSAGE_MAP; + bool UseWithOtherMsg(CUseWithOtherMsg *msg); + bool UseWithCharMsg(CUseWithCharMsg *msg); + bool ActMsg(CActMsg *msg); + bool VisibleMsg(CVisibleMsg *msg); + bool TimerMsg(CTimerMsg *msg); + bool PETGainedObjectMsg(CPETGainedObjectMsg *msg); + bool ParrotTriesChickenMsg(CParrotTriesChickenMsg *msg); + bool MouseDragEndMsg(CMouseDragEndMsg *msg); + bool PETObjectStateMsg(CPETObjectStateMsg *msg); + bool PETLostObjectMsg(CPETLostObjectMsg *msg); +private: + static int _v1; +public: + int _field12C; + CString _string6; + int _field13C; + int _timerId; +public: + CLASSDEF; + CChicken(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHICKEN_H */ diff --git a/engines/titanic/carry/crushed_tv.cpp b/engines/titanic/carry/crushed_tv.cpp new file mode 100644 index 0000000000..a265b611a9 --- /dev/null +++ b/engines/titanic/carry/crushed_tv.cpp @@ -0,0 +1,80 @@ +/* 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 "titanic/carry/crushed_tv.h" +#include "titanic/npcs/character.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CCrushedTV, CCarry) + ON_MESSAGE(ActMsg) + ON_MESSAGE(UseWithCharMsg) + ON_MESSAGE(MouseDragStartMsg) +END_MESSAGE_MAP() + +CCrushedTV::CCrushedTV() : CCarry() { +} + +void CCrushedTV::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CCarry::save(file, indent); +} + +void CCrushedTV::load(SimpleFile *file) { + file->readNumber(); + CCarry::load(file); +} + +bool CCrushedTV::ActMsg(CActMsg *msg) { + if (msg->_action == "SmashTV") { + setVisible(true); + _fieldE0 = 1; + } + + return true; +} + +bool CCrushedTV::UseWithCharMsg(CUseWithCharMsg *msg) { + if (msg->_character->getName() == "Barbot" && msg->_character->_visible) { + setVisible(false); + CActMsg actMsg("CrushedTV"); + actMsg.execute(msg->_character); + return true; + } else { + return CCarry::UseWithCharMsg(msg); + } +} + +bool CCrushedTV::MouseDragStartMsg(CMouseDragStartMsg *msg) { + if (!checkStartDragging(msg)) { + return false; + } else if (compareViewNameTo("BottomOfWell.Node 7.N")) { + changeView("BottomOfWell.Node 12.N", ""); + CActMsg actMsg("TelevisionTaken"); + actMsg.execute("BOWTelevisionMonitor"); + } + + return CCarry::MouseDragStartMsg(msg); +} + + +} // End of namespace Titanic diff --git a/engines/titanic/carry/crushed_tv.h b/engines/titanic/carry/crushed_tv.h new file mode 100644 index 0000000000..340930f842 --- /dev/null +++ b/engines/titanic/carry/crushed_tv.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_CRUSHED_TV_H +#define TITANIC_CRUSHED_TV_H + +#include "titanic/carry/carry.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +class CCrushedTV : public CCarry { + DECLARE_MESSAGE_MAP; + bool ActMsg(CActMsg *msg); + bool UseWithCharMsg(CUseWithCharMsg *msg); + bool MouseDragStartMsg(CMouseDragStartMsg *msg); +public: + CLASSDEF; + CCrushedTV(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CRUSHED_TV_H */ diff --git a/engines/titanic/carry/ear.cpp b/engines/titanic/carry/ear.cpp new file mode 100644 index 0000000000..8d85e247f7 --- /dev/null +++ b/engines/titanic/carry/ear.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/carry/ear.h" + +namespace Titanic { + +CEar::CEar() : CHeadPiece() { +} + +void CEar::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CHeadPiece::save(file, indent); +} + +void CEar::load(SimpleFile *file) { + file->readNumber(); + CHeadPiece::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/ear.h b/engines/titanic/carry/ear.h new file mode 100644 index 0000000000..edef873d35 --- /dev/null +++ b/engines/titanic/carry/ear.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_EAR_H +#define TITANIC_EAR_H + +#include "titanic/carry/head_piece.h" + +namespace Titanic { + +class CEar : public CHeadPiece { +public: + CLASSDEF; + CEar(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EAR_H */ diff --git a/engines/titanic/carry/eye.cpp b/engines/titanic/carry/eye.cpp new file mode 100644 index 0000000000..5de1789e54 --- /dev/null +++ b/engines/titanic/carry/eye.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/carry/eye.h" + +namespace Titanic { + +CEye::CEye() : CHeadPiece(), _eyeNum(0) { +} + +void CEye::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_eyeNum, indent); + CHeadPiece::save(file, indent); +} + +void CEye::load(SimpleFile *file) { + file->readNumber(); + _eyeNum = file->readNumber(); + CHeadPiece::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/eye.h b/engines/titanic/carry/eye.h new file mode 100644 index 0000000000..066a85609b --- /dev/null +++ b/engines/titanic/carry/eye.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_EYE_H +#define TITANIC_EYE_H + +#include "titanic/carry/head_piece.h" + +namespace Titanic { + +class CEye : public CHeadPiece { +private: + int _eyeNum; +public: + CLASSDEF; + CEye(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EYE_H */ diff --git a/engines/titanic/carry/feathers.cpp b/engines/titanic/carry/feathers.cpp new file mode 100644 index 0000000000..a5d2babfb1 --- /dev/null +++ b/engines/titanic/carry/feathers.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/carry/feathers.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CFeathers, CCarry); + +CFeathers::CFeathers() : CCarry() { +} + +void CFeathers::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CCarry::save(file, indent); +} + +void CFeathers::load(SimpleFile *file) { + file->readNumber(); + CCarry::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/feathers.h b/engines/titanic/carry/feathers.h new file mode 100644 index 0000000000..7282bcb580 --- /dev/null +++ b/engines/titanic/carry/feathers.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_FEATHERS_H +#define TITANIC_FEATHERS_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CFeathers : public CCarry { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CFeathers(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FEATHERS_H */ diff --git a/engines/titanic/carry/fruit.cpp b/engines/titanic/carry/fruit.cpp new file mode 100644 index 0000000000..832dccf45a --- /dev/null +++ b/engines/titanic/carry/fruit.cpp @@ -0,0 +1,51 @@ +/* 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 "titanic/carry/fruit.h" + +namespace Titanic { + +CFruit::CFruit() : CCarry(), _field12C(0), + _field130(0), _field134(0), _field138(0) { +} + +void CFruit::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field12C, indent); + file->writeNumberLine(_field130, indent); + file->writeNumberLine(_field134, indent); + file->writeNumberLine(_field138, indent); + + CCarry::save(file, indent); +} + +void CFruit::load(SimpleFile *file) { + file->readNumber(); + _field12C = file->readNumber(); + _field130 = file->readNumber(); + _field134 = file->readNumber(); + _field138 = file->readNumber(); + + CCarry::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/fruit.h b/engines/titanic/carry/fruit.h new file mode 100644 index 0000000000..93fe920740 --- /dev/null +++ b/engines/titanic/carry/fruit.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_FRUIT_H +#define TITANIC_FRUIT_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CFruit : public CCarry { +private: + int _field12C; + int _field130; + int _field134; + int _field138; +public: + CLASSDEF; + CFruit(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FRUIT_H */ diff --git a/engines/titanic/carry/glass.cpp b/engines/titanic/carry/glass.cpp new file mode 100644 index 0000000000..051457af03 --- /dev/null +++ b/engines/titanic/carry/glass.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/carry/glass.h" + +namespace Titanic { + +CGlass::CGlass() : CCarry(), _string6("None") { +} + +void CGlass::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string6, indent); + CCarry::save(file, indent); +} + +void CGlass::load(SimpleFile *file) { + file->readNumber(); + _string6 = file->readString(); + CCarry::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/glass.h b/engines/titanic/carry/glass.h new file mode 100644 index 0000000000..9f4056b1be --- /dev/null +++ b/engines/titanic/carry/glass.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_GLASS_H +#define TITANIC_GLASS_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CGlass : public CCarry { +private: + CString _string6; +public: + CLASSDEF; + CGlass(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GLASS_H */ diff --git a/engines/titanic/carry/hammer.cpp b/engines/titanic/carry/hammer.cpp new file mode 100644 index 0000000000..d3b912184c --- /dev/null +++ b/engines/titanic/carry/hammer.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/carry/hammer.h" + +namespace Titanic { + +CHammer::CHammer() : CCarry() { +} + +void CHammer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CCarry::save(file, indent); +} + +void CHammer::load(SimpleFile *file) { + file->readNumber(); + CCarry::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/hammer.h b/engines/titanic/carry/hammer.h new file mode 100644 index 0000000000..a455d71434 --- /dev/null +++ b/engines/titanic/carry/hammer.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_HAMMER_H +#define TITANIC_HAMMER_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CHammer : public CCarry { +public: + CLASSDEF; + CHammer(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HAMMER_H */ diff --git a/engines/titanic/carry/head_piece.cpp b/engines/titanic/carry/head_piece.cpp new file mode 100644 index 0000000000..ae709644a0 --- /dev/null +++ b/engines/titanic/carry/head_piece.cpp @@ -0,0 +1,49 @@ +/* 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 "titanic/carry/head_piece.h" + +namespace Titanic { + +CHeadPiece::CHeadPiece() : CCarry(), _string6("Not Working"), + _field12C(0), _field13C(0) { +} + +void CHeadPiece::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field12C, indent); + file->writeQuotedLine(_string6, indent); + file->writeNumberLine(_field13C, indent); + + CCarry::save(file, indent); +} + +void CHeadPiece::load(SimpleFile *file) { + file->readNumber(); + _field12C = file->readNumber(); + _string6 = file->readString(); + _field13C = file->readNumber(); + + CCarry::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/head_piece.h b/engines/titanic/carry/head_piece.h new file mode 100644 index 0000000000..05ac772853 --- /dev/null +++ b/engines/titanic/carry/head_piece.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_HEAD_PIECE_H +#define TITANIC_HEAD_PIECE_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CHeadPiece : public CCarry { +private: + int _field12C; + CString _string6; + int _field13C; +public: + CLASSDEF; + CHeadPiece(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HEAD_PIECE_H */ diff --git a/engines/titanic/carry/hose.cpp b/engines/titanic/carry/hose.cpp new file mode 100644 index 0000000000..747d58c339 --- /dev/null +++ b/engines/titanic/carry/hose.cpp @@ -0,0 +1,57 @@ +/* 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 "titanic/carry/hose.h" + +namespace Titanic { + +CHoseStatics *CHose::_statics; + +void CHose::init() { + _statics = new CHoseStatics(); +} + +void CHose::deinit() { + delete _statics; +} + +CHose::CHose() : CCarry(), + _string6("Succ-U-Bus auxiliary hose attachment incompatible with sliding glass cover.") { +} + +void CHose::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_statics->_v1, indent); + file->writeQuotedLine(_statics->_v2, indent); + file->writeQuotedLine(_string6, indent); + CCarry::save(file, indent); +} + +void CHose::load(SimpleFile *file) { + file->readNumber(); + _statics->_v1 = file->readNumber(); + _statics->_v2 = file->readString(); + _string6 = file->readString(); + CCarry::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/hose.h b/engines/titanic/carry/hose.h new file mode 100644 index 0000000000..ebd45860e8 --- /dev/null +++ b/engines/titanic/carry/hose.h @@ -0,0 +1,59 @@ +/* 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 TITANIC_HOSE_H +#define TITANIC_HOSE_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +struct CHoseStatics { + int _v1; + CString _v2; +}; + +class CHose : public CCarry { +protected: + static CHoseStatics *_statics; + + CString _string6; +public: + CLASSDEF; + CHose(); + static void init(); + static void deinit(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HOSE_H */ diff --git a/engines/titanic/carry/hose_end.cpp b/engines/titanic/carry/hose_end.cpp new file mode 100644 index 0000000000..c9996437bb --- /dev/null +++ b/engines/titanic/carry/hose_end.cpp @@ -0,0 +1,45 @@ +/* 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 "titanic/carry/hose_end.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CHoseEnd, CHose); + +CHoseEnd::CHoseEnd() : CHose() { + _string6 = "Connection refused by remote hose."; +} + +void CHoseEnd::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string6, indent); + CHose::save(file, indent); +} + +void CHoseEnd::load(SimpleFile *file) { + file->readNumber(); + _string6 = file->readString(); + CHose::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/hose_end.h b/engines/titanic/carry/hose_end.h new file mode 100644 index 0000000000..836c94456a --- /dev/null +++ b/engines/titanic/carry/hose_end.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_HOSE_END_H +#define TITANIC_HOSE_END_H + +#include "titanic/carry/hose.h" + +namespace Titanic { + +class CHoseEnd : public CHose { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CHoseEnd(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HOSE_END_H */ diff --git a/engines/titanic/carry/key.cpp b/engines/titanic/carry/key.cpp new file mode 100644 index 0000000000..6e947464f1 --- /dev/null +++ b/engines/titanic/carry/key.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/carry/key.h" + +namespace Titanic { + +CKey::CKey() : CCarry() { +} + +void CKey::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CCarry::save(file, indent); +} + +void CKey::load(SimpleFile *file) { + file->readNumber(); + CCarry::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/key.h b/engines/titanic/carry/key.h new file mode 100644 index 0000000000..8f1600f2b3 --- /dev/null +++ b/engines/titanic/carry/key.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_KEY_H +#define TITANIC_KEY_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CKey : public CCarry { +public: + CLASSDEF; + CKey(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_KEY_H */ diff --git a/engines/titanic/carry/liftbot_head.cpp b/engines/titanic/carry/liftbot_head.cpp new file mode 100644 index 0000000000..bcab8e8574 --- /dev/null +++ b/engines/titanic/carry/liftbot_head.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/carry/liftbot_head.h" + +namespace Titanic { + +CLiftbotHead::CLiftbotHead() : CCarry(), _field12C(0) { +} + +void CLiftbotHead::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field12C, indent); + CCarry::save(file, indent); +} + +void CLiftbotHead::load(SimpleFile *file) { + file->readNumber(); + _field12C = file->readNumber(); + CCarry::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/liftbot_head.h b/engines/titanic/carry/liftbot_head.h new file mode 100644 index 0000000000..2fcd6a71f9 --- /dev/null +++ b/engines/titanic/carry/liftbot_head.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_LIFTBOT_HEAD_H +#define TITANIC_LIFTBOT_HEAD_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CLiftbotHead : public CCarry { +private: + int _field12C; +public: + CLASSDEF; + CLiftbotHead(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LIFTBOT_HEAD_H */ diff --git a/engines/titanic/carry/long_stick.cpp b/engines/titanic/carry/long_stick.cpp new file mode 100644 index 0000000000..ab1e42b81f --- /dev/null +++ b/engines/titanic/carry/long_stick.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/carry/long_stick.h" + +namespace Titanic { + +CLongStick::CLongStick() : CCarry() { +} + +void CLongStick::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CCarry::save(file, indent); +} + +void CLongStick::load(SimpleFile *file) { + file->readNumber(); + CCarry::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/long_stick.h b/engines/titanic/carry/long_stick.h new file mode 100644 index 0000000000..2ff5b7228e --- /dev/null +++ b/engines/titanic/carry/long_stick.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_LONG_STICK_H +#define TITANIC_LONG_STICK_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CLongStick : public CCarry { +public: + CLASSDEF; + CLongStick(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LONG_STICK_H */ diff --git a/engines/titanic/carry/magazine.cpp b/engines/titanic/carry/magazine.cpp new file mode 100644 index 0000000000..cdf92fc707 --- /dev/null +++ b/engines/titanic/carry/magazine.cpp @@ -0,0 +1,93 @@ +/* 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 "titanic/carry/magazine.h" +#include "titanic/npcs/deskbot.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CMagazine, CCarry) + ON_MESSAGE(UseWithCharMsg) + ON_MESSAGE(MouseDoubleClickMsg) + ON_MESSAGE(VisibleMsg) + ON_MESSAGE(UseWithOtherMsg) +END_MESSAGE_MAP() + +CMagazine::CMagazine() : CCarry() { +} + +void CMagazine::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field12C, indent); + file->writeNumberLine(_field130, indent); + + CCarry::save(file, indent); +} + +void CMagazine::load(SimpleFile *file) { + file->readNumber(); + _field12C = file->readNumber(); + _field130 = file->readNumber(); + + CCarry::load(file); +} + +bool CMagazine::UseWithCharMsg(CUseWithCharMsg *msg) { + CDeskbot *deskbot = static_cast<CDeskbot *>(msg->_character); + if (deskbot) { + if (deskbot->_deskbotActive) { + setVisible(false); + setPosition(Point(1000, 1000)); + CActMsg actMsg("2ndClassUpgrade"); + actMsg.execute("Deskbot"); + } + + return true; + } else { + return CCarry::UseWithCharMsg(msg); + } +} + +bool CMagazine::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { + return true; +} + +bool CMagazine::VisibleMsg(CVisibleMsg *msg) { + setVisible(msg->_visible); + return true; +} + +bool CMagazine::UseWithOtherMsg(CUseWithOtherMsg *msg) { + if (msg->_other->getName() == "SwitchOnDeskbot") { + // TODO: other _field108 if + if (false) { + setVisible(false); + setPosition(Point(1000, 1000)); + CActMsg actMsg("2ndClassUpgrade"); + actMsg.execute("Deskbot"); + } + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/magazine.h b/engines/titanic/carry/magazine.h new file mode 100644 index 0000000000..d1db4689ba --- /dev/null +++ b/engines/titanic/carry/magazine.h @@ -0,0 +1,58 @@ +/* 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 TITANIC_MAGAZINE_H +#define TITANIC_MAGAZINE_H + +#include "titanic/carry/carry.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +class CMagazine : public CCarry { + DECLARE_MESSAGE_MAP; + bool UseWithCharMsg(CUseWithCharMsg *msg); + bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg); + bool VisibleMsg(CVisibleMsg *msg); + bool UseWithOtherMsg(CUseWithOtherMsg *msg); +private: + int _field12C; + int _field130; +public: + CLASSDEF; + CMagazine(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MAGAZINE_H */ diff --git a/engines/titanic/carry/maitred_left_arm.cpp b/engines/titanic/carry/maitred_left_arm.cpp new file mode 100644 index 0000000000..b31c2a6f6d --- /dev/null +++ b/engines/titanic/carry/maitred_left_arm.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/carry/maitred_left_arm.h" + +namespace Titanic { + +void CMaitreDLeftArm::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field174, indent); + CArm::save(file, indent); +} + +void CMaitreDLeftArm::load(SimpleFile *file) { + file->readNumber(); + _field174 = file->readNumber(); + CArm::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/maitred_left_arm.h b/engines/titanic/carry/maitred_left_arm.h new file mode 100644 index 0000000000..8f5090b073 --- /dev/null +++ b/engines/titanic/carry/maitred_left_arm.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_LEFT_ARM_H +#define TITANIC_LEFT_ARM_H + +#include "titanic/carry/arm.h" + +namespace Titanic { + +class CMaitreDLeftArm : public CArm { +private: + int _field174; +public: + CLASSDEF; + CMaitreDLeftArm() : CArm(), _field174(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LEFT_ARM_H */ diff --git a/engines/titanic/carry/maitred_right_arm.cpp b/engines/titanic/carry/maitred_right_arm.cpp new file mode 100644 index 0000000000..7030e83c9d --- /dev/null +++ b/engines/titanic/carry/maitred_right_arm.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/carry/maitred_right_arm.h" + +namespace Titanic { + +void CMaitreDRightArm::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CArm::save(file, indent); +} + +void CMaitreDRightArm::load(SimpleFile *file) { + file->readNumber(); + CArm::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/maitred_right_arm.h b/engines/titanic/carry/maitred_right_arm.h new file mode 100644 index 0000000000..ce07ed7af4 --- /dev/null +++ b/engines/titanic/carry/maitred_right_arm.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_MAITRED_RIGHT_ARM_H +#define TITANIC_MAITRED_RIGHT_ARM_H + +#include "titanic/carry/arm.h" + +namespace Titanic { + +class CMaitreDRightArm : public CArm { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MAITRED_RIGHT_ARM_H */ diff --git a/engines/titanic/carry/mouth.cpp b/engines/titanic/carry/mouth.cpp new file mode 100644 index 0000000000..8c3791fa9c --- /dev/null +++ b/engines/titanic/carry/mouth.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/carry/mouth.h" + +namespace Titanic { + +CMouth::CMouth() : CHeadPiece() { +} + +void CMouth::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CHeadPiece::save(file, indent); +} + +void CMouth::load(SimpleFile *file) { + file->readNumber(); + CHeadPiece::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/mouth.h b/engines/titanic/carry/mouth.h new file mode 100644 index 0000000000..e394330494 --- /dev/null +++ b/engines/titanic/carry/mouth.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_MOUTH_H +#define TITANIC_MOUTH_H + +#include "titanic/carry/head_piece.h" + +namespace Titanic { + +class CMouth : public CHeadPiece { +public: + CLASSDEF; + CMouth(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOUTH_H */ diff --git a/engines/titanic/carry/napkin.cpp b/engines/titanic/carry/napkin.cpp new file mode 100644 index 0000000000..ace5a389a0 --- /dev/null +++ b/engines/titanic/carry/napkin.cpp @@ -0,0 +1,61 @@ +/* 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 "titanic/carry/napkin.h" +#include "titanic/carry/chicken.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CNapkin, CCarry) + ON_MESSAGE(UseWithOtherMsg) +END_MESSAGE_MAP() + +CNapkin::CNapkin() : CCarry() { +} + +void CNapkin::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CCarry::save(file, indent); +} + +void CNapkin::load(SimpleFile *file) { + file->readNumber(); + CCarry::load(file); +} + +bool CNapkin::UseWithOtherMsg(CUseWithOtherMsg *msg) { + CChicken *chicken = static_cast<CChicken *>(msg->_other); + if (chicken) { + if (chicken->_string6 == "None" || chicken->_field12C) { + CActMsg actMsg("Clean"); + actMsg.execute("Chicken"); + } else { + petDisplayMessage("The Chicken is already quite clean enough, thank you."); + } + } + + petAddToInventory(); + return CCarry::UseWithOtherMsg(msg); +} + + +} // End of namespace Titanic diff --git a/engines/titanic/carry/napkin.h b/engines/titanic/carry/napkin.h new file mode 100644 index 0000000000..ce47dd6059 --- /dev/null +++ b/engines/titanic/carry/napkin.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_NAPKIN_H +#define TITANIC_NAPKIN_H + +#include "titanic/carry/carry.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CNapkin : public CCarry { + DECLARE_MESSAGE_MAP; + bool UseWithOtherMsg(CUseWithOtherMsg *msg); +public: + CLASSDEF; + CNapkin(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NAPKIN_H */ diff --git a/engines/titanic/carry/nose.cpp b/engines/titanic/carry/nose.cpp new file mode 100644 index 0000000000..4f3afe24ac --- /dev/null +++ b/engines/titanic/carry/nose.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/carry/nose.h" + +namespace Titanic { + +CNose::CNose() : CHeadPiece() { +} + +void CNose::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CHeadPiece::save(file, indent); +} + +void CNose::load(SimpleFile *file) { + file->readNumber(); + CHeadPiece::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/nose.h b/engines/titanic/carry/nose.h new file mode 100644 index 0000000000..b688da231a --- /dev/null +++ b/engines/titanic/carry/nose.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_NOSE_H +#define TITANIC_NOSE_H + +#include "titanic/carry/head_piece.h" + +namespace Titanic { + +class CNose : public CHeadPiece { +public: + CLASSDEF; + CNose(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NOSE_H */ diff --git a/engines/titanic/carry/note.cpp b/engines/titanic/carry/note.cpp new file mode 100644 index 0000000000..388f87e638 --- /dev/null +++ b/engines/titanic/carry/note.cpp @@ -0,0 +1,54 @@ +/* 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 "titanic/carry/note.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CNote, CCarry) + ON_MESSAGE(MouseDoubleClickMsg) +END_MESSAGE_MAP() + +CNote::CNote() : CCarry(), _field138(1) { +} + +void CNote::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string6, indent); + file->writeNumberLine(_field138, indent); + + CCarry::save(file, indent); +} + +void CNote::load(SimpleFile *file) { + file->readNumber(); + _string6 = file->readString(); + _field138 = file->readNumber(); + + CCarry::load(file); +} + +bool CNote::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/note.h b/engines/titanic/carry/note.h new file mode 100644 index 0000000000..37ebf96d72 --- /dev/null +++ b/engines/titanic/carry/note.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_NOTE_H +#define TITANIC_NOTE_H + +#include "titanic/carry/carry.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CNote : public CCarry { + DECLARE_MESSAGE_MAP; + bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg); +private: + CString _string6; + int _field138; +public: + CLASSDEF; + CNote(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NOTE_H */ diff --git a/engines/titanic/carry/parcel.cpp b/engines/titanic/carry/parcel.cpp new file mode 100644 index 0000000000..2ffe8b0aac --- /dev/null +++ b/engines/titanic/carry/parcel.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/carry/parcel.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CParcel, CCarry); + +CParcel::CParcel() : CCarry() { +} + +void CParcel::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CCarry::save(file, indent); +} + +void CParcel::load(SimpleFile *file) { + file->readNumber(); + CCarry::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/parcel.h b/engines/titanic/carry/parcel.h new file mode 100644 index 0000000000..f33c2ff65a --- /dev/null +++ b/engines/titanic/carry/parcel.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_PARCEL_H +#define TITANIC_PARCEL_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CParcel : public CCarry { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CParcel(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARCEL_H */ diff --git a/engines/titanic/carry/perch.cpp b/engines/titanic/carry/perch.cpp new file mode 100644 index 0000000000..281b3fce53 --- /dev/null +++ b/engines/titanic/carry/perch.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/carry/perch.h" + +namespace Titanic { + +void CPerch::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CCentralCore::save(file, indent); +} + +void CPerch::load(SimpleFile *file) { + file->readNumber(); + CCentralCore::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/perch.h b/engines/titanic/carry/perch.h new file mode 100644 index 0000000000..d23868d909 --- /dev/null +++ b/engines/titanic/carry/perch.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PERCH_H +#define TITANIC_PERCH_H + +#include "titanic/carry/central_core.h" + +namespace Titanic { + +class CPerch : public CCentralCore { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PERCH_H */ diff --git a/engines/titanic/carry/phonograph_cylinder.cpp b/engines/titanic/carry/phonograph_cylinder.cpp new file mode 100644 index 0000000000..0684c56611 --- /dev/null +++ b/engines/titanic/carry/phonograph_cylinder.cpp @@ -0,0 +1,178 @@ +/* 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 "titanic/carry/phonograph_cylinder.h" +#include "titanic/game/phonograph.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CPhonographCylinder, CCarry) + ON_MESSAGE(UseWithOtherMsg) + ON_MESSAGE(QueryCylinderMsg) + ON_MESSAGE(RecordOntoCylinderMsg) + ON_MESSAGE(SetMusicControlsMsg) + ON_MESSAGE(ErasePhonographCylinderMsg) +END_MESSAGE_MAP() + +CPhonographCylinder::CPhonographCylinder() : CCarry(), + _bellsMuteControl(false), _bellsPitchControl(false), + _bellsSpeedControl(false), _bellsDirectionControl(false), + _bellsInversionControl(false), _snakeMuteControl(false), + _snakeSpeedControl(false), _snakePitchControl(false), + _snakeInversionControl(false), _snakeDirectionControl(false), + _pianoMuteControl(false), _pianoSpeedControl(false), + _pianoPitchControl(false), _pianoInversionControl(false), + _pianoDirectionControl(false), _bassMuteControl(false), + _bassSpeedControl(false), _bassPitchControl(false), + _bassInversionControl(false) { +} + +void CPhonographCylinder::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_itemName, indent); + file->writeNumberLine(_bellsMuteControl, indent); + file->writeNumberLine(_bellsPitchControl, indent); + file->writeNumberLine(_bellsSpeedControl, indent); + file->writeNumberLine(_bellsDirectionControl, indent); + file->writeNumberLine(_bellsInversionControl, indent); + file->writeNumberLine(_snakeMuteControl, indent); + file->writeNumberLine(_snakeSpeedControl, indent); + file->writeNumberLine(_snakePitchControl, indent); + file->writeNumberLine(_snakeInversionControl, indent); + file->writeNumberLine(_snakeDirectionControl, indent); + file->writeNumberLine(_pianoMuteControl, indent); + file->writeNumberLine(_pianoSpeedControl, indent); + file->writeNumberLine(_pianoPitchControl, indent); + file->writeNumberLine(_pianoInversionControl, indent); + file->writeNumberLine(_pianoDirectionControl, indent); + file->writeNumberLine(_bassMuteControl, indent); + file->writeNumberLine(_bassSpeedControl, indent); + file->writeNumberLine(_bassPitchControl, indent); + file->writeNumberLine(_bassInversionControl, indent); + file->writeNumberLine(_bassDirectionControl, indent); + + CCarry::save(file, indent); +} + +void CPhonographCylinder::load(SimpleFile *file) { + file->readNumber(); + _itemName = file->readString(); + _bellsMuteControl = file->readNumber(); + _bellsPitchControl = file->readNumber(); + _bellsSpeedControl = file->readNumber(); + _bellsDirectionControl = file->readNumber(); + _bellsInversionControl = file->readNumber(); + _snakeMuteControl = file->readNumber(); + _snakeSpeedControl = file->readNumber(); + _snakePitchControl = file->readNumber(); + _snakeInversionControl = file->readNumber(); + _snakeDirectionControl = file->readNumber(); + _pianoMuteControl = file->readNumber(); + _pianoSpeedControl = file->readNumber(); + _pianoPitchControl = file->readNumber(); + _pianoInversionControl = file->readNumber(); + _pianoDirectionControl = file->readNumber(); + _bassMuteControl = file->readNumber(); + _bassSpeedControl = file->readNumber(); + _bassPitchControl = file->readNumber(); + _bassInversionControl = file->readNumber(); + _bassDirectionControl = file->readNumber(); + + CCarry::load(file); +} + +bool CPhonographCylinder::UseWithOtherMsg(CUseWithOtherMsg *msg) { + CPhonograph *phonograph = static_cast<CPhonograph *>(msg->_other); + if (phonograph) { + CSetVarMsg varMsg("m_RecordStatus", 1); + return true; + } else { + return CCarry::UseWithOtherMsg(msg); + } +} + +bool CPhonographCylinder::QueryCylinderMsg(CQueryCylinderMsg *msg) { + msg->_name = _itemName; + return true; +} + +bool CPhonographCylinder::RecordOntoCylinderMsg(CRecordOntoCylinderMsg *msg) { + _itemName = "STMusic"; + + CQueryMusicControlSettingMsg queryMsg; + queryMsg.execute("Bells Mute Control"); + _bellsMuteControl = queryMsg._value; + queryMsg.execute("Bells Pitch Control"); + _bellsPitchControl = queryMsg._value; + queryMsg.execute("Bells Speed Control"); + _bellsSpeedControl = queryMsg._value; + queryMsg.execute("Bells Direction Control"); + _bellsDirectionControl = queryMsg._value; + queryMsg.execute("Bells Inversion Control"); + _bellsInversionControl = queryMsg._value; + queryMsg.execute("Snake Mute Control"); + _snakeMuteControl = queryMsg._value; + queryMsg.execute("Snake Speed Control"); + _snakeSpeedControl = queryMsg._value; + queryMsg.execute("Snake Pitch Control"); + _snakePitchControl = queryMsg._value; + queryMsg.execute("Snake Inversion Control"); + _snakeInversionControl = queryMsg._value; + queryMsg.execute("Snake Direction Control"); + _snakeDirectionControl = queryMsg._value; + queryMsg.execute("Piano Mute Control"); + _pianoMuteControl = queryMsg._value; + queryMsg.execute("Piano Speed Control"); + _pianoSpeedControl = queryMsg._value; + queryMsg.execute("Piano Pitch Control"); + _pianoPitchControl = queryMsg._value; + queryMsg.execute("Piano Inversion Control"); + _pianoInversionControl = queryMsg._value; + queryMsg.execute("Piano Direction Control"); + _pianoDirectionControl = queryMsg._value; + queryMsg.execute("Bass Mute Control"); + _bassMuteControl = queryMsg._value; + queryMsg.execute("Bass Speed Control"); + _bassSpeedControl = queryMsg._value; + queryMsg.execute("Bass Pitch Control"); + _bassPitchControl = queryMsg._value; + queryMsg.execute("Bass Inversion Control"); + _bassInversionControl = queryMsg._value; + + return true; +} + +bool CPhonographCylinder::SetMusicControlsMsg(CSetMusicControlsMsg *msg) { + if (_itemName.left(7) == "STMusic") { + //todo + warning("TODO"); + } + + return true; +} + +bool CPhonographCylinder::ErasePhonographCylinderMsg(CErasePhonographCylinderMsg *msg) { + _itemName.clear(); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/phonograph_cylinder.h b/engines/titanic/carry/phonograph_cylinder.h new file mode 100644 index 0000000000..bbb1524cb5 --- /dev/null +++ b/engines/titanic/carry/phonograph_cylinder.h @@ -0,0 +1,76 @@ +/* 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 TITANIC_PHONOGRAPH_CYLINDER_H +#define TITANIC_PHONOGRAPH_CYLINDER_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CPhonographCylinder : public CCarry { + DECLARE_MESSAGE_MAP; + bool UseWithOtherMsg(CUseWithOtherMsg *msg); + bool QueryCylinderMsg(CQueryCylinderMsg *msg); + bool RecordOntoCylinderMsg(CRecordOntoCylinderMsg *msg); + bool SetMusicControlsMsg(CSetMusicControlsMsg *msg); + bool ErasePhonographCylinderMsg(CErasePhonographCylinderMsg *msg); +private: + CString _itemName; + bool _bellsMuteControl; + bool _bellsPitchControl; + bool _bellsSpeedControl; + bool _bellsDirectionControl; + bool _bellsInversionControl; + bool _snakeMuteControl; + bool _snakeSpeedControl; + bool _snakePitchControl; + bool _snakeInversionControl; + bool _snakeDirectionControl; + bool _pianoMuteControl; + bool _pianoSpeedControl; + bool _pianoPitchControl; + bool _pianoInversionControl; + bool _pianoDirectionControl; + bool _bassMuteControl; + bool _bassSpeedControl; + bool _bassPitchControl; + bool _bassInversionControl; + bool _bassDirectionControl; +public: + CLASSDEF; + CPhonographCylinder(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PHONOGRAPH_CYLINDER_H */ diff --git a/engines/titanic/carry/phonograph_ear.cpp b/engines/titanic/carry/phonograph_ear.cpp new file mode 100644 index 0000000000..ceb71babd2 --- /dev/null +++ b/engines/titanic/carry/phonograph_ear.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/carry/phonograph_ear.h" + +namespace Titanic { + +void CPhonographEar::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field140, indent); + CEar::save(file, indent); +} + +void CPhonographEar::load(SimpleFile *file) { + file->readNumber(); + _field140 = file->readNumber(); + CEar::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/phonograph_ear.h b/engines/titanic/carry/phonograph_ear.h new file mode 100644 index 0000000000..582db9f7ef --- /dev/null +++ b/engines/titanic/carry/phonograph_ear.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PHONOGRAPH_EAR_H +#define TITANIC_PHONOGRAPH_EAR_H + +#include "titanic/carry/ear.h" + +namespace Titanic { + +class CPhonographEar : public CEar { +private: + int _field140; +public: + CLASSDEF; + CPhonographEar() : CEar(), _field140(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PHONOGRAPH_EYE_H */ diff --git a/engines/titanic/carry/photograph.cpp b/engines/titanic/carry/photograph.cpp new file mode 100644 index 0000000000..7f32a0623d --- /dev/null +++ b/engines/titanic/carry/photograph.cpp @@ -0,0 +1,98 @@ +/* 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 "titanic/carry/photograph.h" +#include "titanic/core/room_item.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CPhotograph, CCarry) + ON_MESSAGE(MouseDragStartMsg) + ON_MESSAGE(MouseDragEndMsg) + ON_MESSAGE(PETGainedObjectMsg) + ON_MESSAGE(ActMsg) +END_MESSAGE_MAP() + +int CPhotograph::_v1; + +CPhotograph::CPhotograph() : CCarry(), _field12C(0), _field130(0) { +} + +void CPhotograph::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field12C, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_field130, indent); + + CCarry::save(file, indent); +} + +void CPhotograph::load(SimpleFile *file) { + file->readNumber(); + _field12C = file->readNumber(); + _v1 = file->readNumber(); + _field130 = file->readNumber(); + + CCarry::load(file); +} + +bool CPhotograph::MouseDragEndMsg(CMouseDragEndMsg *msg) { + _v1 = 0; + CGameObject *target = msg->_dropTarget; + + if (target && target->getName() != "NavigationComputer") { + warning("TODO: CPhotograph::MouseDragEndMsg"); + return true; + } else { + return CCarry::MouseDragEndMsg(msg); + } +} + +bool CPhotograph::MouseDragStartMsg(CMouseDragStartMsg *msg) { + if (checkPoint(msg->_mousePos, true, true)) { + _v1 = true; + CActMsg actMsg("PlayerPicksUpPhoto"); + actMsg.execute("Doorbot"); + } + + return CCarry::MouseDragStartMsg(msg); +} + +bool CPhotograph::PETGainedObjectMsg(CPETGainedObjectMsg *msg) { + if (getRoom()->getName() == "Home") { + CActMsg actMsg("PlayerPutsPhotoInPET"); + actMsg.execute("Doorbot"); + } + + return true; +} + +bool CPhotograph::ActMsg(CActMsg *msg) { + if (msg->_action == "BecomeGettable") { + _fieldE0 = 1; + _cursorId = CURSOR_HAND; + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/photograph.h b/engines/titanic/carry/photograph.h new file mode 100644 index 0000000000..9cea1e4799 --- /dev/null +++ b/engines/titanic/carry/photograph.h @@ -0,0 +1,61 @@ +/* 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 TITANIC_PHOTOGRAPH_H +#define TITANIC_PHOTOGRAPH_H + +#include "titanic/carry/carry.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/messages/pet_messages.h" + +namespace Titanic { + +class CPhotograph : public CCarry { + DECLARE_MESSAGE_MAP; + bool MouseDragEndMsg(CMouseDragEndMsg *msg); + bool MouseDragStartMsg(CMouseDragStartMsg *msg); + bool PETGainedObjectMsg(CPETGainedObjectMsg *msg); + bool ActMsg(CActMsg *msg); +private: + static int _v1; +private: + int _field12C; + int _field130; +public: + CLASSDEF; + CPhotograph(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PHOTOGRAPH_H */ diff --git a/engines/titanic/carry/plug_in.cpp b/engines/titanic/carry/plug_in.cpp new file mode 100644 index 0000000000..c82a4cc422 --- /dev/null +++ b/engines/titanic/carry/plug_in.cpp @@ -0,0 +1,68 @@ +/* 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 "titanic/carry/plug_in.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CPlugIn, CCarry) + ON_MESSAGE(UseWithOtherMsg) +END_MESSAGE_MAP() + +CPlugIn::CPlugIn() : CCarry(), _field12C(0) { +} + +void CPlugIn::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CCarry::save(file, indent); +} + +void CPlugIn::load(SimpleFile *file) { + file->readNumber(); + CCarry::load(file); +} + +bool CPlugIn::UseWithOtherMsg(CUseWithOtherMsg *msg) { + CGameObject *other = msg->_other; + CString otherName = other->getName(); + + if (otherName == "PET") { + return CCarry::UseWithOtherMsg(msg); + } else if (otherName == "DatasideTransporter") { + CString name = getName(); + if (name == "DatasideTransporter") { + // TODO + if (name != "SendYourself") { + // TODO + } + } else { + // TODO + } + } else { + CShowTextMsg textMsg("This item is incorrectly calibrated."); + textMsg.execute("PET"); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/plug_in.h b/engines/titanic/carry/plug_in.h new file mode 100644 index 0000000000..1358a99e39 --- /dev/null +++ b/engines/titanic/carry/plug_in.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_PLUG_IN_H +#define TITANIC_PLUG_IN_H + +#include "titanic/carry/carry.h" + +namespace Titanic { + +class CPlugIn : public CCarry { + DECLARE_MESSAGE_MAP; + bool UseWithOtherMsg(CUseWithOtherMsg *msg); +private: + int _field12C; +public: + CLASSDEF; + CPlugIn(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PLUG_IN_H */ diff --git a/engines/titanic/carry/speech_centre.cpp b/engines/titanic/carry/speech_centre.cpp new file mode 100644 index 0000000000..b8076aee76 --- /dev/null +++ b/engines/titanic/carry/speech_centre.cpp @@ -0,0 +1,45 @@ +/* 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 "titanic/carry/speech_centre.h" + +namespace Titanic { + +void CSpeechCentre::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field13C, indent); + file->writeQuotedLine(_string1, indent); + file->writeNumberLine(_field14C, indent); + + CBrain::save(file, indent); +} + +void CSpeechCentre::load(SimpleFile *file) { + file->readNumber(); + _field13C = file->readNumber(); + _string1 = file->readString(); + _field14C = file->readNumber(); + + CBrain::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/speech_centre.h b/engines/titanic/carry/speech_centre.h new file mode 100644 index 0000000000..50f47e9c8a --- /dev/null +++ b/engines/titanic/carry/speech_centre.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_SPEECH_CENTRE_H +#define TITANIC_SPEECH_CENTRE_H + +#include "titanic/carry/brain.h" + +namespace Titanic { + +class CSpeechCentre : public CBrain { +private: + int _field13C; + CString _string1; + int _field14C; +public: + CLASSDEF; + CSpeechCentre() : CBrain(), _string1("Summer"), + _field13C(1), _field14C(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SPEECH_CENTRE_H */ diff --git a/engines/titanic/carry/sweets.cpp b/engines/titanic/carry/sweets.cpp new file mode 100644 index 0000000000..f19a8287b7 --- /dev/null +++ b/engines/titanic/carry/sweets.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/carry/sweets.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CSweets, CCarry) + ON_MESSAGE(MouseButtonUpMsg) +END_MESSAGE_MAP() + +CSweets::CSweets() : CCarry() { +} + +void CSweets::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CCarry::save(file, indent); +} + +void CSweets::load(SimpleFile *file) { + file->readNumber(); + CCarry::load(file); +} + +bool CSweets::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/sweets.h b/engines/titanic/carry/sweets.h new file mode 100644 index 0000000000..3655fabfb9 --- /dev/null +++ b/engines/titanic/carry/sweets.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_SWEETS_H +#define TITANIC_SWEETS_H + +#include "titanic/carry/carry.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +class CSweets : public CCarry { + DECLARE_MESSAGE_MAP; + bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); +public: + CLASSDEF; + CSweets(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SWEETS_H */ diff --git a/engines/titanic/carry/vision_centre.cpp b/engines/titanic/carry/vision_centre.cpp new file mode 100644 index 0000000000..8c8bab15f8 --- /dev/null +++ b/engines/titanic/carry/vision_centre.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/carry/vision_centre.h" + +namespace Titanic { + +void CVisionCentre::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CBrain::save(file, indent); +} + +void CVisionCentre::load(SimpleFile *file) { + file->readNumber(); + CBrain::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/carry/vision_centre.h b/engines/titanic/carry/vision_centre.h new file mode 100644 index 0000000000..6cf8e2c653 --- /dev/null +++ b/engines/titanic/carry/vision_centre.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_VISION_CENTRE_H +#define TITANIC_VISION_CENTRE_H + +#include "titanic/carry/brain.h" + +namespace Titanic { + +class CVisionCentre : public CBrain { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_VISION_CENTRE_H */ diff --git a/engines/titanic/configure.engine b/engines/titanic/configure.engine new file mode 100644 index 0000000000..daf4e6b388 --- /dev/null +++ b/engines/titanic/configure.engine @@ -0,0 +1,3 @@ +# This file is included from the main "configure" script +# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] +add_engine titanic "Starship Titanic" no "" "" "16bit jpeg highres" diff --git a/engines/titanic/continue_save_dialog.cpp b/engines/titanic/continue_save_dialog.cpp new file mode 100644 index 0000000000..39b7d1942a --- /dev/null +++ b/engines/titanic/continue_save_dialog.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 "titanic/continue_save_dialog.h" +#include "titanic/titanic.h" + +namespace Titanic { + +#define SAVEGAME_SLOTS_COUNT 5 +#define RESTORE_X 346 +#define RESTORE_Y 94 +#define START_X 370 +#define START_Y 276 + +CContinueSaveDialog::CContinueSaveDialog() { + g_vm->_events->addTarget(this); + _highlightedSlot = _selectedSlot = -999; + _restoreState = _startState = -1; + _mouseDown = false; + _evilTwinShown = false; + + for (int idx = 0; idx < SAVEGAME_SLOTS_COUNT; ++idx) { + Rect slotRect = getSlotBounds(idx); + _slotNames[idx].setFontNumber(0); + _slotNames[idx].setBounds(slotRect); + _slotNames[idx].resize(3); + _slotNames[idx].setMaxCharsPerLine(22); + _slotNames[idx].setHasBorder(false); + _slotNames[idx].setup(); + } +} + +CContinueSaveDialog::~CContinueSaveDialog() { + g_vm->_events->removeTarget(); +} + +void CContinueSaveDialog::addSavegame(int slot, const CString &name) { + assert(_saves.size() < SAVEGAME_SLOTS_COUNT); + _slotNames[_saves.size()].setText(name); + _saves.push_back(SaveEntry(slot, name)); +} + +Rect CContinueSaveDialog::getSlotBounds(int index) { + return Rect(360, 164 + index * 19, 556, 180 + index * 19); +} + +int CContinueSaveDialog::show() { + // Load images for the dialog + loadImages(); + + // Render the view + render(); + + // Event loop waiting for selection + while (!g_vm->shouldQuit() && _selectedSlot == -999) { + g_vm->_events->pollEventsAndWait(); + } + + return _selectedSlot; +} + +void CContinueSaveDialog::loadImages() { + _backdrop.load("Bitmap/BACKDROP"); + _evilTwin.load("Bitmap/EVILTWIN"); + _restoreD.load("Bitmap/RESTORED"); + _restoreU.load("Bitmap/RESTOREU"); + _restoreF.load("Bitmap/RESTOREF"); + _startD.load("Bitmap/STARTD"); + _startU.load("Bitmap/STARTU"); + _startF.load("Bitmap/STARTF"); +} + +void CContinueSaveDialog::render() { + Graphics::Screen &screen = *g_vm->_screen; + screen.clear(); + screen.blitFrom(_backdrop, Common::Point(48, 22)); + + if (_evilTwinShown) + screen.blitFrom(_evilTwin, Common::Point(78, 59)); + + _restoreState = _startState = -1; + renderButtons(); + renderSlots(); +} + +void CContinueSaveDialog::renderButtons() { + Graphics::Screen &screen = *g_vm->_screen; + Rect restoreRect(RESTORE_X, RESTORE_Y, RESTORE_X + _restoreU.w, RESTORE_Y + _restoreU.h); + Rect startRect(START_X, START_Y, START_X + _startU.w, START_Y + _startU.h); + + // Determine the current state for the buttons + int restoreState, startState; + if (!restoreRect.contains(_mousePos)) + restoreState = 0; + else + restoreState = _mouseDown ? 1 : 2; + + if (!startRect.contains(_mousePos)) + startState = 0; + else + startState = _mouseDown ? 1 : 2; + + // Draw the start button + if (startState != _startState) { + _startState = startState; + switch (_startState) { + case 0: + screen.blitFrom(_startU, Common::Point(START_X, START_Y)); + break; + case 1: + screen.blitFrom(_startD, Common::Point(START_X, START_Y)); + break; + case 2: + screen.blitFrom(_startF, Common::Point(START_X, START_Y)); + break; + default: + break; + } + } + + // Draw the restore button + if (restoreState != _restoreState) { + _restoreState = restoreState; + switch (_restoreState) { + case 0: + screen.blitFrom(_restoreU, Common::Point(RESTORE_X, RESTORE_Y)); + break; + case 1: + screen.blitFrom(_restoreD, Common::Point(RESTORE_X, RESTORE_Y)); + break; + case 2: + screen.blitFrom(_restoreF, Common::Point(RESTORE_X, RESTORE_Y)); + break; + default: + break; + } + } +} + +void CContinueSaveDialog::renderSlots() { + for (int idx = 0; idx < (int)_saves.size(); ++idx) { + byte rgb = (_highlightedSlot == idx) ? 255 : 0; + _slotNames[idx].setColor(rgb, rgb, rgb); + _slotNames[idx].setLineColor(0, rgb, rgb, rgb); + _slotNames[idx].draw(CScreenManager::_screenManagerPtr); + } +} + +void CContinueSaveDialog::mouseMove(const Point &mousePos) { + _mousePos = mousePos; + renderButtons(); +} + +void CContinueSaveDialog::leftButtonDown(const Point &mousePos) { + _mouseDown = true; + mouseMove(mousePos); +} + +void CContinueSaveDialog::leftButtonUp(const Point &mousePos) { + Rect restoreRect(RESTORE_X, RESTORE_Y, RESTORE_X + _restoreU.w, RESTORE_Y + _restoreU.h); + Rect startRect(START_X, START_Y, START_X + _startU.w, START_Y + _startU.h); + _mouseDown = false; + + if (restoreRect.contains(mousePos)) { + // Flag to exit dialog and load highlighted slot. If no slot was + // selected explicitly, then fall back on loading the first slot + _selectedSlot = (_highlightedSlot == -999) ? _saves[0]._slot : + _saves[_highlightedSlot]._slot; + } else if (startRect.contains(mousePos)) { + // Start a new game + _selectedSlot = -1; + } else { + // Check whether a filled in slot was selected + for (uint idx = 0; idx < _saves.size(); ++idx) { + if (getSlotBounds(idx).contains(mousePos)) { + _highlightedSlot = idx; + render(); + break; + } + } + } +} + +void CContinueSaveDialog::rightButtonDown(const Point &mousePos) { + Rect eye1(188, 190, 192, 195), eye2(209, 192, 213, 197); + + if (eye1.contains(mousePos) || eye2.contains(mousePos)) { + _evilTwinShown = true; + render(); + } +} + +void CContinueSaveDialog::rightButtonUp(const Point &mousePos) { + if (_evilTwinShown) { + _evilTwinShown = false; + render(); + } +} + +void CContinueSaveDialog::keyDown(Common::KeyState keyState) { + if (keyState.keycode == Common::KEYCODE_ESCAPE) + _selectedSlot = EXIT_GAME; +} + +} // End of namespace Titanic diff --git a/engines/titanic/continue_save_dialog.h b/engines/titanic/continue_save_dialog.h new file mode 100644 index 0000000000..58c7deef00 --- /dev/null +++ b/engines/titanic/continue_save_dialog.h @@ -0,0 +1,105 @@ +/* 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 TITANIC_CONTINUE_SAVE_DIALOG_H +#define TITANIC_CONTINUE_SAVE_DIALOG_H + +#include "common/array.h" +#include "titanic/events.h" +#include "titanic/support/image.h" +#include "titanic/support/rect.h" +#include "titanic/support/string.h" +#include "titanic/pet_control/pet_text.h" + +namespace Titanic { + +#define EXIT_GAME -2 + +class CContinueSaveDialog : public CEventTarget { + struct SaveEntry { + int _slot; + CString _name; + SaveEntry() : _slot(0) {} + SaveEntry(int slot, const CString &name) : _slot(slot), _name(name) {} + }; +private: + Common::Array<SaveEntry> _saves; + CPetText _slotNames[5]; + int _highlightedSlot, _selectedSlot; + Point _mousePos; + bool _evilTwinShown; + bool _mouseDown; + int _restoreState, _startState; + Image _backdrop; + Image _evilTwin; + Image _restoreD, _restoreU, _restoreF; + Image _startD, _startU, _startF; +private: + /** + * Load the images + */ + void loadImages(); + + /** + * Render the dialog + */ + void render(); + + /** + * Render the buttons + */ + void renderButtons(); + + /** + * Render the slots + */ + void renderSlots(); + + /** + * Get the area to draw a slot name in + */ + Rect getSlotBounds(int index); +public: + CContinueSaveDialog(); + virtual ~CContinueSaveDialog(); + + virtual void mouseMove(const Point &mousePos); + virtual void leftButtonDown(const Point &mousePos); + virtual void leftButtonUp(const Point &mousePos); + virtual void rightButtonDown(const Point &mousePos); + virtual void rightButtonUp(const Point &mousePos); + virtual void keyDown(Common::KeyState keyState); + + /** + * Add a savegame to the list to be displayed + */ + void addSavegame(int slot, const CString &name); + + /** + * Show the dialog and wait for a slot to be selected + */ + int show(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CONTINUE_SAVE_DIALOG_H */ diff --git a/engines/titanic/core/background.cpp b/engines/titanic/core/background.cpp new file mode 100644 index 0000000000..733dfc1cf3 --- /dev/null +++ b/engines/titanic/core/background.cpp @@ -0,0 +1,78 @@ +/* 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 "titanic/core/background.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CBackground, CGameObject) + ON_MESSAGE(StatusChangeMsg) + ON_MESSAGE(SetFrameMsg) + ON_MESSAGE(VisibleMsg) +END_MESSAGE_MAP() + +CBackground::CBackground() : CGameObject(), _startFrame(0), _endFrame(0), _fieldDC(0) { +} + +void CBackground::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_startFrame, indent); + file->writeNumberLine(_endFrame, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_fieldDC, indent); + + CGameObject::save(file, indent); +} + +void CBackground::load(SimpleFile *file) { + file->readNumber(); + _startFrame = file->readNumber(); + _endFrame = file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + _fieldDC = file->readNumber(); + + CGameObject::load(file); +} + +bool CBackground::StatusChangeMsg(CStatusChangeMsg *msg) { + setVisible(true); + if (_fieldDC) { + playMovie(_startFrame, _endFrame, 16); + } else { + playMovie(_startFrame, _endFrame, 0); + } + return true; +} + +bool CBackground::SetFrameMsg(CSetFrameMsg *msg) { + loadFrame(msg->_frameNumber); + return true; +} + +bool CBackground::VisibleMsg(CVisibleMsg *msg) { + setVisible(msg->_visible); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/background.h b/engines/titanic/core/background.h new file mode 100644 index 0000000000..b7f160db28 --- /dev/null +++ b/engines/titanic/core/background.h @@ -0,0 +1,59 @@ +/* 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 TITANIC_BACKGROUND_H +#define TITANIC_BACKGROUND_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CBackground : public CGameObject { + DECLARE_MESSAGE_MAP; + bool StatusChangeMsg(CStatusChangeMsg *msg); + bool SetFrameMsg(CSetFrameMsg *msg); + bool VisibleMsg(CVisibleMsg *msg); +protected: + int _startFrame; + int _endFrame; + CString _string1; + CString _string2; + int _fieldDC; +public: + CLASSDEF; + CBackground(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BACKGROUND_H */ diff --git a/engines/titanic/core/click_responder.cpp b/engines/titanic/core/click_responder.cpp new file mode 100644 index 0000000000..f9694557df --- /dev/null +++ b/engines/titanic/core/click_responder.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/core/click_responder.h" + +namespace Titanic { + +void CClickResponder::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + + CGameObject::save(file, indent); +} + +void CClickResponder::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/click_responder.h b/engines/titanic/core/click_responder.h new file mode 100644 index 0000000000..78381b9948 --- /dev/null +++ b/engines/titanic/core/click_responder.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_CLICK_RESPONDER_H +#define TITANIC_CLICK_RESPONDER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CClickResponder : public CGameObject { +protected: + CString _string1, _string2; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CLICK_RESPONDER_H */ diff --git a/engines/titanic/core/dont_save_file_item.cpp b/engines/titanic/core/dont_save_file_item.cpp new file mode 100644 index 0000000000..b8864bb2b5 --- /dev/null +++ b/engines/titanic/core/dont_save_file_item.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/core/dont_save_file_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CDontSaveFileItem, CFileItem); + +void CDontSaveFileItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); +} + +void CDontSaveFileItem::load(SimpleFile *file) { + file->readNumber(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/dont_save_file_item.h b/engines/titanic/core/dont_save_file_item.h new file mode 100644 index 0000000000..f5ec4f791d --- /dev/null +++ b/engines/titanic/core/dont_save_file_item.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_DONT_SAVE_FILE_ITEM_H +#define TITANIC_DONT_SAVE_FILE_ITEM_H + +#include "titanic/core/file_item.h" + +namespace Titanic { + +class CDontSaveFileItem : public CFileItem { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DONT_SAVE_FILE_ITEM_H */ diff --git a/engines/titanic/core/drop_target.cpp b/engines/titanic/core/drop_target.cpp new file mode 100644 index 0000000000..05ea6445c3 --- /dev/null +++ b/engines/titanic/core/drop_target.cpp @@ -0,0 +1,72 @@ +/* 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 "titanic/core/drop_target.h" + +namespace Titanic { + +CDropTarget::CDropTarget() : CGameObject(), _fieldC4(0), + _fieldD4(0), _fieldE4(0), _fieldF4(0), _fieldF8(0), + _fieldFC(0), _field10C(1), _field110(8), _field114(20) { +} + +void CDropTarget::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writePoint(_pos1, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeQuotedLine(_string1, indent); + file->writeNumberLine(_fieldD4, indent); + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeQuotedLine(_string3, indent); + file->writeNumberLine(_fieldF4, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_fieldFC, indent); + file->writeQuotedLine(_string4, indent); + file->writeNumberLine(_field10C, indent); + file->writeNumberLine(_field110, indent); + file->writeNumberLine(_field114, indent); + + CGameObject::save(file, indent); +} + +void CDropTarget::load(SimpleFile *file) { + file->readNumber(); + _pos1 = file->readPoint(); + _fieldC4 = file->readNumber(); + _string1 = file->readString(); + _fieldD4 = file->readNumber(); + _string2 = file->readString(); + _fieldE4 = file->readNumber(); + _string3 = file->readString(); + _fieldF4 = file->readNumber(); + _fieldF8 = file->readNumber(); + _fieldFC = file->readNumber(); + _string4 = file->readString(); + _field10C = file->readNumber(); + _field110 = file->readNumber(); + _field114 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/drop_target.h b/engines/titanic/core/drop_target.h new file mode 100644 index 0000000000..4bd0ae448c --- /dev/null +++ b/engines/titanic/core/drop_target.h @@ -0,0 +1,63 @@ +/* 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 TITANIC_DROP_TARGET_H +#define TITANIC_DROP_TARGET_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CDropTarget : public CGameObject { +private: + Point _pos1; + int _fieldC4; + CString _string1; + int _fieldD4; + CString _string2; + int _fieldE4; + CString _string3; + int _fieldF4; + int _fieldF8; + int _fieldFC; + CString _string4; + int _field10C; + int _field110; + int _field114; +public: + CLASSDEF; + CDropTarget(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DROP_TARGET_H */ diff --git a/engines/titanic/core/file_item.cpp b/engines/titanic/core/file_item.cpp new file mode 100644 index 0000000000..b783c758df --- /dev/null +++ b/engines/titanic/core/file_item.cpp @@ -0,0 +1,49 @@ +/* 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 "titanic/core/file_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CFileItem, CTreeItem); + +void CFileItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + CTreeItem::save(file, indent); +} + +void CFileItem::load(SimpleFile *file) { + file->readNumber(); + + CTreeItem::load(file); +} + +CString CFileItem::formFilename() const { + return ""; +} + +CString CFileItem::getFilename() const { + //dynamic_cast<CFileItem *>(getRoot())->formDataPath(); + return _filename; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/file_item.h b/engines/titanic/core/file_item.h new file mode 100644 index 0000000000..4cecee4882 --- /dev/null +++ b/engines/titanic/core/file_item.h @@ -0,0 +1,67 @@ +/* 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 TITANIC_FILE_ITEM_H +#define TITANIC_FILE_ITEM_H + +#include "titanic/support/string.h" +#include "titanic/core/list.h" +#include "titanic/core/tree_item.h" + +namespace Titanic { + +class CFileItem: public CTreeItem { + DECLARE_MESSAGE_MAP; +private: + CString _filename; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Returns true if the item is a file item + */ + virtual bool isFileItem() const { return true; } + + /** + * Form a filename for the file item + */ + CString formFilename() const; + + /** + * Get a string? + */ + CString getFilename() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FILE_ITEM_H */ diff --git a/engines/titanic/core/game_object.cpp b/engines/titanic/core/game_object.cpp new file mode 100644 index 0000000000..723f2456f3 --- /dev/null +++ b/engines/titanic/core/game_object.cpp @@ -0,0 +1,1668 @@ +/* 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 "titanic/core/game_object.h" +#include "titanic/core/mail_man.h" +#include "titanic/core/resource_key.h" +#include "titanic/core/room_item.h" +#include "titanic/npcs/true_talk_npc.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/star_control/star_control.h" +#include "titanic/support/files_manager.h" +#include "titanic/support/screen_manager.h" +#include "titanic/support/video_surface.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CGameObject, CNamedItem); + +CCreditText *CGameObject::_credits; +int CGameObject::_soundHandles[4]; + +void CGameObject::init() { + _credits = nullptr; + _soundHandles[0] = _soundHandles[1] = 0; + _soundHandles[2] = _soundHandles[3] = -1; +} + +void CGameObject::deinit() { + if (_credits) { + _credits->clear(); + delete _credits; + _credits = nullptr; + } +} + +CGameObject::CGameObject(): CNamedItem() { + _bounds = Rect(0, 0, 15, 15); + _field34 = 0; + _field38 = 0; + _field3C = 0; + _field40 = 0; + _field44 = 0xF0; + _field48 = 0xF0; + _field4C = 0xFF; + _isMail = false; + _id = 0; + _roomFlags = 0; + _visible = true; + _field60 = 0; + _cursorId = CURSOR_ARROW; + _initialFrame = 0; + _frameNumber = -1; + _text = nullptr; + _textBorder = _textBorderRight = 0; + _field9C = 0; + _surface = nullptr; + _fieldB8 = 0; +} + +CGameObject::~CGameObject() { + delete _surface; + delete _text; +} + +void CGameObject::save(SimpleFile *file, int indent) { + file->writeNumberLine(7, indent); + _movieRangeInfoList.destroyContents(); + + if (_surface) { + const CMovieRangeInfoList *rangeList = _surface->getMovieRangeInfo(); + + if (rangeList) { + for (CMovieRangeInfoList::const_iterator i = rangeList->begin(); + i != rangeList->end(); ++i) { + CMovieRangeInfo *rangeInfo = new CMovieRangeInfo(*i); + rangeInfo->_initialFrame = (i == rangeList->begin()) ? getMovieFrame() : -1; + } + } + } + + _movieRangeInfoList.save(file, indent); + _movieRangeInfoList.destroyContents(); + + file->writeNumberLine(getMovieFrame(), indent + 1); + file->writeNumberLine(_cursorId, indent + 1); + _movieClips.save(file, indent + 1); + file->writeNumberLine(_field60, indent + 1); + file->writeNumberLine(_field40, indent + 1); + file->writeQuotedLine(_resource, indent + 1); + file->writeBounds(_bounds, indent + 1); + + file->writeFloatLine(_field34, indent + 1); + file->writeFloatLine(_field38, indent + 1); + file->writeFloatLine(_field3C, indent + 1); + + file->writeNumberLine(_field44, indent + 1); + file->writeNumberLine(_field48, indent + 1); + file->writeNumberLine(_field4C, indent + 1); + file->writeNumberLine(_fieldB8, indent + 1); + file->writeNumberLine(_visible, indent + 1); + file->writeNumberLine(_isMail, indent + 1); + file->writeNumberLine(_id, indent + 1); + file->writeNumberLine(_roomFlags, indent + 1); + + if (_surface) { + _surface->_resourceKey.save(file, indent); + } else { + CResourceKey resourceKey; + resourceKey.save(file, indent); + } + file->writeNumberLine(_surface != nullptr, indent); + + CNamedItem::save(file, indent); +} + +void CGameObject::load(SimpleFile *file) { + int val = file->readNumber(); + CResourceKey resourceKey; + + switch (val) { + case 7: + _movieRangeInfoList.load(file); + _frameNumber = file->readNumber(); + // Deliberate fall-through + + case 6: + _cursorId = (CursorId)file->readNumber(); + // Deliberate fall-through + + case 5: + _movieClips.load(file); + // Deliberate fall-through + + case 4: + _field60 = file->readNumber(); + // Deliberate fall-through + + case 3: + _field40 = file->readNumber(); + // Deliberate fall-through + + case 2: + _resource = file->readString(); + // Deliberate fall-through + + case 1: + _bounds = file->readBounds(); + _field34 = file->readFloat(); + _field38 = file->readFloat(); + _field3C = file->readFloat(); + _field44 = file->readNumber(); + _field48 = file->readNumber(); + _field4C = file->readNumber(); + _fieldB8 = file->readNumber(); + _visible = file->readNumber() != 0; + _isMail = file->readNumber(); + _id = file->readNumber(); + _roomFlags = file->readNumber(); + + resourceKey.load(file); + _surface = nullptr; + val = file->readNumber(); + if (val) { + _resource = resourceKey.getString(); + } + break; + + default: + break; + } + + CNamedItem::load(file); +} + +void CGameObject::draw(CScreenManager *screenManager) { + if (!_visible) + return; + if (_credits && _credits->_objectP == this) { + if (!_credits->draw()) + CGameObject::deinit(); + + return; + } + + if (_field40) { + // If a text object is defined, handle drawing it + if (_text && _bounds.intersects(getGameManager()->_bounds)) + _text->draw(screenManager); + + return; + } else { + if (!_surface) { + if (!_resource.empty()) { + loadResource(_resource); + _resource = ""; + } + } + + if (_surface) { + _bounds.setWidth(_surface->getWidth()); + _bounds.setHeight(_surface->getHeight()); + + if (!_bounds.width() || !_bounds.height()) + return; + + if (_frameNumber >= 0) { + loadFrame(_frameNumber); + _frameNumber = -1; + } + + if (!_movieRangeInfoList.empty()) + processMoveRangeInfo(); + + if (_bounds.intersects(getGameManager()->_bounds)) { + if (_surface) { + Point destPos(_bounds.left, _bounds.top); + screenManager->blitFrom(SURFACE_BACKBUFFER, _surface, &destPos); + } + + if (_text) + _text->draw(screenManager); + } + } + } +} + +Rect CGameObject::getBounds() const { + return (_surface && _surface->hasFrame()) ? _bounds : Rect(); +} + +void CGameObject::viewChange() { + // Handle freeing the surfaces of objects when their view is left + if (_surface) { + _resource = _surface->_resourceKey.getString(); + _initialFrame = getMovieFrame(); + + delete _surface; + _surface = nullptr; + } +} + +void CGameObject::stopMovie() { + if (_surface) + _surface->stopMovie(); +} + +bool CGameObject::checkPoint(const Point &pt, bool ignore40, bool visibleOnly) { + if ((!_visible && visibleOnly) || !_bounds.contains(pt)) + return false; + + if (ignore40 || _field40) + return true; + + if (!_surface) { + if (_frameNumber == -1) + return true; + loadFrame(_frameNumber); + if (!_surface) + return true; + } + + Common::Point pixelPos = pt - _bounds; + if (_surface->_transBlitFlag) { + pixelPos.y = ((_bounds.height() - _bounds.top) / 2) * 2 - pixelPos.y; + } + + uint transColor = _surface->getTransparencyColor(); + uint pixel = _surface->getPixel(pixelPos); + return pixel != transColor; +} + +bool CGameObject::clipRect(const Rect &rect1, Rect &rect2) const { + if (!rect2.intersects(rect1)) + return false; + + rect2.clip(rect1); + return true; +} + +void CGameObject::draw(CScreenManager *screenManager, const Rect &destRect, const Rect &srcRect) { + Rect tempRect = destRect; + if (clipRect(srcRect, tempRect)) { + if (!_surface && !_resource.empty()) { + loadResource(_resource); + _resource.clear(); + } + + if (_surface) + screenManager->blitFrom(SURFACE_PRIMARY, &tempRect, _surface); + } +} + +void CGameObject::draw(CScreenManager *screenManager, const Point &destPos) { + if (!_surface && !_resource.empty()) { + loadResource(_resource); + _resource.clear(); + } + + if (_surface) { + int xSize = _surface->getWidth(); + int ySize = _surface->getHeight(); + + if (xSize > 0 && ySize > 0) { + screenManager->blitFrom(SURFACE_BACKBUFFER, _surface, &destPos); + } + } +} + +void CGameObject::draw(CScreenManager *screenManager, const Point &destPos, const Rect &srcRect) { + draw(screenManager, Rect(destPos.x, destPos.y, destPos.x + 52, destPos.y + 52), srcRect); +} + +bool CGameObject::isPet() const { + return isInstanceOf(CPetControl::_type); +} + +void CGameObject::loadResource(const CString &name) { + switch (name.fileTypeSuffix()) { + case FILETYPE_IMAGE: + loadImage(name); + break; + case FILETYPE_MOVIE: + loadMovie(name); + break; + default: + break; + } +} + +void CGameObject::loadMovie(const CString &name, bool pendingFlag) { + g_vm->_filesManager->preload(name); + + // Create the surface if it doesn't already exist + if (!_surface) { + CGameManager *gameManager = getGameManager(); + _surface = new OSVideoSurface(gameManager->setScreenManager(), nullptr); + } + + // Load the new movie resource + CResourceKey key(name); + _surface->loadResource(key); + + if (_surface->hasSurface() && !pendingFlag) { + _bounds.setWidth(_surface->getWidth()); + _bounds.setHeight(_surface->getHeight()); + } + + if (_initialFrame) + loadFrame(_initialFrame); +} + +void CGameObject::loadImage(const CString &name, bool pendingFlag) { + // Get a refernce to the game and screen managers + CGameManager *gameManager = getGameManager(); + CScreenManager *screenManager; + + if (gameManager && (screenManager = CScreenManager::setCurrent()) != nullptr) { + // Destroy the object's surface if it already had one + if (_surface) { + delete _surface; + _surface = nullptr; + } + + g_vm->_filesManager->preload(name); + + if (!name.empty()) { + _surface = new OSVideoSurface(screenManager, CResourceKey(name), pendingFlag); + } + + if (_surface && !pendingFlag) { + _bounds.right = _surface->getWidth(); + _bounds.bottom = _surface->getHeight(); + } + + // Mark the object's area as dirty, so that on the next frame rendering + // this object will be redrawn + makeDirty(); + } + + _initialFrame = 0; +} + +void CGameObject::loadFrame(int frameNumber) { + if (frameNumber != -1 && !_resource.empty()) + loadResource(_resource); + + if (_surface) + _surface->setMovieFrame(frameNumber); + + makeDirty(); +} + +void CGameObject::processMoveRangeInfo() { + for (CMovieRangeInfoList::iterator i = _movieRangeInfoList.begin(); i != _movieRangeInfoList.end(); ++i) + (*i)->process(this); + + _movieRangeInfoList.destroyContents(); +} + +void CGameObject::makeDirty(const Rect &r) { + CGameManager *gameManager = getGameManager(); + if (gameManager) + gameManager->extendBounds(r); +} + +void CGameObject::makeDirty() { + makeDirty(_bounds); +} + +bool CGameObject::isSoundActive(int handle) const { + if (handle != 0 && handle != -1) { + CGameManager *gameManager = getGameManager(); + if (gameManager) + return gameManager->_sound.isActive(handle); + } + + return false; +} + +void CGameObject::playGlobalSound(const CString &resName, int mode, bool initialMute, bool repeated, int handleIndex) { + if (handleIndex < 0 || handleIndex > 3) + return; + CGameManager *gameManager = getGameManager(); + if (!gameManager) + return; + + // Preload the file, and stop any existing sound using the given slot + CSound &sound = gameManager->_sound; + g_vm->_filesManager->preload(resName); + if (_soundHandles[handleIndex] != -1) { + sound.stopSound(_soundHandles[handleIndex]); + _soundHandles[handleIndex] = -1; + } + + // If no new name specified, then exit + if (resName.empty()) + return; + + uint newVolume = sound._soundManager.getModeVolume(mode); + uint volume = initialMute ? 0 : newVolume; + + CProximity prox; + prox._channelVolume = volume; + prox._repeated = repeated; + + switch (handleIndex) { + case 0: + prox._channel = 6; + break; + case 1: + prox._channel = 7; + break; + case 2: + prox._channel = 8; + break; + case 3: + prox._channel = 9; + break; + default: + break; + } + + _soundHandles[handleIndex] = sound.playSound(resName, prox); + + if (_soundHandles[handleIndex]) + sound.setVolume(_soundHandles[handleIndex], newVolume, 2); +} + +void CGameObject::setSoundVolume(int handle, uint percent, uint seconds) { + if (handle != 0 && handle != -1) { + CGameManager *gameManager = getGameManager(); + if (gameManager) + return gameManager->_sound.setVolume(handle, percent, seconds); + } +} + +void CGameObject::stopGlobalSound(bool transition, int handleIndex) { + CGameManager *gameManager = getGameManager(); + if (!gameManager) + return; + CSound &sound = gameManager->_sound; + + if (handleIndex == -1) { + for (int idx = 0; idx < 4; ++idx) { + if (_soundHandles[idx] != -1) { + sound.setVolume(_soundHandles[idx], 0, transition ? 1 : 0); + sound.setCanFree(_soundHandles[idx]); + _soundHandles[idx] = -1; + } + } + } else if (handleIndex >= 0 && handleIndex <= 2 && _soundHandles[handleIndex] != -1) { + if (transition) { + // Transitioning to silent over 1 second + sound.setVolume(_soundHandles[handleIndex], 0, 1); + sleep(1000); + } + + sound.stopSound(_soundHandles[handleIndex]); + _soundHandles[handleIndex] = -1; + } + warning("CGameObject::soundFn4"); +} + +void CGameObject::setGlobalSoundVolume(int mode, uint seconds, int handleIndex) { + CGameManager *gameManager = getGameManager(); + if (!gameManager) + return; + CSound &sound = gameManager->_sound; + + if (handleIndex == -1) { + // Iterate through calling the method for each handle + for (int idx = 0; idx < 3; ++idx) + setGlobalSoundVolume(mode, seconds, idx); + } else if (handleIndex >= 0 && handleIndex <= 3 && _soundHandles[handleIndex] != -1) { + uint newVolume = sound._soundManager.getModeVolume(mode); + sound.setVolume(_soundHandles[handleIndex], newVolume, seconds); + } +} + +void CGameObject::sound8(bool flag) const { + getGameManager()->_sound.stopChannel(flag ? 3 : 0); +} + +void CGameObject::setVisible(bool val) { + if (val != _visible) { + _visible = val; + makeDirty(); + } +} + +void CGameObject::petHighlightGlyph(int val) { + CPetControl *pet = getPetControl(); + if (pet) + pet->highlightGlyph(val); +} + +void CGameObject::petHideCursor() { + CPetControl *pet = getPetControl(); + if (pet) + pet->hideCursor(); +} + +void CGameObject::petShowCursor() { + CPetControl *pet = getPetControl(); + if (pet) + pet->showCursor(); +} + +void CGameObject::petShow() { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + gameManager->_gameState._petActive = true; + gameManager->_gameState.setMode(GSMODE_INTERACTIVE); + gameManager->initBounds(); + } +} + +void CGameObject::petHide() { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + gameManager->_gameState._petActive = false; + gameManager->_gameState.setMode(GSMODE_INTERACTIVE); + gameManager->initBounds(); + } +} + +void CGameObject::petSetRemoteTarget() { + CPetControl *pet = getPetControl(); + if (pet) + pet->setRemoteTarget(this); +} + +void CGameObject::playMovie(uint flags) { + _frameNumber = -1; + + if (!_surface && !_resource.empty()) { + loadResource(_resource); + _resource.clear(); + } + + CGameObject *obj = (flags & MOVIE_NOTIFY_OBJECT) ? this : nullptr; + if (_surface) { + _surface->playMovie(flags, obj); + if (flags & MOVIE_GAMESTATE) + getGameManager()->_gameState.addMovie(_surface->_movie); + } +} + +void CGameObject::playMovie(int startFrame, int endFrame, uint flags) { + _frameNumber = -1; + + if (!_surface) { + if (!_resource.empty()) + loadResource(_resource); + _resource.clear(); + } + + CGameObject *obj = (flags & MOVIE_NOTIFY_OBJECT) ? this : nullptr; + if (_surface) { + _surface->playMovie(startFrame, endFrame, flags, obj); + if (flags & MOVIE_GAMESTATE) + getGameManager()->_gameState.addMovie(_surface->_movie); + } +} + + +void CGameObject::playMovie(int startFrame, int endFrame, int initialFrame, uint flags) { + _frameNumber = -1; + + if (!_surface) { + if (!_resource.empty()) + loadResource(_resource); + _resource.clear(); + } + + CGameObject *obj = (flags & MOVIE_NOTIFY_OBJECT) ? this : nullptr; + if (_surface) { + _surface->playMovie(startFrame, endFrame, initialFrame, flags, obj); + if (flags & MOVIE_GAMESTATE) + getGameManager()->_gameState.addMovie(_surface->_movie); + } +} + +void CGameObject::playClip(const CString &name, uint flags) { + _frameNumber = -1; + CMovieClip *clip = _movieClips.findByName(name); + if (clip) + playMovie(clip->_startFrame, clip->_endFrame, flags); +} + +void CGameObject::playClip(uint startFrame, uint endFrame) { + CMovieClip *clip = new CMovieClip("", startFrame, endFrame); + CGameManager *gameManager = getGameManager(); + CRoomItem *room = gameManager->getRoom(); + + gameManager->playClip(clip, room, room); +} + +void CGameObject::playRandomClip(const char **names, uint flags) { + // Count size of array + int count = 0; + for (const char **p = names; *p; ++p) + ++count; + + // Play clip + const char *name = names[g_vm->getRandomNumber(count - 1)]; + playClip(name, flags); +} + +void CGameObject::savePosition() { + _savedPos = _bounds; +} + +void CGameObject::resetPosition() { + setPosition(_savedPos); +} + +void CGameObject::setPosition(const Point &newPos) { + makeDirty(); + _bounds.moveTo(newPos); + makeDirty(); +} + +bool CGameObject::checkStartDragging(CMouseDragStartMsg *msg) { + if (_visible && checkPoint(msg->_mousePos, msg->_handled, 1)) { + savePosition(); + msg->_dragItem = this; + return true; + } else { + return false; + } +} + +bool CGameObject::hasActiveMovie() const { + if (_surface && _surface->_movie) + return _surface->_movie->isActive(); + return false; +} + +int CGameObject::getMovieFrame() const { + if (_surface && _surface->_movie) + return _surface->_movie->getFrame(); + return _initialFrame; +} + +bool CGameObject::surfaceHasFrame() const { + return _surface ? _surface->hasFrame() : false; +} + +void CGameObject::loadSound(const CString &name) { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + g_vm->_filesManager->preload(name); + if (!name.empty()) + gameManager->_sound.loadSound(name); + } +} + +int CGameObject::playSound(const CString &name, uint volume, int val3, bool repeated) { + CProximity prox; + prox._channelVolume = volume; + prox._fieldC = val3; + prox._repeated = repeated; + return playSound(name, prox); +} + +int CGameObject::playSound(const CString &name, CProximity &prox) { + if (prox._positioningMode == POSMODE_VECTOR) { + // If the proximity doesn't have a position defined, default it to + // the position of the view to which the game object belongs + if (prox._posX == 0.0 && prox._posY == 0.0 && prox._posZ == 0.0) + findView()->getPosition(prox._posX, prox._posY, prox._posZ); + } + + CGameManager *gameManager = getGameManager(); + if (gameManager) { + g_vm->_filesManager->preload(name); + + gameManager->_sound.playSound(name, prox); + } + + return 0; +} + +int CGameObject::queueSound(const CString &name, uint priorHandle, uint volume, int val3, bool repeated) { + CProximity prox; + prox._fieldC = val3; + prox._repeated = repeated; + prox._channelVolume = volume; + prox._priorSoundHandle = priorHandle; + + return playSound(name, prox); +} + +void CGameObject::stopSound(int handle, uint seconds) { + if (handle != 0 && handle != -1) { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + if (seconds) { + gameManager->_sound.setVolume(handle, 0, seconds); + gameManager->_sound.setCanFree(handle); + } else { + gameManager->_sound.stopSound(handle); + } + } + } +} + +int CGameObject::addTimer(int endVal, uint firstDuration, uint repeatDuration) { + CTimeEventInfo *timer = new CTimeEventInfo(g_vm->_events->getTicksCount(), + repeatDuration != 0, firstDuration, repeatDuration, this, endVal, CString()); + + getGameManager()->addTimer(timer); + return timer->_id; +} + +int CGameObject::addTimer(uint firstDuration, uint repeatDuration) { + CTimeEventInfo *timer = new CTimeEventInfo(g_vm->_events->getTicksCount(), + repeatDuration != 0, firstDuration, repeatDuration, this, 0, CString()); + + getGameManager()->addTimer(timer); + return timer->_id; +} + +int CGameObject::startAnimTimer(const CString &action, uint firstDuration, uint repeatDuration) { + CTimeEventInfo *timer = new CTimeEventInfo(g_vm->_events->getTicksCount(), + repeatDuration > 0, firstDuration, repeatDuration, this, 0, action); + getGameManager()->addTimer(timer); + + return timer->_id; +} + +void CGameObject::stopTimer(int id) { + getGameManager()->stopTimer(id); +} + +void CGameObject::gotoView(const CString &viewName, const CString &clipName) { + CViewItem *newView = parseView(viewName); + CGameManager *gameManager = getGameManager(); + CViewItem *oldView = gameManager ? gameManager->getView() : newView; + if (!oldView || !newView) + return; + + CMovieClip *clip = nullptr; + if (clipName.empty()) { + CLinkItem *link = oldView->findLink(newView); + if (link) + clip = link->getClip(); + } else { + clip = oldView->findNode()->findRoom()->findClip(clipName); + } + + // Change the view + gameManager->_gameState.changeView(newView, clip); +} + +CViewItem *CGameObject::parseView(const CString &viewString) { + int firstIndex = viewString.indexOf('.'); + int lastIndex = viewString.lastIndexOf('.'); + CString roomName, nodeName, viewName; + + if (firstIndex == -1) { + roomName = viewString; + } else { + roomName = viewString.left(firstIndex); + + if (lastIndex > firstIndex) { + nodeName = viewString.mid(firstIndex + 1, lastIndex - firstIndex - 1); + viewName = viewString.mid(lastIndex + 1); + } else { + nodeName = viewString.mid(firstIndex + 1); + } + } + + CGameManager *gameManager = getGameManager(); + if (!gameManager) + return nullptr; + + CRoomItem *room = gameManager->getRoom(); + CProjectItem *project = room->getRoot(); + + // Ensure we have the specified room + if (project) { + if (room->getName() != roomName) { + // Scan for the correct room + for (room = project->findFirstRoom(); room && room->getName() != roomName; + room = project->findNextRoom(room)) ; + } + } + if (!room) + return nullptr; + + // Find the designated node within the room + CNodeItem *node = static_cast<CNodeItem *>(room->findChildInstanceOf(CNodeItem::_type)); + while (node && node->getName() != nodeName) + node = static_cast<CNodeItem *>(room->findNextInstanceOf(CNodeItem::_type, node)); + if (!node) + return nullptr; + + CViewItem *view = static_cast<CViewItem *>(node->findChildInstanceOf(CViewItem::_type)); + while (view && view->getName() != viewName) + view = static_cast<CViewItem *>(node->findNextInstanceOf(CViewItem::_type, view)); + if (!view) + return nullptr; + + // Find the view, so return it + return view; +} + +CString CGameObject::getViewFullName() const { + CGameManager *gameManager = getGameManager(); + CViewItem *view = gameManager->getView(); + CNodeItem *node = view->findNode(); + CRoomItem *room = node->findRoom(); + + return CString::format("%s.%s.%s", room->getName().c_str(), + node->getName().c_str(), view->getName().c_str()); +} + +void CGameObject::sleep(uint milli) { + g_vm->_events->sleep(milli); +} + +Point CGameObject::getMousePos() const { + return getGameManager()->_gameState.getMousePos(); +} + +bool CGameObject::compareViewNameTo(const CString &name) const { + return getViewFullName().compareToIgnoreCase(name); +} + +int CGameObject::compareRoomNameTo(const CString &name) { + CRoomItem *room = getGameManager()->getRoom(); + return room->getName().compareToIgnoreCase(name); +} + +CString CGameObject::getRoomName() const { + CRoomItem *room = getRoom(); + return room ? room->getName() : CString(); +} + +CString CGameObject::getRoomNodeName() const { + CNodeItem *node = getNode(); + if (!node) + return CString(); + + CRoomItem *room = node->findRoom(); + + return CString::format("%s.%s", room->getName().c_str(), node->getName().c_str()); +} + +CString CGameObject::getFullViewName() { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->getFullViewName() : CString(); +} + +CGameObject *CGameObject::getMailManFirstObject() const { + CMailMan *mailMan = getMailMan(); + return mailMan ? mailMan->getFirstObject() : nullptr; +} + +CGameObject *CGameObject::getMailManNextObject(CGameObject *prior) const { + CMailMan *mailMan = getMailMan(); + return mailMan ? mailMan->getNextObject(prior) : nullptr; +} + +CGameObject *CGameObject::findMailByFlags(int mode, uint roomFlags) { + CMailMan *mailMan = getMailMan(); + if (!mailMan) + return nullptr; + + for (CGameObject *obj = mailMan->getFirstObject(); obj; + obj = mailMan->getNextObject(obj)) { + if (compareRoomFlags(mode, roomFlags, obj->_roomFlags)) + return obj; + } + + return nullptr; +} + +CGameObject *CGameObject::getNextMail(CGameObject *prior) { + CMailMan *mailMan = getMailMan(); + return mailMan ? mailMan->getNextObject(prior) : nullptr; +} + +CGameObject *CGameObject::findRoomObject(const CString &name) const { + return static_cast<CGameObject *>(findRoom()->findByName(name)); +} + +CGameObject *CGameObject::findInRoom(const CString &name) { + CRoomItem *room = getRoom(); + return room ? static_cast<CGameObject *>(room->findByName(name)) : nullptr; +} + +Found CGameObject::find(const CString &name, CGameObject **item, int findAreas) { + CGameObject *go; + *item = nullptr; + + // Scan under PET if flagged + if (findAreas & FIND_PET) { + for (go = getPetControl()->getFirstObject(); go; go = getPetControl()->getNextObject(go)) { + if (go->getName() == name) { + *item = go; + return FOUND_PET; + } + } + } + + if (findAreas & FIND_MAILMAN) { + for (go = getMailManFirstObject(); go; go = getMailManNextObject(go)) { + if (go->getName() == name) { + *item = go; + return FOUND_MAILMAN; + } + } + } + + if (findAreas & FIND_GLOBAL) { + go = static_cast<CGameObject *>(getRoot()->findByName(name)); + if (go) { + *item = go; + return FOUND_GLOBAL; + } + } + + if (findAreas & FIND_ROOM) { + go = findRoomObject(name); + if (go) { + *item = go; + return FOUND_ROOM; + } + } + + return FOUND_NONE; +} + +void CGameObject::moveToView() { + CViewItem *view = getGameManager()->getView(); + detach(); + view->addUnder(this); +} + +void CGameObject::moveToView(const CString &name) { + CViewItem *view = parseView(name); + detach(); + view->addUnder(this); +} + +void CGameObject::stateInc14() { + getGameManager()->_gameState.inc14(); +} + +int CGameObject::stateGet14() const { + return getGameManager()->_gameState._field14; +} + +void CGameObject::stateSet24() { + getGameManager()->_gameState.set24(1); +} + +int CGameObject::stateGet24() const { + return getGameManager()->_gameState.get24(); +} + +void CGameObject::stateInc38() { + getGameManager()->_gameState.inc38(); +} + +int CGameObject::stateGet38() const { + return getGameManager()->_gameState._field38; +} + +void CGameObject::quitGame() { + getGameManager()->_gameState._quitGame = true; +} + +void CGameObject::inc54() { + getGameManager()->inc54(); +} + +void CGameObject::dec54() { + getGameManager()->dec54(); +} + +void CGameObject::setMovieFrameRate(double rate) { + if (_surface) + _surface->setMovieFrameRate(rate); +} + +void CGameObject::setTextBorder(const CString &str, int border, int borderRight) { + if (!_text) + _text = new CPetText(); + _textBorder = border; + _textBorderRight = borderRight; + + _text->setText(str); + CScreenManager *screenManager = getGameManager()->setScreenManager(); + _text->scrollToTop(screenManager); +} + +void CGameObject::setTextHasBorders(bool hasBorders) { + if (!_text) + _text = new CPetText(); + + _text->setHasBorder(hasBorders); +} + +void CGameObject::setTextBounds() { + Rect rect = _bounds; + rect.grow(_textBorder); + rect.right -= _textBorderRight; + + _text->setBounds(rect); + makeDirty(); +} + +void CGameObject::setTextColor(byte r, byte g, byte b) { + if (!_text) + _text = new CPetText(); + + _text->setColor(r, g, b); +} + +void CGameObject::setTextFontNumber(int fontNumber) { + if (!_text) + _text = new CPetText(); + + _text->setFontNumber(fontNumber); +} + +int CGameObject::getTextWidth() const { + assert(_text); + return _text->getTextWidth(CScreenManager::_screenManagerPtr); +} + +CTextCursor *CGameObject::getTextCursor() const { + return CScreenManager::_screenManagerPtr->_textCursor; +} + +void CGameObject::scrollTextUp() { + if (_text) + _text->scrollUp(CScreenManager::_screenManagerPtr); +} + +void CGameObject::scrollTextDown() { + if (_text) + _text->scrollDown(CScreenManager::_screenManagerPtr); +} + +void CGameObject::lockMouse() { + CGameManager *gameMan = getGameManager(); + gameMan->lockInputHandler(); + + if (CScreenManager::_screenManagerPtr->_mouseCursor) + CScreenManager::_screenManagerPtr->_mouseCursor->hide(); +} + +void CGameObject::hideMouse() { + CScreenManager::_screenManagerPtr->_mouseCursor->hide(); +} + +void CGameObject::showMouse() { + CScreenManager::_screenManagerPtr->_mouseCursor->show(); +} + +void CGameObject::disableMouse() { + lockInputHandler(); + hideMouse(); +} + +void CGameObject::enableMouse() { + unlockInputHandler(); + showMouse(); +} + +void CGameObject::mouseLockE4() { + CScreenManager::_screenManagerPtr->_mouseCursor->lockE4(); +} + +void CGameObject::mouseUnlockE4() { + CScreenManager::_screenManagerPtr->_mouseCursor->unlockE4(); +} + +void CGameObject::mouseSaveState(int v1, int v2, int v3) { + CScreenManager::_screenManagerPtr->_mouseCursor->saveState(v1, v2, v3); +} + +void CGameObject::lockInputHandler() { + getGameManager()->lockInputHandler(); +} + +void CGameObject::unlockInputHandler() { + getGameManager()->unlockInputHandler(); +} + +void CGameObject::unlockMouse() { + if (CScreenManager::_screenManagerPtr->_mouseCursor) + CScreenManager::_screenManagerPtr->_mouseCursor->show(); + + CGameManager *gameMan = getGameManager(); + gameMan->unlockInputHandler(); +} + +void CGameObject::loadSurface() { + if (!_surface && !_resource.empty()) { + loadResource(_resource); + _resource.clear(); + } + + if (_surface) + _surface->loadIfReady(); +} + +bool CGameObject::changeView(const CString &viewName) { + return changeView(viewName, ""); +} + +bool CGameObject::changeView(const CString &viewName, const CString &clipName) { + CViewItem *newView = parseView(viewName); + CGameManager *gameManager = getGameManager(); + CViewItem *oldView = gameManager->getView(); + + if (!oldView || !newView) + return false; + + CMovieClip *clip = nullptr; + if (!clipName.empty()) { + clip = oldView->findNode()->findRoom()->findClip(clipName); + } else { + CLinkItem *link = oldView->findLink(newView); + if (link) + clip = link->getClip(); + } + + gameManager->_gameState.changeView(newView, clip); + return true; +} + +void CGameObject::dragMove(const Point &pt) { + if (_surface) { + _bounds.setWidth(_surface->getWidth()); + _bounds.setHeight(_surface->getHeight()); + } + + setPosition(Point(pt.x - _bounds.width() / 2, pt.y - _bounds.height() / 2)); +} + +bool CGameObject::isObjectDragging() const { + CTreeItem *item = getGameManager()->_dragItem; + return item ? static_cast<CGameObject *>(item) != nullptr : false; +} + +Point CGameObject::getControid() const { + return Point(_bounds.left + _bounds.width() / 2, + _bounds.top + _bounds.height() / 2); +} + +bool CGameObject::clipExistsByStart(const CString &name, int startFrame) const { + return _movieClips.existsByStart(name, startFrame); +} + +bool CGameObject::clipExistsByEnd(const CString &name, int endFrame) const { + return _movieClips.existsByEnd(name, endFrame); +} + +void CGameObject::petClear() const { + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->resetActiveNPC(); +} + +CDontSaveFileItem *CGameObject::getDontSave() const { + CProjectItem *project = getRoot(); + return project ? project->getDontSaveFileItem() : nullptr; +} + +CPetControl *CGameObject::getPetControl() const { + return static_cast<CPetControl *>(getDontSaveChild(CPetControl::_type)); +} + +CMailMan *CGameObject::getMailMan() const { + return dynamic_cast<CMailMan *>(getDontSaveChild(CMailMan::_type)); +} + +CTreeItem *CGameObject::getDontSaveChild(ClassDef *classDef) const { + CProjectItem *root = getRoot(); + if (!root) + return nullptr; + + CDontSaveFileItem *dontSave = root->getDontSaveFileItem(); + if (!dontSave) + return nullptr; + + return dontSave->findChildInstanceOf(classDef); +} + +CRoomItem *CGameObject::getHiddenRoom() const { + CProjectItem *root = getRoot(); + return root ? root->findHiddenRoom() : nullptr; +} + +CRoomItem *CGameObject::locateRoom(const CString &name) const { + if (name.empty()) + return nullptr; + + CProjectItem *project = getRoot(); + for (CRoomItem *room = project->findFirstRoom(); room; room = project->findNextRoom(room)) { + if (!room->getName().compareToIgnoreCase(name)) + return room; + } + + return nullptr; +} + +CGameObject *CGameObject::getHiddenObject(const CString &name) const { + CRoomItem *room = getHiddenRoom(); + return room ? static_cast<CGameObject *>(findUnder(room, name)) : nullptr; +} + +CTreeItem *CGameObject::findUnder(CTreeItem *parent, const CString &name) const { + if (!parent) + return nullptr; + + for (CTreeItem *item = parent->getFirstChild(); item; item = item->scan(parent)) { + if (item->getName() == name) + return item; + } + + return nullptr; +} + +CRoomItem *CGameObject::findRoomByName(const CString &name) { + CProjectItem *project = getRoot(); + for (CRoomItem *room = project->findFirstRoom(); room; room = project->findNextRoom(room)) { + if (!room->getName().compareToIgnoreCase(name)) + return room; + } + + return nullptr; +} + +CMusicRoom *CGameObject::getMusicRoom() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? &gameManager->_musicRoom : nullptr; +} + +int CGameObject::getPassengerClass() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->_gameState._passengerClass : 3; +} + +int CGameObject::getPriorClass() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->_gameState._priorClass : 3; +} + +void CGameObject::setPassengerClass(int newClass) { + if (newClass >= 1 && newClass <= 4) { + // Change the passenger class + CGameManager *gameMan = getGameManager(); + gameMan->_gameState._priorClass = gameMan->_gameState._passengerClass; + gameMan->_gameState._passengerClass = newClass; + + // Setup the PET again, so the new class's PET background can take effect + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->setup(); + } +} + +void CGameObject::createCredits() { + _credits = new CCreditText(); + CScreenManager *screenManager = getGameManager()->setScreenManager(); + _credits->load(this, screenManager, _bounds); +} + +void CGameObject::fn10(int v1, int v2, int v3) { + makeDirty(); + _field44 = v1; + _field48 = v2; + _field4C = v3; +} + +void CGameObject::movieSetAudioTiming(bool flag) { + if (!_surface && !_resource.empty()) { + loadResource(_resource); + _resource.clear(); + } + + if (_surface && _surface->_movie) + _surface->_movie->_hasAudioTiming = flag; +} + +void CGameObject::movieEvent(int frameNumber) { + if (_surface) + _surface->addMovieEvent(frameNumber, this); +} + +void CGameObject::movieEvent() { + if (_surface) + _surface->addMovieEvent(-1, this); +} + +int CGameObject::getClipDuration(const CString &name, int frameRate) const { + CMovieClip *clip = _movieClips.findByName(name); + return clip ? (clip->_endFrame - clip->_startFrame) * 1000 / frameRate : 0; +} + +uint32 CGameObject::getTickCount() { + return g_vm->_events->getTicksCount(); +} + +bool CGameObject::compareRoomFlags(int mode, uint flags1, uint flags2) { + switch (mode) { + case 1: + return CRoomFlags::compareLocation(flags1, flags2); + + case 2: + return CRoomFlags::compareClassElevator(flags1, flags2); + + case 3: + return CRoomFlags::isTitania(flags1, flags2); + + default: + return false; + } +} + +void CGameObject::setState1C(bool flag) { + getGameManager()->_gameState._field1C = flag; +} + +void CGameObject::addMail(int mailId) { + CMailMan *mailMan = getMailMan(); + if (mailMan) { + makeDirty(); + mailMan->addMail(this, mailId); + } +} + +void CGameObject::setMailId(int mailId) { + CMailMan *mailMan = getMailMan(); + if (mailMan) { + makeDirty(); + mailMan->setMailId(this, mailId); + } +} + +bool CGameObject::mailExists(int id) const { + return findMail(id) != nullptr; +} + +CGameObject *CGameObject::findMail(int id) const { + CMailMan *mailMan = getMailMan(); + return mailMan ? mailMan->findMail(id) : nullptr; +} + +void CGameObject::removeMail(int id, int v) { + CMailMan *mailMan = getMailMan(); + if (mailMan) + mailMan->removeMail(id, v); +} + +void CGameObject::resetMail() { + CMailMan *mailMan = getMailMan(); + if (mailMan) + mailMan->resetValue(); +} + +int CGameObject::getNewRandomNumber(int max, int *oldVal) { + if (oldVal) { + int startingVal = *oldVal; + while (*oldVal == startingVal && max > 0) + *oldVal = g_vm->getRandomNumber(max); + + return *oldVal; + } else { + return g_vm->getRandomNumber(max); + } +} + +/*------------------------------------------------------------------------*/ + +CRoomItem *CGameObject::getRoom() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->getRoom() : nullptr; +} + +CNodeItem *CGameObject::getNode() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->getNode() : nullptr; +} + +CViewItem *CGameObject::getView() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->getView() : nullptr; +} + +/*------------------------------------------------------------------------*/ + +void CGameObject::petAddToCarryParcel(CGameObject *obj) { + CPetControl *pet = getPetControl(); + if (pet) { + CGameObject *parcel = pet->getHiddenObject("CarryParcel"); + if (parcel) + parcel->moveUnder(obj); + } +} + +void CGameObject::petAddToInventory() { + CPetControl *pet = getPetControl(); + if (pet) { + makeDirty(); + pet->addToInventory(this); + } +} + +CTreeItem *CGameObject::petContainerRemove(CGameObject *obj) { + CPetControl *pet = getPetControl(); + if (!obj || !pet) + return nullptr; + if (!obj->compareRoomNameTo("CarryParcel")) + return obj; + + CGameObject *item = static_cast<CGameObject *>(pet->getLastChild()); + if (item) + item->detach(); + + pet->moveToHiddenRoom(obj); + pet->removeFromInventory(item, false, false); + + return item; +} + +bool CGameObject::petCheckNode(const CString &name) { + CPetControl *pet = getPetControl(); + return pet ? pet->checkNode(name) : false; +} + +bool CGameObject::petDismissBot(const CString &name) { + CPetControl *pet = getPetControl(); + return pet ? pet->dismissBot(name) : false; +} + +bool CGameObject::petDoorOrBellbotPresent() const { + CPetControl *pet = getPetControl(); + return pet ? pet->isDoorOrBellbotPresent() : false; +} + +void CGameObject::petDisplayMessage(int unused, const CString &msg) { + petDisplayMessage(msg); +} + +void CGameObject::petDisplayMessage(const CString &msg) { + CPetControl *pet = getPetControl(); + if (pet) + pet->displayMessage(msg); +} + +void CGameObject::petInvChange() { + CPetControl *pet = getPetControl(); + if (pet) + pet->invChange(this); +} + +void CGameObject::petLockInput() { + getPetControl()->incInputLocks(); +} + +void CGameObject::petMoveToHiddenRoom() { + CPetControl *pet = getPetControl(); + if (pet) { + makeDirty(); + pet->moveToHiddenRoom(this); + } +} + +void CGameObject::petReassignRoom(int passClassNum) { + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->reassignRoom(passClassNum); +} + +void CGameObject::petSetArea(PetArea newArea) const { + CPetControl *pet = getPetControl(); + if (pet) + pet->setArea(newArea); +} + +void CGameObject::petSetRoomsWellEntry(int entryNum) { + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->setRoomsWellEntry(entryNum); +} + +int CGameObject::petGetRoomsWellEntry() const { + CPetControl *petControl = getPetControl(); + return petControl ? petControl->getRoomsWellEntry() : 0; +} + +void CGameObject::petSetRooms1D4(int v) { + CPetControl *pet = getPetControl(); + if (pet) + pet->setRooms1D4(v); +} + +void CGameObject::petOnSummonBot(const CString &name, int val) { + CPetControl *pet = getPetControl(); + if (pet) + pet->summonBot(name, val); +} + +void CGameObject::petUnlockInput() { + getPetControl()->decInputLocks(); +} + +/*------------------------------------------------------------------------*/ + +CStarControl *CGameObject::getStarControl() const { + CStarControl *starControl = static_cast<CStarControl *>(getDontSaveChild(CStarControl::_type)); + if (!starControl) { + CViewItem *view = getGameManager()->getView(); + if (view) + starControl = static_cast<CStarControl *>(view->findChildInstanceOf(CStarControl::_type)); + } + + return starControl; +} + +void CGameObject::starFn1(int v) { + CStarControl *starControl = getStarControl(); + if (starControl) + starControl->fn1(v); +} + +void CGameObject::starFn2() { + CStarControl *starControl = getStarControl(); + if (starControl) + starControl->fn4(); +} + +/*------------------------------------------------------------------------*/ + +void CGameObject::startTalking(const CString &npcName, uint id, CViewItem *view) { + CTrueTalkNPC *npc = static_cast<CTrueTalkNPC *>(getRoot()->findByName(npcName)); + startTalking(npc, id, view); +} + +void CGameObject::startTalking(CTrueTalkNPC *npc, uint id, CViewItem *view) { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + CTrueTalkManager *talkManager = gameManager->getTalkManager(); + if (talkManager) + talkManager->start(npc, id, view); + } +} + +void CGameObject::endTalking(CTrueTalkNPC *npc, bool viewFlag, CViewItem *view) { + CPetControl *pet = getPetControl(); + if (pet) + pet->setActiveNPC(npc); + + if (viewFlag) + npc->setView(view); + + if (pet) + pet->refreshNPC(); +} + +void CGameObject::talkSetDialRegion(const CString &name, int dialNum, int regionNum) { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + CTrueTalkManager *talkManager = gameManager->getTalkManager(); + if (talkManager) { + TTnpcScript *npcScript = talkManager->getTalker(name); + if (npcScript) + npcScript->setDialRegion(dialNum, regionNum); + } + } +} + +int CGameObject::talkGetDialRegion(const CString &name, int dialNum) { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + CTrueTalkManager *talkManager = gameManager->getTalkManager(); + if (talkManager) { + TTnpcScript *npcScript = talkManager->getTalker(name); + if (npcScript) + return npcScript->getDialRegion(dialNum); + } + } + + return 0; +} + +/*------------------------------------------------------------------------*/ + +uint CGameObject::getNodeChangedCtr() const { + return getGameManager()->_gameState.getNodeChangedCtr(); +} + +uint CGameObject::getNodeEnterTicks() const { + return getGameManager()->_gameState.getNodeEnterTicks(); +} + + +} // End of namespace Titanic diff --git a/engines/titanic/core/game_object.h b/engines/titanic/core/game_object.h new file mode 100644 index 0000000000..2dc539f739 --- /dev/null +++ b/engines/titanic/core/game_object.h @@ -0,0 +1,947 @@ +/* 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 TITANIC_GAME_OBJECT_H +#define TITANIC_GAME_OBJECT_H + +#include "titanic/support/mouse_cursor.h" +#include "titanic/support/credit_text.h" +#include "titanic/support/movie_range_info.h" +#include "titanic/sound/proximity.h" +#include "titanic/support/rect.h" +#include "titanic/support/movie_clip.h" +#include "titanic/core/named_item.h" +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_text.h" + +namespace Titanic { + +enum Find { FIND_GLOBAL = 1, FIND_ROOM = 2, FIND_PET = 4, FIND_MAILMAN = 8 }; +enum Found { FOUND_NONE = 0, FOUND_GLOBAL = 1, FOUND_ROOM = 2, FOUND_PET = 3, FOUND_MAILMAN = 4 }; + +class CDontSaveFileItem; +class CMailMan; +class CMusicRoom; +class CRoomItem; +class CStarControl; +class CMouseDragStartMsg; +class CTrueTalkNPC; +class CVideoSurface; +class OSMovie; + +class CGameObject : public CNamedItem { + friend class OSMovie; + DECLARE_MESSAGE_MAP; +private: + static CCreditText *_credits; + static int _soundHandles[4]; +private: + /** + * Load a visual resource for the object + */ + void loadResource(const CString &name); + + /** + * Loads a movie + */ + void loadMovie(const CString &name, bool pendingFlag = true); + + /** + * Loads an image + */ + void loadImage(const CString &name, bool pendingFlag = true); + + /** + * Process and remove any registered movie range info + */ + void processMoveRangeInfo(); + + /** + * Merges one rect into another, and returns true if there was + * a common intersection + */ + bool clipRect(const Rect &rect1, Rect &rect2) const; +protected: + Rect _bounds; + double _field34; + double _field38; + double _field3C; + int _field40; + int _field44; + int _field48; + int _field4C; + CMovieClipList _movieClips; + int _initialFrame; + CMovieRangeInfoList _movieRangeInfoList; + int _frameNumber; + CPetText *_text; + uint _textBorder; + uint _textBorderRight; + int _field9C; + Common::Point _savedPos; + CVideoSurface *_surface; + CString _resource; + int _fieldB8; +protected: + /** + * Saves the current position the object is located at + */ + void savePosition(); + + /** + * Resets the object back to the previously saved starting position + */ + void resetPosition(); + + /** + * Check for starting to drag the object + */ + bool checkStartDragging(CMouseDragStartMsg *msg); + + /** + * Goto a new view + */ + void gotoView(const CString &viewName, const CString &clipName); + + /** + * Parses a view into it's components of room, node, and view, + * and locates the designated view + */ + CViewItem * parseView(const CString &viewString); + + void inc54(); + void dec54(); + + /** + * Locks/hides the mouse + */ + void lockMouse(); + + /** + * Unlocks/shows the mouse + */ + void unlockMouse(); + + /** + * Hides the mouse cursor + */ + void hideMouse(); + + /** + * Shows the mouse cursor + */ + void showMouse(); + + /** + * Disable the mouse + */ + void disableMouse(); + + /** + * Enable the mouse + */ + void enableMouse(); + + void mouseLockE4(); + void mouseUnlockE4(); + + void mouseSaveState(int v1, int v2, int v3); + + /** + * Lock the input handler + */ + void lockInputHandler(); + + /** + * Unlock the input handler + */ + void unlockInputHandler(); + + /** + * Load a sound + */ + void loadSound(const CString &name); + + /** + * Plays a sound + * @param resName Filename of sound to play + * @param volume Volume level + */ + int playSound(const CString &name, uint volume = 100, int val3 = 0, bool repeated = false); + + /** + * Plays a sound + * @param resName Filename of sound to play + * @param prox Proximity object with the sound data + */ + int playSound(const CString &name, CProximity &prox); + + /** + * Queues a sound to play after a specified one finishes + * @param resName Filename of sound to play + * @param volume Volume level + */ + int queueSound(const CString &name, uint priorHandle, uint volume = 100, int val3 = 0, bool repeated = false); + + /** + * Stop a sound + * @param handle Sound handle + * @param seconds Optional number of seconds to transition sound off + */ + void stopSound(int handle, uint seconds = 0); + + /** + * Returns true if a sound with the specified handle is active + */ + bool isSoundActive(int handle) const; + + /** + * Sets the volume for a sound + * @param handle Sound handle + * @param volume Volume percentage (0 to 100) + * @param seconds Number of seconds to transition to the new volume + */ + void setSoundVolume(int handle, uint percent, uint seconds); + + /** + * Plays a sound, and saves it's handle in the global sound handles list + * @param resName Filename of sound to play + * @param mode Volume mode level + * @param initialMute If set, sound transitions in from mute over 2 seconds + * @param repeated Flag for repeating sounds + * @param handleIndex Slot 0 to 3 in the shared sound handle list to store the sound's handle + */ + void playGlobalSound(const CString &resName, int mode, bool initialMute, bool repeated, int handleIndex); + + /** + * Stops a sound saved in the global sound handle list + * @param transition If set, the sound transitions to silent before stopping + * @param handleIndex Index of sound to stop. If -1, all global sounds are stopped + */ + void stopGlobalSound(bool transition, int handleIndex); + + /** + * Updates the volume for a global sound based on the specified mode's volume + * @param mode Volume level mode + * @param seconds Number of seconds to transition to new volume + * @param handleIndex Index of global sound to update. If -1, all global sounds are updated + */ + void setGlobalSoundVolume(int mode, uint seconds, int handleIndex); + + void sound8(bool flag) const; + + /** + * Adds a timer + */ + int addTimer(int endVal, uint firstDuration, uint repeatDuration); + + /** + * Adds a timer + */ + int addTimer(uint firstDuration, uint repeatDuration = 0); + + /** + * Start an animation timer + */ + int startAnimTimer(const CString &action, uint firstDuration, uint repeatDuration = 0); + + /** + * Stops a timer + */ + void stopTimer(int id); + + /** + * Causes the game to sleep for the specified time + */ + void sleep(uint milli); + + /** + * Get the current mouse cursor position + */ + Point getMousePos() const; + + /* + * Compares the current view's name in a Room.Node.View tuplet + * string form to the passed string + */ + bool compareViewNameTo(const CString &name) const; + + /** + * Compare the name of the parent room to the item to a passed string + */ + int compareRoomNameTo(const CString &name); + + /** + * Gets the first object under the system MailMan + */ + CGameObject *getMailManFirstObject() const; + + /** + * Gets the next object under the system MailMan + */ + CGameObject *getMailManNextObject(CGameObject *prior) const; + + /** + * Find mail by room flags + */ + CGameObject *findMailByFlags(int mode, uint roomFlags); + + /** + * Find next mail from a given prior one + */ + CGameObject *getNextMail(CGameObject *prior); + + /** + * Finds an object by name within the object's room + */ + CGameObject *findRoomObject(const CString &name) const; + + /** + * FInds an object under the current room + */ + CGameObject *findInRoom(const CString &name); + + /** + * Moves the object to be under the current view + */ + void moveToView(); + + /** + * Moves the object to be under the specified view + */ + void moveToView(const CString &name); + + /** + * Change the view + */ + bool changeView(const CString &viewName, const CString &clipName); + + /** + * Change the view + */ + bool changeView(const CString &viewName); + + /** + * Get the centre of the game object's bounds + */ + Point getControid() const; + + /** + * Play an arbitrary clip + */ + void playClip(const CString &name, uint flags); + + /** + * Play a clip + */ + void playClip(uint startFrame, uint endFrame); + + /** + * Play a clip randomly from a passed list of names + */ + void playRandomClip(const char **names, uint flags); + + /** + * Return the current view/node/room as a single string + */ + CString getViewFullName() const; + + /** + * Returns true if a clip exists in the list with a given name + * and starting frame number + */ + bool clipExistsByStart(const CString &name, int startFrame = 0) const; + + /** + * Returns true if a clip exists in the list with a given name + * and ending frame number + */ + bool clipExistsByEnd(const CString &name, int endFrame = 0) const; + + /** + * Clear the PET display + */ + void petClear() const; + + /** + * Returns the MailMan + */ + CMailMan *getMailMan() const; + + /** + * Gets the don't save container object + */ + CDontSaveFileItem *getDontSave() const; + + /** + * Returns a child of the Dont Save area of the project of the given class + */ + CTreeItem *getDontSaveChild(ClassDef *classDef) const; + + /** + * Returns the special hidden room container + */ + CRoomItem *getHiddenRoom() const; + + /** + * Locates a room with the given name + */ + CRoomItem *locateRoom(const CString &name) const; + + /** + * Scan the specified room for an item by name + */ + CTreeItem *findUnder(CTreeItem *parent, const CString &name) const; + + /** + * Finds a room by name + */ + CRoomItem *findRoomByName(const CString &name); + + /** + * Returns the music room instance from the game manager + */ + CMusicRoom *getMusicRoom() const; + + /** + * Set's the player's passenger class + */ + void setPassengerClass(int newClass); + + /** + * Overrides whether the object's movie has audio timing + */ + void movieSetAudioTiming(bool flag); + + void fn10(int v1, int v2, int v3); + + /** + * Gets the duration of a specified clip in milliseconds + */ + int getClipDuration(const CString &name, int frameRate = 14) const; + + /** + * Returns the current system tick count + */ + uint32 getTickCount(); + + /** + * Adds an object to the mail list + */ + void addMail(int mailId); + + /** + * Sets the mail identifier for an object + */ + void setMailId(int mailId); + + /** + * Returns true if a mail with a specified Id exists + */ + bool mailExists(int id) const; + + /** + * Returns a specified mail, if one exists + */ + CGameObject *findMail(int id) const; + + /** + * Remove an object from the mail list + */ + void removeMail(int id, int v); + + /** + * Resets the Mail Man value + */ + void resetMail(); + + /** + * Locks the PET, disabling all input. Can be called multiple times + */ + void petLockInput(); + + /** + * Unlocks PET input + */ + void petUnlockInput(); + + /** + * Flag to quit the game + */ + void quitGame(); + + /** + * Set the frame rate for the currently loaded movie + */ + void setMovieFrameRate(double rate); + + /** + * Set up the text borders for the object + */ + void setTextBorder(const CString &str, int border = 0, int borderRight = 0); + + /** + * Sets whether the text will use borders + */ + void setTextHasBorders(bool hasBorders); + + /** + * Sets the bounds for a previously defined text area + */ + void setTextBounds(); + + /** + * Sets the color for the object's text + */ + void setTextColor(byte r, byte g, byte b); + + /** + * Sets the font number to use for text + */ + void setTextFontNumber(int fontNumber); + + /** + * Gets the width of the text contents + */ + int getTextWidth() const; + + /** + * Returns the text cursor + */ + CTextCursor *getTextCursor() const; + + /** + * Scroll text up + */ + void scrollTextUp(); + + /** + * Scroll text down + */ + void scrollTextDown(); + + /** + * Gets a new random number + */ + int getNewRandomNumber(int max, int *oldVal = nullptr); +public: + bool _isMail; + int _id; + uint _roomFlags; + int _field60; + CursorId _cursorId; + bool _visible; +public: + /** + * Initializes statics + */ + static void init(); + + /** + * Deinitializes statics + */ + static void deinit(); +public: + CLASSDEF; + CGameObject(); + ~CGameObject(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Returns the clip list, if any, associated with the item + */ + virtual const CMovieClipList *getMovieClips() const { return &_movieClips; } + + /** + * Allows the item to draw itself + */ + virtual void draw(CScreenManager *screenManager); + + /** + * Gets the bounds occupied by the item + */ + virtual Rect getBounds() const; + + /** + * Called when the view changes + */ + virtual void viewChange(); + + /** + * Allows the item to draw itself + */ + void draw(CScreenManager *screenManager, const Rect &destRect, const Rect &srcRect); + + /** + * Allows the item to draw itself + */ + void draw(CScreenManager *screenManager, const Point &destPos); + + /** + * Allows the item to draw itself + */ + void draw(CScreenManager *screenManager, const Point &destPos, const Rect &srcRect); + + /** + * Returns true if the item is the PET control + */ + virtual bool isPet() const; + + /** + * Checks the passed point is validly in the object, + * with extra checking of object flags status + */ + bool checkPoint(const Point &pt, bool ignore40 = false, bool visibleOnly = false); + + /** + * Set the position of the object + */ + void setPosition(const Point &newPos); + + /** + * Change the object's status + */ + void playMovie(uint flags); + + /** + * Play the movie specified in _resource + */ + void playMovie(int startFrame, int endFrame, uint flags); + + /** + * Play the movie specified in _resource + */ + void playMovie(int startFrame, int endFrame, int initialFrame, uint flags); + + /** + * Returns true if the object has a currently active movie + */ + bool hasActiveMovie() const; + + /** + * Stops any movie currently playing for the object + */ + void stopMovie(); + + /** + * Get the current movie frame + */ + int getMovieFrame() const; + + /** + * Returns the object's frame number + */ + int getFrameNumber() const { return _frameNumber; } + + /** + * Loads a frame + */ + void loadFrame(int frameNumber); + + /** + * Load the surface + */ + void loadSurface(); + + /** + * Marks the area occupied by the object as dirty, requiring re-rendering + */ + void makeDirty(); + + /** + * Marks the area in the passed rect as dirty, and requiring re-rendering + */ + void makeDirty(const Rect &r); + + /** + * Sets whether the object is visible + */ + void setVisible(bool val); + + /** + * Return the player's passenger class + */ + int getPassengerClass() const; + + /** + * Return the player's previous passenger class + */ + int getPriorClass() const; + + /** + * Returns true if there's an attached surface which has a frame + * ready for display + */ + bool surfaceHasFrame() const; + + /** + * Finds an item in various system areas + */ + Found find(const CString &name, CGameObject **item, int findAreas); + + /** + * Returns a hidden object + */ + CGameObject *getHiddenObject(const CString &name) const; + + /** + * Sets up credits text + */ + void createCredits(); + + /** + * Support function for drag moving + */ + void dragMove(const Point &pt); + + /** + * Returns true if an item being dragged is a game object + */ + bool isObjectDragging() const; + + bool compareRoomFlags(int mode, uint flags1, uint flags2); + + /*--- CGameManager Methods ---*/ + + /** + * Return the current room + */ + CRoomItem *getRoom() const; + + /** + * Return the current node + */ + CNodeItem *getNode() const; + + /** + * Return the current room + */ + CViewItem *getView() const; + + /** + * Get the current room name + */ + CString getRoomName() const; + + /** + * Get the current node and room in the form "room.node" + */ + CString getRoomNodeName() const; + + /** + * Return the full Id of the current view in a + * room.node.view tuplet form + */ + CString getFullViewName(); + + /*--- CPetControl Methods ---*/ + + /** + * Returns the PET control + */ + CPetControl *getPetControl() const; + + /** + * Moves a specified item to the carry parcel + */ + void petAddToCarryParcel(CGameObject *obj); + + /** + * Add the item to the inventory + */ + void petAddToInventory(); + + CTreeItem *petContainerRemove(CGameObject *obj); + + bool petCheckNode(const CString &name); + + /** + * Dismiss a bot + */ + bool petDismissBot(const CString &name); + + /** + * Is Doorbot or Bellbot present in the current view + */ + bool petDoorOrBellbotPresent() const; + + /** + * Display a message in the PET + */ + void petDisplayMessage(int unused, const CString &msg); + + /** + * Display a message in the PET + */ + void petDisplayMessage(const CString &msg); + + /** + * Gets the entry number used when last arriving at the well + */ + int petGetRoomsWellEntry() const; + + /** + * Hide the PET + */ + void petHide(); + + /** + * Hides the text cursor in the current section, if applicable + */ + void petHideCursor(); + + /** + * Highlights a glyph in the currently active PET section + */ + void petHighlightGlyph(int id); + + /** + * Called when the status of an item in the inventory has changed + */ + void petInvChange(); + + /** + * Moves the item from it's original position to be under the hidden room + */ + void petMoveToHiddenRoom(); + + /** + * Gives the player a new assigned room in the specified passenger class + */ + void petReassignRoom(int passClassNum); + + /** + * Sets a new area in the PET + */ + void petSetArea(PetArea newArea) const; + + /** + * Set the remote target in the PET to this object + */ + void petSetRemoteTarget(); + + /** + * Sets the entry number for arriving at the well + */ + void petSetRoomsWellEntry(int entryNum); + + void petSetRooms1D4(int v); + + + /** + * Show the PET + */ + void petShow(); + + /** + * Shows the text cursor in the current section, if applicable + */ + void petShowCursor(); + + /** + * Summon a bot + */ + void petOnSummonBot(const CString &name, int val); + + /*--- CStarControl Methods ---*/ + + /** + * Returns the star control + */ + CStarControl *getStarControl() const; + + void starFn1(int v); + void starFn2(); + + /*--- CTrueTalkManager Methods ---*/ + + /** + * Stop a conversation with the NPC + */ + void endTalking(CTrueTalkNPC *npc, bool viewFlag, CViewItem *view = nullptr); + + /** + * Start a conversation with the NPC + */ + void startTalking(CTrueTalkNPC *npc, uint id, CViewItem *view = nullptr); + + /** + * Start a conversation with the NPC + */ + void startTalking(const CString &name, uint id, CViewItem *view = nullptr); + + /** + * Sets a dial region for a given NPC + */ + void talkSetDialRegion(const CString &name, int dialNum, int regionNum); + + /** + * Gets a dial region for a given NPC + */ + int talkGetDialRegion(const CString &name, int dialNum); + + /*--- CVideoSurface Methods ---*/ + + /** + * Signal a movie event for the given frame + */ + void movieEvent(int frameNumber); + + /** + * Signal a movie event at the end of all currently + * playing ranges + */ + void movieEvent(); + + /*--- CGameState Methods ---*/ + + void setState1C(bool flag); + void stateInc14(); + int stateGet14() const; + void stateSet24(); + int stateGet24() const; + void stateInc38(); + int stateGet38() const; + + /** + * Gets the game state node changed counter + */ + uint getNodeChangedCtr() const; + + /** + * Gets the game state node enter ticks + */ + uint getNodeEnterTicks() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GAME_OBJECT_H */ diff --git a/engines/titanic/core/game_object_desc_item.cpp b/engines/titanic/core/game_object_desc_item.cpp new file mode 100644 index 0000000000..409334c9d7 --- /dev/null +++ b/engines/titanic/core/game_object_desc_item.cpp @@ -0,0 +1,57 @@ +/* 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 "titanic/core/game_object_desc_item.h" + +namespace Titanic { + +CGameObjectDescItem::CGameObjectDescItem(): CTreeItem() { +} + +void CGameObjectDescItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + _clipList.save(file, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + _list1.save(file, indent); + _list2.save(file, indent); + + CTreeItem::save(file, indent); +} + +void CGameObjectDescItem::load(SimpleFile *file) { + int val = file->readNumber(); + + if (val != 1) { + if (val) + _clipList.load(file); + + _string1 = file->readString(); + _string2 = file->readString(); + _list1.load(file); + _list1.load(file); + } + + CTreeItem::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/game_object_desc_item.h b/engines/titanic/core/game_object_desc_item.h new file mode 100644 index 0000000000..7bfecaf5a2 --- /dev/null +++ b/engines/titanic/core/game_object_desc_item.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_GAME_OBJECT_DESK_ITEM_H +#define TITANIC_GAME_OBJECT_DESK_ITEM_H + +#include "titanic/support/movie_clip.h" +#include "titanic/core/tree_item.h" +#include "titanic/core/list.h" + +namespace Titanic { + +class CGameObjectDescItem : public CTreeItem { +protected: + CString _string1; + CString _string2; + List<ListItem> _list1; + List<ListItem> _list2; + CMovieClipList _clipList; +public: + CLASSDEF; + CGameObjectDescItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GAME_OBJECT_DESK_ITEM_H */ diff --git a/engines/titanic/core/link_item.cpp b/engines/titanic/core/link_item.cpp new file mode 100644 index 0000000000..f77d081c61 --- /dev/null +++ b/engines/titanic/core/link_item.cpp @@ -0,0 +1,176 @@ +/* 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 "titanic/core/link_item.h" +#include "titanic/core/node_item.h" +#include "titanic/core/project_item.h" +#include "titanic/core/view_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CLinkItem, CNamedItem); + +CLinkItem::CLinkItem() : CNamedItem() { + _roomNumber = -1; + _nodeNumber = -1; + _viewNumber = -1; + _linkMode = 0; + _cursorId = CURSOR_ARROW; + _name = "Link"; +} + +CString CLinkItem::formName() { + CViewItem *view = findView(); + CNodeItem *node = view->findNode(); + CRoomItem *room = node->findRoom(); + + CViewItem *destView = getDestView(); + CNodeItem *destNode = destView->findNode(); + CRoomItem *destRoom = destNode->findRoom(); + + switch (_linkMode) { + case 1: + return CString::format("_PANL,%d,%s,%s", node->_nodeNumber, + view->getName().c_str(), destView->getName().c_str()); + + case 2: + return CString::format("_PANR,%d,%s,%s", node->_nodeNumber, + view->getName().c_str(), destView->getName().c_str()); + + case 3: + return CString::format("_TRACK,%d,%s,%d,%s", + node->_nodeNumber, view->getName().c_str(), + destNode->_nodeNumber, destView->getName().c_str()); + + case 4: + return CString::format("_EXIT,%d,%d,%s,%d,%d,%s", + room->_roomNumber, node->_nodeNumber, view->getName().c_str(), + destRoom->_roomNumber, destNode->_nodeNumber, destView->getName().c_str()); + + default: + return getName().c_str(); + } +} + +void CLinkItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(2, indent); + file->writeQuotedLine("L", indent); + file->writeNumberLine(_cursorId, indent + 1); + file->writeNumberLine(_linkMode, indent + 1); + file->writeNumberLine(_roomNumber, indent + 1); + file->writeNumberLine(_nodeNumber, indent + 1); + file->writeNumberLine(_viewNumber, indent + 1); + + file->writeQuotedLine("Hotspot", indent + 1); + file->writeNumberLine(_bounds.left, indent + 2); + file->writeNumberLine(_bounds.top, indent + 2); + file->writeNumberLine(_bounds.right, indent + 2); + file->writeNumberLine(_bounds.bottom, indent + 2); + + CNamedItem::save(file, indent); +} + +void CLinkItem::load(SimpleFile *file) { + int val = file->readNumber(); + file->readBuffer(); + + switch (val) { + case 2: + _cursorId = (CursorId)file->readNumber(); + // Deliberate fall-through + + case 1: + _linkMode = file->readNumber(); + // Deliberate fall-through + + case 0: + _roomNumber = file->readNumber(); + _nodeNumber = file->readNumber(); + _viewNumber = file->readNumber(); + + file->readBuffer(); + _bounds.left = file->readNumber(); + _bounds.top = file->readNumber(); + _bounds.right = file->readNumber(); + _bounds.bottom = file->readNumber(); + break; + + default: + break; + } + + CNamedItem::load(file); + + if (val < 2) { + switch (_linkMode) { + case 2: + _cursorId = CURSOR_MOVE_LEFT; + break; + case 3: + _cursorId = CURSOR_MOVE_RIGHT; + break; + case 5: + _cursorId = CURSOR_MOVE_FORWARD; + break; + default: + _cursorId = CURSOR_MOVE_FORWARD2; + break; + } + } +} + +bool CLinkItem::connectsTo(CViewItem *destView) const { + CNodeItem *destNode = destView->findNode(); + CRoomItem *destRoom = destNode->findRoom(); + + return _viewNumber == destView->_viewNumber && + _nodeNumber == destNode->_nodeNumber && + _roomNumber == destRoom->_roomNumber; +} + +void CLinkItem::setDestination(int roomNumber, int nodeNumber, + int viewNumber, int linkMode) { + _roomNumber = roomNumber; + _nodeNumber = nodeNumber; + _viewNumber = viewNumber; + _linkMode = linkMode; + + _name = formName(); +} + +CViewItem *CLinkItem::getDestView() const { + return getRoot()->findView(_roomNumber, _nodeNumber, _viewNumber); +} + +CNodeItem *CLinkItem::getDestNode() const { + return getDestView()->findNode(); +} + +CRoomItem *CLinkItem::getDestRoom() const { + return getDestNode()->findRoom(); +} + +CMovieClip *CLinkItem::getClip() const { + return findRoom()->findClip(getName()); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/link_item.h b/engines/titanic/core/link_item.h new file mode 100644 index 0000000000..dd93e2a0bf --- /dev/null +++ b/engines/titanic/core/link_item.h @@ -0,0 +1,100 @@ +/* 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 TITANIC_LINK_ITEM_H +#define TITANIC_LINK_ITEM_H + +#include "titanic/support/mouse_cursor.h" +#include "titanic/core/named_item.h" +#include "titanic/support/movie_clip.h" + +namespace Titanic { + +class CViewItem; +class CNodeItem; +class CRoomItem; + +class CLinkItem : public CNamedItem { + DECLARE_MESSAGE_MAP; +private: + /** + * Returns a new name for the link item, based on the + * current values for it's destination + */ + CString formName(); +protected: + int _roomNumber; + int _nodeNumber; + int _viewNumber; + int _linkMode; +public: + Rect _bounds; + CursorId _cursorId; +public: + CLASSDEF; + CLinkItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Returns true if the given item connects to another specified view + */ + virtual bool connectsTo(CViewItem *destView) const; + + /** + * Set the destination for the link item + */ + virtual void setDestination(int roomNumber, int nodeNumber, + int viewNumber, int linkMode); + + /** + * Get the destination view for the link item + */ + virtual CViewItem *getDestView() const; + + /** + * Get the destination node for the link item + */ + virtual CNodeItem *getDestNode() const; + + /** + * Get the destination view for the link item + */ + virtual CRoomItem *getDestRoom() const; + + /** + * Get the movie clip, if any, that's used when the link is used + */ + CMovieClip *getClip() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LINK_ITEM_H */ diff --git a/engines/titanic/core/list.cpp b/engines/titanic/core/list.cpp new file mode 100644 index 0000000000..8e90e9ff40 --- /dev/null +++ b/engines/titanic/core/list.cpp @@ -0,0 +1,35 @@ +/* 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 "titanic/core/list.h" + +namespace Titanic { + +void ListItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); +} + +void ListItem::load(SimpleFile *file) { + file->readNumber(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/list.h b/engines/titanic/core/list.h new file mode 100644 index 0000000000..91a74adbdc --- /dev/null +++ b/engines/titanic/core/list.h @@ -0,0 +1,164 @@ +/* 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 TITANIC_LIST_H +#define TITANIC_LIST_H + +#include "common/scummsys.h" +#include "common/list.h" +#include "titanic/support/simple_file.h" +#include "titanic/core/saveable_object.h" + +namespace Titanic { + +/** + * Base list item class + */ +class ListItem: public CSaveableObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +/** + * List item macro for managed pointers an item + */ +#define PTR_LIST_ITEM(T) class T##ListItem : public ListItem { \ + public: T *_item; \ + T##ListItem() : _item(nullptr) {} \ + T##ListItem(T *item) : _item(item) {} \ + virtual ~T##ListItem() { delete _item; } \ + } + +template<typename T> +class PtrListItem : public ListItem { +public: + T *_item; +public: + PtrListItem() : _item(nullptr) {} + PtrListItem(T *item) : _item(item) {} + virtual ~PtrListItem() { delete _item; } +}; + +template<typename T> +class List : public CSaveableObject, public Common::List<T *> { +public: + virtual ~List() { destroyContents(); } + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + + // Write out number of items + file->writeQuotedLine("L", indent); + file->writeNumberLine(Common::List<T *>::size(), indent); + + // Iterate through writing entries + typename Common::List<T *>::iterator i; + for (i = Common::List<T *>::begin(); i != Common::List<T *>::end(); ++i) { + ListItem *item = *i; + item->saveHeader(file, indent); + item->save(file, indent + 1); + item->saveFooter(file, indent); + } + + } + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file) { + file->readNumber(); + file->readBuffer(); + + Common::List<T *>::clear(); + uint count = file->readNumber(); + + for (uint idx = 0; idx < count; ++idx) { + // Validate the class start header + if (!file->IsClassStart()) + error("Unexpected class end"); + + // Get item's class name and use it to instantiate an item + CString className = file->readString(); + T *newItem = dynamic_cast<T *>(CSaveableObject::createInstance(className)); + if (!newItem) + error("Could not create instance of %s", className.c_str()); + + // Load the item's data and add it to the list + newItem->load(file); + Common::List<T *>::push_back(newItem); + + // Validate the class end footer + if (file->IsClassStart()) + error("Unexpected class start"); + } + } + + /** + * Clear the list and destroy any items in it + */ + void destroyContents() { + typename Common::List<T *>::iterator i; + for (i = Common::List<T *>::begin(); + i != Common::List<T *>::end(); ++i) { + CSaveableObject *obj = *i; + delete obj; + } + + Common::List<T *>::clear(); + } + + /** + * Add a new item to the list of the type the list contains + */ + T *add() { + T *item = new T(); + Common::List<T *>::push_back(item); + return item; + } + + bool contains(const T *item) const { + for (typename Common::List<T *>::const_iterator i = Common::List<T *>::begin(); + i != Common::List<T *>::end(); ++i) { + if (*i == item) + return true; + } + + return false; + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LIST_H */ diff --git a/engines/titanic/core/mail_man.cpp b/engines/titanic/core/mail_man.cpp new file mode 100644 index 0000000000..afe13bebad --- /dev/null +++ b/engines/titanic/core/mail_man.cpp @@ -0,0 +1,81 @@ +/* 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 "titanic/core/mail_man.h" + +namespace Titanic { + +void CMailMan::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CMailMan::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +CGameObject *CMailMan::getFirstObject() const { + return static_cast<CGameObject *>(getFirstChild()); +} + +CGameObject *CMailMan::getNextObject(CGameObject *prior) const { + if (!prior || prior->getParent() != this) + return nullptr; + + return static_cast<CGameObject *>(prior->getNextSibling()); +} + +void CMailMan::addMail(CGameObject *obj, int id) { + obj->detach(); + obj->addUnder(this); + setMailId(obj, id); +} + +void CMailMan::setMailId(CGameObject *obj, int id) { + obj->_id = id; + obj->_roomFlags = 0; + obj->_isMail = true; +} + +CGameObject *CMailMan::findMail(int id) const { + for (CGameObject *obj = getFirstObject(); obj; obj = getNextObject(obj)) { + if (obj->_isMail && obj->_id == id) + return obj; + } + + return nullptr; +} + +void CMailMan::removeMail(int id, int roomFlags) { + for (CGameObject *obj = getFirstObject(); obj; obj = getNextObject(obj)) { + if (obj->_isMail && obj->_id == id) { + obj->_isMail = false; + obj->_roomFlags = roomFlags; + break; + } + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/mail_man.h b/engines/titanic/core/mail_man.h new file mode 100644 index 0000000000..4c63cdfa13 --- /dev/null +++ b/engines/titanic/core/mail_man.h @@ -0,0 +1,84 @@ +/* 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 TITANIC_MAIL_MAN_H +#define TITANIC_MAIL_MAN_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CMailMan : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CMailMan() : CGameObject(), _value(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Get the first game object stored in the PET + */ + CGameObject *getFirstObject() const; + + /** + * Get the next game object stored in the PET following + * the passed game object + */ + CGameObject *getNextObject(CGameObject *prior) const; + + /** + * Add an object to the mail list + */ + void addMail(CGameObject *obj, int id); + + /** + * Sets the mail identifier for an object + */ + static void setMailId(CGameObject *obj, int id); + + /** + * Scan the mail list for a specified item + */ + CGameObject *findMail(int id) const; + + /** + * Remove a mail item + */ + void removeMail(int id, int v); + + void resetValue() { _value = 0; } +}; + + +} // End of namespace Titanic + +#endif /* TITANIC_MAIL_MAN_H */ diff --git a/engines/titanic/core/message_target.cpp b/engines/titanic/core/message_target.cpp new file mode 100644 index 0000000000..4815d03973 --- /dev/null +++ b/engines/titanic/core/message_target.cpp @@ -0,0 +1,50 @@ +/* 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 "titanic/core/message_target.h" + +namespace Titanic { + +const MSGMAP *CMessageTarget::getMessageMap() const { + return getThisMessageMap(); +} + +const MSGMAP *CMessageTarget::getThisMessageMap() { + static const MSGMAP_ENTRY _messageEntries[] = { + { (PMSG)nullptr, nullptr } + }; + + static const MSGMAP messageMap = { nullptr, &_messageEntries[0] }; + return &messageMap; +} + +void CMessageTarget::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + CSaveableObject::save(file, indent); +} + +void CMessageTarget::load(SimpleFile *file) { + file->readNumber(); + CSaveableObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/message_target.h b/engines/titanic/core/message_target.h new file mode 100644 index 0000000000..a382b6392d --- /dev/null +++ b/engines/titanic/core/message_target.h @@ -0,0 +1,104 @@ +/* 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 TITANIC_MESSAGE_TARGET_H +#define TITANIC_MESSAGE_TARGET_H + +#include "titanic/core/saveable_object.h" + +namespace Titanic { + +class CMessageTarget; +class CMessage; + +typedef bool (CMessageTarget::*PMSG)(CMessage *msg); + +struct MSGMAP_ENTRY { + PMSG _fn; + ClassDef *_class; +}; + +struct MSGMAP { + const MSGMAP *(* pFnGetBaseMap)(); + const MSGMAP_ENTRY *lpEntries; +}; + +#define DECLARE_MESSAGE_MAP \ +protected: \ + static const MSGMAP *getThisMessageMap(); \ + virtual const MSGMAP *getMessageMap() const + +#define BEGIN_MESSAGE_MAP(theClass, baseClass) \ + const MSGMAP *theClass::getMessageMap() const \ + { return getThisMessageMap(); } \ + const MSGMAP *theClass::getThisMessageMap() \ + { \ + typedef theClass ThisClass; \ + typedef baseClass TheBaseClass; \ + typedef bool (theClass::*FNPTR)(CMessage *msg); \ + static const MSGMAP_ENTRY _messageEntries[] = { + +#define ON_MESSAGE(msgClass) \ + { static_cast<PMSG>((FNPTR)&ThisClass::msgClass), C##msgClass::_type }, + +#define END_MESSAGE_MAP() \ + { (PMSG)nullptr, nullptr } \ + }; \ + static const MSGMAP messageMap = \ + { &TheBaseClass::getThisMessageMap, &_messageEntries[0] }; \ + return &messageMap; \ + } + +#define EMPTY_MESSAGE_MAP(theClass, baseClass) \ + const MSGMAP *theClass::getMessageMap() const \ + { return getThisMessageMap(); } \ + const MSGMAP *theClass::getThisMessageMap() \ + { \ + typedef baseClass TheBaseClass; \ + static const MSGMAP_ENTRY _messageEntries[] = { \ + { (PMSG)nullptr, nullptr } \ + }; \ + static const MSGMAP messageMap = \ + { &TheBaseClass::getThisMessageMap, &_messageEntries[0] }; \ + return &messageMap; \ + } \ + enum { DUMMY } + +class CMessageTarget: public CSaveableObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MESSAGE_TARGET_H */ diff --git a/engines/titanic/core/multi_drop_target.cpp b/engines/titanic/core/multi_drop_target.cpp new file mode 100644 index 0000000000..f2998199b1 --- /dev/null +++ b/engines/titanic/core/multi_drop_target.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/core/multi_drop_target.h" + +namespace Titanic { + +void CMultiDropTarget::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string5, indent); + file->writeQuotedLine(_string6, indent); + + CDropTarget::save(file, indent); +} + +void CMultiDropTarget::load(SimpleFile *file) { + file->readNumber(); + _string5 = file->readString(); + _string6 = file->readString(); + + CDropTarget::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/multi_drop_target.h b/engines/titanic/core/multi_drop_target.h new file mode 100644 index 0000000000..c004b9bece --- /dev/null +++ b/engines/titanic/core/multi_drop_target.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_MULTI_DROP_TARGET_H +#define TITANIC_MULTI_DROP_TARGET_H + +#include "titanic/core/drop_target.h" + +namespace Titanic { + +class CMultiDropTarget : public CDropTarget { +public: + CString _string5; + CString _string6; +public: + CLASSDEF; + CMultiDropTarget() : CDropTarget(), _string5("1,2") {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CLICK_RESPONDER_H */ diff --git a/engines/titanic/core/named_item.cpp b/engines/titanic/core/named_item.cpp new file mode 100644 index 0000000000..6eafbf8c8b --- /dev/null +++ b/engines/titanic/core/named_item.cpp @@ -0,0 +1,92 @@ +/* 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 "titanic/core/named_item.h" +#include "titanic/core/node_item.h" +#include "titanic/core/room_item.h" +#include "titanic/core/view_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CNamedItem, CTreeItem); + +CString CNamedItem::dumpItem(int indent) const { + CString result = CTreeItem::dumpItem(indent); + result += " " + _name; + + return result; +} + +void CNamedItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + file->writeQuotedLine(_name, indent); + + CTreeItem::save(file, indent); +} + +void CNamedItem::load(SimpleFile *file) { + int val = file->readNumber(); + if (!val) + _name = file->readString(); + + CTreeItem::load(file); +} + +int CNamedItem::compareTo(const CString &name, int maxLen) const { + if (maxLen) { + return getName().left(maxLen).compareToIgnoreCase(name); + } else { + return getName().compareToIgnoreCase(name); + } +} + +CViewItem *CNamedItem::findView() const { + for (CTreeItem *parent = getParent(); parent; parent = parent->getParent()) { + CViewItem *view = dynamic_cast<CViewItem *>(parent); + if (view) + return view; + } + + error("Couldn't find parent view"); +} + +CNodeItem *CNamedItem::findNode() const { + for (CTreeItem *parent = getParent(); parent; parent = parent->getParent()) { + CNodeItem *node = dynamic_cast<CNodeItem *>(parent); + if (node) + return node; + } + + error("Couldn't find parent node"); +} + +CRoomItem *CNamedItem::findRoom() const { + for (CTreeItem *parent = getParent(); parent; parent = parent->getParent()) { + CRoomItem *room = dynamic_cast<CRoomItem *>(parent); + if (room) + return room; + } + + error("Couldn't find parent node"); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/named_item.h b/engines/titanic/core/named_item.h new file mode 100644 index 0000000000..809cda1156 --- /dev/null +++ b/engines/titanic/core/named_item.h @@ -0,0 +1,84 @@ +/* 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 TITANIC_NAMED_ITEM_H +#define TITANIC_NAMED_ITEM_H + +#include "titanic/core/tree_item.h" + +namespace Titanic { + +class CViewItem; +class CNodeItem; +class CRoomItem; + +class CNamedItem: public CTreeItem { + DECLARE_MESSAGE_MAP; +public: + CString _name; +public: + CLASSDEF; + + /** + * Dump the item + */ + virtual CString dumpItem(int indent) const; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Gets the name of the item, if any + */ + virtual const CString getName() const { return _name; } + + /** + * Compares the name of the item to a passed name + */ + virtual int compareTo(const CString &name, int maxLen) const; + + /** + * Find a parent node for the item + */ + virtual CViewItem *findView() const; + + /** + * Find a parent node for the item + */ + virtual CNodeItem *findNode() const; + + /** + * Find a parent room item for the item + */ + virtual CRoomItem *findRoom() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NAMED_ITEM_H */ diff --git a/engines/titanic/core/node_item.cpp b/engines/titanic/core/node_item.cpp new file mode 100644 index 0000000000..85d3f548c0 --- /dev/null +++ b/engines/titanic/core/node_item.cpp @@ -0,0 +1,63 @@ +/* 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 "titanic/core/node_item.h" +#include "titanic/core/room_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CNodeItem, CNamedItem); + +CNodeItem::CNodeItem() : CNamedItem(), _nodeNumber(0) { +} + +void CNodeItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + file->writeQuotedLine("N", indent); + file->writeNumberLine(_nodePos.x, indent + 1); + file->writeNumberLine(_nodePos.y, indent + 1); + + file->writeQuotedLine("N", indent); + file->writeNumberLine(_nodeNumber, indent + 1); + + CNamedItem::save(file, indent); +} + +void CNodeItem::load(SimpleFile *file) { + file->readNumber(); + file->readBuffer(); + _nodePos.x = file->readNumber(); + _nodePos.y = file->readNumber(); + + file->readBuffer(); + _nodeNumber = file->readNumber(); + + CNamedItem::load(file); +} + +void CNodeItem::getPosition(double &xp, double &yp, double &zp) { + CRoomItem *room = findRoom(); + room->calcNodePosition(_nodePos, xp, yp); + zp = 0.0; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/node_item.h b/engines/titanic/core/node_item.h new file mode 100644 index 0000000000..ea403ddc3a --- /dev/null +++ b/engines/titanic/core/node_item.h @@ -0,0 +1,57 @@ +/* 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 TITANIC_NODE_ITEM_H +#define TITANIC_NODE_ITEM_H + +#include "titanic/core/named_item.h" + +namespace Titanic { + +class CNodeItem : public CNamedItem { + DECLARE_MESSAGE_MAP; +public: + int _nodeNumber; + Point _nodePos; +public: + CLASSDEF; + CNodeItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Gets the relative position of the node within the owning room + */ + void getPosition(double &xp, double &yp, double &zp); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FILE_ITEM_H */ diff --git a/engines/titanic/core/project_item.cpp b/engines/titanic/core/project_item.cpp new file mode 100644 index 0000000000..76293233b0 --- /dev/null +++ b/engines/titanic/core/project_item.cpp @@ -0,0 +1,549 @@ +/* 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/file.h" +#include "common/savefile.h" +#include "graphics/scaler.h" +#include "graphics/thumbnail.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" +#include "titanic/core/dont_save_file_item.h" +#include "titanic/core/node_item.h" +#include "titanic/core/project_item.h" +#include "titanic/core/view_item.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +#define CURRENT_SAVEGAME_VERSION 1 +#define MAX_SAVEGAME_SLOTS 99 +#define MINIMUM_SAVEGAME_VERSION 1 + +static const char *const SAVEGAME_STR = "TNIC"; +#define SAVEGAME_STR_SIZE 4 + +EMPTY_MESSAGE_MAP(CProjectItem, CFileItem); + +void CFileListItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + file->writeQuotedLine(_name, indent); + + ListItem::save(file, indent); +} + +void CFileListItem::load(SimpleFile *file) { + file->readNumber(); + _name = file->readString(); + + ListItem::load(file); +} + +/*------------------------------------------------------------------------*/ + +CProjectItem::CProjectItem() : _nextRoomNumber(0), _nextMessageNumber(0), + _nextObjectNumber(0), _gameManager(nullptr) { +} + +void CProjectItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(6, indent); + file->writeQuotedLine("Next Avail. Object Number", indent); + file->writeNumberLine(_nextObjectNumber, indent); + file->writeQuotedLine("Next Avail. Message Number", indent); + file->writeNumberLine(_nextMessageNumber, indent); + + file->writeQuotedLine("", indent); + _files.save(file, indent); + + file->writeQuotedLine("Next Avail. Room Number", indent); + file->writeNumberLine(_nextRoomNumber, indent); + + CTreeItem::save(file, indent); +} + +void CProjectItem::buildFilesList() { + _files.destroyContents(); + + CTreeItem *treeItem = getFirstChild(); + while (treeItem) { + if (treeItem->isFileItem()) { + CString name = static_cast<CFileItem *>(treeItem)->getFilename(); + _files.add()->_name = name; + } + + treeItem = getNextSibling(); + } +} + +void CProjectItem::load(SimpleFile *file) { + int val = file->readNumber(); + _files.destroyContents(); + int count; + + switch (val) { + case 1: + file->readBuffer(); + _nextRoomNumber = file->readNumber(); + // Deliberate fall-through + + case 0: + // Load the list of files + count = file->readNumber(); + for (int idx = 0; idx < count; ++idx) { + CString name = file->readString(); + _files.add()->_name = name; + } + break; + + case 6: + file->readBuffer(); + _nextObjectNumber = file->readNumber(); + // Deliberate fall-through + + case 5: + file->readBuffer(); + _nextMessageNumber = file->readNumber(); + // Deliberate fall-through + + case 4: + file->readBuffer(); + // Deliberate fall-through + + case 2: + case 3: + _files.load(file); + file->readBuffer(); + _nextRoomNumber = file->readNumber(); + break; + + default: + break; + } + + CTreeItem::load(file); +} + +CGameManager *CProjectItem::getGameManager() const { + return _gameManager; +} + +void CProjectItem::setGameManager(CGameManager *gameManager) { + if (!_gameManager) + _gameManager = gameManager; +} + +void CProjectItem::resetGameManager() { + _gameManager = nullptr; +} + +void CProjectItem::loadGame(int slotId) { + CompressedFile file; + + // Clear any existing project contents and call preload code + clear(); + preLoad(); + + // Open either an existing savegame slot or the new game template + if (slotId >= 0) { + Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( + g_vm->generateSaveName(slotId)); + file.open(saveFile); + } else { + Common::File *newFile = new Common::File(); + if (!newFile->open("newgame.st")) + error("Could not open newgame.st"); + file.open(newFile); + } + + // Load the savegame header in + TitanicSavegameHeader header; + readSavegameHeader(&file, header); + delete header._thumbnail; + + // Load the contents in + CProjectItem *newProject = loadData(&file); + file.IsClassStart(); + getGameManager()->load(&file); + + file.close(); + + // Clear existing project + clear(); + + // Detach each item under the loaded project, and re-attach them + // to the existing project instance (this) + CTreeItem *item; + while ((item = newProject->getFirstChild()) != nullptr) { + item->detach(); + item->addUnder(this); + } + + // Loaded project instance is no longer needed + newProject->destroyAll(); + + // Post-load processing + postLoad(); +} + +void CProjectItem::saveGame(int slotId, const CString &desc) { + CompressedFile file; + Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving( + g_vm->generateSaveName(slotId), false); + file.open(saveFile); + + // Signal the game is being saved + preSave(); + + // Write out the savegame header + TitanicSavegameHeader header; + header._saveName = desc; + writeSavegameHeader(&file, header); + + // Save the contents out + saveData(&file, this); + + // Save the game manager data + _gameManager->save(&file); + + // Close the file and signal that the saving has finished + file.close(); + postSave(); +} + +void CProjectItem::clear() { + CTreeItem *item; + while ((item = getFirstChild()) != nullptr) + item->destroyAll(); +} + +CProjectItem *CProjectItem::loadData(SimpleFile *file) { + if (!file->IsClassStart()) + return nullptr; + + CProjectItem *root = nullptr; + CTreeItem *parent = nullptr; + CTreeItem *item = nullptr; + + do { + CString entryString = file->readString(); + + if (entryString == "ALONG") { + // Move along, nothing needed + } else if (entryString == "UP") { + // Move up + if (parent == nullptr || + (parent = parent->getParent()) == nullptr) + break; + } else if (entryString == "DOWN") { + // Move down + if (parent == nullptr) + parent = item; + else + parent = parent->getLastChild(); + } else { + // Create new class instance + item = dynamic_cast<CTreeItem *>(CSaveableObject::createInstance(entryString)); + assert(item); + + if (root) { + // Already created root project + item->addUnder(parent); + } else { + root = dynamic_cast<CProjectItem *>(item); + assert(root); + root->_filename = _filename; + } + + // Load the data for the item + item->load(file); + } + + file->IsClassStart(); + } while (file->IsClassStart()); + + return root; +} + +void CProjectItem::saveData(SimpleFile *file, CTreeItem *item) const { + while (item) { + item->saveHeader(file, 0); + item->save(file, 1); + item->saveFooter(file, 0); + + CTreeItem *child = item->getFirstChild(); + if (child) { + file->write("\n{\n", 3); + file->writeQuotedString("DOWN"); + file->write("\n}\n", 3); + saveData(file, child); + file->write("\n{\n", 3); + file->writeQuotedString("UP"); + } else { + file->write("\n{\n", 3); + file->writeQuotedString("ALONG"); + } + + file->write("\n}\n", 3); + item = item->getNextSibling(); + } +} + +void CProjectItem::preLoad() { + if (_gameManager) + _gameManager->preLoad(); +} + +void CProjectItem::postLoad() { + CGameManager *gameManager = getGameManager(); + if (gameManager) + gameManager->postLoad(this); + + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->postLoad(); +} + +void CProjectItem::preSave() { + if (_gameManager) + _gameManager->preSave(this); +} + +void CProjectItem::postSave() { + if (_gameManager) + _gameManager->postSave(); +} + +CPetControl *CProjectItem::getPetControl() const { + CDontSaveFileItem *fileItem = getDontSaveFileItem(); + CTreeItem *treeItem; + + if (!fileItem || (treeItem = fileItem->getLastChild()) == nullptr) + return nullptr; + + while (treeItem) { + CPetControl *petControl = dynamic_cast<CPetControl *>(treeItem); + if (petControl) + return petControl; + + treeItem = treeItem->getPriorSibling(); + } + + return nullptr; +} + +CRoomItem *CProjectItem::findFirstRoom() const { + return dynamic_cast<CRoomItem *>(findChildInstance(CRoomItem::_type)); +} + +CTreeItem *CProjectItem::findChildInstance(ClassDef *classDef) const { + CTreeItem *treeItem = getFirstChild(); + if (treeItem == nullptr) + return nullptr; + + do { + CTreeItem *childItem = treeItem->getFirstChild(); + if (childItem) { + do { + if (childItem->isInstanceOf(classDef)) + return childItem; + } while ((childItem = childItem->getNextSibling()) != nullptr); + } + } while ((treeItem = treeItem->getNextSibling()) != nullptr); + + return nullptr; +} + +CRoomItem *CProjectItem::findNextRoom(CRoomItem *priorRoom) const { + return dynamic_cast<CRoomItem *>(findSiblingInstanceOf(CRoomItem::_type, priorRoom)); +} + +CTreeItem *CProjectItem::findSiblingInstanceOf(ClassDef *classDef, CTreeItem *startItem) const { + CTreeItem *treeItem = startItem->getParent()->getNextSibling(); + if (treeItem == nullptr) + return nullptr; + + return findChildInstance(classDef); +} + +CDontSaveFileItem *CProjectItem::getDontSaveFileItem() const { + for (CTreeItem *treeItem = getFirstChild(); treeItem; treeItem = treeItem->getNextSibling()) { + if (treeItem->isInstanceOf(CDontSaveFileItem::_type)) + return dynamic_cast<CDontSaveFileItem *>(treeItem); + } + + return nullptr; +} + +CRoomItem *CProjectItem::findHiddenRoom() { + return dynamic_cast<CRoomItem *>(findByName("HiddenRoom")); +} + +CViewItem *CProjectItem::findView(int roomNumber, int nodeNumber, int viewNumber) { + CTreeItem *treeItem = getFirstChild(); + CRoomItem *roomItem = nullptr; + + // Scan for the specified room + if (treeItem) { + do { + CTreeItem *childItem = treeItem->getFirstChild(); + CRoomItem *rItem = dynamic_cast<CRoomItem *>(childItem); + if (rItem && rItem->_roomNumber == roomNumber) { + roomItem = rItem; + break; + } + } while ((treeItem = treeItem->getNextSibling()) != nullptr); + } + if (!roomItem) + return nullptr; + + // Scan for the specified node within the room + CNodeItem *nodeItem = nullptr; + + CNodeItem *nItem = dynamic_cast<CNodeItem *>( + roomItem->findChildInstanceOf(CNodeItem::_type)); + for (; nItem && !nodeItem; nItem = dynamic_cast<CNodeItem *>( + findNextInstanceOf(CNodeItem::_type, nItem))) { + if (nItem->_nodeNumber == nodeNumber) + nodeItem = nItem; + } + if (!nodeItem) + return nullptr; + + // Scan for the specified view within the node + CViewItem *viewItem = dynamic_cast<CViewItem *>( + nodeItem->findChildInstanceOf(CViewItem::_type)); + for (; viewItem; viewItem = dynamic_cast<CViewItem *>( + findNextInstanceOf(CViewItem::_type, viewItem))) { + if (viewItem->_viewNumber == viewNumber) + return viewItem; + } + + return nullptr; +} + +SaveStateList CProjectItem::getSavegameList(const Common::String &target) { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray filenames; + Common::String saveDesc; + Common::String pattern = Common::String::format("%s.0??", target.c_str()); + TitanicSavegameHeader header; + + filenames = saveFileMan->listSavefiles(pattern); + sort(filenames.begin(), filenames.end()); // Sort to get the files in numerical order + + SaveStateList saveList; + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + const char *ext = strrchr(file->c_str(), '.'); + int slot = ext ? atoi(ext + 1) : -1; + + if (slot >= 0 && slot < MAX_SAVEGAME_SLOTS) { + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); + + if (in) { + SimpleFile f; + f.open(in); + if (!readSavegameHeader(&f, header)) + continue; + + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); + + header._thumbnail->free(); + delete header._thumbnail; + delete in; + } + } + } + + return saveList; +} + +bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header) { + char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; + header._thumbnail = nullptr; + + // Validate the header Id + file->unsafeRead(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); + if (strncmp(saveIdentBuffer, SAVEGAME_STR, SAVEGAME_STR_SIZE)) { + file->seek(-SAVEGAME_STR_SIZE, SEEK_CUR); + header._saveName = "Unnamed"; + return true; + } + + header._version = file->readByte(); + if (header._version < MINIMUM_SAVEGAME_VERSION || header._version > CURRENT_SAVEGAME_VERSION) + return false; + + // Read in the string + header._saveName.clear(); + char ch; + while ((ch = (char)file->readByte()) != '\0') header._saveName += ch; + + // Get the thumbnail + header._thumbnail = Graphics::loadThumbnail(*file); + if (!header._thumbnail) + return false; + + // Read in save date/time + header._year = file->readUint16LE(); + header._month = file->readUint16LE(); + header._day = file->readUint16LE(); + header._hour = file->readUint16LE(); + header._minute = file->readUint16LE(); + header._totalFrames = file->readUint32LE(); + + return true; +} + +void CProjectItem::writeSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header) { + // Write out a savegame header + file->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1); + + file->writeByte(CURRENT_SAVEGAME_VERSION); + + // Write savegame name + file->write(header._saveName.c_str(), header._saveName.size()); + file->writeByte('\0'); + + // Create a thumbnail of the screen and save it out + Graphics::Surface *thumb = createThumbnail(); + Graphics::saveThumbnail(*file, *thumb); + thumb->free(); + delete thumb; + + // Write out the save date/time + TimeDate td; + g_system->getTimeAndDate(td); + file->writeUint16LE(td.tm_year + 1900); + file->writeUint16LE(td.tm_mon + 1); + file->writeUint16LE(td.tm_mday); + file->writeUint16LE(td.tm_hour); + file->writeUint16LE(td.tm_min); + file->writeUint32LE(g_vm->_events->getFrameCounter()); +} + +Graphics::Surface *CProjectItem::createThumbnail() { + Graphics::Surface *thumb = new Graphics::Surface(); + + ::createThumbnailFromScreen(thumb); + return thumb; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/project_item.h b/engines/titanic/core/project_item.h new file mode 100644 index 0000000000..473ffd9556 --- /dev/null +++ b/engines/titanic/core/project_item.h @@ -0,0 +1,234 @@ +/* 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 TITANIC_PROJECT_ITEM_H +#define TITANIC_PROJECT_ITEM_H + +#include "common/scummsys.h" +#include "common/str.h" +#include "engines/savestate.h" +#include "graphics/surface.h" +#include "titanic/support/simple_file.h" +#include "titanic/core/dont_save_file_item.h" +#include "titanic/core/file_item.h" +#include "titanic/core/list.h" +#include "titanic/core/room_item.h" + +namespace Titanic { + +struct TitanicSavegameHeader { + uint8 _version; + CString _saveName; + Graphics::Surface *_thumbnail; + int _year, _month, _day; + int _hour, _minute; + int _totalFrames; +}; + + +class CGameManager; +class CPetControl; +class CViewItem; + +/** + * File list item + */ +class CFileListItem : public ListItem { +public: + CString _name; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +/** + * Filename list + */ +class CFileList: public List<CFileListItem> { +}; + +class CProjectItem : public CFileItem { + DECLARE_MESSAGE_MAP; +private: + CString _filename; + CFileList _files; + int _nextRoomNumber; + int _nextMessageNumber; + int _nextObjectNumber; + CGameManager *_gameManager; + + /** + * Called during save, iterates through the children to do some stuff + */ + void buildFilesList(); + + /** + * Called at the beginning of loading a game + */ + void preLoad(); + + /** + * Does post-loading processing + */ + void postLoad(); + + /** + * Called when a game is about to be saved + */ + void preSave(); + + /** + * Called when a game has finished being saved + */ + void postSave(); + + /** + * Finds the first child instance of a given class type + */ + CTreeItem *findChildInstance(ClassDef *classDef) const; + + /** + * Finds the next sibling occurance of a given class type + */ + CTreeItem *findSiblingInstanceOf(ClassDef *classDef, CTreeItem *startItem) const; +private: + /** + * Load project data from the passed file + */ + CProjectItem *loadData(SimpleFile *file); + + /** + * Save project data to the passed file + */ + void saveData(SimpleFile *file, CTreeItem *item) const; + + /** + * Creates a thumbnail for the current on-screen contents + */ + static Graphics::Surface *createThumbnail(); +public: + /** + * Load a list of savegames + */ + static SaveStateList getSavegameList(const Common::String &target); + + /** + * Write out the header information for a savegame + */ + static void writeSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header); + + /** + * Read in the header information for a savegame + */ + static bool readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header); +public: + CLASSDEF; + CProjectItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Get the game manager for the project + */ + virtual CGameManager *getGameManager() const; + + /** + * Sets the game manager for the project, if not already set + */ + void setGameManager(CGameManager *gameManager); + + /** + * Get a reference to the PET control + */ + CPetControl *getPetControl() const; + + /** + * Resets the game manager field + */ + void resetGameManager(); + + /** + * Load the entire project data for a given slot Id + */ + void loadGame(int slotId); + + /** + * Save the entire project data to a given savegame slot + */ + void saveGame(int slotId, const CString &desc); + + /** + * Clear any currently loaded project + */ + void clear(); + + /** + * Set the proejct's name + */ + void setFilename(const CString &name) { _filename = name; } + + /** + * Returns a reference to the first room item in the project + */ + CRoomItem *findFirstRoom() const; + + /** + * Returns a reference to the next room following the specified room + */ + CRoomItem *findNextRoom(CRoomItem *priorRoom) const; + + /** + * Returns the don't save file item, if it exists in the project + */ + CDontSaveFileItem *getDontSaveFileItem() const; + + /** + * Finds the hidden room node of the project + */ + CRoomItem *findHiddenRoom(); + + /** + * Finds a view + */ + CViewItem *findView(int roomNumber, int nodeNumber, int viewNumber); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PROJECT_ITEM_H */ diff --git a/engines/titanic/core/resource_key.cpp b/engines/titanic/core/resource_key.cpp new file mode 100644 index 0000000000..3b390af2d4 --- /dev/null +++ b/engines/titanic/core/resource_key.cpp @@ -0,0 +1,89 @@ +/* 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/file.h" +#include "titanic/titanic.h" +#include "titanic/support/simple_file.h" +#include "titanic/core/resource_key.h" + +namespace Titanic { + +void CResourceKey::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine("Resource Key...", indent); + file->writeQuotedLine(_key, indent); + + CSaveableObject::save(file, indent); +} + +void CResourceKey::load(SimpleFile *file) { + int val = file->readNumber(); + + if (val == 0 || val == 1) { + file->readBuffer(); + CString str = file->readString(); + setValue(str); + } + + CSaveableObject::load(file); +} + +void CResourceKey::setValue(const CString &name) { + CString nameStr = name; + nameStr.toLowercase(); + _key = nameStr; + + _value = nameStr; + int idx = _value.lastIndexOf('\\'); + if (idx >= 0) + _value = _value.mid(idx + 1); +} + +CString CResourceKey::exists() const { + CString name = _key; + + // Check for a resource being specified within an ST container + int idx = name.indexOf('#'); + if (idx >= 0) { + name = name.left(idx); + name += ".st"; + } + + // The original did tests for the file in the different + // asset paths, which aren't needed in ScummVM + Common::File f; + return f.exists(name) ? name : CString(); +} + +bool CResourceKey::scanForFile() const { + return g_vm->_filesManager->scanForFile(_value); +} + +FileType CResourceKey::fileTypeSuffix() const { + return _value.fileTypeSuffix(); +} + +ImageType CResourceKey::imageTypeSuffix() const { + return _value.imageTypeSuffix(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/resource_key.h b/engines/titanic/core/resource_key.h new file mode 100644 index 0000000000..27b23ed1e7 --- /dev/null +++ b/engines/titanic/core/resource_key.h @@ -0,0 +1,81 @@ +/* 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 TITANIC_RESOURCE_KEY_H +#define TITANIC_RESOURCE_KEY_H + +#include "titanic/support/string.h" +#include "titanic/core/saveable_object.h" + +namespace Titanic { + +class CResourceKey: public CSaveableObject { +private: + CString _key; + CString _value; + + void setValue(const CString &name); +public: + CLASSDEF; + CResourceKey() {} + CResourceKey(const CString &name) { setValue(name); } + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Return the key + */ + const CString &getString() const { return _key; } + + /** + * Checks whether a file for the given key exists, + * and returns it's filename if it does + */ + CString exists() const; + + /** + * Scans for a file with a matching name + */ + bool scanForFile() const; + + /** + * Returns the type of the resource based on it's extension + */ + FileType fileTypeSuffix() const; + + /** + * Returns the type of the resource based on it's extension + */ + ImageType imageTypeSuffix() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_RESOURCE_KEY_H */ diff --git a/engines/titanic/core/room_item.cpp b/engines/titanic/core/room_item.cpp new file mode 100644 index 0000000000..541a8e1a9e --- /dev/null +++ b/engines/titanic/core/room_item.cpp @@ -0,0 +1,198 @@ +/* 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 "titanic/core/room_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CRoomItem, CNamedItem); + +CRoomItem::CRoomItem() : CNamedItem(), _roomNumber(0), + _roomDimensionX(0.0), _roomDimensionY(0.0) { +} + +void CRoomItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(3, indent); + file->writeQuotedLine("Exit Movies", indent); + _exitMovieKey.save(file, indent); + + file->writeQuotedLine("Room dimensions x 1000", indent); + file->writeNumberLine(_roomDimensionX * 1000.0, indent + 1); + file->writeNumberLine(_roomDimensionY * 1000.0, indent + 1); + + file->writeQuotedLine("Transition Movie", indent); + _transitionMovieKey.save(file, indent); + + file->writeQuotedLine("Movie Clip list", indent); + _clipList.save(file, indent + 1); + + file->writeQuotedLine("Room Rect", indent); + file->writeNumberLine(_roomRect.left, indent + 1); + file->writeNumberLine(_roomRect.top, indent + 1); + file->writeNumberLine(_roomRect.right, indent + 1); + file->writeNumberLine(_roomRect.bottom, indent + 1); + + file->writeQuotedLine("Room Number", indent); + file->writeNumberLine(_roomNumber, indent); + + CNamedItem::save(file, indent); +} + +void CRoomItem::load(SimpleFile *file) { + int val = file->readNumber(); + + switch (val) { + case 3: + // Read exit movie + file->readBuffer(); + _exitMovieKey.load(file); + // Deliberate fall-through + + case 2: + // Read room dimensions + file->readBuffer(); + _roomDimensionX = (double)file->readNumber() / 1000.0; + _roomDimensionY = (double)file->readNumber() / 1000.0; + // Deliberate fall-through + + case 1: + // Read transition movie key and clip list + file->readBuffer(); + _transitionMovieKey.load(file); + + file->readBuffer(); + _clipList.load(file); + postLoad(); + // Deliberate fall-through + + case 0: + // Read room rect + file->readBuffer(); + _roomRect.left = file->readNumber(); + _roomRect.top = file->readNumber(); + _roomRect.right = file->readNumber(); + _roomRect.bottom = file->readNumber(); + file->readBuffer(); + _roomNumber = file->readNumber(); + break; + + default: + break; + } + + CNamedItem::load(file); +} + +void CRoomItem::postLoad() { + if (!_exitMovieKey.exists().empty()) + return; + + CString name = _transitionMovieKey.exists(); + if (name.right(7) == "nav.avi") { + _exitMovieKey = CResourceKey(name.left(name.size() - 7) + "exit.avi"); + } +} + +void CRoomItem::calcNodePosition(const Point &nodePos, double &xVal, double &yVal) const { + xVal = yVal = 0.0; + + if (_roomDimensionX >= 0.0 && _roomDimensionY >= 0.0) { + xVal = _roomRect.width() / _roomDimensionX; + yVal = _roomRect.height() / _roomDimensionY; + + xVal = (nodePos.x - _roomRect.left) / xVal; + yVal = (nodePos.y - _roomRect.top) / yVal; + } +} + +int CRoomItem::getScriptId() const { + CString name = getName(); + if (name == "1stClassLobby") + return 130; + else if (name == "1stClassRestaurant") + return 132; + else if (name == "1stClassState") + return 131; + else if (name == "2ndClassLobby") + return 128; + else if (name == "Bar") + return 112; + else if (name == "BottomOfWell") + return 108; + else if (name == "Bridge") + return 121; + else if (name == "Dome") + return 122; + else if (name == "Home") + return 100; + else if (name == "Lift") + return 103; + else if (name == "MusicRoom") + return 117; + else if (name == "MusicRoomLobby") + return 118; + else if (name == "ParrotLobby") + return 111; + else if (name == "Pellerator") + return 104; + else if (name == "PromenadeDeck") + return 114; + else if (name == "SculptureChamber") + return 116; + else if (name == "secClassState") + return 129; + else if (name == "ServiceElevator") + return 102; + else if (name == "SGTLeisure") + return 125; + else if (name == "SGTLittleLift") + return 105; + else if (name == "SgtLobby") + return 124; + else if (name == "SGTState") + return 126; + else if (name == "Titania") + return 123; + else if (name == "TopOfWell") + return 107; + else if (name == "EmbLobby" || name == "MoonEmbLobby") + return 110; + else if (name == "CreatorsChamber" || name == "CreatorsChamberOn") + return 113; + else if (name == "Arboretum" || name == "FrozenArboretum") + return 115; + else if (name == "BilgeRoom" || name == "BilgeRoomWith") + return 101; + + return 0; +} + +CResourceKey CRoomItem::getTransitionMovieKey() { + _transitionMovieKey.scanForFile(); + return _transitionMovieKey; +} + +CResourceKey CRoomItem::getExitMovieKey() { + return _exitMovieKey; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/room_item.h b/engines/titanic/core/room_item.h new file mode 100644 index 0000000000..cb343a15d2 --- /dev/null +++ b/engines/titanic/core/room_item.h @@ -0,0 +1,84 @@ +/* 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 TITANIC_ROOM_ITEM_H +#define TITANIC_ROOM_ITEM_H + +#include "titanic/support/rect.h" +#include "titanic/core/list.h" +#include "titanic/support/movie_clip.h" +#include "titanic/core/named_item.h" +#include "titanic/core/resource_key.h" + +namespace Titanic { + +class CRoomItem : public CNamedItem { + DECLARE_MESSAGE_MAP; +private: + /** + * Handles post-load processing + */ + void postLoad(); +public: + Rect _roomRect; + CMovieClipList _clipList; + int _roomNumber; + CResourceKey _transitionMovieKey; + CResourceKey _exitMovieKey; + double _roomDimensionX, _roomDimensionY; +public: + CLASSDEF; + CRoomItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Return a movie clip for the room by name + */ + CMovieClip *findClip(const CString &name) { return _clipList.findByName(name); } + + /** + * Calculates the positioning of a node within the overall room + */ + void calcNodePosition(const Point &nodePos, double &xVal, double &yVal) const; + + /** + * Get the TrueTalk script Id associated with the room + */ + int getScriptId() const; + + CResourceKey getTransitionMovieKey(); + + CResourceKey getExitMovieKey(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ROOM_ITEM_H */ diff --git a/engines/titanic/core/saveable_object.cpp b/engines/titanic/core/saveable_object.cpp new file mode 100644 index 0000000000..62cee47045 --- /dev/null +++ b/engines/titanic/core/saveable_object.cpp @@ -0,0 +1,1642 @@ +/* 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 "titanic/carry/arm.h" +#include "titanic/carry/auditory_centre.h" +#include "titanic/carry/bowl_ear.h" +#include "titanic/carry/brain.h" +#include "titanic/carry/bridge_piece.h" +#include "titanic/carry/carry.h" +#include "titanic/carry/carry_parrot.h" +#include "titanic/carry/central_core.h" +#include "titanic/carry/chicken.h" +#include "titanic/carry/crushed_tv.h" +#include "titanic/carry/eye.h" +#include "titanic/carry/feathers.h" +#include "titanic/carry/fruit.h" +#include "titanic/carry/glass.h" +#include "titanic/carry/hammer.h" +#include "titanic/carry/head_piece.h" +#include "titanic/carry/hose.h" +#include "titanic/carry/hose_end.h" +#include "titanic/carry/key.h" +#include "titanic/carry/liftbot_head.h" +#include "titanic/carry/long_stick.h" +#include "titanic/carry/magazine.h" +#include "titanic/carry/maitred_left_arm.h" +#include "titanic/carry/maitred_right_arm.h" +#include "titanic/carry/mouth.h" +#include "titanic/carry/napkin.h" +#include "titanic/carry/nose.h" +#include "titanic/carry/note.h" +#include "titanic/carry/parcel.h" +#include "titanic/carry/perch.h" +#include "titanic/carry/phonograph_cylinder.h" +#include "titanic/carry/phonograph_ear.h" +#include "titanic/carry/photograph.h" +#include "titanic/carry/plug_in.h" +#include "titanic/carry/speech_centre.h" +#include "titanic/carry/sweets.h" +#include "titanic/carry/vision_centre.h" + +#include "titanic/core/saveable_object.h" +#include "titanic/core/background.h" +#include "titanic/core/click_responder.h" +#include "titanic/core/dont_save_file_item.h" +#include "titanic/core/drop_target.h" +#include "titanic/core/file_item.h" +#include "titanic/core/game_object.h" +#include "titanic/core/game_object_desc_item.h" +#include "titanic/core/link_item.h" +#include "titanic/core/list.h" +#include "titanic/core/mail_man.h" +#include "titanic/core/message_target.h" +#include "titanic/support/movie_clip.h" +#include "titanic/core/multi_drop_target.h" +#include "titanic/core/node_item.h" +#include "titanic/core/project_item.h" +#include "titanic/core/room_item.h" +#include "titanic/core/saveable_object.h" +#include "titanic/core/static_image.h" +#include "titanic/core/turn_on_object.h" +#include "titanic/core/turn_on_play_sound.h" +#include "titanic/core/turn_on_turn_off.h" +#include "titanic/core/tree_item.h" +#include "titanic/core/view_item.h" + +#include "titanic/game/announce.h" +#include "titanic/game/annoy_barbot.h" +#include "titanic/game/arb_background.h" +#include "titanic/game/arboretum_gate.h" +#include "titanic/game/auto_animate.h" +#include "titanic/game/bar_bell.h" +#include "titanic/game/bar_menu.h" +#include "titanic/game/bar_menu_button.h" +#include "titanic/game/belbot_get_light.h" +#include "titanic/game/bilge_succubus.h" +#include "titanic/game/bomb.h" +#include "titanic/game/bottom_of_well_monitor.h" +#include "titanic/game/bowl_unlocker.h" +#include "titanic/game/brain_slot.h" +#include "titanic/game/bridge_door.h" +#include "titanic/game/bridge_view.h" +#include "titanic/game/broken_pell_base.h" +#include "titanic/game/broken_pellerator.h" +#include "titanic/game/broken_pellerator_froz.h" +#include "titanic/game/cage.h" +#include "titanic/game/call_pellerator.h" +#include "titanic/game/captains_wheel.h" +#include "titanic/game/cdrom.h" +#include "titanic/game/cdrom_computer.h" +#include "titanic/game/cdrom_tray.h" +#include "titanic/game/cell_point_button.h" +#include "titanic/game/chev_code.h" +#include "titanic/game/chev_panel.h" +#include "titanic/game/chicken_cooler.h" +#include "titanic/game/chicken_dispensor.h" +#include "titanic/game/close_broken_pel.h" +#include "titanic/game/computer.h" +#include "titanic/game/computer_screen.h" +#include "titanic/game/code_wheel.h" +#include "titanic/game/cookie.h" +#include "titanic/game/credits.h" +#include "titanic/game/credits_button.h" +#include "titanic/game/dead_area.h" +#include "titanic/game/desk_click_responder.h" +#include "titanic/game/doorbot_elevator_handler.h" +#include "titanic/game/doorbot_home_handler.h" +#include "titanic/game/ear_sweet_bowl.h" +#include "titanic/game/eject_phonograph_button.h" +#include "titanic/game/elevator_action_area.h" +#include "titanic/game/emma_control.h" +#include "titanic/game/empty_nut_bowl.h" +#include "titanic/game/end_credit_text.h" +#include "titanic/game/end_credits.h" +#include "titanic/game/end_explode_ship.h" +#include "titanic/game/end_game_credits.h" +#include "titanic/game/end_sequence_control.h" +#include "titanic/game/fan.h" +#include "titanic/game/fan_control.h" +#include "titanic/game/fan_decrease.h" +#include "titanic/game/fan_increase.h" +#include "titanic/game/fan_noises.h" +#include "titanic/game/floor_indicator.h" +#include "titanic/game/games_console.h" +#include "titanic/game/get_lift_eye2.h" +#include "titanic/game/glass_smasher.h" +#include "titanic/game/hammer_clip.h" +#include "titanic/game/hammer_dispensor.h" +#include "titanic/game/hammer_dispensor_button.h" +#include "titanic/game/head_slot.h" +#include "titanic/game/head_smash_event.h" +#include "titanic/game/head_smash_lever.h" +#include "titanic/game/head_spinner.h" +#include "titanic/game/idle_summoner.h" +#include "titanic/game/leave_sec_class_state.h" +#include "titanic/game/lemon_dispensor.h" +#include "titanic/game/light.h" +#include "titanic/game/light_switch.h" +#include "titanic/game/little_lift_button.h" +#include "titanic/game/long_stick_dispenser.h" +#include "titanic/game/missiveomat.h" +#include "titanic/game/missiveomat_button.h" +#include "titanic/game/movie_tester.h" +#include "titanic/game/musical_instrument.h" +#include "titanic/game/music_console_button.h" +#include "titanic/game/music_room_phonograph.h" +#include "titanic/game/music_room_stop_phonograph_button.h" +#include "titanic/game/music_system_lock.h" +#include "titanic/game/nav_helmet.h" +#include "titanic/game/navigation_computer.h" +#include "titanic/game/no_nut_bowl.h" +#include "titanic/game/nose_holder.h" +#include "titanic/game/null_port_hole.h" +#include "titanic/game/nut_replacer.h" +#include "titanic/game/pet_disabler.h" +#include "titanic/game/phonograph.h" +#include "titanic/game/phonograph_lid.h" +#include "titanic/game/play_music_button.h" +#include "titanic/game/play_on_act.h" +#include "titanic/game/port_hole.h" +#include "titanic/game/record_phonograph_button.h" +#include "titanic/game/replacement_ear.h" +#include "titanic/game/reserved_table.h" +#include "titanic/game/restaurant_cylinder_holder.h" +#include "titanic/game/restaurant_phonograph.h" +#include "titanic/game/sauce_dispensor.h" +#include "titanic/game/search_point.h" +#include "titanic/game/season_background.h" +#include "titanic/game/season_barrel.h" +#include "titanic/game/seasonal_adjustment.h" +#include "titanic/game/service_elevator_window.h" +#include "titanic/game/ship_setting.h" +#include "titanic/game/ship_setting_button.h" +#include "titanic/game/show_cell_points.h" +#include "titanic/game/speech_dispensor.h" +#include "titanic/game/splash_animation.h" +#include "titanic/game/starling_puret.h" +#include "titanic/game/start_action.h" +#include "titanic/game/stop_phonograph_button.h" +#include "titanic/game/sub_glass.h" +#include "titanic/game/sub_wrapper.h" +#include "titanic/game/sweet_bowl.h" +#include "titanic/game/television.h" +#include "titanic/game/third_class_canal.h" +#include "titanic/game/throw_tv_down_well.h" +#include "titanic/game/titania_still_control.h" +#include "titanic/game/tow_parrot_nav.h" +#include "titanic/game/up_lighter.h" +#include "titanic/game/useless_lever.h" +#include "titanic/game/volume_control.h" +#include "titanic/game/wheel_button.h" +#include "titanic/game/wheel_hotspot.h" +#include "titanic/game/wheel_spin.h" +#include "titanic/game/wheel_spin_horn.h" +#include "titanic/game/gondolier/gondolier_base.h" +#include "titanic/game/gondolier/gondolier_chest.h" +#include "titanic/game/gondolier/gondolier_face.h" +#include "titanic/game/gondolier/gondolier_mixer.h" +#include "titanic/game/gondolier/gondolier_slider.h" +#include "titanic/game/maitred/maitred_arm_holder.h" +#include "titanic/game/maitred/maitred_body.h" +#include "titanic/game/maitred/maitred_legs.h" +#include "titanic/game/maitred/maitred_prod_receptor.h" +#include "titanic/game/parrot/parrot_lobby_controller.h" +#include "titanic/game/parrot/parrot_lobby_link_updater.h" +#include "titanic/game/parrot/parrot_lobby_object.h" +#include "titanic/game/parrot/parrot_lobby_view_object.h" +#include "titanic/game/parrot/parrot_loser.h" +#include "titanic/game/parrot/parrot_nut_bowl_actor.h" +#include "titanic/game/parrot/parrot_nut_eater.h" +#include "titanic/game/parrot/parrot_perch_holder.h" +#include "titanic/game/parrot/parrot_succubus.h" +#include "titanic/game/parrot/parrot_trigger.h" +#include "titanic/game/parrot/player_meets_parrot.h" +#include "titanic/game/pet/pet.h" +#include "titanic/game/pet/pet_class1.h" +#include "titanic/game/pet/pet_class2.h" +#include "titanic/game/pet/pet_class3.h" +#include "titanic/game/pet/pet_lift.h" +#include "titanic/game/pet/pet_monitor.h" +#include "titanic/game/pet/pet_pellerator.h" +#include "titanic/game/pet/pet_position.h" +#include "titanic/game/pet/pet_sentinal.h" +#include "titanic/game/pet/pet_sounds.h" +#include "titanic/game/pet/pet_transition.h" +#include "titanic/game/pet/pet_transport.h" +#include "titanic/game/pickup/pick_up.h" +#include "titanic/game/pickup/pick_up_bar_glass.h" +#include "titanic/game/pickup/pick_up_hose.h" +#include "titanic/game/pickup/pick_up_lemon.h" +#include "titanic/game/pickup/pick_up_speech_centre.h" +#include "titanic/game/pickup/pick_up_vis_centre.h" +#include "titanic/game/placeholder/bar_shelf_vis_centre.h" +#include "titanic/game/placeholder/lemon_on_bar.h" +#include "titanic/game/placeholder/place_holder_item.h" +#include "titanic/game/placeholder/tv_on_bar.h" +#include "titanic/game/sgt/armchair.h" +#include "titanic/game/sgt/basin.h" +#include "titanic/game/sgt/bedfoot.h" +#include "titanic/game/sgt/bedhead.h" +#include "titanic/game/sgt/chest_of_drawers.h" +#include "titanic/game/sgt/desk.h" +#include "titanic/game/sgt/deskchair.h" +#include "titanic/game/sgt/drawer.h" +#include "titanic/game/sgt/sgt_doors.h" +#include "titanic/game/sgt/sgt_nav.h" +#include "titanic/game/sgt/sgt_navigation.h" +#include "titanic/game/sgt/sgt_restaurant_doors.h" +#include "titanic/game/sgt/sgt_state_control.h" +#include "titanic/game/sgt/sgt_state_room.h" +#include "titanic/game/sgt/sgt_tv.h" +#include "titanic/game/sgt/sgt_upper_doors_sound.h" +#include "titanic/game/sgt/toilet.h" +#include "titanic/game/sgt/vase.h" +#include "titanic/game/sgt/washstand.h" +#include "titanic/game/transport/gondolier.h" +#include "titanic/game/transport/lift.h" +#include "titanic/game/transport/lift_indicator.h" +#include "titanic/game/transport/pellerator.h" +#include "titanic/game/transport/service_elevator.h" +#include "titanic/game/transport/transport.h" +#include "titanic/gfx/act_button.h" +#include "titanic/gfx/changes_season_button.h" +#include "titanic/gfx/chev_left_off.h" +#include "titanic/gfx/chev_left_on.h" +#include "titanic/gfx/chev_right_off.h" +#include "titanic/gfx/chev_right_on.h" +#include "titanic/gfx/chev_send_rec_switch.h" +#include "titanic/gfx/chev_switch.h" +#include "titanic/gfx/edit_control.h" +#include "titanic/gfx/elevator_button.h" +#include "titanic/gfx/get_from_succ.h" +#include "titanic/gfx/helmet_on_off.h" +#include "titanic/gfx/home_photo.h" +#include "titanic/gfx/icon_nav_action.h" +#include "titanic/gfx/icon_nav_butt.h" +#include "titanic/gfx/icon_nav_down.h" +#include "titanic/gfx/icon_nav_image.h" +#include "titanic/gfx/icon_nav_left.h" +#include "titanic/gfx/icon_nav_receive.h" +#include "titanic/gfx/icon_nav_right.h" +#include "titanic/gfx/icon_nav_send.h" +#include "titanic/gfx/icon_nav_up.h" +#include "titanic/gfx/keybrd_butt.h" +#include "titanic/gfx/move_object_button.h" +#include "titanic/gfx/music_control.h" +#include "titanic/gfx/music_slider_pitch.h" +#include "titanic/gfx/music_slider_speed.h" +#include "titanic/gfx/music_switch.h" +#include "titanic/gfx/music_switch_inversion.h" +#include "titanic/gfx/music_switch_reverse.h" +#include "titanic/gfx/music_voice_mute.h" +#include "titanic/gfx/send_to_succ.h" +#include "titanic/gfx/sgt_selector.h" +#include "titanic/gfx/slider_button.h" +#include "titanic/gfx/small_chev_left_off.h" +#include "titanic/gfx/small_chev_left_on.h" +#include "titanic/gfx/small_chev_right_off.h" +#include "titanic/gfx/small_chev_right_on.h" +#include "titanic/gfx/status_change_button.h" +#include "titanic/gfx/st_button.h" +#include "titanic/gfx/toggle_button.h" +#include "titanic/gfx/text_down.h" +#include "titanic/gfx/text_skrew.h" +#include "titanic/gfx/text_up.h" +#include "titanic/gfx/toggle_switch.h" + +#include "titanic/messages/messages.h" +#include "titanic/messages/auto_sound_event.h" +#include "titanic/messages/bilge_auto_sound_event.h" +#include "titanic/messages/bilge_dispensor_event.h" +#include "titanic/messages/door_auto_sound_event.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/messages/pet_messages.h" +#include "titanic/messages/service_elevator_door.h" + +#include "titanic/moves/enter_bomb_room.h" +#include "titanic/moves/enter_bridge.h" +#include "titanic/moves/enter_exit_first_class_state.h" +#include "titanic/moves/enter_exit_mini_lift.h" +#include "titanic/moves/enter_exit_sec_class_mini_lift.h" +#include "titanic/moves/enter_exit_view.h" +#include "titanic/moves/enter_sec_class_state.h" +#include "titanic/moves/exit_arboretum.h" +#include "titanic/moves/exit_bridge.h" +#include "titanic/moves/exit_lift.h" +#include "titanic/moves/exit_pellerator.h" +#include "titanic/moves/exit_state_room.h" +#include "titanic/moves/exit_tiania.h" +#include "titanic/moves/move_player_in_parrot_room.h" +#include "titanic/moves/move_player_to.h" +#include "titanic/moves/move_player_to_from.h" +#include "titanic/moves/multi_move.h" +#include "titanic/moves/pan_from_pel.h" +#include "titanic/moves/restaurant_pan_handler.h" +#include "titanic/moves/restricted_move.h" +#include "titanic/moves/scraliontis_table.h" +#include "titanic/moves/trip_down_canal.h" + +#include "titanic/npcs/barbot.h" +#include "titanic/npcs/bellbot.h" +#include "titanic/npcs/callbot.h" +#include "titanic/npcs/deskbot.h" +#include "titanic/npcs/doorbot.h" +#include "titanic/npcs/liftbot.h" +#include "titanic/npcs/maitre_d.h" +#include "titanic/npcs/mobile.h" +#include "titanic/npcs/parrot.h" +#include "titanic/npcs/starlings.h" +#include "titanic/npcs/succubus.h" +#include "titanic/npcs/summon_bots.h" +#include "titanic/npcs/titania.h" +#include "titanic/npcs/true_talk_npc.h" + +#include "titanic/pet_control/pet_control.h" +#include "titanic/pet_control/pet_drag_chev.h" +#include "titanic/pet_control/pet_graphic.h" +#include "titanic/pet_control/pet_graphic2.h" +#include "titanic/pet_control/pet_leaf.h" +#include "titanic/pet_control/pet_mode_off.h" +#include "titanic/pet_control/pet_mode_on.h" +#include "titanic/pet_control/pet_mode_panel.h" +#include "titanic/pet_control/pet_pannel1.h" +#include "titanic/pet_control/pet_pannel2.h" +#include "titanic/pet_control/pet_pannel3.h" + +#include "titanic/sound/auto_music_player.h" +#include "titanic/sound/auto_music_player_base.h" +#include "titanic/sound/auto_sound_player.h" +#include "titanic/sound/auto_sound_player_adsr.h" +#include "titanic/sound/background_sound_maker.h" +#include "titanic/sound/bird_song.h" +#include "titanic/sound/dome_from_top_of_well.h" +#include "titanic/sound/gondolier_song.h" +#include "titanic/sound/enter_view_toggles_other_music.h" +#include "titanic/sound/music_player.h" +#include "titanic/sound/node_auto_sound_player.h" +#include "titanic/sound/restricted_auto_music_player.h" +#include "titanic/sound/room_auto_sound_player.h" +#include "titanic/sound/room_trigger_auto_music_player.h" +#include "titanic/sound/season_noises.h" +#include "titanic/sound/seasonal_music_player.h" +#include "titanic/sound/titania_speech.h" +#include "titanic/sound/trigger_auto_music_player.h" +#include "titanic/sound/view_auto_sound_player.h" +#include "titanic/sound/view_toggles_other_music.h" +#include "titanic/sound/water_lapping_sounds.h" + +#include "titanic/star_control/star_control.h" +#include "titanic/support/time_event_info.h" + +namespace Titanic { + +CSaveableObject *ClassDef::create() { + return new CSaveableObject(); +} + +/*------------------------------------------------------------------------*/ + +Common::HashMap<Common::String, CSaveableObject::CreateFunction> * + CSaveableObject::_classList = nullptr; +Common::List<ClassDef *> *CSaveableObject::_classDefs; + +#define DEFFN(T) CSaveableObject *Function##T() { return new T(); } \ + ClassDef *T::_type +#define ADDFN(CHILD, PARENT) \ + CHILD::_type = new TypeTemplate<CHILD>(#CHILD, PARENT::_type); \ + (*_classList)[#CHILD] = Function##CHILD + +DEFFN(CArm); +DEFFN(CAuditoryCentre); +DEFFN(CBowlEar); +DEFFN(CBrain); +DEFFN(CBridgePiece); +DEFFN(CCarry); +DEFFN(CCarryParrot); +DEFFN(CCentralCore); +DEFFN(CChicken); +DEFFN(CCrushedTV); +DEFFN(CEar); +DEFFN(CEye); +DEFFN(CFeathers); +DEFFN(CFruit); +DEFFN(CGlass); +DEFFN(CHammer); +DEFFN(CHeadPiece); +DEFFN(CHose); +DEFFN(CHoseEnd); +DEFFN(CKey); +DEFFN(CLiftbotHead); +DEFFN(CLongStick); +DEFFN(CMagazine); +DEFFN(CMaitreDLeftArm); +DEFFN(CMaitreDRightArm); +DEFFN(CMouth); +DEFFN(CNapkin); +DEFFN(CNose); +DEFFN(CNote); +DEFFN(CParcel); +DEFFN(CPerch); +DEFFN(CPhonographCylinder); +DEFFN(CPhonographEar); +DEFFN(CPhotograph); +DEFFN(CPlugIn); +DEFFN(CSpeechCentre); +DEFFN(CSweets); +DEFFN(CVisionCentre); + +DEFFN(CBackground); +DEFFN(CClickResponder); +DEFFN(CDontSaveFileItem); +DEFFN(CDropTarget); +DEFFN(CFileItem); +DEFFN(CFileListItem); +DEFFN(CGameObject); +DEFFN(CGameObjectDescItem); +DEFFN(CLinkItem); +DEFFN(ListItem); +DEFFN(CMailMan); +DEFFN(CMessageTarget); +DEFFN(CMovieClip); +DEFFN(CMultiDropTarget); +DEFFN(CNamedItem); +DEFFN(CNodeItem); +DEFFN(CProjectItem); +DEFFN(CResourceKey); +DEFFN(CRoomItem); +DEFFN(CSaveableObject); +DEFFN(CStaticImage); +DEFFN(CTurnOnObject); +DEFFN(CTurnOnPlaySound); +DEFFN(CTurnOnTurnOff); +DEFFN(CTreeItem); +DEFFN(CViewItem); + +DEFFN(CAnnounce); +DEFFN(CAnnoyBarbot); +DEFFN(CArbBackground); +DEFFN(CArboretumGate); +DEFFN(CAutoAnimate); +DEFFN(CBarBell); +DEFFN(CBarMenu); +DEFFN(CBarMenuButton); +DEFFN(CBelbotGetLight); +DEFFN(CBilgeSuccUBus); +DEFFN(CBomb); +DEFFN(CBottomOfWellMonitor); +DEFFN(CBowlUnlocker); +DEFFN(CBrainSlot); +DEFFN(CBridgeDoor); +DEFFN(CBridgeView); +DEFFN(CBrokenPellBase); +DEFFN(CBrokenPellerator); +DEFFN(CBrokenPelleratorFroz); +DEFFN(CCage); +DEFFN(CCallPellerator); +DEFFN(CCaptainsWheel); +DEFFN(CCDROM); +DEFFN(CCDROMComputer); +DEFFN(CCDROMTray); +DEFFN(CCellPointButton); +DEFFN(CChevCode); +DEFFN(CChevPanel); +DEFFN(CChickenCooler); +DEFFN(CChickenDispensor); +DEFFN(CCloseBrokenPel); +DEFFN(CodeWheel); +DEFFN(CComputer); +DEFFN(CComputerScreen); +DEFFN(CCookie); +DEFFN(CCredits); +DEFFN(CCreditsButton); +DEFFN(CDeadArea); +DEFFN(CDeskClickResponder); +DEFFN(CDoorbotElevatorHandler); +DEFFN(CDoorbotHomeHandler); +DEFFN(CEarSweetBowl); +DEFFN(CEjectPhonographButton); +DEFFN(CElevatorActionArea); +DEFFN(CEmmaControl); +DEFFN(CEmptyNutBowl); +DEFFN(CEndCreditText); +DEFFN(CEndCredits); +DEFFN(CEndExplodeShip); +DEFFN(CEndGameCredits); +DEFFN(CEndSequenceControl); +DEFFN(CFan); +DEFFN(CFanControl); +DEFFN(CFanDecrease); +DEFFN(CFanIncrease); +DEFFN(CFanNoises); +DEFFN(CFloorIndicator); +DEFFN(CGamesConsole); +DEFFN(CGetLiftEye2); +DEFFN(CGlassSmasher); +DEFFN(CHammerClip); +DEFFN(CHammerDispensor); +DEFFN(CHammerDispensorButton); +DEFFN(CHeadSlot); +DEFFN(CHeadSmashEvent); +DEFFN(CHeadSmashLever); +DEFFN(CHeadSpinner); +DEFFN(CIdleSummoner); +DEFFN(CLeaveSecClassState); +DEFFN(CLemonDispensor); +DEFFN(CLight); +DEFFN(CLightSwitch); +DEFFN(CLittleLiftButton); +DEFFN(CLongStickDispenser); +DEFFN(CMissiveOMat); +DEFFN(CMissiveOMatButton); +DEFFN(CMovieTester); +DEFFN(CMusicalInstrument); +DEFFN(CMusicConsoleButton); +DEFFN(CMusicRoomPhonograph); +DEFFN(CMusicRoomStopPhonographButton); +DEFFN(CMusicSystemLock); +DEFFN(CNavHelmet); +DEFFN(CNavigationComputer); +DEFFN(CNoNutBowl); +DEFFN(CNoseHolder); +DEFFN(CNullPortHole); +DEFFN(CNutReplacer); +DEFFN(CPetDisabler); +DEFFN(CPhonograph); +DEFFN(CPhonographLid); +DEFFN(CPlayMusicButton); +DEFFN(CPlayOnAct); +DEFFN(CPortHole); +DEFFN(CRecordPhonographButton); +DEFFN(CReplacementEar); +DEFFN(CReservedTable); +DEFFN(CRestaurantCylinderHolder); +DEFFN(CRestaurantPhonograph); +DEFFN(CSauceDispensor); +DEFFN(CSearchPoint); +DEFFN(CSeasonBackground); +DEFFN(CSeasonBarrel); +DEFFN(CSeasonalAdjustment); +DEFFN(CServiceElevatorWindow); +DEFFN(CShipSetting); +DEFFN(CShipSettingButton); +DEFFN(CShowCellpoints); +DEFFN(CSpeechDispensor); +DEFFN(CSplashAnimation); +DEFFN(CStarlingPuret); +DEFFN(CStartAction); +DEFFN(CStopPhonographButton); +DEFFN(CSUBGlass); +DEFFN(CSUBWrapper); +DEFFN(CSweetBowl); +DEFFN(CTelevision); +DEFFN(CThirdClassCanal); +DEFFN(CThrowTVDownWell); +DEFFN(CTitaniaStillControl); +DEFFN(CTOWParrotNav); +DEFFN(CUpLighter); +DEFFN(CUselessLever); +DEFFN(CVolumeControl); +DEFFN(CWheelButton); +DEFFN(CWheelHotSpot); +DEFFN(CWheelSpin); +DEFFN(CWheelSpinHorn); +DEFFN(CGondolierBase); +DEFFN(CGondolierChest); +DEFFN(CGondolierFace); +DEFFN(CGondolierMixer); +DEFFN(CGondolierSlider); +DEFFN(CMaitreDArmHolder); +DEFFN(CMaitreDBody); +DEFFN(CMaitreDLegs); +DEFFN(CMaitreDProdReceptor); +DEFFN(CParrotLobbyController); +DEFFN(CParrotLobbyLinkUpdater); +DEFFN(CParrotLobbyObject); +DEFFN(CParrotLobbyViewObject); +DEFFN(CParrotLoser); +DEFFN(CParrotNutBowlActor); +DEFFN(CParrotNutEater); +DEFFN(CParrotPerchHolder); +DEFFN(CParrotSuccUBus); +DEFFN(CParrotTrigger); +DEFFN(CPlayerMeetsParrot); +DEFFN(CPET); +DEFFN(CPETClass1); +DEFFN(CPETClass2); +DEFFN(CPETClass3); +DEFFN(CPetControl); +DEFFN(CPetDragChev); +DEFFN(CPetGraphic); +DEFFN(CPetGraphic2); +DEFFN(PETLeaf); +DEFFN(CPETLift); +DEFFN(CPETMonitor); +DEFFN(CPETPellerator); +DEFFN(CPETPosition); +DEFFN(CPETSentinal); +DEFFN(CPETSounds); +DEFFN(CPETTransition); +DEFFN(CPETTransport); +DEFFN(CPickUp); +DEFFN(CPickUpBarGlass); +DEFFN(CPickUpHose); +DEFFN(CPickUpLemon); +DEFFN(CPickUpSpeechCentre); +DEFFN(CPickUpVisCentre); +DEFFN(CBarShelfVisCentre); +DEFFN(CLemonOnBar); +DEFFN(CPlaceHolderItem); +DEFFN(CTVOnBar); +DEFFN(CArmchair); +DEFFN(CBasin); +DEFFN(CBedfoot); +DEFFN(CBedhead); +DEFFN(CChestOfDrawers); +DEFFN(CDesk); +DEFFN(CDeskchair); +DEFFN(CDrawer); +DEFFN(CSGTDoors); +DEFFN(SGTNav); +DEFFN(CSGTNavigation); +DEFFN(CSGTRestaurantDoors); +DEFFN(CSGTStateControl); +DEFFN(CSGTStateRoom); +DEFFN(CSGTTV); +DEFFN(CSGTUpperDoorsSound); +DEFFN(CToilet); +DEFFN(CVase); +DEFFN(CWashstand); + +DEFFN(CGondolier); +DEFFN(CLift); +DEFFN(CLiftindicator); +DEFFN(CPellerator); +DEFFN(CServiceElevator); +DEFFN(CTransport); + +DEFFN(CActButton); +DEFFN(CChangesSeasonButton); +DEFFN(CChevLeftOff); +DEFFN(CChevLeftOn); +DEFFN(CChevRightOff); +DEFFN(CChevRightOn); +DEFFN(CChevSendRecSwitch); +DEFFN(CChevSwitch); +DEFFN(CEditControl); +DEFFN(CElevatorButton); +DEFFN(CGetFromSucc); +DEFFN(CHelmetOnOff); +DEFFN(CHomePhoto); +DEFFN(CIconNavAction); +DEFFN(CIconNavButt); +DEFFN(CIconNavDown); +DEFFN(CIconNavImage); +DEFFN(CIconNavLeft); +DEFFN(CIconNavReceive); +DEFFN(CIconNavRight); +DEFFN(CIconNavSend); +DEFFN(CIconNavUp); +DEFFN(CKeybrdButt); +DEFFN(CMoveObjectButton); +DEFFN(CMusicControl); +DEFFN(CMusicSlider); +DEFFN(CMusicSliderPitch); +DEFFN(CMusicSliderSpeed); +DEFFN(CMusicSwitch); +DEFFN(CMusicSwitchInversion); +DEFFN(CMusicSwitchReverse); +DEFFN(CMusicVoiceMute); +DEFFN(CPetModeOff); +DEFFN(CPetModeOn); +DEFFN(CPetModePanel); +DEFFN(CPetPannel1); +DEFFN(CPetPannel2); +DEFFN(CPetPannel3); +DEFFN(CSendToSucc); +DEFFN(CSGTSelector); +DEFFN(CSliderButton); +DEFFN(CSmallChevLeftOff); +DEFFN(CSmallChevLeftOn); +DEFFN(CSmallChevRightOff); +DEFFN(CSmallChevRightOn); +DEFFN(CStatusChangeButton); +DEFFN(CSTButton); +DEFFN(CTextDown); +DEFFN(CTextSkrew); +DEFFN(CTextUp); +DEFFN(CToggleButton); +DEFFN(CToggleSwitch); + +DEFFN(CActMsg); +DEFFN(CActivationmsg); +DEFFN(CAddHeadPieceMsg); +DEFFN(CAnimateMaitreDMsg); +DEFFN(CArboretumGateMsg); +DEFFN(CArmPickedUpFromTableMsg); +DEFFN(CAutoSoundEvent); +DEFFN(CBilgeAutoSoundEvent); +DEFFN(CBilgeDispensorEvent); +DEFFN(CBodyInBilgeRoomMsg); +DEFFN(CBowlStateChange); +DEFFN(CCarryObjectArrivedMsg); +DEFFN(CChangeMusicMsg); +DEFFN(CChangeSeasonMsg); +DEFFN(CCheckAllPossibleCodes); +DEFFN(CCheckChevCode); +DEFFN(CChildDragEndMsg); +DEFFN(CChildDragMoveMsg); +DEFFN(CChildDragStartMsg); +DEFFN(CClearChevPanelBits); +DEFFN(CCorrectMusicPlayedMsg); +DEFFN(CCreateMusicPlayerMsg); +DEFFN(CCylinderHolderReadyMsg); +DEFFN(CDeactivationMsg); +DEFFN(CDeliverCCarryMsg); +DEFFN(CDisableMaitreDProdReceptor); +DEFFN(CDismissBotMsg); +DEFFN(CDoffNavHelmet); +DEFFN(CDonNavHelmet); +DEFFN(CDoorAutoSoundEvent); +DEFFN(CDoorbotNeededInElevatorMsg); +DEFFN(CDoorbotNeededInHomeMsg); +DEFFN(CDropObjectMsg); +DEFFN(CDropZoneGotObjectMsg); +DEFFN(CDropZoneLostObjectMsg); +DEFFN(CEditControlMsg); +DEFFN(CEnterNodeMsg); +DEFFN(CEnterRoomMsg); +DEFFN(CEnterViewMsg); +DEFFN(CEjectCylinderMsg); +DEFFN(CErasePhonographCylinderMsg); +DEFFN(CFrameMsg); +DEFFN(CFreshenCookieMsg); +DEFFN(CGetChevClassBits); +DEFFN(CGetChevClassNum); +DEFFN(CGetChevCodeFromRoomNameMsg); +DEFFN(CGetChevFloorBits); +DEFFN(CGetChevFloorNum); +DEFFN(CGetChevLiftBits); +DEFFN(CGetChevLiftNum); +DEFFN(CGetChevRoomBits); +DEFFN(CGetChevRoomNum); +DEFFN(CHoseConnectedMsg); +DEFFN(CInitializeAnimMsg); +DEFFN(CIsEarBowlPuzzleDone); +DEFFN(CIsHookedOnMsg); +DEFFN(CIsParrotPresentMsg); +DEFFN(CKeyCharMsg); +DEFFN(CLeaveNodeMsg); +DEFFN(CLeaveRoomMsg); +DEFFN(CLeaveViewMsg); +DEFFN(CLemonFallsFromTreeMsg); +DEFFN(CLightsMsg); +DEFFN(CLoadSuccessMsg); +DEFFN(CLockPhonographMsg); +DEFFN(CMaitreDDefeatedMsg); +DEFFN(CMaitreDHappyMsg); +DEFFN(CMessage); +DEFFN(CMissiveOMatActionMsg); +DEFFN(CMouseMsg); +DEFFN(CMouseMoveMsg); +DEFFN(CMouseButtonMsg); +DEFFN(CMouseButtonDownMsg); +DEFFN(CMouseButtonUpMsg); +DEFFN(CMouseDoubleClickMsg); +DEFFN(CMouseDragMsg); +DEFFN(CMouseDragStartMsg); +DEFFN(CMouseDragMoveMsg); +DEFFN(CMouseDragEndMsg); +DEFFN(CMoveToStartPosMsg); +DEFFN(CMovieEndMsg); +DEFFN(CMovieFrameMsg); +DEFFN(CMusicHasStartedMsg); +DEFFN(CMusicHasStoppedMsg); +DEFFN(CMusicSettingChangedMsg); +DEFFN(CNPCPlayAnimationMsg); +DEFFN(CNPCPlayIdleAnimationMsg); +DEFFN(CNPCPlayTalkingAnimationMsg); +DEFFN(CNPCQueueIdleAnimMsg); +DEFFN(CNutPuzzleMsg); +DEFFN(COnSummonBotMsg); +DEFFN(COpeningCreditsMsg); +DEFFN(CPETDeliverMsg); +DEFFN(CPETGainedObjectMsg); +DEFFN(CPETHelmetOnOffMsg); +DEFFN(CPETKeyboardOnOffMsg); +DEFFN(CPETLostObjectMsg); +DEFFN(CPETObjectSelectedMsg); +DEFFN(CPETObjectStateMsg); +DEFFN(CPETPhotoOnOffMsg); +DEFFN(CPETPlaySoundMsg); +DEFFN(CPETReceiveMsg); +DEFFN(CPETSetStarDestinationMsg); +DEFFN(CPETStarFieldLockMsg); +DEFFN(CPETStereoFieldOnOffMsg); +DEFFN(CPETTargetMsg); +DEFFN(CPETUpMsg); +DEFFN(CPETDownMsg); +DEFFN(CPETLeftMsg); +DEFFN(CPETRightMsg); +DEFFN(CPETActivateMsg); +DEFFN(CPanningAwayFromParrotMsg); +DEFFN(CParrotSpeakMsg); +DEFFN(CParrotTriesChickenMsg); +DEFFN(CPassOnDragStartMsg); +DEFFN(CPhonographPlayMsg); +DEFFN(CPhonographReadyToPlayMsg); +DEFFN(CPhonographRecordMsg); +DEFFN(CPhonographStopMsg); +DEFFN(CPlayRangeMsg); +DEFFN(CPlayerTriesRestaurantTableMsg); +DEFFN(CPreEnterNodeMsg); +DEFFN(CPreEnterRoomMsg); +DEFFN(CPreEnterViewMsg); +DEFFN(CPreSaveMsg); +DEFFN(CProdMaitreDMsg); +DEFFN(CPumpingMsg); +DEFFN(CPutBotBackInHisBoxMsg); +DEFFN(CPutParrotBackMsg); +DEFFN(CPuzzleSolvedMsg); +DEFFN(CQueryCylinderHolderMsg); +DEFFN(CQueryCylinderMsg); +DEFFN(CQueryCylinderNameMsg); +DEFFN(CQueryCylinderTypeMsg); +DEFFN(CQueryMusicControlSettingMsg); +DEFFN(CQueryPhonographState); +DEFFN(CRecordOntoCylinderMsg); +DEFFN(CRemoveFromGameMsg); +DEFFN(CReplaceBowlAndNutsMsg); +DEFFN(CRestaurantMusicChanged); +DEFFN(CSendCCarryMsg); +DEFFN(CSenseWorkingMsg); +DEFFN(CServiceElevatorDoor); +DEFFN(CServiceElevatorFloorChangeMsg); +DEFFN(CServiceElevatorFloorRequestMsg); +DEFFN(CServiceElevatorMsg); +DEFFN(CSetChevButtonImageMsg); +DEFFN(CSetChevClassBits); +DEFFN(CSetChevFloorBits); +DEFFN(CSetChevLiftBits); +DEFFN(CSetChevPanelBitMsg); +DEFFN(CSetChevPanelButtonsMsg); +DEFFN(CSetChevRoomBits); +DEFFN(CSetFrameMsg); +DEFFN(CSetMusicControlsMsg); +DEFFN(CSetVarMsg); +DEFFN(CSetVolumeMsg); +DEFFN(CShipSettingMsg); +DEFFN(CShowTextMsg); +DEFFN(CSignalObject); +DEFFN(CSpeechFallsFromTreeMsg); +DEFFN(CStartMusicMsg); +DEFFN(CStatusChangeMsg); +DEFFN(CStopMusicMsg); +DEFFN(CSubAcceptCCarryMsg); +DEFFN(CSubDeliverCCarryMsg); +DEFFN(CSubSendCCarryMsg); +DEFFN(CSUBTransition); +DEFFN(CSubTurnOffMsg); +DEFFN(CSubTurnOnMsg); +DEFFN(CSummonBotMsg); +DEFFN(CSummonBotQueryMsg); +DEFFN(CTakeHeadPieceMsg); +DEFFN(CTextInputMsg); +DEFFN(CTimeDilationMsg); +DEFFN(CTimeMsg); +DEFFN(CTimerMsg); +DEFFN(CTitleSequenceEndedMsg); +DEFFN(CTransitMsg); +DEFFN(CTranslateObjectMsg); +DEFFN(CTransportMsg); +DEFFN(CTriggerAutoMusicPlayerMsg); +DEFFN(CTriggerNPCEvent); +DEFFN(CTrueTalkGetAnimSetMsg); +DEFFN(CTrueTalkGetAssetDetailsMsg); +DEFFN(CTrueTalkGetStateValueMsg); +DEFFN(CTrueTalkNotifySpeechEndedMsg); +DEFFN(CTrueTalkNotifySpeechStartedMsg); +DEFFN(CTrueTalkQueueUpAnimSetMsg); +DEFFN(CTrueTalkSelfQueueAnimSetMsg); +DEFFN(CTrueTalkTriggerActionMsg); +DEFFN(CTurnOff); +DEFFN(CTurnOn); +DEFFN(CUse); +DEFFN(CUseWithCharMsg); +DEFFN(CUseWithOtherMsg); +DEFFN(CVirtualKeyCharMsg); +DEFFN(CVisibleMsg); + +DEFFN(CEnterBombRoom); +DEFFN(CEnterBridge); +DEFFN(CEnterExitFirstClassState); +DEFFN(CEnterExitMiniLift); +DEFFN(CEnterExitSecClassMiniLift); +DEFFN(CEnterExitView); +DEFFN(CEnterSecClassState); +DEFFN(CExitArboretum); +DEFFN(CExitBridge); +DEFFN(CExitLift); +DEFFN(CExitPellerator); +DEFFN(CExitStateRoom); +DEFFN(CExitTiania); +DEFFN(CMovePlayerInParrotRoom); +DEFFN(CMovePlayerTo); +DEFFN(CMovePlayerToFrom); +DEFFN(CMultiMove); +DEFFN(CPanFromPel); +DEFFN(CRestaurantPanHandler); +DEFFN(CScraliontisTable); +DEFFN(CRestrictedMove); +DEFFN(CTripDownCanal); + +DEFFN(CBarbot); +DEFFN(CBellBot); +DEFFN(CCallBot); +DEFFN(CCharacter); +DEFFN(CDeskbot); +DEFFN(CDoorbot); +DEFFN(CLiftBot); +DEFFN(CMaitreD); +DEFFN(CMobile); +DEFFN(CParrot); +DEFFN(CRobotController); +DEFFN(CStarlings); +DEFFN(CSummonBots); +DEFFN(CSuccUBus); +DEFFN(CTitania); +DEFFN(CTrueTalkNPC); +DEFFN(CAutoMusicPlayer); +DEFFN(CAutoMusicPlayerBase); +DEFFN(CAutoSoundPlayer); +DEFFN(CAutoSoundPlayerADSR); +DEFFN(CBackgroundSoundMaker); +DEFFN(CBirdSong); +DEFFN(CDomeFromTopOfWell); +DEFFN(CEnterViewTogglesOtherMusic); +DEFFN(CGondolierSong); +DEFFN(CMusicPlayer); +DEFFN(CNodeAutoSoundPlayer); +DEFFN(CRestrictedAutoMusicPlayer); +DEFFN(CRoomAutoSoundPlayer); +DEFFN(CRoomTriggerAutoMusicPlayer); +DEFFN(CSeasonNoises); +DEFFN(CSeasonalMusicPlayer); +DEFFN(CTitaniaSpeech); +DEFFN(CTriggerAutoMusicPlayer); +DEFFN(CViewAutoSoundPlayer); +DEFFN(CViewTogglesOtherMusic); +DEFFN(CWaterLappingSounds); +DEFFN(CStarControl); +DEFFN(CTimeEventInfo); + +void CSaveableObject::initClassList() { + _classDefs = new Common::List<ClassDef *>(); + _classList = new Common::HashMap<Common::String, CreateFunction>(); + ADDFN(CArm, CCarry); + ADDFN(CAuditoryCentre, CBrain); + ADDFN(CBowlEar, CEar); + ADDFN(CBrain, CCarry); + ADDFN(CBridgePiece, CCarry); + ADDFN(CCarry, CGameObject); + ADDFN(CCarryParrot, CCarry); + ADDFN(CCentralCore, CBrain); + ADDFN(CChicken, CCarry); + ADDFN(CCrushedTV, CCarry); + ADDFN(CEar, CHeadPiece); + ADDFN(CEye, CHeadPiece); + ADDFN(CFeathers, CCarry); + ADDFN(CFruit, CCarry); + ADDFN(CGlass, CCarry); + ADDFN(CHammer, CCarry); + ADDFN(CHeadPiece, CCarry); + ADDFN(CHose, CCarry); + ADDFN(CHoseEnd, CHose); + ADDFN(CKey, CCarry); + ADDFN(CLiftbotHead, CCarry); + ADDFN(CLongStick, CCarry); + ADDFN(CMagazine, CCarry); + ADDFN(CMaitreDLeftArm, CArm); + ADDFN(CMaitreDRightArm, CArm); + ADDFN(CMouth, CHeadPiece); + ADDFN(CNapkin, CCarry); + ADDFN(CNose, CHeadPiece); + ADDFN(CNote, CCarry); + ADDFN(CParcel, CCarry); + ADDFN(CPerch, CCentralCore); + ADDFN(CPhonographCylinder, CCarry); + ADDFN(CPhonographEar, CEar); + ADDFN(CPhotograph, CCarry); + ADDFN(CPlugIn, CCarry); + ADDFN(CSpeechCentre, CBrain); + ADDFN(CSweets, CCarry); + ADDFN(CVisionCentre, CBrain); + + ADDFN(CBackground, CGameObject); + ADDFN(CClickResponder, CGameObject); + ADDFN(CDontSaveFileItem, CFileItem); + ADDFN(CDropTarget, CGameObject); + ADDFN(CFileItem, CTreeItem); + ADDFN(CFileListItem, ListItem); + ADDFN(CGameObject, CNamedItem); + ADDFN(CGameObjectDescItem, CTreeItem); + ADDFN(CLinkItem, CNamedItem); + ADDFN(ListItem, CSaveableObject); + ADDFN(CMessageTarget, CSaveableObject); + ADDFN(CMailMan, CGameObject); + ADDFN(CMovieClip, ListItem); + ADDFN(CMultiDropTarget, CDropTarget); + ADDFN(CNamedItem, CTreeItem); + ADDFN(CNodeItem, CNamedItem); + ADDFN(CProjectItem, CFileItem); + ADDFN(CResourceKey, CSaveableObject); + ADDFN(CRoomItem, CNamedItem); + ADDFN(CSaveableObject, CSaveableObject); + ADDFN(CStaticImage, CGameObject); + ADDFN(CTurnOnObject, CBackground); + ADDFN(CTreeItem, CMessageTarget); + ADDFN(CTurnOnPlaySound, CTurnOnObject); + ADDFN(CTurnOnTurnOff, CBackground); + ADDFN(CViewItem, CNamedItem); + + ADDFN(CAnnounce, CGameObject); + ADDFN(CAnnoyBarbot, CGameObject); + ADDFN(CArbBackground, CBackground); + ADDFN(CArboretumGate, CBackground); + ADDFN(CAutoAnimate, CBackground); + ADDFN(CBarBell, CGameObject); + ADDFN(CBarMenu, CGameObject); + ADDFN(CBarMenuButton, CGameObject); + ADDFN(CBelbotGetLight, CGameObject); + ADDFN(CBilgeSuccUBus, CSuccUBus); + ADDFN(CBomb, CBackground); + ADDFN(CBottomOfWellMonitor, CGameObject); + ADDFN(CBowlUnlocker, CGameObject); + ADDFN(CBrainSlot, CGameObject); + ADDFN(CBridgeDoor, CGameObject); + ADDFN(CBridgeView, CBackground); + ADDFN(CBrokenPellBase, CBackground); + ADDFN(CBrokenPellerator, CBrokenPellBase); + ADDFN(CBrokenPelleratorFroz, CBrokenPellBase); + ADDFN(CCage, CBackground); + ADDFN(CCallPellerator, CGameObject); + ADDFN(CCaptainsWheel, CBackground); + ADDFN(CCDROM, CGameObject); + ADDFN(CCDROMComputer, CGameObject); + ADDFN(CCDROMTray, CGameObject); + ADDFN(CCellPointButton, CBackground); + ADDFN(CChevCode, CGameObject); + ADDFN(CChevPanel, CGameObject); + ADDFN(CChickenCooler, CGameObject); + ADDFN(CChickenDispensor, CBackground); + ADDFN(CodeWheel, CBomb); + ADDFN(CCloseBrokenPel, CBackground); + ADDFN(CComputer, CBackground); + ADDFN(CComputerScreen, CGameObject); + ADDFN(CCookie, CGameObject); + ADDFN(CCredits, CGameObject); + ADDFN(CCreditsButton, CBackground); + ADDFN(CDeadArea, CGameObject); + ADDFN(CDeskClickResponder, CClickResponder); + ADDFN(CDoorbotElevatorHandler, CGameObject); + ADDFN(CDoorbotHomeHandler, CGameObject); + ADDFN(CDropTarget, CGameObject); + ADDFN(CEarSweetBowl, CSweetBowl); + ADDFN(CEjectPhonographButton, CBackground); + ADDFN(CElevatorActionArea, CGameObject); + ADDFN(CEmmaControl, CBackground); + ADDFN(CEmptyNutBowl, CGameObject); + ADDFN(CEndCreditText, CGameObject); + ADDFN(CEndCredits, CGameObject); + ADDFN(CEndExplodeShip, CGameObject); + ADDFN(CEndGameCredits, CGameObject); + ADDFN(CEndSequenceControl, CGameObject); + ADDFN(CFan, CGameObject); + ADDFN(CFanControl, CGameObject); + ADDFN(CFanDecrease, CGameObject); + ADDFN(CFanIncrease, CGameObject); + ADDFN(CFanNoises, CGameObject); + ADDFN(CFloorIndicator, CGameObject); + ADDFN(CGamesConsole, CBackground); + ADDFN(CGetLiftEye2, CGameObject); + ADDFN(CGlassSmasher, CGameObject); + ADDFN(CHammerClip, CGameObject); + ADDFN(CHammerDispensor, CBackground); + ADDFN(CHammerDispensorButton, CStartAction); + ADDFN(CHeadSlot, CGameObject); + ADDFN(CHeadSmashEvent, CBackground); + ADDFN(CHeadSmashLever, CBackground); + ADDFN(CHeadSpinner, CGameObject); + ADDFN(CIdleSummoner, CGameObject); + ADDFN(CLeaveSecClassState, CGameObject); + ADDFN(CLemonDispensor, CBackground); + ADDFN(CLight, CBackground); + ADDFN(CLightSwitch, CBackground); + ADDFN(CLittleLiftButton, CBackground); + ADDFN(CLongStickDispenser, CGameObject); + ADDFN(CMissiveOMat, CGameObject); + ADDFN(CMissiveOMatButton, CEditControl); + ADDFN(CMovieTester, CGameObject); + ADDFN(CMusicalInstrument, CBackground); + ADDFN(CMusicConsoleButton, CMusicPlayer); + ADDFN(CMusicRoomPhonograph, CRestaurantPhonograph); + ADDFN(CMusicRoomStopPhonographButton, CEjectPhonographButton); + ADDFN(CMusicSystemLock, CDropTarget); + ADDFN(CNavHelmet, CGameObject); + ADDFN(CNavigationComputer, CGameObject); + ADDFN(CNoNutBowl, CBackground); + ADDFN(CNoseHolder, CDropTarget); + ADDFN(CNullPortHole, CClickResponder); + ADDFN(CNutReplacer, CGameObject); + ADDFN(CPetDisabler, CGameObject); + ADDFN(CPhonograph, CMusicPlayer); + ADDFN(CPhonographLid, CGameObject); + ADDFN(CPlayMusicButton, CBackground); + ADDFN(CPlayOnAct, CBackground); + ADDFN(CPortHole, CGameObject); + ADDFN(CRecordPhonographButton, CBackground); + ADDFN(CReplacementEar, CBackground); + ADDFN(CReservedTable, CGameObject); + ADDFN(CRestaurantCylinderHolder, CDropTarget); + ADDFN(CRestaurantPhonograph, CPhonograph); + ADDFN(CSauceDispensor, CBackground); + ADDFN(CSearchPoint, CGameObject); + ADDFN(CSeasonBackground, CBackground); + ADDFN(CSeasonBarrel, CBackground); + ADDFN(CSeasonalAdjustment, CBackground); + ADDFN(CServiceElevatorWindow, CBackground); + ADDFN(CShipSetting, CBackground); + ADDFN(CShipSettingButton, CGameObject); + ADDFN(CShowCellpoints, CGameObject); + ADDFN(CSpeechDispensor, CBackground); + ADDFN(CSplashAnimation, CGameObject); + ADDFN(CStarlingPuret, CGameObject); + ADDFN(CStartAction, CBackground); + ADDFN(CStopPhonographButton, CBackground); + ADDFN(CSUBGlass, CGameObject); + ADDFN(CSUBWrapper, CGameObject); + ADDFN(CSweetBowl, CGameObject); + ADDFN(CTelevision, CBackground); + ADDFN(CThirdClassCanal, CBackground); + ADDFN(CThrowTVDownWell, CGameObject); + ADDFN(CTitaniaStillControl, CGameObject); + ADDFN(CTOWParrotNav, CGameObject); + ADDFN(CUpLighter, CDropTarget); + ADDFN(CUselessLever, CToggleButton); + ADDFN(CVolumeControl, CGameObject); + ADDFN(CWheelButton, CBackground); + ADDFN(CWheelHotSpot, CBackground); + ADDFN(CWheelSpin, CBackground); + ADDFN(CWheelSpinHorn, CWheelSpin); + ADDFN(CGondolierBase, CGameObject); + ADDFN(CGondolierChest, CGondolierBase); + ADDFN(CGondolierFace, CGondolierBase); + ADDFN(CGondolierMixer, CGondolierBase); + ADDFN(CGondolierSlider, CGondolierBase); + ADDFN(CMaitreDArmHolder, CDropTarget); + ADDFN(CMaitreDBody, CMaitreDProdReceptor); + ADDFN(CMaitreDLegs, CMaitreDProdReceptor); + ADDFN(CMaitreDProdReceptor, CGameObject); + ADDFN(CParrotLobbyController, CParrotLobbyObject); + ADDFN(CParrotLobbyLinkUpdater, CParrotLobbyObject); + ADDFN(CParrotLobbyObject, CGameObject); + ADDFN(CParrotLobbyViewObject, CParrotLobbyObject); + ADDFN(CParrotLoser, CGameObject); + ADDFN(CParrotNutBowlActor, CGameObject); + ADDFN(CParrotNutEater, CGameObject); + ADDFN(CParrotPerchHolder, CMultiDropTarget); + ADDFN(CParrotSuccUBus, CSuccUBus); + ADDFN(CParrotTrigger, CGameObject); + ADDFN(CPlayerMeetsParrot, CGameObject); + ADDFN(CPET, CGameObject); + ADDFN(CPETClass1, CGameObject); + ADDFN(CPETClass2, CGameObject); + ADDFN(CPETClass3, CGameObject); + ADDFN(CPETLift, CPETTransport); + ADDFN(CPETMonitor, CGameObject); + ADDFN(CPETPellerator, CPETTransport); + ADDFN(CPETPosition, CGameObject); + ADDFN(CPETSentinal, CGameObject); + ADDFN(CPETSounds, CGameObject); + ADDFN(CPETTransition, CGameObject); + ADDFN(CPETTransport, CGameObject); + ADDFN(CPickUp, CGameObject); + ADDFN(CPickUpBarGlass, CPickUp); + ADDFN(CPickUpHose, CPickUp); + ADDFN(CPickUpLemon, CPickUp); + ADDFN(CPickUpSpeechCentre, CPickUp); + ADDFN(CPickUpVisCentre, CPickUp); + ADDFN(CBarShelfVisCentre, CPlaceHolderItem); + ADDFN(CLemonOnBar, CPlaceHolderItem); + ADDFN(CPlaceHolderItem, CGameObject); + ADDFN(CTVOnBar, CPlaceHolderItem); + ADDFN(CArmchair, CSGTStateRoom); + ADDFN(CBasin, CSGTStateRoom); + ADDFN(CBedfoot, CSGTStateRoom); + ADDFN(CBedhead, CSGTStateRoom); + ADDFN(CChestOfDrawers, CSGTStateRoom); + ADDFN(CDesk, CSGTStateRoom); + ADDFN(CDeskchair, CSGTStateRoom); + ADDFN(CDrawer, CSGTStateRoom); + ADDFN(CSGTDoors, CGameObject); + ADDFN(SGTNav, CSGTStateRoom); + ADDFN(CSGTNavigation, CGameObject); + ADDFN(CSGTRestaurantDoors, CGameObject); + ADDFN(CSGTStateControl, CBackground); + ADDFN(CSGTStateRoom, CBackground); + ADDFN(CSGTTV, CSGTStateRoom); + ADDFN(CSGTUpperDoorsSound, CClickResponder); + ADDFN(CToilet, CSGTStateRoom); + ADDFN(CVase, CSGTStateRoom); + ADDFN(CWashstand, CSGTStateRoom); + + ADDFN(CGondolier, CTransport); + ADDFN(CLift, CTransport); + ADDFN(CLiftindicator, CLift); + ADDFN(CPellerator, CTransport); + ADDFN(CServiceElevator, CTransport); + ADDFN(CTransport, CMobile); + + ADDFN(CActButton, CSTButton); + ADDFN(CChangesSeasonButton, CSTButton); + ADDFN(CChevLeftOff, CToggleSwitch); + ADDFN(CChevLeftOn, CToggleSwitch); + ADDFN(CChevRightOff, CToggleSwitch); + ADDFN(CChevRightOn, CToggleSwitch); + ADDFN(CChevSendRecSwitch, CToggleSwitch); + ADDFN(CChevSwitch, CToggleSwitch); + ADDFN(CEditControl, CGameObject); + ADDFN(CElevatorButton, CSTButton); + ADDFN(CGetFromSucc, CToggleSwitch); + ADDFN(CHelmetOnOff, CToggleSwitch); + ADDFN(CHomePhoto, CToggleSwitch); + ADDFN(CIconNavAction, CToggleSwitch); + ADDFN(CIconNavButt, CPetGraphic); + ADDFN(CIconNavDown, CToggleSwitch); + ADDFN(CIconNavImage, CPetGraphic); + ADDFN(CIconNavLeft, CToggleSwitch); + ADDFN(CIconNavReceive, CPetGraphic); + ADDFN(CIconNavRight, CToggleSwitch); + ADDFN(CIconNavSend, CPetGraphic); + ADDFN(CIconNavUp, CToggleSwitch); + ADDFN(CKeybrdButt, CToggleSwitch); + ADDFN(CMoveObjectButton, CSTButton); + ADDFN(CMusicControl, CBackground); + ADDFN(CMusicSlider, CMusicControl); + ADDFN(CMusicSliderPitch, CMusicSlider); + ADDFN(CMusicSliderSpeed, CMusicSlider); + ADDFN(CMusicSwitch, CMusicControl); + ADDFN(CMusicSwitchInversion, CMusicSwitch); + ADDFN(CMusicSwitchReverse, CMusicSwitch); + ADDFN(CMusicVoiceMute, CMusicControl); + ADDFN(CPetControl, CGameObject); + ADDFN(CPetDragChev, CPetGraphic2); + ADDFN(CPetGraphic, CGameObject); + ADDFN(CPetGraphic2, CGameObject); + ADDFN(PETLeaf, CGameObject); + ADDFN(CPetModeOff, CToggleSwitch); + ADDFN(CPetModeOn, CToggleSwitch); + ADDFN(CPetModePanel, CToggleSwitch); + ADDFN(CPetPannel1, CPetGraphic); + ADDFN(CPetPannel2, CPetGraphic); + ADDFN(CPetPannel3, CPetGraphic); + ADDFN(CSendToSucc, CToggleSwitch); + ADDFN(CSGTSelector, CPetGraphic); + ADDFN(CSliderButton, CSTButton); + ADDFN(CSmallChevLeftOff, CToggleSwitch); + ADDFN(CSmallChevLeftOn, CToggleSwitch); + ADDFN(CSmallChevRightOff, CToggleSwitch); + ADDFN(CSmallChevRightOn, CToggleSwitch); + ADDFN(CStatusChangeButton, CSTButton); + ADDFN(CSTButton, CBackground); + ADDFN(CTextDown, CPetGraphic); + ADDFN(CTextSkrew, CPetGraphic); + ADDFN(CTextUp, CPetGraphic); + ADDFN(CToggleButton, CBackground); + ADDFN(CToggleSwitch, CGameObject); + + ADDFN(CActMsg, CMessage); + ADDFN(CActivationmsg, CMessage); + ADDFN(CAddHeadPieceMsg, CMessage); + ADDFN(CAnimateMaitreDMsg, CMessage); + ADDFN(CArboretumGateMsg, CMessage); + ADDFN(CArmPickedUpFromTableMsg, CMessage); + ADDFN(CAutoSoundEvent, CGameObject); + ADDFN(CBilgeAutoSoundEvent, CAutoSoundEvent); + ADDFN(CBilgeDispensorEvent, CAutoSoundEvent); + ADDFN(CBodyInBilgeRoomMsg, CMessage); + ADDFN(CBowlStateChange, CMessage); + ADDFN(CCarryObjectArrivedMsg, CMessage); + ADDFN(CChangeMusicMsg, CMessage); + ADDFN(CChangeSeasonMsg, CMessage); + ADDFN(CCheckAllPossibleCodes, CMessage); + ADDFN(CCheckChevCode, CMessage); + ADDFN(CChildDragEndMsg, CMessage); + ADDFN(CChildDragMoveMsg, CMessage); + ADDFN(CChildDragStartMsg, CMessage); + ADDFN(CClearChevPanelBits, CMessage); + ADDFN(CCorrectMusicPlayedMsg, CMessage); + ADDFN(CCreateMusicPlayerMsg, CMessage); + ADDFN(CCylinderHolderReadyMsg, CMessage); + ADDFN(CDeactivationMsg, CMessage); + ADDFN(CDeliverCCarryMsg, CMessage); + ADDFN(CDisableMaitreDProdReceptor, CMessage); + ADDFN(CDismissBotMsg, CMessage); + ADDFN(CDoffNavHelmet, CMessage); + ADDFN(CDonNavHelmet, CMessage); + ADDFN(CDoorAutoSoundEvent, CAutoSoundEvent); + ADDFN(CDoorbotNeededInElevatorMsg, CMessage); + ADDFN(CDoorbotNeededInHomeMsg, CMessage); + ADDFN(CDropObjectMsg, CMessage); + ADDFN(CDropZoneGotObjectMsg, CMessage); + ADDFN(CDropZoneLostObjectMsg, CMessage); + ADDFN(CEditControlMsg, CMessage); + ADDFN(CEnterNodeMsg, CMessage); + ADDFN(CEnterRoomMsg, CMessage); + ADDFN(CEnterViewMsg, CMessage); + ADDFN(CEjectCylinderMsg, CMessage); + ADDFN(CErasePhonographCylinderMsg, CMessage); + ADDFN(CFrameMsg, CMessage); + ADDFN(CFreshenCookieMsg, CMessage); + ADDFN(CGetChevClassBits, CMessage); + ADDFN(CGetChevClassNum, CMessage); + ADDFN(CGetChevCodeFromRoomNameMsg, CMessage); + ADDFN(CGetChevFloorBits, CMessage); + ADDFN(CGetChevFloorNum, CMessage); + ADDFN(CGetChevLiftBits, CMessage); + ADDFN(CGetChevLiftNum, CMessage); + ADDFN(CGetChevRoomBits, CMessage); + ADDFN(CGetChevRoomNum, CMessage); + ADDFN(CHoseConnectedMsg, CMessage); + ADDFN(CInitializeAnimMsg, CMessage); + ADDFN(CIsEarBowlPuzzleDone, CMessage); + ADDFN(CIsHookedOnMsg, CMessage); + ADDFN(CIsParrotPresentMsg, CMessage); + ADDFN(CKeyCharMsg, CMessage); + ADDFN(CLeaveNodeMsg, CMessage); + ADDFN(CLeaveRoomMsg, CMessage); + ADDFN(CLeaveViewMsg, CMessage); + ADDFN(CLemonFallsFromTreeMsg, CMessage); + ADDFN(CLightsMsg, CMessage); + ADDFN(CLoadSuccessMsg, CMessage); + ADDFN(CLockPhonographMsg, CMessage); + ADDFN(CMaitreDDefeatedMsg, CMessage); + ADDFN(CMaitreDHappyMsg, CMessage); + ADDFN(CMessage, CSaveableObject); + ADDFN(CMissiveOMatActionMsg, CMessage); + ADDFN(CMouseMsg, CMessage); + ADDFN(CMouseMoveMsg, CMouseMsg); + ADDFN(CMouseButtonMsg, CMouseMsg); + ADDFN(CMouseButtonDownMsg, CMouseButtonMsg); + ADDFN(CMouseButtonUpMsg, CMouseButtonMsg); + ADDFN(CMouseDoubleClickMsg, CMouseButtonMsg); + ADDFN(CMouseDragMsg, CMouseMsg); + ADDFN(CMouseDragStartMsg, CMouseDragMsg); + ADDFN(CMouseDragMoveMsg, CMouseDragMsg); + ADDFN(CMouseDragEndMsg, CMouseDragMsg); + ADDFN(CMoveToStartPosMsg, CMessage); + ADDFN(CMovieEndMsg, CMessage); + ADDFN(CMovieFrameMsg, CMessage); + ADDFN(CMusicHasStartedMsg, CMessage); + ADDFN(CMusicHasStoppedMsg, CMessage); + ADDFN(CMusicSettingChangedMsg, CMessage); + ADDFN(CNPCPlayAnimationMsg, CMessage); + ADDFN(CNPCPlayIdleAnimationMsg, CMessage); + ADDFN(CNPCPlayTalkingAnimationMsg, CMessage); + ADDFN(CNPCQueueIdleAnimMsg, CMessage); + ADDFN(CNutPuzzleMsg, CMessage); + ADDFN(COnSummonBotMsg, CMessage); + ADDFN(COpeningCreditsMsg, CMessage); + ADDFN(CPETDeliverMsg, CMessage); + ADDFN(CPETGainedObjectMsg, CMessage); + ADDFN(CPETHelmetOnOffMsg, CMessage); + ADDFN(CPETKeyboardOnOffMsg, CMessage); + ADDFN(CPETLostObjectMsg, CMessage); + ADDFN(CPETObjectSelectedMsg, CMessage); + ADDFN(CPETObjectStateMsg, CMessage); + ADDFN(CPETPhotoOnOffMsg, CMessage); + ADDFN(CPETPlaySoundMsg, CMessage); + ADDFN(CPETReceiveMsg, CMessage); + ADDFN(CPETSetStarDestinationMsg, CMessage); + ADDFN(CPETStarFieldLockMsg, CMessage); + ADDFN(CPETStereoFieldOnOffMsg, CMessage); + ADDFN(CPETTargetMsg, CMessage); + ADDFN(CPETUpMsg, CPETTargetMsg); + ADDFN(CPETDownMsg, CPETTargetMsg); + ADDFN(CPETLeftMsg, CPETTargetMsg); + ADDFN(CPETRightMsg, CPETTargetMsg); + ADDFN(CPETActivateMsg, CPETTargetMsg); + ADDFN(CPanningAwayFromParrotMsg, CMessage); + ADDFN(CParrotSpeakMsg, CMessage); + ADDFN(CParrotTriesChickenMsg, CMessage); + ADDFN(CPassOnDragStartMsg, CMessage); + ADDFN(CPhonographPlayMsg, CMessage); + ADDFN(CPhonographReadyToPlayMsg, CMessage); + ADDFN(CPhonographRecordMsg, CMessage); + ADDFN(CPhonographStopMsg, CMessage); + ADDFN(CPlayRangeMsg, CMessage); + ADDFN(CPlayerTriesRestaurantTableMsg, CMessage); + ADDFN(CEnterNodeMsg, CMessage); + ADDFN(CEnterRoomMsg, CMessage); + ADDFN(CEnterViewMsg, CMessage); + ADDFN(CPreSaveMsg, CMessage); + ADDFN(CProdMaitreDMsg, CMessage); + ADDFN(CPumpingMsg, CMessage); + ADDFN(CPutBotBackInHisBoxMsg, CMessage); + ADDFN(CPutParrotBackMsg, CMessage); + ADDFN(CPuzzleSolvedMsg, CMessage); + ADDFN(CQueryCylinderHolderMsg, CMessage); + ADDFN(CQueryCylinderMsg, CMessage); + ADDFN(CQueryCylinderNameMsg, CMessage); + ADDFN(CQueryCylinderTypeMsg, CMessage); + ADDFN(CQueryMusicControlSettingMsg, CMessage); + ADDFN(CQueryPhonographState, CMessage); + ADDFN(CRecordOntoCylinderMsg, CMessage); + ADDFN(CRemoveFromGameMsg, CMessage); + ADDFN(CReplaceBowlAndNutsMsg, CMessage); + ADDFN(CRestaurantMusicChanged, CMessage); + ADDFN(CSendCCarryMsg, CMessage); + ADDFN(CSenseWorkingMsg, CMessage); + ADDFN(CServiceElevatorDoor, CMessage); + ADDFN(CServiceElevatorFloorChangeMsg, CMessage); + ADDFN(CServiceElevatorFloorRequestMsg, CMessage); + ADDFN(CServiceElevatorMsg, CMessage); + ADDFN(CSetChevButtonImageMsg, CMessage); + ADDFN(CSetChevClassBits, CMessage); + ADDFN(CSetChevFloorBits, CMessage); + ADDFN(CSetChevLiftBits, CMessage); + ADDFN(CSetChevPanelBitMsg, CMessage); + ADDFN(CSetChevPanelButtonsMsg, CMessage); + ADDFN(CSetChevRoomBits, CMessage); + ADDFN(CSetFrameMsg, CMessage); + ADDFN(CSetMusicControlsMsg, CMessage); + ADDFN(CSetVarMsg, CMessage); + ADDFN(CSetVolumeMsg, CMessage); + ADDFN(CShipSettingMsg, CMessage); + ADDFN(CShowTextMsg, CMessage); + ADDFN(CSignalObject, CMessage); + ADDFN(CSpeechFallsFromTreeMsg, CMessage); + ADDFN(CStartMusicMsg, CMessage); + ADDFN(CStatusChangeMsg, CMessage); + ADDFN(CStopMusicMsg, CMessage); + ADDFN(CSubAcceptCCarryMsg, CMessage); + ADDFN(CSubDeliverCCarryMsg, CMessage); + ADDFN(CSubSendCCarryMsg, CMessage); + ADDFN(CSUBTransition, CMessage); + ADDFN(CSubTurnOffMsg, CMessage); + ADDFN(CSubTurnOnMsg, CMessage); + ADDFN(CSummonBotMsg, CMessage); + ADDFN(CSummonBotQueryMsg, CMessage); + ADDFN(CTakeHeadPieceMsg, CMessage); + ADDFN(CTextInputMsg, CMessage); + ADDFN(CTimeDilationMsg, CMessage); + ADDFN(CTimeMsg, CMessage); + ADDFN(CTimerMsg, CTimeMsg); + ADDFN(CTitleSequenceEndedMsg, CMessage); + ADDFN(CTransitMsg, CMessage); + ADDFN(CTranslateObjectMsg, CMessage); + ADDFN(CTransportMsg, CMessage); + ADDFN(CTriggerAutoMusicPlayerMsg, CMessage); + ADDFN(CTriggerNPCEvent, CMessage); + ADDFN(CTrueTalkGetAnimSetMsg, CMessage); + ADDFN(CTrueTalkGetAssetDetailsMsg, CMessage); + ADDFN(CTrueTalkGetStateValueMsg, CMessage); + ADDFN(CTrueTalkNotifySpeechEndedMsg, CMessage); + ADDFN(CTrueTalkNotifySpeechStartedMsg, CMessage); + ADDFN(CTrueTalkQueueUpAnimSetMsg, CMessage); + ADDFN(CTrueTalkSelfQueueAnimSetMsg, CMessage); + ADDFN(CTrueTalkTriggerActionMsg, CMessage); + ADDFN(CTurnOff, CMessage); + ADDFN(CTurnOn, CMessage); + ADDFN(CUse, CMessage); + ADDFN(CUseWithCharMsg, CMessage); + ADDFN(CUseWithOtherMsg, CMessage); + ADDFN(CVirtualKeyCharMsg, CMessage); + ADDFN(CVisibleMsg, CMessage); + + ADDFN(CEnterBombRoom, CMovePlayerTo); + ADDFN(CEnterBridge, CGameObject); + ADDFN(CEnterExitFirstClassState, CGameObject); + ADDFN(CEnterExitMiniLift, CSGTNavigation); + ADDFN(CEnterExitSecClassMiniLift, CGameObject); + ADDFN(CEnterExitView, CGameObject); + ADDFN(CEnterSecClassState, CGameObject); + ADDFN(CExitArboretum, CMovePlayerTo); + ADDFN(CExitBridge, CMovePlayerTo); + ADDFN(CExitLift, CGameObject); + ADDFN(CExitPellerator, CGameObject); + ADDFN(CExitStateRoom, CMovePlayerTo); + ADDFN(CExitTiania, CMovePlayerTo); + ADDFN(CMovePlayerInParrotRoom, CMovePlayerTo); + ADDFN(CMovePlayerTo, CGameObject); + ADDFN(CMovePlayerToFrom, CGameObject); + ADDFN(CMultiMove, CMovePlayerTo); + ADDFN(CPanFromPel, CMovePlayerTo); + ADDFN(CRestaurantPanHandler, CMovePlayerTo); + ADDFN(CScraliontisTable, CRestaurantPanHandler); + ADDFN(CRestrictedMove, CMovePlayerTo); + ADDFN(CTripDownCanal, CMovePlayerTo); + + ADDFN(CBarbot, CTrueTalkNPC); + ADDFN(CBellBot, CTrueTalkNPC); + ADDFN(CCallBot, CGameObject); + ADDFN(CCharacter, CGameObject); + ADDFN(CDeskbot, CTrueTalkNPC); + ADDFN(CDoorbot, CTrueTalkNPC); + ADDFN(CMaitreD, CTrueTalkNPC); + ADDFN(CLiftBot, CTrueTalkNPC); + ADDFN(CMobile, CCharacter); + ADDFN(CParrot, CTrueTalkNPC); + ADDFN(CRobotController, CGameObject); + ADDFN(CStarlings, CCharacter); + ADDFN(CSuccUBus, CTrueTalkNPC); + ADDFN(CSummonBots, CRobotController); + ADDFN(CTitania, CCharacter); + ADDFN(CTrueTalkNPC, CCharacter); + + ADDFN(CAutoMusicPlayer, CAutoMusicPlayerBase); + ADDFN(CAutoMusicPlayerBase, CGameObject); + ADDFN(CAutoSoundPlayer, CGameObject); + ADDFN(CAutoSoundPlayerADSR, CAutoSoundPlayer); + ADDFN(CBackgroundSoundMaker, CGameObject); + ADDFN(CBirdSong, CRoomAutoSoundPlayer); + ADDFN(CDomeFromTopOfWell, CViewAutoSoundPlayer); + ADDFN(CGondolierSong, CGameObject); + ADDFN(CEnterViewTogglesOtherMusic, CTriggerAutoMusicPlayer); + ADDFN(CGondolierSong, CRoomAutoSoundPlayer); + ADDFN(CMusicPlayer, CGameObject); + ADDFN(CNodeAutoSoundPlayer, CAutoSoundPlayer); + ADDFN(CRestrictedAutoMusicPlayer, CAutoMusicPlayer); + ADDFN(CRoomAutoSoundPlayer, CAutoSoundPlayer); + ADDFN(CRoomTriggerAutoMusicPlayer, CTriggerAutoMusicPlayer); + ADDFN(CSeasonNoises, CViewAutoSoundPlayer); + ADDFN(CSeasonalMusicPlayer, CAutoMusicPlayerBase); + ADDFN(CAutoMusicPlayer, CAutoMusicPlayerBase); + ADDFN(CAutoMusicPlayerBase, CAutoMusicPlayer); + ADDFN(CTitaniaSpeech, CGameObject); + ADDFN(CTriggerAutoMusicPlayer, CGameObject); + ADDFN(CViewAutoSoundPlayer, CAutoSoundPlayer); + ADDFN(CViewTogglesOtherMusic, CEnterViewTogglesOtherMusic); + ADDFN(CWaterLappingSounds, CRoomAutoSoundPlayer); + ADDFN(CStarControl, CGameObject); + ADDFN(CTimeEventInfo, ListItem); +} + +void CSaveableObject::freeClassList() { + Common::List<ClassDef *>::iterator i; + for (i = _classDefs->begin(); i != _classDefs->end(); ++i) + delete *i; + + delete _classDefs; + delete _classList; +} + +CSaveableObject *CSaveableObject::createInstance(const Common::String &name) { + return (*_classList)[name](); +} + +void CSaveableObject::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); +} + +void CSaveableObject::load(SimpleFile *file) { + file->readNumber(); +} + +void CSaveableObject::saveHeader(SimpleFile *file, int indent) { + file->writeClassStart(getType()->_className, indent); +} + +void CSaveableObject::saveFooter(SimpleFile *file, int indent) { + file->writeClassEnd(indent); +} + +bool CSaveableObject::isInstanceOf(const ClassDef *classDef) const { + for (ClassDef *def = getType(); def != nullptr; def = def->_parent) { + if (def == classDef) + return true; + } + + return false; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/saveable_object.h b/engines/titanic/core/saveable_object.h new file mode 100644 index 0000000000..6d80ad121d --- /dev/null +++ b/engines/titanic/core/saveable_object.h @@ -0,0 +1,110 @@ +/* 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 TITANIC_SAVEABLE_OBJECT_H +#define TITANIC_SAVEABLE_OBJECT_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "common/hash-str.h" +#include "common/list.h" +#include "titanic/support/simple_file.h" + +namespace Titanic { + +class CSaveableObject; + +class ClassDef { +public: + const char *_className; + ClassDef *_parent; +public: + ClassDef(const char *className, ClassDef *parent) : + _className(className), _parent(parent) {} + virtual ~ClassDef() {} + virtual CSaveableObject *create(); +}; + +template<typename T> +class TypeTemplate : public ClassDef { +public: + TypeTemplate(const char *className, ClassDef *parent) : + ClassDef(className, parent) {} + virtual CSaveableObject *create() { return new T(); } +}; + +#define CLASSDEF \ + static ClassDef *_type; \ + virtual ClassDef *getType() const { return _type; } + +class CSaveableObject { + typedef CSaveableObject *(*CreateFunction)(); +private: + static Common::List<ClassDef *> *_classDefs; + static Common::HashMap<Common::String, CreateFunction> *_classList; +public: + /** + * Sets up the list of saveable object classes + */ + static void initClassList(); + + /** + * Free the list of saveable object classes + */ + static void freeClassList(); + + /** + * Creates a new instance of a saveable object class + */ + static CSaveableObject *createInstance(const Common::String &name); +public: + CLASSDEF + virtual ~CSaveableObject() {} + + bool isInstanceOf(const ClassDef *classDef) const; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Write out a header definition for the class to file + * prior to saving the actual data for the class + */ + virtual void saveHeader(SimpleFile *file, int indent); + + /** + * Writes out a footer for the class after it's data has + * been written to file + */ + virtual void saveFooter(SimpleFile *file, int indent); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SAVEABLE_OBJECT_H */ diff --git a/engines/titanic/core/static_image.cpp b/engines/titanic/core/static_image.cpp new file mode 100644 index 0000000000..977009e750 --- /dev/null +++ b/engines/titanic/core/static_image.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/core/static_image.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CStaticImage, CGameObject); + +void CStaticImage::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CStaticImage::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/static_image.h b/engines/titanic/core/static_image.h new file mode 100644 index 0000000000..7a715a84fa --- /dev/null +++ b/engines/titanic/core/static_image.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_STATIC_IMAGE_H +#define TITANIC_STATIC_IMAGE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CStaticImage : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STATIC_IMAGE_H */ diff --git a/engines/titanic/core/tree_item.cpp b/engines/titanic/core/tree_item.cpp new file mode 100644 index 0000000000..6adbbe39fa --- /dev/null +++ b/engines/titanic/core/tree_item.cpp @@ -0,0 +1,275 @@ +/* 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 "titanic/core/tree_item.h" +#include "titanic/core/dont_save_file_item.h" +#include "titanic/core/file_item.h" +#include "titanic/core/game_object.h" +#include "titanic/core/game_object_desc_item.h" +#include "titanic/core/link_item.h" +#include "titanic/core/mail_man.h" +#include "titanic/core/named_item.h" +#include "titanic/core/node_item.h" +#include "titanic/core/project_item.h" +#include "titanic/core/view_item.h" +#include "titanic/core/room_item.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/game_manager.h" +#include "titanic/game/placeholder/place_holder_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CTreeItem, CMessageTarget); + +CTreeItem::CTreeItem() : _parent(nullptr), _firstChild(nullptr), + _nextSibling(nullptr), _priorSibling(nullptr), _field14(0) { +} + +void CTreeItem::dump(int indent) { + CString line = dumpItem(indent); + debug("%s", line.c_str()); + + CTreeItem *item = getFirstChild(); + while (item) { + item->dump(indent + 1); + + item = item->getNextSibling(); + } +} + +CString CTreeItem::dumpItem(int indent) const { + CString result; + for (int idx = 0; idx < indent; ++idx) + result += '\t'; + result += getType()->_className; + + return result; +} + +void CTreeItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + CMessageTarget::save(file, indent); +} + +void CTreeItem::load(SimpleFile *file) { + file->readNumber(); + CMessageTarget::load(file); +} + +bool CTreeItem::isFileItem() const { + return isInstanceOf(CFileItem::_type); +} + +bool CTreeItem::isRoomItem() const { + return isInstanceOf(CRoomItem::_type); +} + +bool CTreeItem::isNodeItem() const { + return isInstanceOf(CNodeItem::_type); +} + +bool CTreeItem::isViewItem() const { + return isInstanceOf(CViewItem::_type); +} + +bool CTreeItem::isLinkItem() const { + return isInstanceOf(CLinkItem::_type); +} + +bool CTreeItem::isPlaceHolderItem() const { + return isInstanceOf(CPlaceHolderItem::_type); +} + +bool CTreeItem::isNamedItem() const { + return isInstanceOf(CNamedItem::_type); +} + +bool CTreeItem::isGameObject() const { + return isInstanceOf(CGameObject::_type); +} + +bool CTreeItem::isGameObjectDescItem() const { + return isInstanceOf(CGameObjectDescItem::_type); +} + +CGameManager *CTreeItem::getGameManager() const { + return _parent ? _parent->getGameManager() : nullptr; +} + +CProjectItem *CTreeItem::getRoot() const { + CTreeItem *parent = getParent(); + + if (parent) { + do { + parent = parent->getParent(); + } while (parent->getParent()); + } + + return dynamic_cast<CProjectItem *>(parent); +} + +CTreeItem *CTreeItem::getLastSibling() { + CTreeItem *item = this; + while (item->getNextSibling()) + item = item->getNextSibling(); + + return item; +} + +CTreeItem *CTreeItem::getLastChild() const { + if (!_firstChild) + return nullptr; + return _firstChild->getLastSibling(); +} + +CTreeItem *CTreeItem::scan(CTreeItem *item) const { + if (_firstChild) + return _firstChild; + + const CTreeItem *treeItem = this; + while (treeItem != item) { + if (treeItem->_nextSibling) + return treeItem->_nextSibling; + + treeItem = treeItem->_parent; + if (!treeItem) + break; + } + + return nullptr; +} + +CTreeItem *CTreeItem::findChildInstanceOf(ClassDef *classDef) const { + for (CTreeItem *treeItem = _firstChild; treeItem; treeItem = treeItem->getNextSibling()) { + if (treeItem->isInstanceOf(classDef)) + return treeItem; + } + + return nullptr; +} + +CTreeItem *CTreeItem::findNextInstanceOf(ClassDef *classDef, CTreeItem *startItem) const { + CTreeItem *treeItem = startItem ? startItem->getNextSibling() : getFirstChild(); + + for (; treeItem; treeItem = treeItem->getNextSibling()) { + if (treeItem->isInstanceOf(classDef)) + return treeItem; + } + + return nullptr; +} + +void CTreeItem::addUnder(CTreeItem *newParent) { + if (newParent->_firstChild) + addSibling(newParent->_firstChild->getLastSibling()); + else + setParent(newParent); +} + +void CTreeItem::setParent(CTreeItem *newParent) { + _parent = newParent; + _priorSibling = nullptr; + _nextSibling = newParent->_firstChild; + + if (newParent->_firstChild) + newParent->_firstChild->_priorSibling = this; + newParent->_firstChild = this; +} + +void CTreeItem::addSibling(CTreeItem *item) { + _priorSibling = item; + _nextSibling = item->_nextSibling; + _parent = item->_parent; + + if (item->_nextSibling) + item->_nextSibling->_priorSibling = this; + item->_nextSibling = this; +} + +void CTreeItem::moveUnder(CTreeItem *newParent) { + if (newParent) { + detach(); + addUnder(newParent); + } +} + +void CTreeItem::destroyAll() { + destroyChildren(); + detach(); + delete this; +} + +int CTreeItem::destroyChildren() { + if (!_firstChild) + return 0; + + CTreeItem *item = _firstChild, *child, *nextSibling; + int total = 0; + + do { + child = item->_firstChild; + nextSibling = item->_nextSibling; + + if (child) + total += item->destroyChildren(); + item->detach(); + delete item; + ++total; + } while ((item = nextSibling) != nullptr); + + return total; +} + +void CTreeItem::detach() { + // Delink this item from any prior and/or next siblings + if (_priorSibling) + _priorSibling->_nextSibling = _nextSibling; + if (_nextSibling) + _nextSibling->_priorSibling = _priorSibling; + + if (_parent && _parent->_firstChild == this) + _parent->_firstChild = _nextSibling; + + _priorSibling = _nextSibling = _parent = nullptr; +} + +CNamedItem *CTreeItem::findByName(const CString &name, int maxLen) { + CString nameLower = name; + nameLower.toLowercase(); + + for (CTreeItem *treeItem = this; treeItem; treeItem = treeItem->scan(this)) { + CString nodeName = treeItem->getName(); + nodeName.toLowercase(); + + if (maxLen) { + if (nodeName.left(maxLen).compareTo(nameLower)) + return dynamic_cast<CNamedItem *>(treeItem); + } else { + if (!nodeName.compareTo(nameLower)) + return dynamic_cast<CNamedItem *>(treeItem); + } + } + + return nullptr; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/tree_item.h b/engines/titanic/core/tree_item.h new file mode 100644 index 0000000000..db4ba30a44 --- /dev/null +++ b/engines/titanic/core/tree_item.h @@ -0,0 +1,252 @@ +/* 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 TITANIC_TREE_ITEM_H +#define TITANIC_TREE_ITEM_H + +#include "titanic/core/message_target.h" +#include "titanic/support/simple_file.h" + +namespace Titanic { + +class CGameManager; +class CMovieClipList; +class CNamedItem; +class CProjectItem; +class CScreenManager; +class CViewItem; + +class CTreeItem: public CMessageTarget { + friend class CMessage; + DECLARE_MESSAGE_MAP; +private: + CTreeItem *_parent; + CTreeItem *_nextSibling; + CTreeItem *_priorSibling; + CTreeItem *_firstChild; + int _field14; +public: + CLASSDEF; + CTreeItem(); + + + /** + * Dump the item and any of it's children + */ + void dump(int indent); + + /** + * Dump the item + */ + virtual CString dumpItem(int indent) const; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Get the game manager for the project + */ + virtual CGameManager *getGameManager() const; + + /** + * Returns true if the item is a file item + */ + virtual bool isFileItem() const; + + /** + * Returns true if the item is a room item + */ + virtual bool isRoomItem() const; + + /** + * Returns true if the item is a node item + */ + virtual bool isNodeItem() const; + + /** + * Returns true if the item is a view item + */ + virtual bool isViewItem() const; + + /** + * Returns true if the item is a link item + */ + virtual bool isLinkItem() const; + + /** + * Returns true if the item is a placeholder item + */ + virtual bool isPlaceHolderItem() const; + + /** + * Returns true if the item is a named item + */ + virtual bool isNamedItem() const; + + /** + * Returns true if the item is a game object + */ + virtual bool isGameObject() const; + + /** + * Returns true if the item is a game object desc item + */ + virtual bool isGameObjectDescItem() const; + + /** + * Gets the name of the item, if any + */ + virtual const CString getName() const { return CString(); } + + /** + * Compares the name of the item to a passed name + */ + virtual int compareTo(const CString &name, int maxLen = 0) const { return false; } + + /** + * Returns the clip list, if any, associated with the item + */ + virtual const CMovieClipList *getMovieClips() const { return nullptr; } + + /** + * Returns true if the given item connects to another specified view + */ + virtual bool connectsTo(CViewItem *destView) const { return false; } + + /** + * Allows the item to draw itself + */ + virtual void draw(CScreenManager *screenManager) {} + + /** + * Gets the bounds occupied by the item + */ + virtual Rect getBounds() const { return Rect(); } + + /** + * Called when the view changes + */ + virtual void viewChange() {} + + /** + * Get the parent for the given item + */ + CTreeItem *getParent() const { return _parent; } + + /** + * Jumps up through the parents to find the root item + */ + CProjectItem *getRoot() const; + + /** + * Get the next sibling + */ + CTreeItem *getNextSibling() const { return _nextSibling; } + + /** + * Get the prior sibling + */ + CTreeItem *getPriorSibling() const { return _priorSibling; } + + /** + * Get the last sibling of this sibling + */ + CTreeItem *getLastSibling(); + + /** + * Get the first child of the item, if any + */ + CTreeItem *getFirstChild() const { return _firstChild; } + + /** + * Get the last child of the item, if any + */ + CTreeItem *getLastChild() const; + + /** + * Given all the recursive children of the tree item, gives the next + * item in sequence to the passed starting item + */ + CTreeItem *scan(CTreeItem *item) const; + + /** + * Find the first child item that is of a given type + */ + CTreeItem *findChildInstanceOf(ClassDef *classDef) const; + + /** + * Find the next sibling item that is of the given type + */ + CTreeItem *findNextInstanceOf(ClassDef *classDef, CTreeItem *startItem) const; + + /** + * Adds the item under another tree item + */ + void addUnder(CTreeItem *newParent); + + /** + * Sets the parent for the item + */ + void setParent(CTreeItem *newParent); + + /** + * Adds the item as a sibling of another item + */ + void addSibling(CTreeItem *item); + + /** + * Moves the tree item to be under another parent + */ + void moveUnder(CTreeItem *newParent); + + /** + * Destroys both the item as well as any of it's children + */ + void destroyAll(); + + /** + * Destroys all child tree items under this one. + * @returns Total number of tree items recursively removed + */ + int destroyChildren(); + + /** + * Detach the tree item from any other associated tree items + */ + void detach(); + + /** + * Finds a tree item by name + */ + CNamedItem *findByName(const CString &name, int maxLen = 0); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TREE_ITEM_H */ diff --git a/engines/titanic/core/turn_on_object.cpp b/engines/titanic/core/turn_on_object.cpp new file mode 100644 index 0000000000..221602bb7b --- /dev/null +++ b/engines/titanic/core/turn_on_object.cpp @@ -0,0 +1,59 @@ +/* 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 "titanic/core/turn_on_object.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CTurnOnObject, CBackground) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(MouseButtonUpMsg) +END_MESSAGE_MAP() + +CTurnOnObject::CTurnOnObject() : CBackground(), _msgName("NULL") { +} + +void CTurnOnObject::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_msgName, indent); + + CBackground::save(file, indent); +} + +void CTurnOnObject::load(SimpleFile *file) { + file->readNumber(); + _msgName = file->readString(); + + CBackground::load(file); +} + +bool CTurnOnObject::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + return true; +} + +bool CTurnOnObject::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + CTurnOn turnOn; + turnOn.execute(_msgName); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/turn_on_object.h b/engines/titanic/core/turn_on_object.h new file mode 100644 index 0000000000..0f7cd76382 --- /dev/null +++ b/engines/titanic/core/turn_on_object.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_TURN_ON_OBJECT_H +#define TITANIC_TURN_ON_OBJECT_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CTurnOnObject : public CBackground { + DECLARE_MESSAGE_MAP; + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); +protected: + CString _msgName; +public: + CLASSDEF; + CTurnOnObject(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TURN_ON_OBJECT_H */ diff --git a/engines/titanic/core/turn_on_play_sound.cpp b/engines/titanic/core/turn_on_play_sound.cpp new file mode 100644 index 0000000000..2f9dba24a6 --- /dev/null +++ b/engines/titanic/core/turn_on_play_sound.cpp @@ -0,0 +1,49 @@ +/* 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 "titanic/core/turn_on_play_sound.h" + +namespace Titanic { + +CTurnOnPlaySound::CTurnOnPlaySound() : CTurnOnObject(), + _string3("NULL"), _fieldF8(80), _fieldFC(0) { +} + +void CTurnOnPlaySound::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string3, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_fieldFC, indent); + + CTurnOnObject::save(file, indent); +} + +void CTurnOnPlaySound::load(SimpleFile *file) { + file->readNumber(); + _string3 = file->readString(); + _fieldF8 = file->readNumber(); + _fieldFC = file->readNumber(); + + CTurnOnObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/turn_on_play_sound.h b/engines/titanic/core/turn_on_play_sound.h new file mode 100644 index 0000000000..1164135071 --- /dev/null +++ b/engines/titanic/core/turn_on_play_sound.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_TURN_ON_PLAY_SOUND_H +#define TITANIC_TURN_ON_PLAY_SOUND_H + +#include "titanic/core/turn_on_object.h" + +namespace Titanic { + +class CTurnOnPlaySound : public CTurnOnObject { +private: + CString _string3; + int _fieldF8; + int _fieldFC; +public: + CLASSDEF; + CTurnOnPlaySound(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TURN_ON_PLAY_SOUND_H */ diff --git a/engines/titanic/core/turn_on_turn_off.cpp b/engines/titanic/core/turn_on_turn_off.cpp new file mode 100644 index 0000000000..d43ddf7038 --- /dev/null +++ b/engines/titanic/core/turn_on_turn_off.cpp @@ -0,0 +1,53 @@ +/* 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 "titanic/core/turn_on_turn_off.h" + +namespace Titanic { + +CTurnOnTurnOff::CTurnOnTurnOff() : CBackground(), _fieldE0(0), + _fieldE4(0), _fieldE8(0), _fieldEC(0), _fieldF0(0) { +} + +void CTurnOnTurnOff::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_fieldF0, indent); + + CBackground::save(file, indent); +} + +void CTurnOnTurnOff::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + _fieldF0 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/turn_on_turn_off.h b/engines/titanic/core/turn_on_turn_off.h new file mode 100644 index 0000000000..adca6876ff --- /dev/null +++ b/engines/titanic/core/turn_on_turn_off.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_TURN_ON_TURN_OFF_H +#define TITANIC_TURN_ON_TURN_OFF_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CTurnOnTurnOff : public CBackground { +private: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; + int _fieldF0; +public: + CLASSDEF; + CTurnOnTurnOff(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TURN_ON_TURN_OFF_H */ diff --git a/engines/titanic/core/view_item.cpp b/engines/titanic/core/view_item.cpp new file mode 100644 index 0000000000..03e2753839 --- /dev/null +++ b/engines/titanic/core/view_item.cpp @@ -0,0 +1,332 @@ +/* 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 "titanic/game_manager.h" +#include "titanic/support/screen_manager.h" +#include "titanic/core/project_item.h" +#include "titanic/core/room_item.h" +#include "titanic/core/view_item.h" +#include "titanic/messages/messages.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CViewItem, CNamedItem) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(MouseButtonUpMsg) + ON_MESSAGE(MouseDoubleClickMsg) + ON_MESSAGE(MouseMoveMsg) +END_MESSAGE_MAP() + +CViewItem::CViewItem() : CNamedItem() { + Common::fill(&_buttonUpTargets[0], &_buttonUpTargets[4], (CTreeItem *)nullptr); + _field24 = 0; + _angle = 0.0; + _viewNumber = 0; + setAngle(0.0); +} + +void CViewItem::setAngle(double angle) { + _angle = angle; + _viewPos.x = (int16)(cos(_angle) * 30.0); + _viewPos.y = (int16)(sin(_angle) * -30.0); +} + +void CViewItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + _resourceKey.save(file, indent); + file->writeQuotedLine("V", indent); + file->writeFloatLine(_angle, indent + 1); + file->writeNumberLine(_viewNumber, indent + 1); + + CNamedItem::save(file, indent); +} + +void CViewItem::load(SimpleFile *file) { + int val = file->readNumber(); + + switch (val) { + case 1: + _resourceKey.load(file); + // Deliberate fall-through + + default: + file->readBuffer(); + setAngle(file->readFloat()); + _viewNumber = file->readNumber(); + break; + } + + CNamedItem::load(file); +} + +bool CViewItem::getResourceKey(CResourceKey *key) { + *key = _resourceKey; + CString filename = key->exists(); + return !filename.empty(); +} + +void CViewItem::leaveView(CViewItem *newView) { + // Only do the processing if we've been passed a view, and it's not the same + if (newView && newView != this) { + CLeaveViewMsg viewMsg(this, newView); + viewMsg.execute(this, nullptr, MSGFLAG_SCAN); + + CNodeItem *oldNode = findNode(); + CNodeItem *newNode = newView->findNode(); + if (newNode != oldNode) { + CLeaveNodeMsg nodeMsg(oldNode, newNode); + nodeMsg.execute(oldNode, nullptr, MSGFLAG_SCAN); + + CRoomItem *oldRoom = oldNode->findRoom(); + CRoomItem *newRoom = newNode->findRoom(); + if (newRoom != oldRoom) { + CGameManager *gm = getGameManager(); + if (gm) + gm->viewChange(); + + CLeaveRoomMsg roomMsg(oldRoom, newRoom); + roomMsg.execute(oldRoom, nullptr, MSGFLAG_SCAN); + } + } + } +} + +void CViewItem::preEnterView(CViewItem *newView) { + // Only do the processing if we've been passed a view, and it's not the same + if (newView && newView != this) { + CPreEnterViewMsg viewMsg(this, newView); + viewMsg.execute(this, nullptr, MSGFLAG_SCAN); + + CNodeItem *oldNode = findNode(); + CNodeItem *newNode = newView->findNode(); + if (newNode != oldNode) { + CPreEnterNodeMsg nodeMsg(oldNode, newNode); + nodeMsg.execute(oldNode, nullptr, MSGFLAG_SCAN); + + CRoomItem *oldRoom = oldNode->findRoom(); + CRoomItem *newRoom = newNode->findRoom(); + if (newRoom != oldRoom) { + CPreEnterRoomMsg roomMsg(oldRoom, newRoom); + roomMsg.execute(oldRoom, nullptr, MSGFLAG_SCAN); + } + } + } +} + +void CViewItem::enterView(CViewItem *newView) { + // Only do the processing if we've been passed a view, and it's not the same + if (newView && newView != this) { + CEnterViewMsg viewMsg(this, newView); + viewMsg.execute(this, nullptr, MSGFLAG_SCAN); + + CNodeItem *oldNode = findNode(); + CNodeItem *newNode = newView->findNode(); + if (newNode != oldNode) { + CEnterNodeMsg nodeMsg(oldNode, newNode); + nodeMsg.execute(oldNode, nullptr, MSGFLAG_SCAN); + + CRoomItem *oldRoom = oldNode->findRoom(); + CRoomItem *newRoom = newNode->findRoom(); + + CPetControl *petControl = nullptr; + if (newRoom != nullptr) { + petControl = newRoom->getRoot()->getPetControl(); + if (petControl) + petControl->enterNode(newNode); + } + + if (newRoom != oldRoom) { + CEnterRoomMsg roomMsg(oldRoom, newRoom); + roomMsg.execute(oldRoom, nullptr, MSGFLAG_SCAN); + + if (petControl) + petControl->enterRoom(newRoom); + } + } + } +} + +CLinkItem *CViewItem::findLink(CViewItem *newView) { + for (CTreeItem *treeItem = getFirstChild(); treeItem; + treeItem = scan(treeItem)) { + CLinkItem *link = static_cast<CLinkItem *>(treeItem); + if (link && link->connectsTo(newView)) + return link; + } + + return nullptr; +} + +bool CViewItem::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if (msg->_buttons & MB_LEFT) { + if (!handleMouseMsg(msg, true)) { + CGameManager *gm = getGameManager(); + if (gm->test54()) { + findNode()->findRoom(); + + CLinkItem *linkItem = dynamic_cast<CLinkItem *>( + findChildInstanceOf(CLinkItem::_type)); + while (linkItem) { + if (linkItem->_bounds.contains(msg->_mousePos)) { + gm->_gameState.triggerLink(linkItem); + return true; + } + + linkItem = dynamic_cast<CLinkItem *>( + findNextInstanceOf(CLinkItem::_type, linkItem)); + } + } + } + } + + return true; +} + +bool CViewItem::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + if (msg->_buttons & MB_LEFT) + handleMouseMsg(msg, false); + + return true; +} + +bool CViewItem::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { + if (msg->_buttons & MB_LEFT) + handleMouseMsg(msg, false); + + return true; +} + +bool CViewItem::MouseMoveMsg(CMouseMoveMsg *msg) { + CScreenManager *screenManager = CScreenManager::_screenManagerPtr; + uint changeCount = screenManager->_mouseCursor->getChangeCount(); + + if (handleMouseMsg(msg, true)) { + // If the cursor hasn't been set in the call to handleMouseMsg, + // then reset it back to the default arrow cursor + if (screenManager->_mouseCursor->getChangeCount() == changeCount) + screenManager->_mouseCursor->setCursor(CURSOR_ARROW); + } else { + // Iterate through each link item, and if any is highlighted, + // change the mouse cursor to the designated cursor for the item + CTreeItem *treeItem = getFirstChild(); + while (treeItem) { + CLinkItem *linkItem = dynamic_cast<CLinkItem *>(treeItem); + if (linkItem && linkItem->_bounds.contains(msg->_mousePos)) { + screenManager->_mouseCursor->setCursor(linkItem->_cursorId); + return true; + } + + treeItem = treeItem->getNextSibling(); + } + + if (!handleMouseMsg(msg, false) || (screenManager->_mouseCursor->getChangeCount() == changeCount)) + screenManager->_mouseCursor->setCursor(CURSOR_ARROW); + } + + return true; +} + +bool CViewItem::handleMouseMsg(CMouseMsg *msg, bool flag) { + CMouseButtonUpMsg *upMsg = dynamic_cast<CMouseButtonUpMsg *>(msg); + if (upMsg) { + handleButtonUpMsg(upMsg); + return true; + } + + Common::Array<CGameObject *> gameObjects; + for (CTreeItem *treeItem = scan(this); treeItem; treeItem = treeItem->scan(this)) { + CGameObject *gameObject = dynamic_cast<CGameObject *>(treeItem); + if (gameObject) { + if (gameObject->checkPoint(msg->_mousePos, false, true) && + (!flag || !gameObject->_field60)) { + if (gameObjects.size() < 256) + gameObjects.push_back(gameObject); + } + } + } + + const CMouseMoveMsg *moveMsg = dynamic_cast<const CMouseMoveMsg *>(msg); + if (moveMsg) { + if (gameObjects.size() == 0) + return false; + + for (int idx = (int)gameObjects.size() - 1; idx >= 0; ++idx) { + if (gameObjects[idx]->_cursorId != CURSOR_IGNORE) { + CScreenManager::_screenManagerPtr->_mouseCursor->setCursor(gameObjects[idx]->_cursorId); + break; + } + } + } + if (gameObjects.size() == 0) + return false; + + bool result = false; + for (int idx = (int)gameObjects.size() - 1; idx >= 0; --idx) { + if (msg->execute(gameObjects[idx])) { + if (msg->isButtonDownMsg()) + _buttonUpTargets[msg->_buttons >> 1] = gameObjects[idx]; + return true; + } + + if (CMouseMsg::isSupportedBy(gameObjects[idx])) + result = true; + } + + return result; +} + +void CViewItem::handleButtonUpMsg(CMouseButtonUpMsg *msg) { + CTreeItem *&target = _buttonUpTargets[msg->_buttons >> 1]; + + if (target) { + msg->execute(target); + target = nullptr; + } +} + +void CViewItem::getPosition(double &xp, double &yp, double &zp) { + // Get the position of the owning node within the room + CNodeItem *node = findNode(); + node->getPosition(xp, yp, zp); + + // Adjust the position slightly to compensate for view's angle, + // ensuring different direction views don't all have the same position + xp += cos(_angle) * 0.5; + yp -= sin(_angle) * 0.5; +} + +CString CViewItem::getFullViewName() const { + CNodeItem *node = findNode(); + CRoomItem *room = node->findRoom(); + + return CString::format("%s.%s.%s", room->getName().c_str(), + node->getName().c_str(), getName().c_str()); +} + +CString CViewItem::getNodeViewName() const { + CNodeItem *node = findNode(); + + return CString::format("%s.%s", node->getName().c_str(), getName().c_str()); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/view_item.h b/engines/titanic/core/view_item.h new file mode 100644 index 0000000000..ceb8a020da --- /dev/null +++ b/engines/titanic/core/view_item.h @@ -0,0 +1,122 @@ +/* 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 TITANIC_VIEW_ITEM_H +#define TITANIC_VIEW_ITEM_H + +#include "titanic/core/link_item.h" +#include "titanic/core/named_item.h" +#include "titanic/core/resource_key.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +class CViewItem : public CNamedItem { + DECLARE_MESSAGE_MAP; + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); + bool MouseMoveMsg(CMouseMoveMsg *msg); + bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg); +private: + CTreeItem *_buttonUpTargets[4]; +private: + /** + * Sets the angle of the view relative to the node it belongs to + */ + void setAngle(double angle); + + /** + * Called to handle mouse messagaes on the view + */ + bool handleMouseMsg(CMouseMsg *msg, bool flag); + + /** + * Handles mouse button up messages + */ + void handleButtonUpMsg(CMouseButtonUpMsg *msg); +protected: + int _field24; + CResourceKey _resourceKey; + Point _viewPos; +public: + int _viewNumber; + double _angle; +public: + CLASSDEF; + CViewItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Get the resource key for the view + */ + bool getResourceKey(CResourceKey *key); + + /** + * Called when leaving the view + */ + void leaveView(CViewItem *newView); + + /** + * Called on an old view just left, and about to enter a new view + */ + void preEnterView(CViewItem *newView); + + /** + * Called when a new view is being entered + */ + void enterView(CViewItem *newView); + + /** + * Finds a link which connects to another designated view + */ + CLinkItem *findLink(CViewItem *newView); + + /** + * Return the full Id of the current view in a + * room.node.view tuplet form + */ + CString getFullViewName() const; + + /** + * Return the Id of the current view in a + * room.node.view tuplet form + */ + CString getNodeViewName() const; + + /** + * Gets the relative position of the view within the owning room + */ + void getPosition(double &xp, double &yp, double &zp); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NAMED_ITEM_H */ diff --git a/engines/titanic/debugger.cpp b/engines/titanic/debugger.cpp new file mode 100644 index 0000000000..37fc546851 --- /dev/null +++ b/engines/titanic/debugger.cpp @@ -0,0 +1,263 @@ +/* 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 "titanic/debugger.h" +#include "titanic/titanic.h" +#include "titanic/core/tree_item.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +Debugger::Debugger(TitanicEngine *vm) : GUI::Debugger(), _vm(vm) { + registerCmd("continue", WRAP_METHOD(Debugger, cmdExit)); + registerCmd("dump", WRAP_METHOD(Debugger, cmdDump)); + registerCmd("room", WRAP_METHOD(Debugger, cmdRoom)); + registerCmd("pet", WRAP_METHOD(Debugger, cmdPET)); + registerCmd("item", WRAP_METHOD(Debugger, cmdItem)); +} + +int Debugger::strToInt(const char *s) { + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); + + // Hexadecimal string + uint tmp = 0; + int read = sscanf(s, "%xh", &tmp); + if (read < 1) + error("strToInt failed on string \"%s\"", s); + return (int)tmp; +} + +CRoomItem *Debugger::findRoom(const char *name) { + CTreeItem *root = g_vm->_window->_gameManager->_project; + CRoomItem *roomItem = dynamic_cast<CRoomItem *>(root->findByName(name)); + if (roomItem) + return roomItem; + + int roomNumber = strToInt(name); + for (CTreeItem *treeItem = root; treeItem; treeItem = treeItem->scan(root)) { + roomItem = dynamic_cast<CRoomItem *>(treeItem); + if (roomItem && roomItem->_roomNumber == roomNumber) + return roomItem; + } + + return nullptr; +} + +CNodeItem *Debugger::findNode(CRoomItem *room, const char *name) { + CNodeItem *nodeItem = dynamic_cast<CNodeItem *>(room->findByName(name)); + if (nodeItem) + return nodeItem; + + int nodeNumber = strToInt(name); + nodeItem = dynamic_cast<CNodeItem *>(room->findChildInstanceOf(CNodeItem::_type)); + while (nodeItem) { + if (nodeItem->_nodeNumber == nodeNumber) + return nodeItem; + + nodeItem = dynamic_cast<CNodeItem *>(room->findNextInstanceOf(CNodeItem::_type, nodeItem)); + } + + return nullptr; +} + +CViewItem *Debugger::findView(CNodeItem *node, const char *name) { + CViewItem *viewItem = dynamic_cast<CViewItem *>(node->findByName(name)); + if (viewItem) + return viewItem; + + int viewNumber = strToInt(name); + viewItem = dynamic_cast<CViewItem *>(node->findChildInstanceOf(CViewItem::_type)); + while (viewItem) { + if (viewItem->_viewNumber == viewNumber) + return viewItem; + + viewItem = dynamic_cast<CViewItem *>(node->findNextInstanceOf(CViewItem::_type, viewItem)); + } + + return nullptr; +} + +void Debugger::listRooms() { + CGameManager &gm = *g_vm->_window->_gameManager; + CTreeItem *root = gm._project; + CViewItem *view = gm._gameState._gameLocation.getView(); + CNodeItem *node = gm._gameState._gameLocation.getNode(); + CRoomItem *room = gm._gameState._gameLocation.getRoom(); + debugPrintf("Current location: %s, %s, %s\n", room->getName().c_str(), + node->getName().c_str(), view->getName().c_str()); + + debugPrintf("Available rooms:\n"); + for (CTreeItem *treeItem = root; treeItem; treeItem = treeItem->scan(root)) { + CRoomItem *roomItem = dynamic_cast<CRoomItem *>(treeItem); + if (roomItem) + debugPrintf("%d - %s\n", roomItem->_roomNumber, roomItem->_name.c_str()); + } +} + +void Debugger::listRoom(CRoomItem *room) { + for (CTreeItem *treeItem = room; treeItem; treeItem = treeItem->scan(room)) { + CNodeItem *nodeItem = dynamic_cast<CNodeItem *>(treeItem); + if (nodeItem) + debugPrintf("%s\n", nodeItem->_name.c_str()); + } +} + +void Debugger::listNode(CNodeItem *node) { + for (CTreeItem *treeItem = node; treeItem; treeItem = treeItem->scan(node)) { + CViewItem *viewItem = dynamic_cast<CViewItem *>(treeItem); + if (viewItem) + debugPrintf("%s\n", viewItem->_name.c_str()); + } +} + +bool Debugger::cmdDump(int argc, const char **argv) { + // Get the starting node + CTreeItem *root = g_vm->_window->_gameManager->_project; + if (argc == 2) + root = root->findByName(argv[1]); + + if (root == nullptr) { + debugPrintf("Could not find item\n"); + } else { + root->dump(0); + debugPrintf("Item and it's content were dumped to stdout\n"); + } + + return true; +} + +bool Debugger::cmdRoom(int argc, const char **argv) { + if (argc == 1) { + listRooms(); + } else if (argc >= 2) { + CRoomItem *roomItem = findRoom(argv[1]); + + if (!roomItem) + debugPrintf("Could not find room - %s\n", argv[1]); + else if (argc == 2) + listRoom(roomItem); + else { + CNodeItem *nodeItem = findNode(roomItem, argv[2]); + + if (!nodeItem) + debugPrintf("Could not find node - %s\n", argv[2]); + else if (argc == 3) + listNode(nodeItem); + else { + CViewItem *viewItem = findView(nodeItem, argv[3]); + + if (!viewItem) { + debugPrintf("Could not find view - %s\n", argv[3]); + } else { + // Change to the specified view + g_vm->_window->_gameManager->_gameState.changeView(viewItem, nullptr); + return false; + } + } + } + } + + return true; +} + +bool Debugger::cmdPET(int argc, const char **argv) { + CGameManager &gameManager = *g_vm->_window->_gameManager; + CGameState &gameState = gameManager._gameState; + + if (argc == 2) { + CString s(argv[1]); + s.toLowercase(); + + if (s == "on") { + gameState._petActive = true; + gameManager.initBounds(); + debugPrintf("PET is now on\n"); + return true; + } else if (s == "off") { + gameState._petActive = false; + gameManager.update(); + debugPrintf("PET is now off\n"); + return true; + } + } + + debugPrintf("%s [on | off]\n", argv[0]); + return true; +} + +bool Debugger::cmdItem(int argc, const char **argv) { + CGameManager &gameManager = *g_vm->_window->_gameManager; + CGameState &gameState = gameManager._gameState; + + if (argc == 1) { + // No parameters, so list the available items + debugPrintf("item [<name> [ add ]]\n"); + for (int idx = 0; idx < 40; ++idx) + debugPrintf("%s\n", g_vm->_itemIds[idx].c_str()); + } else { + // Ensure the specified name is a valid inventory item + int itemIndex; + for (itemIndex = 0; itemIndex < 40; ++itemIndex) { + if (g_vm->_itemIds[itemIndex] == argv[1]) + break; + } + if (itemIndex == 40) { + debugPrintf("Could not find item with that name\n"); + return true; + } + + // Get the item + CCarry *item = static_cast<CCarry *>( + g_vm->_window->_project->findByName(argv[1])); + assert(item); + + if (argc == 2) { + // List it's details + CTreeItem *treeItem = item; + CString fullName; + while ((treeItem = treeItem->getParent()) != nullptr) { + if (!treeItem->getName().empty()) + fullName = treeItem->getName() + "." + fullName; + } + + debugPrintf("Current location: %s\n", fullName.c_str()); + } else if (CString(argv[2]) == "add") { + // Ensure the PET is active and add the item to the inventory + gameState._petActive = true; + gameManager.initBounds(); + item->petAddToInventory(); + + return false; + } else { + debugPrintf("Unknown command\n"); + } + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/debugger.h b/engines/titanic/debugger.h new file mode 100644 index 0000000000..5edb7cb324 --- /dev/null +++ b/engines/titanic/debugger.h @@ -0,0 +1,101 @@ +/* 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 TITANIC_DEBUGGER_H +#define TITANIC_DEBUGGER_H + +#include "common/scummsys.h" +#include "gui/debugger.h" +#include "titanic/core/room_item.h" +#include "titanic/core/node_item.h" +#include "titanic/core/view_item.h" + +namespace Titanic { + +class TitanicEngine; + +class Debugger : public GUI::Debugger { +private: + /** + * Converts a decimal or hexadecimal string into a number + */ + int strToInt(const char *s); + + /** + * Find a room by name or number + */ + CRoomItem *findRoom(const char *name); + + /** + * Find a node within a room by name or number + */ + CNodeItem *findNode(CRoomItem *room, const char *name); + + /** + * Find a view within a room node by name or number + */ + CViewItem *findView(CNodeItem *node, const char *name); + + /** + * List all the rooms in the game + */ + void listRooms(); + + /** + * List the nodes within a room + */ + void listRoom(CRoomItem *room); + + /** + * List the views within a room node + */ + void listNode(CNodeItem *node); + + /** + * Dump a portion of the game project + */ + bool cmdDump(int argc, const char **argv); + + /** + * List room details, or jump to a specific view + */ + bool cmdRoom(int argc, const char **argv); + + /** + * Turn the PET on or off + */ + bool cmdPET(int argc, const char **argv); + + /** + * Item handling + */ + bool cmdItem(int argc, const char **argv); +protected: + TitanicEngine *_vm; +public: + Debugger(TitanicEngine *vm); + virtual ~Debugger() {} +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DEBUGGER_H */ diff --git a/engines/titanic/detection.cpp b/engines/titanic/detection.cpp new file mode 100644 index 0000000000..86d26f2f27 --- /dev/null +++ b/engines/titanic/detection.cpp @@ -0,0 +1,189 @@ +/* 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 "titanic/titanic.h" +#include "titanic/core/project_item.h" +#include "titanic/support/simple_file.h" + +#include "base/plugins.h" +#include "common/savefile.h" +#include "common/str-array.h" +#include "common/memstream.h" +#include "engines/advancedDetector.h" +#include "common/system.h" +#include "graphics/colormasks.h" +#include "graphics/surface.h" + +#define MAX_SAVES 99 + +namespace Titanic { + +struct TitanicGameDescription { + ADGameDescription desc; +}; + +uint32 TitanicEngine::getFeatures() const { + return _gameDescription->desc.flags; +} + +bool TitanicEngine::isDemo() const { + return (bool)(_gameDescription->desc.flags & ADGF_DEMO); +} + +Common::Language TitanicEngine::getLanguage() const { + return _gameDescription->desc.language; +} + +} // End of namespace Titanic + +static const PlainGameDescriptor TitanicGames[] = { + {"titanic", "Starship Titanic"}, + {0, 0} +}; + +#include "titanic/detection_tables.h" + +class TitanicMetaEngine : public AdvancedMetaEngine { +public: + TitanicMetaEngine() : AdvancedMetaEngine(Titanic::gameDescriptions, sizeof(Titanic::TitanicGameDescription), TitanicGames) { + _maxScanDepth = 3; + } + + virtual const char *getName() const { + return "Titanic Engine"; + } + + virtual const char *getOriginalCopyright() const { + return "Titanic Engine (c)"; + } + + virtual bool hasFeature(MetaEngineFeature f) const; + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + virtual SaveStateList listSaves(const char *target) const; + virtual int getMaximumSaveSlot() const; + virtual void removeSaveState(const char *target, int slot) const; + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; +}; + +bool TitanicMetaEngine::hasFeature(MetaEngineFeature f) const { + return + (f == kSupportsListSaves) || + (f == kSupportsLoadingDuringStartup) || + (f == kSupportsDeleteSave) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportThumbnail); +} + +bool Titanic::TitanicEngine::hasFeature(EngineFeature f) const { + return + (f == kSupportsRTL) || + (f == kSupportsLoadingDuringRuntime) || + (f == kSupportsSavingDuringRuntime); +} + +bool TitanicMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { + const Titanic::TitanicGameDescription *gd = (const Titanic::TitanicGameDescription *)desc; + *engine = new Titanic::TitanicEngine(syst, gd); + + return gd != 0; +} + +SaveStateList TitanicMetaEngine::listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray filenames; + Common::String saveDesc; + Common::String pattern = Common::String::format("%s.0##", target); + Titanic::TitanicSavegameHeader header; + + filenames = saveFileMan->listSavefiles(pattern); + + SaveStateList saveList; + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + const char *ext = strrchr(file->c_str(), '.'); + int slot = ext ? atoi(ext + 1) : -1; + + if (slot >= 0 && slot < MAX_SAVES) { + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); + + if (in) { + Titanic::CompressedFile cf; + cf.open(in); + + if (Titanic::CProjectItem::readSavegameHeader(&cf, header)) + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); + + if (header._thumbnail) { + header._thumbnail->free(); + delete header._thumbnail; + } + + cf.close(); + } + } + } + + // Sort saves based on slot number. + Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); + return saveList; +} + +int TitanicMetaEngine::getMaximumSaveSlot() const { + return MAX_SAVES; +} + +void TitanicMetaEngine::removeSaveState(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03d", target, slot); + g_system->getSavefileManager()->removeSavefile(filename); +} + +SaveStateDescriptor TitanicMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03d", target, slot); + Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename); + + if (f) { + Titanic::CompressedFile file; + file.open(f); + + Titanic::TitanicSavegameHeader header; + Titanic::CProjectItem::readSavegameHeader(&file, header); + + file.close(); + + // Create the return descriptor + SaveStateDescriptor desc(slot, header._saveName); + desc.setThumbnail(header._thumbnail); + desc.setSaveDate(header._year, header._month, header._day); + desc.setSaveTime(header._hour, header._minute); + desc.setPlayTime(header._totalFrames * GAME_FRAME_TIME); + + return desc; + } + + return SaveStateDescriptor(); +} + + +#if PLUGIN_ENABLED_DYNAMIC(TITANIC) + REGISTER_PLUGIN_DYNAMIC(TITANIC, PLUGIN_TYPE_ENGINE, TitanicMetaEngine); +#else + REGISTER_PLUGIN_STATIC(TITANIC, PLUGIN_TYPE_ENGINE, TitanicMetaEngine); +#endif diff --git a/engines/titanic/detection_tables.h b/engines/titanic/detection_tables.h new file mode 100644 index 0000000000..d4acebc3bf --- /dev/null +++ b/engines/titanic/detection_tables.h @@ -0,0 +1,57 @@ +/* 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. + * + */ + +namespace Titanic { + +static const TitanicGameDescription gameDescriptions[] = { + { + { + "titanic", + 0, + AD_ENTRY1s("newgame.st", "c276f2661f0d0a547445a65db78b2292", 87227), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + }, + +#if 0 + // German version currently disabled because it won't start up, + // even with the English generated titanic.dat file + { + { + "titanic", + 0, + AD_ENTRY1s("newgame.st", "db22924adfd6730f4b79f4e51b25e779", 87608), + Common::DE_DEU, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + }, +#endif + + { AD_TABLE_END_MARKER } +}; + +} // End of namespace Titanic diff --git a/engines/titanic/events.cpp b/engines/titanic/events.cpp new file mode 100644 index 0000000000..318ddf5726 --- /dev/null +++ b/engines/titanic/events.cpp @@ -0,0 +1,150 @@ +/* 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/scummsys.h" +#include "common/events.h" +#include "common/system.h" +#include "engines/util.h" +#include "titanic/events.h" +#include "titanic/titanic.h" +#include "titanic/main_game_window.h" + +namespace Titanic { + +Events::Events(TitanicEngine *vm): _vm(vm), _frameCounter(1), + _priorFrameTime(0) { +} + +void Events::pollEvents() { + checkForNextFrameCounter(); + + Common::Event event; + if (!g_system->getEventManager()->pollEvent(event)) + return; + + switch (event.type) { + case Common::EVENT_MOUSEMOVE: + _mousePos = event.mouse; + eventTarget()->mouseMove(_mousePos); + break; + case Common::EVENT_LBUTTONDOWN: + _mousePos = event.mouse; + eventTarget()->leftButtonDown(_mousePos); + break; + case Common::EVENT_LBUTTONUP: + _mousePos = event.mouse; + eventTarget()->leftButtonUp(_mousePos); + break; + case Common::EVENT_MBUTTONDOWN: + _mousePos = event.mouse; + eventTarget()->middleButtonDown(_mousePos); + break; + case Common::EVENT_MBUTTONUP: + _mousePos = event.mouse; + eventTarget()->middleButtonUp(_mousePos); + break; + case Common::EVENT_RBUTTONDOWN: + _mousePos = event.mouse; + eventTarget()->rightButtonDown(_mousePos); + break; + case Common::EVENT_RBUTTONUP: + _mousePos = event.mouse; + eventTarget()->rightButtonUp(_mousePos); + break; + case Common::EVENT_KEYDOWN: + eventTarget()->keyDown(event.kbd); + break; + case Common::EVENT_KEYUP: + eventTarget()->keyUp(event.kbd); + break; + default: + break; + } +} + +void Events::pollEventsAndWait() { + pollEvents(); + g_system->delayMillis(10); + + // Regularly update the sound mixer + CGameManager *gameManager = g_vm->_window->_gameManager; + if (gameManager) + gameManager->_sound.updateMixer(); +} + +bool Events::checkForNextFrameCounter() { + // Check for next game frame + uint32 milli = g_system->getMillis(); + if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) { + ++_frameCounter; + _priorFrameTime = milli; + + // Handle any idle updates + eventTarget()->onIdle(); + + // Give time to the debugger + _vm->_debugger->onFrame(); + + // Display the frame + _vm->_screen->update(); + + return true; + } + + return false; +} + +uint32 Events::getTicksCount() const { + return g_system->getMillis(); +} + +void Events::sleep(uint time) { + uint32 delayEnd = g_system->getMillis() + time; + + while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) + pollEventsAndWait(); +} + +bool Events::waitForPress(uint expiry) { + uint32 delayEnd = g_system->getMillis() + expiry; + + while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) { + g_system->delayMillis(10); + checkForNextFrameCounter(); + + Common::Event event; + if (g_system->getEventManager()->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_MBUTTONDOWN: + case Common::EVENT_KEYDOWN: + return true; + default: + break; + } + } + } + + return false; +} + +} // End of namespace Titanic diff --git a/engines/titanic/events.h b/engines/titanic/events.h new file mode 100644 index 0000000000..68666c7c46 --- /dev/null +++ b/engines/titanic/events.h @@ -0,0 +1,145 @@ +/* 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 TITANIC_EVENTS_H +#define TITANIC_EVENTS_H + +#include "common/scummsys.h" +#include "common/events.h" +#include "common/stack.h" +#include "support/rect.h" + +namespace Titanic { + +#define GAME_FRAME_RATE 30 +#define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE) +#define DOUBLE_CLICK_TIME 100 + +enum SpecialButtons { + MK_LBUTTON = 1, MK_RBUTTON = 2, MK_SHIFT = 4, MK_CONTROL = 8, + MK_MBUTTON = 0x10 +}; + +class TitanicEngine; + +/** + * A base class for windows that can receive event messages + */ +class CEventTarget { +public: + virtual ~CEventTarget() {} + + /** + * Called to handle any regular updates the game requires + */ + virtual void onIdle() {} + + /** + * Mouse/key event handlers + */ + virtual void mouseMove(const Point &mousePos) {} + virtual void leftButtonDown(const Point &mousePos) {} + virtual void leftButtonUp(const Point &mousePos) {} + virtual void leftButtonDoubleClick(const Point &mousePos) {} + virtual void middleButtonDown(const Point &mousePos) {} + virtual void middleButtonUp(const Point &mousePos) {} + virtual void middleButtonDoubleClick(const Point &mousePos) {} + virtual void rightButtonDown(const Point &mousePos) {} + virtual void rightButtonUp(const Point &mousePos) {} + virtual void keyDown(Common::KeyState keyState) {} + virtual void keyUp(Common::KeyState keyState) {} +}; + +class Events { +private: + TitanicEngine *_vm; + Common::Stack<CEventTarget *> _eventTargets; + uint32 _frameCounter; + uint32 _priorFrameTime; + Common::Point _mousePos; + + /** + * Check whether it's time to display the next screen frame + */ + bool checkForNextFrameCounter(); + + /** + * Return the currently active event target + */ + CEventTarget *eventTarget() const { + return _eventTargets.top(); + } +public: + Events(TitanicEngine *vm); + ~Events() {} + + /** + * Adds a new event target to the top of the list. It will get + * all events generated until such time as another is pushed on + * top of it, or the removeTarget method is called + */ + void addTarget(CEventTarget *target) { + _eventTargets.push(target); + } + + /** + * Removes the currently active event target + */ + void removeTarget() { + _eventTargets.pop(); + } + + /** + * Check for any pending events + */ + void pollEvents(); + + /** + * Poll for events and introduce a small delay, to allow the system to + * yield to other running programs + */ + void pollEventsAndWait(); + + /** + * Return the current game frame number + */ + uint32 getFrameCounter() const { return _frameCounter; } + + /** + * Get the elapsed playtime + */ + uint32 getTicksCount() const; + + /** + * Sleep for a specified period of time + */ + void sleep(uint time); + + /** + * Wait for a mouse or keypress + */ + bool waitForPress(uint expiry); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EVENTS_H */ diff --git a/engines/titanic/game/announce.cpp b/engines/titanic/game/announce.cpp new file mode 100644 index 0000000000..04e7a84271 --- /dev/null +++ b/engines/titanic/game/announce.cpp @@ -0,0 +1,133 @@ +/* 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 "titanic/game/announce.h" +#include "titanic/titanic.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CAnnounce, CGameObject) + ON_MESSAGE(TimerMsg) + ON_MESSAGE(LeaveRoomMsg) + ON_MESSAGE(ActMsg) +END_MESSAGE_MAP() + +CAnnounce::CAnnounce() : _nameIndex(0), _soundHandle(0), _leaveFlag(1), _enabled(false) { +} + +void CAnnounce::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_nameIndex, indent); + file->writeNumberLine(_soundHandle, indent); + file->writeNumberLine(_leaveFlag, indent); + file->writeNumberLine(_enabled, indent); + + CGameObject::save(file, indent); +} + +void CAnnounce::load(SimpleFile *file) { + file->readNumber(); + _nameIndex = file->readNumber(); + _soundHandle = file->readNumber(); + _leaveFlag = file->readNumber(); + _enabled = file->readNumber(); + + CGameObject::load(file); +} + +bool CAnnounce::TimerMsg(CTimerMsg *msg) { + if (!_enabled) + return false; + + if (msg->_timerCtr == 1) { + CString numStr = "0"; + CString waveNames1[20] = { + "z#181.wav", "z#211.wav", "z#203.wav", "z#202.wav", "z#201.wav", + "z#200.wav", "z#199.wav", "z#198.wav", "z#197.wav", "z#196.wav", + "z#210.wav", "z#209.wav", "z#208.wav", "z#207.wav", "z#206.wav", + "z#205.wav", "z#204.wav", "z#145.wav", "", "" + }; + CString waveNames2[37] = { + "z#154.wav", "z#153.wav", "z#152.wav", "z#151.wav", "z#150.wav", + "z#149.wav", "z#148.wav", "z#169.wav", "z#171.wav", "z#178.wav", + "z#176.wav", "z#177.wav", "z#165.wav", "z#170.wav", "z#180.wav", + "z#156.wav", "z#172.wav", "z#173.wav", "z#160.wav", "z#158.wav", + "z#161.wav", "z#179.wav", "z#163.wav", "z#164.wav", "z#162.wav", + "z#159.wav", "z#175.wav", "z#166.wav", "z#174.wav", "z#157.wav", + "", "", "", "", "", "", "" + }; + + int randVal = _nameIndex ? g_vm->getRandomNumber(2) : 0; + switch (randVal) { + case 0: + case 1: + _soundHandle = playSound("z#189.wav"); + if (_nameIndex < 20) { + queueSound(waveNames1[_nameIndex], _soundHandle); + ++_nameIndex; + } else { + queueSound(waveNames1[1 + g_vm->getRandomNumber(17)], _soundHandle); + } + break; + + case 2: + _soundHandle = playSound("z#189.wav"); + queueSound(waveNames2[1 + g_vm->getRandomNumber(35)], _soundHandle); + break; + + default: + break; + } + + addTimer(1, 300000 + g_vm->getRandomNumber(30000), 0); + if (g_vm->getRandomNumber(3) == 0) + addTimer(2, 4000, 0); + + } else if (msg->_timerCtr == 2) { + CParrotSpeakMsg speakMsg; + speakMsg._value1 = "Announcements"; + speakMsg.execute("PerchedParrot"); + } + + return true; +} + +bool CAnnounce::LeaveRoomMsg(CLeaveRoomMsg *msg) { + if (_leaveFlag) { + addTimer(1, 1000, 0); + _leaveFlag = 0; + _enabled = true; + } + + return true; +} + +bool CAnnounce::ActMsg(CActMsg *msg) { + if (msg->_action == "Enable") + _enabled = true; + else if (msg->_action == "Disable") + _enabled = false; + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/announce.h b/engines/titanic/game/announce.h new file mode 100644 index 0000000000..9bf060daae --- /dev/null +++ b/engines/titanic/game/announce.h @@ -0,0 +1,57 @@ +/* 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 TITANIC_ANNOUNCE_H +#define TITANIC_ANNOUNCE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CAnnounce : public CGameObject { + DECLARE_MESSAGE_MAP; + bool TimerMsg(CTimerMsg *msg); + bool LeaveRoomMsg(CLeaveRoomMsg *msg); + bool ActMsg(CActMsg *msg); +private: + int _nameIndex; + int _soundHandle; + bool _leaveFlag; + bool _enabled; +public: + CLASSDEF; + CAnnounce(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ROOM_ITEM_H */ diff --git a/engines/titanic/game/annoy_barbot.cpp b/engines/titanic/game/annoy_barbot.cpp new file mode 100644 index 0000000000..8b22f9c13a --- /dev/null +++ b/engines/titanic/game/annoy_barbot.cpp @@ -0,0 +1,54 @@ +/* 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 "titanic/game/annoy_barbot.h" + +namespace Titanic { + +int CAnnoyBarbot::_v1; + +BEGIN_MESSAGE_MAP(CAnnoyBarbot, CGameObject) + ON_MESSAGE(MouseButtonDownMsg) +END_MESSAGE_MAP() + +void CAnnoyBarbot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + CGameObject::save(file, indent); +} + +void CAnnoyBarbot::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + CGameObject::load(file); +} + +bool CAnnoyBarbot::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if ((++_v1 % 3) == 1) { + CActMsg actMsg("GoRingBell"); + actMsg.execute("Barbot"); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/annoy_barbot.h b/engines/titanic/game/annoy_barbot.h new file mode 100644 index 0000000000..0ccfe43794 --- /dev/null +++ b/engines/titanic/game/annoy_barbot.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_ANNOY_BARBOT_H +#define TITANIC_ANNOY_BARBOT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CAnnoyBarbot : public CGameObject { + DECLARE_MESSAGE_MAP; + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); +private: + static int _v1; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ANNOY_BARBOT_H */ diff --git a/engines/titanic/game/arb_background.cpp b/engines/titanic/game/arb_background.cpp new file mode 100644 index 0000000000..f71bcf90d1 --- /dev/null +++ b/engines/titanic/game/arb_background.cpp @@ -0,0 +1,53 @@ +/* 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 "titanic/game/arb_background.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CArbBackground, CBackground); + +CArbBackground::CArbBackground() : CBackground(), + _fieldE0(0), _fieldE4(61), _fieldE8(62), _fieldEC(118) { +} + +void CArbBackground::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + + CBackground::save(file, indent); +} + +void CArbBackground::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/arb_background.h b/engines/titanic/game/arb_background.h new file mode 100644 index 0000000000..88d4d1bec6 --- /dev/null +++ b/engines/titanic/game/arb_background.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_ARB_BACKGROUND_H +#define TITANIC_ARB_BACKGROUND_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CArbBackground : public CBackground { + DECLARE_MESSAGE_MAP; +public: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; +public: + CLASSDEF; + CArbBackground(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ARB_BACKGROUND_H */ diff --git a/engines/titanic/game/arboretum_gate.cpp b/engines/titanic/game/arboretum_gate.cpp new file mode 100644 index 0000000000..1f92f56acb --- /dev/null +++ b/engines/titanic/game/arboretum_gate.cpp @@ -0,0 +1,331 @@ +/* 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 "titanic/game/arboretum_gate.h" +#include "titanic/titanic.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CArboretumGate, CBackground) + ON_MESSAGE(ChangeSeasonMsg) + ON_MESSAGE(ActMsg) + ON_MESSAGE(MovieEndMsg) + ON_MESSAGE(LeaveViewMsg) + ON_MESSAGE(TurnOff) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(TurnOn) +END_MESSAGE_MAP() + +int CArboretumGate::_v1; +int CArboretumGate::_initialFrame; +int CArboretumGate::_v3; + +CArboretumGate::CArboretumGate() : CBackground() { + _viewName1 = "NULL"; + _viewName2 = "NULL"; + _seasonNum = 0; + _fieldF0 = 0; + _winterOffStartFrame = 244; + _winterOffEndFrame = 304; + _springOffStartFrame = 122; + _springOffEndFrame = 182; + _summerOffStartFrame1 = 183; + _summerOffEndFrame1 = 243; + _summerOffStartFrame2 = 665; + _summerOffEndFrame2 = 724; + _autumnOffStartFrame1 = 61; + _autumnOffEndFrame1 = 121; + _autumnOffStartFrame2 = 0; + _autumnOffEndFrame2 = 60; + _winterOnStartFrame = 485; + _winterOnEndFrame = 544; + _springOnStartFrame = 425; + _springOnEndFrame = 484; + _summerOnStartFrame1 = 545; + _summerOnEndFrame1 = 604; + _summerOnStartFrame2 = 605; + _summerOnEndFrame2 = 664; + _autumnOnStartFrame1 = 305; + _autumnOnEndFrame1 = 364; + _autumnOnStartFrame2 = 365; + _autumnOnEndFrame2 = 424; +} + +void CArboretumGate::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_seasonNum, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_initialFrame, indent); + file->writeNumberLine(_v3, indent); + file->writeQuotedLine(_viewName1, indent); + file->writeNumberLine(_fieldF0, indent); + file->writeNumberLine(_winterOffStartFrame, indent); + file->writeNumberLine(_winterOffEndFrame, indent); + file->writeNumberLine(_springOffStartFrame, indent); + file->writeNumberLine(_springOffEndFrame, indent); + file->writeNumberLine(_summerOffStartFrame1, indent); + file->writeNumberLine(_summerOffEndFrame1, indent); + file->writeNumberLine(_summerOffStartFrame2, indent); + file->writeNumberLine(_summerOffEndFrame2, indent); + file->writeNumberLine(_autumnOffStartFrame1, indent); + file->writeNumberLine(_autumnOffEndFrame1, indent); + file->writeNumberLine(_autumnOffStartFrame2, indent); + file->writeNumberLine(_autumnOffEndFrame2, indent); + file->writeNumberLine(_winterOnStartFrame, indent); + file->writeNumberLine(_winterOnEndFrame, indent); + file->writeNumberLine(_springOnStartFrame, indent); + file->writeNumberLine(_springOnEndFrame, indent); + file->writeNumberLine(_summerOnStartFrame1, indent); + file->writeNumberLine(_summerOnEndFrame1, indent); + file->writeNumberLine(_summerOnStartFrame2, indent); + file->writeNumberLine(_summerOnEndFrame2, indent); + file->writeNumberLine(_autumnOnStartFrame1, indent); + file->writeNumberLine(_autumnOnEndFrame1, indent); + file->writeNumberLine(_autumnOnStartFrame2, indent); + file->writeNumberLine(_autumnOnEndFrame2, indent); + file->writeQuotedLine(_viewName2, indent); + + CBackground::save(file, indent); +} + +void CArboretumGate::load(SimpleFile *file) { + file->readNumber(); + _seasonNum = file->readNumber(); + _v1 = file->readNumber(); + _initialFrame = file->readNumber(); + _v3 = file->readNumber(); + _viewName1 = file->readString(); + _fieldF0 = file->readNumber(); + _winterOffStartFrame = file->readNumber(); + _winterOffEndFrame = file->readNumber(); + _springOffStartFrame = file->readNumber(); + _springOffEndFrame = file->readNumber(); + _summerOffStartFrame1 = file->readNumber(); + _summerOffEndFrame1 = file->readNumber(); + _summerOffStartFrame2 = file->readNumber(); + _summerOffEndFrame2 = file->readNumber(); + _autumnOffStartFrame1 = file->readNumber(); + _autumnOffEndFrame1 = file->readNumber(); + _autumnOffStartFrame2 = file->readNumber(); + _autumnOffEndFrame2 = file->readNumber(); + _winterOnStartFrame = file->readNumber(); + _winterOnEndFrame = file->readNumber(); + _springOnStartFrame = file->readNumber(); + _springOnEndFrame = file->readNumber(); + _summerOnStartFrame1 = file->readNumber(); + _summerOnEndFrame1 = file->readNumber(); + _summerOnStartFrame2 = file->readNumber(); + _summerOnEndFrame2 = file->readNumber(); + _autumnOnStartFrame1 = file->readNumber(); + _autumnOnEndFrame1 = file->readNumber(); + _autumnOnStartFrame2 = file->readNumber(); + _autumnOnEndFrame2 = file->readNumber(); + _viewName2 = file->readString(); + + CBackground::load(file); +} + +bool CArboretumGate::ChangeSeasonMsg(CChangeSeasonMsg *msg) { + _seasonNum = (_seasonNum + 1) % 4; + return true; +} + +bool CArboretumGate::ActMsg(CActMsg *msg) { + if (msg->_action == "PlayerGetsSpeechCentre") { + _v1 = 1; + CVisibleMsg visibleMsg(true); + visibleMsg.execute("SpCtrOverlay"); + } else if (msg->_action == "ExitLFrozen") { + if (_v3) { + _viewName2 = "FrozenArboretum.Node 2.W"; + CTurnOn onMsg; + onMsg.execute(this); + } else { + changeView("FrozenArboretum.Node 2.W"); + } + } else if (msg->_action == "ExitRFrozen") { + if (_v3) { + _viewName2 = "FrozenArboretum.Node 2.E"; + CTurnOn onMsg; + onMsg.execute(this); + } else { + changeView("FrozenArboretum.Node 2.E"); + } + } else if (msg->_action == "ExitLNormal") { + if (_v3) { + _viewName2 = "Arboretum.Node 2.W"; + CTurnOn onMsg; + onMsg.execute(this); + } else { + changeView("Arboretum.Node 2.W"); + } + } else if (msg->_action == "ExitRNormal") { + if (_v3) { + _viewName2 = "Arboretum.Node 2.E"; + CTurnOn onMsg; + onMsg.execute(this); + } + else { + changeView("Arboretum.Node 2.E"); + } + } + + return true; +} + +bool CArboretumGate::MovieEndMsg(CMovieEndMsg *msg) { + setVisible(!_v3); + + if (_viewName1 != "NULL") { + changeView(_viewName1); + } else if (_viewName2 != "NULL") { + changeView(_viewName2); + _viewName2 = "NULL"; + } + + return true; +} + +bool CArboretumGate::LeaveViewMsg(CLeaveViewMsg *msg) { + return false; +} + +bool CArboretumGate::TurnOff(CTurnOff *msg) { + if (!_v3) { + switch (_seasonNum) { + case SPRING: + playMovie(_springOffStartFrame, _springOffEndFrame, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + break; + + case SUMMER: + if (_v1) { + playMovie(_summerOffStartFrame2, _summerOffEndFrame2, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + } else { + playMovie(_summerOffStartFrame1, _summerOffEndFrame1, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + } + break; + + case AUTUMN: + if (_v1) { + playMovie(_autumnOffStartFrame2, _autumnOffEndFrame2, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + } else { + playMovie(_autumnOffStartFrame1, _autumnOffEndFrame1, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + } + break; + + case WINTER: + playMovie(_winterOffStartFrame, _winterOffEndFrame, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + break; + + default: + break; + } + + _v3 = 1; + CArboretumGateMsg gateMsg; + gateMsg.execute("Arboretum", nullptr, MSGFLAG_SCAN); + } + + return true; +} + +bool CArboretumGate::TurnOn(CTurnOn *msg) { + if (_v3) { + CArboretumGateMsg gateMsg(0); + gateMsg.execute("Arboretum"); + setVisible(true); + + switch (_seasonNum) { + case SPRING: + playMovie(_springOnStartFrame, _springOnEndFrame, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + break; + + case SUMMER: + if (_v1) { + playMovie(_summerOnStartFrame2, _summerOnEndFrame2, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + } else { + playMovie(_summerOnStartFrame1, _summerOnEndFrame1, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + } + break; + + case AUTUMN: + if (_v1) { + playMovie(_autumnOnStartFrame2, _autumnOnEndFrame2, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + } else { + playMovie(_autumnOnStartFrame1, _autumnOnEndFrame1, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + } + break; + + case WINTER: + playMovie(_winterOnStartFrame, _winterOnEndFrame, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + break; + + default: + break; + } + + _v3 = 0; + } + + return true; +} + +bool CArboretumGate::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if (!_v3) { + CTurnOff offMsg; + offMsg.execute(this); + } + + return true; +} + +bool CArboretumGate::EnterViewMsg(CEnterViewMsg *msg) { + if (!_v3) { + switch (_seasonNum) { + case SPRING: + _initialFrame = _springOffStartFrame; + break; + + case SUMMER: + _initialFrame = _v1 ? _summerOffStartFrame2 : _summerOffStartFrame1; + break; + + case AUTUMN: + _initialFrame = _v1 ? _autumnOffStartFrame1 : _autumnOffStartFrame2; + break; + + case WINTER: + _initialFrame = _winterOffStartFrame; + break; + + default: + break; + } + + loadFrame(_initialFrame); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/arboretum_gate.h b/engines/titanic/game/arboretum_gate.h new file mode 100644 index 0000000000..62c9200a64 --- /dev/null +++ b/engines/titanic/game/arboretum_gate.h @@ -0,0 +1,92 @@ +/* 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 TITANIC_ARBORETUM_GATE_H +#define TITANIC_ARBORETUM_GATE_H + +#include "titanic/core/background.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +class CArboretumGate : public CBackground { + DECLARE_MESSAGE_MAP; + bool ChangeSeasonMsg(CChangeSeasonMsg *msg); + bool ActMsg(CActMsg *msg); + bool MovieEndMsg(CMovieEndMsg *msg); + bool LeaveViewMsg(CLeaveViewMsg *msg); + bool TurnOff(CTurnOff *msg); + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool EnterViewMsg(CEnterViewMsg *msg); + bool TurnOn(CTurnOn *msg); +private: + static int _v1; + static int _initialFrame; + static int _v3; +private: + int _seasonNum; + CString _viewName1; + int _fieldF0; + int _winterOffStartFrame; + int _winterOffEndFrame; + int _springOffStartFrame; + int _springOffEndFrame; + int _summerOffStartFrame2; + int _summerOffEndFrame2; + int _summerOffStartFrame1; + int _summerOffEndFrame1; + int _autumnOffStartFrame2; + int _autumnOffEndFrame2; + int _autumnOffStartFrame1; + int _autumnOffEndFrame1; + int _winterOnStartFrame; + int _winterOnEndFrame; + int _springOnStartFrame; + int _springOnEndFrame; + int _summerOnStartFrame1; + int _summerOnEndFrame1; + int _summerOnStartFrame2; + int _summerOnEndFrame2; + int _autumnOnStartFrame1; + int _autumnOnEndFrame1; + int _autumnOnStartFrame2; + int _autumnOnEndFrame2; + CString _viewName2; +public: + CLASSDEF; + CArboretumGate(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ARBORETUM_GATE_H */ diff --git a/engines/titanic/game/auto_animate.cpp b/engines/titanic/game/auto_animate.cpp new file mode 100644 index 0000000000..16e6e56747 --- /dev/null +++ b/engines/titanic/game/auto_animate.cpp @@ -0,0 +1,68 @@ +/* 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 "titanic/game/auto_animate.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CAutoAnimate, CBackground) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(InitializeAnimMsg) +END_MESSAGE_MAP() + +void CAutoAnimate::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_enabled, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_repeat, indent); + CBackground::save(file, indent); +} + +void CAutoAnimate::load(SimpleFile *file) { + file->readNumber(); + _enabled = file->readNumber(); + _fieldE4 = file->readNumber(); + _repeat = file->readNumber(); + CBackground::load(file); +} + +bool CAutoAnimate::EnterViewMsg(CEnterViewMsg *msg) { + if (_enabled) { + uint flags = _repeat ? MOVIE_REPEAT : 0; + if (_startFrame != _endFrame) + playMovie(_startFrame, _endFrame, flags); + else + playMovie(flags); + + if (!_fieldE4) + _enabled = false; + } + + return true; +} + +bool CAutoAnimate::InitializeAnimMsg(CInitializeAnimMsg *msg) { + _enabled = true; + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/auto_animate.h b/engines/titanic/game/auto_animate.h new file mode 100644 index 0000000000..735aba922e --- /dev/null +++ b/engines/titanic/game/auto_animate.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_AUTO_ANIMATE_H +#define TITANIC_AUTO_ANIMATE_H + +#include "titanic/core/background.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CAutoAnimate : public CBackground { + DECLARE_MESSAGE_MAP; + bool EnterViewMsg(CEnterViewMsg *msg); + bool InitializeAnimMsg(CInitializeAnimMsg *msg); +private: + bool _enabled; + int _fieldE4; + bool _repeat; +public: + CLASSDEF; + CAutoAnimate() : CBackground(), _enabled(true), _fieldE4(1), _repeat(false) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_AUTO_ANIMATE_H */ diff --git a/engines/titanic/game/bar_bell.cpp b/engines/titanic/game/bar_bell.cpp new file mode 100644 index 0000000000..207644a00e --- /dev/null +++ b/engines/titanic/game/bar_bell.cpp @@ -0,0 +1,131 @@ +/* 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 "titanic/game/bar_bell.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CBarBell, CGameObject) + ON_MESSAGE(EnterRoomMsg) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(MouseButtonUpMsg) + ON_MESSAGE(ActMsg) +END_MESSAGE_MAP() + +CBarBell::CBarBell() : CGameObject(), _fieldBC(0), + _volume(65), _soundVal3(0), _fieldC8(0), _fieldCC(0) { +} + +void CBarBell::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_volume, indent); + file->writeNumberLine(_soundVal3, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeNumberLine(_fieldCC, indent); + + CGameObject::save(file, indent); +} + +void CBarBell::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _volume = file->readNumber(); + _soundVal3 = file->readNumber(); + _fieldC8 = file->readNumber(); + _fieldCC = file->readNumber(); + + CGameObject::load(file); +} + +bool CBarBell::EnterRoomMsg(CEnterRoomMsg *msg) { + _fieldBC = 0; + return true; +} + +bool CBarBell::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if ((_fieldC8 % 3) == 2) { + switch (_fieldBC) { + case 0: + case 1: + case 5: + playSound("c#54.wav", _volume, _soundVal3); + break; + + case 2: + playSound("c#52.wav", _volume, _soundVal3); + break; + + case 3: + playSound("c#53.wav", _volume, _soundVal3); + break; + + case 4: + playSound("c#55.wav", _volume, _soundVal3); + break; + + default: + playSound("c#51.wav", _volume, _soundVal3); + break; + } + } else if (_fieldBC >= 5) { + if (_fieldBC == 6) { + CActMsg actMsg("BellRing3"); + actMsg.execute("Barbot"); + } + + playSound("c#51.wav", _volume, _soundVal3); + } else { + if (_fieldBC == 3) { + CActMsg actMsg("BellRing1"); + actMsg.execute("Barbot"); + } else if (_fieldBC == 4) { + CActMsg actMsg("BellRing2"); + actMsg.execute("Barbot"); + } + + playSound("c#54.wav", _volume, _soundVal3); + } + + return true; +} + +bool CBarBell::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + if (!_fieldBC) { + CTurnOn onMsg; + onMsg.execute("Barbot"); + } + + ++_fieldBC; + return 2; +} + +bool CBarBell::ActMsg(CActMsg *msg) { + if (msg->_action == "ResetCount") { + _fieldBC = 0; + ++_fieldC8; + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/bar_bell.h b/engines/titanic/game/bar_bell.h new file mode 100644 index 0000000000..b50fe505ba --- /dev/null +++ b/engines/titanic/game/bar_bell.h @@ -0,0 +1,60 @@ +/* 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 TITANIC_BAR_BELL_H +#define TITANIC_BAR_BELL_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CBarBell : public CGameObject { + DECLARE_MESSAGE_MAP; + bool EnterRoomMsg(CEnterRoomMsg *msg); + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); + bool ActMsg(CActMsg *msg); +public: + int _fieldBC; + int _volume; + int _soundVal3; + int _fieldC8; + int _fieldCC; +public: + CLASSDEF; + CBarBell(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BAR_BELL_H */ diff --git a/engines/titanic/game/bar_menu.cpp b/engines/titanic/game/bar_menu.cpp new file mode 100644 index 0000000000..b24c429c9b --- /dev/null +++ b/engines/titanic/game/bar_menu.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/game/bar_menu.h" + +namespace Titanic { + +CBarMenu::CBarMenu() : CGameObject(), _fieldBC(0), _fieldC0(0), _fieldC4(6) { +} + +void CBarMenu::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + + CGameObject::save(file, indent); +} + +void CBarMenu::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/bar_menu.h b/engines/titanic/game/bar_menu.h new file mode 100644 index 0000000000..84c0219084 --- /dev/null +++ b/engines/titanic/game/bar_menu.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_BAR_MENU_H +#define TITANIC_BAR_MENU_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CBarMenu : public CGameObject { +public: + int _fieldBC; + int _fieldC0; + int _fieldC4; +public: + CLASSDEF; + CBarMenu(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BAR_MENU_H */ diff --git a/engines/titanic/game/bar_menu_button.cpp b/engines/titanic/game/bar_menu_button.cpp new file mode 100644 index 0000000000..f57d72c64a --- /dev/null +++ b/engines/titanic/game/bar_menu_button.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/bar_menu_button.h" + +namespace Titanic { + +void CBarMenuButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CBarMenuButton::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/bar_menu_button.h b/engines/titanic/game/bar_menu_button.h new file mode 100644 index 0000000000..c666df413b --- /dev/null +++ b/engines/titanic/game/bar_menu_button.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_BAR_MENU_BUTTON_H +#define TITANIC_BAR_MENU_BUTTON_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CBarMenuButton : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CBarMenuButton() : CGameObject(), _value(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BAR_MENU_BUTTON_H */ diff --git a/engines/titanic/game/belbot_get_light.cpp b/engines/titanic/game/belbot_get_light.cpp new file mode 100644 index 0000000000..3e678a8a0c --- /dev/null +++ b/engines/titanic/game/belbot_get_light.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/belbot_get_light.h" + +namespace Titanic { + +void CBelbotGetLight::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_value, indent); + CGameObject::save(file, indent); +} + +void CBelbotGetLight::load(SimpleFile *file) { + file->readNumber(); + _value = file->readString(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/belbot_get_light.h b/engines/titanic/game/belbot_get_light.h new file mode 100644 index 0000000000..a3aa0f737e --- /dev/null +++ b/engines/titanic/game/belbot_get_light.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_BELBOT_GET_LIGHT_H +#define TITANIC_BELBOT_GET_LIGHT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CBelbotGetLight : public CGameObject { +private: + CString _value; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LIGHT_H */ diff --git a/engines/titanic/game/bilge_succubus.cpp b/engines/titanic/game/bilge_succubus.cpp new file mode 100644 index 0000000000..ceee3f7740 --- /dev/null +++ b/engines/titanic/game/bilge_succubus.cpp @@ -0,0 +1,51 @@ +/* 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 "titanic/game/bilge_succubus.h" + +namespace Titanic { + +CBilgeSuccUBus::CBilgeSuccUBus() : CSuccUBus(), _field1DC(0), + _field1E0(0), _field1E4(0), _field1E8(0) { +} + +void CBilgeSuccUBus::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field1DC, indent); + file->writeNumberLine(_field1E0, indent); + file->writeNumberLine(_field1E4, indent); + file->writeNumberLine(_field1E8, indent); + + CSuccUBus::save(file, indent); +} + +void CBilgeSuccUBus::load(SimpleFile *file) { + file->readNumber(); + _field1DC = file->readNumber(); + _field1E0 = file->readNumber(); + _field1E4 = file->readNumber(); + _field1E8 = file->readNumber(); + + CSuccUBus::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/bilge_succubus.h b/engines/titanic/game/bilge_succubus.h new file mode 100644 index 0000000000..4b2a626dc2 --- /dev/null +++ b/engines/titanic/game/bilge_succubus.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_BILGE_SUCCUBUS_H +#define TITANIC_BILGE_SUCCUBUS_H + +#include "titanic/npcs/succubus.h" + +namespace Titanic { + +class CBilgeSuccUBus : public CSuccUBus { +public: + int _field1DC; + int _field1E0; + int _field1E4; + int _field1E8; +public: + CLASSDEF; + CBilgeSuccUBus(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BILGE_SUCCUBUS_H */ diff --git a/engines/titanic/game/bomb.cpp b/engines/titanic/game/bomb.cpp new file mode 100644 index 0000000000..9a08f26ece --- /dev/null +++ b/engines/titanic/game/bomb.cpp @@ -0,0 +1,81 @@ +/* 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 "titanic/game/bomb.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CBomb::CBomb() : CBackground() { + _fieldE0 = 0; + _fieldE4 = 0; + _fieldE8 = 17; + _fieldEC = 9; + _fieldF0 = 0; + _fieldF4 = 999; + _fieldF8 = 0; + _fieldFC = 0; + _startingTicks = 0; + _field104 = 60; +} + +void CBomb::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_fieldF0, indent); + file->writeNumberLine(_fieldF4, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_fieldFC, indent); + file->writeNumberLine(_startingTicks, indent); + file->writeNumberLine(_field104, indent); + + CBackground::save(file, indent); +} + +void CBomb::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + _fieldF0 = file->readNumber(); + _fieldF4 = file->readNumber(); + _fieldF8 = file->readNumber(); + _fieldFC = file->readNumber(); + _startingTicks = file->readNumber(); + _field104 = file->readNumber(); + + CBackground::load(file); +} + +bool CBomb::EnterRoomMsg(CEnterRoomMsg *msg) { + _fieldE8 = 12; + _fieldEC = 9; + _fieldF0 = 0; + _startingTicks = g_vm->_events->getTicksCount(); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/bomb.h b/engines/titanic/game/bomb.h new file mode 100644 index 0000000000..ab4df16db0 --- /dev/null +++ b/engines/titanic/game/bomb.h @@ -0,0 +1,61 @@ +/* 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 TITANIC_BOMB_H +#define TITANIC_BOMB_H + +#include "titanic/core/background.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CBomb : public CBackground { + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; + int _fieldF0; + int _fieldF4; + int _fieldF8; + int _fieldFC; + int _startingTicks; + int _field104; +public: + CLASSDEF; + CBomb(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BOMB_H */ diff --git a/engines/titanic/game/bottom_of_well_monitor.cpp b/engines/titanic/game/bottom_of_well_monitor.cpp new file mode 100644 index 0000000000..beb2a80ce9 --- /dev/null +++ b/engines/titanic/game/bottom_of_well_monitor.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/game/bottom_of_well_monitor.h" + +namespace Titanic { + +int CBottomOfWellMonitor::_v1; +int CBottomOfWellMonitor::_v2; + +void CBottomOfWellMonitor::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CBottomOfWellMonitor::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/bottom_of_well_monitor.h b/engines/titanic/game/bottom_of_well_monitor.h new file mode 100644 index 0000000000..65424aad70 --- /dev/null +++ b/engines/titanic/game/bottom_of_well_monitor.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_BOTTOM_OF_WELL_MONITOR_H +#define TITANIC_BOTTOM_OF_WELL_MONITOR_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CBottomOfWellMonitor : public CGameObject { +public: + static int _v1, _v2; + int _value; +public: + CLASSDEF; + CBottomOfWellMonitor() : _value(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BOTTOM_OF_WELL_MONITOR_H */ diff --git a/engines/titanic/game/bowl_unlocker.cpp b/engines/titanic/game/bowl_unlocker.cpp new file mode 100644 index 0000000000..c3c501dbd6 --- /dev/null +++ b/engines/titanic/game/bowl_unlocker.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/bowl_unlocker.h" + +namespace Titanic { + +void CBowlUnlocker::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CBowlUnlocker::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/bowl_unlocker.h b/engines/titanic/game/bowl_unlocker.h new file mode 100644 index 0000000000..2559ac2c52 --- /dev/null +++ b/engines/titanic/game/bowl_unlocker.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_BOWL_UNLOCKER_H +#define TITANIC_BOWL_UNLOCKER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CBowlUnlocker : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CBowlUnlocker() : CGameObject(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BOWL_UNLOCKER_H */ diff --git a/engines/titanic/game/brain_slot.cpp b/engines/titanic/game/brain_slot.cpp new file mode 100644 index 0000000000..f1963142ac --- /dev/null +++ b/engines/titanic/game/brain_slot.cpp @@ -0,0 +1,50 @@ +/* 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 "titanic/game/brain_slot.h" + +namespace Titanic { + +int CBrainSlot::_v1; +int CBrainSlot::_v2; + +void CBrainSlot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value1, indent); + file->writeQuotedLine(_value2, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + + CGameObject::save(file, indent); +} + +void CBrainSlot::load(SimpleFile *file) { + file->readNumber(); + _value1 = file->readNumber(); + _value2 = file->readString(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/brain_slot.h b/engines/titanic/game/brain_slot.h new file mode 100644 index 0000000000..94b6d7f227 --- /dev/null +++ b/engines/titanic/game/brain_slot.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_BRAIN_SLOT_H +#define TITANIC_BRAIN_SLOT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CBrainSlot : public CGameObject { +public: + static int _v1, _v2; +public: + int _value1; + CString _value2; +public: + CLASSDEF; + CBrainSlot() : CGameObject(), _value1(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BRAIN_SLOT_H */ diff --git a/engines/titanic/game/bridge_door.cpp b/engines/titanic/game/bridge_door.cpp new file mode 100644 index 0000000000..57cdbd23ad --- /dev/null +++ b/engines/titanic/game/bridge_door.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/bridge_door.h" + +namespace Titanic { + +void CBridgeDoor::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CBridgeDoor::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/bridge_door.h b/engines/titanic/game/bridge_door.h new file mode 100644 index 0000000000..c1872a29be --- /dev/null +++ b/engines/titanic/game/bridge_door.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_BRIDGE_DOOR_H +#define TITANIC_BRIDGE_DOOR_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CBridgeDoor : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BRIDGE_DOOR_H */ diff --git a/engines/titanic/game/bridge_view.cpp b/engines/titanic/game/bridge_view.cpp new file mode 100644 index 0000000000..9854969494 --- /dev/null +++ b/engines/titanic/game/bridge_view.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/bridge_view.h" + +namespace Titanic { + +void CBridgeView::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + CBackground::save(file, indent); +} + +void CBridgeView::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/bridge_view.h b/engines/titanic/game/bridge_view.h new file mode 100644 index 0000000000..d7c7c35aa9 --- /dev/null +++ b/engines/titanic/game/bridge_view.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_BRIDGE_VIEW_H +#define TITANIC_BRIDGE_VIEW_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CBridgeView : public CBackground { +public: + int _fieldE0; +public: + CLASSDEF; + CBridgeView() : CBackground(), _fieldE0(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BRIDGE_VIEW_H */ diff --git a/engines/titanic/game/broken_pell_base.cpp b/engines/titanic/game/broken_pell_base.cpp new file mode 100644 index 0000000000..59e2b9bca1 --- /dev/null +++ b/engines/titanic/game/broken_pell_base.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/game/broken_pell_base.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CBrokenPellBase, CBackground); + +int CBrokenPellBase::_v1; +int CBrokenPellBase::_v2; + +void CBrokenPellBase::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + file->writeNumberLine(_fieldE0, indent); + CBackground::save(file, indent); +} + +void CBrokenPellBase::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + _fieldE0 = file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/broken_pell_base.h b/engines/titanic/game/broken_pell_base.h new file mode 100644 index 0000000000..f63cd0112b --- /dev/null +++ b/engines/titanic/game/broken_pell_base.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_BROKEN_PELL_BASE_H +#define TITANIC_BROKEN_PELL_BASE_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CBrokenPellBase : public CBackground { + DECLARE_MESSAGE_MAP; +private: + static int _v1; + static int _v2; + + int _fieldE0; +public: + CLASSDEF; + CBrokenPellBase() : CBackground(), _fieldE0(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BROKEN_PELL_BASE_H */ diff --git a/engines/titanic/game/broken_pellerator.cpp b/engines/titanic/game/broken_pellerator.cpp new file mode 100644 index 0000000000..d3b204b1e5 --- /dev/null +++ b/engines/titanic/game/broken_pellerator.cpp @@ -0,0 +1,47 @@ +/* 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 "titanic/game/broken_pellerator.h" + +namespace Titanic { + +void CBrokenPellerator::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string2, indent); + file->writeQuotedLine(_string3, indent); + file->writeQuotedLine(_string4, indent); + file->writeQuotedLine(_string5, indent); + + CBrokenPellBase::save(file, indent); +} + +void CBrokenPellerator::load(SimpleFile *file) { + file->readNumber(); + _string2 = file->readString(); + _string3 = file->readString(); + _string4 = file->readString(); + _string5 = file->readString(); + + CBrokenPellBase::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/broken_pellerator.h b/engines/titanic/game/broken_pellerator.h new file mode 100644 index 0000000000..6fbde91053 --- /dev/null +++ b/engines/titanic/game/broken_pellerator.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_BROKEN_PELLERATOR_H +#define TITANIC_BROKEN_PELLERATOR_H + +#include "titanic/game/broken_pell_base.h" + +namespace Titanic { + +class CBrokenPellerator : public CBrokenPellBase { +private: + CString _string2; + CString _string3; + CString _string4; + CString _string5; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BROKEN_PELLERATOR_H */ diff --git a/engines/titanic/game/broken_pellerator_froz.cpp b/engines/titanic/game/broken_pellerator_froz.cpp new file mode 100644 index 0000000000..4b21ea93d0 --- /dev/null +++ b/engines/titanic/game/broken_pellerator_froz.cpp @@ -0,0 +1,47 @@ +/* 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 "titanic/game/broken_pellerator_froz.h" + +namespace Titanic { + +void CBrokenPelleratorFroz::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string2, indent); + file->writeQuotedLine(_string3, indent); + file->writeQuotedLine(_string4, indent); + file->writeQuotedLine(_string5, indent); + + CBrokenPellBase::save(file, indent); +} + +void CBrokenPelleratorFroz::load(SimpleFile *file) { + file->readNumber(); + _string2 = file->readString(); + _string3 = file->readString(); + _string4 = file->readString(); + _string5 = file->readString(); + + CBrokenPellBase::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/broken_pellerator_froz.h b/engines/titanic/game/broken_pellerator_froz.h new file mode 100644 index 0000000000..1df6d2d0b2 --- /dev/null +++ b/engines/titanic/game/broken_pellerator_froz.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_BROKEN_PELLERATOR_FROZ_H +#define TITANIC_BROKEN_PELLERATOR_FROZ_H + +#include "titanic/game/broken_pell_base.h" + +namespace Titanic { + +class CBrokenPelleratorFroz : public CBrokenPellBase { +private: + CString _string2; + CString _string3; + CString _string4; + CString _string5; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BROKEN_PELLERATOR_FROZ_H */ diff --git a/engines/titanic/game/cage.cpp b/engines/titanic/game/cage.cpp new file mode 100644 index 0000000000..7fbc052278 --- /dev/null +++ b/engines/titanic/game/cage.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/game/cage.h" + +namespace Titanic { + +int CCage::_v1; +int CCage::_v2; + +void CCage::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + + CBackground::save(file, indent); +} + +void CCage::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/cage.h b/engines/titanic/game/cage.h new file mode 100644 index 0000000000..bbce978489 --- /dev/null +++ b/engines/titanic/game/cage.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_CAGE_H +#define TITANIC_CAGE_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CCage : public CBackground { +public: + static int _v1; + static int _v2; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CAGE_H */ diff --git a/engines/titanic/game/call_pellerator.cpp b/engines/titanic/game/call_pellerator.cpp new file mode 100644 index 0000000000..0ea48131b1 --- /dev/null +++ b/engines/titanic/game/call_pellerator.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/call_pellerator.h" + +namespace Titanic { + +void CCallPellerator::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CCallPellerator::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/call_pellerator.h b/engines/titanic/game/call_pellerator.h new file mode 100644 index 0000000000..7da4b40794 --- /dev/null +++ b/engines/titanic/game/call_pellerator.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_CALL_PELLERATOR_H +#define TITANIC_CALL_PELLERATOR_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CCallPellerator : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CALL_PELLERATOR_H */ diff --git a/engines/titanic/game/captains_wheel.cpp b/engines/titanic/game/captains_wheel.cpp new file mode 100644 index 0000000000..c84c9194ce --- /dev/null +++ b/engines/titanic/game/captains_wheel.cpp @@ -0,0 +1,56 @@ +/* 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 "titanic/game/captains_wheel.h" + +namespace Titanic { + +CCaptainsWheel::CCaptainsWheel() : CBackground(), + _fieldE0(0), _fieldE4(0), _fieldE8(0), _fieldEC(0), + _fieldF0(0), _fieldF4(0) { +} + +void CCaptainsWheel::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_fieldF0, indent); + file->writeNumberLine(_fieldF4, indent); + + CBackground::save(file, indent); +} + +void CCaptainsWheel::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + _fieldF0 = file->readNumber(); + _fieldF4 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/captains_wheel.h b/engines/titanic/game/captains_wheel.h new file mode 100644 index 0000000000..549dcbe685 --- /dev/null +++ b/engines/titanic/game/captains_wheel.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_CAPTAINS_WHEEL_H +#define TITANIC_CAPTAINS_WHEEL_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CCaptainsWheel : public CBackground { +public: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; + int _fieldF0; + int _fieldF4; +public: + CLASSDEF; + CCaptainsWheel(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CAPTAINS_WHEEL_H */ diff --git a/engines/titanic/game/cdrom.cpp b/engines/titanic/game/cdrom.cpp new file mode 100644 index 0000000000..cd913d05f7 --- /dev/null +++ b/engines/titanic/game/cdrom.cpp @@ -0,0 +1,88 @@ +/* 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 "titanic/game/cdrom.h" +#include "titanic/core/room_item.h" +#include "titanic/game/cdrom_tray.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CCDROM, CGameObject) + ON_MESSAGE(MouseDragStartMsg) + ON_MESSAGE(MouseDragEndMsg) + ON_MESSAGE(MouseDragMoveMsg) + ON_MESSAGE(ActMsg) +END_MESSAGE_MAP() + +CCDROM::CCDROM() : CGameObject() { +} + +void CCDROM::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writePoint(_tempPos, indent); + CGameObject::save(file, indent); +} + +void CCDROM::load(SimpleFile *file) { + file->readNumber(); + _tempPos = file->readPoint(); + CGameObject::load(file); +} + +bool CCDROM::MouseDragStartMsg(CMouseDragStartMsg *msg) { + if (checkStartDragging(msg)) { + _tempPos = msg->_mousePos - _bounds; + setPosition(msg->_mousePos - _tempPos); + return true; + } else { + return false; + } +} + +bool CCDROM::MouseDragEndMsg(CMouseDragEndMsg *msg) { + if (msg->_dropTarget && msg->_dropTarget->getName() == "newComputer") { + CCDROMTray *newTray = dynamic_cast<CCDROMTray *>(getRoom()->findByName("newTray")); + + if (newTray->_isOpened && newTray->_insertedCD == "None") { + CActMsg actMsg(getName()); + actMsg.execute(newTray); + setVisible(false); + } + } + + resetPosition(); + return true; +} + +bool CCDROM::MouseDragMoveMsg(CMouseDragMoveMsg *msg) { + setPosition(msg->_mousePos - _tempPos); + return true; +} + +bool CCDROM::ActMsg(CActMsg *msg) { + if (msg->_action == "Ejected") + setVisible(true); + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/cdrom.h b/engines/titanic/game/cdrom.h new file mode 100644 index 0000000000..017914830c --- /dev/null +++ b/engines/titanic/game/cdrom.h @@ -0,0 +1,57 @@ +/* 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 TITANIC_CDROM_H +#define TITANIC_CDROM_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +class CCDROM : public CGameObject { + DECLARE_MESSAGE_MAP; + bool MouseDragStartMsg(CMouseDragStartMsg *msg); + bool MouseDragEndMsg(CMouseDragEndMsg *msg); + bool MouseDragMoveMsg(CMouseDragMoveMsg *msg); + bool ActMsg(CActMsg *msg); +private: + Point _tempPos; +public: + CLASSDEF; + CCDROM(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CDROM_H */ diff --git a/engines/titanic/game/cdrom_computer.cpp b/engines/titanic/game/cdrom_computer.cpp new file mode 100644 index 0000000000..ceb0595188 --- /dev/null +++ b/engines/titanic/game/cdrom_computer.cpp @@ -0,0 +1,78 @@ +/* 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 "titanic/game/cdrom_computer.h" +#include "titanic/core/room_item.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CCDROMComputer, CGameObject) + ON_MESSAGE(MouseButtonDownMsg) +END_MESSAGE_MAP() + +CCDROMComputer::CCDROMComputer() : CGameObject(), + _clickRect(0, 3, 55, 32) { +} + +void CCDROMComputer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_clickRect.left, indent); + file->writeNumberLine(_clickRect.top, indent); + file->writeNumberLine(_clickRect.right, indent); + file->writeNumberLine(_clickRect.bottom, indent); + + CGameObject::save(file, indent); +} + +void CCDROMComputer::load(SimpleFile *file) { + file->readNumber(); + _clickRect.left = file->readNumber(); + _clickRect.top = file->readNumber(); + _clickRect.right = file->readNumber(); + _clickRect.bottom = file->readNumber(); + + CGameObject::load(file); +} + +bool CCDROMComputer::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + CTreeItem *tray = getRoom()->findByName("newTray"); + if (tray) { + CStatusChangeMsg statusMsg; + statusMsg.execute(tray); + + if (!statusMsg._success) { + // Check if the mouse is within the clickable area + Rect tempRect = _clickRect; + tempRect.translate(_bounds.left, _bounds.top); + + if (!tempRect.contains(msg->_mousePos)) + return true; + } + + CActMsg actMsg("ClickedOn"); + actMsg.execute(tray); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/cdrom_computer.h b/engines/titanic/game/cdrom_computer.h new file mode 100644 index 0000000000..39fa9b9498 --- /dev/null +++ b/engines/titanic/game/cdrom_computer.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_CDROM_COMPUTER_H +#define TITANIC_CDROM_COMPUTER_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +class CCDROMComputer : public CGameObject { + DECLARE_MESSAGE_MAP; + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); +private: + Rect _clickRect; +public: + CLASSDEF; + CCDROMComputer(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CDROM_COMPUTER_H */ diff --git a/engines/titanic/game/cdrom_tray.cpp b/engines/titanic/game/cdrom_tray.cpp new file mode 100644 index 0000000000..1e5b135d35 --- /dev/null +++ b/engines/titanic/game/cdrom_tray.cpp @@ -0,0 +1,127 @@ +/* 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 "titanic/core/room_item.h" +#include "titanic/game/cdrom_tray.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CCDROMTray, CGameObject) + ON_MESSAGE(ActMsg) + ON_MESSAGE(MovieEndMsg) + ON_MESSAGE(StatusChangeMsg) +END_MESSAGE_MAP() + + +CCDROMTray::CCDROMTray() : CGameObject(), _isOpened(false) { +} + +void CCDROMTray::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_isOpened, indent); + file->writeQuotedLine(_insertedCD, indent); + + CGameObject::save(file, indent); +} + +void CCDROMTray::load(SimpleFile *file) { + file->readNumber(); + _isOpened = file->readNumber(); + _insertedCD = file->readString(); + + CGameObject::load(file); +} + +bool CCDROMTray::ActMsg(CActMsg *msg) { + if (msg->_action == "ClickedOn") { + if (_isOpened) { + // Closing the tray + if (_insertedCD == "None") { + // No CD in tray + playMovie(55, 65, 0); + playSound("a#35.wav", 50, 0, 0); + _isOpened = false; + } else { + // Ejecting tray with CD + CTreeItem *cdrom = getRoom()->findByName(_insertedCD); + if (cdrom) { + CActMsg actMsg("Ejected"); + actMsg.execute(cdrom); + } + + _insertedCD = "None"; + loadFrame(52); + } + } else if (_insertedCD == "None") { + // Opening tray with no CD + playMovie(44, 54, 0); + playSound("a#34.wav", 50, 0, 0); + _isOpened = true; + } else if (_insertedCD == "newCD1" || _insertedCD == "newCD2") { + // Opening tray with standard CD + playMovie(22, 32, 0); + playSound("a#34.wav", 50, 0, 0); + _isOpened = true; + } else if (_insertedCD == "newSTCD") { + // Opening tray with Starship Titanic CD + playMovie(0, 10, 0); + playSound("a#34.wav", 50, 0, 0); + _isOpened = true; + } + } else if (_isOpened) { + if (msg->_action == "newCD1" || msg->_action == "newCD2") { + // Standard CD dropped on CDROM Tray + playMovie(33, 43, MOVIE_NOTIFY_OBJECT); + playSound("a#35.wav", 50, 0, 0); + } else if (msg->_action == "newSTCD") { + // Starship Titanic CD dropped on CDROM Tray + playMovie(11, 21, MOVIE_NOTIFY_OBJECT); + playSound("a#35.wav", 50, 0, 0); + } else { + return true; + } + + _insertedCD = msg->_action; + _isOpened = false; + } + + return true; +} + +bool CCDROMTray::MovieEndMsg(CMovieEndMsg *msg) { + CTreeItem *screen = getRoom()->findByName("newScreen"); + + if (screen) { + CActMsg actMsg(_insertedCD); + actMsg.execute(screen); + } + + return true; +} + +bool CCDROMTray::StatusChangeMsg(CStatusChangeMsg *msg) { + msg->_success = _isOpened; + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/cdrom_tray.h b/engines/titanic/game/cdrom_tray.h new file mode 100644 index 0000000000..10fc1e145e --- /dev/null +++ b/engines/titanic/game/cdrom_tray.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_CDROM_TRAY_H +#define TITANIC_CDROM_TRAY_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CCDROMTray : public CGameObject { + DECLARE_MESSAGE_MAP; + bool ActMsg(CActMsg *msg); + bool MovieEndMsg(CMovieEndMsg *msg); + bool StatusChangeMsg(CStatusChangeMsg *msg); +public: + bool _isOpened; + CString _insertedCD; +public: + CLASSDEF; + CCDROMTray(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CDROM_TRAY_H */ diff --git a/engines/titanic/game/cell_point_button.cpp b/engines/titanic/game/cell_point_button.cpp new file mode 100644 index 0000000000..18ece09cb0 --- /dev/null +++ b/engines/titanic/game/cell_point_button.cpp @@ -0,0 +1,79 @@ +/* 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 "titanic/game/cell_point_button.h" + +namespace Titanic { + +CCellPointButton::CCellPointButton() : CBackground() { + _fieldE0 = 0; + _fieldE4 = 0; + _fieldE8 = 0; + _fieldEC = 0; + _fieldF0 = 0; + _fieldF4 = 0; + _fieldF8 = 0; + _fieldFC = 0; + _field100 = 0; + _field104 = 0; + _field108 = 1; +} + +void CCellPointButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_fieldF0, indent); + file->writeNumberLine(_fieldF4, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_fieldFC, indent); + file->writeNumberLine(_field100, indent); + file->writeNumberLine(_field104, indent); + file->writeNumberLine(_field108, indent); + file->writeQuotedLine(_string3, indent); + file->writeNumberLine(_field118, indent); + + CBackground::save(file, indent); +} + +void CCellPointButton::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + _fieldF0 = file->readNumber(); + _fieldF4 = file->readNumber(); + _fieldF8 = file->readNumber(); + _fieldFC = file->readNumber(); + _field100 = file->readNumber(); + _field104 = file->readNumber(); + _field108 = file->readNumber(); + _string3 = file->readString(); + _field118 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/cell_point_button.h b/engines/titanic/game/cell_point_button.h new file mode 100644 index 0000000000..6f1fdc3809 --- /dev/null +++ b/engines/titanic/game/cell_point_button.h @@ -0,0 +1,62 @@ +/* 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 TITANIC_CELL_POINT_BUTTON_H +#define TITANIC_CELL_POINT_BUTTON_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CCellPointButton : public CBackground { +public: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; + int _fieldF0; + int _fieldF4; + int _fieldF8; + int _fieldFC; + int _field100; + int _field104; + int _field108; + CString _string3; + int _field118; +public: + CLASSDEF; + CCellPointButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CELL_POINT_BUTTON_H */ diff --git a/engines/titanic/game/chev_code.cpp b/engines/titanic/game/chev_code.cpp new file mode 100644 index 0000000000..ebc20578b7 --- /dev/null +++ b/engines/titanic/game/chev_code.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/chev_code.h" + +namespace Titanic { + +void CChevCode::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CChevCode::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/chev_code.h b/engines/titanic/game/chev_code.h new file mode 100644 index 0000000000..c4552d00a2 --- /dev/null +++ b/engines/titanic/game/chev_code.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_CHEV_CODE_H +#define TITANIC_CHEV_CODE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CChevCode : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CChevCode() : CGameObject(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHEV_CODE_H */ diff --git a/engines/titanic/game/chev_panel.cpp b/engines/titanic/game/chev_panel.cpp new file mode 100644 index 0000000000..245968e356 --- /dev/null +++ b/engines/titanic/game/chev_panel.cpp @@ -0,0 +1,45 @@ +/* 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 "titanic/game/chev_panel.h" + +namespace Titanic { + +void CChevPanel::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + + CGameObject::save(file, indent); +} + +void CChevPanel::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/chev_panel.h b/engines/titanic/game/chev_panel.h new file mode 100644 index 0000000000..99b5501ac2 --- /dev/null +++ b/engines/titanic/game/chev_panel.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_CHEV_PANEL_H +#define TITANIC_CHEV_PANEL_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CChevPanel : public CGameObject { +public: + int _fieldBC; + int _fieldC0; + int _fieldC4; +public: + CLASSDEF; + CChevPanel() : _fieldBC(0), _fieldC0(0), _fieldC4(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHEV_PANEL_H */ diff --git a/engines/titanic/game/chicken_cooler.cpp b/engines/titanic/game/chicken_cooler.cpp new file mode 100644 index 0000000000..29232e10bf --- /dev/null +++ b/engines/titanic/game/chicken_cooler.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/game/chicken_cooler.h" + +namespace Titanic { + +void CChickenCooler::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + + CGameObject::save(file, indent); +} + +void CChickenCooler::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + + CGameObject::load(file); +} + +bool CChickenCooler::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CChickenCoolor::handlEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/chicken_cooler.h b/engines/titanic/game/chicken_cooler.h new file mode 100644 index 0000000000..724727b905 --- /dev/null +++ b/engines/titanic/game/chicken_cooler.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_CHICKEN_COOLER_H +#define TITANIC_CHICKEN_COOLER_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CChickenCooler : public CGameObject { + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + int _fieldBC; + int _fieldC0; +public: + CLASSDEF; + CChickenCooler() : CGameObject(), _fieldBC(0), _fieldC0(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHICKEN_COOLER_H */ diff --git a/engines/titanic/game/chicken_dispensor.cpp b/engines/titanic/game/chicken_dispensor.cpp new file mode 100644 index 0000000000..a9bf576765 --- /dev/null +++ b/engines/titanic/game/chicken_dispensor.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/game/chicken_dispensor.h" + +namespace Titanic { + +CChickenDispensor::CChickenDispensor() : CBackground(), + _fieldE0(0), _fieldE4(0), _fieldE8(0) { +} + +void CChickenDispensor::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + CBackground::save(file, indent); +} + +void CChickenDispensor::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/chicken_dispensor.h b/engines/titanic/game/chicken_dispensor.h new file mode 100644 index 0000000000..d86b850871 --- /dev/null +++ b/engines/titanic/game/chicken_dispensor.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_CHICKEN_DISPENSOR_H +#define TITANIC_CHICKEN_DISPENSOR_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CChickenDispensor : public CBackground { +public: + int _fieldE0; + int _fieldE4; + int _fieldE8; +public: + CLASSDEF; + CChickenDispensor(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHICKEN_DISPENSOR_H */ diff --git a/engines/titanic/game/close_broken_pel.cpp b/engines/titanic/game/close_broken_pel.cpp new file mode 100644 index 0000000000..d27441ac96 --- /dev/null +++ b/engines/titanic/game/close_broken_pel.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/close_broken_pel.h" + +namespace Titanic { + +void CCloseBrokenPel::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string3, indent); + CBackground::save(file, indent); +} + +void CCloseBrokenPel::load(SimpleFile *file) { + file->readNumber(); + _string3 = file->readString(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/close_broken_pel.h b/engines/titanic/game/close_broken_pel.h new file mode 100644 index 0000000000..aacda6c002 --- /dev/null +++ b/engines/titanic/game/close_broken_pel.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_CLOSE_BROKEN_PEL_H +#define TITANIC_CLOSE_BROKEN_PEL_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CCloseBrokenPel : public CBackground { +public: + CString _string3; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CLOSE_BROKEN_PEL_H */ diff --git a/engines/titanic/game/code_wheel.cpp b/engines/titanic/game/code_wheel.cpp new file mode 100644 index 0000000000..d8ce48e390 --- /dev/null +++ b/engines/titanic/game/code_wheel.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/game/code_wheel.h" + +namespace Titanic { + +CodeWheel::CodeWheel() : CBomb(), _field108(0), _field10C(4), _field110(0) { +} + +void CodeWheel::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field108, indent); + file->writeNumberLine(_field10C, indent); + file->writeNumberLine(_field110, indent); + + CBomb::save(file, indent); +} + +void CodeWheel::load(SimpleFile *file) { + file->readNumber(); + _field108 = file->readNumber(); + _field10C = file->readNumber(); + _field110 = file->readNumber(); + + CBomb::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/code_wheel.h b/engines/titanic/game/code_wheel.h new file mode 100644 index 0000000000..63af97c6fb --- /dev/null +++ b/engines/titanic/game/code_wheel.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_CODE_WHEEL_H +#define TITANIC_CODE_WHEEL_H + +#include "titanic/game/bomb.h" + +namespace Titanic { + +class CodeWheel : public CBomb { +private: + int _field108; + int _field10C; + int _field110; +public: + CLASSDEF; + CodeWheel(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CODE_WHEEL_H */ diff --git a/engines/titanic/game/computer.cpp b/engines/titanic/game/computer.cpp new file mode 100644 index 0000000000..90574997b1 --- /dev/null +++ b/engines/titanic/game/computer.cpp @@ -0,0 +1,106 @@ +/* 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 "titanic/game/computer.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CComputer, CBackground) + ON_MESSAGE(ActMsg) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(MovieEndMsg) +END_MESSAGE_MAP() + +void CComputer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_currentCD, indent); + file->writeNumberLine(_state, indent); + CBackground::save(file, indent); +} + +void CComputer::load(SimpleFile *file) { + file->readNumber(); + _currentCD = file->readString(); + _state = file->readNumber(); + CBackground::load(file); +} + +bool CComputer::ActMsg(CActMsg *msg) { + if (_state) { + playSound("a#35.wav", 100, 0, 0); + playMovie(32, 42, 0); + + if (msg->_action == "CD1") + playMovie(43, 49, 0); + else if (msg->_action == "CD2") + playMovie(50, 79, 0); + else if (msg->_action == "STCD") + playMovie(80, 90, 4); + + _currentCD = msg->_action; + _state = 0; + } + + return true; +} + +bool CComputer::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if (_currentCD == "None") { + if (_state) { + playSound("a#35.wav", 100, 0, 0); + playMovie(11, 21, 0); + _state = 0; + } else { + playSound("a#34.wav", 100, 0, 0); + playMovie(0, 10, 0); + _state = 1; + } + } else { + if (_state) { + loadFrame(11); + CActMsg actMsg("EjectCD"); + actMsg.execute(_currentCD); + _currentCD = "None"; + } else { + playSound("a#34.wav", 100, 0, 0); + playMovie(21, 31, 0); + _state = 1; + } + } + + return true; +} + +bool CComputer::MovieEndMsg(CMovieEndMsg *msg) { + if (msg->_endFrame == 90) { + playSound("a#32.wav", 100, 0, 0); + playSound("a#33.wav", 100, 0, 0); + playSound("a#31.wav", 100, 0, 0); + playSound("a#0.wav", 100, 0, 0); + + gotoView("Home.Node 4.E", "_TRACK,3,e-cu,4,E"); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/computer.h b/engines/titanic/game/computer.h new file mode 100644 index 0000000000..6acdba27ea --- /dev/null +++ b/engines/titanic/game/computer.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_COMPUTER_H +#define TITANIC_COMPUTER_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CComputer : public CBackground { + DECLARE_MESSAGE_MAP; + bool ActMsg(CActMsg *msg); + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool MovieEndMsg(CMovieEndMsg *msg); +public: + CString _currentCD; + int _state; +public: + CLASSDEF; + CComputer() : CBackground(), _currentCD("None"), _state(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_COMPUTER_H */ diff --git a/engines/titanic/game/computer_screen.cpp b/engines/titanic/game/computer_screen.cpp new file mode 100644 index 0000000000..3e5172219d --- /dev/null +++ b/engines/titanic/game/computer_screen.cpp @@ -0,0 +1,140 @@ +/* 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 "titanic/game/computer_screen.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CComputerScreen, CGameObject) + ON_MESSAGE(ActMsg) + ON_MESSAGE(MovieEndMsg) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(TimerMsg) +END_MESSAGE_MAP() + +CComputerScreen::CComputerScreen() : CGameObject() { +} + +void CComputerScreen::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CComputerScreen::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +bool CComputerScreen::ActMsg(CActMsg *msg) { + if (msg->_action == "newCD1" || msg->_action == "newCD2") { + playMovie(27, 53, MOVIE_GAMESTATE); + playMovie(19, 26, MOVIE_GAMESTATE); + } else if (msg->_action == "newSTCD") { + playMovie(0, 18, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT); + } + + return true; +} + +bool CComputerScreen::MovieEndMsg(CMovieEndMsg *msg) { + playSound("z#47.wav", 100, 0, 0); + addTimer(0, 3000, 0); + + for (int idx = 0; idx < 10; ++idx) + playMovie(0, 18, 0); + return true; +} + +bool CComputerScreen::EnterViewMsg(CEnterViewMsg *msg) { + loadFrame(26); + return true; +} + +bool CComputerScreen::TimerMsg(CTimerMsg *msg) { + int handle; + + switch (msg->_actionVal) { + case 0: + loadSound("a#32.wav"); + loadSound("a#31.wav"); + loadSound("a#33.wav"); + loadSound("a#30.wav"); + loadSound("a#29.wav"); + playSound("a#25.wav"); + addTimer(1, 2000, 0); + break; + + case 1: + playSound("a#32.wav"); + playSound("a#31.wav"); + addTimer(2, 2000, 0); + break; + + case 2: { + CChangeMusicMsg musicMsg(CString(), 1); + musicMsg.execute("HomeMusicPlayer"); + playSound("a#33.wav"); + playSound("a#31.wav"); + changeView("Home.Node 4.E", ""); + playClip(51, 150); + playSound("a#31.wav"); + playClip(151, 200); + + handle = playSound("a#27.wav"); + playClip(200, 306); + playSound("a#30.wav"); + stopSound(handle, 0); + + playClip(306, 338); + handle = playSound("a#28.wav"); + playClip(338, 392); + playSound("a#29.wav"); + stopSound(handle); + + playSound("y#662.wav"); + setSoundVolume(handle, 10, 2); + playClip(392, 450); + startTalking("Doorbot", 0x3611A); + sleep(8000); + + playClip(450, 492); + startTalking("Doorbot", 0x36121); + playClip(492, 522); + setSoundVolume(handle, 30, 2); + + playClip(523, 540); + setSoundVolume(handle, 0, 1); + + playClip(541, 551); + stopSound(handle); + break; + } + + default: + break; + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/computer_screen.h b/engines/titanic/game/computer_screen.h new file mode 100644 index 0000000000..8fb1dcd4dc --- /dev/null +++ b/engines/titanic/game/computer_screen.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_COMPUTER_SCREEN_H +#define TITANIC_COMPUTER_SCREEN_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CComputerScreen : public CGameObject { + DECLARE_MESSAGE_MAP; + bool ActMsg(CActMsg *msg); + bool MovieEndMsg(CMovieEndMsg *msg); + bool EnterViewMsg(CEnterViewMsg *msg); + bool TimerMsg(CTimerMsg *msg); +public: + CLASSDEF; + CComputerScreen(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_COMPUTER_SCREEN_H */ diff --git a/engines/titanic/game/cookie.cpp b/engines/titanic/game/cookie.cpp new file mode 100644 index 0000000000..915bb93b4a --- /dev/null +++ b/engines/titanic/game/cookie.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/game/cookie.h" + +namespace Titanic { + +void CCookie::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value1, indent); + file->writeNumberLine(_value2, indent); + + CGameObject::save(file, indent); +} + +void CCookie::load(SimpleFile *file) { + file->readNumber(); + _value1 = file->readNumber(); + _value2 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/cookie.h b/engines/titanic/game/cookie.h new file mode 100644 index 0000000000..7ae04f1144 --- /dev/null +++ b/engines/titanic/game/cookie.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_COOKIE_H +#define TITANIC_COOKIE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CCookie : public CGameObject { +public: + int _value1; + int _value2; +public: + CLASSDEF; + CCookie() : CGameObject(), _value1(0), _value2(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_COOKIE_H */ diff --git a/engines/titanic/game/credits.cpp b/engines/titanic/game/credits.cpp new file mode 100644 index 0000000000..7078d41a17 --- /dev/null +++ b/engines/titanic/game/credits.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/game/credits.h" + +namespace Titanic { + +CCredits::CCredits() : CGameObject(), _fieldBC(-1), _fieldC0(1) { +} + +void CCredits::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + + CGameObject::save(file, indent); +} + +void CCredits::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/credits.h b/engines/titanic/game/credits.h new file mode 100644 index 0000000000..fa9794b6de --- /dev/null +++ b/engines/titanic/game/credits.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_CREDITS_H +#define TITANIC_CREDITS_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CCredits : public CGameObject { +public: + int _fieldBC, _fieldC0; +public: + CLASSDEF; + CCredits(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CREDITS_H */ diff --git a/engines/titanic/game/credits_button.cpp b/engines/titanic/game/credits_button.cpp new file mode 100644 index 0000000000..90bb1b5ebe --- /dev/null +++ b/engines/titanic/game/credits_button.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/game/credits_button.h" + +namespace Titanic { + +CCreditsButton::CCreditsButton() : CBackground(), _fieldE0(1) { +} + +void CCreditsButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + CBackground::save(file, indent); +} + +void CCreditsButton::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/credits_button.h b/engines/titanic/game/credits_button.h new file mode 100644 index 0000000000..5e0bf96677 --- /dev/null +++ b/engines/titanic/game/credits_button.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_CREDITS_BUTTON_H +#define TITANIC_CREDITS_BUTTON_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CCreditsButton : public CBackground { +public: + int _fieldE0; +public: + CLASSDEF; + CCreditsButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CREDITS_BUTTON_H */ diff --git a/engines/titanic/game/dead_area.cpp b/engines/titanic/game/dead_area.cpp new file mode 100644 index 0000000000..3c41ab34ba --- /dev/null +++ b/engines/titanic/game/dead_area.cpp @@ -0,0 +1,45 @@ +/* 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 "titanic/game/dead_area.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CDeadArea, CGameObject) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(MouseButtonUpMsg) +END_MESSAGE_MAP() + +CDeadArea::CDeadArea() : CGameObject() { +} + +void CDeadArea::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CDeadArea::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/dead_area.h b/engines/titanic/game/dead_area.h new file mode 100644 index 0000000000..fdb44ef5df --- /dev/null +++ b/engines/titanic/game/dead_area.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_DEAD_AREA_H +#define TITANIC_DEAD_AREA_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +/** + * Implements a non-responsive screen area + */ +class CDeadArea : public CGameObject { + DECLARE_MESSAGE_MAP; + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg) { return true; } + bool MouseButtonUpMsg(CMouseButtonUpMsg *msg) { return true; } +public: + CLASSDEF; + CDeadArea(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DEAD_AREA_H */ diff --git a/engines/titanic/game/desk_click_responder.cpp b/engines/titanic/game/desk_click_responder.cpp new file mode 100644 index 0000000000..d9b2cb64b4 --- /dev/null +++ b/engines/titanic/game/desk_click_responder.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/game/desk_click_responder.h" + +namespace Titanic { + +void CDeskClickResponder::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldD4, indent); + file->writeNumberLine(_fieldD8, indent); + + CClickResponder::save(file, indent); +} + +void CDeskClickResponder::load(SimpleFile *file) { + file->readNumber(); + _fieldD4 = file->readNumber(); + _fieldD8 = file->readNumber(); + + CClickResponder::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/desk_click_responder.h b/engines/titanic/game/desk_click_responder.h new file mode 100644 index 0000000000..12825ba9de --- /dev/null +++ b/engines/titanic/game/desk_click_responder.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_DESK_CLICK_RESPONDER_H +#define TITANIC_DESK_CLICK_RESPONDER_H + +#include "titanic/core/click_responder.h" + +namespace Titanic { + +class CDeskClickResponder : public CClickResponder { +protected: + int _fieldD4; + int _fieldD8; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DESK_CLICK_RESPONDER_H */ diff --git a/engines/titanic/game/doorbot_elevator_handler.cpp b/engines/titanic/game/doorbot_elevator_handler.cpp new file mode 100644 index 0000000000..13fc368137 --- /dev/null +++ b/engines/titanic/game/doorbot_elevator_handler.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/game/doorbot_elevator_handler.h" + +namespace Titanic { + +int CDoorbotElevatorHandler::_v1; + +void CDoorbotElevatorHandler::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + file->writeNumberLine(_v1, indent); + CGameObject::save(file, indent); +} + +void CDoorbotElevatorHandler::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + _v1 = file->readNumber(); + CGameObject::load(file); +} + +bool CDoorbotElevatorHandler::EnterNodeMsg(CEnterNodeMsg *msg) { + warning("CDoorbotElevatorHandler::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/doorbot_elevator_handler.h b/engines/titanic/game/doorbot_elevator_handler.h new file mode 100644 index 0000000000..7b39e727e3 --- /dev/null +++ b/engines/titanic/game/doorbot_elevator_handler.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_DOORBOT_ELEVATOR_HANDLER_H +#define TITANIC_DOORBOT_ELEVATOR_HANDLER_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CDoorbotElevatorHandler : public CGameObject { + bool EnterNodeMsg(CEnterNodeMsg *msg); +private: + static int _v1; + int _value; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DOORBOT_ELEVATOR_HANDLER_H */ diff --git a/engines/titanic/game/doorbot_home_handler.cpp b/engines/titanic/game/doorbot_home_handler.cpp new file mode 100644 index 0000000000..b848308845 --- /dev/null +++ b/engines/titanic/game/doorbot_home_handler.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/game/doorbot_home_handler.h" + +namespace Titanic { + +CDoorbotHomeHandler::CDoorbotHomeHandler() { +} + +void CDoorbotHomeHandler::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CDoorbotHomeHandler::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/doorbot_home_handler.h b/engines/titanic/game/doorbot_home_handler.h new file mode 100644 index 0000000000..99ba6d37a9 --- /dev/null +++ b/engines/titanic/game/doorbot_home_handler.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_DOORBOT_HOME_HANDLER_H +#define TITANIC_DOORBOT_HOME_HANDLER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CDoorbotHomeHandler : public CGameObject { +public: + CLASSDEF; + CDoorbotHomeHandler(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DOORBOT_HOME_HANDLER_H */ diff --git a/engines/titanic/game/ear_sweet_bowl.cpp b/engines/titanic/game/ear_sweet_bowl.cpp new file mode 100644 index 0000000000..0f7069356d --- /dev/null +++ b/engines/titanic/game/ear_sweet_bowl.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/ear_sweet_bowl.h" + +namespace Titanic { + +void CEarSweetBowl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSweetBowl::save(file, indent); +} + +void CEarSweetBowl::load(SimpleFile *file) { + file->readNumber(); + CSweetBowl::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/ear_sweet_bowl.h b/engines/titanic/game/ear_sweet_bowl.h new file mode 100644 index 0000000000..3f41950e47 --- /dev/null +++ b/engines/titanic/game/ear_sweet_bowl.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_EAR_SWEET_BOWL_H +#define TITANIC_EAR_SWEET_BOWL_H + +#include "titanic/game/sweet_bowl.h" + +namespace Titanic { + +class CEarSweetBowl : public CSweetBowl { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EAR_SWEET_BOWL_H */ diff --git a/engines/titanic/game/eject_phonograph_button.cpp b/engines/titanic/game/eject_phonograph_button.cpp new file mode 100644 index 0000000000..4657f04126 --- /dev/null +++ b/engines/titanic/game/eject_phonograph_button.cpp @@ -0,0 +1,47 @@ +/* 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 "titanic/game/eject_phonograph_button.h" + +namespace Titanic { + +void CEjectPhonographButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeQuotedLine(_string3, indent); + file->writeQuotedLine(_string4, indent); + + CBackground::save(file, indent); +} + +void CEjectPhonographButton::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _string3 = file->readString(); + _string4 = file->readString(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/eject_phonograph_button.h b/engines/titanic/game/eject_phonograph_button.h new file mode 100644 index 0000000000..5f5da8053e --- /dev/null +++ b/engines/titanic/game/eject_phonograph_button.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_EJECT_PHONOGRAPH_BUTTON_H +#define TITANIC_EJECT_PHONOGRAPH_BUTTON_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CEjectPhonographButton : public CBackground { +public: + int _fieldE0; + int _fieldE4; + CString _string3; + CString _string4; +public: + CLASSDEF; + CEjectPhonographButton() : CBackground(), _fieldE0(0), _fieldE4(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EJECT_PHONOGRAPH_BUTTON_H */ diff --git a/engines/titanic/game/elevator_action_area.cpp b/engines/titanic/game/elevator_action_area.cpp new file mode 100644 index 0000000000..1cbff8d64d --- /dev/null +++ b/engines/titanic/game/elevator_action_area.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/elevator_action_area.h" + +namespace Titanic { + +void CElevatorActionArea::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CElevatorActionArea::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/elevator_action_area.h b/engines/titanic/game/elevator_action_area.h new file mode 100644 index 0000000000..6c756fb95f --- /dev/null +++ b/engines/titanic/game/elevator_action_area.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_ELEVATOR_ACTION_AREA_H +#define TITANIC_ELEVATOR_ACTION_AREA_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CElevatorActionArea : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CElevatorActionArea() : CGameObject(), _value(4) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ELEVATOR_ACTION_AREA_H */ diff --git a/engines/titanic/game/emma_control.cpp b/engines/titanic/game/emma_control.cpp new file mode 100644 index 0000000000..814cb44d79 --- /dev/null +++ b/engines/titanic/game/emma_control.cpp @@ -0,0 +1,47 @@ +/* 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 "titanic/game/emma_control.h" + +namespace Titanic { + +int CEmmaControl::_v1; + +void CEmmaControl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeQuotedLine(_wavFile1, indent); + file->writeQuotedLine(_wavFile2, indent); + + CBackground::save(file, indent); +} + +void CEmmaControl::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _wavFile1 = file->readString(); + _wavFile2 = file->readString(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/emma_control.h b/engines/titanic/game/emma_control.h new file mode 100644 index 0000000000..721660f61e --- /dev/null +++ b/engines/titanic/game/emma_control.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_EMMA_CONTROL_H +#define TITANIC_EMMA_CONTROL_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CEmmaControl : public CBackground { +private: + static int _v1; + + CString _wavFile1, _wavFile2; +public: + CLASSDEF; + CEmmaControl() : CBackground(), _wavFile1("b#39.wav"), _wavFile2("b#38.wav") {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EMMA_CONTROL_H */ diff --git a/engines/titanic/game/empty_nut_bowl.cpp b/engines/titanic/game/empty_nut_bowl.cpp new file mode 100644 index 0000000000..ae9cb35e4d --- /dev/null +++ b/engines/titanic/game/empty_nut_bowl.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/empty_nut_bowl.h" + +namespace Titanic { + +void CEmptyNutBowl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CEmptyNutBowl::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/empty_nut_bowl.h b/engines/titanic/game/empty_nut_bowl.h new file mode 100644 index 0000000000..112e2c6075 --- /dev/null +++ b/engines/titanic/game/empty_nut_bowl.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_EMPTY_NUT_BOWL_H +#define TITANIC_EMPTY_NUT_BOWL_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CEmptyNutBowl : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CEmptyNutBowl() : CGameObject(), _value(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EMPTY_NUT_BOWL_H */ diff --git a/engines/titanic/game/end_credit_text.cpp b/engines/titanic/game/end_credit_text.cpp new file mode 100644 index 0000000000..6e0c21bbe9 --- /dev/null +++ b/engines/titanic/game/end_credit_text.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/end_credit_text.h" + +namespace Titanic { + +void CEndCreditText::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CEndCreditText::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/end_credit_text.h b/engines/titanic/game/end_credit_text.h new file mode 100644 index 0000000000..54c6c7ff73 --- /dev/null +++ b/engines/titanic/game/end_credit_text.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_END_CREDIT_TEXT_H +#define TITANIC_END_CREDIT_TEXT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CEndCreditText : public CGameObject { +private: + int _value; +public: + CLASSDEF; + CEndCreditText() : CGameObject(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_END_CREDIT_TEXT_H */ diff --git a/engines/titanic/game/end_credits.cpp b/engines/titanic/game/end_credits.cpp new file mode 100644 index 0000000000..61640b92ad --- /dev/null +++ b/engines/titanic/game/end_credits.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/end_credits.h" + +namespace Titanic { + +void CEndCredits::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CEndCredits::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/end_credits.h b/engines/titanic/game/end_credits.h new file mode 100644 index 0000000000..d160bc94e8 --- /dev/null +++ b/engines/titanic/game/end_credits.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_END_CREDITS_H +#define TITANIC_END_CREDITS_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CEndCredits : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CEndCredits() : CGameObject(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_END_CREDITS_H */ diff --git a/engines/titanic/game/end_explode_ship.cpp b/engines/titanic/game/end_explode_ship.cpp new file mode 100644 index 0000000000..f7ac36503f --- /dev/null +++ b/engines/titanic/game/end_explode_ship.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/game/end_explode_ship.h" + +namespace Titanic { + +void CEndExplodeShip::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value1, indent); + file->writeNumberLine(_value2, indent); + + CGameObject::save(file, indent); +} + +void CEndExplodeShip::load(SimpleFile *file) { + file->readNumber(); + _value1 = file->readNumber(); + _value2 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/end_explode_ship.h b/engines/titanic/game/end_explode_ship.h new file mode 100644 index 0000000000..b8159d3ca7 --- /dev/null +++ b/engines/titanic/game/end_explode_ship.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_END_EXPLODE_SHIP_H +#define TITANIC_END_EXPLODE_SHIP_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CEndExplodeShip : public CGameObject { +public: + int _value1, _value2; +public: + CLASSDEF; + CEndExplodeShip() : CGameObject(), _value1(0), _value2(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_END_EXPLODE_SHIP_H */ diff --git a/engines/titanic/game/end_game_credits.cpp b/engines/titanic/game/end_game_credits.cpp new file mode 100644 index 0000000000..2d1aa79b1d --- /dev/null +++ b/engines/titanic/game/end_game_credits.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/game/end_game_credits.h" + +namespace Titanic { + +CEndGameCredits::CEndGameCredits() : CGameObject(), _fieldBC(0) { +} + +void CEndGameCredits::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writePoint(_pos1, indent); + + CGameObject::save(file, indent); +} + +void CEndGameCredits::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _pos1 = file->readPoint(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/end_game_credits.h b/engines/titanic/game/end_game_credits.h new file mode 100644 index 0000000000..5962950737 --- /dev/null +++ b/engines/titanic/game/end_game_credits.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_END_GAME_CREDITS_H +#define TITANIC_END_GAME_CREDITS_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CEndGameCredits : public CGameObject { +private: + int _fieldBC; + Point _pos1; +public: + CLASSDEF; + CEndGameCredits(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_END_GAME_CREDITS_H */ diff --git a/engines/titanic/game/end_sequence_control.cpp b/engines/titanic/game/end_sequence_control.cpp new file mode 100644 index 0000000000..d32b3d1713 --- /dev/null +++ b/engines/titanic/game/end_sequence_control.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/game/end_sequence_control.h" + +namespace Titanic { + +void CEndSequenceControl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CEndSequenceControl::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +bool CEndSequenceControl::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("TODO: CEndSequenceControl::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/end_sequence_control.h b/engines/titanic/game/end_sequence_control.h new file mode 100644 index 0000000000..35e9a934e1 --- /dev/null +++ b/engines/titanic/game/end_sequence_control.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_END_SEQUENCE_CONTROL_H +#define TITANIC_END_SEQUENCE_CONTROL_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CEndSequenceControl : public CGameObject { + bool EnterRoomMsg(CEnterRoomMsg *msg); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_END_SEQUENCE_CONTROL_H */ diff --git a/engines/titanic/game/fan.cpp b/engines/titanic/game/fan.cpp new file mode 100644 index 0000000000..eabaf63568 --- /dev/null +++ b/engines/titanic/game/fan.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/game/fan.h" + +namespace Titanic { + +void CFan::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value1, indent); + file->writeNumberLine(_value2, indent); + + CGameObject::save(file, indent); +} + +void CFan::load(SimpleFile *file) { + file->readNumber(); + _value1 = file->readNumber(); + _value2 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/fan.h b/engines/titanic/game/fan.h new file mode 100644 index 0000000000..2c5a2410a8 --- /dev/null +++ b/engines/titanic/game/fan.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_FAN_H +#define TITANIC_FAN_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CFan : public CGameObject { +public: + int _value1, _value2; +public: + CLASSDEF; + CFan() : CGameObject(), _value1(0), _value2(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FAN_H */ diff --git a/engines/titanic/game/fan_control.cpp b/engines/titanic/game/fan_control.cpp new file mode 100644 index 0000000000..a42e4dd5c1 --- /dev/null +++ b/engines/titanic/game/fan_control.cpp @@ -0,0 +1,53 @@ +/* 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 "titanic/game/fan_control.h" + +namespace Titanic { + +CFanControl::CFanControl() : CGameObject(), _fieldBC(0), + _fieldC0(0), _fieldC4(0), _fieldC8(0), _fieldCC(0) { +} + +void CFanControl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeNumberLine(_fieldCC, indent); + + CGameObject::save(file, indent); +} + +void CFanControl::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + _fieldC8 = file->readNumber(); + _fieldCC = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/fan_control.h b/engines/titanic/game/fan_control.h new file mode 100644 index 0000000000..4d89adb311 --- /dev/null +++ b/engines/titanic/game/fan_control.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_FAN_CONTROL_H +#define TITANIC_FAN_CONTROL_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CFanControl : public CGameObject { +public: + int _fieldBC; + int _fieldC0; + int _fieldC4; + int _fieldC8; + int _fieldCC; +public: + CLASSDEF; + CFanControl(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FAN_CONTROL_H */ diff --git a/engines/titanic/game/fan_decrease.cpp b/engines/titanic/game/fan_decrease.cpp new file mode 100644 index 0000000000..2049b1ebc9 --- /dev/null +++ b/engines/titanic/game/fan_decrease.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/fan_decrease.h" + +namespace Titanic { + +void CFanDecrease::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CFanDecrease::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/fan_decrease.h b/engines/titanic/game/fan_decrease.h new file mode 100644 index 0000000000..765c7d1560 --- /dev/null +++ b/engines/titanic/game/fan_decrease.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_FAN_DECREASE_H +#define TITANIC_FAN_DECREASE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CFanDecrease : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FAN_DECREASE_H */ diff --git a/engines/titanic/game/fan_increase.cpp b/engines/titanic/game/fan_increase.cpp new file mode 100644 index 0000000000..aa23dd9275 --- /dev/null +++ b/engines/titanic/game/fan_increase.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/fan_increase.h" + +namespace Titanic { + +void CFanIncrease::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CFanIncrease::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/fan_increase.h b/engines/titanic/game/fan_increase.h new file mode 100644 index 0000000000..08ec1322cd --- /dev/null +++ b/engines/titanic/game/fan_increase.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_FAN_INCREASE_H +#define TITANIC_FAN_INCREASE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CFanIncrease : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FAN_INCREASE_H */ diff --git a/engines/titanic/game/fan_noises.cpp b/engines/titanic/game/fan_noises.cpp new file mode 100644 index 0000000000..14177ab64e --- /dev/null +++ b/engines/titanic/game/fan_noises.cpp @@ -0,0 +1,63 @@ +/* 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 "titanic/game/fan_noises.h" + +namespace Titanic { + +CFanNoises::CFanNoises() : CGameObject(), _fieldBC(-1), + _fieldC0(0), _fieldC4(70), _fieldC8(-1), _fieldCC(0), + _fieldD0(0), _fieldD4(-1) { +} + +void CFanNoises::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeNumberLine(_fieldCC, indent); + file->writeNumberLine(_fieldD0, indent); + file->writeNumberLine(_fieldD4, indent); + + CGameObject::save(file, indent); +} + +void CFanNoises::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + _fieldC8 = file->readNumber(); + _fieldCC = file->readNumber(); + _fieldD0 = file->readNumber(); + _fieldD4 = file->readNumber(); + + CGameObject::load(file); +} + +bool CFanNoises::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CFanNoises::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/fan_noises.h b/engines/titanic/game/fan_noises.h new file mode 100644 index 0000000000..bb2c35989d --- /dev/null +++ b/engines/titanic/game/fan_noises.h @@ -0,0 +1,58 @@ +/* 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 TITANIC_FAN_NOISES_H +#define TITANIC_FAN_NOISES_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CFanNoises : public CGameObject { + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + int _fieldBC; + int _fieldC0; + int _fieldC4; + int _fieldC8; + int _fieldCC; + int _fieldD0; + int _fieldD4; +public: + CLASSDEF; + CFanNoises(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FAN_NOISES_H */ diff --git a/engines/titanic/game/floor_indicator.cpp b/engines/titanic/game/floor_indicator.cpp new file mode 100644 index 0000000000..360232c38c --- /dev/null +++ b/engines/titanic/game/floor_indicator.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/floor_indicator.h" + +namespace Titanic { + +void CFloorIndicator::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CFloorIndicator::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/floor_indicator.h b/engines/titanic/game/floor_indicator.h new file mode 100644 index 0000000000..066209e52e --- /dev/null +++ b/engines/titanic/game/floor_indicator.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_FLOOR_INDICATOR_H +#define TITANIC_FLOOR_INDICATOR_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CFloorIndicator : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FLOOR_INDICATOR_H */ diff --git a/engines/titanic/game/games_console.cpp b/engines/titanic/game/games_console.cpp new file mode 100644 index 0000000000..b7500f9dd9 --- /dev/null +++ b/engines/titanic/game/games_console.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/games_console.h" + +namespace Titanic { + +void CGamesConsole::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + CBackground::save(file, indent); +} + +void CGamesConsole::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/games_console.h b/engines/titanic/game/games_console.h new file mode 100644 index 0000000000..2b1da70e96 --- /dev/null +++ b/engines/titanic/game/games_console.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_GAMES_CONSOLE_H +#define TITANIC_GAMES_CONSOLE_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CGamesConsole : public CBackground { +public: + int _fieldE0; +public: + CLASSDEF; + CGamesConsole() : CBackground(), _fieldE0(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GAMES_CONSOLE_H */ diff --git a/engines/titanic/game/get_lift_eye2.cpp b/engines/titanic/game/get_lift_eye2.cpp new file mode 100644 index 0000000000..7747f7b0c2 --- /dev/null +++ b/engines/titanic/game/get_lift_eye2.cpp @@ -0,0 +1,54 @@ +/* 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 "titanic/game/get_lift_eye2.h" + +namespace Titanic { + +CString *CGetLiftEye2::_v1; + +void CGetLiftEye2::init() { + _v1 = new CString(); +} + +void CGetLiftEye2::deinit() { + delete _v1; +} + +void CGetLiftEye2::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(*_v1, indent); + CGameObject::save(file, indent); +} + +void CGetLiftEye2::load(SimpleFile *file) { + file->readNumber(); + *_v1 = file->readString(); + CGameObject::load(file); +} + +bool CGetLiftEye2::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CGetLiftEye2::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/get_lift_eye2.h b/engines/titanic/game/get_lift_eye2.h new file mode 100644 index 0000000000..496784a3c1 --- /dev/null +++ b/engines/titanic/game/get_lift_eye2.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_GET_LIFT_EYE2_H +#define TITANIC_GET_LIFT_EYE2_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" +namespace Titanic { + +class CGetLiftEye2 : public CGameObject { + bool EnterRoomMsg(CEnterRoomMsg *msg); +public: + static CString *_v1; +public: + CLASSDEF; + static void init(); + static void deinit(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GET_LIFT_EYE2_H */ diff --git a/engines/titanic/game/glass_smasher.cpp b/engines/titanic/game/glass_smasher.cpp new file mode 100644 index 0000000000..8c33124a47 --- /dev/null +++ b/engines/titanic/game/glass_smasher.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/glass_smasher.h" + +namespace Titanic { + +void CGlassSmasher::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CGlassSmasher::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/glass_smasher.h b/engines/titanic/game/glass_smasher.h new file mode 100644 index 0000000000..7e38f4e36b --- /dev/null +++ b/engines/titanic/game/glass_smasher.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_GLASS_SMASHER_H +#define TITANIC_GLASS_SMASHER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CGlassSmasher : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GLASS_SMASHER_H */ diff --git a/engines/titanic/game/gondolier/gondolier_base.cpp b/engines/titanic/game/gondolier/gondolier_base.cpp new file mode 100644 index 0000000000..1f7339cf38 --- /dev/null +++ b/engines/titanic/game/gondolier/gondolier_base.cpp @@ -0,0 +1,70 @@ +/* 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 "titanic/game/gondolier/gondolier_base.h" + +namespace Titanic { + +int CGondolierBase::_v1; +int CGondolierBase::_v2; +int CGondolierBase::_v3; +int CGondolierBase::_v4; +int CGondolierBase::_v5; +int CGondolierBase::_v6; +int CGondolierBase::_v7; +int CGondolierBase::_v8; +int CGondolierBase::_v9; +int CGondolierBase::_v10; + +void CGondolierBase::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + file->writeNumberLine(_v3, indent); + file->writeNumberLine(_v4, indent); + file->writeNumberLine(_v5, indent); + file->writeNumberLine(_v6, indent); + file->writeNumberLine(_v7, indent); + file->writeNumberLine(_v8, indent); + file->writeNumberLine(_v9, indent); + file->writeNumberLine(_v10, indent); + + CGameObject::save(file, indent); +} + +void CGondolierBase::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + _v3 = file->readNumber(); + _v4 = file->readNumber(); + _v5 = file->readNumber(); + _v6 = file->readNumber(); + _v7 = file->readNumber(); + _v8 = file->readNumber(); + _v9 = file->readNumber(); + _v10 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/gondolier/gondolier_base.h b/engines/titanic/game/gondolier/gondolier_base.h new file mode 100644 index 0000000000..a7ea2d4931 --- /dev/null +++ b/engines/titanic/game/gondolier/gondolier_base.h @@ -0,0 +1,58 @@ +/* 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 TITANIC_GONDOLIER_BASE_H +#define TITANIC_GONDOLIER_BASE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CGondolierBase : public CGameObject { +private: + static int _v1; + static int _v2; + static int _v3; + static int _v4; + static int _v5; + static int _v6; + static int _v7; + static int _v8; + static int _v9; + static int _v10; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GONDOLIER_BASE_H */ diff --git a/engines/titanic/game/gondolier/gondolier_chest.cpp b/engines/titanic/game/gondolier/gondolier_chest.cpp new file mode 100644 index 0000000000..b3e7217502 --- /dev/null +++ b/engines/titanic/game/gondolier/gondolier_chest.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/gondolier/gondolier_chest.h" + +namespace Titanic { + +void CGondolierChest::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGondolierBase::save(file, indent); +} + +void CGondolierChest::load(SimpleFile *file) { + file->readNumber(); + CGondolierBase::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/gondolier/gondolier_chest.h b/engines/titanic/game/gondolier/gondolier_chest.h new file mode 100644 index 0000000000..d796917371 --- /dev/null +++ b/engines/titanic/game/gondolier/gondolier_chest.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_GONDOLIER_CHEST_H +#define TITANIC_GONDOLIER_CHEST_H + +#include "titanic/game/gondolier/gondolier_base.h" + +namespace Titanic { + +class CGondolierChest : public CGondolierBase { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GONDOLIER_CHEST_H */ diff --git a/engines/titanic/game/gondolier/gondolier_face.cpp b/engines/titanic/game/gondolier/gondolier_face.cpp new file mode 100644 index 0000000000..bdab8491ed --- /dev/null +++ b/engines/titanic/game/gondolier/gondolier_face.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/gondolier/gondolier_face.h" + +namespace Titanic { + +void CGondolierFace::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + CGondolierBase::save(file, indent); +} + +void CGondolierFace::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + CGondolierBase::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/gondolier/gondolier_face.h b/engines/titanic/game/gondolier/gondolier_face.h new file mode 100644 index 0000000000..71bdd6d444 --- /dev/null +++ b/engines/titanic/game/gondolier/gondolier_face.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_GONDOLIER_FACE_H +#define TITANIC_GONDOLIER_FACE_H + +#include "titanic/game/gondolier/gondolier_base.h" + +namespace Titanic { + +class CGondolierFace : public CGondolierBase { +private: + int _fieldBC; +public: + CLASSDEF; + CGondolierFace() : CGondolierBase(), _fieldBC(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GONDOLIER_FACE_H */ diff --git a/engines/titanic/game/gondolier/gondolier_mixer.cpp b/engines/titanic/game/gondolier/gondolier_mixer.cpp new file mode 100644 index 0000000000..9b7b72c11b --- /dev/null +++ b/engines/titanic/game/gondolier/gondolier_mixer.cpp @@ -0,0 +1,68 @@ +/* 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 "titanic/game/gondolier/gondolier_mixer.h" +#include "titanic/core/room_item.h" + +namespace Titanic { + +CGondolierMixer::CGondolierMixer() : CGondolierBase(), + _string1("c#0.wav"), _string2("c#1.wav"), + _fieldBC(-1), _fieldC0(-1), _fieldC4(0), _fieldC8(0), + _fieldE4(0) { +} + +void CGondolierMixer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_fieldE4, indent); + + CGondolierBase::save(file, indent); +} + +void CGondolierMixer::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + _fieldC8 = file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + _fieldE4 = file->readNumber(); + + CGondolierBase::load(file); +} + +bool CGondolierMixer::EnterRoomMsg(CEnterRoomMsg *msg) { + CRoomItem *parentRoom = dynamic_cast<CRoomItem *>(getParent()); + if (parentRoom == msg->_newRoom) + msg->execute(parentRoom); + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/gondolier/gondolier_mixer.h b/engines/titanic/game/gondolier/gondolier_mixer.h new file mode 100644 index 0000000000..247e520ba6 --- /dev/null +++ b/engines/titanic/game/gondolier/gondolier_mixer.h @@ -0,0 +1,58 @@ +/* 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 TITANIC_GONDOLIER_MIXER_H +#define TITANIC_GONDOLIER_MIXER_H + +#include "titanic/game/gondolier/gondolier_base.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CGondolierMixer : public CGondolierBase { + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + int _fieldBC; + int _fieldC0; + int _fieldC4; + int _fieldC8; + CString _string1; + CString _string2; + int _fieldE4; +public: + CLASSDEF; + CGondolierMixer(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GONDOLIER_MIXER_H */ diff --git a/engines/titanic/game/gondolier/gondolier_slider.cpp b/engines/titanic/game/gondolier/gondolier_slider.cpp new file mode 100644 index 0000000000..eb6b1a9ad8 --- /dev/null +++ b/engines/titanic/game/gondolier/gondolier_slider.cpp @@ -0,0 +1,82 @@ +/* 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 "titanic/game/gondolier/gondolier_slider.h" + +namespace Titanic { + +CGondolierSlider::CGondolierSlider() : CGondolierBase(), + _fieldBC(0), _fieldC0(0), _fieldC4(0), _fieldC8(0), + _fieldCC(0), _fieldD0(0), _fieldD4(0), _fieldD8(0), + _fieldDC(0), _fieldE0(0), _fieldE4(0), _fieldE8(0), + _fieldEC(0), _string1("NULL"), _fieldFC(0), _field118(0) { +} + +void CGondolierSlider::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeNumberLine(_fieldCC, indent); + file->writeNumberLine(_fieldD0, indent); + file->writeNumberLine(_fieldD4, indent); + file->writeNumberLine(_fieldD8, indent); + file->writeNumberLine(_fieldDC, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldCC, indent); + file->writeQuotedLine(_string1, indent); + file->writeNumberLine(_fieldFC, indent); + file->writeQuotedLine(_string2, indent); + file->writeQuotedLine(_string3, indent); + file->writeNumberLine(_field118, indent); + + CGondolierBase::save(file, indent); +} + +void CGondolierSlider::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + _fieldC8 = file->readNumber(); + _fieldCC = file->readNumber(); + _fieldD0 = file->readNumber(); + _fieldD4 = file->readNumber(); + _fieldD8 = file->readNumber(); + _fieldDC = file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + _string1 = file->readString(); + _fieldFC = file->readNumber(); + _string2 = file->readString(); + _string3 = file->readString(); + _field118 = file->readNumber(); + + CGondolierBase::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/gondolier/gondolier_slider.h b/engines/titanic/game/gondolier/gondolier_slider.h new file mode 100644 index 0000000000..0ae14a91a0 --- /dev/null +++ b/engines/titanic/game/gondolier/gondolier_slider.h @@ -0,0 +1,67 @@ +/* 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 TITANIC_GONDOLIER_SLIDER_H +#define TITANIC_GONDOLIER_SLIDER_H + +#include "titanic/game/gondolier/gondolier_base.h" + +namespace Titanic { + +class CGondolierSlider : public CGondolierBase { +private: + int _fieldBC; + int _fieldC0; + int _fieldC4; + int _fieldC8; + int _fieldCC; + int _fieldD0; + int _fieldD4; + int _fieldD8; + int _fieldDC; + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; + CString _string1; + int _fieldFC; + CString _string2; + CString _string3; + int _field118; +public: + CLASSDEF; + CGondolierSlider(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GONDOLIER_SLIDER_H */ diff --git a/engines/titanic/game/hammer_clip.cpp b/engines/titanic/game/hammer_clip.cpp new file mode 100644 index 0000000000..e3f3a09a90 --- /dev/null +++ b/engines/titanic/game/hammer_clip.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/hammer_clip.h" + +namespace Titanic { + +void CHammerClip::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CHammerClip::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/hammer_clip.h b/engines/titanic/game/hammer_clip.h new file mode 100644 index 0000000000..7f5c5ab5f8 --- /dev/null +++ b/engines/titanic/game/hammer_clip.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_HAMMER_CLIP_H +#define TITANIC_HAMMER_CLIP_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CHammerClip : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CHammerClip() : CGameObject(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HAMMER_CLIP_H */ diff --git a/engines/titanic/game/hammer_dispensor.cpp b/engines/titanic/game/hammer_dispensor.cpp new file mode 100644 index 0000000000..440fe1bc7b --- /dev/null +++ b/engines/titanic/game/hammer_dispensor.cpp @@ -0,0 +1,49 @@ +/* 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 "titanic/game/hammer_dispensor.h" + +namespace Titanic { + +CHammerDispensor::CHammerDispensor() : CBackground(), + _fieldE0(0), _fieldE4(0), _fieldE8(0) { +} + +void CHammerDispensor::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + + CBackground::save(file, indent); +} + +void CHammerDispensor::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/hammer_dispensor.h b/engines/titanic/game/hammer_dispensor.h new file mode 100644 index 0000000000..e1b30d9045 --- /dev/null +++ b/engines/titanic/game/hammer_dispensor.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_HAMMER_DISPENSOR_H +#define TITANIC_HAMMER_DISPENSOR_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CHammerDispensor : public CBackground { +private: + int _fieldE0; + int _fieldE4; + int _fieldE8; +public: + CLASSDEF; + CHammerDispensor(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HAMMER_DISPENSOR_H */ diff --git a/engines/titanic/game/hammer_dispensor_button.cpp b/engines/titanic/game/hammer_dispensor_button.cpp new file mode 100644 index 0000000000..3346498623 --- /dev/null +++ b/engines/titanic/game/hammer_dispensor_button.cpp @@ -0,0 +1,56 @@ +/* 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 "titanic/game/hammer_dispensor_button.h" + +namespace Titanic { + +CHammerDispensorButton::CHammerDispensorButton() : CStartAction(), + _fieldF8(0), _fieldFC(0), _field100(0), _field104(56), + _field108(6), _field10C(0), _field110(0) { +} + +void CHammerDispensorButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_fieldFC, indent); + file->writeNumberLine(_field100, indent); + file->writeNumberLine(_field104, indent); + file->writeNumberLine(_field108, indent); + file->writeNumberLine(_field110, indent); + + CStartAction::save(file, indent); +} + +void CHammerDispensorButton::load(SimpleFile *file) { + file->readNumber(); + _fieldF8 = file->readNumber(); + _fieldFC = file->readNumber(); + _field100 = file->readNumber(); + _field104 = file->readNumber(); + _field108 = file->readNumber(); + _field110 = file->readNumber(); + + CStartAction::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/hammer_dispensor_button.h b/engines/titanic/game/hammer_dispensor_button.h new file mode 100644 index 0000000000..36732adb2d --- /dev/null +++ b/engines/titanic/game/hammer_dispensor_button.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_HAMMER_DISPENSOR_BUTTON_H +#define TITANIC_HAMMER_DISPENSOR_BUTTON_H + +#include "titanic/game/start_action.h" + +namespace Titanic { + +class CHammerDispensorButton : public CStartAction { +private: + int _fieldF8; + int _fieldFC; + int _field100; + int _field104; + int _field108; + int _field10C; + int _field110; +public: + CLASSDEF; + CHammerDispensorButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HAMMER_DISPENSOR_BUTTON_H */ diff --git a/engines/titanic/game/head_slot.cpp b/engines/titanic/game/head_slot.cpp new file mode 100644 index 0000000000..32650b75e4 --- /dev/null +++ b/engines/titanic/game/head_slot.cpp @@ -0,0 +1,66 @@ +/* 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 "titanic/game/head_slot.h" + +namespace Titanic { + +int CHeadSlot::_v1; + +CHeadSlot::CHeadSlot() : CGameObject(), _string1("NotWorking"), _string2("NULL"), + _fieldBC(0), _fieldD8(0), _fieldDC(27), _fieldE0(56), + _fieldE4(82), _fieldE8(112), _fieldEC(0) { +} + +void CHeadSlot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_fieldD8, indent); + file->writeNumberLine(_fieldDC, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_fieldEC, indent); + + CGameObject::save(file, indent); +} + +void CHeadSlot::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + _fieldD8 = file->readNumber(); + _fieldDC = file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _v1 = file->readNumber(); + _fieldEC = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/head_slot.h b/engines/titanic/game/head_slot.h new file mode 100644 index 0000000000..0080411033 --- /dev/null +++ b/engines/titanic/game/head_slot.h @@ -0,0 +1,60 @@ +/* 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 TITANIC_HEAD_SLOT_H +#define TITANIC_HEAD_SLOT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CHeadSlot : public CGameObject { +public: + static int _v1; +public: + int _fieldBC; + CString _string1; + CString _string2; + int _fieldD8; + int _fieldDC; + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; +public: + CLASSDEF; + CHeadSlot(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HEAD_SLOT_H */ diff --git a/engines/titanic/game/head_smash_event.cpp b/engines/titanic/game/head_smash_event.cpp new file mode 100644 index 0000000000..5b79acf7a5 --- /dev/null +++ b/engines/titanic/game/head_smash_event.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/head_smash_event.h" + +namespace Titanic { + +void CHeadSmashEvent::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CBackground::save(file, indent); +} + +void CHeadSmashEvent::load(SimpleFile *file) { + file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/head_smash_event.h b/engines/titanic/game/head_smash_event.h new file mode 100644 index 0000000000..912cf36bf3 --- /dev/null +++ b/engines/titanic/game/head_smash_event.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_HEAD_SMASH_EVENT_H +#define TITANIC_HEAD_SMASH_EVENT_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CHeadSmashEvent : public CBackground { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HEAD_SMASH_EVENT_H */ diff --git a/engines/titanic/game/head_smash_lever.cpp b/engines/titanic/game/head_smash_lever.cpp new file mode 100644 index 0000000000..5a2fe1f4c2 --- /dev/null +++ b/engines/titanic/game/head_smash_lever.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/game/head_smash_lever.h" + +namespace Titanic { + +CHeadSmashLever::CHeadSmashLever() : CBackground(), + _fieldE0(0), _fieldE4(0), _fieldE8(0) {} + +void CHeadSmashLever::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + + CBackground::save(file, indent); +} + +void CHeadSmashLever::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/head_smash_lever.h b/engines/titanic/game/head_smash_lever.h new file mode 100644 index 0000000000..b8f04d39de --- /dev/null +++ b/engines/titanic/game/head_smash_lever.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_HEAD_SMASH_LEVER_H +#define TITANIC_HEAD_SMASH_LEVER_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CHeadSmashLever : public CBackground { +public: + int _fieldE0; + int _fieldE4; + int _fieldE8; +public: + CLASSDEF; + CHeadSmashLever(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HEAD_SMASH_LEVER_H */ diff --git a/engines/titanic/game/head_spinner.cpp b/engines/titanic/game/head_spinner.cpp new file mode 100644 index 0000000000..2fb3654c4a --- /dev/null +++ b/engines/titanic/game/head_spinner.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/game/head_spinner.h" + +namespace Titanic { + +void CHeadSpinner::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value1, indent); + file->writeNumberLine(_value2, indent); + + CGameObject::save(file, indent); +} + +void CHeadSpinner::load(SimpleFile *file) { + file->readNumber(); + _value1 = file->readNumber(); + _value2 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/head_spinner.h b/engines/titanic/game/head_spinner.h new file mode 100644 index 0000000000..4456070ee4 --- /dev/null +++ b/engines/titanic/game/head_spinner.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_HEAD_SPINNER_H +#define TITANIC_HEAD_SPINNER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CHeadSpinner : public CGameObject { +public: + int _value1, _value2; +public: + CHeadSpinner() : CGameObject(), _value1(0), _value2(0) {} + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HEAD_SPINNER_H */ diff --git a/engines/titanic/game/idle_summoner.cpp b/engines/titanic/game/idle_summoner.cpp new file mode 100644 index 0000000000..19d760a8db --- /dev/null +++ b/engines/titanic/game/idle_summoner.cpp @@ -0,0 +1,63 @@ +/* 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 "titanic/game/idle_summoner.h" + +namespace Titanic { + +CIdleSummoner::CIdleSummoner() : CGameObject(), _fieldBC(0x57E40), + _fieldC0(0xEA60), _fieldC4(0x57E40), _fieldC8(0xEA60), + _fieldCC(0xEA60), _fieldD0(0xEA60), _fieldD4(0xEA60), + _fieldD8(0xEA60), _fieldDC(0xEA60) { +} + +void CIdleSummoner::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeNumberLine(_fieldCC, indent); + file->writeNumberLine(_fieldD0, indent); + file->writeNumberLine(_fieldD4, indent); + file->writeNumberLine(_fieldD8, indent); + file->writeNumberLine(_fieldDC, indent); + + CGameObject::save(file, indent); +} + +void CIdleSummoner::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + _fieldC8 = file->readNumber(); + _fieldCC = file->readNumber(); + _fieldD0 = file->readNumber(); + _fieldD4 = file->readNumber(); + _fieldD8 = file->readNumber(); + _fieldDC = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/idle_summoner.h b/engines/titanic/game/idle_summoner.h new file mode 100644 index 0000000000..1d9fcdd176 --- /dev/null +++ b/engines/titanic/game/idle_summoner.h @@ -0,0 +1,58 @@ +/* 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 TITANIC_IDLE_SUMMONER_H +#define TITANIC_IDLE_SUMMONER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CIdleSummoner : public CGameObject { +public: + int _fieldBC; + int _fieldC0; + int _fieldC4; + int _fieldC8; + int _fieldCC; + int _fieldD0; + int _fieldD4; + int _fieldD8; + int _fieldDC; +public: + CIdleSummoner(); + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_IDLE_SUMMONER_H */ diff --git a/engines/titanic/game/leave_sec_class_state.cpp b/engines/titanic/game/leave_sec_class_state.cpp new file mode 100644 index 0000000000..3e23e3ad1c --- /dev/null +++ b/engines/titanic/game/leave_sec_class_state.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/leave_sec_class_state.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CLeaveSecClassState, CGameObject); + +void CLeaveSecClassState::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CLeaveSecClassState::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/leave_sec_class_state.h b/engines/titanic/game/leave_sec_class_state.h new file mode 100644 index 0000000000..0b1e854f57 --- /dev/null +++ b/engines/titanic/game/leave_sec_class_state.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_LEAVE_SEC_CLASS_STATE_H +#define TITANIC_LEAVE_SEC_CLASS_STATE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CLeaveSecClassState : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LEAVE_SEC_CLASS_STATE_H */ diff --git a/engines/titanic/game/lemon_dispensor.cpp b/engines/titanic/game/lemon_dispensor.cpp new file mode 100644 index 0000000000..8e1674cb2d --- /dev/null +++ b/engines/titanic/game/lemon_dispensor.cpp @@ -0,0 +1,61 @@ +/* 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 "titanic/game/lemon_dispensor.h" + +namespace Titanic { + +int CLemonDispensor::_v1; +int CLemonDispensor::_v2; +int CLemonDispensor::_v3; + +CLemonDispensor::CLemonDispensor() : CBackground(), + _fieldE0(0), _fieldE4(9), _fieldE8(15), _fieldEC(0) { +} + +void CLemonDispensor::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + file->writeNumberLine(_v3, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + + CBackground::save(file, indent); +} + +void CLemonDispensor::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + _v3 = file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/lemon_dispensor.h b/engines/titanic/game/lemon_dispensor.h new file mode 100644 index 0000000000..d6315ed620 --- /dev/null +++ b/engines/titanic/game/lemon_dispensor.h @@ -0,0 +1,57 @@ +/* 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 TITANIC_LEMON_DISPENSOR_H +#define TITANIC_LEMON_DISPENSOR_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CLemonDispensor : public CBackground { +private: + static int _v1; + static int _v2; + static int _v3; + + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; +public: + CLASSDEF; + CLemonDispensor(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LEMON_DISPENSOR_H */ diff --git a/engines/titanic/game/light.cpp b/engines/titanic/game/light.cpp new file mode 100644 index 0000000000..fd3c446875 --- /dev/null +++ b/engines/titanic/game/light.cpp @@ -0,0 +1,65 @@ +/* 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 "titanic/game/light.h" + +namespace Titanic { + +CLight::CLight() : CBackground(), _fieldE0(0), _fieldE4(0), + _fieldE8(0), _fieldEC(0), _fieldF0(0), _fieldF4(0), + _fieldF8(0), _fieldFC(0) { +} + +void CLight::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_fieldF0, indent); + file->writeNumberLine(_fieldF4, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_fieldFC, indent); + + CBackground::save(file, indent); +} + +void CLight::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + _fieldF0 = file->readNumber(); + _fieldF4 = file->readNumber(); + _fieldF8 = file->readNumber(); + _fieldFC = file->readNumber(); + + CBackground::load(file); +} + +bool CLight::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CLight::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/light.h b/engines/titanic/game/light.h new file mode 100644 index 0000000000..79e4bc400e --- /dev/null +++ b/engines/titanic/game/light.h @@ -0,0 +1,59 @@ +/* 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 TITANIC_LIGHT_H +#define TITANIC_LIGHT_H + +#include "titanic/core/background.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CLight : public CBackground { + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; + int _fieldF0; + int _fieldF4; + int _fieldF8; + int _fieldFC; +public: + CLASSDEF; + CLight(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LIGHT_H */ diff --git a/engines/titanic/game/light_switch.cpp b/engines/titanic/game/light_switch.cpp new file mode 100644 index 0000000000..3f5c8d2084 --- /dev/null +++ b/engines/titanic/game/light_switch.cpp @@ -0,0 +1,58 @@ +/* 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 "titanic/game/light_switch.h" + +namespace Titanic { + +int CLightSwitch::_v1; + +CLightSwitch::CLightSwitch() : CBackground(), + _fieldE0(0), _fieldE4(0), _fieldE8(0) { +} + +void CLightSwitch::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_fieldE8, indent); + + CBackground::save(file, indent); +} + +void CLightSwitch::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _v1 = file->readNumber(); + _fieldE8 = file->readNumber(); + + CBackground::load(file); +} + +bool CLightSwitch::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CLightSwitch::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/light_switch.h b/engines/titanic/game/light_switch.h new file mode 100644 index 0000000000..ce62d7d68c --- /dev/null +++ b/engines/titanic/game/light_switch.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_LIGHT_SWITCH_H +#define TITANIC_LIGHT_SWITCH_H + +#include "titanic/core/background.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CLightSwitch : public CBackground { + bool EnterRoomMsg(CEnterRoomMsg *msg); +public: + static int _v1; +private: + int _fieldE0; + int _fieldE4; + int _fieldE8; +public: + CLASSDEF; + CLightSwitch(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LIGHT_SWITCH_H */ diff --git a/engines/titanic/game/little_lift_button.cpp b/engines/titanic/game/little_lift_button.cpp new file mode 100644 index 0000000000..5005cb1757 --- /dev/null +++ b/engines/titanic/game/little_lift_button.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/little_lift_button.h" + +namespace Titanic { + +void CLittleLiftButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CBackground::save(file, indent); +} + +void CLittleLiftButton::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/little_lift_button.h b/engines/titanic/game/little_lift_button.h new file mode 100644 index 0000000000..b14651f4b8 --- /dev/null +++ b/engines/titanic/game/little_lift_button.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_LITTLE_LIFT_BUTTON_H +#define TITANIC_LITTLE_LIFT_BUTTON_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CLittleLiftButton : public CBackground { +private: + int _value; +public: + CLASSDEF; + CLittleLiftButton() : CBackground(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LITTLE_LIFT_BUTTON_H */ diff --git a/engines/titanic/game/long_stick_dispenser.cpp b/engines/titanic/game/long_stick_dispenser.cpp new file mode 100644 index 0000000000..cb562ec3ca --- /dev/null +++ b/engines/titanic/game/long_stick_dispenser.cpp @@ -0,0 +1,51 @@ +/* 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 "titanic/game/long_stick_dispenser.h" + +namespace Titanic { + +void CLongStickDispenser::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + + CGameObject::save(file, indent); +} + +void CLongStickDispenser::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + + CGameObject::load(file); +} + +bool CLongStickDispenser::EnterRoomMsg(CEnterRoomMsg *msg) { + _fieldC0 = 0; + _fieldC4 = 1; + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/long_stick_dispenser.h b/engines/titanic/game/long_stick_dispenser.h new file mode 100644 index 0000000000..2a1b86fb84 --- /dev/null +++ b/engines/titanic/game/long_stick_dispenser.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_LONG_STICK_DISPENSER_H +#define TITANIC_LONG_STICK_DISPENSER_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CLongStickDispenser : public CGameObject { + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + int _fieldBC; + int _fieldC0; + int _fieldC4; +public: + CLASSDEF; + CLongStickDispenser() : CGameObject(), _fieldBC(0), + _fieldC0(0), _fieldC4(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LONG_STICK_DISPENSER_H */ diff --git a/engines/titanic/game/maitred/maitred_arm_holder.cpp b/engines/titanic/game/maitred/maitred_arm_holder.cpp new file mode 100644 index 0000000000..4d35277a33 --- /dev/null +++ b/engines/titanic/game/maitred/maitred_arm_holder.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/maitred/maitred_arm_holder.h" + +namespace Titanic { + +void CMaitreDArmHolder::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CDropTarget::save(file, indent); +} + +void CMaitreDArmHolder::load(SimpleFile *file) { + file->readNumber(); + CDropTarget::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/maitred/maitred_arm_holder.h b/engines/titanic/game/maitred/maitred_arm_holder.h new file mode 100644 index 0000000000..3392d60e43 --- /dev/null +++ b/engines/titanic/game/maitred/maitred_arm_holder.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_MAITRED_ARM_HOLDER_H +#define TITANIC_MAITRED_ARM_HOLDER_H + +#include "titanic/core/drop_target.h" + +namespace Titanic { + +class CMaitreDArmHolder : public CDropTarget { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MAITRED_ARM_HOLDER_H */ diff --git a/engines/titanic/game/maitred/maitred_body.cpp b/engines/titanic/game/maitred/maitred_body.cpp new file mode 100644 index 0000000000..6b495e5a1c --- /dev/null +++ b/engines/titanic/game/maitred/maitred_body.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/maitred/maitred_legs.h" + +namespace Titanic { + +void CMaitreDLegs::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldC8, indent); + CMaitreDProdReceptor::save(file, indent); +} + +void CMaitreDLegs::load(SimpleFile *file) { + file->readNumber(); + _fieldC8 = file->readNumber(); + CMaitreDProdReceptor::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/maitred/maitred_body.h b/engines/titanic/game/maitred/maitred_body.h new file mode 100644 index 0000000000..7016c15c71 --- /dev/null +++ b/engines/titanic/game/maitred/maitred_body.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_MAITRED_BODY_H +#define TITANIC_MAITRED_BODY_H + +#include "titanic/game/maitred/maitred_prod_receptor.h" + +namespace Titanic { + +class CMaitreDBody : public CMaitreDProdReceptor { +private: + int _fieldC8; +public: + CLASSDEF; + CMaitreDBody() : CMaitreDProdReceptor(), _fieldC8(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MAITRED_BODY_H */ diff --git a/engines/titanic/game/maitred/maitred_legs.cpp b/engines/titanic/game/maitred/maitred_legs.cpp new file mode 100644 index 0000000000..5071805101 --- /dev/null +++ b/engines/titanic/game/maitred/maitred_legs.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/maitred/maitred_body.h" + +namespace Titanic { + +void CMaitreDBody::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldC8, indent); + CMaitreDProdReceptor::save(file, indent); +} + +void CMaitreDBody::load(SimpleFile *file) { + file->readNumber(); + _fieldC8 = file->readNumber(); + CMaitreDProdReceptor::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/maitred/maitred_legs.h b/engines/titanic/game/maitred/maitred_legs.h new file mode 100644 index 0000000000..24ba01e712 --- /dev/null +++ b/engines/titanic/game/maitred/maitred_legs.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_MAITRED_LEGS_H +#define TITANIC_MAITRED_LEGS_H + +#include "titanic/game/maitred/maitred_prod_receptor.h" + +namespace Titanic { + +class CMaitreDLegs : public CMaitreDProdReceptor { +private: + int _fieldC8; +public: + CLASSDEF; + CMaitreDLegs() : CMaitreDProdReceptor(), _fieldC8(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MAITRED_LEGS_H */ diff --git a/engines/titanic/game/maitred/maitred_prod_receptor.cpp b/engines/titanic/game/maitred/maitred_prod_receptor.cpp new file mode 100644 index 0000000000..4823f143b0 --- /dev/null +++ b/engines/titanic/game/maitred/maitred_prod_receptor.cpp @@ -0,0 +1,45 @@ +/* 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 "titanic/game/maitred/maitred_prod_receptor.h" + +namespace Titanic { + +void CMaitreDProdReceptor::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + + CGameObject::save(file, indent); +} + +void CMaitreDProdReceptor::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/maitred/maitred_prod_receptor.h b/engines/titanic/game/maitred/maitred_prod_receptor.h new file mode 100644 index 0000000000..f3a547b8ef --- /dev/null +++ b/engines/titanic/game/maitred/maitred_prod_receptor.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_MAITRED_PROD_RECEPTOR_H +#define TITANIC_MAITRED_PROD_RECEPTOR_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CMaitreDProdReceptor : public CGameObject { +protected: + int _fieldBC; + int _fieldC0; + int _fieldC4; +public: + CLASSDEF; + CMaitreDProdReceptor() : CGameObject(), + _fieldBC(0), _fieldC0(0), _fieldC4(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MAITRED_PROD_RECEPTOR_H */ diff --git a/engines/titanic/game/missiveomat.cpp b/engines/titanic/game/missiveomat.cpp new file mode 100644 index 0000000000..931b146801 --- /dev/null +++ b/engines/titanic/game/missiveomat.cpp @@ -0,0 +1,55 @@ +/* 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 "titanic/game/missiveomat.h" + +namespace Titanic { + +CMissiveOMat::CMissiveOMat() : CGameObject(), _fieldBC(1), + _fieldC0(0), _fieldC4(0), _fieldE0(-1) { +} + +void CMissiveOMat::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_fieldE0, indent); + + CGameObject::save(file, indent); +} + +void CMissiveOMat::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + _fieldE0 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/missiveomat.h b/engines/titanic/game/missiveomat.h new file mode 100644 index 0000000000..7fde8cf25d --- /dev/null +++ b/engines/titanic/game/missiveomat.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_MISSIVEOMAT_H +#define TITANIC_MISSIVEOMAT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CMissiveOMat : public CGameObject { +public: + int _fieldBC; + int _fieldC0; + int _fieldC4; + CString _string1; + CString _string2; + int _fieldE0; +public: + CLASSDEF; + CMissiveOMat(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MISSIVEOMAT_H */ diff --git a/engines/titanic/game/missiveomat_button.cpp b/engines/titanic/game/missiveomat_button.cpp new file mode 100644 index 0000000000..d5ae75dbc2 --- /dev/null +++ b/engines/titanic/game/missiveomat_button.cpp @@ -0,0 +1,41 @@ +/* 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 "titanic/game/missiveomat_button.h" + +namespace Titanic { + +void CMissiveOMatButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldFC, indent); + + CEditControl::save(file, indent); +} + +void CMissiveOMatButton::load(SimpleFile *file) { + file->readNumber(); + _fieldFC = file->readNumber(); + + CEditControl::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/missiveomat_button.h b/engines/titanic/game/missiveomat_button.h new file mode 100644 index 0000000000..d36f5bd958 --- /dev/null +++ b/engines/titanic/game/missiveomat_button.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_MISSIVEOMAT_BUTTON_H +#define TITANIC_MISSIVEOMAT_BUTTON_H + +#include "titanic/gfx/edit_control.h" + +namespace Titanic { + +class CMissiveOMatButton : public CEditControl { +public: + int _fieldFC; +public: + CLASSDEF; + CMissiveOMatButton() : CEditControl(), _fieldFC(2) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MISSIVEOMAT_BUTTON_H */ diff --git a/engines/titanic/game/movie_tester.cpp b/engines/titanic/game/movie_tester.cpp new file mode 100644 index 0000000000..1b266d9c7e --- /dev/null +++ b/engines/titanic/game/movie_tester.cpp @@ -0,0 +1,41 @@ +/* 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 "titanic/game/movie_tester.h" + +namespace Titanic { + +void CMovieTester::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value1, indent); + file->writeNumberLine(_value2, indent); + CGameObject::save(file, indent); +} + +void CMovieTester::load(SimpleFile *file) { + file->readNumber(); + _value1 = file->readNumber(); + _value2 = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/movie_tester.h b/engines/titanic/game/movie_tester.h new file mode 100644 index 0000000000..de2ef2cc5e --- /dev/null +++ b/engines/titanic/game/movie_tester.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_MOVIE_TESTER_H +#define TITANIC_MOVIE_TESTER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CMovieTester : public CGameObject { +public: + int _value1, _value2; +public: + CLASSDEF; + CMovieTester() : CGameObject(), _value1(0), _value2(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVIE_TESTER_H */ diff --git a/engines/titanic/game/music_console_button.cpp b/engines/titanic/game/music_console_button.cpp new file mode 100644 index 0000000000..1bc78ffe23 --- /dev/null +++ b/engines/titanic/game/music_console_button.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/music_console_button.h" + +namespace Titanic { + +void CMusicConsoleButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMusicPlayer::save(file, indent); +} + +void CMusicConsoleButton::load(SimpleFile *file) { + file->readNumber(); + CMusicPlayer::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/music_console_button.h b/engines/titanic/game/music_console_button.h new file mode 100644 index 0000000000..8e05b698d7 --- /dev/null +++ b/engines/titanic/game/music_console_button.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_MUSIC_CONSOLE_BUTTON_H +#define TITANIC_MUSIC_CONSOLE_BUTTON_H + +#include "titanic/sound/music_player.h" + +namespace Titanic { + +class CMusicConsoleButton : public CMusicPlayer { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_CONSOLE_BUTTON_H */ diff --git a/engines/titanic/game/music_room_phonograph.cpp b/engines/titanic/game/music_room_phonograph.cpp new file mode 100644 index 0000000000..06a35dc4d5 --- /dev/null +++ b/engines/titanic/game/music_room_phonograph.cpp @@ -0,0 +1,41 @@ +/* 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 "titanic/game/music_room_phonograph.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CMusicRoomPhonograph, CRestaurantPhonograph); + +void CMusicRoomPhonograph::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field118, indent); + CRestaurantPhonograph::save(file, indent); +} + +void CMusicRoomPhonograph::load(SimpleFile *file) { + file->readNumber(); + _field118 = file->readNumber(); + CRestaurantPhonograph::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/music_room_phonograph.h b/engines/titanic/game/music_room_phonograph.h new file mode 100644 index 0000000000..9286861785 --- /dev/null +++ b/engines/titanic/game/music_room_phonograph.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_MUSIC_ROOM_PHONOGRAPH_H +#define TITANIC_MUSIC_ROOM_PHONOGRAPH_H + +#include "titanic/game/restaurant_phonograph.h" + +namespace Titanic { + +class CMusicRoomPhonograph : public CRestaurantPhonograph { + DECLARE_MESSAGE_MAP; +private: + int _field118; +public: + CLASSDEF; + CMusicRoomPhonograph() : CRestaurantPhonograph(), _field118(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_ROOM_PHONOGRAPH_H */ diff --git a/engines/titanic/game/music_room_stop_phonograph_button.cpp b/engines/titanic/game/music_room_stop_phonograph_button.cpp new file mode 100644 index 0000000000..44342fc2d6 --- /dev/null +++ b/engines/titanic/game/music_room_stop_phonograph_button.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/music_room_stop_phonograph_button.h" + +namespace Titanic { + +void CMusicRoomStopPhonographButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field100, indent); + CEjectPhonographButton::save(file, indent); +} + +void CMusicRoomStopPhonographButton::load(SimpleFile *file) { + file->readNumber(); + _field100 = file->readNumber(); + CEjectPhonographButton::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/music_room_stop_phonograph_button.h b/engines/titanic/game/music_room_stop_phonograph_button.h new file mode 100644 index 0000000000..7260e5aaab --- /dev/null +++ b/engines/titanic/game/music_room_stop_phonograph_button.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_MUSIC_ROOM_STOP_PHONOGRAPH_BUTTON_H +#define TITANIC_MUSIC_ROOM_STOP_PHONOGRAPH_BUTTON_H + +#include "titanic/game/eject_phonograph_button.h" + +namespace Titanic { + +class CMusicRoomStopPhonographButton : public CEjectPhonographButton { +private: + int _field100; +public: + CLASSDEF; + CMusicRoomStopPhonographButton() : CEjectPhonographButton(), _field100(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_ROOM_STOP_PHONOGRAPH_BUTTON_H */ diff --git a/engines/titanic/game/music_system_lock.cpp b/engines/titanic/game/music_system_lock.cpp new file mode 100644 index 0000000000..f1e062b3ee --- /dev/null +++ b/engines/titanic/game/music_system_lock.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/music_system_lock.h" + +namespace Titanic { + +void CMusicSystemLock::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CDropTarget::save(file, indent); +} + +void CMusicSystemLock::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CDropTarget::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/music_system_lock.h b/engines/titanic/game/music_system_lock.h new file mode 100644 index 0000000000..ff826f5c77 --- /dev/null +++ b/engines/titanic/game/music_system_lock.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_MUSIC_SYSTEM_LOCK_H +#define TITANIC_MUSIC_SYSTEM_LOCK_H + +#include "titanic/core/drop_target.h" + +namespace Titanic { + +class CMusicSystemLock : public CDropTarget { +private: + int _value; +public: + CLASSDEF; + CMusicSystemLock() : CDropTarget(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_SYSTEM_LOCK_H */ diff --git a/engines/titanic/game/musical_instrument.cpp b/engines/titanic/game/musical_instrument.cpp new file mode 100644 index 0000000000..3bd2e37ccc --- /dev/null +++ b/engines/titanic/game/musical_instrument.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/musical_instrument.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CMusicalInstrument, CBackground); + +void CMusicalInstrument::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CBackground::save(file, indent); +} + +void CMusicalInstrument::load(SimpleFile *file) { + file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/musical_instrument.h b/engines/titanic/game/musical_instrument.h new file mode 100644 index 0000000000..5d18ed91f0 --- /dev/null +++ b/engines/titanic/game/musical_instrument.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_MUSICAL_INSTRUMENT_H +#define TITANIC_MUSICAL_INSTRUMENT_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CMusicalInstrument : public CBackground { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSICAL_INSTRUMENT_H */ diff --git a/engines/titanic/game/nav_helmet.cpp b/engines/titanic/game/nav_helmet.cpp new file mode 100644 index 0000000000..770eb7375e --- /dev/null +++ b/engines/titanic/game/nav_helmet.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/nav_helmet.h" + +namespace Titanic { + +void CNavHelmet::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CNavHelmet::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/nav_helmet.h b/engines/titanic/game/nav_helmet.h new file mode 100644 index 0000000000..74caa52534 --- /dev/null +++ b/engines/titanic/game/nav_helmet.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_NAV_HELMET_H +#define TITANIC_NAV_HELMET_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CNavHelmet : public CGameObject { +private: + int _value; +public: + CLASSDEF; + CNavHelmet() : CGameObject(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NAV_HELMET_H */ diff --git a/engines/titanic/game/navigation_computer.cpp b/engines/titanic/game/navigation_computer.cpp new file mode 100644 index 0000000000..49bd252988 --- /dev/null +++ b/engines/titanic/game/navigation_computer.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/navigation_computer.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CNavigationComputer, CGameObject); + +void CNavigationComputer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CNavigationComputer::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/navigation_computer.h b/engines/titanic/game/navigation_computer.h new file mode 100644 index 0000000000..27d06c1f27 --- /dev/null +++ b/engines/titanic/game/navigation_computer.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_NAVIGATION_COMPUTER_H +#define TITANIC_NAVIGATION_COMPUTER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CNavigationComputer : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NAVIGATION_COMPUTER_H */ diff --git a/engines/titanic/game/no_nut_bowl.cpp b/engines/titanic/game/no_nut_bowl.cpp new file mode 100644 index 0000000000..47f9d7901e --- /dev/null +++ b/engines/titanic/game/no_nut_bowl.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/no_nut_bowl.h" + +namespace Titanic { + +void CNoNutBowl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CBackground::save(file, indent); +} + +void CNoNutBowl::load(SimpleFile *file) { + file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/no_nut_bowl.h b/engines/titanic/game/no_nut_bowl.h new file mode 100644 index 0000000000..548b324869 --- /dev/null +++ b/engines/titanic/game/no_nut_bowl.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_NO_NUT_BOWL_H +#define TITANIC_NO_NUT_BOWL_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CNoNutBowl : public CBackground { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NO_NUT_BOWL_H */ diff --git a/engines/titanic/game/nose_holder.cpp b/engines/titanic/game/nose_holder.cpp new file mode 100644 index 0000000000..cd9433ee9c --- /dev/null +++ b/engines/titanic/game/nose_holder.cpp @@ -0,0 +1,44 @@ +/* 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 "titanic/game/nose_holder.h" + +namespace Titanic { + +CNoseHolder::CNoseHolder() : CDropTarget(), _field118(0), _field11C(0) { +} + +void CNoseHolder::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field11C, indent); + + CDropTarget::save(file, indent); +} + +void CNoseHolder::load(SimpleFile *file) { + file->readNumber(); + _field11C = file->readNumber(); + + CDropTarget::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/nose_holder.h b/engines/titanic/game/nose_holder.h new file mode 100644 index 0000000000..b8cca95869 --- /dev/null +++ b/engines/titanic/game/nose_holder.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_NOSE_HOLDER_H +#define TITANIC_NOSE_HOLDER_H + +#include "titanic/core/drop_target.h" + +namespace Titanic { + +class CNoseHolder : public CDropTarget { +private: + int _field118; + int _field11C; +public: + CLASSDEF; + CNoseHolder(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NOSE_HOLDER_H */ diff --git a/engines/titanic/game/null_port_hole.cpp b/engines/titanic/game/null_port_hole.cpp new file mode 100644 index 0000000000..e651b1b59f --- /dev/null +++ b/engines/titanic/game/null_port_hole.cpp @@ -0,0 +1,50 @@ +/* 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 "titanic/game/null_port_hole.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CNullPortHole, CClickResponder); + +CNullPortHole::CNullPortHole() : CClickResponder() { + _string1 = "For a better view, why not visit the Promenade Deck?"; + _string2 = "b#48.wav"; +} + +void CNullPortHole::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string2, indent); + file->writeQuotedLine(_string1, indent); + + CClickResponder::save(file, indent); +} + +void CNullPortHole::load(SimpleFile *file) { + file->readNumber(); + _string2 = file->readString(); + _string1 = file->readString(); + + CClickResponder::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/null_port_hole.h b/engines/titanic/game/null_port_hole.h new file mode 100644 index 0000000000..26564271b9 --- /dev/null +++ b/engines/titanic/game/null_port_hole.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_NULL_PORT_HOLE_H +#define TITANIC_NULL_PORT_HOLE_H + +#include "titanic/core/click_responder.h" + +namespace Titanic { + +class CNullPortHole : public CClickResponder { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CNullPortHole(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NULL_PORT_HOLE_H */ diff --git a/engines/titanic/game/nut_replacer.cpp b/engines/titanic/game/nut_replacer.cpp new file mode 100644 index 0000000000..9a73355c91 --- /dev/null +++ b/engines/titanic/game/nut_replacer.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/nut_replacer.h" + +namespace Titanic { + +void CNutReplacer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CNutReplacer::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/nut_replacer.h b/engines/titanic/game/nut_replacer.h new file mode 100644 index 0000000000..ead9713801 --- /dev/null +++ b/engines/titanic/game/nut_replacer.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_NUT_REPLACER_H +#define TITANIC_NUT_REPLACER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CNutReplacer : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NUT_REPLACER_H */ diff --git a/engines/titanic/game/parrot/parrot_lobby_controller.cpp b/engines/titanic/game/parrot/parrot_lobby_controller.cpp new file mode 100644 index 0000000000..f1e054a8dd --- /dev/null +++ b/engines/titanic/game/parrot/parrot_lobby_controller.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/parrot/parrot_lobby_controller.h" + +namespace Titanic { + +void CParrotLobbyController::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CParrotLobbyObject::save(file, indent); +} + +void CParrotLobbyController::load(SimpleFile *file) { + file->readNumber(); + CParrotLobbyObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/parrot/parrot_lobby_controller.h b/engines/titanic/game/parrot/parrot_lobby_controller.h new file mode 100644 index 0000000000..d2fa4a1801 --- /dev/null +++ b/engines/titanic/game/parrot/parrot_lobby_controller.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PARROT_LOBBY_CONTROLLER_H +#define TITANIC_PARROT_LOBBY_CONTROLLER_H + +#include "titanic/game/parrot/parrot_lobby_object.h" + +namespace Titanic { + +class CParrotLobbyController : public CParrotLobbyObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARROT_LOBBY_CONTROLLER_H */ diff --git a/engines/titanic/game/parrot/parrot_lobby_link_updater.cpp b/engines/titanic/game/parrot/parrot_lobby_link_updater.cpp new file mode 100644 index 0000000000..25d5ec724b --- /dev/null +++ b/engines/titanic/game/parrot/parrot_lobby_link_updater.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/parrot/parrot_lobby_link_updater.h" + +namespace Titanic { + +void CParrotLobbyLinkUpdater::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CParrotLobbyObject::save(file, indent); +} + +void CParrotLobbyLinkUpdater::load(SimpleFile *file) { + file->readNumber(); + CParrotLobbyObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/parrot/parrot_lobby_link_updater.h b/engines/titanic/game/parrot/parrot_lobby_link_updater.h new file mode 100644 index 0000000000..0470a62dee --- /dev/null +++ b/engines/titanic/game/parrot/parrot_lobby_link_updater.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PARROT_LOBBY_LINK_UPDATER_H +#define TITANIC_PARROT_LOBBY_LINK_UPDATER_H + +#include "titanic/game/parrot/parrot_lobby_object.h" + +namespace Titanic { + +class CParrotLobbyLinkUpdater : public CParrotLobbyObject { +public: + int _fieldBC; +public: + CLASSDEF; + CParrotLobbyLinkUpdater() : CParrotLobbyObject(), _fieldBC(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARROT_LOBBY_LINK_UPDATER_H */ diff --git a/engines/titanic/game/parrot/parrot_lobby_object.cpp b/engines/titanic/game/parrot/parrot_lobby_object.cpp new file mode 100644 index 0000000000..a78ab2b6d9 --- /dev/null +++ b/engines/titanic/game/parrot/parrot_lobby_object.cpp @@ -0,0 +1,61 @@ +/* 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 "titanic/game/parrot/parrot_lobby_object.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CParrotLobbyObject, CGameObject); + +int CParrotLobbyObject::_v1; +int CParrotLobbyObject::_v2; +int CParrotLobbyObject::_v3; +int CParrotLobbyObject::_v4; + +void CParrotLobbyObject::init() { + _v1 = 1; + _v2 = 1; + _v3 = 1; + _v4 = 7; +} + +void CParrotLobbyObject::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + file->writeNumberLine(_v3, indent); + file->writeNumberLine(_v4, indent); + + CGameObject::save(file, indent); +} + +void CParrotLobbyObject::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + _v3 = file->readNumber(); + _v4 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/parrot/parrot_lobby_object.h b/engines/titanic/game/parrot/parrot_lobby_object.h new file mode 100644 index 0000000000..5272303888 --- /dev/null +++ b/engines/titanic/game/parrot/parrot_lobby_object.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_PARROT_LOBBY_OBJECT_H +#define TITANIC_PARROT_LOBBY_OBJECT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CParrotLobbyObject : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + static int _v1; + static int _v2; + static int _v3; + static int _v4; + + static void init(); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARROT_LOBBY_OBJECT_H */ diff --git a/engines/titanic/game/parrot/parrot_lobby_view_object.cpp b/engines/titanic/game/parrot/parrot_lobby_view_object.cpp new file mode 100644 index 0000000000..ae398036a8 --- /dev/null +++ b/engines/titanic/game/parrot/parrot_lobby_view_object.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/parrot/parrot_lobby_view_object.h" + +namespace Titanic { + +void CParrotLobbyViewObject::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + CParrotLobbyObject::save(file, indent); +} + +void CParrotLobbyViewObject::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + CParrotLobbyObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/parrot/parrot_lobby_view_object.h b/engines/titanic/game/parrot/parrot_lobby_view_object.h new file mode 100644 index 0000000000..3179bb962d --- /dev/null +++ b/engines/titanic/game/parrot/parrot_lobby_view_object.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PARROT_LOBBY_VIEW_OBJECT_H +#define TITANIC_PARROT_LOBBY_VIEW_OBJECT_H + +#include "titanic/game/parrot/parrot_lobby_object.h" + +namespace Titanic { + +class CParrotLobbyViewObject : public CParrotLobbyObject { +public: + int _fieldBC; +public: + CLASSDEF; + CParrotLobbyViewObject() : CParrotLobbyObject(), _fieldBC(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARROT_LOBBY_VIEW_OBJECT_H */ diff --git a/engines/titanic/game/parrot/parrot_loser.cpp b/engines/titanic/game/parrot/parrot_loser.cpp new file mode 100644 index 0000000000..6e23ef8314 --- /dev/null +++ b/engines/titanic/game/parrot/parrot_loser.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/parrot/parrot_loser.h" + +namespace Titanic { + +void CParrotLoser::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CParrotLoser::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/parrot/parrot_loser.h b/engines/titanic/game/parrot/parrot_loser.h new file mode 100644 index 0000000000..819fd6614c --- /dev/null +++ b/engines/titanic/game/parrot/parrot_loser.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PARROT_LOSER_H +#define TITANIC_PARROT_LOSER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CParrotLoser : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARROT_LOSER_H */ diff --git a/engines/titanic/game/parrot/parrot_nut_bowl_actor.cpp b/engines/titanic/game/parrot/parrot_nut_bowl_actor.cpp new file mode 100644 index 0000000000..c83d66cbdf --- /dev/null +++ b/engines/titanic/game/parrot/parrot_nut_bowl_actor.cpp @@ -0,0 +1,47 @@ +/* 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 "titanic/game/parrot/parrot_nut_bowl_actor.h" + +namespace Titanic { + +CParrotNutBowlActor::CParrotNutBowlActor() : CGameObject(), + _value1(0), _value2(0) { +} + +void CParrotNutBowlActor::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value1, indent); + file->writeNumberLine(_value2, indent); + + CGameObject::save(file, indent); +} + +void CParrotNutBowlActor::load(SimpleFile *file) { + file->readNumber(); + _value1 = file->readNumber(); + _value2 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/parrot/parrot_nut_bowl_actor.h b/engines/titanic/game/parrot/parrot_nut_bowl_actor.h new file mode 100644 index 0000000000..d8395bb65a --- /dev/null +++ b/engines/titanic/game/parrot/parrot_nut_bowl_actor.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PARROT_NUT_BOWL_ACTOR_H +#define TITANIC_PARROT_NUT_BOWL_ACTOR_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CParrotNutBowlActor : public CGameObject { +public: + int _value1, _value2; +public: + CLASSDEF; + CParrotNutBowlActor(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARROT_NUT_BOWL_ACTOR_H */ diff --git a/engines/titanic/game/parrot/parrot_nut_eater.cpp b/engines/titanic/game/parrot/parrot_nut_eater.cpp new file mode 100644 index 0000000000..309b379ab8 --- /dev/null +++ b/engines/titanic/game/parrot/parrot_nut_eater.cpp @@ -0,0 +1,45 @@ +/* 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 "titanic/game/parrot/parrot_nut_eater.h" + +namespace Titanic { + +CParrotNutEater::CParrotNutEater() : CGameObject(), _fieldBC(0), + _fieldC0(69), _fieldC4(132), _fieldC8(0), _fieldCC(68) { +} + +void CParrotNutEater::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + + CGameObject::save(file, indent); +} + +void CParrotNutEater::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/parrot/parrot_nut_eater.h b/engines/titanic/game/parrot/parrot_nut_eater.h new file mode 100644 index 0000000000..5dcb01ca11 --- /dev/null +++ b/engines/titanic/game/parrot/parrot_nut_eater.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_PARROT_NUT_EATER_H +#define TITANIC_PARROT_NUT_EATER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CParrotNutEater : public CGameObject { +public: + int _fieldBC; + int _fieldC0; + int _fieldC4; + int _fieldC8; + int _fieldCC; +public: + CLASSDEF; + CParrotNutEater(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CREDITS_H */ diff --git a/engines/titanic/game/parrot/parrot_perch_holder.cpp b/engines/titanic/game/parrot/parrot_perch_holder.cpp new file mode 100644 index 0000000000..dd8523990b --- /dev/null +++ b/engines/titanic/game/parrot/parrot_perch_holder.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/parrot/parrot_perch_holder.h" + +namespace Titanic { + +void CParrotPerchHolder::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMultiDropTarget::save(file, indent); +} + +void CParrotPerchHolder::load(SimpleFile *file) { + file->readNumber(); + CMultiDropTarget::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/parrot/parrot_perch_holder.h b/engines/titanic/game/parrot/parrot_perch_holder.h new file mode 100644 index 0000000000..ff618f09dc --- /dev/null +++ b/engines/titanic/game/parrot/parrot_perch_holder.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PARROT_PERCH_HOLDER_H +#define TITANIC_PARROT_PERCH_HOLDER_H + +#include "titanic/core/multi_drop_target.h" + +namespace Titanic { + +class CParrotPerchHolder : public CMultiDropTarget { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARROT_PERCH_HOLDER_H */ diff --git a/engines/titanic/game/parrot/parrot_succubus.cpp b/engines/titanic/game/parrot/parrot_succubus.cpp new file mode 100644 index 0000000000..02a29b748e --- /dev/null +++ b/engines/titanic/game/parrot/parrot_succubus.cpp @@ -0,0 +1,49 @@ +/* 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 "titanic/game/parrot/parrot_succubus.h" + +namespace Titanic { + +CParrotSuccUBus::CParrotSuccUBus() : CSuccUBus(), _field1DC(0), + _field1EC(0), _field1F0(376), _field1F4(393) { +} + +void CParrotSuccUBus::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field1DC, indent); + file->writeQuotedLine(_string3, indent); + file->writeNumberLine(_field1EC, indent); + + CSuccUBus::save(file, indent); +} + +void CParrotSuccUBus::load(SimpleFile *file) { + file->readNumber(); + _field1DC = file->readNumber(); + _string3 = file->readString(); + _field1EC = file->readNumber(); + + CSuccUBus::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/parrot/parrot_succubus.h b/engines/titanic/game/parrot/parrot_succubus.h new file mode 100644 index 0000000000..6f5d9e602a --- /dev/null +++ b/engines/titanic/game/parrot/parrot_succubus.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_PARROT_SUCCUBUS_H +#define TITANIC_PARROT_SUCCUBUS_H + +#include "titanic/npcs/succubus.h" + +namespace Titanic { + +class CParrotSuccUBus : public CSuccUBus { +public: + int _field1DC; + CString _string3; + int _field1EC; + int _field1F0; + int _field1F4; +public: + CLASSDEF; + CParrotSuccUBus(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARROT_SUCCUBUS_H */ diff --git a/engines/titanic/game/parrot/parrot_trigger.cpp b/engines/titanic/game/parrot/parrot_trigger.cpp new file mode 100644 index 0000000000..36e99ada33 --- /dev/null +++ b/engines/titanic/game/parrot/parrot_trigger.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/parrot/parrot_trigger.h" + +namespace Titanic { + +void CParrotTrigger::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CParrotTrigger::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/parrot/parrot_trigger.h b/engines/titanic/game/parrot/parrot_trigger.h new file mode 100644 index 0000000000..28a1663fa8 --- /dev/null +++ b/engines/titanic/game/parrot/parrot_trigger.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PARROT_TRIGGER_H +#define TITANIC_PARROT_TRIGGER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CParrotTrigger : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CParrotTrigger() : CGameObject(), _value(0x446AB) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARROT_TRIGGER_H */ diff --git a/engines/titanic/game/parrot/player_meets_parrot.cpp b/engines/titanic/game/parrot/player_meets_parrot.cpp new file mode 100644 index 0000000000..6db9345bc0 --- /dev/null +++ b/engines/titanic/game/parrot/player_meets_parrot.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/game/parrot/player_meets_parrot.h" + +namespace Titanic { + +void CPlayerMeetsParrot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPlayerMeetsParrot::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +bool CPlayerMeetsParrot::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CPlayerMeetsParrot::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/parrot/player_meets_parrot.h b/engines/titanic/game/parrot/player_meets_parrot.h new file mode 100644 index 0000000000..9cee9ee322 --- /dev/null +++ b/engines/titanic/game/parrot/player_meets_parrot.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PLAYER_MEETS_PARROT_H +#define TITANIC_PLAYER_MEETS_PARROT_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CPlayerMeetsParrot : public CGameObject { +protected: + bool EnterRoomMsg(CEnterRoomMsg *msg); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PLAYER_MEETS_PARROT_H */ diff --git a/engines/titanic/game/pet/pet.cpp b/engines/titanic/game/pet/pet.cpp new file mode 100644 index 0000000000..cd4e16d38c --- /dev/null +++ b/engines/titanic/game/pet/pet.cpp @@ -0,0 +1,57 @@ +/* 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 "titanic/game/pet/pet.h" + +namespace Titanic { + +CPET::CPET() : CGameObject(), _fieldBC(0), _fieldC0(3), + _fieldC4(0), _fieldC8(0), _fieldD8(0), _fieldDC(0) { +} + +void CPET::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeQuotedLine(_string1, indent); + file->writeNumberLine(_fieldD8, indent); + file->writeNumberLine(_fieldDC, indent); + + CGameObject::save(file, indent); +} + +void CPET::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + _fieldC8 = file->readNumber(); + _string1 = file->readString(); + _fieldD8 = file->readNumber(); + _fieldDC = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet.h b/engines/titanic/game/pet/pet.h new file mode 100644 index 0000000000..cdad649401 --- /dev/null +++ b/engines/titanic/game/pet/pet.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_PET_H +#define TITANIC_PET_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPET : public CGameObject { +public: + int _fieldBC; + int _fieldC0; + int _fieldC4; + int _fieldC8; + CString _string1; + int _fieldD8; + int _fieldDC; +public: + CLASSDEF; + CPET(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_H */ diff --git a/engines/titanic/game/pet/pet_class1.cpp b/engines/titanic/game/pet/pet_class1.cpp new file mode 100644 index 0000000000..651a8f9ed3 --- /dev/null +++ b/engines/titanic/game/pet/pet_class1.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/pet/pet_class1.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CPETClass1, CGameObject); + +void CPETClass1::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPETClass1::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_class1.h b/engines/titanic/game/pet/pet_class1.h new file mode 100644 index 0000000000..fb7a48b927 --- /dev/null +++ b/engines/titanic/game/pet/pet_class1.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_PET_CLASS1_H +#define TITANIC_PET_CLASS1_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPETClass1 : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_CLASS1_H */ diff --git a/engines/titanic/game/pet/pet_class2.cpp b/engines/titanic/game/pet/pet_class2.cpp new file mode 100644 index 0000000000..e3e23f62ed --- /dev/null +++ b/engines/titanic/game/pet/pet_class2.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/pet/pet_class2.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CPETClass2, CGameObject); + +void CPETClass2::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPETClass2::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_class2.h b/engines/titanic/game/pet/pet_class2.h new file mode 100644 index 0000000000..c8855c82f3 --- /dev/null +++ b/engines/titanic/game/pet/pet_class2.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_PET_CLASS2_H +#define TITANIC_PET_CLASS2_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPETClass2 : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_CLASS2_H */ diff --git a/engines/titanic/game/pet/pet_class3.cpp b/engines/titanic/game/pet/pet_class3.cpp new file mode 100644 index 0000000000..7751b994ab --- /dev/null +++ b/engines/titanic/game/pet/pet_class3.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/pet/pet_class3.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CPETClass3, CGameObject); + +void CPETClass3::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPETClass3::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_class3.h b/engines/titanic/game/pet/pet_class3.h new file mode 100644 index 0000000000..59d8389665 --- /dev/null +++ b/engines/titanic/game/pet/pet_class3.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_PET_CLASS3_H +#define TITANIC_PET_CLASS3_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPETClass3 : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_CLASS3_H */ diff --git a/engines/titanic/game/pet/pet_lift.cpp b/engines/titanic/game/pet/pet_lift.cpp new file mode 100644 index 0000000000..39b0d01540 --- /dev/null +++ b/engines/titanic/game/pet/pet_lift.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/pet/pet_lift.h" + +namespace Titanic { + +void CPETLift::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPETTransport::save(file, indent); +} + +void CPETLift::load(SimpleFile *file) { + file->readNumber(); + CPETTransport::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_lift.h b/engines/titanic/game/pet/pet_lift.h new file mode 100644 index 0000000000..88b4e1c029 --- /dev/null +++ b/engines/titanic/game/pet/pet_lift.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PET_LIFT_H +#define TITANIC_PET_LIFT_H + +#include "titanic/game/pet/pet_transport.h" + +namespace Titanic { + +class CPETLift : public CPETTransport { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_LIFT_H */ diff --git a/engines/titanic/game/pet/pet_monitor.cpp b/engines/titanic/game/pet/pet_monitor.cpp new file mode 100644 index 0000000000..6a0d207a55 --- /dev/null +++ b/engines/titanic/game/pet/pet_monitor.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/game/pet/pet_monitor.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CPETMonitor, CGameObject) + ON_MESSAGE(EnterRoomMsg) +END_MESSAGE_MAP() + +void CPETMonitor::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPETMonitor::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +bool CPETMonitor::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CPETMonitor::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_monitor.h b/engines/titanic/game/pet/pet_monitor.h new file mode 100644 index 0000000000..61d1ba8ab6 --- /dev/null +++ b/engines/titanic/game/pet/pet_monitor.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PET_MONITOR_H +#define TITANIC_PET_MONITOR_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CPETMonitor : public CGameObject { + DECLARE_MESSAGE_MAP; + bool EnterRoomMsg(CEnterRoomMsg *msg); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_MONITOR_H */ diff --git a/engines/titanic/game/pet/pet_pellerator.cpp b/engines/titanic/game/pet/pet_pellerator.cpp new file mode 100644 index 0000000000..a29942ca59 --- /dev/null +++ b/engines/titanic/game/pet/pet_pellerator.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/pet/pet_pellerator.h" + +namespace Titanic { + +void CPETPellerator::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPETTransport::save(file, indent); +} + +void CPETPellerator::load(SimpleFile *file) { + file->readNumber(); + CPETTransport::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_pellerator.h b/engines/titanic/game/pet/pet_pellerator.h new file mode 100644 index 0000000000..9b90c9af28 --- /dev/null +++ b/engines/titanic/game/pet/pet_pellerator.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PET_PELLERATOR_H +#define TITANIC_PET_PELLERATOR_H + +#include "titanic/game/pet/pet_transport.h" + +namespace Titanic { + +class CPETPellerator : public CPETTransport { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_PELLERATOR_H */ diff --git a/engines/titanic/game/pet/pet_position.cpp b/engines/titanic/game/pet/pet_position.cpp new file mode 100644 index 0000000000..d3d030eb16 --- /dev/null +++ b/engines/titanic/game/pet/pet_position.cpp @@ -0,0 +1,264 @@ +/* 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 "titanic/game/pet/pet_position.h" +#include "titanic/core/view_item.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CPETPosition, CGameObject) + ON_MESSAGE(EnterRoomMsg) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(LeaveViewMsg) +END_MESSAGE_MAP() + +void CPETPosition::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPETPosition::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +bool CPETPosition::EnterRoomMsg(CEnterRoomMsg *msg) { + if (msg->_newRoom->getName() == "EmbLobby") { + CPetControl *pet = getPetControl(); + if (pet) + pet->setRoomsFloorNum(1); + } + + return true; +} + +bool CPETPosition::EnterViewMsg(CEnterViewMsg *msg) { + CPetControl *pet = getPetControl(); + CString viewStr = msg->_newView->getNodeViewName(); + CString tempStr; + + if (compareRoomNameTo("TopOfWell")) { + tempStr = msg->_newView->getNodeViewName(); + int wellEntry = 0; + + if (tempStr == "Node 25.N") + wellEntry = 1; + else if (tempStr == "Node 24.SE") + wellEntry = 2; + else if (tempStr == "Node 26.N") + wellEntry = 3; + else if (tempStr == "Node 27.N") + wellEntry = 4; + + if (wellEntry != 0) + petSetRoomsWellEntry(wellEntry); + } else if (compareRoomNameTo("1stClassLobby")) { + int roomNum = 0; + + if (viewStr == "Node 2.N") + roomNum = 1; + else if (viewStr == "Node 3.N") + roomNum = 2; + else if (viewStr == "Node 4.N") + roomNum = 3; + else if (viewStr == "Node 5.N") + roomNum = 1; + else if (viewStr == "Node 6.N") + roomNum = 2; + else if (viewStr == "Node 7.N") + roomNum = 3; + + if (pet) { + pet->setRoomsRoomNum(roomNum); + pet->resetRoomsHighlight(); + + int elevatorNum = pet->getRoomsElevatorNum(); + int wellEntry = 0; + + if (viewStr == "Node 10.S") + wellEntry = (elevatorNum == 1 || elevatorNum == 2) ? 1 : 3; + else if (viewStr == "Node 9.S") + wellEntry = (elevatorNum == 1 || elevatorNum == 2) ? 2 : 4; + + if (wellEntry) + petSetRoomsWellEntry(wellEntry); + } + } else if (compareRoomNameTo("2ndClassLobby")) { + int roomNum = 0; + + if (viewStr == "Node 3.N") + roomNum = 1; + else if (viewStr == "Node 4.N") + roomNum = 2; + else if (viewStr == "Node 5.N") + roomNum = 3; + else if (viewStr == "Node 6.N") + roomNum = 4; + + if (pet) { + pet->setRoomsRoomNum(roomNum); + pet->resetRoomsHighlight(); + + int elevatorNum = pet->getRoomsElevatorNum(); + int wellEntry = 0; + + if (viewStr == "Node 8.S") + wellEntry = (elevatorNum == 1 || elevatorNum == 2) ? 1 : 3; + else if (viewStr == "Node 1.S") + wellEntry = (elevatorNum == 1 || elevatorNum == 2) ? 2 : 4; + + if (wellEntry) + petSetRoomsWellEntry(wellEntry); + } + } else if (compareRoomNameTo("SecClassLittleLift")) { + if (pet && viewStr == "Node 1.N") + pet->resetRoomsHighlight(); + } else if (compareRoomNameTo("SGTLittleLift")) { + if (pet && viewStr == "Node 1.N") + pet->resetRoomsHighlight(); + } else if (compareRoomNameTo("SgtLobby")) { + int roomNum = 0; + + if (viewStr == "Node 4.N") + roomNum = 1; + else if (viewStr == "Node 5.N") + roomNum = 2; + else if (viewStr == "Node 6.N") + roomNum = 3; + else if (viewStr == "Node 7.N") + roomNum = 4; + else if (viewStr == "Node 8.N") + roomNum = 5; + else if (viewStr == "Node 9.N") + roomNum = 6; + + if (pet) { + pet->setRooms1CC(1); + pet->setRoomsRoomNum(roomNum); + + if (viewStr == "Node 1.S") + pet->setRoomsWellEntry(pet->getRoomsElevatorNum()); + } + } else if (compareRoomNameTo("BottomOfWell")) { + if (viewStr == "Node 10.E") + petSetRoomsWellEntry(3); + else if (viewStr == "Node 11.W") + petSetRoomsWellEntry(1); + } + + return true; +} + +bool CPETPosition::LeaveViewMsg(CLeaveViewMsg *msg) { + CPetControl *pet = getPetControl(); + CString oldView = msg->_oldView->getName(); + CString newView = msg->_newView->getName(); + + if (pet && newView == "Lift.Node 1.N") { + int elevatorNum = pet->getRoomsElevatorNum(); + + if (oldView == "TopOfWell.Node 25.N") { + pet->setRoomsFloorNum(1); + pet->setRoomsElevatorNum(1); + return true; + } else if (oldView == "TopOfWell.Node 24.SE") { + pet->setRoomsFloorNum(1); + pet->setRoomsElevatorNum(2); + return true; + } else if (oldView == "TopOfWell.Node 26.N") { + pet->setRoomsFloorNum(1); + pet->setRoomsElevatorNum(3); + return true; + } else if (oldView == "TopOfWell.Node 27.N") { + pet->setRoomsFloorNum(1); + pet->setRoomsElevatorNum(4); + return true; + } else if (oldView == "1stClassLobby.Node 10.S") { + switch (elevatorNum) { + case 1: + pet->setRoomsFloorNum(1); + pet->setRoomsElevatorNum(1); + break; + case 2: + pet->setRoomsElevatorNum(1); + break; + default: + pet->setRoomsElevatorNum(3); + break; + } + return true; + } else if (oldView == "1stClassLobby.Node 9.S") { + switch (elevatorNum) { + case 1: + case 2: + pet->setRoomsElevatorNum(2); + break; + default: + pet->setRoomsElevatorNum(4); + break; + } + return true; + } else if (oldView == "2ndClassLobby.Node 8.S") { + switch (elevatorNum) { + case 1: + case 2: + pet->setRoomsElevatorNum(1); + break; + default: + pet->setRoomsElevatorNum(3); + break; + } + return true; + } else if (oldView == "2ndClassLobby.Node 1.S") { + switch (elevatorNum) { + case 1: + case 2: + pet->setRoomsElevatorNum(2); + break; + default: + pet->setRoomsElevatorNum(4); + break; + } + return true; + } else if (oldView == "SgtLobby.Node 1.S") { + return true; + } else if (oldView == "BottomOfWell.Node 10.E" || oldView == "BottomOfWell.Node 11.W") { + pet->setRoomsElevatorNum(1); + return true; + } + } + + CRoomItem *newRoom = msg->_newView->findRoom(); + if (newRoom) { + CString roomName = newRoom->getName(); + if (roomName == "1stClassLobby" || roomName == "2ndClassLobby" || roomName == "SgtLobby") { + if (pet) + pet->resetRoomsHighlight(); + } + } + + return true; +} + + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_position.h b/engines/titanic/game/pet/pet_position.h new file mode 100644 index 0000000000..0cf835f23f --- /dev/null +++ b/engines/titanic/game/pet/pet_position.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_PET_POSITION_H +#define TITANIC_PET_POSITION_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CPETPosition : public CGameObject { + DECLARE_MESSAGE_MAP; + bool EnterRoomMsg(CEnterRoomMsg *msg); + bool EnterViewMsg(CEnterViewMsg *msg); + bool LeaveViewMsg(CLeaveViewMsg *msg); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_POSITION_H */ diff --git a/engines/titanic/game/pet/pet_sentinal.cpp b/engines/titanic/game/pet/pet_sentinal.cpp new file mode 100644 index 0000000000..1b647d7c62 --- /dev/null +++ b/engines/titanic/game/pet/pet_sentinal.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/pet/pet_sentinal.h" + +namespace Titanic { + +void CPETSentinal::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPETSentinal::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_sentinal.h b/engines/titanic/game/pet/pet_sentinal.h new file mode 100644 index 0000000000..f7f9fef0ba --- /dev/null +++ b/engines/titanic/game/pet/pet_sentinal.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PET_SENTINAL_H +#define TITANIC_PET_SENTINAL_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPETSentinal : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_SENTINAL_H */ diff --git a/engines/titanic/game/pet/pet_sounds.cpp b/engines/titanic/game/pet/pet_sounds.cpp new file mode 100644 index 0000000000..d612c745bb --- /dev/null +++ b/engines/titanic/game/pet/pet_sounds.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/pet/pet_sounds.h" + +namespace Titanic { + +void CPETSounds::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CPETSounds::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_sounds.h b/engines/titanic/game/pet/pet_sounds.h new file mode 100644 index 0000000000..1d3acdb5f3 --- /dev/null +++ b/engines/titanic/game/pet/pet_sounds.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PET_SOUNDS_H +#define TITANIC_PET_SOUNDS_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPETSounds : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CPETSounds() : CGameObject(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_SOUNDS_H */ diff --git a/engines/titanic/game/pet/pet_transition.cpp b/engines/titanic/game/pet/pet_transition.cpp new file mode 100644 index 0000000000..33cc36ca11 --- /dev/null +++ b/engines/titanic/game/pet/pet_transition.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/pet/pet_transition.h" + +namespace Titanic { + +void CPETTransition::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPETTransition::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_transition.h b/engines/titanic/game/pet/pet_transition.h new file mode 100644 index 0000000000..4abf16d509 --- /dev/null +++ b/engines/titanic/game/pet/pet_transition.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PET_TRANSITION_H +#define TITANIC_PET_TRANSITION_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPETTransition : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_TRANSITION_H */ diff --git a/engines/titanic/game/pet/pet_transport.cpp b/engines/titanic/game/pet/pet_transport.cpp new file mode 100644 index 0000000000..9661cace2c --- /dev/null +++ b/engines/titanic/game/pet/pet_transport.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/game/pet/pet_transport.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CPETTransport, CGameObject) + ON_MESSAGE(EnterRoomMsg) +END_MESSAGE_MAP() + +void CPETTransport::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPETTransport::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +bool CPETTransport::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CPETTransport::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_transport.h b/engines/titanic/game/pet/pet_transport.h new file mode 100644 index 0000000000..58aefe6743 --- /dev/null +++ b/engines/titanic/game/pet/pet_transport.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PET_TRANSPORT_H +#define TITANIC_PET_TRANSPORT_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CPETTransport : public CGameObject { + DECLARE_MESSAGE_MAP; + virtual bool EnterRoomMsg(CEnterRoomMsg *msg); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_TRANSPORT_H */ diff --git a/engines/titanic/game/pet/pet_val_base.cpp b/engines/titanic/game/pet/pet_val_base.cpp new file mode 100644 index 0000000000..d77f366436 --- /dev/null +++ b/engines/titanic/game/pet/pet_val_base.cpp @@ -0,0 +1,31 @@ +/* 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 "titanic/game/pet/pet_val_base.h" + +namespace Titanic { + +CPetValBase::CPetValBase() : _field4(0), _field8(0), + _fieldC(0), _field10(0), _field14(0) { +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet/pet_val_base.h b/engines/titanic/game/pet/pet_val_base.h new file mode 100644 index 0000000000..cdb2808108 --- /dev/null +++ b/engines/titanic/game/pet/pet_val_base.h @@ -0,0 +1,61 @@ +/* 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 TITANIC_pet_element_H +#define TITANIC_pet_element_H + +namespace Titanic { + +class CPetElement { +protected: + int _field4; + int _field8; + int _fieldC; + int _field10; + int _field14; +public: + CPetElement(); + + virtual void proc1() {} + virtual void proc2() {} + virtual void proc3() {} + virtual void proc4() {} + + virtual void proc5() {} + + virtual void proc6() {} + virtual void proc7() {} + virtual void proc8() {} + virtual void proc9() {} + virtual void proc10() {} + virtual void proc11() {} + virtual void proc12() {} + virtual void proc13() {} + virtual void proc14() {} + virtual void proc15() {} + virtual void proc16() {} + virtual void proc17() {} +}; + +} // End of namespace Titanic + +#endif /* TITANIC_pet_element_H */ diff --git a/engines/titanic/game/pet_disabler.cpp b/engines/titanic/game/pet_disabler.cpp new file mode 100644 index 0000000000..2275156503 --- /dev/null +++ b/engines/titanic/game/pet_disabler.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/pet_disabler.h" + +namespace Titanic { + +void CPetDisabler::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_value, indent); + CGameObject::save(file, indent); +} + +void CPetDisabler::load(SimpleFile *file) { + file->readNumber(); + _value = file->readString(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pet_disabler.h b/engines/titanic/game/pet_disabler.h new file mode 100644 index 0000000000..92b4dff0a8 --- /dev/null +++ b/engines/titanic/game/pet_disabler.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PET_DISABLER_H +#define TITANIC_PET_DISABLER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPetDisabler : public CGameObject { +public: + CString _value; +public: + CLASSDEF; + CPetDisabler() : CGameObject() {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_DISABLER_H */ diff --git a/engines/titanic/game/phonograph.cpp b/engines/titanic/game/phonograph.cpp new file mode 100644 index 0000000000..9740e29273 --- /dev/null +++ b/engines/titanic/game/phonograph.cpp @@ -0,0 +1,63 @@ +/* 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 "titanic/game/phonograph.h" + +namespace Titanic { + +CPhonograph::CPhonograph() : CMusicPlayer(), + _fieldE0(0), _fieldE4(0), _fieldE8(0), _fieldEC(0), + _fieldF0(0), _fieldF4(0) { +} + +void CPhonograph::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_fieldF0, indent); + file->writeNumberLine(_fieldF4, indent); + + CMusicPlayer::save(file, indent); +} + +void CPhonograph::load(SimpleFile *file) { + file->readNumber(); + _string2 = file->readString(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + _fieldF0 = file->readNumber(); + _fieldF4 = file->readNumber(); + + CMusicPlayer::load(file); +} + +bool CPhonograph::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CPhonograph::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/phonograph.h b/engines/titanic/game/phonograph.h new file mode 100644 index 0000000000..274d4ba367 --- /dev/null +++ b/engines/titanic/game/phonograph.h @@ -0,0 +1,58 @@ +/* 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 TITANIC_PHONOGRAPH_H +#define TITANIC_PHONOGRAPH_H + +#include "titanic/sound/music_player.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CPhonograph : public CMusicPlayer { + bool EnterRoomMsg(CEnterRoomMsg *msg); +protected: + CString _string2; + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; + int _fieldF0; + int _fieldF4; +public: + CLASSDEF; + CPhonograph(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_CONSOLE_BUTTON_H */ diff --git a/engines/titanic/game/phonograph_lid.cpp b/engines/titanic/game/phonograph_lid.cpp new file mode 100644 index 0000000000..a0518420f7 --- /dev/null +++ b/engines/titanic/game/phonograph_lid.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/phonograph_lid.h" + +namespace Titanic { + +void CPhonographLid::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CPhonographLid::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/phonograph_lid.h b/engines/titanic/game/phonograph_lid.h new file mode 100644 index 0000000000..ab32be268b --- /dev/null +++ b/engines/titanic/game/phonograph_lid.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PHONOGRAPH_LID_H +#define TITANIC_PHONOGRAPH_LID_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPhonographLid : public CGameObject { +private: + int _value; +public: + CLASSDEF; + CPhonographLid() : CGameObject(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PHONOGRAPH_LID_H */ diff --git a/engines/titanic/game/pickup/pick_up.cpp b/engines/titanic/game/pickup/pick_up.cpp new file mode 100644 index 0000000000..c660a36a32 --- /dev/null +++ b/engines/titanic/game/pickup/pick_up.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/pickup/pick_up.h" + +namespace Titanic { + +void CPickUp::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + CGameObject::save(file, indent); +} + +void CPickUp::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pickup/pick_up.h b/engines/titanic/game/pickup/pick_up.h new file mode 100644 index 0000000000..f0b6794442 --- /dev/null +++ b/engines/titanic/game/pickup/pick_up.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PICK_UP_H +#define TITANIC_PICK_UP_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPickUp : public CGameObject { +private: + int _fieldBC; +public: + CLASSDEF; + CPickUp() : CGameObject(), _fieldBC(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ANNOY_BARBOT_H */ diff --git a/engines/titanic/game/pickup/pick_up_bar_glass.cpp b/engines/titanic/game/pickup/pick_up_bar_glass.cpp new file mode 100644 index 0000000000..85b883281e --- /dev/null +++ b/engines/titanic/game/pickup/pick_up_bar_glass.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/pickup/pick_up_bar_glass.h" + +namespace Titanic { + +void CPickUpBarGlass::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPickUp::save(file, indent); +} + +void CPickUpBarGlass::load(SimpleFile *file) { + file->readNumber(); + CPickUp::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pickup/pick_up_bar_glass.h b/engines/titanic/game/pickup/pick_up_bar_glass.h new file mode 100644 index 0000000000..b5ef6f5a47 --- /dev/null +++ b/engines/titanic/game/pickup/pick_up_bar_glass.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PICK_UP_BAR_GLASS_H +#define TITANIC_PICK_UP_BAR_GLASS_H + +#include "titanic/game/pickup/pick_up.h" + +namespace Titanic { + +class CPickUpBarGlass : public CPickUp { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PICK_UP_BAR_GLASS_H */ diff --git a/engines/titanic/game/pickup/pick_up_hose.cpp b/engines/titanic/game/pickup/pick_up_hose.cpp new file mode 100644 index 0000000000..7375ddaa63 --- /dev/null +++ b/engines/titanic/game/pickup/pick_up_hose.cpp @@ -0,0 +1,45 @@ +/* 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 "titanic/game/pickup/pick_up_hose.h" + +namespace Titanic { + +int CPickUpHose::_v1; + +void CPickUpHose::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + file->writeNumberLine(_v1, indent); + + CPickUp::save(file, indent); +} + +void CPickUpHose::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + _v1 = file->readNumber(); + + CPickUp::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pickup/pick_up_hose.h b/engines/titanic/game/pickup/pick_up_hose.h new file mode 100644 index 0000000000..80ccedc845 --- /dev/null +++ b/engines/titanic/game/pickup/pick_up_hose.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_PICK_UP_HOSE_H +#define TITANIC_PICK_UP_HOSE_H + +#include "titanic/game/pickup/pick_up.h" + +namespace Titanic { + +class CPickUpHose : public CPickUp { +private: + static int _v1; + + CString _string1; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PICK_UP_HOSE_H */ diff --git a/engines/titanic/game/pickup/pick_up_lemon.cpp b/engines/titanic/game/pickup/pick_up_lemon.cpp new file mode 100644 index 0000000000..772114f76c --- /dev/null +++ b/engines/titanic/game/pickup/pick_up_lemon.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/pickup/pick_up_lemon.h" + +namespace Titanic { + +void CPickUpLemon::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPickUp::save(file, indent); +} + +void CPickUpLemon::load(SimpleFile *file) { + file->readNumber(); + CPickUp::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pickup/pick_up_lemon.h b/engines/titanic/game/pickup/pick_up_lemon.h new file mode 100644 index 0000000000..0312c71012 --- /dev/null +++ b/engines/titanic/game/pickup/pick_up_lemon.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PICK_UP_LEMON_H +#define TITANIC_PICK_UP_LEMON_H + +#include "titanic/game/pickup/pick_up.h" + +namespace Titanic { + +class CPickUpLemon : public CPickUp { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PICK_UP_LEMON_H */ diff --git a/engines/titanic/game/pickup/pick_up_speech_centre.cpp b/engines/titanic/game/pickup/pick_up_speech_centre.cpp new file mode 100644 index 0000000000..0b9a8d2c48 --- /dev/null +++ b/engines/titanic/game/pickup/pick_up_speech_centre.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/pickup/pick_up_speech_centre.h" + +namespace Titanic { + +void CPickUpSpeechCentre::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPickUp::save(file, indent); +} + +void CPickUpSpeechCentre::load(SimpleFile *file) { + file->readNumber(); + CPickUp::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pickup/pick_up_speech_centre.h b/engines/titanic/game/pickup/pick_up_speech_centre.h new file mode 100644 index 0000000000..29dce04fb3 --- /dev/null +++ b/engines/titanic/game/pickup/pick_up_speech_centre.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PICK_UP_SPEECH_CENTRE_H +#define TITANIC_PICK_UP_SPEECH_CENTRE_H + +#include "titanic/game/pickup/pick_up.h" + +namespace Titanic { + +class CPickUpSpeechCentre : public CPickUp { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PICK_UP_SPEECH_CENTRE_H */ diff --git a/engines/titanic/game/pickup/pick_up_vis_centre.cpp b/engines/titanic/game/pickup/pick_up_vis_centre.cpp new file mode 100644 index 0000000000..796e46778c --- /dev/null +++ b/engines/titanic/game/pickup/pick_up_vis_centre.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/pickup/pick_up_vis_centre.h" + +namespace Titanic { + +void CPickUpVisCentre::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPickUp::save(file, indent); +} + +void CPickUpVisCentre::load(SimpleFile *file) { + file->readNumber(); + CPickUp::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/pickup/pick_up_vis_centre.h b/engines/titanic/game/pickup/pick_up_vis_centre.h new file mode 100644 index 0000000000..4f808f73c5 --- /dev/null +++ b/engines/titanic/game/pickup/pick_up_vis_centre.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PICK_UP_VIS_CENTRE_H +#define TITANIC_PICK_UP_VIS_CENTRE_H + +#include "titanic/game/pickup/pick_up.h" + +namespace Titanic { + +class CPickUpVisCentre : public CPickUp { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PICK_UP_VIS_CENTRE_H */ diff --git a/engines/titanic/game/placeholder/bar_shelf_vis_centre.cpp b/engines/titanic/game/placeholder/bar_shelf_vis_centre.cpp new file mode 100644 index 0000000000..a8a33fe1b1 --- /dev/null +++ b/engines/titanic/game/placeholder/bar_shelf_vis_centre.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/placeholder/bar_shelf_vis_centre.h" + +namespace Titanic { + +void CBarShelfVisCentre::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CPlaceHolderItem::save(file, indent); +} + +void CBarShelfVisCentre::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CPlaceHolderItem::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/placeholder/bar_shelf_vis_centre.h b/engines/titanic/game/placeholder/bar_shelf_vis_centre.h new file mode 100644 index 0000000000..a53ef2633f --- /dev/null +++ b/engines/titanic/game/placeholder/bar_shelf_vis_centre.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_BAR_SHELF_VIS_CENTRE_H +#define TITANIC_BAR_SHELF_VIS_CENTRE_H + +#include "titanic/game/placeholder/place_holder_item.h" + +namespace Titanic { + +class CBarShelfVisCentre : public CPlaceHolderItem { +private: + int _value; +public: + CLASSDEF; + CBarShelfVisCentre() : CPlaceHolderItem(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BAR_SHELF_VIS_CENTRE_H */ diff --git a/engines/titanic/game/placeholder/lemon_on_bar.cpp b/engines/titanic/game/placeholder/lemon_on_bar.cpp new file mode 100644 index 0000000000..08d686e81a --- /dev/null +++ b/engines/titanic/game/placeholder/lemon_on_bar.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/placeholder/lemon_on_bar.h" + +namespace Titanic { + +void CLemonOnBar::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writePoint(_pos1, indent); + CPlaceHolderItem::save(file, indent); +} + +void CLemonOnBar::load(SimpleFile *file) { + file->readNumber(); + _pos1 = file->readPoint(); + CPlaceHolderItem::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/placeholder/lemon_on_bar.h b/engines/titanic/game/placeholder/lemon_on_bar.h new file mode 100644 index 0000000000..92dd54c49b --- /dev/null +++ b/engines/titanic/game/placeholder/lemon_on_bar.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_LEMON_ON_BAR_H +#define TITANIC_LEMON_ON_BAR_H + +#include "titanic/game/placeholder/place_holder_item.h" + +namespace Titanic { + +class CLemonOnBar : public CPlaceHolderItem { +private: + Point _pos1; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LEMON_ON_BAR_H */ diff --git a/engines/titanic/game/placeholder/place_holder_item.cpp b/engines/titanic/game/placeholder/place_holder_item.cpp new file mode 100644 index 0000000000..365e8cbe50 --- /dev/null +++ b/engines/titanic/game/placeholder/place_holder_item.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/placeholder/place_holder_item.h" + +namespace Titanic { + +void CPlaceHolderItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPlaceHolderItem::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/placeholder/place_holder_item.h b/engines/titanic/game/placeholder/place_holder_item.h new file mode 100644 index 0000000000..de04a64bf7 --- /dev/null +++ b/engines/titanic/game/placeholder/place_holder_item.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PLACE_HOLDER_H +#define TITANIC_PLACE_HOLDER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPlaceHolderItem : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PLACE_HOLDER_H */ diff --git a/engines/titanic/game/placeholder/tv_on_bar.cpp b/engines/titanic/game/placeholder/tv_on_bar.cpp new file mode 100644 index 0000000000..efbbe50461 --- /dev/null +++ b/engines/titanic/game/placeholder/tv_on_bar.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/placeholder/tv_on_bar.h" + +namespace Titanic { + +void CTVOnBar::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writePoint(_pos1, indent); + CPlaceHolderItem::save(file, indent); +} + +void CTVOnBar::load(SimpleFile *file) { + file->readNumber(); + _pos1 = file->readPoint(); + CPlaceHolderItem::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/placeholder/tv_on_bar.h b/engines/titanic/game/placeholder/tv_on_bar.h new file mode 100644 index 0000000000..d41d972e73 --- /dev/null +++ b/engines/titanic/game/placeholder/tv_on_bar.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_TV_ON_BAR_H +#define TITANIC_TV_ON_BAR_H + +#include "titanic/game/placeholder/place_holder_item.h" + +namespace Titanic { + +class CTVOnBar : public CPlaceHolderItem { +private: + Point _pos1; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TV_ON_BAR_H */ diff --git a/engines/titanic/game/play_music_button.cpp b/engines/titanic/game/play_music_button.cpp new file mode 100644 index 0000000000..8066739f10 --- /dev/null +++ b/engines/titanic/game/play_music_button.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/game/play_music_button.h" + +namespace Titanic { + +void CPlayMusicButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + + CBackground::save(file, indent); +} + +void CPlayMusicButton::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/play_music_button.h b/engines/titanic/game/play_music_button.h new file mode 100644 index 0000000000..4e3474181c --- /dev/null +++ b/engines/titanic/game/play_music_button.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_PLAY_MUSIC_BUTTON_H +#define TITANIC_PLAY_MUSIC_BUTTON_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CPlayMusicButton : public CBackground { +public: + int _fieldE0; + int _fieldE4; +public: + CLASSDEF; + CPlayMusicButton() : CBackground(), _fieldE0(0), _fieldE4(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PLAY_MUSIC_BUTTON_H */ diff --git a/engines/titanic/game/play_on_act.cpp b/engines/titanic/game/play_on_act.cpp new file mode 100644 index 0000000000..e1ef1201c6 --- /dev/null +++ b/engines/titanic/game/play_on_act.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/play_on_act.h" + +namespace Titanic { + +void CPlayOnAct::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CBackground::save(file, indent); +} + +void CPlayOnAct::load(SimpleFile *file) { + file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/play_on_act.h b/engines/titanic/game/play_on_act.h new file mode 100644 index 0000000000..197e647943 --- /dev/null +++ b/engines/titanic/game/play_on_act.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_PLAY_ON_ACT_H +#define TITANIC_PLAY_ON_ACT_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CPlayOnAct : public CBackground { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PLAY_ON_ACT_H */ diff --git a/engines/titanic/game/port_hole.cpp b/engines/titanic/game/port_hole.cpp new file mode 100644 index 0000000000..f3c447f443 --- /dev/null +++ b/engines/titanic/game/port_hole.cpp @@ -0,0 +1,49 @@ +/* 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 "titanic/game/port_hole.h" + +namespace Titanic { + +CPortHole::CPortHole() : CGameObject(), _fieldBC(0), + _string1("b#47.wav"), _string2("b#46.wav") { +} + +void CPortHole::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + + CGameObject::save(file, indent); +} + +void CPortHole::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/port_hole.h b/engines/titanic/game/port_hole.h new file mode 100644 index 0000000000..7bba18d12a --- /dev/null +++ b/engines/titanic/game/port_hole.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_PORT_HOLE_H +#define TITANIC_PORT_HOLE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPortHole : public CGameObject { +private: + int _fieldBC; + CString _string1, _string2; +public: + CLASSDEF; + CPortHole(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PORT_HOLE_H */ diff --git a/engines/titanic/game/record_phonograph_button.cpp b/engines/titanic/game/record_phonograph_button.cpp new file mode 100644 index 0000000000..f022957dbb --- /dev/null +++ b/engines/titanic/game/record_phonograph_button.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/record_phonograph_button.h" + +namespace Titanic { + +void CRecordPhonographButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CBackground::save(file, indent); +} + +void CRecordPhonographButton::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/record_phonograph_button.h b/engines/titanic/game/record_phonograph_button.h new file mode 100644 index 0000000000..3383c01e31 --- /dev/null +++ b/engines/titanic/game/record_phonograph_button.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_RECORD_PHONOGRAPH_BUTTON_H +#define TITANIC_RECORD_PHONOGRAPH_BUTTON_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CRecordPhonographButton : public CBackground { +public: + int _value; +public: + CLASSDEF; + CRecordPhonographButton() : CBackground(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_RECORD_PHONOGRAPH_BUTTON_H */ diff --git a/engines/titanic/game/replacement_ear.cpp b/engines/titanic/game/replacement_ear.cpp new file mode 100644 index 0000000000..1f9960365d --- /dev/null +++ b/engines/titanic/game/replacement_ear.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/replacement_ear.h" + +namespace Titanic { + +void CReplacementEar::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CBackground::save(file, indent); +} + +void CReplacementEar::load(SimpleFile *file) { + file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/replacement_ear.h b/engines/titanic/game/replacement_ear.h new file mode 100644 index 0000000000..0d282b7fb4 --- /dev/null +++ b/engines/titanic/game/replacement_ear.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_REPLACEMENT_EAR_H +#define TITANIC_REPLACEMENT_EAR_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CReplacementEar : public CBackground { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_REPLACEMENT_EAR_H */ diff --git a/engines/titanic/game/reserved_table.cpp b/engines/titanic/game/reserved_table.cpp new file mode 100644 index 0000000000..a600190709 --- /dev/null +++ b/engines/titanic/game/reserved_table.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/game/reserved_table.h" + +namespace Titanic { + +void CReservedTable::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value1, indent); + file->writeNumberLine(_value2, indent); + + CGameObject::save(file, indent); +} + +void CReservedTable::load(SimpleFile *file) { + file->readNumber(); + _value1 = file->readNumber(); + _value2 = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/reserved_table.h b/engines/titanic/game/reserved_table.h new file mode 100644 index 0000000000..a3532c7d14 --- /dev/null +++ b/engines/titanic/game/reserved_table.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_RESERVED_TABLE_H +#define TITANIC_RESERVED_TABLE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CReservedTable : public CGameObject { +public: + int _value1, _value2; +public: + CLASSDEF; + CReservedTable() : CGameObject(), _value1(0), _value2(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_RESERVED_TABLE_H */ diff --git a/engines/titanic/game/restaurant_cylinder_holder.cpp b/engines/titanic/game/restaurant_cylinder_holder.cpp new file mode 100644 index 0000000000..d70009f151 --- /dev/null +++ b/engines/titanic/game/restaurant_cylinder_holder.cpp @@ -0,0 +1,58 @@ +/* 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 "titanic/game/restaurant_cylinder_holder.h" + +namespace Titanic { + +CRestaurantCylinderHolder::CRestaurantCylinderHolder() : CDropTarget(), + _field118(0), _field11C(0), _field12C(0), _field130(0), + _string6("z#61.wav"), _field140(1) { +} + +void CRestaurantCylinderHolder::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field118, indent); + file->writeNumberLine(_field11C, indent); + file->writeQuotedLine(_string5, indent); + file->writeNumberLine(_field12C, indent); + file->writeNumberLine(_field130, indent); + file->writeQuotedLine(_string6, indent); + file->writeNumberLine(_field140, indent); + + CDropTarget::save(file, indent); +} + +void CRestaurantCylinderHolder::load(SimpleFile *file) { + file->readNumber(); + _field118 = file->readNumber(); + _field11C = file->readNumber(); + _string5 = file->readString(); + _field12C = file->readNumber(); + _field130 = file->readNumber(); + _string6 = file->readString(); + _field140 = file->readNumber(); + + CDropTarget::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/restaurant_cylinder_holder.h b/engines/titanic/game/restaurant_cylinder_holder.h new file mode 100644 index 0000000000..3aa979b0a5 --- /dev/null +++ b/engines/titanic/game/restaurant_cylinder_holder.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_RESTAURANT_CYLINDER_HOLDER_H +#define TITANIC_RESTAURANT_CYLINDER_HOLDER_H + +#include "titanic/core/drop_target.h" + +namespace Titanic { + +class CRestaurantCylinderHolder : public CDropTarget { +private: + int _field118; + int _field11C; + CString _string5; + int _field12C; + int _field130; + CString _string6; + int _field140; +public: + CLASSDEF; + CRestaurantCylinderHolder(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_RESTAURANT_CYLINDER_HOLDER_H */ diff --git a/engines/titanic/game/restaurant_phonograph.cpp b/engines/titanic/game/restaurant_phonograph.cpp new file mode 100644 index 0000000000..83a4ac3e71 --- /dev/null +++ b/engines/titanic/game/restaurant_phonograph.cpp @@ -0,0 +1,51 @@ +/* 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 "titanic/game/restaurant_phonograph.h" + +namespace Titanic { + +CRestaurantPhonograph::CRestaurantPhonograph() : CPhonograph(), + _fieldF8(1), _field114(0) {} + +void CRestaurantPhonograph::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeQuotedLine(_string2, indent); + file->writeQuotedLine(_string3, indent); + + file->writeNumberLine(_field114, indent); + + CPhonograph::save(file, indent); +} + +void CRestaurantPhonograph::load(SimpleFile *file) { + file->readNumber(); + _fieldF8 = file->readNumber(); + _string2 = file->readString(); + _string3 = file->readString(); + _field114 = file->readNumber(); + + CPhonograph::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/restaurant_phonograph.h b/engines/titanic/game/restaurant_phonograph.h new file mode 100644 index 0000000000..710a2edd73 --- /dev/null +++ b/engines/titanic/game/restaurant_phonograph.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_RESTAURANT_PHONOGRAPH_H +#define TITANIC_RESTAURANT_PHONOGRAPH_H + +#include "titanic/game/phonograph.h" + +namespace Titanic { + +class CRestaurantPhonograph : public CPhonograph { +private: + int _fieldF8; + CString _string2; + CString _string3; + int _field114; +public: + CLASSDEF; + CRestaurantPhonograph(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_RESTAURANT_PHONOGRAPH_H */ diff --git a/engines/titanic/game/sauce_dispensor.cpp b/engines/titanic/game/sauce_dispensor.cpp new file mode 100644 index 0000000000..8dc818d917 --- /dev/null +++ b/engines/titanic/game/sauce_dispensor.cpp @@ -0,0 +1,57 @@ +/* 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 "titanic/game/sauce_dispensor.h" + +namespace Titanic { + +CSauceDispensor::CSauceDispensor() : CBackground(), + _fieldEC(0), _fieldF0(0), _field104(0), _field108(0) { +} + +void CSauceDispensor::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string3, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_fieldF0, indent); + file->writePoint(_pos1, indent); + file->writePoint(_pos2, indent); + file->writeNumberLine(_field104, indent); + file->writeNumberLine(_field108, indent); + + CBackground::save(file, indent); +} + +void CSauceDispensor::load(SimpleFile *file) { + file->readNumber(); + _string3 = file->readString(); + _fieldEC = file->readNumber(); + _fieldF0 = file->readNumber(); + _pos1 = file->readPoint(); + _pos2 = file->readPoint(); + _field104 = file->readNumber(); + _field108 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sauce_dispensor.h b/engines/titanic/game/sauce_dispensor.h new file mode 100644 index 0000000000..aa177050d5 --- /dev/null +++ b/engines/titanic/game/sauce_dispensor.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_SAUCE_DISPENSOR_H +#define TITANIC_SAUCE_DISPENSOR_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CSauceDispensor : public CBackground { +public: + CString _string3; + int _fieldEC; + int _fieldF0; + Point _pos1; + Point _pos2; + int _field104; + int _field108; +public: + CLASSDEF; + CSauceDispensor(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SAUCE_DISPENSOR_H */ diff --git a/engines/titanic/game/search_point.cpp b/engines/titanic/game/search_point.cpp new file mode 100644 index 0000000000..f60a3132b7 --- /dev/null +++ b/engines/titanic/game/search_point.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/search_point.h" + +namespace Titanic { + +void CSearchPoint::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CSearchPoint::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/search_point.h b/engines/titanic/game/search_point.h new file mode 100644 index 0000000000..3c5639b104 --- /dev/null +++ b/engines/titanic/game/search_point.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_SEARCH_POINT_H +#define TITANIC_SEARCH_POINT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CSearchPoint : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CSearchPoint() : CGameObject(), _value(2) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SEARCH_POINT_H */ diff --git a/engines/titanic/game/season_background.cpp b/engines/titanic/game/season_background.cpp new file mode 100644 index 0000000000..1c63f3d892 --- /dev/null +++ b/engines/titanic/game/season_background.cpp @@ -0,0 +1,51 @@ +/* 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 "titanic/game/season_background.h" + +namespace Titanic { + +CSeasonBackground::CSeasonBackground() : CBackground(), + _fieldE0(0), _fieldE4(0), _fieldE8(46), _fieldEC(0) { +} + +void CSeasonBackground::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + + CBackground::save(file, indent); +} + +void CSeasonBackground::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/season_background.h b/engines/titanic/game/season_background.h new file mode 100644 index 0000000000..f0fd2cdc63 --- /dev/null +++ b/engines/titanic/game/season_background.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_SEASON_BACKGROUND_H +#define TITANIC_SEASON_BACKGROUND_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CSeasonBackground : public CBackground { +public: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; +public: + CLASSDEF; + CSeasonBackground(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SEASON_BACKGROUND_H */ diff --git a/engines/titanic/game/season_barrel.cpp b/engines/titanic/game/season_barrel.cpp new file mode 100644 index 0000000000..9594396885 --- /dev/null +++ b/engines/titanic/game/season_barrel.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/game/season_barrel.h" + +namespace Titanic { + +void CSeasonBarrel::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + + CBackground::save(file, indent); +} + +void CSeasonBarrel::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/season_barrel.h b/engines/titanic/game/season_barrel.h new file mode 100644 index 0000000000..f77864599d --- /dev/null +++ b/engines/titanic/game/season_barrel.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_SEASON_BARREL_H +#define TITANIC_SEASON_BARREL_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CSeasonBarrel : public CBackground { +public: + int _fieldE0; + int _fieldE4; +public: + CLASSDEF; + CSeasonBarrel() : CBackground(), _fieldE0(0), _fieldE4(7) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SEASON_BARREL_H */ diff --git a/engines/titanic/game/seasonal_adjustment.cpp b/engines/titanic/game/seasonal_adjustment.cpp new file mode 100644 index 0000000000..33a0ae89c5 --- /dev/null +++ b/engines/titanic/game/seasonal_adjustment.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/game/seasonal_adjustment.h" + +namespace Titanic { + +void CSeasonalAdjustment::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + + CBackground::save(file, indent); +} + +void CSeasonalAdjustment::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/seasonal_adjustment.h b/engines/titanic/game/seasonal_adjustment.h new file mode 100644 index 0000000000..39132d614d --- /dev/null +++ b/engines/titanic/game/seasonal_adjustment.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_SEASONAL_ADJUSTMENT_H +#define TITANIC_SEASONAL_ADJUSTMENT_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CSeasonalAdjustment : public CBackground { +public: + int _fieldE0; + int _fieldE4; +public: + CLASSDEF; + CSeasonalAdjustment() : CBackground(), _fieldE0(0), _fieldE4(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SEASONAL_ADJUSTMENT_H */ diff --git a/engines/titanic/game/service_elevator_window.cpp b/engines/titanic/game/service_elevator_window.cpp new file mode 100644 index 0000000000..95b2735b37 --- /dev/null +++ b/engines/titanic/game/service_elevator_window.cpp @@ -0,0 +1,51 @@ +/* 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 "titanic/game/service_elevator_window.h" + +namespace Titanic { + +CServiceElevatorWindow::CServiceElevatorWindow() : CBackground(), + _fieldE0(0), _fieldE4(0), _fieldE8(0), _fieldEC(0) { +} + +void CServiceElevatorWindow::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + + CBackground::save(file, indent); +} + +void CServiceElevatorWindow::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/service_elevator_window.h b/engines/titanic/game/service_elevator_window.h new file mode 100644 index 0000000000..4233b8405a --- /dev/null +++ b/engines/titanic/game/service_elevator_window.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_SERVICE_ELEVATOR_WINDOW_H +#define TITANIC_SERVICE_ELEVATOR_WINDOW_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CServiceElevatorWindow : public CBackground { +public: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; +public: + CLASSDEF; + CServiceElevatorWindow(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SERVICE_ELEVATOR_WINDOW_H */ diff --git a/engines/titanic/game/sgt/armchair.cpp b/engines/titanic/game/sgt/armchair.cpp new file mode 100644 index 0000000000..f547c3ef9a --- /dev/null +++ b/engines/titanic/game/sgt/armchair.cpp @@ -0,0 +1,87 @@ +/* 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 "titanic/game/sgt/armchair.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CArmchair, CSGTStateRoom) + ON_MESSAGE(TurnOn) + ON_MESSAGE(TurnOff) + ON_MESSAGE(MovieEndMsg) +END_MESSAGE_MAP() + +void CArmchair::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void CArmchair::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +bool CArmchair::TurnOn(CTurnOn *msg) { + if (_statics->_v8 == "Closed" && _statics->_v12 == "Closed") { + CVisibleMsg visibleMsg(false); + visibleMsg.execute("Deskchair"); + + if (_statics->_v9 == "Open") { + CActMsg actMsg("Squash"); + actMsg.execute("Deskchair"); + _startFrame = 22; + _endFrame = 31; + } else { + _startFrame = 0; + _endFrame = 10; + } + + playMovie(_startFrame, _endFrame, MOVIE_GAMESTATE); + playSound("b#0.wav"); + _statics->_v8 = "Open"; + _fieldE0 = 0; + } + + return true; +} + +bool CArmchair::TurnOff(CTurnOff *msg) { + if (_statics->_v8 == "Open") { + _statics->_v8 = "Closed"; + _startFrame = 11; + _endFrame = 21; + _fieldE0 = 1; + playMovie(11, 21, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT); + playSound("b#0.wav"); + } + + return true; +} + +bool CArmchair::MovieEndMsg(CMovieEndMsg *msg) { + if (_statics->_v8 == "Closed") + loadFrame(0); + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/armchair.h b/engines/titanic/game/sgt/armchair.h new file mode 100644 index 0000000000..169b9b4aa0 --- /dev/null +++ b/engines/titanic/game/sgt/armchair.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_ARMCHAIR_H +#define TITANIC_ARMCHAIR_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CArmchair : public CSGTStateRoom { + DECLARE_MESSAGE_MAP; + bool TurnOn(CTurnOn *msg); + bool TurnOff(CTurnOff *msg); + bool MovieEndMsg(CMovieEndMsg *msg); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ARMCHAIR_H */ diff --git a/engines/titanic/game/sgt/basin.cpp b/engines/titanic/game/sgt/basin.cpp new file mode 100644 index 0000000000..1eb1d161c9 --- /dev/null +++ b/engines/titanic/game/sgt/basin.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sgt/basin.h" + +namespace Titanic { + +void CBasin::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void CBasin::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/basin.h b/engines/titanic/game/sgt/basin.h new file mode 100644 index 0000000000..e4a36eb841 --- /dev/null +++ b/engines/titanic/game/sgt/basin.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_BASIN_H +#define TITANIC_BASIN_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CBasin : public CSGTStateRoom { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BASIN_H */ diff --git a/engines/titanic/game/sgt/bedfoot.cpp b/engines/titanic/game/sgt/bedfoot.cpp new file mode 100644 index 0000000000..18ea07aca0 --- /dev/null +++ b/engines/titanic/game/sgt/bedfoot.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sgt/bedfoot.h" + +namespace Titanic { + +void CBedfoot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void CBedfoot::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/bedfoot.h b/engines/titanic/game/sgt/bedfoot.h new file mode 100644 index 0000000000..df3db42d6d --- /dev/null +++ b/engines/titanic/game/sgt/bedfoot.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_BEDFOOT_H +#define TITANIC_BEDFOOT_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CBedfoot : public CSGTStateRoom { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BEDFOOT_H */ diff --git a/engines/titanic/game/sgt/bedhead.cpp b/engines/titanic/game/sgt/bedhead.cpp new file mode 100644 index 0000000000..fad7272f3a --- /dev/null +++ b/engines/titanic/game/sgt/bedhead.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sgt/bedhead.h" + +namespace Titanic { + +void CBedhead::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void CBedhead::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/bedhead.h b/engines/titanic/game/sgt/bedhead.h new file mode 100644 index 0000000000..f1ba31786c --- /dev/null +++ b/engines/titanic/game/sgt/bedhead.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_BEDHEAD_H +#define TITANIC_BEDHEAD_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CBedhead : public CSGTStateRoom { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BEDHEAD_H */ diff --git a/engines/titanic/game/sgt/chest_of_drawers.cpp b/engines/titanic/game/sgt/chest_of_drawers.cpp new file mode 100644 index 0000000000..be62e12c8e --- /dev/null +++ b/engines/titanic/game/sgt/chest_of_drawers.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sgt/chest_of_drawers.h" + +namespace Titanic { + +void CChestOfDrawers::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void CChestOfDrawers::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/chest_of_drawers.h b/engines/titanic/game/sgt/chest_of_drawers.h new file mode 100644 index 0000000000..16a1bf8fea --- /dev/null +++ b/engines/titanic/game/sgt/chest_of_drawers.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_CHEST_OF_DRAWERS_H +#define TITANIC_CHEST_OF_DRAWERS_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CChestOfDrawers : public CSGTStateRoom { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHEST_OF_DRAWERS_H */ diff --git a/engines/titanic/game/sgt/desk.cpp b/engines/titanic/game/sgt/desk.cpp new file mode 100644 index 0000000000..4dd0fdab92 --- /dev/null +++ b/engines/titanic/game/sgt/desk.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sgt/desk.h" + +namespace Titanic { + +void CDesk::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void CDesk::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/desk.h b/engines/titanic/game/sgt/desk.h new file mode 100644 index 0000000000..77b5fa17af --- /dev/null +++ b/engines/titanic/game/sgt/desk.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_DESK_H +#define TITANIC_DESK_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CDesk : public CSGTStateRoom { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DESK_H */ diff --git a/engines/titanic/game/sgt/deskchair.cpp b/engines/titanic/game/sgt/deskchair.cpp new file mode 100644 index 0000000000..a4a2badeb0 --- /dev/null +++ b/engines/titanic/game/sgt/deskchair.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sgt/deskchair.h" + +namespace Titanic { + +void CDeskchair::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void CDeskchair::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/deskchair.h b/engines/titanic/game/sgt/deskchair.h new file mode 100644 index 0000000000..5181b650d2 --- /dev/null +++ b/engines/titanic/game/sgt/deskchair.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_DESKCHAIR_H +#define TITANIC_DESKCHAIR_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CDeskchair : public CSGTStateRoom { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DESKCHAIR_H */ diff --git a/engines/titanic/game/sgt/drawer.cpp b/engines/titanic/game/sgt/drawer.cpp new file mode 100644 index 0000000000..03aa1b5358 --- /dev/null +++ b/engines/titanic/game/sgt/drawer.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/game/sgt/drawer.h" + +namespace Titanic { + +CDrawer::CDrawer() : CSGTStateRoom(), _fieldF4(0) { +} + +void CDrawer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldF4, indent); + CSGTStateRoom::save(file, indent); +} + +void CDrawer::load(SimpleFile *file) { + file->readNumber(); + _fieldF4 = file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/drawer.h b/engines/titanic/game/sgt/drawer.h new file mode 100644 index 0000000000..c079be389f --- /dev/null +++ b/engines/titanic/game/sgt/drawer.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_DRAWER_H +#define TITANIC_DRAWER_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CDrawer : public CSGTStateRoom { +private: + int _fieldF4; +public: + CLASSDEF; + CDrawer(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DRAWER_H */ diff --git a/engines/titanic/game/sgt/sgt_doors.cpp b/engines/titanic/game/sgt/sgt_doors.cpp new file mode 100644 index 0000000000..516b0f1351 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_doors.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/game/sgt/sgt_doors.h" + +namespace Titanic { + +void CSGTDoors::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value1, indent); + file->writeNumberLine(_value2, indent); + + CGameObject::save(file, indent); +} + +void CSGTDoors::load(SimpleFile *file) { + file->readNumber(); + _value1 = file->readNumber(); + _value2 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/sgt_doors.h b/engines/titanic/game/sgt/sgt_doors.h new file mode 100644 index 0000000000..4b4f4a3153 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_doors.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_SGT_DOORS_H +#define TITANIC_SGT_DOORS_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CSGTDoors : public CGameObject { +public: + int _value1, _value2; +public: + CLASSDEF; + CSGTDoors() : CGameObject(), _value1(0), _value2(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SGT_DOORS_H */ diff --git a/engines/titanic/game/sgt/sgt_nav.cpp b/engines/titanic/game/sgt/sgt_nav.cpp new file mode 100644 index 0000000000..f98e486fd0 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_nav.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sgt/sgt_nav.h" + +namespace Titanic { + +void SGTNav::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void SGTNav::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/sgt_nav.h b/engines/titanic/game/sgt/sgt_nav.h new file mode 100644 index 0000000000..40fdc4eff1 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_nav.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_SGT_NAV_H +#define TITANIC_SGT_NAV_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class SGTNav : public CSGTStateRoom { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SGT_NAV_H */ diff --git a/engines/titanic/game/sgt/sgt_navigation.cpp b/engines/titanic/game/sgt/sgt_navigation.cpp new file mode 100644 index 0000000000..d0c308457c --- /dev/null +++ b/engines/titanic/game/sgt/sgt_navigation.cpp @@ -0,0 +1,55 @@ +/* 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 "titanic/game/sgt/sgt_navigation.h" + +namespace Titanic { + +CSGTNavigationStatics *CSGTNavigation::_statics; + +void CSGTNavigation::init() { + _statics = new CSGTNavigationStatics(); +} + +void CSGTNavigation::deinit() { + delete _statics; +} + +void CSGTNavigation::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_statics->_v1, indent); + file->writeQuotedLine(_statics->_v2, indent); + file->writeQuotedLine(_statics->_v3, indent); + + CGameObject::save(file, indent); +} + +void CSGTNavigation::load(SimpleFile *file) { + file->readNumber(); + _statics->_v1 = file->readNumber(); + _statics->_v2 = file->readString(); + _statics->_v3 = file->readString(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/sgt_navigation.h b/engines/titanic/game/sgt/sgt_navigation.h new file mode 100644 index 0000000000..6d24fe6761 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_navigation.h @@ -0,0 +1,57 @@ +/* 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 TITANIC_SGT_NAVIGATION_H +#define TITANIC_SGT_NAVIGATION_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +struct CSGTNavigationStatics { + int _v1; + CString _v2; + CString _v3; +}; + +class CSGTNavigation : public CGameObject { +private: + static CSGTNavigationStatics *_statics; +public: + CLASSDEF; + static void init(); + static void deinit(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SGT_NAVIGATION_H */ diff --git a/engines/titanic/game/sgt/sgt_restaurant_doors.cpp b/engines/titanic/game/sgt/sgt_restaurant_doors.cpp new file mode 100644 index 0000000000..74a71e75b2 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_restaurant_doors.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/sgt/sgt_restaurant_doors.h" + +namespace Titanic { + +void CSGTRestaurantDoors::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + CGameObject::save(file, indent); +} + +void CSGTRestaurantDoors::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/sgt_restaurant_doors.h b/engines/titanic/game/sgt/sgt_restaurant_doors.h new file mode 100644 index 0000000000..2a10d8f059 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_restaurant_doors.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_SGT_RESTAURANT_DOORS_H +#define TITANIC_SGT_RESTAURANT_DOORS_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CSGTRestaurantDoors : public CGameObject { +private: + int _fieldBC; +public: + CLASSDEF; + CSGTRestaurantDoors() : CGameObject(), _fieldBC(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SGT_RESTAURANT_DOORS_H */ diff --git a/engines/titanic/game/sgt/sgt_state_control.cpp b/engines/titanic/game/sgt/sgt_state_control.cpp new file mode 100644 index 0000000000..07c1f5efc0 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_state_control.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/sgt/sgt_state_control.h" + +namespace Titanic { + +void CSGTStateControl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + CBackground::save(file, indent); +} + +void CSGTStateControl::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/sgt_state_control.h b/engines/titanic/game/sgt/sgt_state_control.h new file mode 100644 index 0000000000..49fd5113cd --- /dev/null +++ b/engines/titanic/game/sgt/sgt_state_control.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_SGT_STATE_CONTROL_H +#define TITANIC_SGT_STATE_CONTROL_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CSGTStateControl : public CBackground { +private: + int _fieldE0; +public: + CLASSDEF; + CSGTStateControl() : CBackground(), _fieldE0(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SGT_STATE_CONTROL_H */ diff --git a/engines/titanic/game/sgt/sgt_state_room.cpp b/engines/titanic/game/sgt/sgt_state_room.cpp new file mode 100644 index 0000000000..55f08de8b4 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_state_room.cpp @@ -0,0 +1,102 @@ +/* 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 "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CSGTStateRoom, CBackground) + ON_MESSAGE(EnterRoomMsg) +END_MESSAGE_MAP() + +CSGTStateRoomStatics *CSGTStateRoom::_statics; + +void CSGTStateRoom::init() { + _statics = new CSGTStateRoomStatics(); +} + +void CSGTStateRoom::deinit() { + delete _statics; +} + +CSGTStateRoom::CSGTStateRoom() : CBackground(), _fieldE0(1), + _fieldE4(1), _fieldE8(0), _fieldEC(1), _fieldF0(1) { +} + +void CSGTStateRoom::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_statics->_v1, indent); + file->writeQuotedLine(_statics->_v2, indent); + file->writeQuotedLine(_statics->_v3, indent); + file->writeQuotedLine(_statics->_v4, indent); + file->writeQuotedLine(_statics->_v5, indent); + file->writeQuotedLine(_statics->_v6, indent); + file->writeQuotedLine(_statics->_v7, indent); + file->writeQuotedLine(_statics->_v8, indent); + file->writeQuotedLine(_statics->_v9, indent); + file->writeQuotedLine(_statics->_v10, indent); + file->writeQuotedLine(_statics->_v11, indent); + file->writeQuotedLine(_statics->_v12, indent); + + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_statics->_v13, indent); + file->writeNumberLine(_statics->_v14, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_fieldF0, indent); + + CBackground::save(file, indent); +} + +void CSGTStateRoom::load(SimpleFile *file) { + file->readNumber(); + _statics->_v1 = file->readString(); + _statics->_v2 = file->readString(); + _statics->_v3 = file->readString(); + _statics->_v4 = file->readString(); + _statics->_v5 = file->readString(); + _statics->_v6 = file->readString(); + _statics->_v7 = file->readString(); + _statics->_v8 = file->readString(); + _statics->_v9 = file->readString(); + _statics->_v10 = file->readString(); + _statics->_v11 = file->readString(); + _statics->_v12 = file->readString(); + + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _statics->_v13 = file->readNumber(); + _statics->_v14 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + _fieldF0 = file->readNumber(); + + CBackground::load(file); +} + +bool CSGTStateRoom::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CSGTStateRoom::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/sgt_state_room.h b/engines/titanic/game/sgt/sgt_state_room.h new file mode 100644 index 0000000000..d9ffdb8e9e --- /dev/null +++ b/engines/titanic/game/sgt/sgt_state_room.h @@ -0,0 +1,78 @@ +/* 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 TITANIC_SGT_STATE_ROOM_H +#define TITANIC_SGT_STATE_ROOM_H + +#include "titanic/core/background.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +struct CSGTStateRoomStatics { + CString _v1; + CString _v2; + CString _v3; + CString _v4; + CString _v5; + CString _v6; + CString _v7; + CString _v8; + CString _v9; + CString _v10; + CString _v11; + CString _v12; + int _v13; + int _v14; +}; + +class CSGTStateRoom : public CBackground { + DECLARE_MESSAGE_MAP; + bool EnterRoomMsg(CEnterRoomMsg *msg); +protected: + static CSGTStateRoomStatics *_statics; +protected: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; + int _fieldF0; +public: + CLASSDEF; + CSGTStateRoom(); + static void init(); + static void deinit(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SGT_STATE_ROOM_H */ diff --git a/engines/titanic/game/sgt/sgt_tv.cpp b/engines/titanic/game/sgt/sgt_tv.cpp new file mode 100644 index 0000000000..ae4c59e2f9 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_tv.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sgt/sgt_tv.h" + +namespace Titanic { + +void CSGTTV::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void CSGTTV::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/sgt_tv.h b/engines/titanic/game/sgt/sgt_tv.h new file mode 100644 index 0000000000..90fed90efe --- /dev/null +++ b/engines/titanic/game/sgt/sgt_tv.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_SGT_TV_H +#define TITANIC_SGT_TV_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CSGTTV : public CSGTStateRoom { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SGT_TV_H */ diff --git a/engines/titanic/game/sgt/sgt_upper_doors_sound.cpp b/engines/titanic/game/sgt/sgt_upper_doors_sound.cpp new file mode 100644 index 0000000000..ed37b0a5c7 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_upper_doors_sound.cpp @@ -0,0 +1,45 @@ +/* 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 "titanic/game/sgt/sgt_upper_doors_sound.h" + +namespace Titanic { + +CSGTUpperDoorsSound::CSGTUpperDoorsSound() { + _string2 = "b#53.wav"; +} + +void CSGTUpperDoorsSound::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string2, indent); + + CClickResponder::save(file, indent); +} + +void CSGTUpperDoorsSound::load(SimpleFile *file) { + file->readNumber(); + _string2 = file->readString(); + + CClickResponder::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/sgt_upper_doors_sound.h b/engines/titanic/game/sgt/sgt_upper_doors_sound.h new file mode 100644 index 0000000000..fc8c6c2bf1 --- /dev/null +++ b/engines/titanic/game/sgt/sgt_upper_doors_sound.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_SGT_UPPER_DOORS_SOUND_H +#define TITANIC_SGT_UPPER_DOORS_SOUND_H + +#include "titanic/core/click_responder.h" + +namespace Titanic { + +class CSGTUpperDoorsSound : public CClickResponder { +public: + CLASSDEF; + CSGTUpperDoorsSound(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SGT_UPPER_DOORS_SOUND_H */ diff --git a/engines/titanic/game/sgt/toilet.cpp b/engines/titanic/game/sgt/toilet.cpp new file mode 100644 index 0000000000..799abd6c76 --- /dev/null +++ b/engines/titanic/game/sgt/toilet.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sgt/toilet.h" + +namespace Titanic { + +void CToilet::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void CToilet::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/toilet.h b/engines/titanic/game/sgt/toilet.h new file mode 100644 index 0000000000..d87531ad7a --- /dev/null +++ b/engines/titanic/game/sgt/toilet.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_TOILET_H +#define TITANIC_TOILET_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CToilet : public CSGTStateRoom { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TOILET_H */ diff --git a/engines/titanic/game/sgt/vase.cpp b/engines/titanic/game/sgt/vase.cpp new file mode 100644 index 0000000000..3e04b5db9e --- /dev/null +++ b/engines/titanic/game/sgt/vase.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sgt/vase.h" + +namespace Titanic { + +void CVase::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void CVase::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/vase.h b/engines/titanic/game/sgt/vase.h new file mode 100644 index 0000000000..8aa35acdf5 --- /dev/null +++ b/engines/titanic/game/sgt/vase.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_VASE_H +#define TITANIC_VASE_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CVase : public CSGTStateRoom { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_VASE_H */ diff --git a/engines/titanic/game/sgt/washstand.cpp b/engines/titanic/game/sgt/washstand.cpp new file mode 100644 index 0000000000..8127a59a59 --- /dev/null +++ b/engines/titanic/game/sgt/washstand.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sgt/washstand.h" + +namespace Titanic { + +void CWashstand::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSGTStateRoom::save(file, indent); +} + +void CWashstand::load(SimpleFile *file) { + file->readNumber(); + CSGTStateRoom::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sgt/washstand.h b/engines/titanic/game/sgt/washstand.h new file mode 100644 index 0000000000..f140b17f49 --- /dev/null +++ b/engines/titanic/game/sgt/washstand.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_WASHSTAND_H +#define TITANIC_WASHSTAND_H + +#include "titanic/game/sgt/sgt_state_room.h" + +namespace Titanic { + +class CWashstand : public CSGTStateRoom { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_WASHSTAND_H */ diff --git a/engines/titanic/game/ship_setting.cpp b/engines/titanic/game/ship_setting.cpp new file mode 100644 index 0000000000..462f396501 --- /dev/null +++ b/engines/titanic/game/ship_setting.cpp @@ -0,0 +1,56 @@ +/* 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 "titanic/game/ship_setting.h" + +namespace Titanic { + +CShipSetting::CShipSetting() : CBackground(), + _string4("NULL"), _string5("NULL") { +} + +void CShipSetting::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string3, indent); + file->writePoint(_pos1, indent); + file->writeQuotedLine(_string4, indent); + file->writeQuotedLine(_string5, indent); + + CBackground::save(file, indent); +} + +void CShipSetting::load(SimpleFile *file) { + file->readNumber(); + _string3 = file->readString(); + _pos1 = file->readPoint(); + _string4 = file->readString(); + _string5 = file->readString(); + + CBackground::load(file); +} + +bool CShipSetting::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CShipSetting::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/ship_setting.h b/engines/titanic/game/ship_setting.h new file mode 100644 index 0000000000..4fcc10a424 --- /dev/null +++ b/engines/titanic/game/ship_setting.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_SHIP_SETTING_H +#define TITANIC_SHIP_SETTING_H + +#include "titanic/core/background.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CShipSetting : public CBackground { + bool EnterRoomMsg(CEnterRoomMsg *msg); +public: + CString _string3; + Point _pos1; + CString _string4; + CString _string5; +public: + CLASSDEF; + CShipSetting(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SHIP_SETTING_H */ diff --git a/engines/titanic/game/ship_setting_button.cpp b/engines/titanic/game/ship_setting_button.cpp new file mode 100644 index 0000000000..7dc2cabac0 --- /dev/null +++ b/engines/titanic/game/ship_setting_button.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/game/ship_setting_button.h" + +namespace Titanic { + +CShipSettingButton::CShipSettingButton() : CGameObject(), _fieldC8(0), _fieldCC(0) { +} + +void CShipSettingButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeNumberLine(_fieldCC, indent); + + CGameObject::save(file, indent); +} + +void CShipSettingButton::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + _fieldC8 = file->readNumber(); + _fieldCC = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/ship_setting_button.h b/engines/titanic/game/ship_setting_button.h new file mode 100644 index 0000000000..e152e8e2c3 --- /dev/null +++ b/engines/titanic/game/ship_setting_button.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_SHIP_SETTING_BUTTON_H +#define TITANIC_SHIP_SETTING_BUTTON_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CShipSettingButton : public CGameObject { +private: + CString _string1; + int _fieldC8; + int _fieldCC; +public: + CLASSDEF; + CShipSettingButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SHIP_SETTING_BUTTON_H */ diff --git a/engines/titanic/game/show_cell_points.cpp b/engines/titanic/game/show_cell_points.cpp new file mode 100644 index 0000000000..7d54401a02 --- /dev/null +++ b/engines/titanic/game/show_cell_points.cpp @@ -0,0 +1,41 @@ +/* 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 "titanic/game/show_cell_points.h" + +namespace Titanic { + +void CShowCellpoints::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_strValue, indent); + file->writeNumberLine(_numValue, indent); + CGameObject::save(file, indent); +} + +void CShowCellpoints::load(SimpleFile *file) { + file->readNumber(); + _strValue = file->readString(); + _numValue = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/show_cell_points.h b/engines/titanic/game/show_cell_points.h new file mode 100644 index 0000000000..9de2e06dca --- /dev/null +++ b/engines/titanic/game/show_cell_points.h @@ -0,0 +1,51 @@ +/* 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 SHOW_CELL_POINTS_H +#define SHOW_CELL_POINTS_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CShowCellpoints : public CGameObject { +public: + CString _strValue; + int _numValue; +public: + CLASSDEF; + CShowCellpoints() : CGameObject(), _numValue(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* SHOW_CELL_POINTS_H */ diff --git a/engines/titanic/game/speech_dispensor.cpp b/engines/titanic/game/speech_dispensor.cpp new file mode 100644 index 0000000000..f9cc019672 --- /dev/null +++ b/engines/titanic/game/speech_dispensor.cpp @@ -0,0 +1,53 @@ +/* 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 "titanic/game/speech_dispensor.h" + +namespace Titanic { + +void CSpeechDispensor::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_fieldF0, indent); + file->writeNumberLine(_fieldF4, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_fieldFC, indent); + + CBackground::save(file, indent); +} + +void CSpeechDispensor::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldEC = file->readNumber(); + _fieldF0 = file->readNumber(); + _fieldF4 = file->readNumber(); + _fieldF8 = file->readNumber(); + _fieldFC = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/speech_dispensor.h b/engines/titanic/game/speech_dispensor.h new file mode 100644 index 0000000000..3b877e8d99 --- /dev/null +++ b/engines/titanic/game/speech_dispensor.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_SPEECH_DISPENSOR_H +#define TITANIC_SPEECH_DISPENSOR_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CSpeechDispensor : public CBackground { +private: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; + int _fieldF0; + int _fieldF4; + int _fieldF8; + int _fieldFC; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SPEECH_DISPENSOR_H */ diff --git a/engines/titanic/game/splash_animation.cpp b/engines/titanic/game/splash_animation.cpp new file mode 100644 index 0000000000..2094ec14fa --- /dev/null +++ b/engines/titanic/game/splash_animation.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/splash_animation.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CSplashAnimation, CGameObject); + +void CSplashAnimation::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CSplashAnimation::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/splash_animation.h b/engines/titanic/game/splash_animation.h new file mode 100644 index 0000000000..11715b4d73 --- /dev/null +++ b/engines/titanic/game/splash_animation.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_SPLASH_ANIMATION_H +#define TITANIC_SPLASH_ANIMATION_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CSplashAnimation : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SPLASH_ANIMATION_H */ diff --git a/engines/titanic/game/starling_puret.cpp b/engines/titanic/game/starling_puret.cpp new file mode 100644 index 0000000000..359ad774df --- /dev/null +++ b/engines/titanic/game/starling_puret.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/starling_puret.h" + +namespace Titanic { + +void CStarlingPuret::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CStarlingPuret::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/starling_puret.h b/engines/titanic/game/starling_puret.h new file mode 100644 index 0000000000..fcd3319958 --- /dev/null +++ b/engines/titanic/game/starling_puret.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_STARLING_PURET_H +#define TITANIC_STARLING_PURET_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CStarlingPuret : public CGameObject { +private: + int _value; +public: + CLASSDEF; + CStarlingPuret() : CGameObject(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STARLING_PURET_H */ diff --git a/engines/titanic/game/start_action.cpp b/engines/titanic/game/start_action.cpp new file mode 100644 index 0000000000..ab356ea1f4 --- /dev/null +++ b/engines/titanic/game/start_action.cpp @@ -0,0 +1,64 @@ +/* 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 "titanic/game/start_action.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CStartAction, CBackground) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(MouseButtonUpMsg) +END_MESSAGE_MAP() + +CStartAction::CStartAction() : CBackground() { +} + +void CStartAction::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_msgTarget, indent); + file->writeQuotedLine(_msgAction, indent); + + CBackground::save(file, indent); +} + +void CStartAction::load(SimpleFile *file) { + file->readNumber(); + _msgTarget = file->readString(); + _msgAction = file->readString(); + + CBackground::load(file); +} + +bool CStartAction::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + // Dispatch the desired action to the desired target + CActMsg actMsg(_msgAction); + actMsg.execute(_msgTarget); + + return true; +} + +bool CStartAction::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/start_action.h b/engines/titanic/game/start_action.h new file mode 100644 index 0000000000..60381bad2f --- /dev/null +++ b/engines/titanic/game/start_action.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_START_ACTION_H +#define TITANIC_START_ACTION_H + +#include "titanic/core/background.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +class CStartAction : public CBackground { + DECLARE_MESSAGE_MAP; + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); +protected: + CString _msgTarget; + CString _msgAction; +public: + CLASSDEF; + CStartAction(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_START_ACTION_H */ diff --git a/engines/titanic/game/stop_phonograph_button.cpp b/engines/titanic/game/stop_phonograph_button.cpp new file mode 100644 index 0000000000..d18f4713ac --- /dev/null +++ b/engines/titanic/game/stop_phonograph_button.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/stop_phonograph_button.h" + +namespace Titanic { + +void CStopPhonographButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CBackground::save(file, indent); +} + +void CStopPhonographButton::load(SimpleFile *file) { + file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/stop_phonograph_button.h b/engines/titanic/game/stop_phonograph_button.h new file mode 100644 index 0000000000..b469375e20 --- /dev/null +++ b/engines/titanic/game/stop_phonograph_button.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_STOP_PHONOGRAPH_BUTTON_H +#define TITANIC_STOP_PHONOGRAPH_BUTTON_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CStopPhonographButton : public CBackground { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STOP_PHONOGRAPH_BUTTON_H */ diff --git a/engines/titanic/game/sub_glass.cpp b/engines/titanic/game/sub_glass.cpp new file mode 100644 index 0000000000..f1349f06ea --- /dev/null +++ b/engines/titanic/game/sub_glass.cpp @@ -0,0 +1,54 @@ +/* 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 "titanic/game/sub_glass.h" + +namespace Titanic { + +CSUBGlass::CSUBGlass() : _fieldBC(0), _fieldC0(0), _fieldC4(1), _fieldC8(0) { +} + +void CSUBGlass::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeNumberLine(_fieldCC, indent); + file->writeQuotedLine(_string, indent); + + CGameObject::save(file, indent); +} + +void CSUBGlass::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + _fieldC8 = file->readNumber(); + _fieldCC = file->readNumber(); + _string = file->readString(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sub_glass.h b/engines/titanic/game/sub_glass.h new file mode 100644 index 0000000000..aab5c8400e --- /dev/null +++ b/engines/titanic/game/sub_glass.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_SUB_GLASS_H +#define TITANIC_SUB_GLASS_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CSUBGlass : public CGameObject { +private: + int _fieldBC; + int _fieldC0; + int _fieldC4; + int _fieldC8; + int _fieldCC; + CString _string; +public: + CLASSDEF; + CSUBGlass(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ROOM_ITEM_H */ diff --git a/engines/titanic/game/sub_wrapper.cpp b/engines/titanic/game/sub_wrapper.cpp new file mode 100644 index 0000000000..dcc489316b --- /dev/null +++ b/engines/titanic/game/sub_wrapper.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/sub_wrapper.h" + +namespace Titanic { + +void CSUBWrapper::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CSUBWrapper::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sub_wrapper.h b/engines/titanic/game/sub_wrapper.h new file mode 100644 index 0000000000..81f8fdc941 --- /dev/null +++ b/engines/titanic/game/sub_wrapper.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_SUB_WRAPPER_H +#define TITANIC_SUB_WRAPPER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CSUBWrapper : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CSUBWrapper() : CGameObject(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SUB_WRAPPER_H */ diff --git a/engines/titanic/game/sweet_bowl.cpp b/engines/titanic/game/sweet_bowl.cpp new file mode 100644 index 0000000000..e14f900e77 --- /dev/null +++ b/engines/titanic/game/sweet_bowl.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/sweet_bowl.h" + +namespace Titanic { + +void CSweetBowl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CSweetBowl::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/sweet_bowl.h b/engines/titanic/game/sweet_bowl.h new file mode 100644 index 0000000000..cf3d0023a4 --- /dev/null +++ b/engines/titanic/game/sweet_bowl.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_SWEET_BOWL_H +#define TITANIC_SWEET_BOWL_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CSweetBowl : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CREDITS_H */ diff --git a/engines/titanic/game/television.cpp b/engines/titanic/game/television.cpp new file mode 100644 index 0000000000..af6bdb8c03 --- /dev/null +++ b/engines/titanic/game/television.cpp @@ -0,0 +1,291 @@ +/* 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 "titanic/titanic.h" +#include "titanic/game/television.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/game/get_lift_eye2.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CTelevision, CGameObject) + ON_MESSAGE(LeaveViewMsg) + ON_MESSAGE(ChangeSeasonMsg) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(PETUpMsg) + ON_MESSAGE(PETDownMsg) + ON_MESSAGE(StatusChangeMsg) + ON_MESSAGE(ActMsg) + ON_MESSAGE(PETActivateMsg) + ON_MESSAGE(MovieEndMsg) + ON_MESSAGE(ShipSettingMsg) + ON_MESSAGE(TurnOff) + ON_MESSAGE(TurnOn) + ON_MESSAGE(LightsMsg) +END_MESSAGE_MAP() + +int CTelevision::_v1; +bool CTelevision::_turnOn; +int CTelevision::_v3; +int CTelevision::_v4; +int CTelevision::_v5; +int CTelevision::_v6; + +CTelevision::CTelevision() : CBackground(), _fieldE0(1), + _fieldE4(7), _isOn(false), _fieldEC(0), _soundHandle(0) { +} + +void CTelevision::init() { + _v1 = 531; + _turnOn = true; + _v3 = 0; + _v4 = 27; + _v5 = 1; + _v6 = 1; +} + +void CTelevision::deinit() { +} + +void CTelevision::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_turnOn, indent); + file->writeNumberLine(_isOn, indent); + file->writeNumberLine(_v3, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_v4, indent); + file->writeNumberLine(_soundHandle, indent); + file->writeNumberLine(_v5, indent); + file->writeNumberLine(_v6, indent); + + CBackground::save(file, indent); +} + +void CTelevision::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _v1 = file->readNumber(); + _fieldE4 = file->readNumber(); + _turnOn = file->readNumber() != 0; + _isOn = file->readNumber() != 0; + _v3 = file->readNumber(); + _fieldEC = file->readNumber(); + _v4 = file->readNumber(); + _soundHandle = file->readNumber(); + _v5 = file->readNumber(); + _v6 = file->readNumber(); + + CBackground::load(file); +} + +bool CTelevision::LeaveViewMsg(CLeaveViewMsg *msg) { + petClear(); + if (_isOn) { + if (isSoundActive(_soundHandle)) + stopSound(_soundHandle, 0); + + loadFrame(622); + stopMovie(); + setVisible(0); + _isOn = false; + + if (compareRoomNameTo("CSGState")) { + CVisibleMsg visibleMsg(true); + visibleMsg.execute("Tellypic"); + } + } + + return true; +} + +bool CTelevision::ChangeSeasonMsg(CChangeSeasonMsg *msg) { + if (msg->_season.compareTo("Autumn")) { + _v1 = 545; + _v3 = 0; + } else if (msg->_season.compareTo("Winter")) { + _v1 = 503; + _v3 = 0; + } else if (msg->_season.compareTo("Spring")) { + _v1 = 517; + _v3 = 0; + } else if (msg->_season.compareTo("Winter")) { + _v1 = 531; + _v3 = 0; + } + + return true; +} + +bool CTelevision::EnterViewMsg(CEnterViewMsg *msg) { + petSetArea(PET_REMOTE); + petHighlightGlyph(GLYPH_TELEVISION_CONTROL); + petSetRemoteTarget(); + setVisible(0); + _fieldE0 = 1; + + return true; +} + +static const int START_FRAMES[9] = { 0, 0, 56, 112, 168, 224, 280, 336, 392 }; +static const int END_FRAMES[8] = { 0, 55, 111, 167, 223, 279, 335, 391 }; + +bool CTelevision::PETUpMsg(CPETUpMsg *msg) { + if (msg->_name == "Television" && _isOn) { + if (isSoundActive(_soundHandle)) + stopSound(_soundHandle, 0); + + _fieldE0 = _fieldE0 % _fieldE4 + 1; + stopMovie(); + playMovie(START_FRAMES[_fieldE0], END_FRAMES[_fieldE0], 4); + } + + return true; +} + +bool CTelevision::PETDownMsg(CPETDownMsg *msg) { + if (msg->_name == "Television" && _isOn) { + if (isSoundActive(_soundHandle)) + stopSound(_soundHandle, 0); + if (--_fieldE0 < 1) + _fieldE0 += _fieldE4; + + _fieldE0 = _fieldE0 % _fieldE4 + 1; + stopMovie(); + playMovie(START_FRAMES[_fieldE0], END_FRAMES[_fieldE0], 4); + } + + return true; +} + +bool CTelevision::StatusChangeMsg(CStatusChangeMsg *msg) { + if (_isOn) { + stopMovie(); + playMovie(0); + } + + return true; +} + +bool CTelevision::ActMsg(CActMsg *msg) { + if (msg->_action == "TurnTVOnOff") { + _isOn = !_isOn; + if (_isOn) { + setVisible(true); + CStatusChangeMsg changeMsg; + changeMsg.execute(this); + } else { + setVisible(_isOn); + stopMovie(); + } + } + + return true; +} + +bool CTelevision::PETActivateMsg(CPETActivateMsg *msg) { + if (msg->_name == "Television") { + CVisibleMsg visibleMsg(_isOn); + _isOn = !_isOn; + + if (_isOn) { + setVisible(true); + playMovie(0, 55, 0); + _fieldE0 = 1; + } else { + stopMovie(); + if (isSoundActive(_soundHandle)) + stopSound(_soundHandle, 0); + + setVisible(false); + } + + if (compareRoomNameTo("SGTState")) + visibleMsg.execute("Tellypic"); + } + + return true; +} + +bool CTelevision::MovieEndMsg(CMovieEndMsg *msg) { + if (g_vm->getRandomNumber(6) == 0) { + CParrotSpeakMsg parrotMsg("Television", ""); + parrotMsg.execute("PerchedParrot"); + } + + if (_fieldE0 == 3 && compareRoomNameTo("SGTState") && !getPassengerClass()) { + playSound("z#47.wav", 100, 0, 0); + _soundHandle = playSound("b#20.wav", 100, 0, 0); + CTreeItem *magazine = getRoot()->findByName("Magazine"); + + if (magazine) { + warning("TODO: CTelevision::MovieEndMsg"); + } + + loadFrame(561); + } else if (_fieldE0 == 2) { + loadFrame(_v1); + } else if (_fieldE0 == 4 && _v5) { + if (_turnOn) + loadFrame(502); + else + warning("There is currently nothing available for your viewing pleasure on this channel."); + } else if (_fieldE0 == 5 && *CGetLiftEye2::_v1 != "NULL") { + loadFrame(393 + _v4); + } else { + warning("There is currently nothing available for your viewing pleasure on this channel."); + } + + return true; +} + +bool CTelevision::ShipSettingMsg(CShipSettingMsg *msg) { + _v4 = msg->_value; + return true; +} + +bool CTelevision::TurnOff(CTurnOff *msg) { + _turnOn = false; + return true; +} + +bool CTelevision::TurnOn(CTurnOn *msg) { + _turnOn = true; + return true; +} + +bool CTelevision::LightsMsg(CLightsMsg *msg) { + CPetControl *pet = getPetControl(); + bool flag = false; + + if (pet) + flag = pet->isRoom59706(); + + if (msg->_field8 || !flag) + _turnOn = true; + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/television.h b/engines/titanic/game/television.h new file mode 100644 index 0000000000..6e6d9b23c2 --- /dev/null +++ b/engines/titanic/game/television.h @@ -0,0 +1,79 @@ +/* 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 TITANIC_TELEVISION_H +#define TITANIC_TELEVISION_H + +#include "titanic/core/background.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/pet_messages.h" + +namespace Titanic { + +class CTelevision : public CBackground { + DECLARE_MESSAGE_MAP; + bool LeaveViewMsg(CLeaveViewMsg *msg); + bool ChangeSeasonMsg(CChangeSeasonMsg *msg); + bool EnterViewMsg(CEnterViewMsg *msg); + bool PETUpMsg(CPETUpMsg *msg); + bool PETDownMsg(CPETDownMsg *msg); + bool StatusChangeMsg(CStatusChangeMsg *msg); + bool ActMsg(CActMsg *msg); + bool PETActivateMsg(CPETActivateMsg *msg); + bool MovieEndMsg(CMovieEndMsg *msg); + bool ShipSettingMsg(CShipSettingMsg *msg); + bool TurnOff(CTurnOff *msg); + bool TurnOn(CTurnOn *msg); + bool LightsMsg(CLightsMsg *msg); +private: + static int _v1; + static bool _turnOn; + static int _v3; + static int _v4; + static int _v5; + static int _v6; +private: + int _fieldE0; + int _fieldE4; + bool _isOn; + int _fieldEC; + int _soundHandle; +public: + CLASSDEF; + CTelevision(); + static void init(); + static void deinit(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TELEVISION_H */ diff --git a/engines/titanic/game/third_class_canal.cpp b/engines/titanic/game/third_class_canal.cpp new file mode 100644 index 0000000000..6b0a101f7b --- /dev/null +++ b/engines/titanic/game/third_class_canal.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/third_class_canal.h" + +namespace Titanic { + +void CThirdClassCanal::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CBackground::save(file, indent); +} + +void CThirdClassCanal::load(SimpleFile *file) { + file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/third_class_canal.h b/engines/titanic/game/third_class_canal.h new file mode 100644 index 0000000000..f6fc471444 --- /dev/null +++ b/engines/titanic/game/third_class_canal.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_THIRD_CLASS_CANAL_H +#define TITANIC_THIRD_CLASS_CANAL_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CThirdClassCanal : public CBackground { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_THIRD_CLASS_CANAL_H */ diff --git a/engines/titanic/game/throw_tv_down_well.cpp b/engines/titanic/game/throw_tv_down_well.cpp new file mode 100644 index 0000000000..c8a9fc7c9e --- /dev/null +++ b/engines/titanic/game/throw_tv_down_well.cpp @@ -0,0 +1,41 @@ +/* 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 "titanic/game/throw_tv_down_well.h" + +namespace Titanic { + +void CThrowTVDownWell::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_strValue, indent); + file->writeNumberLine(_numValue, indent); + CGameObject::save(file, indent); +} + +void CThrowTVDownWell::load(SimpleFile *file) { + file->readNumber(); + _strValue = file->readString(); + _numValue = file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/throw_tv_down_well.h b/engines/titanic/game/throw_tv_down_well.h new file mode 100644 index 0000000000..b6003aa3ef --- /dev/null +++ b/engines/titanic/game/throw_tv_down_well.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_THROW_TV_DOWN_WELL_H +#define TITANIC_THROW_TV_DOWN_WELL_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CThrowTVDownWell : public CGameObject { +public: + CString _strValue; + int _numValue; +public: + CLASSDEF; + CThrowTVDownWell() : CGameObject(), _numValue(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_THROW_TV_DOWN_WELL_H */ diff --git a/engines/titanic/game/titania_still_control.cpp b/engines/titanic/game/titania_still_control.cpp new file mode 100644 index 0000000000..67866ecdcb --- /dev/null +++ b/engines/titanic/game/titania_still_control.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/titania_still_control.h" + +namespace Titanic { + +void CTitaniaStillControl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CTitaniaStillControl::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/titania_still_control.h b/engines/titanic/game/titania_still_control.h new file mode 100644 index 0000000000..66c3045187 --- /dev/null +++ b/engines/titanic/game/titania_still_control.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_TITANIA_STILL_CONTROL_H +#define TITANIC_TITANIA_STILL_CONTROL_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CTitaniaStillControl : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TITANIA_STILL_CONTROL_H */ diff --git a/engines/titanic/game/tow_parrot_nav.cpp b/engines/titanic/game/tow_parrot_nav.cpp new file mode 100644 index 0000000000..9361808870 --- /dev/null +++ b/engines/titanic/game/tow_parrot_nav.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/tow_parrot_nav.h" + +namespace Titanic { + +void CTOWParrotNav::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CTOWParrotNav::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/tow_parrot_nav.h b/engines/titanic/game/tow_parrot_nav.h new file mode 100644 index 0000000000..17618ff6de --- /dev/null +++ b/engines/titanic/game/tow_parrot_nav.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_TOW_PARROT_NAV_H +#define TITANIC_TOW_PARROT_NAV_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CTOWParrotNav : public CGameObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TOW_PARROT_NAV_H */ diff --git a/engines/titanic/game/transport/exit_pellerator.cpp b/engines/titanic/game/transport/exit_pellerator.cpp new file mode 100644 index 0000000000..400214a140 --- /dev/null +++ b/engines/titanic/game/transport/exit_pellerator.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/game/transport/pellerator.h" + +namespace Titanic { + +int CPellerator::_v1; +int CPellerator::_v2; + +void CPellerator::save(SimpleFile *file, int indent) const { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + + CTransport::save(file, indent); +} + +void CPellerator::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + + CTransport::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/transport/exit_pellerator.h b/engines/titanic/game/transport/exit_pellerator.h new file mode 100644 index 0000000000..53056c7417 --- /dev/null +++ b/engines/titanic/game/transport/exit_pellerator.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_PELLERATOR_H +#define TITANIC_PELLERATOR_H + +#include "titanic/game/transport/transport.h" + +namespace Titanic { + +class CPellerator : public CTransport { +private: + static int _v1; + static int _v2; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PELLERATOR_H */ diff --git a/engines/titanic/game/transport/gondolier.cpp b/engines/titanic/game/transport/gondolier.cpp new file mode 100644 index 0000000000..f731e45bde --- /dev/null +++ b/engines/titanic/game/transport/gondolier.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/transport/gondolier.h" + +namespace Titanic { + +void CGondolier::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CTransport::save(file, indent); +} + +void CGondolier::load(SimpleFile *file) { + file->readNumber(); + CTransport::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/transport/gondolier.h b/engines/titanic/game/transport/gondolier.h new file mode 100644 index 0000000000..ac1617256f --- /dev/null +++ b/engines/titanic/game/transport/gondolier.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_GONDOLIER_H +#define TITANIC_GONDOLIER_H + +#include "titanic/game/transport/transport.h" + +namespace Titanic { + +class CGondolier : public CTransport { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GONDOLIER_H */ diff --git a/engines/titanic/game/transport/lift.cpp b/engines/titanic/game/transport/lift.cpp new file mode 100644 index 0000000000..72f832bf76 --- /dev/null +++ b/engines/titanic/game/transport/lift.cpp @@ -0,0 +1,69 @@ +/* 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 "titanic/game/transport/lift.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CLift, CTransport) + ON_MESSAGE(EnterRoomMsg) +END_MESSAGE_MAP() + +int CLift::_v1; +int CLift::_v2; +int CLift::_v3; +int CLift::_v4; +int CLift::_v5; +int CLift::_v6; + +void CLift::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + file->writeNumberLine(_v3, indent); + file->writeNumberLine(_v4, indent); + file->writeNumberLine(_v5, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_v6, indent); + + CTransport::save(file, indent); +} + +void CLift::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + _v3 = file->readNumber(); + _v4 = file->readNumber(); + _v5 = file->readNumber(); + _fieldF8 = file->readNumber(); + _v6 = file->readNumber(); + + CTransport::load(file); +} + +bool CLift::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CLift::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/transport/lift.h b/engines/titanic/game/transport/lift.h new file mode 100644 index 0000000000..4595f0fec2 --- /dev/null +++ b/engines/titanic/game/transport/lift.h @@ -0,0 +1,60 @@ +/* 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 TITANIC_LIFT_H +#define TITANIC_LIFT_H + +#include "titanic/game/transport/transport.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CLift : public CTransport { + DECLARE_MESSAGE_MAP; + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + static int _v1; + static int _v2; + static int _v3; + static int _v4; + static int _v5; + static int _v6; + + int _fieldF8; +public: + CLASSDEF; + CLift() : CTransport(), _fieldF8(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LIFT_H */ diff --git a/engines/titanic/game/transport/lift_indicator.cpp b/engines/titanic/game/transport/lift_indicator.cpp new file mode 100644 index 0000000000..582de8ad3b --- /dev/null +++ b/engines/titanic/game/transport/lift_indicator.cpp @@ -0,0 +1,55 @@ +/* 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 "titanic/game/transport/lift_indicator.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CLiftindicator, CLift) + ON_MESSAGE(EnterRoomMsg) +END_MESSAGE_MAP() + +CLiftindicator::CLiftindicator() : CLift(), + _fieldFC(0), _field108(0), _field10C(0) { +} + +void CLiftindicator::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldFC, indent); + file->writePoint(_pos2, indent); + file->writeNumberLine(_field108, indent); + file->writeNumberLine(_field10C, indent); + + CLift::save(file, indent); +} + +void CLiftindicator::load(SimpleFile *file) { + file->readNumber(); + _fieldFC = file->readNumber(); + _pos2 = file->readPoint(); + _field108 = file->readNumber(); + _field10C = file->readNumber(); + + CLift::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/transport/lift_indicator.h b/engines/titanic/game/transport/lift_indicator.h new file mode 100644 index 0000000000..945f627417 --- /dev/null +++ b/engines/titanic/game/transport/lift_indicator.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_LIFT_INDICATOR_H +#define TITANIC_LIFT_INDICATOR_H + +#include "titanic/game/transport/lift.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CLiftindicator : public CLift { + DECLARE_MESSAGE_MAP; + bool EnterRoomMsg(CEnterRoomMsg *msg) { return true; } +private: + int _fieldFC; + Point _pos2; + int _field108; + int _field10C; +public: + CLASSDEF; + CLiftindicator(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LIFT_INDICATOR_H */ diff --git a/engines/titanic/game/transport/pellerator.cpp b/engines/titanic/game/transport/pellerator.cpp new file mode 100644 index 0000000000..e789c20a3d --- /dev/null +++ b/engines/titanic/game/transport/pellerator.cpp @@ -0,0 +1,55 @@ +/* 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 "titanic/game/transport/pellerator.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CPellerator, CTransport) + ON_MESSAGE(EnterRoomMsg) +END_MESSAGE_MAP() + +int CPellerator::_v1; +int CPellerator::_v2; + +void CPellerator::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + + CTransport::save(file, indent); +} + +void CPellerator::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + + CTransport::load(file); +} + +bool CPellerator::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CPellerator::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/transport/pellerator.h b/engines/titanic/game/transport/pellerator.h new file mode 100644 index 0000000000..fa400a49cd --- /dev/null +++ b/engines/titanic/game/transport/pellerator.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_PELLERATOR_H +#define TITANIC_PELLERATOR_H + +#include "titanic/game/transport/transport.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CPellerator : public CTransport { + DECLARE_MESSAGE_MAP; + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + static int _v1; + static int _v2; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PELLERATOR_H */ diff --git a/engines/titanic/game/transport/service_elevator.cpp b/engines/titanic/game/transport/service_elevator.cpp new file mode 100644 index 0000000000..1ea8d14e36 --- /dev/null +++ b/engines/titanic/game/transport/service_elevator.cpp @@ -0,0 +1,61 @@ +/* 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 "titanic/game/transport/service_elevator.h" + +namespace Titanic { + +int CServiceElevator::_v1; +int CServiceElevator::_v2; +int CServiceElevator::_v3; + +CServiceElevator::CServiceElevator() : CTransport(), + _fieldF8(0), _fieldFC(0), _field100(0), _field104(0) { +} + +void CServiceElevator::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + file->writeNumberLine(_v3, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_fieldFC, indent); + file->writeNumberLine(_field100, indent); + file->writeNumberLine(_field104, indent); + + CTransport::save(file, indent); +} + +void CServiceElevator::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + _v3 = file->readNumber(); + _fieldF8 = file->readNumber(); + _fieldFC = file->readNumber(); + _field100 = file->readNumber(); + _field104 = file->readNumber(); + + CTransport::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/transport/service_elevator.h b/engines/titanic/game/transport/service_elevator.h new file mode 100644 index 0000000000..b2c135021a --- /dev/null +++ b/engines/titanic/game/transport/service_elevator.h @@ -0,0 +1,57 @@ +/* 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 TITANIC_SERVICE_ELEVATOR_H +#define TITANIC_SERVICE_ELEVATOR_H + +#include "titanic/game/transport/transport.h" + +namespace Titanic { + +class CServiceElevator : public CTransport { +private: + static int _v1; + static int _v2; + static int _v3; + + int _fieldF8; + int _fieldFC; + int _field100; + int _field104; +public: + CLASSDEF; + CServiceElevator(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SERVICE_ELEVATOR_H */ diff --git a/engines/titanic/game/transport/transport.cpp b/engines/titanic/game/transport/transport.cpp new file mode 100644 index 0000000000..6fe45c2fc8 --- /dev/null +++ b/engines/titanic/game/transport/transport.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/game/transport/transport.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CTransport, CMobile); + +CTransport::CTransport() : CMobile(), _string1("*.*.*") { +} + +void CTransport::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + + CMobile::save(file, indent); +} + +void CTransport::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + + CMobile::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/transport/transport.h b/engines/titanic/game/transport/transport.h new file mode 100644 index 0000000000..d87251212a --- /dev/null +++ b/engines/titanic/game/transport/transport.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_TRANSPORT_H +#define TITANIC_TRANSPORT_H + +#include "titanic/npcs/mobile.h" + +namespace Titanic { + +class CTransport : public CMobile { + DECLARE_MESSAGE_MAP; +public: + CString _string1; + CString _string2; +public: + CLASSDEF; + CTransport(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TRANSPORT_H */ diff --git a/engines/titanic/game/up_lighter.cpp b/engines/titanic/game/up_lighter.cpp new file mode 100644 index 0000000000..f03b8f37a0 --- /dev/null +++ b/engines/titanic/game/up_lighter.cpp @@ -0,0 +1,56 @@ +/* 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 "titanic/game/up_lighter.h" + +namespace Titanic { + +CUpLighter::CUpLighter() : CDropTarget(), _field118(0), + _field11C(0), _field120(0), _field124(0) { +} + +void CUpLighter::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field118, indent); + file->writeNumberLine(_field11C, indent); + file->writeNumberLine(_field120, indent); + file->writeNumberLine(_field124, indent); + + CDropTarget::save(file, indent); +} + +void CUpLighter::load(SimpleFile *file) { + file->readNumber(); + _field118 = file->readNumber(); + _field11C = file->readNumber(); + _field120 = file->readNumber(); + _field124 = file->readNumber(); + + CDropTarget::load(file); +} + +bool CUpLighter::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CUpLighter::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/up_lighter.h b/engines/titanic/game/up_lighter.h new file mode 100644 index 0000000000..2367e41314 --- /dev/null +++ b/engines/titanic/game/up_lighter.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_UP_LIGHTER_H +#define TITANIC_UP_LIGHTER_H + +#include "titanic/core/drop_target.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CUpLighter : public CDropTarget { + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + int _field118; + int _field11C; + int _field120; + int _field124; +public: + CLASSDEF; + CUpLighter(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_UP_LIGHTER_H */ diff --git a/engines/titanic/game/useless_lever.cpp b/engines/titanic/game/useless_lever.cpp new file mode 100644 index 0000000000..e48ad55a71 --- /dev/null +++ b/engines/titanic/game/useless_lever.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/game/useless_lever.h" + +namespace Titanic { + +void CUselessLever::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleButton::save(file, indent); +} + +void CUselessLever::load(SimpleFile *file) { + file->readNumber(); + CToggleButton::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/useless_lever.h b/engines/titanic/game/useless_lever.h new file mode 100644 index 0000000000..27397de216 --- /dev/null +++ b/engines/titanic/game/useless_lever.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_USELESS_LEVER_H +#define TITANIC_USELESS_LEVER_H + +#include "titanic/gfx/toggle_button.h" + +namespace Titanic { + +class CUselessLever : public CToggleButton { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_UP_LIGHTER_H */ diff --git a/engines/titanic/game/volume_control.cpp b/engines/titanic/game/volume_control.cpp new file mode 100644 index 0000000000..c6b0e414ae --- /dev/null +++ b/engines/titanic/game/volume_control.cpp @@ -0,0 +1,53 @@ +/* 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 "titanic/game/volume_control.h" + +namespace Titanic { + +CVolumeControl::CVolumeControl() : CGameObject() { +} + +void CVolumeControl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeQuotedLine(_string1, indent); + file->writeNumberLine(_fieldCC, indent); + + CGameObject::save(file, indent); +} + +void CVolumeControl::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _string1 = file->readString(); + _fieldCC = file->readNumber(); + + CGameObject::load(file); +} + +bool CVolumeControl::EnterNodeMsg(CEnterNodeMsg *msg) { + warning("CVolumeControl::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/volume_control.h b/engines/titanic/game/volume_control.h new file mode 100644 index 0000000000..dcc6f63781 --- /dev/null +++ b/engines/titanic/game/volume_control.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_VOLUME_CONTROL_H +#define TITANIC_VOLUME_CONTROL_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CVolumeControl : public CGameObject { + bool EnterNodeMsg(CEnterNodeMsg *msg); +private: + int _fieldBC; + CString _string1; + int _fieldCC; +public: + CLASSDEF; + CVolumeControl(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_VOLUME_CONTROL_H */ diff --git a/engines/titanic/game/wheel_button.cpp b/engines/titanic/game/wheel_button.cpp new file mode 100644 index 0000000000..19c42a8807 --- /dev/null +++ b/engines/titanic/game/wheel_button.cpp @@ -0,0 +1,49 @@ +/* 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 "titanic/game/wheel_button.h" + +namespace Titanic { + +CWheelButton::CWheelButton() : CBackground(), + _fieldE0(0), _fieldE4(0), _fieldE8(0) { +} + +void CWheelButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + + CBackground::save(file, indent); +} + +void CWheelButton::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/wheel_button.h b/engines/titanic/game/wheel_button.h new file mode 100644 index 0000000000..cb089a660f --- /dev/null +++ b/engines/titanic/game/wheel_button.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_WHEEL_BUTTON_H +#define TITANIC_WHEEL_BUTTON_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CWheelButton : public CBackground { +public: + int _fieldE0; + int _fieldE4; + int _fieldE8; +public: + CLASSDEF; + CWheelButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_WHEEL_BUTTON_H */ diff --git a/engines/titanic/game/wheel_hotspot.cpp b/engines/titanic/game/wheel_hotspot.cpp new file mode 100644 index 0000000000..f9af594cd5 --- /dev/null +++ b/engines/titanic/game/wheel_hotspot.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/game/wheel_hotspot.h" + +namespace Titanic { + +void CWheelHotSpot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + + CBackground::save(file, indent); +} + +void CWheelHotSpot::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/wheel_hotspot.h b/engines/titanic/game/wheel_hotspot.h new file mode 100644 index 0000000000..364fe9a060 --- /dev/null +++ b/engines/titanic/game/wheel_hotspot.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_WHEEL_HOTSPOT_H +#define TITANIC_WHEEL_HOTSPOT_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CWheelHotSpot : public CBackground { +public: + int _fieldE0; + int _fieldE4; +public: + CLASSDEF; + CWheelHotSpot() : CBackground(), _fieldE0(0), _fieldE4(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_WHEEL_HOTSPOT_H */ diff --git a/engines/titanic/game/wheel_spin.cpp b/engines/titanic/game/wheel_spin.cpp new file mode 100644 index 0000000000..daa9918e29 --- /dev/null +++ b/engines/titanic/game/wheel_spin.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/game/wheel_spin.h" + +namespace Titanic { + +void CWheelSpin::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CBackground::save(file, indent); +} + +void CWheelSpin::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/wheel_spin.h b/engines/titanic/game/wheel_spin.h new file mode 100644 index 0000000000..509db1a4bf --- /dev/null +++ b/engines/titanic/game/wheel_spin.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_WHEEL_SPIN_H +#define TITANIC_WHEEL_SPIN_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CWheelSpin : public CBackground { +public: + int _value; +public: + CLASSDEF; + CWheelSpin() : CBackground(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_WHEEL_SPIN_H */ diff --git a/engines/titanic/game/wheel_spin_horn.cpp b/engines/titanic/game/wheel_spin_horn.cpp new file mode 100644 index 0000000000..b01cc678df --- /dev/null +++ b/engines/titanic/game/wheel_spin_horn.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/game/wheel_spin_horn.h" + +namespace Titanic { + +void CWheelSpinHorn::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + + CWheelSpin::save(file, indent); +} + +void CWheelSpinHorn::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + + CWheelSpin::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game/wheel_spin_horn.h b/engines/titanic/game/wheel_spin_horn.h new file mode 100644 index 0000000000..21182253b3 --- /dev/null +++ b/engines/titanic/game/wheel_spin_horn.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_WHEEL_SPIN_HORN_H +#define TITANIC_WHEEL_SPIN_HORN_H + +#include "titanic/game/wheel_spin.h" + +namespace Titanic { + +class CWheelSpinHorn : public CWheelSpin { +public: + CString _string1; + CString _string2; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_WHEEL_SPIN_HORN_H */ diff --git a/engines/titanic/game_location.cpp b/engines/titanic/game_location.cpp new file mode 100644 index 0000000000..3a1d0c9e48 --- /dev/null +++ b/engines/titanic/game_location.cpp @@ -0,0 +1,115 @@ +/* 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 "titanic/game_location.h" +#include "titanic/game_manager.h" +#include "titanic/game_state.h" +#include "titanic/core/game_object.h" +#include "titanic/core/project_item.h" + +namespace Titanic { + +#define STARTING_ROOM 3 +#define STARTING_NODE 1 +#define STARTING_VIEW 4 + +CGameLocation::CGameLocation(CGameState *owner) : _gameState(owner), + _view(nullptr), _roomNumber(STARTING_ROOM), + _nodeNumber(STARTING_NODE), _viewNumber(STARTING_VIEW) { +} + +void CGameLocation::save(SimpleFile *file) const { + file->writeNumber(_roomNumber); + file->writeNumber(_nodeNumber); + file->writeNumber(_viewNumber); +} + +void CGameLocation::load(SimpleFile *file) { + _view = nullptr; + _roomNumber = file->readNumber(); + _nodeNumber = file->readNumber(); + _viewNumber = file->readNumber(); +} + +void CGameLocation::setView(CViewItem *view) { + if (_view) { + for (CTreeItem *treeItem = _view; treeItem; + treeItem = treeItem->scan(_view)) { + CGameObject *obj = dynamic_cast<CGameObject *>(treeItem); + if (obj) + obj->stopMovie(); + } + } + + _view = view; + if (_view) { + _viewNumber = _view->_viewNumber; + _nodeNumber = _view->findNode()->_nodeNumber; + _roomNumber = _view->findRoom()->_roomNumber; + } else { + _viewNumber = _nodeNumber = _roomNumber = -1; + } +} + +CViewItem *CGameLocation::getView() { + if (!_view) { + CGameManager *gm = _gameState->_gameManager; + _view = gm->_project->findView(_roomNumber, _nodeNumber, _viewNumber); + + if (!_view) { + // Fallback if view not found + _view = gm->_project->findView(STARTING_ROOM, + STARTING_NODE, STARTING_VIEW); + + if (!_view) { + // Fallback for the fallback + for (int idx = 0; idx < 99 && !_view; ++idx) { + _view = gm->_project->findView(idx, 1, 1); + } + } + } + } + + if (!_view) { + // Okay seriously, yet another fallback if view not found + _viewNumber = _nodeNumber = _roomNumber = -1; + _view = nullptr; + } else { + _viewNumber = _view->_viewNumber; + _nodeNumber = _view->findNode()->_nodeNumber; + _roomNumber = _view->findRoom()->_roomNumber; + } + + return _view; +} + +CNodeItem *CGameLocation::getNode() { + CViewItem *view = getView(); + return !view ? nullptr : view->findNode(); +} + +CRoomItem *CGameLocation::getRoom() { + CViewItem *view = getView(); + return !view ? nullptr : view->findRoom(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game_location.h b/engines/titanic/game_location.h new file mode 100644 index 0000000000..f145d36340 --- /dev/null +++ b/engines/titanic/game_location.h @@ -0,0 +1,79 @@ +/* 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 TITANIC_GAME_LOCATION_H +#define TITANIC_GAME_LOCATION_H + +#include "titanic/support/simple_file.h" +#include "titanic/core/node_item.h" +#include "titanic/core/room_item.h" +#include "titanic/core/view_item.h" + +namespace Titanic { + +class CGameState; + +class CGameLocation { +private: + CGameState *_gameState; + CViewItem *_view; + + int _roomNumber; + int _nodeNumber; + int _viewNumber; +public: + CGameLocation(CGameState *owner); + + /** + * Save the data for the class to file + */ + void save(SimpleFile *file) const; + + /** + * Load the data for the class from file + */ + void load(SimpleFile *file); + + /** + * Set the current view + */ + void setView(CViewItem *view); + + /** + * Get the current view + */ + CViewItem *getView(); + + /** + * Get the current node + */ + CNodeItem *getNode(); + + /** + * Get the current room + */ + CRoomItem *getRoom(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GAME_LOCATION_H */ diff --git a/engines/titanic/game_manager.cpp b/engines/titanic/game_manager.cpp new file mode 100644 index 0000000000..9bc9e4d067 --- /dev/null +++ b/engines/titanic/game_manager.cpp @@ -0,0 +1,313 @@ +/* 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 "titanic/titanic.h" +#include "titanic/game_manager.h" +#include "titanic/game_view.h" +#include "titanic/support/screen_manager.h" +#include "titanic/core/project_item.h" +#include "titanic/messages/messages.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +CGameManager::CGameManager(CProjectItem *project, CGameView *gameView, Audio::Mixer *mixer): + _project(project), _gameView(gameView), _trueTalkManager(this), + _inputHandler(this), _inputTranslator(&_inputHandler), + _gameState(this), _sound(this, mixer), _musicRoom(this), + _treeItem(nullptr), _soundMaker(nullptr), _movieRoom(nullptr), + _dragItem(nullptr), _field54(0), _lastDiskTicksCount(0), _tickCount2(0) { + + CTimeEventInfo::_nextId = 0; + _movie = nullptr; + _movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340); + _project->setGameManager(this); + g_vm->_filesManager->setGameManager(this); +} + +CGameManager::~CGameManager() { + delete _movie; + delete _movieSurface; + destroyTreeItem(); + + _project->resetGameManager(); +} + +void CGameManager::destroyTreeItem() { + if (_treeItem) { + _treeItem->destroyAll(); + _treeItem = nullptr; + } +} + +void CGameManager::save(SimpleFile *file) { + file->writeNumber(_lastDiskTicksCount); + _gameState.save(file); + _timers.save(file, 0); + _trueTalkManager.save(file); + _sound.save(file); +} + +void CGameManager::load(SimpleFile *file) { + file->readNumber(); + + _gameState.load(file); + _timers.load(file); + _trueTalkManager.load(file); + _sound.load(file); +} + +void CGameManager::preLoad() { + updateDiskTicksCount(); + _timers.destroyContents(); + _soundMaker = nullptr; + + _trueTalkManager.preLoad(); + _sound.preLoad(); +} + +void CGameManager::postLoad(CProjectItem *project) { + if (_gameView) { + _gameView->postLoad(); + + if (!_gameView->_surface) { + CViewItem *view = getView(); + if (view) + _gameView->setView(view); + } + } + + // Signal to anything interested that the game has been loaded + CLoadSuccessMsg msg(_lastDiskTicksCount - _tickCount2); + msg.execute(project, nullptr, MSGFLAG_SCAN); + + // Signal to any registered timers + _timers.postLoad(_lastDiskTicksCount, _project); + + // Signal the true talk manager and sound + _trueTalkManager.postLoad(); + _sound.postLoad(); +} + +void CGameManager::preSave(CProjectItem *project) { + // Generate a message that a save is being done + updateDiskTicksCount(); + CPreSaveMsg msg(_lastDiskTicksCount); + msg.execute(project, nullptr, MSGFLAG_SCAN); + + // Notify sub-objects of the save + _timers.preSave(_lastDiskTicksCount); + _trueTalkManager.preSave(); + _sound.preSave(); +} + +void CGameManager::postSave() { + _timers.postSave(); + _trueTalkManager.postSave(); + _sound.postSave(); +} + +void CGameManager::initBounds() { + _bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); +} + +void CGameManager::roomTransition(CRoomItem *oldRoom, CRoomItem *newRoom) { + delete _movie; + _movie = nullptr; + + CResourceKey movieKey = (oldRoom == newRoom) ? oldRoom->getTransitionMovieKey() : + oldRoom->getExitMovieKey(); + CString filename = movieKey.exists(); + if (g_vm->_filesManager->fileExists(filename)) { + _movieSurface->freeSurface(); + _movie = g_vm->_movieManager.createMovie(filename, _movieSurface); + } +} + +void CGameManager::playClip(CMovieClip *clip, CRoomItem *oldRoom, CRoomItem *newRoom) { + if (oldRoom != newRoom || newRoom != _movieRoom || !_movie) + roomTransition(oldRoom, newRoom); + + if (clip && clip->_startFrame != clip->_endFrame && _movie) { + // Clip details specifying a sub-section of movie to play + Rect tempRect(20, 10, SCREEN_WIDTH - 20, 350); + + lockInputHandler(); + CScreenManager::_screenManagerPtr->_mouseCursor->hide(); + _movie->playClip(tempRect, clip->_startFrame, clip->_endFrame); + CScreenManager::_screenManagerPtr->_mouseCursor->show(); + unlockInputHandler(); + } +} + +void CGameManager::update() { + updateMovies(); + frameMessage(getRoom()); + _timers.update(g_vm->_events->getTicksCount()); + _trueTalkManager.removeCompleted(); + _trueTalkManager.update2(); + CScreenManager::_screenManagerPtr->_mouseCursor->update(); + + CViewItem *view = getView(); + if (view) { + // Expand the game manager's bounds to encompass all the view's items + for (CTreeItem *item = view; item; item = item->scan(view)) { + Rect r = item->getBounds(); + if (!r.isEmpty()) + _bounds.extend(r); + } + + // Also include the PET control in the bounds + if (_project) { + CPetControl *pet = _project->getPetControl(); + if (pet) + _bounds.extend(pet->getBounds()); + } + + // And the text cursor + CScreenManager *screenManager = CScreenManager::_screenManagerPtr; + CTextCursor *textCursor = screenManager->_textCursor; + if (textCursor && textCursor->_active) + _bounds.extend(textCursor->getCursorBounds()); + + // Set the surface bounds + screenManager->setSurfaceBounds(SURFACE_BACKBUFFER, _bounds); + + // Handle redrawing the view + if (!_bounds.isEmpty()) { + _gameView->draw(_bounds); + _bounds = Rect(); + } + + _gameState.checkForViewChange(); + } +} + +void CGameManager::updateMovies() { + // Initial iteration to mark all the movies as not yet handled + for (CMovieList::iterator i = CMovie::_playingMovies->begin(); + i != CMovie::_playingMovies->end(); ++i) + (*i)->_handled = false; + + bool repeatFlag; + do { + repeatFlag = false; + + // Scan for a movie to process + for (CMovieList::iterator i = CMovie::_playingMovies->begin(); + i != CMovie::_playingMovies->end(); ++i) { + CMovie *movie = *i; + if (movie->_handled) + continue; + + CMovieEventList eventsList; + if (!movie->handleEvents(eventsList)) + movie->removeFromPlayingMovies(); + + while (!eventsList.empty()) { + CMovieEvent *movieEvent = eventsList.front(); + + switch (movieEvent->_type) { + case MET_MOVIE_END: { + CMovieEndMsg endMsg(movieEvent->_startFrame, movieEvent->_endFrame); + endMsg.execute(movieEvent->_gameObject); + break; + } + + case MET_FRAME: { + CMovieFrameMsg frameMsg(movieEvent->_initialFrame, 0); + frameMsg.execute(movieEvent->_gameObject); + break; + } + + default: + break; + } + + eventsList.remove(movieEvent); + } + + // Flag the movie as having been handled + movie->_handled = true; + repeatFlag = true; + break; + } + } while (repeatFlag); +} + +void CGameManager::updateDiskTicksCount() { + _lastDiskTicksCount = g_vm->_events->getTicksCount(); +} + +void CGameManager::viewChange() { + delete _movie; + delete _movieSurface; + + _movie = nullptr; + _movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340); + _trueTalkManager.clear(); + + for (CTreeItem *treeItem = _project; treeItem; treeItem = treeItem->scan(_project)) + treeItem->viewChange(); + + initBounds(); +} + +void CGameManager::frameMessage(CRoomItem *room) { + if (room) { + // Signal the next frame + CFrameMsg frameMsg(g_vm->_events->getTicksCount()); + frameMsg.execute(room, nullptr, MSGFLAG_SCAN); + + if (!_soundMaker) { + // Check for a sound maker in the room + _soundMaker = dynamic_cast<CBackgroundSoundMaker *>( + _project->findByName("zBackgroundSoundMaker")); + } + + // If there's a sound maker, dispatch the event to it as well + if (_soundMaker) + frameMsg.execute(_soundMaker); + } +} + +void CGameManager::extendBounds(const Rect &r) { + if (_bounds.isEmpty()) + _bounds = r; + else + _bounds.combine(r); +} + +CScreenManager *CGameManager::setScreenManager() const { + return CScreenManager::setCurrent(); +} + +CString CGameManager::getFullViewName() { + CViewItem *view = getView(); + CNodeItem *node = view->findNode(); + CRoomItem *room = node->findRoom(); + + return CString::format("%s.%s.%s", room->getName().c_str(), + node->getName().c_str(), view->getName().c_str()); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game_manager.h b/engines/titanic/game_manager.h new file mode 100644 index 0000000000..262ea0169b --- /dev/null +++ b/engines/titanic/game_manager.h @@ -0,0 +1,217 @@ +/* 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 TITANIC_GAME_MANAGER_H +#define TITANIC_GAME_MANAGER_H + +#include "common/scummsys.h" +#include "titanic/game_state.h" +#include "titanic/input_handler.h" +#include "titanic/input_translator.h" +#include "titanic/support/simple_file.h" +#include "titanic/support/time_event_info.h" +#include "titanic/support/video_surface.h" +#include "titanic/true_talk/true_talk_manager.h" +#include "titanic/sound/background_sound_maker.h" +#include "titanic/sound/music_room.h" +#include "titanic/sound/sound.h" + +namespace Titanic { + +class CProjectItem; +class CGameView; + +class CGameManager { +private: + CTrueTalkManager _trueTalkManager; + CTimeEventInfoList _timers; + CTreeItem *_treeItem; + CBackgroundSoundMaker *_soundMaker; + CMovie *_movie; + CRoomItem *_movieRoom; + int _field54; + CVideoSurface *_movieSurface; + uint _lastDiskTicksCount; + uint _tickCount2; +private: + /** + * Generates a message for the next game frame + */ + void frameMessage(CRoomItem *room); + + /** + * Handles any ongoing movie playback + */ + void updateMovies(); + + /** + * Handles a room transition + */ + void roomTransition(CRoomItem *oldRoom, CRoomItem *newRoom); +public: + CProjectItem *_project; + CGameView *_gameView; + CGameState _gameState; + Rect _bounds; + CInputHandler _inputHandler; + CInputTranslator _inputTranslator; + CTreeItem *_dragItem; + CMusicRoom _musicRoom; + CSound _sound; +public: + CGameManager(CProjectItem *project, CGameView *gameView, Audio::Mixer *mixer); + ~CGameManager(); + + /** + * Destroys and allocated tree item + */ + void destroyTreeItem(); + + /** + * Save data to a save file + */ + void save(SimpleFile *file); + + /** + * Load data from a save file + */ + void load(SimpleFile *file); + + /** + * Called when a game is about to be loaded + */ + void preLoad(); + + /** + * Called after loading a game has finished + */ + void postLoad(CProjectItem *project); + + /** + * Called when a game is about to be saved + */ + void preSave(CProjectItem *project); + + /** + * Called when a game has finished being saved + */ + void postSave(); + + /** + * Updates the game time when the last disk access started + */ + void updateDiskTicksCount(); + + /** + * Gets the current view + */ + CViewItem *getView() { return _gameState._gameLocation.getView(); } + + /** + * Gets the current room node + */ + CNodeItem *getNode() { return _gameState._gameLocation.getNode(); } + + /** + * Gets the current room + */ + CRoomItem *getRoom() { return _gameState._gameLocation.getRoom(); } + + /** + * Lock the input handler + */ + void lockInputHandler() { _inputHandler.incLockCount(); } + + /** + * Unlock the input handler + */ + void unlockInputHandler() { _inputHandler.decLockCount(); } + + /** + * Set default screen bounds + */ + void initBounds(); + + /** + * Plays a movie clip + */ + void playClip(CMovieClip *clip, CRoomItem *oldRoom, CRoomItem *newRoom); + + /** + * Main frame update method for the game + */ + void update(); + + /** + * Called when the view changes + */ + void viewChange(); + + bool test54() const { return !_field54; } + + void inc54() { ++_field54; } + + void dec54() { --_field54; } + + /** + * Extends the bounds of the currently affected game display area + * to include the passed rect + */ + void extendBounds(const Rect &r); + + /** + * Set and return the current screen manager + */ + CScreenManager *setScreenManager() const; + + /** + * Adds a timer + */ + void addTimer(CTimeEventInfo *timer) { _timers.push_back(timer); } + + /** + * Stops a timer + */ + void stopTimer(uint id) { _timers.stop(id); } + + /** + * Flags whether the timer will be persisent across save & loads + */ + void setTimerPersisent(uint id, bool flag) { + _timers.setPersisent(id, flag); + } + + /** + * Return the true talk manager + */ + CTrueTalkManager *getTalkManager() { return &_trueTalkManager; } + + /** + * Return the full Id of the current view in a + * room.node.view tuplet form + */ + CString getFullViewName(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GAME_MANAGER_H */ diff --git a/engines/titanic/game_state.cpp b/engines/titanic/game_state.cpp new file mode 100644 index 0000000000..5628161558 --- /dev/null +++ b/engines/titanic/game_state.cpp @@ -0,0 +1,168 @@ +/* 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 "titanic/game_state.h" +#include "titanic/titanic.h" +#include "titanic/game_manager.h" +#include "titanic/support/screen_manager.h" + +namespace Titanic { + +bool CGameStateMovieList::clear() { + for (CGameStateMovieList::iterator i = begin(); i != end(); ) { + CMovieListItem *movieItem = *i; + + if (movieItem->_item->isActive()) { + ++i; + } else { + i = erase(i); + delete movieItem; + } + } + + return !empty(); +} + +/*------------------------------------------------------------------------*/ + +CGameState::CGameState(CGameManager *gameManager) : + _gameManager(gameManager), _gameLocation(this), + _passengerClass(0), _priorClass(0), _mode(GSMODE_NONE), + _field14(0), _petActive(false), _field1C(false), _quitGame(false), + _field24(0), _nodeChangeCtr(0), _nodeEnterTicks(0), _field38(0) { +} + +void CGameState::save(SimpleFile *file) const { + file->writeNumber(_petActive); + file->writeNumber(_passengerClass); + file->writeNumber(_priorClass); + file->writeNumber(_field14); + file->writeNumber(_field24); + file->writeNumber(_field38); + _gameLocation.save(file); + file->writeNumber(_field1C); +} + +void CGameState::load(SimpleFile *file) { + _petActive = file->readNumber() != 0; + _passengerClass = file->readNumber(); + _priorClass = file->readNumber(); + _field14 = file->readNumber(); + _field24 = file->readNumber(); + _field38 = file->readNumber(); + _gameLocation.load(file); + + _field1C = file->readNumber(); + _nodeChangeCtr = 0; + _nodeEnterTicks = 0; +} + +void CGameState::setMode(GameStateMode newMode) { + CScreenManager *sm = CScreenManager::_screenManagerPtr; + + if (newMode == GSMODE_CUTSCENE && newMode != _mode) { + if (_gameManager) + _gameManager->lockInputHandler(); + + if (sm && sm->_mouseCursor) + sm->_mouseCursor->hide(); + + } else if (newMode != GSMODE_CUTSCENE && newMode != _mode) { + if (sm && sm->_mouseCursor) + sm->_mouseCursor->show(); + + if (_gameManager) + _gameManager->unlockInputHandler(); + } + + _mode = newMode; +} + +void CGameState::enterNode() { + ++_nodeChangeCtr; + _nodeEnterTicks = g_vm->_events->getTicksCount(); +} + +void CGameState::enterView() { + CViewItem *oldView = _gameLocation.getView(); + CViewItem *newView = _movieList._view; + oldView->preEnterView(newView); + + _gameManager->_gameView->setView(newView); + CRoomItem *oldRoom = oldView->findNode()->findRoom(); + CRoomItem *newRoom = newView->findNode()->findRoom(); + _gameManager->playClip(_movieList._movieClip, oldRoom, newRoom); + + _gameManager->_sound.preEnterView(newView, newRoom != oldRoom); + _gameManager->dec54(); + oldView->enterView(newView); + + _movieList._view = nullptr; + _movieList._movieClip = nullptr; +} + +void CGameState::triggerLink(CLinkItem *link) { + changeView(link->getDestView(), link->getClip()); +} + +void CGameState::changeView(CViewItem *newView, CMovieClip *clip) { + // Signal the old view that it's being left + CViewItem *oldView = _gameLocation.getView(); + oldView->leaveView(newView); + + // If Shift key is pressed, skip showing the transition clip + if (g_vm->_window->isSpecialPressed(MK_SHIFT)) + clip = nullptr; + + if (_mode == GSMODE_CUTSCENE) { + _movieList._view = newView; + _movieList._movieClip = clip; + } else { + oldView->preEnterView(newView); + _gameManager->_gameView->setView(newView); + CRoomItem *oldRoom = newView->findNode()->findRoom(); + CRoomItem *newRoom = newView->findNode()->findRoom(); + + // If a transition clip is defined, play it + if (clip) + _gameManager->playClip(clip, oldRoom, newRoom); + + // Final view change handling + _gameManager->_sound.preEnterView(newView, newRoom != oldRoom); + oldView->enterView(newView); + } +} + +void CGameState::checkForViewChange() { + if (_mode == GSMODE_CUTSCENE && _movieList.clear()) { + setMode(GSMODE_INTERACTIVE); + if (_movieList._view) + enterView(); + } +} + +void CGameState::addMovie(CMovie *movie) { + _movieList.push_back(new CMovieListItem(movie)); + setMode(GSMODE_CUTSCENE); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game_state.h b/engines/titanic/game_state.h new file mode 100644 index 0000000000..0bfa0d5b31 --- /dev/null +++ b/engines/titanic/game_state.h @@ -0,0 +1,140 @@ +/* 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 TITANIC_GAME_STATE_H +#define TITANIC_GAME_STATE_H + +#include "titanic/core/list.h" +#include "titanic/core/link_item.h" +#include "titanic/support/simple_file.h" +#include "titanic/game_location.h" +#include "titanic/support/movie.h" + +namespace Titanic { + +class CGameManager; + +enum GameStateMode { + GSMODE_NONE = 0, GSMODE_INTERACTIVE = 1, GSMODE_CUTSCENE = 2, + GSMODE_3 = 3, GSMODE_4 = 4, GSMODE_5 = 5, GSMODE_PENDING_LOAD = 6 +}; + +PTR_LIST_ITEM(CMovie); +class CGameStateMovieList : public List<CMovieListItem> { +public: + CViewItem *_view; + CMovieClip *_movieClip; +public: + CGameStateMovieList() : List<CMovieListItem>(), _view(nullptr), _movieClip(nullptr) {} + + /** + * Clear the movie list + */ + bool clear(); +}; + +class CGameState { +public: + CGameManager *_gameManager; + CGameLocation _gameLocation; + CGameStateMovieList _movieList; + int _passengerClass; + int _priorClass; + GameStateMode _mode; + int _field14; + bool _petActive; + bool _field1C; + bool _quitGame; + int _field24; + uint _nodeChangeCtr; + uint32 _nodeEnterTicks; + Point _mousePos; + int _field38; +public: + CGameState(CGameManager *gameManager); + + /** + * Save the data for the class to file + */ + void save(SimpleFile *file) const; + + /** + * Load the data for the class from file + */ + void load(SimpleFile *file); + + /** + * Sets a new mode + */ + void setMode(GameStateMode newMode); + + /** + * Sets the current mouse position + */ + void setMousePos(const Point &pt) { _mousePos = pt; } + + /** + * Gets the current mouse position + */ + Point getMousePos() const { return _mousePos; } + + /** + * Called by the PET when a new node is entered + */ + void enterNode(); + + /** + * Enters a new view + */ + void enterView(); + + /** + * Triggers a link item in a view + */ + void triggerLink(CLinkItem *link); + + /** + * Changes the current view + */ + void changeView(CViewItem *newView, CMovieClip *clip); + + /** + * Check for whether it's time to change the active view + */ + void checkForViewChange(); + + /** + * Adds a movie to the movie list + */ + void addMovie(CMovie *movie); + + void inc14() { _field14 = (_field14 + 1) & 3; } + void set24(int v) { _field24 = v; } + int get24() const { return _field24; } + int getNodeChangedCtr() const { return _nodeChangeCtr; } + uint32 getNodeEnterTicks() const { return _nodeEnterTicks; } + void inc38() { ++_field38; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GAME_STATE_H */ diff --git a/engines/titanic/game_view.cpp b/engines/titanic/game_view.cpp new file mode 100644 index 0000000000..cb84b6a3b1 --- /dev/null +++ b/engines/titanic/game_view.cpp @@ -0,0 +1,96 @@ +/* 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 "titanic/game_view.h" +#include "titanic/game_manager.h" +#include "titanic/main_game_window.h" +#include "titanic/support/screen_manager.h" + +namespace Titanic { + +#define VIEW_OFFSET_X 20 +#define VIEW_OFFSET_Y 10 + +CGameView::CGameView() : _gameManager(nullptr), _surface(nullptr) { +} + +CGameView::~CGameView() { + if (_surface) + delete _surface; +} + +void CGameView::setGameManager(CGameManager *gameManager) { + _gameManager = gameManager; +} + +void CGameView::postLoad() { + delete _surface; + _surface = nullptr; +} + +void CGameView::deleteView(int roomNumber, int nodeNumber, int viewNumber) { + CViewItem *view = _gameManager->_project->findView(roomNumber, nodeNumber, viewNumber); + if (view) + delete view; +} + +void CGameView::createSurface(const CResourceKey &key) { + // Reset any current view surface + _gameManager->initBounds(); + delete _surface; + _surface = nullptr; + + // Create a fresh surface + CScreenManager::setCurrent(); + _surface = CScreenManager::_currentScreenManagerPtr->createSurface(key); + _surface->_fastBlitFlag = true; +} + +void CGameView::drawView() { + CScreenManager::setCurrent(); + Rect srcRect = _gameManager->_bounds; + + Rect rect2(0, 0, 600, 340); + rect2.translate(VIEW_OFFSET_X, VIEW_OFFSET_Y); + srcRect.constrain(rect2); + Common::Point destPos(srcRect.left, srcRect.top); + srcRect.translate(-VIEW_OFFSET_X, -VIEW_OFFSET_Y); + + CScreenManager::_currentScreenManagerPtr->blitFrom(SURFACE_BACKBUFFER, + _surface, &destPos, &srcRect); +} + +/*------------------------------------------------------------------------*/ + +CSTGameView::CSTGameView(CMainGameWindow *gameWindow) : + CGameView(), _gameWindow(gameWindow) { +} + +void CSTGameView::setView(CViewItem *view) { + _gameWindow->setActiveView(view); +} + +void CSTGameView::draw(const Rect &bounds) { + _gameWindow->draw(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/game_view.h b/engines/titanic/game_view.h new file mode 100644 index 0000000000..29e800bc7a --- /dev/null +++ b/engines/titanic/game_view.h @@ -0,0 +1,93 @@ +/* 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 TITANIC_GAME_VIEW_H +#define TITANIC_GAME_VIEW_H + +#include "common/scummsys.h" +#include "titanic/core/view_item.h" +#include "titanic/support/video_surface.h" + +namespace Titanic { + +class CMainGameWindow; +class CGameManager; + +class CGameView { +protected: + CGameManager *_gameManager; +public: + CVideoSurface *_surface; +public: + CGameView(); + virtual ~CGameView(); + + /** + * Set the game manager + */ + void setGameManager(CGameManager *gameManager); + + /** + * Called after loading a game has finished + */ + void postLoad(); + + virtual void deleteView(int roomNumber, int nodeNumber, int viewNumber); + + /** + * Set the currently active view + */ + virtual void setView(CViewItem *item) = 0; + + virtual void draw(const Rect &bounds) = 0; + + /** + * Creates a surface from a specified resource + */ + void createSurface(const CResourceKey &key); + + /** + * Draws the background of a view + */ + void drawView(); +}; + +class CSTGameView: public CGameView { +private: + CMainGameWindow *_gameWindow; +public: + CSTGameView(CMainGameWindow *gameWindow); + + /** + * Set the currently active view + */ + virtual void setView(CViewItem *item); + + /** + * Handles drawing the view + */ + virtual void draw(const Rect &bounds); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GAME_VIEW_H */ diff --git a/engines/titanic/gfx/act_button.cpp b/engines/titanic/gfx/act_button.cpp new file mode 100644 index 0000000000..75c999b10f --- /dev/null +++ b/engines/titanic/gfx/act_button.cpp @@ -0,0 +1,50 @@ +/* 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 "titanic/gfx/act_button.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CActButton, CSTButton) + ON_MESSAGE(MouseButtonUpMsg) +END_MESSAGE_MAP() + +CActButton::CActButton() : CSTButton() { +} + +void CActButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSTButton::save(file, indent); +} + +void CActButton::load(SimpleFile *file) { + file->readNumber(); + CSTButton::load(file); +} + +bool CActButton::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + CActMsg actMsg(_actionName); + actMsg.execute(_actionTarget); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/act_button.h b/engines/titanic/gfx/act_button.h new file mode 100644 index 0000000000..910ace1d13 --- /dev/null +++ b/engines/titanic/gfx/act_button.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_ACT_BUTTON_H +#define TITANIC_ACT_BUTTON_H + +#include "titanic/gfx/st_button.h" + +namespace Titanic { + +class CActButton : public CSTButton { + DECLARE_MESSAGE_MAP; + bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); +public: + CLASSDEF; + CActButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ACT_BUTTON_H */ diff --git a/engines/titanic/gfx/changes_season_button.cpp b/engines/titanic/gfx/changes_season_button.cpp new file mode 100644 index 0000000000..d5242ad890 --- /dev/null +++ b/engines/titanic/gfx/changes_season_button.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/gfx/changes_season_button.h" + +namespace Titanic { + +CChangesSeasonButton::CChangesSeasonButton() : CSTButton() { +} + +void CChangesSeasonButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSTButton::save(file, indent); +} + +void CChangesSeasonButton::load(SimpleFile *file) { + file->readNumber(); + CSTButton::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/changes_season_button.h b/engines/titanic/gfx/changes_season_button.h new file mode 100644 index 0000000000..2b58a3199b --- /dev/null +++ b/engines/titanic/gfx/changes_season_button.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_CHANGES_SEASON_BUTTON_H +#define TITANIC_CHANGES_SEASON_BUTTON_H + +#include "titanic/gfx/st_button.h" + +namespace Titanic { + +class CChangesSeasonButton : public CSTButton { +public: + CLASSDEF; + CChangesSeasonButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHANGES_SEASON_BUTTON_H */ diff --git a/engines/titanic/gfx/chev_left_off.cpp b/engines/titanic/gfx/chev_left_off.cpp new file mode 100644 index 0000000000..d5c7dcffd6 --- /dev/null +++ b/engines/titanic/gfx/chev_left_off.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/chev_left_off.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CChevLeftOff, CToggleSwitch); + +CChevLeftOff::CChevLeftOff() : CToggleSwitch() { +} + +void CChevLeftOff::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CChevLeftOff::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/chev_left_off.h b/engines/titanic/gfx/chev_left_off.h new file mode 100644 index 0000000000..5034c1a71a --- /dev/null +++ b/engines/titanic/gfx/chev_left_off.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_CHEV_LEFT_OFF_H +#define TITANIC_CHEV_LEFT_OFF_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CChevLeftOff : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CChevLeftOff(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHEV_LEFT_OFF_H */ diff --git a/engines/titanic/gfx/chev_left_on.cpp b/engines/titanic/gfx/chev_left_on.cpp new file mode 100644 index 0000000000..9b4a5b6d58 --- /dev/null +++ b/engines/titanic/gfx/chev_left_on.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/chev_left_on.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CChevLeftOn, CToggleSwitch); + +CChevLeftOn::CChevLeftOn() : CToggleSwitch() { +} + +void CChevLeftOn::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CChevLeftOn::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/chev_left_on.h b/engines/titanic/gfx/chev_left_on.h new file mode 100644 index 0000000000..df430f6700 --- /dev/null +++ b/engines/titanic/gfx/chev_left_on.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_CHEV_LEFT_ON_H +#define TITANIC_CHEV_LEFT_ON_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CChevLeftOn : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CChevLeftOn(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHEV_LEFT_ON_H */ diff --git a/engines/titanic/gfx/chev_right_off.cpp b/engines/titanic/gfx/chev_right_off.cpp new file mode 100644 index 0000000000..c4ff3628a0 --- /dev/null +++ b/engines/titanic/gfx/chev_right_off.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/chev_right_off.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CChevRightOff, CToggleSwitch); + +CChevRightOff::CChevRightOff() : CToggleSwitch() { +} + +void CChevRightOff::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CChevRightOff::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/chev_right_off.h b/engines/titanic/gfx/chev_right_off.h new file mode 100644 index 0000000000..8f6c3fc254 --- /dev/null +++ b/engines/titanic/gfx/chev_right_off.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_CHEV_RIGHT_OFF_H +#define TITANIC_CHEV_RIGHT_OFF_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CChevRightOff : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CChevRightOff(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHEV_RIGHT_OFF_H */ diff --git a/engines/titanic/gfx/chev_right_on.cpp b/engines/titanic/gfx/chev_right_on.cpp new file mode 100644 index 0000000000..0351c105d2 --- /dev/null +++ b/engines/titanic/gfx/chev_right_on.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/chev_right_on.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CChevRightOn, CToggleSwitch); + +CChevRightOn::CChevRightOn() : CToggleSwitch() { +} + +void CChevRightOn::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CChevRightOn::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/chev_right_on.h b/engines/titanic/gfx/chev_right_on.h new file mode 100644 index 0000000000..accd42cff8 --- /dev/null +++ b/engines/titanic/gfx/chev_right_on.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_CHEV_RIGHT_ON_H +#define TITANIC_CHEV_RIGHT_ON_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CChevRightOn : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CChevRightOn(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHEV_RIGHT_ON_H */ diff --git a/engines/titanic/gfx/chev_send_rec_switch.cpp b/engines/titanic/gfx/chev_send_rec_switch.cpp new file mode 100644 index 0000000000..6e30280315 --- /dev/null +++ b/engines/titanic/gfx/chev_send_rec_switch.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/chev_send_rec_switch.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CChevSendRecSwitch, CToggleSwitch); + +CChevSendRecSwitch::CChevSendRecSwitch() : CToggleSwitch() { +} + +void CChevSendRecSwitch::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CChevSendRecSwitch::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/chev_send_rec_switch.h b/engines/titanic/gfx/chev_send_rec_switch.h new file mode 100644 index 0000000000..b3ccab2f09 --- /dev/null +++ b/engines/titanic/gfx/chev_send_rec_switch.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_CHEV_SEND_REC_SWITCH_H +#define TITANIC_CHEV_SEND_REC_SWITCH_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CChevSendRecSwitch : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CChevSendRecSwitch(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHEV_SEND_REC_SWITCH_H */ diff --git a/engines/titanic/gfx/chev_switch.cpp b/engines/titanic/gfx/chev_switch.cpp new file mode 100644 index 0000000000..a6ce93098c --- /dev/null +++ b/engines/titanic/gfx/chev_switch.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/gfx/chev_switch.h" + +namespace Titanic { + +CChevSwitch::CChevSwitch() : CToggleSwitch() { +} + +void CChevSwitch::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CChevSwitch::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/chev_switch.h b/engines/titanic/gfx/chev_switch.h new file mode 100644 index 0000000000..0305a6ca83 --- /dev/null +++ b/engines/titanic/gfx/chev_switch.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_CHEV_SWITCH_H +#define TITANIC_CHEV_SWITCH_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CChevSwitch : public CToggleSwitch { +public: + CLASSDEF; + CChevSwitch(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHEV_SWITCH_H */ diff --git a/engines/titanic/gfx/edit_control.cpp b/engines/titanic/gfx/edit_control.cpp new file mode 100644 index 0000000000..3b611e9bbe --- /dev/null +++ b/engines/titanic/gfx/edit_control.cpp @@ -0,0 +1,72 @@ +/* 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 "titanic/gfx/edit_control.h" + +namespace Titanic { + +CEditControl::CEditControl() : CGameObject(), _fieldBC(0), _fieldC0(0), + _fieldC4(0), _fieldC8(0), _fieldCC(0), _fieldD0(0), _fieldD4(2), + _fieldD8(0), _fieldDC(0), _fieldE0(0), _fieldF0(0), _fieldF4(0) + +{ +} + +void CEditControl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeNumberLine(_fieldCC, indent); + file->writeNumberLine(_fieldD0, indent); + file->writeNumberLine(_fieldD4, indent); + file->writeNumberLine(_fieldD8, indent); + file->writeNumberLine(_fieldDC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeQuotedLine(_string1, indent); + file->writeNumberLine(_fieldF0, indent); + file->writeNumberLine(_fieldF4, indent); + + CGameObject::save(file, indent); +} + +void CEditControl::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + _fieldC8 = file->readNumber(); + _fieldCC = file->readNumber(); + _fieldD0 = file->readNumber(); + _fieldD4 = file->readNumber(); + _fieldD8 = file->readNumber(); + _fieldDC = file->readNumber(); + _fieldE0 = file->readNumber(); + _string1 = file->readString(); + _fieldF0 = file->readNumber(); + _fieldF4 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/edit_control.h b/engines/titanic/gfx/edit_control.h new file mode 100644 index 0000000000..77d03cb225 --- /dev/null +++ b/engines/titanic/gfx/edit_control.h @@ -0,0 +1,62 @@ +/* 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 TITANIC_EDIT_CONTROL_H +#define TITANIC_EDIT_CONTROL_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CEditControl : public CGameObject { +protected: + int _fieldBC; + int _fieldC0; + int _fieldC4; + int _fieldC8; + int _fieldCC; + int _fieldD0; + int _fieldD4; + int _fieldD8; + int _fieldDC; + int _fieldE0; + CString _string1; + int _fieldF0; + int _fieldF4; +public: + CLASSDEF; + CEditControl(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EDIT_CONTROL_H */ diff --git a/engines/titanic/gfx/elevator_button.cpp b/engines/titanic/gfx/elevator_button.cpp new file mode 100644 index 0000000000..e66ee19af3 --- /dev/null +++ b/engines/titanic/gfx/elevator_button.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/elevator_button.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CElevatorButton, CSTButton); + +CElevatorButton::CElevatorButton() : CSTButton() { +} + +void CElevatorButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSTButton::save(file, indent); +} + +void CElevatorButton::load(SimpleFile *file) { + file->readNumber(); + CSTButton::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/elevator_button.h b/engines/titanic/gfx/elevator_button.h new file mode 100644 index 0000000000..28110d8102 --- /dev/null +++ b/engines/titanic/gfx/elevator_button.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_ELEVATOR_BUTTON_H +#define TITANIC_ELEVATOR_BUTTON_H + +#include "titanic/gfx/st_button.h" + +namespace Titanic { + +class CElevatorButton : public CSTButton { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CElevatorButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ELEVATOR_BUTTON_H */ diff --git a/engines/titanic/gfx/get_from_succ.cpp b/engines/titanic/gfx/get_from_succ.cpp new file mode 100644 index 0000000000..d701f73537 --- /dev/null +++ b/engines/titanic/gfx/get_from_succ.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/get_from_succ.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CGetFromSucc, CToggleSwitch); + +CGetFromSucc::CGetFromSucc() : CToggleSwitch() { +} + +void CGetFromSucc::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CGetFromSucc::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/get_from_succ.h b/engines/titanic/gfx/get_from_succ.h new file mode 100644 index 0000000000..f85f1b4cf2 --- /dev/null +++ b/engines/titanic/gfx/get_from_succ.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_GET_FROM_SUCC_H +#define TITANIC_GET_FROM_SUCC_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CGetFromSucc : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CGetFromSucc(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GET_FROM_SUCC_H */ diff --git a/engines/titanic/gfx/helmet_on_off.cpp b/engines/titanic/gfx/helmet_on_off.cpp new file mode 100644 index 0000000000..06e7d43d32 --- /dev/null +++ b/engines/titanic/gfx/helmet_on_off.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/helmet_on_off.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CHelmetOnOff, CToggleSwitch); + +CHelmetOnOff::CHelmetOnOff() : CToggleSwitch() { +} + +void CHelmetOnOff::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CHelmetOnOff::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/helmet_on_off.h b/engines/titanic/gfx/helmet_on_off.h new file mode 100644 index 0000000000..c2910eb59d --- /dev/null +++ b/engines/titanic/gfx/helmet_on_off.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_HELMET_ON_OFF_H +#define TITANIC_HELMET_ON_OFF_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CHelmetOnOff : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CHelmetOnOff(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HELMET_ON_OFF_H */ diff --git a/engines/titanic/gfx/home_photo.cpp b/engines/titanic/gfx/home_photo.cpp new file mode 100644 index 0000000000..758a5caa75 --- /dev/null +++ b/engines/titanic/gfx/home_photo.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/home_photo.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CHomePhoto, CToggleSwitch); + +CHomePhoto::CHomePhoto() : CToggleSwitch() { +} + +void CHomePhoto::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CHomePhoto::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/home_photo.h b/engines/titanic/gfx/home_photo.h new file mode 100644 index 0000000000..09b18b7c0f --- /dev/null +++ b/engines/titanic/gfx/home_photo.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_HOME_PHOTO_H +#define TITANIC_HOME_PHOTO_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CHomePhoto : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CHomePhoto(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_HOME_PHOTO_H */ diff --git a/engines/titanic/gfx/icon_nav_action.cpp b/engines/titanic/gfx/icon_nav_action.cpp new file mode 100644 index 0000000000..4d32f46571 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_action.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/icon_nav_action.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CIconNavAction, CToggleSwitch); + +CIconNavAction::CIconNavAction() : CToggleSwitch() { +} + +void CIconNavAction::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CIconNavAction::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/icon_nav_action.h b/engines/titanic/gfx/icon_nav_action.h new file mode 100644 index 0000000000..841334dd41 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_action.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_ICON_NAV_ACTION_H +#define TITANIC_ICON_NAV_ACTION_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CIconNavAction : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CIconNavAction(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ICON_NAV_ACTION_H */ diff --git a/engines/titanic/gfx/icon_nav_butt.cpp b/engines/titanic/gfx/icon_nav_butt.cpp new file mode 100644 index 0000000000..951c2f5e7b --- /dev/null +++ b/engines/titanic/gfx/icon_nav_butt.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/gfx/icon_nav_butt.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CIconNavButt, CPetGraphic); + +void CIconNavButt::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic::save(file, indent); +} + +void CIconNavButt::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/icon_nav_butt.h b/engines/titanic/gfx/icon_nav_butt.h new file mode 100644 index 0000000000..c60877e2c0 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_butt.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_ICON_NAV_BUTT_H +#define TITANIC_ICON_NAV_BUTT_H + +#include "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +class CIconNavButt : public CPetGraphic { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ICON_NAV_BUTT_H */ diff --git a/engines/titanic/gfx/icon_nav_down.cpp b/engines/titanic/gfx/icon_nav_down.cpp new file mode 100644 index 0000000000..efa2124b14 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_down.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/icon_nav_down.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CIconNavDown, CToggleSwitch); + +CIconNavDown::CIconNavDown() : CToggleSwitch() { +} + +void CIconNavDown::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CIconNavDown::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/icon_nav_down.h b/engines/titanic/gfx/icon_nav_down.h new file mode 100644 index 0000000000..6c0c2870e4 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_down.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_ICON_NAV_DOWN_H +#define TITANIC_ICON_NAV_DOWN_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CIconNavDown : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CIconNavDown(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ICON_NAV_DOWN_H */ diff --git a/engines/titanic/gfx/icon_nav_image.cpp b/engines/titanic/gfx/icon_nav_image.cpp new file mode 100644 index 0000000000..403ae44b17 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_image.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/gfx/icon_nav_image.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CIconNavImage, CPetGraphic); + +void CIconNavImage::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic::save(file, indent); +} + +void CIconNavImage::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/icon_nav_image.h b/engines/titanic/gfx/icon_nav_image.h new file mode 100644 index 0000000000..580762c32d --- /dev/null +++ b/engines/titanic/gfx/icon_nav_image.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_ICON_NAV_IMAGE_H +#define TITANIC_ICON_NAV_IMAGE_H + +#include "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +class CIconNavImage : public CPetGraphic { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ICON_NAV_IMAGE_H */ diff --git a/engines/titanic/gfx/icon_nav_left.cpp b/engines/titanic/gfx/icon_nav_left.cpp new file mode 100644 index 0000000000..8d98f3724c --- /dev/null +++ b/engines/titanic/gfx/icon_nav_left.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/icon_nav_left.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CIconNavLeft, CToggleSwitch); + +CIconNavLeft::CIconNavLeft() : CToggleSwitch() { +} + +void CIconNavLeft::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CIconNavLeft::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/icon_nav_left.h b/engines/titanic/gfx/icon_nav_left.h new file mode 100644 index 0000000000..bb61c26362 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_left.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_ICON_NAV_LEFT_H +#define TITANIC_ICON_NAV_LEFT_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CIconNavLeft : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CIconNavLeft(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ICON_NAV_LEFT_H */ diff --git a/engines/titanic/gfx/icon_nav_receive.cpp b/engines/titanic/gfx/icon_nav_receive.cpp new file mode 100644 index 0000000000..e3e0986690 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_receive.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/gfx/icon_nav_receive.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CIconNavReceive, CPetGraphic); + +void CIconNavReceive::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic::save(file, indent); +} + +void CIconNavReceive::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/icon_nav_receive.h b/engines/titanic/gfx/icon_nav_receive.h new file mode 100644 index 0000000000..0744105835 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_receive.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_ICON_NAV_RECEIVE_H +#define TITANIC_ICON_NAV_RECEIVE_H + +#include "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +class CIconNavReceive : public CPetGraphic { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ICON_NAV_RECEIVE_H */ diff --git a/engines/titanic/gfx/icon_nav_right.cpp b/engines/titanic/gfx/icon_nav_right.cpp new file mode 100644 index 0000000000..de827918e9 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_right.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/icon_nav_right.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CIconNavRight, CToggleSwitch); + +CIconNavRight::CIconNavRight() : CToggleSwitch() { +} + +void CIconNavRight::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CIconNavRight::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/icon_nav_right.h b/engines/titanic/gfx/icon_nav_right.h new file mode 100644 index 0000000000..a1bed9ca8f --- /dev/null +++ b/engines/titanic/gfx/icon_nav_right.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_ICON_NAV_RIGHT_H +#define TITANIC_ICON_NAV_RIGHT_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CIconNavRight : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CIconNavRight(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ICON_NAV_RIGHT_H */ diff --git a/engines/titanic/gfx/icon_nav_send.cpp b/engines/titanic/gfx/icon_nav_send.cpp new file mode 100644 index 0000000000..9baa9e8f33 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_send.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/gfx/icon_nav_send.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CIconNavSend, CPetGraphic); + +void CIconNavSend::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic::save(file, indent); +} + +void CIconNavSend::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/icon_nav_send.h b/engines/titanic/gfx/icon_nav_send.h new file mode 100644 index 0000000000..f3af8d9c65 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_send.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_ICON_NAV_SEND_H +#define TITANIC_ICON_NAV_SEND_H + +#include "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +class CIconNavSend : public CPetGraphic { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ICON_NAV_SEND_H */ diff --git a/engines/titanic/gfx/icon_nav_up.cpp b/engines/titanic/gfx/icon_nav_up.cpp new file mode 100644 index 0000000000..4268d97868 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_up.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/icon_nav_up.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CIconNavUp, CToggleSwitch); + +CIconNavUp::CIconNavUp() : CToggleSwitch() { +} + +void CIconNavUp::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CIconNavUp::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/icon_nav_up.h b/engines/titanic/gfx/icon_nav_up.h new file mode 100644 index 0000000000..4b7320d610 --- /dev/null +++ b/engines/titanic/gfx/icon_nav_up.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_ICON_NAV_UP_H +#define TITANIC_ICON_NAV_UP_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CIconNavUp : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CIconNavUp(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ICON_NAV_UP_H */ diff --git a/engines/titanic/gfx/keybrd_butt.cpp b/engines/titanic/gfx/keybrd_butt.cpp new file mode 100644 index 0000000000..063e709a7b --- /dev/null +++ b/engines/titanic/gfx/keybrd_butt.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/keybrd_butt.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CKeybrdButt, CToggleSwitch); + +CKeybrdButt::CKeybrdButt() : CToggleSwitch() { +} + +void CKeybrdButt::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CKeybrdButt::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/keybrd_butt.h b/engines/titanic/gfx/keybrd_butt.h new file mode 100644 index 0000000000..822be41ed2 --- /dev/null +++ b/engines/titanic/gfx/keybrd_butt.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_KEYBRD_BUTT_H +#define TITANIC_KEYBRD_BUTT_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CKeybrdButt : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CKeybrdButt(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_KEYBRD_BUTT_H */ diff --git a/engines/titanic/gfx/move_object_button.cpp b/engines/titanic/gfx/move_object_button.cpp new file mode 100644 index 0000000000..bdc90a673c --- /dev/null +++ b/engines/titanic/gfx/move_object_button.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/gfx/move_object_button.h" + +namespace Titanic { + +CMoveObjectButton::CMoveObjectButton() : CSTButton(), _field11C(1) { +} + +void CMoveObjectButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writePoint(_pos1, indent); + file->writeNumberLine(_field11C, indent); + + CSTButton::save(file, indent); +} + +void CMoveObjectButton::load(SimpleFile *file) { + file->readNumber(); + _pos1 = file->readPoint(); + _field11C = file->readNumber(); + + CSTButton::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/move_object_button.h b/engines/titanic/gfx/move_object_button.h new file mode 100644 index 0000000000..eb2fdc4ff2 --- /dev/null +++ b/engines/titanic/gfx/move_object_button.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_MOVE_OBJECT_BUTTON_H +#define TITANIC_MOVE_OBJECT_BUTTON_H + +#include "titanic/gfx/st_button.h" + +namespace Titanic { + +class CMoveObjectButton : public CSTButton { +private: + Point _pos1; + int _field11C; +public: + CLASSDEF; + CMoveObjectButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVE_OBJECT_BUTTON_H */ diff --git a/engines/titanic/gfx/music_control.cpp b/engines/titanic/gfx/music_control.cpp new file mode 100644 index 0000000000..85a3d777ef --- /dev/null +++ b/engines/titanic/gfx/music_control.cpp @@ -0,0 +1,51 @@ +/* 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 "titanic/gfx/music_control.h" + +namespace Titanic { + +CMusicControl::CMusicControl() : CBackground(), + _fieldE0(0), _fieldE4(0), _fieldE8(1), _fieldEC(1) { +} + +void CMusicControl::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + + CBackground::save(file, indent); +} + +void CMusicControl::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/music_control.h b/engines/titanic/gfx/music_control.h new file mode 100644 index 0000000000..04085f789c --- /dev/null +++ b/engines/titanic/gfx/music_control.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_MUSIC_CONTROL_H +#define TITANIC_MUSIC_CONTROL_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CMusicControl : public CBackground { +public: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; +public: + CLASSDEF; + CMusicControl(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_CONTROL_H */ diff --git a/engines/titanic/gfx/music_slider.cpp b/engines/titanic/gfx/music_slider.cpp new file mode 100644 index 0000000000..ec7ff5e3f6 --- /dev/null +++ b/engines/titanic/gfx/music_slider.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/gfx/music_slider.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CMusicSlider, CMusicControl); + +void CMusicSlider::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMusicControl::save(file, indent); +} + +void CMusicSlider::load(SimpleFile *file) { + file->readNumber(); + CMusicControl::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/music_slider.h b/engines/titanic/gfx/music_slider.h new file mode 100644 index 0000000000..be2c5631b6 --- /dev/null +++ b/engines/titanic/gfx/music_slider.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_MUSIC_SLIDER_H +#define TITANIC_MUSIC_SLIDER_H + +#include "titanic/gfx/music_control.h" + +namespace Titanic { + +class CMusicSlider : public CMusicControl { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_SLIDER_H */ diff --git a/engines/titanic/gfx/music_slider_pitch.h b/engines/titanic/gfx/music_slider_pitch.h new file mode 100644 index 0000000000..10c1d62c3a --- /dev/null +++ b/engines/titanic/gfx/music_slider_pitch.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_MUSIC_SLIDER_PITCH_H +#define TITANIC_MUSIC_SLIDER_PITCH_H + +#include "titanic/gfx/music_slider.h" + +namespace Titanic { + +class CMusicSliderPitch : public CMusicSlider { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMusicSlider::save(file, indent); + } + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file) { + file->readNumber(); + CMusicSlider::load(file); + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_SLIDER_PITCH_H */ diff --git a/engines/titanic/gfx/music_slider_speed.h b/engines/titanic/gfx/music_slider_speed.h new file mode 100644 index 0000000000..9814ca0312 --- /dev/null +++ b/engines/titanic/gfx/music_slider_speed.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_MUSIC_SLIDER_SPEED_H +#define TITANIC_MUSIC_SLIDER_SPEED_H + +#include "titanic/gfx/music_slider.h" + +namespace Titanic { + + class CMusicSliderSpeed : public CMusicSlider { + public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMusicSlider::save(file, indent); + } + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file) { + file->readNumber(); + CMusicSlider::load(file); + } + }; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_SLIDER_SPEED_H */ diff --git a/engines/titanic/gfx/music_switch.cpp b/engines/titanic/gfx/music_switch.cpp new file mode 100644 index 0000000000..1c2ced0b4e --- /dev/null +++ b/engines/titanic/gfx/music_switch.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/gfx/music_switch.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CMusicSwitch, CMusicControl); + +void CMusicSwitch::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMusicControl::save(file, indent); +} + +void CMusicSwitch::load(SimpleFile *file) { + file->readNumber(); + CMusicControl::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/music_switch.h b/engines/titanic/gfx/music_switch.h new file mode 100644 index 0000000000..35af84bdbf --- /dev/null +++ b/engines/titanic/gfx/music_switch.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_MUSIC_SWITCH_H +#define TITANIC_MUSIC_SWITCH_H + +#include "titanic/gfx/music_control.h" + +namespace Titanic { + +class CMusicSwitch : public CMusicControl { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_SWITCH_H */ diff --git a/engines/titanic/gfx/music_switch_inversion.h b/engines/titanic/gfx/music_switch_inversion.h new file mode 100644 index 0000000000..8b3718cf14 --- /dev/null +++ b/engines/titanic/gfx/music_switch_inversion.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_MUSIC_SWITCH_INVERSION_H +#define TITANIC_MUSIC_SWITCH_INVERSION_H + +#include "titanic/gfx/music_switch.h" + +namespace Titanic { + +class CMusicSwitchInversion : public CMusicSwitch { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMusicSwitch::save(file, indent); + } + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file) { + file->readNumber(); + CMusicSwitch::load(file); + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_SWITCH_INVERSION_H */ diff --git a/engines/titanic/gfx/music_switch_reverse.h b/engines/titanic/gfx/music_switch_reverse.h new file mode 100644 index 0000000000..3bfcb53b00 --- /dev/null +++ b/engines/titanic/gfx/music_switch_reverse.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_MUSIC_SWITCH_REVERSE_H +#define TITANIC_MUSIC_SWITCH_REVERSE_H + +#include "titanic/gfx/music_switch.h" + +namespace Titanic { + + class CMusicSwitchReverse : public CMusicSwitch { + public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMusicSwitch::save(file, indent); + } + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file) { + file->readNumber(); + CMusicSwitch::load(file); + } + }; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_SWITCH_REVERSE_H */ diff --git a/engines/titanic/gfx/music_voice_mute.h b/engines/titanic/gfx/music_voice_mute.h new file mode 100644 index 0000000000..ca15806c09 --- /dev/null +++ b/engines/titanic/gfx/music_voice_mute.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_MUSIC_VOICE_MUTE_H +#define TITANIC_MUSIC_VOICE_MUTE_H + +#include "titanic/gfx/music_control.h" + +namespace Titanic { + +class CMusicVoiceMute : public CMusicControl { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMusicControl::save(file, indent); + } + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file) { + file->readNumber(); + CMusicControl::load(file); + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_VOICE_MUTE_H */ diff --git a/engines/titanic/gfx/send_to_succ.cpp b/engines/titanic/gfx/send_to_succ.cpp new file mode 100644 index 0000000000..0e2b83361b --- /dev/null +++ b/engines/titanic/gfx/send_to_succ.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/send_to_succ.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CSendToSucc, CToggleSwitch); + +CSendToSucc::CSendToSucc() : CToggleSwitch() { +} + +void CSendToSucc::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CSendToSucc::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/send_to_succ.h b/engines/titanic/gfx/send_to_succ.h new file mode 100644 index 0000000000..734c4a7db3 --- /dev/null +++ b/engines/titanic/gfx/send_to_succ.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_SEND_TO_SUCC_H +#define TITANIC_SEND_TO_SUCC_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CSendToSucc : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CSendToSucc(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SEND_TO_SUCC_H */ diff --git a/engines/titanic/gfx/sgt_selector.cpp b/engines/titanic/gfx/sgt_selector.cpp new file mode 100644 index 0000000000..81cccb72ce --- /dev/null +++ b/engines/titanic/gfx/sgt_selector.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/gfx/sgt_selector.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CSGTSelector, CPetGraphic); + +void CSGTSelector::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic::save(file, indent); +} + +void CSGTSelector::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/sgt_selector.h b/engines/titanic/gfx/sgt_selector.h new file mode 100644 index 0000000000..be35635c2b --- /dev/null +++ b/engines/titanic/gfx/sgt_selector.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_SGT_SELECTOR_H +#define TITANIC_SGT_SELECTOR_H + +#include "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +class CSGTSelector : public CPetGraphic { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SGT_SELECTOR_H */ diff --git a/engines/titanic/gfx/slider_button.cpp b/engines/titanic/gfx/slider_button.cpp new file mode 100644 index 0000000000..0633158e97 --- /dev/null +++ b/engines/titanic/gfx/slider_button.cpp @@ -0,0 +1,51 @@ +/* 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 "titanic/gfx/slider_button.h" + +namespace Titanic { + +CSliderButton::CSliderButton() : CSTButton(), _field114(0), + _field118(0), _field11C(0) { +} + +void CSliderButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field114, indent); + file->writeNumberLine(_field118, indent); + file->writeNumberLine(_field11C, indent); + file->writePoint(_pos1, indent); + + CSTButton::save(file, indent); +} + +void CSliderButton::load(SimpleFile *file) { + file->readNumber(); + _field114 = file->readNumber(); + _field118 = file->readNumber(); + _field11C = file->readNumber(); + _pos1 = file->readPoint(); + + CSTButton::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/slider_button.h b/engines/titanic/gfx/slider_button.h new file mode 100644 index 0000000000..398290bb05 --- /dev/null +++ b/engines/titanic/gfx/slider_button.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_SLIDER_BUTTON_H +#define TITANIC_SLIDER_BUTTON_H + +#include "titanic/gfx/st_button.h" + +namespace Titanic { + +class CSliderButton : public CSTButton { +private: + int _field114; + int _field118; + int _field11C; + Point _pos1; +public: + CLASSDEF; + CSliderButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SLIDER_BUTTON_H */ diff --git a/engines/titanic/gfx/small_chev_left_off.cpp b/engines/titanic/gfx/small_chev_left_off.cpp new file mode 100644 index 0000000000..f7c27f9036 --- /dev/null +++ b/engines/titanic/gfx/small_chev_left_off.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/small_chev_left_off.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CSmallChevLeftOff, CToggleSwitch); + +CSmallChevLeftOff::CSmallChevLeftOff() : CToggleSwitch() { +} + +void CSmallChevLeftOff::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CSmallChevLeftOff::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/small_chev_left_off.h b/engines/titanic/gfx/small_chev_left_off.h new file mode 100644 index 0000000000..bed64befdb --- /dev/null +++ b/engines/titanic/gfx/small_chev_left_off.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_SMALL_CHEV_LEFT_OFF_H +#define TITANIC_SMALL_CHEV_LEFT_OFF_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CSmallChevLeftOff : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CSmallChevLeftOff(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SMALL_CHEV_LEFT_OFF_H */ diff --git a/engines/titanic/gfx/small_chev_left_on.cpp b/engines/titanic/gfx/small_chev_left_on.cpp new file mode 100644 index 0000000000..7a82c1878e --- /dev/null +++ b/engines/titanic/gfx/small_chev_left_on.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/small_chev_left_on.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CSmallChevLeftOn, CToggleSwitch); + +CSmallChevLeftOn::CSmallChevLeftOn() : CToggleSwitch() { +} + +void CSmallChevLeftOn::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CSmallChevLeftOn::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/small_chev_left_on.h b/engines/titanic/gfx/small_chev_left_on.h new file mode 100644 index 0000000000..9d1771311c --- /dev/null +++ b/engines/titanic/gfx/small_chev_left_on.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_SMALL_CHEV_LEFT_ON_H +#define TITANIC_SMALL_CHEV_LEFT_ON_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CSmallChevLeftOn : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CSmallChevLeftOn(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SMALL_CHEV_LEFT_ON_H */ diff --git a/engines/titanic/gfx/small_chev_right_off.cpp b/engines/titanic/gfx/small_chev_right_off.cpp new file mode 100644 index 0000000000..f07c5a3d00 --- /dev/null +++ b/engines/titanic/gfx/small_chev_right_off.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/small_chev_right_off.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CSmallChevRightOff, CToggleSwitch); + +CSmallChevRightOff::CSmallChevRightOff() : CToggleSwitch() { +} + +void CSmallChevRightOff::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CSmallChevRightOff::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/small_chev_right_off.h b/engines/titanic/gfx/small_chev_right_off.h new file mode 100644 index 0000000000..eb6ca455d2 --- /dev/null +++ b/engines/titanic/gfx/small_chev_right_off.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_SMALL_CHEV_RIGHT_OFF_H +#define TITANIC_SMALL_CHEV_RIGHT_OFF_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CSmallChevRightOff : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CSmallChevRightOff(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SMALL_CHEV_RIGHT_OFF_H */ diff --git a/engines/titanic/gfx/small_chev_right_on.cpp b/engines/titanic/gfx/small_chev_right_on.cpp new file mode 100644 index 0000000000..18aba4a91f --- /dev/null +++ b/engines/titanic/gfx/small_chev_right_on.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/gfx/small_chev_right_on.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CSmallChevRightOn, CToggleSwitch); + +CSmallChevRightOn::CSmallChevRightOn() : CToggleSwitch() { +} + +void CSmallChevRightOn::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CSmallChevRightOn::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/small_chev_right_on.h b/engines/titanic/gfx/small_chev_right_on.h new file mode 100644 index 0000000000..1dfb2d6fb2 --- /dev/null +++ b/engines/titanic/gfx/small_chev_right_on.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_SMALL_CHEV_RIGHT_ON_H +#define TITANIC_SMALL_CHEV_RIGHT_ON_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CSmallChevRightOn : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CSmallChevRightOn(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SMALL_CHEV_RIGHT_ON_H */ diff --git a/engines/titanic/gfx/st_button.cpp b/engines/titanic/gfx/st_button.cpp new file mode 100644 index 0000000000..6fc31f4c64 --- /dev/null +++ b/engines/titanic/gfx/st_button.cpp @@ -0,0 +1,96 @@ +/* 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 "titanic/gfx/st_button.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CSTButton, CBackground) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(MouseButtonUpMsg) + ON_MESSAGE(EnterViewMsg) +END_MESSAGE_MAP() + +CSTButton::CSTButton() : CBackground() { + _statusInc = 0; + _actionTarget = "NULL"; + _fieldF0 = 0; + _currentStatus = 0; + _actionName = "NULL"; + _soundName = "NULL"; + _buttonFrame = 0; +} + +void CSTButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_statusInc, indent); + file->writeQuotedLine(_actionTarget, indent); + file->writeNumberLine(_fieldF0, indent); + file->writeNumberLine(_currentStatus, indent); + file->writeQuotedLine(_actionName, indent); + file->writeQuotedLine(_soundName, indent); + file->writeNumberLine(_buttonFrame, indent); + + CBackground::save(file, indent); +} + +void CSTButton::load(SimpleFile *file) { + file->readNumber(); + _statusInc = file->readNumber(); + _actionTarget = file->readString(); + _fieldF0 = file->readNumber(); + _currentStatus = file->readNumber(); + _actionName = file->readString(); + _soundName = file->readString(); + _buttonFrame = file->readNumber() != 0; + + CBackground::load(file); +} + +bool CSTButton::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + playMovie(0); + playSound(_soundName, 100, 0, 0); + + return true; +} + +bool CSTButton::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + int oldStatus = _currentStatus; + int newStatus = _currentStatus + _statusInc; + + CStatusChangeMsg statusMsg(oldStatus, newStatus, false); + _currentStatus = newStatus; + statusMsg.execute(_actionTarget); + + if (!statusMsg._success) { + _currentStatus -= _statusInc; + } + + return true; +} + +bool CSTButton::EnterViewMsg(CEnterViewMsg *msg) { + loadFrame(_buttonFrame); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/st_button.h b/engines/titanic/gfx/st_button.h new file mode 100644 index 0000000000..444c883f59 --- /dev/null +++ b/engines/titanic/gfx/st_button.h @@ -0,0 +1,62 @@ +/* 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 TITANIC_ST_BUTTON_H +#define TITANIC_ST_BUTTON_H + +#include "titanic/core/background.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CSTButton : public CBackground { + DECLARE_MESSAGE_MAP; + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); + bool EnterViewMsg(CEnterViewMsg *msg); +protected: + int _statusInc; + CString _actionTarget; + int _fieldF0; + int _currentStatus; + CString _actionName; + CString _soundName; + int _buttonFrame; +public: + CLASSDEF; + CSTButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ST_BUTTON_H */ diff --git a/engines/titanic/gfx/status_change_button.cpp b/engines/titanic/gfx/status_change_button.cpp new file mode 100644 index 0000000000..6644247ff2 --- /dev/null +++ b/engines/titanic/gfx/status_change_button.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/gfx/status_change_button.h" + +namespace Titanic { + +CStatusChangeButton::CStatusChangeButton() : CSTButton() { +} + +void CStatusChangeButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CSTButton::save(file, indent); +} + +void CStatusChangeButton::load(SimpleFile *file) { + file->readNumber(); + CSTButton::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/status_change_button.h b/engines/titanic/gfx/status_change_button.h new file mode 100644 index 0000000000..9e410c66f2 --- /dev/null +++ b/engines/titanic/gfx/status_change_button.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_STATUS_CHANGE_BUTTON_H +#define TITANIC_STATUS_CHANGE_BUTTON_H + +#include "titanic/gfx/st_button.h" + +namespace Titanic { + +class CStatusChangeButton : public CSTButton { +public: + CLASSDEF; + CStatusChangeButton(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STATUS_CHANGE_BUTTON_H */ diff --git a/engines/titanic/gfx/text_down.cpp b/engines/titanic/gfx/text_down.cpp new file mode 100644 index 0000000000..4d9bb0b077 --- /dev/null +++ b/engines/titanic/gfx/text_down.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/gfx/text_down.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CTextDown, CPetGraphic); + +void CTextDown::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic::save(file, indent); +} + +void CTextDown::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/text_down.h b/engines/titanic/gfx/text_down.h new file mode 100644 index 0000000000..97660605d5 --- /dev/null +++ b/engines/titanic/gfx/text_down.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_TEXT_DOWN_H +#define TITANIC_TEXT_DOWN_H + +#include "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +class CTextDown : public CPetGraphic { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TEXT_DOWN_H */ diff --git a/engines/titanic/gfx/text_skrew.cpp b/engines/titanic/gfx/text_skrew.cpp new file mode 100644 index 0000000000..6d403eabfb --- /dev/null +++ b/engines/titanic/gfx/text_skrew.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/gfx/text_skrew.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CTextSkrew, CPetGraphic); + +void CTextSkrew::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic::save(file, indent); +} + +void CTextSkrew::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/text_skrew.h b/engines/titanic/gfx/text_skrew.h new file mode 100644 index 0000000000..d0d9b82afd --- /dev/null +++ b/engines/titanic/gfx/text_skrew.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_TEXT_SKREW_H +#define TITANIC_TEXT_SKREW_H + +#include "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +class CTextSkrew : public CPetGraphic { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TEXT_SKREW_H */ diff --git a/engines/titanic/gfx/text_up.cpp b/engines/titanic/gfx/text_up.cpp new file mode 100644 index 0000000000..842be63ee6 --- /dev/null +++ b/engines/titanic/gfx/text_up.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/gfx/text_up.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CTextUp, CPetGraphic); + +void CTextUp::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic::save(file, indent); +} + +void CTextUp::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/text_up.h b/engines/titanic/gfx/text_up.h new file mode 100644 index 0000000000..dda8d8461b --- /dev/null +++ b/engines/titanic/gfx/text_up.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_TEXT_UP_H +#define TITANIC_TEXT_UP_H + +#include "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +class CTextUp : public CPetGraphic { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TEXT_UP_H */ diff --git a/engines/titanic/gfx/toggle_button.cpp b/engines/titanic/gfx/toggle_button.cpp new file mode 100644 index 0000000000..2b7c80d3df --- /dev/null +++ b/engines/titanic/gfx/toggle_button.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/gfx/toggle_button.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CToggleButton, CBackground); + +void CToggleButton::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + + CBackground::save(file, indent); +} + +void CToggleButton::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/toggle_button.h b/engines/titanic/gfx/toggle_button.h new file mode 100644 index 0000000000..5328072982 --- /dev/null +++ b/engines/titanic/gfx/toggle_button.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_TOGGLE_BUTTON_H +#define TITANIC_TOGGLE_BUTTON_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CToggleButton : public CBackground { + DECLARE_MESSAGE_MAP; +private: + int _fieldE0; +public: + CLASSDEF; + CToggleButton() : CBackground(), _fieldE0(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TOGGLE_BUTTON_H */ diff --git a/engines/titanic/gfx/toggle_switch.cpp b/engines/titanic/gfx/toggle_switch.cpp new file mode 100644 index 0000000000..20cbb863ee --- /dev/null +++ b/engines/titanic/gfx/toggle_switch.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +CToggleSwitch::CToggleSwitch() : CGameObject(), _fieldBC(0) { +} + +void CToggleSwitch::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writePoint(_pos1, indent); + + CGameObject::save(file, indent); +} + +void CToggleSwitch::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _pos1 = file->readPoint(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/gfx/toggle_switch.h b/engines/titanic/gfx/toggle_switch.h new file mode 100644 index 0000000000..ae96c75ebd --- /dev/null +++ b/engines/titanic/gfx/toggle_switch.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_TOGGLE_SWITCH_H +#define TITANIC_TOGGLE_SWITCH_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CToggleSwitch : public CGameObject { +private: + int _fieldBC; + Point _pos1; +public: + CLASSDEF; + CToggleSwitch(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TOGGLE_SWITCH_H */ diff --git a/engines/titanic/input_handler.cpp b/engines/titanic/input_handler.cpp new file mode 100644 index 0000000000..7c35a5d855 --- /dev/null +++ b/engines/titanic/input_handler.cpp @@ -0,0 +1,177 @@ +/* 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 "titanic/input_handler.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/support/screen_manager.h" + +namespace Titanic { + +CInputHandler::CInputHandler(CGameManager *owner) : + _gameManager(owner), _inputTranslator(nullptr), _dragging(false), + _buttonDown(false), _dragItem(nullptr), _lockCount(0), + _singleton(false) { + CScreenManager::_screenManagerPtr->_inputHandler = this; +} + +void CInputHandler::setTranslator(CInputTranslator *translator) { + _inputTranslator = translator; +} + +void CInputHandler::incLockCount() { + ++_lockCount; +} + +void CInputHandler::decLockCount() { + if (--_lockCount == 0 && _inputTranslator) { + if (_dragging && !_inputTranslator->isMousePressed()) { + CMouseButtonUpMsg upMsg(_mousePos, MK_LBUTTON); + handleMessage(upMsg); + } + + _buttonDown = _inputTranslator->isMousePressed(); + _singleton = true; + } +} + +void CInputHandler::handleMessage(CMessage &msg, bool respectLock) { + if (!respectLock || _lockCount <= 0) { + if (_gameManager->_gameState._mode == GSMODE_INTERACTIVE) { + processMessage(&msg); + } else if (!msg.isMouseMsg()) { + g_vm->_filesManager->loadDrive(); + } + } +} + +void CInputHandler::processMessage(CMessage *msg) { + const CMouseMsg *mouseMsg = dynamic_cast<const CMouseMsg *>(msg); + _singleton = false; + dispatchMessage(msg); + + if (_singleton) { + _singleton = false; + } else if (mouseMsg) { + // Keep the game state mouse position up to date + if (_mousePos != mouseMsg->_mousePos) { + _mousePos = mouseMsg->_mousePos; + _gameManager->_gameState.setMousePos(mouseMsg->_mousePos); + } + + // Set flag for whether a mouse button is currently being pressed + if (mouseMsg->isButtonDownMsg()) + _buttonDown = true; + else if (mouseMsg->isButtonUpMsg()) + _buttonDown = false; + + // Drag events generation + if (_dragging) { + if (mouseMsg->isMouseMoveMsg()) { + if (_dragItem) { + CMouseDragMoveMsg moveMsg(_mousePos); + moveMsg.execute(_dragItem); + } + } else { + if (mouseMsg->isButtonUpMsg() && _dragItem) { + // Mouse drag ended + CGameObject *target = dragEnd(_mousePos, _dragItem); + CMouseDragEndMsg endMsg(_mousePos, target); + endMsg.execute(_dragItem); + } + + _dragging = false; + _dragItem = nullptr; + } + } else if (_buttonDown) { + if (!mouseMsg->isMouseMoveMsg()) { + // Save where the drag movement started from + _dragStartPos = _mousePos; + } else { + Point delta = mouseMsg->_mousePos - _dragStartPos; + int distance = (int)sqrt(double(delta.x * delta.x + delta.y * delta.y)); + + if (distance > 4) { + // We've moved far enough with the mouse button held down + // to trigger an official dragging operation + CMouseDragStartMsg startMsg(_dragStartPos); + dispatchMessage(&startMsg); + + // Set the drag item, if any, that a handler will have set on the message + _dragItem = startMsg._dragItem; + _gameManager->_dragItem = startMsg._dragItem; + + if (_dragItem) { + CMouseDragMoveMsg moveMsg(_dragStartPos); + dispatchMessage(&moveMsg); + } + + _dragging = true; + } + } + } + } +} + +void CInputHandler::dispatchMessage(CMessage *msg) { + CPetControl *pet = _gameManager->_project->getPetControl(); + if (!pet || !msg->execute(pet, nullptr, MSGFLAG_BREAK_IF_HANDLED)) { + CViewItem *view = _gameManager->getView(); + msg->execute(view); + } +} + +CGameObject *CInputHandler::dragEnd(const Point &pt, CTreeItem *dragItem) { + CViewItem *view = _gameManager->getView(); + if (!view) + return nullptr; + + // Scan through the view items to find the item being dropped on + CGameObject *target = nullptr; + for (CTreeItem *treeItem = view->scan(view); treeItem; treeItem = treeItem->scan(view)) { + CGameObject *gameObject = static_cast<CGameObject *>(treeItem); + if (gameObject && gameObject != dragItem) { + if (gameObject->checkPoint(pt)) + target = gameObject; + } + } + + if (target) { + // Check if the cursor is on the PET. If so, pass to the PET + // to see what specific element the drag ended on + CProjectItem *project = view->getRoot(); + if (project) { + CPetControl *petControl = project->getPetControl(); + if (petControl && petControl->contains(pt)) { + target = petControl->dragEnd(pt); + if (!target) + target = petControl; + } + } + } + + return target; +} + +} // End of namespace Titanic diff --git a/engines/titanic/input_handler.h b/engines/titanic/input_handler.h new file mode 100644 index 0000000000..7244ddc050 --- /dev/null +++ b/engines/titanic/input_handler.h @@ -0,0 +1,83 @@ +/* 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 TITANIC_INPUT_HANDLER_H +#define TITANIC_INPUT_HANDLER_H + +#include "titanic/support/rect.h" +#include "titanic/input_translator.h" +#include "titanic/core/tree_item.h" + +namespace Titanic { + +class CGameManager; + +class CInputHandler { +private: + /** + * Process and dispatch a passed message + */ + void processMessage(CMessage *msg); + + /** + * Dispatches a message to the project + */ + void dispatchMessage(CMessage *msg); + + /** + * Called when a drag operation has ended + */ + CGameObject *dragEnd(const Point &pt, CTreeItem *dragItem); +public: + CGameManager *_gameManager; + CInputTranslator *_inputTranslator; + bool _dragging; + bool _buttonDown; + CTreeItem *_dragItem; + Point _dragStartPos; + Point _mousePos; + int _lockCount; + bool _singleton; +public: + CInputHandler(CGameManager *owner); + + void setTranslator(CInputTranslator *translator); + + /** + * Increment the lock count + */ + void incLockCount(); + + /** + * Decrement the lock count on the input handler + */ + void decLockCount(); + + /** + * Handles a genereated mouse message + */ + void handleMessage(CMessage &msg, bool respectLock = true); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_INPUT_HANDLER_H */ diff --git a/engines/titanic/input_translator.cpp b/engines/titanic/input_translator.cpp new file mode 100644 index 0000000000..ce272d152c --- /dev/null +++ b/engines/titanic/input_translator.cpp @@ -0,0 +1,114 @@ +/* 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 "titanic/input_handler.h" +#include "titanic/input_translator.h" +#include "titanic/events.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CInputTranslator::CInputTranslator(CInputHandler *inputHandler) : + _inputHandler(inputHandler) { + inputHandler->setTranslator(this); +} + +int CInputTranslator::getButtons(int special) const { + int buttons = 0; + if (special & MK_LBUTTON) + buttons |= MB_LEFT; + if (special & MK_MBUTTON) + buttons |= MB_MIDDLE; + if (special & MK_RBUTTON) + buttons |= MB_RIGHT; + + return buttons; +} + +void CInputTranslator::mouseMove(int special, const Point &pt) { + CMouseMoveMsg msg(pt, getButtons(special)); + _inputHandler->handleMessage(msg); +} + +void CInputTranslator::leftButtonDown(int special, const Point &pt) { + CMouseButtonDownMsg msg(pt, MB_LEFT); + _inputHandler->handleMessage(msg); +} + +void CInputTranslator::leftButtonUp(int special, const Point &pt) { + CMouseButtonUpMsg msg(pt, MB_LEFT); + _inputHandler->handleMessage(msg); +} + +void CInputTranslator::leftButtonDoubleClick(int special, const Point &pt) { + CMouseDoubleClickMsg msg(pt, MB_LEFT); + _inputHandler->handleMessage(msg); +} + +void CInputTranslator::middleButtonDown(int special, const Point &pt) { + CMouseButtonDownMsg msg(pt, MB_MIDDLE); + _inputHandler->handleMessage(msg); +} + +void CInputTranslator::middleButtonUp(int special, const Point &pt) { + CMouseButtonUpMsg msg(pt, MB_MIDDLE); + _inputHandler->handleMessage(msg); +} + +void CInputTranslator::middleButtonDoubleClick(int special, const Point &pt) { + CMouseDoubleClickMsg msg(pt, MB_MIDDLE); + _inputHandler->handleMessage(msg); +} + +void CInputTranslator::rightButtonDown(int special, const Point &pt) { + CMouseButtonDownMsg msg(pt, MB_RIGHT); + _inputHandler->handleMessage(msg); +} + +void CInputTranslator::rightButtonUp(int special, const Point &pt) { + CMouseButtonUpMsg msg(pt, MB_RIGHT); + _inputHandler->handleMessage(msg); +} + +void CInputTranslator::rightButtonDoubleClick(int special, const Point &pt) { + CMouseDoubleClickMsg msg(pt, MB_RIGHT); + _inputHandler->handleMessage(msg); +} + +void CInputTranslator::keyDown(const Common::KeyState &keyState) { + if (keyState.keycode >= Common::KEYCODE_F1 && keyState.keycode <= Common::KEYCODE_F5) { + CVirtualKeyCharMsg msg(keyState); + _inputHandler->handleMessage(msg); + } + + if (keyState.ascii <= 127) { + CKeyCharMsg msg(keyState.ascii); + _inputHandler->handleMessage(msg); + } +} + +bool CInputTranslator::isMousePressed() const { + return g_vm->_window->getSpecialButtons() & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON); +} + +} // End of namespace Titanic diff --git a/engines/titanic/input_translator.h b/engines/titanic/input_translator.h new file mode 100644 index 0000000000..d92157bccc --- /dev/null +++ b/engines/titanic/input_translator.h @@ -0,0 +1,64 @@ +/* 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 TITANIC_INPUT_TRANSLATOR_H +#define TITANIC_INPUT_TRANSLATOR_H + +#include "common/keyboard.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +class CInputHandler; + +class CInputTranslator { +private: + /** + * Converts the special buttons bitset into a buttons bitset + */ + int getButtons(int special) const; +public: + CInputHandler *_inputHandler; +public: + CInputTranslator(CInputHandler *inputHandler); + + void mouseMove(int special, const Point &pt); + void leftButtonDown(int special, const Point &pt); + void leftButtonUp(int special, const Point &pt); + void leftButtonDoubleClick(int special, const Point &pt); + void middleButtonDown(int special, const Point &pt); + void middleButtonUp(int special, const Point &pt); + void middleButtonDoubleClick(int special, const Point &pt); + void rightButtonDown(int special, const Point &pt); + void rightButtonUp(int special, const Point &pt); + void rightButtonDoubleClick(int special, const Point &pt); + void keyDown(const Common::KeyState &keyState); + + /** + * Returns true if any mouse button is currently pressed + */ + bool isMousePressed() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_INPUT_TRANSLATOR_H */ diff --git a/engines/titanic/main_game_window.cpp b/engines/titanic/main_game_window.cpp new file mode 100644 index 0000000000..486bc417d7 --- /dev/null +++ b/engines/titanic/main_game_window.cpp @@ -0,0 +1,350 @@ +/* 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 "titanic/titanic.h" +#include "titanic/continue_save_dialog.h" +#include "titanic/game_manager.h" +#include "titanic/game_view.h" +#include "titanic/main_game_window.h" +#include "titanic/messages/messages.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +CMainGameWindow::CMainGameWindow(TitanicEngine *vm): _vm(vm), + _specialButtons(0), _priorLeftDownTime(0), + _priorMiddleDownTime(0), _priorRightDownTime(0) { + _gameView = nullptr; + _gameManager = nullptr; + _project = nullptr; + _inputAllowed = false; + _image = nullptr; + _cursor = nullptr; + _pendingLoadSlot = -1; + + // Set the window as an event target + vm->_events->addTarget(this); +} + +CMainGameWindow::~CMainGameWindow() { +} + +bool CMainGameWindow::Create() { + Image image; + image.load("TITANIC"); + + // TODO: Stuff + return true; +} + +void CMainGameWindow::applicationStarting() { + // Set the video mode + CScreenManager *screenManager = CScreenManager::setCurrent(); + screenManager->setMode(640, 480, 16, 0, true); + + // Set up the game project, and get game slot + int saveSlot = getSavegameSlot(); + if (saveSlot == -2) + return; + + // Create game view and manager + _gameView = new CSTGameView(this); + _gameManager = new CGameManager(_project, _gameView, g_vm->_mixer); + _gameView->setGameManager(_gameManager); + + // Load either a new game or selected existing save + _project->loadGame(saveSlot); + _inputAllowed = true; + _gameManager->_gameState.setMode(GSMODE_INTERACTIVE); + + // TODO: Cursor/image + + // Generate starting messages for entering the view, node, and room. + // Note the old fields are nullptr, since there's no previous view/node/room + CViewItem *view = _gameManager->_gameState._gameLocation.getView(); + CEnterViewMsg enterViewMsg(nullptr, view); + enterViewMsg.execute(view, nullptr, MSGFLAG_SCAN); + + CNodeItem *node = view->findNode(); + CEnterNodeMsg enterNodeMsg(nullptr, node); + enterNodeMsg.execute(node, nullptr, MSGFLAG_SCAN); + + CRoomItem *room = view->findRoom(); + CEnterRoomMsg enterRoomMsg(nullptr, room); + enterRoomMsg.execute(room, nullptr, MSGFLAG_SCAN); + + _gameManager->initBounds(); +} + +int CMainGameWindow::getSavegameSlot() { + _project = new CProjectItem(); + _project->setFilename("starship.prj"); + + return selectSavegame(); +} + +int CMainGameWindow::selectSavegame() { + // If the user selected a savegame from the launcher, return it + if (ConfMan.hasKey("save_slot")) + return ConfMan.getInt("save_slot"); + + CContinueSaveDialog dialog; + bool hasSavegames = false; + + // Loop through save slots to find any existing save slots + for (int idx = 0; idx < MAX_SAVES; ++idx) { + CString saveName = g_vm->getSavegameName(idx); + if (!saveName.empty()) { + dialog.addSavegame(idx, saveName); + hasSavegames = true; + } + } + + // If there are savegames, show the select dialog and get a choice. + // If there aren't, return -1 to indicate starting a new game + return hasSavegames ? dialog.show() : -1; +} + +void CMainGameWindow::setActiveView(CViewItem *viewItem) { + _gameManager->_gameState._gameLocation.setView(viewItem); + + CResourceKey key; + if (viewItem->getResourceKey(&key)) { + // Create a surface based on the key + _gameView->createSurface(key); + } +} + +void CMainGameWindow::draw() { + if (_gameManager) { + if (!_gameView->_surface) { + CViewItem *view = _gameManager->getView(); + if (view) + setActiveView(view); + } + + CScreenManager *scrManager = CScreenManager::setCurrent(); + scrManager->clearSurface(SURFACE_BACKBUFFER, &_gameManager->_bounds); + + switch (_gameManager->_gameState._mode) { + case GSMODE_INTERACTIVE: + case GSMODE_CUTSCENE: + if (_gameManager->_gameState._petActive) + drawPet(scrManager); + + drawView(); + drawViewContents(scrManager); + scrManager->drawCursors(); + break; + + case GSMODE_5: + g_vm->_filesManager->debug(scrManager); + break; + + case GSMODE_PENDING_LOAD: + // Pending savegame to load + _gameManager->_gameState.setMode(GSMODE_INTERACTIVE); + _vm->_window->_project->loadGame(_pendingLoadSlot); + break; + + default: + break; + } + } +} + +void CMainGameWindow::drawPet(CScreenManager *screenManager) { + if (_gameView && _gameView->_surface) { + CPetControl *petControl = _gameManager->_project->getPetControl(); + if (petControl) + petControl->draw(screenManager); + } +} + +void CMainGameWindow::drawView() { + if (_gameView->_surface) + _gameView->drawView(); +} + +void CMainGameWindow::drawViewContents(CScreenManager *screenManager) { + // Get a reference to the reference, validating that it's present + if (!screenManager) + return; + CViewItem *view = _gameManager->getView(); + if (!view) + return; + CNodeItem *node = view->findNode(); + if (!node) + return; + CRoomItem *room = node->findRoom(); + if (!room) + return; + + double xVal = 0.0, yVal = 0.0; + room->calcNodePosition(node->_nodePos, xVal, yVal); + + // Iterate through drawing all the items in the scene except any item + // that's currently being dragged + for (CTreeItem *treeItem = view; treeItem; treeItem = treeItem->scan(view)) { + if (treeItem != _gameManager->_dragItem) + treeItem->draw(screenManager); + } + + // Finally draw the drag item if there is one + if (_gameManager->_dragItem) + _gameManager->_dragItem->draw(screenManager); +} + +void CMainGameWindow::mouseChanged() { + if (_gameManager->_gameState._mode != GSMODE_5) + _gameManager->update(); +} + +void CMainGameWindow::loadGame(int slotId) { + _pendingLoadSlot = slotId; + _gameManager->_gameState.setMode(GSMODE_PENDING_LOAD); +} + +void CMainGameWindow::onIdle() { + if (!_inputAllowed) + return; + CGameManager *gameManager = _gameManager; + if (!gameManager) + return; + + // Let the game manager perform any game updates + gameManager->update(); + + if (gameManager->_gameState._quitGame) { + // Game needs to shut down + _vm->quitGame(); + } +} + +#define HANDLE_MESSAGE(METHOD) if (_inputAllowed) { \ + _gameManager->_inputTranslator.METHOD(_specialButtons, mousePos); \ + mouseChanged(); \ + } + + +void CMainGameWindow::mouseMove(const Point &mousePos) { + HANDLE_MESSAGE(mouseMove) +} + +void CMainGameWindow::leftButtonDown(const Point &mousePos) { + _specialButtons |= MK_LBUTTON; + + if ((_vm->_events->getTicksCount() - _priorLeftDownTime) < DOUBLE_CLICK_TIME) { + _priorLeftDownTime = 0; + leftButtonDoubleClick(mousePos); + } else { + _priorLeftDownTime = _vm->_events->getTicksCount(); + HANDLE_MESSAGE(leftButtonDown) + } +} + +void CMainGameWindow::leftButtonUp(const Point &mousePos) { + _specialButtons &= ~MK_LBUTTON; + HANDLE_MESSAGE(leftButtonUp) +} + +void CMainGameWindow::leftButtonDoubleClick(const Point &mousePos) { + HANDLE_MESSAGE(leftButtonDoubleClick) +} + +void CMainGameWindow::middleButtonDown(const Point &mousePos) { + _specialButtons |= MK_MBUTTON; + + if ((_vm->_events->getTicksCount() - _priorMiddleDownTime) < DOUBLE_CLICK_TIME) { + _priorMiddleDownTime = 0; + middleButtonDoubleClick(mousePos); + } else { + _priorMiddleDownTime = _vm->_events->getTicksCount(); + HANDLE_MESSAGE(middleButtonDown) + } +} + +void CMainGameWindow::middleButtonUp(const Point &mousePos) { + _specialButtons &= ~MK_MBUTTON; + HANDLE_MESSAGE(middleButtonUp) +} + +void CMainGameWindow::middleButtonDoubleClick(const Point &mousePos) { + HANDLE_MESSAGE(middleButtonDoubleClick) +} + +void CMainGameWindow::rightButtonDown(const Point &mousePos) { + _specialButtons |= MK_RBUTTON; + + if ((_vm->_events->getTicksCount() - _priorRightDownTime) < DOUBLE_CLICK_TIME) { + _priorRightDownTime = 0; + rightButtonDoubleClick(mousePos); + } else { + _priorRightDownTime = _vm->_events->getTicksCount(); + HANDLE_MESSAGE(rightButtonDown) + } +} + +void CMainGameWindow::rightButtonUp(const Point &mousePos) { + _specialButtons &= ~MK_RBUTTON; + HANDLE_MESSAGE(rightButtonUp) +} + +void CMainGameWindow::rightButtonDoubleClick(const Point &mousePos) { + HANDLE_MESSAGE(rightButtonDoubleClick) +} + +void CMainGameWindow::charPress(char c) { + +} + +void CMainGameWindow::keyDown(Common::KeyState keyState) { + handleKbdSpecial(keyState); + + if (keyState.keycode == Common::KEYCODE_d && (keyState.flags & Common::KBD_CTRL)) { + // Attach to the debugger + _vm->_debugger->attach(); + _vm->_debugger->onFrame(); + } + + if (_inputAllowed) + _gameManager->_inputTranslator.keyDown(keyState); +} + +void CMainGameWindow::keyUp(Common::KeyState keyState) { + handleKbdSpecial(keyState); +} + +void CMainGameWindow::handleKbdSpecial(Common::KeyState keyState) { + if (keyState.flags & Common::KBD_CTRL) + _specialButtons |= MK_CONTROL; + else + _specialButtons &= ~MK_CONTROL; + + if (keyState.flags & Common::KBD_SHIFT) + _specialButtons |= MK_SHIFT; + else + _specialButtons &= ~MK_SHIFT; +} + +} // End of namespace Titanic diff --git a/engines/titanic/main_game_window.h b/engines/titanic/main_game_window.h new file mode 100644 index 0000000000..82e24e250e --- /dev/null +++ b/engines/titanic/main_game_window.h @@ -0,0 +1,149 @@ +/* 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 TITANIC_MAIN_GAME_WINDOW_H +#define TITANIC_MAIN_GAME_WINDOW_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "titanic/game_manager.h" +#include "titanic/game_view.h" +#include "titanic/support/image.h" +#include "titanic/core/project_item.h" +#include "titanic/events.h" + +namespace Titanic { + +class TitanicEngine; + +class CMainGameWindow : public CEventTarget { +private: + TitanicEngine *_vm; + int _pendingLoadSlot; + uint _specialButtons; + uint32 _priorFrameTime; + uint32 _priorLeftDownTime; + uint32 _priorMiddleDownTime; + uint32 _priorRightDownTime; +private: + /** + * Checks for the presence of any savegames and, if present, + * lets the user pick one to resume + */ + int getSavegameSlot(); + + /** + * Creates the game "project" and determine a game save slot + * to use + */ + int selectSavegame(); + + /** + * Used for drawing the PET fullscreen? maybe + */ + void drawPet(CScreenManager *screenManager); + + /** + * Draws the background for the view + */ + void drawView(); + + /** + * Draws all the items within the view + */ + void drawViewContents(CScreenManager *screenManager); + + void leftButtonDoubleClick(const Point &mousePos); + void middleButtonDoubleClick(const Point &mousePos); + void rightButtonDoubleClick(const Point &mousePos); + void charPress(char c); + void handleKbdSpecial(Common::KeyState keyState); +public: + CGameView *_gameView; + CGameManager *_gameManager; + CProjectItem *_project; + bool _inputAllowed; + Image *_image; + void *_cursor; +public: + CMainGameWindow(TitanicEngine *vm); + virtual ~CMainGameWindow(); + + /** + * Called to handle any regular updates the game requires + */ + void onIdle(); + + virtual void mouseMove(const Point &mousePos); + virtual void leftButtonDown(const Point &mousePos); + virtual void leftButtonUp(const Point &mousePos); + virtual void middleButtonDown(const Point &mousePos); + virtual void middleButtonUp(const Point &mousePos); + virtual void rightButtonDown(const Point &mousePos); + virtual void rightButtonUp(const Point &mousePos); + virtual void keyDown(Common::KeyState keyState); + virtual void keyUp(Common::KeyState keyState); + + /** + * Creates the window + */ + bool Create(); + + /** + * Called when the application starts + */ + void applicationStarting(); + + /** + * Sets the view to be shown + */ + void setActiveView(CViewItem *viewItem); + + /** + * Main draw method for the window + */ + void draw(); + + /** + * Called by the event handler when a mouse event has been generated + */ + void mouseChanged(); + + /** + * Schedules a savegame to be loaded + */ + void loadGame(int slotId); + + /* + * Return whether a given special key is currently pressed + */ + bool isSpecialPressed(SpecialButtons btn) const { return _specialButtons; } + + /** + * Returns the bitset of the currently pressed special buttons + */ + uint getSpecialButtons() const { return _specialButtons; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MAIN_GAME_WINDOW_H */ diff --git a/engines/titanic/messages/auto_sound_event.cpp b/engines/titanic/messages/auto_sound_event.cpp new file mode 100644 index 0000000000..bc2cd7d074 --- /dev/null +++ b/engines/titanic/messages/auto_sound_event.cpp @@ -0,0 +1,57 @@ +/* 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 "titanic/messages/auto_sound_event.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CAutoSoundEvent, CGameObject) + ON_MESSAGE(FrameMsg) +END_MESSAGE_MAP() + +CAutoSoundEvent::CAutoSoundEvent() : CGameObject(), _value1(0), _value2(0xFFFFFF) { +} + +void CAutoSoundEvent::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value1, indent); + file->writeNumberLine(_value2, indent); + + CGameObject::save(file, indent); +} + +void CAutoSoundEvent::load(SimpleFile *file) { + file->readNumber(); + _value1 = file->readNumber(); + _value2 = file->readNumber(); + + CGameObject::load(file); +} + +bool CAutoSoundEvent::FrameMsg(CFrameMsg *msg) { + if (_value1 >= 0) + _value1 = (_value1 + 1) & _value2; + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/messages/auto_sound_event.h b/engines/titanic/messages/auto_sound_event.h new file mode 100644 index 0000000000..d88976708e --- /dev/null +++ b/engines/titanic/messages/auto_sound_event.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_AUTO_SOUND_EVENT_H +#define TITANIC_AUTO_SOUND_EVENT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CAutoSoundEvent : public CGameObject { + DECLARE_MESSAGE_MAP; + bool FrameMsg(CFrameMsg *msg); +public: + int _value1; + int _value2; +public: + CLASSDEF; + CAutoSoundEvent(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_AUTO_SOUND_EVENT_H */ diff --git a/engines/titanic/messages/bilge_auto_sound_event.cpp b/engines/titanic/messages/bilge_auto_sound_event.cpp new file mode 100644 index 0000000000..fa87b4b79c --- /dev/null +++ b/engines/titanic/messages/bilge_auto_sound_event.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/messages/bilge_auto_sound_event.h" + +namespace Titanic { + +void CBilgeAutoSoundEvent::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CAutoSoundEvent::save(file, indent); +} + +void CBilgeAutoSoundEvent::load(SimpleFile *file) { + file->readNumber(); + CAutoSoundEvent::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/messages/bilge_auto_sound_event.h b/engines/titanic/messages/bilge_auto_sound_event.h new file mode 100644 index 0000000000..9a7fbd6261 --- /dev/null +++ b/engines/titanic/messages/bilge_auto_sound_event.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_BILGE_AUTO_SOUND_EVENT_H +#define TITANIC_BILGE_AUTO_SOUND_EVENT_H + +#include "titanic/messages/auto_sound_event.h" + +namespace Titanic { + +class CBilgeAutoSoundEvent : public CAutoSoundEvent { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BILGE_AUTO_SOUND_EVENT_H */ diff --git a/engines/titanic/messages/bilge_dispensor_event.cpp b/engines/titanic/messages/bilge_dispensor_event.cpp new file mode 100644 index 0000000000..043ffe75d3 --- /dev/null +++ b/engines/titanic/messages/bilge_dispensor_event.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/messages/bilge_dispensor_event.h" + +namespace Titanic { + +void CBilgeDispensorEvent::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CAutoSoundEvent::save(file, indent); +} + +void CBilgeDispensorEvent::load(SimpleFile *file) { + file->readNumber(); + CAutoSoundEvent::load(file); +} + +bool CBilgeDispensorEvent::EnterRoomMsg(CEnterRoomMsg *msg) { + _value1 = 0; + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/messages/bilge_dispensor_event.h b/engines/titanic/messages/bilge_dispensor_event.h new file mode 100644 index 0000000000..96ef92a54e --- /dev/null +++ b/engines/titanic/messages/bilge_dispensor_event.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_BILGE_DISPENSOR_EVENT_H +#define TITANIC_BILGE_DISPENSOR_EVENT_H + +#include "titanic/messages/auto_sound_event.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CBilgeDispensorEvent : public CAutoSoundEvent { + bool EnterRoomMsg(CEnterRoomMsg *msg); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BILGE_DISPENSOR_EVENT_H */ diff --git a/engines/titanic/messages/door_auto_sound_event.cpp b/engines/titanic/messages/door_auto_sound_event.cpp new file mode 100644 index 0000000000..b9cedae6de --- /dev/null +++ b/engines/titanic/messages/door_auto_sound_event.cpp @@ -0,0 +1,47 @@ +/* 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 "titanic/messages/door_auto_sound_event.h" + +namespace Titanic { + +void CDoorAutoSoundEvent::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_fieldDC, indent); + file->writeNumberLine(_fieldE0, indent); + + CAutoSoundEvent::save(file, indent); +} + +void CDoorAutoSoundEvent::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + _fieldDC = file->readNumber(); + _fieldE0 = file->readNumber(); + + CAutoSoundEvent::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/messages/door_auto_sound_event.h b/engines/titanic/messages/door_auto_sound_event.h new file mode 100644 index 0000000000..e6ea1b0f98 --- /dev/null +++ b/engines/titanic/messages/door_auto_sound_event.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_DOOR_AUTO_SOUND_EVENT_H +#define TITANIC_DOOR_AUTO_SOUND_EVENT_H + +#include "titanic/messages/auto_sound_event.h" + +namespace Titanic { + +class CDoorAutoSoundEvent : public CAutoSoundEvent { +public: + CString _string1; + CString _string2; + int _fieldDC; + int _fieldE0; +public: + CLASSDEF; + CDoorAutoSoundEvent() : CAutoSoundEvent(), + _string1("z#44.wav"), _string2("z#43.wav"), _fieldDC(25), _fieldE0(25) { + } + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DOOR_AUTO_SOUND_EVENT_H */ diff --git a/engines/titanic/messages/messages.cpp b/engines/titanic/messages/messages.cpp new file mode 100644 index 0000000000..5f587c975d --- /dev/null +++ b/engines/titanic/messages/messages.cpp @@ -0,0 +1,166 @@ +/* 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 "titanic/messages/messages.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/core/game_object.h" +#include "titanic/core/message_target.h" +#include "titanic/core/tree_item.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CMessage::CMessage() : CSaveableObject() { +} + +void CMessage::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); +} + +void CMessage::load(SimpleFile *file) { + file->readNumber(); + CSaveableObject::load(file); +} + +bool CMessage::execute(CTreeItem *target, const ClassDef *classDef, int flags) { + // If no target was specified, then there's nothing to do + if (!target) + return false; + + bool result = false; + CTreeItem *item = target; + CTreeItem *nextItem = nullptr; + do { + if (flags & MSGFLAG_SCAN) + nextItem = item->scan(target); + + if (!classDef || item->isInstanceOf(classDef)) { + bool handled = perform(item); + + if (handled) { + result = true; + if (flags & MSGFLAG_BREAK_IF_HANDLED) + return true; + } + } + + item = nextItem; + } while (nextItem); + + return result; +} + +bool CMessage::execute(const CString &target, const ClassDef *classDef, int flags) { + // Scan for the target by name + CProjectItem *project = g_vm->_window->_project; + for (CTreeItem *treeItem = project; treeItem; treeItem = treeItem->scan(project)) { + if (!treeItem->getName().compareToIgnoreCase(target)) + return execute(treeItem, classDef, flags); + } + + return false; +} + +const MSGMAP_ENTRY *CMessage::findMapEntry(const CTreeItem *treeItem, const ClassDef *classDef) { + // Iterate through the class and any parent classes + for (const MSGMAP *msgMap = treeItem->getMessageMap(); msgMap->pFnGetBaseMap; + msgMap = msgMap->pFnGetBaseMap()) { + // Iterate through the map entries for this class + for (const MSGMAP_ENTRY *entry = msgMap->lpEntries; + entry->_class != nullptr; ++entry) { + // Check if the class or any of it's ancesotrs is handled by this entry + for (const ClassDef *entryDef = entry->_class; entryDef; entryDef = entryDef->_parent) { + if (entryDef == classDef) + return entry; + } + } + } + + return nullptr; +} + +bool CMessage::perform(CTreeItem *treeItem) { + const MSGMAP_ENTRY *entry = findMapEntry(treeItem, getType()); + return entry && (*treeItem.*(entry->_fn))(this); +} + +bool CMessage::supports(const CTreeItem *treeItem, ClassDef *classDef) { + return findMapEntry(treeItem, classDef) != nullptr; +} + +bool CMessage::isMouseMsg() const { + return dynamic_cast<const CMouseMsg *>(this) != nullptr; +} + +bool CMessage::isButtonDownMsg() const { + return dynamic_cast<const CMouseButtonDownMsg *>(this) != nullptr; +} + +bool CMessage::isButtonUpMsg() const { + return dynamic_cast<const CMouseButtonUpMsg *>(this) != nullptr; +} + +bool CMessage::isMouseMoveMsg() const { + return dynamic_cast<const CMouseMoveMsg *>(this) != nullptr; +} + +bool CMessage::isDoubleClickMsg() const { + return dynamic_cast<const CMouseDoubleClickMsg *>(this) != nullptr; +} + +bool CMessage::isEnterRoomMsg() const { + return dynamic_cast<const CEnterRoomMsg *>(this) != nullptr; +} + +bool CMessage::isPreEnterRoomMsg() const { + return dynamic_cast<const CPreEnterRoomMsg *>(this) != nullptr; +} + +bool CMessage::isleaveRoomMsg() const { + return dynamic_cast<const CLeaveRoomMsg *>(this) != nullptr; +} + +bool CMessage::isEnterNodeMsg() const { + return dynamic_cast<const CEnterNodeMsg *>(this) != nullptr; +} + +bool CMessage::isPreEnterNodeMsg() const { + return dynamic_cast<const CPreEnterNodeMsg *>(this) != nullptr; +} + +bool CMessage::isLeaveNodeMsg() const { + return dynamic_cast<const CLeaveNodeMsg *>(this) != nullptr; +} + +bool CMessage::isEnterViewMsg() const { + return dynamic_cast<const CEnterViewMsg *>(this) != nullptr; +} + +bool CMessage::isPreEnterViewMsg() const { + return dynamic_cast<const CPreEnterViewMsg *>(this) != nullptr; +} + +bool CMessage::isLeaveViewMsg() const { + return dynamic_cast<const CLeaveViewMsg *>(this) != nullptr; +} + +} // End of namespace Titanic diff --git a/engines/titanic/messages/messages.h b/engines/titanic/messages/messages.h new file mode 100644 index 0000000000..c1d962f656 --- /dev/null +++ b/engines/titanic/messages/messages.h @@ -0,0 +1,363 @@ +/* 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 TITANIC_MESSAGES_H +#define TITANIC_MESSAGES_H + +#include "common/keyboard.h" +#include "titanic/core/saveable_object.h" +#include "titanic/core/tree_item.h" + +namespace Titanic { + +enum MessageFlag { + MSGFLAG_SCAN = 1, + MSGFLAG_BREAK_IF_HANDLED = 2, + MSGFLAG_CLASS_DEF = 4 +}; + +#define MESSAGE0(NAME) \ + class NAME: public CMessage { \ + public: NAME() : CMessage() {} \ + CLASSDEF; \ + static bool isSupportedBy(const CTreeItem *item) { \ + return supports(item, _type); } \ +} +#define MESSAGE1(NAME, F1, N1, V1) \ + class NAME: public CMessage { \ + public: F1 _##N1; \ + NAME() : CMessage(), _##N1(V1) {} \ + NAME(F1 N1) : CMessage(), _##N1(N1) {} \ + CLASSDEF; \ + static bool isSupportedBy(const CTreeItem *item) { \ + return supports(item, _type); } \ +} +#define MESSAGE2(NAME, F1, N1, V1, F2, N2, V2) \ + class NAME: public CMessage { \ + public: F1 _##N1; F2 _##N2; \ + NAME() : CMessage(), _##N1(V1), _##N2(V2) {} \ + NAME(F1 N1, F2 N2) : CMessage(), _##N1(N1), _##N2(N2) {} \ + CLASSDEF; \ + static bool isSupportedBy(const CTreeItem *item) { \ + return supports(item, _type); } \ +} +#define MESSAGE3(NAME, F1, N1, V1, F2, N2, V2, F3, N3, V3) \ + class NAME: public CMessage { \ + public: F1 _##N1; F2 _##N2; F3 _##N3; \ + NAME() : CMessage(), _##N1(V1), _##N2(V2), _##N3(V3) {} \ + NAME(F1 N1, F2 N2, F3 N3) : CMessage(), _##N1(N1), _##N2(N2), _##N3(N3) {} \ + CLASSDEF; \ + static bool isSupportedBy(const CTreeItem *item) { \ + return supports(item, _type); } \ +} +#define MESSAGE4(NAME, F1, N1, V1, F2, N2, V2, F3, N3, V3, F4, N4, V4) \ + class NAME: public CMessage { \ + public: F1 _##N1; F2 _##N2; F3 _##N3; F4 _##N4; \ + NAME() : CMessage(), _##N1(V1), _##N2(V2), _##N3(V3), _##N4(V4) {} \ + NAME(F1 N1, F2 N2, F3 N3, F4 N4) : CMessage(), _##N1(N1), _##N2(N2), _##N3(N3), _##N4(N4) {} \ + CLASSDEF; \ + static bool isSupportedBy(const CTreeItem *item) { \ + return supports(item, _type); } \ +} + +class CCarry; +class CCharacter; +class CGameObject; +class CRoomItem; +class CNodeItem; +class CViewItem; +class CMusicPlayer; + +class CMessage : public CSaveableObject { +private: + /** + * Find a map entry that supports the given class + */ + static const MSGMAP_ENTRY *findMapEntry(const CTreeItem *treeItem, const ClassDef *classDef); +public: + CLASSDEF; + CMessage(); + + /** + * Executes the message, passing it on to the designated target, + * and optionally it's children + */ + bool execute(CTreeItem *target, const ClassDef *classDef = nullptr, + int flags = MSGFLAG_SCAN | MSGFLAG_BREAK_IF_HANDLED); + + /** + * Executes the message, passing it on to the designated target, + * and optionally it's children + */ + bool execute(const CString &target, const ClassDef *classDef = nullptr, + int flags = MSGFLAG_SCAN | MSGFLAG_BREAK_IF_HANDLED); + + /** + * Makes the passed item execute the message + */ + virtual bool perform(CTreeItem *treeItem); + + /** + * Returns true if the passed item supports the specified message class + */ + static bool supports(const CTreeItem *treeItem, ClassDef *classDef); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + virtual bool isMouseMsg() const; + virtual bool isButtonDownMsg() const; + virtual bool isButtonUpMsg() const; + virtual bool isMouseMoveMsg() const; + virtual bool isDoubleClickMsg() const; + virtual bool isEnterRoomMsg() const; + virtual bool isPreEnterRoomMsg() const; + virtual bool isleaveRoomMsg() const; + virtual bool isEnterNodeMsg() const; + virtual bool isPreEnterNodeMsg() const; + virtual bool isLeaveNodeMsg() const; + virtual bool isEnterViewMsg() const; + virtual bool isPreEnterViewMsg() const; + virtual bool isLeaveViewMsg() const; +}; + +class CEditControlMsg : public CMessage { +public: + int _field4; + int _field8; + CString _string1; + int _field18; + int _field1C; + int _field20; +public: + CLASSDEF; + CEditControlMsg() : _field4(0), _field8(0), _field18(0), + _field1C(0), _field20(0) {} + + static bool isSupportedBy(const CTreeItem *item) { + return CMessage::supports(item, _type); + } +}; + +class CLightsMsg : public CMessage { +public: + int _field4; + int _field8; + int _fieldC; + int _field10; +public: + CLASSDEF; + CLightsMsg() : CMessage(), _field4(0), _field8(0), + _fieldC(0), _field10(0) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } +}; + +MESSAGE1(CTimeMsg, uint, _ticks, 0); + +class CTimerMsg : public CTimeMsg { +public: + uint _timerCtr; + int _actionVal; + CString _action; +public: + CLASSDEF; + CTimerMsg() : CTimeMsg(), _timerCtr(0), _actionVal(0) {} + CTimerMsg(uint ticks, uint timerCtr, int actionVal, const CString &action) : + CTimeMsg(ticks), _timerCtr(timerCtr), _actionVal(actionVal), _action(action) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } +}; + +MESSAGE1(CActMsg, CString, action, ""); +MESSAGE1(CActivationmsg, CString, value, ""); +MESSAGE1(CAddHeadPieceMsg, CString, value, "NULL"); +MESSAGE1(CAnimateMaitreDMsg, int, value, 0); +MESSAGE1(CArboretumGateMsg, int, value, 0); +MESSAGE0(CArmPickedUpFromTableMsg); +MESSAGE0(CBodyInBilgeRoomMsg); +MESSAGE1(CBowlStateChange, int, value, 0); +MESSAGE2(CCarryObjectArrivedMsg, CString, strValue, "", int, numValue, 0); +MESSAGE2(CChangeMusicMsg, CString, filename, "", int, flags, 0); +MESSAGE1(CChangeSeasonMsg, CString, season, "Summer"); +MESSAGE0(CCheckAllPossibleCodes); +MESSAGE2(CCheckChevCode, int, value1, 0, int, value2, 0); +MESSAGE1(CChildDragEndMsg, int, value, 0); +MESSAGE2(CChildDragMoveMsg, int, value1, 0, int, value2, 0); +MESSAGE2(CChildDragStartMsg, int, value1, 0, int, value2, 0); +MESSAGE0(CClearChevPanelBits); +MESSAGE0(CCorrectMusicPlayedMsg); +MESSAGE0(CCreateMusicPlayerMsg); +MESSAGE0(CCylinderHolderReadyMsg); +MESSAGE0(CDeactivationMsg); +MESSAGE1(CDeliverCCarryMsg, CString, value, ""); +MESSAGE0(CDisableMaitreDProdReceptor); +MESSAGE0(CDismissBotMsg); +MESSAGE0(CDoffNavHelmet); +MESSAGE0(CDonNavHelmet); +MESSAGE1(CDoorbotNeededInElevatorMsg, int, value, 0); +MESSAGE0(CDoorbotNeededInHomeMsg); +MESSAGE1(CDropObjectMsg, CCarry *, item, nullptr); +MESSAGE1(CDropZoneGotObjectMsg, int, value, 0); +MESSAGE1(CDropZoneLostObjectMsg, int, value, 0); +MESSAGE1(CEjectCylinderMsg, int, value, 0); +MESSAGE2(CPreEnterNodeMsg, CNodeItem *, oldNode, nullptr, CNodeItem *, newNode, nullptr); +MESSAGE2(CPreEnterRoomMsg, CRoomItem *, oldRoom, nullptr, CRoomItem *, newRoom, nullptr); +MESSAGE2(CPreEnterViewMsg, CViewItem *, oldView, nullptr, CViewItem *, newView, nullptr); +MESSAGE2(CEnterNodeMsg, CNodeItem *, oldNode, nullptr, CNodeItem *, newNode, nullptr); +MESSAGE2(CEnterRoomMsg, CRoomItem *, oldRoom, nullptr, CRoomItem *, newRoom, nullptr); +MESSAGE2(CEnterViewMsg, CViewItem *, oldView, nullptr, CViewItem *, newView, nullptr); +MESSAGE0(CErasePhonographCylinderMsg); +MESSAGE1(CFrameMsg, uint, ticks, 0); +MESSAGE2(CFreshenCookieMsg, int, value1, 0, int, value2, 0); +MESSAGE1(CGetChevClassBits, int, value, 0); +MESSAGE1(CGetChevClassNum, int, value, 0); +MESSAGE2(CGetChevCodeFromRoomNameMsg, CString, strValue, "", int, numValue, 0); +MESSAGE1(CGetChevFloorBits, int, value, 0); +MESSAGE1(CGetChevFloorNum, int, value, 0); +MESSAGE1(CGetChevLiftBits, int, value, 0); +MESSAGE1(CGetChevLiftNum, int, value, 0); +MESSAGE1(CGetChevRoomBits, int, value, 0); +MESSAGE1(CGetChevRoomNum, int, value, 0); +MESSAGE2(CHoseConnectedMsg, int, value1, 1, int, value2, 0); +MESSAGE0(CInitializeAnimMsg); +MESSAGE1(CIsEarBowlPuzzleDone, int, value, 0); +MESSAGE3(CIsHookedOnMsg, Rect, rect, Rect(), bool, result, false, CString, string1, ""); +MESSAGE1(CIsParrotPresentMsg, bool, value, false); +MESSAGE1(CKeyCharMsg, int, key, 32); +MESSAGE2(CLeaveNodeMsg, CNodeItem *, oldNode, nullptr, CNodeItem *, newNode, nullptr); +MESSAGE2(CLeaveRoomMsg, CRoomItem *, oldRoom, nullptr, CRoomItem *, newRoom, nullptr); +MESSAGE2(CLeaveViewMsg, CViewItem *, oldView, nullptr, CViewItem *, newView, nullptr); +MESSAGE2(CLemonFallsFromTreeMsg, int, value1, 0, int, value2, 0); +MESSAGE1(CLoadSuccessMsg, int, ticks, 0); +MESSAGE1(CLockPhonographMsg, int, value, 0); +MESSAGE0(CMaitreDDefeatedMsg); +MESSAGE0(CMaitreDHappyMsg); +MESSAGE1(CMissiveOMatActionMsg, int, value, 0); +MESSAGE0(CMoveToStartPosMsg); +MESSAGE2(CMovieEndMsg, int, startFrame, 0, int, endFrame, 0); +MESSAGE2(CMovieFrameMsg, int, frameNumber, 0, int, value2, 0); +MESSAGE0(CMusicHasStartedMsg); +MESSAGE0(CMusicHasStoppedMsg); +MESSAGE0(CMusicSettingChangedMsg); +MESSAGE2(CNPCPlayAnimationMsg, const char *const *, names, nullptr, int, value2, 0); +MESSAGE1(CNPCPlayIdleAnimationMsg, const char *const *, names, 0); +MESSAGE3(CNPCPlayTalkingAnimationMsg, int, value1, 0, int, value2, 0, const char *const *, names, nullptr); +MESSAGE0(CNPCQueueIdleAnimMsg); +MESSAGE1(CNutPuzzleMsg, CString, value, ""); +MESSAGE1(COnSummonBotMsg, int, value, 0); +MESSAGE0(COpeningCreditsMsg); +MESSAGE1(CPanningAwayFromParrotMsg, int, value, 0); +MESSAGE2(CParrotSpeakMsg, CString, value1, "", CString, value2, ""); +MESSAGE2(CParrotTriesChickenMsg, int, value1, 0, int, value2, 0); +MESSAGE1(CPhonographPlayMsg, int, value, 0); +MESSAGE0(CPhonographReadyToPlayMsg); +MESSAGE1(CPhonographRecordMsg, int, value, 0); +MESSAGE3(CPhonographStopMsg, int, value1, 0, int, value2, 0, int, value3, 0); +MESSAGE2(CPlayRangeMsg, int, value1, 0, int, value2, 0); +MESSAGE2(CPlayerTriesRestaurantTableMsg, int, value1, 0, int, value2, 0); +MESSAGE1(CPreSaveMsg, int, value, 0); +MESSAGE1(CProdMaitreDMsg, int, value, 0); +MESSAGE2(CPumpingMsg, int, value1, 0, int, value2, 0); +MESSAGE1(CPutBotBackInHisBoxMsg, int, value, 0); +MESSAGE1(CPutParrotBackMsg, int, value, 0); +MESSAGE0(CPuzzleSolvedMsg); +MESSAGE3(CQueryCylinderHolderMsg, int, value1, 0, int, value2, 0, int, value3, 0); +MESSAGE1(CQueryCylinderMsg, CString, name, ""); +MESSAGE1(CQueryCylinderNameMsg, CString, name, ""); +MESSAGE3(CQueryCylinderTypeMsg, int, value1, 0, int, value2, 0, int, value3, 0); +MESSAGE1(CQueryMusicControlSettingMsg, int, value, 0); +MESSAGE1(CQueryPhonographState, int, value, 0); +MESSAGE0(CRecordOntoCylinderMsg); +MESSAGE0(CRemoveFromGameMsg); +MESSAGE0(CReplaceBowlAndNutsMsg); +MESSAGE1(CRestaurantMusicChanged, CString, value, ""); +MESSAGE2(CSendCCarryMsg, CString, strValue, "", int, numValue, 0); +MESSAGE1(CSenseWorkingMsg, CString, value, "Not Working"); +MESSAGE2(CServiceElevatorFloorChangeMsg, int, value1, 0, int, value2, 0); +MESSAGE0(CServiceElevatorFloorRequestMsg); +MESSAGE1(CServiceElevatorMsg, int, value, 4); +MESSAGE2(CSetChevButtonImageMsg, int, value1, 0, int, value2, 0); +MESSAGE1(CSetChevClassBits, int, value, 0); +MESSAGE1(CSetChevFloorBits, int, value, 0); +MESSAGE1(CSetChevLiftBits, int, value, 0); +MESSAGE2(CSetChevPanelBitMsg, int, value1, 0, int, value2, 0); +MESSAGE1(CSetChevPanelButtonsMsg, int, value, 0); +MESSAGE1(CSetChevRoomBits, int, value, 0); +MESSAGE1(CSetFrameMsg, int, frameNumber, 0); +MESSAGE0(CSetMusicControlsMsg); +MESSAGE2(CSetVarMsg, CString, varName, "", int, value, 0); +MESSAGE2(CSetVolumeMsg, int, volume, 70, int, secondsTransition, 0); +MESSAGE2(CShipSettingMsg, int, value, 0, CString, name, ""); +MESSAGE1(CShowTextMsg, CString, value, "NO TEXT INCLUDED!!!"); +MESSAGE2(CSignalObject, CString, strValue, "", int, numValue, 0); +MESSAGE2(CSpeechFallsFromTreeMsg, int, value1, 0, int, value2, 0); +MESSAGE1(CStartMusicMsg, CMusicPlayer *, musicPlayer, (CMusicPlayer *)nullptr); +MESSAGE3(CStatusChangeMsg, int, oldStatus, 0, int, newStatus, 0, bool, success, false); +MESSAGE1(CStopMusicMsg, int, value, 0); +MESSAGE4(CSubAcceptCCarryMsg, CString, string1, "", int, value1, 0, int, value2, 0, CCarry *, item, nullptr); +MESSAGE0(CSubDeliverCCarryMsg); +MESSAGE0(CSubSendCCarryMsg); +MESSAGE0(CSUBTransition); +MESSAGE0(CSubTurnOffMsg); +MESSAGE0(CSubTurnOnMsg); +MESSAGE2(CSummonBotMsg, CString, strValue, "", int, numValue, 0); +MESSAGE1(CSummonBotQueryMsg, CString, npcName, ""); +MESSAGE1(CTakeHeadPieceMsg, CString, value, "NULL"); +MESSAGE2(CTextInputMsg, CString, input, "", CString, response, ""); +MESSAGE1(CTimeDilationMsg, int, value, 0); +MESSAGE0(CTitleSequenceEndedMsg); +MESSAGE0(CTransitMsg); +MESSAGE1(CTranslateObjectMsg, Point, delta, Point()); +MESSAGE3(CTransportMsg, CString, roomName, "", int, value1, 0, int, value2, 0); +MESSAGE1(CTriggerAutoMusicPlayerMsg, int, value, 0); +MESSAGE1(CTriggerNPCEvent, int, value, 0); +MESSAGE4(CTrueTalkGetAnimSetMsg, int, value1, 0, uint, index, 0, uint, startFrame, 0, uint, endFrame, 0); +MESSAGE2(CTrueTalkGetAssetDetailsMsg, CString, filename, "", int, numValue, 0); +MESSAGE2(CTrueTalkGetStateValueMsg, int, stateNum, 0, int, stateVal, -1000); +MESSAGE2(CTrueTalkNotifySpeechEndedMsg, int, value1, 0, int, dialogueId, 0); +MESSAGE3(CTrueTalkNotifySpeechStartedMsg, uint, soundId, 0, uint, dialogueId, 0, int, value, 0); +MESSAGE1(CTrueTalkQueueUpAnimSetMsg, int, value, 0); +MESSAGE0(CTrueTalkSelfQueueAnimSetMsg); +MESSAGE3(CTrueTalkTriggerActionMsg, int, action, 0, int, param1, 0, int, param2, 0); +MESSAGE0(CTurnOff); +MESSAGE0(CTurnOn); +MESSAGE1(CUse, CCarry *, item, nullptr); +MESSAGE1(CUseWithCharMsg, CCharacter *, character, nullptr); +MESSAGE1(CUseWithOtherMsg, CGameObject *, other, 0); +MESSAGE1(CVirtualKeyCharMsg, Common::KeyState, keyState, Common::KeyState()); +MESSAGE1(CVisibleMsg, bool, visible, true); + +} // End of namespace Titanic + +#endif /* TITANIC_MESSAGE_H */ diff --git a/engines/titanic/messages/mouse_messages.cpp b/engines/titanic/messages/mouse_messages.cpp new file mode 100644 index 0000000000..8ef7f38fd3 --- /dev/null +++ b/engines/titanic/messages/mouse_messages.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/messages/mouse_messages.h" +#include "titanic/support/mouse_cursor.h" +#include "titanic/support/screen_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +void CMouseButtonDownMsg::generate() { + CInputHandler &inputHandler = *CScreenManager::_screenManagerPtr->_inputHandler; + const Point &mousePos = inputHandler._mousePos; + + CMouseButtonDownMsg msg(mousePos, MB_LEFT); + inputHandler.handleMessage(msg, false); +} + +/*------------------------------------------------------------------------*/ + +void CMouseButtonUpMsg::generate() { + CInputHandler &inputHandler = *CScreenManager::_screenManagerPtr->_inputHandler; + const Point &mousePos = inputHandler._mousePos; + + CMouseButtonUpMsg msg(mousePos, MB_LEFT); + inputHandler.handleMessage(msg, false); +} + +} // End of namespace Titanic diff --git a/engines/titanic/messages/mouse_messages.h b/engines/titanic/messages/mouse_messages.h new file mode 100644 index 0000000000..d17bd51c78 --- /dev/null +++ b/engines/titanic/messages/mouse_messages.h @@ -0,0 +1,184 @@ +/* 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 TITANIC_MOUSE_MESSAGES_H +#define TITANIC_MOUSE_MESSAGES_H + +#include "titanic/support/rect.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +enum MouseButton { MB_LEFT = 1, MB_MIDDLE = 2, MB_RIGHT = 4 }; + +class CMouseMsg : public CMessage { +public: + int _buttons; + Point _mousePos; +public: + CLASSDEF; + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } + + CMouseMsg() : _buttons(0) {} + CMouseMsg(const Point &pt, int buttons) : + _mousePos(pt), _buttons(buttons) {} +}; + +class CMouseMoveMsg : public CMouseMsg { +public: + CLASSDEF; + CMouseMoveMsg() : CMouseMsg() {} + CMouseMoveMsg(const Point &pt, int buttons) : CMouseMsg(pt, buttons) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } +}; + +class CMouseButtonMsg : public CMouseMsg { +public: + int _field10; +public: + CLASSDEF; + CMouseButtonMsg() : CMouseMsg(), _field10(0) {} + CMouseButtonMsg(const Point &pt, int buttons) : CMouseMsg(pt, buttons) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } +}; + +class CMouseButtonDownMsg : public CMouseButtonMsg { +public: + CLASSDEF; + CMouseButtonDownMsg() : CMouseButtonMsg() {} + CMouseButtonDownMsg(const Point &pt, int buttons) : CMouseButtonMsg(pt, buttons) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } + + /** + * Generate a dummy mouse down message at the current mouse position + */ + static void generate(); +}; + +class CMouseButtonUpMsg : public CMouseButtonMsg { +public: + CLASSDEF; + CMouseButtonUpMsg() : CMouseButtonMsg() {} + CMouseButtonUpMsg(const Point &pt, int buttons) : CMouseButtonMsg(pt, buttons) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } + + /** + * Generate a dummy mouse up message at the current mouse position + */ + static void generate(); +}; + +class CMouseDoubleClickMsg : public CMouseButtonMsg { +public: + CLASSDEF; + CMouseDoubleClickMsg() : CMouseButtonMsg() {} + CMouseDoubleClickMsg(const Point &pt, int buttons) : CMouseButtonMsg(pt, buttons) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } +}; + +class CMouseDragMsg : public CMouseMsg { +public: + CLASSDEF; + CMouseDragMsg() : CMouseMsg() {} + CMouseDragMsg(const Point &pt) : CMouseMsg(pt, 0) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } +}; + +class CMouseDragMoveMsg : public CMouseDragMsg { +public: + CLASSDEF; + CMouseDragMoveMsg() : CMouseDragMsg() {} + CMouseDragMoveMsg(const Point &pt) : CMouseDragMsg(pt) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } +}; + +class CMouseDragStartMsg : public CMouseDragMsg { +public: + CTreeItem *_dragItem; + bool _handled; +public: + CLASSDEF; + CMouseDragStartMsg() : CMouseDragMsg(), _dragItem(nullptr), _handled(false) {} + CMouseDragStartMsg(const Point &pt) : CMouseDragMsg(pt), + _dragItem(nullptr), _handled(false) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } +}; + +class CPassOnDragStartMsg : public CMessage { +public: + Point _mousePos; + int _value3; + int _value4; +public: + CLASSDEF; + CPassOnDragStartMsg() : CMessage() {} + CPassOnDragStartMsg(const Point &pt, int v3 = 0, int v4 = 0) : + CMessage(), _mousePos(pt), _value3(v3), _value4(v4) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } +}; + +class CMouseDragEndMsg : public CMouseDragMsg { +public: + CGameObject *_dropTarget; +public: + CLASSDEF; + CMouseDragEndMsg() : CMouseDragMsg(), _dropTarget(nullptr) {} + CMouseDragEndMsg(const Point &pt, CGameObject *dropTarget = nullptr) : + CMouseDragMsg(pt), _dropTarget(dropTarget) {} + + static bool isSupportedBy(const CTreeItem *item) { + return supports(item, _type); + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOUSE_MESSAGES_H */ diff --git a/engines/titanic/messages/pet_messages.h b/engines/titanic/messages/pet_messages.h new file mode 100644 index 0000000000..48e5bab64c --- /dev/null +++ b/engines/titanic/messages/pet_messages.h @@ -0,0 +1,64 @@ +/* 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 TITANIC_PET_MESSAGES_H +#define TITANIC_PET_MESSAGES_H + +#include "titanic/messages/messages.h" + +namespace Titanic { + +MESSAGE0(CPETDeliverMsg); +MESSAGE0(CPETGainedObjectMsg); +MESSAGE0(CPETHelmetOnOffMsg); +MESSAGE0(CPETKeyboardOnOffMsg); +MESSAGE0(CPETLostObjectMsg); +MESSAGE0(CPETObjectSelectedMsg); +MESSAGE1(CPETObjectStateMsg, int, value, 0); +MESSAGE0(CPETPhotoOnOffMsg); +MESSAGE1(CPETPlaySoundMsg, int, value, 0); +MESSAGE0(CPETReceiveMsg); +MESSAGE0(CPETSetStarDestinationMsg); +MESSAGE1(CPETStarFieldLockMsg, int, value, 0); +MESSAGE0(CPETStereoFieldOnOffMsg); +MESSAGE2(CPETTargetMsg, CString, name, "", int, numValue, -1); + +#define PET_MESSAGE(NAME) \ + class NAME: public CPETTargetMsg { \ + public: \ + NAME() : CPETTargetMsg() {} \ + NAME(const CString &name, int num) : CPETTargetMsg(name, num) {} \ + CLASSDEF; \ + static bool isSupportedBy(const CTreeItem *item) { \ + return supports(item, _type); \ + } \ +} + +PET_MESSAGE(CPETDownMsg); +PET_MESSAGE(CPETUpMsg); +PET_MESSAGE(CPETLeftMsg); +PET_MESSAGE(CPETRightMsg); +PET_MESSAGE(CPETActivateMsg); + +} // End of namespace Titanic + +#endif /* TITANIC_PET_MESSAGES_H */ diff --git a/engines/titanic/messages/service_elevator_door.cpp b/engines/titanic/messages/service_elevator_door.cpp new file mode 100644 index 0000000000..748790e4aa --- /dev/null +++ b/engines/titanic/messages/service_elevator_door.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/messages/service_elevator_door.h" + +namespace Titanic { + +CServiceElevatorDoor::CServiceElevatorDoor() : CDoorAutoSoundEvent() { + _string1 = "z#31.wav"; + _string2 = "z#32.wav"; +} + +void CServiceElevatorDoor::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string2, indent); + file->writeQuotedLine(_string1, indent); + + CDoorAutoSoundEvent::save(file, indent); +} + +void CServiceElevatorDoor::load(SimpleFile *file) { + file->readNumber(); + _string2 = file->readString(); + _string1 = file->readString(); + + CDoorAutoSoundEvent::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/messages/service_elevator_door.h b/engines/titanic/messages/service_elevator_door.h new file mode 100644 index 0000000000..cc8da0917d --- /dev/null +++ b/engines/titanic/messages/service_elevator_door.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_SERVICE_ELEVATOR_DOOR_H +#define TITANIC_SERVICE_ELEVATOR_DOOR_H + +#include "titanic/messages/door_auto_sound_event.h" + +namespace Titanic { + +class CServiceElevatorDoor : public CDoorAutoSoundEvent { +public: + CLASSDEF; + CServiceElevatorDoor(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SERVICE_ELEVATOR_DOOR_H */ diff --git a/engines/titanic/module.mk b/engines/titanic/module.mk new file mode 100644 index 0000000000..5c041174a2 --- /dev/null +++ b/engines/titanic/module.mk @@ -0,0 +1,520 @@ +MODULE := engines/titanic + +MODULE_OBJS := \ + continue_save_dialog.o \ + debugger.o \ + detection.o \ + events.o \ + game_location.o \ + game_manager.o \ + game_state.o \ + game_view.o \ + input_handler.o \ + input_translator.o \ + main_game_window.o \ + room_flags.o \ + titanic.o \ + carry/auditory_centre.o \ + carry/arm.o \ + carry/bowl_ear.o \ + carry/brain.o \ + carry/bridge_piece.o \ + carry/carry.o \ + carry/carry_parrot.o \ + carry/central_core.o \ + carry/chicken.o \ + carry/crushed_tv.o \ + carry/ear.o \ + carry/eye.o \ + carry/feathers.o \ + carry/fruit.o \ + carry/glass.o \ + carry/hammer.o \ + carry/head_piece.o \ + carry/hose.o \ + carry/hose_end.o \ + carry/key.o \ + carry/liftbot_head.o \ + carry/long_stick.o \ + carry/magazine.o \ + carry/maitred_left_arm.o \ + carry/maitred_right_arm.o \ + carry/mouth.o \ + carry/napkin.o \ + carry/nose.o \ + carry/note.o \ + carry/parcel.o \ + carry/perch.o \ + carry/phonograph_cylinder.o \ + carry/phonograph_ear.o \ + carry/photograph.o \ + carry/plug_in.o \ + carry/speech_centre.o \ + carry/sweets.o \ + carry/vision_centre.o \ + core/background.o \ + core/click_responder.o \ + core/dont_save_file_item.o \ + core/drop_target.o \ + core/file_item.o \ + core/game_object.o \ + core/game_object_desc_item.o \ + core/link_item.o \ + core/list.o \ + core/mail_man.o \ + core/message_target.o \ + core/multi_drop_target.o \ + core/named_item.o \ + core/node_item.o \ + core/project_item.o \ + core/resource_key.o \ + core/room_item.o \ + core/saveable_object.o \ + core/static_image.o \ + core/turn_on_object.o \ + core/turn_on_play_sound.o \ + core/turn_on_turn_off.o \ + core/tree_item.o \ + core/view_item.o \ + game/announce.o \ + game/annoy_barbot.o \ + game/arb_background.o \ + game/arboretum_gate.o \ + game/auto_animate.o \ + game/bilge_succubus.o \ + game/bar_menu.o \ + game/bar_menu_button.o \ + game/bar_bell.o \ + game/belbot_get_light.o \ + game/bottom_of_well_monitor.o \ + game/bomb.o \ + game/bowl_unlocker.o \ + game/brain_slot.o \ + game/bridge_door.o \ + game/bridge_view.o \ + game/broken_pell_base.o \ + game/broken_pellerator.o \ + game/broken_pellerator_froz.o \ + game/call_pellerator.o \ + game/cage.o \ + game/captains_wheel.o \ + game/cdrom.o \ + game/cdrom_computer.o \ + game/cdrom_tray.o \ + game/cell_point_button.o \ + game/chev_code.o \ + game/chev_panel.o \ + game/chicken_cooler.o \ + game/chicken_dispensor.o \ + game/close_broken_pel.o \ + game/code_wheel.o \ + game/cookie.o \ + game/computer.o \ + game/computer_screen.o \ + game/credits.o \ + game/credits_button.o \ + game/dead_area.o \ + game/desk_click_responder.o \ + game/doorbot_elevator_handler.o \ + game/doorbot_home_handler.o \ + game/ear_sweet_bowl.o \ + game/eject_phonograph_button.o \ + game/elevator_action_area.o \ + game/emma_control.o \ + game/empty_nut_bowl.o \ + game/end_credit_text.o \ + game/end_credits.o \ + game/end_explode_ship.o \ + game/end_game_credits.o \ + game/end_sequence_control.o \ + game/hammer_dispensor.o \ + game/hammer_dispensor_button.o \ + game/fan.o \ + game/fan_control.o \ + game/fan_decrease.o \ + game/fan_increase.o \ + game/fan_noises.o \ + game/floor_indicator.o \ + game/games_console.o \ + game/get_lift_eye2.o \ + game/glass_smasher.o \ + game/hammer_clip.o \ + game/head_slot.o \ + game/head_smash_event.o \ + game/head_smash_lever.o \ + game/head_spinner.o \ + game/idle_summoner.o \ + game/leave_sec_class_state.o \ + game/lemon_dispensor.o \ + game/light.o \ + game/light_switch.o \ + game/little_lift_button.o \ + game/long_stick_dispenser.o \ + game/missiveomat.o \ + game/missiveomat_button.o \ + game/movie_tester.o \ + game/music_console_button.o \ + game/music_room_phonograph.o \ + game/music_room_stop_phonograph_button.o \ + game/music_system_lock.o \ + game/musical_instrument.o \ + game/nav_helmet.o \ + game/navigation_computer.o \ + game/no_nut_bowl.o \ + game/nose_holder.o \ + game/null_port_hole.o \ + game/nut_replacer.o \ + game/pet_disabler.o \ + game/phonograph.o \ + game/phonograph_lid.o \ + game/play_music_button.o \ + game/play_on_act.o \ + game/port_hole.o \ + game/record_phonograph_button.o \ + game/replacement_ear.o \ + game/reserved_table.o \ + game/restaurant_cylinder_holder.o \ + game/restaurant_phonograph.o \ + game/sauce_dispensor.o \ + game/search_point.o \ + game/season_background.o \ + game/season_barrel.o \ + game/seasonal_adjustment.o \ + game/service_elevator_window.o \ + game/ship_setting.o \ + game/ship_setting_button.o \ + game/show_cell_points.o \ + game/speech_dispensor.o \ + game/splash_animation.o \ + game/starling_puret.o \ + game/start_action.o \ + game/stop_phonograph_button.o \ + game/sub_glass.o \ + game/sub_wrapper.o \ + game/sweet_bowl.o \ + game/television.o \ + game/third_class_canal.o \ + game/tow_parrot_nav.o \ + game/throw_tv_down_well.o \ + game/titania_still_control.o \ + game/up_lighter.o \ + game/useless_lever.o \ + game/volume_control.o \ + game/wheel_button.o \ + game/wheel_hotspot.o \ + game/wheel_spin.o \ + game/wheel_spin_horn.o \ + game/gondolier/gondolier_base.o \ + game/gondolier/gondolier_chest.o \ + game/gondolier/gondolier_face.o \ + game/gondolier/gondolier_mixer.o \ + game/gondolier/gondolier_slider.o \ + game/maitred/maitred_arm_holder.o \ + game/maitred/maitred_body.o \ + game/maitred/maitred_legs.o \ + game/maitred/maitred_prod_receptor.o \ + game/parrot/parrot_lobby_controller.o \ + game/parrot/parrot_lobby_link_updater.o \ + game/parrot/parrot_lobby_object.o \ + game/parrot/parrot_lobby_view_object.o \ + game/parrot/parrot_loser.o \ + game/parrot/parrot_nut_bowl_actor.o \ + game/parrot/parrot_nut_eater.o \ + game/parrot/parrot_perch_holder.o \ + game/parrot/parrot_succubus.o \ + game/parrot/parrot_trigger.o \ + game/parrot/player_meets_parrot.o \ + game/pet/pet.o \ + game/pet/pet_class1.o \ + game/pet/pet_class2.o \ + game/pet/pet_class3.o \ + game/pet/pet_lift.o \ + game/pet/pet_monitor.o \ + game/pet/pet_pellerator.o \ + game/pet/pet_position.o \ + game/pet/pet_sentinal.o \ + game/pet/pet_sounds.o \ + game/pet/pet_transition.o \ + game/pet/pet_transport.o \ + game/pickup/pick_up.o \ + game/pickup/pick_up_bar_glass.o \ + game/pickup/pick_up_hose.o \ + game/pickup/pick_up_lemon.o \ + game/pickup/pick_up_speech_centre.o \ + game/pickup/pick_up_vis_centre.o \ + game/placeholder/bar_shelf_vis_centre.o \ + game/placeholder/place_holder_item.o \ + game/placeholder/lemon_on_bar.o \ + game/placeholder/tv_on_bar.o \ + game/transport/gondolier.o \ + game/transport/lift.o \ + game/transport/lift_indicator.o \ + game/transport/pellerator.o \ + game/transport/service_elevator.o \ + game/transport/transport.o \ + game/sgt/armchair.o \ + game/sgt/basin.o \ + game/sgt/bedfoot.o \ + game/sgt/bedhead.o \ + game/sgt/chest_of_drawers.o \ + game/sgt/desk.o \ + game/sgt/deskchair.o \ + game/sgt/drawer.o \ + game/sgt/sgt_doors.o \ + game/sgt/sgt_nav.o \ + game/sgt/sgt_navigation.o \ + game/sgt/sgt_restaurant_doors.o \ + game/sgt/sgt_state_control.o \ + game/sgt/sgt_state_room.o \ + game/sgt/sgt_tv.o \ + game/sgt/sgt_upper_doors_sound.o \ + game/sgt/toilet.o \ + game/sgt/vase.o \ + game/sgt/washstand.o \ + gfx/act_button.o \ + gfx/changes_season_button.o \ + gfx/chev_left_off.o \ + gfx/chev_left_on.o \ + gfx/chev_right_off.o \ + gfx/chev_right_on.o \ + gfx/chev_send_rec_switch.o \ + gfx/chev_switch.o \ + gfx/edit_control.o \ + gfx/elevator_button.o \ + gfx/get_from_succ.o \ + gfx/helmet_on_off.o \ + gfx/home_photo.o \ + gfx/icon_nav_action.o \ + gfx/icon_nav_butt.o \ + gfx/icon_nav_down.o \ + gfx/icon_nav_image.o \ + gfx/icon_nav_left.o \ + gfx/icon_nav_receive.o \ + gfx/icon_nav_right.o \ + gfx/icon_nav_send.o \ + gfx/icon_nav_up.o \ + gfx/keybrd_butt.o \ + gfx/move_object_button.o \ + gfx/music_control.o \ + gfx/music_slider.o \ + gfx/music_switch.o \ + gfx/send_to_succ.o \ + gfx/sgt_selector.o \ + gfx/slider_button.o \ + gfx/small_chev_left_off.o \ + gfx/small_chev_left_on.o \ + gfx/small_chev_right_off.o \ + gfx/small_chev_right_on.o \ + gfx/status_change_button.o \ + gfx/st_button.o \ + gfx/text_down.o \ + gfx/text_skrew.o \ + gfx/text_up.o \ + gfx/toggle_button.o \ + gfx/toggle_switch.o \ + messages/auto_sound_event.o \ + messages/bilge_auto_sound_event.o \ + messages/bilge_dispensor_event.o \ + messages/door_auto_sound_event.o \ + messages/messages.o \ + messages/mouse_messages.o \ + messages/service_elevator_door.o \ + moves/enter_bomb_room.o \ + moves/enter_bridge.o \ + moves/enter_exit_first_class_state.o \ + moves/enter_exit_mini_lift.o \ + moves/enter_exit_sec_class_mini_lift.o \ + moves/enter_exit_view.o \ + moves/enter_sec_class_state.o \ + moves/exit_arboretum.o \ + moves/exit_bridge.o \ + moves/exit_lift.o \ + moves/exit_pellerator.o \ + moves/exit_state_room.o \ + moves/exit_tiania.o \ + moves/move_player_in_parrot_room.o \ + moves/move_player_to_from.o \ + moves/move_player_to.o \ + moves/multi_move.o \ + moves/pan_from_pel.o \ + moves/restaurant_pan_handler.o \ + moves/restricted_move.o \ + moves/scraliontis_table.o \ + moves/trip_down_canal.o \ + npcs/barbot.o \ + npcs/bellbot.o \ + npcs/callbot.o \ + npcs/character.o \ + npcs/deskbot.o \ + npcs/doorbot.o \ + npcs/liftbot.o \ + npcs/maitre_d.o \ + npcs/mobile.o \ + npcs/parrot.o \ + npcs/robot_controller.o \ + npcs/starlings.o \ + npcs/succubus.o \ + npcs/summon_bots.o \ + npcs/titania.o \ + npcs/true_talk_npc.o \ + pet_control/pet_control.o \ + pet_control/pet_conversations.o \ + pet_control/pet_element.o \ + pet_control/pet_frame.o \ + pet_control/pet_gfx_element.o \ + pet_control/pet_inventory.o \ + pet_control/pet_inventory_glyphs.o \ + pet_control/pet_message.o \ + pet_control/pet_starfield.o \ + pet_control/pet_real_life.o \ + pet_control/pet_remote.o \ + pet_control/pet_remote_glyphs.o \ + pet_control/pet_rooms.o \ + pet_control/pet_rooms_glyphs.o \ + pet_control/pet_section.o \ + pet_control/pet_drag_chev.o \ + pet_control/pet_graphic2.o \ + pet_control/pet_graphic.o \ + pet_control/pet_glyphs.o \ + pet_control/pet_leaf.o \ + pet_control/pet_load.o \ + pet_control/pet_load_save.o \ + pet_control/pet_mode_off.o \ + pet_control/pet_mode_on.o \ + pet_control/pet_mode_panel.o \ + pet_control/pet_pannel1.o \ + pet_control/pet_pannel2.o \ + pet_control/pet_pannel3.o \ + pet_control/pet_quit.o \ + pet_control/pet_save.o \ + pet_control/pet_slider.o \ + pet_control/pet_sound.o \ + pet_control/pet_text.o \ + sound/auto_music_player.o \ + sound/auto_music_player_base.o \ + sound/auto_sound_player.o \ + sound/auto_sound_player_adsr.o \ + sound/background_sound_maker.o \ + sound/bird_song.o \ + sound/dome_from_top_of_well.o \ + sound/enter_view_toggles_other_music.o \ + sound/gondolier_song.o \ + sound/music_handler.o \ + sound/music_room.o \ + sound/music_player.o \ + sound/music_wave.o \ + sound/node_auto_sound_player.o \ + sound/proximity.o \ + sound/qmixer.o \ + sound/restricted_auto_music_player.o \ + sound/room_auto_sound_player.o \ + sound/room_trigger_auto_music_player.o \ + sound/season_noises.o \ + sound/seasonal_music_player.o \ + sound/sound.o \ + sound/sound_manager.o \ + sound/titania_speech.o \ + sound/trigger_auto_music_player.o \ + sound/view_auto_sound_player.o \ + sound/view_toggles_other_music.o \ + sound/water_lapping_sounds.o \ + sound/wave_file.o \ + star_control/star_control.o \ + star_control/base_star.o \ + star_control/dmatrix.o \ + star_control/dvector.o \ + star_control/fmatrix.o \ + star_control/fpoint.o \ + star_control/fvector.o \ + star_control/star_control_sub2.o \ + star_control/star_control_sub4.o \ + star_control/star_control_sub5.o \ + star_control/star_control_sub6.o \ + star_control/star_control_sub7.o \ + star_control/star_control_sub8.o \ + star_control/star_control_sub12.o \ + star_control/star_control_sub13.o \ + star_control/star_control_sub20.o \ + star_control/star_control_sub21.o \ + star_control/star_control_sub22.o \ + star_control/star_control_sub23.o \ + star_control/star_control_sub24.o \ + star_control/star_control_sub25.o \ + star_control/star_control_sub26.o \ + star_control/star_control_sub27.o \ + star_control/star_field.o \ + star_control/star_points1.o \ + star_control/star_points2.o \ + star_control/star_view.o \ + star_control/surface_area.o \ + star_control/surface_fader_base.o \ + star_control/surface_fader.o \ + support/avi_surface.o \ + support/direct_draw.o \ + support/direct_draw_surface.o \ + support/exe_resources.o \ + support/files_manager.o \ + support/font.o \ + support/image.o \ + support/image_decoders.o \ + support/mouse_cursor.o \ + support/movie.o \ + support/movie_clip.o \ + support/movie_event.o \ + support/movie_range_info.o \ + support/movie_manager.o \ + support/credit_text.o \ + support/rect.o \ + support/screen_manager.o \ + support/simple_file.o \ + support/string.o \ + support/text_cursor.o \ + support/time_event_info.o \ + support/video_surface.o \ + true_talk/barbot_script.o \ + true_talk/bellbot_script.o \ + true_talk/deskbot_script.o \ + true_talk/dialogue_file.o \ + true_talk/doorbot_script.o \ + true_talk/liftbot_script.o \ + true_talk/maitred_script.o \ + true_talk/parrot_script.o \ + true_talk/succubus_script.o \ + true_talk/title_engine.o \ + true_talk/script_handler.o \ + true_talk/script_support.o \ + true_talk/true_talk_manager.o \ + true_talk/tt_action.o \ + true_talk/tt_adj.o \ + true_talk/tt_concept.o \ + true_talk/tt_concept_node.o \ + true_talk/tt_hist.o \ + true_talk/tt_major_word.o \ + true_talk/tt_node.o \ + true_talk/tt_npc_script.o \ + true_talk/tt_parser.o \ + true_talk/tt_picture.o \ + true_talk/tt_pronoun.o \ + true_talk/tt_quotes.o \ + true_talk/tt_quotes_tree.o \ + true_talk/tt_response.o \ + true_talk/tt_room_script.o \ + true_talk/tt_script_base.o \ + true_talk/tt_scripts.o \ + true_talk/tt_sentence.o \ + true_talk/tt_sentence_node.o \ + true_talk/tt_string.o \ + true_talk/tt_string_node.o \ + true_talk/tt_synonym.o \ + true_talk/tt_talker.o \ + true_talk/tt_title_script.o \ + true_talk/tt_vocab.o \ + true_talk/tt_word.o + +# This module can be built as a plugin +ifeq ($(ENABLE_TITANIC), DYNAMIC_PLUGIN) +PLUGIN := 1 +endif + +# Include common rules +include $(srcdir)/rules.mk diff --git a/engines/titanic/moves/enter_bomb_room.cpp b/engines/titanic/moves/enter_bomb_room.cpp new file mode 100644 index 0000000000..55b838d026 --- /dev/null +++ b/engines/titanic/moves/enter_bomb_room.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/moves/enter_bomb_room.h" + +namespace Titanic { + +CEnterBombRoom::CEnterBombRoom() : CMovePlayerTo(), _fieldC8(0) { +} + +void CEnterBombRoom::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMovePlayerTo::save(file, indent); +} + +void CEnterBombRoom::load(SimpleFile *file) { + file->readNumber(); + CMovePlayerTo::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/enter_bomb_room.h b/engines/titanic/moves/enter_bomb_room.h new file mode 100644 index 0000000000..7fe8287eae --- /dev/null +++ b/engines/titanic/moves/enter_bomb_room.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_ENTER_BOMB_ROOM_H +#define TITANIC_ENTER_BOMB_ROOM_H + +#include "titanic/moves/move_player_to.h" + +namespace Titanic { + +class CEnterBombRoom : public CMovePlayerTo { +protected: + int _fieldC8; +public: + CLASSDEF; + CEnterBombRoom(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ENTER_BOMB_ROOM_H */ diff --git a/engines/titanic/moves/enter_bridge.cpp b/engines/titanic/moves/enter_bridge.cpp new file mode 100644 index 0000000000..2600ee699f --- /dev/null +++ b/engines/titanic/moves/enter_bridge.cpp @@ -0,0 +1,44 @@ +/* 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 "titanic/moves/enter_bridge.h" + +namespace Titanic { + +void CEnterBridge::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CEnterBridge::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +bool CEnterBridge::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CEnterBridge::handlEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/enter_bridge.h b/engines/titanic/moves/enter_bridge.h new file mode 100644 index 0000000000..a2410a6f1f --- /dev/null +++ b/engines/titanic/moves/enter_bridge.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_ENTER_BRIDGE_H +#define TITANIC_ENTER_BRIDGE_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CEnterBridge : public CGameObject { + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + int _value; +public: + CLASSDEF; + CEnterBridge() : CGameObject(), _value(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ENTER_BRIDGE_H */ diff --git a/engines/titanic/moves/enter_exit_first_class_state.cpp b/engines/titanic/moves/enter_exit_first_class_state.cpp new file mode 100644 index 0000000000..0e2c6c0b6c --- /dev/null +++ b/engines/titanic/moves/enter_exit_first_class_state.cpp @@ -0,0 +1,49 @@ +/* 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 "titanic/moves/enter_exit_first_class_state.h" + +namespace Titanic { + +CString *CEnterExitFirstClassState::_v1; + +void CEnterExitFirstClassState::init() { + _v1 = new CString(); +} + +void CEnterExitFirstClassState::deinit() { + delete _v1; +} + +void CEnterExitFirstClassState::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(*_v1, indent); + CGameObject::save(file, indent); +} + +void CEnterExitFirstClassState::load(SimpleFile *file) { + file->readNumber(); + *_v1 = file->readString(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/enter_exit_first_class_state.h b/engines/titanic/moves/enter_exit_first_class_state.h new file mode 100644 index 0000000000..a08de07711 --- /dev/null +++ b/engines/titanic/moves/enter_exit_first_class_state.h @@ -0,0 +1,59 @@ +/* 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 TITANIC_ENTER_EXIT_FIRST_CLASS_STATE_H +#define TITANIC_ENTER_EXIT_FIRST_CLASS_STATE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CEnterExitFirstClassState : public CGameObject { +public: + static CString *_v1; + + /** + * Initialize static data + */ + static void init(); + + /** + * De-initialize static data + */ + static void deinit(); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ENTER_EXIT_FIRST_CLASS_STATE_H */ diff --git a/engines/titanic/moves/enter_exit_mini_lift.cpp b/engines/titanic/moves/enter_exit_mini_lift.cpp new file mode 100644 index 0000000000..eb56bdb3bd --- /dev/null +++ b/engines/titanic/moves/enter_exit_mini_lift.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/moves/enter_exit_mini_lift.h" + +namespace Titanic { + +void CEnterExitMiniLift::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + + CSGTNavigation::save(file, indent); +} + +void CEnterExitMiniLift::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + + CSGTNavigation::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/enter_exit_mini_lift.h b/engines/titanic/moves/enter_exit_mini_lift.h new file mode 100644 index 0000000000..26f3dba8d4 --- /dev/null +++ b/engines/titanic/moves/enter_exit_mini_lift.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_ENTER_EXIT_MINI_LIFT_H +#define TITANIC_ENTER_EXIT_MINI_LIFT_H + +#include "titanic/game/sgt/sgt_navigation.h" + +namespace Titanic { + +class CEnterExitMiniLift : public CSGTNavigation { +private: + int _fieldBC; + int _fieldC0; +public: + CLASSDEF; + CEnterExitMiniLift() : CSGTNavigation(), _fieldBC(0), _fieldC0(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ENTER_EXIT_MINI_LIFT_H */ diff --git a/engines/titanic/moves/enter_exit_sec_class_mini_lift.cpp b/engines/titanic/moves/enter_exit_sec_class_mini_lift.cpp new file mode 100644 index 0000000000..b571a255c5 --- /dev/null +++ b/engines/titanic/moves/enter_exit_sec_class_mini_lift.cpp @@ -0,0 +1,55 @@ +/* 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 "titanic/moves/enter_exit_sec_class_mini_lift.h" + +namespace Titanic { + +CEnterExitSecClassMiniLiftStatics *CEnterExitSecClassMiniLift::_statics; + +void CEnterExitSecClassMiniLift::init() { + _statics = new CEnterExitSecClassMiniLiftStatics(); +} + +void CEnterExitSecClassMiniLift::deinit() { + delete _statics; +} + +void CEnterExitSecClassMiniLift::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_statics->_v1, indent); + file->writeNumberLine(_statics->_v2, indent); + file->writeNumberLine(_value, indent); + + CGameObject::save(file, indent); +} + +void CEnterExitSecClassMiniLift::load(SimpleFile *file) { + file->readNumber(); + _statics->_v1 = file->readString(); + _statics->_v2 = file->readNumber(); + _value = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/enter_exit_sec_class_mini_lift.h b/engines/titanic/moves/enter_exit_sec_class_mini_lift.h new file mode 100644 index 0000000000..10c7edca7d --- /dev/null +++ b/engines/titanic/moves/enter_exit_sec_class_mini_lift.h @@ -0,0 +1,60 @@ +/* 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 TITANIC_ENTER_EXIT_SEC_CLASS_MINI_LIFT_H +#define TITANIC_ENTER_EXIT_SEC_CLASS_MINI_LIFT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +struct CEnterExitSecClassMiniLiftStatics { + CString _v1; + int _v2; + + CEnterExitSecClassMiniLiftStatics() : _v2(1) {} +}; + +class CEnterExitSecClassMiniLift : public CGameObject { +private: + static CEnterExitSecClassMiniLiftStatics *_statics; + int _value; +public: + CLASSDEF; + CEnterExitSecClassMiniLift() : CGameObject(), _value(0) {} + static void init(); + static void deinit(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ENTER_EXIT_SEC_CLASS_MINI_LIFT_H */ diff --git a/engines/titanic/moves/enter_exit_view.cpp b/engines/titanic/moves/enter_exit_view.cpp new file mode 100644 index 0000000000..825156acce --- /dev/null +++ b/engines/titanic/moves/enter_exit_view.cpp @@ -0,0 +1,53 @@ +/* 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 "titanic/moves/enter_exit_view.h" + +namespace Titanic { + +CEnterExitView::CEnterExitView() : CGameObject(), _fieldBC(0), + _fieldC0(0), _fieldC4(0), _fieldC8(0), _fieldCC(0) { +} + +void CEnterExitView::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeNumberLine(_fieldCC, indent); + + CGameObject::save(file, indent); +} + +void CEnterExitView::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + _fieldC8 = file->readNumber(); + _fieldCC = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/enter_exit_view.h b/engines/titanic/moves/enter_exit_view.h new file mode 100644 index 0000000000..4a3f1a967b --- /dev/null +++ b/engines/titanic/moves/enter_exit_view.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_ENTER_EXIT_VIEW_H +#define TITANIC_ENTER_EXIT_VIEW_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CEnterExitView : public CGameObject { +public: + int _fieldBC; + int _fieldC0; + int _fieldC4; + int _fieldC8; + int _fieldCC; +public: + CLASSDEF; + CEnterExitView(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ENTER_EXIT_VIEW_H */ diff --git a/engines/titanic/moves/enter_sec_class_state.cpp b/engines/titanic/moves/enter_sec_class_state.cpp new file mode 100644 index 0000000000..dced724de7 --- /dev/null +++ b/engines/titanic/moves/enter_sec_class_state.cpp @@ -0,0 +1,43 @@ +/* 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 "titanic/moves/enter_sec_class_state.h" + +namespace Titanic { + +void CEnterSecClassState::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value1, indent); + file->writeNumberLine(_value2, indent); + + CGameObject::save(file, indent); +} + +void CEnterSecClassState::load(SimpleFile *file) { + file->readNumber(); + _value1 = file->readNumber(); + _value2 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/enter_sec_class_state.h b/engines/titanic/moves/enter_sec_class_state.h new file mode 100644 index 0000000000..c3e3cabf20 --- /dev/null +++ b/engines/titanic/moves/enter_sec_class_state.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_ENTER_SEC_CLASS_STATE_H +#define TITANIC_ENTER_SEC_CLASS_STATE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CEnterSecClassState : public CGameObject { +public: + int _value1, _value2; +public: + CLASSDEF; + CEnterSecClassState() : CGameObject(), _value1(0), _value2(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ENTER_SEC_CLASS_STATE_H */ diff --git a/engines/titanic/moves/exit_arboretum.cpp b/engines/titanic/moves/exit_arboretum.cpp new file mode 100644 index 0000000000..d606510c6e --- /dev/null +++ b/engines/titanic/moves/exit_arboretum.cpp @@ -0,0 +1,49 @@ +/* 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 "titanic/moves/exit_arboretum.h" + +namespace Titanic { + +CExitArboretum::CExitArboretum() : CMovePlayerTo(), + _fieldC8(0), _fieldCC(0), _fieldD0(1) { +} + +void CExitArboretum::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeNumberLine(_fieldCC, indent); + file->writeNumberLine(_fieldD0, indent); + + CMovePlayerTo::save(file, indent); +} + +void CExitArboretum::load(SimpleFile *file) { + file->readNumber(); + _fieldC8 = file->readNumber(); + _fieldCC = file->readNumber(); + _fieldD0 = file->readNumber(); + + CMovePlayerTo::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/exit_arboretum.h b/engines/titanic/moves/exit_arboretum.h new file mode 100644 index 0000000000..f6ebf71515 --- /dev/null +++ b/engines/titanic/moves/exit_arboretum.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_EXIT_ARBORETUM_H +#define TITANIC_EXIT_ARBORETUM_H + +#include "titanic/moves/move_player_to.h" + +namespace Titanic { + +class CExitArboretum : public CMovePlayerTo { +protected: + int _fieldC8; + int _fieldCC; + int _fieldD0; +public: + CLASSDEF; + CExitArboretum(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BACKGROUND_H */ diff --git a/engines/titanic/moves/exit_bridge.cpp b/engines/titanic/moves/exit_bridge.cpp new file mode 100644 index 0000000000..b913911341 --- /dev/null +++ b/engines/titanic/moves/exit_bridge.cpp @@ -0,0 +1,44 @@ +/* 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 "titanic/moves/exit_bridge.h" + +namespace Titanic { + +CExitBridge::CExitBridge() : CMovePlayerTo() { +} + +void CExitBridge::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + + CMovePlayerTo::save(file, indent); +} + +void CExitBridge::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + + CMovePlayerTo::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/exit_bridge.h b/engines/titanic/moves/exit_bridge.h new file mode 100644 index 0000000000..4ab29524db --- /dev/null +++ b/engines/titanic/moves/exit_bridge.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_EXIT_BRIDGE_H +#define TITANIC_EXIT_BRIDGE_H + +#include "titanic/moves/move_player_to.h" + +namespace Titanic { + +class CExitBridge : public CMovePlayerTo { +private: + CString _string1; +public: + CLASSDEF; + CExitBridge(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EXIT_BRIDGE_H */ diff --git a/engines/titanic/moves/exit_lift.cpp b/engines/titanic/moves/exit_lift.cpp new file mode 100644 index 0000000000..a264be883d --- /dev/null +++ b/engines/titanic/moves/exit_lift.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/moves/exit_lift.h" + +namespace Titanic { + +void CExitLift::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_value, indent); + CGameObject::save(file, indent); +} + +void CExitLift::load(SimpleFile *file) { + file->readNumber(); + _value = file->readString(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/exit_lift.h b/engines/titanic/moves/exit_lift.h new file mode 100644 index 0000000000..04dabfaf13 --- /dev/null +++ b/engines/titanic/moves/exit_lift.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_EXIT_LIFT_H +#define TITANIC_EXIT_LIFT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CExitLift : public CGameObject { +public: + CString _value; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EXIT_LIFT_H */ diff --git a/engines/titanic/moves/exit_pellerator.cpp b/engines/titanic/moves/exit_pellerator.cpp new file mode 100644 index 0000000000..68a2a8da91 --- /dev/null +++ b/engines/titanic/moves/exit_pellerator.cpp @@ -0,0 +1,55 @@ +/* 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 "titanic/moves/exit_pellerator.h" + +namespace Titanic { + +CExitPelleratorStatics *CExitPellerator::_statics; + +void CExitPellerator::init() { + _statics = new CExitPelleratorStatics(); +} + +void CExitPellerator::deinit() { + delete _statics; +} + +void CExitPellerator::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_statics->_v1, indent); + file->writeNumberLine(_statics->_v2, indent); + file->writeNumberLine(_statics->_v3, indent); + + CGameObject::save(file, indent); +} + +void CExitPellerator::load(SimpleFile *file) { + file->readNumber(); + _statics->_v1 = file->readString(); + _statics->_v2 = file->readNumber(); + _statics->_v3 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/exit_pellerator.h b/engines/titanic/moves/exit_pellerator.h new file mode 100644 index 0000000000..280d1e9a6c --- /dev/null +++ b/engines/titanic/moves/exit_pellerator.h @@ -0,0 +1,57 @@ +/* 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 TITANIC_EXIT_PELLERATOR_H +#define TITANIC_EXIT_PELLERATOR_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +struct CExitPelleratorStatics { + CString _v1; + int _v2; + int _v3; +}; + +class CExitPellerator : public CGameObject { +private: + static CExitPelleratorStatics *_statics; +public: + CLASSDEF; + static void init(); + static void deinit(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EXIT_PELLERATOR_H */ diff --git a/engines/titanic/moves/exit_state_room.cpp b/engines/titanic/moves/exit_state_room.cpp new file mode 100644 index 0000000000..1c78a69ac2 --- /dev/null +++ b/engines/titanic/moves/exit_state_room.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/moves/exit_state_room.h" + +namespace Titanic { + +CExitStateRoom::CExitStateRoom() : CMovePlayerTo(), _fieldC8(0) { +} + +void CExitStateRoom::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMovePlayerTo::save(file, indent); +} + +void CExitStateRoom::load(SimpleFile *file) { + file->readNumber(); + CMovePlayerTo::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/exit_state_room.h b/engines/titanic/moves/exit_state_room.h new file mode 100644 index 0000000000..c0f9737817 --- /dev/null +++ b/engines/titanic/moves/exit_state_room.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_EXIT_STATE_ROOM_H +#define TITANIC_EXIT_STATE_ROOM_H + +#include "titanic/moves/move_player_to.h" + +namespace Titanic { + +class CExitStateRoom : public CMovePlayerTo { +protected: + int _fieldC8; +public: + CLASSDEF; + CExitStateRoom(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EXIT_STATE_ROOM_H */ diff --git a/engines/titanic/moves/exit_tiania.cpp b/engines/titanic/moves/exit_tiania.cpp new file mode 100644 index 0000000000..6cb2422b1f --- /dev/null +++ b/engines/titanic/moves/exit_tiania.cpp @@ -0,0 +1,51 @@ +/* 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 "titanic/moves/exit_tiania.h" + +namespace Titanic { + +CExitTiania::CExitTiania() : CMovePlayerTo(), _fieldC8(0), + _string1("NULL"), _string2("NULL"), _string3("NULL") { +} + +void CExitTiania::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + file->writeQuotedLine(_string3, indent); + + CMovePlayerTo::save(file, indent); +} + +void CExitTiania::load(SimpleFile *file) { + file->readNumber(); + _fieldC8 = file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + _string3 = file->readString(); + + CMovePlayerTo::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/exit_tiania.h b/engines/titanic/moves/exit_tiania.h new file mode 100644 index 0000000000..c2b7772ce7 --- /dev/null +++ b/engines/titanic/moves/exit_tiania.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_EXIT_TIANIA_H +#define TITANIC_EXIT_TIANIA_H + +#include "titanic/moves/move_player_to.h" + +namespace Titanic { + +class CExitTiania : public CMovePlayerTo { +private: + int _fieldC8; + CString _string1; + CString _string2; + CString _string3; +public: + CLASSDEF; + CExitTiania(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EXIT_TIANIA_H */ diff --git a/engines/titanic/moves/move_player_in_parrot_room.cpp b/engines/titanic/moves/move_player_in_parrot_room.cpp new file mode 100644 index 0000000000..df38c63cd4 --- /dev/null +++ b/engines/titanic/moves/move_player_in_parrot_room.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/moves/move_player_in_parrot_room.h" + +namespace Titanic { + +CMovePlayerInParrotRoom::CMovePlayerInParrotRoom() : CMovePlayerTo() { +} + +void CMovePlayerInParrotRoom::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMovePlayerTo::save(file, indent); +} + +void CMovePlayerInParrotRoom::load(SimpleFile *file) { + file->readNumber(); + CMovePlayerTo::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/move_player_in_parrot_room.h b/engines/titanic/moves/move_player_in_parrot_room.h new file mode 100644 index 0000000000..de693fe2e2 --- /dev/null +++ b/engines/titanic/moves/move_player_in_parrot_room.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_MOVE_PLAYER_IN_PARROT_ROOM_H +#define TITANIC_MOVE_PLAYER_IN_PARROT_ROOM_H + +#include "titanic/moves/move_player_to.h" + +namespace Titanic { + +class CMovePlayerInParrotRoom : public CMovePlayerTo { +public: + CLASSDEF; + CMovePlayerInParrotRoom(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVE_PLAYER_IN_PARROT_ROOM_H */ diff --git a/engines/titanic/moves/move_player_to.cpp b/engines/titanic/moves/move_player_to.cpp new file mode 100644 index 0000000000..9b6000c4f8 --- /dev/null +++ b/engines/titanic/moves/move_player_to.cpp @@ -0,0 +1,44 @@ +/* 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 "titanic/moves/move_player_to.h" + +namespace Titanic { + +CMovePlayerTo::CMovePlayerTo() : CGameObject() { +} + +void CMovePlayerTo::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_destination, indent); + + CGameObject::save(file, indent); +} + +void CMovePlayerTo::load(SimpleFile *file) { + file->readNumber(); + _destination = file->readString(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/move_player_to.h b/engines/titanic/moves/move_player_to.h new file mode 100644 index 0000000000..4bfffcb0b2 --- /dev/null +++ b/engines/titanic/moves/move_player_to.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_MOVE_PLAYER_TO_H +#define TITANIC_MOVE_PLAYER_TO_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CMovePlayerTo : public CGameObject { +protected: + CString _destination; +public: + CLASSDEF; + CMovePlayerTo(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVE_PLAYER_TO_H */ diff --git a/engines/titanic/moves/move_player_to_from.cpp b/engines/titanic/moves/move_player_to_from.cpp new file mode 100644 index 0000000000..1a67dc8505 --- /dev/null +++ b/engines/titanic/moves/move_player_to_from.cpp @@ -0,0 +1,44 @@ +/* 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 "titanic/moves/move_player_to_from.h" + +namespace Titanic { + +CMovePlayerToFrom::CMovePlayerToFrom() : CGameObject() { +} + +void CMovePlayerToFrom::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string2, indent); + + CGameObject::save(file, indent); +} + +void CMovePlayerToFrom::load(SimpleFile *file) { + file->readNumber(); + _string2 = file->readString(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/move_player_to_from.h b/engines/titanic/moves/move_player_to_from.h new file mode 100644 index 0000000000..c9eefe532f --- /dev/null +++ b/engines/titanic/moves/move_player_to_from.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_MOVE_PLAYER_TO_FROM_H +#define TITANIC_MOVE_PLAYER_TO_FROM_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CMovePlayerToFrom : public CGameObject { +private: + CString _string2; +public: + CLASSDEF; + CMovePlayerToFrom(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVE_PLAYER_TO_FROM_H */ diff --git a/engines/titanic/moves/multi_move.cpp b/engines/titanic/moves/multi_move.cpp new file mode 100644 index 0000000000..fb5570df9b --- /dev/null +++ b/engines/titanic/moves/multi_move.cpp @@ -0,0 +1,52 @@ +/* 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 "titanic/moves/multi_move.h" + +namespace Titanic { + +CMultiMove::CMultiMove() : CMovePlayerTo() { +} + +void CMultiMove::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + file->writeQuotedLine(_string3, indent); + file->writeQuotedLine(_string4, indent); + file->writeQuotedLine(_string5, indent); + + CMovePlayerTo::save(file, indent); +} + +void CMultiMove::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + _string3 = file->readString(); + _string5 = file->readString(); + _string4 = file->readString(); + + CMovePlayerTo::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/multi_move.h b/engines/titanic/moves/multi_move.h new file mode 100644 index 0000000000..977afc2a20 --- /dev/null +++ b/engines/titanic/moves/multi_move.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_MULTI_MOVE_H +#define TITANIC_MULTI_MOVE_H + +#include "titanic/moves/move_player_to.h" + +namespace Titanic { + +class CMultiMove : public CMovePlayerTo { +private: + CString _string1; + CString _string2; + CString _string3; + CString _string4; + CString _string5; +public: + CLASSDEF; + CMultiMove(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MULTI_MOVE_H */ diff --git a/engines/titanic/moves/pan_from_pel.cpp b/engines/titanic/moves/pan_from_pel.cpp new file mode 100644 index 0000000000..fccc643ec5 --- /dev/null +++ b/engines/titanic/moves/pan_from_pel.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/moves/pan_from_pel.h" + +namespace Titanic { + +CPanFromPel::CPanFromPel() : CMovePlayerTo(), _fieldC8(0) { +} + +void CPanFromPel::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeQuotedLine(_string1, indent); + + CMovePlayerTo::save(file, indent); +} + +void CPanFromPel::load(SimpleFile *file) { + file->readNumber(); + _fieldC8 = file->readNumber(); + _string1 = file->readString(); + + CMovePlayerTo::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/pan_from_pel.h b/engines/titanic/moves/pan_from_pel.h new file mode 100644 index 0000000000..c81be9f338 --- /dev/null +++ b/engines/titanic/moves/pan_from_pel.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_PAN_FROM_PEL_H +#define TITANIC_PAN_FROM_PEL_H + +#include "titanic/moves/move_player_to.h" + +namespace Titanic { + +class CPanFromPel : public CMovePlayerTo { +protected: + int _fieldC8; + CString _string1; +public: + CLASSDEF; + CPanFromPel(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PAN_FROM_PEL_H */ diff --git a/engines/titanic/moves/restaurant_pan_handler.cpp b/engines/titanic/moves/restaurant_pan_handler.cpp new file mode 100644 index 0000000000..92f55b46cc --- /dev/null +++ b/engines/titanic/moves/restaurant_pan_handler.cpp @@ -0,0 +1,47 @@ +/* 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 "titanic/moves/restaurant_pan_handler.h" + +namespace Titanic { + +int CRestaurantPanHandler::_v1; + +void CRestaurantPanHandler::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + + CMovePlayerTo::save(file, indent); +} + +void CRestaurantPanHandler::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + + CMovePlayerTo::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/restaurant_pan_handler.h b/engines/titanic/moves/restaurant_pan_handler.h new file mode 100644 index 0000000000..4925aa685b --- /dev/null +++ b/engines/titanic/moves/restaurant_pan_handler.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_RESTAURANT_PAN_HANDLER_H +#define TITANIC_RESTAURANT_PAN_HANDLER_H + +#include "titanic/moves/move_player_to.h" + +namespace Titanic { + +class CRestaurantPanHandler : public CMovePlayerTo { +protected: + static int _v1; + + CString _string1; + CString _string2; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_RESTAURANT_PAN_HANDLER_H */ diff --git a/engines/titanic/moves/restricted_move.cpp b/engines/titanic/moves/restricted_move.cpp new file mode 100644 index 0000000000..5f18dab8ff --- /dev/null +++ b/engines/titanic/moves/restricted_move.cpp @@ -0,0 +1,44 @@ +/* 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 "titanic/moves/restricted_move.h" + +namespace Titanic { + +CRestrictedMove::CRestrictedMove() : CMovePlayerTo(), _fieldC8(0) { +} + +void CRestrictedMove::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldC8, indent); + + CMovePlayerTo::save(file, indent); +} + +void CRestrictedMove::load(SimpleFile *file) { + file->readNumber(); + _fieldC8 = file->readNumber(); + + CMovePlayerTo::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/restricted_move.h b/engines/titanic/moves/restricted_move.h new file mode 100644 index 0000000000..bdf093c353 --- /dev/null +++ b/engines/titanic/moves/restricted_move.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_RESTRICTED_MOVE_H +#define TITANIC_RESTRICTED_MOVE_H + +#include "titanic/moves/move_player_to.h" + +namespace Titanic { + +class CRestrictedMove : public CMovePlayerTo { +protected: + int _fieldC8; +public: + CLASSDEF; + CRestrictedMove(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_RESTRICTED_MOVE_H */ diff --git a/engines/titanic/moves/scraliontis_table.cpp b/engines/titanic/moves/scraliontis_table.cpp new file mode 100644 index 0000000000..77d2f9df60 --- /dev/null +++ b/engines/titanic/moves/scraliontis_table.cpp @@ -0,0 +1,51 @@ +/* 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 "titanic/moves/scraliontis_table.h" + +namespace Titanic { + +CScraliontisTable::CScraliontisTable() : CRestaurantPanHandler(), + _fieldE0(0), _fieldE4(0), _fieldE8(0), _fieldEC(0) { +} + +void CScraliontisTable::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + + CRestaurantPanHandler::save(file, indent); +} + +void CScraliontisTable::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + + CRestaurantPanHandler::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/scraliontis_table.h b/engines/titanic/moves/scraliontis_table.h new file mode 100644 index 0000000000..2ce3745654 --- /dev/null +++ b/engines/titanic/moves/scraliontis_table.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_SCRALIONTIS_TABLE_H +#define TITANIC_SCRALIONTIS_TABLE_H + +#include "titanic/moves/restaurant_pan_handler.h" + +namespace Titanic { + +class CScraliontisTable : public CRestaurantPanHandler { +private: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; +public: + CLASSDEF; + CScraliontisTable(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SCRALIONTIS_TABLE_H */ diff --git a/engines/titanic/moves/trip_down_canal.cpp b/engines/titanic/moves/trip_down_canal.cpp new file mode 100644 index 0000000000..c8051dda03 --- /dev/null +++ b/engines/titanic/moves/trip_down_canal.cpp @@ -0,0 +1,40 @@ +/* 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 "titanic/moves/trip_down_canal.h" + +namespace Titanic { + +CTripDownCanal::CTripDownCanal() : CMovePlayerTo() { +} + +void CTripDownCanal::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CMovePlayerTo::save(file, indent); +} + +void CTripDownCanal::load(SimpleFile *file) { + file->readNumber(); + CMovePlayerTo::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/moves/trip_down_canal.h b/engines/titanic/moves/trip_down_canal.h new file mode 100644 index 0000000000..736caf4131 --- /dev/null +++ b/engines/titanic/moves/trip_down_canal.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_TRIP_DOWN_CANAL_H +#define TITANIC_TRIP_DOWN_CANAL_H + +#include "titanic/moves/move_player_to.h" + +namespace Titanic { + +class CTripDownCanal : public CMovePlayerTo { +public: + CLASSDEF; + CTripDownCanal(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TRIP_DOWN_CANAL_H */ diff --git a/engines/titanic/npcs/barbot.cpp b/engines/titanic/npcs/barbot.cpp new file mode 100644 index 0000000000..8f1c5e6ab3 --- /dev/null +++ b/engines/titanic/npcs/barbot.cpp @@ -0,0 +1,241 @@ +/* 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 "titanic/npcs/barbot.h" + +namespace Titanic { + +int CBarbot::_v0; + +CBarbot::CBarbot() : CTrueTalkNPC() { + _field108 = 0; + _field10C = 0; + _field110 = 0; + _field114 = 0; + _field118 = 0; + _field11C = 0; + _field120 = 0; + _field124 = 0; + _field128 = 0; + _field12C = 0; + _field130 = 0; + _field134 = 0; + _field138 = 0; + _field13C = -1; + _field140 = 30; + _field144 = -1; + _field148 = -1; + _field14C = 0; + _field150 = 0; + _field154 = 0; + _field158 = -1; + _field15C = 0; + _field160 = 0; + _field164 = 558; + _field168 = 585; + _field16C = 659; + _field170 = 692; + _field174 = 802; + _field178 = 816; + _field17C = 1941; + _field180 = 1977; + _field184 = 1901; + _field188 = 1941; + _field18C = 810; + _field190 = 816; + _field194 = 857; + _field198 = 865; + _field19C = 842; + _field1A0 = 857; + _field1A4 = 821; + _field1A8 = 842; + _field1AC = 682; + _field1B0 = 692; + _field1B4 = 1977; + _field1B8 = 2018; + _field1BC = 2140; + _field1C0 = 2170; + _field1C4 = 2101; + _field1C8 = 2139; + _field1CC = 2018; + _field1D0 = 2099; + _field1D4 = 1902; + _field1D8 = 2015; + _field1E0 = 1811; + _field1E4 = 1901; + _field1E8 = 1810; + _field1EC = 1703; + _field1F0 = 1750; + _field1F4 = 1681; + _field1F8 = 1702; + _field1FC = 1642; + + _field200 = 1702; + _field204 = 1571; + _field208 = 1641; + _field20C = 1499; + _field210 = 1570; + _field214 = 1403; + _field218 = 1463; + _field21C = 1464; + _field220 = 1499; + _field224 = 1288; + _field228 = 1295; + _field22C = 1266; + _field230 = 1287; + _field234 = 1245; + _field238 = 1265; + _field23C = 1208; + _field240 = 1244; + _field244 = 1171; + _field248 = 1207; + _field24C = 1120; + _field250 = 1170; + _field254 = 1092; + _field258 = 1120; + _field25C = 1092; + _field260 = 1092; + _field264 = 1044; + _field268 = 1091; + _field26C = 1011; + _field270 = 1043; + _field274 = 1001; + _field278 = 1010; + _field27C = 985; + _field280 = 1001; + _field284 = 927; + _field288 = 984; + _field28C = 912; + _field290 = 926; + _field294 = 898; + _field298 = 906; + _field29C = 802; + _field2A0 = 896; + _field2A4 = 865; + _field2A8 = 896; + _field2AC = 842; + _field2B0 = 865; + _field2B4 = 816; + _field2B8 = 842; + _field2BC = 802; + _field2C0 = 842; + _field2C4 = 740; + _field2C8 = 740; + _field2CC = 740; + _field2D0 = 692; + _field2D4 = 610; + _field2D8 = 558; + _field2E0 = 610; + _field2E4 = 500; + _field2E8 = 558; + _field2EC = 467; + _field2F0 = 500; + _field2F4 = 421; + _field2F8 = 466; + _field2FC = 349; + _field300 = 306; + _field304 = 306; + _field308 = 348; + _field30C = 305; + _field310 = 306; + _field314 = 281; + _field318 = 305; + _field31C = 202; + _field320 = 281; + _field324 = 182; + _field328 = 202; + _field32C = 165; + _field330 = 182; + _field334 = 96; + _field338 = 165; + _field33C = 0; + _field340 = 95; +} + +void CBarbot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field108, indent); + file->writeNumberLine(_field10C, indent); + file->writeNumberLine(_field110, indent); + file->writeNumberLine(_field114, indent); + file->writeNumberLine(_field118, indent); + file->writeNumberLine(_field11C, indent); + file->writeNumberLine(_field120, indent); + file->writeNumberLine(_field124, indent); + file->writeNumberLine(_field128, indent); + + file->writeNumberLine(_v0, indent); + file->writeNumberLine(_field12C, indent); + file->writeNumberLine(_field130, indent); + file->writeNumberLine(_field134, indent); + file->writeNumberLine(_field138, indent); + file->writeNumberLine(_field13C, indent); + file->writeNumberLine(_field140, indent); + file->writeNumberLine(_field144, indent); + file->writeNumberLine(_field148, indent); + file->writeNumberLine(_field14C, indent); + file->writeNumberLine(_field150, indent); + file->writeNumberLine(_field154, indent); + file->writeNumberLine(_field158, indent); + file->writeNumberLine(_field15C, indent); + file->writeNumberLine(_field160, indent); + + CTrueTalkNPC::save(file, indent); +} + +void CBarbot::load(SimpleFile *file) { + file->readNumber(); + _field108 = file->readNumber(); + _field10C = file->readNumber(); + _field110 = file->readNumber(); + _field114 = file->readNumber(); + _field118 = file->readNumber(); + _field11C = file->readNumber(); + _field120 = file->readNumber(); + _field124 = file->readNumber(); + _field128 = file->readNumber(); + + _v0 = file->readNumber(); + _field12C = file->readNumber(); + _field130 = file->readNumber(); + _field134 = file->readNumber(); + _field138 = file->readNumber(); + _field13C = file->readNumber(); + _field140 = file->readNumber(); + _field144 = file->readNumber(); + _field148 = file->readNumber(); + _field14C = file->readNumber(); + _field150 = file->readNumber(); + _field154 = file->readNumber(); + _field158 = file->readNumber(); + _field15C = file->readNumber(); + _field160 = file->readNumber(); + + CTrueTalkNPC::load(file); +} + +bool CBarbot::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("TODO: Barbot::CEnterRoomMsg"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/barbot.h b/engines/titanic/npcs/barbot.h new file mode 100644 index 0000000000..7557fdd2c6 --- /dev/null +++ b/engines/titanic/npcs/barbot.h @@ -0,0 +1,194 @@ +/* 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 TITANIC_BARBOT_H +#define TITANIC_BARBOT_H + +#include "titanic/npcs/true_talk_npc.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CBarbot : public CTrueTalkNPC { + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + static int _v0; +private: + int _field108; + int _field10C; + int _field110; + int _field114; + int _field118; + int _field11C; + int _field120; + int _field124; + int _field128; + int _field12C; + int _field130; + int _field134; + int _field138; + int _field13C; + int _field140; + int _field144; + int _field148; + int _field14C; + int _field150; + int _field154; + int _field158; + int _field15C; + int _field160; + int _field164; + int _field168; + int _field16C; + int _field170; + int _field174; + int _field178; + int _field17C; + int _field180; + int _field184; + int _field188; + int _field18C; + int _field190; + int _field194; + int _field198; + int _field19C; + int _field1A0; + int _field1A4; + int _field1A8; + int _field1AC; + int _field1B0; + int _field1B4; + int _field1B8; + int _field1BC; + int _field1C0; + int _field1C4; + int _field1C8; + int _field1CC; + int _field1D0; + int _field1D4; + int _field1D8; + int _field1E0; + int _field1E4; + int _field1E8; + int _field1EC; + int _field1F0; + int _field1F4; + int _field1F8; + int _field1FC; + int _field200; + int _field204; + int _field208; + int _field20C; + int _field210; + int _field214; + int _field218; + int _field21C; + int _field220; + int _field224; + int _field228; + int _field22C; + int _field230; + int _field234; + int _field238; + int _field23C; + int _field240; + int _field244; + int _field248; + int _field24C; + int _field250; + int _field254; + int _field258; + int _field25C; + int _field260; + int _field264; + int _field268; + int _field26C; + int _field270; + int _field274; + int _field278; + int _field27C; + int _field280; + int _field284; + int _field288; + int _field28C; + int _field290; + int _field294; + int _field298; + int _field29C; + int _field2A0; + int _field2A4; + int _field2A8; + int _field2AC; + int _field2B0; + int _field2B4; + int _field2B8; + int _field2BC; + int _field2C0; + int _field2C4; + int _field2C8; + int _field2CC; + int _field2D0; + int _field2D4; + int _field2D8; + int _field2E0; + int _field2E4; + int _field2E8; + int _field2EC; + int _field2F0; + int _field2F4; + int _field2F8; + int _field2FC; + int _field300; + int _field304; + int _field308; + int _field30C; + int _field310; + int _field314; + int _field318; + int _field31C; + int _field320; + int _field324; + int _field328; + int _field32C; + int _field330; + int _field334; + int _field338; + int _field33C; + int _field340; +public: + CLASSDEF; + CBarbot(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BARBOT_H */ diff --git a/engines/titanic/npcs/bellbot.cpp b/engines/titanic/npcs/bellbot.cpp new file mode 100644 index 0000000000..7ee0128a1e --- /dev/null +++ b/engines/titanic/npcs/bellbot.cpp @@ -0,0 +1,44 @@ +/* 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 "titanic/npcs/bellbot.h" + +namespace Titanic { + +CBellBot::CBellBot() : CTrueTalkNPC(), _field108(0) { +} + +void CBellBot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field108, indent); + + CTrueTalkNPC::save(file, indent); +} + +void CBellBot::load(SimpleFile *file) { + file->readNumber(); + _field108 = file->readNumber(); + + CTrueTalkNPC::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/bellbot.h b/engines/titanic/npcs/bellbot.h new file mode 100644 index 0000000000..93c4a2857d --- /dev/null +++ b/engines/titanic/npcs/bellbot.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_BELLBOT_H +#define TITANIC_BELLBOT_H + +#include "titanic/npcs/true_talk_npc.h" + +namespace Titanic { + +class CBellBot : public CTrueTalkNPC { +private: + int _field108; +public: + CLASSDEF; + CBellBot(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BELLBOT_H */ diff --git a/engines/titanic/npcs/callbot.cpp b/engines/titanic/npcs/callbot.cpp new file mode 100644 index 0000000000..eb0d4b71d5 --- /dev/null +++ b/engines/titanic/npcs/callbot.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/npcs/callbot.h" + +namespace Titanic { + +CCallBot::CCallBot() : CGameObject(), _fieldC8(0) { +} + +void CCallBot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + file->writeNumberLine(_fieldC8, indent); + + CGameObject::save(file, indent); +} + +void CCallBot::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + _fieldC8 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/callbot.h b/engines/titanic/npcs/callbot.h new file mode 100644 index 0000000000..9b89d59d3f --- /dev/null +++ b/engines/titanic/npcs/callbot.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_CALLBOT_H +#define TITANIC_CALLBOT_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CCallBot : public CGameObject { +protected: + CString _string1; + int _fieldC8; +public: + CLASSDEF; + CCallBot(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CALLBOT_H */ diff --git a/engines/titanic/npcs/character.cpp b/engines/titanic/npcs/character.cpp new file mode 100644 index 0000000000..ed36db16d3 --- /dev/null +++ b/engines/titanic/npcs/character.cpp @@ -0,0 +1,79 @@ +/* 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 "titanic/npcs/character.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CCharacter, CGameObject) + ON_MESSAGE(LeaveViewMsg) + ON_MESSAGE(TurnOn) + ON_MESSAGE(TurnOff) +END_MESSAGE_MAP() + +CCharacter::CCharacter() : CGameObject(), _fieldBC(0), _fieldC0(0), _fieldC4(1) { +} + +void CCharacter::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeQuotedLine(_charName, indent); + + CGameObject::save(file, indent); +} + +void CCharacter::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _fieldC4 = file->readNumber(); + _charName = file->readString(); + + CGameObject::load(file); +} + +bool CCharacter::LeaveViewMsg(CLeaveViewMsg *msg) { + CTurnOff offMsg; + offMsg.execute(this); + + return true; +} + +bool CCharacter::TurnOn(CTurnOn *msg) { + if (!_fieldC4) + _fieldC4 = 1; + + return true; +} + +bool CCharacter::TurnOff(CTurnOff *msg) { + CString charName = getName(); + if (charName == "Deskbot" || charName == "Barbot" || charName == "SuccUBus") { + _fieldC4 = 0; + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/character.h b/engines/titanic/npcs/character.h new file mode 100644 index 0000000000..4912740189 --- /dev/null +++ b/engines/titanic/npcs/character.h @@ -0,0 +1,57 @@ +/* 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 TITANIC_CHARACTER_H +#define TITANIC_CHARACTER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CCharacter : public CGameObject { + DECLARE_MESSAGE_MAP; + bool LeaveViewMsg(CLeaveViewMsg *msg); + bool TurnOn(CTurnOn *msg); + bool TurnOff(CTurnOff *msg); +protected: + int _fieldBC; + int _fieldC0; + int _fieldC4; + CString _charName; +public: + CLASSDEF; + CCharacter(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CHARACTER_H */ diff --git a/engines/titanic/npcs/deskbot.cpp b/engines/titanic/npcs/deskbot.cpp new file mode 100644 index 0000000000..d11b135983 --- /dev/null +++ b/engines/titanic/npcs/deskbot.cpp @@ -0,0 +1,310 @@ +/* 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 "titanic/npcs/deskbot.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +static const char *const TALKING_NAMES[] = { + "NeutralTalking", "HandFidget1", "HandFidget2", "LookingAround", + "FriendlyTalking", "MoreRudeness", "HandUp", "TapFingers", + "WaveOn", "WaveArmsAround", "HandsOverEdge" +}; + +static const char *const IDLE_NAMES[] = { + "WaveOn", "HandFidget1", "HandFidget2", "TapFingers", "HandsOverEdge" +}; + +BEGIN_MESSAGE_MAP(CDeskbot, CTrueTalkNPC) + ON_MESSAGE(TurnOn) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(ActMsg) + ON_MESSAGE(MovieEndMsg) + ON_MESSAGE(LeaveViewMsg) + ON_MESSAGE(TrueTalkTriggerActionMsg) + ON_MESSAGE(NPCPlayTalkingAnimationMsg) + ON_MESSAGE(NPCPlayIdleAnimationMsg) + ON_MESSAGE(TrueTalkNotifySpeechStartedMsg) + ON_MESSAGE(TrueTalkNotifySpeechEndedMsg) + ON_MESSAGE(TurnOff) +END_MESSAGE_MAP() + +int CDeskbot::_v1; +int CDeskbot::_v2; + +CDeskbot::CDeskbot() : CTrueTalkNPC(), _deskbotActive(false), _classNum(0) { +} + +void CDeskbot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + file->writeNumberLine(_deskbotActive, indent); + file->writeNumberLine(_classNum, indent); + + CTrueTalkNPC::save(file, indent); +} + +void CDeskbot::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + _deskbotActive = file->readNumber(); + _classNum = file->readNumber(); + + CTrueTalkNPC::load(file); +} + +bool CDeskbot::TurnOn(CTurnOn *msg) { + if (!_deskbotActive) { + setVisible(true); + playClip("BellRinging", 4); + playSound("b#69.wav"); + petSetArea(PET_CONVERSATION); + + _npcFlags |= NPCFLAG_20000; + _deskbotActive = true; + } + + return true; +} + +bool CDeskbot::EnterViewMsg(CEnterViewMsg *msg) { + setVisible(false); + _deskbotActive = false; + _fieldC4 = 0; + loadFrame(625); + + return true; +} + +bool CDeskbot::ActMsg(CActMsg *msg) { + if (msg->_action == "2ndClassUpgrade" && getPassengerClass() > 2) { + startTalking(this, 140, findView()); + } + + return true; +} + +bool CDeskbot::MovieEndMsg(CMovieEndMsg *msg) { + bool flag = false; + if (_npcFlags & NPCFLAG_10000) { + if (_classNum) { + petSetArea(PET_ROOMS); + dec54(); + unlockMouse(); + playSound("z#47.wav", 100, 0, 0); + _classNum = false; + } + + _npcFlags &= ~NPCFLAG_10000; + flag = true; + } + + if (_npcFlags & NPCFLAG_40000) { + _deskbotActive = false; + _npcFlags &= ~(NPCFLAG_40000 | NPCFLAG_20000); + + if (_npcFlags & NPCFLAG_80000) { + CTurnOn turnOn; + turnOn.execute("EmbBellbotTrigger"); + unlockMouse(); + changeView("EmbLobby.Node 4.N", ""); + } else if (_npcFlags & NPCFLAG_100000) { + CTurnOn turnOn; + turnOn.execute("EmbDoorBotTrigger"); + unlockMouse(); + changeView("EmbLobby.Node 4.N", ""); + } + + _npcFlags &= ~(NPCFLAG_80000 | NPCFLAG_100000); + flag = true; + } + + if (_npcFlags & NPCFLAG_20000) { + _npcFlags &= ~(NPCFLAG_40000 | NPCFLAG_20000); + endTalking(this, 1, findView()); + + _npcFlags |= NPCFLAG_4; + flag = true; + } + + if (!flag) + CTrueTalkNPC::MovieEndMsg(msg); + + return true; +} + +bool CDeskbot::LeaveViewMsg(CLeaveViewMsg *msg) { + if (_deskbotActive) { + CTurnOff turnOff; + turnOff.execute(this); + } + + return true; +} + +bool CDeskbot::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) { + switch (msg->_action) { + case 19: + inc54(); + lockMouse(); + petSetArea(PET_CONVERSATION); + playClip("ReprogramPETInHand", 4); + _npcFlags |= NPCFLAG_10000; + _classNum = msg->_param1; + + switch (_classNum) { + case 1: + petDisplayMessage("You have been upgraded to 1st Class status. Enjoy hugely."); + setPassengerClass(_classNum); + petReassignRoom(_classNum); + break; + case 2: + petDisplayMessage("You have been upgraded to 2nd Class status. Enjoy."); + setPassengerClass(_classNum); + petReassignRoom(_classNum); + break; + case 3: + setPassengerClass(3); + petReassignRoom(_classNum); + break; + default: + break; + } + + case 20: + if (getPassengerClass() == 1) { + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->changeLocationClass(4); + } + break; + + case 21: + if (getPassengerClass() == 1) { + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->changeLocationClass(3); + } + break; + + case 22: + if (getPassengerClass() == 1) { + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->changeLocationClass(2); + } + break; + + case 23: + if (getPassengerClass() == 1) { + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->changeLocationClass(1); + } + break; + + case 26: + _npcFlags |= NPCFLAG_80000; + CTurnOff turnOff; + turnOff.execute(this); + lockMouse(); + break; + } + + return true; +} + +bool CDeskbot::NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg) { + if (msg->_value2 != 2) + msg->_names = TALKING_NAMES; + + return true; +} + +bool CDeskbot::NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg) { + msg->_names = IDLE_NAMES; + return true; +} + +bool CDeskbot::TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg) { + if (_npcFlags & NPCFLAG_40000) + return true; + + CTrueTalkNPC::TrueTalkNotifySpeechStartedMsg(msg); + switch (msg->_dialogueId) { + case 41684: + case 41686: + case 41787: + case 41788: + case 41789: + lockMouse(); + break; + default: + break; + } + + return true; +} + +bool CDeskbot::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg) { + if (_npcFlags & NPCFLAG_40000) + return true; + + CTurnOff turnOff; + CTrueTalkNPC::TrueTalkNotifySpeechEndedMsg(msg); + + switch (msg->_dialogueId) { + case 41684: + case 41787: + case 41788: + case 41789: + _npcFlags |= NPCFLAG_80000; + turnOff.execute(this); + + case 41686: + _npcFlags |= NPCFLAG_100000; + turnOff.execute(this); + break; + + default: + break; + } + + return true; +} + +bool CDeskbot::TurnOff(CTurnOff *msg) { + if (_deskbotActive) { + stopMovie(); + performAction(1, findView()); + + _npcFlags = (_npcFlags & ~(NPCFLAG_SPEAKING | NPCFLAG_2 | NPCFLAG_4)) | NPCFLAG_40000; + playClip("Closing", 0x14); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/deskbot.h b/engines/titanic/npcs/deskbot.h new file mode 100644 index 0000000000..ab48d63546 --- /dev/null +++ b/engines/titanic/npcs/deskbot.h @@ -0,0 +1,66 @@ +/* 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 TITANIC_DESKBOT_H +#define TITANIC_DESKBOT_H + +#include "titanic/npcs/true_talk_npc.h" + +namespace Titanic { + +class CDeskbot : public CTrueTalkNPC { + DECLARE_MESSAGE_MAP; + bool TurnOn(CTurnOn *msg); + bool EnterViewMsg(CEnterViewMsg *msg); + bool ActMsg(CActMsg *msg); + bool MovieEndMsg(CMovieEndMsg *msg); + bool LeaveViewMsg(CLeaveViewMsg *msg); + bool TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg); + bool NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg); + bool NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg); + bool TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg); + bool TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg); + bool TurnOff(CTurnOff *msg); +private: + static int _v1; + static int _v2; +public: + bool _deskbotActive; + int _classNum; +public: + CLASSDEF; + CDeskbot(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DESKBOT_H */ diff --git a/engines/titanic/npcs/doorbot.cpp b/engines/titanic/npcs/doorbot.cpp new file mode 100644 index 0000000000..76db55f92c --- /dev/null +++ b/engines/titanic/npcs/doorbot.cpp @@ -0,0 +1,63 @@ +/* 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 "titanic/npcs/doorbot.h" + +namespace Titanic { + +int CDoorbot::_v1; +int CDoorbot::_v2; + +CDoorbot::CDoorbot() : CTrueTalkNPC() { + _field108 = 0; + _field10C = 0; + _field110 = 0; + _field114 = 0; +} + +void CDoorbot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + + file->writeNumberLine(_field108, indent); + file->writeNumberLine(_field10C, indent); + file->writeNumberLine(_field110, indent); + file->writeNumberLine(_field114, indent); + + CTrueTalkNPC::save(file, indent); +} + +void CDoorbot::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + + _field108 = file->readNumber(); + _field10C = file->readNumber(); + _field110 = file->readNumber(); + _field114 = file->readNumber(); + + CTrueTalkNPC::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/doorbot.h b/engines/titanic/npcs/doorbot.h new file mode 100644 index 0000000000..b62026c7d9 --- /dev/null +++ b/engines/titanic/npcs/doorbot.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_DOORBOT_H +#define TITANIC_DOORBOT_H + +#include "titanic/npcs/true_talk_npc.h" + +namespace Titanic { + +class CDoorbot : public CTrueTalkNPC { +private: + static int _v1; + static int _v2; +private: + int _field108; + int _field10C; + int _field110; + int _field114; +public: + CLASSDEF; + CDoorbot(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DOORBOT_H */ diff --git a/engines/titanic/npcs/liftbot.cpp b/engines/titanic/npcs/liftbot.cpp new file mode 100644 index 0000000000..43daa017c1 --- /dev/null +++ b/engines/titanic/npcs/liftbot.cpp @@ -0,0 +1,56 @@ +/* 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 "titanic/npcs/liftbot.h" + +namespace Titanic { + +int CLiftBot::_v1; +int CLiftBot::_v2; + +CLiftBot::CLiftBot() : CTrueTalkNPC(), _field108(1) { +} + +void CLiftBot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_field108, indent); + file->writeNumberLine(_v2, indent); + + CTrueTalkNPC::save(file, indent); +} + +void CLiftBot::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + _field108 = file->readNumber(); + _v2 = file->readNumber(); + + CTrueTalkNPC::load(file); +} + +bool CLiftBot::EnterRoomMsg(CEnterRoomMsg *msg) { + warning("CLiftBot::handleEvent"); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/liftbot.h b/engines/titanic/npcs/liftbot.h new file mode 100644 index 0000000000..7550a8a6f0 --- /dev/null +++ b/engines/titanic/npcs/liftbot.h @@ -0,0 +1,55 @@ +/* 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 TITANIC_LIFTBOT_H +#define TITANIC_LIFTBOT_H + +#include "titanic/npcs/true_talk_npc.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CLiftBot : public CTrueTalkNPC { + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + static int _v1; + static int _v2; +private: + int _field108; +public: + CLASSDEF; + CLiftBot(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LIFTBOT_H */ diff --git a/engines/titanic/npcs/maitre_d.cpp b/engines/titanic/npcs/maitre_d.cpp new file mode 100644 index 0000000000..903f3a49c9 --- /dev/null +++ b/engines/titanic/npcs/maitre_d.cpp @@ -0,0 +1,68 @@ +/* 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 "titanic/npcs/maitre_d.h" + +namespace Titanic { + +int CMaitreD::_v1; + +CMaitreD::CMaitreD() : CTrueTalkNPC(), + _string2("z#40.wav"), _string3("z#40.wav"), _field108(0), _field118(1), + _field11C(0), _field12C(0), _field130(1), _field134(0), _field138(0) { +} + +void CMaitreD::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_field108, indent); + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_field118, indent); + file->writeNumberLine(_field11C, indent); + file->writeQuotedLine(_string3, indent); + file->writeNumberLine(_field12C, indent); + file->writeNumberLine(_field130, indent); + + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_field134, indent); + file->writeNumberLine(_field138, indent); + + CTrueTalkNPC::save(file, indent); +} + +void CMaitreD::load(SimpleFile *file) { + file->readNumber(); + _field108 = file->readNumber(); + _string2 = file->readString(); + _field118 = file->readNumber(); + _field11C = file->readNumber(); + _string3 = file->readString(); + _field12C = file->readNumber(); + _field130 = file->readNumber(); + + _v1 = file->readNumber(); + _field134 = file->readNumber(); + _field138 = file->readNumber(); + + CTrueTalkNPC::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/maitre_d.h b/engines/titanic/npcs/maitre_d.h new file mode 100644 index 0000000000..af73f02a9a --- /dev/null +++ b/engines/titanic/npcs/maitre_d.h @@ -0,0 +1,60 @@ +/* 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 TITANIC_MAITRED_H +#define TITANIC_MAITRED_H + +#include "titanic/npcs/true_talk_npc.h" + +namespace Titanic { + +class CMaitreD : public CTrueTalkNPC { +private: + static int _v1; +private: + int _field108; + CString _string2; + int _field118; + int _field11C; + CString _string3; + int _field12C; + int _field130; + int _field134; + int _field138; +public: + CLASSDEF; + CMaitreD(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MAITRED_H */ diff --git a/engines/titanic/npcs/mobile.cpp b/engines/titanic/npcs/mobile.cpp new file mode 100644 index 0000000000..8a45f9e3cf --- /dev/null +++ b/engines/titanic/npcs/mobile.cpp @@ -0,0 +1,48 @@ +/* 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 "titanic/npcs/mobile.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CMobile, CCharacter); + +CMobile::CMobile() : CCharacter(), _fieldDC(0) { +} + +void CMobile::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writePoint(_pos1, indent); + file->writeNumberLine(_fieldDC, indent); + + CCharacter::save(file, indent); +} + +void CMobile::load(SimpleFile *file) { + file->readNumber(); + _pos1 = file->readPoint(); + _fieldDC = file->readNumber(); + + CCharacter::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/mobile.h b/engines/titanic/npcs/mobile.h new file mode 100644 index 0000000000..68e74a5afe --- /dev/null +++ b/engines/titanic/npcs/mobile.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_MOBILE_H +#define TITANIC_MOBILE_H + +#include "titanic/npcs/character.h" + +namespace Titanic { + +class CMobile : public CCharacter { + DECLARE_MESSAGE_MAP; +private: + Point _pos1; + int _fieldDC; +public: + CLASSDEF; + CMobile(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOBILE_H */ diff --git a/engines/titanic/npcs/parrot.cpp b/engines/titanic/npcs/parrot.cpp new file mode 100644 index 0000000000..49e4f4066e --- /dev/null +++ b/engines/titanic/npcs/parrot.cpp @@ -0,0 +1,143 @@ +/* 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 "titanic/npcs/parrot.h" + +namespace Titanic { + +int CParrot::_v1; +int CParrot::_v2; +int CParrot::_v3; +int CParrot::_v4; +int CParrot::_v5; + +CParrot::CParrot() : CTrueTalkNPC() { + _field108 = 0; + _string2 = "CarryParrot"; + _field118 = 1; + _field11C = 25; + _field120 = 0; + _field124 = 73; + _field128 = 58; + _field12C = 0; + _field130 = 0; + _field134 = 0; + _field138 = 851; + _field13C = 851; + _field140 = 265; + _field144 = 274; + _field148 = 726; + _field14C = 730; + _field150 = 510; + _field154 = 570; + _field158 = 569; + _field15C = 689; + _field160 = 690; + _field164 = 725; + _field168 = 375; + _field16C = 508; + _field170 = 363; + _field174 = 375; + _field178 = 303; + _field17C = 313; + _field180 = 279; + _field184 = 302; + _field188 = 260; + _field18C = 264; + _field190 = 315; + _field194 = 327; + _field198 = 330; + _field19C = 360; + _field1A0 = 175; + _field1A4 = 259; + _field1A8 = 175; + _field1AC = 175; + _field1B0 = 162; + _field1B4 = 175; + _field1B8 = 150; + _field1BC = 162; + _field1C0 = 135; + _field1C4 = 150; + _field1C8 = 95; + _field1CC = 135; + _field1D0 = 76; + _field1D4 = 95; + _field1D8 = 55; + _field1DC = 76; + _field1E0 = 30; + _field1E4 = 55; + _field1E8 = 0; + _field1EC = 30; + + _assetName = "z454.dlg"; + _assetNumber = 0x13880; +} + +void CParrot::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_assetNumber, indent); + + file->writeQuotedLine(_assetName, indent); + file->writeNumberLine(_field108, indent); + file->writeNumberLine(_v1, indent); + file->writeNumberLine(_v2, indent); + file->writeNumberLine(_v3, indent); + + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_field118, indent); + file->writeNumberLine(_field11C, indent); + file->writeNumberLine(_field120, indent); + file->writeNumberLine(_field124, indent); + file->writeNumberLine(_field128, indent); + file->writeNumberLine(_field12C, indent); + file->writeNumberLine(_field130, indent); + file->writeNumberLine(_v4, indent); + file->writeNumberLine(_v5, indent); + + CTrueTalkNPC::save(file, indent); +} + +void CParrot::load(SimpleFile *file) { + file->readNumber(); + _assetNumber = file->readNumber(); + + _assetName = file->readString(); + _field108 = file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + _v3 = file->readNumber(); + + _string2 = file->readString(); + _field118 = file->readNumber(); + _field11C = file->readNumber(); + _field120 = file->readNumber(); + _field124 = file->readNumber(); + _field128 = file->readNumber(); + _field12C = file->readNumber(); + _field130 = file->readNumber(); + _v4 = file->readNumber(); + _v5 = file->readNumber(); + + CTrueTalkNPC::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/parrot.h b/engines/titanic/npcs/parrot.h new file mode 100644 index 0000000000..a3c8540f0e --- /dev/null +++ b/engines/titanic/npcs/parrot.h @@ -0,0 +1,111 @@ +/* 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 TITANIC_PARROT_H +#define TITANIC_PARROT_H + +#include "titanic/npcs/true_talk_npc.h" + +namespace Titanic { + +class CParrot : public CTrueTalkNPC { +public: + static int _v1; + static int _v2; + static int _v3; + static int _v4; + static int _v5; +private: + int _field108; + CString _string2; + int _field118; + int _field11C; + int _field120; + int _field124; + int _field128; + int _field12C; + int _field130; + int _field134; + int _field138; + int _field13C; + int _field140; + int _field144; + int _field148; + int _field14C; + int _field150; + int _field154; + int _field158; + int _field15C; + int _field160; + int _field164; + int _field168; + int _field16C; + int _field170; + int _field174; + int _field178; + int _field17C; + int _field180; + int _field184; + int _field188; + int _field18C; + int _field190; + int _field194; + int _field198; + int _field19C; + int _field1A0; + int _field1A4; + int _field1A8; + int _field1AC; + int _field1B0; + int _field1B4; + int _field1B8; + int _field1BC; + int _field1C0; + int _field1C4; + int _field1C8; + int _field1CC; + int _field1D0; + int _field1D4; + int _field1D8; + int _field1DC; + int _field1E0; + int _field1E4; + int _field1E8; + int _field1EC; +public: + CLASSDEF; + CParrot(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARROT_H */ diff --git a/engines/titanic/npcs/robot_controller.cpp b/engines/titanic/npcs/robot_controller.cpp new file mode 100644 index 0000000000..98866e4505 --- /dev/null +++ b/engines/titanic/npcs/robot_controller.cpp @@ -0,0 +1,44 @@ +/* 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 "titanic/npcs/robot_controller.h" + +namespace Titanic { + +CRobotController::CRobotController() : CGameObject(), _string1("BellBot") { +} + +void CRobotController::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + + CGameObject::save(file, indent); +} + +void CRobotController::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/robot_controller.h b/engines/titanic/npcs/robot_controller.h new file mode 100644 index 0000000000..6cbf57aef2 --- /dev/null +++ b/engines/titanic/npcs/robot_controller.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_ROBOT_CONTROLLER_H +#define TITANIC_ROBOT_CONTROLLER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CRobotController : public CGameObject { +protected: + CString _string1; +public: + CLASSDEF; + CRobotController(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ROBOT_CONTROLLER_H */ diff --git a/engines/titanic/npcs/starlings.cpp b/engines/titanic/npcs/starlings.cpp new file mode 100644 index 0000000000..333f4c4b7a --- /dev/null +++ b/engines/titanic/npcs/starlings.cpp @@ -0,0 +1,46 @@ +/* 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 "titanic/npcs/starlings.h" + +namespace Titanic { + +int CStarlings::_v1; + +CStarlings::CStarlings() : CCharacter() { +} + +void CStarlings::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_v1, indent); + + CCharacter::save(file, indent); +} + +void CStarlings::load(SimpleFile *file) { + file->readNumber(); + _v1 = file->readNumber(); + + CCharacter::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/starlings.h b/engines/titanic/npcs/starlings.h new file mode 100644 index 0000000000..4d96e5c77f --- /dev/null +++ b/engines/titanic/npcs/starlings.h @@ -0,0 +1,50 @@ +/* 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 TITANIC_STARLINGS_H +#define TITANIC_STARLINGS_H + +#include "titanic/npcs/character.h" + +namespace Titanic { + +class CStarlings : public CCharacter { +private: + static int _v1; +public: + CLASSDEF; + CStarlings(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STARLING_H */ diff --git a/engines/titanic/npcs/succubus.cpp b/engines/titanic/npcs/succubus.cpp new file mode 100644 index 0000000000..f66a59cb84 --- /dev/null +++ b/engines/titanic/npcs/succubus.cpp @@ -0,0 +1,215 @@ +/* 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 "titanic/npcs/succubus.h" + +namespace Titanic { + +int CSuccUBus::_v0; +int CSuccUBus::_v1; +int CSuccUBus::_v2; +int CSuccUBus::_v3; +int CSuccUBus::_v4; + +CSuccUBus::CSuccUBus() : CTrueTalkNPC() { + _field108 = -1; + _field10C = -1; + _field110 = -1; + _field114 = -1; + _field118 = 0x44; + _field11C = 0xA8; + _field120 = 0xA8; + _field124 = 0xF8; + _field128 = 0; + _field12C = 0x0E; + _field130 = 0x0E; + _field134 = 27; + _field138 = 40; + _field13C = 0x44; + _field140 = 1; + _field144 = 0; + _field148 = 0; + _field14C = 0; + _field150 = 0xE0; + _field154 = 0; + _field158 = 0; + _field15C = 0; + _string2 = "NULL"; + _field16C = 28; + _field170 = 40; + _field174 = 82; + _field178 = 284; + _field17C = 148; + _field180 = 339; + _field184 = 15; + _field188 = 0; + _field18C = 0; + _field190 = 0; + _field194 = 240; + _field198 = 340; + _field19C = 0; + _field1A0 = -1; + _field1A4 = 0; + _field1A8 = 0; + _field1AC = 0; + _field1B0 = 0; + _field1B4 = 303; + _field1B8 = 312; + _field1BC = 313; + _field1C0 = 325; + _field1C4 = 326; + _field1C8 = 347; + _field1CC = 348; + _field1D0 = 375; + _field1D4 = 1; + _field1D8 = 0; +} + +void CSuccUBus::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + + file->writeNumberLine(_v0, indent); + file->writeNumberLine(_field108, indent); + file->writeNumberLine(_field10C, indent); + file->writeNumberLine(_field110, indent); + file->writeNumberLine(_field114, indent); + file->writeNumberLine(_field118, indent); + file->writeNumberLine(_field11C, indent); + file->writeNumberLine(_field120, indent); + file->writeNumberLine(_field124, indent); + file->writeNumberLine(_field128, indent); + file->writeNumberLine(_field12C, indent); + file->writeNumberLine(_field130, indent); + file->writeNumberLine(_field134, indent); + file->writeNumberLine(_field138, indent); + file->writeNumberLine(_field13C, indent); + file->writeNumberLine(_field140, indent); + + file->writeNumberLine(_v2, indent); + file->writeNumberLine(_field148, indent); + file->writeNumberLine(_field14C, indent); + file->writeNumberLine(_field150, indent); + file->writeNumberLine(_field154, indent); + file->writeNumberLine(_field158, indent); + file->writeNumberLine(_field15C, indent); + + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_field16C, indent); + file->writeNumberLine(_field170, indent); + file->writeNumberLine(_field174, indent); + file->writeNumberLine(_field178, indent); + file->writeNumberLine(_field17C, indent); + file->writeNumberLine(_field180, indent); + file->writeNumberLine(_field184, indent); + file->writeNumberLine(_field188, indent); + file->writeNumberLine(_field18C, indent); + file->writeNumberLine(_field190, indent); + file->writeNumberLine(_field194, indent); + file->writeNumberLine(_field198, indent); + file->writeNumberLine(_field19C, indent); + file->writeNumberLine(_field1A0, indent); + file->writeNumberLine(_field1A4, indent); + file->writeNumberLine(_field1A8, indent); + file->writeNumberLine(_field1AC, indent); + file->writeNumberLine(_field1B0, indent); + file->writeNumberLine(_field1B4, indent); + file->writeNumberLine(_field1B8, indent); + file->writeNumberLine(_field1BC, indent); + file->writeNumberLine(_field1C0, indent); + file->writeNumberLine(_field1C4, indent); + file->writeNumberLine(_field1C8, indent); + file->writeNumberLine(_field1CC, indent); + file->writeNumberLine(_field1D0, indent); + file->writeNumberLine(_field1D4, indent); + + file->writeNumberLine(_v3, indent); + file->writeNumberLine(_field1D8, indent); + file->writeNumberLine(_field104, indent); + + CTrueTalkNPC::save(file, indent); +} + +void CSuccUBus::load(SimpleFile *file) { + file->readNumber(); + + _v0 = file->readNumber(); + _field108 = file->readNumber(); + _field10C = file->readNumber(); + _field110 = file->readNumber(); + _field114 = file->readNumber(); + _field118 = file->readNumber(); + _field11C = file->readNumber(); + _field120 = file->readNumber(); + _field124 = file->readNumber(); + _field128 = file->readNumber(); + _field12C = file->readNumber(); + _field130 = file->readNumber(); + _field134 = file->readNumber(); + _field138 = file->readNumber(); + _field13C = file->readNumber(); + _field140 = file->readNumber(); + + _v2 = file->readNumber(); + _field148 = file->readNumber(); + _field14C = file->readNumber(); + _field150 = file->readNumber(); + _field154 = file->readNumber(); + _field158 = file->readNumber(); + _field15C = file->readNumber(); + + _string2 = file->readString(); + _field16C = file->readNumber(); + _field170 = file->readNumber(); + _field174 = file->readNumber(); + _field178 = file->readNumber(); + _field17C = file->readNumber(); + _field180 = file->readNumber(); + _field184 = file->readNumber(); + _field188 = file->readNumber(); + _field18C = file->readNumber(); + _field190 = file->readNumber(); + _field194 = file->readNumber(); + _field198 = file->readNumber(); + _field19C = file->readNumber(); + _field1A0 = file->readNumber(); + _field1A4 = file->readNumber(); + _field1A8 = file->readNumber(); + _field1AC = file->readNumber(); + _field1B0 = file->readNumber(); + _field1B4 = file->readNumber(); + _field1B8 = file->readNumber(); + _field1BC = file->readNumber(); + _field1C0 = file->readNumber(); + _field1C4 = file->readNumber(); + _field1C8 = file->readNumber(); + _field1CC = file->readNumber(); + _field1D0 = file->readNumber(); + _field1D4 = file->readNumber(); + + _v3 = file->readNumber(); + _field1D8 = file->readNumber(); + _field104 = file->readNumber(); + + CTrueTalkNPC::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/succubus.h b/engines/titanic/npcs/succubus.h new file mode 100644 index 0000000000..f6f5a6b9e9 --- /dev/null +++ b/engines/titanic/npcs/succubus.h @@ -0,0 +1,106 @@ +/* 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 TITANIC_SUCCUBUS_H +#define TITANIC_SUCCUBUS_H + +#include "titanic/npcs/true_talk_npc.h" + +namespace Titanic { + +class CSuccUBus : public CTrueTalkNPC { +private: + static int _v0; + static int _v1; + static int _v2; + static int _v3; + static int _v4; +private: + int _field108; + int _field10C; + int _field110; + int _field114; + int _field118; + int _field11C; + int _field120; + int _field124; + int _field128; + int _field12C; + int _field130; + int _field134; + int _field138; + int _field13C; + int _field140; + int _field144; + int _field148; + int _field14C; + int _field150; + int _field154; + int _field158; + int _field15C; + CString _string2; + int _field16C; + int _field170; + int _field174; + int _field178; + int _field17C; + int _field180; + int _field184; + int _field188; + int _field18C; + int _field190; + int _field194; + int _field198; + int _field19C; + int _field1A0; + int _field1A4; + int _field1A8; + int _field1AC; + int _field1B0; + int _field1B4; + int _field1B8; + int _field1BC; + int _field1C0; + int _field1C4; + int _field1C8; + int _field1CC; + int _field1D0; + int _field1D4; + int _field1D8; +public: + CLASSDEF; + CSuccUBus(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SUCCUBUS_H */ diff --git a/engines/titanic/npcs/summon_bots.cpp b/engines/titanic/npcs/summon_bots.cpp new file mode 100644 index 0000000000..8796e5ffda --- /dev/null +++ b/engines/titanic/npcs/summon_bots.cpp @@ -0,0 +1,49 @@ +/* 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 "titanic/npcs/summon_bots.h" + +namespace Titanic { + +CSummonBots::CSummonBots() : CRobotController(), _string2("NULL"), + _fieldC8(0), _fieldCC(0) { +} + +void CSummonBots::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldC8, indent); + file->writeNumberLine(_fieldCC, indent); + file->writeQuotedLine(_string2, indent); + + CRobotController::save(file, indent); +} + +void CSummonBots::load(SimpleFile *file) { + file->readNumber(); + _fieldC8 = file->readNumber(); + _fieldCC = file->readNumber(); + _string2 = file->readString(); + + CRobotController::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/summon_bots.h b/engines/titanic/npcs/summon_bots.h new file mode 100644 index 0000000000..ee537fee76 --- /dev/null +++ b/engines/titanic/npcs/summon_bots.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_SUMMON_BOTS_H +#define TITANIC_SUMMON_BOTS_H + +#include "titanic/npcs/robot_controller.h" + +namespace Titanic { + +class CSummonBots : public CRobotController { +protected: + CString _string2; + int _fieldC8; + int _fieldCC; +public: + CLASSDEF; + CSummonBots(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SUMMON_BOTS_H */ diff --git a/engines/titanic/npcs/titania.cpp b/engines/titanic/npcs/titania.cpp new file mode 100644 index 0000000000..34c21d0efe --- /dev/null +++ b/engines/titanic/npcs/titania.cpp @@ -0,0 +1,77 @@ +/* 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 "titanic/npcs/titania.h" + +namespace Titanic { + +CTitania::CTitania() : CCharacter() { + _fieldD4 = 0; + _fieldD8 = 0; + _fieldE0 = 0; + _fieldE4 = 0; + _fieldE8 = 0; + _fieldEC = 0; + _fieldF0 = 0; + _fieldF4 = 0; + _fieldF8 = 0; + _fieldFC = 0; + _field100 = 1; +} + +void CTitania::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldD4, indent); + file->writeNumberLine(_fieldD8, indent); + file->writeNumberLine(_fieldDC, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_fieldF0, indent); + file->writeNumberLine(_fieldF4, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_fieldFC, indent); + file->writeNumberLine(_field100, indent); + + CCharacter::save(file, indent); +} + +void CTitania::load(SimpleFile *file) { + file->readNumber(); + _fieldD4 = file->readNumber(); + _fieldD8 = file->readNumber(); + _fieldDC = file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + _fieldF0 = file->readNumber(); + _fieldF4 = file->readNumber(); + _fieldF8 = file->readNumber(); + _fieldFC = file->readNumber(); + _field100 = file->readNumber(); + + CCharacter::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/titania.h b/engines/titanic/npcs/titania.h new file mode 100644 index 0000000000..4edd626ab6 --- /dev/null +++ b/engines/titanic/npcs/titania.h @@ -0,0 +1,61 @@ +/* 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 TITANIC_TITANIA_H +#define TITANIC_TITANIA_H + +#include "titanic/npcs/character.h" + +namespace Titanic { + +class CTitania : public CCharacter { +private: + int _fieldD4; + int _fieldD8; + int _fieldDC; + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; + int _fieldF0; + int _fieldF4; + int _fieldF8; + int _fieldFC; + int _field100; +public: + CLASSDEF; + CTitania(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TITANIA_H */ diff --git a/engines/titanic/npcs/true_talk_npc.cpp b/engines/titanic/npcs/true_talk_npc.cpp new file mode 100644 index 0000000000..9310f285e5 --- /dev/null +++ b/engines/titanic/npcs/true_talk_npc.cpp @@ -0,0 +1,229 @@ +/* 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 "titanic/npcs/true_talk_npc.h" +#include "titanic/core/view_item.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/titanic.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CTrueTalkNPC, CCharacter) + ON_MESSAGE(TextInputMsg) + ON_MESSAGE(TrueTalkGetAssetDetailsMsg) + ON_MESSAGE(DismissBotMsg) + ON_MESSAGE(TrueTalkNotifySpeechStartedMsg) + ON_MESSAGE(TrueTalkNotifySpeechEndedMsg) + ON_MESSAGE(MovieEndMsg) + ON_MESSAGE(NPCQueueIdleAnimMsg) + ON_MESSAGE(TimerMsg) + ON_MESSAGE(NPCPlayAnimationMsg) +END_MESSAGE_MAP() + +CTrueTalkNPC::CTrueTalkNPC() : _assetName("z451.dlg"), + _assetNumber(0x11170), _fieldE4(0), _npcFlags(0), _soundId(0), _fieldF0(0), + _fieldF4(0), _fieldF8(0), _speechTimerId(0), _field100(0), _field104(0) { +} + +void CTrueTalkNPC::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_assetNumber, indent); + file->writeQuotedLine(_assetName, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_npcFlags, indent); + file->writeNumberLine(_soundId, indent); + file->writeNumberLine(_fieldF0, indent); + file->writeNumberLine(_fieldF4, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_speechTimerId, indent); + file->writeNumberLine(_field100, indent); + file->writeNumberLine(_field104, indent); + + CCharacter::save(file, indent); +} + +void CTrueTalkNPC::load(SimpleFile *file) { + file->readNumber(); + _assetNumber = file->readNumber(); + _assetName = file->readString(); + _fieldE4 = file->readNumber(); + _npcFlags = file->readNumber(); + _soundId = file->readNumber(); + _fieldF0 = file->readNumber(); + _fieldF4 = file->readNumber(); + _fieldF8 = file->readNumber(); + _speechTimerId = file->readNumber(); + _field100 = file->readNumber(); + _field104 = file->readNumber(); + + CCharacter::load(file); +} + +bool CTrueTalkNPC::TextInputMsg(CTextInputMsg *msg) { + processInput(msg, _field104 ? findView() : nullptr); + return true; +} + +bool CTrueTalkNPC::TrueTalkGetAssetDetailsMsg(CTrueTalkGetAssetDetailsMsg *msg) { + msg->_filename = _assetName; + msg->_numValue = _assetNumber; + return true; +} + +bool CTrueTalkNPC::DismissBotMsg(CDismissBotMsg *msg) { + performAction(1, 0); + return true; +} + +bool CTrueTalkNPC::TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg) { + _npcFlags |= NPCFLAG_SPEAKING; + ++_field100; + + if (!(_npcFlags & NPCFLAG_8)) { + if (_speechTimerId) + stopTimer(_speechTimerId); + + _soundId = msg->_soundId; + _fieldF0 = g_vm->_events->getTicksCount(); + + if (hasActiveMovie() || (_npcFlags & NPCFLAG_2)) { + _npcFlags &= ~NPCFLAG_2; + stopMovie(); + + CNPCPlayTalkingAnimationMsg msg1(_soundId, 0, 0); + msg1.execute(this); + + if (msg1._names) { + CNPCPlayAnimationMsg msg2(msg1._names, msg1._value1); + msg2.execute(this); + } + } + } + + return true; +} + +bool CTrueTalkNPC::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg) { + _npcFlags &= ~NPCFLAG_SPEAKING; + --_field100; + _soundId = 0; + + if (!(_npcFlags & NPCFLAG_8)) { + CNPCPlayTalkingAnimationMsg msg1(0, 2, 0); + msg1.execute(this); + CNPCQueueIdleAnimMsg msg2; + msg2.execute(this); + } + + return true; +} + +bool CTrueTalkNPC::MovieEndMsg(CMovieEndMsg *msg) { + if (_npcFlags & NPCFLAG_2) { + _npcFlags &= ~NPCFLAG_2; + CNPCQueueIdleAnimMsg idleMsg; + idleMsg.execute(this); + return true; + } else if (!(_npcFlags & NPCFLAG_SPEAKING)) { + return false; + } + + int diff = g_vm->_events->getTicksCount() - _fieldF0; + int ticks = MAX((int)_soundId - diff, 0); + CNPCPlayTalkingAnimationMsg msg1(ticks, ticks > 1000 ? 2 : 1, 0); + msg1.execute(this); + + if (msg1._names) { + CNPCPlayAnimationMsg msg2(msg1._names, msg1._value1); + msg2.execute(this); + } + + return true; +} + +bool CTrueTalkNPC::NPCQueueIdleAnimMsg(CNPCQueueIdleAnimMsg *msg) { + int rndVal = g_vm->getRandomNumber(_fieldF8 - 1) - (_fieldF8 / 2); + _speechTimerId = startAnimTimer("NPCIdleAnim", _fieldF4 + rndVal, 0); + + return true; +} + +bool CTrueTalkNPC::TimerMsg(CTimerMsg *msg) { + if (_npcFlags & NPCFLAG_4) { + if (_field100 > 0) + return false; + + CNPCPlayIdleAnimationMsg idleMsg; + if (idleMsg.execute(this)) { + if (idleMsg._names) { + CNPCPlayAnimationMsg animMsg(idleMsg._names, 0); + animMsg.execute(this); + } + + _npcFlags &= ~NPCFLAG_2; + } + } + + _speechTimerId = 0; + return true; +} + +bool CTrueTalkNPC::NPCPlayAnimationMsg(CNPCPlayAnimationMsg *msg) { + warning("CTrueTalkNPC::NPCPlayAnimationMsg"); + return true; +} + +void CTrueTalkNPC::processInput(CTextInputMsg *msg, CViewItem *view) { + CTrueTalkManager *talkManager = getGameManager()->getTalkManager(); + if (talkManager) + talkManager->processInput(this, msg, view); +} + +void CTrueTalkNPC::stopAnimTimer(int id) { + getGameManager()->stopTimer(id); +} + +void CTrueTalkNPC::setView(CViewItem *view) { + CTrueTalkManager *talkManager = getGameManager()->getTalkManager(); + if (talkManager) + talkManager->start3(this, view); +} + +void CTrueTalkNPC::startTalker(CViewItem *view) { + CGameManager *gameManager = getGameManager(); + if (gameManager) + gameManager->getTalkManager()->start4(this, view); +} + +void CTrueTalkNPC::performAction(bool startTalkingFlag, CViewItem *destView) { + CPetControl *pet = getPetControl(); + if (pet) + pet->resetActiveNPC(); + + if (startTalkingFlag) + startTalker(destView); + + if (pet) + pet->convResetNPC(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/npcs/true_talk_npc.h b/engines/titanic/npcs/true_talk_npc.h new file mode 100644 index 0000000000..0319f7e059 --- /dev/null +++ b/engines/titanic/npcs/true_talk_npc.h @@ -0,0 +1,102 @@ +/* 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 TITANIC_TRUE_TALK_NPC_H +#define TITANIC_TRUE_TALK_NPC_H + +#include "titanic/npcs/character.h" +#include "titanic/messages/messages.h" +#include "titanic/true_talk/tt_talker.h" + +namespace Titanic { + +enum NpcFlag { + NPCFLAG_SPEAKING = 1, NPCFLAG_2 = 2, NPCFLAG_4 = 4, NPCFLAG_8 = 8, + NPCFLAG_10000 = 0x10000, NPCFLAG_20000 = 0x20000, NPCFLAG_40000 = 0x40000, + NPCFLAG_80000 = 0x80000, NPCFLAG_100000 = 0x100000 +}; + +class CViewItem; + +class CTrueTalkNPC : public CCharacter { + DECLARE_MESSAGE_MAP; + bool TextInputMsg(CTextInputMsg *msg); + bool TrueTalkGetAssetDetailsMsg(CTrueTalkGetAssetDetailsMsg *msg); + bool DismissBotMsg(CDismissBotMsg *msg); + bool TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg); + bool TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg); + bool MovieEndMsg(CMovieEndMsg *msg); + bool NPCQueueIdleAnimMsg(CNPCQueueIdleAnimMsg *msg); + bool TimerMsg(CTimerMsg *msg); + bool NPCPlayAnimationMsg(CNPCPlayAnimationMsg *msg); +protected: + int _assetNumber; + CString _assetName; + int _fieldE4; + uint _npcFlags; + uint _soundId; + int _fieldF0; + int _fieldF4; + int _fieldF8; + int _speechTimerId; + int _field100; + int _field104; +protected: + void processInput(CTextInputMsg *msg, CViewItem *view); + + /** + * Stop an animation timer + */ + void stopAnimTimer(int id); + + /** + * Perform an action + */ + void performAction(bool startTalking, CViewItem *view); +public: + CLASSDEF; + CTrueTalkNPC(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Set the view for the NPC + */ + void setView(CViewItem *view); + + /** + * Start the talker in the given view + */ + void startTalker(CViewItem *view); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TRUE_TALK_NPC_H */ diff --git a/engines/titanic/pet_control/pet_control.cpp b/engines/titanic/pet_control/pet_control.cpp new file mode 100644 index 0000000000..b32a7907a4 --- /dev/null +++ b/engines/titanic/pet_control/pet_control.cpp @@ -0,0 +1,680 @@ +/* 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 "titanic/pet_control/pet_control.h" +#include "titanic/carry/carry.h" +#include "titanic/core/project_item.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/pet_messages.h" +#include "titanic/game_manager.h" +#include "titanic/game_state.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CPetControl, CGameObject) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(MouseDragStartMsg) + ON_MESSAGE(MouseDragMoveMsg) + ON_MESSAGE(MouseDragEndMsg) + ON_MESSAGE(MouseButtonUpMsg) + ON_MESSAGE(MouseDoubleClickMsg) + ON_MESSAGE(KeyCharMsg) + ON_MESSAGE(VirtualKeyCharMsg) + ON_MESSAGE(TimerMsg) +END_MESSAGE_MAP() + +CPetControl::CPetControl() : CGameObject(), + _currentArea(PET_CONVERSATION), _inputLockCount(0), _areaLockCount(0), + _areaChangeType(-1), _activeNPC(nullptr), _remoteTarget(nullptr), + _hiddenRoom(nullptr), _drawBounds(20, 350, 620, 480) { + _sections[PET_INVENTORY] = &_inventory; + _sections[PET_CONVERSATION] = &_conversations; + _sections[PET_REMOTE] = &_remote; + _sections[PET_ROOMS] = &_rooms; + _sections[PET_REAL_LIFE] = &_realLife; + _sections[PET_STARFIELD] = &_starfield; + _sections[PET_MESSAGE] = &_message; +} + +void CPetControl::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + file->writeNumberLine(_currentArea, indent); + file->writeQuotedLine(_activeNPCName, indent); + file->writeQuotedLine(_remoteTargetName, indent); + + saveAreas(file, indent); + CGameObject::save(file, indent); +} + +void CPetControl::load(SimpleFile *file) { + int val = file->readNumber(); + isValid(); + + if (!val) { + _currentArea = (PetArea)file->readNumber(); + _activeNPCName = file->readString(); + _remoteTargetName = file->readString(); + + loadAreas(file, 0); + } + + CGameObject::load(file); +} + +void CPetControl::setup() { + _conversations.setup(this); + _rooms.setup(this); + _remote.setup(this); + _inventory.setup(this); + _starfield.setup(this); + _realLife.setup(this); + _message.setup(this); + _frame.setup(this); +} + +bool CPetControl::isValid() { + return _conversations.isValid(this) && + _rooms.isValid(this) && + _remote.isValid(this) && + _inventory.isValid(this) && + _starfield.isValid(this) && + _realLife.isValid(this) && + _message.isValid(this) && + _frame.isValid(this); +} + +void CPetControl::loadAreas(SimpleFile *file, int param) { + _conversations.load(file, param); + _rooms.load(file, param); + _remote.load(file, param); + _inventory.load(file, param); + _starfield.load(file, param); + _realLife.load(file, param); + _message.load(file, param); + _frame.load(file, param); +} + +void CPetControl::saveAreas(SimpleFile *file, int indent) { + _conversations.save(file, indent); + _rooms.save(file, indent); + _remote.save(file, indent); + _inventory.save(file, indent); + _starfield.save(file, indent); + _realLife.save(file, indent); + _message.save(file, indent); + _frame.save(file, indent); +} + +void CPetControl::draw(CScreenManager *screenManager) { + CGameManager *gameManager = getGameManager(); + Rect bounds = _drawBounds; + bounds.constrain(gameManager->_bounds); + + if (!bounds.isEmpty()) { + if (_areaChangeType >= 0) { + _inventory.changed(_areaChangeType); + _areaChangeType = -1; + } + + _frame.drawFrame(screenManager); + + // Draw the specific area that's currently active + _sections[_currentArea]->draw(screenManager); + } +} + +Rect CPetControl::getBounds() const { + return _sections[_currentArea]->getBounds(); +} + +void CPetControl::postLoad() { + CProjectItem *root = getRoot(); + + if (!_activeNPCName.empty() && root) + _activeNPC = root->findByName(_activeNPCName); + if (!_remoteTargetName.empty() && root) + _remoteTarget = static_cast<CGameObject *>(root->findByName(_remoteTargetName)); + + setArea(_currentArea); + loaded(); +} + +void CPetControl::loaded() { + _conversations.postLoad(); + _rooms.postLoad(); + _remote.postLoad(); + _inventory.postLoad(); + _starfield.postLoad(); + _realLife.postLoad(); + _message.postLoad(); + _frame.postLoad(); +} + +void CPetControl::enterNode(CNodeItem *node) { + getGameManager()->_gameState.enterNode(); +} + +void CPetControl::enterRoom(CRoomItem *room) { + _rooms.enterRoom(room); + _remote.enterRoom(room); +} + +void CPetControl::resetRemoteTarget() { + _remoteTarget = nullptr; + _remoteTargetName.clear(); +} + +void CPetControl::setActiveNPC(CTrueTalkNPC *npc) { + if (_activeNPC == npc) { + if (_activeNPC) { + _activeNPCName = npc->getName(); + _conversations.displayNPCName(npc); + } else { + _activeNPCName = ""; + } + } +} + +void CPetControl::refreshNPC() { + _conversations.setNPC(_activeNPCName); +} + +void CPetControl::resetActiveNPC() { + _activeNPC = nullptr; + _activeNPCName = ""; +} + +PetArea CPetControl::setArea(PetArea newArea) { + if (newArea == _currentArea || !isAreaActive()) + return _currentArea; + + // Signal the currently active area that it's being left + _sections[_currentArea]->leave(); + + // Change the current area + PetArea oldArea = _currentArea; + _frame.setArea(newArea); + _currentArea = newArea; + + // Signal to the new view that it's been activated + _sections[_currentArea]->enter(oldArea); + + makeDirty(); + return newArea; +} + +void CPetControl::hideCursor() { + _sections[_currentArea]->hideCursor(); +} + +void CPetControl::showCursor() { + _sections[_currentArea]->showCursor(); +} + +void CPetControl::highlightGlyph(int id) { + _sections[_currentArea]->highlight(id); +} + +void CPetControl::setRemoteTarget(CGameObject *item) { + _remoteTarget = item; + if (item) + _remoteTargetName = item->getName(); + else + _remoteTargetName.clear(); +} + +CRoomItem *CPetControl::getHiddenRoom() { + if (!_hiddenRoom) + _hiddenRoom = CGameObject::getHiddenRoom(); + + return _hiddenRoom; +} + +CGameObject *CPetControl::getHiddenObject(const CString &name) { + CRoomItem *room = getHiddenRoom(); + return room ? static_cast<CGameObject *>(findUnder(room, name)) : nullptr; +} + +bool CPetControl::containsPt(const Common::Point &pt) const { + return _drawBounds.contains(pt); +} + +bool CPetControl::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if (!containsPt(msg->_mousePos) || isInputLocked()) + return false; + + bool result = false; + if (isAreaActive()) + result = _frame.MouseButtonDownMsg(msg); + + if (!result) { + result = _sections[_currentArea]->MouseButtonDownMsg(msg); + } + + makeDirty(); + return result; +} + +bool CPetControl::MouseDragStartMsg(CMouseDragStartMsg *msg) { + if (!containsPt(msg->_mousePos) || isInputLocked()) + return false; + + return _sections[_currentArea]->MouseDragStartMsg(msg); +} + +bool CPetControl::MouseDragMoveMsg(CMouseDragMoveMsg *msg) { + return _sections[_currentArea]->MouseDragMoveMsg(msg); +} + +bool CPetControl::MouseDragEndMsg(CMouseDragEndMsg *msg) { + return _sections[_currentArea]->MouseDragEndMsg(msg); +} + +bool CPetControl::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + if (!containsPt(msg->_mousePos) || isInputLocked()) + return false; + + bool result = false; + if (isAreaActive()) + result = _frame.MouseButtonUpMsg(msg); + + if (!result) + result = _sections[_currentArea]->MouseButtonUpMsg(msg); + + makeDirty(); + return result; +} + +bool CPetControl::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { + if (!containsPt(msg->_mousePos) || isInputLocked()) + return false; + + return _sections[_currentArea]->MouseDoubleClickMsg(msg); +} + +bool CPetControl::KeyCharMsg(CKeyCharMsg *msg) { + if (isInputLocked()) + return false; + + return _sections[_currentArea]->KeyCharMsg(msg); +} + +bool CPetControl::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { + if (isInputLocked()) + return false; + + bool result = _sections[_currentArea]->VirtualKeyCharMsg(msg); + + if (!result) { + switch (msg->_keyState.keycode) { + case Common::KEYCODE_F1: + result = true; + setArea(PET_INVENTORY); + break; + case Common::KEYCODE_F2: + result = true; + setArea(PET_CONVERSATION); + break; + case Common::KEYCODE_F3: + result = true; + setArea(PET_REMOTE); + break; + case Common::KEYCODE_F4: + result = true; + setArea(PET_ROOMS); + break; + case Common::KEYCODE_F5: + result = true; + setArea(PET_REAL_LIFE); + break; + default: + break; + } + } + + return result; +} + +bool CPetControl::TimerMsg(CTimerMsg *msg) { + warning("TODO: CPetControl::CTimerMsg"); + return true; +} + +void CPetControl::drawSquares(CScreenManager *screenManager, int count) { + _frame.drawSquares(screenManager, count); +} + +CGameObject *CPetControl::dragEnd(const Point &pt) const { + return _currentArea == PET_INVENTORY ? _inventory.dragEnd(pt) : nullptr; +} + +bool CPetControl::checkDragEnd(CGameObject *item) const { + return _sections[_currentArea]->checkDragEnd(item); +} + +void CPetControl::displayMessage(const CString &msg) const { + _sections[_currentArea]->displayMessage(msg); +} + +CGameObject *CPetControl::getFirstObject() const { + return static_cast<CGameObject *>(getFirstChild()); +} + +CGameObject *CPetControl::getNextObject(CGameObject *prior) const { + if (!prior || prior->getParent() != this) + return nullptr; + + return static_cast<CGameObject *>(prior->getNextSibling()); +} + +void CPetControl::addToInventory(CGameObject *item) { + item->detach(); + + if (item->getName() == "CarryParcel") { + CCarry *child = static_cast<CCarry *>(getLastChild()); + if (child) + child->detach(); + + item->petMoveToHiddenRoom(); + if (!child) + return; + + item = child; + } + + item->addUnder(this); + _inventory.itemsChanged(); + + setArea(PET_INVENTORY); + if (_currentArea == PET_INVENTORY) + _inventory.highlightItem(item); + + makeDirty(); + CPETGainedObjectMsg msg; + msg.execute(item); +} + +void CPetControl::removeFromInventory(CGameObject *item, CTreeItem *newParent, + bool refreshUI, bool sendMsg) { + if (item && newParent) { + item->detach(); + item->addUnder(newParent); + + if (refreshUI) + _inventory.itemRemoved(item); + if (sendMsg) { + CPETLostObjectMsg lostMsg; + lostMsg.execute(item); + } + } +} + +void CPetControl::removeFromInventory(CGameObject *item, bool refreshUI, bool sendMsg) { + CViewItem *view = getGameManager()->getView(); + removeFromInventory(item, view, refreshUI, sendMsg); +} + +void CPetControl::invChange(CGameObject *item) { + _inventory.change(item); +} + +void CPetControl::moveToHiddenRoom(CTreeItem *item) { + CRoomItem *room = getHiddenRoom(); + if (room) { + item->detach(); + room->addUnder(item); + } +} + +bool CPetControl::checkNode(const CString &name) { + CGameManager *gameManager = getGameManager(); + if (!gameManager) + return true; + if (name == "NULL") + return false; + + CViewItem *view = gameManager->getView(); + if (!view) + return true; + + CNodeItem *node = view->findNode(); + if (!node) + return true; + + CString viewName = view->getName(); + CString nodeName = node->getName(); + CRoomItem *room = getGameManager()->getRoom(); + + if (room) { + CString roomName = room->getName(); + CString newNode; + + if (roomName == "1stClassRestaurant") { + } else if (nodeName == "Lobby Node") { + nodeName = "Node 1"; + } else if (nodeName == "Entrance Node") { + nodeName = "Node 2"; + } else if (nodeName == "MaitreD Node") { + nodeName = "Node 3"; + } else if (nodeName == "Scraliontis Table Standing Node") { + nodeName = "Node 4"; + } else if (nodeName == "Pellerator Node") { + nodeName = "Node 5"; + } else if (nodeName == "SUB Node") { + nodeName = "Node 6"; + } else if (nodeName == "Phonograph Node") { + nodeName = "Node 7"; + } else if (nodeName == "Scraliontis Table Seated Node") { + nodeName = "Node 8"; + } + + if (roomName == "MusicRoom") { + if (nodeName == "Musical Instruments") + nodeName = "Node 1"; + if (nodeName == "Phonograph Node") + nodeName = "Node 2"; + } + } + + CString str = CString::format("%s.%s", nodeName.c_str(), viewName.c_str()); + str = str.right(5); + str.toLowercase(); + + CString nameLower = name; + nameLower.toLowercase(); + + return nameLower.contains(str); +} + +void CPetControl::playSound(int soundNum) { + CTreeItem *player = getHiddenObject("PETSoundPlayer"); + if (player) { + CPETPlaySoundMsg playMsg(soundNum); + playMsg.execute(player); + } +} + +int CPetControl::canSummonBot(const CString &name) { + // If player is the very same view as the NPC, then it's already present + if (isBotInView(name)) + return SUMMON_CAN; + + // Get the room + CGameManager *gameManager = getGameManager(); + if (!gameManager) + return SUMMON_CANT; + CRoomItem *room = gameManager->getRoom(); + if (!room) + return SUMMON_CANT; + + // Query current room to see whether the bot can be summoned to it + CSummonBotQueryMsg queryMsg(name); + return queryMsg.execute(room) ? SUMMON_CAN : SUMMON_CANT; +} + +bool CPetControl::isBotInView(const CString &name) const { + CGameManager *gameManager = getGameManager(); + if (!gameManager) + return false; + CViewItem *view = gameManager->getView(); + if (!view) + return false; + + // Iterate to find NPC + for (CTreeItem *child = view->getFirstChild(); child; child = child->scan(view)) { + CGameObject *gameObject = static_cast<CGameObject *>(child); + if (gameObject) { + if (!gameObject->getName().compareToIgnoreCase(name)) + return true; + } + } + + return false; +} + +void CPetControl::summonBot(const CString &name, int val) { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + CRoomItem *room = gameManager->getRoom(); + + if (room) { + CSummonBotMsg summonMsg(name, val); + summonMsg.execute(room); + } + } +} + +void CPetControl::onSummonBot(const CString &name, int val) { + CGameObject *bot = findBot(name, getHiddenRoom()); + if (!bot) { + bot = findBot(name, getRoot()); + } + + if (bot) { + removeFromInventory(bot, false, false); + + COnSummonBotMsg summonMsg(val); + summonMsg.execute(bot); + } +} + +bool CPetControl::dismissBot(const CString &name) { + CGameManager *gameManager = getGameManager(); + if (!gameManager) + return false; + CViewItem *view = gameManager->getView(); + if (!view) + return false; + + bool result = false; + CDismissBotMsg dismissMsg; + for (CTreeItem *treeItem = view->getFirstChild(); treeItem; + treeItem = treeItem->scan(view)) { + if (!treeItem->getName().compareToIgnoreCase(name)) + dismissMsg.execute(treeItem); + else + result = true; + } + + return result; +} + +bool CPetControl::isDoorOrBellbotPresent() const { + CGameManager *gameManager = getGameManager(); + if (!gameManager) + return false; + CViewItem *view = gameManager->getView(); + if (!view) + return false; + + for (CTreeItem *treeItem = view->getFirstChild(); treeItem; + treeItem = treeItem->scan(view)) { + CString name = treeItem->getName(); + if (static_cast<CGameObject *>(treeItem) && + (name.contains("Doorbot") || name.contains("BellBot"))) + return true; + } + + return false; +} + +void CPetControl::startPetTimer(uint timerIndex, uint firstDuration, uint duration, CPetSection *target) { + stopPetTimer(timerIndex); + _timers[timerIndex]._id = addTimer(timerIndex, firstDuration, duration); + _timers[timerIndex]._target = target; + setTimerPersisent(_timers[timerIndex]._id, false); +} + +void CPetControl::stopPetTimer(uint timerIndex) { + if (_timers[timerIndex]._target) { + stopTimer(_timers[timerIndex]._id); + _timers[timerIndex]._target = nullptr; + } +} + +void CPetControl::setTimerPersisent(int id, bool flag) { + getGameManager()->setTimerPersisent(id, flag); +} + +CGameObject *CPetControl::findBot(const CString &name, CTreeItem *root) { + for (CTreeItem *item = root; item; item = item->scan(root)) { + if (!item->getName().compareToIgnoreCase(name)) { + CGameObject *obj = static_cast<CGameObject *>(item); + if (obj) + return obj; + } + } + + return nullptr; +} + +bool CPetControl::isSuccUBusActive() const { + if (!_activeNPC) + return false; + + CString name = getName(); + return name.contains("Succubus") || name.contains("Sub"); +} + +void CPetControl::convResetDials(int flag) { + if (flag == 1) + _conversations.resetDials(_activeNPCName); +} + +int CPetControl::getMailDest(const CRoomFlags &roomFlags) const { + if (!roomFlags.isSuccUBusRoomFlags()) + return roomFlags.getPassengerClassNum(); + + return roomFlags.getSuccUBusNum(roomFlags.getSuccUBusRoomName()); +} + +void CPetControl::starsSetButtons(int val1, int val2) { + _starfield.setButtons(val1, val2); + if (_currentArea == PET_STARFIELD) + _starfield.makePetDirty(); +} + +void CPetControl::starsSetReference(bool hasRef) { + _starfield.setHasReference(hasRef); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_control.h b/engines/titanic/pet_control/pet_control.h new file mode 100644 index 0000000000..a86d110458 --- /dev/null +++ b/engines/titanic/pet_control/pet_control.h @@ -0,0 +1,574 @@ +/* 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 TITANIC_PET_CONTROL_H +#define TITANIC_PET_CONTROL_H + +#include "titanic/core/game_object.h" +#include "titanic/core/node_item.h" +#include "titanic/core/room_item.h" +#include "titanic/messages/messages.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/pet_control/pet_conversations.h" +#include "titanic/pet_control/pet_frame.h" +#include "titanic/pet_control/pet_inventory.h" +#include "titanic/pet_control/pet_message.h" +#include "titanic/pet_control/pet_starfield.h" +#include "titanic/pet_control/pet_real_life.h" +#include "titanic/pet_control/pet_remote.h" +#include "titanic/pet_control/pet_rooms.h" +#include "titanic/room_flags.h" + +namespace Titanic { + +enum SummonResult { SUMMON_CANT = 0, SUMMON_PRESENT = 1, SUMMON_CAN = 2 }; + +class CPetControl : public CGameObject { + DECLARE_MESSAGE_MAP; + struct PetEventInfo { + int _id; + CPetSection *_target; + PetEventInfo() : _id(0), _target(nullptr) {} + }; +private: + int _inputLockCount; + int _areaLockCount; + int _areaChangeType; + CPetSection *_sections[7]; + CPetConversations _conversations; + CPetInventory _inventory; + CPetStarfield _starfield; + CPetRemote _remote; + CPetRooms _rooms; + CPetRealLife _realLife; + CPetMessage _message; + CPetFrame _frame; + CString _activeNPCName; + CString _remoteTargetName; + CRoomItem *_hiddenRoom; + Rect _drawBounds; + PetEventInfo _timers[2]; +private: + /** + * Returns true if the control is in a valid state + */ + bool isValid(); + + /** + * Loads data for the individual areas + */ + void loadAreas(SimpleFile *file, int param); + + /** + * Saves data for the individual areas + */ + void saveAreas(SimpleFile *file, int indent); + + /** + * Called at the end of the post game-load handling + */ + void loaded(); + + /** + * Returns true if the draw bounds contains the specified point + */ + bool containsPt(const Common::Point &pt) const; + + /** + * Checks whether a designated NPC in present in the current view + */ + bool isBotInView(const CString &name) const; + + /** + * Find a bot under a given root + */ + CGameObject *findBot(const CString &name, CTreeItem *root); + + /** + * Flags whether the timer will be persisent across save & loads + */ + void setTimerPersisent(int id, bool flag); +protected: + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool MouseDragStartMsg(CMouseDragStartMsg *msg); + bool MouseDragMoveMsg(CMouseDragMoveMsg *msg); + bool MouseDragEndMsg(CMouseDragEndMsg *msg); + bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); + bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg); + bool KeyCharMsg(CKeyCharMsg *msg); + bool VirtualKeyCharMsg(CVirtualKeyCharMsg *msg); + bool TimerMsg(CTimerMsg *msg); +public: + PetArea _currentArea; + CTreeItem *_activeNPC; + CGameObject *_remoteTarget; +public: + CLASSDEF; + CPetControl(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Allows the item to draw itself + */ + virtual void draw(CScreenManager *screenManager); + + /** + * Gets the bounds occupied by the item + */ + virtual Rect getBounds() const; + + /** + * Setups the sections within the PET + */ + void setup(); + + /** + * Called after loading a game has finished + */ + void postLoad(); + + /** + * Called when a new node is entered + */ + void enterNode(CNodeItem *node); + + /** + * Called when a new room is entered + */ + void enterRoom(CRoomItem *room); + + /** + * Called to reset the remote target + */ + void resetRemoteTarget(); + + /** + * Set the remote target + */ + void setRemoteTarget(CGameObject *item); + + /** + * Sets the currently viewed area within the PET + */ + PetArea setArea(PetArea newSection); + + /** + * Hides the text cursor in the current section, if applicable + */ + void hideCursor(); + + /** + * Shows the text cursor in the current section, if applicable + */ + void showCursor(); + + /** + * Highlights a glyph item in the currently active section, if applicable + */ + void highlightGlyph(int id); + + + /** + * Returns a game object used by the PET by name from within the + * special hidden room container + */ + CGameObject *getHiddenObject(const CString &name); + + /** + * Returns a reference to the special hidden room container + */ + CRoomItem *getHiddenRoom(); + + /** + * Draws squares for showing glyphs inside + */ + void drawSquares(CScreenManager *screenManager, int count); + + /** + * Returns true if the point is within the PET's draw bounds + */ + bool contains(const Point &pt) const { + return _drawBounds.contains(pt); + } + + /** + * Handles drag ends within the PET + */ + CGameObject *dragEnd(const Point &pt) const; + + /** + * Handles checking when a drag-drop operation ends + */ + bool checkDragEnd(CGameObject *item) const; + + /** + * Display a message + */ + void displayMessage(const CString &msg) const; + + /** + * Get the first game object stored in the PET + */ + CGameObject *getFirstObject() const; + + /** + * Get the next game object stored in the PET following + * the passed game object + */ + CGameObject *getNextObject(CGameObject *prior) const; + + /** + * Adds an item to the PET inventory + */ + void addToInventory(CGameObject *item); + + /** + * Remove an item from the inventory + */ + void removeFromInventory(CGameObject *item, CTreeItem *newParent, + bool refreshUI = true, bool sendMsg = true); + + /** + * Remove an item from the inventory + */ + void removeFromInventory(CGameObject *item, bool refreshUI = true, bool sendMsg = true); + + /** + * Called when the status of an item in the inventory has changed + */ + void invChange(CGameObject *item); + + /** + * Moves a tree item from it's original position to be under the hidden room + */ + void moveToHiddenRoom(CTreeItem *item); + + /** + * Sets a change for the PET Area's glyphs. Only applicable when + * the Inventory is the active tab + */ + void setAreaChangeType(int changeType) { _areaChangeType = changeType; } + + bool checkNode(const CString &name); + + /** + * Play a sound + */ + void playSound(int soundNum); + + /** + * Check whether an NPC can be summoned + */ + int canSummonBot(const CString &name); + + /** + * Summon an NPC to the player + */ + void summonBot(const CString &name, int val); + + /** + * Summon a bot to the player + */ + void onSummonBot(const CString &name, int val); + + /** + * Dismiss an NPC + */ + bool dismissBot(const CString &name); + + /** + * Returns true if Doorbot or Bellbot present + */ + bool isDoorOrBellbotPresent() const; + + /** + * Start a timer for a Pet Area + */ + void startPetTimer(uint timerIndex, uint firstDuration, uint duration, CPetSection *target); + + /** + * Stop a timer + */ + void stopPetTimer(uint timerIndex); + + /** + * Returns true if all input is currently locked (disabled) + */ + bool isInputLocked() const { return _inputLockCount > 0; } + + /** + * Increments the input locked count + */ + void incInputLocks() { ++_inputLockCount; } + + /** + * Decremenst the input locked count + */ + void decInputLocks() { --_inputLockCount; } + + /** + * Returns true if the PET is currently unlocked + */ + bool isAreaActive() const { return _areaLockCount == 0; } + + /** + * Increment the number of PET area (tab) locks + */ + void incAreaLocks() { ++_areaLockCount; } + + /** + * Decrement the number of PET area (tab) locks + */ + void decAreaLocks() { + _areaLockCount = MAX(_areaLockCount - 1, 0); + } + + bool isSuccUBusActive() const; + + /*--- CPetConversations methods ---*/ + + /** + * Sets the active NPC + */ + void setActiveNPC(const CString &name) { + _conversations.setActiveNPC(name); + } + + /** + * Sets the actie NPC + */ + void setActiveNPC(CTrueTalkNPC *npc); + + /** + * Refresh the currently active NPC + */ + void refreshNPC(); + + /** + * Resets the Active NPC + */ + void resetActiveNPC(); + + /** + * Resets NPC in conversations + */ + void convResetNPC() { + _conversations.resetNPC(); + } + + /** + * Resets the conversation dials back to 0 position + */ + void resetDials0() { _conversations.resetDials0(); } + + /** + * Resets the dial display in the conversation tab to reflect new values + */ + void convResetDials(int flag = 1); + + /** + * Adds a line to the conversation log + */ + void convAddLine(const CString &line) { + _conversations.addLine(line); + } + + /*--- CPetRooms methods ---*/ + + /** + * Gives the player a new assigned room in the specified passenger class + */ + void reassignRoom(int passClassNum) { + _rooms.reassignRoom(passClassNum); + } + + /** + * Change the current location passenger class + */ + bool changeLocationClass(int newClassNum) { + return _rooms.changeLocationClass(newClassNum); + } + + /** + * Returns true if the Rooms list has a room with the given flags + */ + bool hasRoomFlags() const { + return _rooms.hasRoomFlags(getRoomFlags()); + } + + uint getRoomFlags() const { + return _rooms.getRoomFlags(); + } + + /** + * Set the current elevator number to use for room glyphs + */ + void setRoomsElevatorNum(int elevNum) { + _rooms.setElevatorNum(elevNum); + } + + /** + * Get the current elevator number used by room glyphs + */ + int getRoomsElevatorNum() const { + return _rooms.getElevatorNum(); + } + + /** + * Set the current floor number to use for room glyphs + */ + void setRoomsFloorNum(int floorNum) { + _rooms.setFloorNum(floorNum); + } + + /** + * Get the current floor number used by room glyphs + */ + int getRoomsFloorNum() const { + return _rooms.getFloorNum(); + } + + /** + * Set the current room number to use for room glyphs + */ + void setRoomsRoomNum(int roomNum) { + _rooms.setRoomNum(roomNum); + } + + /** + * Get the current floor number used by room glyphs + */ + int getRoomsRoomNum() const { + return _rooms.getRoomNum(); + } + + /** + * Sets the entry number for arriving at the well + */ + void setRoomsWellEntry(int entryNum) { + _rooms.setWellEntry(entryNum); + } + + /** + * Gets the entry number used when last arriving at the well + */ + int getRoomsWellEntry() const { + return _rooms.getWellEntry(); + } + + void setRooms1CC(int v) { + _rooms.set1CC(v); + } + int getRooms1CC() const { + return _rooms.get1CC(); + } + + /** + * Reset the highlight + */ + void resetRoomsHighlight() { + _rooms.resetHighlight(); + } + + int getAssignedRoomFlags() const { + return _rooms.getAssignedRoomFlags(); + } + + uint getSpecialRoomFlags(const CString &name) { + return CRoomFlags::getSpecialRoomFlags(name); + } + + /** + * Get mail destination given the specified flags + */ + int getMailDest(const CRoomFlags &roomFlags) const; + + bool testRooms5(uint roomFlags) { + return CRoomFlags(roomFlags).not5(); + } + + /** + * Returns the room number for the player's currently assigned room + */ + int getAssignedRoomNum() const { + return _rooms.getAssignedRoomNum(); + } + + /** + * Returns the floor number for the player's currently assigned room + */ + int getAssignedFloorNum() const { + return _rooms.getAssignedFloorNum(); + } + + /** + * Returns the elevator number for the player's currently assigned room + */ + int getAssignedElevatorNum() const { + return _rooms.getAssignedElevatorNum(); + } + + void setRooms1D4(int val) { + _rooms.set1D4(val); + } + + bool isRoom59706() const { + return CRoomFlags(getRoomFlags()).is59706(); + } + + /** + * Returns true if the passed room flags indicate the room has a succubus + */ + bool isSuccUBusRoom(const CRoomFlags &roomFlags) { + return roomFlags.isSuccUBusRoomFlags(); + } + + /** + * Called with a phonograph action for Send, Receive, or Record + */ + void phonographAction(const CString &action) { + // Original had some code that had no effect + } + + /** + * Sets the status buttons for the starfield control + */ + void starsSetButtons(int val1, int val2); + + /** + * Set whether the user has the galactic reference material + */ + void starsSetReference(bool hasRef); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_CONTROL_H */ diff --git a/engines/titanic/pet_control/pet_conversations.cpp b/engines/titanic/pet_control/pet_conversations.cpp new file mode 100644 index 0000000000..dc096afcfe --- /dev/null +++ b/engines/titanic/pet_control/pet_conversations.cpp @@ -0,0 +1,579 @@ +/* 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 "titanic/pet_control/pet_conversations.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/game_manager.h" + +namespace Titanic { + +CPetConversations::CPetConversations() : CPetSection(), + _logChanged(false), _field418(0), _npcNum(-1), + _rect1(22, 352, 598, 478) { + Rect logRect(85, 18, 513, 87); + logRect.translate(20, 350); + _log.setBounds(logRect); + _log.resize(50); + _log.setHasBorder(false); + _log.setColor(getColor(2)); + _log.setup(); + _log.addLine("Welcome to your PET v1.0a"); + + Rect inputRect(85, 95, 513, 135); + inputRect.translate(20, 350); + _textInput.setBounds(inputRect); + _textInput.setHasBorder(false); + _textInput.resize(2); + _textInput.setMaxCharsPerLine(74); + _textInput.setColor(getColor(0)); + _textInput.setup(); + + _npcLevels[0] = _npcLevels[1] = _npcLevels[2] = 0; +} + +bool CPetConversations::setup(CPetControl *petControl) { + if (petControl && setupControl(petControl)) + return reset(); + return false; +} + +bool CPetConversations::reset() { + _dials[0].setup(MODE_UNSELECTED, "3PetDial1", _petControl); + _dials[1].setup(MODE_UNSELECTED, "3PetDial2", _petControl); + _dials[2].setup(MODE_UNSELECTED, "3PetDial3", _petControl); + + _dialBackground.reset("PetDialBack", _petControl); + _scrollUp.reset("PetScrollUp", _petControl); + _scrollDown.reset("PetScrollDown", _petControl); + + _doorBot.reset("PetCallDoorOut", _petControl, MODE_UNSELECTED); + _doorBot.reset("PetCallDoorIn", _petControl, MODE_SELECTED); + _bellBot.reset("PetCallBellOut", _petControl, MODE_UNSELECTED); + _bellBot.reset("PetCallBellIn", _petControl, MODE_SELECTED); + + _indent.reset("PetSmallCharacterIndent", _petControl); + _splitter.reset("PetSplitter", _petControl); + + _npcIcons[0].setup(MODE_UNSELECTED, "3PetSmlDoorbot", _petControl); + _npcIcons[1].setup(MODE_UNSELECTED, "3PetSmlDeskbot", _petControl); + _npcIcons[2].setup(MODE_UNSELECTED, "3PetSmlLiftbot", _petControl); + _npcIcons[3].setup(MODE_UNSELECTED, "3PetSmlParrot", _petControl); + _npcIcons[4].setup(MODE_UNSELECTED, "3PetSmlBarbot", _petControl); + _npcIcons[5].setup(MODE_UNSELECTED, "3PetSmlChatterbot", _petControl); + _npcIcons[6].setup(MODE_UNSELECTED, "3PetSmlBellbot", _petControl); + _npcIcons[7].setup(MODE_UNSELECTED, "3PetSmlMaitreD", _petControl); + _npcIcons[8].setup(MODE_UNSELECTED, "3PetSmlSuccubus", _petControl); + + if (_petControl->getPassengerClass() == 1) { + uint col = getColor(0); + _textInput.setColor(col); + _textInput.setLineColor(0, col); + + // Replace the log colors with new 1st class ones + uint colors1[5], colors2[5]; + copyColors(2, colors1); + copyColors(1, colors2); + _log.remapColors(5, colors1, colors2); + + _log.setColor(getColor(2)); + } + + return true; +} + +void CPetConversations::draw(CScreenManager *screenManager) { + _dialBackground.draw(screenManager); + _splitter.draw(screenManager); + _dials[0].draw(screenManager); + _dials[1].draw(screenManager); + _dials[2].draw(screenManager); + + _indent.draw(screenManager); + _doorBot.draw(screenManager); + _bellBot.draw(screenManager); + _scrollUp.draw(screenManager); + _scrollDown.draw(screenManager); + _log.draw(screenManager); + _textInput.draw(screenManager); + + if (_logChanged) { + int startIndex = _log.getLinesStart(); + if (startIndex >= 0) { + int npcNum = _log.getNPCNum(1, startIndex); + if (npcNum > 0 && npcNum < 10) + _npcNum = npcNum; + } + + _logChanged = false; + } + + if (_npcNum >= 0) + _npcIcons[_npcNum].draw(screenManager); +} + +Rect CPetConversations::getBounds() const { + Rect rect = _dials[0].getBounds(); + rect.combine(_dials[1].getBounds()); + rect.combine(_dials[2].getBounds()); + + return rect; +} + +bool CPetConversations::isValid(CPetControl *petControl) { + return setupControl(petControl); +} + +bool CPetConversations::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if (_scrollDown.MouseButtonDownMsg(msg->_mousePos)) { + scrollDown(); + return true; + } else if (_scrollUp.MouseButtonDownMsg(msg->_mousePos)) { + scrollUp(); + return true; + } + + return + _doorBot.MouseButtonDownMsg(msg->_mousePos) || + _bellBot.MouseButtonDownMsg(msg->_mousePos); +} + +bool CPetConversations::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + if (_scrollUp.MouseButtonUpMsg(msg->_mousePos) || + _scrollDown.MouseButtonUpMsg(msg->_mousePos)) + return true; + + if (_doorBot.MouseButtonUpMsg(msg->_mousePos)) { + switch (canSummonBot("DoorBot")) { + case SUMMON_CANT: + _log.addLine("Sadly, it is not possible to summon the DoorBot from this location.", getColor(1)); + break; + case SUMMON_CAN: + summonBot("DoorBot"); + return true; + default: + break; + } + + // Scroll to the bottom of the log + scrollToBottom(); + return true; + } + + if (_bellBot.MouseButtonUpMsg(msg->_mousePos)) { + switch (canSummonBot("BellBot")) { + case SUMMON_CANT: + _log.addLine("Sadly, it is not possible to summon the BellBot from this location.", getColor(1)); + break; + case SUMMON_CAN: + summonBot("BellBot"); + return true; + default: + break; + } + + // Scroll to the bottom of the log + scrollToBottom(); + return true; + } + + return false; +} + +bool CPetConversations::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { + return _scrollDown.MouseDoubleClickMsg(msg->_mousePos) + || _scrollUp.MouseDoubleClickMsg(msg->_mousePos); +} + +bool CPetConversations::KeyCharMsg(CKeyCharMsg *msg) { + Common::KeyState keyState; + keyState.ascii = msg->_key; + return handleKey(keyState); +} + +bool CPetConversations::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { + return handleKey(msg->_keyState); +} + +void CPetConversations::displayMessage(const CString &msg) { + _log.addLine(msg, getColor(1)); + scrollToBottom(); +} + +void CPetConversations::load(SimpleFile *file, int param) { + _textInput.load(file, param); + _log.load(file, param); + + for (int idx = 0; idx < TOTAL_DIALS; ++idx) + _npcLevels[idx] = file->readNumber(); +} + +void CPetConversations::postLoad() { + reset(); +} + +void CPetConversations::save(SimpleFile *file, int indent) { + _textInput.save(file, indent); + _log.save(file, indent); + + for (int idx = 0; idx < TOTAL_DIALS; ++idx) + file->writeNumberLine(_npcLevels[idx], indent); +} + +void CPetConversations::enter(PetArea oldArea) { + resetDials(); + + if (_petControl && _petControl->_activeNPC) + // Start a timer for the NPC + startNPCTimer(); + + // Show the text cursor + _textInput.showCursor(-2); +} + +void CPetConversations::leave() { + _textInput.hideCursor(); + stopNPCTimer(); +} + +void CPetConversations::timerExpired(int val) { + if (val == 1) { + CPetSection::timerExpired(val); + } else { + CString name = _field418 ? _npcName : getActiveNPCName(); + + for (int idx = 0; idx < TOTAL_DIALS; ++idx) { + if (!_dials[idx].hasActiveMovie()) + updateDial(idx, name); + } + } +} + +void CPetConversations::displayNPCName(CGameObject *npc) { + if (npc) { + displayMessage(CString()); + CString msg = "Talking to "; + CString name = npc->getName(); + int id = 1; + + if (name.contains("Doorbot")) { + msg += "the DoorBot"; + } else if (name.contains("DeskBot")) { + id = 2; + msg += "the DeskBot"; + } else if (name.contains("LiftBot")) { + id = 3; + msg += "a LiftBot"; + } else if (name.contains("Parrot")) { + id = 4; + msg += "the Parrot"; + } else if (name.contains("BarBot")) { + id = 5; + msg += "the BarBot"; + } else if (name.contains("ChatterBot")) { + id = 6; + msg += "a ChatterBot"; + } else if (name.contains("BellBot")) { + id = 7; + msg += "the BellBot"; + } else if (name.contains("Maitre")) { + id = 8; + msg += "the Maitre d'Bot"; + } else if (name.contains("Succubus") || name.contains("Sub")) { + id = 9; + msg += "a Succ-U-Bus"; + } else { + msg += "Unknown"; + } + + _log.setNPC(1, id); + displayMessage(msg); + } +} + +void CPetConversations::setNPC(const CString &name) { + _field418 = 0; + resetDials(name); + startNPCTimer(); +} + +void CPetConversations::resetNPC() { + stopNPCTimer(); + resetDials("0"); +} + +void CPetConversations::showCursor() { + _textInput.showCursor(-2); +} + +void CPetConversations::hideCursor() { + _textInput.hideCursor(); +} + +bool CPetConversations::setupControl(CPetControl *petControl) { + if (petControl) { + _petControl = petControl; + + _dialBackground.setBounds(Rect(0, 0, 21, 130)); + _dialBackground.translate(20, 350); + + const Rect rect1(0, 0, 22, 36); + _dials[0].setBounds(rect1); + _dials[0].translate(20, 359); + _dials[1].setBounds(rect1); + _dials[1].translate(20, 397); + _dials[2].setBounds(rect1); + _dials[2].translate(20, 434); + + const Rect rect2(0, 0, 11, 24); + _scrollUp.setBounds(rect2); + _scrollUp.translate(87, 374); + _scrollDown.setBounds(rect2); + _scrollDown.translate(87, 421); + + const Rect rect3(0, 0, 39, 39); + _doorBot.setBounds(rect3); + _doorBot.translate(546, 372); + _bellBot.setBounds(rect3); + _bellBot.translate(546, 418); + + _indent.setBounds(Rect(0, 0, 37, 70)); + _indent.translate(46, 374); + _splitter.setBounds(Rect(0, 0, 435, 3)); + _splitter.translate(102, 441); + + const Rect rect4(0, 0, 33, 66); + for (int idx = 0; idx < 9; ++idx) { + _npcIcons[idx].setBounds(rect4); + _npcIcons[idx].translate(48, 376); + } + } + + return true; +} + +void CPetConversations::scrollUp() { + _log.scrollUp(CScreenManager::_screenManagerPtr); + if (_petControl) + _petControl->makeDirty(); + _logChanged = true; +} + +void CPetConversations::scrollDown() { + _log.scrollDown(CScreenManager::_screenManagerPtr); + if (_petControl) + _petControl->makeDirty(); + _logChanged = true; +} + +void CPetConversations::scrollUpPage() { + _log.scrollUpPage(CScreenManager::_screenManagerPtr); + if (_petControl) + _petControl->makeDirty(); + _logChanged = true; +} + +void CPetConversations::scrollDownPage() { + _log.scrollDownPage(CScreenManager::_screenManagerPtr); + if (_petControl) + _petControl->makeDirty(); + _logChanged = true; +} + +void CPetConversations::scrollToTop() { + _log.scrollToTop(CScreenManager::_screenManagerPtr); + if (_petControl) + _petControl->makeDirty(); + _logChanged = true; +} + +void CPetConversations::scrollToBottom() { + _log.scrollToBottom(CScreenManager::_screenManagerPtr); + if (_petControl) + _petControl->makeDirty(); + _logChanged = true; +} + +int CPetConversations::canSummonBot(const CString &name) { + return _petControl ? _petControl->canSummonBot(name) : SUMMON_CANT; +} + +void CPetConversations::summonBot(const CString &name) { + if (_petControl) { + if (_petControl->getPassengerClass() >= 4) { + _petControl->displayMessage("Sorry, you must be at least 3rd class before you can summon for help."); + } else { + _petControl->summonBot(name, 0); + } + } +} + +void CPetConversations::startNPCTimer() { + _petControl->startPetTimer(1, 1000, 1000, this); +} + +void CPetConversations::stopNPCTimer() { + _petControl->stopPetTimer(1); +} + +TTnpcScript *CPetConversations::getNPCScript(const CString &name) const { + if (name.empty() || !_petControl) + return nullptr; + CGameManager *gameManager = _petControl->getGameManager(); + if (!gameManager) + return nullptr; + CTrueTalkManager *trueTalk = gameManager->getTalkManager(); + if (!trueTalk) + return nullptr; + + return trueTalk->getTalker(name); +} + +bool CPetConversations::handleKey(const Common::KeyState &keyState) { + switch (keyState.keycode) { + case Common::KEYCODE_UP: + case Common::KEYCODE_KP8: + scrollUp(); + break; + case Common::KEYCODE_DOWN: + case Common::KEYCODE_KP2: + scrollDown(); + break; + case Common::KEYCODE_PAGEUP: + case Common::KEYCODE_KP9: + scrollUpPage(); + break; + case Common::KEYCODE_PAGEDOWN: + case Common::KEYCODE_KP3: + scrollDownPage(); + break; + case Common::KEYCODE_HOME: + case Common::KEYCODE_KP7: + scrollToTop(); + break; + case Common::KEYCODE_END: + case Common::KEYCODE_KP1: + scrollToBottom(); + break; + default: + if (keyState.ascii > 0 && keyState.ascii) { + if (_textInput.handleKey(keyState.ascii)) + // Text line finished, so process line + textLineEntered(_textInput.getText()); + } + return true; + } + + return false; +} + +void CPetConversations::textLineEntered(const CString &textLine) { + if (textLine.empty() || !_petControl) + return; + + if (_petControl->_activeNPC) { + _log.addLine("- " + textLine, getColor(0)); + + CTextInputMsg inputMsg(textLine, ""); + inputMsg.execute(_petControl->_activeNPC); + + if (!inputMsg._response.empty()) + _log.addLine(inputMsg._response); + } else { + _log.addLine("There is no one here to talk to", getColor(1)); + } + + // Clear input line and scroll log down to end to show response + _textInput.setup(); + scrollToBottom(); +} + +void CPetConversations::setActiveNPC(const CString &name) { + _npcName = name; + _field418 = 1; + resetDials(); + startNPCTimer(); +} + +void CPetConversations::updateDial(uint dialNum, const CString &npcName) { + TTnpcScript *script = getNPCScript(npcName); + uint newLevel = getDialLevel(dialNum, script); + npcDialChange(dialNum, _npcLevels[dialNum], newLevel); + _npcLevels[dialNum] = newLevel; +} + +uint CPetConversations::getDialLevel(uint dialNum, TTnpcScript *script, int v) { + bool flag = v != 0; + + if (!script) + return 0; + else + return MAX(script->getDialLevel(dialNum, flag), 15); +} + +void CPetConversations::npcDialChange(uint dialNum, int oldLevel, int newLevel) { + const uint range1[2] = { 0, 21 }; + const uint range2[2] = { 22, 43 }; + + if (newLevel != oldLevel) { + uint src = range1[0], dest = range1[1]; + if (oldLevel < newLevel) { + src = range2[0]; + dest = range2[1]; + } + + int64 val1 = (oldLevel * dest) + (100 - oldLevel) * src; + uint startFrame = val1 / 100; + + int64 val2 = (newLevel * dest) + (100 - newLevel) * src; + uint endFrame = val2 / 100; + + if (startFrame != endFrame) + _dials[dialNum].playMovie(startFrame, endFrame); + } +} + +void CPetConversations::resetDials() { + resetDials(getActiveNPCName()); +} + +void CPetConversations::resetDials(const CString &name) { + TTnpcScript *script = getNPCScript(name); + + for (int idx = 0; idx < TOTAL_DIALS; ++idx) { + uint oldLevel = _npcLevels[idx]; + uint newLevel = getDialLevel(idx, script); + npcDialChange(idx, oldLevel, newLevel); + _npcLevels[idx] = newLevel; + } +} + +void CPetConversations::resetDials0() { + stopNPCTimer(); + resetDials("0"); +} + +void CPetConversations::addLine(const CString &line) { + _log.addLine(line); + scrollToBottom(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_conversations.h b/engines/titanic/pet_control/pet_conversations.h new file mode 100644 index 0000000000..9e8b093d62 --- /dev/null +++ b/engines/titanic/pet_control/pet_conversations.h @@ -0,0 +1,267 @@ +/* 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 TITANIC_PET_CONVERSATIONS_H +#define TITANIC_PET_CONVERSATIONS_H + +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_text.h" +#include "titanic/pet_control/pet_gfx_element.h" +#include "titanic/true_talk/true_talk_manager.h" + +namespace Titanic { + +#define TOTAL_DIALS 3 + +class CPetConversations : public CPetSection { +private: + CPetGfxElement _scrollUp; + CPetGfxElement _scrollDown; + CPetGfxElement _dialBackground; + CPetGfxElement _dials[TOTAL_DIALS]; + uint _npcLevels[TOTAL_DIALS]; + CPetGfxElement _val4; + CPetGfxElement _val5; + CPetGfxElement _indent; + Rect _rect1; + CPetGfxElement _doorBot; + CPetGfxElement _bellBot; + CPetGfxElement _splitter; + CPetGfxElement _npcIcons[9]; + int _npcNum; + CPetText _log; + CPetText _textInput; + bool _logChanged; + int _field418; + CString _npcName; +private: + /** + * Sets up the control + */ + bool setupControl(CPetControl *petControl); + + /** + * Scroll up the conversation log + */ + void scrollUp(); + + /** + * Scroll down the conversation log + */ + void scrollDown(); + + /** + * Scroll up one page in the conversation log + */ + void scrollUpPage(); + + /** + * Scroll down one page in the conversation log + */ + void scrollDownPage(); + + /** + * Scroll to the top of the conversation log + */ + void scrollToTop(); + + /** + * Scroll to the bottom of the conversation log + */ + void scrollToBottom(); + + /** + * Check whether an NPC can be summoned + */ + int canSummonBot(const CString &name); + + /** + * Summon an NPC + */ + void summonBot(const CString &name); + + /** + * Starts the NPC timer + */ + void startNPCTimer(); + + /** + * Stops the NPC timer + */ + void stopNPCTimer(); + + /** + * Get the TrueTalk script associated with a given NPC + */ + TTnpcScript *getNPCScript(const CString &name) const; + + /** + * Handle a keypress + */ + bool handleKey(const Common::KeyState &keyState); + + /** + * Handles an entered text line + */ + void textLineEntered(const CString &textLine); + + /** + * Updates one of the dials with data from a given NPC + */ + void updateDial(uint dialNum, const CString &npcName); + + /** + * Get a dial level + */ + uint getDialLevel(uint dialNum, TTnpcScript *script, int v = 1); + + /** + * Called when the dial for an NPC is being changed + */ + void npcDialChange(uint dialNum, int oldLevel, int newLevel); +public: + CPetConversations(); + virtual ~CPetConversations() {} + + /** + * Sets up the section + */ + virtual bool setup(CPetControl *petControl); + + /** + * Reset the section + */ + virtual bool reset(); + + /** + * Draw the section + */ + virtual void draw(CScreenManager *screenManager); + + /** + * Get the bounds for the section + */ + virtual Rect getBounds() const; + + /** + * Returns true if the object is in a valid state + */ + virtual bool isValid(CPetControl *petControl); + + /** + * Following are handlers for the various messages that the PET can + * pass onto the currently active section/area + */ + virtual bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + virtual bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); + virtual bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg); + virtual bool KeyCharMsg(CKeyCharMsg *msg); + virtual bool VirtualKeyCharMsg(CVirtualKeyCharMsg *msg); + + /** + * Display a message + */ + virtual void displayMessage(const CString &msg); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file, int param); + + /** + * Called after a game has been loaded + */ + virtual void postLoad(); + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Called when a section is switched to + */ + virtual void enter(PetArea oldArea); + + /** + * Called when a section is being left, to switch to another area + */ + virtual void leave(); + + /** + * Called when a previously set up PET timer expires + */ + virtual void timerExpired(int val); + + /** + * Display a title for an NPC + */ + virtual void displayNPCName(CGameObject *npc); + + /** + * Sets the NPC to use + */ + virtual void setNPC(const CString &name); + + /** + * Resets the active NPC + */ + virtual void resetNPC(); + + /** + * Show the text cursor + */ + virtual void showCursor(); + + /** + * Hide the text cursor + */ + virtual void hideCursor(); + + /** + * Set the active NPC + */ + void setActiveNPC(const CString &name); + + /** + * Resets the dials with the data for the currently active NPC + */ + void resetDials(); + + /** + * Reset the dials with those for a given NPC + */ + void resetDials(const CString &name); + + /** + * Reset the dials to the '0' position + */ + void resetDials0(); + + /** + * Adds a line to the log + */ + void addLine(const CString &line); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_CONVERSATIONS_H */ diff --git a/engines/titanic/pet_control/pet_drag_chev.cpp b/engines/titanic/pet_control/pet_drag_chev.cpp new file mode 100644 index 0000000000..d437d43799 --- /dev/null +++ b/engines/titanic/pet_control/pet_drag_chev.cpp @@ -0,0 +1,76 @@ +/* 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 "titanic/pet_control/pet_drag_chev.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/messages/messages.h" +#include "titanic/npcs/succubus.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CPetDragChev, CPetGraphic2) + ON_MESSAGE(MouseDragStartMsg) + ON_MESSAGE(MouseDragMoveMsg) + ON_MESSAGE(MouseDragEndMsg) +END_MESSAGE_MAP() + +void CPetDragChev::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic2::save(file, indent); +} + +void CPetDragChev::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic2::load(file); +} + +bool CPetDragChev::MouseDragStartMsg(CMouseDragStartMsg *msg) { + getName(); + return checkStartDragging(msg); +} + +bool CPetDragChev::MouseDragMoveMsg(CMouseDragMoveMsg *msg) { + dragMove(msg->_mousePos); + return true; +} + +bool CPetDragChev::MouseDragEndMsg(CMouseDragEndMsg *msg) { + if (msg->_dropTarget) { + CSuccUBus *succubus = static_cast<CSuccUBus *>(msg->_dropTarget); + + if (succubus) { + CSetChevRoomBits chevMsg(_id); + chevMsg.execute(succubus); + } else { + CPetControl *petControl = getPetControl(); + if (petControl && petControl->contains(msg->_mousePos) + && msg->_mousePos.x < 528) { + if (petControl->checkDragEnd(this)) + petMoveToHiddenRoom(); + } + } + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_drag_chev.h b/engines/titanic/pet_control/pet_drag_chev.h new file mode 100644 index 0000000000..9f4a6f0dc9 --- /dev/null +++ b/engines/titanic/pet_control/pet_drag_chev.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_PET_DRAG_CHEV_H +#define TITANIC_PET_DRAG_CHEV_H + +#include "titanic/pet_control/pet_graphic2.h" + +namespace Titanic { + +class CPetDragChev : public CPetGraphic2 { + DECLARE_MESSAGE_MAP; +protected: + bool MouseDragStartMsg(CMouseDragStartMsg *msg); + bool MouseDragMoveMsg(CMouseDragMoveMsg *msg); + bool MouseDragEndMsg(CMouseDragEndMsg *msg); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_DRAG_CHEV_H */ diff --git a/engines/titanic/pet_control/pet_element.cpp b/engines/titanic/pet_control/pet_element.cpp new file mode 100644 index 0000000000..c5e1a6ea9c --- /dev/null +++ b/engines/titanic/pet_control/pet_element.cpp @@ -0,0 +1,106 @@ +/* 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/textconsole.h" +#include "titanic/pet_control/pet_element.h" +#include "titanic/core/game_object.h" + +namespace Titanic { + +CPetElement::CPetElement() : _mode(MODE_UNSELECTED) {} + +Rect CPetElement::getBounds() const { + return Rect(); +} + +bool CPetElement::MouseButtonDownMsg(const Point &pt) { + bool result = _bounds.contains(pt); + if (result) + setMode(MODE_SELECTED); + return result; +} + +bool CPetElement::MouseButtonUpMsg(const Point &pt) { + bool result = _bounds.contains(pt); + if (result) + setMode(MODE_UNSELECTED); + return result; +} + +bool CPetElement::MouseDoubleClickMsg(const Point &pt) const { + return _bounds.contains(pt); +} + +bool CPetElement::MouseMoveMsg(const Point &pt) { + bool result = _bounds.contains(pt); + if (result) + setMode(MODE_FOCUSED); + return result; +} + +bool CPetElement::contains2(const Point &pt) const { + return _bounds.contains(pt); +} + +void CPetElement::playMovie(uint startFrame, uint endFrame) const { + CGameObject *gameObject = getObject(); + + if (gameObject) + gameObject->playMovie(startFrame, endFrame, 0); +} + +void CPetElement::changeStatus(int val) const { + CGameObject *gameObject = getObject(); + + if (gameObject) + gameObject->playMovie(val); +} + +bool CPetElement::hasActiveMovie() const { + CGameObject *gameObject = getObject(); + return gameObject ? gameObject->hasActiveMovie() : false; +} + +void CPetElement::loadFrame(int frameNumber) { + CGameObject *gameObject = getObject(); + if (gameObject) + gameObject->loadFrame(frameNumber); +} + +int CPetElement::getMovieFrame() const { + CGameObject *gameObject = getObject(); + return gameObject ? gameObject->getMovieFrame() : 0; +} + +void CPetElement::setMode(PetElementMode newMode) { + if (newMode >= MODE_UNSELECTED && newMode <= MODE_FOCUSED) + changeMode(newMode); +} + +void CPetElement::setSelected(bool flag) { + if (flag) + changeMode(MODE_SELECTED); + else + changeMode(MODE_UNSELECTED); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_element.h b/engines/titanic/pet_control/pet_element.h new file mode 100644 index 0000000000..bbf3e83537 --- /dev/null +++ b/engines/titanic/pet_control/pet_element.h @@ -0,0 +1,154 @@ +/* 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 TITANIC_PET_ELEMENT_H +#define TITANIC_PET_ELEMENT_H + +#include "titanic/support/simple_file.h" +#include "titanic/support/string.h" +#include "titanic/core/link_item.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +enum PetElementMode { MODE_UNSELECTED = 0, MODE_SELECTED = 1, MODE_FOCUSED = 2 }; + +class CGameObject; +class CPetControl; + +class CPetElement { +protected: + Rect _bounds; + PetElementMode _mode; +public: + CPetElement(); + virtual ~CPetElement() {} + + /** + * Sets up the element + */ + virtual void setup(PetElementMode mode, const CString &name, + CPetControl *petControl) {} + + /** + * Reset the element + */ + virtual void reset(const CString &name, CPetControl *petControl, PetElementMode mode) {} + + /** + * Draw the item + */ + virtual void draw(CScreenManager *screenManager) {} + + /** + * Draw the item + */ + virtual void draw(CScreenManager *screenManager, const Point &destPos) {} + + /** + * Get the bounds for the element + */ + virtual Rect getBounds() const; + + /** + * Handles processing mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt); + + /** + * Handles processing mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Handles processing mouse button double click messages + */ + virtual bool MouseDoubleClickMsg(const Point &pt) const; + + /** + * Handles processing mouse move messages + */ + virtual bool MouseMoveMsg(const Point &pt); + + /** + * Returns whether the passed point falls inside the item + */ + virtual bool contains2(const Point &pt) const; + + /** + * Plays back a range of frames in the loaded video file for the element + */ + virtual void playMovie(uint startFrame, uint endFrame) const; + + /** + * Change the status of the associated object + */ + virtual void changeStatus(int newStatus) const; + + /** + * Returns true if the object associated with the item has an active movie + */ + virtual bool hasActiveMovie() const; + + /** + * Loads a frame + */ + virtual void loadFrame(int frameNumber); + + /** + * Get the current frame + */ + virtual int getMovieFrame() const; + + /** + * Get the game object associated with this item + */ + virtual CGameObject *getObject() const { return nullptr; } + + virtual void changeMode(PetElementMode newMode) { _mode = newMode; } + + void setMode(PetElementMode mode); + + /** + * Set whether the element is selected + */ + void setSelected(bool flag); + + /** + * Set the bounds for the element + */ + void setBounds(const Rect &r) { _bounds = r; } + + /** + * Translate the position of the element + */ + void translate(int deltaX, int deltaY) { _bounds.translate(deltaX, deltaY); } + + /** + * Translate the position of the element + */ + void translate(const Point &delta) { _bounds.translate(delta.x, delta.y); } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_ELEMENT_H */ diff --git a/engines/titanic/pet_control/pet_frame.cpp b/engines/titanic/pet_control/pet_frame.cpp new file mode 100644 index 0000000000..bc1a8e93b6 --- /dev/null +++ b/engines/titanic/pet_control/pet_frame.cpp @@ -0,0 +1,154 @@ +/* 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 "titanic/pet_control/pet_frame.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +static const PetArea PET_AREAS[6] = { + PET_CONVERSATION, PET_INVENTORY, PET_REMOTE, + PET_ROOMS, PET_REAL_LIFE, PET_STARFIELD +}; + +CPetFrame::CPetFrame() : CPetSection() { +} + +bool CPetFrame::setup(CPetControl *petControl) { + if (setPetControl(petControl)) + return reset(); + return false; +} + +bool CPetFrame::reset() { + if (_petControl) { + _background.reset("PetBackground", _petControl, MODE_UNSELECTED); + _modeBackground.reset("PetModeBackground", _petControl, MODE_UNSELECTED); + + for (int idx = 0; idx < 5; ++idx) { + CString resName = Common::String::format("PetMode%d", idx + 1); + _modeButtons[idx].reset(resName, _petControl, MODE_SELECTED); + } + + for (int idx = 0; idx < 6; ++idx) { + CString resName = Common::String::format("3Pettitle%d", idx + 1); + _titles[idx].reset(resName, _petControl, MODE_UNSELECTED); + } + + for (int idx = 0; idx < TOTAL_GLYPHS; ++idx) { + CString resName = Common::String::format("PetIndent%d", idx + 1); + _squares[idx].reset(resName, _petControl, MODE_UNSELECTED); + } + } + + return true; +} + +bool CPetFrame::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + for (int idx = 0; idx < 5; ++idx) { + if (_modeButtons[idx].MouseButtonUpMsg(msg->_mousePos)) { + _petControl->setArea(PET_AREAS[idx]); + resetArea(); + _modeButtons[idx].setMode(MODE_SELECTED); + return true; + } + } + + return false; +} + +bool CPetFrame::isValid(CPetControl *petControl) { + bool result = setPetControl(petControl); + if (result) { + _modeButtons[PET_AREAS[0]].setMode(MODE_UNSELECTED); + _modeButtons[PET_AREAS[4]].setMode(MODE_SELECTED); + } + + return result; +} + +void CPetFrame::postLoad() { + reset(); +} + +bool CPetFrame::setPetControl(CPetControl *petControl) { + if (petControl) { + _petControl = petControl; + + // Set the bounds of the individual elements + _background.setBounds(Rect(20, 350, 620, 480)); + _modeBackground.setBounds(Rect(590, 365, 611, 467)); + + // Squares used for holding glyphs in various tabs + Rect r(35, 373, 91, 429); + for (int idx = 0, xp = 0; idx < TOTAL_GLYPHS; ++idx, xp += 70) { + _squares[idx].setBounds(r); + _squares[idx].translate(xp, 0); + } + + // Draw the mode buttons vertically on the right edge of the PET + r = Rect(590, 365, 606, 381); + const int YLIST[] = { 7, 27, 45, 66, 84 }; + for (int idx = 0; idx < 5; ++idx) { + _modeButtons[idx].setBounds(r); + _modeButtons[idx].translate(4, YLIST[idx]); + } + _modeButtons[PET_AREAS[0]].setMode(MODE_SELECTED); + + const int XLIST[] = { 73, 54, 85, 109, 38, 71 }; + for (int idx = 0; idx < 6; ++idx) { + _titles[idx].setBounds(Rect(0, 0, 110, 11)); + _titles[idx].translate(600 - XLIST[idx], 471); + } + } + + return true; +} + +void CPetFrame::setArea(PetArea newArea) { + resetArea(); + if (newArea < PET_MESSAGE) + _modeButtons[PET_AREAS[newArea]].setMode(MODE_SELECTED); +} + +void CPetFrame::resetArea() { + for (int idx = 0; idx < 6; ++idx) + _modeButtons[idx].setMode(MODE_UNSELECTED); +} + +void CPetFrame::drawFrame(CScreenManager *screenManager) { + _background.draw(screenManager); + _modeBackground.draw(screenManager); + + for (int idx = 0; idx < 5; ++idx) + _modeButtons[idx].draw(screenManager); + + _titles[_petControl->_currentArea].draw(screenManager); +} + +void CPetFrame::drawSquares(CScreenManager *screenManager, int count) { + count = CLIP(count, 0, TOTAL_GLYPHS); + for (int idx = 0; idx < count; ++idx) + _squares[idx].draw(screenManager); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_frame.h b/engines/titanic/pet_control/pet_frame.h new file mode 100644 index 0000000000..d8924e83d3 --- /dev/null +++ b/engines/titanic/pet_control/pet_frame.h @@ -0,0 +1,101 @@ +/* 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 TITANIC_PET_FRAME_H +#define TITANIC_PET_FRAME_H + +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_gfx_element.h" + +namespace Titanic { + +/** + * This implements the frame and background for the PET display. + * This includes the area buttons and title + */ +class CPetFrame : public CPetSection { +private: + CPetGfxElement _modeButtons[6]; + CPetGfxElement _titles[6]; + CPetGfxElement _modeBackground; + CPetGfxElement _val2; + CPetGfxElement _val3; + CPetGfxElement _background; + CPetGfxElement _squares[7]; +private: + /** + * Called to set the owning PET instance and set some initial state + */ + bool setPetControl(CPetControl *petControl); +public: + CPetFrame(); + + /** + * Sets up the section + */ + virtual bool setup(CPetControl *petControl); + + /** + * Sets up the section + */ + virtual bool reset(); + + /** + * Handles mouse down messages + */ + virtual bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + virtual bool MouseButtonUpMsg(CMouseButtonUpMsg *msg) { return false; } + + /** + * Returns true if the object is in a valid state + */ + virtual bool isValid(CPetControl *petControl); + + /** + * Called after a game has been loaded + */ + virtual void postLoad(); + + /** + * Called when the current PET area changes + */ + void setArea(PetArea newArea); + + /** + * Reset the currently selected area + */ + void resetArea(); + + /** + * Draws the PET frame + */ + void drawFrame(CScreenManager *screenManager); + + /** + * Draws the indent + */ + void drawSquares(CScreenManager *screenManager, int count); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_FRAME_H */ diff --git a/engines/titanic/pet_control/pet_gfx_element.cpp b/engines/titanic/pet_control/pet_gfx_element.cpp new file mode 100644 index 0000000000..6022885770 --- /dev/null +++ b/engines/titanic/pet_control/pet_gfx_element.cpp @@ -0,0 +1,103 @@ +/* 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/textconsole.h" +#include "titanic/core/game_object.h" +#include "titanic/pet_control/pet_element.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +void CPetGfxElement::setup(PetElementMode mode, const CString &name, + CPetControl *petControl) { + switch (mode) { + case MODE_UNSELECTED: + _object0 = petControl->getHiddenObject(name); + break; + case MODE_SELECTED: + _object1 = petControl->getHiddenObject(name); + break; + case MODE_FOCUSED: + _object2 = petControl->getHiddenObject(name); + break; + default: + break; + } +} + +void CPetGfxElement::reset(const CString &name, CPetControl *petControl, PetElementMode mode) { + if (!petControl) + return; + + CString numString(3); + int classNum = petControl->getPassengerClass(); + + if (classNum >= 1 && classNum <= 3) { + numString = CString(classNum); + } else if (classNum == 4) { + int stateC = petControl->getPriorClass(); + if (stateC == 1) + numString = CString(stateC); + } + + CString resName = numString + name; + setup(mode, resName, petControl); +} + +void CPetGfxElement::draw(CScreenManager *screenManager) { + draw(screenManager, Common::Point(_bounds.left, _bounds.top)); +} + +void CPetGfxElement::draw(CScreenManager *screenManager, const Common::Point &destPos) { + CGameObject *obj = getObject(); + if (!obj) + obj = _object0; + + if (obj) + obj->draw(screenManager, destPos); +} + +Rect CPetGfxElement::getBounds() const { + CGameObject *obj = getObject(); + if (!obj) + obj = _object0; + + if (obj && obj->surfaceHasFrame()) + return _bounds; + else + return Rect(); +} + +CGameObject *CPetGfxElement::getObject() const { + switch (_mode) { + case MODE_UNSELECTED: + return _object0; + case MODE_SELECTED: + return _object1; + case MODE_FOCUSED: + return _object2; + default: + return nullptr; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_gfx_element.h b/engines/titanic/pet_control/pet_gfx_element.h new file mode 100644 index 0000000000..91d9b9ccb2 --- /dev/null +++ b/engines/titanic/pet_control/pet_gfx_element.h @@ -0,0 +1,74 @@ +/* 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 TITANIC_PET_GFX_ELEMENT_H +#define TITANIC_PET_GFX_ELEMENT_H + +#include "titanic/pet_control/pet_element.h" + +namespace Titanic { + +class CPetGfxElement: public CPetElement { +public: + CGameObject *_object0; + CGameObject *_object1; + CGameObject *_object2; +public: + CPetGfxElement() : CPetElement(), _object0(nullptr), _object1(nullptr), + _object2(nullptr) {} + + /** + * Setup the element + */ + virtual void setup(PetElementMode mode, const CString &name, + CPetControl *petControl); + + /** + * Reset the element + */ + virtual void reset(const CString &name, CPetControl *petControl, + PetElementMode mode = MODE_UNSELECTED); + + /** + * Draw the item + */ + virtual void draw(CScreenManager *screenManager); + + /** + * Draw the item + */ + virtual void draw(CScreenManager *screenManager, const Common::Point &destPos); + + /** + * Get the bounds for the element + */ + virtual Rect getBounds() const; + + /** + * Get the game object associated with this item + */ + virtual CGameObject *getObject() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_GFX_ELEMENT_H */ diff --git a/engines/titanic/pet_control/pet_glyphs.cpp b/engines/titanic/pet_control/pet_glyphs.cpp new file mode 100644 index 0000000000..bd05342095 --- /dev/null +++ b/engines/titanic/pet_control/pet_glyphs.cpp @@ -0,0 +1,566 @@ +/* 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 "titanic/pet_control/pet_glyphs.h" +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +bool CPetGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + _element.setBounds(Rect(0, 0, 52, 50)); + _owner = owner; + return true; +} + +void CPetGlyph::drawAt(CScreenManager *screenManager, const Point &pt, bool isHighlighted_) { + _element.translate(pt.x, pt.y); + _element.draw(screenManager); + _element.translate(-pt.x, -pt.y); +} + +void CPetGlyph::updateTooltip() { + CPetText *petText = getPetSection()->getText(); + if (petText) { + petText->setColor(getPetSection()->getColor(0)); + getTooltip(petText); + + if (_owner) + getPetSection()->stopTextTimer(); + } +} + +bool CPetGlyph::contains(const Point &delta, const Point &pt) { + translate(delta); + bool result = _element.contains2(pt); + translateBack(delta); + + return result; +} + +CPetSection *CPetGlyph::getPetSection() const { + return _owner ? _owner->getOwner() : nullptr; +} + +CPetControl *CPetGlyph::getPetControl() const { + return _owner ? _owner->getPetControl() : nullptr; +} + +void CPetGlyph::setName(const CString &name, CPetControl *petControl) { + Rect r(0, 0, 52, 52); + _element.setBounds(r); + _element.reset(name, petControl, MODE_UNSELECTED); +} + +bool CPetGlyph::isHighlighted() const { + return _owner->isGlyphHighlighted(this); +} + +/*------------------------------------------------------------------------*/ + +CPetGlyphs::CPetGlyphs() : _firstVisibleIndex(0), _numVisibleGlyphs(TOTAL_GLYPHS), + _highlightIndex(-1), _field1C(-1), _flags(0), + _dragGlyph(nullptr), _owner(nullptr) { +} + +void CPetGlyphs::setNumVisible(int total) { + if (total > 0) + _numVisibleGlyphs = total; +} + +void CPetGlyphs::clear() { + changeHighlight(-1); + destroyContents(); + _firstVisibleIndex = 0; +} + +void CPetGlyphs::setup(int numVisible, CPetSection *owner) { + setNumVisible(numVisible); + _owner = owner; + _selection.setBounds(Rect(0, 0, 76, 76)); + + int buttonsLeft = numVisible * 70 + 21; + + _scrollLeft.setBounds(Rect(0, 0, 31, 15)); + _scrollLeft.translate(buttonsLeft, 373); + _scrollRight.setBounds(Rect(0, 0, 31, 15)); + _scrollRight.translate(buttonsLeft, 413); +} + +void CPetGlyphs::reset() { + if (_owner && _owner->_petControl) { + CPetControl *pet = _owner->_petControl; + + _scrollLeft.reset("PetScrollLeft", pet, MODE_UNSELECTED); + _scrollRight.reset("PetScrollRight", pet, MODE_UNSELECTED); + _selection.reset("PetSelection", pet, MODE_UNSELECTED); + + for (iterator i = begin(); i != end(); ++i) { + (*i)->reset(); + } + } +} + +void CPetGlyphs::enter() { + if (_highlightIndex != -1) { + CPetGlyph *glyph = getGlyph(_highlightIndex); + if (glyph) + glyph->enter(); + } +} + +void CPetGlyphs::leave() { + if (_highlightIndex != -1) { + CPetGlyph *glyph = getGlyph(_highlightIndex); + if (glyph) + glyph->leave(); + } +} + +void CPetGlyphs::draw(CScreenManager *screenManager) { + if (_highlightIndex != -1) { + int index = getHighlightedIndex(_highlightIndex); + if (index != -1) { + Point tempPoint; + Point pt = getPosition(index); + pt -= Point(12, 13); + _selection.translate(pt.x, pt.y); + _selection.draw(screenManager); + _selection.translate(-pt.x, -pt.y); + } + } + + // Iterate through displaying glyphs on the screen + int listSize = size(); + for (int index = 0; index < _numVisibleGlyphs; ++index) { + int itemIndex = getItemIndex(index); + + if (itemIndex >= 0 && itemIndex < listSize) { + Point pt = getPosition(itemIndex); + CPetGlyph *glyph = getGlyph(itemIndex); + + if (glyph) + glyph->drawAt(screenManager, pt, index == _highlightIndex); + } + } + + // Draw scrolling arrows if more than a screen's worth of items are showing + if (listSize > _numVisibleGlyphs || (_flags & GFLAG_16)) { + _scrollLeft.draw(screenManager); + _scrollRight.draw(screenManager); + } + + // Handle secondary highlight + if (_highlightIndex != -1) { + CPetGlyph *glyph = getGlyph(_highlightIndex); + if (glyph) + glyph->draw2(screenManager); + } +} + +Point CPetGlyphs::getPosition(int index) const { + Point tempPoint(37 + index * 70, 375); + return tempPoint; +} + +Rect CPetGlyphs::getRect(int index) const { + Point pt = getPosition(index); + return Rect(pt.x, pt.y, pt.x + 52, pt.y + 52); +} + +void CPetGlyphs::changeHighlight(int index) { + if (index == _highlightIndex) + return; + + if (_highlightIndex >= 0 && (_flags & GFLAG_4)) { + CPetGlyph *glyph = getGlyph(_highlightIndex); + if (glyph) + glyph->unhighlightCurrent(); + } + + _highlightIndex = index; + if (index >= 0) { + CPetGlyph *glyph = getGlyph(_highlightIndex); + + if (glyph) { + if (_flags & GFLAG_4) { + Point pt; + int idx = getHighlightedIndex(_highlightIndex); + if (idx >= 0) + pt = getPosition(idx); + + glyph->highlightCurrent(pt); + } + + glyph->updateTooltip(); + } + } else if (_owner) { + _owner->removeText(); + } +} + +void CPetGlyphs::highlight(int index) { + if (index >= 0) { + setSelectedIndex(index); + changeHighlight(index); + makePetDirty(); + } +} + +void CPetGlyphs::highlight(const CPetGlyph *glyph) { + highlight(indexOf(glyph)); +} + +int CPetGlyphs::getHighlightedIndex(int index) const { + int idx = index - _firstVisibleIndex; + return (idx >= 0 && idx < _numVisibleGlyphs) ? idx : -1; +} + +int CPetGlyphs::getItemIndex(int index) const { + return _firstVisibleIndex + index; +} + +void CPetGlyphs::setSelectedIndex(int index) { + if (index >= 0 && index < (int)size() && getHighlightedIndex(index) == -1) { + if (_firstVisibleIndex <= index) + index -= _numVisibleGlyphs - 1; + + setFirstVisible(index); + } +} + +CPetGlyph *CPetGlyphs::getGlyph(int index) const { + for (const_iterator i = begin(); i != end(); ++i) { + if (index-- == 0) + return *i; + } + + return nullptr; +} + +CPetControl *CPetGlyphs::getPetControl() const { + return _owner ? _owner->getPetControl() : nullptr; +} + +void CPetGlyphs::setFirstVisible(int index) { + if (index != _firstVisibleIndex) { + _firstVisibleIndex = index; + + if ((_flags & GFLAG_8) && _highlightIndex != -1) { + CPetGlyph *glyph = getGlyph(_highlightIndex); + + if (glyph) { + int idx = getHighlightedIndex(_highlightIndex); + if (idx != -1) { + Point tempPt = getPosition(idx); + glyph->glyphFocused(tempPt, true); + } + } + } + } +} + +void CPetGlyphs::scrollLeft() { + if (_firstVisibleIndex > 0) { + setFirstVisible(_firstVisibleIndex - 1); + if (_highlightIndex != -1) { + int index = getHighlightedIndex(_highlightIndex); + if (index == -1) + changeHighlight(_highlightIndex - 1); + } + + makePetDirty(); + } +} + +void CPetGlyphs::scrollRight() { + int count = size(); + int right = count - _numVisibleGlyphs; + + if (_firstVisibleIndex < right) { + setFirstVisible(_firstVisibleIndex + 1); + if (_highlightIndex != -1) { + int index = getHighlightedIndex(_highlightIndex); + if (index == -1) + changeHighlight(_highlightIndex + 1); + } + + makePetDirty(); + } +} + +void CPetGlyphs::makePetDirty() { + if (_owner && _owner->_petControl) + _owner->_petControl->makeDirty(); +} + +bool CPetGlyphs::MouseButtonDownMsg(const Point &pt) { + if (_scrollLeft.contains2(pt)) { + scrollLeft(); + return true; + } + + if (_scrollRight.contains2(pt)) { + scrollRight(); + return true; + } + + for (int idx = 0; idx < _numVisibleGlyphs; ++idx) { + Rect glyphRect = getRect(idx); + if (glyphRect.contains(pt)) { + int index = getItemIndex(idx); + CPetGlyph *glyph = getGlyph(index); + if (glyph) { + if (_highlightIndex == index) { + glyph->selectGlyph(glyphRect, pt); + glyph->updateTooltip(); + } else { + changeHighlight(index); + makePetDirty(); + } + + return true; + } + } + } + + if (_highlightIndex != -1) { + CPetGlyph *glyph = getGlyph(_highlightIndex); + + if (glyph) { + if (glyph->MouseButtonDownMsg(pt)) + return true; + + if (!(_flags & GFLAG_2)) { + changeHighlight(-1); + makePetDirty(); + } + } + } + + return false; +} + +bool CPetGlyphs::MouseButtonUpMsg(const Point &pt) { + if (_highlightIndex >= 0) { + CPetGlyph *glyph = getGlyph(_highlightIndex); + if (glyph) { + if (glyph->MouseButtonUpMsg(pt)) + return true; + } + } + + return false; +} + +bool CPetGlyphs::MouseDragStartMsg(CMouseDragStartMsg *msg) { + if (!(_flags & GFLAG_1) && _highlightIndex >= 0) { + CPetGlyph *glyph = getGlyph(_highlightIndex); + int index = getHighlightedIndex(_highlightIndex); + Rect glyphRect = getRect(index); + + if (glyphRect.contains(msg->_mousePos)) + return glyph->dragGlyph(glyphRect, msg); + else + return glyph->MouseDragStartMsg(msg); + } + + return false; +} + +bool CPetGlyphs::MouseDragMoveMsg(CMouseDragMoveMsg *msg) { + if (_dragGlyph) { + return _dragGlyph->MouseDragMoveMsg(msg); + } else { + return false; + } +} + +bool CPetGlyphs::MouseDragEndMsg(CMouseDragEndMsg *msg) { + if (_dragGlyph) { + return _dragGlyph->MouseDragEndMsg(msg); + } else { + return false; + } +} + +bool CPetGlyphs::KeyCharMsg(int key) { + if (_highlightIndex >= 0) { + CPetGlyph *glyph = getGlyph(_highlightIndex); + + if (glyph && glyph->KeyCharMsg(key)) + return true; + } + + return false; +} + +bool CPetGlyphs::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { + Common::KeyCode key = msg->_keyState.keycode; + + switch (key) { + case Common::KEYCODE_LEFT: + decSelection(); + return true; + + case Common::KEYCODE_RIGHT: + incSelection(); + return true; + + default: + break; + } + + if (_highlightIndex >= 0) { + CPetGlyph *glyph = getGlyph(_highlightIndex); + if (glyph && glyph->VirtualKeyCharMsg(msg)) + return true; + } + + return false; +} + +bool CPetGlyphs::enterHighlighted() { + if (_highlightIndex >= 0) + return getGlyph(_highlightIndex)->enterHighlighted(); + else + return false; +} + +void CPetGlyphs::leaveHighlighted() { + if (_highlightIndex >= 0) + getGlyph(_highlightIndex)->leaveHighlighted(); +} + +void CPetGlyphs::startDragging(CPetGlyph *glyph, CMouseDragStartMsg *msg) { + if (glyph) { + _dragGlyph = glyph; + msg->_dragItem = getPetControl(); + } +} + +void CPetGlyphs::endDragging() { + _dragGlyph = nullptr; +} + +bool CPetGlyphs::highlighted14() { + if (_highlightIndex != -1) { + CPetGlyph *pet = getGlyph(_highlightIndex); + if (pet) { + pet->updateTooltip(); + return true; + } + } + + return false; +} + +int CPetGlyphs::indexOf(const CPetGlyph *glyph) const { + int index = 0; + for (const_iterator i = begin(); i != end(); ++i, ++index) { + if (*i == glyph) + return index; + } + + return -1; +} + +void CPetGlyphs::incSelection() { + if (_highlightIndex >= 0 && _highlightIndex < ((int)size() - 1)) { + if (getHighlightedIndex(_highlightIndex) >= (_numVisibleGlyphs - 1)) + scrollRight(); + + changeHighlight(_highlightIndex + 1); + makePetDirty(); + } +} + +void CPetGlyphs::decSelection() { + if (_highlightIndex > 0) { + if (getHighlightedIndex(_highlightIndex) == 0) + scrollLeft(); + + changeHighlight(_highlightIndex - 1); + makePetDirty(); + } +} + +CGameObject *CPetGlyphs::getObjectAt(const Point &pt) const { + for (int idx = 0; idx < _numVisibleGlyphs; ++idx) { + Rect glyphRect = getRect(idx); + if (glyphRect.contains(pt)) { + CPetGlyph *glyph = getGlyph(getItemIndex(idx)); + if (glyph) + return glyph->getObjectAt(); + } + } + + return nullptr; +} + +bool CPetGlyphs::isGlyphHighlighted(const CPetGlyph *glyph) const { + if (_highlightIndex == -1) + return false; + + return indexOf(glyph) == _highlightIndex; +} + +Point CPetGlyphs::getHighlightedGlyphPos() const { + if (_highlightIndex != -1) { + int idx = getHighlightedIndex(_highlightIndex); + if (idx >= 0) + return getPosition(idx); + } + + return Point(0, 0); +} + +bool CPetGlyphs::areItemsValid() const { + for (const_iterator i = begin(); i != end(); ++i) { + if (!(*i)->isValid()) + return false; + } + + return true; +} + +void CPetGlyphs::removeInvalid() { + if (!areItemsValid()) { + changeHighlight(-1); + + for (iterator i = begin(); i != end(); ) { + CPetGlyph *glyph = *i; + + if (!glyph->isValid()) { + i = erase(i); + delete glyph; + } else { + ++i; + } + } + + _firstVisibleIndex = CLIP(_firstVisibleIndex, 0, + (int)size() - _numVisibleGlyphs); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_glyphs.h b/engines/titanic/pet_control/pet_glyphs.h new file mode 100644 index 0000000000..c07cc5ed9a --- /dev/null +++ b/engines/titanic/pet_control/pet_glyphs.h @@ -0,0 +1,492 @@ +/* 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 TITANIC_PET_GLYPHS_H +#define TITANIC_PET_GLYPHS_H + +#include "common/keyboard.h" +#include "titanic/core/list.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/pet_control/pet_gfx_element.h" +#include "titanic/support/rect.h" + +namespace Titanic { + +#define TOTAL_GLYPHS 7 + +class CPetGlyphs; +class CPetSection; +class CPetText; + +enum GlyphActionMode { ACTION_REMOVE = 0, ACTION_REMOVED = 1, ACTION_CHANGE = 2 }; + +enum GlyphFlag { GFLAG_1 = 1, GFLAG_2 = 2, GFLAG_4 = 4, GFLAG_8 = 8, GFLAG_16 = 16 }; + +class CGlyphAction { +protected: + GlyphActionMode _mode; +public: + CGlyphAction() : _mode(ACTION_REMOVED) {} + CGlyphAction(GlyphActionMode mode) : _mode(mode) {} + + GlyphActionMode getMode() const { return _mode; } +}; + +class CPetGlyph : public ListItem { +protected: + /** + * Get the overall pet section owner + */ + CPetSection *getPetSection() const; +public: + CPetGfxElement _element; + CPetGlyphs *_owner; +public: + CPetGlyph() : ListItem(), _owner(nullptr) {} + + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Reset the glyph + */ + virtual bool reset() { return false; } + + /** + * Called when the PET area is entered + */ + virtual void enter() {} + + /** + * Called when the PET area is left + */ + virtual void leave() {} + + /** + * Draw the glyph at a specified position + */ + virtual void drawAt(CScreenManager *screenManager, const Point &pt, bool isHighlighted); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager) {} + + /** + * Updates the tooltip being shown for the glyph + */ + virtual void updateTooltip(); + + /** + * Get the bounds for the glyph + */ + virtual Rect getBounds() const { return Rect(); } + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { return false; } + + /** + * Called when mouse drag starts + */ + virtual bool MouseDragStartMsg(CMouseDragStartMsg *msg) { return false; } + + /** + * Called during mouse drags + */ + virtual bool MouseDragMoveMsg(CMouseDragMoveMsg *msg) { return false; } + + /** + * Called when mouse drag ends + */ + virtual bool MouseDragEndMsg(CMouseDragEndMsg *msg) { return false; } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { return false; } + + /** + * Handles mouse double-click messages + */ + virtual bool MouseDoubleClickMsg(const CMouseDoubleClickMsg *msg) { return false; } + + /** + * Handles keypresses + */ + virtual bool KeyCharMsg(int key) { return false; } + + /** + * Handles keypresses + */ + virtual bool VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { return false; } + + /** + * Unhighlight any currently highlighted element + */ + virtual void unhighlightCurrent() {} + + /** + * Highlight any currently highlighted element + */ + virtual void highlightCurrent(const Point &pt) {} + + /** + * Glyph has been shifted to be first visible one + */ + virtual void glyphFocused(const Point &topLeft, bool flag) {} + + /** + * Selects a glyph + */ + virtual void selectGlyph(const Point &topLeft, const Point &pt) {} + + /** + * Called when a glyph drag starts + */ + virtual bool dragGlyph(const Point &topLeft, CMouseDragStartMsg *msg) { return false; } + + /** + * Returns true if the glyph's bounds, shifted to a given position, + * will contain the specified point + */ + virtual bool contains(const Point &delta, const Point &pt); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text) {} + + /** + * Saves the data for the glyph + */ + virtual void saveGlyph(SimpleFile *file, int indent) {} + + virtual bool proc33(CPetGlyph *glyph) { return true; } + + /** + * Return whether the glyph is currently valid + */ + virtual bool isValid() const { return true; } + + /** + * Called on a highlighted item when PET area is entered + */ + virtual bool enterHighlighted() { return false; } + + /** + * Called on a highlighted item when PET area is left + */ + virtual void leaveHighlighted() {} + + /** + * Returns the object associated with the glyph + */ + virtual CGameObject *getObjectAt() { return nullptr; } + + /** + * Does a processing action on the glyph + */ + virtual bool doAction(CGlyphAction *action) { return true; } + + /** + * Translate the glyph's position + */ + void translate(const Point &pt) { _element.translate(pt.x, pt.y); } + + /** + * Translate the glyph's position back + */ + void translateBack(const Point &pt) { _element.translate(-pt.x, -pt.y); } + + /** + * Get the parent RealLife area + */ + CPetGlyphs *getOwner() { return _owner; } + + /** + * Get the PET control + */ + CPetControl *getPetControl() const; + + /** + * Sets new name and default bounds for glyph + */ + void setName(const CString &name, CPetControl *petControl); + + /** + * Returns true if the specified glyph is the currently highlighted one + */ + bool isHighlighted() const; +}; + +class CPetGlyphs : public List<CPetGlyph> { +private: + /** + * Get a position for the glyph + */ + Point getPosition(int index) const; + + /** + * Get a rect for the glyph + */ + Rect getRect(int index) const; + + /** + * Returns the on-screen index for the highlight to be shown at + */ + int getHighlightedIndex(int index) const; + + /** + * Returns the index of a glyph given the visible on-screen glyph number + */ + int getItemIndex(int index) const; + + /** + * Set the item index + */ + void setSelectedIndex(int index); + + /** + * Return a specified glyph + */ + CPetGlyph *getGlyph(int index) const; + + /** + * Scrolls the glyphs to the left + */ + void scrollLeft(); + + /** + * Scrolls the glyphs to the right + */ + void scrollRight(); + + /** + * Set the first visible glyph index + */ + void setFirstVisible(int index); + + /** + * Make the PET dirty + */ + void makePetDirty(); + + /** + * Returns true if all the glyphs are in a valid state + */ + bool areItemsValid() const; +protected: + int _firstVisibleIndex; + int _totalGlyphs; + int _numVisibleGlyphs; + int _highlightIndex; + int _field1C; + int _flags; + CPetGlyph *_dragGlyph; + CPetSection *_owner; + CPetGfxElement _selection; + CPetGfxElement _scrollLeft; + CPetGfxElement _scrollRight; +protected: + /** + * Change the currently selected glyph + */ + void changeHighlight(int index); +public: + CPetGlyphs(); + + /** + * Set the number of visible glyphs + */ + void setNumVisible(int total); + + /** + * Clears the glyph list + */ + void clear(); + + + /** + * The visual dimensions for the control and it's components + */ + virtual void setup(int numVisible, CPetSection *owner); + + /** + * Set up the control + */ + virtual void reset(); + + /** + * Called when PET area is entered + */ + virtual void enter(); + + /** + * Called when PET area is left + */ + virtual void leave(); + + void setFlags(int flags) { _flags = flags; } + + /** + * Draw the control + */ + void draw(CScreenManager *screenManager); + + /** + * Highlight a specific glyph by indexe + */ + void highlight(int index); + + /** + * Highlight a specific glyph + */ + void highlight(const CPetGlyph *glyph); + + /** + * Get the owning section for the glyphs + */ + CPetSection *getOwner() const { return _owner; } + + /** + * Get the PET control + */ + CPetControl *getPetControl() const; + + /** + * Mouse button down message + */ + bool MouseButtonDownMsg(const Point &pt); + + /** + * Mouse button up message + */ + bool MouseButtonUpMsg(const Point &pt); + + /** + * Mouse double click message + */ + bool MouseDoubleClickMsg(const Point &pt) { return true; } + + /** + * Mouse drag start messagge + */ + bool MouseDragStartMsg(CMouseDragStartMsg *msg); + + /** + * Mouse drag move message + */ + bool MouseDragMoveMsg(CMouseDragMoveMsg *msg); + + /** + * Mouse drag end message + */ + bool MouseDragEndMsg(CMouseDragEndMsg *msg); + + /** + * Key character message + */ + bool KeyCharMsg(int key); + + /** + * Virtual key message + */ + bool VirtualKeyCharMsg(CVirtualKeyCharMsg *msg); + + /** + * When the PET section is entered, passes onto the highlighted + * glyph, if any + */ + bool enterHighlighted(); + + /** + * When the PET section is left, passes onto the highlighted + * glyph, if any + */ + void leaveHighlighted(); + + /** + * Called when a dragging operation starts + */ + void startDragging(CPetGlyph *glyph, CMouseDragStartMsg *msg); + + /** + * Called when a dragging operation ends + */ + void endDragging(); + + /** + * Reset the highlight + */ + void resetHighlight() { changeHighlight(-1); } + + bool highlighted14(); + + /** + * Returns the index of the specified glyph in the lsit + */ + int indexOf(const CPetGlyph *glyph) const; + + /** + * Resets the scrolling of the glyphs list back to the start + */ + void scrollToStart() { _firstVisibleIndex = 0; } + + /** + * Increment the currently selected index + */ + void incSelection(); + + /** + * Decrement the currently selected index + */ + void decSelection(); + + /** + * Returns the object associated the glyph under the specified position + */ + CGameObject *getObjectAt(const Point &pt) const; + + /** + * Returns true if the specified glyph is the currently highlighted one + */ + bool isGlyphHighlighted(const CPetGlyph *glyph) const; + + /** + * Get the top-left position of the currently highlighted glyph + */ + Point getHighlightedGlyphPos() const; + + /** + * Removes any glyphs from the list that no longer have any images + * associated with them + */ + void removeInvalid(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_GLYPHS_H */ diff --git a/engines/titanic/pet_control/pet_graphic.cpp b/engines/titanic/pet_control/pet_graphic.cpp new file mode 100644 index 0000000000..bc7d86142d --- /dev/null +++ b/engines/titanic/pet_control/pet_graphic.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CPetGraphic, CGameObject); + +void CPetGraphic::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPetGraphic::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_graphic.h b/engines/titanic/pet_control/pet_graphic.h new file mode 100644 index 0000000000..630c8446eb --- /dev/null +++ b/engines/titanic/pet_control/pet_graphic.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_PET_GRAPHIC_H +#define TITANIC_PET_GRAPHIC_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPetGraphic : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_GRAPHIC_H */ diff --git a/engines/titanic/pet_control/pet_graphic2.cpp b/engines/titanic/pet_control/pet_graphic2.cpp new file mode 100644 index 0000000000..36c4d0f55a --- /dev/null +++ b/engines/titanic/pet_control/pet_graphic2.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/pet_control/pet_graphic2.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CPetGraphic2, CGameObject); + +void CPetGraphic2::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CPetGraphic2::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_graphic2.h b/engines/titanic/pet_control/pet_graphic2.h new file mode 100644 index 0000000000..58852fc65e --- /dev/null +++ b/engines/titanic/pet_control/pet_graphic2.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_PET_GRAPHIC2_H +#define TITANIC_PET_GRAPHIC2_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CPetGraphic2 : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_GRAPHIC2_H */ diff --git a/engines/titanic/pet_control/pet_inventory.cpp b/engines/titanic/pet_control/pet_inventory.cpp new file mode 100644 index 0000000000..55176d8b0e --- /dev/null +++ b/engines/titanic/pet_control/pet_inventory.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 "titanic/pet_control/pet_inventory.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/carry/carry.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CPetInventory::CPetInventory() : CPetSection(), + _movie(nullptr), _field290(false), _field294(0), _field298(0) { + for (int idx = 0; idx < TOTAL_ITEMS; ++idx) { + _itemBackgrounds[idx] = _itemGlyphs[idx] = nullptr; + } +} + +bool CPetInventory::setup(CPetControl *petControl) { + return setPetControl(petControl) && reset(); +} + +bool CPetInventory::reset() { + _items.reset(); + _text.setup(); + _text.setColor(getColor(0)); + _text.setLineColor(0, getColor(0)); + + return true; +} + +void CPetInventory::draw(CScreenManager *screenManager) { + _petControl->drawSquares(screenManager, 7); + _items.draw(screenManager); + _text.draw(screenManager); +} + +Rect CPetInventory::getBounds() const { + return _movie ? _movie->getBounds() : Rect(); +} + +void CPetInventory::changed(int changeType) { + switch (changeType) { + case 0: + case 2: + itemsChanged(); + break; + case 1: + removeInvalid(); + break; + default: + break; + } +} + +bool CPetInventory::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + return _items.MouseButtonDownMsg(msg->_mousePos); +} + +bool CPetInventory::MouseDragStartMsg(CMouseDragStartMsg *msg) { + bool result = _items.MouseDragStartMsg(msg); + if (result) + _petControl->makeDirty(); + return result; +} + +bool CPetInventory::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + return _items.MouseButtonUpMsg(msg->_mousePos); +} + +bool CPetInventory::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { + return _items.MouseDoubleClickMsg(msg->_mousePos); +} + +bool CPetInventory::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { + return _items.VirtualKeyCharMsg(msg); +} + +CGameObject *CPetInventory::dragEnd(const Point &pt) const { + return _items.getObjectAt(pt); +} + +bool CPetInventory::isValid(CPetControl *petControl) { + setPetControl(petControl); + return true; +} + +void CPetInventory::load(SimpleFile *file, int param) { + _field298 = file->readNumber(); +} + +void CPetInventory::postLoad() { + reset(); + _field290 = 1; + itemsChanged(); + _field290 = 0; +} + +void CPetInventory::save(SimpleFile *file, int indent) { + file->writeNumberLine(_field298, indent); +} + +void CPetInventory::enter(PetArea oldArea) { + _items.enter(); +} + +void CPetInventory::leave() { + _items.leave(); +} + +CGameObject *CPetInventory::getBackground(int index) const { + return (index >= 0 && index < 46) ? _itemBackgrounds[index] : nullptr; +} + +bool CPetInventory::setPetControl(CPetControl *petControl) { + if (!petControl) + return false; + + _petControl = petControl; + _items.setup(7, this); + _items.setFlags(28); + + Rect tempRect(0, 0, 52, 52); + for (uint idx = 0; idx < TOTAL_ITEMS; ++idx) { + if (!g_vm->_itemNames[idx].empty()) { + CString name = "3Pet" + g_vm->_itemNames[idx]; + _itemBackgrounds[idx] = petControl->getHiddenObject(name); + } + + if (!g_vm->_itemObjects[idx].empty()) { + _itemGlyphs[idx] = petControl->getHiddenObject(g_vm->_itemObjects[idx]); + } + } + + tempRect = Rect(0, 0, 580, 15); + tempRect.translate(32, 445); + _text.setBounds(tempRect); + _text.setHasBorder(false); + + return true; +} + +void CPetInventory::change(CGameObject *item) { + if (item) { + CInventoryGlyphAction action(item, ACTION_CHANGE); + _items.doAction(&action); + } +} + +void CPetInventory::itemRemoved(CGameObject *item) { + if (item) { + CInventoryGlyphAction action(item, ACTION_REMOVED); + _items.doAction(&action); + } +} + +void CPetInventory::itemsChanged() { + _items.clear(); + + CGameObject *item = _petControl->getFirstObject(); + while (item) { + CPetInventoryGlyph *glyph = new CPetInventoryGlyph(); + glyph->setup(_petControl, &_items); + glyph->setItem(item, _field290); + + _items.push_back(glyph); + item = _petControl->getNextObject(item); + } +} + +void CPetInventory::highlightItem(CGameObject *item) { + int itemIndex = getItemIndex(item); + _items.highlight(itemIndex); +} + +int CPetInventory::getItemIndex(CGameObject *item) const { + int index = 0; + for (CGameObject *obj = _petControl->getFirstObject(); obj && obj != item; + ++index, obj = _petControl->getNextObject(obj)) { + } + + return index; +} + +CGameObject *CPetInventory::getImage(int index) { + if (index >= 0 && index < 46) { + int bits = 0; + switch (index) { + case 20: + bits = 4; + break; + case 21: + bits = 8; + break; + case 22: + bits = 1; + break; + case 23: + bits = 2; + break; + case 36: + bits = 32; + break; + case 39: + bits = 16; + break; + default: + break; + } + + if (!(bits & _field298)) { + _field298 = bits | _field298; + return _itemGlyphs[index]; + } + } + + return nullptr; +} + +void CPetInventory::playMovie(CGameObject *movie, int flag) { + if (_movie) + _movie->stopMovie(); + _movie = movie; + + if (_movie) { + if (flag) + _movie->playMovie(0, 14, 1); + else + _movie->playMovie(0); + } +} + +void CPetInventory::removeInvalid() { + _items.removeInvalid(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_inventory.h b/engines/titanic/pet_control/pet_inventory.h new file mode 100644 index 0000000000..17649546ce --- /dev/null +++ b/engines/titanic/pet_control/pet_inventory.h @@ -0,0 +1,174 @@ +/* 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 TITANIC_PET_INVENTORY_H +#define TITANIC_PET_INVENTORY_H + +#include "titanic/support/simple_file.h" +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_inventory_glyphs.h" +#include "titanic/pet_control/pet_text.h" + +namespace Titanic { + +/** + * Handles displaying the player's inventory in the PET + */ +class CPetInventory : public CPetSection { +private: + CPetText _text; + CPetInventoryGlyphs _items; + CGameObject *_itemBackgrounds[46]; + CGameObject *_itemGlyphs[46]; + CGameObject *_movie; + bool _field290; + int _field294; + int _field298; +private: + /** + * Handles initial setup + */ + bool setPetControl(CPetControl *petControl); + + /** + * Get the index of an item added to the PET + */ + int getItemIndex(CGameObject *item) const; + + /** + * Remove any invalid inventory glyphs + */ + void removeInvalid(); +public: + CPetInventory(); + + /** + * Sets up the section + */ + virtual bool setup(CPetControl *petControl); + + /** + * Sets up the section + */ + virtual bool reset(); + + /** + * Draw the section + */ + virtual void draw(CScreenManager *screenManager); + + /** + * Get the bounds for the section + */ + virtual Rect getBounds() const; + + /** + * Called when a general change occurs + */ + virtual void changed(int changeType); + + /** + * Following are handlers for the various messages that the PET can + * pass onto the currently active section/area + */ + virtual bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + virtual bool MouseDragStartMsg(CMouseDragStartMsg *msg); + virtual bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); + virtual bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg); + virtual bool VirtualKeyCharMsg(CVirtualKeyCharMsg *msg); + + /** + * Returns item a drag-drop operation has dropped on, if any + */ + virtual CGameObject *dragEnd(const Point &pt) const; + + /** + * Returns true if the object is in a valid state + */ + virtual bool isValid(CPetControl *petControl); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file, int param); + + /** + * Called after a game has been loaded + */ + virtual void postLoad(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Called when a section is switched to + */ + virtual void enter(PetArea oldArea); + + /** + * Called when a section is being left, to switch to another area + */ + virtual void leave(); + + /** + * Get a reference to the tooltip text associated with the section + */ + virtual CPetText *getText() { return &_text; } + + /** + * Special retrieval of glyph background image + */ + virtual CGameObject *getBackground(int index) const; + + /** + * + */ + void change(CGameObject *item); + + /** + * Called when an item has been removed from the PET + */ + void itemRemoved(CGameObject *item); + + /** + * Called when the items under the PET have changed + */ + void itemsChanged(); + + /** + * Called when the inventory can't be shown after adding an item + */ + void highlightItem(CGameObject *item); + + CGameObject *getImage(int index); + + /** + * Play the animated movie for an object + */ + void playMovie(CGameObject *movie, int flag); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_INVENTORY_H */ diff --git a/engines/titanic/pet_control/pet_inventory_glyphs.cpp b/engines/titanic/pet_control/pet_inventory_glyphs.cpp new file mode 100644 index 0000000000..ae306649a2 --- /dev/null +++ b/engines/titanic/pet_control/pet_inventory_glyphs.cpp @@ -0,0 +1,342 @@ +/* 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 "titanic/pet_control/pet_inventory_glyphs.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/pet_control/pet_inventory.h" +#include "titanic/messages/pet_messages.h" +#include "titanic/titanic.h" + +namespace Titanic { + +const uint ITEM_MODES[40] = { + 0, 2, 11, 10, 12, 13, 9, 40, 7, 6, + 4, 5, 8, 15, 19, 24, 25, 26, 30, 20, + 21, 22, 23, 36, 39, 39, 31, 31, 32, 32, + 33, 34, 35, 38, 41, 42, 43, 44, 45, 37 +}; + +void CPetInventoryGlyph::enter() { + startBackgroundMovie(); +} + +void CPetInventoryGlyph::leave() { + stopMovie(); +} + +void CPetInventoryGlyph::drawAt(CScreenManager *screenManager, const Point &pt, bool isHighlighted_) { + if (!_field34) + return; + + if (_image) { + if (_image->hasActiveMovie()) { + if (isHighlighted_) + _image->draw(screenManager); + else + _image->draw(screenManager, pt); + return; + } + + _image = nullptr; + if (_background && isHighlighted_) { + _background->setPosition(pt); + startBackgroundMovie(); + } + } + + if (_background) { + if (isHighlighted_) + _background->draw(screenManager); + else + _background->draw(screenManager, pt); + } else if (_image) { + _image->draw(screenManager, pt, Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + } +} + + +void CPetInventoryGlyph::unhighlightCurrent() { + if (_image) { + _image->setPosition(Point(0, 0)); + stopMovie(); + } else if (_background) { + _background->setPosition(Point(0, 0)); + _background->loadFrame(0); + stopMovie(); + } +} + +void CPetInventoryGlyph::highlightCurrent(const Point &pt) { + reposition(pt); + if (_item) { + CPETObjectSelectedMsg selectedMsg; + selectedMsg.execute(_item); + } +} + +void CPetInventoryGlyph::glyphFocused(const Point &topLeft, bool flag) { + if (_background && flag) + _background->setPosition(topLeft); +} + +bool CPetInventoryGlyph::dragGlyph(const Point &topLeft, CMouseDragStartMsg *msg) { + if (!_item) + return false; + + if (_background) { + _field34 = 0; + stopMovie(); + } + + CPetControl *petControl = getPetControl(); + if (!petControl) + return false; + + CGameObject *carryParcel = petControl->getHiddenObject("CarryParcel"); + + if (petControl->isSuccUBusActive() && carryParcel) { + petControl->removeFromInventory(_item, carryParcel, false, true); + petControl->removeFromInventory(_item, false, false); + + carryParcel->setPosition(Point(msg->_mousePos.x - carryParcel->getBounds().width() / 2, + msg->_mousePos.y - carryParcel->getBounds().height() / 2)); + _item->setPosition(Point(SCREEN_WIDTH, SCREEN_HEIGHT)); + } else { + petControl->removeFromInventory(_item, false, true); + + _item->setPosition(Point(msg->_mousePos.x - carryParcel->getBounds().width() / 2, + msg->_mousePos.y - carryParcel->getBounds().height() / 2)); + _item->setVisible(true); + } + + msg->_handled = true; + if (msg->execute(carryParcel)) { + _item = nullptr; + _background = nullptr; + _field34 = 0; + petControl->setAreaChangeType(1); + return true; + } else { + petControl->addToInventory(carryParcel); + return false; + } +} + +void CPetInventoryGlyph::getTooltip(CPetText *text) { + if (text) { + text->setText(""); + + if (_field34 && _item) { + int itemIndex = populateItem(_item, 0); + if (itemIndex >= 14 && itemIndex <= 18) { + CPETObjectStateMsg stateMsg(0); + stateMsg.execute(_item); + + text->setText(CString::format("%s %s", + stateMsg._value ? "A hot " : "A cold ", + g_vm->_itemDescriptions[itemIndex].c_str() + )); + + } else { + text->setText(g_vm->_itemDescriptions[itemIndex]); + } + } + } +} + +bool CPetInventoryGlyph::doAction(CGlyphAction *action) { + CInventoryGlyphAction *invAction = static_cast<CInventoryGlyphAction *>(action); + CPetInventoryGlyphs *owner = static_cast<CPetInventoryGlyphs *>(_owner); + if (!invAction) + return false; + + switch (invAction->getMode()) { + case ACTION_REMOVED: + if (invAction->_item == _item) { + _item = nullptr; + _background = nullptr; + _field34 = 0; + } + break; + + case ACTION_REMOVE: + if (_item == invAction->_item && _owner) { + int v = populateItem(_item, 0); + _background = owner->getBackground(v); + + if (isHighlighted()) { + Point glyphPos = _owner->getHighlightedGlyphPos(); + reposition(glyphPos); + updateTooltip(); + } + } + break; + + default: + break; + } + + return true; +} + +void CPetInventoryGlyph::setItem(CGameObject *item, int val) { + _item = item; + + if (_owner && item) { + int v1 = populateItem(item, val); + _background = static_cast<CPetInventoryGlyphs *>(_owner)->getBackground(v1); + _image = static_cast<CPetInventory *>(getPetSection())->getImage(v1); + } +} + +int CPetInventoryGlyph::populateItem(CGameObject *item, int val) { + // Scan the master item names list + CString itemName = item->getName(); + int itemIndex = -1; + for (int idx = 0; idx < 40 && itemIndex == -1; ++idx) { + if (itemName == g_vm->_itemIds[idx]) + itemIndex = idx; + } + if (itemIndex == -1) + return -1; + + switch (ITEM_MODES[itemIndex]) { + case 0: + switch (subMode(item, val)) { + case 0: + case 1: + return 0; + case 2: + case 3: + return 1; + default: + return 0; + } + + case 2: + switch (subMode(item, val)) { + case 0: + return 2; + default: + return 3; + } + break; + + case 15: + switch (subMode(item, val)) { + case 0: + case 1: + return 14; + case 2: + return 16; + case 3: + return 15; + case 4: + return 17; + case 5: + return 18; + default: + return 15; + } + break; + + case 26: + switch (subMode(item, val)) { + case 0: + return 26; + case 1: + return 29; + case 2: + return 28; + case 3: + return 27; + default: + return 26; + } + break; + + default: + break; + } + + return ITEM_MODES[itemIndex]; +} + +int CPetInventoryGlyph::subMode(CGameObject *item, int val) { + int frameNum = item->getFrameNumber(); + int movieFrame = item->getMovieFrame(); + + if (val && frameNum != -1 && frameNum != movieFrame) + item->loadFrame(frameNum); + + return frameNum; +} + +void CPetInventoryGlyph::startBackgroundMovie() { + if (_owner) { + CPetInventory *section = static_cast<CPetInventory *>(_owner->getOwner()); + if (section) + section->playMovie(_background, 1); + } +} + +void CPetInventoryGlyph::startForegroundMovie() { + if (_owner) { + CPetInventory *section = static_cast<CPetInventory *>(_owner->getOwner()); + if (section) + section->playMovie(_image, 1); + } +} + +void CPetInventoryGlyph::stopMovie() { + if (_owner) { + CPetInventory *section = static_cast<CPetInventory *>(_owner->getOwner()); + if (section) + section->playMovie(nullptr, 1); + } +} + +void CPetInventoryGlyph::reposition(const Point &pt) { + if (_image) { + _image->setPosition(pt); + startForegroundMovie(); + } else if (_background) { + _background->setPosition(pt); + startBackgroundMovie(); + } +} + +/*------------------------------------------------------------------------*/ + +bool CPetInventoryGlyphs::doAction(CInventoryGlyphAction *action) { + for (iterator i = begin(); i != end(); ++i) { + (*i)->doAction(action); + } + + return true; +} + +CGameObject *CPetInventoryGlyphs::getBackground(int index) { + return _owner ? _owner->getBackground(index) : nullptr; +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_inventory_glyphs.h b/engines/titanic/pet_control/pet_inventory_glyphs.h new file mode 100644 index 0000000000..716c9d1ad1 --- /dev/null +++ b/engines/titanic/pet_control/pet_inventory_glyphs.h @@ -0,0 +1,153 @@ +/* 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 TITANIC_PET_INVENTORY_GLYPHS_H +#define TITANIC_PET_INVENTORY_GLYPHS_H + +#include "titanic/carry/carry.h" +#include "titanic/pet_control/pet_glyphs.h" +#include "titanic/support/screen_manager.h" + +namespace Titanic { + +class CPetInventoryGlyph : public CPetGlyph { +private: + /** + * Populate the details for an item + */ + int populateItem(CGameObject *item, int val); + + int subMode(CGameObject *item, int val); + + /** + * Start any movie for the background + */ + void startBackgroundMovie(); + + /** + * Start any movie for the foreground item + */ + void startForegroundMovie(); + + /** + * Stop any previously started foreground or background movie + */ + void stopMovie(); + + /** + * Reposition the inventory item + */ + void reposition(const Point &pt); +public: + CGameObject *_item; + int _field34; + CGameObject *_background; + CGameObject *_image; +public: + CPetInventoryGlyph() : _item(nullptr), _field34(1), + _background(nullptr), _image(nullptr) {} + CPetInventoryGlyph(CCarry *item, int val) : _item(item), + _field34(val), _background(nullptr), _image(nullptr) {} + + /** + * Called when the PET area is entered + */ + virtual void enter(); + + /** + * Called when the PET area is left + */ + virtual void leave(); + + /** + * Draw the glyph at a specified position + */ + virtual void drawAt(CScreenManager *screenManager, const Point &pt, bool isHighlighted); + + /** + * Unhighlight any currently highlighted element + */ + virtual void unhighlightCurrent(); + + /** + * Highlight any currently highlighted element + */ + virtual void highlightCurrent(const Point &pt); + + /** + * Glyph has been shifted to be first visible one + */ + virtual void glyphFocused(const Point &topLeft, bool flag); + + /** + * Called when a glyph drag starts + */ + virtual bool dragGlyph(const Point &topLeft, CMouseDragStartMsg *msg); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); + + /** + * Return whether the glyph is currently valid + */ + virtual bool isValid() const { return _item && _background; } + + /** + * Returns the object associated with the glyph + */ + virtual CGameObject *getObjectAt() { return _item; } + + /** + * Does a processing action on the glyph + */ + virtual bool doAction(CGlyphAction *action); + + /** + * Set the inventory item + */ + void setItem(CGameObject *item, int val); +}; + +class CInventoryGlyphAction : public CGlyphAction { +public: + CGameObject *_item; +public: + CInventoryGlyphAction(CGameObject *item, GlyphActionMode mode) : + CGlyphAction(mode), _item(item) {} +}; + +class CPetInventoryGlyphs : public CPetGlyphs { + friend class CPetInventoryGlyph; +private: + CGameObject *getBackground(int index); +public: + /** + * Do an action on the glyphs + */ + bool doAction(CInventoryGlyphAction *item); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_INVENTORY_GLYPHS_H */ diff --git a/engines/titanic/pet_control/pet_leaf.cpp b/engines/titanic/pet_control/pet_leaf.cpp new file mode 100644 index 0000000000..718ffe5e6e --- /dev/null +++ b/engines/titanic/pet_control/pet_leaf.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/pet_control/pet_leaf.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(PETLeaf, CGameObject); + +void PETLeaf::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void PETLeaf::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_leaf.h b/engines/titanic/pet_control/pet_leaf.h new file mode 100644 index 0000000000..0c21352e39 --- /dev/null +++ b/engines/titanic/pet_control/pet_leaf.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_PET_LEAF_H +#define TITANIC_PET_LEAF_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class PETLeaf : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_LEAF_H */ diff --git a/engines/titanic/pet_control/pet_load.cpp b/engines/titanic/pet_control/pet_load.cpp new file mode 100644 index 0000000000..04eec54f25 --- /dev/null +++ b/engines/titanic/pet_control/pet_load.cpp @@ -0,0 +1,70 @@ +/* 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 "titanic/pet_control/pet_load.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/core/project_item.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +bool CPetLoad::reset() { + CPetLoadSave::reset(); + + CPetControl *pet = getPetControl(); + if (pet) { + setName("PetLoad", pet); + _btnLoadSave.reset("PetLoadOut", pet, MODE_UNSELECTED); + _btnLoadSave.reset("PetLoadIn", pet, MODE_SELECTED); + } + + return true; +} + +bool CPetLoad::MouseButtonUpMsg(const Point &pt) { + if (_btnLoadSave.MouseButtonUpMsg(pt)) { + execute(); + return true; + } else { + return false; + } +} + +void CPetLoad::getTooltip(CPetText *text) { + text->setText("Load the game."); +} + +void CPetLoad::execute() { + CPetControl *pet = getPetControl(); + + if (_savegameSlotNum >= 0 && _slotInUse[_savegameSlotNum]) { + CMainGameWindow *window = g_vm->_window; + + // WORKAROUND: Schedule the savegame to be loaded after frame rendering ends + window->loadGame(_savegameSlotNum); + } else if (pet) { + pet->displayMessage("You must select a game to load first."); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_load.h b/engines/titanic/pet_control/pet_load.h new file mode 100644 index 0000000000..421531974d --- /dev/null +++ b/engines/titanic/pet_control/pet_load.h @@ -0,0 +1,70 @@ +/* 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 TITANIC_PET_LOAD_H +#define TITANIC_PET_LOAD_H + +#include "titanic/pet_control/pet_load_save.h" + +namespace Titanic { + +class CPetLoad : public CPetLoadSave { +public: + /** + * Reset the glyph + */ + virtual bool reset(); + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Highlight any currently highlighted element + */ + virtual void highlightCurrent(const Point &pt) { resetSlots(); } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); + + /** + * Highlights a save slot + */ + virtual void highlightSave(int index) {} + + /** + * Unhighlight a save slot + */ + virtual void unhighlightSave(int index) {} + + /** + * Executes the loading or saving + */ + virtual void execute(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_LOAD_H */ diff --git a/engines/titanic/pet_control/pet_load_save.cpp b/engines/titanic/pet_control/pet_load_save.cpp new file mode 100644 index 0000000000..aebe43551e --- /dev/null +++ b/engines/titanic/pet_control/pet_load_save.cpp @@ -0,0 +1,191 @@ +/* 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 "titanic/pet_control/pet_load_save.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/core/project_item.h" +#include "titanic/titanic.h" + +namespace Titanic { + +int CPetLoadSave::_savegameSlotNum; + +bool CPetLoadSave::setup(CPetControl *petControl, CPetGlyphs *owner) { + CPetGlyph::setup(petControl, owner); + _savegameSlotNum = -1; + + for (int idx = 0; idx < SAVEGAME_SLOTS_COUNT; ++idx) { + Rect slotRect = getSlotBounds(idx); + _slotNames[idx].setBounds(slotRect); + _slotNames[idx].resize(3); + _slotNames[idx].setMaxCharsPerLine(22); + _slotNames[idx].setHasBorder(false); + _slotNames[idx].setup(); + } + + Rect r1(0, 0, 68, 52); + r1.moveTo(496, 388); + _btnLoadSave.setBounds(r1); + + Rect r2(0, 0, 168, 78); + r2.moveTo(309, 377); + _gutter.setBounds(r2); + return true; +} + +bool CPetLoadSave::reset() { + highlightChange(); + resetSlots(); + + CPetControl *pet = getPetControl(); + if (pet) { + _gutter.reset("PetSaveGutter", pet, MODE_UNSELECTED); + } + + return true; +} + +void CPetLoadSave::draw2(CScreenManager *screenManager) { + _gutter.draw(screenManager); + + for (int idx = 0; idx < SAVEGAME_SLOTS_COUNT; ++idx) + _slotNames[idx].draw(screenManager); + + _btnLoadSave.draw(screenManager); +} + +bool CPetLoadSave::MouseButtonDownMsg(const Point &pt) { + if (_btnLoadSave.MouseButtonDownMsg(pt)) + return true; + + checkSlotsHighlight(pt); + return false; +} + +bool CPetLoadSave::KeyCharMsg(int key) { + switch (key) { + case Common::KEYCODE_TAB: + case Common::KEYCODE_DOWN: + case Common::KEYCODE_KP2: + if (_savegameSlotNum != -1) { + highlightSlot((_savegameSlotNum + 1) % 5); + getPetControl()->makeDirty(); + } + return true; + + case Common::KEYCODE_UP: + case Common::KEYCODE_KP8: + if (_savegameSlotNum != -1) { + int slotNum = --_savegameSlotNum; + highlightSlot((slotNum == -1) ? SAVEGAME_SLOTS_COUNT - 1 : slotNum); + getPetControl()->makeDirty(); + } + return true; + + case Common::KEYCODE_RETURN: + case Common::KEYCODE_KP_ENTER: + execute(); + return true; + + default: + return false; + } +} + +Rect CPetLoadSave::getSlotBounds(int index) { + return Rect(323, 376 + index * 16, 473, 392 + index * 16); +} + +void CPetLoadSave::resetSlots() { + for (int idx = 0; idx < SAVEGAME_SLOTS_COUNT; ++idx) { + _slotNames[idx].setText("Empty"); + _slotInUse[idx] = false; + + // Try and open up the savegame for access + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading( + g_vm->generateSaveName(idx)); + + if (in) { + // Read in the savegame header data + CompressedFile file; + file.open(in); + + TitanicSavegameHeader header; + if (CProjectItem::readSavegameHeader(&file, header)) { + _slotInUse[idx] = true; + _slotNames[idx].setText(header._saveName); + } + + if (header._thumbnail) { + header._thumbnail->free(); + delete header._thumbnail; + } + + file.close(); + } + } + + highlightSlot(_savegameSlotNum); +} + +void CPetLoadSave::highlightSlot(int index) { + unhighlightSave(_savegameSlotNum); + _savegameSlotNum = index; + highlightChange(); + highlightSave(_savegameSlotNum); +} + +void CPetLoadSave::highlightChange() { + CPetSection *section = getPetSection(); + + uint col = section ? section->getColor(3) : 0; + for (int idx = 0; idx < SAVEGAME_SLOTS_COUNT; ++idx) + _slotNames[idx].setColor(col); + + if (_savegameSlotNum != -1) { + col = section ? section->getColor(4) : 0; + _slotNames[_savegameSlotNum].setLineColor(0, col); + } +} + +bool CPetLoadSave::checkSlotsHighlight(const Point &pt) { + for (int idx = 0; idx < SAVEGAME_SLOTS_COUNT; ++idx) { + if (isSlotHighlighted(idx, pt)) { + highlightSlot(idx); + return true; + } + } + + return false; +} + +bool CPetLoadSave::isSlotHighlighted(int index, const Point &pt) { + Rect r = getSlotBounds(index); + if (r.contains(pt)) { + highlightSlot(index); + return true; + } else { + return false; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_load_save.h b/engines/titanic/pet_control/pet_load_save.h new file mode 100644 index 0000000000..dd1c907ef1 --- /dev/null +++ b/engines/titanic/pet_control/pet_load_save.h @@ -0,0 +1,119 @@ +/* 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 TITANIC_PET_LOAD_SAVE_H +#define TITANIC_PET_LOAD_SAVE_H + +#include "titanic/pet_control/pet_glyphs.h" +#include "titanic/pet_control/pet_text.h" + +namespace Titanic { + +#define SAVEGAME_SLOTS_COUNT 5 + +class CPetLoadSave : public CPetGlyph { +private: + /** + * Get the rect area for a given savegame name will be displayed in + */ + Rect getSlotBounds(int index); + + /** + * Highlight one of the slots + */ + void highlightSlot(int index); + + /** + * Called when savegame slot highlight changes or the view is reset + */ + void highlightChange(); + + /** + * Check for whether a slot is under the passed point + */ + bool checkSlotsHighlight(const Point &pt); + + /** + * Checks if a point is within a given saveame slot + */ + bool isSlotHighlighted(int index, const Point &pt); +protected: + CPetText _slotNames[SAVEGAME_SLOTS_COUNT]; + bool _slotInUse[SAVEGAME_SLOTS_COUNT]; + CPetGfxElement _btnLoadSave; + CPetGfxElement _gutter; + static int _savegameSlotNum; +protected: + /** + * Reset the slot names list + */ + void resetSlots(); +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Reset the glyph + */ + virtual bool reset(); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt); + + /** + * Handles keypresses when the glyph is focused + */ + virtual bool KeyCharMsg(int key); + + /** + * Resets highlighting on the save slots + */ + virtual void resetSaves() { resetSlots(); } + + /** + * Highlights a save slot + */ + virtual void highlightSave(int index) = 0; + + /** + * Unhighlight a save slot + */ + virtual void unhighlightSave(int index) = 0; + + /** + * Executes the loading or saving + */ + virtual void execute() = 0; +}; + +} // End of namespace Titanic + +#endif diff --git a/engines/titanic/pet_control/pet_message.cpp b/engines/titanic/pet_control/pet_message.cpp new file mode 100644 index 0000000000..783c9019e2 --- /dev/null +++ b/engines/titanic/pet_control/pet_message.cpp @@ -0,0 +1,57 @@ +/* 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 "titanic/pet_control/pet_message.h" + +namespace Titanic { + +CPetMessage::CPetMessage() { + Rect rect1(0, 0, 580, 70); + rect1.translate(32, 368); + _message.setBounds(rect1); + _message.resize(50); + _message.setHasBorder(false); + + Rect rect2(0, 0, 580, 15); + rect2.translate(32, 445); + _tooltip.setBounds(rect2); + _tooltip.setHasBorder(false); +} + +bool CPetMessage::setup(CPetControl *petControl) { + if (petControl && setupControl(petControl)) + return reset(); + return false; +} + +void CPetMessage::draw(CScreenManager *screenManager) { + _message.draw(screenManager); + _tooltip.draw(screenManager); +} + +bool CPetMessage::setupControl(CPetControl *petControl) { + if (petControl) + _petControl = petControl; + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_message.h b/engines/titanic/pet_control/pet_message.h new file mode 100644 index 0000000000..499f274c54 --- /dev/null +++ b/engines/titanic/pet_control/pet_message.h @@ -0,0 +1,96 @@ +/* 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 TITANIC_PET_MESSAGE_H +#define TITANIC_PET_MESSAGE_H + +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_text.h" + +namespace Titanic { + +class CPetMessage : public CPetSection { +private: + CPetText _message; + CPetText _tooltip; +private: + /** + * Setup the control + */ + bool setupControl(CPetControl *petControl); +public: + CPetMessage(); + + /** + * Sets up the section + */ + virtual bool setup(CPetControl *petControl); + + /** + * Reset the section + */ + virtual bool reset() { return true; } + + /** + * Draw the section + */ + virtual void draw(CScreenManager *screenManager); + + /** + * Following are handlers for the various messages that the PET can + * pass onto the currently active section/area + */ + virtual bool MouseButtonDownMsg(CMouseButtonDownMsg *msg) { return false; } + virtual bool MouseButtonUpMsg(CMouseButtonUpMsg *msg) { return false; } + + /** + * Returns true if the object is in a valid state + */ + virtual bool isValid(CPetControl *petControl) { + return setupControl(petControl); + } + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file, int param) {} + + /** + * Called after a game has been loaded + */ + virtual void postLoad() { reset(); } + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) {} + + /** + * Get a reference to the tooltip text associated with the section + */ + virtual CPetText *getText() { return &_tooltip; } + +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_MESSAGE_H */ diff --git a/engines/titanic/pet_control/pet_mode_off.cpp b/engines/titanic/pet_control/pet_mode_off.cpp new file mode 100644 index 0000000000..119c15a65c --- /dev/null +++ b/engines/titanic/pet_control/pet_mode_off.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/pet_control/pet_mode_off.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CPetModeOff, CToggleSwitch); + +CPetModeOff::CPetModeOff() : CToggleSwitch() { +} + +void CPetModeOff::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CPetModeOff::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_mode_off.h b/engines/titanic/pet_control/pet_mode_off.h new file mode 100644 index 0000000000..9162270953 --- /dev/null +++ b/engines/titanic/pet_control/pet_mode_off.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_PET_MODE_OFF_H +#define TITANIC_PET_MODE_OFF_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CPetModeOff : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CPetModeOff(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_MODE_OFF_H */ diff --git a/engines/titanic/pet_control/pet_mode_on.cpp b/engines/titanic/pet_control/pet_mode_on.cpp new file mode 100644 index 0000000000..2b61461a24 --- /dev/null +++ b/engines/titanic/pet_control/pet_mode_on.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/pet_control/pet_mode_on.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CPetModeOn, CToggleSwitch); + +CPetModeOn::CPetModeOn() : CToggleSwitch() { +} + +void CPetModeOn::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CPetModeOn::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_mode_on.h b/engines/titanic/pet_control/pet_mode_on.h new file mode 100644 index 0000000000..f77fd1f447 --- /dev/null +++ b/engines/titanic/pet_control/pet_mode_on.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_PET_MODE_ON_H +#define TITANIC_PET_MODE_ON_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CPetModeOn : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CPetModeOn(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_MODE_ON_H */ diff --git a/engines/titanic/pet_control/pet_mode_panel.cpp b/engines/titanic/pet_control/pet_mode_panel.cpp new file mode 100644 index 0000000000..8579c31cea --- /dev/null +++ b/engines/titanic/pet_control/pet_mode_panel.cpp @@ -0,0 +1,42 @@ +/* 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 "titanic/pet_control/pet_mode_panel.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CPetModePanel, CToggleSwitch); + +CPetModePanel::CPetModePanel() : CToggleSwitch() { +} + +void CPetModePanel::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CToggleSwitch::save(file, indent); +} + +void CPetModePanel::load(SimpleFile *file) { + file->readNumber(); + CToggleSwitch::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_mode_panel.h b/engines/titanic/pet_control/pet_mode_panel.h new file mode 100644 index 0000000000..f37c543b98 --- /dev/null +++ b/engines/titanic/pet_control/pet_mode_panel.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_PET_MODE_PANEL_H +#define TITANIC_PET_MODE_PANEL_H + +#include "titanic/gfx/toggle_switch.h" + +namespace Titanic { + +class CPetModePanel : public CToggleSwitch { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CPetModePanel(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_MODE_PANEL_H */ diff --git a/engines/titanic/pet_control/pet_pannel1.cpp b/engines/titanic/pet_control/pet_pannel1.cpp new file mode 100644 index 0000000000..7a757bfe57 --- /dev/null +++ b/engines/titanic/pet_control/pet_pannel1.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/pet_control/pet_pannel1.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CPetPannel1, CPetGraphic); + +void CPetPannel1::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic::save(file, indent); +} + +void CPetPannel1::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_pannel1.h b/engines/titanic/pet_control/pet_pannel1.h new file mode 100644 index 0000000000..f39314fed9 --- /dev/null +++ b/engines/titanic/pet_control/pet_pannel1.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_PET_PANNEL1_H +#define TITANIC_PET_PANNEL1_H + +#include "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +class CPetPannel1 : public CPetGraphic { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_PANNEL1_H */ diff --git a/engines/titanic/pet_control/pet_pannel2.cpp b/engines/titanic/pet_control/pet_pannel2.cpp new file mode 100644 index 0000000000..096a39afbf --- /dev/null +++ b/engines/titanic/pet_control/pet_pannel2.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/pet_control/pet_pannel2.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CPetPannel2, CPetGraphic); + +void CPetPannel2::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic::save(file, indent); +} + +void CPetPannel2::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_pannel2.h b/engines/titanic/pet_control/pet_pannel2.h new file mode 100644 index 0000000000..f820847035 --- /dev/null +++ b/engines/titanic/pet_control/pet_pannel2.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_PET_PANNEL2_H +#define TITANIC_PET_PANNEL2_H + +#include "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +class CPetPannel2 : public CPetGraphic { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_PANNEL2_H */ diff --git a/engines/titanic/pet_control/pet_pannel3.cpp b/engines/titanic/pet_control/pet_pannel3.cpp new file mode 100644 index 0000000000..0d095a62c5 --- /dev/null +++ b/engines/titanic/pet_control/pet_pannel3.cpp @@ -0,0 +1,39 @@ +/* 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 "titanic/pet_control/pet_pannel3.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CPetPannel3, CPetGraphic); + +void CPetPannel3::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CPetGraphic::save(file, indent); +} + +void CPetPannel3::load(SimpleFile *file) { + file->readNumber(); + CPetGraphic::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_pannel3.h b/engines/titanic/pet_control/pet_pannel3.h new file mode 100644 index 0000000000..dd0d2f9fa2 --- /dev/null +++ b/engines/titanic/pet_control/pet_pannel3.h @@ -0,0 +1,48 @@ +/* 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 TITANIC_PET_PANNEL3_H +#define TITANIC_PET_PANNEL3_H + +#include "titanic/pet_control/pet_graphic.h" + +namespace Titanic { + +class CPetPannel3 : public CPetGraphic { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_PANNEL3_H */ diff --git a/engines/titanic/pet_control/pet_quit.cpp b/engines/titanic/pet_control/pet_quit.cpp new file mode 100644 index 0000000000..218ed89812 --- /dev/null +++ b/engines/titanic/pet_control/pet_quit.cpp @@ -0,0 +1,90 @@ +/* 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 "titanic/pet_control/pet_quit.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/pet_control/pet_real_life.h" +#include "titanic/support/rect.h" +#include "titanic/game_manager.h" + +namespace Titanic { + +bool CPetQuit::setup(CPetControl *petControl, CPetGlyphs *owner) { + CPetGlyph::setup(petControl, owner); + + Rect tempRect(0, 0, 280, 16); + tempRect.moveTo(322, 407); + _text.setBounds(tempRect); + _text.resize(3); + _text.setHasBorder(false); + _text.setup(); + + Rect btnRect(0, 0, 68, 52); + btnRect.moveTo(496, 388); + _btnYes.setBounds(btnRect); + + return true; +} + +bool CPetQuit::reset() { + CPetControl *pet = getPetControl(); + if (!pet) + return false; + + setName("PetExit", pet); + + uint col = getPetSection()->getColor(0); + _text.setText("Are you sure you want to quit?"); + _text.setLineColor(0, col); + + _btnYes.reset("PetQuitOut", pet, MODE_UNSELECTED); + _btnYes.reset("PetQuitIn", pet, MODE_SELECTED); + + return true; +} + +void CPetQuit::draw2(CScreenManager *screenManager) { + _text.draw(screenManager); + _btnYes.draw(screenManager); +} + +bool CPetQuit::MouseButtonDownMsg(const Point &pt) { + return !_btnYes.MouseButtonDownMsg(pt); +} + +bool CPetQuit::MouseButtonUpMsg(const Point &pt) { + CPetControl *pet = getPetControl(); + if (_btnYes.MouseButtonUpMsg(pt) && pet) { + CGameManager *gameManager = pet->getGameManager(); + if (gameManager) + gameManager->_gameState._quitGame = true; + return true; + } else { + return false; + } +} + +void CPetQuit::getTooltip(CPetText *text) { + text->setText("Quit the game."); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_quit.h b/engines/titanic/pet_control/pet_quit.h new file mode 100644 index 0000000000..87d8aefbbf --- /dev/null +++ b/engines/titanic/pet_control/pet_quit.h @@ -0,0 +1,75 @@ +/* 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 TITANIC_PET_QUIT_H +#define TITANIC_PET_QUIT_H + +#include "titanic/pet_control/pet_gfx_element.h" +#include "titanic/pet_control/pet_glyphs.h" +#include "titanic/pet_control/pet_text.h" + +namespace Titanic { + +class CPetQuit : public CPetGlyph { +private: + CPetText _text; + CPetGfxElement _btnYes; +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Reset the glyph + */ + virtual bool reset(); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt); + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); + + /** + * Get a reference to the tooltip text associated with the section + */ + virtual CPetText *getText() { return &_text; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_QUIT_H */ diff --git a/engines/titanic/pet_control/pet_real_life.cpp b/engines/titanic/pet_control/pet_real_life.cpp new file mode 100644 index 0000000000..b9e1990dd2 --- /dev/null +++ b/engines/titanic/pet_control/pet_real_life.cpp @@ -0,0 +1,129 @@ +/* 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 "titanic/pet_control/pet_real_life.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/pet_control/pet_load.h" +#include "titanic/pet_control/pet_save.h" +#include "titanic/pet_control/pet_sound.h" +#include "titanic/pet_control/pet_quit.h" + +namespace Titanic { + +bool CPetRealLife::setup(CPetControl *petControl) { + if (petControl && setupControl(petControl)) + return reset(); + return false; +} + +bool CPetRealLife::reset() { + _glyphs.reset(); + uint col = getColor(0); + _text.setColor(col); + _text.setLineColor(0, col); + + return true; +} + +void CPetRealLife::draw(CScreenManager *screenManager) { + _petControl->drawSquares(screenManager, 4); + _glyphs.draw(screenManager); + _text.draw(screenManager); +} + +bool CPetRealLife::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + return _glyphs.MouseButtonDownMsg(msg->_mousePos); +} + +bool CPetRealLife::MouseDragStartMsg(CMouseDragStartMsg *msg) { + return _glyphs.MouseDragStartMsg(msg); +} + +bool CPetRealLife::MouseDragMoveMsg(CMouseDragMoveMsg *msg) { + return _glyphs.MouseDragMoveMsg(msg); +} + +bool CPetRealLife::MouseDragEndMsg(CMouseDragEndMsg *msg) { + return _glyphs.MouseDragEndMsg(msg); +} + +bool CPetRealLife::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + return _glyphs.MouseButtonUpMsg(msg->_mousePos); +} + +bool CPetRealLife::KeyCharMsg(CKeyCharMsg *msg) { + _glyphs.KeyCharMsg(msg->_key); + return true; +} + +bool CPetRealLife::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { + return _glyphs.VirtualKeyCharMsg(msg); +} + +void CPetRealLife::postLoad() { + reset(); +} + +bool CPetRealLife::isValid(CPetControl *petControl) { + setupControl(petControl); + return true; +} + +void CPetRealLife::enter(PetArea oldArea) { + _glyphs.enterHighlighted(); +} + +void CPetRealLife::leave() { + _glyphs.leaveHighlighted(); +} + +bool CPetRealLife::setupControl(CPetControl *petControl) { + if (petControl) { + _petControl = petControl; + _glyphs.setup(4, this); + _glyphs.setFlags(6); + + addButton(new CPetLoad()); + addButton(new CPetSave()); + addButton(new CPetSound()); + addButton(new CPetQuit()); + + Rect textRect(0, 0, 276, 30); + textRect.moveTo(32, 436); + _text.setBounds(textRect); + _text.setHasBorder(false); + _text.setup(); + } + + return true; +} + +void CPetRealLife::addButton(CPetGlyph *glyph) { + if (glyph) { + if (glyph->setup(_petControl, &_glyphs)) + _glyphs.push_back(glyph); + } +} + + + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_real_life.h b/engines/titanic/pet_control/pet_real_life.h new file mode 100644 index 0000000000..40bc87d9b5 --- /dev/null +++ b/engines/titanic/pet_control/pet_real_life.h @@ -0,0 +1,138 @@ +/* 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 TITANIC_PET_REAL_LIFE_H +#define TITANIC_PET_REAL_LIFE_H + +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_glyphs.h" +#include "titanic/pet_control/pet_text.h" + +namespace Titanic { + +class CPetSaveGlyphs : public CPetGlyphs { +}; + +class CPetRealLife : public CPetSection { +private: + CPetGlyphs _glyphs; + CPetText _text; +private: + /** + * Does setup + */ + bool setupControl(CPetControl *petControl); + + /** + * Adds one of the four button glyphs for display + */ + void addButton(CPetGlyph *glyph); +public: + virtual ~CPetRealLife() {} + + /** + * Sets up the section + */ + virtual bool setup(CPetControl *petControl); + + /** + * Reset the section + */ + virtual bool reset(); + + /** + * Draw the section + */ + virtual void draw(CScreenManager *screenManager); + + /** + * Get the bounds for the section + */ + virtual Rect getBounds() const { return Rect(); } + + /** + * Following are handlers for the various messages that the PET can + * pass onto the currently active section/area + */ + virtual bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + virtual bool MouseDragStartMsg(CMouseDragStartMsg *msg); + virtual bool MouseDragMoveMsg(CMouseDragMoveMsg *msg); + virtual bool MouseDragEndMsg(CMouseDragEndMsg *msg); + virtual bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); + virtual bool KeyCharMsg(CKeyCharMsg *msg); + virtual bool VirtualKeyCharMsg(CVirtualKeyCharMsg *msg); + + /** + * Returns item a drag-drop operation has dropped on, if any + */ + virtual CGameObject *dragEnd(const Point &pt) const { return nullptr; } + + /** + * Display a message + */ + virtual void displayMessage(const CString &msg) {} + + /** + * Returns true if the object is in a valid state + */ + virtual bool isValid(CPetControl *petControl); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file, int param) {} + + /** + * Called after a game has been loaded + */ + virtual void postLoad(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) {} + + /** + * Called when a section is switched to + */ + virtual void enter(PetArea oldArea); + + /** + * Called when a section is being left, to switch to another area + */ + virtual void leave(); + + /** + * Called when a new room is entered + */ + virtual void enterRoom(CRoomItem *room) {} + + /** + * Get a reference to the tooltip text associated with the section + */ + virtual CPetText *getText() { return &_text; } + +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_REAL_LIFE_H */ diff --git a/engines/titanic/pet_control/pet_remote.cpp b/engines/titanic/pet_control/pet_remote.cpp new file mode 100644 index 0000000000..9b43b8dab9 --- /dev/null +++ b/engines/titanic/pet_control/pet_remote.cpp @@ -0,0 +1,495 @@ +/* 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 "titanic/pet_control/pet_remote.h" +#include "titanic/pet_control/pet_remote_glyphs.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/messages/pet_messages.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +static const byte REMOTE_DATA[] = { + 0x00, 0x02, + GLYPH_SUMMON_ELEVATOR, GLYPH_SUCCUBUS_DELIVERY, + 0x01, 0x02, + GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, + 0x02, 0x03, + GLYPH_TELEVISION_CONTROL, GLYPH_OPERATE_LIGHTS, GLYPH_SUCCUBUS_DELIVERY, + 0x03, 0x02, + GLYPH_SUMMON_ELEVATOR, GLYPH_SUCCUBUS_DELIVERY, + 0x04, 0x02, + GLYPH_TELEVISION_CONTROL, GLYPH_SUCCUBUS_DELIVERY, + 0x05, 0x02, + GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, + 0x06, 0x02, + GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, + 0x07, 0x03, + GLYPH_TELEVISION_CONTROL, GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, + 0x08, 0x01, + GLYPH_SUCCUBUS_DELIVERY, + 0x09, 0x01, + GLYPH_SUCCUBUS_DELIVERY, + 0x0A, 0x02, GLYPH_SUMMON_ELEVATOR, GLYPH_SUCCUBUS_DELIVERY, + 0x0B, 0x01, + GLYPH_NAVIGATION_CONTROLLER, + 0x0C, 0x01, + GLYPH_SUCCUBUS_DELIVERY, + 0x0D, 0x01, + GLYPH_SUCCUBUS_DELIVERY, + 0x0E, 0x00, + 0x0F, 0x01, + GLYPH_TELEVISION_CONTROL, + 0x10, 0x03, + GLYPH_GOTO_BOTTOM_OF_WELL, GLYPH_GOTO_STATEROOM, GLYPH_GOTO_TOP_OF_WELL, + 0x11, 0x01, + GLYPH_SUCCUBUS_DELIVERY, + 0x12, 0x00, + 0x13, 0x02, + GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, + 0x14, 0x00, + 0x15, 0x02, + GLYPH_SUCCUBUS_DELIVERY, GLYPH_TELEVISION_CONTROL, + 0x16, 0x00, + 0x17, 0x02, + GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, + 0x18, 0x01, + GLYPH_SUCCUBUS_DELIVERY, + 0x19, 0x00, + 0x1A, 0x00, + 0x1B, 0x00, + 0x1C, 0x00, + 0x1D, 0x02, + GLYPH_SUMMON_ELEVATOR, GLYPH_SUCCUBUS_DELIVERY, + 0x1E, 0x0C, + GLYPH_DEPLOY_FLORAL, GLYPH_DEPLOY_FULLY_RELAXATION, GLYPH_DEPLOY_COMFORT, + GLYPH_DEPLOY_MINOR_STORAGE, GLYPH_ENTERTAINMENT_DEVICE, + GLYPH_DEPLOY_MAJOR_RELAXATION, GLYPH_INFLATE_RELAXATION, + GLYPH_DEPLOY_MAINTENANCE, GLYPH_DEPLOY_WORK_SURFACE, + GLYPH_DEPLOY_MINOR_RELAXATION, GLYPH_DEPLOY_SINK, + GLYPH_DEPLOY_MAJOR_STORAGE, + 0x1F, 0x01, + GLYPH_SUCCUBUS_DELIVERY, + 0x20, 0x02, + GLYPH_SUMMON_ELEVATOR, GLYPH_SUMMON_PELLERATOR, + 0x21, 0x00 +}; + +CPetRemote::CPetRemote() : CPetSection() { +} + +bool CPetRemote::setup(CPetControl *petControl) { + if (petControl && setupControl(petControl)) + return reset(); + return false; +} + +bool CPetRemote::reset() { + if (_petControl) { + _onOff.reset("PetSwitchOn", _petControl, MODE_SELECTED); + _onOff.reset("PetSwitchOff", _petControl, MODE_UNSELECTED); + + _up.reset("PetUp", _petControl, MODE_UNSELECTED); + _down.reset("PetDown", _petControl, MODE_UNSELECTED); + + _left.reset("PetLeftUp", _petControl, MODE_SELECTED); + _left.reset("PetLeft", _petControl, MODE_UNSELECTED); + _right.reset("PetRightUp", _petControl, MODE_SELECTED); + _right.reset("PetRight", _petControl, MODE_UNSELECTED); + _top.reset("PetTopUp", _petControl, MODE_SELECTED); + _top.reset("PetTop", _petControl, MODE_UNSELECTED); + _bottom.reset("PetBottomUp", _petControl, MODE_SELECTED); + _bottom.reset("PetBottom", _petControl, MODE_UNSELECTED); + _action.reset("PetActionUp", _petControl, MODE_SELECTED); + _action.reset("PetAction", _petControl, MODE_UNSELECTED); + + _send.reset("PetActSend0", _petControl, MODE_UNSELECTED); + _send.reset("PetActSend1", _petControl, MODE_SELECTED); + _receive.reset("PetActReceive0", _petControl, MODE_UNSELECTED); + _receive.reset("PetActReceive1", _petControl, MODE_SELECTED); + _call.reset("PetActCall0", _petControl, MODE_UNSELECTED); + _call.reset("PetActCall1", _petControl, MODE_SELECTED); + + _items.reset(); + uint col = getColor(0); + _text.setColor(col); + _text.setLineColor(0, col); + } + + return true; +} + +void CPetRemote::draw(CScreenManager *screenManager) { + _petControl->drawSquares(screenManager, 6); + _items.draw(screenManager); + _text.draw(screenManager); +} + +bool CPetRemote::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + return _items.MouseButtonDownMsg(msg->_mousePos); +} + +bool CPetRemote::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + return _items.MouseButtonUpMsg(msg->_mousePos); +} + +bool CPetRemote::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { + return _items.MouseButtonDownMsg(msg->_mousePos); +} + +bool CPetRemote::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { + return _items.VirtualKeyCharMsg(msg); +} + +bool CPetRemote::isValid(CPetControl *petControl) { + return setupControl(petControl); +} + +void CPetRemote::postLoad() { + reset(); + CRoomItem *room = getRoom(); + if (room) + enterRoom(room); +} + +void CPetRemote::enter(PetArea oldArea) { + if (_items.highlighted14()) + _text.setText(CString()); +} + +void CPetRemote::enterRoom(CRoomItem *room) { + clearGlyphs(); + + if (room) { + CString roomName = room->getName(); + int roomIndex = roomIndexOf(roomName); + if (roomIndex != -1) { + Common::Array<uint> indexes; + if (getRemoteData(roomIndex, indexes)) { + loadGlyphs(indexes); + _items.scrollToStart(); + } + } + } +} + +CPetText *CPetRemote::getText() { + return &_text; +} + +CPetGfxElement *CPetRemote::getElement(uint id) { + switch (id) { + case 0: + return &_onOff; + case 1: + return &_up; + case 2: + return &_down; + case 3: + return &_left; + case 4: + return &_right; + case 5: + return &_top; + case 6: + return &_bottom; + case 7: + return &_action; + case 16: + return &_send; + case 17: + return &_receive; + case 18: + return &_call; + default: + return nullptr; + } +} + +void CPetRemote::highlight(int id) { + int highlightIndex = getHighlightIndex((RemoteGlyph)id); + if (highlightIndex != -1) + _items.highlight(highlightIndex); +} + +bool CPetRemote::setupControl(CPetControl *petControl) { + _petControl = petControl; + if (!petControl) + return false; + + _onOff.setBounds(Rect(0, 0, 15, 43)); + _onOff.translate(519, 381); + _up.setBounds(Rect(0, 0, 21, 24)); + _up.translate(551, 381); + _down.setBounds(Rect(0, 0, 21, 24)); + _down.translate(551, 402); + _left.setBounds(Rect(0, 0, 22, 21)); + _left.translate(518, 393); + _right.setBounds(Rect(0, 0, 21, 21)); + _right.translate(560, 393); + _top.setBounds(Rect(0, 0, 21, 22)); + _top.translate(539, 371); + _bottom.setBounds(Rect(0, 0, 21, 22)); + _bottom.translate(539, 414); + _action.setBounds(Rect(0, 0, 21, 21)); + _action.translate(539, 393); + _send.setBounds(Rect(0, 0, 62, 38)); + _send.translate(503, 373); + _receive.setBounds(Rect(0, 0, 62, 38)); + _receive.translate(503, 420); + _call.setBounds(Rect(0, 0, 62, 38)); + _call.translate(503, 383); + + Rect rect(0, 0, 580, 15); + rect.moveTo(32, 445); + _text.setBounds(rect); + _text.setHasBorder(false); + + _items.setup(6, this); + _items.setFlags(19); + return true; +} + +CRoomItem *CPetRemote::getRoom() const { + if (_petControl) { + CGameManager *gameManager = _petControl->getGameManager(); + if (gameManager) + return gameManager->getRoom(); + } + + return nullptr; +} + +int CPetRemote::getHighlightIndex(RemoteGlyph val) { + CRoomItem *room = getRoom(); + if (!room) + return -1; + + int roomIndex = roomIndexOf(room->getName()); + if (roomIndex == -1) + return -1; + + Common::Array<uint> remoteData; + getRemoteData(roomIndex, remoteData); + + // Loop through the data for the room + for (uint idx = 0; idx < remoteData.size(); ++idx) { + if ((RemoteGlyph)remoteData[idx + 1] == val) + return idx; + } + + return -1; +} + +int CPetRemote::roomIndexOf(const CString &name) { + for (int idx = 0; idx < TOTAL_ROOMS; ++idx) { + if (g_vm->_roomNames[idx] == name) + return idx; + } + + return -1; +} + +bool CPetRemote::getRemoteData(int roomIndex, Common::Array<uint> &indexes) { + const byte *p = &REMOTE_DATA[0]; + for (int idx = 0; idx < TOTAL_ROOMS; ++idx) { + if (*p == roomIndex) { + for (int ctr = 0; ctr < *p; ++ctr) + indexes.push_back(p[ctr + 1]); + return true; + } + + p += *(p + 1) + 2; + } + + return false; +} + +bool CPetRemote::loadGlyphs(const Common::Array<uint> &indexes) { + for (uint idx = 0; idx < indexes.size(); ++idx) { + if (!loadGlyph(indexes[idx])) + return false; + } + + return true; +} + +bool CPetRemote::loadGlyph(int glyphIndex) { + CPetRemoteGlyph *glyph = nullptr; + + switch (glyphIndex) { + case GLYPH_SUMMON_ELEVATOR: + glyph = new CSummonElevatorGlyph(); + break; + + case GLYPH_SUMMON_PELLERATOR: + glyph = new CSummonPelleratorGlyph(); + break; + + case GLYPH_TELEVISION_CONTROL: + glyph = new CTelevisionControlGlyph(); + break; + + case GLYPH_ENTERTAINMENT_DEVICE: + glyph = new CEntertainmentDeviceGlyph(); + break; + + case GLYPH_OPERATE_LIGHTS: + glyph = new COperateLightsGlyph(); + break; + + case GLYPH_DEPLOY_FLORAL: + glyph = new CDeployFloralGlyph(); + break; + + case GLYPH_DEPLOY_FULLY_RELAXATION: + glyph = new CDeployFullyRelaxationGlyph(); + break; + + case GLYPH_DEPLOY_COMFORT: + glyph = new CDeployComfortGlyph(); + break; + + case GLYPH_DEPLOY_MINOR_STORAGE: + glyph = new CDeployMinorStorageGlyph(); + break; + + case GLYPH_DEPLOY_MAJOR_RELAXATION: + glyph = new CDeployMajorRelaxationGlyph(); + break; + + case GLYPH_INFLATE_RELAXATION: + glyph = new CInflateRelaxationGlyph(); + break; + + case GLYPH_DEPLOY_MAINTENANCE: + glyph = new CDeployMaintenanceGlyph(); + break; + + case GLYPH_DEPLOY_WORK_SURFACE: + glyph = new CDeployWorkSurfaceGlyph(); + break; + + case GLYPH_DEPLOY_MINOR_RELAXATION: + glyph = new CDeployMinorRelaxationGlyph(); + break; + + case GLYPH_DEPLOY_SINK: + glyph = new CDeploySinkGlyph(); + break; + + case GLYPH_DEPLOY_MAJOR_STORAGE: + glyph = new CDeployMajorStorageGlyph(); + break; + + case GLYPH_SUCCUBUS_DELIVERY: + glyph = new CSuccubusDeliveryGlyph(); + break; + + case GLYPH_NAVIGATION_CONTROLLER: + glyph = new CNavigationControllerGlyph(); + break; + + case GLYPH_GOTO_BOTTOM_OF_WELL: + glyph = new CGotoBottomOfWellGlyph(); + break; + + case GLYPH_GOTO_TOP_OF_WELL: + glyph = new CGotoTopOfWellGlyph(); + break; + + case GLYPH_GOTO_STATEROOM: + glyph = new CGotoStateroomGlyph(); + break; + + case GLYPH_GOTO_BAR: + glyph = new CGotoBarGlyph(); + + case GLYPH_GOTO_PROMENADE: + glyph = new CGotoPromenadeDeckGlyph(); + break; + + case GLYPH_GOTO_ARBORETUM: + glyph = new CGotoArboretumGlyph(); + break; + + case GLYPH_GOTO_MUSIC_ROOM: + glyph = new CGotoMusicRoomGlyph(); + break; + + case GLYPH_GOTO_RESTAURANT: + glyph = new CGotoRestaurantGlyph(); + break; + + default: + break; + } + + if (glyph) { + if (glyph->setup(_petControl, &_items)) { + _items.push_back(glyph); + return true; + } + } + + return false; +} + +void CPetRemote::generateMessage(RemoteMessage msgNum, const CString &name, int num) { + switch (msgNum) { + case RMSG_LEFT: { + CPETLeftMsg msg(name, num); + msg.execute(_petControl->_remoteTarget); + break; + } + + case RMSG_RIGHT: { + CPETRightMsg msg(name, num); + msg.execute(_petControl->_remoteTarget); + break; + } + + case RMSG_UP: { + CPETUpMsg msg(name, num); + msg.execute(_petControl->_remoteTarget); + break; + } + + case RMSG_DOWN: { + CPETDownMsg msg(name, num); + msg.execute(_petControl->_remoteTarget); + break; + } + + case RMSG_ACTIVATE: { + CPETActivateMsg msg(name, num); + msg.execute(_petControl->_remoteTarget); + break; + } + + default: + break; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_remote.h b/engines/titanic/pet_control/pet_remote.h new file mode 100644 index 0000000000..22ea1e05ad --- /dev/null +++ b/engines/titanic/pet_control/pet_remote.h @@ -0,0 +1,159 @@ +/* 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 TITANIC_PET_REMOTE_H +#define TITANIC_PET_REMOTE_H + +#include "common/array.h" +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_glyphs.h" +#include "titanic/pet_control/pet_remote_glyphs.h" +#include "titanic/pet_control/pet_text.h" + +namespace Titanic { + +class CPetRemote : public CPetSection { +private: + CPetRemoteGlyphs _items; + CPetGfxElement _onOff; + CPetGfxElement _up; + CPetGfxElement _down; + CPetGfxElement _left; + CPetGfxElement _right; + CPetGfxElement _top; + CPetGfxElement _bottom; + CPetGfxElement _action; + CPetGfxElement _send; + CPetGfxElement _receive; + CPetGfxElement _call; + CPetText _text; +private: + /** + * Setup the control + */ + bool setupControl(CPetControl *petControl); + + /** + * Get the current room + */ + CRoomItem *getRoom() const; + + /** + * Return a highlight index + */ + int getHighlightIndex(RemoteGlyph val); + + /** + * Return the index of a room name in the master room names list + */ + int roomIndexOf(const CString &name); + + /** + * Return a list of remote action glyph indexes for a given room + */ + bool getRemoteData(int roomIndex, Common::Array<uint> &indexes); + + /** + * Clear the list of rooms glyphs + */ + void clearGlyphs() { _items.clear(); } + + /** + * Load the room glyphs + */ + bool loadGlyphs(const Common::Array<uint> &indexes); + + /** + * Load a single room glyph + */ + bool loadGlyph(int glyphIndex); +public: + CPetRemote(); + + /** + * Sets up the section + */ + virtual bool setup(CPetControl *petControl); + + /** + * Reset the section + */ + virtual bool reset(); + + /** + * Draw the section + */ + virtual void draw(CScreenManager *screenManager); + + /** + * Following are handlers for the various messages that the PET can + * pass onto the currently active section/area + */ + virtual bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + virtual bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); + virtual bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg); + virtual bool VirtualKeyCharMsg(CVirtualKeyCharMsg *msg); + + /** + * Returns true if the object is in a valid state + */ + virtual bool isValid(CPetControl *petControl); + + /** + * Called after a game has been loaded + */ + virtual void postLoad(); + + /** + * Called when a section is switched to + */ + virtual void enter(PetArea oldArea); + + /** + * Called when a new room is entered + */ + virtual void enterRoom(CRoomItem *room); + + /** + * Get a reference to the tooltip text associated with the section + */ + virtual CPetText *getText(); + + /** + * Get an element from the section by a designated Id + */ + virtual CPetGfxElement *getElement(uint id); + + /** + * Highlights a glyph item in the section + */ + virtual void highlight(int id); + + /** + * Generates a PET message + */ + void generateMessage(RemoteMessage msgNum, const CString &name, int num); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_REMOTE_H */ diff --git a/engines/titanic/pet_control/pet_remote_glyphs.cpp b/engines/titanic/pet_control/pet_remote_glyphs.cpp new file mode 100644 index 0000000000..6b7c8cb4ae --- /dev/null +++ b/engines/titanic/pet_control/pet_remote_glyphs.cpp @@ -0,0 +1,562 @@ +/* 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 "titanic/pet_control/pet_remote_glyphs.h" +#include "titanic/pet_control/pet_remote.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/messages/pet_messages.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CPetRemote *CPetRemoteGlyphs::getOwner() const { + return static_cast<CPetRemote *>(_owner); +} + +void CPetRemoteGlyphs::generateMessage(RemoteMessage msgNum, const CString &name, int num) { + getOwner()->generateMessage(msgNum, name, num); +} + +/*------------------------------------------------------------------------*/ + +void CPetRemoteGlyph::setDefaults(const CString &name, CPetControl *petControl) { + _element.setBounds(Rect(0, 0, 52, 52)); + _element.setup(MODE_UNSELECTED, name, petControl); +} + +CPetRemoteGlyphs *CPetRemoteGlyph::getOwner() const { + return static_cast<CPetRemoteGlyphs *>(_owner); +} + +CPetGfxElement *CPetRemoteGlyph::getElement(uint id) const { + CPetRemote *remote = static_cast<CPetRemote *>(_owner->getOwner()); + return remote->getElement(id); +} + +/*------------------------------------------------------------------------*/ + +bool CBasicRemoteGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CPetRemoteGlyph::setup(petControl, owner); + setDefaults(_gfxName, petControl); + if (owner) + _gfxElement = getElement(18); + return true; +} + +void CBasicRemoteGlyph::draw2(CScreenManager *screenManager) { + if (_gfxElement) + _gfxElement->draw(screenManager); +} + +bool CBasicRemoteGlyph::MouseButtonDownMsg(const Point &pt) { + return _gfxElement && _gfxElement->MouseButtonDownMsg(pt); +} + +bool CBasicRemoteGlyph::MouseButtonUpMsg(const Point &pt) { + if (_gfxElement && _gfxElement->MouseButtonUpMsg(pt)) { + getOwner()->generateMessage(RMSG_ACTIVATE, "Lift"); + return true; + } + + return false; +} + +void CBasicRemoteGlyph::getTooltip(CPetText *text) { + text->setText(_tooltip); +} + +/*------------------------------------------------------------------------*/ + +bool CToggleRemoteGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CPetGlyph::setup(petControl, owner); + if (owner) + _gfxElement = getElement(0); + return true; +} + +void CToggleRemoteGlyph::draw2(CScreenManager *screenManager) { + _gfxElement->setMode(_flag ? MODE_SELECTED : MODE_UNSELECTED); + _gfxElement->draw(screenManager); +} + +bool CToggleRemoteGlyph::elementMouseButtonDownMsg(const Point &pt, int petNum) { + return _gfxElement->MouseButtonDownMsg(pt); +} + +bool CToggleRemoteGlyph::elementMouseButtonUpMsg(const Point &pt, int petNum) { + if (!_gfxElement->MouseButtonUpMsg(pt)) + return false; + + CTreeItem *target = getPetControl()->_remoteTarget; + if (target) { + CPETActivateMsg msg("SGTSelector", petNum); + msg.execute(target); + _flag = !_flag; + _gfxElement->setMode(_flag ? MODE_SELECTED : MODE_UNSELECTED); + } + + return true; +} + +/*------------------------------------------------------------------------*/ + +bool CRemoteGotoGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CPetRemoteGlyph::setup(petControl, owner); + setDefaults(_gfxName, petControl); + + if (owner) + _gfxElement = getElement(7); + + return true; +} + +void CRemoteGotoGlyph::draw2(CScreenManager *screenManager) { + if (_gfxElement) + _gfxElement->draw(screenManager); +} + +bool CRemoteGotoGlyph::MouseButtonDownMsg(const Point &pt) { + return _gfxElement && _gfxElement->MouseButtonDownMsg(pt); +} + +bool CRemoteGotoGlyph::MouseButtonUpMsg(const Point &pt) { + if (!_gfxElement || !_gfxElement->MouseButtonUpMsg(pt)) + return false; + + CPetControl *petControl = getPetControl(); + if (petControl) { + CGameManager *gameManager = petControl->getGameManager(); + + if (gameManager) { + CRoomItem *room = gameManager->getRoom(); + + if (room) { + CTransportMsg msg(g_vm->_roomNames[_roomIndex], 1, 0); + msg.execute(room); + } + } + } + + return true; +} + +void CRemoteGotoGlyph::getTooltip(CPetText *text) { + text->setText(_tooltip); +} + +/*------------------------------------------------------------------------*/ + +bool CTelevisionControlGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CPetRemoteGlyph::setup(petControl, owner); + setDefaults("3PetTV", petControl); + if (owner) { + _up = getElement(1); + _down = getElement(2); + _onOff = getElement(4); + } + + return true; +} + +void CTelevisionControlGlyph::draw2(CScreenManager *screenManager) { + _onOff->setSelected(_flag); + _onOff->draw(screenManager); + _up->draw(screenManager); + _down->draw(screenManager); +} + +bool CTelevisionControlGlyph::MouseButtonDownMsg(const Point &pt) { + if (_onOff && _onOff->MouseButtonDownMsg(pt)) + return true; + if (_up && _up->MouseButtonDownMsg(pt)) + return true; + if (_down && _down->MouseButtonDownMsg(pt)) + return true; + + return false; +} + +bool CTelevisionControlGlyph::MouseButtonUpMsg(const Point &pt) { + if (_onOff && _onOff->MouseButtonUpMsg(pt)) { + _flag = !_flag; + getOwner()->generateMessage(RMSG_ACTIVATE, "Television"); + return true; + } + + if (_up && _up->MouseButtonUpMsg(pt)) { + getOwner()->generateMessage(RMSG_UP, "Television"); + return true; + } + + if (_down && _down->MouseButtonUpMsg(pt)) { + getOwner()->generateMessage(RMSG_DOWN, "Television"); + return true; + } + + return false; +} + +void CTelevisionControlGlyph::getTooltip(CPetText *text) { + text->setText("Television control"); +} + +/*------------------------------------------------------------------------*/ + +bool CEntertainmentDeviceGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CPetRemoteGlyph::setup(petControl, owner); + if (owner) { + _gfxElement2 = getElement(1); + _gfxElement3 = getElement(2); + } + + return true; +} + +void CEntertainmentDeviceGlyph::draw2(CScreenManager *screenManager) { + CString viewName = getPetControl()->getFullViewName(); + if (viewName == "SGTState.Node 1.S") { + _gfxElement->setSelected(_flag); + _gfxElement->draw(screenManager); + } else if (viewName == "SGTState.Node 4.E") { + _gfxElement->setSelected(_flag2); + _gfxElement->draw(screenManager); + _gfxElement2->draw(screenManager); + _gfxElement3->draw(screenManager); + } +} + +bool CEntertainmentDeviceGlyph::MouseButtonDownMsg(const Point &pt) { + CString viewName = getPetControl()->getFullViewName(); + if (viewName == "SGTState.Node 1.S") { + return elementMouseButtonDownMsg(pt, 4); + } else if (viewName == "SGTState.Node 4.E") { + return _gfxElement->MouseButtonDownMsg(pt) + || _gfxElement2->MouseButtonDownMsg(pt) + || _gfxElement3->MouseButtonDownMsg(pt); + } + + return false; +} + +bool CEntertainmentDeviceGlyph::MouseButtonUpMsg(const Point &pt) { + CString viewName = getPetControl()->getFullViewName(); + if (viewName == "SGTState.Node 1.S") { + return elementMouseButtonUpMsg(pt, 4); + } else if (viewName == "SGTState.Node 4.E") { + if (_gfxElement->MouseButtonUpMsg(pt)) { + _flag2 = !_flag2; + getOwner()->generateMessage(RMSG_ACTIVATE, "Television"); + return true; + } else if (_gfxElement2->MouseButtonUpMsg(pt)) { + getOwner()->generateMessage(RMSG_UP, "Television"); + return true; + } + else if (_gfxElement3->MouseButtonUpMsg(pt)) { + getOwner()->generateMessage(RMSG_DOWN, "Television"); + return true; + } + } + + return false; +} + +void CEntertainmentDeviceGlyph::getTooltip(CPetText *text) { + text->setText("Operate visual entertainment device"); +} + +/*------------------------------------------------------------------------*/ + +bool COperateLightsGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CPetRemoteGlyph::setup(petControl, owner); + setDefaults("3PetLights", petControl); + + if (owner) { + _left = getElement(3); + _right = getElement(4); + _up = getElement(5); + _down = getElement(6); + _activate = getElement(7); + } + + return true; +} + +void COperateLightsGlyph::draw2(CScreenManager *screenManager) { + _left->draw(screenManager); + _right->draw(screenManager); + _up->draw(screenManager); + _down->draw(screenManager); + _activate->draw(screenManager); +} + +bool COperateLightsGlyph::MouseButtonDownMsg(const Point &pt) { + if (_left->MouseButtonDownMsg(pt) + || _right->MouseButtonDownMsg(pt) + || _up->MouseButtonDownMsg(pt) + || _down->MouseButtonDownMsg(pt) + || _activate->MouseButtonDownMsg(pt)) + return true; + return true; +} + +bool COperateLightsGlyph::MouseButtonUpMsg(const Point &pt) { + if (_left && _left->MouseButtonUpMsg(pt)) + getOwner()->generateMessage(RMSG_LEFT, "Light"); + else if (_right && _right->MouseButtonUpMsg(pt)) + getOwner()->generateMessage(RMSG_RIGHT, "Light"); + else if (_up && _up->MouseButtonUpMsg(pt)) + getOwner()->generateMessage(RMSG_UP, "Light"); + else if (_down && _down->MouseButtonUpMsg(pt)) + getOwner()->generateMessage(RMSG_DOWN, "Light"); + else + getOwner()->generateMessage(RMSG_ACTIVATE, "Light"); + + return true; +} + +void COperateLightsGlyph::getTooltip(CPetText *text) { + text->setText("Operate the lights"); +} + +/*------------------------------------------------------------------------*/ + +bool CDeployFloralGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CToggleRemoteGlyph::setup(petControl, owner); + setDefaults("3PetVase", petControl); + return true; +} + +void CDeployFloralGlyph::getTooltip(CPetText *text) { + text->setText("Deploy floral enhancement"); +} + + +/*------------------------------------------------------------------------*/ + +bool CDeployFullyRelaxationGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CToggleRemoteGlyph::setup(petControl, owner); + setDefaults("3PetBedfoot", petControl); + return true; +} + +void CDeployFullyRelaxationGlyph::getTooltip(CPetText *text) { + text->setText("Deploy fully recumbent relaxation device"); +} + +/*------------------------------------------------------------------------*/ + +bool CDeployComfortGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CToggleRemoteGlyph::setup(petControl, owner); + setDefaults("3PetToilet", petControl); + return true; +} + +void CDeployComfortGlyph::getTooltip(CPetText *text) { + text->setText("Deploy comfort workstation"); +} + +/*------------------------------------------------------------------------*/ + +bool CDeployMinorStorageGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CToggleRemoteGlyph::setup(petControl, owner); + setDefaults("3PetDraw", petControl); + return true; +} + +void CDeployMinorStorageGlyph::getTooltip(CPetText *text) { + text->setText("Deploy minor horizontally mobile storage compartment"); +} + +/*------------------------------------------------------------------------*/ + +bool CDeployMajorRelaxationGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CToggleRemoteGlyph::setup(petControl, owner); + setDefaults("3PetArmChair", petControl); + return true; +} + +void CDeployMajorRelaxationGlyph::getTooltip(CPetText *text) { + text->setText("Deploy major semi-recumbent relaxation device"); +} + +/*------------------------------------------------------------------------*/ + +bool CInflateRelaxationGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CToggleRemoteGlyph::setup(petControl, owner); + setDefaults("3PetBedhead", petControl); + return true; +} + +void CInflateRelaxationGlyph::getTooltip(CPetText *text) { + text->setText("Inflate fully recumbent relaxation device "); +} + +/*------------------------------------------------------------------------*/ + +bool CDeployMaintenanceGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CToggleRemoteGlyph::setup(petControl, owner); + setDefaults("3PetWashstand", petControl); + return true; +} + +void CDeployMaintenanceGlyph::getTooltip(CPetText *text) { + text->setText("Deploy personal maintenance hub"); +} + +/*------------------------------------------------------------------------*/ + +bool CDeployWorkSurfaceGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CToggleRemoteGlyph::setup(petControl, owner); + setDefaults("3PetTable", petControl); + return true; +} + +void CDeployWorkSurfaceGlyph::getTooltip(CPetText *text) { + text->setText("Deploy executive horizontal worksurface"); +} + +/*------------------------------------------------------------------------*/ + +bool CDeployMinorRelaxationGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CToggleRemoteGlyph::setup(petControl, owner); + setDefaults("3PetDeskchair", petControl); + return true; +} + +void CDeployMinorRelaxationGlyph::getTooltip(CPetText *text) { + text->setText("Deploy minor semi-recumbent relaxation device"); +} + +/*------------------------------------------------------------------------*/ + +bool CDeploySinkGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CToggleRemoteGlyph::setup(petControl, owner); + setDefaults("3PetDeskchair", petControl); + return true; +} + +void CDeploySinkGlyph::getTooltip(CPetText *text) { + text->setText("Deploy aqueous cleansing receptacle"); +} + +/*------------------------------------------------------------------------*/ + +bool CDeployMajorStorageGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CToggleRemoteGlyph::setup(petControl, owner); + setDefaults("3PetChest", petControl); + return true; +} + +void CDeployMajorStorageGlyph::getTooltip(CPetText *text) { + text->setText("Deploy major horizontally mobile storage compartment"); +} + +/*------------------------------------------------------------------------*/ + +bool CSuccubusDeliveryGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CPetRemoteGlyph::setup(petControl, owner); + setDefaults("3PetSuccubus", petControl); + + if (owner) { + _gfxElement1 = getElement(16); + _gfxElement2 = getElement(17); + } + + return true; +} + +void CSuccubusDeliveryGlyph::draw2(CScreenManager *screenManager) { + _gfxElement1->draw(screenManager); + _gfxElement2->draw(screenManager); +} + +bool CSuccubusDeliveryGlyph::MouseButtonDownMsg(const Point &pt) { + return _gfxElement1->MouseButtonDownMsg(pt) + || _gfxElement2->MouseButtonDownMsg(pt); +} + +bool CSuccubusDeliveryGlyph::MouseButtonUpMsg(const Point &pt) { + CTreeItem *target = getPetControl()->_remoteTarget; + + if (_gfxElement1 && _gfxElement1->MouseButtonUpMsg(pt)) { + if (target) { + CPETDeliverMsg msg; + msg.execute(target); + } + } else if (_gfxElement2 && _gfxElement2->MouseButtonUpMsg(pt)) { + if (target) { + CPETReceiveMsg msg; + msg.execute(target); + } + } else { + return false; + } + + return true; +} + +void CSuccubusDeliveryGlyph::getTooltip(CPetText *text) { + text->setText("Succ-U-Bus delivery system control"); +} + +/*------------------------------------------------------------------------*/ + +bool CNavigationControllerGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + CPetRemoteGlyph::setup(petControl, owner); + setDefaults("3PetStarField", petControl); + + if (owner) + _gfxElement = getElement(0); + + return true; +} + +void CNavigationControllerGlyph::draw2(CScreenManager *screenManager) { + _gfxElement->setMode(_flag ? MODE_SELECTED : MODE_UNSELECTED); + _gfxElement->draw(screenManager); +} + +bool CNavigationControllerGlyph::MouseButtonDownMsg(const Point &pt) { + return _gfxElement->MouseButtonDownMsg(pt); +} + +bool CNavigationControllerGlyph::MouseButtonUpMsg(const Point &pt) { + if (!_gfxElement->MouseButtonUpMsg(pt)) + return false; + + _flag = !_flag; + CTreeItem *target = getPetControl()->_remoteTarget; + if (target) { + CPETHelmetOnOffMsg msg; + msg.execute(target); + } + + return true; +} + +void CNavigationControllerGlyph::getTooltip(CPetText *text) { + text->setText("Navigation controller"); +} + +/*------------------------------------------------------------------------*/ + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_remote_glyphs.h b/engines/titanic/pet_control/pet_remote_glyphs.h new file mode 100644 index 0000000000..d3541d6a94 --- /dev/null +++ b/engines/titanic/pet_control/pet_remote_glyphs.h @@ -0,0 +1,715 @@ +/* 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 TITANIC_PET_REMOTE_GLYPHS_H +#define TITANIC_PET_REMOTE_GLYPHS_H + +#include "titanic/pet_control/pet_glyphs.h" +#include "titanic/pet_control/pet_gfx_element.h" + +namespace Titanic { + +enum RemoteGlyph { + GLYPH_SUMMON_ELEVATOR = 0, GLYPH_SUMMON_PELLERATOR = 1, + GLYPH_TELEVISION_CONTROL = 2, GLYPH_ENTERTAINMENT_DEVICE = 3, + GLYPH_OPERATE_LIGHTS = 4, GLYPH_DEPLOY_FLORAL = 5, + GLYPH_DEPLOY_FULLY_RELAXATION = 6, GLYPH_DEPLOY_COMFORT = 7, + GLYPH_DEPLOY_MINOR_STORAGE = 8, GLYPH_DEPLOY_MAJOR_RELAXATION = 9, + GLYPH_INFLATE_RELAXATION = 10, GLYPH_DEPLOY_MAINTENANCE = 11, + GLYPH_DEPLOY_WORK_SURFACE = 12, GLYPH_DEPLOY_MINOR_RELAXATION = 13, + GLYPH_DEPLOY_SINK = 14, GLYPH_DEPLOY_MAJOR_STORAGE = 15, + GLYPH_SUCCUBUS_DELIVERY = 16, GLYPH_NAVIGATION_CONTROLLER = 17, + GLYPH_GOTO_BOTTOM_OF_WELL = 18, GLYPH_GOTO_TOP_OF_WELL = 19, + GLYPH_GOTO_STATEROOM = 20, GLYPH_GOTO_BAR = 21, + GLYPH_GOTO_PROMENADE = 22, GLYPH_GOTO_ARBORETUM = 23, + GLYPH_GOTO_MUSIC_ROOM = 24, GLYPH_GOTO_RESTAURANT = 25 +}; + +enum RemoteMessage { + RMSG_LEFT = 0, RMSG_RIGHT = 1, RMSG_UP = 2, RMSG_DOWN = 3, RMSG_ACTIVATE = 4 +}; + +class CPetRemote; + +class CPetRemoteGlyphs : public CPetGlyphs { +public: + /** + * Returns the owning CPetRemote + */ + CPetRemote *getOwner() const; + + /** + * Generates a PET message + */ + void generateMessage(RemoteMessage msgNum, const CString &name, int num = -1); +}; + +class CPetRemoteGlyph : public CPetGlyph { +protected: + CPetGfxElement *_gfxElement; +protected: + CPetRemoteGlyph() : CPetGlyph(), _gfxElement(nullptr) {} + + /** + * Set defaults for the glyph + */ + void setDefaults(const CString &name, CPetControl *petControl); + + /** + * Get the owner + */ + CPetRemoteGlyphs *getOwner() const; + + /** + * Get an element by id from the parent Remote section + */ + CPetGfxElement *getElement(uint id) const; +}; + +class CBasicRemoteGlyph : public CPetRemoteGlyph { +private: + CString _gfxName, _tooltip, _msgString; +public: + CBasicRemoteGlyph(const CString &gfxName, const CString &tooltip, + const CString &msgString) : CPetRemoteGlyph(), + _gfxName(gfxName), _tooltip(tooltip), _msgString(msgString) {} + + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt); + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CToggleRemoteGlyph : public CPetRemoteGlyph { +protected: + CPetGfxElement *_gfxElement; + bool _flag; +public: + CToggleRemoteGlyph() : CPetRemoteGlyph(), _gfxElement(nullptr), _flag(false) {} + + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager); + + /** + * Called for mouse button down messages to the default element + */ + bool elementMouseButtonDownMsg(const Point &pt, int petNum); + + /** + * Called for mouse button up messages to the default element + */ + bool elementMouseButtonUpMsg(const Point &pt, int petNum); +}; + +class CRemoteGotoGlyph : public CPetRemoteGlyph { +protected: + int _roomIndex; + CPetGfxElement *_gfxElement; + CString _gfxName, _tooltip; +public: + CRemoteGotoGlyph() : CPetRemoteGlyph(), _gfxElement(nullptr), _roomIndex(21) {} + CRemoteGotoGlyph(const CString &gfxName, const CString &tooltip) : + CPetRemoteGlyph(), _gfxElement(nullptr), _roomIndex(21), + _gfxName(gfxName), _tooltip(tooltip) {} + + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt); + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CSummonElevatorGlyph : public CBasicRemoteGlyph { +public: + CSummonElevatorGlyph() : CBasicRemoteGlyph( + "3PetLift", "Summon Elevator", "Lift") {} +}; + +class CSummonPelleratorGlyph : public CBasicRemoteGlyph { +public: + CSummonPelleratorGlyph() : CBasicRemoteGlyph( + "3PetPellerator", "Summon Pellerator", "Pellerator") {} +}; + +class CTelevisionControlGlyph : public CPetRemoteGlyph { +private: + bool _flag; + CPetGfxElement *_up, *_down, *_onOff; +public: + CTelevisionControlGlyph() : CPetRemoteGlyph(), _flag(false), + _up(nullptr), _down(nullptr), _onOff(nullptr) {} + + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt); + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CEntertainmentDeviceGlyph : public CToggleRemoteGlyph { +public: + bool _flag2; + CPetGfxElement *_gfxElement2, *_gfxElement3; +public: + CEntertainmentDeviceGlyph() : CToggleRemoteGlyph(), + _flag2(false), _gfxElement2(nullptr), _gfxElement3(nullptr) {} + + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt); + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + + +class COperateLightsGlyph : public CPetRemoteGlyph { +public: + CPetGfxElement *_left, *_right, *_up, *_down, *_activate; +public: + COperateLightsGlyph() : CPetRemoteGlyph(), _left(nullptr), _right(nullptr), + _up(nullptr), _down(nullptr), _activate(nullptr) {} + + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt); + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CDeployFloralGlyph : public CToggleRemoteGlyph { +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { + return elementMouseButtonDownMsg(pt, 0); + } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { + return elementMouseButtonUpMsg(pt, 0); + } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CDeployFullyRelaxationGlyph : public CToggleRemoteGlyph { +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { + return elementMouseButtonDownMsg(pt, 1); + } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { + return elementMouseButtonUpMsg(pt, 1); + } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CDeployComfortGlyph : public CToggleRemoteGlyph { +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { + return elementMouseButtonDownMsg(pt, 2); + } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { + return elementMouseButtonUpMsg(pt, 2); + } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CDeployMinorStorageGlyph : public CToggleRemoteGlyph { +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { + return elementMouseButtonDownMsg(pt, 3); + } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { + return elementMouseButtonUpMsg(pt, 3); + } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CDeployMajorRelaxationGlyph : public CToggleRemoteGlyph { +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { + return elementMouseButtonDownMsg(pt, 5); + } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { + return elementMouseButtonUpMsg(pt, 5); + } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CInflateRelaxationGlyph : public CToggleRemoteGlyph { +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { + return elementMouseButtonDownMsg(pt, 6); + } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { + return elementMouseButtonUpMsg(pt, 6); + } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CDeployMaintenanceGlyph : public CToggleRemoteGlyph { +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { + return elementMouseButtonDownMsg(pt, 7); + } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { + return elementMouseButtonUpMsg(pt, 7); + } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CDeployWorkSurfaceGlyph : public CToggleRemoteGlyph { +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { + return elementMouseButtonDownMsg(pt, 8); + } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { + return elementMouseButtonUpMsg(pt, 8); + } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CDeployMinorRelaxationGlyph : public CToggleRemoteGlyph { +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { + return elementMouseButtonDownMsg(pt, 9); + } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { + return elementMouseButtonUpMsg(pt, 9); + } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CDeploySinkGlyph : public CToggleRemoteGlyph { +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { + return elementMouseButtonDownMsg(pt, 10); + } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { + return elementMouseButtonUpMsg(pt, 10); + } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CDeployMajorStorageGlyph : public CToggleRemoteGlyph { +public: + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt) { + return elementMouseButtonDownMsg(pt, 11); + } + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt) { + return elementMouseButtonUpMsg(pt, 11); + } + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CSuccubusDeliveryGlyph : public CPetRemoteGlyph { +private: + CPetGfxElement *_gfxElement1, *_gfxElement2; +public: + CSuccubusDeliveryGlyph() : CPetRemoteGlyph(), + _gfxElement1(nullptr), _gfxElement2(nullptr) {} + + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt); + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CNavigationControllerGlyph : public CPetRemoteGlyph { +private: + bool _flag; + CPetGfxElement *_gfxElement; +public: + CNavigationControllerGlyph() : CPetRemoteGlyph(), + _flag(false), _gfxElement(nullptr) {} + + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt); + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +class CGotoBottomOfWellGlyph : public CRemoteGotoGlyph { +public: + CGotoBottomOfWellGlyph() : CRemoteGotoGlyph("3PetBotOfWell", + "Go to the Bottom of the Well") {} +}; + +class CGotoTopOfWellGlyph : public CRemoteGotoGlyph { +public: + CGotoTopOfWellGlyph() : CRemoteGotoGlyph("3PetTopOfWell", + "Go to the Top of the Well") {} +}; + +class CGotoStateroomGlyph : public CRemoteGotoGlyph { +public: + CGotoStateroomGlyph() : CRemoteGotoGlyph("3PetRoom", + "Go to your stateroom") {} +}; + +class CGotoBarGlyph : public CRemoteGotoGlyph { +public: + CGotoBarGlyph() : CRemoteGotoGlyph("3PetBar", + "Go to the Bar") {} +}; + +class CGotoPromenadeDeckGlyph : public CRemoteGotoGlyph { +public: + CGotoPromenadeDeckGlyph() : CRemoteGotoGlyph("3PetPromDeck", + "Go to the Promenade Deck") {} +}; + +class CGotoArboretumGlyph : public CRemoteGotoGlyph { +public: + CGotoArboretumGlyph() : CRemoteGotoGlyph("3PetArboretum", + "Go to the Arboretum") {} +}; + +class CGotoMusicRoomGlyph : public CRemoteGotoGlyph { +public: + CGotoMusicRoomGlyph() : CRemoteGotoGlyph("3PetMusicRoom", + "Go to the Music Room") {} +}; + +class CGotoRestaurantGlyph : public CRemoteGotoGlyph { +public: + CGotoRestaurantGlyph() : CRemoteGotoGlyph("3Pet1stClassRest", + "Go to the First Class Restaurant") {} +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_REMOTE_GLYPHS_H */ diff --git a/engines/titanic/pet_control/pet_rooms.cpp b/engines/titanic/pet_control/pet_rooms.cpp new file mode 100644 index 0000000000..2415c96966 --- /dev/null +++ b/engines/titanic/pet_control/pet_rooms.cpp @@ -0,0 +1,380 @@ +/* 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 "titanic/pet_control/pet_rooms.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +CPetRooms::CPetRooms() : + _chevLeftOnDim(nullptr), _chevLeftOffDim(nullptr), + _chevRightOnDim(nullptr), _chevRightOffDim(nullptr), + _chevLeftOnLit(nullptr), _chevLeftOffLit(nullptr), + _chevRightOnLit(nullptr), _chevRightOffLit(nullptr), + _floorNum(0), _elevatorNum(0), _roomNum(0), _field1CC(0), + _wellEntry(0), _field1D4(0) { +} + +bool CPetRooms::setup(CPetControl *petControl) { + if (petControl && setupControl(petControl)) + return reset(); + return false; +} + +bool CPetRooms::reset() { + if (_petControl) { + _plinth.reset("PetChevPlinth", _petControl, MODE_UNSELECTED); + _glyphs.reset(); + + uint col = getColor(0); + _text.setColor(col); + _text.setLineColor(0, col); + } + + return true; +} + +void CPetRooms::draw(CScreenManager *screenManager) { + _petControl->drawSquares(screenManager, 6); + _plinth.draw(screenManager); + _glyphItem.drawAt(screenManager, getGlyphPos(), false); + _text.draw(screenManager); +} + +bool CPetRooms::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if (_glyphs.MouseButtonDownMsg(msg->_mousePos)) + return true; + + if (!_glyphItem.contains(getGlyphPos(), msg->_mousePos)) + return false; + + _glyphItem.MouseButtonDownMsg(msg->_mousePos); + return true; +} + +bool CPetRooms::MouseDragStartMsg(CMouseDragStartMsg *msg) { + if (_glyphs.MouseDragStartMsg(msg)) + return true; + + Point topLeft = getGlyphPos(); + if (!_glyphItem.contains(topLeft, msg->_mousePos)) + return false; + + _glyphItem.dragGlyph(topLeft, msg); + return true; +} + +bool CPetRooms::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + return false; +} + +bool CPetRooms::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { + return !_glyphs.MouseButtonDownMsg(msg->_mousePos); +} + +bool CPetRooms::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { + return _glyphs.VirtualKeyCharMsg(msg); +} + +bool CPetRooms::checkDragEnd(CGameObject *item) { + // Ignore any item drops except valid mail items + if (!item->_isMail) + return false; + + uint roomFlags = item->_id; + CPetRoomsGlyph *glyph = _glyphs.findGlyphByFlags(roomFlags); + if (glyph) { + if (_glyphs.findGlyphByFlags(0)) { + _glyphs.highlight(glyph); + return false; + } + + roomFlags = 0; + } + + addRoom(roomFlags, true); + return false; +} + +void CPetRooms::displayMessage(const CString &msg) { + _glyphs.resetHighlight(); + CPetSection::displayMessage(msg); +} + +bool CPetRooms::isValid(CPetControl *petControl) { + return setupControl(petControl); +} + +void CPetRooms::load(SimpleFile *file, int param) { + if (!param) { + int count = file->readNumber(); + + for (int idx = 0; idx < count; ++idx) { + CPetRoomsGlyph *glyph = addGlyph(file->readNumber(), false); + glyph->setMode((RoomGlyphMode)file->readNumber()); + } + + _glyphItem.setMode((RoomGlyphMode)file->readNumber()); + file->readNumber(); + _floorNum = file->readNumber(); + _elevatorNum = file->readNumber(); + _roomNum = file->readNumber(); + _field1CC = file->readNumber(); + _wellEntry = file->readNumber(); + _field1D4 = file->readNumber(); + } +} + +void CPetRooms::postLoad() { + reset(); +} + +void CPetRooms::save(SimpleFile *file, int indent) { + _glyphs.saveGlyphs(file, indent); + _glyphItem.saveGlyph(file, indent); + file->writeNumberLine(_floorNum, indent); + file->writeNumberLine(_elevatorNum, indent); + file->writeNumberLine(_roomNum, indent); + file->writeNumberLine(_field1CC, indent); + file->writeNumberLine(_wellEntry, indent); + file->writeNumberLine(_field1D4, indent); +} + +void CPetRooms::enter(PetArea oldArea) { + if (!_glyphs.highlighted14()) + _text.setText(""); +} + +void CPetRooms::enterRoom(CRoomItem *room) { + +} + +CPetText *CPetRooms::getText() { + return &_text; +} + +CGameObject *CPetRooms::getBackground(int index) const { + switch (index) { + case 8: + return _chevLeftOnDim; + case 9: + return _chevLeftOffDim; + case 10: + return _chevLeftOnLit; + case 11: + return _chevLeftOffLit; + case 12: + return _chevRightOnDim; + case 13: + return _chevRightOffDim; + case 14: + return _chevRightOnLit; + case 15: + return _chevRightOffLit; + default: + return nullptr; + } +} + +bool CPetRooms::setupControl(CPetControl *petControl) { + _petControl = petControl; + if (!petControl) + return false; + + Rect rect1(0, 0, 470, 15); + rect1.moveTo(32, 445); + _text.setBounds(rect1); + _text.setHasBorder(false); + + Rect rect2(0, 0, 81, 81); + _plinth.setBounds(rect2); + _plinth.translate(494, 374); + + _chevLeftOnDim = petControl->getHiddenObject("3PetChevLeftOnDim"); + _chevLeftOffDim = petControl->getHiddenObject("3PetChevLeftOffDim"); + _chevRightOnDim = petControl->getHiddenObject("3PetChevRightOnDim"); + _chevRightOffDim = petControl->getHiddenObject("3PetChevRightOffDim"); + _chevLeftOnLit = petControl->getHiddenObject("3PetChevLeftOnLit"); + _chevLeftOffLit = petControl->getHiddenObject("3PetChevLeftOffLit"); + _chevRightOnLit = petControl->getHiddenObject("3PetChevRightOnLit"); + _chevRightOffLit = petControl->getHiddenObject("3PetChevRightOffLit"); + + _glyphs.setup(6, this); + _glyphs.setFlags(GFLAG_16); + _glyphItem.setup(petControl, &_glyphs); + _glyphItem.set38(1); + return true; +} + +void CPetRooms::resetHighlight() { + _glyphItem.setRoomFlags(getRoomFlags()); + _glyphs.resetHighlight(); + _glyphItem.updateTooltip(); + areaChanged(PET_ROOMS); +} + +uint CPetRooms::getRoomFlags() const { + CRoomFlags roomFlags; + CString roomName = _petControl->getRoomName(); + + uint flags = roomFlags.getSpecialRoomFlags(roomName); + if (flags) + return flags; + + int classNum = roomFlags.whatPassengerClass(_floorNum); + roomFlags.setPassengerClassBits(classNum); + roomFlags.setFloorNum(_floorNum); + + switch (classNum) { + case 1: + roomFlags.setElevatorNum(_elevatorNum); + roomFlags.setRoomBits(_roomNum); + break; + + case 2: + if (_roomNum > 0) { + if (_roomNum >= 3) { + roomFlags.setElevatorNum(_elevatorNum == 1 || _elevatorNum == 2 ? 1 : 3); + } else { + roomFlags.setElevatorNum(_elevatorNum == 1 || _elevatorNum == 2 ? 2 : 4); + } + + roomFlags.setRoomBits(((_roomNum - 1) & 1) + (_field1CC > 1 ? 3 : 2)); + } else { + roomFlags.setRoomBits(0); + } + break; + + case 3: + roomFlags.setElevatorNum(_elevatorNum); + roomFlags.setRoomBits(_roomNum + _field1CC * 6 - 6); + break; + + default: + break; + } + + return roomFlags.get(); +} + +void CPetRooms::reassignRoom(int passClassNum) { + CPetRoomsGlyph *glyph = _glyphs.findAssignedRoom(); + if (glyph) + // Flag the old assigned room as no longer assigned + glyph->setMode(RGM_PREV_ASSIGNED_ROOM); + + CRoomFlags roomFlags; + roomFlags.setRandomLocation(passClassNum, _field1D4); + glyph = addRoom(roomFlags, true); + if (glyph) { + // Flag the new room as assigned to the player, and highlight it + glyph->setMode(RGM_ASSIGNED_ROOM); + _glyphs.highlight(glyph); + } +} + +CPetRoomsGlyph *CPetRooms::addRoom(uint roomFlags, bool highlight_) { + // Ensure that we don't add room if the room is already present + if (_glyphs.hasFlags(roomFlags)) + return nullptr; + + if (_glyphs.size() >= 32) + // Too many rooms already + return nullptr; + + // Do a preliminary scan of the glyph list for any glyph that is + // no longer valid, and thus can be removed + for (CPetRoomsGlyphs::iterator i = _glyphs.begin(); i != _glyphs.end(); ++i) { + CPetRoomsGlyph *glyph = static_cast<CPetRoomsGlyph *>(*i); + if (!glyph->isAssigned()) { + _glyphs.erase(i); + break; + } + } + + // Add the glyph + return addGlyph(roomFlags, highlight_); +} + +CPetRoomsGlyph *CPetRooms::addGlyph(uint roomFlags, bool highlight_) { + CPetRoomsGlyph *glyph = new CPetRoomsGlyph(roomFlags); + if (!glyph->setup(_petControl, &_glyphs)) { + delete glyph; + return nullptr; + } else { + _glyphs.push_back(glyph); + if (highlight_) + _glyphs.highlight(glyph); + + return glyph; + } +} + +bool CPetRooms::changeLocationClass(int newClassNum) { + CPetRoomsGlyph *glyph = _glyphs.findAssignedRoom(); + if (!glyph) + return 0; + + glyph->changeLocation(newClassNum); + return true; +} + +bool CPetRooms::hasRoomFlags(uint roomFlags) const { + for (CPetRoomsGlyphs::const_iterator i = _glyphs.begin(); i != _glyphs.end(); ++i) { + const CPetRoomsGlyph *glyph = static_cast<const CPetRoomsGlyph *>(*i); + if (glyph->isAssigned() && glyph->getRoomFlags() == roomFlags) + return true; + } + + return false; +} + +uint CPetRooms::getAssignedRoomFlags() const { + CPetRoomsGlyph *glyph = _glyphs.findAssignedRoom(); + return glyph ? glyph->getRoomFlags() : 0; +} + +int CPetRooms::getAssignedRoomNum() const { + uint flags = getAssignedRoomFlags(); + if (!flags) + return 0; + + return CRoomFlags(flags).getRoomNum(); +} + +int CPetRooms::getAssignedFloorNum() const { + uint flags = getAssignedRoomFlags(); + if (!flags) + return 0; + + return CRoomFlags(flags).getFloorNum(); +} + +int CPetRooms::getAssignedElevatorNum() const { + uint flags = getAssignedRoomFlags(); + if (!flags) + return 0; + + return CRoomFlags(flags).getElevatorNum(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_rooms.h b/engines/titanic/pet_control/pet_rooms.h new file mode 100644 index 0000000000..af1ea2ae4f --- /dev/null +++ b/engines/titanic/pet_control/pet_rooms.h @@ -0,0 +1,219 @@ +/* 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 TITANIC_PET_ROOMS_H +#define TITANIC_PET_ROOMS_H + +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_text.h" +#include "titanic/pet_control/pet_rooms_glyphs.h" + +namespace Titanic { + +class CPetRooms : public CPetSection { +private: + CPetRoomsGlyphs _glyphs; + CPetRoomsGlyph _glyphItem; + CGameObject *_chevLeftOnDim; + CGameObject *_chevLeftOffDim; + CGameObject *_chevRightOnDim; + CGameObject *_chevRightOffDim; + CGameObject *_chevLeftOnLit; + CGameObject *_chevLeftOffLit; + CGameObject *_chevRightOnLit; + CGameObject *_chevRightOffLit; + CPetGfxElement _plinth; + CPetText _text; + int _floorNum; + int _elevatorNum; + int _roomNum; + int _field1CC; + int _wellEntry; + int _field1D4; +private: + /** + * Setup the control + */ + bool setupControl(CPetControl *petControl); + + /** + * Returns the glyth position + */ + Point getGlyphPos() const { return Point(509, 388); } + + /** + * Adds a glyph to the list + */ + CPetRoomsGlyph *addRoom(uint roomFlags, bool highlight); + + /** + * Adds a glyph to the list + */ + CPetRoomsGlyph *addGlyph(uint roomFlags, bool highlight); +public: + CPetRooms(); + + /** + * Sets up the section + */ + virtual bool setup(CPetControl *petControl); + + /** + * Reset the section + */ + virtual bool reset(); + + /** + * Draw the section + */ + virtual void draw(CScreenManager *screenManager); + + /** + * Following are handlers for the various messages that the PET can + * pass onto the currently active section/area + */ + virtual bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + virtual bool MouseDragStartMsg(CMouseDragStartMsg *msg); + virtual bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); + virtual bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg); + virtual bool VirtualKeyCharMsg(CVirtualKeyCharMsg *msg); + + /** + * Check whether a drag drop can occur + */ + virtual bool checkDragEnd(CGameObject *item); + + /** + * Display a message + */ + virtual void displayMessage(const CString &msg); + + /** + * Returns true if the object is in a valid state + */ + virtual bool isValid(CPetControl *petControl); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file, int param); + + /** + * Called after a game has been loaded + */ + virtual void postLoad(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Called when a section is switched to + */ + virtual void enter(PetArea oldArea); + + /** + * Called when a new room is entered + */ + virtual void enterRoom(CRoomItem *room); + + /** + * Get a reference to the tooltip text associated with the section + */ + virtual CPetText *getText(); + + /** + * Special retrieval of glyph background image + */ + virtual CGameObject *getBackground(int index) const; + + /** + * Reset the highlight + */ + void resetHighlight(); + + /** + * Gives the player a new assigned room in the specified passenger class + */ + void reassignRoom(int passClassNum); + + /** + * Change the current location passenger class + */ + bool changeLocationClass(int newClassNum); + + /** + * Returns true if a room glyph exists with the given flags + */ + bool hasRoomFlags(uint roomFlags) const; + + /** + * Returns the room flags for the player's currently assigned room + */ + uint getAssignedRoomFlags() const; + + /** + * Returns the room number for the player's currently assigned room + */ + int getAssignedRoomNum() const; + + /** + * Returns the floor number for the player's currently assigned room + */ + int getAssignedFloorNum() const; + + /** + * Returns the elevator number for the player's currently assigned room + */ + int getAssignedElevatorNum() const; + + /** + * Gets room flags to use for glyphs + */ + uint getRoomFlags() const; + + void setFloorNum(int floorNum) { _floorNum = floorNum; } + int getFloorNum() const { return _floorNum; } + void setElevatorNum(int elevNum) { _elevatorNum = elevNum; } + int getElevatorNum() const { return _elevatorNum; } + void setRoomNum(int roomNum) { _roomNum = roomNum; } + int getRoomNum() const { return _roomNum; } + void set1CC(int val) { _field1CC = val; } + int get1CC() const { return _field1CC; } + + /** + * Sets the entry number for arriving at the well + */ + void setWellEntry(int val) { _wellEntry = val; } + + /** + * Gets the entry number used when last arriving at the well + */ + int getWellEntry() const { return _wellEntry; } + + void set1D4(int val) { _field1D4 = val; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_ROOMS_SECTION_H */ diff --git a/engines/titanic/pet_control/pet_rooms_glyphs.cpp b/engines/titanic/pet_control/pet_rooms_glyphs.cpp new file mode 100644 index 0000000000..d9e19b1f67 --- /dev/null +++ b/engines/titanic/pet_control/pet_rooms_glyphs.cpp @@ -0,0 +1,257 @@ +/* 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 "titanic/pet_control/pet_rooms_glyphs.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/pet_control/pet_section.h" +#include "titanic/support/screen_manager.h" +#include "titanic/room_flags.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CPetRoomsGlyph::CPetRoomsGlyph() : CPetGlyph(), + _roomFlags(0), _field38(0), _mode(RGM_UNASSIGNED), + _object0(nullptr), _object1(nullptr), _object2(nullptr), _object3(nullptr), + _object4(nullptr), _object5(nullptr), _object6(nullptr), _object7(nullptr) { +} + +CPetRoomsGlyph::CPetRoomsGlyph(uint flags) : CPetGlyph(), + _roomFlags(flags), _field38(0), _mode(RGM_UNASSIGNED), + _object0(nullptr), _object1(nullptr), _object2(nullptr), _object3(nullptr), + _object4(nullptr), _object5(nullptr), _object6(nullptr), _object7(nullptr) { +} + +bool CPetRoomsGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { + if (!CPetGlyph::setup(petControl, owner)) + return false; + + CPetSection *section = owner->getOwner(); + _object0 = section->getBackground(9); + _object1 = section->getBackground(12); + _object4 = section->getBackground(13); + _object5 = section->getBackground(10); + _object2 = section->getBackground(11); + _object3 = section->getBackground(14); + _object6 = section->getBackground(15); + _object7 = _object6; + return true; +} + +void CPetRoomsGlyph::drawAt(CScreenManager *screenManager, const Point &pt, bool isHighlighted_) { + // Clear background + Rect rect(pt.x, pt.y, pt.x + 52, pt.y + 52); + screenManager->fillRect(SURFACE_BACKBUFFER, &rect, 0, 0, 0); + + CRoomFlags roomFlags(_roomFlags); + uint elevBits = roomFlags.getElevatorBits(); + uint classBits = roomFlags.getPassengerClassBits(); + uint floorBits = roomFlags.getFloorBits(); + uint roomBits = roomFlags.getRoomBits(); + + // Save a copy of object pointers that may be modified + CGameObject *obj0 = _object0; + CGameObject *obj1 = _object1; + CGameObject *obj4 = _object4; + CGameObject *obj5 = _object5; + + if (_field38 == 1 || isHighlighted_) { + _object0 = _object2; + _object1 = _object3; + _object4 = _object6; + _object5 = _object7; + } + + // Draw the images + Point destPt = pt; + drawObjects(classBits + elevBits * 4, destPt, screenManager); + destPt.y += 10; + drawObjects((floorBits >> 4) & 15, destPt, screenManager); + destPt.y += 10; + drawObjects(floorBits & 15, destPt, screenManager); + destPt.y += 10; + drawObjects(roomBits >> 3, destPt, screenManager); + destPt.y += 7; + drawObjects(((roomBits & 7) << 1) + (roomFlags.getBit0() ? 1 : 0), + destPt, screenManager); + + // Restore original object pointers + _object0 = obj0; + _object1 = obj1; + _object4 = obj4; + _object5 = obj5; +} + +void CPetRoomsGlyph::selectGlyph(const Point &topLeft, const Point &pt) { + if (isAssigned()) { + bool isShiftPressed = g_vm->_window->getSpecialButtons() & MK_SHIFT; + + if (isShiftPressed) { + int selection = getSelection(topLeft, pt); + if (selection >= 0) + _roomFlags |= 1 << selection; + } + + updateTooltip(); + } +} + +bool CPetRoomsGlyph::dragGlyph(const Point &topLeft, CMouseDragStartMsg *msg) { + bool isShiftPressed = g_vm->_window->getSpecialButtons() & MK_SHIFT; + CPetControl *petControl = getPetControl(); + + if (!isShiftPressed && petControl) { + CGameObject *chevron = petControl->getHiddenObject("3PetChevron"); + + if (chevron) { + chevron->_id = _roomFlags; + chevron->_isMail = _field38; + petControl->removeFromInventory(chevron, false, false); + chevron->loadSurface(); + + chevron->dragMove(msg->_mousePos); + msg->_handled = true; + + if (msg->execute(chevron)) + return true; + } + } + + return false; +} + +void CPetRoomsGlyph::getTooltip(CPetText *text) { + CRoomFlags roomFlags(_roomFlags); + CPetRooms *owner = static_cast<CPetRooms *>(getPetSection()); + + CString msg; + if (isCurrentlyAssigned()) { + msg = "Your assigned room: "; + } else if (isPreviouslyAssigned()) { + msg = "A previously assigned room: "; + } else if (!_field38) { + msg = "Saved Chevron: "; + } else if (_field38 == 1 && owner->getRoomFlags() == _roomFlags) { + msg = "Current location: "; + } + + // Get the room description + CString roomStr = roomFlags.getRoomDesc(); + + if (roomStr == "The Elevator") { + int elevNum = owner->getElevatorNum(); + roomStr = CString::format("Elevator %d", elevNum); + } + + roomStr += " (shift-click edits)"; + text->setText(roomStr); +} + +void CPetRoomsGlyph::saveGlyph(SimpleFile *file, int indent) { + file->writeNumberLine(_roomFlags, indent); + file->writeNumberLine(_mode, indent); +} + +bool CPetRoomsGlyph::proc33(CPetGlyph *glyph) { + CPetRoomsGlyph *roomGlyph = static_cast<CPetRoomsGlyph *>(glyph); + + return CPetGlyph::proc33(glyph) && _roomFlags == roomGlyph->_roomFlags; +} + +void CPetRoomsGlyph::loadFlags(SimpleFile *file, int val) { + if (!val) { + _roomFlags = file->readNumber(); + } +} + +void CPetRoomsGlyph::changeLocation(int newClassNum) { + CRoomFlags roomFlags(_roomFlags); + roomFlags.changeLocation(newClassNum); + _roomFlags = roomFlags.get(); +} + +int CPetRoomsGlyph::getSelection(const Point &topLeft, const Point &pt) { + Rect rects[4] = { + Rect(topLeft.x, topLeft.y, topLeft.x + 13, topLeft.y + 10), + Rect(topLeft.x + 13, topLeft.y, topLeft.x + 26, topLeft.y + 10), + Rect(topLeft.x + 26, topLeft.y, topLeft.x + 39, topLeft.y + 10), + Rect(topLeft.x + 39, topLeft.y, topLeft.x + 52, topLeft.y + 10) + }; + + for (int idx = 0, btnIndex = 19; idx < 5; ++idx, btnIndex -= 4) { + // Iterate through each of the four rects, seeing if there's a match. + // If not, move it down to the next row for the next loop iteration + for (int i = 0; i < 4; ++i) { + if (rects[i].contains(pt)) + return btnIndex - i; + + rects[i].translate(0, 10); + } + } + + return -1; +} + +void CPetRoomsGlyph::drawObjects(uint flags, const Point &pt, CScreenManager *screenManager) { + if (_object0 && _object1 && _object4 && _object5) { + Point destPos = pt; + ((flags & 8) ? _object0 : _object5)->draw(screenManager, destPos); + destPos.x += 13; + ((flags & 4) ? _object4 : _object5)->draw(screenManager, destPos); + destPos.x += 13; + ((flags & 2) ? _object0 : _object1)->draw(screenManager, destPos); + destPos.x += 13; + ((flags & 1) ? _object4 : _object5)->draw(screenManager, destPos); + } +} + + +/*------------------------------------------------------------------------*/ + +void CPetRoomsGlyphs::saveGlyphs(SimpleFile *file, int indent) { + file->writeNumberLine(size(), indent); + + for (const_iterator i = begin(); i != end(); ++i) + (*i)->saveGlyph(file, indent); +} + +CPetRoomsGlyph *CPetRoomsGlyphs::findAssignedRoom() const { + for (const_iterator i = begin(); i != end(); ++i) { + CPetRoomsGlyph *glyph = static_cast<CPetRoomsGlyph *>(*i); + if (glyph->isCurrentlyAssigned()) + return glyph; + } + + return nullptr; +} + +CPetRoomsGlyph *CPetRoomsGlyphs::findGlyphByFlags(uint flags) const { + for (const_iterator i = begin(); i != end(); ++i) { + CPetRoomsGlyph *glyph = static_cast<CPetRoomsGlyph *>(*i); + if (glyph->getRoomFlags() == flags) + return glyph; + } + + return nullptr; +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_rooms_glyphs.h b/engines/titanic/pet_control/pet_rooms_glyphs.h new file mode 100644 index 0000000000..5d0fec84f8 --- /dev/null +++ b/engines/titanic/pet_control/pet_rooms_glyphs.h @@ -0,0 +1,166 @@ +/* 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 TITANIC_PET_ROOMS_GLYPHS_H +#define TITANIC_PET_ROOMS_GLYPHS_H + +#include "titanic/pet_control/pet_glyphs.h" +#include "titanic/support/simple_file.h" + +namespace Titanic { + +enum RoomGlyphMode { + RGM_UNASSIGNED = 0, RGM_ASSIGNED_ROOM = 1, RGM_PREV_ASSIGNED_ROOM = 2 +}; + +class CPetRoomsGlyph : public CPetGlyph { +private: + uint _roomFlags; + int _field38; + RoomGlyphMode _mode; + CGameObject *_object0; + CGameObject *_object1; + CGameObject *_object2; + CGameObject *_object3; + CGameObject *_object4; + CGameObject *_object5; + CGameObject *_object6; + CGameObject *_object7; +private: + /** + * Find the selected button under the given point, based on the buttons + * starting at a designated top/left position + */ + int getSelection(const Point &topLeft, const Point &pt); + + /** + * Draws the objects + */ + void drawObjects(uint flags, const Point &pt, CScreenManager *screenManager); +public: + CPetRoomsGlyph(); + CPetRoomsGlyph(uint flags); + + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Draw the glyph at a specified position + */ + virtual void drawAt(CScreenManager *screenManager, const Point &pt, bool isHighlighted); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager) {} + + /** + * Selects a glyph + */ + virtual void selectGlyph(const Point &topLeft, const Point &pt); + + /** + * Called when a glyph drag starts + */ + virtual bool dragGlyph(const Point &topLeft, CMouseDragStartMsg *msg); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); + + /** + * Saves the data for the glyph + */ + virtual void saveGlyph(SimpleFile *file, int indent); + + virtual bool proc33(CPetGlyph *glyph); + + /** + * Loads flags for the glyph + */ + virtual void loadFlags(SimpleFile *file, int val); + + /** + * Set the room flags for the glyph + */ + void setRoomFlags(uint flags) { _roomFlags = flags; } + + /** + * Get the room flags for the glyph + */ + uint getRoomFlags() const { return _roomFlags; } + + void set38(int val) { _field38 = val; } + + /** + * Sets the mode of the glyph + */ + void setMode(RoomGlyphMode mode) { _mode = mode; } + + void changeLocation(int newClassNum); + + /** + * Returns true if the room is either currently or previously assigned + */ + bool isAssigned() const { return _mode != RGM_UNASSIGNED; } + + /** + * Returns true if the room is the one currently assigned to the player + */ + bool isCurrentlyAssigned() const { return _mode == RGM_ASSIGNED_ROOM; } + + /** + * Returns true if the room was previously assigned to the player + */ + bool isPreviouslyAssigned() const { return _mode == RGM_PREV_ASSIGNED_ROOM; } +}; + +class CPetRoomsGlyphs : public CPetGlyphs { +private: +public: + /** + * Save the list + */ + void saveGlyphs(SimpleFile *file, int indent); + + /** + * Returns the glyph for hte player's assigned room + */ + CPetRoomsGlyph *findAssignedRoom() const; + + /** + * Finds a glyph in the list by it's room flags + */ + CPetRoomsGlyph *findGlyphByFlags(uint flags) const; + + /** + * Returns true if there's a glyph in the list with a given room flags + */ + bool hasFlags(uint flags) const { return findGlyphByFlags(flags) != nullptr; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_ROOMS_GLYPHS_H */ diff --git a/engines/titanic/pet_control/pet_save.cpp b/engines/titanic/pet_control/pet_save.cpp new file mode 100644 index 0000000000..b5e16736bc --- /dev/null +++ b/engines/titanic/pet_control/pet_save.cpp @@ -0,0 +1,72 @@ +/* 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 "titanic/pet_control/pet_save.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +bool CPetSave::reset() { + CPetLoadSave::reset(); + + CPetControl *pet = getPetControl(); + if (pet) { + setName("PetSave", pet); + _btnLoadSave.reset("PetSaveOut", pet, MODE_UNSELECTED); + _btnLoadSave.reset("PetSaveIn", pet, MODE_SELECTED); + } + + return true; +} + +bool CPetSave::MouseButtonUpMsg(const Point &pt) { + if (_btnLoadSave.MouseButtonUpMsg(pt)) { + execute(); + resetSlots(); + return true; + } else { + return false; + } +} + +void CPetSave::highlightCurrent(const Point &pt) { + resetSlots(); + highlightSave(_savegameSlotNum); +} + +void CPetSave::getTooltip(CPetText *text) { + text->setText("Save the game."); +} + +void CPetSave::highlightSave(int index) { + warning("TODO: CPetSave::highlightSave"); +} + +void CPetSave::unhighlightSave(int index) { + warning("TODO: CPetSave::unhighlightSave"); +} + +void CPetSave::execute() { + warning("TODO: CPetSave::execute"); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_save.h b/engines/titanic/pet_control/pet_save.h new file mode 100644 index 0000000000..54e91e4c76 --- /dev/null +++ b/engines/titanic/pet_control/pet_save.h @@ -0,0 +1,88 @@ +/* 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 TITANIC_PET_SAVE_H +#define TITANIC_PET_SAVE_H + +#include "titanic/pet_control/pet_load_save.h" + +namespace Titanic { + +class CPetSave : public CPetLoadSave { +public: + /** + * Reset the glyph + */ + virtual bool reset(); + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Unhighlight any currently highlighted element + */ + virtual void unhighlightCurrent() { unhighlightSave(_savegameSlotNum); } + + /** + * Highlight any currently highlighted element + */ + virtual void highlightCurrent(const Point &pt); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); + + /** + * Called on a highlighted item when PET area is entered + */ + virtual bool enterHighlighted() { + highlightSave(_savegameSlotNum); + return true; + } + + /** + * Called on a highlighted item when PET area is left + */ + virtual void leaveHighlighted() { unhighlightSave(_savegameSlotNum); } + + /** + * Highlights a save slot + */ + virtual void highlightSave(int index); + + /** + * Unhighlight a save slot + */ + virtual void unhighlightSave(int index); + + /** + * Executes the loading or saving + */ + virtual void execute(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_SAVE_H */ diff --git a/engines/titanic/pet_control/pet_section.cpp b/engines/titanic/pet_control/pet_section.cpp new file mode 100644 index 0000000000..50d6c7615c --- /dev/null +++ b/engines/titanic/pet_control/pet_section.cpp @@ -0,0 +1,109 @@ +/* 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/textconsole.h" +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +static const uint PALETTE1[6] = { + 0xA7C0DB, 0x9CFFFE, 0x73AEFF, 0xA7C0DB, 0x9CFFFE, 0 +}; + +static const uint PALETTE2[6] = { + 0x10101, 0x1013C, 0xC80101, 0x10101, 0x800101, 0 +}; + +static const uint PALETTE3[5] = { + 0x10101, 0x1013C, 0xC80101, 0x10101, 0x800101 +}; + +void CPetSection::displayMessage(const CString &msg) { + CPetText *text = getText(); + + if (text) { + text->setColor(getColor(1)); + _petControl->makeDirty(); + removeText(5000); + } +} + +void CPetSection::timerExpired(int val) { + if (!val) { + removeText(); + _petControl->makeDirty(); + } +} + +void CPetSection::removeText(int duration) { + if (duration > 0) + _petControl->startPetTimer(0, duration, 0, this); + else + removeText(); +} + +void CPetSection::removeText() { + CPetText *text = getText(); + if (text) + text->setup(); +} + +void CPetSection::stopTextTimer() { + _petControl->stopPetTimer(0); +} + +uint CPetSection::getColor(uint index) { + return getColorTable()[index]; +} + +const uint *CPetSection::getColorTable(int tableNum) { + if (tableNum == -1) { + CPetControl *pet = getPetControl(); + tableNum = pet ? pet->getPassengerClass() : 3; + } + + switch (tableNum) { + case 1: return PALETTE1; + case 2: return PALETTE2; + default: return PALETTE3; + } +} + +void CPetSection::areaChanged(PetArea area) { + if (_petControl && _petControl->_currentArea == area) + _petControl->makeDirty(); +} + +CString CPetSection::getActiveNPCName() const { + if (_petControl && _petControl->_activeNPC) + return _petControl->_activeNPC->getName(); + else + return CString(); +} + +void CPetSection::copyColors(uint tableNum, uint colors[5]) { + const uint *src = getColorTable(tableNum); + Common::copy(src, src + 5, colors); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_section.h b/engines/titanic/pet_control/pet_section.h new file mode 100644 index 0000000000..8bc427e842 --- /dev/null +++ b/engines/titanic/pet_control/pet_section.h @@ -0,0 +1,250 @@ +/* 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 TITANIC_PET_SECTION_H +#define TITANIC_PET_SECTION_H + +#include "titanic/messages/mouse_messages.h" +#include "titanic/support/simple_file.h" + +namespace Titanic { + +enum PetArea { + PET_INVENTORY = 0, PET_CONVERSATION = 1, PET_REMOTE = 2, + PET_ROOMS = 3, PET_REAL_LIFE = 4, PET_STARFIELD = 5, PET_MESSAGE = 6 +}; + +class CPetControl; +class CPetElement; +class CPetText; +class CScreenManager; +class CRoomItem; + +struct CPetSectionSubData { + int _field0; + int _field4; + int _field8; + int _fieldC; + + CPetSectionSubData() : _field0(0), _field4(0), _field8(0), + _fieldC(0) {} +}; + +class CPetSection { +public: + CPetControl *_petControl; +protected: + /** + * Called when the current area is changed + */ + void areaChanged(PetArea area); + + /** + * Returns the name of the currently active NPC, if any + */ + CString getActiveNPCName() const; + + /** + * Create a color table + */ + void copyColors(uint tableNum, uint colors[5]); +public: + CPetSection() : _petControl(nullptr) {} + virtual ~CPetSection() {} + + /** + * Sets up the section + */ + virtual bool setup(CPetControl *petControl) { return false; } + + /** + * Reset the section + */ + virtual bool reset() { return false; } + + /** + * Draw the section + */ + virtual void draw(CScreenManager *screenManager) {} + + /** + * Get the bounds for the section + */ + virtual Rect getBounds() const { return Rect(); } + + /** + * Called when a general change occurs + */ + virtual void changed(int changeType) {} + + /** + * Following are handlers for the various messages that the PET can + * pass onto the currently active section/area + */ + virtual bool MouseButtonDownMsg(CMouseButtonDownMsg *msg) { return false; } + virtual bool MouseDragStartMsg(CMouseDragStartMsg *msg) { return false; } + virtual bool MouseDragMoveMsg(CMouseDragMoveMsg *msg) { return false; } + virtual bool MouseDragEndMsg(CMouseDragEndMsg *msg) { return false; } + virtual bool MouseButtonUpMsg(CMouseButtonUpMsg *msg) { return false; } + virtual bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { return false; } + virtual bool KeyCharMsg(CKeyCharMsg *msg) { return false; } + virtual bool VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { return false; } + + /** + * Check whether a drag drop can occur + */ + virtual bool checkDragEnd(CGameObject *item) { return false; } + + /** + * Returns item a drag-drop operation has dropped on, if any + */ + virtual CGameObject *dragEnd(const Point &pt) const { return nullptr; } + + /** + * Display a message + */ + virtual void displayMessage(const CString &msg); + + /** + * Returns true if the object is in a valid state + */ + virtual bool isValid(CPetControl *petControl) { return false; } + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file, int param) {} + + /** + * Called after a game has been loaded + */ + virtual void postLoad() {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) {} + + /** + * Called when a section is switched to + */ + virtual void enter(PetArea oldArea) {} + + /** + * Called when a section is being left, to switch to another area + */ + virtual void leave() {} + + virtual void proc23() {} + + /** + * Called when a new room is entered + */ + virtual void enterRoom(CRoomItem *room) {} + + /** + * Called when a previously set up PET timer expires + */ + virtual void timerExpired(int val); + + /** + * Get a reference to the tooltip text associated with the section + */ + virtual CPetText *getText() { return nullptr; } + + /** + * Removes text after a given duration + */ + virtual void removeText(int duration); + + /** + * Removes text after a given duration + */ + virtual void removeText(); + + /** + * Stops the text removal timer + */ + virtual void stopTextTimer(); + + /** + * Get an element from the section by a designated Id + */ + virtual CPetElement *getElement(uint id) { return nullptr; } + + /** + * Special retrieval of glyph background image + */ + virtual CGameObject *getBackground(int index) const { return nullptr; } + + /** + * Display a title for an NPC + */ + virtual void displayNPCName(CGameObject *npc) {} + + virtual void proc33() {} + + /** + * Sets the NPC to use + */ + virtual void setNPC(const CString &name) {} + + /** + * Resets the active NPC + */ + virtual void resetNPC() {} + + /** + * Show the text cursor + */ + virtual void showCursor() {} + + /** + * Hide the text cursor + */ + virtual void hideCursor() {} + + /** + * Highlights a glyph item in the section, if applicable + */ + virtual void highlight(int id) {} + + /** + * Get the PET control + */ + CPetControl *getPetControl() const { return _petControl; } + + /** + * Get a specified color in the currently active UI color table + */ + uint getColor(uint index); + + /** + * Get one of the game's three UI color tables. If the default + * tableNum of -1 is used, the table is taken from the game state + */ + const uint *getColorTable(int tableNum = -1); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_SECTION_H */ diff --git a/engines/titanic/pet_control/pet_slider.cpp b/engines/titanic/pet_control/pet_slider.cpp new file mode 100644 index 0000000000..eb07012f43 --- /dev/null +++ b/engines/titanic/pet_control/pet_slider.cpp @@ -0,0 +1,246 @@ +/* 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 "titanic/pet_control/pet_slider.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +CPetSlider::CPetSlider() { + _orientation = 0; + _thumbWidth = 0; + _thumbHeight = 0; + _sliderOffset = 0; + _thumbFocused = false; +} + +Rect CPetSlider::clearDirtyArea() { + Rect result = _dirtyArea; + _dirtyArea.clear(); + return result; +} + +bool CPetSlider::checkThumb(const Point &pt) { + _thumbFocused = thumbContains(pt); + if (_thumbFocused) + return true; + else + return containsPt(pt); +} + +bool CPetSlider::resetThumbFocus() { + bool result = _thumbFocused; + _thumbFocused = false; + return result; +} + +bool CPetSlider::MouseDragMoveMsg(const Point &pt) { + int newOffset = calcSliderOffset(pt); + setOffsetPixels(newOffset); + return true; +} + +bool CPetSlider::MouseButtonUpMsg(const Point &pt) { + if (thumbContains(pt)) + return true; + if (!containsPt(pt)) + return false; + + int newOffset = calcSliderOffset(pt); + setOffsetPixels(newOffset); + return true; +} + +bool CPetSlider::contains(const Point &pt) const { + return thumbContains(pt) || containsPt(pt); +} + +double CPetSlider::getOffsetPixels() const { + int maxVal = 0, minVal = 0; + if (_orientation & ORIENTATION_HORIZONTAL) { + maxVal = _slidingRect.right; + minVal = _slidingRect.left; + } + + if (_orientation & ORIENTATION_VERTICAL) { + maxVal = _slidingRect.bottom; + minVal = _slidingRect.top; + } + + if (minVal == maxVal) + return 0.0; + + return _sliderOffset / (maxVal - minVal); +} + +void CPetSlider::setSliderOffset(double offset) { + if (_orientation & ORIENTATION_HORIZONTAL) + _sliderOffset = (int)(offset * (_slidingRect.right - _slidingRect.left)); + + if (_orientation & ORIENTATION_VERTICAL) + _sliderOffset = (int)(offset * (_slidingRect.bottom - _slidingRect.top)); +} + +void CPetSlider::setOffsetPixels(int offset) { + // Add the slider's old position to the dirty area + Rect tempRect = getThumbRect(); + _dirtyArea.combine(tempRect); + + // Set the new offset + _sliderOffset = offset; + + // Add the thumb's new location to the dirty area + tempRect = getThumbRect(); + _dirtyArea.combine(tempRect); +} + +Point CPetSlider::getBackgroundDrawPos() { + return Point(_bounds.left, _bounds.top); +} + +Point CPetSlider::getThumbDrawPos() { + Point thumbPos = getThumbCentroidPos(); + thumbPos -= Point(_thumbWidth / 2, _thumbHeight / 2); + return thumbPos; +} + +Point CPetSlider::getThumbCentroidPos() const { + Point pt; + + if (_orientation & ORIENTATION_HORIZONTAL) { + pt = Point(_slidingRect.left + _sliderOffset, + _slidingRect.top + _slidingRect.height() / 2); + } + + if (_orientation & ORIENTATION_VERTICAL) { + pt = Point(_slidingRect.left + _slidingRect.width() / 2, + _slidingRect.top + _sliderOffset); + } + + return pt; +} + +bool CPetSlider::thumbContains(const Point &pt) const { + return getThumbRect().contains(pt); +} + +Rect CPetSlider::getThumbRect() const { + Rect thumbRect(0, 0, _thumbWidth, _thumbHeight); + Point centroid = getThumbCentroidPos(); + thumbRect.moveTo(centroid.x - _thumbWidth / 2, centroid.y - _thumbHeight / 2); + + return thumbRect; +} + +int CPetSlider::calcSliderOffset(const Point &pt) const { + int result = 0; + + if (_orientation & ORIENTATION_HORIZONTAL) { + result = CLIP(pt.x, _slidingRect.left, _slidingRect.right) - _slidingRect.left; + } + + if (_orientation & ORIENTATION_VERTICAL) { + result = CLIP(pt.y, _slidingRect.top, _slidingRect.bottom) - _slidingRect.top; + } + + return result; +} + +void CPetSlider::setOrientation(SliderOrientation orientation) { + _orientation |= orientation; +} + +void CPetSlider::stepPosition(int direction) { + double val = getOffsetPixels(); + + if (direction == -1) { + val = MAX<double>(val - 0.1, 0.0); + } else if (direction == 1) { + val = MIN<double>(val + 0.1, 1.0); + } + + setSliderOffset(val); +} + +/*------------------------------------------------------------------------*/ + +void CPetSoundSlider::setupBackground(const CString &name, CPetControl *petControl) { + if (petControl) { + _background = petControl->getHiddenObject(name); + } +} + +void CPetSoundSlider::setupThumb(const CString &name, CPetControl *petControl) { + if (petControl) { + _thumb = petControl->getHiddenObject(name); + } +} + +void CPetSoundSlider::setupBackground2(const CString &name, CPetControl *petControl) { + if (petControl) { + CString numStr = "3"; + int mode = petControl->getPassengerClass(); + if (mode <= 3) { + numStr = CString(mode); + } else if (mode == 4) { + mode = petControl->getPriorClass(); + if (mode == 1) { + numStr = CString(mode); + } + } + + CString fullName = numStr + name; + setupBackground(fullName, petControl); + } +} + +void CPetSoundSlider::setupThumb2(const CString &name, CPetControl *petControl) { + if (petControl) { + CString numStr = "3"; + int mode = petControl->getPassengerClass(); + if (mode <= 3) { + numStr = CString(mode); + } else if (mode == 4) { + mode = petControl->getPriorClass(); + if (mode == 1) { + numStr = CString(mode); + } + } + + CString fullName = numStr + name; + setupThumb(fullName, petControl); + } +} + +void CPetSoundSlider::draw(CScreenManager *screenManager) { + if (_background) { + Point pt = getBackgroundDrawPos(); + _background->draw(screenManager, pt); + } + + if (_thumb) { + Point pt = getThumbDrawPos(); + _thumb->draw(screenManager, pt); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_slider.h b/engines/titanic/pet_control/pet_slider.h new file mode 100644 index 0000000000..0bc9e825cd --- /dev/null +++ b/engines/titanic/pet_control/pet_slider.h @@ -0,0 +1,239 @@ +/* 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 TITANIC_PET_SLIDER_H +#define TITANIC_PET_SLIDER_H + +#include "titanic/support/rect.h" +#include "titanic/support/string.h" +#include "titanic/core/game_object.h" + +namespace Titanic { + +enum SliderOrientation { ORIENTATION_HORIZONTAL = 1, ORIENTATION_VERTICAL = 2 }; + +class CPetControl; + +class CPetSlider { +private: + int _orientation; + Rect _bounds; + Rect _slidingRect; + int _thumbWidth; + int _thumbHeight; + int _sliderOffset; + bool _thumbFocused; + Rect _dirtyArea; +private: + /** + * Center the center position of the slider's thumb + */ + Point getThumbCentroidPos() const; + + /** + * Returns true if the passed point is within the thumb + */ + bool thumbContains(const Point &pt) const; + + /** + * Gets the area the slider's thumbnail covers + */ + Rect getThumbRect() const; + + /** + * Calculates the slider offset at the specificed position + */ + int calcSliderOffset(const Point &pt) const; +protected: + /** + * Get the position to draw the background at + */ + Point getBackgroundDrawPos(); + + /** + * Get the position to draw the slider thumbnail at + */ + Point getThumbDrawPos(); + + /** + * Returns true if the passed point falls within the slider's bounds + */ + bool containsPt(const Point &pt) const { return _bounds.contains(pt); } +public: + CPetSlider(); + virtual ~CPetSlider() {} + + /** + * Setup the background + */ + virtual void setupBackground(const CString &name, CPetControl *petControl) {} + + /** + * Setup the thumb + */ + virtual void setupThumb(const CString &name, CPetControl *petControl) {} + + /** + * Setup the background + */ + virtual void setupBackground2(const CString &name, CPetControl *petControl) {} + + /** + * Setup the thumb + */ + virtual void setupThumb2(const CString &name, CPetControl *petControl) {} + + /** + * Reset the slider + */ + virtual void reset(const CString &name) {} + + /** + * Draw the slider + */ + virtual void draw(CScreenManager *screenManager) {} + + /** + * Reset the dirty area + */ + virtual Rect clearDirtyArea(); + + /** + * Checks whether the slider is highlighted + */ + virtual bool checkThumb(const Point &pt); + + /** + * Resets the thumb focused flag + */ + virtual bool resetThumbFocus(); + + /** + * Handles dragging the slider + */ + virtual bool MouseDragMoveMsg(const Point &pt); + + /** + * Called when a slider drag ends + */ + virtual bool MouseDragEndMsg(const Point &pt) { return true; } + + /** + * Handles mouse button up messaes + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + virtual bool proc13() { return false; } + virtual bool proc14() { return false; } + + + virtual bool contains(const Point &pt) const; + + /** + * Returns the slider offset in pixels + */ + virtual double getOffsetPixels() const; + + /** + * Sets the slider offset + */ + virtual void setSliderOffset(double offset); + + /** + * Set a new slider offset in pixels + */ + virtual void setOffsetPixels(int offset); + + /** + * Enables a given orientation + */ + void setOrientation(SliderOrientation orientation); + + /** + * Set the bounds for the slider + */ + void setBounds(const Rect &r) { _bounds = r; } + + /** + * Set the sliding bounds for the slider + */ + void setSlidingBounds(const Rect &r) { _slidingRect = r; } + + /** + * Set the size of the slider thumb + */ + void setThumbSize(const Point &pt) { + _thumbWidth = pt.x; + _thumbHeight = pt.y; + } + + /** + * Move the slider + */ + void translate(const Point &pt) { + _bounds.translate(pt.x, pt.y); + _slidingRect.translate(pt.x, pt.y); + } + + /** + * Change the current position of a slider by a step amount + */ + void stepPosition(int direction); +}; + +class CPetSoundSlider : public CPetSlider { +public: + CGameObject *_background; + CGameObject *_thumb; +public: + CPetSoundSlider() : CPetSlider(), _background(nullptr), + _thumb(0) {} + + /** + * Setup the background + */ + virtual void setupBackground(const CString &name, CPetControl *petControl); + + /** + * Setup the thumb + */ + virtual void setupThumb(const CString &name, CPetControl *petControl); + + /** + * Setup the background + */ + virtual void setupBackground2(const CString &name, CPetControl *petControl); + + /** + * Setup the thumb + */ + virtual void setupThumb2(const CString &name, CPetControl *petControl); + + /** + * Draw the slider + */ + virtual void draw(CScreenManager *screenManager); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_SLIDER_H */ diff --git a/engines/titanic/pet_control/pet_sound.cpp b/engines/titanic/pet_control/pet_sound.cpp new file mode 100644 index 0000000000..7bfeb25722 --- /dev/null +++ b/engines/titanic/pet_control/pet_sound.cpp @@ -0,0 +1,282 @@ +/* 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 "titanic/pet_control/pet_sound.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/pet_control/pet_real_life.h" +#include "titanic/game_manager.h" + +namespace Titanic { + +CPetSound::CPetSound() : CPetGlyph(), _draggingSlider(nullptr), _draggingSliderNum(0) { +} + +bool CPetSound::setup(CPetControl *petControl, CPetGlyphs *owner) { + CPetGlyph::setup(petControl, owner); + + _masterVolume.setOrientation(ORIENTATION_HORIZONTAL); + _masterVolume.setBounds(Rect(17, 0, 147, 15)); + _masterVolume.setSlidingBounds(Rect(35, 5, 127, 11)); + _masterVolume.setThumbSize(Point(25, 15)); + _masterVolume.translate(Point(415, 376)); + + _musicVolume.setOrientation(ORIENTATION_HORIZONTAL); + _musicVolume.setBounds(Rect(17, 20, 147, 35)); + _musicVolume.setSlidingBounds(Rect(35, 25, 127, 31)); + _musicVolume.setThumbSize(Point(25, 15)); + _musicVolume.translate(Point(415, 376)); + + _parrotVolume.setOrientation(ORIENTATION_HORIZONTAL); + _parrotVolume.setBounds(Rect(17, 40, 147, 55)); + _parrotVolume.setSlidingBounds(Rect(35, 45, 127, 51)); + _parrotVolume.setThumbSize(Point(25, 15)); + _parrotVolume.translate(Point(415, 376)); + + _parrotVolume.setOrientation(ORIENTATION_HORIZONTAL); + _parrotVolume.setBounds(Rect(17, 60, 147, 75)); + _parrotVolume.setSlidingBounds(Rect(35, 65, 127, 71)); + _parrotVolume.setThumbSize(Point(25, 15)); + _parrotVolume.translate(Point(415, 376)); + + _element.setBounds(Rect(0, 0, 165, 77)); + _element.translate(Point(415, 376)); + + Rect rect(0, 0, 88, 16); + rect.translate(320, 376); + _textMasterVolume.setBounds(rect); + _textMasterVolume.resize(3); + _textMasterVolume.setHasBorder(false); + _textMasterVolume.setText("Master volume"); + + rect.translate(0, 20); + _textMusicVolume.setBounds(rect); + _textMusicVolume.resize(3); + _textMusicVolume.setHasBorder(false); + _textMusicVolume.setText("Music volume"); + + rect.translate(0, 20); + _textParrotVolume.setBounds(rect); + _textParrotVolume.resize(3); + _textParrotVolume.setHasBorder(false); + _textParrotVolume.setText("Parrot volume"); + + rect.translate(0, 20); + _textSpeechVolume.setBounds(rect); + _textSpeechVolume.resize(3); + _textSpeechVolume.setHasBorder(false); + _textSpeechVolume.setText("Speech volume"); + + return true; +} + +bool CPetSound::reset() { + CPetControl *pet = getPetControl(); + if (pet) { + setName("PetSound", pet); + _element.reset("PetVolChannels", pet, MODE_UNSELECTED); + _musicVolume.reset("PetVolSlug"); + _masterVolume.reset("PetVolSlug"); + _parrotVolume.reset("PetVolSlug"); + _speechVolume.reset("PetVolSlug"); + + CPetSection *section = getPetSection(); + uint col = section->getColor(0); + _textMusicVolume.setLineColor(0, col); + _textMasterVolume.setLineColor(0, col); + _textParrotVolume.setLineColor(0, col); + _textSpeechVolume.setLineColor(0, col); + } + + return false; +} + +void CPetSound::draw2(CScreenManager *screenManager) { + _element.draw(screenManager); + + _musicVolume.draw(screenManager); + _masterVolume.draw(screenManager); + _parrotVolume.draw(screenManager); + _speechVolume.draw(screenManager); + + _textMusicVolume.draw(screenManager); + _textMasterVolume.draw(screenManager); + _textParrotVolume.draw(screenManager); + _textSpeechVolume.draw(screenManager); +} + +bool CPetSound::MouseButtonDownMsg(const Point &pt) { + if (_musicVolume.checkThumb(pt) || _masterVolume.checkThumb(pt) || + _speechVolume.checkThumb(pt)) + return true; + + if (_parrotVolume.checkThumb(pt)) { + CPetControl *pet = getPetControl(); + if (pet) + pet->playSound(2); + + return true; + } + + Rect rectLeft(0, 0, 10, 11); + Rect rectRight(0, 0, 10, 11); + rectLeft.translate(415, 379); + rectRight.translate(567, 378); + + CPetSlider *sliders[4] = { &_masterVolume, &_musicVolume, &_parrotVolume, &_speechVolume }; + for (int idx = 0; idx < 4; ++idx) { + CPetSlider *slider = sliders[idx]; + bool isLeft = rectLeft.contains(pt); + bool isRight = rectRight.contains(pt); + double offset; + + if (isLeft) { + slider->stepPosition(-1); + offset = slider->getOffsetPixels(); + } else if (isRight) { + slider->stepPosition(1); + offset = slider->getOffsetPixels(); + } + + if (isLeft || isRight) { + sliderChanged(offset, idx); + return true; + } + + // Move to next slider row + rectLeft.translate(0, 20); + rectRight.translate(0, 20); + } + + return false; +} + +void CPetSound::sliderChanged(double offset, int sliderNum) { + CPetControl *pet = getPetControl(); + if (!pet) + return; + + CGameManager *gameManager = pet->getGameManager(); + if (!gameManager) + return; + + QSoundManager &soundManager = gameManager->_sound._soundManager; + double percent = offset * 100.0; + + switch (sliderNum) { + case 0: + soundManager.setMasterPercent(percent); + break; + case 1: + soundManager.setMusicPercent(percent); + break; + case 2: + soundManager.setParrotPercent(percent); + break; + case 3: + soundManager.setSpeechPercent(percent); + break; + default: + break; + } +} + +bool CPetSound::MouseDragStartMsg(CMouseDragStartMsg *msg) { + if (_musicVolume.resetThumbFocus()) { + _draggingSlider = &_musicVolume; + getOwner()->startDragging(this, msg); + _draggingSliderNum = 0; + return true; + } else if (_masterVolume.resetThumbFocus()) { + _draggingSlider = &_masterVolume; + getOwner()->startDragging(this, msg); + _draggingSliderNum = 1; + return true; + } else if (_parrotVolume.resetThumbFocus()) { + _draggingSlider = &_parrotVolume; + getOwner()->startDragging(this, msg); + _draggingSliderNum = 2; + return true; + } else if (_speechVolume.resetThumbFocus()) { + _draggingSlider = &_speechVolume; + getOwner()->startDragging(this, msg); + _draggingSliderNum = 3; + return true; + } + + _draggingSlider = nullptr; + return false; +} + +bool CPetSound::MouseDragMoveMsg(CMouseDragMoveMsg *msg) { + if (!_draggingSlider) + return false; + + if (_draggingSlider->MouseDragMoveMsg(msg->_mousePos)) { + double offset = _draggingSlider->getOffsetPixels(); + sliderChanged(offset, _draggingSliderNum); + getPetControl()->makeDirty(); + return true; + } + + return false; +} + +bool CPetSound::MouseDragEndMsg(CMouseDragEndMsg *msg) { + if (!_draggingSlider) + return false; + + _draggingSlider->MouseDragEndMsg(msg->_mousePos); + getOwner()->endDragging(); + + return false; +} + +bool CPetSound::MouseButtonUpMsg(const Point &pt) { + int sliderNum = 0; + CPetSlider *slider = nullptr; + + if (_musicVolume.MouseButtonUpMsg(pt)) { + sliderNum = 0; + slider = &_musicVolume; + } else if (_masterVolume.MouseButtonUpMsg(pt)) { + sliderNum = 1; + slider = &_masterVolume; + } else if (_parrotVolume.MouseButtonUpMsg(pt)) { + sliderNum = 2; + slider = &_parrotVolume; + } else if (_speechVolume.MouseButtonUpMsg(pt)) { + sliderNum = 3; + slider = &_speechVolume; + } else { + return false; + } + + double offset = slider->getOffsetPixels(); + sliderChanged(offset, sliderNum); + return true; +} + +void CPetSound::getTooltip(CPetText *text) { + text->setText("Change the volume settings."); +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_sound.h b/engines/titanic/pet_control/pet_sound.h new file mode 100644 index 0000000000..c4b663ad44 --- /dev/null +++ b/engines/titanic/pet_control/pet_sound.h @@ -0,0 +1,104 @@ +/* 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 TITANIC_PET_SOUND_H +#define TITANIC_PET_SOUND_H + +#include "titanic/pet_control/pet_glyphs.h" +#include "titanic/pet_control/pet_gfx_element.h" +#include "titanic/pet_control/pet_text.h" +#include "titanic/pet_control/pet_slider.h" + +namespace Titanic { + +class CPetRealLife; + +class CPetSound : public CPetGlyph { +private: + CPetGfxElement _element; + CPetSlider _masterVolume; + CPetSlider _musicVolume; + CPetSlider _parrotVolume; + CPetSlider _speechVolume; + CPetText _textMasterVolume; + CPetText _textMusicVolume; + CPetText _textParrotVolume; + CPetText _textSpeechVolume; + CPetSlider *_draggingSlider; + int _draggingSliderNum; +private: + /** + * Called when a slider has changed + */ + void sliderChanged(double offset, int sliderNum); +public: + CPetSound(); + + /** + * Setup the glyph + */ + virtual bool setup(CPetControl *petControl, CPetGlyphs *owner); + + /** + * Reset the glyph + */ + virtual bool reset(); + + /** + * Handles any secondary drawing of the glyph + */ + virtual void draw2(CScreenManager *screenManager); + + /** + * Called for mouse button down messages + */ + virtual bool MouseButtonDownMsg(const Point &pt); + + /** + * Called when mouse drag starts + */ + virtual bool MouseDragStartMsg(CMouseDragStartMsg *msg); + + /** + * Called during mouse drags + */ + virtual bool MouseDragMoveMsg(CMouseDragMoveMsg *msg); + + /** + * Called when mouse drag ends + */ + virtual bool MouseDragEndMsg(CMouseDragEndMsg *msg); + + /** + * Handles mouse button up messages + */ + virtual bool MouseButtonUpMsg(const Point &pt); + + /** + * Returns the tooltip text for when the glyph is selected + */ + virtual void getTooltip(CPetText *text); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_SOUND_H */ diff --git a/engines/titanic/pet_control/pet_starfield.cpp b/engines/titanic/pet_control/pet_starfield.cpp new file mode 100644 index 0000000000..34d696e09c --- /dev/null +++ b/engines/titanic/pet_control/pet_starfield.cpp @@ -0,0 +1,257 @@ +/* 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 "titanic/pet_control/pet_starfield.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/messages/pet_messages.h" +#include "titanic/star_control/star_control.h" + +namespace Titanic { + +CPetStarfield::CPetStarfield() : _field18C(0), _photoOn(true), + _hasReference(false), _rect1(22, 352, 598, 478) { + _btnOffsets[0] = _btnOffsets[1] = _btnOffsets[2] = 0; +} + +bool CPetStarfield::setup(CPetControl *petControl) { + if (petControl && setupControl(petControl)) + return reset(); + return false; +} + +bool CPetStarfield::reset() { + if (_petControl) { + _imgStarfield.setup(MODE_UNSELECTED, "3PetStarField", _petControl); + _imgPhoto.setup(MODE_UNSELECTED, "HomePhotoOnOff", _petControl); + _btnSetDest.setup(MODE_UNSELECTED, "3PetSetDestin", _petControl); + _btnSetDest.setup(MODE_SELECTED, "3PetSetDestin1", _petControl); + _imgStarCtrl.setup(MODE_UNSELECTED, "3PetStarCtrl", _petControl); + + _leds[0].setup(MODE_UNSELECTED, "LEDOff1", _petControl); + _leds[1].setup(MODE_UNSELECTED, "LEDOn1", _petControl); + _leds[2].setup(MODE_UNSELECTED, "LEDOff2", _petControl); + _leds[3].setup(MODE_UNSELECTED, "LEDOn2", _petControl); + _leds[4].setup(MODE_UNSELECTED, "LEDOff3", _petControl); + _leds[5].setup(MODE_UNSELECTED, "LEDOn3", _petControl); + + uint col = getColor(0); + _text.setColor(col); + _text.setLineColor(0, col); + } + + return true; +} + +void CPetStarfield::draw(CScreenManager *screenManager) { + _petControl->drawSquares(screenManager, 2); + + _imgStarfield.draw(screenManager); + if (_photoOn) { + _imgPhoto.draw(screenManager); + } else { + _imgStarCtrl.draw(screenManager); + } + + _btnSetDest.draw(screenManager); + drawButton(_btnOffsets[0], 0, screenManager); + drawButton(_btnOffsets[1], 2, screenManager); + drawButton(_btnOffsets[2], 4, screenManager); + _text.draw(screenManager); +} + +bool CPetStarfield::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if (!_petControl->_remoteTarget) + return false; + + if (_imgStarfield.MouseButtonDownMsg(msg->_mousePos)) { + CPETHelmetOnOffMsg helmetMsg; + helmetMsg.execute(_petControl->_remoteTarget); + } else if (_imgPhoto.MouseButtonDownMsg(msg->_mousePos)) { + if (_hasReference) { + _photoOn = !_photoOn; + CPETPhotoOnOffMsg photoMsg; + photoMsg.execute(_petControl->_remoteTarget); + } else { + _petControl->displayMessage("Please supply Galactic reference material."); + } + } else if (!_btnSetDest.MouseButtonDownMsg(msg->_mousePos)) { + return elementsMouseDown(msg); + } + + return true; +} + +bool CPetStarfield::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + if (!_petControl->_remoteTarget || !_btnSetDest.MouseButtonUpMsg(msg->_mousePos)) + return false; + + if (_petControl) { + CStarControl *starControl = _petControl->getStarControl(); + + if (starControl && starControl->canSetStarDestination()) { + CPETSetStarDestinationMsg starfieldMsg; + starfieldMsg.execute(_petControl->_remoteTarget); + starControl->starDestinationSet(); + } + } + + return true; +} + +bool CPetStarfield::isValid(CPetControl *petControl) { + return setupControl(petControl); +} + +void CPetStarfield::load(SimpleFile *file, int param) { + if (!param) { + _photoOn = file->readNumber(); + _hasReference = file->readNumber(); + } +} + +void CPetStarfield::postLoad() { + reset(); +} + +void CPetStarfield::save(SimpleFile *file, int indent) { + file->writeNumberLine(_photoOn, indent); + file->writeNumberLine(_hasReference, indent); +} + +bool CPetStarfield::setupControl(CPetControl *petControl) { + if (petControl) { + _petControl = petControl; + + Rect r(0, 0, 64, 64); + r.translate(_rect1.left, _rect1.top); + + _imgStarfield.setBounds(r); + _imgStarfield.translate(15, 23); + _imgPhoto.setBounds(r); + _imgPhoto.translate(85, 23); + _imgStarCtrl.setBounds(r); + _imgStarCtrl.translate(85, 23); + + r = Rect(0, 0, 34, 34); + r.translate(468, 396); + _leds[0].setBounds(r); + _leds[1].setBounds(r); + + r.translate(36, 0); + _leds[2].setBounds(r); + _leds[3].setBounds(r); + + r.translate(36, 0); + _leds[4].setBounds(r); + _leds[5].setBounds(r); + + r = Rect(0, 0, 157, 51); + r.translate(224, 33); + r.translate(20, 350); + _btnSetDest.setBounds(r); + + r = Rect(0, 0, 580, 15); + r.translate(32, 445); + _text.setBounds(r); + _text.setHasBorder(false); + } + + return true; +} + +void CPetStarfield::drawButton(int offset, int index, CScreenManager *screenManager) { + if (_field18C < 4 && (offset / 3) == 1) + --offset; + if (offset == 2) + offset = 1; + + _leds[index + offset].draw(screenManager); +} + +void CPetStarfield::setButtons(int val1, int val2) { + _btnOffsets[0] = 0; + _btnOffsets[1] = 0; + _btnOffsets[2] = 0; + + if (val1 >= 0) + _btnOffsets[0] = 2; + if (val1 >= 1) + _btnOffsets[1] = 2; + if (val1 >= 2) + _btnOffsets[2] = 2; + + if (val2) { + if (val1 == -1) + _btnOffsets[0] = 1; + if (val1 == 0) + _btnOffsets[1] = 1; + if (val1 == 1) + _btnOffsets[2] = 1; + } + + _field18C = (_field18C + 1) % 8; +} + +void CPetStarfield::makePetDirty() { + _petControl->makeDirty(); +} + +bool CPetStarfield::elementsMouseDown(CMouseButtonDownMsg *msg) { + if (elementMouseButton(0, msg, _leds[0].getBounds())) + return true; + if (elementMouseButton(1, msg, _leds[2].getBounds())) + return true; + if (elementMouseButton(2, msg, _leds[4].getBounds())) + return true; + + return false; +} + +bool CPetStarfield::elementMouseButton(int index, CMouseButtonDownMsg *msg, const Rect &rect) { + if (!rect.contains(msg->_mousePos)) + return false; + + switch (_btnOffsets[index]) { + case 1: + if (_petControl->_remoteTarget) { + CPETStarFieldLockMsg lockMsg(1); + lockMsg.execute(_petControl->_remoteTarget); + } + break; + + case 2: + if (index < 2 && _btnOffsets[index] >= 2) { + if (_petControl->_remoteTarget) { + CPETStarFieldLockMsg lockMsg(1); + lockMsg.execute(_petControl->_remoteTarget); + } + } + break; + + default: + break; + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_starfield.h b/engines/titanic/pet_control/pet_starfield.h new file mode 100644 index 0000000000..9550e0acf9 --- /dev/null +++ b/engines/titanic/pet_control/pet_starfield.h @@ -0,0 +1,125 @@ +/* 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 TITANIC_PET_STARFIELD_H +#define TITANIC_PET_STARFIELD_H + +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_text.h" +#include "titanic/pet_control/pet_gfx_element.h" + +namespace Titanic { + +class CPetStarfield : public CPetSection { +private: + CPetGfxElement _imgStarfield; + CPetGfxElement _imgPhoto; + CPetGfxElement _imgStarCtrl; + CPetGfxElement _btnSetDest; + int _btnOffsets[3]; + CPetGfxElement _leds[6]; + Rect _rect1; + int _field18C; + CPetText _text; + bool _photoOn; + bool _hasReference; +private: + /** + * Setup the control + */ + bool setupControl(CPetControl *petControl); + + /** + * Draw a button + */ + void drawButton(int offset, int index, CScreenManager *screenManager); + + /** + * Mouse down handling for Nav elements + */ + bool elementsMouseDown(CMouseButtonDownMsg *msg); + + bool elementMouseButton(int index, CMouseButtonDownMsg *msg, const Rect &rect); +public: + CPetStarfield(); + + /** + * Sets up the section + */ + virtual bool setup(CPetControl *petControl); + + /** + * Reset the section + */ + virtual bool reset(); + + /** + * Draw the section + */ + virtual void draw(CScreenManager *screenManager); + + /** + * Following are handlers for the various messages that the PET can + * pass onto the currently active section/area + */ + virtual bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + virtual bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); + + /** + * Returns true if the object is in a valid state + */ + virtual bool isValid(CPetControl *petControl); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file, int param); + + /** + * Called after a game has been loaded + */ + virtual void postLoad(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Sets the offsets for each of the buttons + */ + void setButtons(int val1, int val2); + + /** + * Sets whether the player has the galactic reference material + */ + void setHasReference(bool hasRef) { _hasReference = hasRef; } + + /** + * Make the PET as dirty, requiring a redraw + */ + void makePetDirty(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_STARFIELD_H */ diff --git a/engines/titanic/pet_control/pet_text.cpp b/engines/titanic/pet_control/pet_text.cpp new file mode 100644 index 0000000000..6813095626 --- /dev/null +++ b/engines/titanic/pet_control/pet_text.cpp @@ -0,0 +1,478 @@ +/* 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(0), you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation(0), 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(0), 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(0), if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/pet_control/pet_text.h" + +namespace Titanic { + +CPetText::CPetText(uint count) : + _stringsMerged(false), _maxCharsPerLine(-1), _lineCount(0), + _linesStart(-1), _field3C(0), _field40(0), _field44(0), + _backR(0xff), _backG(0xff), _backB(0xff), + _textR(0), _textG(0), _textB(200), + _fontNumber(0), _field64(0), _field68(0), _field6C(0), + _hasBorder(true), _scrollTop(0), _textCursor(nullptr), _field7C(0) { + setupArrays(count); +} + +void CPetText::setupArrays(int count) { + freeArrays(); + if (count < 10 || count > 60) + count = 10; + _array.resize(count); +} + +void CPetText::freeArrays() { + _array.clear(); +} + +void CPetText::setup() { + for (int idx = 0; idx < (int)_array.size(); ++idx) { + _array[idx]._line.clear(); + setLineColor(idx, _textR, _textG, _textB); + _array[idx]._string3.clear(); + } + + _lineCount = 0; + _stringsMerged = false; +} + +void CPetText::setLineColor(uint lineNum, uint col) { + setLineColor(lineNum, col & 0xff, (col >> 16) & 0xff, (col >> 8) & 0xff); +} + +void CPetText::setLineColor(uint lineNum, byte r, byte g, byte b) { + char buffer[6]; + if (!r) + r = 1; + if (!g) + g = 1; + if (!b) + b = 1; + + buffer[0] = TEXTCMD_SET_COLOR; + buffer[1] = r; + buffer[2] = g; + buffer[3] = b; + buffer[4] = TEXTCMD_SET_COLOR; + buffer[5] = '\0'; + _array[lineNum]._rgb = buffer; + + _stringsMerged = false; +} + +void CPetText::load(SimpleFile *file, int param) { + if (!param) { + uint numLines = file->readNumber(); + uint charsPerLine = file->readNumber(); + uint count = file->readNumber(); + _bounds = file->readRect(); + _field3C = file->readNumber(); + _field40 = file->readNumber(); + _field44 = file->readNumber(); + _backR = file->readNumber(); + _backG = file->readNumber(); + _backB = file->readNumber(); + _textR = file->readNumber(); + _textG = file->readNumber(); + _textB = file->readNumber(); + _hasBorder = file->readNumber() != 0; + _scrollTop = file->readNumber(); + + resize(numLines); + setMaxCharsPerLine(charsPerLine); + + assert(_array.size() >= count); + for (uint idx = 0; idx < count; ++idx) { + _array[idx]._line = file->readString(); + _array[idx]._rgb = file->readString(); + _array[idx]._string3 = file->readString(); + } + } +} + +void CPetText::save(SimpleFile *file, int indent) { + int numLines = _lineCount + 1; + + file->writeNumberLine(_array.size(), indent); + file->writeNumberLine(_maxCharsPerLine, indent); + file->writeNumberLine(numLines, indent); + + file->writeRect(_bounds, indent); + file->writeNumberLine(_field3C, indent); + file->writeNumberLine(_field40, indent); + file->writeNumberLine(_field44, indent); + file->writeNumberLine(_backR, indent); + file->writeNumberLine(_backG, indent); + file->writeNumberLine(_backB, indent); + file->writeNumberLine(_textR, indent); + file->writeNumberLine(_textG, indent); + file->writeNumberLine(_textB, indent); + file->writeNumberLine(_hasBorder, indent); + file->writeNumberLine(_scrollTop, indent); + + for (int idx = 0; idx < numLines; ++idx) { + file->writeQuotedLine(_array[idx]._line, indent); + file->writeQuotedLine(_array[idx]._rgb, indent); + file->writeQuotedLine(_array[idx]._string3, indent); + } +} + +void CPetText::draw(CScreenManager *screenManager) { + Rect tempRect = _bounds; + + if (_hasBorder) { + // Create border effect + // Top edge + tempRect.bottom = tempRect.top + 1; + screenManager->fillRect(SURFACE_BACKBUFFER, &tempRect, _backR, _backG, _backB); + + // Bottom edge + tempRect.top = _bounds.bottom - 1; + tempRect.bottom = _bounds.bottom; + screenManager->fillRect(SURFACE_BACKBUFFER, &tempRect, _backR, _backG, _backB); + + // Left edge + tempRect = _bounds; + tempRect.right = tempRect.left + 1; + screenManager->fillRect(SURFACE_BACKBUFFER, &tempRect, _backR, _backG, _backB); + + // Right edge + tempRect = _bounds; + tempRect.left = tempRect.right - 1; + screenManager->fillRect(SURFACE_BACKBUFFER, &tempRect, _backR, _backG, _backB); + } + + getTextHeight(screenManager); + + tempRect = _bounds; + tempRect.grow(-2); + int oldFontNumber = screenManager->setFontNumber(_fontNumber); + + screenManager->writeString(SURFACE_BACKBUFFER, tempRect, _scrollTop, _lines, _textCursor); + + screenManager->setFontNumber(oldFontNumber); +} + +void CPetText::mergeStrings() { + if (!_stringsMerged) { + _lines.clear(); + + for (int idx = 0; idx <= _lineCount; ++idx) { + CString line = _array[idx]._rgb + _array[idx]._string3 + + _array[idx]._line + "\n"; + _lines += line; + } + + _stringsMerged = true; + } +} + +void CPetText::resize(uint count) { + if (!count || _array.size() == count) + return; + _array.clear(); + _array.resize(count); +} + +CString CPetText::getText() const { + CString result = ""; + for (int idx = 0; idx <= _lineCount; ++idx) + result += _array[idx]._line; + + return result; +} + +void CPetText::setText(const CString &str) { + setup(); + appendText(str); +} + +void CPetText::appendText(const CString &str) { + int lineSize = _array[_lineCount]._line.size(); + int strSize = str.size(); + + if (_maxCharsPerLine == -1) { + // No limit on horizontal characters, so append string to current line + _array[_lineCount]._line += str; + } else if ((lineSize + strSize) <= _maxCharsPerLine) { + // New string fits into line, so add it on + _array[_lineCount]._line += str; + } else { + // Only add part of the str up to the maximum allowed limit for line + _array[_lineCount]._line += str.left(_maxCharsPerLine - lineSize); + } + + updateStr3(_lineCount); + _stringsMerged = false; +} + +void CPetText::setColor(uint col) { + _textR = col & 0xff; + _textG = (col >> 8) & 0xff; + _textB = (col >> 16) & 0xff; +} + +void CPetText::setColor(byte r, byte g, byte b) { + _textR = r; + _textG = g; + _textB = b; +} + +void CPetText::remapColors(uint count, uint *srcColors, uint *destColors) { + if (_lineCount >= 0) { + for (int lineNum = 0; lineNum <= _lineCount; ++lineNum) { + // Get the rgb values + uint r = _array[lineNum]._rgb[1]; + uint g = _array[lineNum]._rgb[2]; + uint b = _array[lineNum]._rgb[3]; + uint color = r | (g << 8) | (b << 16); + + for (uint index = 0; index < count; ++index) { + if (color == srcColors[index]) { + // Found a match, so replace the color + setLineColor(lineNum, destColors[lineNum]); + break; + } + } + } + } + + _stringsMerged = false; +} + +void CPetText::setMaxCharsPerLine(int maxChars) { + if (maxChars >= -1 && maxChars < 257) + _maxCharsPerLine = maxChars; +} + +void CPetText::updateStr3(int lineNum) { + if (_field64 > 0 && _field68 > 0) { + char line[5]; + line[0] = line[3] = TEXTCMD_NPC; + line[1] = _field64; + line[2] = _field68; + line[4] = '\0'; + _array[lineNum]._string3 = CString(line); + + _stringsMerged = false; + _field64 = _field68 = 0; + } +} + +int CPetText::getTextWidth(CScreenManager *screenManager) { + mergeStrings(); + int oldFontNumber = screenManager->setFontNumber(_fontNumber); + int textWidth = screenManager->stringWidth(_lines); + screenManager->setFontNumber(oldFontNumber); + + return textWidth; +} + +int CPetText::getTextHeight(CScreenManager *screenManager) { + mergeStrings(); + int oldFontNumber = screenManager->setFontNumber(_fontNumber); + int textHeight = screenManager->getTextBounds(_lines, _bounds.width()); + screenManager->setFontNumber(oldFontNumber); + + return textHeight; +} + +void CPetText::deleteLastChar() { + if (!_array[_lineCount]._line.empty()) { + _array[_lineCount]._line.deleteLastChar(); + _stringsMerged = false; + } +} + +void CPetText::setNPC(int val1, int npcId) { + _field64 = val1; + _field68 = npcId; +} + +void CPetText::scrollUp(CScreenManager *screenManager) { + int oldFontNumber = screenManager->setFontNumber(_fontNumber); + _scrollTop -= screenManager->getFontHeight(); + constrainScrollUp(screenManager); + screenManager->setFontNumber(oldFontNumber); +} + +void CPetText::scrollDown(CScreenManager *screenManager) { + int oldFontNumber = screenManager->setFontNumber(_fontNumber); + _scrollTop += screenManager->getFontHeight(); + constrainScrollDown(screenManager); + screenManager->setFontNumber(oldFontNumber); +} + +void CPetText::scrollUpPage(CScreenManager *screenManager) { + int oldFontNumber = screenManager->setFontNumber(_fontNumber); + _scrollTop -= getPageHeight(screenManager); + constrainScrollUp(screenManager); + screenManager->setFontNumber(oldFontNumber); +} + +void CPetText::scrollDownPage(CScreenManager *screenManager) { + int oldFontNumber = screenManager->setFontNumber(_fontNumber); + _scrollTop += getPageHeight(screenManager); + constrainScrollDown(screenManager); + screenManager->setFontNumber(oldFontNumber); +} + +void CPetText::scrollToTop(CScreenManager *screenManager) { + _scrollTop = 0; +} + +void CPetText::scrollToBottom(CScreenManager *screenManager) { + int oldFontNumber = screenManager->setFontNumber(_fontNumber); + _scrollTop = getTextHeight(screenManager); + constrainScrollDown(screenManager); + screenManager->setFontNumber(oldFontNumber); +} + +void CPetText::constrainScrollUp(CScreenManager *screenManager) { + if (_scrollTop < 0) + _scrollTop = 0; +} + +void CPetText::constrainScrollDown(CScreenManager *screenManager) { + // Figure out the maximum scroll amount allowed + int maxScroll = getTextHeight(screenManager) - _bounds.height() - 4; + if (maxScroll < 0) + maxScroll = 0; + + if (_scrollTop > maxScroll) + _scrollTop = maxScroll; +} + +int CPetText::getPageHeight(CScreenManager *screenManager) { + int textHeight = _bounds.height(); + int oldFontNumber = screenManager->setFontNumber(_fontNumber); + int fontHeight = screenManager->getFontHeight(); + screenManager->setFontNumber(oldFontNumber); + + if (fontHeight) { + int lines = textHeight / fontHeight; + if (lines > 1) + --lines; + return lines * fontHeight; + } else { + return 0; + } +} + +void CPetText::addLine(const CString &str) { + addLine(str, _textR, _textG, _textB); +} + +void CPetText::addLine(const CString &str, uint color) { + addLine(str, color & 0xff, (color >> 8) & 0xff, + (color >> 16) & 0xff); +} + +void CPetText::addLine(const CString &str, byte r, byte g, byte b) { + if (_lineCount == ((int)_array.size() - 1)) { + // Lines array is full + if (_array.size() > 1) { + // Delete the oldest line, and add a new entry at the end + _array.remove_at(0); + _array.resize(_array.size() + 1); + } + + --_lineCount; + } + + setLineColor(_lineCount, r, g, b); + appendText(str); + ++_lineCount; +} + +bool CPetText::handleKey(char c) { + switch (c) { + case (char)Common::KEYCODE_BACKSPACE: + deleteLastChar(); + break; + + case (char)Common::KEYCODE_RETURN: + return true; + + default: + if ((byte)c >= 32 && (byte)c <= 127) + appendText(CString(c, 1)); + break; + } + + return false; +} + +void CPetText::showCursor(int mode) { + CScreenManager *screenManager = CScreenManager::setCurrent(); + _textCursor = screenManager->_textCursor; + if (_textCursor) { + _textCursor->setPos(Point(0, 0)); + _textCursor->setSize(Point(2, 10)); + _textCursor->setColor(0, 0, 0); + _textCursor->setBlinkRate(300); + _textCursor->setMode(mode); + _textCursor->setBounds(_bounds); + _textCursor->show(); + } +} + +void CPetText::hideCursor() { + if (_textCursor) { + _textCursor->setMode(-1); + _textCursor->hide(); + _textCursor = nullptr; + } +} + +int CPetText::getNPCNum(uint npcId, uint startIndex) { + if (!_stringsMerged) { + mergeStrings(); + if (!_stringsMerged) + return -1; + } + + uint size = _lines.size(); + if (startIndex < 5 || startIndex >= size) + return -1; + + // Loop through string + for (const char *strP = _lines.c_str(); size >= 5; ++strP, --size) { + if (*strP == 26) { + byte id = *(strP - 2); + if (id == npcId) + return *(strP - 1); + } else if (*strP == 27) { + strP += 4; + } + } + + return - 1; +} + +void CPetText::setFontNumber(int fontNumber) { + if (fontNumber >= 0 && fontNumber <= 2) + _fontNumber = fontNumber; +} + +} // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_text.h b/engines/titanic/pet_control/pet_text.h new file mode 100644 index 0000000000..f5d4235690 --- /dev/null +++ b/engines/titanic/pet_control/pet_text.h @@ -0,0 +1,270 @@ +/* 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 TITANIC_PET_TEXT_H +#define TITANIC_PET_TEXT_H + +#include "common/keyboard.h" +#include "titanic/support/simple_file.h" +#include "titanic/support/screen_manager.h" +#include "titanic/support/text_cursor.h" + +namespace Titanic { + +class CPetText { + struct ArrayEntry { + CString _line; + CString _rgb; + CString _string3; + }; +private: + Common::Array<ArrayEntry> _array; + CString _lines; + bool _stringsMerged; + Rect _bounds; + int _maxCharsPerLine; + int _lineCount; + int _linesStart; + int _field3C; + int _field40; + int _field44; + int _backR; + int _backG; + int _backB; + int _textR; + int _textG; + int _textB; + int _fontNumber; + int _field64; + int _field68; + int _field6C; + bool _hasBorder; + int _scrollTop; + CTextCursor *_textCursor; + int _field7C; +private: + void setupArrays(int count); + + void freeArrays(); + + /** + * Merges the strings in the strings array + */ + void mergeStrings(); + + /** + * Append text to the current text line + */ + void appendText(const CString &str); + + void updateStr3(int lineNum); + + /** + * Ensures the Y scrolling for the text is in the valid range + */ + void constrainScrollUp(CScreenManager *screenManager); + + /** + * Ensures the Y scrolling for the text is in the valid range + */ + void constrainScrollDown(CScreenManager *screenManager); + + /** + * Get the page height for paging up and down + */ + int getPageHeight(CScreenManager *screenManager); +public: + CPetText(uint count = 10); + + /** + * Set up the control + */ + void setup(); + + /** + * Load the data for the control + */ + void load(SimpleFile *file, int param); + + /** + * Save the data for the control + */ + void save(SimpleFile *file, int indent); + + /** + * Set the bounds for the control + */ + void setBounds(const Rect &bounds) { _bounds = bounds; } + + /** + * Sets the flag for whether to draw a frame border around the control + */ + void setHasBorder(bool val) { _hasBorder = val; } + + /** + * Draw the control + */ + void draw(CScreenManager *screenManager); + + void resize(uint count); + + /** + * Returns the text from all the lines as a single string + */ + CString getText() const; + + /** + * Set the text + */ + void setText(const CString &str); + + /** + * Set text color + */ + void setColor(uint col); + + /** + * Set text color + */ + void setColor(byte r, byte g, byte b); + + /** + * Set the color for a line + */ + void setLineColor(uint lineNum, byte r, byte g, byte b); + + /** + * Set the color for a line + */ + void setLineColor(uint lineNum, uint col); + + /** + * Sets the maximum number of characters per line + */ + void setMaxCharsPerLine(int maxChars); + + /** + * Delete the last character from the last line + */ + void deleteLastChar(); + + void setNPC(int val1, int npcId); + + /** + * Get the index into _lines where on-screen text starts + */ + int getLinesStart() const { return _linesStart; } + + /** + * Scroll the text up + */ + void scrollUp(CScreenManager *screenManager); + + /** + * Scroll the text down + */ + void scrollDown(CScreenManager *screenManager); + + /** + * Scroll the text up one page + */ + void scrollUpPage(CScreenManager *screenManager); + + /** + * Scroll the text down one page + */ + void scrollDownPage(CScreenManager *screenManager); + + /** + * Scroll to the top of the text + */ + void scrollToTop(CScreenManager *screenManager); + + /** + * Scroll to the bottom of the text + */ + void scrollToBottom(CScreenManager *screenManager); + + /** + * Add a line to the text + */ + void addLine(const CString &str); + + /** + * Add a line to the text + */ + void addLine(const CString &str, uint color); + + /** + * Add a line to the text + */ + void addLine(const CString &str, byte r, byte g, byte b); + + /** + * Handles character processing to add or remove characters to + * the current text line + * @returns True if the Enter key was pressed + */ + bool handleKey(char c); + + /** + * Attaches the current system cursor to the text control, + * and give it suitable defaults + */ + void showCursor(int mode); + + /** + * Removes the cursor attached to the text + */ + void hideCursor(); + + /** + * Get an NPC Number embedded within on-screen text. + * Used by the PET log to encode which NPC spoke + */ + int getNPCNum(uint npcId, uint startIndex); + + /** + * Replaces any occurances of line colors that appear in the + * first list with the entry at the same index in the dest list + */ + void remapColors(uint count, uint *srcColors, uint *destColors); + + /** + * Set the font number to use + */ + void setFontNumber(int fontNumber); + + /** + * Get the width of the text + */ + int getTextWidth(CScreenManager *screenManager); + + /** + * Get the required height to draw the text + */ + int getTextHeight(CScreenManager *screenManager); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PET_TEXT_H */ diff --git a/engines/titanic/room_flags.cpp b/engines/titanic/room_flags.cpp new file mode 100644 index 0000000000..4b3aeb424e --- /dev/null +++ b/engines/titanic/room_flags.cpp @@ -0,0 +1,527 @@ +/* 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 "titanic/room_flags.h" +#include "titanic/titanic.h" + +namespace Titanic { + +#define ELEVATOR_SHIFT 18 +#define ELEVATOR_MASK 3 +#define PASSENGER_CLASS_SHIFT 16 +#define PASSENGER_CLASS_MASK 3 +#define FLOOR_SHIFT 8 +#define FLOOR_MASK 0xFF +#define ROOM_SHIFT 1 +#define ROOM_MASK 0x7F + +struct TransportFlagsEntry { + const char *const _roomName; + uint _roomFlags; +}; +struct SuccUBusFlagsEntry { + const char *const _roomName; + uint _roomFlags; + uint _succubusNum; +}; + +#define TRANSPORT_ROOMS_SIZE 6 +const TransportFlagsEntry TRANSPORT_ROOMS[TRANSPORT_ROOMS_SIZE] = { + { "TopOfWell", 0xDF4D1 }, + { "Pellerator", 0xC95E9 }, + { "Dome", 0xAD171 }, + { "Lift", 0x96E45 }, + { "SGTLeisure", 0x5D3AD }, + { "ServiceElevator", 0x68797 } +}; + +#define SUCCUBUS_ROOMS_SIZE 17 +const SuccUBusFlagsEntry SUCCUBUS_ROOMS[SUCCUBUS_ROOMS_SIZE] = { + { "ParrotLobby", 0x1D0D9, 3 }, + { "SculptureChamber", 0x465FB, 2 }, + { "Bar", 0x0B3D97, 2 }, + { "EmbLobby", 0x0CC971, 3 }, + { "MoonEmbLobby", 0x0CC971, 3 }, + { "MusicRoom", 0x0F34DB, 2 }, + { "MusicRoomLobby", 0x0F34DB, 2 }, + { "Titania", 0x8A397, 3 }, + { "BottomOfWell", 0x59FAD, 3 }, + { "Arboretum", 0x4D6AF, 1 }, + { "PromenadeDeck", 0x79C45, 2 }, + { "1stClassRestaurant", 0x896B9, 1 }, + { "CreatorsChamber", 0x2F86D, 2 }, + { "CreatorsChamberOn", 0x2F86D, 2 }, + { "BilgeRoom", 0x3D94B, 3 }, + { "BilgeRoomWith", 0x3D94B, 3 }, + { "Bridge", 0x39FCB, 3 } +}; + +int CRoomFlags::getConditionally() const { + if (getRoomArea() != 5 || getRoomCategory() != 5) + return _data; + else + return 5; +} + +bool CRoomFlags::isTransportRoom() const { + for (int idx = 0; idx < TRANSPORT_ROOMS_SIZE; ++idx) { + if (TRANSPORT_ROOMS[idx]._roomFlags == _data) + return true; + } + + return false; +} + +int CRoomFlags::getRoomCategory() const { + if (getRoomNum() == 0) + return false; + + CRoomFlags tempFlags = _data; + tempFlags.setRoomBits(1); + return tempFlags.getRoomArea() != 5; +} + +int CRoomFlags::getRoomArea() const { + if (isSuccUBusRoomFlags()) + return 4; + + if (!getBit0()) { + uint v3 = getFloorNum(); + if (v3 <= 38) { + uint v4 = getRoomNum(); + if (v4 <= 18) { + uint v6 = getElevatorNum(); + + if (v6 >= 1 && v6 <= 4) { + uint v7 = getPassengerClassNum() - 1; + if (v7) { + uint v8 = v7 - 1; + if (v8) { + if (v8 == 1 && is28To38(v3) && (v6 & 1) && v4 >= 1) + return 3; + } else if (is20To27(v3)) { + if (v6 & 1) { + if (v4 >= 1 && v4 <= 3) + return 2; + } else if (v4 >= 1 && v4 <= 4) { + return 2; + } + } + } else if (is2To19(v3) && v4 >= 1 && v4 <= 3) { + return 1; + } + } + } + } + } + + return 5; +} + +CString CRoomFlags::getRoomDesc() const { + switch (getRoomArea()) { + case 1: + case 2: + case 3: { + CString result = getPassengerClassDesc(); + result += ", "; + result += getFloorDesc(); + result += ", "; + result += getElevatorDesc(); + result += ", "; + result += getRoomDesc(); + return result; + } + + case 4: + if (isTransportRoom()) { + switch (_data) { + case 0x68797: + return "The Service Elevator"; + case 0x5D3AD: + return "The Super Galactic Leisure Lounge"; + case 0x96E45: + return "The Elevator"; + case 0xAD171: + return "The Dome"; + case 0xC95E9: + return "The Pellerator"; + case 0xDF4D1: + return "The Top of the Well"; + default: + break; + } + } + + if (getRoomCategory() == 0) { + return "Nowhere you're likely to want to go."; + } else { + CString result = getPassengerClassDesc(); + result += ", "; + result += getFloorDesc(); + return result; + } + break; + + case 5: + switch (_data) { + case 0x1D0D9: + return "The Parrot Lobby"; + case 0x2F86D: + return "The Creators' Chamber"; + case 0x39FCB: + return "The Bridge"; + case 0x3D94B: + return "The Bilge Room"; + case 0x465FB: + return "The Sculpture Chamber"; + case 0x4D6AF: + return "The Arboretum"; + case 0x59FAD: + return "The Bottom of the Well"; + case 0x79C45: + return "The Promenade Deck"; + case 0x896B9: + return "The 1st class restaurant"; + case 0x8A397: + return "Titania's Room"; + case 0xB3D97: + return "The Bar"; + case 0xCC971: + return "The Embarkation Lobby"; + case 0xF34DB: + return "The Music Room"; + default: + break; + } + return "Unknown Room"; + + default: + break; + } + + return "Unknown Room"; +} + +void CRoomFlags::setElevatorBits(uint val) { + _data &= ~(ELEVATOR_MASK << ELEVATOR_SHIFT); + _data |= (val & ELEVATOR_MASK) << ELEVATOR_SHIFT; +} + +uint CRoomFlags::getElevatorBits() const { + return (_data >> ELEVATOR_SHIFT) & ELEVATOR_MASK; +} + +void CRoomFlags::setPassengerClassBits(uint val) { + _data &= ~(PASSENGER_CLASS_MASK << PASSENGER_CLASS_SHIFT); + _data |= (val & PASSENGER_CLASS_MASK) << PASSENGER_CLASS_SHIFT; +} + +uint CRoomFlags::getPassengerClassBits() const { + return (_data >> PASSENGER_CLASS_SHIFT) & PASSENGER_CLASS_MASK; +} + +CString CRoomFlags::getPassengerClassDesc() const { + int classNum = getPassengerClassNum(); + + switch (classNum) { + case 1: + return "1st class"; + case 2: + return "2nd class"; + case 3: + return "SGT class"; + default: + return "no class"; + } +} + +void CRoomFlags::setFloorBits(uint val) { + _data &= ~(FLOOR_MASK << FLOOR_SHIFT); + _data |= (val & FLOOR_MASK) << FLOOR_SHIFT; +} + +uint CRoomFlags::getFloorBits() const { + return (_data >> FLOOR_SHIFT) & FLOOR_MASK; +} + +uint CRoomFlags::decodeFloorBits(uint bits) const { + int base = 0; + int offset = bits & 0xF; + + switch ((bits >> 4) & 0xF) { + case 1: + case 2: + case 3: + base = 40; + break; + case 4: + base = 10; + break; + case 5: + base = 20; + break; + case 6: + base = 30; + break; + default: + break; + } + + return offset >= 10 ? 0 : base + offset; +} + +void CRoomFlags::setFloorNum(uint floorNum) { + uint base = 0; + + switch (floorNum / 10) { + case 0: + base = 0x90; + break; + case 1: + base = 0xD0; + case 2: + base = 0xE0; + case 3: + base = 0xF0; + break; + default: + break; + } + + setFloorBits(base | (floorNum % 10)); +} + +uint CRoomFlags::getFloorNum() const { + return decodeFloorBits(getFloorBits()); +} + +void CRoomFlags::setRoomBits(uint roomBits) { + _data &= ~(ROOM_MASK << ROOM_SHIFT); + _data |= (roomBits & ROOM_MASK) << ROOM_SHIFT; +} + +uint CRoomFlags::getRoomBits() const { + return (_data >> ROOM_SHIFT) & ROOM_MASK; +} + +bool CRoomFlags::isSuccUBusRoomFlags() const { + for (int idx = 0; idx < SUCCUBUS_ROOMS_SIZE; ++idx) { + if (SUCCUBUS_ROOMS[idx]._roomFlags == _data) + return true; + } + + return false; +} + +bool CRoomFlags::getBit0() const { + return _data & 1; +} + +uint CRoomFlags::getSpecialRoomFlags(const CString &roomName) { + for (int idx = 0; idx < SUCCUBUS_ROOMS_SIZE; ++idx) { + if (!roomName.compareTo(SUCCUBUS_ROOMS[idx]._roomName)) + return SUCCUBUS_ROOMS[idx]._roomFlags; + } + + for (int idx = 0; idx < TRANSPORT_ROOMS_SIZE; ++idx) { + if (!roomName.compareTo(TRANSPORT_ROOMS[idx]._roomName)) + return TRANSPORT_ROOMS[idx]._roomFlags; + } + + return 0; +} + +uint CRoomFlags::getSuccUBusNum(const CString &roomName) const { + for (int idx = 0; idx < SUCCUBUS_ROOMS_SIZE; ++idx) { + if (!roomName.compareTo(SUCCUBUS_ROOMS[idx]._roomName)) + return SUCCUBUS_ROOMS[idx]._succubusNum; + } + + return 0; +} + +CString CRoomFlags::getSuccUBusRoomName() const { + for (int idx = 0; idx < SUCCUBUS_ROOMS_SIZE; ++idx) { + if (SUCCUBUS_ROOMS[idx]._roomFlags == _data) + return SUCCUBUS_ROOMS[idx]._roomName; + } + + return CString(); +} + +void CRoomFlags::changeLocation(int action) { + uint floorNum = getFloorNum(); + uint roomNum = getRoomNum(); + uint elevatorNum = getElevatorNum(); + uint classNum = getPassengerClassNum(); + uint v10, v11, v12, v13; + + switch (classNum) { + case 1: + v10 = 2; + v11 = 19; + v12 = 1; + v13 = 3; + break; + + case 2: + v10 = 20; + v11 = 27; + v12 = 1; + v13 = (elevatorNum & 1) ? 3 : 4; + break; + + case 3: + v10 = 28; + v11 = 38; + v12 = 1; + v13 = 18; + break; + + default: + v10 = 0; + v11 = 0; + v12 = 0; + v13 = 0; + break; + } + + // Perform action to change room or floor + switch (action) { + case 1: + if (--roomNum < v12) + roomNum = v12; + break; + + case 2: + if (++roomNum > v13) + roomNum = v13; + break; + + case 3: + if (--floorNum < v10) + floorNum = v10; + break; + + case 4: + if (++floorNum > v11) + floorNum = v11; + } + + // Set new floor and room + setFloorNum(floorNum); + setRoomBits(roomNum); +} + +bool CRoomFlags::compareClassElevator(uint flags1, uint flags2) { + CRoomFlags f1(flags1); + CRoomFlags f2(flags2); + + if (f1.getFloorNum() != f2.getFloorNum()) + return false; + + uint elev1 = f1.getElevatorNum(); + uint elev2 = f2.getElevatorNum(); + uint class1 = f1.getPassengerClassNum(); + uint class2 = f2.getPassengerClassNum(); + + if (class1 > 0 && class1 < 3) { + if (elev1 == 2) + elev1 = 1; + else if (elev1 == 4) + elev1 = 3; + } + if (class2 > 0 && class2 < 3) { + if (elev2 == 2) + elev2 = 1; + else if (elev2 == 4) + elev2 = 3; + } + + return elev1 == elev2; +} + +bool CRoomFlags::compareLocation(uint flags1, uint flags2) { + CRoomFlags f1(flags1); + CRoomFlags f2(flags2); + + return f1.getElevatorNum() == f2.getElevatorBits() && + f1.getFloorNum() == f2.getFloorNum() && + f1.getRoomNum() == f2.getRoomNum(); +} + +bool CRoomFlags::isTitania(uint flags1, uint flags2) { + return flags2 == 0x8A397; +} + +void CRoomFlags::setRandomLocation(int classNum, bool flag) { + uint minRoom, elevNum, maxRoom, maxFloor, minFloor; + + do { + switch (classNum) { + case 1: + minFloor = 2; + maxFloor = 19; + minRoom = 1; + maxRoom = 3; + elevNum = g_vm->getRandomNumber(flag ? 2 : 3); + break; + + case 2: + minFloor = 20; + maxFloor = 27; + elevNum = g_vm->getRandomNumber(flag ? 2 : 3); + minRoom = 1; + maxRoom = ((elevNum - 1) & 1) ? 3 : 4; + break; + + case 3: + minRoom = 1; + minFloor = 28; + maxFloor = 38; + maxRoom = 18; + elevNum = g_vm->getRandomNumber(1); + if (elevNum == 1) + elevNum = 2; + break; + + default: + return; + } + + uint floorNum = minFloor + g_vm->getRandomNumber(maxFloor - minFloor); + uint roomNum = minRoom + g_vm->getRandomNumber(maxRoom - minRoom); + setElevatorBits(elevNum); + setRoomBits(roomNum); + setFloorNum(floorNum); + } while (_data == 0x59706); +} + +int CRoomFlags::whatPassengerClass(int floorNum) { + if (is2To19(floorNum)) + return 1; + + return is20To27(floorNum) ? 2 : 3; +} + +} // End of namespace Titanic diff --git a/engines/titanic/room_flags.h b/engines/titanic/room_flags.h new file mode 100644 index 0000000000..f0f90f80d1 --- /dev/null +++ b/engines/titanic/room_flags.h @@ -0,0 +1,230 @@ +/* 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 TITANIC_ROOM_FLAGS_H +#define TITANIC_ROOM_FLAGS_H + +#include "titanic/support/string.h" + +namespace Titanic { + +class CRoomFlags { +private: + uint _data; +private: + int getConditionally() const; + + /** + * Returns true if the current flags appear in the + * list of transport rooms + */ + bool isTransportRoom() const; + + int getRoomCategory() const; + + int getRoomArea() const; + + /** + * Set the bits for the elevator number + */ + void setElevatorBits(uint val); + + /** + * Set the bits for the floor number + */ + void setFloorBits(uint val); + + /** + * Translates bits for floor into a floor number + */ + uint decodeFloorBits(uint bits) const; + + static bool is2To19(uint v) { return v >= 2 && v <= 19; } + static bool is20To27(uint v) { return v >= 20 && v <= 27; } + static bool is28To38(uint v) { return v >= 28 && v <= 38; } +public: + /** + * Compares the current flags against the specified flags + * for a matching elevator, floor, and room + */ + static bool compareLocation(uint flags1, uint flags2); + + /** + * Compares two room flags together + */ + static bool compareClassElevator(uint flags1, uint flags2); + + /** + * Returns true if the current flags is for Titania's room + */ + static bool isTitania(uint flags1, uint flags2); +public: + CRoomFlags() : _data(0) {} + CRoomFlags(uint data) : _data(data) {} + operator uint() { return _data; } + + /** + * Set the flags value + */ + void set(uint data) { _data = data; } + + /** + * Get the flags value + */ + uint get() const { return _data; } + + /** + * Gets the special flags for a transport or succubus room + */ + static uint getSpecialRoomFlags(const CString &roomName); + + /** + * Returns true if the current flags are in the succubus list + */ + bool isSuccUBusRoomFlags() const; + + /** + * Get a description for the room + */ + CString getRoomDesc() const; + + /** + * Get the bits for the elevator number + */ + uint getElevatorBits() const; + + /** + * Set the elevator number + */ + void setElevatorNum(uint val) { setElevatorBits(val - 1); } + + /** + * Get the elevator number + */ + uint getElevatorNum() const { return getElevatorBits() + 1; } + + /** + * Get a description for the elevator number + */ + CString getElevatorDesc() const { + return CString::format("Elevator %d", getElevatorNum()); + } + + /** + * Gets the bits for the passenger class + */ + uint getPassengerClassBits() const; + + /** + * Set the bits for the passenger class + */ + void setPassengerClassBits(uint val); + + /** + * Gets the passenger class number + */ + uint getPassengerClassNum() const { return getPassengerClassBits(); } + + /** + * Get a description for the passenger class + */ + CString getPassengerClassDesc() const; + + /** + * Gets the bits for the floor number + */ + uint getFloorBits() const; + + /** + * Sets the floor number + */ + void setFloorNum(uint floorNum); + + /** + * Gets the floor number + */ + uint getFloorNum() const; + + /** + * Get a description for the floor number + */ + CString getFloorDesc() const { + return CString::format("Floor %d", getFloorNum()); + } + + /** + * Sets the bits for the room number + */ + void setRoomBits(uint roomBits); + + /** + * Gets the bits for the room number + */ + uint getRoomBits() const; + + /** + * Gets the room number + */ + uint getRoomNum() const { return getRoomBits(); } + + /** + * Gets a string for the room number + */ + CString getRoomNumDesc() const { + return CString::format("Room %d", getRoomNum()); + } + + bool getBit0() const; + + /** + * Change the passenger class + */ + void changeLocation(int action); + + /** + * Sets a random destination in the flags + */ + void setRandomLocation(int classNum, bool flag); + + /** + * Gets the succubus number associated with a given room + */ + uint getSuccUBusNum(const CString &roomName) const; + + /** + * Gets the succubus room name associated with the current room flags + */ + CString getSuccUBusRoomName() const; + + /** + * Returns what passenger class a particular floor number belongs to + */ + static int whatPassengerClass(int floorNum); + + bool not5() const { return getConditionally() != 5; } + + bool is59706() const { return _data == 0x59706; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ROOM_FLAGS_H */ diff --git a/engines/titanic/sound/auto_music_player.cpp b/engines/titanic/sound/auto_music_player.cpp new file mode 100644 index 0000000000..ce20c33765 --- /dev/null +++ b/engines/titanic/sound/auto_music_player.cpp @@ -0,0 +1,75 @@ +/* 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 "titanic/sound/auto_music_player.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CAutoMusicPlayer, CAutoMusicPlayerBase) + ON_MESSAGE(EnterRoomMsg) + ON_MESSAGE(LeaveRoomMsg) +END_MESSAGE_MAP() + +CAutoMusicPlayer::CAutoMusicPlayer() : CAutoMusicPlayerBase() { +} + +void CAutoMusicPlayer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_leaveRoomSound, indent); + + CAutoMusicPlayerBase::save(file, indent); +} + +void CAutoMusicPlayer::load(SimpleFile *file) { + file->readNumber(); + _leaveRoomSound = file->readString(); + + CAutoMusicPlayerBase::load(file); +} + +bool CAutoMusicPlayer::EnterRoomMsg(CEnterRoomMsg *msg) { + if (!_isRepeated) { + CRoomItem *room = findRoom(); + if (msg->_newRoom == room) + addTimer(2000); + } + + return true; +} + +bool CAutoMusicPlayer::LeaveRoomMsg(CLeaveRoomMsg *msg) { + if (_isRepeated) { + CRoomItem *room = findRoom(); + if (msg->_oldRoom == room) { + CChangeMusicMsg changeMsg; + changeMsg._flags = 1; + changeMsg.execute(this); + } + } + + if (!_leaveRoomSound.empty()) + playSound(_leaveRoomSound); + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/auto_music_player.h b/engines/titanic/sound/auto_music_player.h new file mode 100644 index 0000000000..722aa9cd7f --- /dev/null +++ b/engines/titanic/sound/auto_music_player.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_AUTO_MUSIC_PLAYER_H +#define TITANIC_AUTO_MUSIC_PLAYER_H + +#include "titanic/sound/auto_music_player_base.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CAutoMusicPlayer : public CAutoMusicPlayerBase { + DECLARE_MESSAGE_MAP; + bool EnterRoomMsg(CEnterRoomMsg *msg); + bool LeaveRoomMsg(CLeaveRoomMsg *msg); +private: + CString _leaveRoomSound; +public: + CLASSDEF; + CAutoMusicPlayer(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_AUTO_MUSIC_PLAYER_H */ diff --git a/engines/titanic/sound/auto_music_player_base.cpp b/engines/titanic/sound/auto_music_player_base.cpp new file mode 100644 index 0000000000..ad8b848c03 --- /dev/null +++ b/engines/titanic/sound/auto_music_player_base.cpp @@ -0,0 +1,101 @@ +/* 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 "titanic/sound/auto_music_player_base.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CAutoMusicPlayerBase, CGameObject) + ON_MESSAGE(StatusChangeMsg) + ON_MESSAGE(TimerMsg) + ON_MESSAGE(LoadSuccessMsg) + ON_MESSAGE(ChangeMusicMsg) +END_MESSAGE_MAP() + +CAutoMusicPlayerBase::CAutoMusicPlayerBase() : CGameObject(), + _initialMute(true), _isRepeated(false), _volumeMode(-1), _transition(1) { +} +void CAutoMusicPlayerBase::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_filename, indent); + file->writeNumberLine(_initialMute, indent); + file->writeNumberLine(_isRepeated, indent); + file->writeNumberLine(_volumeMode, indent); + file->writeNumberLine(_transition, indent); + + CGameObject::save(file, indent); +} + +void CAutoMusicPlayerBase::load(SimpleFile *file) { + file->readNumber(); + _filename = file->readString(); + _initialMute = file->readNumber(); + _isRepeated = file->readNumber(); + _volumeMode = file->readNumber(); + _transition = file->readNumber(); + + CGameObject::load(file); +} + +bool CAutoMusicPlayerBase::StatusChangeMsg(CStatusChangeMsg *msg) { + return true; +} + +bool CAutoMusicPlayerBase::TimerMsg(CTimerMsg *msg) { + CChangeMusicMsg musicMsg; + musicMsg._flags = 2; + musicMsg.execute(this); + + return true; +} + +bool CAutoMusicPlayerBase::LoadSuccessMsg(CLoadSuccessMsg *msg) { + if (_isRepeated) + playGlobalSound(_filename, _volumeMode, _initialMute, true, 0); + + return true; +} + +bool CAutoMusicPlayerBase::ChangeMusicMsg(CChangeMusicMsg *msg) { + if (_isRepeated && msg->_flags == 1) { + _isRepeated = false; + stopGlobalSound(_transition, -1); + } + + if (!msg->_filename.empty()) { + _filename = msg->_filename; + + if (_isRepeated) { + stopGlobalSound(_transition, -1); + playGlobalSound(_filename, _volumeMode, _initialMute, true, 0); + } + } + + if (_isRepeated && msg->_flags == 2) { + _isRepeated = true; + playGlobalSound(_filename, _volumeMode, _initialMute, true, 0); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/auto_music_player_base.h b/engines/titanic/sound/auto_music_player_base.h new file mode 100644 index 0000000000..0623258887 --- /dev/null +++ b/engines/titanic/sound/auto_music_player_base.h @@ -0,0 +1,59 @@ +/* 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 TITANIC_AUTO_MUSIC_PLAYER_BASE_H +#define TITANIC_AUTO_MUSIC_PLAYER_BASE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CAutoMusicPlayerBase : public CGameObject { + DECLARE_MESSAGE_MAP; + bool StatusChangeMsg(CStatusChangeMsg *msg); + bool TimerMsg(CTimerMsg *msg); + bool LoadSuccessMsg(CLoadSuccessMsg *msg); + bool ChangeMusicMsg(CChangeMusicMsg *msg); +protected: + CString _filename; + bool _initialMute; + bool _isRepeated; + int _volumeMode; + int _transition; +public: + CLASSDEF; + CAutoMusicPlayerBase(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_AUTO_MUSIC_PLAYER_BASE_H */ diff --git a/engines/titanic/sound/auto_sound_player.cpp b/engines/titanic/sound/auto_sound_player.cpp new file mode 100644 index 0000000000..8267d65037 --- /dev/null +++ b/engines/titanic/sound/auto_sound_player.cpp @@ -0,0 +1,134 @@ +/* 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 "titanic/sound/auto_sound_player.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CAutoSoundPlayer, CGameObject) + ON_MESSAGE(TurnOn) + ON_MESSAGE(TurnOff) + ON_MESSAGE(SignalObject) + ON_MESSAGE(SetVolumeMsg) + ON_MESSAGE(LoadSuccessMsg) +END_MESSAGE_MAP() + +CAutoSoundPlayer::CAutoSoundPlayer() : CGameObject(), + _fieldBC(0), _volume(70), _fieldD0(0), _repeated(false), _soundHandle(-1), + _stopSeconds(0), _startSeconds(-1), _active(false), _fieldE8(0) { +} + +void CAutoSoundPlayer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeQuotedLine(_filename, indent); + file->writeNumberLine(_volume, indent); + file->writeNumberLine(_fieldD0, indent); + file->writeNumberLine(_repeated, indent); + file->writeNumberLine(_soundHandle, indent); + file->writeNumberLine(_stopSeconds, indent); + file->writeNumberLine(_startSeconds, indent); + file->writeNumberLine(_active, indent); + file->writeNumberLine(_fieldE8, indent); + + CGameObject::save(file, indent); +} + +void CAutoSoundPlayer::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _filename = file->readString(); + _volume = file->readNumber(); + _fieldD0 = file->readNumber(); + _repeated = file->readNumber(); + _soundHandle = file->readNumber(); + _stopSeconds = file->readNumber(); + _startSeconds = file->readNumber(); + _active = file->readNumber(); + _fieldE8 = file->readNumber(); + + CGameObject::load(file); +} + +bool CAutoSoundPlayer::TurnOn(CTurnOn *msg) { + if (_soundHandle == -1) { + CProximity prox; + prox._fieldC = _fieldD0; + prox._repeated = _repeated; + if (_fieldE8) + prox._positioningMode = POSMODE_VECTOR; + prox._channelVolume = (_startSeconds == -1) ? _volume : 0; + + _soundHandle = playSound(_filename, prox); + if (_startSeconds != -1) + setSoundVolume(_soundHandle, _volume, _startSeconds); + + _active = true; + } + + return true; +} + +bool CAutoSoundPlayer::TurnOff(CTurnOff *msg) { + if (_soundHandle != -1) { + if (isSoundActive(_soundHandle)) + stopSound(_soundHandle, _stopSeconds); + + _soundHandle = -1; + _active = false; + } + + return true; +} + +bool CAutoSoundPlayer::SignalObject(CSignalObject *msg) { + if (_soundHandle != -1) { + if (isSoundActive(_soundHandle)) + stopSound(_soundHandle, msg->_numValue); + + _soundHandle = -1; + _active = false; + } + + return true; +} + +bool CAutoSoundPlayer::SetVolumeMsg(CSetVolumeMsg *msg) { + if (_soundHandle != -1 && isSoundActive(_soundHandle)) + setSoundVolume(_soundHandle, msg->_volume, msg->_secondsTransition); + + return true; +} + +bool CAutoSoundPlayer::LoadSuccessMsg(CLoadSuccessMsg *msg) { + if (_active) { + _soundHandle = -1; + _active = false; + + CTurnOn onMsg; + onMsg.execute(this); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/auto_sound_player.h b/engines/titanic/sound/auto_sound_player.h new file mode 100644 index 0000000000..c8f1d3480e --- /dev/null +++ b/engines/titanic/sound/auto_sound_player.h @@ -0,0 +1,65 @@ +/* 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 TITANIC_AUTO_SOUND_PLAYER_H +#define TITANIC_AUTO_SOUND_PLAYER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CAutoSoundPlayer : public CGameObject { + DECLARE_MESSAGE_MAP; + bool TurnOn(CTurnOn *msg); + bool TurnOff(CTurnOff *msg); + bool SignalObject(CSignalObject *msg); + bool SetVolumeMsg(CSetVolumeMsg *msg); + bool LoadSuccessMsg(CLoadSuccessMsg *msg); +public: + int _fieldBC; + CString _filename; + int _volume; + int _fieldD0; + bool _repeated; + int _soundHandle; + int _stopSeconds; + int _startSeconds; + bool _active; + int _fieldE8; +public: + CLASSDEF; + CAutoSoundPlayer(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_AUTO_SOUND_PLAYER_H */ diff --git a/engines/titanic/sound/auto_sound_player_adsr.cpp b/engines/titanic/sound/auto_sound_player_adsr.cpp new file mode 100644 index 0000000000..f9f045759b --- /dev/null +++ b/engines/titanic/sound/auto_sound_player_adsr.cpp @@ -0,0 +1,79 @@ +/* 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 "titanic/sound/auto_sound_player_adsr.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CAutoSoundPlayerADSR, CAutoSoundPlayer) + ON_MESSAGE(TurnOn) + ON_MESSAGE(TurnOff) +END_MESSAGE_MAP() + +void CAutoSoundPlayerADSR::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_soundName1, indent); + file->writeQuotedLine(_soundName2, indent); + file->writeQuotedLine(_soundName3, indent); + CAutoSoundPlayer::save(file, indent); +} + +void CAutoSoundPlayerADSR::load(SimpleFile *file) { + file->readNumber(); + _soundName1 = file->readString(); + _soundName2 = file->readString(); + _soundName3 = file->readString(); + CAutoSoundPlayer::load(file); +} + +bool CAutoSoundPlayerADSR::TurnOn(CTurnOn *msg) { + if (_soundHandle == -1) { + if (!_soundName1.empty()) { + _soundHandle = playSound(_soundName1, _volume, _fieldD0); + + if (!_soundName2.empty()) + _soundHandle = queueSound(_soundName2, _soundHandle, _volume, _fieldD0); + + _soundHandle = queueSound(_filename, _soundHandle, _volume, _fieldD0); + _active = true; + } + } + + return true; +} + +bool CAutoSoundPlayerADSR::TurnOff(CTurnOff *msg) { + if (_soundHandle != -1) { + if (!_soundName3.empty()) + queueSound(_soundName3, _soundHandle, _volume, _fieldD0); + + if (isSoundActive(_soundHandle)) + stopSound(_soundHandle); + + _soundHandle = -1; + _active = false; + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/auto_sound_player_adsr.h b/engines/titanic/sound/auto_sound_player_adsr.h new file mode 100644 index 0000000000..9f09636610 --- /dev/null +++ b/engines/titanic/sound/auto_sound_player_adsr.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_AUTO_SOUND_PLAYER_ADSR_H +#define TITANIC_AUTO_SOUND_PLAYER_ADSR_H + +#include "titanic/sound/auto_sound_player.h" + +namespace Titanic { + +class CAutoSoundPlayerADSR : public CAutoSoundPlayer { + DECLARE_MESSAGE_MAP; + bool TurnOn(CTurnOn *msg); + bool TurnOff(CTurnOff *msg); +private: + CString _soundName1; + CString _soundName2; + CString _soundName3; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_AUTO_SOUND_PLAYER_ADSR_H */ diff --git a/engines/titanic/sound/background_sound_maker.cpp b/engines/titanic/sound/background_sound_maker.cpp new file mode 100644 index 0000000000..58dde02518 --- /dev/null +++ b/engines/titanic/sound/background_sound_maker.cpp @@ -0,0 +1,47 @@ +/* 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 "titanic/sound/background_sound_maker.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CBackgroundSoundMaker, CGameObject) + ON_MESSAGE(FrameMsg) +END_MESSAGE_MAP() + +void CBackgroundSoundMaker::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CBackgroundSoundMaker::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +bool CBackgroundSoundMaker::FrameMsg(CFrameMsg *msg) { + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/background_sound_maker.h b/engines/titanic/sound/background_sound_maker.h new file mode 100644 index 0000000000..94f3b792dc --- /dev/null +++ b/engines/titanic/sound/background_sound_maker.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_BACKGROUND_SOUND_MAKER_H +#define TITANIC_BACKGROUND_SOUND_MAKER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CBackgroundSoundMaker : public CGameObject { + DECLARE_MESSAGE_MAP; + bool FrameMsg(CFrameMsg *msg); +public: + int _value; +public: + CLASSDEF; + CBackgroundSoundMaker() : CGameObject(), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BACKGROUND_SOUND_MAKER_H */ diff --git a/engines/titanic/sound/bird_song.cpp b/engines/titanic/sound/bird_song.cpp new file mode 100644 index 0000000000..53a25e2dbe --- /dev/null +++ b/engines/titanic/sound/bird_song.cpp @@ -0,0 +1,56 @@ +/* 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 "titanic/sound/bird_song.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CBirdSong, CAutoSoundPlayer) + ON_MESSAGE(TurnOn) + ON_MESSAGE(SignalObject) +END_MESSAGE_MAP() + +void CBirdSong::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_flag, indent); + CRoomAutoSoundPlayer::save(file, indent); +} + +void CBirdSong::load(SimpleFile *file) { + file->readNumber(); + _flag = file->readNumber(); + CRoomAutoSoundPlayer::load(file); +} + +bool CBirdSong::TurnOn(CTurnOn *msg) { + if (!_flag) + CAutoSoundPlayer::TurnOn(msg); + return true; +} + +bool CBirdSong::SignalObject(CSignalObject *msg) { + _flag = true; + CAutoSoundPlayer::SignalObject(msg); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/bird_song.h b/engines/titanic/sound/bird_song.h new file mode 100644 index 0000000000..52af94b180 --- /dev/null +++ b/engines/titanic/sound/bird_song.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_BIRD_SONG_H +#define TITANIC_BIRD_SONG_H + +#include "titanic/sound/room_auto_sound_player.h" + +namespace Titanic { + +class CBirdSong : public CRoomAutoSoundPlayer { + DECLARE_MESSAGE_MAP; + bool TurnOn(CTurnOn *msg); + bool SignalObject(CSignalObject *msg); +public: + bool _flag; +public: + CLASSDEF; + CBirdSong() : CRoomAutoSoundPlayer(), _flag(false) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BIRD_SONG_H */ diff --git a/engines/titanic/sound/dome_from_top_of_well.cpp b/engines/titanic/sound/dome_from_top_of_well.cpp new file mode 100644 index 0000000000..789d7fa4cb --- /dev/null +++ b/engines/titanic/sound/dome_from_top_of_well.cpp @@ -0,0 +1,47 @@ +/* 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 "titanic/sound/dome_from_top_of_well.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CDomeFromTopOfWell, CViewAutoSoundPlayer); + +CDomeFromTopOfWell::CDomeFromTopOfWell() : CViewAutoSoundPlayer() { + _filename = "z#227.wav"; + _volume = 25; + _repeated = true; + _stopSeconds = 1; + _startSeconds = 1; +} + +void CDomeFromTopOfWell::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CViewAutoSoundPlayer::save(file, indent); +} + +void CDomeFromTopOfWell::load(SimpleFile *file) { + file->readNumber(); + CViewAutoSoundPlayer::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/dome_from_top_of_well.h b/engines/titanic/sound/dome_from_top_of_well.h new file mode 100644 index 0000000000..001f66a1a8 --- /dev/null +++ b/engines/titanic/sound/dome_from_top_of_well.h @@ -0,0 +1,49 @@ +/* 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 TITANIC_DOME_FROM_TOP_OF_WELL_H +#define TITANIC_DOME_FROM_TOP_OF_WELL_H + +#include "titanic/sound/view_auto_sound_player.h" + +namespace Titanic { + +class CDomeFromTopOfWell : public CViewAutoSoundPlayer { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + CDomeFromTopOfWell(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DOME_FROM_TOP_OF_WELL_H */ diff --git a/engines/titanic/sound/enter_view_toggles_other_music.cpp b/engines/titanic/sound/enter_view_toggles_other_music.cpp new file mode 100644 index 0000000000..2f0091a0a3 --- /dev/null +++ b/engines/titanic/sound/enter_view_toggles_other_music.cpp @@ -0,0 +1,60 @@ +/* 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 "titanic/sound/enter_view_toggles_other_music.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CEnterViewTogglesOtherMusic, CTriggerAutoMusicPlayer) + ON_MESSAGE(EnterViewMsg) +END_MESSAGE_MAP() + +CEnterViewTogglesOtherMusic::CEnterViewTogglesOtherMusic() : + CTriggerAutoMusicPlayer(), _value(2) { +} + +void CEnterViewTogglesOtherMusic::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + + CTriggerAutoMusicPlayer::save(file, indent); +} + +void CEnterViewTogglesOtherMusic::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + + CTriggerAutoMusicPlayer::load(file); +} + +bool CEnterViewTogglesOtherMusic::EnterViewMsg(CEnterViewMsg *msg) { + CViewItem *view = findView(); + if (view == msg->_newView) { + CTriggerAutoMusicPlayerMsg triggerMsg; + triggerMsg._value = _value; + triggerMsg.execute(this); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/enter_view_toggles_other_music.h b/engines/titanic/sound/enter_view_toggles_other_music.h new file mode 100644 index 0000000000..a91b1e1933 --- /dev/null +++ b/engines/titanic/sound/enter_view_toggles_other_music.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_ENTER_VIEW_TOGGLES_OTHER_MUSIC_H +#define TITANIC_ENTER_VIEW_TOGGLES_OTHER_MUSIC_H + +#include "titanic/sound/trigger_auto_music_player.h" + +namespace Titanic { + +class CEnterViewTogglesOtherMusic : public CTriggerAutoMusicPlayer { + DECLARE_MESSAGE_MAP; + bool EnterViewMsg(CEnterViewMsg *msg); +protected: + int _value; +public: + CLASSDEF; + CEnterViewTogglesOtherMusic(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ENTER_VIEW_TOGGLES_OTHER_MUSIC_H */ diff --git a/engines/titanic/sound/gondolier_song.cpp b/engines/titanic/sound/gondolier_song.cpp new file mode 100644 index 0000000000..5c96718723 --- /dev/null +++ b/engines/titanic/sound/gondolier_song.cpp @@ -0,0 +1,94 @@ +/* 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 "titanic/sound/gondolier_song.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CGondolierSong, CRoomAutoSoundPlayer) + ON_MESSAGE(TurnOn) + ON_MESSAGE(SignalObject) + ON_MESSAGE(SetVolumeMsg) + ON_MESSAGE(StatusChangeMsg) +END_MESSAGE_MAP() + +void CGondolierSong::save(SimpleFile *file, int indent) { + file->writeNumberLine(_enabled, indent); + file->writeNumberLine(_value, indent); + CRoomAutoSoundPlayer::save(file, indent); +} + +void CGondolierSong::load(SimpleFile *file) { + _enabled = file->readNumber(); + _value = file->readNumber(); + CRoomAutoSoundPlayer::load(file); +} + +bool CGondolierSong::TurnOn(CTurnOn *msg) { + if (_enabled) { + if (_soundHandle != -1) { + int volume = _value * _volume / 100; + + if (_startSeconds == -1) { + _soundHandle = playSound(_filename, volume, _fieldD0, _repeated); + } else { + _soundHandle = playSound(_filename, 0, _fieldD0, _repeated); + setSoundVolume(_soundHandle, _volume, _startSeconds); + } + + _active = true; + } + } + + return true; +} + +bool CGondolierSong::SignalObject(CSignalObject *msg) { + _enabled = false; + CAutoSoundPlayer::SignalObject(msg); + return true; +} + +bool CGondolierSong::SetVolumeMsg(CSetVolumeMsg *msg) { + if (_enabled) { + _volume = msg->_volume; + + if (_soundHandle != -1 && isSoundActive(_soundHandle)) { + int newVolume = _value * _volume / 100; + setSoundVolume(_soundHandle, newVolume, msg->_secondsTransition); + } + } + + return true; +} + +bool CGondolierSong::StatusChangeMsg(CStatusChangeMsg *msg) { + if (_enabled) { + _value = CLIP(msg->_newStatus, 0, 100); + CSetVolumeMsg volumeMsg(_volume, _stopSeconds); + volumeMsg.execute(this); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/gondolier_song.h b/engines/titanic/sound/gondolier_song.h new file mode 100644 index 0000000000..d586711de9 --- /dev/null +++ b/engines/titanic/sound/gondolier_song.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_GONDOLIER_SONG_H +#define TITANIC_GONDOLIER_SONG_H + +#include "titanic/sound/room_auto_sound_player.h" + +namespace Titanic { + +class CGondolierSong : public CRoomAutoSoundPlayer { + DECLARE_MESSAGE_MAP; + bool TurnOn(CTurnOn *msg); + bool SignalObject(CSignalObject *msg); + bool SetVolumeMsg(CSetVolumeMsg *msg); + bool StatusChangeMsg(CStatusChangeMsg *msg); +public: + bool _enabled; + int _value; +public: + CLASSDEF; + CGondolierSong() : CRoomAutoSoundPlayer(), _enabled(true), _value(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GONDOLIER_SONG_H */ diff --git a/engines/titanic/sound/music_handler.cpp b/engines/titanic/sound/music_handler.cpp new file mode 100644 index 0000000000..037c340f0b --- /dev/null +++ b/engines/titanic/sound/music_handler.cpp @@ -0,0 +1,80 @@ +/* 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 "titanic/sound/music_handler.h" +#include "titanic/sound/sound_manager.h" +#include "titanic/core/project_item.h" + +namespace Titanic { + +CMusicHandler::CMusicHandler(CProjectItem *project, CSoundManager *soundManager) : + _project(project), _soundManager(soundManager), _stopWaves(false), + _soundHandle(-1), _waveFile(nullptr) { + Common::fill(&_musicWaves[0], &_musicWaves[4], (CMusicWave *)nullptr); +} + +CMusicHandler::~CMusicHandler() { + stop(); +} + +CMusicWave *CMusicHandler::createMusicWave(int waveIndex, int count) { + switch (waveIndex) { + case 0: + _musicWaves[waveIndex] = new CMusicWave(_project, _soundManager, 2); + break; + case 1: + _musicWaves[waveIndex] = new CMusicWave(_project, _soundManager, 3); + break; + case 2: + _musicWaves[waveIndex] = new CMusicWave(_project, _soundManager, 0); + break; + case 3: + _musicWaves[waveIndex] = new CMusicWave(_project, _soundManager, 1); + break; + default: + return nullptr; + } + + _musicWaves[waveIndex]->setSize(count); + return _musicWaves[waveIndex]; +} + +bool CMusicHandler::isBusy() { + // TODO + return false; +} + +void CMusicHandler::stop() { + if (_waveFile) { + _soundManager->stopSound(_soundHandle); + delete _waveFile; + _waveFile = nullptr; + _soundHandle = -1; + } + + for (int idx = 0; idx < 4; ++idx) { + if (_stopWaves && _musicWaves[idx]) + _musicWaves[idx]->stop(); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/music_handler.h b/engines/titanic/sound/music_handler.h new file mode 100644 index 0000000000..17ffea965a --- /dev/null +++ b/engines/titanic/sound/music_handler.h @@ -0,0 +1,70 @@ +/* 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 TITANIC_MUSIC_HANDLER_H +#define TITANIC_MUSIC_HANDLER_H + +#include "titanic/sound/music_wave.h" +#include "titanic/sound/wave_file.h" + +namespace Titanic { + +class CProjectItem; +class CSoundManager; + +class CMusicHandler { +private: + CProjectItem *_project; + CSoundManager *_soundManager; + CMusicWave *_musicWaves[4]; + bool _stopWaves; + CWaveFile *_waveFile; + int _soundHandle; +public: + CMusicHandler(CProjectItem *project, CSoundManager *soundManager); + ~CMusicHandler(); + + /** + * Creates a new music wave class instance, and assigns it to a slot + * in the music handler + * @param waveIndex Slot to save new instance in + * @param count Number of files the new instance will contain + */ + CMusicWave *createMusicWave(int waveIndex, int count); + + bool isBusy(); + + /** + * Flags whether the loaded music waves will be stopped when the + * music handler is stopped + */ + void setStopWaves(bool flag) { _stopWaves = flag; } + + /** + * Stop playing the music + */ + void stop(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_HANDLER_H */ diff --git a/engines/titanic/sound/music_player.cpp b/engines/titanic/sound/music_player.cpp new file mode 100644 index 0000000000..cd764c7f93 --- /dev/null +++ b/engines/titanic/sound/music_player.cpp @@ -0,0 +1,182 @@ +/* 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 "titanic/sound/music_player.h" +#include "titanic/sound/music_room.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CMusicPlayer, CGameObject) + ON_MESSAGE(StartMusicMsg) + ON_MESSAGE(StopMusicMsg) + ON_MESSAGE(FrameMsg) + ON_MESSAGE(EnterRoomMsg) + ON_MESSAGE(LeaveRoomMsg) + ON_MESSAGE(CreateMusicPlayerMsg) + ON_MESSAGE(LoadSuccessMsg) +END_MESSAGE_MAP() + +void CMusicPlayer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_isActive, indent); + file->writeQuotedLine(_stopTarget, indent); + file->writeNumberLine(_stopWaves, indent); + file->writeNumberLine(_musicId, indent); + + CGameObject::save(file, indent); +} + +void CMusicPlayer::load(SimpleFile *file) { + file->readNumber(); + _isActive = file->readNumber(); + _stopTarget = file->readString(); + _stopWaves = file->readNumber(); + _musicId = file->readNumber(); + + CGameObject::load(file); +} + +bool CMusicPlayer::StartMusicMsg(CStartMusicMsg *msg) { + if (msg->_musicPlayer == this) { + if (_isActive) { + CStopMusicMsg stopMusicMsg; + stopMusicMsg.execute(this); + } + + return false; + } + + if (!_isActive) { + lockMouse(); + + CCreateMusicPlayerMsg createMsg; + createMsg.execute(this); + CSetMusicControlsMsg controlsMsg; + controlsMsg.execute(this, nullptr, MSGFLAG_SCAN); + + getMusicRoom()->startMusic(_musicId); + _isActive = true; + } + + return true; +} + +bool CMusicPlayer::StopMusicMsg(CStopMusicMsg *msg) { + if (!_isActive) + // Player isn't playing, so ignore message + return false; + + // Stop the music + CMusicRoom *musicRoom = getMusicRoom(); + if (musicRoom) + musicRoom->stopMusic(); + _isActive = false; + + CMusicHasStoppedMsg stoppedMsg; + stoppedMsg.execute(_stopTarget, nullptr, MSGFLAG_SCAN); + return true; +} + +bool CMusicPlayer::FrameMsg(CFrameMsg *msg) { + if (_isActive && !CMusicRoom::_musicHandler->isBusy()) { + getMusicRoom()->stopMusic(); + _isActive = false; + + CMusicHasStoppedMsg stoppedMsg; + stoppedMsg.execute(_stopTarget); + } + + return true; +} + +bool CMusicPlayer::EnterRoomMsg(CEnterRoomMsg *msg) { + addTimer(100); + return true; +} + +bool CMusicPlayer::LeaveRoomMsg(CLeaveRoomMsg *msg) { + getMusicRoom()->destroyMusicHandler(); + return true; +} + +bool CMusicPlayer::CreateMusicPlayerMsg(CCreateMusicPlayerMsg *msg) { + if (CMusicRoom::_musicHandler) { + CMusicRoom::_musicHandler->setStopWaves(_stopWaves); + return true; + } + + CMusicHandler *musicHandler = getMusicRoom()->createMusicHandler(); + CMusicWave *wave; + + if (musicHandler) { + wave = musicHandler->createMusicWave(0, 3); + wave->load(0, "z#490.wav", 60); + wave->load(1, "z#488.wav", 62); + wave->load(2, "z#489.wav", 63); + + wave = musicHandler->createMusicWave(1, 5); + wave->load(0, "z#493.wav", 22); + wave->load(1, "z#495.wav", 29); + wave->load(2, "z#492.wav", 34); + wave->load(3, "z#494.wav", 41); + wave->load(4, "z#491.wav", 46); + + wave = musicHandler->createMusicWave(2, 5); + wave->load(0, "z#499.wav", 26); + wave->load(1, "z#497.wav", 34); + wave->load(2, "z#498.wav", 38); + wave->load(3, "z#496.wav", 46); + wave->load(4, "z#500.wav", 60); + + wave = musicHandler->createMusicWave(3, 7); + wave->load(0, "z#504.wav", 22); + wave->load(1, "z#507.wav", 29); + wave->load(2, "z#503.wav", 34); + wave->load(3, "z#506.wav", 41); + wave->load(4, "z#502.wav", 46); + wave->load(5, "z#505.wav", 53); + wave->load(6, "z#501.wav", 58); + + CMusicRoom::_musicHandler->setStopWaves(_stopWaves); + } + + return true; +} + +bool CMusicPlayer::TimerMsg(CTimerMsg *msg) { + CCreateMusicPlayerMsg playerMsg; + playerMsg.execute(this); + return true; +} + +bool CMusicPlayer::LoadSuccessMsg(CLoadSuccessMsg *msg) { + if (_isActive) { + CStopMusicMsg stopMsg; + stopMsg.execute(this); + CStartMusicMsg startMsg; + startMsg.execute(this); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/music_player.h b/engines/titanic/sound/music_player.h new file mode 100644 index 0000000000..7b82d4da00 --- /dev/null +++ b/engines/titanic/sound/music_player.h @@ -0,0 +1,64 @@ +/* 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 TITANIC_MUSIC_PLAYER_H +#define TITANIC_MUSIC_PLAYER_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CMusicPlayer : public CGameObject { + DECLARE_MESSAGE_MAP; + bool StartMusicMsg(CStartMusicMsg *msg); + bool StopMusicMsg(CStopMusicMsg *msg); + bool FrameMsg(CFrameMsg *msg); + bool EnterRoomMsg(CEnterRoomMsg *msg); + bool LeaveRoomMsg(CLeaveRoomMsg *msg); + bool CreateMusicPlayerMsg(CCreateMusicPlayerMsg *msg); + bool TimerMsg(CTimerMsg *msg); + bool LoadSuccessMsg(CLoadSuccessMsg *msg); +protected: + bool _isActive; + CString _stopTarget; + bool _stopWaves; + int _musicId; +public: + CLASSDEF; + CMusicPlayer() : CGameObject(), + _isActive(false), _stopWaves(false), _musicId(100) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_PLAYER_H */ diff --git a/engines/titanic/sound/music_room.cpp b/engines/titanic/sound/music_room.cpp new file mode 100644 index 0000000000..34217de184 --- /dev/null +++ b/engines/titanic/sound/music_room.cpp @@ -0,0 +1,65 @@ +/* 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/textconsole.h" +#include "titanic/sound/music_room.h" +#include "titanic/sound/sound.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CMusicHandler *CMusicRoom::_musicHandler; + +CMusicRoom::CMusicRoom(CGameManager *gameManager) : + _gameManager(gameManager) { + _sound = &_gameManager->_sound; + _items.resize(4); +} + +CMusicRoom::~CMusicRoom() { + destroyMusicHandler(); +} + +CMusicHandler *CMusicRoom::createMusicHandler() { + if (_musicHandler) + destroyMusicHandler(); + + _musicHandler = new CMusicHandler(_gameManager->_project, &_sound->_soundManager); + return _musicHandler; +} + +void CMusicRoom::destroyMusicHandler() { + delete _musicHandler; + _musicHandler = nullptr; +} + +void CMusicRoom::startMusic(int musicId) { + // TODO +} + +void CMusicRoom::stopMusic() { + if (_musicHandler) + _musicHandler->stop(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/music_room.h b/engines/titanic/sound/music_room.h new file mode 100644 index 0000000000..15363ef392 --- /dev/null +++ b/engines/titanic/sound/music_room.h @@ -0,0 +1,84 @@ +/* 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 TITANIC_MUSIC_ROOM_H +#define TITANIC_MUSIC_ROOM_H + +#include "common/array.h" +#include "titanic/sound/music_handler.h" + +namespace Titanic { + +class CGameManager; +class CSound; + +class CMusicRoom { + struct Entry { + uint _val1; + uint _val2; + uint _val3; + uint _val4; + uint _val5; + + Entry() : _val1(0), _val2(0), _val3(0), _val4(0), _val5(0) {} + }; +private: + Common::Array<Entry> _items; +public: + static CMusicHandler *_musicHandler; +public: + CGameManager *_gameManager; + CSound *_sound; +public: + CMusicRoom(CGameManager *owner); + ~CMusicRoom(); + + /** + * Creates a music handler + */ + CMusicHandler *createMusicHandler(); + + /** + * Destroys and currently active music handler + */ + void destroyMusicHandler(); + + void setItem1(int index, int val) { _items[index]._val1 = val; } + void setItem2(int index, int val) { _items[index]._val2 = val; } + void setItem3(int index, int val) { _items[index]._val3 = val; } + void setItem4(int index, int val) { _items[index]._val4 = val; } + void setItem5(int index, int val) { _items[index]._val5 = val; } + + /** + * Start playing a given music number + */ + void startMusic(int musicId); + + /** + * Stop playing music + */ + void stopMusic(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_ROOM_H */ diff --git a/engines/titanic/sound/music_wave.cpp b/engines/titanic/sound/music_wave.cpp new file mode 100644 index 0000000000..6b5b187805 --- /dev/null +++ b/engines/titanic/sound/music_wave.cpp @@ -0,0 +1,54 @@ +/* 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 "titanic/sound/music_wave.h" +#include "titanic/sound/sound_manager.h" +#include "titanic/core/project_item.h" + +namespace Titanic { + +CMusicWave::CMusicWave(CProjectItem *project, CSoundManager *soundManager, int index) : + _project(project), _soundManager(soundManager) { +} + +void CMusicWave::setSize(uint count) { + assert(_items.empty()); + _items.resize(count); +} + +void CMusicWave::load(int index, const CString &filename, int v3) { + assert(!_items[index]._waveFile); + _items[index]._waveFile = createWaveFile(filename); + _items[index]._value = v3; +} + +CWaveFile *CMusicWave::createWaveFile(const CString &name) { + if (name.empty()) + return nullptr; + return _soundManager->loadSound(name); +} + +void CMusicWave::stop() { + +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/music_wave.h b/engines/titanic/sound/music_wave.h new file mode 100644 index 0000000000..b240f4a856 --- /dev/null +++ b/engines/titanic/sound/music_wave.h @@ -0,0 +1,71 @@ +/* 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 TITANIC_MUSIC_WAVE_H +#define TITANIC_MUSIC_WAVE_H + +#include "common/array.h" +#include "titanic/support/string.h" + +namespace Titanic { + +class CProjectItem; +class CSoundManager; +class CWaveFile; + +class CMusicWave { + struct CMusicWaveFile { + CWaveFile *_waveFile; + int _value; + CMusicWaveFile() : _waveFile(nullptr), _value(0) {} + }; +private: + CProjectItem *_project; + CSoundManager *_soundManager; + Common::Array<CMusicWaveFile> _items; +private: + /** + * Loads the specified wave file, and returns a CWaveFile instance for it + */ + CWaveFile *createWaveFile(const CString &name); +public: + CMusicWave(CProjectItem *project, CSoundManager *soundManager, int index); + + /** + * Sets the maximum number of allowed files that be defined + */ + void setSize(uint count); + + /** + * Loads a new file into the list of available entries + */ + void load(int index, const CString &filename, int v3); + + /** + * Stops the music + */ + void stop(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_WAVE_H */ diff --git a/engines/titanic/sound/node_auto_sound_player.cpp b/engines/titanic/sound/node_auto_sound_player.cpp new file mode 100644 index 0000000000..40b3d2ea39 --- /dev/null +++ b/engines/titanic/sound/node_auto_sound_player.cpp @@ -0,0 +1,84 @@ +/* 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 "titanic/sound/node_auto_sound_player.h" +#include "titanic/sound/auto_music_player.h" +#include "titanic/core/room_item.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CNodeAutoSoundPlayer, CAutoSoundPlayer) + ON_MESSAGE(EnterNodeMsg) + ON_MESSAGE(LeaveNodeMsg) +END_MESSAGE_MAP() + +void CNodeAutoSoundPlayer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_enabled, indent); + CAutoSoundPlayer::save(file, indent); +} + +void CNodeAutoSoundPlayer::load(SimpleFile *file) { + file->readNumber(); + _enabled = file->readNumber(); + CAutoSoundPlayer::load(file); +} + +bool CNodeAutoSoundPlayer::EnterNodeMsg(CEnterNodeMsg *msg) { + CNodeItem *node = findNode(); + CRoomItem *room = findRoom(); + + if (node == msg->_newNode) { + CTurnOn onMsg; + onMsg.execute(this); + + if (_enabled) { + CChangeMusicMsg changeMsg; + changeMsg._flags = 1; + changeMsg.execute(room, CAutoMusicPlayer::_type, + MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN); + } + } + + return true; +} + +bool CNodeAutoSoundPlayer::LeaveNodeMsg(CLeaveNodeMsg *msg) { + CNodeItem *node = findNode(); + CRoomItem *room = findRoom(); + + if (node == msg->_oldNode) { + CTurnOff offMsg; + offMsg.execute(this); + + if (_enabled) { + CChangeMusicMsg changeMsg; + changeMsg._flags = 2; + changeMsg.execute(room, CAutoMusicPlayer::_type, + MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN); + } + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/node_auto_sound_player.h b/engines/titanic/sound/node_auto_sound_player.h new file mode 100644 index 0000000000..f5bdc42c3c --- /dev/null +++ b/engines/titanic/sound/node_auto_sound_player.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_NODE_AUTO_SOUND_PLAYER_H +#define TITANIC_NODE_AUTO_SOUND_PLAYER_H + +#include "titanic/sound/auto_sound_player.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CNodeAutoSoundPlayer : public CAutoSoundPlayer { + DECLARE_MESSAGE_MAP; + bool EnterNodeMsg(CEnterNodeMsg *msg); + bool LeaveNodeMsg(CLeaveNodeMsg *msg); +private: + bool _enabled; +public: + CLASSDEF; + CNodeAutoSoundPlayer() : CAutoSoundPlayer(), _enabled(true) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NODE_AUTO_SOUND_PLAYER_H */ diff --git a/engines/titanic/sound/proximity.cpp b/engines/titanic/sound/proximity.cpp new file mode 100644 index 0000000000..7f4e6784f2 --- /dev/null +++ b/engines/titanic/sound/proximity.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/sound/proximity.h" +#include "titanic/true_talk/tt_talker.h" + +namespace Titanic { + +CProximity::CProximity() : _field4(0), _channelVolume(100), _fieldC(0), + _priorSoundHandle(-1), _field14(0), _frequencyMultiplier(0.0), _field1C(1.875), + _repeated(false), _channel(10), _positioningMode(POSMODE_NONE), _azimuth(0.0), + _range(0.5), _elevation(0), _posX(0.0), _posY(0.0), _posZ(0.0), + _hasVelocity(false), _velocityX(0), _velocityY(0), _velocityZ(0), + _field54(0), _field58(0), _field5C(0), _freeSoundFlag(false), _endTalkerFn(nullptr), + _talker(nullptr), _field6C(0) { +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/proximity.h b/engines/titanic/sound/proximity.h new file mode 100644 index 0000000000..b728f22c26 --- /dev/null +++ b/engines/titanic/sound/proximity.h @@ -0,0 +1,71 @@ +/* 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 TITANIC_PROXIMITY_H +#define TITANIC_PROXIMITY_H + +#include "common/scummsys.h" + +namespace Titanic { + +enum PositioningMode { POSMODE_NONE = 0, POSMODE_POLAR = 1, POSMODE_VECTOR = 2 }; + +class TTtalker; + +typedef void (*CEndTalkerFn)(TTtalker *talker); + +class CProximity { +public: + int _field4; + int _channelVolume; + int _fieldC; + int _priorSoundHandle; + int _field14; + double _frequencyMultiplier; + double _field1C; + bool _repeated; + int _channel; + PositioningMode _positioningMode; + double _azimuth; + double _range; + double _elevation; + double _posX; + double _posY; + double _posZ; + bool _hasVelocity; + double _velocityX; + double _velocityY; + double _velocityZ; + int _field54; + int _field58; + int _field5C; + bool _freeSoundFlag; + CEndTalkerFn _endTalkerFn; + TTtalker *_talker; + int _field6C; +public: + CProximity(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PROXIMITY_H */ diff --git a/engines/titanic/sound/qmixer.cpp b/engines/titanic/sound/qmixer.cpp new file mode 100644 index 0000000000..145d142b2d --- /dev/null +++ b/engines/titanic/sound/qmixer.cpp @@ -0,0 +1,173 @@ +/* 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 "titanic/sound/qmixer.h" + +namespace Titanic { + +QMixer::QMixer(Audio::Mixer *mixer) : _mixer(mixer) { +} + +bool QMixer::qsWaveMixInitEx(const QMIXCONFIG &config) { + assert(_channels.empty()); + assert(config.iChannels > 0 && config.iChannels < 256); + + _channels.resize(config.iChannels); + return true; +} + +void QMixer::qsWaveMixActivate(bool fActivate) { + // Not currently implemented in ScummVM +} + +int QMixer::qsWaveMixOpenChannel(int iChannel, QMixFlag mode) { + // Not currently implemented in ScummVM + return 0; +} + +int QMixer::qsWaveMixEnableChannel(int iChannel, uint flags, bool enabled) { + // Not currently implemented in ScummVM + return 0; +} + +void QMixer::qsWaveMixCloseSession() { + _mixer->stopAll(); + _channels.clear(); +} + +void QMixer::qsWaveMixFreeWave(Audio::SoundHandle &handle) { + _mixer->stopHandle(handle); +} + +void QMixer::qsWaveMixFlushChannel(int iChannel, uint flags) { + // Not currently implemented in ScummVM +} + +void QMixer::qsWaveMixSetPanRate(int iChannel, uint flags, uint rate) { + // Not currently implemented in ScummVM +} + +void QMixer::qsWaveMixSetVolume(int iChannel, uint flags, uint volume) { + // Not currently implemented in ScummVM +} + +void QMixer::qsWaveMixSetSourcePosition(int iChannel, uint flags, const QSVECTOR &position) { + // Not currently implemented in ScummVM +} + +void QMixer::qsWaveMixSetPolarPosition(int iChannel, uint flags, const QSPOLAR &position) { + // Not currently implemented in ScummVM +} + +void QMixer::qsWaveMixSetListenerPosition(const QSVECTOR &position, uint flags) { + // Not currently implemented in ScummVM +} + +void QMixer::qsWaveMixSetListenerOrientation(const QSVECTOR &direction, const QSVECTOR &up, uint flags) { + // Not currently implemented in ScummVM +} + +void QMixer::qsWaveMixSetDistanceMapping(int iChannel, uint flags, const QMIX_DISTANCES &distances) { + // Not currently implemented in ScummVM +} + +void QMixer::qsWaveMixSetFrequency(int iChannel, uint flags, uint frequency) { + // Not currently implemented in ScummVM +} + +void QMixer::qsWaveMixSetSourceVelocity(int iChannel, uint flags, const QSVECTOR &velocity) { + // Not currently implemented in ScummVM +} + +int QMixer::qsWaveMixPlayEx(int iChannel, uint flags, CWaveFile *waveFile, int loops, const QMIXPLAYPARAMS ¶ms) { + if (iChannel == -1) { + // Find a free channel + for (iChannel = 0; iChannel < (int)_channels.size(); ++iChannel) { + if (_channels[iChannel]._sounds.empty()) + break; + } + assert(iChannel != (int)_channels.size()); + } + + // If the new sound replaces current ones, then clear the channel + ChannelEntry &channel = _channels[iChannel]; + if (flags & QMIX_CLEARQUEUE) { + if (!channel._sounds.empty() && channel._sounds.front()._started) + _mixer->stopHandle(channel._sounds.front()._soundHandle); + + channel._sounds.clear(); + } + + // Add the sound to the channel + channel._sounds.push_back(SoundEntry(waveFile, params.callback, loops, params.dwUser)); + qsWaveMixPump(); + + return 0; +} + +bool QMixer::qsWaveMixIsChannelDone(int iChannel) const { + return _channels[iChannel]._sounds.empty(); +} + +void QMixer::qsWaveMixPump() { + // Iterate through each of the channels + for (uint iChannel = 0; iChannel < _channels.size(); ++iChannel) { + ChannelEntry &channel = _channels[iChannel]; + + // If the playing sound on the channel is finished, then call + // the callback registered for it, and remove it from the list + if (!channel._sounds.empty()) { + SoundEntry &sound = channel._sounds.front(); + if (sound._started && !_mixer->isSoundHandleActive(sound._soundHandle)) { + if (sound._loops == -1 || sound._loops-- > 0) { + // Need to loop the sound again + sound._waveFile->_stream->rewind(); + _mixer->playStream(sound._waveFile->_soundType, + &sound._soundHandle, sound._waveFile->_stream, + -1, 0xff, 0, DisposeAfterUse::NO); + } else { + // Sound is finished + if (sound._callback) + // Call the callback to signal end + sound._callback(iChannel, sound._waveFile, sound._userData); + + // Remove sound record from channel + channel._sounds.erase(channel._sounds.begin()); + } + } + } + + // If there's an unstarted sound at the front of a channel's + // sound list, then start it playing + if (!channel._sounds.empty()) { + SoundEntry &sound = channel._sounds.front(); + if (!sound._started) { + _mixer->playStream(sound._waveFile->_soundType, + &sound._soundHandle, sound._waveFile->_stream, + -1, 0xff, 0, DisposeAfterUse::NO); + sound._started = true; + } + } + } +} + +} // End of namespace Titanic z diff --git a/engines/titanic/sound/qmixer.h b/engines/titanic/sound/qmixer.h new file mode 100644 index 0000000000..4ba76a8969 --- /dev/null +++ b/engines/titanic/sound/qmixer.h @@ -0,0 +1,312 @@ +/* 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_QMIXER_H +#define TITANIC_QMIXER_H + +#include "audio/mixer.h" +#include "titanic/sound/wave_file.h" + +namespace Titanic { + +enum QMixFlag { + QMIX_OPENSINGLE = 0, // Open the single channel specified by iChannel + QMIX_OPENALL = 1, // Opens all the channels, iChannel ignored + QMIX_OPENCOUNT = 2, // Open iChannel Channels (eg. if iChannel = 4 will create channels 0-3) + QMIX_OPENAVAILABLE = 3, // Open the first unopened channel, and return channel number + + // Channel function flags + QMIX_ALL = 0x01, // apply to all channels + QMIX_NOREMIX = 0x02, // don't remix + QMIX_CONTROL_NOREMIX = 0x04, // don't remix + QMIX_USEONCE = 0x10 // settings are temporary +}; + +// qsWaveMixEnableChannel flags: if mode==0, use conventional, high-performance +// stereo mixer. Non-zero modes imply some form of additional processing. +enum QMixChannelFlag { + QMIX_CHANNEL_STEREO = 0x0000, // Perform stereo mixing + QMIX_CHANNEL_QSOUND = 0x0001, // Perform QSound localization (default) + QMIX_CHANNEL_DOPPLER = 0x0002, // Calculate velocity using position updates + QMIX_CHANNEL_RANGE = 0x0004, // Do range effects + QMIX_CHANNEL_ELEVATION = 0x0008, // Do elevation effects + QMIX_CHANNEL_NODOPPLERPITCH = 0x0010, // Disable Doppler pitch shift for this channel + QMIX_CHANNEL_PITCH_COPY = 0x0000, // Pitch shifting using copying (fastest) + QMIX_CHANNEL_PITCH_LINEAR = 0x0100, // Pitch shifting using linear interpolation (better but slower) + QMIX_CHANNEL_PITCH_SPLINE = 0x0200, // Pitch shifting using spline interpolation (better yet, but much slower) + QMIX_CHANNEL_PITCH_FILTER = 0x0300, // Pitch shifting using FIR filter (best, but slowest) + QMIX_CHANNEL_PITCH_MASK = 0x0700 // Bits reserved for pitch types +}; + +/** + * Options for dwFlags parameter in QSWaveMixPlayEx. + * + * Notes: The QMIX_USELRUCHANNEL flag has two roles. When QMIX_CLEARQUEUE is also set, + * the channel that has been playing the longest (least-recently-used) is cleared and + * the buffer played. When QMIX_QUEUEWAVE is set, the channel that will first finish + * playing will be selected and the buffer queued to play. Of course, if an unused + * channel is found, it will be selected instead. + * If QMIX_WAIT hasn't been specified, then the channel number will be returned + * in the iChannel field. + */ +enum QMixPlayFlag { + QMIX_QUEUEWAVE = 0x0000, // Queue on channel + QMIX_CLEARQUEUE = 0x0001, // Clear queue on channel + QMIX_USELRUCHANNEL = 0x0002, // See notes above + QMIX_HIGHPRIORITY = 0x0004, + QMIX_WAIT = 0x0008, // Queue to be played with other sounds + QMIX_IMMEDIATE = 0x0020, // Apply volume/pan changes without interpolation + + QMIX_PLAY_SETEVENT = 0x0100, // Calls SetEvent in the original library when done + QMIX_PLAY_PULSEEVENT = 0x0200, // Calls PulseEvent in the original library when done + QMIX_PLAY_NOTIFYSTOP = 0x0400 // Do callback even when stopping or flushing sound +}; + +/** + * Mixer configuration structure for qsWaveMixInitEx + */ +struct QMIXCONFIG { + uint32 dwSize; + uint32 dwFlags; + uint32 dwSamplingRate; // Sampling rate in Hz + void *lpIDirectSound; + const void *lpGuid; + int iChannels; // Number of channels + int iOutput; // if 0, uses best output device + int iLatency; // (in ms) if 0, uses default for output device + int iMath; // style of math + uint hwnd; + + QMIXCONFIG() : dwSize(40), dwFlags(0), dwSamplingRate(0), lpIDirectSound(nullptr), + lpGuid(nullptr), iChannels(0), iOutput(0), iLatency(0), iMath(0), hwnd(0) {} + QMIXCONFIG(uint32 rate, int channels, int latency) : dwSize(40), dwFlags(0), + dwSamplingRate(rate), iChannels(channels), iLatency(latency), + lpIDirectSound(nullptr), lpGuid(nullptr), iOutput(0), iMath(0), hwnd(0) {} +}; + +/** + * Vector positioning in metres + */ +struct QSVECTOR { + double x; + double y; + double z; + + QSVECTOR() : x(0.0), y(0.0), z(0.0) {} + QSVECTOR(double xp, double yp, double zp) : x(xp), y(yp), z(zp) {} +}; + +/** + * Polar positioning + */ +struct QSPOLAR { + double azimuth; // degrees + double range; // meters + double elevation; // degrees + + QSPOLAR() : azimuth(0.0), range(0.0), elevation(0.0) {} + QSPOLAR(double azimuth_, double range_, double elevation_) : + azimuth(azimuth_), range(range_), elevation(elevation_) {} +}; + +struct QMIX_DISTANCES { + int cbSize; // Structure size + double minDistance; // sounds are at full volume if closer than this + double maxDistance; // sounds are muted if further away than this + double scale; // relative amount to adjust rolloff by + + QMIX_DISTANCES() : cbSize(16), minDistance(0.0), maxDistance(0.0), scale(0.0) {} + QMIX_DISTANCES(double minDistance_, double maxDistance_, double scale_) : + cbSize(16), minDistance(minDistance_), maxDistance(maxDistance_), scale(scale_) {} +}; + +typedef void (*LPQMIXDONECALLBACK)(int iChannel, CWaveFile *lpWave, void *dwUser); + +struct QMIXPLAYPARAMS { + uint dwSize; // Size of the play structure + void *lpImage; // Additional preprocessed audio for high performance + uint hwndNotify; // if set, WOM_OPEN and WOM_DONE messages sent to that window + LPQMIXDONECALLBACK callback; // Callback function + void *dwUser; // User data accompanying callback + int lStart; + int lStartLoop; + int lEndLoop; + int lEnd; + const void *lpChannelParams; // initialize with these parameters + // Properties introduced by ScummVM + Audio::Mixer::SoundType _soundType; + + QMIXPLAYPARAMS() : dwSize(36), lpImage(nullptr), hwndNotify(0), callback(nullptr), + dwUser(nullptr), lStart(0), lStartLoop(0), lEndLoop(0), lEnd(0), + lpChannelParams(nullptr), _soundType(Audio::Mixer::kPlainSoundType) {} +}; + +/** + * This class represents an interface to the QMixer library developed by + * QSound Labs, Inc. Which itself is apparently based on Microsoft's + * WaveMix API. + * + * It does not currently have any actual code from the library, + * and instead remaps calls to ScummVM's existing mixer where possible. + * This means that advanced features of the QMixer library, like being + * able to set up both the player and sounds at different positions are + * currently ignored, and all sounds play at full volume. + */ +class QMixer { + struct SoundEntry { + bool _started; + CWaveFile *_waveFile; + Audio::SoundHandle _soundHandle; + LPQMIXDONECALLBACK _callback; + int _loops; + void *_userData; + SoundEntry() : _started(false), _waveFile(nullptr), _callback(nullptr), + _loops(0), _userData(nullptr) {} + + SoundEntry(CWaveFile *waveFile, LPQMIXDONECALLBACK callback, int loops, void *userData) : + _started(false), _waveFile(waveFile), _callback(callback), _loops(loops), _userData(userData) {} + }; + struct ChannelEntry { + Common::List<SoundEntry> _sounds; + }; +private: + Audio::Mixer *_mixer; + Common::Array<ChannelEntry> _channels; +public: + QMixer(Audio::Mixer *mixer); + virtual ~QMixer() {} + + /** + * Initializes the mixer + */ + bool qsWaveMixInitEx(const QMIXCONFIG &config); + + /** + * Activates the mixer + */ + void qsWaveMixActivate(bool fActivate); + + /** + * Opens channels in the mixer for access + */ + int qsWaveMixOpenChannel(int iChannel, QMixFlag mode); + + /** + * Enables a given channel + */ + int qsWaveMixEnableChannel(int iChannel, uint flags, bool enabled); + + /** + * Closes down the mixer + */ + void qsWaveMixCloseSession(); + + /** + * Stops a sound from playing + */ + void qsWaveMixFreeWave(Audio::SoundHandle &handle); + + /** + * Flushes a channel + */ + void qsWaveMixFlushChannel(int iChannel, uint flags = 0); + + /** + * Sets the amount of time, in milliseconds, to effect a change in + * a channel property (e.g. volume, position). Non-zero values + * smooth out changes + * @param iChannel Channel to change + * @param flags Flags + * @param rate Pan rate in milliseconds + */ + void qsWaveMixSetPanRate(int iChannel, uint flags, uint rate); + + /** + * Sets the volume for a channel + */ + void qsWaveMixSetVolume(int iChannel, uint flags, uint volume); + + /** + * Sets the relative position of a channel + * @param iChannel Channel number + * @param Flags Flags + * @param position Vector position for channel + */ + void qsWaveMixSetSourcePosition(int iChannel, uint flags, const QSVECTOR &position); + + /** + * Sets the relative position of a channel using polar co-ordinates + * @param iChannel Channel number + * @param Flags Flags + * @param position Polar position for channel + */ + void qsWaveMixSetPolarPosition(int iChannel, uint flags, const QSPOLAR &position); + + /** + * Sets the listener position + */ + void qsWaveMixSetListenerPosition(const QSVECTOR &position, uint flags = 0); + + /** + * Sets the listener orientation + */ + void qsWaveMixSetListenerOrientation(const QSVECTOR &direction, const QSVECTOR &up, uint flags = 0); + + /** + * Sets the mapping ditance range + */ + void qsWaveMixSetDistanceMapping(int iChannel, uint flags, const QMIX_DISTANCES &distances); + + /** + * + */ + void qsWaveMixSetFrequency(int iChannel, uint flags, uint frequency); + + /** + * Sets the velocity of the source (listener) + */ + void qsWaveMixSetSourceVelocity(int iChannel, uint flags, const QSVECTOR &velocity); + + /** + * Plays sound + * @param iChannel The channel number to be played on + * @param flags Play flags + * @param mixWave Data for the sound to be played + * @param loops Number of loops to play (-1 for forever) + * @param params Playback parameter data + */ + int qsWaveMixPlayEx(int iChannel, uint flags, CWaveFile *waveFile, int loops, const QMIXPLAYPARAMS ¶ms); + + /** + * Returns true if there are no more buffers playing or queued on the channel + */ + bool qsWaveMixIsChannelDone(int iChannel) const; + + /** + * Handles regularly updating the mixer + */ + void qsWaveMixPump(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_QMIXER_H */ diff --git a/engines/titanic/sound/restricted_auto_music_player.cpp b/engines/titanic/sound/restricted_auto_music_player.cpp new file mode 100644 index 0000000000..2384d4da25 --- /dev/null +++ b/engines/titanic/sound/restricted_auto_music_player.cpp @@ -0,0 +1,79 @@ +/* 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 "titanic/sound/restricted_auto_music_player.h" +#include "titanic/core/room_item.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CRestrictedAutoMusicPlayer, CAutoMusicPlayer) + ON_MESSAGE(EnterRoomMsg) + ON_MESSAGE(LeaveRoomMsg) +END_MESSAGE_MAP() + +void CRestrictedAutoMusicPlayer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_oldNodeName, indent); + file->writeQuotedLine(_newNodeName, indent); + file->writeQuotedLine(_newRoomName, indent); + file->writeQuotedLine(_oldRoomName, indent); + + CAutoMusicPlayer::save(file, indent); +} + +void CRestrictedAutoMusicPlayer::load(SimpleFile *file) { + file->readNumber(); + _oldNodeName = file->readString(); + _newNodeName = file->readString(); + _newRoomName = file->readString(); + _oldRoomName = file->readString(); + + CAutoMusicPlayer::load(file); +} + +bool CRestrictedAutoMusicPlayer::EnterRoomMsg(CEnterRoomMsg *msg) { + if (!msg->_oldRoom) + return true; + if (petCheckNode(_oldNodeName)) + return false; + + CString roomName = msg->_oldRoom->getName(); + if (_oldRoomName.compareToIgnoreCase(roomName)) { + _isRepeated = true; + return false; + } else { + return CAutoMusicPlayer::EnterRoomMsg(msg); + } +} + +bool CRestrictedAutoMusicPlayer::LeaveRoomMsg(CLeaveRoomMsg *msg) { + CString roomName = msg->_newRoom->getName(); + + if (petCheckNode(_newNodeName) || _newRoomName.compareToIgnoreCase(roomName)) { + _isRepeated = false; + return true; + } else { + return CAutoMusicPlayer::LeaveRoomMsg(msg); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/restricted_auto_music_player.h b/engines/titanic/sound/restricted_auto_music_player.h new file mode 100644 index 0000000000..d36ee5a7ab --- /dev/null +++ b/engines/titanic/sound/restricted_auto_music_player.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_RESTRICTED_AUTO_MUSIC_PLAYER_H +#define TITANIC_RESTRICTED_AUTO_MUSIC_PLAYER_H + +#include "titanic/sound/auto_music_player.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CRestrictedAutoMusicPlayer : public CAutoMusicPlayer { + DECLARE_MESSAGE_MAP; + bool EnterRoomMsg(CEnterRoomMsg *msg); + bool LeaveRoomMsg(CLeaveRoomMsg *msg); +private: + CString _oldNodeName; + CString _newNodeName; + CString _newRoomName; + CString _oldRoomName; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_RESTRICTED_AUTO_MUSIC_PLAYER_H */ diff --git a/engines/titanic/sound/room_auto_sound_player.cpp b/engines/titanic/sound/room_auto_sound_player.cpp new file mode 100644 index 0000000000..cad7c10771 --- /dev/null +++ b/engines/titanic/sound/room_auto_sound_player.cpp @@ -0,0 +1,62 @@ +/* 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 "titanic/sound/room_auto_sound_player.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CRoomAutoSoundPlayer, CAutoSoundPlayer) + ON_MESSAGE(EnterRoomMsg) + ON_MESSAGE(LeaveRoomMsg) +END_MESSAGE_MAP() + +void CRoomAutoSoundPlayer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CAutoSoundPlayer::save(file, indent); +} + +void CRoomAutoSoundPlayer::load(SimpleFile *file) { + file->readNumber(); + CAutoSoundPlayer::load(file); +} + +bool CRoomAutoSoundPlayer::EnterRoomMsg(CEnterRoomMsg *msg) { + CRoomItem *room = findRoom(); + if (room == msg->_newRoom) { + CTurnOn onMsg; + onMsg.execute(this); + } + + return true; +} + +bool CRoomAutoSoundPlayer::LeaveRoomMsg(CLeaveRoomMsg *msg) { + CRoomItem *room = findRoom(); + if (room == msg->_oldRoom) { + CTurnOff offMsg; + offMsg.execute(this); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/room_auto_sound_player.h b/engines/titanic/sound/room_auto_sound_player.h new file mode 100644 index 0000000000..56525ccfa3 --- /dev/null +++ b/engines/titanic/sound/room_auto_sound_player.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_ROOM_AUTO_SOUND_PLAYER_H +#define TITANIC_ROOM_AUTO_SOUND_PLAYER_H + +#include "titanic/sound/auto_sound_player.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CRoomAutoSoundPlayer : public CAutoSoundPlayer { + DECLARE_MESSAGE_MAP; + bool EnterRoomMsg(CEnterRoomMsg *msg); + bool LeaveRoomMsg(CLeaveRoomMsg *msg); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ROOM_AUTO_SOUND_PLAYER_H */ diff --git a/engines/titanic/sound/room_trigger_auto_music_player.cpp b/engines/titanic/sound/room_trigger_auto_music_player.cpp new file mode 100644 index 0000000000..7782cef0e2 --- /dev/null +++ b/engines/titanic/sound/room_trigger_auto_music_player.cpp @@ -0,0 +1,62 @@ +/* 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 "titanic/sound/room_trigger_auto_music_player.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CRoomTriggerAutoMusicPlayer, CTriggerAutoMusicPlayer) + ON_MESSAGE(LeaveRoomMsg) + ON_MESSAGE(EnterRoomMsg) +END_MESSAGE_MAP() + +void CRoomTriggerAutoMusicPlayer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CTriggerAutoMusicPlayer::save(file, indent); +} + +void CRoomTriggerAutoMusicPlayer::load(SimpleFile *file) { + file->readNumber(); + CTriggerAutoMusicPlayer::load(file); +} + +bool CRoomTriggerAutoMusicPlayer::LeaveRoomMsg(CLeaveRoomMsg *msg) { + if (msg->_oldRoom == findRoom()) { + CTriggerAutoMusicPlayerMsg triggerMsg; + triggerMsg._value = 1; + triggerMsg.execute(this); + } + + return true; +} + +bool CRoomTriggerAutoMusicPlayer::EnterRoomMsg(CEnterRoomMsg *msg) { + if (msg->_newRoom == findRoom()) { + CTriggerAutoMusicPlayerMsg triggerMsg; + triggerMsg._value = 2; + triggerMsg.execute(this); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/room_trigger_auto_music_player.h b/engines/titanic/sound/room_trigger_auto_music_player.h new file mode 100644 index 0000000000..a57e133eb6 --- /dev/null +++ b/engines/titanic/sound/room_trigger_auto_music_player.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_ROOM_TRIGGER_AUTO_MUSIC_PLAYER_H +#define TITANIC_ROOM_TRIGGER_AUTO_MUSIC_PLAYER_H + +#include "titanic/sound/trigger_auto_music_player.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CRoomTriggerAutoMusicPlayer : public CTriggerAutoMusicPlayer { + DECLARE_MESSAGE_MAP; + bool LeaveRoomMsg(CLeaveRoomMsg *msg); + bool EnterRoomMsg(CEnterRoomMsg *msg); +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ROOM_TRIGGER_AUTO_MUSIC_PLAYER_H */ diff --git a/engines/titanic/sound/season_noises.cpp b/engines/titanic/sound/season_noises.cpp new file mode 100644 index 0000000000..ce045488ee --- /dev/null +++ b/engines/titanic/sound/season_noises.cpp @@ -0,0 +1,115 @@ +/* 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 "titanic/sound/season_noises.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CSeasonNoises, CViewAutoSoundPlayer) + ON_MESSAGE(ChangeSeasonMsg) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(ActMsg) + ON_MESSAGE(LoadSuccessMsg) +END_MESSAGE_MAP() + +CSeasonNoises::CSeasonNoises() : CViewAutoSoundPlayer(), _seasonNumber(0), + _springName("NULL"), _summerName("NULL"), _autumnName("NULL"), _winterName("NULL") { +} + +void CSeasonNoises::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_seasonNumber, indent); + file->writeQuotedLine(_springName, indent); + file->writeQuotedLine(_summerName, indent); + file->writeQuotedLine(_autumnName, indent); + file->writeQuotedLine(_winterName, indent); + + CViewAutoSoundPlayer::save(file, indent); +} + +void CSeasonNoises::load(SimpleFile *file) { + file->readNumber(); + _seasonNumber = file->readNumber(); + _springName = file->readString(); + _summerName = file->readString(); + _autumnName = file->readString(); + _winterName = file->readString(); + + CViewAutoSoundPlayer::load(file); +} + +bool CSeasonNoises::ChangeSeasonMsg(CChangeSeasonMsg *msg) { + _seasonNumber = (_seasonNumber + 1) % 4; + CActMsg actMsg("Update"); + actMsg.execute(this); + + return true; +} + +bool CSeasonNoises::EnterViewMsg(CEnterViewMsg *msg) { + CActMsg actMsg("Update"); + return true; +} + +bool CSeasonNoises::ActMsg(CActMsg *msg) { + msg->_action = "Update"; + + switch (_seasonNumber) { + case 0: + _filename = _springName; + break; + case 1: + _filename = _summerName; + break; + case 2: + _filename = _autumnName; + break; + case 3: + _filename = _winterName; + break; + default: + break; + } + + CSignalObject signalMsg; + signalMsg._numValue = 2; + signalMsg.execute(this); + + CTurnOn onMsg; + onMsg.execute(this); + + return true; +} + +bool CSeasonNoises::LoadSuccessMsg(CLoadSuccessMsg *msg) { + if (_active) { + _active = false; + _soundHandle = -1; + + CActMsg actMsg("Update"); + actMsg.execute(this); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/season_noises.h b/engines/titanic/sound/season_noises.h new file mode 100644 index 0000000000..796628d10d --- /dev/null +++ b/engines/titanic/sound/season_noises.h @@ -0,0 +1,59 @@ +/* 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 TITANIC_SEASON_NOISES_H +#define TITANIC_SEASON_NOISES_H + +#include "titanic/sound/view_auto_sound_player.h" + +namespace Titanic { + +class CSeasonNoises : public CViewAutoSoundPlayer { + DECLARE_MESSAGE_MAP; + bool ChangeSeasonMsg(CChangeSeasonMsg *msg); + bool EnterViewMsg(CEnterViewMsg *msg); + bool ActMsg(CActMsg *msg); + bool LoadSuccessMsg(CLoadSuccessMsg *msg); +private: + int _seasonNumber; + CString _springName; + CString _summerName; + CString _autumnName; + CString _winterName; +public: + CLASSDEF; + CSeasonNoises(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SEASON_NOISES_H */ diff --git a/engines/titanic/sound/seasonal_music_player.cpp b/engines/titanic/sound/seasonal_music_player.cpp new file mode 100644 index 0000000000..3532311bdf --- /dev/null +++ b/engines/titanic/sound/seasonal_music_player.cpp @@ -0,0 +1,135 @@ +/* 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 "titanic/sound/seasonal_music_player.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CSeasonalMusicPlayer, CAutoMusicPlayerBase) + ON_MESSAGE(ChangeSeasonMsg) + ON_MESSAGE(ArboretumGateMsg) + ON_MESSAGE(ChangeMusicMsg) +END_MESSAGE_MAP() + +CSeasonalMusicPlayer::CSeasonalMusicPlayer() : CAutoMusicPlayerBase() { + _isSpring = false; + _isSummer = true; + _isAutumn = false; + _isWinter = false; + _springMode = -4; + _summerMode = -2; + _autumnMode = -4; + _winterMode = -4; +} + +void CSeasonalMusicPlayer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_isSpring, indent); + file->writeNumberLine(_isSummer, indent); + file->writeNumberLine(_isAutumn, indent); + file->writeNumberLine(_isWinter, indent); + file->writeNumberLine(_springMode, indent); + file->writeNumberLine(_summerMode, indent); + file->writeNumberLine(_autumnMode, indent); + file->writeNumberLine(_winterMode, indent); + + CAutoMusicPlayerBase::save(file, indent); +} + +void CSeasonalMusicPlayer::load(SimpleFile *file) { + file->readNumber(); + _isSpring = file->readNumber(); + _isSummer = file->readNumber(); + _isAutumn = file->readNumber(); + _isWinter = file->readNumber(); + _springMode = file->readNumber(); + _summerMode = file->readNumber(); + _autumnMode = file->readNumber(); + _winterMode = file->readNumber(); + + CAutoMusicPlayerBase::load(file); +} + +bool CSeasonalMusicPlayer::ChangeSeasonMsg(CChangeSeasonMsg *msg) { + _isSpring = msg->_season == "spring"; + _isSummer = msg->_season == "summer"; + _isAutumn = msg->_season == "autumn"; + _isWinter = msg->_season == "winter"; + + _springMode = _isSpring ? -2 : -4; + _summerMode = _isSummer ? -2 : -4; + _autumnMode = _isAutumn ? -2 : -4; + _winterMode = _isWinter ? -2 : -4; + + CChangeMusicMsg changeMsg; + changeMsg._filename = msg->_season; + changeMsg.execute(this); + + return true; +} + +bool CSeasonalMusicPlayer::ArboretumGateMsg(CArboretumGateMsg *msg) { + CChangeMusicMsg changeMsg; + changeMsg._flags = msg->_value ? 2 : 1; + changeMsg.execute(this); + + return true; +} + +bool CSeasonalMusicPlayer::ChangeMusicMsg(CChangeMusicMsg *msg) { + if (_isRepeated && msg->_flags == 1) { + _isRepeated = false; + stopGlobalSound(_transition, -1); + } + + if (!msg->_filename.empty()) { + if (_isSummer) { + setGlobalSoundVolume(-4, 2, 0); + setGlobalSoundVolume(-2, 2, 1); + } else if (_isAutumn) { + setGlobalSoundVolume(-4, 2, 1); + setGlobalSoundVolume(-2, 2, 2); + } else if (_isWinter) { + setGlobalSoundVolume(-4, 2, 2); + setGlobalSoundVolume(-2, 2, 3); + } else if (_isSpring) { + setGlobalSoundVolume(-4, 2, 3); + setGlobalSoundVolume(-2, 2, 0); + } + } + + if (!_isRepeated && msg->_flags == 2) { + _isRepeated = true; + loadSound("c#64.wav"); + loadSound("c#63.wav"); + loadSound("c#65.wav"); + loadSound("c#62.wav"); + playGlobalSound("c#64.wav", _springMode, _isSpring, true, 0); + playGlobalSound("c#63.wav", _summerMode, _isSummer, true, 1); + playGlobalSound("c#65.wav", _autumnMode, _isAutumn, true, 2); + playGlobalSound("c#62.wav", _winterMode, _isWinter, true, 3); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/seasonal_music_player.h b/engines/titanic/sound/seasonal_music_player.h new file mode 100644 index 0000000000..d6a79d73da --- /dev/null +++ b/engines/titanic/sound/seasonal_music_player.h @@ -0,0 +1,61 @@ +/* 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 TITANIC_SEASONAL_MUSIC_PLAYER_H +#define TITANIC_SEASONAL_MUSIC_PLAYER_H + +#include "titanic/sound/auto_music_player_base.h" + +namespace Titanic { + +class CSeasonalMusicPlayer : public CAutoMusicPlayerBase { + DECLARE_MESSAGE_MAP; + bool ChangeSeasonMsg(CChangeSeasonMsg *msg); + bool ArboretumGateMsg(CArboretumGateMsg *msg); + bool ChangeMusicMsg(CChangeMusicMsg *msg); +private: + bool _isSpring; + bool _isSummer; + bool _isAutumn; + bool _isWinter; + int _springMode; + int _summerMode; + int _autumnMode; + int _winterMode; +public: + CLASSDEF; + CSeasonalMusicPlayer(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SEASONAL_MUSIC_PLAYER_H */ diff --git a/engines/titanic/sound/sound.cpp b/engines/titanic/sound/sound.cpp new file mode 100644 index 0000000000..7e791c2ba5 --- /dev/null +++ b/engines/titanic/sound/sound.cpp @@ -0,0 +1,223 @@ +/* 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 "titanic/sound/sound.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CSound::CSound(CGameManager *owner, Audio::Mixer *mixer) : + _gameManager(owner), _soundManager(mixer) { + g_vm->_movieManager.setSoundManager(&_soundManager); +} + +void CSound::save(SimpleFile *file) const { + _soundManager.save(file); +} + +void CSound::load(SimpleFile *file) { + _soundManager.load(file); +} + +void CSound::preLoad() { + _soundManager.preLoad(); + + if (_gameManager) + _gameManager->_musicRoom.destroyMusicHandler(); +} + +void CSound::preEnterView(CViewItem *newView, bool isNewRoom) { + CNodeItem *node = newView->findNode(); + double xp, yp, zp; + node->getPosition(xp, yp, zp); + + double cosVal = cos(newView->_angle); + double sinVal = -sin(newView->_angle); + + _soundManager.setListenerPosition(xp, yp, zp, cosVal, sinVal, 0, isNewRoom); +} + +bool CSound::isActive(int handle) const { + if (handle != 0 && handle != -1) + return _soundManager.isActive(handle); + + return false; +} + +void CSound::setVolume(uint handle, uint volume, uint seconds) { + _soundManager.setVolume(handle, volume, seconds); +} + +void CSound::activateSound(CWaveFile *waveFile, bool freeFlag) { + for (CSoundItemList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) { + CSoundItem *sound = *i; + if (sound->_waveFile == waveFile) { + sound->_active = true; + sound->_freeFlag = freeFlag; + + if (!freeFlag && waveFile->size() > 51200) + sound->_freeFlag = true; + break; + } + } +} + +void CSound::stopChannel(int channel) { + _soundManager.stopChannel(channel); +} + +void CSound::checkSounds() { + for (CSoundItemList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) { + CSoundItem *soundItem = *i; + if (soundItem->_active && soundItem->_freeFlag) { + if (_soundManager.isActive(soundItem->_waveFile)) { + _sounds.remove(soundItem); + delete soundItem; + } + } + } +} + +void CSound::removeOldest() { + for (CSoundItemList::iterator i = _sounds.reverse_begin(); + i != _sounds.end(); --i) { + CSoundItem *soundItem = *i; + if (soundItem->_active && !_soundManager.isActive(soundItem->_waveFile)) { + _sounds.remove(soundItem); + delete soundItem; + break; + } + } +} + +CWaveFile *CSound::getTrueTalkSound(CDialogueFile *dialogueFile, int index) { + return loadSpeech(dialogueFile, index); +} + +CWaveFile *CSound::loadSound(const CString &name) { + checkSounds(); + + // Check whether an entry for the given name is already active + for (CSoundItemList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) { + CSoundItem *soundItem = *i; + if (soundItem->_name == name) { + // Found it, so move it to the front of the list and return + _sounds.remove(soundItem); + _sounds.push_front(soundItem); + return soundItem->_waveFile; + } + } + + // Create new sound item + CSoundItem *soundItem = new CSoundItem(name); + soundItem->_waveFile = _soundManager.loadSound(name); + + if (!soundItem->_waveFile) { + // Couldn't load sound, so destroy new item and return + delete soundItem; + return 0; + } + + // Add the item to the list of sounds + _sounds.push_front(soundItem); + + // If there are more than 10 sounds loaded, remove the last one, + // which is the least recently used of all of them + if (_sounds.size() > 10) + removeOldest(); + + return soundItem->_waveFile; +} + +int CSound::playSound(const CString &name, CProximity &prox) { + CWaveFile *waveFile = loadSound(name); + if (!waveFile) + return -1; + + prox._field6C = waveFile->fn1(); + activateSound(waveFile, prox._freeSoundFlag); + + return _soundManager.playSound(*waveFile, prox); +} + +CWaveFile *CSound::loadSpeech(CDialogueFile *dialogueFile, int speechId) { + checkSounds(); + + // Check whether an entry for the given name is already active + for (CSoundItemList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) { + CSoundItem *soundItem = *i; + if (soundItem->_dialogueFileHandle == dialogueFile->getFile() + && soundItem->_speechId == speechId) { + // Found it, so move it to the front of the list and return + _sounds.remove(soundItem); + _sounds.push_front(soundItem); + return soundItem->_waveFile; + } + } + + // Create new sound item + CSoundItem *soundItem = new CSoundItem(dialogueFile->getFile(), speechId); + soundItem->_waveFile = _soundManager.loadSpeech(dialogueFile, speechId); + + if (!soundItem->_waveFile) { + // Couldn't load speech, so destroy new item and return + delete soundItem; + return 0; + } + + // Add the item to the list of sounds + _sounds.push_front(soundItem); + + // If there are more than 10 sounds loaded, remove the last one, + // which is the least recently used of all of them + if (_sounds.size() > 10) + removeOldest(); + + return soundItem->_waveFile; +} + +int CSound::playSpeech(CDialogueFile *dialogueFile, int speechId, CProximity &prox) { + CWaveFile *waveFile = loadSpeech(dialogueFile, speechId); + if (!waveFile) + return -1; + + prox._field6C = waveFile->fn1(); + activateSound(waveFile, prox._freeSoundFlag); + + return _soundManager.playSound(*waveFile, prox); +} + +void CSound::stopSound(uint handle) { + _soundManager.stopSound(handle); +} + +void CSound::setCanFree(int handle) { + if (handle != 0 && handle != -1) + _soundManager.setCanFree(handle); +} + +void CSound::updateMixer() { + _soundManager.waveMixPump(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/sound.h b/engines/titanic/sound/sound.h new file mode 100644 index 0000000000..de95f9edf1 --- /dev/null +++ b/engines/titanic/sound/sound.h @@ -0,0 +1,190 @@ +/* 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 TITANIC_SOUND_H +#define TITANIC_SOUND_H + +#include "titanic/support/simple_file.h" +#include "titanic/sound/proximity.h" +#include "titanic/sound/sound_manager.h" +#include "titanic/sound/wave_file.h" +#include "titanic/core/list.h" +#include "titanic/core/view_item.h" +#include "titanic/true_talk/dialogue_file.h" + +namespace Titanic { + +class CGameManager; + +class CSoundItem : public ListItem { +public: + CString _name; + CWaveFile *_waveFile; + File *_dialogueFileHandle; + int _speechId; + bool _freeFlag; + bool _active; +public: + CSoundItem() : ListItem(), _waveFile(nullptr), _dialogueFileHandle(nullptr), + _speechId(0), _freeFlag(false), _active(false) {} + CSoundItem(const CString &name) : ListItem(), _name(name), _waveFile(nullptr), + _dialogueFileHandle(nullptr), _speechId(0), _freeFlag(false), _active(false) {} + CSoundItem(File *dialogueFile, int speechId) : ListItem(), _waveFile(nullptr), + _dialogueFileHandle(dialogueFile), _speechId(speechId), _freeFlag(false), _active(false) {} +}; + +class CSoundItemList : public List<CSoundItem> { +}; + +class CSound { +private: + CGameManager *_gameManager; + CSoundItemList _sounds; +private: + /** + * Check whether any sounds are done and can be be removed + */ + void checkSounds(); + + /** + * Removes the oldest sound from the sounds list that isn't + * currently playing + */ + void removeOldest(); +public: + QSoundManager _soundManager; +public: + CSound(CGameManager *owner, Audio::Mixer *mixer); + + /** + * Save the data for the class to file + */ + void save(SimpleFile *file) const; + + /** + * Load the data for the class from file + */ + void load(SimpleFile *file); + + /** + * Called when a game is about to be loaded + */ + void preLoad(); + + /** + * Called when loading a game is complete + */ + void postLoad() { _soundManager.postLoad(); } + + /** + * Called when a game is about to be saved + */ + void preSave() { _soundManager.preSave(); } + + /** + * Called when a game has finished being saved + */ + void postSave() { _soundManager.postSave(); } + + /** + * Called when the view has been changed + */ + void preEnterView(CViewItem *newView, bool isNewRoom); + + /** + * Returns true if a sound with the specified handle is active + */ + bool isActive(int handle) const; + + /** + * Sets the volume for a sound + * @param handle Sound handle + * @param volume Volume percentage (0 to 100) + * @param seconds Number of seconds to transition to the new volume + */ + void setVolume(uint handle, uint volume, uint seconds); + + /** + * Flags a sound about to be played as activated + */ + void activateSound(CWaveFile *waveFile, bool freeFlag); + + /** + * Stops any sounds attached to a given channel + */ + void stopChannel(int channel); + + /** + * Loads a TrueTalk dialogue + * @param dialogueFile Dialogue file reference + * @param speechId Speech Id within dialogue + * @returns Wave file instance + */ + CWaveFile *getTrueTalkSound(CDialogueFile *dialogueFile, int index); + + /** + * Load a speech resource + * @param dialogueFile Dialogue file reference + * @param speechId Speech Id within dialogue + * @returns Wave file instance + */ + CWaveFile *loadSpeech(CDialogueFile *dialogueFile, int speechId); + + /** + * Play a speech + * @param dialogueFile Dialogue file reference + * @param speechId Speech Id within dialogue + * @param prox Proximity instance + */ + int playSpeech(CDialogueFile *dialogueFile, int speechId, CProximity &prox); + + /** + * Load a sound + * @param name Name of sound resource + * @returns Sound item record + */ + CWaveFile *loadSound(const CString &name); + + /** + * Play a sound + */ + int playSound(const CString &name, CProximity &prox); + + /** + * Stop a sound + */ + void stopSound(uint handle); + + /** + * Flags that a sound can be freed if a timeout is set + */ + void setCanFree(int handle); + + /** + * Handles regularly updating the mixer + */ + void updateMixer(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SOUND_H */ diff --git a/engines/titanic/sound/sound_manager.cpp b/engines/titanic/sound/sound_manager.cpp new file mode 100644 index 0000000000..84d38ed2ab --- /dev/null +++ b/engines/titanic/sound/sound_manager.cpp @@ -0,0 +1,480 @@ +/* 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 "titanic/sound/sound_manager.h" +#include "titanic/titanic.h" +namespace Titanic { + +const uint SAMPLING_RATE = 22050; +const uint LATENCY = 100; +const uint CHANNELS_COUNT = 16; + +CSoundManager::CSoundManager() : _musicPercent(75.0), _speechPercent(75.0), + _masterPercent(75.0), _parrotPercent(75.0), _handleCtr(1) { +} + +double CSoundManager::getModeVolume(int mode) { + switch (mode) { + case -1: + return _masterPercent; + case -2: + return _masterPercent * 30 / 100; + case -3: + return _masterPercent * 15 / 100; + default: + return 0; + } +} + +/*------------------------------------------------------------------------*/ + +void QSoundManagerSounds::add(CWaveFile *waveFile, int iChannel, CEndTalkerFn endFn, TTtalker *talker) { + push_back(new QSoundManagerSound(waveFile, iChannel, endFn, talker)); +} + +void QSoundManagerSounds::flushChannel(int iChannel) { + for (iterator i = begin(); i != end(); ++i) { + QSoundManagerSound *item = *i; + if (item->_iChannel == iChannel) { + if (item->_endFn) + item->_endFn(item->_talker); + + remove(item); + delete item; + break; + } + } +} + +void QSoundManagerSounds::flushChannel(CWaveFile *waveFile, int iChannel) { + for (iterator i = begin(); i != end(); ++i) { + QSoundManagerSound *item = *i; + if (item->_waveFile->isLoaded() && item->_iChannel == iChannel) { + if (item->_endFn) + item->_endFn(item->_talker); + + remove(item); + delete item; + break; + } + } +} + +bool QSoundManagerSounds::contains(const CWaveFile *waveFile) const { + for (const_iterator i = begin(); i != end(); ++i) { + const QSoundManagerSound *item = *i; + if (item->_waveFile == waveFile) + return true; + } + + return false; +} + +/*------------------------------------------------------------------------*/ + +void QSoundManager::Slot::clear() { + _waveFile = nullptr; + _isTimed = false; + _ticks = 0; + _channel = -1; + _handle = 0; + _positioningMode = POSMODE_NONE; +} + +/*------------------------------------------------------------------------*/ + +QSoundManager::QSoundManager(Audio::Mixer *mixer) : CSoundManager(), QMixer(mixer), + _field18(0), _field1C(0) { + _slots.resize(48); + Common::fill(&_channelsVolume[0], &_channelsVolume[16], 0); + Common::fill(&_channelsMode[0], &_channelsMode[16], 0); + + qsWaveMixInitEx(QMIXCONFIG(SAMPLING_RATE, CHANNELS_COUNT, LATENCY)); + qsWaveMixActivate(true); + qsWaveMixOpenChannel(0, QMIX_OPENALL); +} + +QSoundManager::~QSoundManager() { + // Close down the mixer + qsWaveMixCloseSession(); +} + +CWaveFile *QSoundManager::loadSound(const CString &name) { + CWaveFile *waveFile = new CWaveFile(); + + // Try to load the specified sound + if (!waveFile->loadSound(name)) { + delete waveFile; + return nullptr; + } + + return waveFile; +} + +CWaveFile *QSoundManager::loadSpeech(CDialogueFile *dialogueFile, int speechId) { + CWaveFile *waveFile = new CWaveFile(); + + // Try to load the specified sound + if (!waveFile->loadSpeech(dialogueFile, speechId)) { + delete waveFile; + return nullptr; + } + + return waveFile; +} + +CWaveFile *QSoundManager::loadMusic(const CString &name) { + CWaveFile *waveFile = new CWaveFile(); + + // Try to load the specified sound + if (!waveFile->loadMusic(name)) { + delete waveFile; + return nullptr; + } + + return waveFile; +} + +int QSoundManager::playSound(CWaveFile &waveFile, CProximity &prox) { + int channel = -1; + uint flags = QMIX_CLEARQUEUE; + + if (prox._priorSoundHandle >= 1) { + // This sound should only be started after a prior one finishes, + // so scan the slots for the specified sound + for (uint idx = 0; idx < _slots.size(); ++idx) { + if (_slots[idx]._handle == prox._priorSoundHandle) { + channel = _slots[idx]._channel; + flags = QMIX_QUEUEWAVE; + break; + } + } + } + + if (channel >= 0 || (channel = resetChannel(prox._channel)) != -1) { + return playWave(&waveFile, channel, flags, prox); + } + + return 0; +} + +void QSoundManager::stopSound(int handle) { + resetChannel(10); + + for (uint idx = 0; idx < _slots.size(); ++idx) { + Slot &slot = _slots[idx]; + if (slot._handle == handle) { + qsWaveMixFlushChannel(slot._channel); + _sounds.flushChannel(slot._channel); + resetChannel(10); + } + } +} + +void QSoundManager::stopChannel(int channel) { + int endChannel; + switch (channel) { + case 0: + case 3: + endChannel = channel + 3; + break; + case 6: + endChannel = 10; + break; + case 10: + endChannel = 48; + break; + default: + return; + } + + for (; channel < endChannel; ++channel) { + qsWaveMixFlushChannel(channel); + _sounds.flushChannel(channel); + } +} + +void QSoundManager::setCanFree(int handle) { + for (uint idx = 0; idx < _slots.size(); ++idx) { + if (_slots[idx]._handle == handle) + _slots[idx]._isTimed = true; + } +} + +void QSoundManager::stopAllChannels() { + qsWaveMixFlushChannel(0, QMIX_OPENALL); + + for (int idx = 0; idx < 16; ++idx) + _sounds.flushChannel(idx); + resetChannel(10); +} + +int QSoundManager::resetChannel(int iChannel) { + int newChannel = -1; + int channelStart = 10; + int channelEnd = 16; + + if (iChannel != 10) { + qsWaveMixFlushChannel(iChannel); + _sounds.flushChannel(iChannel); + channelStart = iChannel; + channelEnd = iChannel + 1; + } else { + uint ticks = g_vm->_events->getTicksCount(); + + for (uint idx = 0; idx < _slots.size(); ++idx) { + Slot &slot = _slots[idx]; + if (slot._isTimed && slot._ticks && ticks > slot._ticks) { + qsWaveMixFlushChannel(slot._channel); + _sounds.flushChannel(slot._channel); + } + } + } + + for (iChannel = channelStart; iChannel < channelEnd; ++iChannel) { + if (qsWaveMixIsChannelDone(iChannel)) { + // Scan through the slots, and reset any slot using the channel + for (uint idx = 0; idx < _slots.size(); ++idx) { + Slot &slot = _slots[idx]; + if (slot._channel == iChannel) + slot.clear(); + } + + // Use the empty channel + newChannel = iChannel; + } + } + + return newChannel; +} + +void QSoundManager::setVolume(int handle, uint volume, uint seconds) { + for (uint idx = 0; idx < _slots.size(); ++idx) { + Slot &slot = _slots[idx]; + if (slot._handle == handle) { + _channelsVolume[slot._channel] = volume; + updateVolume(slot._channel, seconds * 1000); + + if (volume) { + uint ticks = g_vm->_events->getTicksCount() + seconds * 1000; + if (!slot._ticks || ticks >= slot._ticks) + slot._ticks = ticks; + } else { + slot._ticks = 0; + } + break; + } + } +} + +void QSoundManager::setVectorPosition(int handle, double x, double y, double z, uint panRate) { + for (uint idx = 0; idx < _slots.size(); ++idx) { + Slot &slot = _slots[idx]; + if (slot._handle == handle) { + qsWaveMixSetPanRate(slot._channel, QMIX_USEONCE, panRate); + qsWaveMixSetSourcePosition(slot._channel, QMIX_USEONCE, QSVECTOR(x, y, z)); + break; + } + } +} + +void QSoundManager::setPolarPosition(int handle, double range, double azimuth, double elevation, uint panRate) { + for (uint idx = 0; idx < _slots.size(); ++idx) { + Slot &slot = _slots[idx]; + if (slot._handle == handle) { + qsWaveMixSetPanRate(slot._channel, QMIX_USEONCE, panRate); + qsWaveMixSetPolarPosition(slot._channel, QMIX_USEONCE, + QSPOLAR(azimuth, range, elevation)); + break; + } + } +} + +bool QSoundManager::isActive(int handle) const { + for (uint idx = 0; idx < _slots.size(); ++idx) { + if (_slots[idx]._handle == handle) + return true; + } + + return false; +} + +bool QSoundManager::isActive(const CWaveFile *waveFile) const { + return _sounds.contains(waveFile); +} + +void QSoundManager::waveMixPump() { + qsWaveMixPump(); +} + +uint QSoundManager::getLatency() const { + return LATENCY; +} + +void QSoundManager::setMusicPercent(double percent) { + _musicPercent = percent; + updateVolumes(); +} + +void QSoundManager::setSpeechPercent(double percent) { + _speechPercent = percent; + updateVolumes(); +} + +void QSoundManager::setMasterPercent(double percent) { + _masterPercent = percent; + updateVolumes(); +} + +void QSoundManager::setParrotPercent(double percent) { + _parrotPercent = percent; +} + +void QSoundManager::setListenerPosition(double posX, double posY, double posZ, + double directionX, double directionY, double directionZ, bool stopSounds) { + if (stopSounds) { + // Stop any running sounds + for (uint idx = 0; idx < _slots.size(); ++idx) { + if (_slots[idx]._positioningMode != 0) + stopSound(_slots[idx]._handle); + } + } + + qsWaveMixSetListenerPosition(QSVECTOR(posX, posY, posZ)); + qsWaveMixSetListenerOrientation(QSVECTOR(directionX, directionY, directionZ), + QSVECTOR(0.0, 0.0, -1.0)); +} + +int QSoundManager::playWave(CWaveFile *waveFile, int iChannel, uint flags, CProximity &prox) { + if (!waveFile || !waveFile->isLoaded()) + return 0; + + prox._channelVolume = CLIP(prox._channelVolume, 0, 100); + prox._fieldC = CLIP(prox._fieldC, -100, 100); + + int slotIndex = findFreeSlot(); + if (slotIndex == -1) + return -1; + + switch (prox._positioningMode) { + case POSMODE_POLAR: + qsWaveMixSetPolarPosition(iChannel, 8, QSPOLAR(prox._azimuth, prox._range, prox._elevation)); + qsWaveMixEnableChannel(iChannel, QMIX_CHANNEL_ELEVATION, true); + qsWaveMixSetDistanceMapping(iChannel, 8, QMIX_DISTANCES(5.0, 3.0, 1.0)); + break; + + case POSMODE_VECTOR: + qsWaveMixSetSourcePosition(iChannel, 8, QSVECTOR(prox._posX, prox._posY, prox._posZ)); + qsWaveMixEnableChannel(iChannel, QMIX_CHANNEL_ELEVATION, true); + qsWaveMixSetDistanceMapping(iChannel, 8, QMIX_DISTANCES(5.0, 3.0, 1.0)); + break; + + default: + qsWaveMixEnableChannel(iChannel, QMIX_CHANNEL_ELEVATION, true); + qsWaveMixSetPolarPosition(iChannel, 8, QSPOLAR(0.0, 1.0, 0.0)); + break; + } + + if (prox._frequencyMultiplier || prox._field1C != 1.875) { + uint freq = (uint)(waveFile->getFrequency() * prox._frequencyMultiplier); + qsWaveMixSetFrequency(iChannel, 8, freq); + } + + _sounds.add(waveFile, iChannel, prox._endTalkerFn, prox._talker); + + QMIXPLAYPARAMS playParams; + playParams.callback = soundFinished; + playParams.dwUser = this; + if (!qsWaveMixPlayEx(iChannel, flags, waveFile, prox._repeated ? -1 : 0, playParams)) { + Slot &slot = _slots[slotIndex]; + slot._handle = _handleCtr++; + slot._channel = iChannel; + slot._waveFile = waveFile; + slot._positioningMode = prox._positioningMode; + + return slot._handle; + } else { + _sounds.flushChannel(waveFile, iChannel); + if (prox._freeSoundFlag) + delete waveFile; + return 0; + } +} + +void QSoundManager::soundFreed(Audio::SoundHandle &handle) { + qsWaveMixFreeWave(handle); +} + +void QSoundManager::updateVolume(int channel, uint panRate) { + uint volume = _channelsVolume[channel] * 327; + + switch (_channelsMode[channel]) { + case 0: + case 1: + case 2: + volume = (_speechPercent * volume) / 100; + break; + case 3: + case 4: + case 5: + volume = (24525 * volume) / 100; + break; + case 6: + case 7: + case 8: + case 9: + volume = (_masterPercent * volume) / 100; + break; + default: + break; + } + + volume = (_musicPercent * volume) / 100; + qsWaveMixSetPanRate(channel, 0, panRate); + qsWaveMixSetVolume(channel, 0, volume); +} + +void QSoundManager::updateVolumes() { + for (uint idx = 0; idx < CHANNELS_COUNT; ++idx) + updateVolume(idx, 250); +} + +void QSoundManager::soundFinished(int iChannel, CWaveFile *waveFile, void *soundManager) { + static_cast<QSoundManager *>(soundManager)->_sounds.flushChannel(waveFile, iChannel); +} + +int QSoundManager::findFreeSlot() { + for (uint idx = 0; idx < _slots.size(); ++idx) { + if (!_slots[idx]._waveFile) + return idx; + } + + return -1; +} + +void QSoundManager::setChannelVolume(int iChannel, uint volume, uint mode) { + _channelsVolume[iChannel] = volume; + _channelsMode[iChannel] = mode; + updateVolume(iChannel, 250); +} + +} // End of namespace Titanic z diff --git a/engines/titanic/sound/sound_manager.h b/engines/titanic/sound/sound_manager.h new file mode 100644 index 0000000000..3dfba92e9c --- /dev/null +++ b/engines/titanic/sound/sound_manager.h @@ -0,0 +1,454 @@ +/* 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 TITANIC_SOUND_MANAGER_H +#define TITANIC_SOUND_MANAGER_H + +#include "titanic/core/list.h" +#include "titanic/support/simple_file.h" +#include "titanic/sound/proximity.h" +#include "titanic/sound/qmixer.h" +#include "titanic/sound/wave_file.h" +#include "titanic/true_talk/dialogue_file.h" + +namespace Titanic { + +/** + * Abstract interface class for a sound manager + */ +class CSoundManager { +protected: + double _musicPercent; + double _speechPercent; + double _masterPercent; + double _parrotPercent; + uint _handleCtr; +public: + CSoundManager(); + virtual ~CSoundManager() {} + + /** + * Loads a sound + * @param name Name of sound resource + * @returns Loaded wave file + */ + virtual CWaveFile *loadSound(const CString &name) { return nullptr; } + + /** + * Loads a speech resource from a dialogue file + * @param name Name of sound resource + * @returns Loaded wave file + */ + virtual CWaveFile *loadSpeech(CDialogueFile *dialogueFile, int speechId) { return 0; } + + /** + * Loads a music file + * @param name Name of music resource + * @returns Loaded wave file + * @remarks The original created a streaming audio buffer for the wave file, + * and passed this to the method. For ScummVM, this has been discarded + * in favor of simply passing the filename. + */ + virtual CWaveFile *loadMusic(const CString &name) { return nullptr; } + + /** + * Start playing a previously loaded wave file + */ + virtual int playSound(CWaveFile &waveFile, CProximity &prox) = 0; + + /** + * Stop playing the specified sound + */ + virtual void stopSound(int handle) = 0; + + /** + * Stops a designated range of channels + */ + virtual void stopChannel(int channel) = 0; + + virtual void proc9(int handle) {} + + /** + * Stops sounds on all playing channels + */ + virtual void stopAllChannels() = 0; + + /** + * Sets the volume for a sound + * @param handle Handle for sound + * @param volume New volume + * @param seconds Number of seconds to transition to the new volume + */ + virtual void setVolume(int handle, uint volume, uint seconds) = 0; + + /** + * Set the position for a sound + * @param handle Handle for sound + * @param x x position in metres + * @param y y position in metres + * @param z z position in metres + * @param panRate Rate in milliseconds to transition + */ + virtual void setVectorPosition(int handle, double x, double y, double z, uint panRate) {} + + /** + * Set the position for a sound + * @param handle Handle for sound + * @param range Range value in metres + * @param azimuth Azimuth value in degrees + * @param elevation Elevation value in degrees + * @param panRate Rate in milliseconds to transition + */ + virtual void setPolarPosition(int handle, double range, double azimuth, double elevation, uint panRate) {} + + /** + * Returns true if the given sound is currently active + */ + virtual bool isActive(int handle) const = 0; + + /** + * Returns true if the given sound is currently active + */ + virtual bool isActive(const CWaveFile *waveFile) const { return false; } + + /** + * Handles regularly updating the mixer + */ + virtual void waveMixPump() = 0; + + /** + * Returns the movie latency + */ + virtual uint getLatency() const { return 0; } + + /** + * Sets the music volume percent + */ + virtual void setMusicPercent(double percent) = 0; + + /** + * Sets the speech volume percent + */ + virtual void setSpeechPercent(double percent) = 0; + + /** + * Sets the master volume percent + */ + virtual void setMasterPercent(double percent) = 0; + + /** + * Sets the Parrot NPC volume percent + */ + virtual void setParrotPercent(double percent) = 0; + + /** + * Called when a game is about to be loaded + */ + virtual void preLoad() { stopAllChannels(); } + + /** + * Load the data for the class from file + */ + void load(SimpleFile *file) {} + + /** + * Called after loading of a game is completed + */ + virtual void postLoad() {} + + /** + * Called when a game is about to be saved + */ + virtual void preSave() {} + + /** + * Save the data for the class to file + */ + void save(SimpleFile *file) const {} + + /** + * Called after saving is complete + */ + virtual void postSave() {} + + /** + * Sets the position and orientation for the listener (player) + */ + virtual void setListenerPosition(double posX, double posY, double posZ, + double directionX, double directionY, double directionZ, bool stopSounds) {} + + /** + * Returns the music volume percent + */ + double getMusicVolume() const { return _musicPercent; } + + /** + * Returns the speech volume percent + */ + double getSpeechVolume() const { return _speechPercent; } + + /** + * Returns the parrot volume percent + */ + double getParrotVolume() const { return _parrotPercent; } + + /** + * Gets the volume for a given mode? value + */ + double getModeVolume(int mode); +}; + +class QSoundManagerSound : public ListItem { +public: + CWaveFile *_waveFile; + int _iChannel; + CEndTalkerFn _endFn; + TTtalker *_talker; +public: + QSoundManagerSound() : ListItem(), _waveFile(nullptr), + _iChannel(0), _endFn(nullptr), _talker(nullptr) {} + QSoundManagerSound(CWaveFile *waveFile, int iChannel, CEndTalkerFn endFn, TTtalker *talker) : + ListItem(), _waveFile(waveFile), _iChannel(iChannel), _endFn(endFn), _talker(talker) {} +}; + +class QSoundManagerSounds : public List<QSoundManagerSound> { +public: + /** + * Adds a new sound entry to the list + */ + void add(CWaveFile *waveFile, int iChannel, CEndTalkerFn endFn, TTtalker *talker); + + /** + * Flushes a wave file attached to the specified channel + */ + void flushChannel(int iChannel); + + /** + * Flushes a wave file attached to the specified channel + */ + void flushChannel(CWaveFile *waveFile, int iChannel); + + /** + * Returns true if the list contains the specified wave file + */ + bool contains(const CWaveFile *waveFile) const; +}; + +/** + * Concrete sound manager class that handles interfacing with + * the QMixer sound mixer class + */ +class QSoundManager : public CSoundManager, public QMixer { + struct Slot { + CWaveFile *_waveFile; + bool _isTimed; + uint _ticks; + int _channel; + int _handle; + PositioningMode _positioningMode; + + Slot() : _waveFile(0), _isTimed(0), _ticks(0), _channel(-1), + _handle(0), _positioningMode(POSMODE_NONE) {} + void clear(); + }; +private: + QSoundManagerSounds _sounds; + Common::Array<Slot> _slots; + uint _channelsVolume[16]; + int _channelsMode[16]; +private: + /** + * Updates the volume for a channel + * @param channel Channel to be update + * @param panRate Time in milliseconds for change to occur + */ + void updateVolume(int channel, uint panRate); + + /** + * Updates all the volumes + */ + void updateVolumes(); + + /** + * Called by the QMixer when a sound finishes playing + */ + static void soundFinished(int iChannel, CWaveFile *waveFile, void *soundManager); + + /** + * Finds the first free slot + */ + int findFreeSlot(); + + /** + * Sets a channel volume + */ + void setChannelVolume(int iChannel, uint volume, uint mode); + + /** + * Resets the specified channel and returns a new free one + */ + int resetChannel(int iChannel); +public: + int _field18; + int _field1C; + +public: + QSoundManager(Audio::Mixer *mixer); + virtual ~QSoundManager(); + + /** + * Loads a sound + * @param name Name of sound resource + * @returns Loaded wave file + */ + virtual CWaveFile *loadSound(const CString &name); + + /** + * Loads a speech resource from a dialogue file + * @param name Name of sound resource + * @returns Loaded wave file + */ + virtual CWaveFile *loadSpeech(CDialogueFile *dialogueFile, int speechId); + + /** + * Loads a music file + * @param name Name of music resource + * @returns Loaded wave file + * @remarks The original created a streaming audio buffer for the wave file, + * and passed this to the method. For ScummVM, this has been discarded + * in favor of simply passing the filename. + */ + virtual CWaveFile *loadMusic(const CString &name); + + /** + * Start playing a previously loaded sound resource + */ + virtual int playSound(CWaveFile &waveFile, CProximity &prox); + + /** + * Stop playing the specified sound + */ + virtual void stopSound(int handle); + + /** + * Stops a designated range of channels + */ + virtual void stopChannel(int channel); + + /** + * Flags that a sound can be freed if a timeout is set + */ + virtual void setCanFree(int handle); + + /** + * Stops sounds on all playing channels + */ + virtual void stopAllChannels(); + + /** + * Sets the volume for a sound + * @param handle Handle for sound + * @param volume New volume + * @param seconds Number of seconds to transition to the new volume + */ + virtual void setVolume(int handle, uint volume, uint seconds); + + /** + * Set the position for a sound + * @param handle Handle for sound + * @param x x position in metres + * @param y y position in metres + * @param z z position in metres + * @param panRate Rate in milliseconds to transition + */ + virtual void setVectorPosition(int handle, double x, double y, double z, uint panRate); + + /** + * Set the position for a sound + * @param handle Handle for sound + * @param range Range value in metres + * @param azimuth Azimuth value in degrees + * @param elevation Elevation value in degrees + * @param panRate Rate in milliseconds to transition + */ + virtual void setPolarPosition(int handle, double range, double azimuth, double elevation, uint panRate); + + /** + * Returns true if the given sound is currently active + */ + virtual bool isActive(int handle) const; + + /** + * Returns true if the given sound is currently active + */ + virtual bool isActive(const CWaveFile *waveFile) const; + + /** + * Handles regularly updating the mixer + */ + virtual void waveMixPump(); + + /** + * Returns the movie latency + */ + virtual uint getLatency() const; + + /** + * Sets the music volume percent + */ + virtual void setMusicPercent(double percent); + + /** + * Sets the speech volume percent + */ + virtual void setSpeechPercent(double percent); + + /** + * Sets the master volume percent + */ + virtual void setMasterPercent(double percent); + + /** + * Sets the Parrot NPC volume percent + */ + virtual void setParrotPercent(double percent); + + /** + * Sets the position and orientation for the listener (player) + */ + virtual void setListenerPosition(double posX, double posY, double posZ, + double directionX, double directionY, double directionZ, bool stopSounds); + + /** + * Starts a wave file playing + */ + virtual int playWave(CWaveFile *waveFile, int iChannel, uint flags, CProximity &prox); + + /** + * Called when a wave file is freed + */ + void soundFreed(Audio::SoundHandle &handle); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_QSOUND_MANAGER_H */ diff --git a/engines/titanic/sound/titania_speech.cpp b/engines/titanic/sound/titania_speech.cpp new file mode 100644 index 0000000000..a07cc79334 --- /dev/null +++ b/engines/titanic/sound/titania_speech.cpp @@ -0,0 +1,157 @@ +/* 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 "titanic/sound/titania_speech.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CTitaniaSpeech, CGameObject) + ON_MESSAGE(ActMsg) + ON_MESSAGE(MovieEndMsg) + ON_MESSAGE(MovieFrameMsg) + ON_MESSAGE(TimerMsg) + ON_MESSAGE(EnterRoomMsg) +END_MESSAGE_MAP() + +void CTitaniaSpeech::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_paraNum, indent); + file->writeNumberLine(_frameNum, indent); + + CGameObject::save(file, indent); +} + +void CTitaniaSpeech::load(SimpleFile *file) { + file->readNumber(); + _paraNum = file->readNumber(); + _frameNum = file->readNumber(); + + CGameObject::load(file); +} + +bool CTitaniaSpeech::ActMsg(CActMsg *msg) { + CSetFrameMsg frameMsg; + CVisibleMsg visibleMsg; + CActMsg actMsg; + + if (msg->_action == "TitaniaSpeech") { + switch (_paraNum) { + case 0: + movieSetAudioTiming(true); + loadSound("a#12.wav"); + sleep(1000); + playMovie(0, 187, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + movieEvent(0); + break; + + case 1: + loadSound("a#11.wav"); + addTimer(0); + startAnimTimer("Para2", 300); + addTimer(6000); + addTimer(12000); + addTimer(18000); + addTimer(24000); + startAnimTimer("NextPara", 30000); + break; + + case 2: + visibleMsg._visible = false; + visibleMsg.execute("TitaniaStillControl"); + loadSound("a#10.wav"); + playMovie(585, 706, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + playSound("a#10.wav"); + break; + + case 3: + visibleMsg._visible = false; + visibleMsg.execute("TitaniaStillControl"); + loadSound("a#9.wav"); + playMovie(707, 905, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + playSound("a#9.wav"); + break; + + case 4: + visibleMsg._visible = false; + visibleMsg.execute("TitaniaStillControl"); + loadSound("a#8.wav"); + playMovie(906, 938, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT); + playSound("a#8.wav"); + break; + + default: + sleep(3000); + actMsg._action = "SleepTitania"; + actMsg.execute(this); + } + } + + return true; +} + +bool CTitaniaSpeech::MovieEndMsg(CMovieEndMsg *msg) { + if (_paraNum == 5) { + startAnimTimer("NextPara", 0); + } else { + if (_paraNum != 1) + addTimer(0); + startAnimTimer("NextPara", 3000); + } + + return true; +} + +bool CTitaniaSpeech::MovieFrameMsg(CMovieFrameMsg *msg) { + int frame = getMovieFrame(); + if (!frame) + playSound("a#12.wav"); + + return true; +} + +bool CTitaniaSpeech::TimerMsg(CTimerMsg *msg) { + CSetFrameMsg frameMsg; + CVisibleMsg visibleMsg; + CActMsg actMsg("TitaniaSpeech"); + + if (msg->_action == "NextPara") { + visibleMsg.execute("TitaniaStillControl"); + ++_paraNum; + actMsg.execute(this); + } else if (msg->_action == "Para2") { + playSound("a#11.wav"); + } else { + frameMsg._frameNumber = _frameNum; + frameMsg.execute("TitaniaStillControl"); + } + + return true; +} + +bool CTitaniaSpeech::EnterRoomMsg(CEnterRoomMsg *msg) { + CActMsg actMsg("Disable"); + actMsg.execute("ShipAnnouncements"); + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/titania_speech.h b/engines/titanic/sound/titania_speech.h new file mode 100644 index 0000000000..2244bb01af --- /dev/null +++ b/engines/titanic/sound/titania_speech.h @@ -0,0 +1,57 @@ +/* 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 TITANIC_TITANIA_SPEECH_H +#define TITANIC_TITANIA_SPEECH_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CTitaniaSpeech : public CGameObject { + DECLARE_MESSAGE_MAP; + bool ActMsg(CActMsg *msg); + bool MovieEndMsg(CMovieEndMsg *msg); + bool MovieFrameMsg(CMovieFrameMsg *msg); + bool TimerMsg(CTimerMsg *msg); + bool EnterRoomMsg(CEnterRoomMsg *msg); +private: + int _paraNum, _frameNum; +public: + CLASSDEF; + CTitaniaSpeech() : CGameObject(), _paraNum(1), _frameNum(0) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TITANIA_SPEECH_H */ diff --git a/engines/titanic/sound/trigger_auto_music_player.cpp b/engines/titanic/sound/trigger_auto_music_player.cpp new file mode 100644 index 0000000000..a332570aba --- /dev/null +++ b/engines/titanic/sound/trigger_auto_music_player.cpp @@ -0,0 +1,61 @@ +/* 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 "titanic/sound/trigger_auto_music_player.h" +#include "titanic/sound/auto_music_player.h" +#include "titanic/core/room_item.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CTriggerAutoMusicPlayer, CGameObject) + ON_MESSAGE(TriggerAutoMusicPlayerMsg) +END_MESSAGE_MAP() + +void CTriggerAutoMusicPlayer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_roomName, indent); + CGameObject::save(file, indent); +} + +void CTriggerAutoMusicPlayer::load(SimpleFile *file) { + file->readNumber(); + _roomName = file->readString(); + CGameObject::load(file); +} + +bool CTriggerAutoMusicPlayer::TriggerAutoMusicPlayerMsg(CTriggerAutoMusicPlayerMsg *msg) { + CRoomItem *room1 = msg->_value == 1 ? locateRoom(_roomName) : findRoom(); + CRoomItem *room2 = msg->_value == 2 ? locateRoom(_roomName) : findRoom(); + + CChangeMusicMsg changeMsg; + changeMsg._flags = 1; + changeMsg.execute(room1, CAutoMusicPlayer::_type, + MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN); + + changeMsg._flags = 2; + changeMsg.execute(room2, CAutoMusicPlayer::_type, + MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN); + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/trigger_auto_music_player.h b/engines/titanic/sound/trigger_auto_music_player.h new file mode 100644 index 0000000000..45631e08fc --- /dev/null +++ b/engines/titanic/sound/trigger_auto_music_player.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_TRIGGER_AUTO_MUSIC_PLAYER_H +#define TITANIC_TRIGGER_AUTO_MUSIC_PLAYER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CTriggerAutoMusicPlayer : public CGameObject { + DECLARE_MESSAGE_MAP; + bool TriggerAutoMusicPlayerMsg(CTriggerAutoMusicPlayerMsg *msg); +protected: + CString _roomName; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TRIGGER_AUTO_MUSIC_PLAYER_H */ diff --git a/engines/titanic/sound/view_auto_sound_player.cpp b/engines/titanic/sound/view_auto_sound_player.cpp new file mode 100644 index 0000000000..55501fe340 --- /dev/null +++ b/engines/titanic/sound/view_auto_sound_player.cpp @@ -0,0 +1,84 @@ +/* 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 "titanic/sound/view_auto_sound_player.h" +#include "titanic/sound/auto_music_player.h" +#include "titanic/core/room_item.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CViewAutoSoundPlayer, CAutoSoundPlayer) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(LeaveViewMsg) +END_MESSAGE_MAP() + +void CViewAutoSoundPlayer::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_enabled, indent); + CAutoSoundPlayer::save(file, indent); +} + +void CViewAutoSoundPlayer::load(SimpleFile *file) { + file->readNumber(); + _enabled = file->readNumber(); + CAutoSoundPlayer::load(file); +} + +bool CViewAutoSoundPlayer::EnterViewMsg(CEnterViewMsg *msg) { + CViewItem *view = findView(); + CRoomItem *room = findRoom(); + + if (view == msg->_newView) { + CTurnOn onMsg; + onMsg.execute(this); + + if (_enabled) { + CChangeMusicMsg changeMsg; + changeMsg._flags = 1; + changeMsg.execute(room, CAutoMusicPlayer::_type, + MSGFLAG_CLASS_DEF |MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN); + } + } + + return true; +} + +bool CViewAutoSoundPlayer::LeaveViewMsg(CLeaveViewMsg *msg) { + CViewItem *view = findView(); + CRoomItem *room = findRoom(); + + if (view == msg->_oldView) { + CTurnOff offMsg; + offMsg.execute(this); + + if (_enabled) { + CChangeMusicMsg changeMsg; + changeMsg._flags = 2; + changeMsg.execute(room, CAutoMusicPlayer::_type, + MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN); + } + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/view_auto_sound_player.h b/engines/titanic/sound/view_auto_sound_player.h new file mode 100644 index 0000000000..b62805ea6e --- /dev/null +++ b/engines/titanic/sound/view_auto_sound_player.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_VIEW_AUTO_SOUND_PLAYER_H +#define TITANIC_VIEW_AUTO_SOUND_PLAYER_H + +#include "titanic/sound/auto_sound_player.h" + +namespace Titanic { + +class CViewAutoSoundPlayer : public CAutoSoundPlayer { + DECLARE_MESSAGE_MAP; + bool EnterViewMsg(CEnterViewMsg *msg); + bool LeaveViewMsg(CLeaveViewMsg *msg); +private: + bool _enabled; +public: + CLASSDEF; + CViewAutoSoundPlayer() : CAutoSoundPlayer(), _enabled(false) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_VIEW_AUTO_SOUND_PLAYER_H */ diff --git a/engines/titanic/sound/view_toggles_other_music.cpp b/engines/titanic/sound/view_toggles_other_music.cpp new file mode 100644 index 0000000000..731f59bd53 --- /dev/null +++ b/engines/titanic/sound/view_toggles_other_music.cpp @@ -0,0 +1,58 @@ +/* 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 "titanic/sound/view_toggles_other_music.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CViewTogglesOtherMusic, CEnterViewTogglesOtherMusic) + ON_MESSAGE(LeaveViewMsg) +END_MESSAGE_MAP() + +CViewTogglesOtherMusic::CViewTogglesOtherMusic() : + CEnterViewTogglesOtherMusic(), _value(1) { +} + +void CViewTogglesOtherMusic::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + + CEnterViewTogglesOtherMusic::save(file, indent); +} + +void CViewTogglesOtherMusic::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + + CEnterViewTogglesOtherMusic::load(file); +} + +bool CViewTogglesOtherMusic::LeaveViewMsg(CLeaveViewMsg *msg) { + if (msg->_oldView == findView()) { + CTriggerAutoMusicPlayerMsg playerMsg(_value); + playerMsg.execute(this); + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/view_toggles_other_music.h b/engines/titanic/sound/view_toggles_other_music.h new file mode 100644 index 0000000000..1b5f110e70 --- /dev/null +++ b/engines/titanic/sound/view_toggles_other_music.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_VIEW_TOGGLES_OTHER_MUSIC_H +#define TITANIC_VIEW_TOGGLES_OTHER_MUSIC_H + +#include "titanic/sound/enter_view_toggles_other_music.h" + +namespace Titanic { + +class CViewTogglesOtherMusic : public CEnterViewTogglesOtherMusic { + DECLARE_MESSAGE_MAP; + bool LeaveViewMsg(CLeaveViewMsg *msg); +private: + int _value; +public: + CLASSDEF; + CViewTogglesOtherMusic(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_VIEW_TOGGLES_OTHER_MUSIC_H */ diff --git a/engines/titanic/sound/water_lapping_sounds.cpp b/engines/titanic/sound/water_lapping_sounds.cpp new file mode 100644 index 0000000000..7616c4b43b --- /dev/null +++ b/engines/titanic/sound/water_lapping_sounds.cpp @@ -0,0 +1,56 @@ +/* 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 "titanic/sound/water_lapping_sounds.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CWaterLappingSounds, CRoomAutoSoundPlayer); + +CWaterLappingSounds::CWaterLappingSounds() : CRoomAutoSoundPlayer(), + _value(0) { + _filename = "z#217.wav"; + _repeated = false; + _startSeconds = 0; +} + +void CWaterLappingSounds::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_filename, indent); + file->writeNumberLine(_repeated, indent); + file->writeNumberLine(_startSeconds, indent); + file->writeNumberLine(_value, indent); + + CRoomAutoSoundPlayer::save(file, indent); +} + +void CWaterLappingSounds::load(SimpleFile *file) { + file->readNumber(); + _filename = file->readString(); + _repeated = file->readNumber(); + _startSeconds = file->readNumber(); + _value = file->readNumber(); + + CRoomAutoSoundPlayer::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/water_lapping_sounds.h b/engines/titanic/sound/water_lapping_sounds.h new file mode 100644 index 0000000000..2d0594b26b --- /dev/null +++ b/engines/titanic/sound/water_lapping_sounds.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_WATER_LAPPING_SOUNDS_H +#define TITANIC_WATER_LAPPING_SOUNDS_H + +#include "titanic/sound/room_auto_sound_player.h" + +namespace Titanic { + +class CWaterLappingSounds : public CRoomAutoSoundPlayer { + DECLARE_MESSAGE_MAP; +public: + int _value; +public: + CLASSDEF; + CWaterLappingSounds(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_WATER_LAPPING_SOUNDS_H */ diff --git a/engines/titanic/sound/wave_file.cpp b/engines/titanic/sound/wave_file.cpp new file mode 100644 index 0000000000..8c00637d73 --- /dev/null +++ b/engines/titanic/sound/wave_file.cpp @@ -0,0 +1,101 @@ +/* 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 "audio/decoders/wave.h" +#include "common/memstream.h" +#include "titanic/sound/wave_file.h" +#include "titanic/sound/sound_manager.h" +#include "titanic/support/simple_file.h" + +namespace Titanic { + +CWaveFile::CWaveFile() : _owner(nullptr), _stream(nullptr), + _soundType(Audio::Mixer::kPlainSoundType) { +} + +CWaveFile::CWaveFile(QSoundManager *owner) : _owner(owner), _stream(nullptr), + _soundType(Audio::Mixer::kPlainSoundType) { +} + +CWaveFile::~CWaveFile() { + if (_stream) { + _owner->soundFreed(_soundHandle); + delete _stream; + } +} + +int CWaveFile::fn1() { + // TODO + return 0; +} + +bool CWaveFile::loadSound(const CString &name) { + assert(!_stream); + + StdCWadFile file; + if (!file.open(name)) + return false; + + Common::SeekableReadStream *stream = file.readStream(); + _size = stream->size(); + _stream = Audio::makeWAVStream(stream->readStream(_size), DisposeAfterUse::YES); + _soundType = Audio::Mixer::kSFXSoundType; + + return true; +} + +bool CWaveFile::loadSpeech(CDialogueFile *dialogueFile, int speechIndex) { + DialogueResource *res = dialogueFile->openWaveEntry(speechIndex); + if (!res) + return false; + + byte *data = (byte *)malloc(res->_size); + dialogueFile->read(res, data, res->_size); + + _size = res->_size; + _stream = Audio::makeWAVStream(new Common::MemoryReadStream(data, _size, DisposeAfterUse::YES), + DisposeAfterUse::YES); + _soundType = Audio::Mixer::kSpeechSoundType; + + return true; +} + +bool CWaveFile::loadMusic(const CString &name) { + assert(!_stream); + + StdCWadFile file; + if (!file.open(name)) + return false; + + Common::SeekableReadStream *stream = file.readStream(); + _size = stream->size(); + _stream = Audio::makeWAVStream(stream->readStream(_size), DisposeAfterUse::YES); + _soundType = Audio::Mixer::kMusicSoundType; + + return true; +} + +uint CWaveFile::getFrequency() const { + return _stream->getRate(); +} + +} // End of namespace Titanic z diff --git a/engines/titanic/sound/wave_file.h b/engines/titanic/sound/wave_file.h new file mode 100644 index 0000000000..aede0c9328 --- /dev/null +++ b/engines/titanic/sound/wave_file.h @@ -0,0 +1,83 @@ +/* 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 TITANIC_WAVE_FILE_H +#define TITANIC_WAVE_FILE_H + +#include "audio/audiostream.h" +#include "audio/mixer.h" +#include "titanic/support/string.h" +#include "titanic/true_talk/dialogue_file.h" + +namespace Titanic { + +class QSoundManager; + +class CWaveFile { +private: + uint _size; +public: + QSoundManager *_owner; + Audio::SeekableAudioStream *_stream; + Audio::SoundHandle _soundHandle; + Audio::Mixer::SoundType _soundType; +public: + CWaveFile(); + CWaveFile(QSoundManager *owner); + ~CWaveFile(); + + int fn1(); + + /** + * Return the size of the wave file + */ + uint size() const { return _size; } + + /** + * Tries to load the specified wave file sound + */ + bool loadSound(const CString &name); + + /** + * Tries to load speech from a specified dialogue file + */ + bool loadSpeech(CDialogueFile *dialogueFile, int speechIndex); + + /** + * Tries to load the specified music wave file + */ + bool loadMusic(const CString &name); + + /** + * Returns true if the wave file has data loaded + */ + bool isLoaded() const { return _stream != nullptr; } + + /** + * Return the frequency of the loaded wave file + */ + uint getFrequency() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_WAVE_FILE_H */ diff --git a/engines/titanic/star_control/base_star.cpp b/engines/titanic/star_control/base_star.cpp new file mode 100644 index 0000000000..f09df38620 --- /dev/null +++ b/engines/titanic/star_control/base_star.cpp @@ -0,0 +1,118 @@ +/* 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 "titanic/star_control/base_star.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CBaseStarEntry::CBaseStarEntry() : _field0(0), _value(0.0) { + Common::fill(&_data[0], &_data[5], 0); +} + +void CBaseStarEntry::load(Common::SeekableReadStream &s) { + _field0 = s.readByte(); + _field1 = s.readByte(); + _field2 = s.readByte(); + _field3 = s.readByte(); + *((uint32 *)&_value) = s.readUint32LE(); // FIXME + _val._v1 = s.readUint32LE(); + _val._v2 = s.readUint32LE(); + _val._v3 = s.readUint32LE(); + + for (int idx = 0; idx < 5; ++idx) + _data[idx] = s.readUint32LE(); +} + +/*------------------------------------------------------------------------*/ + +CBaseStar::CBaseStar() : _minVal(0.0), _maxVal(1.0), _range(0.0) { +} + +void CBaseStar::draw(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12, CStarControlSub5 *sub5) { + // TODO +} + +void CBaseStar::clear() { + _data.clear(); +} + +void CBaseStar::initialize() { + _minVal = 9.9999998e10; + _maxVal = -9.9999998e10; + _sub4.initialize(); + + for (uint idx = 0; idx < _data.size(); ++idx) { + const CBaseStarEntry *entry = getDataPtr(idx); + _sub4.checkEntry(entry->_val); + + if (entry->_value < _minVal) + _minVal = entry->_value; + if (entry->_value > _maxVal) + _maxVal = entry->_value; + } + + _range = (_maxVal - _minVal) / 1.0; +} + +CBaseStarEntry *CBaseStar::getDataPtr(int index) { + return (index >= 0 && index < (int)_data.size()) ? &_data[index] : nullptr; +} + +void CBaseStar::loadData(Common::SeekableReadStream &s) { + uint headerId = s.readUint32LE(); + uint count = s.readUint32LE(); + if (headerId != 100 || count == 0) + error("Invalid star data"); + + // Initialize the data array + clear(); + _data.resize(count); + + // Iterate through reading the data for each entry + for (uint idx = 0; idx < count; ++idx) + _data[idx].load(s); +} + +void CBaseStar::loadData(const CString &resName) { + // Get a stream to read the data from the DAT file + Common::SeekableReadStream *stream = g_vm->_filesManager->getResource(resName); + assert(stream); + + // Load the stream + loadData(*stream); + delete stream; +} + +void CBaseStar::resetEntry(CBaseStarEntry &entry) { + entry._field0 = 0xFF; + entry._field1 = 0xFF; + entry._field2 = 0xFF; + entry._field3 = 0; + entry._val._v1 = 0; + entry._val._v2 = 0; + entry._val._v3 = 0; + for (int idx = 0; idx < 5; ++idx) + entry._data[idx] = 0; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/base_star.h b/engines/titanic/star_control/base_star.h new file mode 100644 index 0000000000..cf5cbc72d2 --- /dev/null +++ b/engines/titanic/star_control/base_star.h @@ -0,0 +1,110 @@ +/* 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 TITANIC_STAR_CONTROL_SUB3_H +#define TITANIC_STAR_CONTROL_SUB3_H + +#include "titanic/support/simple_file.h" +#include "titanic/star_control/star_control_sub4.h" +#include "titanic/star_control/star_control_sub5.h" +#include "titanic/star_control/surface_area.h" + +namespace Titanic { + +class CStarControlSub12; + +struct CBaseStarEntry { + byte _field0; + byte _field1; + byte _field2; + byte _field3; + double _value; + CBaseStarVal _val; + uint _data[5]; + + CBaseStarEntry(); + void load(Common::SeekableReadStream &s); +}; + +class CBaseStar { +protected: + Common::Array<CBaseStarEntry> _data; + CStarControlSub4 _sub4; + double _minVal; + double _maxVal; + double _range; +protected: + /** + * Get a pointer to a data entry + */ + CBaseStarEntry *getDataPtr(int index); + + /** + * Load entry data from a passed stream + */ + void loadData(Common::SeekableReadStream &s); + + /** + * Load entry data from a specified resource + */ + void loadData(const CString &resName); + + /** + * Reset the data for an entry + */ + void resetEntry(CBaseStarEntry &entry); +public: + CBaseStar(); + virtual ~CBaseStar() {} + + /** + * Draw the item + */ + virtual void draw(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12, CStarControlSub5 *sub5); + + virtual bool loadYale(int v1) { return true; } + virtual bool proc4(int v1, int v2, int v3, int v4, int v5) { return false; } + virtual bool proc5(int v1) { return false; } + virtual bool loadStar() { return false; } + virtual bool proc7(int v1, int v2) { return true; } + + /** + * Load the item's data + */ + virtual void load(SimpleFile *file) {} + + /** + * Save the item's data + */ + virtual void save(SimpleFile *file, int indent) {} + + /** + * Clear allocated data + */ + void clear(); + + void initialize(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB3_H */ diff --git a/engines/titanic/star_control/dmatrix.cpp b/engines/titanic/star_control/dmatrix.cpp new file mode 100644 index 0000000000..70008054b6 --- /dev/null +++ b/engines/titanic/star_control/dmatrix.cpp @@ -0,0 +1,104 @@ +/* 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 "titanic/star_control/dmatrix.h" +#include "titanic/star_control/fmatrix.h" +#include "titanic/star_control/star_control_sub26.h" + +namespace Titanic { + +DMatrix *DMatrix::_static; + +DMatrix::DMatrix() : + _row1(1.0, 0.0, 0.0), _row2(0.0, 1.0, 0.0), _row3(0.0, 0.0, 1.0) { +} + +DMatrix::DMatrix(int mode, const FMatrix *src) { + assert(!mode); + + _row1._x = 1.0; + _row2._y = 1.0; + _row3._z = 1.0; + _frow1._x = src->_row1._x; + _frow1._y = src->_row1._y; + _frow1._z = src->_row1._z; + _frow2._x = src->_row2._x; + _frow2._y = src->_row2._y; + _frow2._z = src->_row2._z; +} + +DMatrix::DMatrix(int mode, double val) { + set(mode, val); +} + +void DMatrix::init() { + _static = nullptr; +} + +void DMatrix::deinit() { + delete _static; + _static = nullptr; +} + +void DMatrix::set(int mode, double amount) { + const double FACTOR = 0.0174532925199433; + double sinVal = sin(amount * FACTOR); + double cosVal = cos(amount * FACTOR); + + switch (mode) { + case 0: + _row1._x = 1.0; + _row2._y = cosVal; + _row2._z = sinVal; + _row3._y = -sinVal; + _row3._z = cosVal; + break; + + case 1: + _row1._x = cosVal; + _row1._z = sinVal; + _row2._y = 1.0; + _row3._x = -sinVal; + _row3._z = cosVal; + break; + + case 2: + _row1._x = cosVal; + _row1._y = sinVal; + _row2._x = -sinVal; + _row2._y = cosVal; + _row3._z = 1.0; + break; + + default: + break; + } +} + +void DMatrix::fn3(CStarControlSub26 *sub26) { + double v = sub26->fn1(); + v = (v < 0.0) ? 0.0 : 2.0 / v; + + error("TODO: DMatrix::fn3 %d", (int)v); +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/dmatrix.h b/engines/titanic/star_control/dmatrix.h new file mode 100644 index 0000000000..14f6bb0331 --- /dev/null +++ b/engines/titanic/star_control/dmatrix.h @@ -0,0 +1,65 @@ +/* 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 TITANIC_DMATRIX_H +#define TITANIC_DMATRIX_H + +#include "titanic/star_control/dvector.h" +#include "titanic/star_control/fvector.h" + +namespace Titanic { + +class FMatrix; +class CStarControlSub26; + +/** + * Double based matrix class. + * @remarks TODO: See if it can be merged with FMatrix + */ +class DMatrix { +private: + static DMatrix *_static; +public: + DVector _row1; + DVector _row2; + DVector _row3; + FVector _frow1; + FVector _frow2; +public: + static void init(); + static void deinit(); +public: + DMatrix(); + DMatrix(int mode, const FMatrix *src); + DMatrix(int mode, double val); + + /** + * Sets up data for the matrix + */ + void set(int mode, double amount); + + void fn3(CStarControlSub26 *sub26); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DMATRIX_H */ diff --git a/engines/titanic/star_control/dvector.cpp b/engines/titanic/star_control/dvector.cpp new file mode 100644 index 0000000000..e4c5b15cb0 --- /dev/null +++ b/engines/titanic/star_control/dvector.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/star_control/dvector.h" +#include "common/algorithm.h" + +namespace Titanic { + +void DVector::fn3() { + double hyp = sqrt(_x * _x + _y * _y + _z * _z); + assert(hyp); + + _x *= 1.0 / hyp; + _y *= 1.0 / hyp; + _z *= 1.0 / hyp; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/dvector.h b/engines/titanic/star_control/dvector.h new file mode 100644 index 0000000000..7aca407c1c --- /dev/null +++ b/engines/titanic/star_control/dvector.h @@ -0,0 +1,44 @@ +/* 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 TITANIC_DVECTOR_H +#define TITANIC_DVECTOR_H + +namespace Titanic { + +/** + * Double based vector class. + * @remarks TODO: See if it can be merged with FVector + */ +class DVector { +public: + double _x, _y, _z; +public: + DVector() : _x(0), _y(0), _z(0) {} + DVector(double x, double y, double z) : _x(x), _y(y), _z(z) {} + + void fn3(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DVECTOR_H */ diff --git a/engines/titanic/star_control/error_code.h b/engines/titanic/star_control/error_code.h new file mode 100644 index 0000000000..52b0fb9f9e --- /dev/null +++ b/engines/titanic/star_control/error_code.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_ERROR_CODE_H +#define TITANIC_ERROR_CODE_H + +namespace Titanic { + +class CErrorCode { +private: + int _value; +public: + CErrorCode() : _value(0) {} + + /** + * Sets the error code + */ + void set() { _value = 1; } + + /** + * Gets the error code and resets it + */ + int get() { + int result = _value; + _value = 0; + return result; + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ERROR_CODE_H */ diff --git a/engines/titanic/star_control/fmatrix.cpp b/engines/titanic/star_control/fmatrix.cpp new file mode 100644 index 0000000000..af15477d04 --- /dev/null +++ b/engines/titanic/star_control/fmatrix.cpp @@ -0,0 +1,136 @@ +/* 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 "titanic/star_control/fmatrix.h" + +namespace Titanic { + +FMatrix::FMatrix() : + _row1(1.0, 0.0, 0.0), _row2(0.0, 1.0, 0.0), _row3(0.0, 0.0, 1.0) { +} + +FMatrix::FMatrix(DMatrix *src) { + copyFrom(src); +} + +FMatrix::FMatrix(FMatrix *src) { + _row1 = src->_row1; + _row2 = src->_row2; + _row3 = src->_row3; +} + +void FMatrix::copyFrom(const DMatrix *src) { + // TODO +} + +void FMatrix::load(SimpleFile *file, int param) { + _row1._x = file->readFloat(); + _row1._y = file->readFloat(); + _row1._z = file->readFloat(); + _row2._x = file->readFloat(); + _row2._y = file->readFloat(); + _row2._z = file->readFloat(); + _row3._x = file->readFloat(); + _row3._y = file->readFloat(); + _row3._z = file->readFloat(); +} + +void FMatrix::save(SimpleFile *file, int indent) { + file->writeFloatLine(_row1._x, indent); + file->writeFloatLine(_row1._y, indent); + file->writeFloatLine(_row1._z, indent); + file->writeFloatLine(_row2._x, indent); + file->writeFloatLine(_row2._y, indent); + file->writeFloatLine(_row2._z, indent); + file->writeFloatLine(_row3._x, indent); + file->writeFloatLine(_row3._y, indent); + file->writeFloatLine(_row3._z, indent); +} + +void FMatrix::clear() { + _row1 = FVector(1.0, 0.0, 0.0); + _row2 = FVector(0.0, 1.0, 0.0); + _row3 = FVector(0.0, 0.0, 1.0); +} + +void FMatrix::set(FVector *row1, FVector *row2, FVector *row3) { + _row1 = *row1; + _row2 = *row2; + _row3 = *row3; +} + +void FMatrix::fn1(const FVector *v) { + _row3._x = v->_x; + + FVector tempVector; + _row3.fn1(&tempVector); + + _row2._x = tempVector._x; + _row2._y = tempVector._y; + _row2._z = tempVector._z; + + _row3.multiply(&tempVector, &_row2); + _row1._x = _row2._x; + _row1._y = _row2._y; + _row1._z = _row2._z; + _row1.fn3(); + + _row3.multiply(&tempVector, &_row1); + _row2._x = _row1._x; + _row2._y = _row1._y; + _row2._z = _row1._z; + _row2.fn3(); +} + +void FMatrix::fn2(FMatrix *m) { + double x1 = _row1._y * m->_row2._x + _row1._z * m->_row3._x + _row1._x * m->_row1._x; + double y1 = _row1._x * m->_row1._y + m->_row2._y * _row1._y + m->_row3._y * _row1._z; + double z1 = _row1._x * m->_row1._z + _row1._y * m->_row2._z + _row1._z * m->_row3._z; + double x2 = m->_row1._x * _row2._x + m->_row3._x * _row2._z + m->_row2._x * _row2._y; + double y2 = m->_row3._y * _row2._z + m->_row1._y * _row2._x + m->_row2._y * _row2._y; + double z2 = _row2._z * m->_row3._z + _row2._x * m->_row1._z + _row2._y * m->_row2._z; + double x3 = m->_row1._x * _row3._x + _row3._z * m->_row3._x + _row3._y * m->_row2._x; + double y3 = _row3._y * m->_row2._y + _row3._z * m->_row3._y + _row3._x * m->_row1._y; + double z3 = _row3._x * m->_row1._z + _row3._y * m->_row2._z + _row3._z * m->_row3._z; + + _row1 = FVector(x1, y1, z1); + _row2 = FVector(x2, y2, z2); + _row3 = FVector(x3, y3, z3); +} + +void FMatrix::fn3(FMatrix *m) { + double x1 = _row2._x * m->_row1._y + m->_row1._z * _row3._x + _row1._x * m->_row1._x; + double y1 = m->_row1._x * _row1._y + _row3._y * m->_row1._z + _row2._y * m->_row1._y; + double z1 = m->_row1._x * _row1._z + m->_row1._y * _row2._z + m->_row1._z * _row3._z; + double x2 = _row1._x * m->_row2._x + _row2._x * m->_row2._y + _row3._x * m->_row2._z; + double y2 = _row3._y * m->_row2._z + _row1._y * m->_row2._x + _row2._y * m->_row2._y; + double z2 = m->_row2._z * _row3._z + m->_row2._x * _row1._z + m->_row2._y * _row2._z; + double x3 = _row1._x * m->_row3._x + m->_row3._z * _row3._x + m->_row3._y * _row2._x; + double y3 = m->_row3._y * _row2._y + m->_row3._z * _row3._y + m->_row3._x * _row1._y; + double z3 = m->_row3._x * _row1._z + m->_row3._y * _row2._z + m->_row3._z * _row3._z; + + _row1 = FVector(x1, y1, z1); + _row2 = FVector(x2, y2, z2); + _row3 = FVector(x3, y3, z3); +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/fmatrix.h b/engines/titanic/star_control/fmatrix.h new file mode 100644 index 0000000000..d7c4acfbdc --- /dev/null +++ b/engines/titanic/star_control/fmatrix.h @@ -0,0 +1,94 @@ +/* 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 TITANIC_FMATRIX_H +#define TITANIC_FMATRIX_H + +#include "titanic/support/simple_file.h" +#include "titanic/star_control/fvector.h" + +namespace Titanic { + +class DMatrix; + +/** + * Floating point matrix class. + * @remarks TODO: See if it can be merged with DMatrix + */ +class FMatrix { +private: + /** + * Copys data from a given source + */ + void copyFrom(const DMatrix *src); +public: + FVector _row1; + FVector _row2; + FVector _row3; +public: + FMatrix(); + FMatrix(DMatrix *src); + FMatrix(FMatrix *src); + + /** + * Load the data for the class from file + */ + void load(SimpleFile *file, int param); + + /** + * Save the data for the class to file + */ + void save(SimpleFile *file, int indent); + + /** + * Clears the matrix + */ + void clear(); + + /** + * Sets the data for the matrix + */ + void set(FVector *row1, FVector *row2, FVector *row3); + + void fn1(const FVector *v); + + void fn2(FMatrix *m); + void fn3(FMatrix *m); + + /** + * Returns true if the passed matrix equals this one + */ + bool operator==(const FMatrix &src) { + return _row1 == src._row1 && _row2 == src._row2 && _row3 == src._row3; + } + + /** + * Returns true if the passed matrix does not equal this one + */ + bool operator!=(const FMatrix &src) { + return !operator==(src); + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MATRIX3_H */ diff --git a/engines/titanic/star_control/fpoint.cpp b/engines/titanic/star_control/fpoint.cpp new file mode 100644 index 0000000000..f3d7008324 --- /dev/null +++ b/engines/titanic/star_control/fpoint.cpp @@ -0,0 +1,28 @@ +/* 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 "titanic/star_control/fpoint.h" + +namespace Titanic { + + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/fpoint.h b/engines/titanic/star_control/fpoint.h new file mode 100644 index 0000000000..f2cef18ea5 --- /dev/null +++ b/engines/titanic/star_control/fpoint.h @@ -0,0 +1,41 @@ +/* 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 TITANIC_FPOINT_H +#define TITANIC_FPOINT_H + +namespace Titanic { + +/** + * Floating point Point class + */ +class FPoint { +public: + double _x, _y; +public: + FPoint() : _x(0), _y(0) {} + FPoint(double x, double y) : _x(x), _y(y) {} +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FPOINT_H */ diff --git a/engines/titanic/star_control/fvector.cpp b/engines/titanic/star_control/fvector.cpp new file mode 100644 index 0000000000..aa99e8b4d1 --- /dev/null +++ b/engines/titanic/star_control/fvector.cpp @@ -0,0 +1,71 @@ +/* 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 "titanic/star_control/fvector.h" +#include "titanic/star_control/star_control_sub6.h" +#include "common/algorithm.h" +#include "common/textconsole.h" + +namespace Titanic { + +void FVector::fn1(FVector *v) { + v->_x = (ABS(_x - _y) < 0.00001 && ABS(_y - _z) < 0.00001 && + ABS(_x - _z) < 0.00001) ? -_x : _x; + v->_y = _y; + v->_z = _z; +} + +void FVector::multiply(FVector *dest, const FVector *src) { + dest->_x = (src->_z * _y) - (_z * src->_y); + dest->_y = (src->_x * _z) - (_x * src->_z); + dest->_z = (src->_y * _x) - (_y * src->_x); +} + +void FVector::fn3() { + double hyp = sqrt(_x * _x + _y * _y + _z * _z); + assert(hyp); + + _x *= 1.0 / hyp; + _y *= 1.0 / hyp; + _z *= 1.0 / hyp; +} + +double FVector::getDistance(const FVector *src) const { + double xd = src->_x - _x; + double yd = src->_y - _y; + double zd = src->_z - _z; + + return sqrt(xd * xd + yd * yd + zd * zd); +} + +void FVector::fn4(FVector *dest, const FVector *v1, const FVector *v2) { + FVector tempVector(v1->_x + v2->_x, v1->_y + v2->_y, v1->_z + v2->_z); + tempVector.fn3(); + + *dest = tempVector; +} + +void FVector::fn5(FVector *dest, const CStarControlSub6 *sub6) const { + error("TODO: FVector::fn5"); +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/fvector.h b/engines/titanic/star_control/fvector.h new file mode 100644 index 0000000000..8e1ba47a3e --- /dev/null +++ b/engines/titanic/star_control/fvector.h @@ -0,0 +1,70 @@ +/* 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 TITANIC_FVECTOR_H +#define TITANIC_FVECTOR_H + +namespace Titanic { + +class CStarControlSub6; + +/** + * Floating point vector class. + * @remarks TODO: See if it can be merged with DVector + */ +class FVector { +public: + double _x, _y, _z; +public: + FVector() : _x(0), _y(0), _z(0) {} + FVector(double x, double y, double z) : _x(x), _y(y), _z(z) {} + + void fn1(FVector *v); + void multiply(FVector *dest, const FVector *src); + void fn3(); + + /** + * Returns the distance between a specified point and this one + */ + double getDistance(const FVector *src) const; + + static void fn4(FVector *dest, const FVector *v1, const FVector *v2); + void fn5(FVector *dest, const CStarControlSub6 *sub6) const; + + /** + * Returns true if the passed vector equals this one + */ + bool operator==(const FVector &src) const { + return _x != src._x || _y != src._y || _z != src._z; + } + + /** + * Returns true if the passed vector does not equal this one + */ + bool operator!=(const FVector &src) const { + return !operator==(src); + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FVECTOR_H */ diff --git a/engines/titanic/star_control/star_control.cpp b/engines/titanic/star_control/star_control.cpp new file mode 100644 index 0000000000..7ba160cd37 --- /dev/null +++ b/engines/titanic/star_control/star_control.cpp @@ -0,0 +1,148 @@ +/* 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 "titanic/support/screen_manager.h" +#include "titanic/star_control/star_control.h" +#include "titanic/star_control/dmatrix.h" +#include "titanic/star_control/error_code.h" +#include "titanic/star_control/star_control_sub6.h" +#include "titanic/star_control/star_control_sub12.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CStarControl, CGameObject) + ON_MESSAGE(MouseMoveMsg) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(KeyCharMsg) + ON_MESSAGE(FrameMsg) +END_MESSAGE_MAP() + +CStarControl::CStarControl() : _fieldBC(0), _field80B0(0), + _starRect(20, 10, 620, 350) { + CStarControlSub6::init(); + CStarControlSub12::init(); + DMatrix::init(); +} + +CStarControl::~CStarControl() { + CStarControlSub6::deinit(); + CStarControlSub12::deinit(); + DMatrix::deinit(); +} + +void CStarControl::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + _starField.save(file, indent); + _view.save(file, indent); + CGameObject::save(file, indent); +} + +void CStarControl::load(SimpleFile *file) { + int val = file->readNumber(); + + if (!val) { + _starField.load(file); + if (!_starField.initDocument()) + error("Couldn't initialise the StarField document"); + + _view.load(file, 0); + CScreenManager *screenManager = CScreenManager::setCurrent(); + if (!screenManager) + error("There's no screen manager during loading"); + + _view.setup(screenManager, &_starField, this); + _view.reset(); + + _fieldBC = 1; + } + + CGameObject::load(file); +} + +void CStarControl::draw(CScreenManager *screenManager) { + if (_visible) + _view.draw(screenManager); +} + +bool CStarControl::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if (_visible && _starRect.contains(msg->_mousePos)) { + _view.MouseButtonDownMsg(0, Point(msg->_mousePos.x - 20, + msg->_mousePos.y - 10)); + return true; + } else { + return false; + } +} + +bool CStarControl::MouseMoveMsg(CMouseMoveMsg *msg) { + if (_visible && _starRect.contains(msg->_mousePos)) { + _view.MouseMoveMsg(0, Point(msg->_mousePos.x - 20, + msg->_mousePos.y - 10)); + makeDirty(); + return true; + } else { + return false; + } +} + +bool CStarControl::KeyCharMsg(CKeyCharMsg *msg) { + if (_visible) + _view.KeyCharMsg(msg->_key); + + return false; +} + +bool CStarControl::FrameMsg(CFrameMsg *msg) { + if (_visible) { + Point pt = getMousePos(); + if (_starRect.contains(pt)) + _view.MouseMoveMsg(0, pt); + + newFrame(); + makeDirty(); + return true; + } else { + return false; + } +} + +void CStarControl::newFrame() { + // TODO +} + +void CStarControl::fn1(int action) { + // TODO +} + +bool CStarControl::fn4() { + return _starField.get6(); +} + +bool CStarControl::canSetStarDestination() const { + return _view.canSetStarDestination(); +} + +void CStarControl::starDestinationSet() { + _view.starDestinationSet(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control.h b/engines/titanic/star_control/star_control.h new file mode 100644 index 0000000000..c0561ce908 --- /dev/null +++ b/engines/titanic/star_control/star_control.h @@ -0,0 +1,85 @@ +/* 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 TITANIC_STAR_CONTROL_H +#define TITANIC_STAR_CONTROL_H + +#include "titanic/core/game_object.h" +#include "titanic/star_control/star_field.h" +#include "titanic/star_control/star_view.h" + +namespace Titanic { + +class CStarControl : public CGameObject { + DECLARE_MESSAGE_MAP; + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool MouseMoveMsg(CMouseMoveMsg *msg); + bool KeyCharMsg(CKeyCharMsg *msg); + bool FrameMsg(CFrameMsg *msg); +private: + int _fieldBC; + CStarField _starField; + CStarView _view; + Rect _starRect; + int _field80B0; +private: + /** + * Called for ever new game frame + */ + void newFrame(); +public: + CLASSDEF; + CStarControl(); + virtual ~CStarControl(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Allows the item to draw itself + */ + virtual void draw(CScreenManager *screenManager); + + void fn1(int action); + bool fn4(); + + /** + * Returns true if a star destination can be set + */ + bool canSetStarDestination() const; + + /** + * Called when a star destination is set + */ + void starDestinationSet(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_H */ diff --git a/engines/titanic/star_control/star_control_sub12.cpp b/engines/titanic/star_control/star_control_sub12.cpp new file mode 100644 index 0000000000..5840495d34 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub12.cpp @@ -0,0 +1,283 @@ +/* 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 "titanic/star_control/star_control_sub12.h" +#include "titanic/star_control/star_control_sub21.h" +#include "titanic/star_control/star_control_sub22.h" + +namespace Titanic { + +FMatrix *CStarControlSub12::_matrix1; +FMatrix *CStarControlSub12::_matrix2; + +CStarControlSub12::CStarControlSub12(void *val1, const CStar20Data *data) : + _currentIndex(-1), _handlerP(nullptr), _field108(0), + _sub13(val1) { + setupHandler(data); +} + +CStarControlSub12::CStarControlSub12(CStarControlSub13 *src) : + _currentIndex(-1), _handlerP(nullptr), _field108(0), _sub13(src) { +} + +void CStarControlSub12::init() { + _matrix1 = nullptr; + _matrix2 = nullptr; +} + +void CStarControlSub12::deinit() { + delete _matrix1; + delete _matrix2; + _matrix1 = nullptr; + _matrix2 = nullptr; +} + +CStarControlSub12::~CStarControlSub12() { + deleteHandler(); +} + +void CStarControlSub12::proc2(const void *src) { + _sub13.copyFrom(src); +} + +void CStarControlSub12::proc3(const CStar20Data *src) { + _handlerP->copyFrom(src); +} + +void CStarControlSub12::setPosition(const FVector &v) { + if (!isLocked()) { + _sub13.setPosition(v); + set108(); + } +} + +void CStarControlSub12::proc5(const FVector &v) { + if (!isLocked()) + _sub13.fn11(v); +} + +void CStarControlSub12::proc6(int v) { + if (!isLocked()) + _sub13.setC(v); +} + +void CStarControlSub12::proc7(int v) { + if (!isLocked()) + _sub13.set10(v); +} + +void CStarControlSub12::proc8(int v) { + if (!isLocked()) + _sub13.set14(v); +} + +void CStarControlSub12::proc9(int v) { + if (!isLocked()) + _sub13.set18(v); +} + +void CStarControlSub12::proc10(int v) { + if (!isLocked()) + _sub13.set1C(v); +} + +void CStarControlSub12::proc11() { + if (!isLocked()) + _sub13.fn12(); +} + +void CStarControlSub12::proc12(double v1, double v2) { + if (!isLocked()) + _sub13.fn13(v1, v2); +} + +void CStarControlSub12::proc13(CStarControlSub13 *dest) { + *dest = _sub13; +} + +void CStarControlSub12::proc14(int v) { + FMatrix matrix; + _sub13.getMatrix(&matrix); + FVector vector = _sub13._position; + + _handlerP->proc9(&vector, v, &matrix); +} + +void CStarControlSub12::proc15(int v) { + if (!_matrix1) + _matrix1 = new FMatrix(); + if (!_matrix2) + _matrix2 = new FMatrix(); + + _sub13.getMatrix(_matrix1); + *_matrix2 = *_matrix1; + + FVector v1 = _sub13._position; + FVector v2 = _sub13._position; + CErrorCode errorCode; + _handlerP->proc11(errorCode, v2, _matrix2); + + if (v1 != v2) { + _sub13.setPosition(v2); + set108(); + } + + if (_matrix1 != _matrix2) { + _sub13.setMatrix(_matrix2); + } +} + +void CStarControlSub12::proc16() { + _handlerP->proc4(); +} + +void CStarControlSub12::proc17() { + _handlerP->proc5(); +} + +void CStarControlSub12::proc18() { + _handlerP->proc6(); +} + +void CStarControlSub12::proc19() { + _handlerP->proc7(); +} + +void CStarControlSub12::proc20(double v) { + if (!isLocked()) + _sub13.fn14(v); +} + +void CStarControlSub12::proc21(CStarControlSub6 &sub6) { + if (!isLocked()) { + _sub13.setPosition(sub6); + set108(); + } +} + +void CStarControlSub12::proc22(FMatrix &m) { + if (!isLocked()) + _sub13.fn15(m); +} + +CStarControlSub6 CStarControlSub12::proc23() { + return _sub13.getSub1(); +} + +CStarControlSub6 CStarControlSub12::proc24() { + return _sub13.getSub2(); +} + +double CStarControlSub12::proc25() const { + return _sub13._field10; +} + +double CStarControlSub12::proc26() const { + return _sub13._field14; +} + +int CStarControlSub12::proc27() const { + return _sub13._field24; +} + +FVector CStarControlSub12::proc28(int index, const void *v2) { + error("TODO: CStarControlSub12::proc28"); + return FVector(); +} + +FVector CStarControlSub12::proc29(const FVector &v) { + return _sub13.fn16(v); +} + +FVector CStarControlSub12::proc30(int index, const FVector &v) { + return _sub13.fn17(index, v); +} + +FVector CStarControlSub12::proc31(int index, const FVector &v) { + return _sub13.fn18(index, v); +} + +void CStarControlSub12::proc32(double v1, double v2) { + error("TODO: CStarControlSub12::proc32"); +} + +bool CStarControlSub12::setArrayVector(const FVector &v) { + if (_currentIndex >= 2) + return false; + + error("TODO: CStarControlSub12::setArrayVector"); +} + +bool CStarControlSub12::proc35() { + if (_currentIndex == -1) + return false; + + error("TODO: CStarControlSub12::proc35"); +} + +void CStarControlSub12::proc36(double *v1, double *v2, double *v3, double *v4) { + _sub13.fn19(v1, v2, v3, v4); +} + +void CStarControlSub12::load(SimpleFile *file, int param) { + _sub13.load(file, param); +} + +void CStarControlSub12::save(SimpleFile *file, int indent) { + _sub13.save(file, indent); +} + +bool CStarControlSub12::setupHandler(const CStar20Data *src) { + CStarControlSub20 *handler = nullptr; + + switch (_currentIndex) { + case -1: + handler = new CStarControlSub21(src); + break; + + case 0: + case 1: + case 2: + handler = new CStarControlSub22(src); + break; + + default: + break; + } + + if (handler) { + assert(!_handlerP); + _handlerP = handler; + return true; + } else { + return false; + } +} + +void CStarControlSub12::deleteHandler() { + if (_handlerP) { + delete _handlerP; + _handlerP = nullptr; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub12.h b/engines/titanic/star_control/star_control_sub12.h new file mode 100644 index 0000000000..8da45df5c0 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub12.h @@ -0,0 +1,120 @@ +/* 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 TITANIC_STAR_CONTROL_SUB12_H +#define TITANIC_STAR_CONTROL_SUB12_H + +#include "titanic/support/simple_file.h" +#include "titanic/star_control/fmatrix.h" +#include "titanic/star_control/star_control_sub13.h" +#include "titanic/star_control/star_control_sub20.h" + +namespace Titanic { + +class CStarControlSub12 { +private: + static FMatrix *_matrix1; + static FMatrix *_matrix2; +private: + int _currentIndex; + FVector _array[3]; + CStarControlSub20 *_handlerP; + CStarControlSub13 _sub13; + int _field108; +private: + /** + * Set up a handler + */ + bool setupHandler(const CStar20Data *src); + + /** + * Deletes any previous handler + */ + void deleteHandler(); + + /** + * Return whether the handler is locked + */ + bool isLocked() { return _handlerP->isLocked(); } +public: + static void init(); + static void deinit(); +public: + CStarControlSub12(void *val1, const CStar20Data *data); + CStarControlSub12(CStarControlSub13 *src); + virtual ~CStarControlSub12(); + + virtual void proc2(const void *src); + virtual void proc3(const CStar20Data *src); + virtual void setPosition(const FVector &v); + virtual void proc5(const FVector &v); + virtual void proc6(int v); + virtual void proc7(int v); + virtual void proc8(int v); + virtual void proc9(int v); + virtual void proc10(int v); + virtual void proc11(); + virtual void proc12(double v1, double v2); + virtual void proc13(CStarControlSub13 *dest); + virtual void proc14(int v); + virtual void proc15(int v); + virtual void proc16(); + virtual void proc17(); + virtual void proc18(); + virtual void proc19(); + virtual void proc20(double v); + virtual void proc21(CStarControlSub6 &sub6); + virtual void proc22(FMatrix &m); + virtual CStarControlSub6 proc23(); + virtual CStarControlSub6 proc24(); + virtual double proc25() const; + virtual double proc26() const; + virtual int proc27() const; + virtual FVector proc28(int index, const void *v2); + virtual FVector proc29(const FVector &v); + virtual FVector proc30(int index, const FVector &v); + virtual FVector proc31(int index, const FVector &v); + virtual void proc32(double v1, double v2); + virtual int getCurrentIndex() const { return _currentIndex; } + virtual bool setArrayVector(const FVector &v); + virtual bool proc35(); + virtual void proc36(double *v1, double *v2, double *v3, double *v4); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file, int param); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + + bool is108() const { return _field108; } + void set108() { _field108 = true; } + void reset108() { _field108 = false; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB12_H */ diff --git a/engines/titanic/star_control/star_control_sub13.cpp b/engines/titanic/star_control/star_control_sub13.cpp new file mode 100644 index 0000000000..c721b395c6 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub13.cpp @@ -0,0 +1,237 @@ +/* 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 "titanic/star_control/star_control_sub13.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CStarControlSub13::CStarControlSub13(void *src) : + _fieldC0(0), _fieldC4(0), _fieldC8(0), _fieldCC(0), _fieldD0(0) { + if (src) { + setup(src); + } else { + _fieldC = 0; + _field10 = 0x44480000; + _field14 = 0x461C4000; + _field18 = 0x41A00000; + _field1C = 0x41A00000; + _width = 600; + _height = 340; + _field24 = 0; + } + + _fieldD4 = 0; +} + +CStarControlSub13::CStarControlSub13(CStarControlSub13 *src) : + _matrix(&src->_matrix), _sub1(&src->_sub1), _sub2(&src->_sub2) { + _position = src->_position; + _fieldC = src->_fieldC; + _field10 = src->_field10; + _field14 = src->_field14; + _field18 = src->_field18; + _field1C = src->_field1C; + _width = src->_width; + _height = src->_height; + + _fieldCC = src->_fieldCC; + _fieldD0 = src->_fieldD0; + _fieldC0 = src->_fieldC0; + _fieldC4 = src->_fieldC4; + _fieldC8 = src->_fieldC8; + _field24 = src->_field24; + + _valArray[0] = src->_valArray[0]; + _valArray[2] = src->_valArray[2]; + _valArray[3] = src->_valArray[3]; + _fieldD4 = 0; +} + +void CStarControlSub13::setup(void *ptr) { + // TODO +} + +void CStarControlSub13::copyFrom(const void *src) { + if (!src) + return; +/* + _field0 = src->_field0; + _field4 = src->_field4; + _field8 = src->_field8; + _fieldC = src->_field18; + _field10 = src->_field1C; + */ +} + +void CStarControlSub13::load(SimpleFile *file, int param) { + _position._x = file->readFloat(); + _position._y = file->readFloat(); + _position._z = file->readFloat(); + _fieldC = file->readFloat(); + _field10 = file->readFloat(); + _field14 = file->readFloat(); + _field18 = file->readFloat(); + _field1C = file->readFloat(); + + int widthHeight = file->readNumber(); + _width = widthHeight & 0xff; + _height = _width >> 16; + _field24 = file->readNumber(); + + for (int idx = 0; idx < 5; ++idx) + _valArray[idx] = file->readFloat(); + + _matrix.load(file, param); + _fieldD4 = 0; +} + +void CStarControlSub13::save(SimpleFile *file, int indent) { + file->writeFloatLine(_position._x, indent); + file->writeFloatLine(_position._y, indent); + file->writeFloatLine(_position._z, indent); + file->writeFloatLine(_fieldC, indent); + file->writeFloatLine(_field10, indent); + file->writeFloatLine(_field14, indent); + file->writeFloatLine(_field18, indent); + file->writeFloatLine(_field1C, indent); + file->writeFloatLine(_width | (_height << 16), indent); + + for (int idx = 0; idx < 5; ++idx) + file->writeFloatLine(_valArray[idx], indent); + + _matrix.save(file, indent); +} + +void CStarControlSub13::setPosition(const FVector &v) { + _position = v; + _fieldD4 = 0; +} + +void CStarControlSub13::setPosition(const CStarControlSub6 &sub6) { + FVector vector; + _position.fn5(&vector, &sub6); + _position = sub6._matrix._row1; + _fieldD4 = 0; +} + +void CStarControlSub13::setMatrix(const FMatrix &m) { + _matrix = m; + _fieldD4 = 0; +} + +void CStarControlSub13::fn11(const FVector &v) { + _matrix.fn1(&v); + _fieldD4 = 0; +} + +void CStarControlSub13::setC(int v) { + _fieldC = v; + _fieldD4 = 0; +} + +void CStarControlSub13::set10(int v) { + _field10 = v; + _fieldD4 = 0; +} + +void CStarControlSub13::set14(int v) { + _field10 = v; +} + +void CStarControlSub13::set18(int v) { + _field18 = v; + _fieldD4 = 0; +} + +void CStarControlSub13::set1C(int v) { + _field1C = v; + _fieldD4 = 0; +} + +void CStarControlSub13::fn12() { + _matrix.clear(); + error("TODO: CStarControlSub13::fn12"); +} + +void CStarControlSub13::fn13(double v1, double v2) { + if (v1 == 0.0) { + _valArray[0] = v2; + _valArray[1] = -v2; + } else { + _valArray[3] = v2; + _valArray[4] = -v2; + } + + _valArray[2] = 0.0; + _field24 = v2 ? 2 : 0; +} + +void CStarControlSub13::fn14(double v) { + error("TODO: CStarControlSub13::fn14"); +} + +void CStarControlSub13::fn15(FMatrix &matrix) { + _matrix.fn3(&matrix); + _fieldD4 = 0; +} + +CStarControlSub6 CStarControlSub13::getSub1() { + if (!_fieldD4) + reset(); + + return _sub1; +} + +CStarControlSub6 CStarControlSub13::getSub2() { + if (!_fieldD4) + reset(); + + return _sub2; +} + +FVector CStarControlSub13::fn16(const FVector &v) { + error("TODO: CStarControlSub13::fn16"); +} + +FVector CStarControlSub13::fn17(int index, const FVector &v) { + error("TODO: CStarControlSub13::fn17"); +} + +FVector CStarControlSub13::fn18(int index, const FVector &v) { + error("TODO: CStarControlSub13::fn17"); +} + +void CStarControlSub13::fn19(double *v1, double *v2, double *v3, double *v4) { + error("TODO: CStarControlSub13::fn19"); +} + +void CStarControlSub13::reset() { + const double FACTOR = 3.1415927 * 0.0055555557; + error("TODO: CStarControlSub13::reset"); +} + +void CStarControlSub13::getMatrix(FMatrix *matrix) { + *matrix = _matrix; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub13.h b/engines/titanic/star_control/star_control_sub13.h new file mode 100644 index 0000000000..2f0b479cec --- /dev/null +++ b/engines/titanic/star_control/star_control_sub13.h @@ -0,0 +1,115 @@ +/* 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 TITANIC_STAR_CONTROL_SUB13_H +#define TITANIC_STAR_CONTROL_SUB13_H + +#include "titanic/support/simple_file.h" +#include "titanic/star_control/star_control_sub6.h" +#include "titanic/star_control/fmatrix.h" + +namespace Titanic { + +class CStarControlSub13 { +private: + double _fieldC; + double _field18; + double _field1C; + int _width; + int _height; + double _valArray[5]; + FMatrix _matrix; + CStarControlSub6 _sub1; + CStarControlSub6 _sub2; + double _fieldC0; + double _fieldC4; + int _fieldC8; + int _fieldCC; + double _fieldD0; + int _fieldD4; +private: + void setup(void *ptr); + + void reset(); +public: + FVector _position; + double _field10; + double _field14; + int _field24; +public: + CStarControlSub13(void *ptr); + CStarControlSub13(CStarControlSub13 *src); + + void copyFrom(const void *src); + + /** + * Load the data for the class from file + */ + void load(SimpleFile *file, int param); + + /** + * Save the data for the class to file + */ + void save(SimpleFile *file, int indent); + + /** + * Sets the position + */ + void setPosition(const FVector &v); + + /** + * Sets the position + */ + void setPosition(const CStarControlSub6 &sub6); + + /** + * Sets the matrix + */ + void setMatrix(const FMatrix &m); + + void fn11(const FVector &v); + void fn12(); + void fn13(double v1, double v2); + void fn14(double v); + void fn15(FMatrix &matrix); + CStarControlSub6 getSub1(); + CStarControlSub6 getSub2(); + FVector fn16(const FVector &v); + FVector fn17(int index, const FVector &v); + FVector fn18(int index, const FVector &v); + void fn19(double *v1, double *v2, double *v3, double *v4); + + /** + * Makes a copy of the instance's matrix into the passed matrix + */ + void getMatrix(FMatrix *matrix); + + void setC(int v); + void set10(int v); + void set14(int v); + void set18(int v); + void set1C(int v); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB13_H */ diff --git a/engines/titanic/star_control/star_control_sub2.cpp b/engines/titanic/star_control/star_control_sub2.cpp new file mode 100644 index 0000000000..fcbb70cbcb --- /dev/null +++ b/engines/titanic/star_control/star_control_sub2.cpp @@ -0,0 +1,53 @@ +/* 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 "titanic/star_control/star_control_sub2.h" + +namespace Titanic { + +bool CStarControlSub2::proc3(int v1) { + clear(); + // TODO + return true; +} + +bool CStarControlSub2::proc4(int v1, int v2, int v3, int v4, int v5) { + // TODO + return true; +} + +bool CStarControlSub2::loadStar() { + // TODO + return true; +} + +bool CStarControlSub2::proc7(int v1, int v2) { + // TODO + return true; +} + +bool CStarControlSub2::setup() { + // TODO + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub2.h b/engines/titanic/star_control/star_control_sub2.h new file mode 100644 index 0000000000..cd7781548f --- /dev/null +++ b/engines/titanic/star_control/star_control_sub2.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_STAR_CONTROL_SUB2_H +#define TITANIC_STAR_CONTROL_SUB2_H + +#include "titanic/star_control/base_star.h" + +namespace Titanic { + +class CStarControlSub2: public CBaseStar { +public: + virtual ~CStarControlSub2() {} + + virtual bool proc3(int v1); + virtual bool proc4(int v1, int v2, int v3, int v4, int v5); + virtual bool loadStar(); + virtual bool proc7(int v1, int v2); + + /** + * Setup the control + */ + bool setup(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB2_H */ diff --git a/engines/titanic/star_control/star_control_sub20.cpp b/engines/titanic/star_control/star_control_sub20.cpp new file mode 100644 index 0000000000..5c6c243eaa --- /dev/null +++ b/engines/titanic/star_control/star_control_sub20.cpp @@ -0,0 +1,144 @@ +/* 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 "titanic/star_control/star_control_sub20.h" +#include "common/textconsole.h" + +namespace Titanic { + +CStarControlSub20::CStarControlSub20(const CStar20Data *src) { + _lockCounter = 0; + _dataP = nullptr; + + if (src) { + copyFrom(src); + } else { + _field0 = 0.0; + _field4 = 0.0; + _field8 = 20.0; + _fieldC = 0.0; + _field10 = 50000.0; + _field14 = 1.0; + _field18 = 1.0; + _field1C = 0.0; + } +} + +CStarControlSub20::~CStarControlSub20() { + clear(); +} + +void CStarControlSub20::copyFrom(const CStar20Data *src) { + *((CStar20Data *)this) = *src; +} + +void CStarControlSub20::copyTo(CStar20Data *dest) { + *dest = *((CStar20Data *)this); +} + +void CStarControlSub20::proc4() { + if (!isLocked() && _field0 < _field10) { + _field4 += _field0; + if (_field8 == _field4) + _field0 -= _field4; + else + _field0 += _field4; + } +} + +void CStarControlSub20::proc5() { + if (!isLocked()) { + _field4 -= _field8; + if (_field4 == _field0) + _field0 += _field4; + else + _field0 -= _field4; + + if (_field4 < 0.0) + _field4 = 0.0; + } +} + +void CStarControlSub20::proc6() { + if (!isLocked()) + _field0 = _field10; +} + +void CStarControlSub20::proc7() { + if (!isLocked()) { + _field0 = 0.0; + _field4 = 0.0; + } +} + +void CStarControlSub20::proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m) { + if (_field0 > 0.0) { + warning("TODO: CStarControlSub20::proc11"); + } +} + +void CStarControlSub20::setData(void *data) { + clear(); + _dataP = (byte *)data; +} + +void CStarControlSub20::clear() { + if (_dataP) { + delete _dataP; + _dataP = nullptr; + } +} + +void CStarControlSub20::load(SimpleFile *file, int val) { + if (!val) { + _field0 = file->readFloat(); + _field4 = file->readFloat(); + _field8 = file->readFloat(); + _fieldC = file->readFloat(); + _field10 = file->readFloat(); + _field14 = file->readFloat(); + _field18 = file->readFloat(); + _field1C = file->readFloat(); + } +} + +void CStarControlSub20::save(SimpleFile *file, int indent) { + file->writeFloatLine(_field0, indent); + file->writeFloatLine(_field4, indent); + file->writeFloatLine(_field8, indent); + file->writeFloatLine(_fieldC, indent); + file->writeFloatLine(_field10, indent); + file->writeFloatLine(_field14, indent); + file->writeFloatLine(_field18, indent); + file->writeFloatLine(_field1C, indent); +} + +void CStarControlSub20::incLockCount() { + ++_lockCounter; +} + +void CStarControlSub20::decLockCount() { + if (_lockCounter > 0) + --_lockCounter; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub20.h b/engines/titanic/star_control/star_control_sub20.h new file mode 100644 index 0000000000..9dbabbb7f1 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub20.h @@ -0,0 +1,100 @@ +/* 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 TITANIC_STAR_CONTROL_SUB20_H +#define TITANIC_STAR_CONTROL_SUB20_H + +#include "titanic/support/simple_file.h" +#include "titanic/star_control/error_code.h" +#include "titanic/star_control/fmatrix.h" + +namespace Titanic { + +struct CStar20Data { + double _field0; + double _field4; + double _field8; + double _fieldC; + double _field10; + double _field14; + double _field18; + double _field1C; +}; + +class CStarControlSub20 : public CStar20Data { +public: + int _lockCounter; + byte *_dataP; +public: + CStarControlSub20(const CStar20Data *src); + virtual ~CStarControlSub20(); + + virtual void copyFrom(const CStar20Data *src); + virtual void copyTo(CStar20Data *dest); + virtual void proc4(); + virtual void proc5(); + virtual void proc6(); + virtual void proc7(); + virtual void proc8() {} + virtual void proc9(FVector *v, int v2, FMatrix *matrix) {} + virtual void proc10() {} + virtual void proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m); + + /** + * Set the data + */ + virtual void setData(void *data); + + /** + * Clear the class + */ + virtual void clear(); + + /** + * Load the class + */ + virtual void load(SimpleFile *file, int val = 0); + + /** + * Save the class + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Increment tthe lock counter + */ + void incLockCount(); + + /** + * Decrement the lock counter + */ + void decLockCount(); + + /** + * Returns true if the lock counter is non-zero + */ + bool isLocked() const { return _lockCounter > 0; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB20_H */ diff --git a/engines/titanic/star_control/star_control_sub21.cpp b/engines/titanic/star_control/star_control_sub21.cpp new file mode 100644 index 0000000000..1730244184 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub21.cpp @@ -0,0 +1,32 @@ +/* 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 "titanic/star_control/star_control_sub21.h" +#include "common/textconsole.h" + +namespace Titanic { + +CStarControlSub21::CStarControlSub21(const CStar20Data *src) : + CStarControlSub20(src), _sub24() { +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub21.h b/engines/titanic/star_control/star_control_sub21.h new file mode 100644 index 0000000000..5febda0ebb --- /dev/null +++ b/engines/titanic/star_control/star_control_sub21.h @@ -0,0 +1,40 @@ +/* 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 TITANIC_STAR_CONTROL_SUB21_H +#define TITANIC_STAR_CONTROL_SUB21_H + +#include "titanic/star_control/star_control_sub20.h" +#include "titanic/star_control/star_control_sub24.h" + +namespace Titanic { + +class CStarControlSub21 : public CStarControlSub20 { +private: + CStarControlSub24 _sub24; +public: + CStarControlSub21(const CStar20Data *src); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB21_H */ diff --git a/engines/titanic/star_control/star_control_sub22.cpp b/engines/titanic/star_control/star_control_sub22.cpp new file mode 100644 index 0000000000..b06731b6d2 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub22.cpp @@ -0,0 +1,32 @@ +/* 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 "titanic/star_control/star_control_sub22.h" +#include "common/textconsole.h" + +namespace Titanic { + +CStarControlSub22::CStarControlSub22(const CStar20Data *src) : + CStarControlSub20(src), _sub27() { +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub22.h b/engines/titanic/star_control/star_control_sub22.h new file mode 100644 index 0000000000..88a114f8c3 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub22.h @@ -0,0 +1,40 @@ +/* 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 TITANIC_STAR_CONTROL_SUB22_H +#define TITANIC_STAR_CONTROL_SUB22_H + +#include "titanic/star_control/star_control_sub20.h" +#include "titanic/star_control/star_control_sub27.h" + +namespace Titanic { + +class CStarControlSub22 : public CStarControlSub20 { +private: + CStarControlSub27 _sub27; +public: + CStarControlSub22(const CStar20Data *src); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB22_H */ diff --git a/engines/titanic/star_control/star_control_sub23.cpp b/engines/titanic/star_control/star_control_sub23.cpp new file mode 100644 index 0000000000..b009cbc35b --- /dev/null +++ b/engines/titanic/star_control/star_control_sub23.cpp @@ -0,0 +1,28 @@ +/* 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 "titanic/star_control/star_control_sub23.h" +#include "common/textconsole.h" + +namespace Titanic { + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub23.h b/engines/titanic/star_control/star_control_sub23.h new file mode 100644 index 0000000000..136401e329 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub23.h @@ -0,0 +1,33 @@ +/* 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 TITANIC_STAR_CONTROL_SUB23_H +#define TITANIC_STAR_CONTROL_SUB23_H + +namespace Titanic { + +class CStarControlSub23 { +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB23_H */ diff --git a/engines/titanic/star_control/star_control_sub24.cpp b/engines/titanic/star_control/star_control_sub24.cpp new file mode 100644 index 0000000000..6f17eb7193 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub24.cpp @@ -0,0 +1,29 @@ +/* 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 "titanic/star_control/star_control_sub24.h" +#include "common/textconsole.h" + +namespace Titanic { + + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub24.h b/engines/titanic/star_control/star_control_sub24.h new file mode 100644 index 0000000000..e0970fc1de --- /dev/null +++ b/engines/titanic/star_control/star_control_sub24.h @@ -0,0 +1,35 @@ +/* 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 TITANIC_STAR_CONTROL_SUB24_H +#define TITANIC_STAR_CONTROL_SUB24_H + +#include "titanic/star_control/star_control_sub23.h" + +namespace Titanic { + +class CStarControlSub24 : public CStarControlSub23 { +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB24_H */ diff --git a/engines/titanic/star_control/star_control_sub25.cpp b/engines/titanic/star_control/star_control_sub25.cpp new file mode 100644 index 0000000000..f91c75af6a --- /dev/null +++ b/engines/titanic/star_control/star_control_sub25.cpp @@ -0,0 +1,28 @@ +/* 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 "titanic/star_control/star_control_sub25.h" +#include "common/textconsole.h" + +namespace Titanic { + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub25.h b/engines/titanic/star_control/star_control_sub25.h new file mode 100644 index 0000000000..e943782e37 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub25.h @@ -0,0 +1,43 @@ +/* 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 TITANIC_STAR_CONTROL_SUB25_H +#define TITANIC_STAR_CONTROL_SUB25_H + +#include "titanic/star_control/fmatrix.h" +#include "titanic/star_control/star_control_sub26.h" + +namespace Titanic { + +class CStarControlSub25 { +public: + FMatrix _matrix1; + FMatrix _matrix2; + CStarControlSub26 _sub1; + CStarControlSub26 _sub2; +public: + +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB25_H */ diff --git a/engines/titanic/star_control/star_control_sub26.cpp b/engines/titanic/star_control/star_control_sub26.cpp new file mode 100644 index 0000000000..89ff93c347 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub26.cpp @@ -0,0 +1,34 @@ +/* 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 "titanic/star_control/star_control_sub26.h" +#include "common/textconsole.h" + +namespace Titanic { + +double CStarControlSub26::fn1() const { + return _sub._v1 * _sub._v1 + _sub._v2 * _sub._v2 + + _sub._v3 * _sub._v3 + _field0 * _field0; +} + + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub26.h b/engines/titanic/star_control/star_control_sub26.h new file mode 100644 index 0000000000..4054a2ba6e --- /dev/null +++ b/engines/titanic/star_control/star_control_sub26.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_STAR_CONTROL_SUB26_H +#define TITANIC_STAR_CONTROL_SUB26_H + +namespace Titanic { + +class CStarControlSub26 { + struct Sub { + double _v1; + double _v2; + double _v3; + + Sub() : _v1(0.0), _v2(0.0), _v3(0.0) {} + }; +public: + double _field0; + Sub _sub; +public: + CStarControlSub26() : _field0(1.0) {} + + double fn1() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB26_H */ diff --git a/engines/titanic/star_control/star_control_sub27.cpp b/engines/titanic/star_control/star_control_sub27.cpp new file mode 100644 index 0000000000..6f17eb7193 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub27.cpp @@ -0,0 +1,29 @@ +/* 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 "titanic/star_control/star_control_sub24.h" +#include "common/textconsole.h" + +namespace Titanic { + + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub27.h b/engines/titanic/star_control/star_control_sub27.h new file mode 100644 index 0000000000..01782b69ca --- /dev/null +++ b/engines/titanic/star_control/star_control_sub27.h @@ -0,0 +1,35 @@ +/* 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 TITANIC_STAR_CONTROL_SUB27_H +#define TITANIC_STAR_CONTROL_SUB27_H + +#include "titanic/star_control/star_control_sub23.h" + +namespace Titanic { + +class CStarControlSub27 : public CStarControlSub23 { +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB27_H */ diff --git a/engines/titanic/star_control/star_control_sub4.cpp b/engines/titanic/star_control/star_control_sub4.cpp new file mode 100644 index 0000000000..f765acbbc1 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub4.cpp @@ -0,0 +1,45 @@ +/* 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/algorithm.h" +#include "titanic/star_control/star_control_sub4.h" + +namespace Titanic { + +CStarControlSub4::CStarControlSub4() { +} + +void CStarControlSub4::initialize() { + _min._v1 = _min._v2 = _min._v3 = 9.9999994e27; + _max._v1 = _max._v2 = _max._v3 = -9.9999994e27; +} + +void CStarControlSub4::checkEntry(const CBaseStarVal &val) { + _min._v1 = MIN(_min._v1, val._v1); + _min._v2 = MIN(_min._v2, val._v2); + _min._v3 = MIN(_min._v3, val._v3); + _max._v1 = MAX(_max._v1, val._v1); + _max._v2 = MAX(_max._v2, val._v2); + _max._v3 = MAX(_max._v3, val._v3); +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub4.h b/engines/titanic/star_control/star_control_sub4.h new file mode 100644 index 0000000000..f0fcfaf7f4 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub4.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_STAR_CONTROL_SUB4_H +#define TITANIC_STAR_CONTROL_SUB4_H + +namespace Titanic { + +struct CBaseStarVal { + double _v1, _v2, _v3; + CBaseStarVal() : _v1(0), _v2(0), _v3(0) {} +}; + +class CStarControlSub4 { +private: + CBaseStarVal _min; + CBaseStarVal _max; +public: + CStarControlSub4(); + + void initialize(); + + void checkEntry(const CBaseStarVal &val); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB4_H */ diff --git a/engines/titanic/star_control/star_control_sub5.cpp b/engines/titanic/star_control/star_control_sub5.cpp new file mode 100644 index 0000000000..e2899220c8 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub5.cpp @@ -0,0 +1,44 @@ +/* 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 "titanic/star_control/star_control_sub5.h" + +namespace Titanic { + +CStarControlSub5::CStarControlSub5() : + _field4(1), _field78AC(0), _field78B0(0) { +} + +bool CStarControlSub5::setup() { + // TODO + return true; +} + +void CStarControlSub5::proc2() { + // TODO +} + +void CStarControlSub5::proc3(CErrorCode *errorCode) { + // TODO +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub5.h b/engines/titanic/star_control/star_control_sub5.h new file mode 100644 index 0000000000..ce92ef1135 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub5.h @@ -0,0 +1,59 @@ +/* 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 TITANIC_STAR_CONTROL_SUB5_H +#define TITANIC_STAR_CONTROL_SUB5_H + +#include "titanic/star_control/star_control_sub6.h" +#include "titanic/star_control/error_code.h" + +namespace Titanic { + +class CStarControlSub5 { + struct SubEntry { + int _field0; + int _field4; + int _field8; + int _fieldC; + }; +private: + int _field4; + SubEntry _array[5]; + CStarControlSub6 _sub1, _sub2; + int _field7914; + int _field78AC; + int _field78B0; +public: + CStarControlSub5(); + virtual ~CStarControlSub5() {} + + virtual bool setup(); + virtual void proc2(); + virtual void proc3(CErrorCode *errorCode); + + int get4() const { return _field4; } + void set4(int val) { _field4 = val; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB5_H */ diff --git a/engines/titanic/star_control/star_control_sub6.cpp b/engines/titanic/star_control/star_control_sub6.cpp new file mode 100644 index 0000000000..a5a1d81aa8 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub6.cpp @@ -0,0 +1,115 @@ +/* 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 "titanic/star_control/star_control_sub6.h" + +namespace Titanic { + +CStarControlSub6 *CStarControlSub6::_static; + +CStarControlSub6::CStarControlSub6() { + clear(); +} + +CStarControlSub6::CStarControlSub6(int mode, double val) { + set(mode, val); +} + +CStarControlSub6::CStarControlSub6(const CStarControlSub6 *src) { + copyFrom(src); +} + +void CStarControlSub6::init() { + _static = nullptr; +} + +void CStarControlSub6::deinit() { + delete _static; + _static = nullptr; +} + +void CStarControlSub6::clear() { + _matrix.clear(); + _field24 = 0; + _field28 = 0; + _field2C = 0; +} + +void CStarControlSub6::set(int mode, double amount) { + const double ROTATION = 3.1415927 * 0.0055555557; + double sinVal = sin(amount * ROTATION); + double cosVal = cos(amount * ROTATION); + + switch (mode) { + case 0: + _matrix._row1._x = 1.0; + _matrix._row1._y = 0.0; + _matrix._row1._z = 0.0; + _matrix._row2._x = 0.0; + _matrix._row2._y = cosVal; + _matrix._row2._z = sinVal; + _matrix._row3._x = 0.0; + _matrix._row3._y = -sinVal; + _matrix._row3._z = cosVal; + break; + + case 1: + _matrix._row1._x = cosVal; + _matrix._row1._y = 0.0; + _matrix._row1._z = sinVal; + _matrix._row2._x = 0.0; + _matrix._row2._y = 1.0; + _matrix._row2._z = 0.0; + _matrix._row3._x = -sinVal; + _matrix._row3._y = 0.0; + _matrix._row3._z = sinVal; + break; + + case 2: + _matrix._row1._x = cosVal; + _matrix._row1._y = sinVal; + _matrix._row1._z = 0.0; + _matrix._row2._x = -sinVal; + _matrix._row2._y = cosVal; + _matrix._row2._z = 0.0; + _matrix._row3._x = 0.0; + _matrix._row3._y = 0.0; + _matrix._row3._z = 1.0; + break; + + default: + break; + } + + _field24 = 0.0; + _field28 = 0.0; + _field2C = 0.0; +} + +void CStarControlSub6::copyFrom(const CStarControlSub6 *src) { + _matrix = src->_matrix; + _field24 = src->_field24; + _field28 = src->_field28; + _field2C = src->_field2C; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub6.h b/engines/titanic/star_control/star_control_sub6.h new file mode 100644 index 0000000000..118c7c7f10 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub6.h @@ -0,0 +1,62 @@ +/* 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 TITANIC_STAR_CONTROL_SUB6_H +#define TITANIC_STAR_CONTROL_SUB6_H + +#include "titanic/star_control/fmatrix.h" + +namespace Titanic { + +class CStarControlSub6 { +private: + int _field24; + int _field28; + int _field2C; +private: + static CStarControlSub6 *_static; +public: + static void init(); + static void deinit(); +public: + FMatrix _matrix; +public: + CStarControlSub6(); + CStarControlSub6(int mode, double amount); + CStarControlSub6(const CStarControlSub6 *src); + + /** + * Clear the item + */ + void clear(); + + /** + * Sets the default data + */ + void set(int mode, double val); + + void copyFrom(const CStarControlSub6 *src); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB6_H */ diff --git a/engines/titanic/star_control/star_control_sub7.cpp b/engines/titanic/star_control/star_control_sub7.cpp new file mode 100644 index 0000000000..b33f8be582 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub7.cpp @@ -0,0 +1,36 @@ +/* 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 "titanic/star_control/star_control_sub7.h" + +namespace Titanic { + +void CStarControlSub7::proc2(int v1, int v2, int v3) { + // TODO +} + +bool CStarControlSub7::proc5(int v1) { + // TODO + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub7.h b/engines/titanic/star_control/star_control_sub7.h new file mode 100644 index 0000000000..b73124ddd7 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub7.h @@ -0,0 +1,39 @@ +/* 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 TITANIC_STAR_CONTROL_SUB7_H +#define TITANIC_STAR_CONTROL_SUB7_H + +#include "titanic/star_control/base_star.h" +namespace Titanic { + +class CStarControlSub7 : public CBaseStar { +public: + virtual ~CStarControlSub7() { clear(); } + + virtual void proc2(int v1, int v2, int v3); + virtual bool proc5(int v1); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB7_H */ diff --git a/engines/titanic/star_control/star_control_sub8.cpp b/engines/titanic/star_control/star_control_sub8.cpp new file mode 100644 index 0000000000..cdb249b663 --- /dev/null +++ b/engines/titanic/star_control/star_control_sub8.cpp @@ -0,0 +1,31 @@ +/* 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 "titanic/star_control/star_control_sub8.h" + +namespace Titanic { + +CStarControlSub8::CStarControlSub8() : + _field0(0), _field4(0), _field8(-1), _fieldC(-1) { +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_control_sub8.h b/engines/titanic/star_control/star_control_sub8.h new file mode 100644 index 0000000000..6d8d1f0c7d --- /dev/null +++ b/engines/titanic/star_control/star_control_sub8.h @@ -0,0 +1,60 @@ +/* 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 TITANIC_STAR_CONTROL_SUB8_H +#define TITANIC_STAR_CONTROL_SUB8_H + +#include "titanic/support/simple_file.h" + +namespace Titanic { + +class CStarControlSub8 { + struct StructEntry { + int _field0; + int _field4; + int _field8; + int _fieldC; + }; +private: + int _field0; + int _field4; + int _fieldC; + StructEntry _array[3]; +public: + int _field8; +public: + CStarControlSub8(); + + /** + * Load the data for the class from file + */ + void load(SimpleFile *file) {} + + /** + * Save the data for the class to file + */ + void save(SimpleFile *file, int indent) {} +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB8_H */ diff --git a/engines/titanic/star_control/star_field.cpp b/engines/titanic/star_control/star_field.cpp new file mode 100644 index 0000000000..c50e8466ec --- /dev/null +++ b/engines/titanic/star_control/star_field.cpp @@ -0,0 +1,130 @@ +/* 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 "titanic/star_control/star_field.h" +#include "titanic/star_control/surface_area.h" + +namespace Titanic { + +CStarField::CStarField() : _val1(0), _val2(0), _val3(0), _val4(true), + _val5(0), _val6(false) { +} + +void CStarField::load(SimpleFile *file) { + _sub7.load(file); + _sub8.load(file); + _val1 = file->readNumber(); + _val2 = file->readNumber(); + _val3 = file->readNumber(); + _val4 = file->readNumber(); + _val6 = file->readNumber(); +} + +void CStarField::save(SimpleFile *file, int indent) { + _sub7.save(file, indent); + _sub8.save(file, indent); + file->writeNumberLine(_val1, indent); + file->writeNumberLine(_val2, indent); + file->writeNumberLine(_val3, indent); + file->writeNumberLine(_val4, indent); + file->writeNumberLine(_val6, indent); +} + +bool CStarField::initDocument() { + bool valid = setup() && _points1.initialize(); + if (valid) + valid = _sub5.setup(); + if (valid) + valid = _points1.initialize(); + if (valid) + valid = _points2.initialize(); + + return valid; +} + +void CStarField::render(CVideoSurface *surface, CStarControlSub12 *sub12) { + CSurfaceArea surfaceArea(surface); + draw(&surfaceArea, sub12, &_sub5); + + + // TODO +} + +int CStarField::get1() const { + return _val1; +} + +void CStarField::set1(int val) { + _val1 = val; +} + +int CStarField::get2() const { + return _val2; +} + +void CStarField::set2(int val) { + _val2 = val; +} + +int CStarField::get54() const { + return _sub5.get4(); +} + +void CStarField::set54(int val) { + _sub5.set4(val); +} + +int CStarField::get3() const { + return _val3; +} + +void CStarField::set3(int val) { + _val3 = val; +} + +void CStarField::toggle4() { + _val4 = !_val4; +} + +bool CStarField::set4(bool val) { + bool oldVal = _val4; + _val4 = val; + return oldVal; +} + +int CStarField::get88() const { + return _sub8._field8; +} + +int CStarField::get5() const { + return _val5; +} + +void CStarField::update6() { + _val6 = _sub8._field8 == 2; +} + +int CStarField::get6() const { + return _val6; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_field.h b/engines/titanic/star_control/star_field.h new file mode 100644 index 0000000000..ef1ee29737 --- /dev/null +++ b/engines/titanic/star_control/star_field.h @@ -0,0 +1,86 @@ +/* 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 TITANIC_STAR_FIELD_H +#define TITANIC_STAR_FIELD_H + +#include "titanic/star_control/star_control_sub2.h" +#include "titanic/star_control/star_control_sub5.h" +#include "titanic/star_control/star_control_sub7.h" +#include "titanic/star_control/star_control_sub8.h" +#include "titanic/star_control/star_points1.h" +#include "titanic/star_control/star_points2.h" + +namespace Titanic { + +class CStarField : public CStarControlSub2 { +private: + CStarControlSub7 _sub7; + CStarControlSub8 _sub8; + CStarPoints1 _points1; + CStarPoints2 _points2; + CStarControlSub5 _sub5; + int _val1; + int _val2; + int _val3; + bool _val4; + int _val5; + bool _val6; +public: + CStarField(); + + /** + * Load the data for the class from file + */ + void load(SimpleFile *file); + + /** + * Save the data for the class to file + */ + void save(SimpleFile *file, int indent); + + bool initDocument(); + + /** + * Renders the contents of the starfield + */ + void render(CVideoSurface *surface, CStarControlSub12 *sub12); + + int get1() const; + void set1(int val); + int get2() const; + void set2(int val); + int get54() const; + void set54(int val); + int get3() const; + void set3(int val); + void toggle4(); + bool set4(bool val); + int get88() const; + int get5() const; + void update6(); + int get6() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_FIELD_H */ diff --git a/engines/titanic/star_control/star_points1.cpp b/engines/titanic/star_control/star_points1.cpp new file mode 100644 index 0000000000..6e698d61f7 --- /dev/null +++ b/engines/titanic/star_control/star_points1.cpp @@ -0,0 +1,69 @@ +/* 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 "titanic/star_control/star_points1.h" +#include "titanic/star_control/star_control_sub12.h" +#include "titanic/titanic.h" + +namespace Titanic { + +#define ARRAY_COUNT 876 +const double FACTOR = 3.1415927 * 0.0055555557; + +CStarPoints1::CStarPoints1() { +} + +bool CStarPoints1::initialize() { + // Get a reference to the starfield points resource + Common::SeekableReadStream *stream = g_vm->_filesManager->getResource("STARFIELD/POINTS"); + assert(stream && stream->size() == (12 * ARRAY_COUNT)); + + _data.resize(ARRAY_COUNT); + for (int idx = 0; idx < ARRAY_COUNT; ++idx) { + FVector &entry = _data[idx]; + + // Get the next set of values + double v1 = stream->readUint32LE(); + double v2 = stream->readUint32LE(); + stream->readUint32LE(); + + v1 *= 0.0099999998 * FACTOR; + v2 *= 0.015 * FACTOR; + + entry._x = cos(v2) * 3000000.0 * cos(v1); + entry._y = sin(v2) * 3000000.0 * cos(v1); + entry._z = sin(v1) * 3000000.0; + } + + return true; +} + +void CStarPoints1::draw(CSurfaceArea *surface, CStarControlSub12 *img) { + if (_data.empty()) + return; + + + + // TODO +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_points1.h b/engines/titanic/star_control/star_points1.h new file mode 100644 index 0000000000..a6e4ee2ec9 --- /dev/null +++ b/engines/titanic/star_control/star_points1.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_STAR_POINTS1_H +#define TITANIC_STAR_POINTS1_H + +#include "common/array.h" +#include "titanic/star_control/surface_area.h" +#include "titanic/star_control/fvector.h" + +namespace Titanic { + +class CStarControlSub12; + +class CStarPoints1 { +private: + Common::Array<FVector> _data; +public: + CStarPoints1(); + + /** + * Initialize the array + */ + bool initialize(); + + /** + * Draw the starfield points + */ + void draw(CSurfaceArea *surface, CStarControlSub12 *img); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_POINTS1_H */ diff --git a/engines/titanic/star_control/star_points2.cpp b/engines/titanic/star_control/star_points2.cpp new file mode 100644 index 0000000000..4fea298f93 --- /dev/null +++ b/engines/titanic/star_control/star_points2.cpp @@ -0,0 +1,59 @@ +/* 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 "titanic/star_control/star_points2.h" +#include "titanic/titanic.h" + +namespace Titanic { + +#define ARRAY_COUNT 80 +const double FACTOR = 3.1415927 * 0.0055555557; + +bool CStarPoints2::initialize() { + // Get a reference to the starfield points resource + Common::SeekableReadStream *stream = g_vm->_filesManager->getResource("STARFIELD/POINTS2"); + + _data.resize(ARRAY_COUNT); + for (int rootCtr = 0; rootCtr < ARRAY_COUNT; ++rootCtr) { + // Get the number of sub-entries for this entry + int count = stream->readUint32LE(); + double v1, v2; + + // Read in the sub-entries + RootEntry &rootEntry = _data[rootCtr]; + rootEntry.resize(count * 2); + for (int idx = 0; idx < count * 2; ++idx) { + DataEntry &entry = rootEntry[idx]; + v1 = stream->readSint32LE(); + v2 = stream->readSint32LE(); + v1 *= 0.015 * FACTOR; + v2 *= 0.0099999998 * FACTOR; + entry._v1 = cos(v1) * 3000000.0 * cos(v2); + entry._v2 = sin(v1) * 3000000.0 * cos(v2); + entry._v3 = sin(v2) * 3000000.0; + } + } + + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_points2.h b/engines/titanic/star_control/star_points2.h new file mode 100644 index 0000000000..31bded4069 --- /dev/null +++ b/engines/titanic/star_control/star_points2.h @@ -0,0 +1,53 @@ +/* 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 TITANIC_STAR_POINTS2_H +#define TITANIC_STAR_POINTS2_H + +#include "common/array.h" + +namespace Titanic { + +class CStarPoints2 { + struct DataEntry { + int _v1; + int _v2; + int _v3; + }; + + class RootEntry : public Common::Array<DataEntry> { + public: + int _field0; + RootEntry() : _field0(0) {} + }; +private: + Common::Array<RootEntry> _data; +public: + /** + * Initializes the data + */ + bool initialize(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_POINTS2_H */ diff --git a/engines/titanic/star_control/star_view.cpp b/engines/titanic/star_control/star_view.cpp new file mode 100644 index 0000000000..f5d1d36c49 --- /dev/null +++ b/engines/titanic/star_control/star_view.cpp @@ -0,0 +1,135 @@ +/* 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 "titanic/support/screen_manager.h" +#include "titanic/star_control/star_view.h" +#include "titanic/star_control/star_control.h" +#include "titanic/star_control/star_field.h" +#include "titanic/core/game_object.h" + +namespace Titanic { + +CStarView::CStarView() : _sub12(nullptr, nullptr), _sub13((void *)nullptr), + _owner(nullptr), _starField(nullptr), _videoSurface(nullptr), _field118(0), + _videoSurface2(nullptr), _field210(0), _homePhotoMask(nullptr), + _field218(0), _field21C(0) { + CStar20Data data = { 0, 0, 0x47C35000, 0, 0x41A00000, + 0x3F800000, 0x3F800000, 0x3F800000 }; + + _sub12.proc3(&data); +} + +void CStarView::load(SimpleFile *file, int param) { + if (!param) { + _sub12.load(file, param); + + _field118 = file->readNumber(); + if (_field118) + _sub13.load(file, 0); + + _field218 = file->readNumber(); + _field21C = file->readNumber(); + } +} + +void CStarView::save(SimpleFile *file, int indent) { + _sub12.save(file, indent); + + file->writeNumberLine(_field118, indent); + if (_field118) + _sub13.save(file, indent); + + file->writeNumberLine(_field218, indent); + file->writeNumberLine(_field21C, indent); +} + +void CStarView::setup(CScreenManager *screenManager, CStarField *starField, CStarControl *starControl) { + _starField = starField; + _owner = starControl; +} + +void CStarView::reset() { + // TODO +} + +void CStarView::draw(CScreenManager *screenManager) { + if (!screenManager || !_videoSurface || !_starField) + return; + + if (_fader.isActive()) { + CVideoSurface *surface = _field21C ? _videoSurface2 : _videoSurface; + surface = _fader.fade(screenManager, surface); + screenManager->blitFrom(SURFACE_PRIMARY, surface); + } else { + Point destPos(20, 10); + + if (_field21C) { + screenManager->blitFrom(SURFACE_PRIMARY, _videoSurface2, &destPos); + + if (!_homePhotoMask && _owner) { + _homePhotoMask = _owner->getHiddenObject("HomePhotoMask"); + } + + if (_homePhotoMask) + _homePhotoMask->draw(screenManager, Point(20, 187)); + } else { + fn1(); + + // Render the display + _videoSurface->clear(); + _videoSurface->lock(); + _starField->render(_videoSurface, &_sub12); + _videoSurface->unlock(); + + // Blit the resulting surface to the screen + screenManager->blitFrom(SURFACE_PRIMARY, _videoSurface, &destPos); + } + } +} + +void CStarView::MouseButtonDownMsg(int unused, const Point &pt) { + // TODO +} + +void CStarView::MouseMoveMsg(int unused, const Point &pt) { + // TODO +} + +CErrorCode CStarView::KeyCharMsg(int key) { + // TODO + return CErrorCode(); +} + +bool CStarView::canSetStarDestination() const { + // TODO + return false; +} + +void CStarView::starDestinationSet() { + // TODO +} + +void CStarView::fn1() { + // TODO +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/star_view.h b/engines/titanic/star_control/star_view.h new file mode 100644 index 0000000000..bcba5ac436 --- /dev/null +++ b/engines/titanic/star_control/star_view.h @@ -0,0 +1,107 @@ +/* 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 TITANIC_STAR_VIEW_H +#define TITANIC_STAR_VIEW_H + +#include "titanic/support/simple_file.h" +#include "titanic/support/video_surface.h" +#include "titanic/star_control/star_control_sub12.h" +#include "titanic/star_control/star_control_sub13.h" +#include "titanic/star_control/surface_fader.h" +#include "titanic/star_control/error_code.h" + +namespace Titanic { + +class CStarControl; +class CStarField; + +class CStarView { +private: + CStarControl *_owner; + CStarField *_starField; + CVideoSurface *_videoSurface; + CStarControlSub12 _sub12; + int _field118; + CStarControlSub13 _sub13; + CSurfaceFader _fader; + CVideoSurface *_videoSurface2; + int _field210; + CGameObject *_homePhotoMask; + int _field218; + int _field21C; +private: + void fn1(); +public: + CStarView(); + + /** + * Load the data for the class from file + */ + void load(SimpleFile *file, int param); + + /** + * Save the data for the class to file + */ + void save(SimpleFile *file, int indent); + + /** + * Sets references used by the view + */ + void setup(CScreenManager *screenManager, CStarField *starField, CStarControl *starControl); + + void reset(); + + /** + * Allows the item to draw itself + */ + void draw(CScreenManager *screenManager); + + /** + * Handles mouse down messages + */ + void MouseButtonDownMsg(int unused, const Point &pt); + + /** + * Handles mouse move messages + */ + void MouseMoveMsg(int unused, const Point &pt); + + /** + * Handles keyboard messages + */ + CErrorCode KeyCharMsg(int key); + + /** + * Returns true if a star destination can be set + */ + bool canSetStarDestination() const; + + /** + * Called when a star destination is set + */ + void starDestinationSet(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_RENDERER_H */ diff --git a/engines/titanic/star_control/surface_area.cpp b/engines/titanic/star_control/surface_area.cpp new file mode 100644 index 0000000000..77f8222dad --- /dev/null +++ b/engines/titanic/star_control/surface_area.cpp @@ -0,0 +1,50 @@ +/* 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 "titanic/star_control/surface_area.h" + +namespace Titanic { + +CSurfaceArea::CSurfaceArea(CVideoSurface *surface) { + _width = surface->getWidth(); + _height = surface->getHeight(); + _pitch = surface->getPitch(); + + // Original supported other pixel depths + _bpp = surface->getPixelDepth(); + assert(_bpp == 2); + _pixelsPtr = surface->getPixels(); + + initialize(); +} + +void CSurfaceArea::initialize() { + _bounds = Rect(0, 0, _width - 1, _height - 1); + _centroid = Point(_width / 2, _height / 2); + _field22 = _field21 = _field20 = 0xFF; + _field27 = _field26 = _field25 = 0; + _field24 = _field23 = 0; + _field28 = _field2C = 0; + _field38 = 0; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/surface_area.h b/engines/titanic/star_control/surface_area.h new file mode 100644 index 0000000000..4d1913123c --- /dev/null +++ b/engines/titanic/star_control/surface_area.h @@ -0,0 +1,65 @@ +/* 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 TITANIC_SURFACE_OBJ_H +#define TITANIC_SURFACE_OBJ_H + +#include "titanic/support/rect.h" +#include "titanic/support/video_surface.h" + +namespace Titanic { + +class CSurfaceArea { +private: + /** + * Initialize data for the class + */ + void initialize(); +public: + int _field0; + int _width; + int _height; + int _pitch; + int _bpp; + uint16 *_pixelsPtr; + Point _centroid; + byte _field20; + byte _field21; + byte _field22; + byte _field23; + byte _field24; + byte _field25; + byte _field26; + byte _field27; + int _field28; + int _field2C; + int _field30; + int _field34; + int _field38; + Rect _bounds; +public: + CSurfaceArea(CVideoSurface *surface); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STAR_CONTROL_SUB16_H */ diff --git a/engines/titanic/star_control/surface_fader.cpp b/engines/titanic/star_control/surface_fader.cpp new file mode 100644 index 0000000000..089ad51717 --- /dev/null +++ b/engines/titanic/star_control/surface_fader.cpp @@ -0,0 +1,73 @@ +/* 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 "titanic/star_control/surface_fader.h" +#include "common/system.h" +#include "graphics/pixelformat.h" + +namespace Titanic { + +CSurfaceFader::CSurfaceFader() : CSurfaceFaderBase() { + _dataP = new byte[_count]; + + for (int idx = 0; idx < _count; ++idx) { + // TODO: Setup data bytes + } +} + +CSurfaceFader::~CSurfaceFader() { + delete[] _dataP; +} + +void CSurfaceFader::copySurface(CSurfaceArea &srcSurface, CSurfaceArea &destSurface) { + const uint16 *srcPixelP = srcSurface._pixelsPtr; + uint16 *destPixelP = destSurface._pixelsPtr; + + // Currently we only support 2 bytes per pixel surfaces + assert(srcSurface._bpp == 2); + + byte dataVal = _dataP[_index]; + double fraction = (double)dataVal / ((double)(_count - 1)); + if (!_fadeIn) + // For fade outs, reverse the percentage visibility + fraction = 1.0 - fraction; + + // Iterate through the pixels + byte r, g, b; + Graphics::PixelFormat format = g_system->getScreenFormat(); + + for (int yp = 0; yp < srcSurface._height; ++yp) { + for (int xp = 0; xp < srcSurface._width; ++xp, ++srcPixelP, ++destPixelP) { + format.colorToRGB(*srcPixelP, r, g, b); + r = (byte)((double)r * fraction); + g = (byte)((double)g * fraction); + b = (byte)((double)b * fraction); + *destPixelP = format.RGBToColor(r, g, b); + } + } +} + +void CSurfaceFader::setFadeIn(bool fadeIn) { + _fadeIn = fadeIn; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/surface_fader.h b/engines/titanic/star_control/surface_fader.h new file mode 100644 index 0000000000..650cbbb19b --- /dev/null +++ b/engines/titanic/star_control/surface_fader.h @@ -0,0 +1,51 @@ +/* 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 TITANIC_SURFACE_FADER_H +#define TITANIC_SURFACE_FADER_H + +#include "titanic/star_control/surface_fader_base.h" + +namespace Titanic { + +class CSurfaceFader: public CSurfaceFaderBase { +private: + byte *_dataP; + bool _fadeIn; +protected: + /** + * Create a faded version of the source surface at the given dest + */ + virtual void copySurface(CSurfaceArea &srcSurface, CSurfaceArea &destSurface); +public: + CSurfaceFader(); + virtual ~CSurfaceFader(); + + /** + * Sets whether a fade in (versus a fade out) should be done + */ + void setFadeIn(bool fadeIn); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SURFACE_SHADER_H */ diff --git a/engines/titanic/star_control/surface_fader_base.cpp b/engines/titanic/star_control/surface_fader_base.cpp new file mode 100644 index 0000000000..dfd7c4ab1d --- /dev/null +++ b/engines/titanic/star_control/surface_fader_base.cpp @@ -0,0 +1,78 @@ +/* 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 "titanic/star_control/surface_fader_base.h" + +namespace Titanic { + +CSurfaceFaderBase::CSurfaceFaderBase() : _index(-1), _count(32), + _videoSurface(nullptr) { +} + +CSurfaceFaderBase::~CSurfaceFaderBase() { + delete _videoSurface; +} + +void CSurfaceFaderBase::reset() { + _index = 0; +} + +bool CSurfaceFaderBase::setupSurface(CScreenManager *screenManager, CVideoSurface *srcSurface) { + int width = srcSurface->getWidth(); + int height = srcSurface->getHeight(); + + if (_videoSurface) { + if (width == _videoSurface->getWidth() && _videoSurface->getHeight()) + // Allocated surface already matches new size + return true; + + // Different sizes, so delete old surface + delete _videoSurface; + } + + _videoSurface = screenManager->createSurface(width, height); + return true; +} + +CVideoSurface *CSurfaceFaderBase::fade(CScreenManager *screenManager, CVideoSurface *srcSurface) { + if (_index == -1 || _index >= _count) + return srcSurface; + + if (!_count && !setupSurface(screenManager, srcSurface)) + return nullptr; + + srcSurface->lock(); + _videoSurface->lock(); + CSurfaceArea srCSurfaceArea(srcSurface); + CSurfaceArea destSurfaceObj(_videoSurface); + + // Copy the surface with fading + copySurface(srCSurfaceArea, destSurfaceObj); + + srcSurface->unlock(); + _videoSurface->unlock(); + + ++_index; + return _videoSurface; +} + +} // End of namespace Titanic diff --git a/engines/titanic/star_control/surface_fader_base.h b/engines/titanic/star_control/surface_fader_base.h new file mode 100644 index 0000000000..463183537b --- /dev/null +++ b/engines/titanic/star_control/surface_fader_base.h @@ -0,0 +1,70 @@ +/* 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 TITANIC_SURFACE_FADER_BASE_H +#define TITANIC_SURFACE_FADER_BASE_H + +#include "titanic/support/video_surface.h" +#include "titanic/support/screen_manager.h" +#include "titanic/star_control/surface_area.h" + +namespace Titanic { + +class CSurfaceFaderBase { +private: + /** + * Sets up an internal surface to match the size of the specified one + */ + bool setupSurface(CScreenManager *screenManager, CVideoSurface *srcSurface); +protected: + /** + * Create a faded version of the source surface at the given dest + */ + virtual void copySurface(CSurfaceArea &srcSurface, CSurfaceArea &destSurface) = 0; +public: + int _index; + int _count; + CVideoSurface *_videoSurface; +public: + CSurfaceFaderBase(); + virtual ~CSurfaceFaderBase(); + + /** + * Reset fading back to the start + */ + virtual void reset(); + + /** + * Creates a faded version of the passed source surface, based on a percentage + * visibility specified by _index of _count + */ + virtual CVideoSurface *fade(CScreenManager *screenManager, CVideoSurface *srcSurface); + + /** + * Returns true if a fade is in progress + */ + bool isActive() const { return _index != -1 && _index < _count; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SURFACE_FADER_BASE_H */ diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp new file mode 100644 index 0000000000..c37bd83616 --- /dev/null +++ b/engines/titanic/support/avi_surface.cpp @@ -0,0 +1,361 @@ +/* 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 "titanic/support/avi_surface.h" +#include "titanic/support/screen_manager.h" +#include "titanic/support/video_surface.h" +#include "common/system.h" +#include "graphics/pixelformat.h" +#include "video/avi_decoder.h" + +namespace Titanic { + +Video::AVIDecoder::AVIVideoTrack &AVIDecoder::getVideoTrack() { + for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++) + if ((*it)->getTrackType() == Track::kTrackTypeVideo) + return *static_cast<AVIVideoTrack *>(*it); + + error("Could not find video track"); +} + +/** + * Track filter for AVIDecoder that filters out any secondary video track + */ +static bool primaryTrackSelect(bool isVideo, int trackCounter) { + return !isVideo || trackCounter == 0; +} + +/** + * Track filter for AVIDecoder that only accepts the secondary video track + * for a video, if present + */ +static bool secondaryTrackSelect(bool isVideo, int trackCounter) { + return isVideo && trackCounter > 0; +} + +AVISurface::AVISurface(const CResourceKey &key) { + _videoSurface = nullptr; + _streamCount = 0; + _movieFrameSurface[0] = _movieFrameSurface[1] = nullptr; + + // Reset current frame. We need to keep track of frames separately from the decoders, + // since it needs to be able to go beyond the frame count or to negative to allow + // correct detection of when range playbacks have finished + _currentFrame = -1; + _isReversed = false; + + // Create a decoder for the audio (if any) and primary video track + _decoders[0] = new AVIDecoder(Audio::Mixer::kPlainSoundType, primaryTrackSelect); + if (!_decoders[0]->loadFile(key.getString())) + error("Could not open video - %s", key.getString().c_str()); + + _streamCount = 1; + + // Create a decoder for any secondary video track + AVIDecoder *decoder2 = new AVIDecoder(Audio::Mixer::kPlainSoundType, secondaryTrackSelect); + if (decoder2->loadFile(key.getString())) { + _decoders[1] = decoder2; + ++_streamCount; + } else { + delete decoder2; + _decoders[1] = nullptr; + } +} + +AVISurface::~AVISurface() { + if (_videoSurface) + _videoSurface->_transBlitFlag = false; + delete _movieFrameSurface[0]; + delete _movieFrameSurface[1]; + delete _decoders[0]; + delete _decoders[1]; +} + +bool AVISurface::play(uint flags, CGameObject *obj) { + if (flags & MOVIE_REVERSE) + return play(_decoders[0]->getFrameCount() - 1, 0, flags, obj); + else + return play(0, _decoders[0]->getFrameCount() - 1, flags, obj); +} + +bool AVISurface::play(int startFrame, int endFrame, uint flags, CGameObject *obj) { + if (flags & MOVIE_STOP_PREVIOUS) + stop(); + + return play(startFrame, endFrame, -1, flags, obj); +} + +bool AVISurface::play(int startFrame, int endFrame, int initialFrame, uint flags, CGameObject *obj) { + CMovieRangeInfo *info = new CMovieRangeInfo(); + info->_startFrame = startFrame; + info->_endFrame = endFrame; + info->_isReversed = endFrame < startFrame; + info->_initialFrame = 0; + info->_isRepeat = flags & MOVIE_REPEAT; + + if (obj) { + CMovieEvent *me = new CMovieEvent(); + me->_type = MET_MOVIE_END; + me->_startFrame = startFrame; + me->_endFrame = endFrame; + me->_initialFrame = 0; + me->_gameObject = obj; + + info->addEvent(me); + } + + _movieRangeInfo.push_back(info); + + if (_movieRangeInfo.size() == 1) { + // First play call, so start the movie playing + setReversed(info->_isReversed); + return startAtFrame(initialFrame); + } else { + return true; + } +} + +void AVISurface::stop() { + _decoders[0]->stop(); + if (_decoders[1]) + _decoders[1]->stop(); + + _movieRangeInfo.destroyContents(); +} + +bool AVISurface::startAtFrame(int frameNumber) { + if (isPlaying()) + // If it's already playing, then don't allow it + return false; + + if (frameNumber == -1) + // Default to starting frame of first movie range + frameNumber = _movieRangeInfo.front()->_startFrame; + + // Get the initial frame + seekToFrame(frameNumber); + renderFrame(); + + // Start the playback + _decoders[0]->start(); + if (_decoders[1]) + _decoders[1]->start(); + + return true; +} + +void AVISurface::seekToFrame(uint frameNumber) { + if ((int)frameNumber != getFrame()) { + _decoders[0]->seekToFrame(frameNumber); + if (_decoders[1]) + _decoders[1]->seekToFrame(frameNumber); + + _currentFrame = (int)frameNumber; + } + + renderFrame(); +} + +void AVISurface::setReversed(bool isReversed) { + _decoders[0]->setReverse(isReversed); + if (_decoders[1]) + _decoders[1]->setReverse(isReversed); + + _isReversed = isReversed; +} + +bool AVISurface::handleEvents(CMovieEventList &events) { + if (!isPlaying()) + return true; + + CMovieRangeInfo *info = _movieRangeInfo.front(); + _currentFrame += _isReversed ? -1 : 1; + + int newFrame = _currentFrame; + if ((info->_isReversed && newFrame <= info->_endFrame) || + (!info->_isReversed && newFrame >= info->_endFrame)) { + if (info->_isRepeat) { + newFrame = info->_startFrame; + } else { + info->getMovieEnd(events); + _movieRangeInfo.remove(info); + delete info; + + if (_movieRangeInfo.empty()) { + // NO more ranges, so stop playback + stop(); + } else { + // Not empty, so move onto new first one + info = _movieRangeInfo.front(); + newFrame = info->_startFrame; + } + } + } + + if (isPlaying()) { + if (newFrame != getFrame()) { + // The frame has been changed, so move to new position + setReversed(info->_isReversed); + seekToFrame(newFrame); + } + + // Get any events for the given position + info->getMovieFrame(events, newFrame); + return renderFrame(); + } else { + return false; + } +} + +void AVISurface::setVideoSurface(CVideoSurface *surface) { + _videoSurface = surface; + + // Handling for secondary video stream + if (_decoders[1]) { + const Common::String &streamName = _decoders[1]->getVideoTrack().getName(); + + if (streamName == "mask0") { + _videoSurface->_transparencyMode = TRANS_MASK0; + } else if (streamName == "mask255") { + _videoSurface->_transparencyMode = TRANS_MASK255; + } else if (streamName == "alpha0") { + _videoSurface->_transparencyMode = TRANS_ALPHA0; + } else if (streamName == "alpha255") { + _videoSurface->_transparencyMode = TRANS_ALPHA255; + } + } + + setupDecompressor(); +} + +void AVISurface::setupDecompressor() { + for (int idx = 0; idx < 2; ++idx) { + if (!_decoders[idx]) + continue; + AVIDecoder &decoder = *_decoders[idx]; + + // Setup frame surface + _movieFrameSurface[idx] = new Graphics::ManagedSurface(decoder.getWidth(), decoder.getHeight(), + g_system->getScreenFormat()); + + // TODO: See whether this simplified form of original works + if (idx == 1) + _videoSurface->_transBlitFlag = true; + } +} + +uint AVISurface::getWidth() const { + return _decoders[0]->getWidth(); +} + +uint AVISurface::getHeight() const { + return _decoders[0]->getHeight(); +} + +void AVISurface::setFrame(int frameNumber) { + // If playback was in process, stop it + if (isPlaying()) + stop(); + + // Ensure the frame number is valid + if (frameNumber >= (int)_decoders[0]->getFrameCount()) + frameNumber = _decoders[0]->getFrameCount() - 1; + + seekToFrame(frameNumber); + renderFrame(); +} + +bool AVISurface::isNextFrame() const { + return _decoders[0]->getTimeToNextFrame() == 0; +} + +bool AVISurface::renderFrame() { + // Check there's a frame ready for display + if (!_decoders[0]->needsUpdate()) + return false; + + // Decode each decoder's video stream into the appropriate surface + for (int idx = 0; idx < _streamCount; ++idx) { + const Graphics::Surface *frame = _decoders[idx]->decodeNextFrame(); + + if (_movieFrameSurface[idx]->format == frame->format) { + _movieFrameSurface[idx]->blitFrom(*frame); + } else { + // Format mis-match, so we need to convert the frame + Graphics::Surface *s = frame->convertTo(_movieFrameSurface[idx]->format, + _decoders[idx]->getPalette()); + _movieFrameSurface[idx]->blitFrom(*s); + s->free(); + delete s; + } + } + + // Blit the primary video frame onto the main overall surface + _videoSurface->lock(); + _videoSurface->getRawSurface()->blitFrom(*_movieFrameSurface[0]); + _videoSurface->unlock(); + + return false; +} + +bool AVISurface::addEvent(int frameNumber, CGameObject *obj) { + if (!_movieRangeInfo.empty()) { + CMovieRangeInfo *tail = _movieRangeInfo.back(); + if (frameNumber == -1) + frameNumber = tail->_startFrame; + + CMovieEvent *me = new CMovieEvent(); + me->_type = MET_FRAME; + me->_startFrame = 0; + me->_endFrame = 0; + me->_initialFrame = frameNumber; + me->_gameObject = obj; + tail->addEvent(me); + + return _movieRangeInfo.size() == 1 && frameNumber == getFrame(); + } + + return false; +} + +void AVISurface::setFrameRate(double rate) { + _decoders[0]->setRate(Common::Rational(rate)); + if (_decoders[1]) + _decoders[1]->setRate(Common::Rational(rate)); +} + +Graphics::ManagedSurface *AVISurface::getSecondarySurface() { + return _streamCount <= 1 ? nullptr : _movieFrameSurface[1]; +} + +Graphics::ManagedSurface *AVISurface::duplicateSecondaryFrame() const { + if (_streamCount <= 1) { + return nullptr; + } else { + Graphics::ManagedSurface *dest = new Graphics::ManagedSurface(_movieFrameSurface[1]->w, + _movieFrameSurface[1]->h, _movieFrameSurface[1]->format); + dest->blitFrom(*_movieFrameSurface[1]); + return dest; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h new file mode 100644 index 0000000000..d21182bca9 --- /dev/null +++ b/engines/titanic/support/avi_surface.h @@ -0,0 +1,183 @@ +/* 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 TITANIC_AVI_SURFACE_H +#define TITANIC_AVI_SURFACE_H + +#include "video/avi_decoder.h" +#include "graphics/managed_surface.h" +#include "titanic/core/resource_key.h" +#include "titanic/support/movie_range_info.h" + +namespace Titanic { + +class CSoundManager; +class CVideoSurface; + +enum MovieFlag { + MOVIE_REPEAT = 1, MOVIE_STOP_PREVIOUS = 2, MOVIE_NOTIFY_OBJECT = 4, + MOVIE_REVERSE = 8, MOVIE_GAMESTATE = 0x10 +}; + +class AVIDecoder : public Video::AVIDecoder { +public: + AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType, SelectTrackFn trackFn = nullptr) : + Video::AVIDecoder(soundType, trackFn) {} + AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType, + SelectTrackFn trackFn = nullptr) : Video::AVIDecoder(frameRateOverride, soundType, trackFn) {} + + Video::AVIDecoder::AVIVideoTrack &getVideoTrack(); +}; + +class AVISurface { +private: + AVIDecoder *_decoders[2]; + CVideoSurface *_videoSurface; + CMovieRangeInfoList _movieRangeInfo; + int _streamCount; + Graphics::ManagedSurface *_movieFrameSurface[2]; + bool _isReversed; + int _currentFrame; +private: + /** + * Render a frame to the video surface + */ + bool renderFrame(); + + /** + * Sets up for video decompression + */ + void setupDecompressor(); +protected: + /** + * Start playback at the specified frame + */ + bool startAtFrame(int frameNumber); + + /** + * Sets whether the movie is playing in reverse + */ + void setReversed(bool isReversed); + + /** + * Seeks to a given frame number in the video + */ + virtual void seekToFrame(uint frameNumber); +public: + CSoundManager *_soundManager; + bool _hasAudio; + double _frameRate; +public: + AVISurface(const CResourceKey &key); + virtual ~AVISurface(); + + /** + * Start playing the loaded AVI video + */ + virtual bool play(uint flags, CGameObject *obj); + + /** + * Start playing the loaded AVI video + */ + virtual bool play(int startFrame, int endFrame, uint flags, CGameObject *obj); + + /** + * Start playing the loaded AVI video + */ + virtual bool play(int startFrame, int endFrame, int initialFrame, uint flags, CGameObject *obj); + + /** + * Stop the currently playing video + */ + virtual void stop(); + + /** + * Return true if a video is currently playing + */ + virtual bool isPlaying() const { return _decoders[0]->isPlaying(); } + + /** + * Handle any movie events relevent for the frame + */ + virtual bool handleEvents(CMovieEventList &events); + + /** + * Set the video surface the AVI Surface will render on + */ + void setVideoSurface(CVideoSurface *surface); + + /** + * Get the width of the video + */ + uint getWidth() const; + + /** + * Get the height of the video + */ + uint getHeight() const; + + /** + * Set the current frame + */ + void setFrame(int frameNumber); + + /** + * Gets the current frame + */ + int getFrame() const { return _currentFrame; } + + /** + * Add a movie event + */ + bool addEvent(int frameNumber, CGameObject *obj); + + /** + * Set the frame rate + */ + void setFrameRate(double rate); + + /** + * Returns the surface for the secondary video track frame, if present + */ + Graphics::ManagedSurface *getSecondarySurface(); + + /** + * Get a reference to the movie range info list + */ + const CMovieRangeInfoList *getMovieRangeInfo() const { + return &_movieRangeInfo; + } + + /** + * Duplicates the secondary frame, if the movie has a second video track + */ + Graphics::ManagedSurface *duplicateSecondaryFrame() const; + + /** + * Returns true if it's time for the next + */ + bool isNextFrame() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_AVI_SURFACE_H */ diff --git a/engines/titanic/support/credit_text.cpp b/engines/titanic/support/credit_text.cpp new file mode 100644 index 0000000000..0e9715aaa6 --- /dev/null +++ b/engines/titanic/support/credit_text.cpp @@ -0,0 +1,153 @@ +/* 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 "titanic/support/credit_text.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CCreditText::CCreditText() : _screenManagerP(nullptr), _field14(0), + _ticks(0), _fontHeight(1), _objectP(nullptr), _totalHeight(0), + _field40(0), _field44(0), _field48(0), _field4C(0), _field50(0), + _field54(0), _field58(0), _field5C(0) { +} + +void CCreditText::clear() { + _groups.destroyContents(); + _objectP = nullptr; +} + +void CCreditText::load(CGameObject *obj, CScreenManager *screenManager, + const Rect &rect, int v) { + _objectP = obj; + _screenManagerP = screenManager; + _field14 = v; + + setup(); + + _ticks = g_vm->_events->getTicksCount(); + _field40 = 0; + _field44 = 0xFF; + _field48 = 0xFF; + _field4C = 0xFF; + _field50 = 0; + _field54 = 0; + _field58 = 0; + _field5C = 0; +} + +void CCreditText::setup() { + Common::SeekableReadStream *stream = g_vm->_filesManager->getResource( + CString::format("TEXT/155")); + int oldFontNumber = _screenManagerP->setFontNumber(3); + _fontHeight = _screenManagerP->getFontHeight(); + + while (stream->pos() < stream->size()) { + // Read in the line + CString srcLine = readLine(stream); + + // Create a new group and line within it + CCreditLineGroup *group = new CCreditLineGroup(); + CCreditLine *line = new CCreditLine(srcLine, + _screenManagerP->stringWidth(srcLine)); + group->_lines.push_back(line); + + // Loop to add more lines to the group + bool hasDots = false; + while (stream->pos() < stream->size()) { + srcLine = readLine(stream); + if (srcLine.empty()) + break; + + line = new CCreditLine(srcLine, + _screenManagerP->stringWidth(srcLine)); + group->_lines.push_back(line); + + if (srcLine.contains("....")) + hasDots = true; + } + + _groups.push_back(group); + } + + _groupIt = _groups.begin(); + _lineIt = (*_groupIt)->_lines.begin(); + _totalHeight = _objectP->getBounds().height() + _fontHeight * 2; +} + +CString CCreditText::readLine(Common::SeekableReadStream *stream) { + CString line; + char c = stream->readByte(); + + while (c != '\r' && c != '\n' && c != '\0') { + line += c; + + if (stream->pos() == stream->size()) + break; + c = stream->readByte(); + } + + if (c == '\r') { + // Read following '\n' + stream->readByte(); + } + + return line; +} + +void CCreditText::handleDots(CCreditLineGroup *group) { + uint maxWidth = 0; + CCreditLines::iterator second = group->_lines.begin(); + ++second; + + // Figure out the maximum width of secondary lines + for (CCreditLines::iterator i = second; i != group->_lines.end(); ++i) + maxWidth = MAX(maxWidth, (*i)->_lineWidth); + + int charWidth = _screenManagerP->stringWidth("."); + + // Process the secondary lines + for (CCreditLines::iterator i = second; i != group->_lines.end(); ++i) { + CCreditLine *line = *i; + if (line->_lineWidth >= maxWidth) + continue; + + int dotsCount = (maxWidth + charWidth / 2 - line->_lineWidth) / charWidth; + int dotIndex = line->_line.indexOf("...."); + + if (dotIndex > 0) { + CString leftStr = line->_line.left(dotIndex); + CString dotsStr('.', dotsCount); + CString rightStr = line->_line.right(dotIndex); + + line->_line = CString::format("%s%s%s", leftStr.c_str(), + dotsStr.c_str(), rightStr.c_str()); + line->_lineWidth = maxWidth; + } + } +} + +bool CCreditText::draw() { + return false; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/credit_text.h b/engines/titanic/support/credit_text.h new file mode 100644 index 0000000000..ec8fc22cda --- /dev/null +++ b/engines/titanic/support/credit_text.h @@ -0,0 +1,106 @@ +/* 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 TITANIC_CREDIT_TEXT_H +#define TITANIC_CREDIT_TEXT_H + +#include "titanic/core/list.h" + +namespace Titanic { + +class CGameObject; +class CScreenManager; + +class CCreditLine : public ListItem { +public: + CString _line; + uint _lineWidth; +public: + CCreditLine() : _lineWidth(0) {} + CCreditLine(const CString &line, uint lineWidth) : _line(line), _lineWidth(lineWidth) {} +}; +typedef List<CCreditLine> CCreditLines; + +class CCreditLineGroup : public ListItem { +public: + CCreditLines _lines; +}; +typedef List<CCreditLineGroup> CCreditLineGroups; + +class CCreditText { +private: + /** + * Sets up needed data + */ + void setup(); + + /** + * Read in a text line from the passed stream + */ + CString readLine(Common::SeekableReadStream *stream); + + /** + * Handles a group where the .... sequence was encountered + */ + void handleDots(CCreditLineGroup *group); +public: + CScreenManager *_screenManagerP; + Rect _rect; + int _field14; + CCreditLineGroups _groups; + uint _ticks; + uint _fontHeight; + CGameObject *_objectP; + CCreditLineGroups::iterator _groupIt; + CCreditLines::iterator _lineIt; + uint _totalHeight; + int _field40; + int _field44; + int _field48; + int _field4C; + int _field50; + int _field54; + int _field58; + int _field5C; +public: + CCreditText(); + + /** + * Clears the object + */ + void clear(); + + /** + * Sets the game object this override is associated with + */ + void load(CGameObject *obj, CScreenManager *screenManager, + const Rect &rect, int v = 0); + + /** + * Draw the item + */ + bool draw(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CREDIT_TEXT_H */ diff --git a/engines/titanic/support/direct_draw.cpp b/engines/titanic/support/direct_draw.cpp new file mode 100644 index 0000000000..5ddb25bec9 --- /dev/null +++ b/engines/titanic/support/direct_draw.cpp @@ -0,0 +1,109 @@ +/* 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/debug.h" +#include "engines/util.h" +#include "graphics/pixelformat.h" +#include "titanic/titanic.h" +#include "titanic/support/direct_draw.h" + +namespace Titanic { + +DirectDraw::DirectDraw(TitanicEngine *vm) : _vm(vm), + _windowed(false), _fieldC(0), _width(0), _height(0), + _bpp(0), _numBackSurfaces(0), _field24(0) { +} + +void DirectDraw::setDisplayMode(int width, int height, int bpp, int refreshRate) { + debugC(ERROR_BASIC, kDebugGraphics, "DirectDraw::SetDisplayMode (%d x %d), %d bpp", + width, height, bpp); + assert(bpp == 16); + + Graphics::PixelFormat pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); + initGraphics(width, height, true, &pixelFormat); +} + +void DirectDraw::diagnostics() { + debugC(ERROR_BASIC, kDebugGraphics, "Running DirectDraw Diagnostic..."); +} + +DirectDrawSurface *DirectDraw::createSurfaceFromDesc(const DDSurfaceDesc &desc) { + DirectDrawSurface *surface = new DirectDrawSurface(); + surface->create(desc._w, desc._h); + + return surface; +} + +/*------------------------------------------------------------------------*/ + +DirectDrawManager::DirectDrawManager(TitanicEngine *vm, bool windowed) : _directDraw(vm) { + _mainSurface = nullptr; + _backSurfaces[0] = _backSurfaces[1] = nullptr; + _directDraw._windowed = windowed; +} + +void DirectDrawManager::initVideo(int width, int height, int bpp, int numBackSurfaces) { + debugC(ERROR_BASIC, kDebugGraphics, "Initialising video surfaces"); + _directDraw._width = width; + _directDraw._numBackSurfaces = numBackSurfaces; + _directDraw._height = height; + _directDraw._bpp = bpp; + + if (_directDraw._windowed) { + initWindowed(); + } else { + initFullScreen(); + } +} + +void DirectDrawManager::setResolution() { + // TODO +} + +void DirectDrawManager::proc2() { + +} + +void DirectDrawManager::proc3() { + +} + +void DirectDrawManager::initFullScreen() { + debugC(ERROR_BASIC, kDebugGraphics, "Creating surfaces"); + _directDraw.setDisplayMode(_directDraw._width, _directDraw._height, + _directDraw._bpp, 0); + + _mainSurface = new DirectDrawSurface(); + _mainSurface->create(g_vm->_screen); + _backSurfaces[0] = new DirectDrawSurface(); + _backSurfaces[0]->create(_directDraw._width, _directDraw._height); +} + +DirectDrawSurface *DirectDrawManager::createSurface(int w, int h, int surfaceNum) { + if (surfaceNum) + return nullptr; + + assert(_mainSurface); + return _directDraw.createSurfaceFromDesc(DDSurfaceDesc(w, h)); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/direct_draw.h b/engines/titanic/support/direct_draw.h new file mode 100644 index 0000000000..85c344c600 --- /dev/null +++ b/engines/titanic/support/direct_draw.h @@ -0,0 +1,105 @@ +/* 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 TITANIC_DIRECT_DRAW_H +#define TITANIC_DIRECT_DRAW_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "titanic/support/direct_draw_surface.h" + +namespace Titanic { + +class TitanicEngine; + +class DirectDraw { +private: + TitanicEngine *_vm; +public: + bool _windowed; + int _fieldC; + int _width; + int _height; + int _bpp; + int _numBackSurfaces; + int _field24; +public: + DirectDraw(TitanicEngine *vm); + + /** + * Sets a new display mode + */ + void setDisplayMode(int width, int height, int bpp, int refreshRate); + + /** + * Logs diagnostic information + */ + void diagnostics(); + + /** + * Create a surface from a passed description record + */ + DirectDrawSurface *createSurfaceFromDesc(const DDSurfaceDesc &desc); +}; + +class DirectDrawManager { +public: + DirectDraw _directDraw; + DirectDrawSurface *_mainSurface; + DirectDrawSurface *_backSurfaces[2]; +public: + DirectDrawManager(TitanicEngine *vm, bool windowed); + + /** + * Initializes video surfaces + * @param width Screen width + * @param height Screen height + * @param bpp Bits per pixel + * @param numBackSurfaces Number of back surfaces + */ + void initVideo(int width, int height, int bpp, int numBackSurfaces); + + void setResolution(); + + void proc2(); + + void proc3(); + + /** + * Initializes the surfaces in windowed mode + */ + void initWindowed() { initFullScreen(); } + + /** + * Initializes the surfaces for the screen + */ + void initFullScreen(); + + /** + * Create a surface + */ + DirectDrawSurface *createSurface(int w, int h, int surfaceNum); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DIRECT_DRAW_H */ diff --git a/engines/titanic/support/direct_draw_surface.cpp b/engines/titanic/support/direct_draw_surface.cpp new file mode 100644 index 0000000000..9ebda15b0e --- /dev/null +++ b/engines/titanic/support/direct_draw_surface.cpp @@ -0,0 +1,100 @@ +/* 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 "titanic/support/direct_draw_surface.h" + +namespace Titanic { + +DirectDrawSurface::DirectDrawSurface() : _surface(nullptr), + _disposeAfterUse(DisposeAfterUse::YES) { +} + +DirectDrawSurface::~DirectDrawSurface() { + free(); +} + +void DirectDrawSurface::create(Graphics::ManagedSurface *surface) { + free(); + _surface = surface; + _disposeAfterUse = DisposeAfterUse::NO; +} + +void DirectDrawSurface::create(int w, int h) { + Graphics::PixelFormat pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); + _surface = new Graphics::ManagedSurface(w, h, pixelFormat); + _disposeAfterUse = DisposeAfterUse::YES; +} + +void DirectDrawSurface::free() { + if (_disposeAfterUse == DisposeAfterUse::YES) + delete _surface; + _surface = nullptr; + _disposeAfterUse = DisposeAfterUse::NO; +} + +Graphics::ManagedSurface *DirectDrawSurface::lock(const Rect *bounds, int flags) { + assert(!_surface->empty()); + return _surface; +} + +void DirectDrawSurface::unlock() { + assert(_surface->w != 0 && _surface->h != 0); +} + +void DirectDrawSurface::fill(const Rect *bounds, uint32 color) { + Rect tempBounds; + + assert(_surface); + if (bounds) { + // Bounds are provided, clip them to the bounds of this surface + tempBounds = *bounds; + tempBounds.clip(Rect(0, 0, _surface->w, _surface->h)); + } else { + // No bounds provided, so use the entire surface + tempBounds = Rect(0, 0, _surface->w, _surface->h); + } + + // Fill the area + _surface->fillRect(tempBounds, color); +} + +void DirectDrawSurface::fillRect(Rect *rect, byte r, byte g, byte b) { + uint color = _surface->format.RGBToColor(r, g, b); + Rect tempRect = rect ? *rect : Rect(0, 0, getWidth(), getHeight()); + + _surface->fillRect(tempRect, color); +} + +void DirectDrawSurface::blit(const Rect &destRect, DirectDrawSurface *srcSurface, Rect &srcRect) { + assert(srcSurface); + if (!destRect.isEmpty()) + _surface->transBlitFrom(*srcSurface->_surface, srcRect, destRect, (uint)-1); +} + +void DirectDrawSurface::blit(const Point &destPos, DirectDrawSurface *srcSurface, Rect *bounds) { + if (bounds) + _surface->blitFrom(*srcSurface->_surface, *bounds, destPos); + else + _surface->blitFrom(*srcSurface->_surface, destPos); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/direct_draw_surface.h b/engines/titanic/support/direct_draw_surface.h new file mode 100644 index 0000000000..af19e369d2 --- /dev/null +++ b/engines/titanic/support/direct_draw_surface.h @@ -0,0 +1,126 @@ +/* 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 TITANIC_DIRECT_DRAW_SURFACE_H +#define TITANIC_DIRECT_DRAW_SURFACE_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "graphics/managed_surface.h" +#include "titanic/support/rect.h" + +namespace Titanic { + +class TitanicEngine; + +struct DDSurfaceDesc { + int _w; + int _h; + int _flags; + int _caps; + + DDSurfaceDesc(int w, int h) : _w(w), _h(h), _flags(0x1006), _caps(64) {} +}; + +class DirectDrawSurface { +private: + Graphics::ManagedSurface *_surface; + DisposeAfterUse::Flag _disposeAfterUse; +public: + DirectDrawSurface(); + ~DirectDrawSurface(); + + /** + * Create a surface + */ + void create(int w, int h); + + /** + * Create a surface based on a passed surface + */ + void create(Graphics::ManagedSurface *surface); + + /** + * Frees the surface + */ + void free(); + + /** + * Return the size of the surface in ytes + */ + int getSize() const { return _surface->pitch * _surface->h; } + + /** + * Return the surface width + */ + int getWidth() const { return _surface->w; } + + /** + * Return the surface width + */ + int getHeight() const { return _surface->h; } + + /** + * Return the surface pitch + */ + int getPitch() const { return _surface->pitch; } + + /** + * Return the surface's format + */ + const Graphics::PixelFormat &getFormat() { return _surface->format; } + + /** + * Lock the surface for access + */ + Graphics::ManagedSurface *lock(const Rect *bounds, int flags); + + /** + * Unlocks the surface at the end of direct accesses + */ + void unlock(); + + /** + * Fills an area of the surfae with the specified color. If no bounds are passed, + * then the entire surface is filled + */ + void fill(const Rect *bounds, uint32 color); + + /** + * Fill an area with a specific color + */ + void fillRect(Rect *rect, byte r, byte g, byte b); + + /** + * Copy data from a source surfcae into this one + */ + void blit(const Rect &destRect, DirectDrawSurface *srcSurface, Rect &srcRect); + + /** + * Copy data from a source surfcae into this one + */ + void blit(const Point &destPos, DirectDrawSurface *srcSurface, Rect *bounds); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DIRECT_DRAW_SURFACE_H */ diff --git a/engines/titanic/support/exe_resources.cpp b/engines/titanic/support/exe_resources.cpp new file mode 100644 index 0000000000..522e92f718 --- /dev/null +++ b/engines/titanic/support/exe_resources.cpp @@ -0,0 +1,37 @@ +/* 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 "titanic/support/exe_resources.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CExeResources::CExeResources() : _owner(nullptr), _field4(0), _field8(0), + _fieldC(0), _field10(0), _field14(0), _field18(0) { +} + +void CExeResources::reset(CScriptHandler *owner, int val1, int val2) { + _owner = owner; + _field18 = val2; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/exe_resources.h b/engines/titanic/support/exe_resources.h new file mode 100644 index 0000000000..993c34db97 --- /dev/null +++ b/engines/titanic/support/exe_resources.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_EXE_RESOURCES_H +#define TITANIC_EXE_RESOURCES_H + +namespace Titanic { + +class CScriptHandler; + +enum FileHandle { HANDLE_STDIN = 0, HANDLE_STDOUT = 1, HANDLE_STDERR = 2 }; + +class CExeResources { +public: + CScriptHandler *_owner; + int _field4; + int _field8; + int _fieldC; + int _field10; + int _field14; + int _field18; +public: + CExeResources(); + + void reset(CScriptHandler *owner, int val1, int val2); + + bool is18Equals(int val) const { return _field18 == val; } + int get18() const { return _field18; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EXE_RESOURCES_H */ diff --git a/engines/titanic/support/files_manager.cpp b/engines/titanic/support/files_manager.cpp new file mode 100644 index 0000000000..04928b96d6 --- /dev/null +++ b/engines/titanic/support/files_manager.cpp @@ -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. + * + */ + +#include "common/file.h" +#include "titanic/support/files_manager.h" +#include "titanic/game_manager.h" + +namespace Titanic { + +CFilesManager::CFilesManager() : _gameManager(nullptr), _assetsPath("Assets"), + _field0(0), _drive(-1), _field18(0), _field1C(0), _field3C(0) { + loadResourceIndex(); +} + +CFilesManager::~CFilesManager() { + _datFile.close(); +} + +void CFilesManager::loadResourceIndex() { + if (!_datFile.open("titanic.dat")) + error("Could not find titanic.dat data file"); + + uint headerId = _datFile.readUint32BE(); + uint version = _datFile.readUint16LE(); + if (headerId != MKTAG('S', 'V', 'T', 'N') || version < 1) + error("Invalid data file"); + + // Read in entries + uint offset, size; + char c; + Common::String resourceName; + for (;;) { + offset = _datFile.readUint32LE(); + size = _datFile.readUint32LE(); + if (size == 0) + break; + + Common::String resName; + while ((c = _datFile.readByte()) != '\0') + resName += c; + + _resources[resName] = ResourceEntry(offset, size); + } +} + +bool CFilesManager::fileExists(const CString &name) { + Common::File f; + return f.exists(name); +} + +bool CFilesManager::scanForFile(const CString &name) { + if (name.empty()) + return false; + + CString filename = name; + filename.toLowercase(); + + if (filename[0] == 'y' || filename[0] == 'z') + return true; + else if (filename[0] < 'a' || filename[0] > 'c') + return false; + + CString fname = filename; + int idx = fname.indexOf('#'); + if (idx >= 0) { + fname = fname.left(idx); + fname += ".st"; + } + + // Return true if the file exists + if (fileExists(fname)) + return true; + + // Couldn't find file. Start by calling the game manager's viewChange + // method, which handles all active scene objects freeing their resources + if (_gameManager) + _gameManager->viewChange(); + + return false; +} + +void CFilesManager::loadDrive() { + assert(_drive == -1); + resetView(); +} + +void CFilesManager::debug(CScreenManager *screenManager) { + warning("TODO: CFilesManager::debug"); +} + +void CFilesManager::resetView() { + if (_gameManager) { + _gameManager->_gameState.setMode(GSMODE_INTERACTIVE); + _gameManager->initBounds(); + } +} + +void CFilesManager::fn4(const CString &name) { + warning("TODO: CFilesManager::fn4"); +} + +void CFilesManager::preload(const CString &name) { + // We don't currently do any preloading of resources +} + +Common::SeekableReadStream *CFilesManager::getResource(const CString &str) { + ResourceEntry resEntry = _resources[str]; + _datFile.seek(resEntry._offset); + + return _datFile.readStream(resEntry._size); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/files_manager.h b/engines/titanic/support/files_manager.h new file mode 100644 index 0000000000..ec0c7fc008 --- /dev/null +++ b/engines/titanic/support/files_manager.h @@ -0,0 +1,109 @@ +/* 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 TITANIC_FILES_MANAGER_H +#define TITANIC_FILES_MANAGER_H + +#include "common/hashmap.h" +#include "titanic/core/list.h" +#include "titanic/support/screen_manager.h" + +namespace Titanic { + +class CGameManager; + +class CFilesManagerList : public List<ListItem> { +}; + +class CFilesManager { + struct ResourceEntry { + uint _offset; + uint _size; + + ResourceEntry() : _offset(0), _size(0) {} + ResourceEntry(uint offset, uint size) : _offset(offset), _size(size) {} + }; + typedef Common::HashMap<Common::String, ResourceEntry> ResourceHash; +private: + CGameManager *_gameManager; + Common::File _datFile; + ResourceHash _resources; + CFilesManagerList _list; + CString _string1; + CString _string2; + int _field0; + int _drive; + int _field18; + int _field1C; + int _field3C; + const CString _assetsPath; +private: + void loadResourceIndex(); +public: + CFilesManager(); + ~CFilesManager(); + + /** + * Sets the game manager + */ + void setGameManager(CGameManager *gameManager) { + _gameManager = gameManager; + } + + /** + * Returns true if a file of the given name exists + */ + static bool fileExists(const CString &name); + + /** + * Scans for a file with a matching name + */ + bool scanForFile(const CString &name); + + /** + * Handles displaying a load drive view if necessary + */ + void loadDrive(); + + void debug(CScreenManager *screenManager); + + /** + * Resets the view being displayed + */ + void resetView(); + + void fn4(const CString &name); + + /** + * Preloads and caches a file for access shortly + */ + void preload(const CString &name); + + /** + * Get a resource from the executable + */ + Common::SeekableReadStream *getResource(const CString &str); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FILES_MANAGER_H */ diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp new file mode 100644 index 0000000000..69c0efe504 --- /dev/null +++ b/engines/titanic/support/font.cpp @@ -0,0 +1,281 @@ +/* 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/textconsole.h" +#include "titanic/support/font.h" +#include "titanic/support/files_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +STFont::STFont() { + _dataPtr = nullptr; + _dataSize = 0; + _fontHeight = 0; + _dataWidth = 0; + _fontR = _fontG = _fontB = 0; +} + +STFont::~STFont() { + delete[] _dataPtr; +} + +void STFont::load(int fontNumber) { + assert(!_dataPtr); + Common::SeekableReadStream *stream = g_vm->_filesManager->getResource( + CString::format("STFONT/%d", fontNumber)); + if (!stream) + error("Could not locate the specified font"); + + _fontHeight = stream->readUint32LE(); + _dataWidth = stream->readUint32LE(); + for (uint idx = 0; idx < 256; ++idx) + _chars[idx]._width = stream->readUint32LE(); + for (uint idx = 0; idx < 256; ++idx) + _chars[idx]._offset = stream->readUint32LE(); + + _dataSize = stream->readUint32LE(); + _dataPtr = new byte[_dataSize]; + stream->read(_dataPtr, _dataSize); + + delete stream; +} + +void STFont::setColor(byte r, byte g, byte b) { + _fontR = r; + _fontG = g; + _fontB = b; +} + +uint16 STFont::getColor() const { + return g_system->getScreenFormat().RGBToColor(_fontR, _fontG, _fontB); +} + +int STFont::getTextBounds(const CString &str, int maxWidth, Point *sizeOut) const { + Point textSize; + + // Reset output dimensions if provided + if (sizeOut) + *sizeOut = Point(0, 0); + + if (_fontHeight == 0 || !_dataPtr) + // No font, so return immediately + return 0; + + // Loop through the characters of the string + if (!str.empty()) { + for (const char *strP = str.c_str(); *strP; ++strP) { + if (*strP == TEXTCMD_NPC) { + strP += 3; + } else if (*strP == TEXTCMD_SET_COLOR) { + strP += 4; + } else { + if (*strP == ' ') { + // Check fo rline wrapping + checkLineWrap(textSize, maxWidth, strP); + } + + extendBounds(textSize, *strP, maxWidth); + } + } + } + + if (sizeOut) + *sizeOut = textSize; + + return textSize.y + _fontHeight; +} + +int STFont::stringWidth(const CString &text) const { + if (text.empty()) + return 0; + + const char *srcP = text.c_str(); + int total = 0; + char c; + while ((c = *srcP++)) { + if (c == 26) { + // Skip over command parameter bytes + srcP += 3; + } else if (c == TEXTCMD_SET_COLOR) { + // Skip over command parameter bytes + srcP += 4; + } else if (c != '\n') { + total += _chars[(byte)c]._width; + } + } + + return total; +} + +int STFont::writeString(CVideoSurface *surface, const Rect &rect1, const Rect &destRect, + int yOffset, const CString &str, CTextCursor *textCursor) { + if (!_fontHeight || !_dataPtr) + return -1; + + Point textSize(0, -yOffset); + Rect destBounds = destRect; + destBounds.constrain(rect1); + if (destBounds.isEmpty()) + return -1; + + const char *endP = nullptr; + const char *strEndP = str.c_str() + str.size() - 1; + for (const char *srcP = str.c_str(); *srcP; ++srcP) { + if (*srcP == TEXTCMD_NPC) { + srcP += 3; + } else if (*srcP == TEXTCMD_SET_COLOR) { + // Change the color used for characters + byte r = *++srcP; + byte g = *++srcP; + byte b = *++srcP; + ++srcP; + setColor(r, g, b); + } else { + if (*srcP == ' ') { + // Check fo rline wrapping + checkLineWrap(textSize, rect1.width(), srcP); + if (!*srcP) + return endP - str.c_str(); + } + + if (*srcP != '\n') { + WriteCharacterResult result = writeChar(surface, *srcP, textSize, rect1, &destBounds); + if (result == WC_OUTSIDE_BOTTOM) + return endP - str.c_str(); + else if (result == WC_IN_BOUNDS) + endP = srcP; + } + + if (srcP < strEndP) + extendBounds(textSize, *srcP, rect1.width()); + } + } + + if (textCursor && textCursor->getMode() == -2) { + Point cursorPos(rect1.left + textSize.x, rect1.top + textSize.y); + textCursor->setPos(cursorPos); + } + + return endP ? endP - str.c_str() : 0; +} + +WriteCharacterResult STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt, + const Rect &destRect, const Rect *srcRect) { + if (c == 233) + c = '$'; + + Rect tempRect; + tempRect.left = _chars[c]._offset; + tempRect.right = _chars[c]._offset + _chars[c]._width; + tempRect.top = 0; + tempRect.bottom = _fontHeight; + Point destPos(pt.x + destRect.left, pt.y + destRect.top); + + if (srcRect->isEmpty()) + srcRect = &destRect; + if (destPos.y > srcRect->bottom) + return WC_OUTSIDE_BOTTOM; + + if ((destPos.y + tempRect.height()) > srcRect->bottom) { + tempRect.bottom += tempRect.top - destPos.y; + } + + if (destPos.y < srcRect->top) { + if ((tempRect.height() + destPos.y) < srcRect->top) + return WC_OUTSIDE_TOP; + + tempRect.top += srcRect->top - destPos.y; + destPos.y = srcRect->top; + } + + if (destPos.x < srcRect->left) { + if ((tempRect.width() + destPos.x) < srcRect->left) + return WC_OUTSIDE_LEFT; + + tempRect.left += srcRect->left - destPos.x; + destPos.x = srcRect->left; + } else { + if ((tempRect.width() + destPos.x) > srcRect->right) { + if (destPos.x > srcRect->right) + return WC_OUTSIDE_RIGHT; + + tempRect.right += srcRect->left - destPos.x; + } + } + + copyRect(surface, destPos, tempRect); + return WC_IN_BOUNDS; +} + +void STFont::copyRect(CVideoSurface *surface, const Point &pt, Rect &rect) { + if (surface->lock()) { + uint16 *lineP = surface->getBasePtr(pt.x, pt.y); + uint16 color = getColor(); + + for (int yp = rect.top; yp < rect.bottom; ++yp, lineP += surface->getWidth()) { + uint16 *destP = lineP; + for (int xp = rect.left; xp < rect.right; ++xp, ++destP) { + const byte *srcP = _dataPtr + yp * _dataWidth + xp; + surface->changePixel(destP, &color, *srcP >> 3, true); + } + } + + surface->unlock(); + } +} + +void STFont::extendBounds(Point &textSize, byte c, int maxWidth) const { + textSize.x += _chars[c]._width; + + if (c == '\n' || textSize.x > maxWidth) { + textSize.x = 0; + textSize.y += _fontHeight; + } +} + +void STFont::checkLineWrap(Point &textSize, int maxWidth, const char *&str) const { + bool flag = false; + int totalWidth = 0; + for (const char *srcPtr = str; *srcPtr && *srcPtr != ' '; ++srcPtr) { + if (*srcPtr == ' ' && flag) + break; + + if (*srcPtr == TEXTCMD_NPC) { + srcPtr += 3; + } else if (*srcPtr == TEXTCMD_SET_COLOR) { + srcPtr += 4; + } else { + totalWidth += _chars[(byte)*srcPtr]._width; + flag = true; + } + } + + if ((textSize.x + totalWidth) >= maxWidth && totalWidth < maxWidth) { + // Word wrap + textSize.x = 0; + textSize.y += _fontHeight; + ++str; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h new file mode 100644 index 0000000000..591fb4661c --- /dev/null +++ b/engines/titanic/support/font.h @@ -0,0 +1,123 @@ +/* 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 TITANIC_FONT_H +#define TITANIC_FONT_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "titanic/support/rect.h" +#include "titanic/support/string.h" +#include "titanic/support/text_cursor.h" + +namespace Titanic { + +enum TextCommand { TEXTCMD_NPC = 26, TEXTCMD_SET_COLOR = 27 }; + +enum WriteCharacterResult { + WC_IN_BOUNDS = 0, WC_OUTSIDE_TOP = -1, WC_OUTSIDE_BOTTOM = -2, + WC_OUTSIDE_LEFT = -3, WC_OUTSIDE_RIGHT = -4 +}; + +class CVideoSurface; + +class STFont { + struct CharEntry { + uint _width; + uint _offset; + }; +private: + /** + * Copys a rectangle representing a character in the font data to + * a given destination position in the surface + */ + void copyRect(CVideoSurface *surface, const Common::Point &destPos, + Rect &srcRect); + + /** + * Write a character + */ + WriteCharacterResult writeChar(CVideoSurface *surface, unsigned char c, + const Common::Point &pt, const Rect &destRect, const Rect *srcRect); + + /** + * Extends a passed text area by the space required for + * the given character + */ + void extendBounds(Point &textSize, byte c, int maxWidth) const; + + /** + * Called at spacing between words, checks for line wrapping + */ + void checkLineWrap(Point &textSize, int maxWidth, const char *&str) const; +public: + byte *_dataPtr; + size_t _dataSize; + int _fontHeight; + uint _dataWidth; + CharEntry _chars[256]; + byte _fontR, _fontG, _fontB; +public: + STFont(); + ~STFont(); + + /** + * Load a specified font + */ + void load(int fontNumber); + + /** + * Return the width in pixels of the specified text + */ + int stringWidth(const CString &text) const; + + /** + * Write a string to the specified surface + * @returns The index of the last character that was visible + * with the drawing area + */ + int writeString(CVideoSurface *surface, const Rect &rect1, const Rect &destRect, + int yOffset, const CString &str, CTextCursor *textCursor); + + /** + * Get the text area a string will fit into + * @param str String + * @param maxWidth Maximum width in pixels + * @param sizeOut Optional pointer to output size (width, height) + * @returns Required height + */ + int getTextBounds(const CString &str, int maxWidth, Point *sizeOut) const; + + /** + * Sets the font color + */ + void setColor(byte r, byte g, byte b); + + /** + * Gets the font color + */ + uint16 getColor() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FONT_H */ diff --git a/engines/titanic/support/image.cpp b/engines/titanic/support/image.cpp new file mode 100644 index 0000000000..1e936b6940 --- /dev/null +++ b/engines/titanic/support/image.cpp @@ -0,0 +1,56 @@ +/* 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 "titanic/support/image.h" +#include "titanic/titanic.h" +#include "image/bmp.h" + +namespace Titanic { + +void Image::load(const CString &resName) { + Common::SeekableReadStream *stream = g_vm->_filesManager->getResource(resName); + loadBitmap(*stream); + delete stream; +} + +void Image::loadBitmap(Common::SeekableReadStream &s) { + ::Image::BitmapDecoder decoder; + decoder.loadStream(s); + const Graphics::Surface *src = decoder.getSurface(); + Graphics::PixelFormat scrFormat = g_system->getScreenFormat(); + + if (src->format == scrFormat) { + create(src->w, src->h, scrFormat); + blitFrom(*src); + } else { + // Convert the loaded surface to the screen surface format + const byte *palette = decoder.getPalette(); + Graphics::Surface *surface = src->convertTo(scrFormat, palette); + create(surface->w, surface->h, scrFormat); + blitFrom(*surface); + + surface->free(); + delete surface; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/image.h b/engines/titanic/support/image.h new file mode 100644 index 0000000000..9876f15c40 --- /dev/null +++ b/engines/titanic/support/image.h @@ -0,0 +1,43 @@ +/* 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 TITANIC_IMAGE_H +#define TITANIC_IMAGE_H + +#include "common/stream.h" +#include "graphics/managed_surface.h" +#include "titanic/support/string.h" + +namespace Titanic { + +class Image : public Graphics::ManagedSurface { +private: + void loadBitmap(Common::SeekableReadStream &s); +public: + virtual ~Image() {} + + void load(const CString &resName); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_IMAGE_H */ diff --git a/engines/titanic/support/image_decoders.cpp b/engines/titanic/support/image_decoders.cpp new file mode 100644 index 0000000000..495d1d0982 --- /dev/null +++ b/engines/titanic/support/image_decoders.cpp @@ -0,0 +1,81 @@ +/* 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 "titanic/support/image_decoders.h" + +namespace Titanic { + +void CJPEGDecode::decode(OSVideoSurface &surface, const CString &name) { + // Open up the resource + StdCWadFile file; + file.open(name); + + // Use the ScucmmVM deoder to decode it + loadStream(*file.readStream()); + const Graphics::Surface *srcSurf = getSurface(); + + // Resize the surface if necessary + if (!surface.hasSurface() || surface.getWidth() != srcSurf->w + || surface.getHeight() != srcSurf->h) + surface.recreate(srcSurf->w, srcSurf->h); + + // Convert the decoded surface to the correct pixel format, and then copy it over + surface.lock(); + Graphics::Surface *convertedSurface = srcSurf->convertTo(surface._rawSurface->format); + + Common::copy((byte *)convertedSurface->getPixels(), (byte *)convertedSurface->getPixels() + + surface.getPitch() * surface.getHeight(), (byte *)surface._rawSurface->getPixels()); + + convertedSurface->free(); + delete convertedSurface; + surface.unlock(); +} + +/*------------------------------------------------------------------------*/ + +void CTargaDecode::decode(OSVideoSurface &surface, const CString &name) { + // Open up the resource + StdCWadFile file; + file.open(name); + + // Use the ScucmmVM deoder to decode it + loadStream(*file.readStream()); + const Graphics::Surface *srcSurf = getSurface(); + + // Resize the surface if necessary + if (!surface.hasSurface() || surface.getWidth() != srcSurf->w + || surface.getHeight() != srcSurf->h) + surface.recreate(srcSurf->w, srcSurf->h); + + // Convert the decoded surface to the correct pixel format, and then copy it over + surface.lock(); + Graphics::Surface *convertedSurface = srcSurf->convertTo(surface._rawSurface->format); + + Common::copy((byte *)convertedSurface->getPixels(), (byte *)convertedSurface->getPixels() + + surface.getPitch() * surface.getHeight(), (byte *)surface._rawSurface->getPixels()); + + convertedSurface->free(); + delete convertedSurface; + surface.unlock(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/image_decoders.h b/engines/titanic/support/image_decoders.h new file mode 100644 index 0000000000..b824b786a7 --- /dev/null +++ b/engines/titanic/support/image_decoders.h @@ -0,0 +1,52 @@ +/* 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 TITANIC_IMAGE_DECODERS_H +#define TITANIC_IMAGE_DECODERS_H + +#include "image/jpeg.h" +#include "image/tga.h" +#include "titanic/support/string.h" +#include "titanic/support/simple_file.h" +#include "titanic/support/video_surface.h" + +namespace Titanic { + +class CJPEGDecode : public Image::JPEGDecoder { +public: + /** + * Decode the image file onto the passed surface + */ + void decode(OSVideoSurface &surface, const CString &name); +}; + +class CTargaDecode : public Image::TGADecoder { +public: + /** + * Decode the image file onto the passed surface + */ + void decode(OSVideoSurface &surface, const CString &name); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_IMAGE_DECODERS_H */ diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp new file mode 100644 index 0000000000..d6a42823f5 --- /dev/null +++ b/engines/titanic/support/mouse_cursor.cpp @@ -0,0 +1,135 @@ +/* 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/memstream.h" +#include "common/textconsole.h" +#include "graphics/cursorman.h" +#include "titanic/support/mouse_cursor.h" +#include "titanic/support/movie.h" +#include "titanic/support/screen_manager.h" +#include "titanic/titanic.h" +#include "titanic/support/video_surface.h" +#include "titanic/core/resource_key.h" + +namespace Titanic { + +static const int CURSOR_DATA[NUM_CURSORS][4] = { + { 1, 136, 19, 18 }, + { 2, 139, 1, 1 }, + { 3, 140, 32, 1 }, + { 4, 137, 13, 0 }, + { 5, 145, 13, 0 }, + { 6, 144, 13, 22 }, + { 7, 137, 14, 0 }, + { 8, 148, 22, 40 }, + { 9, 136, 19, 18 }, + { 10, 143, 11, 11 }, + { 11, 146, 11, 11 }, + { 12, 136, 19, 18 }, + { 13, 136, 19, 25 }, + { 14, 136, 13, 22 }, + { 15, 138, 20, 28 } +}; + +CMouseCursor::CursorEntry::~CursorEntry() { + delete _videoSurface; + delete _frameSurface; +} + +CMouseCursor::CMouseCursor(CScreenManager *screenManager) : + _screenManager(screenManager), _cursorId(CURSOR_HOURGLASS), + _setCursorCount(0), _fieldE4(0), _fieldE8(0) { + loadCursorImages(); + setCursor(CURSOR_ARROW); +} + +CMouseCursor::~CMouseCursor() { +} + +void CMouseCursor::loadCursorImages() { + const CResourceKey key("ycursors.avi"); + g_vm->_filesManager->fn4(key.getString()); + + // Iterate through getting each cursor + for (int idx = 0; idx < NUM_CURSORS; ++idx) { + assert(CURSOR_DATA[idx][0] == (idx + 1)); + _cursors[idx]._centroid = Common::Point(CURSOR_DATA[idx][2], + CURSOR_DATA[idx][3]); + + // Create the surface + CVideoSurface *surface = _screenManager->createSurface(64, 64); + _cursors[idx]._videoSurface = surface; + + // Open the cursors video and move to the given frame + OSMovie movie(key, surface); + movie.setFrame(idx); + + Graphics::ManagedSurface *frameSurface = movie.duplicateFrame(); + _cursors[idx]._frameSurface = frameSurface; + surface->setMovieFrameSurface(frameSurface); + } +} + +void CMouseCursor::show() { + CursorMan.showMouse(true); +} + +void CMouseCursor::hide() { + CursorMan.showMouse(false); +} + +void CMouseCursor::setCursor(CursorId cursorId) { + ++_setCursorCount; + + if (cursorId != _cursorId) { + CursorEntry &ce = _cursors[cursorId - 1]; + CVideoSurface &surface = *ce._videoSurface; + surface.lock(); + + CursorMan.replaceCursor(surface.getPixels(), surface.getWidth(), surface.getHeight(), + ce._centroid.x, ce._centroid.y, 0, false, &g_vm->_screen->format); + surface.unlock(); + + _cursorId = cursorId; + } +} + +void CMouseCursor::update() { + // No implementation needed +} + +void CMouseCursor::lockE4() { + _fieldE4 = 0; + CScreenManager::_screenManagerPtr->_inputHandler->incLockCount(); +} + +void CMouseCursor::unlockE4() { + _fieldE4 = 1; + _fieldE8 = 0; + CScreenManager::_screenManagerPtr->_inputHandler->decLockCount(); +} + +void CMouseCursor::saveState(int v1, int v2, int v3) { + // TODO +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h new file mode 100644 index 0000000000..7a81ad43fa --- /dev/null +++ b/engines/titanic/support/mouse_cursor.h @@ -0,0 +1,114 @@ +/* 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 TITANIC_MOUSE_CURSOR_H +#define TITANIC_MOUSE_CURSOR_H + +#include "common/scummsys.h" +#include "common/rect.h" +#include "graphics/managed_surface.h" + +namespace Titanic { + +#define NUM_CURSORS 15 + +enum CursorId { + CURSOR_ARROW = 1, + CURSOR_MOVE_LEFT = 2, + CURSOR_MOVE_RIGHT = 3, + CURSOR_MOVE_FORWARD = 4, + CURSOR_MOVE_UP = 5, + CURSOR_MOVE_DOWN1 = 6, + CURSOR_MOVE_FORWARD2 = 7, + CURSOR_HAND = 8, + CURSOR_ACTIVATE = 9, + CURSOR_INVALID = 10, + CURSOR_MAGNIFIER = 11, + CURSOR_IGNORE = 12, + CURSOR_BACKWARDS = 13, + CURSOR_DOWN = 14, + CURSOR_HOURGLASS = 15 +}; + +class CScreenManager; +class CVideoSurface; + +class CMouseCursor { + struct CursorEntry { + CVideoSurface *_videoSurface; + Graphics::ManagedSurface *_frameSurface; + Common::Point _centroid; + + CursorEntry() : _videoSurface(nullptr), _frameSurface(nullptr) {} + ~CursorEntry(); + }; +private: + CScreenManager *_screenManager; + CursorId _cursorId; + CursorEntry _cursors[NUM_CURSORS]; + uint _setCursorCount; + int _fieldE4; + int _fieldE8; + + /** + * Load the images for each cursor + */ + void loadCursorImages(); +public: + CMouseCursor(CScreenManager *screenManager); + ~CMouseCursor(); + + /** + * Make the mouse cursor visible + */ + void show(); + + /** + * Hide the mouse cursor + */ + void hide(); + + /** + * Set the cursor + */ + void setCursor(CursorId cursorId); + + /** + * Updates the mouse cursor + */ + void update(); + + /** + * Returns the number of times the cursor has been set + */ + uint getChangeCount() const { return _setCursorCount; } + + void lockE4(); + void unlockE4(); + + void saveState(int v1, int v2, int v3); +}; + + +} // End of namespace Titanic + +#endif /* TITANIC_MOUSE_CURSOR_H */ diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp new file mode 100644 index 0000000000..3bb9fb88cf --- /dev/null +++ b/engines/titanic/support/movie.cpp @@ -0,0 +1,218 @@ +/* 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 "titanic/support/movie.h" +#include "titanic/support/avi_surface.h" +#include "titanic/sound/sound_manager.h" +#include "titanic/messages/messages.h" +#include "titanic/titanic.h" + +namespace Titanic { + +#define CLIP_WIDTH 600 +#define CLIP_WIDTH_REDUCED (CLIP_WIDTH / 2) +#define CLIP_HEIGHT 340 +#define CLIP_HEIGHT_REDUCED (CLIP_HEIGHT / 2) + +CMovieList *CMovie::_playingMovies; +CVideoSurface *CMovie::_movieSurface; + +CMovie::CMovie() : ListItem(), _handled(false), _hasVideoFrame(false), + _hasAudioTiming(false) { +} + +CMovie::~CMovie() { + removeFromPlayingMovies(); +} + +void CMovie::init() { + _playingMovies = new CMovieList(); + _movieSurface = nullptr; +} + +void CMovie::deinit() { + // Delete each movie in turn + for (CMovieList::iterator i = _playingMovies->begin(); i != _playingMovies->end(); ) { + // We need to increment iterator before deleting movie, + // since the CMovie destructor calls removeFromPlayingMovies + CMovie *movie = *i; + ++i; + delete movie; + } + + delete _playingMovies; + delete _movieSurface; +} + +void CMovie::addToPlayingMovies() { + if (!isActive()) + _playingMovies->push_back(this); +} + +void CMovie::removeFromPlayingMovies() { + _playingMovies->remove(this); +} + +bool CMovie::isActive() const { + return _playingMovies->contains(this); +} + +bool CMovie::hasVideoFrame() { + if (_hasVideoFrame) { + _hasVideoFrame = 0; + return true; + } else { + return false; + } +} + +/*------------------------------------------------------------------------*/ + +OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) : + _aviSurface(name), _videoSurface(surface) { + _field18 = 0; + _field24 = 0; + _field28 = 0; + _field2C = 0; + + surface->resize(_aviSurface.getWidth(), _aviSurface.getHeight()); + _aviSurface.setVideoSurface(surface); +} + +OSMovie::~OSMovie() { +} + +void OSMovie::play(uint flags, CGameObject *obj) { + _aviSurface.play(flags, obj); + + if (_aviSurface.isPlaying()) + movieStarted(); +} + +void OSMovie::play(uint startFrame, uint endFrame, uint flags, CGameObject *obj) { + _aviSurface.play(startFrame, endFrame, flags, obj); + + if (_aviSurface.isPlaying()) + movieStarted(); +} + +void OSMovie::play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) { + _aviSurface.play(startFrame, endFrame, initialFrame, flags, obj); + + if (_aviSurface.isPlaying()) + movieStarted(); +} + +void OSMovie::playClip(const Point &drawPos, uint startFrame, uint endFrame) { + if (!_movieSurface) + _movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340); + + bool widthLess = _videoSurface->getWidth() < 600; + bool heightLess = _videoSurface->getHeight() < 340; + Rect r(drawPos.x, drawPos.y, + drawPos.x + (widthLess ? CLIP_WIDTH_REDUCED : CLIP_WIDTH), + drawPos.y + (heightLess ? CLIP_HEIGHT_REDUCED : CLIP_HEIGHT) + ); + + uint timePerFrame = (uint)(1000.0 / _aviSurface._frameRate); + + for (; endFrame >= startFrame; ++startFrame) { + // Set the frame + _aviSurface.setFrame(startFrame); + + // TODO: See if we need to do anything further here. The original had a bunch + // of calls and using of the _movieSurface; perhaps to allow scaling down + // videos to half-size + if (widthLess || heightLess) + warning("Not properly reducing clip size: %d %d", r.width(), r.height()); + + // Wait for the next frame, unless the user interrupts the clip + if (g_vm->_events->waitForPress(timePerFrame)) + break; + } +} + +void OSMovie::stop() { + _aviSurface.stop(); + removeFromPlayingMovies(); +} + +void OSMovie::addEvent(int frameNumber, CGameObject *obj) { + if (_aviSurface.addEvent(frameNumber, obj)) { + CMovieFrameMsg frameMsg(frameNumber, 0); + frameMsg.execute(obj); + } +} + +void OSMovie::setFrame(uint frameNumber) { + _aviSurface.setFrame(frameNumber); + _videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface()); +} + +bool OSMovie::handleEvents(CMovieEventList &events) { + if (!_aviSurface.isPlaying()) + return false; + if (!_aviSurface.isNextFrame()) + return _aviSurface.isPlaying(); + + // Handle updating the frame + while (_aviSurface.isPlaying() && _aviSurface.isNextFrame()) { + _aviSurface.handleEvents(events); + _videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface()); + } + + // Flag there's a video frame + _hasVideoFrame = true; + + return _aviSurface.isPlaying(); +} + +const CMovieRangeInfoList *OSMovie::getMovieRangeInfo() const { + return _aviSurface.getMovieRangeInfo(); +} + +void OSMovie::setSoundManager(CSoundManager *soundManager) { + _aviSurface._soundManager = soundManager; +} + +int OSMovie::getFrame() const { + return _aviSurface.getFrame(); +} + +void OSMovie::movieStarted() { + //if (_aviSurface._hasAudio) + // _aviSurface._soundManager->movieStarted(); + + // Register the movie in the playing list + addToPlayingMovies(); + _hasVideoFrame = true; +} + +void OSMovie::setFrameRate(double rate) { + _aviSurface.setFrameRate(rate); +} + +Graphics::ManagedSurface *OSMovie::duplicateFrame() const { + return _aviSurface.duplicateSecondaryFrame(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h new file mode 100644 index 0000000000..2d1c264f03 --- /dev/null +++ b/engines/titanic/support/movie.h @@ -0,0 +1,237 @@ +/* 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 TITANIC_MOVIE_H +#define TITANIC_MOVIE_H + +#include "common/list.h" +#include "video/video_decoder.h" +#include "titanic/core/list.h" +#include "titanic/core/resource_key.h" +#include "titanic/support/avi_surface.h" +#include "titanic/support/movie_range_info.h" + +namespace Titanic { + +class CGameObject; +class CMovie; +class CSoundManager; +class CVideoSurface; + +class CMovieList : public List<CMovie> { +public: +}; + +class CMovie : public ListItem { +protected: + /** + * Adds the movie to the list of currently playing movies + */ + void addToPlayingMovies(); +public: + bool _handled; + bool _hasVideoFrame; + bool _hasAudioTiming; +public: + static CMovieList *_playingMovies; + static CVideoSurface *_movieSurface; + + /** + * Initializes statics + */ + static void init(); + + /** + * Deinitializes statics + */ + static void deinit(); +public: + CMovie(); + virtual ~CMovie(); + + /** + * Starts playing the movie + */ + virtual void play(uint flags, CGameObject *obj) = 0; + + /** + * Starts playing the movie + */ + virtual void play(uint startFrame, uint endFrame, uint flags, CGameObject *obj) = 0; + + /** + * Starts playing the movie + */ + virtual void play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) = 0; + + /** + * Plays a sub-section of a movie + */ + virtual void playClip(const Point &drawPos, uint startFrame, uint endFrame) = 0; + + /** + * Stops the movie + */ + virtual void stop() = 0; + + /** + * Add a playback event + */ + virtual void addEvent(int frameNumber, CGameObject *obj) = 0; + + /** + * Set the current frame number + */ + virtual void setFrame(uint frameNumber) = 0; + + /** + * Handle any pending movie events + */ + virtual bool handleEvents(CMovieEventList &events) = 0; + + /** + * Return any movie range info associated with the movie + */ + virtual const CMovieRangeInfoList *getMovieRangeInfo() const = 0; + + /** + * Set the sound manager reference + */ + virtual void setSoundManager(CSoundManager *soundManager) = 0; + + /** + * Get the current movie frame + */ + virtual int getFrame() const = 0; + + /** + * Set the frame rate for the movie + */ + virtual void setFrameRate(double rate) = 0; + + /** + * Creates a duplicate of the movie's frame + */ + virtual Graphics::ManagedSurface *duplicateFrame() const = 0; + + /** + * Removes the movie from the list of currently playing movies + */ + void removeFromPlayingMovies(); + + /** + * Returns true if the movie is currently active + */ + bool isActive() const; + + /** + * Returns true if there's a video frame + */ + bool hasVideoFrame(); +}; + +class OSMovie : public CMovie { +private: + AVISurface _aviSurface; + CVideoSurface *_videoSurface; + int _field18; + int _field24; + int _field28; + int _field2C; +private: + /** + * Called when a movie is started playing + */ + void movieStarted(); +public: + OSMovie(const CResourceKey &name, CVideoSurface *surface); + virtual ~OSMovie(); + + /** + * Starts playing the movie + */ + virtual void play(uint flags, CGameObject *obj); + + /** + * Starts playing the movie + */ + virtual void play(uint startFrame, uint endFrame, uint flags, CGameObject *obj); + + /** + * Starts playing the movie + */ + virtual void play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj); + + /** + * Plays a sub-section of a movie + */ + virtual void playClip(const Point &drawPos, uint startFrame, uint endFrame); + + /** + * Stops the movie + */ + virtual void stop(); + + /** + * Add a playback event + */ + virtual void addEvent(int eventId, CGameObject *obj); + + /** + * Set the current frame number + */ + virtual void setFrame(uint frameNumber); + + /** + * Handle any pending movie events + */ + virtual bool handleEvents(CMovieEventList &events); + + /** + * Get the current frame number + */ + virtual int getFrame() const; + + /** + * Return any movie range info associated with the movie + */ + virtual const CMovieRangeInfoList *getMovieRangeInfo() const; + + /** + * Set the sound manager reference + */ + virtual void setSoundManager(CSoundManager *soundManager); + + /** + * Set the frame rate for the movie + */ + virtual void setFrameRate(double rate); + + /** + * Creates a duplicate of the frame info + */ + virtual Graphics::ManagedSurface *duplicateFrame() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVIE_H */ diff --git a/engines/titanic/support/movie_clip.cpp b/engines/titanic/support/movie_clip.cpp new file mode 100644 index 0000000000..1f2ef66428 --- /dev/null +++ b/engines/titanic/support/movie_clip.cpp @@ -0,0 +1,100 @@ +/* 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 "titanic/support/movie_clip.h" +#include "titanic/core/game_object.h" + +namespace Titanic { + +CMovieClip::CMovieClip(): ListItem(), _startFrame(0), _endFrame(0) { +} + +CMovieClip::CMovieClip(const CString &name, int startFrame, int endFrame): + ListItem(), _name(name), _startFrame(startFrame), _endFrame(endFrame) { +} + +void CMovieClip::save(SimpleFile *file, int indent) { + file->writeNumberLine(2, indent); + file->writeQuotedLine("Clip", indent); + file->writeQuotedLine(_name, indent); + file->writeNumberLine(_startFrame, indent); + file->writeNumberLine(_endFrame, indent); + + ListItem::save(file, indent); +} + +void CMovieClip::load(SimpleFile *file) { + int val = file->readNumber(); + + switch (val) { + case 1: + // This should never be used + assert(0); + break; + + case 2: + file->readString(); + _name = file->readString(); + _startFrame = file->readNumber(); + _endFrame = file->readNumber(); + break; + + default: + break; + } + + ListItem::load(file); +} + +/*------------------------------------------------------------------------*/ + +CMovieClip *CMovieClipList::findByName(const Common::String &name) const { + for (const_iterator i = begin(); i != end(); ++i) { + CMovieClip *clip = *i; + if (clip->_name == name) + return clip; + } + + return nullptr; +} + +bool CMovieClipList::existsByStart(const CString &name, int startFrame) const { + for (const_iterator i = begin(); i != end(); ++i) { + CMovieClip *clip = *i; + if (clip->_startFrame == startFrame && clip->_name == name) + return true; + } + + return false; +} + +bool CMovieClipList::existsByEnd(const CString &name, int endFrame) const { + for (const_iterator i = begin(); i != end(); ++i) { + CMovieClip *clip = *i; + if (clip->_endFrame == endFrame && clip->_name == name) + return true; + } + + return false; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/movie_clip.h b/engines/titanic/support/movie_clip.h new file mode 100644 index 0000000000..513ed4a339 --- /dev/null +++ b/engines/titanic/support/movie_clip.h @@ -0,0 +1,92 @@ +/* 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 TITANIC_MOVIE_CLIP_H +#define TITANIC_MOVIE_CLIP_H + +#include "titanic/core/list.h" + +namespace Titanic { + +enum ClipFlag { + CLIPFLAG_HAS_END_FRAME = 1, + CLIPFLAG_4 = 4, + CLIPFLAG_HAS_START_FRAME = 8, + CLIPFLAG_PLAY = 0x10 +}; + +class CGameObject; + +/** + * Movie clip + */ +class CMovieClip : public ListItem { +private: + Common::List<void *> _items; + CString _string2; + CString _string3; +public: + CString _name; + int _startFrame; + int _endFrame; +public: + CLASSDEF; + CMovieClip(); + CMovieClip(const CString &name, int startFrame, int endFrame); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +/** + * Movie clip list + */ +class CMovieClipList: public List<CMovieClip> { +public: + /** + * Finds and returns a movie clip in the list by name + */ + CMovieClip *findByName(const Common::String &name) const; + + /** + * Returns true if a clip exists in the list with a given name + * and starting frame number + */ + bool existsByStart(const CString &name, int startFrame = 0) const; + + /** + * Returns true if a clip exists in the list with a given name + * and starting frame number + */ + bool existsByEnd(const CString &name, int endFrame = 0) const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVIE_CLIP_H */ diff --git a/engines/titanic/support/movie_event.cpp b/engines/titanic/support/movie_event.cpp new file mode 100644 index 0000000000..5f8a6da019 --- /dev/null +++ b/engines/titanic/support/movie_event.cpp @@ -0,0 +1,64 @@ +/* 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 "titanic/support/movie_event.h" +#include "titanic/core/game_object.h" + +namespace Titanic { + +CMovieEvent::CMovieEvent() : ListItem(), _type(MET_PLAY), _startFrame(0), + _endFrame(0), _initialFrame(0), _gameObject(nullptr) { +} + +CMovieEvent::CMovieEvent(const CMovieEvent *src) { + _type = src->_type; + _startFrame = src->_startFrame; + _endFrame = src->_endFrame; + _initialFrame = src->_initialFrame; + _gameObject = src->_gameObject; +} + +void CMovieEvent::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + file->writeNumberLine(_startFrame, indent + 1); + file->writeNumberLine(_endFrame, indent + 1); + error("FIXME: Original save/loaded object pointer"); + // file->writeNumberLine(_gameObject, indent + 1); + file->writeNumberLine(_initialFrame, indent + 1); + + ListItem::save(file, indent); +} + +void CMovieEvent::load(SimpleFile *file) { + int val = file->readNumber(); + if (!val) { + _startFrame = file->readNumber(); + _endFrame = file->readNumber(); + file->readNumber(); + error("FIXME: Original save/loaded object pointer"); + _initialFrame = file->readNumber(); + } + + ListItem::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/movie_event.h b/engines/titanic/support/movie_event.h new file mode 100644 index 0000000000..af93c76a31 --- /dev/null +++ b/engines/titanic/support/movie_event.h @@ -0,0 +1,66 @@ +/* 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 TITANIC_MOVIE_EVENT_H +#define TITANIC_MOVIE_EVENT_H + +#include "titanic/core/list.h" + +namespace Titanic { + +enum MovieEventType { MET_PLAY = 0, MET_MOVIE_END = 1, MET_FRAME = 2 }; + +class CGameObject; + +class CMovieEvent : public ListItem { +public: + MovieEventType _type; + int _startFrame; + int _endFrame; + CGameObject *_gameObject; + int _initialFrame; +public: + CMovieEvent(); + CMovieEvent(const CMovieEvent *src); + virtual ~CMovieEvent() {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +class CMovieEventList : public List<CMovieEvent> { +}; + +class CSharedMovieEventList : public Common::List<CMovieEvent> { +}; + + +} // End of namespace Titanic + +#endif /* TITANIC_MOVIE_EVENT_H */ diff --git a/engines/titanic/support/movie_manager.cpp b/engines/titanic/support/movie_manager.cpp new file mode 100644 index 0000000000..bfeb081b5c --- /dev/null +++ b/engines/titanic/support/movie_manager.cpp @@ -0,0 +1,35 @@ +/* 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 "titanic/support/movie_manager.h" +#include "titanic/support/movie.h" +#include "titanic/support/video_surface.h" + +namespace Titanic { + +CMovie *CMovieManager::createMovie(const CResourceKey &key, CVideoSurface *surface) { + CMovie *movie = new OSMovie(key, surface); + movie->setSoundManager(_soundManager); + return movie; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/movie_manager.h b/engines/titanic/support/movie_manager.h new file mode 100644 index 0000000000..2920d909b7 --- /dev/null +++ b/engines/titanic/support/movie_manager.h @@ -0,0 +1,65 @@ +/* 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 TITANIC_MOVIE_MANAGER_H +#define TITANIC_MOVIE_MANAGER_H + +#include "titanic/core/list.h" +#include "titanic/core/resource_key.h" +#include "titanic/sound/sound_manager.h" + +namespace Titanic { + +class CMovie; +class CVideoSurface; + +class CMovieManagerBase { +public: + virtual ~CMovieManagerBase() {} + + /** + * Create a new movie and return it + */ + virtual CMovie *createMovie(const CResourceKey &key, CVideoSurface *surface) = 0; +}; + +class CMovieManager : public CMovieManagerBase { +private: + CSoundManager *_soundManager; +public: + CMovieManager() : CMovieManagerBase(), _soundManager(nullptr) {} + virtual ~CMovieManager() {} + + /** + * Create a new movie and return it + */ + virtual CMovie *createMovie(const CResourceKey &key, CVideoSurface *surface); + + /** + * Sets the sound manager that will be attached to all created movies + */ + void setSoundManager(CSoundManager *soundManager) { _soundManager = soundManager; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVIE_MANAGER_H */ diff --git a/engines/titanic/support/movie_range_info.cpp b/engines/titanic/support/movie_range_info.cpp new file mode 100644 index 0000000000..d4d9fc0e2a --- /dev/null +++ b/engines/titanic/support/movie_range_info.cpp @@ -0,0 +1,112 @@ +/* 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 "titanic/support/movie_range_info.h" +#include "titanic/support/movie_clip.h" +#include "titanic/core/game_object.h" + +namespace Titanic { + +CMovieRangeInfo::CMovieRangeInfo() : ListItem(), _startFrame(0), _endFrame(0) { +} + +CMovieRangeInfo::~CMovieRangeInfo() { + _events.destroyContents(); +} + +CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() { + _startFrame = src->_startFrame; + _endFrame = src->_endFrame; + _initialFrame = src->_initialFrame; + _isReversed = src->_isReversed; + _isRepeat = src->_isRepeat; + + // Duplicate the events list + for (CMovieEventList::const_iterator i = _events.begin(); + i != _events.end(); ++i) { + _events.push_back(new CMovieEvent(*i)); + } +} + +void CMovieRangeInfo::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + file->writeNumberLine(_startFrame, indent + 1); + file->writeNumberLine(_endFrame, indent + 1); + file->writeNumberLine(_initialFrame, indent + 1); + file->writeNumberLine(_isRepeat, indent + 1); + file->writeNumberLine(_isReversed, indent + 1); + _events.save(file, indent + 1); +} + +void CMovieRangeInfo::load(SimpleFile *file) { + int val = file->readNumber(); + if (!val) { + _startFrame = file->readNumber(); + _endFrame = file->readNumber(); + _initialFrame = file->readNumber(); + _isRepeat = file->readNumber(); + _isReversed = file->readNumber(); + _events.load(file); + } +} + +void CMovieRangeInfo::getMovieEnd(CMovieEventList &list) { + for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { + CMovieEvent *movieEvent = *i; + if (movieEvent->_type == MET_MOVIE_END) + list.push_back(new CMovieEvent(movieEvent)); + } +} + +void CMovieRangeInfo::getMovieFrame(CMovieEventList &list, int frameNumber) { + for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { + CMovieEvent *movieEvent = *i; + if (movieEvent->_type == MET_FRAME && movieEvent->_initialFrame == frameNumber) + list.push_back(new CMovieEvent(movieEvent)); + } +} + +void CMovieRangeInfo::process(CGameObject *owner) { + int flags = 0; + if (_endFrame) + flags |= MOVIE_REPEAT; + if (_startFrame) + flags |= MOVIE_REVERSE; + + for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { + CMovieEvent *movieEvent = *i; + if (movieEvent->_type == MET_MOVIE_END) { + flags |= CLIPFLAG_PLAY; + break; + } + } + + owner->playMovie(_startFrame, _endFrame, _initialFrame, flags); + + for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { + CMovieEvent *movieEvent = *i; + if (movieEvent->_type == MET_PLAY) + owner->movieEvent(movieEvent->_initialFrame); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/movie_range_info.h b/engines/titanic/support/movie_range_info.h new file mode 100644 index 0000000000..6b13fbadb5 --- /dev/null +++ b/engines/titanic/support/movie_range_info.h @@ -0,0 +1,81 @@ +/* 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 TITANIC_MOVIE_RANGE_INFO_H +#define TITANIC_MOVIE_RANGE_INFO_H + +#include "video/video_decoder.h" +#include "titanic/core/list.h" +#include "titanic/core/resource_key.h" +#include "titanic/support/movie_event.h" + +namespace Titanic { + +class CGameObject; + +class CMovieRangeInfo : public ListItem { +public: + int _startFrame; + int _endFrame; + int _initialFrame; + bool _isReversed; + bool _isRepeat; + CMovieEventList _events; +public: + CMovieRangeInfo(); + CMovieRangeInfo(const CMovieRangeInfo *src); + virtual ~CMovieRangeInfo(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Adds an event to the events list + */ + void addEvent(CMovieEvent *movieEvent) { _events.push_back(movieEvent); } + + /** + * Get any movie end events for the range + */ + void getMovieEnd(CMovieEventList &list); + + /** + * Get any movie frame events for a specified frame number + */ + void getMovieFrame(CMovieEventList &list, int frameNumber); + + void process(CGameObject *owner); +}; + +class CMovieRangeInfoList : public List<CMovieRangeInfo> { +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVIE_RANGE_INFO_H */ diff --git a/engines/titanic/support/rect.cpp b/engines/titanic/support/rect.cpp new file mode 100644 index 0000000000..5fce4402cb --- /dev/null +++ b/engines/titanic/support/rect.cpp @@ -0,0 +1,44 @@ +/* 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 "titanic/support/rect.h" + +namespace Titanic { + +void Rect::combine(const Rect &r) { + if (isEmpty() || r.isEmpty()) + return; + + Common::Rect::extend(r); +} + +void Rect::constrain(const Rect &r) { + if (!isEmpty()) { + if (r.isEmpty()) { + clear(); + } else { + Common::Rect::clip(r); + } + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/rect.h b/engines/titanic/support/rect.h new file mode 100644 index 0000000000..1661711870 --- /dev/null +++ b/engines/titanic/support/rect.h @@ -0,0 +1,61 @@ +/* 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 TITANIC_RECT_H +#define TITANIC_RECT_H + +#include "common/rect.h" + +namespace Titanic { + +typedef Common::Point Point; + +class Rect : public Common::Rect { +public: + Rect() : Common::Rect() {} + Rect(int16 w, int16 h) : Common::Rect(w, h) {} + Rect(int16 x1, int16 y1, int16 x2, int16 y2) : Common::Rect(x1, y1, x2, y2) {} + + /** + * Returns the top/left corner of the rect as a point + */ + operator const Point() { return Point(left, top); } + + /** + * Clear the rect + */ + void clear() { left = top = right = bottom = 0; } + + /** + * Combine another rect into this one + */ + void combine(const Rect &r); + + /** + * Constrains/clips to the intersection area of the given rect + */ + void constrain(const Rect &r); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_RECT_H */ diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp new file mode 100644 index 0000000000..d795f78764 --- /dev/null +++ b/engines/titanic/support/screen_manager.cpp @@ -0,0 +1,326 @@ +/* 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 "titanic/support/screen_manager.h" +#include "titanic/titanic.h" +#include "titanic/support/video_surface.h" + +namespace Titanic { + +CScreenManager *CScreenManager::_screenManagerPtr; +CScreenManager *CScreenManager::_currentScreenManagerPtr; + +CScreenManager::CScreenManager(TitanicEngine *vm): _vm(vm) { + _screenManagerPtr = nullptr; + _currentScreenManagerPtr = nullptr; + + _frontRenderSurface = nullptr; + _mouseCursor = nullptr; + _textCursor = nullptr; + _inputHandler = nullptr; + _fontNumber = 0; + // TODO: Further initialization + + _screenManagerPtr = this; +} + +CScreenManager::~CScreenManager() { + _screenManagerPtr = nullptr; +} + +void CScreenManager::setWindowHandle(int v) { + // Not needed +} + +bool CScreenManager::resetWindowHandle(int v) { + hideCursor(); + return true; +} + +CScreenManager *CScreenManager::setCurrent() { + if (!_currentScreenManagerPtr) + _currentScreenManagerPtr = _screenManagerPtr; + + return _currentScreenManagerPtr; +} + +void CScreenManager::setSurfaceBounds(SurfaceNum surfaceNum, const Rect &r) { + if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size()) + _backSurfaces[surfaceNum]._bounds = r; +} + +int CScreenManager::setFontNumber(int fontNumber) { + int oldFontNumber = _fontNumber; + _fontNumber = fontNumber; + return oldFontNumber; +} + +/*------------------------------------------------------------------------*/ + +OSScreenManager::OSScreenManager(TitanicEngine *vm): CScreenManager(vm), + _directDrawManager(vm, false) { + _field48 = 0; + _field4C = 0; + _field50 = 0; + _field54 = 0; +} + +OSScreenManager::~OSScreenManager() { + destroyFrontAndBackBuffers(); + delete _mouseCursor; + delete _textCursor; +} + +void OSScreenManager::setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2) { + assert(bpp == 16); + destroyFrontAndBackBuffers(); + _directDrawManager.initVideo(width, height, bpp, numBackSurfaces); + + _vm->_screen->create(width, height, g_system->getScreenFormat()); + _frontRenderSurface = new OSVideoSurface(this, nullptr); + _frontRenderSurface->setSurface(this, _directDrawManager._mainSurface); + + _backSurfaces.resize(numBackSurfaces); + for (uint idx = 0; idx < numBackSurfaces; ++idx) { + _backSurfaces[idx]._surface = new OSVideoSurface(this, nullptr); + _backSurfaces[idx]._surface->setSurface(this, _directDrawManager._backSurfaces[idx]); + } + + // Load fonts + _fonts[0].load(149); + _fonts[1].load(151); + _fonts[2].load(152); + _fonts[3].load(153); + + // Load the cursors + loadCursors(); +} + +void OSScreenManager::drawCursors() { + // The original did both text and mouse cursor drawing here. + // For ScummVM, we only need to worry about the text cursor + _textCursor->draw(); +} + +DirectDrawSurface *OSScreenManager::getDDSurface(SurfaceNum surfaceNum) { + if (surfaceNum == SURFACE_PRIMARY) + return _directDrawManager._mainSurface; + else if (surfaceNum < (int)_backSurfaces.size()) + return _directDrawManager._backSurfaces[surfaceNum]; + else + return nullptr; +} + +CVideoSurface *OSScreenManager::lockSurface(SurfaceNum surfaceNum) { + CVideoSurface *surface = getSurface(surfaceNum); + surface->lock(); + return surface; +} + +void OSScreenManager::unlockSurface(CVideoSurface *surface) { + surface->unlock(); +} + +CVideoSurface *OSScreenManager::getSurface(SurfaceNum surfaceNum) const { + if (surfaceNum == SURFACE_PRIMARY) + return _frontRenderSurface; + else if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size()) + return _backSurfaces[surfaceNum]._surface; + else + return nullptr; +} + +void OSScreenManager::fillRect(SurfaceNum surfaceNum, Rect *rect, byte r, byte g, byte b) { + DirectDrawSurface *surface = getDDSurface(surfaceNum); + if (!surface) + return; + + // If bounds are provided, clip and use them. Otherwise, use entire surface area + Rect surfaceRect(0, 0, surface->getWidth(), surface->getHeight()); + Rect tempRect; + + if (rect) { + tempRect = *rect; + tempRect.clip(surfaceRect); + } else { + tempRect = surfaceRect; + } + + if (tempRect.isValidRect()) + surface->fillRect(&tempRect, r, g, b); +} + +void OSScreenManager::blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, + const Point *destPos, const Rect *srcRect) { + // Get the dest surface + CVideoSurface *destSurface = _frontRenderSurface; + if (surfaceNum < -1) + return; + if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size()) + destSurface = _backSurfaces[surfaceNum]._surface; + if (!destSurface->hasSurface()) + return; + + Point destPoint = destPos ? *destPos : Point(0, 0); + Rect srcBounds = srcRect ? *srcRect : Rect(0, 0, src->getWidth(), src->getHeight()); + Rect *bounds = &srcBounds; + Rect rect2; + + if (surfaceNum >= 0 && !_backSurfaces[surfaceNum]._bounds.isEmpty()) { + // Perform clipping to the bounds of the back surface + rect2 = srcBounds; + rect2.translate(-srcBounds.left, -srcBounds.top); + rect2.translate(destPoint.x, destPoint.y); + rect2.constrain(_backSurfaces[surfaceNum]._bounds); + + rect2.translate(-destPoint.x, -destPoint.y); + rect2.translate(srcBounds.left, srcBounds.top); + + if (rect2.isEmpty()) + return; + + destPoint.x += rect2.left - srcBounds.left; + destPoint.y += rect2.top - srcBounds.top; + bounds = &rect2; + } + + if (!bounds->isEmpty()) + destSurface->blitFrom(destPoint, src, bounds); +} + +void OSScreenManager::blitFrom(SurfaceNum surfaceNum, const Rect *rect, CVideoSurface *src, int v) { + // Get the dest surface + CVideoSurface *destSurface = _frontRenderSurface; + if (surfaceNum < -1) + return; + if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size()) + destSurface = _backSurfaces[surfaceNum]._surface; + if (!destSurface->hasSurface()) + return; + + if (!rect->isEmpty()) + destSurface->blitFrom(Point(rect->left, rect->top), src, rect); +} + +int OSScreenManager::writeString(int surfaceNum, const Rect &destRect, + int yOffset, const CString &str, CTextCursor *textCursor) { + CVideoSurface *surface; + Rect bounds; + + if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size()) { + surface = _backSurfaces[surfaceNum]._surface; + bounds = _backSurfaces[surfaceNum]._bounds; + } else if (surfaceNum == -1) { + surface = _frontRenderSurface; + bounds = Rect(0, 0, surface->getWidth(), surface->getHeight()); + } else { + return -1; + } + + return _fonts[_fontNumber].writeString(surface, destRect, bounds, + yOffset, str, textCursor); +} + +int OSScreenManager::writeString(int surfaceNum, const Rect &srcRect, + const Rect &destRect, const CString &str, CTextCursor *textCursor) { + // TODO + return 0; +} + +void OSScreenManager::setFontColor(byte r, byte g, byte b) { + _fonts[_fontNumber].setColor(r, g, b); +} + +int OSScreenManager::getTextBounds(const CString &str, int maxWidth, Point *sizeOut) const { + return _fonts[_fontNumber].getTextBounds(str, maxWidth, sizeOut); +} + +int OSScreenManager::getFontHeight() const { + return _fonts[_fontNumber]._fontHeight; +} + +int OSScreenManager::stringWidth(const CString &str) { + return _fonts[_fontNumber].stringWidth(str); +} + +void OSScreenManager::frameRect(SurfaceNum surfaceNum, const Rect &rect, byte r, byte g, byte b) { + Rect top(rect.left, rect.top, rect.right, rect.top + 1); + fillRect(surfaceNum, &top, r, g, b); + Rect bottom(rect.left, rect.bottom - 1, rect.right, rect.bottom); + fillRect(surfaceNum, &bottom, r, g, b); + Rect left(rect.left, rect.top, rect.left + 1, rect.bottom); + fillRect(surfaceNum, &left, r, g, b); + Rect right(rect.right - 1, rect.top, rect.right, rect.bottom); +} + +void OSScreenManager::clearSurface(SurfaceNum surfaceNum, Rect *bounds) { + if (surfaceNum == SURFACE_PRIMARY) + _directDrawManager._mainSurface->fill(bounds, 0); + else if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size()) + _directDrawManager._backSurfaces[surfaceNum]->fill(bounds, 0); +} + +void OSScreenManager::resizeSurface(CVideoSurface *surface, int width, int height) { + DirectDrawSurface *ddSurface = _directDrawManager.createSurface(width, height, 0); + surface->setSurface(this, ddSurface); +} + +CVideoSurface *OSScreenManager::createSurface(int w, int h) { + DirectDrawSurface *ddSurface = _directDrawManager.createSurface(w, h, 0); + return new OSVideoSurface(this, ddSurface); +} + +CVideoSurface *OSScreenManager::createSurface(const CResourceKey &key) { + return new OSVideoSurface(this, key); +} + +void OSScreenManager::showCursor() { + CScreenManager::_screenManagerPtr->_mouseCursor->show(); +} + +void OSScreenManager::hideCursor() { + CScreenManager::_screenManagerPtr->_mouseCursor->hide(); +} + +void OSScreenManager::destroyFrontAndBackBuffers() { + delete _frontRenderSurface; + _frontRenderSurface = nullptr; + + for (uint idx = 0; idx < _backSurfaces.size(); ++idx) + delete _backSurfaces[idx]._surface; + _backSurfaces.clear(); +} + +void OSScreenManager::loadCursors() { + if (_mouseCursor) { + hideCursor(); + delete _mouseCursor; + } + _mouseCursor = new CMouseCursor(this); + showCursor(); + + if (!_textCursor) { + _textCursor = new CTextCursor(this); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h new file mode 100644 index 0000000000..0736f1393c --- /dev/null +++ b/engines/titanic/support/screen_manager.h @@ -0,0 +1,395 @@ +/* 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 TITANIC_SCREEN_MANAGER_H +#define TITANIC_SCREEN_MANAGER_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "titanic/support/direct_draw.h" +#include "titanic/support/font.h" +#include "titanic/input_handler.h" +#include "titanic/support/mouse_cursor.h" +#include "titanic/support/text_cursor.h" +#include "titanic/support/video_surface.h" +#include "titanic/core/resource_key.h" + +namespace Titanic { + +/** + * The original used page flipping with one primary and one back buffer. + * Since we don't need that in ScummVM, the back buffer number below is + * remapped to the primary surface + */ +enum SurfaceNum { + SURFACE_PRIMARY = -1, // Surface 0 + SURFACE_BACKBUFFER = -1 // Surface -1 +}; + +class TitanicEngine; + +class CScreenManager { + struct VideoSurfaceEntry { + CVideoSurface *_surface; + Rect _bounds; + }; +protected: + TitanicEngine *_vm; +public: + static CScreenManager *_screenManagerPtr; + static CScreenManager *_currentScreenManagerPtr; + + /** + * Set the current screen manager + */ + static CScreenManager *setCurrent(); +public: + Common::Array<VideoSurfaceEntry> _backSurfaces; + CVideoSurface *_frontRenderSurface; + CMouseCursor *_mouseCursor; + CTextCursor *_textCursor; + CInputHandler *_inputHandler; + int _fontNumber; +public: + CScreenManager(TitanicEngine *vm); + virtual ~CScreenManager(); + + void fn1() {} + void fn2() {} + + virtual void setWindowHandle(int v); + virtual bool resetWindowHandle(int v); + + /** + * Sets the video mode + */ + virtual void setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2) = 0; + + /** + * Handles drawing the cursors + */ + virtual void drawCursors() = 0; + + /** + * Locks a specified surface number for access and returns a pointer to it + */ + virtual CVideoSurface *lockSurface(SurfaceNum surfaceNum) = 0; + + /** + * Unlocks a previously locked surface + */ + virtual void unlockSurface(CVideoSurface *surface) = 0; + + /** + * Gets a specified surface number + */ + virtual CVideoSurface *getSurface(SurfaceNum surfaceNum) const = 0; + + /** + * Return the front render surface + */ + virtual CVideoSurface *getFrontRenderSurface() const = 0; + + /** + * Fill an area with a specific color + */ + virtual void fillRect(SurfaceNum surfaceNum, Rect *rect, byte r, byte g, byte b) = 0; + + /** + * Blits a surface onto one of the screen surfaces + */ + virtual void blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, const Point *destPos = nullptr, + const Rect *srcRect = nullptr) = 0; + + /** + * Blits a surface onto one of the screen surfaces + */ + virtual void blitFrom(SurfaceNum surfaceNum, const Rect *rect, CVideoSurface *src, int v = 0) = 0; + + /** + * Write a string + * @param surfaceNum Destination surface + * @param destRect Bounds within dest surface + * @param yOffset Y offset for drawing, to allow for parts of + * the text to be scrolled off-screen + * @param str Line or lines to write + * @param textCursor Optional text cursor pointer + */ + virtual int writeString(int surfaceNum, const Rect &destRect, + int yOffset, const CString &str, CTextCursor *textCursor) = 0; + + /** + * Write a string + * @param surfaceNum Destination surface + * @param srcRect Drawing area + * @param destRect Bounds of dest surface + * @param str Line or lines to write + * @param textCursor Optional text cursor pointer + */ + virtual int writeString(int surfaceNum, const Rect &srcRect, + const Rect &destRect, const CString &str, CTextCursor *textCursor) = 0; + + /** + * Set the font color + */ + virtual void setFontColor(byte r, byte g, byte b) = 0; + + /** + * Get the text area a string will fit into + * @param str String + * @param maxWidth Maximum width in pixels + * @param sizeOut Optional pointer to output size + * @returns Required height + */ + virtual int getTextBounds(const CString &str, int maxWidth, Point *sizeOut = nullptr) const = 0; + + /** + * Get the current font height + */ + virtual int getFontHeight() const = 0; + + /** + * Returns the width of a given string in pixels + */ + virtual int stringWidth(const CString &str) = 0; + + /** + * Draws a frame enclosing the specified area + */ + virtual void frameRect(SurfaceNum surfaceNum, const Rect &rect, byte r, byte g, byte b) = 0; + + /** + * Clear a portion of a specified surface + */ + virtual void clearSurface(SurfaceNum surfaceNum, Rect *_bounds) = 0; + + /** + * Resize the passed surface + */ + virtual void resizeSurface(CVideoSurface *surface, int width, int height) = 0; + + /** + * Creates a surface of a given size + */ + virtual CVideoSurface *createSurface(int w, int h) = 0; + + /** + * Creates a surface from a specified resource + */ + virtual CVideoSurface *createSurface(const CResourceKey &key) = 0; + + /** + * Get the top-left corner of the screen in global screen co-ordinates + * For ScummVM, this is always (0, 0), even in Windowed mode + */ + virtual Point getScreenTopLeft() { return Point(0, 0); } + + /** + * Waits for a vertical screen sync + * For ScummVM, this can be safely ignored + */ + virtual void waitForVSync() {} + + /** + * Show the mouse cursor + */ + virtual void showCursor() = 0; + + /** + * Hide the mouse cursor + */ + virtual void hideCursor() = 0; + + /** + * Set drawing bounds for a specified surface + */ + void setSurfaceBounds(SurfaceNum surfaceNum, const Rect &r); + + /** + * Set the current font number + */ + int setFontNumber(int fontNumber); +}; + +class OSScreenManager: CScreenManager { +private: + DirectDrawManager _directDrawManager; + + /** + * Frees any surface buffers + */ + void destroyFrontAndBackBuffers(); + + /** + * Load game cursors + */ + void loadCursors(); + + /** + * Gets an underlying surface + */ + DirectDrawSurface *getDDSurface(SurfaceNum surfaceNum); +public: + int _field48; + int _field4C; + int _field50; + int _field54; + STFont _fonts[4]; +public: + OSScreenManager(TitanicEngine *vm); + virtual ~OSScreenManager(); + + /** + * Sets the video mode + */ + virtual void setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2); + + /** + * Handles drawing the cursors + */ + virtual void drawCursors(); + + /** + * Locks a specified surface number for access and returns a pointer to it + */ + virtual CVideoSurface *lockSurface(SurfaceNum surfaceNum); + + /** + * Unlocks a previously locked surface + */ + virtual void unlockSurface(CVideoSurface *surface); + + /** + * Gets a specified surface number + */ + virtual CVideoSurface *getSurface(SurfaceNum surfaceNum) const; + + /** + * Return the front render surface + */ + virtual CVideoSurface *getFrontRenderSurface() const { + return _frontRenderSurface; + } + + + /** + * Fill an area with a specific color + */ + virtual void fillRect(SurfaceNum surfaceNum, Rect *rect, byte r, byte g, byte b); + + /** + * Blits a surface onto one of the screen surfaces + */ + virtual void blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, const Point *destPos, + const Rect *srcRect = nullptr); + + /** + * Blits a surface onto one of the screen surfaces + */ + virtual void blitFrom(SurfaceNum surfaceNum, const Rect *rect, CVideoSurface *src, int v = 0); + + /** + * Write a string + * @param surfaceNum Destination surface + * @param destRect Bounds within dest surface + * @param yOffset Y offset for drawing, to allow for parts of + * the text to be scrolled off-screen + * @param str Line or lines to write + * @param textCursor Optional text cursor pointer + */ + virtual int writeString(int surfaceNum, const Rect &destRect, + int yOffset, const CString &str, CTextCursor *textCursor); + + /** + * Write a string + * @param surfaceNum Destination surface + * @param srcRect Drawing area + * @param destRect Bounds of dest surface + * @param str Line or lines to write + * @param textCursor Optional text cursor pointer + */ + virtual int writeString(int surfaceNum, const Rect &srcRect, + const Rect &destRect, const CString &str, CTextCursor *textCursor); + + /** + * Set the font color + */ + virtual void setFontColor(byte r, byte g, byte b); + + /** + * Get the text area a string will fit into + * @param str String + * @param maxWidth Maximum width in pixels + * @param sizeOut Optional pointer to output size + * @returns Required height + */ + virtual int getTextBounds(const CString &str, int maxWidth, Point *sizeOut = nullptr) const; + + /** + * Get the current font height + */ + virtual int getFontHeight() const; + + /** + * Returns the width of a given string in pixels + */ + virtual int stringWidth(const CString &str); + + /** + * Draws a frame enclosing the specified area + */ + virtual void frameRect(SurfaceNum surfaceNum, const Rect &rect, byte r, byte g, byte b); + + /** + * Clear a portion of the screen surface + */ + virtual void clearSurface(SurfaceNum surfaceNum, Rect *bounds); + + /** + * Resize the passed surface + */ + virtual void resizeSurface(CVideoSurface *surface, int width, int height); + + /** + * Creates a surface of a given size + */ + virtual CVideoSurface *createSurface(int w, int h); + + /** + * Creates a surface from a specified resource + */ + virtual CVideoSurface *createSurface(const CResourceKey &key); + + /** + * Show the mouse cursor + */ + virtual void showCursor(); + + /** + * Hide the mouse cursor + */ + virtual void hideCursor(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SCREEN_MANAGER_H */ diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp new file mode 100644 index 0000000000..35b2e28e4a --- /dev/null +++ b/engines/titanic/support/simple_file.cpp @@ -0,0 +1,512 @@ +/* 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/util.h" +#include "titanic/support/simple_file.h" + +namespace Titanic { + +CString readStringFromStream(Common::SeekableReadStream *s) { + CString result; + char c; + while ((c = s->readByte()) != '\0') + result += c; + + return result; +} + +/*------------------------------------------------------------------------*/ + +bool File::open(const Common::String &filename) { + if (!Common::File::open(filename)) + error("Could not open file - %s", filename.c_str()); + return true; +} + +/*------------------------------------------------------------------------*/ + +SimpleFile::SimpleFile(): _inStream(nullptr), _outStream(nullptr), _lineCount(1) { +} + +SimpleFile::~SimpleFile() { + close(); +} + +void SimpleFile::open(Common::SeekableReadStream *stream) { + close(); + _inStream = stream; +} + +void SimpleFile::open(Common::OutSaveFile *stream) { + close(); + _outStream = stream; +} + +void SimpleFile::close() { + if (_outStream) { + _outStream->finalize(); + delete _outStream; + _outStream = nullptr; + } + + if (_inStream) { + delete _inStream; + _inStream = nullptr; + } +} + +void SimpleFile::safeRead(void *dst, size_t count) { + if (unsafeRead(dst, count) != count) + error("Could not read %d bytes", (int)count); +} + +size_t SimpleFile::unsafeRead(void *dst, size_t count) { + assert(_inStream); + return _inStream->read(dst, count); +} + +size_t SimpleFile::write(const void *src, size_t count) const { + assert(_outStream); + return _outStream->write(src, count); +} + +void SimpleFile::seek(int offset, int origin) { + assert(_inStream); + _inStream->seek(offset, origin); +} + +byte SimpleFile::readByte() { + byte b; + safeRead(&b, 1); + return b; +} + +uint SimpleFile::readUint16LE() { + uint val; + safeRead(&val, 2); + return READ_LE_UINT16(&val); +} + +uint SimpleFile::readUint32LE() { + uint val; + safeRead(&val, 4); + return READ_LE_UINT32(&val); +} + +CString SimpleFile::readString() { + char c; + CString result; + bool backslashFlag = false; + + // First skip any spaces + do { + safeRead(&c, 1); + } while (Common::isSpace(c)); + + // Ensure we've found a starting quote for the string + if (c != '"') + error("Could not find starting quote"); + + bool endFlag = false; + while (!endFlag) { + // Read the next character + safeRead(&c, 1); + + if (backslashFlag) { + backslashFlag = false; + switch (c) { + case 'n': + result += '\n'; + break; + case 'r': + result += '\r'; + break; + case '\t': + result += '\t'; + break; + default: + result += c; + break; + } + } else { + switch (c) { + case '"': + endFlag = true; + break; + case '\\': + backslashFlag = true; + break; + default: + result += c; + break; + } + } + } + + // Return the string + return result; +} + +int SimpleFile::readNumber() { + char c; + int result = 0; + bool minusFlag = false; + + // First skip any spaces + do { + safeRead(&c, 1); + } while (Common::isSpace(c)); + + // Check for prefix sign + if (c == '+' || c == '-') { + minusFlag = c == '-'; + safeRead(&c, 1); + } + + // Read in the number + if (!Common::isDigit(c)) + error("Invalid number"); + + while (Common::isDigit(c)) { + result = result * 10 + (c - '0'); + safeRead(&c, 1); + } + + // Finally, if it's a minus value, then negate it + if (minusFlag) + result = -result; + + return result; +} + +double SimpleFile::readFloat() { + char c; + Common::String result; + + // First skip any spaces + do { + safeRead(&c, 1); + } while (Common::isSpace(c)); + + // Check for prefix sign + if (c == '+' || c == '-') { + result += c; + safeRead(&c, 1); + } + + // Read in the number + if (!Common::isDigit(c)) + error("Invalid number"); + + while (Common::isDigit(c) || c == '.') { + result += c; + safeRead(&c, 1); + } + + // Convert to a float and return it + float floatValue; + sscanf(result.c_str(), "%f", &floatValue); + + return floatValue; +} + +Point SimpleFile::readPoint() { + Point pt; + pt.x = readNumber(); + pt.y = readNumber(); + + return pt; +} + +Rect SimpleFile::readRect() { + Rect r; + r.left = readNumber(); + r.top = readNumber(); + r.right = readNumber(); + r.bottom = readNumber(); + + return r; +} + +Rect SimpleFile::readBounds() { + Rect r; + r.left = readNumber(); + r.top = readNumber(); + r.setWidth(readNumber()); + r.setHeight(readNumber()); + + return r; +} + +void SimpleFile::readBuffer(char *buffer, size_t count) { + CString tempString = readString(); + if (buffer) { + strncpy(buffer, tempString.c_str(), count); + buffer[count - 1] = '\0'; + } +} + +void SimpleFile::writeUint16LE(uint val) { + byte lo = val & 0xff; + byte hi = (val >> 8) & 0xff; + write(&lo, 1); + write(&hi, 1); +} + +void SimpleFile::writeUint32LE(uint val) { + uint16 lo = val & 0xffff; + uint16 hi = (val >> 16) & 0xff; + writeUint16LE(lo); + writeUint16LE(hi); +} + +void SimpleFile::writeLine(const CString &str) const { + write(str.c_str(), str.size()); + write("\r\n", 2); +} + +void SimpleFile::writeString(const CString &str) const { + if (str.empty()) + return; + + const char *msgP = str.c_str(); + char c; + + while ((c = *msgP++) != '\0') { + switch (c) { + case '\r': + write("\\r", 2); + break; + case '\n': + write("\\n", 2); + break; + case '\t': + write("\\t", 2); + break; + case '\"': + write("\\\"", 2); + break; + case '\\': + write("\\\\", 2); + break; + case '{': + write("\\{", 2); + break; + case '}': + write("\\}", 2); + break; + default: + write(&c, 1); + break; + } + } +} + +void SimpleFile::writeQuotedString(const CString &str) const { + write("\"", 1); + writeString(str); + write("\" ", 2); +} + +void SimpleFile::writeQuotedLine(const CString &str, int indent) const { + writeIndent(indent); + writeQuotedString(str); + write("\n", 1); +} + +void SimpleFile::writeNumber(int val) const { + CString str = CString::format("%d ", val); + write(str.c_str(), str.size()); +} + +void SimpleFile::writeNumberLine(int val, int indent) const { + writeIndent(indent); + writeNumber(val); + write("\n", 1); +} + +void SimpleFile::writeFloat(double val) const { + Common::String valStr = Common::String::format("%f ", val); + write(valStr.c_str(), valStr.size()); +} + +void SimpleFile::writeFloatLine(double val, int indent) const { + writeIndent(indent); + writeFloat(val); + write("\n", 1); +} + +void SimpleFile::writePoint(const Point &pt, int indent) const { + writeIndent(indent); + writeNumber(pt.x); + writeNumber(pt.y); + write("\n", 1); +} + +void SimpleFile::writeRect(const Rect &r, int indent) const { + writePoint(Point(r.left, r.top), indent); + writePoint(Point(r.right, r.bottom), indent); +} + +void SimpleFile::writeBounds(const Rect &r, int indent) const { + writePoint(Point(r.left, r.top), indent); + writePoint(Point(r.width(), r.height()), indent); +} + +void SimpleFile::writeFormat(const char *format, ...) const { + // Convert the format specifier and params to a string + va_list va; + va_start(va, format); + CString line = CString::vformat(format, va); + va_end(va); + + // Write out the string + write(format, strlen(format)); +} + +void SimpleFile::writeIndent(uint indent) const { + for (uint idx = 0; idx < indent; ++idx) + write("\t", 1); +} + +bool SimpleFile::IsClassStart() { + char c; + + do { + safeRead(&c, 1); + } while (Common::isSpace(c)); + + assert(c == '{' || c == '}'); + return c == '{'; +} + +void SimpleFile::writeClassStart(const CString &classStr, int indent) { + write("\n", 1); + writeIndent(indent); + write("{\n", 2); + writeIndent(indent + 1); + writeQuotedString(classStr); + write("\n", 1); +} + +void SimpleFile::writeClassEnd(int indent) { + writeIndent(indent); + write("}\n", 2); +} + +bool SimpleFile::scanf(const char *format, ...) { + va_list va; + va_start(va, format); + char c; + + CString formatStr(format); + while (!formatStr.empty()) { + if (formatStr.hasPrefix(" ")) { + formatStr.deleteChar(0); + + safeRead(&c, 1); + if (!Common::isSpace(c)) + return false; + + // Skip over whitespaces + skipSpaces(); + } else if (formatStr.hasPrefix("%d")) { + // Read in a number + formatStr = CString(formatStr.c_str() + 2); + int *param = (int *)va_arg(va, int *); + *param = readNumber(); + + if (!eos()) + _inStream->seek(-1, SEEK_CUR); + } else if (formatStr.hasPrefix("%s")) { + // Read in text until the next space + formatStr = CString(formatStr.c_str() + 2); + CString *str = (CString *)va_arg(va, CString *); + str->clear(); + while (!eos() && !Common::isSpace(c = readByte())) + *str += c; + + if (!eos()) + _inStream->seek(-1, SEEK_CUR); + } + } + + skipSpaces(); + va_end(va); + return true; +} + +void SimpleFile::skipSpaces() { + char c = ' '; + while (!eos() && Common::isSpace(c)) + safeRead(&c, 1); + + if (!eos()) + _inStream->seek(-1, SEEK_CUR); +} + +/*------------------------------------------------------------------------*/ + +bool StdCWadFile::open(const Common::String &filename) { + File f; + CString name = filename; + + // Check for whether it is indeed a file/resource pair + int idx = name.indexOf('#'); + + if (idx < 0) { + // Nope, so open up file for standard reading + assert(!name.empty()); + f.open(name); + + SimpleFile::open(f.readStream(f.size())); + return true; + } + + // Split up the name and resource, and get the resource index + CString fname = name.left(idx) + ".st"; + int extPos = name.lastIndexOf('.'); + CString resStr = name.mid(idx + 1, extPos - idx - 1); + int resIndex = resStr.readInt(); + + // Open up the index for access + f.open(fname); + int indexSize = f.readUint32LE() / 4; + assert(resIndex < indexSize); + + // Get the specific resource's offset, and size by also + // getting the offset of the following resource + f.seek(resIndex * 4); + uint resOffset = f.readUint32LE(); + uint nextOffset = (resIndex == (indexSize - 1)) ? f.size() : + f.readUint32LE(); + + // Read in the resource + f.seek(resOffset); + Common::SeekableReadStream *stream = f.readStream(nextOffset - resOffset); + SimpleFile::open(stream); + + f.close(); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h new file mode 100644 index 0000000000..f5d0bc7c1b --- /dev/null +++ b/engines/titanic/support/simple_file.h @@ -0,0 +1,321 @@ +/* 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 TITANIC_SIMPLE_FILE_H +#define TITANIC_SIMPLE_FILE_H + +#include "common/file.h" +#include "titanic/support/rect.h" +#include "common/savefile.h" +#include "common/stream.h" +#include "common/zlib.h" +#include "titanic/support/string.h" + +namespace Titanic { + +class Decompressor; +class DecompressorData; + +/** + * Simple ScummVM File descendent that throws a wobbly if + * the file it tries to open isn't present + */ +class File : public Common::File { +public: + virtual bool open(const Common::String &filename); +}; + +/** + * This class implements basic reading and writing to files + */ +class SimpleFile { +private: + /** + * Skip over any pending spaces + */ + void skipSpaces(); +protected: + Common::SeekableReadStream *_inStream; + Common::OutSaveFile *_outStream; + int _lineCount; +public: + SimpleFile(); + virtual ~SimpleFile(); + + operator Common::SeekableReadStream &() { return *_inStream; } + operator Common::WriteStream &() { return *_outStream; } + + /** + * Set up a stream for read access + */ + virtual void open(Common::SeekableReadStream *stream); + + /** + * Set up a stream for write access + */ + virtual void open(Common::OutSaveFile *stream); + + /** + * Close the file + */ + virtual void close(); + + /** + * Read from the file with validation + */ + virtual void safeRead(void *dst, size_t count); + + /** + * Read from the file + */ + virtual size_t unsafeRead(void *dst, size_t count); + + /** + * Write out data + */ + virtual size_t write(const void *src, size_t count) const; + + /** + * Seek + */ + virtual void seek(int offset, int origin); + /** + * Read a byte + */ + byte readByte(); + + /** + * Read a 16-bit LE number + */ + uint readUint16LE(); + + /** + * Read a 32-bit LE number + */ + uint readUint32LE(); + + /** + * Read a string from the file + */ + CString readString(); + + /** + * Read a number from the file + */ + int readNumber(); + + /** + * Read a floating point number from the file + */ + double readFloat(); + + /** + * Read in a point + */ + Point readPoint(); + + /** + * Read in a rect + */ + Rect readRect(); + + /** + * Rect in a bounds + */ + Rect readBounds(); + + /** + * Read a string and copy it into an optionally passed buffer + */ + void readBuffer(char *buffer = nullptr, size_t count = 0); + + /** + * Scan in values from the file + */ + bool scanf(const char *format, ...); + + /** + * Write out a byte + */ + void writeByte(byte b) { write(&b, 1); } + + /** + * Write out a raw 16-bit LE number + */ + void writeUint16LE(uint val); + + /** + * Write out a raw 32-bit LE number + */ + void writeUint32LE(uint val); + + /** + * Write a string line + */ + void writeLine(const CString &str) const; + + /** + * Write a string + */ + void writeString(const CString &str) const; + + /** + * Write a quoted string + */ + void writeQuotedString(const CString &str) const; + + /** + * Write a quoted string line + */ + void writeQuotedLine(const CString &str, int indent) const; + + /** + * Write a number to file + */ + void writeNumber(int val) const; + + /** + * Write a number line to file + */ + void writeNumberLine(int val, int indent) const; + + /** + * Write a floating point number + */ + void writeFloat(double val) const; + + /** + * Write a floating point number as a line + */ + void writeFloatLine(double val, int indent) const; + + /** + * Write out a point line + */ + void writePoint(const Point &pt, int indent)const; + + /** + * Write out a rect line + */ + void writeRect(const Rect &r, int indent) const; + + /** + * Write out a bounds line + */ + void writeBounds(const Rect &r, int indent) const; + + /** + * Write out a string using a format specifier, just like fprintf + */ + void writeFormat(const char *format, ...) const; + + /** + * Write out a number of tabs to form an indent in the output + */ + void writeIndent(uint indent) const; + + /** + * Validates that the following non-space character is either + * an opening or closing squiggly bracket denoting a class + * definition start or end. Returns true if it's a class start + */ + bool IsClassStart(); + + /** + * Write the starting header for a class definition + */ + void writeClassStart(const CString &classStr, int indent); + + /** + * Write out the ending footer for a class definition + */ + void writeClassEnd(int indent); + + /** + * Return true if the stream has finished being read + */ + bool eos() const { + assert(_inStream); + return _inStream->pos() >= _inStream->size(); + } +}; + +/** + * Derived file that handles compressed files + */ +class CompressedFile : public SimpleFile { +public: + CompressedFile() : SimpleFile() {} + virtual ~CompressedFile() {} + + /** + * Set up a stream for read access + */ + virtual void open(Common::SeekableReadStream *stream) { + SimpleFile::open(Common::wrapCompressedReadStream(stream)); + } + + /** + * Set up a stream for write access + */ + virtual void open(Common::OutSaveFile *stream) { + SimpleFile::open(Common::wrapCompressedWriteStream(stream)); + } +}; + +/** + * Derived file that handles WAD archives containing multiple files + */ +class StdCWadFile : public SimpleFile { +public: + StdCWadFile() : SimpleFile() {} + virtual ~StdCWadFile() {} + + /** + * Open up the specified file + */ + virtual bool open(const Common::String &filename); + + /** + * Unsupported open method from parent class + */ + virtual void open(Common::SeekableReadStream *stream) {} + + /** + * Unsupported open method from parent class + */ + virtual void open(Common::OutSaveFile *stream) {} + + /** + * Return a reference to the read stream + */ + Common::SeekableReadStream *readStream() const { return _inStream; } +}; + +/** + * General purpose support method for reading an ASCIIZ string from a stream + */ +CString readStringFromStream(Common::SeekableReadStream *s); + +} // End of namespace Titanic + +#endif /* TITANIC_SIMPLE_FILE_H */ diff --git a/engines/titanic/support/string.cpp b/engines/titanic/support/string.cpp new file mode 100644 index 0000000000..cd39c03861 --- /dev/null +++ b/engines/titanic/support/string.cpp @@ -0,0 +1,125 @@ +/* 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/algorithm.h" +#include "titanic/support/string.h" + +namespace Titanic { + +CString::CString(char c, uint32 len) : Common::String() { + ensureCapacity(len, false); + for (uint idx = 0; idx < len; ++idx) + (*this) += c; +} + +CString::CString(int val) : Common::String() { + *this = CString::format("%d", val); +} + +CString CString::left(uint count) const { + return (count > size()) ? CString() : CString(c_str(), c_str() + count); +} + +CString CString::right(uint count) const { + uint strSize = size(); + return (count > strSize) ? CString() : + CString(c_str() + strSize - count, c_str() + strSize); +} + +CString CString::mid(uint start, uint count) const { + if (start >= size()) + return CString(); + else + return CString(c_str() + start, MIN(count, size() - start)); +} + +CString CString::mid(uint start) const { + uint strSize = size(); + assert(start <= strSize); + return mid(start, strSize - start); +} + +int CString::indexOf(char c) const { + const char *charP = strchr(c_str(), c); + return charP ? charP - c_str() : -1; +} + +int CString::indexOf(const char *s) const { + const char *strP = strstr(c_str(), s); + return strP ? strP - c_str() : -1; +} + +int CString::lastIndexOf(char c) const { + const char *charP = strrchr(c_str(), c); + return charP ? charP - c_str() : -1; +} + +FileType CString::fileTypeSuffix() const { + CString ext = right(1); + if (ext == "0" || ext == "4") + return FILETYPE_IMAGE; + else if (ext == "1") + return FILETYPE_WAV; + else if (ext == "2" || ext == "3") + return FILETYPE_MOVIE; + + ext = right(3); + if (ext == "tga" || ext == "jpg") + return FILETYPE_IMAGE; + else if (ext == "wav") + return FILETYPE_WAV; + else if (ext == "avi" || ext == "mov") + return FILETYPE_MOVIE; + else if (ext == "dlg") + return FILETYPE_DLG; + else + return FILETYPE_UNKNOWN; +} + +ImageType CString::imageTypeSuffix() const { + CString ext = right(1); + if (ext == "0") + return IMAGETYPE_TARGA; + else if (ext == "4") + return IMAGETYPE_JPEG; + + ext = right(3); + if (ext == "tga") + return IMAGETYPE_TARGA; + else if (ext == "jpg") + return IMAGETYPE_JPEG; + else + return IMAGETYPE_UNKNOWN; +} + +CString CString::format(const char *fmt, ...) { + String output; + + va_list va; + va_start(va, fmt); + output = String::vformat(fmt, va); + va_end(va); + + return output; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/string.h b/engines/titanic/support/string.h new file mode 100644 index 0000000000..9550ce88a7 --- /dev/null +++ b/engines/titanic/support/string.h @@ -0,0 +1,114 @@ +/* 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 TITANIC_STRING_H +#define TITANIC_STRING_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "common/str.h" + +namespace Titanic { + +enum FileType { + FILETYPE_UNKNOWN = 0, FILETYPE_IMAGE = 1, FILETYPE_MOVIE = 2, + FILETYPE_WAV = 3, FILETYPE_DLG = 4 +}; + +enum ImageType { + IMAGETYPE_UNKNOWN = 0, IMAGETYPE_TARGA = 1, IMAGETYPE_JPEG = 2 +}; + +class CString : public Common::String { +public: + CString() : Common::String() {} + CString(const char *str) : Common::String(str) {} + CString(const char *str, uint32 len) : Common::String(str, len) {} + CString(const char *beginP, const char *endP) : Common::String(beginP, endP) {} + CString(const String &str) : Common::String(str) {} + CString(char c, uint32 len); + explicit CString(char c) : Common::String(c) {} + explicit CString(int val); + + /** + * Returns the left n characters of the string + */ + CString left(uint count) const; + + /** + * Returns the right n characters of the string + */ + CString right(uint count) const; + + /** + * Returns a substring from within the string + */ + CString mid(uint start, uint count) const; + + /** + * Returns a substring from within the string + */ + CString mid(uint start) const; + + /** + * Returns the index of the first occurance of a given character + */ + int indexOf(char c) const; + + /** + * Returns the index of the first occurance of a given string + */ + int indexOf(const char *s) const; + + /** + * Returns the index of the last occurance of a given character + */ + int lastIndexOf(char c) const; + + /** + * Returns the type of a filename based on it's extension + */ + FileType fileTypeSuffix() const; + + /** + * Returns the type of an image filename based on it's extension + */ + ImageType imageTypeSuffix() const; + + /** + * Parses the string as an integer and returns the value + */ + int readInt() const { + return atoi(c_str()); + } + + /** + * Format a string + */ + static CString format(const char *fmt, ...); +}; + +typedef Common::Array<CString> StringArray; + +} // End of namespace Titanic + +#endif /* TITANIC_STRING_H */ diff --git a/engines/titanic/support/text_cursor.cpp b/engines/titanic/support/text_cursor.cpp new file mode 100644 index 0000000000..ad3fe4ed26 --- /dev/null +++ b/engines/titanic/support/text_cursor.cpp @@ -0,0 +1,88 @@ +/* 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/textconsole.h" +#include "titanic/support/text_cursor.h" +#include "titanic/support/screen_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CTextCursor::CTextCursor(CScreenManager *screenManager) : + _screenManager(screenManager), _active(false), _blinkVisible(false), + _backRenderSurface(nullptr), _frontRenderSurface(nullptr), + _blinkDelay(300), _size(2, 10), _priorBlinkTime(0), + _cursorR(0), _cursorG(0), _cursorB(0), _mode(-1) { + _surface = screenManager->createSurface(10, 10); +} + +CTextCursor::~CTextCursor() { + delete _surface; +} + +void CTextCursor::setColor(byte r, byte g, byte b) { + _cursorR = r; + _cursorG = g; + _cursorB = b; +} + +void CTextCursor::show() { + _backRenderSurface = _screenManager->getSurface(SURFACE_BACKBUFFER); + _frontRenderSurface = _screenManager->getFrontRenderSurface(); + _active = true; + _priorBlinkTime = g_vm->_events->getTicksCount(); +} + +void CTextCursor::hide() { + _active = false; +} + +void CTextCursor::draw() { + if (!_active) + return; + + // Handle updating whether the blinking cursor is visible or not + uint newTicks = g_vm->_events->getTicksCount(); + while (newTicks > (_priorBlinkTime + _blinkDelay)) { + _priorBlinkTime += _blinkDelay; + _blinkVisible = !_blinkVisible; + } + + if (_blinkVisible) { + Rect cursorRect = getCursorBounds(); + _surface->blitFrom(Common::Point(0, 0), _backRenderSurface, &cursorRect); + + if (!_screenBounds.isEmpty()) + // Limit the cursor rect to only within designated screen area + cursorRect.constrain(_screenBounds); + + if (!cursorRect.isEmpty()) { + // Draw cursor onto the screen + _backRenderSurface->_ddSurface->fillRect(&cursorRect, + _cursorR, _cursorG, _cursorB); + } + + //_screenManager->blitFrom(SURFACE_BACKBUFFER, _surface, &_pos); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/text_cursor.h b/engines/titanic/support/text_cursor.h new file mode 100644 index 0000000000..d8c6ac0653 --- /dev/null +++ b/engines/titanic/support/text_cursor.h @@ -0,0 +1,121 @@ +/* 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 TITANIC_TEXT_CURSOR_H +#define TITANIC_TEXT_CURSOR_H + +#include "common/scummsys.h" +#include "titanic/support/rect.h" + +namespace Titanic { + +class CScreenManager; +class CVideoSurface; + +class CTextCursor { +private: + CScreenManager *_screenManager; + CVideoSurface *_backRenderSurface; + CVideoSurface *_frontRenderSurface; + Point _pos; + Rect _screenBounds; + uint _blinkDelay; + bool _blinkVisible; + Point _size; + Point _screenTopLeft; + uint _priorBlinkTime; + byte _cursorR; + byte _cursorG; + byte _cursorB; + CVideoSurface *_surface; + int _mode; +public: + bool _active; +public: + CTextCursor(CScreenManager *screenManager); + ~CTextCursor(); + + /** + * Sets the position of the cursor + */ + void setPos(const Point &pt) { _pos = pt; } + + /** + * Sets the size of the cursor + */ + void setSize(const Point &size) { _size = size; } + + /** + * Returns the bounds for the cursor + */ + Rect getCursorBounds() const { + return Rect(_pos.x, _pos.y, _pos.x + _size.x, _pos.y + _size.y); + } + + /** + * Set bounds + */ + void setBounds(const Rect &r) { _screenBounds = r; } + + /** + * Clear the bounds + */ + void clearBounds() { _screenBounds.clear(); } + + /** + * Set the blinking rate + */ + void setBlinkRate(uint ticks) { _blinkDelay = ticks; } + + /** + * Set the cursor color + */ + void setColor(byte r, byte g, byte b); + + /** + * Returns whether the text cursor is active + */ + bool isActive() const { return _active; } + + int getMode() const { return _mode; } + + void setMode(int mode) { _mode = mode; } + + /** + * Show the text cursor + */ + void show(); + + /** + * Hide the text cursor + */ + void hide(); + + /** + * Update and draw the cursor if necessary + */ + void draw(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TEXT_CURSOR_H */ diff --git a/engines/titanic/support/time_event_info.cpp b/engines/titanic/support/time_event_info.cpp new file mode 100644 index 0000000000..0226223f1a --- /dev/null +++ b/engines/titanic/support/time_event_info.cpp @@ -0,0 +1,206 @@ +/* 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 "titanic/support/time_event_info.h" +#include "titanic/core/game_object.h" +#include "titanic/core/project_item.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +void CTimeEventInfoList::postLoad(uint ticks, CProjectItem *project) { + for (iterator i = begin(); i != end(); ++i) + (*i)->postLoad(ticks, project); +} + +void CTimeEventInfoList::preSave(uint ticks) { + for (iterator i = begin(); i != end(); ++i) + (*i)->preSave(ticks); +} + +void CTimeEventInfoList::postSave() { + for (iterator i = begin(); i != end(); ++i) + (*i)->postSave(); +} + +void CTimeEventInfoList::update(uint ticks) { + // Remove any items that are done + for (iterator i = begin(); i != end(); ) { + CTimeEventInfo *item = *i; + if (item->_done) { + i = erase(i); + delete item; + } else { + ++i; + } + } + + // Handle updating the items + for (iterator i = begin(); i != end(); ) { + CTimeEventInfo *item = *i; + if (!item->update(ticks)) { + ++i; + } else { + i = erase(i); + delete item; + } + } +} + +void CTimeEventInfoList::stop(uint id) { + for (iterator i = begin(); i != end(); ++i) { + CTimeEventInfo *item = *i; + if (item->_id == id) { + item->_done = true; + return; + } + } +} + +void CTimeEventInfoList::setPersisent(uint id, bool flag) { + for (iterator i = begin(); i != end(); ++i) { + CTimeEventInfo *item = *i; + if (item->_id == id) { + item->setPersisent(flag); + return; + } + } +} + +/*------------------------------------------------------------------------*/ + +uint CTimeEventInfo::_nextId; + +CTimeEventInfo::CTimeEventInfo() : ListItem(), _lockCounter(0), + _repeated(false), _firstDuration(0), _repeatDuration(0), + _target(nullptr), _actionVal(0), _timerCtr(0), _done(false), + _lastTimerTicks(0), _relativeTicks(0), _persisent(true) { + _id = _nextId++; +} + +CTimeEventInfo::CTimeEventInfo(uint ticks, bool repeated, uint firstDuration, + uint repeatDuration, CTreeItem *target, int endVal, const CString &action) : + ListItem(), _lockCounter(0), _repeated(repeated), _firstDuration(firstDuration), + _repeatDuration(repeatDuration), _target(target), _actionVal(endVal), _done(false), + _timerCtr(0), _lastTimerTicks(ticks), _relativeTicks(0), _persisent(true) { + _id = _nextId++; +} + +void CTimeEventInfo::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + + CString targetName; + if (_target) + targetName = _target->getName(); + file->writeQuotedLine(targetName, indent); + file->writeNumberLine(_id, indent); + file->writeNumberLine(_repeated, indent); + file->writeNumberLine(_firstDuration, indent); + file->writeNumberLine(_repeatDuration, indent); + file->writeNumberLine(_actionVal, indent); + file->writeQuotedLine(_action, indent); + file->writeNumberLine(_timerCtr, indent); + file->writeNumberLine(_relativeTicks, indent); + file->writeNumberLine(_done, indent); + file->writeNumberLine(_persisent, indent); +} + +void CTimeEventInfo::load(SimpleFile *file) { + lock(); + int val = file->readNumber(); + + if (!val) { + _targetName = file->readString(); + _id = file->readNumber(); + _repeated = file->readNumber(); + _firstDuration = file->readNumber(); + _repeatDuration = file->readNumber(); + _actionVal = file->readNumber(); + _action = file->readString(); + _timerCtr = file->readNumber(); + _relativeTicks = file->readNumber(); + _done = file->readNumber() != 0; + _persisent = file->readNumber() != 0; + _target = nullptr; + } +} + +void CTimeEventInfo::postLoad(uint ticks, CProjectItem *project) { + if (!_persisent || _targetName.empty()) + _done = true; + + // Get the timer's target + if (project) + _target = project->findByName(_targetName); + if (!_target) + _done = true; + + _lastTimerTicks = ticks + _relativeTicks; + if (_id >= _nextId) + _nextId = _id + 1; + + unlock(); +} + +void CTimeEventInfo::preSave(uint ticks) { + _relativeTicks = _lastTimerTicks - ticks; + lock(); +} + +void CTimeEventInfo::postSave() { + unlock(); +} + +bool CTimeEventInfo::update(uint ticks) { + if (_lockCounter) + return false; + + if (_timerCtr) { + if (ticks > (_lastTimerTicks + _repeatDuration)) { + ++_timerCtr; + _lastTimerTicks = ticks; + + if (_target) { + CTimerMsg timerMsg(ticks, _timerCtr, _actionVal, _action); + timerMsg.execute(_target); + } + } + } else { + if (ticks > (_lastTimerTicks + _firstDuration)) { + _timerCtr = 1; + _lastTimerTicks = ticks; + + if (_target) { + CTimerMsg timerMsg(ticks, _timerCtr, _actionVal, _action); + timerMsg.execute(_target); + } + + if (!_repeated) + // Event is done, and can be removed + return true; + } + } + + return false; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/time_event_info.h b/engines/titanic/support/time_event_info.h new file mode 100644 index 0000000000..ebf5b54458 --- /dev/null +++ b/engines/titanic/support/time_event_info.h @@ -0,0 +1,138 @@ +/* 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 TITANIC_TIMER_H +#define TITANIC_TIMER_H + +#include "common/algorithm.h" +#include "titanic/core/list.h" + +namespace Titanic { + +class CTreeItem; +class CProjectItem; + +class CTimeEventInfo : public ListItem { +private: + /** + * Increments the counter + */ + void lock() { ++_lockCounter; } + + /** + * Called at the end of both post load and post save actions + */ + void unlock() { + _lockCounter = MAX(_lockCounter - 1, 0); + } +public: + static uint _nextId; +public: + int _lockCounter; + uint _id; + bool _repeated; + uint _firstDuration; + uint _repeatDuration; + CTreeItem *_target; + uint _actionVal; + CString _action; + uint _timerCtr; + uint _lastTimerTicks; + uint _relativeTicks; + bool _done; + bool _persisent; + CString _targetName; +public: + CLASSDEF; + CTimeEventInfo(); + CTimeEventInfo(uint ticks, bool repeated, uint firstDuration, uint repeatDuration, + CTreeItem *target, int endVal, const CString &action); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Called after loading a game has finished + */ + void postLoad(uint ticks, CProjectItem *project); + + /** + * Called when a game is about to be saved + */ + void preSave(uint ticks); + + /** + * Called when a game has finished being saved + */ + void postSave(); + + bool update(uint ticks); + + /** + * Flags whether the timer will be persisent across save & loads + */ + void setPersisent(bool val) { _persisent = val; } +}; + +class CTimeEventInfoList : public List<CTimeEventInfo> { +public: + /** + * Called after loading a game has finished + */ + void postLoad(uint ticks, CProjectItem *project); + + /** + * Called when a game is about to be saved + */ + void preSave(uint ticks); + + /** + * Called when a game has finished being saved + */ + void postSave(); + + /** + * Handles an update + */ + void update(uint ticks); + + /** + * Remove an item with the given Id + */ + void stop(uint id); + + /** + * Sets whether a timer with a given Id will be persisent across saves + */ + void setPersisent(uint id, bool flag); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TIMER_H */ diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp new file mode 100644 index 0000000000..594f660937 --- /dev/null +++ b/engines/titanic/support/video_surface.cpp @@ -0,0 +1,583 @@ +/* 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 "titanic/support/video_surface.h" +#include "titanic/support/image_decoders.h" +#include "titanic/support/screen_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +int CVideoSurface::_videoSurfaceCounter = 0; + +CVideoSurface::CVideoSurface(CScreenManager *screenManager) : + _screenManager(screenManager), _rawSurface(nullptr), _movie(nullptr), + _pendingLoad(false), _transBlitFlag(false), _fastBlitFlag(false), + _movieFrameSurface(nullptr), _transparencyMode(TRANS_DEFAULT), + _freeMovieSurface(DisposeAfterUse::NO), _hasFrame(true), _lockCount(0) { + _videoSurfaceNum = _videoSurfaceCounter++; +} + +CVideoSurface::~CVideoSurface() { + if (_ddSurface) + _videoSurfaceCounter -= freeSurface(); + --_videoSurfaceCounter; + + if (_freeMovieSurface == DisposeAfterUse::YES) + delete _movieFrameSurface; +} + +void CVideoSurface::setSurface(CScreenManager *screenManager, DirectDrawSurface *surface) { + _screenManager = screenManager; + _ddSurface = surface; +} + +void CVideoSurface::blitFrom(const Point &destPos, CVideoSurface *src, const Rect *srcRect) { + if (loadIfReady() && src->loadIfReady() && _ddSurface && src->_ddSurface) { + Rect srcBounds, destBounds; + clipBounds(srcBounds, destBounds, src, srcRect, &destPos); + + if (src->_transBlitFlag) + blitRect2(srcBounds, destBounds, src); + else + blitRect1(srcBounds, destBounds, src); + } +} + +void CVideoSurface::blitFrom(const Point &destPos, const Graphics::Surface *src) { + lock(); + _rawSurface->blitFrom(*src, destPos); + unlock(); +} + +void CVideoSurface::clipBounds(Rect &srcRect, Rect &destRect, + CVideoSurface *srcSurface, const Rect *subRect, const Point *destPos) { + // Figure out initial source rect and dest rect, based on whether + // specific subRect and/or destPos have been passed + if (destPos) { + destRect.left = destPos->x; + destRect.top = destPos->y; + } else { + destRect.left = destRect.top = 0; + } + + if (subRect) { + destRect.right = destRect.left + subRect->width(); + destRect.bottom = destRect.top + subRect->height(); + srcRect = *subRect; + } else { + srcRect.right = srcRect.left + srcSurface->getWidth(); + srcRect.bottom = srcRect.top + srcSurface->getHeight(); + srcRect = Rect(0, 0, srcSurface->getWidth(), srcSurface->getHeight()); + } + + // Clip destination rect to be on-screen + if (destRect.left < 0) { + srcRect.left -= destRect.left; + destRect.left = 0; + } + if (destRect.top < 0) { + srcRect.top -= destRect.top; + destRect.top = 0; + } + if (destRect.right > getWidth()) { + srcRect.right += getWidth() - destRect.right; + destRect.right = getWidth(); + } + if (destRect.bottom > getHeight()) { + srcRect.bottom += getHeight() - destRect.bottom; + destRect.bottom = getHeight(); + } + + // Clip source rect to be within the source surface + if (srcRect.left < 0) { + destRect.left -= srcRect.left; + srcRect.left = 0; + } + if (srcRect.top < 0) { + destRect.top -= srcRect.top; + srcRect.top = 0; + } + if (srcRect.right > srcSurface->getWidth()) { + destRect.right += srcSurface->getWidth() - srcRect.right; + srcRect.right = srcSurface->getWidth(); + } + if (srcRect.bottom > srcSurface->getHeight()) { + destRect.bottom += srcSurface->getHeight() - srcRect.bottom; + srcRect.bottom = srcSurface->getHeight(); + } + + // Validate that the resulting rects are valid + if (destRect.left >= destRect.right || destRect.top >= destRect.bottom + || srcRect.left >= srcRect.right || srcRect.top >= srcRect.bottom) + error("Invalid rect"); +} + +void CVideoSurface::blitRect1(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { + src->lock(); + lock(); + + if (src->_fastBlitFlag) { + _rawSurface->blitFrom(*src->_rawSurface, srcRect, Point(destRect.left, destRect.top)); + } else if (getMovieFrameSurface()) { + movieBlitRect(srcRect, destRect, src); + } else { + _rawSurface->transBlitFrom(*src->_rawSurface, srcRect, destRect, src->getTransparencyColor()); + } + + src->unlock(); + unlock(); +} + +void CVideoSurface::blitRect2(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { + if (getMovieFrameSurface()) { + movieBlitRect(srcRect, destRect, src); + } else { + src->lock(); + lock(); + + _rawSurface->blitFrom(*src->_rawSurface, srcRect, Point(destRect.left, destRect.top)); + + src->unlock(); + unlock(); + } +} + +void CVideoSurface::movieBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { + // TODO +} + +uint CVideoSurface::getTransparencyColor() { + uint32 val = -(getPixelDepth() - 2); + val &= 0xFFFF8400; + val += 0xF81F; + return val; +} + +bool CVideoSurface::hasFrame() { + if (_hasFrame) { + _hasFrame = false; + return true; + } else if (_movie) { + return _movie->hasVideoFrame(); + } else { + return false; + } +} + +/*------------------------------------------------------------------------*/ + +byte OSVideoSurface::_palette1[32][32]; +byte OSVideoSurface::_palette2[32][32]; + +OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface) : + CVideoSurface(screenManager) { + _ddSurface = surface; +} + +OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, const CResourceKey &key, bool pendingLoad) : + CVideoSurface(screenManager) { + _ddSurface = nullptr; + _pendingLoad = pendingLoad; + + if (_pendingLoad) { + loadResource(key); + } else { + _resourceKey = key; + load(); + } +} + +void OSVideoSurface::setupPalette(byte palette[32][32], byte val) { + for (uint idx1 = 0; idx1 < 32; ++idx1) { + for (uint idx2 = 0, base = 0; idx2 < 32; ++idx2, base += idx1) { + int64 v = 0x84210843; + v *= base; + uint v2 = (v >> 36); + v = ((v2 >> 31) + v2) & 0xff; + palette[idx1][idx2] = v << 3; + + if (val != 0xff && v != idx2) { + v = 0x80808081 * v * val; + v2 = v >> 39; + palette[idx1][idx2] = ((v2 >> 31) + v2) << 3; + } + } + } +} + +void OSVideoSurface::loadResource(const CResourceKey &key) { + _resourceKey = key; + _pendingLoad = true; + + if (hasSurface()) + load(); +} + +void OSVideoSurface::loadTarga(const CResourceKey &key) { + // Decode the image + CTargaDecode decoder; + decoder.decode(*this, key.getString()); + + if (getPixelDepth() == 2) + shiftColors(); + + _resourceKey = key; + +} + +void OSVideoSurface::loadJPEG(const CResourceKey &key) { + // Decode the image + CJPEGDecode decoder; + decoder.decode(*this, key.getString()); + + if (getPixelDepth() == 2) + shiftColors(); + + _resourceKey = key; +} + +void OSVideoSurface::loadTarga(const CString &name) { + CResourceKey key(name); + loadTarga(key); +} + +void OSVideoSurface::loadMovie(const CResourceKey &key, bool destroyFlag) { + // Delete any prior movie + if (_movie) { + delete _movie; + _movie = nullptr; + } + + // Create the new movie and load the first frame to the video surface + _movie = g_vm->_movieManager.createMovie(key, this); + _movie->setFrame(0); + + // If flagged to destroy, then immediately destroy movie instance + if (destroyFlag) { + delete _movie; + _movie = nullptr; + } + + _resourceKey = key; +} + +bool OSVideoSurface::lock() { + if (!loadIfReady()) + return false; + + ++_lockCount; + _rawSurface = _ddSurface->lock(nullptr, 0); + return true; +} + +void OSVideoSurface::unlock() { + if (!--_lockCount) { + if (_rawSurface) + _ddSurface->unlock(); + _rawSurface = nullptr; + } +} + +bool OSVideoSurface::hasSurface() { + return _ddSurface != nullptr; +} + +int OSVideoSurface::getWidth() { + if (!loadIfReady()) + error("Could not load resource"); + + return _ddSurface->getWidth(); +} + +int OSVideoSurface::getHeight() { + if (!loadIfReady()) + error("Could not load resource"); + + return _ddSurface->getHeight(); +} + +int OSVideoSurface::getPitch() { + if (!loadIfReady()) + error("Could not load resource"); + + return _ddSurface->getPitch(); +} + +int OSVideoSurface::getBpp() { + if (!loadIfReady()) + error("Could not load resource"); + + return getPixelDepth(); +} + +void OSVideoSurface::recreate(int width, int height) { + freeSurface(); + + _screenManager->resizeSurface(this, width, height); + if (_ddSurface) + _videoSurfaceCounter += _ddSurface->getSize(); +} + +void OSVideoSurface::resize(int width, int height) { + if (!_ddSurface || _ddSurface->getWidth() != width || + _ddSurface->getHeight() != height) + recreate(width, height); +} + +void OSVideoSurface::detachSurface() { + _ddSurface = nullptr; +} + +int OSVideoSurface::getPixelDepth() { + if (!loadIfReady()) + error("Could not load resource"); + + lock(); + + int result = _rawSurface->format.bytesPerPixel; + if (result == 1) + // Paletted 8-bit images don't store the color directly in the pixels + result = 0; + + unlock(); + return result; +} + +bool OSVideoSurface::load() { + if (!_resourceKey.scanForFile()) + return false; + + switch (_resourceKey.fileTypeSuffix()) { + case FILETYPE_IMAGE: + switch (_resourceKey.imageTypeSuffix()) { + case IMAGETYPE_TARGA: + loadTarga(_resourceKey); + break; + case IMAGETYPE_JPEG: + loadJPEG(_resourceKey); + break; + default: + break; + } + return true; + + case FILETYPE_MOVIE: + loadMovie(_resourceKey); + return true; + + default: + return false; + } +} + +uint16 OSVideoSurface::getPixel(const Common::Point &pt) { + if (!loadIfReady()) + return 0; + + if (pt.x >= 0 && pt.y >= 0 && pt.x < getWidth() && pt.y < getHeight()) { + lock(); + uint16 pixel = *(uint16 *)_rawSurface->getBasePtr(pt.x, pt.y); + unlock(); + return pixel; + } else { + return getTransparencyColor(); + } +} + +void OSVideoSurface::setPixel(const Point &pt, uint pixel) { + assert(getPixelDepth() == 2); + + uint16 *pixelP = (uint16 *)_rawSurface->getBasePtr(pt.x, pt.y); + *pixelP = pixel; +} + +void OSVideoSurface::changePixel(uint16 *pixelP, uint16 *color, byte srcVal, bool remapFlag) { + assert(getPixelDepth() == 2); + const Graphics::PixelFormat &destFormat = _ddSurface->getFormat(); + const Graphics::PixelFormat srcFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); + + // Get the color + byte r, g, b; + srcFormat.colorToRGB(*color, r, g, b); + if (remapFlag) { + r = _palette1[31 - srcVal][r >> 3]; + g = _palette1[31 - srcVal][g >> 3]; + b = _palette1[31 - srcVal][b >> 3]; + } + + byte r2, g2, b2; + destFormat.colorToRGB(*pixelP, r2, g2, b2); + r2 = _palette1[srcVal][r2 >> 3]; + g2 = _palette1[srcVal][g2 >> 3]; + b2 = _palette1[srcVal][b2 >> 3]; + + *pixelP = destFormat.RGBToColor(r + r2, g + g2, b + b2); +} + +void OSVideoSurface::shiftColors() { + if (!loadIfReady()) + return; + + // Currently no further processing is needed, since for ScummVM, + // we already convert 16-bit surfaces as soon as they're loaded +} + +void OSVideoSurface::clear() { + if (!loadIfReady()) + error("Could not load resource"); + +} + +void OSVideoSurface::playMovie(uint flags, CGameObject *obj) { + if (loadIfReady() && _movie) + _movie->play(flags, obj); + + _ddSurface->fill(nullptr, 0); +} + +void OSVideoSurface::playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj) { + if (loadIfReady() && _movie) { + _movie->play(startFrame, endFrame, flags, obj); + } +} + +void OSVideoSurface::playMovie(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) { + if (loadIfReady() && _movie) { + _movie->play(startFrame, endFrame, initialFrame, flags, obj); + } +} + +void OSVideoSurface::stopMovie() { + if (_movie) + _movie->stop(); +} + +void OSVideoSurface::setMovieFrame(uint frameNumber) { + if (loadIfReady() && _movie) + _movie->setFrame(frameNumber); +} + +void OSVideoSurface::addMovieEvent(int frameNumber, CGameObject *obj) { + if (_movie) + _movie->addEvent(frameNumber, obj); +} + +void OSVideoSurface::setMovieFrameRate(double rate) { + if (_movie) + _movie->setFrameRate(rate); +} + +const CMovieRangeInfoList *OSVideoSurface::getMovieRangeInfo() const { + return _movie ? _movie->getMovieRangeInfo() : nullptr; +} + +void OSVideoSurface::flipVertically(bool needsLock) { + if (!loadIfReady() || !_transBlitFlag) + return; + + if (needsLock) + lock(); + + byte lineBuffer[SCREEN_WIDTH * 2]; + int pitch = getBpp() * getWidth(); + assert(pitch < (SCREEN_WIDTH * 2)); + + for (int yp = 0; yp < (_rawSurface->h / 2); ++yp) { + byte *line1P = (byte *)_rawSurface->getBasePtr(0, yp); + byte *line2P = (byte *)_rawSurface->getBasePtr(0, _rawSurface->h - yp - 1); + + Common::copy(line1P, line1P + pitch, lineBuffer); + Common::copy(line2P, line2P + pitch, line1P); + Common::copy(lineBuffer, lineBuffer + pitch, line1P); + } + + _transBlitFlag = false; + if (needsLock) + unlock(); +} + +bool OSVideoSurface::loadIfReady() { + _videoSurfaceNum = _videoSurfaceCounter; + + if (hasSurface()) { + return true; + } else if (_pendingLoad) { + _hasFrame = true; + load(); + return true; + } else { + return false; + } +} + +void OSVideoSurface::transPixelate() { + if (!loadIfReady()) + return; + + lock(); + Graphics::ManagedSurface *surface = _rawSurface; + uint transColor = getTransparencyColor(); + // TODO: Check whether color is correct + uint pixelColor = surface->format.RGBToColor(0x50, 0, 0); + + for (int yp = 0; yp < surface->h; ++yp) { + uint16 *pixelsP = (uint16 *)surface->getBasePtr(0, yp); + bool bitFlag = (yp % 2) == 0; + int replaceCtr = yp & 3; + + for (int xp = 0; xp < surface->w; ++xp, ++pixelsP) { + if (bitFlag && *pixelsP == transColor && replaceCtr == 0) + *pixelsP = pixelColor; + + bitFlag = !bitFlag; + replaceCtr = (replaceCtr + 1) & 3; + } + } + + surface->markAllDirty(); + unlock(); +} + +Graphics::ManagedSurface *OSVideoSurface::dupMovieFrame() const { + return _movie ? _movie->duplicateFrame() : nullptr; +} + +int OSVideoSurface::freeSurface() { + if (!_ddSurface) + return 0; + int surfaceSize = _ddSurface->getSize(); + + delete _movie; + _movie = nullptr; + delete _ddSurface; + _ddSurface = nullptr; + + return surfaceSize; +} + +uint16 *OSVideoSurface::getBasePtr(int x, int y) { + assert(_rawSurface); + return (uint16 *)_rawSurface->getBasePtr(x, y); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h new file mode 100644 index 0000000000..053eabb0f9 --- /dev/null +++ b/engines/titanic/support/video_surface.h @@ -0,0 +1,537 @@ +/* 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 TITANIC_VIDEO_SURFACE_H +#define TITANIC_VIDEO_SURFACE_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "graphics/managed_surface.h" +#include "titanic/support/font.h" +#include "titanic/support/direct_draw.h" +#include "titanic/support/movie.h" +#include "titanic/support/movie_range_info.h" +#include "titanic/support/rect.h" +#include "titanic/core/list.h" +#include "titanic/core/resource_key.h" + +namespace Titanic { + +enum TransparencyMode { + TRANS_MASK0 = 0, TRANS_MASK255 = 1, TRANS_ALPHA0 = 2, + TRANS_ALPHA255 = 3, TRANS_DEFAULT = 4 +}; + +class CScreenManager; +class CJPEGDecode; +class CTargaDecode; + +class CVideoSurface : public ListItem { + friend class CJPEGDecode; + friend class CTargaDecode; +private: + /** + * Calculates blitting bounds + */ + void clipBounds(Rect &srcRect, Rect &destRect, CVideoSurface *srcSurface, + const Rect *subRect = nullptr, const Point *destPos = nullptr); + + void blitRect1(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); + void blitRect2(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); + void movieBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); +protected: + static int _videoSurfaceCounter; +protected: + CScreenManager *_screenManager; + Graphics::ManagedSurface *_rawSurface; + bool _pendingLoad; + Graphics::ManagedSurface *_movieFrameSurface; + DisposeAfterUse::Flag _freeMovieSurface; + int _videoSurfaceNum; + bool _hasFrame; + int _lockCount; +public: + CMovie *_movie; + DirectDrawSurface *_ddSurface; + bool _fastBlitFlag; + bool _transBlitFlag; + CResourceKey _resourceKey; + TransparencyMode _transparencyMode; +public: + CVideoSurface(CScreenManager *screenManager); + virtual ~CVideoSurface(); + + /** + * Set the underlying surface for this video surface + */ + void setSurface(CScreenManager *screenManager, DirectDrawSurface *surface); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file) { + ListItem::load(file); + } + + /** + * Load the surface with the passed resource + */ + virtual void loadResource(const CResourceKey &key) = 0; + + /** + * Loads a Targa image file specified by the resource key + */ + virtual void loadTarga(const CResourceKey &key) = 0; + + /** + * Loads a JPEG image file specified by the resource key + */ + virtual void loadJPEG(const CResourceKey &key) = 0; + + /** + * Loads a Targa image file specified by the given name + */ + virtual void loadTarga(const CString &name) = 0; + + /** + * Loads a movie file specified by the resource key. + * @param key Resource key for movie to load + * @param destroyFlag Immediately destroy movie after decoding first frame + */ + virtual void loadMovie(const CResourceKey &key, bool destroyFlag = false) = 0; + + /** + * Lock the surface for direct access to the pixels + */ + virtual bool lock() = 0; + + /** + * Unlocks the surface after prior calls to lock() + */ + virtual void unlock() = 0; + + /** + * Returns true if an underlying raw surface has been set + */ + virtual bool hasSurface() = 0; + + /** + * Returns the width of the surface + */ + virtual int getWidth() = 0; + + /** + * Returns the height of the surface + */ + virtual int getHeight() = 0; + + /** + * Returns the pitch of the surface in bytes + */ + virtual int getPitch() = 0; + + /** + * Returns the bytes per pixel of the surface + */ + virtual int getBpp() = 0; + + /** + * Recreates the surface + */ + virtual void recreate(int width, int height) = 0; + + /** + * Resizes the surface + */ + virtual void resize(int width, int height) = 0; + + /** + * Detachs the underlying raw surface + */ + virtual void detachSurface() = 0; + + /** + * Returns the number of bytes per pixel in the surface + */ + virtual int getPixelDepth() = 0; + + /** + * Gets the pixel at the specified position within the surface + */ + virtual uint16 getPixel(const Common::Point &pt) = 0; + + + /** + * Sets a pixel at a specified position within the surface + */ + virtual void setPixel(const Point &pt, uint pixel) = 0; + + /** + * Change a pixel + */ + virtual void changePixel(uint16 *pixelP, uint16 *color, byte srcVal, bool remapFlag = true) = 0; + + /** + * Shifts the colors of the surface.. maybe greys it out? + */ + virtual void shiftColors() = 0; + + /** + * Clears the entire surface to black + */ + virtual void clear() = 0; + + /** + * Plays a movie, loading it from the specified _resource + * if not already loaded + */ + virtual void playMovie(uint flags, CGameObject *obj) = 0; + + /** + * Plays a movie, loading it from the specified _resource + * if not already loaded + */ + virtual void playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj) = 0; + + /** + * Plays a movie, loading it from the specified _resource + * if not already loaded + */ + virtual void playMovie(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) = 0; + + /** + * Stops any movie currently attached to the surface + */ + virtual void stopMovie() = 0; + + /** + * Set the current movie frame number + */ + virtual void setMovieFrame(uint frameNumber) = 0; + + /** + * Adds a movie playback event + */ + virtual void addMovieEvent(int eventId, CGameObject *obj) = 0; + + /** + * Set the movie frame rate + */ + virtual void setMovieFrameRate(double rate) = 0; + + /** + * Return any movie range info associated with the surface's movie + */ + virtual const CMovieRangeInfoList *getMovieRangeInfo() const = 0; + + /** + * + */ + virtual void flipVertically(bool needsLock = true) = 0; + + /** + * Loads the surface's resource if there's one pending + */ + virtual bool loadIfReady() = 0; + + /** + * Loads the surface data based on the currently set resource key + */ + virtual bool load() = 0; + + /** + * Does a replacement of transparent pixels on certain lines at regular + * intervals. This is totally weird + */ + virtual void transPixelate() = 0; + + /** + * Returns true if there's a frame to display on the video surface + */ + virtual bool hasFrame(); + + /** + * Duplicates movie frame surface + */ + virtual Graphics::ManagedSurface *dupMovieFrame() const = 0; + + /** + * Frees the underlying surface + */ + virtual int freeSurface() { return 0; } + + /** + * Get a pointer into the underlying surface + */ + virtual uint16 *getBasePtr(int x, int y) = 0; + + /** + * Blit from another surface + */ + void blitFrom(const Point &destPos, CVideoSurface *src, const Rect *srcRect = nullptr); + + /** + * Blit from another surface + */ + void blitFrom(const Point &destPos, const Graphics::Surface *src); + + /** + * Sets the movie frame surface containing frame data from an active movie + */ + void setMovieFrameSurface(Graphics::ManagedSurface *frameSurface) { _movieFrameSurface = frameSurface; } + + /** + * Get the previously set movie frame surface + */ + Graphics::ManagedSurface *getMovieFrameSurface() const { return _movieFrameSurface; } + + /** + * Get the pixels associated with the surface. Only valid when the + * surface has been locked for access + */ + uint16 *getPixels() { return (uint16 *)_rawSurface->getPixels(); } + + /** + * Get a reference to the underlying surface. Only valid when the surface + * has been locked for access + */ + Graphics::ManagedSurface *getRawSurface() { return _rawSurface; } + + /** + * Returns the transparent color + */ + uint getTransparencyColor(); +}; + +class OSVideoSurface : public CVideoSurface { + friend class OSMovie; +private: + static byte _palette1[32][32]; + static byte _palette2[32][32]; + + /** + * Setup the shading palettes + */ + static void setupPalette(byte palette[32][32], byte val); +public: + /** + * Setup statics + */ + static void setup() { + setupPalette(_palette1, 0xff); + setupPalette(_palette2, 0xe0); + } +public: + OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface); + OSVideoSurface(CScreenManager *screenManager, const CResourceKey &key, bool flag = false); + + /** + * Load the surface with the passed resource + */ + virtual void loadResource(const CResourceKey &key); + + /** + * Loads a Targa image file specified by the resource key + */ + virtual void loadTarga(const CResourceKey &key); + + /** + * Loads a JPEG image file specified by the resource key + */ + virtual void loadJPEG(const CResourceKey &key); + + /** + * Loads a Targa image file specified by the given name + */ + virtual void loadTarga(const CString &name); + + /** + * Loads a movie file specified by the resource key. + * @param key Resource key for movie to load + * @param destroyFlag Immediately destroy movie after decoding first frame + */ + virtual void loadMovie(const CResourceKey &key, bool destroyFlag = false); + + /** + * Lock the surface for direct access to the pixels + */ + virtual bool lock(); + + /** + * Unlocks the surface after prior calls to lock() + */ + virtual void unlock(); + + /** + * Returns true if an underlying raw surface has been set + */ + virtual bool hasSurface(); + + /** + * Returns the width of the surface + */ + virtual int getWidth(); + + /** + * Returns the height of the surface + */ + virtual int getHeight(); + + /** + * Returns the pitch of the surface in bytes + */ + virtual int getPitch(); + + /** + * Returns the bytes per pixel of the surface + */ + virtual int getBpp(); + + /** + * Recreates the surface with the designated size + */ + virtual void recreate(int width, int height); + + /** + * Resizes the surface + */ + virtual void resize(int width, int height); + + /** + * Detachs the underlying raw surface + */ + virtual void detachSurface(); + + /** + * Returns the number of bytes per pixel in the surface + */ + virtual int getPixelDepth(); + + /** + * Gets the pixel at the specified position within the surface + */ + virtual uint16 getPixel(const Point &pt); + + /** + * Sets a pixel at a specified position within the surface + */ + virtual void setPixel(const Point &pt, uint pixel); + + /** + * Change a pixel + */ + virtual void changePixel(uint16 *pixelP, uint16 *color, byte srcVal, bool remapFlag = true); + + /** + * Shifts the colors of the surface.. maybe greys it out? + */ + virtual void shiftColors(); + + /** + * Clears the entire surface to black + */ + virtual void clear(); + + /** + * Plays a movie, loading it from the specified _resource + * if not already loaded + */ + virtual void playMovie(uint flags, CGameObject *obj); + + /** + * Plays a movie, loading it from the specified _resource + * if not already loaded + */ + virtual void playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj); + + /** + * Plays a movie, loading it from the specified _resource + * if not already loaded + */ + virtual void playMovie(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj); + + /** + * Stops any movie currently attached to the surface + */ + virtual void stopMovie(); + + /** + * Sets the movie to the specified frame number + */ + virtual void setMovieFrame(uint frameNumber); + + /** + * Adds a movie playback event + */ + virtual void addMovieEvent(int frameNumber, CGameObject *obj); + + /** + * Set the movie frame rate + */ + virtual void setMovieFrameRate(double rate); + + /** + * Return any movie range info associated with the surface's movie + */ + virtual const CMovieRangeInfoList *getMovieRangeInfo() const; + + /** + * + */ + virtual void flipVertically(bool needsLock = true); + + /** + * Loads the surface's resource if there's one pending + */ + virtual bool loadIfReady(); + + /** + * Loads the surface data based on the currently set resource key + */ + virtual bool load(); + + /** + * Does a replacement of transparent pixels on certain lines at regular + * intervals. This is totally weird + */ + virtual void transPixelate(); + + /** + * Duplicates movie frame surface + */ + virtual Graphics::ManagedSurface *dupMovieFrame() const; + + + /** + * Frees the underlying surface + */ + virtual int freeSurface(); + + /** + * Get a pointer into the underlying surface + */ + virtual uint16 *getBasePtr(int x, int y); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_VIDEO_SURFACE_H */ diff --git a/engines/titanic/titanic.cpp b/engines/titanic/titanic.cpp new file mode 100644 index 0000000000..af894d6997 --- /dev/null +++ b/engines/titanic/titanic.cpp @@ -0,0 +1,216 @@ +/* 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/scummsys.h" +#include "common/archive.h" +#include "common/config-manager.h" +#include "common/debug-channels.h" +#include "common/events.h" +#include "engines/util.h" +#include "graphics/scaler.h" +#include "graphics/thumbnail.h" +#include "titanic/titanic.h" +#include "titanic/debugger.h" +#include "titanic/carry/hose.h" +#include "titanic/core/saveable_object.h" +#include "titanic/game/get_lift_eye2.h" +#include "titanic/game/television.h" +#include "titanic/game/parrot/parrot_lobby_object.h" +#include "titanic/game/sgt/sgt_navigation.h" +#include "titanic/game/sgt/sgt_state_room.h" +#include "titanic/moves/enter_exit_first_class_state.h" +#include "titanic/moves/enter_exit_sec_class_mini_lift.h" +#include "titanic/moves/exit_pellerator.h" +#include "titanic/support/simple_file.h" +#include "titanic/true_talk/tt_npc_script.h" + +namespace Titanic { + +TitanicEngine *g_vm; + +TitanicEngine::TitanicEngine(OSystem *syst, const TitanicGameDescription *gameDesc) + : _gameDescription(gameDesc), Engine(syst), _randomSource("Titanic") { + g_vm = this; + _debugger = nullptr; + _events = nullptr; + _filesManager = nullptr; + _window = nullptr; + _screen = nullptr; + _screenManager = nullptr; + _scriptHandler = nullptr; + _script = nullptr; + CMusicRoom::_musicHandler = nullptr; +} + +TitanicEngine::~TitanicEngine() { + delete _debugger; + delete _events; + delete _screen; + delete _window; + delete _screenManager; + delete _filesManager; + CSaveableObject::freeClassList(); +} + +void TitanicEngine::initializePath(const Common::FSNode &gamePath) { + Engine::initializePath(gamePath); + SearchMan.addSubDirectoryMatching(gamePath, "assets"); +} + +void TitanicEngine::initialize() { + // Set up debug channels + DebugMan.addDebugChannel(kDebugCore, "core", "Core engine debug level"); + DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts"); + DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling"); + DebugMan.addDebugChannel(kDebugSound, "sound", "Sound and Music handling"); + + _debugger = new Debugger(this); + _filesManager = new CFilesManager(); + + CSaveableObject::initClassList(); + CEnterExitFirstClassState::init(); + CGameObject::init(); + CGetLiftEye2::init(); + CHose::init(); + CMovie::init(); + CParrotLobbyObject::init(); + CSGTNavigation::init(); + CSGTStateRoom::init(); + CExitPellerator::init(); + CEnterExitSecClassMiniLift::init(); + CTelevision::init(); + TTnpcScript::init(); + OSVideoSurface::setup(); + + _events = new Events(this); + _screen = new Graphics::Screen(0, 0); + _screenManager = new OSScreenManager(this); + _window = new CMainGameWindow(this); + + setItemNames(); + setRoomNames(); + + _window->applicationStarting(); +} + +void TitanicEngine::deinitialize() { + CEnterExitFirstClassState::deinit(); + CGetLiftEye2::deinit(); + CHose::deinit(); + CMovie::deinit(); + CSGTNavigation::deinit(); + CSGTStateRoom::deinit(); + CExitPellerator::deinit(); + CEnterExitSecClassMiniLift::deinit(); + CGameObject::deinit(); + CTelevision::deinit(); + TTnpcScript::deinit(); +} + +Common::Error TitanicEngine::run() { + initialize(); + + // Main event loop + while (!shouldQuit()) { + _events->pollEventsAndWait(); + } + + deinitialize(); + return Common::kNoError; +} + +void TitanicEngine::setItemNames() { + Common::SeekableReadStream *r; + r = g_vm->_filesManager->getResource("TEXT/ITEM_NAMES"); + while (r->pos() < r->size()) + _itemNames.push_back(readStringFromStream(r)); + delete r; + + r = g_vm->_filesManager->getResource("TEXT/ITEM_DESCRIPTIONS"); + while (r->pos() < r->size()) + _itemNames.push_back(readStringFromStream(r)); + delete r; + + r = g_vm->_filesManager->getResource("TEXT/ITEM_IDS"); + while (r->pos() < r->size()) + _itemIds.push_back(readStringFromStream(r)); + delete r; +} + +void TitanicEngine::setRoomNames() { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource("TEXT/ROOM_NAMES"); + while (r->pos() < r->size()) + _roomNames.push_back(readStringFromStream(r)); + delete r; +} + + +bool TitanicEngine::canLoadGameStateCurrently() { + return _window->_inputAllowed; +} + +bool TitanicEngine::canSaveGameStateCurrently() { + return _window->_inputAllowed; +} + +Common::Error TitanicEngine::loadGameState(int slot) { + _window->_project->loadGame(slot); + return Common::kNoError; +} + +Common::Error TitanicEngine::saveGameState(int slot, const Common::String &desc) { + _window->_project->saveGame(slot, desc); + return Common::kNoError; +} + +CString TitanicEngine::generateSaveName(int slot) { + return CString::format("%s.%03d", _targetName.c_str(), slot); +} + +CString TitanicEngine::getSavegameName(int slot) { + // Try and open up the savegame for access + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading( + generateSaveName(slot)); + + if (in) { + // Read in the savegame header data + CompressedFile file; + file.open(in); + + TitanicSavegameHeader header; + bool isValid = CProjectItem::readSavegameHeader(&file, header); + if (header._thumbnail) { + header._thumbnail->free(); + delete header._thumbnail; + } + + file.close(); + + if (isValid) + // Set the name text + return header._saveName; + } + + return CString(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/titanic.h b/engines/titanic/titanic.h new file mode 100644 index 0000000000..3c71f68b6e --- /dev/null +++ b/engines/titanic/titanic.h @@ -0,0 +1,183 @@ +/* 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 TITANIC_TITANIC_H +#define TITANIC_TITANIC_H + +#include "common/scummsys.h" +#include "common/random.h" +#include "common/str-array.h" +#include "common/system.h" +#include "common/serializer.h" +#include "engines/advancedDetector.h" +#include "engines/engine.h" +#include "graphics/screen.h" +#include "titanic/debugger.h" +#include "titanic/events.h" +#include "titanic/support/files_manager.h" +#include "titanic/main_game_window.h" +#include "titanic/support/exe_resources.h" +#include "titanic/support/movie_manager.h" +#include "titanic/support/screen_manager.h" +#include "titanic/support/string.h" +#include "titanic/true_talk/tt_script_base.h" + +/** + * This is the namespace of the Titanic engine. + * + * Status of this engine: In Development + * + * Games using this engine: + * - Starship Titanic + */ +namespace Titanic { + +enum TitanicDebugChannels { + kDebugCore = 1 << 0, + kDebugScripts = 1 << 1, + kDebugGraphics = 1 << 2, + kDebugSound = 1 << 3 +}; + +enum Season { + SPRING = 0, + SUMMER = 1, + AUTUMN = 2, + WINTER = 3 +}; + +#define TITANIC_SAVEGAME_VERSION 1 + +#define SCREEN_WIDTH 640 +#define SCREEN_HEIGHT 480 + +#define ERROR_BASIC 1 +#define ERROR_INTERMEDIATE 2 +#define ERROR_DETAILED 3 + +#define TOTAL_ITEMS 46 +#define TOTAL_ROOMS 34 + +#define MAX_SAVES 99 + +struct TitanicGameDescription; +class TitanicEngine; + +class TitanicEngine : public Engine { +private: + /** + * Handles basic initialization + */ + void initialize(); + + /** + * Handles game deinitialization + */ + void deinitialize(); + + /** + * Sets up the item names, short, and long descriptions + */ + void setItemNames(); + + /** + * Sets up the list of room names + */ + void setRoomNames(); +protected: + const TitanicGameDescription *_gameDescription; + int _loadSaveSlot; + + // Engine APIs + virtual void initializePath(const Common::FSNode &gamePath); + virtual Common::Error run(); + virtual bool hasFeature(EngineFeature f) const; +public: + Debugger *_debugger; + Events *_events; + CFilesManager *_filesManager; + CMovieManager _movieManager; + Graphics::Screen *_screen; + OSScreenManager *_screenManager; + CMainGameWindow *_window; + Common::RandomSource _randomSource; + CScriptHandler *_scriptHandler; + TTscriptBase *_script; + CTrueTalkManager *_trueTalkManager; + CExeResources _exeResources; + StringArray _itemNames; + StringArray _itemDescriptions; + CString _itemObjects[TOTAL_ITEMS]; + StringArray _itemIds; + StringArray _roomNames; +public: + TitanicEngine(OSystem *syst, const TitanicGameDescription *gameDesc); + virtual ~TitanicEngine(); + + + /** + * Returns true if a savegame can be loaded + */ + virtual bool canLoadGameStateCurrently(); + + /** + * Returns true if the game can be saved + */ + virtual bool canSaveGameStateCurrently(); + + /** + * Called by the GMM to load a savegame + */ + virtual Common::Error loadGameState(int slot); + + /** + * Called by the GMM to save the game + */ + virtual Common::Error saveGameState(int slot, const Common::String &desc); + + uint32 getFeatures() const; + bool isDemo() const; + Common::Language getLanguage() const; + + /** + * Gets a random number + */ + uint getRandomNumber(uint max) { return _randomSource.getRandomNumber(max); } + + /** + * Support method that generates a savegame name + * @param slot Slot number + */ + CString generateSaveName(int slot); + + /** + * Checks whether a savegame exists for the given slot, + * and if it exists, returns it's description + */ + CString getSavegameName(int slot); +}; + +extern TitanicEngine *g_vm; + +} // End of namespace Titanic + +#endif /* TITANIC_TITANIC_H */ diff --git a/engines/titanic/true_talk/barbot_script.cpp b/engines/titanic/true_talk/barbot_script.cpp new file mode 100644 index 0000000000..b327c3647e --- /dev/null +++ b/engines/titanic/true_talk/barbot_script.cpp @@ -0,0 +1,1200 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/barbot_script.h" +#include "titanic/true_talk/true_talk_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +static const int STATE_ARRAY[7] = { + 0xCAB0, 0xCAB2, 0xCAB3, 0xCAB4, 0xCAB5, 0xCAB6, 0xCAB7 +}; + +static const uint ARRAY1[] = { + 0, 50033, 50044, 50045, 50046, 50047, 50048, 50049, + 50050, 50051, 50034, 50035, 50036, 50037, 50038, 50039, + 50040, 50041, 50042, 50043, 50411, 0 +}; + +static const uint ARRAY2[] = { + 51899, 51900, 51901, 51902, 51903, 51904, 51905, 51906, 51907, 0 +}; + +BarbotScript::BarbotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) : + TTnpcScript(val1, charClass, v2, charName, v3, val2, v4, v5, v6, v7) { + _state = 0; + _arrIndex = 0; + + loadRanges("Ranges/Barbot"); + loadResponses("Responses/Barbot"); + setupSentences(); + _tagMappings.load("TagMap/Barbot"); + _quotes.load("Quotes/Barbot"); + _states.load("States/Barbot"); + _preResponses.load("PreResponses/Barbot"); +} + +void BarbotScript::setupSentences() { + for (int idx = 28; idx < 35; ++idx) + CTrueTalkManager::setFlags(idx, 0); + setupDials(100, 100, 100); + + if (!_currentDialNum) + _currentDialNum = 2; + + _mappings.load("Mappings/Barbot", 8); + _entries.load("Sentences/Barbot"); + _entries2.load("Sentences/Barbot2"); + _words.load("Words/Barbot"); +} + +int BarbotScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) { + if (tag == MKTAG('D', 'N', 'A', '1') || tag == MKTAG('H', 'H', 'G', 'Q') || + tag == MKTAG('A', 'N', 'S', 'W') || tag == MKTAG('S', 'U', 'M', 'S')) { + if (_state < 7) { + addResponse(STATE_ARRAY[_state++]); + } else { + selectResponse(51896); + setState(1); + _state = 0; + } + + applyResponse(); + return 2; + + } else if (tag == MKTAG('S', 'W', 'E', 'R')) { + adjustDial(0, -18); + adjustDial(1, -5); + + if (getRandomNumber(100) > 50) { + addResponse(getDialogueId(getDialRegion(0) == 0 ? 250200 : 250062)); + applyResponse(); + return 2; + } + + } else if (tag == MKTAG('B', 'A', 'R', 'K') && getRandomNumber(100) > 50) { + selectResponse(250025); + switch (getDialsBitset()) { + case 4: + case 6: + addResponse(getDialogueId(250125)); + break; + default: + break; + } + + applyResponse(); + return 2; + + } else if (tag == MKTAG('B', 'A', 'R', 'U') && getRandomNumber(100) > 50) { + selectResponse(250025); + switch (getDialsBitset()) { + case 4: + case 6: + addResponse(getDialogueId(250112)); + break; + default: + break; + } + + applyResponse(); + return 2; + } + + if (tag == MKTAG('T', 'H', 'R', 'T') || tag == MKTAG('S', 'L', 'O', 'W') || + tag == MKTAG('S', 'E', 'X', '1') || tag == MKTAG('P', 'K', 'U', 'P')) { + adjustDial(0, -7); + adjustDial(1, -3); + } + + return TTnpcScript::chooseResponse(roomScript, sentence, tag); +} + +int BarbotScript::process(const TTroomScript *roomScript, const TTsentence *sentence) { + int dialogueId = 0; + + if (roomScript->_scriptId != 112) + return 2; + + checkItems(roomScript, sentence); + if (isState9()) { + if (sentence->localWord("visioncenter") || sentence->localWord("brain") || + sentence->contains("vision") || sentence->contains("visual") || + sentence->contains("brain") || sentence->contains("crystal")) { + if (CTrueTalkManager::getStateValue(2)) { + addResponse(getDialogueId(251003)); + applyResponse(); + CTrueTalkManager::triggerAction(6, 0); + return 2; + } + } + + if (sentence->contains("goldfish")) { + addResponse(getDialogueId(250184)); + applyResponse(); + return 2; + } + + dialogueId = ARRAY1[getRandomNumber(20)]; + if (!ARRAY2[_arrIndex]) + _arrIndex = 0; + + if (_arrIndex) { + dialogueId = ARRAY2[_arrIndex++]; + } else if (getRandomNumber(100) > 35) { + dialogueId = ARRAY2[0]; + _arrIndex = 1; + } else if (getRandomNumber(100) > 60) { + switch (sentence->_field2C) { + case 2: + dialogueId = 51914; + break; + case 3: + dialogueId = 51911; + break; + case 4: + dialogueId = 51913; + break; + case 5: + dialogueId = 51912; + break; + case 6: + dialogueId = 51915; + break; + case 7: + dialogueId = 51909; + break; + default: + break; + } + } + + addResponse(dialogueId); + if (getRandomNumber(100) > 65) + addResponse(getDialogueId(251250)); + applyResponse(); + return 2; + } + + CTrueTalkManager::setFlags(29, getValue(29) - 1); + CTrueTalkManager::setFlags(30, getValue(30) - 1); + CTrueTalkManager::setFlags(31, getValue(31) - 1); + CTrueTalkManager::setFlags(32, getValue(32) - 1); + CTrueTalkManager::setFlags(33, getValue(33) - 1); + CTrueTalkManager::setFlags(34, getValue(34) - 1); + + TTtreeResult treeResult; + int val34 = getState(); + setState(0); + + int val2C = sentence->_field2C; + bool flag = val2C == 11 || val2C == 13; + bool flag2 = val2C == 12; + + if (!val34) { + goto done; + } else if (val34 > 50357) { + goto done; + } else if (val34 == 50357) { + return applySentenceIds(50358, -1); + } + + switch (val34) { + case 1: + if (flag) + return applySentenceIds(51898, 2); + if (flag2) + return applySentenceIds(51897); + break; + case 2: + if (flag) + return applySentenceIds(51897); + break; + case 3: + if (sentence->localWord("useless") || sentence->contains("useless")) + return applySentenceIds(50824); + break; + case 4: + if (flag) + return applySentenceIds(getRandomBit() ? 50512 : 51642); + else if (flag2) + return applySentenceIds(getRandomBit() ? 50511 : 51643); + break; + case 5: + if (flag) + return applySentenceIds(50829, 6); + if (flag2) + return applySentenceIds(50828); + break; + case 6: + if (flag) + return applySentenceIds(50831); + if (flag2) + return applySentenceIds(50830); + break; + case 7: + if (flag2 || sentence->contains("never")) + return applySentenceIds(51553); + if (flag || sentence->contains("nicest")) + return applySentenceIds(51554); + break; + case 8: + if (flag) + return applySentenceIds(50961); + if (flag2) + return applySentenceIds(50960); + break; + case 9: + if (flag) + return applySentenceIds(getDialogueId(251858)); + break; + case 10: + if (flag) + return applySentenceIds(getDialogueId(251014)); + else if (flag2) + return applySentenceIds(getDialogueId(251013)); + break; + case 11: + if (flag) + return applySentenceIds(getDialogueId(251008)); + else if (flag2) + return applySentenceIds(getDialogueId(251007)); + break; + case 12: + if (flag) + return applySentenceIds(getDialogueId(250656)); + else if (flag2) + return applySentenceIds(getDialogueId(250655)); + break; + case 13: + if (flag) + return applySentenceIds(getDialogueId(250614)); + else if (flag2) + return applySentenceIds(getDialogueId(250613)); + break; + case 14: + if (val2C == 6) + return applySentenceIds(getDialogueId(250946)); + break; + case 15: + if (flag || sentence->contains("or")) { + return applySentenceIds(getDialogueId(250526), 16); + } else { + if (g_vm->_trueTalkManager->_quotesTree.search( + sentence->_normalizedLine.c_str(), TREE_3, &treeResult, 0, nullptr) != -1) { + uint newId = getDialogueId(250526); + return applySentenceIds(newId, 16); + } + } + break; + case 17: + if (flag) { + return applySentenceIds(50382); + } else if (flag2) { + return applySentenceIds(51423); + } + // Deliberate fall-through + + case 16: + if (val2C == 7 || val2C == 10) + return applySentenceIds(getDialogueId(250525)); + break; + case 18: + return applySentenceIds(getDialogueId(250589)); + case 19: + return applySentenceIds(getDialogueId(250565), 20); + case 20: + if (flag) + return applySentenceIds(50307); + if (flag2) + return applySentenceIds(50306); + break; + case 21: + if (flag) + return applySentenceIds(50359); + if (flag2) + return applySentenceIds(50357); + break; + case 23: + if (val2C == 6 || val2C == 10) + return applySentenceIds(getDialogueId(250551)); + break; + case 24: + if (sentence->contains("do not know") + || sentence->contains("no idea") + || sentence->contains("a clue")) { + return applySentenceIds(getDialogueId(250553)); + } else { + return applySentenceIds(getDialogueId(250552)); + } + break; + case 25: + if (flag || val2C == 10) + applySentenceIds(getDialogueId(251899), 26); + else if (flag2) + return applySentenceIds(50215); + break; + case 26: + if (g_vm->_trueTalkManager->_quotesTree.search( + sentence->_normalizedLine.c_str(), TREE_3, &treeResult, 0, nullptr) != -1) + return applySentenceIds(getDialogueId(251899), 26); + break; + + case 27: + if (flag) + return applySentenceIds(getDialogueId(250766)); + else if (flag2) + return applySentenceIds(getDialogueId(250764)); + break; + case 28: + return applySentenceIds(getDialogueId(250765)); + case 29: + return applySentenceIds(getDialogueId(250652)); + case 30: + return applySentenceIds(getDialogueId(250653)); + case 31: + if (flag) + return applySentenceIds(getDialogueId(250664)); + else if (flag2) + return applySentenceIds(getDialogueId(250663)); + break; + case 32: + if (flag) + return applySentenceIds(getDialogueId(250643)); + else if (flag2) + return applySentenceIds(getDialogueId(250642)); + break; + case 33: + return applySentenceIds(50763); + case 34: + if (flag) + return applySentenceIds(getDialogueId(251622)); + else if (flag2) + return applySentenceIds(getDialogueId(251624)); + break; + case 35: + if (val2C == 6 || val2C == 10) + return applySentenceIds(getDialogueId(251623)); + break; + case 36: + if (flag) + return applySentenceIds(50335); + if (flag2) + return applySentenceIds(50334); + break; + case 37: + if (flag) + return applySentenceIds(50217); + if (flag2) + return applySentenceIds(50153); + break; + case 38: + return applySentenceIds(getDialogueId(250637)); + case 39: + return applySentenceIds(getDialogueId(250638)); + case 40: + return applySentenceIds(getDialogueId(250639)); + case 41: + return applySentenceIds(getDialogueId(250640)); + case 42: + if (flag) + return applySentenceIds(getDialogueId(250676)); + else if (flag2) + return applySentenceIds(getDialogueId(250673)); + break; + case 43: + if (flag) + return applySentenceIds(50416, -1); + if (flag2) + return applySentenceIds(50415, -1); + break; + case 44: + if (flag) + return applySentenceIds(getDialogueId(250468)); + else if (flag2) + return applySentenceIds(getDialogueId(250413)); + + if (val2C == 6 || val2C == 10) + return applySentenceIds(getDialogueId(251649)); + break; + case 45: + if (sentence->localWord("summer") + || sentence->contains("summer") + || sentence->localWord("autumn") + || sentence->contains("autumn")) { + return applySentenceIds(50743); + } else if (sentence->localWord("winter") || sentence->contains("winter")) { + return applySentenceIds(50696); + } else { + return applySentenceIds(50225); + } + break; + case 46: + if (val2C == 7 || val2C == 10) + return applySentenceIds(50698); + break; + case 47: + if (flag || flag2 || val2C == 6) + return applySentenceIds(50717); + break; + case 48: + if (flag) + return applySentenceIds(50710); + if (flag2) + return applySentenceIds(50225); + break; + case 49: + if (sentence->localWord("scraliontis") || sentence->contains("scraliontis")) + return applySentenceIds(50711); + if (sentence->localWord("brobostigon") || sentence->contains("brobostigon")) + return applySentenceIds(50712); + break; + case 50: + return applySentenceIds(50713); + case 51: + if (flag) + return applySentenceIds(50715); + if (flag2) + return applySentenceIds(50714); + break; + case 52: + if (sentence->localWord("note") || sentence->contains("note")) + return applySentenceIds(50716); + return applySentenceIds(50210); + case 53: + return applySentenceIds(50210); + case 54: + if (getDialRegion(0) != 0) { + if (val2C == 12) + return applySentenceIds(50174); + else + return applySentenceIds(50300); + } else if (val2C == 7 || val2C == 10) { + return applySentenceIds(50871); + } + break; + case 55: + if (flag) + return applySentenceIds(50302); + if (flag2) + return applySentenceIds(50301); + break; + case 56: + if (flag) + return applySentenceIds(50304); + if (flag2) + return applySentenceIds(50303); + break; + case 57: + if (sentence->localWord("mustard") + || sentence->contains("mustard") + || sentence->localWord("tomato") + || sentence->contains("tomato")) + return applySentenceIds(50320); + if (sentence->localWord("sauce") + || sentence->localWord("puree") + || sentence->contains("sauce") + || sentence->contains("puree") + || sentence->contains("bird") + || sentence->contains("starling")) { + applySentenceIds(50321); + CTrueTalkManager::triggerAction(30, 0); + return 2; + } + + return applySentenceIds(50320); + case 58: + if (val2C == 6 || val2C == 10) + return applySentenceIds(50880); + break; + case 59: + if (flag) { + if (addRandomResponse(true)) { + setState(59); + return 2; + } + } else if (flag2) { + return applySentenceIds(getDialogueId(251754)); + } + break; + case 60: + if (flag && addRandomResponse(true)) { + setState(59); + return 2; + } else if (flag2 || val2C == 7 || val2C == 10) { + return applySentenceIds(getDialogueId(251712)); + } + break; + case 61: + if (val2C == 3) { + if (sentence->localWord("loop")) + return applySentenceIds(getDialogueId(250269)); + else if (sentence->localWord("do")) + return applySentenceIds(getDialogueId(250270)); + } else if (val2C == 7) { + return applySentenceIds(getDialogueId(250270)); + } else if (flag) { + return applySentenceIds(getDialogueId(250270)); + } + + return applySentenceIds(getDialogueId(250272)); + case 62: + if (flag + || (val2C == 3 && sentence->localWord("do")) + || val2C == 7 + || sentence->localWord("help")) + return applySentenceIds(getDialogueId(250270)); + + return applySentenceIds(getDialogueId(2570272)); + case 63: + if (flag + || (val2C == 3 || sentence->localWord("do")) + || val2C == 7 + || sentence->localWord("help")) + return applySentenceIds(getDialogueId(250271)); + + return applySentenceIds(getDialogueId(250272)); + case 64: + if (flag || val2C == 3 || val2C == 8) + return applySentenceIds(getDialogueId(250631)); + break; + case 65: + if (sentence->localWord("now") || sentence->localWord("soonh")) + return applySentenceIds(getDialogueId(250424)); + return applySentenceIds(getDialogueId(250506)); + case 66: + if (flag || sentence->localWord("good") || sentence->localWord("well")) + return applySentenceIds(getDialogueId(251027)); + return applySentenceIds(getDialogueId(251021)); + case 67: + if (flag || val2C == 6 || val2C == 10) { + setDial(0, getDialLevel(0, false) - 8); + return applySentenceIds(getDialogueId(251589)); + } + break; + case 68: + if (flag || val2C == 6 || val2C == 10) { + setDial(0, getDialLevel(0, false) - 12); + return applySentenceIds(getDialogueId(251590)); + } + break; + case 69: + if (flag || val2C == 6 || val2C == 10) { + setDial(0, getDialLevel(0, false) - 25); + return applySentenceIds(getDialogueId(251591)); + } + break; + default: + break; + } + +done: + // Adjust primary dial + setState(0); + if (sentence->get58() != 5) { + adjustDial(0, sentence->get58() * 4 - 20); + } else if (getDialLevel(0, false) > 65) { + adjustDial(0, -2 - getRandomNumber(7)); + } else if (getDialLevel(0, false) < 35) { + adjustDial(0, 2 + getRandomNumber(7)); + } + + updateCurrentDial(true); + + if (sentence->contains("goldfish")) { + addResponse(250184); + } else if ((sentence->localWord("puree") || sentence->localWord("pureed")) + && sentence->localWord("parrot")) { + addResponse(250021); + } else if (sentence->localWord("starling")) { + addResponse(250024); + } else { + if (getRandomNumber(100) > 95 && getDialRegion(2) == 0) { + addResponse(getDialogueId(250210)); + } + + if (processEntries(&_entries, _entryCount, roomScript, sentence) == 2) + return 2; + if (processEntries(_defaultEntries, 0, roomScript, sentence) != 2 + && !defaultProcess(roomScript, sentence)) { + int dval = 0; + flag = getRandomNumber(100) > 50; + int val; + + switch (_field2C) { + case 2: + val = getValue(29); + if (val < 16) + val += 4; + if (val < 9) { + val = val / 2; + dval = 250081 + (flag ? 0 : 267); + } + CTrueTalkManager::setFlags(29, val); + break; + + case 3: + val = getValue(30); + if (val < 16) + val += 4; + if (val < 9) { + val = val / 2; + dval = 250081 + (flag ? 0 : 243); + } + CTrueTalkManager::setFlags(30, val); + break; + + case 4: + val = getValue(31); + if (val < 16) + val += 4; + if (val < 9) { + val = val / 2; + dval = 250081 + (flag ? 0 : 256); + } + CTrueTalkManager::setFlags(31, val); + break; + + case 5: + val = getValue(32); + if (val < 16) + val += 4; + if (val < 9) { + val = val / 2; + dval = 250081 + (flag ? 0 : 251); + } + CTrueTalkManager::setFlags(32, val); + break; + + case 6: + val = getValue(33); + if (val < 16) + val += 4; + if (val < 9) { + val = val / 2; + dval = 250081 + (flag ? 0 : 273); + } + CTrueTalkManager::setFlags(33, val); + break; + + case 7: + val = getValue(34); + if (val < 16) + val += 4; + if (val < 9) { + val = val / 2; + dval = 250081 + (flag ? 0 : 236); + } + CTrueTalkManager::setFlags(34, val); + break; + + + case 11: + addResponse(getDialogueId(250463)); + applyResponse(); + return 2; + + case 12: + addResponse(getDialogueId(250455)); + applyResponse(); + return 2; + + case 13: + addResponse(getDialogueId(250447)); + applyResponse(); + return 2; + + case 19: + return applySentenceIds(getDialogueId(getDialRegion(0) ? 250062 : 250200)); + + default: + break; + } + + if (dval) { + adjustDial(0, -9); + adjustDial(1, -2); + + if (dval != 250081) { + selectResponse(250286); + selectResponse(250296); + selectResponse(250307); + applyResponse(); + return 2; + } + } else if (processEntries(&_entries2, 0, roomScript, sentence) == 2) { + return 2; + } + + addResponse(getDialogueId(250082 + getRandomNumber(100) <= 89 ? 128 : 0)); + } + } + + applyResponse(); + return 2; +} + +ScriptChangedResult BarbotScript::scriptChanged(const TTroomScript *roomScript, uint id) { + switch (id) { + case 1: + case 100: + if (!isState9()) { + selectResponse(250210); + applyResponse(); + } + + adjustDial(0, getRandomBit() ? getRandomNumber(5) * 4 : + -(int)getRandomNumber(5) * 4); + break; + + case 3: + if (isState9()) { + selectResponse(250244); + applyResponse(); + resetFlags(); + } else { + if (!getValue(28) || !fn10(true)) { + addResponse(getDialogueId(251627 + getValue(28) ? -1034 : 0)); + applyResponse(); + } + + CTrueTalkManager::setFlags(28, 1); + resetFlags(); + } + break; + + case 4: + selectResponse(isState9() ? 250141 : 250140); + applyResponse(); + adjustDial(2, getDialLevel(2, false) < 50 ? -15 - getRandomNumber(30) : + 15 + getRandomNumber(30)); + + if (getDialRegion(1) != 0 && getRandomNumber(100) > 75) + adjustDial(1, -35); + break; + + case 143: + addResponse(getDialogueId(isState9() ? 250577 : 250576)); + break; + + case 144: + addResponse(getDialogueId(isState9() ? 250577 : 250584)); + break; + + case 145: + if (isState9()) { + addResponse(getDialogueId(250577)); + applyResponse(); + } else { + setState(57); + } + break; + + case 146: + addResponse(getDialogueId(isState9() ? 250577 : 250574)); + break; + + case 147: + addResponse(getDialogueId(250579)); + break; + + } + + if (id >= 250000 && id <= 251900) { + if (id > 250571) { + if (id != 250575 && (id == 250586 || id == 251858 || !isState9())) { + addResponse(getDialogueId(id)); + applyResponse(); + } + } else if (id == 250571 || (id != 250244 && !isState9()) || isState9()) { + addResponse(getDialogueId(id)); + applyResponse(); + } else { + addResponse(getDialogueId(251018)); + applyResponse(); + } + } + + return SCR_2; +} + +int BarbotScript::handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder) { + switch (tagId) { + case MKTAG('A', 'D', 'V', 'T'): + case MKTAG('A', 'R', 'T', 'I'): + case MKTAG('A', 'R', 'T', 'Y'): + case MKTAG('B', 'R', 'N', 'D'): + case MKTAG('C', 'O', 'M', 'D'): + case MKTAG('D', 'N', 'C', 'E'): + case MKTAG('H', 'B', 'B', 'Y'): + case MKTAG('M', 'A', 'G', 'S'): + case MKTAG('L', 'I', 'T', 'R'): + case MKTAG('M', 'C', 'P', 'Y'): + case MKTAG('M', 'I', 'N', 'S'): + case MKTAG('M', 'U', 'S', 'I'): + case MKTAG('N', 'I', 'K', 'E'): + case MKTAG('S', 'F', 'S', 'F'): + case MKTAG('S', 'O', 'A', 'P'): + case MKTAG('S', 'O', 'N', 'G'): + case MKTAG('S', 'P', 'R', 'T'): + case MKTAG('T', 'E', 'A', 'M'): + case MKTAG('T', 'U', 'S', 'H'): + case MKTAG('W', 'W', 'E', 'B'): + tagId = MKTAG('E', 'N', 'T', 'N'); + break; + case MKTAG('A', 'U', 'T', 'H'): + case MKTAG('B', 'A', 'R', 'K'): + case MKTAG('B', 'L', 'R', '1'): + case MKTAG('B', 'L', 'P', '1'): + case MKTAG('B', 'L', 'P', '2'): + case MKTAG('B', 'L', 'P', '3'): + case MKTAG('B', 'L', 'P', '4'): + case MKTAG('B', 'L', 'T', '1'): + case MKTAG('B', 'L', 'T', '2'): + case MKTAG('B', 'L', 'T', '3'): + case MKTAG('B', 'L', 'T', '4'): + case MKTAG('B', 'L', 'T', '5'): + case MKTAG('B', 'O', 'Y', 'S'): + case MKTAG('C', 'O', 'P', 'S'): + case MKTAG('D', 'C', 'T', 'R'): + case MKTAG('F', 'A', 'M', 'E'): + case MKTAG('F', 'A', 'S', 'H'): + case MKTAG('G', 'I', 'R', 'L'): + case MKTAG('H', 'E', 'R', 'O'): + case MKTAG('H', 'O', 'S', 'T'): + case MKTAG('K', 'N', 'O', 'B'): + case MKTAG('N', 'H', 'R', 'O'): + case MKTAG('R', 'A', 'C', 'E'): + case MKTAG('S', 'C', 'I', 'T'): + case MKTAG('T', 'D', 'V', 'P'): + case MKTAG('T', 'W', 'A', 'T'): + case MKTAG('W', 'E', 'A', 'T'): + tagId = MKTAG('P', 'R', 'S', 'N'); + break; + case MKTAG('C', 'H', 'S', 'E'): + case MKTAG('C', 'M', 'N', 'T'): + case MKTAG('F', 'I', 'L', 'M'): + case MKTAG('J', 'F', 'O', 'D'): + case MKTAG('L', 'I', 'Q', 'D'): + tagId = MKTAG('F', 'O', 'O', 'D'); + break; + case MKTAG('C', 'R', 'M', 'N'): + case MKTAG('C', 'S', 'P', 'Y'): + case MKTAG('U', 'B', 'A', 'D'): + tagId = MKTAG('V', 'B', 'A', 'D'); + break; + case MKTAG('E', 'A', 'R', 'T'): + case MKTAG('H', 'O', 'M', 'E'): + case MKTAG('N', 'P', 'L', 'C'): + case MKTAG('P', 'L', 'A', 'C'): + case MKTAG('P', 'L', 'A', 'N'): + tagId = MKTAG('P', 'L', 'A', 'C'); + break; + case MKTAG('F', 'A', 'U', 'N'): + case MKTAG('F', 'I', 'S', 'H'): + case MKTAG('F', 'L', 'O', 'R'): + tagId = MKTAG('N', 'A', 'T', 'R'); + break; + case MKTAG('H', 'H', 'L', 'D'): + case MKTAG('T', 'O', 'Y', 'S'): + case MKTAG('W', 'E', 'A', 'P'): + tagId = MKTAG('M', 'A', 'C', 'H'); + break; + case MKTAG('M', 'L', 'T', 'Y'): + case MKTAG('P', 'G', 'R', 'P'): + case MKTAG('P', 'T', 'I', 'C'): + tagId = MKTAG('G', 'R', 'U', 'P'); + break; + case MKTAG('P', 'K', 'U', 'P'): + case MKTAG('S', 'E', 'X', '1'): + case MKTAG('S', 'W', 'E', 'R'): + tagId = MKTAG('R', 'U', 'D', 'E'); + break; + case MKTAG('P', 'H', 'I', 'L'): + case MKTAG('R', 'C', 'K', 'T'): + case MKTAG('S', 'C', 'I', 'E'): + tagId = MKTAG('S', 'C', 'I', 'E'); + break; + case MKTAG('T', 'R', 'A', '2'): + case MKTAG('T', 'R', 'A', '3'): + tagId = MKTAG('T', 'R', 'A', 'V'); + break; + default: + break; + } + + if (val == 36) { + switch (getValue(1)) { + case 1: + return setResponse(getDialogueId(220837), -1); + break; + case 2: + return setResponse(getDialogueId(220849), -1); + default: + return setResponse(getDialogueId(220858), -1); + } + } else if (val == 61 && getValue(1) > 2) { + return setResponse(getDialogueId(222301), -1); + } + + return TTnpcScript::handleQuote(roomScript, sentence, val, tagId, remainder); +} + +int BarbotScript::updateState(uint oldId, uint newId, int index) { + if (newId == 250538) { + CTrueTalkManager::triggerAction(28, 0); + return 250538; + } + if (newId == 251704) { + return 251701 + (_field7C ? 3 : 0); + } + + for (uint idx = 0; idx < _states.size(); ++idx) { + const TTupdateState &us = _states[idx]; + if (us._newId == newId) { + if ((us._dialBits & 1) && !getDialRegion(0)) + continue; + if ((us._dialBits & 2) && getDialRegion(0)) + continue; + if ((us._dialBits & 4) && !getDialRegion(1)) + continue; + if ((us._dialBits & 8) && getDialRegion(1)) + continue; + if ((us._dialBits & 0x10) && !getDialRegion(2)) + continue; + if ((us._dialBits & 0x20) && getDialRegion(2)) + continue; + + setState(us._newValue); + break; + } + } + + return newId; +} + +int BarbotScript::preResponse(uint id) { + if (getDialRegion(0) == 0 && getRandomNumber(100) > 80) + return 251250; + + return _preResponses.find(id); +} + +uint BarbotScript::getDialsBitset() const { + uint bits = 0; + if (!getDialRegion(0)) + bits = 1; + if (!getDialRegion(1)) + bits |= 2; + if (!getDialRegion(2)) + bits |= 4; + + return bits; +} + +int BarbotScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) { + int v34 = getState(); + uint id = 0; + + if (v34 > 0x200) { + switch (v34 - 0x201) { + case 0: + if (getValue(4) != 2) + id = 250738; + break; + case 1: + if (getValue(4) != 3) + id = 250738; + case 2: + if (getValue(4) != 0) + id = 250738; + break; + default: + break; + } + } else if (v34 == 0x200) { + if (getValue(4) != 1) + id = 250738; + } else { + switch (v34) { + case 2: + if (getValue(1) != 1) + return 1; + break; + case 3: + if (getValue(1) != 2) + return 1; + break; + case 4: + if (getValue(1) != 3) + return 1; + break; + case 5: + if (getValue(1) == 3) + return 1; + break; + case 6: + if (sentence->contains("do not") || sentence->contains("have no") || + sentence->contains("got no")) + return 1; + break; + case 7: + if (!sentence->contains("do not") && !sentence->contains("have no") && + !sentence->contains("got no")) + return 1; + break; + case 8: + if (sentence->_field38 == 2) + return 1; + break; + case 9: { + uint val = CTrueTalkManager::getStateValue(3); + bool bit0 = (val & 1) != 0; + bool bit2 = (val & 4) != 0; + bool bit3 = (val & 8) != 0; + + if (bit2) { + if (!bit0) { + id = 250085 - (bit3 ? 0 : 199715); + break; + } else if (!bit3) { + id = 250627; + } + } else { + if (!bit0) { + id = 50365 + (bit3 ? 0 : 2); + } else if (!bit3) { + id = 50370; + } + } + + if (id) { + addResponse(getDialogueId(id)); + applyResponse(); + return 2; + } + break; + } + + case 10: { + uint val = CTrueTalkManager::getStateValue(3); + bool bit0 = (val & 1) != 0; + bool bit2 = (val & 4) != 0; + bool bit3 = (val & 8) != 0; + + if (bit0 && bit2 && bit3) { + addResponse(getDialogueId(251027)); + applyResponse(); + CTrueTalkManager::triggerAction(7, 0); + return 2; + } else { + if (getDialRegion(1) == 1) { + if (*srcIdP != 251650) + id = 251651; + } else { + addResponse(getDialRegion(0) != 0 ? 51444 : 51530); + applyResponse(); + return 2; + } + } + break; + } + + case 11: + if (CTrueTalkManager::getStateValue(2) != 0) { + CTrueTalkManager::triggerAction(6, 0); + id = 251003; + } + break; + + case 12: + if (getDialRegion(1) == 0) { + addResponse(getDialogueId(251871)); + applyResponse(); + return 2; + } else if (getRandomNumber(100) > 25 && addRandomResponse(false)) { + return 2; + } + + default: + break; + } + } + + if (id) { + addResponse(getDialogueId(id)); + applyResponse(); + } + + return 2; +} + +void BarbotScript::setDialRegion(int dialNum, int region) { + TTnpcScript::setDialRegion(dialNum, region); + selectResponse(250365); + applyResponse(); +} + +void BarbotScript::adjustDial(int dialNum, int amount) { + int level = CLIP(getDialLevel(dialNum) + amount, 0, 100); + setDial(dialNum, level); +} + +bool BarbotScript::isState9() const { + return CTrueTalkManager::getStateValue(9) != 0; +} + +int BarbotScript::applySentenceIds(int dialogueId, int v34) { + addResponse(dialogueId); + applyResponse(); + + if (v34 != -1) { + setState(v34); + } else { + for (uint idx = 0; idx < _mappings.size(); ++idx) { + const TTscriptMapping &m = _mappings[idx]; + for (int vidx = 0; vidx < _mappings._valuesPerMapping; ++idx) { + if (m._values[vidx] == (uint)dialogueId) { + updateState(m._id, m._id, vidx); + break; + } + } + } + } + + return -2; +} + +int BarbotScript::setResponse(int dialogueId, int state) { + addResponse(dialogueId); + applyResponse(); + + if (state != -1) + setState(state); + return 2; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/barbot_script.h b/engines/titanic/true_talk/barbot_script.h new file mode 100644 index 0000000000..1820d77216 --- /dev/null +++ b/engines/titanic/true_talk/barbot_script.h @@ -0,0 +1,106 @@ +/* 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 TITANIC_BARBOT_SCRIPT_H +#define TITANIC_BARBOT_SCRIPT_H + +#include "titanic/true_talk/tt_npc_script.h" + +namespace Titanic { + +class BarbotScript : public TTnpcScript { +private: + int _state; + int _arrIndex; + TTsentenceEntries _entries2; + TTupdateStateArray _states; + TTmapEntryArray _preResponses; +private: + /** + * Adjust a given dial number by a given delta amount + */ + void adjustDial(int dialNum, int amount); + + /** + * Setup sentence data + */ + void setupSentences(); + + bool isState9() const; + + int applySentenceIds(int dialogueId, int v34 = -1); + + /** + * Add a response and optionally set the state + */ + int setResponse(int dialogueId, int state = -1); +public: + BarbotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7); + + /** + * Chooses and adds a conversation response based on a specified tag Id. + */ + virtual int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag); + + /** + * Does NPC specific processing of the parsed sentence + */ + virtual int process(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id); + + virtual int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder); + + /** + * Handles updating NPC state based on specified dialogue Ids and dial positions + */ + virtual int updateState(uint oldId, uint newId, int index); + + /** + * Handles getting a pre-response + */ + virtual int preResponse(uint id); + + /** + * Returns a bitset of the first three dialgs being on or not + */ + virtual uint getDialsBitset() const; + + /** + * Process a sentence fragment entry + */ + virtual int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Sets a given dial to be pointing in a specified region (0 to 2) + */ + virtual void setDialRegion(int dialNum, int region); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BARBOT_SCRIPT_H */ diff --git a/engines/titanic/true_talk/bellbot_script.cpp b/engines/titanic/true_talk/bellbot_script.cpp new file mode 100644 index 0000000000..7da2ab6201 --- /dev/null +++ b/engines/titanic/true_talk/bellbot_script.cpp @@ -0,0 +1,1905 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/bellbot_script.h" +#include "titanic/true_talk/true_talk_manager.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/core/node_item.h" +#include "titanic/titanic.h" + +namespace Titanic { + +uint BellbotScript::_oldId; + +static const RoomDialogueId ROOM_DIALOGUE_IDS[] = { + { 100, 201442 },{ 101, 201417 },{ 107, 201491 },{ 108, 201421 }, + { 109, 201437 },{ 110, 201431 },{ 111, 201457 },{ 112, 201411 }, + { 113, 201424 },{ 114, 201464 },{ 115, 201407 },{ 116, 201468 }, + { 117, 201447 },{ 122, 201491 },{ 123, 201299 },{ 124, 201479 }, + { 125, 201480 },{ 126, 201476 },{ 127, 201483 },{ 128, 201399 }, + { 129, 201400 },{ 130, 201387 },{ 131, 201395 },{ 132, 201388 }, + { 0, 0 } +}; + +BellbotScript::BellbotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2) : + TTnpcScript(val1, charClass, v2, charName, v3, val2, -1, -1, -1, 0), + _field2D0(0), _field2D4(0), _field2D8(0), _field2DC(0), + _room107First(false) { + CTrueTalkManager::setFlags(25, 0); + CTrueTalkManager::setFlags(24, 0); + CTrueTalkManager::setFlags(40, 0); + CTrueTalkManager::setFlags(26, 0); + + setupDials(0, 0, 0); + _array[0] = 100; + _array[1] = 0; + + loadRanges("Ranges/Bellbot"); + loadResponses("Responses/Bellbot", 4); + setupSentences(); + _tagMappings.load("TagMap/Bellbot"); + _words.load("Words/Bellbot"); + _quotes.load("Quotes/Bellbot"); + _states.load("States/Bellbot"); + _preResponses.load("PreResponses/Bellbot"); + _phrases.load("Phrases/Bellbot"); +} + +void BellbotScript::setupSentences() { + _mappings.load("Mappings/Bellbot", 1); + _entries.load("Sentences/Bellbot"); + for (int idx = 1; idx < 20; ++idx) + _sentences[idx].load(CString::format("Sentences/Bellbot/%d", idx)); + + _field2DC = 0; + _field68 = 0; + _entryCount = 0; +} + +int BellbotScript::process(const TTroomScript *roomScript, const TTsentence *sentence) { + int val24 = getValue(24); + CTrueTalkManager::setFlags(24, 0); + + int result = preprocess(roomScript, sentence); + if (result != 1) + return 1; + + CTrueTalkManager::setFlags(23, 0); + setState(0); + if (getValue(1) <= 2) + updateCurrentDial(1); + + // Handle room specific sentences + switch (roomScript->_scriptId) { + case 101: + if (getValue(2) == 1) { + result = processEntries(&_sentences[11], 0, roomScript, sentence); + } + break; + + case 107: + result = processEntries(&_sentences[5], 0, roomScript, sentence); + break; + + case 108: + result = processEntries(&_sentences[7], 0, roomScript, sentence); + break; + + case 109: + result = processEntries(&_sentences[13], 0, roomScript, sentence); + break; + + case 110: + result = processEntries(&_sentences[16], 0, roomScript, sentence); + break; + + case 111: + result = processEntries(&_sentences[10], 0, roomScript, sentence); + break; + + case 112: + result = processEntries(&_sentences[15], 0, roomScript, sentence); + break; + + case 113: + result = processEntries(&_sentences[9], 0, roomScript, sentence); + break; + + case 114: + result = processEntries(&_sentences[18], 0, roomScript, sentence); + break; + + case 115: + result = processEntries(&_sentences[12], 0, roomScript, sentence); + break; + + case 116: + result = processEntries(&_sentences[8], 0, roomScript, sentence); + break; + + case 117: + result = processEntries(&_sentences[6], 0, roomScript, sentence); + break; + + case 123: + result = processEntries(&_sentences[17], 0, roomScript, sentence); + break; + + case 125: + result = processEntries(&_sentences[14], 0, roomScript, sentence); + break; + + case 131: + if (getValue(26) == 0) { + result = processEntries(&_sentences[getValue(6) ? 5 : 4], 0, roomScript, sentence); + } + break; + } + + if (result == 2) + return 2; + if (sentence->contains("pretend you summoned yourself") || + sentence->contains("pretend you just summoned yourself")) { + if (scriptChanged(roomScript, 157) == 2) + return 2; + } + + if (sentence->localWord("television") || roomScript->_scriptId == 111) { + if (sentence->localWord("drop") || sentence->localWord("throw") + || sentence->localWord("smash") || sentence->localWord("destroy") + || sentence->localWord("toss") || sentence->localWord("put") + || sentence->localWord("pitch") || sentence->localWord("heft")) { + if (getValue(40) == 1) { + addResponse(getDialogueId(201687)); + applyResponse(); + return 2; + } + else if (roomScript->_scriptId == 111) { + addResponse(getDialogueId(201687)); + applyResponse(); + CTrueTalkManager::triggerAction(17, 0); + CTrueTalkManager::setFlags(40, 1); + return 2; + } + else { + addResponse(getDialogueId(200710)); + addResponse(getDialogueId(201334)); + applyResponse(); + return 2; + } + } + } + + if (sentence->contains("what should i do here") + || sentence->contains("what do i do here") + || sentence->contains("what shall i do in here") + || sentence->contains("what shall i do in this room") + || sentence->contains("what should i do in this room") + || sentence->contains("what am i supposed to do in here") + || sentence->contains("what should i do in here") + || sentence->contains("what do i do in this room")) { + if (addRoomDescription(roomScript)) { + applyResponse(); + return 2; + } + } + + if (sentence->contains("help") + || sentence->contains("what now") + || sentence->contains("what next") + || sentence->contains("give me a hint") + || sentence->contains("i need a hint") + || sentence->contains("what should i be doing") + || sentence->contains("what do you reckon i should do now") + || sentence->contains("what shall i do") + || sentence->contains("what would you do") + || sentence->contains("what should i do") + || sentence->contains("what do i do")) { + if (getDialRegion(0) == 1) { + randomResponse4(roomScript, getValue(1)); + applyResponse(); + return 2; + } else { + randomResponse3(roomScript, getValue(1)); + } + } + + if (sentence->get58() > 6 && sentence->contains("please")) { + addResponse(getDialogueId(200432)); + applyResponse(); + return 2; + } + + if (checkCommonSentences(roomScript, sentence) == 2) + return 2; + + // WORKAROUND: Skip processEntries call on unassigned sentence array + + // Standard sentence list + if (processEntries(&_entries, _entryCount, roomScript, sentence) == 2) + return 2; + + if ((sentence->_field2C == 4 && sentence->localWord("am") && sentence->localWord("i")) + || (sentence->localWord("are") && sentence->localWord("we")) + || (sentence->_field2C == 3 && sentence->localWord("room") + && sentence->localWord("we") && sentence->localWord("in")) + || (sentence->_field2C == 3 && sentence->localWord("rom") + && sentence->localWord("is") && sentence->localWord("this")) + ) { + uint id = getRangeValue(getRoomDialogueId(roomScript)); + addResponse(getDialogueId(id ? id : 201384)); + applyResponse(); + return 2; + } + + if (getValue(1) >= 3) { + result = processEntries(&_sentences[1], 0, roomScript, sentence); + } else if (getValue(1) == 2) { + result = processEntries(&_sentences[2], 0, roomScript, sentence); + } else if (getValue(1) == 1) { + result = processEntries(&_sentences[3], 0, roomScript, sentence); + + if (sentence->contains("shrinkbot")) { + addResponse(getDialogueId(200583)); + applyResponse(); + return 2; + } + } + + if (sentence->localWord("television") || sentence->localWord("tv") + || sentence->localWord("crush") || sentence->localWord("crushed")) { + if (roomScript->_scriptId == 111 || getRandomBit()) { + addResponse(getDialogueId(getRandomBit() ? 200912 : 200913)); + } else { + addResponse(getDialogueId(200710)); + addResponse(getDialogueId(201334)); + } + + applyResponse(); + return 2; + } + + if (checkCommonWords(roomScript, sentence)) { + applyResponse(); + setState(0); + return 2; + } + + if (sentence->contains("my") && (sentence->contains("where can i find") + || sentence->contains("where is") + || sentence->contains("wheres") + || sentence->contains("help me find") + || sentence->contains("what have you done with") + || sentence->contains("have you got") + || sentence->contains("id like") + || sentence->contains("i would like") + || sentence->contains("have you seen") + )) { + addResponse(getDialogueId(200799)); + applyResponse(); + return 2; + } + + setupSentences(); + uint tagId = g_vm->_trueTalkManager->_quotes.find(sentence->_normalizedLine); + if (tagId && chooseResponse(roomScript, sentence, tagId) == 2) + return 2; + if (defaultProcess(roomScript, sentence)) + return 2; + if (!processEntries(&_sentences[19], 0, roomScript, sentence)) + return 2; + if (!processEntries(_defaultEntries, 0, roomScript, sentence)) + return 2; + + if (sentence->contains("42")) { + addResponse(getDialogueId(200515)); + applyResponse(); + return 2; + } + + CTrueTalkManager::setFlags(24, val24 + 1); + if (getValue(24) > 3) { + addResponse(getDialogueId(200200)); + applyResponse(); + return 2; + } + + if (sentence->localWord("get")) { + addResponse(getDialogueId(200475)); + applyResponse(); + return 2; + } + + if (getRandomNumber(100) <= 75) { + addResponse(getDialogueId(200060)); + applyResponse(); + return 2; + } + + addResponse(getDialogueId(200140)); + addResponse(getDialogueId(getRandomBit() ? 200192 : 200157)); + addResponse(getDialogueId(200176)); + applyResponse(); + return 2; +} + +ScriptChangedResult BellbotScript::scriptChanged(const TTroomScript *roomScript, uint id) { + if (!roomScript) + return SCR_2; + + switch (id) { + case 104: + addResponse(getDialogueId(200617)); + applyResponse(); + break; + + case 105: + addResponse(getDialogueId(200732)); + applyResponse(); + break; + + case 106: + addResponse(getDialogueId(200733)); + applyResponse(); + break; + + case 107: + addResponse(getDialogueId(200731)); + applyResponse(); + break; + + case 157: + _field2DC = 1; + break; + + case 158: + CTrueTalkManager::setFlags(26, 1); + break; + + case 3: + if (_field2DC) { + if (randomResponse0(roomScript, id)) + return SCR_2; + } else { + addResponse(getDialogueId(201693)); + applyResponse(); + } + + _field2DC = 0; + CTrueTalkManager::_v9 = 0; + // Deliberate fall-through + default: + if (roomScript->_scriptId == 115 && id == 103) { + switch (getValue(4)) { + case 0: + addResponse(getDialogueId(200014)); + applyResponse(); + break; + case 1: + case 2: + addResponse(getDialogueId(200011)); + applyResponse(); + break; + case 3: + addResponse(getDialogueId(200007)); + applyResponse(); + break; + default: + break; + } + } + break; + } + + return SCR_2; +} + +int BellbotScript::handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder) { + switch (tagId) { + case MKTAG('A', 'D', 'V', 'T'): + case MKTAG('A', 'R', 'T', 'I'): + case MKTAG('A', 'R', 'T', 'Y'): + case MKTAG('B', 'R', 'N', 'D'): + case MKTAG('C', 'O', 'M', 'D'): + case MKTAG('D', 'N', 'C', 'E'): + case MKTAG('H', 'B', 'B', 'Y'): + case MKTAG('L', 'I', 'T', 'R'): + case MKTAG('M', 'A', 'G', 'S'): + case MKTAG('M', 'C', 'P', 'Y'): + case MKTAG('M', 'I', 'N', 'S'): + case MKTAG('M', 'U', 'S', 'I'): + case MKTAG('N', 'I', 'K', 'E'): + case MKTAG('S', 'F', 'S', 'F'): + case MKTAG('S', 'O', 'A', 'P'): + case MKTAG('S', 'O', 'N', 'G'): + case MKTAG('S', 'P', 'R', 'T'): + case MKTAG('T', 'E', 'A', 'M'): + case MKTAG('T', 'V', 'S', 'H'): + case MKTAG('W', 'W', 'E', 'B'): + tagId = MKTAG('E', 'N', 'T', 'N'); + break; + case MKTAG('A', 'C', 'T', 'R'): + case MKTAG('A', 'C', 'T', 'S'): + case MKTAG('A', 'U', 'T', 'H'): + case MKTAG('B', 'A', 'R', 'K'): + case MKTAG('B', 'A', 'R', 'U'): + case MKTAG('B', 'L', 'F', '1'): + case MKTAG('B', 'L', 'F', '2'): + case MKTAG('B', 'L', 'P', '1'): + case MKTAG('B', 'L', 'P', '2'): + case MKTAG('B', 'L', 'P', '3'): + case MKTAG('B', 'L', 'P', '4'): + case MKTAG('B', 'L', 'R', '1'): + case MKTAG('B', 'L', 'R', '2'): + case MKTAG('B', 'L', 'T', '1'): + case MKTAG('B', 'L', 'T', '2'): + case MKTAG('B', 'L', 'T', '3'): + case MKTAG('B', 'L', 'T', '4'): + case MKTAG('B', 'L', 'T', '5'): + case MKTAG('C', 'O', 'P', 'S'): + case MKTAG('D', 'C', 'T', 'R'): + case MKTAG('F', 'A', 'S', 'H'): + case MKTAG('F', 'A', 'M', 'E'): + case MKTAG('H', 'E', 'R', 'D'): + case MKTAG('H', 'O', 'S', 'T'): + case MKTAG('K', 'N', 'O', 'B'): + case MKTAG('N', 'H', 'R', 'O'): + case MKTAG('R', 'A', 'C', 'E'): + case MKTAG('S', 'C', 'I', 'T'): + case MKTAG('T', 'O', 'U', 'P'): + case MKTAG('T', 'W', 'A', 'T'): + case MKTAG('W', 'E', 'A', 'T'): + tagId = MKTAG('P', 'R', 'S', 'N'); + break; + case MKTAG('C', 'H', 'S', 'E'): + case MKTAG('C', 'M', 'N', 't'): + case MKTAG('F', 'I', 'L', 'M'): + case MKTAG('J', 'F', 'O', 'D'): + case MKTAG('L', 'I', 'Q', 'D'): + tagId = MKTAG('F', 'O', 'O', 'D'); + break; + case MKTAG('C', 'R', 'I', 'M'): + case MKTAG('C', 'S', 'P', 'Y'): + case MKTAG('D', 'R', 'U', 'G'): + tagId = MKTAG('V', 'B', 'A', 'D'); + break; + case MKTAG('E', 'A', 'R', 'T'): + case MKTAG('H', 'O', 'M', 'E'): + case MKTAG('N', 'P', 'L', 'C'): + case MKTAG('P', 'L', 'A', 'N'): + tagId = MKTAG('P', 'L', 'A', 'C'); + break; + case MKTAG('F', 'A', 'U', 'N'): + case MKTAG('F', 'I', 'S', 'H'): + case MKTAG('F', 'L', 'O', 'R'): + tagId = MKTAG('N', 'A', 'T', 'R'); + break; + case MKTAG('H', 'H', 'L', 'D'): + case MKTAG('T', 'O', 'Y', 'S'): + case MKTAG('W', 'E', 'A', 'P'): + tagId = MKTAG('M', 'A', 'C', 'H'); + break; + case MKTAG('M', 'L', 'T', 'Y'): + case MKTAG('P', 'G', 'R', 'P'): + case MKTAG('P', 'T', 'I', 'C'): + tagId = MKTAG('G', 'R', 'U', 'P'); + break; + case MKTAG('P', 'K', 'U', 'P'): + case MKTAG('S', 'E', 'X', '1'): + case MKTAG('S', 'W', 'E', 'R'): + tagId = MKTAG('R', 'U', 'D', 'E'); + break; + case MKTAG('P', 'H', 'I', 'L'): + case MKTAG('R', 'C', 'K', 'T'): + tagId = MKTAG('S', 'C', 'I', 'E'); + break; + case MKTAG('T', 'R', 'A', '2'): + case MKTAG('T', 'R', 'A', '3'): + tagId = MKTAG('T', 'R', 'A', 'V'); + break; + default: + break; + } + + return TTnpcScript::handleQuote(roomScript, sentence, val, tagId, remainder); +} + +int BellbotScript::updateState(uint oldId, uint newId, int index) { + if (!getValue(25)) { + newId = 202043 - getValue(1) <= 2 ? 994 : 0; + CTrueTalkManager::setFlags(25, 1); + } + + if (oldId == _oldId && _rangeResetCtr >= 3) { + TTscriptRange *range = findRange(oldId); + if (range) + range->_priorIndex = 0; + + _rangeResetCtr = 0; + return getRangeValue(200370); + } + + if (oldId != _oldId) { + _oldId = oldId; + _rangeResetCtr = 0; + } + + if (oldId >= 201709 && oldId <= 201754) { + addResponse(getDialogueId(201705)); + addResponse(getDialogueId(201706)); + newId = getRangeValue(201707); + } + + if (newId == 202276) + newId = addLocation(); + if (newId == 202275) + newId = getStateDialogueId(); + + if (getValue(1) >= 2) { + if (newId == 200840 || newId == 200845 || newId == 200846 || newId == 200851) { + if (getValue(1) == 2) { + newId = 202047; + } else { + newId = getRangeValue(202848); + } + } + } + + if (getValue(1) >= 3) { + if (newId == 200841 || newId == 200842 || newId == 200843 || + newId == 200847 || newId == 200848 || newId == 200854) { + newId = getRangeValue(202038); + } + } + + if (newId == 200264 && getValue(1) == 1) + newId = 200267; + if (newId == 202231 && getValue(1) == 1) + newId = 200848; + + int v4 = getValue(4); + if (newId == 200187 && v4) { + return 200188; + } else if (newId == 200188 && !v4) { + return 200187; + } else if (newId == 200014 && (v4 == 1 || v4 == 2)) { + return 200011; + } else if (newId == 200011 && !v4) { + return 200014; + } + + if (oldId == 200612) { + CTrueTalkManager::setFlags(25, 2); + CTrueTalkManager::setFlags(5, 1); + } + + if (newId == 200423 || newId == 200424 || newId == 200425) { + if (getValue(5)) { + CTrueTalkManager::triggerAction(16, 0); + } else { + newId = 200611; + } + } + + if (oldId == 200261 && getRandomNumber(10) == 1) { + if (getValue(1) >= 3) + newId = getRangeValue(200283); + else if (getValue(1) == 2) + newId = getRangeValue(200279); + } + + if (oldId == 200962) { + if (getValue(1) == 2) + return 200963; + if (getValue(1) == 1) + return 200964; + } + if (oldId == 200989 && getValue(1) <= 2) + return 200990; + + if (oldId == 201760) { + CGameManager *gameManager = g_vm->_trueTalkManager->getGameManager(); + CPetControl *pet = getPetControl(gameManager); + + if (pet) { + bool canSummon = pet->canSummonBot("DoorBot"); + if (canSummon) { + CTrueTalkManager::_v9 = 101; + CTrueTalkManager::triggerAction(5, 0); + } else { + newId = 201857; + } + } + } + + setValue23(newId); + return newId; +} + +int BellbotScript::preResponse(uint id) { + int newId = _preResponses.find(id); + + if (newId == 202277) { + applyResponse(); + CTrueTalkManager::triggerAction(1, 0); + } + if (newId == 200769) { + applyResponse(); + CTrueTalkManager::triggerAction(18, 0); + } + + if (id == 21790) + CTrueTalkManager::triggerAction(13, 0); + + return newId; +} + +int BellbotScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) { + switch (val1) { + case 1: + addResponse(getDialogueId(*srcIdP)); + applyResponse(); + return 2; + + case 2: + addResponse(getDialogueId(*srcIdP)); + addResponse(getDialogueId(getRandomNumber(2) == 1 ? 200192 : 200157)); + addResponse(getDialogueId(200176)); + applyResponse(); + return 2; + + case 21: + if (CTrueTalkManager::getStateValue(7) == 0) { + selectResponse(21372); + applyResponse(); + return 2; + } + + if (!sentence->localWord("broken") && !sentence->contains("broken") && + CTrueTalkManager::_currentNPC) { + CNodeItem *node = CTrueTalkManager::_currentNPC->getNode(); + if (node) { + CString nodeName = node->getName(); + if (nodeName == "5" || nodeName == "6" || nodeName == "7") { + CTrueTalkManager::triggerAction(29, 2); + selectResponse(201571); + applyResponse(); + return 2; + } + } + } + + CTrueTalkManager::triggerAction(29, 1); + selectResponse(201771); + applyResponse(); + return 2; + + case 22: + if (CTrueTalkManager::getStateValue(7) == 0) { + selectResponse(21372); + applyResponse(); + return 2; + } + + if (!sentence->localWord("broken") && !sentence->contains("broken") && + CTrueTalkManager::_currentNPC) { + CNodeItem *node = CTrueTalkManager::_currentNPC->getNode(); + if (node) { + CString nodeName = node->getName(); + if (nodeName == "5" || nodeName == "6" || nodeName != "7") { + CTrueTalkManager::triggerAction(29, 2); + selectResponse(201571); + applyResponse(); + return 2; + } + } + } + + CTrueTalkManager::triggerAction(29, 1); + selectResponse(201771); + applyResponse(); + return 2; + + case 23: + case 24: + if (CTrueTalkManager::getStateValue(7) == 0) { + selectResponse(21372); + applyResponse(); + return 2; + } + + CTrueTalkManager::triggerAction(29, val1 == 23 ? 3 : 4); + break; + + default: + break; + } + + return 0; +} + +bool BellbotScript::randomResponse(uint index) { + if (getRandomNumber(100) > 10 || getRandomNumber(10) <= index) + return 0; + + if (getRandomNumber(100) > 95) { + deleteResponses(); + addResponse(getDialogueId(201695)); + applyResponse(); + } else { + setResponseFromArray(index, 201696); + } + + return true; +} + +int BellbotScript::addLocation() { + addResponse(getDialogueId(202228)); + int roomNum, floorNum, elevatorNum; + getAssignedRoom(&roomNum, &floorNum, &elevatorNum); + + addResponse(getDialogueId(202071 + roomNum)); + addResponse(getDialogueId(201933 + floorNum)); + addResponse(getDialogueId(201916 + elevatorNum)); + + return 200858; +} + +int BellbotScript::getStateDialogueId() const { + switch (getValue(1)) { + case 1: + return 201253; + case 2: + return 200282; + default: + return 201246; + } +} + +void BellbotScript::setValue23(uint id) { + uint val = 0; + for (uint idx = 0; idx < _states.size() && !val; ++idx) { + TTmapEntry &us = _states[idx]; + if (us._src == id) + val = us._dest; + } + + CTrueTalkManager::setFlags(23, val); +} + +int BellbotScript::preprocess(const TTroomScript *roomScript, const TTsentence *sentence) { + if (!roomScript || !sentence) + return true; + + bool applyFlag = false, stateFlag = true; + switch (getValue(23)) { + case 1: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200818)); + applyFlag = true; + } + if (sentence->_field2C == 12) { + addResponse(getDialogueId(200817)); + applyFlag = true; + } + break; + + case 2: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200835)); + addResponse(getDialogueId(200830)); + applyFlag = true; + } else if (sentence->_field2C == 12) { + addResponse(getDialogueId(200834)); + addResponse(getDialogueId(200830)); + applyFlag = true; + } + break; + + case 3: + if (sentence->_field2C >= 11 && sentence->_field2C <= 13) { + addResponse(getDialogueId(200831)); + addResponse(getDialogueId(200833)); + applyFlag = true; + } + break; + + case 4: + if (sentence->_field2C == 11) { + addResponse(getDialogueId(200872)); + applyFlag = true; + } + if (sentence->_field2C == 12 || sentence->_field2C == 13) { + addResponse(getDialogueId(200873)); + applyFlag = true; + } + break; + + case 5: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200492)); + applyFlag = true; + } + if (sentence->_field2C == 12) { + addResponse(getDialogueId(200491)); + applyFlag = true; + } + break; + + case 6: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200496)); + applyResponse(); + setState(0); + CTrueTalkManager::setFlags(23, 7); + return 2; + } + if (sentence->_field2C == 12) { + addResponse(getDialogueId(200127)); + applyFlag = true; + } + break; + + case 7: + addResponse(getDialogueId(200504)); + addResponse(getDialogueId(200496)); + applyFlag = true; + stateFlag = false; + break; + + case 8: + addResponse(getDialogueId(200494)); + applyFlag = true; + stateFlag = false; + break; + + case 9: + addResponse(getDialogueId(sentence->localWord("guess") ? 200495 : 200493)); + applyFlag = true; + break; + + case 10: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200317)); + applyResponse(); + setState(0); + CTrueTalkManager::setFlags(23, 11); + return 2; + } + + addResponse(getDialogueId(sentence->_field2C == 12 ? 200316 : 200315)); + applyFlag = true; + break; + + case 11: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200055)); + } else if (sentence->_field2C == 12) { + addResponse(getDialogueId(200318)); + } else { + addResponse(getDialogueId(200315)); + } + + applyFlag = true; + break; + + case 12: + if (sentence->_field2C == 6) { + addResponse(getDialogueId(200259)); + applyFlag = true; + } + break; + + case 13: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200207)); + applyFlag = true; + } else if (sentence->_field2C == 12) { + addResponse(getDialogueId(200206)); + applyFlag = true; + } + break; + + case 14: + if (sentence->_field2C == 6) { + addResponse(getDialogueId(200349)); + applyFlag = true; + } + + case 15: + if (sentence->_field2C == 6) { + addResponse(getDialogueId(200130)); + applyResponse(); + setState(0); + CTrueTalkManager::setFlags(23, 16); + return 2; + } + break; + + case 16: + if (sentence->localWord("invented")) { + addResponse(getDialogueId(200131)); + applyFlag = true; + } + break; + + case 17: + if ((sentence->_field2C == 3 && sentence->localWord("code")) + || (sentence->localWord("which") && sentence->localWord("is")) + || sentence->localWord("remember") + || sentence->localWord("know") + ) { + addResponse(getDialogueId(200044)); + applyFlag = true; + stateFlag = false; + } + break; + + case 19: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200223)); + applyFlag = true; + } + break; + + case 20: + addResponse(getDialogueId(200254)); + applyFlag = true; + break; + + case 21: + if (sentence->contains("hiker") || sentence->contains("hug")) { + addResponse(getDialogueId(200379)); + applyFlag = true; + } + break; + + case 22: + if (sentence->localWord("get") || sentence->localWord("it")) { + addResponse(getDialogueId(200474)); + applyFlag = true; + } + break; + + case 23: + addResponse(getDialogueId(sentence->localWord("long") ? 200870 : 200871)); + applyFlag = true; + break; + + case 24: + addResponse(getDialogueId(200793)); + applyFlag = true; + stateFlag = false; + break; + + case 25: + if (sentence->localWord("parrot")) { + addResponse(getDialogueId(200255)); + applyFlag = true; + stateFlag = false; + } + break; + + case 26: + if (sentence->localWord("cage")) { + addResponse(getDialogueId(200380)); + applyFlag = true; + stateFlag = false; + } + break; + + case 27: + addResponse(getDialogueId(200347)); + applyFlag = true; + stateFlag = false; + break; + + case 28: + if (sentence->localWord("perch")) { + addResponse(getDialogueId(200242)); + applyFlag = true; + stateFlag = false; + } + break; + + case 29: + if (sentence->localWord("brain") || sentence->localWord("titania")) { + addResponse(getDialogueId(200392)); + applyFlag = true; + stateFlag = false; + } + break; + + case 30: + if ((sentence->localWord("did") || sentence->localWord("not")) + || (sentence->localWord("would") || sentence->localWord("not")) + || (sentence->localWord("could") || sentence->localWord("not")) + || sentence->localWord("tried")) { + addResponse(getDialogueId(200416)); + applyFlag = true; + } + break; + + case 31: + addResponse(getDialogueId(sentence->_field2C == 11 ? 200810 : 200811)); + applyFlag = true; + break; + + case 32: + addResponse(getDialogueId(sentence->_field2C == 11 ? 200810 : 200812)); + applyFlag = true; + break; + + case 33: + addResponse(getDialogueId(200822)); + applyFlag = true; + break; + + case 34: + addResponse(getDialogueId(200824)); + applyFlag = true; + break; + + case 35: + if (sentence->_field2C == 3 && sentence->localWord("it") + && (sentence->localWord("for") || sentence->localWord("do"))) { + addResponse(getDialogueId(200768)); + applyFlag = true; + } + break; + + case 36: + if (sentence->_field2C == 11) { + CTrueTalkManager::triggerAction(14, 0); + addResponse(getDialogueId(200761)); + applyFlag = true; + } + break; + + case 37: + addResponse(getDialogueId(200630)); + applyFlag = true; + break; + + case 38: + if (sentence->_field2C == 12) { + addResponse(getDialogueId(200631)); + applyFlag = true; + } + break; + + case 39: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200632)); + stateFlag = false; + } else { + addResponse(getDialogueId(200633)); + } + applyFlag = true; + break; + + case 40: + addResponse(getDialogueId(200633)); + applyFlag = true; + break; + + case 41: + addResponse(getDialogueId(sentence->contains("42") ? 200139 : 200627)); + applyFlag = true; + break; + + case 42: + if ((sentence->localWord("carry") && sentence->localWord("on")) + || (sentence->localWord("go") && sentence->localWord("on")) + || sentence->localWord("more") + || sentence->localWord("going") + || sentence->localWord("elaborate") + || sentence->localWord("suspicious") + || sentence->localWord("they")) { + addResponse(getDialogueId(200642)); + applyFlag = true; + stateFlag = false; + } + break; + + case 43: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200643)); + applyFlag = true; + } + break; + + case 44: +case44: + if (better(sentence, 200615, 200613)) { + applyFlag = true; + stateFlag = false; + } + break; + + case 45: + if (sentence->contains("surprise")) { + addResponse(getDialogueId(200614)); + applyFlag = true; + stateFlag = false; + break; + } + goto case44; + + case 46: + if (sentence->contains("good")) { + addResponse(getDialogueId(200616)); + applyFlag = true; + stateFlag = false; + break; + } + goto case44; + + case 47: + if (sentence->_field2C == 12) + addResponse(getDialogueId(200368)); + addResponse(getDialogueId(200366)); + applyFlag = true; + stateFlag = false; + break; + + case 48: + if ((sentence->localWord("carry") && sentence->localWord("on")) + || sentence->localWord("more") + || (sentence->localWord("go") && sentence->localWord("on")) + || sentence->localWord("going") + || sentence->localWord("yes") + || sentence->localWord("really")) { + addResponse(getDialogueId(200367)); + applyFlag = true; + } + break; + + case 49: + if (sentence->_field2C >= 11 && sentence->_field2C <= 13) { + addResponse(getDialogueId(200407)); + applyFlag = true; + stateFlag = false; + } + break; + + case 50: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200408)); + stateFlag = false; + } else { + addResponse(getDialogueId(200409)); + } + applyFlag = true; + break; + + case 51: + if (sentence->localWord("no") || sentence->localWord("it") + || sentence->localWord("is") || sentence->localWord("not") + || sentence->contains("yeah right")) { + addResponse(getDialogueId(200636)); + applyFlag = true; + } + break; + + case 52: + if (sentence->_field2C >= 11 && sentence->_field2C <= 13) { + addResponse(getDialogueId(200872)); + applyFlag = true; + } + break; + + case 53: + if (sentence->_field2C == 12) { + addResponse(getDialogueId(200525)); + applyFlag = true; + } else if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200526)); + applyFlag = true; + } + break; + + case 54: + if (sentence->_field2C == 12) { + addResponse(getDialogueId(200095)); + applyFlag = true; + stateFlag = false; + } + break; + + case 55: + if (sentence->_field2C == 6) { + addResponse(getDialogueId(200112)); + applyFlag = true; + } + break; + + case 56: + if (sentence->localWord("sure") + || (sentence->localWord("nothing") && sentence->localWord("else"))) { + addResponse(getDialogueId(200649)); + applyFlag = true; + stateFlag = false; + } + break; + + case 57: + if (sentence->localWord("bad") + || (sentence->localWord("not") && sentence->localWord("good"))) { + addResponse(getDialogueId(200654)); + } else { + addResponse(getDialogueId(200655)); + stateFlag = false; + } + applyFlag = true; + break; + + case 58: + if (sentence->localWord("more") + || (sentence->localWord("go") && sentence->localWord("on")) + || (sentence->_field2C == 11 && sentence->localWord("really"))) { + addResponse(getDialogueId(200650)); + applyFlag = true; + stateFlag = false; + } + break; + + case 59: + if (!sentence->localWord("shutup")) { + addResponse(getDialogueId(200651)); + applyFlag = true; + stateFlag = false; + } + break; + + case 60: + if (sentence->_field2C == 3 && sentence->localWord("they") && sentence->localWord("do")) { + addResponse(getDialogueId(200652)); + applyFlag = true; +stateFlag = false; + } + break; + + case 61: + if ((sentence->localWord("that") && sentence->localWord("all")) + || (sentence->localWord("anything") && sentence->localWord("else"))) { + addResponse(getDialogueId(200653)); + applyFlag = true; + } + break; + + case 62: + if (sentence->localWord("meant") || sentence->localWord("woman")) { + addResponse(getDialogueId(200743)); + applyFlag = true; + } + break; + + case 63: + addResponse(getDialogueId(200208)); + applyFlag = true; + break; + + case 64: + if (sentence->localWord("rowboat")) { + addResponse(getDialogueId(200052)); + applyFlag = true; + } + break; + + case 65: + if (sentence->localWord("sorry")) { + addResponse(getDialogueId(200056)); + applyFlag = true; + stateFlag = false; + } + break; + + case 66: + if (sentence->localWord("sorry")) { + addResponse(getDialogueId(200057)); + applyFlag = true; + stateFlag = false; + } + break; + + case 67: + if (sentence->localWord("sorry")) { + addResponse(getDialogueId(200055)); + applyFlag = true; + stateFlag = false; + } + break; + + case 68: + if ((sentence->localWord("i") && sentence->localWord("care")) + || sentence->localWord("do") + || sentence->localWord("me")) { + addResponse(getDialogueId(201006)); + applyFlag = true; + } + break; + + case 69: + if ((sentence->localWord("what") && sentence->localWord("happen")) + || sentence->localWord("filigon")) { + addResponse(getDialogueId(201011)); + applyFlag = true; + stateFlag = false; + } + break; + + case 70: + if (sentence->_field2C == 12) { + addResponse(getDialogueId(201012)); + applyFlag = true; + stateFlag = false; + } + break; + + case 71: + if (sentence->localWord("why")) { + addResponse(getDialogueId(201013)); + applyFlag = true; + } + break; + + case 72: + if (sentence->_field2C == 12) { + addResponse(getDialogueId(200921)); + applyFlag = true; + } else if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(200920)); + applyFlag = true; + } + break; + + case 73: + if (sentence->localWord("mood") && (charId() == 7 || charId() == 5)) { + addResponse(getDialogueId(201021)); + applyFlag = true; + stateFlag = false; + } + break; + + case 74: + if (sentence->_field2C == 6) { + addResponse(getDialogueId(201022)); + applyFlag = true; + stateFlag = false; + } + break; + + case 75: + if (sentence->_field2C == 3) { + if (sentence->localWord("that") || sentence->localWord("worb")) { + addResponse(getDialogueId(201802)); + applyFlag = true; + } + } + break; + + case 76: + if (sentence->_field2C == 2 && (sentence->localWord("that") || sentence->localWord("gat"))) { + addResponse(getDialogueId(201034)); + applyFlag = true; + stateFlag = false; + } + break; + + case 77: + if (sentence->_field2C == 4 || sentence->_field2C == 3) { + if (sentence->localWord("that") || sentence->localWord("blerontis")) { + addResponse(getDialogueId(201035)); + applyFlag = true; + } + } + break; + + case 78: + if (sentence->_field2C == 12) { + addResponse(getDialogueId(201034)); + applyFlag = true; + stateFlag = false; + } else if (sentence->_field2C == 11) { + addResponse(getDialogueId(201040)); + applyFlag = true; + } else if ((sentence->localWord("not") && sentence->localWord("remember")) + || sentence->localWord("forgot")) { + addResponse(getDialogueId(201041)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("why")) { + addResponse(getDialogueId(201042)); + applyFlag = true; + stateFlag = false; + } + break; + + case 79: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(201052)); + CTrueTalkManager::triggerAction(14, 0); + applyFlag = true; + stateFlag = false; + } else if (sentence->_field2C == 12) { + addResponse(getDialogueId(202119)); + addResponse(getDialogueId(200256)); + applyFlag = true; + } + break; + + case 80: + if ((!sentence->localWord("what") && sentence->localWord("how")) + || sentence->localWord("about") + || sentence->localWord("you")) { + if (sentence->_field2C != 3 && sentence->_field2C != 4 && sentence->_field2C != 7) { + addResponse(getDialogueId(201694)); + applyFlag = true; + stateFlag = false; + } + } else { + addResponse(getDialogueId(201135)); + applyFlag = true; + } + break; + + case 81: + if ((!sentence->localWord("what") && !sentence->localWord("how")) + || !sentence->localWord("about") + || !sentence->localWord("you")) { + if (!sentence->localWord("and") || !sentence->localWord("yourself")) + break; + } + addResponse(getDialogueId(201135)); + applyFlag = true; + break; + + case 82: + if ((sentence->_field2C == 3 && sentence->localWord("mean")) + || sentence->localWord("surf") + || (sentence->localWord("what") && sentence->localWord("talk") + && sentence->localWord("about"))) { + addResponse(getDialogueId(201694)); + applyFlag = true; + stateFlag = false; + } + break; + + case 83: + if (sentence->_field2C != 3 && sentence->_field2C != 4 && sentence->_field2C != 7) { + addResponse(getDialogueId(201083)); + applyFlag = true; + } + break; + + case 84: + if (sentence->_field2C == 12) { + addResponse(getDialogueId(202119)); + + switch (getValue(1)) { + case 1: + addResponse(getDialogueId(202024)); + applyFlag = true; + break; + case 2: + addResponse(getDialogueId(201812)); + applyFlag = true; + stateFlag = false; + break; + default: + break; + } + } else if (sentence->_field2C == 11) { + addResponse(getDialogueId(201060)); + addResponse(getDialogueId(201079)); + applyFlag = true; + stateFlag = false; + } + break; + + case 85: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(201814)); + applyFlag = true; + } + if (sentence->_field2C == 12) { + addResponse(getDialogueId(201813)); + applyFlag = true; + } + break; + + case 86: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(202109)); + applyFlag = true; + } + if (sentence->_field2C == 12) { + addResponse(getDialogueId(202108)); + applyFlag = true; + } + break; + + case 87: + if (better(sentence, 201993, 200720)) { + applyFlag = true; + } + break; + + case 88: + if (sentence->_field2C == 6 || sentence->contains("upside down")) { + addResponse(getDialogueId(202142)); + applyFlag = true; + } + break; + + case 89: + if (sentence->_field2C == 2) { + addResponse(getDialogueId(200739)); + applyFlag = true; + stateFlag = false; + } + break; + + case 90: + if (sentence->contains("like") && (sentence->contains("slug") || sentence->contains("snail"))) { + addResponse(getDialogueId(201029)); + applyFlag = true; + stateFlag = false; + } else if (sentence->contains("slime") || sentence->localWord("what")) { + addResponse(getDialogueId(201220)); + applyFlag = true; + stateFlag = false; + } + + default: + break; + } + + if (applyFlag) + applyResponse(); + if (stateFlag) { + setState(0); + CTrueTalkManager::setFlags(23, 0); + } + + return applyFlag ? 2 : 1; +} + +bool BellbotScript::better(const TTsentence *sentence, uint id1, uint id2) { + if (sentence->contains("good") || sentence->localWord("better")) { + addResponse(getDialogueId(id1)); + } else if (sentence->localWord("bad")) { + addResponse(getDialogueId(id2)); + } else { + return false; + } + + return true; +} + +bool BellbotScript::randomResponse0(const TTroomScript *roomScript, uint id) { + bool dr0 = getDialRegion(0) == 1; + uint newId = getValue(1); + + if (getValue(25) == 0) { + CTrueTalkManager::setFlags(25, 1); + if (getValue(1) > 2) { + addResponse(getDialogueId(202043)); + applyResponse(); + return true; + } + } + + bool result = dr0 ? randomResponse1(roomScript, newId) : + randomResponse2(roomScript, newId); + if (result) + CTrueTalkManager::triggerAction(1, 0); + + return true; +} + +bool BellbotScript::randomResponse1(const TTroomScript *roomScript, uint id) { + if (getRandomNumber(100) < 10) { + addResponse(getDialogueId(201978)); + applyResponse(); + } else { + if (getRandomNumber(100) < 50) + addResponse(getDialogueId(202259)); + + randomResponse3(roomScript, id); + applyResponse(); + } + + return false; +} + +bool BellbotScript::randomResponse2(const TTroomScript *roomScript, uint id) { + if (getRandomNumber(100) < 5) { + addResponse(getDialogueId(202262)); + applyResponse(); + } else { + if (getRandomNumber(100) < 40) + addResponse(getDialogueId(202258)); + + randomResponse4(roomScript, id); + applyResponse(); + } + + return false; +} + +void BellbotScript::randomResponse3(const TTroomScript *roomScript, uint id) { + bool result = false; + if (roomScript && getRandomNumber(100) < 50) + result = addRoomDescription(roomScript); + + if (result) + return; + if (getRandomNumber(100) >= 50) { + addResponse(getDialogueId(202262)); + return; + } + + if (id <= 2) { + if (getRandomNumber(100) < 50) { + addResponse(getDialogueId(202266)); + return; + } else if (id == 2) { + addResponse(getDialogueId(202264)); + return; + } + } + + addResponse(getDialogueId(id == 1 ? 202265 : 202263)); +} + +void BellbotScript::randomResponse4(const TTroomScript *roomScript, uint id) { + if (getRandomNumber(100) < 4 && id <= 2) { + addResponse(getDialogueId(202268)); + } else { + addResponse(getDialogueId(202267)); + } +} + +int BellbotScript::checkCommonSentences(const TTroomScript *roomScript, const TTsentence *sentence) { + if (!roomScript || !sentence) + return 1; + + uint val1 = getValue(1); + for (uint idx = 0; idx < _phrases.size(); ++idx) { + TTcommonPhrase &cp = _phrases[idx]; + + if (cp._roomNum != 0 && cp._roomNum != roomScript->_scriptId) + continue; + if (cp._val1 != 0 && cp._val1 != val1 && (cp._val1 == 3 || val1 != 4)) + continue; + if (!sentence->contains(cp._str.c_str())) + continue; + + addResponse(getDialogueId(cp._dialogueId)); + applyResponse(); + return 2; + } + + return 0; +} + +bool BellbotScript::checkCommonWords(const TTroomScript *roomScript, const TTsentence *sentence) { + if (!roomScript || !sentence) + return 0; + CTrueTalkManager::setFlags(23, 0); + if (sentence->_field2C != 4) + return 0; + + if (sentence->localWord("garage")) { + addResponse(getDialogueId(200874)); + } else if (sentence->localWord("parrotfoodshop")) { + addResponse(getDialogueId(200821)); + } else if (sentence->localWord("sgt") && sentence->localWord("restaurant")) { + addResponse(getDialogueId(200857)); + } else if (sentence->localWord("firstclass") && sentence->localWord("restaurant")) { + addResponse(getDialogueId(200839)); + } else if (sentence->localWord("restaurant")) { + addResponse(getDialogueId(getValue(1) == 1 ? 200839 : 200857)); + } else if (getValue(1) == 1 && sentence->localWord("canal") && sentence->localWord("firstclass")) { + addResponse(getDialogueId(200846)); + } else if (getValue(1) == 2 && sentence->localWord("canal") && sentence->localWord("secondclass")) { + addResponse(getDialogueId(200847)); + } else if (sentence->localWord("canal")) { + addResponse(getDialogueId(getValue(1) == 1 ? 200846 : 200847)); + } else if (sentence->localWord("firstclass") && + (sentence->localWord("stateroom") || sentence->localWord("room"))) { + addResponse(getDialogueId(getValue(1) == 1 ? 200840 : 200306)); + } else if (sentence->localWord("secondclass") && sentence->localWord("stateroom") && sentence->localWord("room")) { + addResponse(getDialogueId(getValue(1) < 3 ? 202231 : 200306)); + } else if (sentence->localWord("stateroom") || sentence->contains("my room")) { + addResponse(getDialogueId(202231)); + } else if (sentence->localWord("firstclass")) { + addResponse(getDialogueId(200840)); + } else if (sentence->localWord("secondclass")) { + addResponse(getDialogueId(200841)); + } else if (sentence->localWord("thirdclass")) { + addResponse(getDialogueId(202231)); + } else if (sentence->localWord("arboretum")) { + addResponse(getDialogueId(200842)); + } else if (sentence->localWord("bar")) { + addResponse(getDialogueId(200843)); + } else if (sentence->localWord("bottomofwell")) { + addResponse(getDialogueId(200860)); + } else if (sentence->localWord("topwell") || sentence->localWord("well")) { + addResponse(getDialogueId(200861)); + } else if (sentence->localWord("bridge")) { + addResponse(getDialogueId(202213)); + } else if (sentence->localWord("creatorroom")) { + addResponse(getDialogueId(200848)); + } else if (sentence->localWord("servicelift")) { + addResponse(getDialogueId(200855)); + } else if (sentence->localWord("lift")) { + addResponse(getDialogueId(202256)); + } else if (sentence->localWord("bilgeroom")) { + addResponse(getDialogueId(202255)); + } else if (sentence->localWord("musicroom")) { + addResponse(getDialogueId(200851)); + } else if (sentence->localWord("parrotlobby")) { + addResponse(getDialogueId(200852)); + } else if (sentence->localWord("parrot") && + (sentence->localWord("room") || sentence->localWord("lobby"))) { + addResponse(getDialogueId(200852)); + } else if (sentence->localWord("promenade")) { + addResponse(getDialogueId(200853)); + } else if (sentence->localWord("sculpture") || sentence->localWord("sculptureroom") + || sentence->localWord("statue")) { + addResponse(getDialogueId(200854)); + } else if (sentence->localWord("lounge")) { + addResponse(getDialogueId(200856)); + } else if (sentence->localWord("titania")) { + if (sentence->localWord("room")) { + addResponse(getDialogueId(200859)); + } else if (sentence->localWord("nose")) { + addResponse(getDialogueId(200703)); + } else if (sentence->localWord("mouth")) { + addResponse(getDialogueId(200702)); + } else if (sentence->localWord("eyes")) { + addResponse(getDialogueId(200701)); + } else if (sentence->localWord("ear")) { + addResponse(getDialogueId(200698)); + } else if (sentence->localWord("brain")) { + addResponse(getDialogueId(200693)); + } else { + addResponse(getDialogueId(200686)); + } + } else if (sentence->localWord("embarklobby") + || sentence->localWord("lobby")) { + addResponse(getDialogueId(200850)); + } else if (sentence->localWord("pellerator")) { + addResponse(getDialogueId(200862)); + } else if (sentence->localWord("servicelift") + || (sentence->localWord("service") && sentence->localWord("elevator"))) { + addResponse(getDialogueId(200855)); + } else if (sentence->localWord("elevator")) { + addResponse(getDialogueId(202256)); + } else if (sentence->localWord("now")) { + addResponse(getDialogueId(200788)); + } else if (sentence->localWord("room")) { + addResponse(getDialogueId(200311)); + } else { + return false; + } + + return true; +} + +uint BellbotScript::getRoomDialogueId(const TTroomScript *roomScript) { + if (!roomScript) + return 0; + + for (int idx = 0; ROOM_DIALOGUE_IDS[idx]._roomNum; ++idx) { + if (ROOM_DIALOGUE_IDS[idx]._roomNum == roomScript->_scriptId) + return ROOM_DIALOGUE_IDS[idx]._dialogueId; + } + + return 0; +} + +bool BellbotScript::addRoomDescription(const TTroomScript *roomScript) { + if (!roomScript) + return false; + + switch (roomScript->_scriptId) { + case 101: + addResponse(getDialogueId(getValue(2) == 1 ? 20185 : 201832)); + break; + case 107: + if (_room107First) { + addResponse(getDialogueId(202162)); + } else { + addResponse(getDialogueId(202162)); + _room107First = true; + } + break; + case 108: + addResponse(getDialogueId(201844)); + break; + case 109: + addResponse(getDialogueId(200303)); + break; + case 110: + addResponse(getDialogueId(202257)); + break; + case 111: + addResponse(getDialogueId(202056)); + break; + case 112: + addResponse(getDialogueId(201828)); + break; + case 113: + addResponse(getDialogueId(201859)); + break; + case 114: + addResponse(getDialogueId(202052)); + break; + case 115: + addResponse(getDialogueId(202004)); + break; + case 116: + addResponse(getDialogueId(202092)); + break; + case 117: + addResponse(getDialogueId(202027)); + break; + case 124: + addResponse(getDialogueId(202110)); + break; + case 125: + addResponse(getDialogueId(202103)); + break; + case 126: + addResponse(getDialogueId(202116)); + break; + case 127: + addResponse(getDialogueId(202111)); + break; + case 128: + addResponse(getDialogueId(201815)); + break; + case 129: + addResponse(getDialogueId(201816)); + break; + case 131: + addResponse(getDialogueId(201930)); + break; + case 132: + addResponse(getDialogueId(201924)); + break; + default: + return false; + } + + return true; +} + + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/bellbot_script.h b/engines/titanic/true_talk/bellbot_script.h new file mode 100644 index 0000000000..3080b56902 --- /dev/null +++ b/engines/titanic/true_talk/bellbot_script.h @@ -0,0 +1,129 @@ +/* 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 TITANIC_BELLBOT_SCRIPT_H +#define TITANIC_BELLBOT_SCRIPT_H + +#include "titanic/true_talk/tt_npc_script.h" + +namespace Titanic { + +class BellbotScript : public TTnpcScript { +private: + static uint _oldId; + TTmapEntryArray _states; + TTmapEntryArray _preResponses; + TTsentenceEntries _sentences[20]; + TTcommonPhraseArray _phrases; + int _array[150]; + int _field2D0; + int _field2D4; + int _field2D8; + int _field2DC; + bool _room107First; +private: + /** + * Setup sentence data + */ + void setupSentences(); + + /** + * Add the current location to the response + */ + int addLocation(); + + /** + * Get a dialogue Id based on the state + */ + int getStateDialogueId() const; + + /** + * Sets the state value 25 based on the passed Id + */ + void setValue23(uint id); + + /** + * Does preprocessing for the sentence + */ + int preprocess(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Checks for good, better, or bad in the sentence + */ + bool better(const TTsentence *sentence, uint id1, uint id2); + + bool randomResponse0(const TTroomScript *roomScript, uint id); + bool randomResponse1(const TTroomScript *roomScript, uint id); + bool randomResponse2(const TTroomScript *roomScript, uint id); + void randomResponse3(const TTroomScript *roomScript, uint id); + void randomResponse4(const TTroomScript *roomScript, uint id); + + int checkCommonSentences(const TTroomScript *roomScript, const TTsentence *sentence); + bool checkCommonWords(const TTroomScript *roomScript, const TTsentence *sentence); + + uint getRoomDialogueId(const TTroomScript *roomScript); + + /** + * Adds a description of the room to the conversation response + */ + bool addRoomDescription(const TTroomScript *roomScript); +public: + BellbotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2); + + /** + * Does NPC specific processing of the parsed sentence + */ + virtual int process(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id); + + virtual int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder); + + /** + * Handles updating NPC state based on specified dialogue Ids and dial positions + */ + virtual int updateState(uint oldId, uint newId, int index); + + /** + * Handles getting a pre-response + */ + virtual int preResponse(uint id); + + /** + * Process a sentence fragment entry + */ + virtual int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Handles a randomzied response + */ + virtual bool randomResponse(uint index); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BELLBOT_SCRIPT_H */ diff --git a/engines/titanic/true_talk/deskbot_script.cpp b/engines/titanic/true_talk/deskbot_script.cpp new file mode 100644 index 0000000000..f3a997e218 --- /dev/null +++ b/engines/titanic/true_talk/deskbot_script.cpp @@ -0,0 +1,1502 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/deskbot_script.h" +#include "titanic/true_talk/true_talk_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +int DeskbotScript::_oldId; + +DeskbotScript::DeskbotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2) : + TTnpcScript(val1, charClass, v2, charName, v3, val2, -1, -1, -1, 0) { + CTrueTalkManager::setFlags(18, 0); + CTrueTalkManager::setFlags(19, 0); + CTrueTalkManager::setFlags(20, 0); + CTrueTalkManager::setFlags(21, 0); + CTrueTalkManager::setFlags(22, 0); + + setupDials(0, 0, 0); + _data[0] = 100; + if (_currentDialNum == 1) + _currentDialNum = 0; + + loadRanges("Ranges/Deskbot"); + loadResponses("Responses/Deskbot", 4); + setupSentences(); + _tagMappings.load("TagMap/Deskbot"); + _words.load("Words/Deskbot"); + _quotes.load("Quotes/Deskbot"); + _states.load("States/Deskbot"); +} + +void DeskbotScript::setupSentences() { + _mappings.load("Mappings/Deskbot", 4); + _entries.load("Sentences/Deskbot"); + _entries2.load("Sentences/Deskbot/2"); + _entries3.load("Sentences/Deskbot/3"); + _dialValues[0] = _dialValues[1] = 0; + _field68 = 0; + _entryCount = 0; +} + +int DeskbotScript::process(const TTroomScript *roomScript, const TTsentence *sentence) { + if (roomScript->_scriptId != 110) + return 2; + + bool flag20 = getValue(20) != 0; + CTrueTalkManager::setFlags(20, 0); + checkItems(nullptr, nullptr); + + if (preprocess(roomScript, sentence) != 1) + return 1; + + CTrueTalkManager::setFlags(17, 0); + setState(0); + updateCurrentDial(false); + + if (getValue(1) == 3) { + if (sentence->localWord("competition") || sentence->contains("competition") + || sentence->localWord("won") || sentence->contains("won") + || sentence->localWord("winning") || sentence->contains("winning") + || sentence->localWord("winner") || sentence->contains("winner") + || sentence->contains("35279") || sentence->contains("3 5 2 7 9") + ) { + addResponse(getDialogueId(41773)); + applyResponse(); + return 2; + } else if (sentence->localWord("magazine") || sentence->contains("magazine")) { + addResponse(getDialogueId(41771)); + applyResponse(); + return 2; + } else if (sentence->localWord("upgrade") || sentence->contains("upgrade")) { + if (CTrueTalkManager::_currentNPC) { + CGameObject *obj; + if (CTrueTalkManager::_currentNPC->find("Magazine", &obj, FIND_PET)) { + addResponse(getDialogueId(41773)); + applyResponse(); + return 2; + } + } + } + } + + if (processEntries(&_entries, _entryCount, roomScript, sentence) != 2 + && processEntries(&_entries2, 0, roomScript, sentence) != 2) { + if (sentence->localWord("sauce") || sentence->localWord("pureed")) { + addResponse(getDialogueId(240398)); + applyResponse(); + } else if (sentence->contains("cherries")) { + addResponse(getDialogueId(240358)); + applyResponse(); + } else if (sentence->contains("42")) { + addResponse(getDialogueId(240453)); + applyResponse(); + } else if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(241778)); + applyResponse(); + } else { + if (sentence->contains("98129812")) + setDialRegion(1, 1); + + if (!defaultProcess(roomScript, sentence) + && processEntries(&_entries3, 0, roomScript, sentence) != 2 + && processEntries(_defaultEntries, 0, roomScript, sentence) != 2) { + if (flag20) + CTrueTalkManager::setFlags(20, 1); + addResponse(getDialogueId(240569)); + applyResponse(); + } + } + } + + return 2; +} + +ScriptChangedResult DeskbotScript::scriptChanged(const TTroomScript *roomScript, uint id) { + switch (id) { + case 3: + case 100: + case 108: + CTrueTalkManager::setFlags(21, getValue(21) + 1); + addResponse(getDialogueId(getValue(22) ? 240577 : 241261)); + applyResponse(); + break; + + case 109: + addResponse(getDialogueId(241627)); + applyResponse(); + break; + + case 140: + if (getValue(1) == 3) + addAssignedRoomDialogue3(); + break; + + case 148: + CTrueTalkManager::setFlags(3, 1); + break; + + case 150: + CTrueTalkManager::setFlags(2, 1); + break; + } + + return SCR_2; +} + +int DeskbotScript::handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder) { + switch (tagId) { + case MKTAG('A', 'D', 'V', 'T'): + case MKTAG('A', 'R', 'T', 'I'): + case MKTAG('A', 'R', 'T', 'Y'): + case MKTAG('B', 'R', 'N', 'D'): + case MKTAG('C', 'O', 'M', 'D'): + case MKTAG('D', 'N', 'C', 'E'): + case MKTAG('H', 'B', 'B', 'Y'): + case MKTAG('L', 'I', 'T', 'R'): + case MKTAG('M', 'A', 'G', 'S'): + case MKTAG('M', 'C', 'P', 'Y'): + case MKTAG('M', 'I', 'N', 'S'): + case MKTAG('M', 'U', 'S', 'I'): + case MKTAG('N', 'I', 'K', 'E'): + case MKTAG('S', 'F', 'S', 'F'): + case MKTAG('S', 'O', 'A', 'P'): + case MKTAG('S', 'O', 'N', 'G'): + case MKTAG('S', 'P', 'R', 'T'): + case MKTAG('T', 'E', 'A', 'M'): + case MKTAG('T', 'V', 'S', 'H'): + tagId = MKTAG('E', 'N', 'T', 'N'); + break; + case MKTAG('A', 'C', 'T', 'R'): + case MKTAG('A', 'C', 'T', 'S'): + case MKTAG('A', 'U', 'T', 'H'): + case MKTAG('B', 'A', 'R', 'K'): + case MKTAG('B', 'A', 'R', 'U'): + case MKTAG('B', 'L', 'F', '1'): + case MKTAG('B', 'L', 'F', '2'): + case MKTAG('B', 'L', 'P', '1'): + case MKTAG('B', 'L', 'P', '2'): + case MKTAG('B', 'L', 'P', '3'): + case MKTAG('B', 'L', 'P', '4'): + case MKTAG('B', 'L', 'R', '1'): + case MKTAG('B', 'L', 'R', '2'): + case MKTAG('B', 'L', 'T', '1'): + case MKTAG('B', 'L', 'T', '2'): + case MKTAG('B', 'L', 'T', '3'): + case MKTAG('B', 'L', 'T', '4'): + case MKTAG('B', 'L', 'T', '5'): + case MKTAG('B', 'O', 'Y', 'S'): + case MKTAG('C', 'O', 'P', 'S'): + case MKTAG('D', 'C', 'T', 'R'): + case MKTAG('F', 'A', 'M', 'E'): + case MKTAG('F', 'A', 'S', 'H'): + case MKTAG('G', 'I', 'R', 'L'): + case MKTAG('H', 'E', 'R', 'O'): + case MKTAG('H', 'O', 'S', 'T'): + case MKTAG('K', 'N', 'O', 'B'): + case MKTAG('N', 'H', 'R', 'O'): + case MKTAG('R', 'A', 'C', 'E'): + case MKTAG('S', 'C', 'I', 'T'): + case MKTAG('T', 'D', 'V', 'P'): + case MKTAG('T', 'W', 'A', 'T'): + case MKTAG('W', 'E', 'A', 'T'): + case MKTAG('W', 'W', 'E', 'B'): + tagId = MKTAG('P', 'R', 'S', 'N'); + break; + case MKTAG('C', 'H', 'S', 'E'): + case MKTAG('C', 'M', 'N', 'T'): + case MKTAG('F', 'I', 'L', 'M'): + case MKTAG('J', 'F', 'O', 'D'): + case MKTAG('L', 'I', 'Q', 'D'): + tagId = MKTAG('F', 'O', 'O', 'D'); + break; + case MKTAG('C', 'R', 'I', 'M'): + case MKTAG('C', 'S', 'P', 'Y'): + case MKTAG('D', 'R', 'U', 'G'): + tagId = MKTAG('V', 'B', 'A', 'D'); + break; + case MKTAG('E', 'A', 'R', 'T'): + case MKTAG('H', 'O', 'M', 'E'): + case MKTAG('N', 'P', 'L', 'C'): + case MKTAG('P', 'L', 'A', 'N'): + tagId = MKTAG('P', 'L', 'A', 'C'); + break; + case MKTAG('F', 'A', 'U', 'N'): + case MKTAG('F', 'I', 'S', 'H'): + case MKTAG('F', 'L', 'O', 'R'): + tagId = MKTAG('N', 'A', 'T', 'R'); + break; + case MKTAG('H', 'H', 'L', 'D'): + case MKTAG('T', 'O', 'Y', 'S'): + case MKTAG('W', 'E', 'A', 'P'): + tagId = MKTAG('M', 'A', 'C', 'H'); + break; + case MKTAG('M', 'L', 'T', 'Y'): + case MKTAG('P', 'G', 'R', 'P'): + case MKTAG('P', 'T', 'I', 'C'): + tagId = MKTAG('G', 'R', 'U', 'P'); + break; + case MKTAG('P', 'K', 'U', 'P'): + case MKTAG('S', 'E', 'X', '1'): + case MKTAG('S', 'W', 'E', 'R'): + tagId = MKTAG('R', 'U', 'D', 'E'); + break; + case MKTAG('P', 'H', 'I', 'L'): + case MKTAG('R', 'C', 'K', 'T'): + tagId = MKTAG('S', 'C', 'I', 'E'); + break; + case MKTAG('T', 'R', 'A', '2'): + case MKTAG('T', 'R', 'A', '3'): + tagId = MKTAG('T', 'R', 'A', 'V'); + break; + default: + break; + } + + return TTnpcScript::handleQuote(roomScript, sentence, val, tagId, remainder); + +} + +int DeskbotScript::updateState(uint oldId, uint newId, int index) { + if (isDial1Medium() || getValue(1) < 4) + CTrueTalkManager::setFlags(22, 1); + + if (newId == 240420 || newId == 240947 || newId == 241261) { + if (getValue(22) && (newId == 240947 || newId == 241261)) + newId = getRangeValue(241184); + } + + if (newId == 240832) + setDialRegion(1, 0); + + if (oldId == 241183) { + if (getValue(1) == 2) + newId = getRangeValue(241182); + else if (getValue(1) == 1) + newId = getRangeValue(241181); + } + + if (newId == 240931 && getValue(1) <= 2) { + newId = 240924; + } else if (newId == 240924 && getValue(1) > 2) { + newId = 240931; + } + + if (newId == 240830 && getValue(1) == 1) { + newId = 240801; + } else if (newId == 240801 && getValue(1) > 1) { + newId = 240830; + } + + if (oldId >= 241217 && oldId <= 241259) { + addResponse(getDialogueId(241202)); + addResponse(getDialogueId(241200)); + newId = getRangeValue(241199); + } + + if (newId == 241354) + newId = addAssignedRoomDialogue2(); + if (newId == 241353) + newId = getStateDialogueId(); + if (newId == 240464 && getValue(1) != 1) + newId = 240462; + + if (newId == 241635 && isDial1Medium()) { + addResponse(getDialogueId(241556)); + newId = getRangeValue(241632); + } + + if (getValue(20) && (oldId == 240569 || oldId == 240576)) + newId = 240460; + if (!getValue(20)) { + if (newId != 240460) + goto exit; + CTrueTalkManager::setFlags(20, 1); + } + if (newId == 240460 && _oldId != 240569) { + CTrueTalkManager::setFlags(20, 0); + newId = 240455; + } + +exit: + _oldId = oldId; + setFlags17(newId, index); + + return newId; +} + +int DeskbotScript::preResponse(uint id) { + int newId = 0; + if (getValue(1) >= 3 && (id == 41176 || id == 41738 || id == 41413 || id == 41740)) + newId = 241601; + + if (id == 42114) + CTrueTalkManager::triggerAction(20, 0); + + return newId; +} + +uint DeskbotScript::getDialsBitset() const { + if (getDialRegion(1)) + return getDialRegion(0) ? 2 : 3; + else + return getDialRegion(0) ? 0 : 1; +} + +int DeskbotScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) { + uint id; + + switch (val1) { + case 1: + id = *srcIdP; + if (id == 240431 || id == 240432) { + switch (getValue(1)) { + case 1: + id = 240336; + break; + case 2: + id = addAssignedRoomDialogue(); + break; + case 3: + if (getValue(3) == 1) { + if (id == 240431) + id = 240432; + } + else { + if (id == 240432) + id = 240431; + } + default: + break; + } + + addResponse(getDialogueId(id)); + applyResponse(); + return 2; + } + break; + + case 2: + if (getValue(1) == 1) + return true; + break; + + default: + break; + } + + return 0; +} + +bool DeskbotScript::randomResponse(uint index) { + if (getValue(1) == 1 || getRandomNumber(100) > 10 || getRandomNumber(2) <= index) + return 0; + + if (getRandomNumber(100) > 95) { + deleteResponses(); + addResponse(getDialogueId(241195)); + applyResponse(); + } else { + setResponseFromArray(index, 241193); + } + + return true; +} + +bool DeskbotScript::isDial0Medium() const { + return getDialRegion(0) == 1; +} + +bool DeskbotScript::isDial0Low() const { + return getDialRegion(0) == 0; +} + +bool DeskbotScript::isDial1Medium() const { + return getDialRegion(1) == 1; +} + +bool DeskbotScript::isDial1Low() const { + return getDialRegion(1) == 0; +} + +uint DeskbotScript::addAssignedRoomDialogue() { + if (isDial1Medium()) { + addResponse(getDialogueId(240407)); + addResponse(getDialogueId(241510)); + CTrueTalkManager::setFlags(1, 1); + CTrueTalkManager::triggerAction(19, 1); + + int roomNum, floorNum, elevatorNum; + getAssignedRoom(&roomNum, &floorNum, &elevatorNum); + + addResponse(getDialogueId(241317 + roomNum)); + addResponse(getDialogueId(241271 + floorNum)); + addResponse(getDialogueId(241511)); + addResponse(getDialogueId(241313 + elevatorNum)); + + return 241512; + } else { + return 240567; + } +} + +uint DeskbotScript::addAssignedRoomDialogue2() { + addResponse(getDialogueId(241355)); + int roomNum = 0, floorNum = 0, elevatorNum = 0; + getAssignedRoom(&roomNum, &floorNum, &elevatorNum); + + addResponse(getDialogueId(241317 + roomNum)); + addResponse(getDialogueId(241271 + floorNum)); + addResponse(getDialogueId(241356)); + addResponse(getDialogueId(241313 + elevatorNum)); + + return 241357; +} + +void DeskbotScript::addAssignedRoomDialogue3() { + addResponse(getDialogueId(241513)); + addResponse(getDialogueId(241510)); + + CTrueTalkManager::setFlags(1, 2); + setDialRegion(0, 0); + setDialRegion(1, 0); + CTrueTalkManager::triggerAction(19, 2); + CTrueTalkManager::setFlags(3, 0); + + int roomNum = 1, floorNum = 1, elevatorNum = 1; + getAssignedRoom(&roomNum, &floorNum, &elevatorNum); + + addResponse(getDialogueId(241317 + roomNum)); + addResponse(getDialogueId(241271 + floorNum)); + addResponse(getDialogueId(241511)); + addResponse(getDialogueId(241313 + elevatorNum)); + addResponse(getDialogueId(241512)); + applyResponse(); +} + +uint DeskbotScript::getStateDialogueId() const { + switch (getValue(1)) { + case 1: + return 241503; + case 2: + return 241504; + default: + return 241505; + } +} + +void DeskbotScript::setFlags17(uint newId, uint index) { + int newValue = getValue(17); + + for (uint idx = 0; idx < _states.size(); ++idx) { + const TTupdateState &us = _states[idx]; + if (newId == (idx == 0 ? 0 : us._newId)) { + uint bits = us._dialBits; + + if (!bits + || (index == 1 && (bits & 1) && (bits & 4)) + || (index == 0 && (bits & 2) && (bits & 4)) + || (index == 3 && (bits & 1) && (bits & 8)) + || (index == 2 && (bits & 2) && (bits & 8))) { + newValue = us._newValue; + break; + } + } + } + + CTrueTalkManager::setFlags(17, newValue); +} + +int DeskbotScript::preprocess(const TTroomScript *roomScript, const TTsentence *sentence) { + if (!roomScript || !sentence) + return 1; + + bool stateFlag = true, applyFlag = false; + switch (getValue(17)) { + case 1: + if (sentence->_field2C != 3 && sentence->_field2C != 4 + && sentence->_field2C != 6 && sentence->_field2C != 10 + && sentence->_field2C != 2) { + addResponse(getDialogueId(240423)); + applyFlag = true; + } + break; + + case 2: + if (sentence->localWord("gobbledygook")) { + addResponse(getDialogueId(240427)); + applyFlag = true; + } + break; + + case 3: + if (sentence->_field2C == 11 || sentence->_field2C == 13 + || sentence->_field2C == 3 || sentence->localWord("upgrade")) { + addResponse(getDialogueId(240433)); + applyFlag = true; + } + break; + + case 4: + addResponse(getDialogueId(sentence->_field2C == 11 || sentence->_field2C == 13 + ? 240495 : 240494)); + applyFlag = true; + break; + + case 5: + if (isDial1Low() && getValue(1) == 4) { + if (sentence->localWord("name") || sentence->localWord("called") + || sentence->localWord("passenger")) { + addResponse(getDialogueId(240867)); + addResponse(getDialogueId(240745)); + } else { + addResponse(getDialogueId(240446)); + } + + applyFlag = true; + stateFlag = false; + } + break; + + case 6: + if (isDial1Low() && getValue(1) == 4) { + if (sentence->localWord("passenger")) { + addResponse(getDialogueId(240449)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("home") + || sentence->localWord("destroy")) { + addResponse(getDialogueId(240574)); + stateFlag = true; + } else if (sentence->localWord("name") + || sentence->localWord("called") + || sentence->_field2C == 11) { + addResponse(getDialogueId(240448)); + stateFlag = true; + } else { + addResponse(getDialogueId(240489)); + stateFlag = true; + } + } + break; + + case 7: + if (sentence->_field2C == 11 || sentence->_field2C == 13 + || (sentence->localWord("what") && sentence->localWord("wrong")) + || sentence->localWord("clothes")) { + addResponse(getDialogueId(240489)); + applyFlag = true; + stateFlag = false; + } + break; + + case 8: + if (isDial1Low() && getValue(1) == 4) { + if (sentence->_field2C == 12 || sentence->_field2C == 13 + || sentence->contains("do not")) { + + addResponse(getDialogueId(240447)); + setDialRegion(0, 0); + setDialRegion(1, 0); + CTrueTalkManager::setFlags(1, 3); + CTrueTalkManager::triggerAction(19, 3); + CTrueTalkManager::setFlags(22, 1); + applyFlag = true; + } else if (sentence->_field2C == 11) { + addResponse(getDialogueId(240746)); + applyFlag = true; + stateFlag = false; + } else { + addResponse(getDialogueId(240448)); + applyFlag = true; + stateFlag = false; + } + } + break; + + case 9: + if (searchQuotes(roomScript, sentence)) { + if (isDial0Medium()) { + addResponse(getDialogueId(240382)); + applyFlag = true; + stateFlag = false; + } else { + addResponse(getDialogueId(240548)); + applyFlag = true; + } + } + break; + + case 10: + if (isDial1Medium() && searchQuotes(roomScript, sentence)) { + if (isDial0Medium()) { + addResponse(getDialogueId(240405)); + applyFlag = true; + stateFlag = false; + } else { + addResponse(getDialogueId(240548)); + applyFlag = true; + } + } + break; + + case 11: + if (isDial0Medium() && isDial1Medium() + && searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240403)); + applyFlag = true; + stateFlag = false; + } + break; + + case 12: + if (isDial0Medium() && isDial1Medium() + && searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240548)); + applyFlag = true; + stateFlag = false; + } + break; + + case 13: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240348)); + applyFlag = true; + stateFlag = false; + } + break; + + case 14: + if (isDial1Medium()) { + addResponse(getDialogueId(240568)); + applyFlag = true; + stateFlag = false; + } + break; + + case 15: + if (sentence->localWord("magazine")) { + addAssignedRoomDialogue3(); + stateFlag = true; + } + break; + + case 17: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240401)); + applyFlag = true; + stateFlag = false; + } + break; + + case 18: + if (!isDial0Low() || !isDial1Low()) { + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240402)); + applyFlag = true; + stateFlag = false; + } + } + break; + + case 19: + if (!isDial0Low() && searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240403)); + applyFlag = true; + stateFlag = false; + } + break; + + case 20: + if (!isDial1Medium() && searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240548)); + applyFlag = true; + } + break; + + case 21: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240382)); + applyFlag = true; + stateFlag = false; + } + break; + + case 22: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240383)); + applyFlag = true; + stateFlag = false; + } + break; + + case 23: + if (isDial0Medium() && searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240384)); + applyFlag = true; + stateFlag = false; + } + break; + + case 24: + setDialRegion(0, 0); + + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240548)); + applyFlag = true; + } + break; + + case 25: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240349)); + applyFlag = true; + stateFlag = false; + } + break; + + case 26: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240350)); + applyFlag = true; + stateFlag = false; + } + break; + + case 27: + case 30: + case 33: + case 36: + case 40: + case 43: + case 46: + case 50: + case 55: + case 58: + case 61: + case 68: + case 73: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240548)); + applyFlag = true; + } + break; + + case 28: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240373)); + applyFlag = true; + stateFlag = false; + } + break; + + case 29: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240374)); + applyFlag = true; + stateFlag = false; + } + break; + + case 31: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240346)); + applyFlag = true; + stateFlag = false; + } + break; + + case 32: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240347)); + applyFlag = true; + stateFlag = false; + } + break; + + case 34: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240376)); + applyFlag = true; + stateFlag = false; + } + break; + + case 35: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240377)); + applyFlag = true; + stateFlag = false; + } + break; + + case 37: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240369)); + applyFlag = true; + stateFlag = false; + } + break; + + case 38: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240370)); + applyFlag = true; + stateFlag = false; + } + break; + + case 39: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240371)); + applyFlag = true; + stateFlag = false; + } + break; + + case 41: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240352)); + applyFlag = true; + stateFlag = false; + } + break; + + case 42: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240353)); + applyFlag = true; + stateFlag = false; + } + break; + + case 44: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240389)); + applyFlag = true; + stateFlag = false; + } + break; + + case 45: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240390)); + applyFlag = true; + stateFlag = false; + } + break; + + case 47: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240395)); + applyFlag = true; + stateFlag = false; + } + break; + + case 48: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240396)); + applyFlag = true; + stateFlag = false; + } + break; + + case 49: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240397)); + applyFlag = true; + stateFlag = false; + } + break; + + case 51: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240363)); + applyFlag = true; + stateFlag = false; + } + break; + + case 52: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240364)); + applyFlag = true; + stateFlag = false; + } + break; + + case 53: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240365)); + applyFlag = true; + stateFlag = false; + } + break; + + case 54: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240366)); + applyFlag = true; + stateFlag = false; + } + break; + + case 56: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240392)); + applyFlag = true; + stateFlag = false; + } + break; + + case 57: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240393)); + applyFlag = true; + stateFlag = false; + } + break; + + case 59: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240386)); + applyFlag = true; + stateFlag = false; + } + break; + + case 60: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240387)); + applyFlag = true; + stateFlag = false; + } + break; + + case 62: + if (isDial1Medium() && getValue(1) == 1) { + if (isDial0Medium()) { + if (sentence->localWord("down")) { + addResponse(getDialogueId(240413)); + applyFlag = true; + } + } else if (sentence->contains("left") || sentence->contains("right")) { + addResponse(getDialogueId(240415)); + CTrueTalkManager::triggerAction(sentence->localWord("down") ? 22 : 23, 0); + } else { + addResponse(getDialogueId(240414)); + applyFlag = true; + } + } + break; + + case 63: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240836)); + applyFlag = true; + stateFlag = false; + } + break; + + case 64: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240837)); + applyFlag = true; + stateFlag = false; + } + break; + + case 65: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240838)); + applyFlag = true; + stateFlag = false; + } + break; + + case 66: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240839)); + applyFlag = true; + stateFlag = false; + } + break; + + case 67: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(240840)); + applyFlag = true; + stateFlag = false; + } + break; + + case 69: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(241104)); + applyFlag = true; + stateFlag = false; + } + break; + + case 70: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(241105)); + applyFlag = true; + stateFlag = false; + } + break; + + case 71: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(241106)); + applyFlag = true; + stateFlag = false; + } + break; + + case 72: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(241107)); + applyFlag = true; + stateFlag = false; + } + break; + + case 74: + case 75: + if (sentence->_field2C == 24) { + addResponse(getDialogueId(240972)); + applyFlag = true; + } else if (sentence->localWord("good") || sentence->localWord("yes") + || sentence->localWord("well") || sentence->localWord("ill") + || sentence->localWord("sad")) { + addResponse(getDialogueId(240805)); + applyFlag = true; + } + break; + + case 76: + if (sentence->_field2C == 6) { + addResponse(getDialogueId(240767)); + applyFlag = true; + stateFlag = false; + } + break; + + case 77: + if (sentence->_field2C == 3) { + addResponse(getDialogueId(241109)); + applyFlag = true; + stateFlag = false; + } + + case 78: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(241262)); + } else if (sentence->_field2C == 12 || sentence->contains("do not")) { + setDialRegion(0, 0); + setDialRegion(1, 0); + addResponse(getDialogueId(241268)); + add241716(); + } else { + addResponse(getDialogueId(240745)); + } + + applyFlag = true; + stateFlag = false; + break; + + case 79: + switch (checkCommonWords(sentence)) { + case 1: + addResponse(getDialogueId(241263)); + break; + case 2: + addResponse(getDialogueId(241266)); + break; + case 3: + addAssignedRoom(); + setState(0); + CTrueTalkManager::setFlags(17, 0); + return 2; + default: + addResponse(getDialogueId(241267)); + break; + } + + add241716(); + applyFlag = true; + stateFlag = false; + break; + + case 81: + addResponse(getDialogueId(sentence->_field2C == 12 ? 240602 : 241337)); + applyResponse(); + setState(0); + CTrueTalkManager::setFlags(17, 0); + return 2; + + case 82: + if (sentence->_field2C == 2) { + addResponse(getDialogueId(241339)); + applyFlag = true; + } + break; + + case 83: + if ((isDial1Medium() && isDial0Low()) || + (isDial1Low() && isDial0Medium())) { + if (sentence->localWord("yes") || sentence->localWord("but")) { + if (sentence->localWord("will") || sentence->localWord("do")) { + addResponse(getDialogueId(241366)); + applyFlag = true; + } + } + } + break; + + case 84: + if (sentence->_field2C == 12 || sentence->contains("vegetarian") + || sentence->contains("vegitarian")) { + addResponse(getDialogueId(241718)); + addResponse(getDialogueId(241709)); + applyFlag = true; + stateFlag = false; + } else if (sentence->contains("continental") + || sentence->contains("full") + || sentence->contains("porky") + || sentence->contains("the 1") + || sentence->contains("the 2") + || sentence->contains("former") + || sentence->contains("latter")) { + addResponse(getDialogueId(241717)); + addResponse(getDialogueId(241709)); + applyFlag = true; + stateFlag = false; + } else { + if (sentence2C(sentence)) + addResponse(getDialogueId(241707)); + addResponse(getDialogueId(241719)); + applyFlag = true; + stateFlag = false; + } + break; + + case 85: + if (sentence->_field2C == 12 || sentence->contains("bugle") + || sentence->contains("buggle") || sentence->contains("trumpet") + || sentence->contains("saxophone") || sentence->contains("kazoo") + || sentence->contains("blerontin 1") || sentence->contains("the 1") + || sentence->contains("the 2") || sentence->contains("the 3") + || sentence->contains("the 4") || sentence->contains("all of them") + || sentence->contains("the lot")) { + addResponse(getDialogueId(241710)); + addResponse(getDialogueId(241713)); + } else { + if (getRandomNumber(100) < 80 && sentence2C(sentence)) + addResponse(getDialogueId(241707)); + + addResponse(getDialogueId(241711)); + } + + applyFlag = true; + stateFlag = false; + break; + + case 86: + if (sentence->_field2C == 12 || sentence->_field2C == 11 || sentence->contains("view")) { + addResponse(getDialogueId(241714)); + addResponse(getDialogueId(241699)); + } else { + if (getRandomNumber(100) < 80 && sentence2C(sentence)) + addResponse(getDialogueId(241707)); + + if (getRandomNumber(100) < 50) { + addResponse(getDialogueId(241715)); + } else { + addResponse(getDialogueId(241712)); + addResponse(getDialogueId(241713)); + } + + } + + applyFlag = true; + stateFlag = false; + break; + + case 87: + if (sentence->contains("corner") || sentence->contains("on the end") + || sentence->contains("balcony") || sentence->contains("neither") + || sentence->contains("the 1") || sentence->contains("the 2") + || sentence->contains("former") || sentence->contains("latter") + || sentence->contains("either")) { + addResponse(getDialogueId(241700)); + addResponse(getDialogueId(241687)); + } else { + if (getRandomNumber(100) < 80 && sentence2C(sentence)) + addResponse(getDialogueId(241707)); + + addResponse(getDialogueId(241701)); + addResponse(getDialogueId(241699)); + } + + applyFlag = true; + stateFlag = false; + break; + + case 88: + if (sentence->contains("imperial") || sentence->contains("the 1")) { + addResponse(getDialogueId(241700)); + addResponse(getDialogueId(241739)); + } else if (sentence->contains("royal") || sentence->contains("the 2")) { + addResponse(getDialogueId(241690)); + } else if (sentence->contains("despotic") || sentence->contains("the last") + || sentence->contains("latter")) { + addResponse(getDialogueId(241688)); + } else if (sentence->contains("president") || sentence->contains("presidential") + || sentence->contains("the 3")) { + addResponse(getDialogueId(241689)); + } else { + if (getRandomNumber(100) < 80 && sentence2C(sentence)) + addResponse(getDialogueId(241707)); + + addResponse(getDialogueId(241692)); + } + + applyFlag = true; + stateFlag = false; + break; + + case 89: + if (sentence->contains("king")) { + addResponse(getDialogueId(241691)); + } else if (sentence->contains("queen") || sentence->contains("prince") + || sentence->contains("princess") || sentence->contains("small") + || sentence->contains("the 1") || sentence->contains("the 2") + || sentence->contains("the 3") || sentence->contains("the 4") + || sentence->contains("big") || sentence->contains("large")) { + addResponse(getDialogueId(241700)); + addResponse(getDialogueId(241739)); + } else { + if (getRandomNumber(100) < 100 && sentence2C(sentence)) + addResponse(getDialogueId(241707)); + + addResponse(getDialogueId(241690)); + } + + applyFlag = true; + stateFlag = false; + break; + + case 90: + if (sentence->contains("constitutional") || sentence->contains("const") + || sentence->contains("absolute") || sentence->contains("small") + || sentence->contains("the 1") || sentence->contains("the 2") + || sentence->contains("big") || sentence->contains("large")) { + addResponse(getDialogueId(241700)); + addResponse(getDialogueId(241739)); + } else { + if (getRandomNumber(100) < 80 && sentence2C(sentence)) + addResponse(getDialogueId(241708)); + + addResponse(getDialogueId(241691)); + } + + applyFlag = true; + stateFlag = false; + break; + + case 91: + if (sentence->contains("benev") || sentence->contains("dict") + || sentence->contains("small") || sentence->contains("the 1") + || sentence->contains("the 2") || sentence->contains("big") + || sentence->contains("large") || sentence->contains("former") + || sentence->contains("latter")) { + addResponse(getDialogueId(241700)); + addResponse(getDialogueId(241739)); + } else { + if (getRandomNumber(100) < 80 && sentence2C(sentence)) + addResponse(getDialogueId(241708)); + + addResponse(getDialogueId(241688)); + } + + applyFlag = true; + stateFlag = false; + break; + + case 92: + case 93: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(241077)); + addResponse(getDialogueId(241706)); + } else if (sentence->_field2C == 12) { + addAssignedRoom(); + setState(0); + CTrueTalkManager::setFlags(17, 0); + return 2; + } else if (g_vm->_trueTalkManager->_quotes.find(sentence->_normalizedLine.c_str()) + == MKTAG('F', 'I', 'S', 'H')) { + addResponse(getDialogueId(240877)); + addResponse(getDialogueId(241706)); + }else { + if (getRandomNumber(100) < 80 && sentence2C(sentence)) + addResponse(getDialogueId(241707)); + + addResponse(getDialogueId(241705)); + if (getRandomNumber(100) < 80) + addResponse(getDialogueId(241739)); + } + + applyFlag = true; + stateFlag = false; + break; + + case 94: + if (sentence->contains("seperate") || sentence->contains("separate") + || sentence->contains("detached") || sentence->contains("outside") + || sentence->contains("onsweet") || sentence->contains("ensuite") + || sentence->contains("suite") || sentence->contains("next door") + || sentence->contains("the 1") || sentence->contains("the 2") + || sentence->contains("former") || sentence->contains("latter") + || sentence->contains("same room")) { + addAssignedRoom(); + setState(0); + CTrueTalkManager::setFlags(17, 0); + return 2; + } else { + if (getRandomNumber(100) < 80 && sentence2C(sentence)) + addResponse(getDialogueId(241707)); + addResponse(getDialogueId(241706)); + applyFlag = true; + stateFlag = false; + } + break; + + case 95: + if (isDial1Medium()) { + if ((sentence->localWord("i") && sentence->localWord("am")) + || sentence->localWord("me")) { + addResponse(getDialogueId(240632)); + applyFlag = true; + stateFlag = false; + } + } + break; + + case 96: + if (sentence->_field2C == 2) { + addResponse(getDialogueId(241350)); + applyFlag = true; + stateFlag = false; + } + break; + + case 97: + if (searchQuotes(roomScript, sentence)) { + addResponse(getDialogueId(241351)); + applyFlag = true; + stateFlag = false; + } + break; + + default: + break; + } + + if (applyFlag) + applyResponse(); + if (stateFlag) { + setState(0); + CTrueTalkManager::setFlags(17, 0); + } + + return applyFlag ? 2 : 1; +} + +int DeskbotScript::searchQuotes(const TTroomScript *roomScript, const TTsentence *sentence) { + TTtreeResult treeResult; + return g_vm->_trueTalkManager->_quotesTree.search(sentence->_normalizedLine.c_str(), + TREE_2, &treeResult, 0, 0) != -1; +} + +int DeskbotScript::checkCommonWords(const TTsentence *sentence) { + if (sentence->contains("xyzzy")) + return 3; + + const TTquotes "es = g_vm->_trueTalkManager->_quotes; + if (quotes._loaded) { + uint tagId = quotes.find(sentence->_normalizedLine.c_str()); + if (tagId == MKTAG('F', 'U', 'L', 'N') + || tagId == MKTAG('T', 'D', 'V', 'P') + || tagId == MKTAG('H', 'E', 'R', 'O') + || sentence->contains("douglas adam")) + return 1; + else if (tagId == MKTAG('J', 'N', 'A', 'M') + || tagId == MKTAG('N', 'I', 'K', 'N') + || tagId == MKTAG('B', 'O', 'Y', 'S') + || tagId == MKTAG('G', 'I', 'R', 'L')) + return 2; + } else { + if (sentence->contains("douglas adams") + || sentence->contains("shaikh") + || sentence->contains("millican") + || sentence->contains("williams") + || sentence->contains("henkes") + || sentence->contains("kenny")) + return 1; + else if (sentence->contains("richard") + || sentence->contains("jason") + || sentence->contains("mike") + || sentence->contains("renata")) + return 2; + } + + return 0; +} + +void DeskbotScript::add241716() { + addResponse(getDialogueId(241716)); +} + +void DeskbotScript::addAssignedRoom() { + addResponse(getDialogueId(241696)); + addResponse(getDialogueId(241697)); + CTrueTalkManager::setFlags(1, 3); + CTrueTalkManager::triggerAction(19, 3); + CTrueTalkManager::setFlags(22, 1); + + int roomNum = 1, floorNum = 1, elevatorNum = 1; + getAssignedRoom(&roomNum, &floorNum, &elevatorNum); + addResponse(getDialogueId(241313 + elevatorNum)); + addResponse(getDialogueId(241271 + floorNum)); + addResponse(getDialogueId(241317 + roomNum)); + addResponse(getDialogueId(241698)); +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/deskbot_script.h b/engines/titanic/true_talk/deskbot_script.h new file mode 100644 index 0000000000..f5978553ce --- /dev/null +++ b/engines/titanic/true_talk/deskbot_script.h @@ -0,0 +1,157 @@ +/* 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 TITANIC_DESKBOT_SCRIPT_H +#define TITANIC_DESKBOT_SCRIPT_H + +#include "common/array.h" +#include "titanic/true_talk/tt_npc_script.h" + +namespace Titanic { + +class DeskbotScript : public TTnpcScript { +private: + static int _oldId; + TTupdateStateArray _states; + TTsentenceEntries _entries2; + TTsentenceEntries _entries3; +private: + /** + * Setup sentence data + */ + void setupSentences(); + + /** + * Adds dialogue for the player's assigned room + */ + uint addAssignedRoomDialogue(); + + /** + * Adds dialogue for the player's assigned room + */ + uint addAssignedRoomDialogue2(); + + /** + * Adds dialogue for the player's assigned room + */ + void addAssignedRoomDialogue3(); + + /** + * Gets a dialogue Id based on the NPC's state + */ + uint getStateDialogueId() const; + + /** + * Sets state data in flags 17 + */ + void setFlags17(uint newId, uint index); + + /** + * Does preprocessing for the sentence + */ + int preprocess(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Scans the quotes tree + */ + int searchQuotes(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Checks for common words + */ + int checkCommonWords(const TTsentence *sentence); + + /** + * Adds response dialogue 241716 + */ + void add241716(); + + /** + * Adds a dialogue description for the player's assigned room + */ + void addAssignedRoom(); +public: + DeskbotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2); + + /** + * Does NPC specific processing of the parsed sentence + */ + virtual int process(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id); + + virtual int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder); + + /** + * Handles updating NPC state based on specified dialogue Ids and dial positions + */ + virtual int updateState(uint oldId, uint newId, int index); + + /** + * Handles getting a pre-response + */ + virtual int preResponse(uint id); + + /** + * Returns a bitset of the first three dialgs being on or not + */ + virtual uint getDialsBitset() const; + + /** + * Process a sentence fragment entry + */ + virtual int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Handles a randomzied response + */ + virtual bool randomResponse(uint index); + + /** + * Returns true if dial 1 is the medium (1) region + */ + virtual bool isDial0Medium() const; + + /** + * Returns true if dial 0 is the low end region + */ + virtual bool isDial0Low() const; + + /** + * Returns true if dial 1 is the medium (1) region + */ + bool isDial1Medium() const; + + /** + * Returns true if dial 1 is the low end region + */ + virtual bool isDial1Low() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DESKBOT_SCRIPT_H */ diff --git a/engines/titanic/true_talk/dialogue_file.cpp b/engines/titanic/true_talk/dialogue_file.cpp new file mode 100644 index 0000000000..34eb164779 --- /dev/null +++ b/engines/titanic/true_talk/dialogue_file.cpp @@ -0,0 +1,109 @@ +/* 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 "titanic/true_talk/dialogue_file.h" + +namespace Titanic { + +void DialogueIndexEntry::load(Common::SeekableReadStream &s) { + _v1 = s.readUint32LE(); + _offset = s.readUint32LE(); +} + +/*------------------------------------------------------------------------*/ + +CDialogueFile::CDialogueFile(const CString &filename, uint count) { + if (!_file.open(filename)) + error("Could not locate dialogue file - %s", filename.c_str()); + + _cache.resize(count); + + _file.readUint32LE(); // Skip over file Id + _index.resize(_file.readUint32LE()); + + // Read in the entries + for (uint idx = 0; idx < _index.size(); ++idx) + _index[idx].load(_file); +} + +CDialogueFile::~CDialogueFile() { + clear(); +} + +void CDialogueFile::clear() { + _file.close(); +} + +DialogueResource *CDialogueFile::addToCache(int index) { + if (_index.size() == 0 || index < 0 || index >= (int)_index.size() + || _cache.empty()) + return nullptr; + + // Scan cache for a free slot + uint cacheIndex = 0; + while (cacheIndex < _cache.size() && !_cache[cacheIndex]._active) + ++cacheIndex; + if (cacheIndex == _cache.size()) + return nullptr; + + DialogueIndexEntry &indexEntry = _index[index]; + DialogueResource &res = _cache[cacheIndex]; + + res._active = true; + res._offset = indexEntry._offset; + res._bytesRead = 0; + res._entryPtr = &indexEntry; + + // Figure out the size of the entry + if (index == ((int)_index.size() - 1)) { + res._size = _file.size() - indexEntry._offset; + } else { + res._size = _index[index + 1]._offset - indexEntry._offset; + } + + // Return a pointer to the loaded entry + return &res; +} + +bool CDialogueFile::closeEntry(DialogueResource *cacheEntry) { + if (!cacheEntry || !cacheEntry->_active) + return false; + + cacheEntry->_active = false; + return true; +} + +bool CDialogueFile::read(DialogueResource *cacheEntry, byte *buffer, size_t bytesToRead) { + // Sanity checks that a valid record is passed, and the size can be read + if (!cacheEntry || !cacheEntry->_active || !bytesToRead + || (cacheEntry->_bytesRead + bytesToRead) > cacheEntry->_size) + return false; + + // Move to the correct position in the file + _file.seek(cacheEntry->_offset + cacheEntry->_bytesRead); + bool result = _file.read(buffer, bytesToRead) == bytesToRead; + cacheEntry->_bytesRead += bytesToRead; + + return result; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/dialogue_file.h b/engines/titanic/true_talk/dialogue_file.h new file mode 100644 index 0000000000..19e94cf9b9 --- /dev/null +++ b/engines/titanic/true_talk/dialogue_file.h @@ -0,0 +1,100 @@ +/* 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 TITANIC_DIALOGUE_FILE_H +#define TITANIC_DIALOGUE_FILE_H + +#include "titanic/support/simple_file.h" +#include "titanic/support/string.h" + +namespace Titanic { + +struct DialogueIndexEntry { + uint _v1, _offset; + + DialogueIndexEntry() : _v1(0), _offset(0) {} + void load(Common::SeekableReadStream &s); +}; + +struct DialogueResource { + bool _active; + uint _offset, _bytesRead, _size; + DialogueIndexEntry *_entryPtr; + + DialogueResource() : _active(false), _offset(0), + _bytesRead(0), _size(0), _entryPtr(nullptr) {} + + /** + * Return the size of a cache entry + */ + size_t size() const { return _active ? _size : 0; } +}; + +class CDialogueFile { +private: + File _file; + Common::Array<DialogueIndexEntry> _index; + Common::Array<DialogueResource> _cache; +private: + /** + * Add a dialogue file entry to the active cache + */ + DialogueResource *addToCache(int index); +public: + CDialogueFile(const CString &filename, uint count); + ~CDialogueFile(); + + /** + * Clear the loaded data + */ + void clear(); + + File *getFile() { return &_file; } + + /** + * Sets up a text entry within the dialogue file for access + */ + DialogueResource *openTextEntry(int index) { + return addToCache(index * 2); + } + + /** + * Sets up a wave (sound) entry within the dialogue file for access + */ + DialogueResource *openWaveEntry(int index) { + return addToCache(index * 2 + 1); + } + + /** + * Removes an entry from the cache + */ + bool closeEntry(DialogueResource *cacheEntry); + + /** + * Read data for a resource + */ + bool read(DialogueResource *cacheEntry, byte *buffer, size_t bytesToRead); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TITLE_ENGINE_H */ diff --git a/engines/titanic/true_talk/doorbot_script.cpp b/engines/titanic/true_talk/doorbot_script.cpp new file mode 100644 index 0000000000..1ca1ab13e5 --- /dev/null +++ b/engines/titanic/true_talk/doorbot_script.cpp @@ -0,0 +1,1013 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/doorbot_script.h" +#include "titanic/true_talk/tt_room_script.h" +#include "titanic/true_talk/true_talk_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +static const int STATE_ARRAY[9] = { + 0x2E2A, 0x2E2B, 0x2E2C, 0x2E2D, 0x2E2E, 0x2E2F, 0x2E30, 0x2E31, 0x2E32 +}; + +static const RoomDialogueId ROOM_DIALOGUES1[] = { + { 100, 10523 }, { 101, 10499 }, { 107, 10516 }, { 108, 10500 }, + { 109, 10490 }, { 110, 10504 }, { 111, 10506 }, { 112, 10498 }, + { 113, 10502 }, { 114, 10507 }, { 115, 10497 }, { 116, 10508 }, + { 117, 10505 }, { 118, 10505 }, { 122, 10516 }, { 123, 10383 }, + { 124, 10510 }, { 125, 10511 }, { 126, 10513 }, { 127, 10512 }, + { 128, 10495 }, { 129, 10496 }, { 130, 10491 }, { 131, 10493 }, + { 132, 10492 }, { 0, 0 } +}; +static const RoomDialogueId ROOM_DIALOGUES2[] = { + { 102, 221981 }, { 110, 221948 }, { 111, 221968 }, { 107, 222000 }, + { 101, 221935 }, { 112, 221924 }, { 113, 221942 }, { 116, 221977 }, + { 124, 221987 }, { 125, 221984 }, { 127, 221991 }, { 128, 221916 }, + { 129, 221919 }, { 131, 221912 }, { 132, 221908 }, { 0, 0 } +}; + +DoorbotScript::DoorbotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) : + TTnpcScript(val1, charClass, v2, charName, v3, val2, v4, v5, v6, v7) { + loadRanges("Ranges/Doorbot"); + loadResponses("Responses/Doorbot"); + setupSentences(); + _tagMappings.load("TagMap/Doorbot"); + _words.load("Words/Doorbot"); + _quotes.load("Quotes/Doorbot"); + _states.load("States/Doorbot"); +} + +void DoorbotScript::setupSentences() { + for (int idx = 35; idx < 40; ++idx) + CTrueTalkManager::setFlags(idx, 0); + _doorbotState = 1; + _field68 = 0; + _entryCount = 0; + _dialValues[0] = _dialValues[1] = 100; + + _mappings.load("Mappings/Doorbot", 4); + _entries.load("Sentences/Doorbot"); + + static const int SENTENCE_NUMS[11] = { + 2, 100, 101, 102, 107, 110, 111, 124, 129, 131, 132 + }; + for (int idx = 0; idx < 11; ++idx) { + _sentences[idx] = TTsentenceEntries(); + _sentences[idx].load(CString::format("Sentences/Doorbot/%d", SENTENCE_NUMS[idx])); + } +} + +int DoorbotScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) { + if (tag == MKTAG('D', 'N', 'A', '1') || tag == MKTAG('H', 'H', 'G', 'Q') || + tag == MKTAG('A', 'N', 'S', 'W') || tag == MKTAG('S', 'U', 'M', 'S')) { + if (_stateIndex > 9) + _stateIndex = 0; + addResponse(STATE_ARRAY[_stateIndex]); + applyResponse(); + + if (STATE_ARRAY[_stateIndex] == 11826) + setState(1); + ++_stateIndex; + return 2; + } + + if (tag == MKTAG('C', 'H', 'S', 'E') || tag == MKTAG('C', 'M', 'N', 'T') || + tag == MKTAG('J', 'F', 'O', 'D')) + tag = MKTAG('F', 'O', 'O', 'D'); + + if (tag == MKTAG('F', 'O', 'O', 'D') && roomScript->_scriptId == 132) { + return setResponse(getDialogueId(220818)); + } + + if (tag == MKTAG('T', 'R', 'A', 'V')) { + return setResponse(11858 - getRandomBit()); + } else if (tag == MKTAG('C', 'S', 'P', 'Y')) { + return setResponse(10405, 3); + } else if (tag == MKTAG('S', 'C', 'I', 'T')) { + return setResponse(10410, 14); + } else if (tag == MKTAG('L', 'I', 'T', 'E')) { + return setResponse(10296, 17); + } else if (tag == MKTAG('D', 'O', 'R', '1')) { + return setResponse(getDialogueId(222034)); + } else if (tag == MKTAG('W', 'T', 'H', 'R')) { + return setResponse(getDialogueId(222126)); + } else if (tag == MKTAG('N', 'A', 'U', 'T')) { + return setResponse(getDialogueId(222259)); + } else if (tag == MKTAG('T', 'R', 'A', '2')) { + return setResponse(getRandomBit() ? 11860 : 11859); + } else if (tag == MKTAG('T', 'R', 'A', '3')) { + return setResponse(getRandomBit() ? 11859 : 11858); + } else if (tag == MKTAG('B', 'R', 'N', 'D')) { + switch (getRandomNumber(3)) { + case 1: + tag = MKTAG('B', 'R', 'N', '2'); + break; + case 2: + tag = MKTAG('B', 'R', 'N', '3'); + break; + default: + break; + } + } + + return TTnpcScript::chooseResponse(roomScript, sentence, tag); +} + +int DoorbotScript::process(const TTroomScript *roomScript, const TTsentence *sentence) { + int currState; + + switch (roomScript->_scriptId) { + case 100: + case 101: + case 102: + case 103: + case 104: + case 106: + case 107: + case 108: + case 109: + case 110: + case 111: + case 113: + case 116: + case 117: + case 118: + case 122: + case 123: + case 124: + case 125: + case 126: + case 127: + case 128: + case 129: + case 130: + case 131: + case 132: + break; + + default: + return 2; + } + + checkItems(nullptr, nullptr); + if (getState() == 0) { + if (CTrueTalkManager::_v2 > getValue(36)) { + if (getDialRegion(1) == 1 && getRandomBit()) { + setDialRegion(0, getDialRegion(1) ? 0 : 1); + } else { + setDialRegion(1, getDialRegion(1) ? 0 : 1); + } + CTrueTalkManager::setFlags(36, CTrueTalkManager::_v2 + 3 + getRandomNumber(5)); + + if (getValue(37)) { + CTrueTalkManager::setFlags(37, 0); + setState(0); + return setResponse(getDialogueId(221140)); + } + } + } + + if (getValue(35) == 0 && roomScript->_scriptId != 100 && sentence->localWord("parrot")) { + CTrueTalkManager::setFlags(35, 1); + setState(0); + return setResponse(getDialogueId(220113)); + } + + if (sentence->_field2C == 6 && sentence->contains("why not")) { + return setResponse(11871, 8); + } + + currState = getState(); + if (currState) { + int sentMode = sentence->_field2C; + bool flag1 = sentMode == 11 || sentMode == 13; + bool flag2 = sentMode == 12; + + switch (currState) { + case 1: + if (flag1) + return setResponse(11828, 2); + if (flag2) + return setResponse(11827, 0); + break; + + case 2: + if (flag1) + return setResponse(11827, 0); + break; + + case 3: + if (sentMode == 3) + return setResponse(10406, 0); + break; + + case 4: + if (flag1) + return setResponse(11332, 0); + if (flag2) + return setResponse(11331, 0); + break; + + case 5: + return setResponse(11868, 0); + + case 6: + return setResponse(11872, 0); + + case 7: + return setResponse(11869, 0); + + case 8: + return setResponse(11870, 0); + + case 12: + if (flag1) + return setResponse(11894, 13); + if (flag2) + return setResponse(11893, 13); + break; + + case 13: + return setResponse(11895, 12); + + case 15: + if (sentMode == 3 || sentMode == 6) + return setResponse(10257, 0); + break; + + case 16: { + TTtreeResult treeResult; + if (g_vm->_trueTalkManager->_quotesTree.search(sentence->_normalizedLine.c_str(), + TREE_3, &treeResult, 0, nullptr) != -1) + return setResponse(getDialogueId(221380), 0); + break; + } + + case 17: + return setResponse(getDialogueId(221126), 0); + + case 18: + if (flag1) + return setResponse(getDialogueId(221135), 0); + if (flag2) + return setResponse(getDialogueId(221134), 0); + break; + + case 19: + if (flag1) { + if (addRandomResponse(true)) { + setState(10); + return 2; + } + } + if (flag2) + return setResponse(getDialogueId(221966), 0); + break; + + case 20: + if (flag1) { + if (addRandomResponse(true)) { + setState(19); + return 2; + } + } + if (flag2 || sentMode == 7 || sentMode == 10) { + return setResponse(getDialogueId(221879), 0); + } + break; + + case 21: + if (flag2) + return setResponse(10935, 0); + break; + + case 22: + if (flag1) { + if (getRandomBit()) { + return setResponse(11211, 23); + } else { + return setResponse(10127, 0); + } + } + if (flag2) + return setResponse(10136, 0); + break; + + case 23: + return setResponse(10212, 0); + + case 24: + if (flag1) + return setResponse(11151, 0); + if (flag2) + return setResponse(11150, 0); + break; + + case 25: + case 26: + if (flag2) { + if (getRandomBit()) { + return setResponse(11211, 23); + } else { + return setResponse(10127, 0); + } + } + if (flag1) + return setResponse(10136, 0); + break; + + case 27: + if (flag1 || sentence->localWord("did") || sentence->contains("did")) + return setResponse(221175, 28); + break; + + case 28: + if (flag1 || sentence->localWord("did") || sentence->contains("did")) + return setResponse(getDialogueId(221176), 29); + break; + + case 29: + if (flag1 || sentence->localWord("did") || sentence->contains("did")) + return setResponse(getDialogueId(221177), 30); + break; + + case 30: + return setResponse(getDialogueId(221178), 31); + + case 31: + if (sentMode == 3 || sentMode == 10) + return setResponse(10350, 0); + break; + + case 32: + return setResponse(10110, 0); + + case 33: + if (sentence->contains("sieve") || sentence->contains("colander") + || sentence->contains("vegetable") || sentence->contains("ground") + || sentence->contains("earth") || sentence->contains("garden") + || sentence->contains("cheese") || sentence->contains("strainer")) { + return setResponse(getDialogueId(221375), 0); + } else if (getRandomNumber(100) > 30) { + return setResponse(getDialogueId(221376), 33); + } else { + return setResponse(getDialogueId(221376), 0); + } + break; + + case 34: + if (sentence->localWord("bellbot")) + return setResponse(10094, 0); + if (sentence->localWord("bellbot")) + return setResponse(10349, 0); + if (sentence->localWord("deskbot") || sentence->localWord("titania")) + return setResponse(10148, 0); + if (sentence->localWord("barbot") || sentence->localWord("rowbot") + || sentence->localWord("liftbot") || sentence->localWord("maitredbot")) + return setResponse(10147, 0); + break; + + case 35: + return setResponse(10811, 36); + + case 36: + if (flag1) + return setResponse(10813, 37); + if (flag2) + return setResponse(10812, 37); + break; + + case 37: + if (flag1) + return setResponse(10815, 37); + if (flag2) + return setResponse(10814, 37); + break; + + case 38: + return setResponse(10848, 39); + + case 39: + return setResponse(10823, 40); + + case 40: + return setResponse(10832, 41); + + case 41: + addResponse(10833); + return setResponse(10835, 0); + + case 42: + if (sentence->localWord("please")) + return setResponse(10840, 43); + return setResponse(10844, 0); + + case 43: + case 45: + return setResponse(10844, 0); + + case 44: + if (sentence->localWord("thanks")) + return setResponse(10843, 45); + return setResponse(10844, 0); + + case 46: + if (flag1) + return setResponse(getDialogueId(222251), 0); + if (flag2) + return setResponse(10713, 0); + break; + + } + } + + if (currState != 14) + setState(0); + + if (getDialRegion(1) != 1 && getRandomNumber(100) > 92) + return setResponse(getDialogueId(221043), 0); + + int result = 0; + switch (roomScript->_scriptId) { + case 100: + case 101: + case 102: + case 107: + case 110: + case 111: + case 124: + case 129: + case 131: + case 132: + result = processEntries(&_sentences[roomScript->_scriptId], 0, roomScript, sentence); + break; + default: + break; + } + if (result == 2) + return 2; + + if (processEntries(&_entries, _entryCount, roomScript, sentence) == 2 + || processEntries(_defaultEntries, 0, roomScript, sentence) == 2 + || defaultProcess(roomScript, sentence)) + return 2; + + switch (sentence->_field2C) { + case 11: + if (getRandomNumber(100) > 90) + return setResponse(10839, 42); + return setResponse(222415, 0); + + case 12: + if (getRandomNumber(100) > 90) + return setResponse(10841, 44); + return setResponse(getDialogueId(222416), 0); + + case 13: + return setResponse(getDialogueId(222415), 0); + + default: + if (getRandomNumber(100) > 75 && getStateValue()) + return setResponse(getDialogueId(221095)); + + if (processEntries(&_sentences[2], 0, roomScript, sentence) != 2) + return setResponse(getDialogueId(220000)); + break; + } + + return 2; +} + +ScriptChangedResult DoorbotScript::scriptChanged(const TTroomScript *roomScript, uint id) { + if (id == 3) { + if (roomScript != nullptr && roomScript->_scriptId != 100) { + if (CTrueTalkManager::_v9 == 101) { + addResponse(getDialogueId(220873)); + applyResponse(); + } else { + bool flag = false; + if (CTrueTalkManager::_currentNPC) { + CGameObject *obj; + if (CTrueTalkManager::_currentNPC->find("Magazine", &obj, FIND_PET)) { + setResponse(getDialogueId(222248), 46); + flag = true; + } + } + + if (!flag) { + if (getRandomNumber(100) > 80 && getStateValue()) { + addResponse(getDialogueId(221095)); + applyResponse(); + flag = true; + } + + if (!flag && (_doorbotState || !fn10(true))) { + addResponse(getDialogueId(220074)); + applyResponse(); + } + } + } + } + + _doorbotState = 0; + resetFlags(); + CTrueTalkManager::_v9 = 0; + } else if (id == 4) { + setState(0); + if (getValue(38) == 0) { + addResponse(getDialogueId(220883)); + applyResponse(); + } + + CTrueTalkManager::setFlags(38, 0); + CTrueTalkManager::setFlags(39, 0); + } + + if (id >= 220000 && id <= 222418) { + addResponse(getDialogueId(id)); + applyResponse(); + } else if (id >= 10000 && id <= 11986) { + addResponse(id); + applyResponse(); + } + + return SCR_2; +} + +int DoorbotScript::handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder) { + switch (tagId) { + case MKTAG('A', 'D', 'V', 'T'): + case MKTAG('A', 'R', 'T', 'I'): + case MKTAG('A', 'R', 'T', 'Y'): + case MKTAG('B', 'R', 'N', 'D'): + case MKTAG('C', 'O', 'M', 'D'): + case MKTAG('D', 'N', 'C', 'E'): + case MKTAG('H', 'B', 'B', 'Y'): + case MKTAG('L', 'I', 'T', 'R'): + case MKTAG('M', 'A', 'G', 'S'): + case MKTAG('M', 'C', 'P', 'Y'): + case MKTAG('M', 'I', 'N', 'S'): + case MKTAG('M', 'U', 'S', 'I'): + case MKTAG('N', 'I', 'K', 'E'): + case MKTAG('S', 'F', 'S', 'F'): + case MKTAG('S', 'O', 'A', 'P'): + case MKTAG('S', 'O', 'N', 'G'): + case MKTAG('S', 'P', 'R', 'T'): + case MKTAG('T', 'E', 'A', 'M'): + case MKTAG('T', 'V', 'S', 'H'): + case MKTAG('W', 'W', 'E', 'B'): + tagId = MKTAG('E', 'N', 'T', 'N'); + break; + case MKTAG('A', 'C', 'T', 'R'): + case MKTAG('A', 'C', 'T', 'S'): + case MKTAG('A', 'U', 'T', 'H'): + case MKTAG('B', 'A', 'R', 'K'): + case MKTAG('B', 'A', 'R', 'U'): + case MKTAG('B', 'L', 'F', '1'): + case MKTAG('B', 'L', 'F', '2'): + case MKTAG('B', 'L', 'P', '1'): + case MKTAG('B', 'L', 'P', '2'): + case MKTAG('B', 'L', 'P', '3'): + case MKTAG('B', 'L', 'P', '4'): + case MKTAG('B', 'L', 'T', '1'): + case MKTAG('B', 'L', 'T', '2'): + case MKTAG('B', 'L', 'T', '3'): + case MKTAG('B', 'L', 'T', '4'): + case MKTAG('B', 'L', 'T', '5'): + case MKTAG('B', 'O', 'Y', 'S'): + case MKTAG('D', 'C', 'T', 'R'): + case MKTAG('F', 'A', 'M', 'E'): + case MKTAG('F', 'A', 'S', 'H'): + case MKTAG('G', 'I', 'R', 'L'): + case MKTAG('H', 'E', 'R', 'O'): + case MKTAG('H', 'O', 'S', 'T'): + case MKTAG('K', 'N', 'O', 'B'): + case MKTAG('N', 'H', 'R', 'O'): + case MKTAG('R', 'A', 'C', 'E'): + case MKTAG('S', 'C', 'I', 'T'): + case MKTAG('T', 'D', 'V', 'P'): + case MKTAG('T', 'W', 'A', 'T'): + case MKTAG('W', 'E', 'A', 'T'): + tagId = MKTAG('P', 'R', 'S', 'N'); + break; + case MKTAG('C', 'H', 'S', 'E'): + case MKTAG('C', 'M', 'N', 'T'): + case MKTAG('F', 'I', 'L', 'M'): + case MKTAG('J', 'F', 'O', 'D'): + case MKTAG('L', 'I', 'Q', 'D'): + tagId = MKTAG('F', 'O', 'O', 'D'); + break; + case MKTAG('C', 'R', 'I', 'M'): + case MKTAG('C', 'S', 'P', 'Y'): + case MKTAG('D', 'R', 'U', 'G'): + tagId = MKTAG('V', 'B', 'A', 'D'); + break; + case MKTAG('E', 'A', 'R', 'T'): + case MKTAG('H', 'O', 'M', 'E'): + case MKTAG('N', 'P', 'L', 'C'): + case MKTAG('P', 'L', 'A', 'N'): + tagId = MKTAG('P', 'L', 'A', 'C'); + break; + case MKTAG('F', 'A', 'U', 'N'): + case MKTAG('F', 'I', 'S', 'H'): + case MKTAG('F', 'L', 'O', 'R'): + tagId = MKTAG('N', 'A', 'T', 'R'); + break; + case MKTAG('H', 'H', 'L', 'D'): + case MKTAG('T', 'O', 'Y', 'S'): + case MKTAG('W', 'E', 'A', 'P'): + tagId = MKTAG('M', 'A', 'C', 'H'); + break; + case MKTAG('M', 'L', 'T', 'Y'): + case MKTAG('P', 'G', 'R', 'P'): + case MKTAG('P', 'T', 'I', 'C'): + tagId = MKTAG('G', 'R', 'U', 'P'); + break; + case MKTAG('P', 'K', 'U', 'P'): + case MKTAG('S', 'E', 'X', '1'): + case MKTAG('S', 'W', 'E', 'R'): + tagId = MKTAG('R', 'U', 'D', 'E'); + break; + case MKTAG('P', 'H', 'I', 'L'): + case MKTAG('R', 'C', 'K', 'T'): + tagId = MKTAG('S', 'C', 'I', 'E'); + break; + case MKTAG('T', 'R', 'A', '2'): + case MKTAG('T', 'R', 'A', '3'): + tagId = MKTAG('T', 'R', 'A', 'V'); + break; + default: + break; + } + + return TTnpcScript::handleQuote(roomScript, sentence, val, tagId, remainder); +} + +int DoorbotScript::updateState(uint oldId, uint newId, int index) { + getValue(38); + bool flag39 = getValue(39) != 0; + CTrueTalkManager::setFlags(38, 0); + CTrueTalkManager::setFlags(39, 0); + + if (newId > 220890) { + switch (newId) { + case 221064: + return getValue(1) == 2 ? newId : 221062; + case 221080: + return getValue(1) >= 2 ? newId : 221066; + case 221078: + case 221079: + return getValue(1) >= 3 ? newId : 221065; + case 221081: + return getValue(7) == 0 ? newId : 221070; + case 221251: + CTrueTalkManager::triggerAction(28, 0); + break; + default: + break; + } + } else if (newId >= 220883) { + CTrueTalkManager::setFlags(38, 1); + CTrueTalkManager::triggerAction(28, 0); + } else if (newId >= 220076) { + switch (newId) { + case 220078: + case 220080: + case 220081: + case 220082: + case 220083: + case 220084: + if (flag39) + return getRangeValue(221381); + break; + default: + break; + } + + CTrueTalkManager::setFlags(39, 1); + } else if (newId == 220075) { + if (flag39) + return getRangeValue(221381); + CTrueTalkManager::setFlags(39, 1); + } else if (newId == 220038) { + return 220038; + } + + for (uint idx = 0; idx < _states.size(); ++idx) { + TTupdateState &us = _states[idx]; + if (us._newId == newId) { + uint bits = us._dialBits; + + if (!bits + || (index == 0 && (bits == 5 || bits == 1)) + || (index == 1 && (bits == 6 || bits == 2)) + || (index == 2 && (bits == 9 || bits == 1)) + || (index == 3 && (bits == 10 || bits == 2))) { + setState(us._newValue); + break; + } + } + } + + return newId; +} + +int DoorbotScript::preResponse(uint id) { + uint newId = 0; + if (getDialRegion(0) != 1 && getRandomNumber(100) > 60) { + addResponse(11195); + newId = 222193; + } + + return newId; +} + +uint DoorbotScript::getDialsBitset() const { + uint bits = 0; + if (!getDialRegion(1)) + bits = 1; + if (!getDialRegion(0)) + bits |= 2; + + return bits; +} + +int DoorbotScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) { + int id2, id = 0; + + switch (val1) { + case 2: + if (getValue(1) != 1) + return 1; + break; + case 3: + if (getValue(1) != 2) + return 1; + break; + case 4: + if (getValue(1) != 3) + return 1; + break; + case 5: + if (getValue(1) == 3) + return 1; + case 6: + if (getRoom54(132)) + return 1; + break; + case 9: + if (sentence->localWord("my") || sentence->contains("my")) + return true; + id2 = getRoomDialogueId1(roomScript); + if (id2) { + addResponse(id2); + applyResponse(); + return 2; + } + break; + case 11: + switch (getValue(1)) { + case 1: + id = 220837; + break; + case 2: + id = 220849; + break; + default: + id = 220858; + break; + } + break; + case 12: + if (getValue(4) != 1) + id = 221157; + break; + case 13: + if (getValue(4) != 2) + id = 221157; + break; + case 14: + if (getValue(4) != 3) + id = 221157; + break; + case 15: + if (getValue(4) != 0) + id = 221157; + break; + case 16: + if (!sentence->localWord("weather")) + return true; + switch (getRandomNumber(4)) { + case 1: + if (getValue(4) != 0) + id = 221354 - getRandomNumber(2) ? -489 : 0; + break; + case 2: + switch (getValue(4)) { + case 0: + id = 220851; + break; + case 1: + id = 221268; + break; + case 2: + id = 221270; + break; + default: + id = 220865; + } + break; + case 3: + id = 221280; + break; + default: + break; + } + break; + case 17: + if (getState()) + return 1; + setState(0); + break; + case 18: + if (roomScript->_scriptId == 100) { + CTrueTalkManager::triggerAction(3, 0); + return 2; + } + break; + case 19: + CTrueTalkManager::_v9 = 104; + CTrueTalkManager::triggerAction(4, 0); + break; + case 20: + CTrueTalkManager::triggerAction(28, 0); + break; + case 22: + CTrueTalkManager::triggerAction(29, 1); + break; + case 23: + CTrueTalkManager::triggerAction(29, 2); + break; + case 24: + CTrueTalkManager::triggerAction(29, 3); + break; + case 25: + CTrueTalkManager::triggerAction(29, 4); + break; + case 26: + if (!sentence->localWord("my") && !sentence->contains("my")) + return 1; + break; + case 27: + if (!sentence->localWord("earth") && !sentence->contains("earth")) + return 1; + break; + case 28: + id2 = getRoomDialogueId2(roomScript); + if (id2) { + addResponse(id2); + applyResponse(); + return 2; + } + break; + case 29: + if (sentence->localWord("another") || sentence->localWord("more") || + sentence->localWord("additional") || sentence->contains("another") || + sentence->contains("more") || sentence->contains("additional")) { + addResponse(getDialogueId(220058)); + applyResponse(); + return 2; + } + break; + case 30: + if (!sentence->localWord("because") && !sentence->contains("because")) + return 1; + break; + case 0x200: + if (getValue(4) != 1) + id = 221157; + break; + case 0x201: + if (getValue(4) != 2) + id = 221157; + break; + case 0x202: + if (getValue(4) != 3) + id = 221157; + break; + case 0x203: + if (getValue(4) != 0) + id = 221157; + break; + default: + break; + } + + if (id) { + addResponse(getDialogueId(id)); + applyResponse(); + return 2; + } else { + return 0; + } +} + +void DoorbotScript::setDialRegion(int dialNum, int region) { + TTnpcScript::setDialRegion(dialNum, region); + if (dialNum == 1 && region != 1) { + CTrueTalkManager::setFlags(37, dialNum); + } else { + addResponse(getDialogueId(221777)); + applyResponse(); + } +} + +bool DoorbotScript::randomResponse(uint index) { + static const int DIALOGUE_IDS[] = { + 220133, 220074, 220000, 220008, 220009, 220010, 220011, + 220012, 220013, 220014, 220015, 220016, 221053, 221054, + 221055, 221056, 221057, 221058, 221059, 221060, 221061, + 221173, 221174, 221175, 221176, 221177, 222415, 222416, + 221157, 221165, 221166, 221167, 221168, 221169, 221170, + 221171, 221172, 221158, 221159, 221356, 221364, 221365, + 221366, 221367, 221368, 221369, 221370, 221371, 221357, + 221358, 221359, 221360, 221252, 221019, 221355, 220952, + 220996, 220916, 220924, 220926, 220931, 220948, 220956, + 220965, 220967, 220968, 220980, 220981, 220982, 220983, + 220984, 220988, 220903, 221095, 222202, 222239, 221758, + 221759, 221762, 221763, 221766, 221767, 221768, 0 + }; + + int *dataP = _data.getSlot(index); + bool flag = false; + for (const int *idP = DIALOGUE_IDS; *idP && !flag; ++idP) { + flag = *idP == *dataP; + } + + if (flag || (getDialRegion(1) != 1 && getRandomNumber(100) > 33) + || getRandomNumber(8) <= index) + return false; + + if (getRandomNumber(100) > 40) { + deleteResponses(); + addResponse(getDialogueId(221242)); + applyResponse(); + } else { + setResponseFromArray(index, 221245); + } + + return true; +} + +int DoorbotScript::setResponse(int dialogueId, int v34) { + addResponse(dialogueId); + applyResponse(); + + if (v34 != -1) + setState(v34); + return 2; +} + +int DoorbotScript::getRoomDialogueId1(const TTroomScript *roomScript) { + for (const RoomDialogueId *r = ROOM_DIALOGUES1; r->_roomNum; ++r) { + if (r->_roomNum == roomScript->_scriptId) + return getDialogueId(r->_dialogueId); + } + + return 0; +} + +int DoorbotScript::getRoomDialogueId2(const TTroomScript *roomScript) { + for (const RoomDialogueId *r = ROOM_DIALOGUES2; r->_roomNum; ++r) { + if (r->_roomNum == roomScript->_scriptId) + return getDialogueId(r->_dialogueId); + } + + return 0; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/doorbot_script.h b/engines/titanic/true_talk/doorbot_script.h new file mode 100644 index 0000000000..78ebcbfd68 --- /dev/null +++ b/engines/titanic/true_talk/doorbot_script.h @@ -0,0 +1,113 @@ +/* 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 TITANIC_DOORBOT_SCRIPT_H +#define TITANIC_DOORBOT_SCRIPT_H + +#include "common/hashmap.h" +#include "titanic/true_talk/tt_npc_script.h" + +namespace Titanic { + +class DoorbotScript : public TTnpcScript { + typedef Common::HashMap<uint, TTsentenceEntries> SentenceEntriesMap; +private: + TTupdateStateArray _states; + SentenceEntriesMap _sentences; + int _stateIndex; + int _doorbotState; +private: + /** + * Setup sentence data + */ + void setupSentences(); + + /** + * Sets a response + */ + int setResponse(int dialogueId, int v34 = -1); + + /** + * Gets the dialogue Id for a given room + */ + int getRoomDialogueId1(const TTroomScript *roomScript); + + /** + * Gets the dialogue Id for a given room + */ + int getRoomDialogueId2(const TTroomScript *roomScript); +public: + DoorbotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7); + + /** + * Chooses and adds a conversation response based on a specified tag Id. + */ + virtual int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag); + + /** + * Does NPC specific processing of the parsed sentence + */ + virtual int process(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id); + + virtual int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder); + + /** + * Handles updating NPC state based on specified dialogue Ids and dial positions + */ + virtual int updateState(uint oldId, uint newId, int index); + + /** + * Handles getting a pre-response + */ + virtual int preResponse(uint id); + + /** + * Returns a bitset of the dials being off or not + */ + virtual uint getDialsBitset() const; + + /** + * Process a sentence fragment entry + */ + virtual int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Sets a given dial to be pointing in a specified region (0 to 2) + */ + virtual void setDialRegion(int dialNum, int region); + + /** + * Handles a randomzied response + */ + virtual bool randomResponse(uint index); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DOORBOT_SCRIPT_H */ diff --git a/engines/titanic/true_talk/liftbot_script.cpp b/engines/titanic/true_talk/liftbot_script.cpp new file mode 100644 index 0000000000..ab995b71b9 --- /dev/null +++ b/engines/titanic/true_talk/liftbot_script.cpp @@ -0,0 +1,695 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/liftbot_script.h" +#include "titanic/true_talk/true_talk_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +int LiftbotScript::_stateIndex; + +static const int STATE_ARRAY[7] = { + 0x78BE, 0x78C0, 0x78C1, 0x78C2, 0x78C3, 0x78C4, 0x78C5 +}; + +LiftbotScript::LiftbotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) : + TTnpcScript(val1, charClass, v2, charName, v3, val2, v4, v5, v6, v7) { + _stateIndex = 0; + + loadRanges("Ranges/Liftbot"); + loadResponses("Responses/Liftbot"); + setupSentences(); + _tagMappings.load("TagMap/Liftbot"); + _words.load("Words/Liftbot"); + _quotes.load("Quotes/Liftbot"); + _states.load("States/Liftbot"); +} + +void LiftbotScript::setupSentences() { + CTrueTalkManager::setFlags(27, 0); + setupDials(getRandomNumber(40) + 60, getRandomNumber(40) + 60, 0); + + _mappings.load("Mappings/Liftbot", 4); + _entries.load("Sentences/Liftbot"); + _field68 = 0; + _entryCount = 0; +} + +int LiftbotScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) { + switch (tag) { + case MKTAG('D', 'N', 'A', '1'): + case MKTAG('H', 'H', 'G', 'Q'): + case MKTAG('A', 'N', 'S', 'W'): + if (_stateIndex >= 7) { + selectResponse(30918); + setState(2); + _stateIndex = 0; + } else { + addResponse(STATE_ARRAY[_stateIndex++]); + } + + applyResponse(); + return 2; + + case MKTAG('O', 'R', 'D', '8'): + addResponse(30475); + addResponse(30467); + addResponse(30466); + addResponse(30474); + applyResponse(); + return SS_2; + + default: + return TTnpcScript::chooseResponse(roomScript, sentence, tag); + } +} + +int LiftbotScript::process(const TTroomScript *roomScript, const TTsentence *sentence) { + if (roomScript->_scriptId != 103) + return 2; + + checkItems(roomScript, sentence); + int currState = getState(); + int sentMode = sentence->_field2C; + TTtreeResult treeResult; + + if (currState) { + setState(0); + bool flag1 = sentMode == 11 || sentMode == 13; + bool flag2 = sentMode == 12; + + switch (currState) { + case 2: + if (flag1) + return addDialogueAndState(30920, 3); + if (flag2) + return addDialogueAndState(30919, 1); + break; + + case 3: + if (flag1) + return addDialogueAndState(30919, 1); + break; + + case 4: + return addDialogueAndState(210391, 1); + + case 5: + if (sentence->contains("reborzo") || sentence->contains("is that")) + return addDialogueAndState(30515, 1); + break; + + case 6: + if (sentMode == 6) + return addDialogueAndState(getDialogueId(210771), 1); + break; + + case 7: + case 8: + if (sentMode == 6 || sentMode == 10) + return addDialogueAndState(getDialogueId(210099), 1); + break; + + case 9: + if (sentMode == 10 || g_vm->_trueTalkManager->_quotesTree.search( + sentence->_normalizedLine.c_str(), TREE_2, &treeResult, 0, 0) != -1) + return addDialogueAndState(getDialogueId(210970), 9); + break; + + default: + break; + } + } + + updateCurrentDial(true); + if (processEntries(&_entries, _entryCount, roomScript, sentence) == 2) + return 2; + + if (sentence->localWord("injury") || sentence->localWord("illness")) { + addResponse(getDialogueId(210059)); + applyResponse(); + } else if (processEntries(_defaultEntries, 0, roomScript, sentence) != 2 + && !defaultProcess(roomScript, sentence) + && !sentence1(sentence)) { + if (getDialRegion(1) != 0 && getRandomNumber(100) <= 20) { + addResponse(getDialogueId(210906)); + addResponse(getDialogueId(210901)); + } else { + addResponse(getDialogueId(210590)); + } + applyResponse(); + } + + return 2; +} + +ScriptChangedResult LiftbotScript::scriptChanged(uint id) { + return scriptChanged(nullptr, id); +} + +ScriptChangedResult LiftbotScript::scriptChanged(const TTroomScript *roomScript, uint id) { + switch (id) { + case 3: + if (getValue(27) == 0) { + addResponse(getDialogueId(210018)); + } else if (getStateValue()) { + addResponse(getDialogueId(210682)); + } else { + addResponse(getDialogueId(210033)); + } + CTrueTalkManager::setFlags(27, 1); + break; + + case 155: + selectResponse(30446); + applyResponse(); + break; + + case 156: + if (getCurrentFloor() == 1) { + addResponse(getDialogueId(210614)); + } else { + selectResponse(30270); + } + applyResponse(); + break; + + default: + break; + } + + if (id >= 210000 && id <= 211001) { + addResponse(getDialogueId(id)); + applyResponse(); + } + + return SCR_2; +} + +int LiftbotScript::handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder) { + switch (tagId) { + case MKTAG('A', 'D', 'V', 'T'): + case MKTAG('A', 'R', 'T', 'I'): + case MKTAG('A', 'R', 'T', 'Y'): + case MKTAG('B', 'R', 'N', 'D'): + case MKTAG('C', 'O', 'M', 'D'): + case MKTAG('D', 'N', 'C', 'E'): + case MKTAG('H', 'B', 'B', 'Y'): + case MKTAG('L', 'I', 'T', 'R'): + case MKTAG('M', 'A', 'G', 'S'): + case MKTAG('M', 'C', 'P', 'Y'): + case MKTAG('M', 'I', 'N', 'S'): + case MKTAG('M', 'U', 'S', 'I'): + case MKTAG('N', 'I', 'K', 'E'): + case MKTAG('S', 'F', 'S', 'F'): + case MKTAG('S', 'O', 'A', 'P'): + case MKTAG('S', 'O', 'N', 'G'): + case MKTAG('S', 'P', 'R', 'T'): + case MKTAG('T', 'E', 'A', 'M'): + case MKTAG('T', 'V', 'S', 'H'): + case MKTAG('W', 'W', 'E', 'B'): + tagId = MKTAG('E', 'N', 'T', 'N'); + break; + case MKTAG('A', 'C', 'T', 'R'): + case MKTAG('A', 'C', 'T', 'S'): + case MKTAG('A', 'U', 'T', 'H'): + case MKTAG('B', 'A', 'R', 'K'): + case MKTAG('B', 'A', 'R', 'U'): + case MKTAG('B', 'L', 'F', '1'): + case MKTAG('B', 'L', 'F', '2'): + case MKTAG('B', 'L', 'R', '1'): + case MKTAG('B', 'L', 'R', '2'): + case MKTAG('B', 'L', 'P', '1'): + case MKTAG('B', 'L', 'P', '2'): + case MKTAG('B', 'L', 'P', '3'): + case MKTAG('B', 'L', 'P', '4'): + case MKTAG('B', 'L', 'T', '1'): + case MKTAG('B', 'L', 'T', '2'): + case MKTAG('B', 'L', 'T', '3'): + case MKTAG('B', 'L', 'T', '4'): + case MKTAG('B', 'L', 'T', '5'): + case MKTAG('B', 'O', 'Y', 'S'): + case MKTAG('C', 'O', 'P', 'S'): + case MKTAG('D', 'C', 'T', 'R'): + case MKTAG('F', 'A', 'M', 'E'): + case MKTAG('F', 'A', 'S', 'H'): + case MKTAG('G', 'I', 'R', 'L'): + case MKTAG('H', 'E', 'R', 'O'): + case MKTAG('H', 'O', 'S', 'T'): + case MKTAG('K', 'N', 'O', 'B'): + case MKTAG('N', 'H', 'R', 'O'): + case MKTAG('R', 'A', 'C', 'E'): + case MKTAG('S', 'C', 'I', 'T'): + case MKTAG('T', 'D', 'V', 'P'): + case MKTAG('T', 'W', 'A', 'T'): + case MKTAG('W', 'E', 'A', 'T'): + tagId = MKTAG('P', 'R', 'S', 'N'); + break; + case MKTAG('C', 'H', 'S', 'E'): + case MKTAG('C', 'M', 'N', 'T'): + case MKTAG('F', 'I', 'L', 'M'): + case MKTAG('J', 'F', 'O', 'D'): + case MKTAG('L', 'I', 'Q', 'D'): + tagId = MKTAG('F', 'O', 'O', 'D'); + break; + case MKTAG('C', 'R', 'I', 'M'): + case MKTAG('C', 'S', 'P', 'Y'): + case MKTAG('D', 'R', 'U', 'G'): + tagId = MKTAG('V', 'B', 'A', 'D'); + break; + case MKTAG('E', 'A', 'R', 'T'): + case MKTAG('H', 'O', 'M', 'E'): + case MKTAG('N', 'P', 'L', 'C'): + case MKTAG('P', 'L', 'A', 'N'): + tagId = MKTAG('P', 'L', 'A', 'C'); + break; + case MKTAG('F', 'A', 'U', 'N'): + case MKTAG('F', 'I', 'S', 'H'): + case MKTAG('F', 'L', 'O', 'R'): + tagId = MKTAG('N', 'A', 'T', 'R'); + break; + case MKTAG('H', 'H', 'L', 'D'): + case MKTAG('T', 'O', 'Y', 'S'): + case MKTAG('W', 'E', 'A', 'P'): + tagId = MKTAG('M', 'A', 'C', 'H'); + break; + case MKTAG('M', 'L', 'T', 'Y'): + case MKTAG('P', 'G', 'R', 'P'): + case MKTAG('P', 'T', 'I', 'C'): + tagId = MKTAG('G', 'R', 'U', 'P'); + break; + case MKTAG('P', 'K', 'U', 'P'): + case MKTAG('S', 'E', 'X', '1'): + case MKTAG('S', 'W', 'E', 'R'): + tagId = MKTAG('R', 'U', 'D', 'E'); + break; + case MKTAG('P', 'H', 'I', 'L'): + case MKTAG('R', 'C', 'K', 'T'): + tagId = MKTAG('S', 'C', 'I', 'E'); + break; + case MKTAG('T', 'R', 'A', '2'): + case MKTAG('T', 'R', 'A', '3'): + tagId = MKTAG('T', 'R', 'A', 'V'); + break; + } + + return TTnpcScript::handleQuote(roomScript, sentence, val, tagId, remainder); +} + +int LiftbotScript::updateState(uint oldId, uint newId, int index) { + for (uint idx = 0; idx < _states.size(); ++idx) { + TTmapEntry &us = _states[idx]; + if (us._src == newId) { + setState(us._dest); + break; + } + } + + return newId; +} + +int LiftbotScript::preResponse(uint id) { + if (id == 30565 || id == 30566 || id == 30567 || id == 30568 + || id == 30569 || id == 30570 || id == 30571) + return 210901; + + if (getDialRegion(0) == 0 && getRandomNumber(100) > 60) + return 210830; + + return 0; +} + +uint LiftbotScript::getDialsBitset() const { + uint bits = 0; + if (!getDialRegion(1)) + bits = 1; + if (!getDialRegion(0)) + bits |= 2; + if (bits > 1) + bits ^= 1; + + return bits; +} + + +int LiftbotScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) { + static const int ARRAY13[] = { + 210724, 210735, 210746, 210757, 210758, 210759, 210760, + 210761, 210762, 210725, 210726, 210727, 210728, 210729, + 210730, 210731, 210732, 210733, 210734, 210736, 210737, + 210738, 210739, 210740, 210741, 210742, 210743, 210744, + 210745, 210747, 210748, 210749, 210750, 210751, 210752, + 210753, 210754, 210755, 210756 + }; + static const int ARRAY14[] = { + 0, 210849, 210850, 210851, 210852, 210838, 210839, 210840, 210841, 0 + }; + + getState(); + int stateVal; + + switch (val1) { + case 1: + if (getValue(1) != 1) + return 1; + break; + case 2: + if (getValue(1) != 2) + return 1; + break; + case 3: + if (getValue(1) != 3) + return 1; + break; + case 4: + case 5: + return !sentence1(sentence); + case 6: + if (sentence->localWord("big") || sentence->localWord("small")) { + addResponse(getDialogueId(210215)); + applyResponse(); + } else if (sentence->localWord("my") || sentence->contains("my") || + sentence->contains("bedroom") || sentence->contains("state")) { + addResponse1(CTrueTalkManager::getStateValue(4), true, 0); + } else { + selectResponse(210763); + applyResponse(); + } + return 2; + case 7: + if (!sentence->localWord("ill") && !sentence->localWord("well")) + return 1; + break; + case 8: + if (!sentence->localWord("long")) + return 1; + break; + case 9: + if (addResponse1(1, false, 0)) + return 2; + break; + case 10: + if (addResponse1(39, false, 0)) + return 2; + break; + case 11: + if (getState6() == 2 || getState6() == 4) + return 1; + break; + case 12: + if (getState6() == 1 || getState6() == 3) + return 1; + break; + case 13: + selectResponse(ARRAY13[getCurrentFloor()]); + applyResponse(); + return 2; + case 14: + stateVal = getState6(); + if (sentence->contains("elevator") || + (!sentence->contains("lift") && getRandomNumber(100) > 60)) + stateVal += 4; + selectResponse(ARRAY14[stateVal]); + applyResponse(); + return 2; + case 15: + if (getRandomNumber(100) > 60) { + addResponse(getDialogueId(210440)); + } else { + addResponse(getDialogueId(210906)); + addResponse(getDialogueId(210901)); + } + applyResponse(); + return 2; + case 16: + if (sentence->contains("elevator") || sentence->contains("elavator")) + addResponse(30579); + else + addResponse(30580); + applyResponse(); + return 2; + case 17: + if (sentence->localWord("restaurant") || sentence->contains("restaurant")) + return 1; + break; + default: + break; + } + + return 0; +} + +void LiftbotScript::setDialRegion(int dialNum, int region) { + TTnpcScript::setDialRegion(dialNum, region); + addResponse(getDialogueId(210688)); + applyResponse(); +} + +int LiftbotScript::getCurrentFloor() const { + int val = CTrueTalkManager::getStateValue(5); + return CLIP(val, 1, 39); +} + +int LiftbotScript::getState6() const { + int val = CTrueTalkManager::getStateValue(6); + return (val < 1 || val > 4) ? 1 : val; +} + +int LiftbotScript::addDialogueAndState(int id, int state) { + addResponse(id); + applyResponse(); + + if (state != 1) + setState(state); + return 2; +} + +int LiftbotScript::addResponse1(int index, bool flag, int id) { + static const int DIALOGUE_IDS[37] = { + 210735, 210746, 210757, 210758, 210759, 210760, 210761, 210762, + 210725, 210726, 210727, 210728, 210729, 210730, 210731, 210732, + 210733, 210734, 210736, 210737, 210738, 210739, 210740, 210741, + 210742, 210743, 210744, 210745, 210747, 210748, 210749, 210750, + 210751, 210752, 210753, 210754, 210755 + }; + + int stateVal = getState6(); + int maxIndex = (stateVal == 2 || stateVal == 4) ? 27 : 39; + + if (index < 1 || index > maxIndex) { + addResponse(getDialogueId(maxIndex == 27 ? 210587 : 210586)); + applyResponse(); + return 1; + } else if (index == getCurrentFloor()) { + if (index == 1) { + addResponse(30558 - getRandomBit() ? 290 : 0); + addResponse(getDialogueId(210589)); + } else { + if (index == 39) + addResponse(30346); + addResponse(getDialogueId(210589)); + } + + applyResponse(); + return 2; + } + + stateVal = getValue(1); + if (index >= 2 && index <= 19 && stateVal > 1) { + addResponse(getDialogueId(210203)); + applyResponse(); + setState(7); + return true; + } + + if (index >= 20 && index <= 27 && stateVal > 2) { + addResponse(getDialogueId(210210)); + applyResponse(); + setState(8); + return true; + } + + if (flag) { + if (index == 1) { + selectResponse(30558 - getRandomBit() ? 290 : 0); + } else if (index == 39) { + addResponse(30346); + } else { + if (getRandomNumber(100) > 35 && index >= 2 && index <= 38) { + addResponse(getDialogueId(DIALOGUE_IDS[index - 2])); + } + + addResponse(getDialogueId(210588)); + } + + if (id) { + if (id == 210717 || id == 210716 || id == 210719 || id == 210718) { + addResponse(getDialogueId(210720)); + addResponse(getDialogueId(id)); + addResponse(getDialogueId(210715)); + } else { + addResponse(getDialogueId(id)); + } + } + + applyResponse(); + } + + CTrueTalkManager::triggerAction(2, index); + return flag; +} + +int LiftbotScript::sentence1(const TTsentence *sentence) { + if (CTrueTalkManager::_v1 >= 0) { + if (sentence->localWord("room")) { + addResponse1(getStateValue(), true, 0); + } else if (CTrueTalkManager::_v1 >= 1 && CTrueTalkManager::_v1 <= 39) { + if (CTrueTalkManager::_v1 != 1 || !sentence->localWord("floor")) { + addResponse1(CTrueTalkManager::_v1, true, 0); + } else if (sentence->localWord("up") || sentence->localWord("above")) { + addResponse1(getCurrentFloor() - 1, true, 0); + } else if (sentence->localWord("down") || sentence->localWord("below")) { + addResponse1(getCurrentFloor() + 1, true, 0); + } else { + addResponse1(CTrueTalkManager::_v1, true, 0); + } + } + return 1; + } + + int classNum = 1; + bool classSet = true; + if (sentence->localWord("firstclass")) + classNum = 1; + else if (sentence->localWord("secondclass")) + classNum = 2; + else if (sentence->localWord("thirdclass")) + classNum = 3; + else + classSet = false; + + uint newId = 0; + int diff = 1; + if (sentence->localWord("promenade")) { + newId = 210718; + } else if (sentence->localWord("bar")) { + newId = 210894 - (getRandomBit() ? 178 : 0); + } else if (sentence->localWord("musicroom")) { + newId = 210897 - (getRandomBit() ? 180 : 0); + } else if (sentence->localWord("creatorroom")) { + newId = 210713; + } else if (sentence->localWord("sculpture") || sentence->localWord("sculptureroom")) { + newId = 210722; + } else if (sentence->localWord("embarklobby")) { + newId = 210714; + } else if (sentence->localWord("parrotlobby")) { + newId = 210721; + } else if (sentence->localWord("arboretum")) { + newId = 210711; + } else if (sentence->localWord("canal")) { + newId = 210896; + } else if (sentence->localWord("bar")) { + newId = 210894; + } else if (sentence->localWord("bilgeroom")) { + newId = 210895; + } else if (sentence->localWord("titaniaroom")) { + newId = 210723; + } else if (sentence->localWord("restaurant")) { + if (classNum == 1) { + newId = 210719; + diff = 1; + } else { + newId = 210898; + diff = -98; + } + } else if (sentence->localWord("topwell") || sentence->localWord("servicelift") + || sentence->localWord("bridge") || sentence->localWord("dome") + || sentence->localWord("pellerator") || sentence->localWord("top")) { + diff = 1; + } else { + diff = -100; + } + + if (sentence->localWord("lobby")) + diff = (getValue(1) == 0 ? 1 : 0) - 99; + if (sentence->localWord("bottomofwell") || sentence->contains("bottom")) + diff = 39; + + if (diff == -99 || (diff == -100 && classSet)) { + if (classNum == 1) + addResponse(getDialogueId(210235)); + else if (classNum == 2) + addResponse(getDialogueId(210241)); + else + addResponse(getDialogueId(210242)); + applyResponse(); + + return 1; + } + + if (sentence->_field2C == 4 || sentence->localWord("find") + || sentence->contains("get to")) { + if (getCurrentFloor() != diff) { + selectResponse(diff == 1 ? 210769 : 210764); + applyResponse(); + } else if (!newId) { + selectResponse(210764); + applyResponse(); + } else if (newId >= 210715 && newId <= 210719) { + selectResponse(newId); + applyResponse(); + } else { + addResponse(getDialogueId(210720)); + selectResponse(210715); + applyResponse(); + } + + return 1; + } + + if (diff == -98) { + addResponse1(getStateValue(), true, newId); + return 1; + } else if (diff >= 0) { + addResponse1(diff, true, newId); + return 1; + } else if (sentence->localWord("up") || sentence->localWord("ascend")) { + selectResponse(210128); + applyResponse(); + return 1; + } else if (sentence->localWord("down") || sentence->localWord("descend")) { + selectResponse(210138); + applyResponse(); + return 1; + } else if (diff >= 0) { + addResponse1(diff, true, newId); + return 1; + } else { + return 0; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/liftbot_script.h b/engines/titanic/true_talk/liftbot_script.h new file mode 100644 index 0000000000..0a9cdfd6f0 --- /dev/null +++ b/engines/titanic/true_talk/liftbot_script.h @@ -0,0 +1,109 @@ +/* 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 TITANIC_LIFTBOT_SCRIPT_H +#define TITANIC_LIFTBOT_SCRIPT_H + +#include "titanic/true_talk/tt_npc_script.h" + +namespace Titanic { + +class LiftbotScript : public TTnpcScript { +private: + TTmapEntryArray _states; + static int _stateIndex; +private: + /** + * Setup sentence data + */ + void setupSentences(); + + int addResponse1(int mode, bool flag, int id); + int sentence1(const TTsentence *sentence); + + /** + * Gets the current floor + */ + int getCurrentFloor() const; + + int getState6() const; + + /** + * Adds a dialogue response and sets the state + */ + int addDialogueAndState(int id, int state); +public: + LiftbotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7); + + /** + * Chooses and adds a conversation response based on a specified tag Id. + */ + virtual int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag); + + /** + * Does NPC specific processing of the parsed sentence + */ + virtual int process(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(uint id); + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id); + + virtual int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder); + + /** + * Handles updating NPC state based on specified dialogue Ids and dial positions + */ + virtual int updateState(uint oldId, uint newId, int index); + + /** + * Handles getting a pre-response + */ + virtual int preResponse(uint id); + + /** + * Returns a bitset of the dials being off or not + */ + virtual uint getDialsBitset() const; + + /** + * Process a sentence fragment entry + */ + virtual int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Sets a given dial to be pointing in a specified region (0 to 2) + */ + virtual void setDialRegion(int dialNum, int region); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LIFTBOT_SCRIPT_H */ diff --git a/engines/titanic/true_talk/maitred_script.cpp b/engines/titanic/true_talk/maitred_script.cpp new file mode 100644 index 0000000000..e0636d045f --- /dev/null +++ b/engines/titanic/true_talk/maitred_script.cpp @@ -0,0 +1,1057 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/maitred_script.h" +#include "titanic/true_talk/true_talk_manager.h" + +namespace Titanic { + +MaitreDScript::MaitreDScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2) : + TTnpcScript(val1, charClass, v2, charName, v3, val2, -1, -1, -1, 0) { + _answerCtr = 0; + + CTrueTalkManager::setFlags(9, 1); + CTrueTalkManager::setFlags(10, 0); + CTrueTalkManager::setFlags(11, 0); + CTrueTalkManager::setFlags(12, 0); + CTrueTalkManager::setFlags(13, 0); + CTrueTalkManager::setFlags(14, 0); + CTrueTalkManager::setFlags(15, 0); + CTrueTalkManager::setFlags(16, 0); + + loadRanges("Ranges/MaitreD"); + loadResponses("Responses/MaitreD"); + setupSentences(); + _tagMappings.load("TagMap/MaitreD"); + _quotes.load("Quotes/MaitreD"); + _states.load("States/MaitreD"); +} + +void MaitreDScript::setupSentences() { + _mappings.load("Mappings/MaitreD", 1); + _entries.load("Sentences/MaitreD"); + _sentences1.load("Sentences/MaitreD/1"); + _field68 = 0; + _entryCount = 0; +} + +int MaitreDScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) { + if (tag == MKTAG('F', 'O', 'O', 'D') || tag == MKTAG('F', 'I', 'S', 'H') || + tag == MKTAG('C', 'H', 'S', 'E')) { + addResponse(getDialogueId(260388)); + addResponse(getDialogueId(260659)); + applyResponse(); + return 2; + } + + return TTnpcScript::chooseResponse(roomScript, sentence, tag); +} + +int MaitreDScript::process(const TTroomScript *roomScript, const TTsentence *sentence) { + if (roomScript->_scriptId != 132) + return 2; + if (preprocess(roomScript, sentence) == 1) + return 1; + + CTrueTalkManager::setFlags(10, 0); + setState(0); + + if (getValue(12) == 0) { + trigger12(false); + _answerCtr = 0; + + if (sentence->contains("restaurant at the end of the universe") + || sentence->contains("milliway") + || sentence->contains("big bang burger bar")) { + addResponse(getDialogueId(260975)); + applyResponse(); + } else if (processEntries(&_entries, _entryCount, roomScript, sentence) == 2) { + // Do nothing further + } else if (sentence->localWord("menu")) { + addResponse(getDialogueId(260683)); + applyResponse(); + } else if (sentence->localWord("table") && sentence->localWord("other")) { + addResponse(getDialogueId(260091)); + applyResponse(); + } else if ((sentence->localWord("not") && sentence->localWord("busy")) + || (sentence->localWord("no") && sentence->localWord("people")) + || sentence->localWord("empty")) { + addResponse(getDialogueId(260087)); + applyResponse(); + } else if (!defaultProcess(roomScript, sentence) + && processEntries(&_sentences1, 0, roomScript, sentence) != 2 + && processEntries(_defaultEntries, 0, roomScript, sentence) != 2) { + addResponse(getDialogueId(260975)); + applyResponse(); + } + + return 2; + } + + if (++_answerCtr > 50 || sentence->localWord("stop") || sentence->localWord("enough") + || sentence->contains("i give up") || sentence->contains("i give in") + || sentence->contains("i surrender") || sentence->contains("i submit")) { + _answerCtr = 0; + trigger12(false); + addResponse(getDialogueId(260063)); + } else if (sentence->localWord("not") && sentence->localWord("fight") && + (sentence->localWord("feel") || sentence->localWord("want") + || sentence->localWord("do") || sentence->localWord("will"))) { + _answerCtr = 0; + trigger12(false); + addResponse(getDialogueId(260678)); + } else if (sentence->contains("touche") || sentence->contains("toushe")) { + addResponse(getDialogueId(260098)); + } else if (sentence->contains("have at you")) { + addResponse(getDialogueId(260047)); + } else if (sentence->contains("en garde") || sentence->contains("on guard")) { + addResponse(getDialogueId(260008)); + } else if ((sentence->localWord("surrender") && !sentence->contains("i surrender")) + || (sentence->contains("give up") && !sentence->contains("i give up")) + || (sentence->contains("give in") && !sentence->contains("i give in")) + || (sentence->contains("submit") && !sentence->contains("i submit"))) { + addResponse(getDialogueId(260086)); + } else { + addResponse(getDialogueId(260031)); + } + + applyResponse(); + return 2; +} + +ScriptChangedResult MaitreDScript::scriptChanged(const TTroomScript *roomScript, uint id) { + resetFlags(); + bool flag1 = false, flag2 = false; + + switch (id) { + case 3: + if (getValue(4)) + addResponse(getDialogueId(260655)); + else if (getValue(12)) + addResponse(getDialogueId(260622)); + else if (getValue(9) && getValue(16)) + addResponse(getDialogueId(getValue(16))); + else if (getValue(15)) + addResponse(getDialogueId(260649)); + else + addResponse(getDialogueId(260112)); + + CTrueTalkManager::setFlags(16, 0); + CTrueTalkManager::setFlags(15, 1); + applyResponse(); + break; + + case 110: + addResponse(getDialogueId(260118)); + applyResponse(); + trigger12(true); + CTrueTalkManager::setFlags(8, 1); + CTrueTalkManager::setFlags(9, 1); + break; + + case 111: + CTrueTalkManager::setFlags(16, 260680); + CTrueTalkManager::setFlags(8, 0); + CTrueTalkManager::setFlags(9, 1); + break; + + case 112: + addResponse(getDialogueId(getValue(8) ? 260095 : 260127)); + applyResponse(); + break; + + case 113: + CTrueTalkManager::setFlags(16, 260266); + CTrueTalkManager::setFlags(8, 0); + CTrueTalkManager::setFlags(9, 1); + break; + + case 114: + CTrueTalkManager::setFlags(16, 260267); + CTrueTalkManager::setFlags(8, 0); + CTrueTalkManager::setFlags(9, 1); + break; + + case 115: + CTrueTalkManager::setFlags(16, 260268); + CTrueTalkManager::setFlags(8, 0); + CTrueTalkManager::setFlags(9, 1); + break; + + case 116: + CTrueTalkManager::setFlags(8, 0); + CTrueTalkManager::setFlags(9, 1); + break; + + case 117: + CTrueTalkManager::setFlags(8, 0); + CTrueTalkManager::setFlags(9, 0); + setFlags12(); + break; + + case 132: + addResponse(getDialogueId(260655)); + applyResponse(); + break; + + default: + flag1 = true; + break; + } + + if (!getValue(8)) { + switch (id - 118) { + case 0: + addResponse(getDialogueId(260676)); + applyResponse(); + break; + case 1: + addResponse(getDialogueId(260677)); + applyResponse(); + break; + case 2: + addResponse(getDialogueId(260189)); + applyResponse(); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + CTrueTalkManager::setFlags(13, id - 120); + break; + case 8: + CTrueTalkManager::setFlags(13, 0); + break; + case 9: + if (!getValue(12)) { + addResponse(getDialogueId(getValue(14) == 1 ? 260063 : 260120)); + applyResponse(); + } else if (getRandomNumber(4) == 1) { + addResponse(getDialogueId(260067)); + applyResponse(); + } else { + addResponse(getDialogueId(260131)); + applyResponse(); + } + break; + + case 10: + if (getValue(12) == 0) { + addResponse(getDialogueId(getValue(14) == 1 ? 260063 : 260119)); + applyResponse(); + } else if (getRandomNumber(4) == 1) { + addResponse(getDialogueId(260077)); + applyResponse(); + } else { + addResponse(getDialogueId(260131)); + applyResponse(); + } + break; + + case 11: + if (getValue(12)) { + addResponse(getDialogueId(260121)); + applyResponse(); + } else { + addResponse(getDialogueId(getValue(14) == 1 ? 260063 : 260119)); + applyResponse(); + } + break; + + case 12: + if (getValue(12)) { + addResponse(getDialogueId(260131)); + applyResponse(); + } else { + addResponse(getDialogueId(getValue(14) == 1 ? 260063 : 260119)); + applyResponse(); + } + break; + + case 13: + setFlags12(); + addResponse(getDialogueId(260131)); + applyResponse(); + break; + + case 15: + CTrueTalkManager::setFlags(13, 1); + if (getValue(12)) { + addResponse(getDialogueId(260122)); + applyResponse(); + } else { + addResponse(getDialogueId(getValue(14) == 1 ? 260063 : 260119)); + applyResponse(); + } + break; + + case 16: + CTrueTalkManager::setFlags(13, 2); + if (getValue(12)) { + addResponse(getDialogueId(260123)); + applyResponse(); + } else { + addResponse(getDialogueId(getValue(14) == 1 ? 260063 : 260119)); + applyResponse(); + } + break; + + case 17: + CTrueTalkManager::setFlags(13, 3); + if (getValue(12)) { + addResponse(getDialogueId(260124)); + applyResponse(); + } else { + addResponse(getDialogueId(getValue(14) == 1 ? 260063 : 260119)); + applyResponse(); + } + break; + + case 18: + CTrueTalkManager::setFlags(13, 4); + if (getValue(12)) { + addResponse(getDialogueId(260125)); + applyResponse(); + } else { + addResponse(getDialogueId(getValue(14) == 1 ? 260063 : 260119)); + applyResponse(); + } + break; + + case 19: + CTrueTalkManager::setFlags(13, 5); + if (getValue(12)) { + addResponse(getDialogueId(260126)); + applyResponse(); + } else { + addResponse(getDialogueId(getValue(14) == 1 ? 260063 : 260119)); + applyResponse(); + } + break; + + default: + flag2 = true; + break; + } + } + + return !flag1 || !flag2 ? SCR_2 : SCR_0; +} + +int MaitreDScript::handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder) { + switch (tagId) { + case MKTAG('A', 'D', 'V', 'T'): + case MKTAG('A', 'R', 'T', 'I'): + case MKTAG('A', 'R', 'T', 'Y'): + case MKTAG('B', 'R', 'N', 'D'): + case MKTAG('C', 'O', 'M', 'D'): + case MKTAG('D', 'N', 'C', 'E'): + case MKTAG('H', 'B', 'B', 'Y'): + case MKTAG('L', 'I', 'T', 'R'): + case MKTAG('M', 'A', 'G', 'S'): + case MKTAG('M', 'C', 'P', 'Y'): + case MKTAG('M', 'I', 'N', 'S'): + case MKTAG('M', 'U', 'S', 'I'): + case MKTAG('N', 'I', 'K', 'E'): + case MKTAG('S', 'F', 'S', 'F'): + case MKTAG('S', 'O', 'A', 'P'): + case MKTAG('S', 'P', 'R', 'T'): + case MKTAG('S', 'O', 'N', 'G'): + case MKTAG('T', 'E', 'A', 'M'): + case MKTAG('T', 'V', 'S', 'H'): + case MKTAG('W', 'W', 'E', 'B'): + tagId = MKTAG('E', 'N', 'T', 'N'); + break; + case MKTAG('A', 'C', 'T', 'R'): + case MKTAG('A', 'C', 'T', 'S'): + case MKTAG('A', 'U', 'T', 'H'): + case MKTAG('B', 'A', 'R', 'K'): + case MKTAG('B', 'A', 'R', 'U'): + case MKTAG('B', 'L', 'F', '1'): + case MKTAG('B', 'L', 'F', '2'): + case MKTAG('B', 'L', 'P', '1'): + case MKTAG('B', 'L', 'P', '2'): + case MKTAG('B', 'L', 'P', '3'): + case MKTAG('B', 'L', 'P', '4'): + case MKTAG('B', 'L', 'R', '1'): + case MKTAG('B', 'L', 'R', '2'): + case MKTAG('B', 'L', 'T', '1'): + case MKTAG('B', 'L', 'T', '2'): + case MKTAG('B', 'L', 'T', '3'): + case MKTAG('B', 'L', 'T', '4'): + case MKTAG('B', 'L', 'T', '5'): + case MKTAG('C', 'O', 'P', 'S'): + case MKTAG('D', 'C', 'T', 'R'): + case MKTAG('F', 'A', 'M', 'E'): + case MKTAG('F', 'A', 'S', 'H'): + case MKTAG('G', 'I', 'R', 'L'): + case MKTAG('H', 'E', 'R', 'O'): + case MKTAG('H', 'O', 'S', 'T'): + case MKTAG('K', 'N', 'O', 'B'): + case MKTAG('N', 'H', 'R', 'O'): + case MKTAG('R', 'A', 'C', 'E'): + case MKTAG('S', 'C', 'I', 'T'): + case MKTAG('T', 'D', 'V', 'P'): + case MKTAG('T', 'W', 'A', 'T'): + case MKTAG('W', 'E', 'A', 'T'): + tagId = MKTAG('P', 'R', 'S', 'N'); + break; + case MKTAG('C', 'H', 'S', 'E'): + case MKTAG('C', 'M', 'N', 'T'): + case MKTAG('F', 'I', 'L', 'M'): + case MKTAG('L', 'I', 'Q', 'D'): + tagId = MKTAG('F', 'O', 'O', 'D'); + break; + case MKTAG('C', 'R', 'I', 'M'): + case MKTAG('C', 'S', 'P', 'Y'): + case MKTAG('D', 'R', 'U', 'G'): + tagId = MKTAG('V', 'B', 'A', 'D'); + break; + case MKTAG('E', 'A', 'R', 'T'): + case MKTAG('H', 'O', 'M', 'E'): + case MKTAG('N', 'P', 'L', 'C'): + case MKTAG('P', 'L', 'A', 'N'): + tagId = MKTAG('P', 'L', 'A', 'C'); + break; + case MKTAG('F', 'A', 'U', 'N'): + case MKTAG('F', 'I', 'S', 'H'): + case MKTAG('F', 'L', 'O', 'R'): + tagId = MKTAG('N', 'A', 'T', 'R'); + break; + case MKTAG('H', 'H', 'L', 'D'): + case MKTAG('T', 'O', 'Y', 'S'): + case MKTAG('W', 'E', 'A', 'P'): + tagId = MKTAG('M', 'A', 'C', 'H'); + break; + case MKTAG('M', 'L', 'T', 'Y'): + case MKTAG('P', 'G', 'R', 'P'): + case MKTAG('P', 'T', 'I', 'C'): + tagId = MKTAG('G', 'R', 'U', 'P'); + break; + case MKTAG('P', 'K', 'U', 'P'): + case MKTAG('S', 'E', 'X', '1'): + case MKTAG('S', 'W', 'E', 'R'): + tagId = MKTAG('R', 'U', 'D', 'E'); + break; + case MKTAG('P', 'H', 'I', 'L'): + case MKTAG('R', 'C', 'K', 'T'): + tagId = MKTAG('S', 'C', 'I', 'E'); + break; + case MKTAG('T', 'R', 'A', '2'): + case MKTAG('T', 'R', 'A', '3'): + tagId = MKTAG('T', 'R', 'A', 'V'); + break; + + } + + return TTnpcScript::handleQuote(roomScript, sentence, val, tagId, remainder); +} + +int MaitreDScript::updateState(uint oldId, uint newId, int index) { + if (getValue(8)) { + if (oldId == 260112) + return getRangeValue(260654); + if (oldId != 260655 && oldId != 260654) + return getRangeValue(260655); + } + + newId = getStateDialogueId(oldId, newId); + + if (newId == 260023) { + switch (getValue(13)) { + case 1: + newId = 260023; break; + case 2: + newId = 260024; break; + case 3: + newId = 260025; break; + case 4: + newId = 260026; break; + case 5: + newId = 260027; break; + default: + newId = 260016; break; + } + } + + if (newId == 260034) { + switch (getValue(13)) { + case 1: + newId = 260034; break; + case 2: + newId = 260035; break; + case 3: + newId = 260036; break; + case 4: + newId = 260037; break; + case 5: + newId = 260038; break; + default: + newId = 260045; break; + } + } + + if (newId == 260070) { + switch (getValue(13)) { + case 1: + newId = 260070; break; + case 2: + newId = 260071; break; + case 3: + newId = 260072; break; + case 4: + newId = 260073; break; + case 5: + newId = 260074; break; + default: + newId = 260110; break; + } + } + + if (newId == 260076 || newId == 260181 || newId == 261010) { + CTrueTalkManager::setFlags(14, 1); + trigger12(true); + setFlags10(newId, index); + return newId; + } + + if (!getValue(12)) { + static const uint FLAG_IDS[] = { + 260080, 260066, 260067, 260062, 260050, 260087, 260090, 260171, 260173, + 260184, 260193, 260202, 260205, 260220, 260221, 260223, 260231, 260232, + 260365, 260373, 260374, 260387, 260421, 260622, 260695, 0 + }; + + for (uint idx = 0; FLAG_IDS[idx]; ++idx) { + if (FLAG_IDS[idx] == newId) { + setFlags12(); + break; + } + } + } + + if (newId == 261018) { + if (getValue(8) == 0 && getValue(9) == 0) { + newId = getRangeValue(260961); + setFlags10(newId, index); + return newId; + } + + if (getValue(8) == 1 && getValue(9) == 1) { + newId = getRangeValue(260655); + setFlags10(newId, index); + return newId; + } + + if (getValue(9) && getValue(16)) { + newId = getValue(16); + setFlags10(newId, index); + return index; + } + + newId = 260989; + } + + setFlags10(newId, index); + return newId; +} + +int MaitreDScript::preResponse(uint id) { + if (id == 60911) + return 260101; + + return 0; +} + +uint MaitreDScript::getStateDialogueId(uint oldId, uint newId) { + if (getValue(8) || getValue(9)) + return newId; + + switch (newId) { + case 260009: + case 260010: + case 260011: + case 260012: + return getRangeValue(260961); + case 260052: + return 260094; + case 260203: + return 260204; + case 260211: + case 260212: + case 260761: + case 260986: + case 260987: + case 260989: + return getRangeValue(260961); + case 260263: + case 260264: + return 260265; + case 260411: + return 260457; + case 260427: + case 260053: + case 260054: + case 260055: + case 260056: + case 260057: + case 260058: + case 260059: + case 260060: + return 260135; + case 260698: + case 260895: + case 260896: + return 260457; + case 260799: + return 260214; + + default: + return newId; + } +} + + +void MaitreDScript::setFlags12() { + int val = getValue(12); + CTrueTalkManager::setFlags(12, 1); + + if (!val) { + CTrueTalkManager::triggerAction(8, 0); + resetRange(260121); + resetRange(260122); + resetRange(260123); + resetRange(260124); + resetRange(260125); + resetRange(260126); + } +} + +void MaitreDScript::setFlags10(uint newId, uint index) { + int val = 28; + for (uint idx = 0; idx < _states.size(); ++idx) { + TTmapEntry &us = _states[idx]; + if (us._src == newId) { + val = us._dest; + break; + } + } + + CTrueTalkManager::setFlags(10, val); +} + +void MaitreDScript::trigger12(bool flag) { + int val = getValue(12); + CTrueTalkManager::setFlags(12, 0); + + if (val) { + CTrueTalkManager::triggerAction(flag ? 10 : 9, 0); + } +} + +int MaitreDScript::preprocess(const TTroomScript *roomScript, const TTsentence *sentence) { + if (!roomScript || !sentence || getValue(8)) + return 1; + + bool stateFlag = true, applyFlag = false; + switch (getValue(10)) { + case 1: + if (!getValue(11) && !getValue(8)) { + addResponse(getDialogueId(260052)); + applyFlag = true; + stateFlag = false; + } + break; + + case 2: + if (sentence->localWord("change") || sentence->localWord("music")) { + addResponse(getDialogueId(200684)); + applyFlag = true; + } + break; + + case 3: + if (sentence->localWord("chance") && (sentence->localWord("another") + || sentence->localWord("other") || sentence->localWord("more"))) { + addResponse(getDialogueId(260106)); + } else { + addResponse(getDialogueId(260107)); + } + applyFlag = true; + break; + + case 4: + if (sentence->contains("unless what")) { + addResponse(getDialogueId(260099)); + } else { + addResponse(getDialogueId(260131)); + applyFlag = true; + stateFlag = false; + } + break; + + case 5: + addResponse(getDialogueId(260096)); + applyFlag = true; + stateFlag = false; + break; + + case 6: + addResponse(getDialogueId(260097)); + applyFlag = true; + stateFlag = false; + break; + + case 7: + if (sentence->_field2C == 12) { + addResponse(getDialogueId(260089)); + applyFlag = true; + stateFlag = false; + } else { + addResponse(getDialogueId(260094)); + applyFlag = true; + CTrueTalkManager::setFlags(11, 1); + } + break; + + case 8: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + trigger12(false); + addResponse(getDialogueId(260094)); + CTrueTalkManager::setFlags(11, 1); + } else { + setFlags12(); + addResponse(getDialogueId(260131)); + } + applyFlag = true; + break; + + case 9: + setFlags12(); + break; + + case 11: + if ((sentence->localWord("say") || sentence->localWord("talk")) || + sentence->localWord("you")) { + addResponse(getDialogueId(260216)); + applyFlag = true; + } + break; + + case 12: + if (sentence->localWord("why") && sentence->localWord("naughty")) { + addResponse(getDialogueId(260196)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("what") && sentence->localWord("his") + && sentence->localWord("name")) { + addResponse(getDialogueId(260197)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("i") && sentence->localWord("meet")) { + addResponse(getDialogueId(260198)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("i") && sentence->localWord("speak")) { + addResponse(getDialogueId(260206)); + applyFlag = true; + stateFlag = false; + } + break; + + case 13: + if (sentence->localWord("why") || sentence->localWord("please") + || sentence->contains("go on") || sentence->localWord("need") + || sentence->contains("got to") || sentence->localWord("must")) { + addResponse(getDialogueId(260199)); + applyFlag = true; + stateFlag = false; + } + break; + + case 14: + if (sentence->localWord("what") || sentence->localWord("why") + || sentence->localWord("kill")) { + addResponse(getDialogueId(260200)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("you") && sentence->localWord("kill")) { + addResponse(getDialogueId(260574)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("how") && sentence->localWord("kill")) { + addResponse(getDialogueId(260557)); + applyFlag = true; + stateFlag = false; + } + break; + + case 15: + if ((sentence->localWord("what") && sentence->localWord("way")) + || sentence->localWord("how")) { + addResponse(getDialogueId(260201)); + applyFlag = true; + stateFlag = false; + } + break; + + case 16: + addResponse(getDialogueId(sentence->_field2C == 11 ? 260209 : 260210)); + applyFlag = true; + stateFlag = false; + break; + + case 17: + if (sentence->localWord("what") && sentence->localWord("mean")) { + addResponse(getDialogueId(260222)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("laugh") && sentence->localWord("with") + && sentence->localWord("you")) { + addResponse(getDialogueId(260221)); + applyFlag = true; + stateFlag = false; + } else { + setFlags12(); + addResponse(getDialogueId(260221)); + applyFlag = true; + stateFlag = false; + } + break; + + case 18: + if (sentence->_field2C == 11) { + addResponse(getDialogueId(260232)); + applyFlag = true; + } else if (sentence->_field2C == 12) { + addResponse(getDialogueId(260231)); + applyFlag = true; + } else if (sentence->_field2C == 13) { + addResponse(getDialogueId(260444)); + addResponse(getDialogueId(260233)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("what") && sentence->localWord("happen")) { + addResponse(getDialogueId(260233)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("why") && sentence->localWord("stressed")) { + addResponse(getDialogueId(260245)); + addResponse(getDialogueId(260233)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("why")) { + addResponse(getDialogueId(260453)); + addResponse(getDialogueId(260233)); + applyFlag = true; + stateFlag = false; + } + break; + + case 19: + if ((sentence->localWord("what") && sentence->localWord("scral")) + || (sentence->localWord("what") && sentence->localWord("happen")) + || sentence->contains("go on") || sentence->contains("and then")) { + addResponse(getDialogueId(260234)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("why") && sentence->localWord("stressed")) { + addResponse(getDialogueId(260245)); + addResponse(getDialogueId(260234)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("why")) { + addResponse(getDialogueId(260276)); + addResponse(getDialogueId(260237)); + addResponse(getDialogueId(260234)); + applyFlag = true; + stateFlag = false; + } + break; + + case 20: + if ((sentence->localWord("what") && sentence->localWord("leovinus")) + || (sentence->localWord("what") && sentence->localWord("happen"))) { + addResponse(getDialogueId(260235)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("where") && sentence->localWord("leovinus")) { + addResponse(getDialogueId(260236)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("why") && sentence->localWord("stressed")) { + addResponse(getDialogueId(260245)); + addResponse(getDialogueId(260235)); + applyFlag = true; + stateFlag = false; + } else { + addResponse(getDialogueId(260237)); + applyFlag = true; + stateFlag = false; + } + break; + + case 21: + case 22: + if (sentence->contains("cooking") + || (sentence->localWord("what") && sentence->localWord("mean"))) { + addResponse(getDialogueId(260238)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("where") && sentence->localWord("now")) { + addResponse(getDialogueId(260236)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("why") && sentence->localWord("stressed")) { + addResponse(getDialogueId(260245)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("why")) { + addResponse(getDialogueId(260239)); + applyFlag = true; + stateFlag = false; + } + break; + + case 23: + if (sentence->_field2C == 11) { + addResponse(getDialogueId(260237)); + applyFlag = true; + stateFlag = false; + } + break; + + case 24: + if ((sentence->localWord("can") && sentence->localWord("i") + && sentence->localWord("have")) + || (sentence->localWord("give") && sentence->localWord("me")) + || (sentence->localWord("i") && sentence->localWord("want")) + || (sentence->localWord("i") && sentence->localWord("need")) + ) { + addResponse(getDialogueId(260251)); + applyFlag = true; + } + + case 25: + if ((sentence->localWord("open") && sentence->localWord("it")) + || (sentence->localWord("how") && sentence->localWord("open")) + || (sentence->localWord("how") && sentence->localWord("get") && sentence->localWord("in")) + || (sentence->localWord("how") && sentence->localWord("change") && sentence->localWord("music")) + ) { + addResponse(getDialogueId(260253)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("where") && (sentence->localWord("it") + || sentence->localWord("that"))) { + addResponse(getDialogueId(260252)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("where") && sentence->localWord("key")) { + addResponse(getDialogueId(260254)); + applyFlag = true; + stateFlag = false; + } else if ((sentence->localWord("how") && sentence->localWord("work")) + || (sentence->localWord("what") && sentence->localWord("i") && sentence->localWord("do"))) { + addResponse(getDialogueId(260259)); + applyFlag = true; + stateFlag = false; + } + break; + + case 26: + if (sentence->localWord("where") && (sentence->localWord("key") + || sentence->localWord("it"))) { + addResponse(getDialogueId(260254)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("where") && (sentence->localWord("hand") + || sentence->localWord("that"))) { + addResponse(getDialogueId(260256)); + applyFlag = true; + stateFlag = false; + } else if (sentence->_field2C == 12) { + addResponse(getDialogueId(260255)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("why") && sentence->localWord("need")) { + addResponse(getDialogueId(260685)); + applyFlag = true; + stateFlag = false; + } + break; + + case 27: + if (sentence->localWord("where") && (sentence->localWord("that") + || sentence->localWord("it"))) { + addResponse(getDialogueId(260262)); + applyFlag = true; + } + break; + + case 28: + if (sentence->localWord("why")) { + addResponse(getDialogueId(260386)); + applyFlag = true; + stateFlag = false; + } else if (sentence->localWord("insist")) { + addResponse(getDialogueId(260387)); + applyFlag = true; + stateFlag = false; + } + break; + + case 29: + if (sentence->_field2C == 11) { + setFlags12(); + addResponse(getDialogueId(260131)); + } else { + addResponse(getDialogueId(260966)); + } + applyFlag = true; + break; + + case 30: + if (sentence->_field2C == 11 || sentence->_field2C == 13) { + addResponse(getDialogueId(260695)); + applyFlag = true; + } else if (sentence->_field2C == 12) { + addResponse(getDialogueId(260696)); + applyFlag = true; + } + break; + } + + if (applyFlag) + applyResponse(); + if (stateFlag) { + setState(0); + CTrueTalkManager::setFlags(10, 0); + } + + return applyFlag ? 2 : 1; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/maitred_script.h b/engines/titanic/true_talk/maitred_script.h new file mode 100644 index 0000000000..0472050d20 --- /dev/null +++ b/engines/titanic/true_talk/maitred_script.h @@ -0,0 +1,101 @@ +/* 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 TITANIC_MAITRED_SCRIPT_H +#define TITANIC_MAITRED_SCRIPT_H + +#include "titanic/true_talk/tt_npc_script.h" + +namespace Titanic { + +class MaitreDScript : public TTnpcScript { +private: + TTmapEntryArray _states; + TTsentenceEntries _sentences1; + int _answerCtr; +private: + /** + * Setup sentence data + */ + void setupSentences(); + + /** + * Alter dialogue Id based on current NPC state + */ + uint getStateDialogueId(uint oldId, uint newId); + + /** + * Sets flags 12 and resets some ranges + */ + void setFlags12(); + + /** + * Sets flags 10 to different values based on the passed + * dialogue Id + */ + void setFlags10(uint newId, uint index); + + /** + * Trigers 12 + */ + void trigger12(bool flag); + + /** + * Does preprocessing for the sentence + */ + int preprocess(const TTroomScript *roomScript, const TTsentence *sentence); +public: + MaitreDScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2); + + /** + * Chooses and adds a conversation response based on a specified tag Id. + */ + virtual int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag); + + /** + * Does NPC specific processing of the parsed sentence + */ + virtual int process(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id); + + virtual int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder); + + /** + * Handles updating NPC state based on specified dialogue Ids and dial positions + */ + virtual int updateState(uint oldId, uint newId, int index); + + /** + * Handles getting a pre-response + */ + virtual int preResponse(uint id); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MAITRED_SCRIPT_H */ diff --git a/engines/titanic/true_talk/parrot_script.cpp b/engines/titanic/true_talk/parrot_script.cpp new file mode 100644 index 0000000000..b09e74505c --- /dev/null +++ b/engines/titanic/true_talk/parrot_script.cpp @@ -0,0 +1,110 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/parrot_script.h" +#include "titanic/titanic.h" + +namespace Titanic { + +ParrotScript::ParrotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) : + TTnpcScript(val1, charClass, v2, charName, v3, val2, v4, v5, v6, v7) { + + loadRanges("Ranges/Parrot"); + setupSentences(); +} + +void ParrotScript::setupSentences() { + _mappings.load("Mappings/Parrot", 1); + _entries.load("Sentences/Parrot"); + _field68 = 0; + _entryCount = 0; +} + +int ParrotScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) { + if (tag == MKTAG('B', 'Y', 'Z', 'A')) { + addResponse(getDialogueId(280246)); + applyResponse(); + return 2; + } else { + return 1; + } +} + +int ParrotScript::process(const TTroomScript *roomScript, const TTsentence *sentence) { + if (processEntries(roomScript, sentence) == 2) { + int tagId = g_vm->_trueTalkManager->_quotes.find(sentence->_normalizedLine); + if (!tagId || chooseResponse(roomScript, sentence, tagId) != 2) { + addResponse(getDialogueId(sentence->check2C() ? 280248 : 280235)); + applyResponse(); + } + } + + return 2; +} + +ScriptChangedResult ParrotScript::scriptChanged(const TTroomScript *roomScript, uint id) { + if (id >= 280000 && id <= 280276) { + if (id == 280258) { + if (CTrueTalkManager::_currentNPC) { + CGameObject *chicken; + if (CTrueTalkManager::_currentNPC->find("Chicken", &chicken, FIND_PET)) + id = 280147 - getRandomBit(); + } + + id = getDialogueId(id); + } else { + if ((id == 280146 || id == 280147) && CTrueTalkManager::_currentNPC) { + CGameObject *chicken; + if (CTrueTalkManager::_currentNPC->find("Chicken", &chicken, FIND_PET)) + id = 280142; + } + + addResponse(getDialogueId(id)); + if (id == 280192) + addResponse(getDialogueId(280222)); + applyResponse(); + } + } + + if (id >= 80000 && id <= 80244) { + if ((id == 80155 || id == 80156) && CTrueTalkManager::_currentNPC) { + CGameObject *chicken; + if (CTrueTalkManager::_currentNPC->find("Chicken", &chicken, FIND_PET)) + id = 80151; + } + + addResponse(id); + if (id == 80201) + addResponse(getDialogueId(280222)); + applyResponse(); + } + + return (id == 3) ? SCR_2 : SCR_1; +} + +int ParrotScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) { + return 0; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/parrot_script.h b/engines/titanic/true_talk/parrot_script.h new file mode 100644 index 0000000000..ec7bec7629 --- /dev/null +++ b/engines/titanic/true_talk/parrot_script.h @@ -0,0 +1,63 @@ +/* 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 TITANIC_PARROT_SCRIPT_H +#define TITANIC_PARROT_SCRIPT_H + +#include "titanic/true_talk/tt_npc_script.h" + +namespace Titanic { + +class ParrotScript : public TTnpcScript { +private: + /** + * Setup sentence data + */ + void setupSentences(); +public: + ParrotScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7); + + /** + * Chooses and adds a conversation response based on a specified tag Id. + */ + virtual int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag); + + /** + * Does NPC specific processing of the parsed sentence + */ + virtual int process(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id); + + /** + * Process a sentence fragment entry + */ + virtual int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PARROT_SCRIPT_H */ diff --git a/engines/titanic/true_talk/script_handler.cpp b/engines/titanic/true_talk/script_handler.cpp new file mode 100644 index 0000000000..64e789a4b9 --- /dev/null +++ b/engines/titanic/true_talk/script_handler.cpp @@ -0,0 +1,148 @@ +/* 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 "titanic/true_talk/script_handler.h" +#include "titanic/true_talk/tt_concept.h" +#include "titanic/true_talk/tt_sentence.h" +#include "titanic/true_talk/tt_parser.h" +#include "titanic/true_talk/tt_word.h" +#include "titanic/titanic.h" + +namespace Titanic { + +/*------------------------------------------------------------------------*/ + +CScriptHandler::CScriptHandler(CTitleEngine *owner, int val1, int val2) : + _owner(owner), _script(owner->_script), _resources(g_vm->_exeResources), + _parser(this), _field10(0), _inputCtr(0), + _concept1P(nullptr), _concept2P(nullptr), _concept3P(nullptr), + _concept4P(nullptr), _field30(0) { + g_vm->_scriptHandler = this; + g_vm->_script = _script; + g_vm->_exeResources.reset(this, val1, val2); + _vocab = new TTvocab(val2); +} + +CScriptHandler::~CScriptHandler() { + delete _vocab; + delete _concept1P; + delete _concept2P; + delete _concept3P; + delete _concept4P; +} + +ScriptChangedResult CScriptHandler::scriptChanged(TTroomScript *roomScript, TTnpcScript *npcScript, uint dialogueId) { + if (!npcScript || !roomScript) { + ++_inputCtr; + return SCR_5; + } + + ScriptChangedResult result = roomScript->notifyScript(npcScript, dialogueId); + if (result == SCR_1) + result = npcScript->notifyScript(roomScript, dialogueId); + + if (result != SCR_3 && result != SCR_4) + return result; + + ++_inputCtr; + delete _concept1P; + delete _concept2P; + delete _concept3P; + delete _concept4P; + _concept1P = nullptr; + _concept2P = nullptr; + _concept3P = nullptr; + _concept4P = nullptr; + + return result; +} + +int CScriptHandler::processInput(TTroomScript *roomScript, TTnpcScript *npcScript, + const TTstring &line) { + if (!roomScript || !line.isValid()) + return SS_5; + + TTsentence *sentence = new TTsentence(_inputCtr++, line, this, roomScript, npcScript); + int result = _parser.preprocess(sentence); + roomScript->scriptPreprocess(sentence); + npcScript->scriptPreprocess(sentence); + + int canProcess = 0; + if (result) { + sentence->setState(result); + if (roomScript->canRespond(npcScript, sentence, result)) { + canProcess = npcScript->chooseResponse(roomScript, sentence, result); + } + } + + if (canProcess == 0 || canProcess == 1) { + if (!_parser.findFrames(sentence)) { + if (roomScript->canProcess(npcScript, sentence) && npcScript) { + npcScript->process(roomScript, sentence); + } + } + } + + delete sentence; + return SS_VALID; +} + +SimpleFile *CScriptHandler::openResource(const CString &name) { + return _owner->open(name); +} + +void CScriptHandler::setParserConcept(TTconcept *newConcept, TTconcept *oldConcept) { + _parser.conceptChanged(newConcept, oldConcept); +} + +int CScriptHandler::setResponse(TTscriptBase *script, TTresponse *response) { + return _owner->setResponse(script, response); +} + +void CScriptHandler::handleWord(const TTstring *str) { + handleWord1(str); + handleWord2(str); +} + +void CScriptHandler::handleWord1(const TTstring *str) { + if (_concept2P) + delete _concept2P; + _concept2P = nullptr; + + if (str) { + TTword word(*str, WC_UNKNOWN, 0); + _concept2P = new TTconcept(&word); + } +} + +void CScriptHandler::handleWord2(const TTstring *str) { + if (_concept1P) + delete _concept1P; + _concept1P = nullptr; + + if (str) { + TTword word(*str, WC_UNKNOWN, 0); + _concept1P = new TTconcept(&word); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/script_handler.h b/engines/titanic/true_talk/script_handler.h new file mode 100644 index 0000000000..193c60f719 --- /dev/null +++ b/engines/titanic/true_talk/script_handler.h @@ -0,0 +1,89 @@ +/* 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 TITANIC_SCRIPT_HANDLER_H +#define TITANIC_SCRIPT_HANDLER_H + +#include "titanic/true_talk/tt_npc_script.h" +#include "titanic/true_talk/tt_parser.h" +#include "titanic/true_talk/tt_room_script.h" +#include "titanic/true_talk/tt_string.h" +#include "titanic/true_talk/tt_vocab.h" +#include "titanic/support/exe_resources.h" + +namespace Titanic { + +class CTitleEngine; +class CScriptHandler; + +class CScriptHandler { +private: + CTitleEngine *_owner; + CExeResources &_resources; + int _field10; + int _inputCtr; + int _field30; +private: + void handleWord1(const TTstring *str); + void handleWord2(const TTstring *str); +public: + TTparser _parser; + TTvocab *_vocab; + TTscriptBase *_script; + TTconcept *_concept1P; + TTconcept *_concept2P; + TTconcept *_concept3P; + TTconcept *_concept4P; +public: + CScriptHandler(CTitleEngine *owner, int val1, int val2); + ~CScriptHandler(); + + /** + * Set the character and room + */ + ScriptChangedResult scriptChanged(TTroomScript *roomScript, + TTnpcScript *npcScript, uint dialogueId); + + int processInput(TTroomScript *roomScript, TTnpcScript *npcScript, + const TTstring &line); + + /** + * Open a resource for access + */ + SimpleFile *openResource(const CString &name); + + /** + * Called when concept data is copied from one to another + */ + void setParserConcept(TTconcept *newConcept, TTconcept *oldConcept); + + /** + * Sets a conversation reponse + */ + int setResponse(TTscriptBase *script, TTresponse *response); + + void handleWord(const TTstring *str); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SCRIPT_HANDLER_H */ diff --git a/engines/titanic/true_talk/script_support.cpp b/engines/titanic/true_talk/script_support.cpp new file mode 100644 index 0000000000..c24e275827 --- /dev/null +++ b/engines/titanic/true_talk/script_support.cpp @@ -0,0 +1,226 @@ +/* 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 "titanic/true_talk/script_support.h" +#include "titanic/titanic.h" + +namespace Titanic { + +int TTnpcScriptResponse::size() const { + for (int idx = 0; idx < 4; ++idx) { + if (_values[idx] == 0) + return idx; + } + + return 4; +} + +/*------------------------------------------------------------------------*/ + +TTscriptRange::TTscriptRange(uint id, const Common::Array<uint> &values, + bool isRandom, bool isSequential) : + _id(id), _nextP(nullptr) { + _mode = SF_NONE; + if (isRandom) + _mode = SF_RANDOM; + if (isSequential) + _mode = SF_SEQUENTIAL; + + for (uint idx = 0; idx < values.size(); ++idx) + _values.push_back(values[idx]); +} + +/*------------------------------------------------------------------------*/ + + +bool TTsentenceEntry::load(Common::SeekableReadStream *s) { + if (s->pos() >= s->size()) + return false; + + _field0 = s->readUint32LE(); + _field4 = s->readUint32LE(); + _string8 = readStringFromStream(s); + _fieldC = s->readUint32LE(); + _string10 = readStringFromStream(s); + _string14 = readStringFromStream(s); + _string18 = readStringFromStream(s); + _string1C = readStringFromStream(s); + _field20 = s->readUint32LE(); + _string24 = readStringFromStream(s); + _field28 = s->readUint32LE(); + _field2C = s->readUint32LE(); + _field30 = s->readUint32LE(); + + return true; +} + +/*------------------------------------------------------------------------*/ + +void TTsentenceEntries::load(const CString &resName) { + TTsentenceEntry entry; + Common::SeekableReadStream *r = g_vm->_filesManager->getResource(resName); + + while (entry.load(r)) + push_back(entry); + + delete r; +} + +/*------------------------------------------------------------------------*/ + +TTscriptMapping::TTscriptMapping() : _id(0) { + Common::fill(&_values[0], &_values[8], 0); +} + +/*------------------------------------------------------------------------*/ + +void TTscriptMappings::load(const char *name, int valuesPerMapping) { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name); + _valuesPerMapping = valuesPerMapping; + + while (r->pos() < r->size()) { + resize(size() + 1); + TTscriptMapping &m = (*this)[size() - 1]; + + m._id = r->readUint32LE(); + for (int idx = 0; idx < valuesPerMapping; ++idx) + m._values[idx] = r->readUint32LE(); + } + + delete r; +} + +/*------------------------------------------------------------------------*/ + +void TTtagMappings::load(const char *name) { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name); + + while (r->pos() < r->size()) { + uint src = r->readUint32LE(); + uint dest = r->readUint32LE(); + + push_back(TTtagMapping(src, dest)); + } + + delete r; +} + +/*------------------------------------------------------------------------*/ + +void TTwordEntries::load(const char *name) { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name); + + while (r->pos() < r->size()) { + TTwordEntry we; + we._id = r->readUint32LE(); + we._text = readStringFromStream(r); + + push_back(we); + } + + delete r; +} + +/*------------------------------------------------------------------------*/ + +void TThandleQuoteEntries::load(const char *name) { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name); + + _tag1 = r->readUint32LE(); + _tag2 = r->readUint32LE(); + _rangeStart = r->readUint32LE(); + _rangeEnd = r->readUint32LE(); + + while (r->pos() < r->size()) { + TThandleQuoteEntry qe; + qe._index = r->readUint32LE(); + qe._tagId = r->readUint32LE(); + qe._dialogueId = r->readUint32LE(); + + push_back(qe); + } + + delete r; +} + +/*------------------------------------------------------------------------*/ + +void TTmapEntryArray::load(const char *name) { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name); + + while (r->pos() < r->size()) { + TTmapEntry us; + us._src = r->readUint32LE(); + us._dest = r->readUint32LE(); + + push_back(us); + } + + delete r; +} + +int TTmapEntryArray::find(uint id) const { + for (uint idx = 0; idx < size(); ++idx) { + const TTmapEntry &me = (*this)[idx]; + if (me._src == id) + return me._dest; + } + + return 0; +} + +/*------------------------------------------------------------------------*/ + +void TTupdateStateArray::load(const char *name) { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name); + + while (r->pos() < r->size()) { + TTupdateState us; + us._newId = r->readUint32LE(); + us._newValue = r->readUint32LE(); + us._dialBits = r->readUint32LE(); + + push_back(us); + } + + delete r; +} + +/*------------------------------------------------------------------------*/ + +void TTcommonPhraseArray::load(const char *name) { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name); + + while (r->pos() < r->size()) { + TTcommonPhrase cp; + cp._str = readStringFromStream(r); + cp._dialogueId = r->readUint32LE(); + cp._roomNum = r->readUint32LE(); + cp._val1 = r->readUint32LE(); + + push_back(cp); + } + + delete r; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/script_support.h b/engines/titanic/true_talk/script_support.h new file mode 100644 index 0000000000..a41673bd5c --- /dev/null +++ b/engines/titanic/true_talk/script_support.h @@ -0,0 +1,194 @@ +/* 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 TITANIC_SCRIPT_SUPPORT_H +#define TITANIC_SCRIPT_SUPPORT_H + +#include "titanic/support/simple_file.h" + +namespace Titanic { + +#define DIALS_ARRAY_COUNT 10 + +enum ScriptArrayFlag { SF_NONE = 0, SF_RANDOM = 1, SF_SEQUENTIAL = 2 }; + +struct RoomDialogueId { + uint _roomNum; + uint _dialogueId; +}; + +struct TTnpcScriptResponse { + uint _tag; + uint _values[4]; + + /** + * Returns the size of the values list plus 1 + */ + int size() const; +}; + +struct TTscriptRange { + uint _id; + Common::Array<uint> _values; + TTscriptRange *_nextP; + uint _priorIndex; + ScriptArrayFlag _mode; + + TTscriptRange() : _id(0), _nextP(nullptr), + _priorIndex(0), _mode(SF_NONE) {} + TTscriptRange(uint id, const Common::Array<uint> &values, bool isRandom, + bool isSequential); +}; + + +struct TTsentenceEntry { + int _field0; + int _field4; + CString _string8; + int _fieldC; + CString _string10; + CString _string14; + CString _string18; + CString _string1C; + int _field20; + CString _string24; + int _field28; + int _field2C; + int _field30; + + TTsentenceEntry() : _field0(0), _field4(0), _fieldC(0), + _field20(0), _field28(0), _field2C(0), _field30(0) {} + + /** + * Load an entry from the passed stream, and returns true + * if an entry was successfully loaded + */ + bool load(Common::SeekableReadStream *s); +}; + +class TTsentenceEntries : public Common::Array<TTsentenceEntry> { +public: + /** + * Load a list of entries from the specified resource + */ + void load(const CString &resName); +}; + +struct TTscriptMapping { + uint _id; + uint _values[8]; + + TTscriptMapping(); +}; + +class TTscriptMappings : public Common::Array<TTscriptMapping> { +public: + int _valuesPerMapping; + + void load(const char *name, int valuesPerMapping); +}; + +struct TTtagMapping { + uint _src, _dest; + TTtagMapping() : _src(0), _dest(0) {} + TTtagMapping(uint src, uint dest) : _src(src), _dest(dest) {} +}; + +class TTtagMappings : public Common::Array<TTtagMapping> { +public: + void load(const char *name); +}; + +struct TTwordEntry { + uint _id; + CString _text; + + TTwordEntry() : _id(0) {} +}; + +class TTwordEntries : public Common::Array<TTwordEntry> { +public: + void load(const char *name); +}; + +struct TThandleQuoteEntry { + uint _index; + uint _tagId; + uint _dialogueId; + + TThandleQuoteEntry() : _index(0), _tagId(0), _dialogueId(0) {} +}; + +class TThandleQuoteEntries : public Common::Array<TThandleQuoteEntry> { +public: + uint _tag1, _tag2; + uint _rangeStart, _rangeEnd; +public: + TThandleQuoteEntries() : _tag1(0), _tag2(0), _rangeStart(0), _rangeEnd(0) {} + void load(const char *name); +}; + +struct TTmapEntry { + uint _src; + uint _dest; + + TTmapEntry() : _src(0), _dest(0) {} +}; + +class TTmapEntryArray : public Common::Array<TTmapEntry> { +public: + void load(const char *name); + + /** + * Finds a record by Id, and returns it's associated value + */ + int find(uint id) const; +}; + +struct TTupdateState { + uint _newId; + uint _newValue; + uint _dialBits; + + TTupdateState() : _newId(0), _newValue(0), _dialBits(0) {} +}; + +class TTupdateStateArray : public Common::Array<TTupdateState> { +public: + void load(const char *name); +}; + +struct TTcommonPhrase { + CString _str; + uint _dialogueId; + uint _roomNum; + uint _val1; +}; + +class TTcommonPhraseArray : public Common::Array<TTcommonPhrase> { +public: + void load(const char *name); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_NPC_SCRIPT_H */ diff --git a/engines/titanic/true_talk/succubus_script.cpp b/engines/titanic/true_talk/succubus_script.cpp new file mode 100644 index 0000000000..db537c6470 --- /dev/null +++ b/engines/titanic/true_talk/succubus_script.cpp @@ -0,0 +1,237 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/succubus_script.h" +#include "titanic/true_talk/true_talk_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +SuccUBusScript::SuccUBusScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) : + TTnpcScript(val1, charClass, v2, charName, v3, val2, v4, v5, v6, v7), + _isRoom101(false) { + + loadRanges("Ranges/SuccUBus"); + setupSentences(); +} + +void SuccUBusScript::setupSentences() { + _mappings.load("Mappings/SuccUBus", 1); + _entries.load("Sentences/SuccUBus"); + _field68 = 0; + _entryCount = 0; +} + +int SuccUBusScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) { + uint dialogueId = tag; + + switch (tag) { + case MKTAG('S', 'L', 'O', 'W'): + case MKTAG('T', 'H', 'R', 'T'): + dialogueId = 70021; + + case MKTAG('S', 'U', 'C', '1'): + dialogueId = getDialogueId(230009); + break; + + case MKTAG('S', 'U', 'C', '2'): + dialogueId = 70117; + break; + + case MKTAG('S', 'W', 'E', 'R'): + dialogueId = getRandomNumber(100) > 40 ? 70103 : getDialogueId(230030); + break; + + default: + break; + } + + if (dialogueId) { + addResponse(dialogueId); + applyResponse(); + return 2; + } else { + return 1; + } +} + +int SuccUBusScript::process(const TTroomScript *roomScript, const TTsentence *sentence) { + if (!CTrueTalkManager::getStateValue(1)) + return 2; + + if (roomScript && roomScript->_scriptId == 101) + _isRoom101 = true; + + int currState = getState(); + if (currState) { + int currMode = sentence->_field2C; + bool modeFlag1 = currMode == 11 || currMode == 13; + bool modeFlag2 = currMode == 12; + setState(0); + + switch (currState) { + case 1: + if (currMode == 3 || currMode == 10) + return setResponse(70050, 0); + break; + + case 2: + if (modeFlag1 || modeFlag2) + return setResponse(70070 + (getRandomBit() ? 254 : 0), 0); + break; + + case 3: + if (currMode == 3 || currMode == 10) + return setResponse(70074, 0); + break; + + case 4: + if (currMode == 4) + return setResponse(70077, 0); + if (currMode == 3) + return setResponse(getDialogueId(230117), 0); + break; + + case 5: + if (currMode == 3 || currMode == 10) + return setResponse(70089, 0); + break; + + case 6: + if (modeFlag1) + return setResponse(70103, 0); + if (modeFlag2) + return setResponse(70102, 0); + break; + + case 7: + if (modeFlag1) + return setResponse(getDialogueId(230157), 0); + break; + + case 8: + if (modeFlag1) + return setResponse(getDialogueId(230159), 0); + break; + + case 9: + if (modeFlag1) + return setResponse(getDialogueId(230160), 0); + break; + + case 10: + if (modeFlag1) + return setResponse(getDialogueId(230161), 0); + break; + + case 11: + if (modeFlag1) + return setResponse(getDialogueId(230142), 0); + break; + + case 12: + return setResponse(70030, 0); + + default: + break; + } + } + + if (processEntries(&_entries, _entryCount, roomScript, sentence) != 2) { + uint tagId = g_vm->_trueTalkManager->_quotes.find(sentence->_normalizedLine.c_str()); + if (tagId && chooseResponse(roomScript, sentence, tagId) != 2) { + addResponse(getDialogueId(230030)); + applyResponse(); + } + } + + return 2; +} + +ScriptChangedResult SuccUBusScript::scriptChanged(const TTroomScript *roomScript, uint id) { + if (id == 148) + CTrueTalkManager::setFlags(3, 1); + else if (id == 150) + CTrueTalkManager::setFlags(2, 1); + + if (id >= 230000 && id <= 230245) { + addResponse(getDialogueId(id)); + applyResponse(); + } + else if (id >= 70000 && id <= 70243) { + addResponse(id); + applyResponse(); + } + + return SCR_2; +} + +int SuccUBusScript::updateState(uint oldId, uint newId, int index) { + if (newId == 230199) { + return _isRoom101 ? 230148 : newId; + } else if (newId >= 230208 && newId <= 230235) { + addResponse(70158 - getRandomBit()); + return newId; + } else if (newId >= 230061 && newId <= 230063) { + if (getValue(2)) + return 230125; + } + + static const uint UPDATE_STATES[][2] = { + { 230078, 1 }, { 230106, 2 }, { 230112, 3 }, { 230115, 4 }, + { 230127, 5 }, { 230140, 6 }, { 230156, 7 }, { 230157, 8 }, + { 230159, 9 }, { 230160, 10 }, { 230161, 11 }, { 230072, 12 } + }; + + for (int idx = 0; idx < 12; ++idx) { + if (UPDATE_STATES[idx][0] == newId) { + setState(UPDATE_STATES[idx][1]); + break; + } + } + + return newId; +} + +int SuccUBusScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) { + if (val1 == 1 && roomScript && roomScript->_scriptId == 101) { + addResponse(getDialogueId(230239)); + applyResponse(); + return 2; + } + + return 0; +} + +int SuccUBusScript::setResponse(int dialogueId, int state) { + addResponse(dialogueId); + applyResponse(); + + if (state != -1) + setState(state); + + return 2; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/succubus_script.h b/engines/titanic/true_talk/succubus_script.h new file mode 100644 index 0000000000..d5cea7e66f --- /dev/null +++ b/engines/titanic/true_talk/succubus_script.h @@ -0,0 +1,75 @@ +/* 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 TITANIC_SUCCUBUS_SCRIPT_H +#define TITANIC_SUCCUBUS_SCRIPT_H + +#include "titanic/true_talk/tt_npc_script.h" + +namespace Titanic { + +class SuccUBusScript : public TTnpcScript { +private: + bool _isRoom101; +private: + /** + * Setup sentence data + */ + void setupSentences(); + + /** + * Add a response and optionally set the state + */ + int setResponse(int dialogueId, int state = -1); +public: + SuccUBusScript(int val1, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7); + + /** + * Chooses and adds a conversation response based on a specified tag Id. + */ + virtual int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag); + + /** + * Does NPC specific processing of the parsed sentence + */ + virtual int process(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id); + + /** + * Handles updating NPC state based on specified dialogue Ids and dial positions + */ + virtual int updateState(uint oldId, uint newId, int index); + + /** + * Process a sentence fragment entry + */ + virtual int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SUCCUBUS_SCRIPT_H */ diff --git a/engines/titanic/true_talk/title_engine.cpp b/engines/titanic/true_talk/title_engine.cpp new file mode 100644 index 0000000000..4dd45ba335 --- /dev/null +++ b/engines/titanic/true_talk/title_engine.cpp @@ -0,0 +1,83 @@ +/* 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 "titanic/true_talk/title_engine.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CTitleEngine::CTitleEngine() : _script(nullptr), _scriptHandler(nullptr) { +} + +CTitleEngine::~CTitleEngine() { + delete _script; + delete _scriptHandler; +} + +void CTitleEngine::setup(int val1, int val2) { + _script = new TTTitleScript(); + _scriptHandler = new CScriptHandler(this, val1, val2); +} + +/*------------------------------------------------------------------------*/ + +STtitleEngine::STtitleEngine(): CTitleEngine(), + _responseP(nullptr), _field58(0) { +} + +STtitleEngine::~STtitleEngine() { + delete _stream; +} + +void STtitleEngine::reset() { + _field58 = 0; + _indexes.clear(); +} + +void STtitleEngine::setup(int val1, int val2) { + CTitleEngine::setup(val1, 3); +} + +int STtitleEngine::setResponse(TTscriptBase *script, TTresponse *response) { + _indexes.clear(); + for (TTresponse *respP = response; respP; respP = respP->getNext()) { + _indexes.push_back(respP->getDialogueId()); + } + + return 0; +} + +void STtitleEngine::dump(int val1, int val2) { + // TODO +} + +SimpleFile *STtitleEngine::open(const CString &name) { + Common::SeekableReadStream *stream = g_vm->_filesManager->getResource( + CString::format("TEXT/%s", name.c_str())); + assert(stream); + + SimpleFile *file = new SimpleFile(); + file->open(stream); + return file; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/title_engine.h b/engines/titanic/true_talk/title_engine.h new file mode 100644 index 0000000000..afd2d3b92f --- /dev/null +++ b/engines/titanic/true_talk/title_engine.h @@ -0,0 +1,113 @@ +/* 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 TITANIC_TITLE_ENGINE_H +#define TITANIC_TITLE_ENGINE_H + +#include "common/stream.h" +#include "common/winexe_pe.h" +#include "titanic/support/string.h" +#include "titanic/true_talk/script_handler.h" +#include "titanic/true_talk/tt_response.h" +#include "titanic/true_talk/tt_script_base.h" +#include "titanic/true_talk/tt_title_script.h" + +namespace Titanic { + +class CTitleEngine; + +class CTitleStream : public SimpleFile { +public: + CTitleStream() : SimpleFile() {} +}; + +class CTitleEngine { +public: + CScriptHandler *_scriptHandler; + TTscriptBase *_script; +public: + CTitleEngine(); + virtual ~CTitleEngine(); + + /** + * Setup the engine + */ + virtual void setup(int val1, int val2 = 0); + + /** + * Sets a conversation reponse + */ + virtual int setResponse(TTscriptBase *script, TTresponse *response) { return SS_4; } + + virtual int proc4(int unused) const = 0; + virtual int proc5(int64 unused) const = 0; + virtual int proc6(int64 unused) const = 0; + virtual int proc7(int64 unused) const = 0; + virtual int proc8() const = 0; + + /** + * Open a designated file + */ + virtual SimpleFile *open(const CString &name) = 0; +}; + +class STtitleEngine : public CTitleEngine { +private: + Common::SeekableReadStream *_stream; + TTresponse *_responseP; + int _field58; +public: + Common::Array<uint> _indexes; + Common::Array<byte> _data; +public: + STtitleEngine(); + virtual ~STtitleEngine(); + + void reset(); + + /** + * Setup the engine + */ + virtual void setup(int val1, int val2 = 0); + + /** + * Sets a conversation reponse + */ + virtual int setResponse(TTscriptBase *script, TTresponse *response); + + virtual void dump(int val1, int val2); + + virtual int proc4(int unused) const { return 0; } + virtual int proc5(int64 unused) const { return 0; } + virtual int proc6(int64 unused) const { return 0; } + virtual int proc7(int64 unused) const { return 0; } + virtual int proc8() const { return 0; } + + /** + * Open a designated file + */ + virtual SimpleFile *open(const CString &name); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TITLE_ENGINE_H */ diff --git a/engines/titanic/true_talk/true_talk_manager.cpp b/engines/titanic/true_talk/true_talk_manager.cpp new file mode 100644 index 0000000000..977edd5399 --- /dev/null +++ b/engines/titanic/true_talk/true_talk_manager.cpp @@ -0,0 +1,597 @@ +/* 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 "titanic/true_talk/true_talk_manager.h" +#include "titanic/core/tree_item.h" +#include "titanic/npcs/true_talk_npc.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" + +#define MKTAG_BE(a3,a2,a1,a0) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24))) + +namespace Titanic { + +int CTrueTalkManager::_v1; +int CTrueTalkManager::_v2; +int CTrueTalkManager::_v3; +bool CTrueTalkManager::_v4; +bool CTrueTalkManager::_v5; +int CTrueTalkManager::_v6; +int CTrueTalkManager::_v7; +bool CTrueTalkManager::_v8; +int CTrueTalkManager::_v9; +bool CTrueTalkManager::_v10; +int CTrueTalkManager::_v11[41]; +CTrueTalkNPC *CTrueTalkManager::_currentNPC; + +/*------------------------------------------------------------------------*/ + +CTrueTalkManager::CTrueTalkManager(CGameManager *owner) : + _gameManager(owner), _scripts(&_titleEngine), _currentCharId(0), + _dialogueFile(nullptr), _dialogueId(0) { + _titleEngine.setup(3, 3); + _quotes.load(); + _quotesTree.load(); + + _currentNPC = nullptr; + g_vm->_trueTalkManager = this; +} + +CTrueTalkManager::~CTrueTalkManager() { + clear(); + g_vm->_trueTalkManager = nullptr; +} + +void CTrueTalkManager::save(SimpleFile *file) const { + saveStatics(file); + + saveNPC(file, 101); + saveNPC(file, 103); + saveNPC(file, 104); + saveNPC(file, 105); + saveNPC(file, 111); + saveNPC(file, 100); + saveNPC(file, 112); + saveNPC(file, 107); + file->writeNumber(0); +} + +void CTrueTalkManager::load(SimpleFile *file) { + loadStatics(file); + + // Iterate through loading characters + int charId = file->readNumber(); + while (charId) { + loadNPC(file, charId); + + int ident1 = file->readNumber(); + int ident2 = file->readNumber(); + + if (ident1 != MKTAG_BE('U', 'R', 'A', 'H')) { + while (ident2 != MKTAG_BE('A', 'K', 'E', 'R')) { + ident1 = ident2; + ident2 = file->readNumber(); + + if (!ident1) + break; + } + } + + // Get start of next character + charId = file->readNumber(); + } +} + +void CTrueTalkManager::loadStatics(SimpleFile *file) { + int count = file->readNumber(); + _v1 = file->readNumber(); + _v2 = file->readNumber(); + _v3 = file->readNumber(); + _v4 = file->readNumber() != 0; + _v5 = file->readNumber() != 0; + _v6 = file->readNumber(); + _v7 = file->readNumber(); + _v8 = file->readNumber() != 0; + _v9 = file->readNumber(); + _v10 = file->readNumber() != 0; + + for (int idx = count; count > 10; --idx) + file->readNumber(); + + int count2 = file->readNumber(); + for (int idx = 0; idx < count2; ++idx) { + int v = file->readNumber(); + if (idx < 41) + _v11[idx] = v; + } +} + +void CTrueTalkManager::saveStatics(SimpleFile *file) { + file->writeNumber(10); + file->writeNumber(_v1); + file->writeNumber(_v2); + file->writeNumber(_v3); + file->writeNumber(_v4 ? 1 : 0); + file->writeNumber(_v5 ? 1 : 0); + file->writeNumber(_v6); + file->writeNumber(_v7); + file->writeNumber(_v8 ? 1 : 0); + file->writeNumber(_v9); + file->writeNumber(_v10 ? 1 : 0); + + file->writeNumber(41); + for (int idx = 0; idx < 41; ++idx) + file->writeNumber(_v11[idx]); +} + +void CTrueTalkManager::clear() { + delete _dialogueFile; + _dialogueFile = nullptr; + _currentCharId = 0; +} + +void CTrueTalkManager::setFlags(int index, int val) { + switch (index) { + case 1: + if (val >= 1 && val <= 3) + _v3 = val; + break; + + case 2: + _v4 = !val; + break; + + case 3: + _v5 = val != 0; + break; + + case 4: + if (val >= 0 && val <= 3) + _v6 = val; + break; + + case 5: + _v7 = val; + break; + + case 6: + _v8 = val != 0; + break; + + default: + if (index < 41) + _v11[index] = val; + break; + } +} + +void CTrueTalkManager::loadNPC(SimpleFile *file, int charId) { + TTnpcScript *script = _scripts.getNpcScript(charId); + if (script) + script->load(file); +} + +void CTrueTalkManager::saveNPC(SimpleFile *file, int charId) const { + TTnpcScript *script = _scripts.getNpcScript(charId); + if (script) { + script->save(file); + file->writeNumber(MKTAG_BE('U', 'R', 'A', 'H')); + file->writeNumber(MKTAG_BE('A', 'K', 'E', 'R')); + } +} + +void CTrueTalkManager::preLoad() { + // Delete any previous talkers + for (TTtalkerList::iterator i = _talkers.begin(); i != _talkers.end(); ++i) + delete *i; + _talkers.clear(); +} + +void CTrueTalkManager::removeCompleted() { + for (TTtalkerList::iterator i = _talkers.begin(); i != _talkers.end(); ) { + TTtalker *talker = *i; + + if (talker->_done) { + i = _talkers.erase(i); + delete talker; + } else { + ++i; + } + } +} + +void CTrueTalkManager::update2() { + //warning("CTrueTalkManager::update2"); +} + +void CTrueTalkManager::start(CTrueTalkNPC *npc, uint id, CViewItem *view) { + TTnpcScript *npcScript = getNpcScript(npc); + TTroomScript *roomScript = getRoomScript(); + + _titleEngine.reset(); + uint charId = npcScript->charId(); + loadAssets(npc, charId); + + _currentNPC = npc; + _titleEngine._scriptHandler->scriptChanged(roomScript, npcScript, id); + _currentNPC = nullptr; + + setDialogue(npc, roomScript, view); +} + +void CTrueTalkManager::start3(CTrueTalkNPC *npc, CViewItem *view) { + start(npc, 3, view); +} + +void CTrueTalkManager::start4(CTrueTalkNPC *npc, CViewItem *view) { + start(npc, 4, view); +} + +TTnpcScript *CTrueTalkManager::getTalker(const CString &name) const { + if (name.contains("Doorbot")) + return _scripts.getNpcScript(104); + else if (name.contains("DeskBot")) + return _scripts.getNpcScript(103); + else if (name.contains("LiftBot")) + return _scripts.getNpcScript(105); + else if (name.contains("Parrot")) + return _scripts.getNpcScript(107); + else if (name.contains("BarBot")) + return _scripts.getNpcScript(100); + else if (name.contains("ChatterBot")) + return _scripts.getNpcScript(102); + else if (name.contains("BellBot")) + return _scripts.getNpcScript(101); + else if (name.contains("MaitreD")) + return _scripts.getNpcScript(112); + else if (name.contains("Succubus") || name.contains("Sub")) + return _scripts.getNpcScript(111); + + return nullptr; +} + +TTnpcScript *CTrueTalkManager::getNpcScript(CTrueTalkNPC *npc) const { + CString npcName = npc->getName(); + TTnpcScript *script = getTalker(npcName); + + if (!script) { + // Fall back on the default NPC script + script = _scripts.getNpcScript(101); + } + + return script; +} + +TTroomScript *CTrueTalkManager::getRoomScript() const { + CRoomItem *room = _gameManager->getRoom(); + TTroomScript *script = nullptr; + if (room) { + int scriptId = room->getScriptId(); + if (scriptId) + script = _scripts.getRoomScript(scriptId); + } + + if (!script) { + // Fall back on the default Room script + script = _scripts.getRoomScript(110); + } + + return script; +} + +TTroomScript *CTrueTalkManager::getRoomScript(int roomId) const { + TTroomScript *script = nullptr; + if (roomId) + script = _scripts.getRoomScript(roomId); + + if (!script) + // Fall back on the default Room script + script = _scripts.getRoomScript(110); + + return script; +} + +void CTrueTalkManager::loadAssets(CTrueTalkNPC *npc, int charId) { + // If assets for the character are already loaded, simply exit + if (_currentCharId == charId) + return; + + // Clear any previously loaded data + clear(); + + // Signal the NPC to get the asset details + CTrueTalkGetAssetDetailsMsg detailsMsg; + detailsMsg.execute(npc); + + if (!detailsMsg._filename.empty()) { + _dialogueFile = new CDialogueFile(detailsMsg._filename, 20); + _dialogueId = detailsMsg._numValue + 1; + } +} + +void CTrueTalkManager::processInput(CTrueTalkNPC *npc, CTextInputMsg *msg, CViewItem *view) { + TTnpcScript *npcScript = getNpcScript(npc); + TTroomScript *roomScript = getRoomScript(); + _titleEngine.reset(); + + if (npcScript && roomScript) { + _currentNPC = npc; + _titleEngine._scriptHandler->processInput(roomScript, npcScript, TTstring(msg->_input)); + _currentNPC = nullptr; + + loadAssets(npc, npcScript->charId()); + setDialogue(npc, roomScript, view); + } + + _currentNPC = nullptr; +} + +void CTrueTalkManager::setDialogue(CTrueTalkNPC *npc, TTroomScript *roomScript, CViewItem *view) { + // Get the dialog text + CString dialogueStr = readDialogueString(); + if (dialogueStr.empty()) + return; + + int soundId = readDialogSound(); + TTtalker *talker = new TTtalker(this, npc); + _talkers.push_back(talker); + + bool isParrot = npc->getName().contains("parrot"); + triggerNPC(npc); + playSpeech(talker, roomScript, view, isParrot); + talker->speechStarted(dialogueStr, _titleEngine._indexes[0], soundId); +} + +#define STRING_BUFFER_SIZE 2048 + +CString CTrueTalkManager::readDialogueString() { + byte buffer[STRING_BUFFER_SIZE]; + CString result; + + for (uint idx = 0; idx < _titleEngine._indexes.size(); ++idx) { + if (idx != 0) + result += " "; + + // Open a text entry from the dialogue file for access + DialogueResource *textRes = _dialogueFile->openTextEntry( + _titleEngine._indexes[idx] - _dialogueId); + if (!textRes) + continue; + + size_t entrySize = textRes->size(); + byte *tempBuffer = (entrySize < STRING_BUFFER_SIZE) ? buffer : + new byte[entrySize + 1]; + + _dialogueFile->read(textRes, tempBuffer, entrySize); + buffer[entrySize] = '\0'; + + // Close the resource + _dialogueFile->closeEntry(textRes); + + // Strip off any non-printable characters + for (byte *p = buffer; *p != '\0'; ++p) { + if (*p < 32 || *p > 127) + *p = ' '; + } + + // Add string to result + result += CString((const char *)buffer); + + // Free buffer if one was allocated + if (entrySize >= STRING_BUFFER_SIZE) + delete[] tempBuffer; + } + + return result; +} + +int CTrueTalkManager::readDialogSound() { + _field18 = 0; + + for (uint idx = 0; idx < _titleEngine._indexes.size(); ++idx) { + CWaveFile *waveFile = _gameManager->_sound.getTrueTalkSound( + _dialogueFile, _titleEngine._indexes[idx] - _dialogueId); + if (waveFile) { + _field18 = waveFile->fn1(); + } + } + + return _field18; +} + +void CTrueTalkManager::triggerNPC(CTrueTalkNPC *npc) { + CTrueTalkSelfQueueAnimSetMsg queueSetMsg; + if (queueSetMsg.execute(npc)) { + if (_field18 > 300) { + CTrueTalkQueueUpAnimSetMsg upMsg(_field18); + upMsg.execute(npc); + } + } else { + CTrueTalkGetAnimSetMsg getAnimMsg; + if (_field18 > 300) { + do { + getAnimMsg.execute(npc); + if (!getAnimMsg._endFrame) + break; + + npc->playMovie(getAnimMsg._startFrame, getAnimMsg._endFrame, 0); + getAnimMsg._endFrame = 0; + + uint numFrames = getAnimMsg._endFrame - getAnimMsg._startFrame; + int64 val = (numFrames * 1000) * 0x88888889; + uint diff = (val >> (32 + 5)) - 500; + _field18 += diff; + + getAnimMsg._index++; + } while (_field18 > 0); + } + } +} + +void CTrueTalkManager::playSpeech(TTtalker *talker, TTroomScript *roomScript, CViewItem *view, bool isParrot) { + uint milli, index; + switch (roomScript->_scriptId) { + case 101: + milli = 300; + index = 16; + break; + case 106: + case 107: + case 110: + case 114: + case 115: + case 122: + milli = 130; + index = 10; + break; + case 108: + case 109: + milli = 200; + index = 10; + break; + case 111: + case 116: + case 121: + milli = 80; + index = 12; + break; + case 112: + case 124: + case 128: + case 130: + milli = 80; + index = 4; + break; + case 132: + milli = 60; + index = 4; + break; + default: + milli = 0; + index = 4; + break; + } + + // Setup proximities + CProximity p1, p2, p3; + if (isParrot) { + p1._channel = 3; + p2._channel = 5; + p3._channel = 4; + } else { + p1._channel = 0; + p2._channel = 1; + p3._channel = 2; + } + + if (milli > 0) { + p3._channelVolume = (index * 3) / 2; + p3._positioningMode = POSMODE_POLAR; + p3._azimuth = -135.0; + p3._range = 1.0; + p3._elevation = 0; + + p2._channelVolume = (index * 3) / 4; + p2._positioningMode = POSMODE_NONE; + p2._azimuth = 135.0; + p2._range = 1.0; + p2._elevation = 0; + } + + _gameManager->_sound.stopChannel(p1._channel); + if (view) { + p1._positioningMode = POSMODE_VECTOR; + view->getPosition(p1._posX, p1._posY, p1._posZ); + } + + // Loop through adding each of the speech portions in. We use the + // _priorSoundHandle of CProximity to chain each successive speech + // to start when the prior one finishes + for (uint idx = 0; idx < _titleEngine._indexes.size(); ++idx) { + uint id = _titleEngine._indexes[idx]; + if (id > 100000) + continue; + + if (idx == (_titleEngine._indexes.size() - 1)) { + // Final iteration of speech segments to play + p1._endTalkerFn = &talkerEnd; + p1._talker = talker; + } + + // Start the speech + p1._priorSoundHandle = _gameManager->_sound.playSpeech(_dialogueFile, id - _dialogueId, p1); + if (!milli) + continue; + + if (idx == 0) + g_vm->_events->sleep(milli); + + p3._priorSoundHandle = _gameManager->_sound.playSpeech(_dialogueFile, id - _dialogueId, p3); + if (idx == 0) + g_vm->_events->sleep(milli); + + p2._priorSoundHandle = _gameManager->_sound.playSpeech(_dialogueFile, id - _dialogueId, p2); + } +} + +int CTrueTalkManager::getStateValue(int stateNum) { + if (!_currentNPC) + return -1000; + + CTrueTalkGetStateValueMsg msg(stateNum, -1000); + msg.execute(_currentNPC); + return msg._stateVal; +} + +bool CTrueTalkManager::triggerAction(int action, int param) { + if (!_currentNPC) + return false; + + CTrueTalkTriggerActionMsg msg(action, param, 0); + msg.execute(_currentNPC); + return true; +} + +void CTrueTalkManager::talkerEnd(TTtalker *talker) { + if (talker) + talker->endSpeech(0); +} + +CGameManager *CTrueTalkManager::getGameManager() const { + return _gameManager; +} + +CGameState *CTrueTalkManager::getGameState() const { + return _gameManager ? &_gameManager->_gameState : nullptr; +} + +int CTrueTalkManager::getPassengerClass() const { + CGameState *gameState = getGameState(); + return gameState ? gameState->_passengerClass : 4; +} + +int CTrueTalkManager::getState14() const { + CGameState *gameState = getGameState(); + return gameState ? gameState->_field14 : 0; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/true_talk_manager.h b/engines/titanic/true_talk/true_talk_manager.h new file mode 100644 index 0000000000..8a8895917a --- /dev/null +++ b/engines/titanic/true_talk/true_talk_manager.h @@ -0,0 +1,245 @@ +/* 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 TITANIC_TRUE_TALK_MANAGER_H +#define TITANIC_TRUE_TALK_MANAGER_H + +#include "titanic/messages/messages.h" +#include "titanic/support/simple_file.h" +#include "titanic/true_talk/dialogue_file.h" +#include "titanic/true_talk/title_engine.h" +#include "titanic/true_talk/tt_quotes.h" +#include "titanic/true_talk/tt_quotes_tree.h" +#include "titanic/true_talk/tt_scripts.h" +#include "titanic/true_talk/tt_talker.h" + +namespace Titanic { + +class CGameManager; +class CGameState; +class CTreeItem; +class CViewItem; +class CTrueTalkManager; +class CTrueTalkNPC; + +class CTrueTalkManager { +private: + CGameManager *_gameManager; + STtitleEngine _titleEngine; + TTscripts _scripts; + int _currentCharId; + CDialogueFile *_dialogueFile; + int _dialogueId; + int _field18; + TTtalkerList _talkers; +private: + /** + * Loads the statics for the class + */ + static void loadStatics(SimpleFile *file); + + /** + * Saves the statics associated with the class + */ + static void saveStatics(SimpleFile *file); + + /** + * Loads an NPC from file + */ + void loadNPC(SimpleFile *file, int charId); + + /** + * Saves the specified NPC to file + */ + void saveNPC(SimpleFile *file, int charId) const; + + /** + * Gets the script associated with an NPC game object + */ + TTnpcScript *getNpcScript(CTrueTalkNPC *npc) const; + + /** + * Gets the script associated with the current room + */ + TTroomScript *getRoomScript() const; + + /** + * Loads assets for the current character, if it's changed + */ + void loadAssets(CTrueTalkNPC *npc, int charId); + + void setDialogue(CTrueTalkNPC *npc, TTroomScript *roomScript, CViewItem *view); + + /** + * Read in text from the dialogue file + */ + CString readDialogueString(); + + /** + * Read in the sound from the dialogue file + */ + int readDialogSound(); + + /** + * Triggers animation for the NPC + */ + void triggerNPC(CTrueTalkNPC *npc); + + /** + * Plays speech specified by the manager's indexes array + */ + void playSpeech(TTtalker *talker, TTroomScript *roomScript, CViewItem *view, bool isParrot); + + /** + * Called when a talker finishes + */ + static void talkerEnd(TTtalker *talker); + + /** + * Return the game state + */ + CGameState *getGameState() const; +public: + static int _v1; + static int _v2; + static int _v3; + static bool _v4; + static bool _v5; + static int _v6; + static int _v7; + static bool _v8; + static int _v9; + static bool _v10; + static int _v11[41]; + static CTrueTalkNPC *_currentNPC; + + static void setFlags(int index, int val); +public: + TTquotes _quotes; + TTquotesTree _quotesTree; +public: + /** + * Get a specified state value from the currently set NPC + */ + static int getStateValue(int stateNum); + + /** + * Trigger an NPC action + */ + static bool triggerAction(int action, int param); +public: + CTrueTalkManager(CGameManager *owner); + ~CTrueTalkManager(); + + /** + * Save the data for the class to file + */ + void save(SimpleFile *file) const; + + /** + * Load the data for the class from file + */ + void load(SimpleFile *file); + + /** + * Clear the manager + */ + void clear(); + + /** + * Called when a game is about to be loaded + */ + void preLoad(); + + /** + * Called when loading a game is complete + */ + void postLoad() {} + + /** + * Called when a game is about to be saved + */ + void preSave() {} + + /** + * Called when a game has finished being saved + */ + void postSave() {} + + /** + * Returns the scripts for the manager + */ + TTscripts &getScripts() { return _scripts; } + + /** + * Remove any completed talkers + */ + void removeCompleted(); + + /** + * Return the game manager + */ + CGameManager *getGameManager() const; + + void update2(); + + /** + * Start a TrueTalk conversation + */ + void start(CTrueTalkNPC *npc, uint id, CViewItem *view); + + /** + * Start a TrueTalk conversation + */ + void start3(CTrueTalkNPC *npc, CViewItem *view); + + /** + * Start a TrueTalk conversation + */ + void start4(CTrueTalkNPC *npc, CViewItem *view); + + /** + * Return a TrueTalk talker/script + */ + TTnpcScript *getTalker(const CString &name) const; + + /** + * Process player's input + */ + void processInput(CTrueTalkNPC *npc, CTextInputMsg *msg, CViewItem *view); + + /** + * Gets the script associated with a specific room + */ + TTroomScript *getRoomScript(int roomId) const; + + /** + * Get the player's passenger class + */ + int getPassengerClass() const; + + int getState14() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TRUE_TALK_MANAGER_H */ diff --git a/engines/titanic/true_talk/tt_action.cpp b/engines/titanic/true_talk/tt_action.cpp new file mode 100644 index 0000000000..5bf91c71df --- /dev/null +++ b/engines/titanic/true_talk/tt_action.cpp @@ -0,0 +1,69 @@ +/* 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 "titanic/true_talk/tt_action.h" + +namespace Titanic { + +bool TTaction::_staticFlag; + +TTaction::TTaction(const TTstring &str, WordClass wordClass, int val2, int val3, int val4) : + TTmajorWord(str, wordClass, val2, val3), _field30(val4) { +} + +TTaction::TTaction(const TTaction *src) : TTmajorWord(src) { + if (src->getStatus()) { + _field30 = 0; + _status = SS_5; + } else { + _field30 = src->_field30; + } +} + +int TTaction::load(SimpleFile *file) { + int val; + + if (!TTword::load(file, WC_ACTION) && file->scanf("%d", &val)) { + _field30 = val; + return 0; + } else { + return 8; + } +} + +TTword *TTaction::copy() const { + TTaction *returnWordP = new TTaction(this); + returnWordP->_status = _status; + if (!_status) { + _staticFlag = false; + return returnWordP; + } else if (_status == SS_13 && !_staticFlag) { + _staticFlag = true; + delete returnWordP; + return copy(); + } else { + delete returnWordP; + return nullptr; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_action.h b/engines/titanic/true_talk/tt_action.h new file mode 100644 index 0000000000..29e2bc4e4a --- /dev/null +++ b/engines/titanic/true_talk/tt_action.h @@ -0,0 +1,57 @@ +/* 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 TITANIC_TT_ACTION_H +#define TITANIC_TT_ACTION_H + +#include "titanic/true_talk/tt_major_word.h" + +namespace Titanic { + +class TTaction : public TTmajorWord { +private: + static bool _staticFlag; +protected: + int _field30; +public: + TTaction(const TTstring &str, WordClass wordClass, int val2, int val3, int val4); + TTaction(const TTaction *src); + + /** + * Load the word + */ + int load(SimpleFile *file); + + void setVal(int val) { _field30 = val; } + int getVal() const { return _field30; } + + /** + * Creates a copy of the word + */ + virtual TTword *copy() const; + + virtual bool proc12(int val) const { return _field30 == val; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_ACTION_H */ diff --git a/engines/titanic/true_talk/tt_adj.cpp b/engines/titanic/true_talk/tt_adj.cpp new file mode 100644 index 0000000000..a14784798f --- /dev/null +++ b/engines/titanic/true_talk/tt_adj.cpp @@ -0,0 +1,84 @@ +/* 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 "titanic/true_talk/tt_adj.h" + +namespace Titanic { + +bool TTadj::_staticFlag; + +TTadj::TTadj(TTstring &str, WordClass wordClass, int val2, int val3, int val4) : + TTmajorWord(str, wordClass, val2, val3) { + if (val4 >= 0 && val4 <= 9) { + _val = val4; + } else { + _val = 0; + _status = SS_5; + } +} + +TTadj::TTadj(const TTadj *src) : TTmajorWord(src) { + if (src->getStatus()) { + _val = 0; + _status = SS_5; + } else { + _val = src->_val; + } +} + +int TTadj::load(SimpleFile *file) { + int val; + + if (!TTword::load(file, WC_ADJECTIVE) && file->scanf("%d", &val)) { + _val = val; + return 0; + } else { + return 8; + } +} + +int TTadj::adjFn1(int val) { + if (_val < 0 || _val > 9) { + return SS_4; + } else { + _val = val; + return SS_VALID; + } +} + +TTword *TTadj::copy() const { + TTadj *returnWordP = new TTadj(this); + returnWordP->_status = _status; + if (!_status) { + _staticFlag = false; + return returnWordP; + } else if (_status == SS_13 && !_staticFlag) { + _staticFlag = true; + delete returnWordP; + return copy(); + } else { + delete returnWordP; + return nullptr; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_adj.h b/engines/titanic/true_talk/tt_adj.h new file mode 100644 index 0000000000..1dec8a77d2 --- /dev/null +++ b/engines/titanic/true_talk/tt_adj.h @@ -0,0 +1,67 @@ +/* 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 TITANIC_TT_ADJ_H +#define TITANIC_TT_ADJ_H + +#include "titanic/true_talk/tt_major_word.h" + +namespace Titanic { + +class TTadj : public TTmajorWord { +private: + static bool _staticFlag; +protected: + int _val; +public: + TTadj(TTstring &str, WordClass wordClass, int val2, int val3, int val4); + TTadj(const TTadj *src); + + /** + * Load the word + */ + int load(SimpleFile *file); + + int adjFn1(int val); + + /** + * Creates a copy of the word + */ + virtual TTword *copy() const; + + virtual bool proc14(int val) const { return _val == val; } + virtual int proc15() const { return _val; } + virtual bool proc16() const { return _val >= 7; } + virtual bool proc17() const { return _val <= 3; } + virtual bool proc18() const { return _val > 3 && _val < 7; } + + /** + * Dumps data associated with the word to file + */ + virtual int save(SimpleFile *file) const { + return saveData(file, _val); + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_ADJ_H */ diff --git a/engines/titanic/true_talk/tt_concept.cpp b/engines/titanic/true_talk/tt_concept.cpp new file mode 100644 index 0000000000..c614e14dae --- /dev/null +++ b/engines/titanic/true_talk/tt_concept.cpp @@ -0,0 +1,308 @@ +/* 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 "titanic/true_talk/tt_concept.h" +#include "titanic/true_talk/tt_script_base.h" +#include "titanic/true_talk/tt_word.h" +#include "titanic/titanic.h" + +namespace Titanic { + +TTconcept::TTconcept() : _string1(" "), _string2(" "), + _scriptP(nullptr), _wordP(nullptr) { + if (setStatus()) + setScriptType(ST_UNKNOWN_SCRIPT); + else + reset(); +} + +TTconcept::TTconcept(TTscriptBase *script, ScriptType scriptType) : + _string1(" "), _string2(" "), _wordP(nullptr), _scriptP(nullptr) { + if (!script->getStatus()) { + setScriptType(scriptType); + _scriptP = script; + + if (scriptType == ST_UNKNOWN_SCRIPT && script->_id == 1) + _scriptType = ST_ROOM_SCRIPT; + } + + if (_status) + reset(); +} + +TTconcept::TTconcept(TTword *word, ScriptType scriptType) : + _string1(" "), _string2(" "), _wordP(nullptr), _scriptP(nullptr) { + + if (!word || !setStatus() || word->getStatus()) { + _status = SS_5; + } else { + _status = initializeWordRef(word); + if (!_status) + setScriptType(scriptType); + } + + if (_status) + reset(); +} + +TTconcept::TTconcept(TTconcept &src) : + _string1(src._string1), _string2(src._string2), + _wordP(nullptr), _scriptP(nullptr) { + + if (src.getStatus()) { + _status = SS_5; + } else { + if (setStatus()) { + _status = SS_VALID; + _scriptP = src._scriptP; + + if (src._wordP) { + _status = initializeWordRef(src._wordP); + initialize(src); + } + } + } + + if (_status) + reset(); +} + +TTconcept::~TTconcept() { + if (_word2P) { + _word2P->deleteSiblings(); + delete _word2P; + } + delete _wordP; + + if (_flag) + g_vm->_exeResources._owner->setParserConcept(this, nullptr); +} + +void TTconcept::deleteSiblings() { + for (TTconcept *currP = _nextP, *nextP; currP; currP = nextP) { + nextP = currP->_nextP; + delete currP; + } + + _nextP = nullptr; +} + +bool TTconcept::setStatus() { + if (_string1.isValid() && _string2.isValid()) { + _status = SS_VALID; + return true; + } else { + _status = SS_11; + return false; + } +} + +void TTconcept::setScriptType(ScriptType scriptType) { + _nextP = nullptr; + _field14 = 0; + _scriptType = scriptType; + _field1C = -1; + _field20 = 0; + _word2P = nullptr; + _field30 = 0; + _field34 = 0; + _flag = false; + _status = 0; +} + +int TTconcept::initializeWordRef(TTword *word) { + delete _wordP; + _wordP = word; + return 0; +} + +void TTconcept::reset() { + delete _wordP; + _wordP = nullptr; + _scriptP = nullptr; + + int oldStatus = _status; + setScriptType(ST_UNKNOWN_SCRIPT); + _status = oldStatus; +} + +bool TTconcept::compareTo(const char *str) const { + return this != nullptr && _wordP != nullptr && + _wordP->compareTo(str); +} + +bool TTconcept::compareTo(TTword *word) const { + if (_wordP && _wordP->compareTo(word->_text)) + return true; + + if (_scriptP && _scriptP->getId() == 1 && word->comparePronounTo(1)) + return true; + + return false; +} + +void TTconcept::initialize(TTconcept &src) { + _nextP = src._nextP; + _field14 = src._field14; + _scriptType = src._scriptType; + _field1C = src._field1C; + _field20 = src._field20; + + if (src._word2P) { + _word2P = src._word2P->copyWords(); + if (src._word2P->getChainStatus()) + _status = 11; + } else { + _word2P = nullptr; + } + + _field30 = src._field30; + _field34 = src._field34; + + if (src._flag) { + g_vm->_exeResources._owner->setParserConcept(this, &src); + src.setFlag(true); + _flag = true; + } + + _status = src._status; +} + +void TTconcept::copyFrom(TTconcept *src) { + if (this != src) { + if (src->getStatus()) { + _status = SS_5; + } else { + _string1 = src->_string1; + _string2 = src->_string2; + + if (setStatus()) { + _scriptP = src->_scriptP; + if (src->_wordP) { + _status = initializeWordRef(src->_wordP); + initialize(*src); + } else { + _wordP = nullptr; + initialize(*src); + } + } + } + } + + if (_status) + reset(); +} + +int TTconcept::setOwner(TTconcept *src) { + if (this) { + if (src->_wordP) { + TTword *newWord = src->_wordP->copy(); + return setOwner(newWord, 1); + } + } + + return 0; +} + +int TTconcept::setOwner(TTword *src, bool dontDup) { + TTword *word = dontDup ? src : src->copy(); + + if (word) { + if (!_word2P) { + _word2P = word; + } else { + // Add word to end of word list + TTword *tailP = _word2P; + while (tailP->_nextP) + tailP = tailP->_nextP; + + tailP->_nextP = word; + } + } + + return 0; +} + +bool TTconcept::checkWordId1() const { + return (_wordP && (_wordP->_id == 200 || _wordP->_id == 201 || + _wordP->_id == 602 || _wordP->_id == 607)) || + (_scriptP && _scriptP->_id <= 2); +} + +bool TTconcept::checkWordId2() const { + return (_wordP && _wordP->_id == 204) || (_scriptP && _scriptP->getId() == 3); +} + +bool TTconcept::checkWordId3() const { + return isWordClass(WC_ABSTRACT) || isWordClass(WC_ADJECTIVE) || + (isWordClass(WC_ADVERB) && getWordId() != 910); +} + +bool TTconcept::checkWordClass() const { + return !_scriptP && _wordP && (_wordP->_wordClass == WC_THING || _wordP->_wordClass == WC_PRONOUN); +} + +const TTstring TTconcept::getText() { + if (_scriptP) + return _scriptP->getText(); + else if (_wordP) + return _wordP->getText(); + else + return TTstring(); +} + +TTconcept *TTconcept::findByWordId(int id) { + for (TTconcept *conceptP = this; conceptP; conceptP = conceptP->_nextP) { + if (conceptP->_wordP && conceptP->_wordP->_id == id) + return conceptP; + } + + return nullptr; +} + +TTconcept *TTconcept::findByWordClass(WordClass wordClass) { + for (TTconcept *conceptP = this; conceptP; conceptP = conceptP->_nextP) { + if (conceptP->_wordP && conceptP->_wordP->_wordClass == wordClass) + return conceptP; + } + + return nullptr; +} + +TTconcept *TTconcept::findBy20(int val) { + for (TTconcept *conceptP = this; conceptP; conceptP = conceptP->_nextP) { + if (conceptP->_field20 == val) + return conceptP; + } + + return nullptr; +} + +bool TTconcept::isWordId(int id) const { + return this && _wordP && _wordP->_id == id; +} + +int TTconcept::getWordId() const { + return this && _wordP ? _wordP->_id : 0; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_concept.h b/engines/titanic/true_talk/tt_concept.h new file mode 100644 index 0000000000..88afb6f28b --- /dev/null +++ b/engines/titanic/true_talk/tt_concept.h @@ -0,0 +1,172 @@ +/* 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 TITANIC_TT_CONCEPT_H +#define TITANIC_TT_CONCEPT_H + +#include "titanic/true_talk/tt_string.h" +#include "titanic/true_talk/tt_word.h" + +namespace Titanic { + +enum ScriptType { ST_UNKNOWN_SCRIPT = 0, ST_ROOM_SCRIPT = 1, ST_NPC_SCRIPT = 2 }; + +class TTscriptBase; +class TTword; + +class TTconcept { +private: + TTstring _string1; + int _field1C; + TTword *_word2P; + int _field30; + bool _flag; + int _status; +private: + /** + * Sets the status of the concept + */ + bool setStatus(); + + /** + * Sets the script type and resets other fields + */ + void setScriptType(ScriptType scriptType); + + /** + * Sets up the concept for a word reference + */ + int initializeWordRef(TTword *word); + + /** + * Resets the concept + */ + void reset(); + + /** + * Initialize inner data for the concept from a given source concept + */ + void initialize(TTconcept &src); +public: + TTconcept *_nextP; + TTscriptBase *_scriptP; + TTword *_wordP; + int _scriptType; + int _field14; + int _field20; + int _field34; + TTstring _string2; +public: + TTconcept(); + TTconcept(TTscriptBase *script, ScriptType scriptType); + TTconcept(TTword *word, ScriptType scriptType = ST_UNKNOWN_SCRIPT); + TTconcept(TTconcept &src); + ~TTconcept(); + + /** + * Destroys any attached sibling concepts to the given concept + */ + void deleteSiblings(); + + /** + * Copies data from a source concept + */ + void copyFrom(TTconcept *src); + + /** + * Compares the name of the associated word, if any, to the passed string + */ + bool compareTo(const char *str) const; + + /** + * Compares the concept to the specified word + */ + bool compareTo(TTword *word) const; + + /** + * Set an owner for the concept + */ + int setOwner(TTconcept *src); + + /** + * Set an owner for the concept + */ + int setOwner(TTword *src, bool dontDup); + + /** + * Return the status of the concept + */ + int getStatus() const { return _status; } + + /** + * True true if the concept is valid + */ + bool isValid() const { return _status == SS_VALID; } + + /** + * Returns true if the word is of the specified class + */ + bool isWordClass(WordClass wordClass) const { + return _wordP && _wordP->isClass(wordClass); + } + + void setFlag(bool val) { _flag = val; } + void set1C(int val) { _field1C = val; } + int get20() const { return _field20; } + int getState() const { return _field34; } + + bool checkWordId1() const; + bool checkWordId2() const; + bool checkWordId3() const; + bool checkWordClass() const; + + /** + * Return text assocaited with the concept's word or script + */ + const TTstring getText(); + + /** + * Find a word by Id + */ + TTconcept *findByWordId(int id); + + /** + * Find a word by it's class + */ + TTconcept *findByWordClass(WordClass wordClass); + + TTconcept *findBy20(int val); + + /** + * Returns true if the concept has a word with a given Id + */ + bool isWordId(int id) const; + + /** + * If a word is associated, return it's Id + */ + int getWordId() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_CONCEPT_H */ diff --git a/engines/titanic/true_talk/tt_concept_node.cpp b/engines/titanic/true_talk/tt_concept_node.cpp new file mode 100644 index 0000000000..454ca59971 --- /dev/null +++ b/engines/titanic/true_talk/tt_concept_node.cpp @@ -0,0 +1,165 @@ +/* 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 "titanic/true_talk/tt_concept_node.h" +#include "titanic/true_talk/script_handler.h" +#include "titanic/titanic.h" + +namespace Titanic { + +TTconceptNode::TTconceptNode() : _concept0P(_concepts[0]), _concept1P(_concepts[1]), + _concept2P(_concepts[2]), _concept3P(_concepts[3]), _concept4P(_concepts[4]), + _concept5P(_concepts[5]), _field18(0), _field1C(0), _nextP(nullptr), _status(0) { +} + +TTconceptNode::TTconceptNode(const TTconceptNode &src) : _concept0P(_concepts[0]), _concept1P(_concepts[1]), + _concept2P(_concepts[2]), _concept3P(_concepts[3]), _concept4P(_concepts[4]), + _concept5P(_concepts[5]), _field18(0), _field1C(0), _nextP(nullptr), _status(0) { + if (src._status) { + _status = SS_5; + } else { + for (int idx = 0; idx < 6; ++idx) { + if (src._concepts[idx]) { + _concepts[idx] = new TTconcept(*src._concepts[idx]); + if (!_concepts[idx]->isValid()) + _status = SS_11; + } + } + + _field18 = src._field18; + _field1C = src._field1C; + _nextP = src._nextP; + } +} + +void TTconceptNode::deleteSiblings() { + // Iterate through the linked chain of nodes, deleting each in turn + for (TTconceptNode *curP = _nextP, *nextP = nullptr; nextP; curP = nextP) { + nextP = curP->_nextP; + delete curP; + } + + _nextP = nullptr; +} + +TTconcept **TTconceptNode::setConcept(int conceptIndex, TTconcept *src) { + TTconcept **conceptPP = nullptr; + switch (conceptIndex) { + case 1: + conceptPP = &_concept1P; + break; + case 2: + conceptPP = &_concept2P; + break; + case 3: + conceptPP = &_concept3P; + break; + case 4: + conceptPP = &_concept4P; + break; + case 5: + conceptPP = &_concept5P; + break; + default: + break; + } + + bool isPronoun = false; + StringArray &pronouns = g_vm->_scriptHandler->_parser._pronouns; + for (uint idx = 0; idx < pronouns.size() && !isPronoun; ++idx) { + isPronoun = pronouns[idx] == src->getText(); + } + + CScriptHandler &scrHandler = *g_vm->_exeResources._owner; + if (!isPronoun) { + switch (conceptIndex) { + case 0: + delete scrHandler._concept2P; + scrHandler._concept2P = new TTconcept(*src); + break; + + case 1: + delete scrHandler._concept4P; + scrHandler._concept4P = new TTconcept(*src); + break; + + case 2: + delete scrHandler._concept1P; + scrHandler._concept1P = new TTconcept(*src); + break; + + default: + break; + } + } + + return conceptPP; +} + +int TTconceptNode::replaceConcept(int mode, int conceptIndex, TTconcept *concept) { + TTconcept **conceptPP = setConcept(conceptIndex, concept); + + if (mode == 0 || (mode == 1 && !*conceptPP)) { + if (!concept || !concept->isValid()) + return SS_5; + + if (mode == 0 && *conceptPP) { + delete *conceptPP; + } + + *conceptPP = new TTconcept(*concept); + return (*conceptPP)->isValid() ? SS_VALID : SS_11; + } else { + return SS_1; + } +} + +int TTconceptNode::changeConcept(int mode, TTconcept **conceptPP, int conceptIndex) { + TTconcept **newConceptPP = setConcept(conceptIndex, *conceptPP); + + if (mode == 0 || (mode == 1 && !*newConceptPP)) { + if (!*conceptPP) + return SS_5; + + delete *newConceptPP; + *newConceptPP = new TTconcept(**conceptPP); + return SS_VALID; + } else { + return SS_1; + } +} + +bool TTconceptNode::createConcept(int mode, int conceptIndex, TTword *word) { + TTconcept *newConcept = new TTconcept(word, ST_UNKNOWN_SCRIPT); + TTconcept **conceptPP = setConcept(conceptIndex, newConcept); + + if (mode == 0 || (mode == 1 && !*conceptPP)) { + delete *conceptPP; + *conceptPP = newConcept; + return false; + } else { + delete newConcept; + return true; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_concept_node.h b/engines/titanic/true_talk/tt_concept_node.h new file mode 100644 index 0000000000..9a1c3a9912 --- /dev/null +++ b/engines/titanic/true_talk/tt_concept_node.h @@ -0,0 +1,75 @@ +/* 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 TITANIC_TT_CONCEPT_NODE_H +#define TITANIC_TT_CONCEPT_NODE_H + +#include "titanic/true_talk/tt_concept.h" + +namespace Titanic { + +class TTconceptNode { +public: + TTconcept *_concepts[6]; + TTconcept *&_concept0P; + TTconcept *&_concept1P; + TTconcept *&_concept2P; + TTconcept *&_concept3P; + TTconcept *&_concept4P; + TTconcept *&_concept5P; + int _field18; + int _field1C; + TTconceptNode *_nextP; + int _status; +public: + TTconceptNode(); + TTconceptNode(const TTconceptNode &src); + + /** + * Delete any sibling chain attached to this node + */ + void deleteSiblings(); + + void set18(int val) { _field18 = val; } + int get18() const { return _field18; } + + /** + * Returns true if the node is valid + */ + bool isValid() const { return _status == SS_VALID; } + + TTconcept **setConcept(int conceptIndex, TTconcept *src); + int replaceConcept(int mode, int conceptIndex, TTconcept *concept); + int changeConcept(int mode, TTconcept **conceptPP, int conceptIndex); + bool createConcept(int mode, int conceptIndex, TTword *word); + + int concept1WordId() const { + return _concept1P ? _concept1P->getWordId() : 0; + } + int concept5WordId() const { + return _concept5P ? _concept5P->getWordId() : 0; + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_CONCEPT_NODE_H */ diff --git a/engines/titanic/true_talk/tt_hist.cpp b/engines/titanic/true_talk/tt_hist.cpp new file mode 100644 index 0000000000..fae9ae6286 --- /dev/null +++ b/engines/titanic/true_talk/tt_hist.cpp @@ -0,0 +1,36 @@ +/* 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 "titanic/true_talk/tt_hist.h" +#include "titanic/true_talk/tt_sentence.h" + +namespace Titanic { + +TThist::TThist(TTsentence *sentence) : _status(0) { + _sentence = new TTsentence(sentence); +} + +TThist::~TThist() { + delete _sentence; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_hist.h b/engines/titanic/true_talk/tt_hist.h new file mode 100644 index 0000000000..f67a0387c5 --- /dev/null +++ b/engines/titanic/true_talk/tt_hist.h @@ -0,0 +1,47 @@ +/* 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 TITANIC_TT_HIST_H +#define TITANIC_TT_HIST_H + +namespace Titanic { + +class TTsentence; + +class TThist { +protected: + int _field0; + TTsentence *_sentence; + int _status; +public: + TThist(TTsentence *sentence); + virtual ~TThist(); +}; + +class TTscriptHist : public TThist { +public: + TTscriptHist(TTsentence *sentence) : TThist(sentence) {} +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_HIST_H */ diff --git a/engines/titanic/true_talk/tt_major_word.cpp b/engines/titanic/true_talk/tt_major_word.cpp new file mode 100644 index 0000000000..18a56a40be --- /dev/null +++ b/engines/titanic/true_talk/tt_major_word.cpp @@ -0,0 +1,70 @@ +/* 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 "titanic/true_talk/tt_major_word.h" + +namespace Titanic { + +bool TTmajorWord::_staticFlag; + +TTmajorWord::TTmajorWord(const TTstring &str, WordClass wordClass, int val2, int val3) : + TTword(str, wordClass, val2), _field2C(val3) { +} + +TTmajorWord::TTmajorWord(const TTmajorWord *src) : TTword(src) { + if (src->getStatus()) { + _field2C = 0; + _status = SS_5; + } else { + _field2C = src->_field2C; + } +} + +int TTmajorWord::saveData(SimpleFile *file, int val) const { + int result = TTword::save(file); + if (!result) { + file->writeFormat("%1.0d", val); + file->writeFormat("%c", '\n'); + if (_synP) + result = _synP->save(file); + } + + return result; +} + +TTword *TTmajorWord::copy() const { + TTmajorWord *returnWordP = new TTmajorWord(this); + returnWordP->_status = _status; + if (!_status) { + _staticFlag = false; + return returnWordP; + } else if (_status == SS_13 && !_staticFlag) { + _staticFlag = true; + delete returnWordP; + return copy(); + } else { + delete returnWordP; + return nullptr; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_major_word.h b/engines/titanic/true_talk/tt_major_word.h new file mode 100644 index 0000000000..c9a708abfb --- /dev/null +++ b/engines/titanic/true_talk/tt_major_word.h @@ -0,0 +1,54 @@ +/* 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 TITANIC_TT_MAJOR_WORD_H +#define TITANIC_TT_MAJOR_WORD_H + +#include "titanic/true_talk/tt_word.h" + +namespace Titanic { + +class TTmajorWord : public TTword { +private: + static bool _staticFlag; +protected: + int _field2C; +protected: + /** + * Dumps data for the word to a file + */ + int saveData(SimpleFile *file, int val) const; +public: + TTmajorWord(const TTstring &str, WordClass wordClass, int val2, int val3); + TTmajorWord(const TTmajorWord *src); + + /** + * Creates a copy of the word + */ + virtual TTword *copy() const; + + virtual bool proc2(int val) const { return _field2C == val; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_MAJOR_WORD_H */ diff --git a/engines/titanic/true_talk/tt_node.cpp b/engines/titanic/true_talk/tt_node.cpp new file mode 100644 index 0000000000..cbbb1dd756 --- /dev/null +++ b/engines/titanic/true_talk/tt_node.cpp @@ -0,0 +1,89 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/tt_node.h" + +namespace Titanic { + +TTnode::TTnode() : _priorP(nullptr), _nextP(nullptr) { +} + +TTnode::~TTnode() { + detach(); +} + +void TTnode::addToTail(TTnode *newNode) { + TTnode *tail = getTail(); + tail->_nextP = newNode; + newNode->_priorP = this; +} + +void TTnode::addToHead(TTnode *newNode) { + TTnode *head = getHead(); + head->_priorP = newNode; + newNode->_nextP = head; +} + +void TTnode::detach() { + if (_priorP) + _priorP->_nextP = _nextP; + + if (_nextP) + _nextP->_priorP = _priorP; +} + +void TTnode::deleteSiblings() { + // Detach current node from prior one, if there is one + if (_priorP) + _priorP->_nextP = nullptr; + + // Iterate through the linked chain of nodes, deleting each in turn + for (TTnode *curP = _nextP, *nextP = nullptr; nextP; curP = nextP) { + nextP = curP->_nextP; + delete curP; + } +} + +TTnode *TTnode::getHead() { + if (_priorP == nullptr) + return this; + + TTnode *node = _priorP; + while (node->_priorP) + node = node->_priorP; + + return node; +} + +TTnode *TTnode::getTail() { + if (_nextP == nullptr) + return this; + + TTnode *node = _nextP; + while (node->_nextP) + node = node->_nextP; + + return node; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_node.h b/engines/titanic/true_talk/tt_node.h new file mode 100644 index 0000000000..36d44288fd --- /dev/null +++ b/engines/titanic/true_talk/tt_node.h @@ -0,0 +1,69 @@ +/* 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 TITANIC_TT_NODE_H +#define TITANIC_TT_NODE_H + +namespace Titanic { + +class TTnode { +public: + TTnode *_priorP; + TTnode *_nextP; +public: + TTnode(); + virtual ~TTnode(); + + /** + * Adds a new node at the beginning of the linked list + */ + void addToHead(TTnode *newNode); + + /** + * Links the passed node to this node as a linked list + */ + void addToTail(TTnode *newNode); + + /** + * Detaches a node from any predecessor and/or successor + */ + void detach(); + + /** + * Delete any sibling chain attached to this node + */ + void deleteSiblings(); + + /** + * Returns the first node at the beginning of a linked list of nodes + */ + TTnode *getHead(); + + /** + * Returns the final node at the end of the linked list of nodes + */ + TTnode *getTail(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_NODE_H */ diff --git a/engines/titanic/true_talk/tt_npc_script.cpp b/engines/titanic/true_talk/tt_npc_script.cpp new file mode 100644 index 0000000000..61c3b0e00c --- /dev/null +++ b/engines/titanic/true_talk/tt_npc_script.cpp @@ -0,0 +1,1009 @@ +/* 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/algorithm.h" +#include "common/textconsole.h" +#include "titanic/messages/messages.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/true_talk/tt_npc_script.h" +#include "titanic/true_talk/tt_sentence.h" +#include "titanic/true_talk/true_talk_manager.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +TTsentenceEntries *TTnpcScript::_defaultEntries; + +static const char *const ITEMS[] = { + "chicken", "napkin", "parrot", "moth", "fuse", "eye", "nose", "ear", "mouth", + "auditorycenter", "visioncenter", "olfactorycenter", "speechcenter", "stick", + "longstick", "bomb", "lemon", "puree", "television", "hammer", nullptr +}; + +struct ItemRec { + const char *const _name; + uint _id; +}; +static const ItemRec ARRAY1[] = { + { ITEMS[0], 290138 }, + { ITEMS[1], 290139 }, + { ITEMS[2], 290141 }, + { ITEMS[3], 290142 }, + { ITEMS[4], 290153 }, + { ITEMS[5], 290158 }, + { ITEMS[6], 290159 }, + { ITEMS[7], 290160 }, + { ITEMS[8], 290161 }, + { ITEMS[9], 290162 }, + { ITEMS[10], 290163 }, + { ITEMS[11], 290164 }, + { ITEMS[12], 290165 }, + { ITEMS[13], 290166 }, + { ITEMS[14], 290166 }, + { ITEMS[15], 290178 }, + { ITEMS[16], 290174 }, + { ITEMS[17], 290175 }, + { ITEMS[18], 290176 }, + { ITEMS[19], 290179 }, + { nullptr, 0 } +}; +static const uint ARRAY2[] = { + 290167, 290178, 290183, 290144, 290148, 290151, 290154, 290156, 290158, 290159, 290160, 290161, + 290162, 290163, 290164, 290165, 290177, 290181, 0 +}; +static const uint RANDOM1[] = { + 290184, 290185, 290187, 290188, 290190, 290191, 290193, 290195, 290196, 290197, 290198, 290199, + 290202, 290205, 0 +}; +static const uint RANDOM2[] = { + 290186, 290187, 290188, 290190, 290191, 290193, 290194, 290195, 290196, 290197, 290198, 290199, + 290200, 290201, 290202, 290204, 290205, 0 +}; +static const uint RANDOM3[] = { + 290188, 290190, 290192, 290194, 290197, 290200, 290201, 290202, 290204, 290205, 0 +}; +static const uint RANDOM4[] = { + 290206, 290207, 290209, 290210, 290211, 290212, 290216, 290217, 290218, 290219, 290222, 290223, 0 +}; +static const uint RANDOM5[] = { + 290208, 290209, 290210, 290211, 290212, 290214, 290215, 290216, 290217, 290218, 290219, 290221, + 290222, 290223, 0 +}; +static const uint RANDOM6[] = { + 290210, 290211, 290213, 290214, 290215, 290220, 290221, 290222, 290223, 0 +}; +static const uint RANDOM7[] = { + 290225, 290226, 290228, 290229, 290230, 290232, 290231, 290235, 290236, 290237, 290238, 290241, 0 +}; +static const uint RANDOM8[] = { + 290227, 290228, 290229, 290230, 290231, 290232, 290233, 290234, 290235, 290236, 290237, 290238, + 290240, 290241, 0 +}; +static const uint RANDOM9[] = { + 290228, 290229, 290230, 290232, 290233, 290234, 290239, 290240, 290241, 0 +}; + +/*------------------------------------------------------------------------*/ + +TTnpcData::TTnpcData() { + Common::fill(&_array[0], &_array[136], 0); +} + +void TTnpcData::resetFlags() { + Common::fill(&_array[20], &_array[136], 0); +} + +/*------------------------------------------------------------------------*/ + +TTnpcScriptBase::TTnpcScriptBase(int charId_, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) : + TTscriptBase(0, charClass, v2, charName, v3, v4, v5, v6, v7), + _charId(charId_), _field54(0), _val2(val2) { +} + +/*------------------------------------------------------------------------*/ + +void TTnpcScript::init() { + _defaultEntries = new TTsentenceEntries(); + _defaultEntries->load("Sentences/Default"); +} + +void TTnpcScript::deinit() { + delete _defaultEntries; + _defaultEntries = nullptr; +} + +TTnpcScript::TTnpcScript(int charId_, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) : + TTnpcScriptBase(charId_, charClass, v2, charName, v3, val2, v4, v5, v6, v7), + _entryCount(0), _field68(0), _field6C(0), _rangeResetCtr(0), + _currentDialNum(0), _dialDelta(0), _field7C(0), _itemStringP(nullptr), _field2CC(false) { + CTrueTalkManager::_v2 = 0; + Common::fill(&_dialValues[0], &_dialValues[DIALS_ARRAY_COUNT], 0); + + if (!CTrueTalkManager::_v10) { + Common::fill(&CTrueTalkManager::_v11[0], &CTrueTalkManager::_v11[41], 0); + CTrueTalkManager::_v10 = true; + } + + resetFlags(); +} + +void TTnpcScript::loadResponses(const char *name, int valuesPerResponse) { + _valuesPerResponse = valuesPerResponse; + Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name); + + while (r->pos() < r->size()) { + TTnpcScriptResponse sr; + sr._tag = r->readUint32LE(); + for (int idx = 0; idx < valuesPerResponse; ++idx) + sr._values[idx] = r->readUint32LE(); + + _responses.push_back(sr); + } + + delete r; +} + +void TTnpcScript::loadRanges(const char *name) { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name); + + while (r->pos() < r->size()) { + Common::Array<uint> values; + uint id = r->readUint32LE(); + bool isRandom = r->readByte(); + bool isSequential = r->readByte(); + + uint v; + do { + v = r->readUint32LE(); + values.push_back(v); + } while (v); + + addRange(id, values, isRandom, isSequential); + } + + delete r; +} + +void TTnpcScript::resetFlags() { + _data.resetFlags(); + _field2CC = false; +} + +void TTnpcScript::setupDials(int dial1, int dial2, int dial3) { + _dialValues[0] = dial1; + _dialValues[1] = dial2; + _dialValues[2] = dial3; + _currentDialNum = getRandomNumber(3) - 1; + _dialDelta = getRandomNumber(5) + 6; + + if (_dialValues[0] > 70) + _dialDelta = -_dialDelta; +} + +void TTnpcScript::addResponse(int id) { + if (id > 200000) + id = getDialogueId(id); + + handleWord(id); + TTscriptBase::addResponse(id); +} + +int TTnpcScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) { + for (uint idx = 0; idx < _responses.size(); ++idx) { + const TTnpcScriptResponse &response = _responses[idx]; + + if (response._tag == tag) { + if (_valuesPerResponse == 1) { + selectResponse(response._values[0]); + } else { + int valIndex = getRandomNumber(response.size()) - 1; + uint diagId = getDialogueId(response._values[valIndex]); + addResponse(diagId); + } + + applyResponse(); + return 2; + } + } + + return 1; +} + +int TTnpcScript::process(const TTroomScript *roomScript, const TTsentence *sentence) { + return processEntries(&_entries, _entryCount, roomScript, sentence); +} + +int TTnpcScript::proc8() const { + return 0; +} + +int TTnpcScript::proc11() const { + return 2; +} + +int TTnpcScript::proc12() const { + return 1; +} + +void TTnpcScript::selectResponse(int id) { + if (id >= 200000 && id <= 290264) + id = getDialogueId(id); + + addResponse(id); +} + +bool TTnpcScript::handleWord(uint id) const { + if (_words.empty()) + return false; + + for (uint idx = 0; idx < _words.size(); ++idx) { + const TTwordEntry &we = _words[idx]; + if (we._id == id) { + TTstring str(we._text); + g_vm->_scriptHandler->handleWord(&str); + return true; + } + } + + g_vm->_scriptHandler->handleWord(nullptr); + return true; +} + +int TTnpcScript::handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder) { + if (_quotes.empty()) + return 1; + + + int loopCounter = 0; + for (uint idx = 0; idx < _quotes.size() && loopCounter < 2; ++idx) { + const TThandleQuoteEntry *qe = &_quotes[idx]; + + if (!qe->_index) { + // End of list; start at beginning again + ++loopCounter; + idx = 0; + qe = &_quotes[0]; + } + + if (qe->_index == val && ( + (tagId == 0 && loopCounter == 2) || + (qe->_tagId < MKTAG('A', 'A', 'A', 'A')) || + (qe->_tagId == tagId) + )) { + uint foundTagId = qe->_tagId; + if (foundTagId > 0 && foundTagId < 100) { + if (!tagId) + foundTagId >>= 1; + if (getRandomNumber(100) < foundTagId) + return 1; + } + + uint dialogueId = qe->_dialogueId; + if (dialogueId >= _quotes._rangeStart && dialogueId <= _quotes._rangeEnd) { + dialogueId -= _quotes._rangeStart; + if (dialogueId > 3) + error("Invalid dialogue index in BarbotScript"); + + const int RANDOM_LIMITS[4] = { 30, 50, 70, 60 }; + int rangeLimit = RANDOM_LIMITS[dialogueId]; + int dialRegion = getDialRegion(0); + + if (dialRegion != 1) { + rangeLimit = MAX(rangeLimit - 20, 20); + } + + dialogueId = (((int)remainder + 25) % 100) >= rangeLimit + ? _quotes._tag1 : _quotes._tag2; + } + + addResponse(getDialogueId(dialogueId)); + applyResponse(); + return 2; + } + } + + return 1; + +} + +uint TTnpcScript::getRangeValue(uint id) { + TTscriptRange *range = findRange(id); + if (!range) + return 0; + + switch (range->_mode) { + case SF_RANDOM: { + uint count = range->_values.size(); + + uint index = getRandomNumber(count) - 1; + if (count > 1 && range->_values[index] == range->_priorIndex) { + for (int retry = 0; retry < 8 && index != range->_priorIndex; ++retry) + index = getRandomNumber(count) - 1; + } + + range->_priorIndex = index; + return range->_values[index]; + } + + case SF_SEQUENTIAL: { + // Get the next value from the array sequentially + int val = range->_values[range->_priorIndex]; + if (!val) { + // Reached end of array, so reset back to start + range->_priorIndex = 1; + val = range->_values[1]; + } + + ++range->_priorIndex; + return val; + } + + default: + if (range->_values[range->_priorIndex]) + return range->_values[range->_priorIndex++]; + + range->_priorIndex = 1; + ++_rangeResetCtr; + return range->_values[0]; + } +} + +void TTnpcScript::resetRange(int id) { + TTscriptRange *range = findRange(id); + if (range && range->_mode != SF_RANDOM) + range->_priorIndex = 0; +} + +int TTnpcScript::updateState(uint oldId, uint newId, int index) { + return newId; +} + +int TTnpcScript::preResponse(uint id) { + return 0; +} + +const TTscriptMapping *TTnpcScript::getMapping(int index) { + if (index >= 0 && index < (int)_mappings.size()) + return &_mappings[index]; + return nullptr; +} + +int TTnpcScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) { + return 0; +} + +void TTnpcScript::save(SimpleFile *file) { + file->writeNumber(charId()); + saveBody(file); + + file->writeNumber(4); + file->writeNumber(_rangeResetCtr); + file->writeNumber(_currentDialNum); + file->writeNumber(_dialDelta); + file->writeNumber(_field7C); + + file->writeNumber(10); + for (int idx = 0; idx < 10; ++idx) + file->writeNumber(_data[idx]); +} + +void TTnpcScript::load(SimpleFile *file) { + loadBody(file); + + int count = file->readNumber(); + _rangeResetCtr = file->readNumber(); + _currentDialNum = file->readNumber(); + _dialDelta = file->readNumber(); + _field7C = file->readNumber(); + + for (int idx = count; idx > 4; --idx) + file->readNumber(); + + count = file->readNumber(); + for (int idx = 0; idx < count; ++idx) { + int v = file->readNumber(); + if (idx < 10) + _data[idx] = v; + } +} + +void TTnpcScript::saveBody(SimpleFile *file) { + int count = proc31(); + file->writeNumber(count); + + if (count > 0) { + for (uint idx = 0; idx < _ranges.size(); ++idx) { + const TTscriptRange &item = _ranges[idx]; + if (item._mode == SF_RANDOM && item._priorIndex) { + file->writeNumber(item._id); + file->writeNumber(item._priorIndex); + } + } + } +} + +void TTnpcScript::loadBody(SimpleFile *file) { + int count = file->readNumber(); + preLoad(); + + for (int index = 0; index < count; index += 2) { + int id = file->readNumber(); + int val = file->readNumber(); + + for (uint idx = 0; idx < _ranges.size(); ++idx) { + TTscriptRange &item = _ranges[idx]; + if (item._id == (uint)id) { + item._priorIndex = val; + break; + } + } + } +} + +int TTnpcScript::proc31() const { + int count = 0; + for (uint idx = 0; idx < _ranges.size(); ++idx) { + const TTscriptRange &item = _ranges[idx]; + if (item._mode != SF_RANDOM && item._priorIndex) + ++count; + } + + return count * 2; +} + +void TTnpcScript::setDialRegion(int dialNum, int region) { + if (dialNum < DIALS_ARRAY_COUNT) + _dialValues[dialNum] = region * 100; + + if (g_vm->_trueTalkManager) { + CPetControl *petControl = getPetControl(g_vm->_trueTalkManager->getGameManager()); + if (petControl) + petControl->playSound(1); + } +} + +void TTnpcScript::setDial(int dialNum, int value) { + if (dialNum < DIALS_ARRAY_COUNT) { + int oldRegion = getDialRegion(dialNum); + + int newRegion = 1; + if (value < 50) + newRegion = 0; + else if (value > 150) + newRegion = 2; + + if (oldRegion == newRegion) + setDialRegion(dialNum, newRegion); + + _dialValues[dialNum] = value; + } + + if (g_vm->_trueTalkManager) { + CPetControl *petControl = getPetControl(g_vm->_trueTalkManager->getGameManager()); + if (petControl) + petControl->convResetDials(); + } +} + +int TTnpcScript::getDialRegion(int dialNum) const { + if (dialNum < DIALS_ARRAY_COUNT) { + int value = _dialValues[dialNum]; + if (value < 50) + return 0; + else if (value > 150) + return 2; + else + return 1; + } else { + return 0; + } +} + +int TTnpcScript::getDialLevel(uint dialNum, bool randomizeFlag) { + int result = _dialValues[dialNum]; + if (randomizeFlag) { + bool lowFlag = result <= 50; + result = CLIP(result + (int)getRandomNumber(18) - 9, 0, 100); + + if (lowFlag) { + result = MIN(result, 46); + } else { + result = MAX(result, 54); + } + } + + return result; +} + +bool TTnpcScript::randomResponse(uint index) { + return false; +} + +uint TTnpcScript::translateId(uint id) const { + for (uint idx = 0; idx < _tagMappings.size(); ++idx) { + if (_tagMappings[idx]._src == id) + return _tagMappings[idx]._dest; + } + + return 0; +} + +void TTnpcScript::preLoad() { + for (uint idx = 0; idx < _ranges.size(); ++idx) + _ranges[idx]._priorIndex = 0; +} + +int TTnpcScript::getRoom54(int roomId) { + TTroomScript *room = g_vm->_trueTalkManager->getRoomScript(roomId); + return room ? room->_field54 : 0; +} + +int TTnpcScript::getValue(int testNum) const { + switch (testNum) { + case 0: + return CTrueTalkManager::_v2; + + case 1: + if (g_vm->_trueTalkManager) + CTrueTalkManager::_v3 = g_vm->_trueTalkManager->getPassengerClass(); + return CTrueTalkManager::_v3; + + case 2: + return CTrueTalkManager::_v4; + + case 3: + return CTrueTalkManager::_v5 != 0; + + case 4: + if (g_vm->_trueTalkManager) { + switch (g_vm->_trueTalkManager->getState14()) { + case 1: + CTrueTalkManager::_v6 = 3; + break; + case 2: + CTrueTalkManager::_v6 = 0; + break; + case 3: + CTrueTalkManager::_v6 = 1; + break; + default: + CTrueTalkManager::_v6 = 2; + break; + } + } + return CTrueTalkManager::_v6; + + case 5: + return CTrueTalkManager::_v7; + + case 6: + return CTrueTalkManager::_v8 != 0; + + case 7: + return !!getRoom54(123); + + default: + return CTrueTalkManager::_v11[testNum]; + } +} + +uint TTnpcScript::getRandomNumber(int max) const { + return 1 + g_vm->getRandomNumber(max - 1); +} + +uint TTnpcScript::getDialogueId(uint tagId) { + if (tagId < 200000) + return tagId; + + // Perform any script specific translation + uint origId = tagId; + if (tagId >= 290000 && tagId <= 290263) + tagId = translateId(tagId); + if (!tagId) + return 0; + + if (!_field2CC) { + _field2CC = true; + int val = translateByArray(tagId); + if (val > 0) { + if (randomResponse(val)) + return 4; + } + } + + uint oldTagId = tagId; + tagId = getRangeValue(tagId); + if (tagId != oldTagId) + tagId = getRangeValue(tagId); + + oldTagId = getDialsBitset(); + uint newId = updateState(origId, tagId, oldTagId); + if (!newId) + return 0; + + int idx = 0; + const TTscriptMapping *tableP; + for (;;) { + tableP = getMapping(idx++); + if (!tableP) + return 0; + + if (tableP->_id == newId) + break; + } + uint newVal = tableP->_values[oldTagId]; + + // First slot dialogue Ids + idx = 0; + int *arrP = _data.getSlot(0); + while (idx < 4 && arrP[idx]) + ++idx; + + if (idx == 4) + return newVal; + arrP[idx] = origId; + + // Second slot dialogue Ids + idx = 0; + arrP = _data.getSlot(1); + while (idx < 4 && arrP[idx]) + ++idx; + + if (idx == 4) + return newVal; + arrP[idx] = newVal; + + return newVal; +} + +int TTnpcScript::translateByArray(int id) { + for (uint idx = 1, arrIndex = 35; idx < 15; ++idx, arrIndex += 8) { + if (_data[idx - 1] == id && _data[idx] == 0) + return idx; + } + + return -1; +} + +CPetControl *TTnpcScript::getPetControl(CGameManager *gameManager) { + if (gameManager && gameManager->_project) + return gameManager->_project->getPetControl(); + return nullptr; +} + +int TTnpcScript::processEntries(const TTsentenceEntries *entries, uint entryCount, const TTroomScript *roomScript, const TTsentence *sentence) { + if (!entries) + return SS_1; + if (!entryCount) + // No count specified, so use entire list + entryCount = entries->size(); + int entryId = _field2C; + + for (uint loopCtr = 0; loopCtr < 2; ++loopCtr) { + for (uint entryCtr = 0; entryCtr < entryCount; ++entryCtr) { + const TTsentenceEntry &entry = (*entries)[entryCtr]; + if (entry._field4 != entryId && (loopCtr == 0 || entry._field4)) + continue; + + bool flag; + if (entry._fieldC || entry._string10.empty()) { + flag = sentence->fn1(entry._string8, entry._fieldC, + entry._string14, entry._string18, entry._string1C, + entry._field20, entry._field28, 0, nullptr); + } else { + flag = sentence->fn3(entry._string8, entry._string10, + entry._string14, entry._string18, entry._string1C, + entry._string24, entry._field28, 0, nullptr); + } + + if (flag) { + if (entry._field2C) { + bool flag2 = true; + if (entry._field2C & 0x1000000) + flag2 = sentence->isConcept34(1); + + if (entry._field2C & 0x2000000) + flag2 = sentence->isConcept34(0) || sentence->isConcept34(4); + + if (!flag2) { + flag = false; + } else { + int result = doSentenceEntry(entry._field2C & 0xFFFFFF, &entry._field0, + roomScript, sentence); + if (result == 2) + return 2; + flag = !result; + } + } + + if (flag) { + int dialogueId = getDialogueId(entry._field0); + int id; + if (!dialogueId) + return 1; + else if (dialogueId == 4) + return 2; + addResponse(dialogueId); + + id = preResponse(dialogueId); + if (id) + addResponse(getDialogueId(id)); + applyResponse(); + + if (entry._field30) + postResponse(entry._field30, &entry, roomScript, sentence); + + return 2; + } + } + } + } + + return 1; +} + +bool TTnpcScript::defaultProcess(const TTroomScript *roomScript, const TTsentence *sentence) { + uint remainder; + TTtreeResult results[32]; + const TTstring &line = sentence->_normalizedLine; + + uint tagId = g_vm->_trueTalkManager->_quotes.find(line.c_str()); + int val = g_vm->_trueTalkManager->_quotesTree.search(line.c_str(), TREE_1, results, tagId, &remainder); + + if (val > 0) { + if (!handleQuote(roomScript, sentence, val, tagId, remainder)) + return true; + } + + if (tagId) { + if (chooseResponse(roomScript, sentence, tagId) == 2) + return true; + } + + return false; +} + +void TTnpcScript::addRange(uint id, const Common::Array<uint> &values, bool isRandom, bool isSequential) { + _ranges.push_back(TTscriptRange(id, values, isRandom, isSequential)); +} + +TTscriptRange *TTnpcScript::findRange(uint id) { + for (uint idx = 0; idx < _ranges.size(); ++idx) { + if (_ranges[idx]._id == id) + return &_ranges[idx]; + } + + return nullptr; +} + +void TTnpcScript::checkItems(const TTroomScript *roomScript, const TTsentence *sentence) { + _field2CC = 0; + ++CTrueTalkManager::_v2; + + if (sentence) { + if (!_itemStringP || getRandomNumber(100) > 80) { + for (const char *const *strP = &ITEMS[0]; *strP; ++strP) { + if (sentence->localWord(*strP)) { + _itemStringP = *strP; + break; + } + } + } + + if (sentence->localWord("bomb")) + _field7C = 1; + } +} + +bool TTnpcScript::addRandomResponse(bool flag) { + if (getValue(1) > 3) + return false; + + const uint *data; + if (flag) { + if (getValue(1) == 2) + data = RANDOM8; + else if (getValue(1) == 1) + data = RANDOM7; + else + data = RANDOM9; + } else if (getRandomBit()) { + if (getValue(1) == 2) + data = RANDOM2; + else if (getValue(1) == 1) + data = RANDOM1; + else + data = RANDOM3; + } else { + if (getValue(1) == 2) + data = RANDOM5; + else if (getValue(1) == 1) + data = RANDOM4; + else + data = RANDOM6; + } + + // Pick a random entry + uint count = 0; + while (data[count]) + ++count; + uint id = data[getRandomNumber(count - 1)]; + + if (id == 290188 && getRoom54(101)) + id = 290189; + else if (id == 290202 && getRoom54(123)) + id = 290203; + + if (!id) + return false; + id = getDialogueId(id); + if (id == 4) + return true; + if (!id) + return false; + + if (flag) + addResponse(getDialogueId(290224)); + + addResponse(id); + applyResponse(); + return true; +} + +void TTnpcScript::updateCurrentDial(bool changeDial) { + int dialLevel = CLIP(getDialLevel(_currentDialNum) + _dialDelta, 0, 100); + setDial(_currentDialNum, dialLevel); + + bool edgeFlag = false; + if (_dialDelta < 0) { + if (dialLevel < 10 || getRandomNumber(100) > 93) + edgeFlag = true; + } else { + if (dialLevel > 90 || getRandomNumber(100) > 93) + edgeFlag = true; + } + + if (edgeFlag) { + if (changeDial) + _currentDialNum = getRandomNumber(3); + + _dialDelta = getRandomNumber(12) + 3; + dialLevel = getDialLevel(_currentDialNum, false); + if (dialLevel > 50) + _dialDelta = -_dialDelta; + } +} + +bool TTnpcScript::fn10(bool flag) { + if (_itemStringP) { + for (const ItemRec *ir = ARRAY1; ir->_id; ++ir) { + if (!strcmp(ir->_name, _itemStringP)) { + _itemStringP = nullptr; + uint id = getDialogueId(ir->_id); + if (id == 4) { + return true; + } else if (id != 0) { + addResponse(id); + applyResponse(); + return true; + } + break; + } + } + + _itemStringP = nullptr; + } + + if (flag && getRandomNumber(100) > 60) { + int val = getRandomNumber(18) - 1; + + if (val == 0 && !getRoom54(101) && !getRoom54(132)) + val = -1; + else if ((val == 1 && !_field7C) || val == 2) + val = -1; + + if (val >= 0) { + val = getDialogueId(ARRAY2[val]); + if (val == 4) { + return true; + } else { + addResponse(val); + applyResponse(); + return true; + } + } + } + + return false; +} + +bool TTnpcScript::getStateValue() const { + if (!CTrueTalkManager::_currentNPC) + return false; + + CGameObject *bomb; + if (CTrueTalkManager::_currentNPC->find("Bomb", &bomb, FIND_GLOBAL) && bomb) { + CTrueTalkGetStateValueMsg stateMsg(10, -1000); + stateMsg.execute(bomb); + if (stateMsg._stateVal) + return true; + } + + return false; +} + +bool TTnpcScript::sentence2C(const TTsentence *sentence) { + return sentence->_field2C >= 2 && sentence->_field2C <= 7; +} + +void TTnpcScript::getAssignedRoom(int *roomNum, int *floorNum, int *elevatorNum) const { + if (roomNum) + *roomNum = 5; + if (floorNum) + *floorNum = 40; + if (elevatorNum) + *elevatorNum = 3; + + CGameManager *gameManager = g_vm->_trueTalkManager->getGameManager(); + CPetControl *petControl = getPetControl(gameManager); + if (petControl) { + if (roomNum) + *roomNum = petControl->getAssignedRoomNum(); + if (floorNum) + *floorNum = petControl->getAssignedFloorNum(); + if (elevatorNum) + *elevatorNum = petControl->getAssignedElevatorNum(); + } + + if (floorNum) + *floorNum = CLIP(*floorNum, 1, 42); + if (roomNum) + *roomNum = CLIP(*roomNum, 1, 18); + if (elevatorNum) + *elevatorNum = CLIP(*elevatorNum, 1, 4); +} + +void TTnpcScript::setResponseFromArray(int index, int id) { + if (index >= 0 && index <= 15) { + deleteResponses(); + if (id) + addResponse(getDialogueId(id)); + + // Add any loaded responses + int *vals = _data.getSlot(index + 1); + for (int idx = 0; idx < 4; ++idx) { + if (vals[idx]) + addResponse(vals[idx]); + } + applyResponse(); + + // Clear out the values used + if (index) + Common::fill(vals, vals + 4, 0); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_npc_script.h b/engines/titanic/true_talk/tt_npc_script.h new file mode 100644 index 0000000000..b9afdfad8a --- /dev/null +++ b/engines/titanic/true_talk/tt_npc_script.h @@ -0,0 +1,355 @@ +/* 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 TITANIC_TT_NPC_SCRIPT_H +#define TITANIC_TT_NPC_SCRIPT_H + +#include "titanic/support/simple_file.h" +#include "titanic/true_talk/tt_script_base.h" +#include "titanic/true_talk/script_support.h" + +namespace Titanic { + +#define DIALS_ARRAY_COUNT 10 + +class CGameManager; +class CPetControl; +class TTroomScript; + +struct TTnpcData { +private: + int _array[136]; +public: + TTnpcData(); + int &operator[](int idx) { return _array[idx]; } + int *getSlot(int idx) { return &_array[16 + idx * 4]; } + void resetFlags(); +}; + +class TTnpcScriptBase : public TTscriptBase { +protected: + int _field54; + int _val2; +public: + int _charId; +public: + TTnpcScriptBase(int charId, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, + int v5, int v6, int v7); + + /** + * Chooses and adds a conversation response based on a specified tag Id. + */ + virtual int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) = 0; + + /** + * Does NPC specific processing of the parsed sentence + */ + virtual int process(const TTroomScript *roomScript, const TTsentence *sentence) = 0; + + virtual int proc8() const = 0; + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(uint id) = 0; + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) = 0; + + virtual int proc11() const = 0; + virtual int proc12() const = 0; + + int charId() const { return _charId; } +}; + +class TTnpcScript : public TTnpcScriptBase { +private: + int translateByArray(int id); +protected: + static TTsentenceEntries *_defaultEntries; +protected: + Common::Array<TTnpcScriptResponse> _responses; + int _valuesPerResponse; + Common::Array<TTscriptRange> _ranges; + TTscriptMappings _mappings; + TTsentenceEntries _entries; + TTtagMappings _tagMappings; + TTwordEntries _words; + TThandleQuoteEntries _quotes; + int _entryCount; + int _field68; + int _field6C; + int _rangeResetCtr; + int _currentDialNum; + int _dialDelta; + int _field7C; + const char *_itemStringP; + int _dialValues[DIALS_ARRAY_COUNT]; + TTnpcData _data; + bool _field2CC; +protected: + /** + * Loads response data for the NPC from the given resource + */ + void loadResponses(const char *name, int valuesPerResponse = 1); + + /** + * Load ranges data for the NPC from the given resource + */ + void loadRanges(const char *name); + + /** + * Reset script flags + */ + void resetFlags(); + + /** + * Setup dials + */ + void setupDials(int dial1, int dial2, int dial3); + + static int getRoom54(int roomId); + + /** + * Perform test on various state values + */ + int getValue(int testNum) const; + + /** + * Gets a random number between 1 and a given max + */ + uint getRandomNumber(int max) const; + + /** + * Gets a random number of 0 or 1 + */ + uint getRandomBit() const { + return getRandomNumber(2) - 1; + } + + /** + * Returns a dialogue Id by script tag value Id + */ + uint getDialogueId(uint tagId); + + /** + * Returns a pointer to the PET control + */ + static CPetControl *getPetControl(CGameManager *gameManager); + + /** + * Adds a new item to the list of number ranges + */ + void addRange(uint id, const Common::Array<uint> &values, bool isRandom, bool isSequential); + + /** + * Finds an entry in the list of prevoiusly registered number ranges + */ + TTscriptRange *findRange(uint id); + + /** + * Scans through a list of sentence entries for a matching standardized response + */ + int processEntries(const TTsentenceEntries *entries, uint entryCount, const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Scans through a list of sentence entries for a matching standardized response + */ + int processEntries(const TTroomScript *roomScript, const TTsentence *sentence) { + return processEntries(&_entries, _entryCount, roomScript, sentence); + } + + bool defaultProcess(const TTroomScript *roomScript, const TTsentence *sentence); + + void checkItems(const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Adds a random conversation response + */ + bool addRandomResponse(bool flag); + + /** + * Updates the current dial with the given delta + */ + void updateCurrentDial(bool changeDial); + + bool fn10(bool flag); + + static bool sentence2C(const TTsentence *sentence); + + /** + * Gets the True Talk state value + */ + bool getStateValue() const; + + /** + * Gets the assigned room's room, floor, and elevator number + */ + void getAssignedRoom(int *roomNum, int *floorNum, int *elevatorNum) const; + + /** + * Uses a porition of the state _array to set up a new response + */ + void setResponseFromArray(int index, int id); +public: + static void init(); + static void deinit(); +public: + TTnpcScript(int charId, const char *charClass, int v2, + const char *charName, int v3, int val2, int v4, + int v5, int v6, int v7); + + virtual void addResponse(int id); + + /** + * Chooses and adds a conversation response based on a specified tag Id. + * This default implementation does a lookup into a list of known tags, + * and chooses a random dialogue Id from the available ones for that tag + */ + virtual int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag); + + /** + * Does NPC specific processing of the parsed sentence + */ + virtual int process(const TTroomScript *roomScript, const TTsentence *sentence); + + virtual int proc8() const; + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(uint id) { + return SCR_2; + } + + /** + * Called when the script/id changes + */ + virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) { + return SCR_2; + } + + virtual int proc11() const; + virtual int proc12() const; + + /** + * Translate a passed Id to a dialogue Id if necessary, + * and adds it to the response + */ + virtual void selectResponse(int id); + + /** + * Handles scanning the word list for a given Id, and if + * found adds it to the sentence concept list + */ + virtual bool handleWord(uint id) const; + + virtual int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, + uint val, uint tagId, uint remainder); + + /** + * Given an Id for a previously registered set of random number values, + * picks one of the array values and returns it.. depending on flags, + * either a random value, or each value in turn + */ + virtual uint getRangeValue(uint id); + + /** + * Resets the prior used index for the specified range + */ + virtual void resetRange(int id); + + /** + * Handles updating NPC state based on specified dialogue Ids and dial positions + */ + virtual int updateState(uint oldId, uint newId, int index); + + /** + * Handles getting a pre-response + */ + virtual int preResponse(uint id); + + /** + * Returns a bitset of the dials being off or not + */ + virtual uint getDialsBitset() const { return 0; } + + virtual const TTscriptMapping *getMapping(int index); + virtual int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence); + + /** + * Handles any post-response NPC processing + */ + virtual void postResponse(int v1, const TTsentenceEntry *entry, const TTroomScript *roomScript, const TTsentence *sentence) {} + + virtual void save(SimpleFile *file); + virtual void load(SimpleFile *file); + virtual void saveBody(SimpleFile *file); + virtual void loadBody(SimpleFile *file); + virtual int proc31() const; + + /** + * Sets a given dial to be pointing in a specified region (0 to 2) + */ + virtual void setDialRegion(int dialNum, int region); + + /** + * Sets the value for an NPC's dial + */ + virtual void setDial(int dialNum, int value); + + /** + * Returns a dial's region number + */ + virtual int getDialRegion(int dialNum) const; + + /** + * Gets the value for a dial + * @param dialNum Dial number + * @param randomizeFlag If set, introduces a slight random variance so that + * the displayed dial will oscillate randomly around it's real level + */ + virtual int getDialLevel(uint dialNum, bool randomizeFlag = true); + + /** + * Handles a randomzied response + */ + virtual bool randomResponse(uint index); + + virtual uint translateId(uint id) const; + + void preLoad(); + + /** + * Called with the script and id changes + */ + ScriptChangedResult notifyScript(TTroomScript *roomScript, int id) { + return scriptChanged(roomScript, id); + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_NPC_SCRIPT_H */ diff --git a/engines/titanic/true_talk/tt_parser.cpp b/engines/titanic/true_talk/tt_parser.cpp new file mode 100644 index 0000000000..1d9c199054 --- /dev/null +++ b/engines/titanic/true_talk/tt_parser.cpp @@ -0,0 +1,1713 @@ +/* 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 "titanic/true_talk/tt_parser.h" +#include "titanic/true_talk/script_handler.h" +#include "titanic/true_talk/tt_action.h" +#include "titanic/true_talk/tt_concept.h" +#include "titanic/true_talk/tt_picture.h" +#include "titanic/true_talk/tt_sentence.h" +#include "titanic/true_talk/tt_word.h" +#include "titanic/titanic.h" + +namespace Titanic { + +TTparser::TTparser(CScriptHandler *owner) : _owner(owner), _sentenceConcept(nullptr), + _sentence(nullptr), _fieldC(0), _field10(0), _field14(0), + _currentWordP(nullptr), _nodesP(nullptr), _conceptP(nullptr) { + loadArrays(); +} + +TTparser::~TTparser() { + if (_nodesP) { + _nodesP->deleteSiblings(); + delete _nodesP; + } + + if (_conceptP) { + _conceptP->deleteSiblings(); + delete _conceptP; + } + + delete _currentWordP; +} + +void TTparser::loadArray(StringArray &arr, const CString &name) { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name); + while (r->pos() < r->size()) + arr.push_back(readStringFromStream(r)); + delete r; +} + +void TTparser::loadArrays() { + loadArray(_replacements1, "TEXT/REPLACEMENTS1"); + loadArray(_replacements2, "TEXT/REPLACEMENTS2"); + loadArray(_replacements3, "TEXT/REPLACEMENTS3"); + loadArray(_phrases, "TEXT/PHRASES"); + loadArray(_pronouns, "TEXT/PRONOUNS"); + + Common::SeekableReadStream *r = g_vm->_filesManager->getResource("TEXT/NUMBERS"); + while (r->pos() < r->size()) { + NumberEntry ne; + ne._text = readStringFromStream(r); + ne._value = r->readSint32LE(); + ne._flags = r->readUint32LE(); + _numbers.push_back(ne); + } + delete r; +} + +int TTparser::preprocess(TTsentence *sentence) { + _sentence = sentence; + if (normalize(sentence)) + return 0; + + // Scan for and replace common slang and contractions with verbose versions + searchAndReplace(sentence->_normalizedLine, _replacements1); + searchAndReplace(sentence->_normalizedLine, _replacements2); + + // Check entire normalized line against common phrases to replace + for (uint idx = 0; idx < _phrases.size(); idx += 2) { + if (!_phrases[idx].compareTo(sentence->_normalizedLine)) + sentence->_normalizedLine = _phrases[idx + 1]; + } + + // Do a further search and replace of roman numerals to decimal + searchAndReplace(sentence->_normalizedLine, _replacements3); + + // Replace any roman numerals, spelled out words, etc. with decimal numbers + CTrueTalkManager::_v1 = -1000; + int idx = 0; + do { + idx = replaceNumbers(sentence->_normalizedLine, idx); + } while (idx >= 0); + + if (CTrueTalkManager::_v1 == -1000 && !sentence->_normalizedLine.empty()) { + // Scan the text for any numeric digits + for (const char *strP = sentence->_normalizedLine.c_str(); *strP; ++strP) { + if (Common::isDigit(*strP)) { + // Found digit, so convert it and any following ones + CTrueTalkManager::_v1 = atoi(strP); + break; + } + } + } + + return 0; +} + +int TTparser::normalize(TTsentence *sentence) { + TTstring *destLine = new TTstring(); + const TTstring &srcLine = sentence->_initialLine; + int srcSize = srcLine.size(); + int savedIndex = 0; + int counter1 = 0; + int commandVal; + + for (int index = 0; index < srcSize; ++index) { + char c = srcLine[index]; + if (Common::isLower(c)) { + (*destLine) += c; + } else if (Common::isSpace(c)) { + if (!destLine->empty() && destLine->lastChar() != ' ') + (*destLine) += ' '; + } else if (Common::isUpper(c)) { + (*destLine) += toupper(c); + } else if (Common::isDigit(c)) { + if (c == '0' && isEmoticon(srcLine, index)) { + sentence->set38(10); + } else { + // Iterate through all the digits of the number + (*destLine) += c; + while (Common::isDigit(srcLine[index + 1])) + (*destLine) += srcLine[++index]; + } + } else if (Common::isPunct(c)) { + bool flag = false; + switch (c) { + case '!': + sentence->set38(3); + break; + + case '\'': + if (!normalizeContraction(srcLine, index, *destLine)) + flag = true; + break; + + case '.': + sentence->set38(1); + break; + + case ':': + commandVal = isEmoticon(srcLine, index); + if (commandVal) { + sentence->set38(commandVal); + index += 2; + } else { + flag = true; + } + break; + + case ';': + commandVal = isEmoticon(srcLine, index); + if (commandVal == 6) { + sentence->set38(7); + index += 2; + } else if (commandVal != 0) { + sentence->set38(commandVal); + index += 2; + } + break; + + case '<': + ++index; + commandVal = isEmoticon(srcLine, index); + if (commandVal == 6) { + sentence->set38(12); + } else { + --index; + flag = true; + } + break; + + case '>': + ++index; + commandVal = isEmoticon(srcLine, index); + if (commandVal == 6 || commandVal == 9) { + sentence->set38(11); + } else { + --index; + flag = true; + } + break; + + case '?': + sentence->set38(2); + break; + + default: + flag = true; + break; + } + + if (flag && (!savedIndex || (index - savedIndex) == 1)) + ++counter1; + + savedIndex = index; + } + } + + if (counter1 >= 4) + sentence->set38(4); + + // Remove any trailing spaces + while (destLine->hasSuffix(" ")) + destLine->deleteLastChar(); + + // Copy out the normalized line + sentence->_normalizedLine = *destLine; + delete destLine; + + return 0; +} + +int TTparser::isEmoticon(const TTstring &str, int &index) { + if (str[index] != ':' && str[index] != ';') + return 0; + + if (str[index + 1] != '-') + return 0; + + index += 2; + switch (str[index]) { + case '(': + case '<': + return 8; + + case ')': + case '>': + return 6; + + case 'P': + case 'p': + return 9; + + default: + return 5; + } +} + +bool TTparser::normalizeContraction(const TTstring &srcLine, int srcIndex, TTstring &destLine) { + int startIndex = srcIndex + 1; + switch (srcLine[startIndex]) { + case 'd': + srcIndex += 2; + if (srcLine.compareAt(srcIndex, " a ") || srcLine.compareAt(srcIndex, " the ")) { + destLine += " had"; + } else { + destLine += " would"; + } + + srcIndex = startIndex; + break; + + case 'l': + if (srcLine[srcIndex + 2] == 'l') { + // 'll ending + destLine += " will"; + srcIndex = startIndex; + } + break; + + case 'm': + // 'm ending + destLine += " am"; + srcIndex = startIndex; + break; + + case 'r': + // 're ending + if (srcLine[srcIndex + 2] == 'e') { + destLine += " are"; + srcIndex = startIndex; + } + break; + + case 's': + destLine += "s*"; + srcIndex = startIndex; + break; + + case 't': + if (srcLine[srcIndex - 1] == 'n' && srcIndex >= 3) { + if (srcLine[srcIndex - 3] == 'c' && srcLine[srcIndex - 2] == 'a' && + (srcIndex == 3 || srcLine[srcIndex - 4])) { + // can't -> can not + destLine += 'n'; + } else if (srcLine[srcIndex - 3] == 'w' && srcLine[srcIndex - 2] == 'o' && + (srcIndex == 3 || srcLine[srcIndex - 4])) { + // won't -> will not + destLine.deleteLastChar(); + destLine.deleteLastChar(); + destLine += "ill"; + } else if (srcLine[srcIndex - 3] == 'a' && srcLine[srcIndex - 2] == 'i' && + (srcIndex == 3 || srcLine[srcIndex - 4])) { + // ain't -> am not + destLine.deleteLastChar(); + destLine.deleteLastChar(); + destLine += "m"; + } else if (srcLine.hasSuffix(" sha") || + (srcIndex == 4 && srcLine.hasSuffix("sha"))) { + // shan't -> shall not + destLine.deleteLastChar(); + destLine += "ll"; + } + + destLine += " not"; + } + break; + + case 'v': + // 've ending + if (srcLine[startIndex + 2] == 'e') { + destLine += " have"; + srcIndex = startIndex; + } + break; + + default: + break; + } + + return false; +} + +void TTparser::searchAndReplace(TTstring &line, const StringArray &strings) { + int charIndex = 0; + while (charIndex >= 0) + charIndex = searchAndReplace(line, charIndex, strings); +} + +int TTparser::searchAndReplace(TTstring &line, int startIndex, const StringArray &strings) { + int lineSize = line.size(); + if (startIndex >= lineSize) + return -1; + + for (uint idx = 0; idx < strings.size(); idx += 2) { + const CString &origStr = strings[idx]; + const CString &replacementStr = strings[idx + 1]; + + if (!strncmp(line.c_str() + startIndex, origStr.c_str(), strings[idx].size())) { + // Ensure that that a space follows the match, or the end of string, + // so the end of the string doesn't match on parts of larger words + char c = line[startIndex + strings[idx].size()]; + if (c == ' ' || c == '\0') { + // Replace the text in the line with it's replacement + line = CString(line.c_str(), line.c_str() + startIndex) + replacementStr + + CString(line.c_str() + startIndex + origStr.size()); + + startIndex += replacementStr.size(); + break; + } + } + } + + // Skip to the end of the current word + while (startIndex < lineSize && line[startIndex] != ' ') + ++startIndex; + if (startIndex == lineSize) + return -1; + + // ..and all spaces following it until the start of the next word + while (startIndex < lineSize && line[startIndex] == ' ') + ++startIndex; + if (startIndex == lineSize) + return -1; + + // Return index of the start of the next word + return startIndex; +} + +int TTparser::replaceNumbers(TTstring &line, int startIndex) { + int index = startIndex; + const NumberEntry *numEntry = replaceNumbers2(line, &index); + if (!numEntry || !(numEntry->_flags & NF_2)) + return index; + + bool flag1 = false, flag2 = false, flag3 = false; + int total = 0, factor = 0; + + do { + if (numEntry->_flags & NF_1) { + flag2 = true; + if (numEntry->_flags & NF_8) + flag1 = true; + + if (numEntry->_flags & NF_4) { + flag3 = true; + factor *= numEntry->_value; + } + + if (numEntry->_flags & NF_2) { + if (flag3) { + total += factor; + factor = 0; + } + + factor += numEntry->_value; + } + } + } while (replaceNumbers2(line, &index)); + + if (!flag2) + return index; + + if (index >= 0) { + if (line[index - 1] != ' ') + return index; + } + + total += factor; + CTrueTalkManager::_v1 = total; + if (flag1) + total = -total; + + CString numStr = CString::format("%d", total); + line = CString(line.c_str(), line.c_str() + startIndex) + numStr + + CString(line.c_str() + index); + return index; +} + +const NumberEntry *TTparser::replaceNumbers2(TTstring &line, int *startIndex) { + int lineSize = line.size(); + int index = *startIndex; + if (index < 0 || index >= lineSize) { + *startIndex = -1; + return nullptr; + } + + NumberEntry *numEntry = nullptr; + + for (uint idx = 0; idx < _numbers.size(); ++idx) { + NumberEntry &ne = _numbers[idx]; + if (!strncmp(line.c_str() + index, ne._text.c_str(), ne._text.size())) { + if ((ne._flags & NF_10) || (index + (int)ne._text.size()) >= lineSize || + line[index + ne._text.size()] == ' ') { + *startIndex += ne._text.size(); + numEntry = ≠ + break; + } + } + } + + if (!numEntry || !(numEntry->_flags & NF_10)) { + // Skip to end of current word + while (*startIndex < lineSize && !Common::isSpace(line[*startIndex])) + ++*startIndex; + } + + // Skip over following spaces until start of following word is reached + while (*startIndex < lineSize && Common::isSpace(line[*startIndex])) + ++*startIndex; + + if (*startIndex >= lineSize) + *startIndex = -1; + + return numEntry; +} + +int TTparser::findFrames(TTsentence *sentence) { + _sentenceConcept = &sentence->_sentenceConcept; + _sentence = sentence; + + TTstring *line = sentence->_normalizedLine.copy(); + TTstring wordString; + int status = 0; + for (int ctr = 1; !status; ++ctr) { + // Keep stripping words off the start of the passed input + wordString = line->tokenize(" \n"); + if (wordString.empty()) + break; + + TTword *srcWord = nullptr; + TTword *word = _owner->_vocab->getWord(wordString, &word); + sentence->storeVocabHit(srcWord); + + if (!word && ctr == 1) { + word = new TTword(wordString, WC_UNKNOWN, 0); + } + + for (TTword *currP = word; currP && !status; currP = currP->_nextP) + status = processRequests(currP); + + word->deleteSiblings(); + delete word; + } + + if (!status) { + status = checkForAction(); + } + + delete line; + return status; +} + +int TTparser::loadRequests(TTword *word) { + int status = 0; + + if (word->_tag != MKTAG('Z', 'Z', 'Z', 'T')) + addNode(word->_tag); + + switch (word->_wordClass) { + case WC_UNKNOWN: + break; + + case WC_ACTION: + if (word->_id != 0x70 && word->_id != 0x71) + addNode(1); + addNode(17); + + switch (word->_id) { + case 101: + case 110: + addNode(5); + addNode(4); + break; + + case 102: + addNode(4); + break; + + case 103: + case 111: + addNode(8); + addNode(7); + addNode(5); + addNode(4); + break; + + case 104: + case 107: + addNode(15); + addNode(5); + addNode(4); + break; + + case 106: + addNode(7); + addNode(4); + break; + + case 108: + addNode(5); + addNode(4); + addNode(23); + break; + + case 112: + case 113: + addNode(13); + addNode(5); + break; + + default: + break; + } + + if (_sentenceConcept) { + if (_sentenceConcept->get18() == 0 || _sentenceConcept->get18() == 2) { + TTaction *action = static_cast<TTaction *>(word); + _sentenceConcept->set18(action->getVal()); + } + } + break; + + case WC_THING: + if (word->checkTag() && _sentence->_field58 > 0) + _sentence->_field58--; + addNode(14); + break; + + case WC_ABSTRACT: + switch (word->_id) { + case 300: + addNode(14); + status = 1; + break; + + case 306: + addNode(23); + addNode(4); + break; + + case 307: + case 308: + addNode(23); + break; + + default: + break; + } + + if (status != 1) { + addToConceptList(word); + addNode(14); + } + break; + + case WC_ARTICLE: + addNode(2); + status = 1; + break; + + case WC_CONJUNCTION: + if (_sentence->check2C()) { + _sentenceConcept->_field1C = 1; + _sentenceConcept = _sentenceConcept->addSibling(); + delete this; + } else { + addNode(23); + } + break; + + case WC_PRONOUN: + status = fn2(word); + break; + + case WC_PREPOSITION: + switch (word->_id) { + case 700: + addNode(6); + addNode(5); + break; + case 701: + addNode(11); + break; + case 702: + status = 1; + break; + case 703: + addNode(9); + break; + case 704: + addNode(10); + break; + default: + break; + } + + case WC_ADJECTIVE: + if (word->_id == 304) { + // Nothing + } else if (word->_id == 801) { + addNode(22); + } else { + if (word->proc16()) + _sentence->_field58++; + if (word->proc17()) + _sentence->_field58++; + } + break; + + case WC_ADVERB: + switch (word->_id) { + case 900: + case 901: + case 902: + case 904: + if (_sentence->_field2C == 9) { + _sentenceConcept->_field1C = 1; + _sentenceConcept = _sentenceConcept->addSibling(); + addNode(1); + } + else { + addNode(23); + addNode(13); + addNode(1); + } + break; + + case 905: + case 907: + case 908: + case 909: + addNode(23); + break; + + case 906: + addNode(23); + status = 1; + break; + + case 910: + addNode(4); + addNode(24); + addNode(23); + addNode(14); + status = 1; + break; + + default: + break; + } + + if (word->_id == 906) { + addNode(14); + status = 1; + } + break; + + default: + break; + } + + return status; +} + +int TTparser::considerRequests(TTword *word) { + if (!_nodesP || !word) + return 0; + + TTconcept *concept = nullptr; + int status = 0; + bool flag = false; + bool modifierFlag = false; + int seekVal = 0; + + for (TTparserNode *nodeP = _nodesP; nodeP; ) { + switch (nodeP->_tag) { + case CHECK_COMMAND_FORM: + if (_sentenceConcept->_concept1P && _sentence->_field2C == 1 && + !_sentenceConcept->_concept0P) { + concept = new TTconcept(_sentence->_npcScript, ST_NPC_SCRIPT); + _sentenceConcept->_concept0P = concept; + _sentenceConcept->_field18 = 3; + } + + flag = true; + break; + + case EXPECT_THING: + if (!word->_wordClass) { + word->_wordClass = WC_THING; + addToConceptList(word); + addNode(14); + } + + flag = true; + break; + + case OBJECT_IS_TO: + flag = resetConcept(&_sentenceConcept->_concept2P, 3); + break; + + case SEEK_ACTOR: + case MKTAG('S', 'A', 'C', 'T'): + if (!_sentenceConcept->_concept0P) { + flag = filterConcepts(5, 0); + } else if (_sentenceConcept->_concept0P->compareTo("?") && + _sentenceConcept->_concept1P->isWordId(113) && + word->_wordClass == WC_THING) { + TTconcept *oldConcept = _sentenceConcept->_concept0P; + _sentenceConcept->_concept0P = nullptr; + flag = filterConcepts(5, 2); + if (flag) + delete oldConcept; + } else { + flag = true; + } + break; + + case SEEK_OBJECT: + if (_sentenceConcept->_concept2P && _sentenceConcept->_concept2P->compareTo(word)) { + flag = true; + } else if (!_sentenceConcept->_concept2P) { + if (filterConcepts(5, 2) && _sentenceConcept->_concept2P->checkWordId1()) + addNode(5); + } else if (word->_wordClass == WC_THING && _sentence->fn2(2, TTstring("?"), _sentenceConcept)) { + TTconcept *oldConcept = _sentenceConcept->_concept2P; + flag = filterConcepts(5, 2); + _sentenceConcept->_concept2P->_field20 = oldConcept->get20(); + if (flag) + delete oldConcept; + } else if (!_sentenceConcept->_concept3P && + (!_sentenceConcept->_concept1P || (_sentenceConcept->_concept1P->getWordId() && + _sentenceConcept->_concept1P->getWordId() == 112)) && + _sentenceConcept->_concept2P->checkWordId1() && + (word->_wordClass == WC_THING || word->_wordClass == WC_PRONOUN)) { + _sentenceConcept->changeConcept(0, &_sentenceConcept->_concept2P, 3); + + if (_conceptP && _conceptP->isWordId(word->_id)) { + status = _sentenceConcept->replaceConcept(0, 2, _conceptP); + removeConcept(_conceptP); + } else { + status = _sentenceConcept->createConcept(0, 2, word); + } + + if (!status && !_sentenceConcept->_concept4P && _sentenceConcept->_concept0P) { + TTconcept *oldConcept = _sentenceConcept->_concept2P; + flag = filterConcepts(5, 2); + _sentenceConcept->_concept2P->_field20 = oldConcept->get20(); + if (flag) + delete oldConcept; + } else { + flag = true; + } + } + break; + + case SEEK_OBJECT_OVERRIDE: + if ((word->_wordClass == WC_THING || word->_wordClass == WC_PRONOUN) && + _sentence->fn2(2, TTstring("thePlayer"), _sentenceConcept) && + !_sentenceConcept->_concept3P) { + _sentenceConcept->_concept3P = _sentenceConcept->_concept2P; + _sentenceConcept->_concept2P = nullptr; + + flag = filterConcepts(5, 2); + if (!flag) { + status = _sentenceConcept->createConcept(0, 2, word); + } + } + break; + + case SEEK_TO: + if (!_sentenceConcept->_concept3P) { + if (!filterConcepts(8, 3)) + flag = filterConcepts(3, 3); + } else { + flag = true; + } + break; + + case SEEK_FROM: + if (!_sentenceConcept->_concept4P) { + if (!filterConcepts(8, 4)) + flag = filterConcepts(3, 3); + } else { + flag = true; + } + break; + + case SEEK_TO_OVERRIDE: + if (word->_wordClass == WC_ACTION) { + status = _sentenceConcept->createConcept(0, 1, word); + if (!status) { + seekVal = _sentenceConcept->_field18; + _sentenceConcept->_field18 = 4; + flag = true; + } + } else if (word->_id == 703) { + if (_sentenceConcept->_concept2P) { + delete _sentenceConcept->_concept2P; + _sentenceConcept->_concept2P = nullptr; + } + + if (_sentenceConcept->_concept4P || !_sentenceConcept->_concept0P) { + addNode(7); + } else { + _sentenceConcept->changeConcept(1, &_sentenceConcept->_concept0P, 4); + concept = nullptr; + addNode(7); + } + } else { + flag = true; + } + break; + + case SEEK_FROM_OVERRIDE: + if (_sentenceConcept->_concept4P) { + delete _sentenceConcept->_concept4P; + _sentenceConcept->_concept4P = nullptr; + } + + addNode(8); + flag = true; + break; + + case SEEK_LOCATION: + addNode(5); + _sentenceConcept->createConcept(0, 5, word); + flag = true; + break; + + case SEEK_OWNERSHIP: + if (word->_id == 601) { + if (_conceptP->findByWordClass(WC_THING)) + status = _conceptP->setOwner(word, false); + + flag = true; + } + break; + + case SEEK_STATE: + if (_sentenceConcept->_concept5P) { + if (_sentenceConcept->_concept5P->findByWordId(306) || + _sentenceConcept->_concept5P->findByWordId(904)) { + TTconcept *oldConcept = _sentenceConcept->_concept5P; + _sentenceConcept->_concept5P = nullptr; + flag = filterConcepts(9, 5); + if (flag) + delete oldConcept; + } else { + flag = true; + } + } else { + flag = filterConcepts(9, 5); + if (!flag && word->_wordClass == WC_ADVERB) { + status = _sentenceConcept->createConcept(1, 5, word); + flag = true; + } + } + break; + + case SEEK_MODIFIERS: + if (!modifierFlag) { + bool tempFlag = false; + + switch (word->_wordClass) { + case WC_ACTION: + status = processModifiers(1, word); + break; + case WC_THING: + status = processModifiers(2, word); + break; + case WC_ABSTRACT: + if (word->_id != 300) { + status = processModifiers(3, word); + } else if (!_conceptP->findByWordClass(WC_THING)) { + status = processModifiers(3, word); + } else { + word->_id = atoi(word->_text.c_str()); + } + break; + case WC_PRONOUN: + if (word->_id != 602) + addToConceptList(word); + break; + case WC_ADJECTIVE: { + TTconcept *conceptP = _conceptP->findByWordClass(WC_THING); + if (conceptP) { + conceptP->_string2 += ' '; + conceptP->_string2 += word->getText(); + } else { + status = processModifiers(8, word); + } + break; + } + case WC_ADVERB: + if (word->_id == 906) { + for (TTconcept *currP = _conceptP; currP; currP = currP->_nextP) { + if (_sentence->isFrameSlotClass(1, WC_ACTION) || + _sentence->isFrameSlotClass(1, WC_THING)) + currP->_field34 = 1; + } + } else { + TTconcept *conceptP = _conceptP->findByWordClass(WC_ACTION); + + if (conceptP) { + conceptP->_string2 += ' '; + conceptP->_string2 += word->getText(); + } else { + tempFlag = true; + } + } + break; + default: + addToConceptList(word); + status = 0; + break; + } + + if (tempFlag) + status = _sentenceConcept->createConcept(1, 5, word); + + modifierFlag = true; + flag = true; + } + break; + + case SEEK_NEW_FRAME: + if (word->_wordClass == WC_ACTION && word->_id != 104 && word->_id != 107) { + if (concept && (_sentenceConcept->_concept5P || _sentenceConcept->_concept2P)) { + TTsentenceConcept *oldNode = _sentenceConcept; + oldNode->_field1C = 2; + _sentenceConcept = oldNode->addSibling(); + concept = nullptr; + + _sentenceConcept->_concept1P = oldNode->_concept1P; + _sentenceConcept->_concept5P = oldNode->_concept5P; + _sentenceConcept->_concept2P = oldNode->_concept2P; + + if (seekVal) { + seekVal = 0; + + _sentenceConcept->_field18 = oldNode->_field18; + oldNode->_field18 = seekVal; + } + } + + flag = true; + } + break; + + case SEEK_STATE_OBJECT: + if (!_sentenceConcept->_concept5P) { + addToConceptList(word); + } else if (_sentenceConcept->concept5WordId() == 113 || + _sentenceConcept->concept5WordId() == 112) { + _sentenceConcept->createConcept(1, 2, word); + } else { + addToConceptList(word); + } + + flag = true; + break; + + case SET_ACTION: + if (_sentence->fn4(1, 104, _sentenceConcept) || + _sentence->fn4(1, 107, _sentenceConcept)) { + concept = _sentenceConcept->_concept1P; + _sentenceConcept->_concept1P = nullptr; + addNode(15); + } + + if (_sentence->check2C() && word->_id == 113) + addNode(4); + + if (word->_wordClass == WC_ACTION) + _sentenceConcept->createConcept(0, 1, word); + + flag = true; + break; + + case ACTOR_IS_TO: + _sentenceConcept->changeConcept(1, &_sentenceConcept->_concept0P, 3); + flag = true; + break; + + case ACTOR_IS_FROM: + _sentenceConcept->changeConcept(1, &_sentenceConcept->_concept0P, 4); + break; + + case ACTOR_IS_OBJECT: + flag = resetConcept(&_sentenceConcept->_concept0P, 2); + break; + + case WORD_TYPE_IS_SENTENCE_TYPE: + if (_sentence->_field2C == 1 || _sentence->_field2C == 10) { + for (TTword *wordP = _currentWordP; wordP; wordP = wordP->_nextP) { + if (wordP->_id == 906) { + _sentence->_field2C = 12; + flag = true; + break; + } + } + + TTpicture *newPictP; + TTconcept *newConceptP; + switch (word->_id) { + case 108: + _sentence->_field2C = 8; + break; + case 113: + if (!_sentenceConcept->_concept3P) + _sentence->_field2C = 22; + break; + case 304: + _sentence->_field2C = 25; + break; + case 305: + _sentence->_field2C = 24; + break; + case 306: + _sentence->_field2C = 7; + break; + case 501: + _sentence->_field2C = 9; + break; + case 900: + _sentence->_field2C = 5; + break; + case 901: + _sentence->_field2C = 4; + break; + case 904: + _sentence->_field2C = 6; + break; + case 905: + _sentence->_field2C = 11; + break; + case 906: + _sentence->_field2C = 12; + break; + case 907: + _sentence->_field2C = 13; + break; + case 908: + _sentence->_field2C = 2; + if (!_sentenceConcept->_concept0P) { + newPictP = new TTpicture(TTstring("?"), WC_THING, 0, 0, 0, 0, 0); + newConceptP = new TTconcept(newPictP); + + _sentenceConcept->_concept0P = newConceptP; + delete newPictP; + addNode(4); + } + break; + case 909: + _sentence->_field2C = 3; + newPictP = new TTpicture(TTstring("?"), WC_THING, 0, 0, 0, 0, 0); + newConceptP = new TTconcept(newPictP); + + _sentenceConcept->_concept2P = newConceptP; + delete newPictP; + addNode(4); + break; + + default: + break; + } + } + + flag = true; + break; + + case COMPLEX_VERB: + if (word->_wordClass == WC_ACTION) { + flag = true; + } else if (!_sentenceConcept->_concept1P) { + TTstring wordStr = word->getText(); + if (wordStr == "do" || wordStr == "doing" || wordStr == "does" || wordStr == "done") { + TTaction *verbP = new TTaction(TTstring("do"), WC_ACTION, 112, 0, + _sentenceConcept->get18()); + status = _sentenceConcept->createConcept(1, 1, verbP); + delete verbP; + } + + flag = true; + } + break; + + case MKTAG('C', 'O', 'M', 'E'): + addNode(7); + addNode(5); + addNode(21); + + if (!_sentence->_field2C) + _sentence->_field2C = 15; + break; + + case MKTAG('C', 'U', 'R', 'S'): + case MKTAG('S', 'E', 'X', 'X'): + if (_sentence->_field58 > 1) + _sentence->_field58--; + flag = true; + break; + + case MKTAG('E', 'X', 'I', 'T'): + addNode(8); + addNode(5); + addNode(21); + + if (!_sentence->_field2C) + _sentence->_field2C = 14; + break; + + case MKTAG('F', 'A', 'R', 'R'): + if (_conceptP->findBy20(0)) + _conceptP->_field20 = 2; + break; + + case MKTAG('F', 'U', 'T', 'R'): + _sentenceConcept->_field18 = 3; + break; + + case MKTAG('G', 'O', 'G', 'O'): + addNode(7); + addNode(5); + addNode(21); + + if (_sentence->_field2C == 1) + _sentence->_field2C = 14; + + flag = true; + break; + + case MKTAG('H', 'E', 'L', 'P'): + if (_sentence->_field2C == 1) + _sentence->_field2C = 18; + + flag = true; + break; + + case MKTAG('L', 'O', 'C', 'F'): + status = _sentenceConcept->createConcept(1, 5, word); + if (!status) + _sentenceConcept->_concept5P->_field20 = 2; + + flag = true; + break; + + case MKTAG('L', 'O', 'C', 'N'): + status = _sentenceConcept->createConcept(1, 5, word); + if (!status) + _sentenceConcept->_concept5P->_field20 = 1; + + flag = true; + break; + + case MKTAG('N', 'E', 'A', 'R'): + if (_conceptP->findBy20(0)) { + _conceptP->_field20 = 1; + } else { + TTpicture *newPictP = new TTpicture(TTstring("?"), WC_THING, 0, 0, 0, 0, 0); + status = addToConceptList(newPictP); + _conceptP->_field20 = 1; + if (!status) + delete newPictP; + } + + flag = true; + break; + + case MKTAG('P', 'A', 'S', 'T'): + _sentenceConcept->_field18 = 1; + flag = true; + break; + + case MKTAG('P', 'L', 'E', 'Z'): + if (_sentence->_field58 < 10) + _sentence->_field58++; + break; + + case MKTAG('P', 'R', 'E', 'Z'): + _sentenceConcept->_field18 = 2; + flag = true; + break; + + case MKTAG('S', 'A', 'A', 'O'): + addNode(5); + addNode(4); + flag = true; + break; + + case MKTAG('S', 'S', 'T', 'A'): + addNode(13); + addNode(5); + flag = true; + break; + + case MKTAG('T', 'E', 'A', 'C'): + if (_sentence->_field2C == 1) + _sentence->_field2C = 10; + + flag = true; + break; + + case MKTAG('V', 'O', 'B', 'J'): + status = _sentenceConcept->createConcept(1, 2, word); + flag = true; + break; + + default: + flag = true; + break; + } + + TTparserNode *nextP = static_cast<TTparserNode *>(nodeP->_nextP); + if (flag) + delete nodeP; + nodeP = nextP; + } + + delete concept; + return status; +} + +int TTparser::processRequests(TTword *word) { + int status = loadRequests(word); + switch (status) { + case 0: + status = considerRequests(word); + + // Iterate through the words + while (_currentWordP) { + considerRequests(_currentWordP); + TTword *nextP = _currentWordP->_nextP; + + delete _currentWordP; + _currentWordP = nextP; + } + break; + + case 1: { + TTword *newWord = new TTword(word); + newWord->_nextP = nullptr; + + // Add word to word chain + if (_currentWordP) { + // Add at end of existing chain + for (word = _currentWordP; word->_nextP; word = word->_nextP) + ; + word->_nextP = newWord; + } else { + // First word, so set as head + _currentWordP = newWord; + } + break; + } + + default: + warning("unexpected return from consider requests"); + break; + } + + return status; +} + +int TTparser::addToConceptList(TTword *word) { + TTconcept *concept = new TTconcept(word, ST_UNKNOWN_SCRIPT); + addConcept(concept); + return 0; +} + +void TTparser::addNode(uint tag) { + TTparserNode *newNode = new TTparserNode(tag); + if (_nodesP) + _nodesP->addToHead(newNode); + _nodesP = newNode; +} + +int TTparser::addConcept(TTconcept *concept) { + if (!concept) + return SS_5; + + if (_conceptP) + concept->_nextP = _conceptP; + _conceptP = concept; + + return SS_VALID; +} + +void TTparser::removeConcept(TTconcept *concept) { + // If no concept passed, exit immediately + if (!concept) + return; + + if (_conceptP == concept) { + // Concept specified is the ver ystart of the linked list, so reset head pointer + _conceptP = _conceptP->_nextP; + } else { + // Scan through the linked list, looking for the specific concept + for (TTconcept *currP = _conceptP; currP; currP = currP->_nextP) { + if (currP->_nextP == concept) { + // Found match, so unlink the next link from the chain + currP->_nextP = currP->_nextP->_nextP; + break; + } + } + } + + // FInally, delete the concept + concept->_nextP = nullptr; + delete concept; +} + +void TTparser::removeNode(TTparserNode *node) { + if (!node->_priorP) + // Node is the head of the chain, so reset parser's nodes pointer + _nodesP = static_cast<TTparserNode *>(node->_nextP); + + delete node; +} + +int TTparser::checkForAction() { + int status = SS_VALID; + bool flag = false; + bool actionFlag = false; + + if (_conceptP && _currentWordP) { + // Firstly we need to get the next word to process, and remove it from + // the list pointed to by _currentWordP + TTword *word = _currentWordP; + if (word->_nextP) { + // Chain of words, so we need to find the last word of the chain, + // and set the last-but-one's _nextP to nullptr to detach the last one + TTword *prior = nullptr; + for (word = word->_nextP; word->_nextP; word = word->_nextP) { + prior = word; + } + + if (prior) + prior->_nextP = nullptr; + } else { + // No chain, so singular word can simply be removed + _currentWordP = nullptr; + if (word->_id == 906 && _sentence->_field2C == 1) + _sentence->_field2C = 12; + } + + if (word->_text == "do" || word->_text == "doing" || word->_text == "does" || + word->_text == "done") { + TTstring doStr("do"); + TTaction *action = new TTaction(doStr, WC_ACTION, 112, 0, _sentenceConcept->get18()); + + if (!action->isValid()) { + status = SS_4; + } else { + // Have the new action replace the old word instance + delete word; + word = action; + actionFlag = true; + } + } + + addToConceptList(word); + delete word; + flag = true; + } + + // Handle any remaining words + while (_currentWordP) { + int result = considerRequests(_currentWordP); + if (result > 1) { + status = result; + } else { + // Delete the top of the word chain + TTword *wordP = _currentWordP; + _currentWordP = _currentWordP->_nextP; + delete wordP; + } + } + + if (flag && _conceptP) { + if (actionFlag && (!_sentenceConcept->_concept1P || _sentenceConcept->_concept1P->isWordId(113))) { + _sentenceConcept->replaceConcept(0, 1, _conceptP); + } else if (!_sentenceConcept->_concept5P) { + _sentenceConcept->replaceConcept(1, 5, _conceptP); + } else if (_sentenceConcept->_concept5P->isWordId(904)) { + _sentenceConcept->replaceConcept(0, 5, _conceptP); + } + + removeConcept(_conceptP); + } + + if (_sentence->fn2(3, TTstring("thePlayer"), _sentenceConcept) && !flag) { + if (_sentenceConcept->concept1WordId() == 101) { + _sentence->_field2C = 16; + } else if (_sentence->_field2C != 18 && _sentenceConcept->concept1WordId() == 102) { + if (_sentence->fn2(0, TTstring("targetNpc"), _sentenceConcept)) + _sentence->_field2C = 15; + } + } + + if (_sentence->fn2(2, TTstring("thePlayer"), _sentenceConcept) && + _sentenceConcept->concept1WordId() == 101 && flag) + _sentence->_field2C = 17; + + if (!_sentenceConcept->_concept0P && !_sentenceConcept->_concept1P && + !_sentenceConcept->_concept2P && !_sentenceConcept->_concept5P && !flag) { + if (_conceptP) + filterConcepts(5, 2); + + if (!_sentenceConcept->_concept2P && _sentence->_field2C == 1) + _sentence->_field2C = 0; + } + + if (_sentence->_field58 < 5 && _sentence->_field2C == 1 && !flag) + _sentence->_field2C = 19; + + for (TTconceptNode *nodeP = &_sentence->_sentenceConcept; nodeP; nodeP = nodeP->_nextP) { + if (nodeP->_field18 == 0 && nodeP->_concept1P) { + nodeP->_field18 = _sentence->concept18(nodeP); + } else if (nodeP->_field18 == 4 && !_sentenceConcept->_concept0P) { + if (_sentenceConcept->_concept3P) { + _sentenceConcept->_concept0P = _sentenceConcept->_concept3P; + _sentenceConcept->_concept3P = nullptr; + } else if (_sentenceConcept->_concept2P) { + _sentenceConcept->_concept0P = _sentenceConcept->_concept2P; + _sentenceConcept->_concept2P = nullptr; + } + } + } + + if (_sentence->_field2C == 1 && _sentenceConcept->_concept5P && + _sentenceConcept->_concept2P) { + if (_sentence->fn4(1, 113, nullptr)) { + if (_sentence->fn2(2, TTstring("targetNpc"), nullptr)) { + _sentence->_field2C = 20; + } else if (_sentence->fn2(2, TTstring("thePlayer"), nullptr)) { + _sentence->_field2C = 21; + } else { + _sentence->_field2C = 22; + } + } + } else if (!_sentenceConcept->_concept0P && !_sentenceConcept->_concept1P && + !_sentenceConcept->_concept2P && !_sentenceConcept->_concept5P) { + if (_conceptP) + filterConcepts(5, 2); + + if (!_sentenceConcept->_concept2P && _sentence->_field2C == 1) + _sentence->_field2C = 0; + } + + return status; +} + +int TTparser::fn2(TTword *word) { + switch (word->_id) { + case 600: + addNode(13); + return 0; + + case 601: + addNode(12); + return 1; + + case 602: + case 607: + return checkReferent(static_cast<TTpronoun *>(word)); + + case 608: + return 1; + + default: + return 0; + } +} + +int TTparser::checkReferent(TTpronoun *pronoun) { + TTconcept *concept; + + switch (pronoun->getVal()) { + case 0: + return 0; + + case 1: + concept = new TTconcept(_owner->_script, ST_ROOM_SCRIPT); + break; + + case 2: + concept = new TTconcept(_sentence->_npcScript, ST_NPC_SCRIPT); + break; + + default: + concept = new TTconcept(pronoun, (ScriptType)pronoun->getVal()); + break; + } + + addConcept(concept); + return 0; +} + +void TTparser::conceptChanged(TTconcept *newConcept, TTconcept *oldConcept) { + if (!oldConcept && newConcept != _currentConceptP) + _currentConceptP = nullptr; + else if (oldConcept && oldConcept == _currentConceptP) + _currentConceptP = newConcept; +} + +bool TTparser::checkConcept2(TTconcept *concept, int conceptMode) { + switch (conceptMode) { + case 3: + return concept->checkWordId2(); + + case 5: + return concept->checkWordClass(); + + case 8: + return concept->checkWordId1(); + + case 9: + if (!concept->checkWordId3() && _sentenceConcept->_concept2P) { + if (!_sentenceConcept->_concept2P->checkWordId2() || !concept->checkWordId2()) { + return _sentenceConcept->_concept2P->checkWordClass() && + concept->checkWordClass(); + } + } + break; + + default: + break; + } + + return false; +} + +int TTparser::filterConcepts(int conceptMode, int conceptIndex) { + int result = 0; + + for (TTconcept *currP = _conceptP; currP && !result; currP = currP->_nextP) { + if (checkConcept2(currP, conceptMode)) { + TTconcept **ptrPP = _sentenceConcept->setConcept(conceptIndex, currP); + TTconcept *newConcept = new TTconcept(*currP); + *ptrPP = newConcept; + + if (newConcept->isValid()) { + removeConcept(currP); + (*ptrPP)->_nextP = nullptr; + result = 1; + } else { + result = -2; + } + } + } + + return result; +} + +bool TTparser::resetConcept(TTconcept **conceptPP, int conceptIndex) { + TTconcept **ptrPP = _sentenceConcept->setConcept(conceptIndex, nullptr); + + if (!*ptrPP) + return 0; + + int result = _sentenceConcept->changeConcept(1, conceptPP, conceptIndex); + if (*conceptPP) + _sentenceConcept->setConcept(conceptIndex, *conceptPP); + + return !result; +} + +int TTparser::processModifiers(int modifier, TTword *word) { + TTconcept *newConcept = new TTconcept(word, ST_UNKNOWN_SCRIPT); + + // Cycles through each word + for (TTword *currP = _currentWordP; currP != word; currP = _currentWordP) { + if ((modifier == 2 && currP->_wordClass == WC_ADJECTIVE) || + (modifier == 1 && currP->_wordClass == WC_ADVERB)) { + newConcept->_string2 += ' '; + newConcept->_string2 += _currentWordP->getText(); + } else if (word->_id == 113 && currP->_wordClass == WC_ADJECTIVE) { + addToConceptList(currP); + addNode(13); + } + + if (modifier == 2 || modifier == 3) { + switch (_currentWordP->_id) { + case 94: + _currentConceptP->setOwner(newConcept); + if (_currentWordP) { + _currentWordP->deleteSiblings(); + delete _currentWordP; + _currentWordP = nullptr; + } + + delete newConcept; + newConcept = nullptr; + break; + + case 204: + newConcept->_field34 = 1; + if (_sentence->_field2C == 1) + _sentence->_field2C = 12; + newConcept->_field14 = 1; + break; + + case 300: + newConcept->set1C(atoi(_currentWordP->_text.c_str())); + break; + + case 400: + newConcept->_field14 = 2; + break; + + case 401: + newConcept->_field14 = 1; + break; + + case 601: + newConcept->setOwner(_currentWordP, false); + break; + + case 608: + if (_currentWordP->comparePronounTo(10)) { + newConcept->_field20 = 1; + } else if (_currentWordP->comparePronounTo(11)) { + newConcept->_field20 = 2; + } + + default: + break; + } + } + + if (_currentWordP) { + // Detaches word and deletes it + TTword *wordP = _currentWordP; + _currentWordP = wordP->_nextP; + + wordP->_nextP = nullptr; + delete wordP; + } + } + + if (newConcept) { + newConcept->setFlag(true); + _currentConceptP = newConcept; + addConcept(newConcept); + } + + return 0; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_parser.h b/engines/titanic/true_talk/tt_parser.h new file mode 100644 index 0000000000..201de7eb0e --- /dev/null +++ b/engines/titanic/true_talk/tt_parser.h @@ -0,0 +1,208 @@ +/* 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 TITANIC_TT_PARSER_H +#define TITANIC_TT_PARSER_H + +#include "titanic/true_talk/tt_node.h" +#include "titanic/true_talk/tt_pronoun.h" +#include "titanic/true_talk/tt_sentence.h" +#include "titanic/true_talk/tt_string.h" + +namespace Titanic { + +enum NumberFlag { NF_1 = 1, NF_2 = 2, NF_4 = 4, NF_8 = 8, NF_10 = 0x10 }; + +enum ParserAction { + NO_ACTION = 0, CHECK_COMMAND_FORM, EXPECT_THING, OBJECT_IS_TO, + SEEK_ACTOR, SEEK_OBJECT, SEEK_OBJECT_OVERRIDE, SEEK_TO, + SEEK_FROM, SEEK_TO_OVERRIDE, SEEK_FROM_OVERRIDE, SEEK_LOCATION, + SEEK_OWNERSHIP, SEEK_STATE, SEEK_MODIFIERS, SEEK_NEW_FRAME, + SEEK_STATE_OBJECT, SET_ACTION, SET_COLOR, ACTOR_IS_TO, + ACTOR_IS_FROM, ACTOR_IS_OBJECT, STATE_IDENTITY, + WORD_TYPE_IS_SENTENCE_TYPE, COMPLEX_VERB +}; + +class CScriptHandler; +class TTconcept; + +struct NumberEntry { + CString _text; + int _value; + int _flags; + + NumberEntry() : _value(0), _flags(0) {} + NumberEntry(const CString &text, int value, int flags) : + _text(text), _value(value), _flags(flags) {} +}; +typedef Common::Array<NumberEntry> NumberArray; + +class TTparserNode : public TTnode { +public: + uint _tag; +public: + TTparserNode() : TTnode(), _tag(0) {} + TTparserNode(uint tag) : TTnode(), _tag(tag) {} +}; + +class TTparser { +private: + StringArray _replacements1; + StringArray _replacements2; + StringArray _replacements3; + StringArray _phrases; + NumberArray _numbers; + TTparserNode *_nodesP; + TTconcept *_conceptP; + TTconcept *_currentConceptP; +private: + /** + * Load the data for a given array resource + */ + void loadArray(StringArray &arr, const CString &name); + + /** + * Loads the various replacement string data arrays + */ + void loadArrays(); + + /** + * Normalizes a passed input, taking care of things like removing extra + * spaces and lowercasing everything + */ + int normalize(TTsentence *sentence); + + /** + * Submethod called by normalize to handle expanding contacted word pairs + * like can't, should've, and so on. + */ + bool normalizeContraction(const TTstring &srcLine, int srcIndex, TTstring &destLine); + + /** + * Checks for what is likely special developer cheat codes + */ + static int isEmoticon(const TTstring &str, int &index); + + /** + * Checks if any word within a passed line has an entry in the list of replacements, + * and if found, replaces it with it's equivalent replacement string + * @param line Line to check + * @param strings List of strings to check for. Strings come in pairs, with the + * first being the string to match, and the second the replacement + */ + static void searchAndReplace(TTstring &line, const StringArray &strings); + + /** + * Checks the string starting at a given index for any word in the passed string array, + * and if found, replaces it in the line with it's replacement + * @param line Line to check + * @param startIndex Starting index in the start to check + * @param strings List of strings to check for. Strings come in pairs, with the + * first being the string to match, and the second the replacement + * @returns Index of the start of the following word + */ + static int searchAndReplace(TTstring &line, int startIndex, const StringArray &strings); + + /** + * Checks the string starting at a given index for a number representation + * such as roman numericals, spelled out numbers, etc. and replaces it with + * a plain decimal representation. + * @param line Line to check + * @param startIndex Starting index in the start to check + * @returns Index of the start of the following word, or -1 if at end of line + */ + int replaceNumbers(TTstring &line, int startIndex); + + /** + * Checks the string starting at a given index for a number representation + * such as roman numericals, spelled out numbers, etc. and replaces it with + * a plain decimal representation. + * @param line Line to check + * @param startIndex Starting index in the start to check + * @returns Pointer to matching number entry, if match occurred + */ + const NumberEntry *replaceNumbers2(TTstring &line, int *startIndex); + + int loadRequests(TTword *word); + int considerRequests(TTword *word); + int processRequests(TTword *word); + + int addToConceptList(TTword *word); + int checkReferent(TTpronoun *pronoun); + + /** + * Creates a new parser node, and adds it to the parser's list + */ + void addNode(uint tag); + + /** + * Add a concept node + */ + int addConcept(TTconcept *concept); + + /** + * Detaches a concept from the main concept list if prseent, then deletes it + */ + void removeConcept(TTconcept *concept); + + /** + * Detaches a node from the main node list + */ + void removeNode(TTparserNode *node); + + int processModifiers(int modifier, TTword *word); + + int checkForAction(); + int fn2(TTword *word); + bool checkConcept2(TTconcept *concept, int conceptMode); + int filterConcepts(int conceptMode, int conceptIndex); + bool resetConcept(TTconcept **conceptPP, int conceptIndex); +public: + CScriptHandler *_owner; + TTsentenceConcept *_sentenceConcept; + TTsentence *_sentence; + int _fieldC; + int _field10; + int _field14; + TTword *_currentWordP; + StringArray _pronouns; +public: + TTparser(CScriptHandler *owner); + ~TTparser(); + + /** + * Preprocesses the passed input text, to handle things like lowercasing + * all the words, and replcaing common slang with their full equivalents + */ + int preprocess(TTsentence *sentence); + + int findFrames(TTsentence *sentence); + + /** + * Called when a concept is copied from one to another + */ + void conceptChanged(TTconcept *newConcept, TTconcept *oldConcept); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_PARSER_H */ diff --git a/engines/titanic/true_talk/tt_picture.cpp b/engines/titanic/true_talk/tt_picture.cpp new file mode 100644 index 0000000000..4b04b8825b --- /dev/null +++ b/engines/titanic/true_talk/tt_picture.cpp @@ -0,0 +1,102 @@ +/* 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 "titanic/true_talk/tt_picture.h" + +namespace Titanic { + +bool TTpicture::_staticFlag; + +TTpicture::TTpicture(const TTstring &str, WordClass wordClass, int val2, int val3, int val4, int val5, int val6) : + TTmajorWord(str, wordClass, val2, val4), _tag(val3), _field30(val5), _field3C(val6), + _field38(0) { +} + +TTpicture::TTpicture(const TTpicture *src) : TTmajorWord(src) { + if (getStatus()) { + _tag = 0; + _field30 = 0; + _field38 = 0; + _field3C = 0; + _status = SS_5; + } else { + _tag = src->_tag; + _field30 = src->_field30; + _field38 = src->_field38; + _field3C = src->_field3C; + } +} + +int TTpicture::load(SimpleFile *file) { + CString str; + int val1, val2; + + if (!TTword::load(file, WC_THING) && file->scanf("%s %d %d", &str, &val1, &val2)) { + _tag = readNumber(str.c_str()); + _field30 = val1; + _field3C = val2; + return 0; + } else { + return 3; + } +} + +TTword *TTpicture::copy() const { + TTpicture *returnWordP = new TTpicture(this); + returnWordP->_status = _status; + if (!_status) { + _staticFlag = false; + return returnWordP; + } else if (_status == SS_13 && !_staticFlag) { + _staticFlag = true; + delete returnWordP; + return copy(); + } else { + delete returnWordP; + return nullptr; + } +} + +bool TTpicture::checkTag() const { + return _tag == MKTAG('S', 'E', 'X', 'X') || + _tag == MKTAG('E', 'X', 'C', 'R') || + _tag == MKTAG('P', 'P', 'R', 'T') || + _tag == MKTAG('B', 'L', 'A', 'S'); +} + +bool TTpicture::compareTagTo(uint tag) const { + return _tag == tag; +} + +uint TTpicture::getTag() const { + return _tag; +} + +bool TTpicture::proc9(int val) const { + return _field3C == val; +} + +int TTpicture::proc10() const { + return _field3C; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_picture.h b/engines/titanic/true_talk/tt_picture.h new file mode 100644 index 0000000000..18cb88278f --- /dev/null +++ b/engines/titanic/true_talk/tt_picture.h @@ -0,0 +1,74 @@ +/* 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 TITANIC_TT_PICTURE_H +#define TITANIC_TT_PICTURE_H + +#include "titanic/true_talk/tt_major_word.h" + +namespace Titanic { + +class TTpicture : public TTmajorWord { +private: + static bool _staticFlag; +protected: + int _field30; + uint _tag; + int _field38; + int _field3C; +public: + TTpicture(const TTstring &str, WordClass wordClass, int val2, int val3, int val4, int val5, int val6); + TTpicture(const TTpicture *src); + + /** + * Load the word + */ + int load(SimpleFile *file); + + /** + * Creates a copy of the word + */ + virtual TTword *copy() const; + + /** + * Checks whether the word's tag is a known type + */ + virtual bool checkTag() const; + + /** + * Compare the word's tag to a given tag value + */ + virtual bool compareTagTo(uint tag) const; + + /** + * Return the tag associated with the word + */ + virtual uint getTag() const; + + virtual bool proc9(int val) const; + virtual int proc10() const; + +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_PICTURE_H */ diff --git a/engines/titanic/true_talk/tt_pronoun.cpp b/engines/titanic/true_talk/tt_pronoun.cpp new file mode 100644 index 0000000000..3ef48314e6 --- /dev/null +++ b/engines/titanic/true_talk/tt_pronoun.cpp @@ -0,0 +1,73 @@ +/* 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 "titanic/true_talk/tt_pronoun.h" + +namespace Titanic { + +bool TTpronoun::_staticFlag; + +TTpronoun::TTpronoun(TTstring &str, WordClass wordClass, int val2, int val3, int val4) : + TTmajorWord(str, wordClass, val2, val3), _field30(val4) { +} + +TTpronoun::TTpronoun(const TTpronoun *src) : TTmajorWord(src) { + if (src->getStatus()) { + _field30 = 0; + _status = SS_5; + } else { + _field30 = src->_field30; + } +} + +int TTpronoun::load(SimpleFile *file) { + int val; + + if (!TTword::load(file, WC_PRONOUN) && file->scanf("%d", &val)) { + if (val >= 0 && val <= 12) { + _field30 = val; + return 0; + } else { + return 5; + } + } else { + return 8; + } +} + +TTword *TTpronoun::copy() const { + TTpronoun *returnWordP = new TTpronoun(this); + returnWordP->_status = _status; + if (!_status) { + _staticFlag = false; + return returnWordP; + } else if (_status == SS_13 && !_staticFlag) { + _staticFlag = true; + delete returnWordP; + return copy(); + } else { + delete returnWordP; + return nullptr; + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_pronoun.h b/engines/titanic/true_talk/tt_pronoun.h new file mode 100644 index 0000000000..ccc077152c --- /dev/null +++ b/engines/titanic/true_talk/tt_pronoun.h @@ -0,0 +1,65 @@ +/* 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 TITANIC_TT_PRONOUN_H +#define TITANIC_TT_PRONOUN_H + +#include "titanic/true_talk/tt_major_word.h" + +namespace Titanic { + +class TTpronoun : public TTmajorWord { +private: + static bool _staticFlag; +protected: + int _field30; +public: + TTpronoun(TTstring &str, WordClass wordClass, int val2, int val3, int val4); + TTpronoun(const TTpronoun *src); + + /** + * Load the word + */ + int load(SimpleFile *file); + + int getVal() const { return _field30; } + + /** + * Creates a copy of the word + */ + virtual TTword *copy() const; + + virtual bool comparePronounTo(int val) const { + return _field30 == val; + } + + /** + * Dumps data associated with the word to file + */ + virtual int save(SimpleFile *file) const { + return saveData(file, _field30); + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_WORD_H */ diff --git a/engines/titanic/true_talk/tt_quotes.cpp b/engines/titanic/true_talk/tt_quotes.cpp new file mode 100644 index 0000000000..c690ac8780 --- /dev/null +++ b/engines/titanic/true_talk/tt_quotes.cpp @@ -0,0 +1,145 @@ +/* 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/algorithm.h" +#include "titanic/true_talk/tt_quotes.h" +#include "titanic/titanic.h" + +namespace Titanic { + +TTquotes::TTquotes() : _loaded(false), _dataP(nullptr), _dataSize(0), + _field544(0) { + Common::fill(&_tags[0], &_tags[256], 0); +} + +TTquotes::~TTquotes() { + delete[] _dataP; +} + +void TTquotes::load() { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource("TEXT/JRQUOTES.TXT"); + size_t size = r->readUint32LE(); + _loaded = true; + + _dataSize = _field544 = size; + _dataP = new char[size + 0x10]; + + for (int idx = 0; idx < 256; ++idx) + _tags[idx] = r->readUint32LE(); + + for (int charIdx = 0; charIdx < 26; ++charIdx) { + TTquotesLetter &letter = _alphabet[charIdx]; + int count = r->readUint32LE(); + + // Load the list of entries for the given letter + letter._entries.resize(count); + for (int idx = 0; idx < count; ++idx) { + letter._entries[idx]._tagIndex = r->readByte(); + letter._entries[idx]._maxSize = r->readByte(); + letter._entries[idx]._strP = _dataP + r->readUint32LE(); + } + } + + // Read in buffer and then decode it + r->read((byte *)_dataP, _dataSize); + for (size_t idx = 0; idx < _dataSize; idx += 4) + WRITE_LE_UINT32((byte *)_dataP + idx, READ_LE_UINT32((const byte *)_dataP + idx) ^ 0xA55A5AA5); + + delete r; +} + +int TTquotes::find(const char *str) const { + if (!str || !*str) + return 0; + + // Find start and end of string + const char *startP = str, *endP = str; + while (*endP) + ++endP; + + do { + int tagId = find(startP, endP); + if (tagId) + return tagId; + + // Move to next following space or end of string + while (*startP && *startP != ' ') + ++startP; + // If it's a space, then move past it to start of next word + while (*startP && *startP == ' ') + ++startP; + + } while (*startP); + + // No match + return 0; +} + +int TTquotes::find(const char *startP, const char *endP) const { + int size = endP - startP; + if (size < 3) + return 0; + + uint index = MIN((uint)(*startP - 'a'), (uint)25); + const TTquotesLetter &letter = _alphabet[index]; + if (letter._entries.empty()) + // No entries for the letter, so exit immediately + return 0; + + int maxSize = size + 4; + + for (uint idx = 0; idx < letter._entries.size(); ++idx) { + const TTquotesEntry &entry = letter._entries[idx]; + if (entry._maxSize > maxSize) + continue; + + const char *srcP = startP; + const char *destP = entry._strP; + int srcIndex = index != 25 ? 1 : 0, destIndex = 0; + if (*destP) { + do { + if (!srcP[srcIndex]) { + break; + } else if (srcP[srcIndex] == '*') { + ++srcIndex; + } else if (destP[destIndex] == '-') { + ++destIndex; + if (srcP[srcIndex] == ' ') + ++srcIndex; + } else if (srcP[srcIndex] != destP[destIndex]) { + break; + } else { + ++destIndex; + ++srcIndex; + } + } while (destP[destIndex]); + + if (!destP[destIndex] && (srcP[srcIndex] <= '*' || + (srcP[srcIndex] == 's' && srcP[srcIndex + 1] <= '*'))) + return _tags[entry._tagIndex]; + } + } + + return 0; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_quotes.h b/engines/titanic/true_talk/tt_quotes.h new file mode 100644 index 0000000000..5958c9ebcf --- /dev/null +++ b/engines/titanic/true_talk/tt_quotes.h @@ -0,0 +1,77 @@ +/* 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 TITANIC_TT_QUOTES_H +#define TITANIC_TT_QUOTES_H + +#include "common/scummsys.h" +#include "common/stream.h" +#include "titanic/support/string.h" + +namespace Titanic { + +class TTquotes { + struct TTquotesEntry { + byte _tagIndex, _maxSize; + const char *_strP; + TTquotesEntry() : _tagIndex(0), _maxSize(0), _strP(nullptr) {} + }; + struct TTquotesLetter { + Common::Array<TTquotesEntry> _entries; + int _field4; + int _field8; + + TTquotesLetter() : _field4(0), _field8(0) {} + }; +private: + TTquotesLetter _alphabet[26]; + uint _tags[256]; + char *_dataP; + size_t _dataSize; + int _field544; +private: + /** + * Test whether a substring contains one of the quotes, + * and if so, returns the 4-character tag Id associated with it + */ + int find(const char *startP, const char *endP) const; +public: + bool _loaded; +public: + TTquotes(); + ~TTquotes(); + + /** + * Load quotes data resource + */ + void load(); + + /** + * Test whether a passed string contains one of the quotes, + * and if so, returns the 4-character tag Id associated with it + */ + int find(const char *str) const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_QUOTES_H */ diff --git a/engines/titanic/true_talk/tt_quotes_tree.cpp b/engines/titanic/true_talk/tt_quotes_tree.cpp new file mode 100644 index 0000000000..1f073b83f2 --- /dev/null +++ b/engines/titanic/true_talk/tt_quotes_tree.cpp @@ -0,0 +1,214 @@ +/* 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/algorithm.h" +#include "titanic/true_talk/tt_quotes_tree.h" +#include "titanic/titanic.h" + +namespace Titanic { + +/** + * Specifies the starting index for each of the three main trees + */ +static uint TABLE_INDEXES[3] = { 922, 1015, 1018 }; + +void TTquotesTree::load() { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource("TEXT/TREE"); + + for (int idx = 0; idx < QUOTES_TREE_COUNT; ++idx) { + TTquotesTreeEntry &rec = _entries[idx]; + assert(r->pos() < r->size()); + + rec._id = r->readUint32LE(); + if (rec._id == 0) { + // Nothing needed + } else { + byte type = r->readByte(); + if (type == 0) { + // Index to sub-table + rec._subTable = &_entries[0] + r->readUint32LE(); + } else { + // Read in string for entry + char c; + while ((c = r->readByte()) != '\0') + rec._string += c; + } + } + } + + assert(r->pos() == r->size()); + delete r; +} + +int TTquotesTree::search(const char *str, QuoteTreeNum treeNum, + TTtreeResult *buffer, uint tagId, uint *remainder) { + const TTquotesTreeEntry *bTree = &_entries[TABLE_INDEXES[treeNum]]; + if (!search1(&str, bTree, buffer, tagId) || !buffer->_treeItemP) + return -1; + + if (remainder) { + while (*str) { + if (*str >= 'a' && *str != 's') + *remainder += *str; + } + } + + return buffer->_treeItemP->_id & 0xffffff; +} + +bool TTquotesTree::search1(const char **str, const TTquotesTreeEntry *bTree, + TTtreeResult *buffer, uint tagId) { + buffer->_treeItemP = nullptr; + (buffer + 1)->_treeItemP = nullptr; + + const char *strP = *str; + bool flag = false; + + for (uint mode = bTree->_id >> 24; mode != 0; + ++bTree, mode = bTree->_id >> 24) { + + switch (mode) { + case 1: + if (compareWord(str, bTree->_string.c_str())) + flag = true; + break; + + case 2: + compareWord(str, bTree->_string.c_str()); + break; + + case 5: + if (READ_LE_UINT32(bTree->_string.c_str()) == tagId) + flag = true; + break; + + case 7: + if (search1(str, bTree->_subTable, buffer + 1, tagId)) + flag = true; + break; + + case 8: + if (search2(str, bTree->_subTable, buffer + 1, tagId)) + flag = true; + break; + + default: + break; + } + + if (flag) { + buffer->_treeItemP = bTree; + return true; + } + } + + *str = strP; + return false; +} + +bool TTquotesTree::search2(const char **str, const TTquotesTreeEntry *bTree, + TTtreeResult *buffer, uint tagId) { + buffer->_treeItemP = bTree; + (buffer + 1)->_treeItemP = nullptr; + + const char *strP = *str; + bool flag = false; + for (uint mode = bTree->_id >> 24; mode != 0; + ++bTree, mode = bTree->_id >> 24) { + switch (mode) { + case 0: + return true; + + case 1: + if (compareWord(str, bTree->_string.c_str())) + flag = true; + break; + + case 2: + compareWord(str, bTree->_string.c_str()); + break; + + case 5: + if (READ_LE_UINT32(bTree->_string.c_str()) == tagId) + flag = true; + break; + + case 7: + if (search1(str, bTree->_subTable, buffer + 1, tagId)) + flag = true; + break; + + case 8: + if (search2(str, bTree->_subTable, buffer + 1, tagId)) + flag = true; + break; + + default: + break; + } + + if (flag) { + buffer->_treeItemP = nullptr; + *str = strP; + return false; + } + } + + return true; +} + +bool TTquotesTree::compareWord(const char **str, const char *refStr) { + // Skip over any spaces + const char *strP = *str; + while (*strP && *strP == ' ') + ++strP; + *str = strP; + + // Compare against the reference string + while (*strP && *refStr && *refStr != '*') { + if (*refStr == '-') { + if (*strP == ' ') + ++strP; + } else if (*strP == *refStr) { + ++strP; + } else { + return false; + } + } + + if (*refStr && *refStr != '*') + return false; + if (!*refStr && *strP && *strP != ' ') + return false; + + if (*refStr == '*') { + // Skip over to the end of the word + while (*strP && *strP != ' ') + ++strP; + } + + // Pass out the new updated string position + *str = strP; + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_quotes_tree.h b/engines/titanic/true_talk/tt_quotes_tree.h new file mode 100644 index 0000000000..d7ca798ae8 --- /dev/null +++ b/engines/titanic/true_talk/tt_quotes_tree.h @@ -0,0 +1,84 @@ +/* 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 TITANIC_TT_QUOTES_TREE_H +#define TITANIC_TT_QUOTES_TREE_H + +#include "common/scummsys.h" +#include "common/stream.h" +#include "titanic/support/string.h" + +namespace Titanic { + +#define QUOTES_TREE_COUNT 1022 + +enum QuoteTreeNum { TREE_1 = 0, TREE_2 = 1, TREE_3 = 2 }; + +struct TTquotesTreeEntry { + uint _id; + TTquotesTreeEntry *_subTable; + CString _string; + + TTquotesTreeEntry() : _id(0), _subTable(nullptr) {} +}; + +class TTtreeResult { +public: + int _id; + const TTquotesTreeEntry *_treeItemP; +public: + TTtreeResult() : _id(0), _treeItemP(nullptr) {} +}; + +class TTquotesTree { +private: + TTquotesTreeEntry _entries[QUOTES_TREE_COUNT]; +private: + /** + * First inner search method + */ + bool search1(const char **str, const TTquotesTreeEntry *bTree, + TTtreeResult *buffer, uint tagId); + + /** + * Second inner search method + */ + bool search2(const char **str, const TTquotesTreeEntry *bTree, + TTtreeResult *buffer, uint tagId); + + /** + * Compare the current word in the string against a specified word + */ + bool compareWord(const char **str, const char *refStr); +public: + /** + * Load data for the quotes tree + */ + void load(); + + int search(const char *str, QuoteTreeNum treeNum, + TTtreeResult *buffer, uint tagId, uint *remainder); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_QUOTES_TREE_H */ diff --git a/engines/titanic/true_talk/tt_response.cpp b/engines/titanic/true_talk/tt_response.cpp new file mode 100644 index 0000000000..f007f98f97 --- /dev/null +++ b/engines/titanic/true_talk/tt_response.cpp @@ -0,0 +1,71 @@ +/* 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 "titanic/true_talk/tt_response.h" + +namespace Titanic { + +TTresponse::TTresponse(const TTstring &src) : _field0(0), _text(src), + _dialogueId(0), _nextP(nullptr), _linkP(nullptr) { +} + +TTresponse::TTresponse(int dialogueId, int val2) : _field0(val2), _text(" "), + _dialogueId(dialogueId), _nextP(nullptr), _linkP(nullptr) { +} + +TTresponse::TTresponse(const TTresponse *src) : _field0(src->_field0), + _text(src->_text), _dialogueId(src->_dialogueId), _nextP(src->_nextP), + _linkP(src->_linkP) { +} + +TTresponse::~TTresponse() { + // Iterate through destroying any successive linked response items + TTresponse *nextP; + for (TTresponse *currP = _nextP; currP; currP = nextP) { + // Get the following response and detach it from the current one, + // so that when the current is destroyed, it will only destroy itself + nextP = currP->_nextP; + currP->_nextP = nullptr; + delete currP; + } +} + +TTresponse *TTresponse::copyChain() const { + TTresponse *returnResponseP = new TTresponse(this); + + for (TTresponse *srcP = _nextP, *destP = returnResponseP; + srcP; srcP = srcP->_nextP, destP = destP->_nextP) { + destP->_nextP = new TTresponse(*srcP); + } + + return returnResponseP; +} + +void TTresponse::addLink(TTresponse *item) { + TTresponse *currP = this; + while (currP->_linkP) + currP = currP->_linkP; + + currP->_linkP = item; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_response.h b/engines/titanic/true_talk/tt_response.h new file mode 100644 index 0000000000..d39d18c193 --- /dev/null +++ b/engines/titanic/true_talk/tt_response.h @@ -0,0 +1,66 @@ +/* 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 TITANIC_TT_RESPONSE_H +#define TITANIC_TT_RESPONSE_H + +#include "titanic/true_talk/tt_string.h" +namespace Titanic { + +class TTsentence; + +class TTresponse { +private: + int _field0; + TTstring _text; + int _dialogueId; + TTresponse *_nextP; + TTresponse *_linkP; +public: + TTresponse(const TTstring &src); + TTresponse(int val1, int val2); + TTresponse(const TTresponse *src); + virtual ~TTresponse(); + + /** + * Makes a copy of the chain of responses + */ + TTresponse *copyChain() const; + + TTresponse *getLink() const { return _linkP; } + + void addLink(TTresponse *item); + + /** + * Get the dialogue Id for the response + */ + int getDialogueId() const { return _dialogueId; } + + /** + * Return the next response item, if present + */ + TTresponse *getNext() const { return _nextP; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_RESPONSE_H */ diff --git a/engines/titanic/true_talk/tt_room_script.cpp b/engines/titanic/true_talk/tt_room_script.cpp new file mode 100644 index 0000000000..b8fbca7d39 --- /dev/null +++ b/engines/titanic/true_talk/tt_room_script.cpp @@ -0,0 +1,60 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/tt_room_script.h" + +namespace Titanic { + +TTroomScriptBase::TTroomScriptBase(int scriptId, + const char *charClass, const char *charName, + int v3, int v4, int v5, int v6, int v2, int v7) : _scriptId(scriptId), + TTscriptBase(3, charClass, v2, charName, v3, v4, v5, v6, v7) { +} + +/*------------------------------------------------------------------------*/ + +TTroomScript::TTroomScript(int scriptId) : + TTroomScriptBase(scriptId, "", "", 0, -1, -1, -1, 0, 0) { +} + +bool TTroomScript::proc8() const { + return false; +} + +void TTroomScript::proc9(int v) { + if (v == 1) + _field54 = 1; +} + +ScriptChangedResult TTroomScript::scriptChanged(TTscriptBase *npcScript, int id) { + if (id == 1) + _field54 = 1; + + return SCR_1; +} + +bool TTroomScript::proc11() const { + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_room_script.h b/engines/titanic/true_talk/tt_room_script.h new file mode 100644 index 0000000000..39a50ac30d --- /dev/null +++ b/engines/titanic/true_talk/tt_room_script.h @@ -0,0 +1,103 @@ +/* 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 TITANIC_TT_ROOM_SCRIPT_H +#define TITANIC_TT_ROOM_SCRIPT_H + +#include "titanic/true_talk/tt_script_base.h" + +namespace Titanic { + +class TTnpcScript; +class TTsentence; + +class TTroomScriptBase : public TTscriptBase { +public: + uint _scriptId; +public: + TTroomScriptBase(int scriptId, const char *charClass, const char *charName, + int v3, int v4, int v5, int v6, int v2, int v7); + + /** + * Returns true if a response can be made + */ + virtual bool canRespond(TTnpcScript *npcScript, TTsentence *sentence, int val) const = 0; + + /** + * Returns true if further sentence processing is allowed + */ + virtual bool canProcess(TTnpcScript *npcScript, TTsentence *sentence) const = 0; + + virtual bool proc8() const = 0; + virtual void proc9(int v) = 0; + + /** + * Called when the script changes + */ + virtual ScriptChangedResult scriptChanged(TTscriptBase *npcScript, int id) = 0; + + virtual bool proc11() const = 0; +}; + + +class TTroomScript : public TTroomScriptBase { +public: + int _field54; +public: + TTroomScript(int scriptId); + + /** + * Returns true if a response can be made + */ + virtual bool canRespond(TTnpcScript *npcScript, TTsentence *sentence, int val) const { + return true; + } + + /** + * Returns true if further sentence processing is allowed + */ + virtual bool canProcess(TTnpcScript *npcScript, TTsentence *sentence) const { + return true; + } + + virtual bool proc8() const; + + virtual void proc9(int v); + + /** + * Called when the script changes + */ + virtual ScriptChangedResult scriptChanged(TTscriptBase *npcScript, int id); + + virtual bool proc11() const; + + /** + * Called with the new script and id + */ + ScriptChangedResult notifyScript(TTscriptBase *npcScript, int id) { + return scriptChanged(npcScript, id); + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_ROOM_SCRIPT_H */ diff --git a/engines/titanic/true_talk/tt_script_base.cpp b/engines/titanic/true_talk/tt_script_base.cpp new file mode 100644 index 0000000000..4109134501 --- /dev/null +++ b/engines/titanic/true_talk/tt_script_base.cpp @@ -0,0 +1,156 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/tt_script_base.h" +#include "titanic/titanic.h" + +namespace Titanic { + +TTscriptBase::TTscriptBase(int scriptId, const char *charClass, int state, + const char *charName, int v3, int v4, int v5, int v6, int v7) : + _charName(charName), _charClass(charClass), _status(0), + _nodesP(nullptr), _id(0), _hist1P(nullptr), + _field20(0), _field24(0), _field28(0), _field2C(0), + _field30(0), _state(0), _hist2P(nullptr), _field3C(0), + _respHeadP(nullptr), _respTailP(nullptr), _oldResponseP(nullptr) { + if (!isValid()) { + if (!v7 || !getStatus()) { + _id = scriptId; + _field20 = v3; + _field24 = v4; + _field28 = v5; + _field2C = v6; + _field30 = v7; + _state = state; + } else { + _status = 5; + } + } + + if (_status) + reset(); +} + +TTscriptBase::~TTscriptBase() { + deleteResponses(); + delete _oldResponseP; + + delete _hist1P; + delete _hist2P; + + if (_nodesP) { + _nodesP->deleteSiblings(); + delete _nodesP; + } +} + +bool TTscriptBase::isValid() { + bool result = !_charName.isValid() && !_charClass.isValid(); + _status = result ? 0 : 11; + return result; +} + +void TTscriptBase::reset() { + _nodesP = nullptr; + _id = 4; + _hist1P = nullptr; + _field20 = 0; + _field24 = -1; + _field28 = -1; + _field2C = -1; + _field30 = 0; + _state = 0; + _hist2P = nullptr; + _field3C = 0; + _respHeadP = nullptr; + _respTailP = nullptr; + _oldResponseP = nullptr; +} + +int TTscriptBase::scriptPreprocess(TTsentence *sentence) { + delete _hist1P; + _hist1P = new TTscriptHist(sentence); + + return _hist1P ? SS_VALID : SS_7; +} + +void TTscriptBase::addResponse(const TTstring &str) { + appendResponse2(-1, nullptr, str); +} + +void TTscriptBase::addResponse(int id) { + appendResponse(-1, nullptr, id); +} + +void TTscriptBase::applyResponse() { + delete _oldResponseP; + _oldResponseP = nullptr; + + if (_respHeadP) { + g_vm->_scriptHandler->setResponse(this, _respHeadP); + _oldResponseP = _respHeadP->copyChain(); + TTresponse *oldRespP = _respHeadP; + _respHeadP = _respHeadP->getLink(); + _respTailP = nullptr; + + delete oldRespP; + } +} + +void TTscriptBase::deleteResponses() { + while (_respTailP) { + _respHeadP = _respTailP; + _respTailP = _respHeadP->getLink(); + delete _respHeadP; + } +} + +void TTscriptBase::appendResponse(int val1, int *val2, int val3) { + if (!val2 || val1 <= *val2) { + if (_respHeadP) { + _respHeadP = new TTresponse(_respHeadP); + } else { + _respHeadP = new TTresponse(val3, 3); + if (_respTailP) + _respTailP->addLink(_respHeadP); + else + _respTailP = _respHeadP; + } + } +} + +void TTscriptBase::appendResponse(int val1, int *val2, const TTstring &str) { + if (!val2 || val1 <= *val2) { + if (_respHeadP) { + _respHeadP = new TTresponse(str); + } else { + _respHeadP = new TTresponse(str); + if (_respTailP) + _respTailP->addLink(_respHeadP); + else + _respTailP = _respHeadP; + } + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_script_base.h b/engines/titanic/true_talk/tt_script_base.h new file mode 100644 index 0000000000..c489dcb0a7 --- /dev/null +++ b/engines/titanic/true_talk/tt_script_base.h @@ -0,0 +1,131 @@ +/* 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 TITANIC_TT_SCRIPT_BASE_H +#define TITANIC_TT_SCRIPT_BASE_H + +#include "titanic/true_talk/tt_string.h" +#include "titanic/true_talk/tt_hist.h" +#include "titanic/true_talk/tt_node.h" +#include "titanic/true_talk/tt_response.h" + +namespace Titanic { + +enum ScriptChangedResult { + SCR_0 = 0, SCR_1 = 1, SCR_2 = 2, SCR_3 = 3, SCR_4 = 4, SCR_5 = 5 +}; + +class TTsentence; + +class TTscriptBase { +private: + void reset(); +protected: + TTnode *_nodesP; + TThist *_hist1P; + TTstring _charName, _charClass; + int _field20; + int _field24; + int _field28; + int _field2C; + int _field30; + int _state; + TThist *_hist2P; + int _field3C; + TTresponse *_respHeadP; + TTresponse *_respTailP; + TTresponse *_oldResponseP; + int _status; +protected: + /** + * Delete any responses set up for the script + */ + void deleteResponses(); + + /** + * Creates and appends a new response to the script + */ + void appendResponse(int val1, int *val2, int val3); + + void appendResponse(int val1, int *val2, const TTstring &str); + + void appendResponse2(int val1, int *val2, const TTstring &str) { + appendResponse(val1, val2, str); + } + + /** + * Set the script state + */ + void setState(int state) { _state = state; } + + /** + * Get the current state + */ + int getState() const { return _state; } +public: + int _id; +public: + TTscriptBase(int scriptId, const char *charClass, int v2, const char *charName, + int v3, int v4, int v5, int v6, int v7); + virtual ~TTscriptBase(); + + virtual void addResponse(const TTstring &str); + + virtual void addResponse(int id); + + /** + * Passes on the list of dialogue Ids stored in the response(s) + * to the title engine for later display in the PET + */ + virtual void applyResponse(); + + /** + * Returns true if the script is in a valid state + */ + bool isValid(); + + /** + * Return the Id of the script + */ + int getId() const { return _id; } + + /** + * Return the status + */ + int getStatus() const { return _status; } + + /** + * Return the script text + */ + const TTstring getText() { return _charClass; } + + /** + * Gets passed a newly created input wrapper during conversation text processing + */ + int scriptPreprocess(TTsentence *sentence); + +}; + + +} // End of namespace Titanic + +#endif /* TITANIC_TT_SCRIPT_BASE_H */ diff --git a/engines/titanic/true_talk/tt_scripts.cpp b/engines/titanic/true_talk/tt_scripts.cpp new file mode 100644 index 0000000000..f8ea65a475 --- /dev/null +++ b/engines/titanic/true_talk/tt_scripts.cpp @@ -0,0 +1,97 @@ +/* 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 "titanic/true_talk/tt_scripts.h" +#include "titanic/true_talk/title_engine.h" +#include "titanic/true_talk/barbot_script.h" +#include "titanic/true_talk/bellbot_script.h" +#include "titanic/true_talk/deskbot_script.h" +#include "titanic/true_talk/doorbot_script.h" +#include "titanic/true_talk/liftbot_script.h" +#include "titanic/true_talk/maitred_script.h" +#include "titanic/true_talk/parrot_script.h" +#include "titanic/true_talk/succubus_script.h" + +namespace Titanic { + +TTnpcScript *TTnpcScriptList::findById(int charId) const { + for (TTnpcScriptList::const_iterator i = begin(); i != end(); ++i) { + const TTnpcScriptListItem *item = *i; + if (item->_npcScript->_charId == charId) + return item->_npcScript; + } + + return nullptr; +} + +/*------------------------------------------------------------------------*/ + +TTroomScript *TTroomScriptList::findById(uint scriptId) const { + for (TTroomScriptList::const_iterator i = begin(); i != end(); ++i) { + const TTroomScriptListItem *item = *i; + if (item->_item->_scriptId == scriptId) + return item->_item; + } + + return nullptr; +} + +/*------------------------------------------------------------------------*/ + +TTscripts::TTscripts(CTitleEngine *titleEngine) : + _titleEngine(titleEngine), _field24(0), _field28(0) { + // Load room scripts + for (int scriptNum = 100; scriptNum < 133; ++scriptNum) + addScript(new TTroomScript(scriptNum)); + + // Load npc scripts + addScript(new DoorbotScript(104, "Doorbot", 0, "Fentible", 11, 1, -1, -1, -1, 0), 100); + addScript(new BellbotScript(101, "Bellbot", 0, "Krage", 8, 1), 110); + addScript(new LiftbotScript(105, "LiftBot", 0, "Nobby", 11, 1, -1, -1, -1, 0), 103); + addScript(new DeskbotScript(103, "DeskBot", 0, "Marsinta", 11, 2), 110); + addScript(new BarbotScript(100, "Barbot", 0, "Fortillian", 9, 1, -1, -1, -1, 0), 112); + addScript(new ParrotScript(107, "Parrot", 0, "The Parrot", 5, 1, -1, -1, -1, 0), 111); + addScript(new MaitreDScript(112, "MaitreDBot", 0, "Dastrogaaar", 8, 1), 132); + addScript(new SuccUBusScript(111, "Succubus", 0, "Shorbert", 9, 1, -1, -1, -1, 0), 110); +} + +void TTscripts::addScript(TTnpcScript *script, int scriptId) { + // Find the room script this is associated with + TTroomScript *roomScript = getRoomScript(scriptId); + assert(roomScript); + + _npcScripts.push_back(new TTnpcScriptListItem(script, roomScript)); +} + +void TTscripts::addScript(TTroomScript *script) { + _roomScripts.push_back(new TTroomScriptListItem(script)); +} + +TTroomScript *TTscripts::getRoomScript(int scriptId) const { + return _roomScripts.findById(scriptId); +} + +TTnpcScript *TTscripts::getNpcScript(int charId) const { + return _npcScripts.findById(charId); +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_scripts.h b/engines/titanic/true_talk/tt_scripts.h new file mode 100644 index 0000000000..734d86256f --- /dev/null +++ b/engines/titanic/true_talk/tt_scripts.h @@ -0,0 +1,90 @@ +/* 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 TITANIC_TT_SCRIPTS_H +#define TITANIC_TT_SCRIPTS_H + +#include "titanic/core/list.h" +#include "titanic/true_talk/tt_npc_script.h" +#include "titanic/true_talk/tt_room_script.h" + +namespace Titanic { + +class CTitleEngine; + +class TTnpcScriptListItem : public ListItem { +public: + TTnpcScript *_npcScript; + TTroomScript *_roomScript; +public: + TTnpcScriptListItem() : _npcScript(nullptr), _roomScript(nullptr) {} + TTnpcScriptListItem(TTnpcScript *script, TTroomScript *roomScript) : + _npcScript(script), _roomScript(roomScript) {} + virtual ~TTnpcScriptListItem() { delete _npcScript; } +}; + +PTR_LIST_ITEM(TTroomScript); + +class TTnpcScriptList : public List<TTnpcScriptListItem> { +public: + TTnpcScript *findById(int charId) const; +}; + +class TTroomScriptList : public List<TTroomScriptListItem> { +public: + TTroomScript *findById(uint scriptId) const; +}; + +class TTscripts { +private: + TTnpcScriptList _npcScripts; + TTroomScriptList _roomScripts; + CTitleEngine *_titleEngine; + int _field24; + int _field28; +private: + /** + * Add a named script to the named scripts list + */ + void addScript(TTnpcScript *script, int charId); + + /** + * Add an unnamed script to the unnamed scripts list + */ + void addScript(TTroomScript *script); +public: + TTscripts(CTitleEngine *titleEngine); + + /** + * Return a pointer to the specified room script + */ + TTroomScript *getRoomScript(int scriptId) const; + + /** + * Return a pointer to the specified character script + */ + TTnpcScript *getNpcScript(int charId) const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_CHARACTERS_H */ diff --git a/engines/titanic/true_talk/tt_sentence.cpp b/engines/titanic/true_talk/tt_sentence.cpp new file mode 100644 index 0000000000..9588ee021e --- /dev/null +++ b/engines/titanic/true_talk/tt_sentence.cpp @@ -0,0 +1,347 @@ +/* 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 "titanic/true_talk/tt_sentence.h" +#include "titanic/true_talk/tt_concept.h" +#include "titanic/true_talk/script_handler.h" +#include "titanic/titanic.h" + +namespace Titanic { + +TTsentenceConcept *TTsentenceConcept::addSibling() { + if (this == nullptr || _nextP != nullptr) + // This should never happen + return nullptr; + + TTsentenceConcept *nextP = new TTsentenceConcept(); + _nextP = nextP; + return nextP; +} + +/*------------------------------------------------------------------------*/ + +TTsentence::TTsentence(int inputCtr, const TTstring &line, CScriptHandler *owner, + TTroomScript *roomScript, TTnpcScript *npcScript) : + _owner(owner), _field2C(1), _inputCtr(inputCtr), _field34(0), + _field38(0), _initialLine(line), _nodesP(nullptr), _roomScript(roomScript), + _npcScript(npcScript), _field58(0), _field5C(0) { + _status = _initialLine.isValid() && _normalizedLine.isValid() ? SS_11: SS_VALID; +} + +TTsentence::TTsentence(const TTsentence *src) : _sentenceConcept(src->_sentenceConcept), + _initialLine(src->_initialLine), _normalizedLine(src->_normalizedLine) { + copyFrom(*src); +} + +TTsentence::~TTsentence() { + _sentenceConcept.deleteSiblings(); + + if (_nodesP) { + _nodesP->deleteSiblings(); + delete _nodesP; + } +} + +void TTsentence::copyFrom(const TTsentence &src) { + if (!src.getStatus()) + _status = SS_5; + else if (!src._initialLine.isValid() || !src._normalizedLine.isValid()) + _status = SS_11; + else + _status = SS_VALID; + + _inputCtr = src._inputCtr; + _owner = src._owner; + _roomScript = src._roomScript; + _npcScript = src._npcScript; + _field58 = src._field58; + _field5C = src._field5C; + _field34 = src._field34; + _field38 = src._field38; + _field2C = src._field2C; + _nodesP = nullptr; + + if (src._nodesP) { + // Source has processed nodes, so duplicate them + for (TTsentenceNode *node = src._nodesP; node; + node = static_cast<TTsentenceNode *>(node->_nextP)) { + TTsentenceNode *newNode = new TTsentenceNode(node->_wordP); + if (_nodesP) + _nodesP->addToTail(newNode); + else + _nodesP = newNode; + } + } +} + +int TTsentence::storeVocabHit(TTword *word) { + if (!word) + return 0; + + TTsentenceNode *node = new TTsentenceNode(word); + if (_nodesP) { + _nodesP->addToTail(node); + } else { + _nodesP = node; + } + + return 0; +} + +bool TTsentence::fn1(const CString &str, int wordId1, const CString &str1, const CString &str2, + const CString &str3, int wordId2, int val1, int val2, const TTconceptNode *node) const { + if (node) + node = &_sentenceConcept; + + if (!node && !node) + return false; + if (val1 && !is18(val1, node)) + return false; + if (!str.empty() && !fn2(0, str, node)) + return false; + if (wordId1 && !fn4(1, wordId1, node)) + return false; + if (!str1.empty() && !fn2(2, str1, node)) + return false; + if (!str2.empty() && !fn2(3, str2, node)) + return false; + if (!str3.empty() && !fn2(4, str3, node)) + return false; + if (wordId2 && !fn4(5, wordId2, node)) + return false; + if (val2 && !is1C(val2, node)) + return false; + + return true; +} + +bool TTsentence::fn3(const CString &str1, const CString &str2, const CString &str3, + const CString &str4, const CString &str5, const CString &str6, + int val1, int val2, const TTconceptNode *node) const { + if (!node) + node = &_sentenceConcept; + + if (val1 && !is18(val1, node)) + return false; + if (!str1.empty() && !fn2(0, str1, node)) + return false; + if (!str2.empty() && !fn2(1, str2, node)) + return false; + if (!str3.empty() && !fn2(2, str3, node)) + return false; + if (!str4.empty() && !fn2(3, str4, node)) + return false; + if (!str5.empty() && !fn2(4, str5, node)) + return false; + if (!str6.empty() && !fn2(5, str6, node)) + return false; + if (!val2 && !is1C(val2, node)) + return false; + + return true; +} + +bool TTsentence::fn2(int slotIndex, const TTstring &str, const TTconceptNode *node) const { + if (!node) + node = &_sentenceConcept; + TTconcept *concept = getFrameSlot(slotIndex, node); + + if (!concept) + return str == "isEmpty"; + + bool abortFlag = false; + switch (concept->_scriptType) { + case 1: + if (str == "thePlayer") + abortFlag = 1; + break; + + case 2: + if (str == "targetNpc") + abortFlag = 1; + break; + + case 3: + if (str == "otherNpc") + abortFlag = 1; + break; + + default: + break; + } + + TTstring conceptText = concept->getText(); + if (abortFlag || str == conceptText || concept->compareTo(str)) { + delete concept; + return true; + } + + if (slotIndex == 1 && g_vm->_exeResources._owner->_concept4P) { + if (str == g_vm->_exeResources._owner->_concept4P->getText() && + conceptText == "do") + goto exit; + } + + if (g_vm->_exeResources._owner->_concept2P && (slotIndex == 0 || + slotIndex == 3 || slotIndex == 4)) { + if (str == g_vm->_exeResources._owner->_concept2P->getText() && + (conceptText == "it" || conceptText == "he" || conceptText == "she" || + conceptText == "him" || conceptText == "her" || conceptText == "them" || + conceptText == "they")) + goto exit; + } + + if (g_vm->_exeResources._owner->_concept1P && (slotIndex == 0 || + slotIndex == 2 || slotIndex == 3 || slotIndex == 4 || slotIndex == 5)) { + if (str == g_vm->_exeResources._owner->_concept2P->getText() && + (conceptText == "it" || conceptText == "that" || conceptText == "he" || + conceptText == "she" || conceptText == "him" || conceptText == "her" || + conceptText == "them" || conceptText == "they" || conceptText == "those" || + conceptText == "1" || conceptText == "thing")) + goto exit; + } + + if (g_vm->_exeResources._owner->_concept1P && (slotIndex == 0 || slotIndex == 2)) { + if (conceptText == "?" && str == g_vm->_exeResources._owner->_concept2P->getText()) { + delete concept; + concept = getFrameSlot(5, node); + conceptText = concept->getText(); + + if (conceptText == "it" || conceptText == "that" || conceptText == "he" || + conceptText == "she" || conceptText == "him" || conceptText == "her" || + conceptText == "them" || conceptText == "they" || conceptText == "those" || + conceptText == "1" || conceptText == "thing") + abortFlag = true; + } + } + +exit: + delete concept; + return abortFlag; +} + +bool TTsentence::fn4(int mode, int wordId, const TTconceptNode *node) const { + if (!node) + node = &_sentenceConcept; + + switch (mode) { + case 1: + return node->_concept1P && node->_concept1P->getWordId() == wordId; + + case 5: + return node->_concept5P && node->_concept5P->getWordId() == wordId; + + default: + return false; + } +} + +TTconcept *TTsentence::getFrameEntry(int slotIndex, const TTconceptNode *conceptNode) const { + if (!conceptNode) + conceptNode = &_sentenceConcept; + + return conceptNode->_concepts[slotIndex]; +} + +TTconcept *TTsentence::getFrameSlot(int slotIndex, const TTconceptNode *conceptNode) const { + TTconcept *newConcept = new TTconcept(); + TTconcept *concept = getFrameEntry(slotIndex, conceptNode); + newConcept->copyFrom(concept); + + if (!newConcept->isValid()) { + delete newConcept; + newConcept = nullptr; + } + + return newConcept; +} + +bool TTsentence::isFrameSlotClass(int slotIndex, WordClass wordClass, const TTconceptNode *conceptNode) const { + TTconcept *concept = getFrameEntry(slotIndex, conceptNode); + if (concept && concept->_wordP) { + return concept->_wordP->isClass(wordClass); + } else { + return false; + } +} + +int TTsentence::is18(int val, const TTconceptNode *node) const { + if (!node) + node = &_sentenceConcept; + return node->_field18 == val; +} + +int TTsentence::is1C(int val, const TTconceptNode *node) const { + if (!node) + node = &_sentenceConcept; + return node->_field1C == val; +} + +bool TTsentence::isConcept34(int slotIndex, const TTconceptNode *node) const { + TTconcept *concept = getFrameEntry(slotIndex, node); + return concept && concept->getState(); +} + +bool TTsentence::localWord(const char *str) const { + CScriptHandler &scriptHandler = *g_vm->_exeResources._owner; + bool foundMatch = false; + + if (scriptHandler._concept1P) { + TTstring s = scriptHandler._concept1P->getText(); + if (s == str) + foundMatch = true; + } else if (scriptHandler._concept2P) { + TTstring s = scriptHandler._concept2P->getText(); + if (s == str) + foundMatch = true; + } + + int val = g_vm->_exeResources.get18(); + bool result = false; + + for (TTsentenceNode *nodeP = _nodesP; nodeP && !result; + nodeP = static_cast<TTsentenceNode *>(nodeP->_nextP)) { + TTsynonym syn; + if (!nodeP->_wordP) + continue; + + const TTstring wordStr = nodeP->_wordP->_text; + if (val == 3 && wordStr == str) { + result = true; + } else if (nodeP->_wordP->findSynByName(str, &syn, val)) { + result = true; + } else if (foundMatch) { + result = wordStr == "it" || wordStr == "that" || wordStr == "he" + || wordStr == "she" || wordStr == "him" || wordStr == "her" + || wordStr == "them" || wordStr == "they" || wordStr == "those" + || wordStr == "1" || wordStr == "thing"; + } + } + + return result; +} + +bool TTsentence::contains(const char *str) const { + return _initialLine.contains(str) || _normalizedLine.contains(str); +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_sentence.h b/engines/titanic/true_talk/tt_sentence.h new file mode 100644 index 0000000000..7b2c6400c5 --- /dev/null +++ b/engines/titanic/true_talk/tt_sentence.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 TITANIC_TT_SENTENCE_H +#define TITANIC_TT_SENTENCE_H + +#include "common/array.h" +#include "titanic/true_talk/tt_concept_node.h" +#include "titanic/true_talk/tt_npc_script.h" +#include "titanic/true_talk/tt_room_script.h" +#include "titanic/true_talk/tt_sentence_node.h" +#include "titanic/true_talk/tt_string.h" + +namespace Titanic { + +class CScriptHandler; +class TTword; + +class TTsentenceConcept : public TTconceptNode { +public: + TTsentenceConcept() : TTconceptNode() {} + TTsentenceConcept(const TTsentenceConcept &src) : TTconceptNode(src) {} + + /** + * Adds a new sibling instance + */ + TTsentenceConcept *addSibling(); +}; + +class TTsentence { +private: + CScriptHandler *_owner; + int _inputCtr; + int _field34; + TTsentenceNode *_nodesP; + int _field5C; + int _status; +private: + /** + * Copy sentence data from a given source + */ + void copyFrom(const TTsentence &src); +public: + TTsentenceConcept _sentenceConcept; + TTstring _initialLine; + TTstring _normalizedLine; + int _field38; + int _field58; + TTroomScript *_roomScript; + TTnpcScript *_npcScript; + int _field2C; +public: + TTsentence(int inputCtr, const TTstring &line, CScriptHandler *owner, + TTroomScript *roomScript, TTnpcScript *npcScript); + TTsentence(const TTsentence *src); + ~TTsentence(); + + void setState(int v) { _field34 = v; } + void set38(int v) { _field38 = v; } + bool check2C() const { return _field2C > 1 && _field2C <= 10; } + int concept18(TTconceptNode *conceptNode) { + return conceptNode ? conceptNode->get18() : 0; + } + int get58() const { return _field58; } + int is18(int val, const TTconceptNode *node) const; + int is1C(int val, const TTconceptNode *node) const; + + int getStatus() const { return _status; } + + /** + * Gets a concept slot + */ + TTconcept *getFrameEntry(int slotIndex, const TTconceptNode *conceptNode = nullptr) const; + + /** + * Gets a conecpt slot and returns a duplicate of it + */ + TTconcept *getFrameSlot(int slotIndex, const TTconceptNode *conceptNode = nullptr) const; + + /** + * Returns true if the specified slot has an attached word with a given class + */ + bool isFrameSlotClass(int slotIndex, WordClass wordClass, const TTconceptNode *conceptNode = nullptr) const; + + /** + * Adds a found vocab word to the list of words representing + * the player's input + * @param word Word to node + */ + int storeVocabHit(TTword *word); + + bool fn1(const CString &str, int wordId1, const CString &str1, const CString &str2, + const CString &str3, int wordId2, int val1, int val2, const TTconceptNode *node) const; + bool fn3(const CString &str1, const CString &str2, const CString &str3, + const CString &str4, const CString &str5, const CString &str6, + int val1, int val2, const TTconceptNode *node) const; + bool fn2(int slotIndex, const TTstring &str, const TTconceptNode *node = nullptr) const; + bool fn4(int mode, int wordId, const TTconceptNode *node = nullptr) const; + + bool isConcept34(int slotIndex, const TTconceptNode *node = nullptr) const; + + bool localWord(const char *str) const; + + /** + * Returns true if the sentence (either the original or normalized lines) + * contain the specified substring + */ + bool contains(const char *str) const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_SENTENCE_H */ diff --git a/engines/titanic/true_talk/tt_sentence_node.cpp b/engines/titanic/true_talk/tt_sentence_node.cpp new file mode 100644 index 0000000000..33d7501c55 --- /dev/null +++ b/engines/titanic/true_talk/tt_sentence_node.cpp @@ -0,0 +1,34 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/tt_sentence_node.h" + +namespace Titanic { + +TTsentenceNode::TTsentenceNode() : TTnode(), _wordP(nullptr) { +} + +TTsentenceNode::TTsentenceNode(TTword *word) : TTnode(), _wordP(word) { +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_sentence_node.h b/engines/titanic/true_talk/tt_sentence_node.h new file mode 100644 index 0000000000..18fa56fd57 --- /dev/null +++ b/engines/titanic/true_talk/tt_sentence_node.h @@ -0,0 +1,41 @@ +/* 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 TITANIC_TT_SENTENCE_NODE_H +#define TITANIC_TT_SENTENCE_NODE_H + +#include "titanic/true_talk/tt_node.h" +#include "titanic/true_talk/tt_word.h" + +namespace Titanic { + +class TTsentenceNode : public TTnode { +public: + TTword *_wordP; +public: + TTsentenceNode(); + TTsentenceNode(TTword *word); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_SENTENCE_NODE_H */ diff --git a/engines/titanic/true_talk/tt_string.cpp b/engines/titanic/true_talk/tt_string.cpp new file mode 100644 index 0000000000..198a8c2e80 --- /dev/null +++ b/engines/titanic/true_talk/tt_string.cpp @@ -0,0 +1,164 @@ +/* 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 "titanic/true_talk/tt_string.h" +#include "titanic/support/simple_file.h" + +namespace Titanic { + +TTstring::TTstring() : _status(SS_VALID) { + _data = new TTstringData(); +} + +TTstring::TTstring(const char *str) : _status(SS_VALID) { + _data = new TTstringData(str); +} + +TTstring::TTstring(const CString &str) { + _status = SS_VALID; + _data = new TTstringData(str); +} + +TTstring::TTstring(const TTstring &str) { + if (str._status != SS_VALID) { + _status = SS_5; + _data = nullptr; + } else { + _status = SS_VALID; + _data = str._data; + _data->_referenceCount++; + } +} + +TTstring::~TTstring() { + if (_data && --_data->_referenceCount == 0) + delete _data; +} + +void TTstring::operator=(const TTstring &str) { + // Delete old string reference, if any + if (_data && --_data->_referenceCount == 0) + delete _data; + + // Copy source string data + _status = str._status; + _data = str._data; + if (_data) + _data->_referenceCount++; +} + +void TTstring::operator=(const CString &str) { + operator=(str.c_str()); +} + +void TTstring::operator=(const char *str) { + // Delete old string reference, if any + if (_data && --_data->_referenceCount == 0) + delete _data; + + // Create new string data + _data = new TTstringData(str); + _status = SS_VALID; +} + +TTstring &TTstring::operator+=(const char *str) { + _data->_string += str; + return *this; +} + +TTstring &TTstring::operator+=(const TTstring &str) { + _data->_string += str; + return *this; +} + +TTstring &TTstring::operator+=(char c) { + _data->_string += c; + return *this; +} + +bool TTstring::operator==(const TTstring &str) const { + return _data && str._data && _data->_string == str._data->_string; +} + +bool TTstring::operator==(const char *str) const { + return _data && _data->_string == str; +} + +void TTstring::save(SimpleFile *file) const { + file->writeFormat("%s", c_str()); +} + +TTstring TTstring::tokenize(const char *delim) { + const char *strP = _data->_string.c_str(); + const char *splitP = nullptr, *chP; + + for (const char *d = delim; d; ++d) { + chP = strchr(strP, *d); + if (chP && (splitP == nullptr || chP < splitP)) + splitP = chP; + } + + if (splitP) { + TTstring result(CString(strP, splitP)); + _data->_string = CString(splitP + 1); + return result; + } else { + return TTstring(); + } +} + +int TTstring::deletePrefix(int count) { + int strSize = size(); + if (count > strSize) + count = strSize; + + if (_data->_referenceCount == 1) { + // No other references to this string, so we can just directly modify it + _data->_string = CString(_data->_string.c_str() + count); + } else { + // Detach string from current shared data, and create a new one with the substring + _data->_referenceCount--; + _data = new TTstringData(_data->_string.c_str() + count); + } + + return 1; +} + +int TTstring::deleteSuffix(int count) { + int strSize = size(); + if (count > strSize) + count = strSize; + + CString newStr(_data->_string.c_str(), _data->_string.c_str() + strSize - count); + if (_data->_referenceCount == 1) { + // No other references to this string, so we can just directly modify it + _data->_string = newStr; + } else { + // Detach string from current shared data, and create a new one with the substring + _data->_referenceCount--; + _data = new TTstringData(newStr); + } + + return 1; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_string.h b/engines/titanic/true_talk/tt_string.h new file mode 100644 index 0000000000..5b12d93418 --- /dev/null +++ b/engines/titanic/true_talk/tt_string.h @@ -0,0 +1,173 @@ +/* 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 TITANIC_TT_STRING_H +#define TITANIC_TT_STRING_H + +#include "titanic/support/string.h" + +namespace Titanic { + +class SimpleFile; + +struct TTstringData { + CString _string; + int _referenceCount; + + TTstringData() : _referenceCount(1) {} + TTstringData(const char *str) : _string(str), _referenceCount(1) {} + TTstringData(const CString &str) : _string(str), _referenceCount(1) {} +}; + +enum TTstringStatus { + SS_VALID = 0, SS_1 = 1, SS_2 = 2, SS_3 = 3, SS_4 = 4, + SS_5 = 5, SS_7 = 7, SS_8 = 8, SS_11 = 11, SS_13 = 13 +}; + +class TTstring { +private: + TTstringData *_data; + TTstringStatus _status; +public: + TTstring(); + TTstring(const char *str); + TTstring(const CString &str); + TTstring(const TTstring &str); + virtual ~TTstring(); + + void operator=(const TTstring &str); + void operator=(const CString &str); + void operator=(const char *str); + TTstring &operator+=(const char *str); + TTstring &operator+=(const TTstring &str); + TTstring &operator+=(char c); + bool operator==(const TTstring &str) const; + bool operator==(const char *str) const; + + const char &operator[](int index) { + return *(c_str() + index); + } + + bool empty() const { + return _data->_string.empty(); + } + + char firstChar() const { + return _data->_string.firstChar(); + } + + char lastChar() const { + return _data->_string.lastChar(); + } + + int size() const { + return _data->_string.size(); + } + + void deleteLastChar() { + _data->_string.deleteLastChar(); + } + + bool hasPrefix(const CString &str) const { + return _data->_string.hasPrefix(str); + } + bool hasPrefix(const char *str) const { + return _data->_string.hasPrefix(str); + } + bool hasSuffix(const CString &str) const { + return _data->_string.hasSuffix(str); + } + bool hasSuffix(const char *str) const { + return _data->_string.hasSuffix(str); + } + + bool contains(const char *s) const { + return _data->_string.contains(s); + } + + /** + * Create a new copy of the string + */ + TTstring *copy() const { + return new TTstring(c_str()); + } + + /** + * Returns true if the string is valid + */ + bool isValid() const { + return _status == SS_VALID; + } + + /** + * Get the status of the string + */ + TTstringStatus getStatus() const { return _status; } + + /** + * Get a char * pointer to the string data + */ + const char *c_str() const { return _data->_string.c_str(); } + + /** + * Automatic operator to convert to a const char * + */ + operator const char *() const { return c_str(); } + + /** + * Get a character at a specified index + */ + char charAt(int index) const { return *(c_str() + index); } + + /** + * Save the sring to a passed file + */ + void save(SimpleFile *file) const; + + /** + * Compare a substring within the string at the specified index + */ + bool compareAt(int index, const char *str) const { + return !strncmp(c_str() + index, str, strlen(str)); + } + + /** + * Split off everything in the string until the first occurance + * of any specified delimiter character + */ + TTstring tokenize(const char *delim); + + /** + * Delets a specififed number of characters from the start of the string + */ + int deletePrefix(int count); + + /** + * Delets a specififed number of characters from the end of the string + */ + int deleteSuffix(int count); + +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_STRING_H */ diff --git a/engines/titanic/true_talk/tt_string_node.cpp b/engines/titanic/true_talk/tt_string_node.cpp new file mode 100644 index 0000000000..2bb0c5a74b --- /dev/null +++ b/engines/titanic/true_talk/tt_string_node.cpp @@ -0,0 +1,68 @@ +/* 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/textconsole.h" +#include "titanic/true_talk/tt_string_node.h" + +namespace Titanic { + +TTstringNode::TTstringNode() : TTnode() { +} + +void TTstringNode::initialize(int mode) { + _mode = mode; + _file = HANDLE_STDIN; + + if (_string.isValid()) { + _field1C = 0; + } else { + _field1C = 11; + warning("TTstringNode::initialize has bad subobj"); + } +} + +void TTstringNode::initialize(TTstringNode *oldNode) { + _mode = oldNode->_mode; + _file = oldNode->_file; + + if (_string.isValid()) { + _field1C = 0; + } else { + _field1C = 11; + warning("TTstringNode::initialize has bad subobj"); + } + + delete oldNode; +} + +TTstringNode *TTstringNode::findByName(const TTstring &str, int mode) { + for (TTstringNode *nodeP = this; nodeP; nodeP = static_cast<TTstringNode *>(nodeP->_nextP)) { + if (nodeP->_mode == mode || (mode == 3 && nodeP->_mode < 3)) { + if (nodeP->_string == str) + return nodeP; + } + } + + return nullptr; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_string_node.h b/engines/titanic/true_talk/tt_string_node.h new file mode 100644 index 0000000000..ced162b439 --- /dev/null +++ b/engines/titanic/true_talk/tt_string_node.h @@ -0,0 +1,59 @@ +/* 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 TITANIC_TT_STRING_NODE_H +#define TITANIC_TT_STRING_NODE_H + +#include "titanic/true_talk/tt_node.h" +#include "titanic/true_talk/tt_string.h" +#include "titanic/support/exe_resources.h" + +namespace Titanic { + +class TTstringNode : public TTnode { +protected: + /** + * Initializes state for the node + */ + void initialize(int mode); + + /** + * Initializes state for the node + */ + void initialize(TTstringNode *oldNode); +public: + TTstring _string; + FileHandle _file; + int _mode; + int _field1C; +public: + TTstringNode(); + + /** + * Find a string node in the linked chain by name + */ + TTstringNode *findByName(const TTstring &str, int mode); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_STRING_NODE_H */ diff --git a/engines/titanic/true_talk/tt_synonym.cpp b/engines/titanic/true_talk/tt_synonym.cpp new file mode 100644 index 0000000000..0f56c5cb22 --- /dev/null +++ b/engines/titanic/true_talk/tt_synonym.cpp @@ -0,0 +1,87 @@ +/* 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 "titanic/true_talk/tt_synonym.h" + +namespace Titanic { + +TTsynonym::TTsynonym() : TTstringNode(), _file(HANDLE_STDIN), + _mode(0), _field1C(0) { +} + +TTsynonym::TTsynonym(const TTsynonym *src) : TTstringNode(), + _mode(0), _field1C(0) { + _string = src->_string; + initialize(src->_mode); + _file = src->_file; +} + +TTsynonym::TTsynonym(int mode, const char *str, FileHandle file) : + TTstringNode(), _mode(0), _field1C(0) { + _string = str; + initialize(mode); + _file = file; +} + +TTsynonym::TTsynonym(int mode, TTstring *str) : TTstringNode() { + _string = *str; + initialize(mode); +} + +TTsynonym *TTsynonym::copyFrom(const TTsynonym *src) { + if (src->_field1C) { + _field1C = 5; + } else { + _field1C = 0; + if (src != this) + _string = src->_string; + } + + return this; +} + +int TTsynonym::save(SimpleFile *file) { + for (TTstringNode *synP = this; synP; synP = static_cast<TTstringNode *>(synP->_nextP)) { + file->writeFormat("%s", " 0 "); + synP->_string.save(file); + file->writeFormat("%c", ' '); + + if (synP->_mode) { + file->writeFormat("%1.0d", synP->_mode); + } else { + file->writeFormat("%c", '0'); + } + + file->writeFormat("%c", ' '); + + if (synP->_file) { + file->writeFormat("%2.0d", synP->_file); + } else { + file->writeFormat("%c", ' '); + } + file->writeFormat("%c", '\n'); + } + + return 0; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_synonym.h b/engines/titanic/true_talk/tt_synonym.h new file mode 100644 index 0000000000..d5dc2be09e --- /dev/null +++ b/engines/titanic/true_talk/tt_synonym.h @@ -0,0 +1,56 @@ +/* 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 TITANIC_TT_SYNONYM_H +#define TITANIC_TT_SYNONYM_H + +#include "titanic/true_talk/tt_string_node.h" +#include "titanic/support/simple_file.h" + +namespace Titanic { + +class TTsynonym : public TTstringNode { +public: + TTstring _string; + FileHandle _file; + int _mode; + int _field1C; +public: + TTsynonym(); + TTsynonym(const TTsynonym *src); + TTsynonym(int mode, const char *str, FileHandle file); + TTsynonym(int mode, TTstring *str); + + /** + * Copies data from one synonym to another + */ + TTsynonym *copyFrom(const TTsynonym *src); + + /** + * Save data for the synonym to file + */ + int save(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_SYNONYM_H */ diff --git a/engines/titanic/true_talk/tt_talker.cpp b/engines/titanic/true_talk/tt_talker.cpp new file mode 100644 index 0000000000..61443a4835 --- /dev/null +++ b/engines/titanic/true_talk/tt_talker.cpp @@ -0,0 +1,52 @@ +/* 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 "titanic/true_talk/tt_talker.h" +#include "titanic/messages/messages.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +void TTtalker::speechStarted(const CString &dialogueStr, uint dialogueId, uint soundId) { + _dialogueId = dialogueId; + + CTrueTalkNotifySpeechStartedMsg msg(soundId, dialogueId, 0); + msg.execute(_npc, nullptr, MSGFLAG_BREAK_IF_HANDLED); +} + +TTtalker::~TTtalker() { + CPetControl *petControl = _npc->getPetControl(); + if (petControl) + // Add in final line + petControl->convAddLine(_line); + + // Notify the end of the speech + CTrueTalkNotifySpeechEndedMsg endedMsg(_field24, _dialogueId); + endedMsg.execute(_npc, nullptr, MSGFLAG_BREAK_IF_HANDLED); +} + +void TTtalker::endSpeech(int val) { + _done = true; + _field24 = val; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_talker.h b/engines/titanic/true_talk/tt_talker.h new file mode 100644 index 0000000000..636eb0c022 --- /dev/null +++ b/engines/titanic/true_talk/tt_talker.h @@ -0,0 +1,65 @@ +/* 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 TITANIC_TT_TALKER_H +#define TITANIC_TT_TALKER_H + +#include "titanic/core/list.h" +#include "titanic/npcs/true_talk_npc.h" +#include "titanic/support/string.h" + +namespace Titanic { + +class CTrueTalkManager; + +class TTtalker : public ListItem { +public: + CTrueTalkManager *_owner; + CTrueTalkNPC *_npc; + CString _line; + int _dialogueId; + int _field24; + int _done; +public: + TTtalker() : _owner(nullptr), _npc(nullptr), + _dialogueId(0), _field24(0), _done(0) {} + TTtalker(CTrueTalkManager *owner, CTrueTalkNPC *npc) : + _owner(owner), _npc(npc), _dialogueId(0), _field24(0), _done(0) {} + ~TTtalker(); + + /** + * Start a new speech + */ + void speechStarted(const CString &dialogueStr, uint dialogueId, uint soundId); + + /** + * End the speech + */ + void endSpeech(int val); +}; + +class TTtalkerList : public List<TTtalker> { +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_TALKER_H */ diff --git a/engines/titanic/true_talk/tt_title_script.cpp b/engines/titanic/true_talk/tt_title_script.cpp new file mode 100644 index 0000000000..85b56d0e1e --- /dev/null +++ b/engines/titanic/true_talk/tt_title_script.cpp @@ -0,0 +1,31 @@ +/* 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 "titanic/true_talk/tt_title_script.h" + +namespace Titanic { + +TTTitleScript::TTTitleScript() : TTscriptBase(1, "", 0, "", 0, -1, -1, -1, 0), + _field50(0), _field5C(-1), _field60(0) { +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_title_script.h b/engines/titanic/true_talk/tt_title_script.h new file mode 100644 index 0000000000..f02e591c54 --- /dev/null +++ b/engines/titanic/true_talk/tt_title_script.h @@ -0,0 +1,43 @@ +/* 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 TITANIC_TT_TITLE_SCRIPT_H +#define TITANIC_TT_TITLE_SCRIPT_H + +#include "titanic/true_talk/tt_script_base.h" +#include "titanic/true_talk/tt_string.h" + +namespace Titanic { + +class TTTitleScript : public TTscriptBase { +private: + int _field50; + TTstring _string1; + int _field5C; + int _field60; +public: + TTTitleScript(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_TITLE_SCRIPT_H */ diff --git a/engines/titanic/true_talk/tt_vocab.cpp b/engines/titanic/true_talk/tt_vocab.cpp new file mode 100644 index 0000000000..08d6e9e1a7 --- /dev/null +++ b/engines/titanic/true_talk/tt_vocab.cpp @@ -0,0 +1,557 @@ +/* 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/file.h"
+#include "titanic/true_talk/tt_vocab.h"
+#include "titanic/true_talk/tt_adj.h"
+#include "titanic/true_talk/tt_action.h"
+#include "titanic/true_talk/tt_adj.h"
+#include "titanic/true_talk/tt_major_word.h"
+#include "titanic/true_talk/tt_picture.h"
+#include "titanic/true_talk/tt_pronoun.h"
+#include "titanic/titanic.h"
+
+namespace Titanic {
+
+TTvocab::TTvocab(int val): _headP(nullptr), _tailP(nullptr), _word(nullptr),
+ _fieldC(0), _field10(0), _vocabMode(val) {
+ load("STVOCAB.TXT");
+}
+
+TTvocab::~TTvocab() {
+ if (_headP) {
+ _headP->deleteSiblings();
+ delete _headP;
+ _headP = _tailP = nullptr;
+ }
+}
+
+int TTvocab::load(const CString &name) {
+ SimpleFile *file = g_vm->_exeResources._owner->openResource(name);
+ int result = 0;
+ bool skipFlag;
+
+ while (!result && !file->eos()) {
+ skipFlag = false;
+ WordClass wordClass = (WordClass)file->readNumber();
+ TTstring space(" ");
+
+ switch (wordClass) {
+ case WC_UNKNOWN: {
+ if (_word)
+ result = _word->readSyn(file);
+ skipFlag = true;
+ break;
+ }
+
+ case WC_ACTION: {
+ TTaction *word = new TTaction(space, WC_UNKNOWN, 0, 0, 0);
+ result = word->load(file);
+ _word = word;
+ break;
+ }
+
+ case WC_THING: {
+ TTpicture *word = new TTpicture(space, WC_UNKNOWN, 0, 0, 0, 0, 0);
+ result = word->load(file);
+ _word = word;
+ break;
+ }
+
+ case WC_ABSTRACT:
+ case WC_ADVERB: {
+ TTmajorWord *word = new TTmajorWord(space, WC_UNKNOWN, 0, 0);
+ result = word->load(file, wordClass);
+ _word = word;
+ break;
+ }
+
+ case WC_ARTICLE:
+ case WC_CONJUNCTION:
+ case WC_PREPOSITION: {
+ TTword *word = new TTword(space, WC_UNKNOWN, 0);
+ result = word->load(file, wordClass);
+ _word = word;
+ break;
+ }
+
+ case WC_ADJECTIVE: {
+ TTadj *word = new TTadj(space, WC_UNKNOWN, 0, 0, 0);
+ result = word->load(file);
+ _word = word;
+ break;
+ }
+
+ case WC_PRONOUN: {
+ TTpronoun *word = new TTpronoun(space, WC_UNKNOWN, 0, 0, 0);
+ result = word->load(file);
+ _word = word;
+ break;
+ }
+
+ default:
+ result = 4;
+ break;
+ }
+
+ if (!skipFlag && _word) {
+ if (result) {
+ // Something wrong occurred, so delete word
+ delete _word;
+ _word = nullptr;
+ } else {
+ // Add the word to the master vocab list
+ addWord(_word);
+ }
+ }
+ }
+
+ // Close resource and return result
+ delete file;
+ return result;
+}
+
+void TTvocab::addWord(TTword *word) {
+ TTword *existingWord = findWord(word->_text);
+
+ if (existingWord) {
+ if (word->_synP) {
+ // Move over the synonym
+ existingWord->appendNode(word->_synP);
+ word->_synP = nullptr;
+ }
+
+ _word = nullptr;
+ if (word)
+ delete word;
+ } else if (_tailP) {
+ _tailP->_nextP = word;
+ _tailP = word;
+ } else {
+ if (!_headP)
+ _headP = word;
+
+ _tailP = word;
+ }
+}
+
+TTword *TTvocab::findWord(const TTstring &str) {
+ TTsynonym *tempNode = new TTsynonym();
+ bool flag = false;
+ TTword *word = _headP;
+
+ while (word && !flag) {
+ if (_vocabMode != 3 || strcmp(word->c_str(), str)) {
+ if (word->findSynByName(str, tempNode, _vocabMode))
+ flag = true;
+ else
+ word = word->_nextP;
+ } else {
+ flag = true;
+ }
+ }
+
+ delete tempNode;
+ return word;
+}
+
+TTword *TTvocab::getWord(TTstring &str, TTword **srcWord) const {
+ TTword *word = getPrimeWord(str, srcWord);
+
+ if (!word) {
+ TTstring tempStr(str);
+ if (tempStr.size() > 2) {
+ word = getSuffixedWord(tempStr);
+
+ if (!word)
+ word = getPrefixedWord(tempStr);
+ }
+ }
+
+ return word;
+}
+
+TTword *TTvocab::getPrimeWord(TTstring &str, TTword **srcWord) const {
+ TTsynonym tempSyn;
+ char c = str.charAt(0);
+ TTword *newWord = nullptr;
+ TTword *vocabP;
+
+ if (!Common::isDigit(c)) {
+ vocabP = _headP;
+ newWord = new TTword(str, WC_ABSTRACT, 300);
+ } else {
+ for (vocabP = _headP; vocabP && !newWord; vocabP = vocabP->_nextP) {
+ if (_vocabMode == 3 && !strcmp(str.c_str(), vocabP->c_str())) {
+ newWord = vocabP->copy();
+ newWord->_nextP = nullptr;
+ newWord->setSyn(nullptr);
+ } else if (vocabP->findSynByName(str, &tempSyn, _vocabMode)) {
+ // Create a copy of the word and the found synonym
+ TTsynonym *newSyn = new TTsynonym(tempSyn);
+ newSyn->_nextP = newSyn->_priorP = nullptr;
+ newWord = vocabP->copy();
+ newWord->_nextP = nullptr;
+ newWord->setSyn(newSyn);
+ }
+ }
+ }
+
+ if (srcWord)
+ // Pass out the pointer to the original word
+ *srcWord = vocabP;
+
+ // Return the new copy of the word
+ return newWord;
+}
+
+TTword *TTvocab::getSuffixedWord(TTstring &str) const {
+ TTstring tempStr(str);
+ TTword *word = nullptr;
+
+ if (tempStr.hasSuffix("s")) {
+ tempStr.deleteSuffix(1);
+ word = getPrimeWord(tempStr);
+
+ if (!word) {
+ if (!tempStr.hasSuffix("e")) {
+ tempStr = str;
+ } else {
+ tempStr.deleteLastChar();
+ word = getPrimeWord(tempStr);
+ }
+ }
+
+ } else if (tempStr.hasSuffix("ing")) {
+ tempStr.deleteSuffix(3);
+ word = getPrimeWord(tempStr);
+
+ if (word) {
+ if (word->_wordClass == 1) {
+ delete word;
+ word = nullptr;
+ } else {
+ delete word;
+ word = new TTadj(str, WC_ADJECTIVE, 0, 0, 0);
+ }
+ } else {
+ tempStr += "e";
+ word = getPrimeWord(tempStr);
+
+ if (word) {
+ if (word->_wordClass != 1) {
+ delete word;
+ word = new TTadj(str, WC_ADJECTIVE, 0, 0, 0);
+ }
+ } else {
+ tempStr.deleteSuffix(2);
+ word = getPrimeWord(tempStr);
+
+ if (word) {
+ if (word->_wordClass != 1) {
+ delete word;
+ word = new TTadj(str, WC_ADJECTIVE, 0, 0, 0);
+ }
+ } else {
+ tempStr = str;
+ }
+ }
+ }
+
+ } else if (tempStr.hasSuffix("ed")) {
+ tempStr.deleteSuffix(1);
+ word = getPrimeWord(tempStr);
+
+ if (!word) {
+ tempStr.deleteSuffix(1);
+ word = getPrimeWord(tempStr);
+ }
+
+ if (word) {
+ if (word->_wordClass == WC_ACTION) {
+ static_cast<TTaction *>(word)->setVal(1);
+ }
+ } else {
+ tempStr = str;
+ }
+
+ } else if (tempStr.hasSuffix("ly")) {
+ tempStr.deleteSuffix(2);
+ word = getPrimeWord(tempStr);
+
+ if (word) {
+ delete word;
+ word = new TTword(str, WC_ADVERB, 0);
+ } else {
+ tempStr = str;
+ }
+
+ } else if (tempStr.hasSuffix("er")) {
+ tempStr.deleteSuffix(1);
+ word = getPrimeWord(tempStr);
+
+ if (word) {
+ if (word->_wordClass == WC_ADJECTIVE) {
+ TTadj *adj = static_cast<TTadj *>(word);
+ int val1 = word->proc15();
+ int val2 = word->proc15();
+
+ if (val2 < 5) {
+ if (--val1 > 0) {
+ adj->adjFn1(val1);
+ }
+ } else {
+ if (++val1 < 11) {
+ adj->adjFn1(val1);
+ }
+ }
+ }
+ } else {
+ tempStr.deleteSuffix(1);
+ word = getPrimeWord(tempStr);
+
+ if (word) {
+ if (word->_wordClass == WC_ADJECTIVE) {
+ TTadj *adj = static_cast<TTadj *>(word);
+ int val1 = word->proc15();
+ int val2 = word->proc15();
+
+ if (val2 < 5) {
+ if (--val1 > 0) {
+ adj->adjFn1(val1);
+ }
+ } else {
+ if (++val1 < 11) {
+ adj->adjFn1(val1);
+ }
+ }
+ }
+ } else {
+ tempStr.deleteSuffix(1);
+ word = getPrimeWord(tempStr);
+
+ if (word && word->_wordClass == WC_ADJECTIVE) {
+ TTadj *adj = static_cast<TTadj *>(word);
+ int val1 = word->proc15();
+ int val2 = word->proc15();
+
+ if (val2 < 5) {
+ if (--val1 > 0) {
+ adj->adjFn1(val1);
+ }
+ } else {
+ if (++val1 < 11) {
+ adj->adjFn1(val1);
+ }
+ }
+ }
+ }
+ }
+
+ } else if (tempStr.hasSuffix("est")) {
+ tempStr.deleteSuffix(2);
+ word = getPrimeWord(tempStr);
+
+ if (word) {
+ if (word->_wordClass == WC_ADJECTIVE) {
+ TTadj *adj = static_cast<TTadj *>(word);
+ int val1 = word->proc15();
+ int val2 = word->proc15();
+
+ if (val2 < 5) {
+ if (--val1 > 0) {
+ adj->adjFn1(val1);
+ }
+ } else {
+ if (++val1 < 11) {
+ adj->adjFn1(val1);
+ }
+ }
+ }
+ } else {
+ tempStr.deleteSuffix(1);
+ word = getPrimeWord(tempStr);
+
+ if (word) {
+ if (word->_wordClass == WC_ADJECTIVE) {
+ TTadj *adj = static_cast<TTadj *>(word);
+ int val1 = word->proc15();
+ int val2 = word->proc15();
+
+ if (val2 < 5) {
+ if (--val1 > 0) {
+ adj->adjFn1(val1);
+ }
+ } else {
+ if (++val1 < 11) {
+ adj->adjFn1(val1);
+ }
+ }
+ }
+ } else {
+ tempStr.deleteSuffix(1);
+ word = getPrimeWord(tempStr);
+
+ if (word) {
+ TTadj *adj = static_cast<TTadj *>(word);
+ int val1 = word->proc15();
+ int val2 = word->proc15();
+
+ if (val2 < 5) {
+ if (--val1 > 0) {
+ adj->adjFn1(val1);
+ }
+ } else {
+ if (++val1 < 11) {
+ adj->adjFn1(val1);
+ }
+ }
+ }
+ }
+ }
+
+ } else if (tempStr.hasSuffix("s*")) {
+ tempStr.deleteSuffix(2);
+ word = getPrimeWord(tempStr);
+
+ if (word) {
+ if (word->_wordClass == WC_PRONOUN || word->_wordClass == WC_ADVERB) {
+ delete word;
+ TTstring isStr("is");
+ word = getPrimeWord(isStr);
+ } else {
+ switch (word->_id) {
+ case 200:
+ if (word->proc10() == 2) {
+ delete word;
+ word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 5);
+ } else if (word->proc10() == 1) {
+ delete word;
+ word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 4);
+ }
+ break;
+
+ case 201:
+ delete word;
+ word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 5);
+ break;
+
+ case 202:
+ case 203:
+ if (word->proc10() == 2) {
+ delete word;
+ word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 5);
+ } else {
+ int val = word->proc10() == 1 ? 0 : 4;
+ delete word;
+ word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, val);
+ }
+ break;
+
+ case 204:
+ delete word;
+ word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 6);
+ break;
+
+ default:
+ delete word;
+ word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 0);
+ break;
+ }
+ }
+ }
+ }
+
+ if (word)
+ word->setSynStr(str);
+
+ return word;
+}
+
+TTword *TTvocab::getPrefixedWord(TTstring &str) const {
+ TTstring tempStr(str);
+ TTword *word = nullptr;
+ int prefixLen = 0;
+
+ if (tempStr.hasPrefix("pre")) {
+ prefixLen = 3;
+ } else if (tempStr.hasPrefix("re") || tempStr.hasPrefix("co")) {
+ prefixLen = 2;
+ } else if (tempStr.hasPrefix("inter") || tempStr.hasPrefix("multi")) {
+ prefixLen = 5;
+ } else if (tempStr.hasPrefix("over") || tempStr.hasPrefix("post") || tempStr.hasPrefix("self")) {
+ prefixLen = 4;
+ }
+
+ if (prefixLen) {
+ // Known prefix found, so scan for word without prefix
+ tempStr.deletePrefix(prefixLen);
+ word = getPrimeWord(tempStr);
+ if (word)
+ tempStr = str;
+
+ } else if (tempStr.hasPrefix("anti") || tempStr.hasPrefix("counter")) {
+ prefixLen = tempStr[0] == 'a' ? 4 : 7;
+
+ tempStr.deletePrefix(prefixLen);
+ word = getPrimeWord(tempStr);
+ if (!word)
+ tempStr = str;
+ else if (word->_wordClass == 8) {
+ delete word;
+ word = nullptr;
+ }
+
+ } else if (tempStr.hasPrefix("hyper") || tempStr.hasPrefix("super") ||
+ tempStr.hasPrefix("ultra")) {
+ tempStr.deletePrefix(5);
+ word = getPrimeWord(tempStr);
+
+ if (!word)
+ tempStr = str;
+ else if (word->_wordClass == WC_ADJECTIVE) {
+ TTadj *adj = static_cast<TTadj *>(word);
+ int val1 = word->proc15();
+ int val2 = word->proc15();
+
+ if (val2 < 5) {
+ if (--val1 > 0)
+ adj->adjFn1(val1);
+ } else if (++val1 < 11) {
+ adj->adjFn1(val1);
+ }
+ }
+ }
+
+ if (word) {
+ // Set the original word on either the found word or synonym
+ if (word->hasSynonyms())
+ word->setSynStr(str);
+ else
+ word->_text = str;
+ }
+
+ delete tempStr;
+ return word;
+}
+
+} // End of namespace Titanic
diff --git a/engines/titanic/true_talk/tt_vocab.h b/engines/titanic/true_talk/tt_vocab.h new file mode 100644 index 0000000000..fc7ee2e102 --- /dev/null +++ b/engines/titanic/true_talk/tt_vocab.h @@ -0,0 +1,96 @@ +/* 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 TITANIC_ST_VOCAB_H +#define TITANIC_ST_VOCAB_H + +#include "titanic/support/string.h" +#include "titanic/true_talk/tt_string.h" +#include "titanic/true_talk/tt_word.h" + +namespace Titanic { + +class TTvocab { +private: + TTword *_headP; + TTword *_tailP; + TTword *_word; + int _fieldC; + int _field10; + int _vocabMode; +private: + /** + * Load the vocab data + */ + int load(const CString &name); + + /** + * Adds a specified word to the vocab list + */ + void addWord(TTword *word); + + /** + * Scans the vocab list for an existing word match + */ + TTword *findWord(const TTstring &str); + + /** + * Scans the vocab list for a word with a synonym matching the passed string. + * If found, creates a new word instance that only has the matching synonym + * linked to it. + * @param str Word text to scan for + * @param srcWord Optional pointer to store the original word match was found on + * @returns A new word instance if a match if found, or null if not + */ + TTword *getPrimeWord(TTstring &str, TTword **srcWord = nullptr) const; + + /** + * Checks the passed word for common suffixes, like 's', 'ing', etc. and, if found, + * checks for a word match for the base word without the suffix. + * @param str Word to check + * @returns New word instance for found match, or nullptr otherwise + */ + TTword *getSuffixedWord(TTstring &str) const; + + /** + * Checks the passed word for common prefixes, and checks for a word + * match for the word without the given prefix + * @param str Word to check + * @returns New word instance for found match, or nullptr otherwise + */ + TTword *getPrefixedWord(TTstring &str) const; +public: + TTvocab(int val); + ~TTvocab(); + + /** + * Gets a matching word from the vocab list given a passed string + * @param str Word text to scan for + * @param srcWord Optional pointer to store the original word match was found on + * @returns A new word instance if a match if found, or null if not + */ + TTword *getWord(TTstring &str, TTword **srcWord = nullptr) const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ST_VOCAB_H */ diff --git a/engines/titanic/true_talk/tt_word.cpp b/engines/titanic/true_talk/tt_word.cpp new file mode 100644 index 0000000000..df6ee5c7bc --- /dev/null +++ b/engines/titanic/true_talk/tt_word.cpp @@ -0,0 +1,226 @@ +/* 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 "titanic/true_talk/tt_word.h" +#include "titanic/true_talk/tt_string_node.h" +#include "titanic/titanic.h" + +namespace Titanic { + +TTword::TTword(const TTstring &str, WordClass wordClass, int id) : _text(str), + _wordClass(wordClass), _id(id), _tag(0), _field24(0), + _field28(0), _synP(nullptr), _nextP(nullptr) { + _status = str.getStatus() == SS_VALID ? SS_VALID : SS_5; +} + +TTword::TTword(const TTword *src) { + if (src->getStatus() != SS_VALID) { + _status = SS_5; + return; + } + + _text = src->_text; + _wordClass = src->_wordClass; + _id = src->_id; + _tag = src->_tag; + _synP = nullptr; + + TTsynonym *priorSyn = nullptr; + for (TTsynonym *synP = _synP; synP && !_status;) { + TTsynonym *newSyn = new TTsynonym(synP); + if (!newSyn) { + _status = SS_7; + } else { + newSyn->_priorP = priorSyn; + newSyn->_nextP = nullptr; + + if (priorSyn) { + priorSyn->_nextP = newSyn; + } else { + _synP = newSyn; + } + + priorSyn = newSyn; + } + } + + _nextP = src->_nextP; + _field24 = src->_field24; + _field28 = src->_field28; +} + +TTword::~TTword() { + if (_synP) { + _synP->deleteSiblings(); + delete _synP; + } +} + +void TTword::deleteSiblings() { + while (_nextP) { + TTword *next = _nextP; + _nextP = next->_nextP; + delete next; + } +} + +int TTword::readSyn(SimpleFile *file) { + CString str; + int mode, val1; + + if (!file->scanf("%s %d %d", &str, &mode, &val1)) + return 8; + if (!testFileHandle(file)) + return 5; + + // Create new synanym node + TTsynonym *synNode = new TTsynonym(mode, str.c_str(), (FileHandle)val1); + + if (_synP) { + // A synonym already exists, so add new one as a tail + // at the end of the linked list of synonyms + _synP->addToTail(synNode); + } else { + // Very first synonym, so set it + _synP = synNode; + } + + return 0; +} + +void TTword::setSyn(TTsynonym *synP) { + if (_synP) { + _synP->deleteSiblings(); + delete _synP; + } + + _synP = synP; +} + +int TTword::setSynStr(TTstring &str) { + if (str.empty()) + return 4; + + TTstring *newStr = new TTstring(str); + TTsynonym *newSyn = new TTsynonym(4, newStr); + setSyn(newSyn); + return 0; +} + +void TTword::appendNode(TTsynonym *node) { + if (_synP) + _synP->addToTail(node); + else + _synP = node; +} + +int TTword::load(SimpleFile *file, WordClass wordClass) { + CString str1, str2; + int id; + + if (file->scanf("%d %s %s", &id, &str1, &str2)) { + _text = str1; + _id = id; + _tag = readNumber(str2.c_str()); + _wordClass = wordClass; + return 0; + } else { + return 3; + } +} + +uint TTword::readNumber(const char *str) { + uint numValue = *str; + if (*str == '0') { + numValue = MKTAG('Z', 'Z', 'Z', '['); + } else { + ++str; + for (int idx = 0; idx < 3; ++idx, ++str) + numValue = (numValue << 8) + *str; + } + + return numValue; +} + +bool TTword::testFileHandle(FileHandle file) const { + if (g_vm->_exeResources.is18Equals(3)) + return true; + + // TODO: Figure out why original compares passed file handle against specific values + return true; +} + +bool TTword::findSynByName(const TTstring &str, TTsynonym *dest, int mode) const { + if (!_synP) + return false; + + const TTsynonym *synP = static_cast<const TTsynonym *>(_synP->findByName(str, mode)); + if (synP) { + dest->copyFrom(synP); + dest->_priorP = nullptr; + dest->_nextP = nullptr; + + return true; + } else { + return false; + } +} + +bool TTword::compareTo(const char *str) const { + return _text == str; +} + +TTword *TTword::copy() const { + return new TTword(this); +} + +FileHandle TTword::getSynFile() const { + return _synP ? _synP->_file : HANDLE_STDIN; +} + +bool TTword::checkSynFile(FileHandle file) const { + return _synP && _synP->_file == file; +} + +void TTword::setSynFile(FileHandle file) { + if (_synP && testFileHandle(file)) + _synP->_file = file; +} + +TTstringStatus TTword::getChainStatus() const { + for (const TTword *word = this; word; word = word->_nextP) { + if (word->getStatus()) + return word->getStatus(); + } + + return SS_VALID; +} + +TTword *TTword::copyWords() { + TTword *result = copy(); + for (TTword *word = result; word; word = word->_nextP) + word->_nextP = word->_nextP->copy(); + + return result; +} + +} // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_word.h b/engines/titanic/true_talk/tt_word.h new file mode 100644 index 0000000000..7fd61c38ac --- /dev/null +++ b/engines/titanic/true_talk/tt_word.h @@ -0,0 +1,216 @@ +/* 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 TITANIC_TT_WORD_H +#define TITANIC_TT_WORD_H + +#include "titanic/support/simple_file.h" +#include "titanic/true_talk/tt_string.h" +#include "titanic/true_talk/tt_synonym.h" + +namespace Titanic { + +/** + * Types of words + */ +enum WordClass { + WC_UNKNOWN = 0, WC_ACTION = 1, WC_THING = 2, WC_ABSTRACT = 3, + WC_ARTICLE = 4, WC_CONJUNCTION = 5, WC_PRONOUN = 6, + WC_PREPOSITION = 7, WC_ADJECTIVE = 8, WC_ADVERB = 9 +}; + +class TTword { +protected: + TTstringStatus _status; + int _field24; + int _field28; +protected: + /** + * Read in a number + */ + uint readNumber(const char *str); + + bool testFileHandle(SimpleFile *file) const { return true; } + bool testFileHandle(FileHandle resHandle) const; +public: + TTword *_nextP; + TTsynonym *_synP; + TTstring _text; + WordClass _wordClass; + int _id; + uint _tag; +public: + TTword(const TTstring &str, WordClass wordClass, int val2); + TTword(const TTword *src); + virtual ~TTword(); + + /** + * Delete any following words chained to the word + */ + void deleteSiblings(); + + /** + * Read in a synonym for the given word + */ + int readSyn(SimpleFile *file); + + /** + * Set a new synonym for the word + */ + void setSyn(TTsynonym *synP); + + /** + * Set a new synonym string + */ + int setSynStr(TTstring &str); + + /** + * Returns true if synonyms have been set for the word + */ + bool hasSynonyms() const { return _synP != nullptr; } + + /** + * Either sets the first synonym for a word, or adds it to an existing one + */ + void appendNode(TTsynonym *node); + + /** + * Load the word + */ + int load(SimpleFile *file, WordClass wordClass); + + /** + * Finds a synonym in the word by name, if one exists + * @param str Name to search for + * @param dest Destination synonym instance to copy match into + * @returns Returns true if a match was found + */ + bool findSynByName(const TTstring &str, TTsynonym *dest, int mode) const; + + const char *c_str() const { return _text.c_str(); } + operator const char *() const { return c_str(); } + + /** + * Return the text of the word + */ + const TTstring getText() { return _text; } + + /** + * Compares the word's text to a passed string + */ + bool compareTo(const char *str) const; + + /** + * Compares the word's text to a passed string + */ + bool compareTo(TTstring *str) const { + return compareTo(str->c_str()); + } + + /** + * Return the status of the word + */ + TTstringStatus getStatus() const { return _status; } + + /** + * Returns true if the word is in a valid state + */ + bool isValid() const { return _status == SS_VALID; } + + /** + * Return the status of the entire word chain + */ + TTstringStatus getChainStatus() const; + + /** + * Returns true if the word is of the specified class + */ + bool isClass(WordClass wordClass) const { return _wordClass == wordClass; } + + /** + * Copy the word and any attached to it + */ + TTword *copyWords(); + + /** + * Creates a copy of the word + */ + virtual TTword *copy() const; + + virtual bool proc2(int val) const { return false; } + virtual int proc3() const { return -1; } + virtual void proc4() {} + virtual void proc5() {} + + /** + * Checks whether the word's tag is a known type + */ + virtual bool checkTag() const { return false; } + + /** + * Compare the word's tag to a given tag value + */ + virtual bool compareTagTo(uint tag) const { return false; } + + /** + * Return the tag associated with the word + */ + virtual uint getTag() const { return 0; } + + virtual bool proc9(int val) const { return false; } + virtual int proc10() const { return 0; } + virtual void proc11() {} + virtual bool proc12(int val) const { return false; } + virtual int proc13() const { return 0; } + virtual bool proc14(int val) const { return false; } + virtual int proc15() const { return -1; } + virtual bool proc16() const { return false; } + virtual bool proc17() const { return false; } + virtual bool proc18() const { return false; } + virtual bool comparePronounTo(int val) const { return false; } + virtual int proc20() const { return 0; } + + /** + * Returns the file associated with the word's first synonym + */ + virtual FileHandle getSynFile() const; + + /** + * Checks whether the file associated with the word's first + * synonym matches the specified file + */ + virtual bool checkSynFile(FileHandle file) const; + + /** + * Sets the file associated with a synonym + */ + virtual void setSynFile(FileHandle file); + + /** + * Dumps data associated with the word to file + */ + virtual int save(SimpleFile *file) const { return 0; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TT_WORD_H */ diff --git a/engines/wage/design.cpp b/engines/wage/design.cpp index 2bfea9df7d..86b325e2b9 100644 --- a/engines/wage/design.cpp +++ b/engines/wage/design.cpp @@ -47,20 +47,20 @@ #include "graphics/managed_surface.h" #include "graphics/primitives.h" +#include "graphics/macgui/macwindowmanager.h" -#include "wage/macwindowmanager.h" #include "wage/design.h" namespace Wage { struct PlotData { Graphics::ManagedSurface *surface; - Patterns *patterns; + Graphics::MacPatterns *patterns; uint fillType; int thickness; Design *design; - PlotData(Graphics::ManagedSurface *s, Patterns *p, int f, int t, Design *d) : + PlotData(Graphics::ManagedSurface *s, Graphics::MacPatterns *p, int f, int t, Design *d) : surface(s), patterns(p), fillType(f), thickness(t), design(d) {} }; @@ -85,7 +85,7 @@ Design::~Design() { delete _surface; } -void Design::paint(Graphics::ManagedSurface *surface, Patterns &patterns, int x, int y) { +void Design::paint(Graphics::ManagedSurface *surface, Graphics::MacPatterns &patterns, int x, int y) { bool needRender = false; if (_surface == NULL) { @@ -141,7 +141,7 @@ void Design::paint(Graphics::ManagedSurface *surface, Patterns &patterns, int x, } } -void Design::render(Patterns &patterns) { +void Design::render(Graphics::MacPatterns &patterns) { Common::MemoryReadStream in(_data, _len); bool needRender = true; @@ -265,7 +265,7 @@ void drawPixelPlain(int x, int y, int color, void *data) { } void Design::drawRect(Graphics::ManagedSurface *surface, Common::ReadStream &in, - Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType) { + Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType) { int16 y1 = in.readSint16BE(); int16 x1 = in.readSint16BE(); int16 y2 = in.readSint16BE(); @@ -294,7 +294,7 @@ void Design::drawRect(Graphics::ManagedSurface *surface, Common::ReadStream &in, } void Design::drawRoundRect(Graphics::ManagedSurface *surface, Common::ReadStream &in, - Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType) { + Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType) { int16 y1 = in.readSint16BE(); int16 x1 = in.readSint16BE(); int16 y2 = in.readSint16BE(); @@ -320,7 +320,7 @@ void Design::drawRoundRect(Graphics::ManagedSurface *surface, Common::ReadStream } void Design::drawPolygon(Graphics::ManagedSurface *surface, Common::ReadStream &in, - Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType) { + Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType) { byte ignored = in.readSint16BE(); // ignored @@ -397,7 +397,7 @@ void Design::drawPolygon(Graphics::ManagedSurface *surface, Common::ReadStream & } void Design::drawOval(Graphics::ManagedSurface *surface, Common::ReadStream &in, - Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType) { + Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType) { int16 y1 = in.readSint16BE(); int16 x1 = in.readSint16BE(); int16 y2 = in.readSint16BE(); @@ -501,11 +501,11 @@ void Design::drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadS tmp.free(); } -void Design::drawRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int thickness, int color, Patterns &patterns, byte fillType) { +void Design::drawRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType) { drawRect(surface, rect.left, rect.top, rect.right, rect.bottom, thickness, color, patterns, fillType); } -void Design::drawRect(Graphics::ManagedSurface *surface, int x1, int y1, int x2, int y2, int thickness, int color, Patterns &patterns, byte fillType) { +void Design::drawRect(Graphics::ManagedSurface *surface, int x1, int y1, int x2, int y2, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType) { PlotData pd(surface, &patterns, fillType, thickness, nullptr); Graphics::drawLine(x1, y1, x2, y1, kColorBlack, drawPixel, &pd); @@ -515,26 +515,26 @@ void Design::drawRect(Graphics::ManagedSurface *surface, int x1, int y1, int x2, } -void Design::drawFilledRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int color, Patterns &patterns, byte fillType) { +void Design::drawFilledRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int color, Graphics::MacPatterns &patterns, byte fillType) { PlotData pd(surface, &patterns, fillType, 1, nullptr); for (int y = rect.top; y <= rect.bottom; y++) Graphics::drawHLine(rect.left, rect.right, y, color, drawPixel, &pd); } -void Design::drawFilledRoundRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int arc, int color, Patterns &patterns, byte fillType) { +void Design::drawFilledRoundRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int arc, int color, Graphics::MacPatterns &patterns, byte fillType) { PlotData pd(surface, &patterns, fillType, 1, nullptr); Graphics::drawRoundRect(rect, arc, color, true, drawPixel, &pd); } -void Design::drawHLine(Graphics::ManagedSurface *surface, int x1, int x2, int y, int thickness, int color, Patterns &patterns, byte fillType) { +void Design::drawHLine(Graphics::ManagedSurface *surface, int x1, int x2, int y, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType) { PlotData pd(surface, &patterns, fillType, thickness, nullptr); Graphics::drawHLine(x1, x2, y, color, drawPixel, &pd); } -void Design::drawVLine(Graphics::ManagedSurface *surface, int x, int y1, int y2, int thickness, int color, Patterns &patterns, byte fillType) { +void Design::drawVLine(Graphics::ManagedSurface *surface, int x, int y1, int y2, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType) { PlotData pd(surface, &patterns, fillType, thickness, nullptr); Graphics::drawVLine(x, y1, y2, color, drawPixel, &pd); diff --git a/engines/wage/design.h b/engines/wage/design.h index 86225c9224..017fdfc14d 100644 --- a/engines/wage/design.h +++ b/engines/wage/design.h @@ -51,10 +51,15 @@ #include "common/memstream.h" #include "common/rect.h" -#include "wage/macwindowmanager.h" +#include "graphics/nine_patch.h" +#include "graphics/transparent_surface.h" + +#include "graphics/macgui/macwindowmanager.h" namespace Wage { +using namespace Graphics::MacGUIConstants; + class Design { public: Design(Common::SeekableReadStream *data); @@ -68,14 +73,14 @@ public: return _bounds; } - void paint(Graphics::ManagedSurface *canvas, Patterns &patterns, int x, int y); + void paint(Graphics::ManagedSurface *canvas, Graphics::MacPatterns &patterns, int x, int y); bool isPointOpaque(int x, int y); - static void drawRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int thickness, int color, Patterns &patterns, byte fillType); - static void drawRect(Graphics::ManagedSurface *surface, int x1, int y1, int x2, int y2, int thickness, int color, Patterns &patterns, byte fillType); - static void drawFilledRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int color, Patterns &patterns, byte fillType); - static void drawFilledRoundRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int arc, int color, Patterns &patterns, byte fillType); - static void drawHLine(Graphics::ManagedSurface *surface, int x1, int x2, int y, int thickness, int color, Patterns &patterns, byte fillType); - static void drawVLine(Graphics::ManagedSurface *surface, int x, int y1, int y2, int thickness, int color, Patterns &patterns, byte fillType); + static void drawRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType); + static void drawRect(Graphics::ManagedSurface *surface, int x1, int y1, int x2, int y2, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType); + static void drawFilledRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int color, Graphics::MacPatterns &patterns, byte fillType); + static void drawFilledRoundRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int arc, int color, Graphics::MacPatterns &patterns, byte fillType); + static void drawHLine(Graphics::ManagedSurface *surface, int x1, int x2, int y, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType); + static void drawVLine(Graphics::ManagedSurface *surface, int x, int y1, int y2, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType); bool isBoundsCalculation() { return _boundsCalculationMode; } void adjustBounds(int16 x, int16 y); @@ -88,15 +93,15 @@ private: bool _boundsCalculationMode; private: - void render(Patterns &patterns); + void render(Graphics::MacPatterns &patterns); void drawRect(Graphics::ManagedSurface *surface, Common::ReadStream &in, - Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType); + Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType); void drawRoundRect(Graphics::ManagedSurface *surface, Common::ReadStream &in, - Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType); + Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType); void drawPolygon(Graphics::ManagedSurface *surface, Common::ReadStream &in, - Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType); + Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType); void drawOval(Graphics::ManagedSurface *surface, Common::ReadStream &in, - Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType); + Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType); void drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadStream &in); }; diff --git a/engines/wage/detection.cpp b/engines/wage/detection.cpp index 8b8a6399a8..a27bfd7fde 100644 --- a/engines/wage/detection.cpp +++ b/engines/wage/detection.cpp @@ -99,7 +99,7 @@ SaveStateList WageMetaEngine::listSaves(const char *target) const { const uint32 WAGEflag = MKTAG('W','A','G','E'); Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::StringArray filenames; - char saveDesc[31]; + char saveDesc[128] = {0}; Common::String pattern = target; pattern += ".###"; @@ -113,9 +113,18 @@ SaveStateList WageMetaEngine::listSaves(const char *target) const { if (slotNum >= 0 && slotNum <= 999) { Common::InSaveFile *in = saveFileMan->openForLoading(*file); if (in) { + saveDesc[0] = 0; + in->seek(in->size() - 8); + uint32 offset = in->readUint32BE(); uint32 type = in->readUint32BE(); - if (type == WAGEflag) - in->read(saveDesc, 31); + if (type == WAGEflag) { + in->seek(offset); + + type = in->readUint32BE(); + if (type == WAGEflag) { + in->read(saveDesc, 127); + } + } saveList.push_back(SaveStateDescriptor(slotNum, saveDesc)); delete in; } @@ -142,11 +151,11 @@ void WageMetaEngine::removeSaveState(const char *target, int slot) const { namespace Wage { bool WageEngine::canLoadGameStateCurrently() { - return false; + return true; } bool WageEngine::canSaveGameStateCurrently() { - return false; + return true; } } // End of namespace Wage diff --git a/engines/wage/dialog.cpp b/engines/wage/dialog.cpp index 86080c9a6f..0a326817be 100644 --- a/engines/wage/dialog.cpp +++ b/engines/wage/dialog.cpp @@ -48,8 +48,9 @@ #include "common/system.h" #include "common/events.h" +#include "graphics/macgui/macwindowmanager.h" + #include "wage/wage.h" -#include "wage/macwindowmanager.h" #include "wage/design.h" #include "wage/gui.h" #include "wage/dialog.h" @@ -91,7 +92,7 @@ Dialog::~Dialog() { } const Graphics::Font *Dialog::getDialogFont() { - return _gui->_wm.getFont("Chicago-12", Graphics::FontManager::kBigGUIFont); + return _gui->_wm.getFont(_gui->_wm.getFontName(0, 12), Graphics::FontManager::kBigGUIFont); // Default is Chicago } void Dialog::paint() { diff --git a/engines/wage/entities.cpp b/engines/wage/entities.cpp index 43ac6c8cc7..3dcf37033a 100644 --- a/engines/wage/entities.cpp +++ b/engines/wage/entities.cpp @@ -48,6 +48,7 @@ #include "wage/wage.h" #include "wage/entities.h" #include "wage/design.h" +#include "wage/gui.h" #include "wage/script.h" #include "wage/world.h" @@ -80,6 +81,8 @@ Context::Context() { } Scene::Scene() { + _resourceId = 0; + _script = NULL; _design = NULL; _textBounds = NULL; @@ -104,6 +107,8 @@ Scene::Scene(Common::String name, Common::SeekableReadStream *data) { _classType = SCENE; _design = new Design(data); + _resourceId = 0; + _script = NULL; _textBounds = NULL; _fontSize = 0; @@ -142,65 +147,23 @@ void Scene::paint(Graphics::ManagedSurface *surface, int x, int y) { _design->paint(surface, *((WageEngine *)g_engine)->_world->_patterns, x, y); for (ObjList::const_iterator it = _objs.begin(); it != _objs.end(); ++it) { - debug(2, "paining Obj: %s, index: %d, type: %d", (*it)->_name.c_str(), (*it)->_index, (*it)->_type); + debug(2, "painting Obj: %s, index: %d, type: %d", (*it)->_name.c_str(), (*it)->_index, (*it)->_type); (*it)->_design->paint(surface, *((WageEngine *)g_engine)->_world->_patterns, x, y); } for (ChrList::const_iterator it = _chrs.begin(); it != _chrs.end(); ++it) { - debug(2, "paining Chr: %s", (*it)->_name.c_str()); + debug(2, "painting Chr: %s", (*it)->_name.c_str()); (*it)->_design->paint(surface, *((WageEngine *)g_engine)->_world->_patterns, x, y); } } -// Source: Apple IIGS Technical Note #41, "Font Family Numbers" -// http://apple2.boldt.ca/?page=til/tn.iigs.041 -static const char *const fontNames[] = { - "Chicago", // system font - "Geneva", // application font - "New York", - "Geneva", - - "Monaco", - "Venice", - "London", - "Athens", - - "San Francisco", - "Toronto", - NULL, - "Cairo", - "Los Angeles", // 12 - - "Zapf Dingbats", - "Bookman", - "Helvetica Narrow", - "Palatino", - NULL, - "Zapf Chancery", - NULL, - - "Times", // 20 - "Helvetica", - "Courier", - "Symbol", - "Taliesin", // mobile? - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, // 30 - NULL, - NULL, - "Avant Garde", - "New Century Schoolbook" -}; - const char *Scene::getFontName() { - if (_fontType >= 0 && _fontType < ARRAYSIZE(fontNames) && fontNames[_fontType] != NULL) { - return fontNames[_fontType]; - } - return "Unknown"; + const char *name = ((WageEngine *)g_engine)->_gui->_wm.getFontName(_fontType, _fontSize); + + if (!name) + return "Unknown"; + + return name; } Designed *Scene::lookUpEntity(int x, int y) { @@ -221,6 +184,7 @@ Designed *Scene::lookUpEntity(int x, int y) { Obj::Obj() : _currentOwner(NULL), _currentScene(NULL) { _index = 0; + _resourceId = 0; _namePlural = false; _value = 0; _attackType = 0; @@ -231,7 +195,9 @@ Obj::Obj() : _currentOwner(NULL), _currentScene(NULL) { _damage = 0; } -Obj::Obj(Common::String name, Common::SeekableReadStream *data) { +Obj::Obj(Common::String name, Common::SeekableReadStream *data, int resourceId) { + _resourceId = resourceId; + _name = name; _classType = OBJ; _currentOwner = NULL; @@ -322,6 +288,7 @@ Chr::Chr(Common::String name, Common::SeekableReadStream *data) { _design = new Design(data); _index = 0; + _resourceId = 0; _currentScene = NULL; setDesignBounds(readRect(data)); diff --git a/engines/wage/entities.h b/engines/wage/entities.h index 9e706f0d58..f327270254 100644 --- a/engines/wage/entities.h +++ b/engines/wage/entities.h @@ -152,6 +152,7 @@ public: Chr(Common::String name, Common::SeekableReadStream *data); int _index; + int _resourceId; Common::String _initialScene; int _gender; bool _nameProperNoun; @@ -229,7 +230,7 @@ public: class Obj : public Designed { public: Obj(); - Obj(Common::String name, Common::SeekableReadStream *data); + Obj(Common::String name, Common::SeekableReadStream *data, int resourceId); ~Obj(); enum ObjectType { @@ -256,6 +257,7 @@ public: public: int _index; + int _resourceId; bool _namePlural; uint _value; int _attackType; @@ -301,6 +303,8 @@ public: RANDOM = 1 }; + int _resourceId; + Script *_script; Common::String _text; Common::Rect *_textBounds; diff --git a/engines/wage/gui-console.cpp b/engines/wage/gui-console.cpp index 8b6fe43a17..2476a8c7fb 100644 --- a/engines/wage/gui-console.cpp +++ b/engines/wage/gui-console.cpp @@ -51,24 +51,21 @@ #include "graphics/cursorman.h" #include "graphics/fonts/bdf.h" #include "graphics/palette.h" +#include "graphics/macgui/macwindow.h" +#include "graphics/macgui/macmenu.h" #include "wage/wage.h" #include "wage/design.h" #include "wage/entities.h" -#include "wage/macwindow.h" -#include "wage/macmenu.h" #include "wage/gui.h" #include "wage/world.h" namespace Wage { const Graphics::Font *Gui::getConsoleFont() { - char fontName[128]; Scene *scene = _engine->_world->_player->_currentScene; - snprintf(fontName, 128, "%s-%d", scene->getFontName(), scene->_fontSize); - - return _wm.getFont(fontName, Graphics::FontManager::kConsoleFont); + return _wm.getFont(scene->getFontName(), Graphics::FontManager::kConsoleFont); } void Gui::clearOutput() { @@ -309,7 +306,20 @@ void Gui::drawInput() { font->drawString(&_screen, _out[_inputTextLineNum], x, y, _screen.w, kColorBlack); - g_system->copyRectToScreen(_screen.getBasePtr(x, y), _screen.pitch, x, y, _consoleWindow->getInnerDimensions().width(), font->getFontHeight()); + int w = _consoleWindow->getInnerDimensions().width(); + int h = font->getFontHeight(); + if (x < 0) { + w += x; + x = 0; + } + if (y < 0) { + h += y; + y = 0; + } + if (x + w > _screen.w) w = _screen.w - x; + if (y + h > _screen.h) h = _screen.h - y; + if (w != 0 && h != 0) + g_system->copyRectToScreen(_screen.getBasePtr(x, y), _screen.pitch, x, y, w, h); } _cursorX = font->getStringWidth(_out[_inputTextLineNum]) + kConHPadding; diff --git a/engines/wage/gui.cpp b/engines/wage/gui.cpp index 099279158f..cd259e6ddd 100644 --- a/engines/wage/gui.cpp +++ b/engines/wage/gui.cpp @@ -49,25 +49,25 @@ #include "common/system.h" #include "graphics/cursorman.h" #include "graphics/primitives.h" +#include "graphics/macgui/macwindowmanager.h" +#include "graphics/macgui/macwindow.h" +#include "graphics/macgui/macmenu.h" #include "wage/wage.h" #include "wage/design.h" #include "wage/entities.h" #include "wage/gui.h" -#include "wage/macwindow.h" -#include "wage/macwindowmanager.h" -#include "wage/macmenu.h" #include "wage/world.h" namespace Wage { -static const MenuData menuSubItems[] = { +static const Graphics::MenuData menuSubItems[] = { { kMenuHighLevel, "File", 0, 0, false }, { kMenuHighLevel, "Edit", 0, 0, false }, { kMenuFile, "New", kMenuActionNew, 0, false }, - { kMenuFile, "Open...", kMenuActionOpen, 0, false }, + { kMenuFile, "Open...", kMenuActionOpen, 0, true }, { kMenuFile, "Close", kMenuActionClose, 0, true }, - { kMenuFile, "Save", kMenuActionSave, 0, false }, + { kMenuFile, "Save", kMenuActionSave, 0, true }, { kMenuFile, "Save as...", kMenuActionSaveAs, 0, true }, { kMenuFile, "Revert", kMenuActionRevert, 0, false }, { kMenuFile, "Quit", kMenuActionQuit, 0, true }, @@ -96,16 +96,22 @@ static void cursorTimerHandler(void *refCon) { x += gui->_consoleWindow->getInnerDimensions().left; y += gui->_consoleWindow->getInnerDimensions().top; + int h = kCursorHeight; - gui->_screen.vLine(x, y, y + kCursorHeight, gui->_cursorState ? kColorBlack : kColorWhite); + if (y + h > gui->_consoleWindow->getInnerDimensions().bottom) { + h = gui->_consoleWindow->getInnerDimensions().bottom - y; + } + + if (h > 0) + gui->_screen.vLine(x, y, y + h, gui->_cursorState ? kColorBlack : kColorWhite); if (!gui->_cursorOff) gui->_cursorState = !gui->_cursorState; gui->_cursorRect.left = x; gui->_cursorRect.right = MIN<uint16>(x + 1, gui->_screen.w); - gui->_cursorRect.top = y; - gui->_cursorRect.bottom = MIN<uint16>(y + kCursorHeight, gui->_screen.h); + gui->_cursorRect.top = MIN<uint16>(y - 1, gui->_consoleWindow->getInnerDimensions().top); + gui->_cursorRect.bottom = MIN<uint16>(MIN<uint16>(y + h, gui->_screen.h), gui->_consoleWindow->getInnerDimensions().bottom); gui->_cursorDirty = true; } @@ -168,6 +174,9 @@ Gui::Gui(WageEngine *engine) { _consoleWindow = _wm.addWindow(true, true, true); _consoleWindow->setCallback(consoleWindowCallback, this); + + loadBorders(); + } Gui::~Gui() { @@ -211,8 +220,19 @@ void Gui::draw() { _wm.draw(); if (_cursorDirty && _cursorRect.left < _screen.w && _cursorRect.bottom < _screen.h) { - g_system->copyRectToScreen(_screen.getBasePtr(_cursorRect.left, _cursorRect.top), _screen.pitch, - _cursorRect.left, _cursorRect.top, _cursorRect.width(), _cursorRect.height()); + int x = _cursorRect.left, y = _cursorRect.top, w = _cursorRect.width(), h = _cursorRect.height(); + if (x < 0) { + w += x; + x = 0; + } + if (y < 0) { + h += y; + y = 0; + } + if (x + w > _screen.w) w = _screen.w - x; + if (y + h > _screen.h) h = _screen.h - y; + if (w != 0 && h != 0) + g_system->copyRectToScreen(_screen.getBasePtr(x, y), _screen.pitch, x, y, w, h); _cursorDirty = false; } @@ -323,12 +343,19 @@ void Gui::executeMenuCommand(int action, Common::String &text) { switch(action) { case kMenuActionAbout: case kMenuActionNew: - case kMenuActionOpen: case kMenuActionClose: - case kMenuActionSave: - case kMenuActionSaveAs: case kMenuActionRevert: case kMenuActionQuit: + break; + + case kMenuActionOpen: + _engine->scummVMSaveLoadDialog(false); + break; + + case kMenuActionSave: + case kMenuActionSaveAs: + _engine->scummVMSaveLoadDialog(true); + break; case kMenuActionUndo: actionUndo(); @@ -356,4 +383,30 @@ void Gui::executeMenuCommand(int action, Common::String &text) { } } +void Gui::loadBorders() { + // Do not load borders for now + //loadBorder(_sceneWindow, "border_inac.bmp", false); + //loadBorder(_sceneWindow, "border_act.bmp", true); +} + +void Gui::loadBorder(Graphics::MacWindow *target, Common::String filename, bool active) { + Common::File borderfile; + + if (!borderfile.open(filename)) { + debug(1, "Cannot open border file"); + return; + } + + Image::BitmapDecoder bmpDecoder; + Common::SeekableReadStream *stream = borderfile.readStream(borderfile.size()); + if (stream) { + + target->loadBorder(*stream, active, 10, 10, 1, 1); + + borderfile.close(); + + delete stream; + } +} + } // End of namespace Wage diff --git a/engines/wage/gui.h b/engines/wage/gui.h index ba1bb5ef3b..898c7c3162 100644 --- a/engines/wage/gui.h +++ b/engines/wage/gui.h @@ -51,15 +51,25 @@ #include "common/str-array.h" #include "graphics/font.h" #include "graphics/managed_surface.h" +#include "graphics/macgui/macwindowmanager.h" +#include "graphics/macgui/macwindow.h" +#include "graphics/macgui/macmenu.h" +#include "graphics/macgui/macwindowborder.h" + #include "common/events.h" #include "common/rect.h" -#include "wage/macwindow.h" -#include "wage/macwindowmanager.h" +#include "common/file.h" +#include "graphics/pixelformat.h" +#include "image/bmp.h" + +#include "graphics/palette.h" + namespace Wage { -class Menu; +using namespace Graphics::MacWindowConstants; + class Scene; class WageEngine; @@ -67,6 +77,44 @@ enum { kCursorHeight = 12 }; +enum { + kFontStyleBold = 1, + kFontStyleItalic = 2, + kFontStyleUnderline = 4, + kFontStyleOutline = 8, + kFontStyleShadow = 16, + kFontStyleCondensed = 32, + kFontStyleExtended = 64 +}; + +enum { + kMenuHighLevel = -1, + kMenuAbout = 0, + kMenuFile = 1, + kMenuEdit = 2, + kMenuCommands = 3, + kMenuWeapons = 4 +}; + +enum { + kMenuActionAbout, + kMenuActionNew, + kMenuActionOpen, + kMenuActionClose, + kMenuActionSave, + kMenuActionSaveAs, + kMenuActionRevert, + kMenuActionQuit, + + kMenuActionUndo, + kMenuActionCut, + kMenuActionCopy, + kMenuActionPaste, + kMenuActionClear, + + kMenuActionCommand +}; + class Gui { public: Gui(WageEngine *engine); @@ -107,6 +155,9 @@ private: int calcTextX(int x, int textLine); int calcTextY(int y); void updateTextSelection(int x, int y); + + void loadBorders(); + void loadBorder(Graphics::MacWindow *target, Common::String filename, bool active); public: Graphics::ManagedSurface _screen; @@ -121,13 +172,14 @@ public: Scene *_scene; - MacWindowManager _wm; - MacWindow *_sceneWindow; - MacWindow *_consoleWindow; + Graphics::MacWindowManager _wm; + Graphics::MacWindow *_sceneWindow; + Graphics::MacWindow *_consoleWindow; private: + Graphics::ManagedSurface _console; - Menu *_menu; + Graphics::Menu *_menu; bool _sceneDirty; bool _consoleDirty; diff --git a/engines/wage/macwindow.h b/engines/wage/macwindow.h deleted file mode 100644 index 4c6e9efeff..0000000000 --- a/engines/wage/macwindow.h +++ /dev/null @@ -1,161 +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. - * - * MIT License: - * - * Copyright (c) 2009 Alexei Svitkine, Eugene Sandulenko - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef WAGE_MACWINDOW_H -#define WAGE_MACWINDOW_H - -#include "graphics/managed_surface.h" - -namespace Wage { - -class MacWindowManager; - -enum WindowType { - kWindowUnknown, - kWindowWindow, - kWindowMenu -}; - -enum { - kBorderWidth = 17 -}; - -enum WindowClick { - kBorderNone = 0, - kBorderScrollUp, - kBorderScrollDown, - kBorderCloseButton, - kBorderInner, - kBorderBorder, - kBorderResizeButton -}; - -class BaseMacWindow { -public: - BaseMacWindow(int id, bool editable, MacWindowManager *wm); - virtual ~BaseMacWindow() {} - - const Common::Rect &getDimensions() { return _dims; } - int getId() { return _id; } - WindowType getType() { return _type; } - bool isEditable() { return _editable; } - Graphics::ManagedSurface *getSurface() { return &_surface; } - virtual void setActive(bool active) = 0; - void setDirty(bool dirty) { _contentIsDirty = dirty; } - - virtual bool draw(Graphics::ManagedSurface *g, bool forceRedraw = false) = 0; - virtual bool processEvent(Common::Event &event) = 0; - - virtual bool hasAllFocus() = 0; - - void setCallback(bool (*callback)(WindowClick, Common::Event &, void *), void *data) { _callback = callback; _dataPtr = data; } - -protected: - int _id; - WindowType _type; - - bool _editable; - - Graphics::ManagedSurface _surface; - bool _contentIsDirty; - - Common::Rect _dims; - - bool (*_callback)(WindowClick, Common::Event &, void *); - void *_dataPtr; - - MacWindowManager *_wm; -}; - -class MacWindow : public BaseMacWindow { -public: - MacWindow(int id, bool scrollable, bool resizable, bool editable, MacWindowManager *wm); - virtual ~MacWindow(); - void move(int x, int y); - void resize(int w, int h); - void setDimensions(const Common::Rect &r); - const Common::Rect &getInnerDimensions() { return _innerDims; } - - bool draw(Graphics::ManagedSurface *g, bool forceRedraw = false); - - void setActive(bool active); - void setTitle(Common::String &title) { _title = title; } - void setHighlight(WindowClick highlightedPart); - void setScroll(float scrollPos, float scrollSize); - bool processEvent(Common::Event &event); - bool hasAllFocus() { return _beingDragged || _beingResized; } - -private: - void drawBorder(); - void drawBox(Graphics::ManagedSurface *g, int x, int y, int w, int h); - void fillRect(Graphics::ManagedSurface *g, int x, int y, int w, int h, int color); - const Graphics::Font *getTitleFont(); - void updateInnerDims(); - WindowClick isInBorder(int x, int y); - -private: - Graphics::ManagedSurface _borderSurface; - Graphics::ManagedSurface _composeSurface; - bool _scrollable; - bool _resizable; - bool _active; - bool _borderIsDirty; - - bool _beingDragged, _beingResized; - int _draggedX, _draggedY; - - WindowClick _highlightedPart; - float _scrollPos, _scrollSize; - - Common::Rect _innerDims; - - Common::String _title; -}; - -} // End of namespace Wage - -#endif diff --git a/engines/wage/macwindowmanager.h b/engines/wage/macwindowmanager.h deleted file mode 100644 index 13f85cddd4..0000000000 --- a/engines/wage/macwindowmanager.h +++ /dev/null @@ -1,141 +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. - * - * MIT License: - * - * Copyright (c) 2009 Alexei Svitkine, Eugene Sandulenko - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef WAGE_MACWINDOWMANAGER_H -#define WAGE_MACWINDOWMANAGER_H - -#include "common/array.h" -#include "common/list.h" -#include "common/events.h" -#include "common/archive.h" - -#include "graphics/fontman.h" - -namespace Graphics { -class ManagedSurface; -} - -namespace Wage { - -enum { - kDesktopArc = 7 -}; - -enum { - kColorBlack = 0, - kColorGray = 1, - kColorWhite = 2, - kColorGreen = 3, - kColorGreen2 = 4 -}; - -enum { - kPatternSolid = 1, - kPatternStripes = 2, - kPatternCheckers = 3, - kPatternCheckers2 = 4 -}; - -class BaseMacWindow; -class MacWindow; -class Menu; - -typedef Common::Array<byte *> Patterns; - -class MacWindowManager { -public: - MacWindowManager(); - ~MacWindowManager(); - - void setScreen(Graphics::ManagedSurface *screen) { _screen = screen; } - bool hasBuiltInFonts() { return _builtInFonts; } - const Graphics::Font *getFont(const char *name, Graphics::FontManager::FontUsage fallback); - - MacWindow *addWindow(bool scrollable, bool resizable, bool editable); - Menu *addMenu(); - void setActive(int id); - - void setFullRefresh(bool redraw) { _fullRefresh = true; } - - void draw(); - - bool processEvent(Common::Event &event); - - BaseMacWindow *getWindow(int id) { return _windows[id]; } - - Patterns &getPatterns() { return _patterns; } - void drawFilledRoundRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int arc, int color); - - void pushArrowCursor(); - void popCursor(); - -private: - void drawDesktop(); - void loadFonts(); - -private: - Graphics::ManagedSurface *_screen; - - Common::List<BaseMacWindow *> _windowStack; - Common::Array<BaseMacWindow *> _windows; - - int _lastId; - int _activeWindow; - - bool _fullRefresh; - - Patterns _patterns; - - Menu *_menu; - - bool _builtInFonts; - bool _cursorIsArrow; -}; - -} // End of namespace Wage - -#endif diff --git a/engines/wage/module.mk b/engines/wage/module.mk index e150d5f27e..be148dd439 100644 --- a/engines/wage/module.mk +++ b/engines/wage/module.mk @@ -9,10 +9,8 @@ MODULE_OBJS := \ entities.o \ gui.o \ gui-console.o \ - macmenu.o \ - macwindow.o \ - macwindowmanager.o \ randomhat.o \ + saveload.o \ script.o \ sound.o \ util.o \ diff --git a/engines/wage/saveload.cpp b/engines/wage/saveload.cpp new file mode 100644 index 0000000000..c3b20bdf2f --- /dev/null +++ b/engines/wage/saveload.cpp @@ -0,0 +1,776 @@ +/* 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. + * + * MIT License: + * + * Copyright (c) 2009 Alexei Svitkine, Eugene Sandulenko + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "common/file.h" +#include "common/debug.h" +#include "common/debug-channels.h" +#include "common/config-manager.h" +#include "common/savefile.h" +#include "common/system.h" +#include "common/textconsole.h" +#include "common/translation.h" + +#include "gui/saveload.h" + +#include "graphics/thumbnail.h" +#include "graphics/surface.h" + +#include "wage/wage.h" +#include "wage/world.h" +#include "wage/entities.h" + +#define SAVEGAME_CURRENT_VERSION 1 + +// +// Original saves format is supported. +// ScummVM adds flags, description and thumbnail +// in the end of the file (shouldn't make saves incompatible). +// +// Version 0 (original/ScummVM): first ScummVM version +// + +namespace Wage { + +static const uint32 WAGEflag = MKTAG('W', 'A', 'G', 'E'); + +//TODO: make sure these are calculated right: (we add flag, description, etc) +#define VARS_INDEX 0x005E +#define SCENES_INDEX 0x0232 + +#define SCENE_SIZE 0x0010 +#define CHR_SIZE 0x0016 +#define OBJ_SIZE 0x0010 + +#define GET_HEX_OFFSET(ptr, baseOffset, entrySize) ((ptr) == nullptr ? -1 : ((baseOffset) + (entrySize) * (ptr)->_index)) +#define GET_HEX_CHR_OFFSET(ptr) GET_HEX_OFFSET((ptr), chrsHexOffset, CHR_SIZE) +#define GET_HEX_OBJ_OFFSET(ptr) GET_HEX_OFFSET((ptr), objsHexOffset, OBJ_SIZE) +#define GET_HEX_SCENE_OFFSET(ptr) ((ptr) == nullptr ? -1 : \ + ((ptr) == _world->_storageScene ? 0 : (SCENES_INDEX + getSceneIndex(_world->_player->_currentScene) * SCENE_SIZE))) + +int WageEngine::getSceneIndex(Scene *scene) const { + assert(scene); + Common::Array<Scene *> &orderedScenes = _world->_orderedScenes; + for (uint32 i = 0; i < orderedScenes.size(); ++i) { + if (orderedScenes[i] == scene) return i-1; + } + + warning("Scene's index not found"); + return -1; +} + +Obj *WageEngine::getObjByOffset(int offset, int objBaseOffset) const { + int objIndex = -1; + + if (offset != 0xFFFF) { + objIndex = (offset - objBaseOffset) / CHR_SIZE; + } + + if (objIndex >= 0 && objIndex < _world->_orderedObjs.size()) { + return _world->_orderedObjs[objIndex]; + } + + return nullptr; +} + +Chr *WageEngine::getChrById(int resId) const { + Common::Array<Chr *> &orderedChrs = _world->_orderedChrs; + for (uint32 i = 0; i < orderedChrs.size(); ++i) { + if (orderedChrs[i]->_resourceId == resId) + return orderedChrs[i]; + } + + return nullptr; +} + +Chr *WageEngine::getChrByOffset(int offset, int chrBaseOffset) const { + int chrIndex = -1; + + if (offset != 0xFFFF) { + chrIndex = (offset - chrBaseOffset) / CHR_SIZE; + } + + if (chrIndex >= 0 && chrIndex < _world->_orderedChrs.size()) { + return _world->_orderedChrs[chrIndex]; + } + + return nullptr; +} + +Scene *WageEngine::getSceneById(int resId) const { + Common::Array<Scene *> &orderedScenes = _world->_orderedScenes; + for (uint32 i = 0; i < orderedScenes.size(); ++i) { + if (orderedScenes[i]->_resourceId == resId) + return orderedScenes[i]; + } + + return nullptr; +} + +Scene *WageEngine::getSceneByOffset(int offset) const { + int sceneIndex = -1; + + if (offset != 0xFFFF) { + if (offset == 0) + sceneIndex = 0; + else + sceneIndex = 1 + (offset - SCENES_INDEX) / SCENE_SIZE; + } + + if (sceneIndex >= 0 && sceneIndex < _world->_orderedScenes.size()) { + if (sceneIndex == 0) return _world->_storageScene; + return _world->_orderedScenes[sceneIndex]; + } + + return nullptr; +} + +int WageEngine::saveGame(const Common::String &fileName, const Common::String &descriptionString) { + Common::OutSaveFile *out; + int result = 0; + + debug(9, "WageEngine::saveGame(%s, %s)", fileName.c_str(), descriptionString.c_str()); + if (!(out = _saveFileMan->openForSaving(fileName))) { + warning("Can't create file '%s', game not saved", fileName.c_str()); + return -1; + } else { + debug(9, "Successfully opened %s for writing", fileName.c_str()); + } + + // Counters + out->writeSint16LE(_world->_scenes.size()); //numScenes + out->writeSint16LE(_world->_chrs.size()); //numChars + out->writeSint16LE(_world->_objs.size()); //numObjs + + // Hex Offsets + int chrsHexOffset = SCENES_INDEX + _world->_scenes.size() * SCENE_SIZE; //chrs start after scenes + int objsHexOffset = chrsHexOffset + _world->_chrs.size() * CHR_SIZE; //objs start after chrs + out->writeSint32LE(chrsHexOffset); + out->writeSint32LE(objsHexOffset); + + // Unique 8-byte World Signature + out->writeSint32LE(_world->_signature); //8-byte ints? seriously? (uses 4 bytes in java code too) + + Chr *player = _world->_player; + Context &playerContext = player->_context; + + // More Counters + out->writeSint32LE(playerContext._visits); //visitNum + out->writeSint32LE(_loopCount); //loopNum + out->writeSint32LE(playerContext._kills); //killNum + + // Hex offset to player character + out->writeSint32LE(GET_HEX_CHR_OFFSET(player)); //getPlayerHexOffset() == getHexOffsetForChr(player) + + // character in this scene? + out->writeSint32LE(GET_HEX_CHR_OFFSET(_monster)); //getPresCharHexOffset() == getHexOffsetForChr(monster) + + // Hex offset to current scene + out->writeSint32LE(GET_HEX_SCENE_OFFSET(player->_currentScene)); //getCurSceneHexOffset() + + // wearing a helmet? + out->writeSint32LE(GET_HEX_OBJ_OFFSET(player->_armor[Chr::HEAD_ARMOR])); //helmetIndex + + // holding a shield? + out->writeSint32LE(GET_HEX_OBJ_OFFSET(player->_armor[Chr::SHIELD_ARMOR])); //shieldIndex + + // wearing chest armor? + out->writeSint32LE(GET_HEX_OBJ_OFFSET(player->_armor[Chr::BODY_ARMOR])); //chestArmIndex + + // wearing spiritual armor? + out->writeSint32LE(GET_HEX_OBJ_OFFSET(player->_armor[Chr::MAGIC_ARMOR])); //sprtArmIndex + + // TODO: + out->writeSint16LE(0xffff); // ???? - always FFFF + out->writeSint16LE(0xffff); // ???? - always FFFF + out->writeSint16LE(0xffff); // ???? - always FFFF + out->writeSint16LE(0xffff); // ???? - always FFFF + + // did a character just escape? + out->writeSint32LE(GET_HEX_CHR_OFFSET(_running)); //getRunCharHexOffset() == getHexOffsetForChr(running) + + // players experience points + out->writeSint32LE(playerContext._experience); + + out->writeSint16LE(_aim); //aim + out->writeSint16LE(_opponentAim); //opponentAim + + // TODO: + out->writeSint16LE(0x0000); // always 0 + out->writeSint16LE(0x0000); // always 0 + out->writeSint16LE(0x0000); // always 0 + + // Base character stats + out->writeByte(playerContext._statVariables[PHYS_STR_BAS]); //state.getBasePhysStr() + out->writeByte(playerContext._statVariables[PHYS_HIT_BAS]); //state.getBasePhysHp() + out->writeByte(playerContext._statVariables[PHYS_ARM_BAS]); //state.getBasePhysArm() + out->writeByte(playerContext._statVariables[PHYS_ACC_BAS]); //state.getBasePhysAcc() + out->writeByte(playerContext._statVariables[SPIR_STR_BAS]); //state.getBaseSprtStr() + out->writeByte(playerContext._statVariables[SPIR_HIT_BAS]); //state.getBaseSprtHp() + out->writeByte(playerContext._statVariables[SPIR_ARM_BAS]); //state.getBaseSprtArm() + out->writeByte(playerContext._statVariables[SPIR_ACC_BAS]); //state.getBaseSprtAcc() + out->writeByte(playerContext._statVariables[PHYS_SPE_BAS]); //state.getBaseRunSpeed() + + // TODO: + out->writeByte(0x0A); // ???? - always seems to be 0x0A + + // write user vars + for (uint32 i = 0; i < 26 * 9; ++i) + out->writeSint16LE(playerContext._userVariables[i]); + + // write updated info for all scenes + Common::Array<Scene *> &orderedScenes = _world->_orderedScenes; + for (uint32 i = 0; i < orderedScenes.size(); ++i) { + Scene *scene = orderedScenes[i]; + if (scene != _world->_storageScene) { + out->writeSint16LE(scene->_resourceId); + out->writeSint16LE(scene->_worldY); + out->writeSint16LE(scene->_worldX); + out->writeByte(scene->_blocked[NORTH] ? 0x01 : 0x00); + out->writeByte(scene->_blocked[SOUTH] ? 0x01 : 0x00); + out->writeByte(scene->_blocked[EAST] ? 0x01 : 0x00); + out->writeByte(scene->_blocked[WEST] ? 0x01 : 0x00); + out->writeSint16LE(scene->_soundFrequency); + out->writeByte(scene->_soundType); + // the following two bytes are currently unknown + out->writeByte(0); + out->writeByte(0); + out->writeByte(scene->_visited ? 0x01 : 0x00); + } + } + + // write updated info for all characters + Common::Array<Chr *> &orderedChrs = _world->_orderedChrs; + for (uint32 i = 0; i < orderedChrs.size(); ++i) { + Chr *chr = orderedChrs[i]; + out->writeSint16LE(chr->_resourceId); + out->writeSint16LE(chr->_currentScene->_resourceId); + Context &chrContext = chr->_context; + out->writeByte(chrContext._statVariables[PHYS_STR_CUR]); + out->writeByte(chrContext._statVariables[PHYS_HIT_CUR]); + out->writeByte(chrContext._statVariables[PHYS_ARM_CUR]); + out->writeByte(chrContext._statVariables[PHYS_ACC_CUR]); + out->writeByte(chrContext._statVariables[SPIR_STR_CUR]); + out->writeByte(chrContext._statVariables[SPIR_HIT_CUR]); + out->writeByte(chrContext._statVariables[SPIR_ARM_CUR]); + out->writeByte(chrContext._statVariables[SPIR_ACC_CUR]); + out->writeByte(chrContext._statVariables[PHYS_SPE_CUR]); + out->writeByte(chr->_rejectsOffers); + out->writeByte(chr->_followsOpponent); + // bytes 16-20 are unknown + out->writeByte(0); + out->writeByte(0); + out->writeByte(0); + out->writeByte(0); + out->writeByte(0); + out->writeByte(chr->_weaponDamage1); + out->writeByte(chr->_weaponDamage2); + } + + // write updated info for all objects + Common::Array<Obj *> &orderedObjs = _world->_orderedObjs; + for (uint32 i = 0; i < orderedObjs.size(); ++i) { + Obj *obj = orderedObjs[i]; + Scene *location = obj->_currentScene; + Chr *owner = obj->_currentOwner; + + out->writeSint16LE(obj->_resourceId); + out->writeSint16LE(location == nullptr ? 0 : location->_resourceId); + out->writeSint16LE(owner == nullptr ? 0 : owner->_resourceId); + + // bytes 7-9 are unknown (always = 0) + out->writeByte(0); + out->writeByte(0); + out->writeByte(0); + + out->writeByte(obj->_accuracy); + out->writeByte(obj->_value); + out->writeByte(obj->_type); + out->writeByte(obj->_damage); + out->writeByte(obj->_attackType); + out->writeSint16LE(obj->_numberOfUses); + } + + // the following is appended by ScummVM + int32 appendixOffset = out->pos(); + if (appendixOffset < 0) { + warning("OutSaveFile::pos() failed"); + } + out->writeUint32BE(WAGEflag); + + // Write description of saved game, limited to WAGE_SAVEDGAME_DESCRIPTION_LEN characters + terminating NUL + const int WAGE_SAVEDGAME_DESCRIPTION_LEN = 127; + char description[WAGE_SAVEDGAME_DESCRIPTION_LEN + 1]; + + memset(description, 0, sizeof(description)); + strncpy(description, descriptionString.c_str(), WAGE_SAVEDGAME_DESCRIPTION_LEN); + assert(WAGE_SAVEDGAME_DESCRIPTION_LEN + 1 == 128); // safety + out->write(description, 128); + + out->writeByte(SAVEGAME_CURRENT_VERSION); + debug(9, "Writing save game version (%d)", SAVEGAME_CURRENT_VERSION); + + // Thumbnail + Graphics::saveThumbnail(*out); + + out->writeUint32BE(appendixOffset); + + // this one to make checking easier: + // it couldn't be added to the beginning + // and we won't be able to find it in the middle, + // so these would be the last 4 bytes of the file + out->writeUint32BE(WAGEflag); + + out->finalize(); + if (out->err()) { + warning("Can't write file '%s'. (Disk full?)", fileName.c_str()); + result = -1; + } else + debug(9, "Saved game %s in file %s", descriptionString.c_str(), fileName.c_str()); + + delete out; + return result; +} + +int WageEngine::loadGame(int slotId) { + Common::InSaveFile *data; + Common::String fileName = getSavegameFilename(slotId); + + debug(9, "WageEngine::loadGame(%d)", slotId); + if (!(data = _saveFileMan->openForLoading(fileName))) { + warning("Can't open file '%s', game not loaded", fileName.c_str()); + return -1; + } else { + debug(9, "Successfully opened %s for reading", fileName.c_str()); + } + + // Counters + int numScenes = data->readSint16LE(); + int numChars = data->readSint16LE(); + int numObjs = data->readSint16LE(); + + // Hex Offsets + int chrsHexOffset = data->readSint32LE(); + int objsHexOffset = data->readSint32LE(); + + // Unique 8-byte World Signature + int signature = data->readSint32LE(); + if (_world->_signature != signature) { + warning("This saved game is for a different world, please select another one"); + warning("World signature = %d, save signature = %d", _world->_signature, signature); + delete data; + return -1; + } + + // More Counters + int visitNum = data->readSint32LE(); //visitNum + int loopNum = data->readSint32LE(); //loopNum + int killNum = data->readSint32LE(); //killNum + + // Hex offset to player character + int playerOffset = data->readSint32LE(); + + // character in this scene? + int presCharOffset = data->readSint32LE(); + + // Hex offset to current scene + int currentSceneOffset = data->readSint32LE(); + + // find player and current scene + Chr *player = getChrByOffset(playerOffset, chrsHexOffset); + if (player == nullptr) { + warning("Invalid Character! Aborting load."); + delete data; + return -1; + } + + Scene *currentScene = getSceneByOffset(currentSceneOffset); + if (currentScene == nullptr) { + warning("Invalid Scene! Aborting load."); + delete data; + return -1; + } + + // set player character + _world->_player = player; + + // set current scene + player->_currentScene = currentScene; + + // clear the players inventory list + player->_inventory.clear(); + + // wearing a helmet? + int helmetOffset = data->readSint32LE(); //helmetIndex + + // holding a shield? + int shieldOffset = data->readSint32LE(); //shieldIndex + + // wearing chest armor? + int armorOffset = data->readSint32LE(); //chestArmIndex + + // wearing spiritual armor? + int spiritualArmorOffset = data->readSint32LE(); //sprtArmIndex + + data->readSint16LE(); // FFFF + data->readSint16LE(); // FFFF + data->readSint16LE(); // FFFF + data->readSint16LE(); // FFFF + + int runCharOffset = data->readSint32LE(); + + // players experience points + int exp = data->readSint32LE(); // @ playerContext._experience + + int aim = data->readSint16LE(); //aim + int opponentAim = data->readSint16LE(); //opponentAim + + data->readSint16LE(); // 0000 + data->readSint16LE(); // 0000 + data->readSint16LE(); // 0000 + + // Base character stats + int basePhysStr = data->readByte(); + int basePhysHp = data->readByte(); + int basePhysArm = data->readByte(); + int basePhysAcc = data->readByte(); + int baseSprtStr = data->readByte(); + int baseSprtHp = data->readByte(); + int baseSprtArm = data->readByte(); + int baseSprtAcc = data->readByte(); + int baseRunSpeed = data->readByte(); + + // set player stats + Context &playerContext = player->_context; + // I'm setting player fields also, because those are used as base values in Chr::resetState() + playerContext._statVariables[PHYS_STR_BAS] = player->_physicalStrength = basePhysStr; + playerContext._statVariables[PHYS_HIT_BAS] = player->_physicalHp = basePhysHp; + playerContext._statVariables[PHYS_ARM_BAS] = player->_naturalArmor = basePhysArm; + playerContext._statVariables[PHYS_ACC_BAS] = player->_physicalAccuracy = basePhysAcc; + playerContext._statVariables[SPIR_STR_BAS] = player->_spiritualStength = baseSprtStr; + playerContext._statVariables[SPIR_HIT_BAS] = player->_spiritialHp = baseSprtHp; + playerContext._statVariables[SPIR_ARM_BAS] = player->_resistanceToMagic = baseSprtArm; + playerContext._statVariables[SPIR_ACC_BAS] = player->_spiritualAccuracy = baseSprtAcc; + playerContext._statVariables[PHYS_SPE_BAS] = player->_runningSpeed = baseRunSpeed; + + // set visit# + playerContext._visits = visitNum; + + // set monsters killed + playerContext._kills = killNum; + + // set experience + playerContext._experience = exp; + + // if a character is present, move it to this scene + // TODO: This is done in the engine object, would it be cleaner + // to move it here? + // well, it's actually down there now, now sure if that's "cleaner" + // when it's up there or down there + + // if a character just ran away, let our engine know + // TODO: The current engine doesn't have a case for this, we + // should update it + // yep, I don't see such code anywhere in java, so not added it here + + data->readByte(); // 0x0A? + + // set all user variables + for (uint32 i = 0; i < 26 * 9; ++i) { + playerContext._userVariables[i] = data->readSint16LE(); + } + + // update all scene stats + Common::Array<Scene *> &orderedScenes = _world->_orderedScenes; + if (numScenes != orderedScenes.size()) { + warning("scenes number in file (%d) differs from the one in world (%d)", numScenes, orderedScenes.size()); + } + for (uint32 i = 0; i < orderedScenes.size(); ++i) { + Scene *scene = orderedScenes[i]; + if (scene == _world->_storageScene) { + scene->_chrs.clear(); + scene->_objs.clear(); + } else { + int id = data->readSint16LE(); + + if (scene->_resourceId != id) { + warning("loadGame(): updating scenes: expected %d but got %d", scene->_resourceId, id); + data->skip(14); //2,2,1,1,1,1,2,1,1,1,1 down there + continue; + } + + scene->_worldY = data->readSint16LE(); + scene->_worldX = data->readSint16LE(); + scene->_blocked[NORTH] = data->readByte() != 0; + scene->_blocked[SOUTH] = data->readByte() != 0; + scene->_blocked[EAST] = data->readByte() != 0; + scene->_blocked[WEST] = data->readByte() != 0; + scene->_soundFrequency = data->readSint16LE(); + scene->_soundType = data->readByte(); + // the following two bytes are currently unknown + data->readByte(); + data->readByte(); + scene->_visited = data->readByte() != 0; + } + } + + // update all char locations and stats + Common::Array<Chr *> &orderedChrs = _world->_orderedChrs; + if (numChars != orderedChrs.size()) { + warning("characters number in file (%d) differs from the one in world (%d)", numChars, orderedChrs.size()); + } + for (uint32 i = 0; i < orderedChrs.size(); ++i) { + int resourceId = data->readSint16LE(); + int sceneResourceId = data->readSint16LE(); + + int strength = data->readByte(); + int hp = data->readByte(); + int armor = data->readByte(); + int accuracy = data->readByte(); + int spirStrength = data->readByte(); + int spirHp = data->readByte(); + int spirArmor = data->readByte(); + int spirAccuracy = data->readByte(); + int speed = data->readByte(); + int rejectsOffers = data->readByte(); + int followsOpponent = data->readByte(); + + // bytes 16-20 are unknown + data->readByte(); + data->readByte(); + data->readByte(); + data->readByte(); + data->readByte(); + + int weaponDamage1 = data->readByte(); + int weaponDamage2 = data->readByte(); + + Chr *chr = orderedChrs[i]; + if (chr->_resourceId != resourceId) { + warning("loadGame(): updating chrs: expected %d but got %d", chr->_resourceId, resourceId); + continue; + } + + chr->_currentScene = getSceneById(sceneResourceId); + Context &chrContext = chr->_context; + chrContext._statVariables[PHYS_STR_CUR] = strength; + chrContext._statVariables[PHYS_HIT_CUR] = hp; + chrContext._statVariables[PHYS_ARM_CUR] = armor; + chrContext._statVariables[PHYS_ACC_CUR] = accuracy; + chrContext._statVariables[SPIR_STR_CUR] = spirStrength; + chrContext._statVariables[SPIR_HIT_CUR] = spirHp; + chrContext._statVariables[SPIR_ARM_CUR] = spirArmor; + chrContext._statVariables[SPIR_ACC_CUR] = spirAccuracy; + chrContext._statVariables[PHYS_SPE_CUR] = speed; + chr->_rejectsOffers = rejectsOffers; + chr->_followsOpponent = followsOpponent; + chr->_weaponDamage1 = weaponDamage1; + chr->_weaponDamage2 = weaponDamage2; + } + + // update all object locations and stats + Common::Array<Obj *> &orderedObjs = _world->_orderedObjs; + if (numObjs != orderedObjs.size()) { + warning("objects number in file (%d) differs from the one in world (%d)", numObjs, orderedObjs.size()); + } + for (uint32 i = 0; i < orderedObjs.size(); ++i) { + int resourceId = data->readSint16LE(); + int locationResourceId = data->readSint16LE(); + int ownerResourceId = data->readSint16LE(); + + // bytes 7-9 are unknown (always = 0) + data->readByte(); + data->readByte(); + data->readByte(); + + int accuracy = data->readByte(); + int value = data->readByte(); + int type = data->readByte(); + int damage = data->readByte(); + int attackType= data->readByte(); + int numberOfUses = data->readSint16LE(); + + Obj *obj = orderedObjs[i]; + if (obj->_resourceId != resourceId) { + warning("loadGame(): updating objs: expected %d but got %d", obj->_resourceId, resourceId); + continue; + } + + if (ownerResourceId != 0) { + obj->setCurrentOwner(getChrById(ownerResourceId)); + if (obj->_currentOwner == nullptr) + warning("loadGame(): updating objs: owner not found - char with id %d", ownerResourceId); + } else { + obj->setCurrentScene(getSceneById(locationResourceId)); + if (obj->_currentScene == nullptr) + warning("loadGame(): updating objs: scene with id %d not found", ownerResourceId); + } + + obj->_accuracy = accuracy; + obj->_value = value; + obj->_type = type; + obj->_damage = damage; + obj->_attackType = attackType; + obj->_numberOfUses = numberOfUses; + } + + // update inventories and scene contents + for (uint32 i = 0; i < orderedObjs.size(); ++i) { + Obj *obj = orderedObjs[i]; + Chr *chr = obj->_currentOwner; + if (chr != nullptr) { + chr->_inventory.push_back(obj); + } else { + Scene *scene = obj->_currentScene; + scene->_objs.push_back(obj); + } + } + + // update scene chrs + for (uint32 i = 0; i < orderedChrs.size(); ++i) { + Chr *chr = orderedChrs[i]; + Scene *scene = chr->_currentScene; + scene->_chrs.push_back(chr); + if (chr != player) { + wearObjs(chr); + } + } + + // move all worn helmets, shields, chest armors and spiritual + // armors to player + for (int type = 0; type < Chr::NUMBER_OF_ARMOR_TYPES; ++type) { + Obj *armor; + + if (type == Chr::HEAD_ARMOR) + armor = getObjByOffset(helmetOffset, objsHexOffset); + else if (type == Chr::SHIELD_ARMOR) + armor = getObjByOffset(shieldOffset, objsHexOffset); + else if (type == Chr::BODY_ARMOR) + armor = getObjByOffset(armorOffset, objsHexOffset); + else + armor = getObjByOffset(spiritualArmorOffset, objsHexOffset); + + if (armor != nullptr) { + _world->move(armor, player); + player->_armor[type] = armor; + } + } + + //TODO: make sure that armor in the inventory gets put on if we are wearing it + + _loopCount = loopNum; + + // let the engine know if there is a npc in the current scene + if (presCharOffset != 0xffff) { + _monster = getChrByOffset(presCharOffset, chrsHexOffset); + } + + // java engine calls clearOutput(); here + // processTurn("look", NULL); called in Wage right after this loadGame() + + // TODO: as you may see, aim, opponentAim or runCharOffset are not used anywhere + // I'm fixing the first two, as those are clearly not even mentioned anywhere + // the runCharOffset is mentioned up there as "not implemented case" + _aim = aim; + _opponentAim = opponentAim; + + delete data; + return 0; +} + +Common::String WageEngine::getSavegameFilename(int16 slotId) const { + Common::String saveLoadSlot = _targetName; + saveLoadSlot += Common::String::format(".%.3d", slotId); + return saveLoadSlot; +} + +Common::Error WageEngine::loadGameState(int slot) { + if (loadGame(slot) == 0) + return Common::kNoError; + else + return Common::kUnknownError; +} + +Common::Error WageEngine::saveGameState(int slot, const Common::String &description) { + Common::String saveLoadSlot = getSavegameFilename(slot); + if (saveGame(saveLoadSlot, description) == 0) + return Common::kNoError; + else + return Common::kUnknownError; +} + +bool WageEngine::scummVMSaveLoadDialog(bool isSave) { + if (!isSave) { + // do loading + GUI::SaveLoadChooser dialog = GUI::SaveLoadChooser(_("Load game:"), _("Load"), false); + int slot = dialog.runModalWithCurrentTarget(); + + if (slot < 0) + return true; + + return loadGameState(slot).getCode() == Common::kNoError; + } + + // do saving + GUI::SaveLoadChooser dialog = GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); + int slot = dialog.runModalWithCurrentTarget(); + Common::String desc = dialog.getResultString(); + + if (desc.empty()) { + // create our own description for the saved game, the user didnt enter it + desc = dialog.createDefaultSaveDescription(slot); + } + + if (desc.size() > 28) + desc = Common::String(desc.c_str(), 28); + + if (slot < 0) + return true; + + return saveGameState(slot, desc).getCode() == Common::kNoError; +} + +} // End of namespace Agi diff --git a/engines/wage/wage.cpp b/engines/wage/wage.cpp index 567e2768d8..6a33efa02a 100644 --- a/engines/wage/wage.cpp +++ b/engines/wage/wage.cpp @@ -45,6 +45,7 @@ * */ +#include "common/config-manager.h" #include "common/debug-channels.h" #include "common/error.h" #include "common/events.h" @@ -126,6 +127,12 @@ Common::Error WageEngine::run() { _temporarilyHidden = true; performInitialSetup(); + if (ConfMan.hasKey("save_slot")) { + int saveSlot = ConfMan.getInt("save_slot"); + loadGame(saveSlot); + _gui->regenCommandsMenu(); + _gui->regenWeaponsMenu(); + } Common::String input("look"); processTurn(&input, NULL); _temporarilyHidden = false; @@ -307,6 +314,11 @@ void WageEngine::performInitialSetup() { } } +void WageEngine::wearObjs(Chr* chr) { + if (chr != nullptr) + chr->wearObjs(); +} + void WageEngine::doClose() { warning("STUB: doClose()"); } diff --git a/engines/wage/wage.h b/engines/wage/wage.h index eb50a2e3dd..511a2d9e26 100644 --- a/engines/wage/wage.h +++ b/engines/wage/wage.h @@ -208,6 +208,23 @@ public: void redrawScene(); void saveGame(); + virtual Common::Error loadGameState(int slot); + virtual Common::Error saveGameState(int slot, const Common::String &description); + bool scummVMSaveLoadDialog(bool isSave); + +private: + int getSceneIndex(Scene *scene) const; + Obj *getObjByOffset(int offset, int objBaseOffset) const; + Chr *getChrById(int resId) const; + Chr *getChrByOffset(int offset, int chrBaseOffset) const; + Scene *getSceneById(int id) const; + Scene *getSceneByOffset(int offset) const; + int saveGame(const Common::String &fileName, const Common::String &descriptionString); + int loadGame(int slotId); + Common::String getSavegameFilename(int16 slotId) const; + +public: + virtual GUI::Debugger *getDebugger() { return _debugger; } private: diff --git a/engines/wage/world.cpp b/engines/wage/world.cpp index 0e40e114b4..acc2a83d97 100644 --- a/engines/wage/world.cpp +++ b/engines/wage/world.cpp @@ -69,12 +69,13 @@ World::World(WageEngine *engine) { _globalScript = nullptr; _player = nullptr; + _signature = 0; _weaponMenuDisabled = true; _engine = engine; - _patterns = new Patterns; + _patterns = new Graphics::MacPatterns; } World::~World() { @@ -146,7 +147,8 @@ bool World::loadWorld(Common::MacResManager *resMan) { res = resMan->getResource(MKTAG('V','E','R','S'), resArray[0]); - res->skip(10); + _signature = res->readSint32LE(); + res->skip(6); byte b = res->readByte(); _weaponMenuDisabled = (b != 0); if (b != 0 && b != 1) @@ -215,6 +217,8 @@ bool World::loadWorld(Common::MacResManager *resMan) { delete res; } + + scene->_resourceId = *iter; addScene(scene); } @@ -224,7 +228,7 @@ bool World::loadWorld(Common::MacResManager *resMan) { for (iter = resArray.begin(); iter != resArray.end(); ++iter) { res = resMan->getResource(MKTAG('A','O','B','J'), *iter); - addObj(new Obj(resMan->getResName(MKTAG('A','O','B','J'), *iter), res)); + addObj(new Obj(resMan->getResName(MKTAG('A','O','B','J'), *iter), res, *iter)); } // Load Characters @@ -234,7 +238,7 @@ bool World::loadWorld(Common::MacResManager *resMan) { for (iter = resArray.begin(); iter != resArray.end(); ++iter) { res = resMan->getResource(MKTAG('A','C','H','R'), *iter); Chr *chr = new Chr(resMan->getResName(MKTAG('A','C','H','R'), *iter), res); - + chr->_resourceId = *iter; addChr(chr); // TODO: What if there's more than one player character? if (chr->_playerCharacter) diff --git a/engines/wage/world.h b/engines/wage/world.h index 468bedbc59..5c1aaf319e 100644 --- a/engines/wage/world.h +++ b/engines/wage/world.h @@ -48,10 +48,15 @@ #ifndef WAGE_WORLD_H #define WAGE_WORLD_H -#include "wage/macwindowmanager.h" +#include "wage/entities.h" +#include "graphics/macgui/macwindowmanager.h" namespace Wage { +// Import the enum definitions +using Graphics::MacPatterns; + +class Script; class Sound; class World { @@ -87,9 +92,10 @@ public: ObjArray _orderedObjs; ChrArray _orderedChrs; Common::Array<Sound *> _orderedSounds; - Patterns *_patterns; + Graphics::MacPatterns *_patterns; Scene *_storageScene; Chr *_player; + int _signature; //List<MoveListener> moveListeners; Common::String *_gameOverMessage; diff --git a/engines/wintermute/ad/ad_entity.cpp b/engines/wintermute/ad/ad_entity.cpp index 1bbadeb7f7..0909d7ef91 100644 --- a/engines/wintermute/ad/ad_entity.cpp +++ b/engines/wintermute/ad/ad_entity.cpp @@ -1134,4 +1134,7 @@ bool AdEntity::setSprite(const char *filename) { } } +Common::String AdEntity::debuggerToString() const { + return Common::String::format("%p: Entity \"%s\"; (X,Y): (%d, %d), rotate(%d): %f deg, scale(%d): (%f, %f)%%", (const void *)this, getName(), _posX, _posY, _rotatable, _rotate, _zoomable, _scaleX, _scaleY); +} } // End of namespace Wintermute diff --git a/engines/wintermute/ad/ad_entity.h b/engines/wintermute/ad/ad_entity.h index 7e1525b7c1..678608af36 100644 --- a/engines/wintermute/ad/ad_entity.h +++ b/engines/wintermute/ad/ad_entity.h @@ -60,6 +60,7 @@ public: virtual bool scSetProperty(const char *name, ScValue *value) override; virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override; virtual const char *scToString() override; + Common::String debuggerToString() const override; private: int32 _walkToX; int32 _walkToY; diff --git a/engines/wintermute/ad/ad_game.cpp b/engines/wintermute/ad/ad_game.cpp index df0328ce5e..088184b0f6 100644 --- a/engines/wintermute/ad/ad_game.cpp +++ b/engines/wintermute/ad/ad_game.cpp @@ -2280,4 +2280,7 @@ bool AdGame::onScriptShutdown(ScScript *script) { return STATUS_OK; } +Common::String AdGame::debuggerToString() const { + return Common::String::format("%p: Game \"%s\"", (const void *)this, getName()); +} } // End of namespace Wintermute diff --git a/engines/wintermute/ad/ad_game.h b/engines/wintermute/ad/ad_game.h index ebb37e9a07..0e5abc9b3b 100644 --- a/engines/wintermute/ad/ad_game.h +++ b/engines/wintermute/ad/ad_game.h @@ -130,6 +130,7 @@ public: virtual bool scSetProperty(const char *name, ScValue *value) override; virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override; bool validMouse(); + Common::String debuggerToString() const override; private: virtual bool externalCall(ScScript *script, ScStack *stack, ScStack *thisStack, char *name) override; diff --git a/engines/wintermute/ad/ad_scene.cpp b/engines/wintermute/ad/ad_scene.cpp index 02a6aeb801..b57faef69b 100644 --- a/engines/wintermute/ad/ad_scene.cpp +++ b/engines/wintermute/ad/ad_scene.cpp @@ -2998,4 +2998,9 @@ bool AdScene::getRegionObjects(AdRegion *region, BaseArray<AdObject *> &objects, return STATUS_OK; } + +Common::String AdScene::debuggerToString() const { + return Common::String::format("%p: Scene \"%s\", paralax: %d, autoscroll: %d", (const void *)this, getName(), _paralaxScrolling, _autoScroll); +} } // End of namespace Wintermute + diff --git a/engines/wintermute/ad/ad_scene.h b/engines/wintermute/ad/ad_scene.h index 1ca52bdda9..71567d2475 100644 --- a/engines/wintermute/ad/ad_scene.h +++ b/engines/wintermute/ad/ad_scene.h @@ -160,7 +160,7 @@ public: virtual bool scSetProperty(const char *name, ScValue *value) override; virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override; virtual const char *scToString() override; - + virtual Common::String debuggerToString() const override; private: bool persistState(bool saving = true); diff --git a/engines/wintermute/base/base_frame.cpp b/engines/wintermute/base/base_frame.cpp index 471185f2d2..910ab64a76 100644 --- a/engines/wintermute/base/base_frame.cpp +++ b/engines/wintermute/base/base_frame.cpp @@ -764,4 +764,7 @@ const char *BaseFrame::scToString() { return "[frame]"; } +Common::String BaseFrame::debuggerToString() const { + return Common::String::format("%p: Frame \"%s\": #subframes %d ", (const void *)this, getName(), _subframes.size()); +} } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_frame.h b/engines/wintermute/base/base_frame.h index ff9e67a166..8d261c9e71 100644 --- a/engines/wintermute/base/base_frame.h +++ b/engines/wintermute/base/base_frame.h @@ -65,6 +65,8 @@ public: virtual bool scSetProperty(const char *name, ScValue *value) override; virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override; virtual const char *scToString() override; + virtual Common::String debuggerToString() const override; + private: bool _keyframe; bool _editorExpanded; diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp index 668053bb3a..ce4c5fdda5 100644 --- a/engines/wintermute/base/base_game.cpp +++ b/engines/wintermute/base/base_game.cpp @@ -71,6 +71,10 @@ #include "common/system.h" #include "common/file.h" +#if EXTENDED_DEBUGGER_ENABLED == true +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h" +#endif + namespace Wintermute { ////////////////////////////////////////////////////////////////////// @@ -398,7 +402,11 @@ bool BaseGame::initialize1() { break; } +#if EXTENDED_DEBUGGER_ENABLED == true + _scEngine = new DebuggableScEngine(this); +#else _scEngine = new ScEngine(this); +#endif if (_scEngine == nullptr) { break; } diff --git a/engines/wintermute/base/base_game.h b/engines/wintermute/base/base_game.h index e535cc9618..409cc20ba4 100644 --- a/engines/wintermute/base/base_game.h +++ b/engines/wintermute/base/base_game.h @@ -34,7 +34,11 @@ #include "engines/wintermute/persistent.h" #include "engines/wintermute/coll_templ.h" #include "engines/wintermute/math/rect32.h" +#include "engines/wintermute/debugger.h" #include "common/events.h" +#if EXTENDED_DEBUGGER_ENABLED == true +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h" +#endif namespace Wintermute { @@ -148,7 +152,11 @@ public: BaseRenderer *_renderer; BaseSoundMgr *_soundMgr; +#if EXTENDED_DEBUGGER_ENABLED == true + DebuggableScEngine *_scEngine; +#else ScEngine *_scEngine; +#endif BaseScriptable *_mathClass; BaseSurfaceStorage *_surfaceStorage; BaseFontStorage *_fontStorage; diff --git a/engines/wintermute/base/base_region.cpp b/engines/wintermute/base/base_region.cpp index 9a31f5cd66..02ab365eff 100644 --- a/engines/wintermute/base/base_region.cpp +++ b/engines/wintermute/base/base_region.cpp @@ -532,4 +532,7 @@ bool BaseRegion::mimic(BaseRegion *region, float scale, int x, int y) { return createRegion() ? STATUS_OK : STATUS_FAILED; } +Common::String BaseRegion::debuggerToString() const { + return Common::String::format("%p: Region \"%s\": Rect (top, right, bottom, left): (%d, %d, %d, %d), active: %d ", (const void *)this, getName(), _rect.top, _rect.right, _rect.bottom, _rect.left, _active); +} } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_region.h b/engines/wintermute/base/base_region.h index fc3389c501..4cb5dd85d6 100644 --- a/engines/wintermute/base/base_region.h +++ b/engines/wintermute/base/base_region.h @@ -59,6 +59,8 @@ public: virtual bool scSetProperty(const char *name, ScValue *value) override; virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override; virtual const char *scToString() override; + virtual Common::String debuggerToString() const override; + private: float _lastMimicScale; int32 _lastMimicX; diff --git a/engines/wintermute/base/base_script_holder.cpp b/engines/wintermute/base/base_script_holder.cpp index 5b1c961479..7427a9b082 100644 --- a/engines/wintermute/base/base_script_holder.cpp +++ b/engines/wintermute/base/base_script_holder.cpp @@ -42,7 +42,7 @@ IMPLEMENT_PERSISTENT(BaseScriptHolder, false) ////////////////////////////////////////////////////////////////////// BaseScriptHolder::BaseScriptHolder(BaseGame *inGame) : BaseScriptable(inGame) { setName("<unnamed>"); - + _ready = false; _freezable = true; _filename = nullptr; } @@ -312,7 +312,11 @@ bool BaseScriptHolder::addScript(const char *filename) { if (!scr) { if (_gameRef->_editorForceScripts) { // editor hack +#if EXTENDED_DEBUGGER_ENABLED + scr = new DebuggableScript(_gameRef, _gameRef->_scEngine); +#else scr = new ScScript(_gameRef, _gameRef->_scEngine); +#endif scr->_filename = new char[strlen(filename) + 1]; strcpy(scr->_filename, filename); scr->_state = SCRIPT_ERROR; @@ -462,8 +466,15 @@ void BaseScriptHolder::makeFreezable(bool freezable) { ScScript *BaseScriptHolder::invokeMethodThread(const char *methodName) { for (int i = _scripts.size() - 1; i >= 0; i--) { if (_scripts[i]->canHandleMethod(methodName)) { - +#if EXTENDED_DEBUGGER_ENABLED == true + DebuggableScEngine* debuggableEngine; + debuggableEngine = dynamic_cast<DebuggableScEngine*>(_scripts[i]->_engine); + // TODO: Not pretty + assert(debuggableEngine); + ScScript *thread = new DebuggableScript(_gameRef, debuggableEngine); +#else ScScript *thread = new ScScript(_gameRef, _scripts[i]->_engine); +#endif if (thread) { bool ret = thread->createMethodThread(_scripts[i], methodName); if (DID_SUCCEED(ret)) { diff --git a/engines/wintermute/base/base_scriptable.cpp b/engines/wintermute/base/base_scriptable.cpp index c65d30d941..01f6f9e02f 100644 --- a/engines/wintermute/base/base_scriptable.cpp +++ b/engines/wintermute/base/base_scriptable.cpp @@ -188,4 +188,9 @@ ScScript *BaseScriptable::invokeMethodThread(const char *methodName) { return nullptr; } +Common::String BaseScriptable::debuggerToString() const { + return Common::String::format("%p: BaseScriptable %s", (const void *)this, getName()); +} + + } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_scriptable.h b/engines/wintermute/base/base_scriptable.h index b32668d6c8..7b4f269871 100644 --- a/engines/wintermute/base/base_scriptable.h +++ b/engines/wintermute/base/base_scriptable.h @@ -63,6 +63,7 @@ public: virtual void scSetBool(bool val); virtual int scCompare(BaseScriptable *val); virtual void scDebuggerDesc(char *buf, int bufSize); + virtual Common::String debuggerToString() const; int32 _refCount; ScValue *_scValue; ScValue *_scProp; diff --git a/engines/wintermute/base/base_sprite.cpp b/engines/wintermute/base/base_sprite.cpp index 09e138a1fd..f282004a59 100644 --- a/engines/wintermute/base/base_sprite.cpp +++ b/engines/wintermute/base/base_sprite.cpp @@ -826,4 +826,7 @@ bool BaseSprite::killAllSounds() { return STATUS_OK; } +Common::String BaseSprite::debuggerToString() const { + return Common::String::format("%p: Sprite \"%s\"", (const void *)this, getName()); +} } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_sprite.h b/engines/wintermute/base/base_sprite.h index ec71512ec9..2313b7b3dc 100644 --- a/engines/wintermute/base/base_sprite.h +++ b/engines/wintermute/base/base_sprite.h @@ -69,6 +69,7 @@ public: virtual bool scSetProperty(const char *name, ScValue *value) override; virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override; virtual const char *scToString() override; + Common::String debuggerToString() const override; private: BaseObject *_owner; bool _canBreak; diff --git a/engines/wintermute/base/base_sub_frame.cpp b/engines/wintermute/base/base_sub_frame.cpp index 6d0c48ff17..8068e61168 100644 --- a/engines/wintermute/base/base_sub_frame.cpp +++ b/engines/wintermute/base/base_sub_frame.cpp @@ -673,4 +673,8 @@ bool BaseSubFrame::setSurfaceSimple() { } } +Common::String BaseSubFrame::debuggerToString() const { + return Common::String::format("%p: BaseSubFrame \"%s\" - Mirror:(%d, %d), Hotspot:(%d, %d), ", (const void *)this, getName(), _mirrorX, _mirrorY, _hotspotX, _hotspotY); +} + } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_sub_frame.h b/engines/wintermute/base/base_sub_frame.h index f156c332d6..0fd38f9548 100644 --- a/engines/wintermute/base/base_sub_frame.h +++ b/engines/wintermute/base/base_sub_frame.h @@ -86,6 +86,7 @@ public: virtual bool scSetProperty(const char *name, ScValue *value); virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); virtual const char *scToString(); + Common::String debuggerToString() const override; }; diff --git a/engines/wintermute/base/base_viewport.cpp b/engines/wintermute/base/base_viewport.cpp index bf3700a14e..aed0355eb9 100644 --- a/engines/wintermute/base/base_viewport.cpp +++ b/engines/wintermute/base/base_viewport.cpp @@ -96,4 +96,7 @@ int BaseViewport::getHeight() const { return _rect.bottom - _rect.top; } +Common::String BaseViewport::debuggerToString() const { + return Common::String::format("%p: BaseViewport: (top, right, bottom, left): (%d, %d, %d, %d)", (const void *)this, _rect.top, _rect.right, _rect.bottom, _rect.left); +} } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_viewport.h b/engines/wintermute/base/base_viewport.h index eae756f9c6..c2e8727ad8 100644 --- a/engines/wintermute/base/base_viewport.h +++ b/engines/wintermute/base/base_viewport.h @@ -48,6 +48,7 @@ public: BaseObject *_mainObject; BaseViewport(BaseGame *inGame = nullptr); virtual ~BaseViewport(); + virtual Common::String debuggerToString() const; private: Rect32 _rect; }; diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp new file mode 100644 index 0000000000..5a2291894f --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp @@ -0,0 +1,148 @@ +/* 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/tokenizer.h" +#include "debuggable_script.h" +#include "engines/wintermute/base/scriptables/script_stack.h" +#include "engines/wintermute/base/scriptables/script_value.h" +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h" +#include "engines/wintermute/debugger/breakpoint.h" +#include "engines/wintermute/debugger/script_monitor.h" +#include "engines/wintermute/debugger/watch_instance.h" + +namespace Wintermute { + +DebuggableScript::DebuggableScript(BaseGame *inGame, DebuggableScEngine *engine) : ScScript(inGame, engine), _engine(engine), _stepDepth(kDefaultStepDepth) { + _engine->_watches.subscribe(this); + for (uint i = 0; i < _engine->_watches.size(); i++) { + _watchInstances.push_back(new WatchInstance(_engine->_watches[i], this)); + } +} + +DebuggableScript::~DebuggableScript() { + for (uint i = 0; i < _watchInstances.size(); i++) { + delete _watchInstances[i]; + } + _engine->_watches.unsubscribe(this); +} +void DebuggableScript::preInstHook(uint32 inst) {} + +void DebuggableScript::postInstHook(uint32 inst) { + if (inst == II_DBG_LINE) { + for (uint j = 0; j < _engine->_breakpoints.size(); j++) { + _engine->_breakpoints[j]->evaluate(this); + } + + if (_callStack->_sP <= _stepDepth) { + _engine->_monitor->notifyStep(this); + } + } + + for (uint i = 0; i < _watchInstances.size(); i++) { + this->_watchInstances[i]->evaluate(); + } + +} + +void DebuggableScript::setStepDepth(int depth) { + _stepDepth = depth; +} + +void DebuggableScript::step() { + setStepDepth(_callStack->_sP); + // TODO double check +} + +void DebuggableScript::stepContinue() { + setStepDepth(kDefaultStepDepth); +} + +void DebuggableScript::stepFinish() { + setStepDepth(_callStack->_sP - 1); +} + +ScValue *DebuggableScript::resolveName(const Common::String &name) { + + Common::String trimmed = name; + trimmed.trim(); + Common::StringTokenizer st = Common::StringTokenizer(trimmed.c_str(), "."); + Common::String nextToken; + + nextToken = st.nextToken(); + + + char cstr[256]; // TODO not pretty + Common::strlcpy(cstr, nextToken.c_str(), nextToken.size() + 1); + cstr[255] = '\0'; // We 0-terminate it just in case it's > 256 chars. + + ScValue *value = getVar(cstr); + ScValue *res = new ScValue(_gameRef); + + if (value == nullptr) { + return res; + } + + nextToken = st.nextToken(); + + while (nextToken.size() > 0 && (value->isObject() || value->isNative())) { + value = value->getProp(nextToken.c_str()); + nextToken = st.nextToken(); + if (value == nullptr) { + return res; + } + } + + res->copy(value); + + return res; +} + +uint DebuggableScript::dbgGetLine() const { + return _currentLine; +} + +Common::String DebuggableScript::dbgGetFilename() const { + return _filename; +} + +void DebuggableScript::updateWatches() { + // We drop obsolete watches + for (uint i = 0; i < _watchInstances.size(); i++) { + Watch *findMe = _watchInstances[i]->_watch; + if (Common::find(_engine->_watches.begin(), _engine->_watches.end(), findMe) == _engine->_watches.end()) { + // Not found on engine-wide list, must have been removed from watches. Must remove it from local list. + delete _watchInstances[i]; + _watchInstances.remove_at(i); + } + } + + // We add any new watches + for (uint i = 0; i < _engine->_watches.size(); i++) { + Watch *findMe = _engine->_watches[i]; + if (Common::find(_engine->_watches.begin(), _engine->_watches.end(), findMe) == _engine->_watches.end()) { + // Not found on local list, must be a new one. + _watchInstances.push_back(new WatchInstance(_engine->_watches[i], this)); + } + } +} +} // End of namespace Wintermute + diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.h b/engines/wintermute/base/scriptables/debuggable/debuggable_script.h new file mode 100644 index 0000000000..b32a5ca4af --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.h @@ -0,0 +1,67 @@ +/* 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 DEBUGGABLE_SCRIPT_H_ +#define DEBUGGABLE_SCRIPT_H_ +#include "engines/wintermute/base/scriptables/script.h" + +namespace Wintermute { +class ScriptMonitor; +class Watch; +class WatchInstance; +class DebuggableScEngine; + +class DebuggableScript : public ScScript { + static const int kDefaultStepDepth = -2; + int32 _stepDepth; + DebuggableScEngine *_engine; + BaseArray<WatchInstance *> _watchInstances; + virtual void preInstHook(uint32 inst) override; + virtual void postInstHook(uint32 inst) override; + void setStepDepth(int depth); +public: + DebuggableScript(BaseGame *inGame, DebuggableScEngine *engine); + virtual ~DebuggableScript(); + ScValue *resolveName(const Common::String &name); + /** + * Return argument to last II_DBG_LINE encountered + */ + virtual uint dbgGetLine() const; + virtual Common::String dbgGetFilename() const; + /** + * Execute one more instruction + */ + void step(); + /** + * Continue execution + */ + void stepContinue(); + /** + * Continue execution until the activation record on top of the stack is popped + */ + void stepFinish(); + void updateWatches(); +}; + +} // End of namespace Wintermute + +#endif /* DEBUGGABLE_SCRIPT_H_ */ diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp new file mode 100644 index 0000000000..28a00cd4ae --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp @@ -0,0 +1,35 @@ +/* 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 "debuggable_script_engine.h" +#include "debuggable_script.h" +#include "engines/wintermute/debugger/watch_instance.h" + +namespace Wintermute { + +DebuggableScEngine::DebuggableScEngine(BaseGame *inGame) : ScEngine(inGame), _monitor(nullptr) {} + +void DebuggableScEngine::attachMonitor(ScriptMonitor *monitor) { + _monitor = monitor; +} + +} // End of namespace Wintermute diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h new file mode 100644 index 0000000000..a4d9d2bfe7 --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h @@ -0,0 +1,110 @@ +/* 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 DEBUGGABLE_SCRIPT_ENGINE_H_ +#define DEBUGGABLE_SCRIPT_ENGINE_H_ +#include "engines/wintermute/base/scriptables/script_engine.h" +#include "engines/wintermute/coll_templ.h" +#include "common/algorithm.h" +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h" + +namespace Wintermute { + +class Breakpoint; +class Watch; +class DebuggableScript; +class DebuggableScEngine; +class ScriptMonitor; + +class PublisherWArray : private Common::Array<Watch *> { + Common::Array<DebuggableScript *> _subscribers; + void notifySubscribers() { + for (uint i = 0; i < _subscribers.size(); i++) { + _subscribers[i]->updateWatches(); + } + } +public: + void subscribe(DebuggableScript *script) { + if (Common::find(_subscribers.begin(), _subscribers.end(), script) == _subscribers.end()) { + // If not already contained + _subscribers.push_back(script); + } + } + + void unsubscribe(DebuggableScript *script) { + int location = -1; + for (uint i = 0; i < _subscribers.size() && location == -1; i++) { + if (_subscribers[i] == script) { + location = i; + } + } + if (location >= 0) { + _subscribers.remove_at(location); + } else { + // TODO: If this happens... it's funny. Some script out there forgot to subscribe. + } + } + + void push_back(Watch *newElement) { + Common::Array<Watch *>::push_back(newElement); + notifySubscribers(); + } + + size_type size() { + return Common::Array<Watch *>::size(); + } + + iterator begin() { + return Common::Array<Watch *>::begin(); + } + + iterator end() { + return Common::Array<Watch *>::end(); + } + + Watch *&operator[](size_type idx) { + return Common::Array<Watch *>::operator[](idx); + } + Watch *remove_at(size_type idx) { + Watch *res = Common::Array<Watch *>::remove_at(idx); + notifySubscribers(); + return res; + } +}; + +class DebuggableScEngine : public ScEngine { + Common::Array<Breakpoint *> _breakpoints; + PublisherWArray _watches; + ScriptMonitor *_monitor; +public: + DebuggableScEngine(BaseGame *inGame); + void attachMonitor(ScriptMonitor *); + + friend class DebuggerController; + friend class DebuggableScript; + friend class ScScript; + friend class WatchableScriptArray; +}; + +} // End of namespace Wintermute + +#endif /* DEBUGGABLE_SCRIPT_ENGINE_H_ */ diff --git a/engines/wintermute/base/scriptables/script.cpp b/engines/wintermute/base/scriptables/script.cpp index 44fd117e61..938ec031da 100644 --- a/engines/wintermute/base/scriptables/script.cpp +++ b/engines/wintermute/base/scriptables/script.cpp @@ -32,7 +32,9 @@ #include "engines/wintermute/base/scriptables/script_engine.h" #include "engines/wintermute/base/scriptables/script_stack.h" #include "common/memstream.h" - +#if EXTENDED_DEBUGGER_ENABLED == true +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h" +#endif namespace Wintermute { IMPLEMENT_PERSISTENT(ScScript, false) @@ -522,6 +524,9 @@ bool ScScript::executeInstruction() { ScValue *op2; uint32 inst = getDWORD(); + + preInstHook(inst); + switch (inst) { case II_DEF_VAR: @@ -1092,6 +1097,7 @@ bool ScScript::executeInstruction() { ret = STATUS_FAILED; } // switch(instruction) + postInstHook(inst); //delete op; return ret; @@ -1314,8 +1320,15 @@ ScScript *ScScript::invokeEventHandler(const Common::String &eventName, bool unb if (!pos) { return nullptr; } - +#if EXTENDED_DEBUGGER_ENABLED == true + // TODO: Not pretty + DebuggableScEngine* debuggableEngine; + debuggableEngine = dynamic_cast<DebuggableScEngine*>(_engine); + assert(debuggableEngine); + ScScript *thread = new DebuggableScript(_gameRef, debuggableEngine); +#else ScScript *thread = new ScScript(_gameRef, _engine); +#endif if (thread) { bool ret = thread->createThread(this, pos, eventName); if (DID_SUCCEED(ret)) { @@ -1434,18 +1447,6 @@ bool ScScript::finishThreads() { return STATUS_OK; } - -////////////////////////////////////////////////////////////////////////// -// IWmeDebugScript interface implementation -int ScScript::dbgGetLine() { - return _currentLine; -} - -////////////////////////////////////////////////////////////////////////// -const char *ScScript::dbgGetFilename() { - return _filename; -} - ////////////////////////////////////////////////////////////////////////// void ScScript::afterLoad() { if (_buffer == nullptr) { @@ -1466,4 +1467,8 @@ void ScScript::afterLoad() { } } +void ScScript::preInstHook(uint32 inst) {} + +void ScScript::postInstHook(uint32 inst) {} + } // End of namespace Wintermute diff --git a/engines/wintermute/base/scriptables/script.h b/engines/wintermute/base/scriptables/script.h index 1edeae5b55..c1d1cce4ee 100644 --- a/engines/wintermute/base/scriptables/script.h +++ b/engines/wintermute/base/scriptables/script.h @@ -33,12 +33,15 @@ #include "engines/wintermute/base/base.h" #include "engines/wintermute/base/scriptables/dcscript.h" // Added by ClassView #include "engines/wintermute/coll_templ.h" +#include "engines/wintermute/persistent.h" namespace Wintermute { class BaseScriptHolder; class BaseObject; class ScEngine; class ScStack; +class ScValue; + class ScScript : public BaseClass { public: BaseArray<int> _breakpoints; @@ -50,7 +53,7 @@ public: bool copyParameters(ScStack *stack); void afterLoad(); -private: +protected: ScValue *_operand; ScValue *_reg1; public: @@ -125,7 +128,7 @@ public: ScValue *_globals; ScEngine *_engine; int32 _currentLine; - bool executeInstruction(); + virtual bool executeInstruction(); char *getString(); uint32 getDWORD(); double getFloat(); @@ -162,11 +165,8 @@ private: bool initScript(); bool initTables(); - -// IWmeDebugScript interface implementation -public: - virtual int dbgGetLine(); - virtual const char *dbgGetFilename(); + virtual void preInstHook(uint32 inst); + virtual void postInstHook(uint32 inst); }; } // End of namespace Wintermute diff --git a/engines/wintermute/base/scriptables/script_engine.cpp b/engines/wintermute/base/scriptables/script_engine.cpp index cdf55a304c..26122094f1 100644 --- a/engines/wintermute/base/scriptables/script_engine.cpp +++ b/engines/wintermute/base/scriptables/script_engine.cpp @@ -144,7 +144,15 @@ ScScript *ScEngine::runScript(const char *filename, BaseScriptHolder *owner) { } // add new script +#if EXTENDED_DEBUGGER_ENABLED == true + DebuggableScEngine* debuggableEngine; + debuggableEngine = dynamic_cast<DebuggableScEngine*>(this); + // TODO: Not pretty + assert(debuggableEngine); + ScScript *script = new DebuggableScript(_gameRef, debuggableEngine); +#else ScScript *script = new ScScript(_gameRef, this); +#endif bool ret = script->create(filename, compBuffer, compSize, owner); if (DID_FAIL(ret)) { _gameRef->LOG(ret, "Error running script '%s'...", filename); diff --git a/engines/wintermute/base/scriptables/script_engine.h b/engines/wintermute/base/scriptables/script_engine.h index bdb139e1f8..8b7e4acd19 100644 --- a/engines/wintermute/base/scriptables/script_engine.h +++ b/engines/wintermute/base/scriptables/script_engine.h @@ -66,20 +66,6 @@ public: Common::String _filename; }; - class CScBreakpoint { - public: - CScBreakpoint(const char *filename) { - _filename = filename; - } - - ~CScBreakpoint() { - _lines.clear(); - } - - Common::String _filename; - BaseArray<int> _lines; - }; - public: bool clearGlobals(bool includingNatives = false); bool tickUnbreakable(); diff --git a/engines/wintermute/debugger.cpp b/engines/wintermute/debugger.cpp index 5b617d9db9..c643c33246 100644 --- a/engines/wintermute/debugger.cpp +++ b/engines/wintermute/debugger.cpp @@ -21,29 +21,289 @@ */ #include "engines/wintermute/debugger.h" -#include "engines/wintermute/wintermute.h" #include "engines/wintermute/base/base_engine.h" #include "engines/wintermute/base/base_file_manager.h" -#include "engines/wintermute/base/base_game.h" +#include "engines/wintermute/base/scriptables/script_value.h" +#include "engines/wintermute/debugger/debugger_controller.h" +#include "engines/wintermute/wintermute.h" + +#define CONTROLLER _engineRef->_dbgController namespace Wintermute { Console::Console(WintermuteEngine *vm) : GUI::Debugger(), _engineRef(vm) { registerCmd("show_fps", WRAP_METHOD(Console, Cmd_ShowFps)); registerCmd("dump_file", WRAP_METHOD(Console, Cmd_DumpFile)); + registerCmd("show_fps", WRAP_METHOD(Console, Cmd_ShowFps)); + registerCmd("dump_file", WRAP_METHOD(Console, Cmd_DumpFile)); + registerCmd("help", WRAP_METHOD(Console, Cmd_Help)); + // Actual (script) debugger commands + registerCmd(STEP_CMD, WRAP_METHOD(Console, Cmd_Step)); + registerCmd(CONTINUE_CMD, WRAP_METHOD(Console, Cmd_Continue)); + registerCmd(FINISH_CMD, WRAP_METHOD(Console, Cmd_Finish)); + registerCmd(WATCH_CMD, WRAP_METHOD(Console, Cmd_Watch)); + registerCmd(BREAK_CMD, WRAP_METHOD(Console, Cmd_AddBreakpoint)); + registerCmd(LIST_CMD, WRAP_METHOD(Console, Cmd_List)); + registerCmd(REMOVE_BREAKPOINT_CMD, WRAP_METHOD(Console, Cmd_RemoveBreakpoint)); + registerCmd(DISABLE_BREAKPOINT_CMD, WRAP_METHOD(Console, Cmd_DisableBreakpoint)); + registerCmd(ENABLE_BREAKPOINT_CMD, WRAP_METHOD(Console, Cmd_EnableBreakpoint)); + registerCmd(REMOVE_WATCH_CMD, WRAP_METHOD(Console, Cmd_RemoveWatch)); + registerCmd(DISABLE_WATCH_CMD, WRAP_METHOD(Console, Cmd_DisableWatch)); + registerCmd(ENABLE_WATCH_CMD, WRAP_METHOD(Console, Cmd_EnableWatch)); + registerCmd(PRINT_CMD, WRAP_METHOD(Console, Cmd_Print)); + registerCmd(SET_CMD, WRAP_METHOD(Console, Cmd_Set)); + registerCmd(INFO_CMD, WRAP_METHOD(Console, Cmd_Info)); + registerCmd(SET_PATH_CMD, WRAP_METHOD(Console, Cmd_SourcePath)); + registerCmd(TOP_CMD, WRAP_METHOD(Console, Cmd_Top)); } Console::~Console(void) { +} + +bool Console::Cmd_Help(int argc, const char **argv) { + if (argc == 1) { + // Debugger::Cmd_Help(argc, argv); + debugPrintf("\nType help somecommand to get specific help.\n"); + } else { + printUsage(argv[1]); + } + return true; +} +void Console::printUsage(const Common::String &command) { + // TODO: This is horrible and would probably benefit from a map or something. + if (command.equals(BREAK_CMD)) { + debugPrintf("Usage: %s <file path> <line> to break at line <line> of file <file path>\n", command.c_str()); + } else if (command.equals(REMOVE_BREAKPOINT_CMD)) { + debugPrintf("Usage: %s <id> to remove breakpoint #id\n", command.c_str()); + } else if (command.equals(ENABLE_BREAKPOINT_CMD)) { + debugPrintf("Usage: %s <id> to enable breakpoint #id\n", command.c_str()); + } else if (command.equals(DISABLE_BREAKPOINT_CMD)) { + debugPrintf("Usage: %s <id> to disable breakpoint #id\n", command.c_str()); + } else if (command.equals(REMOVE_WATCH_CMD)) { + debugPrintf("Usage: %s <id> to remove watchpoint #id\n", command.c_str()); + } else if (command.equals(ENABLE_WATCH_CMD)) { + debugPrintf("Usage: %s <id> to enable watchpoint #id\n", command.c_str()); + } else if (command.equals(DISABLE_WATCH_CMD)) { + debugPrintf("Usage: %s <id> to disable watchpoint #id\n", command.c_str()); + } else if (command.equals(INFO_CMD)) { + debugPrintf("Usage: %s [watch|breakpoints]\n", command.c_str()); + } else if (command.equals(WATCH_CMD)) { + debugPrintf("Usage: %s <file path> <name> to watch for <name> in file <file path>\n", command.c_str()); + } else if (command.equals(STEP_CMD)) { + debugPrintf("Usage: %s to step\n", command.c_str()); + } else if (command.equals(CONTINUE_CMD)) { + debugPrintf("Usage: %s to continue\n", command.c_str()); + } else if (command.equals(FINISH_CMD)) { + debugPrintf("Usage: %s to finish\n", command.c_str()); + } else if (command.equals(PRINT_CMD)) { + debugPrintf("Usage: %s <name> to print value of <name>\n", command.c_str()); + } else if (command.equals(SET_CMD)) { + debugPrintf("Usage: %s <name> = <value> to set <name> to <value>\n", command.c_str()); + } else { + debugPrintf("No help about this command, sorry."); + } +} + +bool Console::Cmd_AddBreakpoint(int argc, const char **argv) { + if (argc == 3) { + Wintermute::Error error = CONTROLLER->addBreakpoint(argv[1], atoi(argv[2])); + printError(argv[0], error); + } else { + printUsage(argv[0]); + } + return true; +} + +bool Console::Cmd_RemoveBreakpoint(int argc, const char **argv) { + if (argc == 2) { + Error error = CONTROLLER->removeBreakpoint(atoi(argv[1])); + printError(argv[0], error); + } else { + printUsage(argv[0]); + } + return true; +} + +bool Console::Cmd_EnableBreakpoint(int argc, const char **argv) { + if (argc == 2) { + Error error = CONTROLLER->enableBreakpoint(atoi(argv[1])); + printError(argv[0], error); + } else { + printUsage(argv[0]); + } + return true; +} + +bool Console::Cmd_DisableBreakpoint(int argc, const char **argv) { + if (argc == 2) { + Error error = CONTROLLER->disableBreakpoint(atoi(argv[1])); + debugPrintf("%s: %s\n", argv[0], error.getErrorDisplayStr().c_str()); + } else { + printUsage(argv[0]); + } + return true; +} + +bool Console::Cmd_RemoveWatch(int argc, const char **argv) { + if (argc == 2) { + Error error = CONTROLLER->removeWatchpoint(atoi(argv[1])); + printError(argv[0], error); + } else { + printUsage(argv[0]); + } + + return true; +} + +bool Console::Cmd_EnableWatch(int argc, const char **argv) { + if (argc == 2) { + Error error = CONTROLLER->enableWatchpoint(atoi(argv[1])); + printError(argv[0], error); + } else { + printUsage(argv[0]); + } + return true; +} + +bool Console::Cmd_DisableWatch(int argc, const char **argv) { + if (argc == 2) { + Error error = CONTROLLER->disableWatchpoint(atoi(argv[1])); + printError(argv[0], error); + } else { + printUsage(argv[0]); + } + return true; +} + +bool Console::Cmd_Watch(int argc, const char **argv) { + if (argc == 3) { + Error error = CONTROLLER->addWatch(argv[1], argv[2]); + printError(argv[0], error); + } else { + printUsage(argv[0]); + } + return true; +} + +bool Console::Cmd_Info(int argc, const char **argv) { + if (argc == 2 && !strncmp(argv[1], "breakpoints", 10)) { + Common::Array<BreakpointInfo> breakpoints = CONTROLLER->getBreakpoints(); + for (uint i = 0; i < breakpoints.size(); i++) { + debugPrintf("%d %s:%d x%d, enabled: %d \n", i, breakpoints[i]._filename.c_str(), breakpoints[i]._line, breakpoints[i]._hits, breakpoints[i]._enabled); + } + return 1; + } else if (argc == 2 && !strncmp(argv[1], WATCH_CMD, 5)) { + Common::Array<WatchInfo>watchlist = CONTROLLER->getWatchlist(); + for (uint i = 0; i < watchlist.size(); i++) { + debugPrintf("%d %s:%s x%d \n", i, watchlist[i]._filename.c_str(), watchlist[i]._symbol.c_str(), watchlist[i]._hits); + } + return 1; + } else { + printUsage(argv[0]); + return 1; + } +} + +bool Console::Cmd_Step(int argc, const char **argv) { + if (argc == 1) { + Error error = CONTROLLER->step(); + if (error.getErrorLevel() == SUCCESS) { + return false; + } else { + printError(argv[0], error); + return true; + } + } else { + printUsage(argv[0]); + return true; + } +} + +bool Console::Cmd_Continue(int argc, const char **argv) { + if (argc == 1) { + Error error = CONTROLLER->stepContinue(); + if (error.getErrorLevel() == SUCCESS) { + return false; + } else { + printError(argv[0], error); + return true; + } + } else { + printUsage(argv[0]); + return true; + } +} + +bool Console::Cmd_Finish(int argc, const char **argv) { + if (argc == 1) { + Error error = CONTROLLER->stepFinish(); + printError(argv[0], error); + if (error.getErrorLevel() == SUCCESS) { + return false; + } else { + printError(argv[0], error); + return true; + } + } else { + printUsage(argv[0]); + return true; + } +} + +bool Console::Cmd_List(int argc, const char **argv) { + Error error = printSource(); + if (error.getErrorLevel() != SUCCESS) { + printError(argv[0], error); + } + return true; +} + +bool Console::Cmd_Print(int argc, const char **argv) { + if (argc == 2) { + Error error = Error(SUCCESS, OK, 0); + Common::String temp = CONTROLLER->readValue(argv[1], &error); + if (error.getErrorLevel() == SUCCESS) { + debugPrintf("%s = %s \n", argv[1], temp.c_str()); + return true; + } else { + printError(argv[0], error); + return true; + } + } else { + printUsage(argv[0]); + return true; + } +} + + +bool Console::Cmd_Set(int argc, const char **argv) { + if (argc == 4 && !strncmp("=", argv[2], 1)) { + ScValue *val = nullptr; + Error error = CONTROLLER->setValue(argv[1], argv[3], val); + if (error.getErrorLevel() == SUCCESS) { + assert(val); + debugPrintf("%s = %s\n", argv[1], val->getString()); + } else { + printError(argv[0], error); + } + } else { + printUsage(argv[0]); + } + return true; } bool Console::Cmd_ShowFps(int argc, const char **argv) { - if (argc > 1) { + if (argc == 2) { if (Common::String(argv[1]) == "true") { - _engineRef->_game->setShowFPS(true); + CONTROLLER->showFps(true); } else if (Common::String(argv[1]) == "false") { - _engineRef->_game->setShowFPS(false); + CONTROLLER->showFps(false); + } else { + debugPrintf("%s: argument 1 must be \"true\" or \"false\"\n", argv[0]); } + } else { + debugPrintf("Usage: %s [true|false]\n", argv[0]); } return true; } @@ -81,4 +341,80 @@ bool Console::Cmd_DumpFile(int argc, const char **argv) { return true; } + +bool Console::Cmd_SourcePath(int argc, const char **argv) { + if (argc != 2) { + debugPrintf("Usage: %s <source path>\n", argv[0]); + return true; + } else { + if (CONTROLLER->setSourcePath(Common::String(argv[1])).getErrorCode() == OK) { + debugPrintf("Source path set to '%s'\n", CONTROLLER->getSourcePath().c_str()); + } else { + debugPrintf("Error setting source path. Note that \"\" is illegal."); + } + return true; + } +} + +void Console::notifyBreakpoint(const char *filename, int line) { + debugPrintf("Breakpoint hit %s: %d\n", filename, line); + printSource(0); + attach(); + onFrame(); +} + +void Console::notifyStep(const char *filename, int line) { + debugPrintf("Step: %s:%d\n", filename, line); + printSource(0); + attach(); + onFrame(); +} + +void Console::notifyWatch(const char *filename, const char *symbol, const char *newValue) { + debugPrintf("Watch: %s:%s <---- %s\n", filename, symbol, newValue); + printSource(0); + attach(); + onFrame(); +} + +Error Console::printSource(int n) { + + Error* error = nullptr; + Listing *listing = CONTROLLER->getListing(error); + Error err(*error); + delete error; + + if (err.getErrorLevel() == SUCCESS || err.getErrorLevel() == WARNING) { + Common::Array<ListingLine> lines = listing->getLines(CONTROLLER->getLastLine(), n/2, n/2); + for (uint i = 0; i < lines.size(); i++) { + if (lines[i].number == CONTROLLER->getLastLine()) { + debugPrintf(" -> "); + } else { + debugPrintf(" "); + } + debugPrintf("%d", lines[i].number); + debugPrintf("%s", lines[i].text.c_str()); + debugPrintf("\n"); + } + } + + delete listing; + return err; +} + +bool Console::Cmd_Top(int argc, const char **argv) { + Common::Array<TopEntry> entries = CONTROLLER->getTop(); + for (uint i = 0; i < entries.size(); i++) { + if (entries[i].current) { + debugPrintf("%d*: %s\n", i, entries[i].filename.c_str()); + } else { + debugPrintf("%d: %s\n", i, entries[i].filename.c_str()); + } + } + return true; +} + +void Console::printError(const Common::String &command, Error error) { + debugPrintf("%s: %s\n", command.c_str(), error.getErrorDisplayStr().c_str()); +} } // End of namespace Wintermute diff --git a/engines/wintermute/debugger.h b/engines/wintermute/debugger.h index 625da0ce41..e5008bee3b 100644 --- a/engines/wintermute/debugger.h +++ b/engines/wintermute/debugger.h @@ -23,20 +23,134 @@ #ifndef WINTERMUTE_DEBUGGER_H #define WINTERMUTE_DEBUGGER_H +#define EXTENDED_DEBUGGER_ENABLED true + #include "gui/debugger.h" -namespace Wintermute { +#if EXTENDED_DEBUGGER_ENABLED == true +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h" +#else +#include "engines/wintermute/base/scriptables/script.h" +#endif + +#define DEFAULT_SOURCE_PADDING 5 + +#define STEP_CMD "step" +#define CONTINUE_CMD "continue" +#define FINISH_CMD "finish" +#define WATCH_CMD "watch" +#define BREAK_CMD "break" +#define LIST_CMD "list" +#define REMOVE_BREAKPOINT_CMD "del" +#define DISABLE_BREAKPOINT_CMD "disable" +#define ENABLE_BREAKPOINT_CMD "enable" +#define REMOVE_WATCH_CMD "delw" +#define DISABLE_WATCH_CMD "disablew" +#define ENABLE_WATCH_CMD "enablew" +#define INFO_CMD "info" +#define SET_CMD "set" +#define PRINT_CMD "print" +#define SET_PATH_CMD "set_path" +#define TOP_CMD "top" + +namespace Wintermute { class WintermuteEngine; +class Adapter; +class DebuggerController; +class Error; + class Console : public GUI::Debugger { public: Console(WintermuteEngine *vm); virtual ~Console(); - + /* + * Debug commands + */ + bool Cmd_Help(int argc, const char **argv); bool Cmd_ShowFps(int argc, const char **argv); bool Cmd_DumpFile(int argc, const char **argv); + +#if EXTENDED_DEBUGGER_ENABLED == true + /** + * Step - break again on next line + */ + bool Cmd_Step(int argc, const char **argv); + /** + * Continue execution + */ + bool Cmd_Continue(int argc, const char **argv); + /** + * Only break again when the current function is finished + * (activation record is popped) + */ + bool Cmd_Finish(int argc, const char **argv); + bool Cmd_Print(int argc, const char **argv); + bool Cmd_Set(int argc, const char **argv); + // Breakpoints + bool Cmd_AddBreakpoint(int argc, const char **argv); + bool Cmd_RemoveBreakpoint(int argc, const char **argv); + bool Cmd_EnableBreakpoint(int argc, const char **argv); + bool Cmd_DisableBreakpoint(int argc, const char **argv); + /** + * Add a watch. + * + * It monitors the value of some variable x against its + * last known state and it breaks if it has changed since. + * + */ + bool Cmd_Watch(int argc, const char **argv); + bool Cmd_RemoveWatch(int argc, const char **argv); + bool Cmd_EnableWatch(int argc, const char **argv); + bool Cmd_DisableWatch(int argc, const char **argv); + /** + * Print info re:watch and breakpoints. + * This differs from e.g. gdb in that we have separate lists. + */ + bool Cmd_Info(int argc, const char **argv); + /** + * Print source + */ + bool Cmd_List(int argc, const char **argv); + /** + * Set (DOS-style) source path for debugging. + * This is where you will (optionally) put your sources + * to enable printing of sources as you step through the + * scripts. + * + * Please note that we have no checksum or anything + * to make sure your source files are up to date. + * + * YOU HAVE to make sure of that. + * + * You have been warned! :) + */ + bool Cmd_SourcePath(int argc, const char **argv); + + /** + * Top + */ + bool Cmd_Top(int argc, const char **argv); + + Error printSource(int n = DEFAULT_SOURCE_PADDING); + + /** + * Hooks for the controller to open the console + */ + void notifyBreakpoint(const char *filename, int line); + void notifyStep(const char *filename, int line); + /** + * To be called by the adapter when a watched variable + * is changed. + * Opens a console and prints info and listing if available. + */ + void notifyWatch(const char *filename, const char *symbol, const char *newValue); +#endif + private: - WintermuteEngine *_engineRef; + const WintermuteEngine *_engineRef; + void printError(const Common::String &command, Error error); + void printUsage(const Common::String &command); }; } diff --git a/engines/wintermute/debugger/breakpoint.cpp b/engines/wintermute/debugger/breakpoint.cpp new file mode 100644 index 0000000000..7f2a02b0ea --- /dev/null +++ b/engines/wintermute/debugger/breakpoint.cpp @@ -0,0 +1,68 @@ +/* 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 "breakpoint.h" +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h" +#include "script_monitor.h" + +namespace Wintermute { + +Breakpoint::Breakpoint(const Common::String &filename, uint line, ScriptMonitor *monitor) : + _filename(filename), _line(line), _monitor(monitor), _enabled(0), _hits(0) {} + +void Breakpoint::hit(DebuggableScript *script) { + _hits++; + _monitor->onBreakpoint(this, script); +} + +Common::String Breakpoint::getFilename() const { + return _filename; +} +int Breakpoint::getLine() const { + return _line; +} +int Breakpoint::getHits() const { + return _hits; +} +bool Breakpoint::isEnabled() const { + return _enabled; +} +void Breakpoint::enable() { + _enabled = true; +} +void Breakpoint::disable() { + _enabled = false; +} + +void Breakpoint::evaluate(DebuggableScript *script) { + if (isEnabled() && + getLine() == script->_currentLine && + !getFilename().compareTo(script->_filename)) { + hit(script); + } +} + +Breakpoint::~Breakpoint() { + // Nothing to take care of in here +} + +} // End of namespace Wintermute diff --git a/engines/wintermute/debugger/breakpoint.h b/engines/wintermute/debugger/breakpoint.h new file mode 100644 index 0000000000..3757791ba3 --- /dev/null +++ b/engines/wintermute/debugger/breakpoint.h @@ -0,0 +1,58 @@ +/* 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 BREAKPOINT_H_ +#define BREAKPOINT_H_ +#include "common/str.h" + +namespace Wintermute { + +class ScriptMonitor; +class DebuggableScript; + +class Breakpoint { + const Common::String _filename; + const uint _line; + uint _hits; + bool _enabled; + ScriptMonitor *_monitor; + void hit(DebuggableScript *script); +public: + Breakpoint(const Common::String &filename, uint line, ScriptMonitor *monitor); + /** + * This should be called inside the interpreter; the breakpoint is evaluated + * in the context of script, and, if it is enabled and filename & line match, + * the attached ScriptMonitor is notified. + */ + void evaluate(DebuggableScript* script); + Common::String getFilename() const; + int getLine() const; + int getHits() const; + bool isEnabled() const; + void enable(); + void disable(); + virtual ~Breakpoint(); +}; + +} // End of namespace Wintermute + +#endif /* BREAKPOINT_H_ */ diff --git a/engines/wintermute/debugger/debugger_controller.cpp b/engines/wintermute/debugger/debugger_controller.cpp new file mode 100644 index 0000000000..aef96ed9c9 --- /dev/null +++ b/engines/wintermute/debugger/debugger_controller.cpp @@ -0,0 +1,325 @@ +/* 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/algorithm.h" +#include "common/str.h" +#include "common/tokenizer.h" +#include "engines/wintermute/debugger.h" +#include "engines/wintermute/base/base_file_manager.h" +#include "engines/wintermute/base/base_engine.h" +#include "engines/wintermute/base/base_game.h" +#include "engines/wintermute/base/scriptables/script.h" +#include "engines/wintermute/base/scriptables/script_value.h" +#include "engines/wintermute/base/scriptables/script_stack.h" +#include "engines/wintermute/debugger/breakpoint.h" +#include "engines/wintermute/debugger/debugger_controller.h" +#include "engines/wintermute/debugger/watch.h" +#include "engines/wintermute/debugger/listing_providers/blank_listing_provider.h" +#include "engines/wintermute/debugger/listing_providers/cached_source_listing_provider.h" +#include "engines/wintermute/debugger/listing_providers/source_listing.h" +#define SCENGINE _engine->_game->_scEngine +#define DEBUGGER _engine->_debugger + +namespace Wintermute { + +DebuggerController::~DebuggerController() { + delete _sourceListingProvider; +} + +DebuggerController::DebuggerController(WintermuteEngine *vm) : _engine(vm) { + _sourceListingProvider = new CachedSourceListingProvider(); + clear(); +} + +bool DebuggerController::bytecodeExists(const Common::String &filename) { + uint32 compSize; + byte *compBuffer = SCENGINE->getCompiledScript(filename.c_str(), &compSize); + if (!compBuffer) { + return false; + } else { + return true; + } +} + +Error DebuggerController::addBreakpoint(const char *filename, int line) { + assert(SCENGINE); + if (bytecodeExists(filename)) { + SCENGINE->_breakpoints.push_back(new Breakpoint(filename, line, this)); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BYTECODE); + } +} + +Error DebuggerController::removeBreakpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_breakpoints.size() > id) { + SCENGINE->_breakpoints.remove_at(id); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } +} + +Error DebuggerController::disableBreakpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_breakpoints.size() > id) { + SCENGINE->_breakpoints[id]->disable(); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } +} + +Error DebuggerController::enableBreakpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_breakpoints.size() > id) { + SCENGINE->_breakpoints[id]->enable(); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } +} + +Error DebuggerController::removeWatchpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_watches.size() > id) { + SCENGINE->_watches.remove_at(id); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } +} + + +Error DebuggerController::disableWatchpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_watches.size() > id) { + SCENGINE->_watches[id]->disable(); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } +} + +Error DebuggerController::enableWatchpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_watches.size() > id) { + SCENGINE->_watches[id]->enable(); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } + +} + +Error DebuggerController::addWatch(const char *filename, const char *symbol) { + assert(SCENGINE); + if (!bytecodeExists(filename)) { + return Error(ERROR, NO_SUCH_BYTECODE, filename); + } + SCENGINE->_watches.push_back(new Watch(filename, symbol, this)); + return Error(SUCCESS, OK, "Watchpoint added"); +} + +void DebuggerController::onBreakpoint(const Breakpoint *breakpoint, DebuggableScript *script) { + _lastScript = script; + _lastLine = script->_currentLine; + DEBUGGER->notifyBreakpoint(script->dbgGetFilename().c_str(), script->_currentLine); +} + +void DebuggerController::notifyStep(DebuggableScript *script) { + _lastScript = script; + _lastLine = script->_currentLine; + DEBUGGER->notifyStep(script->dbgGetFilename().c_str(), script->_currentLine); +} + +void DebuggerController::onWatch(const Watch *watch, DebuggableScript *script) { + _lastScript = script; // If script has changed do we still care? + _lastLine = script->_currentLine; + Common::String symbol = watch->getSymbol(); + DEBUGGER->notifyWatch(script->dbgGetFilename().c_str(), symbol.c_str(), script->resolveName(symbol)->getString()); +} + +Error DebuggerController::step() { + if (!_lastScript) { + return Error(ERROR, NOT_ALLOWED); + } + _lastScript->step(); + clear(); + return Error(SUCCESS, OK); +} + +Error DebuggerController::stepContinue() { + if (!_lastScript) { + return Error(ERROR, NOT_ALLOWED); + } + _lastScript->stepContinue(); + return Error(SUCCESS, OK); +} + +Error DebuggerController::stepFinish() { + if (!_lastScript) { + return Error(ERROR, NOT_ALLOWED); + } + _lastScript->stepFinish(); + clear(); + return Error(SUCCESS, OK); +} + +void DebuggerController::clear() { + _lastScript = nullptr; + _lastLine = -1; +} + +Common::String DebuggerController::readValue(const Common::String &name, Error *error) { + if (!_lastScript) { + delete error; + error = new Error(ERROR, NOT_ALLOWED); + return Common::String(); + } + char cstr[256]; // TODO not pretty + Common::strlcpy(cstr, name.c_str(), name.size() + 1); + cstr[255] = '\0'; // We 0-terminate it just in case it's longer than 255. + return _lastScript->resolveName(cstr)->getString(); +} + +Error DebuggerController::setValue(const Common::String &name, const Common::String &value, ScValue *&var) { + if (!_lastScript) { + return Error(ERROR, NOT_ALLOWED); + } + + Common::String trimmed = value; + trimmed.trim(); + char cstr[256]; + Common::strlcpy(cstr, name.c_str(), name.size() + 1); // TODO not pretty + + var = _lastScript->getVar(cstr); + if (var->_type == VAL_INT) { + char *endptr; + int res = strtol(trimmed.c_str(), &endptr, 10); // TODO: Hex too? + if (endptr == trimmed.c_str()) { + return Error(ERROR, PARSE_ERROR); + } else if (endptr == trimmed.c_str() + trimmed.size()) { + // We've parsed all of it, have we? + var->setInt(res); + } else { + assert(false); + return Error(ERROR, PARSE_ERROR); + // Something funny happened here. + } + } else if (var->_type == VAL_FLOAT) { + char *endptr; + float res = (float)strtod(trimmed.c_str(), &endptr); + if (endptr == trimmed.c_str()) { + return Error(ERROR, PARSE_ERROR); + } else if (endptr == trimmed.c_str() + trimmed.size()) { + // We've parsed all of it, have we? + var->setFloat(res); + } else { + return Error(ERROR, PARSE_ERROR); + assert(false); + // Something funny happened here. + } + } else if (var->_type == VAL_BOOL) { + Common::String str = Common::String(trimmed); + bool valAsBool; + if (Common::parseBool(trimmed, valAsBool)) { + var->setBool(valAsBool); + } else { + return Error(ERROR, PARSE_ERROR); + } + } else if (var->_type == VAL_STRING) { + var->setString(trimmed); + } else { + return Error(ERROR, NOT_YET_IMPLEMENTED); + } + return Error(SUCCESS, OK); +} + +void DebuggerController::showFps(bool show) { + _engine->_game->setShowFPS(show); +} + +Common::Array<BreakpointInfo> DebuggerController::getBreakpoints() const { + assert(SCENGINE); + Common::Array<BreakpointInfo> breakpoints; + for (uint i = 0; i < SCENGINE->_breakpoints.size(); i++) { + BreakpointInfo bpInfo; + bpInfo._filename = SCENGINE->_breakpoints[i]->getFilename(); + bpInfo._line = SCENGINE->_breakpoints[i]->getLine(); + bpInfo._hits = SCENGINE->_breakpoints[i]->getHits(); + bpInfo._enabled = SCENGINE->_breakpoints[i]->isEnabled(); + breakpoints.push_back(bpInfo); + } + return breakpoints; +} + +Common::Array<WatchInfo> DebuggerController::getWatchlist() const { + Common::Array<WatchInfo> watchlist; + for (uint i = 0; i < SCENGINE->_watches.size(); i++) { + WatchInfo watchInfo; + watchInfo._filename = SCENGINE->_watches[i]->getFilename(); + watchInfo._symbol = SCENGINE->_watches[i]->getSymbol(); + watchlist.push_back(watchInfo); + } + return watchlist; +} + +uint32 DebuggerController::getLastLine() const { + return _lastLine; +} + +Common::String DebuggerController::getSourcePath() const { + return _sourceListingProvider->getPath(); +} + +Error DebuggerController::setSourcePath(const Common::String &sourcePath) { + ErrorCode err = _sourceListingProvider->setPath(sourcePath); + return Error((err == OK ? SUCCESS : ERROR), err); +} + +Listing* DebuggerController::getListing(Error* &error) { + delete (error); + if (_lastScript == nullptr) { + error = new Error(ERROR, NOT_ALLOWED); + return nullptr; + } + ErrorCode err; + Listing* res = _sourceListingProvider->getListing(SCENGINE->_currentScript->_filename, err); + error = new Error(err == OK ? SUCCESS : ERROR, err); + return res; +} + +Common::Array<TopEntry> DebuggerController::getTop() const { + Common::Array<TopEntry> res; + assert(SCENGINE); + for (uint i = 0; i < SCENGINE->_scripts.size(); i++) { + TopEntry entry; + entry.filename = SCENGINE->_scripts[i]->_filename; + entry.current = (SCENGINE->_scripts[i] == SCENGINE->_currentScript); + res.push_back(entry); + } + return res; +} + +} // end of namespace Wintermute diff --git a/engines/wintermute/debugger/debugger_controller.h b/engines/wintermute/debugger/debugger_controller.h new file mode 100644 index 0000000000..345b42f0cb --- /dev/null +++ b/engines/wintermute/debugger/debugger_controller.h @@ -0,0 +1,119 @@ +/* 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 WINTERMUTE_DEBUGGER_ADAPTER_H +#define WINTERMUTE_DEBUGGER_ADAPTER_H + +#include "common/str.h" +#include "engines/wintermute/coll_templ.h" +#include "engines/wintermute/wintermute.h" +#include "engines/wintermute/debugger/listing_providers/source_listing_provider.h" +#include "script_monitor.h" +#include "error.h" +#include "listing.h" +namespace Wintermute { + +class ScScript; +class DebuggableScript; +class ScValue; + +struct BreakpointInfo { + Common::String _filename; + int _line; + int _hits; + bool _enabled; +}; + +struct WatchInfo { + Common::String _filename; + Common::String _symbol; + int _hits; + bool _enabled; +}; + +struct TopEntry { + bool current; + Common::String filename; + int watches; + int breakpointInfo; +}; + +class DebuggerController : public ScriptMonitor { + SourceListingProvider *_sourceListingProvider; + const WintermuteEngine *_engine; + DebuggableScript *_lastScript; + uint32 _lastDepth; + uint32 _lastLine; + void clear(); + bool bytecodeExists(const Common::String &filename); +public: + DebuggerController(WintermuteEngine *vm); + ~DebuggerController(); + Common::Array<TopEntry> getTop() const; + /** + * Get the last line # we've stopped at + */ + uint32 getLastLine() const; + Error addBreakpoint(const char *filename, int line); + Error removeBreakpoint(uint id); + Error disableBreakpoint(uint id); + Error enableBreakpoint(uint id); + Error addWatch(const char *filename, const char *symbol); + Error removeWatchpoint(uint id); + Error disableWatchpoint(uint id); + Error enableWatchpoint(uint id); + Common::Array<BreakpointInfo> getBreakpoints() const; + Common::Array<WatchInfo> getWatchlist() const; + /** + * @brief step one instruction + */ + Error step(); + /** + * @brief continue execution and don't step until next breakpoint + */ + Error stepContinue(); + /** + * @brief continue execution and don't step until the current activation record is popped + */ + Error stepFinish(); + /** + * @brief read value for a variable accessible from within the current scope. + */ + Common::String readValue(const Common::String &name, Error *error); + /** + * @brief set value for a variable accessible from within the current scope. + */ + Error setValue(const Common::String &name, const Common::String &value, ScValue*&var); + Error setSourcePath(const Common::String &sourcePath); + Common::String getSourcePath() const; + Listing *getListing(Error* &err); + void showFps(bool show); + /** + * Inherited from ScriptMonitor + */ + void onBreakpoint(const Breakpoint *breakpoint, DebuggableScript *script); + void onWatch(const Watch *watch, DebuggableScript *script); + void notifyStep(DebuggableScript *script) override; +}; +} + +#endif // WINTERMUTE_DEBUGGER_H diff --git a/engines/wintermute/debugger/error.cpp b/engines/wintermute/debugger/error.cpp new file mode 100644 index 0000000000..dd6e41c7bc --- /dev/null +++ b/engines/wintermute/debugger/error.cpp @@ -0,0 +1,137 @@ +/* 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 "error.h" +#include "engines/wintermute/debugger.h" + +namespace Wintermute { + +Error::Error(ErrorLevel errorLevel, + ErrorCode errorCode, + Common::String errorExtraString, + int errorExtraInt) : + _errorLevel(errorLevel), + _errorCode(errorCode), + _errorExtraInt(errorExtraInt), + _errorExtraString(errorExtraString){} + +Error::Error(ErrorLevel errorLevel, + ErrorCode errorCode, + int errorExtraInt) : + _errorLevel(errorLevel), + _errorCode(errorCode), + _errorExtraInt(errorExtraInt), + _errorExtraString(""){} + +Error::Error(ErrorLevel errorLevel, + ErrorCode errorCode) : + _errorLevel(errorLevel), + _errorCode(errorCode), + _errorExtraInt(0), + _errorExtraString(""){} + +Error::Error(ErrorLevel errorLevel, + ErrorCode errorCode, + Common::String errorExtraString) : + _errorLevel(errorLevel), + _errorCode(errorCode), + _errorExtraInt(0), + _errorExtraString(errorExtraString){} + +ErrorLevel Error::getErrorLevel() const { + return _errorLevel; +} + +ErrorCode Error::getErrorCode() const { + return _errorCode; +} + +Common::String Error::getErrorLevelStr() const { + switch (this->_errorLevel) { + case SUCCESS: + return "SUCCESS"; + break; + case NOTICE: + return "NOTICE"; + break; + case WARNING: + return "WARNING"; + break; + case ERROR: + return "ERROR"; + break; + } + return "SUCCESS"; +} + +Common::String Error::getErrorDisplayStr() const { + + Common::String errorStr; + + switch (this->_errorLevel) { + case SUCCESS: + errorStr += "OK!"; + break; + case WARNING: + errorStr += "WARNING: "; + break; + case ERROR: + errorStr += "ERROR: "; + break; + case NOTICE: + errorStr += "NOTICE: "; + break; + default: + // Um... + break; + } + + switch (this->_errorCode) { + case OK: + break; + case NOT_ALLOWED: + errorStr += "Could not execute requested operation. This is allowed only after a break."; + break; + case NO_SUCH_SOURCE: + errorStr += Common::String::format("Can't find source for %s. Double check you source path.", this->_errorExtraString.c_str()); + break; + case NO_SUCH_BYTECODE: + errorStr += Common::String::format("No such script: %s. Can't find bytecode; double check the script path.", this->_errorExtraString.c_str()); + break; + case SOURCE_PATH_NOT_SET: + errorStr += Common::String("Source path not set. Source won't be displayed. Try 'help " + Common::String(SET_PATH_CMD) + "'."); + break; + case NO_SUCH_BREAKPOINT: + errorStr += Common::String::format("No such breakpoint %d.", this->_errorExtraInt); + break; + case WRONG_TYPE: + errorStr += Common::String::format("Incompatible type: %s.", this->_errorExtraString.c_str()); + break; + default: + errorStr += Common::String::format("Unknown condition %d", this->_errorCode); + break; + } + + return errorStr; +} + +} // End namespace Wintermute diff --git a/engines/wintermute/debugger/error.h b/engines/wintermute/debugger/error.h new file mode 100644 index 0000000000..4e5b973445 --- /dev/null +++ b/engines/wintermute/debugger/error.h @@ -0,0 +1,73 @@ +/* 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 ERROR_H_ +#define ERROR_H_ + +#include "common/str.h" + +namespace Wintermute { + +enum ErrorLevel { + SUCCESS, + NOTICE, + WARNING, + ERROR +}; + +enum ErrorCode { + OK, + NO_SUCH_SOURCE, + COULD_NOT_OPEN, + NO_SUCH_LINE, + NOT_ALLOWED, + NO_SUCH_BYTECODE, + DUPLICATE_BREAKPOINT, + NO_SUCH_BREAKPOINT, + WRONG_TYPE, + PARSE_ERROR, + NOT_YET_IMPLEMENTED, + SOURCE_PATH_NOT_SET, + ILLEGAL_PATH, + UNKNOWN_ERROR +}; + + +class Error { + const ErrorLevel _errorLevel; + const ErrorCode _errorCode; + const int _errorExtraInt; + const Common::String _errorExtraString; +public: + Error(ErrorLevel, ErrorCode); + Error(ErrorLevel, ErrorCode, int errorExtraInt); + Error(ErrorLevel, ErrorCode, Common::String errorExtraString); + Error(ErrorLevel, ErrorCode, Common::String errorExtraString, int errorExtraInt); + ErrorLevel getErrorLevel() const; + ErrorCode getErrorCode() const; + Common::String getErrorLevelStr() const; + Common::String getErrorDisplayStr() const; +}; + +} // End of namespace Wintermute + +#endif /* ERROR_H_ */ diff --git a/engines/wintermute/debugger/listing.cpp b/engines/wintermute/debugger/listing.cpp new file mode 100644 index 0000000000..b8707fb842 --- /dev/null +++ b/engines/wintermute/debugger/listing.cpp @@ -0,0 +1,46 @@ +/* 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 "listing.h" +#include "common/array.h" + +namespace Wintermute { + +Common::Array<ListingLine> Listing::getLines(uint begin, uint end) { + assert(begin <= end); + Common::Array<ListingLine> ret; + for (uint i = begin; i <= end; i++) { + ListingLine listingline; + listingline.number = i; + listingline.text = getLine(i); + ret.push_back(listingline); + } + return ret; +} + +Common::Array<ListingLine> Listing::getLines(uint centre, uint before, uint after) { + uint begin = MAX(centre - before, (uint)1); // Line numbers start from 1 + uint end = MIN(centre + after, (uint)(getLength() - 1)); // Line numbers start from 1 + return getLines(begin, end); +} + +} // End of namespace Wintermute diff --git a/engines/wintermute/debugger/listing.h b/engines/wintermute/debugger/listing.h new file mode 100644 index 0000000000..2ef21b702d --- /dev/null +++ b/engines/wintermute/debugger/listing.h @@ -0,0 +1,64 @@ +/* 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 LISTING_H_ +#define LISTING_H_ + +#include "common/array.h" + + +namespace Common { + +class String; + +} + +namespace Wintermute { + +struct ListingLine { + uint number; + Common::String text; +}; + +class Listing { +public: + virtual ~Listing() {}; + /** + * @brief get the listing length (in lines) + */ + virtual uint getLength() const = 0; + /** + * @brief return a specific line from a listing + * @param n line number + */ + virtual Common::String getLine(uint n) = 0; + /** + * @brief shorthand to get a lump of lines instead of calling getLine a number of times + * Generally you won't need to redefine these + */ + virtual Common::Array<ListingLine> getLines(uint centre, uint before, uint after); + virtual Common::Array<ListingLine> getLines(uint beginning, uint end); +}; + +} // End of namespace Wintermute + +#endif /* LISTING_H_ */ diff --git a/engines/wintermute/debugger/listing_provider.h b/engines/wintermute/debugger/listing_provider.h new file mode 100644 index 0000000000..b5ea23e49b --- /dev/null +++ b/engines/wintermute/debugger/listing_provider.h @@ -0,0 +1,42 @@ +/* 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 LISTING_PROVIDER_H_ +#define LISTING_PROVIDER_H_ + +#include "listing.h" +#include "engines/wintermute/debugger/error.h" + +namespace Wintermute { + +class ListingProvider { +public: + virtual ~ListingProvider() {}; + /** + * Get a listing. When implementing this, the result should be safe to delete for the caller. + */ + virtual Listing *getListing(const Common::String &filename, ErrorCode &error) = 0; +}; + +} // End of namespace Wintermute + +#endif /* LISTING_PROVIDER_H_ */ diff --git a/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.cpp b/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.cpp new file mode 100644 index 0000000000..30d29ee23e --- /dev/null +++ b/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.cpp @@ -0,0 +1,92 @@ +/* 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 "basic_source_listing_provider.h" +#include "engines/wintermute/base/base_file_manager.h" + +namespace Wintermute { +BasicSourceListingProvider::BasicSourceListingProvider() : _fsDirectory(nullptr) { +} + +BasicSourceListingProvider::~BasicSourceListingProvider() { +} + +SourceListing *BasicSourceListingProvider::getListing(const Common::String &filename, ErrorCode &_err) { + _err = OK; + if (!_fsDirectory) { + _err = SOURCE_PATH_NOT_SET; + return nullptr; + }; + + Common::String unixFilename; + + for (uint i = 0; i < filename.size(); i++) { + if (filename[i] == '\\') { + unixFilename.insertChar('/', unixFilename.size()); + } else { + unixFilename.insertChar(filename[i], unixFilename.size()); + } + } + + Common::SeekableReadStream *file = _fsDirectory->createReadStreamForMember(unixFilename); + Common::Array<Common::String> strings; + + if (!file) { + _err = NO_SUCH_SOURCE; + } else { + if (file->err()) { + _err = UNKNOWN_ERROR; + } + while (!file->eos()) { + strings.push_back(file->readLine()); + if (file->err()) { + _err = UNKNOWN_ERROR; + } + } + } + + if (_err == OK) { + return new SourceListing(strings); + } else { + return nullptr; + } +} + +ErrorCode BasicSourceListingProvider::setPath(const Common::String &path) { + if (path == "") + return ILLEGAL_PATH; + delete _fsDirectory; + Common::FSNode node(path); + if (node.exists() && node.isDirectory()) { + _fsDirectory = new Common::FSDirectory(node, 64); + return OK; + } else { + return COULD_NOT_OPEN; + } +} + +Common::String BasicSourceListingProvider::getPath() const { + if (!_fsDirectory) return ""; + return _fsDirectory->getFSNode().getPath(); +} + +} diff --git a/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.h b/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.h new file mode 100644 index 0000000000..e242205578 --- /dev/null +++ b/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.h @@ -0,0 +1,44 @@ +/* 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 BASIC_SOURCE_LISTING_PROVIDER_H_ +#define BASIC_SOURCE_LISTING_PROVIDER_H_ + +#include "engines/wintermute/debugger/listing_provider.h" +#include "source_listing_provider.h" +#include "source_listing.h" +#include "common/fs.h" + +namespace Wintermute { + +class BasicSourceListingProvider : public SourceListingProvider { + Common::FSDirectory *_fsDirectory; +public: + BasicSourceListingProvider(); + virtual ~BasicSourceListingProvider(); + SourceListing *getListing(const Common::String &filename, ErrorCode &err); + ErrorCode setPath(const Common::String &path); + Common::String getPath() const; +}; + +} +#endif /* BASIC_SOURCE_LISTING_PROVIDER_H_ */ diff --git a/engines/wintermute/debugger/listing_providers/blank_listing.cpp b/engines/wintermute/debugger/listing_providers/blank_listing.cpp new file mode 100644 index 0000000000..928c91dc7f --- /dev/null +++ b/engines/wintermute/debugger/listing_providers/blank_listing.cpp @@ -0,0 +1,38 @@ +/* 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 "blank_listing.h" +#include "limits.h" + +namespace Wintermute { + +BlankListing::BlankListing(const Common::String filename) : _filename(filename) {} + +uint BlankListing::getLength() const { return UINT_MAX; } + +Common::String BlankListing::getLine(uint n) { + return "<no source for " + _filename + " ~~~ line: " + Common::String::format("%d", n) + ">"; +} +BlankListing::~BlankListing() {} + +} + diff --git a/engines/wintermute/debugger/listing_providers/blank_listing.h b/engines/wintermute/debugger/listing_providers/blank_listing.h new file mode 100644 index 0000000000..8c5ea19aa7 --- /dev/null +++ b/engines/wintermute/debugger/listing_providers/blank_listing.h @@ -0,0 +1,39 @@ +/* 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 BLANK_LISTING_H_ +#define BLANK_LISTING_H_ +#include "engines/wintermute/debugger/listing.h" + +namespace Wintermute { +class BlankListing : public Listing { + const Common::String _filename; +public: + BlankListing(const Common::String filename); + virtual ~BlankListing(); + virtual uint getLength() const; + virtual Common::String getLine(uint n); +}; + +} // End of namespace Wintermute + +#endif diff --git a/engines/wintermute/debugger/listing_providers/blank_listing_provider.cpp b/engines/wintermute/debugger/listing_providers/blank_listing_provider.cpp new file mode 100644 index 0000000000..58e9e7e156 --- /dev/null +++ b/engines/wintermute/debugger/listing_providers/blank_listing_provider.cpp @@ -0,0 +1,35 @@ +/* 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 "blank_listing_provider.h" +#include "blank_listing.h" +namespace Wintermute { +BlankListingProvider::BlankListingProvider() {} + +BlankListingProvider::~BlankListingProvider() {} + +Listing *BlankListingProvider::getListing(const Common::String &filename, ErrorCode &error) { + Listing *l = new BlankListing(filename); + error = OK; + return l; // Delete this sometime please. +} +} // End of namespace Wintermute diff --git a/engines/wintermute/debugger/listing_providers/blank_listing_provider.h b/engines/wintermute/debugger/listing_providers/blank_listing_provider.h new file mode 100644 index 0000000000..e583455c92 --- /dev/null +++ b/engines/wintermute/debugger/listing_providers/blank_listing_provider.h @@ -0,0 +1,38 @@ +/* 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 BLANK_LISTING_PROVIDER_H_ +#define BLANK_LISTING_PROVIDER_H_ + +#include "engines/wintermute/debugger/listing.h" +#include "engines/wintermute/debugger/listing_provider.h" +#include "engines/wintermute/debugger/error.h" + +namespace Wintermute { +class BlankListingProvider : public ListingProvider { +public: + BlankListingProvider(); + ~BlankListingProvider(); + Listing *getListing(const Common::String &filename, ErrorCode &error); +}; +} // End of namespace Wintermute +#endif diff --git a/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.cpp b/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.cpp new file mode 100644 index 0000000000..20fe708380 --- /dev/null +++ b/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.cpp @@ -0,0 +1,80 @@ +/* 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 "cached_source_listing_provider.h" +#include "basic_source_listing_provider.h" +#include "blank_listing_provider.h" +#include "source_listing.h" + +namespace Wintermute { + +CachedSourceListingProvider::CachedSourceListingProvider() { + _sourceListingProvider = new BasicSourceListingProvider(); + _fallbackListingProvider = new BlankListingProvider(); +} + +CachedSourceListingProvider::~CachedSourceListingProvider() { + delete _sourceListingProvider; + delete _fallbackListingProvider; + for (Common::HashMap<Common::String, SourceListing*>::iterator it = _cached.begin(); + it != _cached.end(); it++) { + delete (it->_value); + } +} + +Listing *CachedSourceListingProvider::getListing(const Common::String &filename, Wintermute::ErrorCode &error) { + if (_cached.contains(filename)) { + error = OK; + SourceListing *copy = new SourceListing(*_cached.getVal(filename)); + return copy; + } else { + ErrorCode inner; + SourceListing *res = _sourceListingProvider->getListing(filename, inner); + if (inner == OK) { + SourceListing *copy = new SourceListing(*res); + _cached.setVal(filename, copy); // The cached copy is deleted on destruction + return res; + } else { + delete res; + return _fallbackListingProvider->getListing(filename, error); + } + } +} + +void CachedSourceListingProvider::invalidateCache() { + for (Common::HashMap<Common::String, SourceListing*>::iterator it = _cached.begin(); + it != _cached.end(); it++) { + delete (it->_value); + } + _cached.clear(); +} + +ErrorCode CachedSourceListingProvider::setPath(const Common::String &path) { + invalidateCache(); + return _sourceListingProvider->setPath(path); +} + +Common::String CachedSourceListingProvider::getPath() const { + return _sourceListingProvider->getPath(); +} + +} // End of namespace Wintermute diff --git a/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.h b/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.h new file mode 100644 index 0000000000..6e4925f2b4 --- /dev/null +++ b/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.h @@ -0,0 +1,52 @@ +/* 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 CACHED_LISTING_PROVIDER_H_ +#define CACHED_LISTING_PROVIDER_H_ + +#include "common/hashmap.h" +#include "common/hash-str.h" +#include "engines/wintermute/debugger/error.h" +#include "source_listing_provider.h" + +namespace Wintermute { + +class BasicSourceListingProvider; +class BlankListingProvider; +class Listing; + +class CachedSourceListingProvider : public SourceListingProvider { + BasicSourceListingProvider *_sourceListingProvider; + BlankListingProvider *_fallbackListingProvider; + Common::HashMap<Common::String, SourceListing *> _cached; + void invalidateCache(); +public: + CachedSourceListingProvider(); + virtual ~CachedSourceListingProvider(); + ErrorCode setPath(const Common::String &path); + Common::String getPath() const; + Listing *getListing(const Common::String &filename, ErrorCode &err); +}; + +} // End of namespace Wintermute + +#endif /* CACHED_LISTING_PROVIDER_H_ */ diff --git a/engines/wintermute/debugger/listing_providers/source_listing.cpp b/engines/wintermute/debugger/listing_providers/source_listing.cpp new file mode 100644 index 0000000000..ff81e20f02 --- /dev/null +++ b/engines/wintermute/debugger/listing_providers/source_listing.cpp @@ -0,0 +1,57 @@ +/* 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 "source_listing.h" + +namespace Wintermute { + +SourceListing::SourceListing(const Common::Array<Common::String> &strings) : _strings(strings) {} + +SourceListing::~SourceListing() {} + +uint SourceListing::getLength() const { + return _strings.size(); +} + +Common::String SourceListing::getLine(uint n) { + uint index = n - 1; // Line numbers start from 1, arrays from 0 + /* + * Clients should not ask for a line number that + * is not in the source file. + * 0 is undefined, n - 1 is undefined. + * It is easy for the client to check that n > 0 + * and n < getLength(), so it should just not happen. + * We return '^', after vim, to misbehaving clients. + */ + if (n == 0) { + return Common::String("^"); + } + if (index < getLength()) { + return _strings[index]; + } else { + return Common::String("^"); + } +} + +} // End of namespace Wintermute + + diff --git a/engines/wintermute/debugger/listing_providers/source_listing.h b/engines/wintermute/debugger/listing_providers/source_listing.h new file mode 100644 index 0000000000..bf08578218 --- /dev/null +++ b/engines/wintermute/debugger/listing_providers/source_listing.h @@ -0,0 +1,37 @@ +/* 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 SOURCE_LISTING_H_ +#define SOURCE_LISTING_H_ +#include "engines/wintermute/debugger/listing.h" + +namespace Wintermute { +class SourceListing : public Listing { + const Common::Array<Common::String> _strings; +public: + SourceListing(const Common::Array<Common::String> &strings); + virtual ~SourceListing(); + virtual uint getLength() const; + virtual Common::String getLine(uint n); +}; +} +#endif /* DUMMY_LISTING_H_ */ diff --git a/engines/wintermute/debugger/listing_providers/source_listing_provider.h b/engines/wintermute/debugger/listing_providers/source_listing_provider.h new file mode 100644 index 0000000000..18f05e56ed --- /dev/null +++ b/engines/wintermute/debugger/listing_providers/source_listing_provider.h @@ -0,0 +1,49 @@ +/* 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 SOURCE_LISTING_PROVIDER_H_ +#define SOURCE_LISTING_PROVIDER_H_ + +#include "engines/wintermute/debugger/error.h" +#include "engines/wintermute/debugger/listing_provider.h" +#include "common/str.h" + +namespace Wintermute { + +class SourceListing; +class Listing; + +class SourceListingProvider : ListingProvider { +public: + virtual ~SourceListingProvider() {}; + /** + * Get a listing. When implementing this, the result should be safe to delete for the caller. + */ + virtual Listing *getListing(const Common::String &filename, ErrorCode &err) = 0; + virtual ErrorCode setPath(const Common::String &path) = 0; + virtual Common::String getPath() const = 0; + +}; + +} // End of namespace Wintermute + +#endif /* SOURCE_LISTING_PROVIDER_H_ */ diff --git a/engines/wintermute/debugger/script_monitor.cpp b/engines/wintermute/debugger/script_monitor.cpp new file mode 100644 index 0000000000..2e9370c923 --- /dev/null +++ b/engines/wintermute/debugger/script_monitor.cpp @@ -0,0 +1,26 @@ +/* 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 "script_monitor.h" + +namespace Wintermute { +} diff --git a/engines/wintermute/debugger/script_monitor.h b/engines/wintermute/debugger/script_monitor.h new file mode 100644 index 0000000000..e9559e2ade --- /dev/null +++ b/engines/wintermute/debugger/script_monitor.h @@ -0,0 +1,43 @@ +/* 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 SCRIPTMONITOR_H_ +#define SCRIPTMONITOR_H_ + +namespace Wintermute { + +class DebuggableScript; +class Breakpoint; +class Watch; + +class ScriptMonitor { +public: + + virtual ~ScriptMonitor() {}; + virtual void notifyStep(DebuggableScript* script) = 0; + virtual void onBreakpoint(const Breakpoint* breakpoint, DebuggableScript* script) = 0; + virtual void onWatch(const Watch* watch, DebuggableScript* script) = 0; +}; + +} // End of namespace Wintermute + +#endif /* SCRIPTMONITOR_H_ */ diff --git a/engines/wintermute/debugger/watch.cpp b/engines/wintermute/debugger/watch.cpp new file mode 100644 index 0000000000..410756fdc8 --- /dev/null +++ b/engines/wintermute/debugger/watch.cpp @@ -0,0 +1,42 @@ +/* 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 "watch.h" +#include "watch_instance.h" +#include "script_monitor.h" + +namespace Wintermute { + +Watch::Watch(const Common::String &filename, const Common::String &symbol, ScriptMonitor* monitor) : _enabled(false), _filename(filename), _symbol(symbol), _monitor(monitor) {} + +Watch::~Watch() { /* Nothing to take care of in here */ } + +void Watch::trigger(WatchInstance* instance) { + _monitor->onWatch(this, instance->_script); +} + +Common::String Watch::getFilename() const { return _filename; } +Common::String Watch::getSymbol() const { return _symbol; } +bool Watch::isEnabled() const { return _enabled; } +void Watch::enable() { _enabled = true; } +void Watch::disable() { _enabled = false; } +} diff --git a/engines/wintermute/debugger/watch.h b/engines/wintermute/debugger/watch.h new file mode 100644 index 0000000000..cbffe43b41 --- /dev/null +++ b/engines/wintermute/debugger/watch.h @@ -0,0 +1,51 @@ +/* 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 WATCH_H_ +#define WATCH_H_ + +#include "common/str.h" + +namespace Wintermute { + +class ScValue; +class ScScript; +class WatchInstance; +class ScriptMonitor; + +class Watch { + const Common::String _filename; + const Common::String _symbol; + int _enabled; + ScriptMonitor *_monitor; +public: + Watch(const Common::String &filename, const Common::String &symbol, ScriptMonitor*); + Common::String getFilename() const; + Common::String getSymbol() const; + bool isEnabled() const; + void enable(); + void disable(); + void trigger(WatchInstance*); + virtual ~Watch(); +}; +} +#endif /* WATCH_H_ */ diff --git a/engines/wintermute/debugger/watch_instance.cpp b/engines/wintermute/debugger/watch_instance.cpp new file mode 100644 index 0000000000..2d31221ad4 --- /dev/null +++ b/engines/wintermute/debugger/watch_instance.cpp @@ -0,0 +1,53 @@ +/* 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 "watch_instance.h" +#include "engines/wintermute/base/scriptables/script_value.h" +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h" +#include "engines/wintermute/debugger/watch.h" + +namespace Wintermute { + +WatchInstance::WatchInstance(Watch* watch, DebuggableScript* script) : _watch(watch), _script(script), _lastValue(nullptr) {} +WatchInstance::~WatchInstance() { delete _lastValue; } + +void WatchInstance::evaluate() { + if (_watch->isEnabled()) { + if (!_watch->getFilename().compareTo(_script->_filename)) { + + if(_lastValue == nullptr) { + _lastValue = new ScValue(_script->_gameRef); + // ^^ This here is NULL by default + } + ScValue* currentValue = _script->resolveName(_watch->getSymbol()); + if(ScValue::compare( + currentValue, + _lastValue + )) { + _lastValue->copy(currentValue); + _watch->trigger(this); + } + delete currentValue; + } + } +} +} // End of namespace Wintermute diff --git a/engines/wintermute/debugger/watch_instance.h b/engines/wintermute/debugger/watch_instance.h new file mode 100644 index 0000000000..84fb62968d --- /dev/null +++ b/engines/wintermute/debugger/watch_instance.h @@ -0,0 +1,44 @@ +/* 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 WATCH_INSTANCE_H_ +#define WATCH_INSTANCE_H_ + +namespace Wintermute { +class Watch; +class ScValue; +class DebuggableScript; + +class WatchInstance { + Watch* _watch; + ScValue *_lastValue; + DebuggableScript* _script; +public: + WatchInstance (Watch* watch, DebuggableScript* script); + ~WatchInstance(); + void evaluate(); +friend class DebuggableScript; +friend class Watch; +}; +} // End of namespace Wintermute + +#endif /* WATCH_INSTANCE_H_ */ diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk index 4c95314a02..2c9c2e0180 100644 --- a/engines/wintermute/module.mk +++ b/engines/wintermute/module.mk @@ -27,6 +27,8 @@ MODULE_OBJS := \ ad/ad_talk_holder.o \ ad/ad_talk_node.o \ ad/ad_waypoint_group.o \ + base/scriptables/debuggable/debuggable_script.o \ + base/scriptables/debuggable/debuggable_script_engine.o \ base/scriptables/script.o \ base/scriptables/script_engine.o \ base/scriptables/script_stack.o \ @@ -88,6 +90,18 @@ MODULE_OBJS := \ base/saveload.o \ base/save_thumb_helper.o \ base/timer.o \ + debugger/breakpoint.o \ + debugger/debugger_controller.o \ + debugger/error.o \ + debugger/listing_providers/blank_listing.o \ + debugger/listing_providers/blank_listing_provider.o \ + debugger/listing_providers/basic_source_listing_provider.o \ + debugger/listing_providers/cached_source_listing_provider.o \ + debugger/listing_providers/source_listing.o \ + debugger/listing.o \ + debugger/script_monitor.o \ + debugger/watch.o \ + debugger/watch_instance.o \ detection.o \ math/math_util.o \ math/matrix4.o \ diff --git a/engines/wintermute/wintermute.cpp b/engines/wintermute/wintermute.cpp index 955f2dc1c2..05dfb961cb 100644 --- a/engines/wintermute/wintermute.cpp +++ b/engines/wintermute/wintermute.cpp @@ -41,6 +41,7 @@ #include "engines/wintermute/base/base_file_manager.h" #include "engines/wintermute/base/gfx/base_renderer.h" #include "engines/wintermute/base/scriptables/script_engine.h" +#include "engines/wintermute/debugger/debugger_controller.h" namespace Wintermute { @@ -49,6 +50,7 @@ namespace Wintermute { WintermuteEngine::WintermuteEngine() : Engine(g_system) { _game = new AdGame(""); _debugger = nullptr; + _dbgController = nullptr; _trigDebug = false; _gameDescription = nullptr; } @@ -76,6 +78,7 @@ WintermuteEngine::WintermuteEngine(OSystem *syst, const WMEGameDescription *desc _game = nullptr; _debugger = nullptr; + _dbgController = nullptr; _trigDebug = false; } @@ -112,6 +115,7 @@ Common::Error WintermuteEngine::run() { } // Create debugger console. It requires GFX to be initialized + _dbgController = new DebuggerController(this); _debugger = new Console(this); // DebugMan.enableDebugChannel("enginelog"); @@ -171,7 +175,6 @@ int WintermuteEngine::init() { } _game->initialize3(); - // initialize sound manager (non-fatal if we fail) ret = _game->_soundMgr->initialize(); if (DID_FAIL(ret)) { @@ -200,6 +203,8 @@ int WintermuteEngine::init() { _game->loadGame(slot); } + _game->_scEngine->attachMonitor(_dbgController); + // all set, ready to go return 0; } diff --git a/engines/wintermute/wintermute.h b/engines/wintermute/wintermute.h index f61a809b22..a8f9a18530 100644 --- a/engines/wintermute/wintermute.h +++ b/engines/wintermute/wintermute.h @@ -33,6 +33,8 @@ namespace Wintermute { class Console; class BaseGame; class SystemClassRegistry; +class DebuggerController; + // our engine debug channels enum { kWintermuteDebugLog = 1 << 0, // The debug-logs from the original engine @@ -49,7 +51,7 @@ public: WintermuteEngine(); ~WintermuteEngine(); - virtual GUI::Debugger *getDebugger() { return _debugger; } + virtual Wintermute::Console *getConsole() { return _debugger; } void trigDebugger() { _trigDebug = true; } virtual Common::Error run(); @@ -66,11 +68,13 @@ private: int init(); void deinit(); int messageLoop(); - GUI::Debugger *_debugger; + Wintermute::Console *_debugger; BaseGame *_game; + Wintermute::DebuggerController *_dbgController; const WMEGameDescription *_gameDescription; friend class Console; + friend class DebuggerController; }; } // End of namespace Wintermute diff --git a/engines/wage/macmenu.cpp b/graphics/macgui/macmenu.cpp index ed5f5070ff..a78fa2e6ce 100644 --- a/engines/wage/macmenu.cpp +++ b/graphics/macgui/macmenu.cpp @@ -50,12 +50,11 @@ #include "graphics/primitives.h" #include "graphics/font.h" +#include "graphics/macgui/macwindowmanager.h" +#include "graphics/macgui/macwindow.h" +#include "graphics/macgui/macmenu.h" -#include "wage/macwindowmanager.h" -#include "wage/macwindow.h" -#include "wage/macmenu.h" - -namespace Wage { +namespace Graphics { enum { kMenuHeight = 20, @@ -67,6 +66,25 @@ enum { kMenuItemHeight = 20 }; +enum { + kMenuHighLevel = -1 +}; + +enum { + kFontStyleBold = 1, + kFontStyleItalic = 2, + kFontStyleUnderline = 4, + kFontStyleOutline = 8, + kFontStyleShadow = 16, + kFontStyleCondensed = 32, + kFontStyleExtended = 64 +}; + +enum { + kMenuActionCommand +}; + + struct MenuSubItem { Common::String text; int action; @@ -93,7 +111,7 @@ Menu::Menu(int id, const Common::Rect &bounds, MacWindowManager *wm) : BaseMacWindow(id, false, wm) { _font = getMenuFont(); - _screen.create(bounds.width(), bounds.height(), Graphics::PixelFormat::createFormatCLUT8()); + _screen.create(bounds.width(), bounds.height(), PixelFormat::createFormatCLUT8()); _bbox.left = 0; _bbox.top = 0; @@ -107,7 +125,7 @@ Menu::Menu(int id, const Common::Rect &bounds, MacWindowManager *wm) _ccallback = NULL; _cdata = NULL; - _tempSurface.create(_screen.w, _font->getFontHeight(), Graphics::PixelFormat::createFormatCLUT8()); + _tempSurface.create(_screen.w, _font->getFontHeight(), PixelFormat::createFormatCLUT8()); } Menu::~Menu() { @@ -145,6 +163,8 @@ int Menu::addMenuItem(const char *name) { void Menu::addMenuSubItem(int id, const char *text, int action, int style, char shortcut, bool enabled) { _items[id]->subitems.push_back(new MenuSubItem(text, action, style, shortcut, enabled)); + + calcMenuBounds(_items[id]); } void Menu::calcDimensions() { @@ -229,7 +249,7 @@ void Menu::createSubMenuFromString(int id, const char *str) { Common::String tmpitem(item); tmpitem.trim(); - if (tmpitem[0] == '(') { + if (tmpitem.size() > 0 && tmpitem[0] == '(') { enabled = false; for (uint j = 0; j < item.size(); j++) @@ -248,8 +268,8 @@ void Menu::createSubMenuFromString(int id, const char *str) { calcMenuBounds(menu); } -const Graphics::Font *Menu::getMenuFont() { - return _wm->getFont("Chicago-12", Graphics::FontManager::kBigGUIFont); +const Font *Menu::getMenuFont() { + return _wm->getFont("Chicago-12", FontManager::kBigGUIFont); } const char *Menu::getAcceleratorString(MenuSubItem *item, const char *prefix) { @@ -297,17 +317,17 @@ void Menu::calcMenuBounds(MenuItem *menu) { } static void drawPixelPlain(int x, int y, int color, void *data) { - Graphics::ManagedSurface *surface = (Graphics::ManagedSurface *)data; + ManagedSurface *surface = (ManagedSurface *)data; if (x >= 0 && x < surface->w && y >= 0 && y < surface->h) *((byte *)surface->getBasePtr(x, y)) = (byte)color; } -static void drawFilledRoundRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int arc, int color) { - Graphics::drawRoundRect(rect, arc, color, true, drawPixelPlain, surface); +static void drawFilledRoundRect(ManagedSurface *surface, Common::Rect &rect, int arc, int color) { + drawRoundRect(rect, arc, color, true, drawPixelPlain, surface); } -bool Menu::draw(Graphics::ManagedSurface *g, bool forceRedraw) { +bool Menu::draw(ManagedSurface *g, bool forceRedraw) { Common::Rect r(_bbox); if (!_contentIsDirty && !forceRedraw) @@ -383,7 +403,7 @@ void Menu::renderSubmenu(MenuItem *menu) { } if (!text.empty()) { - Graphics::ManagedSurface *s = &_screen; + ManagedSurface *s = &_screen; int tx = x, ty = y; if (!menu->subitems[i]->enabled) { diff --git a/engines/wage/macmenu.h b/graphics/macgui/macmenu.h index e73e4c48a9..7114066ae6 100644 --- a/engines/wage/macmenu.h +++ b/graphics/macgui/macmenu.h @@ -45,52 +45,14 @@ * */ -#ifndef WAGE_MACMENU_H -#define WAGE_MACMENU_H +#ifndef GRAPHICS_MACGUI_MACMENU_H +#define GRAPHICS_MACGUI_MACMENU_H -namespace Wage { +namespace Graphics { struct MenuItem; struct MenuSubItem; -enum { - kFontStyleBold = 1, - kFontStyleItalic = 2, - kFontStyleUnderline = 4, - kFontStyleOutline = 8, - kFontStyleShadow = 16, - kFontStyleCondensed = 32, - kFontStyleExtended = 64 -}; - -enum { - kMenuHighLevel = -1, - kMenuAbout = 0, - kMenuFile = 1, - kMenuEdit = 2, - kMenuCommands = 3, - kMenuWeapons = 4 -}; - -enum { - kMenuActionAbout, - kMenuActionNew, - kMenuActionOpen, - kMenuActionClose, - kMenuActionSave, - kMenuActionSaveAs, - kMenuActionRevert, - kMenuActionQuit, - - kMenuActionUndo, - kMenuActionCut, - kMenuActionCopy, - kMenuActionPaste, - kMenuActionClear, - - kMenuActionCommand -}; - struct MenuData { int menunum; const char *title; @@ -114,7 +76,7 @@ public: void createSubMenuFromString(int id, const char *string); void clearSubMenu(int id); - bool draw(Graphics::ManagedSurface *g, bool forceRedraw = false); + bool draw(ManagedSurface *g, bool forceRedraw = false); bool processEvent(Common::Event &event); void enableCommand(int menunum, int action, bool state); @@ -126,11 +88,11 @@ public: Common::Rect _bbox; private: - Graphics::ManagedSurface _screen; - Graphics::ManagedSurface _tempSurface; + ManagedSurface _screen; + ManagedSurface _tempSurface; private: - const Graphics::Font *getMenuFont(); + const Font *getMenuFont(); const char *getAcceleratorString(MenuSubItem *item, const char *prefix); int calculateMenuWidth(MenuItem *menu); void calcMenuBounds(MenuItem *menu); @@ -145,7 +107,7 @@ private: Common::Array<MenuItem *> _items; - const Graphics::Font *_font; + const Font *_font; bool _menuActivated; @@ -156,6 +118,6 @@ private: void *_cdata; }; -} // End of namespace Wage +} // End of namespace Graphics #endif diff --git a/engines/wage/macwindow.cpp b/graphics/macgui/macwindow.cpp index db8ef38c39..dbb600ba82 100644 --- a/engines/wage/macwindow.cpp +++ b/graphics/macgui/macwindow.cpp @@ -48,11 +48,11 @@ #include "graphics/font.h" #include "graphics/primitives.h" #include "common/events.h" +#include "graphics/macgui/macwindowmanager.h" +#include "graphics/macgui/macwindow.h" +#include "image/bmp.h" -#include "wage/macwindow.h" -#include "wage/macwindowmanager.h" - -namespace Wage { +namespace Graphics { BaseMacWindow::BaseMacWindow(int id, bool editable, MacWindowManager *wm) : _id(id), _editable(editable), _wm(wm) { @@ -79,13 +79,17 @@ MacWindow::MacWindow(int id, bool scrollable, bool resizable, bool editable, Mac _draggedX = _draggedY = 0; _type = kWindowWindow; + + _closeable = false; + + _borderWidth = kBorderWidth; } MacWindow::~MacWindow() { } -const Graphics::Font *MacWindow::getTitleFont() { - return _wm->getFont("Chicago-12", Graphics::FontManager::kBigGUIFont); +const Font *MacWindow::getTitleFont() { + return _wm->getFont("Chicago-12", FontManager::kBigGUIFont); } void MacWindow::setActive(bool active) { @@ -96,16 +100,18 @@ void MacWindow::setActive(bool active) { _borderIsDirty = true; } +bool MacWindow::isActive() { return _active; } + void MacWindow::resize(int w, int h) { if (_surface.w == w && _surface.h == h) return; _surface.free(); - _surface.create(w, h, Graphics::PixelFormat::createFormatCLUT8()); + _surface.create(w, h, PixelFormat::createFormatCLUT8()); _borderSurface.free(); - _borderSurface.create(w, h, Graphics::PixelFormat::createFormatCLUT8()); + _borderSurface.create(w, h, PixelFormat::createFormatCLUT8()); _composeSurface.free(); - _composeSurface.create(w, h, Graphics::PixelFormat::createFormatCLUT8()); + _composeSurface.create(w, h, PixelFormat::createFormatCLUT8()); _dims.setWidth(w); _dims.setHeight(h); @@ -134,7 +140,7 @@ void MacWindow::setDimensions(const Common::Rect &r) { _contentIsDirty = true; } -bool MacWindow::draw(Graphics::ManagedSurface *g, bool forceRedraw) { +bool MacWindow::draw(ManagedSurface *g, bool forceRedraw) { if (!_borderIsDirty && !_contentIsDirty && !forceRedraw) return false; @@ -152,6 +158,7 @@ bool MacWindow::draw(Graphics::ManagedSurface *g, bool forceRedraw) { return true; } + #define ARROW_W 12 #define ARROW_H 6 const int arrowPixels[ARROW_H][ARROW_W] = { @@ -163,7 +170,7 @@ const int arrowPixels[ARROW_H][ARROW_W] = { {1,1,1,1,1,1,1,1,1,1,1,1}}; static void drawPixelInverted(int x, int y, int color, void *data) { - Graphics::ManagedSurface *surface = (Graphics::ManagedSurface *)data; + ManagedSurface *surface = (ManagedSurface *)data; if (x >= 0 && x < surface->w && y >= 0 && y < surface->h) { byte *p = (byte *)surface->getBasePtr(x, y); @@ -173,26 +180,59 @@ static void drawPixelInverted(int x, int y, int color, void *data) { } void MacWindow::updateInnerDims() { - _innerDims = _dims; - _innerDims.grow(-kBorderWidth); + if (_macBorder.hasBorder(_active) && _macBorder.hasOffsets()) { + _innerDims = Common::Rect( + _dims.left + _macBorder.getOffset(kBorderOffsetLeft), + _dims.top + _macBorder.getOffset(kBorderOffsetTop), + _dims.right - _macBorder.getOffset(kBorderOffsetRight), + _dims.bottom - _macBorder.getOffset(kBorderOffsetBottom)); + } else { + _innerDims = _dims; + _innerDims.grow(-kBorderWidth); + } } void MacWindow::drawBorder() { _borderIsDirty = false; + ManagedSurface *g = &_borderSurface; + + if (_macBorder.hasBorder(_active)) { + drawBorderFromSurface(g); + } else { + drawSimpleBorder(g); + } +} + +void MacWindow::prepareBorderSurface(ManagedSurface *g) { + // We draw rect with outer kColorGreen2 and inner kColorGreen, so on 2 passes we cut out + // scene by external shape of the border + int sz = kBorderWidth / 2; + int width = g->w; + int height = g->h; + g->clear(kColorGreen2); + g->fillRect(Common::Rect(sz, sz, width - sz, height - sz), kColorGreen); +} + +void MacWindow::drawBorderFromSurface(ManagedSurface *g) { + g->clear(kColorGreen2); + Common::Rect inside = _innerDims; + inside.moveTo(_macBorder.getOffset(kBorderOffsetLeft), _macBorder.getOffset(kBorderOffsetTop)); + g->fillRect(inside, kColorGreen); + + _macBorder.blitBorderInto(_borderSurface, _active); +} + +void MacWindow::drawSimpleBorder(ManagedSurface *g) { + bool active = _active, scrollable = _scrollable, closeable = _active, drawTitle = !_title.empty(); const int size = kBorderWidth; int x = 0; int y = 0; int width = _borderSurface.w; int height = _borderSurface.h; - Graphics::ManagedSurface *g = &_borderSurface; - // We draw rect with outer kColorGreen2 and inner kColorGreen, so on 2 passes we cut out - // scene by external shape of the border - int sz = kBorderWidth / 2; - g->clear(kColorGreen2); - g->fillRect(Common::Rect(sz, sz, width - sz, height - sz), kColorGreen); + prepareBorderSurface(g); drawBox(g, x, y, size, size); drawBox(g, x + width - size - 1, y, size, size); @@ -275,15 +315,42 @@ void MacWindow::setScroll(float scrollPos, float scrollSize) { _borderIsDirty = true; } +void MacWindow::loadBorder(Common::SeekableReadStream &file, bool active, int lo, int ro, int to, int bo) { + Image::BitmapDecoder bmpDecoder; + Graphics::Surface source; + Graphics::TransparentSurface *surface = new Graphics::TransparentSurface(); + + bmpDecoder.loadStream(file); + source = *(bmpDecoder.getSurface()); + + source.convertToInPlace(surface->getSupportedPixelFormat(), bmpDecoder.getPalette()); + surface->create(source.w, source.h, source.format); + surface->copyFrom(source); + surface->applyColorKey(255, 0, 255, false); -void MacWindow::drawBox(Graphics::ManagedSurface *g, int x, int y, int w, int h) { + if (active) + _macBorder.addActiveBorder(*surface); + else + _macBorder.addInactiveBorder(*surface); + + if (!_macBorder.hasOffsets()) + _macBorder.setOffsets(lo, ro, to, bo); + + updateInnerDims(); +} + +void MacWindow::setCloseable(bool closeable) { + _closeable = closeable; +} + +void MacWindow::drawBox(ManagedSurface *g, int x, int y, int w, int h) { Common::Rect r(x, y, x + w + 1, y + h + 1); g->fillRect(r, kColorWhite); g->frameRect(r, kColorBlack); } -void MacWindow::fillRect(Graphics::ManagedSurface *g, int x, int y, int w, int h, int color) { +void MacWindow::fillRect(ManagedSurface *g, int x, int y, int w, int h, int color) { Common::Rect r(x, y, x + w, y + h); g->fillRect(r, color); @@ -293,18 +360,54 @@ WindowClick MacWindow::isInBorder(int x, int y) { if (_innerDims.contains(x, y)) return kBorderInner; - if (x >= _innerDims.left - kBorderWidth && x < _innerDims.left && y >= _innerDims.top - kBorderWidth && y < _innerDims.top) + if (isInCloseButton(x, y)) return kBorderCloseButton; if (_resizable) - if (x >= _innerDims.right && x < _innerDims.right + kBorderWidth && y >= _innerDims.bottom && y < _innerDims.bottom + kBorderWidth) + if (isInResizeButton(x, y)) return kBorderResizeButton; - if (_scrollable && x >= _innerDims.right && x < _innerDims.right + kBorderWidth) { - if (y < _innerDims.top - kBorderWidth) + if (_scrollable) + return isInScroll(x, y); + + return kBorderBorder; +} + +bool MacWindow::isInCloseButton(int x, int y) { + int bLeft = kBorderWidth; + int bTop = kBorderWidth; + if (_macBorder.hasOffsets()) { + bLeft = _macBorder.getOffset(kBorderOffsetLeft); + bTop = _macBorder.getOffset(kBorderOffsetTop); + } + return (x >= _innerDims.left - bLeft && x < _innerDims.left && y >= _innerDims.top - bTop && y < _innerDims.top); +} + +bool MacWindow::isInResizeButton(int x, int y) { + int bRight = kBorderWidth; + int bBottom = kBorderWidth; + if (_macBorder.hasOffsets()) { + bRight = _macBorder.getOffset(kBorderOffsetRight); + bBottom = _macBorder.getOffset(kBorderOffsetBottom); + } + return (x >= _innerDims.right && x < _innerDims.right + bRight && y >= _innerDims.bottom && y < _innerDims.bottom + bBottom); +} + +WindowClick MacWindow::isInScroll(int x, int y) { + int bTop = kBorderWidth; + int bRight = kBorderWidth; + int bBottom = kBorderWidth; + if (_macBorder.hasOffsets()) { + bTop = _macBorder.getOffset(kBorderOffsetTop); + bRight = _macBorder.getOffset(kBorderOffsetRight); + bBottom = _macBorder.getOffset(kBorderOffsetBottom); + } + + if (x >= _innerDims.right && x < _innerDims.right + bRight) { + if (y < _innerDims.top - bTop) return kBorderBorder; - if (y >= _innerDims.bottom + kBorderWidth) + if (y >= _innerDims.bottom + bBottom) return kBorderBorder; if (y >= _innerDims.top + _innerDims.height() / 2) @@ -313,6 +416,19 @@ WindowClick MacWindow::isInBorder(int x, int y) { return kBorderScrollUp; } + if (y >= _innerDims.bottom && y < _innerDims.bottom + bBottom) { + if (x < _innerDims.left - bTop) + return kBorderBorder; + + if (x >= _innerDims.right + bRight) + return kBorderBorder; + + if (x >= _innerDims.left + _innerDims.width() / 2) + return kBorderScrollRight; + + return kBorderScrollLeft; + } + return kBorderBorder; } @@ -332,8 +448,8 @@ bool MacWindow::processEvent(Common::Event &event) { } if (_beingResized) { - resize(MAX(kBorderWidth * 4, _dims.width() + event.mouse.x - _draggedX), - MAX(kBorderWidth * 4, _dims.height() + event.mouse.y - _draggedY)); + resize(MAX(_borderWidth * 4, _dims.width() + event.mouse.x - _draggedX), + MAX(_borderWidth * 4, _dims.height() + event.mouse.y - _draggedY)); _draggedX = event.mouse.x; _draggedY = event.mouse.y; @@ -359,6 +475,10 @@ bool MacWindow::processEvent(Common::Event &event) { _draggedY = event.mouse.y; } + if (click == kBorderCloseButton && _closeable) { + _wm->removeWindow(this); + } + break; case Common::EVENT_LBUTTONUP: _beingDragged = false; diff --git a/graphics/macgui/macwindow.h b/graphics/macgui/macwindow.h new file mode 100644 index 0000000000..c40c1a4a38 --- /dev/null +++ b/graphics/macgui/macwindow.h @@ -0,0 +1,350 @@ +/* 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. + * + * MIT License: + * + * Copyright (c) 2009 Alexei Svitkine, Eugene Sandulenko + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef GRAPHICS_MACGUI_MACWINDOW_H +#define GRAPHICS_MACGUI_MACWINDOW_H + +#include "graphics/managed_surface.h" +#include "graphics/transparent_surface.h" +#include "graphics/nine_patch.h" +#include "graphics/palette.h" + +#include "graphics/macgui/macwindowborder.h" + +namespace Graphics { + +class MacWindowManager; +class MacWindowBorder; + +namespace MacWindowConstants { +enum WindowType { + kWindowUnknown, + kWindowWindow, + kWindowMenu +}; + +enum { + kBorderWidth = 17 +}; + +enum WindowClick { + kBorderNone = 0, + kBorderScrollUp, + kBorderScrollDown, + kBorderScrollLeft, + kBorderScrollRight, + kBorderCloseButton, + kBorderInner, + kBorderBorder, + kBorderResizeButton +}; +} +using namespace MacWindowConstants; + +/** + * Abstract class that defines common functionality for all window classes. + * It supports event callbacks and drawing. + */ +class BaseMacWindow { +public: + /** + * Base constructor. + * @param id ID of the window. + * @param editable True if the window is editable. + * @param wm Pointer to the MacWindowManager that owns the window. + */ + BaseMacWindow(int id, bool editable, MacWindowManager *wm); + virtual ~BaseMacWindow() {} + + /** + * Accessor method for the complete dimensions of the window. + * @return Dimensions of the window (including border) relative to the WM's screen. + */ + const Common::Rect &getDimensions() { return _dims; } + + /** + * Accessor method to the id of the window. + * @return The id set in the constructor. + */ + int getId() { return _id; } + + /** + * Accessor method to the type of window. + * Each subclass must indicate it's type. + * @return The type of the window. + */ + WindowType getType() { return _type; } + + /** + * Accessor method to check whether the window is editable (e.g. for resizing). + * @return True if the window is editable as indicated in the constructor. + */ + bool isEditable() { return _editable; } + + /** + * Method to access the entire surface of the window (e.g. to draw an image). + * @return A pointer to the entire surface of the window. + */ + ManagedSurface *getSurface() { return &_surface; } + + /** + * Abstract method for indicating whether the window is active or inactive. + * Used by the WM to handle focus on windows, etc. + * @param active Desired state of the window. + */ + virtual void setActive(bool active) = 0; + + /** + * Method for marking the window for redraw. + * @param dirty True if the window needs to be redrawn. + */ + void setDirty(bool dirty) { _contentIsDirty = dirty; } + + /** + * Method called to draw the window into the target surface. + * This method is most often called by the WM, and relies on + * the window being marked as dirty unless otherwise specified. + * @param g Surface on which to draw the window. + * @param forceRedraw It's behavior depends on the subclass. + */ + virtual bool draw(ManagedSurface *g, bool forceRedraw = false) = 0; + + /** + * Method called by the WM when there is an event concerning the window. + * Note that depending on the subclass of the window, it might not be called + * if the window is not active. + * @param event Event to be processed. + * @return true If the event was successfully consumed and processed. + */ + virtual bool processEvent(Common::Event &event) = 0; + + virtual bool hasAllFocus() = 0; + + /** + * Set the callback that will be used when an event needs to be processed. + * @param callback A function pointer to a function that accepts: + * - A WindowClick, the pert of the window that was clicked. + * - The event to be processed. + * - Any additional required data (e.g. the engine's GUI). + */ + void setCallback(bool (*callback)(WindowClick, Common::Event &, void *), void *data) { _callback = callback; _dataPtr = data; } + +protected: + int _id; + WindowType _type; + + bool _editable; + + ManagedSurface _surface; + bool _contentIsDirty; + + Common::Rect _dims; + + bool (*_callback)(WindowClick, Common::Event &, void *); + void *_dataPtr; + + MacWindowManager *_wm; +}; + +/** + * An implementation of an ordinary window in the Mac interface. + * It supports custom resizing, scrolling, borders, etc. + */ +class MacWindow : public BaseMacWindow { +public: + /** + * Construct a simple window, with the default settings. + * Note that the scroll must be implemented in the event handling, + * even if the scrollable flag is set to true. + * @param id See BaseMacWindow. + * @param scrollable True if the window can be scrolled. + * @param resizable True if the window can be resized. + * @param editable See BaseMacWindow. + * @param wm See BaseMacWindow. + */ + MacWindow(int id, bool scrollable, bool resizable, bool editable, MacWindowManager *wm); + virtual ~MacWindow(); + + /** + * Change the window's location to fixed coordinates (not delta). + * @param x New left position of the window relative to the WM's screen. + * @param y New top position of the window relative to the WM's screen. + */ + void move(int x, int y); + + /* + * Change the width and the height of the window. + * @param w New width of the window. + * @param h New height of the window. + */ + void resize(int w, int h); + + /** + * Change the dimensions of the window ([0, 0, 0, 0] by default). + * Note that this can be used to update both the position and the size + * of the window, although move() and resize() might be more comfortable. + * @param r The desired dimensions of the window. + */ + void setDimensions(const Common::Rect &r); + + /** + * Accessor to retrieve the dimensions of the inner surface of the window + * (i.e. without taking borders into account). + * Note that the returned dimensions' position is relative to the WM's + * screen, just like in getDimensions(). + * @return The inner dimensions of the window. + */ + const Common::Rect &getInnerDimensions() { return _innerDims; } + + /** + * Similar to that described in BaseMacWindow. + * @param g See BaseMacWindow. + * @param forceRedraw If true, the borders are guarranteed to redraw. + */ + bool draw(ManagedSurface *g, bool forceRedraw = false); + + /** + * Mutator to change the active state of the window. + * Most often called from the WM. + * @param active Target state. + */ + void setActive(bool active); + /** + * Accessor to determine whether a window is active. + * @return True if the window is active. + */ + bool isActive(); + + /** + * Mutator to change the title of the window. + * @param title Target title of the window. + */ + void setTitle(Common::String &title) { _title = title; } + /** + * Highlight the target part of the window. + * Used for the default borders. + * @param highlightedPart Part to be highlighted. + */ + void setHighlight(WindowClick highlightedPart); + /** + * Set the scroll poisition. + * @param scrollPos Target scroll position. + * @param scrollSize Size of the scrolling bar. + */ + void setScroll(float scrollPos, float scrollSize); + /** + * See BaseMacWindow. + */ + bool processEvent(Common::Event &event); + bool hasAllFocus() { return _beingDragged || _beingResized; } + + /** + * Set arbitrary border from a BMP data stream, with custom border offsets. + * Note that the BMP has to be 9patch compliant. For examples, go to: + * https://github.com/blorente/MacVenture-Extract-Guide/tree/master/borders + * @param file The BMP data stream with the desired border. + * @param active Whether the border corresponds with the active state of the window. + * @param lo Width of the left side of the border, in pixels. + * @param ro Width of the right side of the border, in pixels. + * @param to Width of the top side of the border, in pixels. + * @param bo Width of the bottom side of the border, in pixels. + */ + void loadBorder(Common::SeekableReadStream &file, bool active, int lo, int ro, int to, int bo); + //void setBorder(TransparentSurface &border, bool active); + + /** + * Indicate whether the window can be closed (false by default). + * @param closeable True if the window can be closed. + */ + void setCloseable(bool closeable); + +private: + void drawBorder(); + void prepareBorderSurface(ManagedSurface *g); + void drawSimpleBorder(ManagedSurface *g); + void drawBorderFromSurface(ManagedSurface *g); + void drawBox(ManagedSurface *g, int x, int y, int w, int h); + void fillRect(ManagedSurface *g, int x, int y, int w, int h, int color); + const Font *getTitleFont(); + void updateInnerDims(); + WindowClick isInBorder(int x, int y); + + bool isInCloseButton(int x, int y); + bool isInResizeButton(int x, int y); + WindowClick isInScroll(int x, int y); + +private: + ManagedSurface _borderSurface; + ManagedSurface _composeSurface; + + MacWindowBorder _macBorder; + + bool _scrollable; + bool _resizable; + bool _active; + bool _borderIsDirty; + + bool _closeable; + + int _borderWidth; + + bool _beingDragged, _beingResized; + int _draggedX, _draggedY; + + WindowClick _highlightedPart; + float _scrollPos, _scrollSize; + + Common::Rect _innerDims; + + Common::String _title; +}; + + + +} // End of namespace Graphics + +#endif diff --git a/graphics/macgui/macwindowborder.cpp b/graphics/macgui/macwindowborder.cpp new file mode 100644 index 0000000000..b77fa35603 --- /dev/null +++ b/graphics/macgui/macwindowborder.cpp @@ -0,0 +1,117 @@ +/* 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. +* +* MIT License: +* +* Copyright (c) 2016 Borja Lorente +* +* Permission is hereby granted, free of charge, to any person +* obtaining a copy of this software and associated documentation +* files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, +* copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following +* conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +*/ + +#include "common/system.h" + +#include "graphics/macgui/macwindowborder.h" +#include "graphics/macgui/macwindowmanager.h" + +namespace Graphics { + +using namespace Graphics::MacGUIConstants; + +MacWindowBorder::MacWindowBorder() : _activeInitialized(false), _inactiveInitialized(false) { + _activeBorder = nullptr; + _inactiveBorder = nullptr; + _hasOffsets = false; +} + +MacWindowBorder::~MacWindowBorder() { + if (_activeBorder) + delete _activeBorder; + if (_inactiveBorder) + delete _inactiveBorder; +} + +bool MacWindowBorder::hasBorder(bool active) { + return active ? _activeInitialized : _inactiveInitialized; +} + +void MacWindowBorder::addActiveBorder(TransparentSurface &source) { + assert(!_activeBorder); + _activeBorder = new NinePatchBitmap(&source, false); + _activeInitialized = true; +} + +void MacWindowBorder::addInactiveBorder(TransparentSurface &source) { + assert(!_inactiveBorder); + _inactiveBorder = new NinePatchBitmap(&source, false); + _inactiveInitialized = true; +} + +bool MacWindowBorder::hasOffsets() { + return _hasOffsets; +} + +void MacWindowBorder::setOffsets(int left, int right, int top, int bottom) { + _borderOffsets[0] = left; + _borderOffsets[1] = right; + _borderOffsets[2] = top; + _borderOffsets[3] = bottom; + _hasOffsets = true; +} + +int MacWindowBorder::getOffset(MacBorderOffset offset) { + return _borderOffsets[offset]; +} + +void MacWindowBorder::blitBorderInto(ManagedSurface &destination, bool active) { + + TransparentSurface srf; + NinePatchBitmap *src = active ? _activeBorder : _inactiveBorder; + + srf.create(destination.w, destination.h, destination.format); + srf.fillRect(Common::Rect(0, 0, srf.w, srf.h), kColorGreen2); + + byte palette[kColorCount]; + g_system->getPaletteManager()->grabPalette(palette, 0, kColorCount); + + src->blit(srf, 0, 0, srf.w, srf.h, palette, kColorCount); + destination.transBlitFrom(srf, kColorGreen2); +} + +} // End of namespace Graphics diff --git a/graphics/macgui/macwindowborder.h b/graphics/macgui/macwindowborder.h new file mode 100644 index 0000000000..54938e5143 --- /dev/null +++ b/graphics/macgui/macwindowborder.h @@ -0,0 +1,149 @@ +/* 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. +* +* MIT License: +* +* Copyright (c) 2016 Borja Lorente +* +* Permission is hereby granted, free of charge, to any person +* obtaining a copy of this software and associated documentation +* files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, +* copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following +* conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +*/ + +#ifndef GRAPHICS_MACGUI_MACWINDOWBORDER_H +#define GRAPHICS_MACGUI_MACWINDOWBORDER_H + +#include "common/str.h" +#include "common/list.h" + +#include "graphics/nine_patch.h" +#include "graphics/managed_surface.h" +#include "graphics/transparent_surface.h" + +namespace Graphics { + +enum MacBorderOffset { + kBorderOffsetLeft = 0, + kBorderOffsetRight = 1, + kBorderOffsetTop = 2, + kBorderOffsetBottom = 3 +}; + +/** + * A representation of a custom border, which allows for arbitrary border offsets + * and nine-patch resizable displays for both active and inactive states. + * However, the border offsets are the same for both active and inactive states. + */ +class MacWindowBorder { +public: + MacWindowBorder(); + ~MacWindowBorder(); + + /** + * Accessor to check whether or not a border is loaded. + * @param active State that we want to check. If true it checks for active border, if false it checks for inactive. + * @return True if the checked state has a border loaded, false otherwise. + */ + bool hasBorder(bool active); + + /** + * Add the given surface as the display of the border in the active state. + * Will fail if there is already an active border. + * @param The surface that will be displayed. + */ + void addActiveBorder(TransparentSurface &source); + + /** + * Add the given surface as the display of the border in the inactive state. + * Will fail if there is already an inactive border. + * @param The surface that will be displayed. + */ + void addInactiveBorder(TransparentSurface &source); + + /** + * Accessor function for the custom offsets. + * @return True if custom offsets have been indicated (setOffsets has been called previously). + */ + bool hasOffsets(); + + /** + * Mutator method to indicate the custom border offsets. + * These should be set to the desired thickness of each side of the border. + * e.g. For a border that is 10 pixels wide and 5 pixels tall, the call should be: + * setOffsets(10, 10, 5, 5) + * Note that this function does not check whether those borders form + * a valid rect when combined with the window dimensions. + * @param left Thickness (in pixels) of the left side of the border. + * @param right Thickness (in pixels) of the right side of the border. + * @param top Thickness (in pixels) of the top side of the border. + * @param bottom Thickness (in pixels) of the bottom side of the border. + */ + void setOffsets(int left, int right, int top, int bottom); + + /** + * Accessor method to retrieve a given border. + * Note that it does not check for validity, and thus if setOffsets + * was not called before it might return garbage. + * @param offset The identifier of the offset wanted. + * @return The desired offset in pixels. + */ + int getOffset(MacBorderOffset offset); + + /** + * Blit the desired border (active or inactive) into a destination surface. + * It automatically resizes the border to fit the given surface. + * @param destination The surface we want to blit into. + * @param active True if we want to blit the active border, false otherwise. + */ + void blitBorderInto(ManagedSurface &destination, bool active); + +private: + + NinePatchBitmap *_activeBorder; + NinePatchBitmap *_inactiveBorder; + + bool _activeInitialized; + bool _inactiveInitialized; + + bool _hasOffsets; + int _borderOffsets[4]; + +}; + +} // End of namespace Graphics +#endif diff --git a/engines/wage/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp index 6ca2efd7c9..d19e40781f 100644 --- a/engines/wage/macwindowmanager.cpp +++ b/graphics/macgui/macwindowmanager.cpp @@ -57,12 +57,11 @@ #include "graphics/managed_surface.h" #include "graphics/palette.h" #include "graphics/primitives.h" +#include "graphics/macgui/macwindowmanager.h" +#include "graphics/macgui/macwindow.h" +#include "graphics/macgui/macmenu.h" -#include "wage/macwindowmanager.h" -#include "wage/macwindow.h" -#include "wage/macmenu.h" - -namespace Wage { +namespace Graphics { static const byte palette[] = { 0, 0, 0, // Black @@ -185,13 +184,18 @@ void MacWindowManager::setActive(int id) { _fullRefresh = true; } +void MacWindowManager::removeWindow(MacWindow *target) { + _windowsToRemove.push_back(target); + _needsRemoval = true; +} + struct PlotData { Graphics::ManagedSurface *surface; - Patterns *patterns; + MacPatterns *patterns; uint fillType; int thickness; - PlotData(Graphics::ManagedSurface *s, Patterns *p, int f, int t) : + PlotData(Graphics::ManagedSurface *s, MacPatterns *p, int f, int t) : surface(s), patterns(p), fillType(f), thickness(t) {} }; @@ -243,6 +247,8 @@ void MacWindowManager::drawDesktop() { void MacWindowManager::draw() { assert(_screen); + removeMarked(); + if (_fullRefresh) drawDesktop(); @@ -291,6 +297,7 @@ bool MacWindowManager::processEvent(Common::Event &event) { it--; BaseMacWindow *w = *it; + if (w->hasAllFocus() || w->getDimensions().contains(event.mouse.x, event.mouse.y)) { if (event.type == Common::EVENT_LBUTTONDOWN || event.type == Common::EVENT_LBUTTONUP) setActive(w->getId()); @@ -302,6 +309,42 @@ bool MacWindowManager::processEvent(Common::Event &event) { return false; } +void MacWindowManager::removeMarked() { + if (!_needsRemoval) return; + + Common::List<BaseMacWindow *>::const_iterator it; + for (it = _windowsToRemove.begin(); it != _windowsToRemove.end(); it++) { + removeFromStack(*it); + removeFromWindowList(*it); + delete *it; + _activeWindow = 0; + _fullRefresh = true; + } + _windowsToRemove.clear(); + _needsRemoval = false; +} + +void MacWindowManager::removeFromStack(BaseMacWindow *target) { + Common::List<BaseMacWindow *>::iterator stackIt; + for (stackIt = _windowStack.begin(); stackIt != _windowStack.end(); stackIt++) { + if (*stackIt == target) { + stackIt = _windowStack.erase(stackIt); + stackIt--; + } + } +} + +void MacWindowManager::removeFromWindowList(BaseMacWindow *target) { + int size = _windows.size(); + int ndx = 0; + for (int i = 0; i < size; i++) { + if (_windows[i] == target) { + ndx = i; + } + } + _windows.remove_at(ndx); +} + ////////////////////// // Font stuff ////////////////////// @@ -365,6 +408,61 @@ const Graphics::Font *MacWindowManager::getFont(const char *name, Graphics::Font return font; } +// Source: Apple IIGS Technical Note #41, "Font Family Numbers" +// http://apple2.boldt.ca/?page=til/tn.iigs.041 +static const char *const fontNames[] = { + "Chicago", // system font + "Geneva", // application font + "New York", + "Geneva", + + "Monaco", + "Venice", + "London", + "Athens", + + "San Francisco", + "Toronto", + NULL, + "Cairo", + "Los Angeles", // 12 + + "Zapf Dingbats", + "Bookman", + "Helvetica Narrow", + "Palatino", + NULL, + "Zapf Chancery", + NULL, + + "Times", // 20 + "Helvetica", + "Courier", + "Symbol", + "Taliesin", // mobile? + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, // 30 + NULL, + NULL, + "Avant Garde", + "New Century Schoolbook" +}; + +const char *MacWindowManager::getFontName(int id, int size) { + static char name[128]; + + if (id > ARRAYSIZE(fontNames)) + return NULL; + + snprintf(name, 128, "%s-%d", fontNames[id], size); + + return name; +} + ///////////////// // Cursor stuff ///////////////// @@ -376,4 +474,5 @@ void MacWindowManager::popCursor() { CursorMan.popCursor(); } -} // End of namespace Wage + +} // End of namespace Graphics diff --git a/graphics/macgui/macwindowmanager.h b/graphics/macgui/macwindowmanager.h new file mode 100644 index 0000000000..cb432d9699 --- /dev/null +++ b/graphics/macgui/macwindowmanager.h @@ -0,0 +1,226 @@ +/* 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. + * + * MIT License: + * + * Copyright (c) 2009 Alexei Svitkine, Eugene Sandulenko + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef GRAPHICS_MACGUI_MACWINDOWMANAGER_H +#define GRAPHICS_MACGUI_MACWINDOWMANAGER_H + +#include "common/array.h" +#include "common/list.h" +#include "common/events.h" +#include "common/archive.h" + +#include "graphics/fontman.h" +#include "graphics/macgui/macwindow.h" + +namespace Graphics { + +namespace MacGUIConstants { +enum { + kDesktopArc = 7 +}; + +enum { + kColorBlack = 0, + kColorGray = 1, + kColorWhite = 2, + kColorGreen = 3, + kColorGreen2 = 4, + kColorCount +}; + +enum { + kPatternSolid = 1, + kPatternStripes = 2, + kPatternCheckers = 3, + kPatternCheckers2 = 4 +}; +} +using namespace MacGUIConstants; + +class ManagedSurface; + +class Menu; + +typedef Common::Array<byte *> MacPatterns; + +/** + * A manager class to handle window creation, destruction, + * drawing, moving and event handling. + */ +class MacWindowManager { +public: + MacWindowManager(); + ~MacWindowManager(); + + /** + * Mutator to indicate the surface onto which the desktop will be drawn. + * Note that this method should be called as soon as the WM is created. + * @param screen Surface on which the desktop will be drawn. + */ + void setScreen(ManagedSurface *screen) { _screen = screen; } + /** + * Accessor method to check the presence of built-in fonts. + * @return True if there are bult-in fonts. + */ + bool hasBuiltInFonts() { return _builtInFonts; } + /** + * Retrieve a font from the available ones. + * @param name Name of the desired font. + * @param fallback Fallback policy in case the desired font isn't there. + * @return The requested font or the fallback. + */ + const Font *getFont(const char *name, FontManager::FontUsage fallback); + + /** + * Return font name from standard ID + * @param id ID of the font + * @param size size of the font + * @return the font name or NULL if ID goes beyond the mapping + */ + const char *getFontName(int id, int size); + + /** + * Create a window with the given parameters. + * Note that this method allocates the necessary memory for the window. + * @param scrollable True if the window has to be scrollable. + * @param resizable True if the window can be resized. + * @param editable True if the window can be edited. + * @return Pointer to the newly created window. + */ + MacWindow *addWindow(bool scrollable, bool resizable, bool editable); + /** + * Add the menu to the desktop. + * Note that the returned menu is empty, and therefore must be filled + * afterwards. + * @return Pointer to a new empty menu. + */ + Menu *addMenu(); + /** + * Set the desired window state to active. + * @param id ID of the window that has to be set to active. + */ + void setActive(int id); + /** + * Mark a window for removal. + * Note that the window data will be destroyed. + * @param target Window to be removed. + */ + void removeWindow(MacWindow *target); + + /** + * Mutator to indicate that the entire desktop must be refreshed. + * @param redraw Currently unused. + */ + void setFullRefresh(bool redraw) { _fullRefresh = true; } + + /** + * Method to draw the desktop into the screen, + * It will take into accout the contents set as dirty. + * Note that this method does not refresh the screen, + * g_system must be called separately. + */ + void draw(); + + /** + * Method to process the events from the engine. + * Most often this method will be called from the engine's GUI, and + * will send the event to the relevant windows for them to process. + * @param event The event to be processed. + * @return True if the event was processed. + */ + bool processEvent(Common::Event &event); + + /** + * Accessor to retrieve an arbitrary window. + * @param id The id of the desired window. + * @return Pointer to the requested window, if it exists. + */ + BaseMacWindow *getWindow(int id) { return _windows[id]; } + + /** + * Retrieve the patterns used to fill surfaces. + * @return A MacPatterns object reference with the patterns. + */ + MacPatterns &getPatterns() { return _patterns; } + void drawFilledRoundRect(ManagedSurface *surface, Common::Rect &rect, int arc, int color); + + void pushArrowCursor(); + void popCursor(); + +private: + void drawDesktop(); + void loadFonts(); + + void removeMarked(); + void removeFromStack(BaseMacWindow *target); + void removeFromWindowList(BaseMacWindow *target); + +private: + ManagedSurface *_screen; + + Common::List<BaseMacWindow *> _windowStack; + Common::Array<BaseMacWindow *> _windows; + + Common::List<BaseMacWindow *> _windowsToRemove; + bool _needsRemoval; + + int _lastId; + int _activeWindow; + + bool _fullRefresh; + + MacPatterns _patterns; + + Menu *_menu; + + bool _builtInFonts; + bool _cursorIsArrow; +}; + +} // End of namespace Graphics + +#endif diff --git a/graphics/module.mk b/graphics/module.mk index 7331a56c93..1c87e74ba7 100644 --- a/graphics/module.mk +++ b/graphics/module.mk @@ -12,6 +12,10 @@ MODULE_OBJS := \ fonts/ttf.o \ fonts/winfont.o \ maccursor.o \ + macgui/macmenu.o \ + macgui/macwindow.o \ + macgui/macwindowborder.o \ + macgui/macwindowmanager.o \ managed_surface.o \ nine_patch.o \ pixelformat.o \ diff --git a/graphics/nine_patch.cpp b/graphics/nine_patch.cpp index 8ac6977eed..fa2ef20a6e 100644 --- a/graphics/nine_patch.cpp +++ b/graphics/nine_patch.cpp @@ -48,6 +48,8 @@ #include "graphics/transparent_surface.h" #include "graphics/nine_patch.h" +#include "graphics/managed_surface.h" + namespace Graphics { NinePatchSide::~NinePatchSide() { @@ -201,7 +203,7 @@ bad_bitmap: } } -void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, int dh) { +void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, int dh, byte *palette, byte numColors) { /* don't draw bitmaps that are smaller than the fixed area */ if (dw < _h._fix || dh < _v._fix) return; @@ -223,6 +225,43 @@ void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, in _cached_dh = dh; } + /* Handle CLUT8 */ + if (target.format.bytesPerPixel == 1) { + if (!palette) + warning("Trying to blit into a surface with 1bpp, you need the palette."); + + Surface srf; + srf.create(target.w, target.h, _bmp->format); + + drawRegions(srf, dx, dy, dw, dh); + + //TODO: This can be further optimized by keeping the data between draws, + // and using a unique identifier for each palette, so that it only gets + // recalculated when the palette changes. + _cached_colors.clear(); + + for (uint i = 0; i < srf.w; ++i) { + for (uint j = 0; j < srf.h; ++j) { + uint32 color = *(uint32*)srf.getBasePtr(i, j); + if (color > 0) { + *((byte *)target.getBasePtr(i, j)) = closestGrayscale(color, palette, numColors); + } + } + } + + return; + } + + /* Else, draw regions normally */ + drawRegions(target, dx, dy, dw, dh); +} + +NinePatchBitmap::~NinePatchBitmap() { + if (_destroy_bmp) + delete _bmp; +} + +void NinePatchBitmap::drawRegions(Graphics::Surface &target, int dx, int dy, int dw, int dh) { /* draw each region */ for (uint i = 0; i < _v._m.size(); ++i) { for (uint j = 0; j < _h._m.size(); ++j) { @@ -271,9 +310,50 @@ void NinePatchBitmap::blitClip(Graphics::Surface &target, Common::Rect clip, int } } -NinePatchBitmap::~NinePatchBitmap() { - if (_destroy_bmp) - delete _bmp; +byte NinePatchBitmap::getColorIndex(uint32 target, byte* palette) { + byte *pal = palette; + uint i = 0; + uint32 color = TS_RGB(pal[0], pal[1], pal[2]); + while (color != target) { + i += 3; + color = TS_RGB(pal[i], pal[i + 1], pal[i + 2]); + } + return (i / 3); +} + +uint32 NinePatchBitmap::grayscale(uint32 color) { + byte r, g, b; + _bmp->format.colorToRGB(color, r, g, b); + return grayscale(r, g, b); +} + +uint32 NinePatchBitmap::grayscale(byte r, byte g, byte b) { + return (0.29 * r + 0.58 * g + 0.11 * b) / 3; +} + +static inline uint32 dist(uint32 a, uint32 b) { + if (a > b) + return (a - b); + + return b - a; +} + +byte NinePatchBitmap::closestGrayscale(uint32 color, byte* palette, byte paletteLength) { + if (!_cached_colors.contains(color)) { + byte target = grayscale(color); + byte bestNdx = 0; + byte bestColor = grayscale(palette[0], palette[1], palette[2]); + for (byte i = 1; i < paletteLength; ++i) { + byte current = grayscale(palette[i * 3], palette[(i * 3) + 1], palette[(i * 3) + 2]); + if (dist(target, bestColor) >= dist(target, current)) { + bestColor = current; + bestNdx = i; + } + } + _cached_colors[color] = bestNdx; + } + + return _cached_colors[color]; } } // end of namespace Graphics diff --git a/graphics/nine_patch.h b/graphics/nine_patch.h index 45e4e0918a..faf44e553f 100644 --- a/graphics/nine_patch.h +++ b/graphics/nine_patch.h @@ -47,9 +47,14 @@ #define GRAPHICS_NINE_PATCH_H #include "common/array.h" +#include "common/rect.h" +#include "common/hashmap.h" namespace Graphics { +struct TransparentSurface; +struct Surface; + struct NinePatchMark { int offset; int length; @@ -77,12 +82,13 @@ class NinePatchBitmap { bool _destroy_bmp; int _width, _height; int _cached_dw, _cached_dh; + Common::HashMap<uint32, int> _cached_colors; public: NinePatchBitmap(Graphics::TransparentSurface *bmp, bool owns_bitmap); ~NinePatchBitmap(); - void blit(Graphics::Surface &target, int dx, int dy, int dw, int dh); + void blit(Graphics::Surface &target, int dx, int dy, int dw, int dh, byte *palette = NULL, byte numColors = 0); void blitClip(Graphics::Surface &target, Common::Rect clip, int dx, int dy, int dw, int dh); int getWidth() { return _width; } @@ -91,6 +97,16 @@ public: int getMinHeight() { return _v._fix; } Graphics::TransparentSurface *getSource() { return _bmp; } Common::Rect &getPadding() { return _padding; } + +private: + + void drawRegions(Graphics::Surface &target, int dx, int dy, int dw, int dh); + + // Assumes color is in the palette + byte getColorIndex(uint32 target, byte *palette); + uint32 grayscale(uint32 color); + uint32 grayscale(byte r, byte g, byte b); + byte closestGrayscale(uint32 color, byte* palette, byte paletteLength); }; } // end of namespace Graphics diff --git a/gui/themes/translations.dat b/gui/themes/translations.dat Binary files differindex b4f41fc5f1..7533d41454 100644 --- a/gui/themes/translations.dat +++ b/gui/themes/translations.dat diff --git a/image/tga.h b/image/tga.h index 677c17834f..ef897becdd 100644 --- a/image/tga.h +++ b/image/tga.h @@ -26,6 +26,7 @@ /* * TGA decoder used in engines: + * - titanic * - wintermute * - zvision */ diff --git a/po/hu_HU.po b/po/hu_HU.po index 0d968c13fe..69fc239a21 100755 --- a/po/hu_HU.po +++ b/po/hu_HU.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: ScummVM 1.3.0svn\n" "Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n" "POT-Creation-Date: 2016-07-19 09:07+0200\n" -"PO-Revision-Date: 2016-06-08 06:22+0200\n" +"PO-Revision-Date: 2016-07-20 05:59+0200\n" "Last-Translator: George Kormendi <grubycza@hotmail.com>\n" "Language-Team: Hungarian\n" "Language: Magyar\n" @@ -2880,13 +2880,12 @@ msgid "Enable high resolution graphics/content" msgstr "Nagy felbontású grafika/tartalom engedélyezése" #: engines/sci/detection.cpp:404 -#, fuzzy msgid "Enable black-lined video" -msgstr "Roland GS Mód engedélyezve" +msgstr "Feketevonalas videó engedélyezve" #: engines/sci/detection.cpp:405 msgid "Draw black lines over videos to increase their apparent sharpness" -msgstr "" +msgstr "Fekete vonalat rajzol a videó fölé, hogy növelje a kép élességét" #: engines/sci/detection.cpp:414 msgid "Prefer digital sound effects" @@ -18,6 +18,10 @@ install: $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) "$(DESTDIR)$(docdir)" $(INSTALL) -d "$(DESTDIR)$(datadir)" $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) "$(DESTDIR)$(datadir)/" + $(INSTALL) -d "$(DESTDIR)$(datarootdir)/applications" + $(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.desktop" "$(DESTDIR)$(datarootdir)/applications/scummvm.desktop" + $(INSTALL) -d "$(DESTDIR)$(datarootdir)/appdata" + $(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.appdata.xml" "$(DESTDIR)$(datarootdir)/appdata/scummvm.appdata.xml" ifdef DYNAMIC_MODULES $(INSTALL) -d "$(DESTDIR)$(libdir)/scummvm/" $(INSTALL) -c -m 644 $(PLUGINS) "$(DESTDIR)$(libdir)/scummvm/" @@ -36,6 +40,10 @@ install-strip: $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) "$(DESTDIR)$(docdir)" $(INSTALL) -d "$(DESTDIR)$(datadir)" $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) "$(DESTDIR)$(datadir)/" + $(INSTALL) -d "$(DESTDIR)$(datarootdir)/applications" + $(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.desktop" "$(DESTDIR)$(datarootdir)/applications/scummvm.desktop" + $(INSTALL) -d "$(DESTDIR)$(datarootdir)/appdata" + $(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.appdata.xml" "$(DESTDIR)$(datarootdir)/appdata/scummvm.appdata.xml" ifdef DYNAMIC_MODULES $(INSTALL) -d "$(DESTDIR)$(libdir)/scummvm/" $(INSTALL) -c -s -m 644 $(PLUGINS) "$(DESTDIR)$(libdir)/scummvm/" @@ -48,6 +56,8 @@ uninstall: rm -f "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/scummvm.svg" rm -rf "$(DESTDIR)$(docdir)" rm -rf "$(DESTDIR)$(datadir)" + rm -f "$(DESTDIR)$(datarootdir)/applications/scummvm.desktop" + rm -f "$(DESTDIR)$(datarootdir)/appdata/scummvm.appdata.xml" ifdef DYNAMIC_MODULES rm -rf "$(DESTDIR)$(libdir)/scummvm/" endif @@ -373,7 +383,7 @@ osxsnap: bundle mkdir ScummVM-snapshot/doc/da cp $(srcdir)/doc/da/HurtigStart ./ScummVM-snapshot/doc/da/HurtigStart mkdir ScummVM-snapshot/doc/de - cp $(srcdir)/doc/de/Liesmich ./ScummVM-snapshot/doc/de/Liesmich + cp $(srcdir)/doc/de/LIESMICH ./ScummVM-snapshot/doc/de/LIESMICH cp $(srcdir)/doc/de/Schnellstart ./ScummVM-snapshot/doc/de/Schnellstart mkdir ScummVM-snapshot/doc/es cp $(srcdir)/doc/es/InicioRapido ./ScummVM-snapshot/doc/es @@ -438,7 +448,7 @@ win32dist: $(EXECUTABLE) cp $(srcdir)/COPYRIGHT $(WIN32PATH)/COPYRIGHT.txt cp $(srcdir)/NEWS $(WIN32PATH)/NEWS.txt cp $(srcdir)/doc/cz/PrectiMe $(WIN32PATH)/doc/cz/PrectiMe.txt - cp $(srcdir)/doc/de/Neues $(WIN32PATH)/doc/de/Neues.txt + cp $(srcdir)/doc/de/NEUES $(WIN32PATH)/doc/de/NEUES.txt cp $(srcdir)/doc/QuickStart $(WIN32PATH)/doc/QuickStart.txt cp $(srcdir)/doc/es/InicioRapido $(WIN32PATH)/doc/es/InicioRapido.txt cp $(srcdir)/doc/fr/DemarrageRapide $(WIN32PATH)/doc/fr/DemarrageRapide.txt @@ -448,7 +458,7 @@ win32dist: $(EXECUTABLE) cp $(srcdir)/doc/de/Schnellstart $(WIN32PATH)/doc/de/Schnellstart.txt cp $(srcdir)/doc/se/Snabbstart $(WIN32PATH)/doc/se/Snabbstart.txt cp $(srcdir)/README $(WIN32PATH)/README.txt - cp $(srcdir)/doc/de/Liesmich $(WIN32PATH)/doc/de/Liesmich.txt + cp $(srcdir)/doc/de/LIESMICH $(WIN32PATH)/doc/de/LIESMICH.txt cp $(srcdir)/doc/se/LasMig $(WIN32PATH)/doc/se/LasMig.txt cp /usr/local/README-SDL.txt $(WIN32PATH) cp /usr/local/bin/SDL.dll $(WIN32PATH) diff --git a/test/module.mk b/test/module.mk index e591854ace..11ee6bd200 100644 --- a/test/module.mk +++ b/test/module.mk @@ -26,7 +26,6 @@ endif #TEST_LDFLAGS += -L/usr/X11R6/lib -lX11 -test: CXXFLAGS += -DCOMPILING_TESTS=1 test: test/runner ./test/runner test/runner: test/runner.cpp $(TEST_LIBS) diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp index 52a55f600c..980ce3a3ea 100644 --- a/video/avi_decoder.cpp +++ b/video/avi_decoder.cpp @@ -76,12 +76,13 @@ enum { }; -AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType) : _frameRateOverride(0), _soundType(soundType) { +AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType, SelectTrackFn trackFn) : + _frameRateOverride(0), _soundType(soundType), _selectTrackFn(trackFn) { initCommon(); } -AVIDecoder::AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType) - : _frameRateOverride(frameRateOverride), _soundType(soundType) { +AVIDecoder::AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType, + SelectTrackFn trackFn) : _frameRateOverride(frameRateOverride), _soundType(soundType), _selectTrackFn(trackFn) { initCommon(); } @@ -99,6 +100,8 @@ void AVIDecoder::initCommon() { _movieListStart = 0; _movieListEnd = 0; _fileStream = 0; + _videoTrackCounter = _audioTrackCounter = 0; + _lastAddedTrack = nullptr; memset(&_header, 0, sizeof(_header)); } @@ -115,7 +118,7 @@ bool AVIDecoder::parseNextChunk() { if (_fileStream->eos()) return false; - debug(3, "Decoding tag %s", tag2str(tag)); + debug(6, "Decoding tag %s", tag2str(tag)); switch (tag) { case ID_LIST: @@ -145,10 +148,12 @@ bool AVIDecoder::parseNextChunk() { case ID_JUNQ: // Same as JUNK, safe to ignore case ID_ISFT: // Metadata, safe to ignore case ID_DISP: // Metadata, should be safe to ignore - case ID_STRN: // Metadata, safe to ignore case ID_DMLH: // OpenDML extension, contains an extra total frames field, safe to ignore skipChunk(size); break; + case ID_STRN: // Metadata, safe to ignore + readStreamName(size); + break; case ID_IDX1: readOldIndex(size); break; @@ -169,7 +174,7 @@ void AVIDecoder::handleList(uint32 listSize) { listSize -= 4; // Subtract away listType's 4 bytes uint32 curPos = _fileStream->pos(); - debug(0, "Found LIST of type %s", tag2str(listType)); + debug(7, "Found LIST of type %s", tag2str(listType)); switch (listType) { case ID_MOVI: // Movie List @@ -287,6 +292,39 @@ void AVIDecoder::handleStreamHeader(uint32 size) { _fileStream->seek(startPos + strfSize); } +void AVIDecoder::addTrack(Track *track, bool isExternal) { + if (!_selectTrackFn || + (dynamic_cast<AVIVideoTrack *>(track) && _selectTrackFn(true, _videoTrackCounter++)) || + (dynamic_cast<AVIAudioTrack *>(track) && _selectTrackFn(false, _audioTrackCounter++))) { + VideoDecoder::addTrack(track, isExternal); + _lastAddedTrack = track; + } else { + _lastAddedTrack = nullptr; + } +} + +void AVIDecoder::readStreamName(uint32 size) { + if (!_lastAddedTrack) { + skipChunk(size); + } else { + // Get in the name + assert(size > 0 && size < 64); + char buffer[64]; + _fileStream->read(buffer, size); + if (size & 1) + _fileStream->skip(1); + + // Apply it to the most recently read stream + assert(_lastAddedTrack); + AVIVideoTrack *vidTrack = dynamic_cast<AVIVideoTrack *>(_lastAddedTrack); + AVIAudioTrack *audTrack = dynamic_cast<AVIAudioTrack *>(_lastAddedTrack); + if (vidTrack) + vidTrack->getName() = Common::String(buffer); + else if (audTrack) + audTrack->getName() = Common::String(buffer); + } +} + bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { close(); @@ -296,7 +334,7 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { return false; } - /* uint32 fileSize = */ stream->readUint32LE(); + int32 fileSize = stream->readUint32LE(); uint32 riffType = stream->readUint32BE(); if (riffType != ID_AVI) { @@ -307,7 +345,7 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { _fileStream = stream; // Go through all chunks in the file - while (parseNextChunk()) + while (_fileStream->pos() < fileSize && parseNextChunk()) ; if (!_decodedHeader) { @@ -337,7 +375,6 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { } if (_videoTracks.size() != 1) { - warning("Unhandled AVI video track count: %d", _videoTracks.size()); close(); return false; } @@ -384,7 +421,7 @@ void AVIDecoder::handleNextPacket(TrackStatus &status) { if (status.track->getTrackType() == Track::kTrackTypeVideo) { // Horrible AVI video has a premature end // Force the frame to be the last frame - debug(0, "Forcing end of AVI video"); + debug(7, "Forcing end of AVI video"); ((AVIVideoTrack *)status.track)->forceTrackEnd(); } @@ -404,7 +441,7 @@ void AVIDecoder::handleNextPacket(TrackStatus &status) { if (status.track->getTrackType() == Track::kTrackTypeVideo) { // Horrible AVI video has a premature end // Force the frame to be the last frame - debug(0, "Forcing end of AVI video"); + debug(7, "Forcing end of AVI video"); ((AVIVideoTrack *)status.track)->forceTrackEnd(); } @@ -647,7 +684,7 @@ byte AVIDecoder::getStreamIndex(uint32 tag) const { void AVIDecoder::readOldIndex(uint32 size) { uint32 entryCount = size / 16; - debug(0, "Old Index: %d entries", entryCount); + debug(7, "Old Index: %d entries", entryCount); if (entryCount == 0) return; @@ -663,12 +700,12 @@ void AVIDecoder::readOldIndex(uint32 size) { // If it's absolute, the offset will equal the start of the movie list bool isAbsolute = firstEntry.offset == _movieListStart; - debug(1, "Old index is %s", isAbsolute ? "absolute" : "relative"); + debug(6, "Old index is %s", isAbsolute ? "absolute" : "relative"); if (!isAbsolute) firstEntry.offset += _movieListStart - 4; - debug(0, "Index 0: Tag '%s', Offset = %d, Size = %d (Flags = %d)", tag2str(firstEntry.id), firstEntry.offset, firstEntry.size, firstEntry.flags); + debug(7, "Index 0: Tag '%s', Offset = %d, Size = %d (Flags = %d)", tag2str(firstEntry.id), firstEntry.offset, firstEntry.size, firstEntry.flags); _indexEntries.push_back(firstEntry); for (uint32 i = 1; i < entryCount; i++) { @@ -683,7 +720,7 @@ void AVIDecoder::readOldIndex(uint32 size) { indexEntry.offset += _movieListStart - 4; _indexEntries.push_back(indexEntry); - debug(0, "Index %d: Tag '%s', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags); + debug(7, "Index %d: Tag '%s', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags); } } diff --git a/video/avi_decoder.h b/video/avi_decoder.h index 96d9e821ff..a3733b579c 100644 --- a/video/avi_decoder.h +++ b/video/avi_decoder.h @@ -57,12 +57,15 @@ namespace Video { * - sci * - sword1 * - sword2 + * - titanic * - zvision */ class AVIDecoder : public VideoDecoder { public: - AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); - AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); + typedef bool(*SelectTrackFn)(bool isVideo, int trackNumber); + AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType, SelectTrackFn trackFn = nullptr); + AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType, + SelectTrackFn trackFn = nullptr); virtual ~AVIDecoder(); bool loadStream(Common::SeekableReadStream *stream); @@ -81,6 +84,16 @@ protected: bool supportsAudioTrackSwitching() const { return true; } AudioTrack *getAudioTrack(int index); + /** + * Define a track to be used by this class. + * + * The pointer is then owned by this base class. + * + * @param track The track to add + * @param isExternal Is this an external track not found by loadStream()? + */ + void addTrack(Track *track, bool isExternal = false); + struct BitmapInfoHeader { uint32 size; uint32 width; @@ -164,6 +177,7 @@ protected: uint32 quality; uint32 sampleSize; Common::Rect frame; + Common::String name; }; class AVIVideoTrack : public FixedRateVideoTrack { @@ -179,6 +193,7 @@ protected: Graphics::PixelFormat getPixelFormat() const; int getCurFrame() const { return _curFrame; } int getFrameCount() const { return _frameCount; } + Common::String &getName() { return _vidsHeader.name; } const Graphics::Surface *decodeNextFrame() { return _lastFrame; } const byte *getPalette() const; @@ -222,6 +237,7 @@ protected: void skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime); virtual void resetStream(); uint32 getCurChunk() const { return _curChunk; } + Common::String &getName() { return _audsHeader.name; } void setCurChunk(uint32 chunk) { _curChunk = chunk; } bool isRewindable() const { return true; } @@ -268,12 +284,18 @@ protected: Audio::Mixer::SoundType _soundType; Common::Rational _frameRateOverride; + + int _videoTrackCounter, _audioTrackCounter; + Track *_lastAddedTrack; + SelectTrackFn _selectTrackFn; + void initCommon(); bool parseNextChunk(); void skipChunk(uint32 size); void handleList(uint32 listSize); void handleStreamHeader(uint32 size); + void readStreamName(uint32 size); uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; } byte getStreamIndex(uint32 tag) const; void checkTruemotion1(); |