diff options
122 files changed, 14302 insertions, 9915 deletions
@@ -32,7 +32,7 @@ ScummVM Team Max Horn - (retired) Travis Howell Pawel Kolodziejski - Codecs, iMUSE, Smush, etc. - Gregory Montoir + Gregory Montoir - (retired) Eugene Sandulenko - FT INSANE, MM NES, MM C64, game detection, Herc/CGA Ludvig Strigeus - (retired) @@ -40,7 +40,7 @@ ScummVM Team HE: Jonathan Gray - (retired) Travis Howell - Gregory Montoir + Gregory Montoir - (retired) Eugene Sandulenko AGI: @@ -67,7 +67,7 @@ ScummVM Team Cine: Vincent Hamm - (retired) Pawel Kolodziejski - Gregory Montoir + Gregory Montoir - (retired) Kari Salminen Eugene Sandulenko @@ -111,7 +111,7 @@ ScummVM Team Torbjorn Andersson - VQA Player Oystein Eftevaag Florian Kagerer - Gregory Montoir + Gregory Montoir - (retired) Johannes Schickel Lastexpress: @@ -139,7 +139,7 @@ ScummVM Team Queen: David Eriksson - (retired) - Gregory Montoir + Gregory Montoir - (retired) Joost Peters SAGA: @@ -198,14 +198,14 @@ ScummVM Team Sylvain Dupont Touche: - Gregory Montoir + Gregory Montoir - (retired) TsAGE: Arnaud Boutonne Paul Gilbert Tucker: - Gregory Montoir + Gregory Montoir - (retired) Backend Teams ------------- @@ -11,6 +11,9 @@ For a more comprehensive changelog of the latest experimental code, see: Broken Sword 1: - Fixed incorrect sound effects in the DOS/Windows demo. + Cine: + - Implemented Roland MT-32 output driver. + SCUMM: - Added support for the Macintosh version of SPY Fox in Hold the Mustard. diff --git a/audio/decoders/quicktime.cpp b/audio/decoders/quicktime.cpp index 8cf0305e88..e737bf8e10 100644 --- a/audio/decoders/quicktime.cpp +++ b/audio/decoders/quicktime.cpp @@ -87,6 +87,9 @@ void QuickTimeAudioDecoder::init() { // Initialize the codec (if necessary) entry->initCodec(); + + if (_tracks[_audioTrackIndex]->editCount != 1) + warning("Multiple edit list entries in an audio track. Things may go awry"); } } } @@ -414,7 +417,9 @@ public: } Timestamp getLength() const { - return Timestamp(0, _tracks[_audioTrackIndex]->duration, _tracks[_audioTrackIndex]->timeScale); + // TODO: Switch to the other one when audio edits are supported + //return Timestamp(0, _tracks[_audioTrackIndex]->duration, _timeScale); + return Timestamp(0, _tracks[_audioTrackIndex]->mediaDuration, _tracks[_audioTrackIndex]->timeScale); } }; diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index cfc78cfcac..f2b3168e36 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -318,12 +318,12 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() { // only used to ensure that the original pixel size aspect for these // modes is used. // (Non-square pixels on old monitors vs square pixel on new ones). - if (_videoMode.aspectRatioCorrection - && ((_videoMode.screenWidth == 320 && _videoMode.screenHeight == 200) - || (_videoMode.screenWidth == 640 && _videoMode.screenHeight == 400))) - _videoMode.overlayHeight = _videoMode.hardwareHeight = 240 * scaleFactor; - else - _videoMode.overlayHeight = _videoMode.hardwareHeight = _videoMode.screenHeight * scaleFactor; + if (_videoMode.aspectRatioCorrection) { + if (_videoMode.screenWidth == 320 && _videoMode.screenHeight == 200) + _videoMode.overlayHeight = _videoMode.hardwareHeight = 240 * scaleFactor; + else if (_videoMode.screenWidth == 640 && _videoMode.screenHeight == 400) + _videoMode.overlayHeight = _videoMode.hardwareHeight = 480 * scaleFactor; + } } _screenResized = false; diff --git a/backends/keymapper/action.h b/backends/keymapper/action.h index b15b3aaaad..e5bf6d51dd 100644 --- a/backends/keymapper/action.h +++ b/backends/keymapper/action.h @@ -40,6 +40,12 @@ class Keymap; #define ACTION_ID_SIZE (4) +struct KeyActionEntry { + const KeyState ks; + const char *id; + const char *description; +}; + struct Action { /** unique id used for saving/loading to config */ char id[ACTION_ID_SIZE]; diff --git a/backends/keymapper/remap-dialog.cpp b/backends/keymapper/remap-dialog.cpp index b0f42fe426..4813beb38c 100644 --- a/backends/keymapper/remap-dialog.cpp +++ b/backends/keymapper/remap-dialog.cpp @@ -172,16 +172,7 @@ void RemapDialog::reflowLayout() { new GUI::StaticTextWidget(this, 0, 0, 0, 0, "", Graphics::kTextAlignRight); widg.keyButton = new GUI::ButtonWidget(this, 0, 0, 0, 0, "", 0, kRemapCmd + i); -#ifndef DISABLE_FANCY_THEMES - if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) { - widg.clearButton = new GUI::PicButtonWidget(this, 0, 0, clearButtonWidth, clearButtonHeight, _("Clear value"), kClearCmd + i); - ((GUI::PicButtonWidget *)widg.clearButton)->useThemeTransparency(true); - ((GUI::PicButtonWidget *)widg.clearButton)->setGfx(g_gui.theme()->getImageSurface(GUI::ThemeEngine::kImageEraser)); - } - else -#endif - widg.clearButton = new GUI::ButtonWidget(this, 0, 0, 0, 0, "C", _("Clear value"), kClearCmd + i); - + widg.clearButton = addClearButton(this, "", kClearCmd, 0, 0, clearButtonWidth, clearButtonHeight); _keymapWidgets.push_back(widg); } else { widg = _keymapWidgets[i]; diff --git a/backends/midi/coreaudio.cpp b/backends/midi/coreaudio.cpp index 305b462836..4b707eace6 100644 --- a/backends/midi/coreaudio.cpp +++ b/backends/midi/coreaudio.cpp @@ -26,15 +26,24 @@ #ifdef MACOSX -// HACK to disable deprecated warnings under Mac OS X 10.5. -// Apple depracted the AUGraphNewNode & AUGraphGetNodeInfo APIs -// in favor of the new AUGraphAddNode & AUGraphNodeInfo APIs. -// While it would be trivial to switch to those, this would break -// binary compatibility with all pre-10.5 systems, so we don't want -// to do that just now. Maybe when 10.6 comes... :) + +// HACK to disable deprecated warnings under Mac OS X 10.5. Apple deprecated the +// AUGraphNewNode & AUGraphGetNodeInfo APIs in favor of the new AUGraphAddNode & +// AUGraphNodeInfo APIs. While it is easy to switch to those, it breaks +// compatibility with all pre-10.5 systems. +// If you want to retain compatibility with old systems, enable the following +// switch. But Apple will eventually remove these APIs, at which point the +// switch needs to be disabled. +// +// Also note that only the new API is available on the iPhone! +#define USE_DEPRECATED_COREAUDIO_API + + +#ifdef USE_DEPRECATED_COREAUDIO_API #include <AvailabilityMacros.h> #undef DEPRECATED_ATTRIBUTE #define DEPRECATED_ATTRIBUTE +#endif #include "common/config-manager.h" @@ -105,7 +114,11 @@ int MidiDriver_CORE::open() { RequireNoErr(NewAUGraph(&_auGraph)); AUNode outputNode, synthNode; +#ifdef USE_DEPRECATED_COREAUDIO_API ComponentDescription desc; +#else + AudioComponentDescription desc; +#endif // The default output device desc.componentType = kAudioUnitType_Output; @@ -113,13 +126,21 @@ int MidiDriver_CORE::open() { desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentFlags = 0; desc.componentFlagsMask = 0; +#ifdef USE_DEPRECATED_COREAUDIO_API RequireNoErr(AUGraphNewNode(_auGraph, &desc, 0, NULL, &outputNode)); +#else + RequireNoErr(AUGraphAddNode(_auGraph, &desc, &outputNode)); +#endif // The built-in default (softsynth) music device desc.componentType = kAudioUnitType_MusicDevice; desc.componentSubType = kAudioUnitSubType_DLSSynth; desc.componentManufacturer = kAudioUnitManufacturer_Apple; +#ifdef USE_DEPRECATED_COREAUDIO_API RequireNoErr(AUGraphNewNode(_auGraph, &desc, 0, NULL, &synthNode)); +#else + RequireNoErr(AUGraphAddNode(_auGraph, &desc, &synthNode)); +#endif // Connect the softsynth to the default output RequireNoErr(AUGraphConnectNodeInput(_auGraph, synthNode, 0, outputNode, 0)); @@ -129,8 +150,11 @@ int MidiDriver_CORE::open() { RequireNoErr(AUGraphInitialize(_auGraph)); // Get the music device from the graph. +#ifdef USE_DEPRECATED_COREAUDIO_API RequireNoErr(AUGraphGetNodeInfo(_auGraph, synthNode, NULL, NULL, NULL, &_synth)); - +#else + RequireNoErr(AUGraphNodeInfo(_auGraph, synthNode, NULL, &_synth)); +#endif // Load custom soundfont, if specified if (ConfMan.hasKey("soundfont")) { diff --git a/backends/midi/timidity.cpp b/backends/midi/timidity.cpp index 87cd08659c..172d31e799 100644 --- a/backends/midi/timidity.cpp +++ b/backends/midi/timidity.cpp @@ -197,6 +197,8 @@ int MidiDriver_TIMIDITY::open() { /* should read something like "200 63017 is ready acceptable", * where 63017 is port for data connection */ + // FIXME: The following looks like a cheap endian test. If this is true, then + // it should be replaced by suitable #ifdef SCUMM_LITTLE_ENDIAN. i = 1; if (*(char *)&i == 1) res = timidity_ctl_command("OPEN lsb"); diff --git a/backends/platform/android/asset-archive.cpp b/backends/platform/android/asset-archive.cpp index fe52a3d8d4..14840de996 100644 --- a/backends/platform/android/asset-archive.cpp +++ b/backends/platform/android/asset-archive.cpp @@ -103,7 +103,7 @@ JavaInputStream::JavaInputStream(JNIEnv *env, jobject is) : MID_mark = env->GetMethodID(cls, "mark", "(I)V"); assert(MID_mark); MID_available = env->GetMethodID(cls, "available", "()I"); - assert(MID_mark); + assert(MID_available); MID_close = env->GetMethodID(cls, "close", "()V"); assert(MID_close); MID_read = env->GetMethodID(cls, "read", "([BII)I"); @@ -389,7 +389,7 @@ AndroidAssetArchive::~AndroidAssetArchive() { env->DeleteGlobalRef(_am); } -bool AndroidAssetArchive::hasFile(const Common::String &name) { +bool AndroidAssetArchive::hasFile(const Common::String &name) const { JNIEnv *env = JNI::getEnv(); jstring path = env->NewStringUTF(name.c_str()); jobject result = env->CallObjectMethod(_am, MID_open, path, ACCESS_UNKNOWN); @@ -409,7 +409,7 @@ bool AndroidAssetArchive::hasFile(const Common::String &name) { return true; } -int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) { +int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) const { JNIEnv *env = JNI::getEnv(); Common::List<Common::String> dirlist; dirlist.push_back(""); @@ -466,7 +466,7 @@ int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) { return count; } -Common::ArchiveMemberPtr AndroidAssetArchive::getMember(const Common::String &name) { +const Common::ArchiveMemberPtr AndroidAssetArchive::getMember(const Common::String &name) const { return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this)); } diff --git a/backends/platform/android/asset-archive.h b/backends/platform/android/asset-archive.h index 9216412e0a..c5e43555e0 100644 --- a/backends/platform/android/asset-archive.h +++ b/backends/platform/android/asset-archive.h @@ -37,9 +37,9 @@ public: AndroidAssetArchive(jobject am); virtual ~AndroidAssetArchive(); - virtual bool hasFile(const Common::String &name); - virtual int listMembers(Common::ArchiveMemberList &list); - virtual Common::ArchiveMemberPtr getMember(const Common::String &name); + virtual bool hasFile(const Common::String &name) const; + virtual int listMembers(Common::ArchiveMemberList &list) const; + virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const; virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; private: diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp index a2c8e43424..3e09aa2640 100644 --- a/backends/platform/sdl/win32/win32.cpp +++ b/backends/platform/sdl/win32/win32.cpp @@ -256,9 +256,9 @@ class Win32ResourceArchive : public Common::Archive { public: Win32ResourceArchive(); - virtual bool hasFile(const Common::String &name); - virtual int listMembers(Common::ArchiveMemberList &list); - virtual Common::ArchiveMemberPtr getMember(const Common::String &name); + virtual bool hasFile(const Common::String &name) const; + virtual int listMembers(Common::ArchiveMemberList &list) const; + virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const; virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; private: typedef Common::List<Common::String> FilenameList; @@ -279,7 +279,7 @@ Win32ResourceArchive::Win32ResourceArchive() { EnumResourceNames(NULL, MAKEINTRESOURCE(256), &EnumResNameProc, (LONG_PTR)this); } -bool Win32ResourceArchive::hasFile(const Common::String &name) { +bool Win32ResourceArchive::hasFile(const Common::String &name) const { for (FilenameList::const_iterator i = _files.begin(); i != _files.end(); ++i) { if (i->equalsIgnoreCase(name)) return true; @@ -288,7 +288,7 @@ bool Win32ResourceArchive::hasFile(const Common::String &name) { return false; } -int Win32ResourceArchive::listMembers(Common::ArchiveMemberList &list) { +int Win32ResourceArchive::listMembers(Common::ArchiveMemberList &list) const { int count = 0; for (FilenameList::const_iterator i = _files.begin(); i != _files.end(); ++i, ++count) @@ -297,7 +297,7 @@ int Win32ResourceArchive::listMembers(Common::ArchiveMemberList &list) { return count; } -Common::ArchiveMemberPtr Win32ResourceArchive::getMember(const Common::String &name) { +const Common::ArchiveMemberPtr Win32ResourceArchive::getMember(const Common::String &name) const { return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this)); } diff --git a/common/archive.cpp b/common/archive.cpp index 954de8bcaa..1323f14805 100644 --- a/common/archive.cpp +++ b/common/archive.cpp @@ -27,7 +27,7 @@ namespace Common { -GenericArchiveMember::GenericArchiveMember(String name, Archive *parent) +GenericArchiveMember::GenericArchiveMember(const String &name, const Archive *parent) : _parent(parent), _name(name) { } @@ -40,14 +40,14 @@ SeekableReadStream *GenericArchiveMember::createReadStream() const { } -int Archive::listMatchingMembers(ArchiveMemberList &list, const String &pattern) { +int Archive::listMatchingMembers(ArchiveMemberList &list, const String &pattern) const { // Get all "names" (TODO: "files" ?) ArchiveMemberList allNames; listMembers(allNames); int matches = 0; - ArchiveMemberList::iterator it = allNames.begin(); + ArchiveMemberList::const_iterator it = allNames.begin(); for ( ; it != allNames.end(); ++it) { // TODO: We match case-insenstivie for now, our API does not define whether that's ok or not though... // For our use case case-insensitive is probably what we want to have though. @@ -206,11 +206,11 @@ void SearchSet::setPriority(const String &name, int priority) { insert(node); } -bool SearchSet::hasFile(const String &name) { +bool SearchSet::hasFile(const String &name) const { if (name.empty()) return false; - ArchiveNodeList::iterator it = _list.begin(); + ArchiveNodeList::const_iterator it = _list.begin(); for ( ; it != _list.end(); ++it) { if (it->_arc->hasFile(name)) return true; @@ -219,31 +219,31 @@ bool SearchSet::hasFile(const String &name) { return false; } -int SearchSet::listMatchingMembers(ArchiveMemberList &list, const String &pattern) { +int SearchSet::listMatchingMembers(ArchiveMemberList &list, const String &pattern) const { int matches = 0; - ArchiveNodeList::iterator it = _list.begin(); + ArchiveNodeList::const_iterator it = _list.begin(); for ( ; it != _list.end(); ++it) matches += it->_arc->listMatchingMembers(list, pattern); return matches; } -int SearchSet::listMembers(ArchiveMemberList &list) { +int SearchSet::listMembers(ArchiveMemberList &list) const { int matches = 0; - ArchiveNodeList::iterator it = _list.begin(); + ArchiveNodeList::const_iterator it = _list.begin(); for ( ; it != _list.end(); ++it) matches += it->_arc->listMembers(list); return matches; } -ArchiveMemberPtr SearchSet::getMember(const String &name) { +const ArchiveMemberPtr SearchSet::getMember(const String &name) const { if (name.empty()) return ArchiveMemberPtr(); - ArchiveNodeList::iterator it = _list.begin(); + ArchiveNodeList::const_iterator it = _list.begin(); for ( ; it != _list.end(); ++it) { if (it->_arc->hasFile(name)) return it->_arc->getMember(name); diff --git a/common/archive.h b/common/archive.h index c8e78f9bc8..ffd86d786d 100644 --- a/common/archive.h +++ b/common/archive.h @@ -65,10 +65,10 @@ class Archive; * is destroyed. */ class GenericArchiveMember : public ArchiveMember { - Archive *_parent; - String _name; + const Archive *_parent; + const String _name; public: - GenericArchiveMember(String name, Archive *parent); + GenericArchiveMember(const String &name, const Archive *parent); String getName() const; SeekableReadStream *createReadStream() const; }; @@ -88,7 +88,7 @@ public: * Patterns are not allowed, as this is meant to be a quick File::exists() * replacement. */ - virtual bool hasFile(const String &name) = 0; + virtual bool hasFile(const String &name) const = 0; /** * Add all members of the Archive matching the specified pattern to list. @@ -96,7 +96,7 @@ public: * * @return the number of members added to list */ - virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern); + virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern) const; /** * Add all members of the Archive to list. @@ -104,12 +104,12 @@ public: * * @return the number of names added to list */ - virtual int listMembers(ArchiveMemberList &list) = 0; + virtual int listMembers(ArchiveMemberList &list) const = 0; /** * Returns a ArchiveMember representation of the given file. */ - virtual ArchiveMemberPtr getMember(const String &name) = 0; + virtual const ArchiveMemberPtr getMember(const String &name) const = 0; /** * Create a stream bound to a member with the specified name in the @@ -230,11 +230,11 @@ public: */ void setPriority(const String& name, int priority); - virtual bool hasFile(const String &name); - virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern); - virtual int listMembers(ArchiveMemberList &list); + virtual bool hasFile(const String &name) const; + virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern) const; + virtual int listMembers(ArchiveMemberList &list) const; - virtual ArchiveMemberPtr getMember(const String &name); + virtual const ArchiveMemberPtr getMember(const String &name) const; /** * Implements createReadStreamForMember from Archive base class. The current policy is diff --git a/common/fs.cpp b/common/fs.cpp index 4b56cc4594..8ea96e458a 100644 --- a/common/fs.cpp +++ b/common/fs.cpp @@ -197,7 +197,7 @@ FSNode *FSDirectory::lookupCache(NodeCache &cache, const String &name) const { return 0; } -bool FSDirectory::hasFile(const String &name) { +bool FSDirectory::hasFile(const String &name) const { if (name.empty() || !_node.isDirectory()) return false; @@ -205,7 +205,7 @@ bool FSDirectory::hasFile(const String &name) { return node && node->exists(); } -ArchiveMemberPtr FSDirectory::getMember(const String &name) { +const ArchiveMemberPtr FSDirectory::getMember(const String &name) const { if (name.empty() || !_node.isDirectory()) return ArchiveMemberPtr(); @@ -295,7 +295,7 @@ void FSDirectory::ensureCached() const { _cached = true; } -int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &pattern) { +int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &pattern) const { if (!_node.isDirectory()) return 0; @@ -308,7 +308,7 @@ int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &patt lowercasePattern.toLowercase(); int matches = 0; - NodeCache::iterator it = _fileCache.begin(); + NodeCache::const_iterator it = _fileCache.begin(); for ( ; it != _fileCache.end(); ++it) { if (it->_key.matchString(lowercasePattern, false, true)) { list.push_back(ArchiveMemberPtr(new FSNode(it->_value))); @@ -318,7 +318,7 @@ int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &patt return matches; } -int FSDirectory::listMembers(ArchiveMemberList &list) { +int FSDirectory::listMembers(ArchiveMemberList &list) const { if (!_node.isDirectory()) return 0; @@ -326,7 +326,7 @@ int FSDirectory::listMembers(ArchiveMemberList &list) { ensureCached(); int files = 0; - for (NodeCache::iterator it = _fileCache.begin(); it != _fileCache.end(); ++it) { + for (NodeCache::const_iterator it = _fileCache.begin(); it != _fileCache.end(); ++it) { list.push_back(ArchiveMemberPtr(new FSNode(it->_value))); ++files; } diff --git a/common/fs.h b/common/fs.h index aeaa14718e..fadd672bb1 100644 --- a/common/fs.h +++ b/common/fs.h @@ -318,23 +318,23 @@ public: * Checks for existence in the cache. A full match of relative path and filename is needed * for success. */ - virtual bool hasFile(const String &name); + virtual bool hasFile(const String &name) const; /** * Returns a list of matching file names. Pattern can use GLOB wildcards. */ - virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern); + virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern) const; /** * Returns a list of all the files in the cache. */ - virtual int listMembers(ArchiveMemberList &list); + virtual int listMembers(ArchiveMemberList &list) const; /** * Get a ArchiveMember representation of the specified file. A full match of relative * path and filename is needed for success. */ - virtual ArchiveMemberPtr getMember(const String &name); + virtual const ArchiveMemberPtr getMember(const String &name) const; /** * Open the specified file. A full match of relative path and filename is needed diff --git a/common/quicktime.cpp b/common/quicktime.cpp index 9ea8c229ea..dbec7f7b90 100644 --- a/common/quicktime.cpp +++ b/common/quicktime.cpp @@ -135,7 +135,7 @@ void QuickTimeParser::initParseTable() { { &QuickTimeParser::readDefault, MKTAG('e', 'd', 't', 's') }, { &QuickTimeParser::readELST, MKTAG('e', 'l', 's', 't') }, { &QuickTimeParser::readHDLR, MKTAG('h', 'd', 'l', 'r') }, - { &QuickTimeParser::readDefault, MKTAG('m', 'd', 'a', 't') }, + { &QuickTimeParser::readLeaf, MKTAG('m', 'd', 'a', 't') }, { &QuickTimeParser::readMDHD, MKTAG('m', 'd', 'h', 'd') }, { &QuickTimeParser::readDefault, MKTAG('m', 'd', 'i', 'a') }, { &QuickTimeParser::readDefault, MKTAG('m', 'i', 'n', 'f') }, @@ -386,8 +386,7 @@ int QuickTimeParser::readTKHD(Atom atom) { /* track->id = */_fd->readUint32BE(); // track id (NOT 0 !) _fd->readUint32BE(); // reserved - //track->startTime = 0; // check - (version == 1) ? (_fd->readUint32BE(), _fd->readUint32BE()) : _fd->readUint32BE(); // highlevel (considering edits) duration in movie timebase + track->duration = (version == 1) ? (_fd->readUint32BE(), _fd->readUint32BE()) : _fd->readUint32BE(); // highlevel (considering edits) duration in movie timebase _fd->readUint32BE(); // reserved _fd->readUint32BE(); // reserved @@ -410,8 +409,8 @@ int QuickTimeParser::readTKHD(Atom atom) { track->scaleFactorY.debugPrint(1, "readTKHD(): scaleFactorY ="); // these are fixed-point, 16:16 - // uint32 tkWidth = _fd->readUint32BE() >> 16; // track width - // uint32 tkHeight = _fd->readUint32BE() >> 16; // track height + //_fd->readUint32BE() >> 16; // track width + //_fd->readUint32BE() >> 16; // track height return 0; } @@ -428,17 +427,18 @@ int QuickTimeParser::readELST(Atom atom) { debug(2, "Track %d edit list count: %d", _tracks.size() - 1, track->editCount); + uint32 offset = 0; + for (uint32 i = 0; i < track->editCount; i++){ track->editList[i].trackDuration = _fd->readUint32BE(); track->editList[i].mediaTime = _fd->readSint32BE(); track->editList[i].mediaRate = Rational(_fd->readUint32BE(), 0x10000); - debugN(3, "\tDuration = %d, Media Time = %d, ", track->editList[i].trackDuration, track->editList[i].mediaTime); + track->editList[i].timeOffset = offset; + debugN(3, "\tDuration = %d (Offset = %d), Media Time = %d, ", track->editList[i].trackDuration, offset, track->editList[i].mediaTime); track->editList[i].mediaRate.debugPrint(3, "Media Rate ="); + offset += track->editList[i].trackDuration; } - if (track->editCount != 1) - warning("Multiple edit list entries. Things may go awry"); - return 0; } @@ -500,7 +500,7 @@ int QuickTimeParser::readMDHD(Atom atom) { } track->timeScale = _fd->readUint32BE(); - track->duration = (version == 1) ? (_fd->readUint32BE(), _fd->readUint32BE()) : _fd->readUint32BE(); // duration + track->mediaDuration = (version == 1) ? (_fd->readUint32BE(), _fd->readUint32BE()) : _fd->readUint32BE(); // duration _fd->readUint16BE(); // language _fd->readUint16BE(); // quality @@ -793,6 +793,7 @@ QuickTimeParser::Track::Track() { duration = 0; startTime = 0; objectTypeMP4 = 0; + mediaDuration = 0; } QuickTimeParser::Track::~Track() { diff --git a/common/quicktime.h b/common/quicktime.h index e4c821e209..d7e2691c2b 100644 --- a/common/quicktime.h +++ b/common/quicktime.h @@ -109,6 +109,7 @@ protected: struct EditListEntry { uint32 trackDuration; + uint32 timeOffset; int32 mediaTime; Rational mediaRate; }; @@ -163,6 +164,7 @@ protected: uint32 frameCount; uint32 duration; + uint32 mediaDuration; uint32 startTime; Rational scaleFactorX; Rational scaleFactorY; diff --git a/common/unarj.cpp b/common/unarj.cpp index cccc330bb5..fe3c17a2ac 100644 --- a/common/unarj.cpp +++ b/common/unarj.cpp @@ -701,9 +701,9 @@ public: virtual ~ArjArchive(); // Archive implementation - virtual bool hasFile(const String &name); - virtual int listMembers(ArchiveMemberList &list); - virtual ArchiveMemberPtr getMember(const String &name); + virtual bool hasFile(const String &name) const; + virtual int listMembers(ArchiveMemberList &list) const; + virtual const ArchiveMemberPtr getMember(const String &name) const; virtual SeekableReadStream *createReadStreamForMember(const String &name) const; }; @@ -745,14 +745,14 @@ ArjArchive::~ArjArchive() { } } -bool ArjArchive::hasFile(const String &name) { +bool ArjArchive::hasFile(const String &name) const { return _headers.contains(name); } -int ArjArchive::listMembers(ArchiveMemberList &list) { +int ArjArchive::listMembers(ArchiveMemberList &list) const { int matches = 0; - ArjHeadersMap::iterator it = _headers.begin(); + ArjHeadersMap::const_iterator it = _headers.begin(); for ( ; it != _headers.end(); ++it) { list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(it->_value->filename, this))); matches++; @@ -761,7 +761,7 @@ int ArjArchive::listMembers(ArchiveMemberList &list) { return matches; } -ArchiveMemberPtr ArjArchive::getMember(const String &name) { +const ArchiveMemberPtr ArjArchive::getMember(const String &name) const { if (!hasFile(name)) return ArchiveMemberPtr(); diff --git a/common/unzip.cpp b/common/unzip.cpp index 8650c91866..8061f712d4 100644 --- a/common/unzip.cpp +++ b/common/unzip.cpp @@ -1426,9 +1426,9 @@ public: ~ZipArchive(); - virtual bool hasFile(const String &name); - virtual int listMembers(ArchiveMemberList &list); - virtual ArchiveMemberPtr getMember(const String &name); + virtual bool hasFile(const String &name) const; + virtual int listMembers(ArchiveMemberList &list) const; + virtual const ArchiveMemberPtr getMember(const String &name) const; virtual SeekableReadStream *createReadStreamForMember(const String &name) const; }; @@ -1458,11 +1458,11 @@ ZipArchive::~ZipArchive() { unzClose(_zipFile); } -bool ZipArchive::hasFile(const String &name) { +bool ZipArchive::hasFile(const String &name) const { return (unzLocateFile(_zipFile, name.c_str(), 2) == UNZ_OK); } -int ZipArchive::listMembers(ArchiveMemberList &list) { +int ZipArchive::listMembers(ArchiveMemberList &list) const { int matches = 0; int err = unzGoToFirstFile(_zipFile); @@ -1481,7 +1481,7 @@ int ZipArchive::listMembers(ArchiveMemberList &list) { return matches; } -ArchiveMemberPtr ZipArchive::getMember(const String &name) { +const ArchiveMemberPtr ZipArchive::getMember(const String &name) const { if (!hasFile(name)) return ArchiveMemberPtr(); @@ -137,7 +137,7 @@ _seq_midi=auto _timidity=auto _zlib=auto _sparkle=auto -_png=auto +_png=no _theoradec=auto _faad=auto _fluidsynth=auto @@ -1279,7 +1279,7 @@ wii) wince) _host_os=wince _host_cpu=arm - _host_alias=arm-wince-mingw32ce + _host_alias=arm-mingw32ce ;; *) if test -n "$_host"; then @@ -2292,7 +2292,6 @@ if test -n "$_host"; then CXXFLAGS="$CXXFLAGS -mcpu=arm926ej-s" CXXFLAGS="$CXXFLAGS -fomit-frame-pointer" INCLUDES="$INCLUDES -I/usr/X11R6/include" - LIBS="$LIBS -lpthread" LIBS="$LIBS -lX11" LIBS="$LIBS -L/usr/lib" diff --git a/devtools/credits.pl b/devtools/credits.pl index 2833236e75..86ba7412fa 100755 --- a/devtools/credits.pl +++ b/devtools/credits.pl @@ -484,7 +484,7 @@ begin_credits("Credits"); add_person("Max Horn", "Fingolfin", "(retired)"); add_person("Travis Howell", "Kirben", ""); add_person("Paweł Kołodziejski", "aquadran", "Codecs, iMUSE, Smush, etc."); - add_person("Gregory Montoir", "cyx", ""); + add_person("Gregory Montoir", "cyx", "(retired)"); add_person("Eugene Sandulenko", "sev", "FT INSANE, MM NES, MM C64, game detection, Herc/CGA"); add_person("Ludvig Strigeus", "ludde", "(retired)"); end_section(); @@ -492,7 +492,7 @@ begin_credits("Credits"); begin_section("HE"); add_person("Jonathan Gray", "khalek", "(retired)"); add_person("Travis Howell", "Kirben", ""); - add_person("Gregory Montoir", "cyx", ""); + add_person("Gregory Montoir", "cyx", "(retired)"); add_person("Eugene Sandulenko", "sev", ""); end_section(); @@ -523,7 +523,7 @@ begin_credits("Credits"); begin_section("Cine"); add_person("Vincent Hamm", "yaz0r", "(retired)"); add_person("Paweł Kołodziejski", "aquadran", ""); - add_person("Gregory Montoir", "cyx", ""); + add_person("Gregory Montoir", "cyx", "(retired)"); add_person("Kari Salminen", "Buddha^", ""); add_person("Eugene Sandulenko", "sev", ""); end_section(); @@ -576,7 +576,7 @@ begin_credits("Credits"); add_person("Torbjörn Andersson", "eriktorbjorn", "VQA Player"); add_person("Oystein Eftevaag", "vinterstum", ""); add_person("Florian Kagerer", "athrxx", ""); - add_person("Gregory Montoir", "cyx", ""); + add_person("Gregory Montoir", "cyx", "(retired)"); add_person("Johannes Schickel", "LordHoto", ""); end_section(); @@ -610,7 +610,7 @@ begin_credits("Credits"); begin_section("Queen"); add_person("David Eriksson", "twogood", "(retired)"); - add_person("Gregory Montoir", "cyx", ""); + add_person("Gregory Montoir", "cyx", "(retired)"); add_person("Joost Peters", "joostp", ""); end_section(); @@ -679,7 +679,7 @@ begin_credits("Credits"); end_section(); begin_section("Touché"); - add_person("Gregory Montoir", "cyx", ""); + add_person("Gregory Montoir", "cyx", "(retired)"); end_section(); begin_section("TsAGE"); @@ -688,7 +688,7 @@ begin_credits("Credits"); end_section(); begin_section("Tucker"); - add_person("Gregory Montoir", "cyx", ""); + add_person("Gregory Montoir", "cyx", "(retired)"); end_section(); end_section(); diff --git a/devtools/tasmrecover/dreamweb/sprite.asm b/devtools/tasmrecover/dreamweb/sprite.asm index 06b06c76e3..658484db11 100644 --- a/devtools/tasmrecover/dreamweb/sprite.asm +++ b/devtools/tasmrecover/dreamweb/sprite.asm @@ -244,7 +244,7 @@ Reelroutines db 1,44,0 ;Room number and x,y db 255 -Lenofreelrouts equ $-reelroutines +Lenofreelrouts equ 457 ; $-reelroutines Reelcalls dw gamer,sparkydrip,eden,edeninbath,sparky,smokebloke diff --git a/devtools/tasmrecover/tasm-recover b/devtools/tasmrecover/tasm-recover index ae0d4015ad..e7716acb34 100755 --- a/devtools/tasmrecover/tasm-recover +++ b/devtools/tasmrecover/tasm-recover @@ -46,13 +46,22 @@ p = parser(skip_binary_data = [ 'spritename1', 'icongraphics0', 'icongraphics1', + 'savenames', + 'volumetabname', + 'commandline', + 'openchangesize', # keypad.asm 'keypadlist', 'symbollist', + 'diarylist', + # monitor.asm + 'comlist', + 'keys', # newplace.asm 'destlist', # object.asm - 'invlist1', 'invlist1continued', + 'invlist1', + 'invlist1continued', 'examlist', 'withlist1', # saveload.asm @@ -71,9 +80,15 @@ p = parser(skip_binary_data = [ 'gameinfo', 'endgametext1', 'savefiles', + 'decidelist', + 'discopslist', + 'opslist', # sblaster.asm 'dmaaddresses', + 'speechfilename', + 'speechfile', # sprite.asm + 'reelroutines', 'reelcalls', 'facelist', 'rainlocations', @@ -81,6 +96,9 @@ p = parser(skip_binary_data = [ 'r0','r1','r2','r6','r8','r9','r10','r11','r12','r13','r14', 'r20','r22','r23','r25','r26','r27','r28','r29', 'r45','r46','r47','r52','r53','r55', + #talk.asm + 'talklist', + 'quitlist', # titles.asm 'introtextname', 'title0graphics', @@ -92,11 +110,67 @@ p = parser(skip_binary_data = [ 'title6graphics', # use.asm 'uselist', + 'money1poke', + 'money2poke', # vars.asm 'currentset', 'icons1', 'icons2', 'tempcharset', + 'currentframe', + 'takeoff', + 'reelpointer', + 'needsoundbuff', + 'oldint8seg', + 'oldint8add', + 'oldint9seg', + 'oldint9add', + 'soundbuffer', + 'soundbufferad', + 'soundbufferpage', + 'soundtimes', + 'oldsoundintseg', + 'oldsoundintadd', + 'soundbaseadd', + 'dsp_status', + 'dsp_write', + 'dmaaddress', + 'soundint', + 'sounddmachannel', + 'sampleplaying', + 'testresult', + 'currentirq', + 'gameerror', + 'howmuchalloc', + 'inputport', + 'emmhandle', + 'emmpageframe', + 'emmhardwarepage', + 'ch0emmpage', + 'ch0offset', + 'ch0oldemmpage', + 'ch0oldoffset', + 'ch0oldblockstocopy', + 'ch1emmpage', + 'ch1offset', + 'ch1blocksplayed', + 'soundemmpage', + 'speechemmpage', + 'lineroutine', + 'increment1', + 'increment2', + 'keypadax', + 'keypadcx', + 'soundbuffer', + 'cursloc', + 'liftsoundcount', + 'playblock', + 'gotfrom', + 'flagx', + 'flagy', + 'lastflagex', + 'keynum', + 'newlogonum', # vgagrafx.asm 'cityname', 'extragraphics1', @@ -116,6 +190,7 @@ p = parser(skip_binary_data = [ 'puzzletextname', 'commandtextname', 'characterset2', + 'characterset3', 'monitorfile1', 'monitorfile2', 'monitorfile10', @@ -131,7 +206,14 @@ p = parser(skip_binary_data = [ 'palettescreen', 'idname', 'samplename', + 'diarygraphic', + 'diarytext', + 'title7graphics', + 'handle', # 'basicsample', # This can't be removed due to tasm-recover limitations + 'endtextname', + 'gungraphic', + 'monkface', ]) p.strip_path = 3 context = p.parse('dreamweb/dreamweb.asm') @@ -145,24 +227,34 @@ generator = cpp(context, "DreamGen", blacklist = [ 'actualload', 'actualsave', 'addalong', + 'additionaltext', 'addlength', 'addtopeoplelist', 'addtopresslist', + 'adjustdown', + 'adjustleft', 'adjustlen', + 'adjustright', + 'adjustup', + 'advisor', 'afterintroroom', + 'afternewroom', 'aide', 'alleybarksound', 'allocatebuffers', 'allocateload', 'allocatemem', 'allocatework', + 'allpalette', 'allpointer', 'animpointer', 'atmospheres', 'attendant', + 'autoappear', 'autolook', 'autosetwalk', 'backobject', + 'bartender', 'barwoman', 'biblequote', 'blank', @@ -171,6 +263,7 @@ generator = cpp(context, "DreamGen", blacklist = [ 'bossman', 'bothchannels', 'bresenhams', + 'businessman', 'buttoneight', 'buttonenter', 'buttonfive', @@ -193,6 +286,7 @@ generator = cpp(context, "DreamGen", blacklist = [ 'candles', 'candles1', 'candles2', + 'cantdrop', 'carparkdrip', 'channel0only', 'channel0tran', @@ -201,16 +295,22 @@ generator = cpp(context, "DreamGen", blacklist = [ 'checkcoords', 'checkdest', 'checkforemm', + 'checkforexit', + 'checkforshake', 'checkifex', 'checkiffree', 'checkifpathison', 'checkifperson', 'checkifset', + 'checkinput', + 'checkinside', 'checkone', 'checksoundint', 'checkspeed', 'chewy', 'clearbeforeload', + 'clearbuffers', + 'clearchanges', 'clearendpal', 'clearpalette', 'clearreels', @@ -227,41 +327,57 @@ generator = cpp(context, "DreamGen", blacklist = [ 'convertkey', 'convicons', 'convnum', + 'copper', 'copyname', 'createfile', + 'createname', 'createpanel', 'createpanel2', 'credits', 'crosshair', 'dealwithspecial', 'deallocatemem', + 'decide', 'delchar', 'delcurs', + 'deleteexframe', + 'deleteextext', + 'deleteexobject', 'deletetaken', 'deleverything', 'delpointer', 'delsprite', 'deltextline', 'delthisone', + 'describeob', 'destselect', + 'diarykeyp', + 'diarykeyn', 'disablepath', 'disablesoundint', + 'discops', 'dmaend', 'doblocks', 'dochange', 'dodoor', + 'dofade', 'doload', 'dolook', 'domix', 'dontloadseg', 'doorway', + 'dosaveload', 'dosreturn', 'doshake', 'drawflags', 'drawfloor', + 'drawitall', 'drinker', + 'droperror', 'drunk', 'dumpblink', + 'dumpcurrent', + 'dumpdiarykeys', 'dumpeverything', 'dumpkeypad', 'dumpmap', @@ -277,26 +393,34 @@ generator = cpp(context, "DreamGen", blacklist = [ 'edeninbath', 'edenscdplayer', 'enablesoundint', + 'endgame', + 'endgameseq', 'endpaltostart', 'entercode', 'entersymbol', + 'entryanims', + 'entrytexts', 'eraseoldobs', 'error', 'errormessage1', 'errormessage2', 'errormessage3', 'examicon', - 'examineinventory', + 'examinventory', 'examineob', 'examineobtext', + 'execcommand', 'facerightway', 'fadecalculation', 'fadedos', + 'fadefromwhite', 'fadescreenup', 'fadescreenups', 'fadescreenuphalf', 'fadescreendown', 'fadescreendowns', + 'fadescreendownhalf', + 'fadetowhite', 'fadeupmonfirst', 'fadeupyellows', 'femalefan', @@ -304,12 +428,17 @@ generator = cpp(context, "DreamGen", blacklist = [ 'fillspace', 'finalframe', 'findallryan', + 'findexobject', + 'findinvpos', 'findlen', 'findnextcolon', 'findobname', 'findormake', + 'findpuztext', 'findroominloc', + 'findsetobject', 'findsource', + 'findtext1', 'findxyfrompath', 'finishedwalking', 'folderexit', @@ -323,6 +452,7 @@ generator = cpp(context, "DreamGen", blacklist = [ 'gates', 'generalerror', 'getanyaddir', + 'getback1', 'getbackfromob', 'getbackfromops', 'getbacktoops', @@ -330,10 +460,13 @@ generator = cpp(context, "DreamGen", blacklist = [ 'getdimension', 'getexpos', 'getflagunderp', + 'getkeyandlogo', 'getlocation', 'getmapad', + 'getnamepos', 'getnextword', 'getnumber', + 'getopenedsize', 'getpersframe', 'getreelframeax', 'getreelstart', @@ -350,25 +483,33 @@ generator = cpp(context, "DreamGen", blacklist = [ 'getroomspaths', 'gettime', 'gettingshot', + 'getundercentre', 'getundermenu', 'getundertimed', + 'getunderzoom', 'getxad', 'getyad', 'grafittidoor', + 'greyscalesum', 'handclap', 'hangon', 'hangoncurs', 'hangone', 'hangonp', + 'hangonpq', 'hangonw', + 'heavy', + 'helicopter', 'hotelbell', 'hotelcontrol', + 'identifyob', 'initialinv', 'initman', 'initrain', 'input', 'interupttest', 'interviewer', + 'intoinv', 'intro', 'intro1text', 'intro2text', @@ -376,11 +517,14 @@ generator = cpp(context, "DreamGen", blacklist = [ 'intromagic1', 'intromagic2', 'intromagic3', + 'intromonks1', + 'intromonks2', 'intromusic', 'inventory', 'isitdescribed', 'isitright', 'isitworn', + 'isryanholding', 'issetobonmap', 'keeper', 'kernchars', @@ -414,18 +558,25 @@ generator = cpp(context, "DreamGen", blacklist = [ 'loadtemptext', 'loadtraveltext', 'lockeddoorway', + 'locklightoff', + 'locklighton', 'lockmon', 'look', + 'lookatcard', + 'lookatplace', + 'lookininterface', 'loopchannel0', 'louis', 'louischair', 'madman', + 'madmanrun', 'madmanstelly', 'madmantext', 'madmode', 'mainman', 'mainscreen', 'makebackob', + 'makecaps', 'makeheader', 'makemainscreen', 'makename', @@ -437,24 +588,32 @@ generator = cpp(context, "DreamGen", blacklist = [ 'manasleep2', 'mansatstill', 'maptopanel', + 'middlepanel', 'mode640x480', 'modifychar', + 'moneypoke', + 'monitorlogo', 'monkandryan', 'monks2text', + 'monkspeaking', 'monmessage', 'monprint', 'moretalk', 'mousecall', 'movemap', + 'mugger', 'multidump', 'multiget', 'multiput', 'namestoold', 'neterror', 'newgame', + 'newplace', + 'nextcolon', 'nextdest', 'nextfolder', 'nextsymbol', + 'nothelderror', 'obicons', 'obname', 'obpicture', @@ -471,6 +630,7 @@ generator = cpp(context, "DreamGen", blacklist = [ 'openhoteldoor2', 'openinv', 'openlouis', + 'openob', 'openpoolboss', 'openryan', 'opensarters', @@ -479,6 +639,7 @@ generator = cpp(context, "DreamGen", blacklist = [ 'openyourneighbour', 'othersmoker', 'out22c', + 'outofinv', 'paltoendpal', 'paltostartpal', 'panelicons1', @@ -488,11 +649,13 @@ generator = cpp(context, "DreamGen", blacklist = [ 'pickupob', 'pitinterupt', 'pixelcheckset', + 'placefreeobject', 'placesetobject', 'playchannel0', 'playchannel1', 'playguitar', 'plotreel', + 'poolguard', 'powerlightoff', 'powerlighton', 'priest', @@ -504,14 +667,21 @@ generator = cpp(context, "DreamGen", blacklist = [ 'printdirect', 'printlogo', 'printmessage', + 'printmessage2', + 'printoutermon', 'printslow', 'printsprites', 'printundermon', + 'processtrigger', 'putbackobstuff', + 'putundercentre', 'putundermenu', 'putundertimed', + 'putunderzoom', 'quickquit', 'quickquit2', + 'quitkey', + 'quitsymbol', 'random', 'randomaccess', 'randomnum1', @@ -531,19 +701,26 @@ generator = cpp(context, "DreamGen", blacklist = [ 'readoneblock', 'readsetdata', 'realcredits', + 'receptionist', 'reconstruct', 'redes', 'redrawmainscrn', 'reelsonscreen', 'reexfromopen', 'removeemm', + 'removefreeobject', 'removesetobject', + 'removeobfrominv', 'resetkeyboard', 'restoreall', 'restoreems', 'restorereels', 'rockstar', + 'rollendcredits', + 'rollendcredits2', 'roomname', + 'runendseq', + 'runtap', 'runintroseq', 'saveems', 'savefileread', @@ -558,6 +735,8 @@ generator = cpp(context, "DreamGen", blacklist = [ 'security', 'seecommandtail', 'selectlocation', + 'selectob', + 'selectslot', 'selectslot2', 'set16colpalette', 'setallchanges', @@ -567,20 +746,27 @@ generator = cpp(context, "DreamGen", blacklist = [ 'setlocation', 'setmode', 'setmouse', + 'setpickup', 'setsoundoff', 'settopleft', 'settopright', 'setupemm', 'setuppit', 'setuptimedtemp', + 'setuptimeduse', 'setwalk', 'showallex', 'showallfree', 'showallobs', + 'showarrows', 'showblink', 'showbyte', 'showcity', 'showcurrentfile', + 'showdecisions', + 'showdiary', + 'showdiarykeys', + 'showdiarypage', 'showdiscops', 'showexit', 'showfirstuse', @@ -588,26 +774,36 @@ generator = cpp(context, "DreamGen", blacklist = [ 'showframe', 'showgamereel', 'showgroup', + 'showgun', 'showicon', 'showkeypad', + 'showkeys', 'showleftpage', + 'showloadops', 'showmainops', 'showman', 'showmenu', + 'showmonk', + 'shownames', + 'showopbox', 'showoutermenu', 'showouterpad', 'showpanel', 'showpcx', 'showpointer', + 'showpuztext', 'showrain', 'showreelframe', 'showrightpage', 'showryanpage', + 'showsaveops', 'showseconduse', + 'showslots', 'showsymbol', 'showtime', 'showwatch', 'showword', + 'signon', 'singlekey', 'sitdowninbar', 'slabdoora', @@ -618,6 +814,7 @@ generator = cpp(context, "DreamGen", blacklist = [ 'slabdoorf', 'smallcandle', 'smokebloke', + 'soldier1', 'sortoutmap', 'soundend', 'soundonreels', @@ -636,6 +833,7 @@ generator = cpp(context, "DreamGen", blacklist = [ 'storeit', 'switchryanoff', 'switchryanon', + 'talk', 'tattooman', 'textforend', 'textformonk', @@ -644,6 +842,7 @@ generator = cpp(context, "DreamGen", blacklist = [ 'transferinv', 'transfertext', 'trapdoor', + 'triggermessage', 'trysoundalloc', 'turnanypathoff', 'turnanypathon', @@ -651,17 +850,27 @@ generator = cpp(context, "DreamGen", blacklist = [ 'turnpathoff', 'turnpathon', 'twodigitnum', + 'undertextline', 'updatepeople', + 'updatesymboltop', + 'updatesymbolbot', + 'usealtar', + 'useaxe', 'usebalcony', + 'usebuttona', 'usecardreader1', 'usecardreader2', 'usecardreader3', 'usecart', + 'usecashcard', 'usecharset1', 'usechurchgate', 'usechurchhole', 'useclearbox', + 'usecontrol', + 'usecooker', 'usecoveredbox', + 'usediary', 'usedryer', 'useelevator1', 'useelevator2', @@ -670,19 +879,27 @@ generator = cpp(context, "DreamGen", blacklist = [ 'useelevator5', 'useelvdoor', 'usefullcart', + 'usegun', + 'usehandle', 'usehole', + 'usekey', 'useladder', 'useladderb', + 'uselighter', 'usehatch', 'usemenu', 'usemon', 'useobject', + 'useopenbox', + 'usepipe', 'useplate', 'useplinth', 'usepoolreader', 'userailing', 'useroutine', 'useshield', + 'useslab', + 'usestereo', 'usetempcharset', 'usetext', 'usetimedtext', @@ -690,6 +907,7 @@ generator = cpp(context, "DreamGen", blacklist = [ 'usewall', 'usewinch', 'usewindow', + 'usewire', 'viewfolder', 'vsync', 'volumeadjust', @@ -699,11 +917,14 @@ generator = cpp(context, "DreamGen", blacklist = [ 'walkintoroom', 'walktotext', 'watchcount', + 'watchreel', 'wearwatch', 'wearshades', 'wheelsound', 'widedoor', 'width160', + 'withwhat', + 'workoutframes', 'worktoscreen', 'worktoscreenm', 'wornerror', @@ -717,748 +938,742 @@ generator = cpp(context, "DreamGen", blacklist = [ header_omit_blacklisted = True, function_name_remapping = { # This remaps the function naming at output for readability + 'aboutturn' : 'aboutTurn', + 'accesslightoff' : 'accessLightOff', + 'accesslighton' : 'accessLightOn', + 'actualload' : 'actualLoad', + 'actualsave' : 'actualSave', + 'addalong' : 'addAlong', + 'additionaltext' : 'additionalText', + 'addlength' : 'addLength', + 'addtopeoplelist' : 'addToPeopleList', + 'addtopresslist' : 'addToPressList', + 'adjustdown' : 'adjustDown', + 'adjustleft' : 'adjustLeft', + 'adjustlen' : 'adjustLen', + 'adjustright' : 'adjustRight', + 'adjustup' : 'adjustUp', + 'advisor' : 'advisor', + 'afterintroroom' : 'afterIntroRoom', + 'afternewroom' : 'afterNewRoom', + 'aide' : 'aide', + 'alleybarksound' : 'alleyBarkSound', + 'allocatebuffers' : 'allocateBuffers', + 'allocateload' : 'allocateLoad', + 'allocatemem' : 'allocateMem', + 'allocatework' : 'allocateWork', + 'allpointer' : 'allPointer', + 'animpointer' : 'animPointer', + 'atmospheres' : 'atmospheres', + 'attendant' : 'attendant', + 'autoappear' : 'autoAppear', + 'autolook' : 'autoLook', + 'autosetwalk' : 'autoSetWalk', + 'backobject' : 'backObject', + 'bartender' : 'bartender', + 'barwoman' : 'barWoman', + 'biblequote' : 'bibleQuote', + 'blank' : 'blank', + 'blockget' : 'blockGet', + 'blocknametext' : 'blockNameText', + 'bossman' : 'bossMan', 'bothchannels' : 'bothChannels', - 'usewire' : 'useWire', - 'getnamepos' : 'getNamePos', - 'loadtemptext' : 'loadTempText', - 'femalefan' : 'femaleFan', - 'identifyob' : 'identifyOb', - 'trysoundalloc' : 'trySoundAlloc', - 'uselighter' : 'useLighter', - 'showmenu' : 'showMenu', - 'usepoolreader' : 'usePoolReader', - 'startdmablock' : 'startDMABlock', - 'useopenbox' : 'useOpenBox', - 'clearbuffers' : 'clearBuffers', - 'channel0only' : 'channel0only', - 'worktoscreenm' : 'workToScreenM', - 'removeemm' : 'removeEMM', - 'getobtextstart' : 'getObTextStart', - 'dumpdiarykeys' : 'dumpDiaryKeys', - 'getridofreels' : 'getRidOfReels', - 'readkey' : 'readKey', - 'louis' : 'louis', - 'entrytexts' : 'entryTexts', + 'businessman' : 'businessMan', + 'buttoneight' : 'buttonEight', 'buttonenter' : 'buttonEnter', - 'checkinput' : 'checkInput', - 'setmode' : 'setMode', - 'getbackfromops' : 'getBackFromOps', - 'opensarters' : 'openSarters', - 'putundercentre' : 'putUnderCentre', - 'checkobjectsize' : 'checkObjectSize', - 'titles' : 'titles', - 'deallocatemem' : 'deallocateMem', - 'mainscreen' : 'mainScreen', - 'watchreel' : 'watchReel', - 'showslots' : 'showSlots', - 'openfilefromc' : 'openFileFromC', - 'gettime' : 'getTime', - 'loadtraveltext' : 'loadTravelText', - 'drawfloor' : 'drawFloor', - 'loadkeypad' : 'loadKeypad', - 'findtext1' : 'findText1', - 'isryanholding' : 'isRyanHolding', - 'interupttest' : 'interruptTest', - 'usecashcard' : 'useCashCard', - 'usewall' : 'useWall', - 'opentomb' : 'openTomb', + 'buttonfive' : 'buttonFive', 'buttonfour' : 'buttonFour', - 'dosometalk' : 'doSomeTalk', - 'getanyaddir' : 'getAnyAdDir', - 'showsaveops' : 'showSaveOps', - 'intromonks1' : 'introMonks1', - 'resetlocation' : 'resetLocation', - 'intromonks2' : 'introMonks2', - 'advisor' : 'advisor', - 'additionaltext' : 'additionalText', - 'othersmoker' : 'otherSmoker', - 'dofade' : 'doFade', - 'useelevator5' : 'useElevator5', - 'useelevator4' : 'useElevator4', - 'useelevator1' : 'useElevator1', - 'useelevator3' : 'useElevator3', - 'useelevator2' : 'useElevator2', + 'buttonnine' : 'buttonNine', + 'buttonnought' : 'buttonNought', 'buttonone' : 'buttonOne', - 'keyboardread' : 'keyboardRead', - 'entercode' : 'enterCode', - 'getopenedsize' : 'getOpenedSize', - 'doshake' : 'doShake', - 'resetkeyboard' : 'resetKeyboard', - 'soundstartup' : 'soundStartup', - 'slabdoora' : 'sLabDoorA', - 'slabdoorc' : 'sLabDoorC', - 'slabdoorb' : 'sLabDoorB', - 'slabdoore' : 'sLabDoorE', - 'slabdoord' : 'sLabDoorD', - 'adjustup' : 'adjustUp', - 'slabdoorf' : 'sLabDoorF', - 'loadintroroom' : 'loadIntroRoom', - 'mousecall' : 'mouseCall', - 'train' : 'train', - 'fadedownmon' : 'fadeDownMon', - 'loadcart' : 'loadCart', - 'bartender' : 'bartender', - 'eden' : 'eden', - 'showdiary' : 'showDiary', - 'outofopen' : 'outOfOpen', - 'dircom' : 'dirCom', - 'dumpkeypad' : 'dumpKeypad', - 'showsymbol' : 'showSymbol', - 'endgameseq' : 'endGameSeq', - 'setbotleft' : 'setBotLeft', - 'findfirstpath' : 'findFirstPath', - 'loadold' : 'loadOld', - 'useslab' : 'useSLab', - 'dumpzoom' : 'dumpZoom', - 'usealtar' : 'useAltar', - 'manasleep2' : 'manAsleep2', - 'moretalk' : 'moreTalk', - 'starttalk' : 'startTalk', - 'delchar' : 'delChar', - 'getanyad' : 'getAnyAd', - 'endgame' : 'endGame', - 'usepipe' : 'usePipe', - 'getunderzoom' : 'getUnderZoom', - 'candles' : 'candles', - 'backobject' : 'backObject', - 'rollendcredits2' : 'rollEndCredits2', - 'reminders' : 'reminders', - 'selectslot2' : 'selectSlot2', - 'runtap' : 'runTap', - 'talk' : 'talk', - 'getridoftemp2' : 'getRidOfTemp2', - 'usebalcony' : 'useBalcony', - 'runendseq' : 'runEndSeq', - 'decide' : 'decide', - 'disablesoundint' : 'disableSoundInt', - 'priesttext' : 'priestText', - 'openpoolboss' : 'openPoolBoss', + 'buttonpress' : 'buttonPress', + 'buttonseven' : 'buttonSeven', + 'buttonsix' : 'buttonSix', + 'buttonthree' : 'buttonThree', 'buttontwo' : 'buttonTwo', - 'fadescreendownhalf' : 'fadeScreenDownHalf', - 'useplate' : 'usePlate', - 'candles1' : 'candles1', - 'lookininterface' : 'lookInInterface', - 'manasleep' : 'manAsleep', - 'hotelbell' : 'hotelBell', - 'loadspeech' : 'loadSpeech', - 'adjustleft' : 'adjustLeft', + 'calcfrframe' : 'calcFrFrame', + 'calcmapad' : 'calcMapAd', + 'calledensdlift' : 'callEdensDLift', 'calledenslift' : 'callEdensLift', - 'useclearbox' : 'useClearBox', - 'entryanims' : 'entryAnims', - 'getfreead' : 'getFreeAd', - 'showarrows' : 'showArrows', - 'walkintoroom' : 'walkIntoRoom', - 'usehatch' : 'useHatch', - 'printoutermon' : 'printOuterMon', - 'setuppit' : 'setupPit', - 'showpcx' : 'showPCX', - 'showdecisions' : 'showDecisions', + 'callhotellift' : 'callHotelLift', + 'cancelch0' : 'cancelCh0', + 'cancelch1' : 'cancelCh1', + 'candles' : 'candles', + 'candles1' : 'candles1', + 'candles2' : 'candles2', + 'cantdrop' : 'cantDrop', + 'carparkdrip' : 'carParkDrip', + 'channel0only' : 'channel0only', + 'channel0tran' : 'channel0Tran', + 'channel1only' : 'channel1only', + 'checkbasemem' : 'checkBaseMem', + 'checkcoords' : 'checkCoords', + 'checkdest' : 'checkDest', + 'checkforemm' : 'checkForEMM', + 'checkforexit' : 'checkForExit', + 'checkforshake' : 'checkForShake', + 'checkifex' : 'checkIfEx', + 'checkiffree' : 'checkIfFree', + 'checkifpathison' : 'checkIfPathIsOn', + 'checkifperson' : 'checkIfPerson', + 'checkifset' : 'checkIfSet', + 'checkinput' : 'checkInput', + 'checkinside' : 'checkInside', + 'checkobjectsize' : 'checkObjectSize', + 'checkone' : 'checkOne', + 'checksoundint' : 'checkSoundInt', 'checkspeed' : 'checkSpeed', - 'showkeypad' : 'showKeypad', - 'removeobfrominv' : 'removeObFromInv', - 'usecoveredbox' : 'useCoveredBox', - 'openyourneighbour' : 'openYourNeighbour', - 'fadescreenuphalf' : 'fadeScreenUpHalf', - 'getridoftempcharset' : 'getRidOfTempCharset', - 'heavy' : 'heavy', - 'usekey' : 'useKey', - 'locklighton' : 'lockLightOn', - 'useladderb' : 'useLadderB', - 'discops' : 'discOps', - 'middlepanel' : 'middlePanel', - 'monitorlogo' : 'monitorLogo', - 'entersymbol' : 'enterSymbol', - 'dirfile' : 'dirFile', - 'pickupconts' : 'pickupConts', - 'locklightoff' : 'lockLightOff', - 'wearwatch' : 'wearWatch', - 'runintroseq' : 'runIntroSeq', - 'nextcolon' : 'nextColon', - 'attendant' : 'attendant', - 'nextsymbol' : 'nextSymbol', - 'monks2text' : 'monks2text', + 'chewy' : 'chewy', + 'clearbeforeload' : 'clearBeforeLoad', + 'clearbuffers' : 'clearBuffers', + 'clearchanges' : 'clearChanges', + 'clearendpal' : 'clearEndPal', 'clearpalette' : 'clearPalette', - 'cantdrop' : 'cantDrop', - 'getridofall' : 'getRidOfAll', + 'clearreels' : 'clearReels', + 'clearrest' : 'clearRest', + 'clearsprites' : 'clearSprites', + 'clearstartpal' : 'clearStartPal', + 'clearwork' : 'clearWork', + 'closefile' : 'closeFile', + 'commandonly' : 'commandOnly', + 'commandwithob' : 'commandWithOb', + 'constant' : 'constant', + 'convertkey' : 'convertKey', + 'convicons' : 'convIcons', + 'convnum' : 'convNum', 'copper' : 'copper', - 'openhoteldoor' : 'openHotelDoor', - 'blank' : 'blank', + 'copyname' : 'copyName', + 'createfile' : 'createFile', + 'createname' : 'createName', + 'createpanel' : 'createPanel', + 'createpanel2' : 'createPanel2', + 'credits' : 'credits', + 'crosshair' : 'crossHair', + 'deallocatemem' : 'deallocateMem', + 'dealwithspecial' : 'dealWithSpecial', + 'decide' : 'decide', + 'delchar' : 'delChar', + 'delcurs' : 'delCurs', + 'deleteexframe' : 'deleteExFrame', + 'deleteexobject' : 'deleteExObject', + 'deleteextext' : 'deleteExText', + 'deletetaken' : 'deleteTaken', + 'deleverything' : 'delEverything', + 'delpointer' : 'delPointer', + 'delsprite' : 'delSprite', + 'deltextline' : 'delTextLine', + 'delthisone' : 'delThisOne', + 'describeob' : 'describeOb', + 'destselect' : 'destSelect', + 'diarykeyn' : 'diaryKeyN', + 'diarykeyp' : 'diaryKeyP', + 'dircom' : 'dirCom', + 'dirfile' : 'dirFile', + 'disablepath' : 'disablePath', + 'disablesoundint' : 'disableSoundInt', + 'discops' : 'discOps', + 'dmaend' : 'DMAEnd', + 'doblocks' : 'doBlocks', + 'dochange' : 'doChange', + 'dodoor' : 'doDoor', + 'doload' : 'doLoad', + 'dolook' : 'doLook', + 'domix' : 'doMix', + 'dontloadseg' : 'dontLoadSeg', + 'dosaveload' : 'doSaveLoad', + 'doshake' : 'doShake', + 'dosometalk' : 'doSomeTalk', + 'dosreturn' : 'DOSReturn', + 'drawflags' : 'drawFlags', + 'drawfloor' : 'drawFloor', + 'drawitall' : 'drawItAll', + 'dreamweb' : 'dreamweb', 'drinker' : 'drinker', - 'placefreeobject' : 'placeFreeObject', - 'allpalette' : 'allPalette', - 'rockstar' : 'rockstar', - 'adjustright' : 'adjustRight', - 'putunderzoom' : 'putUnderZoom', - 'vsync' : 'vSync', - 'findinvpos' : 'findInvPos', + 'droperror' : 'dropError', + 'dropobject' : 'dropObject', + 'drunk' : 'drunk', + 'dumpblink' : 'dumpBlink', + 'dumpdiarykeys' : 'dumpDiaryKeys', + 'dumpeverything' : 'dumpEverything', + 'dumpkeypad' : 'dumpKeypad', + 'dumpmap' : 'dumpMap', 'dumpmenu' : 'dumpMenu', - 'liftnoise' : 'liftNoise', - 'workoutframes' : 'workoutFrames', - 'dumpsymbox' : 'dumpSymBox', - 'loadgame' : 'loadGame', - 'getridoftemp' : 'getRidOfTemp', + 'dumppointer' : 'dumpPointer', 'dumpsymbol' : 'dumpSymbol', - 'buttonsix' : 'buttonSix', - 'intro2text' : 'intro2Text', - 'showouterpad' : 'showOuterPad', - 'getkeyandlogo' : 'getKeyAndLogo', - 'selectob' : 'selectOb', - 'useplinth' : 'usePlinth', - 'usecooker' : 'useCooker', - 'loadmenu' : 'loadMenu', - 'checkforemm' : 'checkForEMM', - 'receptionist' : 'receptionist', - 'selectslot' : 'selectSlot', - 'openfilenocheck' : 'openFileNoCheck', - 'fadeupmon' : 'fadeUpMon', - 'fadetowhite' : 'fadeToWhite', - 'loadsavebox' : 'loadSaveBox', - 'soundend' : 'soundEnd', - 'redes' : 'redes', + 'dumpsymbox' : 'dumpSymBox', + 'dumptextline' : 'dumpTextLine', + 'dumptimedtext' : 'dumpTimedText', + 'dumpwatch' : 'dumpWatch', + 'dumpzoom' : 'dumpZoom', + 'eden' : 'eden', + 'edeninbath' : 'edenInBath', + 'edenscdplayer' : 'edensCDPlayer', + 'emergencypurge' : 'emergencyPurge', + 'enablesoundint' : 'enableSoundInt', + 'endgame' : 'endGame', + 'endgameseq' : 'endGameSeq', + 'endpaltostart' : 'endPalToStart', + 'entercode' : 'enterCode', + 'entersymbol' : 'enterSymbol', + 'entryanims' : 'entryAnims', + 'entrytexts' : 'entryTexts', + 'eraseoldobs' : 'eraseOldObs', + 'error' : 'error', 'errormessage1' : 'errorMessage1', 'errormessage2' : 'errorMessage2', 'errormessage3' : 'errorMessage3', - 'intromagic2' : 'introMagic2', - 'intromagic3' : 'introMagic3', - 'edeninbath' : 'edenInBath', - 'intromagic1' : 'introMagic1', - 'showdiarypage' : 'showDiaryPage', - 'useshield' : 'useShield', - 'getbacktoops' : 'getBackToOps', - 'rollendcredits' : 'rollEndCredits', - 'intro1text' : 'intro1Text', - 'transfertoex' : 'transferToEx', - 'steady' : 'steady', - 'reexfrominv' : 'reExFromInv', + 'examicon' : 'examIcon', + 'examineob' : 'examineOb', + 'examineobtext' : 'examineObText', 'examinventory' : 'examineInventory', - 'getridoftemp3' : 'getRidOfTemp3', - 'usedryer' : 'useDryer', - 'outofinv' : 'outOfInv', - 'diarykeyp' : 'diaryKeyP', - 'random' : 'random', - 'mainman' : 'mainMan', - 'mansatstill' : 'manSatStill', - 'channel1only' : 'channel1only', - 'transfermap' : 'transferMap', - 'showmonk' : 'showMonk', - 'diarykeyn' : 'diaryKeyN', - 'set16colpalette' : 'set16ColPalette', - 'sparky' : 'sparky', - 'interviewer' : 'interviewer', - 'purgeanitem' : 'purgeAnItem', - 'madman' : 'madman', - 'chewy' : 'chewy', - 'madmanstelly' : 'madmansTelly', - 'constant' : 'constant', - 'purgealocation' : 'purgeALocation', - 'sparkydrip' : 'sparkyDrip', - 'getridofpit' : 'getRidOfPit', - 'nothelderror' : 'notHeldError', - 'getsetad' : 'getSetAd', - 'soldier1' : 'soldier1', - 'getundercentre' : 'getUnderCentre', - 'checkforexit' : 'checkForExit', - 'loadseg' : 'loadSeg', - 'showkeys' : 'showKeys', - 'setkeyboardint' : 'setKeyboardInt', - 'priest' : 'priest', - 'printmessage2' : 'printmessage2', - 'loadnews' : 'loadNews', - 'rollem' : 'rollEm', - 'hangonpq' : 'hangOnPQ', - 'savegame' : 'saveGame', - 'findopenpos' : 'findOpenPos', - 'describeob' : 'describeOb', - 'deleteexframe' : 'deleteExFrame', - 'bossman' : 'bossMan', - 'dosreturn' : 'DOSReturn', - 'wheelsound' : 'wheelSound', - 'playguitar' : 'playGuitar', - 'searchforsame' : 'searchForSame', - 'enablesoundint' : 'enableSoundInt', - 'getback1' : 'getBack1', + 'execcommand' : 'execCommand', + 'facerightway' : 'faceRightWay', + 'fadecalculation' : 'fadeCalculation', + 'fadedownmon' : 'fadeDownMon', 'fadefromwhite' : 'fadeFromWhite', - 'usewindow' : 'useWindow', - 'wearshades' : 'wearShades', - 'pitinterupt' : 'pitInterrupt', - 'deleverything' : 'delEverything', 'fadescreendown' : 'fadeScreenDown', - 'poolguard' : 'poolGuard', - 'openinv' : 'openInv', - 'lookatplace' : 'lookAtPlace', - 'useaxe' : 'useAxe', - 'buttonnought' : 'buttonNought', - 'useelvdoor' : 'useElvDoor', - 'putbackobstuff' : 'putBackObStuff', - 'useladder' : 'useLadder', - 'realcredits' : 'realCredits', - 'handclap' : 'handClap', - 'smokebloke' : 'smokeBloke', - 'afterintroroom' : 'afterIntroRoom', - 'buttonnine' : 'buttonNine', + 'fadescreendownhalf' : 'fadeScreenDownHalf', + 'fadescreendowns' : 'fadeScreenDowns', + 'fadescreenup' : 'fadeScreenUp', + 'fadescreenuphalf' : 'fadeScreenUpHalf', + 'fadescreenups' : 'fadeScreenUps', + 'fadetowhite' : 'fadeToWhite', + 'fadeupmon' : 'fadeUpMon', + 'fadeupmonfirst' : 'fadeUpMonFirst', + 'fadeupyellows' : 'fadeUpYellows', + 'femalefan' : 'femaleFan', + 'fillopen' : 'fillOpen', + 'fillryan' : 'fillRyan', + 'fillspace' : 'fillSpace', + 'finalframe' : 'finalFrame', 'findallopen' : 'findAllOpen', - 'gamer' : 'gamer', - 'readfromfile' : 'readFromFile', - 'initialinv' : 'initialInv', - 'quitsymbol' : 'quitSymbol', - 'settopright' : 'setTopRight', + 'findallryan' : 'findAllRyan', + 'findexobject' : 'findExObject', + 'findfirstpath' : 'findFirstPath', + 'findinvpos' : 'findInvPos', + 'findlen' : 'findLen', + 'findnextcolon' : 'findNextColon', + 'findobname' : 'findObName', + 'findopenpos' : 'findOpenPos', + 'findormake' : 'findOrMake', + 'findpathofpoint' : 'findPathOfPoint', + 'findpuztext' : 'findPuzText', + 'findroominloc' : 'findRoomInLoc', 'findsetobject' : 'findSetObject', - 'singlekey' : 'singleKey', - 'hangone' : 'hangOne', - 'carparkdrip' : 'carParkDrip', - 'usediary' : 'useDiary', - 'deleteexobject' : 'deleteExObject', - 'moneypoke' : 'moneyPoke', - 'destselect' : 'destSelect', - 'restoreems' : 'restoreEMS', - 'lastdest' : 'lastDest', - 'removefreeobject' : 'removeFreeObject', - 'trapdoor' : 'trapDoor', - 'openlouis' : 'openLouis', - 'buttonthree' : 'buttonThree', - 'lookatcard' : 'lookAtCard', - 'helicopter' : 'helicopter', - 'setsoundoff' : 'setSoundOff', - 'setpickup' : 'setPickup', - 'dropobject' : 'dropObject', - 'isitright' : 'isItRight', - 'reexfromopen' : 'reExFromOpen', - 'drawitall' : 'drawItAll', - 'usestereo' : 'useStereo', - 'candles2' : 'candles2', - 'pickupob' : 'pickupOb', - 'error' : 'error', - 'showopbox' : 'showOpBox', - 'clearbeforeload' : 'clearBeforeLoad', - 'biblequote' : 'bibleQuote', - 'doload' : 'doLoad', - 'showexit' : 'showExit', - 'usetrainer' : 'useTrainer', - 'addtopresslist' : 'addToPressList', - 'dmaend' : 'DMAEnd', - 'dumpcurrent' : 'dumpCurrent', - 'showdiarykeys' : 'showDiaryKeys', - 'dontloadseg' : 'dontLoadSeg', - 'intro3text' : 'intro3Text', - 'allocatemem' : 'allocateMem', - 'useopened' : 'useOpened', - 'inventory' : 'inventory', - 'fillopen' : 'fillOpen', - 'signon' : 'signOn', - 'deleteextext' : 'deleteExText', + 'findsource' : 'findSource', + 'findtext1' : 'findText1', + 'findxyfrompath' : 'findXYFromPath', + 'finishedwalking' : 'finishedWalking', 'foghornsound' : 'foghornSound', - 'showloadops' : 'showLoadOps', - 'examicon' : 'examIcon', - 'showgun' : 'showGun', - 'louischair' : 'louisChair', - 'saveems' : 'saveEMS', - 'locationpic' : 'locationPic', - 'opentvdoor' : 'openTVDoor', - 'triggermessage' : 'triggerMessage', - 'smallcandle' : 'smallCandle', - 'swapwithopen' : 'swapWithOpen', - 'dreamweb' : 'dreamweb', - 'droperror' : 'dropError', - 'edenscdplayer' : 'edensCDPlayer', - 'calledensdlift' : 'callEdensDLift', - 'checkinside' : 'checkInside', + 'folderexit' : 'folderExit', + 'folderhints' : 'folderHints', + 'frameoutbh' : 'frameOutbh', + 'frameoutfx' : 'frameOutfx', + 'frameoutnm' : 'frameOutnm', + 'frameoutv' : 'frameOutV', + 'gamer' : 'gamer', 'gates' : 'gates', - 'newgame' : 'newGame', - 'setwalk' : 'setWalk', - 'findpathofpoint' : 'findPathOfPoint', - 'issetobonmap' : 'isSetObOnMap', + 'generalerror' : 'generalError', + 'getanyad' : 'getAnyAd', + 'getanyaddir' : 'getAnyAdDir', + 'getback1' : 'getBack1', + 'getbackfromob' : 'getBackFromOb', + 'getbackfromops' : 'getBackFromOps', + 'getbacktoops' : 'getBackToOps', + 'getblockofpixel' : 'getBlockOfPixel', 'getdestinfo' : 'getDestInfo', - 'drunk' : 'drunk', + 'getdimension' : 'getDimension', + 'geteitherad' : 'getEitherAd', + 'getexad' : 'getExAd', + 'getexpos' : 'getExPos', + 'getflagunderp' : 'getFlagUnderP', + 'getfreead' : 'getFreeAd', + 'getkeyandlogo' : 'getKeyAndLogo', + 'getlocation' : 'getLocation', + 'getmapad' : 'getMapAd', + 'getnamepos' : 'getNamePos', + 'getnextword' : 'getNextWord', + 'getnumber' : 'getNumber', + 'getobtextstart' : 'getObTextStart', + 'getopenedsize' : 'getOpenedSize', + 'getpersframe' : 'getPersFrame', + 'getpersontext' : 'getPersonText', + 'getreelframeax' : 'getReelFrameAX', + 'getreelstart' : 'getReelStart', + 'getridofall' : 'getRidOfAll', + 'getridofpit' : 'getRidOfPit', + 'getridofpitsetuppit' : 'getRidOfPitSetupPit', + 'getridofreels' : 'getRidOfReels', + 'getridoftemp' : 'getRidOfTemp', + 'getridoftemp2' : 'getRidOfTemp2', + 'getridoftemp3' : 'getRidOfTemp3', + 'getridoftempcharset' : 'getRidOfTempCharset', + 'getridoftempsp' : 'getRidOfTempsP', 'getridoftemptext' : 'getRidOfTempText', - 'setuptimeduse' : 'setupTimedUse', + 'getroomdata' : 'getRoomData', + 'getroomspaths' : 'getRoomsPaths', + 'getsetad' : 'getSetAd', + 'gettime' : 'getTime', + 'gettingshot' : 'gettingShot', + 'getundercentre' : 'getUnderCentre', + 'getundermenu' : 'getUnderMenu', + 'getundertimed' : 'getUnderTimed', + 'getunderzoom' : 'getUnderZoom', + 'getxad' : 'getXAd', + 'getyad' : 'getYAd', 'grafittidoor' : 'grafittiDoor', - 'nextdest' : 'nextDest', - 'makecaps' : 'makeCaps', - 'read' : 'read', - 'fadescreenups' : 'fadeScreenUps', + 'handclap' : 'handClap', + 'hangon' : 'hangOn', + 'hangoncurs' : 'hangOnCurs', + 'hangone' : 'hangOne', + 'hangonp' : 'hangOnP', + 'hangonpq' : 'hangOnPQ', + 'hangonw' : 'hangOnW', + 'heavy' : 'heavy', + 'helicopter' : 'helicopter', + 'hotelbell' : 'hotelBell', 'hotelcontrol' : 'hotelControl', - 'mugger' : 'mugger', - 'atmospheres' : 'atmospheres', - 'out22c' : 'out22c', - 'loadpersonal' : 'loadPersonal', - 'gettingshot' : 'gettingShot', - 'settopleft' : 'setTopLeft', - 'searchforstring' : 'searchForString', - 'selectopenob' : 'selectOpenOb', - 'security' : 'security', - 'buttonfive' : 'buttonFive', - 'soundonreels' : 'soundOnReels', - 'usegun' : 'useGun', - 'autoappear' : 'autoAppear', - 'openryan' : 'openRyan', - 'callhotellift' : 'callHotelLift', - 'showman' : 'showMan', - 'usefullcart' : 'useFullCart', - 'newplace' : 'newPlace', - 'loadsample' : 'loadSample', - 'usecardreader1' : 'useCardReader1', - 'usecardreader2' : 'useCardReader2', - 'usecardreader3' : 'useCardReader3', - 'tattooman' : 'tattooMan', - 'usehandle' : 'useHandle', - 'openfile' : 'openFile', - 'showpuztext' : 'showPuzText', + 'identifyob' : 'identifyOb', 'incryanpage' : 'incRyanPage', - 'greyscalesum' : 'greyscaleSum', - 'buttoneight' : 'buttonEight', - 'findexobject' : 'findExObject', - 'clearchanges' : 'clearChanges', - 'usechurchhole' : 'useChurchHole', - 'searchforfiles' : 'searchForFiles', - 'monkspeaking' : 'monkSpeaking', - 'clearrest' : 'clearRest', - 'barwoman' : 'barWoman', - 'credits' : 'credits', - 'madmanrun' : 'madmanRun', - 'randomnum1' : 'randomNum1', - 'keeper' : 'keeper', - 'afternewroom' : 'afterNewRoom', - 'getexad' : 'getExAd', - 'closefile' : 'closeFile', + 'initialinv' : 'initialInv', 'initialmoncols' : 'initialMonCols', - 'checkforshake' : 'checkForShake', - 'usebuttona' : 'useButtonA', - 'fadescreenup' : 'fadeScreenUp', - 'generalerror' : 'generalError', - 'mode640x480' : 'mode640x480', - 'openeden' : 'openEden', - 'execcommand' : 'execCommand', - 'obsthatdothings' : 'obsThatDoThings', - 'updatesymbolbot' : 'updateSymbolBot', - 'findpuztext' : 'findPuzText', - 'usechurchgate' : 'useChurchGate', - 'monkandryan' : 'monkAndRyan', - 'allocatebuffers' : 'allocateBuffers', - 'swapwithinv' : 'swapWithInv', - 'usecontrol' : 'useControl', - 'buttonseven' : 'buttonSeven', - 'redrawmainscrn' : 'redrawMainScrn', - 'showgroup' : 'showGroup', - 'buttonpress' : 'buttonPress', - 'makemainscreen' : 'makeMainScreen', - 'usewinch' : 'useWinch', - 'setbotright' : 'setBotRight', - 'setupemm' : 'setupEMM', - 'aide' : 'aide', - 'geteitherad' : 'getEitherAd', - 'zoomonoff' : 'zoomOnOff', - 'updatesymboltop' : 'updateSymbolTop', - 'allpointer' : 'allPointer', - 'checksoundint' : 'checkSoundInt', - 'clearreels' : 'clearReels', - 'malefan' : 'maleFan', - 'dosaveload' : 'doSaveLoad', - 'createname' : 'createName', - 'readcitypic' : 'readCityPic', - 'getpersontext' : 'getPersonText', + 'initman' : 'initMan', + 'initrain' : 'initRain', + 'interupttest' : 'interruptTest', + 'interviewer' : 'interviewer', 'intoinv' : 'inToInv', - 'parser' : 'parser', - 'setmouse' : 'setMouse', 'intro' : 'intro', - 'fadescreendowns' : 'fadeScreenDowns', - 'openhoteldoor2' : 'openHotelDoor2', - 'getridoftempsp' : 'getRidOfTempsP', - 'scanfornames' : 'scanForNames', - 'selectlocation' : 'selectLocation', - 'undertextline' : 'underTextLine', - 'sitdowninbar' : 'sitDownInBar', - 'shownames' : 'showNames', - 'savefileread' : 'saveFileRead', - 'emergencypurge' : 'emergencyPurge', - 'usemenu' : 'useMenu', - 'alleybarksound' : 'alleyBarkSound', - 'usecart' : 'useCart', + 'intro1text' : 'intro1Text', + 'intro2text' : 'intro2Text', + 'intro3text' : 'intro3Text', + 'intromagic1' : 'introMagic1', + 'intromagic2' : 'introMagic2', + 'intromagic3' : 'introMagic3', + 'intromonks1' : 'introMonks1', + 'intromonks2' : 'introMonks2', 'intromusic' : 'introMusic', - 'quitkey' : 'quitKey', - 'processtrigger' : 'processTrigger', - 'randomnum2' : 'randomNum2', - 'loadsecondsample' : 'loadSecondSample', - 'transfercontoex' : 'transferConToEx', - 'businessman' : 'businessMan', - 'panelicons1' : 'panelIcons1', - 'adjustdown' : 'adjustDown', - 'withwhat' : 'withWhat', - 'openob' : 'openOb', - 'createfile' : 'createFile', - 'userailing' : 'useRailing', - 'usehole' : 'useHole', - 'useobject' : 'useObject', - 'readdesticon' : 'readDestIcon', - 'randomnumber' : 'randomNumber', - 'screenupdate' : 'screenUpdate', - 'saveload' : 'saveLoad', - 'switchryanon' : 'switchRyanOn', - 'switchryanoff' : 'switchRyanOff', - 'quickquit' : 'quickQuit', - 'quickquit2' : 'quickQuit2', - 'seecommandtail' : 'seeCommandTail', - 'multiget' : 'multiGet', - 'multiput' : 'multiPut', - 'multidump' : 'multiDump', - 'frameoutnm' : 'frameOutnm', - 'frameoutbh' : 'frameOutbh', - 'frameoutfx' : 'frameOutfx', - 'clearwork' : 'clearWork', - 'printundermon' : 'printUnderMon', + 'inventory' : 'inventory', + 'isitdescribed' : 'isItDescribed', + 'isitright' : 'isItRight', + 'isitworn' : 'isItWorn', + 'isryanholding' : 'isRyanHolding', + 'issetobonmap' : 'isSetObOnMap', + 'keeper' : 'keeper', 'kernchars' : 'kernChars', - 'getnextword' : 'getNextWord', - 'getnumber' : 'getNumber', - 'dumptextline' : 'dumpTextLine', - 'printboth' : 'printBoth', - 'printchar' : 'printChar', - 'printdirect' : 'printDirect', - 'printslow' : 'printSlow', - 'printmessage' : 'printMessage', - 'usetimedtext' : 'useTimedText', - 'dumptimedtext' : 'dumpTimedText', - 'setuptimedtemp' : 'setupTimedTemp', - 'putundertimed' : 'putUnderTimed', - 'getundertimed' : 'getUnderTimed', - 'worktoscreen' : 'workToScreen', - 'convertkey' : 'convertKey', - 'readabyte' : 'readAByte', - 'readoneblock' : 'readOneBlock', - 'printsprites' : 'printSprites', - 'printasprite' : 'printASprite', - 'eraseoldobs' : 'eraseOldObs', - 'oldtonames' : 'oldToNames', - 'namestoold' : 'namesToOld', + 'keyboardread' : 'keyboardRead', + 'lastdest' : 'lastDest', + 'lastfolder' : 'lastFolder', + 'liftnoise' : 'liftNoise', + 'liftsprite' : 'liftSprite', + 'loadcart' : 'loadCart', + 'loadfolder' : 'loadFolder', + 'loadgame' : 'loadGame', + 'loadintotemp' : 'loadIntoTemp', + 'loadintotemp2' : 'loadIntoTemp2', + 'loadintotemp3' : 'loadIntoTemp3', + 'loadintroroom' : 'loadIntroRoom', + 'loadkeypad' : 'loadKeypad', + 'loadmenu' : 'loadMenu', + 'loadnews' : 'loadNews', + 'loadold' : 'loadOld', 'loadpalfromiff' : 'loadPalFromIFF', - 'clearsprites' : 'clearSprites', - 'makesprite' : 'makeSprite', - 'showframe' : 'showFrame', - 'initman' : 'initMan', - 'aboutturn' : 'aboutTurn', - 'readheader' : 'readHeader', - 'fillspace' : 'fillSpace', - 'getroomdata' : 'getRoomData', - 'startloading' : 'startLoading', - 'showreelframe' : 'showReelFrame', - 'showgamereel' : 'showGameReel', - 'getreelframeax' : 'getReelFrameAX', - 'findsource' : 'findSource', - 'autosetwalk' : 'autoSetWalk', - 'checkdest' : 'checkDest', - 'spriteupdate' : 'spriteUpdate', - 'dodoor' : 'doDoor', + 'loadpersonal' : 'loadPersonal', + 'loadposition' : 'loadPosition', + 'loadroom' : 'loadRoom', + 'loadroomssample' : 'loadRoomsSample', + 'loadsample' : 'loadSample', + 'loadsavebox' : 'loadSaveBox', + 'loadsecondsample' : 'loadSecondSample', + 'loadseg' : 'loadSeg', + 'loadspeech' : 'loadSpeech', + 'loadtempcharset' : 'loadTempCharset', + 'loadtemptext' : 'loadTempText', + 'loadtraveltext' : 'loadTravelText', + 'locationpic' : 'locationPic', 'lockeddoorway' : 'lockedDoorway', - 'liftsprite' : 'liftSprite', - 'frameoutv' : 'frameOutV', - 'modifychar' : 'modifyChar', - 'allocatework' : 'allocateWork', + 'locklightoff' : 'lockLightOff', + 'locklighton' : 'lockLightOn', 'lockmon' : 'lockMon', - 'cancelch0' : 'cancelCh0', - 'cancelch1' : 'cancelCh1', - 'getroomspaths' : 'getRoomsPaths', - 'makebackob' : 'makeBackOb', - 'dealwithspecial' : 'dealWithSpecial', - 'plotreel' : 'plotReel', - 'facerightway' : 'faceRightWay', - 'crosshair' : 'crossHair', - 'showrain' : 'showRain', - 'domix' : 'doMix', - 'channel0tran' : 'channel0Tran', - 'makenextblock' : 'makeNextBlock', + 'lookatcard' : 'lookAtCard', + 'lookatplace' : 'lookAtPlace', + 'lookininterface' : 'lookInInterface', 'loopchannel0' : 'loopChannel0', - 'parseblaster' : 'parseBlaster', - 'deltextline' : 'delTextLine', - 'doblocks' : 'doBlocks', - 'checkifperson' : 'checkIfPerson', - 'checkiffree' : 'checkIfFree', - 'checkifex' : 'checkIfEx', - 'getreelstart' : 'getReelStart', - 'findobname' : 'findObName', - 'copyname' : 'copyName', - 'commandwithob' : 'commandWithOb', - 'showpanel' : 'showPanel', - 'updatepeople' : 'updatePeople', + 'louis' : 'louis', + 'louischair' : 'louisChair', + 'madman' : 'madman', + 'madmanrun' : 'madmanRun', + 'madmanstelly' : 'madmansTelly', 'madmantext' : 'madmanText', 'madmode' : 'madMode', - 'movemap' : 'moveMap', - 'widedoor' : 'wideDoor', - 'showallobs' : 'showAllObs', - 'addalong' : 'addAlong', - 'addlength' : 'addLength', - 'getdimension' : 'getDimension', - 'getxad' : 'getXAd', - 'getyad' : 'getYAd', - 'getmapad' : 'getMapAd', - 'calcmapad' : 'calcMapAd', - 'calcfrframe' : 'calcFrFrame', - 'finalframe' : 'finalFrame', - 'commandonly' : 'commandOnly', + 'mainman' : 'mainMan', + 'mainscreen' : 'mainScreen', + 'makebackob' : 'makeBackOb', + 'makecaps' : 'makeCaps', + 'makeheader' : 'makeHeader', + 'makemainscreen' : 'makeMainScreen', 'makename' : 'makeName', - 'findlen' : 'findLen', - 'blocknametext' : 'blockNameText', - 'walktotext' : 'walkToText', + 'makenextblock' : 'makeNextBlock', + 'makesprite' : 'makeSprite', + 'makeworn' : 'makeWorn', + 'malefan' : 'maleFan', + 'manasleep' : 'manAsleep', + 'manasleep2' : 'manAsleep2', + 'mansatstill' : 'manSatStill', + 'maptopanel' : 'mapToPanel', + 'middlepanel' : 'middlePanel', + 'mode640x480' : 'mode640x480', + 'modifychar' : 'modifyChar', + 'moneypoke' : 'moneyPoke', + 'monitorlogo' : 'monitorLogo', + 'monkandryan' : 'monkAndRyan', + 'monks2text' : 'monks2text', + 'monkspeaking' : 'monkSpeaking', + 'monmessage' : 'monMessage', + 'monprint' : 'monPrint', + 'moretalk' : 'moreTalk', + 'mousecall' : 'mouseCall', + 'movemap' : 'moveMap', + 'mugger' : 'mugger', + 'multidump' : 'multiDump', + 'multiget' : 'multiGet', + 'multiput' : 'multiPut', + 'namestoold' : 'namesToOld', + 'neterror' : 'netError', + 'newgame' : 'newGame', + 'newplace' : 'newPlace', + 'nextcolon' : 'nextColon', + 'nextdest' : 'nextDest', + 'nextfolder' : 'nextFolder', + 'nextsymbol' : 'nextSymbol', + 'obicons' : 'obIcons', + 'obname' : 'obName', + 'obpicture' : 'obPicture', + 'obsthatdothings' : 'obsThatDoThings', + 'obtoinv' : 'obToInv', + 'oldtonames' : 'oldToNames', + 'onedigit' : 'oneDigit', + 'openeden' : 'openEden', + 'openfile' : 'openFile', + 'openfilefromc' : 'openFileFromC', + 'openfilenocheck' : 'openFileNoCheck', + 'openforsave' : 'openForSave', + 'openhoteldoor' : 'openHotelDoor', + 'openhoteldoor2' : 'openHotelDoor2', + 'openinv' : 'openInv', + 'openlouis' : 'openLouis', + 'openob' : 'openOb', + 'openpoolboss' : 'openPoolBoss', + 'openryan' : 'openRyan', + 'opensarters' : 'openSarters', + 'opentomb' : 'openTomb', + 'opentvdoor' : 'openTVDoor', + 'openyourneighbour' : 'openYourNeighbour', + 'othersmoker' : 'otherSmoker', + 'out22c' : 'out22c', + 'outofinv' : 'outOfInv', + 'outofopen' : 'outOfOpen', + 'paltoendpal' : 'palToEndPal', + 'paltostartpal' : 'palToStartPal', + 'panelicons1' : 'panelIcons1', + 'paneltomap' : 'panelToMap', + 'parseblaster' : 'parseBlaster', + 'parser' : 'parser', 'personnametext' : 'personNameText', - 'findxyfrompath' : 'findXYFromPath', - 'findormake' : 'findOrMake', - 'setallchanges' : 'setAllChanges', - 'dochange' : 'doChange', - 'deletetaken' : 'deleteTaken', + 'pickupconts' : 'pickupConts', + 'pickupob' : 'pickupOb', + 'pitinterupt' : 'pitInterrupt', + 'pixelcheckset' : 'pixelCheckSet', + 'placefreeobject' : 'placeFreeObject', 'placesetobject' : 'placeSetObject', - 'removesetobject' : 'removeSetObject', - 'showallfree' : 'showAllFree', - 'showallex' : 'showAllEx', - 'adjustlen' : 'adjustLen', - 'finishedwalking' : 'finishedWalking', - 'checkone' : 'checkOne', - 'getblockofpixel' : 'getBlockOfPixel', - 'getflagunderp' : 'getFlagUnderP', - 'walkandexamine' : 'walkAndExamine', - 'obname' : 'obName', - 'delpointer' : 'delPointer', - 'showblink' : 'showBlink', - 'dumpblink' : 'dumpBlink', - 'dumppointer' : 'dumpPointer', - 'showpointer' : 'showPointer', - 'animpointer' : 'animPointer', - 'showicon' : 'showIcon', - 'checkcoords' : 'checkCoords', + 'playchannel0' : 'playChannel0', + 'playchannel1' : 'playChannel1', + 'playguitar' : 'playGuitar', + 'plotreel' : 'plotReel', + 'poolguard' : 'poolGuard', + 'powerlightoff' : 'powerLightOff', + 'powerlighton' : 'powerLightOn', + 'priest' : 'priest', + 'priesttext' : 'priestText', + 'printasprite' : 'printASprite', + 'printboth' : 'printBoth', + 'printchar' : 'printChar', + 'printcurs' : 'printCurs', + 'printdirect' : 'printDirect', + 'printlogo' : 'printLogo', + 'printmessage' : 'printMessage', + 'printmessage2' : 'printMessage2', + 'printoutermon' : 'printOuterMon', + 'printslow' : 'printSlow', + 'printsprites' : 'printSprites', + 'printundermon' : 'printUnderMon', + 'processtrigger' : 'processTrigger', + 'purgealocation' : 'purgeALocation', + 'purgeanitem' : 'purgeAnItem', + 'putbackobstuff' : 'putBackObStuff', + 'putundercentre' : 'putUnderCentre', + 'putundermenu' : 'putUnderMenu', + 'putundertimed' : 'putUnderTimed', + 'putunderzoom' : 'putUnderZoom', + 'quickquit' : 'quickQuit', + 'quickquit2' : 'quickQuit2', + 'quitkey' : 'quitKey', + 'quitsymbol' : 'quitSymbol', + 'random' : 'random', + 'randomaccess' : 'randomAccess', + 'randomnum1' : 'randomNum1', + 'randomnum2' : 'randomNum2', + 'randomnumber' : 'randomNumber', + 'read' : 'read', + 'readabyte' : 'readAByte', + 'readcitypic' : 'readCityPic', + 'readdesticon' : 'readDestIcon', + 'readfromfile' : 'readFromFile', + 'readheader' : 'readHeader', + 'readkey' : 'readKey', 'readmouse' : 'readMouse', 'readmouse1' : 'readMouse1', 'readmouse2' : 'readMouse2', 'readmouse3' : 'readMouse3', 'readmouse4' : 'readMouse4', - 'waitframes' : 'waitFrames', - 'drawflags' : 'drawFlags', - 'blockget' : 'blockGet', - 'addtopeoplelist' : 'addToPeopleList', - 'getexpos' : 'getExPos', - 'paneltomap' : 'panelToMap', - 'maptopanel' : 'mapToPanel', - 'dumpmap' : 'dumpMap', - 'obpicture' : 'obPicture', - 'delthisone' : 'delThisOne', - 'transferinv' : 'transferInv', - 'obicons' : 'obIcons', - 'pixelcheckset' : 'pixelCheckSet', - 'turnpathon' : 'turnPathOn', - 'turnpathoff' : 'turnPathOff', - 'turnanypathon' : 'turnAnyPathOn', - 'turnanypathoff' : 'turnAnyPathOff', - 'isitdescribed' : 'isItDescribed', - 'checkifset' : 'checkIfSet', - 'checkifpathison' : 'checkIfPathIsOn', - 'delsprite' : 'delSprite', - 'dumpeverything' : 'dumpEverything', - 'isitworn' : 'isItWorn', - 'makeworn' : 'makeWorn', - 'obtoinv' : 'obToInv', - 'showryanpage' : 'showRyanPage', - 'findallryan' : 'findAllRyan', - 'fillryan' : 'fillRyan', - 'useroutine' : 'useRoutine', - 'hangon' : 'hangOn', - 'hangonp' : 'hangOnP', - 'hangonw' : 'hangOnW', - 'findnextcolon' : 'findNextColon', - 'usetext' : 'useText', - 'sortoutmap' : 'sortOutMap', + 'readoneblock' : 'readOneBlock', + 'readsetdata' : 'readSetData', + 'realcredits' : 'realCredits', + 'receptionist' : 'receptionist', + 'redes' : 'redes', + 'redrawmainscrn' : 'redrawMainScrn', + 'reelsonscreen' : 'reelsOnScreen', + 'reexfrominv' : 'reExFromInv', + 'reexfromopen' : 'reExFromOpen', + 'reminders' : 'reminders', + 'removeemm' : 'removeEMM', + 'removefreeobject' : 'removeFreeObject', + 'removeobfrominv' : 'removeObFromInv', + 'removesetobject' : 'removeSetObject', + 'resetkeyboard' : 'resetKeyboard', + 'resetlocation' : 'resetLocation', + 'restoreall' : 'restoreAll', + 'restoreems' : 'restoreEMS', + 'restorereels' : 'restoreReels', + 'rockstar' : 'rockstar', + 'rollem' : 'rollEm', + 'rollendcredits' : 'rollEndCredits', + 'rollendcredits2' : 'rollEndCredits2', + 'roomname' : 'roomName', + 'runendseq' : 'runEndSeq', + 'runintroseq' : 'runIntroSeq', + 'runtap' : 'runTap', + 'saveems' : 'saveEMS', + 'savefileread' : 'saveFileRead', + 'savefilewrite' : 'savefileWrite', + 'savegame' : 'saveGame', + 'saveload' : 'saveLoad', + 'saveposition' : 'savePosition', + 'saveseg' : 'saveSeg', + 'scanfornames' : 'scanForNames', + 'screenupdate' : 'screenUpdate', + 'scrollmonitor' : 'scrollMonitor', + 'searchforfiles' : 'searchForFiles', + 'searchforsame' : 'searchForSame', + 'searchforstring' : 'searchForString', + 'security' : 'security', + 'seecommandtail' : 'seeCommandTail', + 'selectlocation' : 'selectLocation', + 'selectob' : 'selectOb', + 'selectopenob' : 'selectOpenOb', + 'selectslot' : 'selectSlot', + 'selectslot2' : 'selectSlot2', + 'set16colpalette' : 'set16ColPalette', + 'setallchanges' : 'setAllChanges', + 'setbotleft' : 'setBotLeft', + 'setbotright' : 'setBotRight', + 'setkeyboardint' : 'setKeyboardInt', + 'setlocation' : 'setLocation', + 'setmode' : 'setMode', + 'setmouse' : 'setMouse', + 'setpickup' : 'setPickup', + 'setsoundoff' : 'setSoundOff', + 'settopleft' : 'setTopLeft', + 'settopright' : 'setTopRight', + 'setupemm' : 'setupEMM', + 'setuppit' : 'setupPit', + 'setuptimedtemp' : 'setupTimedTemp', + 'setuptimeduse' : 'setupTimedUse', + 'setwalk' : 'setWalk', + 'showallex' : 'showAllEx', + 'showallfree' : 'showAllFree', + 'showallobs' : 'showAllObs', + 'showarrows' : 'showArrows', + 'showblink' : 'showBlink', + 'showbyte' : 'showByte', 'showcity' : 'showCity', - 'examineobtext' : 'examineObText', - 'wornerror' : 'wornError', - 'getpersframe' : 'getPersFrame', - 'convicons' : 'convIcons', - 'examineob' : 'examineOb', - 'showwatch' : 'showWatch', - 'dumpwatch' : 'dumpWatch', + 'showcurrentfile' : 'showCurrentFile', + 'showdecisions' : 'showDecisions', + 'showdiary' : 'showDiary', + 'showdiarykeys' : 'showDiaryKeys', + 'showdiarypage' : 'showDiaryPage', + 'showdiscops' : 'showDiscOps', + 'showexit' : 'showExit', + 'showfirstuse' : 'showFirstUse', + 'showfolder' : 'showFolder', + 'showframe' : 'showFrame', + 'showgamereel' : 'showGameReel', + 'showgroup' : 'showGroup', + 'showgun' : 'showGun', + 'showicon' : 'showIcon', + 'showkeypad' : 'showKeypad', + 'showkeys' : 'showKeys', + 'showleftpage' : 'showLeftPage', + 'showloadops' : 'showLoadOps', + 'showmainops' : 'showMainOps', + 'showman' : 'showMan', + 'showmenu' : 'showMenu', + 'showmonk' : 'showMonk', + 'shownames' : 'showNames', + 'showopbox' : 'showOpBox', + 'showoutermenu' : 'showOuterMenu', + 'showouterpad' : 'showOuterPad', + 'showpanel' : 'showPanel', + 'showpcx' : 'showPCX', + 'showpointer' : 'showPointer', + 'showpuztext' : 'showPuzText', + 'showrain' : 'showRain', + 'showreelframe' : 'showReelFrame', + 'showrightpage' : 'showRightPage', + 'showryanpage' : 'showRyanPage', + 'showsaveops' : 'showSaveOps', + 'showseconduse' : 'showSecondUse', + 'showslots' : 'showSlots', + 'showsymbol' : 'showSymbol', 'showtime' : 'showTime', - 'roomname' : 'roomName', - 'transfertext' : 'transferText', + 'showwatch' : 'showWatch', + 'showword' : 'showWord', + 'signon' : 'signOn', + 'singlekey' : 'singleKey', + 'sitdowninbar' : 'sitDownInBar', + 'slabdoora' : 'sLabDoorA', + 'slabdoorb' : 'sLabDoorB', + 'slabdoorc' : 'sLabDoorC', + 'slabdoord' : 'sLabDoorD', + 'slabdoore' : 'sLabDoorE', + 'slabdoorf' : 'sLabDoorF', + 'smallcandle' : 'smallCandle', + 'smokebloke' : 'smokeBloke', + 'soldier1' : 'soldier1', + 'sortoutmap' : 'sortOutMap', + 'soundend' : 'soundEnd', + 'soundonreels' : 'soundOnReels', + 'soundstartup' : 'soundStartup', + 'sparky' : 'sparky', + 'sparkydrip' : 'sparkyDrip', 'splitintolines' : 'splitIntoLines', - 'initrain' : 'initRain', - 'checkbasemem' : 'checkBaseMem', - 'clearstartpal' : 'clearStartPal', - 'clearendpal' : 'clearEndPal', - 'paltostartpal' : 'palToStartPal', - 'endpaltostart' : 'endPalToStart', + 'spriteupdate' : 'spriteUpdate', + 'standardload' : 'standardLoad', + 'startdmablock' : 'startDMABlock', + 'startloading' : 'startLoading', 'startpaltoend' : 'startPalToEnd', - 'paltoendpal' : 'palToEndPal', - 'fadecalculation' : 'fadeCalculation', - 'watchcount' : 'watchCount', - 'zoomicon' : 'zoomIcon', - 'loadroom' : 'loadRoom', - 'getundermenu' : 'getUnderMenu', - 'putundermenu' : 'putUnderMenu', - 'showoutermenu' : 'showOuterMenu', + 'starttalk' : 'startTalk', + 'steady' : 'steady', + 'storeit' : 'storeIt', + 'swapwithinv' : 'swapWithInv', + 'swapwithopen' : 'swapWithOpen', + 'switchryanoff' : 'switchRyanOff', + 'switchryanon' : 'switchRyanOn', + 'talk' : 'talk', + 'tattooman' : 'tattooMan', 'textforend' : 'textForEnd', 'textformonk' : 'textForMonk', - 'standardload' : 'standardLoad', - 'twodigitnum' : 'twoDigitNum', - 'readsetdata' : 'readSetData', - 'loadintotemp' : 'loadIntoTemp', - 'loadintotemp2' : 'loadIntoTemp2', - 'loadintotemp3' : 'loadIntoTemp3', - 'loadtempcharset' : 'loadTempCharset', - 'printcurs' : 'printCurs', - 'delcurs' : 'delCurs', - 'hangoncurs' : 'hangOnCurs', - 'fadeupyellows' : 'fadeUpYellows', - 'fadeupmonfirst' : 'fadeUpMonFirst', - 'loadroomssample' : 'loadRoomsSample', - 'printlogo' : 'printLogo', - 'usemon' : 'useMon', - 'scrollmonitor' : 'scrollMonitor', - 'showcurrentfile' : 'showCurrentFile', - 'monprint' : 'monPrint', - 'monmessage' : 'monMessage', - 'neterror' : 'netError', - 'randomaccess' : 'randomAccess', + 'titles' : 'titles', + 'train' : 'train', + 'transfercontoex' : 'transferConToEx', + 'transferinv' : 'transferInv', + 'transfermap' : 'transferMap', + 'transfertext' : 'transferText', + 'transfertoex' : 'transferToEx', + 'trapdoor' : 'trapDoor', + 'triggermessage' : 'triggerMessage', + 'trysoundalloc' : 'trySoundAlloc', + 'turnanypathoff' : 'turnAnyPathOff', + 'turnanypathon' : 'turnAnyPathOn', 'turnonpower' : 'turnOnPower', - 'showmainops' : 'showMainOps', - 'showdiscops' : 'showDiscOps', - 'powerlighton' : 'powerLightOn', - 'powerlightoff' : 'powerLightOff', - 'accesslighton' : 'accessLightOn', - 'accesslightoff' : 'accessLightOff', - 'playchannel0' : 'playChannel0', - 'playchannel1' : 'playChannel1', - 'createpanel' : 'createPanel', - 'createpanel2' : 'createPanel2', - 'findroominloc' : 'findRoomInLoc', - 'autolook' : 'autoLook', - 'dolook' : 'doLook', - 'reelsonscreen' : 'reelsOnScreen', - 'showbyte' : 'showByte', - 'onedigit' : 'oneDigit', - 'showword' : 'showWord', - 'convnum' : 'convNum', + 'turnpathoff' : 'turnPathOff', + 'turnpathon' : 'turnPathOn', + 'twodigitnum' : 'twoDigitNum', + 'undertextline' : 'underTextLine', + 'updatepeople' : 'updatePeople', + 'updatesymbolbot' : 'updateSymbolBot', + 'updatesymboltop' : 'updateSymbolTop', + 'usealtar' : 'useAltar', + 'useaxe' : 'useAxe', + 'usebalcony' : 'useBalcony', + 'usebuttona' : 'useButtonA', + 'usecardreader1' : 'useCardReader1', + 'usecardreader2' : 'useCardReader2', + 'usecardreader3' : 'useCardReader3', + 'usecart' : 'useCart', + 'usecashcard' : 'useCashCard', 'usecharset1' : 'useCharset1', + 'usechurchgate' : 'useChurchGate', + 'usechurchhole' : 'useChurchHole', + 'useclearbox' : 'useClearBox', + 'usecontrol' : 'useControl', + 'usecooker' : 'useCooker', + 'usecoveredbox' : 'useCoveredBox', + 'usediary' : 'useDiary', + 'usedryer' : 'useDryer', + 'useelevator1' : 'useElevator1', + 'useelevator2' : 'useElevator2', + 'useelevator3' : 'useElevator3', + 'useelevator4' : 'useElevator4', + 'useelevator5' : 'useElevator5', + 'useelvdoor' : 'useElvDoor', + 'usefullcart' : 'useFullCart', + 'usegun' : 'useGun', + 'usehandle' : 'useHandle', + 'usehatch' : 'useHatch', + 'usehole' : 'useHole', + 'usekey' : 'useKey', + 'useladder' : 'useLadder', + 'useladderb' : 'useLadderB', + 'uselighter' : 'useLighter', + 'usemenu' : 'useMenu', + 'usemon' : 'useMon', + 'useobject' : 'useObject', + 'useopenbox' : 'useOpenBox', + 'useopened' : 'useOpened', + 'usepipe' : 'usePipe', + 'useplate' : 'usePlate', + 'useplinth' : 'usePlinth', + 'usepoolreader' : 'usePoolReader', + 'userailing' : 'useRailing', + 'useroutine' : 'useRoutine', + 'useshield' : 'useShield', + 'useslab' : 'useSLab', + 'usestereo' : 'useStereo', 'usetempcharset' : 'useTempCharset', - 'disablepath' : 'disablePath', - 'getbackfromob' : 'getBackFromOb', - 'showfirstuse' : 'showFirstUse', - 'showseconduse' : 'showSecondUse', - 'actualload' : 'actualLoad', - 'actualsave' : 'actualSave', - 'loadposition' : 'loadPosition', - 'saveposition' : 'savePosition', - 'saveseg' : 'saveSeg', - 'openforsave' : 'openForSave', - 'makeheader' : 'makeHeader', - 'savefilewrite' : 'savefileWrite', - 'storeit' : 'storeIt', - 'restoreall' : 'restoreAll', - 'restorereels' : 'restoreReels', - 'allocateload' : 'allocateLoad', + 'usetext' : 'useText', + 'usetimedtext' : 'useTimedText', + 'usetrainer' : 'useTrainer', + 'usewall' : 'useWall', + 'usewinch' : 'useWinch', + 'usewindow' : 'useWindow', + 'usewire' : 'useWire', 'viewfolder' : 'viewFolder', - 'loadfolder' : 'loadFolder', - 'showfolder' : 'showFolder', - 'showleftpage' : 'showLeftPage', - 'showrightpage' : 'showRightPage', - 'nextfolder' : 'nextFolder', - 'lastfolder' : 'lastFolder', - 'folderhints' : 'folderHints', - 'folderexit' : 'folderExit', - 'getlocation' : 'getLocation', - 'setlocation' : 'setLocation', - 'getridofpitsetuppit' : 'getRidOfPitSetupPit', + 'vsync' : 'vSync', + 'waitframes' : 'waitFrames', + 'walkandexamine' : 'walkAndExamine', + 'walkintoroom' : 'walkIntoRoom', + 'walktotext' : 'walkToText', + 'watchcount' : 'watchCount', + 'watchreel' : 'watchReel', + 'wearshades' : 'wearShades', + 'wearwatch' : 'wearWatch', + 'wheelsound' : 'wheelSound', + 'widedoor' : 'wideDoor', + 'withwhat' : 'withWhat', + 'worktoscreen' : 'workToScreen', + 'worktoscreenm' : 'workToScreenM', + 'wornerror' : 'wornError', + 'zoomicon' : 'zoomIcon', + 'zoomonoff' : 'zoomOnOff', }) generator.generate('dreamweb') #start routine diff --git a/devtools/tasmrecover/tasm/cpp.py b/devtools/tasmrecover/tasm/cpp.py index e507fd451d..686aea9ee9 100644 --- a/devtools/tasmrecover/tasm/cpp.py +++ b/devtools/tasmrecover/tasm/cpp.py @@ -644,7 +644,7 @@ namespace %s { """ class %sContext : public DreamBase, public Context { public: - DreamGenContext(DreamWeb::DreamWebEngine *en) : DreamBase(en), Context(data) {} + DreamGenContext(DreamWeb::DreamWebEngine *en) : DreamBase(en), Context(this) {} void __start(); """ diff --git a/engines/agi/agi.h b/engines/agi/agi.h index 6bb3beec78..e9923aba2e 100644 --- a/engines/agi/agi.h +++ b/engines/agi/agi.h @@ -809,8 +809,6 @@ public: virtual void replayImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3, int16 p4, int16 p5, int16 p6, int16 p7) = 0; virtual void releaseImageStack() = 0; - virtual int saveGame(const Common::String &fileName, const Common::String &saveName) = 0; - virtual int loadGame(const Common::String &fileName, bool checkId = true) = 0; int _soundemu; diff --git a/engines/agi/objects.cpp b/engines/agi/objects.cpp index 94eef92579..447cff2a3f 100644 --- a/engines/agi/objects.cpp +++ b/engines/agi/objects.cpp @@ -52,7 +52,7 @@ int AgiEngine::decodeObjects(uint8 *mem, uint32 flen) { // alloc memory for object list // byte 3 = number of animated objects. this is ignored.. ?? - if (READ_LE_UINT16(mem) / padsize >= 256) { + if (READ_LE_UINT16(mem) / padsize > 256) { // die with no error! AGDS game needs not to die to work!! :( return errOK; } diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp index 41d9cc3ac9..7e04328a67 100644 --- a/engines/agi/op_cmd.cpp +++ b/engines/agi/op_cmd.cpp @@ -1702,6 +1702,9 @@ void cmdSetItemView(AgiGame *state, uint8 *p) { void cmdCallV1(AgiGame *state, uint8 *p) { state->_vm->agiLoadResource(rLOGIC, p0); + // FIXME: The following instruction looks incomplete. + // Maybe something is meant to be assigned to, or read from, + // the logic_list entry? state->logic_list[++state->max_logics]; _v[13] = 1; } diff --git a/engines/agos/installshield_cab.cpp b/engines/agos/installshield_cab.cpp index ac4e40d1d1..d4e636f7b3 100644 --- a/engines/agos/installshield_cab.cpp +++ b/engines/agos/installshield_cab.cpp @@ -60,9 +60,9 @@ public: ~InstallShieldCabinet(); // Common::Archive API implementation - bool hasFile(const Common::String &name); - int listMembers(Common::ArchiveMemberList &list); - Common::ArchiveMemberPtr getMember(const Common::String &name); + bool hasFile(const Common::String &name) const; + int listMembers(Common::ArchiveMemberList &list) const; + const Common::ArchiveMemberPtr getMember(const Common::String &name) const; Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; private: @@ -161,18 +161,18 @@ InstallShieldCabinet::InstallShieldCabinet(const Common::String &filename) : _in delete[] fileTableOffsets; } -bool InstallShieldCabinet::hasFile(const Common::String &name) { +bool InstallShieldCabinet::hasFile(const Common::String &name) const { return _map.contains(name); } -int InstallShieldCabinet::listMembers(Common::ArchiveMemberList &list) { +int InstallShieldCabinet::listMembers(Common::ArchiveMemberList &list) const { for (FileMap::const_iterator it = _map.begin(); it != _map.end(); it++) list.push_back(getMember(it->_key)); return _map.size(); } -Common::ArchiveMemberPtr InstallShieldCabinet::getMember(const Common::String &name) { +const Common::ArchiveMemberPtr InstallShieldCabinet::getMember(const Common::String &name) const { return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this)); } diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp index a64272d967..ed656682ee 100644 --- a/engines/cine/detection.cpp +++ b/engines/cine/detection.cpp @@ -65,7 +65,7 @@ class CineMetaEngine : public AdvancedMetaEngine { public: CineMetaEngine() : AdvancedMetaEngine(Cine::gameDescriptions, sizeof(Cine::CINEGameDescription), cineGames) { _singleid = "cine"; - _guioptions = GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI); + _guioptions = GUIO1(GUIO_NOSPEECH); } virtual GameDescriptor findGame(const char *gameid) const { diff --git a/engines/cine/detection_tables.h b/engines/cine/detection_tables.h index ddb63c960b..0ec2768bae 100644 --- a/engines/cine/detection_tables.h +++ b/engines/cine/detection_tables.h @@ -122,7 +122,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_FW, 0, @@ -136,7 +136,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_USA, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_FW, 0, @@ -150,7 +150,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_FW, GF_ALT_FONT, @@ -164,7 +164,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_FW, 0, @@ -178,7 +178,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_FW, 0, @@ -192,7 +192,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_FW, 0, @@ -210,7 +210,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformAmiga, ADGF_DEMO, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_FW, 0, @@ -224,7 +224,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformAtariST, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_FW, 0, @@ -238,7 +238,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformAtariST, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_FW, 0, @@ -384,7 +384,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_GRB, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_OS, 0, @@ -398,7 +398,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_GRB, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_OS, 0, @@ -412,7 +412,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_USA, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_OS, 0, @@ -426,7 +426,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_OS, 0, @@ -440,7 +440,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_OS, 0, @@ -454,7 +454,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_OS, 0, @@ -468,7 +468,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_GRB, Common::kPlatformAmiga, ADGF_DEMO, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_OS, GF_DEMO, @@ -482,7 +482,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_GRB, Common::kPlatformAtariST, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_OS, 0, @@ -496,7 +496,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformAtariST, ADGF_NO_FLAGS, - GUIO0() + GUIO1(GUIO_NOMIDI) }, GType_OS, 0, diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp index 48c5e3d0a5..b2e992e8f6 100644 --- a/engines/cine/sound.cpp +++ b/engines/cine/sound.cpp @@ -25,12 +25,16 @@ #include "common/memstream.h" #include "common/system.h" #include "common/textconsole.h" +#include "common/timer.h" +#include "common/mutex.h" +#include "common/config-manager.h" #include "cine/cine.h" #include "cine/sound.h" #include "audio/audiostream.h" #include "audio/fmopl.h" +#include "audio/mididrv.h" #include "audio/decoders/raw.h" #include "audio/mods/soundfx.h" @@ -48,14 +52,13 @@ public: virtual void playSample(const byte *data, int size, int channel, int volume) = 0; virtual void stopAll() = 0; virtual const char *getInstrumentExtension() const { return ""; } + virtual void notifyInstrumentLoad(const byte *data, int size, int channel) {} - void setUpdateCallback(UpdateCallback upCb, void *ref); + virtual void setUpdateCallback(UpdateCallback upCb, void *ref) = 0; void resetChannel(int channel); void findNote(int freq, int *note, int *oct) const; protected: - UpdateCallback _upCb; - void *_upRef; static const int _noteTable[]; static const int _noteTableCount; @@ -104,6 +107,7 @@ public: virtual ~AdLibSoundDriver(); // PCSoundDriver interface + virtual void setUpdateCallback(UpdateCallback upCb, void *ref); virtual void setupChannel(int channel, const byte *data, int instrument, int volume); virtual void stopChannel(int channel); virtual void stopAll(); @@ -121,6 +125,9 @@ public: virtual void loadInstrument(const byte *data, AdLibSoundInstrument *asi) = 0; protected: + UpdateCallback _upCb; + void *_upRef; + FM_OPL *_opl; int _sampleRate; Audio::Mixer *_mixer; @@ -177,6 +184,30 @@ public: virtual void playSample(const byte *data, int size, int channel, int volume); }; +// (Future Wars) MIDI driver +class MidiSoundDriverH32 : public PCSoundDriver { +public: + MidiSoundDriverH32(MidiDriver *output); + ~MidiSoundDriverH32(); + + virtual void setUpdateCallback(UpdateCallback upCb, void *ref); + virtual void setupChannel(int channel, const byte *data, int instrument, int volume); + virtual void setChannelFrequency(int channel, int frequency); + virtual void stopChannel(int channel); + virtual void playSample(const byte *data, int size, int channel, int volume); + virtual void stopAll() {} + virtual const char *getInstrumentExtension() const { return ".H32"; } + virtual void notifyInstrumentLoad(const byte *data, int size, int channel); + +private: + MidiDriver *_output; + UpdateCallback _callback; + Common::Mutex _mutex; + + void writeInstrument(int offset, const byte *data, int size); + void selectInstrument(int channel, int timbreGroup, int timbreNumber, int volume); +}; + class PCSoundFxPlayer { public: @@ -213,23 +244,35 @@ private: byte *_sfxData; byte *_instrumentsData[NUM_INSTRUMENTS]; PCSoundDriver *_driver; + Common::Mutex _mutex; }; -void PCSoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) { - _upCb = upCb; - _upRef = ref; -} - void PCSoundDriver::findNote(int freq, int *note, int *oct) const { - *note = _noteTableCount - 1; - for (int i = 0; i < _noteTableCount; ++i) { - if (_noteTable[i] <= freq) { + if (freq > 0x777) + *oct = 0; + else if (freq > 0x3BB) + *oct = 1; + else if (freq > 0x1DD) + *oct = 2; + else if (freq > 0x0EE) + *oct = 3; + else if (freq > 0x077) + *oct = 4; + else if (freq > 0x03B) + *oct = 5; + else if (freq > 0x01D) + *oct = 6; + else + *oct = 7; + + *note = 11; + for (int i = 0; i < 12; ++i) { + if (_noteTable[*oct * 12 + i] <= freq) { *note = i; break; } } - *oct = *note / 12; } void PCSoundDriver::resetChannel(int channel) { @@ -252,6 +295,11 @@ AdLibSoundDriver::~AdLibSoundDriver() { OPLDestroy(_opl); } +void AdLibSoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) { + _upCb = upCb; + _upRef = ref; +} + void AdLibSoundDriver::setupChannel(int channel, const byte *data, int instrument, int volume) { assert(channel < 4); if (data) { @@ -441,12 +489,11 @@ void AdLibSoundDriverINS::setChannelFrequency(int channel, int frequency) { if (ins->mode == 0 || ins->channel == 6) { int freq, note, oct; findNote(frequency, ¬e, &oct); - if (channel == 6) { - note %= 12; - } + if (channel == 6) + oct = 0; freq = _freqTable[note % 12]; OPLWriteReg(_opl, 0xA0 | channel, freq); - freq = ((note / 12) << 2) | ((freq & 0x300) >> 8); + freq = (oct << 2) | ((freq & 0x300) >> 8); if (ins->mode == 0) { freq |= 0x20; } @@ -509,14 +556,16 @@ void AdLibSoundDriverADL::setChannelFrequency(int channel, int frequency) { findNote(frequency, ¬e, &oct); if (ins->amDepth) { note = ins->amDepth; + oct = note / 12; } if (note < 0) { note = 0; + oct = 0; } freq = _freqTable[note % 12]; OPLWriteReg(_opl, 0xA0 | channel, freq); - freq = ((note / 12) << 2) | ((freq & 0x300) >> 8); + freq = (oct << 2) | ((freq & 0x300) >> 8); if (ins->mode == 0) { freq |= 0x20; } @@ -564,8 +613,163 @@ void AdLibSoundDriverADL::playSample(const byte *data, int size, int channel, in } } +MidiSoundDriverH32::MidiSoundDriverH32(MidiDriver *output) + : _output(output), _callback(0), _mutex() { +} + +MidiSoundDriverH32::~MidiSoundDriverH32() { + if (_callback) + g_system->getTimerManager()->removeTimerProc(_callback); + + _output->close(); + delete _output; +} + +void MidiSoundDriverH32::setUpdateCallback(UpdateCallback upCb, void *ref) { + Common::StackLock lock(_mutex); + + Common::TimerManager *timer = g_system->getTimerManager(); + assert(timer); + + if (_callback) + timer->removeTimerProc(_callback); + + _callback = upCb; + if (_callback) + timer->installTimerProc(_callback, 1000000 / 50, ref, "MidiSoundDriverH32"); +} + +void MidiSoundDriverH32::setupChannel(int channel, const byte *data, int instrument, int volume) { + Common::StackLock lock(_mutex); + + if (volume < 0 || volume > 100) + volume = 0; + + if (!data) + selectInstrument(channel, 0, 0, volume); + // In case the instrument is a builtin instrument select it directly. + else if (data[0] < 0x80) + selectInstrument(channel, data[0] / 0x40, data[0] % 0x40, volume); + // In case we use a custom instrument we need to specify the timbre group + // 2, which means it's a timbre from the timbre memory area. + else + selectInstrument(channel, 2, instrument, volume); +} + +void MidiSoundDriverH32::setChannelFrequency(int channel, int frequency) { + Common::StackLock lock(_mutex); + + int note, oct; + findNote(frequency, ¬e, &oct); + note %= 12; + note = oct * 12 + note + 12; + + _output->send(0x91 + channel, note, 0x7F); +} + +void MidiSoundDriverH32::stopChannel(int channel) { + Common::StackLock lock(_mutex); + + _output->send(0xB1 + channel, 0x7B, 0x00); +} + +void MidiSoundDriverH32::playSample(const byte *data, int size, int channel, int volume) { + Common::StackLock lock(_mutex); + + stopChannel(channel); + + volume = volume * 8 / 5; + + if (data[0] < 0x80) { + selectInstrument(channel, data[0] / 0x40, data[0] % 0x40, volume); + } else { + writeInstrument(channel * 512 + 0x80000, data + 1, 256); + selectInstrument(channel, 2, channel, volume); + } + + _output->send(0x91 + channel, 12, 0x7F); +} + +void MidiSoundDriverH32::notifyInstrumentLoad(const byte *data, int size, int channel) { + Common::StackLock lock(_mutex); + + // In case we specify a standard instrument or standard rhythm instrument + // do not do anything here. It might be noteworthy that the instrument + // selection client code does not support rhythm instruments! + if (data[0] < 0x80 || data[0] > 0xC0) + return; + + writeInstrument(channel * 512 + 0x80000, data + 1, size - 1); +} + +void MidiSoundDriverH32::writeInstrument(int offset, const byte *data, int size) { + byte sysEx[254]; + + sysEx[0] = 0x41; + sysEx[1] = 0x10; + sysEx[2] = 0x16; + sysEx[3] = 0x12; + sysEx[4] = (offset >> 16) & 0xFF; + sysEx[5] = (offset >> 8) & 0xFF; + sysEx[6] = (offset >> 0) & 0xFF; + int copySize = MIN(246, size); + memcpy(&sysEx[7], data, copySize); + + byte checkSum = 0; + for (int i = 0; i < copySize + 3; ++i) + checkSum += sysEx[4 + i]; + sysEx[7 + copySize] = 0x80 - (checkSum & 0x7F); + + _output->sysEx(sysEx, copySize + 8); +} + +void MidiSoundDriverH32::selectInstrument(int channel, int timbreGroup, int timbreNumber, int volume) { + const int offset = channel * 16 + 0x30000; // 0x30000 is the start of the patch temp area + + byte sysEx[24] = { + 0x41, 0x10, 0x16, 0x12, + 0x00, 0x00, 0x00, // offset + 0x00, // Timbre group _ timbreGroup * 64 + timbreNumber should be the + 0x00, // Timbre number / MT-32 instrument in case timbreGroup is 0 or 1. + 0x18, // Key shift (= 0) + 0x32, // Fine tune (= 0) + 0x0C, // Bender Range + 0x03, // Assign Mode + 0x01, // Reverb Switch (= enabled) + 0x00, // dummy + 0x00, // Output level + 0x07, // Panpot (= balanced) + 0x00, // dummy + 0x00, // dummy + 0x00, // dummy + 0x00, // dummy + 0x00, // dummy + 0x00, // dummy + 0x00 // checksum + }; + + + sysEx[4] = (offset >> 16) & 0xFF; + sysEx[5] = (offset >> 8) & 0xFF; + sysEx[6] = (offset >> 0) & 0xFF; + + sysEx[7] = timbreGroup; + sysEx[8] = timbreNumber; + + sysEx[15] = volume; + + byte checkSum = 0; + + for (int i = 4; i < 23; ++i) + checkSum += sysEx[i]; + + sysEx[23] = 0x80 - (checkSum & 0x7F); + + _output->sysEx(sysEx, 24); +} + PCSoundFxPlayer::PCSoundFxPlayer(PCSoundDriver *driver) - : _playing(false), _driver(driver) { + : _playing(false), _driver(driver), _mutex() { memset(_instrumentsData, 0, sizeof(_instrumentsData)); _sfxData = NULL; _fadeOutCounter = 0; @@ -573,12 +777,15 @@ PCSoundFxPlayer::PCSoundFxPlayer(PCSoundDriver *driver) } PCSoundFxPlayer::~PCSoundFxPlayer() { + Common::StackLock lock(_mutex); + _driver->setUpdateCallback(NULL, NULL); stop(); } bool PCSoundFxPlayer::load(const char *song) { debug(9, "PCSoundFxPlayer::load('%s')", song); + Common::StackLock lock(_mutex); /* stop (w/ fade out) the previous song */ while (_fadeOutCounter != 0 && _fadeOutCounter < 100) { @@ -608,9 +815,12 @@ bool PCSoundFxPlayer::load(const char *song) { *dot = '\0'; } strcat(instrument, _driver->getInstrumentExtension()); - _instrumentsData[i] = readBundleSoundFile(instrument); + uint32 instrumentSize; + _instrumentsData[i] = readBundleSoundFile(instrument, &instrumentSize); if (!_instrumentsData[i]) { warning("Unable to load soundfx instrument '%s'", instrument); + } else { + _driver->notifyInstrumentLoad(_instrumentsData[i], instrumentSize, i); } } } @@ -619,6 +829,7 @@ bool PCSoundFxPlayer::load(const char *song) { void PCSoundFxPlayer::play() { debug(9, "PCSoundFxPlayer::play()"); + Common::StackLock lock(_mutex); if (_sfxData) { for (int i = 0; i < NUM_CHANNELS; ++i) { _instrumentsChannelTable[i] = -1; @@ -633,6 +844,7 @@ void PCSoundFxPlayer::play() { } void PCSoundFxPlayer::stop() { + Common::StackLock lock(_mutex); if (_playing || _fadeOutCounter != 0) { _fadeOutCounter = 0; _playing = false; @@ -645,6 +857,7 @@ void PCSoundFxPlayer::stop() { } void PCSoundFxPlayer::fadeOut() { + Common::StackLock lock(_mutex); if (_playing) { _fadeOutCounter = 1; _playing = false; @@ -656,6 +869,7 @@ void PCSoundFxPlayer::updateCallback(void *ref) { } void PCSoundFxPlayer::update() { + Common::StackLock lock(_mutex); if (_playing || (_fadeOutCounter != 0 && _fadeOutCounter < 100)) { ++_updateTicksCounter; if (_updateTicksCounter > _eventsDelay) { @@ -717,12 +931,33 @@ void PCSoundFxPlayer::unload() { PCSound::PCSound(Audio::Mixer *mixer, CineEngine *vm) - : Sound(mixer, vm) { - if (_vm->getGameType() == GType_FW) { - _soundDriver = new AdLibSoundDriverINS(_mixer); - } else { - _soundDriver = new AdLibSoundDriverADL(_mixer); + : Sound(mixer, vm), _soundDriver(0) { + + const MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB); + const MusicType musicType = MidiDriver::getMusicType(dev); + if (musicType == MT_MT32 || musicType == MT_GM) { + const bool isMT32 = (musicType == MT_MT32 || ConfMan.getBool("native_mt32")); + if (isMT32) { + MidiDriver *driver = MidiDriver::createMidi(dev); + if (driver && driver->open() == 0) { + driver->sendMT32Reset(); + _soundDriver = new MidiSoundDriverH32(driver); + } else { + warning("Could not create MIDI output, falling back to AdLib"); + } + } else { + warning("General MIDI output devices are not supported, falling back to AdLib"); + } } + + if (!_soundDriver) { + if (_vm->getGameType() == GType_FW) { + _soundDriver = new AdLibSoundDriverINS(_mixer); + } else { + _soundDriver = new AdLibSoundDriverADL(_mixer); + } + } + _player = new PCSoundFxPlayer(_soundDriver); } diff --git a/engines/dreamweb/backdrop.cpp b/engines/dreamweb/backdrop.cpp index 065ce638d4..38ccb0296c 100644 --- a/engines/dreamweb/backdrop.cpp +++ b/engines/dreamweb/backdrop.cpp @@ -24,7 +24,7 @@ namespace DreamGen { -void DreamGenContext::doBlocks() { +void DreamBase::doBlocks() { uint16 dstOffset = data.word(kMapady) * 320 + data.word(kMapadx); uint16 mapOffset = kMap + data.byte(kMapy) * kMapwidth + data.byte(kMapx); const uint8 *mapData = getSegment(data.word(kMapdata)).ptr(mapOffset, 0); @@ -49,7 +49,6 @@ void DreamGenContext::doBlocks() { dst += 320; } dst += 4; - ax = 0x0dfdf; memset(dst, 0xdf, 16); dst += 320; memset(dst, 0xdf, 16); @@ -63,7 +62,7 @@ void DreamGenContext::doBlocks() { } } -uint8 DreamGenContext::getXAd(const uint8 *setData, uint8 *result) { +uint8 DreamBase::getXAd(const uint8 *setData, uint8 *result) { uint8 v0 = setData[0]; uint8 v1 = setData[1]; uint8 v2 = setData[2]; @@ -78,7 +77,7 @@ uint8 DreamGenContext::getXAd(const uint8 *setData, uint8 *result) { return 1; } -uint8 DreamGenContext::getYAd(const uint8 *setData, uint8 *result) { +uint8 DreamBase::getYAd(const uint8 *setData, uint8 *result) { uint8 v0 = setData[3]; uint8 v1 = setData[4]; if (v0 < data.byte(kMapy)) @@ -90,11 +89,7 @@ uint8 DreamGenContext::getYAd(const uint8 *setData, uint8 *result) { return 1; } -void DreamGenContext::getMapAd() { - ch = getMapAd((const uint8 *)es.ptr(si, 5)); -} - -uint8 DreamGenContext::getMapAd(const uint8 *setData) { +uint8 DreamBase::getMapAd(const uint8 *setData) { uint8 xad, yad; if (getXAd(setData, &xad) == 0) return 0; @@ -105,15 +100,8 @@ uint8 DreamGenContext::getMapAd(const uint8 *setData) { return 1; } -void DreamGenContext::calcFrFrame() { - uint8 width, height; - calcFrFrame(&width, &height); - cl = width; - ch = height; -} - -void DreamGenContext::calcFrFrame(uint8* width, uint8* height) { - const Frame *frame = (const Frame *)getSegment(data.word(kFrsegment)).ptr(data.word(kCurrentframe) * sizeof(Frame), sizeof(Frame)); +void DreamBase::calcFrFrame(uint16 frameNum, uint8* width, uint8* height) { + const Frame *frame = (const Frame *)getSegment(data.word(kFrsegment)).ptr(frameNum * sizeof(Frame), sizeof(Frame)); data.word(kSavesource) = data.word(kFramesad) + frame->ptr(); data.byte(kSavesize+0) = frame->width; data.byte(kSavesize+1) = frame->height; @@ -123,21 +111,34 @@ void DreamGenContext::calcFrFrame(uint8* width, uint8* height) { *height = frame->height; } -void DreamGenContext::finalFrame() { - uint16 x, y; - finalFrame(&x, &y); - di = x; - bx = y; -} - -void DreamGenContext::finalFrame(uint16 *x, uint16 *y) { +void DreamBase::finalFrame(uint16 *x, uint16 *y) { data.byte(kSavex) = (data.word(kObjectx) + data.word(kOffsetx)) & 0xff; data.byte(kSavey) = (data.word(kObjecty) + data.word(kOffsety)) & 0xff; *x = data.word(kObjectx); *y = data.word(kObjecty); } -void DreamGenContext::showAllObs() { +void DreamBase::makeBackOb(SetObject *objData) { + if (data.byte(kNewobs) == 0) + return; + uint8 priority = objData->priority; + uint8 type = objData->type; + Sprite *sprite = makeSprite(data.word(kObjectx), data.word(kObjecty), addr_backobject, data.word(kSetframes), 0); + + uint16 objDataOffset = (uint8 *)objData - getSegment(data.word(kSetdat)).ptr(0, 0); + assert(objDataOffset % sizeof(SetObject) == 0); + assert(objDataOffset < 128 * sizeof(SetObject)); + sprite->setObjData(objDataOffset); + if (priority == 255) + priority = 0; + sprite->priority = priority; + sprite->type = type; + sprite->b16 = 0; + sprite->delay = 0; + sprite->animFrame = 0; +} + +void DreamBase::showAllObs() { data.word(kListpos) = kSetlist; memset(getSegment(data.word(kBuffers)).ptr(kSetlist, 0), 0xff, 128 * 5); data.word(kFrsegment) = data.word(kSetframes); @@ -151,17 +152,17 @@ void DreamGenContext::showAllObs() { if (getMapAd(setEntry->mapad) == 0) continue; uint8 currentFrame = setEntry->frames[0]; - data.word(kCurrentframe) = currentFrame; if (currentFrame == 0xff) continue; - calcFrFrame(); + uint8 width, height; + calcFrFrame(currentFrame, &width, &height); uint16 x, y; finalFrame(&x, &y); setEntry->index = setEntry->frames[0]; if ((setEntry->type == 0) && (setEntry->priority != 5) && (setEntry->priority != 6)) { x += data.word(kMapadx); y += data.word(kMapady); - showFrame(frames, x, y, data.word(kCurrentframe), 0); + showFrame(frames, x, y, currentFrame, 0); } else makeBackOb(setEntry); @@ -175,17 +176,7 @@ void DreamGenContext::showAllObs() { } } -void DreamGenContext::getDimension() { - uint8 mapXstart, mapYstart; - uint8 mapXsize, mapYsize; - getDimension(&mapXstart, &mapYstart, &mapXsize, &mapYsize); - cl = mapXstart; - ch = mapYstart; - dl = mapXsize; - dh = mapYsize; -} - -bool DreamGenContext::addAlong(const uint8 *mapFlags) { +bool DreamBase::addAlong(const uint8 *mapFlags) { for (size_t i = 0; i < 11; ++i) { if (mapFlags[3 * i] != 0) return true; @@ -193,7 +184,7 @@ bool DreamGenContext::addAlong(const uint8 *mapFlags) { return false; } -bool DreamGenContext::addLength(const uint8 *mapFlags) { +bool DreamBase::addLength(const uint8 *mapFlags) { for (size_t i = 0; i < 10; ++i) { if (mapFlags[3 * 11 * i] != 0) return true; @@ -201,7 +192,7 @@ bool DreamGenContext::addLength(const uint8 *mapFlags) { return false; } -void DreamGenContext::getDimension(uint8 *mapXstart, uint8 *mapYstart, uint8 *mapXsize, uint8 *mapYsize) { +void DreamBase::getDimension(uint8 *mapXstart, uint8 *mapYstart, uint8 *mapXsize, uint8 *mapYsize) { const uint8 *mapFlags = getSegment(data.word(kBuffers)).ptr(kMapflags, 0); uint8 yStart = 0; @@ -230,7 +221,7 @@ void DreamGenContext::getDimension(uint8 *mapXstart, uint8 *mapYstart, uint8 *ma data.byte(kMapysize) = *mapYsize << 4; } -void DreamGenContext::calcMapAd() { +void DreamBase::calcMapAd() { uint8 mapXstart, mapYstart; uint8 mapXsize, mapYsize; getDimension(&mapXstart, &mapYstart, &mapXsize, &mapYsize); @@ -238,7 +229,7 @@ void DreamGenContext::calcMapAd() { data.word(kMapady) = data.word(kMapoffsety) - 8 * (mapYsize + 2 * mapYstart - 10); } -void DreamGenContext::showAllFree() { +void DreamBase::showAllFree() { data.word(kListpos) = kFreelist; ObjPos *listPos = (ObjPos *)getSegment(data.word(kBuffers)).ptr(kFreelist, 80 * sizeof(ObjPos)); memset(listPos, 0xff, 80 * sizeof(ObjPos)); @@ -248,18 +239,19 @@ void DreamGenContext::showAllFree() { data.word(kFramesad) = kFrframes; data.byte(kCurrentfree) = 0; const DynObject *freeObjects = (const DynObject *)getSegment(data.word(kFreedat)).ptr(0, 0); - for(size_t i = 0; i < 80; ++i) { + for (size_t i = 0; i < 80; ++i) { uint8 mapAd = getMapAd(freeObjects[i].mapad); if (mapAd != 0) { - data.word(kCurrentframe) = 3 * data.byte(kCurrentfree); uint8 width, height; - calcFrFrame(&width, &height); + uint16 currentFrame = 3 * data.byte(kCurrentfree); + calcFrFrame(currentFrame, &width, &height); uint16 x, y; finalFrame(&x, &y); if ((width != 0) || (height != 0)) { x += data.word(kMapadx); y += data.word(kMapady); - showFrame((Frame *)getSegment(data.word(kFrsegment)).ptr(0, 0), x, y, data.word(kCurrentframe) & 0xff, 0); + assert(currentFrame < 256); + showFrame((Frame *)getSegment(data.word(kFrsegment)).ptr(0, 0), x, y, currentFrame, 0); ObjPos *objPos = (ObjPos *)getSegment(data.word(kBuffers)).ptr(data.word(kListpos), sizeof(ObjPos)); objPos->xMin = data.byte(kSavex); objPos->yMin = data.byte(kSavey); @@ -274,7 +266,7 @@ void DreamGenContext::showAllFree() { } } -void DreamGenContext::drawFlags() { +void DreamBase::drawFlags() { uint8 *mapFlags = getSegment(data.word(kBuffers)).ptr(kMapflags, 0); const uint8 *mapData = getSegment(data.word(kMapdata)).ptr(kMap + data.byte(kMapy) * kMapwidth + data.byte(kMapx), 0); const uint8 *backdropFlags = getSegment(data.word(kBackdrop)).ptr(kFlags, 0); @@ -290,7 +282,7 @@ void DreamGenContext::drawFlags() { } } -void DreamGenContext::showAllEx() { +void DreamBase::showAllEx() { data.word(kListpos) = kExlist; memset(getSegment(data.word(kBuffers)).ptr(kExlist, 100 * 5), 0xff, 100 * 5); @@ -307,13 +299,14 @@ void DreamGenContext::showAllEx() { continue; if (getMapAd(object->mapad) == 0) continue; - data.word(kCurrentframe) = 3 * data.byte(kCurrentex); uint8 width, height; - calcFrFrame(&width, &height); + uint16 currentFrame = 3 * data.byte(kCurrentex); + calcFrFrame(currentFrame, &width, &height); uint16 x, y; finalFrame(&x, &y); if ((width != 0) || (height != 0)) { - showFrame((Frame *)getSegment(data.word(kFrsegment)).ptr(0, 0), x + data.word(kMapadx), y + data.word(kMapady), data.word(kCurrentframe) & 0xff, 0); + assert(currentFrame < 256); + showFrame((Frame *)getSegment(data.word(kFrsegment)).ptr(0, 0), x + data.word(kMapadx), y + data.word(kMapady), currentFrame, 0); ObjPos *objPos = (ObjPos *)getSegment(data.word(kBuffers)).ptr(data.word(kListpos), sizeof(ObjPos)); objPos->xMin = data.byte(kSavex); objPos->yMin = data.byte(kSavey); diff --git a/engines/dreamweb/detection.cpp b/engines/dreamweb/detection.cpp index a3f311c304..3a5c28a104 100644 --- a/engines/dreamweb/detection.cpp +++ b/engines/dreamweb/detection.cpp @@ -25,7 +25,10 @@ #include "common/algorithm.h" #include "common/system.h" +#include "graphics/thumbnail.h" + #include "dreamweb/dreamweb.h" +#include "dreamweb/structs.h" static const PlainGameDescriptor dreamWebGames[] = { { "dreamweb", "DreamWeb" }, @@ -56,6 +59,7 @@ public: 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 DreamWebMetaEngine::hasFeature(MetaEngineFeature f) const { @@ -63,6 +67,10 @@ bool DreamWebMetaEngine::hasFeature(MetaEngineFeature f) const { case kSupportsListSaves: case kSupportsLoadingDuringStartup: case kSupportsDeleteSave: + case kSavesSupportMetaInfo: + case kSavesSupportThumbnail: + case kSavesSupportCreationDate: + case kSavesSupportPlayTime: return true; default: return false; @@ -95,7 +103,7 @@ SaveStateList DreamWebMetaEngine::listSaves(const char *target) const { Common::sort(files.begin(), files.end()); SaveStateList saveList; - for(uint i = 0; i < files.size(); ++i) { + for (uint i = 0; i < files.size(); ++i) { const Common::String &file = files[i]; Common::InSaveFile *stream = saveFileMan->openForLoading(file); if (!stream) @@ -116,6 +124,71 @@ SaveStateList DreamWebMetaEngine::listSaves(const char *target) const { int DreamWebMetaEngine::getMaximumSaveSlot() const { return 99; } void DreamWebMetaEngine::removeSaveState(const char *target, int slot) const { + Common::String fileName = Common::String::format("DREAMWEB.D%02d", slot); + g_system->getSavefileManager()->removeSavefile(fileName); +} + +SaveStateDescriptor DreamWebMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + Common::String filename = Common::String::format("DREAMWEB.D%02d", slot); + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str()); + + if (in) { + DreamGen::FileHeader header; + in->read((uint8 *)&header, sizeof(DreamGen::FileHeader)); + + Common::String saveName; + byte descSize = header.len(0); + byte i; + + for (i = 0; i < descSize; i++) + saveName += (char)in->readByte(); + + SaveStateDescriptor desc(slot, saveName); + desc.setDeletableFlag(true); + desc.setWriteProtectedFlag(false); + + // Check if there is a ScummVM data block + if (header.len(6) == SCUMMVM_BLOCK_MAGIC_SIZE) { + // Skip the game data + for (i = 1; i <= 5; i++) + in->skip(header.len(i)); + + uint32 tag = in->readUint32BE(); + if (tag != SCUMMVM_HEADER) { + warning("ScummVM data block found, but the block header is incorrect - skipping"); + delete in; + return desc; + } + + byte version = in->readByte(); + if (version > SAVEGAME_VERSION) { + warning("ScummVM data block found, but it has been saved with a newer version of ScummVM - skipping"); + delete in; + return desc; + } + + uint32 saveDate = in->readUint32LE(); + uint32 saveTime = in->readUint32LE(); + uint32 playTime = in->readUint32LE(); + Graphics::Surface *thumbnail = Graphics::loadThumbnail(*in); + + int day = (saveDate >> 24) & 0xFF; + int month = (saveDate >> 16) & 0xFF; + int year = saveDate & 0xFFFF; + int hour = (saveTime >> 16) & 0xFF; + int minutes = (saveTime >> 8) & 0xFF; + + desc.setSaveDate(year, month, day); + desc.setSaveTime(hour, minutes); + desc.setPlayTime(playTime * 1000); + desc.setThumbnail(thumbnail); + } + + delete in; + return desc; + } + + return SaveStateDescriptor(); } #if PLUGIN_ENABLED_DYNAMIC(DREAMWEB) diff --git a/engines/dreamweb/dreambase.h b/engines/dreamweb/dreambase.h index 99cb8476e1..6de854f452 100644 --- a/engines/dreamweb/dreambase.h +++ b/engines/dreamweb/dreambase.h @@ -25,7 +25,7 @@ #include "common/scummsys.h" -#include "dreamweb/runtime.h" +#include "dreamweb/segment.h" namespace DreamWeb { class DreamWebEngine; @@ -34,6 +34,9 @@ namespace DreamWeb { namespace DreamGen { + +const unsigned int kNumReelRoutines = 57; + /** * This class is one of the parent classes of DreamGenContext. Its sole purpose * is to allow us to incrementally move things out of DreamGenContext into this @@ -43,45 +46,450 @@ namespace DreamGen { * together with class Context. When that happens, we can probably merge * DreamBase into DreamWebEngine. */ -class DreamBase { +class DreamBase : public SegmentManager { protected: DreamWeb::DreamWebEngine *engine; -public: - enum { kDefaultDataSegment = 0x1000 }; + // from object.cpp + uint16 _openChangeSize; + + // from pathfind.cpp + Common::Point _lineData[200]; // Output of Bresenham + + // from saveload.cpp + char _saveNames[17*7]; + char _saveNamesOld[17*7]; + + // from vgagrafx.cpp + uint8 _workspace[(0x1000 + 2) * 16]; - SegmentPtr _realData; ///< the primary data segment, points to a huge blob of binary data - SegmentRef data; ///< fake segment register always pointing to data segment + // from people.cpp + ReelRoutine _reelRoutines[kNumReelRoutines+1]; - DreamBase(DreamWeb::DreamWebEngine *en) : - engine(en), - _realData(new Segment()), - data(kDefaultDataSegment, _realData) { - } +public: + DreamBase(DreamWeb::DreamWebEngine *en); public: + // from backdrop.cpp + void doBlocks(); + uint8 getXAd(const uint8 *setData, uint8 *result); + uint8 getYAd(const uint8 *setData, uint8 *result); + uint8 getMapAd(const uint8 *setData); + void calcFrFrame(uint16 frame, uint8* width, uint8* height); + void finalFrame(uint16 *x, uint16 *y); + void makeBackOb(SetObject *objData); + void showAllObs(); + bool addAlong(const uint8 *mapFlags); + bool addLength(const uint8 *mapFlags); + void getDimension(uint8 *mapXstart, uint8 *mapYstart, uint8 *mapXsize, uint8 *mapYsize); + void calcMapAd(); + void showAllFree(); + void drawFlags(); + void showAllEx(); + + // from keypad.cpp + void getUnderMenu(); + void putUnderMenu(); + void singleKey(uint8 key, uint16 x, uint16 y); + void loadKeypad(); + void showKeypad(); + bool isItRight(uint8 digit0, uint8 digit1, uint8 digit2, uint8 digit3); + void addToPressList(); + void buttonOne(); + void buttonTwo(); + void buttonThree(); + void buttonFour(); + void buttonFive(); + void buttonSix(); + void buttonSeven(); + void buttonEight(); + void buttonNine(); + void buttonNought(); + void buttonEnter(); + void buttonPress(uint8 buttonId); + void showOuterPad(); + void dumpKeypad(); + void dumpSymbol(); + void dumpSymBox(); + void quitSymbol(); + + // from monitor.cpp + void input(); + byte makeCaps(byte c); + void delChar(); + void monMessage(uint8 index); + void netError(); + void monitorLogo(); + void randomAccess(uint16 count); + void printOuterMon(); + void showCurrentFile(); + void accessLightOn(); + void accessLightOff(); + void turnOnPower(); + void powerLightOn(); + void powerLightOff(); + void printLogo(); + void scrollMonitor(); + const char *monPrint(const char *string); + void lockLightOn(); + void lockLightOff(); + void loadPersonal(); + void loadNews(); + void loadCart(); + + // from object.cpp + void obIcons(); + void fillRyan(); + void findAllRyan(uint8 *inv); + void obToInv(uint8 index, uint8 flag, uint16 x, uint16 y); + void obPicture(); + void removeObFromInv(); + void deleteExObject(uint8 index); + void deleteExFrame(uint8 frameNum); + void deleteExText(uint8 textNum); + // from pathfind.cpp - Common::Point _lineData[200]; // Output of Bresenham + void turnPathOn(uint8 param); + void turnPathOff(uint8 param); + void turnAnyPathOn(uint8 param, uint8 room); + void turnAnyPathOff(uint8 param, uint8 room); + RoomPaths *getRoomsPaths(); + void faceRightWay(); + void setWalk(); + void autoSetWalk(); void checkDest(const RoomPaths *roomsPaths); + void findXYFromPath(); + bool checkIfPathIsOn(uint8 index); + void bresenhams(); + void workoutFrames(); + + // from people.cpp + void setupInitialReelRoutines(); + void updatePeople(); + void madmanText(); + void madman(ReelRoutine &routine); + void madMode(); + void addToPeopleList(ReelRoutine *routine); + bool checkSpeed(ReelRoutine &routine); + void sparkyDrip(ReelRoutine &routine); + void genericPerson(ReelRoutine &routine); + void gamer(ReelRoutine &routine); + void eden(ReelRoutine &routine); + void sparky(ReelRoutine &routine); + void rockstar(ReelRoutine &routine); + void madmansTelly(ReelRoutine &routine); + void smokeBloke(ReelRoutine &routine); + void manAsleep(ReelRoutine &routine); + void drunk(ReelRoutine &routine); + void introMagic1(ReelRoutine &routine); + void introMagic2(ReelRoutine &routine); + void introMagic3(ReelRoutine &routine); + void introMusic(ReelRoutine &routine); + void candles(ReelRoutine &routine); + void candles1(ReelRoutine &routine); + void candles2(ReelRoutine &routine); + void smallCandle(ReelRoutine &routine); + void gates(ReelRoutine &routine); + void security(ReelRoutine &routine); + void edenInBath(ReelRoutine &routine); + void louis(ReelRoutine &routine); + void handClap(ReelRoutine &routine); + void carParkDrip(ReelRoutine &routine); + void foghornSound(ReelRoutine &routine); + void train(ReelRoutine &routine); + void attendant(ReelRoutine &routine); + void keeper(ReelRoutine &routine); + void interviewer(ReelRoutine &routine); + void drinker(ReelRoutine &routine); + void alleyBarkSound(ReelRoutine &routine); + void louisChair(ReelRoutine &routine); + void bossMan(ReelRoutine &routine); + void priest(ReelRoutine &routine); + void monkAndRyan(ReelRoutine &routine); + void copper(ReelRoutine &routine); + void introMonks1(ReelRoutine &routine); + void introMonks2(ReelRoutine &routine); + void soldier1(ReelRoutine &routine); + void receptionist(ReelRoutine &routine); + void bartender(ReelRoutine &routine); + void heavy(ReelRoutine &routine); + void helicopter(ReelRoutine &routine); + void mugger(ReelRoutine &routine); + void businessMan(ReelRoutine &routine); + void endGameSeq(ReelRoutine &routine); + void poolGuard(ReelRoutine &routine); // from print.cpp uint8 getNextWord(const Frame *charSet, const uint8 *string, uint8 *totalWidth, uint8 *charCount); + void printChar(const Frame* charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height); + void printChar(const Frame* charSet, uint16 x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height); + void printBoth(const Frame* charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar); + uint8 printDirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered); + uint8 printDirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered); uint8 getNumber(const Frame *charSet, const uint8 *string, uint16 maxWidth, bool centered, uint16 *offset); uint8 kernChars(uint8 firstChar, uint8 secondChar, uint8 width); + uint8 printSlow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered); + uint16 waitFrames(); + void printCurs(); + void delCurs(); + + // from saveload.cpp + void oldToNames(); + void namesToOld(); + void showMainOps(); + void showDiscOps(); + void showNames(); + void loadPosition(unsigned int slot); + void savePosition(unsigned int slot, const char *descbuf); + + // from sound.cpp + bool loadSpeech(byte type1, int idx1, byte type2, int idx2); + void volumeAdjust(); + void cancelCh0(); + void cancelCh1(); + void loadRoomsSample(); + void playChannel0(uint8 index, uint8 repeat); + void playChannel1(uint8 index); + + // from sprite.cpp + Sprite *spriteTable(); + void printSprites(); + void printASprite(const Sprite *sprite); + void clearSprites(); + Sprite *makeSprite(uint8 x, uint8 y, uint16 updateCallback, uint16 frameData, uint16 somethingInDi); + void initMan(); + void walking(Sprite *sprite); + void aboutTurn(Sprite *sprite); + void backObject(Sprite *sprite); + void constant(Sprite *sprite, SetObject *objData); + void randomSprite(Sprite *sprite, SetObject *objData); + void doorway(Sprite *sprite, SetObject *objData); + void wideDoor(Sprite *sprite, SetObject *objData); + void doDoor(Sprite *sprite, SetObject *objData, Common::Rect check); + void steady(Sprite *sprite, SetObject *objData); + void lockedDoorway(Sprite *sprite, SetObject *objData); + void liftSprite(Sprite *sprite, SetObject *objData); + + Reel *getReelStart(uint16 reelPointer); + const Frame *findSource(uint16 &frame); + void showReelFrame(Reel *reel); + void showGameReel(ReelRoutine *routine); + const Frame *getReelFrameAX(uint16 frame); + void moveMap(uint8 param); + void checkOne(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uint8 *type, uint8 *flagX, uint8 *flagY); + + uint8 getBlockOfPixel(uint8 x, uint8 y); + Rain *splitIntoLines(uint8 x, uint8 y, Rain *rain); + void initRain(); + + void intro1Text(); + void intro2Text(uint16 nextReelPointer); + void intro3Text(uint16 nextReelPointer); + + void rollEndCredits(); + void monks2text(); + void textForEnd(); + void textForMonkHelper(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount); + void textForMonk(); + void priestText(ReelRoutine &routine); + void soundOnReels(uint16 reelPointer); + void clearBeforeLoad(); + void clearReels(); + void getRidOfReels(); + void liftNoise(uint8 index); + void checkForExit(Sprite *sprite); + void mainMan(Sprite *sprite); + void spriteUpdate(); + void showRain(); + void reconstruct(); + void reelsOnScreen(); // from stubs.cpp + bool isCD(); void crosshair(); + void delTextLine(); void showBlink(); void dumpBlink(); void dumpPointer(); + void showPointer(); + void delPointer(); void showRyanPage(); - void volumeAdjust(); + void switchRyanOn(); + void switchRyanOff(); + Frame *tempGraphics(); + Frame *tempGraphics2(); + Frame *tempGraphics3(); + void showArrows(); + void showOpBox(); + void middlePanel(); + void showDiary(); + void readMouse(); + uint16 readMouseState(); + void hangOn(uint16 frameCount); + bool quitRequested(); + void lockMon(); + uint8 *textUnder(); + void readKey(); + void findOrMake(uint8 index, uint8 value, uint8 type); + DynObject *getFreeAd(uint8 index); + DynObject *getExAd(uint8 index); + DynObject *getEitherAdCPP(); + void *getAnyAdDir(uint8 index, uint8 flag); + void showWatch(); + void showTime(); + void showExit(); + void showMan(); + void panelIcons1(); + SetObject *getSetAd(uint8 index); + void *getAnyAd(uint8 *value1, uint8 *value2); + const uint8 *getTextInFile1(uint16 index); + uint8 findNextColon(const uint8 **string); + void allocateBuffers(); + uint16 allocateMem(uint16 paragraphs); + void deallocateMem(uint16 segment); + uint16 allocateAndLoad(unsigned int size); + uint16 standardLoad(const char *fileName, uint16 *outSizeInBytes = NULL); // Returns a segment handle which needs to be freed with deallocatemem for symmetry + void *standardLoadCPP(const char *fileName, uint16 *outSizeInBytes = NULL); // And this one should be 'free'd + void loadIntoTemp(const char *fileName); + void loadIntoTemp2(const char *fileName); + void loadIntoTemp3(const char *fileName); + void loadTempCharset(const char *fileName); + void loadTravelText(); + void loadTempText(const char *fileName); + void clearAndLoad(uint8 *buf, uint8 c, unsigned int size, unsigned int maxSize); + void clearAndLoad(uint16 seg, uint8 c, unsigned int size, unsigned int maxSize); + void sortOutMap(); + void loadRoomData(const Room &room, bool skipDat); + void useTempCharset(); + void useCharset1(); + void printMessage(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered); + void printMessage2(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered, uint8 count); + bool isItDescribed(const ObjPos *objPos); + void zoomIcon(); + void roomName(); + void showIcon(); + void eraseOldObs(); + void commandOnly(uint8 command); + void blank(); + void setTopLeft(); + void setTopRight(); + void setBotLeft(); + void setBotRight(); + void examIcon(); + void animPointer(); + void getFlagUnderP(uint8 *flag, uint8 *flagEx); + void workToScreenM(); + void quitKey(); + void restoreReels(); + void loadFolder(); + void folderHints(); + void folderExit(); + void showFolder(); + void showLeftPage(); + void showRightPage(); + void underTextLine(); + void hangOnP(uint16 count); + void getUnderZoom(); + void putUnderZoom(); + void examineInventory(); + void openInv(); + void getBack1(); + void getBackFromOb(); + void getBackFromOps(); + void getBackToOps(); + void DOSReturn(); + bool isItWorn(const DynObject *object); + bool compare(uint8 index, uint8 flag, const char id[4]); + void hangOnW(uint16 frameCount); + void getRidOfTemp(); + void getRidOfTempText(); + void getRidOfTemp2(); + void getRidOfTemp3(); + void getRidOfTempCharset(); + void getRidOfTempsP(); + void getRidOfAll(); + void placeSetObject(uint8 index); + void removeSetObject(uint8 index); + bool isSetObOnMap(uint8 index); + void dumpZoom(); + void diaryKeyP(); + void diaryKeyN(); + void findRoomInLoc(); + void loadMenu(); + void showMenu(); + void dumpMenu(); + void dealWithSpecial(uint8 firstParam, uint8 secondParam); + void plotReel(uint16 &reelPointer); + void setupTimedTemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount); + void getUnderTimed(); + void putUnderTimed(); + void dumpTextLine(); + void useTimedText(); + void dumpTimedText(); + void getTime(); + void doChange(uint8 index, uint8 value, uint8 type); + bool isRyanHolding(const char *id); + void clearBuffers(); + void clearChanges(); + void drawFloor(); + uint16 findSetObject(const char *id); + void hangOnCurs(uint16 frameCount); + const uint8 *findObName(uint8 type, uint8 index); + void copyName(uint8 type, uint8 index, uint8 *dst); + uint16 findExObject(const char *id); + void makeMainScreen(); + void showWatchReel(); + void watchReel(); + + // from use.cpp + void placeFreeObject(uint8 index); + void removeFreeObject(uint8 index); + void setupTimedUse(uint16 offset, uint16 countToTimed, uint16 timeCount, byte x, byte y); + void withWhat(); + uint16 checkInside(uint16 command, uint16 type); + void showPuzText(uint16 command, uint16 count); + + // from vgafades.cpp + uint8 *mainPalette(); + uint8 *startPalette(); + uint8 *endPalette(); + void clearStartPal(); + void clearEndPal(); + void palToStartPal(); + void endPalToStart(); + void startPalToEnd(); + void palToEndPal(); + void fadeDOS(); + void doFade(); + void fadeCalculation(); + void fadeupYellows(); + void fadeupMonFirst(); + void fadeScreenUp(); + void fadeScreenUps(); + void fadeScreenUpHalf(); + void fadeScreenDown(); + void fadeScreenDowns(); + void fadeScreenDownHalf(); + void clearPalette(); + void greyscaleSum(); + void allPalette(); + void dumpCurrent(); // from vgagrafx.cpp - uint8 _workspace[(0x1000 + 2) * 16]; inline uint8 *workspace() { return _workspace; } void clearWork(); + uint8 getLocation(uint8 index); + void setLocation(uint8 index); + void getUnderCentre(); + void putUnderCentre(); + uint8 *mapStore(); + void panelToMap(); + void mapToPanel(); + void dumpMap(); + + void transferInv(); + void multiGet(uint8 *dst, uint16 x, uint16 y, uint8 width, uint8 height); void multiPut(const uint8 *src, uint16 x, uint16 y, uint8 width, uint8 height); void multiDump(uint16 x, uint16 y, uint8 width, uint8 height); @@ -93,12 +501,16 @@ public: void frameOutBh(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y); void frameOutFx(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y); void doShake(); + void vSync(); + void setMode(); void showPCX(const Common::String &name); void showFrame(const Frame *frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height); void showFrame(const Frame *frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag); + void loadPalFromIFF(); void createPanel(); void createPanel2(); void showPanel(); + void entryTexts(); }; diff --git a/engines/dreamweb/dreamgen.cpp b/engines/dreamweb/dreamgen.cpp index 965306313d..a0ce29d416 100644 --- a/engines/dreamweb/dreamgen.cpp +++ b/engines/dreamweb/dreamgen.cpp @@ -26,996 +26,6 @@ namespace DreamGen { -void DreamGenContext::receptionist() { - STACK_CHECK; - checkSpeed(); - if (!flags.z()) - goto gotrecep; - _cmp(data.byte(kCardpassflag), 1); - if (!flags.z()) - goto notsetcard; - _inc(data.byte(kCardpassflag)); - es.byte(bx+7) = 1; - es.word(bx+3) = 64; -notsetcard: - _cmp(es.word(bx+3), 58); - if (!flags.z()) - goto notdes1; - randomNumber(); - _cmp(al, 30); - if (flags.c()) - goto notdes2; - es.word(bx+3) = 55; - goto gotrecep; -notdes1: - _cmp(es.word(bx+3), 60); - if (!flags.z()) - goto notdes2; - randomNumber(); - _cmp(al, 240); - if (flags.c()) - goto gotrecep; - es.word(bx+3) = 53; - goto gotrecep; -notdes2: - _cmp(es.word(bx+3), 88); - if (!flags.z()) - goto notendcard; - es.word(bx+3) = 53; - goto gotrecep; -notendcard: - _inc(es.word(bx+3)); -gotrecep: - showGameReel(); - addToPeopleList(); - al = es.byte(bx+7); - _and(al, 128); - if (flags.z()) - return /* (nottalkedrecep) */; - data.byte(kTalkedtorecep) = 1; -} - -void DreamGenContext::bartender() { - STACK_CHECK; - checkSpeed(); - if (!flags.z()) - goto gotsmoket; - _cmp(es.word(bx+3), 86); - if (!flags.z()) - goto notsmoket1; - randomNumber(); - _cmp(al, 18); - if (flags.c()) - goto notsmoket2; - es.word(bx+3) = 81; - goto gotsmoket; -notsmoket1: - _cmp(es.word(bx+3), 103); - if (!flags.z()) - goto notsmoket2; - es.word(bx+3) = 81; - goto gotsmoket; -notsmoket2: - _inc(es.word(bx+3)); -gotsmoket: - showGameReel(); - _cmp(data.byte(kGunpassflag), 1); - if (!flags.z()) - goto notgotgun; - es.byte(bx+7) = 9; -notgotgun: - addToPeopleList(); -} - -void DreamGenContext::soldier1() { - STACK_CHECK; - _cmp(es.word(bx+3), 0); - if (flags.z()) - goto soldierwait; - data.word(kWatchingtime) = 10; - _cmp(es.word(bx+3), 30); - if (!flags.z()) - goto notaftersshot; - _inc(data.byte(kCombatcount)); - _cmp(data.byte(kCombatcount), 40); - if (!flags.z()) - goto gotsoldframe; - data.byte(kMandead) = 2; - goto gotsoldframe; -notaftersshot: - checkSpeed(); - if (!flags.z()) - goto gotsoldframe; - _inc(es.word(bx+3)); - goto gotsoldframe; -soldierwait: - _cmp(data.byte(kLastweapon), 1); - if (!flags.z()) - goto gotsoldframe; - data.word(kWatchingtime) = 10; - _cmp(data.byte(kManspath), 2); - if (!flags.z()) - goto gotsoldframe; - _cmp(data.byte(kFacing), 4); - if (!flags.z()) - goto gotsoldframe; - _inc(es.word(bx+3)); - data.byte(kLastweapon) = -1; - data.byte(kCombatcount) = 0; -gotsoldframe: - showGameReel(); - addToPeopleList(); -} - -void DreamGenContext::helicopter() { - STACK_CHECK; - ax = es.word(bx+3); - _cmp(ax, 203); - if (flags.z()) - goto heliwon; - checkSpeed(); - if (!flags.z()) - goto helispeed; - ax = es.word(bx+3); - _inc(ax); - _cmp(ax, 53); - if (!flags.z()) - goto notbeforehdead; - _inc(data.byte(kCombatcount)); - _cmp(data.byte(kCombatcount), 8); - if (flags.c()) - goto waitabit; - data.byte(kMandead) = 2; -waitabit: - ax = 49; - goto gotheliframe; -notbeforehdead: - _cmp(ax, 9); - if (!flags.z()) - goto gotheliframe; - _dec(ax); - _cmp(data.byte(kLastweapon), 1); - if (!flags.z()) - goto notgunonheli; - data.byte(kLastweapon) = -1; - ax = 55; - goto gotheliframe; -notgunonheli: - ax = 5; - _inc(data.byte(kCombatcount)); - _cmp(data.byte(kCombatcount), 20); - if (!flags.z()) - goto gotheliframe; - data.byte(kCombatcount) = 0; - ax = 9; -gotheliframe: - es.word(bx+3) = ax; -helispeed: - showGameReel(); - al = data.byte(kMapx); - es.byte(bx+1) = al; - ax = es.word(bx+3); - _cmp(ax, 9); - if (!flags.c()) - goto notwaitingheli; - _cmp(data.byte(kCombatcount), 7); - if (flags.c()) - goto notwaitingheli; - data.byte(kPointermode) = 2; - data.word(kWatchingtime) = 0; - return; -notwaitingheli: - data.byte(kPointermode) = 0; - data.word(kWatchingtime) = 2; - return; -heliwon: - data.byte(kPointermode) = 0; -} - -void DreamGenContext::mugger() { - STACK_CHECK; - ax = es.word(bx+3); - _cmp(ax, 138); - if (flags.z()) - goto endmugger1; - _cmp(ax, 176); - if (flags.z()) - return /* (endmugger2) */; - _cmp(ax, 2); - if (!flags.z()) - goto havesetwatch; - data.word(kWatchingtime) = 175*2; -havesetwatch: - checkSpeed(); - if (!flags.z()) - goto notmugger; - _inc(es.word(bx+3)); -notmugger: - showGameReel(); - al = data.byte(kMapx); - es.byte(bx+1) = al; - return; -endmugger1: - push(es); - push(bx); - createPanel2(); - showIcon(); - al = 41; - findPuzText(); - di = 33+20; - bx = 104; - dl = 241; - ah = 0; - printDirect(); - workToScreen(); - cx = 300; - hangOn(); - bx = pop(); - es = pop(); - push(es); - push(bx); - es.word(bx+3) = 140; - data.byte(kManspath) = 2; - data.byte(kFinaldest) = 2; - findXYFromPath(); - data.byte(kResetmanxy) = 1; - al = 'W'; - ah = 'E'; - cl = 'T'; - ch = 'A'; - findExObject(); - data.byte(kCommand) = al; - data.byte(kObjecttype) = 4; - removeObFromInv(); - al = 'W'; - ah = 'E'; - cl = 'T'; - ch = 'B'; - findExObject(); - data.byte(kCommand) = al; - data.byte(kObjecttype) = 4; - removeObFromInv(); - makeMainScreen(); - al = 48; - bl = 68-32; - bh = 54+64; - cx = 70; - dx = 10; - setupTimedUse(); - data.byte(kBeenmugged) = 1; - bx = pop(); - es = pop(); -} - -void DreamGenContext::businessMan() { - STACK_CHECK; - data.byte(kPointermode) = 0; - data.word(kWatchingtime) = 2; - ax = es.word(bx+3); - _cmp(ax, 2); - if (!flags.z()) - goto notfirstbiz; - push(ax); - push(bx); - push(es); - al = 49; - cx = 30; - dx = 1; - bl = 68; - bh = 174; - setupTimedUse(); - es = pop(); - bx = pop(); - ax = pop(); -notfirstbiz: - _cmp(ax, 95); - if (flags.z()) - goto buscombatwonend; - _cmp(ax, 49); - if (flags.z()) - return /* (buscombatend) */; - checkSpeed(); - if (!flags.z()) - goto busspeed; - ax = es.word(bx+3); - _inc(ax); - _cmp(ax, 48); - if (!flags.z()) - goto notbeforedeadb; - data.byte(kMandead) = 2; - goto gotbusframe; -notbeforedeadb: - _cmp(ax, 15); - if (!flags.z()) - goto buscombatwon; - _dec(ax); - _cmp(data.byte(kLastweapon), 3); - if (!flags.z()) - goto notshieldonbus; - data.byte(kLastweapon) = -1; - data.byte(kCombatcount) = 0; - ax = 51; - goto gotbusframe; -notshieldonbus: - _inc(data.byte(kCombatcount)); - _cmp(data.byte(kCombatcount), 20); - if (!flags.z()) - goto gotbusframe; - data.byte(kCombatcount) = 0; - ax = 15; - goto gotbusframe; -buscombatwon: - _cmp(ax, 91); - if (!flags.z()) - goto gotbusframe; - push(bx); - push(es); - al = 0; - turnPathOn(); - al = 1; - turnPathOn(); - al = 2; - turnPathOn(); - al = 3; - turnPathOff(); - data.byte(kManspath) = 5; - data.byte(kFinaldest) = 5; - findXYFromPath(); - data.byte(kResetmanxy) = 1; - es = pop(); - bx = pop(); - ax = 92; - goto gotbusframe; -gotbusframe: - es.word(bx+3) = ax; -busspeed: - showGameReel(); - al = data.byte(kMapy); - es.byte(bx+2) = al; - ax = es.word(bx+3); - _cmp(ax, 14); - if (!flags.z()) - return /* (buscombatend) */; - data.word(kWatchingtime) = 0; - data.byte(kPointermode) = 2; - return; -buscombatwonend: - data.byte(kPointermode) = 0; - data.word(kWatchingtime) = 0; -} - -void DreamGenContext::poolGuard() { - STACK_CHECK; - ax = es.word(bx+3); - _cmp(ax, 214); - if (flags.z()) - goto combatover2; - _cmp(ax, 258); - if (flags.z()) - goto combatover2; - _cmp(ax, 185); - if (flags.z()) - goto combatover1; - _cmp(ax, 0); - if (!flags.z()) - goto notfirstpool; - al = 0; - turnPathOn(); -notfirstpool: - checkSpeed(); - if (!flags.z()) - goto guardspeed; - ax = es.word(bx+3); - _inc(ax); - _cmp(ax, 122); - if (!flags.z()) - goto notendguard1; - _dec(ax); - _cmp(data.byte(kLastweapon), 2); - if (!flags.z()) - goto notaxeonpool; - data.byte(kLastweapon) = -1; - ax = 122; - goto gotguardframe; -notaxeonpool: - _inc(data.byte(kCombatcount)); - _cmp(data.byte(kCombatcount), 40); - if (!flags.z()) - goto gotguardframe; - data.byte(kCombatcount) = 0; - ax = 195; - goto gotguardframe; -notendguard1: - _cmp(ax, 147); - if (!flags.z()) - goto gotguardframe; - _dec(ax); - _cmp(data.byte(kLastweapon), 1); - if (!flags.z()) - goto notgunonpool; - data.byte(kLastweapon) = -1; - ax = 147; - goto gotguardframe; -notgunonpool: - _inc(data.byte(kCombatcount)); - _cmp(data.byte(kCombatcount), 40); - if (!flags.z()) - goto gotguardframe; - data.byte(kCombatcount) = 0; - ax = 220; -gotguardframe: - es.word(bx+3) = ax; -guardspeed: - showGameReel(); - ax = es.word(bx+3); - _cmp(ax, 121); - if (flags.z()) - goto iswaitingpool; - _cmp(ax, 146); - if (flags.z()) - goto iswaitingpool; - data.byte(kPointermode) = 0; - data.word(kWatchingtime) = 2; - return; -iswaitingpool: - data.byte(kPointermode) = 2; - data.word(kWatchingtime) = 0; - return; -combatover1: - data.word(kWatchingtime) = 0; - data.byte(kPointermode) = 0; - al = 0; - turnPathOn(); - al = 1; - turnPathOff(); - return; -combatover2: - showGameReel(); - data.word(kWatchingtime) = 2; - data.byte(kPointermode) = 0; - _inc(data.byte(kCombatcount)); - _cmp(data.byte(kCombatcount), 100); - if (flags.c()) - return /* (doneover2) */; - data.word(kWatchingtime) = 0; - data.byte(kMandead) = 2; -} - -void DreamGenContext::heavy() { - STACK_CHECK; - al = es.byte(bx+7); - _and(al, 127); - es.byte(bx+7) = al; - _cmp(es.word(bx+3), 43); - if (flags.z()) - goto heavywait; - data.word(kWatchingtime) = 10; - _cmp(es.word(bx+3), 70); - if (!flags.z()) - goto notafterhshot; - _inc(data.byte(kCombatcount)); - _cmp(data.byte(kCombatcount), 80); - if (!flags.z()) - goto gotheavyframe; - data.byte(kMandead) = 2; - goto gotheavyframe; -notafterhshot: - checkSpeed(); - if (!flags.z()) - goto gotheavyframe; - _inc(es.word(bx+3)); - goto gotheavyframe; -heavywait: - _cmp(data.byte(kLastweapon), 1); - if (!flags.z()) - goto gotheavyframe; - _cmp(data.byte(kManspath), 5); - if (!flags.z()) - goto gotheavyframe; - _cmp(data.byte(kFacing), 4); - if (!flags.z()) - goto gotheavyframe; - data.byte(kLastweapon) = -1; - _inc(es.word(bx+3)); - data.byte(kCombatcount) = 0; -gotheavyframe: - showGameReel(); - addToPeopleList(); -} - -void DreamGenContext::introMonks1() { - STACK_CHECK; - checkSpeed(); - if (!flags.z()) - goto intromonk1fin; - ax = es.word(bx+3); - _inc(ax); - _cmp(ax, 80); - if (!flags.z()) - goto notendmonk1; - _add(data.byte(kMapy), 10); - data.byte(kNowinnewroom) = 1; - showGameReel(); - return; -notendmonk1: - _cmp(ax, 30); - if (!flags.z()) - goto gotintromonk1; - _sub(data.byte(kMapy), 10); - data.byte(kNowinnewroom) = 1; - ax = 51; -gotintromonk1: - es.word(bx+3) = ax; - _cmp(ax, 5); - if (flags.z()) - goto waitstep; - _cmp(ax, 15); - if (flags.z()) - goto waitstep; - _cmp(ax, 25); - if (flags.z()) - goto waitstep; - _cmp(ax, 61); - if (flags.z()) - goto waitstep; - _cmp(ax, 71); - if (flags.z()) - goto waitstep; - goto intromonk1fin; -waitstep: - push(es); - push(bx); - intro2Text(); - bx = pop(); - es = pop(); - es.byte(bx+6) = -20; -intromonk1fin: - showGameReel(); - al = data.byte(kMapy); - es.byte(bx+2) = al; -} - -void DreamGenContext::introMonks2() { - STACK_CHECK; - checkSpeed(); - if (!flags.z()) - goto intromonk2fin; - ax = es.word(bx+3); - _inc(ax); - _cmp(ax, 87); - if (!flags.z()) - goto nottalk1; - _inc(data.byte(kIntrocount)); - push(es); - push(bx); - monks2text(); - bx = pop(); - es = pop(); - _cmp(data.byte(kIntrocount), 19); - if (!flags.z()) - goto notlasttalk1; - ax = 87; - goto gotintromonk2; -notlasttalk1: - ax = 74; - goto gotintromonk2; -nottalk1: - _cmp(ax, 110); - if (!flags.z()) - goto notraisearm; - _inc(data.byte(kIntrocount)); - push(es); - push(bx); - monks2text(); - bx = pop(); - es = pop(); - _cmp(data.byte(kIntrocount), 35); - if (!flags.z()) - goto notlastraise; - ax = 111; - goto gotintromonk2; -notlastraise: - ax = 98; - goto gotintromonk2; -notraisearm: - _cmp(ax, 176); - if (!flags.z()) - goto notendmonk2; - data.byte(kGetback) = 1; - goto gotintromonk2; -notendmonk2: - _cmp(ax, 125); - if (!flags.z()) - goto gotintromonk2; - ax = 140; -gotintromonk2: - es.word(bx+3) = ax; -intromonk2fin: - showGameReel(); -} - -void DreamGenContext::endGameSeq() { - STACK_CHECK; - checkSpeed(); - if (!flags.z()) - goto notendseq; - ax = es.word(bx+3); - _inc(ax); - _cmp(ax, 51); - if (!flags.z()) - goto gotendseq; - _cmp(data.byte(kIntrocount), 140); - if (flags.z()) - goto gotendseq; - _inc(data.byte(kIntrocount)); - push(es); - push(bx); - textForEnd(); - bx = pop(); - es = pop(); - ax = 50; -gotendseq: - es.word(bx+3) = ax; - _cmp(ax, 134); - if (!flags.z()) - goto notfadedown; - push(es); - push(bx); - push(ax); - fadeScreenDownHalf(); - ax = pop(); - bx = pop(); - es = pop(); - goto notendseq; -notfadedown: - _cmp(ax, 324); - if (!flags.z()) - goto notfadeend; - push(es); - push(bx); - push(ax); - fadeScreenDowns(); - data.byte(kVolumeto) = 7; - data.byte(kVolumedirection) = 1; - ax = pop(); - bx = pop(); - es = pop(); -notfadeend: - _cmp(ax, 340); - if (!flags.z()) - goto notendseq; - data.byte(kGetback) = 1; -notendseq: - showGameReel(); - al = data.byte(kMapy); - es.byte(bx+2) = al; - ax = es.word(bx+3); - _cmp(ax, 145); - if (!flags.z()) - return /* (notendcreds) */; - es.word(bx+3) = 146; - rollEndCredits(); -} - -void DreamGenContext::rollEndCredits() { - STACK_CHECK; - al = 16; - ah = 255; - playChannel0(); - data.byte(kVolume) = 7; - data.byte(kVolumeto) = 0; - data.byte(kVolumedirection) = -1; - cl = 160; - ch = 160; - di = 75; - bx = 20; - ds = data.word(kMapstore); - si = 0; - multiGet(); - es = data.word(kTextfile1); - si = 3*2; - ax = es.word(si); - si = ax; - _add(si, (66*2)); - cx = 254; -endcredits1: - push(cx); - bx = 10; - cx = data.word(kLinespacing); -endcredits2: - push(cx); - push(si); - push(di); - push(es); - push(bx); - vSync(); - cl = 160; - ch = 160; - di = 75; - bx = 20; - ds = data.word(kMapstore); - si = 0; - multiPut(); - vSync(); - bx = pop(); - es = pop(); - di = pop(); - si = pop(); - push(si); - push(di); - push(es); - push(bx); - cx = 18; -onelot: - push(cx); - di = 75; - dx = 161; - ax = 0; - printDirect(); - _add(bx, data.word(kLinespacing)); - cx = pop(); - if (--cx) - goto onelot; - vSync(); - cl = 160; - ch = 160; - di = 75; - bx = 20; - multiDump(); - bx = pop(); - es = pop(); - di = pop(); - si = pop(); - cx = pop(); - _dec(bx); - if (--cx) - goto endcredits2; - cx = pop(); -looknext: - al = es.byte(si); - _inc(si); - _cmp(al, ':'); - if (flags.z()) - goto gotnext; - _cmp(al, 0); - if (flags.z()) - goto gotnext; - goto looknext; -gotnext: - if (--cx) - goto endcredits1; - cx = 100; - hangOn(); - panelToMap(); - fadeScreenUpHalf(); -} - -void DreamGenContext::advisor() { - STACK_CHECK; - checkSpeed(); - if (!flags.z()) - goto noadvisor; - goto noadvisor; - ax = es.word(bx+3); - _inc(ax); - _cmp(ax, 123); - if (!flags.z()) - goto notendadvis; - ax = 106; - goto gotadvframe; -notendadvis: - _cmp(ax, 108); - if (!flags.z()) - goto gotadvframe; - push(ax); - randomNumber(); - cl = al; - ax = pop(); - _cmp(cl, 3); - if (flags.c()) - goto gotadvframe; - ax = 106; -gotadvframe: - es.word(bx+3) = ax; -noadvisor: - showGameReel(); - addToPeopleList(); -} - -void DreamGenContext::copper() { - STACK_CHECK; - checkSpeed(); - if (!flags.z()) - goto nocopper; - ax = es.word(bx+3); - _inc(ax); - _cmp(ax, 94); - if (!flags.z()) - goto notendcopper; - ax = 64; - goto gotcopframe; -notendcopper: - _cmp(ax, 81); - if (flags.z()) - goto mightwait; - _cmp(ax, 66); - if (!flags.z()) - goto gotcopframe; -mightwait: - push(ax); - randomNumber(); - cl = al; - ax = pop(); - _cmp(cl, 7); - if (flags.c()) - goto gotcopframe; - _dec(ax); -gotcopframe: - es.word(bx+3) = ax; -nocopper: - showGameReel(); - addToPeopleList(); -} - -void DreamGenContext::checkForExit() { - STACK_CHECK; - cl = data.byte(kRyanx); - _add(cl, 12); - ch = data.byte(kRyany); - _add(ch, 12); - checkOne(); - data.byte(kLastflag) = cl; - data.byte(kLastflagex) = ch; - data.byte(kFlagx) = dl; - data.byte(kFlagy) = dh; - al = data.byte(kLastflag); - _test(al, 64); - if (flags.z()) - goto notnewdirect; - al = data.byte(kLastflagex); - data.byte(kAutolocation) = al; - return; -notnewdirect: - _test(al, 32); - if (flags.z()) - goto notleave; - push(es); - push(bx); - _cmp(data.byte(kReallocation), 2); - if (!flags.z()) - goto notlouis; - bl = 0; - push(bx); - al = 'W'; - ah = 'E'; - cl = 'T'; - ch = 'A'; - isRyanHolding(); - bx = pop(); - if (flags.z()) - goto noshoe1; - _inc(bl); -noshoe1: - push(bx); - al = 'W'; - ah = 'E'; - cl = 'T'; - ch = 'B'; - isRyanHolding(); - bx = pop(); - if (flags.z()) - goto noshoe2; - _inc(bl); -noshoe2: - _cmp(bl, 2); - if (flags.z()) - goto notlouis; - al = 42; - _cmp(bl, 0); - if (flags.z()) - goto notravmessage; - _inc(al); -notravmessage: - cx = 80; - dx = 10; - bl = 68; - bh = 64; - setupTimedUse(); - al = data.byte(kFacing); - _add(al, 4); - _and(al, 7); - data.byte(kTurntoface) = al; - bx = pop(); - es = pop(); - return; -notlouis: - bx = pop(); - es = pop(); - data.byte(kNeedtotravel) = 1; - return; -notleave: - _test(al, 4); - if (flags.z()) - goto notaleft; - adjustLeft(); - return; -notaleft: - _test(al, 2); - if (flags.z()) - goto notaright; - adjustRight(); - return; -notaright: - _test(al, 8); - if (flags.z()) - goto notadown; - adjustDown(); - return; -notadown: - _test(al, 16); - if (flags.z()) - return /* (notanup) */; - adjustUp(); -} - -void DreamGenContext::adjustDown() { - STACK_CHECK; - push(es); - push(bx); - _add(data.byte(kMapy), 10); - al = data.byte(kLastflagex); - cl = 16; - _mul(cl); - es.byte(bx+11) = al; - data.byte(kNowinnewroom) = 1; - bx = pop(); - es = pop(); -} - -void DreamGenContext::adjustUp() { - STACK_CHECK; - push(es); - push(bx); - _sub(data.byte(kMapy), 10); - al = data.byte(kLastflagex); - cl = 16; - _mul(cl); - es.byte(bx+11) = al; - data.byte(kNowinnewroom) = 1; - bx = pop(); - es = pop(); -} - -void DreamGenContext::adjustLeft() { - STACK_CHECK; - push(es); - push(bx); - data.byte(kLastflag) = 0; - _sub(data.byte(kMapx), 11); - al = data.byte(kLastflagex); - cl = 16; - _mul(cl); - es.byte(bx+10) = al; - data.byte(kNowinnewroom) = 1; - bx = pop(); - es = pop(); -} - -void DreamGenContext::adjustRight() { - STACK_CHECK; - push(es); - push(bx); - _add(data.byte(kMapx), 11); - al = data.byte(kLastflagex); - cl = 16; - _mul(cl); - _sub(al, 2); - es.byte(bx+10) = al; - data.byte(kNowinnewroom) = 1; - bx = pop(); - es = pop(); -} - void DreamGenContext::reminders() { STACK_CHECK; _cmp(data.byte(kReallocation), 24); @@ -1116,153 +126,6 @@ void DreamGenContext::transferMap() { _add(data.word(kExframepos), cx); } -void DreamGenContext::doFade() { - STACK_CHECK; - _cmp(data.byte(kFadedirection), 0); - if (flags.z()) - return /* (finishfade) */; - cl = data.byte(kNumtofade); - ch = 0; - al = data.byte(kColourpos); - ah = 0; - ds = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)); - _add(si, ax); - _add(si, ax); - _add(si, ax); - showGroup(); - al = data.byte(kNumtofade); - _add(al, data.byte(kColourpos)); - data.byte(kColourpos) = al; - _cmp(al, 0); - if (!flags.z()) - return /* (finishfade) */; - fadeCalculation(); -} - -void DreamGenContext::fadeToWhite() { - STACK_CHECK; - es = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768); - cx = 768; - al = 63; - _stosb(cx, true); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768); - al = 0; - _stosb(3); - palToStartPal(); - data.byte(kFadedirection) = 1; - data.byte(kFadecount) = 63; - data.byte(kColourpos) = 0; - data.byte(kNumtofade) = 128; -} - -void DreamGenContext::fadeFromWhite() { - STACK_CHECK; - es = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)); - cx = 768; - al = 63; - _stosb(cx, true); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)); - al = 0; - _stosb(3); - palToEndPal(); - data.byte(kFadedirection) = 1; - data.byte(kFadecount) = 63; - data.byte(kColourpos) = 0; - data.byte(kNumtofade) = 128; -} - -void DreamGenContext::fadeScreenDownHalf() { - STACK_CHECK; - palToStartPal(); - palToEndPal(); - cx = 768; - es = data.word(kBuffers); - bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768); -halfend: - al = es.byte(bx); - _shr(al, 1); - es.byte(bx) = al; - _inc(bx); - if (--cx) - goto halfend; - ds = data.word(kBuffers); - es = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3))+(56*3); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768)+(56*3); - cx = 3*5; - _movsb(cx, true); - si = (0+(228*13)+32+60+(32*32)+(11*10*3))+(77*3); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768)+(77*3); - cx = 3*2; - _movsb(cx, true); - data.byte(kFadedirection) = 1; - data.byte(kFadecount) = 31; - data.byte(kColourpos) = 0; - data.byte(kNumtofade) = 32; -} - -void DreamGenContext::showGun() { - STACK_CHECK; - data.byte(kAddtored) = 0; - data.byte(kAddtogreen) = 0; - data.byte(kAddtoblue) = 0; - palToStartPal(); - palToEndPal(); - greyscaleSum(); - data.byte(kFadedirection) = 1; - data.byte(kFadecount) = 63; - data.byte(kColourpos) = 0; - data.byte(kNumtofade) = 128; - cx = 130; - hangOn(); - endPalToStart(); - clearEndPal(); - data.byte(kFadedirection) = 1; - data.byte(kFadecount) = 63; - data.byte(kColourpos) = 0; - data.byte(kNumtofade) = 128; - cx = 200; - hangOn(); - data.byte(kRoomssample) = 34; - loadRoomsSample(); - data.byte(kVolume) = 0; - dx = 1061; - loadIntoTemp(); - createPanel2(); - ds = data.word(kTempgraphics); - al = 0; - ah = 0; - di = 100; - bx = 4; - showFrame(); - ds = data.word(kTempgraphics); - al = 1; - ah = 0; - di = 158; - bx = 106; - showFrame(); - workToScreen(); - getRidOfTemp(); - fadeScreenUp(); - cx = 160; - hangOn(); - al = 12; - ah = 0; - playChannel0(); - dx = 1035; - loadTempText(); - rollEndCredits2(); - getRidOfTempText(); -} - -void DreamGenContext::rollEndCredits2() { - STACK_CHECK; - rollEm(); -} - void DreamGenContext::rollEm() { STACK_CHECK; cl = 160; @@ -1357,89 +220,6 @@ endearly2: cx = pop(); } -void DreamGenContext::greyscaleSum() { - STACK_CHECK; - es = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768); - cx = 256; -greysumloop1: - push(cx); - bx = 0; - al = es.byte(si); - ah = 0; - cx = 20; - _mul(cx); - _add(bx, ax); - al = es.byte(si+1); - ah = 0; - cx = 59; - _mul(cx); - _add(bx, ax); - al = es.byte(si+2); - ah = 0; - cx = 11; - _mul(cx); - _add(bx, ax); - al = -1; -greysumloop2: - _inc(al); - _sub(bx, 100); - if (!flags.c()) - goto greysumloop2; - bl = al; - al = bl; - ah = data.byte(kAddtored); - _cmp(al, 0); - _add(al, ah); - _stosb(); - ah = data.byte(kAddtogreen); - al = bl; - _cmp(al, 0); - if (flags.z()) - goto noaddg; - _add(al, ah); -noaddg: - _stosb(); - ah = data.byte(kAddtoblue); - al = bl; - _cmp(al, 0); - if (flags.z()) - goto noaddb; - _add(al, ah); -noaddb: - _stosb(); - _add(si, 3); - cx = pop(); - if (--cx) - goto greysumloop1; -} - -void DreamGenContext::allPalette() { - STACK_CHECK; - es = data.word(kBuffers); - ds = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768); - cx = 768/2; - _movsw(cx, true); - dumpCurrent(); -} - -void DreamGenContext::dumpCurrent() { - STACK_CHECK; - si = (0+(228*13)+32+60+(32*32)+(11*10*3)); - ds = data.word(kBuffers); - vSync(); - al = 0; - cx = 128; - showGroup(); - vSync(); - al = 128; - cx = 128; - showGroup(); -} - void DreamGenContext::fadeDownMon() { STACK_CHECK; palToStartPal(); @@ -1498,97 +278,6 @@ void DreamGenContext::initialMonCols() { showGroup(); } -void DreamGenContext::endGame() { - STACK_CHECK; - dx = 1035; - loadTempText(); - monkSpeaking(); - gettingShot(); - getRidOfTempText(); - data.byte(kVolumeto) = 7; - data.byte(kVolumedirection) = 1; - cx = 200; - hangOn(); -} - -void DreamGenContext::monkSpeaking() { - STACK_CHECK; - data.byte(kRoomssample) = 35; - loadRoomsSample(); - dx = 1074; - loadIntoTemp(); - clearWork(); - showMonk(); - workToScreen(); - data.byte(kVolume) = 7; - data.byte(kVolumedirection) = -1; - data.byte(kVolumeto) = 5; - al = 12; - ah = 255; - playChannel0(); - fadeScreenUps(); - cx = 300; - hangOn(); - al = 40; -loadspeech2: - push(ax); - dl = 'T'; - dh = 83; - cl = 'T'; - ah = 0; - loadSpeech(); - al = 50+12; - playChannel1(); -notloadspeech2: - vSync(); - _cmp(data.byte(kCh1playing), 255); - if (!flags.z()) - goto notloadspeech2; - ax = pop(); - _inc(al); - _cmp(al, 48); - if (!flags.z()) - goto loadspeech2; - data.byte(kVolumedirection) = 1; - data.byte(kVolumeto) = 7; - fadeScreenDowns(); - cx = 300; - hangOn(); - getRidOfTemp(); -} - -void DreamGenContext::showMonk() { - STACK_CHECK; - al = 0; - ah = 128; - di = 160; - bx = 72; - ds = data.word(kTempgraphics); - showFrame(); -} - -void DreamGenContext::runEndSeq() { - STACK_CHECK; - atmospheres(); - data.byte(kGetback) = 0; -moreendseq: - vSync(); - spriteUpdate(); - vSync(); - delEverything(); - printSprites(); - reelsOnScreen(); - afterIntroRoom(); - useTimedText(); - vSync(); - dumpMap(); - dumpTimedText(); - vSync(); - _cmp(data.byte(kGetback), 1); - if (!flags.z()) - goto moreendseq; -} - void DreamGenContext::fillOpen() { STACK_CHECK; delTextLine(); @@ -1740,117 +429,6 @@ findnewpage: delPointer(); } -void DreamGenContext::openOb() { - STACK_CHECK; - al = data.byte(kOpenedob); - ah = data.byte(kOpenedtype); - di = offset_commandline; - copyName(); - di = (80); - bx = (58)+86; - al = 62; - dl = 240; - printMessage(); - di = data.word(kLastxpos); - _add(di, 5); - bx = (58)+86; - es = cs; - si = offset_commandline; - dl = 220; - al = 0; - ah = 0; - printDirect(); - fillOpen(); - getOpenedSize(); - al = ah; - ah = 0; - cx = (44); - _mul(cx); - _add(ax, (80)); - bx = offset_openchangesize; - cs.word(bx) = ax; -} - -void DreamGenContext::describeOb() { - STACK_CHECK; - getObTextStart(); - di = 33; - bx = 92; - _cmp(data.byte(kForeignrelease), 0); - if (flags.z()) - goto notsetd; - _cmp(data.byte(kObjecttype), 1); - if (!flags.z()) - goto notsetd; - bx = 82; -notsetd: - dl = 241; - ah = 16; - data.word(kCharshift) = 91+91; - printDirect(); - data.word(kCharshift) = 0; - di = 36; - bx = 104; - _cmp(data.byte(kForeignrelease), 0); - if (flags.z()) - goto notsetd2; - _cmp(data.byte(kObjecttype), 1); - if (!flags.z()) - goto notsetd2; - bx = 94; -notsetd2: - dl = 241; - ah = 0; - printDirect(); - push(bx); - obsThatDoThings(); - bx = pop(); - additionalText(); -} - -void DreamGenContext::additionalText() { - STACK_CHECK; - _add(bx, 10); - push(bx); - al = data.byte(kCommand); - ah = data.byte(kObjecttype); - cl = 'C'; - ch = 'U'; - dl = 'P'; - dh = 'E'; - compare(); - if (flags.z()) - goto emptycup; - al = data.byte(kCommand); - ah = data.byte(kObjecttype); - cl = 'C'; - ch = 'U'; - dl = 'P'; - dh = 'F'; - compare(); - if (flags.z()) - goto fullcup; - bx = pop(); - return; -emptycup: - al = 40; - findPuzText(); - bx = pop(); - di = 36; - dl = 241; - ah = 0; - printDirect(); - return; -fullcup: - al = 39; - findPuzText(); - bx = pop(); - di = 36; - dl = 241; - ah = 0; - printDirect(); -} - void DreamGenContext::getObTextStart() { STACK_CHECK; es = data.word(kFreedesc); @@ -1941,71 +519,6 @@ foundmatch: bx = pop(); } -void DreamGenContext::setPickup() { - STACK_CHECK; - _cmp(data.byte(kObjecttype), 1); - if (flags.z()) - goto cantpick; - _cmp(data.byte(kObjecttype), 3); - if (flags.z()) - goto cantpick; - getAnyAd(); - al = es.byte(bx+2); - _cmp(al, 4); - if (!flags.z()) - goto canpick; -cantpick: - blank(); - return; -canpick: - _cmp(data.byte(kCommandtype), 209); - if (flags.z()) - goto alreadysp; - data.byte(kCommandtype) = 209; - bl = data.byte(kCommand); - bh = data.byte(kObjecttype); - al = 33; - commandWithOb(); -alreadysp: - ax = data.word(kMousebutton); - _cmp(ax, 1); - if (!flags.z()) - return /* (nosetpick) */; - _cmp(ax, data.word(kOldbutton)); - if (!flags.z()) - goto dosetpick; - return; -dosetpick: - createPanel(); - showPanel(); - showMan(); - showExit(); - examIcon(); - data.byte(kPickup) = 1; - data.byte(kInvopen) = 2; - _cmp(data.byte(kObjecttype), 4); - if (flags.z()) - goto pickupexob; - al = data.byte(kCommand); - data.byte(kItemframe) = al; - data.byte(kOpenedob) = 255; - transferToEx(); - data.byte(kItemframe) = al; - data.byte(kObjecttype) = 4; - getEitherAd(); - es.byte(bx+2) = 20; - es.byte(bx+3) = 255; - openInv(); - workToScreenM(); - return; -pickupexob: - al = data.byte(kCommand); - data.byte(kItemframe) = al; - data.byte(kOpenedob) = 255; - openInv(); - workToScreenM(); -} - void DreamGenContext::reExFromInv() { STACK_CHECK; findInvPos(); @@ -2178,118 +691,6 @@ actuallyswap: delPointer(); } -void DreamGenContext::inToInv() { - STACK_CHECK; - _cmp(data.byte(kPickup), 0); - if (!flags.z()) - goto notout; - outOfInv(); - return; -notout: - findInvPos(); - ax = es.word(bx); - _cmp(al, 255); - if (flags.z()) - goto canplace1; - swapWithInv(); - return; -canplace1: - al = data.byte(kItemframe); - ah = data.byte(kObjecttype); - _cmp(ax, data.word(kOldsubject)); - if (!flags.z()) - goto difsub1; - _cmp(data.byte(kCommandtype), 220); - if (flags.z()) - goto alreadyplce; - data.byte(kCommandtype) = 220; -difsub1: - data.word(kOldsubject) = ax; - bx = ax; - al = 35; - commandWithOb(); -alreadyplce: - ax = data.word(kMousebutton); - _cmp(ax, data.word(kOldbutton)); - if (flags.z()) - return /* (notletgo2) */; - _and(ax, 1); - if (!flags.z()) - goto doplace; - return; -doplace: - delPointer(); - al = data.byte(kItemframe); - getExAd(); - es.byte(bx+2) = 4; - es.byte(bx+3) = 255; - al = data.byte(kLastinvpos); - es.byte(bx+4) = al; - data.byte(kPickup) = 0; - fillRyan(); - readMouse(); - showPointer(); - outOfInv(); - workToScreen(); - delPointer(); -} - -void DreamGenContext::outOfInv() { - STACK_CHECK; - findInvPos(); - ax = es.word(bx); - _cmp(al, 255); - if (!flags.z()) - goto canpick2; - blank(); - return; -canpick2: - bx = data.word(kMousebutton); - _cmp(bx, 2); - if (!flags.z()) - goto canpick2a; - reExFromInv(); - return; -canpick2a: - _cmp(ax, data.word(kOldsubject)); - if (!flags.z()) - goto difsub3; - _cmp(data.byte(kCommandtype), 221); - if (flags.z()) - goto alreadygrab; - data.byte(kCommandtype) = 221; -difsub3: - data.word(kOldsubject) = ax; - bx = ax; - al = 36; - commandWithOb(); -alreadygrab: - ax = data.word(kMousebutton); - _cmp(ax, data.word(kOldbutton)); - if (flags.z()) - return /* (notletgo) */; - _and(ax, 1); - if (!flags.z()) - goto dograb; - return; -dograb: - delPointer(); - data.byte(kPickup) = 1; - findInvPos(); - ax = es.word(bx); - data.byte(kItemframe) = al; - data.byte(kObjecttype) = ah; - getExAd(); - es.byte(bx+2) = 20; - es.byte(bx+3) = 255; - fillRyan(); - readMouse(); - showPointer(); - inToInv(); - workToScreen(); - delPointer(); -} - void DreamGenContext::getFreeAd() { STACK_CHECK; ah = 0; @@ -2345,29 +746,6 @@ isex: ax = es.word(bx+7); } -void DreamGenContext::getOpenedSize() { - STACK_CHECK; - _cmp(data.byte(kOpenedtype), 4); - if (flags.z()) - goto isex2; - _cmp(data.byte(kOpenedtype), 2); - if (flags.z()) - goto isfree2; - al = data.byte(kOpenedob); - getSetAd(); - ax = es.word(bx+3); - return; -isfree2: - al = data.byte(kOpenedob); - getFreeAd(); - ax = es.word(bx+7); - return; -isex2: - al = data.byte(kOpenedob); - getExAd(); - ax = es.word(bx+7); -} - void DreamGenContext::getSetAd() { STACK_CHECK; ah = 0; @@ -2377,36 +755,6 @@ void DreamGenContext::getSetAd() { es = data.word(kSetdat); } -void DreamGenContext::findInvPos() { - STACK_CHECK; - cx = data.word(kMousex); - _sub(cx, (80)); - bx = -1; -findinv1: - _inc(bx); - _sub(cx, (44)); - if (!flags.c()) - goto findinv1; - cx = data.word(kMousey); - _sub(cx, (58)); - _sub(bx, 5); -findinv2: - _add(bx, 5); - _sub(cx, (44)); - if (!flags.c()) - goto findinv2; - al = data.byte(kRyanpage); - ah = 0; - cx = 10; - _mul(cx); - _add(bx, ax); - al = bl; - data.byte(kLastinvpos) = al; - _add(bx, bx); - es = data.word(kBuffers); - _add(bx, (0+(228*13)+32)); -} - void DreamGenContext::findOpenPos() { STACK_CHECK; cx = data.word(kMousex); @@ -2525,56 +873,6 @@ notinlift: es.byte(bx) = al; } -void DreamGenContext::dropError() { - STACK_CHECK; - data.byte(kCommandtype) = 255; - delPointer(); - di = 76; - bx = 21; - al = 56; - dl = 240; - printMessage(); - workToScreenM(); - cx = 50; - hangOnP(); - showPanel(); - showMan(); - examIcon(); - data.byte(kCommandtype) = 255; - workToScreenM(); -} - -void DreamGenContext::cantDrop() { - STACK_CHECK; - data.byte(kCommandtype) = 255; - delPointer(); - di = 76; - bx = 21; - al = 24; - dl = 240; - printMessage(); - workToScreenM(); - cx = 50; - hangOnP(); - showPanel(); - showMan(); - examIcon(); - data.byte(kCommandtype) = 255; - workToScreenM(); -} - -void DreamGenContext::removeObFromInv() { - STACK_CHECK; - _cmp(data.byte(kCommand), 100); - if (flags.z()) - return /* (obnotexist) */; - getAnyAd(); - di = bx; - cl = data.byte(kCommand); - ch = 0; - deleteExObject(); -} - void DreamGenContext::selectOpenOb() { STACK_CHECK; al = data.byte(kCommand); @@ -3044,219 +1342,6 @@ cantpurge2: goto lookforpurge2; } -void DreamGenContext::deleteExObject() { - STACK_CHECK; - push(cx); - push(cx); - push(cx); - push(cx); - al = 255; - cx = 16; - _stosb(cx, true); - ax = pop(); - cl = al; - _add(al, al); - _add(al, cl); - deleteExFrame(); - ax = pop(); - cl = al; - _add(al, al); - _add(al, cl); - _inc(al); - deleteExFrame(); - ax = pop(); - deleteExText(); - bx = pop(); - bh = bl; - bl = 4; - di = (0+2080+30000); - cx = 0; -deleteconts: - _cmp(es.word(di+2), bx); - if (!flags.z()) - goto notinsideex; - push(bx); - push(cx); - push(di); - deleteExObject(); - di = pop(); - cx = pop(); - bx = pop(); -notinsideex: - _add(di, 16); - _inc(cx); - _cmp(cx, (114)); - if (!flags.z()) - goto deleteconts; -} - -void DreamGenContext::deleteExFrame() { - STACK_CHECK; - di = (0); - ah = 0; - _add(ax, ax); - _add(di, ax); - _add(ax, ax); - _add(di, ax); - al = es.byte(di); - ah = 0; - cl = es.byte(di+1); - ch = 0; - _mul(cx); - si = es.word(di+2); - push(si); - _add(si, (0+2080)); - cx = (30000); - _sub(cx, es.word(di+2)); - di = si; - _add(si, ax); - push(ax); - ds = es; - _movsb(cx, true); - bx = pop(); - _sub(data.word(kExframepos), bx); - si = pop(); - cx = (114)*3; - di = (0); -shuffleadsdown: - ax = es.word(di+2); - _cmp(ax, si); - if (flags.c()) - goto beforethisone; - _sub(ax, bx); -beforethisone: - es.word(di+2) = ax; - _add(di, 6); - if (--cx) - goto shuffleadsdown; -} - -void DreamGenContext::deleteExText() { - STACK_CHECK; - di = (0+2080+30000+(16*114)); - ah = 0; - _add(ax, ax); - _add(di, ax); - ax = es.word(di); - si = ax; - di = ax; - _add(si, (0+2080+30000+(16*114)+((114+2)*2))); - _add(di, (0+2080+30000+(16*114)+((114+2)*2))); - ax = 0; -findlenextext: - cl = es.byte(si); - _inc(ax); - _inc(si); - _cmp(cl, 0); - if (!flags.z()) - goto findlenextext; - cx = (18000); - bx = si; - _sub(bx, (0+2080+30000+(16*114)+((114+2)*2))); - push(bx); - push(ax); - _sub(cx, bx); - _movsb(cx, true); - bx = pop(); - _sub(data.word(kExtextpos), bx); - si = pop(); - cx = (114); - di = (0+2080+30000+(16*114)); -shuffletextads: - ax = es.word(di); - _cmp(ax, si); - if (flags.c()) - goto beforethistext; - _sub(ax, bx); -beforethistext: - es.word(di) = ax; - _add(di, 2); - if (--cx) - goto shuffletextads; -} - -void DreamGenContext::getBack1() { - STACK_CHECK; - _cmp(data.byte(kPickup), 0); - if (flags.z()) - goto notgotobject; - blank(); - return; -notgotobject: - _cmp(data.byte(kCommandtype), 202); - if (flags.z()) - goto alreadyget; - data.byte(kCommandtype) = 202; - al = 26; - commandOnly(); -alreadyget: - ax = data.word(kMousebutton); - _cmp(ax, data.word(kOldbutton)); - if (flags.z()) - return /* (nogetback) */; - _and(ax, 1); - if (!flags.z()) - goto dogetback; - return; -dogetback: - data.byte(kGetback) = 1; - data.byte(kPickup) = 0; -} - -void DreamGenContext::talk() { - STACK_CHECK; - data.byte(kTalkpos) = 0; - data.byte(kInmaparea) = 0; - al = data.byte(kCommand); - data.byte(kCharacter) = al; - createPanel(); - showPanel(); - showMan(); - showExit(); - underTextLine(); - convIcons(); - startTalk(); - data.byte(kCommandtype) = 255; - readMouse(); - showPointer(); - workToScreen(); -waittalk: - delPointer(); - readMouse(); - animPointer(); - showPointer(); - vSync(); - dumpPointer(); - dumpTextLine(); - data.byte(kGetback) = 0; - bx = offset_talklist; - checkCoords(); - _cmp(data.byte(kQuitrequested), 0); - if (!flags.z()) - goto finishtalk; - _cmp(data.byte(kGetback), 0); - if (flags.z()) - goto waittalk; -finishtalk: - bx = data.word(kPersondata); - es = cs; - _cmp(data.byte(kTalkpos), 4); - if (flags.c()) - goto notnexttalk; - al = es.byte(bx+7); - _or(al, 128); - es.byte(bx+7) = al; -notnexttalk: - redrawMainScrn(); - workToScreenM(); - _cmp(data.byte(kSpeechloaded), 1); - if (!flags.z()) - return /* (nospeech) */; - cancelCh1(); - data.byte(kVolumedirection) = -1; - data.byte(kVolumeto) = 0; -} - void DreamGenContext::startTalk() { STACK_CHECK; data.byte(kTalkmode) = 0; @@ -3450,171 +1535,6 @@ endheartalk: data.byte(kPointermode) = 0; } -void DreamGenContext::hangOnPQ() { - STACK_CHECK; - data.byte(kGetback) = 0; - bx = 0; -hangloopq: - push(cx); - push(bx); - delPointer(); - readMouse(); - animPointer(); - showPointer(); - vSync(); - dumpPointer(); - dumpTextLine(); - bx = offset_quitlist; - checkCoords(); - bx = pop(); - cx = pop(); - _cmp(data.byte(kGetback), 1); - if (flags.z()) - goto quitconv; - _cmp(data.byte(kQuitrequested), 0); - if (!flags.z()) - goto quitconv; - _cmp(data.byte(kSpeechloaded), 1); - if (!flags.z()) - goto notspeaking; - _cmp(data.byte(kCh1playing), 255); - if (!flags.z()) - goto notspeaking; - _inc(bx); - _cmp(bx, 40); - if (flags.z()) - goto finishconv; -notspeaking: - _cmp(data.word(kMousebutton), 0); - if (flags.z()) - goto hangloopq; - _cmp(data.word(kOldbutton), 0); - if (!flags.z()) - goto hangloopq; -finishconv: - delPointer(); - data.byte(kPointermode) = 0; - flags._c = false; - return; -quitconv: - delPointer(); - data.byte(kPointermode) = 0; - cancelCh1(); - flags._c = true; - } - -void DreamGenContext::newPlace() { - STACK_CHECK; - _cmp(data.byte(kNeedtotravel), 1); - if (flags.z()) - goto istravel; - _cmp(data.byte(kAutolocation), -1); - if (!flags.z()) - goto isautoloc; - return; -isautoloc: - al = data.byte(kAutolocation); - data.byte(kNewlocation) = al; - data.byte(kAutolocation) = -1; - return; -istravel: - data.byte(kNeedtotravel) = 0; - selectLocation(); -} - -void DreamGenContext::lookAtPlace() { - STACK_CHECK; - _cmp(data.byte(kCommandtype), 224); - if (flags.z()) - goto alreadyinfo; - data.byte(kCommandtype) = 224; - al = 27; - commandOnly(); -alreadyinfo: - ax = data.word(kMousebutton); - _and(ax, 1); - if (flags.z()) - return /* (noinfo) */; - _cmp(ax, data.word(kOldbutton)); - if (flags.z()) - return /* (noinfo) */; - bl = data.byte(kDestpos); - _cmp(bl, 15); - if (!flags.c()) - return /* (noinfo) */; - push(bx); - delPointer(); - delTextLine(); - getUnderCentre(); - ds = data.word(kTempgraphics3); - al = 0; - ah = 0; - di = 60; - bx = 72; - showFrame(); - al = 4; - ah = 0; - di = 60; - bx = 72+55; - showFrame(); - _cmp(data.byte(kForeignrelease), 0); - if (flags.z()) - goto _tmp1; - al = 4; - ah = 0; - di = 60; - bx = 72+55+21; - showFrame(); -_tmp1: - bx = pop(); - bh = 0; - _add(bx, bx); - es = data.word(kTraveltext); - si = es.word(bx); - _add(si, (66*2)); - findNextColon(); - di = 63; - bx = 84; - _cmp(data.byte(kForeignrelease), 0); - if (flags.z()) - goto _tmp2; - bx = 84+4; -_tmp2: - dl = 191; - al = 0; - ah = 0; - printDirect(); - workToScreenM(); - cx = 500; - hangOnP(); - data.byte(kPointermode) = 0; - data.byte(kPointerframe) = 0; - putUnderCentre(); - workToScreenM(); -} - -void DreamGenContext::getUnderCentre() { - STACK_CHECK; - di = 58; - bx = 72; - ds = data.word(kMapstore); - si = 0; - cl = 254; - ch = 110; - multiGet(); -} - -void DreamGenContext::putUnderCentre() { - STACK_CHECK; - di = 58; - bx = 72; - ds = data.word(kMapstore); - si = 0; - cl = 254; - ch = 110; - multiPut(); -} - void DreamGenContext::locationPic() { STACK_CHECK; getDestInfo(); @@ -3670,40 +1590,18 @@ void DreamGenContext::getDestInfo() { push(ax); dx = data; es = dx; - si = 1661; + si = 555; _add(si, ax); cl = es.byte(si); ax = pop(); push(cx); dx = data; es = dx; - si = 1677; + si = 571; _add(si, ax); ax = pop(); } -void DreamGenContext::showArrows() { - STACK_CHECK; - di = 116-12; - bx = 16; - ds = data.word(kTempgraphics); - al = 0; - ah = 0; - showFrame(); - di = 226+12; - bx = 16; - ds = data.word(kTempgraphics); - al = 1; - ah = 0; - showFrame(); - di = 280; - bx = 14; - ds = data.word(kTempgraphics); - al = 2; - ah = 0; - showFrame(); -} - void DreamGenContext::resetLocation() { STACK_CHECK; push(ax); @@ -3751,181 +1649,10 @@ clearedlocations: bx = ax; dx = data; es = dx; - _add(bx, 1661); + _add(bx, 555); es.byte(bx) = 0; } -void DreamGenContext::printOuterMon() { - STACK_CHECK; - di = 40; - bx = 32; - ds = data.word(kTempgraphics); - al = 1; - ah = 0; - showFrame(); - di = 264; - bx = 32; - ds = data.word(kTempgraphics); - al = 2; - ah = 0; - showFrame(); - di = 40; - bx = 12; - ds = data.word(kTempgraphics); - al = 3; - ah = 0; - showFrame(); - di = 40; - bx = 164; - ds = data.word(kTempgraphics); - al = 4; - ah = 0; - showFrame(); -} - -void DreamGenContext::lookInInterface() { - STACK_CHECK; - al = 'I'; - ah = 'N'; - cl = 'T'; - ch = 'F'; - findSetObject(); - ah = 1; - checkInside(); - _cmp(cl, (114)); - if (flags.z()) - goto emptyinterface; - al = es.byte(bx+15); - _inc(al); - return; -emptyinterface: - al = 0; -} - -void DreamGenContext::lockLightOn() { - STACK_CHECK; - di = 56; - bx = 182; - ds = data.word(kTempgraphics); - al = 10; - ah = 0; - push(di); - push(bx); - showFrame(); - bx = pop(); - di = pop(); - cl = 12; - ch = 8; - multiDump(); -} - -void DreamGenContext::lockLightOff() { - STACK_CHECK; - di = 56; - bx = 182; - ds = data.word(kTempgraphics); - al = 9; - ah = 0; - push(di); - push(bx); - showFrame(); - bx = pop(); - di = pop(); - cl = 12; - ch = 8; - multiDump(); -} - -void DreamGenContext::makeCaps() { - STACK_CHECK; - _cmp(al, 'a'); - if (flags.c()) - return /* (notupperc) */; - _sub(al, 32); -} - -void DreamGenContext::execCommand() { - STACK_CHECK; - es = cs; - bx = offset_comlist; - ds = cs; - si = 1695; - al = ds.byte(si); - _cmp(al, 0); - if (!flags.z()) - goto notblankinp; - scrollMonitor(); - return; -notblankinp: - cl = 0; -comloop: - push(bx); - push(si); -comloop2: - al = ds.byte(si); - _add(si, 2); - ah = es.byte(bx); - _inc(bx); - _cmp(ah, 32); - if (flags.z()) - goto foundcom; - _cmp(al, ah); - if (flags.z()) - goto comloop2; - si = pop(); - bx = pop(); - _add(bx, 10); - _inc(cl); - _cmp(cl, 6); - if (!flags.z()) - goto comloop; - netError(); - al = 0; - return; -foundcom: - si = pop(); - bx = pop(); - _cmp(cl, 1); - if (flags.z()) - goto testcom; - _cmp(cl, 2); - if (flags.z()) - goto directory; - _cmp(cl, 3); - if (flags.z()) - goto accesscom; - _cmp(cl, 4); - if (flags.z()) - goto signoncom; - _cmp(cl, 5); - if (flags.z()) - goto keyscom; - goto quitcom; -directory: - dirCom(); - al = 0; - return; -signoncom: - signOn(); - al = 0; - return; -accesscom: - read(); - al = 0; - return; -keyscom: - showKeys(); - al = 0; - return; -testcom: - al = 6; - monMessage(); - al = 0; - return; -quitcom: - al = 1; -} - void DreamGenContext::dirCom() { STACK_CHECK; cx = 30; @@ -3942,7 +1669,7 @@ dirroot: si = offset_rootdir; _inc(si); es = cs; - di = 1350; + di = 480; _inc(di); cx = 12; _movsb(cx, true); @@ -3975,134 +1702,6 @@ directloop1: goto directloop1; } -void DreamGenContext::signOn() { - STACK_CHECK; - parser(); - _inc(di); - ds = cs; - si = offset_keys; - cx = 4; -signonloop: - push(cx); - push(si); - push(di); - _add(si, 14); - cx = 11; -signonloop2: - _lodsb(); - _cmp(al, 32); - if (flags.z()) - goto foundsign; - makeCaps(); - ah = es.byte(di); - _inc(di); - _cmp(al, ah); - if (!flags.z()) - goto nomatch; - if (--cx) - goto signonloop2; -nomatch: - di = pop(); - si = pop(); - cx = pop(); - _add(si, 26); - if (--cx) - goto signonloop; - al = 13; - monMessage(); - return; -foundsign: - di = pop(); - si = pop(); - cx = pop(); - bx = si; - es = ds; - _cmp(es.byte(bx), 0); - if (flags.z()) - goto notyetassigned; - al = 17; - monMessage(); - return; -notyetassigned: - push(es); - push(bx); - scrollMonitor(); - al = 15; - monMessage(); - di = data.word(kMonadx); - bx = data.word(kMonady); - push(di); - push(bx); - input(); - bx = pop(); - di = pop(); - data.word(kMonadx) = di; - data.word(kMonady) = bx; - bx = pop(); - es = pop(); - push(es); - push(bx); - _add(bx, 2); - ds = cs; - si = 1695; -checkpass: - _lodsw(); - ah = es.byte(bx); - _inc(bx); - _cmp(ah, 32); - if (flags.z()) - goto passpassed; - _cmp(al, ah); - if (flags.z()) - goto checkpass; - bx = pop(); - es = pop(); - scrollMonitor(); - al = 16; - monMessage(); - return; -passpassed: - al = 14; - monMessage(); - bx = pop(); - es = pop(); - push(es); - push(bx); - _add(bx, 14); - monPrint(); - scrollMonitor(); - bx = pop(); - es = pop(); - es.byte(bx) = 1; -} - -void DreamGenContext::showKeys() { - STACK_CHECK; - cx = 10; - randomAccess(); - scrollMonitor(); - al = 18; - monMessage(); - es = cs; - bx = offset_keys; - cx = 4; -keysloop: - push(cx); - push(bx); - _cmp(es.byte(bx), 0); - if (flags.z()) - goto notheld; - _add(bx, 14); - monPrint(); -notheld: - bx = pop(); - cx = pop(); - _add(bx, 26); - if (--cx) - goto keysloop; - scrollMonitor(); -} - void DreamGenContext::read() { STACK_CHECK; cx = 40; @@ -4115,7 +1714,7 @@ void DreamGenContext::read() { return; okcom: es = cs; - di = 1350; + di = 480; ax = data.word(kTextfile1); data.word(kMonsource) = ax; ds = ax; @@ -4245,7 +1844,7 @@ keyok2: ds = cs; si = offset_operand1+1; es = cs; - di = 1350+1; + di = 480+1; cx = 12; _movsb(cx, true); monitorLogo(); @@ -4272,51 +1871,6 @@ endofdir2: scrollMonitor(); } -void DreamGenContext::getKeyAndLogo() { - STACK_CHECK; - _inc(bx); - al = es.byte(bx); - _sub(al, 48); - data.byte(kNewlogonum) = al; - _add(bx, 2); - al = es.byte(bx); - _sub(al, 48); - data.byte(kKeynum) = al; - _inc(bx); - push(es); - push(bx); - al = data.byte(kKeynum); - ah = 0; - cx = 26; - _mul(cx); - es = cs; - bx = offset_keys; - _add(bx, ax); - al = es.byte(bx); - _cmp(al, 1); - if (flags.z()) - goto keyok; - push(bx); - push(es); - al = 12; - monMessage(); - es = pop(); - bx = pop(); - _add(bx, 14); - monPrint(); - scrollMonitor(); - bx = pop(); - es = pop(); - al = 1; - return; -keyok: - bx = pop(); - es = pop(); - al = data.byte(kNewlogonum); - data.byte(kLogonum) = al; - al = 0; -} - void DreamGenContext::searchForString() { STACK_CHECK; dl = es.byte(di); @@ -4372,7 +1926,7 @@ void DreamGenContext::parser() { al = '='; _stosb(); ds = cs; - si = 1695; + si = 589; notspace1: _lodsw(); _cmp(al, 32); @@ -4400,2782 +1954,6 @@ finishpars: di = offset_operand1; } -void DreamGenContext::monitorLogo() { - STACK_CHECK; - al = data.byte(kLogonum); - _cmp(al, data.byte(kOldlogonum)); - if (flags.z()) - goto notnewlogo; - data.byte(kOldlogonum) = al; - printLogo(); - printUnderMon(); - workToScreen(); - printLogo(); - printLogo(); - al = 26; - playChannel1(); - cx = 20; - randomAccess(); - return; -notnewlogo: - printLogo(); -} - -void DreamGenContext::processTrigger() { - STACK_CHECK; - _cmp(data.byte(kLasttrigger), '1'); - if (!flags.z()) - goto notfirsttrigger; - al = 8; - setLocation(); - al = 45; - triggerMessage(); - return; -notfirsttrigger: - _cmp(data.byte(kLasttrigger), '2'); - if (!flags.z()) - goto notsecondtrigger; - al = 9; - setLocation(); - al = 55; - triggerMessage(); - return; -notsecondtrigger: - _cmp(data.byte(kLasttrigger), '3'); - if (!flags.z()) - return /* (notthirdtrigger) */; - al = 2; - setLocation(); - al = 59; - triggerMessage(); -} - -void DreamGenContext::triggerMessage() { - STACK_CHECK; - push(ax); - di = 174; - bx = 153; - cl = 200; - ch = 63; - ds = data.word(kMapstore); - si = 0; - multiGet(); - ax = pop(); - findPuzText(); - di = 174; - bx = 156; - dl = 141; - ah = 16; - printDirect(); - cx = 140; - hangOn(); - workToScreen(); - cx = 340; - hangOn(); - di = 174; - bx = 153; - cl = 200; - ch = 63; - ds = data.word(kMapstore); - si = 0; - multiPut(); - workToScreen(); - data.byte(kLasttrigger) = 0; -} - -void DreamGenContext::runTap() { - STACK_CHECK; - _cmp(data.byte(kWithobject), 255); - if (!flags.z()) - goto tapwith; - withWhat(); - return; -tapwith: - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'C'; - ch = 'U'; - dl = 'P'; - dh = 'E'; - compare(); - if (flags.z()) - goto fillcupfromtap; - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'C'; - ch = 'U'; - dl = 'P'; - dh = 'F'; - compare(); - if (flags.z()) - goto cupfromtapfull; - cx = 300; - al = 56; - showPuzText(); - putBackObStuff(); - return; -fillcupfromtap: - al = data.byte(kWithobject); - getExAd(); - es.byte(bx+15) = 'F'-'A'; - al = 8; - playChannel1(); - cx = 300; - al = 57; - showPuzText(); - putBackObStuff(); - return; -cupfromtapfull: - cx = 300; - al = 58; - showPuzText(); - putBackObStuff(); -} - -void DreamGenContext::notHeldError() { - STACK_CHECK; - createPanel(); - showPanel(); - showMan(); - showExit(); - obIcons(); - di = 64; - bx = 100; - al = 63; - ah = 1; - dl = 201; - printmessage2(); - workToScreenM(); - cx = 50; - hangOnP(); - putBackObStuff(); -} - -void DreamGenContext::usePipe() { - STACK_CHECK; - _cmp(data.byte(kWithobject), 255); - if (!flags.z()) - goto pipewith; - withWhat(); - return; -pipewith: - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'C'; - ch = 'U'; - dl = 'P'; - dh = 'E'; - compare(); - if (flags.z()) - goto fillcup; - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'C'; - ch = 'U'; - dl = 'P'; - dh = 'F'; - compare(); - if (flags.z()) - goto alreadyfull; - cx = 300; - al = 14; - showPuzText(); - putBackObStuff(); - return; -fillcup: - cx = 300; - al = 36; - showPuzText(); - putBackObStuff(); - al = data.byte(kWithobject); - getExAd(); - es.byte(bx+15) = 'F'-'A'; - return; -alreadyfull: - cx = 300; - al = 35; - showPuzText(); - putBackObStuff(); -} - -void DreamGenContext::useSLab() { - STACK_CHECK; - _cmp(data.byte(kWithobject), 255); - if (!flags.z()) - goto slabwith; - withWhat(); - return; -slabwith: - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'J'; - ch = 'E'; - dl = 'W'; - dh = 'L'; - compare(); - if (flags.z()) - goto nextslab; - cx = 300; - al = 14; - showPuzText(); - putBackObStuff(); - return; -nextslab: - al = data.byte(kWithobject); - getExAd(); - es.byte(bx+2) = 0; - al = data.byte(kCommand); - push(ax); - removeSetObject(); - ax = pop(); - _inc(al); - push(ax); - placeSetObject(); - ax = pop(); - _cmp(al, 54); - if (!flags.z()) - goto notlastslab; - al = 0; - turnPathOn(); - data.word(kWatchingtime) = 22; - data.word(kReeltowatch) = 35; - data.word(kEndwatchreel) = 48; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; -notlastslab: - _inc(data.byte(kProgresspoints)); - showFirstUse(); - data.byte(kGetback) = 1; -} - -void DreamGenContext::useOpenBox() { - STACK_CHECK; - _cmp(data.byte(kWithobject), 255); - if (!flags.z()) - goto openboxwith; - withWhat(); - return; -openboxwith: - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'C'; - ch = 'U'; - dl = 'P'; - dh = 'F'; - compare(); - if (flags.z()) - goto destoryopenbox; - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'C'; - ch = 'U'; - dl = 'P'; - dh = 'E'; - compare(); - if (flags.z()) - goto openboxwrong; - showFirstUse(); - return; -destoryopenbox: - _inc(data.byte(kProgresspoints)); - cx = 300; - al = 37; - showPuzText(); - al = data.byte(kWithobject); - getExAd(); - es.byte(bx+15) = 'E'-'A'; - data.word(kWatchingtime) = 140; - data.word(kReeltowatch) = 105; - data.word(kEndwatchreel) = 181; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - al = 4; - turnPathOn(); - data.byte(kGetback) = 1; - return; -openboxwrong: - cx = 300; - al = 38; - showPuzText(); - putBackObStuff(); -} - -void DreamGenContext::useAltar() { - STACK_CHECK; - al = 'C'; - ah = 'N'; - cl = 'D'; - ch = 'A'; - findExObject(); - _cmp(al, (114)); - if (flags.z()) - goto thingsonaltar; - al = 'C'; - ah = 'N'; - cl = 'D'; - ch = 'B'; - findExObject(); - _cmp(al, (114)); - if (flags.z()) - goto thingsonaltar; - _cmp(data.byte(kCanmovealtar), 1); - if (flags.z()) - goto movealtar; - cx = 300; - al = 23; - showPuzText(); - data.byte(kGetback) = 1; - return; -movealtar: - _inc(data.byte(kProgresspoints)); - showSecondUse(); - data.word(kWatchingtime) = 160; - data.word(kReeltowatch) = 81; - data.word(kEndwatchreel) = 174; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - al = 47; - bl = 52; - bh = 76; - cx = 32; - dx = 98; - setupTimedUse(); - data.byte(kGetback) = 1; - return; -thingsonaltar: - showFirstUse(); - data.byte(kGetback) = 1; -} - -void DreamGenContext::nextColon() { - STACK_CHECK; -lookcolon: - al = es.byte(si); - _inc(si); - _cmp(al, ':'); - if (!flags.z()) - goto lookcolon; -} - -void DreamGenContext::drawItAll() { - STACK_CHECK; - createPanel(); - drawFloor(); - printSprites(); - showIcon(); -} - -void DreamGenContext::useLighter() { - STACK_CHECK; - _cmp(data.byte(kWithobject), 255); - if (!flags.z()) - goto gotlighterwith; - withWhat(); - return; -gotlighterwith: - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'S'; - ch = 'M'; - dl = 'K'; - dh = 'E'; - compare(); - if (flags.z()) - goto cigarette; - showFirstUse(); - putBackObStuff(); - return; -cigarette: - cx = 300; - al = 9; - showPuzText(); - al = data.byte(kWithobject); - getExAd(); - es.byte(bx+2) = 255; - data.byte(kGetback) = 1; -} - -void DreamGenContext::useCashCard() { - STACK_CHECK; - getRidOfReels(); - loadKeypad(); - createPanel(); - showPanel(); - showExit(); - showMan(); - di = 114; - bx = 120; - _cmp(data.byte(kForeignrelease), 0); - if (flags.z()) - goto _tmp1; - bx = 120-3; -_tmp1: - ds = data.word(kTempgraphics); - al = 39; - ah = 0; - showFrame(); - ax = data.word(kCard1money); - moneyPoke(); - getObTextStart(); - nextColon(); - nextColon(); - di = 36; - bx = 98; - dl = 241; - al = 0; - ah = 0; - printDirect(); - di = 160; - bx = 155; - es = cs; - si = offset_money1poke; - data.word(kCharshift) = 91*2+75; - al = 0; - ah = 0; - dl = 240; - printDirect(); - di = 187; - bx = 155; - es = cs; - si = offset_money2poke; - data.word(kCharshift) = 91*2+85; - al = 0; - ah = 0; - dl = 240; - printDirect(); - data.word(kCharshift) = 0; - workToScreenM(); - cx = 400; - hangOnP(); - getRidOfTemp(); - restoreReels(); - putBackObStuff(); -} - -void DreamGenContext::lookAtCard() { - STACK_CHECK; - data.byte(kManisoffscreen) = 1; - getRidOfReels(); - loadKeypad(); - createPanel2(); - di = 160; - bx = 80; - ds = data.word(kTempgraphics); - al = 42; - ah = 128; - showFrame(); - getObTextStart(); - findNextColon(); - findNextColon(); - findNextColon(); - di = 36; - bx = 124; - dl = 241; - al = 0; - ah = 0; - printDirect(); - push(es); - push(si); - workToScreenM(); - cx = 280; - hangOnW(); - createPanel2(); - di = 160; - bx = 80; - ds = data.word(kTempgraphics); - al = 42; - ah = 128; - showFrame(); - si = pop(); - es = pop(); - di = 36; - bx = 130; - dl = 241; - al = 0; - ah = 0; - printDirect(); - workToScreenM(); - cx = 200; - hangOnW(); - data.byte(kManisoffscreen) = 0; - getRidOfTemp(); - restoreReels(); - putBackObStuff(); -} - -void DreamGenContext::moneyPoke() { - STACK_CHECK; - bx = offset_money1poke; - cl = 48-1; -numberpoke0: - _inc(cl); - _sub(ax, 10000); - if (!flags.c()) - goto numberpoke0; - _add(ax, 10000); - cs.byte(bx) = cl; - _inc(bx); - cl = 48-1; -numberpoke1: - _inc(cl); - _sub(ax, 1000); - if (!flags.c()) - goto numberpoke1; - _add(ax, 1000); - cs.byte(bx) = cl; - _inc(bx); - cl = 48-1; -numberpoke2: - _inc(cl); - _sub(ax, 100); - if (!flags.c()) - goto numberpoke2; - _add(ax, 100); - cs.byte(bx) = cl; - _inc(bx); - cl = 48-1; -numberpoke3: - _inc(cl); - _sub(ax, 10); - if (!flags.c()) - goto numberpoke3; - _add(ax, 10); - cs.byte(bx) = cl; - bx = offset_money2poke; - _add(al, 48); - cs.byte(bx) = al; -} - -void DreamGenContext::useControl() { - STACK_CHECK; - _cmp(data.byte(kWithobject), 255); - if (!flags.z()) - goto gotcontrolwith; - withWhat(); - return; -gotcontrolwith: - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'K'; - ch = 'E'; - dl = 'Y'; - dh = 'A'; - compare(); - if (flags.z()) - goto rightkey; - _cmp(data.byte(kReallocation), 21); - if (!flags.z()) - goto balls; - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'K'; - ch = 'N'; - dl = 'F'; - dh = 'E'; - compare(); - if (flags.z()) - goto jimmycontrols; - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'A'; - ch = 'X'; - dl = 'E'; - dh = 'D'; - compare(); - if (flags.z()) - goto axeoncontrols; -balls: - showFirstUse(); - putBackObStuff(); - return; -rightkey: - al = 16; - playChannel1(); - _cmp(data.byte(kLocation), 21); - if (flags.z()) - goto goingdown; - cx = 300; - al = 0; - showPuzText(); - data.byte(kNewlocation) = 21; - data.byte(kCounttoclose) = 8; - data.byte(kCounttoopen) = 0; - data.word(kWatchingtime) = 80; - data.byte(kGetback) = 1; - return; -goingdown: - cx = 300; - al = 3; - showPuzText(); - data.byte(kNewlocation) = 30; - data.byte(kCounttoclose) = 8; - data.byte(kCounttoopen) = 0; - data.word(kWatchingtime) = 80; - data.byte(kGetback) = 1; - return; -jimmycontrols: - al = 50; - placeSetObject(); - al = 51; - placeSetObject(); - al = 26; - placeSetObject(); - al = 30; - placeSetObject(); - al = 16; - removeSetObject(); - al = 17; - removeSetObject(); - al = 14; - playChannel1(); - cx = 300; - al = 10; - showPuzText(); - _inc(data.byte(kProgresspoints)); - data.byte(kGetback) = 1; - return; -axeoncontrols: - cx = 300; - al = 16; - showPuzText(); - _inc(data.byte(kProgresspoints)); - putBackObStuff(); -} - -void DreamGenContext::useWire() { - STACK_CHECK; - _cmp(data.byte(kWithobject), 255); - if (!flags.z()) - goto gotwirewith; - withWhat(); - return; -gotwirewith: - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'K'; - ch = 'N'; - dl = 'F'; - dh = 'E'; - compare(); - if (flags.z()) - goto wireknife; - al = data.byte(kWithobject); - ah = data.byte(kWithtype); - cl = 'A'; - ch = 'X'; - dl = 'E'; - dh = 'D'; - compare(); - if (flags.z()) - goto wireaxe; - cx = 300; - al = 14; - showPuzText(); - putBackObStuff(); - return; -wireaxe: - cx = 300; - al = 16; - showPuzText(); - putBackObStuff(); - return; -wireknife: - al = 51; - removeSetObject(); - al = 52; - placeSetObject(); - cx = 300; - al = 11; - showPuzText(); - _inc(data.byte(kProgresspoints)); - data.byte(kGetback) = 1; -} - -void DreamGenContext::useHandle() { - STACK_CHECK; - al = 'C'; - ah = 'U'; - cl = 'T'; - ch = 'W'; - findSetObject(); - al = es.byte(bx+58); - _cmp(al, 255); - if (!flags.z()) - goto havecutwire; - cx = 300; - al = 12; - showPuzText(); - data.byte(kGetback) = 1; - return; -havecutwire: - cx = 300; - al = 13; - showPuzText(); - data.byte(kNewlocation) = 22; - data.byte(kGetback) = 1; -} - -void DreamGenContext::useKey() { - STACK_CHECK; - _cmp(data.byte(kLocation), 5); - if (flags.z()) - goto usekey1; - _cmp(data.byte(kLocation), 30); - if (flags.z()) - goto usekey1; - _cmp(data.byte(kLocation), 21); - if (flags.z()) - goto usekey2; - cx = 200; - al = 1; - showPuzText(); - putBackObStuff(); - return; -usekey1: - _cmp(data.byte(kMapx), 22); - if (!flags.z()) - goto wrongroom1; - _cmp(data.byte(kMapy), 10); - if (!flags.z()) - goto wrongroom1; - cx = 300; - al = 0; - showPuzText(); - data.byte(kCounttoclose) = 100; - data.byte(kGetback) = 1; - return; -usekey2: - _cmp(data.byte(kMapx), 11); - if (!flags.z()) - goto wrongroom1; - _cmp(data.byte(kMapy), 10); - if (!flags.z()) - goto wrongroom1; - cx = 300; - al = 3; - showPuzText(); - data.byte(kNewlocation) = 30; - al = 2; - fadeScreenDown(); - showFirstUse(); - putBackObStuff(); - return; -wrongroom1: - cx = 200; - al = 2; - showPuzText(); - putBackObStuff(); -} - -void DreamGenContext::useStereo() { - STACK_CHECK; - _cmp(data.byte(kLocation), 0); - if (flags.z()) - goto stereook; - cx = 400; - al = 4; - showPuzText(); - putBackObStuff(); - return; -stereook: - _cmp(data.byte(kMapx), 11); - if (!flags.z()) - goto stereonotok; - _cmp(data.byte(kMapy), 0); - if (flags.z()) - goto stereook2; -stereonotok: - cx = 400; - al = 5; - showPuzText(); - putBackObStuff(); - return; -stereook2: - al = 'C'; - ah = 'D'; - cl = 'P'; - ch = 'L'; - findSetObject(); - ah = 1; - checkInside(); - _cmp(cl, (114)); - if (!flags.z()) - goto cdinside; - al = 6; - cx = 400; - showPuzText(); - putBackObStuff(); - getAnyAd(); - al = 255; - es.byte(bx+10) = al; - return; -cdinside: - getAnyAd(); - al = es.byte(bx+10); - _xor(al, 1); - es.byte(bx+10) = al; - _cmp(al, 255); - if (flags.z()) - goto stereoon; - al = 7; - cx = 400; - showPuzText(); - putBackObStuff(); - return; -stereoon: - al = 8; - cx = 400; - showPuzText(); - putBackObStuff(); -} - -void DreamGenContext::useCooker() { - STACK_CHECK; - al = data.byte(kCommand); - ah = data.byte(kObjecttype); - checkInside(); - _cmp(cl, (114)); - if (!flags.z()) - goto foodinside; - showFirstUse(); - putBackObStuff(); - return; -foodinside: - showSecondUse(); - putBackObStuff(); -} - -void DreamGenContext::useAxe() { - STACK_CHECK; - _cmp(data.byte(kReallocation), 22); - if (!flags.z()) - goto notinpool; - _cmp(data.byte(kMapy), 10); - if (flags.z()) - goto axeondoor; - showSecondUse(); - _inc(data.byte(kProgresspoints)); - data.byte(kLastweapon) = 2; - data.byte(kGetback) = 1; - removeObFromInv(); - return; -notinpool: - showFirstUse(); - return; -/*continuing to unbounded code: axeondoor from useelvdoor:19-30*/ -axeondoor: - al = 15; - cx = 300; - showPuzText(); - _inc(data.byte(kProgresspoints)); - data.word(kWatchingtime) = 46*2; - data.word(kReeltowatch) = 31; - data.word(kEndwatchreel) = 77; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - data.byte(kGetback) = 1; -} - -void DreamGenContext::withWhat() { - STACK_CHECK; - createPanel(); - showPanel(); - showMan(); - showExit(); - al = data.byte(kCommand); - ah = data.byte(kObjecttype); - es = cs; - di = offset_commandline; - copyName(); - di = 100; - bx = 21; - dl = 200; - al = 63; - ah = 2; - printmessage2(); - di = data.word(kLastxpos); - _add(di, 5); - bx = 21; - es = cs; - si = offset_commandline; - dl = 220; - al = 0; - ah = 0; - printDirect(); - di = data.word(kLastxpos); - _add(di, 5); - bx = 21; - dl = 200; - al = 63; - ah = 3; - printmessage2(); - fillRyan(); - data.byte(kCommandtype) = 255; - readMouse(); - showPointer(); - workToScreen(); - delPointer(); - data.byte(kInvopen) = 2; -} - -void DreamGenContext::selectOb() { - STACK_CHECK; - findInvPos(); - ax = es.word(bx); - _cmp(al, 255); - if (!flags.z()) - goto canselectob; - blank(); - return; -canselectob: - data.byte(kWithobject) = al; - data.byte(kWithtype) = ah; - _cmp(ax, data.word(kOldsubject)); - if (!flags.z()) - goto diffsub3; - _cmp(data.byte(kCommandtype), 221); - if (flags.z()) - goto alreadyselob; - data.byte(kCommandtype) = 221; -diffsub3: - data.word(kOldsubject) = ax; - bx = ax; - al = 0; - commandWithOb(); -alreadyselob: - ax = data.word(kMousebutton); - _cmp(ax, data.word(kOldbutton)); - if (flags.z()) - return /* (notselob) */; - _and(ax, 1); - if (!flags.z()) - goto doselob; - return; -doselob: - delPointer(); - data.byte(kInvopen) = 0; - useRoutine(); -} - -void DreamGenContext::findSetObject() { - STACK_CHECK; - _sub(al, 'A'); - _sub(ah, 'A'); - _sub(cl, 'A'); - _sub(ch, 'A'); - es = data.word(kSetdat); - bx = 0; - dl = 0; -findsetloop: - _cmp(al, es.byte(bx+12)); - if (!flags.z()) - goto nofind; - _cmp(ah, es.byte(bx+13)); - if (!flags.z()) - goto nofind; - _cmp(cl, es.byte(bx+14)); - if (!flags.z()) - goto nofind; - _cmp(ch, es.byte(bx+15)); - if (!flags.z()) - goto nofind; - al = dl; - return; -nofind: - _add(bx, 64); - _inc(dl); - _cmp(dl, 128); - if (!flags.z()) - goto findsetloop; - al = dl; -} - -void DreamGenContext::findExObject() { - STACK_CHECK; - _sub(al, 'A'); - _sub(ah, 'A'); - _sub(cl, 'A'); - _sub(ch, 'A'); - es = data.word(kExtras); - bx = (0+2080+30000); - dl = 0; -findexloop: - _cmp(al, es.byte(bx+12)); - if (!flags.z()) - goto nofindex; - _cmp(ah, es.byte(bx+13)); - if (!flags.z()) - goto nofindex; - _cmp(cl, es.byte(bx+14)); - if (!flags.z()) - goto nofindex; - _cmp(ch, es.byte(bx+15)); - if (!flags.z()) - goto nofindex; - al = dl; - return; -nofindex: - _add(bx, 16); - _inc(dl); - _cmp(dl, (114)); - if (!flags.z()) - goto findexloop; - al = dl; -} - -void DreamGenContext::isRyanHolding() { - STACK_CHECK; - _sub(al, 'A'); - _sub(ah, 'A'); - _sub(cl, 'A'); - _sub(ch, 'A'); - es = data.word(kExtras); - bx = (0+2080+30000); - dl = 0; -searchinv: - _cmp(es.byte(bx+2), 4); - if (!flags.z()) - goto nofindininv; - _cmp(al, es.byte(bx+12)); - if (!flags.z()) - goto nofindininv; - _cmp(ah, es.byte(bx+13)); - if (!flags.z()) - goto nofindininv; - _cmp(cl, es.byte(bx+14)); - if (!flags.z()) - goto nofindininv; - _cmp(ch, es.byte(bx+15)); - if (!flags.z()) - goto nofindininv; - al = dl; - _cmp(al, (114)); - return; -nofindininv: - _add(bx, 16); - _inc(dl); - _cmp(dl, (114)); - if (!flags.z()) - goto searchinv; - al = dl; - _cmp(al, (114)); -} - -void DreamGenContext::checkInside() { - STACK_CHECK; - es = data.word(kExtras); - bx = (0+2080+30000); - cl = 0; -insideloop: - _cmp(al, es.byte(bx+3)); - if (!flags.z()) - goto notfoundinside; - _cmp(ah, es.byte(bx+2)); - if (!flags.z()) - goto notfoundinside; - return; -notfoundinside: - _add(bx, 16); - _inc(cl); - _cmp(cl, (114)); - if (!flags.z()) - goto insideloop; -} - -void DreamGenContext::showPuzText() { - STACK_CHECK; - push(cx); - findPuzText(); - push(es); - push(si); - createPanel(); - showPanel(); - showMan(); - showExit(); - obIcons(); - si = pop(); - es = pop(); - di = 36; - bx = 104; - dl = 241; - ah = 0; - printDirect(); - workToScreenM(); - cx = pop(); - hangOnP(); -} - -void DreamGenContext::findPuzText() { - STACK_CHECK; - ah = 0; - si = ax; - _add(si, si); - es = data.word(kPuzzletext); - ax = es.word(si); - _add(ax, (66*2)); - si = ax; -} - -void DreamGenContext::placeFreeObject() { - STACK_CHECK; - push(es); - push(bx); - cl = 0; - ch = 1; - findOrMake(); - getFreeAd(); - es.byte(bx+2) = 0; - bx = pop(); - es = pop(); -} - -void DreamGenContext::removeFreeObject() { - STACK_CHECK; - push(es); - push(bx); - getFreeAd(); - es.byte(bx+2) = 255; - bx = pop(); - es = pop(); -} - -void DreamGenContext::autoAppear() { - STACK_CHECK; - _cmp(data.byte(kLocation), 32); - if (!flags.z()) - goto notinalley; - al = 5; - resetLocation(); - al = 10; - setLocation(); - data.byte(kDestpos) = 10; - return; -notinalley: - _cmp(data.byte(kReallocation), 24); - if (!flags.z()) - goto notinedens; - _cmp(data.byte(kGeneraldead), 1); - if (!flags.z()) - goto edenspart2; - _inc(data.byte(kGeneraldead)); - al = 44; - placeSetObject(); - al = 18; - placeSetObject(); - al = 93; - placeSetObject(); - al = 92; - removeSetObject(); - al = 55; - removeSetObject(); - al = 75; - removeSetObject(); - al = 84; - removeSetObject(); - al = 85; - removeSetObject(); - return; -edenspart2: - _cmp(data.byte(kSartaindead), 1); - if (!flags.z()) - return /* (notedens2) */; - al = 44; - removeSetObject(); - al = 93; - removeSetObject(); - al = 55; - placeSetObject(); - _inc(data.byte(kSartaindead)); - return; -notinedens: - _cmp(data.byte(kReallocation), 25); - if (!flags.z()) - goto notonsartroof; - data.byte(kNewsitem) = 3; - al = 6; - resetLocation(); - al = 11; - setLocation(); - data.byte(kDestpos) = 11; - return; -notonsartroof: - _cmp(data.byte(kReallocation), 2); - if (!flags.z()) - return /* (notinlouiss) */; - _cmp(data.byte(kRockstardead), 0); - if (flags.z()) - return /* (notinlouiss) */; - al = 23; - placeSetObject(); -} - -void DreamGenContext::setupTimedUse() { - STACK_CHECK; - _cmp(data.word(kTimecount), 0); - if (!flags.z()) - return /* (cantsetup) */; - data.byte(kTimedy) = bh; - data.byte(kTimedx) = bl; - data.word(kCounttotimed) = cx; - _add(dx, cx); - data.word(kTimecount) = dx; - bl = al; - bh = 0; - _add(bx, bx); - es = data.word(kPuzzletext); - cx = (66*2); - ax = es.word(bx); - _add(ax, cx); - bx = ax; - data.word(kTimedseg) = es; - data.word(kTimedoffset) = bx; -} - -void DreamGenContext::useGun() { - STACK_CHECK; - _cmp(data.byte(kObjecttype), 4); - if (flags.z()) - goto istakengun; - showSecondUse(); - putBackObStuff(); - return; -istakengun: - _cmp(data.byte(kReallocation), 22); - if (!flags.z()) - goto notinpoolroom; - cx = 300; - al = 34; - showPuzText(); - data.byte(kLastweapon) = 1; - data.byte(kCombatcount) = 39; - data.byte(kGetback) = 1; - _inc(data.byte(kProgresspoints)); - return; -notinpoolroom: - _cmp(data.byte(kReallocation), 25); - if (!flags.z()) - goto nothelicopter; - cx = 300; - al = 34; - showPuzText(); - data.byte(kLastweapon) = 1; - data.byte(kCombatcount) = 19; - data.byte(kGetback) = 1; - data.byte(kDreamnumber) = 2; - data.byte(kRoomafterdream) = 38; - data.byte(kSartaindead) = 1; - _inc(data.byte(kProgresspoints)); - return; -nothelicopter: - _cmp(data.byte(kReallocation), 27); - if (!flags.z()) - goto notinrockroom; - cx = 300; - al = 46; - showPuzText(); - data.byte(kPointermode) = 2; - data.byte(kRockstardead) = 1; - data.byte(kLastweapon) = 1; - data.byte(kNewsitem) = 1; - data.byte(kGetback) = 1; - data.byte(kRoomafterdream) = 32; - data.byte(kDreamnumber) = 0; - _inc(data.byte(kProgresspoints)); - return; -notinrockroom: - _cmp(data.byte(kReallocation), 8); - if (!flags.z()) - goto notbystudio; - _cmp(data.byte(kMapx), 22); - if (!flags.z()) - goto notbystudio; - _cmp(data.byte(kMapy), 40); - if (!flags.z()) - goto notbystudio; - al = 92; - isSetObOnMap(); - if (flags.z()) - goto notbystudio; - _cmp(data.byte(kManspath), 9); - if (flags.z()) - goto notbystudio; - data.byte(kDestination) = 9; - data.byte(kFinaldest) = 9; - autoSetWalk(); - data.byte(kLastweapon) = 1; - data.byte(kGetback) = 1; - _inc(data.byte(kProgresspoints)); - return; -notbystudio: - _cmp(data.byte(kReallocation), 6); - if (!flags.z()) - goto notsarters; - _cmp(data.byte(kMapx), 11); - if (!flags.z()) - goto notsarters; - _cmp(data.byte(kMapy), 20); - if (!flags.z()) - goto notsarters; - al = 5; - isSetObOnMap(); - if (!flags.z()) - goto notsarters; - data.byte(kDestination) = 1; - data.byte(kFinaldest) = 1; - autoSetWalk(); - al = 5; - removeSetObject(); - al = 6; - placeSetObject(); - al = 1; - ah = data.byte(kRoomnum); - _dec(ah); - turnAnyPathOn(); - data.byte(kLiftflag) = 1; - data.word(kWatchingtime) = 40*2; - data.word(kReeltowatch) = 4; - data.word(kEndwatchreel) = 43; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - data.byte(kGetback) = 1; - _inc(data.byte(kProgresspoints)); - return; -notsarters: - _cmp(data.byte(kReallocation), 29); - if (!flags.z()) - goto notaide; - data.byte(kGetback) = 1; - al = 13; - resetLocation(); - al = 12; - setLocation(); - data.byte(kDestpos) = 12; - data.byte(kDestination) = 2; - data.byte(kFinaldest) = 2; - autoSetWalk(); - data.word(kWatchingtime) = 164*2; - data.word(kReeltowatch) = 3; - data.word(kEndwatchreel) = 164; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - data.byte(kAidedead) = 1; - data.byte(kDreamnumber) = 3; - data.byte(kRoomafterdream) = 33; - _inc(data.byte(kProgresspoints)); - return; -notaide: - _cmp(data.byte(kReallocation), 23); - if (!flags.z()) - goto notwithboss; - _cmp(data.byte(kMapx), 0); - if (!flags.z()) - goto notwithboss; - _cmp(data.byte(kMapy), 50); - if (!flags.z()) - goto notwithboss; - _cmp(data.byte(kManspath), 5); - if (flags.z()) - goto pathokboss; - data.byte(kDestination) = 5; - data.byte(kFinaldest) = 5; - autoSetWalk(); -pathokboss: - data.byte(kLastweapon) = 1; - data.byte(kGetback) = 1; - return; -notwithboss: - _cmp(data.byte(kReallocation), 8); - if (!flags.z()) - goto nottvsoldier; - _cmp(data.byte(kMapx), 11); - if (!flags.z()) - goto nottvsoldier; - _cmp(data.byte(kMapy), 10); - if (!flags.z()) - goto nottvsoldier; - _cmp(data.byte(kManspath), 2); - if (flags.z()) - goto pathoktv; - data.byte(kDestination) = 2; - data.byte(kFinaldest) = 2; - autoSetWalk(); -pathoktv: - data.byte(kLastweapon) = 1; - data.byte(kGetback) = 1; - return; -nottvsoldier: - showFirstUse(); - putBackObStuff(); -} - -void DreamGenContext::useButtonA() { - STACK_CHECK; - al = 95; - isSetObOnMap(); - if (flags.z()) - goto donethisbit; - showFirstUse(); - al = 0; - ah = data.byte(kRoomnum); - _dec(ah); - turnAnyPathOn(); - al = 9; - removeSetObject(); - al = 95; - placeSetObject(); - data.word(kWatchingtime) = 15*2; - data.word(kReeltowatch) = 71; - data.word(kEndwatchreel) = 85; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - data.byte(kGetback) = 1; - _inc(data.byte(kProgresspoints)); - return; -donethisbit: - showSecondUse(); - putBackObStuff(); -} - -void DreamGenContext::quitKey() { - STACK_CHECK; - _cmp(data.byte(kCommandtype), 222); - if (flags.z()) - goto alreadyqk; - data.byte(kCommandtype) = 222; - al = 4; - commandOnly(); -alreadyqk: - ax = data.word(kMousebutton); - _cmp(ax, data.word(kOldbutton)); - if (flags.z()) - return /* (notqk) */; - _and(ax, 1); - if (!flags.z()) - goto doqk; - return; -doqk: - data.byte(kGetback) = 1; -} - -void DreamGenContext::quitSymbol() { - STACK_CHECK; - _cmp(data.byte(kSymboltopx), 24); - if (!flags.z()) - { blank(); return; }; - _cmp(data.byte(kSymbolbotx), 24); - if (!flags.z()) - { blank(); return; }; - _cmp(data.byte(kCommandtype), 222); - if (flags.z()) - goto alreadyqs; - data.byte(kCommandtype) = 222; - al = 18; - commandOnly(); -alreadyqs: - ax = data.word(kMousebutton); - _cmp(ax, data.word(kOldbutton)); - if (flags.z()) - return /* (notqs) */; - _and(ax, 1); - if (!flags.z()) - goto doqs; - return; -doqs: - data.byte(kGetback) = 1; -} - -void DreamGenContext::updateSymbolTop() { - STACK_CHECK; - _cmp(data.byte(kSymboltopdir), 0); - if (flags.z()) - return /* (topfinished) */; - _cmp(data.byte(kSymboltopdir), -1); - if (flags.z()) - goto backwards; - _inc(data.byte(kSymboltopx)); - _cmp(data.byte(kSymboltopx), 49); - if (!flags.z()) - goto notwrapfor; - data.byte(kSymboltopx) = 0; - _dec(data.byte(kSymboltopnum)); - _cmp(data.byte(kSymboltopnum), -1); - if (!flags.z()) - return /* (topfinished) */; - data.byte(kSymboltopnum) = 5; - return; -notwrapfor: - _cmp(data.byte(kSymboltopx), 24); - if (!flags.z()) - return /* (topfinished) */; - data.byte(kSymboltopdir) = 0; - return; -backwards: - _dec(data.byte(kSymboltopx)); - _cmp(data.byte(kSymboltopx), -1); - if (!flags.z()) - goto notwrapback; - data.byte(kSymboltopx) = 48; - _inc(data.byte(kSymboltopnum)); - _cmp(data.byte(kSymboltopnum), 6); - if (!flags.z()) - return /* (topfinished) */; - data.byte(kSymboltopnum) = 0; - return; -notwrapback: - _cmp(data.byte(kSymboltopx), 24); - if (!flags.z()) - return /* (topfinished) */; - data.byte(kSymboltopdir) = 0; -} - -void DreamGenContext::updateSymbolBot() { - STACK_CHECK; - _cmp(data.byte(kSymbolbotdir), 0); - if (flags.z()) - return /* (botfinished) */; - _cmp(data.byte(kSymbolbotdir), -1); - if (flags.z()) - goto backwardsbot; - _inc(data.byte(kSymbolbotx)); - _cmp(data.byte(kSymbolbotx), 49); - if (!flags.z()) - goto notwrapforb; - data.byte(kSymbolbotx) = 0; - _dec(data.byte(kSymbolbotnum)); - _cmp(data.byte(kSymbolbotnum), -1); - if (!flags.z()) - return /* (botfinished) */; - data.byte(kSymbolbotnum) = 5; - return; -notwrapforb: - _cmp(data.byte(kSymbolbotx), 24); - if (!flags.z()) - return /* (botfinished) */; - data.byte(kSymbolbotdir) = 0; - return; -backwardsbot: - _dec(data.byte(kSymbolbotx)); - _cmp(data.byte(kSymbolbotx), -1); - if (!flags.z()) - goto notwrapbackb; - data.byte(kSymbolbotx) = 48; - _inc(data.byte(kSymbolbotnum)); - _cmp(data.byte(kSymbolbotnum), 6); - if (!flags.z()) - return /* (botfinished) */; - data.byte(kSymbolbotnum) = 0; - return; -notwrapbackb: - _cmp(data.byte(kSymbolbotx), 24); - if (!flags.z()) - return /* (botfinished) */; - data.byte(kSymbolbotdir) = 0; -} - -void DreamGenContext::useDiary() { - STACK_CHECK; - getRidOfReels(); - dx = 1009; - loadIntoTemp(); - dx = 1022; - loadTempText(); - dx = 983; - loadTempCharset(); - createPanel(); - showIcon(); - showDiary(); - underTextLine(); - showDiaryPage(); - readMouse(); - showPointer(); - workToScreen(); - delPointer(); - data.byte(kGetback) = 0; -diaryloop: - delPointer(); - readMouse(); - showDiaryKeys(); - showPointer(); - vSync(); - dumpPointer(); - dumpDiaryKeys(); - dumpTextLine(); - bx = offset_diarylist; - checkCoords(); - _cmp(data.byte(kGetback), 0); - if (flags.z()) - goto diaryloop; - getRidOfTemp(); - getRidOfTempText(); - getRidOfTempCharset(); - restoreReels(); - data.byte(kManisoffscreen) = 0; - redrawMainScrn(); - workToScreenM(); -} - -void DreamGenContext::showDiary() { - STACK_CHECK; - al = 1; - ah = 0; - di = (68+24); - bx = (48+12)+37; - ds = data.word(kTempgraphics); - showFrame(); - al = 2; - ah = 0; - di = (68+24)+176; - bx = (48+12)+108; - ds = data.word(kTempgraphics); - showFrame(); -} - -void DreamGenContext::showDiaryKeys() { - STACK_CHECK; - _cmp(data.byte(kPresscount), 0); - if (flags.z()) - return /* (nokeyatall) */; - _dec(data.byte(kPresscount)); - _cmp(data.byte(kPresscount), 0); - if (flags.z()) - return /* (nokeyatall) */; - _cmp(data.byte(kPressed), 'N'); - if (!flags.z()) - goto nokeyn; - al = 3; - _cmp(data.byte(kPresscount), 1); - if (flags.z()) - goto gotkeyn; - al = 4; -gotkeyn: - ah = 0; - di = (68+24)+94; - bx = (48+12)+97; - ds = data.word(kTempgraphics); - showFrame(); - _cmp(data.byte(kPresscount), 1); - if (!flags.z()) - return /* (notshown) */; - showDiaryPage(); - return; -nokeyn: - al = 5; - _cmp(data.byte(kPresscount), 1); - if (flags.z()) - goto gotkeyp; - al = 6; -gotkeyp: - ah = 0; - di = (68+24)+151; - bx = (48+12)+71; - ds = data.word(kTempgraphics); - showFrame(); - _cmp(data.byte(kPresscount), 1); - if (!flags.z()) - return /* (notshowp) */; - showDiaryPage(); -} - -void DreamGenContext::dumpDiaryKeys() { - STACK_CHECK; - _cmp(data.byte(kPresscount), 1); - if (!flags.z()) - goto notdumpdiary; - _cmp(data.byte(kSartaindead), 1); - if (flags.z()) - goto notsartadd; - _cmp(data.byte(kDiarypage), 5); - if (!flags.z()) - goto notsartadd; - _cmp(data.byte(kDiarypage), 5); - if (!flags.z()) - goto notsartadd; - al = 6; - getLocation(); - _cmp(al, 1); - if (flags.z()) - goto notsartadd; - al = 6; - setLocation(); - delPointer(); - al = 12; - findText1(); - di = 70; - bx = 106; - dl = 241; - ah = 16; - printDirect(); - workToScreenM(); - cx = 200; - hangOnP(); - createPanel(); - showIcon(); - showDiary(); - showDiaryPage(); - workToScreenM(); - showPointer(); - return; -notsartadd: - di = (68+24)+48; - bx = (48+12)+15; - cl = 200; - ch = 16; - multiDump(); -notdumpdiary: - di = (68+24)+94; - bx = (48+12)+97; - cl = 16; - ch = 16; - multiDump(); - di = (68+24)+151; - bx = (48+12)+71; - cl = 16; - ch = 16; - multiDump(); -} - -void DreamGenContext::diaryKeyP() { - STACK_CHECK; - _cmp(data.byte(kCommandtype), 214); - if (flags.z()) - goto alreadykeyp; - data.byte(kCommandtype) = 214; - al = 23; - commandOnly(); -alreadykeyp: - _cmp(data.word(kMousebutton), 0); - if (flags.z()) - return /* (notkeyp) */; - ax = data.word(kOldbutton); - _cmp(ax, data.word(kMousebutton)); - if (flags.z()) - return /* (notkeyp) */; - _cmp(data.byte(kPresscount), 0); - if (!flags.z()) - return /* (notkeyp) */; - al = 16; - playChannel1(); - data.byte(kPresscount) = 12; - data.byte(kPressed) = 'P'; - _dec(data.byte(kDiarypage)); - _cmp(data.byte(kDiarypage), -1); - if (!flags.z()) - return /* (notkeyp) */; - data.byte(kDiarypage) = 11; -} - -void DreamGenContext::diaryKeyN() { - STACK_CHECK; - _cmp(data.byte(kCommandtype), 213); - if (flags.z()) - goto alreadykeyn; - data.byte(kCommandtype) = 213; - al = 23; - commandOnly(); -alreadykeyn: - _cmp(data.word(kMousebutton), 0); - if (flags.z()) - return /* (notkeyn) */; - ax = data.word(kOldbutton); - _cmp(ax, data.word(kMousebutton)); - if (flags.z()) - return /* (notkeyn) */; - _cmp(data.byte(kPresscount), 0); - if (!flags.z()) - return /* (notkeyn) */; - al = 16; - playChannel1(); - data.byte(kPresscount) = 12; - data.byte(kPressed) = 'N'; - _inc(data.byte(kDiarypage)); - _cmp(data.byte(kDiarypage), 12); - if (!flags.z()) - return /* (notkeyn) */; - data.byte(kDiarypage) = 0; -} - -void DreamGenContext::showDiaryPage() { - STACK_CHECK; - al = 0; - ah = 0; - di = (68+24); - bx = (48+12); - ds = data.word(kTempgraphics); - showFrame(); - al = data.byte(kDiarypage); - findText1(); - data.byte(kKerning) = 1; - useTempCharset(); - di = (68+24)+48; - bx = (48+12)+16; - dl = 240; - ah = 16; - data.word(kCharshift) = 91+91; - printDirect(); - di = (68+24)+129; - bx = (48+12)+16; - dl = 240; - ah = 16; - printDirect(); - di = (68+24)+48; - bx = (48+12)+23; - dl = 240; - ah = 16; - printDirect(); - data.byte(kKerning) = 0; - data.word(kCharshift) = 0; - useCharset1(); -} - -void DreamGenContext::findText1() { - STACK_CHECK; - ah = 0; - si = ax; - _add(si, si); - es = data.word(kTextfile1); - ax = es.word(si); - _add(ax, (66*2)); - si = ax; -} - -void DreamGenContext::doSaveLoad() { - STACK_CHECK; - data.byte(kPointerframe) = 0; - data.word(kTextaddressx) = 70; - data.word(kTextaddressy) = 182-8; - data.byte(kTextlen) = 181; - data.byte(kManisoffscreen) = 1; - clearWork(); - createPanel2(); - underTextLine(); - getRidOfAll(); - loadSaveBox(); - showOpBox(); - showMainOps(); - workToScreen(); - goto donefirstops; -restartops: - showOpBox(); - showMainOps(); - workToScreenM(); -donefirstops: - data.byte(kGetback) = 0; -waitops: - _cmp(data.byte(kQuitrequested), 0); - if (!flags.z()) - goto justret; - readMouse(); - showPointer(); - vSync(); - dumpPointer(); - dumpTextLine(); - delPointer(); - bx = offset_opslist; - checkCoords(); - _cmp(data.byte(kGetback), 0); - if (flags.z()) - goto waitops; - _cmp(data.byte(kGetback), 2); - if (flags.z()) - goto restartops; - data.word(kTextaddressx) = 13; - data.word(kTextaddressy) = 182; - data.byte(kTextlen) = 240; - _cmp(data.byte(kGetback), 4); - if (flags.z()) - goto justret; - getRidOfTemp(); - restoreAll(); - redrawMainScrn(); - workToScreenM(); - data.byte(kCommandtype) = 200; -justret: - data.byte(kManisoffscreen) = 0; -} - -void DreamGenContext::discOps() { - STACK_CHECK; - _cmp(data.byte(kCommandtype), 249); - if (flags.z()) - goto alreadydiscops; - data.byte(kCommandtype) = 249; - al = 43; - commandOnly(); -alreadydiscops: - ax = data.word(kMousebutton); - _cmp(ax, data.word(kOldbutton)); - if (flags.z()) - return /* (nodiscops) */; - _and(ax, 1); - if (!flags.z()) - goto dodiscops; - return; -dodiscops: - scanForNames(); - data.byte(kLoadingorsave) = 2; - showOpBox(); - showDiscOps(); - data.byte(kCurrentslot) = 0; - workToScreenM(); - data.byte(kGetback) = 0; -discopsloop: - _cmp(data.byte(kQuitrequested), 0); - if (!flags.z()) - return /* (quitdiscops) */; - delPointer(); - readMouse(); - showPointer(); - vSync(); - dumpPointer(); - dumpTextLine(); - bx = offset_discopslist; - checkCoords(); - _cmp(data.byte(kGetback), 0); - if (flags.z()) - goto discopsloop; -} - -void DreamGenContext::checkInput() { - STACK_CHECK; - _cmp(data.byte(kLoadingorsave), 3); - if (flags.z()) - return /* (nokeypress) */; - readKey(); - al = data.byte(kCurrentkey); - _cmp(al, 0); - if (flags.z()) - return /* (nokeypress) */; - _cmp(al, 13); - if (!flags.z()) - goto notret; - data.byte(kLoadingorsave) = 3; - goto afterkey; -notret: - _cmp(al, 8); - if (!flags.z()) - goto nodel2; - _cmp(data.byte(kCursorpos), 0); - if (flags.z()) - return /* (nokeypress) */; - getNamePos(); - _dec(data.byte(kCursorpos)); - es.byte(bx) = 0; - es.byte(bx+1) = 1; - goto afterkey; -nodel2: - _cmp(data.byte(kCursorpos), 14); - if (flags.z()) - return /* (nokeypress) */; - getNamePos(); - _inc(data.byte(kCursorpos)); - al = data.byte(kCurrentkey); - es.byte(bx+1) = al; - es.byte(bx+2) = 0; - es.byte(bx+3) = 1; - goto afterkey; - return; -afterkey: - showOpBox(); - showNames(); - showSlots(); - showSaveOps(); - workToScreenM(); -} - -void DreamGenContext::getNamePos() { - STACK_CHECK; - al = data.byte(kCurrentslot); - ah = 0; - cx = 17; - _mul(cx); - dx = data; - es = dx; - bx = 1829; - _add(bx, ax); - al = data.byte(kCursorpos); - ah = 0; - _add(bx, ax); -} - -void DreamGenContext::showOpBox() { - STACK_CHECK; - ds = data.word(kTempgraphics); - di = (60); - bx = (52); - al = 0; - ah = 0; - showFrame(); - ds = data.word(kTempgraphics); - di = (60); - bx = (52)+55; - al = 4; - ah = 0; - showFrame(); -} - -void DreamGenContext::showLoadOps() { - STACK_CHECK; - ds = data.word(kTempgraphics); - di = (60)+128+4; - bx = (52)+12; - al = 1; - ah = 0; - showFrame(); - ds = data.word(kTempgraphics); - di = (60)+176+2; - bx = (52)+60-4; - al = 5; - ah = 0; - showFrame(); - di = (60)+104; - bx = (52)+14; - al = 55; - dl = 101; - printMessage(); -} - -void DreamGenContext::showSaveOps() { - STACK_CHECK; - ds = data.word(kTempgraphics); - di = (60)+128+4; - bx = (52)+12; - al = 1; - ah = 0; - showFrame(); - ds = data.word(kTempgraphics); - di = (60)+176+2; - bx = (52)+60-4; - al = 5; - ah = 0; - showFrame(); - di = (60)+104; - bx = (52)+14; - al = 54; - dl = 101; - printMessage(); -} - -void DreamGenContext::selectSlot() { - STACK_CHECK; - _cmp(data.byte(kCommandtype), 244); - if (flags.z()) - goto alreadysel; - data.byte(kCommandtype) = 244; - al = 45; - commandOnly(); -alreadysel: - ax = data.word(kMousebutton); - _cmp(ax, 1); - if (!flags.z()) - return /* (noselslot) */; - _cmp(ax, data.word(kOldbutton)); - if (flags.z()) - return /* (noselslot) */; - _cmp(data.byte(kLoadingorsave), 3); - if (!flags.z()) - goto notnocurs; - _dec(data.byte(kLoadingorsave)); -notnocurs: - oldToNames(); - ax = data.word(kMousey); - _sub(ax, (52)+4); - cl = -1; -getslotnum: - _inc(cl); - _sub(ax, 11); - if (!flags.c()) - goto getslotnum; - data.byte(kCurrentslot) = cl; - delPointer(); - showOpBox(); - showSlots(); - showNames(); - _cmp(data.byte(kLoadingorsave), 1); - if (flags.z()) - goto isloadmode; - showSaveOps(); - readMouse(); - showPointer(); - workToScreen(); - delPointer(); - return; -isloadmode: - showLoadOps(); - readMouse(); - showPointer(); - workToScreen(); - delPointer(); -} - -void DreamGenContext::showSlots() { - STACK_CHECK; - di = (60)+7; - bx = (52)+8; - al = 2; - ds = data.word(kTempgraphics); - ah = 0; - showFrame(); - di = (60)+10; - bx = (52)+11; - cl = 0; -slotloop: - push(cx); - push(di); - push(bx); - _cmp(cl, data.byte(kCurrentslot)); - if (!flags.z()) - goto nomatchslot; - al = 3; - ds = data.word(kTempgraphics); - ah = 0; - showFrame(); -nomatchslot: - bx = pop(); - di = pop(); - cx = pop(); - _add(bx, 10); - _inc(cl); - _cmp(cl, 7); - if (!flags.z()) - goto slotloop; -} - -void DreamGenContext::showNames() { - STACK_CHECK; - dx = data; - es = dx; - si = 1829+1; - di = (60)+21; - bx = (52)+10; - cl = 0; -shownameloop: - push(cx); - push(di); - push(es); - push(bx); - push(si); - al = 4; - _cmp(cl, data.byte(kCurrentslot)); - if (!flags.z()) - goto nomatchslot2; - _cmp(data.byte(kLoadingorsave), 2); - if (!flags.z()) - goto loadmode; - dx = si; - cx = 15; - _add(si, 15); -zerostill: - _dec(si); - _dec(cl); - _cmp(es.byte(si), 1); - if (!flags.z()) - goto foundcharacter; - goto zerostill; -foundcharacter: - data.byte(kCursorpos) = cl; - es.byte(si) = '/'; - es.byte(si+1) = 0; - push(si); - si = dx; - dl = 200; - ah = 0; - printDirect(); - si = pop(); - es.byte(si) = 0; - es.byte(si+1) = 1; - goto afterprintname; -loadmode: - al = 0; - dl = 200; - ah = 0; - data.word(kCharshift) = 91; - printDirect(); - data.word(kCharshift) = 0; - goto afterprintname; -nomatchslot2: - dl = 200; - ah = 0; - printDirect(); -afterprintname: - si = pop(); - bx = pop(); - es = pop(); - di = pop(); - cx = pop(); - _add(si, 17); - _add(bx, 10); - _inc(cl); - _cmp(cl, 7); - if (!flags.z()) - goto shownameloop; -} - -void DreamGenContext::decide() { - STACK_CHECK; - setMode(); - loadPalFromIFF(); - clearPalette(); - data.byte(kPointermode) = 0; - data.word(kWatchingtime) = 0; - data.byte(kPointerframe) = 0; - data.word(kTextaddressx) = 70; - data.word(kTextaddressy) = 182-8; - data.byte(kTextlen) = 181; - data.byte(kManisoffscreen) = 1; - loadSaveBox(); - showDecisions(); - workToScreen(); - fadeScreenUp(); - data.byte(kGetback) = 0; -waitdecide: - _cmp(data.byte(kQuitrequested), 0); - if (flags.z()) - goto _tmp1; - return; -_tmp1: - readMouse(); - showPointer(); - vSync(); - dumpPointer(); - dumpTextLine(); - delPointer(); - bx = offset_decidelist; - checkCoords(); - _cmp(data.byte(kGetback), 0); - if (flags.z()) - goto waitdecide; - _cmp(data.byte(kGetback), 4); - if (flags.z()) - goto hasloadedroom; - getRidOfTemp(); -hasloadedroom: - data.word(kTextaddressx) = 13; - data.word(kTextaddressy) = 182; - data.byte(kTextlen) = 240; -} - -void DreamGenContext::showDecisions() { - STACK_CHECK; - createPanel2(); - showOpBox(); - ds = data.word(kTempgraphics); - di = (60)+17; - bx = (52)+13; - al = 6; - ah = 0; - showFrame(); - underTextLine(); -} - -void DreamGenContext::createName() { - STACK_CHECK; - push(ax); - di = offset_speechfile; - cs.byte(di+0) = dl; - cs.byte(di+3) = cl; - al = dh; - ah = '0'-1; -findten: - _inc(ah); - _sub(al, 10); - if (!flags.c()) - goto findten; - cs.byte(di+1) = ah; - _add(al, 10+'0'); - cs.byte(di+2) = al; - ax = pop(); - cl = '0'-1; -thousandsc: - _inc(cl); - _sub(ax, 1000); - if (!flags.c()) - goto thousandsc; - _add(ax, 1000); - cs.byte(di+4) = cl; - cl = '0'-1; -hundredsc: - _inc(cl); - _sub(ax, 100); - if (!flags.c()) - goto hundredsc; - _add(ax, 100); - cs.byte(di+5) = cl; - cl = '0'-1; -tensc: - _inc(cl); - _sub(ax, 10); - if (!flags.c()) - goto tensc; - _add(ax, 10); - cs.byte(di+6) = cl; - _add(al, '0'); - cs.byte(di+7) = al; -} - -void DreamGenContext::entryTexts() { - STACK_CHECK; - _cmp(data.byte(kLocation), 21); - if (!flags.z()) - goto notloc15; - al = 28; - cx = 60; - dx = 11; - bl = 68; - bh = 64; - setupTimedUse(); - return; -notloc15: - _cmp(data.byte(kLocation), 30); - if (!flags.z()) - goto notloc43; - al = 27; - cx = 60; - dx = 11; - bl = 68; - bh = 64; - setupTimedUse(); - return; -notloc43: - _cmp(data.byte(kLocation), 23); - if (!flags.z()) - goto notloc23; - al = 29; - cx = 60; - dx = 11; - bl = 68; - bh = 64; - setupTimedUse(); - return; -notloc23: - _cmp(data.byte(kLocation), 31); - if (!flags.z()) - goto notloc44; - al = 30; - cx = 60; - dx = 11; - bl = 68; - bh = 64; - setupTimedUse(); - return; -notloc44: - _cmp(data.byte(kLocation), 20); - if (!flags.z()) - goto notsarters2; - al = 31; - cx = 60; - dx = 11; - bl = 68; - bh = 64; - setupTimedUse(); - return; -notsarters2: - _cmp(data.byte(kLocation), 24); - if (!flags.z()) - goto notedenlob; - al = 32; - cx = 60; - dx = 3; - bl = 68; - bh = 64; - setupTimedUse(); - return; -notedenlob: - _cmp(data.byte(kLocation), 34); - if (!flags.z()) - return /* (noteden2) */; - al = 33; - cx = 60; - dx = 3; - bl = 68; - bh = 64; - setupTimedUse(); -} - -void DreamGenContext::entryAnims() { - STACK_CHECK; - data.word(kReeltowatch) = -1; - data.byte(kWatchmode) = -1; - _cmp(data.byte(kLocation), 33); - if (!flags.z()) - goto notinthebeach; - switchRyanOff(); - data.word(kWatchingtime) = 76*2; - data.word(kReeltowatch) = 0; - data.word(kEndwatchreel) = 76; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - return; -notinthebeach: - _cmp(data.byte(kLocation), 44); - if (!flags.z()) - goto notsparkys; - al = 8; - resetLocation(); - data.word(kWatchingtime) = 50*2; - data.word(kReeltowatch) = 247; - data.word(kEndwatchreel) = 297; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - switchRyanOff(); - return; -notsparkys: - _cmp(data.byte(kLocation), 22); - if (!flags.z()) - goto notinthelift; - data.word(kWatchingtime) = 31*2; - data.word(kReeltowatch) = 0; - data.word(kEndwatchreel) = 30; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - switchRyanOff(); - return; -notinthelift: - _cmp(data.byte(kLocation), 26); - if (!flags.z()) - goto notunderchurch; - data.byte(kSymboltopnum) = 2; - data.byte(kSymbolbotnum) = 1; - return; -notunderchurch: - _cmp(data.byte(kLocation), 45); - if (!flags.z()) - goto notenterdream; - data.byte(kKeeperflag) = 0; - data.word(kWatchingtime) = 296; - data.word(kReeltowatch) = 45; - data.word(kEndwatchreel) = 198; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - switchRyanOff(); - return; -notenterdream: - _cmp(data.byte(kReallocation), 46); - if (!flags.z()) - goto notcrystal; - _cmp(data.byte(kSartaindead), 1); - if (!flags.z()) - goto notcrystal; - al = 0; - removeFreeObject(); - return; -notcrystal: - _cmp(data.byte(kLocation), 9); - if (!flags.z()) - goto nottopchurch; - al = 2; - checkIfPathIsOn(); - if (flags.z()) - goto nottopchurch; - _cmp(data.byte(kAidedead), 0); - if (flags.z()) - goto nottopchurch; - al = 3; - checkIfPathIsOn(); - if (!flags.z()) - goto makedoorsopen; - al = 2; - turnPathOn(); -makedoorsopen: - al = 4; - removeSetObject(); - al = 5; - placeSetObject(); - return; -nottopchurch: - _cmp(data.byte(kLocation), 47); - if (!flags.z()) - goto notdreamcentre; - al = 4; - placeSetObject(); - al = 5; - placeSetObject(); - return; -notdreamcentre: - _cmp(data.byte(kLocation), 38); - if (!flags.z()) - goto notcarpark; - data.word(kWatchingtime) = 57*2; - data.word(kReeltowatch) = 4; - data.word(kEndwatchreel) = 57; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - switchRyanOff(); - return; -notcarpark: - _cmp(data.byte(kLocation), 32); - if (!flags.z()) - goto notalley; - data.word(kWatchingtime) = 66*2; - data.word(kReeltowatch) = 0; - data.word(kEndwatchreel) = 66; - data.byte(kWatchspeed) = 1; - data.byte(kSpeedcount) = 1; - switchRyanOff(); - return; -notalley: - _cmp(data.byte(kLocation), 24); - if (!flags.z()) - return /* (notedensagain) */; - al = 2; - ah = data.byte(kRoomnum); - _dec(ah); - turnAnyPathOn(); -} - -void DreamGenContext::clearBuffers() { - STACK_CHECK; - es = data.word(kBuffers); - cx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+983-526+68-0)/2; - ax = 0; - di = 0; - _stosw(cx, true); - es = data.word(kExtras); - cx = (0+2080+30000+(16*114)+((114+2)*2)+18000)/2; - ax = 0x0ffff; - di = 0; - _stosw(cx, true); - es = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)); - ds = cs; - si = 526; - cx = (983-526); - _movsb(cx, true); - es = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+983-526); - ds = cs; - si = 0; - cx = (68-0); - _movsb(cx, true); - clearChanges(); -} - -void DreamGenContext::clearChanges() { - STACK_CHECK; - es = data.word(kBuffers); - cx = (250)*2; - ax = 0x0ffff; - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)); - _stosw(cx, true); - ds = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)); - es = cs; - di = 526; - cx = (983-526); - _movsb(cx, true); - ds = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+983-526); - es = cs; - di = 0; - cx = (68-0); - _movsb(cx, true); - data.byte(kExpos) = 0; - data.word(kExframepos) = 0; - data.word(kExtextpos) = 0; - es = data.word(kExtras); - cx = (0+2080+30000+(16*114)+((114+2)*2)+18000)/2; - ax = 0x0ffff; - di = 0; - _stosw(cx, true); - es = cs; - di = 1661; - al = 1; - _stosb(2); - al = 0; - _stosb(); - al = 1; - _stosb(); - ax = 0; - cx = 6; - _stosw(cx, true); -} - -void DreamGenContext::watchReel() { - STACK_CHECK; - _cmp(data.word(kReeltowatch), -1); - if (flags.z()) - goto notplayingreel; - al = data.byte(kManspath); - _cmp(al, data.byte(kFinaldest)); - if (!flags.z()) - return /* (waitstopwalk) */; - al = data.byte(kTurntoface); - _cmp(al, data.byte(kFacing)); - if (flags.z()) - goto notwatchpath; - return; -notwatchpath: - _dec(data.byte(kSpeedcount)); - _cmp(data.byte(kSpeedcount), -1); - if (!flags.z()) - goto showwatchreel; - al = data.byte(kWatchspeed); - data.byte(kSpeedcount) = al; - ax = data.word(kReeltowatch); - _cmp(ax, data.word(kEndwatchreel)); - if (!flags.z()) - goto ismorereel; - _cmp(data.word(kWatchingtime), 0); - if (!flags.z()) - goto showwatchreel; - data.word(kReeltowatch) = -1; - data.byte(kWatchmode) = -1; - _cmp(data.word(kReeltohold), -1); - if (flags.z()) - return /* (nomorereel) */; - data.byte(kWatchmode) = 1; - goto notplayingreel; -ismorereel: - _inc(data.word(kReeltowatch)); -showwatchreel: - ax = data.word(kReeltowatch); - data.word(kReelpointer) = ax; - plotReel(); - ax = data.word(kReelpointer); - data.word(kReeltowatch) = ax; - checkForShake(); - return; -notplayingreel: - _cmp(data.byte(kWatchmode), 1); - if (!flags.z()) - goto notholdingreel; - ax = data.word(kReeltohold); - data.word(kReelpointer) = ax; - plotReel(); - return; -notholdingreel: - _cmp(data.byte(kWatchmode), 2); - if (!flags.z()) - return /* (notreleasehold) */; - _dec(data.byte(kSpeedcount)); - _cmp(data.byte(kSpeedcount), -1); - if (!flags.z()) - goto notlastspeed2; - al = data.byte(kWatchspeed); - data.byte(kSpeedcount) = al; - _inc(data.word(kReeltohold)); -notlastspeed2: - ax = data.word(kReeltohold); - _cmp(ax, data.word(kEndofholdreel)); - if (!flags.z()) - goto ismorereel2; - data.word(kReeltohold) = -1; - data.byte(kWatchmode) = -1; - al = data.byte(kDestafterhold); - data.byte(kDestination) = al; - data.byte(kFinaldest) = al; - autoSetWalk(); - return; -ismorereel2: - ax = data.word(kReeltohold); - data.word(kReelpointer) = ax; - plotReel(); -} - -void DreamGenContext::checkForShake() { - STACK_CHECK; - _cmp(data.byte(kReallocation), 26); - if (!flags.z()) - return /* (notstartshake) */; - _cmp(ax, 104); - if (!flags.z()) - return /* (notstartshake) */; - data.byte(kShakecounter) = -1; -} - -void DreamGenContext::madmanRun() { - STACK_CHECK; - _cmp(data.byte(kLocation), 14); - if (!flags.z()) - { identifyOb(); return; }; - _cmp(data.byte(kMapx), 22); - if (!flags.z()) - { identifyOb(); return; }; - _cmp(data.byte(kPointermode), 2); - if (!flags.z()) - { identifyOb(); return; }; - _cmp(data.byte(kMadmanflag), 0); - if (!flags.z()) - { identifyOb(); return; }; - _cmp(data.byte(kCommandtype), 211); - if (flags.z()) - goto alreadyrun; - data.byte(kCommandtype) = 211; - al = 52; - commandOnly(); -alreadyrun: - _cmp(data.word(kMousebutton), 1); - if (!flags.z()) - return /* (norun) */; - ax = data.word(kMousebutton); - _cmp(ax, data.word(kOldbutton)); - if (flags.z()) - return /* (norun) */; - data.byte(kLastweapon) = 8; -} - -void DreamGenContext::identifyOb() { - STACK_CHECK; - _cmp(data.word(kWatchingtime), 0); - if (!flags.z()) - { blank(); return; }; - ax = data.word(kMousex); - _sub(ax, data.word(kMapadx)); - _cmp(ax, 22*8); - if (flags.c()) - goto notover1; - blank(); - return; -notover1: - bx = data.word(kMousey); - _sub(bx, data.word(kMapady)); - _cmp(bx, 20*8); - if (flags.c()) - goto notover2; - blank(); - return; -notover2: - data.byte(kInmaparea) = 1; - ah = bl; - push(ax); - findPathOfPoint(); - data.byte(kPointerspath) = dl; - ax = pop(); - push(ax); - findFirstPath(); - data.byte(kPointerfirstpath) = al; - ax = pop(); - checkIfEx(); - if (!flags.z()) - return /* (finishidentify) */; - checkIfFree(); - if (!flags.z()) - return /* (finishidentify) */; - checkIfPerson(); - if (!flags.z()) - return /* (finishidentify) */; - checkIfSet(); - if (!flags.z()) - return /* (finishidentify) */; - ax = data.word(kMousex); - _sub(ax, data.word(kMapadx)); - cl = al; - ax = data.word(kMousey); - _sub(ax, data.word(kMapady)); - ch = al; - checkOne(); - _cmp(al, 0); - if (flags.z()) - goto nothingund; - _cmp(data.byte(kMandead), 1); - if (flags.z()) - goto nothingund; - ah = 3; - obName(); - return; -nothingund: - blank(); -} - void DreamGenContext::findPathOfPoint() { STACK_CHECK; push(ax); @@ -7263,227 +2041,6 @@ gotfirst: al = es.byte(bx+6); } -void DreamGenContext::afterNewRoom() { - STACK_CHECK; - _cmp(data.byte(kNowinnewroom), 0); - if (flags.z()) - return /* (notnew) */; - data.word(kTimecount) = 0; - createPanel(); - data.byte(kCommandtype) = 0; - findRoomInLoc(); - _cmp(data.byte(kRyanon), 1); - if (flags.z()) - goto ryansoff; - al = data.byte(kRyanx); - _add(al, 12); - ah = data.byte(kRyany); - _add(ah, 12); - findPathOfPoint(); - data.byte(kManspath) = dl; - findXYFromPath(); - data.byte(kResetmanxy) = 1; -ryansoff: - data.byte(kNewobs) = 1; - drawFloor(); - data.word(kLookcounter) = 160; - data.byte(kNowinnewroom) = 0; - showIcon(); - spriteUpdate(); - printSprites(); - underTextLine(); - reelsOnScreen(); - mainScreen(); - getUnderZoom(); - zoom(); - workToScreenM(); - walkIntoRoom(); - reminders(); - atmospheres(); -} - -void DreamGenContext::printmessage2() { - STACK_CHECK; - push(dx); - push(bx); - push(di); - push(ax); - ah = 0; - _add(ax, ax); - bx = ax; - es = data.word(kCommandtext); - ax = es.word(bx); - _add(ax, (66*2)); - si = ax; - ax = pop(); -searchmess: - push(ax); - findNextColon(); - ax = pop(); - _dec(ah); - if (!flags.z()) - goto searchmess; - di = pop(); - bx = pop(); - dx = pop(); - al = 0; - ah = 0; - printDirect(); -} - -void DreamGenContext::workoutFrames() { - STACK_CHECK; - bx = data.word(kLinestartx); - _add(bx, 32); - ax = data.word(kLineendx); - _add(ax, 32); - _sub(bx, ax); - if (!flags.c()) - goto notneg1; - _neg(bx); -notneg1: - cx = data.word(kLinestarty); - _add(cx, 32); - ax = data.word(kLineendy); - _add(ax, 32); - _sub(cx, ax); - if (!flags.c()) - goto notneg2; - _neg(cx); -notneg2: - _cmp(bx, cx); - if (!flags.c()) - goto tendstohoriz; - dl = 2; - ax = cx; - _shr(ax, 1); - _cmp(bx, ax); - if (flags.c()) - goto gotquad; - dl = 1; - goto gotquad; -tendstohoriz: - dl = 0; - ax = bx; - _shr(ax, 1); - _cmp(cx, ax); - if (flags.c()) - goto gotquad; - dl = 1; - goto gotquad; -gotquad: - bx = data.word(kLinestartx); - _add(bx, 32); - ax = data.word(kLineendx); - _add(ax, 32); - _sub(bx, ax); - if (flags.c()) - goto isinright; - cx = data.word(kLinestarty); - _add(cx, 32); - ax = data.word(kLineendy); - _add(ax, 32); - _sub(cx, ax); - if (!flags.c()) - goto topleft; - _cmp(dl, 1); - if (flags.z()) - goto noswap1; - _xor(dl, 2); -noswap1: - _add(dl, 4); - goto success; -topleft: - _add(dl, 6); - goto success; -isinright: - cx = data.word(kLinestarty); - _add(cx, 32); - ax = data.word(kLineendy); - _add(ax, 32); - _sub(cx, ax); - if (!flags.c()) - goto botright; - _add(dl, 2); - goto success; -botright: - _cmp(dl, 1); - if (flags.z()) - goto noswap2; - _xor(dl, 2); -noswap2: -success: - _and(dl, 7); - data.byte(kTurntoface) = dl; - data.byte(kTurndirection) = 0; -} - -void DreamGenContext::middlePanel() { - STACK_CHECK; - ds = data.word(kTempsprites); - di = 72+47+20; - bx = 0; - al = 48; - ah = 0; - showFrame(); - ds = data.word(kTempsprites); - di = 72+19; - bx = 21; - al = 47; - ah = 0; - showFrame(); - ds = data.word(kTempsprites); - di = 160+23; - bx = 0; - al = 48; - ah = 4; - showFrame(); - ds = data.word(kTempsprites); - di = 160+71; - bx = 21; - al = 47; - ah = 4; - showFrame(); -} - -void DreamGenContext::getUnderZoom() { - STACK_CHECK; - di = (8)+5; - bx = (132)+4; - ds = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)); - cl = 46; - ch = 40; - multiGet(); -} - -void DreamGenContext::putUnderZoom() { - STACK_CHECK; - di = (8)+5; - bx = (132)+4; - ds = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)); - cl = 46; - ch = 40; - multiPut(); -} - -void DreamGenContext::underTextLine() { - STACK_CHECK; - di = data.word(kTextaddressx); - bx = data.word(kTextaddressy); - _cmp(data.byte(kForeignrelease), 0); - if (flags.z()) - goto _tmp1; - _sub(bx, 3); -_tmp1: - ds = data.word(kBuffers); - si = (0); - cl = (228); - ch = (13); - multiGet(); -} - void DreamGenContext::__start() { static const uint8 src[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -7508,14 +2065,14 @@ void DreamGenContext::__start() { //0x0090: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00a0: .... .... .... .... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00b0: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00c0: .... .... .... .... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, + //0x00d0: .... .... .... . . 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x00d0: .... .... .... .... - 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x00e0: .. .... .... .... + //0x00e0: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00f0: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -7530,205 +2087,53 @@ void DreamGenContext::__start() { //0x0140: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x0150: .... .... .... .... - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, //0x0160: .... .... .... .... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //0x0170: .... .... .... .... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //0x0180: .... .... .... .... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x0190: .... .... .... .... - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - //0x01a0: .... .... .... .... - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - //0x01b0: .... .... .... .... - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x17, 0x00, - //0x01c0: .... .... .... .... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x01d0: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x01e0: .... .... .... .... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x01f0: .... .... .... .... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2c, - //0x0200: .... .... .... ..., - 0x00, 0x14, 0x00, 0x02, 0x00, 0x01, 0x01, 0x37, 0x00, 0x00, 0x00, 0x32, 0x14, 0x00, 0x18, 0x16, - //0x0210: .... ...7 ...2 .... - 0x00, 0x4a, 0x00, 0x01, 0x00, 0x00, 0x18, 0x21, 0x0a, 0x4b, 0x00, 0x01, 0x00, 0x01, 0x01, 0x2c, - //0x0220: .J.. ...! .K.. ..., - 0x00, 0x1b, 0x00, 0x02, 0x00, 0x02, 0x01, 0x2c, 0x00, 0x60, 0x00, 0x03, 0x00, 0x04, 0x01, 0x2c, - //0x0230: .... ..., .`.. ..., - 0x00, 0x76, 0x00, 0x02, 0x00, 0x05, 0x01, 0x2c, 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x16, - //0x0240: .v.. ..., .... .... - 0x14, 0x35, 0x00, 0x03, 0x00, 0x00, 0x05, 0x16, 0x14, 0x28, 0x00, 0x01, 0x00, 0x02, 0x05, 0x16, - //0x0250: .5.. .... .(.. .... - 0x14, 0x32, 0x00, 0x01, 0x00, 0x03, 0x02, 0x0b, 0x0a, 0xc0, 0x00, 0x01, 0x00, 0x00, 0x02, 0x0b, - //0x0260: .2.. .... .... .... - 0x0a, 0xb6, 0x00, 0x02, 0x00, 0x01, 0x08, 0x0b, 0x0a, 0x00, 0x00, 0x02, 0x00, 0x01, 0x17, 0x00, - //0x0270: .... .... .... .... - 0x32, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1c, 0x0b, 0x14, 0xfa, 0x00, 0x04, 0x00, 0x00, 0x17, 0x00, - //0x0280: 2... .... .... .... - 0x32, 0x2b, 0x00, 0x02, 0x00, 0x08, 0x17, 0x0b, 0x28, 0x82, 0x00, 0x02, 0x00, 0x01, 0x17, 0x16, - //0x0290: 2+.. .... (... .... - 0x28, 0x7a, 0x00, 0x02, 0x00, 0x02, 0x17, 0x16, 0x28, 0x69, 0x00, 0x02, 0x00, 0x03, 0x17, 0x16, - //0x02a0: (z.. .... (i.. .... - 0x28, 0x51, 0x00, 0x02, 0x00, 0x04, 0x17, 0x0b, 0x28, 0x87, 0x00, 0x02, 0x00, 0x05, 0x17, 0x16, - //0x02b0: (Q.. .... (... .... - 0x28, 0x91, 0x00, 0x02, 0x00, 0x06, 0x04, 0x16, 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x2d, 0x16, - //0x02c0: (... .... .... ..-. - 0x1e, 0xc8, 0x00, 0x00, 0x00, 0x14, 0x2d, 0x16, 0x1e, 0x27, 0x00, 0x02, 0x00, 0x00, 0x2d, 0x16, - //0x02d0: .... ..-. .'.. ..-. - 0x1e, 0x19, 0x00, 0x02, 0x00, 0x00, 0x08, 0x16, 0x28, 0x20, 0x00, 0x02, 0x00, 0x00, 0x07, 0x0b, - //0x02e0: .... .... ( .. .... - 0x14, 0x40, 0x00, 0x02, 0x00, 0x00, 0x16, 0x16, 0x14, 0x52, 0x00, 0x02, 0x00, 0x00, 0x1b, 0x0b, - //0x02f0: .@.. .... .R.. .... - 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x00, 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0e, 0x21, - //0x0300: .... .... .... ...! - 0x28, 0x15, 0x00, 0x01, 0x00, 0x00, 0x1d, 0x0b, 0x0a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x16, - //0x0310: (... .... .... .... - 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00, 0x32, 0x04, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16, - //0x0320: .... .... 2... ..2. - 0x1e, 0x79, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16, 0x1e, 0x00, 0x00, 0x14, 0x00, 0x00, 0x34, 0x16, - //0x0330: .y.. ..2. .... ..4. - 0x1e, 0xc0, 0x00, 0x02, 0x00, 0x00, 0x34, 0x16, 0x1e, 0xe9, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16, - //0x0340: .... ..4. .... ..2. - 0x28, 0x68, 0x00, 0x37, 0x00, 0x00, 0x35, 0x21, 0x00, 0x63, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16, - //0x0350: (h.7 ..5! .c.. ..2. - 0x28, 0x00, 0x00, 0x03, 0x00, 0x00, 0x32, 0x16, 0x1e, 0xa2, 0x00, 0x02, 0x00, 0x00, 0x34, 0x16, - //0x0360: (... ..2. .... ..4. - 0x1e, 0x39, 0x00, 0x02, 0x00, 0x00, 0x34, 0x16, 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x36, 0x00, - //0x0370: .9.. ..4. .... ..6. - 0x00, 0x48, 0x00, 0x03, 0x00, 0x00, 0x37, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x00, - //0x0380: .H.. ..7, .... .... - 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x0e, 0x16, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x0e, 0x16, - //0x0390: .... .... .... .... - 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x0a, 0x16, 0x1e, 0xae, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x16, - //0x03a0: .,.. .... .... .... - 0x14, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0b, 0x14, 0x00, 0x00, 0x32, 0x14, 0x00, 0x0b, 0x0b, - //0x03b0: .... .... ...2 .... - 0x1e, 0x00, 0x00, 0x32, 0x14, 0x00, 0x0b, 0x16, 0x14, 0x00, 0x00, 0x32, 0x14, 0x00, 0x0e, 0x21, - //0x03c0: ...2 .... ...2 ...! - 0x28, 0x00, 0x00, 0x32, 0x14, 0x00, 0xff, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, - //0x03d0: (..2 ...D REAM WEB. - 0x43, 0x30, 0x32, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x56, 0x39, 0x39, - //0x03e0: C02. DREA MWEB .V99 - 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x31, 0x34, 0x00, 0x44, 0x52, - //0x03f0: .DRE AMWE B.G1 4.DR - 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x35, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, - //0x0400: EAMW EB.T 51.D REAM - 0x57, 0x45, 0x42, 0x2e, 0x54, 0x38, 0x33, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, - //0x0410: WEB. T83. DREA MWEB - 0x2e, 0x56, 0x4f, 0x4c, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x31, - //0x0420: .VOL .DRE AMWE B.G1 - 0x33, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x31, 0x35, 0x00, 0x44, - //0x0430: 3.DR EAMW EB.G 15.D - 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x49, 0x30, 0x37, 0x00, 0x00, 0x01, 0x11, 0x01, - //0x0440: REAM WEB. I07. .... - 0x40, 0x01, 0x9d, 0x00, 0xc6, 0x00, 0x7c, 0xc4, 0xf0, 0x00, 0x22, 0x01, 0x02, 0x00, 0x2c, 0x00, - //0x0450: @... ..|. ..". ..,. - 0x94, 0xc4, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x11, 0x01, - //0x0460: .... @... .... .... - 0x40, 0x01, 0x9d, 0x00, 0xc6, 0x00, 0x7c, 0xc4, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, - //0x0470: @... ..|. ..@. .... - 0xa0, 0xca, 0xff, 0xff, 0x45, 0x58, 0x49, 0x54, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x48, 0x45, - //0x0480: .... EXIT HE - 0x4c, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x49, 0x53, 0x54, 0x20, 0x20, 0x20, 0x20, - //0x0490: LP LIST - 0x20, 0x20, 0x52, 0x45, 0x41, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x4f, 0x47, 0x4f, - //0x04a0: RE AD LOGO - 0x4e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4b, 0x45, 0x59, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - //0x04b0: N KE YS - 0x01, 0x00, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x55, - //0x04c0: ..PU BLIC PU - 0x42, 0x4c, 0x49, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x42, 0x4c, 0x41, 0x43, - //0x04d0: BLIC ... BLAC - 0x4b, 0x44, 0x52, 0x41, 0x47, 0x4f, 0x4e, 0x20, 0x52, 0x59, 0x41, 0x4e, 0x20, 0x20, 0x20, 0x20, - //0x04e0: KDRA GON RYAN - 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x48, 0x45, 0x4e, 0x44, 0x52, 0x49, 0x58, 0x20, 0x20, 0x20, - //0x04f0: . ..HE NDRI X - 0x20, 0x20, 0x4c, 0x4f, 0x55, 0x49, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, - //0x0500: LO UIS ... - 0x53, 0x45, 0x50, 0x54, 0x49, 0x4d, 0x55, 0x53, 0x20, 0x20, 0x20, 0x20, 0x42, 0x45, 0x43, 0x4b, - //0x0510: SEPT IMUS BECK - 0x45, 0x54, 0x54, 0x20, 0x20, 0x20, 0x20, 0x00, 0xff, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - //0x0520: ETT . .. - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x22, 0x52, 0x4f, 0x4f, 0x54, 0x20, 0x20, 0x20, - //0x0530: . "ROO T - 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - //0x0540: ." - 0x20, 0x20, 0x20, 0x00, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0xba, 0x00, 0xca, 0x00, - //0x0550: . 0000 .00. .... - 0x9d, 0x00, 0xad, 0x00, 0x1c, 0xc8, 0xf3, 0x00, 0x03, 0x01, 0x83, 0x00, 0x93, 0x00, 0x18, 0xc8, - //0x0560: .... .... .... .... - 0x0c, 0x01, 0x1c, 0x01, 0xa8, 0x00, 0xb8, 0x00, 0x50, 0xc7, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, - //0x0570: .... .... P... @... - 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x77, 0x00, 0xae, 0x00, 0x52, 0x00, 0x80, 0x00, 0x34, 0xc8, - //0x0580: .... ..w. ..R. ..4. - 0x46, 0x00, 0x89, 0x00, 0x3e, 0x00, 0x6f, 0x00, 0x80, 0xc8, 0xbc, 0x00, 0xfa, 0x00, 0x44, 0x00, - //0x0590: F... >.o. .... ..D. - 0x98, 0x00, 0x4c, 0xc8, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, - //0x05a0: ..L. ..@. .... .... - 0x77, 0x00, 0xae, 0x00, 0x52, 0x00, 0x80, 0x00, 0x44, 0xc8, 0x46, 0x00, 0x8b, 0x00, 0x3e, 0x00, - //0x05b0: w... R... D.F. ..>. - 0x6f, 0x00, 0x50, 0xc8, 0xec, 0x00, 0xfc, 0x00, 0x70, 0x00, 0x80, 0x00, 0x48, 0xc8, 0x00, 0x00, - //0x05c0: o.P. .... p... H... - 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x0d, 0x0a, 0x0d, 0x0a, 0x24, 0x81, - //0x05d0: @... .... .... ..$. - 0x00, 0xb8, 0x00, 0x52, 0x00, 0x80, 0x00, 0xc0, 0xc8, 0x50, 0x00, 0x93, 0x00, 0x3e, 0x00, 0x6f, - //0x05e0: ...R .... .P.. .>.o - 0x00, 0x80, 0xc8, 0xb7, 0x00, 0xfa, 0x00, 0x3e, 0x00, 0x6f, 0x00, 0xc4, 0xc8, 0x00, 0x00, 0x40, - //0x05f0: .... ...> .o.. ...@ - 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x53, 0x50, 0x45, 0x45, 0x43, 0x48, 0x52, - //0x0600: .... .... .SPE ECHR - 0x32, 0x34, 0x43, 0x30, 0x30, 0x30, 0x35, 0x2e, 0x52, 0x41, 0x57, 0x00, 0x4f, 0x42, 0x4a, 0x45, - //0x0610: 24C0 005. RAW. OBJE - 0x43, 0x54, 0x20, 0x4e, 0x41, 0x4d, 0x45, 0x20, 0x4f, 0x4e, 0x45, 0x20, 0x20, 0x20, 0x20, 0x20, - //0x0620: CT N AME ONE - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - //0x0630: - 0x20, 0x20, 0x20, 0x20, 0x00, 0x10, 0x12, 0x12, 0x11, 0x10, 0x10, 0x10, 0x01, 0x01, 0x01, 0x01, - //0x0640: .... .... .... - 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x44, 0x3a, 0x00, - //0x0650: .... .... .... .D:. + //0x01a0: .... .... .... .... + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, + //0x01b0: .... ...D REAM WEB. + 0x56, 0x39, 0x39, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + //0x01c0: V99. + 0x20, 0x00, 0x22, 0x52, 0x4f, 0x4f, 0x54, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + //0x01d0: ."R OOT . + 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, + //0x01e0: " ... + 0x0d, 0x0a, 0x24, 0x10, 0x12, 0x12, 0x11, 0x10, 0x10, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + //0x01f0: ..$. .... .... .... + 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x44, 0x3a, 0x00, 0x00, 0x00, + //0x0200: .... .... ...D :... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x0660: .... .... .... .... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, - //0x0670: .... .... .... .... - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, - //0x0680: .... .... .... .... - 0x02, 0x04, 0x01, 0x0a, 0x09, 0x08, 0x06, 0x0b, 0x04, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x0690: .... .... .... .... + //0x0210: .... .... .... .... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, + //0x0220: .... .... .... .... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x02, 0x04, + //0x0230: .... .... .... .... + 0x01, 0x0a, 0x09, 0x08, 0x06, 0x0b, 0x04, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + //0x0240: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x06a0: .... .... .... .... + //0x0250: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x06b0: .... .... .... .... + //0x0260: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x06c0: .... .... .... .... + //0x0270: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x06d0: .... .... .... .... + //0x0280: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x06e0: .... .... .... .... + //0x0290: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x06f0: .... .... .... .... + //0x02a0: .... .... .... .... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x0700: .... .... .... .... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - //0x0710: .... .... .... .... - 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - //0x0720: .... .... .... .... - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - //0x0730: .... .... .... .... - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - //0x0740: .... .... .... .... - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - //0x0750: .... .... .... .... - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, - //0x0760: .... .... .... .... - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, - //0x0770: .... .... .... .... - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, - //0x0780: .... .... .... .... - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, }; + //0x02b0: .... .... .... .... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + //0x02c0: .... .... .... .... + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, }; ds.assign(src, src + sizeof(src)); dreamweb(); } diff --git a/engines/dreamweb/dreamgen.h b/engines/dreamweb/dreamgen.h index fe922cd959..b13d150ad4 100644 --- a/engines/dreamweb/dreamgen.h +++ b/engines/dreamweb/dreamgen.h @@ -32,21 +32,8 @@ namespace DreamGen { -static const uint16 offset_speechfile = 0x060f; -static const uint16 offset_operand1 = 0x052a; -static const uint16 offset_comlist = 0x0484; -static const uint16 offset_money2poke = 0x0559; -static const uint16 offset_discopslist = 0x05b0; -static const uint16 offset_openchangesize = 0x044c; -static const uint16 offset_keys = 0x04c0; -static const uint16 offset_diarylist = 0x055c; -static const uint16 offset_quitlist = 0x046e; -static const uint16 offset_rootdir = 0x0538; -static const uint16 offset_decidelist = 0x05df; -static const uint16 offset_money1poke = 0x0554; -static const uint16 offset_commandline = 0x061c; -static const uint16 offset_opslist = 0x0586; -static const uint16 offset_talklist = 0x044e; +static const uint16 offset_operand1 = 0x01c4; +static const uint16 offset_rootdir = 0x01d2; static const uint16 kStartvars = 0; static const uint16 kProgresspoints = 1; static const uint16 kWatchon = 2; @@ -169,277 +156,214 @@ static const uint16 kNewscreen = 149; static const uint16 kRyanx = 150; static const uint16 kRyany = 151; static const uint16 kLastflag = 152; -static const uint16 kLastflagex = 153; -static const uint16 kFlagx = 154; -static const uint16 kFlagy = 155; -static const uint16 kCurrentex = 156; -static const uint16 kCurrentfree = 157; -static const uint16 kCurrentframe = 158; -static const uint16 kFramesad = 160; -static const uint16 kDataad = 162; -static const uint16 kFrsegment = 164; -static const uint16 kObjectx = 166; -static const uint16 kObjecty = 168; -static const uint16 kOffsetx = 170; -static const uint16 kOffsety = 172; -static const uint16 kSavesize = 174; -static const uint16 kSavesource = 176; -static const uint16 kSavex = 178; -static const uint16 kSavey = 179; -static const uint16 kCurrentob = 180; -static const uint16 kPrioritydep = 181; -static const uint16 kDestpos = 182; -static const uint16 kReallocation = 183; -static const uint16 kRoomnum = 184; -static const uint16 kNowinnewroom = 185; -static const uint16 kResetmanxy = 186; -static const uint16 kNewlocation = 187; -static const uint16 kAutolocation = 188; -static const uint16 kMustload = 189; -static const uint16 kAnswered = 190; -static const uint16 kSaidno = 191; -static const uint16 kDoorcheck1 = 192; -static const uint16 kDoorcheck2 = 193; -static const uint16 kDoorcheck3 = 194; -static const uint16 kDoorcheck4 = 195; -static const uint16 kMousex = 196; -static const uint16 kMousey = 198; -static const uint16 kMousebutton = 200; -static const uint16 kMousebutton1 = 202; -static const uint16 kMousebutton2 = 204; -static const uint16 kMousebutton3 = 206; -static const uint16 kMousebutton4 = 208; -static const uint16 kOldbutton = 210; -static const uint16 kOldx = 212; -static const uint16 kOldy = 214; -static const uint16 kLastbutton = 216; -static const uint16 kOldpointerx = 218; -static const uint16 kOldpointery = 220; -static const uint16 kDelherex = 222; -static const uint16 kDelherey = 224; -static const uint16 kPointerxs = 226; -static const uint16 kPointerys = 227; -static const uint16 kDelxs = 228; -static const uint16 kDelys = 229; -static const uint16 kPointerframe = 230; -static const uint16 kPointerpower = 231; -static const uint16 kAuxpointerframe = 232; -static const uint16 kPointermode = 233; -static const uint16 kPointerspeed = 234; -static const uint16 kPointercount = 235; -static const uint16 kInmaparea = 236; -static const uint16 kReelpointer = 237; -static const uint16 kSlotdata = 239; -static const uint16 kThisslot = 240; -static const uint16 kSlotflags = 241; -static const uint16 kTakeoff = 242; -static const uint16 kTalkmode = 244; -static const uint16 kTalkpos = 245; -static const uint16 kCharacter = 246; -static const uint16 kPersondata = 247; -static const uint16 kTalknum = 249; -static const uint16 kNumberinroom = 250; -static const uint16 kCurrentcel = 251; -static const uint16 kOldselection = 252; -static const uint16 kStopwalking = 253; -static const uint16 kMouseon = 254; -static const uint16 kPlayed = 255; -static const uint16 kTimer1 = 257; -static const uint16 kTimer2 = 258; -static const uint16 kTimer3 = 259; -static const uint16 kWholetimer = 260; -static const uint16 kTimer1to = 262; -static const uint16 kTimer2to = 263; -static const uint16 kTimer3to = 264; -static const uint16 kWatchdump = 265; -static const uint16 kLogonum = 266; -static const uint16 kOldlogonum = 267; -static const uint16 kNewlogonum = 268; -static const uint16 kNetseg = 269; -static const uint16 kNetpoint = 271; -static const uint16 kKeynum = 273; -static const uint16 kCursorstate = 274; -static const uint16 kPressed = 275; -static const uint16 kPresspointer = 276; -static const uint16 kGraphicpress = 278; -static const uint16 kPresscount = 279; -static const uint16 kKeypadax = 280; -static const uint16 kKeypadcx = 282; -static const uint16 kLightcount = 284; -static const uint16 kFolderpage = 285; -static const uint16 kDiarypage = 286; -static const uint16 kMenucount = 287; -static const uint16 kSymboltopx = 288; -static const uint16 kSymboltopnum = 289; -static const uint16 kSymboltopdir = 290; -static const uint16 kSymbolbotx = 291; -static const uint16 kSymbolbotnum = 292; -static const uint16 kSymbolbotdir = 293; -static const uint16 kSymboltolight = 294; -static const uint16 kSymbol1 = 295; -static const uint16 kSymbol2 = 296; -static const uint16 kSymbol3 = 297; -static const uint16 kSymbolnum = 298; -static const uint16 kDumpx = 299; -static const uint16 kDumpy = 301; -static const uint16 kWalkandexam = 303; -static const uint16 kWalkexamtype = 304; -static const uint16 kWalkexamnum = 305; -static const uint16 kCursloc = 306; -static const uint16 kCurslocx = 308; -static const uint16 kCurslocy = 310; -static const uint16 kCurpos = 312; -static const uint16 kMonadx = 314; -static const uint16 kMonady = 316; -static const uint16 kGotfrom = 318; -static const uint16 kMonsource = 320; -static const uint16 kNumtodo = 322; -static const uint16 kTimecount = 324; -static const uint16 kCounttotimed = 326; -static const uint16 kTimedseg = 328; -static const uint16 kTimedoffset = 330; -static const uint16 kTimedy = 332; -static const uint16 kTimedx = 333; -static const uint16 kNeedtodumptimed = 334; -static const uint16 kHandle = 335; -static const uint16 kLoadingorsave = 337; -static const uint16 kCurrentslot = 338; -static const uint16 kCursorpos = 339; -static const uint16 kColourpos = 340; -static const uint16 kFadedirection = 341; -static const uint16 kNumtofade = 342; -static const uint16 kFadecount = 343; -static const uint16 kAddtogreen = 344; -static const uint16 kAddtored = 345; -static const uint16 kAddtoblue = 346; -static const uint16 kLastsoundreel = 347; -static const uint16 kSoundbuffer = 349; -static const uint16 kSoundbufferad = 351; -static const uint16 kSoundbufferpage = 353; -static const uint16 kSoundtimes = 354; -static const uint16 kNeedsoundbuff = 355; -static const uint16 kOldint9seg = 356; -static const uint16 kOldint9add = 358; -static const uint16 kOldint8seg = 360; -static const uint16 kOldint8add = 362; -static const uint16 kOldsoundintseg = 364; -static const uint16 kOldsoundintadd = 366; -static const uint16 kSoundbaseadd = 368; -static const uint16 kDsp_status = 370; -static const uint16 kDsp_write = 372; -static const uint16 kDmaaddress = 374; -static const uint16 kSoundint = 375; -static const uint16 kSounddmachannel = 376; -static const uint16 kSampleplaying = 377; -static const uint16 kTestresult = 378; -static const uint16 kCurrentirq = 379; -static const uint16 kSpeechloaded = 380; -static const uint16 kSpeechlength = 381; -static const uint16 kVolume = 383; -static const uint16 kVolumeto = 384; -static const uint16 kVolumedirection = 385; -static const uint16 kVolumecount = 386; -static const uint16 kPlayblock = 387; -static const uint16 kWongame = 388; -static const uint16 kLasthardkey = 389; -static const uint16 kBufferin = 390; -static const uint16 kBufferout = 392; -static const uint16 kExtras = 394; -static const uint16 kWorkspace = 396; -static const uint16 kMapstore = 398; -static const uint16 kCharset1 = 400; -static const uint16 kBuffers = 402; -static const uint16 kMainsprites = 404; -static const uint16 kBackdrop = 406; -static const uint16 kMapdata = 408; -static const uint16 kSounddata = 410; -static const uint16 kSounddata2 = 412; -static const uint16 kRecordspace = 414; -static const uint16 kFreedat = 416; -static const uint16 kSetdat = 418; -static const uint16 kReel1 = 420; -static const uint16 kReel2 = 422; -static const uint16 kReel3 = 424; -static const uint16 kRoomdesc = 426; -static const uint16 kFreedesc = 428; -static const uint16 kSetdesc = 430; -static const uint16 kBlockdesc = 432; -static const uint16 kSetframes = 434; -static const uint16 kFreeframes = 436; -static const uint16 kPeople = 438; -static const uint16 kReels = 440; -static const uint16 kCommandtext = 442; -static const uint16 kPuzzletext = 444; -static const uint16 kTraveltext = 446; -static const uint16 kTempgraphics = 448; -static const uint16 kTempgraphics2 = 450; -static const uint16 kTempgraphics3 = 452; -static const uint16 kTempsprites = 454; -static const uint16 kTextfile1 = 456; -static const uint16 kTextfile2 = 458; -static const uint16 kTextfile3 = 460; -static const uint16 kBlinkframe = 462; -static const uint16 kBlinkcount = 463; -static const uint16 kReasseschanges = 464; -static const uint16 kPointerspath = 465; -static const uint16 kManspath = 466; -static const uint16 kPointerfirstpath = 467; -static const uint16 kFinaldest = 468; -static const uint16 kDestination = 469; -static const uint16 kLinestartx = 470; -static const uint16 kLinestarty = 472; -static const uint16 kLineendx = 474; -static const uint16 kLineendy = 476; -static const uint16 kIncrement1 = 478; -static const uint16 kIncrement2 = 480; -static const uint16 kLineroutine = 482; -static const uint16 kLinepointer = 483; -static const uint16 kLinedirection = 484; -static const uint16 kLinelength = 485; -static const uint16 kLiftsoundcount = 486; -static const uint16 kEmmhandle = 487; -static const uint16 kEmmpageframe = 489; -static const uint16 kEmmhardwarepage = 491; -static const uint16 kCh0emmpage = 492; -static const uint16 kCh0offset = 494; -static const uint16 kCh0blockstocopy = 496; -static const uint16 kCh0playing = 498; -static const uint16 kCh0repeat = 499; -static const uint16 kCh0oldemmpage = 500; -static const uint16 kCh0oldoffset = 502; -static const uint16 kCh0oldblockstocopy = 504; -static const uint16 kCh1playing = 506; -static const uint16 kCh1emmpage = 507; -static const uint16 kCh1offset = 509; -static const uint16 kCh1blockstocopy = 511; -static const uint16 kCh1blocksplayed = 513; -static const uint16 kSoundbufferwrite = 515; -static const uint16 kSoundemmpage = 517; -static const uint16 kSpeechemmpage = 519; -static const uint16 kCurrentsample = 521; -static const uint16 kRoomssample = 522; -static const uint16 kGameerror = 523; -static const uint16 kHowmuchalloc = 524; -static const uint16 kReelroutines = 526; -static const uint16 kCharacterset3 = 983; -static const uint16 kBasicsample = 996; -static const uint16 kDiarygraphic = 1009; -static const uint16 kDiarytext = 1022; -static const uint16 kEndtextname = 1035; -static const uint16 kVolumetabname = 1048; -static const uint16 kGungraphic = 1061; -static const uint16 kMonkface = 1074; -static const uint16 kTitle7graphics = 1087; -static const uint16 kCurrentfile = 1350; -static const uint16 kRoomscango = 1661; -static const uint16 kRoompics = 1677; -static const uint16 kOplist = 1692; -static const uint16 kInputline = 1695; -static const uint16 kPresslist = 1823; -static const uint16 kSavenames = 1829; -static const uint16 kQuitrequested = 1948; -static const uint16 kSubtitles = 1949; -static const uint16 kForeignrelease = 1950; +static const uint16 kCurrentex = 153; +static const uint16 kCurrentfree = 154; +static const uint16 kFramesad = 155; +static const uint16 kDataad = 157; +static const uint16 kFrsegment = 159; +static const uint16 kObjectx = 161; +static const uint16 kObjecty = 163; +static const uint16 kOffsetx = 165; +static const uint16 kOffsety = 167; +static const uint16 kSavesize = 169; +static const uint16 kSavesource = 171; +static const uint16 kSavex = 173; +static const uint16 kSavey = 174; +static const uint16 kCurrentob = 175; +static const uint16 kPrioritydep = 176; +static const uint16 kDestpos = 177; +static const uint16 kReallocation = 178; +static const uint16 kRoomnum = 179; +static const uint16 kNowinnewroom = 180; +static const uint16 kResetmanxy = 181; +static const uint16 kNewlocation = 182; +static const uint16 kAutolocation = 183; +static const uint16 kMustload = 184; +static const uint16 kAnswered = 185; +static const uint16 kSaidno = 186; +static const uint16 kDoorcheck1 = 187; +static const uint16 kDoorcheck2 = 188; +static const uint16 kDoorcheck3 = 189; +static const uint16 kDoorcheck4 = 190; +static const uint16 kMousex = 191; +static const uint16 kMousey = 193; +static const uint16 kMousebutton = 195; +static const uint16 kMousebutton1 = 197; +static const uint16 kMousebutton2 = 199; +static const uint16 kMousebutton3 = 201; +static const uint16 kMousebutton4 = 203; +static const uint16 kOldbutton = 205; +static const uint16 kOldx = 207; +static const uint16 kOldy = 209; +static const uint16 kLastbutton = 211; +static const uint16 kOldpointerx = 213; +static const uint16 kOldpointery = 215; +static const uint16 kDelherex = 217; +static const uint16 kDelherey = 219; +static const uint16 kPointerxs = 221; +static const uint16 kPointerys = 222; +static const uint16 kDelxs = 223; +static const uint16 kDelys = 224; +static const uint16 kPointerframe = 225; +static const uint16 kPointerpower = 226; +static const uint16 kAuxpointerframe = 227; +static const uint16 kPointermode = 228; +static const uint16 kPointerspeed = 229; +static const uint16 kPointercount = 230; +static const uint16 kInmaparea = 231; +static const uint16 kSlotdata = 232; +static const uint16 kThisslot = 233; +static const uint16 kSlotflags = 234; +static const uint16 kTalkmode = 235; +static const uint16 kTalkpos = 236; +static const uint16 kCharacter = 237; +static const uint16 kPersondata = 238; +static const uint16 kTalknum = 240; +static const uint16 kNumberinroom = 241; +static const uint16 kCurrentcel = 242; +static const uint16 kOldselection = 243; +static const uint16 kStopwalking = 244; +static const uint16 kMouseon = 245; +static const uint16 kPlayed = 246; +static const uint16 kTimer1 = 248; +static const uint16 kTimer2 = 249; +static const uint16 kTimer3 = 250; +static const uint16 kWholetimer = 251; +static const uint16 kTimer1to = 253; +static const uint16 kTimer2to = 254; +static const uint16 kTimer3to = 255; +static const uint16 kWatchdump = 256; +static const uint16 kLogonum = 257; +static const uint16 kOldlogonum = 258; +static const uint16 kNetseg = 259; +static const uint16 kNetpoint = 261; +static const uint16 kCursorstate = 263; +static const uint16 kPressed = 264; +static const uint16 kPresspointer = 265; +static const uint16 kGraphicpress = 267; +static const uint16 kPresscount = 268; +static const uint16 kLightcount = 269; +static const uint16 kFolderpage = 270; +static const uint16 kDiarypage = 271; +static const uint16 kMenucount = 272; +static const uint16 kSymboltopx = 273; +static const uint16 kSymboltopnum = 274; +static const uint16 kSymboltopdir = 275; +static const uint16 kSymbolbotx = 276; +static const uint16 kSymbolbotnum = 277; +static const uint16 kSymbolbotdir = 278; +static const uint16 kSymboltolight = 279; +static const uint16 kSymbol1 = 280; +static const uint16 kSymbol2 = 281; +static const uint16 kSymbol3 = 282; +static const uint16 kSymbolnum = 283; +static const uint16 kDumpx = 284; +static const uint16 kDumpy = 286; +static const uint16 kWalkandexam = 288; +static const uint16 kWalkexamtype = 289; +static const uint16 kWalkexamnum = 290; +static const uint16 kCurslocx = 291; +static const uint16 kCurslocy = 293; +static const uint16 kCurpos = 295; +static const uint16 kMonadx = 297; +static const uint16 kMonady = 299; +static const uint16 kMonsource = 301; +static const uint16 kNumtodo = 303; +static const uint16 kTimecount = 305; +static const uint16 kCounttotimed = 307; +static const uint16 kTimedseg = 309; +static const uint16 kTimedoffset = 311; +static const uint16 kTimedy = 313; +static const uint16 kTimedx = 314; +static const uint16 kNeedtodumptimed = 315; +static const uint16 kLoadingorsave = 316; +static const uint16 kCurrentslot = 317; +static const uint16 kCursorpos = 318; +static const uint16 kColourpos = 319; +static const uint16 kFadedirection = 320; +static const uint16 kNumtofade = 321; +static const uint16 kFadecount = 322; +static const uint16 kAddtogreen = 323; +static const uint16 kAddtored = 324; +static const uint16 kAddtoblue = 325; +static const uint16 kLastsoundreel = 326; +static const uint16 kSpeechloaded = 328; +static const uint16 kSpeechlength = 329; +static const uint16 kVolume = 331; +static const uint16 kVolumeto = 332; +static const uint16 kVolumedirection = 333; +static const uint16 kVolumecount = 334; +static const uint16 kWongame = 335; +static const uint16 kLasthardkey = 336; +static const uint16 kBufferin = 337; +static const uint16 kBufferout = 339; +static const uint16 kExtras = 341; +static const uint16 kWorkspace = 343; +static const uint16 kMapstore = 345; +static const uint16 kCharset1 = 347; +static const uint16 kBuffers = 349; +static const uint16 kMainsprites = 351; +static const uint16 kBackdrop = 353; +static const uint16 kMapdata = 355; +static const uint16 kSounddata = 357; +static const uint16 kSounddata2 = 359; +static const uint16 kRecordspace = 361; +static const uint16 kFreedat = 363; +static const uint16 kSetdat = 365; +static const uint16 kReel1 = 367; +static const uint16 kReel2 = 369; +static const uint16 kReel3 = 371; +static const uint16 kRoomdesc = 373; +static const uint16 kFreedesc = 375; +static const uint16 kSetdesc = 377; +static const uint16 kBlockdesc = 379; +static const uint16 kSetframes = 381; +static const uint16 kFreeframes = 383; +static const uint16 kPeople = 385; +static const uint16 kReels = 387; +static const uint16 kCommandtext = 389; +static const uint16 kPuzzletext = 391; +static const uint16 kTraveltext = 393; +static const uint16 kTempgraphics = 395; +static const uint16 kTempgraphics2 = 397; +static const uint16 kTempgraphics3 = 399; +static const uint16 kTempsprites = 401; +static const uint16 kTextfile1 = 403; +static const uint16 kTextfile2 = 405; +static const uint16 kTextfile3 = 407; +static const uint16 kBlinkframe = 409; +static const uint16 kBlinkcount = 410; +static const uint16 kReasseschanges = 411; +static const uint16 kPointerspath = 412; +static const uint16 kManspath = 413; +static const uint16 kPointerfirstpath = 414; +static const uint16 kFinaldest = 415; +static const uint16 kDestination = 416; +static const uint16 kLinestartx = 417; +static const uint16 kLinestarty = 419; +static const uint16 kLineendx = 421; +static const uint16 kLineendy = 423; +static const uint16 kLinepointer = 425; +static const uint16 kLinedirection = 426; +static const uint16 kLinelength = 427; +static const uint16 kCh0blockstocopy = 428; +static const uint16 kCh0playing = 430; +static const uint16 kCh0repeat = 431; +static const uint16 kCh1playing = 432; +static const uint16 kCh1blockstocopy = 433; +static const uint16 kSoundbufferwrite = 435; +static const uint16 kCurrentsample = 437; +static const uint16 kRoomssample = 438; +static const uint16 kBasicsample = 439; +static const uint16 kCurrentfile = 480; +static const uint16 kRoomscango = 555; +static const uint16 kRoompics = 571; +static const uint16 kOplist = 586; +static const uint16 kInputline = 589; +static const uint16 kPresslist = 717; +static const uint16 kQuitrequested = 723; +static const uint16 kSubtitles = 724; +static const uint16 kForeignrelease = 725; static const uint16 kBlocktextdat = (0); static const uint16 kPersonframes = (0); static const uint16 kDebuglevel1 = (0); @@ -448,13 +372,13 @@ static const uint16 kPlayback = (0); static const uint16 kMap = (0); static const uint16 kSettextdat = (0); static const uint16 kSpanish = (0); -static const uint16 kFramedata = (0); static const uint16 kRecording = (0); static const uint16 kFlags = (0); static const uint16 kGerman = (0); static const uint16 kTextunder = (0); static const uint16 kPathdata = (0); static const uint16 kDemo = (0); +static const uint16 kFramedata = (0); static const uint16 kExframedata = (0); static const uint16 kIntextdat = (0); static const uint16 kFreetextdat = (0); @@ -478,8 +402,8 @@ static const uint16 kListofchanges = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768 static const uint16 kUndertimedtext = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)); static const uint16 kRainlist = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)); static const uint16 kInitialreelrouts = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)); -static const uint16 kInitialvars = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+983-526); -static const uint16 kLengthofbuffer = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+983-526+68-0); +static const uint16 kInitialvars = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+457); +static const uint16 kLengthofbuffer = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)+(6*64)+457+68-0); static const uint16 kReellist = (0+(36*144)); static const uint16 kIntext = (0+(38*2)); static const uint16 kLengthofmap = (0+(66*60)); @@ -512,6 +436,7 @@ static const uint16 kTablesize = (32); static const uint16 kScreenwidth = (320); static const uint16 kKeypadx = (36+112); static const uint16 kItempicsize = (44); +static const uint16 kLenofreelrouts = (457); static const uint16 kDiaryy = (48+12); static const uint16 kOpsy = (52); static const uint16 kSymboly = (56); @@ -531,201 +456,61 @@ static const uint16 kZoomx = (8); static const uint16 kInventx = (80); static const uint16 kMenux = (80+40); static const uint16 kHeaderlen = (96); -static const uint16 kLenofreelrouts = (983-526); class DreamGenContext : public DreamBase, public Context { public: - DreamGenContext(DreamWeb::DreamWebEngine *en) : DreamBase(en), Context(data) {} + DreamGenContext(DreamWeb::DreamWebEngine *en) : DreamBase(en), Context(this) {} void __start(); #include "stubs.h" // Allow hand-reversed functions to have a signature different than void f() - void useWire(); - void getNamePos(); - void identifyOb(); - void useLighter(); - void runEndSeq(); - void useOpenBox(); - void clearBuffers(); + void fadeDownMon(); + void getPersonText(); void getObTextStart(); - void dumpDiaryKeys(); - void entryTexts(); - void checkInput(); - void putUnderCentre(); void checkObjectSize(); - void watchReel(); - void findText1(); - void isRyanHolding(); - void showSlots(); - void useCashCard(); - void moneyPoke(); void doSomeTalk(); - void showSaveOps(); - void introMonks1(); void resetLocation(); - void introMonks2(); - void greyscaleSum(); - void getOpenedSize(); - void adjustUp(); - void fadeScreenDownHalf(); - void fadeDownMon(); - void printmessage2(); - void bartender(); - void showDiary(); void outOfOpen(); void dirCom(); - void endGameSeq(); void findFirstPath(); - void useSLab(); - void useAltar(); void startTalk(); void getAnyAd(); - void endGame(); - void usePipe(); - void getUnderZoom(); void reminders(); - void runTap(); - void talk(); - void showMonk(); - void checkForExit(); - void lookInInterface(); - void inToInv(); - void adjustLeft(); - void deleteExText(); - void entryAnims(); void getFreeAd(); - void showArrows(); - void printOuterMon(); - void showDecisions(); - void removeObFromInv(); - void heavy(); - void useKey(); - void lockLightOn(); - void discOps(); - void middlePanel(); - void monitorLogo(); void dirFile(); void pickupConts(); - void lockLightOff(); - void advisor(); - void allPalette(); - void cantDrop(); - void copper(); - void placeFreeObject(); - void putUnderZoom(); - void findInvPos(); - void workoutFrames(); - void rollEndCredits(); - void getKeyAndLogo(); - void selectOb(); - void useCooker(); - void receptionist(); - void selectSlot(); - void decide(); void fadeUpMon(); - void showDiaryPage(); - void transferToEx(); void reExFromInv(); - void businessMan(); - void outOfInv(); - void diaryKeyP(); void transferMap(); - void diaryKeyN(); void purgeAnItem(); void purgeALocation(); - void notHeldError(); void getSetAd(); - void soldier1(); - void getUnderCentre(); - void showKeys(); - void nextColon(); - void hangOnPQ(); void findOpenPos(); - void describeOb(); - void deleteExFrame(); void searchForSame(); - void fadeFromWhite(); void rollEm(); - void poolGuard(); - void lookAtPlace(); - void useAxe(); void findAllOpen(); - void quitSymbol(); - void findSetObject(); - void useDiary(); - void deleteExObject(); - void removeFreeObject(); - void lookAtCard(); - void helicopter(); + void fillOpen(); void getEitherAd(); - void setPickup(); void dropObject(); - void openOb(); - void drawItAll(); - void useStereo(); - void showOpBox(); - void doFade(); - void dumpCurrent(); - void showDiaryKeys(); - void rollEndCredits2(); void useOpened(); - void fillOpen(); - void signOn(); - void showGun(); void locationPic(); - void triggerMessage(); void swapWithOpen(); void dreamweb(); - void dropError(); - void checkInside(); void findPathOfPoint(); - void getBack1(); void getDestInfo(); - void setupTimedUse(); - void makeCaps(); void read(); - void additionalText(); - void mugger(); void searchForString(); void selectOpenOb(); - void useGun(); - void autoAppear(); - void newPlace(); - void useHandle(); - void showPuzText(); void incRyanPage(); - void findExObject(); - void clearChanges(); void searchForFiles(); - void monkSpeaking(); - void madmanRun(); - void afterNewRoom(); void getExAd(); void initialMonCols(); - void checkForShake(); - void useButtonA(); - void execCommand(); - void updateSymbolBot(); - void findPuzText(); void swapWithInv(); - void useControl(); - void adjustRight(); - void updateSymbolTop(); - void doSaveLoad(); - void createName(); - void getPersonText(); + void transferToEx(); void parser(); - void showLoadOps(); - void underTextLine(); - void showNames(); void emergencyPurge(); - void quitKey(); - void processTrigger(); void transferConToEx(); - void adjustDown(); - void withWhat(); - void fadeToWhite(); }; } // End of namespace DreamGen diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp index df39c4dfd6..997f36438e 100644 --- a/engines/dreamweb/dreamweb.cpp +++ b/engines/dreamweb/dreamweb.cpp @@ -30,9 +30,6 @@ #include "common/timer.h" #include "common/util.h" -#include "audio/mixer.h" -#include "audio/decoders/raw.h" - #include "graphics/palette.h" #include "graphics/surface.h" @@ -54,7 +51,6 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam _console = 0; DebugMan.addDebugChannel(kDebugAnimation, "Animation", "Animation Debug Flag"); DebugMan.addDebugChannel(kDebugSaveLoad, "SaveLoad", "Track Save/Load Function"); - _outSaveFile = 0; _inSaveFile = 0; _speed = 1; _turbo = false; @@ -101,7 +97,7 @@ void DreamWebEngine::waitForVSync() { } _base.doShake(); - _context.doFade(); + _base.doFade(); _system->updateScreen(); } @@ -111,8 +107,7 @@ void DreamWebEngine::quit() { } void DreamWebEngine::processEvents() { - Common::EventManager *event_manager = _system->getEventManager(); - if (event_manager->shouldQuit()) { + if (_eventMan->shouldQuit()) { quit(); return; } @@ -120,7 +115,7 @@ void DreamWebEngine::processEvents() { soundHandler(); Common::Event event; int softKey, hardKey; - while (event_manager->pollEvent(event)) { + while (_eventMan->pollEvent(event)) { switch(event.type) { case Common::EVENT_RTL: quit(); @@ -214,13 +209,13 @@ Common::Error DreamWebEngine::run() { syncSoundSettings(); _console = new DreamWebConsole(this); - ConfMan.registerDefault("dreamweb_originalsaveload", "true"); + ConfMan.registerDefault("dreamweb_originalsaveload", "false"); - getTimerManager()->installTimerProc(vSyncInterrupt, 1000000 / 70, this, "dreamwebVSync"); + _timer->installTimerProc(vSyncInterrupt, 1000000 / 70, this, "dreamwebVSync"); _context.__start(); _base.data.byte(DreamGen::kQuitrequested) = 0; - getTimerManager()->removeTimerProc(vSyncInterrupt); + _timer->removeTimerProc(vSyncInterrupt); return Common::kNoError; } @@ -228,8 +223,8 @@ Common::Error DreamWebEngine::run() { void DreamWebEngine::setSpeed(uint speed) { debug(0, "setting speed %u", speed); _speed = speed; - getTimerManager()->removeTimerProc(vSyncInterrupt); - getTimerManager()->installTimerProc(vSyncInterrupt, 1000000 / 70 / speed, this, "dreamwebVSync"); + _timer->removeTimerProc(vSyncInterrupt); + _timer->installTimerProc(vSyncInterrupt, 1000000 / 70 / speed, this, "dreamwebVSync"); } void DreamWebEngine::openFile(const Common::String &name) { @@ -237,7 +232,10 @@ void DreamWebEngine::openFile(const Common::String &name) { closeFile(); if (_file.open(name)) return; - _inSaveFile = _system->getSavefileManager()->openForLoading(name); + // File not found? See if there is a save state with this name + // FIXME: Is this really needed? If yes, document why; if not, + // remove all traces of _inSaveFile. + _inSaveFile = _saveFileMan->openForLoading(name); if (_inSaveFile) return; error("cannot open file %s", name.c_str()); @@ -264,35 +262,15 @@ void DreamWebEngine::closeFile() { _file.close(); delete _inSaveFile; _inSaveFile = 0; - delete _outSaveFile; - _outSaveFile = 0; } -void DreamWebEngine::openSaveFileForWriting(const Common::String &name) { - processEvents(); - delete _outSaveFile; - _outSaveFile = _system->getSavefileManager()->openForSaving(name); -} - -bool DreamWebEngine::openSaveFileForReading(const Common::String &name) { - processEvents(); - delete _inSaveFile; - _inSaveFile = _system->getSavefileManager()->openForLoading(name); - return _inSaveFile != 0; -} - -uint DreamWebEngine::writeToSaveFile(const uint8 *data, uint size) { - processEvents(); - if (!_outSaveFile) - error("save file was not opened for writing"); - return _outSaveFile->write(data, size); -} - -uint DreamWebEngine::readFromSaveFile(uint8 *data, uint size) { - processEvents(); - if (!_inSaveFile) - error("save file was not opened for reading"); - return _inSaveFile->read(data, size); +Common::String DreamWebEngine::getSavegameFilename(int slot) const { + // TODO: Are saves from all versions of Dreamweb compatible with each other? + // Then we can can consider keeping the filenames as DREAMWEB.Dnn. + // Otherwise, this must be changed to be target dependent. + //Common::String filename = _targetName + Common::String::format(".d%02d", savegameId); + Common::String filename = Common::String::format("DREAMWEB.D%02d", slot); + return filename; } void DreamWebEngine::keyPressed(uint16 ascii) { @@ -309,8 +287,7 @@ void DreamWebEngine::keyPressed(uint16 ascii) { void DreamWebEngine::mouseCall(uint16 *x, uint16 *y, uint16 *state) { processEvents(); - Common::EventManager *eventMan = _system->getEventManager(); - Common::Point pos = eventMan->getMousePos(); + Common::Point pos = _eventMan->getMousePos(); if (pos.x > 298) pos.x = 298; if (pos.x < 15) @@ -322,21 +299,21 @@ void DreamWebEngine::mouseCall(uint16 *x, uint16 *y, uint16 *state) { *x = pos.x; *y = pos.y; - unsigned newState = eventMan->getButtonState(); + unsigned newState = _eventMan->getButtonState(); *state = (newState == _oldMouseState? 0 : newState); _oldMouseState = newState; } void DreamWebEngine::getPalette(uint8 *data, uint start, uint count) { _system->getPaletteManager()->grabPalette(data, start, count); - while(count--) + while (count--) *data++ >>= 2; } void DreamWebEngine::setPalette(const uint8 *data, uint start, uint count) { assert(start + count <= 256); uint8 fixed[768]; - for(uint i = 0; i < count * 3; ++i) { + for (uint i = 0; i < count * 3; ++i) { fixed[i] = data[i] << 2; } _system->getPaletteManager()->setPalette(fixed, start, count); @@ -353,15 +330,15 @@ void DreamWebEngine::blit(const uint8 *src, int pitch, int x, int y, int w, int } void DreamWebEngine::printUnderMonitor() { - uint8 *dst = _base._workspace + DreamGen::kScreenwidth * 43 + 76; + uint8 *dst = _base.workspace() + DreamGen::kScreenwidth * 43 + 76; Graphics::Surface *s = _system->lockScreen(); if (!s) error("lockScreen failed"); - for(uint y = 0; y < 104; ++y) { + for (uint y = 0; y < 104; ++y) { uint8 *src = (uint8 *)s->getBasePtr(76, 43 + 8 + y); - for(uint x = 0; x < 170; ++x) { + for (uint x = 0; x < 170; ++x) { if (*src < 231) *dst++ = *src++; else { @@ -377,170 +354,6 @@ void DreamWebEngine::cls() { _system->fillScreen(0); } -void DreamWebEngine::playSound(uint8 channel, uint8 id, uint8 loops) { - debug(1, "playSound(%u, %u, %u)", channel, id, loops); - - int bank = 0; - bool speech = false; - Audio::Mixer::SoundType type = channel == 0? - Audio::Mixer::kMusicSoundType: Audio::Mixer::kSFXSoundType; - - if (id >= 12) { - id -= 12; - bank = 1; - if (id == 50) { - speech = true; - type = Audio::Mixer::kSpeechSoundType; - } - } - const SoundData &data = _soundData[bank]; - - Audio::SeekableAudioStream *raw; - if (!speech) { - if (id >= data.samples.size() || data.samples[id].size == 0) { - warning("invalid sample #%u played", id); - return; - } - - const Sample &sample = data.samples[id]; - uint8 *buffer = (uint8 *)malloc(sample.size); - if (!buffer) - error("out of memory: cannot allocate memory for sound(%u bytes)", sample.size); - memcpy(buffer, data.data.begin() + sample.offset, sample.size); - - raw = Audio::makeRawStream( - buffer, - sample.size, 22050, Audio::FLAG_UNSIGNED); - } else { - uint8 *buffer = (uint8 *)malloc(_speechData.size()); - if (!buffer) - error("out of memory: cannot allocate memory for sound(%u bytes)", _speechData.size()); - memcpy(buffer, _speechData.begin(), _speechData.size()); - raw = Audio::makeRawStream( - buffer, - _speechData.size(), 22050, Audio::FLAG_UNSIGNED); - - } - - Audio::AudioStream *stream; - if (loops > 1) { - stream = new Audio::LoopingAudioStream(raw, loops < 255? loops: 0); - } else - stream = raw; - - if (_mixer->isSoundHandleActive(_channelHandle[channel])) - _mixer->stopHandle(_channelHandle[channel]); - _mixer->playStream(type, &_channelHandle[channel], stream); -} - -void DreamWebEngine::stopSound(uint8 channel) { - debug(1, "stopSound(%u)", channel); - assert(channel == 0 || channel == 1); - _mixer->stopHandle(_channelHandle[channel]); - if (channel == 0) - _channel0 = 0; - else - _channel1 = 0; -} - -bool DreamWebEngine::loadSpeech(const Common::String &filename) { - if (ConfMan.getBool("speech_mute")) - return false; - - Common::File file; - if (!file.open("speech/" + filename)) - return false; - - debug(1, "loadSpeech(%s)", filename.c_str()); - - uint size = file.size(); - _speechData.resize(size); - file.read(_speechData.begin(), size); - file.close(); - return true; -} - -void DreamWebEngine::soundHandler() { - _base.data.byte(DreamGen::kSubtitles) = ConfMan.getBool("subtitles"); - _base.volumeAdjust(); - - uint volume = _base.data.byte(DreamGen::kVolume); - //.vol file loaded into soundbuf:0x4000 - //volume table at (volume * 0x100 + 0x3f00) - //volume value could be from 1 to 7 - //1 - 0x10-0xff - //2 - 0x1f-0xdf - //3 - 0x2f-0xd0 - //4 - 0x3e-0xc1 - //5 - 0x4d-0xb2 - //6 - 0x5d-0xa2 - //7 - 0x6f-0x91 - if (volume >= 8) - volume = 7; - volume = (8 - volume) * Audio::Mixer::kMaxChannelVolume / 8; - _mixer->setChannelVolume(_channelHandle[0], volume); - - uint8 ch0 = _base.data.byte(DreamGen::kCh0playing); - if (ch0 == 255) - ch0 = 0; - uint8 ch1 = _base.data.byte(DreamGen::kCh1playing); - if (ch1 == 255) - ch1 = 0; - uint8 ch0loop = _base.data.byte(DreamGen::kCh0repeat); - - if (_channel0 != ch0) { - _channel0 = ch0; - if (ch0) { - playSound(0, ch0, ch0loop); - } - } - if (_channel1 != ch1) { - _channel1 = ch1; - if (ch1) { - playSound(1, ch1, 1); - } - } - if (!_mixer->isSoundHandleActive(_channelHandle[0])) { - _base.data.byte(DreamGen::kCh0playing) = 255; - _channel0 = 0; - } - if (!_mixer->isSoundHandleActive(_channelHandle[1])) { - _base.data.byte(DreamGen::kCh1playing) = 255; - _channel1 = 0; - } - -} - -void DreamWebEngine::loadSounds(uint bank, const Common::String &filename) { - debug(1, "loadSounds(%u, %s)", bank, filename.c_str()); - Common::File file; - if (!file.open(filename)) { - warning("cannot open %s", filename.c_str()); - return; - } - - uint8 header[0x60]; - file.read(header, sizeof(header)); - uint tablesize = READ_LE_UINT16(header + 0x32); - debug(1, "table size = %u", tablesize); - - SoundData &soundData = _soundData[bank]; - soundData.samples.resize(tablesize / 6); - uint total = 0; - for(uint i = 0; i < tablesize / 6; ++i) { - uint8 entry[6]; - Sample &sample = soundData.samples[i]; - file.read(entry, sizeof(entry)); - sample.offset = entry[0] * 0x4000 + READ_LE_UINT16(entry + 1); - sample.size = READ_LE_UINT16(entry + 3) * 0x800; - total += sample.size; - debug(1, "offset: %08x, size: %u", sample.offset, sample.size); - } - soundData.data.resize(total); - file.read(soundData.data.begin(), total); - file.close(); -} - uint8 DreamWebEngine::modifyChar(uint8 c) const { if (c < 128) return c; @@ -597,3 +410,13 @@ uint8 DreamWebEngine::modifyChar(uint8 c) const { } } // End of namespace DreamWeb + + +namespace DreamGen { + +// FIXME/TODO: Move this to a better place. +DreamBase::DreamBase(DreamWeb::DreamWebEngine *en) : engine(en) { + _openChangeSize = kInventx+(4*kItempicsize); +} + +} // End of namespace DreamGen diff --git a/engines/dreamweb/dreamweb.h b/engines/dreamweb/dreamweb.h index 1d16a188d2..4d7bf5f0e4 100644 --- a/engines/dreamweb/dreamweb.h +++ b/engines/dreamweb/dreamweb.h @@ -42,6 +42,10 @@ #include "dreamweb/structs.h" +#define SCUMMVM_HEADER MKTAG('S', 'C', 'V', 'M') +#define SCUMMVM_BLOCK_MAGIC_SIZE 0x1234 +#define SAVEGAME_VERSION 1 + namespace DreamGen { // These are for ReelRoutine::reelPointer, which is a callback field. @@ -104,11 +108,7 @@ public: void getPalette(uint8 *data, uint start, uint count); void setPalette(const uint8 *data, uint start, uint count); - void openSaveFileForWriting(const Common::String &name); - uint writeToSaveFile(const uint8 *data, uint size); - - bool openSaveFileForReading(const Common::String &name); - uint readFromSaveFile(uint8 *data, uint size); + Common::String getSavegameFilename(int slot) const; void setShakePos(int pos) { _system->setShakePos(pos); } void printUnderMonitor(); @@ -149,7 +149,6 @@ private: Common::RandomSource _rnd; Common::File _file; - Common::OutSaveFile *_outSaveFile; Common::InSaveFile *_inSaveFile; uint _speed; diff --git a/engines/dreamweb/keypad.cpp b/engines/dreamweb/keypad.cpp index 44b01c4cc9..43f6749cad 100644 --- a/engines/dreamweb/keypad.cpp +++ b/engines/dreamweb/keypad.cpp @@ -24,15 +24,15 @@ namespace DreamGen { -void DreamGenContext::getUnderMenu() { +void DreamBase::getUnderMenu() { multiGet(getSegment(data.word(kBuffers)).ptr(kUndertimedtext, 0), kMenux, kMenuy, 48, 48); } -void DreamGenContext::putUnderMenu() { +void DreamBase::putUnderMenu() { multiPut(getSegment(data.word(kBuffers)).ptr(kUndertimedtext, 0), kMenux, kMenuy, 48, 48); } -void DreamGenContext::singleKey(uint8 key, uint16 x, uint16 y) { +void DreamBase::singleKey(uint8 key, uint16 x, uint16 y) { if (key == data.byte(kGraphicpress)) { key += 11; if (data.byte(kPresscount) < 8) @@ -42,11 +42,11 @@ void DreamGenContext::singleKey(uint8 key, uint16 x, uint16 y) { showFrame(tempGraphics(), x, y, key, 0); } -void DreamGenContext::loadKeypad() { +void DreamBase::loadKeypad() { loadIntoTemp("DREAMWEB.G02"); } -void DreamGenContext::showKeypad() { +void DreamBase::showKeypad() { singleKey(22, kKeypadx+9, kKeypady+5); singleKey(23, kKeypadx+31, kKeypady+5); singleKey(24, kKeypadx+53, kKeypady+5); @@ -75,13 +75,13 @@ void DreamGenContext::showKeypad() { } } -bool DreamGenContext::isItRight(uint8 digit0, uint8 digit1, uint8 digit2, uint8 digit3) { +bool DreamBase::isItRight(uint8 digit0, uint8 digit1, uint8 digit2, uint8 digit3) { return digit0 == data.byte(kPresslist+0) && digit1 == data.byte(kPresslist+1) && digit2 == data.byte(kPresslist+2) && digit3 == data.byte(kPresslist+3); } -void DreamGenContext::addToPressList() { +void DreamBase::addToPressList() { if (data.word(kPresspointer) == 5) return; uint8 pressed = data.byte(kPressed); @@ -94,19 +94,19 @@ void DreamGenContext::addToPressList() { void DreamGenContext::enterCode(uint8 digit0, uint8 digit1, uint8 digit2, uint8 digit3) { RectWithCallback keypadList[] = { - { kKeypadx+9,kKeypadx+30,kKeypady+9,kKeypady+22,&DreamGenContext::buttonOne }, - { kKeypadx+31,kKeypadx+52,kKeypady+9,kKeypady+22,&DreamGenContext::buttonTwo }, - { kKeypadx+53,kKeypadx+74,kKeypady+9,kKeypady+22,&DreamGenContext::buttonThree }, - { kKeypadx+9,kKeypadx+30,kKeypady+23,kKeypady+40,&DreamGenContext::buttonFour }, - { kKeypadx+31,kKeypadx+52,kKeypady+23,kKeypady+40,&DreamGenContext::buttonFive }, - { kKeypadx+53,kKeypadx+74,kKeypady+23,kKeypady+40,&DreamGenContext::buttonSix }, - { kKeypadx+9,kKeypadx+30,kKeypady+41,kKeypady+58,&DreamGenContext::buttonSeven }, - { kKeypadx+31,kKeypadx+52,kKeypady+41,kKeypady+58,&DreamGenContext::buttonEight }, - { kKeypadx+53,kKeypadx+74,kKeypady+41,kKeypady+58,&DreamGenContext::buttonNine }, - { kKeypadx+9,kKeypadx+30,kKeypady+59,kKeypady+73,&DreamGenContext::buttonNought }, - { kKeypadx+31,kKeypadx+74,kKeypady+59,kKeypady+73,&DreamGenContext::buttonEnter }, - { kKeypadx+72,kKeypadx+86,kKeypady+80,kKeypady+94,&DreamGenContext::quitKey }, - { 0,320,0,200,&DreamGenContext::blank }, + { kKeypadx+9,kKeypadx+30,kKeypady+9,kKeypady+22,&DreamBase::buttonOne }, + { kKeypadx+31,kKeypadx+52,kKeypady+9,kKeypady+22,&DreamBase::buttonTwo }, + { kKeypadx+53,kKeypadx+74,kKeypady+9,kKeypady+22,&DreamBase::buttonThree }, + { kKeypadx+9,kKeypadx+30,kKeypady+23,kKeypady+40,&DreamBase::buttonFour }, + { kKeypadx+31,kKeypadx+52,kKeypady+23,kKeypady+40,&DreamBase::buttonFive }, + { kKeypadx+53,kKeypadx+74,kKeypady+23,kKeypady+40,&DreamBase::buttonSix }, + { kKeypadx+9,kKeypadx+30,kKeypady+41,kKeypady+58,&DreamBase::buttonSeven }, + { kKeypadx+31,kKeypadx+52,kKeypady+41,kKeypady+58,&DreamBase::buttonEight }, + { kKeypadx+53,kKeypadx+74,kKeypady+41,kKeypady+58,&DreamBase::buttonNine }, + { kKeypadx+9,kKeypadx+30,kKeypady+59,kKeypady+73,&DreamBase::buttonNought }, + { kKeypadx+31,kKeypadx+74,kKeypady+59,kKeypady+73,&DreamBase::buttonEnter }, + { kKeypadx+72,kKeypadx+86,kKeypady+80,kKeypady+94,&DreamBase::quitKey }, + { 0,320,0,200,&DreamBase::blank }, { 0xFFFF,0,0,0,0 } }; @@ -118,7 +118,7 @@ void DreamGenContext::enterCode(uint8 digit0, uint8 digit1, uint8 digit2, uint8 showKeypad(); readMouse(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); data.word(kPresspointer) = 0; data.byte(kGetback) = 0; @@ -164,51 +164,51 @@ void DreamGenContext::enterCode(uint8 digit0, uint8 digit1, uint8 digit2, uint8 workToScreenM(); } -void DreamGenContext::buttonOne() { +void DreamBase::buttonOne() { buttonPress(1); } -void DreamGenContext::buttonTwo() { +void DreamBase::buttonTwo() { buttonPress(2); } -void DreamGenContext::buttonThree() { +void DreamBase::buttonThree() { buttonPress(3); } -void DreamGenContext::buttonFour() { +void DreamBase::buttonFour() { buttonPress(4); } -void DreamGenContext::buttonFive() { +void DreamBase::buttonFive() { buttonPress(5); } -void DreamGenContext::buttonSix() { +void DreamBase::buttonSix() { buttonPress(6); } -void DreamGenContext::buttonSeven() { +void DreamBase::buttonSeven() { buttonPress(7); } -void DreamGenContext::buttonEight() { +void DreamBase::buttonEight() { buttonPress(8); } -void DreamGenContext::buttonNine() { +void DreamBase::buttonNine() { buttonPress(9); } -void DreamGenContext::buttonNought() { +void DreamBase::buttonNought() { buttonPress(10); } -void DreamGenContext::buttonEnter() { +void DreamBase::buttonEnter() { buttonPress(11); } -void DreamGenContext::buttonPress(uint8 buttonId) { +void DreamBase::buttonPress(uint8 buttonId) { uint8 commandType = 100 + buttonId; if (data.byte(kCommandtype) != commandType) { data.byte(kCommandtype) = commandType; @@ -223,25 +223,45 @@ void DreamGenContext::buttonPress(uint8 buttonId) { } } -void DreamGenContext::showOuterPad() { +void DreamBase::showOuterPad() { showFrame(tempGraphics(), kKeypadx-3, kKeypady-4, 1, 0); showFrame(tempGraphics(), kKeypadx+74, kKeypady+76, 37, 0); } -void DreamGenContext::dumpKeypad() { +void DreamBase::dumpKeypad() { multiDump(kKeypadx - 3, kKeypady - 4, 120, 90); } -void DreamGenContext::dumpSymbol() { +void DreamBase::dumpSymbol() { data.byte(kNewtextline) = 0; multiDump(kSymbolx, kSymboly + 20, 104, 60); } -void DreamGenContext::dumpSymBox() { +void DreamBase::dumpSymBox() { if (data.word(kDumpx) != 0xFFFF) { multiDump(data.word(kDumpx), data.word(kDumpy), 30, 77); data.word(kDumpx) = 0xFFFF; } } +void DreamBase::quitSymbol() { + if (data.byte(kSymboltopx) != 24 || data.byte(kSymbolbotx) != 24) { + blank(); + return; + }; + + if (data.byte(kCommandtype) != 222) { + data.byte(kCommandtype) = 222; + commandOnly(18); + } + + if (data.word(kMousebutton) == data.word(kOldbutton)) + return; // notqs + + if (!(data.word(kMousebutton) & 1)) + return; + + data.byte(kGetback) = 1; +} + } // End of namespace DreamGen diff --git a/engines/dreamweb/module.mk b/engines/dreamweb/module.mk index 304daf6036..398f0b8db0 100644 --- a/engines/dreamweb/module.mk +++ b/engines/dreamweb/module.mk @@ -13,6 +13,7 @@ MODULE_OBJS := \ people.o \ print.o \ saveload.o \ + sound.o \ sprite.o \ stubs.o \ talk.o \ diff --git a/engines/dreamweb/monitor.cpp b/engines/dreamweb/monitor.cpp index f552b71c00..26caeb29ec 100644 --- a/engines/dreamweb/monitor.cpp +++ b/engines/dreamweb/monitor.cpp @@ -25,9 +25,17 @@ namespace DreamGen { struct MonitorKeyEntry { - uint8 b0; - uint8 b1; - char b2[24]; + uint8 keyAssigned; + char username[12]; + char password[12]; +}; + +// New monitor key list +static MonitorKeyEntry monitorKeyEntries[4] = { + { 1, "PUBLIC", "PUBLIC" }, + { 0, "RYAN", "BLACKDRAGON" }, + { 0, "LOUIS", "HENDRIX" }, + { 0, "BECKETT", "SEPTIMUS" } }; void DreamGenContext::useMon() { @@ -35,11 +43,10 @@ void DreamGenContext::useMon() { memset(data.ptr(kCurrentfile+1, 0), ' ', 12); memset(data.ptr(offset_operand1+1, 0), ' ', 12); - MonitorKeyEntry *monitorKeyEntries = (MonitorKeyEntry *)data.ptr(offset_keys, 0); - monitorKeyEntries[0].b0 = 1; - monitorKeyEntries[1].b0 = 0; - monitorKeyEntries[2].b0 = 0; - monitorKeyEntries[3].b0 = 0; + monitorKeyEntries[0].keyAssigned = 1; + monitorKeyEntries[1].keyAssigned = 0; + monitorKeyEntries[2].keyAssigned = 0; + monitorKeyEntries[3].keyAssigned = 0; createPanel(); showPanel(); @@ -54,7 +61,7 @@ void DreamGenContext::useMon() { printOuterMon(); initialMonCols(); printLogo(); - workToScreen(); + workToScreenCPP(); turnOnPower(); fadeupYellows(); fadeupMonFirst(); @@ -70,20 +77,17 @@ void DreamGenContext::useMon() { scrollMonitor(); data.word(kBufferin) = 0; data.word(kBufferout) = 0; + bool stop = false; do { - di = data.word(kMonadx); - bx = data.word(kMonady); - push(di); - push(bx); + uint16 oldMonadx = data.word(kMonadx); + uint16 oldMonady = data.word(kMonady); input(); - bx = pop(); - di = pop(); - data.word(kMonadx) = di; - data.word(kMonady) = bx; - execCommand(); + data.word(kMonadx) = oldMonadx; + data.word(kMonady) = oldMonady; + stop = execCommand(); if (quitRequested()) //TODO : Check why it crashes when put before the execcommand break; - } while (al == 0); + } while (!stop); getRidOfTemp(); getRidOfTempCharset(); deallocateMem(data.word(kTextfile1)); @@ -97,12 +101,94 @@ void DreamGenContext::useMon() { workToScreenM(); } -void DreamGenContext::printLogo() { +bool DreamGenContext::execCommand() { + static const char *comlist[] = { + "EXIT", + "HELP", + "LIST", + "READ", + "LOGON", + "KEYS" + }; + + const char *inputLine = (const char *)data.ptr(kInputline, 64); + if (*inputLine == 0) { + // No input + scrollMonitor(); + return false; + } + + int cmd; + bool done = false; + // Loop over all commands in the list and see if we get a match + for (cmd = 0; cmd < ARRAYSIZE(comlist); ++cmd) { + const char *cmdStr = comlist[cmd]; + const char *inputStr = inputLine; + // Compare the command, char by char, to see if we get a match. + // We only care about the prefix matching, though. + char inputChar, cmdChar; + do { + inputChar = *inputStr; inputStr += 2; + cmdChar = *cmdStr++; + if (cmdChar == 0) { + done = true; + break; + } + } while (inputChar == cmdChar); + + if (done) + break; + } + + // Execute the selected command + switch (cmd) { + case 0: + return true; + case 1: + monMessage(6); + break; + case 2: + dirCom(); + break; + case 3: + read(); + break; + case 4: + signOn(); + break; + case 5: + showKeys(); + break; + default: + netError(); + break; + } + return false; +} + + + +void DreamBase::monitorLogo() { + if (data.byte(kLogonum) != data.byte(kOldlogonum)) { + data.byte(kOldlogonum) = data.byte(kLogonum); + printLogo(); + printUnderMon(); + workToScreenCPP(); + printLogo(); + printLogo(); + playChannel1(26); + randomAccess(20); + } else { + printLogo(); + } +} + +void DreamBase::printLogo() { showFrame(tempGraphics(), 56, 32, 0, 0); showCurrentFile(); } -void DreamGenContext::input() { +void DreamBase::input() { char *inputLine = (char *)data.ptr(kInputline, 64); memset(inputLine, 0, 64); data.word(kCurpos) = 0; @@ -132,9 +218,7 @@ void DreamGenContext::input() { continue; if ((currentKey == 32) && (data.word(kCurpos) == 0)) continue; - al = currentKey; - makeCaps(); - currentKey = al; + currentKey = makeCaps(currentKey); inputLine[data.word(kCurpos) * 2 + 0] = currentKey; if (currentKey > 'Z') continue; @@ -148,7 +232,18 @@ void DreamGenContext::input() { } } -void DreamGenContext::delChar() { +void DreamGenContext::makeCaps() { + al = makeCaps(al); +} + +byte DreamBase::makeCaps(byte c) { + // TODO: Replace calls to this by toupper() ? + if (c >= 'a') + c -= 'a' - 'A'; // = 32 + return c; +} + +void DreamBase::delChar() { char *inputLine = (char *)data.ptr(kInputline, 0); --data.word(kCurpos); inputLine[data.word(kCurpos) * 2] = 0; @@ -158,10 +253,10 @@ void DreamGenContext::delChar() { uint16 offset = data.word(kCurpos); offset = ((offset & 0x00ff) << 8) | ((offset & 0xff00) >> 8); multiPut(mapStore() + offset, data.word(kMonadx), data.word(kMonady), 8, 8); - multiDump(data.word(kMonadx), data.word(kMonady), al, 8); + multiDump(data.word(kMonadx), data.word(kMonady), 8, 8); } -void DreamGenContext::printCurs() { +void DreamBase::printCurs() { uint16 x = data.word(kCurslocx); uint16 y = data.word(kCurslocy); uint16 height; @@ -177,7 +272,7 @@ void DreamGenContext::printCurs() { multiDump(x - 6, y, 12, height); } -void DreamGenContext::delCurs() { +void DreamBase::delCurs() { uint16 x = data.word(kCurslocx); uint16 y = data.word(kCurslocy); uint16 width = 6; @@ -191,18 +286,14 @@ void DreamGenContext::delCurs() { multiDump(x, y, width, height); } -void DreamGenContext::hangOnCurs() { - hangOnCurs(cx); -} - -void DreamGenContext::scrollMonitor() { +void DreamBase::scrollMonitor() { printLogo(); printUnderMon(); workToScreenCPP(); playChannel1(25); } -void DreamGenContext::showCurrentFile() { +void DreamBase::showCurrentFile() { uint16 x = 178; // TODO: Looks like this hardcoded constant in the asm doesn't match the frame const char *currentFile = (const char *)data.ptr(kCurrentfile+1, 0); while (*currentFile) { @@ -212,12 +303,12 @@ void DreamGenContext::showCurrentFile() { } } -void DreamGenContext::accessLightOn() { +void DreamBase::accessLightOn() { showFrame(tempGraphics(), 74, 182, 8, 0); multiDump(74, 182, 12, 8); } -void DreamGenContext::accessLightOff() { +void DreamBase::accessLightOff() { showFrame(tempGraphics(), 74, 182, 7, 0); multiDump(74, 182, 12, 8); } @@ -226,7 +317,7 @@ void DreamGenContext::randomAccess() { randomAccess(cx); } -void DreamGenContext::randomAccess(uint16 count) { +void DreamBase::randomAccess(uint16 count) { for (uint16 i = 0; i < count; ++i) { vSync(); vSync(); @@ -243,7 +334,7 @@ void DreamGenContext::monMessage() { monMessage(al); } -void DreamGenContext::monMessage(uint8 index) { +void DreamBase::monMessage(uint8 index) { assert(index > 0); const char *string = (const char *)getSegment(data.word(kTextfile1)).ptr(kTextstart, 0); for (uint8 i = 0; i < index; ++i) { @@ -253,22 +344,32 @@ void DreamGenContext::monMessage(uint8 index) { monPrint(string); } -void DreamGenContext::netError() { +void DreamBase::netError() { monMessage(5); scrollMonitor(); } -void DreamGenContext::powerLightOn() { +void DreamBase::powerLightOn() { showFrame(tempGraphics(), 257+4, 182, 6, 0); multiDump(257+4, 182, 12, 8); } -void DreamGenContext::powerLightOff() { +void DreamBase::powerLightOff() { showFrame(tempGraphics(), 257+4, 182, 5, 0); multiDump(257+4, 182, 12, 8); } -void DreamGenContext::turnOnPower() { +void DreamBase::lockLightOn() { + showFrame(tempGraphics(), 56, 182, 10, 0); + multiDump(58, 182, 12, 8); +} + +void DreamBase::lockLightOff() { + showFrame(tempGraphics(), 56, 182, 9, 0); + multiDump(58, 182, 12, 8); +} + +void DreamBase::turnOnPower() { for (size_t i = 0; i < 3; ++i) { powerLightOn(); hangOn(30); @@ -278,14 +379,21 @@ void DreamGenContext::turnOnPower() { powerLightOn(); } -void DreamGenContext::loadPersonal() { +void DreamBase::printOuterMon() { + showFrame(tempGraphics(), 40, 32, 1, 0); + showFrame(tempGraphics(), 264, 32, 2, 0); + showFrame(tempGraphics(), 40, 12, 3, 0); + showFrame(tempGraphics(), 40, 164, 4, 0); +} + +void DreamBase::loadPersonal() { if (data.byte(kLocation) == 0 || data.byte(kLocation) == 42) data.word(kTextfile1) = standardLoad("DREAMWEB.T01"); // monitor file 1 else data.word(kTextfile1) = standardLoad("DREAMWEB.T02"); // monitor file 2 } -void DreamGenContext::loadNews() { +void DreamBase::loadNews() { // textfile2 holds information accessible by anyone if (data.byte(kNewsitem) == 0) data.word(kTextfile2) = standardLoad("DREAMWEB.T10"); // monitor file 10 @@ -297,19 +405,111 @@ void DreamGenContext::loadNews() { data.word(kTextfile2) = standardLoad("DREAMWEB.T13"); // monitor file 13 } -void DreamGenContext::loadCart() { - lookInInterface(); +void DreamBase::loadCart() { + byte cartridgeId = 0; + uint16 objectIndex = findSetObject("INTF"); + uint16 cartridgeIndex = checkInside(objectIndex, 1); + if (cartridgeIndex != kNumexobjects) + cartridgeId = getExAd(cartridgeIndex)->id[3] + 1; - if (al == 0) + if (cartridgeId == 0) data.word(kTextfile3) = standardLoad("DREAMWEB.T20"); // monitor file 20 - else if (al == 1) + else if (cartridgeId == 1) data.word(kTextfile3) = standardLoad("DREAMWEB.T21"); // monitor file 21 - else if (al == 2) + else if (cartridgeId == 2) data.word(kTextfile3) = standardLoad("DREAMWEB.T22"); // monitor file 22 - else if (al == 3) + else if (cartridgeId == 3) data.word(kTextfile3) = standardLoad("DREAMWEB.T23"); // monitor file 23 else data.word(kTextfile3) = standardLoad("DREAMWEB.T24"); // monitor file 24 } +void DreamGenContext::showKeys() { + randomAccess(10); + scrollMonitor(); + monMessage(18); + + for (int i = 0; i < 4; i++) { + if (monitorKeyEntries[i].keyAssigned) + monPrint(monitorKeyEntries[i].username); + } + + scrollMonitor(); +} + +void DreamGenContext::getKeyAndLogo() { + byte newLogo = es.byte(bx + 1) - 48; + byte keyNum = es.byte(bx + 1 + 2) - 48; + bx += 1 + 2 + 1; + + if (monitorKeyEntries[keyNum].keyAssigned == 1) { + // Key OK + data.byte(kLogonum) = newLogo; + al = 0; + } else { + monMessage(12); // "Access denied, key required -" + monPrint(monitorKeyEntries[keyNum].username); + scrollMonitor(); + al = 1; + } +} + +void DreamGenContext::signOn() { + parser(); + + int8 foundIndex = -1; + Common::String inputLine = (const char *)data.ptr(offset_operand1 + 1, 0); + inputLine.trim(); + + for (byte i = 0; i < 4; i++) { + if (inputLine.equalsIgnoreCase(monitorKeyEntries[i].username)) { + // Check if the key has already been assigned + if (monitorKeyEntries[i].keyAssigned) { + monMessage(17); + return; + } else { + foundIndex = i; + break; + } + } + } + + if (foundIndex == -1) { + monMessage(13); + return; + } + + monMessage(15); + + uint16 prevX = data.word(kMonadx); + uint16 prevY = data.word(kMonady); + input(); // password input + data.word(kMonadx) = prevX; + data.word(kMonady) = prevY; + + inputLine = (const char *)data.ptr(kInputline, 0); + inputLine.toUppercase(); + + // The entered line has zeroes in-between each character + uint32 len = strlen(monitorKeyEntries[foundIndex].password); + bool found = true; + + for (uint32 i = 0; i < len; i++) { + if (monitorKeyEntries[foundIndex].password[i] != inputLine[i * 2]) { + found = false; + break; + } + } + + if (!found) { + scrollMonitor(); + monMessage(16); + } else { + monMessage(14); + monPrint(monitorKeyEntries[foundIndex].username); + scrollMonitor(); + monitorKeyEntries[foundIndex].keyAssigned = 1; + } +} + } // End of namespace DreamGen diff --git a/engines/dreamweb/object.cpp b/engines/dreamweb/object.cpp index 44be58c168..9fe94c4bd4 100644 --- a/engines/dreamweb/object.cpp +++ b/engines/dreamweb/object.cpp @@ -24,7 +24,27 @@ namespace DreamGen { -void DreamGenContext::fillRyan() { +void DreamBase::showRyanPage() { + showFrame(engine->icons1(), kInventx + 167, kInventy - 12, 12, 0); + showFrame(engine->icons1(), kInventx + 167 + 18 * data.byte(kRyanpage), kInventy - 12, 13 + data.byte(kRyanpage), 0); +} + +void DreamBase::findAllRyan(uint8 *inv) { + memset(inv, 0xff, 60); + for (size_t i = 0; i < kNumexobjects; ++i) { + DynObject *extra = getExAd(i); + if (extra->mapad[0] != 4) + continue; + if (extra->mapad[1] != 0xff) + continue; + uint8 slot = extra->mapad[2]; + assert(slot < 30); + inv[2 * slot + 0] = i; + inv[2 * slot + 1] = 4; + } +} + +void DreamBase::fillRyan() { uint8 *inv = getSegment(data.word(kBuffers)).ptr(kRyaninvlist, 60); findAllRyan(inv); inv += data.byte(kRyanpage) * 2 * 10; @@ -42,7 +62,7 @@ void DreamGenContext::isItWorn() { flags._z = isItWorn((const DynObject *)es.ptr(bx, sizeof(DynObject))); } -bool DreamGenContext::isItWorn(const DynObject *object) { +bool DreamBase::isItWorn(const DynObject *object) { return (object->id[0] == 'W'-'A') && (object->id[1] == 'E'-'A'); } @@ -72,7 +92,7 @@ void DreamGenContext::obToInv() { obToInv(al, ah, di, bx); } -void DreamGenContext::obToInv(uint8 index, uint8 flag, uint16 x, uint16 y) { +void DreamBase::obToInv(uint8 index, uint8 flag, uint16 x, uint16 y) { showFrame(engine->icons1(), x - 2, y - 1, 10, 0); if (index == 0xff) return; @@ -87,11 +107,11 @@ void DreamGenContext::obToInv(uint8 index, uint8 flag, uint16 x, uint16 y) { showFrame(engine->icons1(), x - 3, y - 2, 7, 0); } -void DreamGenContext::obPicture() { - if (data.byte(kObjecttype) == 1) +void DreamBase::obPicture() { + if (data.byte(kObjecttype) == kSetObjectType1) return; Frame *frames; - if (data.byte(kObjecttype) == 4) + if (data.byte(kObjecttype) == kExObjectType) frames = (Frame *)getSegment(data.word(kExtras)).ptr(0, 0); else frames = (Frame *)getSegment(data.word(kFreeframes)).ptr(0, 0); @@ -99,7 +119,7 @@ void DreamGenContext::obPicture() { showFrame(frames, 160, 68, frame, 0x80); } -void DreamGenContext::obIcons() { +void DreamBase::obIcons() { uint8 value1, value2; getAnyAd(&value1, &value2); if (value1 != 0xff) { @@ -113,6 +133,7 @@ void DreamGenContext::obIcons() { void DreamGenContext::examineOb(bool examineAgain) { data.byte(kPointermode) = 0; data.word(kTimecount) = 0; + while (true) { if (examineAgain) { data.byte(kInmaparea) = 0; @@ -120,8 +141,7 @@ void DreamGenContext::examineOb(bool examineAgain) { data.byte(kOpenedob) = 255; data.byte(kOpenedtype) = 255; data.byte(kInvopen) = 0; - al = data.byte(kCommandtype); - data.byte(kObjecttype) = al; + data.byte(kObjecttype) = data.byte(kCommandtype); data.byte(kItemframe) = 0; data.byte(kPointerframe) = 0; createPanel(); @@ -135,7 +155,7 @@ void DreamGenContext::examineOb(bool examineAgain) { data.byte(kCommandtype) = 255; readMouse(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); examineAgain = false; } @@ -147,6 +167,7 @@ void DreamGenContext::examineOb(bool examineAgain) { dumpTextLine(); delPointer(); data.byte(kGetback) = 0; + switch (data.byte(kInvopen)) { case 0: { RectWithCallback examList[] = { @@ -154,22 +175,22 @@ void DreamGenContext::examineOb(bool examineAgain) { { 260,300,0,44,&DreamGenContext::useObject }, { 210,254,0,44,&DreamGenContext::selectOpenOb }, { 144,176,64,96,&DreamGenContext::setPickup }, - { 0,50,50,200,&DreamGenContext::examineInventory }, - { 0,320,0,200,&DreamGenContext::blank }, + { 0,50,50,200,&DreamBase::examineInventory }, + { 0,320,0,200,&DreamBase::blank }, { 0xFFFF,0,0,0,0 } }; checkCoords(examList); break; } case 1: { - // NB: This table contains the non-constant openChangeSize! + // Note: This table contains the non-constant _openChangeSize! RectWithCallback invList1[] = { { 273,320,157,198,&DreamGenContext::getBackFromOb }, { 255,294,0,24,&DreamGenContext::dropObject }, { kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamGenContext::incRyanPage }, - { kInventx, data.word(offset_openchangesize),kInventy+100,kInventy+100+kItempicsize,&DreamGenContext::useOpened }, - { kInventx,kInventx+(5*kItempicsize), kInventy,kInventy+(2*kItempicsize),&DreamGenContext::inToInv }, - { 0,320,0,200,&DreamGenContext::blank }, + { kInventx,_openChangeSize,kInventy+100,kInventy+100+kItempicsize,&DreamGenContext::useOpened }, + { kInventx,kInventx+(5*kItempicsize),kInventy,kInventy+(2*kItempicsize),&DreamGenContext::inToInv }, + { 0,320,0,200,&DreamBase::blank }, { 0xFFFF,0,0,0,0 } }; checkCoords(invList1); @@ -180,13 +201,14 @@ void DreamGenContext::examineOb(bool examineAgain) { { 273,320,157,198,&DreamGenContext::getBackFromOb }, { kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamGenContext::incRyanPage }, { kInventx,kInventx+(5*kItempicsize), kInventy,kInventy+(2*kItempicsize),&DreamGenContext::selectOb }, - { 0,320,0,200,&DreamGenContext::blank }, + { 0,320,0,200,&DreamBase::blank }, { 0xFFFF,0,0,0,0 } }; checkCoords(withList1); break; } } + if (data.byte(kQuitrequested) != 0) break; if (data.byte(kExamagain) != 0) @@ -238,7 +260,7 @@ void DreamGenContext::inventory() { openInv(); readMouse(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); data.byte(kOpenedob) = 255; examineOb(false); @@ -256,11 +278,371 @@ void DreamGenContext::transferText() { data.word(kExtextpos) += len + 1; } -void DreamGenContext::getBackFromOb() { +void DreamBase::getBackFromOb() { if (data.byte(kPickup) != 1) getBack1(); else blank(); } +void DreamGenContext::getOpenedSize() { + //ax = getOpenedSizeCPP(); + + // We need to call the ASM-style versions of get*Ad, as these also set + // bx and es + + al = data.byte(kOpenedob); + + switch (data.byte(kOpenedtype)) { + case 4: + getExAd(); + ax = es.word(bx+7); + break; + case 2: + getFreeAd(); + ax = es.word(bx+7); + break; + default: + getSetAd(); + ax = es.word(bx+3); + break; + } +} + +byte DreamGenContext::getOpenedSizeCPP() { + byte obj = data.byte(kOpenedob); + switch (data.byte(kOpenedtype)) { + case 4: + return getExAd(obj)->slotCount; + case 2: + return getFreeAd(obj)->slotCount; + default: + return getSetAd(obj)->slotCount; + } +} + +void DreamGenContext::openOb() { + uint8 commandLine[64] = "OBJECT NAME ONE "; + + copyName(data.byte(kOpenedtype), data.byte(kOpenedob), commandLine); + + printMessage(kInventx, kInventy+86, 62, 240, false); + + al = printDirect(commandLine, data.word(kLastxpos) + 5, kInventy+86, 220, false); + + fillOpen(); + _openChangeSize = getOpenedSizeCPP() * kItempicsize + kInventx; +} + +void DreamGenContext::identifyOb() { + if (data.word(kWatchingtime) != 0) { + blank(); + return; + } + + ax = data.word(kMousex) - data.word(kMapadx); + bx = data.word(kMousey) - data.word(kMapady); + + if (ax >= 22 * 8 || bx >= 20 * 8) { + blank(); + return; + } + + data.byte(kInmaparea) = 1; + ah = bl; + push(ax); + findPathOfPoint(); + data.byte(kPointerspath) = dl; + ax = pop(); + push(ax); + findFirstPath(); + data.byte(kPointerfirstpath) = al; + ax = pop(); + + byte x = al; + byte y = ah; + + if (checkIfEx(x, y) || checkIfFree(x, y) || + checkIfPerson(x, y) || checkIfSet(x, y)) + return; // finishidentify + + x = (data.word(kMousex) - data.word(kMapadx)) & 0xFF; + y = (data.word(kMousey) - data.word(kMapady)) & 0xFF; + byte flag, flagEx, type, flagX, flagY; + + checkOne(x, y, &flag, &flagEx, &type, &flagX, &flagY); + + if (type != 0 && data.byte(kMandead) != 1) + obName(type, 3); + else + blank(); +} + +uint16 DreamGenContext::findInvPosCPP() { + uint16 x = data.word(kMousex) - kInventx; + uint16 y = data.word(kMousey) - kInventy; + uint16 pos = (x / kItempicsize) + (y / kItempicsize) * 5; + uint16 invPos = data.byte(kRyanpage) * 10 + pos; + data.byte(kLastinvpos) = invPos & 0xFF; + return invPos * 2 + kRyaninvlist; +} + +void DreamGenContext::findInvPos() { + bx = findInvPosCPP(); + es = data.word(kBuffers); +} + +void DreamGenContext::selectOb() { + es = data.word(kBuffers); + + uint16 objectId = es.word(findInvPosCPP()); + if ((objectId & 0xFF) == 255) { + blank(); + return; + } + + data.byte(kWithobject) = objectId & 0x00FF; + data.byte(kWithtype) = objectId >> 8; + + if (objectId == data.word(kOldsubject)) { + if (data.byte(kCommandtype) == 221) { + // Object already selected + if (data.word(kMousebutton) != data.word(kOldbutton) && (data.word(kMousebutton) & 1)) { + delPointer(); + data.byte(kInvopen) = 0; + useRoutine(); + } + return; + } else { + data.byte(kCommandtype) = 221; + } + } + + data.word(kOldsubject) = objectId; + commandWithOb(0, data.byte(kWithtype), data.byte(kWithobject)); + + if (data.word(kMousebutton) != data.word(kOldbutton) && (data.word(kMousebutton) & 1)) { + delPointer(); + data.byte(kInvopen) = 0; + useRoutine(); + } +} + +void DreamGenContext::setPickup() { + if (data.byte(kObjecttype) != kSetObjectType1 && data.byte(kObjecttype) != kSetObjectType3) { + // The original called getAnyAd() here. However, since object types + // 1 and 3 are excluded, the resulting object is a DynObject + uint8 dummy; + DynObject *object = (DynObject *)getAnyAd(&dummy, &dummy); + if (object->mapad[0] == 4) { + blank(); + return; + } + } else { + blank(); + return; + } + + if (data.byte(kCommandtype) != 209) { + data.byte(kCommandtype) = 209; + commandWithOb(33, data.byte(kObjecttype), data.byte(kCommand)); + } + + if (data.word(kMousebutton) != 1 || data.word(kMousebutton) == data.word(kOldbutton)) + return; + + createPanel(); + showPanel(); + showMan(); + showExit(); + examIcon(); + data.byte(kPickup) = 1; + data.byte(kInvopen) = 2; + + if (data.byte(kObjecttype) != kExObjectType) { + data.byte(kItemframe) = data.byte(kCommand); + data.byte(kOpenedob) = 255; + transferToEx(); + data.byte(kItemframe) = al; + data.byte(kObjecttype) = kExObjectType; + DynObject *object = getExAd(data.byte(kItemframe)); + object->mapad[0] = 20; + object->mapad[1] = 255; + } else { + data.byte(kItemframe) = data.byte(kCommand); + data.byte(kOpenedob) = 255; + } + + openInv(); + workToScreenM(); +} + +void DreamGenContext::deleteExFrame() { + deleteExFrame(al); +} + +void DreamBase::deleteExFrame(uint8 frameNum) { + Frame *frame = (Frame *)getSegment(data.word(kExtras)).ptr(kExframedata + sizeof(Frame)*frameNum, sizeof(Frame)); + + uint16 frameSize = frame->width * frame->height; + // Note: the original asm didn't subtract frameSize from remainder + uint16 remainder = kExframeslen - frame->ptr() - frameSize; + uint16 startOff = kExframes + frame->ptr(); + uint16 endOff = startOff + frameSize; + + // Shift frame data after this one down + memmove(getSegment(data.word(kExtras)).ptr(startOff, remainder), getSegment(data.word(kExtras)).ptr(endOff, remainder), remainder); + + // Combined frame data is now frameSize smaller + data.word(kExframepos) -= frameSize; + + // Adjust all frame pointers pointing into the shifted data + for (unsigned int i = 0; i < 3*kNumexobjects; ++i) { + frame = (Frame *)getSegment(data.word(kExtras)).ptr(kExframedata + sizeof(Frame)*i, sizeof(Frame)); + if (frame->ptr() >= startOff) + frame->setPtr(frame->ptr() - frameSize); + } +} + +void DreamGenContext::deleteExText() { + deleteExText(al); +} + +void DreamBase::deleteExText(uint8 textNum) { + uint16 offset = getSegment(data.word(kExtras)).word(kExtextdat + 2*textNum); + + uint16 startOff = kExtext + offset; + uint16 textSize = strlen((char *)getSegment(data.word(kExtras)).ptr(startOff, 0)) + 1; + uint16 endOff = startOff + textSize; + uint16 remainder = kExtextlen - offset - textSize; + + // Shift text data after this one down + memmove(getSegment(data.word(kExtras)).ptr(startOff, remainder), getSegment(data.word(kExtras)).ptr(endOff, remainder), remainder); + + // Combined text data is now frameSize smaller + data.word(kExtextpos) -= textSize; + + // Adjust all text pointers pointing into the shifted data + for (unsigned int i = 0; i < kNumexobjects; ++i) { + uint16 t = getSegment(data.word(kExtras)).word(kExtextdat + 2*i); + if (t >= offset + textSize) + getSegment(data.word(kExtras)).word(kExtextdat + 2*i) = t - textSize; + } +} + +// This takes es:di and cl as input, but es:di always points to getExAd(cl) +void DreamGenContext::deleteExObject() { + deleteExObject(cl); +} + +void DreamBase::deleteExObject(uint8 index) { + DynObject *obj = getExAd(index); + + memset(obj, 0xFF, sizeof(DynObject)); + + deleteExFrame(3*index); + deleteExFrame(3*index + 1); + + deleteExText(index); + + for (uint8 i = 0; i < kNumexobjects; ++i) { + DynObject *t = getExAd(index); + // Is this object contained in the one we've just deleted? + if (t->mapad[0] == 4 && t->mapad[1] == index) + deleteExObject(i); + } +} + +void DreamBase::removeObFromInv() { + if (data.byte(kCommand) == 100) + return; // object doesn't exit + + assert(data.byte(kObjecttype) == kExObjectType); + + deleteExObject(data.byte(kCommand)); +} + +void DreamGenContext::inToInv() { + if (!data.byte(kPickup)) { + outOfInv(); + return; + } + + findInvPos(); + ax = es.word(bx); + + if (al != 255) { + swapWithInv(); + return; + } + + al = data.byte(kItemframe); + ah = data.byte(kObjecttype); + + if (ax == data.word(kOldsubject) && data.byte(kCommandtype) != 220) + data.byte(kCommandtype) = 220; + + data.word(kOldsubject) = ax; + commandWithOb(35, data.byte(kObjecttype), data.byte(kItemframe)); + + if (data.word(kMousebutton) == data.word(kOldbutton) || !(data.word(kMousebutton) & 1)) + return; // notletgo2 + + delPointer(); + DynObject *object = getExAd(data.byte(kItemframe)); + object->mapad[0] = 4; + object->mapad[1] = 255; + object->mapad[2] = data.byte(kLastinvpos); + data.byte(kPickup) = 0; + fillRyan(); + readMouse(); + showPointer(); + outOfInv(); + workToScreen(); + delPointer(); +} + +void DreamGenContext::outOfInv() { + findInvPos(); + ax = es.word(bx); + + if (al == 255) { + blank(); + return; + } + + if (data.word(kMousebutton) == 2) { + reExFromInv(); + return; + } + + if (ax == data.word(kOldsubject) && data.byte(kCommandtype) != 221) + data.byte(kCommandtype) = 221; + + data.word(kOldsubject) = ax; + commandWithOb(36, ah, al); + + if (data.word(kMousebutton) == data.word(kOldbutton)) + return; // notletgo + + if (!(data.word(kMousebutton) & 1)) + return; + + delPointer(); + data.byte(kPickup) = 1; + findInvPos(); + ax = es.word(bx); + data.byte(kItemframe) = al; + data.byte(kObjecttype) = ah; + DynObject *object = getExAd(data.byte(kItemframe)); + object->mapad[0] = 20; + object->mapad[1] = 255; + fillRyan(); + readMouse(); + showPointer(); + inToInv(); + workToScreen(); + delPointer(); +} + } // End of namespace DreamGen diff --git a/engines/dreamweb/pathfind.cpp b/engines/dreamweb/pathfind.cpp index ff2659c235..8d9d9a95bb 100644 --- a/engines/dreamweb/pathfind.cpp +++ b/engines/dreamweb/pathfind.cpp @@ -24,11 +24,7 @@ namespace DreamGen { -void DreamGenContext::turnPathOn() { - turnPathOn(al); -} - -void DreamGenContext::turnPathOn(uint8 param) { +void DreamBase::turnPathOn(uint8 param) { findOrMake(param, 0xff, data.byte(kRoomnum) + 100); PathNode *roomsPaths = getRoomsPaths()->nodes; if (param == 0xff) @@ -36,11 +32,7 @@ void DreamGenContext::turnPathOn(uint8 param) { roomsPaths[param].on = 0xff; } -void DreamGenContext::turnPathOff() { - turnPathOff(al); -} - -void DreamGenContext::turnPathOff(uint8 param) { +void DreamBase::turnPathOff(uint8 param) { findOrMake(param, 0x00, data.byte(kRoomnum) + 100); PathNode *roomsPaths = getRoomsPaths()->nodes; if (param == 0xff) @@ -48,32 +40,31 @@ void DreamGenContext::turnPathOff(uint8 param) { roomsPaths[param].on = 0x00; } -void DreamGenContext::turnAnyPathOn(uint8 param, uint8 room) { +void DreamBase::turnAnyPathOn(uint8 param, uint8 room) { findOrMake(param, 0xff, room + 100); PathNode *paths = (PathNode *)getSegment(data.word(kReels)).ptr(kPathdata + 144 * room, 0); paths[param].on = 0xff; } -void DreamGenContext::turnAnyPathOn() { - turnAnyPathOn(al, ah); -} - -void DreamGenContext::turnAnyPathOff(uint8 param, uint8 room) { +void DreamBase::turnAnyPathOff(uint8 param, uint8 room) { findOrMake(param, 0x00, room + 100); PathNode *paths = (PathNode *)getSegment(data.word(kReels)).ptr(kPathdata + 144 * room, 0); paths[param].on = 0x00; } -void DreamGenContext::turnAnyPathOff() { - turnAnyPathOff(al, ah); -} - -RoomPaths *DreamGenContext::getRoomsPaths() { +RoomPaths *DreamBase::getRoomsPaths() { void *result = getSegment(data.word(kReels)).ptr(data.byte(kRoomnum) * 144, 144); return (RoomPaths *)result; } -void DreamGenContext::setWalk() { +void DreamBase::faceRightWay() { + PathNode *paths = getRoomsPaths()->nodes; + uint8 dir = paths[data.byte(kManspath)].dir; + data.byte(kTurntoface) = dir; + data.byte(kLeavedirection) = dir; +} + +void DreamBase::setWalk() { if (data.byte(kLinepointer) != 254) { // Already walking data.byte(kFinaldest) = data.byte(kPointerspath); @@ -100,7 +91,7 @@ void DreamGenContext::setWalk() { } } -void DreamGenContext::autoSetWalk() { +void DreamBase::autoSetWalk() { if (data.byte(kFinaldest) == data.byte(kManspath)) return; const RoomPaths *roomsPaths = getRoomsPaths(); @@ -137,23 +128,19 @@ void DreamBase::checkDest(const RoomPaths *roomsPaths) { data.byte(kDestination) = destination; } -void DreamGenContext::findXYFromPath() { +void DreamBase::findXYFromPath() { const PathNode *roomsPaths = getRoomsPaths()->nodes; data.byte(kRyanx) = roomsPaths[data.byte(kManspath)].x - 12; data.byte(kRyany) = roomsPaths[data.byte(kManspath)].y - 12; } -void DreamGenContext::checkIfPathIsOn() { - flags._z = checkIfPathIsOn(al); -} - -bool DreamGenContext::checkIfPathIsOn(uint8 index) { +bool DreamBase::checkIfPathIsOn(uint8 index) { RoomPaths *roomsPaths = getRoomsPaths(); uint8 pathOn = roomsPaths->nodes[index].on; return pathOn == 0xff; } -void DreamGenContext::bresenhams() { +void DreamBase::bresenhams() { workoutFrames(); Common::Point *lineData = &_lineData[0]; int16 startX = (int16)data.word(kLinestartx); @@ -223,33 +210,35 @@ void DreamGenContext::bresenhams() { } uint16 delta1, delta2; + byte lineRoutine; + if (deltaY > deltaX) { - data.byte(kLineroutine) = 1; + lineRoutine = 1; delta1 = deltaY; delta2 = deltaX; } else { - data.byte(kLineroutine) = 0; + lineRoutine = 0; delta1 = deltaX; delta2 = deltaY; } - data.word(kIncrement1) = delta2 * 2; + uint16 increment1 = delta2 * 2; + uint16 increment2 = delta2 * 2 - delta1 * 2; int16 remainder = delta2 * 2 - delta1; - data.word(kIncrement2) = delta2 * 2 - delta1 * 2; ++delta1; int8 x = (int8)startX; int8 y = (int8)startY; data.byte(kLinelength) = delta1; - if (data.byte(kLineroutine) != 1) { + if (lineRoutine != 1) { for (; delta1; --delta1) { lineData->x = x; lineData->y = y; ++lineData; ++x; if (remainder < 0) { - remainder += data.word(kIncrement1); + remainder += increment1; } else { - remainder += data.word(kIncrement2); + remainder += increment2; y += increment; } } @@ -260,13 +249,64 @@ void DreamGenContext::bresenhams() { ++lineData; y += increment; if (remainder < 0) { - remainder += data.word(kIncrement1); + remainder += increment1; } else { - remainder += data.word(kIncrement2); + remainder += increment2; ++x; } } } } +void DreamBase::workoutFrames() { + byte tmp; + int diffx, diffy; + + // We have to use signed arithmetic here because these values can + // be slightly negative when walking off-screen + int lineStartX = (int16)data.word(kLinestartx); + int lineStartY = (int16)data.word(kLinestarty); + int lineEndX = (int16)data.word(kLineendx); + int lineEndY = (int16)data.word(kLineendy); + + + diffx = ABS(lineStartX - lineEndX); + diffy = ABS(lineStartY - lineEndY); + + if (diffx < diffy) { + tmp = 2; + if (diffx >= (diffy >> 1)) + tmp = 1; + } else { + // tendstohoriz + tmp = 0; + if (diffy >= (diffx >> 1)) + tmp = 1; + } + + if (lineStartX >= lineEndX) { + // isinleft + if (lineStartY < lineEndY) { + if (tmp != 1) + tmp ^= 2; + tmp += 4; + } else { + // topleft + tmp += 6; + } + } else { + // isinright + if (lineStartY < lineEndY) { + tmp += 2; + } else { + // botright + if (tmp != 1) + tmp ^= 2; + } + } + + data.byte(kTurntoface) = tmp & 7; + data.byte(kTurndirection) = 0; +} + } // End of namespace DreamGen diff --git a/engines/dreamweb/people.cpp b/engines/dreamweb/people.cpp index 403f8f1912..4d66134e96 100644 --- a/engines/dreamweb/people.cpp +++ b/engines/dreamweb/people.cpp @@ -24,118 +24,146 @@ namespace DreamGen { -static void (DreamGenContext::*reelCallbacks[57])() = { - NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL, NULL, - &DreamGenContext::receptionist, NULL, - NULL, NULL, - NULL, &DreamGenContext::soldier1, - NULL, NULL, - &DreamGenContext::heavy, NULL, - NULL, NULL, - &DreamGenContext::bartender, NULL, - NULL, NULL, - NULL, NULL, - NULL, NULL, - &DreamGenContext::copper, &DreamGenContext::poolGuard, - NULL, &DreamGenContext::businessMan, - NULL, NULL, - &DreamGenContext::mugger, &DreamGenContext::helicopter, - NULL, NULL, - NULL, NULL, - NULL, NULL, - &DreamGenContext::introMonks1, NULL, - &DreamGenContext::introMonks2, NULL, - NULL, &DreamGenContext::endGameSeq, - NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL +static void (DreamBase::*reelCallbacks[57])(ReelRoutine &) = { + &DreamBase::gamer, &DreamBase::sparkyDrip, + &DreamBase::eden, &DreamBase::edenInBath, + &DreamBase::sparky, &DreamBase::smokeBloke, + &DreamBase::manAsleep, &DreamBase::drunk, + &DreamBase::receptionist, &DreamBase::genericPerson /*maleFan*/, + &DreamBase::genericPerson /*femaleFan*/, &DreamBase::louis, + &DreamBase::louisChair, &DreamBase::soldier1, + &DreamBase::bossMan, &DreamBase::interviewer, + &DreamBase::heavy, &DreamBase::manAsleep /*manAsleep2*/, + &DreamBase::genericPerson /*manSatStill*/, &DreamBase::drinker, + &DreamBase::bartender, &DreamBase::genericPerson /*otherSmoker*/, + &DreamBase::genericPerson /*tattooMan*/, &DreamBase::attendant, + &DreamBase::keeper, &DreamBase::candles1, + &DreamBase::smallCandle, &DreamBase::security, + &DreamBase::copper, &DreamBase::poolGuard, + &DreamBase::rockstar, &DreamBase::businessMan, + &DreamBase::train, &DreamBase::genericPerson /*aide*/, + &DreamBase::mugger, &DreamBase::helicopter, + &DreamBase::introMagic1, &DreamBase::introMusic, + &DreamBase::introMagic2, &DreamBase::candles2, + &DreamBase::gates, &DreamBase::introMagic3, + &DreamBase::introMonks1, &DreamBase::candles, + &DreamBase::introMonks2, &DreamBase::handClap, + &DreamBase::monkAndRyan, &DreamBase::endGameSeq, + &DreamBase::priest, &DreamBase::madman, + &DreamBase::madmansTelly, &DreamBase::alleyBarkSound, + &DreamBase::foghornSound, &DreamBase::carParkDrip, + &DreamBase::carParkDrip, &DreamBase::carParkDrip, + &DreamBase::carParkDrip }; -static void (DreamGenContext::*reelCallbacksCPP[57])(ReelRoutine &) = { - &DreamGenContext::gamer, &DreamGenContext::sparkyDrip, - &DreamGenContext::eden, &DreamGenContext::edenInBath, - &DreamGenContext::sparky, &DreamGenContext::smokeBloke, - &DreamGenContext::manAsleep, &DreamGenContext::drunk, - /*&DreamGenContext::receptionist*/NULL, &DreamGenContext::genericPerson /*maleFan*/, - &DreamGenContext::genericPerson /*femaleFan*/, &DreamGenContext::louis, - &DreamGenContext::louisChair, /*&DreamGenContext::soldier1*/NULL, - &DreamGenContext::bossMan, &DreamGenContext::interviewer, - /*&DreamGenContext::heavy*/NULL, &DreamGenContext::manAsleep /*manAsleep2*/, - &DreamGenContext::genericPerson /*manSatStill*/, &DreamGenContext::drinker, - /*&DreamGenContext::bartender*/NULL, &DreamGenContext::genericPerson /*otherSmoker*/, - &DreamGenContext::genericPerson /*tattooMan*/, &DreamGenContext::attendant, - &DreamGenContext::keeper, &DreamGenContext::candles1, - &DreamGenContext::smallCandle, &DreamGenContext::security, - /*&DreamGenContext::copper*/NULL, /*&DreamGenContext::poolGuard*/NULL, - &DreamGenContext::rockstar, /*&DreamGenContext::businessMan*/NULL, - &DreamGenContext::train, &DreamGenContext::genericPerson /*aide*/, - /*&DreamGenContext::mugger*/NULL, /*&DreamGenContext::helicopter*/NULL, - &DreamGenContext::introMagic1, &DreamGenContext::introMusic, - &DreamGenContext::introMagic2, &DreamGenContext::candles2, - &DreamGenContext::gates, &DreamGenContext::introMagic3, - /*&DreamGenContext::intromonks1*/NULL, &DreamGenContext::candles, - /*&DreamGenContext::intromonks2*/NULL, &DreamGenContext::handClap, - &DreamGenContext::monkAndRyan, /*&DreamGenContext::endGameSeq*/NULL, - &DreamGenContext::priest, &DreamGenContext::madman, - &DreamGenContext::madmansTelly, &DreamGenContext::alleyBarkSound, - &DreamGenContext::foghornSound, &DreamGenContext::carParkDrip, - &DreamGenContext::carParkDrip, &DreamGenContext::carParkDrip, - &DreamGenContext::carParkDrip +static const ReelRoutine g_initialReelRoutines[] = { +// Room number and x,y +// reel pointer +// speed,speed count,convers. no. + { 1,44,0, 20, 2,0,1 }, + { 1,55,0, 0, 50,20,0 }, + { 24,22,0, 74, 1,0,0 }, + { 24,33,10, 75, 1,0,1 }, + { 1,44,0, 27, 2,0,2 }, + { 1,44,0, 96, 3,0,4 }, + { 1,44,0, 118, 2,0,5 }, + { 1,44,10, 0, 2,0,0 }, + { 5,22,20, 53, 3,0,0 }, + { 5,22,20, 40, 1,0,2 }, + { 5,22,20, 50, 1,0,3 }, + { 2,11,10, 192, 1,0,0 }, + { 2,11,10, 182, 2,0,1 }, + { 8,11,10, 0, 2,0,1 }, + { 23,0,50, 0, 3,0,0 }, + { 28,11,20, 250, 4,0,0 }, + { 23,0,50, 43, 2,0,8 }, + { 23,11,40, 130, 2,0,1 }, + { 23,22,40, 122, 2,0,2 }, + { 23,22,40, 105, 2,0,3 }, + { 23,22,40, 81, 2,0,4 }, + { 23,11,40, 135, 2,0,5 }, + { 23,22,40, 145, 2,0,6 }, + { 4,22,30, 0, 2,0,0 }, + { 45,22,30, 200, 0,0,20 }, + { 45,22,30, 39, 2,0,0 }, + { 45,22,30, 25, 2,0,0 }, + { 8,22,40, 32, 2,0,0 }, + { 7,11,20, 64, 2,0,0 }, + { 22,22,20, 82, 2,0,0 }, + { 27,11,30, 0, 2,0,0 }, + { 20,0,30, 0, 2,0,0 }, + { 14,33,40, 21, 1,0,0 }, + { 29,11,10, 0, 1,0,0 }, + { 2,22,0, 2, 2,0,0 }, + { 25,0,50, 4, 2,0,0 }, + { 50,22,30, 121, 2,0,0 }, + { 50,22,30, 0, 20,0,0 }, + { 52,22,30, 192, 2,0,0 }, + { 52,22,30, 233, 2,0,0 }, + { 50,22,40, 104, 55,0,0 }, // ...., 65,0,0 for German CD + { 53,33,0, 99, 2,0,0 }, + { 50,22,40, 0, 3,0,0 }, + { 50,22,30, 162, 2,0,0 }, + { 52,22,30, 57, 2,0,0 }, + { 52,22,30, 0, 2,0,0 }, + { 54,0,0, 72, 3,0,0 }, + { 55,44,0, 0, 2,0,0 }, + { 19,0,0, 0, 28,0,0 }, + { 14,22,0, 2, 2,0,0 }, + { 14,22,0, 300, 1,0,0 }, + { 10,22,30, 174, 0,0,0 }, + { 12,22,20, 0, 1,0,0 }, + { 11,11,20, 0, 50,20,0 }, + { 11,11,30, 0, 50,20,0 }, + { 11,22,20, 0, 50,20,0 }, + { 14,33,40, 0, 50,20,0 }, + { 255,0,0, 0, 0,0,0 } }; -void DreamGenContext::updatePeople() { +void DreamBase::setupInitialReelRoutines() { + for (unsigned int i = 0; i < kNumReelRoutines + 1; ++i) { + _reelRoutines[i] = g_initialReelRoutines[i]; + if (_reelRoutines[i].period == 55 && isCD() && engine->getLanguage() == Common::DE_DEU) + _reelRoutines[i].period = 65; + } +} + +void DreamBase::updatePeople() { data.word(kListpos) = kPeoplelist; memset(getSegment(data.word(kBuffers)).ptr(kPeoplelist, 12 * sizeof(People)), 0xff, 12 * sizeof(People)); ++data.word(kMaintimer); - // The original callbacks are called with es:bx pointing to their reelRoutine entry. - // The new callbacks take a mutable ReelRoutine parameter. - - es = data; - ReelRoutine *r = (ReelRoutine *)data.ptr(kReelroutines, 0); - - for (int i = 0; r[i].reallocation != 255; ++i) { - bx = kReelroutines + 8*i; - if (r[i].reallocation == data.byte(kReallocation) && - r[i].mapX == data.byte(kMapx) && - r[i].mapY == data.byte(kMapy)) { - if (reelCallbacks[i]) { - assert(!reelCallbacksCPP[i]); - (this->*(reelCallbacks[i]))(); - } else { - assert(reelCallbacksCPP[i]); - (this->*(reelCallbacksCPP[i]))(r[i]); - } + for (int i = 0; _reelRoutines[i].reallocation != 255; ++i) { + if (_reelRoutines[i].reallocation == data.byte(kReallocation) && + _reelRoutines[i].mapX == data.byte(kMapx) && + _reelRoutines[i].mapY == data.byte(kMapy)) { + assert(reelCallbacks[i]); + (this->*(reelCallbacks[i]))(_reelRoutines[i]); } } } -void DreamGenContext::madmanText() { +void DreamBase::madmanText() { + byte origCount; + if (isCD()) { if (data.byte(kSpeechcount) >= 63) return; if (data.byte(kCh1playing) != 255) return; - al = data.byte(kSpeechcount); + origCount = data.byte(kSpeechcount); ++data.byte(kSpeechcount); } else { if (data.byte(kCombatcount) >= 61) return; - al = data.byte(kCombatcount); - _and(al, 3); - if (!flags.z()) + if (data.byte(kCombatcount) & 3) return; - al = data.byte(kCombatcount) / 4; + origCount = data.byte(kCombatcount) / 4; } - setupTimedTemp(47 + al, 82, 72, 80, 90, 1); + setupTimedTemp(47 + origCount, 82, 72, 80, 90, 1); } -void DreamGenContext::madman(ReelRoutine &routine) { +void DreamBase::madman(ReelRoutine &routine) { data.word(kWatchingtime) = 2; if (checkSpeed(routine)) { uint16 newReelPointer = routine.reelPointer(); @@ -181,7 +209,7 @@ void DreamGenContext::madman(ReelRoutine &routine) { madMode(); } -void DreamGenContext::madMode() { +void DreamBase::madMode() { data.word(kWatchingtime) = 2; data.byte(kPointermode) = 0; if (data.byte(kCombatcount) < (isCD() ? 65 : 63)) @@ -191,11 +219,7 @@ void DreamGenContext::madMode() { data.byte(kPointermode) = 2; } -void DreamGenContext::addToPeopleList() { - addToPeopleList((ReelRoutine *)es.ptr(bx, sizeof(ReelRoutine))); -} - -void DreamGenContext::addToPeopleList(ReelRoutine *routine) { +void DreamBase::addToPeopleList(ReelRoutine *routine) { uint16 routinePointer = (const uint8 *)routine - data.ptr(0, 0); People *people = (People *)getSegment(data.word(kBuffers)).ptr(data.word(kListpos), sizeof(People)); @@ -205,12 +229,7 @@ void DreamGenContext::addToPeopleList(ReelRoutine *routine) { data.word(kListpos) += sizeof(People); } -void DreamGenContext::checkSpeed() { - ReelRoutine *routine = (ReelRoutine *)es.ptr(bx, sizeof(ReelRoutine)); - flags._z = checkSpeed(*routine); -} - -bool DreamGenContext::checkSpeed(ReelRoutine &routine) { +bool DreamBase::checkSpeed(ReelRoutine &routine) { if (data.byte(kLastweapon) != (uint8)-1) return true; ++routine.counter; @@ -220,17 +239,17 @@ bool DreamGenContext::checkSpeed(ReelRoutine &routine) { return true; } -void DreamGenContext::sparkyDrip(ReelRoutine &routine) { +void DreamBase::sparkyDrip(ReelRoutine &routine) { if (checkSpeed(routine)) playChannel0(14, 0); } -void DreamGenContext::genericPerson(ReelRoutine &routine) { +void DreamBase::genericPerson(ReelRoutine &routine) { showGameReel(&routine); addToPeopleList(&routine); } -void DreamGenContext::gamer(ReelRoutine &routine) { +void DreamBase::gamer(ReelRoutine &routine) { if (checkSpeed(routine)) { uint8 v; do { @@ -243,14 +262,14 @@ void DreamGenContext::gamer(ReelRoutine &routine) { addToPeopleList(&routine); } -void DreamGenContext::eden(ReelRoutine &routine) { +void DreamBase::eden(ReelRoutine &routine) { if (data.byte(kGeneraldead)) return; showGameReel(&routine); addToPeopleList(&routine); } -void DreamGenContext::sparky(ReelRoutine &routine) { +void DreamBase::sparky(ReelRoutine &routine) { if (data.word(kCard1money)) routine.b7 = 3; if (checkSpeed(routine)) { @@ -272,7 +291,7 @@ void DreamGenContext::sparky(ReelRoutine &routine) { data.byte(kTalkedtosparky) = 1; } -void DreamGenContext::rockstar(ReelRoutine &routine) { +void DreamBase::rockstar(ReelRoutine &routine) { if ((routine.reelPointer() == 303) || (routine.reelPointer() == 118)) { data.byte(kNewlocation) = 45; showGameReel(&routine); @@ -309,7 +328,7 @@ void DreamGenContext::rockstar(ReelRoutine &routine) { } } -void DreamGenContext::madmansTelly(ReelRoutine &routine) { +void DreamBase::madmansTelly(ReelRoutine &routine) { uint16 nextReelPointer = routine.reelPointer() + 1; if (nextReelPointer == 307) nextReelPointer = 300; @@ -318,10 +337,10 @@ void DreamGenContext::madmansTelly(ReelRoutine &routine) { } -void DreamGenContext::smokeBloke(ReelRoutine &routine) { +void DreamBase::smokeBloke(ReelRoutine &routine) { if (data.byte(kRockstardead) == 0) { if (routine.b7 & 128) - setLocation(5); + DreamBase::setLocation(5); } if (checkSpeed(routine)) { if (routine.reelPointer() == 100) { @@ -338,20 +357,20 @@ void DreamGenContext::smokeBloke(ReelRoutine &routine) { addToPeopleList(&routine); } -void DreamGenContext::manAsleep(ReelRoutine &routine) { +void DreamBase::manAsleep(ReelRoutine &routine) { routine.b7 &= 127; showGameReel(&routine); addToPeopleList(&routine); } -void DreamGenContext::attendant(ReelRoutine &routine) { +void DreamBase::attendant(ReelRoutine &routine) { showGameReel(&routine); addToPeopleList(&routine); if (routine.b7 & 128) data.byte(kTalkedtoattendant) = 1; } -void DreamGenContext::keeper(ReelRoutine &routine) { +void DreamBase::keeper(ReelRoutine &routine) { if (data.byte(kKeeperflag) != 0) { // Not waiting addToPeopleList(&routine); @@ -368,7 +387,7 @@ void DreamGenContext::keeper(ReelRoutine &routine) { routine.b7 = data.byte(kDreamnumber); } -void DreamGenContext::drunk(ReelRoutine &routine) { +void DreamBase::drunk(ReelRoutine &routine) { if (data.byte(kGeneraldead)) return; routine.b7 &= 127; @@ -376,7 +395,7 @@ void DreamGenContext::drunk(ReelRoutine &routine) { addToPeopleList(&routine); } -void DreamGenContext::interviewer(ReelRoutine &routine) { +void DreamBase::interviewer(ReelRoutine &routine) { if (data.word(kReeltowatch) == 68) routine.incReelPointer(); @@ -386,7 +405,7 @@ void DreamGenContext::interviewer(ReelRoutine &routine) { showGameReel(&routine); } -void DreamGenContext::drinker(ReelRoutine &routine) { +void DreamBase::drinker(ReelRoutine &routine) { if (checkSpeed(routine)) { routine.incReelPointer(); @@ -399,7 +418,7 @@ void DreamGenContext::drinker(ReelRoutine &routine) { addToPeopleList(&routine); } -void DreamGenContext::alleyBarkSound(ReelRoutine &routine) { +void DreamBase::alleyBarkSound(ReelRoutine &routine) { uint16 prevReelPointer = routine.reelPointer() - 1; if (prevReelPointer == 0) { playChannel1(14); @@ -409,7 +428,7 @@ void DreamGenContext::alleyBarkSound(ReelRoutine &routine) { } } -void DreamGenContext::introMagic1(ReelRoutine &routine) { +void DreamBase::introMagic1(ReelRoutine &routine) { if (checkSpeed(routine)) { uint16 nextReelPointer = routine.reelPointer() + 1; if (nextReelPointer == 145) @@ -417,11 +436,7 @@ void DreamGenContext::introMagic1(ReelRoutine &routine) { routine.setReelPointer(nextReelPointer); if (nextReelPointer == 121) { ++data.byte(kIntrocount); - push(es); - push(bx); intro1Text(); - bx = pop(); - es = pop(); if (data.byte(kIntrocount) == 8) { data.byte(kMapy) += 10; data.byte(kNowinnewroom) = 1; @@ -431,7 +446,7 @@ void DreamGenContext::introMagic1(ReelRoutine &routine) { showGameReel(&routine); } -void DreamGenContext::introMagic2(ReelRoutine &routine) { +void DreamBase::introMagic2(ReelRoutine &routine) { if (checkSpeed(routine)) { uint16 nextReelPointer = routine.reelPointer() + 1; if (nextReelPointer == 216) @@ -441,7 +456,7 @@ void DreamGenContext::introMagic2(ReelRoutine &routine) { showGameReel(&routine); } -void DreamGenContext::introMagic3(ReelRoutine &routine) { +void DreamBase::introMagic3(ReelRoutine &routine) { if (checkSpeed(routine)) { uint16 nextReelPointer = routine.reelPointer() + 1; if (nextReelPointer == 218) @@ -452,7 +467,7 @@ void DreamGenContext::introMagic3(ReelRoutine &routine) { routine.mapX = data.byte(kMapx); } -void DreamGenContext::candles1(ReelRoutine &routine) { +void DreamBase::candles1(ReelRoutine &routine) { if (checkSpeed(routine)) { uint16 nextReelPointer = routine.reelPointer() + 1; if (nextReelPointer == 44) @@ -462,7 +477,7 @@ void DreamGenContext::candles1(ReelRoutine &routine) { showGameReel(&routine); } -void DreamGenContext::candles2(ReelRoutine &routine) { +void DreamBase::candles2(ReelRoutine &routine) { if (checkSpeed(routine)) { uint16 nextReelPointer = routine.reelPointer() + 1; if (nextReelPointer == 238) @@ -472,7 +487,7 @@ void DreamGenContext::candles2(ReelRoutine &routine) { showGameReel(&routine); } -void DreamGenContext::smallCandle(ReelRoutine &routine) { +void DreamBase::smallCandle(ReelRoutine &routine) { if (checkSpeed(routine)) { uint16 nextReelPointer = routine.reelPointer() + 1; if (nextReelPointer == 37) @@ -482,10 +497,10 @@ void DreamGenContext::smallCandle(ReelRoutine &routine) { showGameReel(&routine); } -void DreamGenContext::introMusic(ReelRoutine &routine) { +void DreamBase::introMusic(ReelRoutine &routine) { } -void DreamGenContext::candles(ReelRoutine &routine) { +void DreamBase::candles(ReelRoutine &routine) { if (checkSpeed(routine)) { uint16 nextReelPointer = routine.reelPointer() + 1; if (nextReelPointer == 167) @@ -495,7 +510,7 @@ void DreamGenContext::candles(ReelRoutine &routine) { showGameReel(&routine); } -void DreamGenContext::gates(ReelRoutine &routine) { +void DreamBase::gates(ReelRoutine &routine) { if (checkSpeed(routine)) { uint16 nextReelPointer = routine.reelPointer() + 1; if (nextReelPointer == 116) @@ -507,17 +522,12 @@ void DreamGenContext::gates(ReelRoutine &routine) { nextReelPointer = 119; } routine.setReelPointer(nextReelPointer); - push(es); - push(bx); - ax = nextReelPointer; - intro3Text(); - bx = pop(); - es = pop(); + intro3Text(nextReelPointer); } showGameReel(&routine); } -void DreamGenContext::security(ReelRoutine &routine) { +void DreamBase::security(ReelRoutine &routine) { if (routine.reelPointer() == 32) { if (data.byte(kLastweapon) == 1) { data.word(kWatchingtime) = 10; @@ -537,7 +547,7 @@ void DreamGenContext::security(ReelRoutine &routine) { addToPeopleList(&routine); } -void DreamGenContext::edenInBath(ReelRoutine &routine) { +void DreamBase::edenInBath(ReelRoutine &routine) { if (data.byte(kGeneraldead) == 0 || data.byte(kSartaindead) != 0) return; @@ -545,7 +555,7 @@ void DreamGenContext::edenInBath(ReelRoutine &routine) { addToPeopleList(&routine); } -void DreamGenContext::louis(ReelRoutine &routine) { +void DreamBase::louis(ReelRoutine &routine) { if (data.byte(kRockstardead) != 0) return; @@ -553,25 +563,26 @@ void DreamGenContext::louis(ReelRoutine &routine) { addToPeopleList(&routine); } -void DreamGenContext::handClap(ReelRoutine &routine) { +void DreamBase::handClap(ReelRoutine &routine) { } -void DreamGenContext::carParkDrip(ReelRoutine &routine) { +void DreamBase::carParkDrip(ReelRoutine &routine) { if (!checkSpeed(routine)) return; // cantdrip2 playChannel1(14); } -void DreamGenContext::foghornSound(ReelRoutine &routine) { +void DreamBase::foghornSound(ReelRoutine &routine) { if (engine->randomNumber() == 198) playChannel1(13); } -void DreamGenContext::train(ReelRoutine &routine) { +void DreamBase::train(ReelRoutine &routine) { + // The original code has logic for this, but it is disabled } -void DreamGenContext::louisChair(ReelRoutine &routine) { +void DreamBase::louisChair(ReelRoutine &routine) { if (data.byte(kRockstardead) == 0) return; // notlouis2 @@ -593,7 +604,7 @@ void DreamGenContext::louisChair(ReelRoutine &routine) { addToPeopleList(&routine); } -void DreamGenContext::bossMan(ReelRoutine &routine) { +void DreamBase::bossMan(ReelRoutine &routine) { if (checkSpeed(routine)) { uint16 nextReelPointer = routine.reelPointer() + 1; @@ -619,7 +630,7 @@ void DreamGenContext::bossMan(ReelRoutine &routine) { data.byte(kTalkedtoboss) = 1; } -void DreamGenContext::priest(ReelRoutine &routine) { +void DreamBase::priest(ReelRoutine &routine) { if (routine.reelPointer() == 8) return; // priestspoken @@ -628,28 +639,19 @@ void DreamGenContext::priest(ReelRoutine &routine) { if (checkSpeed(routine)) { routine.incReelPointer(); - push(es); - push(bx); priestText(routine); - bx = pop(); - es = pop(); } } -void DreamGenContext::priestText(ReelRoutine &routine) { +void DreamBase::priestText(ReelRoutine &routine) { uint16 reel = routine.reelPointer(); if (reel < 2 || reel >= 7 || (reel & 1)) return; // nopriesttext - al = ((reel & 0xFF) >> 1) + 50; - bl = 72; - bh = 80; - cx = 54; - dx = 1; - setupTimedUse(); + setupTimedUse((reel >> 1) + 50, 54, 1, 72, 80); } -void DreamGenContext::monkAndRyan(ReelRoutine &routine) { +void DreamBase::monkAndRyan(ReelRoutine &routine) { if (checkSpeed(routine)) { uint16 nextReelPointer = routine.reelPointer() + 1; if (nextReelPointer == 83) { @@ -669,4 +671,443 @@ void DreamGenContext::monkAndRyan(ReelRoutine &routine) { showGameReel(&routine); } +void DreamBase::copper(ReelRoutine &routine) { + if (checkSpeed(routine)) { + uint16 nextReelPointer = routine.reelPointer() + 1; + if (nextReelPointer == 94) { + nextReelPointer = 64; + } else if (nextReelPointer == 81 || nextReelPointer == 66) { + // Might wait + if (engine->randomNumber() >= 7) + nextReelPointer--; + } + + routine.setReelPointer(nextReelPointer); + } + + showGameReel(&routine); + addToPeopleList(&routine); +} + +void DreamBase::introMonks1(ReelRoutine &routine) { + if (checkSpeed(routine)) { + uint16 nextReelPointer = routine.reelPointer() + 1; + + if (nextReelPointer == 80) { + data.byte(kMapy) += 10; + data.byte(kNowinnewroom) = 1; + showGameReel(&routine); + return; + } else if (nextReelPointer == 30) { + data.byte(kMapy) -= 10; + data.byte(kNowinnewroom) = 1; + nextReelPointer = 51; + } + + routine.setReelPointer(nextReelPointer); + + if (nextReelPointer == 5 || nextReelPointer == 15 || + nextReelPointer == 25 || nextReelPointer == 61 || + nextReelPointer == 71) { + // Wait step + intro2Text(nextReelPointer); + routine.counter = (uint8)-20; + } + } + + showGameReel(&routine); + routine.mapY = data.byte(kMapy); +} + +void DreamBase::introMonks2(ReelRoutine &routine) { + if (checkSpeed(routine)) { + uint16 nextReelPointer = routine.reelPointer() + 1; + if (nextReelPointer == 87) { + data.byte(kIntrocount)++; + monks2text(); + + if (data.byte(kIntrocount), 19) + nextReelPointer = 87; + else + nextReelPointer = 74; + } + + if (nextReelPointer == 110) { + data.byte(kIntrocount)++; + monks2text(); + + if (data.byte(kIntrocount) == 35) + nextReelPointer = 111; + else + nextReelPointer = 98; + } else if (nextReelPointer == 176) { + data.byte(kGetback) = 1; + } else if (nextReelPointer == 125) { + nextReelPointer = 140; + } + + routine.setReelPointer(nextReelPointer); + } + + showGameReel(&routine); +} + +void DreamBase::soldier1(ReelRoutine &routine) { + if (routine.reelPointer() != 0) { + data.word(kWatchingtime) = 10; + if (routine.reelPointer() == 30) { + data.byte(kCombatcount)++; + if (data.byte(kCombatcount) == 40) + data.byte(kMandead) = 2; + } else if (checkSpeed(routine)) { + // Not after shot + routine.incReelPointer(); + } + } else if (data.byte(kLastweapon) == 1) { + data.word(kWatchingtime) = 10; + if (data.byte(kManspath) == 2 && data.byte(kFacing) == 4) + routine.incReelPointer(); + data.byte(kLastweapon) = 0xFF; + data.byte(kCombatcount) = 0; + } + + showGameReel(&routine); + addToPeopleList(&routine); +} + +void DreamBase::receptionist(ReelRoutine &routine) { + if (checkSpeed(routine)) { + if (data.byte(kCardpassflag) == 1) { + // Set card + data.byte(kCardpassflag)++; + routine.b7 = 1; + routine.setReelPointer(64); + } + + if (routine.reelPointer() != 58) { + // notdes1 + if (routine.reelPointer() != 60) { + // notdes2 + if (routine.reelPointer() != 88) + routine.incReelPointer(); // not end card + else + routine.setReelPointer(53); + } else if (engine->randomNumber() >= 240) { + routine.setReelPointer(53); + } + } else if (engine->randomNumber() >= 30) { + routine.setReelPointer(55); + } else { + // notdes2 + if (routine.reelPointer() != 88) + routine.incReelPointer(); // not end card + else + routine.setReelPointer(53); + } + } + + showGameReel(&routine); + addToPeopleList(&routine); + if (routine.b7 & 128) + data.byte(kTalkedtorecep) = 1; +} + +void DreamBase::bartender(ReelRoutine &routine) { + if (checkSpeed(routine)) { + if (routine.reelPointer() == 86) { + if (engine->randomNumber() >= 18) + routine.setReelPointer(81); + else + routine.incReelPointer(); // notsmoket2 + } else if (routine.reelPointer() == 103) { + routine.setReelPointer(81); // notsmoket1 + } else { + routine.incReelPointer(); // notsmoket2 + } + } + + showGameReel(&routine); + if (data.byte(kGunpassflag) == 1) + routine.b7 = 9; // got gun + + addToPeopleList(&routine); +} + +void DreamBase::heavy(ReelRoutine &routine) { + routine.b7 &= 127; + if (routine.reelPointer() != 43) { + data.word(kWatchingtime) = 10; + if (routine.reelPointer() == 70) { + // After shot + data.byte(kCombatcount)++; + if (data.byte(kCombatcount) == 80) + data.byte(kMandead) = 2; + } else { + if (checkSpeed(routine)) + routine.incReelPointer(); + } + } else if (data.byte(kLastweapon) == 1 && data.byte(kManspath) == 5 && data.byte(kFacing) == 4) { + // Heavy wait + data.byte(kLastweapon) = (byte)-1; + routine.incReelPointer(); + data.byte(kCombatcount) = 0; + } + + showGameReel(&routine); + addToPeopleList(&routine); +} + +void DreamBase::helicopter(ReelRoutine &routine) { + if (routine.reelPointer() == 203) { + // Won helicopter + data.byte(kPointermode) = 0; + return; + } + + if (checkSpeed(routine)) { + uint16 nextReelPointer = routine.reelPointer() + 1; + if (nextReelPointer == 53) { + // Before killing helicopter + data.byte(kCombatcount)++; + if (data.byte(kCombatcount) >= 8) + data.byte(kMandead) = 2; + nextReelPointer = 49; + } else if (nextReelPointer == 9) { + nextReelPointer--; + if (data.byte(kLastweapon) == 1) { + data.byte(kLastweapon) = (byte)-1; + nextReelPointer = 55; + } else { + nextReelPointer = 5; + data.byte(kCombatcount)++; + if (data.byte(kCombatcount) == 20) { + data.byte(kCombatcount) = 0; + nextReelPointer = 9; + } + } + } + + routine.setReelPointer(nextReelPointer); + } + + showGameReel(&routine); + routine.mapX = data.byte(kMapx); + if (routine.reelPointer() < 9 && data.byte(kCombatcount) >= 7) { + data.byte(kPointermode) = 2; + data.word(kWatchingtime) = 0; + } else { + // Not waiting helicopter + data.byte(kPointermode) = 0; + data.word(kWatchingtime) = 2; + } +} + +void DreamBase::mugger(ReelRoutine &routine) { + if (routine.reelPointer() != 138) { + if (routine.reelPointer() == 176) + return; // endmugger2 + + if (routine.reelPointer() == 2) + data.word(kWatchingtime) = 175 * 2; // set watch + + if (checkSpeed(routine)) + routine.incReelPointer(); + + showGameReel(&routine); + routine.mapX = data.byte(kMapx); + } else { + createPanel2(); + showIcon(); + + uint16 offset = kTextstart + getSegment(data.word(kPuzzletext)).word(41 * 2); + const uint8 *string = getSegment(data.word(kPuzzletext)).ptr(offset, 0); + uint16 y = 104; + printDirect(&string, 33 + 20, &y, 241, 241 & 1); + workToScreenCPP(); + hangOn(300); + routine.setReelPointer(140); + data.byte(kManspath) = 2; + data.byte(kFinaldest) = 2; + findXYFromPath(); + data.byte(kResetmanxy) = 1; + data.byte(kCommand) = findExObject("WETA"); + data.byte(kObjecttype) = kExObjectType; + removeObFromInv(); + data.byte(kCommand) = findExObject("WETB"); + data.byte(kObjecttype) = kExObjectType; + removeObFromInv(); + makeMainScreen(); + DreamBase::setupTimedUse(48, 70, 10, 68 - 32, 54 + 64); + data.byte(kBeenmugged) = 1; + } +} + +// Exiting the elevator of Sartain's industries, Sartain (the businessman) and +// two bodyguards are expecting Ryan. +void DreamBase::businessMan(ReelRoutine &routine) { + data.byte(kPointermode) = 0; + data.word(kWatchingtime) = 2; + if (routine.reelPointer() == 2) + DreamBase::setupTimedUse(49, 30, 1, 68, 174); // First + + if (routine.reelPointer() == 95) { + // Businessman combat won - end + data.byte(kPointermode) = 0; + data.word(kWatchingtime) = 0; + return; + } + + if (routine.reelPointer() == 49) + return; // Businessman combat end + + if (checkSpeed(routine)) { + uint16 nextReelPointer = routine.reelPointer() + 1; + if (nextReelPointer == 48) { + data.byte(kMandead) = 2; // before dead body + } else if (nextReelPointer == 15) { + nextReelPointer--; + if (data.byte(kLastweapon) == 3) { + // Shield on bus + data.byte(kLastweapon) = (byte)-1; + data.byte(kCombatcount) = 0; + nextReelPointer = 51; + } else { + // No shield on businessman + data.byte(kCombatcount)++; + if (data.byte(kCombatcount) == 20) { + data.byte(kCombatcount) = 0; + nextReelPointer = 15; + } + } + } else { + // Businessman combat won + if (nextReelPointer == 91) { + turnPathOn(0); + turnPathOn(1); + turnPathOn(2); + turnPathOff(3); + data.byte(kManspath) = 5; + data.byte(kFinaldest) = 5; + findXYFromPath(); + data.byte(kResetmanxy) = 1; + nextReelPointer = 92; + } + } + + routine.setReelPointer(nextReelPointer); + } + + showGameReel(&routine); + routine.mapY = data.byte(kMapy); + if (routine.reelPointer() == 14) { + data.word(kWatchingtime) = 0; + data.byte(kPointermode) = 2; + } +} + +void DreamBase::endGameSeq(ReelRoutine &routine) { + if (checkSpeed(routine)) { + uint16 nextReelPointer = routine.reelPointer() + 1; + if (nextReelPointer == 51 && data.byte(kIntrocount) != 140) { + data.byte(kIntrocount)++; + textForEnd(); + nextReelPointer = 50; + } + + routine.setReelPointer(nextReelPointer); + if (nextReelPointer == 134) { + fadeScreenDownHalf(); + } else if (nextReelPointer == 324) { + fadeScreenDowns(); + data.byte(kVolumeto) = 7; + data.byte(kVolumedirection) = 1; + } + + if (nextReelPointer == 340) + data.byte(kGetback) = 1; + } + + showGameReel(&routine); + routine.mapY = data.byte(kMapy); + + if (routine.reelPointer() == 145) { + routine.setReelPointer(146); + rollEndCredits(); + } +} + +void DreamBase::poolGuard(ReelRoutine &routine) { + if (routine.reelPointer() == 214 || routine.reelPointer() == 258) { + // Combat over 2 + showGameReel(&routine); + data.word(kWatchingtime) = 2; + data.byte(kPointermode) = 0; + data.byte(kCombatcount)++; + if (data.byte(kCombatcount) < 100) + return; // doneover2 + data.word(kWatchingtime) = 0; + data.byte(kMandead) = 2; + return; + } else if (routine.reelPointer() == 185) { + // Combat over 1 + data.word(kWatchingtime) = 0; + data.byte(kPointermode) = 0; + turnPathOn(0); + turnPathOff(1); + return; + } + + if (routine.reelPointer() == 0) + turnPathOn(0); // first pool + + if (checkSpeed(routine)) { + uint16 nextReelPointer = routine.reelPointer() + 1; + + if (nextReelPointer != 122) { + // Not end guard 1 + if (nextReelPointer == 147) { + nextReelPointer--; + if (data.byte(kLastweapon) == 1) { + // Gun on pool + data.byte(kLastweapon) = (byte)-1; + nextReelPointer = 147; + } else { + // Gun not on pool + data.byte(kCombatcount)++; + if (data.byte(kCombatcount) == 40) { + data.byte(kCombatcount) = 0; + nextReelPointer = 220; + } + } + } + } else { + nextReelPointer--; + + if (data.byte(kLastweapon) == 2) { + // Axe on pool + data.byte(kLastweapon) = (byte)-1; + nextReelPointer = 122; + } else { + data.byte(kCombatcount)++; + if (data.byte(kCombatcount) == 40) { + data.byte(kCombatcount) = 0; + nextReelPointer = 195; + } + } + } + + routine.setReelPointer(nextReelPointer); + } + + showGameReel(&routine); + + if (routine.reelPointer() != 121 && routine.reelPointer() != 146) { + data.byte(kPointermode) = 0; + data.word(kWatchingtime) = 2; + } else { + data.byte(kPointermode) = 2; + data.word(kWatchingtime) = 0; + } +} + } // End of namespace DreamGen diff --git a/engines/dreamweb/print.cpp b/engines/dreamweb/print.cpp index 1fc652f4b3..0fd596ceac 100644 --- a/engines/dreamweb/print.cpp +++ b/engines/dreamweb/print.cpp @@ -24,7 +24,7 @@ namespace DreamGen { -void DreamGenContext::printBoth(const Frame *charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar) { +void DreamBase::printBoth(const Frame *charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar) { uint16 newX = *x; uint8 width, height; printChar(charSet, &newX, y, c, nextChar, &width, &height); @@ -35,7 +35,7 @@ void DreamGenContext::printBoth(const Frame *charSet, uint16 *x, uint16 y, uint8 uint8 DreamBase::getNextWord(const Frame *charSet, const uint8 *string, uint8 *totalWidth, uint8 *charCount) { *totalWidth = 0; *charCount = 0; - while(true) { + while (true) { uint8 firstChar = *string; ++string; ++*charCount; @@ -57,7 +57,7 @@ uint8 DreamBase::getNextWord(const Frame *charSet, const uint8 *string, uint8 *t } } -void DreamGenContext::printChar(const Frame *charSet, uint16* x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) { +void DreamBase::printChar(const Frame *charSet, uint16* x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) { if (c == 255) return; @@ -75,11 +75,11 @@ void DreamGenContext::printChar(const Frame *charSet, uint16* x, uint16 y, uint8 (*x) += *width; } -void DreamGenContext::printChar(const Frame *charSet, uint16 x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) { +void DreamBase::printChar(const Frame *charSet, uint16 x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) { printChar(charSet, &x, y, c, nextChar, width, height); } -uint8 DreamGenContext::printSlow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered) { +uint8 DreamBase::printSlow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered) { data.byte(kPointerframe) = 1; data.byte(kPointermode) = 3; const Frame* charSet = (const Frame *)getSegment(data.word(kCharset1)).ptr(0, 0); @@ -122,19 +122,18 @@ uint8 DreamGenContext::printSlow(const uint8 *string, uint16 x, uint16 y, uint8 void DreamGenContext::printDirect() { uint16 y = bx; - uint16 initialSi = si; const uint8 *initialString = es.ptr(si, 0); const uint8 *string = initialString; - al = printDirect(&string, di, &y, dl, (bool)(dl & 1)); - si = initialSi + (string - initialString); + al = DreamBase::printDirect(&string, di, &y, dl, (bool)(dl & 1)); + si += (string - initialString); bx = y; } -uint8 DreamGenContext::printDirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered) { +uint8 DreamBase::printDirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered) { return printDirect(&string, x, &y, maxWidth, centered); } -uint8 DreamGenContext::printDirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered) { +uint8 DreamBase::printDirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered) { data.word(kLastxpos) = x; const Frame *charSet = engine->currentCharset(); while (true) { @@ -153,7 +152,7 @@ uint8 DreamGenContext::printDirect(const uint8** string, uint16 x, uint16 *y, ui printChar(charSet, &i, *y, c, nextChar, &width, &height); data.word(kLastxpos) = i; --charCount; - } while(charCount); + } while (charCount); *y += data.word(kLinespacing); } } @@ -205,7 +204,7 @@ uint8 DreamBase::kernChars(uint8 firstChar, uint8 secondChar, uint8 width) { return width; } -uint16 DreamGenContext::waitFrames() { +uint16 DreamBase::waitFrames() { readMouse(); showPointer(); vSync(); @@ -221,7 +220,7 @@ void DreamGenContext::monPrint() { bx = originalBx + (nextString - string); } -const char *DreamGenContext::monPrint(const char *string) { +const char *DreamBase::monPrint(const char *string) { data.byte(kKerning) = 1; uint16 x = data.word(kMonadx); Frame *charset = engine->tempCharset(); diff --git a/engines/dreamweb/runtime.h b/engines/dreamweb/runtime.h index a37fb56967..9b70d164a6 100644 --- a/engines/dreamweb/runtime.h +++ b/engines/dreamweb/runtime.h @@ -20,16 +20,15 @@ * */ -#ifndef DREAMGEN_RUNTIME_H__ -#define DREAMGEN_RUNTIME_H__ +#ifndef DREAMGEN_RUNTIME_H +#define DREAMGEN_RUNTIME_H #include <assert.h> #include "common/scummsys.h" #include "common/array.h" #include "common/debug.h" -#include "common/hashmap.h" -#include "common/list.h" -#include "common/ptr.h" + +#include "dreamweb/segment.h" namespace DreamGen { @@ -41,12 +40,6 @@ struct Register { inline Register(): _value() {} inline Register& operator=(uint16 v) { _value = v; return *this; } inline operator uint16&() { return _value; } - inline void cbw() { - if (_value & 0x80) - _value |= 0xff00; - else - _value &= 0x7f; - } }; template<int kIndex> //from low to high @@ -78,134 +71,6 @@ struct RegisterPart { typedef RegisterPart<0> HighPartOfRegister; #endif -class WordRef { - uint8 *_data; - unsigned _index; - uint16 _value; - -public: - inline WordRef(Common::Array<uint8> &data, unsigned index) : _data(data.begin() + index), _index(index) { - assert(index + 1 < data.size()); - _value = _data[0] | (_data[1] << 8); - } - - inline WordRef& operator=(const WordRef &ref) { - _value = ref._value; - return *this; - } - - inline WordRef& operator=(uint16 v) { - _value = v; - return *this; - } - - inline operator uint16&() { - return _value; - } - - inline ~WordRef() { - _data[0] = _value & 0xff; - _data[1] = _value >> 8; - _value = _data[0] | (_data[1] << 8); - } -}; - -class Segment { - Common::Array<uint8> data; - -public: - Segment(uint size = 0) { - if (size > 0) - data.resize(size); - } - - inline void assign(const uint8 *b, const uint8 *e) { - data.assign(b, e); - } - - inline uint8 &byte(unsigned index) { - assert(index < data.size()); - return data[index]; - } - - inline WordRef word(unsigned index) { - return WordRef(data, index); - } - - inline uint8 *ptr(unsigned index, unsigned size) { - assert(index + size <= data.size()); - return data.begin() + index; - } -}; - -typedef Common::SharedPtr<Segment> SegmentPtr; - -class Context; - -class SegmentRef { - uint16 _value; - SegmentPtr _segment; - -public: - SegmentRef(uint16 value = 0, SegmentPtr segment = SegmentPtr()) - : _value(value), _segment(segment) { - } - - inline operator uint16() const { - return _value; - } - - SegmentPtr getSegmentPtr() const { - return _segment; - } - - inline uint8 &byte(unsigned index) { - assert(_segment != 0); - return _segment->byte(index); - } - - inline WordRef word(unsigned index) { - //debug(1, "getting word ref for %04x:%d", _value, index); - assert(_segment != 0); - return _segment->word(index); - } - - inline void assign(const uint8 *b, const uint8 *e) { - assert(_segment != 0); - _segment->assign(b, e); - } - - inline uint8 *ptr(unsigned index, unsigned size) { - assert(_segment != 0); - return _segment->ptr(index, size); - } - -protected: - SegmentRef &operator=(const SegmentRef &seg) { - _value = seg._value; - _segment = seg._segment; - return *this; - } - -}; - -class MutableSegmentRef : public SegmentRef { -protected: - Context *_context; - -public: - MutableSegmentRef(Context *ctx, uint16 value = 0, SegmentPtr segment = SegmentPtr()) - : _context(ctx), SegmentRef(value, segment) { - } - - MutableSegmentRef(Context *ctx, SegmentRef seg) - : _context(ctx), SegmentRef(seg) { - } - - inline MutableSegmentRef& operator=(const uint16 id); - -}; - struct Flags { bool _z, _c, _s, _o; inline Flags(): _z(true), _c(false), _s(false), _o(false) {} @@ -239,15 +104,7 @@ struct Flags { }; class Context { - typedef Common::HashMap<uint16, SegmentPtr> SegmentMap; - SegmentMap _segments; - - typedef Common::List<uint16> FreeSegmentList; - FreeSegmentList _freeSegments; - public: - enum { kDefaultDataSegment = 0x1000 }; - Register ax, dx, bx, cx, si, di; LowPartOfRegister al; HighPartOfRegister ah; @@ -263,44 +120,11 @@ public: MutableSegmentRef es; Flags flags; - Context(SegmentRef data): al(ax), ah(ax), bl(bx), bh(bx), cl(cx), ch(cx), dl(dx), dh(dx), - cs(data), - ds(this, data), - es(this, data) { + Context(SegmentManager *segMan): al(ax), ah(ax), bl(bx), bh(bx), cl(cx), ch(cx), dl(dx), dh(dx), + cs(segMan->data), + ds(segMan, segMan->data), + es(segMan, segMan->data) { - _segments[kDefaultDataSegment] = data.getSegmentPtr(); - } - - SegmentRef getSegment(uint16 value) { - SegmentMap::iterator i = _segments.find(value); - if (i != _segments.end()) - return SegmentRef(value, i->_value); - else - return SegmentRef(value); - } - - SegmentRef allocateSegment(uint size) { - unsigned id; - if (_freeSegments.empty()) - id = kDefaultDataSegment + _segments.size(); - else { - id = _freeSegments.front(); - _freeSegments.pop_front(); - } - assert(!_segments.contains(id)); - SegmentPtr seg(new Segment(size)); - _segments[id] = seg; - return SegmentRef(id, seg); - } - - void deallocateSegment(uint16 id) { - SegmentMap::iterator i = _segments.find(id); - if(i != _segments.end()) { - _segments.erase(i); - _freeSegments.push_back(id); - } else { - debug("Deallocating non existent segment! Client code should be fixed."); - } } inline void _cmp(uint8 a, uint8 b) { @@ -574,11 +398,6 @@ public: } }; -inline MutableSegmentRef& MutableSegmentRef::operator=(const uint16 id) { - SegmentRef::operator=(_context->getSegment(id)); - return *this; -} - class StackChecker { const Context &_context; const uint _stackDepth; @@ -594,6 +413,6 @@ public: # define STACK_CHECK do {} while (0) #endif -} // End of namespace DreamWeb +} // End of namespace DreamGen #endif diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp index 45a1c8ef7a..cd32e4fa34 100644 --- a/engines/dreamweb/saveload.cpp +++ b/engines/dreamweb/saveload.cpp @@ -22,9 +22,11 @@ #include "dreamweb/dreamweb.h" #include "engines/metaengine.h" +#include "graphics/thumbnail.h" #include "gui/saveload.h" #include "common/config-manager.h" #include "common/translation.h" +#include "common/serializer.h" namespace DreamGen { @@ -32,6 +34,16 @@ namespace DreamGen { Room g_madeUpRoomDat; +void syncReelRoutine(Common::Serializer &s, ReelRoutine *reel) { + s.syncAsByte(reel->reallocation); + s.syncAsByte(reel->mapX); + s.syncAsByte(reel->mapY); + s.syncAsUint16LE(reel->_reelPointer); + s.syncAsByte(reel->period); + s.syncAsByte(reel->counter); + s.syncAsByte(reel->b7); +} + void DreamGenContext::loadGame() { if (data.byte(kCommandtype) != 246) { data.byte(kCommandtype) = 246; @@ -72,7 +84,7 @@ void DreamGenContext::doLoad(int savegameId) { { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamGenContext::getBackToOps }, { kOpsx+128,kOpsx+190,kOpsy+12,kOpsy+100,&DreamGenContext::actualLoad }, { kOpsx+2,kOpsx+92,kOpsy+4,kOpsy+81,&DreamGenContext::selectSlot }, - { 0,320,0,200,&DreamGenContext::blank }, + { 0,320,0,200,&DreamBase::blank }, { 0xFFFF,0,0,0,0 } }; checkCoords(loadlist); @@ -121,7 +133,7 @@ void DreamGenContext::doLoad(int savegameId) { data.word(kTextaddressy) = 182; data.byte(kTextlen) = 240; startup(); - workToScreen(); + workToScreenCPP(); data.byte(kGetback) = 4; } @@ -168,7 +180,7 @@ void DreamGenContext::saveGame() { { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamGenContext::getBackToOps }, { kOpsx+128,kOpsx+190,kOpsy+12,kOpsy+100,&DreamGenContext::actualSave }, { kOpsx+2,kOpsx+92,kOpsy+4,kOpsy+81,&DreamGenContext::selectSlot }, - { 0,320,0,200,&DreamGenContext::blank }, + { 0,320,0,200,&DreamBase::blank }, { 0xFFFF,0,0,0,0 } }; checkCoords(savelist); @@ -191,20 +203,15 @@ void DreamGenContext::saveGame() { return; } - // TODO: Check if this 2 is a constant - uint8 descbuf[17] = { 2, 0 }; - strncpy((char*)descbuf+1, game_description.c_str(), 16); + char descbuf[17] = { 2, 0 }; + Common::strlcpy((char*)descbuf + 1, game_description.c_str(), 16); unsigned int desclen = game_description.size(); if (desclen > 15) desclen = 15; // zero terminate, and pad with ones descbuf[++desclen] = 0; - while (desclen < 17) + while (desclen < 16) descbuf[++desclen] = 1; - if (savegameId < 7) - memcpy(data.ptr(kSavenames + 17*savegameId, 17), descbuf, 17); - - savePosition(savegameId, descbuf); // TODO: The below is copied from actualsave getRidOfTemp(); @@ -213,17 +220,23 @@ void DreamGenContext::saveGame() { data.word(kTextaddressy) = 182; data.byte(kTextlen) = 240; redrawMainScrn(); + workToScreenCPP(); // show the main screen without the mouse pointer + + // We need to save after the scene has been redrawn, to capture the + // correct screen thumbnail + savePosition(savegameId, descbuf); + workToScreenM(); data.byte(kGetback) = 4; } } -void DreamGenContext::namesToOld() { - memcpy(getSegment(data.word(kBuffers)).ptr(kZoomspace, 0), data.ptr(kSavenames, 0), 17*4); +void DreamBase::namesToOld() { + memcpy(_saveNamesOld, _saveNames, 17*7); } -void DreamGenContext::oldToNames() { - memcpy(data.ptr(kSavenames, 0), getSegment(data.word(kBuffers)).ptr(kZoomspace, 0), 17*4); +void DreamBase::oldToNames() { + memcpy(_saveNames, _saveNamesOld, 17*7); } void DreamGenContext::saveLoad() { @@ -239,13 +252,77 @@ void DreamGenContext::saveLoad() { doSaveLoad(); } -void DreamGenContext::showMainOps() { +void DreamGenContext::doSaveLoad() { + data.byte(kPointerframe) = 0; + data.word(kTextaddressx) = 70; + data.word(kTextaddressy) = 182-8; + data.byte(kTextlen) = 181; + data.byte(kManisoffscreen) = 1; + clearWork(); + createPanel2(); + underTextLine(); + getRidOfAll(); + loadSaveBox(); + showOpBox(); + showMainOps(); + workToScreenCPP(); + + RectWithCallback opsList[] = { + { kOpsx+59,kOpsx+114,kOpsy+30,kOpsy+76,&DreamGenContext::getBackFromOps }, + { kOpsx+10,kOpsx+77,kOpsy+10,kOpsy+59,&DreamBase::DOSReturn }, + { kOpsx+128,kOpsx+190,kOpsy+16,kOpsy+100,&DreamGenContext::discOps }, + { 0,320,0,200,&DreamBase::blank }, + { 0xFFFF,0,0,0,0 } + }; + + bool firstOps = true; + + do { // restart ops + if (firstOps) { + firstOps = false; + } else { + showOpBox(); + showMainOps(); + workToScreenM(); + } + data.byte(kGetback) = 0; + + do { // wait ops + if (data.byte(kQuitrequested)) { + data.byte(kManisoffscreen) = 0; + return; + } + + readMouse(); + showPointer(); + vSync(); + dumpPointer(); + dumpTextLine(); + delPointer(); + checkCoords(opsList); + } while (!data.byte(kGetback)); + } while (data.byte(kGetback) == 2); + + data.word(kTextaddressx) = 13; + data.word(kTextaddressy) = 182; + data.byte(kTextlen) = 240; + if (data.byte(kGetback) != 4) { + getRidOfTemp(); + restoreAll(); + redrawMainScrn(); + workToScreenM(); + data.byte(kCommandtype) = 200; + } + data.byte(kManisoffscreen) = 0; +} + +void DreamBase::showMainOps() { showFrame(tempGraphics(), kOpsx+10, kOpsy+10, 8, 0); showFrame(tempGraphics(), kOpsx+59, kOpsy+30, 7, 0); showFrame(tempGraphics(), kOpsx+128+4, kOpsy+12, 1, 0); } -void DreamGenContext::showDiscOps() { +void DreamBase::showDiscOps() { showFrame(tempGraphics(), kOpsx+128+4, kOpsy+12, 1, 0); showFrame(tempGraphics(), kOpsx+10, kOpsy+10, 9, 0); showFrame(tempGraphics(), kOpsx+59, kOpsy+30, 10, 0); @@ -263,7 +340,7 @@ void DreamGenContext::actualSave() { unsigned int slot = data.byte(kCurrentslot); - const uint8 *desc = data.ptr(kSavenames + 17*slot, 16); + const char *desc = &_saveNames[17*slot]; if (desc[1] == 0) // The actual description string starts at desc[1] return; @@ -290,7 +367,7 @@ void DreamGenContext::actualLoad() { unsigned int slot = data.byte(kCurrentslot); - const uint8 *desc = data.ptr(kSavenames + 17*slot, 16); + const char *desc = &_saveNames[17*slot]; if (desc[1] == 0) // The actual description string starts at desc[1] return; @@ -298,7 +375,7 @@ void DreamGenContext::actualLoad() { data.byte(kGetback) = 1; } -void DreamGenContext::savePosition(unsigned int slot, const uint8 *descbuf) { +void DreamBase::savePosition(unsigned int slot, const char *descbuf) { const Room ¤tRoom = g_roomData[data.byte(kLocation)]; @@ -311,7 +388,11 @@ void DreamGenContext::savePosition(unsigned int slot, const uint8 *descbuf) { madeUpRoom.facing = data.byte(kFacing); madeUpRoom.b27 = 255; - openForSave(slot); + Common::String filename = engine->getSavegameFilename(slot); + debug(1, "savePosition: slot %d filename %s", slot, filename.c_str()); + Common::OutSaveFile *outSaveFile = engine->getSaveFileManager()->openForSaving(filename); + if (!outSaveFile) // TODO: Do proper error handling! + error("save could not be opened for writing"); // Initialize new header FileHeader header; @@ -325,33 +406,68 @@ void DreamGenContext::savePosition(unsigned int slot, const uint8 *descbuf) { // fill length fields in savegame file header uint16 len[6] = { 17, kLengthofvars, kLengthofextra, - 4*kNumchanges, 48, kLenofreelrouts }; + 4*kNumchanges, 48, kNumReelRoutines*8+1 }; for (int i = 0; i < 6; ++i) header.setLen(i, len[i]); - engine->writeToSaveFile((const uint8 *)&header, sizeof(FileHeader)); - engine->writeToSaveFile(descbuf, len[0]); - engine->writeToSaveFile(data.ptr(kStartvars, len[1]), len[1]); - engine->writeToSaveFile(getSegment(data.word(kExtras)).ptr(kExframedata, len[2]), len[2]); - engine->writeToSaveFile(getSegment(data.word(kBuffers)).ptr(kListofchanges, len[3]), len[3]); + // Write a new section with data that we need for ScummVM (version, + // thumbnail, played time etc). We don't really care for its size, + // so we just set it to a magic number. + header.setLen(6, SCUMMVM_BLOCK_MAGIC_SIZE); + + outSaveFile->write((const uint8 *)&header, sizeof(FileHeader)); + outSaveFile->write(descbuf, len[0]); + outSaveFile->write(data.ptr(kStartvars, len[1]), len[1]); + outSaveFile->write(getSegment(data.word(kExtras)).ptr(kExframedata, len[2]), len[2]); + outSaveFile->write(getSegment(data.word(kBuffers)).ptr(kListofchanges, len[3]), len[3]); // len[4] == 48, which is sizeof(Room) plus 16 for 'Roomscango' - engine->writeToSaveFile((const uint8 *)&madeUpRoom, sizeof(Room)); - engine->writeToSaveFile(data.ptr(kRoomscango, 16), 16); + outSaveFile->write((const uint8 *)&madeUpRoom, sizeof(Room)); + outSaveFile->write(data.ptr(kRoomscango, 16), 16); + + // TODO: Convert more to serializer? + Common::Serializer s(0, outSaveFile); + for (unsigned int i = 0; i < kNumReelRoutines; ++i) { + syncReelRoutine(s, &_reelRoutines[i]); + } + // Terminator + s.syncAsByte(_reelRoutines[kNumReelRoutines].reallocation); + + // ScummVM data block + outSaveFile->writeUint32BE(SCUMMVM_HEADER); + outSaveFile->writeByte(SAVEGAME_VERSION); + TimeDate curTime; + g_system->getTimeAndDate(curTime); + uint32 saveDate = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF); + uint32 saveTime = ((curTime.tm_hour & 0xFF) << 16) | (((curTime.tm_min) & 0xFF) << 8) | ((curTime.tm_sec) & 0xFF); + uint32 playTime = g_engine->getTotalPlayTime() / 1000; + outSaveFile->writeUint32LE(saveDate); + outSaveFile->writeUint32LE(saveTime); + outSaveFile->writeUint32LE(playTime); + Graphics::saveThumbnail(*outSaveFile); + + outSaveFile->finalize(); + if (outSaveFile->err()) { + // TODO: Do proper error handling + warning("an error occurred while writing the savegame"); + } - engine->writeToSaveFile(data.ptr(kReelroutines, len[5]), len[5]); - closeFile(); + delete outSaveFile; } -void DreamGenContext::loadPosition(unsigned int slot) { +void DreamBase::loadPosition(unsigned int slot) { data.word(kTimecount) = 0; clearChanges(); - openForLoad(slot); + Common::String filename = engine->getSavegameFilename(slot); + debug(1, "loadPosition: slot %d filename %s", slot, filename.c_str()); + Common::InSaveFile *inSaveFile = engine->getSaveFileManager()->openForLoading(filename); + if (!inSaveFile) // TODO: Do proper error handling! + error("save could not be opened for reading"); FileHeader header; - engine->readFromSaveFile((uint8 *)&header, sizeof(FileHeader)); + inSaveFile->read((uint8 *)&header, sizeof(FileHeader)); // read segment lengths from savegame file header int len[6]; @@ -361,56 +477,92 @@ void DreamGenContext::loadPosition(unsigned int slot) { ::error("Error loading save: description buffer isn't 17 bytes"); if (slot < 7) { - engine->readFromSaveFile(data.ptr(kSavenames + 17*slot, len[0]), len[0]); + inSaveFile->read(&_saveNames[17*slot], len[0]); } else { // The savenames buffer only has room for 7 descriptions uint8 namebuf[17]; - engine->readFromSaveFile(namebuf, 17); + inSaveFile->read(namebuf, 17); } - engine->readFromSaveFile(data.ptr(kStartvars, len[1]), len[1]); - engine->readFromSaveFile(getSegment(data.word(kExtras)).ptr(kExframedata, len[2]), len[2]); - engine->readFromSaveFile(getSegment(data.word(kBuffers)).ptr(kListofchanges, len[3]), len[3]); + inSaveFile->read(data.ptr(kStartvars, len[1]), len[1]); + inSaveFile->read(getSegment(data.word(kExtras)).ptr(kExframedata, len[2]), len[2]); + inSaveFile->read(getSegment(data.word(kBuffers)).ptr(kListofchanges, len[3]), len[3]); // len[4] == 48, which is sizeof(Room) plus 16 for 'Roomscango' // Note: the values read into g_madeUpRoomDat are only used in actualLoad, // which is (almost) immediately called after this function - engine->readFromSaveFile((uint8 *)&g_madeUpRoomDat, sizeof(Room)); - engine->readFromSaveFile(data.ptr(kRoomscango, 16), 16); + inSaveFile->read((uint8 *)&g_madeUpRoomDat, sizeof(Room)); + inSaveFile->read(data.ptr(kRoomscango, 16), 16); - engine->readFromSaveFile(data.ptr(kReelroutines, len[5]), len[5]); - - closeFile(); -} - -// Count number of save files, and load their descriptions into kSavenames -unsigned int DreamGenContext::scanForNames() { - unsigned int count = 0; - - FileHeader header; - - for (unsigned int slot = 0; slot < 7; ++slot) { + // TODO: Use serializer for more + Common::Serializer s(inSaveFile, 0); + for (unsigned int i = 0; i < kNumReelRoutines; ++i) { + syncReelRoutine(s, &_reelRoutines[i]); + } + // Terminator + s.syncAsByte(_reelRoutines[kNumReelRoutines].reallocation); + + // Check if there's a ScummVM data block + if (header.len(6) == SCUMMVM_BLOCK_MAGIC_SIZE) { + uint32 tag = inSaveFile->readUint32BE(); + if (tag != SCUMMVM_HEADER) { + warning("ScummVM data block found, but the block header is incorrect - skipping"); + delete inSaveFile; + return; + } - if (!openForLoad(slot)) continue; + byte version = inSaveFile->readByte(); + if (version > SAVEGAME_VERSION) { + warning("ScummVM data block found, but it has been saved with a newer version of ScummVM - skipping"); + delete inSaveFile; + return; + } - ++count; + inSaveFile->skip(4); // saveDate + inSaveFile->skip(4); // saveTime + uint32 playTime = inSaveFile->readUint32LE(); + g_engine->setTotalPlayTime(playTime * 1000); - engine->readFromSaveFile((uint8 *)&header, sizeof(FileHeader)); + // The thumbnail data follows, but we don't need it here + } - if (header.len(0) != 17) { - ::warning("Error loading save: description buffer isn't 17 bytes"); - closeFile(); - continue; - } + delete inSaveFile; +} - // NB: Only possible if slot < 7 - engine->readFromSaveFile(data.ptr(kSavenames + 17*slot, 17), 17); +// Count number of save files, and load their descriptions into _saveNames +unsigned int DreamGenContext::scanForNames() { + // Initialize the first 7 slots (like the original code expects) + for (unsigned int slot = 0; slot < 7; ++slot) { + _saveNames[17 * slot + 0] = 2; + _saveNames[17 * slot + 1] = 0; + for (int i = 2; i < 17; ++i) + _saveNames[17 * slot + i] = 1; // initialize with 1's + } - closeFile(); + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray files = saveFileMan->listSavefiles("DREAMWEB.D??"); + Common::sort(files.begin(), files.end()); + + SaveStateList saveList; + for (uint i = 0; i < files.size(); ++i) { + const Common::String &file = files[i]; + Common::InSaveFile *stream = saveFileMan->openForLoading(file); + if (!stream) + error("cannot open save file %s", file.c_str()); + char name[17] = {}; + stream->seek(0x61); + stream->read(name, sizeof(name) - 1); + delete stream; + + int slotNum = atoi(file.c_str() + file.size() - 2); + SaveStateDescriptor sd(slotNum, name); + saveList.push_back(sd); + if (slotNum < 7) + Common::strlcpy(&_saveNames[17 * slotNum + 1], name, 16); // the first character is unused } - al = (uint8)count; + al = saveList.size() <= 7 ? (uint8)saveList.size() : 7; - return count; + return saveList.size(); } void DreamGenContext::loadOld() { @@ -436,4 +588,97 @@ void DreamGenContext::loadSaveBox() { loadIntoTemp("DREAMWEB.G08"); } +// show savegame names (original interface), and set kCursorpos +void DreamBase::showNames() { + for (int slot = 0; slot < 7; ++slot) { + // The first character of the savegame name is unused + Common::String name(&_saveNames[17*slot + 1]); + + if (slot != data.byte(kCurrentslot)) { + printDirect((const uint8 *)name.c_str(), kOpsx + 21, kOpsy + 10*slot + 10, 200, false); + continue; + } + if (data.byte(kLoadingorsave) != 2) { + data.word(kCharshift) = 91; + printDirect((const uint8 *)name.c_str(), kOpsx + 21, kOpsy + 10*slot + 10, 200, false); + data.word(kCharshift) = 0; + continue; + } + + int pos = name.size(); + data.byte(kCursorpos) = pos; + name += '/'; // cursor character + printDirect((const uint8 *)name.c_str(), kOpsx + 21, kOpsy + 10*slot + 10, 200, false); + } +} + +void DreamGenContext::checkInput() { + if (data.byte(kLoadingorsave) == 3) + return; + + readKey(); + + // The first character of the savegame name is unused + char *name = &_saveNames[17*data.byte(kCurrentslot) + 1]; + + if (data.byte(kCurrentkey) == 0) { + return; + } else if (data.byte(kCurrentkey) == 13) { + data.byte(kLoadingorsave) = 3; + } else if (data.byte(kCurrentkey) == 8) { + if (data.byte(kCursorpos) == 0) + return; + + --data.byte(kCursorpos); + name[data.byte(kCursorpos)] = 0; + name[data.byte(kCursorpos)+1] = 1; + } else { + if (data.byte(kCursorpos) == 14) + return; + + name[data.byte(kCursorpos)] = data.byte(kCurrentkey); + name[data.byte(kCursorpos)+1] = 0; + name[data.byte(kCursorpos)+2] = 1; + ++data.byte(kCursorpos); + } + + showOpBox(); + showNames(); + showSlots(); + showSaveOps(); + workToScreenM(); +} + +void DreamGenContext::selectSlot() { + if (data.byte(kCommandtype) != 244) { + data.byte(kCommandtype) = 244; + commandOnly(45); + } + + if (data.word(kMousebutton) != 1 || data.word(kMousebutton) == data.word(kOldbutton)) + return; // noselslot + if (data.byte(kLoadingorsave) == 3) + data.byte(kLoadingorsave)--; + + oldToNames(); + int y = data.word(kMousey) - (kOpsy + 4); + if (y < 11) + data.byte(kCurrentslot) = 0; + else + data.byte(kCurrentslot) = y / 11; + + delPointer(); + showOpBox(); + showSlots(); + showNames(); + if (data.byte(kLoadingorsave) == 1) + showLoadOps(); + else + showSaveOps(); + readMouse(); + showPointer(); + workToScreen(); + delPointer(); +} + } // End of namespace DreamGen diff --git a/engines/dreamweb/segment.h b/engines/dreamweb/segment.h new file mode 100644 index 0000000000..65bc2335ea --- /dev/null +++ b/engines/dreamweb/segment.h @@ -0,0 +1,232 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef DREAMGEN_SEGMENT_H +#define DREAMGEN_SEGMENT_H + +#include "common/array.h" +#include "common/ptr.h" +#include "common/hashmap.h" +#include "common/list.h" + +namespace DreamGen { + +class WordRef { + uint8 *_data; + unsigned _index; + uint16 _value; + +public: + inline WordRef(Common::Array<uint8> &data, unsigned index) : _data(data.begin() + index), _index(index) { + assert(index + 1 < data.size()); + _value = _data[0] | (_data[1] << 8); + } + + inline WordRef& operator=(const WordRef &ref) { + _value = ref._value; + return *this; + } + + inline WordRef& operator=(uint16 v) { + _value = v; + return *this; + } + + inline operator uint16&() { + return _value; + } + + inline ~WordRef() { + // FIXME: This is _too late_ to write back the + // value. Example: in the call + // printDirect(data.word(kLastxpos), .....) + // the destructor isn't called until after printDirect returns. This + // destroys the modifications to lastXPos that printDirect makes. + _data[0] = _value & 0xff; + _data[1] = _value >> 8; + _value = _data[0] | (_data[1] << 8); + } +}; + +class Segment { + Common::Array<uint8> data; + +public: + Segment(uint size = 0) { + if (size > 0) + data.resize(size); + } + + inline void assign(const uint8 *b, const uint8 *e) { + data.assign(b, e); + } + + inline uint8 &byte(unsigned index) { + assert(index < data.size()); + return data[index]; + } + + inline WordRef word(unsigned index) { + return WordRef(data, index); + } + + inline uint8 *ptr(unsigned index, unsigned size) { + assert(index + size <= data.size()); + return data.begin() + index; + } +}; + +typedef Common::SharedPtr<Segment> SegmentPtr; + +class SegmentRef { + uint16 _value; + SegmentPtr _segment; + +public: + SegmentRef(uint16 value = 0, SegmentPtr segment = SegmentPtr()) + : _value(value), _segment(segment) { + } + + inline operator uint16() const { + return _value; + } + + SegmentPtr getSegmentPtr() const { + return _segment; + } + + inline uint8 &byte(unsigned index) { + assert(_segment != 0); + return _segment->byte(index); + } + + inline WordRef word(unsigned index) { + //debug(1, "getting word ref for %04x:%d", _value, index); + assert(_segment != 0); + return _segment->word(index); + } + + inline void assign(const uint8 *b, const uint8 *e) { + assert(_segment != 0); + _segment->assign(b, e); + } + + inline uint8 *ptr(unsigned index, unsigned size) { + assert(_segment != 0); + return _segment->ptr(index, size); + } + +protected: + SegmentRef &operator=(const SegmentRef &seg) { + _value = seg._value; + _segment = seg._segment; + return *this; + } + +}; + +class SegmentManager; + +class MutableSegmentRef : public SegmentRef { +protected: + SegmentManager *_segMan; + +public: + MutableSegmentRef(SegmentManager *segMan, uint16 value = 0, SegmentPtr segment = SegmentPtr()) + : _segMan(segMan), SegmentRef(value, segment) { + } + + MutableSegmentRef(SegmentManager *segMan, SegmentRef seg) + : _segMan(segMan), SegmentRef(seg) { + } + + inline MutableSegmentRef& operator=(const uint16 id); + +}; + + +class SegmentManager { +private: + typedef Common::HashMap<uint16, SegmentPtr> SegmentMap; + SegmentMap _segments; + + typedef Common::List<uint16> FreeSegmentList; + FreeSegmentList _freeSegments; + + enum { kDefaultDataSegment = 0x1000 }; + +public: + + SegmentPtr _realData; ///< the primary data segment, points to a huge blob of binary data + SegmentRef data; ///< fake segment register always pointing to data segment + +public: + SegmentManager() : + _realData(new Segment()), + data(kDefaultDataSegment, _realData) { + + _segments[kDefaultDataSegment] = data.getSegmentPtr(); + } + + SegmentRef getSegment(uint16 value) { + SegmentMap::iterator i = _segments.find(value); + if (i != _segments.end()) + return SegmentRef(value, i->_value); + else + return SegmentRef(value); + } + + SegmentRef allocateSegment(uint size) { + unsigned id; + if (_freeSegments.empty()) + id = kDefaultDataSegment + _segments.size(); + else { + id = _freeSegments.front(); + _freeSegments.pop_front(); + } + assert(!_segments.contains(id)); + SegmentPtr seg(new Segment(size)); + _segments[id] = seg; + return SegmentRef(id, seg); + } + + void deallocateSegment(uint16 id) { + SegmentMap::iterator i = _segments.find(id); + if(i != _segments.end()) { + _segments.erase(i); + _freeSegments.push_back(id); + } else { + debug("Deallocating non existent segment! Client code should be fixed."); + } + } + +}; + + +inline MutableSegmentRef& MutableSegmentRef::operator=(const uint16 id) { + SegmentRef::operator=(_segMan->getSegment(id)); + return *this; +} + +} // End of namespace DreamGen + +#endif diff --git a/engines/dreamweb/sound.cpp b/engines/dreamweb/sound.cpp new file mode 100644 index 0000000000..784a6d0d11 --- /dev/null +++ b/engines/dreamweb/sound.cpp @@ -0,0 +1,294 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "dreamweb/dreamweb.h" +#include "dreamweb/dreamgen.h" + +#include "audio/mixer.h" +#include "audio/decoders/raw.h" + +#include "common/config-manager.h" + +namespace DreamGen { + +void DreamGenContext::loadSpeech() { + loadSpeech((uint8)dl, (uint8)dh, (uint8)cl, (uint16)ax); +} + +bool DreamBase::loadSpeech(byte type1, int idx1, byte type2, int idx2) { + cancelCh1(); + + Common::String name = Common::String::format("%c%02d%c%04d.RAW", type1, idx1, type2, idx2); + //debug("name = %s", name.c_str()); + bool result = engine->loadSpeech(name); + + data.byte(kSpeechloaded) = result; + return result; +} + + +void DreamBase::volumeAdjust() { + if (data.byte(kVolumedirection) == 0) + return; + if (data.byte(kVolume) != data.byte(kVolumeto)) { + data.byte(kVolumecount) += 64; + // Only modify the volume every 256/64 = 4th time around + if (data.byte(kVolumecount) == 0) + data.byte(kVolume) += data.byte(kVolumedirection); + } else { + data.byte(kVolumedirection) = 0; + } +} + +void DreamBase::playChannel0(uint8 index, uint8 repeat) { + data.byte(kCh0playing) = index; + Sound *soundBank; + if (index >= 12) { + soundBank = (Sound *)getSegment(data.word(kSounddata2)).ptr(0, 0); + index -= 12; + } else + soundBank = (Sound *)getSegment(data.word(kSounddata)).ptr(0, 0); + + data.byte(kCh0repeat) = repeat; + data.word(kCh0blockstocopy) = soundBank[index].blockCount(); +} + +void DreamBase::playChannel1(uint8 index) { + if (data.byte(kCh1playing) == 7) + return; + + data.byte(kCh1playing) = index; + Sound *soundBank; + if (index >= 12) { + soundBank = (Sound *)getSegment(data.word(kSounddata2)).ptr(0, 0); + index -= 12; + } else + soundBank = (Sound *)getSegment(data.word(kSounddata)).ptr(0, 0); + + data.word(kCh1blockstocopy) = soundBank[index].blockCount(); +} + +void DreamGenContext::playChannel1() { + playChannel1(al); +} + +void DreamBase::cancelCh0() { + data.byte(kCh0repeat) = 0; + data.word(kCh0blockstocopy) = 0; + data.byte(kCh0playing) = 255; + engine->stopSound(0); +} + +void DreamBase::cancelCh1() { + data.word(kCh1blockstocopy) = 0; + data.byte(kCh1playing) = 255; + engine->stopSound(1); +} + +void DreamBase::loadRoomsSample() { + uint8 sample = data.byte(kRoomssample); + + if (sample == 255 || data.byte(kCurrentsample) == sample) + return; // loaded already + + assert(sample < 100); + Common::String sampleName = Common::String::format("DREAMWEB.V%02d", sample); + + uint8 ch0 = data.byte(kCh0playing); + if (ch0 >= 12 && ch0 != 255) + cancelCh0(); + uint8 ch1 = data.byte(kCh1playing); + if (ch1 >= 12) + cancelCh1(); + engine->loadSounds(1, sampleName.c_str()); +} + +} // End of namespace DreamGen + + +namespace DreamWeb { + +void DreamWebEngine::playSound(uint8 channel, uint8 id, uint8 loops) { + debug(1, "playSound(%u, %u, %u)", channel, id, loops); + + int bank = 0; + bool speech = false; + Audio::Mixer::SoundType type = channel == 0? + Audio::Mixer::kMusicSoundType: Audio::Mixer::kSFXSoundType; + + if (id >= 12) { + id -= 12; + bank = 1; + if (id == 50) { + speech = true; + type = Audio::Mixer::kSpeechSoundType; + } + } + const SoundData &data = _soundData[bank]; + + Audio::SeekableAudioStream *raw; + if (!speech) { + if (id >= data.samples.size() || data.samples[id].size == 0) { + warning("invalid sample #%u played", id); + return; + } + + const Sample &sample = data.samples[id]; + uint8 *buffer = (uint8 *)malloc(sample.size); + if (!buffer) + error("out of memory: cannot allocate memory for sound(%u bytes)", sample.size); + memcpy(buffer, data.data.begin() + sample.offset, sample.size); + + raw = Audio::makeRawStream( + buffer, + sample.size, 22050, Audio::FLAG_UNSIGNED); + } else { + uint8 *buffer = (uint8 *)malloc(_speechData.size()); + if (!buffer) + error("out of memory: cannot allocate memory for sound(%u bytes)", _speechData.size()); + memcpy(buffer, _speechData.begin(), _speechData.size()); + raw = Audio::makeRawStream( + buffer, + _speechData.size(), 22050, Audio::FLAG_UNSIGNED); + + } + + Audio::AudioStream *stream; + if (loops > 1) { + stream = new Audio::LoopingAudioStream(raw, loops < 255? loops: 0); + } else + stream = raw; + + if (_mixer->isSoundHandleActive(_channelHandle[channel])) + _mixer->stopHandle(_channelHandle[channel]); + _mixer->playStream(type, &_channelHandle[channel], stream); +} + +void DreamWebEngine::stopSound(uint8 channel) { + debug(1, "stopSound(%u)", channel); + assert(channel == 0 || channel == 1); + _mixer->stopHandle(_channelHandle[channel]); + if (channel == 0) + _channel0 = 0; + else + _channel1 = 0; +} + +bool DreamWebEngine::loadSpeech(const Common::String &filename) { + if (ConfMan.getBool("speech_mute")) + return false; + + Common::File file; + if (!file.open("speech/" + filename)) + return false; + + debug(1, "loadSpeech(%s)", filename.c_str()); + + uint size = file.size(); + _speechData.resize(size); + file.read(_speechData.begin(), size); + file.close(); + return true; +} + +void DreamWebEngine::soundHandler() { + _base.data.byte(DreamGen::kSubtitles) = ConfMan.getBool("subtitles"); + _base.volumeAdjust(); + + uint volume = _base.data.byte(DreamGen::kVolume); + //.vol file loaded into soundbuf:0x4000 + //volume table at (volume * 0x100 + 0x3f00) + //volume value could be from 1 to 7 + //1 - 0x10-0xff + //2 - 0x1f-0xdf + //3 - 0x2f-0xd0 + //4 - 0x3e-0xc1 + //5 - 0x4d-0xb2 + //6 - 0x5d-0xa2 + //7 - 0x6f-0x91 + if (volume >= 8) + volume = 7; + volume = (8 - volume) * Audio::Mixer::kMaxChannelVolume / 8; + _mixer->setChannelVolume(_channelHandle[0], volume); + + uint8 ch0 = _base.data.byte(DreamGen::kCh0playing); + if (ch0 == 255) + ch0 = 0; + uint8 ch1 = _base.data.byte(DreamGen::kCh1playing); + if (ch1 == 255) + ch1 = 0; + uint8 ch0loop = _base.data.byte(DreamGen::kCh0repeat); + + if (_channel0 != ch0) { + _channel0 = ch0; + if (ch0) { + playSound(0, ch0, ch0loop); + } + } + if (_channel1 != ch1) { + _channel1 = ch1; + if (ch1) { + playSound(1, ch1, 1); + } + } + if (!_mixer->isSoundHandleActive(_channelHandle[0])) { + _base.data.byte(DreamGen::kCh0playing) = 255; + _channel0 = 0; + } + if (!_mixer->isSoundHandleActive(_channelHandle[1])) { + _base.data.byte(DreamGen::kCh1playing) = 255; + _channel1 = 0; + } + +} + +void DreamWebEngine::loadSounds(uint bank, const Common::String &filename) { + debug(1, "loadSounds(%u, %s)", bank, filename.c_str()); + Common::File file; + if (!file.open(filename)) { + warning("cannot open %s", filename.c_str()); + return; + } + + uint8 header[0x60]; + file.read(header, sizeof(header)); + uint tablesize = READ_LE_UINT16(header + 0x32); + debug(1, "table size = %u", tablesize); + + SoundData &soundData = _soundData[bank]; + soundData.samples.resize(tablesize / 6); + uint total = 0; + for (uint i = 0; i < tablesize / 6; ++i) { + uint8 entry[6]; + Sample &sample = soundData.samples[i]; + file.read(entry, sizeof(entry)); + sample.offset = entry[0] * 0x4000 + READ_LE_UINT16(entry + 1); + sample.size = READ_LE_UINT16(entry + 3) * 0x800; + total += sample.size; + debug(1, "offset: %08x, size: %u", sample.offset, sample.size); + } + soundData.data.resize(total); + file.read(soundData.data.begin(), total); + file.close(); +} + +} // End of namespace DreamWeb diff --git a/engines/dreamweb/sprite.cpp b/engines/dreamweb/sprite.cpp index 14794a81a8..cc6b09fd68 100644 --- a/engines/dreamweb/sprite.cpp +++ b/engines/dreamweb/sprite.cpp @@ -24,12 +24,12 @@ namespace DreamGen { -Sprite *DreamGenContext::spriteTable() { +Sprite *DreamBase::spriteTable() { Sprite *sprite = (Sprite *)getSegment(data.word(kBuffers)).ptr(kSpritetable, 16 * sizeof(Sprite)); return sprite; } -void DreamGenContext::printSprites() { +void DreamBase::printSprites() { for (size_t priority = 0; priority < 7; ++priority) { Sprite *sprites = spriteTable(); for (size_t j = 0; j < 16; ++j) { @@ -45,7 +45,7 @@ void DreamGenContext::printSprites() { } } -void DreamGenContext::printASprite(const Sprite *sprite) { +void DreamBase::printASprite(const Sprite *sprite) { uint16 x, y; if (sprite->y >= 220) { y = data.word(kMapady) - (256 - sprite->y); @@ -67,11 +67,11 @@ void DreamGenContext::printASprite(const Sprite *sprite) { showFrame((const Frame *)getSegment(sprite->frameData()).ptr(0, 0), x, y, sprite->frameNumber, c); } -void DreamGenContext::clearSprites() { +void DreamBase::clearSprites() { memset(spriteTable(), 0xff, sizeof(Sprite) * 16); } -Sprite *DreamGenContext::makeSprite(uint8 x, uint8 y, uint16 updateCallback, uint16 frameData, uint16 somethingInDi) { +Sprite *DreamBase::makeSprite(uint8 x, uint8 y, uint16 updateCallback, uint16 frameData, uint16 somethingInDi) { Sprite *sprite = spriteTable(); while (sprite->frameNumber != 0xff) { // NB: No boundchecking in the original code either ++sprite; @@ -88,7 +88,7 @@ Sprite *DreamGenContext::makeSprite(uint8 x, uint8 y, uint16 updateCallback, uin return sprite; } -void DreamGenContext::spriteUpdate() { +void DreamBase::spriteUpdate() { Sprite *sprites = spriteTable(); sprites[0].hidden = data.byte(kRyanon); @@ -111,48 +111,33 @@ void DreamGenContext::spriteUpdate() { } } -void DreamGenContext::initMan() { +void DreamBase::initMan() { Sprite *sprite = makeSprite(data.byte(kRyanx), data.byte(kRyany), addr_mainman, data.word(kMainsprites), 0); sprite->priority = 4; sprite->speed = 0; sprite->walkFrame = 0; } -void DreamGenContext::mainMan() { - assert(false); -} - -void DreamGenContext::mainMan(Sprite *sprite) { - push(es); - push(ds); - - // Recover es:bx from sprite - es = data.word(kBuffers); - bx = kSpritetable; - Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16); - bx += 32 * (sprite - sprites); - // - +void DreamBase::mainMan(Sprite *sprite) { if (data.byte(kResetmanxy) == 1) { data.byte(kResetmanxy) = 0; sprite->x = data.byte(kRyanx); sprite->y = data.byte(kRyany); sprite->walkFrame = 0; } + --sprite->speed; - if (sprite->speed != 0xff) { - ds = pop(); - es = pop(); + if (sprite->speed != 0xff) return; - } sprite->speed = 0; + if (data.byte(kTurntoface) != data.byte(kFacing)) { aboutTurn(sprite); } else { if ((data.byte(kTurndirection) != 0) && (data.byte(kLinepointer) == 254)) { data.byte(kReasseschanges) = 1; if (data.byte(kFacing) == data.byte(kLeavedirection)) - checkForExit(); + checkForExit(sprite); } data.byte(kTurndirection) = 0; if (data.byte(kLinepointer) == 254) { @@ -172,7 +157,7 @@ void DreamGenContext::mainMan(Sprite *sprite) { if (data.byte(kTurntoface) == data.byte(kFacing)) { data.byte(kReasseschanges) = 1; if (data.byte(kFacing) == data.byte(kLeavedirection)) - checkForExit(); + checkForExit(sprite); } } } @@ -181,12 +166,9 @@ void DreamGenContext::mainMan(Sprite *sprite) { sprite->frameNumber = sprite->walkFrame + facelist[data.byte(kFacing)]; data.byte(kRyanx) = sprite->x; data.byte(kRyany) = sprite->y; - - ds = pop(); - es = pop(); } -void DreamGenContext::walking(Sprite *sprite) { +void DreamBase::walking(Sprite *sprite) { uint8 comp; if (data.byte(kLinedirection) != 0) { --data.byte(kLinepointer); @@ -208,14 +190,10 @@ void DreamGenContext::walking(Sprite *sprite) { return; } data.byte(kDestination) = data.byte(kFinaldest); - push(es); - push(bx); autoSetWalk(); - bx = pop(); - es = pop(); } -void DreamGenContext::aboutTurn(Sprite *sprite) { +void DreamBase::aboutTurn(Sprite *sprite) { bool incdir = true; if (data.byte(kTurndirection) == 1) @@ -249,11 +227,7 @@ void DreamGenContext::aboutTurn(Sprite *sprite) { } } -void DreamGenContext::backObject() { - assert(false); -} - -void DreamGenContext::backObject(Sprite *sprite) { +void DreamBase::backObject(Sprite *sprite) { SetObject *objData = (SetObject *)getSegment(data.word(kSetdat)).ptr(sprite->objData(), 0); if (sprite->delay != 0) { @@ -278,7 +252,7 @@ void DreamGenContext::backObject(Sprite *sprite) { steady(sprite, objData); } -void DreamGenContext::constant(Sprite *sprite, SetObject *objData) { +void DreamBase::constant(Sprite *sprite, SetObject *objData) { ++sprite->animFrame; if (objData->frames[sprite->animFrame] == 255) { sprite->animFrame = 0; @@ -288,22 +262,22 @@ void DreamGenContext::constant(Sprite *sprite, SetObject *objData) { sprite->frameNumber = frame; } -void DreamGenContext::randomSprite(Sprite *sprite, SetObject *objData) { +void DreamBase::randomSprite(Sprite *sprite, SetObject *objData) { uint8 r = engine->randomNumber(); sprite->frameNumber = objData->frames[r&7]; } -void DreamGenContext::doorway(Sprite *sprite, SetObject *objData) { +void DreamBase::doorway(Sprite *sprite, SetObject *objData) { Common::Rect check(-24, -30, 10, 10); doDoor(sprite, objData, check); } -void DreamGenContext::wideDoor(Sprite *sprite, SetObject *objData) { +void DreamBase::wideDoor(Sprite *sprite, SetObject *objData) { Common::Rect check(-24, -30, 24, 24); doDoor(sprite, objData, check); } -void DreamGenContext::doDoor(Sprite *sprite, SetObject *objData, Common::Rect check) { +void DreamBase::doDoor(Sprite *sprite, SetObject *objData, Common::Rect check) { int ryanx = data.byte(kRyanx); int ryany = data.byte(kRyany); @@ -352,13 +326,13 @@ void DreamGenContext::doDoor(Sprite *sprite, SetObject *objData, Common::Rect ch } } -void DreamGenContext::steady(Sprite *sprite, SetObject *objData) { +void DreamBase::steady(Sprite *sprite, SetObject *objData) { uint8 frame = objData->frames[0]; objData->index = frame; sprite->frameNumber = frame; } -void DreamGenContext::lockedDoorway(Sprite *sprite, SetObject *objData) { +void DreamBase::lockedDoorway(Sprite *sprite, SetObject *objData) { int ryanx = data.byte(kRyanx); int ryany = data.byte(kRyany); @@ -409,13 +383,13 @@ void DreamGenContext::lockedDoorway(Sprite *sprite, SetObject *objData) { } } -void DreamGenContext::liftSprite(Sprite *sprite, SetObject *objData) { +void DreamBase::liftSprite(Sprite *sprite, SetObject *objData) { uint8 liftFlag = data.byte(kLiftflag); if (liftFlag == 0) { //liftclosed turnPathOff(data.byte(kLiftpath)); if (data.byte(kCounttoopen) != 0) { - _dec(data.byte(kCounttoopen)); + data.byte(kCounttoopen)--; if (data.byte(kCounttoopen) == 0) data.byte(kLiftflag) = 3; } @@ -426,7 +400,7 @@ void DreamGenContext::liftSprite(Sprite *sprite, SetObject *objData) { turnPathOn(data.byte(kLiftpath)); if (data.byte(kCounttoclose) != 0) { - _dec(data.byte(kCounttoclose)); + data.byte(kCounttoclose)--; if (data.byte(kCounttoclose) == 0) data.byte(kLiftflag) = 2; } @@ -457,86 +431,67 @@ void DreamGenContext::liftSprite(Sprite *sprite, SetObject *objData) { } } -void DreamGenContext::faceRightWay() { - PathNode *paths = getRoomsPaths()->nodes; - uint8 dir = paths[data.byte(kManspath)].dir; - data.byte(kTurntoface) = dir; - data.byte(kLeavedirection) = dir; +Reel *DreamBase::getReelStart(uint16 reelPointer) { + Reel *reel = (Reel *)getSegment(data.word(kReels)).ptr(kReellist + reelPointer * sizeof(Reel) * 8, sizeof(Reel)); + return reel; } -// Locate the reel segment (reel1, reel2, reel3) this frame is stored in. -// The return value is a pointer to the start of the segment. -// data.word(kCurrentframe) - data.word(kTakeoff) is the number of the frame -// inside that segment -Frame *DreamGenContext::findSource() { - uint16 currentFrame = data.word(kCurrentframe); - if (currentFrame < 160) { - data.word(kTakeoff) = 0; - return (Frame *)getSegment(data.word(kReel1)).ptr(0, 0); - } else if (currentFrame < 320) { - data.word(kTakeoff) = 160; - return (Frame *)getSegment(data.word(kReel2)).ptr(0, 0); +// Locate the reel segment (reel1, reel2, reel3) this frame is stored in, +// and adjust the frame number relative to this segment. +const Frame *DreamBase::findSource(uint16 &frame) { + uint16 base; + if (frame < 160) { + base = data.word(kReel1); + } else if (frame < 320) { + frame -= 160; + base = data.word(kReel2); } else { - data.word(kTakeoff) = 320; - return (Frame *)getSegment(data.word(kReel3)).ptr(0, 0); + frame -= 320; + base = data.word(kReel3); } + return (const Frame *)getSegment(base).ptr(0, (frame+1)*sizeof(Frame)); } -Reel *DreamGenContext::getReelStart() { - Reel *reel = (Reel *)getSegment(data.word(kReels)).ptr(kReellist + data.word(kReelpointer) * sizeof(Reel) * 8, sizeof(Reel)); - return reel; -} - -void DreamGenContext::showReelFrame(Reel *reel) { +void DreamBase::showReelFrame(Reel *reel) { uint16 x = reel->x + data.word(kMapadx); uint16 y = reel->y + data.word(kMapady); - data.word(kCurrentframe) = reel->frame(); - Frame *source = findSource(); - uint16 frame = data.word(kCurrentframe) - data.word(kTakeoff); - showFrame(source, x, y, frame, 8); -} - -void DreamGenContext::showGameReel() { - showGameReel((ReelRoutine *)es.ptr(bx, sizeof(ReelRoutine))); + uint16 frame = reel->frame(); + const Frame *base = findSource(frame); + showFrame(base, x, y, frame, 8); } -void DreamGenContext::showGameReel(ReelRoutine *routine) { +void DreamBase::showGameReel(ReelRoutine *routine) { uint16 reelPointer = routine->reelPointer(); if (reelPointer >= 512) return; - data.word(kReelpointer) = reelPointer; - plotReel(); - routine->setReelPointer(data.word(kReelpointer)); + plotReel(reelPointer); + routine->setReelPointer(reelPointer); } -const Frame *DreamGenContext::getReelFrameAX(uint16 frame) { - data.word(kCurrentframe) = frame; - Frame *source = findSource(); - uint16 offset = data.word(kCurrentframe) - data.word(kTakeoff); - return source + offset; +const Frame *DreamBase::getReelFrameAX(uint16 frame) { + const Frame *base = findSource(frame); + return base + frame; } -void DreamGenContext::showRain() { +void DreamBase::showRain() { Rain *rain = (Rain *)getSegment(data.word(kBuffers)).ptr(kRainlist, 0); // Do nothing if there's no rain at all if (rain->x == 255) return; - ds = data.word(kMainsprites); - si = 6*58; // Frame 58 - ax = ds.word(si+2); // Frame::ptr - si = ax + 2080; + const Frame *frame = (const Frame *)getSegment(data.word(kMainsprites)).ptr(58 * sizeof(Frame), sizeof(Frame)); + const uint8 *frameData = getSegment(data.word(kMainsprites)).ptr(kFrframes + frame->ptr(), 512); for (; rain->x != 255; ++rain) { uint16 y = rain->y + data.word(kMapady) + data.word(kMapystart); uint16 x = rain->x + data.word(kMapadx) + data.word(kMapxstart); uint16 size = rain->size; - ax = ((uint16)(rain->w3() - rain->b5)) & 511; - rain->setW3(ax); - const uint8 *src = ds.ptr(si, 0) + ax; + uint16 offset = (rain->w3() - rain->b5) & 511; + rain->setW3(offset); + const uint8 *src = frameData + offset; uint8 *dst = workspace() + y * 320 + x; - for(uint16 i = 0; i < size; ++i) { + for (uint16 i = 0; i < size; ++i) { uint8 v = src[i]; if (v != 0) *dst = v; @@ -562,7 +517,7 @@ void DreamGenContext::showRain() { playChannel1(soundIndex); } -void DreamGenContext::moveMap(uint8 param) { +void DreamBase::moveMap(uint8 param) { switch (param) { case 32: data.byte(kMapy) -= 20; @@ -594,7 +549,7 @@ void DreamGenContext::checkOne() { al = type; } -void DreamGenContext::checkOne(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uint8 *type, uint8 *flagX, uint8 *flagY) { +void DreamBase::checkOne(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uint8 *type, uint8 *flagX, uint8 *flagY) { *flagX = x / 16; *flagY = y / 16; const uint8 *tileData = getSegment(data.word(kBuffers)).ptr(kMapflags + (*flagY * 11 + *flagX) * 3, 3); @@ -603,11 +558,7 @@ void DreamGenContext::checkOne(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uin *type = tileData[2]; } -void DreamGenContext::getBlockOfPixel() { - al = getBlockOfPixel(cl, ch); -} - -uint8 DreamGenContext::getBlockOfPixel(uint8 x, uint8 y) { +uint8 DreamBase::getBlockOfPixel(uint8 x, uint8 y) { uint8 flag, flagEx, type, flagX, flagY; checkOne(x + data.word(kMapxstart), y + data.word(kMapystart), &flag, &flagEx, &type, &flagX, &flagY); if (flag & 1) @@ -616,7 +567,7 @@ uint8 DreamGenContext::getBlockOfPixel(uint8 x, uint8 y) { return type; } -Rain *DreamGenContext::splitIntoLines(uint8 x, uint8 y, Rain *rain) { +Rain *DreamBase::splitIntoLines(uint8 x, uint8 y, Rain *rain) { do { // Look for line start while (!getBlockOfPixel(x, y)) { @@ -687,7 +638,7 @@ static const RainLocation rainLocationList[] = { { 255,0,0,0 } }; -void DreamGenContext::initRain() { +void DreamBase::initRain() { const RainLocation *r = rainLocationList; Rain *rainList = (Rain *)getSegment(data.word(kBuffers)).ptr(kRainlist, 0); Rain *rain = rainList; @@ -742,7 +693,7 @@ void DreamGenContext::initRain() { rain->x = 0xff; } -void DreamGenContext::intro1Text() { +void DreamBase::intro1Text() { if (data.byte(kIntrocount) != 2 && data.byte(kIntrocount) != 4 && data.byte(kIntrocount) != 6) return; @@ -758,21 +709,65 @@ void DreamGenContext::intro1Text() { } } -void DreamGenContext::intro2Text() { - if (ax == 5) +void DreamBase::intro2Text(uint16 nextReelPointer) { + if (nextReelPointer == 5) setupTimedTemp(43, 82, 34, 40, 90, 1); - else if (ax == 15) + else if (nextReelPointer == 15) setupTimedTemp(44, 82, 34, 40, 90, 1); } -void DreamGenContext::intro3Text() { - if (ax == 107) +void DreamBase::intro3Text(uint16 nextReelPointer) { + if (nextReelPointer == 107) setupTimedTemp(45, 82, 36, 56, 100, 1); - else if (ax == (isCD() ? 108 : 109)) + else if (nextReelPointer == (isCD() ? 108 : 109)) setupTimedTemp(46, 82, 36, 56, 100, 1); } -void DreamGenContext::monks2text() { +void DreamBase::rollEndCredits() { + playChannel0(16, 255); + data.byte(kVolume) = 7; + data.byte(kVolumeto) = 0; + data.byte(kVolumedirection) = (byte)-1; + + multiGet(mapStore(), 75, 20, 160, 160); + + const uint8 *string = getTextInFile1(3); + const int linespacing = data.word(kLinespacing); + + for (int i = 0; i < 254; ++i) { + // Output the text, initially with an offset of 10 pixels, + // then move it up one pixel until we shifted it by a complete + // line of text. + for (int j = 0; j < linespacing; ++j) { + vSync(); + multiPut(mapStore(), 75, 20, 160, 160); + vSync(); + + // Output up to 18 lines of text + uint16 y = 10 - j; + const uint8 *tmp_str = string; + for (int k = 0; k < 18; ++k) { + DreamBase::printDirect(&tmp_str, 75, &y, 160 + 1, true); + y += linespacing; + } + + vSync(); + multiDump(75, 20, 160, 160); + } + + // Skip to the next text line + byte c; + do { + c = *string++; + } while (c != ':' && c != 0); + } + hangOn(100); + panelToMap(); + fadeScreenUpHalf(); +} + + +void DreamBase::monks2text() { bool isGermanCD = isCD() && engine->getLanguage() == Common::DE_DEU; if (data.byte(kIntrocount) == 1) @@ -809,7 +804,7 @@ void DreamGenContext::monks2text() { setupTimedTemp(18, 82, 36, 160, 120, 1); } -void DreamGenContext::textForEnd() { +void DreamBase::textForEnd() { if (data.byte(kIntrocount) == 20) setupTimedTemp(0, 83, 34, 20, 60, 1); else if (data.byte(kIntrocount) == (isCD() ? 50 : 65)) @@ -818,14 +813,14 @@ void DreamGenContext::textForEnd() { setupTimedTemp(2, 83, 34, 20, 60, 1); } -void DreamGenContext::textForMonkHelper(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) { +void DreamBase::textForMonkHelper(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) { if (isCD() && data.byte(kCh1playing) != 255) data.byte(kIntrocount)--; else setupTimedTemp(textIndex, voiceIndex, x, y, countToTimed, timeCount); } -void DreamGenContext::textForMonk() { +void DreamBase::textForMonk() { if (data.byte(kIntrocount) == 1) textForMonkHelper(19, 82, 68, 154, 120, 1); else if (data.byte(kIntrocount) == 5) @@ -861,7 +856,7 @@ void DreamGenContext::textForMonk() { } } -void DreamGenContext::reelsOnScreen() { +void DreamBase::reelsOnScreen() { reconstruct(); updatePeople(); watchReel(); @@ -869,7 +864,7 @@ void DreamGenContext::reelsOnScreen() { useTimedText(); } -void DreamGenContext::reconstruct() { +void DreamBase::reconstruct() { if (data.byte(kHavedoneobs) == 0) return; data.byte(kNewobs) = 1; @@ -1133,14 +1128,14 @@ static const ReelSound *g_roomByRoom[] = { }; -void DreamGenContext::soundOnReels() { +void DreamBase::soundOnReels(uint16 reelPointer) { const ReelSound *r = g_roomByRoom[data.byte(kReallocation)]; if (engine->getLanguage() == Common::DE_DEU && r == g_roomSound29) r = g_roomSound29_German; for (; r->_sample != 255; ++r) { - if (r->_reelPointer != data.word(kReelpointer)) + if (r->_reelPointer != reelPointer) continue; if (r->_reelPointer == data.word(kLastsoundreel)) continue; @@ -1156,11 +1151,11 @@ void DreamGenContext::soundOnReels() { playChannel0(r->_sample & 63, 255); } - if (data.word(kReelpointer) != data.word(kLastsoundreel)) + if (data.word(kLastsoundreel) != reelPointer) data.word(kLastsoundreel) = (uint16)-1; } -void DreamGenContext::clearBeforeLoad() { +void DreamBase::clearBeforeLoad() { if (data.byte(kRoomloaded) != 1) return /* (noclear) */; @@ -1182,13 +1177,13 @@ void DreamGenContext::clearBeforeLoad() { data.byte(kRoomloaded) = 0; } -void DreamGenContext::clearReels() { +void DreamBase::clearReels() { deallocateMem(data.word(kReel1)); deallocateMem(data.word(kReel2)); deallocateMem(data.word(kReel3)); } -void DreamGenContext::getRidOfReels() { +void DreamBase::getRidOfReels() { if (data.byte(kRoomloaded) == 0) return /* (dontgetrid) */; @@ -1197,11 +1192,68 @@ void DreamGenContext::getRidOfReels() { deallocateMem(data.word(kReel3)); } -void DreamGenContext::liftNoise(uint8 index) { +void DreamBase::liftNoise(uint8 index) { if (data.byte(kReallocation) == 5 || data.byte(kReallocation) == 21) playChannel1(13); // hiss noise else playChannel1(index); } +void DreamBase::checkForExit(Sprite *sprite) { + uint8 flag, flagEx, type, flagX, flagY; + checkOne(data.byte(kRyanx) + 12, data.byte(kRyany) + 12, &flag, &flagEx, &type, &flagX, &flagY); + data.byte(kLastflag) = flag; + + if (flag & 64) { + data.byte(kAutolocation) = flagEx; + return; + } + + if (!(flag & 32)) { + if (flag & 4) { + // adjust left + data.byte(kLastflag) = 0; + data.byte(kMapx) -= 11; + sprite->x = 16 * flagEx; + data.byte(kNowinnewroom) = 1; + } else if (flag & 2) { + // adjust right + data.byte(kMapx) += 11; + sprite->x = 16 * flagEx - 2; + data.byte(kNowinnewroom) = 1; + } else if (flag & 8) { + // adjust down + data.byte(kMapy) += 10; + sprite->y = 16 * flagEx; + data.byte(kNowinnewroom) = 1; + } else if (flag & 16) { + // adjust up + data.byte(kMapy) -= 10; + sprite->y = 16 * flagEx; + data.byte(kNowinnewroom) = 1; + } + + return; + } + + if (data.byte(kReallocation) == 2) { + // Can't leave Louis' until you found shoes + + int shoeCount = 0; + if (isRyanHolding("WETA")) shoeCount++; + if (isRyanHolding("WETB")) shoeCount++; + + if (shoeCount < 2) { + uint8 text = shoeCount ? 43 : 42; + setupTimedUse(text, 80, 10, 68, 64); + + data.byte(kTurntoface) = (data.byte(kFacing) + 4) & 7; + return; + } + + } + + data.byte(kNeedtotravel) = 1; +} + } // End of namespace DreamGen diff --git a/engines/dreamweb/structs.h b/engines/dreamweb/structs.h index aeda4725ea..313f3caf0b 100644 --- a/engines/dreamweb/structs.h +++ b/engines/dreamweb/structs.h @@ -76,8 +76,8 @@ struct SetObject { uint8 b0; uint8 b1; uint8 b2; - uint8 b3; - uint8 b4; + uint8 slotSize; + uint8 slotCount; uint8 priority; uint8 b6; uint8 delay; @@ -125,8 +125,8 @@ struct DynObject { uint8 currentLocation; uint8 index; uint8 mapad[5]; - uint8 b7; - uint8 b8; + uint8 slotSize; + uint8 slotCount; uint8 b9; uint8 b10; uint8 initialLocation; @@ -168,11 +168,10 @@ struct ReelRoutine { uint8 reallocation; uint8 mapX; uint8 mapY; - uint8 b3; - uint8 b4; - uint16 reelPointer() const { return READ_LE_UINT16(&b3); } - void setReelPointer(uint16 v) { WRITE_LE_UINT16(&b3, v); } - void incReelPointer() { setReelPointer(reelPointer() + 1); } + uint16 _reelPointer; + uint16 reelPointer() const { return _reelPointer; } + void setReelPointer(uint16 v) { _reelPointer = v; } + void incReelPointer() { _reelPointer++; } uint8 period; uint8 counter; uint8 b7; @@ -255,7 +254,6 @@ struct RoomPaths { }; struct Sound { - uint8 emmPage; uint8 w1_lo; uint8 w1_hi; uint16 offset() const { return READ_LE_UINT16(&w1_lo); } @@ -290,6 +288,13 @@ struct Atmosphere { uint8 _repeat; }; +enum ObjectTypes { + kSetObjectType1 = 1, + kFreeObjectType = 2, + kSetObjectType3 = 3, + kExObjectType = 4 +}; + } // End of namespace DreamWeb #endif diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp index 839665dd67..6989a57a93 100644 --- a/engines/dreamweb/stubs.cpp +++ b/engines/dreamweb/stubs.cpp @@ -509,7 +509,7 @@ void DreamGenContext::dreamweb() { clearPalette(); doLoad(savegameId); - workToScreen(); + workToScreenCPP(); fadeScreenUp(); startNewGame = false; @@ -576,7 +576,7 @@ void DreamGenContext::dreamweb() { data.byte(kLastflag) = 32; startup1(); data.byte(kVolumeto) = 0; - data.byte(kVolumedirection) = (uint8)-1; + data.byte(kVolumedirection) = (byte)-1; data.byte(kCommandtype) = 255; } @@ -640,12 +640,14 @@ void DreamGenContext::dreamweb() { } done: // The engine will need some cleaner finalization, let's put it here for now + // FIXME: This triggers "Deallocating non existent segment" errors when + // quitting from a menu. getRidOfAll(); engine->freeIcons1(); engine->freeIcons2(); } -bool DreamGenContext::quitRequested() { +bool DreamBase::quitRequested() { return data.byte(kQuitrequested); } @@ -726,37 +728,37 @@ void DreamGenContext::startup1() { startup(); - workToScreen(); + workToScreenCPP(); fadeScreenUp(); } -void DreamGenContext::switchRyanOn() { +void DreamBase::switchRyanOn() { data.byte(kRyanon) = 255; } -void DreamGenContext::switchRyanOff() { +void DreamBase::switchRyanOff() { data.byte(kRyanon) = 1; } -uint8 *DreamGenContext::textUnder() { +uint8 *DreamBase::textUnder() { return getSegment(data.word(kBuffers)).ptr(kTextunder, 0); } -uint16 DreamGenContext::standardLoad(const char *fileName, uint16 *outSizeInBytes) { +uint16 DreamBase::standardLoad(const char *fileName, uint16 *outSizeInBytes) { FileHeader header; - engine->openFile(fileName); - engine->readFromFile((uint8 *)&header, sizeof(FileHeader)); + Common::File file; + file.open(fileName); + file.read((uint8 *)&header, sizeof(FileHeader)); uint16 sizeInBytes = header.len(0); if (outSizeInBytes) *outSizeInBytes = sizeInBytes; uint16 result = allocateMem((sizeInBytes + 15) / 16); - engine->readFromFile(getSegment(result).ptr(0, 0), sizeInBytes); - engine->closeFile(); + file.read(getSegment(result).ptr(0, 0), sizeInBytes); return result; } -void *DreamGenContext::standardLoadCPP(const char *fileName, uint16 *outSizeInBytes) { +void *DreamBase::standardLoadCPP(const char *fileName, uint16 *outSizeInBytes) { uint16 sizeInBytes; uint16 seg = standardLoad(fileName, &sizeInBytes); void *buffer = malloc(sizeInBytes); @@ -767,31 +769,23 @@ void *DreamGenContext::standardLoadCPP(const char *fileName, uint16 *outSizeInBy return buffer; } -void DreamGenContext::loadIntoTemp() { - loadIntoTemp((const char *)data.ptr(dx, 0)); -} - -void DreamGenContext::loadIntoTemp(const char *fileName) { +void DreamBase::loadIntoTemp(const char *fileName) { data.word(kTempgraphics) = standardLoad(fileName); } -void DreamGenContext::loadIntoTemp2(const char *fileName) { +void DreamBase::loadIntoTemp2(const char *fileName) { data.word(kTempgraphics2) = standardLoad(fileName); } -void DreamGenContext::loadIntoTemp3(const char *fileName) { +void DreamBase::loadIntoTemp3(const char *fileName) { data.word(kTempgraphics3) = standardLoad(fileName); } -void DreamGenContext::loadTempCharset() { - loadTempCharset((const char *)data.ptr(dx, 0)); -} - -void DreamGenContext::loadTempCharset(const char *fileName) { +void DreamBase::loadTempCharset(const char *fileName) { engine->setTempCharset(standardLoadCPP(fileName)); } -void DreamGenContext::hangOnCurs(uint16 frameCount) { +void DreamBase::hangOnCurs(uint16 frameCount) { for (uint16 i = 0; i < frameCount; ++i) { printCurs(); vSync(); @@ -800,15 +794,7 @@ void DreamGenContext::hangOnCurs(uint16 frameCount) { } void DreamGenContext::seeCommandTail() { - data.word(kSoundbaseadd) = 0x220; - data.byte(kSoundint) = 5; - data.byte(kSounddmachannel) = 1; data.byte(kBrightness) = 1; - data.word(kHowmuchalloc) = 0x9360; -} - -void DreamGenContext::randomNumber() { - al = engine->randomNumber(); } void DreamGenContext::quickQuit() { @@ -819,36 +805,13 @@ void DreamGenContext::quickQuit2() { engine->quit(); } -void DreamGenContext::closeFile() { - engine->closeFile(); - data.byte(kHandle) = 0; -} - -void DreamGenContext::openForSave(unsigned int slot) { - //Common::String filename = ConfMan.getActiveDomainName() + Common::String::format(".d%02d", savegameId); - Common::String filename = Common::String::format("DREAMWEB.D%02d", slot); - debug(1, "openForSave(%s)", filename.c_str()); - engine->openSaveFileForWriting(filename); -} - -bool DreamGenContext::openForLoad(unsigned int slot) { - //Common::String filename = ConfMan.getActiveDomainName() + Common::String::format(".d%02d", savegameId); - Common::String filename = Common::String::format("DREAMWEB.D%02d", slot); - debug(1, "openForLoad(%s)", filename.c_str()); - return engine->openSaveFileForReading(filename); -} - -uint8 *DreamGenContext::mapStore() { - return getSegment(data.word(kMapstore)).ptr(0, 0); -} - -void DreamGenContext::readMouse() { +void DreamBase::readMouse() { data.word(kOldbutton) = data.word(kMousebutton); uint16 state = readMouseState(); data.word(kMousebutton) = state; } -uint16 DreamGenContext::readMouseState() { +uint16 DreamBase::readMouseState() { data.word(kOldx) = data.word(kMousex); data.word(kOldy) = data.word(kMousey); uint16 x, y, state; @@ -858,7 +821,7 @@ uint16 DreamGenContext::readMouseState() { return state; } -void DreamGenContext::dumpTextLine() { +void DreamBase::dumpTextLine() { if (data.byte(kNewtextline) != 1) return; data.byte(kNewtextline) = 0; @@ -869,25 +832,56 @@ void DreamGenContext::dumpTextLine() { multiDump(x, y, 228, 13); } -void DreamGenContext::getUnderTimed() { +void DreamBase::getUnderTimed() { uint16 y = data.byte(kTimedy); if (data.byte(kForeignrelease)) y -= 3; - ds = data.word(kBuffers); - si = kUndertimedtext; - multiGet(ds.ptr(si, 0), data.byte(kTimedx), y, 240, kUndertimedysize); + multiGet(getSegment(data.word(kBuffers)).ptr(kUndertimedtext, 0), data.byte(kTimedx), y, 240, kUndertimedysize); } -void DreamGenContext::putUnderTimed() { +void DreamBase::putUnderTimed() { uint16 y = data.byte(kTimedy); if (data.byte(kForeignrelease)) y -= 3; - ds = data.word(kBuffers); - si = kUndertimedtext; - multiPut(ds.ptr(si, 0), data.byte(kTimedx), y, 240, kUndertimedysize); + multiPut(getSegment(data.word(kBuffers)).ptr(kUndertimedtext, 0), data.byte(kTimedx), y, 240, kUndertimedysize); +} + +void DreamBase::getUnderCentre() { + multiGet(mapStore(), 58, 72, 254, 110); } -void DreamGenContext::useTimedText() { +void DreamBase::putUnderCentre() { + multiPut(mapStore(), 58, 72, 254, 110); +} + +void DreamGenContext::triggerMessage(uint16 index) { + multiGet(mapStore(), 174, 153, 200, 63); + uint16 offset = kTextstart + getSegment(data.word(kPuzzletext)).word(index * 2); + const uint8 *string = getSegment(data.word(kPuzzletext)).ptr(offset, 0); + uint16 y = 156; + printDirect(&string, 174, &y, 141, true); + hangOn(140); + workToScreenCPP(); + hangOn(340); + multiPut(mapStore(), 174, 153, 200, 63); + workToScreenCPP(); + data.byte(kLasttrigger) = 0; +} + +void DreamGenContext::processTrigger() { + if (data.byte(kLasttrigger) == '1') { + setLocation(8); + triggerMessage(45); + } else if (data.byte(kLasttrigger) == '2') { + setLocation(9); + triggerMessage(55); + } else if (data.byte(kLasttrigger) == '3') { + setLocation(2); + triggerMessage(59); + } +} + +void DreamBase::useTimedText() { if (data.word(kTimecount) == 0) return; --data.word(kTimecount); @@ -902,34 +896,18 @@ void DreamGenContext::useTimedText() { else if (data.word(kTimecount) > data.word(kCounttotimed)) return; - es = data.word(kTimedseg); - si = data.word(kTimedoffset); - const uint8 *string = es.ptr(si, 0); + const uint8 *string = getSegment(data.word(kTimedseg)).ptr(data.word(kTimedoffset), 0); uint16 y = data.byte(kTimedy); printDirect(&string, data.byte(kTimedx), &y, 237, true); data.byte(kNeedtodumptimed) = 1; } -void DreamGenContext::setupTimedTemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) { +void DreamBase::setupTimedTemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) { #if 1 // if cd if (voiceIndex != 0) { - push(ax); - push(bx); - push(cx); - push(dx); - dl = 'T'; - dh = voiceIndex; - cl = 'T'; - ah = 0; - al = textIndex; - loadSpeech(); - if (data.byte(kSpeechloaded) == 1) { + if (loadSpeech('T', voiceIndex, 'T', textIndex)) { playChannel1(50+12); } - dx = pop(); - cx = pop(); - bx = pop(); - ax = pop(); // FIXME: This fallthrough does not properly support subtitles+speech // mode. The parameters to setuptimedtemp() are sometimes different @@ -951,7 +929,7 @@ void DreamGenContext::setupTimedTemp(uint8 textIndex, uint8 voiceIndex, uint8 x, debug(1, "setupTimedTemp: (%d, %d) => '%s'", textIndex, voiceIndex, string); } -void DreamGenContext::dumpTimedText() { +void DreamBase::dumpTimedText() { if (data.byte(kNeedtodumptimed) != 1) return; uint8 y = data.byte(kTimedy); @@ -962,34 +940,28 @@ void DreamGenContext::dumpTimedText() { data.byte(kNeedtodumptimed) = 0; } -void DreamGenContext::getTime() { +void DreamBase::getTime() { TimeDate t; g_system->getTimeAndDate(t); debug(1, "\tgettime: %02d:%02d:%02d", t.tm_hour, t.tm_min, t.tm_sec); - ch = t.tm_hour; - cl = t.tm_min; - dh = t.tm_sec; - data.byte(kSecondcount) = dh; - data.byte(kMinutecount) = cl; - data.byte(kHourcount) = ch; + data.byte(kSecondcount) = t.tm_sec; + data.byte(kMinutecount) = t.tm_min; + data.byte(kHourcount) = t.tm_hour; } -uint16 DreamGenContext::allocateMem(uint16 paragraphs) { +uint16 DreamBase::allocateMem(uint16 paragraphs) { uint size = (paragraphs + 2) * 16; debug(1, "allocate mem, %u bytes", size); - flags._c = false; SegmentRef seg = allocateSegment(size); uint16 result = (uint16)seg; debug(1, "\tsegment address -> %04x", result); return result; } -void DreamGenContext::deallocateMem(uint16 segment) { +void DreamBase::deallocateMem(uint16 segment) { debug(1, "deallocating segment %04x", segment); deallocateSegment(segment); - //fixing invalid entries in the sprite table - es = data; uint tsize = 16 * 32; uint16 bseg = data.word(kBuffers); if (!bseg) @@ -997,7 +969,7 @@ void DreamGenContext::deallocateMem(uint16 segment) { MutableSegmentRef buffers(this); buffers = bseg; uint8 *ptr = buffers.ptr(kSpritetable, tsize); - for(uint i = 0; i < tsize; i += 32) { + for (uint i = 0; i < tsize; i += 32) { uint16 seg = READ_LE_UINT16(ptr + i + 6); //debug(1, "sprite segment = %04x", seg); if (seg == segment) @@ -1005,17 +977,7 @@ void DreamGenContext::deallocateMem(uint16 segment) { } } -void DreamGenContext::loadSpeech() { - cancelCh1(); - data.byte(kSpeechloaded) = 0; - createName(); - const char *name = (const char *)data.ptr(di, 13); - //warning("name = %s", name); - if (engine->loadSpeech(name)) - data.byte(kSpeechloaded) = 1; -} - -void DreamGenContext::DOSReturn() { +void DreamBase::DOSReturn() { if (data.byte(kCommandtype) != 250) { data.byte(kCommandtype) = 250; commandOnly(46); @@ -1030,35 +992,7 @@ void DreamGenContext::DOSReturn() { void DreamGenContext::set16ColPalette() { } -void DreamGenContext::showGroup() { - engine->processEvents(); - unsigned n = (uint16)cx; - uint8 *src = ds.ptr(si, n * 3); - engine->setPalette(src, al, n); - si += n * 3; - cx = 0; -} - -void DreamGenContext::fadeDOS() { - ds = es = data.word(kBuffers); - return; //fixme later - engine->waitForVSync(); - //processEvents will be called from vsync - uint8 *dst = es.ptr(kStartpal, 768); - engine->getPalette(dst, 0, 64); - for(int fade = 0; fade < 64; ++fade) { - for(int c = 0; c < 768; ++c) { //original sources decrement 768 values -> 256 colors - if (dst[c]) { - --dst[c]; - } - } - engine->setPalette(dst, 0, 64); - engine->waitForVSync(); - } -} - - -void DreamGenContext::eraseOldObs() { +void DreamBase::eraseOldObs() { if (data.byte(kNewobs) == 0) return; @@ -1071,7 +1005,7 @@ void DreamGenContext::eraseOldObs() { } } -void DreamGenContext::lockMon() { +void DreamBase::lockMon() { // Pressing space pauses text output in the monitor. We use the "hard" // key because calling readkey() drains characters from the input // buffer, we we want the user to be able to type ahead while the text @@ -1097,54 +1031,21 @@ void DreamGenContext::lockMon() { } } -void DreamGenContext::cancelCh0() { - data.byte(kCh0repeat) = 0; - data.word(kCh0blockstocopy) = 0; - data.byte(kCh0playing) = 255; - engine->stopSound(0); -} - -void DreamGenContext::cancelCh1() { - data.word(kCh1blockstocopy) = 0; - data.byte(kCh1playing) = 255; - engine->stopSound(1); -} - -void DreamGenContext::makeBackOb(SetObject *objData) { - if (data.byte(kNewobs) == 0) - return; - uint8 priority = objData->priority; - uint8 type = objData->type; - Sprite *sprite = makeSprite(data.word(kObjectx), data.word(kObjecty), addr_backobject, data.word(kSetframes), 0); - - uint16 objDataOffset = (uint8 *)objData - getSegment(data.word(kSetdat)).ptr(0, 0); - assert(objDataOffset % sizeof(SetObject) == 0); - assert(objDataOffset < 128 * sizeof(SetObject)); - sprite->setObjData(objDataOffset); - if (priority == 255) - priority = 0; - sprite->priority = priority; - sprite->type = type; - sprite->b16 = 0; - sprite->delay = 0; - sprite->animFrame = 0; -} - -uint16 DreamGenContext::allocateAndLoad(unsigned int size) { +uint16 DreamBase::allocateAndLoad(unsigned int size) { // allocatemem adds 32 bytes, so it doesn't matter that size/16 rounds down uint16 result = allocateMem(size / 16); engine->readFromFile(getSegment(result).ptr(0, size), size); return result; } -void DreamGenContext::clearAndLoad(uint8 *buf, uint8 c, +void DreamBase::clearAndLoad(uint8 *buf, uint8 c, unsigned int size, unsigned int maxSize) { assert(size <= maxSize); memset(buf, c, maxSize); engine->readFromFile(buf, size); } -void DreamGenContext::clearAndLoad(uint16 seg, uint8 c, +void DreamBase::clearAndLoad(uint16 seg, uint8 c, unsigned int size, unsigned int maxSize) { assert(size <= maxSize); uint8 *buf = getSegment(seg).ptr(0, maxSize); @@ -1166,7 +1067,6 @@ void DreamGenContext::startLoading(const Room &room) { data.byte(kLiftpath) = room.liftPath; data.byte(kDoorpath) = room.doorPath; data.byte(kLastweapon) = (uint8)-1; - ah = data.byte(kReallocation); data.byte(kReallocation) = room.realLocation; loadRoomData(room, false); @@ -1176,10 +1076,6 @@ void DreamGenContext::startLoading(const Room &room) { setAllChanges(); autoAppear(); // const Room &newRoom = g_roomData[data.byte(kNewlocation)]; - bx = 0x7fff; // TODO: bx used to be set to the offset of newRoom - // It seems to be unused (like newRoom itself), but set it - // to an invalid value to catch any missed use of it. - // (The push/pop of bx below is likely also unnecessary) data.byte(kLastweapon) = (uint8)-1; data.byte(kMandead) = 0; data.word(kLookcounter) = 160; @@ -1187,14 +1083,12 @@ void DreamGenContext::startLoading(const Room &room) { data.byte(kLinepointer) = 254; if (room.b27 != 255) { data.byte(kManspath) = room.b27; - push(bx); autoSetWalk(); - bx = pop(); } findXYFromPath(); } -void DreamGenContext::dealWithSpecial(uint8 firstParam, uint8 secondParam) { +void DreamBase::dealWithSpecial(uint8 firstParam, uint8 secondParam) { uint8 type = firstParam - 220; if (type == 0) { placeSetObject(secondParam); @@ -1203,12 +1097,10 @@ void DreamGenContext::dealWithSpecial(uint8 firstParam, uint8 secondParam) { removeSetObject(secondParam); data.byte(kHavedoneobs) = 1; } else if (type == 2) { - al = secondParam; - placeFreeObject(); + placeFreeObject(secondParam); data.byte(kHavedoneobs) = 1; } else if (type == 3) { - al = secondParam; - removeFreeObject(); + removeFreeObject(secondParam); data.byte(kHavedoneobs) = 1; } else if (type == 4) { switchRyanOff(); @@ -1223,11 +1115,11 @@ void DreamGenContext::dealWithSpecial(uint8 firstParam, uint8 secondParam) { } } -void DreamGenContext::plotReel() { - Reel *reel = getReelStart(); +void DreamBase::plotReel(uint16 &reelPointer) { + Reel *reel = getReelStart(reelPointer); while (reel->x >= 220 && reel->x != 255) { dealWithSpecial(reel->x, reel->y); - ++data.word(kReelpointer); + ++reelPointer; reel += 8; } @@ -1236,11 +1128,7 @@ void DreamGenContext::plotReel() { showReelFrame(reel); ++reel; } - push(es); - push(bx); - soundOnReels(); - bx = pop(); - es = pop(); + soundOnReels(reelPointer); } void DreamBase::crosshair() { @@ -1253,7 +1141,7 @@ void DreamBase::crosshair() { showFrame(engine->icons1(), kZoomx + 24, kZoomy + 19, frame, 0); } -void DreamGenContext::delTextLine() { +void DreamBase::delTextLine() { uint16 x = data.word(kTextaddressx); uint16 y = data.word(kTextaddressy); if (data.byte(kForeignrelease) != 0) @@ -1262,10 +1150,10 @@ void DreamGenContext::delTextLine() { } void DreamGenContext::commandOnly() { - commandOnly(al); + commandOnly(al); } -void DreamGenContext::commandOnly(uint8 command) { +void DreamBase::commandOnly(uint8 command) { delTextLine(); uint16 index = command * 2; uint16 offset = kTextstart + getSegment(data.word(kCommandtext)).word(index); @@ -1285,8 +1173,7 @@ bool DreamGenContext::checkIfPerson(uint8 x, uint8 y) { for (size_t i = 0; i < 12; ++i, ++people) { if (people->b4 == 255) continue; - data.word(kReelpointer) = people->reelPointer(); - Reel *reel = getReelStart(); + Reel *reel = getReelStart(people->reelPointer()); if (reel->frame() == 0xffff) ++reel; const Frame *frame = getReelFrameAX(reel->frame()); @@ -1341,7 +1228,7 @@ bool DreamGenContext::checkIfEx(uint8 x, uint8 y) { return false; } -const uint8 *DreamGenContext::findObName(uint8 type, uint8 index) { +const uint8 *DreamBase::findObName(uint8 type, uint8 index) { if (type == 5) { uint16 i = 64 * 2 * (index & 127); uint16 offset = getSegment(data.word(kPeople)).word(kPersontxtdat + i) + kPersontext; @@ -1361,11 +1248,7 @@ const uint8 *DreamGenContext::findObName(uint8 type, uint8 index) { } } -void DreamGenContext::copyName() { - copyName(ah, al, data.ptr(di, 0)); -} - -void DreamGenContext::copyName(uint8 type, uint8 index, uint8 *dst) { +void DreamBase::copyName(uint8 type, uint8 index, uint8 *dst) { const uint8 *src = findObName(type, index); size_t i; for (i = 0; i < 28; ++i) { @@ -1416,14 +1299,7 @@ void DreamGenContext::walkToText() { commandWithOb(3, data.byte(kCommandtype), data.byte(kCommand)); } -void DreamGenContext::findOrMake() { - uint8 b0 = al; - uint8 b2 = cl; - uint8 b3 = ch; - findOrMake(b0, b2, b3); -} - -void DreamGenContext::findOrMake(uint8 index, uint8 value, uint8 type) { +void DreamBase::findOrMake(uint8 index, uint8 value, uint8 type) { Change *change = (Change *)getSegment(data.word(kBuffers)).ptr(kListofchanges, sizeof(Change)); for (; change->index != 0xff; ++change) { if (index == change->index && data.byte(kReallocation) == change->location && type == change->type) { @@ -1445,41 +1321,45 @@ void DreamGenContext::setAllChanges() { doChange(change->index, change->value, change->type); } -DynObject *DreamGenContext::getFreeAd(uint8 index) { +DynObject *DreamBase::getFreeAd(uint8 index) { return (DynObject *)getSegment(data.word(kFreedat)).ptr(0, 0) + index; } -DynObject *DreamGenContext::getExAd(uint8 index) { +DynObject *DreamBase::getExAd(uint8 index) { return (DynObject *)getSegment(data.word(kExtras)).ptr(kExdata, 0) + index; } -DynObject *DreamGenContext::getEitherAdCPP() { - if (data.byte(kObjecttype) == 4) +DynObject *DreamBase::getEitherAdCPP() { + if (data.byte(kObjecttype) == kExObjectType) return getExAd(data.byte(kItemframe)); else return getFreeAd(data.byte(kItemframe)); } -void *DreamGenContext::getAnyAd(uint8 *value1, uint8 *value2) { - if (data.byte(kObjecttype) == 4) { +void *DreamBase::getAnyAd(uint8 *value1, uint8 *value2) { + if (data.byte(kObjecttype) == kExObjectType) { DynObject *exObject = getExAd(data.byte(kCommand)); - *value1 = exObject->b7; - *value2 = exObject->b8; + *value1 = exObject->slotSize; + *value2 = exObject->slotCount; return exObject; - } else if (data.byte(kObjecttype) == 2) { + } else if (data.byte(kObjecttype) == kFreeObjectType) { DynObject *freeObject = getFreeAd(data.byte(kCommand)); - *value1 = freeObject->b7; - *value2 = freeObject->b8; + *value1 = freeObject->slotSize; + *value2 = freeObject->slotCount; return freeObject; - } else { + } else { // 1 or 3. 0 should never happen SetObject *setObject = getSetAd(data.byte(kCommand)); - *value1 = setObject->b4; - *value2 = setObject->priority; + // Note: the original returned slotCount/priority (bytes 4 and 5) + // instead of slotSize/slotCount (bytes 3 and 4). + // Changed this for consistency with the Ex/Free cases, and also + // with getOpenedSize() + *value1 = setObject->slotSize; + *value2 = setObject->slotCount; return setObject; } } -void *DreamGenContext::getAnyAdDir(uint8 index, uint8 flag) { +void *DreamBase::getAnyAdDir(uint8 index, uint8 flag) { if (flag == 4) return getExAd(index); else if (flag == 2) @@ -1488,11 +1368,11 @@ void *DreamGenContext::getAnyAdDir(uint8 index, uint8 flag) { return getSetAd(index); } -SetObject *DreamGenContext::getSetAd(uint8 index) { +SetObject *DreamBase::getSetAd(uint8 index) { return (SetObject *)getSegment(data.word(kSetdat)).ptr(0, 0) + index; } -void DreamGenContext::doChange(uint8 index, uint8 value, uint8 type) { +void DreamBase::doChange(uint8 index, uint8 value, uint8 type) { if (type == 0) { //object getSetAd(index)->mapad[0] = value; } else if (type == 1) { //freeObject @@ -1500,16 +1380,16 @@ void DreamGenContext::doChange(uint8 index, uint8 value, uint8 type) { if (freeObject->mapad[0] == 0xff) freeObject->mapad[0] = value; } else { //path - bx = kPathdata + (type - 100) * 144 + index * 8; - es = data.word(kReels); - es.byte(bx+6) = value; +// getSegment(data.word(kReels)).byte(kPathdata + (type - 100) * 144 + index * 8 + 6) = value; + PathNode *paths = (PathNode *)getSegment(data.word(kReels)).ptr(kPathdata + 144 * (type - 100), 0); + paths[index].on = value; } } void DreamGenContext::deleteTaken() { const DynObject *extraObjects = (const DynObject *)getSegment(data.word(kExtras)).ptr(kExdata, 0); DynObject *freeObjects = (DynObject *)getSegment(data.word(kFreedat)).ptr(0, 0); - for(size_t i = 0; i < kNumexobjects; ++i) { + for (size_t i = 0; i < kNumexobjects; ++i) { uint8 location = extraObjects[i].initialLocation; if (location == data.byte(kReallocation)) { uint8 index = extraObjects[i].index; @@ -1532,20 +1412,12 @@ void DreamGenContext::getExPos() { di = kExdata + kNumexobjects * sizeof(DynObject); } -void DreamGenContext::placeSetObject() { - placeSetObject(al); -} - -void DreamGenContext::placeSetObject(uint8 index) { +void DreamBase::placeSetObject(uint8 index) { findOrMake(index, 0, 0); getSetAd(index)->mapad[0] = 0; } -void DreamGenContext::removeSetObject() { - removeSetObject(al); -} - -void DreamGenContext::removeSetObject(uint8 index) { +void DreamBase::removeSetObject(uint8 index) { findOrMake(index, 0xff, 0); getSetAd(index)->mapad[0] = 0xff; } @@ -1558,18 +1430,10 @@ bool DreamGenContext::finishedWalkingCPP() { return (data.byte(kLinepointer) == 254) && (data.byte(kFacing) == data.byte(kTurntoface)); } -void DreamGenContext::getFlagUnderP() { - uint8 flag, flagEx; - getFlagUnderP(&flag, &flagEx); - cl = flag; - ch = flagEx; -} - -void DreamGenContext::getFlagUnderP(uint8 *flag, uint8 *flagEx) { +void DreamBase::getFlagUnderP(uint8 *flag, uint8 *flagEx) { uint8 type, flagX, flagY; checkOne(data.word(kMousex) - data.word(kMapadx), data.word(kMousey) - data.word(kMapady), flag, flagEx, &type, &flagX, &flagY); - cl = data.byte(kLastflag) = *flag; - ch = data.byte(kLastflagex) = *flagEx; + data.byte(kLastflag) = *flag; } void DreamGenContext::walkAndExamine() { @@ -1644,7 +1508,8 @@ void DreamGenContext::obName(uint8 command, uint8 commandType) { } } - getFlagUnderP(); + uint8 flag, flagEx; + getFlagUnderP(&flag, &flagEx); if (data.byte(kLastflag) < 2) { blockNameText(); return; @@ -1657,7 +1522,7 @@ void DreamGenContext::obName(uint8 command, uint8 commandType) { } } -void DreamGenContext::delPointer() { +void DreamBase::delPointer() { if (data.word(kOldpointerx) == 0xffff) return; data.word(kDelherex) = data.word(kOldpointerx); @@ -1705,79 +1570,6 @@ void DreamBase::dumpPointer() { multiDump(data.word(kOldpointerx), data.word(kOldpointery), data.byte(kPointerxs), data.byte(kPointerys)); } -void DreamGenContext::checkCoords() { - - // FIXME: Move all these lists to the callers - - switch ((uint16)bx) { - case offset_talklist: { - RectWithCallback talkList[] = { - { 273,320,157,198,&DreamGenContext::getBack1 }, - { 240,290,2,44,&DreamGenContext::moreTalk }, - { 0,320,0,200,&DreamGenContext::blank }, - { 0xFFFF,0,0,0,0 } - }; - checkCoords(talkList); - break; - } - case offset_quitlist: { - RectWithCallback quitList[] = { - { 273,320,157,198,&DreamGenContext::getBack1 }, - { 0,320,0,200,&DreamGenContext::blank }, - { 0xFFFF,0,0,0,0 } - }; - checkCoords(quitList); - break; - } - case offset_diarylist: { - RectWithCallback diaryList[] = { - { kDiaryx+94,kDiaryx+110,kDiaryy+97,kDiaryy+113,&DreamGenContext::diaryKeyN }, - { kDiaryx+151,kDiaryx+167,kDiaryy+71,kDiaryy+87,&DreamGenContext::diaryKeyP }, - { kDiaryx+176,kDiaryx+192,kDiaryy+108,kDiaryy+124,&DreamGenContext::quitKey }, - { 0,320,0,200,&DreamGenContext::blank }, - { 0xFFFF,0,0,0,0 } - }; - checkCoords(diaryList); - break; - } - case offset_opslist: { - RectWithCallback opsList[] = { - { kOpsx+59,kOpsx+114,kOpsy+30,kOpsy+76,&DreamGenContext::getBackFromOps }, - { kOpsx+10,kOpsx+77,kOpsy+10,kOpsy+59,&DreamGenContext::DOSReturn }, - { kOpsx+128,kOpsx+190,kOpsy+16,kOpsy+100,&DreamGenContext::discOps }, - { 0,320,0,200,&DreamGenContext::blank }, - { 0xFFFF,0,0,0,0 } - }; - checkCoords(opsList); - break; - } - case offset_discopslist: { - RectWithCallback discOpsList[] = { - { kOpsx+59,kOpsx+114,kOpsy+30,kOpsy+76,&DreamGenContext::loadGame }, - { kOpsx+10,kOpsx+79,kOpsy+10,kOpsy+59,&DreamGenContext::saveGame }, - { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamGenContext::getBackToOps }, - { 0,320,0,200,&DreamGenContext::blank }, - { 0xFFFF,0,0,0,0 } - }; - checkCoords(discOpsList); - break; - } - case offset_decidelist: { - RectWithCallback decideList[] = { - { kOpsx+69,kOpsx+124,kOpsy+30,kOpsy+76,&DreamGenContext::newGame }, - { kOpsx+20,kOpsx+87,kOpsy+10,kOpsy+59,&DreamGenContext::DOSReturn }, - { kOpsx+123,kOpsx+190,kOpsy+10,kOpsy+59,&DreamGenContext::loadOld }, - { 0,320,0,200,&DreamGenContext::blank }, - { 0xFFFF,0,0,0,0 } - }; - checkCoords(decideList); - break; - } - default: - ::error("Unimplemented checkcoords() call"); - } -} - void DreamGenContext::checkCoords(const RectWithCallback *rectWithCallbacks) { if (data.byte(kNewlocation) != 0xff) return; @@ -1791,7 +1583,7 @@ void DreamGenContext::checkCoords(const RectWithCallback *rectWithCallbacks) { } } -void DreamGenContext::showPointer() { +void DreamBase::showPointer() { showBlink(); uint16 x = data.word(kMousex); data.word(kOldpointerx) = data.word(kMousex); @@ -1799,7 +1591,7 @@ void DreamGenContext::showPointer() { data.word(kOldpointery) = data.word(kMousey); if (data.byte(kPickup) == 1) { const Frame *frames; - if (data.byte(kObjecttype) != 4) + if (data.byte(kObjecttype) != kExObjectType) frames = (const Frame *)getSegment(data.word(kFreeframes)).ptr(0, 0); else frames = (const Frame *)getSegment(data.word(kExtras)).ptr(0, 0); @@ -1834,7 +1626,7 @@ void DreamGenContext::showPointer() { } } -void DreamGenContext::animPointer() { +void DreamBase::animPointer() { if (data.byte(kPointermode) == 2) { data.byte(kPointerframe) = 0; @@ -1888,14 +1680,28 @@ void DreamGenContext::animPointer() { data.byte(kPointerframe) = 8; } -void DreamGenContext::printMessage() { - printMessage(di, bx, al, dl, (bool)(dl & 1)); +void DreamBase::printMessage(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered) { + uint16 offset = kTextstart + getSegment(data.word(kCommandtext)).word(index * 2); + const uint8 *string = getSegment(data.word(kCommandtext)).ptr(offset, 0); + printDirect(string, x, y, maxWidth, centered); } -void DreamGenContext::printMessage(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered) { +void DreamBase::printMessage2(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered, uint8 count) { uint16 offset = kTextstart + getSegment(data.word(kCommandtext)).word(index * 2); const uint8 *string = getSegment(data.word(kCommandtext)).ptr(offset, 0); - printDirect(&string, x, &y, maxWidth, centered); + while (count--) { + findNextColon(&string); + } + printDirect(string, x, y, maxWidth, centered); +} + +static bool objectMatches(void *object, const char *id) { + const char *objId = (const char *)(((const uint8 *)object) + 12); // whether it is a DynObject or a SetObject + for (size_t i = 0; i < 4; ++i) { + if (id[i] != objId[i] + 'A') + return false; + } + return true; } void DreamGenContext::compare() { @@ -1903,23 +1709,67 @@ void DreamGenContext::compare() { flags._z = compare(al, ah, id); } -bool DreamGenContext::compare(uint8 index, uint8 flag, const char id[4]) { - void *ptr = getAnyAdDir(index, flag); - const char *objId = (const char *)(((const uint8 *)ptr) + 12); // whether it is a DynObject or a SetObject - for (size_t i = 0; i < 4; ++i) { - if(id[i] != objId[i] + 'A') - return false; +bool DreamBase::compare(uint8 index, uint8 flag, const char id[4]) { + return objectMatches(getAnyAdDir(index, flag), id); +} + +uint16 DreamBase::findSetObject(const char *id) { + for (uint16 index = 0; index < 128; index++) { + if (objectMatches(getSetAd(index), id)) + return index; } - return true; + + return 128; +} + +void DreamGenContext::findExObject() { + char id[5]; + id[0] = al; + id[1] = ah; + id[2] = cl; + id[3] = ch; + id[4] = '\0'; + al = findExObject(id); + es = data.word(kExtras); + bx = kExdata + al * 16; +} + +uint16 DreamBase::findExObject(const char *id) { + for (uint16 index = 0; index < kNumexobjects; index++) { + if (objectMatches(getExAd(index), id)) + return index; + } + + return kNumexobjects; +} + +void DreamGenContext::isRyanHolding() { + char id[5]; + id[0] = al; + id[1] = ah; + id[2] = cl; + id[3] = ch; + id[4] = '\0'; + flags._z = !isRyanHolding(id); +} + +bool DreamBase::isRyanHolding(const char *id) { + for (uint16 index = 0; index < kNumexobjects; index++) { + DynObject *object = getExAd(index); + if (object->mapad[0] == 4 && objectMatches(object, id)) + return true; + } + + return false; } -bool DreamGenContext::isItDescribed(const ObjPos *pos) { +bool DreamBase::isItDescribed(const ObjPos *pos) { uint16 offset = getSegment(data.word(kSetdesc)).word(kSettextdat + pos->index * 2); uint8 result = getSegment(data.word(kSetdesc)).byte(kSettext + offset); return result != 0; } -bool DreamGenContext::isCD() { +bool DreamBase::isCD() { // The original sources has two codepaths depending if the game is 'if cd' or not // This is a hack to guess which version to use with the assumption that if we have a cd version // we managed to load the speech. At least it is isolated in this function and can be changed. @@ -1927,7 +1777,7 @@ bool DreamGenContext::isCD() { return (data.byte(kSpeechloaded) == 1); } -void DreamGenContext::showIcon() { +void DreamBase::showIcon() { if (data.byte(kReallocation) < 50) { showPanel(); showMan(); @@ -1966,35 +1816,11 @@ bool DreamGenContext::checkIfSet(uint8 x, uint8 y) { return false; } -void DreamBase::showRyanPage() { - showFrame(engine->icons1(), kInventx + 167, kInventy - 12, 12, 0); - showFrame(engine->icons1(), kInventx + 167 + 18 * data.byte(kRyanpage), kInventy - 12, 13 + data.byte(kRyanpage), 0); -} - -void DreamGenContext::findAllRyan() { - findAllRyan(es.ptr(di, 60)); -} - -void DreamGenContext::findAllRyan(uint8 *inv) { - memset(inv, 0xff, 60); - for (size_t i = 0; i < kNumexobjects; ++i) { - DynObject *extra = getExAd(i); - if (extra->mapad[0] != 4) - continue; - if (extra->mapad[1] != 0xff) - continue; - uint8 slot = extra->mapad[2]; - assert(slot < 30); - inv[2 * slot + 0] = i; - inv[2 * slot + 1] = 4; - } -} - void DreamGenContext::hangOn() { hangOn(cx); } -void DreamGenContext::hangOn(uint16 frameCount) { +void DreamBase::hangOn(uint16 frameCount) { while (frameCount) { vSync(); --frameCount; @@ -2003,11 +1829,7 @@ void DreamGenContext::hangOn(uint16 frameCount) { } } -void DreamGenContext::hangOnW() { - hangOnW(cx); -} - -void DreamGenContext::hangOnW(uint16 frameCount) { +void DreamBase::hangOnW(uint16 frameCount) { while (frameCount) { delPointer(); readMouse(); @@ -2025,7 +1847,7 @@ void DreamGenContext::hangOnP() { hangOnP(cx); } -void DreamGenContext::hangOnP(uint16 count) { +void DreamBase::hangOnP(uint16 count) { data.word(kMaintimer) = 0; uint8 pointerFrame = data.byte(kPointerframe); uint8 pickup = data.byte(kPickup); @@ -2059,13 +1881,13 @@ void DreamGenContext::hangOnP(uint16 count) { } void DreamGenContext::findNextColon() { - uint8 *initialString = es.ptr(si, 0); - uint8 *string = initialString; + const uint8 *initialString = es.ptr(si, 0); + const uint8 *string = initialString; al = findNextColon(&string); si += (string - initialString); } -uint8 DreamGenContext::findNextColon(uint8 **string) { +uint8 DreamBase::findNextColon(const uint8 **string) { uint8 c; do { c = **string; @@ -2074,11 +1896,11 @@ uint8 DreamGenContext::findNextColon(uint8 **string) { return c; } -uint8 *DreamGenContext::getObTextStartCPP() { +const uint8 *DreamGenContext::getObTextStartCPP() { push(es); push(si); getObTextStart(); - uint8 *result = es.ptr(si, 0); + const uint8 *result = es.ptr(si, 0); si = pop(); es = pop(); return result; @@ -2109,12 +1931,12 @@ void DreamGenContext::enterSymbol() { dumpTextLine(); dumpSymbol(); RectWithCallback symbolList[] = { - { kSymbolx+40,kSymbolx+64,kSymboly+2,kSymboly+16,&DreamGenContext::quitSymbol }, - { kSymbolx,kSymbolx+52,kSymboly+20,kSymboly+50,&DreamGenContext::setTopLeft }, - { kSymbolx+52,kSymbolx+104,kSymboly+20,kSymboly+50,&DreamGenContext::setTopRight }, - { kSymbolx,kSymbolx+52,kSymboly+50,kSymboly+80,&DreamGenContext::setBotLeft }, - { kSymbolx+52,kSymbolx+104,kSymboly+50,kSymboly+80,&DreamGenContext::setBotRight }, - { 0,320,0,200,&DreamGenContext::blank }, + { kSymbolx+40,kSymbolx+64,kSymboly+2,kSymboly+16,&DreamBase::quitSymbol }, + { kSymbolx,kSymbolx+52,kSymboly+20,kSymboly+50,&DreamBase::setTopLeft }, + { kSymbolx+52,kSymbolx+104,kSymboly+20,kSymboly+50,&DreamBase::setTopRight }, + { kSymbolx,kSymbolx+52,kSymboly+50,kSymboly+80,&DreamBase::setBotLeft }, + { kSymbolx+52,kSymbolx+104,kSymboly+50,kSymboly+80,&DreamBase::setBotRight }, + { 0,320,0,200,&DreamBase::blank }, { 0xFFFF,0,0,0,0 } }; checkCoords(symbolList); @@ -2169,7 +1991,7 @@ void DreamGenContext::zoomOnOff() { workToScreenM(); } -void DreamGenContext::sortOutMap() { +void DreamBase::sortOutMap() { const uint8 *src = workspace(); uint8 *dst = (uint8 *)getSegment(data.word(kMapdata)).ptr(0, 0); for (uint16 y = 0; y < kMaplength; ++y) { @@ -2215,7 +2037,7 @@ void DreamGenContext::mainScreen() { walkAndExamine(); } -void DreamGenContext::showWatch() { +void DreamBase::showWatch() { if (data.byte(kWatchon)) { showFrame(engine->icons1(), 250, 1, 6, 0); showTime(); @@ -2229,7 +2051,7 @@ void DreamGenContext::dumpWatch() { data.byte(kWatchdump) = 0; } -void DreamGenContext::showTime() { +void DreamBase::showTime() { if (data.byte(kWatchon) == 0) return; Frame *charset = (Frame *)getSegment(data.word(kCharset1)).ptr(0, 0); @@ -2275,7 +2097,7 @@ void DreamGenContext::watchCount() { } } -void DreamGenContext::roomName() { +void DreamBase::roomName() { printMessage(88, 18, 53, 240, false); uint16 textIndex = data.byte(kRoomnum); if (textIndex >= 32) @@ -2289,7 +2111,7 @@ void DreamGenContext::roomName() { useCharset1(); } -void DreamGenContext::zoomIcon() { +void DreamBase::zoomIcon() { if (data.byte(kZoomon) == 0) return; showFrame(engine->icons1(), kZoomx, kZoomy-1, 8, 0); @@ -2310,25 +2132,14 @@ void DreamGenContext::loadRoom() { loadRoomsSample(); switchRyanOn(); drawFlags(); - getDimension(); -} - -void DreamGenContext::loadRoomsSample() { - uint8 sample = data.byte(kRoomssample); - - if (sample == 255 || data.byte(kCurrentsample) == sample) - return; // loaded already - - assert(sample < 100); - Common::String sampleName = Common::String::format("DREAMWEB.V%02d", sample); - uint8 ch0 = data.byte(kCh0playing); - if (ch0 >= 12 && ch0 != 255) - cancelCh0(); - uint8 ch1 = data.byte(kCh1playing); - if (ch1 >= 12) - cancelCh1(); - engine->loadSounds(1, sampleName.c_str()); + uint8 mapXstart, mapYstart; + uint8 mapXsize, mapYsize; + getDimension(&mapXstart, &mapYstart, &mapXsize, &mapYsize); + cl = mapXstart; + ch = mapYstart; + dl = mapXsize; + dh = mapYsize; } void DreamGenContext::readSetData() { @@ -2343,91 +2154,27 @@ void DreamGenContext::readSetData() { data.word(kPuzzletext) = standardLoad("DREAMWEB.T80"); data.word(kCommandtext) = standardLoad("DREAMWEB.T84"); useCharset1(); - if (data.byte(kSoundint) == 0xff) - return; + // FIXME: Why is this commented out? //engine->openFile("DREAMWEB.VOL"); //uint8 *volumeTab = getSegment(data.word(kSoundbuffer)).ptr(16384, 0); //engine->readFromFile(volumeTab, 2048-256); //engine->closeFile(); } -Frame * DreamGenContext::tempGraphics() { +Frame * DreamBase::tempGraphics() { return (Frame *)getSegment(data.word(kTempgraphics)).ptr(0, 0); } -Frame * DreamGenContext::tempGraphics2() { +Frame * DreamBase::tempGraphics2() { return (Frame *)getSegment(data.word(kTempgraphics2)).ptr(0, 0); } -Frame * DreamGenContext::tempGraphics3() { +Frame * DreamBase::tempGraphics3() { return (Frame *)getSegment(data.word(kTempgraphics3)).ptr(0, 0); } -void DreamBase::volumeAdjust() { - if (data.byte(kVolumedirection) == 0) - return; - if (data.byte(kVolume) != data.byte(kVolumeto)) { - data.byte(kVolumecount) += 64; - // Only modify the volume every 256/64 = 4th time around - if (data.byte(kVolumecount) == 0) - data.byte(kVolume) += data.byte(kVolumedirection); - } else { - data.byte(kVolumedirection) = 0; - } -} - -void DreamGenContext::playChannel0(uint8 index, uint8 repeat) { - if (data.byte(kSoundint) == 255) - return; - - data.byte(kCh0playing) = index; - Sound *soundBank; - if (index >= 12) { - soundBank = (Sound *)getSegment(data.word(kSounddata2)).ptr(0, 0); - index -= 12; - } else - soundBank = (Sound *)getSegment(data.word(kSounddata)).ptr(0, 0); - - data.byte(kCh0repeat) = repeat; - data.word(kCh0emmpage) = soundBank[index].emmPage; - data.word(kCh0offset) = soundBank[index].offset(); - data.word(kCh0blockstocopy) = soundBank[index].blockCount(); - if (repeat) { - data.word(kCh0oldemmpage) = data.word(kCh0emmpage); - data.word(kCh0oldoffset) = data.word(kCh0offset); - data.word(kCh0oldblockstocopy) = data.word(kCh0blockstocopy); - } -} - -void DreamGenContext::playChannel0() { - playChannel0(al, ah); -} - -void DreamGenContext::playChannel1(uint8 index) { - if (data.byte(kSoundint) == 255) - return; - if (data.byte(kCh1playing) == 7) - return; - - data.byte(kCh1playing) = index; - Sound *soundBank; - if (index >= 12) { - soundBank = (Sound *)getSegment(data.word(kSounddata2)).ptr(0, 0); - index -= 12; - } else - soundBank = (Sound *)getSegment(data.word(kSounddata)).ptr(0, 0); - - data.word(kCh1emmpage) = soundBank[index].emmPage; - data.word(kCh1offset) = soundBank[index].offset(); - data.word(kCh1blockstocopy) = soundBank[index].blockCount(); -} - -void DreamGenContext::playChannel1() { - playChannel1(al); -} - -void DreamGenContext::findRoomInLoc() { +void DreamBase::findRoomInLoc() { uint8 x = data.byte(kMapx) / 11; uint8 y = data.byte(kMapy) / 10; uint8 roomNum = y * 6 + x; @@ -2470,7 +2217,7 @@ void DreamGenContext::doLook() { dumpTextLine(); uint8 index = data.byte(kRoomnum) & 31; uint16 offset = getSegment(data.word(kRoomdesc)).word(kIntextdat + index * 2); - uint8 *string = getSegment(data.word(kRoomdesc)).ptr(kIntext, 0) + offset; + const uint8 *string = getSegment(data.word(kRoomdesc)).ptr(kIntext, 0) + offset; findNextColon(&string); uint16 x; if (data.byte(kReallocation) < 50) @@ -2486,39 +2233,39 @@ void DreamGenContext::doLook() { workToScreenM(); } -void DreamGenContext::useCharset1() { +void DreamBase::useCharset1() { engine->setCurrentCharset((Frame *)getSegment(data.word(kCharset1)).ptr(0, 0)); } -void DreamGenContext::useTempCharset() { +void DreamBase::useTempCharset() { engine->setCurrentCharset(engine->tempCharset()); } -void DreamGenContext::getRidOfTemp() { +void DreamBase::getRidOfTemp() { deallocateMem(data.word(kTempgraphics)); } -void DreamGenContext::getRidOfTempText() { +void DreamBase::getRidOfTempText() { deallocateMem(data.word(kTextfile1)); } -void DreamGenContext::getRidOfTemp2() { +void DreamBase::getRidOfTemp2() { deallocateMem(data.word(kTempgraphics2)); } -void DreamGenContext::getRidOfTemp3() { +void DreamBase::getRidOfTemp3() { deallocateMem(data.word(kTempgraphics3)); } -void DreamGenContext::getRidOfTempCharset() { +void DreamBase::getRidOfTempCharset() { engine->freeTempCharset(); } -void DreamGenContext::getRidOfTempsP() { +void DreamBase::getRidOfTempsP() { deallocateMem(data.word(kTempsprites)); } -void DreamGenContext::getRidOfAll() { +void DreamBase::getRidOfAll() { deallocateMem(data.word(kBackdrop)); deallocateMem(data.word(kSetframes)); deallocateMem(data.word(kReel1)); @@ -2534,10 +2281,8 @@ void DreamGenContext::getRidOfAll() { } // if skipDat, skip clearing and loading Setdat and Freedat -void DreamGenContext::loadRoomData(const Room &room, bool skipDat) { +void DreamBase::loadRoomData(const Room &room, bool skipDat) { engine->openFile(room.name); - data.word(kHandle) = 1; //only one handle - flags._c = false; FileHeader header; engine->readFromFile((uint8 *)&header, sizeof(FileHeader)); @@ -2573,7 +2318,7 @@ void DreamGenContext::loadRoomData(const Room &room, bool skipDat) { engine->skipBytes(len[13]); data.word(kFreedesc) = allocateAndLoad(len[14]); - closeFile(); + engine->closeFile(); } void DreamGenContext::restoreAll() { @@ -2582,15 +2327,13 @@ void DreamGenContext::restoreAll() { setAllChanges(); } -void DreamGenContext::restoreReels() { +void DreamBase::restoreReels() { if (data.byte(kRoomloaded) == 0) return; const Room &room = g_roomData[data.byte(kReallocation)]; engine->openFile(room.name); - data.word(kHandle) = 1; //only one handle - flags._c = false; FileHeader header; engine->readFromFile((uint8 *)&header, sizeof(FileHeader)); @@ -2608,10 +2351,10 @@ void DreamGenContext::restoreReels() { data.word(kReel2) = allocateAndLoad(len[5]); data.word(kReel3) = allocateAndLoad(len[6]); - closeFile(); + engine->closeFile(); } -void DreamGenContext::loadFolder() { +void DreamBase::loadFolder() { loadIntoTemp("DREAMWEB.G09"); // folder graphics 1 loadIntoTemp2("DREAMWEB.G10"); // folder graphics 2 loadIntoTemp3("DREAMWEB.G11"); // folder graphics 3 @@ -2619,7 +2362,7 @@ void DreamGenContext::loadFolder() { loadTempText("DREAMWEB.T50"); // folder text } -void DreamGenContext::showFolder() { +void DreamBase::showFolder() { data.byte(kCommandtype) = 255; if (data.byte(kFolderpage)) { useTempCharset(); @@ -2644,7 +2387,7 @@ void DreamGenContext::showFolder() { } } -void DreamGenContext::showLeftPage() { +void DreamBase::showLeftPage() { showFrame(tempGraphics2(), 0, 12, 3, 0); uint16 y = 12+5; for (size_t i = 0; i < 9; ++i) { @@ -2677,7 +2420,7 @@ void DreamGenContext::showLeftPage() { } } -void DreamGenContext::showRightPage() { +void DreamBase::showRightPage() { showFrame(tempGraphics2(), 143, 12, 0, 0); uint16 y = 12+37; for (size_t i = 0; i < 7; ++i) { @@ -2702,18 +2445,18 @@ void DreamGenContext::showRightPage() { data.word(kLinespacing) = 10; } -void DreamGenContext::showExit() { +void DreamBase::showExit() { showFrame(engine->icons1(), 274, 154, 11, 0); } -void DreamGenContext::showMan() { +void DreamBase::showMan() { showFrame(engine->icons1(), 0, 0, 0, 0); showFrame(engine->icons1(), 0, 114, 1, 0); if (data.byte(kShadeson)) showFrame(engine->icons1(), 28, 25, 2, 0); } -void DreamGenContext::panelIcons1() { +void DreamBase::panelIcons1() { uint16 x; if (data.byte(kWatchon) != 1) x = 48; @@ -2725,38 +2468,31 @@ void DreamGenContext::panelIcons1() { showWatch(); } -void DreamGenContext::examIcon() { +void DreamBase::examIcon() { showFrame(engine->icons2(), 254, 5, 3, 0); } -uint8 DreamGenContext::getLocation(uint8 index) { +uint8 DreamBase::getLocation(uint8 index) { return data.byte(kRoomscango + index); } -void DreamGenContext::getLocation() { - al = getLocation(al); -} - -void DreamGenContext::setLocation(uint8 index) { +void DreamBase::setLocation(uint8 index) { data.byte(kRoomscango + index) = 1; } -void DreamGenContext::setLocation() { - setLocation(al); -} - -const uint8 *DreamGenContext::getTextInFile1(uint16 index) { - uint16 offset = getSegment(data.word(kTextfile1)).word(index * 2) + kTextstart; - const uint8 *string = getSegment(data.word(kTextfile1)).ptr(offset, 0); +const uint8 *DreamBase::getTextInFile1(uint16 index) { + SegmentRef text = getSegment(data.word(kTextfile1)); + uint16 offset = text.word(index * 2) + kTextstart; + const uint8 *string = text.ptr(offset, 0); return string; } void DreamGenContext::checkFolderCoords() { RectWithCallback folderList[] = { - { 280,320,160,200, &DreamGenContext::quitKey }, + { 280,320,160,200, &DreamBase::quitKey }, { 143,300,6,194, &DreamGenContext::nextFolder }, { 0,143,6,194, &DreamGenContext::lastFolder }, - { 0,320,0,200, &DreamGenContext::blank }, + { 0,320,0,200, &DreamBase::blank }, { 0xFFFF,0,0,0, 0 } }; checkCoords(folderList); @@ -2802,7 +2538,7 @@ void DreamGenContext::lastFolder() { } } -void DreamGenContext::folderHints() { +void DreamBase::folderHints() { if (data.byte(kFolderpage) == 5) { if ((data.byte(kAidedead) != 1) && (getLocation(13) != 1)) { setLocation(13); @@ -2824,23 +2560,19 @@ void DreamGenContext::folderHints() { } } -void DreamGenContext::folderExit() { +void DreamBase::folderExit() { showFrame(tempGraphics2(), 296, 178, 6, 0); } -void DreamGenContext::loadTravelText() { +void DreamBase::loadTravelText() { data.word(kTraveltext) = standardLoad("DREAMWEB.T81"); // location descs } -void DreamGenContext::loadTempText() { - loadTempText((const char *)data.ptr(dx, 0)); -} - -void DreamGenContext::loadTempText(const char *fileName) { +void DreamBase::loadTempText(const char *fileName) { data.word(kTextfile1) = standardLoad(fileName); } -void DreamGenContext::drawFloor() { +void DreamBase::drawFloor() { eraseOldObs(); drawFlags(); calcMapAd(); @@ -2853,7 +2585,7 @@ void DreamGenContext::drawFloor() { data.byte(kNewobs) = 0; } -void DreamGenContext::allocateBuffers() { +void DreamBase::allocateBuffers() { data.word(kExtras) = allocateMem(kLengthofextra/16); data.word(kMapdata) = allocateMem(kLengthofmap/16); data.word(kBuffers) = allocateMem(kLengthofbuffer/16); @@ -2864,28 +2596,28 @@ void DreamGenContext::allocateBuffers() { data.word(kSounddata2) = allocateMem(2048/16); } -void DreamGenContext::workToScreenM() { +void DreamBase::workToScreenM() { animPointer(); readMouse(); showPointer(); vSync(); - workToScreen(); + workToScreenCPP(); delPointer(); } -void DreamGenContext::loadMenu() { +void DreamBase::loadMenu() { loadIntoTemp("DREAMWEB.S02"); // sprite name 3 loadIntoTemp2("DREAMWEB.G07"); // mon. graphics 2 } -void DreamGenContext::showMenu() { +void DreamBase::showMenu() { ++data.byte(kMenucount); if (data.byte(kMenucount) == 37*2) data.byte(kMenucount) = 0; showFrame(tempGraphics(), kMenux, kMenuy, data.byte(kMenucount) / 2, 0); } -void DreamGenContext::dumpMenu() { +void DreamBase::dumpMenu() { multiDump(kMenux, kMenuy, 48, 48); } @@ -2914,8 +2646,8 @@ void DreamGenContext::useMenu() { dumpMenu(); dumpTextLine(); RectWithCallback menuList[] = { - { kMenux+54,kMenux+68,kMenuy+72,kMenuy+88,&DreamGenContext::quitKey }, - { 0,320,0,200,&DreamGenContext::blank }, + { kMenux+54,kMenux+68,kMenuy+72,kMenuy+88,&DreamBase::quitKey }, + { 0,320,0,200,&DreamBase::blank }, { 0xFFFF,0,0,0,0 } }; checkCoords(menuList); @@ -3025,7 +2757,7 @@ void DreamGenContext::showSymbol() { showFrame(tempGraphics(), data.byte(kSymbolbotx) + kSymbolx+54, kSymboly+49, 6 + nextNextBotSymbol, 32); } -void DreamGenContext::readKey() { +void DreamBase::readKey() { uint16 bufOut = data.word(kBufferout); if (bufOut == data.word(kBufferin)) { @@ -3293,7 +3025,7 @@ void DreamGenContext::intro() { clearPalette(); loadIntroRoom(); data.byte(kVolume) = 7; - data.byte(kVolumedirection) = (uint8)-1; + data.byte(kVolumedirection) = (byte)-1; data.byte(kVolumeto) = 4; playChannel0(12, 255); fadeScreenUps(); @@ -3341,7 +3073,7 @@ void DreamGenContext::intro() { data.byte(kLasthardkey) = 0; } -void DreamGenContext::setTopLeft() { +void DreamBase::setTopLeft() { if (data.byte(kSymboltopdir) != 0) { blank(); return; @@ -3356,7 +3088,7 @@ void DreamGenContext::setTopLeft() { data.byte(kSymboltopdir) = 0xFF; } -void DreamGenContext::setTopRight() { +void DreamBase::setTopRight() { if (data.byte(kSymboltopdir) != 0) { blank(); return; @@ -3371,7 +3103,7 @@ void DreamGenContext::setTopRight() { data.byte(kSymboltopdir) = 1; } -void DreamGenContext::setBotLeft() { +void DreamBase::setBotLeft() { if (data.byte(kSymbolbotdir) != 0) { blank(); return; @@ -3386,7 +3118,7 @@ void DreamGenContext::setBotLeft() { data.byte(kSymbolbotdir) = 0xFF; } -void DreamGenContext::setBotRight() { +void DreamBase::setBotRight() { if (data.byte(kSymbolbotdir) != 0) { blank(); return; @@ -3411,14 +3143,14 @@ void DreamGenContext::newGame() { data.byte(kGetback) = 3; } -void DreamGenContext::getBackFromOps() { +void DreamBase::getBackFromOps() { if (data.byte(kMandead) == 2) blank(); else getBack1(); } -void DreamGenContext::getBackToOps() { +void DreamBase::getBackToOps() { if (data.byte(kCommandtype) != 201) { data.byte(kCommandtype) = 201; commandOnly(42); @@ -3434,7 +3166,7 @@ void DreamGenContext::getBackToOps() { void DreamGenContext::pickupOb(uint8 command, uint8 pos) { data.byte(kLastinvpos) = pos; - data.byte(kObjecttype) = 2; + data.byte(kObjecttype) = kFreeObjectType; data.byte(kItemframe) = command; data.byte(kCommand) = command; getAnyAd(); @@ -3485,7 +3217,7 @@ void DreamGenContext::loadIntroRoom() { reelsOnScreen(); spriteUpdate(); printSprites(); - workToScreen(); + workToScreenCPP(); } void DreamGenContext::afterIntroRoom() { @@ -3499,7 +3231,7 @@ void DreamGenContext::afterIntroRoom() { reelsOnScreen(); spriteUpdate(); printSprites(); - workToScreen(); + workToScreenCPP(); data.byte(kNowinnewroom) = 0; } @@ -3509,7 +3241,7 @@ void DreamGenContext::gettingShot() { loadIntroRoom(); fadeScreenUps(); data.byte(kVolumeto) = 0; - data.byte(kVolumedirection) = 0xFF; + data.byte(kVolumedirection) = (byte)-1; runEndSeq(); clearBeforeLoad(); } @@ -3528,13 +3260,7 @@ void DreamGenContext::redrawMainScrn() { data.byte(kCommandtype) = 255; } -void DreamGenContext::selectSlot2() { - if (data.word(kMousebutton)) - data.byte(kLoadingorsave) = 2; - selectSlot(); -} - -void DreamGenContext::blank() { +void DreamBase::blank() { if (data.byte(kCommandtype) != 199) { data.byte(kCommandtype) = 199; commandOnly(0); @@ -3547,7 +3273,7 @@ void DreamGenContext::allPointer() { dumpPointer(); } -void DreamGenContext::makeMainScreen() { +void DreamBase::makeMainScreen() { createPanel(); data.byte(kNewobs) = 1; drawFloor(); @@ -3564,7 +3290,7 @@ void DreamGenContext::makeMainScreen() { data.byte(kManisoffscreen) = 0; } -void DreamGenContext::openInv() { +void DreamBase::openInv() { data.byte(kInvopen) = 1; printMessage(80, 58 - 10, 61, 240, (240 & 1)); fillRyan(); @@ -3572,8 +3298,7 @@ void DreamGenContext::openInv() { } void DreamGenContext::obsThatDoThings() { - char id[4] = { 'M', 'E', 'M', 'B' }; // TODO: convert to string with trailing zero - if (!compare(data.byte(kCommand), data.byte(kObjecttype), id)) + if (!compare(data.byte(kCommand), data.byte(kObjecttype), "MEMB")) return; // notlouiscard if (getLocation(4) != 1) { @@ -3582,6 +3307,34 @@ void DreamGenContext::obsThatDoThings() { } } +void DreamGenContext::describeOb() { + const uint8 *obText = getObTextStartCPP(); + uint16 y = 92; + if (data.byte(kForeignrelease) && data.byte(kObjecttype) == kSetObjectType1) + y = 82; + data.word(kCharshift) = 91 + 91; + printDirect(&obText, 33, &y, 241, 241 & 1); + data.word(kCharshift) = 0; + y = 104; + if (data.byte(kForeignrelease) && data.byte(kObjecttype) == kSetObjectType1) + y = 94; + printDirect(&obText, 36, &y, 241, 241 & 1); + obsThatDoThings(); + + // Additional text + if (compare(data.byte(kCommand), data.byte(kObjecttype), "CUPE")) { + // Empty cup + uint16 offset = kTextstart + getSegment(data.word(kPuzzletext)).word(40 * 2); + const uint8 *string = getSegment(data.word(kPuzzletext)).ptr(offset, 0); + printDirect(string, 36, y + 10, 241, 241 & 1); + } else if (compare(data.byte(kCommand), data.byte(kObjecttype), "CUPF")) { + // Full cup + uint16 offset = kTextstart + getSegment(data.word(kPuzzletext)).word(39 * 2); + const uint8 *string = getSegment(data.word(kPuzzletext)).ptr(offset, 0); + printDirect(string, 36, y + 10, 241, 241 & 1); + } +} + void DreamGenContext::delEverything() { if (data.byte(kMapysize) + data.word(kMapoffsety) < 182) { mapToPanel(); @@ -3598,7 +3351,7 @@ void DreamGenContext::errorMessage1() { printMessage(76, 21, 58, 240, (240 & 1)); readMouse(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); hangOnP(50); showPanel(); @@ -3607,7 +3360,7 @@ void DreamGenContext::errorMessage1() { readMouse(); useOpened(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); } @@ -3617,7 +3370,7 @@ void DreamGenContext::errorMessage2() { printMessage(76, 21, 59, 240, (240 & 1)); readMouse(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); hangOnP(50); showPanel(); @@ -3626,7 +3379,7 @@ void DreamGenContext::errorMessage2() { readMouse(); useOpened(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); } @@ -3641,7 +3394,7 @@ void DreamGenContext::errorMessage3() { readMouse(); useOpened(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); } @@ -3664,7 +3417,7 @@ void DreamGenContext::nextDest() { data.byte(kDestpos) = 0; // last destination getDestInfo(); - } while(al == 0); + } while (al == 0); data.byte(kNewtextline) = 1; delTextLine(); @@ -3676,7 +3429,7 @@ void DreamGenContext::nextDest() { underTextLine(); readMouse(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); } @@ -3695,7 +3448,7 @@ void DreamGenContext::lastDest() { data.byte(kDestpos) = 15; // first destination getDestInfo(); - } while(al == 0); + } while (al == 0); data.byte(kNewtextline) = 1; delTextLine(); @@ -3707,7 +3460,7 @@ void DreamGenContext::lastDest() { underTextLine(); readMouse(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); } @@ -3736,7 +3489,7 @@ void DreamGenContext::putBackObStuff() { data.byte(kCommandtype) = 255; readMouse(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); } @@ -3763,7 +3516,7 @@ void DreamGenContext::redes() { startTalk(); readMouse(); showPointer(); - workToScreen(); + workToScreenCPP(); delPointer(); } @@ -3792,15 +3545,11 @@ void DreamGenContext::moreTalk() { doSomeTalk(); } -bool DreamGenContext::isSetObOnMap(uint8 index) { +bool DreamBase::isSetObOnMap(uint8 index) { return (getSetAd(index)->mapad[0] == 0); } -void DreamGenContext::isSetObOnMap() { - flags._z = isSetObOnMap(al); -} - -void DreamGenContext::dumpZoom() { +void DreamBase::dumpZoom() { if (data.byte(kZoomon) == 1) multiDump(kZoomx + 5, kZoomy + 4, 46, 40); } @@ -3825,7 +3574,7 @@ void DreamGenContext::selectLocation() { readMouse(); data.byte(kPointerframe) = 0; showPointer(); - workToScreen(); + workToScreenCPP(); playChannel0(9, 255); data.byte(kNewlocation) = 255; @@ -3848,8 +3597,8 @@ void DreamGenContext::selectLocation() { { 104,124,4,44,&DreamGenContext::lastDest }, { 280,308,4,44,&DreamGenContext::lookAtPlace }, { 104,216,138,192,&DreamGenContext::destSelect }, - { 273,320,157,198,&DreamGenContext::getBack1 }, - { 0,320,0,200,&DreamGenContext::blank }, + { 273,320,157,198,&DreamBase::getBack1 }, + { 0,320,0,200,&DreamBase::blank }, { 0xFFFF,0,0,0,0 } }; checkCoords(destList); @@ -3867,7 +3616,7 @@ void DreamGenContext::selectLocation() { } -void DreamGenContext::examineInventory() { +void DreamBase::examineInventory() { if (data.byte(kCommandtype) != 249) { data.byte(kCommandtype) = 249; commandOnly(32); @@ -3887,4 +3636,984 @@ void DreamGenContext::examineInventory() { workToScreenM(); } +void DreamBase::showArrows() { + showFrame(tempGraphics(), 116 - 12, 16, 0, 0); + showFrame(tempGraphics(), 226 + 12, 16, 1, 0); + showFrame(tempGraphics(), 280, 14, 2, 0); +} + +void DreamBase::showOpBox() { + showFrame(tempGraphics(), kOpsx, kOpsy, 0, 0); + + // CHECKME: There seem to be versions of dreamweb in which this call + // should be removed. It displays a red dot on the ops dialogs if left in. + showFrame(tempGraphics(), kOpsx, kOpsy + 55, 4, 0); +} + +void DreamGenContext::showLoadOps() { + showFrame(tempGraphics(), kOpsx + 128 + 4, kOpsy + 12, 1, 0); + showFrame(tempGraphics(), kOpsx + 176 + 2, kOpsy + 60 - 4, 5, 0); + printMessage(kOpsx + 104, kOpsy + 14, 55, 101, (101 & 1)); +} + +void DreamGenContext::showSaveOps() { + showFrame(tempGraphics(), kOpsx + 128 + 4, kOpsy + 12, 1, 0); + showFrame(tempGraphics(), kOpsx + 176 + 2, kOpsy + 60 - 4, 5, 0); + printMessage(kOpsx + 104, kOpsy + 14, 54, 101, (101 & 1)); +} + +void DreamBase::middlePanel() { + Frame *tempSprites = (Frame *)getSegment(data.word(kTempsprites)).ptr(0, 0); + showFrame(tempSprites, 72 + 47 + 20, 0, 48, 0); + showFrame(tempSprites, 72 + 19, 21, 47, 0); + showFrame(tempSprites, 160 + 23, 0, 48, 4); + showFrame(tempSprites, 160 + 71, 21, 47, 4); +} + +void DreamBase::showDiary() { + showFrame(tempGraphics(), kDiaryx, kDiaryy + 37, 1, 0); + showFrame(tempGraphics(), kDiaryx + 176, kDiaryy + 108, 2, 0); +} + +void DreamBase::underTextLine() { + uint16 y = data.word(kTextaddressy); + if (data.byte(kForeignrelease)) + y -= 3; + multiGet(textUnder(), data.byte(kTextaddressx), y, kUndertextsizex, kUndertextsizey); +} + +void DreamGenContext::showDecisions() { + createPanel2(); + showOpBox(); + showFrame(tempGraphics(), kOpsx + 17, kOpsy + 13, 6, 0); + underTextLine(); +} + +void DreamBase::getUnderZoom() { + multiGet(getSegment(data.word(kBuffers)).ptr(kZoomspace, 0), kZoomx + 5, kZoomy + 4, 46, 40); +} + +void DreamBase::putUnderZoom() { + multiPut(getSegment(data.word(kBuffers)).ptr(kZoomspace, 0), kZoomx + 5, kZoomy + 4, 46, 40); +} + +void DreamBase::showWatchReel() { + uint16 reelPointer = data.word(kReeltowatch); + plotReel(reelPointer); + data.word(kReeltowatch) = reelPointer; + + // check for shake + if (data.byte(kReallocation) == 26 && reelPointer == 104) + data.byte(kShakecounter) = 0xFF; +} + +void DreamBase::watchReel() { + if (data.word(kReeltowatch) != 0xFFFF) { + if (data.byte(kManspath) != data.byte(kFinaldest)) + return; // Wait until stopped walking + if (data.byte(kTurntoface) != data.byte(kFacing)) + return; + + if (--data.byte(kSpeedcount) != 0xFF) { + showWatchReel(); + return; + } + data.byte(kSpeedcount) = data.byte(kWatchspeed); + if (data.word(kReeltowatch) != data.word(kEndwatchreel)) { + ++data.word(kReeltowatch); + showWatchReel(); + return; + } + if (data.word(kWatchingtime)) { + showWatchReel(); + return; + } + data.word(kReeltowatch) = 0xFFFF; + data.byte(kWatchmode) = 0xFF; + if (data.word(kReeltohold) == 0xFFFF) + return; // No more reel + data.byte(kWatchmode) = 1; + } else if (data.byte(kWatchmode) != 1) { + if (data.byte(kWatchmode) != 2) + return; // "notreleasehold" + if (--data.byte(kSpeedcount) == 0xFF) { + data.byte(kSpeedcount) = data.byte(kWatchspeed); + ++data.word(kReeltohold); + } + if (data.word(kReeltohold) == data.word(kEndofholdreel)) { + data.word(kReeltohold) = 0xFFFF; + data.byte(kWatchmode) = 0xFF; + data.byte(kDestination) = data.byte(kDestafterhold); + data.byte(kFinaldest) = data.byte(kDestafterhold); + autoSetWalk(); + return; + } + } + + uint16 reelPointer = data.word(kReeltohold); + plotReel(reelPointer); +} + +void DreamGenContext::afterNewRoom() { + if (data.byte(kNowinnewroom) == 0) + return; // notnew + + data.word(kTimecount) = 0; + createPanel(); + data.byte(kCommandtype) = 0; + findRoomInLoc(); + if (data.byte(kRyanon) != 1) { + al = data.byte(kRyanx) + 12; + ah = data.byte(kRyany) + 12; + findPathOfPoint(); + data.byte(kManspath) = dl; + findXYFromPath(); + data.byte(kResetmanxy) = 1; + } + data.byte(kNewobs) = 1; + drawFloor(); + data.word(kLookcounter) = 160; + data.byte(kNowinnewroom) = 0; + showIcon(); + spriteUpdate(); + printSprites(); + underTextLine(); + reelsOnScreen(); + mainScreen(); + getUnderZoom(); + zoom(); + workToScreenM(); + walkIntoRoom(); + reminders(); + atmospheres(); +} + +void DreamGenContext::madmanRun() { + if (data.byte(kLocation) != 14 || + data.byte(kMapx) != 22 || + data.byte(kPointermode) != 2 || + data.byte(kMadmanflag) != 0) { + identifyOb(); + return; + } + + if (data.byte(kCommandtype) != 211) { + data.byte(kCommandtype) = 211; + commandOnly(52); + } + + if (data.word(kMousebutton) == 1 && + data.word(kMousebutton) != data.word(kOldbutton)) + data.byte(kLastweapon) = 8; +} + + +void DreamGenContext::decide() { + setMode(); + loadPalFromIFF(); + clearPalette(); + data.byte(kPointermode) = 0; + data.word(kWatchingtime) = 0; + data.byte(kPointerframe) = 0; + data.word(kTextaddressx) = 70; + data.word(kTextaddressy) = 182 - 8; + data.byte(kTextlen) = 181; + data.byte(kManisoffscreen) = 1; + loadSaveBox(); + showDecisions(); + workToScreenCPP(); + fadeScreenUp(); + data.byte(kGetback) = 0; + + RectWithCallback decideList[] = { + { kOpsx+69,kOpsx+124,kOpsy+30,kOpsy+76,&DreamGenContext::newGame }, + { kOpsx+20,kOpsx+87,kOpsy+10,kOpsy+59,&DreamBase::DOSReturn }, + { kOpsx+123,kOpsx+190,kOpsy+10,kOpsy+59,&DreamGenContext::loadOld }, + { 0,320,0,200,&DreamBase::blank }, + { 0xFFFF,0,0,0,0 } + }; + + do { + if (data.byte(kQuitrequested) != 0) + return; + + readMouse(); + showPointer(); + vSync(); + dumpPointer(); + dumpTextLine(); + delPointer(); + checkCoords(decideList); + } while (!data.byte(kGetback)); + + if (data.byte(kGetback) != 4) + getRidOfTemp(); // room not loaded + + data.word(kTextaddressx) = 13; + data.word(kTextaddressy) = 182; + data.byte(kTextlen) = 240; +} + +void DreamGenContext::talk() { + data.byte(kTalkpos) = 0; + data.byte(kInmaparea) = 0; + data.byte(kCharacter) = data.byte(kCommand); + createPanel(); + showPanel(); + showMan(); + showExit(); + underTextLine(); + convIcons(); + startTalk(); + data.byte(kCommandtype) = 255; + readMouse(); + showPointer(); + workToScreenCPP(); + + RectWithCallback talkList[] = { + { 273,320,157,198,&DreamBase::getBack1 }, + { 240,290,2,44,&DreamGenContext::moreTalk }, + { 0,320,0,200,&DreamBase::blank }, + { 0xFFFF,0,0,0,0 } + }; + + do { + delPointer(); + readMouse(); + animPointer(); + showPointer(); + vSync(); + dumpPointer(); + dumpTextLine(); + data.byte(kGetback) = 0; + checkCoords(talkList); + if (data.byte(kQuitrequested)) + break; + } while (!data.byte(kGetback)); + + if (data.byte(kTalkpos) >= 4) + data.byte(data.word(kPersondata)+7) |= 128; + + redrawMainScrn(); + workToScreenM(); + if (data.byte(kSpeechloaded) == 1) { + cancelCh1(); + data.byte(kVolumedirection) = (byte)-1; + data.byte(kVolumeto) = 0; + } +} + +void DreamGenContext::discOps() { + if (data.byte(kCommandtype) != 249) { + data.byte(kCommandtype) = 249; + commandOnly(43); + } + + if (data.word(kMousebutton) == data.word(kOldbutton) || !(data.word(kMousebutton) & 1)) + return; + + scanForNames(); + data.byte(kLoadingorsave) = 2; + showOpBox(); + showDiscOps(); + data.byte(kCurrentslot) = 0; + workToScreenM(); + data.byte(kGetback) = 0; + + RectWithCallback discOpsList[] = { + { kOpsx+59,kOpsx+114,kOpsy+30,kOpsy+76,&DreamGenContext::loadGame }, + { kOpsx+10,kOpsx+79,kOpsy+10,kOpsy+59,&DreamGenContext::saveGame }, + { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamGenContext::getBackToOps }, + { 0,320,0,200,&DreamBase::blank }, + { 0xFFFF,0,0,0,0 } + }; + + do { + if (data.byte(kQuitrequested) != 0) + return; // quitdiscops + + delPointer(); + readMouse(); + showPointer(); + vSync(); + dumpPointer(); + dumpTextLine(); + checkCoords(discOpsList); + } while (!data.byte(kGetback)); +} + +void DreamGenContext::hangOnPQ() { + data.byte(kGetback) = 0; + + RectWithCallback quitList[] = { + { 273,320,157,198,&DreamBase::getBack1 }, + { 0,320,0,200,&DreamBase::blank }, + { 0xFFFF,0,0,0,0 } + }; + + uint16 speechFlag = 0; + + do { + delPointer(); + readMouse(); + animPointer(); + showPointer(); + vSync(); + dumpPointer(); + dumpTextLine(); + checkCoords(quitList); + + if (data.byte(kGetback) == 1 || data.byte(kQuitrequested)) { + // Quit conversation + delPointer(); + data.byte(kPointermode) = 0; + cancelCh1(); + flags._c = true; + return; + } + + if (data.byte(kSpeechloaded) == 1 && data.byte(kCh1playing) == 255) { + speechFlag++; + if (speechFlag == 40) + break; + } + } while (!data.word(kMousebutton) || data.word(kOldbutton)); + + delPointer(); + data.byte(kPointermode) = 0; + flags._c = false; + } + +void DreamGenContext::endGame() { + loadTempText("DREAMWEB.T83"); + monkSpeaking(); + gettingShot(); + getRidOfTempText(); + data.byte(kVolumeto) = 7; + data.byte(kVolumedirection) = 1; + hangOn(200); +} + +void DreamGenContext::showGun() { + data.byte(kAddtored) = 0; + data.byte(kAddtogreen) = 0; + data.byte(kAddtoblue) = 0; + palToStartPal(); + palToEndPal(); + greyscaleSum(); + data.byte(kFadedirection) = 1; + data.byte(kFadecount) = 63; + data.byte(kColourpos) = 0; + data.byte(kNumtofade) = 128; + hangOn(130); + endPalToStart(); + clearEndPal(); + data.byte(kFadedirection) = 1; + data.byte(kFadecount) = 63; + data.byte(kColourpos) = 0; + data.byte(kNumtofade) = 128; + hangOn(200); + data.byte(kRoomssample) = 34; + loadRoomsSample(); + data.byte(kVolume) = 0; + loadIntoTemp("DREAMWEB.G13"); + createPanel2(); + showFrame(tempGraphics(), 100, 4, 0, 0); + showFrame(tempGraphics(), 158, 106, 1, 0); + workToScreenCPP(); + getRidOfTemp(); + fadeScreenUp(); + hangOn(160); + playChannel0(12, 0); + loadTempText("DREAMWEB.T83"); + rollEndCredits2(); + getRidOfTempText(); +} + +void DreamBase::diaryKeyP() { + if (data.byte(kCommandtype) != 214) { + data.byte(kCommandtype) = 214; + commandOnly(23); + } + + if (!data.word(kMousebutton) || + data.word(kOldbutton) == data.word(kMousebutton) || + data.byte(kPresscount)) + return; // notkeyp + + playChannel1(16); + data.byte(kPresscount) = 12; + data.byte(kPressed) = 'P'; + data.byte(kDiarypage)--; + + if (data.byte(kDiarypage) == 0xFF) + data.byte(kDiarypage) = 11; +} + +void DreamBase::diaryKeyN() { + if (data.byte(kCommandtype) != 213) { + data.byte(kCommandtype) = 213; + commandOnly(23); + } + + if (!data.word(kMousebutton) || + data.word(kOldbutton) == data.word(kMousebutton) || + data.byte(kPresscount)) + return; // notkeyn + + playChannel1(16); + data.byte(kPresscount) = 12; + data.byte(kPressed) = 'N'; + data.byte(kDiarypage)++; + + if (data.byte(kDiarypage) == 12) + data.byte(kDiarypage) = 0; +} + +void DreamGenContext::dropError() { + data.byte(kCommandtype) = 255; + delPointer(); + printMessage(76, 21, 56, 240, 240 & 1); + workToScreenM(); + hangOnP(50); + showPanel(); + showMan(); + examIcon(); + data.byte(kCommandtype) = 255; + workToScreenM(); +} + +void DreamGenContext::cantDrop() { + data.byte(kCommandtype) = 255; + delPointer(); + printMessage(76, 21, 24, 240, 240 & 1); + workToScreenM(); + hangOnP(50); + showPanel(); + showMan(); + examIcon(); + data.byte(kCommandtype) = 255; + workToScreenM(); +} + +void DreamBase::getBack1() { + if (data.byte(kPickup) != 0) { + blank(); + return; + } + + + if (data.byte(kCommandtype) != 202) { + data.byte(kCommandtype) = 202; + commandOnly(26); + } + + if (data.word(kMousebutton) == data.word(kOldbutton)) + return; + + if (data.word(kMousebutton) & 1) { + // Get back + data.byte(kGetback) = 1; + data.byte(kPickup) = 0; + } +} + +void DreamGenContext::newPlace() { + if (data.byte(kNeedtotravel) == 1) { + data.byte(kNeedtotravel) = 0; + selectLocation(); + } else if (data.byte(kAutolocation) != 0xFF) { + data.byte(kNewlocation) = data.byte(kAutolocation); + data.byte(kAutolocation) = 0xFF; + } +} + +void DreamGenContext::monkSpeaking() { + // FIXME: This is the CD version only. + + data.byte(kRoomssample) = 35; + loadRoomsSample(); + loadIntoTemp("DREAMWEB.G15"); + clearWork(); + showFrame(tempGraphics(), 160, 72, 0, 128); // show monk + workToScreen(); + data.byte(kVolume) = 7; + data.byte(kVolumedirection) = (byte)-1; + data.byte(kVolumeto) = 5; + playChannel0(12, 255); + fadeScreenUps(); + hangOn(300); + + for (int i = 40; i <= 48; i++) { + loadSpeech('T', 83, 'T', i); + + playChannel1(50 + 12); + + do { + engine->waitForVSync(); + } while (data.byte(kCh1playing) != 255); + } + + data.byte(kVolumedirection) = 1; + data.byte(kVolumeto) = 7; + fadeScreenDowns(); + hangOn(300); + getRidOfTemp(); +} + +void DreamGenContext::useButtonA() { + if (!isSetObOnMap(95)) { + showFirstUse(); + turnAnyPathOn(0, data.byte(kRoomnum) - 1); + removeSetObject(9); + placeSetObject(95); + data.word(kWatchingtime) = 15 * 2; + data.word(kReeltowatch) = 71; + data.word(kEndwatchreel) = 85; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + data.byte(kGetback) = 1; + data.byte(kProgresspoints)++; + } else { + // Done this bit + showSecondUse(); + putBackObStuff(); + } +} + +void DreamGenContext::autoAppear() { + if (data.byte(kLocation) == 32) { + // In alley + al = 5; + resetLocation(); + setLocation(10); + data.byte(kDestpos) = 10; + return; + } + + if (data.byte(kReallocation) == 24) { + // In Eden's apartment + if (data.byte(kGeneraldead) == 1) { + data.byte(kGeneraldead)++; + placeSetObject(44); + placeSetObject(18); + placeSetObject(93); + removeSetObject(92); + removeSetObject(55); + removeSetObject(75); + removeSetObject(84); + removeSetObject(85); + } else if (data.byte(kSartaindead) == 1) { + // Eden's part 2 + removeSetObject(44); + removeSetObject(93); + placeSetObject(55); + data.byte(kSartaindead)++; + } + } else { + // Not in Eden's + if (data.byte(kReallocation) == 25) { + // Sart roof + data.byte(kNewsitem) = 3; + al = 6; + resetLocation(); + setLocation(11); + data.byte(kDestpos) = 11; + } else { + if (data.byte(kReallocation) == 2 && data.byte(kRockstardead) != 0) + placeSetObject(23); + } + } +} + +void DreamBase::quitKey() { + if (data.byte(kCommandtype) != 222) { + data.byte(kCommandtype) = 222; + commandOnly(4); + } + + if (data.word(kMousebutton) != data.word(kOldbutton) && (data.word(kMousebutton) & 1)) + data.byte(kGetback) = 1; +} + +void DreamGenContext::setupTimedUse() { + DreamBase::setupTimedUse(al, cx, dx, bl, bh); +} + +void DreamBase::setupTimedUse(uint16 textIndex, uint16 countToTimed, uint16 timeCount, byte x, byte y) { + if (data.word(kTimecount) != 0) + return; // can't setup + + data.byte(kTimedy) = y; + data.byte(kTimedx) = x; + data.word(kCounttotimed) = countToTimed; + data.word(kTimecount) = timeCount + countToTimed; + data.word(kTimedseg) = data.word(kPuzzletext); + data.word(kTimedoffset) = kTextstart + getSegment(data.word(kPuzzletext)).word(textIndex * 2); + const uint8 *string = getSegment(data.word(kPuzzletext)).ptr(data.word(kTimedoffset), 0); + debug(1, "setupTimedUse: %d => '%s'", textIndex, string); +} + +void DreamBase::entryTexts() { + switch (data.byte(kLocation)) { + case 21: + setupTimedUse(28, 60, 11, 68, 64); + break; + case 30: + setupTimedUse(27, 60, 11, 68, 64); + break; + case 23: + setupTimedUse(29, 60, 11, 68, 64); + break; + case 31: + setupTimedUse(30, 60, 11, 68, 64); + break; + case 20: // Sarter's 2 + setupTimedUse(31, 60, 11, 68, 64); + break; + case 24: // Eden's lobby + setupTimedUse(32, 60, 3, 68, 64); + break; + case 34: // Eden 2 + setupTimedUse(33, 60, 3, 68, 64); + break; + default: + break; + } +} + +void DreamGenContext::entryAnims() { + data.word(kReeltowatch) = 0xFFFF; + data.byte(kWatchmode) = (byte)-1; + + switch (data.byte(kLocation)) { + case 33: // beach + switchRyanOff(); + data.word(kWatchingtime) = 76 * 2; + data.word(kReeltowatch) = 0; + data.word(kEndwatchreel) = 76; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + break; + case 44: // Sparky's + al = 8; + resetLocation(); + data.word(kWatchingtime) = 50*2; + data.word(kReeltowatch) = 247; + data.word(kEndwatchreel) = 297; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + switchRyanOff(); + break; + case 22: // lift + data.word(kWatchingtime) = 31 * 2; + data.word(kReeltowatch) = 0; + data.word(kEndwatchreel) = 30; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + switchRyanOff(); + break; + case 26: // under church + data.byte(kSymboltopnum) = 2; + data.byte(kSymbolbotnum) = 1; + break; + case 45: // entered Dreamweb + data.byte(kKeeperflag) = 0; + data.word(kWatchingtime) = 296; + data.word(kReeltowatch) = 45; + data.word(kEndwatchreel) = 198; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + switchRyanOff(); + break; + default: + if (data.byte(kReallocation) == 46 && data.byte(kSartaindead) == 1) { // Crystal + removeFreeObject(0); + } else if (data.byte(kLocation) == 9 && !checkIfPathIsOn(2) && data.byte(kAidedead) != 0) { + // Top of church + if (checkIfPathIsOn(3)) + turnPathOn(2); + + // Make doors open + removeSetObject(4); + placeSetObject(5); + } else if (data.byte(kLocation) == 47) { // Dream centre + placeSetObject(4); + placeSetObject(5); + } else if (data.byte(kLocation) == 38) { // Car park + data.word(kWatchingtime) = 57 * 2; + data.word(kReeltowatch) = 4; + data.word(kEndwatchreel) = 57; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + switchRyanOff(); + } else if (data.byte(kLocation) == 32) { // Alley + data.word(kWatchingtime) = 66 * 2; + data.word(kReeltowatch) = 0; + data.word(kEndwatchreel) = 66; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + switchRyanOff(); + } else if (data.byte(kLocation) == 24) { // Eden's again + turnAnyPathOn(2, data.byte(kRoomnum) - 1); + } + } +} + +void DreamGenContext::updateSymbolTop() { + if (!data.byte(kSymboltopdir)) + return; // topfinished + + if (data.byte(kSymboltopdir) == (byte)-1) { + // Backward + data.byte(kSymboltopx)--; + if (data.byte(kSymboltopx) != (byte)-1) { + // Not wrapping + if (data.byte(kSymboltopx) != 24) + return; // topfinished + data.byte(kSymboltopdir) = 0; + } else { + data.byte(kSymboltopx) = 48; + data.byte(kSymboltopnum)++; + if (data.byte(kSymboltopnum) != 6) + return; // topfinished + data.byte(kSymboltopnum) = 0; + } + } else { + // Forward + data.byte(kSymboltopx)++; + if (data.byte(kSymboltopx) != 49) { + // Not wrapping + if (data.byte(kSymboltopx) != 24) + return; // topfinished + data.byte(kSymboltopdir) = 0; + } else { + data.byte(kSymboltopx) = 0; + data.byte(kSymboltopnum)--; + if (data.byte(kSymboltopnum) != (byte)-1) + return; // topfinished + data.byte(kSymboltopnum) = 5; + } + } +} + +void DreamGenContext::updateSymbolBot() { + if (!data.byte(kSymbolbotdir)) + return; // botfinished + + if (data.byte(kSymbolbotdir) == (byte)-1) { + // Backward + data.byte(kSymbolbotx)--; + if (data.byte(kSymbolbotx) != (byte)-1) { + // Not wrapping + if (data.byte(kSymbolbotx) != 24) + return; // botfinished + data.byte(kSymbolbotdir) = 0; + } else { + data.byte(kSymbolbotx) = 48; + data.byte(kSymbolbotnum)++; + if (data.byte(kSymbolbotnum) != 6) + return; // botfinished + data.byte(kSymbolbotnum) = 0; + } + } else { + // Forward + data.byte(kSymbolbotx)++; + if (data.byte(kSymbolbotx) != 49) { + // Not wrapping + if (data.byte(kSymbolbotx) != 24) + return; // botfinished + data.byte(kSymbolbotdir) = 0; + } else { + data.byte(kSymbolbotx) = 0; + data.byte(kSymbolbotnum)--; + if (data.byte(kSymbolbotnum) != (byte)-1) + return; // botfinished + data.byte(kSymbolbotnum) = 5; + } + } +} + +void DreamGenContext::showDiaryPage() { + showFrame(tempGraphics(), kDiaryx, kDiaryy, 0, 0); + data.byte(kKerning) = 1; + useTempCharset(); + data.word(kCharshift) = 91+91; + const uint8 *string = getTextInFile1(data.byte(kDiarypage)); + uint16 y = kDiaryy + 16; + printDirect(&string, kDiaryx + 48, &y, 240, 240 & 1); + y = kDiaryy + 16; + printDirect(&string, kDiaryx + 129, &y, 240, 240 & 1); + y = kDiaryy + 23; + printDirect(&string, kDiaryx + 48, &y, 240, 240 & 1); + data.byte(kKerning) = 0; + data.word(kCharshift) = 0; + useCharset1(); +} + +void DreamGenContext::dumpDiaryKeys() { + if (data.byte(kPresscount) == 1) { + if (data.byte(kSartaindead) != 1 && data.byte(kDiarypage) == 5 && getLocation(6) != 1) { + // Add Sartain Industries note + setLocation(6); + delPointer(); + const uint8 *string = getTextInFile1(12); + printDirect(string, 70, 106, 241, 241 & 1); + workToScreenM(); + hangOnP(200); + createPanel(); + showIcon(); + showDiary(); + showDiaryPage(); + workToScreenM(); + showPointer(); + return; + } else { + multiDump(kDiaryx + 48, kDiaryy + 15, 200, 16); + } + } + + multiDump(kDiaryx + 94, kDiaryy + 97, 16, 16); + multiDump(kDiaryx + 151, kDiaryy + 71, 16, 16); +} + +void DreamGenContext::runEndSeq() { + atmospheres(); + data.byte(kGetback) = 0; + + do { + vSync(); + spriteUpdate(); + vSync(); + delEverything(); + printSprites(); + reelsOnScreen(); + afterIntroRoom(); + useTimedText(); + vSync(); + dumpMap(); + dumpTimedText(); + vSync(); + } while (data.byte(kGetback) != 1); +} + +void DreamGenContext::lookAtCard() { + data.byte(kManisoffscreen) = 1; + getRidOfReels(); + loadKeypad(); + createPanel2(); + showFrame(tempGraphics(), 160, 80, 42, 128); + const uint8 *obText = getObTextStartCPP(); + findNextColon(&obText); + findNextColon(&obText); + findNextColon(&obText); + uint16 y = 124; + printDirect(&obText, 36, &y, 241, 241 & 1); + workToScreenM(); + hangOnW(280); + createPanel2(); + showFrame(tempGraphics(), 160, 80, 42, 128); + printDirect(obText, 36, 130, 241, 241 & 1); + workToScreenM(); + hangOnW(200); + data.byte(kManisoffscreen) = 0; + getRidOfTemp(); + restoreReels(); + putBackObStuff(); +} + +void DreamGenContext::showSlots() { + showFrame(tempGraphics(), kOpsx + 7, kOpsy + 8, 2, 0); + + uint16 y = kOpsy + 11; + + for (int slot = 0; slot < 7; slot++) { + if (slot == data.byte(kCurrentslot)) + showFrame(tempGraphics(), kOpsx + 10, y, 3, 0); + + y += 10; + } +} + +void DreamBase::clearBuffers() { + memset(getSegment(data.word(kBuffers)).ptr(0, kLengthofbuffer), 0, kLengthofbuffer); + + memset(getSegment(data.word(kExtras)).ptr(0, kLengthofextra), 0xFF, kLengthofextra); + + memcpy(getSegment(data.word(kBuffers)).ptr(kInitialvars, kLengthofvars), data.ptr(kStartvars, kLengthofvars), kLengthofvars); + + clearChanges(); +} + +void DreamBase::clearChanges() { + memset(getSegment(data.word(kBuffers)).ptr(kListofchanges, 4*kNumchanges), 0xFF, 4*kNumchanges); + + setupInitialReelRoutines(); + + memcpy(data.ptr(kStartvars, kLengthofvars), getSegment(data.word(kBuffers)).ptr(kInitialvars, kLengthofvars), kLengthofvars); + + data.byte(kExpos) = 0; + data.word(kExframepos) = 0; + data.word(kExtextpos) = 0; + + memset(getSegment(data.word(kExtras)).ptr(0, kLengthofextra), 0xFF, kLengthofextra); + + const uint8 initialRoomsCanGo[] = { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + memcpy(data.ptr(kRoomscango, 16), initialRoomsCanGo, 16); +} + +void DreamGenContext::showDiaryKeys() { + if (!data.byte(kPresscount)) + return; // nokeyatall + + data.byte(kPresscount)--; + + if (!data.byte(kPresscount)) + return; // nokeyatall + + if (data.byte(kPressed) == 'N') { + byte frame = (data.byte(kPresscount) == 1) ? 3 : 4; + showFrame(tempGraphics(), kDiaryx + 94, kDiaryy + 97, frame, 0); + } else { + byte frame = (data.byte(kPresscount) == 1) ? 5 : 6; + showFrame(tempGraphics(), kDiaryx + 151, kDiaryy + 71, frame, 0); + } + + if (data.byte(kPresscount) == 1) + showDiaryPage(); +} + +void DreamGenContext::lookAtPlace() { + if (data.byte(kCommandtype) != 224) { + data.byte(kCommandtype) = 224; + commandOnly(27); + } + + if (!(data.word(kMousebutton) & 1) || + data.word(kMousebutton) == data.word(kOldbutton) || + data.byte(kDestpos) >= 15) + return; // noinfo + + delPointer(); + delTextLine(); + getUnderCentre(); + showFrame(tempGraphics3(), 60, 72, 0, 0); + showFrame(tempGraphics3(), 60, 72 + 55, 4, 0); + if (data.byte(kForeignrelease)) + showFrame(tempGraphics3(), 60, 72+55+21, 4, 0); + + uint16 offset = kTextstart + getSegment(data.word(kTraveltext)).word(data.byte(kDestpos) * 2); + const uint8 *string = getSegment(data.word(kTraveltext)).ptr(offset, 0); + findNextColon(&string); + uint16 y = (data.byte(kForeignrelease)) ? 84 + 4 : 84; + printDirect(&string, 63, &y, 191, 191 & 1); + workToScreenM(); + hangOnP(500); + data.byte(kPointermode) = 0; + data.byte(kPointerframe) = 0; + putUnderCentre(); + workToScreenM(); +} + } // End of namespace DreamGen diff --git a/engines/dreamweb/stubs.h b/engines/dreamweb/stubs.h index 73fa7a62ef..1a76a785b8 100644 --- a/engines/dreamweb/stubs.h +++ b/engines/dreamweb/stubs.h @@ -23,30 +23,10 @@ #define DREAMWEB_STUBS_H void screenUpdate(); - bool quitRequested(); void startup(); void startup1(); - void switchRyanOn(); - void switchRyanOff(); - uint16 allocateMem(uint16 paragraphs); - void deallocateMem(uint16 segment); - uint8 *textUnder(); - uint16 standardLoad(const char *fileName, uint16 *outSizeInBytes = NULL); // Returns a segment handle which needs to be freed with deallocatemem for symmetry - void *standardLoadCPP(const char *fileName, uint16 *outSizeInBytes = NULL); // And this one should be 'free'd - void loadIntoTemp(); - void loadIntoTemp(const char *fileName); - void loadIntoTemp2(const char *fileName); - void loadIntoTemp3(const char *fileName); - void loadTempCharset(); - void loadTempCharset(const char *fileName); void saveLoad(); - void printCurs(); - void delCurs(); - void delChar(); - void hangOnCurs(uint16 frameCount); - void hangOnCurs(); void workToScreen(); - uint8 *mapStore(); void multiGet(); void multiGet(uint8 *dst, uint16 x, uint16 y, uint8 width, uint8 height) { DreamBase::multiGet(dst, x, y, width, height); @@ -59,34 +39,20 @@ void multiDump(uint16 x, uint16 y, uint8 width, uint8 height) { DreamBase::multiDump(x, y, width, height); } - void printSprites(); void quickQuit(); void readOneBlock(); void readCityPic(); void readDestIcon(); void seeCommandTail(); - void randomNumber(); void quickQuit2(); - void printBoth(const Frame* charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar); - void printChar(const Frame* charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height); - void printChar(const Frame* charSet, uint16 x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height); void printDirect(); - uint8 printDirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered); - uint8 printDirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered); - void printMessage(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered); - void printMessage(); - void useTimedText(); - void dumpTimedText(); - void setupTimedTemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount); - void getUnderTimed(); - void putUnderTimed(); - uint8 printSlow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered); - void dumpTextLine(); - void oldToNames(); - void namesToOld(); - void loadPalFromIFF(); + uint8 printDirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered) { + return DreamBase::printDirect(string, x, y, maxWidth, centered); + } + uint8 printDirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered) { + return DreamBase::printDirect(string, x, y, maxWidth, centered); + } void startLoading(const Room &room); - Sprite *spriteTable(); void showFrame(); void showFrame(const Frame *frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height) { DreamBase::showFrame(frameData, x, y, frameNumber, effectsFlag, width, height); @@ -94,268 +60,121 @@ void showFrame(const Frame *frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag) { DreamBase::showFrame(frameData, x, y, frameNumber, effectsFlag); } - void printASprite(const Sprite *sprite); void width160(); - void eraseOldObs(); - void clearSprites(); - Sprite *makeSprite(uint8 x, uint8 y, uint16 updateCallback, uint16 frameData, uint16 somethingInDi); - void spriteUpdate(); - void initMan(); - void mainMan(Sprite *sprite); - void mainMan(); - void faceRightWay(); - void walking(Sprite *sprite); - void autoSetWalk(); - void aboutTurn(Sprite *sprite); - void backObject(Sprite *sprite); - void backObject(); - void constant(Sprite *sprite, SetObject *objData); - void steady(Sprite *sprite, SetObject *objData); - void randomSprite(Sprite *sprite, SetObject *objData); - void doDoor(Sprite *sprite, SetObject *objData, Common::Rect check); - void doorway(Sprite *sprite, SetObject *objData); - void wideDoor(Sprite *sprite, SetObject *objData); - void lockedDoorway(Sprite *sprite, SetObject *objData); - void liftSprite(Sprite *sprite, SetObject *objData); - Frame *findSource(); - void showGameReel(); - void showGameReel(ReelRoutine *routine); - void showReelFrame(Reel *reel); - const Frame *getReelFrameAX(uint16 frame); - void turnPathOn(uint8 param); - void turnPathOff(uint8 param); - void turnPathOn(); - void turnPathOff(); - void turnAnyPathOn(uint8 param, uint8 room); - void turnAnyPathOff(uint8 param, uint8 room); - void turnAnyPathOn(); - void turnAnyPathOff(); - RoomPaths *getRoomsPaths(); - void makeBackOb(SetObject *objData); - void lockMon(); - void cancelCh0(); - void cancelCh1(); - void plotReel(); - Reel *getReelStart(); - void dealWithSpecial(uint8 firstParam, uint8 secondParam); void zoom(); - void showRain(); - void delTextLine(); void commandOnly(); - void commandOnly(uint8 command); - void doBlocks(); + void commandOnly(uint8 command) { + DreamBase::commandOnly(command); + } void checkIfPerson(); bool checkIfPerson(uint8 x, uint8 y); void checkIfFree(); bool checkIfFree(uint8 x, uint8 y); void checkIfEx(); bool checkIfEx(uint8 x, uint8 y); - const uint8 *findObName(uint8 type, uint8 index); - void copyName(); - void copyName(uint8 type, uint8 index, uint8 *dst); void commandWithOb(); void commandWithOb(uint8 command, uint8 type, uint8 index); - void updatePeople(); - void madman(ReelRoutine &routine); - void madmanText(); - void madMode(); - void moveMap(uint8 param); - bool addAlong(const uint8 *mapFlags); - bool addLength(const uint8 *mapFlags); - void getDimension(); - void getDimension(uint8 *mapXstart, uint8 *mapYstart, uint8 *mapXsize, uint8 *mapYsize); - void getMapAd(); - void calcMapAd(); - uint8 getMapAd(const uint8 *setData); - uint8 getXAd(const uint8 *setData, uint8 *result); - uint8 getYAd(const uint8 *setData, uint8 *result); - void calcFrFrame(); - void calcFrFrame(uint8* width, uint8* height); - void finalFrame(); - void finalFrame(uint16 *x, uint16 *y); - void showAllObs(); void blockNameText(); void walkToText(); void personNameText(); - void findXYFromPath(); - void findOrMake(); - void findOrMake(uint8 index, uint8 value, uint8 type); - DynObject *getFreeAd(uint8 index); - DynObject *getExAd(uint8 index); - DynObject *getEitherAdCPP(); - SetObject *getSetAd(uint8 index); - void *getAnyAd(uint8 *value1, uint8 *value2); - void *getAnyAdDir(uint8 index, uint8 flag); + DynObject *getFreeAd(uint8 index) { + return DreamBase::getFreeAd(index); + } + DynObject *getExAd(uint8 index) { + return DreamBase::getExAd(index); + } + void *getAnyAd(uint8 *value1, uint8 *value2) { + return DreamBase::getAnyAd(value1, value2); + } + SetObject *getSetAd(uint8 index) { + return DreamBase::getSetAd(index); + } void setAllChanges(); - void doChange(uint8 index, uint8 value, uint8 type); void deleteTaken(); - bool isCD(); - void placeSetObject(); - void placeSetObject(uint8 index); - void removeSetObject(); - void removeSetObject(uint8 index); - void showAllFree(); - void showAllEx(); bool finishedWalkingCPP(); void finishedWalking(); void checkOne(); - void checkOne(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uint8 *type, uint8 *flagX, uint8 *flagY); - void getFlagUnderP(); - void getFlagUnderP(uint8 *flag, uint8 *flagEx); + void checkOne(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uint8 *type, uint8 *flagX, uint8 *flagY) { + DreamBase::checkOne(x, y, flag, flagEx, type, flagX, flagY); + } void walkAndExamine(); void obName(); void obName(uint8 command, uint8 commandType); - void delPointer(); - void showPointer(); - void animPointer(); - void checkCoords(); void checkCoords(const RectWithCallback *rectWithCallbacks); - void readMouse(); - uint16 readMouseState(); - uint16 waitFrames(); - void drawFlags(); - void addToPeopleList(); - void addToPeopleList(ReelRoutine *routine); void getExPos(); - void panelToMap(); - void mapToPanel(); - void dumpMap(); - void obPicture(); - void transferInv(); - void obIcons(); void compare(); - bool compare(uint8 index, uint8 flag, const char id[4]); + bool compare(uint8 index, uint8 flag, const char id[4]) { + return DreamBase::compare(index, flag, id); + } bool pixelCheckSet(const ObjPos *pos, uint8 x, uint8 y); - bool isItDescribed(const ObjPos *objPos); void checkIfSet(); bool checkIfSet(uint8 x, uint8 y); - void checkIfPathIsOn(); - bool checkIfPathIsOn(uint8 index); void isItWorn(); - bool isItWorn(const DynObject *object); + bool isItWorn(const DynObject *object) { + return DreamBase::isItWorn(object); + } void wornError(); void makeWorn(); void makeWorn(DynObject *object); void obToInv(); - void obToInv(uint8 index, uint8 flag, uint16 x, uint16 y); - void findAllRyan(); - void findAllRyan(uint8 *inv); - void fillRyan(); + void obToInv(uint8 index, uint8 flag, uint16 x, uint16 y) { + DreamBase::obToInv(index, flag, x, y); + } void useRoutine(); void hangOn(); - void hangOn(uint16 frameCount); - void hangOnW(); - void hangOnW(uint16 frameCount); + void hangOn(uint16 frameCount) { + DreamBase::hangOn(frameCount); + } void hangOnP(); - void hangOnP(uint16 count); - void showIcon(); - uint8 findNextColon(uint8 **string); + void hangOnP(uint16 count) { + DreamBase::hangOnP(count); + } + uint8 findNextColon(const uint8 **string) { + return DreamBase::findNextColon(string); + } void findNextColon(); - uint8 *getObTextStartCPP(); + const uint8 *getObTextStartCPP(); void useText(const uint8 *string); - void useText(); - void getBlockOfPixel(); - uint8 getBlockOfPixel(uint8 x, uint8 y); - void bresenhams(); void examineObText(); - void sortOutMap(); void showCity(); uint16 getPersFrame(uint8 index); void convIcons(); void examineOb(bool examineAgain = true); - void showWatch(); void dumpWatch(); - void showTime(); - void roomName(); void transferText(); - void initRain(); - Rain *splitIntoLines(uint8 x, uint8 y, Rain *rain); - uint8 *mainPalette(); - uint8 *startPalette(); - uint8 *endPalette(); - void clearStartPal(); - void clearEndPal(); - void palToStartPal(); - void endPalToStart(); - void startPalToEnd(); - void palToEndPal(); - void fadeCalculation(); void watchCount(); - void zoomIcon(); void loadRoom(); - void getUnderMenu(); - void putUnderMenu(); - void textForMonk(); - void textForMonkHelper(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount); - void textForEnd(); - void monks2text(); - void intro1Text(); - void intro2Text(); - void intro3Text(); void readSetData(); - void loadRoomsSample(); - void fadeupYellows(); - void fadeupMonFirst(); - void printLogo(); - void loadMenu(); - void showMenu(); - void dumpMenu(); void useMenu(); void useMon(); - void scrollMonitor(); - void showCurrentFile(); - void input(); + void makeCaps(); + byte makeCaps(byte c) { + return DreamBase::makeCaps(c); + } void monPrint(); - const char *monPrint(const char *string); - Frame *tempGraphics(); - Frame *tempGraphics2(); - Frame *tempGraphics3(); - void accessLightOn(); - void accessLightOff(); - void randomAccess(uint16 count); + const char *monPrint(const char *string) { + return DreamBase::monPrint(string); + } void randomAccess(); - void monMessage(uint8 index); + void randomAccess(uint16 count) { + DreamBase::randomAccess(count); + } void monMessage(); - void netError(); - void turnOnPower(); - void powerLightOn(); - void powerLightOff(); - void playChannel0(); - void playChannel0(uint8 index, uint8 repeat); + void monMessage(uint8 index) { + DreamBase::monMessage(index); + } void playChannel1(); - void playChannel1(uint8 index); - void showMainOps(); - void showDiscOps(); - void findRoomInLoc(); - void reelsOnScreen(); - void reconstruct(); + void playChannel1(uint8 index) { + DreamBase::playChannel1(index); + } void look(); void autoLook(); void doLook(); - void useTempCharset(); - void useCharset1(); - void getBackFromOb(); - void getRidOfAll(); - void getRidOfTemp(); - void getRidOfTempText(); - void getRidOfTemp2(); - void getRidOfTemp3(); - void getRidOfTempCharset(); - void getRidOfTempsP(); void showFirstUse(); void showSecondUse(); void actualSave(); void actualLoad(); - void loadPosition(unsigned int slot); - void savePosition(unsigned int slot, const uint8 *descbuf); - void openForSave(unsigned int slot); - bool openForLoad(unsigned int slot); - uint16 allocateAndLoad(unsigned int size); - void clearAndLoad(uint8 *buf, uint8 c, unsigned int size, unsigned int maxSize); - void clearAndLoad(uint16 seg, uint8 c, unsigned int size, unsigned int maxSize); - void loadRoomData(const Room &room, bool skipDat); void restoreAll(); - void restoreReels(); void enterSymbol(); void viewFolder(); void edensCDPlayer(); @@ -377,6 +196,12 @@ void useRailing(); void useWindow(); void useHatch(); + void useLighter(); + void useSLab(); + void usePipe(); + void useOpenBox(); + void useAxe(); + void useKey(); void wheelSound(); void callHotelLift(); void useShield(); @@ -393,93 +218,22 @@ void useCardReader2(); void useCardReader3(); void usePoolReader(); + void useCooker(); + void useWire(); + void useControl(); + void useHandle(); + void useAltar(); bool defaultUseHandler(const char *id); void openTVDoor(); void wearWatch(); void wearShades(); void checkFolderCoords(); - void loadFolder(); - void showFolder(); - void showLeftPage(); - void showRightPage(); void nextFolder(); void lastFolder(); - void folderHints(); - void folderExit(); - uint8 getLocation(uint8 index); - void getLocation(); - void setLocation(uint8 index); - void setLocation(); - const uint8 *getTextInFile1(uint16 index); - void loadTempText(); - void loadTempText(const char *fileName); - void loadTravelText(); - void drawFloor(); - void allocateBuffers(); - void workToScreenM(); - bool checkSpeed(ReelRoutine &routine); - void checkSpeed(); - void sparkyDrip(ReelRoutine &routine); - void genericPerson(ReelRoutine &routine); - void gamer(ReelRoutine &routine); - void eden(ReelRoutine &routine); - void sparky(ReelRoutine &routine); - void rockstar(ReelRoutine &routine); - void madmansTelly(ReelRoutine &routine); - void smokeBloke(ReelRoutine &routine); - void manAsleep(ReelRoutine &routine); - void drunk(ReelRoutine &routine); - void introMagic1(ReelRoutine &routine); - void introMagic2(ReelRoutine &routine); - void introMagic3(ReelRoutine &routine); - void introMusic(ReelRoutine &routine); - void candles(ReelRoutine &routine); - void candles1(ReelRoutine &routine); - void candles2(ReelRoutine &routine); - void smallCandle(ReelRoutine &routine); - void gates(ReelRoutine &routine); - void security(ReelRoutine &routine); - void edenInBath(ReelRoutine &routine); - void louis(ReelRoutine &routine); - void handClap(ReelRoutine &routine); - void carParkDrip(ReelRoutine &routine); - void foghornSound(ReelRoutine &routine); - void train(ReelRoutine &routine); - void attendant(ReelRoutine &routine); - void keeper(ReelRoutine &routine); - void interviewer(ReelRoutine &routine); - void drinker(ReelRoutine &routine); - void alleyBarkSound(ReelRoutine &routine); - void louisChair(ReelRoutine &routine); - void bossMan(ReelRoutine &routine); - void priest(ReelRoutine &routine); - void priestText(ReelRoutine &routine); - void monkAndRyan(ReelRoutine &routine); void singleKey(uint8 key, uint16 x, uint16 y); void loadSaveBox(); - void loadKeypad(); - void showKeypad(); - void showOuterPad(); uint8 nextSymbol(uint8 symbol); void showSymbol(); - void showExit(); - void showMan(); - void panelIcons1(); - void examIcon(); - void buttonOne(); - void buttonTwo(); - void buttonThree(); - void buttonFour(); - void buttonFive(); - void buttonSix(); - void buttonSeven(); - void buttonEight(); - void buttonNine(); - void buttonNought(); - void buttonEnter(); - void buttonPress(uint8 buttonId); - void addToPressList(); - bool isItRight(uint8 digit0, uint8 digit1, uint8 digit2, uint8 digit3); void enterCode(uint8 digit0, uint8 digit1, uint8 digit2, uint8 digit3); unsigned int scanForNames(); void doLoad(int slot); @@ -490,35 +244,13 @@ void saveGame(); void zoomOnOff(); void atmospheres(); - void loadPersonal(); - void loadNews(); - void loadCart(); - void soundOnReels(); - void readKey(); void hangOne(uint16 delay); void hangOne(); - void showPCX(const Common::String &name); void bibleQuote(); void realCredits(); void runIntroSeq(); void intro(); - void fadeScreenUp(); - void fadeScreenUps(); - void fadeScreenUpHalf(); - void fadeScreenDown(); - void fadeScreenDowns(); - void clearBeforeLoad(); - void clearReels(); - void getRidOfReels(); - void setMode(); - void liftNoise(uint8 index); - void setTopLeft(); - void setTopRight(); - void setBotLeft(); - void setBotRight(); void newGame(); - void getBackFromOps(); - void getBackToOps(); void pickupOb(uint8 command, uint8 pos); void initialInv(); void walkIntoRoom(); @@ -526,8 +258,8 @@ void afterIntroRoom(); void gettingShot(); void redrawMainScrn(); + void selectSlot(); void selectSlot2(); - void blank(); void allPointer(); void openYourNeighbour(); void openRyan(); @@ -535,13 +267,12 @@ void openEden(); void openSarters(); void openLouis(); - void DOSReturn(); - void setWalk(); void useLadder(); void useLadderB(); void useCart(); void useTrainer(); void useHole(); + void runTap(); void chewy(); void sLabDoorA(); void sLabDoorB(); @@ -555,10 +286,7 @@ void openTomb(); void hotelControl(); void obsThatDoThings(); - void makeMainScreen(); - void openInv(); void delEverything(); - void clearPalette(); void errorMessage1(); void errorMessage2(); void errorMessage3(); @@ -569,20 +297,85 @@ void putBackObStuff(); void moreTalk(); void redes(); - void isSetObOnMap(); - bool isSetObOnMap(uint8 index); - void dumpKeypad(); - void dumpSymbol(); - void dumpSymBox(); - void dumpZoom(); - void fadeDOS(); void selectLocation(); - void vSync(); void showGroup(); void loadSpeech(); - void closeFile(); - void getTime(); + bool loadSpeech(byte type1, int idx1, byte type2, int idx2) { + return DreamBase::loadSpeech(type1, idx1, type2, idx2); + } void set16ColPalette(); - void examineInventory(); + void showSaveOps(); + void showLoadOps(); + void afterNewRoom(); + void madmanRun(); + void showDecisions(); + void decide(); + void talk(); + void discOps(); + void doSaveLoad(); + void useDiary(); + void hangOnPQ(); + void showGun(); + void endGame(); + void checkInput(); + void dropError(); + void cantDrop(); + void newPlace(); + void monkSpeaking(); + void rollEndCredits2(); + void useButtonA(); + void autoAppear(); + void setupTimedUse(); + void entryAnims(); + void triggerMessage(uint16 index); + void processTrigger(); + void updateSymbolTop(); + void updateSymbolBot(); + void showDiaryPage(); + void dumpDiaryKeys(); + void runEndSeq(); + void lookAtCard(); + bool execCommand(); + void findExObject(); + uint16 findExObject(const char *id) { + return DreamBase::findExObject(id); + } + void isRyanHolding(); + bool isRyanHolding(const char *id) { + return DreamBase::isRyanHolding(id); + } + void describeOb(); + void getOpenedSize(); + byte getOpenedSizeCPP(); + void openOb(); + void notHeldError(); + void useGun(); + void identifyOb(); + void showSlots(); + void useCashCard(); + void useStereo(); + void selectOb(); + void findInvPos(); + uint16 findInvPosCPP(); + void setPickup(); + void showDiaryKeys(); + void showKeys(); + void getKeyAndLogo(); + void deleteExObject(); + void deleteExObject(uint8 index) { + DreamBase::deleteExObject(index); + } + void deleteExFrame(); + void deleteExFrame(uint8 frameNum) { + DreamBase::deleteExFrame(frameNum); + } + void deleteExText(); + void deleteExText(uint8 textNum) { + DreamBase::deleteExText(textNum); + } + void signOn(); + void lookAtPlace(); + void inToInv(); + void outOfInv(); #endif diff --git a/engines/dreamweb/talk.cpp b/engines/dreamweb/talk.cpp index 42fc3523a5..86d1b886ef 100644 --- a/engines/dreamweb/talk.cpp +++ b/engines/dreamweb/talk.cpp @@ -30,10 +30,9 @@ uint16 DreamGenContext::getPersFrame(uint8 index) { void DreamGenContext::convIcons() { uint8 index = data.byte(kCharacter) & 127; - data.word(kCurrentframe) = getPersFrame(index); - Frame *frame = findSource(); - uint16 frameNumber = (data.word(kCurrentframe) - data.word(kTakeoff)) & 0xff; - showFrame(frame, 234, 2, frameNumber, 0); + uint16 frame = getPersFrame(index); + const Frame *base = findSource(frame); + showFrame(base, 234, 2, frame, 0); } } // End of namespace DreamGen diff --git a/engines/dreamweb/use.cpp b/engines/dreamweb/use.cpp index 044a4fba40..5cb1f6b92c 100644 --- a/engines/dreamweb/use.cpp +++ b/engines/dreamweb/use.cpp @@ -139,7 +139,7 @@ void DreamGenContext::useRoutine() { } delPointer(); - uint8 *obText = getObTextStartCPP(); + const uint8 *obText = getObTextStartCPP(); if (findNextColon(&obText) != 0) { if (findNextColon(&obText) != 0) { if (*obText != 0) { @@ -163,10 +163,6 @@ void DreamGenContext::useRoutine() { data.byte(kCommandtype) = 255; } -void DreamGenContext::useText() { - useText(es.ptr(si, 0)); -} - void DreamGenContext::useText(const uint8 *string) { createPanel(); showPanel(); @@ -178,7 +174,7 @@ void DreamGenContext::useText(const uint8 *string) { } void DreamGenContext::showFirstUse() { - uint8 *obText = getObTextStartCPP(); + const uint8 *obText = getObTextStartCPP(); findNextColon(&obText); findNextColon(&obText); useText(obText); @@ -186,7 +182,7 @@ void DreamGenContext::showFirstUse() { } void DreamGenContext::showSecondUse() { - uint8 *obText = getObTextStartCPP(); + const uint8 *obText = getObTextStartCPP(); findNextColon(&obText); findNextColon(&obText); findNextColon(&obText); @@ -625,17 +621,9 @@ void DreamGenContext::sLabDoorB() { data.byte(kWatchspeed) = 1; data.byte(kSpeedcount) = 1; } else { - al = 'S'; - ah = 'H'; - cl = 'L'; - ch = 'D'; - isRyanHolding(); - - if (flags.z()) { + if (!isRyanHolding("SHLD")) { // No crystal - al = 44; - cx = 200; - showPuzText(); + showPuzText(44, 200); putBackObStuff(); } else { // Got crystal @@ -740,9 +728,7 @@ bool DreamGenContext::defaultUseHandler(const char *id) { if (!compare(data.byte(kWithobject), data.byte(kWithtype), id)) { // Wrong item - cx = 300; - al = 14; - showPuzText(); + showPuzText(14, 300); putBackObStuff(); return true; // event handled } @@ -751,8 +737,7 @@ bool DreamGenContext::defaultUseHandler(const char *id) { } void DreamGenContext::useChurchGate() { - char id[4] = { 'C', 'U', 'T', 'T' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("CUTT")) return; // Cut gate @@ -769,6 +754,118 @@ void DreamGenContext::useChurchGate() { turnPathOn(2); // Open church } +void DreamGenContext::useGun() { + + if (data.byte(kObjecttype) != kExObjectType) { + // gun is not taken + showSecondUse(); + putBackObStuff(); + + } else if (data.byte(kReallocation) == 22) { + // in pool room + showPuzText(34, 300); + data.byte(kLastweapon) = 1; + data.byte(kCombatcount) = 39; + data.byte(kGetback) = 1; + data.byte(kProgresspoints)++; + + } else if (data.byte(kReallocation) == 25) { + // helicopter + showPuzText(34, 300); + data.byte(kLastweapon) = 1; + data.byte(kCombatcount) = 19; + data.byte(kGetback) = 1; + data.byte(kDreamnumber) = 2; + data.byte(kRoomafterdream) = 38; + data.byte(kSartaindead) = 1; + data.byte(kProgresspoints)++; + + } else if (data.byte(kReallocation) == 27) { + // in rock room + showPuzText(46, 300); + data.byte(kPointermode) = 2; + data.byte(kRockstardead) = 1; + data.byte(kLastweapon) = 1; + data.byte(kNewsitem) = 1; + data.byte(kGetback) = 1; + data.byte(kRoomafterdream) = 32; + data.byte(kDreamnumber) = 0; + data.byte(kProgresspoints)++; + + } else if (data.byte(kReallocation) == 8 && data.byte(kMapx) == 22 && data.byte(kMapy) == 40 + && !isSetObOnMap(92) && data.byte(kManspath) != 9) { + // by studio + data.byte(kDestination) = 9; + data.byte(kFinaldest) = 9; + autoSetWalk(); + data.byte(kLastweapon) = 1; + data.byte(kGetback) = 1; + data.byte(kProgresspoints)++; + + } else if (data.byte(kReallocation) == 6 && data.byte(kMapx) == 11 && data.byte(kMapy) == 20 + && isSetObOnMap(5)) { + // sarters + data.byte(kDestination) = 1; + data.byte(kFinaldest) = 1; + autoSetWalk(); + removeSetObject(5); + placeSetObject(6); + turnAnyPathOn(1, data.byte(kRoomnum) - 1); + data.byte(kLiftflag) = 1; + data.word(kWatchingtime) = 40*2; + data.word(kReeltowatch) = 4; + data.word(kEndwatchreel) = 43; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + data.byte(kGetback) = 1; + data.byte(kProgresspoints)++; + + } else if (data.byte(kReallocation) == 29) { + // aide + data.byte(kGetback) = 1; + al = 13; + resetLocation(); + setLocation(12); + data.byte(kDestpos) = 12; + data.byte(kDestination) = 2; + data.byte(kFinaldest) = 2; + autoSetWalk(); + data.word(kWatchingtime) = 164*2; + data.word(kReeltowatch) = 3; + data.word(kEndwatchreel) = 164; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + data.byte(kAidedead) = 1; + data.byte(kDreamnumber) = 3; + data.byte(kRoomafterdream) = 33; + data.byte(kProgresspoints)++; + + } else if (data.byte(kReallocation) == 23 && data.byte(kMapx) == 0 && data.byte(kMapy) == 50) { + // with boss + if (data.byte(kManspath) != 5) { + data.byte(kDestination) = 5; + data.byte(kFinaldest) = 5; + autoSetWalk(); + } + data.byte(kLastweapon) = 1; + data.byte(kGetback) = 1; + + } else if (data.byte(kReallocation) == 8 && data.byte(kMapx) == 11 && data.byte(kMapy) == 10) { + // tv soldier + if (data.byte(kManspath) != 2) { + data.byte(kDestination) = 2; + data.byte(kFinaldest) = 2; + autoSetWalk(); + } + data.byte(kLastweapon) = 1; + data.byte(kGetback) = 1; + + } else { + showFirstUse(); + putBackObStuff(); + } +} + void DreamGenContext::useFullCart() { data.byte(kProgresspoints)++; turnAnyPathOn(2, data.byte(kRoomnum) + 6); @@ -788,8 +885,7 @@ void DreamGenContext::useFullCart() { } void DreamGenContext::useClearBox() { - char id[4] = { 'R', 'A', 'I', 'L' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("RAIL")) return; // Open box @@ -804,8 +900,7 @@ void DreamGenContext::useClearBox() { } void DreamGenContext::openTVDoor() { - char id[4] = { 'U', 'L', 'O', 'K' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("ULOK")) return; // Key on TV @@ -820,30 +915,23 @@ void DreamGenContext::usePlate() { return; } - char screw[4] = { 'S', 'C', 'R', 'W' }; // TODO: convert to string with trailing zero - char knife[4] = { 'K', 'N', 'F', 'E' }; // TODO: convert to string with trailing zero - if (compare(data.byte(kWithobject), data.byte(kWithtype), screw)) { + if (compare(data.byte(kWithobject), data.byte(kWithtype), "SCRW")) { // Unscrew plate playChannel1(20); showFirstUse(); placeSetObject(28); placeSetObject(24); removeSetObject(25); - al = 0; - placeFreeObject(); + placeFreeObject(0); data.byte(kProgresspoints)++; data.byte(kGetback) = 1; - } else if (compare(data.byte(kWithobject), data.byte(kWithtype), knife)) { + } else if (compare(data.byte(kWithobject), data.byte(kWithtype), "KNFE")) { // Tried knife - cx = 300; - al = 54; - showPuzText(); + showPuzText(54, 300); putBackObStuff(); } else { // Wrong item - cx = 300; - al = 14; - showPuzText(); + showPuzText(14, 300); putBackObStuff(); } } @@ -854,8 +942,7 @@ void DreamGenContext::usePlinth() { return; } - char id[4] = { 'D', 'K', 'E', 'Y' }; // TODO: convert to string with trailing zero - if (!compare(data.byte(kWithobject), data.byte(kWithtype), id)) { + if (!compare(data.byte(kWithobject), data.byte(kWithtype), "DKEY")) { // Wrong key showFirstUse(); putBackObStuff(); @@ -873,15 +960,12 @@ void DreamGenContext::usePlinth() { } void DreamGenContext::useElvDoor() { - char id[4] = { 'A', 'X', 'E', 'D' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("AXED")) return; // Axe on door - al = 15; - cx = 300; - showPuzText(); - _inc(data.byte(kProgresspoints)); + showPuzText(15, 300); + data.byte(kProgresspoints)++; data.word(kWatchingtime) = 46 * 2; data.word(kReeltowatch) = 31; data.word(kEndwatchreel) = 77; @@ -906,12 +990,8 @@ void DreamGenContext::useObject() { } void DreamGenContext::useWinch() { - al = 40; - ah = 1; - checkInside(); - - char id[4] = { 'F', 'U', 'S', 'E' }; // TODO: convert to string with trailing zero - if (cl == kNumexobjects || !compare(cl, 4, id)) { + uint16 contentIndex = checkInside(40, 1); + if (contentIndex == kNumexobjects || !compare(contentIndex, kExObjectType, "FUSE")) { // No winch showFirstUse(); putBackObStuff(); @@ -934,8 +1014,7 @@ void DreamGenContext::useWinch() { } void DreamGenContext::useCart() { - char id[4] = { 'R', 'O', 'C', 'K' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("ROCK")) return; DynObject *exObject = getExAd(data.byte(kWithobject)); @@ -970,8 +1049,7 @@ void DreamGenContext::chewy() { } void DreamGenContext::useHole() { - char id[4] = { 'H', 'N', 'D', 'A' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("HNDA")) return; showFirstUse(); @@ -983,8 +1061,7 @@ void DreamGenContext::useHole() { } void DreamGenContext::openHotelDoor() { - char id[4] = { 'K', 'E', 'Y', 'A' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("KEYA")) return; playChannel1(16); @@ -994,8 +1071,7 @@ void DreamGenContext::openHotelDoor() { } void DreamGenContext::openHotelDoor2() { - char id[4] = { 'K', 'E', 'Y', 'A' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("KEYA")) return; playChannel1(16); @@ -1004,8 +1080,7 @@ void DreamGenContext::openHotelDoor2() { } void DreamGenContext::grafittiDoor() { - char id[4] = { 'A', 'P', 'E', 'N' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("APEN")) return; showFirstUse(); @@ -1013,8 +1088,7 @@ void DreamGenContext::grafittiDoor() { } void DreamGenContext::usePoolReader() { - char id[4] = { 'M', 'E', 'M', 'B' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("MEMB")) return; if (data.byte(kTalkedtoattendant) != 1) { @@ -1030,8 +1104,7 @@ void DreamGenContext::usePoolReader() { } void DreamGenContext::useCardReader1() { - char id[4] = { 'C', 'S', 'H', 'R' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("CSHR")) return; if (data.byte(kTalkedtosparky) == 0) { @@ -1040,16 +1113,12 @@ void DreamGenContext::useCardReader1() { putBackObStuff(); } else if (data.word(kCard1money) != 0) { // No cash - cx = 300; - al = 17; - showPuzText(); + showPuzText(17, 300); putBackObStuff(); } else { // Get cash playChannel1(16); - cx = 300; - al = 18; - showPuzText(); + showPuzText(18, 300); data.byte(kProgresspoints)++; data.word(kCard1money) = 12432; data.byte(kGetback) = 1; @@ -1057,8 +1126,7 @@ void DreamGenContext::useCardReader1() { } void DreamGenContext::useCardReader2() { - char id[4] = { 'C', 'S', 'H', 'R' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("CSHR")) return; if (data.byte(kTalkedtoboss) == 0) { @@ -1067,21 +1135,15 @@ void DreamGenContext::useCardReader2() { putBackObStuff(); } else if (data.byte(kCard1money) == 0) { // No cash - cx = 300; - al = 20; - showPuzText(); + showPuzText(20, 300); putBackObStuff(); } else if (data.byte(kGunpassflag) == 2) { // Already got new - cx = 300; - al = 22; - showPuzText(); + showPuzText(22, 300); putBackObStuff(); } else { playChannel1(18); - cx = 300; - al = 19; - showPuzText(); + showPuzText(19, 300); placeSetObject(94); data.byte(kGunpassflag) = 1; data.word(kCard1money) -= 2000; @@ -1091,8 +1153,7 @@ void DreamGenContext::useCardReader2() { } void DreamGenContext::useCardReader3() { - char id[4] = { 'C', 'S', 'H', 'R' }; // TODO: convert to string with trailing zero - if (defaultUseHandler(id)) + if (defaultUseHandler("CSHR")) return; if (data.byte(kTalkedtorecep) == 0) { @@ -1101,15 +1162,11 @@ void DreamGenContext::useCardReader3() { putBackObStuff(); } else if (data.byte(kCardpassflag) != 0) { // Already used it - cx = 300; - al = 26; - showPuzText(); + showPuzText(26, 300); putBackObStuff(); } else { playChannel1(16); - cx = 300; - al = 25; - showPuzText(); + showPuzText(25, 300); data.byte(kProgresspoints)++; data.word(kCard1money) -= 8300; data.byte(kCardpassflag) = 1; @@ -1117,6 +1174,48 @@ void DreamGenContext::useCardReader3() { } } +void DreamGenContext::useLighter() { + if (data.byte(kWithobject) == 255) { + withWhat(); + return; + } + + if (!compare(data.byte(kWithobject), data.byte(kWithtype), "SMKE")) { + showFirstUse(); + putBackObStuff(); + } else { + showPuzText(9, 300); + DynObject *withObj = getExAd(data.byte(kWithobject)); + withObj->mapad[0] = 255; + data.byte(kGetback) = 1; + } +} + +void DreamGenContext::useWire() { + if (data.byte(kWithobject) == 255) { + withWhat(); + return; + } + + if (compare(data.byte(kWithobject), data.byte(kWithtype), "KNFE")) { + removeSetObject(51); + placeSetObject(52); + showPuzText(11, 300); + data.byte(kProgresspoints)++; + data.byte(kGetback) = 1; + return; + } + + if (compare(data.byte(kWithobject), data.byte(kWithtype), "AXED")) { + showPuzText(16, 300); + putBackObStuff(); + return; + } + + showPuzText(14, 300); + putBackObStuff(); +} + void DreamGenContext::openTomb() { data.byte(kProgresspoints)++; showFirstUse(); @@ -1137,4 +1236,452 @@ void DreamGenContext::hotelControl() { putBackObStuff(); } +void DreamGenContext::useCooker() { + if (checkInside(data.byte(kCommand), data.byte(kObjecttype)) == kNumexobjects) + showFirstUse(); + else + showSecondUse(); // Food inside + + putBackObStuff(); +} + +void DreamBase::placeFreeObject(uint8 index) { + findOrMake(index, 0, 1); + getFreeAd(index)->mapad[0] = 0; +} + +void DreamBase::removeFreeObject(uint8 index) { + getFreeAd(index)->mapad[0] = 0xFF; +} + +void DreamGenContext::useDiary() { + getRidOfReels(); + loadIntoTemp("DREAMWEB.G14"); + loadTempText("DREAMWEB.T51"); + loadTempCharset("DREAMWEB.C02"); + createPanel(); + showIcon(); + showDiary(); + underTextLine(); + showDiaryPage(); + readMouse(); + showPointer(); + workToScreenCPP(); + delPointer(); + data.byte(kGetback) = 0; + + RectWithCallback diaryList[] = { + { kDiaryx+94,kDiaryx+110,kDiaryy+97,kDiaryy+113,&DreamBase::diaryKeyN }, + { kDiaryx+151,kDiaryx+167,kDiaryy+71,kDiaryy+87,&DreamBase::diaryKeyP }, + { kDiaryx+176,kDiaryx+192,kDiaryy+108,kDiaryy+124,&DreamBase::quitKey }, + { 0,320,0,200,&DreamBase::blank }, + { 0xFFFF,0,0,0,0 } + }; + + do { + delPointer(); + readMouse(); + showDiaryKeys(); + showPointer(); + vSync(); + dumpPointer(); + dumpDiaryKeys(); + dumpTextLine(); + checkCoords(diaryList); + } while (!data.byte(kGetback) && !quitRequested()); + + + getRidOfTemp(); + getRidOfTempText(); + getRidOfTempCharset(); + restoreReels(); + data.byte(kManisoffscreen) = 0; + redrawMainScrn(); + workToScreenM(); +} + +void DreamGenContext::useControl() { + if (data.byte(kWithobject) == 255) { + withWhat(); + return; + } + + if (compare(data.byte(kWithobject), data.byte(kWithtype), "KEYA")) { // Right key + playChannel1(16); + if (data.byte(kLocation) == 21) { // Going down + showPuzText(3, 300); + data.byte(kNewlocation) = 30; + } else { + showPuzText(0, 300); + data.byte(kNewlocation) = 21; + } + + data.byte(kCounttoclose) = 8; + data.byte(kCounttoopen) = 0; + data.word(kWatchingtime) = 80; + data.byte(kGetback) = 1; + return; + } + + if (data.byte(kReallocation) == 21) { + if (compare(data.byte(kWithobject), data.byte(kWithtype), "KNFE")) { + // Jimmy controls + placeSetObject(50); + placeSetObject(51); + placeSetObject(26); + placeSetObject(30); + removeSetObject(16); + removeSetObject(17); + playChannel1(14); + showPuzText(10, 300); + data.byte(kProgresspoints)++; + data.byte(kGetback) = 1; + } else if (compare(data.byte(kWithobject), data.byte(kWithtype), "AXED")) { + // Axe on controls + showPuzText(16, 300); + data.byte(kProgresspoints)++; + putBackObStuff(); + } else { + // Balls + showFirstUse(); + putBackObStuff(); + } + } else { + // Balls + showFirstUse(); + putBackObStuff(); + } +} + +void DreamGenContext::useSLab() { + if (data.byte(kWithobject) == 255) { + withWhat(); + return; + } + + if (!compare(data.byte(kWithobject), data.byte(kWithtype), "JEWL")) { + showPuzText(14, 300); + putBackObStuff(); + return; + } + + DynObject *exObject = getExAd(data.byte(kWithobject)); + exObject->mapad[0] = 0; + + removeSetObject(data.byte(kCommand)); + placeSetObject(data.byte(kCommand) + 1); + if (data.byte(kCommand) + 1 == 54) { + // Last slab + turnPathOn(0); + data.word(kWatchingtime) = 22; + data.word(kReeltowatch) = 35; + data.word(kEndwatchreel) = 48; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + } + + data.byte(kProgresspoints)++; + showFirstUse(); + data.byte(kGetback) = 1; +} + +void DreamGenContext::usePipe() { + if (data.byte(kWithobject) == 255) { + withWhat(); + return; + } + + if (compare(data.byte(kWithobject), data.byte(kWithtype), "CUPE")) { + // Fill cup + showPuzText(36, 300); + putBackObStuff(); + DynObject *exObject = getExAd(data.byte(kWithobject)); + exObject->id[3] = 'F'-'A'; // CUPE (empty cup) -> CUPF (full cup) + return; + } else if (compare(data.byte(kWithobject), data.byte(kWithtype), "CUPF")) { + // Already full + showPuzText(35, 300); + putBackObStuff(); + } else { + showPuzText(14, 300); + putBackObStuff(); + } +} + +void DreamGenContext::useOpenBox() { + if (data.byte(kWithobject) == 255) { + withWhat(); + return; + } + + if (compare(data.byte(kWithobject), data.byte(kWithtype), "CUPF")) { + // Destroy open box + data.byte(kProgresspoints)++; + showPuzText(37, 300); + DynObject *exObject = getExAd(data.byte(kWithobject)); + exObject->id[3] = 'E'-'A'; // CUPF (full cup) -> CUPE (empty cup) + data.word(kWatchingtime) = 140; + data.word(kReeltowatch) = 105; + data.word(kEndwatchreel) = 181; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + turnPathOn(4); + data.byte(kGetback) = 1; + return; + } + + if (compare(data.byte(kWithobject), data.byte(kWithtype), "CUPE")) { + // Open box wrong + showPuzText(38, 300); + putBackObStuff(); + return; + } + + showFirstUse(); +} + +void DreamGenContext::runTap() { + if (data.byte(kWithobject) == 255) { + withWhat(); + return; + } + + if (compare(data.byte(kWithobject), data.byte(kWithtype), "CUPE")) { + // Fill cup from tap + DynObject *exObject = getExAd(data.byte(kWithobject)); + exObject->id[3] = 'F'-'A'; // CUPE (empty cup) -> CUPF (full cup) + playChannel1(8); + showPuzText(57, 300); + putBackObStuff(); + return; + } + + if (compare(data.byte(kWithobject), data.byte(kWithtype), "CUPF")) { + // Cup from tap full + showPuzText(58, 300); + putBackObStuff(); + return; + } + + showPuzText(56, 300); + putBackObStuff(); +} + +void DreamGenContext::useAxe() { + if (data.byte(kReallocation) != 22) { + // Not in pool + showFirstUse(); + return; + } + + if (data.byte(kMapy) == 10) { + // Axe on door + showPuzText(15, 300); + data.byte(kProgresspoints)++; + data.word(kWatchingtime) = 46*2; + data.word(kReeltowatch) = 31; + data.word(kEndwatchreel) = 77; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + data.byte(kGetback) = 1; + return; + } + + showSecondUse(); + data.byte(kProgresspoints)++; + data.byte(kLastweapon) = 2; + data.byte(kGetback) = 1; + removeObFromInv(); +} + +void DreamGenContext::useKey() { + switch(data.byte(kLocation)) { + case 5: + case 30: + if (data.byte(kMapx) == 22 && data.byte(kMapy) == 10) { + showPuzText(0, 300); + data.byte(kCounttoclose) = 100; + data.byte(kGetback) = 1; + } else { + // Wrong room + showPuzText(2, 200); + putBackObStuff(); + } + break; + case 21: + if (data.byte(kMapx) == 11 && data.byte(kMapy) == 10) { + showPuzText(3, 300); + data.byte(kNewlocation) = 30; + al = 2; + fadeScreenDown(); + showFirstUse(); + putBackObStuff(); + } else { + // Wrong room + showPuzText(2, 200); + putBackObStuff(); + } + default: + showPuzText(1, 200); + putBackObStuff(); + break; + } +} + +void DreamGenContext::useHandle() { + SetObject *object = getSetAd(findSetObject("CUTW")); + if (object->mapad[0] == 255) { + // Wire not cut + showPuzText(12, 300); + } else { + // Wire has been cut + showPuzText(13, 300); + data.byte(kNewlocation) = 22; + } + + data.byte(kGetback) = 1; +} + +void DreamGenContext::useAltar() { + if (findExObject("CNDA") == 114 || findExObject("CNDB") == 114) { + // Things on altar + showFirstUse(); + data.byte(kGetback) = 1; + return; + } + + if (data.byte(kCanmovealtar) == 1) { + // Move altar + data.byte(kProgresspoints)++; + showSecondUse(); + data.word(kWatchingtime) = 160; + data.word(kReeltowatch) = 81; + data.word(kEndwatchreel) = 174; + data.byte(kWatchspeed) = 1; + data.byte(kSpeedcount) = 1; + DreamBase::setupTimedUse(47, 32, 98, 52, 76); + data.byte(kGetback) = 1; + } else { + showPuzText(23, 300); + data.byte(kGetback) = 1; + } +} + +void DreamBase::withWhat() { + uint8 commandLine[64] = "OBJECT NAME ONE "; + + createPanel(); + showPanel(); + showMan(); + showExit(); + + copyName(data.byte(kObjecttype), data.byte(kCommand), commandLine); + printMessage2(100, 21, 63, 200, false, 2); + uint16 x = data.word(kLastxpos) + 5; + printDirect(commandLine, x, 21, 220, false); + printMessage2(data.word(kLastxpos) + 5, 21, 63, 200, false, 3); + + fillRyan(); + data.byte(kCommandtype) = 255; + readMouse(); + showPointer(); + workToScreenCPP(); + delPointer(); + data.byte(kInvopen) = 2; +} + +void DreamGenContext::notHeldError() { + createPanel(); + showPanel(); + showMan(); + showExit(); + obIcons(); + printMessage2(64, 100, 63, 200 + 1, true, 1); + workToScreenM(); + hangOnP(50); + putBackObStuff(); +} + +void DreamGenContext::useCashCard() { + getRidOfReels(); + loadKeypad(); + createPanel(); + showPanel(); + showExit(); + showMan(); + uint16 y = (!data.byte(kForeignrelease)) ? 120 : 120 - 3; + showFrame(tempGraphics(), 114, y, 39, 0); + const uint8 *obText = getObTextStartCPP(); + findNextColon(&obText); + findNextColon(&obText); + y = 98; + printDirect(&obText, 36, &y, 36, 36 & 1); + char amountStr[10]; + sprintf(amountStr, "%04d", data.word(kCard1money) / 10); + data.word(kCharshift) = 91 * 2 + 75; + printDirect((const uint8 *)amountStr, 160, 155, 240, 240 & 1); + sprintf(amountStr, "%02d", (data.word(kCard1money) % 10) * 10); + data.word(kCharshift) = 91 * 2 + 85; + printDirect((const uint8 *)amountStr, 187, 155, 240, 240 & 1); + data.word(kCharshift) = 0; + workToScreenM(); + hangOnP(400); + getRidOfTemp(); + restoreReels(); + putBackObStuff(); +} + +void DreamGenContext::useStereo() { + if (data.byte(kLocation) != 0) { + showPuzText(4, 400); + putBackObStuff(); + } else if (data.byte(kMapx) != 11) { + showPuzText(5, 400); + putBackObStuff(); + } else if (checkInside(findSetObject("CDPL"), 1) == kNumexobjects) { + // No CD inside + showPuzText(6, 400); + putBackObStuff(); + // TODO: Use the C++ version of getAnyAd() + getAnyAd(); + es.byte(bx + 10) = 255; + } else { + // CD inside + getAnyAd(); + es.byte(bx + 10) ^= 1; + if (es.byte(bx + 10) != 255) { + // Stereo off + showPuzText(7, 400); + } else { + // Stereo on + showPuzText(8, 400); + } + + putBackObStuff(); + } +} + +uint16 DreamBase::checkInside(uint16 command, uint16 type) { + for (uint16 index = 0; index < kNumexobjects; index++) { + DynObject *object = getExAd(index); + if (object->mapad[1] == command && object->mapad[0] == type) + return index; + } + + return kNumexobjects; +} + +void DreamBase::showPuzText(uint16 command, uint16 count) { + createPanel(); + showPanel(); + showMan(); + showExit(); + obIcons(); + uint16 offset = kTextstart + getSegment(data.word(kPuzzletext)).word(command * 2); + const uint8 *string = getSegment(data.word(kPuzzletext)).ptr(offset, 0); + printDirect(string, 36, 104, 241, 241 & 1); + workToScreenM(); + hangOnP(count); +} + } // End of namespace DreamGen diff --git a/engines/dreamweb/vgafades.cpp b/engines/dreamweb/vgafades.cpp index a0d92c59c0..7518c226f4 100644 --- a/engines/dreamweb/vgafades.cpp +++ b/engines/dreamweb/vgafades.cpp @@ -24,43 +24,74 @@ namespace DreamGen { -uint8 *DreamGenContext::mainPalette() { +uint8 *DreamBase::mainPalette() { return getSegment(data.word(kBuffers)).ptr(kMaingamepal, 256 * 3); } -uint8 *DreamGenContext::startPalette() { +uint8 *DreamBase::startPalette() { return getSegment(data.word(kBuffers)).ptr(kStartpal, 256 * 3); } -uint8 *DreamGenContext::endPalette() { +uint8 *DreamBase::endPalette() { return getSegment(data.word(kBuffers)).ptr(kEndpal, 256 * 3); } -void DreamGenContext::clearStartPal() { +void DreamBase::clearStartPal() { memset(startPalette(), 0, 256 * 3); } -void DreamGenContext::clearEndPal() { +void DreamBase::clearEndPal() { memset(endPalette(), 0, 256 * 3); } -void DreamGenContext::palToStartPal() { +void DreamBase::palToStartPal() { memcpy(startPalette(), mainPalette(), 256 * 3); } -void DreamGenContext::endPalToStart() { +void DreamBase::endPalToStart() { memcpy(startPalette(), endPalette(), 256 * 3); } -void DreamGenContext::startPalToEnd() { +void DreamBase::startPalToEnd() { memcpy(endPalette(), startPalette(), 256 * 3); } -void DreamGenContext::palToEndPal() { +void DreamBase::palToEndPal() { memcpy(endPalette(), mainPalette(), 256 * 3); } -void DreamGenContext::fadeCalculation() { +void DreamBase::fadeDOS() { + return; // FIXME later + + engine->waitForVSync(); + //processEvents will be called from vsync + uint8 *dst = startPalette(); + engine->getPalette(dst, 0, 64); + for (int fade = 0; fade < 64; ++fade) { + for (int c = 0; c < 768; ++c) { //original sources decrement 768 values -> 256 colors + if (dst[c]) { + --dst[c]; + } + } + engine->setPalette(dst, 0, 64); + engine->waitForVSync(); + } +} + +void DreamBase::doFade() { + if (data.byte(kFadedirection) == 0) + return; + + engine->processEvents(); + uint8 *src = startPalette() + 3 * data.byte(kColourpos); + engine->setPalette(src, data.byte(kColourpos), data.byte(kNumtofade)); + + data.byte(kColourpos) += data.byte(kNumtofade); + if (data.byte(kColourpos) == 0) + fadeCalculation(); +} + +void DreamBase::fadeCalculation() { if (data.byte(kFadecount) == 0) { data.byte(kFadedirection) = 0; return; @@ -68,7 +99,7 @@ void DreamGenContext::fadeCalculation() { uint8 *startPal = startPalette(); const uint8 *endPal = endPalette(); - for (size_t i = 0; i < 256 * 3; ++i, ++si, ++di) { + for (size_t i = 0; i < 256 * 3; ++i) { uint8 s = startPal[i]; uint8 e = endPal[i]; if (s == e) @@ -83,7 +114,7 @@ void DreamGenContext::fadeCalculation() { --data.byte(kFadecount); } -void DreamGenContext::fadeupYellows() { +void DreamBase::fadeupYellows() { palToEndPal(); memset(endPalette() + 231 * 3, 0, 8 * 3); memset(endPalette() + 246 * 3, 0, 1 * 3); @@ -94,7 +125,7 @@ void DreamGenContext::fadeupYellows() { hangOn(128); } -void DreamGenContext::fadeupMonFirst() { +void DreamBase::fadeupMonFirst() { palToStartPal(); palToEndPal(); memset(startPalette() + 231 * 3, 0, 8 * 3); @@ -108,7 +139,7 @@ void DreamGenContext::fadeupMonFirst() { hangOn(64); } -void DreamGenContext::fadeScreenUp() { +void DreamBase::fadeScreenUp() { clearStartPal(); palToEndPal(); data.byte(kFadedirection) = 1; @@ -117,8 +148,7 @@ void DreamGenContext::fadeScreenUp() { data.byte(kNumtofade) = 128; } - -void DreamGenContext::fadeScreenUps() { +void DreamBase::fadeScreenUps() { clearStartPal(); palToEndPal(); data.byte(kFadedirection) = 1; @@ -127,7 +157,7 @@ void DreamGenContext::fadeScreenUps() { data.byte(kNumtofade) = 64; } -void DreamGenContext::fadeScreenUpHalf() { +void DreamBase::fadeScreenUpHalf() { endPalToStart(); palToEndPal(); data.byte(kFadedirection) = 1; @@ -136,7 +166,7 @@ void DreamGenContext::fadeScreenUpHalf() { data.byte(kNumtofade) = 32; } -void DreamGenContext::fadeScreenDown() { +void DreamBase::fadeScreenDown() { palToStartPal(); clearEndPal(); data.byte(kFadedirection) = 1; @@ -145,7 +175,7 @@ void DreamGenContext::fadeScreenDown() { data.byte(kNumtofade) = 128; } -void DreamGenContext::fadeScreenDowns() { +void DreamBase::fadeScreenDowns() { palToStartPal(); clearEndPal(); data.byte(kFadedirection) = 1; @@ -154,10 +184,93 @@ void DreamGenContext::fadeScreenDowns() { data.byte(kNumtofade) = 64; } -void DreamGenContext::clearPalette() { +void DreamBase::fadeScreenDownHalf() { + palToStartPal(); + palToEndPal(); + + const uint8 *startPal = startPalette(); + uint8 *endPal = endPalette(); + for (int i = 0; i < 256 * 3; ++i) { + *endPal >>= 1; + endPal++; + } + + memcpy(endPal + (56*3), startPal + (56*3), 3*5); + memcpy(endPal + (77*3), startPal + (77*3), 3*2); + + data.byte(kFadedirection) = 1; + data.byte(kFadecount) = 31; + data.byte(kColourpos) = 0; + data.byte(kNumtofade) = 32; +} + + +void DreamBase::clearPalette() { data.byte(kFadedirection) = 0; clearStartPal(); dumpCurrent(); } +// Converts palette to grey scale, summed using formula +// .20xred + .59xGreen + .11xBlue +void DreamBase::greyscaleSum() { + byte *src = mainPalette(); + byte *dst = endPalette(); + + for (int i = 0; i < 256; ++i) { + const unsigned int r = 20 * *src++; + const unsigned int g = 59 * *src++; + const unsigned int b = 11 * *src++; + const byte grey = (r + b + g) / 100; + byte tmp; + + tmp = grey; + //if (tmp != 0) // FIXME: The assembler code has this check commented out. Bug or feature? + tmp += data.byte(kAddtored); + *dst++ = tmp; + + tmp = grey; + if (tmp != 0) + tmp += data.byte(kAddtogreen); + *dst++ = tmp; + + tmp = grey; + if (tmp != 0) + tmp += data.byte(kAddtoblue); + *dst++ = tmp; + } +} + +void DreamBase::allPalette() { + memcpy(startPalette(), mainPalette(), 3 * 256); + dumpCurrent(); +} + +void DreamBase::dumpCurrent() { + uint8 *pal = startPalette(); + + engine->waitForVSync(); + engine->processEvents(); + engine->setPalette(pal, 0, 128); + + pal += 128 * 3; + + engine->waitForVSync(); + engine->processEvents(); + engine->setPalette(pal, 128, 128); +} + +void DreamGenContext::showGroup() { + engine->processEvents(); + unsigned n = (uint16)cx; + uint8 *src = ds.ptr(si, n * 3); + engine->setPalette(src, al, n); + si += n * 3; + cx = 0; +} + +void DreamGenContext::rollEndCredits2() { + rollEm(); +} + } // End of namespace DreamGen diff --git a/engines/dreamweb/vgagrafx.cpp b/engines/dreamweb/vgagrafx.cpp index 4c3ba57e6c..cea9dbef8c 100644 --- a/engines/dreamweb/vgagrafx.cpp +++ b/engines/dreamweb/vgagrafx.cpp @@ -43,7 +43,7 @@ void DreamBase::multiGet(uint8 *dst, uint16 x, uint16 y, uint8 w, uint8 h) { if (x + w > 320) w = 320 - x; //debug(1, "multiGet %u,%u %ux%u -> segment: %04x->%04x", x, y, w, h, (uint16)ds, (uint16)es); - for(unsigned l = 0; l < h; ++l) { + for (unsigned l = 0; l < h; ++l) { const uint8 *src_p = src + kScreenwidth * l; uint8 *dst_p = dst + w * l; memcpy(dst_p, src_p, w); @@ -66,7 +66,7 @@ void DreamBase::multiPut(const uint8 *src, uint16 x, uint16 y, uint8 w, uint8 h) if (x + w > 320) w = 320 - x; //debug(1, "multiPut %ux%u -> segment: %04x->%04x", w, h, (uint16)ds, (uint16)es); - for(unsigned l = 0; l < h; ++l) { + for (unsigned l = 0; l < h; ++l) { const uint8 *src_p = src + w * l; uint8 *dst_p = dst + kScreenwidth * l; memcpy(dst_p, src_p, w); @@ -178,32 +178,16 @@ void DreamBase::doShake() { engine->setShakePos(offset >= 0 ? offset : -offset); } -void DreamGenContext::vSync() { - push(ax); - push(bx); - push(cx); - push(dx); - push(si); - push(di); - push(es); - push(ds); +void DreamBase::vSync() { + engine->waitForVSync(); +} + +void DreamBase::setMode() { engine->waitForVSync(); - ds = pop(); - es = pop(); - di = pop(); - si = pop(); - dx = pop(); - cx = pop(); - bx = pop(); - ax = pop(); -} - -void DreamGenContext::setMode() { - vSync(); initGraphics(320, 200, false); } -void DreamGenContext::showPCX(const Common::String &name) { +void DreamBase::showPCX(const Common::String &name) { Common::File pcxFile; if (!pcxFile.open(name)) { @@ -218,7 +202,7 @@ void DreamGenContext::showPCX(const Common::String &name) { // the color components have to be adjusted from 8 to 6 bits. pcxFile.seek(16, SEEK_SET); - mainGamePal = getSegment(data.word(kBuffers)).ptr(kMaingamepal, 768); + mainGamePal = mainPalette(); pcxFile.read(mainGamePal, 48); memset(mainGamePal + 48, 0xff, 720); @@ -276,26 +260,26 @@ void DreamBase::frameOutV(uint8 *dst, const uint8 *src, uint16 pitch, uint16 wid // or was something broken during porting to C++? assert(pitch == 320); - if(x < 0) { + if (x < 0) { assert(width >= -x); width -= -x; src += -x; x = 0; } - if(y < 0) { + if (y < 0) { assert(height >= -y); height -= -y; src += (-y) * width; y = 0; } - if(x >= 320) + if (x >= 320) return; - if(y >= 200) + if (y >= 200) return; - if(x + width > 320) { + if (x + width > 320) { width = 320 - x; } - if(y + height > 200) { + if (y + height > 200) { height = 200 - y; } @@ -400,8 +384,8 @@ void DreamGenContext::zoom() { uint16 dstOffset = (kZoomy + 4) * 320 + (kZoomx + 5); const uint8 *src = workspace() + srcOffset; uint8 *dst = workspace() + dstOffset; - for(size_t i=0; i<20; ++i) { - for(size_t j=0; j<23; ++j) { + for (size_t i = 0; i < 20; ++i) { + for (size_t j = 0; j < 23; ++j) { uint8 v = src[j]; dst[2*j+0] = v; dst[2*j+1] = v; @@ -415,19 +399,23 @@ void DreamGenContext::zoom() { data.byte(kDidzoom) = 1; } -void DreamGenContext::panelToMap() { +uint8 *DreamBase::mapStore() { + return getSegment(data.word(kMapstore)).ptr(0, 0); +} + +void DreamBase::panelToMap() { multiGet(mapStore(), data.word(kMapxstart) + data.word(kMapadx), data.word(kMapystart) + data.word(kMapady), data.byte(kMapxsize), data.byte(kMapysize)); } -void DreamGenContext::mapToPanel() { +void DreamBase::mapToPanel() { multiPut(mapStore(), data.word(kMapxstart) + data.word(kMapadx), data.word(kMapystart) + data.word(kMapady), data.byte(kMapxsize), data.byte(kMapysize)); } -void DreamGenContext::dumpMap() { +void DreamBase::dumpMap() { multiDump(data.word(kMapxstart) + data.word(kMapadx), data.word(kMapystart) + data.word(kMapady), data.byte(kMapxsize), data.byte(kMapysize)); } -void DreamGenContext::transferInv() { +void DreamBase::transferInv() { const Frame *freeFrames = (const Frame *)getSegment(data.word(kFreeframes)).ptr(kFrframedata, 0); const Frame *freeFrame = freeFrames + (3 * data.byte(kItemtotran) + 1); Frame *exFrames = (Frame *)getSegment(data.word(kExtras)).ptr(kExframedata, 0); @@ -453,10 +441,11 @@ bool DreamGenContext::pixelCheckSet(const ObjPos *pos, uint8 x, uint8 y) { return *ptr != 0; } -void DreamGenContext::loadPalFromIFF() { - engine->openFile("DREAMWEB.PAL"); - engine->readFromFile(mapStore(), 2000); - engine->closeFile(); +void DreamBase::loadPalFromIFF() { + Common::File palFile; + palFile.open("DREAMWEB.PAL"); + palFile.read(mapStore(), 2000); + palFile.close(); const uint8 *src = mapStore() + 0x30; uint8 *dst = mainPalette(); diff --git a/engines/hugo/sound.h b/engines/hugo/sound.h index 1e504fbdea..cb6d4e3168 100644 --- a/engines/hugo/sound.h +++ b/engines/hugo/sound.h @@ -43,6 +43,12 @@ public: void pause(bool p); void play(uint8 *stream, uint16 size); + // The following line prevents compiler warnings about hiding the pause() + // method from the parent class. + // FIXME: Maybe the pause(bool p) method should be removed and the + // pause/resume methods of the parent class be used instead? + virtual void pause() { Audio::MidiPlayer::pause(); } + uint32 getBaseTempo(); // Overload Audio::MidiPlayer method diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 538e88aa90..120900537b 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -568,41 +568,27 @@ void LoLEngine::initKeymap() { Common::Action *act; Common::Keymap *engineKeyMap = new Common::Keymap(kKeymapName); - act = new Common::Action(engineKeyMap, "AT1", _("Attack 1"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_F1, Common::ASCII_F1 , 0)); - - act = new Common::Action(engineKeyMap, "AT2", _("Attack 2"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_F2, Common::ASCII_F2 , 0)); - - act = new Common::Action(engineKeyMap, "AT3", _("Attack 3"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_F3, Common::ASCII_F3 , 0)); - - act = new Common::Action(engineKeyMap, "MVF", _("Move Forward"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_UP)); - - act = new Common::Action(engineKeyMap, "MVB", _("Move Back"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_DOWN)); - - act = new Common::Action(engineKeyMap, "SLL", _("Slide Left"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_LEFT)); - - act = new Common::Action(engineKeyMap, "SLR", _("Slide Right"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_RIGHT)); - - act = new Common::Action(engineKeyMap, "TL", _("Turn Left"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_HOME)); - - act = new Common::Action(engineKeyMap, "TR", _("Turn Right"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_PAGEUP)); - - act = new Common::Action(engineKeyMap, "RST", _("Rest"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_r)); - - act = new Common::Action(engineKeyMap, "OPT", _("Options"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_o)); + const Common::KeyActionEntry keyActionEntries[] = { + {Common::KeyState(Common::KEYCODE_F1, Common::ASCII_F1, 0), "AT1", _("Attack 1")}, + {Common::KeyState(Common::KEYCODE_F2, Common::ASCII_F2, 0), "AT2", _("Attack 2")}, + {Common::KeyState(Common::KEYCODE_F3, Common::ASCII_F2, 0), "AT3", _("Attack 3")}, + {Common::KeyState(Common::KEYCODE_UP), "MVF", _("Move Forward")}, + {Common::KeyState(Common::KEYCODE_DOWN), "MVB", _("Move Back")}, + {Common::KeyState(Common::KEYCODE_LEFT), "SLL", _("Slide Left")}, + {Common::KeyState(Common::KEYCODE_RIGHT), "SLR", _("Slide Right")}, + {Common::KeyState(Common::KEYCODE_HOME), "TL", _("Turn Left")}, + {Common::KeyState(Common::KEYCODE_PAGEUP), "TR", _("Turn Right")}, + {Common::KeyState(Common::KEYCODE_r), "RST", _("Rest")}, + {Common::KeyState(Common::KEYCODE_o), "OPT", _("Options")}, + {Common::KeyState(Common::KEYCODE_SLASH), "SPL", _("Choose Spell")}, + {Common::KeyState(), 0, 0} + }; - act = new Common::Action(engineKeyMap, "SPL", _("Choose Spell"), Common::kGenericActionType, Common::kActionKeyType); - act->addKeyEvent(Common::KeyState(Common::KEYCODE_SLASH)); + const Common::KeyActionEntry *entry; + for (entry = keyActionEntries; entry->id; ++entry) { + act = new Common::Action(engineKeyMap, entry->id, Common::String(entry->description), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(entry->ks)); + } mapper->addGameKeymap(engineKeyMap); diff --git a/engines/kyra/resource_intern.cpp b/engines/kyra/resource_intern.cpp index 482bd1a5d6..f9aae2c550 100644 --- a/engines/kyra/resource_intern.cpp +++ b/engines/kyra/resource_intern.cpp @@ -37,11 +37,11 @@ PlainArchive::PlainArchive(Common::ArchiveMemberPtr file) : _file(file), _files() { } -bool PlainArchive::hasFile(const Common::String &name) { +bool PlainArchive::hasFile(const Common::String &name) const { return (_files.find(name) != _files.end()); } -int PlainArchive::listMembers(Common::ArchiveMemberList &list) { +int PlainArchive::listMembers(Common::ArchiveMemberList &list) const { int count = 0; for (FileMap::const_iterator i = _files.begin(); i != _files.end(); ++i) { @@ -52,7 +52,7 @@ int PlainArchive::listMembers(Common::ArchiveMemberList &list) { return count; } -Common::ArchiveMemberPtr PlainArchive::getMember(const Common::String &name) { +const Common::ArchiveMemberPtr PlainArchive::getMember(const Common::String &name) const { if (!hasFile(name)) return Common::ArchiveMemberPtr(); @@ -92,11 +92,11 @@ TlkArchive::~TlkArchive() { delete[] _fileEntries; } -bool TlkArchive::hasFile(const Common::String &name) { +bool TlkArchive::hasFile(const Common::String &name) const { return (findFile(name) != 0); } -int TlkArchive::listMembers(Common::ArchiveMemberList &list) { +int TlkArchive::listMembers(Common::ArchiveMemberList &list) const { uint count = 0; for (; count < _entryCount; ++count) { @@ -107,7 +107,7 @@ int TlkArchive::listMembers(Common::ArchiveMemberList &list) { return count; } -Common::ArchiveMemberPtr TlkArchive::getMember(const Common::String &name) { +const Common::ArchiveMemberPtr TlkArchive::getMember(const Common::String &name) const { if (!hasFile(name)) return Common::ArchiveMemberPtr(); @@ -186,11 +186,11 @@ CachedArchive::~CachedArchive() { _files.clear(); } -bool CachedArchive::hasFile(const Common::String &name) { +bool CachedArchive::hasFile(const Common::String &name) const { return (_files.find(name) != _files.end()); } -int CachedArchive::listMembers(Common::ArchiveMemberList &list) { +int CachedArchive::listMembers(Common::ArchiveMemberList &list) const { int count = 0; for (FileMap::const_iterator i = _files.begin(); i != _files.end(); ++i) { @@ -201,7 +201,7 @@ int CachedArchive::listMembers(Common::ArchiveMemberList &list) { return count; } -Common::ArchiveMemberPtr CachedArchive::getMember(const Common::String &name) { +const Common::ArchiveMemberPtr CachedArchive::getMember(const Common::String &name) const { if (!hasFile(name)) return Common::ArchiveMemberPtr(); diff --git a/engines/kyra/resource_intern.h b/engines/kyra/resource_intern.h index 03c9d871e8..9d9574d823 100644 --- a/engines/kyra/resource_intern.h +++ b/engines/kyra/resource_intern.h @@ -49,9 +49,9 @@ public: Entry getFileEntry(const Common::String &name) const; // Common::Archive API implementation - bool hasFile(const Common::String &name); - int listMembers(Common::ArchiveMemberList &list); - Common::ArchiveMemberPtr getMember(const Common::String &name); + bool hasFile(const Common::String &name) const; + int listMembers(Common::ArchiveMemberList &list) const; + const Common::ArchiveMemberPtr getMember(const Common::String &name) const; Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; private: typedef Common::HashMap<Common::String, Entry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap; @@ -65,9 +65,9 @@ public: TlkArchive(Common::ArchiveMemberPtr file, uint16 entryCount, const uint32 *fileEntries); ~TlkArchive(); - bool hasFile(const Common::String &name); - int listMembers(Common::ArchiveMemberList &list); - Common::ArchiveMemberPtr getMember(const Common::String &name); + bool hasFile(const Common::String &name) const; + int listMembers(Common::ArchiveMemberList &list) const; + const Common::ArchiveMemberPtr getMember(const Common::String &name) const; Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; private: Common::ArchiveMemberPtr _file; @@ -92,9 +92,9 @@ public: CachedArchive(const FileInputList &files); ~CachedArchive(); - bool hasFile(const Common::String &name); - int listMembers(Common::ArchiveMemberList &list); - Common::ArchiveMemberPtr getMember(const Common::String &name); + bool hasFile(const Common::String &name) const; + int listMembers(Common::ArchiveMemberList &list) const; + const Common::ArchiveMemberPtr getMember(const Common::String &name) const; Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; private: struct Entry { diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp index 531d864293..1bdcde5177 100644 --- a/engines/kyra/seqplayer.cpp +++ b/engines/kyra/seqplayer.cpp @@ -624,7 +624,7 @@ bool SeqPlayer::playSequence(const uint8 *seqData, bool skipSeq) { if (_vm->gameFlags().lang == Common::JA_JPN) charStr[1] = _vm->seqTextsTable()[_seqDisplayedText][++_seqDisplayedChar]; _screen->printText(charStr, _seqDisplayedTextX, 180, 0xF, 0xC); - _seqDisplayedTextX += _screen->getCharWidth(charStr[0]); + _seqDisplayedTextX += _screen->getCharWidth((uint8)charStr[0]); ++_seqDisplayedChar; if (_vm->seqTextsTable()[_seqDisplayedText][_seqDisplayedChar] == '\0') diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp index 50b5db78fc..b27f0df137 100644 --- a/engines/kyra/sequences_hof.cpp +++ b/engines/kyra/sequences_hof.cpp @@ -2622,7 +2622,7 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int while (*str2) { cChar[0] = *str2; _screen->printText(cChar, x, y, col1++, 0); - x += _screen->getCharWidth(*str2++); + x += _screen->getCharWidth((uint8)*str2++); } palCycle = true; } else if (!strcmp(str, specialData[1])) { @@ -2631,7 +2631,7 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int while (*str2) { cChar[0] = *str2; _screen->printText(cChar, x, y, col1--, 0); - x += _screen->getCharWidth(*str2++); + x += _screen->getCharWidth((uint8)*str2++); } palCycle = true; } else { diff --git a/engines/lastexpress/data/archive.cpp b/engines/lastexpress/data/archive.cpp index 3aa5584ca4..908d58254a 100644 --- a/engines/lastexpress/data/archive.cpp +++ b/engines/lastexpress/data/archive.cpp @@ -74,11 +74,11 @@ HPFArchive::HPFArchive(const Common::String &path) { delete archive; } -bool HPFArchive::hasFile(const Common::String &name) { +bool HPFArchive::hasFile(const Common::String &name) const { return (_files.find(name) != _files.end()); } -int HPFArchive::listMembers(Common::ArchiveMemberList &list) { +int HPFArchive::listMembers(Common::ArchiveMemberList &list) const { int numMembers = 0; for (FileMap::const_iterator i = _files.begin(); i != _files.end(); ++i) { @@ -89,7 +89,7 @@ int HPFArchive::listMembers(Common::ArchiveMemberList &list) { return numMembers; } -Common::ArchiveMemberPtr HPFArchive::getMember(const Common::String &name) { +const Common::ArchiveMemberPtr HPFArchive::getMember(const Common::String &name) const { if (!hasFile(name)) return Common::ArchiveMemberPtr(); diff --git a/engines/lastexpress/data/archive.h b/engines/lastexpress/data/archive.h index 8e0c46f183..011c830668 100644 --- a/engines/lastexpress/data/archive.h +++ b/engines/lastexpress/data/archive.h @@ -46,9 +46,9 @@ class HPFArchive : public Common::Archive { public: HPFArchive(const Common::String &path); - bool hasFile(const Common::String &name); - int listMembers(Common::ArchiveMemberList &list); - Common::ArchiveMemberPtr getMember(const Common::String &name); + bool hasFile(const Common::String &name) const; + int listMembers(Common::ArchiveMemberList &list) const; + const Common::ArchiveMemberPtr getMember(const Common::String &name) const; Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; int count() { return _files.size(); } diff --git a/engines/lastexpress/resource.cpp b/engines/lastexpress/resource.cpp index 3910aaa010..ee4885e34e 100644 --- a/engines/lastexpress/resource.cpp +++ b/engines/lastexpress/resource.cpp @@ -148,8 +148,8 @@ Common::SeekableReadStream *ResourceManager::getFileStream(const Common::String ////////////////////////////////////////////////////////////////////////// // Archive functions ////////////////////////////////////////////////////////////////////////// -bool ResourceManager::hasFile(const Common::String &name) { - for (Common::Array<HPFArchive *>::iterator it = _archives.begin(); it != _archives.end(); ++it) { +bool ResourceManager::hasFile(const Common::String &name) const { + for (Common::Array<HPFArchive *>::const_iterator it = _archives.begin(); it != _archives.end(); ++it) { if ((*it)->hasFile(name)) return true; } @@ -157,10 +157,10 @@ bool ResourceManager::hasFile(const Common::String &name) { return false; } -int ResourceManager::listMembers(Common::ArchiveMemberList &list) { +int ResourceManager::listMembers(Common::ArchiveMemberList &list) const { int count = 0; - for (Common::Array<HPFArchive *>::iterator it = _archives.begin(); it != _archives.end(); ++it) { + for (Common::Array<HPFArchive *>::const_iterator it = _archives.begin(); it != _archives.end(); ++it) { Common::ArchiveMemberList members; count += (*it)->listMembers(members); @@ -171,7 +171,7 @@ int ResourceManager::listMembers(Common::ArchiveMemberList &list) { return count; } -Common::ArchiveMemberPtr ResourceManager::getMember(const Common::String &name) { +const Common::ArchiveMemberPtr ResourceManager::getMember(const Common::String &name) const { if (!hasFile(name)) return Common::ArchiveMemberPtr(); diff --git a/engines/lastexpress/resource.h b/engines/lastexpress/resource.h index 9e05a90399..f2f5d63bce 100644 --- a/engines/lastexpress/resource.h +++ b/engines/lastexpress/resource.h @@ -45,9 +45,9 @@ public: Common::SeekableReadStream *getFileStream(const Common::String &name); // Archive functions - bool hasFile(const Common::String &name); - int listMembers(Common::ArchiveMemberList &list); - Common::ArchiveMemberPtr getMember(const Common::String &name); + bool hasFile(const Common::String &name) const; + int listMembers(Common::ArchiveMemberList &list) const; + const Common::ArchiveMemberPtr getMember(const Common::String &name) const; Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; // Resource loading diff --git a/engines/lure/decode.cpp b/engines/lure/decode.cpp index 59390e6e91..1338559534 100644 --- a/engines/lure/decode.cpp +++ b/engines/lure/decode.cpp @@ -34,12 +34,18 @@ namespace Lure { /* Provides the functionality for decoding screens */ /*--------------------------------------------------------------------------*/ +/** + * Write a single byte to the output buffer + */ void PictureDecoder::writeByte(MemoryBlock *dest, byte v) { if (outputOffset == dest->size()) error("Decoded data exceeded allocated output buffer size"); dest->data()[outputOffset++] = v; } +/** + * Writes out a specified byte a given number of times to the output + */ void PictureDecoder::writeBytes(MemoryBlock *dest, byte v, uint16 numBytes) { if (outputOffset + numBytes > dest->size()) error("Decoded data exceeded allocated output buffer size"); @@ -47,6 +53,9 @@ void PictureDecoder::writeBytes(MemoryBlock *dest, byte v, uint16 numBytes) { outputOffset += numBytes; } +/** + * Gets a byte from the compressed source using the first data pointer + */ byte PictureDecoder::DSSI(bool incr) { if (dataPos > dataIn->size()) error("PictureDecoder went beyond end of source data"); @@ -57,6 +66,9 @@ byte PictureDecoder::DSSI(bool incr) { return result; } +/** + * Gets a byte from the compressed source using the second data pointer + */ byte PictureDecoder::ESBX(bool incr) { if (dataPos2 >= dataIn->size()) error("PictureDecoder went beyond end of source data"); @@ -227,56 +239,61 @@ MemoryBlock *PictureDecoder::vgaDecode(MemoryBlock *src, uint32 maxOutputSize) { CH = ESBX(); CL = 9; -Loc754: - AL = DSSI(); - writeByte(dest, AL); - BP = ((uint16) AL) << 2; - -Loc755: - decrCtr(); - if (shlCarry()) goto Loc761; - decrCtr(); - if (shlCarry()) goto Loc759; - AL = dataIn->data()[BP]; - -Loc758: - writeByte(dest, AL); - BP = ((uint16) AL) << 2; - goto Loc755; - -Loc759: - AL = (byte) (BP >> 2); - AH = DSSI(); - if (AH == 0) goto Loc768; - - writeBytes(dest, AL, AH); - goto Loc755; - -Loc761: - decrCtr(); - if (shlCarry()) goto Loc765; - decrCtr(); - - if (shlCarry()) goto Loc764; - AL = dataIn->data()[BP+1]; - goto Loc758; - -Loc764: - AL = dataIn->data()[BP+2]; - goto Loc758; - -Loc765: - decrCtr(); - if (shlCarry()) goto Loc767; - AL = dataIn->data()[BP+3]; - goto Loc758; - -Loc767: - goto Loc754; - -Loc768: - AL = DSSI(); - if (AL != 0) goto Loc755; + // Main decoding loop + bool loopFlag = true; + while (loopFlag) { + AL = DSSI(); + writeByte(dest, AL); + BP = ((uint16) AL) << 2; + + // Inner loop + for (;;) { + decrCtr(); + if (shlCarry()) { + decrCtr(); + if (shlCarry()) { + decrCtr(); + if (shlCarry()) + break; + + AL = dataIn->data()[BP + 3]; + } else { + decrCtr(); + if (shlCarry()) + AL = dataIn->data()[BP + 2]; + else + AL = dataIn->data()[BP + 1]; + } + } else { + decrCtr(); + if (shlCarry()) { + AL = (byte) (BP >> 2); + AH = DSSI(); + if (AH == 0) { + AL = DSSI(); + if (AL == 0) { + // Finally done + loopFlag = false; + break; + } else { + // Keep going + continue; + } + } else { + // Write out byte sequence + writeBytes(dest, AL, AH); + continue; + } + } else { + AL = dataIn->data()[BP]; + } + } + + // Write out the next byte + writeByte(dest, AL); + BP = ((uint16) AL) << 2; + } + } // Resize the output to be the number of outputed bytes and return it if (outputOffset < dest->size()) dest->reallocate(outputOffset); @@ -355,106 +372,54 @@ uint32 AnimationDecoder::decode_data(MemoryBlock *src, MemoryBlock *dest, uint32 currData <<= 4; dx = 1; - for (;;) { - carry = false; - rcl(currData, carry); - if (--bitCtr == 0) { - GET_BYTE; - bitCtr = 8; - } - if (carry) goto loc_1441; - tableOffset = BX_VAL(0); - -loc_1439: - dx ^= 1; - if ((dx & 1) != 0) { - SET_HI_BYTE(dx, tableOffset << 4); - *pDest = dx >> 8; - } else { - *pDest++ |= tableOffset; - } - continue; - -loc_1441: - rcl(currData, carry); - if (--bitCtr == 0) { - GET_BYTE; - bitCtr = 8; - } - if (!carry) { + // Main loop + bool loopFlag = true; + while (loopFlag) { + for (;;) { + carry = false; rcl(currData, carry); if (--bitCtr == 0) { GET_BYTE; bitCtr = 8; } - if (!carry) { - tableOffset = BX_VAL(0x10); - } else { - tableOffset = BX_VAL(0x20); + tableOffset = BX_VAL(0); + break; } - goto loc_1439; - } - - rcl(currData, carry); - if (--bitCtr == 0) { - GET_BYTE; - bitCtr = 8; - } - if (!carry) { - tableOffset = BX_VAL(0x30); - goto loc_1439; - } - SET_HI_BYTE(dx, currData >> 12); - carry = false; - for (int ctr = 0; ctr < 4; ++ctr) { rcl(currData, carry); if (--bitCtr == 0) { GET_BYTE; bitCtr = 8; } - } - - byte dxHigh = dx >> 8; - if (dxHigh == BX_VAL(0)) { - tempReg1 = bitCtr; - tempReg2 = dx; - decode_data_2(src, pSrc, currData, bitCtr, dx, carry); - - SET_LO_BYTE(dx, dx >> 8); - decode_data_2(src, pSrc, currData, bitCtr, dx, carry); - SET_HI_BYTE(bitCtr, dx & 0xff); - SET_LO_BYTE(bitCtr, dx >> 8); - dx = tempReg2; - - if (bitCtr == 0) - // Exit out of infinite loop - break; - - } else if (dxHigh == BX_VAL(0x10)) { - tempReg1 = bitCtr; - decode_data_2(src, pSrc, currData, bitCtr, dx, carry); - bitCtr = dx >> 8; - - } else if (dxHigh == BX_VAL(0x20)) { - SET_HI_BYTE(dx, currData >> 10); - - for (v = 0; v < 6; ++v) { + if (!carry) { rcl(currData, carry); if (--bitCtr == 0) { GET_BYTE; bitCtr = 8; } - } - tempReg1 = bitCtr; - bitCtr = dx >> 8; + if (!carry) { + tableOffset = BX_VAL(0x10); + } else { + tableOffset = BX_VAL(0x20); + } + break; + } - } else if (dxHigh == BX_VAL(0x30)) { - SET_HI_BYTE(dx, currData >> 11); + rcl(currData, carry); + if (--bitCtr == 0) { + GET_BYTE; + bitCtr = 8; + } + if (!carry) { + tableOffset = BX_VAL(0x30); + break; + } - for (v = 0; v < 5; ++v) { + SET_HI_BYTE(dx, currData >> 12); + carry = false; + for (int ctr = 0; ctr < 4; ++ctr) { rcl(currData, carry); if (--bitCtr == 0) { GET_BYTE; @@ -462,34 +427,92 @@ loc_1441: } } - tempReg1 = bitCtr; - bitCtr = dx >> 8; + byte dxHigh = dx >> 8; + if (dxHigh == BX_VAL(0)) { + tempReg1 = bitCtr; + tempReg2 = dx; + decode_data_2(src, pSrc, currData, bitCtr, dx, carry); + + SET_LO_BYTE(dx, dx >> 8); + decode_data_2(src, pSrc, currData, bitCtr, dx, carry); + SET_HI_BYTE(bitCtr, dx & 0xff); + SET_LO_BYTE(bitCtr, dx >> 8); + dx = tempReg2; + + if (bitCtr == 0) { + // End of decompression + loopFlag = false; + break; + } + } else if (dxHigh == BX_VAL(0x10)) { + tempReg1 = bitCtr; + decode_data_2(src, pSrc, currData, bitCtr, dx, carry); + bitCtr = dx >> 8; + + } else if (dxHigh == BX_VAL(0x20)) { + SET_HI_BYTE(dx, currData >> 10); + + for (v = 0; v < 6; ++v) { + rcl(currData, carry); + if (--bitCtr == 0) { + GET_BYTE; + bitCtr = 8; + } + } + + tempReg1 = bitCtr; + bitCtr = dx >> 8; - } else { - tableOffset = dx >> 8; - goto loc_1439; - } + } else if (dxHigh == BX_VAL(0x30)) { + SET_HI_BYTE(dx, currData >> 11); - if ((dx & 1) == 1) { - *pDest++ |= tableOffset; - --bitCtr; - dx &= 0xfffe; - } + for (v = 0; v < 5; ++v) { + rcl(currData, carry); + if (--bitCtr == 0) { + GET_BYTE; + bitCtr = 8; + } + } - SET_HI_BYTE(dx, tableOffset << 4); - tableOffset |= dx >> 8; + tempReg1 = bitCtr; + bitCtr = dx >> 8; - v = bitCtr >> 1; - while (v-- > 0) *pDest++ = tableOffset; + } else { + tableOffset = dx >> 8; + break; + } - bitCtr &= 1; - if (bitCtr != 0) { - *pDest = tableOffset & 0xf0; - dx |= 1; //dx.l + if ((dx & 1) == 1) { + *pDest++ |= tableOffset; + --bitCtr; + dx &= 0xfffe; + } + + SET_HI_BYTE(dx, tableOffset << 4); + tableOffset |= dx >> 8; + + v = bitCtr >> 1; + while (v-- > 0) *pDest++ = tableOffset; + + bitCtr &= 1; + if (bitCtr != 0) { + *pDest = tableOffset & 0xf0; + dx |= 1; //dx.l + } + + bitCtr = tempReg1; + tableOffset &= 0x0f; } - bitCtr = tempReg1; - tableOffset &= 0x0f; + if (loopFlag) { + dx ^= 1; + if ((dx & 1) != 0) { + SET_HI_BYTE(dx, tableOffset << 4); + *pDest = dx >> 8; + } else { + *pDest++ |= tableOffset; + } + } } // Return number of bytes written diff --git a/engines/mohawk/graphics.cpp b/engines/mohawk/graphics.cpp index c4326d175f..dcb0c7940d 100644 --- a/engines/mohawk/graphics.cpp +++ b/engines/mohawk/graphics.cpp @@ -308,16 +308,19 @@ MystGraphics::~MystGraphics() { delete _backBuffer; } -static const char* picFileNames[] = { +static const char *s_picFileNames[] = { "CHpics", "", + "", "DUpics", "INpics", + "", "MEpics", "MYpics", "SEpics", - "STpics", - "" + "", + "", + "STpics" }; void MystGraphics::loadExternalPictureFile(uint16 stack) { @@ -328,11 +331,11 @@ void MystGraphics::loadExternalPictureFile(uint16 stack) { _pictureFile.picFile.close(); delete[] _pictureFile.entries; - if (!scumm_stricmp(picFileNames[stack], "")) + if (!scumm_stricmp(s_picFileNames[stack], "")) return; - if (!_pictureFile.picFile.open(picFileNames[stack])) - error ("Could not open external picture file \'%s\'", picFileNames[stack]); + if (!_pictureFile.picFile.open(s_picFileNames[stack])) + error ("Could not open external picture file \'%s\'", s_picFileNames[stack]); _pictureFile.pictureCount = _pictureFile.picFile.readUint32BE(); _pictureFile.entries = new PictureFile::PictureEntry[_pictureFile.pictureCount]; diff --git a/engines/mohawk/installer_archive.cpp b/engines/mohawk/installer_archive.cpp index 83796158a6..636b7ae476 100644 --- a/engines/mohawk/installer_archive.cpp +++ b/engines/mohawk/installer_archive.cpp @@ -107,18 +107,18 @@ void InstallerArchive::close() { _map.clear(); } -bool InstallerArchive::hasFile(const Common::String &name) { +bool InstallerArchive::hasFile(const Common::String &name) const { return _map.contains(name); } -int InstallerArchive::listMembers(Common::ArchiveMemberList &list) { +int InstallerArchive::listMembers(Common::ArchiveMemberList &list) const { for (FileMap::const_iterator it = _map.begin(); it != _map.end(); it++) list.push_back(getMember(it->_key)); return _map.size(); } -Common::ArchiveMemberPtr InstallerArchive::getMember(const Common::String &name) { +const Common::ArchiveMemberPtr InstallerArchive::getMember(const Common::String &name) const { return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this)); } diff --git a/engines/mohawk/installer_archive.h b/engines/mohawk/installer_archive.h index 27877d69f9..89d2d85f8d 100644 --- a/engines/mohawk/installer_archive.h +++ b/engines/mohawk/installer_archive.h @@ -43,9 +43,9 @@ public: bool isOpen() const { return _stream != 0; } // Common::Archive API implementation - bool hasFile(const Common::String &name); - int listMembers(Common::ArchiveMemberList &list); - Common::ArchiveMemberPtr getMember(const Common::String &name); + bool hasFile(const Common::String &name) const; + int listMembers(Common::ArchiveMemberList &list) const; + const Common::ArchiveMemberPtr getMember(const Common::String &name) const; Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; private: diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp index f0d918129e..08f3b86c7c 100644 --- a/engines/mohawk/livingbooks.cpp +++ b/engines/mohawk/livingbooks.cpp @@ -104,7 +104,12 @@ void LBPage::open(Archive *mhk, uint16 baseId) { _items[i]->init(); for (uint32 i = 0; i < _items.size(); i++) - _items[i]->startPhase(0xFFFE); + _items[i]->startPhase(kLBPhaseLoad); +} + +void LBPage::addClonedItem(LBItem *item) { + _vm->addItem(item); + _items.push_back(item); } void LBPage::itemDestroyed(LBItem *item) { @@ -444,9 +449,9 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) { void MohawkEngine_LivingBooks::updatePage() { switch (_phase) { - case 0: + case kLBPhaseInit: for (uint32 i = 0; i < _items.size(); i++) - _items[i]->startPhase(0xFFFF); + _items[i]->startPhase(kLBPhaseCreate); for (uint32 i = 0; i < _items.size(); i++) _items[i]->startPhase(_phase); @@ -542,7 +547,7 @@ void MohawkEngine_LivingBooks::updatePage() { _phase++; break; - case 1: + case kLBPhaseIntro: for (uint32 i = 0; i < _items.size(); i++) _items[i]->startPhase(_phase); @@ -555,7 +560,7 @@ void MohawkEngine_LivingBooks::updatePage() { _phase++; break; - case 2: + case kLBPhaseMain: if (!_introDone) break; @@ -1954,7 +1959,10 @@ LBScriptEntry::~LBScriptEntry() { } LBItem::LBItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : _vm(vm), _page(page), _rect(rect) { - _phase = 0; + if (_vm->getGameType() == GType_LIVINGBOOKSV1 || _vm->getGameType() == GType_LIVINGBOOKSV2) + _phase = kLBPhaseInit; + else + _phase = kLBPhaseLoad; _loopMode = 0; _delayMin = 0; @@ -2446,7 +2454,7 @@ bool LBItem::contains(Common::Point point) { } void LBItem::update() { - if (_phase != 0x7FFF && (!_loaded || !_enabled || !_globalEnabled)) + if (_phase != kLBPhaseNone && (!_loaded || !_enabled || !_globalEnabled)) return; if (_nextTime == 0 || _nextTime > (uint32)(_vm->_system->getMillis() / 16)) @@ -2484,7 +2492,7 @@ bool LBItem::togglePlaying(bool playing, bool restart) { _vm->queueDelayedEvent(DelayedEvent(this, kLBDelayedEventDone)); return true; } - if (((_loaded && _enabled && _globalEnabled) || _phase == 0x7FFF) && !_playing) { + if (((_loaded && _enabled && _globalEnabled) || _phase == kLBPhaseNone) && !_playing) { _playing = togglePlaying(true, restart); if (_playing) { _nextTime = 0; @@ -2574,7 +2582,7 @@ void LBItem::setGlobalVisible(bool visible) { void LBItem::startPhase(uint phase) { if (_phase == phase) { - if (_phase != 0x7fff) { + if (_phase != kLBPhaseNone) { setEnabled(true); } @@ -2582,31 +2590,31 @@ void LBItem::startPhase(uint phase) { } switch (phase) { - case 0xFFFE: + case kLBPhaseLoad: runScript(kLBEventListLoad); break; - case 0xFFFF: + case kLBPhaseCreate: runScript(kLBEventPhaseCreate); if (_timingMode == kLBAutoCreate) { debug(2, "Phase create: time startup"); setNextTime(_periodMin, _periodMax); } break; - case 0: + case kLBPhaseInit: runScript(kLBEventPhaseInit); if (_timingMode == kLBAutoInit) { debug(2, "Phase init: time startup"); setNextTime(_periodMin, _periodMax); } break; - case 1: + case kLBPhaseIntro: runScript(kLBEventPhaseIntro); if (_timingMode == kLBAutoIntro || _timingMode == kLBAutoUserIdle) { debug(2, "Phase intro: time startup"); setNextTime(_periodMin, _periodMax); } break; - case 2: + case kLBPhaseMain: runScript(kLBEventPhaseMain); if (_timingMode == kLBAutoUserIdle || _timingMode == kLBAutoMain) { debug(2, "Phase main: time startup"); @@ -2667,6 +2675,24 @@ void LBItem::moveTo(const Common::Point &pos) { _rect.moveTo(pos); } +LBItem *LBItem::clone(uint16 newId, const Common::String &newName) { + LBItem *item = createClone(); + + item->_itemId = newId; + item->_desc = newName; + + item->_resourceId = _resourceId; + // FIXME: the rest + + _page->addClonedItem(item); + // FIXME: zorder? + return item; +} + +LBItem *LBItem::createClone() { + return new LBItem(_vm, _page, _rect); +} + void LBItem::runScript(uint event, uint16 data, uint16 from) { for (uint i = 0; i < _scriptEntries.size(); i++) { LBScriptEntry *entry = _scriptEntries[i]; @@ -3072,6 +3098,10 @@ void LBSoundItem::stop() { LBItem::stop(); } +LBItem *LBSoundItem::createClone() { + return new LBSoundItem(_vm, _page, _rect); +} + LBGroupItem::LBGroupItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBGroupItem"); _starting = false; @@ -3219,6 +3249,12 @@ void LBGroupItem::moveTo(const Common::Point &pos) { } } +LBItem *LBGroupItem::createClone() { + // TODO: needed? + error("LBGroupItem::createClone unimplemented"); + return new LBGroupItem(_vm, _page, _rect); +} + LBPaletteItem::LBPaletteItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBPaletteItem"); @@ -3304,6 +3340,10 @@ void LBPaletteItem::update() { LBItem::update(); } +LBItem *LBPaletteItem::createClone() { + error("can't clone LBPaletteItem"); +} + LBLiveTextItem::LBLiveTextItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { _currentPhrase = 0xFFFF; _currentWord = 0xFFFF; @@ -3551,6 +3591,10 @@ void LBLiveTextItem::notify(uint16 data, uint16 from) { LBItem::notify(data, from); } +LBItem *LBLiveTextItem::createClone() { + error("can't clone LBLiveTextItem"); +} + LBPictureItem::LBPictureItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBPictureItem"); } @@ -3596,6 +3640,10 @@ void LBPictureItem::draw() { _vm->_gfx->copyAnimImageToScreen(_resourceId, _rect.left, _rect.top); } +LBItem *LBPictureItem::createClone() { + return new LBPictureItem(_vm, _page, _rect); +} + LBAnimationItem::LBAnimationItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { _anim = NULL; _running = false; @@ -3701,6 +3749,12 @@ void LBAnimationItem::draw() { _anim->draw(); } +LBItem *LBAnimationItem::createClone() { + LBAnimationItem *item = new LBAnimationItem(_vm, _page, _rect); + item->_anim = new LBAnimation(_vm, item, _resourceId); + return item; +} + LBMovieItem::LBMovieItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBMovieItem"); } @@ -3720,7 +3774,7 @@ void LBMovieItem::update() { bool LBMovieItem::togglePlaying(bool playing, bool restart) { if (playing) { - if ((_loaded && _enabled && _globalEnabled) || _phase == 0x7FFF) { + if ((_loaded && _enabled && _globalEnabled) || _phase == kLBPhaseNone) { _vm->_video->playMovie(_resourceId, _rect.left, _rect.top); return true; @@ -3730,6 +3784,10 @@ bool LBMovieItem::togglePlaying(bool playing, bool restart) { return LBItem::togglePlaying(playing, restart); } +LBItem *LBMovieItem::createClone() { + return new LBMovieItem(_vm, _page, _rect); +} + LBMiniGameItem::LBMiniGameItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBMiniGameItem"); } @@ -3765,6 +3823,10 @@ bool LBMiniGameItem::togglePlaying(bool playing, bool restart) { return false; } +LBItem *LBMiniGameItem::createClone() { + error("can't clone LBMiniGameItem"); +} + LBProxyItem::LBProxyItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBProxyItem"); @@ -3808,4 +3870,8 @@ void LBProxyItem::unload() { LBItem::unload(); } +LBItem *LBProxyItem::createClone() { + return new LBProxyItem(_vm, _page, _rect); +} + } // End of namespace Mohawk diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h index 28dd49e78a..23ab0acfb1 100644 --- a/engines/mohawk/livingbooks.h +++ b/engines/mohawk/livingbooks.h @@ -68,6 +68,15 @@ enum LBMode { kLBPlayMode = 6 }; +enum { + kLBPhaseInit = 0x0, + kLBPhaseIntro = 0x1, + kLBPhaseMain = 0x2, + kLBPhaseNone = 0x7fff, + kLBPhaseLoad = 0xfffe, + kLBPhaseCreate = 0xffff +}; + // automatic modes used in _timingMode enum { kLBAutoNone = 0, @@ -406,6 +415,8 @@ public: virtual void moveBy(const Common::Point &pos); virtual void moveTo(const Common::Point &pos); + LBItem *clone(uint16 newId, const Common::String &newName); + uint16 getId() { return _itemId; } const Common::String &getName() { return _desc; } const Common::Rect &getRect() { return _rect; } @@ -415,6 +426,9 @@ public: Common::List<LBItem *>::iterator _iterator; + // TODO: make private + Common::HashMap<Common::String, LBValue, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _variables; + protected: MohawkEngine_LivingBooks *_vm; LBPage *_page; @@ -440,6 +454,8 @@ protected: bool _isAmbient; bool _doHitTest; + virtual LBItem *createClone(); + Common::Array<LBScriptEntry *> _scriptEntries; void runScript(uint event, uint16 data = 0, uint16 from = 0); int runScriptEntry(LBScriptEntry *entry); @@ -460,6 +476,8 @@ public: void stop(); protected: + LBItem *createClone(); + bool _running; }; @@ -491,6 +509,8 @@ public: void moveTo(const Common::Point &pos); protected: + LBItem *createClone(); + bool _starting; Common::Array<GroupEntry> _groupEntries; @@ -507,6 +527,8 @@ public: void update(); protected: + LBItem *createClone(); + uint16 _fadeInPeriod, _fadeInStep, _drawStart, _drawCount; uint32 _fadeInStart, _fadeInCurrent; byte *_palette; @@ -538,6 +560,8 @@ public: void notify(uint16 data, uint16 from); protected: + LBItem *createClone(); + void paletteUpdate(uint16 word, bool on); void drawWord(uint word, uint yPos); @@ -561,6 +585,9 @@ public: bool contains(Common::Point point); void draw(); void init(); + +protected: + LBItem *createClone(); }; class LBAnimationItem : public LBItem { @@ -581,6 +608,8 @@ public: void stop(); protected: + LBItem *createClone(); + LBAnimation *_anim; bool _running; }; @@ -592,6 +621,9 @@ public: void update(); bool togglePlaying(bool playing, bool restart); + +protected: + LBItem *createClone(); }; class LBMiniGameItem : public LBItem { @@ -600,6 +632,9 @@ public: ~LBMiniGameItem(); bool togglePlaying(bool playing, bool restart); + +protected: + LBItem *createClone(); }; class LBProxyItem : public LBItem { @@ -611,6 +646,8 @@ public: void unload(); protected: + LBItem *createClone(); + class LBPage *_page; }; @@ -647,6 +684,7 @@ public: void open(Archive *mhk, uint16 baseId); uint16 getResourceVersion(); + void addClonedItem(LBItem *item); void itemDestroyed(LBItem *item); LBCode *_code; @@ -710,7 +748,7 @@ public: void nextPage(); // TODO: make private - Common::HashMap<Common::String, LBValue> _variables; + Common::HashMap<Common::String, LBValue, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _variables; // helper functions, also used by LBProxyItem Common::String getFileNameFromConfig(const Common::String §ion, const Common::String &key, Common::String &leftover); diff --git a/engines/mohawk/livingbooks_code.cpp b/engines/mohawk/livingbooks_code.cpp index 8e7c69b070..41acea19c4 100644 --- a/engines/mohawk/livingbooks_code.cpp +++ b/engines/mohawk/livingbooks_code.cpp @@ -847,8 +847,8 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = { { "deleteAt", &LBCode::cmdDeleteAt }, { "clearList", &LBCode::cmdUnimplemented }, { "setWorld", 0 }, - { "setProperty", 0 }, - { "getProperty", 0 }, + { "setProperty", &LBCode::cmdSetProperty }, + { "getProperty", &LBCode::cmdGetProperty }, { "copyList", 0 }, { "invoke", 0 }, { "exec", &LBCode::cmdExec }, @@ -1189,6 +1189,45 @@ void LBCode::cmdDeleteAt(const Common::Array<LBValue> ¶ms) { params[0].list->array.remove_at(params[1].integer - 1); } +void LBCode::cmdSetProperty(const Common::Array<LBValue> ¶ms) { + if (params.size() < 2 || params.size() > 3) + error("incorrect number of parameters (%d) to setProperty", params.size()); + + Common::String name; + LBValue val; + LBItem *target = _currSource; + if (params.size() == 3) { + target = resolveItem(params[0]); + if (!target) + error("attempted setProperty on invalid item (%s)", params[0].toString().c_str()); + name = params[1].toString(); + val = params[2]; + } else { + name = params[0].toString(); + val = params[1]; + } + + target->_variables[name] = val; +} + +void LBCode::cmdGetProperty(const Common::Array<LBValue> ¶ms) { + if (params.size() < 1 || params.size() > 2) + error("incorrect number of parameters (%d) to getProperty", params.size()); + + Common::String name; + LBItem *target = _currSource; + if (params.size() == 2) { + target = resolveItem(params[0]); + if (!target) + error("attempted getProperty on invalid item (%s)", params[0].toString().c_str()); + name = params[1].toString(); + } else { + name = params[0].toString(); + } + + _stack.push(target->_variables[name]); +} + void LBCode::cmdExec(const Common::Array<LBValue> ¶ms) { if (params.size() != 1) error("incorrect number of parameters (%d) to exec", params.size()); @@ -1297,7 +1336,7 @@ void LBCode::cmdKey(const Common::Array<LBValue> ¶ms) { #define NUM_ITEM_COMMANDS 34 CodeCommandInfo itemCommandInfo[NUM_ITEM_COMMANDS] = { - { "clone", 0 }, + { "clone", &LBCode::itemClone }, { "destroy", 0 }, { "dragBeginFrom", 0 }, { "dragEnd", 0 }, @@ -1350,6 +1389,17 @@ void LBCode::runItemCommand() { (this->*(info.func))(params); } +void LBCode::itemClone(const Common::Array<LBValue> ¶ms) { + // TODO: first param can be target? + if (params.size() != 2) + error("incorrect number of parameters (%d) to setParent", params.size()); + + uint id = params[0].toInt(); + const Common::String &name = params[1].toString(); + + _currSource->clone(id, name); +} + void LBCode::itemIsPlaying(const Common::Array<LBValue> ¶ms) { // TODO warning("ignoring isPlaying"); @@ -1423,7 +1473,7 @@ void LBCode::runNotifyCommand() { debugN("goto"); Common::Array<LBValue> params = readParams(); // TODO: type-checking - NotifyEvent notifyEvent(kLBNotifyChangePage, 0); + NotifyEvent notifyEvent(kLBNotifyChangePage, 1); switch (params.size()) { case 4: notifyEvent.type = kLBNotifyChangeMode; // FIXME: type 8? diff --git a/engines/mohawk/livingbooks_code.h b/engines/mohawk/livingbooks_code.h index 2cb1994492..47dd90f814 100644 --- a/engines/mohawk/livingbooks_code.h +++ b/engines/mohawk/livingbooks_code.h @@ -270,6 +270,8 @@ public: void cmdSetAt(const Common::Array<LBValue> ¶ms); void cmdListLen(const Common::Array<LBValue> ¶ms); void cmdDeleteAt(const Common::Array<LBValue> ¶ms); + void cmdSetProperty(const Common::Array<LBValue> ¶ms); + void cmdGetProperty(const Common::Array<LBValue> ¶ms); void cmdExec(const Common::Array<LBValue> ¶ms); void cmdReturn(const Common::Array<LBValue> ¶ms); void cmdSetPlayParams(const Common::Array<LBValue> ¶ms); @@ -279,6 +281,7 @@ public: void cmdLBXFunc(const Common::Array<LBValue> ¶ms); void cmdKey(const Common::Array<LBValue> ¶ms); + void itemClone(const Common::Array<LBValue> ¶ms); void itemIsPlaying(const Common::Array<LBValue> ¶ms); void itemIsLoaded(const Common::Array<LBValue> ¶ms); void itemMoveTo(const Common::Array<LBValue> ¶ms); diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp index b6c0a3212f..b3222e0322 100644 --- a/engines/mohawk/myst_stacks/myst.cpp +++ b/engines/mohawk/myst_stacks/myst.cpp @@ -2978,15 +2978,17 @@ void Myst::clockReset() { } void Myst::clockResetWeight() { - // Set video bounds, weight going up + _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack) , 124, 0); + if (!(_vm->getFeatures() & GF_ME)) { - _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack) , 124, 0); + // Set video bounds, weight going up _vm->_video->setVideoBounds(_clockWeightVideo, Audio::Timestamp(0, 2214 * 2 - _clockWeightPosition, 600), Audio::Timestamp(0, 2214 * 2, 600)); } else { - //FIXME: Needs QT backwards playing + //FIXME: Needs QT backwards playing, for now just display the weight up warning("Weight going back up not implemented"); + _vm->_video->drawVideoFrame(_clockWeightVideo, Audio::Timestamp(0, 0, 600)); } // Reset position diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp index 4c715b56e4..6d54d0c586 100644 --- a/engines/mohawk/myst_stacks/stoneship.cpp +++ b/engines/mohawk/myst_stacks/stoneship.cpp @@ -623,7 +623,7 @@ void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, uint16 argc, uint uint16 selectionPos = position * 1500 / 243; VideoHandle handleMovie = _hologramSelection->playMovie(); - _vm->_video->setVideoBounds(handleMovie, Audio::Timestamp(0, selectionPos, 600), Audio::Timestamp(0, selectionPos, 600)); + _vm->_video->drawVideoFrame(handleMovie, Audio::Timestamp(0, selectionPos, 600)); _hologramDisplayPos = position * 1450 / 243 + 350; @@ -631,7 +631,7 @@ void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, uint16 argc, uint if (_hologramTurnedOn) { _hologramDisplay->setBlocking(false); VideoHandle displayMovie = _hologramDisplay->playMovie(); - _vm->_video->setVideoBounds(displayMovie, Audio::Timestamp(0, _hologramDisplayPos, 600), Audio::Timestamp(0, _hologramDisplayPos, 600)); + _vm->_video->drawVideoFrame(displayMovie, Audio::Timestamp(0, _hologramDisplayPos, 600)); } } } diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp index cd8fc8ef80..7958906897 100644 --- a/engines/mohawk/video.cpp +++ b/engines/mohawk/video.cpp @@ -529,6 +529,15 @@ void VideoManager::setVideoBounds(VideoHandle handle, Audio::Timestamp start, Au _videoStreams[handle]->seekToTime(start); } +void VideoManager::drawVideoFrame(VideoHandle handle, Audio::Timestamp time) { + assert(handle != NULL_VID_HANDLE); + _videoStreams[handle].end = Audio::Timestamp(0xffffffff, 1); + _videoStreams[handle]->seekToTime(time); + updateMovies(); + delete _videoStreams[handle].video; + _videoStreams[handle].clear(); +} + void VideoManager::seekToTime(VideoHandle handle, Audio::Timestamp time) { assert(handle != NULL_VID_HANDLE); _videoStreams[handle]->seekToTime(time); diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h index efa81edfbd..34c287497f 100644 --- a/engines/mohawk/video.h +++ b/engines/mohawk/video.h @@ -104,6 +104,7 @@ public: uint32 getDuration(VideoHandle videoHandle); bool endOfVideo(VideoHandle handle); void setVideoBounds(VideoHandle handle, Audio::Timestamp start, Audio::Timestamp end); + void drawVideoFrame(VideoHandle handle, Audio::Timestamp time); void seekToTime(VideoHandle handle, Audio::Timestamp time); void setVideoLooping(VideoHandle handle, bool loop); void waitUntilMovieEnds(VideoHandle videoHandle); diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp index 05ea60f510..e145743f09 100644 --- a/engines/parallaction/disk_ns.cpp +++ b/engines/parallaction/disk_ns.cpp @@ -73,9 +73,9 @@ public: ~NSArchive(); Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; - bool hasFile(const Common::String &name); - int listMembers(Common::ArchiveMemberList &list); - Common::ArchiveMemberPtr getMember(const Common::String &name); + bool hasFile(const Common::String &name) const; + int listMembers(Common::ArchiveMemberList &list) const; + const Common::ArchiveMemberPtr getMember(const Common::String &name) const; }; @@ -137,23 +137,23 @@ Common::SeekableReadStream *NSArchive::createReadStreamForMember(const Common::S return new Common::SeekableSubReadStream(_stream, offset, endOffset, DisposeAfterUse::NO); } -bool NSArchive::hasFile(const Common::String &name) { +bool NSArchive::hasFile(const Common::String &name) const { if (name.empty()) return false; return lookup(name.c_str()) != _numFiles; } -int NSArchive::listMembers(Common::ArchiveMemberList &list) { +int NSArchive::listMembers(Common::ArchiveMemberList &list) const { for (uint32 i = 0; i < _numFiles; i++) { list.push_back(Common::SharedPtr<Common::GenericArchiveMember>(new Common::GenericArchiveMember(_archiveDir[i], this))); } return _numFiles; } -Common::ArchiveMemberPtr NSArchive::getMember(const Common::String &name) { +const Common::ArchiveMemberPtr NSArchive::getMember(const Common::String &name) const { uint32 index = lookup(name.c_str()); - char *item = 0; + const char *item = 0; if (index < _numFiles) { item = _archiveDir[index]; } diff --git a/engines/sci/sound/drivers/amigamac.cpp b/engines/sci/sound/drivers/amigamac.cpp index 3c750401b9..41697d4a07 100644 --- a/engines/sci/sound/drivers/amigamac.cpp +++ b/engines/sci/sound/drivers/amigamac.cpp @@ -130,7 +130,7 @@ private: }; bool _isSci1; - bool _isSci1Early; // KQ1 Amiga, patch 5 + bool _isSci1Early; // KQ1/MUMG Amiga, patch 5 bool _playSwitch; int _masterVolume; int _frequency; @@ -586,12 +586,12 @@ int MidiDriver_AmigaMac::open() { } else { ResourceManager *resMan = g_sci->getResMan(); - Resource *resource = resMan->findResource(ResourceId(kResourceTypePatch, 7), false); // Mac + Resource *resource = resMan->findResource(ResourceId(kResourceTypePatch, 7), false); // Mac if (!resource) - resource = resMan->findResource(ResourceId(kResourceTypePatch, 9), false); // Amiga + resource = resMan->findResource(ResourceId(kResourceTypePatch, 9), false); // Amiga if (!resource) { - resource = resMan->findResource(ResourceId(kResourceTypePatch, 5), false); // KQ1 Amiga + resource = resMan->findResource(ResourceId(kResourceTypePatch, 5), false); // KQ1/MUMG Amiga if (resource) _isSci1Early = true; } @@ -892,7 +892,7 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file) _bank.size = 128; if (_isSci1Early) - file.skip(4); // TODO: What is this offset for? + file.readUint32BE(); // Skip size of bank Common::Array<uint32> instrumentOffsets; instrumentOffsets.resize(_bank.size); @@ -911,12 +911,6 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file) // Read in the instrument name file.read(_bank.instruments[i].name, 10); // last two bytes are always 0 - // TODO: Finish off support of SCI1 early patches (patch.005 - KQ1 Amiga) - if (_isSci1Early) { - warning("Music patch 5 isn't supported yet - ignoring instrument %d", i); - continue; - } - for (uint32 j = 0; ; j++) { InstrumentSample *sample = new InstrumentSample; memset(sample, 0, sizeof(InstrumentSample)); @@ -943,16 +937,30 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file) int16 loop = file.readSint16BE(); uint32 nextSamplePos = file.pos(); - file.seek(samplePtr); + file.seek(samplePtr + (_isSci1Early ? 4 : 0)); file.read(sample->name, 8); - sample->isUnsigned = file.readUint16BE() == 0; - uint16 phase1Offset = file.readUint16BE(); - uint16 phase1End = file.readUint16BE(); - uint16 phase2Offset = file.readUint16BE(); - uint16 phase2End = file.readUint16BE(); - sample->baseNote = file.readUint16BE(); - uint32 periodTableOffset = file.readUint32BE(); + uint16 phase1Offset, phase1End; + uint16 phase2Offset, phase2End; + + if (_isSci1Early) { + sample->isUnsigned = false; + file.readUint32BE(); // skip total sample size + phase2Offset = file.readUint16BE(); + phase2End = file.readUint16BE(); + sample->baseNote = file.readUint16BE(); + phase1Offset = file.readUint16BE(); + phase1End = file.readUint16BE(); + } else { + sample->isUnsigned = file.readUint16BE() == 0; + phase1Offset = file.readUint16BE(); + phase1End = file.readUint16BE(); + phase2Offset = file.readUint16BE(); + phase2End = file.readUint16BE(); + sample->baseNote = file.readUint16BE(); + } + + uint32 periodTableOffset = _isSci1Early ? 0 : file.readUint32BE(); uint32 sampleDataPos = file.pos(); sample->size = phase1End - phase1Offset + 1; @@ -974,8 +982,13 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file) _bank.instruments[i].push_back(sample); - file.seek(periodTableOffset + 0xe0); - sample->baseFreq = file.readUint16BE(); + if (_isSci1Early) { + // There's no frequency specified by the sample and is hardcoded like in SCI0 + sample->baseFreq = 11000; + } else { + file.seek(periodTableOffset + 0xe0); + sample->baseFreq = file.readUint16BE(); + } file.seek(nextSamplePos); } diff --git a/engines/tsage/blue_force/blueforce_dialogs.cpp b/engines/tsage/blue_force/blueforce_dialogs.cpp index b9b3ad6c22..11c0358aca 100644 --- a/engines/tsage/blue_force/blueforce_dialogs.cpp +++ b/engines/tsage/blue_force/blueforce_dialogs.cpp @@ -163,9 +163,12 @@ void RightClickDialog::execute() { } g_system->delayMillis(10); - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); } + // Deactivate the graphics manager used for the dialog + _gfxManager.deactivate(); + // Execute the specified action CursorType cursorNum = CURSOR_NONE; switch (_selectedAction) { @@ -193,8 +196,6 @@ void RightClickDialog::execute() { if (cursorNum != CURSOR_NONE) BF_GLOBALS._events.setCursor(cursorNum); - - _gfxManager.deactivate(); } /*--------------------------------------------------------------------------*/ @@ -243,7 +244,7 @@ void AmmoBeltDialog::execute() { } g_system->delayMillis(10); - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); } _gfxManager.deactivate(); @@ -435,29 +436,45 @@ void OptionsDialog::show() { OptionsDialog *dlg = new OptionsDialog(); dlg->draw(); + // Show the dialog GfxButton *btn = dlg->execute(); - if (btn == &dlg->_btnQuit) { + // Get which button was pressed + int btnIndex = -1; + if (btn == &dlg->_btnRestore) + btnIndex = 0; + else if (btn == &dlg->_btnSave) + btnIndex = 1; + else if (btn == &dlg->_btnRestart) + btnIndex = 2; + else if (btn == &dlg->_btnQuit) + btnIndex = 3; + else if (btn == &dlg->_btnSound) + btnIndex = 4; + + // Close the dialog + dlg->remove(); + delete dlg; + + // Execute the given selection + if (btnIndex == 0) { + // Restore button + g_globals->_game->restoreGame(); + } else if (btnIndex == 1) { + // Save button + g_globals->_game->saveGame(); + } else if (btnIndex == 2) { + // Restart game + g_globals->_game->restartGame(); + } else if (btnIndex == 3) { // Quit game if (MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING) == 1) { g_vm->quitGame(); } - } else if (btn == &dlg->_btnRestart) { - // Restart game - g_globals->_game->restartGame(); - } else if (btn == &dlg->_btnSound) { + } else if (btnIndex == 4) { // Sound dialog SoundDialog::execute(); - } else if (btn == &dlg->_btnSave) { - // Save button - g_globals->_game->saveGame(); - } else if (btn == &dlg->_btnRestore) { - // Restore button - g_globals->_game->restoreGame(); } - - dlg->remove(); - delete dlg; } OptionsDialog::OptionsDialog() { diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp index 22299c1bf1..91cba43e1d 100644 --- a/engines/tsage/blue_force/blueforce_logic.cpp +++ b/engines/tsage/blue_force/blueforce_logic.cpp @@ -20,6 +20,7 @@ * */ +#include "common/config-manager.h" #include "tsage/blue_force/blueforce_logic.h" #include "tsage/blue_force/blueforce_dialogs.h" #include "tsage/blue_force/blueforce_scenes0.h" @@ -42,8 +43,25 @@ namespace TsAGE { namespace BlueForce { void BlueForceGame::start() { - // Start the game - g_globals->_sceneManager.changeScene(20); + int slot = -1; + + // Check for a savegame to load straight from the launcher + if (ConfMan.hasKey("save_slot")) { + slot = ConfMan.getInt("save_slot"); + Common::String file = g_vm->generateSaveName(slot); + Common::InSaveFile *in = g_vm->_system->getSavefileManager()->openForLoading(file); + if (in) + delete in; + else + slot = -1; + } + + if (slot >= 0) + // Set the savegame slot to load in the main loop + g_globals->_sceneHandler->_loadGameSlot = slot; + else + // Switch to the title screen + g_globals->_sceneManager.setNewScene(20); } Scene *BlueForceGame::createScene(int sceneNumber) { @@ -255,14 +273,16 @@ Scene *BlueForceGame::createScene(int sceneNumber) { * Returns true if it is currently okay to restore a game */ bool BlueForceGame::canLoadGameStateCurrently() { - return true; + // Don't allow a game to be loaded if a dialog is active + return g_globals->_gfxManagers.size() == 1; } /** * Returns true if it is currently okay to save the game */ bool BlueForceGame::canSaveGameStateCurrently() { - return true; + // Don't allow a game to be saved if a dialog is active + return g_globals->_gfxManagers.size() == 1; } void BlueForceGame::rightClick() { diff --git a/engines/tsage/blue_force/blueforce_logic.h b/engines/tsage/blue_force/blueforce_logic.h index d0d0e0ee40..f5a3938f2b 100644 --- a/engines/tsage/blue_force/blueforce_logic.h +++ b/engines/tsage/blue_force/blueforce_logic.h @@ -65,6 +65,9 @@ public: void add(EventHandler *obj); void remove(EventHandler *obj); + // The following line prevents compiler warnings about hiding the remove() + // method from the parent class. + virtual void remove() { EventHandler::remove(); } }; class Timer: public EventHandler { diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp index b98f6f609d..00c0b3a1f1 100644 --- a/engines/tsage/converse.cpp +++ b/engines/tsage/converse.cpp @@ -451,7 +451,7 @@ int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) { while (!g_globals->_events.getEvent(event, EVENT_KEYPRESS | EVENT_BUTTON_DOWN | EVENT_MOUSE_MOVE) && !g_vm->shouldQuit()) { g_system->delayMillis(10); - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); } if (g_vm->shouldQuit()) break; @@ -531,29 +531,52 @@ void ConversationChoiceDialog::draw() { /*--------------------------------------------------------------------------*/ void Obj44::load(const byte *dataP) { - _id = READ_LE_UINT16(dataP); + Common::MemoryReadStream s(dataP, (g_vm->getGameID() == GType_Ringworld2) ? 126 : 68); + + if (g_vm->getGameID() == GType_Ringworld2) { + _mode = s.readSint16LE(); + _lookupValue = s.readSint16LE(); + _lookupIndex = s.readSint16LE(); + _field6 = s.readSint16LE(); + _field8 = s.readSint16LE(); + } + + _id = s.readSint16LE(); for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx) - _field2[idx] = READ_LE_UINT16(dataP + 2 + idx * 2); + _callbackId[idx] = s.readSint16LE(); + + if (g_vm->getGameID() == GType_Ringworld2) { + _field16 = s.readSint16LE(); + s.skip(20); + } else { + s.skip(4); + } - const byte *listP = dataP + 0x10; - for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx, listP += 10) { - _list[idx]._id = READ_LE_UINT16(listP); - _list[idx]._scriptOffset = READ_LE_UINT16(listP + 2); + for (int idx = 0; idx < OBJ0A_LIST_SIZE; ++idx) { + _list[idx]._id = s.readSint16LE(); + _list[idx]._scriptOffset = s.readSint16LE(); + s.skip(6); } - _speakerOffset = READ_LE_UINT16(dataP + 0x42); + _speakerOffset = s.readSint16LE(); } void Obj44::synchronize(Serializer &s) { s.syncAsSint32LE(_id); for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx) - s.syncAsSint32LE(_field2[idx]); - for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx) + s.syncAsSint32LE(_callbackId[idx]); + for (int idx = 0; idx < OBJ0A_LIST_SIZE; ++idx) _list[idx].synchronize(s); s.syncAsUint32LE(_speakerOffset); - if (g_vm->getGameID() == GType_Ringworld2) + if (g_vm->getGameID() == GType_Ringworld2) { s.syncAsSint16LE(_mode); + s.syncAsSint16LE(_lookupValue); + s.syncAsSint16LE(_lookupIndex); + s.syncAsSint16LE(_field6); + s.syncAsSint16LE(_field8); + s.syncAsSint16LE(_field16); + } } /*--------------------------------------------------------------------------*/ @@ -622,10 +645,12 @@ void StripManager::load() { // Get the object list byte *obj44List = g_resourceManager->getResource(RES_STRIP, _stripNum, 1); int dataSize = g_vm->_memoryManager.getSize(obj44List); - assert((dataSize % 0x44) == 0); + + int obj44Size = (g_vm->getGameID() == GType_Ringworld2) ? 126 : 68; + assert((dataSize % obj44Size) == 0); byte *dataP = obj44List; - for (int idx = 0; idx < (dataSize / 0x44); ++idx, dataP += 0x44) { + for (int idx = 0; idx < (dataSize / obj44Size); ++idx, dataP += obj44Size) { Obj44 obj; obj.load(dataP); _obj44List.push_back(obj); @@ -731,11 +756,21 @@ void StripManager::signal() { if (g_vm->getGameID() != GType_Ringworld2) { _field2E8 = obj44._id; } else { - if (obj44._id) - _field2E8 = obj44._id; + // Return to Ringworld specific handling + if (obj44._field6) + _field2E8 = obj44._field6; switch (obj44._mode) { case 1: + ++_lookupList[obj44._lookupIndex - 1]; + break; + case 2: + --_lookupList[obj44._lookupIndex - 1]; + break; + case 3: + _lookupList[obj44._lookupIndex - 1] = obj44._lookupValue; + break; + default: break; } } @@ -744,12 +779,27 @@ void StripManager::signal() { // Build up a list of script entries int idx; - for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) { - if (!obj44._list[idx]._id) - break; - // Get the next one - choiceList.push_back((const char *)&_script[0] + obj44._list[idx]._scriptOffset); + if (g_vm->getGameID() == GType_Ringworld2 && obj44._field16) { + // Special loading mode used in Return to Ringworld + for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) { + int objIndex = _lookupList[obj44._field16 - 1]; + + if (!obj44._list[objIndex]._id) + break; + + // Get the next one + choiceList.push_back((const char *)&_script[0] + obj44._list[objIndex]._scriptOffset); + } + } else { + // Standard choices loading + for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) { + if (!obj44._list[idx]._id) + break; + + // Get the next one + choiceList.push_back((const char *)&_script[0] + obj44._list[idx]._scriptOffset); + } } int strIndex = 0; @@ -779,10 +829,10 @@ void StripManager::signal() { if (_callbackObject) { for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) { - if (!obj44._field2[idx]) + if (!obj44._callbackId[idx]) break; - _callbackObject->stripCallback(obj44._field2[idx]); + _callbackObject->stripCallback(obj44._callbackId[idx]); } } diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h index db05913e08..0c4eb9539d 100644 --- a/engines/tsage/converse.h +++ b/engines/tsage/converse.h @@ -178,16 +178,19 @@ public: }; #define OBJ44_LIST_SIZE 5 +#define OBJ0A_LIST_SIZE ((g_vm->getGameID() == GType_Ringworld2) ? 8 : 5) class Obj44 : public Serialisable { public: int _id; - int _field2[OBJ44_LIST_SIZE]; - Obj0A _list[OBJ44_LIST_SIZE]; + int _callbackId[OBJ44_LIST_SIZE]; + Obj0A _list[8]; uint _speakerOffset; // Return to Ringworld specific field int _mode; + int _lookupValue, _lookupIndex, _field6; + int _field8, _field16; public: void load(const byte *dataP); virtual void synchronize(Serializer &s); diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index 6a84b2521b..c243624608 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -1415,7 +1415,7 @@ void ScenePalette::fade(const byte *adjustData, bool fullAdjust, int percent) { // Set the altered pale4tte g_system->getPaletteManager()->setPalette((const byte *)&tempPalette[0], 0, 256); - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); } PaletteRotation *ScenePalette::addRotation(int start, int end, int rotationMode, int duration, Action *action) { @@ -1576,12 +1576,11 @@ void SceneItem::display(int resNum, int lineNum, ...) { g_globals->_sceneObjects->draw(); } - GfxFontBackup font; Common::Point pos(160, 100); Rect textRect; int maxWidth = 120; bool keepOnscreen = false; - bool centerText = g_vm->getGameID() == GType_Ringworld; + bool centerText = g_vm->getGameID() != GType_BlueForce; Common::List<int> playList; if (resNum != 0) { @@ -1709,7 +1708,7 @@ void SceneItem::display(int resNum, int lineNum, ...) { // Keep event on-screen until a mouse or keypress while (!g_vm->shouldQuit() && !g_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) { - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); g_system->delayMillis(10); } @@ -2662,43 +2661,48 @@ void SceneObjectList::draw() { } g_globals->_paneRegions[paneNum].setRect(0, 0, 0, 0); -redraw: - // Main draw loop - for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) { - SceneObject *obj = objList[objIndex]; - - if ((obj->_flags & flagMask) && !(obj->_flags & OBJFLAG_HIDE)) { - obj->_paneRects[paneNum] = obj->_bounds; - obj->draw(); + + // FIXME: Currently, removing objects causes screen flickers when the removed object intersects + // another drawn object, since the background is briefly redrawn over the object. For now, I'm + // using a forced jump back to redraw objects. In the long term, I should figure out how the + // original game does this properly + bool redrawFlag = true; + while (redrawFlag) { + redrawFlag = false; + + // Main draw loop + for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) { + SceneObject *obj = objList[objIndex]; + + if ((obj->_flags & flagMask) && !(obj->_flags & OBJFLAG_HIDE)) { + obj->_paneRects[paneNum] = obj->_bounds; + obj->draw(); + } } - } - // Update the palette - g_globals->_sceneManager.fadeInIfNecessary(); - g_globals->_sceneManager._loadMode = 0; - g_globals->_paneRefreshFlag[paneNum] = 0; - - // Loop through the object list, removing any objects and refreshing the screen as necessary - for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) { - SceneObject *obj = objList[objIndex]; - - if (obj->_flags & OBJFLAG_HIDE) - obj->_flags |= OBJFLAG_HIDING; - obj->_flags &= ~flagMask; - if (obj->_flags & OBJFLAG_REMOVE) { - obj->_flags |= OBJFLAG_PANES; - - checkIntersection(objList, objIndex, CURRENT_PANENUM); - - obj->updateScreen(); - obj->removeObject(); - - // FIXME: Currently, removing objects causes screen flickers when the removed object intersects - // another drawn object, since the background is briefly redrawn over the object. For now, I'm - // using a forced jump back to redraw objects. In the long term, I should figure out how the - // original game does this properly - objList.remove_at(objIndex); - goto redraw; + // Update the palette + g_globals->_sceneManager.fadeInIfNecessary(); + g_globals->_sceneManager._loadMode = 0; + g_globals->_paneRefreshFlag[paneNum] = 0; + + // Loop through the object list, removing any objects and refreshing the screen as necessary + for (uint objIndex = 0; objIndex < objList.size() && !redrawFlag; ++objIndex) { + SceneObject *obj = objList[objIndex]; + + if (obj->_flags & OBJFLAG_HIDE) + obj->_flags |= OBJFLAG_HIDING; + obj->_flags &= ~flagMask; + if (obj->_flags & OBJFLAG_REMOVE) { + obj->_flags |= OBJFLAG_PANES; + + checkIntersection(objList, objIndex, CURRENT_PANENUM); + + obj->updateScreen(); + obj->removeObject(); + + objList.remove_at(objIndex); + redrawFlag = true; + } } } } @@ -2985,7 +2989,7 @@ Player::Player(): SceneObject() { _field8C = 0; // Return to Ringworld specific fields - _characterIndex = 0; + _characterIndex = R2_NONE; for (int i = 0; i < MAX_CHARACTERS; ++i) { _characterScene[i] = 0; diff --git a/engines/tsage/core.h b/engines/tsage/core.h index d55352319f..060ffee121 100644 --- a/engines/tsage/core.h +++ b/engines/tsage/core.h @@ -421,7 +421,6 @@ public: virtual void destroy() {} virtual bool startAction(CursorType action, Event &event); virtual void doAction(int action); - virtual bool performAction(CursorType action, Event &event) { return startAction(action, event); } bool contains(const Common::Point &pt); void setBounds(const Rect &newBounds) { _bounds = newBounds; } @@ -621,6 +620,7 @@ public: }; #define MAX_CHARACTERS 4 +enum R2RCharacter { R2_NONE = 0, R2_QUINN = 1, R2_SEEKER = 2, R2_MIRANDA = 3 }; class Player : public SceneObject { public: @@ -630,7 +630,7 @@ public: bool _enabled; // Return to Ringworld specific fields - int _characterIndex; + R2RCharacter _characterIndex; int _characterScene[MAX_CHARACTERS]; int _oldCharacterScene[MAX_CHARACTERS]; Common::Point _characterPos[MAX_CHARACTERS]; diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h index 360dbac0ae..d6b1760b80 100644 --- a/engines/tsage/detection_tables.h +++ b/engines/tsage/detection_tables.h @@ -150,7 +150,7 @@ static const tSageGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, - GUIO2(GUIO_NOSPEECH, GUIO_NOSFX) + GUIO0() }, GType_Ringworld2, GF_CD | GF_ALT_REGIONS diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp index ac08997563..21dc86b8ec 100644 --- a/engines/tsage/events.cpp +++ b/engines/tsage/events.cpp @@ -49,8 +49,8 @@ bool EventsClass::pollEvent() { _priorFrameTime = milli; ++_frameNumber; - // Update screen - g_system->updateScreen(); + // Update the physical screen with any updates to the screen surface + GLOBALS._screenSurface.copyToScreen(); } if (!g_system->getEventManager()->pollEvent(_event)) return false; @@ -386,7 +386,7 @@ bool EventsClass::isCursorVisible() const { */ void EventsClass::delay(int numFrames) { while (_frameNumber < (_prevDelayFrame + numFrames)) { - uint32 delayAmount = CLIP(_priorFrameTime + GAME_FRAME_TIME - g_system->getMillis(), + uint32 delayAmount = CLIP(_priorFrameTime + GAME_SCRIPT_TIME - g_system->getMillis(), (uint32)0, (uint32)GAME_FRAME_TIME); if (delayAmount > 0) g_system->delayMillis(delayAmount); @@ -395,7 +395,7 @@ void EventsClass::delay(int numFrames) { _priorFrameTime = g_system->getMillis(); } - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); _prevDelayFrame = _frameNumber; _priorFrameTime = g_system->getMillis(); } diff --git a/engines/tsage/events.h b/engines/tsage/events.h index 1942c98901..fe4d3ecde6 100644 --- a/engines/tsage/events.h +++ b/engines/tsage/events.h @@ -36,9 +36,12 @@ enum EventType {EVENT_NONE = 0, EVENT_BUTTON_DOWN = 1, EVENT_BUTTON_UP = 2, EVEN enum ButtonShiftFlags {BTNSHIFT_LEFT = 0, BTNSHIFT_RIGHT = 3, BTNSHIFT_MIDDLE = 4}; -// Intrinisc game delay between execution frames. This runs at 60Hz -#define GAME_FRAME_RATE 60 -#define GAME_FRAME_TIME (1000 / 60) +// Intrinisc game delay between execution frames +#define GAME_FRAME_RATE 50 +#define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE) + +#define GAME_SCRIPT_RATE 80 +#define GAME_SCRIPT_TIME (1000 / GAME_SCRIPT_RATE) class GfxManager; @@ -83,9 +86,10 @@ enum CursorType { INV_CARAVAN_KEY = 67, BF_LAST_INVENT = 68, // Ringworld 2 objects - R2_OPTO_DISK = 1, R2_2 = 2, R2_NEGATOR_GUN = 3, R2_STEPPING_DISKS = 4, R2_5 = 5, R2_6 = 6, - R2_7 = 7, R2_8 = 8, R2_9 = 9, R2_10 = 10, R2_11 = 11, R2_12 = 12, R2_13 = 13, R2_14 = 14, - R2_15 = 15, R2_16 = 16, R2_17 = 17, R2_18 = 18, R2_19 = 19, R2_20 = 20, R2_21 = 21, + R2_OPTO_DISK = 1, R2_READER = 2, R2_NEGATOR_GUN = 3, R2_STEPPING_DISKS = 4, + R2_ATTRACTOR_UNIT = 5, R2_SENSOR_PROBE = 6, + R2_7 = 7, R2_8 = 8, R2_9 = 9, R2_10 = 10, R2_11 = 11, R2_12 = 12, R2_13 = 13, R2_OPTICAL_FIBRE = 14, + R2_CLAMP = 15, R2_16 = 16, R2_17 = 17, R2_18 = 18, R2_19 = 19, R2_20 = 20, R2_21 = 21, R2_22 = 22, R2_23 = 23, R2_24 = 24, R2_25 = 25, R2_26 = 26, R2_27 = 27, R2_28 = 28, R2_29 = 29, R2_30 = 30, R2_31 = 31, R2_32 = 32, R2_33 = 33, R2_34 = 34, R2_35 = 35, R2_36 = 36, R2_37 = 37, R2_38 = 38, R2_39 = 39, R2_40 = 40, R2_41 = 41, R2_42 = 42, diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp index 0b59fd4e36..1d0e37d071 100644 --- a/engines/tsage/globals.cpp +++ b/engines/tsage/globals.cpp @@ -108,9 +108,15 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface _color2 = _gfxColors.foreground; _color3 = _gfxColors.foreground; } - _screenSurface.setScreenSurface(); + + // Set up a buffer for the screen surface + _screenSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT); + _screenSurface.trackDirtyRects(); + + // Add the global graphics manager to the graphic manager list _gfxManagers.push_back(&_gfxManagerInstance); + // Set up the global scene objects list _sceneObjects = &_sceneObjectsInstance; _sceneObjects_queue.push_front(_sceneObjects); @@ -377,12 +383,13 @@ void Ringworld2Globals::reset() { // Reset fields _v5657C = 0; _v565F5 = 0; + _v565AE = 0; for (int i = 0; i < 14; i++) _v56605[i] = 0; _v57C2C = 0; _v58CE2 = 0; Common::fill(&_v565F1[0], &_v565F1[MAX_CHARACTERS], 0); - _speechSubtitles = 0; + _speechSubtitles = SPEECH_VOICE | SPEECH_TEXT; _insetUp = 0; Common::fill(&_v565F1[0], &_v565F1[MAX_CHARACTERS], 0); @@ -399,7 +406,7 @@ void Ringworld2Globals::reset() { _stripManager_lookupList[11] = 1; // Reset fields stored in the player class - _player._characterIndex = 1; + _player._characterIndex = R2_QUINN; _player._characterScene[1] = 100; _player._characterScene[2] = 300; _player._characterScene[3] = 300; @@ -417,6 +424,8 @@ void Ringworld2Globals::synchronize(Serializer &s) { for (i = 0; i < MAX_CHARACTERS; ++i) s.syncAsSint16LE(_v565F1[i]); + + s.syncAsByte(_v565AE); for (i = 0; i < 14; ++i) s.syncAsByte(_v56605[i]); diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h index e3c6f5cbc7..9048899953 100644 --- a/engines/tsage/globals.h +++ b/engines/tsage/globals.h @@ -239,6 +239,9 @@ public: namespace Ringworld2 { +#define SPEECH_TEXT 1 +#define SPEECH_VOICE 2 + class Ringworld2Globals: public TsAGE2Globals { public: ASoundExt _sound1, _sound2, _sound3, _sound4; @@ -247,6 +250,7 @@ public: int _insetUp; int _v565F5; int _v5657C; + byte _v565AE; byte _v56605[14]; int _v57C2C; int _v58CE2; diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp index 171167c2ea..bc4ce75c22 100644 --- a/engines/tsage/graphics.cpp +++ b/engines/tsage/graphics.cpp @@ -220,11 +220,10 @@ void Rect::synchronize(Serializer &s) { GfxSurface::GfxSurface() : _bounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) { _disableUpdates = false; - _screenSurface = false; _lockSurfaceCtr = 0; _customSurface = NULL; - _screenSurfaceP = NULL; _transColor = -1; + _trackDirtyRects = false; } GfxSurface::GfxSurface(const GfxSurface &s) { @@ -241,12 +240,41 @@ GfxSurface::~GfxSurface() { } /** - * Specifies that the surface will encapsulate the ScummVM screen surface + * Turns on dirty rectangle tracking for the surface */ -void GfxSurface::setScreenSurface() { - _screenSurface = true; - _customSurface = NULL; - _lockSurfaceCtr = 0; +void GfxSurface::trackDirtyRects() { + _trackDirtyRects = true; +} + +void GfxSurface::addDirtyRect(const Rect &r) { + if (_trackDirtyRects) + _dirtyRects.push_back(Rect(r.left, r.top, + MIN(r.right + 1, SCREEN_WIDTH), MIN(r.bottom + 1, SCREEN_HEIGHT))); +} + +/** + * Copies all areas specified by the dirty rect list to the screen + */ +void GfxSurface::copyToScreen() { + assert(_trackDirtyRects); + + // Merge any overlapping dirty rects + mergeDirtyRects(); + + // Loop through the dirty rect list to copy the affected areas to the sc + for (Common::List<Rect>::iterator i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) { + Rect r = *i; + + const byte *srcP = (const byte *)_customSurface->getBasePtr(r.left, r.top); + g_system->copyRectToScreen(srcP, _customSurface->pitch, r.left, r.top, + r.width(), r.height()); + } + + // Update the physical screen + g_system->updateScreen(); + + // Now that the dirty rects have been copied, clear the dirty rect list + _dirtyRects.clear(); } /** @@ -254,11 +282,13 @@ void GfxSurface::setScreenSurface() { */ void GfxSurface::create(int width, int height) { assert((width >= 0) && (height >= 0)); - _screenSurface = false; + + // Delete any prior internal surface that may have been previously created if (_customSurface) { _customSurface->free(); delete _customSurface; } + _customSurface = new Graphics::Surface(); _customSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); Common::fill((byte *)_customSurface->pixels, (byte *)_customSurface->pixels + (width * height), 0); @@ -271,13 +301,7 @@ void GfxSurface::create(int width, int height) { Graphics::Surface GfxSurface::lockSurface() { ++_lockSurfaceCtr; - Graphics::Surface *src; - if (_screenSurface) { - if (_lockSurfaceCtr == 1) - _screenSurfaceP = g_system->lockScreen(); - src = _screenSurfaceP; - } else - src = _customSurface; + Graphics::Surface *src = _customSurface; assert(src); // Setup the returned surface either as one pointing to the same pixels as the source, or @@ -298,15 +322,10 @@ Graphics::Surface GfxSurface::lockSurface() { void GfxSurface::unlockSurface() { assert(_lockSurfaceCtr > 0); --_lockSurfaceCtr; - - if ((_lockSurfaceCtr == 0) && _screenSurface) { - g_system->unlockScreen(); - } } void GfxSurface::synchronize(Serializer &s) { assert(!_lockSurfaceCtr); - assert(!_screenSurface); s.syncAsByte(_disableUpdates); _bounds.synchronize(s); @@ -351,6 +370,7 @@ void GfxSurface::fillRect(const Rect &bounds, int color) { Graphics::Surface surface = lockSurface(); surface.fillRect(bounds, color); unlockSurface(); + addDirtyRect(bounds); } GfxSurface &GfxSurface::operator=(const GfxSurface &s) { @@ -363,7 +383,6 @@ GfxSurface &GfxSurface::operator=(const GfxSurface &s) { } _customSurface = s._customSurface; - _screenSurface = s._screenSurface; _disableUpdates = s._disableUpdates; _bounds = s._bounds; _centroid = s._centroid; @@ -567,10 +586,17 @@ void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Regi if (destBounds.bottom > destSurface.h) destBounds.bottom = destSurface.h; - if (destBounds.isValidRect()) { + if (destBounds.isValidRect() && (destBounds.left < SCREEN_WIDTH) && (destBounds.right >= 0) && + (destBounds.top < SCREEN_HEIGHT) && (destBounds.bottom >= 0)) { + // Register the affected area as dirty + addDirtyRect(Rect(destBounds.left + _bounds.left, destBounds.top + _bounds.top, + destBounds.right + _bounds.left, destBounds.bottom + _bounds.top)); + + // Get pointers to the source and destination surface areas const byte *pSrc = (const byte *)srcSurface.getBasePtr(srcX, srcY); byte *pDest = (byte *)destSurface.getBasePtr(destBounds.left, destBounds.top); + // Loop through copying each row for (int y = 0; y < destBounds.height(); ++y, pSrc += srcSurface.pitch, pDest += destSurface.pitch) { if (!priorityRegion && (src._transColor == -1)) @@ -595,6 +621,7 @@ void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Regi } } + // Unlock the surfaces unlockSurface(); srcImage.unlockSurface(); } @@ -613,6 +640,68 @@ void GfxSurface::draw(const Common::Point &pt, Rect *rect) { } } +/** + * Merges any clipping rectangles that overlap to try and reduce + * the total number of clip rectangles. + */ +void GfxSurface::mergeDirtyRects() { + if (_dirtyRects.size() <= 1) + return; + + Common::List<Rect>::iterator rOuter, rInner; + + for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) { + rInner = rOuter; + while (++rInner != _dirtyRects.end()) { + + if (looseIntersectRectangle(*rOuter, *rInner)) { + // these two rectangles overlap or + // are next to each other - merge them + + unionRectangle(*rOuter, *rOuter, *rInner); + + // remove the inner rect from the list + _dirtyRects.erase(rInner); + + // move back to beginning of list + rInner = rOuter; + } + } + } +} + +/** + * Check if the two rectangles are next to each other. + * @param pSrc1 a source rectangle + * @param pSrc2 a source rectangle + */ +bool GfxSurface::looseIntersectRectangle(const Rect &src1, const Rect &src2) { + Rect destRect; + + destRect.left = MAX(src1.left, src2.left); + destRect.top = MAX(src1.top, src2.top); + destRect.right = MIN(src1.right, src2.right); + destRect.bottom = MIN(src1.bottom, src2.bottom); + + return destRect.isValidRect(); +} + +/** + * Creates the union of two rectangles. + * Returns True if there is a union. + * @param pDest destination rectangle that is to receive the new union + * @param pSrc1 a source rectangle + * @param pSrc2 a source rectangle + */ +bool GfxSurface::unionRectangle(Common::Rect &destRect, const Rect &src1, const Rect &src2) { + destRect.left = MIN(src1.left, src2.left); + destRect.top = MIN(src1.top, src2.top); + destRect.right = MAX(src1.right, src2.right); + destRect.bottom = MAX(src1.bottom, src2.bottom); + + return !destRect.isEmpty(); +} + /*--------------------------------------------------------------------------*/ GfxElement::GfxElement() { @@ -639,6 +728,9 @@ void GfxElement::highlight() { GfxManager &gfxManager = g_globals->gfxManager(); Graphics::Surface surface = gfxManager.lockSurface(); + // Mark the area is dirty + gfxManager.addDirtyRect(_bounds); + // Scan through the contents of the element, switching any occurances of the foreground // color with the background color and vice versa Rect tempRect(_bounds); @@ -734,6 +826,7 @@ void GfxElement::drawFrame() { gfxManager.fillRect2(tempRect.right, tempRect.top + 2, 1, tempRect.height() - 3, 0); gfxManager.unlockSurface(); + gfxManager.addDirtyRect(_bounds); } /** @@ -1090,7 +1183,7 @@ GfxButton *GfxDialog::execute(GfxButton *defaultButton) { } g_system->delayMillis(10); - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); } _gfxManager.deactivate(); @@ -1174,6 +1267,11 @@ void GfxManager::fillArea(int xp, int yp, int color) { _surface.fillRect(tempRect, color); } +void GfxManager::addDirtyRect(const Rect &r) { + _surface.addDirtyRect(Rect(r.left + _bounds.left, r.top + _bounds.top, + r.right + _bounds.left, r.bottom + _bounds.top)); +} + void GfxManager::fillRect(const Rect &bounds, int color) { _surface.setBounds(_bounds); _surface.fillRect(bounds, color); diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h index dba3401700..e32994505c 100644 --- a/engines/tsage/graphics.h +++ b/engines/tsage/graphics.h @@ -74,12 +74,16 @@ public: class GfxSurface { private: Graphics::Surface *_customSurface; - Graphics::Surface *_screenSurfaceP; int _lockSurfaceCtr; - bool _screenSurface; bool _disableUpdates; Rect _bounds; + bool _trackDirtyRects; + Common::List<Rect> _dirtyRects; + + void mergeDirtyRects(); + bool looseIntersectRectangle(const Rect &src1, const Rect &src2); + bool unionRectangle(Common::Rect &destRect, const Rect &src1, const Rect &src2); public: Common::Point _centroid; int _transColor; @@ -88,7 +92,9 @@ public: GfxSurface(const GfxSurface &s); ~GfxSurface(); - void setScreenSurface(); + void trackDirtyRects(); + void addDirtyRect(const Rect &r); + void copyToScreen(); Graphics::Surface lockSurface(); void unlockSurface(); void synchronize(Serializer &s); @@ -274,6 +280,7 @@ public: return _surface.lockSurface(); } void unlockSurface() { _surface.unlockSurface(); } + void addDirtyRect(const Rect &r); void fillArea(int xp, int yp, int color); void fillRect(const Rect &bounds, int color); void fillRect2(int xs, int ys, int width, int height, int color); @@ -301,7 +308,6 @@ public: void copyFrom(GfxSurface &src, int destX, int destY) { _surface.setBounds(_bounds); _surface.copyFrom(src, destX, destY); - g_system->updateScreen(); } GfxSurface &getSurface() { _surface.setBounds(_bounds); diff --git a/engines/tsage/module.mk b/engines/tsage/module.mk index 44f808ba8e..95a1a583dd 100644 --- a/engines/tsage/module.mk +++ b/engines/tsage/module.mk @@ -39,6 +39,7 @@ MODULE_OBJS := \ ringworld2/ringworld2_logic.o \ ringworld2/ringworld2_scenes0.o \ ringworld2/ringworld2_scenes2.o \ + ringworld2/ringworld2_scenes3.o \ ringworld2/ringworld2_speakers.o \ saveload.o \ scenes.o \ diff --git a/engines/tsage/ringworld/ringworld_dialogs.cpp b/engines/tsage/ringworld/ringworld_dialogs.cpp index 37101c9c58..0561a27055 100644 --- a/engines/tsage/ringworld/ringworld_dialogs.cpp +++ b/engines/tsage/ringworld/ringworld_dialogs.cpp @@ -183,9 +183,11 @@ void RightClickDialog::execute() { } g_system->delayMillis(10); - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); } + _gfxManager.deactivate(); + // Execute the specified action switch (_selectedAction) { case 1: @@ -213,8 +215,6 @@ void RightClickDialog::execute() { Ringworld::OptionsDialog::show(); break; } - - _gfxManager.deactivate(); } /*--------------------------------------------------------------------------*/ @@ -394,7 +394,7 @@ void InventoryDialog::execute() { Event event; while (!g_globals->_events.getEvent(event) && !g_vm->shouldQuit()) { g_system->delayMillis(10); - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); } if (g_vm->shouldQuit()) break; diff --git a/engines/tsage/ringworld/ringworld_logic.cpp b/engines/tsage/ringworld/ringworld_logic.cpp index ad67b66f69..2497327a01 100644 --- a/engines/tsage/ringworld/ringworld_logic.cpp +++ b/engines/tsage/ringworld/ringworld_logic.cpp @@ -196,14 +196,17 @@ Scene *RingworldGame::createScene(int sceneNumber) { * Returns true if it is currently okay to restore a game */ bool RingworldGame::canLoadGameStateCurrently() { - return !g_globals->getFlag(50); + // Don't allow a game to be loaded if a dialog is active + return !g_globals->getFlag(50) && (g_globals->_gfxManagers.size() == 1); + } /** * Returns true if it is currently okay to save the game */ bool RingworldGame::canSaveGameStateCurrently() { - return !g_globals->getFlag(50); + // Don't allow a game to be saved if a dialog is active + return !g_globals->getFlag(50) && (g_globals->_gfxManagers.size() == 1); } /*--------------------------------------------------------------------------*/ @@ -312,7 +315,7 @@ void SceneArea::wait() { // Wait until a mouse or keypress Event event; while (!g_vm->shouldQuit() && !g_globals->_events.getEvent(event)) { - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); g_system->delayMillis(10); } diff --git a/engines/tsage/ringworld/ringworld_scenes3.cpp b/engines/tsage/ringworld/ringworld_scenes3.cpp index 81190aea7b..6f3d1ed93a 100644 --- a/engines/tsage/ringworld/ringworld_scenes3.cpp +++ b/engines/tsage/ringworld/ringworld_scenes3.cpp @@ -532,7 +532,7 @@ void Scene2100::Action1::signal() { // Wait for an event Event event; if (!g_globals->_events.getEvent(event)) { - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); g_system->delayMillis(10); continue; } @@ -2263,7 +2263,7 @@ void Scene2150::Action1::signal() { // Wait for an event Event event; if (!g_globals->_events.getEvent(event)) { - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); g_system->delayMillis(10); continue; } @@ -5118,7 +5118,7 @@ void Scene2320::Action3::signal() { // Wait for an event Event event; if (!g_globals->_events.getEvent(event)) { - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); g_system->delayMillis(10); continue; } diff --git a/engines/tsage/ringworld/ringworld_scenes5.cpp b/engines/tsage/ringworld/ringworld_scenes5.cpp index 49726eba2e..7c8da54fac 100644 --- a/engines/tsage/ringworld/ringworld_scenes5.cpp +++ b/engines/tsage/ringworld/ringworld_scenes5.cpp @@ -2810,7 +2810,7 @@ void Scene4150::Action1::signal() { case 4: { for (int idx = 100; idx >= 0; idx -= 5) { g_globals->_scenePalette.fade(adjustData, false, idx); - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); g_system->delayMillis(10); } @@ -2838,7 +2838,7 @@ void Scene4150::Action1::signal() { case 7: for (int idx = 100; idx >= 0; idx -= 5) { g_globals->_scenePalette.fade(adjustData, false, idx); - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); g_system->delayMillis(10); } diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.cpp b/engines/tsage/ringworld2/ringworld2_dialogs.cpp index 54a15f3d98..6035b37e19 100644 --- a/engines/tsage/ringworld2/ringworld2_dialogs.cpp +++ b/engines/tsage/ringworld2/ringworld2_dialogs.cpp @@ -153,7 +153,7 @@ void RightClickDialog::execute() { } g_system->delayMillis(10); - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); } // Execute the specified action @@ -218,11 +218,11 @@ void CharacterDialog::show() { // Figure out the new selected character if (btn == &dlg->_btnQuinn) - R2_GLOBALS._player._characterIndex = 1; + R2_GLOBALS._player._characterIndex = R2_QUINN; else if (btn == &dlg->_btnSeeker) - R2_GLOBALS._player._characterIndex = 2; + R2_GLOBALS._player._characterIndex = R2_SEEKER; else if (btn == &dlg->_btnMiranda) - R2_GLOBALS._player._characterIndex = 3; + R2_GLOBALS._player._characterIndex = R2_MIRANDA; // Remove the dialog dlg->remove(); diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp index 19b4bb6513..689b2b5f0f 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.cpp +++ b/engines/tsage/ringworld2/ringworld2_logic.cpp @@ -28,6 +28,7 @@ #include "tsage/ringworld2/ringworld2_dialogs.h" #include "tsage/ringworld2/ringworld2_scenes0.h" #include "tsage/ringworld2/ringworld2_scenes2.h" +#include "tsage/ringworld2/ringworld2_scenes3.h" namespace TsAGE { @@ -36,35 +37,51 @@ namespace Ringworld2 { Scene *Ringworld2Game::createScene(int sceneNumber) { switch (sceneNumber) { /* Scene group #0 */ - // - case 50: return new Scene50(); - // Quinn's room - case 100: return new Scene100(); - // Computer console - case 125: return new Scene125(); - // - case 150: + case 50: + // Waking up cutscene + return new Scene50(); + case 100: + // Quinn's room + return new Scene100(); + case 125: + // Computer console + return new Scene125(); + case 150: + // Empty Bedroom #1 + return new Scene150(); case 160: + error("Missing scene %d from group 0", sceneNumber); case 175: + // Empty Bedroom #2 + return new Scene175(); case 180: error("Missing scene %d from group 0", sceneNumber); case 200: - // Ship Corridor + // Deck #2 - By Lift return new Scene200(); case 205: - case 250: error("Missing scene %d from group 0", sceneNumber); + case 250: + // Lift + return new Scene250(); case 300: + // Bridge return new Scene300(); case 325: + error("Missing scene %d from group 0", sceneNumber); case 400: + // Science Lab + return new Scene400(); case 500: case 525: case 600: case 700: case 800: case 825: + error("Missing scene %d from group 0", sceneNumber); case 850: + // Deck #5 - By Lift + return new Scene850(); case 900: error("Missing scene %d from group 0", sceneNumber); /* Scene group #1 */ @@ -95,36 +112,65 @@ Scene *Ringworld2Game::createScene(int sceneNumber) { /* Scene group #2 */ // case 2000: - // Maze + // Ice Maze return new Scene2000(); case 2350: - // Maze: Balloon Launch Platform + // Ice Maze: Balloon Launch Platform return new Scene2350(); case 2400: - // Maze: Large empty room + // Ice Maze: Large empty room return new Scene2400(); case 2425: - // Maze: + // Ice Maze: return new Scene2425(); case 2430: + // Ice Maze: Bedroom + return new Scene2430(); case 2435: + // Ice Maze: Throne room + return new Scene2435(); case 2440: + // Ice Maze: Another bedroom + return new Scene2440(); case 2445: + // Ice Maze: + return new Scene2445(); case 2450: + // Ice Maze: Another bedroom + return new Scene2450(); case 2455: + // Ice Maze: Inside crevasse + return new Scene2455(); case 2500: + // Ice Maze: Large Cave + return new Scene2500(); case 2525: + // Ice Maze: Furnace room + return new Scene2525(); case 2530: + // Ice Maze: Well + return new Scene2530(); case 2535: + // Ice Maze: Tannery + return new Scene2535(); case 2600: + // Ice Maze: Exit + return new Scene2600(); case 2700: + // Forest Maze + return new Scene2700(); case 2750: + // Forest Maze + return new Scene2750(); case 2800: + // Exiting Forest + return new Scene2800(); case 2900: error("Missing scene %d from group 2", sceneNumber); /* Scene group #3 */ // case 3100: + return new Scene3100(); case 3125: case 3150: case 3175: @@ -159,14 +205,16 @@ Scene *Ringworld2Game::createScene(int sceneNumber) { * Returns true if it is currently okay to restore a game */ bool Ringworld2Game::canLoadGameStateCurrently() { - return true; + // Don't allow a game to be loaded if a dialog is active + return g_globals->_gfxManagers.size() == 1; } /** * Returns true if it is currently okay to save the game */ bool Ringworld2Game::canSaveGameStateCurrently() { - return true; + // Don't allow a game to be saved if a dialog is active + return g_globals->_gfxManagers.size() == 1; } /*--------------------------------------------------------------------------*/ @@ -244,14 +292,16 @@ void SceneExt::loadScene(int sceneNum) { bool SceneExt::display(CursorType action) { switch (action) { + case CURSOR_CROSSHAIRS: + return false; case CURSOR_LOOK: - SceneItem::display2(9000, R2_GLOBALS._randomSource.getRandomNumber(2)); + SceneItem::display2(1, R2_GLOBALS._randomSource.getRandomNumber(4)); break; case CURSOR_USE: - SceneItem::display2(9000, R2_GLOBALS._randomSource.getRandomNumber(2) + 6); + SceneItem::display2(1, R2_GLOBALS._randomSource.getRandomNumber(4) + 5); break; case CURSOR_TALK: - SceneItem::display2(9000, R2_GLOBALS._randomSource.getRandomNumber(2) + 3); + SceneItem::display2(1, R2_GLOBALS._randomSource.getRandomNumber(4) + 10); break; default: return false; @@ -554,11 +604,11 @@ void Ringworld2InvObjectList::reset() { // Set up default inventory setObjectScene(R2_OPTO_DISK, 800); - setObjectScene(R2_2, 400); + setObjectScene(R2_READER, 400); setObjectScene(R2_NEGATOR_GUN, 100); setObjectScene(R2_STEPPING_DISKS, 100); - setObjectScene(R2_5, 400); - setObjectScene(R2_6, 400); + setObjectScene(R2_ATTRACTOR_UNIT, 400); + setObjectScene(R2_SENSOR_PROBE, 400); setObjectScene(R2_7, 500); setObjectScene(R2_8, 700); setObjectScene(R2_9, 800); @@ -566,8 +616,8 @@ void Ringworld2InvObjectList::reset() { setObjectScene(R2_11, 400); setObjectScene(R2_12, 500); setObjectScene(R2_13, 1550); - setObjectScene(R2_14, 850); - setObjectScene(R2_15, 850); + setObjectScene(R2_OPTICAL_FIBRE, 850); + setObjectScene(R2_CLAMP, 850); setObjectScene(R2_16, 0); setObjectScene(R2_17, 1550); setObjectScene(R2_18, 1550); diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp index 5ca178596f..7a3b0cdd78 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp @@ -64,7 +64,7 @@ void Scene50::process(Event &event) { event.handled = true; warning("TODO: incomplete Scene50::process()"); // CursorType _oldCursorId = _cursorId; - g_globals->_events.setCursor(R2_2); + g_globals->_events.setCursor(CURSOR_ARROW); // _cursorManager.sub_1D474(2, 0); // sub_5566A(1); // _cursorManager._fieldE = _oldCursorId; @@ -94,11 +94,11 @@ bool Scene100::Door::startAction(CursorType action, Event &event) { if (_state) { SceneItem::display2(100, 26); _state = 0; - scene->_object10.setFrame(1); + scene->_doorDisplay.setFrame(1); } else { SceneItem::display2(100, 27); _state = 1; - scene->_object10.setFrame(2); + scene->_doorDisplay.setFrame(2); } return true; default: @@ -176,7 +176,7 @@ bool Scene100::StasisNegator::startAction(CursorType action, Event &event) { } } -bool Scene100::Object10::startAction(CursorType action, Event &event) { +bool Scene100::DoorDisplay::startAction(CursorType action, Event &event) { Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene; switch (action) { @@ -242,34 +242,35 @@ void Scene100::postInit(SceneObjectList *OwnerList) { _door.setPosition(Common::Point(160, 84)); _door.setDetails(100, 3, 4, 5, 1, NULL); - _object10.postInit(); - _object10.setup(100, 2, 1); - _object10.setDetails(100, -1, -1, -1, 1, NULL); + _doorDisplay.postInit(); + _doorDisplay.setup(100, 2, 1); + _doorDisplay.setPosition(Common::Point(202, 53)); + _doorDisplay.setDetails(100, -1, -1, -1, 1, NULL); _table.postInit(); _table.setup(100, 2, 3); _table.setPosition(Common::Point(175, 157)); _table.setDetails(100, 17, 18, 20, 1, NULL); - _object1.postInit(); - _object1.setup(100, 3, 1); - _object1.setPosition(Common::Point(89, 79)); - _object1.fixPriority(250); - _object1.animate(ANIM_MODE_2, NULL); - _object1._numFrames = 3; - - _object2.postInit(); - _object2.setup(100, 3, 1); - _object2.setPosition(Common::Point(89, 147)); - _object2.fixPriority(250); - _object2.animate(ANIM_MODE_7, 0, NULL); - _object2._numFrames = 3; - - _object6.postInit(); - _object6.setVisage(101); - _object6.setPosition(Common::Point(231, 126)); - _object6.fixPriority(10); - _object6.setDetails(100, 37, -1, 39, 1, NULL); + _bedLights1.postInit(); + _bedLights1.setup(100, 3, 1); + _bedLights1.setPosition(Common::Point(89, 79)); + _bedLights1.fixPriority(250); + _bedLights1.animate(ANIM_MODE_2, NULL); + _bedLights1._numFrames = 3; + + _bedLights2.postInit(); + _bedLights2.setup(100, 3, 1); + _bedLights2.setPosition(Common::Point(89, 147)); + _bedLights2.fixPriority(250); + _bedLights2.animate(ANIM_MODE_7, 0, NULL); + _bedLights2._numFrames = 3; + + _wardrobe.postInit(); + _wardrobe.setVisage(101); + _wardrobe.setPosition(Common::Point(231, 126)); + _wardrobe.fixPriority(10); + _wardrobe.setDetails(100, 37, -1, 39, 1, NULL); if (R2_INVENTORY.getObjectScene(R2_STEPPING_DISKS) == 100) { _steppingDisks.postInit(); @@ -296,7 +297,7 @@ void Scene100::postInit(SceneObjectList *OwnerList) { _object5.postInit(); _object4.postInit(); _sceneMode = 104; - setAction(&_sequenceManager1, this, 104, &R2_GLOBALS._player, &_object6, &_object4, &_object5, NULL); + setAction(&_sequenceManager1, this, 104, &R2_GLOBALS._player, &_wardrobe, &_object4, &_object5, NULL); break; case 125: _sceneMode = 100; @@ -356,10 +357,10 @@ void Scene100::signal() { case 110: if (_door._state) { _door._state = 0; - _object10.setFrame(1); + _doorDisplay.setFrame(1); } else { _door._state = 1; - _object10.setFrame(2); + _doorDisplay.setFrame(2); } R2_GLOBALS._player.enableControl(); break; @@ -774,7 +775,7 @@ void Scene125::signal() { case 12: if (_soundCount > 0) --_soundCount; - if (!_soundCount || (R2_GLOBALS._speechSubtitles & 2)) { + if (!_soundCount || (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) { _soundIndex = 0; R2_GLOBALS._playStream.stop(); } else { @@ -1148,7 +1149,7 @@ void Scene125::setDetails(int resNum, int lineNum) { R2_GLOBALS._sceneObjects->draw(); - if ((_soundCount > 0) && (R2_GLOBALS._speechSubtitles & 2)) { + if ((_soundCount > 0) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) { _sceneMode = 12; R2_GLOBALS._playStream.play(_soundIndexes[_soundIndex], this); } @@ -1199,6 +1200,96 @@ Common::String Scene125::parseMessage(const Common::String &msg) { } /*-------------------------------------------------------------------------- + * Scene 150 - Empty Bedroom + * + *--------------------------------------------------------------------------*/ + +void Scene150::postInit(SceneObjectList *OwnerList) { + SceneExt::postInit(); + loadScene(100); + + _door.postInit(); + _door._state = 0; + _door.setVisage(100); + _door.setPosition(Common::Point(160, 84)); + _door.setDetails(100, 3, -1, -1, 1, NULL); + + _doorDisplay.postInit(); + _doorDisplay.setup(100, 2, 1); + _doorDisplay.setPosition(Common::Point(202, 53)); + _doorDisplay.setDetails(100, -1, -1, -1, 1, NULL); + + _emptyRoomTable.postInit(); + _emptyRoomTable.setVisage(100); + _emptyRoomTable.setStrip(4); + _emptyRoomTable.setFrame(1); + _emptyRoomTable.setPosition(Common::Point(175, 157)); + _emptyRoomTable.setDetails(150, 3, 4, 5, 1, NULL); + + _wardrobe.postInit(); + _wardrobe.setVisage(101); + _wardrobe.setPosition(Common::Point(231, 126)); + _wardrobe.fixPriority(10); + _wardrobe.setDetails(100, 37, -1, 39, 1, NULL); + + _terminal.setDetails(11, 100, 14, 15, 16); + _desk.setDetails(12, 100, 11, -1, 13); + _bed.setDetails(13, 100, 8, 9, 10); + _duct.setDetails(14, 100, 34, -1, 36); + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.setVisage(10); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player.disableControl(); + + _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 150, 0, 1, -1, 1, NULL); + _sceneMode = 100; + + switch (R2_GLOBALS._sceneManager._previousScene) { + case 100: + setAction(&_sequenceManager1, this, 106, &R2_GLOBALS._player, NULL); + break; + case 200: + setAction(&_sequenceManager1, this, 100, &R2_GLOBALS._player, &_door, NULL); + break; + default: + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.setPosition(Common::Point(180, 100)); + R2_GLOBALS._player.enableControl(); + break; + } +} + +void Scene150::remove() { + R2_GLOBALS._sound1.fadeOut2(NULL); + SceneExt::remove(); +} + +void Scene150::signal() { + switch (_sceneMode) { + case 101: + R2_GLOBALS._sceneManager.changeScene(200); + break; + case 105: + R2_GLOBALS._sceneManager.changeScene(125); + break; + case 110: + if (_door._state) { + _door._state = 0; + _doorDisplay.setFrame(1); + } else { + _door._state = 1; + _doorDisplay.setFrame(2); + } + R2_GLOBALS._player.enableControl(); + break; + default: + R2_GLOBALS._player.enableControl(); + break; + } +} + +/*-------------------------------------------------------------------------- * Scene 200 - Ship Corridor * *--------------------------------------------------------------------------*/ @@ -1353,6 +1444,312 @@ void Scene200::signal() { } /*-------------------------------------------------------------------------- + * Scene 250 - Lift + * + *--------------------------------------------------------------------------*/ + +Scene250::Button::Button(): SceneActor() { + _floorNumber = _v2 = 0; +} + +void Scene250::Button::synchronize(Serializer &s) { + SceneActor::synchronize(s); + + s.syncAsSint16LE(_floorNumber); + s.syncAsSint16LE(_v2); +} + +bool Scene250::Button::startAction(CursorType action, Event &event) { + Scene250 *scene = (Scene250 *)R2_GLOBALS._sceneManager._scene; + + switch (action) { + case CURSOR_USE: + if (scene->_field414) { + SceneItem::display2(250, 15); + } else { + switch (_floorNumber) { + case 1: + case 2: + case 5: + case 9: + scene->_sound1.play(14); + scene->changeFloor(_floorNumber); + break; + case 10: + // Current Floor + scene->_sound1.play(14); + R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._sceneManager._previousScene); + break; + default: + SceneItem::display2(250, 16); + break; + } + } + return true; + + case CURSOR_LOOK: + switch (_floorNumber) { + case 1: + case 2: + case 5: + case 9: + SceneItem::display2(250, 12); + break; + case 10: + SceneItem::display2(250, 13); + break; + case 11: + SceneItem::display2(250, 14); + break; + default: + SceneItem::display2(250, 16); + break; + } + return true; + + default: + return SceneActor::startAction(action, event); + } +} + +void Scene250::Button::setFloor(int floorNumber) { + SceneActor::postInit(); + _floorNumber = floorNumber; + _v2 = 0; + + if (_floorNumber <= 9) { + SceneObject::setup(250, 1, 4); + + switch (_floorNumber) { + case 1: + case 2: + case 5: + case 9: + setFrame(6); + break; + default: + break; + } + + setPosition(Common::Point(111, (_floorNumber - 1) * 12 + 43)); + fixPriority(10); + setDetails(250, -1, -1, -1, 1, NULL); + } +} + +/*--------------------------------------------------------------------------*/ + +Scene250::Scene250(): SceneExt() { + _field412 = _field414 = _field416 = _field418 = _field41A = 0; +} + +void Scene250::synchronize(Serializer &s) { + SceneExt::synchronize(s); + + s.syncAsSint16LE(_field412); + s.syncAsSint16LE(_field414); + s.syncAsSint16LE(_field416); + s.syncAsSint16LE(_field418); + s.syncAsSint16LE(_field41A); +} + +void Scene250::postInit(SceneObjectList *OwnerList) { + SceneExt::postInit(); + loadScene(250); + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.setVisage(10); + R2_GLOBALS._player.hide(); + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + + _currentFloor.setFloor(10); + _currentFloor.setup(250, 1, 5); + _currentFloor.setDetails(250, 13, -1, -1, 1, NULL); + + _button1.setFloor(11); + _button1.setup(250, 1, 3); + _button1.setPosition(Common::Point(400, 100)); + _button1.setDetails(250, 14, -1, -1, 1, NULL); + _button1.fixPriority(190); + _button1.hide(); + + _floor1.setFloor(1); + _floor2.setFloor(2); + _floor3.setFloor(3); + _floor4.setFloor(4); + _floor5.setFloor(5); + _floor6.setFloor(6); + _floor7.setFloor(7); + _floor8.setFloor(8); + _floor9.setFloor(9); + + _item2.setDetails(Rect(0, 0, 73, SCREEN_HEIGHT), 250, 9, -1, 9, 1, NULL); + _item4.setDetails(Rect(239, 16, 283, 164), 250, 6, -1, -1, 1, NULL); + _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 250, 0, 1, -1, 1, NULL); + + R2_GLOBALS._events.setCursor(CURSOR_USE); + + switch (R2_GLOBALS._sceneManager._previousScene) { + case 200: + _field412 = 55; + break; + case 300: + _field412 = 43; + break; + case 700: + _field412 = 139; + break; + case 850: + _field412 = 91; + break; + default: + R2_GLOBALS._sceneManager._previousScene = 200; + _field412 = 55; + break; + } + + _currentFloor.setPosition(Common::Point(111, _field412)); +} + +void Scene250::signal() { + if (_field41A) + _sceneMode = 20; + + switch (_sceneMode) { + case 1: + _sound1.play(22); + R2_GLOBALS._player.show(); + R2_GLOBALS._player.setup(250, 1, 2); + R2_GLOBALS._player.setPosition(Common::Point(261, 185)); + ADD_MOVER(R2_GLOBALS._player, 261, 15); + + _field416 = 0; + _sceneMode = 2; + break; + case 2: + _sceneMode = ((_field414 - 12) == _field412) ? 4 : 3; + signal(); + break; + case 3: + _currentFloor.setPosition(Common::Point(111, _currentFloor._position.y + 12)); + _field412 += 12; + R2_GLOBALS._player.setPosition(Common::Point(261, 185)); + ADD_MOVER(R2_GLOBALS._player, 261, 15); + + if ((_field414 - 12) == _field412) + _sceneMode = 4; + break; + case 4: + _sound1.play(21); + + _currentFloor.setPosition(Common::Point(111, _currentFloor._position.y + 12)); + R2_GLOBALS._player.setPosition(Common::Point(261, 185)); + ADD_MOVER(R2_GLOBALS._player, 261, 15); + _sceneMode = 5; + break; + case 5: + R2_GLOBALS._player.disableControl(); + _sceneMode = 20; + signal(); + break; + case 6: + _sound1.play(22); + R2_GLOBALS._player.show(); + R2_GLOBALS._player.setup(250, 1, 2); + R2_GLOBALS._player.setPosition(Common::Point(261, 15)); + ADD_MOVER(R2_GLOBALS._player, 261, 185); + _field416 = 0; + _sceneMode = 7; + break; + case 7: + _field418 = 1; + if ((_field414 + 12) == _field412) + _sceneMode = 8; + signal(); + break; + case 8: + _currentFloor.setPosition(Common::Point(111, _currentFloor._position.y - 12)); + _field412 -= 12; + R2_GLOBALS._player.setPosition(Common::Point(261, 15)); + ADD_MOVER(R2_GLOBALS._player, 261, 185); + + if ((_field414 + 12) == _field412) + _sceneMode = 9; + break; + case 9: + _sound1.play(21); + _currentFloor.setPosition(Common::Point(111, _currentFloor._position.y - 12)); + R2_GLOBALS._player.setPosition(Common::Point(261, 15)); + ADD_MOVER(R2_GLOBALS._player, 261, 185); + _sceneMode = 10; + break; + case 10: + _sceneMode = 20; + signal(); + break; + case 20: + // Handle changing scene + switch (_field414) { + case 55: + R2_GLOBALS._sceneManager.changeScene(200); + break; + case 43: + R2_GLOBALS._sceneManager.changeScene(300); + break; + case 139: + R2_GLOBALS._sceneManager.changeScene(139); + break; + case 91: + R2_GLOBALS._sceneManager.changeScene(850); + break; + default: + break; + } + break; + default: + break; + } +} + +void Scene250::changeFloor(int floorNumber) { + _field414 = (floorNumber - 1) * 12 + 43; + _button1.setPosition(Common::Point(111, _field414)); + _button1.show(); + + _sceneMode = (_field412 >= _field414) ? 6 : 1; + if (_field414 == _field412) + _sceneMode = 20; + + signal(); +} + +void Scene250::process(Event &event) { + if (!event.handled) { + if (((event.eventType == EVENT_KEYPRESS) || (event.btnState != 0)) && _field418) { + _field41A = 1; + event.handled = true; + } + + SceneExt::process(event); + } +} + +void Scene250::dispatch() { + SceneExt::dispatch(); + + if (((_sceneMode == 2) || (_sceneMode == 7)) && (_field416 < 100)) { + ++_field416; + R2_GLOBALS._player._moveDiff.y = _field416 / 5; + } + + if (((_sceneMode == 5) || (_sceneMode == 10)) && (R2_GLOBALS._player._moveDiff.y > 4)) { + --_field416; + R2_GLOBALS._player._moveDiff.y = _field416 / 7 + 3; + } +} + +/*-------------------------------------------------------------------------- * Scene 300 - Bridge * *--------------------------------------------------------------------------*/ @@ -1527,18 +1924,54 @@ bool Scene300::Miranda::startAction(CursorType action, Event &event) { switch (action) { case CURSOR_TALK: - if (R2_GLOBALS._player._characterIndex == 1) { - warning("TODO: talk sequence"); + if (R2_GLOBALS._player._characterIndex == R2_QUINN) { + // Quinn talking to Miranda + R2_GLOBALS._player.disableControl(); + + if (!R2_GLOBALS.getFlag(44)) { + if (R2_GLOBALS.getFlag(40)) + scene->_stripId = 119; + else if (R2_GLOBALS.getFlag(38)) + scene->_stripId = 101; + else { + R2_GLOBALS._sound1.play(69); + scene->_stripId = 100; + } + + scene->_sceneMode = 309; + scene->setAction(&scene->_sequenceManager1, scene, 309, &R2_GLOBALS._player, NULL); + } else if (!R2_GLOBALS.getFlag(55)) { + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + scene->_sceneMode = 10; + scene->_stripManager.start3(scene->_stripId, scene, R2_GLOBALS._stripManager_lookupList); + } else { + scene->_sceneMode = 16; + + if (!R2_GLOBALS.getFlag(57)) { + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + scene->_stripManager.start3(434, scene, R2_GLOBALS._stripManager_lookupList); + } else if (R2_GLOBALS._player._characterScene[R2_MIRANDA] != 500) { + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + scene->_stripManager.start3(407, scene, R2_GLOBALS._stripManager_lookupList); + } else { + scene->_stripId = 433; + scene->_sceneMode = 309; + scene->setAction(&scene->_sequenceManager1, scene, 309, &R2_GLOBALS._player, NULL); + } + } } else { + // Seeker talking to Miranda scene->_sceneMode = 10; R2_GLOBALS._events.setCursor(CURSOR_ARROW); if (!R2_GLOBALS.getFlag(44)) - scene->_field412 = 174 + R2_GLOBALS._randomSource.getRandomNumber(2); + scene->_stripId = 174 + R2_GLOBALS._randomSource.getRandomNumber(2); else if (!R2_GLOBALS.getFlag(55)) - scene->_field412 = 211; + scene->_stripId = 211; else - scene->_field412 = 438; + scene->_stripId = 438; + + scene->_stripManager.start3(scene->_stripId, scene, R2_GLOBALS._stripManager_lookupList); } return true; @@ -1546,12 +1979,12 @@ bool Scene300::Miranda::startAction(CursorType action, Event &event) { SceneItem::display2(300, 54); return true; - case R2_2: + case R2_READER: if (!R2_GLOBALS.getFlag(2) || !R2_GLOBALS.getFlag(3) || (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 1)) SceneItem::display2(300, 55); else { R2_GLOBALS._player.disableControl(); - scene->_field412 = R2_GLOBALS.getFlag(4) ? 121 : 120; + scene->_stripId = R2_GLOBALS.getFlag(4) ? 121 : 120; scene->_sceneMode = 309; scene->setAction(&scene->_sequenceManager1, scene, 309, &R2_GLOBALS._player, NULL); } @@ -1565,24 +1998,142 @@ bool Scene300::Miranda::startAction(CursorType action, Event &event) { } bool Scene300::Seeker::startAction(CursorType action, Event &event) { - return false; + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + + switch (action) { + case CURSOR_TALK: + R2_GLOBALS._player.disableControl(); + + if (R2_GLOBALS._player._characterIndex == R2_QUINN) { + if (R2_GLOBALS.getFlag(44)) { + if (!R2_GLOBALS.getFlag(38)) { + R2_GLOBALS._sound1.play(69); + scene->_stripId = 181; + scene->_sceneMode = 310; + scene->setAction(&scene->_sequenceManager1, scene, 309, &R2_GLOBALS._player, NULL); + } else { + scene->_stripId = R2_GLOBALS.getFlag(40) ? 170 : 150; + scene->_sceneMode = 310; + scene->setAction(&scene->_sequenceManager1, scene, 309, &R2_GLOBALS._player, NULL); + } + } else { + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + if (!R2_GLOBALS.getFlag(55)) { + scene->_sceneMode = 10; + scene->_stripManager.start3(205, scene, R2_GLOBALS._stripManager_lookupList); + } else { + scene->_sceneMode = 16; + scene->_stripManager.start3(R2_GLOBALS.getFlag(57) ? 407 : 401, scene, R2_GLOBALS._stripManager_lookupList); + } + } + } else { + scene->_sceneMode = 10; + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + + if (!R2_GLOBALS.getFlag(44)) + scene->_stripId = 122 + R2_GLOBALS._randomSource.getRandomNumber(2); + else if (!R2_GLOBALS.getFlag(55)) + scene->_stripId = 209; + else + scene->_stripId = 440; + + scene->_stripManager.start3(scene->_stripId, scene, R2_GLOBALS._stripManager_lookupList); + } + return true; + + case R2_OPTO_DISK: + if (R2_GLOBALS.getFlag(13)) { + SceneItem::display2(300, 53); + } else { + R2_GLOBALS._player.disableControl(); + scene->_stripId = 171; + } + + scene->_sceneMode = 310; + scene->setAction(&scene->_sequenceManager1, scene, 310, &R2_GLOBALS._player, NULL); + return true; + + case R2_READER: + if (!R2_GLOBALS.getFlag(2) || !R2_GLOBALS.getFlag(3) || (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 1)) + break; + + R2_GLOBALS._player.disableControl(); + scene->_stripId = R2_GLOBALS.getFlag(4) ? 173 : 172; + scene->_sceneMode = 310; + scene->setAction(&scene->_sequenceManager1, scene, 310, &R2_GLOBALS._player, NULL); + return true; + + default: + break; + } + + return SceneActor::startAction(action, event); } bool Scene300::Quinn::startAction(CursorType action, Event &event) { - return false; + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + + switch (action) { + case CURSOR_TALK: + R2_GLOBALS._player.disableControl(); + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + scene->_sceneMode = 10; + + if (R2_GLOBALS._player._characterIndex == R2_MIRANDA) { + if (R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500) + scene->_stripId = 442; + else if (!R2_GLOBALS.getFlag(44)) + scene->_stripId = 177 + R2_GLOBALS._randomSource.getRandomNumber(2); + else if (!R2_GLOBALS.getFlag(55)) + scene->_stripId = 208; + else + scene->_stripId = 441; + } else if (R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500) { + scene->_stripId = 442; + } else if (R2_GLOBALS.getFlag(44)) { + scene->_stripId = R2_GLOBALS.getFlag(55) ? 441 : 208; + } else { + scene->_stripId = 125 + R2_GLOBALS._randomSource.getRandomNumber(2); + } + + scene->_stripManager.start3(scene->_stripId, scene, R2_GLOBALS._stripManager_lookupList); + return true; + + default: + return SceneActor::startAction(action, event); + } +} + +bool Scene300::Doorway::startAction(CursorType action, Event &event) { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + + if (action == CURSOR_USE) { + if ((R2_GLOBALS._player._characterIndex == R2_QUINN) && + (!R2_GLOBALS.getFlag(44) || R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500)) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 301; + scene->setAction(&scene->_sequenceManager1, scene, 301, &R2_GLOBALS._player, this, NULL); + } else { + SceneItem::display2(300, 45); + } + + return true; + } else { + return SceneActor::startAction(action, event); + } } /*--------------------------------------------------------------------------*/ Scene300::Scene300(): SceneExt() { - _field412 = 0; + _stripId = 0; _rotation = NULL; } void Scene300::synchronize(Serializer &s) { SceneExt::synchronize(s); - s.syncAsSint16LE(_field412); + s.syncAsSint16LE(_stripId); SYNC_POINTER(_rotation); } @@ -1594,7 +2145,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) { if (R2_GLOBALS._sceneManager._previousScene == -1) { R2_GLOBALS._sceneManager._previousScene = 1000; - R2_GLOBALS._player._characterIndex = 1; + R2_GLOBALS._player._characterIndex = R2_QUINN; } _stripManager.setColors(60, 255); @@ -1634,7 +2185,6 @@ void Scene300::postInit(SceneObjectList *OwnerList) { _object4.postInit(); _object4.setup(300, 5, 1); _object4.setPosition(Common::Point(236, 48)); - _object4.animate(ANIM_MODE_2, NULL); _protocolDisplay.postInit(); @@ -1820,7 +2370,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) { case 1100: R2_GLOBALS._player.setVisage(10); R2_GLOBALS._player.setPosition(Common::Point(160, 95)); - _field412 = 400; + _stripId = 400; _sceneMode = 309; setAction(&_sequenceManager1, this, 309, &R2_GLOBALS._player, NULL); break; @@ -1919,7 +2469,7 @@ void Scene300::signal() { } _stripManager._field2E8 = 0; - switch (_field412) { + switch (_stripId) { case 400: R2_GLOBALS._player.disableControl(); _sceneMode = 15; @@ -2002,7 +2552,7 @@ void Scene300::signal() { break; case 20: - R2_GLOBALS._player._characterIndex = 1; + R2_GLOBALS._player._characterIndex = R2_QUINN; R2_GLOBALS._sceneManager.changeScene(1500); break; @@ -2032,7 +2582,7 @@ void Scene300::signal() { signal309(); R2_GLOBALS._events.setCursor(CURSOR_ARROW); _sceneMode = 10; - _stripManager.start3(_field412, this, R2_GLOBALS._stripManager_lookupList); + _stripManager.start3(_stripId, this, R2_GLOBALS._stripManager_lookupList); break; case 313: @@ -2079,7 +2629,7 @@ void Scene300::signal() { void Scene300::signal309() { if (R2_GLOBALS.getFlag(2)) - R2_GLOBALS._stripManager_lookupList[0] = (R2_INVENTORY.getObjectScene(R2_2) == 1) ? 3 : 2; + R2_GLOBALS._stripManager_lookupList[0] = (R2_INVENTORY.getObjectScene(R2_READER) == 1) ? 3 : 2; if (R2_GLOBALS.getFlag(4)) R2_GLOBALS._stripManager_lookupList[0] = 4; @@ -2116,6 +2666,414 @@ void Scene300::signal309() { R2_GLOBALS._stripManager_lookupList[4] = 3; } +/*-------------------------------------------------------------------------- + * Scene 400 - Science Lab + * + *--------------------------------------------------------------------------*/ + +bool Scene400::Terminal::startAction(CursorType action, Event &event) { + Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene; + + if (action == CURSOR_USE) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 402; + scene->setAction(&scene->_sequenceManager1, scene, 402, &R2_GLOBALS._player, this, NULL); + + return true; + } else { + return NamedHotspot::startAction(action, event); + } +} + +/*--------------------------------------------------------------------------*/ + +bool Scene400::Door::startAction(CursorType action, Event &event) { + Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene; + + if (action == CURSOR_USE) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 401; + scene->setAction(&scene->_sequenceManager1, scene, 401, &R2_GLOBALS._player, this, NULL); + + return true; + } else { + return SceneActor::startAction(action, event); + } +} + +bool Scene400::Reader::startAction(CursorType action, Event &event) { + Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene; + + if (action == CURSOR_USE) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 405; + scene->setAction(&scene->_sequenceManager1, scene, 405, &R2_GLOBALS._player, this, NULL); + + return true; + } else { + return SceneActor::startAction(action, event); + } +} + +bool Scene400::SensorProbe::startAction(CursorType action, Event &event) { + Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene; + + if (action == CURSOR_USE) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 404; + scene->setAction(&scene->_sequenceManager1, scene, 404, &R2_GLOBALS._player, this, NULL); + + return true; + } else { + return SceneActor::startAction(action, event); + } +} + +bool Scene400::AttractorUnit::startAction(CursorType action, Event &event) { + Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene; + + if (action == CURSOR_USE) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 406; + scene->setAction(&scene->_sequenceManager1, scene, 406, &R2_GLOBALS._player, this, NULL); + + return true; + } else { + return SceneActor::startAction(action, event); + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene400::postInit(SceneObjectList *OwnerList) { + SceneExt::postInit(); + loadScene(400); + _sound1.play(20); + + _door.postInit(); + _door.setVisage(100); + _door.setPosition(Common::Point(123, 84)); + _door.setDetails(400, 24, -1, 26, 1, NULL); + + _consoleDisplay.postInit(); + _consoleDisplay.setup(400, 4, 1); + _consoleDisplay.setPosition(Common::Point(236, 92)); + _consoleDisplay.fixPriority(120); + _consoleDisplay.animate(ANIM_MODE_2, NULL); + _consoleDisplay._numFrames = 5; + + _testerDisplay.postInit(); + _testerDisplay.setup(400, 2, 1); + _testerDisplay.setPosition(Common::Point(198, 83)); + _testerDisplay.animate(ANIM_MODE_2, NULL); + _testerDisplay._numFrames = 20; + + if (R2_INVENTORY.getObjectScene(R2_READER) == 400) { + _reader.postInit(); + _reader.setup(400, 5, 2); + _reader.setPosition(Common::Point(301, 95)); + _reader.setDetails(400, 54, -1, 56, 1, NULL); + } + + if (R2_INVENTORY.getObjectScene(R2_SENSOR_PROBE) == 400) { + _sensorProbe.postInit(); + _sensorProbe.setup(400, 5, 1); + _sensorProbe.setPosition(Common::Point(251, 104)); + _sensorProbe.fixPriority(121); + _sensorProbe.setDetails(400, 57, -1, 59, 1, NULL); + } + + if (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_UNIT) == 400) { + _attractorUnit.postInit(); + _attractorUnit.setup(400, 5, 3); + _attractorUnit.setPosition(Common::Point(265, 129)); + _attractorUnit.setDetails(400, 60, -1, 62, 1, NULL); + } + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.setVisage(10); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player.disableControl(); + + _equipment1.setDetails(11, 400, 3, -1, -1); + _equipment2.setDetails(24, 400, 3, -1, -1); + _equipment3.setDetails(25, 400, 3, -1, -1); + _equipment4.setDetails(26, 400, 3, -1, -1); + _equipment5.setDetails(28, 400, 3, -1, -1); + _equipment6.setDetails(29, 400, 3, -1, -1); + _desk.setDetails(12, 400, 6, -1, -1); + _desk2.setDetails(27, 400, 6, -1, -1); + _terminal.setDetails(13, 400, 6, -1, 11); + _duct.setDetails(14, 400, 12, -1, -1); + _console.setDetails(15, 400, 15, -1, 17); + _equalizer.setDetails(Rect(284, 99, 308, 108), 400, 36, -1, 38, 1, NULL); + _transducer.setDetails(Rect(295, 67, 314, 79), 400, 39, -1, 41, 1, NULL); + _optimizer.setDetails(Rect(308, 106, 315, 113), 400, 42, -1, 44, 1, NULL); + _soundModule.setDetails(Rect(291, 118, 315, 131), 400, 45, -1, 47, 1, NULL); + _tester.setDetails(Rect(179, 62, 217, 92), 400, 30, -1, 32, 1, NULL); + _helmet.setDetails(Rect(181, 53, 197, 65), 400, 48, -1, 50, 1, NULL); + _nullifier.setDetails(Rect(201, 56, 212, 65), 400, 51, -1, 50, 1, NULL); + _shelves.setDetails(16, 400, 18, -1, 20); + _cabinet.setDetails(17, 400, 21, -1, -1); + _doorDisplay.setDetails(Rect(161, 43, 166, 52), 400, 27, -1, -1, 1, NULL); + _lights.setDetails(Rect(113, 3, 168, 14), 400, 33, -1, -1, 1, NULL); + _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 400, 0, 1, -1, 1, NULL); + + _sceneMode = 400; + switch (R2_GLOBALS._sceneManager._previousScene) { + case 125: + setAction(&_sequenceManager1, this, 403, &R2_GLOBALS._player, NULL); + break; + case 200: + setAction(&_sequenceManager1, this, 400, &R2_GLOBALS._player, &_door, NULL); + break; + default: + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.setPosition(Common::Point(180, 100)); + R2_GLOBALS._player.enableControl(); + break; + } +} + +void Scene400::remove() { + R2_GLOBALS._sound1.fadeOut2(NULL); + SceneExt::remove(); +} + +void Scene400::signal() { + switch (_sceneMode) { + case 400: + case 403: + R2_GLOBALS._player.enableControl(); + break; + case 401: + R2_GLOBALS._sceneManager.changeScene(200); + break; + case 402: + R2_GLOBALS._sceneManager.changeScene(125); + break; + case 404: + // Getting the sensor probe + R2_INVENTORY.setObjectScene(R2_SENSOR_PROBE, 1); + _sensorProbe.remove(); + R2_GLOBALS._player.enableControl(); + break; + case 405: + // Getting the reader + R2_INVENTORY.setObjectScene(R2_READER, 1); + _reader.remove(); + R2_GLOBALS._player.enableControl(); + break; + case 406: + R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 1); + _attractorUnit.remove(); + R2_GLOBALS._player.enableControl(); + break; + default: + break; + } +} + +void Scene400::dispatch() { + SceneExt::dispatch(); + + switch (R2_GLOBALS._player.getRegionIndex() - 15) { + case 0: + case 11: + case 12: + R2_GLOBALS._player._shade = 2; + break; + case 9: + R2_GLOBALS._player._shade = 0; + break; + case 10: + R2_GLOBALS._player._shade = 1; + break; + case 13: + R2_GLOBALS._player._shade = 3; + break; + case 14: + R2_GLOBALS._player._shade = 4; + break; + default: + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 850 - Deck #5 - By Lift + * + *--------------------------------------------------------------------------*/ + +bool Scene850::Indicator::startAction(CursorType action, Event &event) { + Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene; + + if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) != 850)) + return NamedHotspot::startAction(action, event); + else { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 851; + scene->setAction(&scene->_sequenceManager1, scene, 851, &R2_GLOBALS._player, &scene->_fibre, NULL); + return true; + } +} + +/*--------------------------------------------------------------------------*/ + +bool Scene850::LiftDoor::startAction(CursorType action, Event &event) { + Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene; + + if (action != CURSOR_USE) + return SceneActor::startAction(action, event); + else { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 202; + scene->setAction(&scene->_sequenceManager1, scene, 202, &R2_GLOBALS._player, this, NULL); + return true; + } +} + +bool Scene850::SickBayDoor::startAction(CursorType action, Event &event) { + Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene; + + if (action != CURSOR_USE) + return SceneActor::startAction(action, event); + else { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 204; + scene->setAction(&scene->_sequenceManager1, scene, 204, &R2_GLOBALS._player, this, NULL); + return true; + } +} + +bool Scene850::Clamp::startAction(CursorType action, Event &event) { + Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene; + + if (!R2_GLOBALS.getFlag(7)) + return false; + else if (action != CURSOR_USE) + return SceneActor::startAction(action, event); + else { + R2_GLOBALS._player.disableControl(); + scene->_object1.postInit(); + scene->_sceneMode = 850; + scene->setAction(&scene->_sequenceManager1, scene, 850, &R2_GLOBALS._player, this, &scene->_object1, NULL); + return true; + } +} + +bool Scene850::Panel::startAction(CursorType action, Event &event) { + Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene; + + if ((action != CURSOR_USE) || R2_GLOBALS.getFlag(7)) + return SceneActor::startAction(action, event); + else { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 852; + scene->setAction(&scene->_sequenceManager1, scene, 852, &R2_GLOBALS._player, this, &scene->_object1, NULL); + return true; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene850::postInit(SceneObjectList *OwnerList) { + SceneExt::postInit(); + loadScene(850); + + _liftDoor.postInit(); + _liftDoor.setup(850, 2, 1); + _liftDoor.setPosition(Common::Point(188, 79)); + _liftDoor.setDetails(850, 3, -1, -1, 1, NULL); + + _sickBayDoor.postInit(); + _sickBayDoor.setup(850, 3, 1); + _sickBayDoor.setPosition(Common::Point(62, 84)); + _sickBayDoor.setDetails(850, 9, -1, -1, 1, NULL); + + if (R2_INVENTORY.getObjectScene(R2_CLAMP) == 850) { + _clamp.postInit(); + _clamp.setup(850, 5, 1); + _clamp.setPosition(Common::Point(242, 93)); + _clamp.fixPriority(81); + _clamp.animate(ANIM_MODE_2, NULL); + _clamp.setDetails(850, 27, -1, -1, 1, NULL); + } + + _panel.postInit(); + _panel.setVisage(850); + + if (R2_GLOBALS.getFlag(7)) + _panel.setFrame(7); + + _panel.setPosition(Common::Point(232, 119)); + _panel.fixPriority(82); + _panel.setDetails(850, 24, -1, -1, 1, NULL); + + if (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) == 850) { + _fibre.postInit(); + _fibre.setup(850, 6, 1); + _fibre.setPosition(Common::Point(280, 87)); + } + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.setVisage(10); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player.disableControl(); + + _eastDoor.setDetails(Rect(289, 53, 315, 125), 850, 6, -1, 8, 1, NULL); + _indicator.setDetails(Rect(275, 67, 286, 79), 850, 18, -1, 20, 1, NULL); + _sickBayIndicator.setDetails(Rect(41, 51, 48, 61), 850, 15, -1, -1, 1, NULL); + _liftControls.setDetails(Rect(156, 32, 166, 44), 850, 21, -1, -1, 1, NULL); + _compartment.setDetails(Rect(4, 88, 153, 167), 850, 12, -1, -1, 1, NULL); + _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 850, 0, -1, -1, 1, NULL); + + switch (R2_GLOBALS._sceneManager._previousScene) { + case 250: + _sceneMode = 203; + setAction(&_sequenceManager1, this, 203, &R2_GLOBALS._player, &_liftDoor, NULL); + break; + case 800: + _sceneMode = 205; + setAction(&_sequenceManager1, this, 205, &R2_GLOBALS._player, &_sickBayDoor, NULL); + break; + default: + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.setPosition(Common::Point(215, 115)); + R2_GLOBALS._player.enableControl(); + break; + } +} + +void Scene850::signal() { + switch (_sceneMode) { + case 202: + R2_GLOBALS._sceneManager.changeScene(250); + break; + case 204: + R2_GLOBALS._sceneManager.changeScene(800); + break; + case 850: + R2_INVENTORY.setObjectScene(R2_CLAMP, 1); + _clamp.remove(); + _object1.remove(); + R2_GLOBALS._player.enableControl(); + break; + case 851: + R2_INVENTORY.setObjectScene(R2_OPTICAL_FIBRE, 1); + _fibre.remove(); + R2_GLOBALS._player.enableControl(); + break; + case 852: + R2_GLOBALS.setFlag(7); + R2_GLOBALS._player.enableControl(); + break; + default: + R2_GLOBALS._player.enableControl(); + break; + } +} + } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.h b/engines/tsage/ringworld2/ringworld2_scenes0.h index 4d2c454c4e..5f2d768f90 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes0.h +++ b/engines/tsage/ringworld2/ringworld2_scenes0.h @@ -67,7 +67,7 @@ class Scene100: public SceneExt { public: bool startAction(CursorType action, Event &event); }; - class Object10: public SceneActorExt { + class DoorDisplay: public SceneActorExt { public: bool startAction(CursorType action, Event &event); }; @@ -85,12 +85,12 @@ class Scene100: public SceneExt { public: NamedHotspot _background, _duct, _bed, _desk; Terminal _terminal; - SceneActor _object1, _object2, _object3, _object4, _object5; - SceneActor _object6; + SceneActor _bedLights1, _bedLights2, _object3, _object4, _object5; + SceneActor _wardrobe; Door _door; Table _table; StasisNegator _stasisNegator; - Object10 _object10; + DoorDisplay _doorDisplay; SteppingDisks _steppingDisks; SequenceManager _sequenceManager1, _sequenceManager2; @@ -157,6 +157,18 @@ public: Common::String parseMessage(const Common::String &msg); }; +class Scene150: public Scene100 { +public: + SceneActor _emptyRoomTable; +public: + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void signal(); +}; + +class Scene175: public Scene150 { +}; + class Scene200: public SceneExt { /* Objects */ class NorthDoor: public SceneActor { @@ -194,6 +206,35 @@ public: virtual void signal(); }; +class Scene250: public SceneExt { + class Button: public SceneActor { + public: + int _floorNumber, _v2; + Button(); + void setFloor(int floorNumber); + + virtual void synchronize(Serializer &s); + virtual bool startAction(CursorType action, Event &event); + }; +public: + int _field412, _field414, _field416, _field418, _field41A; + NamedHotspot _background, _item2, _item3, _item4; + Button _button1, _currentFloor; + Button _floor1, _floor2, _floor3, _floor4, _floor5; + Button _floor6, _floor7, _floor8, _floor9; + ASoundExt _sound1; + SequenceManager _sequenceManager1; +public: + Scene250(); + void changeFloor(int floorNumber); + + virtual void synchronize(Serializer &s); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void process(Event &event); + virtual void dispatch(); +}; + class Scene300: public SceneExt { /* Actions */ class Action1: public Action { @@ -240,6 +281,10 @@ class Scene300: public SceneExt { public: virtual bool startAction(CursorType action, Event &event); }; + class Doorway: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; public: SequenceManager _sequenceManager1, _sequenceManager2, _sequenceManager3, _sequenceManager4; ASoundExt _sound1; @@ -258,7 +303,8 @@ public: MirandaWorkstation _mirandaWorkstation1, _mirandaWorkstation2; SceneActor _object1, _object2, _object3, _object4, _protocolDisplay; SceneActor _object6, _object7, _object8, _object9; - SceneActor _teal, _soldier, _object12, _doorway; + SceneActor _teal, _soldier, _object12; + Doorway _doorway; Miranda _miranda; Seeker _seeker; Quinn _quinn; @@ -267,7 +313,7 @@ public: Action3 _action3; Action4 _action4; PaletteRotation *_rotation; - int _field412; + int _stripId; Scene300(); void signal309(); @@ -278,6 +324,91 @@ public: virtual void signal(); }; +class Scene400: public SceneExt { + /* Items */ + class Terminal: public NamedHotspot { + public: + virtual bool startAction(CursorType action, Event &event); + }; + + /* Objects */ + class Door: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; + class Reader: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; + class SensorProbe: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; + class AttractorUnit: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; +public: + NamedHotspot _background, _equipment1, _equipment2, _equipment3; + NamedHotspot _equipment4, _equipment5, _equipment6; + NamedHotspot _desk, _desk2, _console; + NamedHotspot _duct, _shelves, _cabinet, _doorDisplay, _lights; + NamedHotspot _equalizer, _transducer, _optimizer, _soundModule, _tester; + NamedHotspot _helmet, _nullifier; + Terminal _terminal; + SceneActor _consoleDisplay, _testerDisplay; + Door _door; + Reader _reader; + SensorProbe _sensorProbe; + AttractorUnit _attractorUnit; + SequenceManager _sequenceManager1; + ASoundExt _sound1; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene850: public SceneExt { + /* Items */ + class Indicator: public NamedHotspot { + public: + virtual bool startAction(CursorType action, Event &event); + }; + + /* Objects */ + class LiftDoor: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; + class SickBayDoor: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; + class Clamp: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; + class Panel: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; +public: + NamedHotspot _background, _eastDoor, _compartment, _sickBayIndicator; + NamedHotspot _liftControls; + Indicator _indicator; + SceneActor _object1, _fibre; + LiftDoor _liftDoor; + SickBayDoor _sickBayDoor; + Clamp _clamp; + Panel _panel; + SequenceManager _sequenceManager1; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.cpp b/engines/tsage/ringworld2/ringworld2_scenes2.cpp index 46c6261413..b851ed4e22 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes2.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes2.cpp @@ -30,7 +30,7 @@ namespace TsAGE { namespace Ringworld2 { /*-------------------------------------------------------------------------- - * Scene 2000 - Maze + * Scene 2000 - Ice Maze * *--------------------------------------------------------------------------*/ void Scene2000::initPlayer() { @@ -1047,7 +1047,7 @@ void Scene2000::synchronize(Serializer &s) { * *--------------------------------------------------------------------------*/ bool Scene2350::Actor2::startAction(CursorType action, Event &event) { - if (action != R2_6) + if (action != R2_SENSOR_PROBE) return(SceneActor::startAction(action, event)); return true; } @@ -1222,7 +1222,7 @@ void Scene2350::process(Event &event) { } /*-------------------------------------------------------------------------- - * Scene 2400 - Maze: Large empty room + * Scene 2400 - Ice Maze: Large empty room * *--------------------------------------------------------------------------*/ void Scene2400::Exit1::changeScene() { @@ -1284,7 +1284,7 @@ void Scene2400::signal() { } /*-------------------------------------------------------------------------- - * Scene 2425 - Maze: + * Scene 2425 - Ice Maze: * *--------------------------------------------------------------------------*/ @@ -1300,9 +1300,9 @@ bool Scene2425::Item1::startAction(CursorType action, Event &event) { } else if (action == R2_37) { R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS); R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS); - return startAction(R2_STEPPING_DISKS, event); + return NamedHotspot::startAction(R2_STEPPING_DISKS, event); } else - return startAction(action, event); + return NamedHotspot::startAction(action, event); } bool Scene2425::Item2::startAction(CursorType action, Event &event) { @@ -1317,16 +1317,16 @@ bool Scene2425::Item2::startAction(CursorType action, Event &event) { } else if (action == R2_37) { R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS); R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS); - return startAction(R2_STEPPING_DISKS, event); + return NamedHotspot::startAction(R2_STEPPING_DISKS, event); } else - return startAction(action, event); + return NamedHotspot::startAction(action, event); } bool Scene2425::Item3::startAction(CursorType action, Event &event) { Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene; if (action != R2_37) - return startAction(action, event); + return NamedHotspot::startAction(action, event); else { R2_GLOBALS._player.disableControl(); if (R2_GLOBALS.getFlag(84)) { @@ -1343,11 +1343,11 @@ bool Scene2425::Item3::startAction(CursorType action, Event &event) { bool Scene2425::Item4::startAction(CursorType action, Event &event) { if (action != R2_37) - return startAction(action, event); + return NamedHotspot::startAction(action, event); else { R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS); R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS); - return startAction(R2_STEPPING_DISKS, event); + return NamedHotspot::startAction(R2_STEPPING_DISKS, event); } } @@ -1357,21 +1357,21 @@ bool Scene2425::Actor1::startAction(CursorType action, Event &event) { R2_GLOBALS._events.setCursor(R2_37); return true; } else { - return startAction(action, event); + return SceneActor::startAction(action, event); } } else if (R2_GLOBALS._events.getCursor() == R2_37) return false; else - return startAction(action, event); + return SceneActor::startAction(action, event); } bool Scene2425::Actor2::startAction(CursorType action, Event &event) { if (action != R2_37) - return startAction(action, event); + return SceneActor::startAction(action, event); else { R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS); R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS); - return startAction(R2_STEPPING_DISKS, event); + return SceneActor::startAction(R2_STEPPING_DISKS, event); } } @@ -1393,7 +1393,7 @@ void Scene2425::postInit(SceneObjectList *OwnerList) { loadScene(2425); SceneExt::postInit(); if (R2_GLOBALS._sceneManager._previousScene == -1) { - R2_GLOBALS._player._characterIndex = 2; + R2_GLOBALS._player._characterIndex = R2_SEEKER; R2_GLOBALS._sceneManager._previousScene = 2000; } @@ -1441,7 +1441,7 @@ void Scene2425::postInit(SceneObjectList *OwnerList) { _actor3._lookLineNum = 3; _actor3._talkLineNum = -1; _actor3._useLineNum = 6; - g_globals->_sceneItems.addItems(&_actor3, this); + g_globals->_sceneItems.push_back(&_actor3); _item3.setDetails(12, 2425, 7, -1, 9); _item4.setDetails(Rect(0, 0, 320, 200), 2425, 0, -1, -1, 1, NULL); @@ -1498,5 +1498,3052 @@ void Scene2425::signal() { } } +/*-------------------------------------------------------------------------- + * Scene 2430 - Ice Maze: Bedroom + * + *--------------------------------------------------------------------------*/ + +bool Scene2430::Actor1::startAction(CursorType action, Event &event) { + return SceneActor::startAction(action, event); +} + +bool Scene2430::Actor2::startAction(CursorType action, Event &event) { + Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene; + + if ((action != R2_STEPPING_DISKS) || (R2_GLOBALS._player._characterIndex != 2)) + return SceneActor::startAction(action, event); + + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2430; + scene->setAction(&scene->_sequenceManager, scene, 2430, &R2_GLOBALS._player, &scene->_actor2, NULL); + return true; +} + +bool Scene2430::Actor3::startAction(CursorType action, Event &event) { + Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene; + + if ((action != R2_STEPPING_DISKS) || (R2_GLOBALS._player._characterIndex != 2)) + return SceneActor::startAction(action, event); + + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2435; + scene->setAction(&scene->_sequenceManager, scene, 2435, &R2_GLOBALS._player, &scene->_actor3, NULL); + return true; +} + +void Scene2430::Exit1::changeScene() { + Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene; + + scene->_sceneMode = 0; + R2_GLOBALS._events.setCursor(R2_NEGATOR_GUN); + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 11; + Common::Point pt(108, 200); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); +} + +void Scene2430::postInit(SceneObjectList *OwnerList) { + loadScene(2430); + SceneExt::postInit(); + _exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000); + _exit1.setDest(Common::Point(108, 160)); + + if (R2_INVENTORY.getObjectScene(37) == 2430) { + _actor2.postInit(); + _actor2.setup(2435, 1, 5); + _actor2.setPosition(Common::Point(205, 119)); + _actor2.fixPriority(152); + _actor2.setDetails(2430, 51, -1, 53, 1, NULL); + } + + if (R2_INVENTORY.getObjectScene(50) == 2435) { + _actor3.postInit(); + _actor3.setup(2435, 1, 1); + _actor3.setPosition(Common::Point(31, 65)); + _actor3.setDetails(2430, 48, -1, -1, 1, NULL); + } + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + if (R2_GLOBALS._player._characterIndex == 1) { + R2_GLOBALS._player.setVisage(2008); + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + } else { + R2_GLOBALS._player.setVisage(20); + R2_GLOBALS._player._moveDiff = Common::Point(5, 3); + } + R2_GLOBALS._player.setPosition(Common::Point(100, 200)); + + if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) { + _actor1.postInit(); + if (R2_GLOBALS._player._characterIndex == 1) { + _actor1.setup(20, 5, 1); + _actor1.setDetails(9002, 0, 4, 3, 1, NULL); + } else { + _actor1.setup(2008, 5, 1); + _actor1.setDetails(9001, 0, 5, 3, 1, NULL); + } + _actor1.setPosition(Common::Point(189, 137)); + R2_GLOBALS._walkRegions.enableRegion(4); + } + + _item2.setDetails(Rect(11, 30, 37, 45), 2430, 3, -1, 5, 1, NULL); + _item3.setDetails(Rect(9, 58, 63, 92), 2430, 6, -1, -1, 1, NULL); + _item4.setDetails(Rect(20, 89, 127, 107), 2430, 9, -1, 11, 1, NULL); + _item5.setDetails(Rect(49, 7, 60, 27), 2430, 12, 13, 14, 1, NULL); + _item6.setDetails(Rect(69, 10, 95, 72), 2430, 15, -1, 14, 1, NULL); + _item10.setDetails(Rect(198, 4, 222, 146), 2430, 30, 31, 32, 1, NULL); + _item7.setDetails(Rect(155, 40, 304, 120), 2430, 21, -1, 23, 1, NULL); + _item8.setDetails(Rect(249, 3, 261, 39), 2430, 24, 25, -1, 1, NULL); + _item9.setDetails(Rect(279, 13, 305, 34), 2430, 33, -1, 18, 1, NULL); + // CHECKME: initialized for the 2nd time?? + _item2.setDetails(Rect(11, 30, 37, 45), 2430, 33, -1, 18, 1, NULL); + _item11.setDetails(Rect(116, 104, 148, 111), 2430, 39, -1, -1, 1, NULL); + _item12.setDetails(Rect(66, 77, 84, 83), 2430, 39, -1, -1, 1, NULL); + _item13.setDetails(Rect(117, 118, 201, 141), 2430, 9, -1, 11, 1, NULL); + _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL); + + if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) { + R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2430; + Common::Point pt(108, 150); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else { + R2_GLOBALS._player.setPosition(Common::Point(105, 145)); + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.enableControl(); + } +} + +void Scene2430::signal() { + switch (_sceneMode) { + case 11: + g_globals->_sceneManager.changeScene(2000); + break; + case 2430: + _actor2.remove(); + R2_INVENTORY.setObjectScene(R2_37, 2); + R2_GLOBALS._player.enableControl(); + break; + case 2435: + _actor3.remove(); + R2_INVENTORY.setObjectScene(R2_50, 2); + R2_GLOBALS._player.enableControl(); + break; + default: + R2_GLOBALS._player.enableControl(); + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2435 - Ice Maze: Throne room + * + *--------------------------------------------------------------------------*/ +bool Scene2435::Actor1::startAction(CursorType action, Event &event) { + return SceneActor::startAction(action, event); +} + +bool Scene2435::Actor2::startAction(CursorType action, Event &event) { + Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene; + + switch (action) { + case R2_34: + R2_GLOBALS._player.disableControl(); + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + R2_GLOBALS.setFlag(82); + scene->_stripManager.start(603, scene); + return true; + case R2_35: + R2_GLOBALS._player.disableControl(); + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + R2_GLOBALS.setFlag(82); + scene->_stripManager.start(602, scene); + R2_INVENTORY.setObjectScene(R2_35, 2000); + return true; + case CURSOR_TALK: + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 20; + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + if ((R2_GLOBALS._player._characterIndex == 1) || (R2_GLOBALS.getFlag(82))) { + scene->_stripManager.start(605, scene); + return true; + } else if (R2_INVENTORY.getObjectScene(R2_35) == 2) { + scene->_stripManager.start(601, scene); + return true; + } else { + R2_GLOBALS.setFlag(82); + scene->_stripManager.start(600, scene); + return true; + } + default: + return SceneActor::startAction(action, event); + } +} + +void Scene2435::Exit1::changeScene() { + Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene; + + _enabled = false; + R2_GLOBALS._events.setCursor(R2_NEGATOR_GUN); + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 11; + Common::Point pt(175, 200); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + +} + +void Scene2435::postInit(SceneObjectList *OwnerList) { + loadScene(2435); + SceneExt::postInit(); + R2_GLOBALS._sound1.play(201); + _stripManager.addSpeaker(&_quinnSpeaker); + _stripManager.addSpeaker(&_seekerSpeaker); + _stripManager.addSpeaker(&_pharishaSpeaker); + _exit1.setDetails(Rect(142, 155, 207, 167), EXITCURSOR_S, 2000); + _exit1.setDest(Common::Point(175, 160)); + _actor2.postInit(); + _actor2.setup(2005, 3, 1); + _actor2.setPosition(Common::Point(219, 106)); + _actor2.setDetails(2001, 25, 26, -1, 1, NULL); + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + if (R2_GLOBALS._player._characterIndex == 1) { + R2_GLOBALS._player.setVisage(2008); + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + } else { + R2_GLOBALS._player.setVisage(20); + R2_GLOBALS._player._moveDiff = Common::Point(5, 3); + } + R2_GLOBALS._player.setPosition(Common::Point(715, 200)); + if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) { + _actor1.postInit(); + if (R2_GLOBALS._player._characterIndex == 1) { + _actor1.setup(20, 5, 1); + _actor1.setDetails(9002, 0, 4, 3, 1, NULL); + } else { + _actor1.setup(2008, 5, 1); + _actor1.setDetails(9001, 0, 5, 3, 1, NULL); + } + _actor1.setPosition(Common::Point(107, 145)); + R2_GLOBALS._walkRegions.enableRegion(2); + } + + _item2.setDetails(Rect(52, 44, 96, 82), 2430, 3, -1, 5, 1, NULL); + _item3.setDetails(Rect(117, 36, 161, 74), 2430, 3, -1, 5, 1, NULL); + _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL); + R2_GLOBALS._player.disableControl(); + if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) { + _sceneMode = 10; + Common::Point pt(175, 150); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2450) { + _sceneMode = 30; + Common::Point pt(175, 150); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else { + R2_GLOBALS._player.setPosition(Common::Point(210, 150)); + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.enableControl(); + } + R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2435; + R2_GLOBALS._v56605[1 + R2_GLOBALS._player._characterIndex] = 12; +} + +void Scene2435::remove() { + R2_GLOBALS._sound1.fadeOut2(NULL); + SceneExt::remove(); +} + +void Scene2435::signal() { + switch (_sceneMode) { + case 11: + g_globals->_sceneManager.changeScene(2000); + break; + case 20: + R2_GLOBALS._player.enableControl(CURSOR_TALK); + break; + case 30: + R2_GLOBALS._player._characterScene[1] = 2435; + R2_GLOBALS._player._characterScene[2] = 2435; + R2_GLOBALS._player._oldCharacterScene[1] = 2435; + R2_GLOBALS._player._oldCharacterScene[2] = 2435; + R2_GLOBALS._v56605[1] = 12; + R2_GLOBALS._v56605[2] = 12; + R2_GLOBALS.setFlag(81); + _sceneMode = 2436; + R2_GLOBALS._player.setStrip(7); + _actor1.postInit(); + if (R2_GLOBALS._player._characterIndex == 1) + _actor1.setVisage(20); + else + _actor1.setVisage(2008); + setAction(&_sequenceManager, this, 2436, &_actor1, NULL); + break; + case 2436: + R2_GLOBALS._walkRegions.enableRegion(2); + _sceneMode = 20; + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + _stripManager.start(709, this); + default: + R2_GLOBALS._player.enableControl(); + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2440 - Ice Maze: Another bedroom + * + *--------------------------------------------------------------------------*/ + +bool Scene2440::Actor1::startAction(CursorType action, Event &event) { + return SceneActor::startAction(action, event); +} + +bool Scene2440::Actor2::startAction(CursorType action, Event &event) { + Scene2440 *scene = (Scene2440 *)R2_GLOBALS._sceneManager._scene; + + if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == 2)){ + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2440; + scene->setAction(&scene->_sequenceManager, scene, 2440, &R2_GLOBALS._player, &scene->_actor2, NULL); + return true; + } + + return SceneActor::startAction(action, event); +} + +void Scene2440::Exit1::changeScene() { + Scene2440 *scene = (Scene2440 *)R2_GLOBALS._sceneManager._scene; + + _enabled = false; + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 11; + Common::Point pt(210, 200); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); +} + +void Scene2440::postInit(SceneObjectList *OwnerList) { + loadScene(2440); + SceneExt::postInit(); + R2_GLOBALS._sound1.play(200); + // Fix exit cursor, the original was using NW + _exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_SE, 2000); + _exit1.setDest(Common::Point(210, 160)); + if (R2_INVENTORY.getObjectScene(49) == 2440) { + _actor2.postInit(); + _actor2.setup(2435, 1, 1); + _actor2.setPosition(Common::Point(94, 80)); + _actor2.fixPriority(106); + _actor2.setDetails(2430, 48, -1, -1, 1, NULL); + } + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + + if (R2_GLOBALS._player._characterIndex == 1) { + R2_GLOBALS._player.setVisage(2008); + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + } else { + R2_GLOBALS._player.setVisage(20); + R2_GLOBALS._player._moveDiff = Common::Point(5, 3); + } + R2_GLOBALS._player.setPosition(Common::Point(210, 200)); + if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) { + _actor1.postInit(); + if (R2_GLOBALS._player._characterIndex == 1) { + _actor1.setup(20, 5, 1); + _actor1.setDetails(9002, 0, 4, 3, 1, NULL); + } else { + _actor1.setup(2008, 5, 1); + _actor1.setDetails(9002, 0, 5, 3, 1, NULL); + } + _actor1.setPosition(Common::Point(38, 119)); + } + + _item2.setDetails(Rect(125, 25, 142, 73), 2430, 15, -1, 14, 1, NULL); + _item3.setDetails(Rect(124, 78, 237, 120), 2430, 36, -1, 38, 1, NULL); + _item4.setDetails(Rect(250, 3, 265, 133), 2430, 30, 31, 32, 1, NULL); + _item5.setDetails(Rect(91, 117, 203, 140), 2430, 9, -1, 11, 1, NULL); + _item6.setDetails(Rect(48, 78, 103, 112), 2430, 6, -1, -1, 1, NULL); + _item7.setDetails(Rect(48, 31, 73, 52), 2430, 33, -1, 18, 1, NULL); + _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL); + + R2_GLOBALS._player.disableControl(); + + if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) { + R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2440; + Common::Point pt(210, 150); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else { + R2_GLOBALS._player.setPosition(Common::Point(210, 150)); + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.enableControl(); + } +} + +void Scene2440::remove() { + R2_GLOBALS._sound1.fadeOut2(NULL); + SceneExt::remove(); +} + +void Scene2440::signal() { + switch (_sceneMode) { + case 11: + g_globals->_sceneManager.changeScene(2000); + break; + case 2440: + _actor2.remove(); + R2_INVENTORY.setObjectScene(49, 2); + // No break on purpose + default: + R2_GLOBALS._player.enableControl(); + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2445 - Ice Maze: + * + *--------------------------------------------------------------------------*/ +void Scene2445::postInit(SceneObjectList *OwnerList) { + loadScene(2445); + SceneExt::postInit(); + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player.setVisage(10); + R2_GLOBALS._player.setPosition(Common::Point(160, 140)); + R2_GLOBALS._player.disableControl(); +} + +void Scene2445::signal() { + R2_GLOBALS._player.enableControl(); +} + +/*-------------------------------------------------------------------------- + * Scene 2450 - Ice Maze: Another bedroom + * + *--------------------------------------------------------------------------*/ + +bool Scene2450::Actor2::startAction(CursorType action, Event &event) { + Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene; + + if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == 1)) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2452; + scene->setAction(&scene->_sequenceManager, scene, 2452, &R2_GLOBALS._player, &scene->_actor2, NULL); + return true; + } + return SceneActor::startAction(action, event); +} + +bool Scene2450::Actor3::startAction(CursorType action, Event &event) { + Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene; + + if (action == CURSOR_TALK) { + R2_GLOBALS._player.disableControl(); + if (R2_GLOBALS._v565AE < 3) { + ++R2_GLOBALS._v565AE; + scene->_sceneMode = 20; + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + if (R2_GLOBALS._player._characterIndex == 1) + scene->_stripManager.start(699 + (R2_GLOBALS._v565AE * 2), scene); + else + scene->_stripManager.start(700 + (R2_GLOBALS._v565AE * 2), scene); + } + return true;} else { + return SceneActor::startAction(action, event); + } +} + +void Scene2450::Exit1::changeScene() { + Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene; + + if ((R2_GLOBALS._player._characterIndex == 2) || (R2_GLOBALS.getFlag(61))) { + _enabled = false; + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 10; + Common::Point pt(-10, 180); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + } else { + _moving = false; + SceneItem::display(2450, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); + Common::Point pt(60, 140); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, NULL); + } +} + +void Scene2450::postInit(SceneObjectList *OwnerList) { + loadScene(2450); + SceneExt::postInit(); + R2_GLOBALS._sound1.play(200); + if (R2_GLOBALS._sceneManager._previousScene == -1) { + R2_GLOBALS._sceneManager._previousScene = 1900; + R2_GLOBALS._player._oldCharacterScene[1] = 1900; + R2_GLOBALS._player._oldCharacterScene[2] = 1900; + } + _stripManager.addSpeaker(&_quinnSpeaker); + _stripManager.addSpeaker(&_seekerSpeaker); + _stripManager.addSpeaker(&_caretakerSpeaker); + + if (R2_GLOBALS.getFlag(72)) { + _exit1.setDetails(Rect(0, 143, 47, 168), EXITCURSOR_SW, 2000); + _exit1.setDest(Common::Point(10, 160)); + } + + if (!R2_GLOBALS.getFlag(61)) { + _actor2.postInit(); + _actor2.setVisage(2009); + _actor2.setPosition(Common::Point(190, 119)); + _actor2.fixPriority(50); + _actor2.setDetails(2450, 0, -1, -1, 1, NULL); + } + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.disableControl(); + switch (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) { + case 1900: + R2_GLOBALS._v565AE = 0; + R2_GLOBALS._player._characterScene[1] = 2450; + R2_GLOBALS._player._characterScene[2] = 2450; + R2_GLOBALS._player._oldCharacterScene[1] = 2450; + R2_GLOBALS._player._oldCharacterScene[2] = 2450; + R2_GLOBALS._player.setup(2450, 1, 1); + R2_GLOBALS._player.setPosition(Common::Point(126, 101)); + setAction(&_sequenceManager, this, 2450, &R2_GLOBALS._player, NULL); + break; + case 2000: + _sceneMode = 2451; + if (R2_GLOBALS._player._characterIndex == 1) { + if (R2_GLOBALS._player._characterScene[2] == 2450) { + _actor1.postInit(); + _actor1.setup(20, 6, 1); + _actor1.setPosition(Common::Point(240, 120)); + _actor1.setDetails(9002, 0, 4, 3, 1, NULL); + } + setAction(&_sequenceManager, this, 2451, &R2_GLOBALS._player, NULL); + } else { + R2_GLOBALS._player._oldCharacterScene[2] = 2450; + R2_GLOBALS._player._characterScene[2] = 2450; + if (R2_GLOBALS._player._characterScene[1] == 2450) { + _actor1.postInit(); + if (R2_GLOBALS.getFlag(61)) + _actor1.setup(2008, 6, 1); + else + _actor1.setup(10, 6, 1); + _actor1.setDetails(9001, 0, 5, 3, 1, NULL); + _actor1.setPosition(Common::Point(106, 111)); + } + setAction(&_sequenceManager, this, 2456, &R2_GLOBALS._player, NULL); + } + break; + case 2450: + if (R2_GLOBALS._player._characterIndex == 1) { + R2_GLOBALS._player.postInit(); + if (R2_GLOBALS.getFlag(61)) { + R2_GLOBALS._player.setup(2008, 6, 1); + } else { + R2_GLOBALS._player.setup(10, 6, 1); + } + R2_GLOBALS._player.setPosition(Common::Point(106, 111)); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + if (R2_GLOBALS.getFlag(72)) { + if (R2_GLOBALS._player._characterScene[2] == 2450) { + _actor1.postInit(); + _actor1.setup(20, 6, 1); + _actor1.setPosition(Common::Point(240, 120)); + _actor1.setDetails(9002, 0, 4, 3, 1, NULL); + } + } else { + _actor1.postInit(); + _actor1.setup(20, 8, 1); + _actor1.setPosition(Common::Point(93, 158)); + _actor1.setDetails(9002, 0, 4, 3, 1, NULL); + + _actor3.postInit(); + _actor3.setup(2001, 7, 1); + _actor3.setPosition(Common::Point(34, 153)); + _actor3.setDetails(2001, 40, -1, -1, 1, NULL); + + _exit1._enabled = false; + } + } else { + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.setup(20, 8, 1); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player.setPosition(Common::Point(93, 158)); + if (R2_GLOBALS.getFlag(72)) { + if (R2_GLOBALS._player._characterScene[1] == 2450) { + _actor1.postInit(); + if (R2_GLOBALS.getFlag(61)) { + _actor1.setup(2008, 6, 1); + } else { + _actor1.setup(10, 6, 1); + } + _actor1.setPosition(Common::Point(106, 111)); + _actor1.setDetails(9001, 0, 5, 3, 1, NULL); + } + } else { + _actor1.postInit(); + if (R2_GLOBALS.getFlag(61)) { + _actor1.setup(2008, 6, 1); + } else { + _actor1.setup(10, 6, 1); + } + _actor1.setPosition(Common::Point(106, 111)); + _actor1.setDetails(9001, 0, 5, 3, 1, NULL); + + _actor3.postInit(); + _actor3.setup(2001, 7, 1); + _actor3.setPosition(Common::Point(34, 153)); + _actor3.setDetails(2001, 40, -1, -1, 1, NULL); + + _exit1._enabled = false; + } + } + R2_GLOBALS._player.enableControl(); + if (!R2_GLOBALS.getFlag(72)) { + R2_GLOBALS._player._canWalk = false; + } + break; + default: + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + if (R2_GLOBALS._player._characterIndex == 1) { + if (R2_GLOBALS.getFlag(61)) { + R2_GLOBALS._player.setup(2008, 3, 1); + } else { + R2_GLOBALS._player.setup(10, 3, 1); + } + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + } else { + R2_GLOBALS._player.setVisage(20); + R2_GLOBALS._player._moveDiff = Common::Point(5, 3); + } + R2_GLOBALS._player.setPosition(Common::Point(100, 130)); + R2_GLOBALS._player.enableControl(); + break; + } + _item2.setDetails(Rect(174, 4, 199, 123), 2430, 30, 31, 32, 1, NULL); + _item3.setDetails(Rect(67, 73, 207, 121), 2430, 36, -1, 38, 1, NULL); + _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL); +} + +void Scene2450::remove() { + R2_GLOBALS._sound1.fadeOut2(NULL); + SceneExt::remove(); +} + +void Scene2450::signal() { + switch (_sceneMode) { + case 10: + g_globals->_sceneManager.changeScene(2000); + break; + case 20: + if (R2_GLOBALS._v565AE == 3) { + R2_GLOBALS._player.disableControl(); + R2_GLOBALS._v565AE = 4; + _sceneMode = 2454; + setAction(&_sequenceManager, this, 2454, &_actor3, NULL); + } else { + R2_GLOBALS._player.enableControl(CURSOR_TALK); + if (R2_GLOBALS._v565AE < 4) + R2_GLOBALS._player._canWalk = false; + } + break; + case 30: + R2_GLOBALS._player.disableControl(); + _sceneMode = 2455; + setAction(&_sequenceManager, this, 2455, &_actor1, NULL); + break; + case 31: + R2_GLOBALS.setFlag(61); + g_globals->_sceneManager.changeScene(2435); + break; + case 2451: + R2_GLOBALS._player.enableControl(); + break; + case 2452: + R2_GLOBALS.setFlag(61); + _actor2.remove(); + R2_GLOBALS._player.enableControl(); + if (!R2_GLOBALS.getFlag(72)) { + R2_GLOBALS._player.setStrip(6); + R2_GLOBALS._player._canWalk = false; + } + break; + case 2453: + _sceneMode = 20; + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + _stripManager.start(700, this); + break; + case 2454: + _exit1._enabled = true; + R2_GLOBALS.setFlag(72); + _actor3.remove(); + if (R2_GLOBALS.getFlag(61)) { + g_globals->_sceneManager.changeScene(2435); + } else { + _sceneMode = 31; + if (R2_GLOBALS._player._characterIndex == 1) { + setAction(&_sequenceManager, this, 2452, &R2_GLOBALS._player, NULL); + } else { + setAction(&_sequenceManager, this, 2452, &_actor1, &_actor2, NULL); + } + } + break; + case 2455: + R2_GLOBALS._player._oldCharacterScene[2] = 2450; + R2_GLOBALS._player._characterScene[2] = 2000; + R2_GLOBALS._v56605[2] = 3; + _actor1.remove(); + R2_GLOBALS._player.enableControl(CURSOR_ARROW); + break; + default: + _actor1.postInit(); + _actor1.setDetails(9002, 0, 4, 3, 2, NULL); + _actor3.postInit(); + _actor3.setDetails(2001, 40, -1, -1, 2, NULL); + _sceneMode = 2453; + setAction(&_sequenceManager, this, 2453, &_actor3, &_actor1, NULL); + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2455 - Ice Maze: Inside crevasse + * + *--------------------------------------------------------------------------*/ + +bool Scene2455::Actor1::startAction(CursorType action, Event &event) { + Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene; + + if (action == R2_29) { + if ((R2_INVENTORY.getObjectScene(49) == 2455) || (R2_INVENTORY.getObjectScene(50) == 2455)) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2458; + scene->_actor2._lookLineNum = 9; + scene->_actor1.remove(); + scene->_actor3.postInit(); + scene->_actor3.setDetails(2455, 16, 1, -1, 2, NULL); + scene->setAction(&scene->_sequenceManager, scene, 2458, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor3, NULL); + return true; + } + } + + return SceneActor::startAction(action, event); +} + +bool Scene2455::Actor2::startAction(CursorType action, Event &event) { + Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene; + + switch (action) { + case R2_49: + if (R2_INVENTORY.getObjectScene(50) != 2455) { + R2_GLOBALS._player.disableControl(); + scene->_actor1.postInit(); + scene->_actor1.setup(2456, 3, 3); + scene->_actor1.setPosition(Common::Point(162, 165)); + scene->_actor1.setDetails(2455, 15, 1, -1, 2, NULL); + scene->_sceneMode = 11; + scene->setAction(&scene->_sequenceManager, scene, 2457, &R2_GLOBALS._player, &scene->_actor2, NULL); + return true; + } + break; + case R2_50: + if (R2_INVENTORY.getObjectScene(49) != 2455) { + R2_GLOBALS._player.disableControl(); + scene->_actor1.postInit(); + scene->_actor1.setup(2456, 3, 3); + scene->_actor1.setPosition(Common::Point(162, 165)); + scene->_actor1.setDetails(2455, 15, 1, -1, 2, NULL); + scene->_sceneMode = 12; + scene->setAction(&scene->_sequenceManager, scene, 2457, &R2_GLOBALS._player, &scene->_actor2, NULL); + return true; + } + break; + default: + break; + } + + return SceneActor::startAction(action, event); +} + +bool Scene2455::Actor3::startAction(CursorType action, Event &event) { + Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene; + + if (action == CURSOR_USE) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2459; + scene->setAction(&scene->_sequenceManager, scene, 2459, &R2_GLOBALS._player, &scene->_actor3, NULL); + return true; + } + + return SceneActor::startAction(action, event); +} + +void Scene2455::Exit1::changeScene() { + Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene; + + _enabled = false; + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2461; + scene->setAction(&scene->_sequenceManager, scene, 2461, &R2_GLOBALS._player, NULL); +} + +void Scene2455::postInit(SceneObjectList *OwnerList) { + loadScene(2455); + SceneExt::postInit(); + + if (R2_GLOBALS._sceneManager._previousScene == -1) { + R2_INVENTORY.setObjectScene(29, 2); + R2_INVENTORY.setObjectScene(50, 2); + } + + R2_GLOBALS._sound1.play(200); + _exit1.setDetails(Rect(0, 0, 320, 15), EXITCURSOR_N, 2425); + + if (R2_INVENTORY.getObjectScene(29) == 2455) { + if ((R2_INVENTORY.getObjectScene(50) == 2455) || (R2_INVENTORY.getObjectScene(49) == 2455)) { + _actor1.postInit(); + _actor1.setup(2456, 3, 3); + _actor1.setPosition(Common::Point(162, 165)); + _actor1.setDetails(2455, 15, 1, -1, 1, NULL); + } + } else { + _actor3.postInit(); + _actor3.setup(2456, 3, 1); + _actor3.setPosition(Common::Point(176, 165)); + _actor3.setDetails(2455, 16, 1, -1, 1, NULL); + } + + _actor2.postInit(); + if (R2_INVENTORY.getObjectScene(29) == 2455) { + _actor2.setup(2456, 3, 2); + _actor2.setDetails(2455, 9, 1, -1, 1, NULL); + } else { + if ((R2_INVENTORY.getObjectScene(50) != 2455) && (R2_INVENTORY.getObjectScene(49) != 2455)) + _actor2.setup(2455, 1, 1); + else + _actor2.setup(2456, 1, 1); + _actor2.setDetails(2455, 3, 1, -1, 1, NULL); + } + _actor2.setPosition(Common::Point(162, 165)); + _actor2.fixPriority(20); + if (R2_INVENTORY.getObjectScene(29) != 2455) + _actor2.animate(ANIM_MODE_2, NULL); + + R2_GLOBALS._player.postInit(); + _item1.setDetails(Rect(0, 0, 320, 200), 2455, 0, 1, -1, 1, NULL); + R2_GLOBALS._player.disableControl(); + + if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2425) { + _sceneMode = 2460; + setAction(&_sequenceManager, this, 2460, &R2_GLOBALS._player, NULL); + } else { + R2_GLOBALS._player.setup(2455, 2, 9); + R2_GLOBALS._player.setPosition(Common::Point(118, 165)); + R2_GLOBALS._player.enableControl(CURSOR_USE); + R2_GLOBALS._player._canWalk = false; + } + R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2455; +} + +void Scene2455::remove() { + R2_GLOBALS._sound1.fadeOut2(NULL); + SceneExt::remove(); +} + +void Scene2455::signal() { + switch (_sceneMode) { + case 10: + // No break on purpose + case 2461: + g_globals->_sceneManager.changeScene(2425); + break; + case 11: + R2_INVENTORY.setObjectScene(49, 2455); + R2_GLOBALS._player.enableControl(CURSOR_USE); + R2_GLOBALS._player._canWalk = false; + break; + case 12: + R2_INVENTORY.setObjectScene(50, 2455); + R2_GLOBALS._player.enableControl(CURSOR_USE); + R2_GLOBALS._player._canWalk = false; + break; + case 2458: + R2_INVENTORY.setObjectScene(29, 2455); + R2_GLOBALS._player.enableControl(CURSOR_USE); + R2_GLOBALS._player._canWalk = false; + break; + case 2459: + _actor3.remove(); + R2_INVENTORY.setObjectScene(31, 2); + R2_GLOBALS._player.enableControl(CURSOR_USE); + R2_GLOBALS._player._canWalk = false; + break; + default: + R2_GLOBALS._player.enableControl(CURSOR_USE); + R2_GLOBALS._player._canWalk = false; + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2500 - Ice Maze: Large Cave + * + *--------------------------------------------------------------------------*/ + +void Scene2500::Exit1::changeScene() { + Scene2500 *scene = (Scene2500 *)R2_GLOBALS._sceneManager._scene; + + _enabled = false; + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 11; + + Common::Point pt(20, 105); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); +} + +void Scene2500::postInit(SceneObjectList *OwnerList) { + loadScene(2500); + SceneExt::postInit(); + + if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 3100) + R2_GLOBALS._v58CE2 = 0; + + _stripManager.addSpeaker(&_quinnSpeaker); + _stripManager.addSpeaker(&_seekerSpeaker); + _stripManager.addSpeaker(&_mirandaSpeaker); + _stripManager.addSpeaker(&_webbsterSpeaker); + + if (R2_GLOBALS._sceneManager._previousScene == -1) + R2_GLOBALS._sceneManager._previousScene = 2000; + + _exit1.setDetails(Rect(30, 50, 85, 105), EXITCURSOR_W, 2000); + _exit1.setDest(Common::Point(84, 104)); + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + + if (R2_GLOBALS._player._characterIndex == 1) { + R2_GLOBALS._player.setVisage(11); + R2_GLOBALS._player._moveDiff = Common::Point(2, 1); + } else { + R2_GLOBALS._player.setVisage(21); + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + } + + if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) { + _actor1.postInit(); + if (R2_GLOBALS._player._characterIndex == 1) { + _actor1.setup(21, 3, 1); + _actor1.setDetails(9002, 1, -1, -1, 1, NULL); + } else { + _actor1.setup(2008, 3, 1); + _actor1.changeZoom(50); + _actor1.setDetails(9001, 0, -1, -1, 1, NULL); + } + _actor1.setPosition(Common::Point(141, 94)); + } + + _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL); + R2_GLOBALS._player.disableControl(); + + if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) { + _sceneMode = 10; + R2_GLOBALS._player.setPosition(Common::Point(20, 105)); + Common::Point pt(95, 105); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 3100) { + _sceneMode = 2500; + _actor2.postInit(); + _actor3.postInit(); + setAction(&_sequenceManager, this, 2500, &R2_GLOBALS._player, &_actor2, &_actor3, NULL); + } else { + R2_GLOBALS._player.setPosition(Common::Point(160, 150)); + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.enableControl(); + } + R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2500; +} + +void Scene2500::signal() { + switch (_sceneMode) { + case 11: + g_globals->_sceneManager.changeScene(2000); + break; + case 20: + R2_GLOBALS._player.disableControl(); + _sceneMode = 2501; + setAction(&_sequenceManager, this, 2501, &R2_GLOBALS._player, &_actor2, &_actor3, NULL); + break; + case 2500: + _sceneMode = 20; + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + _stripManager.start(900, this); + break; + case 2501: + g_globals->_sceneManager.changeScene(1000); + break; + default: + R2_GLOBALS._player.enableControl(); + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2525 - Furnace room + * + *--------------------------------------------------------------------------*/ +bool Scene2525::Item5::startAction(CursorType action, Event &event) { + Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene; + + if ((action == R2_20) && (!R2_GLOBALS.getFlag(74))) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2526; + scene->setAction(&scene->_sequenceManager, scene, 2526, &R2_GLOBALS._player, NULL); + return true; + } + + return SceneItem::startAction(action, event); +} + +bool Scene2525::Actor3::startAction(CursorType action, Event &event) { + Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene; + + if (action != CURSOR_USE) + return SceneActor::startAction(action, event); + + if (R2_GLOBALS._player._characterIndex == 2) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2525; + scene->setAction(&scene->_sequenceManager, scene, 2525, &R2_GLOBALS._player, &scene->_actor3, NULL); + } else { + SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); + } + return true; +} + +void Scene2525::Exit1::changeScene() { + Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene; + + _enabled = false; + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 11; + + Common::Point pt(R2_GLOBALS._player._position.x, 200); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); +} + +void Scene2525::postInit(SceneObjectList *OwnerList) { + loadScene(2525); + SceneExt::postInit(); + R2_GLOBALS._sound1.play(200); + R2_GLOBALS._sound2.play(207); + + _exit1.setDetails(Rect(86, 155, 228, 168), EXITCURSOR_S, 2000); + + if (R2_INVENTORY.getObjectScene(29) == 2525) { + _actor3.postInit(); + _actor3.setup(2435, 1, 2); + _actor3.setPosition(Common::Point(78, 155)); + _actor3.fixPriority(155); + _actor3.setDetails(2525, 27, -1, -1, 1, NULL); + } + + _actor2.postInit(); + _actor2.setup(2525, 1, 1); + _actor2.setPosition(Common::Point(183, 114)); + _actor2.setDetails(2525, 15, -1, -1, 1, NULL); + _actor2.animate(ANIM_MODE_2, NULL); + _actor2._numFrames = 3; + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + if (R2_GLOBALS._player._characterIndex == 1) { + R2_GLOBALS._player.setup(2008, 3, 1); + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + } else { + R2_GLOBALS._player.setup(20, 3, 1); + R2_GLOBALS._player._moveDiff = Common::Point(5, 3); + } + + if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) { + _actor1.postInit(); + if (R2_GLOBALS._player._characterIndex == 1) { + _actor1.setup(20, 5, 1); + _actor1.setDetails(9002, 0, 4, 3, 1, NULL); + } else { + _actor1.setup(2008, 5, 1); + _actor1.setDetails(9001, 0, 5, 3, 1, NULL); + } + _actor1.setPosition(Common::Point(209, 162)); + + R2_GLOBALS._walkRegions.enableRegion(4); + } + + _item5.setDetails(Rect(125, 73, 140, 86), 2525, 6, -1, -1, 1, NULL); + _item3.setDetails(Rect(137, 11, 163, 72), 2525, 12, -1, -1, 1, NULL); + _item4.setDetails(Rect(204, 20, 234, 78), 2525, 12, -1, -1, 1, NULL); + _item2.setDetails(Rect(102, 62, 230, 134), 2525, 0, -1, -1, 1, NULL); + _item1.setDetails(Rect(0, 0, 320, 200), 2525, 24, -1, -1, 1, NULL); + + R2_GLOBALS._player.disableControl(); + + if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) { + R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2525; + R2_GLOBALS._player.setPosition(Common::Point(160, 200)); + Common::Point pt(160, 150); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else { + R2_GLOBALS._player.setPosition(Common::Point(160, 150)); + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.enableControl(); + } +} + +void Scene2525::remove() { + R2_GLOBALS._sound1.fadeOut2(NULL); + R2_GLOBALS._sound2.fadeOut2(NULL); + SceneExt::remove(); +} + +void Scene2525::signal() { + switch (_sceneMode) { + case 11: + g_globals->_sceneManager.changeScene(2000); + break; + case 2525: + _actor3.remove(); + R2_INVENTORY.setObjectScene(29, 2); + R2_GLOBALS._player.enableControl(); + break; + case 2526: + R2_GLOBALS.setFlag(74); + R2_GLOBALS._player.enableControl(); + break; + default: + R2_GLOBALS._player.enableControl(); + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2530 - Ice Maze: Well + * + *--------------------------------------------------------------------------*/ +bool Scene2530::Actor2::startAction(CursorType action, Event &event) { + Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene; + + if (action != CURSOR_USE) + return SceneActor::startAction(action, event); + + if (R2_GLOBALS._player._characterIndex == 2) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2530; + scene->setAction(&scene->_sequenceManager, scene, 2530, &R2_GLOBALS._player, &scene->_actor2, NULL); + } else { + SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); + } + + return true; +} + +bool Scene2530::Actor3::startAction(CursorType action, Event &event) { + Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene; + + if (action != CURSOR_USE) + return SceneActor::startAction(action, event); + + if (R2_GLOBALS._player._characterIndex == 1) { + if (R2_GLOBALS.getFlag(73)) + SceneItem::display(2530, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); + else { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2532; + scene->setAction(&scene->_sequenceManager, scene, 2532, &R2_GLOBALS._player, &scene->_actor3, NULL); + } + } else { + if (R2_GLOBALS.getFlag(73)) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2533; + scene->setAction(&scene->_sequenceManager, scene, 2533, &R2_GLOBALS._player, &scene->_actor3, NULL); + } else { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2531; + scene->setAction(&scene->_sequenceManager, scene, 2531, &R2_GLOBALS._player, &scene->_actor3, NULL); + } + } + + return true; +} + +void Scene2530::Exit1::changeScene() { + Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene; + + _enabled = false; + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 11; + + Common::Point pt(108, 200); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); +} + +void Scene2530::postInit(SceneObjectList *OwnerList) { + loadScene(2530); + SceneExt::postInit(); + + _exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000); + _exit1.setDest(Common::Point(108, 160)); + + if (R2_INVENTORY.getObjectScene(33) == 2530) { + _actor2.postInit(); + _actor2.setup(2435, 1, 3); + _actor2.setPosition(Common::Point(299, 80)); + _actor2.fixPriority(80); + _actor2.setDetails(2530, 28, -1, -1, 1, NULL); + } + + _actor3.postInit(); + if (R2_GLOBALS.getFlag(73)) { + _actor3.setup(2531, 4, 2); + _actor3.setPosition(Common::Point(154, 130)); + } else { + _actor3.setup(2531, 4, 1); + _actor3.setPosition(Common::Point(173, 131)); + } + _actor3.setDetails(2530, 22, -1, -1, 1, NULL); + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + + if (R2_GLOBALS._player._characterIndex == 1) { + R2_GLOBALS._player.setVisage(2008); + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + } else { + R2_GLOBALS._player.setVisage(20); + R2_GLOBALS._player._moveDiff = Common::Point(5, 3); + } + R2_GLOBALS._player.setPosition(Common::Point(100, 200)); + + if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) { + _actor1.postInit(); + if (R2_GLOBALS._player._characterIndex == 1) { + _actor1.setup(20, 5, 1); + _actor1.setDetails(9002, 0, 4, 3, 1, NULL); + } else { + _actor1.setup(2008, 5, 1); + _actor1.setDetails(9001, 0, 5, 3, 1, NULL); + } + _actor1.setPosition(Common::Point(20, 130)); + R2_GLOBALS._walkRegions.enableRegion(1); + } + + _item2.setDetails(Rect(108, 90, 135, 205), 2530, 22, -1, -1, 1, NULL); + _item5.setDetails(Rect(115, 112, 206, 130), 2530, 25, -1, 27, 1, NULL); + _item3.setDetails(Rect(256, 64, 311, 85), 2530, 31, -1, 33, 1, NULL); + _item1.setDetails(Rect(0, 0, 320, 200), 2530, 0, 1, -1, 1, NULL); + + R2_GLOBALS._player.disableControl(); + + if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) { + R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2530; + Common::Point pt(108, 150); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else { + R2_GLOBALS._player.setPosition(Common::Point(105, 145)); + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.enableControl(); + } +} + +void Scene2530::signal() { + switch (_sceneMode) { + case 11: + g_globals->_sceneManager.changeScene(2000); + break; + case 2530: + R2_INVENTORY.setObjectScene(33, 2); + _actor2.remove(); + break; + case 2531: + // No break on purpose + case 2532: + R2_GLOBALS.setFlag(73); + R2_GLOBALS._player.enableControl(); + break; + case 2533: + R2_GLOBALS.clearFlag(73); + R2_GLOBALS._player.enableControl(); + break; + default: + R2_GLOBALS._player.enableControl(); + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2535 - Ice Maze: Tannery + * + *--------------------------------------------------------------------------*/ + +bool Scene2535::Actor3::startAction(CursorType action, Event &event) { + Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene; + + if (action != CURSOR_USE) + return SceneActor::startAction(action, event); + + if (R2_GLOBALS._player._characterIndex == 1) { + R2_GLOBALS._player.disableControl(); + if (R2_INVENTORY.getObjectScene(20) == 2535) { + scene->_sceneMode = 2536; + scene->setAction(&scene->_sequenceManager, scene, 2536, &R2_GLOBALS._player, &scene->_actor3, NULL); + } else { + scene->_sceneMode = 2537; + scene->setAction(&scene->_sequenceManager, scene, 2537, &R2_GLOBALS._player, &scene->_actor3, NULL); + } + } else { + SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); + } + + return true; +} + +bool Scene2535::Actor4::startAction(CursorType action, Event &event) { + Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene; + + if (action != CURSOR_USE) + return SceneActor::startAction(action, event); + + if (R2_GLOBALS._player._characterIndex == 2) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2535; + scene->setAction(&scene->_sequenceManager, scene, 2535, &R2_GLOBALS._player, &scene->_actor4, NULL); + } else { + SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); + } + + return true; +} + +void Scene2535::Exit1::changeScene() { + Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene; + + _enabled = false; + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 11; + Common::Point pt(210, 200); + PlayerMover *mover = new PlayerMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); +} + +void Scene2535::postInit(SceneObjectList *OwnerList) { + loadScene(2535); + SceneExt::postInit(); + if (R2_GLOBALS._sceneManager._previousScene == -1) { + R2_GLOBALS.setFlag(73); + R2_INVENTORY.setObjectScene(20, 2535); + } + _exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_S, 2000); + _exit1.setDest(Common::Point(210, 160)); + + if (R2_INVENTORY.getObjectScene(32) == 2535) { + _actor4.postInit(); + _actor4.setup(2435, 1, 4); + _actor4.setPosition(Common::Point(47, 74)); + _actor4.fixPriority(74); + _actor4.setDetails(2535, 21, -1, -1, 1, NULL); + } + + if (R2_INVENTORY.getObjectScene(20) == 2535) { + _actor3.postInit(); + _actor3.setup(2535, 3, 1); + _actor3.setPosition(Common::Point(203, 131)); + _actor3.setDetails(3, 20, -1, -1, 1, NULL); + R2_GLOBALS._walkRegions.enableRegion(6); + } + + if ((R2_INVENTORY.getObjectScene(20) == 0) && (R2_GLOBALS.getFlag(73))) { + _actor3.postInit(); + _actor3.setup(2536, 1, 2); + _actor3.setPosition(Common::Point(164, 133)); + _actor3.setDetails(3, 20, -1, -1, 1, NULL); + } + + if (R2_GLOBALS.getFlag(73)) { + _actor2.postInit(); + _actor2.setup(2536, 1, 1); + _actor2.setPosition(Common::Point(160, 130)); + _actor2.fixPriority(122); + _actor2.setDetails(2535, 37, -1, -1, 1, NULL); + } + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + if (R2_GLOBALS._player._characterIndex == 1) { + R2_GLOBALS._player.setVisage(2008); + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + } else { + R2_GLOBALS._player.setVisage(20); + R2_GLOBALS._player._moveDiff = Common::Point(5, 3); + } + R2_GLOBALS._player.setPosition(Common::Point(210, 200)); + + if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) { + _actor1.postInit(); + if (R2_GLOBALS._player._characterIndex == 1) { + _actor1.setup(20, 5, 1); + _actor1.setDetails(9002, 0, 4, 3, 1, NULL); + } else { + _actor1.setup(2008, 5, 1); + _actor1.setDetails(9001, 0, 5, 3, 1, NULL); + } + _actor1.setPosition(Common::Point(245, 115)); + R2_GLOBALS._walkRegions.enableRegion(2); + } + + _item2.setDetails(Rect(96, 3, 215, 33), 2535, 3, 6, 5, 1, NULL); + _item3.setDetails(Rect(4, 43, 40, 101), 2535, 6, 7, 8, 1, NULL); + _item4.setDetails(Rect(55, 13, 140, 89), 2535, 6, 7, 8, 1, NULL); + _item5.setDetails(Rect(144, 23, 216, 76), 2535, 6, 7, 8, 1, NULL); + _item6.setDetails(Rect(227, 8, 307, 99), 2535, 6, 7, 8, 1, NULL); + _item7.setDetails(Rect(116, 111, 201, 132), 2535, 18, 19, 20, 1, NULL); + _item1.setDetails(Rect(0, 0, 320, 200), 2535, 0, 1, -1, 1, NULL); + R2_GLOBALS._player.disableControl(); + + if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) { + R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2535; + Common::Point pt(210, 150); + PlayerMover *mover = new PlayerMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else { + R2_GLOBALS._player.setPosition(Common::Point(210, 150)); + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.enableControl(); + } +} + +void Scene2535::signal() { + switch (_sceneMode) { + case 11: + g_globals->_sceneManager.changeScene(2000); + break; + case 2535: + R2_INVENTORY.setObjectScene(32, 2); + _actor4.remove(); + R2_GLOBALS._player.enableControl(); + break; + case 2536: + R2_INVENTORY.setObjectScene(20, 0); + R2_GLOBALS._walkRegions.disableRegion(6); + if (!R2_GLOBALS.getFlag(73)) { + _actor3.remove(); + R2_GLOBALS._player.enableControl(); + } else { + _sceneMode = 20; + _actor3.show(); + _actor3.setup(2536, 1, 2); + _actor3.setDetails(3, 20, -1, -1, 3, NULL); + _actor3.setPosition(Common::Point(164, 150)); + _actor3.fixPriority(130); + _actor3._moveDiff.y = 1; + Common::Point pt(164, 133); + PlayerMover *mover = new PlayerMover(); + _actor3.addMover(mover, &pt, this); + } + break; + case 2537: + _actor3.remove(); + R2_INVENTORY.setObjectScene(20, 1); + R2_GLOBALS._player.enableControl(); + break; + case 20: + // No break on purpose + default: + R2_GLOBALS._player.enableControl(); + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2600 - Ice Maze: Exit + * + *--------------------------------------------------------------------------*/ +Scene2600::Scene2600(): SceneExt() { + _rotation = NULL; +} + +void Scene2600::synchronize(Serializer &s) { + SceneExt::synchronize(s); + + SYNC_POINTER(_rotation); +} + +void Scene2600::postInit(SceneObjectList *OwnerList) { + loadScene(2600); + R2_GLOBALS._v58CE2 = 0; + SceneExt::postInit(); + R2_GLOBALS._sound1.fadeSound(214); + R2_GLOBALS._sound2.play(215); + _rotation = R2_GLOBALS._scenePalette.addRotation(176, 191, 1); + _rotation->setDelay(3); + _rotation->_countdown = 1; + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.disableControl(); + _sceneMode = 2600; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2600, &R2_GLOBALS._player, NULL); +} + +void Scene2600::remove() { + R2_GLOBALS._sound1.fadeOut2(NULL); + R2_GLOBALS._sound2.fadeOut2(NULL); +// _rotation->remove(); + SceneExt::remove(); +} + +void Scene2600::signal() { + if (_sceneMode == 2600) + g_globals->_sceneManager.changeScene(3800); +} + +/*-------------------------------------------------------------------------- + * Scene 2700 - Forest Maze + * + *--------------------------------------------------------------------------*/ +Scene2700::Scene2700(): SceneExt() { + _field412 = _field414 = _field416 = 0; +} + +void Scene2700::synchronize(Serializer &s) { + SceneExt::synchronize(s); + + s.syncAsSint16LE(_field412); + s.syncAsSint16LE(_field414); + s.syncAsSint16LE(_field416); +} + +void Scene2700::Action1::signal() { + Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene; + + setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300)); + scene->_actor2.animate(ANIM_MODE_5, NULL); +} + +void Scene2700::Action2::signal() { + Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene; + + setDelay(300 + R2_GLOBALS._randomSource.getRandomNumber(300)); + scene->_actor3.animate(ANIM_MODE_5, NULL); +} + +void Scene2700::Action3::signal() { + Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene; + + setDelay(450 + R2_GLOBALS._randomSource.getRandomNumber(450)); + scene->_actor4.animate(ANIM_MODE_8, 1, NULL); +} + +void Scene2700::Action4::signal() { + Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene; + + setDelay(300 + R2_GLOBALS._randomSource.getRandomNumber(300)); + scene->_actor5.animate(ANIM_MODE_8, 1, NULL); +} + +void Scene2700::Area1::process(Event &event) { + SceneArea::process(event); + if ((event.eventType == 1) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) { + Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene; + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 10; + scene->_field414 = 2703; + switch (scene->_field412) { + case 0: + // No break on purpose + case 6: + scene->_sceneMode = 2703; + scene->setAction(&scene->_sequenceManager, scene, 2703, &R2_GLOBALS._player, NULL); + break; + case 1: { + Common::Point pt(80, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 2: { + Common::Point pt(155, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 3: { + Common::Point pt(140, 162); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 4: { + Common::Point pt(155, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 5: { + Common::Point pt(235, 132); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + default: + break; + } + } +} + +void Scene2700::Area2::process(Event &event) { + SceneArea::process(event); + if ((event.eventType == 1) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) { + Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene; + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 10; + scene->_field414 = 2704; + switch (scene->_field412) { + case 0: { + Common::Point pt(140, 162); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 1: { + Common::Point pt(80, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 2: { + Common::Point pt(155, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 3: { + Common::Point pt(155, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 4: { + Common::Point pt(235, 132); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 5: + scene->_sceneMode = 2704; + scene->setAction(&scene->_sequenceManager, scene, 2704, &R2_GLOBALS._player, NULL); + break; + case 6: { + Common::Point pt(140, 162); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + default: + break; + } + } +} + +void Scene2700::postInit(SceneObjectList *OwnerList) { + loadScene(2700); + SceneExt::postInit(); + R2_GLOBALS._sound1.stop(); + R2_GLOBALS._sound2.stop(); + + _area1.setDetails(Rect(135, 160, 185, 168), SHADECURSOR_DOWN); + _area2.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E); + _rect1.set(70, 122, 90, 132); + _rect2.set(150, 122, 160, 132); + _rect3.set(90, 142, 130, 157); + _rect4.set(175, 137, 200, 147); + _rect5.set(280, 127, 300, 137); + _rect6.set(240, 157, 265, 167); + + _actor2.postInit(); + _actor2.setup(2700, 1, 1); + _actor2.setPosition(Common::Point(140, 29)); + _actor2.setAction(&_action1); + + _actor3.postInit(); + _actor3.setup(2700, 2, 1); + _actor3.setPosition(Common::Point(213, 32)); + _actor3.setAction(&_action2); + + _actor4.postInit(); + _actor4.setup(2700, 3, 1); + _actor4.setPosition(Common::Point(17, 39)); + _actor4.setAction(&_action3); + + _actor5.postInit(); + _actor5.setup(2700, 5, 1); + _actor5.setPosition(Common::Point(17, 71)); + _actor5.setAction(&_action4); + + _item2.setDetails(Rect(52, 38, 68, 60), 2700, 4, -1, 6, 1, NULL); + _item3.setDetails(Rect(113, 22, 127, 33), 2700, 4, -1, 6, 1, NULL); + _item4.setDetails(Rect(161, 44, 170, 52), 2700, 4, -1, 6, 1, NULL); + _item5.setDetails(Rect(221, 19, 233, 31), 2700, 4, -1, 6, 1, NULL); + _item6.setDetails(Rect(235, 59, 250, 75), 2700, 4, -1, 6, 1, NULL); + _item1.setDetails(Rect(0, 0, 320, 200), 2700, 4, -1, 6, 1, NULL); + + _stripManager.setColors(60, 255); + _stripManager.setFontNumber(3); + _stripManager.addSpeaker(&_quinnSpeaker); + _stripManager.addSpeaker(&_nejSpeaker); + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.setVisage(19); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player._moveDiff = Common::Point(2, 2); + R2_GLOBALS._player.disableControl(); + + if (R2_INVENTORY.getObjectScene(36) == 0) + R2_GLOBALS._sound1.changeSound(234); + + if (R2_GLOBALS._sceneManager._previousScene == 2750) { + _sceneMode = 2702; + _field412 = 5; + setAction(&_sequenceManager, this, 2702, &R2_GLOBALS._player, NULL); + } else { + _field412 = 0; + if (R2_GLOBALS._sceneManager._previousScene == 3900) { + _sceneMode = 2701; + setAction(&_sequenceManager, this, 2701, &R2_GLOBALS._player, NULL); + } else { + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.setPosition(Common::Point(164, 160)); + R2_GLOBALS._player.enableControl(); + } + } +} + +void Scene2700::signal() { + switch (_sceneMode) { + case 10: + switch (_field414) { + case 1: + switch (_field412) { + case 0: + case 2: + case 4: + case 6: + _field412 = 3; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2705, &R2_GLOBALS._player, NULL); + break; + case 3: { + _sceneMode = _field414; + _field412 = 1; + Common::Point pt(80, 127); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 5: + _field412 = 4; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL); + break; + default: // includes case 1 + break; + } + break; + case 2: + switch (_field412) { + case 0: + case 1: + case 6: + _field412 = 3; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL); + break; + case 3: + case 4: { + _sceneMode = _field414; + _field412 = 2; + Common::Point pt(155, 127); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 5: + _field412 = 4; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL); + break; + default: // includes case 2 + break; + } + break; + case 3: + switch (_field412) { + case 0: + case 1: + case 2: + case 4: + case 6: { + _sceneMode = _field414; + _field412 = 3; + Common::Point pt(115, 152); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 5: + _field412 = 4; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL); + break; + default: // includes case 3 + break; + } + break; + case 4: + switch (_field412) { + case 0: + case 1: + case 6: + _field412 = 3; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL); + break; + case 2: + case 3: + _field412 = 4; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL); + break; + case 4: + case 5: + _sceneMode = _field414; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2704, &R2_GLOBALS._player, NULL); + break; + default: + break; + } + break; + case 5: + switch (_field412) { + case 0: + case 1: + case 6: + _field412 = 3; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL); + break; + case 2: + case 3: + _field412 = 4; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL); + break; + case 4: { + _sceneMode = _field414; + _field412 = 5; + Common::Point pt(285, 132); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + default: // includes case 5 + break; + } + break; + case 6: + switch (_field412) { + case 0: + case 3: { + _sceneMode = _field414; + _field412 = 6; + Common::Point pt(250, 162); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 1: + case 2: + case 4: + _field412 = 3; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL); + break; + case 5: + _field412 = 4; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL); + break; + default: + break; + } + break; + case 2703: + switch (_field412) { + case 0: + case 3: + case 6: + _sceneMode = _field414; + setAction(&_sequenceManager, this, 2703, &R2_GLOBALS._player, NULL); + break; + case 1: + case 2: + case 4: + _field412 = 3; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL); + break; + case 5: + _field412 = 4; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL); + break; + default: + break; + } + break; + case 2704: + switch (_field412) { + case 0: + case 1: + case 6: + _field412 = 3; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL); + break; + case 2: + case 3: + _field412 = 4; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL); + break; + case 4: + case 5: + _sceneMode = _field414; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2704, &R2_GLOBALS._player, NULL); + break; + default: + break; + } + break; + case 2710: + switch (_field412) { + case 0: + case 1: + case 3: + _field412 = 3; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL); + break; + case 2: + case 5: { + _sceneMode = _field414; + Common::Point pt(164, 160); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 4: + _field412 = 4; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL); + break; + default: + break; + } + break; + default: + break; + } + break; + case 11: + R2_INVENTORY.setObjectScene(36, 0); + R2_GLOBALS._player.disableControl(); + _field412 = 0; + _sceneMode = 2700; + setAction(&_sequenceManager, this, 2700, &_actor1, NULL); + break; + case 12: + R2_GLOBALS._sound1.play(234); + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + _sceneMode = 2711; + _stripManager.start(_field416, this); + break; + case 13: + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + _sceneMode = 2712; + _stripManager.start(_field416, this); + break; + case 14: + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + _sceneMode = 2713; + _stripManager.start(_field416, this); + break; + case 15: + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + _sceneMode = 11; + _stripManager.start(_field416, this); + break; + case 2700: + _actor1.remove(); + R2_GLOBALS._player.enableControl(CURSOR_ARROW); + break; + case 2703: + g_globals->_sceneManager.changeScene(3900); + break; + case 2704: + g_globals->_sceneManager.changeScene(2750); + break; + case 2710: + _field416 = 1200; + _sceneMode = 12; + _actor1.postInit(); + setAction(&_sequenceManager, this, 2710, &R2_GLOBALS._player, &_actor1, NULL); + break; + case 2711: + R2_GLOBALS._player.disableControl(); + _field416 = 1201; + _sceneMode = 13; + setAction(&_sequenceManager, this, 2711, &R2_GLOBALS._player, &_actor1, NULL); + break; + case 2712: + R2_GLOBALS._player.disableControl(); + _field416 = 1202; + _sceneMode = 14; + setAction(&_sequenceManager, this, 2712, &R2_GLOBALS._player, &_actor1, NULL); + break; + case 2713: + R2_GLOBALS._player.disableControl(); + _field416 = 1203; + _sceneMode = 14; + setAction(&_sequenceManager, this, 2713, &R2_GLOBALS._player, &_actor1, NULL); + break; + default: + R2_GLOBALS._player.enableControl(CURSOR_ARROW); + break; + } +} +void Scene2700::process(Event &event) { + if ((R2_GLOBALS._player._canWalk) && (event.eventType == EVENT_BUTTON_DOWN)) { + if (R2_GLOBALS._events.getCursor() == R2_36) { + if (R2_GLOBALS._player._bounds.contains(event.mousePos)) { + _sceneMode = 10; + _field414 = 2710; + R2_GLOBALS._player.disableControl(); + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + switch (_field412) { + case 0: { + _sceneMode = 2710; + Common::Point pt(164, 160); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 1: { + Common::Point pt(80, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 2: { + Common::Point pt(155, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 3: { + Common::Point pt(140, 162); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 4: { + Common::Point pt(155, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 5: { + Common::Point pt(235, 132); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 6: { + Common::Point pt(205, 162); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + default: + break; + } + event.handled = true; + } else { + SceneItem::display(2700, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); + } + } else if (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN) { + if (_rect1.contains(event.mousePos)) { + if (!_rect1.contains(R2_GLOBALS._player._position)) { + event.handled = true; + _sceneMode = 10; + _field414 = 1; + } + } else if (_rect2.contains(event.mousePos)) { + if (!_rect2.contains(R2_GLOBALS._player._position)) { + event.handled = true; + _sceneMode = 10; + _field414 = 2; + } + } else if (_rect3.contains(event.mousePos)) { + if (!_rect3.contains(R2_GLOBALS._player._position)) { + event.handled = true; + _sceneMode = 10; + _field414 = 3; + } + } else if (_rect4.contains(event.mousePos)) { + if (!_rect4.contains(R2_GLOBALS._player._position)) { + event.handled = true; + _sceneMode = 10; + _field414 = 4; + } + } else if (_rect5.contains(event.mousePos)) { + if (!_rect5.contains(R2_GLOBALS._player._position)) { + event.handled = true; + _sceneMode = 10; + _field414 = 5; + } + } else if (_rect6.contains(event.mousePos)) { + if (!_rect6.contains(R2_GLOBALS._player._position)) { + event.handled = true; + _sceneMode = 10; + _field414 = 6; + } + } else { + event.handled = true; + R2_GLOBALS._player.updateAngle(Common::Point(event.mousePos.x, event.mousePos.y)); + } + if (_sceneMode == 10) { + R2_GLOBALS._player.disableControl(); + switch (_field412) { + case 0: + if (_field414 >= 6) { + Common::Point pt(205, 162); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else { + Common::Point pt(140, 162); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + case 1: { + Common::Point pt(80, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 2: { + Common::Point pt(155, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 3: + if (_field414 == 1) { + Common::Point pt(80, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else if (_field414 == 6) { + Common::Point pt(140, 162); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else { + Common::Point pt(155, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + case 4: + if (_field414 == 5) { + Common::Point pt(235, 132); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else { + Common::Point pt(155, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + case 5: { + Common::Point pt(235, 132); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 6: { + Common::Point pt(140, 162); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + default: + break; + } + } + } + } + Scene::process(event); +} + +/*-------------------------------------------------------------------------- + * Scene 2750 - Forest Maze + * + *--------------------------------------------------------------------------*/ +Scene2750::Scene2750(): SceneExt() { + _field412 = _field414 = _field416 = 0; +} + +void Scene2750::synchronize(Serializer &s) { + SceneExt::synchronize(s); + + s.syncAsSint16LE(_field412); + s.syncAsSint16LE(_field414); + s.syncAsSint16LE(_field416); +} + +void Scene2750::Action1::signal() { + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + + switch (_actionIndex) { + case 1: + setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(240)); + _actionIndex = 2; + scene->_actor5.show(); + scene->_actor5.animate(ANIM_MODE_8, 1, NULL); + break; + case 2: + setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(600)); + _actionIndex = 0; + scene->_actor5.show(); + scene->_actor3.animate(ANIM_MODE_2, NULL); + break; + default: + setDelay(30); + _actionIndex = 1; + scene->_actor3.animate(ANIM_MODE_6, NULL); + scene->_actor4.animate(ANIM_MODE_8, 1, NULL); + break; + } +} + +void Scene2750::Action2::signal() { + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + + setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300)); + scene->_actor6.animate(ANIM_MODE_8, 1, NULL); +} + +void Scene2750::Action3::signal() { + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + + if (scene->_actor7._position.x <= 320) { + setDelay(1800 + R2_GLOBALS._randomSource.getRandomNumber(600)); + } else { + setDelay(60); + scene->_actor7.setPosition(Common::Point(-10, 25)); + Common::Point pt(330, 45); + NpcMover *mover = new NpcMover(); + scene->_actor7.addMover(mover, &pt, NULL); + } +} + +void Scene2750::Action4::signal() { + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + + setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300)); + scene->_actor8.animate(ANIM_MODE_8, 1, NULL); +} + +void Scene2750::Action5::signal() { + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + + setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300)); + scene->_actor9.animate(ANIM_MODE_8, 1, NULL); +} + +void Scene2750::Action6::signal() { + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + + setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300)); + scene->_actor10.animate(ANIM_MODE_8, 1, NULL); +} + +void Scene2750::Action7::signal() { + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + + setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300)); + scene->_actor11.animate(ANIM_MODE_8, 1, NULL); +} + +void Scene2750::Area1::process(Event &event) { + SceneArea::process(event); + if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) { + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 10; + scene->_field414 = 2752; + switch (scene->_field412) { + case 1: { + scene->_sceneMode = 2752; + scene->setAction(&scene->_sequenceManager, scene, 2752, &R2_GLOBALS._player, NULL); + break; + } + case 2: { + Common::Point pt(140, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 3: { + Common::Point pt(210, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + default: + break; + } + } +} + +void Scene2750::Area2::process(Event &event) { + SceneArea::process(event); + if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) { + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 10; + scene->_field414 = 2753; + switch (scene->_field412) { + case 1: { + Common::Point pt(140, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 2: { + Common::Point pt(210, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, scene); + break; + } + case 3: { + scene->_sceneMode = 2753; + scene->setAction(&scene->_sequenceManager, scene, 2753, &R2_GLOBALS._player, NULL); + break; + } + default: + break; + } + } +} + +void Scene2750::postInit(SceneObjectList *OwnerList) { + loadScene(2750); + R2_GLOBALS._sound2.stop(); + SceneExt::postInit(); + _area1.setDetails(Rect(0, 90, 20, 135), EXITCURSOR_W); + _area2.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E); + + _rect1.set(30, 127, 155, 147); + _rect2.set(130, 142, 210, 167); + _rect3.set(-1, 137, 290, 147); + + if (R2_INVENTORY.getObjectScene(36) == 0) { + R2_GLOBALS._sound1.changeSound(235); + _actor2.postInit(); + _actor2.setup(2751, 1, 1); + _actor2.setPosition(Common::Point(104, 158)); + _actor2.animate(ANIM_MODE_2, NULL); + } + + _actor3.postInit(); + _actor3.setup(2750, 1, 1); + _actor3.setPosition(Common::Point(188, 34)); + _actor3.animate(ANIM_MODE_2, NULL); + _actor3._numFrames = 16; + + _actor4.postInit(); + _actor4.setup(2700, 4, 1); + _actor4.setPosition(Common::Point(188, 37)); + _actor4.fixPriority(26); + + _actor5.postInit(); + _actor5.setup(2750, 2, 1); + _actor5.setPosition(Common::Point(188, 34)); + _actor5.hide(); + + _actor3.setAction(&_action1); + + _actor6.postInit(); + _actor6.setup(2750, 3, 1); + _actor6.setPosition(Common::Point(9, 167)); + _actor6.fixPriority(252); + _actor6.setAction(&_action2); + + _actor7.postInit(); + _actor7.setup(2750, 4, 1); + _actor7.setPosition(Common::Point(-10, 25)); + _actor7.animate(ANIM_MODE_1, NULL); + _actor7.setStrip2(4); + _actor7._moveRate = 20; + _actor7.setAction(&_action3); + + _actor8.postInit(); + _actor8.fixPriority(26); + _actor8.setup(2750, 5, 1); + _actor8.setPosition(Common::Point(258, 33)); + _actor8.setAction(&_action4); + + _actor9.postInit(); + _actor9.fixPriority(26); + _actor9.setup(2750, 6, 1); + _actor9.setPosition(Common::Point(61, 38)); + _actor9.setAction(&_action5); + + _actor10.postInit(); + _actor10.fixPriority(26); + _actor10.setup(2750, 7, 1); + _actor10.setPosition(Common::Point(69, 37)); + _actor10.setAction(&_action6); + + _actor11.postInit(); + _actor11.fixPriority(26); + _actor11.setup(2750, 8, 1); + _actor11.setPosition(Common::Point(80, 35)); + _actor11.setAction(&_action7); + + _item2.setDetails(Rect(29, 50, 35, 56), 2750, 3, -1, 5, 1, NULL); + _item3.setDetails(Rect(47, 36, 54, 42), 2750, 3, -1, 5, 1, NULL); + _item4.setDetails(Rect(193, 21, 206, 34), 2750, 3, -1, 5, 1, NULL); + _item5.setDetails(Rect(301, 18, 315, 32), 2750, 3, -1, 5, 1, NULL); + _item1.setDetails(Rect(0, 0, 320, 200), 2700, 0, -1, 2, 1, NULL); + + _stripManager.setColors(60, 255); + _stripManager.setFontNumber(3); + _stripManager.addSpeaker(&_quinnSpeaker); + _stripManager.addSpeaker(&_nejSpeaker); + + if (R2_INVENTORY.getObjectScene(36) == 0) { + _actor1.postInit(); + _actor1.setup(2752, 5, 1); + _actor1.animate(ANIM_MODE_NONE, NULL); + _actor1.setPosition(Common::Point(101, 148)); + } + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.setVisage(19); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player._moveDiff = Common::Point(2, 2); + R2_GLOBALS._player.disableControl(); + + if (R2_GLOBALS._sceneManager._previousScene == 2700) { + if (R2_INVENTORY.getObjectScene(36) == 0) { + R2_GLOBALS._player.setVisage(2752); + R2_GLOBALS._player.setStrip(6); + R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL); + R2_GLOBALS._player.setPosition(Common::Point(81, 165)); + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + _field416 = 1204; + _sceneMode = 11; + _stripManager.start(_field416, this); + } else { + _sceneMode = 2750; + _field412 = 1; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2750, &R2_GLOBALS._player, NULL); + } + } else if (R2_GLOBALS._sceneManager._previousScene == 2800) { + _sceneMode = 2751; + _field412 = 3; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2751, &R2_GLOBALS._player, NULL); + } else { + _field412 = 1; + R2_GLOBALS._player.setPosition(Common::Point(90, 137)); + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.enableControl(); + } +} +void Scene2750::signal() { + switch (_sceneMode) { + case 10: + switch (_field414) { + case 1: + switch (_field412) { + case 2: { + _sceneMode = _field414; + _field412 = 1; + Common::Point pt(90, 137); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + case 3: { + _field412 = 2; + Common::Point pt(140, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + default: + break; + } + break; + case 2: { + _sceneMode = _field414; + _field412 = 2; + Common::Point pt(170, 162); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + case 3: + switch (_field412) { + case 1: { + _field412 = 2; + Common::Point pt(210, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + case 2: { + _sceneMode = _field414; + _field412 = 3; + Common::Point pt(270, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + default: + break; + } + break; + case 2752: + switch (_field412) { + case 1: + _sceneMode = _field414; + setAction(&_sequenceManager, this, 2752, &R2_GLOBALS._player, NULL); + break; + case 2: { + _field412 = 1; + Common::Point pt(20, 132); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + case 3: { + _field412 = 2; + Common::Point pt(140, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + default: + break; + } + break; + case 2753: + switch (_field412) { + case 1: { + _field412 = 2; + Common::Point pt(210, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + case 2: { + _field412 = 3; + Common::Point pt(300, 132); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + case 3: + _sceneMode = _field414; + setAction(&_sequenceManager, this, 2753, &R2_GLOBALS._player, NULL); + break; + default: + break; + } + break; + default: + break; + } + break; + case 11: + // No break on purpose + case 2753: + g_globals->_sceneManager.changeScene(2800); + break; + case 2752: + g_globals->_sceneManager.changeScene(2700); + break; + default: + R2_GLOBALS._player.enableControl(R2_NEGATOR_GUN); + break; + } +} + +void Scene2750::process(Event &event) { + if ((R2_GLOBALS._player._canWalk) && (event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN)) { + if (_rect1.contains(event.mousePos)) { + if (!_rect1.contains(R2_GLOBALS._player._position)) { + event.handled = true; + _sceneMode = 10; + _field414 = 1; + } + } else if (_rect2.contains(event.mousePos)) { + if (!_rect2.contains(R2_GLOBALS._player._position)) { + event.handled = true; + _sceneMode = 10; + _field414 = 2; + } + } else if (_rect3.contains(event.mousePos)) { + if (!_rect3.contains(R2_GLOBALS._player._position)) { + event.handled = true; + _sceneMode = 10; + _field414 = 3; + } + } else { + event.handled = true; + R2_GLOBALS._player.updateAngle(Common::Point(event.mousePos.x, event.mousePos.y)); + } + + if (_sceneMode == 10) { + R2_GLOBALS._player.disableControl(); + switch (_field412) { + case 1: { + Common::Point pt(140, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + case 2: + if (_field414 == 1) { + Common::Point pt(140, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } else { + Common::Point pt(210, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + case 3: { + Common::Point pt(210, 142); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + } + break; + default: + break; + } + } + } + Scene::process(event); +} + +/*-------------------------------------------------------------------------- + * Scene 2800 - Exiting forest + * + *--------------------------------------------------------------------------*/ +Scene2800::Scene2800(): SceneExt() { + _field412 = 0; +} + +void Scene2800::synchronize(Serializer &s) { + SceneExt::synchronize(s); + + s.syncAsSint16LE(_field412); +} + +bool Scene2800::Item2::startAction(CursorType action, Event &event) { + Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene; + + if ((action == CURSOR_USE) && (R2_GLOBALS.getFlag(47))) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 2805; + scene->setAction(&scene->_sequenceManager, scene, 2805, &R2_GLOBALS._player, NULL); + return true; + } else + return SceneHotspot::startAction(action, event); +} + +bool Scene2800::Actor1::startAction(CursorType action, Event &event) { + Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene; + + if (action == CURSOR_TALK) { + R2_GLOBALS._player.disableControl(); + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + R2_GLOBALS.setFlag(47); + scene->_field412 = 1205; + scene->_sceneMode = 2803; + scene->_stripManager.start(scene->_field412, scene); + return true; + } else if (action == R2_7) { + R2_GLOBALS._events.setCursor(CURSOR_ARROW); + R2_GLOBALS._player.disableControl(); + R2_GLOBALS.setFlag(47); + scene->_sceneMode = 10; + scene->setAction(&scene->_sequenceManager, scene, 2802, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor1, NULL); + return true; + } else + return SceneActor::startAction(action, event); +} + +void Scene2800::Action1::signal() { + Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene; + + if (R2_GLOBALS._player._position.x <= 320) { + setDelay(120); + Common::Point pt(330, 25); + NpcMover *mover = new NpcMover(); + scene->_object1.addMover(mover, &pt, NULL); + } else { + setDelay(1800 + R2_GLOBALS._randomSource.getRandomNumber(600)); + scene->_object1.setPosition(Common::Point(-10, 45)); + } +} + +void Scene2800::Action2::signal() { + Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(240); + R2_GLOBALS._sound1.changeSound(240); + R2_GLOBALS._sound2.stop(); + break; + case 1: + _object2.postInit(); + _object2.setVisage(2800); + _object2.setStrip(1); + _object2._numFrames = 8; + _object2._moveRate = 8; + _object2.changeZoom(100); + _object2.setPosition(Common::Point(1, 1)); + _object2.show(); + _object2.animate(ANIM_MODE_5, this); + break; + case 2: + R2_GLOBALS._sound2.play(130); + _object2.setVisage(2800); + _object2.setStrip(7); + + _object3.postInit(); + _object3.setVisage(2800); + _object3.setStrip(3); + _object3._numFrames = 8; + _object3._moveRate = 8; + _object3.changeZoom(100); + _object3.setPosition(Common::Point(300, 104)); + _object3.show(); + _object3.animate(ANIM_MODE_5, this); + break; + case 3: + R2_GLOBALS._sound1.play(241); + _object4.postInit(); + _object4.setVisage(2800); + _object4.setStrip(2); + _object4._numFrames = 4; + _object4._moveRate = 4; + _object4.changeZoom(100); + _object4.setPosition(Common::Point(300, 104)); + _object4.fixPriority(105); + _object4.show(); + _object4.animate(ANIM_MODE_5, this); + break; + case 4: + setDelay(18); + _object4.setStrip(4); + scene->_actor1.setVisage(2800); + scene->_actor1.setStrip(5); + scene->_actor1.setFrame(1); + scene->_actor1._numFrames = 5; + scene->_actor1._moveRate = 5; + scene->_actor1.setPosition(Common::Point(300, 104)); + scene->_actor1.fixPriority(110); + scene->_actor1.changeZoom(100); + scene->_actor1.show(); + break; + case 5: + scene->_actor1.animate(ANIM_MODE_5, this); + break; + case 6: { + scene->_actor1.changeZoom(-1); + scene->_actor1.setVisage(3107); + scene->_actor1.animate(ANIM_MODE_1, NULL); + scene->_actor1.setStrip(3); + scene->_actor1.setPosition(Common::Point(297, 140)); + scene->_actor1._numFrames = 10; + scene->_actor1._moveRate = 10; + scene->_actor1._moveDiff = Common::Point(3, 2); + + Common::Point pt(297, 160); + NpcMover *mover = new NpcMover(); + scene->_actor1.addMover(mover, &pt, this); + break; + } + case 7: { + scene->_actor1.changeZoom(75); + scene->_actor1.updateAngle(R2_GLOBALS._player._position); + + Common::Point pt(105, 82); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 8: { + R2_GLOBALS._player._numFrames = 8; + R2_GLOBALS._player._moveRate = 8; + R2_GLOBALS._player.animate(ANIM_MODE_2, NULL); + R2_GLOBALS._player.setObjectWrapper(NULL); + R2_GLOBALS._player.setStrip(2); + R2_GLOBALS._player.changeZoom(-1); + + Common::Point pt(79, 100); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 9: { + R2_GLOBALS._player._numFrames = 10; + R2_GLOBALS._player._moveRate = 10; + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper()); + + Common::Point pt(100, 64); + NpcMover *mover = new NpcMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 10: { + R2_GLOBALS._player.fixPriority(124); + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + + Common::Point pt(160, 124); + PlayerMover *mover = new PlayerMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 11: { + R2_GLOBALS._player.fixPriority(-1); + + Common::Point pt(160, 160); + PlayerMover *mover = new PlayerMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 12: { + Common::Point pt(270, 160); + PlayerMover *mover = new PlayerMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 13: + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + scene->_field412 = 1207; + scene->_stripManager.start(scene->_field412, this); + break; + case 14: { + R2_GLOBALS._player.disableControl(); + R2_GLOBALS._player.fixPriority(110); + + Common::Point pt(288, 140); + PlayerMover *mover = new PlayerMover(); + R2_GLOBALS._player.addMover(mover, &pt, this); + break; + } + case 15: + setDelay(18); + scene->_actor1.updateAngle(R2_GLOBALS._player._position); + R2_GLOBALS._player.setVisage(2800); + R2_GLOBALS._player.setStrip(6); + R2_GLOBALS._player.setFrame(1); + R2_GLOBALS._player.changeZoom(100); + R2_GLOBALS._player.setPosition(Common::Point(300, 104)); + R2_GLOBALS._player._numFrames = 5; + R2_GLOBALS._player._moveRate = 5; + break; + case 16: + R2_GLOBALS._player.animate(ANIM_MODE_5, this); + break; + case 17: + setDelay(6); + _object4.setStrip(2); + _object4.setFrame(11); + R2_GLOBALS._player.hide(); + // No break on purpose + case 18: + R2_GLOBALS._sound1.play(241); + _object4.animate(ANIM_MODE_6, this); + break; + case 19: + _object4.remove(); + _object3.animate(ANIM_MODE_6, this); + break; + case 20: + setDelay(6); + _object3.remove(); + _object2.setStrip(1); + _object2.setFrame(19); + break; + case 21: + setDelay(150); + R2_GLOBALS._sound1.play(269); + R2_GLOBALS._sound2.stop(); + break; + case 22: + scene->_sceneMode = 12; + _object2.animate(ANIM_MODE_6, scene); + break; + default: + break; + } +} + +void Scene2800::postInit(SceneObjectList *OwnerList) { + loadScene(2800); + setZoomPercents(100, 50, 124, 75); + R2_GLOBALS._sound1.stop(); + R2_GLOBALS._sound2.stop(); + SceneExt::postInit(); + + _object1.postInit(); + _object1.setup(2750, 4, 1); + _object1.setPosition(Common::Point(-10, 25)); + _object1.animate(ANIM_MODE_1, NULL); + _object1.setStrip2(4); + _object1._moveRate = 20; + _object1.setAction(&_action1); + + _actor3.postInit(); + _actor3.setup(2802, 1, 1); + _actor3.setPosition(Common::Point(116, 80)); + _actor3.fixPriority(111); + _actor3.animate(ANIM_MODE_2, NULL); + _actor3._numFrames = 6; + + if (!R2_GLOBALS.getFlag(47)) { + _actor1.postInit(); + _actor1.setVisage(3105); + _actor1.setStrip(3); + _actor1.setFrame(1); + _actor1.setZoom(50); + _actor1._moveDiff = Common::Point(2, 1); + _actor1.setPosition(Common::Point(122, 82)); + _actor1.animate(ANIM_MODE_NONE, NULL); + _actor1.setDetails(2800, -1, -1, -1, 1, NULL); + } + + _item1.setDetails(Rect(0, 0, 320, 200), 2800, -1, -1, -1, 1, NULL); + + _stripManager.setColors(60, 255); + _stripManager.setFontNumber(3); + _stripManager.addSpeaker(&_quinnSpeaker); + _stripManager.addSpeaker(&_nejSpeaker); + _stripManager.addSpeaker(&_guardSpeaker); + + if (R2_INVENTORY.getObjectScene(36) == 0) { + R2_GLOBALS._sound1.fadeSound(237); + if (R2_GLOBALS.getFlag(47)) { + _item2.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL); + } else { + _actor2.postInit(); + _actor2.setup(2752, 5, 1); + _actor2.animate(ANIM_MODE_NONE, NULL); + _actor2.changeZoom(100); + _actor2._moveDiff = Common::Point(2, 1); + _actor2.setPosition(Common::Point(101, 148)); + } + } + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.setVisage(19); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player.changeZoom(100); + R2_GLOBALS._player._moveDiff = Common::Point(2, 2); + R2_GLOBALS._player.disableControl(); + + if (R2_INVENTORY.getObjectScene(36) == 0) { + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2800, &R2_GLOBALS._player, NULL); + } else if (R2_GLOBALS.getFlag(47)) { + R2_GLOBALS._player.setVisage(3110); + R2_GLOBALS._player.changeZoom(-1); + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + R2_GLOBALS._player.setPosition(Common::Point(160, 124)); + R2_GLOBALS._player.enableControl(); + } else { + _sceneMode = 2801; + R2_GLOBALS._player.setAction(&_sequenceManager, this, 2801, &R2_GLOBALS._player, &_actor2, &_actor1, NULL); + } +} + +void Scene2800::signal() { + switch (_sceneMode) { + case 10: + R2_GLOBALS._sound1.play(238); + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + _field412 = 1206; + _sceneMode = 2804; + _stripManager.start(_field412, this); + break; + case 11: + _actor2.remove(); + _object1.setAction(NULL); + R2_GLOBALS._player.enableControl(CURSOR_ARROW); + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + _item2.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL); + break; + case 12: + R2_GLOBALS._sound1.fadeOut2(NULL); + R2_GLOBALS._sound2.fadeOut2(NULL); + g_globals->_sceneManager.changeScene(1000); + break; + case 2800: + g_globals->_sceneManager.changeScene(2750); + break; + case 2801: + R2_GLOBALS._player.enableControl(CURSOR_ARROW); + R2_GLOBALS._player._canWalk = false; + break; + case 2803: + R2_GLOBALS._player.disableControl(); + _sceneMode = 10; + setAction(&_sequenceManager, this, 2803, &R2_GLOBALS._player, &_actor2, &_actor1, NULL); + break; + case 2804: + R2_GLOBALS._player.disableControl(); + _sceneMode = 11; + setAction(&_sequenceManager, this, 2804, &R2_GLOBALS._player, &_actor2, NULL); + break; + case 2805: + _object1.remove(); + setAction(&_action2); + break; + default: + break; + } +} + } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.h b/engines/tsage/ringworld2/ringworld2_scenes2.h index f9d4c9f2ce..d007f7e9f5 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes2.h +++ b/engines/tsage/ringworld2/ringworld2_scenes2.h @@ -186,6 +186,485 @@ public: virtual void signal(); }; +class Scene2430 : public SceneExt { + class Actor1 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + class Actor2 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + class Actor3 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + + class Exit1 : public SceneExit { + public: + virtual void changeScene(); + }; +public: + NamedHotspot _item1; + NamedHotspot _item2; + NamedHotspot _item3; + NamedHotspot _item4; + NamedHotspot _item5; + NamedHotspot _item6; + NamedHotspot _item7; + NamedHotspot _item8; + NamedHotspot _item9; + NamedHotspot _item10; + NamedHotspot _item11; + NamedHotspot _item12; + NamedHotspot _item13; + Actor1 _actor1; + Actor2 _actor2; + Actor3 _actor3; + Exit1 _exit1; + SequenceManager _sequenceManager; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + +class Scene2435 : public SceneExt { + class Actor1 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + class Actor2 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + + class Exit1 : public SceneExit { + public: + virtual void changeScene(); + }; +public: + SpeakerQuinn2435 _quinnSpeaker; + SpeakerSeeker2435 _seekerSpeaker; + SpeakerPharisha2435 _pharishaSpeaker; + NamedHotspot _item1; + NamedHotspot _item2; + NamedHotspot _item3; + Actor1 _actor1; + Actor2 _actor2; + Exit1 _exit1; + SequenceManager _sequenceManager; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void signal(); +}; + +class Scene2440 : public SceneExt { + class Actor1 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + class Actor2 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + + class Exit1 : public SceneExit { + public: + virtual void changeScene(); + }; +public: + NamedHotspot _item1; + NamedHotspot _item2; + NamedHotspot _item3; + NamedHotspot _item4; + NamedHotspot _item5; + NamedHotspot _item6; + NamedHotspot _item7; + Actor1 _actor1; + Actor2 _actor2; + Exit1 _exit1; + SequenceManager _sequenceManager; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void signal(); +}; + +class Scene2445 : public SceneExt { +public: + SequenceManager _sequenceManager; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + +class Scene2450 : public SceneExt { + class Actor2 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + class Actor3 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + + class Exit1 : public SceneExit { + public: + virtual void changeScene(); + }; +public: + SpeakerQuinn2450 _quinnSpeaker; + SpeakerSeeker2450 _seekerSpeaker; + SpeakerCaretaker2450 _caretakerSpeaker; + NamedHotspot _item1; + NamedHotspot _item2; + NamedHotspot _item3; + SceneActor _actor1; + Actor2 _actor2; + Actor3 _actor3; + Exit1 _exit1; + SequenceManager _sequenceManager; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void signal(); +}; + +class Scene2455 : public SceneExt { + class Actor1 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + class Actor2 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + class Actor3 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + + class Exit1 : public SceneExit { + public: + virtual void changeScene(); + }; +public: + NamedHotspot _item1; + Actor1 _actor1; + Actor2 _actor2; + Actor3 _actor3; + Exit1 _exit1; + SequenceManager _sequenceManager; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void signal(); +}; + +class Scene2500 : public SceneExt { + class Exit1 : public SceneExit { + public: + virtual void changeScene(); + }; +public: + SpeakerQuinn2500 _quinnSpeaker; + SpeakerSeeker2500 _seekerSpeaker; + SpeakerMiranda2500 _mirandaSpeaker; + SpeakerWebbster2500 _webbsterSpeaker; + NamedHotspot _item1; + SceneActor _actor1; + SceneActor _actor2; + SceneActor _actor3; + Exit1 _exit1; + SequenceManager _sequenceManager; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + +class Scene2525 : public SceneExt { + class Item5 : public NamedHotspot { + public: + virtual bool startAction(CursorType action, Event &event); + }; + + class Actor3 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + + class Exit1 : public SceneExit { + public: + virtual void changeScene(); + }; +public: + NamedHotspot _item1; + NamedHotspot _item2; + NamedHotspot _item3; + NamedHotspot _item4; + Item5 _item5; + SceneActor _actor1; + SceneActor _actor2; + Actor3 _actor3; + Exit1 _exit1; + SequenceManager _sequenceManager; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void signal(); +}; + +class Scene2530 : public SceneExt { + class Actor2 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + class Actor3 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + + class Exit1 : public SceneExit { + public: + virtual void changeScene(); + }; +public: + NamedHotspot _item1; + NamedHotspot _item2; + NamedHotspot _item3; + NamedHotspot _item4; + NamedHotspot _item5; + SceneActor _actor1; + Actor2 _actor2; + Actor3 _actor3; + Exit1 _exit1; + SequenceManager _sequenceManager; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + +class Scene2535 : public SceneExt { + class Actor3 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + class Actor4 : public SceneActor { + public: + bool startAction(CursorType action, Event &event); + }; + + class Exit1 : public SceneExit { + public: + virtual void changeScene(); + }; +public: + NamedHotspot _item1; + NamedHotspot _item2; + NamedHotspot _item3; + NamedHotspot _item4; + NamedHotspot _item5; + NamedHotspot _item6; + NamedHotspot _item7; + SceneActor _actor1; + SceneActor _actor2; + Actor3 _actor3; + Actor4 _actor4; + Exit1 _exit1; + SequenceManager _sequenceManager; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + +class Scene2600 : public SceneExt { +public: + SequenceManager _sequenceManager; + PaletteRotation *_rotation; + + Scene2600(); + virtual void synchronize(Serializer &s); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void signal(); +}; + +class Scene2700 : public SceneExt { + class Action1: public Action { + public: + void signal(); + }; + class Action2: public Action { + public: + void signal(); + }; + class Action3: public Action { + public: + void signal(); + }; + class Action4: public Action { + public: + void signal(); + }; + + class Area1: public SceneArea { + public: + void process(Event &event); + }; + class Area2: public SceneArea { + public: + void process(Event &event); + }; +public: + SpeakerQuinn2700 _quinnSpeaker; + SpeakerNej2700 _nejSpeaker; + NamedHotspot _item1; + NamedHotspot _item2; + NamedHotspot _item3; + NamedHotspot _item4; + NamedHotspot _item5; + NamedHotspot _item6; + SceneActor _actor1; + SceneActor _actor2; + SceneActor _actor3; + SceneActor _actor4; + SceneActor _actor5; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Area1 _area1; + Area2 _area2; + Rect _rect1, _rect2, _rect3, _rect4, _rect5, _rect6; + SequenceManager _sequenceManager; + int _field412, _field414, _field416; + + Scene2700(); + virtual void synchronize(Serializer &s); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void process(Event &event); +}; + +class Scene2750 : public SceneExt { + class Action1: public Action { + public: + void signal(); + }; + class Action2: public Action { + public: + void signal(); + }; + class Action3: public Action { + public: + void signal(); + }; + class Action4: public Action { + public: + void signal(); + }; + class Action5: public Action { + public: + void signal(); + }; + class Action6: public Action { + public: + void signal(); + }; + class Action7: public Action { + public: + void signal(); + }; + + class Area1: public SceneArea { + public: + void process(Event &event); + }; + class Area2: public SceneArea { + public: + void process(Event &event); + }; +public: + SpeakerQuinn2750 _quinnSpeaker; + SpeakerNej2750 _nejSpeaker; + NamedHotspot _item1; + NamedHotspot _item2; + NamedHotspot _item3; + NamedHotspot _item4; + NamedHotspot _item5; + SceneActor _actor1; + SceneActor _actor2; + SceneActor _actor3; + SceneActor _actor4; + SceneActor _actor5; + SceneActor _actor6; + SceneActor _actor7; + SceneActor _actor8; + SceneActor _actor9; + SceneActor _actor10; + SceneActor _actor11; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + Action7 _action7; + Area1 _area1; + Area2 _area2; + Rect _rect1, _rect2, _rect3; + SequenceManager _sequenceManager; + int _field412, _field414, _field416; + + Scene2750(); + virtual void synchronize(Serializer &s); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void process(Event &event); +}; + +class Scene2800 : public SceneExt { + class Item2 : public NamedHotspot { + public: + virtual bool startAction(CursorType action, Event &event); + }; + + class Actor1 : public SceneActor { + virtual bool startAction(CursorType action, Event &event); + }; + + class Action1: public Action { + public: + void signal(); + }; + class Action2: public Action { + SceneObject _object2; + SceneObject _object3; + SceneObject _object4; + public: + void signal(); + }; +public: + SpeakerQuinn2800 _quinnSpeaker; + SpeakerNej2800 _nejSpeaker; + SpeakerGuard2800 _guardSpeaker; + NamedHotspot _item1; + Item2 _item2; + Actor1 _actor1; + SceneActor _actor2; + SceneActor _actor3; + SceneObject _object1; + Action1 _action1; + Action2 _action2; + SequenceManager _sequenceManager; + int _field412; + + Scene2800(); + virtual void synchronize(Serializer &s); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.cpp b/engines/tsage/ringworld2/ringworld2_scenes3.cpp new file mode 100644 index 0000000000..22e58b6d2b --- /dev/null +++ b/engines/tsage/ringworld2/ringworld2_scenes3.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 "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" +#include "tsage/ringworld2/ringworld2_scenes3.h" + +namespace TsAGE { + +namespace Ringworld2 { + +/*-------------------------------------------------------------------------- + * Scene 3100 - + * + *--------------------------------------------------------------------------*/ +Scene3100::Scene3100() { + _field412 = 0; +} + +void Scene3100::synchronize(Serializer &s) { + SceneExt::synchronize(s); + + s.syncAsSint16LE(_field412); +} + +bool Scene3100::Actor6::startAction(CursorType action, Event &event) { + if (action != CURSOR_TALK) + return SceneActor::startAction(action, event); + + Scene3100 *scene = (Scene3100 *)R2_GLOBALS._sceneManager._scene; + + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 10; + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + scene->_stripManager.start(606, scene); + return true; +} + +void Scene3100::postInit(SceneObjectList *OwnerList) { + if (R2_GLOBALS._sceneManager._previousScene == 1000) { + if (R2_GLOBALS._player._oldCharacterScene[1] == 3100) { + loadScene(3101); + R2_GLOBALS._v58CE2 = 0; + } else { + loadScene(3100); + g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0)); + } + } else { + loadScene(3100); + } + // Original was doing it twice in a row. Skipped. + + if (R2_GLOBALS._sceneManager._previousScene == 3255) + R2_GLOBALS._v58CE2 = 0; + + SceneExt::postInit(); + _stripManager.addSpeaker(&_guardSpeaker); + + if (R2_GLOBALS._sceneManager._previousScene == -1) + R2_GLOBALS._sceneManager._previousScene = 1000; + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player._characterIndex = R2_QUINN; + R2_GLOBALS._player.disableControl(); + + _actor1.postInit(); + _item2.setDetails(Rect(212, 97, 320, 114), 3100, 3, -1, -1, 1, NULL); + _item1.setDetails(Rect(0, 0, 480, 200), 3100, 0, -1, -1, 1, NULL); + _field412 = 0; + + if (R2_GLOBALS._sceneManager._previousScene == 1000) { + if (R2_GLOBALS._player._oldCharacterScene[1] == 3100) { + _sceneMode = 3102; + _actor3.postInit(); + _actor4.postInit(); + _actor5.postInit(); + R2_GLOBALS._sound1.play(274); + _sound1.fadeSound(130); + setAction(&_sequenceManager, this, 3102, &_actor1, &R2_GLOBALS._player, &_actor3, &_actor4, &_actor5, NULL); + } else { + _actor6.postInit(); + _actor6.setup(3110, 5, 1); + _actor6.changeZoom(50); + _actor6.setPosition(Common::Point(10, 149)); + _actor6.setDetails(3100, 6, -1, -1, 2, NULL); + + _actor4.postInit(); + _actor4.setup(3103, 1, 1); + _actor4.setPosition(Common::Point(278, 113)); + _actor4.setDetails(3100, 9, -1, -1, 2, NULL); + _actor4.animate(ANIM_MODE_2, NULL); + + _field412 = 1; + _actor1.setDetails(3100, 3, -1, -1, 2, NULL); + R2_GLOBALS._sound1.play(243); + R2_GLOBALS._sound2.play(130); + _sceneMode = 3100; + + setAction(&_sequenceManager, this, 3100, &R2_GLOBALS._player, &_actor1, NULL); + } + } else if (R2_GLOBALS._sceneManager._previousScene == 3255) { + _sceneMode = 3101; + _actor2.postInit(); + _actor3.postInit(); + _field412 = 1; + + setAction(&_sequenceManager, this, 3101, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL); + } else { + _actor6.postInit(); + _actor6.setup(3110, 5, 1); + _actor6.changeZoom(50); + _actor6.setPosition(Common::Point(10, 149)); + _actor6.setDetails(3100, 6, -1, -1, 2, NULL); + + _actor4.postInit(); + _actor4.setup(3103, 1, 1); + _actor4.setPosition(Common::Point(278, 113)); + _actor4.setDetails(3100, 9, -1, -1, 2, NULL); + _actor4.animate(ANIM_MODE_2, NULL); + + _actor1.postInit(); + _actor1.setup(3104, 4, 1); + _actor1.setPosition(Common::Point(143, 104)); + _actor1.setDetails(3100, 3, -1, -1, 2, NULL); + + R2_GLOBALS._player.setup(3110, 3, 1); + R2_GLOBALS._player.changeZoom(50); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player.setPosition(Common::Point(160, 150)); + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + R2_GLOBALS._player.enableControl(CURSOR_ARROW); + + R2_GLOBALS._sound1.play(243); + } + + R2_GLOBALS._player._oldCharacterScene[1] = 3100; +} + +void Scene3100::remove() { + R2_GLOBALS._scrollFollower = &R2_GLOBALS._player; + R2_GLOBALS._sound1.fadeOut2(NULL); + R2_GLOBALS._sound2.fadeOut2(NULL); + _sound1.fadeOut2(NULL); + SceneExt::remove(); +} + +void Scene3100::signal() { + switch (_sceneMode) { + case 10: + warning("TODO: Unknown cursor used (6/-6)"); + R2_GLOBALS._player.enableControl(); + break; + case 3100: + R2_GLOBALS._player._moveDiff = Common::Point(3, 2); + R2_GLOBALS._scrollFollower = &R2_GLOBALS._player; + R2_GLOBALS._player.enableControl(CURSOR_ARROW); + break; + case 3101: + R2_GLOBALS._sceneManager.changeScene(1000); + break; + case 3102: + R2_GLOBALS._player._oldCharacterScene[1] = 1000; + R2_GLOBALS._sceneManager.changeScene(1000); + break; + default: + R2_GLOBALS._player.enableControl(CURSOR_ARROW); + break; + } +} + +void Scene3100::dispatch() { + if ((_sceneMode == 3100) && (_field412 != 0) && (R2_GLOBALS._player._position.y == 104)) { + _field412 = 0; + R2_GLOBALS._sound2.fadeOut2(NULL); + } + + if ((_sceneMode == 3101) && (_field412 != 0) && (R2_GLOBALS._player._position.y < 104)) { + _field412 = 0; + _sound1.fadeSound(130); + } + + Scene::dispatch(); +} + +} // End of namespace Ringworld2 +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.h b/engines/tsage/ringworld2/ringworld2_scenes3.h new file mode 100644 index 0000000000..fe00e2cf09 --- /dev/null +++ b/engines/tsage/ringworld2/ringworld2_scenes3.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 TSAGE_RINGWORLD2_SCENES3_H +#define TSAGE_RINGWORLD2_SCENES3_H + +#include "common/scummsys.h" +#include "tsage/converse.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/scenes.h" +#include "tsage/globals.h" +#include "tsage/sound.h" +#include "tsage/ringworld2/ringworld2_logic.h" +#include "tsage/ringworld2/ringworld2_speakers.h" + +namespace TsAGE { + +namespace Ringworld2 { + +using namespace TsAGE; + + +class Scene3100 : public SceneExt { + class Actor6 : public SceneActor { + virtual bool startAction(CursorType action, Event &event); + }; +public: + + int _field412; + SpeakerGuard3100 _guardSpeaker; + NamedHotspot _item1; + NamedHotspot _item2; + SceneActor _actor1; + SceneActor _actor2; + SceneActor _actor3; + SceneActor _actor4; + SceneActor _actor5; + Actor6 _actor6; + ASoundExt _sound1; + SequenceManager _sequenceManager; + + Scene3100(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void signal(); + virtual void dispatch(); + virtual void synchronize(Serializer &s); +}; + +} // End of namespace Ringworld2 +} // End of namespace TsAGE + +#endif diff --git a/engines/tsage/ringworld2/ringworld2_speakers.cpp b/engines/tsage/ringworld2/ringworld2_speakers.cpp index 2875652641..3ec1df41d0 100644 --- a/engines/tsage/ringworld2/ringworld2_speakers.cpp +++ b/engines/tsage/ringworld2/ringworld2_speakers.cpp @@ -26,6 +26,7 @@ #include "tsage/graphics.h" #include "tsage/staticres.h" #include "tsage/ringworld2/ringworld2_scenes0.h" +#include "tsage/ringworld2/ringworld2_scenes2.h" namespace TsAGE { @@ -109,7 +110,7 @@ void VisualSpeaker::setText(const Common::String &msg) { Common::String s = msg; if (s.hasPrefix("!")) { s.deleteChar(0); - _soundId = atoi(msg.c_str()); + _soundId = atoi(s.c_str()); while (!s.empty() && (*s.c_str() >= '0' && *s.c_str() <= '9')) s.deleteChar(0); @@ -122,20 +123,20 @@ void VisualSpeaker::setText(const Common::String &msg) { _sceneText._width = _textWidth; _sceneText._fontNumber = _fontNumber; _sceneText._textMode = _textMode; - _sceneText.setup(msg); + _sceneText.setup(s); //_sceneText.clone(); _sceneText.setPosition(_textPos); - _sceneText.setPriority(0x100); + _sceneText.fixPriority(256); // If subtitles are turned off, don't show the text - if (!(R2_GLOBALS._speechSubtitles & 1)) { + if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) { _sceneText.hide(); } // Figure out the text delay if subtitles are turned on, or there's no speech resource specified - if ((R2_GLOBALS._speechSubtitles & 1) || !_soundId) { + if ((R2_GLOBALS._speechSubtitles & SPEECH_TEXT) || !_soundId) { const char *msgP = s.c_str(); int numWords = 0; while (*msgP != '\0') { @@ -147,7 +148,7 @@ void VisualSpeaker::setText(const Common::String &msg) { ++numWords; _numFrames = numWords * 30 + 120; - setFrame(_numFrames); + setDelay(_numFrames); } else { _numFrames = 1; } @@ -158,10 +159,10 @@ void VisualSpeaker::setText(const Common::String &msg) { if (_fieldF6) { - if ((R2_GLOBALS._speechSubtitles & 1) || !_soundId) + if ((R2_GLOBALS._speechSubtitles & SPEECH_TEXT) || !_soundId) _sceneText.hide(); } else { - if ((R2_GLOBALS._speechSubtitles & 2) && _soundId) { + if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) && _soundId) { if (!R2_GLOBALS._playStream.play(_soundId, NULL)) _sceneText.show(); } @@ -184,6 +185,11 @@ void VisualSpeaker::setFrame(int numFrames) { _frameNumber = R2_GLOBALS._events.getFrameNumber(); } +void VisualSpeaker::setDelay(int delay) { + _delayAmount = delay; + _frameNumber = R2_GLOBALS._events.getFrameNumber(); +} + /*--------------------------------------------------------------------------*/ SpeakerMiranda300::SpeakerMiranda300(): VisualSpeaker() { @@ -482,6 +488,569 @@ SpeakerPharisha2350::SpeakerPharisha2350(): VisualSpeaker() { _numFrames = 0; } -} // End of namespace Ringworld2 +/*--------------------------------------------------------------------------*/ + +SpeakerQuinn2435::SpeakerQuinn2435() { + _speakerName = "QUINN"; + _color1 = 60; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} +void SpeakerQuinn2435::proc15() { + int v = _fieldF6; + + if (!_object2) { + if (R2_GLOBALS._player._characterIndex == 1) { + _object2 = &R2_GLOBALS._player; + } else { + Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene; + _object2 = &scene->_actor1; + } + + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + _object2->setStrip(7); + _object1.setup(2020, 5, 1); + _object1.animate(ANIM_MODE_5, this); + } +} + +SpeakerSeeker2435::SpeakerSeeker2435() { + _speakerName = "SEEKER"; + _color1 = 35; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerSeeker2435::proc15() { + int v = _fieldF6; + + if (!_object2) { + if (R2_GLOBALS._player._characterIndex == 2) { + _object2 = &R2_GLOBALS._player; + } else { + Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene; + _object2 = &scene->_actor1; + } + + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + _object2->setStrip(7); + _object1.setup(4099, 1, 1); + _object1.animate(ANIM_MODE_5, this); + } +} + +SpeakerPharisha2435::SpeakerPharisha2435() { + _speakerName = "PHARISHA"; + _color1 = 151; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerPharisha2435::proc15() { + int v = _fieldF6; + Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene; + + if (!_object2) { + _object2 = &scene->_actor2; + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + _object1.setup(4098, 5, 1); + _object1.animate(ANIM_MODE_5, this); + } +} + +/*--------------------------------------------------------------------------*/ + +SpeakerQuinn2450::SpeakerQuinn2450() { + _speakerName = "QUINN"; + _color1 = 60; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} +void SpeakerQuinn2450::proc15() { + int v = _fieldF6; + + if (!_object2) { + if (R2_GLOBALS._player._characterIndex == 1) { + _object2 = &R2_GLOBALS._player; + } else { + Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene; + _object2 = &scene->_actor1; + } + + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + if (R2_GLOBALS.getFlag(61)) + _object1.setup(2020, 3, 1); + else + _object1.setup(2020, 1, 1); + _object1.animate(ANIM_MODE_5, this); + } +} + +SpeakerSeeker2450::SpeakerSeeker2450() { + _speakerName = "SEEKER"; + _color1 = 35; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerSeeker2450::proc15() { + int v = _fieldF6; + + if (!_object2) { + if (R2_GLOBALS._player._characterIndex == 2) { + _object2 = &R2_GLOBALS._player; + } else { + Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene; + _object2 = &scene->_actor1; + } + + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + _object1.setup(4099, 3, 1); + _object1.animate(ANIM_MODE_5, this); + } +} + +SpeakerCaretaker2450::SpeakerCaretaker2450() { + _speakerName = "CARETAKER"; + _color1 = 43; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerQuinn2500::SpeakerQuinn2500() { + _speakerName = "QUINN"; + _color1 = 60; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +SpeakerSeeker2500::SpeakerSeeker2500() { + _speakerName = "SEEKER"; + _color1 = 35; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +SpeakerMiranda2500::SpeakerMiranda2500() { + // Not in uppercase in the original + _speakerName = "Miranda"; + _color1 = 154; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +SpeakerWebbster2500::SpeakerWebbster2500() { + // Not in uppercase in the original + _speakerName = "Webbster"; + _color1 = 27; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +SpeakerQuinn2700::SpeakerQuinn2700() { + _speakerName = "QUINN"; + _color1 = 60; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerQuinn2700::proc15() { + int v = _fieldF6; + + if (!_object2) { + _object2 = &R2_GLOBALS._player; + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + switch (_object2->_visage) { + case 19: + _object1.setup(4022, 5, 1); + break; + case 2701: + _object1.setup(4022, 1, 1); + break; + default: + break; + } + _object1.animate(ANIM_MODE_5, this); + } +} + +SpeakerNej2700::SpeakerNej2700() { + _speakerName = "NEJ"; + _color1 = 171; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerNej2700::proc15() { + int v = _fieldF6; + Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene; + + if (!_object2) { + _object2 = &scene->_actor1; + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + switch (_object2->_visage) { + case 2701: + _object1.setup(4022, 3, 1); + _object1.setPosition(Common::Point(164, 163)); + _object2->setPosition(Common::Point(-10, -10)); + break; + case 2705: + _object1.setup(4022, 7, 1); + _object1.fixPriority(162); + break; + default: + break; + } + _object1.animate(ANIM_MODE_5, this); + } +} + +SpeakerQuinn2750::SpeakerQuinn2750() { + _speakerName = "QUINN"; + _color1 = 60; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerQuinn2750::proc15() { + int v = _fieldF6; + + if (!_object2) { + _object2 = &R2_GLOBALS._player; + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + switch (_object2->_visage) { + case 19: + _object1.setup(4022, 5, 1); + break; + case 2752: + _object1.setup(2752, 1, 1); + break; + default: + break; + } + _object1.animate(ANIM_MODE_5, this); + } +} + +SpeakerNej2750::SpeakerNej2750() { + _speakerName = "NEJ"; + _color1 = 171; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerNej2750::proc15() { + int v = _fieldF6; + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + + if (!_object2) { + _object2 = &scene->_actor1; + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + switch (_object2->_visage) { + case 2705: + _object1.setup(4022, 7, 1); + break; + case 2752: + _object1.setup(2752, 1, 1); + break; + default: + break; + } + _object1.animate(ANIM_MODE_5, this); + } +} + +SpeakerQuinn2800::SpeakerQuinn2800() { + _speakerName = "QUINN"; + _color1 = 60; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerQuinn2800::proc15() { + int v = _fieldF6; + + if (!_object2) { + _object2 = &R2_GLOBALS._player; + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + switch (_object2->_visage) { + case 16: + _object1.setZoom(75); + _object1.setup(4023, 5, 1); + break; + case 19: + _object1.setup(4023, 1, 1); + break; + case 3110: + _object1.setZoom(75); + if (_object2->_strip == 1) + _object1.setup(4061 , 1, 1); + else + _object1.setup(4061 , 3, 1); + break; + default: + break; + } + _object1.animate(ANIM_MODE_5, this); + } +} + +SpeakerNej2800::SpeakerNej2800() { + _speakerName = "NEJ"; + _color1 = 171; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerNej2800::proc15() { + int v = _fieldF6; + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + + if (!_object2) { + _object2 = &scene->_actor2; + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + _object1.setup(4023, 3, 1); + if (_object2->_visage == 2801) + _object1.setPosition(Common::Point(R2_GLOBALS._player._position.x - 12, R2_GLOBALS._player._position.y)); + _object1.animate(ANIM_MODE_5, this); + } +} + +SpeakerGuard2800::SpeakerGuard2800() { + _speakerName = "GUARD"; + _color1 = 5; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerGuard2800::proc15() { + int v = _fieldF6; + Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; + + if (!_object2) { + _object2 = &scene->_actor1; + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + _object1.setZoom(75); + _object1.setup(4060, 3, 1); + _object1.animate(ANIM_MODE_5, this); + } +} + +SpeakerGuard3100::SpeakerGuard3100() { + _speakerName = "GUARD"; + _color1 = 5; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +} // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_speakers.h b/engines/tsage/ringworld2/ringworld2_speakers.h index 5793f4377e..1d99a54e7c 100644 --- a/engines/tsage/ringworld2/ringworld2_speakers.h +++ b/engines/tsage/ringworld2/ringworld2_speakers.h @@ -59,6 +59,8 @@ public: virtual void setText(const Common::String &msg); virtual void proc15() {} virtual void proc16(); + + void setDelay(int delay); }; class SpeakerMiranda300 : public VisualSpeaker { @@ -129,6 +131,143 @@ public: virtual Common::String getClassName() { return "SpeakerPharisha2350"; } }; +class SpeakerQuinn2435 : public VisualSpeaker { +public: + SpeakerQuinn2435(); + + virtual Common::String getClassName() { return "SpeakerQuinn2435"; } + virtual void proc15(); +}; + +class SpeakerSeeker2435 : public VisualSpeaker { +public: + SpeakerSeeker2435(); + + virtual Common::String getClassName() { return "SpeakerSeeker2435"; } + virtual void proc15(); +}; + +class SpeakerPharisha2435 : public VisualSpeaker { +public: + SpeakerPharisha2435(); + + virtual Common::String getClassName() { return "SpeakerPharisha2435"; } + virtual void proc15(); +}; + +class SpeakerQuinn2450 : public VisualSpeaker { +public: + SpeakerQuinn2450(); + + virtual Common::String getClassName() { return "SpeakerQuinn2450"; } + virtual void proc15(); +}; + +class SpeakerSeeker2450 : public VisualSpeaker { +public: + SpeakerSeeker2450(); + + virtual Common::String getClassName() { return "SpeakerSeeker2450"; } + virtual void proc15(); +}; + +class SpeakerCaretaker2450 : public VisualSpeaker { +public: + SpeakerCaretaker2450(); + + virtual Common::String getClassName() { return "SpeakerCaretaker2450"; } +}; + +class SpeakerQuinn2500 : public VisualSpeaker { +public: + SpeakerQuinn2500(); + + virtual Common::String getClassName() { return "SpeakerQuinn2500"; } +}; + +class SpeakerSeeker2500 : public VisualSpeaker { +public: + SpeakerSeeker2500(); + + virtual Common::String getClassName() { return "SpeakerSeeker2500"; } +}; + +class SpeakerMiranda2500 : public VisualSpeaker { +public: + SpeakerMiranda2500(); + + virtual Common::String getClassName() { return "SpeakerMiranda2500"; } +}; + +class SpeakerWebbster2500 : public VisualSpeaker { +public: + SpeakerWebbster2500(); + + virtual Common::String getClassName() { return "SpeakerWebbster2500"; } +}; + +class SpeakerQuinn2700 : public VisualSpeaker { +public: + SpeakerQuinn2700(); + + virtual Common::String getClassName() { return "SpeakerQuinn2700"; } + virtual void proc15(); +}; + +class SpeakerNej2700 : public VisualSpeaker { +public: + SpeakerNej2700(); + + virtual Common::String getClassName() { return "SpeakerNej2700"; } + virtual void proc15(); +}; + +class SpeakerQuinn2750 : public VisualSpeaker { +public: + SpeakerQuinn2750(); + + virtual Common::String getClassName() { return "SpeakerQuinn2750"; } + virtual void proc15(); +}; + +class SpeakerNej2750 : public VisualSpeaker { +public: + SpeakerNej2750(); + + virtual Common::String getClassName() { return "SpeakerNej2750"; } + virtual void proc15(); +}; + +class SpeakerQuinn2800 : public VisualSpeaker { +public: + SpeakerQuinn2800(); + + virtual Common::String getClassName() { return "SpeakerQuinn2800"; } + virtual void proc15(); +}; + +class SpeakerNej2800 : public VisualSpeaker { +public: + SpeakerNej2800(); + + virtual Common::String getClassName() { return "SpeakerNej2800"; } + virtual void proc15(); +}; + +class SpeakerGuard2800 : public VisualSpeaker { +public: + SpeakerGuard2800(); + + virtual Common::String getClassName() { return "SpeakerGuard2800"; } + virtual void proc15(); +}; + +class SpeakerGuard3100 : public VisualSpeaker { +public: + SpeakerGuard3100(); + + virtual Common::String getClassName() { return "SpeakerGuard3100"; } +}; } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp index 6362c63bc3..03c7d8d0ae 100644 --- a/engines/tsage/scenes.cpp +++ b/engines/tsage/scenes.cpp @@ -133,7 +133,7 @@ void SceneManager::fadeInIfNecessary() { percent = 100; g_globals->_scenePalette.fade((const byte *)&adjustData, false, percent); - g_system->updateScreen(); + GLOBALS._screenSurface.copyToScreen(); g_system->delayMillis(10); } diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 87706a36f5..e98f4aa761 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -493,7 +493,6 @@ protected: uint32 _dynamicData; /**< Dynamic data from the GUI Theme that modifies the drawing of the current shape */ int _gradientFactor; /**< Multiplication factor of the active gradient */ - int _gradientBytes[3]; /**< Color bytes of the active gradient, used to speed up calculation */ }; } // End of namespace Graphics diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index 1bd07af237..b5dc129e3c 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -224,17 +224,6 @@ VectorRenderer *createRenderer(int mode) { } template<typename PixelType> -void VectorRendererSpec<PixelType>:: -setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) { - _gradientEnd = _format.RGBToColor(r2, g2, b2); - _gradientStart = _format.RGBToColor(r1, g1, b1); - - Base::_gradientBytes[0] = (_gradientEnd & _redMask) - (_gradientStart & _redMask); - Base::_gradientBytes[1] = (_gradientEnd & _greenMask) - (_gradientStart & _greenMask); - Base::_gradientBytes[2] = (_gradientEnd & _blueMask) - (_gradientStart & _blueMask); -} - -template<typename PixelType> VectorRendererSpec<PixelType>:: VectorRendererSpec(PixelFormat format) : _format(format), @@ -246,6 +235,93 @@ VectorRendererSpec(PixelFormat format) : _bitmapAlphaColor = _format.RGBToColor(255, 0, 255); } +/**************************** + * Gradient-related methods * + ****************************/ + +template<typename PixelType> +void VectorRendererSpec<PixelType>:: +setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) { + _gradientEnd = _format.RGBToColor(r2, g2, b2); + _gradientStart = _format.RGBToColor(r1, g1, b1); + + _gradientBytes[0] = (_gradientEnd & _redMask) - (_gradientStart & _redMask); + _gradientBytes[1] = (_gradientEnd & _greenMask) - (_gradientStart & _greenMask); + _gradientBytes[2] = (_gradientEnd & _blueMask) - (_gradientStart & _blueMask); +} + +template<typename PixelType> +inline PixelType VectorRendererSpec<PixelType>:: +calcGradient(uint32 pos, uint32 max) { + PixelType output = 0; + pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max; + + output |= ((_gradientStart & _redMask) + ((_gradientBytes[0] * pos) >> 12)) & _redMask; + output |= ((_gradientStart & _greenMask) + ((_gradientBytes[1] * pos) >> 12)) & _greenMask; + output |= ((_gradientStart & _blueMask) + ((_gradientBytes[2] * pos) >> 12)) & _blueMask; + output |= _alphaMask; + + return output; +} + +template<typename PixelType> +void VectorRendererSpec<PixelType>:: +precalcGradient(int h) { + PixelType prevcolor = 0, color; + + _gradCache.resize(0); + _gradIndexes.resize(0); + + for (int i = 0; i < h + 2; i++) { + color = calcGradient(i, h); + if (color != prevcolor || i == 0 || i > h - 1) { + prevcolor = color; + _gradCache.push_back(color); + _gradIndexes.push_back(i); + } + } +} + +template<typename PixelType> +void VectorRendererSpec<PixelType>:: +gradientFill(PixelType *ptr, int width, int x, int y) { + bool ox = ((y & 1) == 1); + int stripSize; + int curGrad = 0; + + while (_gradIndexes[curGrad + 1] <= y) + curGrad++; + + stripSize = _gradIndexes[curGrad + 1] - _gradIndexes[curGrad]; + + int grad = (((y - _gradIndexes[curGrad]) % stripSize) << 2) / stripSize; + + // Dithering: + // +--+ +--+ +--+ +--+ + // | | | | | *| | *| + // | | | *| |* | |**| + // +--+ +--+ +--+ +--+ + // 0 1 2 3 + if (grad == 0 || + _gradCache[curGrad] == _gradCache[curGrad + 1] || // no color change + stripSize < 2) { // the stip is small + colorFill<PixelType>(ptr, ptr + width, _gradCache[curGrad]); + } else if (grad == 3 && ox) { + colorFill<PixelType>(ptr, ptr + width, _gradCache[curGrad + 1]); + } else { + for (int j = x; j < x + width; j++, ptr++) { + bool oy = ((j & 1) == 1); + + if ((ox && oy) || + ((grad == 2 || grad == 3) && ox && !oy) || + (grad == 3 && oy)) + *ptr = _gradCache[curGrad + 1]; + else + *ptr = _gradCache[curGrad]; + } + } +} + template<typename PixelType> void VectorRendererSpec<PixelType>:: fillSurface() { @@ -259,9 +335,11 @@ fillSurface() { } else if (Base::_fillMode == kFillForeground) { colorFill<PixelType>((PixelType *)ptr, (PixelType *)(ptr + pitch * h), _fgColor); } else if (Base::_fillMode == kFillGradient) { - int i = h; - while (i--) { - colorFill<PixelType>((PixelType *)ptr, (PixelType *)(ptr + pitch), calcGradient(h - i, h)); + precalcGradient(h); + + for (int i = 0; i < h; i++) { + gradientFill((PixelType *)ptr, _activeSurface->w, 0, i); + ptr += pitch; } } @@ -413,20 +491,6 @@ blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) { (((int)(idst & _alphaMask) * alpha) >> 8)))); } -template<typename PixelType> -inline PixelType VectorRendererSpec<PixelType>:: -calcGradient(uint32 pos, uint32 max) { - PixelType output = 0; - pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max; - - output |= ((_gradientStart & _redMask) + ((Base::_gradientBytes[0] * pos) >> 12)) & _redMask; - output |= ((_gradientStart & _greenMask) + ((Base::_gradientBytes[1] * pos) >> 12)) & _greenMask; - output |= ((_gradientStart & _blueMask) + ((Base::_gradientBytes[2] * pos) >> 12)) & _blueMask; - output |= _alphaMask; - - return output; -} - /******************************************************************** ******************************************************************** * Primitive shapes drawing - Public API calls - VectorRendererSpec * @@ -816,6 +880,8 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer: } else { BE_RESET(); + precalcGradient(long_h); + PixelType color1, color2; color1 = color2 = color; @@ -825,22 +891,32 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer: if (fill_m == kFillGradient) { color1 = calcGradient(real_radius - x, long_h); color2 = calcGradient(real_radius - y, long_h); - } - colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color2); - colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color1); + gradientFill(ptr_tl - x - py, w - 2 * r + 2 * x, x1 + r - x - y, real_radius - y); + gradientFill(ptr_tl - y - px, w - 2 * r + 2 * y, x1 + r - y - x, real_radius - x); + + *(ptr_tr + (y) - (px)) = color1; + *(ptr_tr + (x) - (py)) = color2; + *(ptr_tl - (x) - (py)) = color2; + *(ptr_tl - (y) - (px)) = color1; + } else { + colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color); + colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color); - *(ptr_tr + (y) - (px)) = color1; - *(ptr_tr + (x) - (py)) = color2; - *(ptr_tl - (x) - (py)) = color2; - *(ptr_tl - (y) - (px)) = color1; + *(ptr_tr + (y) - (px)) = color; + *(ptr_tr + (x) - (py)) = color; + *(ptr_tl - (x) - (py)) = color; + *(ptr_tl - (y) - (px)) = color; + } } ptr_fill += pitch * r; while (short_h--) { - if (fill_m == kFillGradient) - color = calcGradient(real_radius++, long_h); - colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color); + if (fill_m == kFillGradient) { + gradientFill(ptr_fill, w + 1, x1, real_radius++); + } else { + colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color); + } ptr_fill += pitch; } } @@ -1326,6 +1402,8 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto PixelType color1, color2, color3, color4; if (fill_m == kFillGradient) { + precalcGradient(long_h); + while (x++ < y) { BE_ALGORITHM(); @@ -1334,11 +1412,11 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto color3 = calcGradient(long_h - r + x, long_h); color4 = calcGradient(long_h - r + y, long_h); - colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color2); - colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color1); + gradientFill(ptr_tl - x - py, w - 2 * r + 2 * x, x1 + r - x - y, real_radius - y); + gradientFill(ptr_tl - y - px, w - 2 * r + 2 * y, x1 + r - y - x, real_radius - x); - colorFill<PixelType>(ptr_bl - x + py, ptr_br + x + py, color4); - colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color3); + gradientFill(ptr_bl - x + py, w - 2 * r + 2 * x, x1 + r - x - y, long_h - r + y); + gradientFill(ptr_bl - y + px, w - 2 * r + 2 * y, x1 + r - y - x, long_h - r + x); BE_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py); } @@ -1359,9 +1437,11 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto ptr_fill += pitch * r; while (short_h--) { - if (fill_m == kFillGradient) - color = calcGradient(real_radius++, long_h); - colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color); + if (fill_m == kFillGradient) { + gradientFill(ptr_fill, w + 1, x1, real_radius++); + } else { + colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color); + } ptr_fill += pitch; } } diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h index 3ba7d88e4e..fe64f9774d 100644 --- a/graphics/VectorRendererSpec.h +++ b/graphics/VectorRendererSpec.h @@ -185,6 +185,9 @@ protected: */ inline PixelType calcGradient(uint32 pos, uint32 max); + void precalcGradient(int h); + void gradientFill(PixelType *first, int width, int x, int y); + /** * Fills several pixels in a row with a given color and the specified alpha blending. * @@ -208,6 +211,11 @@ protected: PixelType _gradientStart; /**< Start color for the fill gradient */ PixelType _gradientEnd; /**< End color for the fill gradient */ + int _gradientBytes[3]; /**< Color bytes of the active gradient, used to speed up calculation */ + + Common::Array<PixelType> _gradCache; + Common::Array<int> _gradIndexes; + PixelType _bevelColor; PixelType _bitmapAlphaColor; }; diff --git a/gui/credits.h b/gui/credits.h index 08be2e0534..dd839c2c3b 100644 --- a/gui/credits.h +++ b/gui/credits.h @@ -39,6 +39,7 @@ static const char *credits[] = { "C0""Pawel Kolodziejski", "C2""Codecs, iMUSE, Smush, etc.", "C0""Gregory Montoir", +"C2""(retired)", "C0""Eugene Sandulenko", "C2""FT INSANE, MM NES, MM C64, game detection, Herc/CGA", "C0""Ludvig Strigeus", @@ -49,6 +50,7 @@ static const char *credits[] = { "C2""(retired)", "C0""Travis Howell", "C0""Gregory Montoir", +"C2""(retired)", "C0""Eugene Sandulenko", "", "C1""AGI", @@ -81,6 +83,7 @@ static const char *credits[] = { "C2""(retired)", "C0""Pawel Kolodziejski", "C0""Gregory Montoir", +"C2""(retired)", "C0""Kari Salminen", "C0""Eugene Sandulenko", "", @@ -128,6 +131,7 @@ static const char *credits[] = { "C0""Oystein Eftevaag", "C0""Florian Kagerer", "C0""Gregory Montoir", +"C2""(retired)", "C0""Johannes Schickel", "", "C1""Lastexpress", @@ -157,6 +161,7 @@ static const char *credits[] = { "C0""David Eriksson", "C2""(retired)", "C0""Gregory Montoir", +"C2""(retired)", "C0""Joost Peters", "", "C1""SAGA", @@ -230,6 +235,7 @@ static const char *credits[] = { "", "C1""Touch\351", "C0""Gregory Montoir", +"C2""(retired)", "", "C1""TsAGE", "C0""Arnaud Boutonn\351", @@ -237,6 +243,7 @@ static const char *credits[] = { "", "C1""Tucker", "C0""Gregory Montoir", +"C2""(retired)", "", "", "C1""Backend Teams", diff --git a/gui/options.cpp b/gui/options.cpp index dfa30d1e3e..4fa5a821fb 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -1033,22 +1033,6 @@ void OptionsDialog::saveMusicDeviceSetting(PopUpWidget *popup, Common::String se ConfMan.removeKey(setting, _domain); } -ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd) { - ButtonWidget *button; - -#ifndef DISABLE_FANCY_THEMES - if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) { - button = new PicButtonWidget(boss, name, _("Clear value"), cmd); - ((PicButtonWidget *)button)->useThemeTransparency(true); - ((PicButtonWidget *)button)->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageEraser)); - } else -#endif - button = new ButtonWidget(boss, name, "C", _("Clear value"), cmd); - - return button; -} - - int OptionsDialog::getSubtitleMode(bool subtitles, bool speech_mute) { if (_guioptions.contains(GUIO_NOSUBTITLES)) return kSubtitlesSpeech; // Speech only diff --git a/gui/options.h b/gui/options.h index 479f836ec0..92ce3e5df4 100644 --- a/gui/options.h +++ b/gui/options.h @@ -43,8 +43,6 @@ class GuiObject; class RadiobuttonGroup; class RadiobuttonWidget; -ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd); - class OptionsDialog : public Dialog { public: OptionsDialog(const Common::String &domain, int x, int y, int w, int h); diff --git a/gui/widget.cpp b/gui/widget.cpp index d11ebda821..82007c588f 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -23,6 +23,7 @@ #include "common/system.h" #include "common/rect.h" #include "common/textconsole.h" +#include "common/translation.h" #include "graphics/pixelformat.h" #include "gui/widget.h" #include "gui/gui-manager.h" @@ -302,6 +303,27 @@ void ButtonWidget::setLabel(const Common::String &label) { StaticTextWidget::setLabel(cleanupHotkey(label)); } +ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd, int x, int y, int w, int h) { + ButtonWidget *button; + +#ifndef DISABLE_FANCY_THEMES + if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) { + if (!name.empty()) + button = new PicButtonWidget(boss, name, _("Clear value"), cmd); + else + button = new PicButtonWidget(boss, x, y, w, h, _("Clear value"), cmd); + ((PicButtonWidget *)button)->useThemeTransparency(true); + ((PicButtonWidget *)button)->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageEraser)); + } else +#endif + if (!name.empty()) + button = new ButtonWidget(boss, name, "C", _("Clear value"), cmd); + else + button = new ButtonWidget(boss, x, y, w, h, "C", _("Clear value"), cmd); + + return button; +} + #pragma mark - PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey) diff --git a/gui/widget.h b/gui/widget.h index 428ab7981e..789fc09231 100644 --- a/gui/widget.h +++ b/gui/widget.h @@ -354,6 +354,8 @@ protected: void drawWidget(); }; +ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd, int x=0, int y=0, int w=0, int h=0); + } // End of namespace GUI #endif diff --git a/po/POTFILES b/po/POTFILES index 14ab5688ff..9898958222 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -13,6 +13,7 @@ gui/options.cpp gui/saveload.cpp gui/themebrowser.cpp gui/ThemeEngine.cpp +gui/widget.cpp base/main.cpp diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp index 74bf533e62..4a57ac405d 100644 --- a/video/qt_decoder.cpp +++ b/video/qt_decoder.cpp @@ -56,155 +56,42 @@ namespace Video { //////////////////////////////////////////// QuickTimeDecoder::QuickTimeDecoder() { - _curFrame = -1; - _startTime = _nextFrameStartTime = 0; + _setStartTime = false; _audHandle = Audio::SoundHandle(); _scaledSurface = 0; _dirtyPalette = false; _palette = 0; + _width = _height = 0; + _needUpdate = false; } QuickTimeDecoder::~QuickTimeDecoder() { close(); } -uint16 QuickTimeDecoder::getWidth() const { - if (_videoTrackIndex < 0) - return 0; - - return (Common::Rational(_tracks[_videoTrackIndex]->width) / getScaleFactorX()).toInt(); -} - -uint16 QuickTimeDecoder::getHeight() const { - if (_videoTrackIndex < 0) - return 0; - - return (Common::Rational(_tracks[_videoTrackIndex]->height) / getScaleFactorY()).toInt(); -} - -uint32 QuickTimeDecoder::getFrameCount() const { - if (_videoTrackIndex < 0) - return 0; - - return _tracks[_videoTrackIndex]->frameCount; -} - -Common::Rational QuickTimeDecoder::getScaleFactorX() const { - if (_videoTrackIndex < 0) - return 1; - - return (_scaleFactorX * _tracks[_videoTrackIndex]->scaleFactorX); -} - -Common::Rational QuickTimeDecoder::getScaleFactorY() const { - if (_videoTrackIndex < 0) - return 1; +int32 QuickTimeDecoder::getCurFrame() const { + // TODO: This is rather simplistic and doesn't take edits that + // repeat sections of the media into account. Doing that + // over-complicates things and shouldn't be necessary, but + // it would be nice to have in the future. - return (_scaleFactorY * _tracks[_videoTrackIndex]->scaleFactorY); -} + int32 frame = -1; -uint32 QuickTimeDecoder::getFrameDuration() { - if (_videoTrackIndex < 0) - return 0; + for (uint32 i = 0; i < _handlers.size(); i++) + if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo) + frame += ((VideoTrackHandler *)_handlers[i])->getCurFrame() + 1; - uint32 curFrameIndex = 0; - for (int32 i = 0; i < _tracks[_videoTrackIndex]->timeToSampleCount; i++) { - curFrameIndex += _tracks[_videoTrackIndex]->timeToSample[i].count; - if ((uint32)_curFrame < curFrameIndex) { - // Ok, now we have what duration this frame has. - return _tracks[_videoTrackIndex]->timeToSample[i].duration; - } - } - - // This should never occur - error ("Cannot find duration for frame %d", _curFrame); - return 0; -} - -Graphics::PixelFormat QuickTimeDecoder::getPixelFormat() const { - Codec *codec = findDefaultVideoCodec(); - - if (!codec) - return Graphics::PixelFormat::createFormatCLUT8(); - - return codec->getPixelFormat(); -} - -uint32 QuickTimeDecoder::findKeyFrame(uint32 frame) const { - for (int i = _tracks[_videoTrackIndex]->keyframeCount - 1; i >= 0; i--) - if (_tracks[_videoTrackIndex]->keyframes[i] <= frame) - return _tracks[_videoTrackIndex]->keyframes[i]; - - // If none found, we'll assume the requested frame is a key frame return frame; } -void QuickTimeDecoder::seekToFrame(uint32 frame) { - assert(_videoTrackIndex >= 0); - assert(frame < _tracks[_videoTrackIndex]->frameCount); - - // Stop all audio (for now) - stopAudio(); - - // Track down the keyframe - _curFrame = findKeyFrame(frame) - 1; - while (_curFrame < (int32)frame - 1) - decodeNextFrame(); - - // Map out the starting point - _nextFrameStartTime = 0; - uint32 curFrame = 0; - - for (int32 i = 0; i < _tracks[_videoTrackIndex]->timeToSampleCount && curFrame < frame; i++) { - for (int32 j = 0; j < _tracks[_videoTrackIndex]->timeToSample[i].count && curFrame < frame; j++) { - curFrame++; - _nextFrameStartTime += _tracks[_videoTrackIndex]->timeToSample[i].duration; - } - } - - // Adjust the video starting point - const Audio::Timestamp curVideoTime(0, _nextFrameStartTime, _tracks[_videoTrackIndex]->timeScale); - _startTime = g_system->getMillis() - curVideoTime.msecs(); - resetPauseStartTime(); - - // Adjust the audio starting point - if (_audioTrackIndex >= 0) { - _audioStartOffset = curVideoTime; - - // Seek to the new audio location - setAudioStreamPos(_audioStartOffset); - - // Restart the audio - startAudio(); - - // Pause the audio again if we're still paused - if (isPaused() && _audStream) - g_system->getMixer()->pauseHandle(_audHandle, true); - } -} - -void QuickTimeDecoder::seekToTime(Audio::Timestamp time) { - // Use makeQuickTimeStream() instead - if (_videoTrackIndex < 0) - error("Audio-only seeking not supported"); - - // Try to find the last frame that should have been decoded - uint32 frame = 0; - Audio::Timestamp totalDuration(0, _tracks[_videoTrackIndex]->timeScale); - bool done = false; +uint32 QuickTimeDecoder::getFrameCount() const { + uint32 count = 0; - for (int32 i = 0; i < _tracks[_videoTrackIndex]->timeToSampleCount && !done; i++) { - for (int32 j = 0; j < _tracks[_videoTrackIndex]->timeToSample[i].count; j++) { - totalDuration = totalDuration.addFrames(_tracks[_videoTrackIndex]->timeToSample[i].duration); - if (totalDuration > time) { - done = true; - break; - } - frame++; - } - } + for (uint32 i = 0; i < _handlers.size(); i++) + if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo) + count += ((VideoTrackHandler *)_handlers[i])->getFrameCount(); - seekToFrame(frame); + return count; } void QuickTimeDecoder::startAudio() { @@ -224,98 +111,109 @@ void QuickTimeDecoder::pauseVideoIntern(bool pause) { g_system->getMixer()->pauseHandle(_audHandle, pause); } -Codec *QuickTimeDecoder::findDefaultVideoCodec() const { - if (_videoTrackIndex < 0 || _tracks[_videoTrackIndex]->sampleDescs.empty()) - return 0; +QuickTimeDecoder::VideoTrackHandler *QuickTimeDecoder::findNextVideoTrack() const { + VideoTrackHandler *bestTrack = 0; + int32 num; + uint32 bestTime = 0xffffffff; + + for (uint32 i = 0; i < _handlers.size(); i++) { + if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo && !_handlers[i]->endOfTrack()) { + VideoTrackHandler *track = (VideoTrackHandler *)_handlers[i]; + uint32 time = track->getNextFrameStartTime(); + + if (time < bestTime) { + bestTime = time; + bestTrack = track; + num = i; + } + } + } - return ((VideoSampleDesc *)_tracks[_videoTrackIndex]->sampleDescs[0])->_videoCodec; + return bestTrack; } const Graphics::Surface *QuickTimeDecoder::decodeNextFrame() { - if (_videoTrackIndex < 0 || _curFrame >= (int32)getFrameCount() - 1) + if (!_nextVideoTrack) return 0; - if (_startTime == 0) - _startTime = g_system->getMillis(); - - _curFrame++; - _nextFrameStartTime += getFrameDuration(); - - // Update the audio while we're at it - updateAudioBuffer(); - - // Get the next packet - uint32 descId; - Common::SeekableReadStream *frameData = getNextFramePacket(descId); - - if (!frameData || !descId || descId > _tracks[_videoTrackIndex]->sampleDescs.size()) - return 0; + const Graphics::Surface *frame = _nextVideoTrack->decodeNextFrame(); - // Find which video description entry we want - VideoSampleDesc *entry = (VideoSampleDesc *)_tracks[_videoTrackIndex]->sampleDescs[descId - 1]; + if (!_setStartTime) { + _startTime = g_system->getMillis(); + _setStartTime = true; + } - if (!entry->_videoCodec) - return 0; + _nextVideoTrack = findNextVideoTrack(); + _needUpdate = false; - const Graphics::Surface *frame = entry->_videoCodec->decodeImage(frameData); - delete frameData; + // Update audio buffers too + // (needs to be done after we find the next track) + for (uint32 i = 0; i < _handlers.size(); i++) + if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeAudio) + ((AudioTrackHandler *)_handlers[i])->updateBuffer(); - // Update the palette - if (entry->_videoCodec->containsPalette()) { - // The codec itself contains a palette - if (entry->_videoCodec->hasDirtyPalette()) { - _palette = entry->_videoCodec->getPalette(); - _dirtyPalette = true; - } - } else { - // Check if the video description has been updated - byte *palette = entry->_palette; - - if (palette != _palette) { - _palette = palette; - _dirtyPalette = true; - } + if (_scaledSurface) { + scaleSurface(frame, _scaledSurface, _scaleFactorX, _scaleFactorY); + return _scaledSurface; } - return scaleSurface(frame); + return frame; } -const Graphics::Surface *QuickTimeDecoder::scaleSurface(const Graphics::Surface *frame) { - if (getScaleFactorX() == 1 && getScaleFactorY() == 1) - return frame; +void QuickTimeDecoder::scaleSurface(const Graphics::Surface *src, Graphics::Surface *dst, Common::Rational scaleFactorX, Common::Rational scaleFactorY) { + assert(src && dst); - assert(_scaledSurface); - - for (int32 j = 0; j < _scaledSurface->h; j++) - for (int32 k = 0; k < _scaledSurface->w; k++) - memcpy(_scaledSurface->getBasePtr(k, j), frame->getBasePtr((k * getScaleFactorX()).toInt() , (j * getScaleFactorY()).toInt()), frame->format.bytesPerPixel); - - return _scaledSurface; + for (int32 j = 0; j < dst->h; j++) + for (int32 k = 0; k < dst->w; k++) + memcpy(dst->getBasePtr(k, j), src->getBasePtr((k * scaleFactorX).toInt() , (j * scaleFactorY).toInt()), src->format.bytesPerPixel); } bool QuickTimeDecoder::endOfVideo() const { - return (!_audStream || _audStream->endOfData()) && (!findDefaultVideoCodec() || SeekableVideoDecoder::endOfVideo()); + if (!isVideoLoaded()) + return true; + + for (uint32 i = 0; i < _handlers.size(); i++) + if (!_handlers[i]->endOfTrack()) + return false; + + return true; } uint32 QuickTimeDecoder::getElapsedTime() const { - if (_audStream) - return g_system->getMixer()->getSoundElapsedTime(_audHandle) + _audioStartOffset.msecs(); + // TODO: Convert to multi-track + if (_audStream) { + // Use the audio time if present and the audio track's time is less than the + // total length of the audio track. The audio track can end before the video + // track, so we need to fall back on the getMillis() time tracking in that + // case. + uint32 time = g_system->getMixer()->getSoundElapsedTime(_audHandle) + _audioStartOffset.msecs(); + if (time < _tracks[_audioTrackIndex]->mediaDuration * 1000 / _tracks[_audioTrackIndex]->timeScale) + return time; + } + // Just use time elapsed since the beginning return SeekableVideoDecoder::getElapsedTime(); } uint32 QuickTimeDecoder::getTimeToNextFrame() const { - if (endOfVideo() || _curFrame < 0) + if (_needUpdate) return 0; - // Convert from the QuickTime rate base to 1000 - uint32 nextFrameStartTime = _nextFrameStartTime * 1000 / _tracks[_videoTrackIndex]->timeScale; - uint32 elapsedTime = getElapsedTime(); + if (_nextVideoTrack) { + uint32 nextFrameStartTime = _nextVideoTrack->getNextFrameStartTime(); - if (nextFrameStartTime <= elapsedTime) - return 0; + if (nextFrameStartTime == 0) + return 0; + + // TODO: Add support for rate modification + + uint32 elapsedTime = getElapsedTime(); + + if (elapsedTime < nextFrameStartTime) + return nextFrameStartTime - elapsedTime; + } - return nextFrameStartTime - elapsedTime; + return 0; } bool QuickTimeDecoder::loadFile(const Common::String &filename) { @@ -337,30 +235,49 @@ bool QuickTimeDecoder::loadStream(Common::SeekableReadStream *stream) { void QuickTimeDecoder::init() { Audio::QuickTimeAudioDecoder::init(); - _videoTrackIndex = -1; _startTime = 0; - - // Find video streams - for (uint32 i = 0; i < _tracks.size(); i++) - if (_tracks[i]->codecType == CODEC_TYPE_VIDEO && _videoTrackIndex < 0) - _videoTrackIndex = i; + _setStartTime = false; // Start the audio codec if we've got one that we can handle if (_audStream) { startAudio(); _audioStartOffset = Audio::Timestamp(0); + + // TODO: Support multiple audio tracks + // For now, just push back a handler for the first audio track + _handlers.push_back(new AudioTrackHandler(this, _tracks[_audioTrackIndex])); } - // Initialize video, if present - if (_videoTrackIndex >= 0) { - for (uint32 i = 0; i < _tracks[_videoTrackIndex]->sampleDescs.size(); i++) - ((VideoSampleDesc *)_tracks[_videoTrackIndex]->sampleDescs[i])->initCodec(); + // Initialize all the video tracks + for (uint32 i = 0; i < _tracks.size(); i++) { + if (_tracks[i]->codecType == CODEC_TYPE_VIDEO) { + for (uint32 j = 0; j < _tracks[i]->sampleDescs.size(); j++) + ((VideoSampleDesc *)_tracks[i]->sampleDescs[j])->initCodec(); - if (getScaleFactorX() != 1 || getScaleFactorY() != 1) { + _handlers.push_back(new VideoTrackHandler(this, _tracks[i])); + } + } + + // Prepare the first video track + _nextVideoTrack = findNextVideoTrack(); + + if (_nextVideoTrack) { + // Initialize the scaled surface + if (_scaleFactorX != 1 || _scaleFactorY != 1) { // We have to initialize the scaled surface _scaledSurface = new Graphics::Surface(); - _scaledSurface->create(getWidth(), getHeight(), getPixelFormat()); + _scaledSurface->create((_nextVideoTrack->getWidth() / _scaleFactorX).toInt(), + (_nextVideoTrack->getHeight() / _scaleFactorY).toInt(), getPixelFormat()); + _width = _scaledSurface->w; + _height = _scaledSurface->h; + } else { + _width = _nextVideoTrack->getWidth().toInt(); + _height = _nextVideoTrack->getHeight().toInt(); } + + _needUpdate = true; + } else { + _needUpdate = false; } } @@ -464,6 +381,7 @@ Common::QuickTimeParser::SampleDesc *QuickTimeDecoder::readSampleDesc(Track *tra void QuickTimeDecoder::close() { stopAudio(); + freeAllTrackHandlers(); if (_scaledSurface) { _scaledSurface->free(); @@ -471,93 +389,46 @@ void QuickTimeDecoder::close() { _scaledSurface = 0; } + _width = _height = 0; + Common::QuickTimeParser::close(); SeekableVideoDecoder::reset(); } -Common::SeekableReadStream *QuickTimeDecoder::getNextFramePacket(uint32 &descId) { - if (_videoTrackIndex < 0) - return NULL; - - // First, we have to track down which chunk holds the sample and which sample in the chunk contains the frame we are looking for. - int32 totalSampleCount = 0; - int32 sampleInChunk = 0; - int32 actualChunk = -1; - uint32 sampleToChunkIndex = 0; +void QuickTimeDecoder::freeAllTrackHandlers() { + for (uint32 i = 0; i < _handlers.size(); i++) + delete _handlers[i]; - for (uint32 i = 0; i < _tracks[_videoTrackIndex]->chunkCount; i++) { - if (sampleToChunkIndex < _tracks[_videoTrackIndex]->sampleToChunkCount && i >= _tracks[_videoTrackIndex]->sampleToChunk[sampleToChunkIndex].first) - sampleToChunkIndex++; - - totalSampleCount += _tracks[_videoTrackIndex]->sampleToChunk[sampleToChunkIndex - 1].count; - - if (totalSampleCount > getCurFrame()) { - actualChunk = i; - descId = _tracks[_videoTrackIndex]->sampleToChunk[sampleToChunkIndex - 1].id; - sampleInChunk = _tracks[_videoTrackIndex]->sampleToChunk[sampleToChunkIndex - 1].count - totalSampleCount + getCurFrame(); - break; - } - } - - if (actualChunk < 0) { - warning ("Could not find data for frame %d", getCurFrame()); - return NULL; - } - - // Next seek to that frame - _fd->seek(_tracks[_videoTrackIndex]->chunkOffsets[actualChunk]); - - // Then, if the chunk holds more than one frame, seek to where the frame we want is located - for (int32 i = getCurFrame() - sampleInChunk; i < getCurFrame(); i++) { - if (_tracks[_videoTrackIndex]->sampleSize != 0) - _fd->skip(_tracks[_videoTrackIndex]->sampleSize); - else - _fd->skip(_tracks[_videoTrackIndex]->sampleSizes[i]); - } + _handlers.clear(); +} - // Finally, read in the raw data for the frame - //printf ("Frame Data[%d]: Offset = %d, Size = %d\n", getCurFrame(), _fd->pos(), _tracks[_videoTrackIndex]->sampleSizes[getCurFrame()]); +void QuickTimeDecoder::seekToTime(Audio::Timestamp time) { + // Sets all tracks to this time + for (uint32 i = 0; i < _handlers.size(); i++) + _handlers[i]->seekToTime(time); - if (_tracks[_videoTrackIndex]->sampleSize != 0) - return _fd->readStream(_tracks[_videoTrackIndex]->sampleSize); + // Reset our start time + _startTime = g_system->getMillis() - time.msecs(); + _setStartTime = true; + resetPauseStartTime(); - return _fd->readStream(_tracks[_videoTrackIndex]->sampleSizes[getCurFrame()]); + // Reset the next video track too + _nextVideoTrack = findNextVideoTrack(); + _needUpdate = _nextVideoTrack != 0; } void QuickTimeDecoder::updateAudioBuffer() { - if (!_audStream) - return; - - uint32 numberOfChunksNeeded = 0; - - if (_videoTrackIndex < 0 || _curFrame == (int32)_tracks[_videoTrackIndex]->frameCount - 1) { - // If we have no video, there's nothing to base our buffer against - // However, one must ask why a QuickTimeDecoder is being used instead of the nice makeQuickTimeStream() function - - // If we're on the last frame, make sure all audio remaining is buffered - numberOfChunksNeeded = _tracks[_audioTrackIndex]->chunkCount; - } else { - Audio::QuickTimeAudioDecoder::AudioSampleDesc *entry = (Audio::QuickTimeAudioDecoder::AudioSampleDesc *)_tracks[_audioTrackIndex]->sampleDescs[0]; - - // Calculate the amount of chunks we need in memory until the next frame - uint32 timeToNextFrame = getTimeToNextFrame(); - uint32 timeFilled = 0; - uint32 curAudioChunk = _curAudioChunk - _audStream->numQueuedStreams(); - - for (; timeFilled < timeToNextFrame && curAudioChunk < _tracks[_audioTrackIndex]->chunkCount; numberOfChunksNeeded++, curAudioChunk++) { - uint32 sampleCount = entry->getAudioChunkSampleCount(curAudioChunk); - assert(sampleCount); - - timeFilled += sampleCount * 1000 / entry->_sampleRate; - } + // Updates the audio buffers for all audio tracks + for (uint32 i = 0; i < _handlers.size(); i++) + if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeAudio) + ((AudioTrackHandler *)_handlers[i])->updateBuffer(); +} - // Add a couple extra to ensure we don't underrun - numberOfChunksNeeded += 3; - } +Graphics::PixelFormat QuickTimeDecoder::getPixelFormat() const { + if (_nextVideoTrack) + return _nextVideoTrack->getPixelFormat(); - // Keep three streams in buffer so that if/when the first two end, it goes right into the next - while (_audStream->numQueuedStreams() < numberOfChunksNeeded && _curAudioChunk < _tracks[_audioTrackIndex]->chunkCount) - queueNextAudioChunk(); + return Graphics::PixelFormat(); } QuickTimeDecoder::VideoSampleDesc::VideoSampleDesc(Common::QuickTimeParser::Track *parentTrack, uint32 codecTag) : Common::QuickTimeParser::SampleDesc(parentTrack, codecTag) { @@ -612,4 +483,383 @@ void QuickTimeDecoder::VideoSampleDesc::initCodec() { } } +bool QuickTimeDecoder::endOfVideoTracks() const { + for (uint32 i = 0; i < _handlers.size(); i++) + if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo && !_handlers[i]->endOfTrack()) + return false; + + return true; +} + +QuickTimeDecoder::TrackHandler::TrackHandler(QuickTimeDecoder *decoder, Track *parent) : _decoder(decoder), _parent(parent), _fd(_decoder->_fd) { + _curEdit = 0; +} + +bool QuickTimeDecoder::TrackHandler::endOfTrack() { + // A track is over when we've finished going through all edits + return _curEdit == _parent->editCount; +} + +QuickTimeDecoder::AudioTrackHandler::AudioTrackHandler(QuickTimeDecoder *decoder, Track *parent) : TrackHandler(decoder, parent) { +} + +void QuickTimeDecoder::AudioTrackHandler::updateBuffer() { + if (!_decoder->_audStream) + return; + + uint32 numberOfChunksNeeded = 0; + + if (_decoder->endOfVideoTracks()) { + // If we have no video left (or no video), there's nothing to base our buffer against + numberOfChunksNeeded = _parent->chunkCount; + } else { + Audio::QuickTimeAudioDecoder::AudioSampleDesc *entry = (Audio::QuickTimeAudioDecoder::AudioSampleDesc *)_parent->sampleDescs[0]; + + // Calculate the amount of chunks we need in memory until the next frame + uint32 timeToNextFrame = _decoder->getTimeToNextFrame(); + uint32 timeFilled = 0; + uint32 curAudioChunk = _decoder->_curAudioChunk - _decoder->_audStream->numQueuedStreams(); + + for (; timeFilled < timeToNextFrame && curAudioChunk < _parent->chunkCount; numberOfChunksNeeded++, curAudioChunk++) { + uint32 sampleCount = entry->getAudioChunkSampleCount(curAudioChunk); + assert(sampleCount); + + timeFilled += sampleCount * 1000 / entry->_sampleRate; + } + + // Add a couple extra to ensure we don't underrun + numberOfChunksNeeded += 3; + } + + // Keep three streams in buffer so that if/when the first two end, it goes right into the next + while (_decoder->_audStream->numQueuedStreams() < numberOfChunksNeeded && _decoder->_curAudioChunk < _parent->chunkCount) + _decoder->queueNextAudioChunk(); +} + +bool QuickTimeDecoder::AudioTrackHandler::endOfTrack() { + // TODO: Handle edits + return (_decoder->_curAudioChunk == _parent->chunkCount) && _decoder->_audStream->endOfData(); +} + +void QuickTimeDecoder::AudioTrackHandler::seekToTime(Audio::Timestamp time) { + if (_decoder->_audStream) { + // Stop all audio + _decoder->stopAudio(); + + _decoder->_audioStartOffset = time; + + // Seek to the new audio location + _decoder->setAudioStreamPos(_decoder->_audioStartOffset); + + // Restart the audio + _decoder->startAudio(); + + // Pause the audio again if we're still paused + if (_decoder->isPaused() && _decoder->_audStream) + g_system->getMixer()->pauseHandle(_decoder->_audHandle, true); + } +} + +QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : TrackHandler(decoder, parent) { + if (_parent->scaleFactorX != 1 || _parent->scaleFactorY != 1) { + _scaledSurface = new Graphics::Surface(); + _scaledSurface->create(getWidth().toInt(), getHeight().toInt(), getPixelFormat()); + } else { + _scaledSurface = 0; + } + + enterNewEditList(false); + + _holdNextFrameStartTime = false; + _curFrame = -1; + _durationOverride = -1; + +} + +QuickTimeDecoder::VideoTrackHandler::~VideoTrackHandler() { + if (_scaledSurface) { + _scaledSurface->free(); + delete _scaledSurface; + } +} + +const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame() { + if (endOfTrack()) + return 0; + + const Graphics::Surface *frame = bufferNextFrame(); + + if (_holdNextFrameStartTime) { + // Don't set the next frame start time here; we just did a seek + _holdNextFrameStartTime = false; + } else if (_durationOverride >= 0) { + // Use our own duration from the edit list calculation + _nextFrameStartTime += _durationOverride; + _durationOverride = -1; + } else { + _nextFrameStartTime += getFrameDuration(); + } + + // Update the edit list, if applicable + // HACK: We're also accepting the time minus one because edit lists + // aren't as accurate as one would hope. + if (!endOfTrack() && getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration() - 1) { + _curEdit++; + + if (!endOfTrack()) + enterNewEditList(true); + } + + if (_scaledSurface) { + _decoder->scaleSurface(frame, _scaledSurface, _parent->scaleFactorX, _parent->scaleFactorY); + return _scaledSurface; + } + + return frame; +} + +void QuickTimeDecoder::VideoTrackHandler::enterNewEditList(bool bufferFrames) { + // Bypass all empty edit lists first + while (!endOfTrack() && _parent->editList[_curEdit].mediaTime == -1) + _curEdit++; + + if (endOfTrack()) + return; + + uint32 frameNum = 0; + bool done = false; + uint32 totalDuration = 0; + uint32 prevDuration = 0; + + // Track down where the mediaTime is in the media + for (int32 i = 0; i < _parent->timeToSampleCount && !done; i++) { + for (int32 j = 0; j < _parent->timeToSample[i].count; j++) { + if (totalDuration == (uint32)_parent->editList[_curEdit].mediaTime) { + done = true; + prevDuration = totalDuration; + break; + } else if (totalDuration > (uint32)_parent->editList[_curEdit].mediaTime) { + done = true; + frameNum--; + break; + } + + prevDuration = totalDuration; + totalDuration += _parent->timeToSample[i].duration; + frameNum++; + } + } + + if (bufferFrames) { + // Track down the keyframe + _curFrame = findKeyFrame(frameNum) - 1; + while (_curFrame < (int32)frameNum - 1) + bufferNextFrame(); + } else { + _curFrame = frameNum - 1; + } + + _nextFrameStartTime = getCurEditTimeOffset(); + + // Set an override for the duration since we came up in-between two frames + if (prevDuration != totalDuration) + _durationOverride = totalDuration - prevDuration; +} + +const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::bufferNextFrame() { + _curFrame++; + + // Get the next packet + uint32 descId; + Common::SeekableReadStream *frameData = getNextFramePacket(descId); + + if (!frameData || !descId || descId > _parent->sampleDescs.size()) + return 0; + + // Find which video description entry we want + VideoSampleDesc *entry = (VideoSampleDesc *)_parent->sampleDescs[descId - 1]; + + if (!entry->_videoCodec) + return 0; + + const Graphics::Surface *frame = entry->_videoCodec->decodeImage(frameData); + delete frameData; + + // Update the palette + if (entry->_videoCodec->containsPalette()) { + // The codec itself contains a palette + if (entry->_videoCodec->hasDirtyPalette()) { + _decoder->_palette = entry->_videoCodec->getPalette(); + _decoder->_dirtyPalette = true; + } + } else { + // Check if the video description has been updated + byte *palette = entry->_palette; + + if (palette !=_decoder-> _palette) { + _decoder->_palette = palette; + _decoder->_dirtyPalette = true; + } + } + + return frame; +} + +uint32 QuickTimeDecoder::VideoTrackHandler::getNextFrameStartTime() { + if (endOfTrack()) + return 0; + + // Convert to milliseconds so the tracks can be compared + return getRateAdjustedFrameTime() * 1000 / _parent->timeScale; +} + +uint32 QuickTimeDecoder::VideoTrackHandler::getFrameCount() { + return _parent->frameCount; +} + +uint32 QuickTimeDecoder::VideoTrackHandler::getFrameDuration() { + uint32 curFrameIndex = 0; + for (int32 i = 0; i < _parent->timeToSampleCount; i++) { + curFrameIndex += _parent->timeToSample[i].count; + if ((uint32)_curFrame < curFrameIndex) { + // Ok, now we have what duration this frame has. + return _parent->timeToSample[i].duration; + } + } + + // This should never occur + error("Cannot find duration for frame %d", _curFrame); + return 0; +} + +Common::SeekableReadStream *QuickTimeDecoder::VideoTrackHandler::getNextFramePacket(uint32 &descId) { + // First, we have to track down which chunk holds the sample and which sample in the chunk contains the frame we are looking for. + int32 totalSampleCount = 0; + int32 sampleInChunk = 0; + int32 actualChunk = -1; + uint32 sampleToChunkIndex = 0; + + for (uint32 i = 0; i < _parent->chunkCount; i++) { + if (sampleToChunkIndex < _parent->sampleToChunkCount && i >= _parent->sampleToChunk[sampleToChunkIndex].first) + sampleToChunkIndex++; + + totalSampleCount += _parent->sampleToChunk[sampleToChunkIndex - 1].count; + + if (totalSampleCount > _curFrame) { + actualChunk = i; + descId = _parent->sampleToChunk[sampleToChunkIndex - 1].id; + sampleInChunk = _parent->sampleToChunk[sampleToChunkIndex - 1].count - totalSampleCount + _curFrame; + break; + } + } + + if (actualChunk < 0) { + warning("Could not find data for frame %d", _curFrame); + return 0; + } + + // Next seek to that frame + _fd->seek(_parent->chunkOffsets[actualChunk]); + + // Then, if the chunk holds more than one frame, seek to where the frame we want is located + for (int32 i = _curFrame - sampleInChunk; i < _curFrame; i++) { + if (_parent->sampleSize != 0) + _fd->skip(_parent->sampleSize); + else + _fd->skip(_parent->sampleSizes[i]); + } + + // Finally, read in the raw data for the frame + //debug("Frame Data[%d]: Offset = %d, Size = %d", _curFrame, _fd->pos(), _parent->sampleSizes[_curFrame]); + + if (_parent->sampleSize != 0) + return _fd->readStream(_parent->sampleSize); + + return _fd->readStream(_parent->sampleSizes[_curFrame]); +} + +uint32 QuickTimeDecoder::VideoTrackHandler::findKeyFrame(uint32 frame) const { + for (int i = _parent->keyframeCount - 1; i >= 0; i--) + if (_parent->keyframes[i] <= frame) + return _parent->keyframes[i]; + + // If none found, we'll assume the requested frame is a key frame + return frame; +} + +void QuickTimeDecoder::VideoTrackHandler::seekToTime(Audio::Timestamp time) { + // First, figure out what edit we're in + time = time.convertToFramerate(_parent->timeScale); + + // Continue until we get to where we need to be + for (_curEdit = 0; !endOfTrack(); _curEdit++) + if ((uint32)time.totalNumberOfFrames() >= getCurEditTimeOffset() && (uint32)time.totalNumberOfFrames() < getCurEditTimeOffset() + getCurEditTrackDuration()) + break; + + // This track is done + if (endOfTrack()) + return; + + enterNewEditList(false); + + // One extra check for the end of a track + if (endOfTrack()) + return; + + // Now we're in the edit and need to figure out what frame we need + while (getRateAdjustedFrameTime() < (uint32)time.totalNumberOfFrames()) { + _curFrame++; + if (_durationOverride >= 0) { + _nextFrameStartTime += _durationOverride; + _durationOverride = -1; + } else { + _nextFrameStartTime += getFrameDuration(); + } + } + + // All that's left is to figure out what our starting time is going to be + // Compare the starting point for the frame to where we need to be + _holdNextFrameStartTime = getRateAdjustedFrameTime() != (uint32)time.totalNumberOfFrames(); + + // If we went past the time, go back a frame + if (_holdNextFrameStartTime) + _curFrame--; + + // Handle the keyframe here + int32 destinationFrame = _curFrame + 1; + + assert(destinationFrame < (int32)_parent->frameCount); + _curFrame = findKeyFrame(destinationFrame) - 1; + while (_curFrame < destinationFrame - 1) + bufferNextFrame(); +} + +Common::Rational QuickTimeDecoder::VideoTrackHandler::getWidth() const { + return Common::Rational(_parent->width) / _parent->scaleFactorX; +} + +Common::Rational QuickTimeDecoder::VideoTrackHandler::getHeight() const { + return Common::Rational(_parent->height) / _parent->scaleFactorY; +} + +Graphics::PixelFormat QuickTimeDecoder::VideoTrackHandler::getPixelFormat() const { + return ((VideoSampleDesc *)_parent->sampleDescs[0])->_videoCodec->getPixelFormat(); +} + +uint32 QuickTimeDecoder::VideoTrackHandler::getRateAdjustedFrameTime() const { + // Figure out what time the next frame is at taking the edit list rate into account + uint32 convertedTime = (Common::Rational(_nextFrameStartTime - getCurEditTimeOffset()) / _parent->editList[_curEdit].mediaRate).toInt(); + return convertedTime + getCurEditTimeOffset(); +} + +uint32 QuickTimeDecoder::VideoTrackHandler::getCurEditTimeOffset() const { + // Need to convert to the track scale + return _parent->editList[_curEdit].timeOffset * _parent->timeScale / _decoder->_timeScale; +} + +uint32 QuickTimeDecoder::VideoTrackHandler::getCurEditTrackDuration() const { + // Need to convert to the track scale + return _parent->editList[_curEdit].trackDuration * _parent->timeScale / _decoder->_timeScale; +} + } // End of namespace Video diff --git a/video/qt_decoder.h b/video/qt_decoder.h index b51fd043e7..b2d7153f42 100644 --- a/video/qt_decoder.h +++ b/video/qt_decoder.h @@ -31,14 +31,14 @@ #ifndef VIDEO_QT_DECODER_H #define VIDEO_QT_DECODER_H +#include "audio/mixer.h" +#include "audio/decoders/quicktime_intern.h" #include "common/scummsys.h" #include "common/rational.h" +#include "graphics/pixelformat.h" #include "video/video_decoder.h" -#include "audio/mixer.h" -#include "audio/decoders/quicktime_intern.h" - namespace Common { class Rational; } @@ -63,13 +63,13 @@ public: * Returns the width of the video * @return the width of the video */ - uint16 getWidth() const; + uint16 getWidth() const { return _width; } /** * Returns the height of the video * @return the height of the video */ - uint16 getHeight() const; + uint16 getHeight() const { return _height; } /** * Returns the amount of frames in the video @@ -101,6 +101,8 @@ public: const byte *getPalette() { _dirtyPalette = false; return _palette; } bool hasDirtyPalette() const { return _dirtyPalette; } + int32 getCurFrame() const; + bool isVideoLoaded() const { return isOpen(); } const Graphics::Surface *decodeNextFrame(); bool endOfVideo() const; @@ -132,8 +134,6 @@ protected: Common::QuickTimeParser::SampleDesc *readSampleDesc(Track *track, uint32 format); private: - Common::SeekableReadStream *getNextFramePacket(uint32 &descId); - uint32 getFrameDuration(); void init(); void startAudio(); @@ -144,20 +144,108 @@ private: Audio::Timestamp _audioStartOffset; Codec *createCodec(uint32 codecTag, byte bitsPerPixel); - Codec *findDefaultVideoCodec() const; - uint32 _nextFrameStartTime; - int _videoTrackIndex; uint32 findKeyFrame(uint32 frame) const; bool _dirtyPalette; const byte *_palette; + bool _setStartTime; + bool _needUpdate; + + uint16 _width, _height; Graphics::Surface *_scaledSurface; - const Graphics::Surface *scaleSurface(const Graphics::Surface *frame); - Common::Rational getScaleFactorX() const; - Common::Rational getScaleFactorY() const; + void scaleSurface(const Graphics::Surface *src, Graphics::Surface *dst, + Common::Rational scaleFactorX, Common::Rational scaleFactorY); void pauseVideoIntern(bool pause); + bool endOfVideoTracks() const; + + // The TrackHandler is a class that wraps around a QuickTime Track + // and handles playback in this decoder class. + class TrackHandler { + public: + TrackHandler(QuickTimeDecoder *decoder, Track *parent); + virtual ~TrackHandler() {} + + enum TrackType { + kTrackTypeAudio, + kTrackTypeVideo + }; + + virtual TrackType getTrackType() const = 0; + + virtual void seekToTime(Audio::Timestamp time) = 0; + + virtual bool endOfTrack(); + + protected: + uint32 _curEdit; + QuickTimeDecoder *_decoder; + Common::SeekableReadStream *_fd; + Track *_parent; + }; + + // The AudioTrackHandler is currently just a wrapper around some + // QuickTimeDecoder functions. Eventually this can be made to + // handle multiple audio tracks, but I haven't seen a video with + // that yet. + class AudioTrackHandler : public TrackHandler { + public: + AudioTrackHandler(QuickTimeDecoder *decoder, Track *parent); + TrackType getTrackType() const { return kTrackTypeAudio; } + + void updateBuffer(); + void seekToTime(Audio::Timestamp time); + bool endOfTrack(); + }; + + // The VideoTrackHandler is the bridge between the time of playback + // and the media for the given track. It calculates when to start + // tracks and at what rate to play the media using the edit list. + class VideoTrackHandler : public TrackHandler { + public: + VideoTrackHandler(QuickTimeDecoder *decoder, Track *parent); + ~VideoTrackHandler(); + + TrackType getTrackType() const { return kTrackTypeVideo; } + + const Graphics::Surface *decodeNextFrame(); + + uint32 getNextFrameStartTime(); + + uint32 getFrameCount(); + + int32 getCurFrame() { return _curFrame; } + + Graphics::PixelFormat getPixelFormat() const; + + void seekToTime(Audio::Timestamp time); + + Common::Rational getWidth() const; + Common::Rational getHeight() const; + + private: + int32 _curFrame; + uint32 _nextFrameStartTime; + Graphics::Surface *_scaledSurface; + bool _holdNextFrameStartTime; + int32 _durationOverride; + + Common::SeekableReadStream *getNextFramePacket(uint32 &descId); + uint32 getFrameDuration(); + uint32 findKeyFrame(uint32 frame) const; + void enterNewEditList(bool bufferFrames); + const Graphics::Surface *bufferNextFrame(); + uint32 getRateAdjustedFrameTime() const; + uint32 getCurEditTimeOffset() const; + uint32 getCurEditTrackDuration() const; + }; + + Common::Array<TrackHandler *> _handlers; + VideoTrackHandler *_nextVideoTrack; + VideoTrackHandler *findNextVideoTrack() const; + + void freeAllTrackHandlers(); }; } // End of namespace Video |