diff options
442 files changed, 12159 insertions, 24303 deletions
@@ -190,9 +190,6 @@ ScummVM Team Nintendo DS: Neil Millstone - PalmOS: - Chris Apers - PocketPC / WinCE: Nicolas Bacca - (retired) Kostas Nakos @@ -256,6 +253,7 @@ ScummVM Team Retired Team Members -------------------- + Chris Apers - Former PalmOS porter Ralph Brorsen - Help with GUI implementation Jamieson Christian - iMUSE, MIDI, all things musical Felix Jakschitsch - Zak256 reverse engineering @@ -6,6 +6,7 @@ For a more comprehensive changelog for the latest experimental SVN code, see: - Added Android port. General: + - Removed the outdated PalmOS port. - Switched to the "fast" DOSBox OPL emulator. - Fixed a crash in the rjp1 player code affecting the FOTAQ Amiga version. - Added support for more original media layouts. @@ -29,6 +30,10 @@ For a more comprehensive changelog for the latest experimental SVN code, see: - Added support for the Macintosh version of The 7th Guest. - Added support for custom MT-32 instruments. + KYRA: + - Fixed some minor graphical glitches. + - Implemented formerly missing recreation of some in game items. + Parallaction: - Made part one of The Big Red Adventure completable. @@ -859,17 +859,13 @@ Supported platforms include (but are not limited to): Nintendo DS Nintendo Wii OS/2 - PalmOS PlayStation 2 PlayStation Portable Symbian The Dreamcast port does not support The Curse of Monkey Island, nor The -Dig. The PalmOS port does not support The Curse of Monkey Island, -Beneath a Steel Sky, nor either Simon the Sorcerer 1 or 2. The Dig will -only work on some Palm devices (those with a large dynamic heap). The -Nintendo DS port does not support Full Throttle, The Dig, or The Curse -of Monkey Island. +Dig. The Nintendo DS port does not support Full Throttle, The Dig, or +The Curse of Monkey Island. For more platform specific limitations, please refer to our Wiki: http://wiki.scummvm.org/index.php/Platforms diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp index 212cb130c1..0616713eab 100644 --- a/backends/events/default/default-events.cpp +++ b/backends/events/default/default-events.cpp @@ -95,13 +95,11 @@ bool DefaultEventManager::pollEvent(Common::Event &event) { case Common::EVENT_KEYDOWN: _modifierState = event.kbd.flags; // init continuous event stream - // not done on PalmOS because keyboard is emulated and keyup is not generated -#if !defined(PALMOS_MODE) _currentKeyDown.ascii = event.kbd.ascii; _currentKeyDown.keycode = event.kbd.keycode; _currentKeyDown.flags = event.kbd.flags; _keyRepeatTime = time + kKeyRepeatInitialDelay; -#endif + // Global Main Menu if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_F5) { if (g_engine && !g_engine->isPaused()) { diff --git a/backends/fs/palmos/palmos-fs-factory.cpp b/backends/fs/palmos/palmos-fs-factory.cpp deleted file mode 100644 index 97b3644205..0000000000 --- a/backends/fs/palmos/palmos-fs-factory.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#if defined(PALMOS_MODE) -#include "backends/fs/palmos/palmos-fs-factory.h" -#include "backends/fs/palmos/palmos-fs.cpp" - -DECLARE_SINGLETON(PalmOSFilesystemFactory) - -AbstractFSNode *PalmOSFilesystemFactory::makeRootFileNode() const { - return new PalmOSFilesystemNode(); -} - -AbstractFSNode *PalmOSFilesystemFactory::makeCurrentDirectoryFileNode() const { - return new PalmOSFilesystemNode(); -} - -AbstractFSNode *PalmOSFilesystemFactory::makeFileNodePath(const Common::String &path) const { - return new PalmOSFilesystemNode(path); -} -#endif diff --git a/backends/fs/palmos/palmos-fs.cpp b/backends/fs/palmos/palmos-fs.cpp deleted file mode 100644 index 4e05f75d19..0000000000 --- a/backends/fs/palmos/palmos-fs.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#if defined(PALMOS_MODE) - -#include "PalmVersion.h" -#include "globals.h" - -#include "backends/fs/abstract-fs.h" -#include "backends/fs/stdiostream.h" - -/** - * Implementation of the ScummVM file system API based on PalmOS VFS API. - * - * Parts of this class are documented in the base interface class, AbstractFSNode. - */ -class PalmOSFilesystemNode : public AbstractFSNode { -protected: - Common::String _displayName; - Common::String _path; - bool _isDirectory; - bool _isValid; - bool _isPseudoRoot; // TODO: get rid of this - -public: - /** - * Creates a PalmOSFilesystemNode with the root node as path. - */ - PalmOSFilesystemNode(); - - /** - * Creates a PalmOSFilesystemNode for a given path. - * - * @param path Common::String with the path the new node should point to. - */ - PalmOSFilesystemNode(const Common::String &p); - - virtual bool exists() const { return _isValid; } - virtual Common::String getDisplayName() const { return _displayName; } - virtual Common::String getName() const { return _displayName; } - virtual Common::String getPath() const { return _path; } - virtual bool isDirectory() const { return _isDirectory; } - virtual bool isReadable() const { return true; } //FIXME: this is just a stub - virtual bool isWritable() const { return true; } //FIXME: this is just a stub - - virtual AbstractFSNode *getChild(const Common::String &n) const; - virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const; - virtual AbstractFSNode *getParent() const; - - virtual Common::SeekableReadStream *createReadStream(); - virtual Common::WriteStream *createWriteStream(); - -private: - /** - * Adds a single PalmOSFilesystemNode to a given list. - * This method is used by getChildren() to populate the directory entries list. - * - * @param list List to put the file entry node in. - * @param mode Mode to use while adding the file entry to the list. - * @param base Common::String with the directory being listed. - * @param find_data Describes a file that the FindFirstFile, FindFirstFileEx, or FindNextFile functions find. - */ - static void addFile(AbstractFSList &list, ListMode mode, const Char *base, FileInfoType* find_data); -}; - -void PalmOSFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const char *base, FileInfoType* find_data) { - PalmOSFilesystemNode entry; - bool isDir; - - isDir = (find_data->attributes & vfsFileAttrDirectory); - - if ((!isDir && mode == Common::FSNode::kListDirectoriesOnly) || - (isDir && mode == Common::FSNode::kListFilesOnly)) - return; - - entry._isDirectory = isDir; - entry._displayName = find_data->nameP; - entry._path = base; - entry._path += find_data->nameP; - - if (entry._isDirectory) - entry._path += "/"; - - entry._isValid = true; - entry._isPseudoRoot = false; - - list.push_back(new PalmOSFilesystemNode(entry)); -} - -PalmOSFilesystemNode::PalmOSFilesystemNode() { - _isDirectory = true; - _displayName = "Root"; - _isValid = true; - _path = "/"; - _isPseudoRoot = false; -} - -PalmOSFilesystemNode::PalmOSFilesystemNode(const Common::String &p) { - assert(p.size() > 0); - - _path = p; - _displayName = lastPathComponent(_path, '/'); - - UInt32 attr; - FileRef handle; - Err error = VFSFileOpen(gVars->VFS.volRefNum, _path.c_str(), vfsModeRead, &handle); - if (!error) { - error = VFSFileGetAttributes(handle, &attr); - VFSFileClose(handle); - } - - if (error) { - _isValid = false; - _isDirectory = false; - - } else { - _isValid = true; - _isDirectory = (attr & vfsFileAttrDirectory); - } - - _isPseudoRoot = false; -} - -AbstractFSNode *PalmOSFilesystemNode::getChild(const Common::String &n) const { - // FIXME: Pretty lame implementation! We do no error checking to speak - // of, do not check if this is a special node, etc. - assert(_isDirectory); - - Common::String newPath(_path); - if (_path.lastChar() != '/') - newPath += '/'; - newPath += n; - - return new PalmOSFilesystemNode(newPath); -} - -bool PalmOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const { - assert(_isDirectory); - - //TODO: honor the hidden flag - - Err error; - Char nameP[256]; - FileInfoType desc; - FileRef handle; - UInt32 dirIterator = expIteratorStart; - - desc.nameP = nameP; - desc.nameBufLen = 256; - - error = VFSFileOpen(gVars->VFS.volRefNum, _path.c_str(), vfsModeRead, &handle); - if (error) - return false; - - while (dirIterator != expIteratorStop) { - error = VFSDirEntryEnumerate(handle, &dirIterator, &desc); - if (!error) - addFile(myList, mode, _path.c_str(), &desc); - } - - VFSFileClose(handle); - return true; -} - -AbstractFSNode *PalmOSFilesystemNode::getParent() const { - PalmOSFilesystemNode *p = 0; - - if (!_isPseudoRoot) { - const char *start = _path.c_str(); - const char *end = lastPathComponent(_path, '/'); - - p = new PalmOSFilesystemNode(); - p->_path = Common::String(start, end - start); - p->_isValid = true; - p->_isDirectory = true; - p->_displayName = lastPathComponent(p->_path, '/'); - p->_isPseudoRoot =(p->_path == "/"); - } - - return p; -} - -Common::SeekableReadStream *PalmOSFilesystemNode::createReadStream() { - return StdioStream::makeFromPath(getPath().c_str(), false); -} - -Common::WriteStream *PalmOSFilesystemNode::createWriteStream() { - return StdioStream::makeFromPath(getPath().c_str(), true); -} - -#endif // PALMOS_MODE diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp index e0c7dc7100..5eb6e6e693 100644 --- a/backends/graphics/sdl/sdl-graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -940,7 +940,8 @@ void SdlGraphicsManager::internUpdateScreen() { #endif // If the shake position changed, fill the dirty area with blackness - if (_currentShakePos != _newShakePos) { + if (_currentShakePos != _newShakePos || + (_mouseNeedsRedraw && _mouseBackup.y <= _currentShakePos)) { SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor}; if (_videoMode.aspectRatioCorrection && !_overlayVisible) @@ -1842,7 +1843,7 @@ void SdlGraphicsManager::undrawMouse() { return; if (_mouseBackup.w != 0 && _mouseBackup.h != 0) - addDirtyRect(x, y, _mouseBackup.w, _mouseBackup.h); + addDirtyRect(x, y - _currentShakePos, _mouseBackup.w, _mouseBackup.h); } void SdlGraphicsManager::drawMouse() { diff --git a/backends/midi/alsa.cpp b/backends/midi/alsa.cpp index a82fffdf0d..4f73d7384b 100644 --- a/backends/midi/alsa.cpp +++ b/backends/midi/alsa.cpp @@ -24,7 +24,7 @@ #include "common/scummsys.h" -#if defined(UNIX) && defined(USE_ALSA) +#if defined(USE_ALSA) #include "common/config-manager.h" #include "common/util.h" @@ -48,6 +48,17 @@ #define my_snd_seq_open(seqp) snd_seq_open(seqp, SND_SEQ_OPEN) #endif +#define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) + +static int check_permission(snd_seq_port_info_t *pinfo) +{ + if (perm_ok(pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) { + if (!(snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_NO_EXPORT)) + return 1; + } + return 0; +} + /* * parse address string */ @@ -56,7 +67,7 @@ class MidiDriver_ALSA:public MidiDriver_MPU401 { public: - MidiDriver_ALSA(); + MidiDriver_ALSA(int client, int port); int open(); void close(); void send(uint32 b); @@ -69,34 +80,19 @@ private: snd_seq_t *seq_handle; int seq_client, seq_port; int my_client, my_port; - static int parse_addr(const char *arg, int *client, int *port); }; -MidiDriver_ALSA::MidiDriver_ALSA() - : _isOpen(false), seq_handle(0), seq_client(0), seq_port(0), my_client(0), my_port(0) +MidiDriver_ALSA::MidiDriver_ALSA(int client, int port) + : _isOpen(false), seq_handle(0), seq_client(client), seq_port(port), my_client(0), my_port(0) { memset(&ev, 0, sizeof(ev)); } int MidiDriver_ALSA::open() { - const char *var = NULL; - if (_isOpen) return MERR_ALREADY_OPEN; _isOpen = true; - var = getenv("SCUMMVM_PORT"); - if (!var && ConfMan.hasKey("alsa_port")) { - var = ConfMan.get("alsa_port").c_str(); - } - - if (var) { - if (parse_addr(var, &seq_client, &seq_port) < 0) { - error("Invalid port %s", var); - return -1; - } - } - if (my_snd_seq_open(&seq_handle) < 0) { error("Can't open sequencer"); return -1; @@ -108,9 +104,14 @@ int MidiDriver_ALSA::open() { } snd_seq_set_client_group(seq_handle, "input"); - my_port = snd_seq_create_simple_port(seq_handle, "SCUMMVM port 0", - SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE | - SND_SEQ_PORT_CAP_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC); + // According to http://www.alsa-project.org/~tiwai/alsa-subs.html + // you can set read or write capabilities to allow other clients to + // read or write the port. I don't think we need that, unless maybe + // to be able to record the sound, but I can't get that to work even + // with those capabilities. + + my_port = snd_seq_create_simple_port(seq_handle, "SCUMMVM port 0", 0, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); if (my_port < 0) { snd_seq_close(seq_handle); @@ -118,29 +119,45 @@ int MidiDriver_ALSA::open() { return -1; } - if (var) { - if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) { - // subscribe to MIDI port - if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) { - error("Can't subscribe to MIDI port (%d:%d) see README for help", seq_client, seq_port); + if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) { + // Subscribe to MIDI port. Prefer one that doesn't already have + // any connections, unless we've forced a port number already. + if (seq_port == -1) { + snd_seq_client_info_t *cinfo; + snd_seq_port_info_t *pinfo; + + snd_seq_client_info_alloca(&cinfo); + snd_seq_port_info_alloca(&pinfo); + + snd_seq_get_any_client_info(seq_handle, seq_client, cinfo); + + int first_port = -1; + int found_port = -1; + + snd_seq_port_info_set_client(pinfo, seq_client); + snd_seq_port_info_set_port(pinfo, -1); + while (found_port == -1 && snd_seq_query_next_port(seq_handle, pinfo) >= 0) { + if (check_permission(pinfo)) { + if (first_port == -1) + first_port = snd_seq_port_info_get_port(pinfo); + if (found_port == -1 && snd_seq_port_info_get_write_use(pinfo) == 0) + found_port = snd_seq_port_info_get_port(pinfo); + } + } + + if (found_port == -1) { + // Should we abort here? For now, use the first + // available port. + seq_port = first_port; + warning("MidiDriver_ALSA: All ports on client %d (%s) are already in use", seq_client, snd_seq_client_info_get_name(cinfo)); + } else { + seq_port = found_port; } - } - } else { - int defaultPorts[] = { - 65, 0, - 17, 0 - }; - int i; - - for (i = 0; i < ARRAYSIZE(defaultPorts); i += 2) { - seq_client = defaultPorts[i]; - seq_port = defaultPorts[i + 1]; - if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) >= 0) - break; } - if (i >= ARRAYSIZE(defaultPorts)) - error("Can't subscribe to MIDI port (65:0) or (17:0)"); + if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) { + error("Can't subscribe to MIDI port (%d:%d) see README for help", seq_client, seq_port); + } } printf("Connected to Alsa sequencer client [%d:%d]\n", seq_client, seq_port); @@ -150,10 +167,13 @@ int MidiDriver_ALSA::open() { } void MidiDriver_ALSA::close() { - _isOpen = false; - MidiDriver_MPU401::close(); - if (seq_handle) - snd_seq_close(seq_handle); + if (_isOpen) { + _isOpen = false; + MidiDriver_MPU401::close(); + if (seq_handle) + snd_seq_close(seq_handle); + } else + warning("MidiDriver_ALSA: Closing the driver before opening it"); } void MidiDriver_ALSA::send(uint32 b) { @@ -227,24 +247,6 @@ void MidiDriver_ALSA::sysEx(const byte *msg, uint16 length) { send_event(1); } -int MidiDriver_ALSA::parse_addr(const char *arg, int *client, int *port) { - const char *p; - - if (isdigit(*arg)) { - if ((p = strpbrk(arg, ADDR_DELIM)) == NULL) - return -1; - *client = atoi(arg); - *port = atoi(p + 1); - } else { - if (*arg == 's' || *arg == 'S') { - *client = SND_SEQ_ADDRESS_SUBSCRIBERS; - *port = 0; - } else - return -1; - } - return 0; -} - void MidiDriver_ALSA::send_event(int do_flush) { snd_seq_ev_set_direct(&ev); snd_seq_ev_set_source(&ev, my_port); @@ -258,6 +260,37 @@ void MidiDriver_ALSA::send_event(int do_flush) { // Plugin interface +class AlsaDevice { +public: + AlsaDevice(Common::String name, MusicType mt, int client); + Common::String getName(); + MusicType getType(); + int getClient(); + +private: + Common::String _name; + MusicType _type; + int _client; +}; + +typedef Common::List<AlsaDevice> AlsaDevices; + +AlsaDevice::AlsaDevice(Common::String name, MusicType mt, int client) + : _name(name), _type(mt), _client(client) { +} + +Common::String AlsaDevice::getName() { + return _name; +} + +MusicType AlsaDevice::getType() { + return _type; +} + +int AlsaDevice::getClient() { + return _client; +} + class AlsaMusicPlugin : public MusicPluginObject { public: const char *getName() const { @@ -268,26 +301,18 @@ public: return "alsa"; } + AlsaDevices getAlsaDevices() const; MusicDevices getDevices() const; Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; -}; -#define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) - -static int check_permission(snd_seq_port_info_t *pinfo) -{ - if (perm_ok(pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) { - if (!(snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_NO_EXPORT)) - return 1; - } - return 0; -} - -MusicDevices AlsaMusicPlugin::getDevices() const { - MusicDevices devices; +private: + static int parse_addr(const char *arg, int *client, int *port); +}; - snd_seq_t *seq; - if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) +AlsaDevices AlsaMusicPlugin::getAlsaDevices() const { + AlsaDevices devices; + snd_seq_t *seq_handle; + if (my_snd_seq_open(&seq_handle) < 0) return devices; // can't open sequencer snd_seq_client_info_t *cinfo; @@ -295,32 +320,147 @@ MusicDevices AlsaMusicPlugin::getDevices() const { snd_seq_port_info_t *pinfo; snd_seq_port_info_alloca(&pinfo); snd_seq_client_info_set_client(cinfo, -1); - while (snd_seq_query_next_client(seq, cinfo) >= 0) { + while (snd_seq_query_next_client(seq_handle, cinfo) >= 0) { bool found_valid_port = false; /* reset query info */ snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); snd_seq_port_info_set_port(pinfo, -1); - while (!found_valid_port && snd_seq_query_next_port(seq, pinfo) >= 0) { + while (!found_valid_port && snd_seq_query_next_port(seq_handle, pinfo) >= 0) { if (check_permission(pinfo)) { found_valid_port = true; - // TODO: Return a different music type depending on the configuration - devices.push_back(MusicDevice(this, snd_seq_client_info_get_name(cinfo), MT_GM)); - //snd_seq_client_info_get_client(cinfo) : snd_seq_port_info_get_port(pinfo) + + const char *name = snd_seq_client_info_get_name(cinfo); + // TODO: Can we figure out the appropriate music type? + MusicType type = MT_GM; + int client = snd_seq_client_info_get_client(cinfo); + devices.push_back(AlsaDevice(name, type, client)); } } } - snd_seq_close(seq); + snd_seq_close(seq_handle); return devices; } -Common::Error AlsaMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { - *mididriver = new MidiDriver_ALSA(); +MusicDevices AlsaMusicPlugin::getDevices() const { + MusicDevices devices; + AlsaDevices::iterator d; + + AlsaDevices alsaDevices = getAlsaDevices(); + + // Since the default behaviour is to use the first device in the list, + // try to put something sensible there. We used to have 17:0 and 65:0 + // as defaults. + + for (d = alsaDevices.begin(); d != alsaDevices.end();) { + const int client = d->getClient(); + + if (client == 17 || client == 65) { + devices.push_back(MusicDevice(this, d->getName(), d->getType())); + d = alsaDevices.erase(d); + } else { + ++d; + } + } + + // 128:0 is probably TiMidity, or something like that, so that's + // probably a good second choice. + + for (d = alsaDevices.begin(); d != alsaDevices.end();) { + if (d->getClient() == 128) { + devices.push_back(MusicDevice(this, d->getName(), d->getType())); + d = alsaDevices.erase(d); + } else { + ++d; + } + } + + // Add the remaining devices in the order they were found. + + for (d = alsaDevices.begin(); d != alsaDevices.end(); ++d) + devices.push_back(MusicDevice(this, d->getName(), d->getType())); + + return devices; +} + +Common::Error AlsaMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle dev) const { + bool found = false; + int seq_client, seq_port; + + const char *var = NULL; + + // TODO: Upgrade from old alsa_port setting. This probably isn't the + // right place to do that, though. + + if (ConfMan.hasKey("alsa_port")) { + warning("AlsaMusicPlugin: Found old 'alsa_port' setting, which will be ignored"); + } + + // The SCUMMVM_PORT environment variable can still be used to override + // any config setting. + + var = getenv("SCUMMVM_PORT"); + if (var) { + warning("AlsaMusicPlugin: SCUMMVM_PORT environment variable overrides config settings"); + if (parse_addr(var, &seq_client, &seq_port) >= 0) { + found = true; + } else { + warning("AlsaMusicPlugin: Invalid port %s, using config settings instead", var); + } + } + + // Try to match the setting to an available ALSA device. + + if (!found && dev) { + AlsaDevices alsaDevices = getAlsaDevices(); + + for (AlsaDevices::iterator d = alsaDevices.begin(); d != alsaDevices.end(); ++d) { + MusicDevice device(this, d->getName(), d->getType()); + + if (device.getCompleteId().equals(MidiDriver::getDeviceString(dev, MidiDriver::kDeviceId))) { + found = true; + seq_client = d->getClient(); + seq_port = -1; + break; + } + } + } + + // Still nothing? Try a sensible default. + + if (!found) { + // TODO: What's a sensible default anyway? And exactly when do + // we get to this case? + + warning("AlsaMusicPlugin: Using 17:0 as default ALSA port"); + seq_client = 17; + seq_port = 0; + } + + *mididriver = new MidiDriver_ALSA(seq_client, seq_port); return Common::kNoError; } +int AlsaMusicPlugin::parse_addr(const char *arg, int *client, int *port) { + const char *p; + + if (isdigit(*arg)) { + if ((p = strpbrk(arg, ADDR_DELIM)) == NULL) + return -1; + *client = atoi(arg); + *port = atoi(p + 1); + } else { + if (*arg == 's' || *arg == 'S') { + *client = SND_SEQ_ADDRESS_SUBSCRIBERS; + *port = 0; + } else + return -1; + } + return 0; +} + //#if PLUGIN_ENABLED_DYNAMIC(ALSA) //REGISTER_PLUGIN_DYNAMIC(ALSA, PLUGIN_TYPE_MUSIC, AlsaMusicPlugin); //#else diff --git a/backends/midi/seq.cpp b/backends/midi/seq.cpp index b1815adee5..e3d2c35b39 100644 --- a/backends/midi/seq.cpp +++ b/backends/midi/seq.cpp @@ -28,7 +28,9 @@ * both the QuickTime support and (vkeybd http://www.alsa-project.org/~iwai/alsa.html) */ -#if defined(UNIX) && !defined(__BEOS__) && !defined(__MAEMO__) && !defined(__MINT__) && !defined(__ANDROID__) +#include "common/scummsys.h" + +#if defined(USE_SEQ_MIDI) #include "common/util.h" #include "sound/musicplugin.h" diff --git a/backends/midi/ypa1.cpp b/backends/midi/ypa1.cpp deleted file mode 100644 index fb114d625c..0000000000 --- a/backends/midi/ypa1.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#include "common/util.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" - -#include "Pa1Lib.h" - -class MidiDriver_YamahaPa1:public MidiDriver_MPU401 { -public: - MidiDriver_YamahaPa1(); - int open(); - void close(); - void send(uint32 b); - -private: - UInt8 _midiHandle; - Boolean _isOpen; - }; - -MidiDriver_YamahaPa1::MidiDriver_YamahaPa1() { - _isOpen = false; - _midiHandle = 0; -} - -int MidiDriver_YamahaPa1::open() { - if (!(_isOpen = Pa1Lib_midiOpen(NULL, &_midiHandle))) - return MERR_DEVICE_NOT_AVAILABLE; - - return 0; -} - -void MidiDriver_YamahaPa1::close() { - if (_isOpen) { - _isOpen = false; - MidiDriver_MPU401::close(); - for (UInt8 channel = 0; channel < 16; channel++) { - Pa1Lib_midiControlChange(_midiHandle, channel, 120,0); // all sound off - Pa1Lib_midiControlChange(_midiHandle, channel, 121,0); // reset all controller - Pa1Lib_midiControlChange(_midiHandle, channel, 123, 0); // all notes off - } - Pa1Lib_midiClose(_midiHandle); - } -} - -void MidiDriver_YamahaPa1::send(uint32 b) { - if (!_isOpen) - return; - - UInt8 midiCmd[4]; - UInt8 chanID,mdCmd; - - midiCmd[3] = (b & 0xFF000000) >> 24; - midiCmd[2] = (b & 0x00FF0000) >> 16; - midiCmd[1] = (b & 0x0000FF00) >> 8; - midiCmd[0] = (b & 0x000000FF); - - chanID = (midiCmd[0] & 0x0F) ; - mdCmd = midiCmd[0] & 0xF0; - - switch (mdCmd) { - case 0x80: // note off - Pa1Lib_midiNoteOff(_midiHandle, chanID, midiCmd[1], 0); - break; - - case 0x90: // note on - Pa1Lib_midiNoteOn(_midiHandle, chanID, midiCmd[1], midiCmd[2]); - break; - - case 0xB0: // control change - Pa1Lib_midiControlChange(_midiHandle, chanID, midiCmd[1], midiCmd[2]); - break; - - case 0xC0: // progam change - Pa1Lib_midiProgramChange(_midiHandle, chanID, midiCmd[1]); - break; - - case 0xE0: // pitchBend - Pa1Lib_midiPitchBend(_midiHandle, chanID, (short)(midiCmd[1] | (midiCmd[2] << 8))); - break; - } -} - - -// Plugin interface - -class YamahaPa1MusicPlugin : public MusicPluginObject { -public: - const char *getName() const { - return "Yamaha Pa1"; - } - - const char *getId() const { - return "ypa1"; - } - - MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; -}; - -MusicDevices YamahaPa1MusicPlugin::getDevices() const { - MusicDevices devices; - // TODO: Return a different music type depending on the configuration - // TODO: List the available devices - devices.push_back(MusicDevice(this, "", MT_GM)); - return devices; -} - -Common::Error YamahaPa1MusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { - *mididriver = new MidiDriver_YamahaPa1(); - - return Common::kNoError; -} - -//#if PLUGIN_ENABLED_DYNAMIC(YPA1) - //REGISTER_PLUGIN_DYNAMIC(YPA1, PLUGIN_TYPE_MUSIC, YamahaPa1MusicPlugin); -//#else - REGISTER_PLUGIN_STATIC(YPA1, PLUGIN_TYPE_MUSIC, YamahaPa1MusicPlugin); -//#endif diff --git a/backends/midi/zodiac.cpp b/backends/midi/zodiac.cpp deleted file mode 100644 index e848315ca4..0000000000 --- a/backends/midi/zodiac.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#include "common/util.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" - -#ifndef DISABLE_TAPWAVE - -#include <tapwave.h> - - -class MidiDriver_Zodiac:public MidiDriver_MPU401 { -public: - MidiDriver_Zodiac(); - int open(); - void close(); - void send(uint32 b); - void sysEx(const byte *msg, uint16 length); - -private: - TwMidiHandle _midiHandle; - Boolean _isOpen; - Int32 _oldVol; - }; - -MidiDriver_Zodiac::MidiDriver_Zodiac() { - _isOpen = false; - _midiHandle = 0; -} - -int MidiDriver_Zodiac::open() { - Err e; - - if (e = TwMidiOpen(&_midiHandle)) - return MERR_DEVICE_NOT_AVAILABLE; - - TwMidiGetMasterVolume(&_oldVol); - TwMidiSetMasterVolume(twMidiMaxVolume); // TODO : set volume based on gVars - - _isOpen = true; - return 0; -} - -void MidiDriver_Zodiac::close() { - if (_isOpen) { - _isOpen = false; - MidiDriver_MPU401::close(); - - TwMidiSetMasterVolume(_oldVol); - TwMidiClose(_midiHandle); - } -} - -void MidiDriver_Zodiac::send(uint32 b) { - if (!_isOpen) - return; - - UInt8 midiCmd[4]; - UInt8 chanID,mdCmd; - - midiCmd[3] = (b & 0xFF000000) >> 24; - midiCmd[2] = (b & 0x00FF0000) >> 16; - midiCmd[1] = (b & 0x0000FF00) >> 8; - midiCmd[0] = (b & 0x000000FF); - - chanID = (midiCmd[0] & 0x0F) ; - mdCmd = midiCmd[0] & 0xF0; - - switch (mdCmd) { - case 0x80: // note off - TwMidiNoteOff(_midiHandle, chanID, midiCmd[1], 0); - break; - - case 0x90: // note on - TwMidiNoteOn(_midiHandle, chanID, midiCmd[1], midiCmd[2]); - break; - - case 0xB0: // control change - TwMidiControlChange(_midiHandle, chanID, midiCmd[1], midiCmd[2]); - break; - - case 0xC0: // progam change - TwMidiProgramChange(_midiHandle, chanID, midiCmd[1]); - break; - - case 0xE0: // pitchBend - TwMidiPitchBend(_midiHandle, chanID, (short)(midiCmd[1] | (midiCmd[2] << 8))); - break; - } -} - -void MidiDriver_Zodiac::sysEx(const byte *msg, uint16 length) { - unsigned char buf[266]; - - buf[0] = 0xF0; - memcpy(buf + 1, msg, length); - buf[length + 1] = 0xF7; - - TwMidiSysEx(_midiHandle, 0, (byte *)buf, length + 2); -} - - -// Plugin interface - -class ZodiacMusicPlugin : public MusicPluginObject { -public: - const char *getName() const { - return "Tapwave Zodiac"; - } - - const char *getId() const { - return "zodiac"; - } - - MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; -}; - -MusicDevices ZodiacMusicPlugin::getDevices() const { - MusicDevices devices; - // TODO: Return a different music type depending on the configuration - // TODO: List the available devices - devices.push_back(MusicDevice(this, "", MT_GM)); - return devices; -} - -Common::Error ZodiacMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { - *mididriver = new MidiDriver_Zodiac(); - - return Common::kNoError; -} - -//#if PLUGIN_ENABLED_DYNAMIC(ZODIAC) - //REGISTER_PLUGIN_DYNAMIC(ZODIAC, PLUGIN_TYPE_MUSIC, ZodiacMusicPlugin); -//#else - REGISTER_PLUGIN_STATIC(ZODIAC, PLUGIN_TYPE_MUSIC, ZodiacMusicPlugin); -//#endif - -#endif diff --git a/backends/module.mk b/backends/module.mk index 801c98135f..f5677ed470 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -14,17 +14,9 @@ MODULE_OBJS := \ fs/abstract-fs.o \ fs/stdiostream.o \ fs/amigaos4/amigaos4-fs-factory.o \ - fs/ds/ds-fs-factory.o \ - fs/palmos/palmos-fs-factory.o \ fs/posix/posix-fs-factory.o \ - fs/ps2/ps2-fs-factory.o \ - fs/psp/psp-fs-factory.o \ - fs/psp/psp-stream.o \ fs/symbian/symbian-fs-factory.o \ fs/windows/windows-fs-factory.o \ - fs/wii/wii-fs-factory.o \ - fs/n64/n64-fs-factory.o \ - fs/n64/romfsstream.o \ graphics/gp2xsdl/gp2xsdl-graphics.o \ graphics/gp2xwizsdl/gp2xwizsdl-graphics.o \ graphics/linuxmotosdl/linuxmotosdl-graphics.o \ @@ -55,13 +47,10 @@ MODULE_OBJS := \ plugins/posix/posix-provider.o \ plugins/sdl/sdl-provider.o \ plugins/win32/win32-provider.o \ - plugins/psp/psp-provider.o \ saves/savefile.o \ saves/default/default-saves.o \ saves/posix/posix-saves.o \ - saves/psp/psp-saves.o \ timer/default/default-timer.o \ - timer/psp/timer.o \ timer/sdl/sdl-timer.o \ vkeybd/image-map.o \ vkeybd/polygon.o \ @@ -69,5 +58,41 @@ MODULE_OBJS := \ vkeybd/virtual-keyboard-gui.o \ vkeybd/virtual-keyboard-parser.o +ifeq ($(BACKEND),dc) +MODULE_OBJS += \ + plugins/dc/dc-provider.o +endif + +ifeq ($(BACKEND),ds) +MODULE_OBJS += \ + fs/ds/ds-fs-factory.o \ + fs/ds/ds-fs.o +endif + +ifeq ($(BACKEND),n64) +MODULE_OBJS += \ + fs/n64/n64-fs-factory.o \ + fs/n64/romfsstream.o +endif + +ifeq ($(BACKEND),ps2) +MODULE_OBJS += \ + fs/ps2/ps2-fs-factory.o +endif + +ifeq ($(BACKEND),psp) +MODULE_OBJS += \ + fs/psp/psp-fs-factory.o \ + fs/psp/psp-stream.o \ + plugins/psp/psp-provider.o \ + saves/psp/psp-saves.o \ + timer/psp/timer.o +endif + +ifeq ($(BACKEND),wii) +MODULE_OBJS += \ + fs/wii/wii-fs-factory.o +endif + # Include common rules include $(srcdir)/rules.mk diff --git a/backends/platform/PalmOS/Rsc/Resource.Frk/Starter.rsrc b/backends/platform/PalmOS/Rsc/Resource.Frk/Starter.rsrc Binary files differdeleted file mode 100644 index 70f74412e7..0000000000 --- a/backends/platform/PalmOS/Rsc/Resource.Frk/Starter.rsrc +++ /dev/null diff --git a/backends/platform/PalmOS/Rsc/Starter.rsrc b/backends/platform/PalmOS/Rsc/Starter.rsrc deleted file mode 100644 index e69de29bb2..0000000000 --- a/backends/platform/PalmOS/Rsc/Starter.rsrc +++ /dev/null diff --git a/backends/platform/PalmOS/Rsc/StarterRsc.h b/backends/platform/PalmOS/Rsc/StarterRsc.h deleted file mode 100644 index fba46b310b..0000000000 --- a/backends/platform/PalmOS/Rsc/StarterRsc.h +++ /dev/null @@ -1,395 +0,0 @@ -#ifndef STARTERRSC_H -#define STARTERRSC_H - -// Header generated by Constructor for Palm OS (R) 1.9.1 -// -// Generated at 12:00:06 on samedi 25 août 2007 -// -// Generated for file: Starter.rsrc -// -// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE -// DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST -// -// Palm App Name: "ScummVM" -// -// Palm App Version: "1.0" - - -// Resource: tFRM 1000 -#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) -#define MainCardsButton 1003 //(Left Origin = 135, Top Origin = 1, Width = 12, Height = 12, Usable = 1, Anchor Left = 1, Frame = 0, Non-bold Frame = 0, Font = Standard) -#define MainAboutButton 1012 //(Left Origin = 148, Top Origin = 1, Width = 12, Height = 12, Usable = 1, Anchor Left = 1, Frame = 0, Non-bold Frame = 1, Font = Standard) -#define MainMSBitMap 1100 //(Left Origin = 135, Top Origin = 1, Bitmap Resource ID = 1100, Usable = 0) -#define MainMSNoneBitMap 1110 //(Left Origin = 135, Top Origin = 1, Bitmap Resource ID = 1110, Usable = 0) -#define MainUnnamed1010BitMap 2000 //(Left Origin = 148, Top Origin = 1, Bitmap Resource ID = 2000, Usable = 1) - -// Resource: tFRM 1200 -#define SkinsForm 1200 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 1203) -#define SkinsOKButton 1202 //(Left Origin = 5, Top Origin = 139, Width = 32, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define SkinsCancelButton 1203 //(Left Origin = 43, Top Origin = 139, Width = 32, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define SkinsDeleteButton 1205 //(Left Origin = 119, Top Origin = 139, Width = 32, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define SkinsBeamButton 1206 //(Left Origin = 81, Top Origin = 139, Width = 32, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define SkinsSoundClickCheckbox 1204 //(Left Origin = 5, Top Origin = 118, Width = 93, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define SkinsSkinList 1201 //(Left Origin = 5, Top Origin = 17, Width = 146, Usable = 1, Font = Standard, Visible Items = 9) - -// Resource: tFRM 1500 -#define CardSlotForm 1500 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define CardSlotOkButton 1510 //(Left Origin = 3, Top Origin = 140, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define CardSlotCancelButton 1511 //(Left Origin = 44, Top Origin = 140, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) - -// Resource: tFRM 2700 -#define MiscForm 2700 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define MiscOKButton 2710 //(Left Origin = 5, Top Origin = 139, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define MiscCancelButton 2711 //(Left Origin = 46, Top Origin = 139, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) - -// Resource: tFRM 2000 -#define ConvertForm 2000 //(Left Origin = 34, Top Origin = 64, Width = 91, Height = 32, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define ConvertUnnamed2001Label 2001 //(Left Origin = 7, Top Origin = 4, Usable = 1, Font = Standard) -#define ConvertUnnamed2002Label 2002 //(Left Origin = 16, Top Origin = 16, Usable = 1, Font = Bold) - -// Resource: tFRM 2100 -#define BeamForm 2100 //(Left Origin = 2, Top Origin = 72, Width = 156, Height = 86, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define BeamSendButton 2105 //(Left Origin = 5, Top Origin = 69, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define BeamCancelButton 2106 //(Left Origin = 47, Top Origin = 69, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define BeamMathlibCheckbox 2101 //(Left Origin = 4, Top Origin = 28, Width = 55, Height = 12, Usable = 1, Selected = 1, Group ID = 0, Font = Standard) -#define BeamGamesCheckbox 2103 //(Left Origin = 4, Top Origin = 40, Width = 86, Height = 12, Usable = 1, Selected = 1, Group ID = 0, Font = Standard) -#define BeamSkinCheckbox 2104 //(Left Origin = 4, Top Origin = 52, Width = 84, Height = 12, Usable = 1, Selected = 1, Group ID = 0, Font = Standard) -#define BeamUnnamed2102Label 2102 //(Left Origin = 4, Top Origin = 16, Usable = 1, Font = Bold) - -// Resource: tFRM 2200 -#define MusicForm 2200 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define MusicOKButton 2210 //(Left Origin = 5, Top Origin = 139, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define MusicCancelButton 2211 //(Left Origin = 46, Top Origin = 139, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) - -// Resource: tFRM 2300 -#define TabMusicForm 2300 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 120, Usable = 0, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabMusicMusicCheckbox 2301 //(Left Origin = 4, Top Origin = 12, Width = 100, Height = 12, Usable = 1, Selected = 1, Group ID = 0, Font = Standard) -#define TabMusicMultiMidiCheckbox 2308 //(Left Origin = 4, Top Origin = 24, Width = 120, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMusicTempoField 2302 //(Left Origin = 54, Top Origin = 36, Width = 16, Height = 12, Usable = 1, Editable = 1, Underline = 1, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 3, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 1) -#define TabMusicTitleLabel 2303 //(Left Origin = 6, Top Origin = 0, Usable = 1, Font = Bold) -#define TabMusicUnnamed2304Label 2304 //(Left Origin = 21, Top Origin = 48, Usable = 1, Font = Standard) -#define TabMusicUnnamed2305Label 2305 //(Left Origin = 16, Top Origin = 60, Usable = 1, Font = Standard) -#define TabMusicUnnamed2306Label 2306 //(Left Origin = 18, Top Origin = 36, Usable = 1, Font = Standard) -#define TabMusicUnnamed2307Label 2307 //(Left Origin = 72, Top Origin = 36, Usable = 1, Font = Standard) -#define TabMusicUnnamed2309Label 2309 //(Left Origin = 28, Top Origin = 72, Usable = 1, Font = Standard) -#define TabMusicRateList 2311 //(Left Origin = 54, Top Origin = 73, Width = 55, Usable = 0, Font = Standard, Visible Items = 3) -#define TabMusicQualityList 2313 //(Left Origin = 54, Top Origin = 60, Width = 60, Usable = 0, Font = Standard, Visible Items = 3) -#define TabMusicDriverList 2331 //(Left Origin = 54, Top Origin = 24, Width = 65, Usable = 0, Font = Standard, Visible Items = 4) -#define TabMusicRatePopTrigger 2310 //(Left Origin = 54, Top Origin = 72, Width = 55, Height = 12, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 2311) -#define TabMusicQualityPopTrigger 2312 //(Left Origin = 54, Top Origin = 60, Width = 50, Height = 12, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 2313) -#define TabMusicDriverPopTrigger 2330 //(Left Origin = 54, Top Origin = 48, Width = 65, Height = 12, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 2331) - -// Resource: tFRM 2500 -#define TabAudioCDForm 2500 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 110, Usable = 0, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabAudioCDMP3Checkbox 2502 //(Left Origin = 4, Top Origin = 12, Width = 125, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabAudioCDLengthSecsField 2504 //(Left Origin = 112, Top Origin = 60, Width = 16, Height = 12, Usable = 1, Editable = 1, Underline = 1, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 3, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 1) -#define TabAudioCDFirstTrackField 2507 //(Left Origin = 112, Top Origin = 50, Width = 16, Height = 12, Usable = 1, Editable = 1, Underline = 1, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 80, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 1) -#define TabAudioCDUnnamed2501Label 2501 //(Left Origin = 6, Top Origin = 0, Usable = 1, Font = Bold) -#define TabAudioCDUnnamed2503Label 2503 //(Left Origin = 20, Top Origin = 60, Usable = 1, Font = Standard) -#define TabAudioCDUnnamed2505Label 2505 //(Left Origin = 130, Top Origin = 61, Usable = 1, Font = Standard) -#define TabAudioCDUnnamed2506Label 2506 //(Left Origin = 21, Top Origin = 48, Usable = 1, Font = Standard) -#define TabAudioCDUnnamed2508Label 2508 //(Left Origin = 25, Top Origin = 24, Usable = 1, Font = Standard) -#define TabAudioCDUnnamed2511Label 2511 //(Left Origin = 21, Top Origin = 36, Usable = 1, Font = Standard) -#define TabAudioCDUnnamed2514Label 2514 //(Left Origin = 4, Top Origin = 80, Usable = 1, Font = Standard) -#define TabAudioCDDriverList 2510 //(Left Origin = 58, Top Origin = 24, Width = 90, Usable = 0, Font = Standard, Visible Items = 4) -#define TabAudioCDFormatList 2513 //(Left Origin = 58, Top Origin = 36, Width = 70, Usable = 0, Font = Standard, Visible Items = 2) -#define TabAudioCDDriverPopTrigger 2509 //(Left Origin = 58, Top Origin = 24, Width = 90, Height = 12, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 2510) -#define TabAudioCDFormatPopTrigger 2512 //(Left Origin = 58, Top Origin = 36, Width = 70, Height = 12, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 2513) - -// Resource: tFRM 2600 -#define TabVolumeForm 2600 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 100, Usable = 0, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabVolumeUnnamed2601Label 2601 //(Left Origin = 29, Top Origin = 69, Usable = 1, Font = Standard) -#define TabVolumeUnnamed2603Label 2603 //(Left Origin = 6, Top Origin = 0, Usable = 1, Font = Bold) -#define TabVolumeUnnamed2606Label 2606 //(Left Origin = 26, Top Origin = 15, Usable = 1, Font = Standard) -#define TabVolumeUnnamed2607Label 2607 //(Left Origin = 12, Top Origin = 30, Usable = 1, Font = Standard) -#define TabVolumeUnnamed2608Label 2608 //(Left Origin = 20, Top Origin = 45, Usable = 1, Font = Standard) -#define TabVolumeUnnamed2610Label 2610 //(Left Origin = 14, Top Origin = 84, Usable = 1, Font = Standard) -#define TabVolumeMusicSliderControl 2602 //(Left Origin = 58, Top Origin = 12, Width = 93, Height = 15, Usable = 1, Initial Value = 0, Minimum Value = 0, Maximum Value = 255, Page Jump Amount = 1, Thumb Bitmap = 0, Background Bitmap = 0) -#define TabVolumeSfxSliderControl 2604 //(Left Origin = 58, Top Origin = 27, Width = 93, Height = 15, Usable = 1, Initial Value = 0, Minimum Value = 0, Maximum Value = 255, Page Jump Amount = 1, Thumb Bitmap = 0, Background Bitmap = 0) -#define TabVolumePalmSliderControl 2605 //(Left Origin = 58, Top Origin = 66, Width = 93, Height = 15, Usable = 1, Initial Value = 0, Minimum Value = 0, Maximum Value = 100, Page Jump Amount = 1, Thumb Bitmap = 0, Background Bitmap = 0) -#define TabVolumeSpeechSliderControl 2609 //(Left Origin = 58, Top Origin = 42, Width = 93, Height = 15, Usable = 1, Initial Value = 0, Minimum Value = 0, Maximum Value = 255, Page Jump Amount = 1, Thumb Bitmap = 0, Background Bitmap = 0) -#define TabVolumeAudioCDSliderControl 2611 //(Left Origin = 58, Top Origin = 81, Width = 93, Height = 15, Usable = 1, Initial Value = 0, Minimum Value = 0, Maximum Value = 100, Page Jump Amount = 1, Thumb Bitmap = 0, Background Bitmap = 0) - -// Resource: tFRM 2800 -#define TabMiscPalmOSForm 2800 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 120, Usable = 0, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabMiscPalmOSVibratorCheckbox 2802 //(Left Origin = 4, Top Origin = 12, Width = 128, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscPalmOSNoAutoOffCheckbox 2803 //(Left Origin = 4, Top Origin = 24, Width = 152, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscPalmOSStdPaletteCheckbox 2804 //(Left Origin = 4, Top Origin = 84, Width = 146, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscPalmOSLargerStackCheckbox 2805 //(Left Origin = 4, Top Origin = 36, Width = 100, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscPalmOSAdvancedCheckbox 2806 //(Left Origin = 4, Top Origin = 96, Width = 100, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscPalmOSArrowCheckbox 2807 //(Left Origin = 4, Top Origin = 72, Width = 150, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscPalmOSExitLauncherCheckbox 2810 //(Left Origin = 4, Top Origin = 48, Width = 150, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscPalmOSStylusClickCheckbox 2811 //(Left Origin = 4, Top Origin = 60, Width = 120, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscPalmOSTabTitlePalmLabel 2801 //(Left Origin = 4, Top Origin = 0, Usable = 1, Font = Bold) - -// Resource: tFRM 2900 -#define TabMiscScummVMForm 2900 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 120, Usable = 0, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabMiscScummVMAutosaveCheckbox 2902 //(Left Origin = 4, Top Origin = 48, Width = 90, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscScummVMDebugCheckbox 2904 //(Left Origin = 4, Top Origin = 60, Width = 90, Height = 12, Usable = 0, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscScummVMDemoCheckbox 2905 //(Left Origin = 4, Top Origin = 12, Width = 100, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscScummVMCopyProtectionCheckbox 2906 //(Left Origin = 4, Top Origin = 24, Width = 120, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscScummVMAltIntroCheckbox 2908 //(Left Origin = 4, Top Origin = 36, Width = 120, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscScummVMDebugLevelField 2907 //(Left Origin = 101, Top Origin = 60, Width = 12, Height = 12, Usable = 1, Editable = 1, Underline = 1, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 1, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 1) -#define TabMiscScummVMAutosaveField 2910 //(Left Origin = 101, Top Origin = 48, Width = 20, Height = 12, Usable = 1, Editable = 1, Underline = 1, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 4, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 1) -#define TabMiscScummVMTabTitleScummLabel 2901 //(Left Origin = 4, Top Origin = 0, Usable = 1, Font = Bold) -#define TabMiscScummVMUnnamed2903Label 2903 //(Left Origin = 97, Top Origin = 61, Usable = 1, Font = Standard) -#define TabMiscScummVMUnnamed2909Label 2909 //(Left Origin = 97, Top Origin = 48, Usable = 1, Font = Standard) -#define TabMiscScummVMUnnamed2911Label 2911 //(Left Origin = 123, Top Origin = 48, Usable = 1, Font = Standard) - -// Resource: tFRM 3000 -#define GameEditForm 3000 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 1411) -#define GameEditOKButton 3020 //(Left Origin = 5, Top Origin = 139, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define GameEditCancelButton 3021 //(Left Origin = 46, Top Origin = 139, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define GameEditDeleteButton 3023 //(Left Origin = 109, Top Origin = 139, Width = 42, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define GameEditUnnamed3022GraffitiShift 3022 //(Left Origin = 87, Top Origin = 140) - -// Resource: tFRM 3100 -#define TabGameInfoForm 3100 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 120, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabGameInfoEntryNameField 3102 //(Left Origin = 4, Top Origin = 12, Width = 151, Height = 24, Usable = 1, Editable = 1, Underline = 1, Single Line = 0, Dynamic Size = 0, Left Justified = 1, Max Characters = 50, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 0) -#define TabGameInfoPathField 3104 //(Left Origin = 37, Top Origin = 38, Width = 118, Height = 24, Usable = 1, Editable = 1, Underline = 1, Single Line = 0, Dynamic Size = 0, Left Justified = 1, Max Characters = 150, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 0) -#define TabGameInfoGameField 3106 //(Left Origin = 37, Top Origin = 64, Width = 52, Height = 12, Usable = 1, Editable = 1, Underline = 1, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 15, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 0) -#define TabGameInfoUnnamed3101Label 3101 //(Left Origin = 4, Top Origin = 0, Usable = 1, Font = Bold) -#define TabGameInfoUnnamed3103Label 3103 //(Left Origin = 11, Top Origin = 38, Usable = 1, Font = Standard) -#define TabGameInfoUnnamed3105Label 3105 //(Left Origin = 6, Top Origin = 64, Usable = 1, Font = Standard) -#define TabGameInfoUnnamed3107Label 3107 //(Left Origin = 4, Top Origin = 79, Usable = 1, Font = Standard) -#define TabGameInfoEngineList 3109 //(Left Origin = 37, Top Origin = 57, Width = 115, Usable = 0, Font = Standard, Visible Items = 3) -#define TabGameInfoBrowsePushButton 3110 //(Left Origin = 11, Top Origin = 50, Width = 22, Height = 12, Usable = 1, Group ID = 0, Font = Standard) -#define TabGameInfoEnginePopTrigger 3108 //(Left Origin = 37, Top Origin = 79, Width = 115, Height = 12, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 3109) - -// Resource: tFRM 3200 -#define TabGameDisplayForm 3200 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 95, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabGameDisplayFilterCheckbox 3205 //(Left Origin = 4, Top Origin = 36, Width = 80, Height = 12, Usable = 1, Selected = 1, Group ID = 0, Font = Standard) -#define TabGameDisplayFullscreenCheckbox 3206 //(Left Origin = 4, Top Origin = 60, Width = 100, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabGameDisplayAspectRatioCheckbox 3207 //(Left Origin = 4, Top Origin = 48, Width = 120, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabGameDisplayUnnamed3201Label 3201 //(Left Origin = 4, Top Origin = 0, Usable = 1, Font = Bold) -#define TabGameDisplayUnnamed3202Label 3202 //(Left Origin = 5, Top Origin = 24, Usable = 1, Font = Standard) -#define TabGameDisplayUnnamed3208Label 3208 //(Left Origin = 10, Top Origin = 12, Usable = 1, Font = Standard) -#define TabGameDisplayGfxListList 3204 //(Left Origin = 38, Top Origin = 12, Width = 75, Usable = 0, Font = Standard, Visible Items = 2) -#define TabGameDisplayRenderList 3210 //(Left Origin = 38, Top Origin = 24, Width = 75, Usable = 0, Font = Standard, Visible Items = 6) -#define TabGameDisplayGfxPopupPopTrigger 3203 //(Left Origin = 38, Top Origin = 12, Width = 80, Height = 12, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 3204) -#define TabGameDisplayRenderPopTrigger 3209 //(Left Origin = 38, Top Origin = 24, Width = 85, Height = 12, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 3209) - -// Resource: tFRM 3300 -#define TabGameOptionsForm 3300 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabGameOptionsLoadSlotCheckbox 3302 //(Left Origin = 4, Top Origin = 24, Width = 85, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabGameOptionsStartRoomCheckbox 3303 //(Left Origin = 4, Top Origin = 36, Width = 84, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabGameOptionsAmigaCheckbox 3306 //(Left Origin = 4, Top Origin = 48, Width = 81, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabGameOptionsSubtitlesCheckbox 3307 //(Left Origin = 4, Top Origin = 60, Width = 82, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabGameOptionsTalkSpeedCheckbox 3308 //(Left Origin = 4, Top Origin = 12, Width = 66, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabGameOptionsLoadSlotField 3304 //(Left Origin = 92, Top Origin = 24, Width = 12, Height = 12, Usable = 1, Editable = 1, Underline = 1, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 2, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 1) -#define TabGameOptionsStartRoomField 3305 //(Left Origin = 92, Top Origin = 36, Width = 18, Height = 12, Usable = 1, Editable = 1, Underline = 1, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 4, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 1) -#define TabGameOptionsTalkSpeedField 3309 //(Left Origin = 92, Top Origin = 12, Width = 18, Height = 12, Usable = 1, Editable = 1, Underline = 1, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 3, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 1) -#define TabGameOptionsUnnamed3301Label 3301 //(Left Origin = 4, Top Origin = 0, Usable = 1, Font = Bold) -#define TabGameOptionsUnnamed3314Label 3314 //(Left Origin = 88, Top Origin = 24, Usable = 1, Font = Standard) -#define TabGameOptionsUnnamed3315Label 3315 //(Left Origin = 88, Top Origin = 36, Usable = 1, Font = Standard) -#define TabGameOptionsUnnamed3316Label 3316 //(Left Origin = 88, Top Origin = 12, Usable = 1, Font = Standard) -#define TabGameOptionsUnnamed3317Label 3317 //(Left Origin = 88, Top Origin = 48, Usable = 1, Font = Standard) -#define TabGameOptionsUnnamed3318Label 3318 //(Left Origin = 88, Top Origin = 60, Usable = 1, Font = Standard) -#define TabGameOptionsLanguageList 3311 //(Left Origin = 92, Top Origin = 15, Width = 64, Usable = 0, Font = Standard, Visible Items = 5) -#define TabGameOptionsPlatformList 3313 //(Left Origin = 92, Top Origin = 15, Width = 64, Usable = 0, Font = Standard, Visible Items = 4) -#define TabGameOptionsLanguagePopTrigger 3310 //(Left Origin = 90, Top Origin = 60, Width = 65, Height = 12, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 3311) -#define TabGameOptionsPlatformPopTrigger 3312 //(Left Origin = 90, Top Origin = 48, Width = 65, Height = 12, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 3313) - -// Resource: tFRM 3400 -#define ImportForm 3400 //(Left Origin = 34, Top Origin = 64, Width = 91, Height = 32, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define ImportUnnamed3401Label 3401 //(Left Origin = 4, Top Origin = 4, Usable = 1, Font = Standard) -#define ImportUnnamed3402Label 3402 //(Left Origin = 16, Top Origin = 16, Usable = 1, Font = Bold) - -// Resource: tFRM 1400 -#define EngineForm 1400 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define EngineOkButton 1403 //(Left Origin = 4, Top Origin = 139, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define EngineCancelButton 1420 //(Left Origin = 45, Top Origin = 139, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) -#define EngineUnnamed1402Label 1402 //(Left Origin = 4, Top Origin = 16, Usable = 1, Font = Bold) -#define EngineUnnamed1404Label 1404 //(Left Origin = 4, Top Origin = 88, Usable = 1, Font = Bold) -#define EngineListList 1401 //(Left Origin = 4, Top Origin = 30, Width = 148, Usable = 1, Font = Standard, Visible Items = 5) -#define EngineSupportedList 1405 //(Left Origin = 4, Top Origin = 102, Width = 148, Usable = 1, Font = Standard, Visible Items = 3) - -// Resource: tFRM 4000 -#define InfoForm 4000 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define InfoOKButton 4020 //(Left Origin = 5, Top Origin = 139, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) - -// Resource: tFRM 4100 -#define TabInfoAboutForm 4100 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 125, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabInfoAboutTabTitleAboutLabel 4101 //(Left Origin = 4, Top Origin = 0, Usable = 1, Font = Bold) -#define TabInfoAboutUnnamed4103Label 4103 //(Left Origin = 23, Top Origin = 58, Usable = 1, Font = Bold) -#define TabInfoAboutUnnamed4104Label 4104 //(Left Origin = 34, Top Origin = 70, Usable = 1, Font = Standard) -#define TabInfoAboutUnnamed4105Label 4105 //(Left Origin = 8, Top Origin = 82, Usable = 1, Font = Bold) - -// Resource: tFRM 4200 -#define TabInfoVersionForm 4200 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 100, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabInfoVersionTabTitleAboutLabel 4201 //(Left Origin = 4, Top Origin = 0, Usable = 1, Font = Bold) -#define TabInfoVersionUnnamed4202Label 4202 //(Left Origin = 10, Top Origin = 12, Usable = 1, Font = Standard) -#define TabInfoVersionUnnamed4203Label 4203 //(Left Origin = 24, Top Origin = 24, Usable = 1, Font = Standard) -#define TabInfoVersionUnnamed4204Label 4204 //(Left Origin = 4, Top Origin = 42, Usable = 1, Font = Bold) -#define TabInfoVersionUnnamed4205Label 4205 //(Left Origin = 5, Top Origin = 53, Usable = 1, Font = Standard) -#define TabInfoVersionUnnamed4206Label 4206 //(Left Origin = 4, Top Origin = 72, Usable = 1, Font = Bold) -#define TabInfoVersionUnnamed4207Label 4207 //(Left Origin = 4, Top Origin = 84, Usable = 1, Font = Standard) - -// Resource: tFRM 4300 -#define TabInfoSystemForm 4300 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 100, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabInfoSystemTabTitleAboutLabel 4301 //(Left Origin = 4, Top Origin = 0, Usable = 1, Font = Bold) -#define TabInfoSystemUnnamed4302Label 4302 //(Left Origin = 10, Top Origin = 12, Usable = 1, Font = Standard) -#define TabInfoSystemUnnamed4303Label 4303 //(Left Origin = 13, Top Origin = 24, Usable = 1, Font = Standard) -#define TabInfoSystemUnnamed4304Label 4304 //(Left Origin = 5, Top Origin = 36, Usable = 1, Font = Standard) -#define TabInfoSystemUnnamed4305Label 4305 //(Left Origin = 96, Top Origin = 0, Usable = 1, Font = Standard) -#define TabInfoSystemUnnamed4306Label 4306 //(Left Origin = 132, Top Origin = 0, Usable = 1, Font = Standard) - -// Resource: tFRM 1600 -#define TabCardConfigForm 1600 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 110, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabCardConfigDetectCheckbox 1602 //(Left Origin = 4, Top Origin = 86, Width = 150, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabCardConfigCacheCheckbox 1604 //(Left Origin = 4, Top Origin = 62, Width = 120, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabCardConfigLedCheckbox 1608 //(Left Origin = 4, Top Origin = 50, Width = 130, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabCardConfigCacheSizeField 1606 //(Left Origin = 68, Top Origin = 74, Width = 18, Height = 12, Usable = 1, Editable = 1, Underline = 1, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 3, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 1) -#define TabCardConfigTabTitleAboutLabel 1601 //(Left Origin = 4, Top Origin = 0, Usable = 1, Font = Bold) -#define TabCardConfigUnnamed1605Label 1605 //(Left Origin = 21, Top Origin = 74, Usable = 1, Font = Standard) -#define TabCardConfigUnnamed1607Label 1607 //(Left Origin = 88, Top Origin = 74, Usable = 1, Font = Standard) -#define TabCardConfigSlotList 1620 //(Left Origin = 7, Top Origin = 14, Width = 146, Usable = 1, Font = Standard, Visible Items = 3) - -// Resource: tFRM 1700 -#define TabCardGameListForm 1700 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 100, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabCardGameListMoveCheckbox 1702 //(Left Origin = 4, Top Origin = 12, Width = 143, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabCardGameListDeleteCheckbox 1703 //(Left Origin = 4, Top Origin = 24, Width = 142, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabCardGameListConfirmCheckbox 1704 //(Left Origin = 4, Top Origin = 36, Width = 152, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabCardGameListUnnamed1701Label 1701 //(Left Origin = 4, Top Origin = 0, Usable = 1, Font = Bold) - -// Resource: tFRM 3500 -#define TabMiscExtsForm 3500 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 80, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) -#define TabMiscExtsLightspeedCheckbox 3502 //(Left Origin = 4, Top Origin = 24, Width = 95, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscExtsGolcdCheckbox 3505 //(Left Origin = 4, Top Origin = 12, Width = 120, Height = 12, Usable = 1, Selected = 0, Group ID = 0, Font = Standard) -#define TabMiscExtsTabTitleMoreLabel 3501 //(Left Origin = 4, Top Origin = 0, Usable = 1, Font = Bold) -#define TabMiscExtsNothingLabel 3506 //(Left Origin = 4, Top Origin = 36, Usable = 0, Font = Standard) -#define TabMiscExtsLightspeedList 3504 //(Left Origin = 96, Top Origin = 24, Width = 50, Usable = 0, Font = Standard, Visible Items = 3) -#define TabMiscExtsLightspeedPopTrigger 3503 //(Left Origin = 96, Top Origin = 24, Width = 60, Height = 12, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 3504) - - -// Resource: Talt 1001 -#define RomIncompatibleAlert 1001 -#define RomIncompatibleOK 0 - -// Resource: Talt 1000 -#define FrmWarnAlert 1000 -#define FrmWarnOK 0 - -// Resource: Talt 1100 -#define FrmErrorAlert 1100 -#define FrmErrorCancel 0 - -// Resource: Talt 1300 -#define FrmConfirmAlert 1300 -#define FrmConfirmYes 0 -#define FrmConfirmNo 1 - -// Resource: Talt 1400 -#define FrmInfoAlert 1400 -#define FrmInfoOK 0 - - -// Resource: MBAR 1000 -#define MainFormMenuBar 1000 - - -// Resource: MENU 1000 -#define MainOptionsMenu 1000 -#define MainOptionsMisc 1000 // Command Key: I -#define MainOptionsSkins 1001 -#define MainOptionsBeam 1003 -#define MainOptionsAbout 1005 - -// Resource: MENU 1100 -#define MainGamesMenu 1100 -#define MainGamesNew 1100 // Command Key: N -#define MainGamesEdit 1101 // Command Key: E -#define MainGamesMusicSound 1102 // Command Key: M -#define MainGamesDelete 1103 -#define MainGamesMemoryCard 1105 // Command Key: C - - -// Resource: tSTR 9991 -#define ClieCatString 9991 // "32779" - -// Resource: tSTR 9990 -#define ClieDescString 9990 // "Play your favorite Point'n'Click games" - - -// Resource: PICT 1001 -#define Bitmap 1001 - -// Resource: PICT 1002 -#define Bitmap2 1002 - -// Resource: PICT 1008 -#define Bitmap3 1008 - -// Resource: PICT 1011 -#define Bitmap4 1011 - -// Resource: PICT 1012 -#define Bitmap5 1012 - -// Resource: PICT 1018 -#define Bitmap6 1018 - -// Resource: PICT 2000 -#define infoBitmap 2000 - -// Resource: PICT 1100 -#define msOnBitmap 1100 - -// Resource: PICT 1009 -#define Bitmap7 1009 - -// Resource: PICT 1010 -#define Bitmap8 1010 - -// Resource: PICT 1110 -#define msNoneBitmap 1110 - -// Resource: PICT 1020 -#define BitmapID1020Bitmap 1020 - -// Resource: PICT 1019 -#define BitmapID1019Bitmap 1019 - -// Resource: PICT 1200 -#define msOnD2Bitmap 1200 - -// Resource: PICT 1300 -#define msNoneD2Bitmap 1300 - -// Resource: PICT 2100 -#define infoD2Bitmap 2100 - -// Resource: PICT 1501 -#define ScummVMlogoD1Bitmap 1501 - -// Resource: PICT 1502 -#define ScummVMlogoD2Bitmap 1502 - -// Resource: PICT 1000 -#define icon16bitD2Bitmap 1000 - - -// Resource: tbmf 1000 -#define Icon_infoBitmapFamily 1000 - -// Resource: tbmf 1100 -#define MsOnBitmapFamily 1100 - -// Resource: tbmf 2000 -#define InfoBitmapFamily 2000 - -// Resource: tbmf 1110 -#define MsNoneBitmapFamily 1110 - -// Resource: tbmf 1200 -#define LogoBitmapFamily 1200 - - -// Resource: taif 1000 -#define Largeicons12and8bitsAppIconFamily 1000 - -// Resource: taif 1001 -#define Smallicons12and8bitsAppIconFamily 1001 - - -#endif // STARTERRSC_H diff --git a/backends/platform/PalmOS/Rsc/batLow.bmp b/backends/platform/PalmOS/Rsc/batLow.bmp Binary files differdeleted file mode 100644 index 1d18131450..0000000000 --- a/backends/platform/PalmOS/Rsc/batLow.bmp +++ /dev/null diff --git a/backends/platform/PalmOS/Rsc/keyAlt.bmp b/backends/platform/PalmOS/Rsc/keyAlt.bmp Binary files differdeleted file mode 100644 index 28165394f8..0000000000 --- a/backends/platform/PalmOS/Rsc/keyAlt.bmp +++ /dev/null diff --git a/backends/platform/PalmOS/Rsc/keyCommand.bmp b/backends/platform/PalmOS/Rsc/keyCommand.bmp Binary files differdeleted file mode 100644 index 1324037cd3..0000000000 --- a/backends/platform/PalmOS/Rsc/keyCommand.bmp +++ /dev/null diff --git a/backends/platform/PalmOS/Rsc/keyCtrl.bmp b/backends/platform/PalmOS/Rsc/keyCtrl.bmp Binary files differdeleted file mode 100644 index fed20fd8d0..0000000000 --- a/backends/platform/PalmOS/Rsc/keyCtrl.bmp +++ /dev/null diff --git a/backends/platform/PalmOS/Rsc/modules.rcp b/backends/platform/PalmOS/Rsc/modules.rcp deleted file mode 100644 index c7b17221b2..0000000000 --- a/backends/platform/PalmOS/Rsc/modules.rcp +++ /dev/null @@ -1,71 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2010 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -BITMAP ID 3100 -BEGIN - BITMAP "keyCommand.bmp" BPP 1 DENSITY 2 -END -BITMAP ID 3101 -BEGIN - BITMAP "keyAlt.bmp" BPP 1 DENSITY 2 -END -BITMAP ID 3102 -BEGIN - BITMAP "keyCtrl.bmp" BPP 1 DENSITY 2 -END -BITMAP ID 3120 -BEGIN - BITMAP "batLow.bmp" BPP 1 DENSITY 2 -END -BITMAP ID 3130 -BEGIN - BITMAP "numpad.bmp" BPP 1 DENSITY 2 -END - -/* -BITMAP ID 3100 "keyCommand.bmp" DENSITY 2 -BITMAP ID 3101 "keyAlt.bmp" DENSITY 2 -BITMAP ID 3102 "keyCtrl.bmp" DENSITY 2 -BITMAP ID 3120 "batLow.bmp" DENSITY 2 -BITMAP ID 3130 "numpad.bmp" DENSITY 2 -*/ -BITMAP ID 3000 "keyCommand.bmp" DENSITY 1 -BITMAP ID 3001 "keyAlt.bmp" DENSITY 1 -BITMAP ID 3002 "keyCtrl.bmp" DENSITY 1 -BITMAP ID 3020 "batLow.bmp" DENSITY 1 -BITMAP ID 3030 "numpad.bmp" DENSITY 1 - -ALERT ID 1200 - DEFAULTBUTTON 0 - ERROR -BEGIN - TITLE "ScummVM Fatal Error" - MESSAGE "^1" - BUTTONS "Exit" -END - diff --git a/backends/platform/PalmOS/Rsc/modulesrsc.h b/backends/platform/PalmOS/Rsc/modulesrsc.h deleted file mode 100644 index 14b32ee0b6..0000000000 --- a/backends/platform/PalmOS/Rsc/modulesrsc.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef MODULESRSC_H -#define MODULESRSC_H - -#define FrmFatalErrorAlert 1200 - -#endif diff --git a/backends/platform/PalmOS/Rsc/numpad.bmp b/backends/platform/PalmOS/Rsc/numpad.bmp Binary files differdeleted file mode 100644 index 7763d76c05..0000000000 --- a/backends/platform/PalmOS/Rsc/numpad.bmp +++ /dev/null diff --git a/backends/platform/PalmOS/Src/args.cpp b/backends/platform/PalmOS/Src/args.cpp deleted file mode 100644 index bfc34866e3..0000000000 --- a/backends/platform/PalmOS/Src/args.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include <PalmOS.h> -#include "palmdefs.h" -#include "args.h" -#include "pace.h" -#include "endianutils.h" - -Char **ArgsInit() { - // first 4 bytes keep the real address of the chunk - MemHandle argvH = MemHandleNew(sizeof(Char *) + (MAX_ARG * sizeof(Char **) + 2)); - // real addr - Char *lockP = (Char *)MemHandleLock(argvH); - // 4byte aligned - Char **argvP = (Char **)ALIGN_4BYTE(lockP); - // save real addr - argvP[0] = lockP; - // initial position - argvP++; - - for (UInt8 count = 0; count < MAX_ARG; count++) - argvP[count] = NULL; - - return argvP; -} - -void ArgsAdd(Char **argvP, const Char *argP, const Char *parmP, UInt8 *countArgP) { - if (argP) { - MemHandle newArg; - UInt16 len2 = 0; - UInt16 len1 = StrLen(argP); - - if (len1 > 0) { - if (parmP) - len2 = StrLen(parmP); - - (*countArgP)++; - newArg = MemHandleNew(len1 + len2 + 1); // +1 = NULL CHAR - *argvP = (Char *)MemHandleLock(newArg); - StrCopy(*argvP, argP); - - if (parmP) - StrCat(*argvP, parmP); - } - } -} - -void ArgsFree(Char **argvP) { - if (!argvP) - return; - - MemHandle oldH; - - for (UInt8 count = 0; count < MAX_ARG; count++) - if (argvP[count]) { - oldH = MemPtrRecoverHandle(argvP[count]); - MemHandleUnlock(oldH); - MemHandleFree(oldH); - } - - argvP--; - oldH = MemPtrRecoverHandle(argvP[0]); - MemHandleUnlock(oldH); - MemHandleFree(oldH); -} - -void ArgsSetOwner(Char **argvP, UInt16 owner) { - if (!argvP) - return; - - MemHandle oldH; - - for (UInt8 count = 0; count < MAX_ARG; count++) - if (argvP[count]) { - oldH = MemPtrRecoverHandle(argvP[count]); - MemHandleSetOwner(oldH, owner); - } - - argvP--; - oldH = MemPtrRecoverHandle(argvP[0]); - MemHandleSetOwner(oldH, owner); -} - -void ArgsExportInit(Char **argvP, UInt32 countArg, Boolean arm) { - if (arm) { - for (UInt8 count = 0; count < MAX_ARG; count++) - if (argvP[count]) - argvP[count] = (Char *)ByteSwap32(argvP[count]); - } - - FtrSet(appFileCreator, ftrArgsData , (UInt32)argvP); - FtrSet(appFileCreator, ftrArgsCount, (UInt32)countArg); -} - -void ArgsExportRelease(Boolean arm) { - if (arm) { - Char **argvP; - Err e = FtrGet(appFileCreator, ftrArgsData, (UInt32 *)&argvP); - - if (argvP) - for (UInt8 count = 0; count < MAX_ARG; count++) - if (argvP[count]) - argvP[count] = (Char *)ByteSwap32(argvP[count]); - } - - FtrUnregister(appFileCreator, ftrArgsCount); - FtrUnregister(appFileCreator, ftrArgsData); -} diff --git a/backends/platform/PalmOS/Src/args.h b/backends/platform/PalmOS/Src/args.h deleted file mode 100644 index fa988fe35f..0000000000 --- a/backends/platform/PalmOS/Src/args.h +++ /dev/null @@ -1,44 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef ARGS_H -#define ARGS_H - -#define MAX_ARG 25 - -#define ftrArgsData 1300 -#define ftrArgsCount 1301 -#define ftrVars 1302 -#define ftrStack 1303 - -Char **ArgsInit(); -void ArgsAdd(Char **argvP, const Char *argP, const Char *parmP, UInt8 *countArgP); -void ArgsFree(Char **argvP); -void ArgsSetOwner(Char **argvP, UInt16 owner); - -void ArgsExportInit(Char **argvP, UInt32 countArg, Boolean arm); -void ArgsExportRelease(Boolean arm); - -#endif diff --git a/backends/platform/PalmOS/Src/base_event.cpp b/backends/platform/PalmOS/Src/base_event.cpp deleted file mode 100644 index ae93514e34..0000000000 --- a/backends/platform/PalmOS/Src/base_event.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_base.h" -#include "common/events.h" - -#ifdef STDLIB_TRACE_MEMORY -# include <stdlib.h> -#endif - -#if defined(COMPILE_OS5) && defined(PALMOS_ARM) -extern "C" void SysEventGet(EventType *eventP, Int32 timeout); -extern "C" void SysEventAddToQueue (const EventType *eventP); -#endif - -void OSystem_PalmBase::timer_handler() { - UInt32 msecs = getMillis(); - - if (_timer.active && (msecs >= _timer.nextExpiry)) { - _timer.duration = _timer.callback(_timer.duration); - _timer.nextExpiry = msecs + _timer.duration; - } -} - -void OSystem_PalmBase::battery_handler() { - // check battery level every 15secs - if ((TimGetTicks() - _batCheckLast) > _batCheckTicks) { - UInt16 voltage, warnThreshold, criticalThreshold; - Boolean pluggedIn; - voltage = SysBatteryInfoV20(false, &warnThreshold, &criticalThreshold, NULL, NULL, &pluggedIn); - - if (!pluggedIn) { - if (voltage <= warnThreshold) { - if (!_showBatLow) { - _showBatLow = true; - draw_osd(kDrawBatLow, _screenDest.w - 18, -16, true, 2); - displayMessageOnOSD("Battery low."); - } - } else { - if (_showBatLow) { - _showBatLow = false; - draw_osd(kDrawBatLow, _screenDest.w - 18, -16, false); - } - } - - if (voltage <= criticalThreshold) { - ::EventType event; - event.eType = keyDownEvent; - event.data.keyDown.chr = vchrPowerOff; - event.data.keyDown.modifiers = commandKeyMask; -#if defined(COMPILE_OS5) && defined(PALMOS_ARM) - SysEventAddToQueue(&event); -#else - EvtAddEventToQueue(&event); -#endif - } - } - - _batCheckLast = TimGetTicks(); - } -} - -bool OSystem_PalmBase::pollEvent(Common::Event &event) { - ::EventType ev; - Boolean handled; - UInt32 keyCurrentState; - Coord x, y; - - battery_handler(); - timer_handler(); - sound_handler(); - - for (;;) { - // check for hardkey repeat for mouse emulation - keyCurrentState = KeyCurrentState(); - - // if it was a key pressed, let the keyup event raise - if (_keyExtraPressed) { - if (gVars->arrowKeys) { - if (_keyExtraPressed & _keyExtra.bitLeft) { - if (!(keyCurrentState & _keyExtra.bitLeft)) { - _keyExtraPressed &= ~_keyExtra.bitLeft; - - event.type = Common::EVENT_KEYUP; - event.kbd.keycode = Common::KEYCODE_LEFT; - event.kbd.ascii = event.kbd.keycode; - event.kbd.flags = 0; - return true; - } - } - if (_keyExtraPressed & _keyExtra.bitRight) { - if (!(keyCurrentState & _keyExtra.bitRight)) { - _keyExtraPressed &= ~_keyExtra.bitRight; - - event.type = Common::EVENT_KEYUP; - event.kbd.keycode = Common::KEYCODE_RIGHT; - event.kbd.ascii = event.kbd.keycode; - event.kbd.flags = 0; - return true; - } - } - if (_keyExtraPressed & _keyExtra.bitUp) { - if (!(keyCurrentState & _keyExtra.bitUp)) { - _keyExtraPressed &= ~_keyExtra.bitUp; - - event.type = Common::EVENT_KEYUP; - event.kbd.keycode = Common::KEYCODE_UP; - event.kbd.ascii = event.kbd.keycode; - event.kbd.flags = 0; - return true; - } - } - if (_keyExtraPressed & _keyExtra.bitDown) { - if (!(keyCurrentState & _keyExtra.bitDown)) { - _keyExtraPressed &= ~_keyExtra.bitDown; - - event.type = Common::EVENT_KEYUP; - event.kbd.keycode = Common::KEYCODE_DOWN; - event.kbd.ascii = event.kbd.keycode; - event.kbd.flags = 0; - return true; - } - } - } - - if (_keyExtraPressed & _keyExtra.bitActionA) { - if (!(keyCurrentState & _keyExtra.bitActionA)) { - _keyExtraPressed &= ~_keyExtra.bitActionA; - - event.type = Common::EVENT_LBUTTONUP; - event.mouse.x = _mouseCurState.x; - event.mouse.y = _mouseCurState.y; - return true; - } - } - - if (_keyExtraPressed & _keyExtra.bitActionB) { - if (!(keyCurrentState & _keyExtra.bitActionB)) { - _keyExtraPressed &= ~_keyExtra.bitActionB; - - event.type = Common::EVENT_RBUTTONUP; - event.mouse.x = _mouseCurState.x; - event.mouse.y = _mouseCurState.y; - return true; - } - } - - // no more event till up is raised - return false; - } - - if (!(keyCurrentState & _keyExtraMask)) { - _lastKeyRepeat = 0; - - } else if (getMillis() >= (_keyExtraRepeat + _keyExtraDelay)) { - _keyExtraRepeat = getMillis(); - - if (gVars->arrowKeys) { - if (keyCurrentState & _keyExtra.bitLeft) { - _keyExtraPressed |= _keyExtra.bitLeft; - event.kbd.keycode = Common::KEYCODE_LEFT; - - } else if (keyCurrentState & _keyExtra.bitRight) { - _keyExtraPressed |= _keyExtra.bitRight; - event.kbd.keycode = Common::KEYCODE_RIGHT; - - } else if (keyCurrentState & _keyExtra.bitUp) { - _keyExtraPressed |= _keyExtra.bitUp; - event.kbd.keycode = Common::KEYCODE_UP; - - } else if (keyCurrentState & _keyExtra.bitDown) { - _keyExtraPressed |= _keyExtra.bitDown; - event.kbd.keycode = Common::KEYCODE_DOWN; - } - - event.type = Common::EVENT_KEYDOWN; - event.kbd.ascii = event.kbd.keycode; - event.kbd.flags = 0; - return true; - - } else { - Int8 sx = 0; - Int8 sy = 0; - - if (keyCurrentState & _keyExtra.bitUp) - sy = -1; - else if (keyCurrentState & _keyExtra.bitDown) - sy = +1; - - if (keyCurrentState & _keyExtra.bitLeft) - sx = -1; - else if (keyCurrentState & _keyExtra.bitRight) - sx = +1; - - if (sx || sy) { - simulate_mouse(event, sx, sy, &x, &y); - event.type = Common::EVENT_MOUSEMOVE; - event.mouse.x = x; - event.mouse.y = y; - warpMouse(x, y); - - return true; - } - } - } - -#if defined(COMPILE_OS5) && defined(PALMOS_ARM) - SysEventGet(&ev, evtNoWait); -#else - EvtGetEvent(&ev, evtNoWait); -#endif - - if (ev.eType == keyUpEvent) { - Common::KeyCode k = Common::KEYCODE_INVALID; - switch (ev.data.keyUp.chr) { - - // arrow keys - case chrUpArrow: - k = Common::KEYCODE_UP; break; - case chrDownArrow: - k = Common::KEYCODE_DOWN; break; - case chrRightArrow: - k = Common::KEYCODE_RIGHT; break; - case chrLeftArrow: - k = Common::KEYCODE_LEFT; break; - } - - if (k) { - event.type = Common::EVENT_KEYUP; - event.kbd.keycode = k; - event.kbd.ascii = k; - event.kbd.flags = 0; - return true; - } - - } else if (ev.eType == keyDownEvent) { - Common::KeyCode k = Common::KEYCODE_INVALID; - switch (ev.data.keyDown.chr) { - // ESC key - case vchrLaunch: - event.type = Common::EVENT_KEYDOWN; - event.kbd.keycode = Common::KEYCODE_ESCAPE; - event.kbd.ascii = Common::ASCII_ESCAPE; - event.kbd.flags = 0; - return true; - - // F5 = menu - case vchrMenu: - event.type = Common::EVENT_KEYDOWN; - event.kbd.keycode = Common::KEYCODE_F5; - event.kbd.ascii = Common::ASCII_F5; - event.kbd.flags = 0; - return true; - - // if hotsync pressed, etc... - case vchrHardCradle: - case vchrHardCradle2: - case vchrLowBattery: - case vchrFind: -// case vchrBrightness: // volume control on Zodiac, let other backends disable it - case vchrContrast: - // do nothing - return true; - - // arrow keys - case chrUpArrow: - k = Common::KEYCODE_UP; break; - case chrDownArrow: - k = Common::KEYCODE_DOWN; break; - case chrRightArrow: - k = Common::KEYCODE_RIGHT; break; - case chrLeftArrow: - k = Common::KEYCODE_LEFT; break; - - // return - case chrLineFeed: - case chrCarriageReturn: - k = Common::KEYCODE_RETURN; break; - - } - - if (k) { - event.type = Common::EVENT_KEYDOWN; - event.kbd.keycode = k; - event.kbd.ascii = k; - event.kbd.flags = 0; - return true; - } - } - - if (check_event(event, &ev)) - return true; - - // prevent crash when alarm is raised - handled = ((ev.eType == keyDownEvent) && - (ev.data.keyDown.modifiers & commandKeyMask) && - ((ev.data.keyDown.chr == vchrAttnStateChanged) || - (ev.data.keyDown.chr == vchrAttnUnsnooze))); - - // graffiti strokes, auto-off, etc... - if (!handled) - if (SysHandleEvent(&ev)) - continue; - - switch (ev.eType) { - case penMoveEvent: - get_coordinates(&ev, x, y); - - if (y > _screenHeight || y < 0 || x > _screenWidth || x < 0) - return false; - - if (abs(y - event.mouse.y) <= 2 || abs(x - event.mouse.x) <= 2) - return false; - - event.type = Common::EVENT_MOUSEMOVE; - event.mouse.x = x; - event.mouse.y = y; - warpMouse(x, y); - return true; - - case penDownEvent: - get_coordinates(&ev, x, y); - - // indy fight mode - if (_useNumPad && !_overlayVisible) { - char num = '1'; - num += 9 - - (3 - (3 * x / _screenWidth )) - - (3 * (3 * y / _screenHeight)); - - event.type = Common::EVENT_KEYDOWN; - event.kbd.keycode = (Common::KeyCode)num; - event.kbd.ascii = num; - event.kbd.flags = 0; - - _wasKey = true; - return true; - } - - if (y > _screenHeight || y < 0 || x > _screenWidth || x < 0) - return false; - - event.type = ((gVars->stylusClick || _overlayVisible) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_MOUSEMOVE); - event.mouse.x = x; - event.mouse.y = y; - warpMouse(x, y); - return true; - - case penUpEvent: - get_coordinates(&ev, x, y); - - event.type = ((gVars->stylusClick || _overlayVisible) ? Common::EVENT_LBUTTONUP : Common::EVENT_MOUSEMOVE); - if (y > _screenHeight || y < 0 || x > _screenWidth || x < 0) - return false; - - event.mouse.x = x; - event.mouse.y = y; - warpMouse(x, y); - return true; - - case keyDownEvent: - if (ev.data.keyDown.chr == vchrCommand && - (ev.data.keyDown.modifiers & commandKeyMask)) { - - _lastKeyModifier++; - _lastKeyModifier %= kModifierCount; - - if (_lastKeyModifier) - draw_osd((kDrawKeyState + _lastKeyModifier - 1), 2, _screenDest.h + 2, true); - else - draw_osd(kDrawKeyState, 2, _screenDest.h + 2, false); - - return false; - } - - char mask = 0; - UInt16 key = ev.data.keyDown.chr; - - if (_lastKeyModifier == kModifierNone) { - // for keyboard mode - if (ev.data.keyDown.modifiers & shiftKeyMask) mask |= Common::KBD_SHIFT; - if (ev.data.keyDown.modifiers & controlKeyMask) mask |= Common::KBD_CTRL; - if (ev.data.keyDown.modifiers & optionKeyMask) mask |= Common::KBD_ALT; - if (ev.data.keyDown.modifiers & commandKeyMask) mask |= Common::KBD_CTRL|Common::KBD_ALT; - } else { - // for grafiti mode - if (_lastKeyModifier == kModifierCommand) mask = Common::KBD_CTRL|Common::KBD_ALT; - if (_lastKeyModifier == kModifierAlt) mask = Common::KBD_ALT; - if (_lastKeyModifier == kModifierCtrl) mask = Common::KBD_CTRL; - } - - if (_lastKeyModifier) - draw_osd(kDrawKeyState, 2, _screenDest.h + 2, false); - _lastKeyModifier = kModifierNone; - - // F1 -> F10 key - if (key >= '0' && key <= '9' && mask == (Common::KBD_CTRL|Common::KBD_ALT)) { - key = (key == '0') ? 324 : (315 + key - '1'); - mask = 0; - -#ifdef STDLIB_TRACE_MEMORY - // print memory - } else if (key == 'm' && mask == (Common::KBD_CTRL|Common::KBD_ALT)) { - printf("Used memory: %d\n", __stdlib_trace_memory); -#endif - // exit - } else if ((key == 'z' && mask == Common::KBD_CTRL) || (mask == Common::KBD_ALT && key == 'x')) { - event.type = Common::EVENT_QUIT; - return true; - - // num pad (indy fight mode) - } else if (key == 'n' && mask == (Common::KBD_CTRL|Common::KBD_ALT) && !_overlayVisible) { - _useNumPad = !_useNumPad; - draw_osd(kDrawFight, _screenDest.w - 34, _screenDest.h + 2, _useNumPad, 1); - displayMessageOnOSD(_useNumPad ? "Fight mode on." : "Fight mode off."); - return false; - } - - // other keys - _wasKey = true; - event.type = Common::EVENT_KEYDOWN; - event.kbd.keycode = (Common::KeyCode)key; - event.kbd.ascii = key; - event.kbd.flags = mask; - return true; - - default: - if (_wasKey && ev.eType != keyHoldEvent) { - event.type = Common::EVENT_KEYUP; - _wasKey = false; - return true; - } - return false; - }; - } -} diff --git a/backends/platform/PalmOS/Src/base_gfx.cpp b/backends/platform/PalmOS/Src/base_gfx.cpp deleted file mode 100644 index 46238efdc2..0000000000 --- a/backends/platform/PalmOS/Src/base_gfx.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_base.h" - -/* - * Graphics modes - * - */ - -static const OSystem::GraphicsMode s_supportedGraphicsModes[] = { - {"1x", "Normal", GFX_NORMAL}, - {"wide", "Wide", GFX_WIDE}, - {0, 0, 0} -}; - -int OSystem_PalmBase::getDefaultGraphicsMode() const { - return GFX_NORMAL; -} - -const OSystem::GraphicsMode *OSystem_PalmBase::getSupportedGraphicsModes() const { - return int_getSupportedGraphicsModes(); -} - -const OSystem::GraphicsMode *OSystem_PalmBase::int_getSupportedGraphicsModes() const { - return s_supportedGraphicsModes; -} - -int OSystem_PalmBase::getGraphicsMode() const { - return _mode; -} - -bool OSystem_PalmBase::setGraphicsMode(int mode) { - switch (mode) { - case GFX_NORMAL: - case GFX_WIDE: - _setMode = mode; - break; - - default: - warning("unknown gfx mode %d", mode); - _setMode = GFX_NORMAL; - return false; - } - - return true; -} - -/* - * Init - * - */ - -void OSystem_PalmBase::initSize(uint w, uint h, const Graphics::PixelFormat *format) { - _screenWidth = w; - _screenHeight = h; - - _screenDest.w = _screenWidth; - _screenDest.h = _screenHeight; - - unload_gfx_mode(); - _mode = _setMode; - load_gfx_mode(); - - warpMouse(200, 150); - int_initSize(w, h); -} - -/* - * Palette - * - */ -void OSystem_PalmBase::setPalette(const byte *colors, uint start, uint num) { - RGBColorType *base = _currentPalette + start; - - for (uint i = 0; i < num; i++) { - base[i].r = colors[0]; - base[i].g = colors[1]; - base[i].b = colors[2]; - - extras_palette(i + start, colors[0], colors[1], colors[2]); - colors += 4; - } - - if (start < _paletteDirtyStart) - _paletteDirtyStart = start; - - if (start + num > _paletteDirtyEnd) - _paletteDirtyEnd = start + num; -} - -void OSystem_PalmBase::grabPalette(byte *colors, uint start, uint num) { - const RGBColorType *base = _currentPalette + start; - - for (uint i = 0; i < num; ++i) { - colors[i * 4] = base[i].r; - colors[i * 4 + 1] = base[i].g; - colors[i * 4 + 2] = base[i].b; - colors[i * 4 + 3] = 0xFF; - } -} - -/* - * Screen - * - */ - -void OSystem_PalmBase::setShakePos(int shakeOffset) { - _new_shake_pos = shakeOffset; - int_setShakePos(shakeOffset); -} - -void OSystem_PalmBase::updateScreen() { - // Check whether the palette was changed in the meantime and update the - // screen surface accordingly. - if (_paletteDirtyEnd != 0 && _setPalette) { - WinSetDrawWindow(WinGetDisplayWindow()); - WinPalette(winPaletteSet, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart, _currentPalette + _paletteDirtyStart); - _paletteDirtyEnd = 0; - //_redawOSD = true; - } - if (_redawOSD) { - _redawOSD = false; - draw_osd(kDrawBatLow, _screenDest.w - 18, -16, _showBatLow, 2); - draw_osd(kDrawFight, _screenDest.w - 34, _screenDest.h + 2, (_useNumPad && !_overlayVisible), 1); - } - int_updateScreen(); - -} - -void OSystem_PalmBase::draw_osd(UInt16 id, Int32 x, Int32 y, Boolean show, UInt8 color) { -//return; - - MemHandle hTemp = DmGetResource('abmp', id + 100); - - if (hTemp) { - /*static const UInt32 pal[3] = { - (TwGfxComponentsToPackedRGB(0,255,0)), - (TwGfxComponentsToPackedRGB(255,255,0)), - (TwGfxComponentsToPackedRGB(255,0,0)) - };*/ - - BitmapType *bmTemp; - bmTemp = (BitmapType *)MemHandleLock(hTemp); - - Coord w, h; - BmpGetDimensions(bmTemp, &w, &h, 0); - - PointType dst = { _screenOffset.x + x, _screenOffset.y + y }; - RectangleType r = { dst.x, dst.y, w, h }; - - RectangleType c; - - UInt16 old = WinSetCoordinateSystem(kCoordinatesNative); - WinGetClip(&c); - WinResetClip(); - if (show) { - WinSetDrawWindow(_screenH); - WinSetBackColor(0); - WinSetForeColor(120); // pal[color] - WinFillRectangle(&r, 0); - WinSetDrawMode(winOverlay); - WinDrawBitmap(bmTemp, 0, 0); - WinSetDrawMode(winPaint); - - } else { - WinSetBackColor(0); - WinFillRectangle(&r, 0); - } - WinSetClip(&c); - WinSetCoordinateSystem(old); - - MemPtrUnlock(bmTemp); - DmReleaseResource(hTemp); - } -} diff --git a/backends/platform/PalmOS/Src/base_mouse.cpp b/backends/platform/PalmOS/Src/base_mouse.cpp deleted file mode 100644 index bf11a4b106..0000000000 --- a/backends/platform/PalmOS/Src/base_mouse.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_base.h" - -void OSystem_PalmBase::warpMouse(int x, int y) { - if (x != _mouseCurState.x || y != _mouseCurState.y) { - x = x >= _screenWidth ? _screenWidth - 1 : x; - y = y >= _screenHeight ? _screenHeight - 1 : y; - - _mouseCurState.x = x; - _mouseCurState.y = y; - } -} - -bool OSystem_PalmBase::showMouse(bool visible) { - bool last = _mouseVisible; - _mouseVisible = visible; - - return last; -} - -void OSystem_PalmBase::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { - if (w == 0 || h == 0) - return; - - _mouseHotspotX = hotspotX; - _mouseHotspotY = hotspotY; - - _mouseKeyColor = keycolor; - - if (_mouseCurState.w != w || _mouseCurState.h != h) { - _mouseCurState.w = w; - _mouseCurState.h = h; - - if (_mouseDataP) - free(_mouseDataP); - - if (_mouseBackupP) - free(_mouseBackupP); - - _mouseDataP = (byte *)malloc(w * h); - _mouseBackupP = (byte *)malloc(w * h * 2); // if 16bit = *2 - } - - if (!_mouseBackupP) { - free(_mouseDataP); - _mouseDataP = NULL; - } - - if (_mouseDataP) - memcpy(_mouseDataP, buf, w * h); -} - -void OSystem_PalmBase::simulate_mouse(Common::Event &event, Int8 iHoriz, Int8 iVert, Coord *xr, Coord *yr) { - Int16 x = _mouseCurState.x; - Int16 y = _mouseCurState.y; - Int16 slow, fact; - - _lastKeyRepeat++; - fact = _screenWidth / 320; - fact = (fact) ? fact : 1; - - if (_lastKeyRepeat > 32 * fact) - _lastKeyRepeat = 32 * fact; - - slow = (iHoriz && iVert) ? 2 : 1; - - x += iHoriz * (_lastKeyRepeat >> 2) / slow * fact; - y += iVert * (_lastKeyRepeat >> 2) / slow * fact; - - x = (x < 0 ) ? 0 : x; - x = (x >= _screenWidth ) ? _screenWidth - 1 : x; - y = (y < 0 ) ? 0 : y; - y = (y >= _screenHeight ) ? _screenHeight - 1 : y; - - *xr = x; - *yr = y; -} diff --git a/backends/platform/PalmOS/Src/be_68k.cpp b/backends/platform/PalmOS/Src/be_68k.cpp deleted file mode 100644 index 77b1e22615..0000000000 --- a/backends/platform/PalmOS/Src/be_68k.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - - -/* More to come */ diff --git a/backends/platform/PalmOS/Src/be_68k.h b/backends/platform/PalmOS/Src/be_68k.h deleted file mode 100644 index 77b1e22615..0000000000 --- a/backends/platform/PalmOS/Src/be_68k.h +++ /dev/null @@ -1,27 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - - -/* More to come */ diff --git a/backends/platform/PalmOS/Src/be_base.cpp b/backends/platform/PalmOS/Src/be_base.cpp deleted file mode 100644 index b3caee105d..0000000000 --- a/backends/platform/PalmOS/Src/be_base.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_base.h" -#include "common/config-file.h" -#include "common/config-manager.h" -#include "backends/saves/default/default-saves.h" -#include "backends/timer/default/default-timer.h" -#include "backends/fs/palmos/palmos-fs-factory.h" -#include "sound/mixer_intern.h" - -#define DEFAULT_SAVE_PATH "/PALM/Programs/ScummVM/Saved/" - - -OSystem_PalmBase::OSystem_PalmBase() { - _overlayVisible = false; - - _current_shake_pos = 0; - _new_shake_pos = 0; - - _paletteDirtyStart = 0; - _paletteDirtyEnd = 0; - - _gfxLoaded = false; - _modeChanged = false; - _setMode = GFX_NORMAL; - _mode = _setMode; - _redawOSD = false; - _setPalette = true; - - _offScreenH = NULL; - _screenH = NULL; - _offScreenP = NULL; - _screenP = NULL; - _screenPitch = gVars->screenPitch; - - _wasKey = false; - _lastKeyModifier = kModifierNone; - _lastKeyRepeat = 100; - _useNumPad = false; - _showBatLow = false; - _batCheckTicks = SysTicksPerSecond() * 15; - _batCheckLast = TimGetTicks(); - - _saveMgr = 0; - _timerMgr = 0; - _mixerMgr = 0; - - _mouseDataP = NULL; - _mouseBackupP = NULL; - _mouseVisible = false; - _mouseDrawn = false; - MemSet(&_keyExtra, sizeof(_keyExtra), 0); - MemSet(&_mouseCurState, sizeof(_mouseCurState), 0); - MemSet(&_mouseOldState, sizeof(_mouseOldState), 0); - MemSet(&_timer, sizeof(TimerType), 0); - MemSet(&_sound, sizeof(SoundType), 0); - - _keyExtraRepeat = 0; - _keyExtraPressed = 0; - _keyExtraDelay = (gVars->arrowKeys) ? computeMsecs(125) : computeMsecs(25); -} - -static int timer_handler(int t) { - DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager(); - tm->handler(); - return t; -} - -void OSystem_PalmBase::initBackend() { - if (gVars->autoSave != -1) - ConfMan.setInt("autosave_period", gVars->autoSave); - - _keyExtra.bitUp = keyBitPageUp; - _keyExtra.bitDown = keyBitPageDown; - _keyExtra.bitLeft = keyBitHard2; - _keyExtra.bitRight = keyBitHard3; - - int_initBackend(); - _keyExtraMask = (_keyExtra.bitUp | _keyExtra.bitDown | _keyExtra.bitLeft | _keyExtra.bitRight | _keyExtra.bitActionA | _keyExtra.bitActionB); - - // Create the savefile manager, if none exists yet (we check for this to - // allow subclasses to provide their own). - if (_saveMgr == 0) { - _saveMgr = new DefaultSaveFileManager(DEFAULT_SAVE_PATH); - } - - // Create and hook up the mixer, if none exists yet (we check for this to - // allow subclasses to provide their own). - if (_mixerMgr == 0) { - setupMixer(); - } - - // Create and hook up the timer manager, if none exists yet (we check for - // this to allow subclasses to provide their own). - if (_timerMgr == 0) { - _timerMgr = new DefaultTimerManager(); - setTimerCallback(::timer_handler, 10); - } - - OSystem::initBackend(); -} - -void OSystem_PalmBase::getTimeAndDate(TimeDate &td) const { - time_t curTime = time(0); - struct tm t = *localtime(&curTime); - td.tm_sec = t.tm_sec; - td.tm_min = t.tm_min; - td.tm_hour = t.tm_hour; - td.tm_mday = t.tm_mday; - td.tm_mon = t.tm_mon; - td.tm_year = t.tm_year; -} - -uint32 OSystem_PalmBase::getMillis() { - return TimGetTicks() * 1000 / SysTicksPerSecond(); -} - -void OSystem_PalmBase::delayMillis(uint msecs) { - Int32 delay = computeMsecs(msecs); - - if (delay > 0) - SysTaskDelay(delay); -} - -void OSystem_PalmBase::setTimerCallback(TimerProc callback, int timer) { - if (callback != NULL) { - _timer.duration = timer; - _timer.nextExpiry = getMillis() + timer; - _timer.callback = callback; - _timer.active = true; - } else { - _timer.active = false; - } -} - -void OSystem_PalmBase::quit() { - int_quit(); - clearSoundCallback(); - unload_gfx_mode(); - - if (_mouseDataP) { - MemPtrFree(_mouseBackupP); - MemPtrFree(_mouseDataP); - } - - delete _saveMgr; - delete _timerMgr; - delete _mixerMgr; - - exit(0); -} - -Common::SaveFileManager *OSystem_PalmBase::getSavefileManager() { - return _saveMgr; -} - -Audio::Mixer *OSystem_PalmBase::getMixer() { - return _mixerMgr; -} - -Common::TimerManager *OSystem_PalmBase::getTimerManager() { - return _timerMgr; -} - -FilesystemFactory *OSystem_PalmBase::getFilesystemFactory() { - return &PalmOSFilesystemFactory::instance(); -} - - -#define PALMOS_CONFIG_FILE "/PALM/Programs/ScummVM/scummvm.ini" - -Common::SeekableReadStream *OSystem_PalmBase::createConfigReadStream() { - Common::FSNode file(PALMOS_CONFIG_FILE); - return file.createReadStream(); -} - -Common::WriteStream *OSystem_PalmBase::createConfigWriteStream() { - Common::FSNode file(PALMOS_CONFIG_FILE); - return file.createWriteStream(); -} diff --git a/backends/platform/PalmOS/Src/be_base.h b/backends/platform/PalmOS/Src/be_base.h deleted file mode 100644 index 1885114ace..0000000000 --- a/backends/platform/PalmOS/Src/be_base.h +++ /dev/null @@ -1,265 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef BE_BASE_H -#define BE_BASE_H - -#include <time.h> - -#include "PalmVersion.h" -#include "globals.h" - -#include "backends/base-backend.h" -#include "common/scummsys.h" -#include "common/events.h" -#include "graphics/surface.h" -#include "graphics/colormasks.h" - -namespace Audio { - class MixerImpl; -} - -namespace Common { - class SaveFileManager; - class TimerManager; -} - -enum { - GFX_NORMAL = 0, - GFX_WIDE, -}; - -// OSD key state -enum { - kModifierNone = 0, - kModifierCommand, - kModifierAlt, - kModifierCtrl, - kModifierCount -}; - -// Mouse button event -enum { - vchrMouseLeft = vchrHardKeyMax - 2, - vchrMouseRight = vchrHardKeyMax - 1 -}; - -// OSD resource id -#define kDrawKeyState 3000 -#define kDrawNumPad 3010 -#define kDrawBatLow 3020 -#define kDrawFight 3030 - -#define computeMsecs(x) ((SysTicksPerSecond() * x) / 1000) - - -//typedef void (*SoundProc)(void *param, byte *buf, int len); -typedef void (*SoundProc)(byte *buf, uint len); -typedef int (*TimerProc)(int interval); - -typedef struct { - UInt32 duration, nextExpiry; - Boolean active; - TimerProc callback; -} TimerType, *TimerPtr; - -typedef struct { - Boolean active; - void *proc; - void *param; -} SoundType, *SoundPtr; - -class OSystem_PalmBase : public BaseBackend { -private: - virtual void int_initBackend() { } - - virtual const GraphicsMode *int_getSupportedGraphicsModes() const; - virtual void int_updateScreen() = 0; - virtual void int_initSize(uint w, uint h) = 0; - virtual void int_setShakePos(int shakeOffset) { } - - virtual void extras_palette(uint8 index, uint8 r, uint8 g, uint8 b) { } - virtual void int_quit() { } - - virtual void unload_gfx_mode() = 0; - virtual void load_gfx_mode() = 0; - - virtual void draw_mouse() = 0; - virtual void undraw_mouse() = 0; - - virtual bool check_event(Common::Event &event, EventPtr ev) = 0; - - virtual void timer_handler(); - void battery_handler(); - virtual void get_coordinates(EventPtr ev, Coord &x, Coord &y) = 0; - void simulate_mouse(Common::Event &event, Int8 iHoriz, Int8 iVert, Coord *xr, Coord *yr); - - virtual void sound_handler() = 0; - virtual bool setupMixer() = 0; - virtual void clearSoundCallback() = 0; - -protected: - OSystem_PalmBase(); - - virtual void draw_osd(UInt16 id, Int32 x, Int32 y, Boolean show, UInt8 color = 0); - virtual void clear_screen() = 0; - - struct MousePos { - int16 x,y,w,h; - }; - - TimerType _timer; - SoundType _sound; - - Common::SaveFileManager *_saveMgr; - Audio::MixerImpl *_mixerMgr; - Common::TimerManager *_timerMgr; - - RGBColorType _currentPalette[256]; - uint _paletteDirtyStart, _paletteDirtyEnd; - - int _mode, _setMode; - int16 _screenWidth, _screenHeight; - Boolean _modeChanged, _gfxLoaded; - UInt32 _screenPitch; - - PointType _screenOffset; - struct { - Coord w, h; - } _screenDest; - byte *_screenP, *_offScreenP; - WinHandle _screenH, _offScreenH; - - int _current_shake_pos; - int _new_shake_pos; - - Boolean _overlayVisible; - Boolean _redawOSD, _setPalette; - - UInt32 _keyExtraMask, _keyExtraPressed, _keyExtraRepeat, _keyExtraDelay; - struct { - UInt32 bitUp; - UInt32 bitDown; - UInt32 bitLeft; - UInt32 bitRight; - UInt32 bitActionA; // left mouse button - UInt32 bitActionB; // right mouse button - } _keyExtra; - - bool _mouseVisible; - bool _mouseDrawn; - MousePos _mouseCurState; - MousePos _mouseOldState; - int16 _mouseHotspotX; - int16 _mouseHotspotY; - byte _mouseKeyColor; - byte *_mouseDataP, *_mouseBackupP; - - - bool _wasKey; - UInt8 _lastKeyModifier; - UInt32 _lastKeyRepeat; - Boolean _useNumPad, _showBatLow; - UInt32 _batCheckTicks, _batCheckLast; - -public: - void initBackend(); - -/* - virtual void setFeatureState(Feature f, bool enable) {}; - - - bool hasFeature(Feature f); - bool getFeatureState(Feature f); - - virtual void beginGFXTransaction(); - virtual void endGFXTransaction(); - - virtual int16 getOverlayHeight(); - virtual int16 getOverlayWidth(); - - virtual void setCursorPalette(const byte *colors, uint start, uint num); - virtual void disableCursorPalette(bool disable); - - virtual void displayMessageOnOSD(const char *msg); -*/ - const GraphicsMode *getSupportedGraphicsModes() const; - int getGraphicsMode() const; - virtual int getDefaultGraphicsMode() const; - virtual bool setGraphicsMode(int mode); - - void initSize(uint w, uint h, const Graphics::PixelFormat *format); - int16 getWidth() { return _screenWidth; } - int16 getHeight() { return _screenHeight; } - - void setShakePos(int shakeOffset); - virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) = 0; - virtual void updateScreen(); - - bool showMouse(bool visible); - void warpMouse(int x, int y); - void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); - - virtual void showOverlay() = 0; - virtual void hideOverlay() = 0; - virtual void clearOverlay() = 0; - virtual void grabOverlay(OverlayColor *buf, int pitch) = 0; - virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) = 0; - - int16 getOverlayWidth() { return getWidth(); } - int16 getOverlayHeight() { return getHeight(); } - - void setPalette(const byte *colors, uint start, uint num); - void grabPalette(byte *colors, uint start, uint num); - virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<565>(); } - - bool pollEvent(Common::Event &event); - - - void getTimeAndDate(TimeDate& td) const; - virtual uint32 getMillis(); - virtual void delayMillis(uint msecs); - - virtual void setTimerCallback(TimerProc callback, int interval); - - virtual MutexRef createMutex() { return NULL; } - virtual void lockMutex(MutexRef mutex) {} - virtual void unlockMutex(MutexRef mutex) {} - virtual void deleteMutex(MutexRef mutex) {} - - virtual Audio::Mixer *getMixer(); - - void quit(); - virtual void setWindowCaption(const char *caption) = 0; - - Common::SaveFileManager *getSavefileManager(); - Common::TimerManager *getTimerManager(); - FilesystemFactory *getFilesystemFactory(); - - virtual Common::SeekableReadStream *createConfigReadStream(); - virtual Common::WriteStream *createConfigWriteStream(); -}; - -#endif diff --git a/backends/platform/PalmOS/Src/be_os5.cpp b/backends/platform/PalmOS/Src/be_os5.cpp deleted file mode 100644 index c9ef9ecf7c..0000000000 --- a/backends/platform/PalmOS/Src/be_os5.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_os5.h" -#include <HsKeyCommon.h> - -OSystem_PalmOS5::OSystem_PalmOS5() : OSystem_PalmBase() { - _sound.active = false; - _setPalette = false; - - _workScreenH = NULL; - _overlayH = NULL; - _isSwitchable = false; - _wasRotated = false; - _cursorPaletteDisabled = true; - - MemSet(&_soundEx, sizeof(SoundExType), 0); - _soundEx.sound = &_sound; -} - -void OSystem_PalmOS5::calc_scale() { - for (int y = 0; y < _screenDest.h; y++) { - int ys = y * _screenHeight / _screenDest.h; - _scaleTableY[y] = ys * _screenWidth; - } - - for (int x = 0; x < _screenDest.w; x++) { - int xs = x * _screenWidth / _screenDest.w; - _scaleTableX[x] = xs; - } -} - -void OSystem_PalmOS5::calc_rect(Boolean fullscreen) { - Int32 w, h; - - if (fullscreen) { - w = (_ratio.adjustAspect == kRatioWidth) ? _ratio.width : gVars->screenFullWidth; - h = (_ratio.adjustAspect == kRatioHeight) ? _ratio.height : gVars->screenFullHeight; - - _screenOffset.x = (_ratio.adjustAspect == kRatioWidth) ? (gVars->screenFullWidth - _ratio.width) / 2 : 0; - _screenOffset.y = (_ratio.adjustAspect == kRatioHeight) ? (gVars->screenFullHeight - _ratio.height) / 2 : 0; - - } else { - w = gVars->screenWidth; - h = gVars->screenHeight * _screenHeight / _screenWidth; - - _screenOffset.x = 0; - _screenOffset.y = (gVars->screenHeight - h) / 2; - } - - _screenDest.w = w; - _screenDest.h = h; -} - -void OSystem_PalmOS5::int_initBackend() { - _keyExtra.bitUp = keyBitRockerUp|keyBitPageUp; - _keyExtra.bitDown = keyBitRockerDown|keyBitPageDown; - _keyExtra.bitLeft = keyBitRockerLeft; - _keyExtra.bitRight = keyBitRockerRight; - _keyExtra.bitActionA = keyBitHard3; - _keyExtra.bitActionB = keyBitHard4; -} - -bool OSystem_PalmOS5::hasFeature(Feature f) { - switch (f) { - case kFeatureCursorHasPalette: - return true; - } - - return false; -} - -void OSystem_PalmOS5::setFeatureState(Feature f, bool enable) { - switch (f) { -/* case kFeatureFullscreenMode: - if (_gfxLoaded) - if (OPTIONS_TST(kOptModeWide) && _initMode != GFX_WIDE) { - _fullscreen = enable; - hotswap_gfx_mode(_mode); - } - break; -*/ - case kFeatureAspectRatioCorrection: - if (_mode == GFX_WIDE) { - _ratio.adjustAspect = (_ratio.adjustAspect + 1) % 3; - //calc_rect(true); - hotswap_gfx_mode(_mode); -// TwGfxSetClip(_palmScreenP, &_dstRect); - clear_screen(); - } - break; - } -} - -void OSystem_PalmOS5::setWindowCaption(const char *caption) { -/* -FIXME/TODO: Convert caption from ISO Latin 1 to "right" encoding ? -If the output encoding is unclear or conversion impossible, -then one could just skip over any chars > 0x7F and display the rest -*/ - Err e; - Char buf[64]; - Coord w, y, h = FntLineHeight() + 2; - const Char *loading = "Loading, please wait\0"; - - // allocate bitmap - BitmapTypeV3 *bmp2P; - BitmapType *bmp1P = BmpCreate(320, (h * 3), 8, NULL, &e); - WinHandle tmpH = WinCreateBitmapWindow(bmp1P, &e); - - WinSetDrawWindow(tmpH); - WinSetBackColor(0); - WinSetTextColor(255); - WinEraseWindow(); - - // loading message - FntSetFont(boldFont); - w = FntCharsWidth(loading, StrLen(loading)); - w = (320 - w) / 2; - WinDrawChars(loading, StrLen(loading), w, 0 + h); - - // caption - FntSetFont(stdFont); - w = FntCharsWidth(caption, StrLen(caption)); - w = (320 - w) / 2; - WinDrawChars(caption, StrLen(caption), w, 0); - - // memory size - StrPrintF(buf, "memory : %ld KB", gVars->startupMemory); - w = FntCharsWidth(buf, StrLen(buf)); - w = (320 - w) / 2; - WinDrawChars(buf, StrLen(buf), w, h * 2); - - // set the bitmap as v3 - bmp2P = BmpCreateBitmapV3(bmp1P, kDensityDouble, BmpGetBits(bmp1P), NULL); - y = (80 - (h / 4) - 5); - - // draw it - WinSetDrawWindow(WinGetDisplayWindow()); - WinEraseWindow(); - WinDrawBitmap((BitmapPtr)bmp2P, 0, y); - - // free - WinDeleteWindow(tmpH, 0); - BmpDelete((BitmapPtr)bmp2P); - BmpDelete(bmp1P); -} diff --git a/backends/platform/PalmOS/Src/be_os5.h b/backends/platform/PalmOS/Src/be_os5.h deleted file mode 100644 index 2040c7faea..0000000000 --- a/backends/platform/PalmOS/Src/be_os5.h +++ /dev/null @@ -1,189 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef BE_OS5_H -#define BE_OS5_H - -#include "be_base.h" - -#if !defined(SYSTEM_CALLBACK) || defined(PALMOS_68K) -# define SYSTEM_CALLBACK -# ifdef PALMOS_ARM -# define CALLBACK_PROLOGUE \ - __asm { \ - stmfd r13!,{r9,r10}; \ - ldr r9,[r0]; \ - ldr r10,[r0,#4]; \ - } -# define CALLBACK_EPILOGUE __asm { ldmfd r13!,{r9,r10} } -# define CALLBACK_INIT(regs) \ - __asm { \ - ldr r0, = regs; \ - add r0,r0,r10; \ - str r9,[r0]; \ - str r10,[r0,#4]; \ - } -# else -# define CALLBACK_PROLOGUE \ - asm ( \ - movem.l a4-a5, -(sp); \ - move.l UserDataP, a0; \ - move.l 0(a0), a4; \ - move.l 4(a0), a5; \ - ); -# define CALLBACK_EPILOGUE asm ( movem.l (sp)+, a4-a5 ); -# define CALLBACK_INIT(regs) \ - { \ - void *ptr = ®s; \ - asm ( \ - move.l ptr, a0; \ - move.l a4, 0(a0); \ - move.l a5, 4(a0); \ - ); \ - } -# endif -#else -# define CALLBACK_PROLOGUE -# define CALLBACK_EPILOGUE -# define CALLBACK_INIT(regs) -#endif - -// TODO : change / remove this -#define gfxMakeDisplayRGB_BigEndian(_r,_g,_b) \ - ( (((_g) & 0xFC) << 11) | (((_b) & 0xF8) << 5) | ((_r) & 0xF8) | (((_g) & 0xFF) >> 5) ) - -#define gfxMakeDisplayRGB_LittleEndian(_r,_g,_b) \ - ( (((_r) & 0xF8) << 8) | (((_g) & 0xFC) << 3) | (((_b) & 0xF8) >> 3) ) - -#if CPU_TYPE == CPU_68K -#define gfxMakeDisplayRGB(_r,_g,_b) gfxMakeDisplayRGB_BigEndian(_r,_g,_b) -#else -#define gfxMakeDisplayRGB(_r,_g,_b) gfxMakeDisplayRGB_LittleEndian(_r,_g,_b) -#endif - -typedef struct { - // for real thread version only - UInt32 __reg1; - UInt32 __reg2; - - // no real thread version - Boolean set; - UInt32 size; - void *dataP; - - // default sound stuff - SndStreamRef handle; - SoundPtr sound; -} SoundExType, *SoundExPtr; -extern SoundExType _soundEx; - -class OSystem_PalmOS5 : public OSystem_PalmBase { -protected: - uint16 _nativePal[256], _mousePal[256]; - -private: - uint16 _scaleTableX[512]; - uint32 _scaleTableY[512]; - - typedef void (OSystem_PalmOS5::*RendererProc)(RectangleType &r, PointType &p); - RendererProc _render; - - Graphics::Surface _framebuffer; - - OverlayColor *_overlayP; - WinHandle _overlayH, _workScreenH; - uint16 *_workScreenP; - - Boolean _isSwitchable, _wasRotated; - - virtual void int_initBackend(); - virtual void int_updateScreen(); - virtual void int_initSize(uint w, uint h); - - virtual void unload_gfx_mode(); - virtual void load_gfx_mode(); - virtual void hotswap_gfx_mode(int mode); - - void draw_mouse(); - void undraw_mouse(); - virtual bool check_event(Common::Event &event, EventPtr ev); - void extras_palette(uint8 index, uint8 r, uint8 g, uint8 b); - void calc_scale(); - - void render_landscapeAny(RectangleType &r, PointType &p); - void render_landscape15x(RectangleType &r, PointType &p); - void render_1x(RectangleType &r, PointType &p); - WinHandle alloc_screen(Coord w, Coord h); - virtual void draw_osd(UInt16 id, Int32 x, Int32 y, Boolean show, UInt8 color = 0); - - virtual SndStreamVariableBufferCallback sound_callback(); - virtual void sound_handler(); - virtual bool setupMixer(); - void clearSoundCallback(); - -protected: - UInt16 _sysOldCoord, _sysOldOrientation, _sysOldTriggerState; - Boolean _stretched, _cursorPaletteDisabled; - - enum { - kRatioNone = 0, - kRatioHeight, - kRatioWidth - }; - struct { - UInt8 adjustAspect; - Coord width; // (width x 320) - Coord height; // (480 x height) - } _ratio; - - void calc_rect(Boolean fullscreen); - void get_coordinates(EventPtr ev, Coord &x, Coord &y); - void clear_screen(); - -public: - OSystem_PalmOS5(); - static OSystem *create(); - - bool hasFeature(Feature f); - void setFeatureState(Feature f, bool enable); - - void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h); - virtual Graphics::Surface *lockScreen(); - virtual void unlockScreen(); - - void setCursorPalette(const byte *colors, uint start, uint num); - void disableCursorPalette(bool disable); - - void showOverlay(); - void hideOverlay(); - virtual void clearOverlay(); - virtual void grabOverlay(OverlayColor *buf, int pitch); - virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); - - void setWindowCaption(const char *caption); - -}; - -#endif diff --git a/backends/platform/PalmOS/Src/be_os5ex.cpp b/backends/platform/PalmOS/Src/be_os5ex.cpp deleted file mode 100644 index 05bf5e49ce..0000000000 --- a/backends/platform/PalmOS/Src/be_os5ex.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -// for DAL.h -#define ALLOW_ACCESS_TO_INTERNALS_OF_BITMAPS - -#include "be_os5ex.h" -#include "palmdefs.h" - -#include <System/WIP.h> -#include <System/DAL.h> - -static TimerExType _timerEx; - -OSystem_PalmOS5Ex::OSystem_PalmOS5Ex() : OSystem_PalmOS5() { - _timerEx.timerID = 0; - _timerEx.timer = &_timer; - _timerEx.ticks = SysTicksPerSecond(); -} - -static SYSTEM_CALLBACK void timer_handler(void *userDataP) { - CALLBACK_PROLOGUE - TimerExPtr _timerEx = (TimerExPtr)userDataP; - TimerPtr _timer = _timerEx->timer; - _timer->duration = _timer->callback(_timer->duration); - KALTimerSet(_timerEx->timerID, (_timer->duration * _timerEx->ticks / 1000)); - CALLBACK_EPILOGUE -} - -void OSystem_PalmOS5Ex::setTimerCallback(TimerProc callback, int timer) { - if (_timer.active && _timerEx.timerID) - KALTimerDelete(_timerEx.timerID); - - if (callback != NULL) { - Err e; - CALLBACK_INIT(_timerEx); - _timer.duration = timer; - _timer.callback = callback; - - // create the timer - e = KALTimerCreate(&_timerEx.timerID, appFileCreator, &::timer_handler, &_timerEx); - if (!e) { - e = KALTimerSet(_timerEx.timerID, (timer * _timerEx.ticks / 1000)); - if (e) KALTimerDelete(_timerEx.timerID); - } - _timer.active = (!e); - - } else { - _timer.active = false; - } - - if (!_timer.active) - _timerEx.timerID = 0; -} - -OSystem::MutexRef OSystem_PalmOS5Ex::createMutex() { - UInt32 mutexID; - Err e = KALMutexCreate(&mutexID, appFileCreator); - return (MutexRef)(e ? NULL : mutexID); - -} - -void OSystem_PalmOS5Ex::lockMutex(MutexRef mutex) { - if (mutex) - KALMutexReserve((UInt32)mutex); -} - -void OSystem_PalmOS5Ex::unlockMutex(MutexRef mutex) { - if (mutex) - KALMutexRelease((UInt32)mutex, 0); -} - -void OSystem_PalmOS5Ex::deleteMutex(MutexRef mutex) { - if (mutex) - KALMutexDelete((UInt32)mutex); -} - -void OSystem_PalmOS5Ex::int_quit() { - if (_timerEx.timerID) - KALTimerDelete(_timerEx.timerID); -} diff --git a/backends/platform/PalmOS/Src/be_os5ex.h b/backends/platform/PalmOS/Src/be_os5ex.h deleted file mode 100644 index f9842d82ac..0000000000 --- a/backends/platform/PalmOS/Src/be_os5ex.h +++ /dev/null @@ -1,68 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef BE_OS5EX_H -#define BE_OS5EX_H - -#include "be_os5.h" - -#undef dprintf // fix compilation in Zodiac mode - -#ifndef PALMOS_ARM -// Not usable with 68k mode (?), so ... -#define OSystem_PalmOS5Ex OSystem_PalmOS5 -#else - -typedef struct { - UInt32 __r9; - UInt32 __r10; - UInt32 timerID; - UInt32 ticks; - - TimerPtr timer; -} TimerExType, *TimerExPtr; - -class OSystem_PalmOS5Ex : public OSystem_PalmOS5 { -private: - void timer_handler() {} - void sound_handler() {} - void int_quit(); - - SndStreamVariableBufferCallback sound_callback(); - -public: - OSystem_PalmOS5Ex(); - static OSystem *create(); - - void setTimerCallback(TimerProc callback, int interval); - - MutexRef createMutex(); - void lockMutex(MutexRef mutex); - void unlockMutex(MutexRef mutex); - void deleteMutex(MutexRef mutex); -}; -#endif - -#endif diff --git a/backends/platform/PalmOS/Src/be_zodiac.cpp b/backends/platform/PalmOS/Src/be_zodiac.cpp deleted file mode 100644 index d6e7e2c292..0000000000 --- a/backends/platform/PalmOS/Src/be_zodiac.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_zodiac.h" - -OSystem_PalmZodiac::OSystem_PalmZodiac() : OSystem_PalmOS5Ex() { - _gfxH = NULL; - _overlayP = NULL; - _palmScreenP = NULL; - _tmpScreenP = NULL; - _stretched = false; -} - -void OSystem_PalmZodiac::int_initBackend() { - _keyExtra.bitUp = keyBitRockerUp; - _keyExtra.bitDown = keyBitRockerDown; - _keyExtra.bitLeft = keyBitRockerLeft; - _keyExtra.bitRight = keyBitRockerRight; - -// _keyExtra.bitActionA = keyBitActionD; -// _keyExtra.bitActionB = keyBitActionB; -} - -void OSystem_PalmZodiac::calc_rect(Boolean fullscreen) { - OSystem_PalmOS5::calc_rect(fullscreen); - - _dstRect.x = _screenOffset.x; - _dstRect.y = _screenOffset.y; - _dstRect.w = _screenDest.w; - _dstRect.h = _screenDest.h; -} - -void OSystem_PalmZodiac::setFeatureState(Feature f, bool enable) { - switch (f) { -/* case kFeatureFullscreenMode: - if (_gfxLoaded) - if (OPTIONS_TST(kOptModeWide) && _initMode != GFX_WIDE) { - _fullscreen = enable; - hotswap_gfx_mode(_mode); - } - break; -*/ - case kFeatureAspectRatioCorrection: - if (_mode == GFX_WIDE) { - _ratio.adjustAspect = (_ratio.adjustAspect + 1) % 3; - calc_rect(true); - TwGfxSetClip(_palmScreenP, &_dstRect); - clear_screen(); - } - break; - } -} diff --git a/backends/platform/PalmOS/Src/be_zodiac.h b/backends/platform/PalmOS/Src/be_zodiac.h deleted file mode 100644 index 28fcf29ddd..0000000000 --- a/backends/platform/PalmOS/Src/be_zodiac.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef BE_ZODIAC_H -#define BE_ZODIAC_H - -#include <tapwave.h> -#include "be_os5ex.h" - -#define MIN_OFFSET 20 - -class OSystem_PalmZodiac : public OSystem_PalmOS5Ex { -private: - - TwGfxType *_gfxH; - TwGfxSurfaceType *_palmScreenP, *_tmpScreenP; - TwGfxSurfaceType *_overlayP; - Boolean _fullscreen; - - TwGfxPointType _srcPos; - TwGfxRectType _srcRect, _dstRect; - TwGfxBitmapType _srcBmp; - - void int_initBackend(); - void int_setShakePos(int shakeOffset); - - void draw_mouse(); - void undraw_mouse(); - - void unload_gfx_mode(); - void load_gfx_mode(); - void hotswap_gfx_mode(int mode); - - void calc_rect(Boolean fullscreen); - bool check_event(Common::Event &event, EventPtr ev); - void draw_osd(UInt16 id, Int32 x, Int32 y, Boolean show, UInt8 color = 0); - -public: - OSystem_PalmZodiac(); - - static OSystem *create(); - - void setFeatureState(Feature f, bool enable); - - int getDefaultGraphicsMode() const; - - void updateScreen(); - - void clearOverlay(); - void grabOverlay(OverlayColor *buf, int pitch); - void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); -}; - -#endif diff --git a/backends/platform/PalmOS/Src/cd_aeroplayer.cpp b/backends/platform/PalmOS/Src/cd_aeroplayer.cpp deleted file mode 100644 index c30fba595c..0000000000 --- a/backends/platform/PalmOS/Src/cd_aeroplayer.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/system.h" -#include "common/config-manager.h" - -#include "cd_aeroplayer.h" - -AeroCDPlayer::AeroCDPlayer(OSystem *sys) { - _sys = sys; - StrCopy(gameP, ConfMan.getActiveDomainName().c_str()); -} - -bool AeroCDPlayer::init() { - aeroplayer_Startup(); - _isInitialized = aeroplayer_PlayerIsActive(); - - if (_isInitialized) - _volumeLimit = aeroplayer_GetMaxVolumeIndex(); - - return _isInitialized; -} - -void AeroCDPlayer::release() { - aeroplayer_Shutdown(); - - // self delete - delete this; -} - -UInt32 AeroCDPlayer::getStatus() { - return aeroplayer_GetPlaybackStatus(); -} - -UInt32 AeroCDPlayer::getPosition() { - return aeroplayer_GetPosition_msec(); -} - -UInt32 AeroCDPlayer::getDuration() { - return aeroplayer_GetDuration_msec(); -} - -void AeroCDPlayer::setPosition(UInt32 value) { - aeroplayer_Seek_abs_msec(value); -} - -void AeroCDPlayer::setVolume(int volume) { - _volumeLevel = volume; - aeroplayer_SetVolumeIndex((_volumeLimit * volume) / 100); -} - -bool AeroCDPlayer::poll() { - return - ( _pckLoops != 0 && - ( getPosition() < _pckTrackEndFrame && - getStatus() == AEROPLAYER_STATUS_PLAY - ) - ); -} - -void AeroCDPlayer::update() { - - // stop replay upon request of stopCD() - if (_pckStopTime != 0 && _sys->getMillis() >= _pckStopTime) { - forceStop(); - _pckLoops = 0; - _pckStopTime = 0; - _pckTrackEndFrame = 0; - return; - } - - // not fully played - if (getPosition() < _pckTrackEndFrame && getStatus() == AEROPLAYER_STATUS_PLAY) - return; - - aeroplayer_Pause(); -// _pckStopTime = _sys->getMillis(); - - // loop again ? - if (_pckLoops > 0) - _pckLoops--; - - // loop if needed - if (_pckLoops == 0) - forceStop(); - else { - //_pckStopTime = 0; - - if (_pckTrackStartFrame == 0 && _pckTrackDuration == 0) { - setPosition(0); - } else { - setPosition(_pckTrackStartFrame); - } - - aeroplayer_Play(); - _pckEndTime = _sys->getMillis() + _pckTrackDuration; - } -} - -void AeroCDPlayer::stop() { - _pckStopTime = _sys->getMillis(); - _pckLoops = 0; - return; -} - -void AeroCDPlayer::forceStop() { - if (getStatus() != AEROPLAYER_STATUS_STOP) - aeroplayer_PlayTrack(vfsInvalidVolRef, NULL); -} - -void AeroCDPlayer::play(int track, int num_loops, int start_frame, int duration) { - if (!num_loops && !start_frame) - return; - - Char fileP[100]; - static const Char *ext[] = { "mp3", "ogg" }; - -// if (duration > 0) -// duration += 5; - - _pckTrack = track; - _pckLoops = num_loops; - _pckTrackStartFrame = TO_MSECS(start_frame); - _pckTrackDuration = TO_MSECS(duration); - - StrPrintF(fileP, "/Palm/Programs/ScummVM/Audio/%s_%03ld.%s", gameP, (track + gVars->CD.firstTrack - 1), ext[gVars->CD.format]); - aeroplayer_Pause(); - aeroplayer_PlayTrack(gVars->VFS.volRefNum, fileP); - aeroplayer_Pause(); - - if (_pckTrackStartFrame == 0 && _pckTrackDuration == 0) { - _pckTrackDuration = getDuration(); - } else { - setPosition(_pckTrackStartFrame); - if (_pckTrackDuration == 0) - _pckTrackDuration = getDuration() - _pckTrackStartFrame; - } - - aeroplayer_Play(); - - _pckStopTime = 0; - _pckTrackEndFrame = _pckTrackStartFrame + _pckTrackDuration; - _pckEndTime = _sys->getMillis() + _pckTrackDuration; -} diff --git a/backends/platform/PalmOS/Src/cd_aeroplayer.h b/backends/platform/PalmOS/Src/cd_aeroplayer.h deleted file mode 100644 index e661e06d52..0000000000 --- a/backends/platform/PalmOS/Src/cd_aeroplayer.h +++ /dev/null @@ -1,65 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef CD_AEROPLAYER_H -#define CD_AEROPLAYER_H - -#include "cdaudio.h" -#include "aeroplayer_public.h" - -class AeroCDPlayer : public CDAudio { -public: - AeroCDPlayer(OSystem *sys); - - bool init(); - void release(); - - bool poll(); - void update(); - void play(int track, int num_loops, int start_frame, int duration); - void stop(); - - void setVolume(int volume); - -private: - OSystem *_sys; - Char gameP[15]; - - UInt32 getStatus(); - void setPosition(UInt32 value); - UInt32 getDuration(); - UInt32 getPosition(); - void forceStop(); - - UInt16 _volumeLimit; - - Boolean _isPlaying; - // cdrom - UInt16 _pckLoops, _pckTrack; - UInt32 _pckTrackStartFrame, _pckTrackEndFrame; - UInt32 _pckStopTime, _pckEndTime, _pckTrackDuration; -}; - -#endif diff --git a/backends/platform/PalmOS/Src/cd_default.cpp b/backends/platform/PalmOS/Src/cd_default.cpp deleted file mode 100644 index 416701524d..0000000000 --- a/backends/platform/PalmOS/Src/cd_default.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ -#include "common/system.h" -#include "cd_default.h" - -DefaultCDPlayer::DefaultCDPlayer(OSystem *sys) { - _sys = sys; -} - -bool DefaultCDPlayer::init() { - _isInitialized = true; - return _isInitialized; -} - -void DefaultCDPlayer::release() { - // self delete - delete this; -} - -bool DefaultCDPlayer::poll() { - return (_defLoops != 0 && _sys->getMillis() < _defTrackEndFrame); -} - -void DefaultCDPlayer::update() { - - // stop replay upon request of stopCD() - if (_defStopTime != 0 && _sys->getMillis() >= _defStopTime) { - _defLoops = 0; - _defStopTime = 0; - _defTrackEndFrame = 0; - return; - } - - // not fully played - if (_sys->getMillis() < _defTrackEndFrame) - return; - - if (_defLoops == 0) - return; - - // loop again ? - if (_defLoops > 0) - _defLoops--; - - // loop if needed - if (_defLoops != 0) { - _defTrackEndFrame = _sys->getMillis() + _defTrackLength; - } -} - -void DefaultCDPlayer::stop() { /* Stop CD Audio in 1/10th of a second */ - _defStopTime = _sys->getMillis() + 100; - _defLoops = 0; - return; -} - -void DefaultCDPlayer::play(int track, int num_loops, int start_frame, int duration) { - if (!num_loops && !start_frame) - return; - - UInt32 fullLength; - - _defLoops = num_loops; - start_frame = TO_MSECS(start_frame); - duration = TO_MSECS(duration); - - // frame in milli-seconds - _defStopTime = 0; - fullLength = start_frame + gVars->CD.defaultTrackLength * 1000; - - if (duration > 0) { - _defTrackLength = duration; - } else if (start_frame > 0) { - _defTrackLength = fullLength; - _defTrackLength -= start_frame; - } else { - _defTrackLength = fullLength; - } - - // try to play the track - _defTrackEndFrame = _sys->getMillis() + _defTrackLength; -} diff --git a/backends/platform/PalmOS/Src/cd_default.h b/backends/platform/PalmOS/Src/cd_default.h deleted file mode 100644 index 69d909b1e7..0000000000 --- a/backends/platform/PalmOS/Src/cd_default.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - - #ifndef CD_DEFAULT_H - #define CD_DEFAULT_H - - #include "cdaudio.h" - - class DefaultCDPlayer : public CDAudio { - public: - DefaultCDPlayer(OSystem *sys); - - bool init(); - void release(); - - bool poll(); - void update(); - void play(int track, int num_loops, int start_frame, int duration); - void stop(); - - private: - OSystem *_sys; - - // cdrom - UInt16 _defLoops; - UInt32 _defStopTime, _defTrackEndFrame, _defTrackLength; - }; - - #endif diff --git a/backends/platform/PalmOS/Src/cd_msa.cpp b/backends/platform/PalmOS/Src/cd_msa.cpp deleted file mode 100644 index 5812d49b6d..0000000000 --- a/backends/platform/PalmOS/Src/cd_msa.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ -#include <SonyClie.h> -#include "common/system.h" -#include "cd_msa.h" -#include "start.h" // for appFileCreat - -static void doErr(Err e, const Char *msg) { - Char err[100]; - StrPrintF(err, "%ld : " , e); - StrCat(err,msg); - FrmCustomAlert(1000,err,0,0); -} - -MsaCDPlayer::MsaCDPlayer(OSystem *sys) { - _sys = sys; - _msaRefNum = sysInvalidRefNum; - - _msaLoops = 0; - _msaStopTime = 0; - _msaTrackEndSu = 0; -} - -bool MsaCDPlayer::init() { - SonySysFtrSysInfoP sonySysFtrSysInfoP; - Err error = errNone; - - if (!(error = FtrGet(sonySysFtrCreator, sonySysFtrNumSysInfoP, (UInt32*)&sonySysFtrSysInfoP))) { - // not found with audio adapter ?! - //if (sonySysFtrSysInfoP->libr & sonySysFtrSysInfoLibrMsa) { - if ((error = SysLibFind(sonySysLibNameMsa, &_msaRefNum))) - if (error == sysErrLibNotFound) - error = SysLibLoad(sonySysFileTMsaLib, sonySysFileCMsaLib, &_msaRefNum); - - // FIXME : still don't understand how this lib works, it seems to be very unstable - // and with the very bad documentation provided by Sony it's difficult to find out why - // this doesn't work the same way on build-in MP3 device and external MP3 devices - if (!error) { - //MsaLibClose(_msaRefNum, msaLibOpenModeAlbum); // close the lib if we previously let it open (?) Need to add Notify for sonySysNotifyMsaEnforceOpenEvent just in case ... - error = MsaLibOpen(_msaRefNum, msaLibOpenModeAlbum); - - //if (error == msaErrAlreadyOpen) - // error = MsaLibEnforceOpen(_msaRefNum, msaLibOpenModeAlbum, appFileCreator); - - //error = (error != msaErrStillOpen) ? error : errNone; - } - //} - } - -// if (error) -// _msaRefNum = sysInvalidRefNum; - - _isInitialized = (_msaRefNum != sysInvalidRefNum); - initInternal(); - return _isInitialized; -} - -void MsaCDPlayer::initInternal() { - if (!_isInitialized) - return; - - Err e; - Char nameP[256]; - UInt32 dummy, albumIterater = albumIteratorStart; - - MemSet(&_msaAlbum, sizeof(_msaAlbum), 0); - _msaAlbum.maskflag = msa_INF_ALBUM; - _msaAlbum.code = msa_LANG_CODE_ASCII; - _msaAlbum.nameP = nameP; - _msaAlbum.fileNameLength = 256; - - e = MsaAlbumEnumerate(_msaRefNum, &albumIterater, &_msaAlbum); - e = MsaSetAlbum(_msaRefNum, _msaAlbum.albumRefNum, &dummy); - - // TODO : use RMC to control volume - MsaOutCapabilityType capability; - MsaOutGetCapability(_msaRefNum, &capability); - _volumeLLimit = capability.volumeLLimit; - _volumeRLimit = capability.volumeRLimit; -} - -void MsaCDPlayer::setVolume(int volume) { - _volumeLevel = volume; - MsaOutSetVolume(_msaRefNum, (_volumeLLimit * volume) / 100, (_volumeRLimit * volume) / 100); -} - -void MsaCDPlayer::release() { - if (_isInitialized) { - if (_msaRefNum != sysInvalidRefNum) { - // stop the current track if any (needed if we use enforce open to prevent the track to play after exit) - MsaStop(_msaRefNum, true); - MsaLibClose(_msaRefNum, msaLibOpenModeAlbum); - } - } - - // self delete - delete this; -} - -bool MsaCDPlayer::poll() { - if (!_isInitialized) - return false; - - MsaPBStatus pb; - MsaGetPBStatus(_msaRefNum, &pb); - return (_msaLoops != 0 && (pb.currentSU < _msaTrackEndSu || pb.status != msa_STOPSTATUS)); -} - -void MsaCDPlayer::update() { - if (!_isInitialized) - return; - - // get playback status - MsaPBStatus pb; - MsaGetPBStatus(_msaRefNum, &pb); - - // stop replay upon request of stopCD() - if (_msaStopTime != 0 && _sys->getMillis() >= _msaStopTime) { - MsaStop(_msaRefNum, true); - _msaLoops = 0; - _msaStopTime = 0; - _msaTrackEndSu = 0; - return; - } - - // not fully played nad still playing the correct track - // (when playing a full track the return SU is not correct - // and so we need to check if we are still playing the correct track) - if (pb.currentSU < _msaTrackEndSu) { - UInt16 trackNo; - MsaPBListIndexToTrackNo(_msaRefNum, pb.currentpblistindex, &trackNo); - if (trackNo == _msaTrack) - return; - } - - MsaStop(_msaRefNum, true); - - if (_msaLoops == 0) - return; - - // track ends and last play, force stop if still playing -/* if (_msaLoops != 1 && pb.status != msa_STOPSTATUS) { - MsaStop(_msaRefNum, true); - return; - } -*/ - // loop again ? - if (_msaLoops > 0) - _msaLoops--; - - // loop if needed - if (_msaLoops != 0) { - if (_msaStartFrame == 0 && _msaDuration == 0) - MsaPlay(_msaRefNum, _msaTrack, 0, msa_PBRATE_SP); - else - MsaPlay(_msaRefNum, _msaTrack, _msaTrackStartSu, msa_PBRATE_SP); - } -} - -void MsaCDPlayer::stop() { /* Stop CD Audio in 1/10th of a second */ - if (!_isInitialized) - return; - - _msaStopTime = _sys->getMillis() + 100; - _msaLoops = 0; - return; -} - -void MsaCDPlayer::play(int track, int num_loops, int start_frame, int duration) { - if (!_isInitialized) - return; - - if (!num_loops && !start_frame) - return; - - _msaTrack = track + gVars->CD.firstTrack - 1; // first track >= 1 ?, not 0 (0=album) - _msaLoops = num_loops; - _msaStartFrame = TO_MSECS(start_frame); - _msaDuration = TO_MSECS(duration); - - Err e; - MemHandle trackH; - - // stop current play if any - MsaStop(_msaRefNum, true); - _msaStopTime = 0; - - // retreive track infos - e = MsaGetTrackInfo(_msaRefNum, _msaTrack, 0, msa_LANG_CODE_ASCII, &trackH); - - // track exists - if (!e && trackH) { - MsaTime msaTime; - MsaTrackInfo *trackP; - UInt32 SU, fullLength; - - // FIXME (?) : this enable MsaSuToTime to return the right value in some cases - MsaPlay(_msaRefNum, _msaTrack, 0, msa_PBRATE_SP); - MsaStop(_msaRefNum, true); - - // get the msa time - trackP = (MsaTrackInfo *)MemHandleLock(trackH); - MsaSuToTime(_msaRefNum, trackP->totalsu, &msaTime); - SU = trackP->totalsu; - MemPtrUnlock(trackP); - MemHandleFree(trackH); - - // MSA frame in milli-seconds - fullLength = FROM_MIN(msaTime.minute); - fullLength += FROM_SEC(msaTime.second); - fullLength += msaTime.frame; - - if (_msaDuration > 0) { - _msaTrackLength = _msaDuration; - } else if (_msaStartFrame > 0) { - _msaTrackLength = fullLength; - _msaTrackLength -= _msaStartFrame; - } else { - _msaTrackLength = fullLength; - } - - // try to play the track - if (start_frame == 0 && duration == 0) { - MsaPlay(_msaRefNum, _msaTrack, 0, msa_PBRATE_SP); - _msaTrackEndSu = SU; - } else { - // FIXME : MsaTimeToSu doesn't work ... (may work with previous FIXME) - _msaTrackStartSu = (UInt32) ((float)(_msaStartFrame) / ((float)fullLength / (float)SU)); - _msaTrackEndSu = (UInt32) ((float)(_msaTrackLength) / ((float)fullLength / (float)SU)); - _msaTrackEndSu += _msaTrackStartSu; - - if (_msaTrackEndSu > SU) - _msaTrackEndSu = SU; - - MsaPlay(_msaRefNum, _msaTrack, _msaTrackStartSu, msa_PBRATE_SP); - } - } - // TODO : use default track length if track not found -} diff --git a/backends/platform/PalmOS/Src/cd_msa.h b/backends/platform/PalmOS/Src/cd_msa.h deleted file mode 100644 index 223bc0efcf..0000000000 --- a/backends/platform/PalmOS/Src/cd_msa.h +++ /dev/null @@ -1,68 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef CD_MSA_H -#define CD_MSA_H - -#include "cdaudio.h" - -class MsaCDPlayer : public CDAudio { -public: - MsaCDPlayer(OSystem *sys); - - bool init(); - void release(); - - bool poll(); - void update(); - void play(int track, int num_loops, int start_frame, int duration); - void stop(); - - void setVolume(int volume); - - private: - void initInternal(); - - OSystem *_sys; - UInt16 _msaRefNum; - - UInt32 _volumeLLimit; - UInt32 _volumeRLimit; - - // cdrom - AlbumInfoType _msaAlbum; - UInt16 _msaLoops; - - UInt32 _msaStopTime; - - UInt32 _msaStartFrame; - UInt32 _msaDuration; - - UInt16 _msaTrack; - UInt32 _msaTrackStartSu, _msaTrackEndSu; - UInt32 _msaTrackLength; -}; - -#endif diff --git a/backends/platform/PalmOS/Src/cd_pockettunes.cpp b/backends/platform/PalmOS/Src/cd_pockettunes.cpp deleted file mode 100644 index 5a9f3874eb..0000000000 --- a/backends/platform/PalmOS/Src/cd_pockettunes.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ -#include "common/system.h" -#include "common/config-manager.h" - -#include "cd_pockettunes.h" - -PckTunesCDPlayer::PckTunesCDPlayer(OSystem *sys) { - _sys = sys; - StrCopy(gameP, ConfMan.getActiveDomainName().c_str()); -} - -bool PckTunesCDPlayer::init() { - PocketTunesStart(); - _isInitialized = PocketTunesIsRunning(); - _isPlaying = false; - _pAction = NULL; - - if (_isInitialized) { - _pAction = (PocketTunesAction*)MemPtrNew(sizeof(PocketTunesAction)); - _volumeLimit = getVolumeLimit(); - } - - _isInitialized = (_isInitialized && _pAction); - return _isInitialized; -} - -void PckTunesCDPlayer::release() { - PocketTunesStop(); - if (_pAction) - MemPtrFree(_pAction); - - // self delete - delete this; -} - -UInt32 PckTunesCDPlayer::getVolumeLimit() { - UInt32 value = 0; - - if (!_pAction) - return value; - - _pAction->action = kPocketTunesActionGetValue; - _pAction->data.getValueAction.which = kPtunesValueMaxVolume; - - EvtGetEvent(&_eAction, evtNoWait); - if (PocketTunesCallSynch(_pAction) == errNone) - value = _pAction->data.getValueAction.value; - - return value; -} - -UInt32 PckTunesCDPlayer::getStatus() { - UInt32 status = kPtunesStopped; - - if (!_isPlaying || !_pAction) - return status; - - _pAction->action = kPocketTunesActionGetStatus; - - EvtGetEvent(&_eAction, evtNoWait); - if (PocketTunesCallSynch(_pAction) == errNone) - status = _pAction->data.getStatusAction.status; - - return status; -} - -UInt32 PckTunesCDPlayer::getPosition(UInt32 deflt) { - UInt32 value = deflt; - - if (!_isPlaying || !_pAction) - return value; - - _pAction->action = kPocketTunesActionGetValue; - _pAction->data.getValueAction.which = kPtunesValueSongPosition; - - EvtGetEvent(&_eAction, evtNoWait); - if (PocketTunesCallSynch(_pAction) == errNone) - value = _pAction->data.getValueAction.value; - - return value; -} - -UInt32 PckTunesCDPlayer::getDuration() { - UInt32 value = gVars->CD.defaultTrackLength; - - if (!_isPlaying || !_pAction) - return value; - - _pAction->action = kPocketTunesActionGetValue; - _pAction->data.getValueAction.which = kPtunesValueSongDuration; - - EvtGetEvent(&_eAction, evtNoWait); - if (PocketTunesCallSynch(_pAction) == errNone) - value = _pAction->data.getValueAction.value; - - return value; -} - -void PckTunesCDPlayer::setPosition(UInt32 value) { - if (!_isPlaying) - return; - - PocketTunesAction *pAction = AllocateAsynchronousActionStruct(); - if (!pAction) - return; - - pAction->action = kPocketTunesActionSetValue; - pAction->data.getValueAction.which = kPtunesValueSongPosition; - pAction->data.getValueAction.value = value; - - EvtGetEvent(&_eAction, evtNoWait); - PocketTunesCall(pAction); -} - -void PckTunesCDPlayer::setVolume(int volume) { - _volumeLevel = volume; - - PocketTunesAction *pAction = AllocateAsynchronousActionStruct(); - if (!pAction) - return; - - pAction->action = kPocketTunesActionSetValue; - pAction->data.getValueAction.which = kPtunesValueVolume; - pAction->data.getValueAction.value = (_volumeLimit * volume) / 100; - - EvtGetEvent(&_eAction, evtNoWait); - PocketTunesCall(pAction); -} - -bool PckTunesCDPlayer::poll() { - return (_pckLoops != 0 && (getPosition(_pckTrackEndFrame) < _pckTrackEndFrame || getStatus() != kPtunesStopped)); -} - -void PckTunesCDPlayer::update() { - - // stop replay upon request of stopCD() - if (_pckStopTime != 0 && _sys->getMillis() >= _pckStopTime) { - PocketTunesStop(); - _pckLoops = 0; - _pckStopTime = 0; - _pckTrackEndFrame = 0; - return; - } - - // not fully played - if (getPosition(_pckTrackEndFrame) < _pckTrackEndFrame && getStatus() != kPtunesStopped) - return; - - PocketTunesStop(); - - if (_pckLoops == 0) - return; - - // loop again ? - if (_pckLoops > 0) - _pckLoops--; - - // loop if needed - if (_pckLoops != 0 && _isPlaying) { - if (_pckTrackStartFrame == 0 && _pckTrackDuration == 0) { - setPosition(0); - } else { - setPosition(_pckTrackStartFrame); - } - - PocketTunesPlay(); - } -} - -void PckTunesCDPlayer::stop() { /* Stop CD Audio in 1/10th of a second */ - _pckStopTime = _sys->getMillis() + 100; - _pckLoops = 0; - return; -} - -void PckTunesCDPlayer::play(int track, int num_loops, int start_frame, int duration) { - if (!num_loops && !start_frame) - return; - - EventType e; - Char nameP[256], fileP[100]; - static const Char *ext[] = { "mp3", "ogg" }; - - _pckTrack = track; - _pckLoops = num_loops; - _pckTrackStartFrame = TO_MSECS(start_frame); - _pckTrackDuration = TO_MSECS(duration); - - VFSVolumeGetLabel(gVars->VFS.volRefNum, nameP, 256); - - StrPrintF(fileP, "/Palm/Programs/ScummVM/Audio/%s_%03ld.%s", gameP, (track + gVars->CD.firstTrack - 1), ext[gVars->CD.format]); - - if (PocketTunesOpenFile(nameP, fileP, 0) == errNone) { - EvtGetEvent(&e, evtNoWait); - PocketTunesPauseIfPlaying(); - _isPlaying = true; - - if (_pckTrackStartFrame == 0 && _pckTrackDuration == 0) { - _pckTrackDuration = getDuration(); - } else { - setPosition(_pckTrackStartFrame); - if (_pckTrackDuration == 0) - _pckTrackDuration = getDuration() - _pckTrackStartFrame; - } - - PocketTunesPlay(); - - } else { - _isPlaying = false; - _pckTrackDuration = gVars->CD.defaultTrackLength * 1000; - } - - _pckStopTime = 0; - _pckTrackEndFrame = _pckTrackStartFrame + _pckTrackDuration; -} diff --git a/backends/platform/PalmOS/Src/cd_pockettunes.h b/backends/platform/PalmOS/Src/cd_pockettunes.h deleted file mode 100644 index 77938d846a..0000000000 --- a/backends/platform/PalmOS/Src/cd_pockettunes.h +++ /dev/null @@ -1,69 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - - #ifndef CD_POCKETTUNES_H - #define CD_POCKETTUNES_H - - #include "cdaudio.h" - #include "pockettunes.h" - - class PckTunesCDPlayer : public CDAudio { - public: - PckTunesCDPlayer(OSystem *sys); - - bool init(); - void release(); - - bool poll(); - void update(); - void play(int track, int num_loops, int start_frame, int duration); - void stop(); - - void setVolume(int volume); - - private: - OSystem *_sys; - Char gameP[15]; - - PocketTunesAction *_pAction; // prevent memory fragmentation - EventType _eAction; - - UInt32 getStatus(); - void setPosition(UInt32 value); - UInt32 getDuration(); - UInt32 getPosition(UInt32 deft); - - UInt32 _volumeLimit; - UInt32 getVolumeLimit(); - - Boolean _isPlaying; - // cdrom - UInt16 _pckLoops, _pckTrack; - UInt32 _pckTrackStartFrame, _pckTrackEndFrame; - UInt32 _pckStopTime, _pckTrackDuration; - }; - - #endif - diff --git a/backends/platform/PalmOS/Src/cdaudio.h b/backends/platform/PalmOS/Src/cdaudio.h deleted file mode 100644 index 7a3f5e56e4..0000000000 --- a/backends/platform/PalmOS/Src/cdaudio.h +++ /dev/null @@ -1,67 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef CDAUDIO_H -#define CDAUDIO_H - -#include "common/system.h" - -// CD frames are 1/75 sec -#define CD_FPS 75 -#define TO_MSECS(frame) ((UInt32)((frame) * 1000 / CD_FPS)) - -// consider frame at 1/1000 sec -#define FROM_MIN(mins) ((UInt32)((mins) * 60 * 1000)) -#define FROM_SEC(secs) ((UInt32)((secs) * 1000)) - -class CDAudio { -public: - CDAudio() { - _isInitialized = false; - _volumeLevel = 100; - }; - - virtual bool init() = 0; - virtual void release() = 0; - - // OSystem functions - virtual bool poll() = 0; - virtual void play(int track, int num_loops, int start_frame, int duration) = 0; - virtual void stop() = 0; - virtual void update() = 0; - - // volume in percent - virtual void setVolume(int volume) { _volumeLevel = volume; } - virtual int getVolume() const { return _volumeLevel; } - - virtual void upVolume(int value) {} - virtual void downVolume(int value) {} - -protected: - int _volumeLevel; - bool _isInitialized; -}; - -#endif diff --git a/backends/platform/PalmOS/Src/extend.cpp b/backends/platform/PalmOS/Src/extend.cpp deleted file mode 100644 index 430563a302..0000000000 --- a/backends/platform/PalmOS/Src/extend.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "PalmVersion.h" -#include <stdlib.h> -#include "globals.h" - -#include "modulesrsc.h" - -void PalmFatalError(const char *err) { - WinSetDrawWindow(WinGetDisplayWindow()); - WinPalette(winPaletteSetToDefault,0,0,0); - WinSetBackColor(0); - WinEraseWindow(); - FrmCustomAlert(FrmFatalErrorAlert, err, 0,0); -} - -void DrawStatus(Boolean show) { - if (OPTIONS_TST(kOptDisableOnScrDisp)) - return; - - UInt8 x,y; - UInt32 depth, d1; - Boolean d2; - WinScreenMode(winScreenModeGet, &d1, &d1, &depth, &d2); - Int16 color = (show ? gVars->indicator.on : gVars->indicator.off); - - if (depth == 8) { - UInt8 *src = (UInt8 *)BmpGetBits(WinGetBitmap(WinGetDisplayWindow())); - src += gVars->screenPitch + 1; - for (y=0; y < 4; y++) { - for (x=0; x < 4; x++) - src[x] = color; - - src += gVars->screenPitch; - } - - } else if (depth == 16) { - Int16 *src = (Int16 *)BmpGetBits(WinGetBitmap(WinGetDisplayWindow())); - src += gVars->screenPitch + 1; - for (y=0; y < 4; y++) { - for (x=0; x < 4; x++) - src[x] = color; - - src += gVars->screenPitch; - } - } -} - -#ifndef PALMOS_ARM - -// This is now required since some classes are now very big :) -#include "MemGlue.h" -void *operator new(UInt32 size) { - void *ptr = MemGluePtrNew(size); - MemSet(ptr, 0, size); - return ptr; -} - -void *operator new [] (UInt32 size) { - void *ptr = MemGluePtrNew(size); - MemSet(ptr, 0, size); - return ptr; -} -#elif defined(COMPILE_OS5) || defined(STDLIB_TRACE_MEMORY) - -void *operator new(UInt32 size) { - void *ptr = malloc(size); - MemSet(ptr, 0, size); - return ptr; -} - -void *operator new [] (UInt32 size) { - void *ptr = malloc(size); - MemSet(ptr, 0, size); - return ptr; -} - -void operator delete(void *ptr) throw() { - if (ptr) free(ptr); -} - -void operator delete[](void *ptr) throw() { - if (ptr) free(ptr); -} - -#endif diff --git a/backends/platform/PalmOS/Src/features.h b/backends/platform/PalmOS/Src/features.h deleted file mode 100644 index f82c7692fa..0000000000 --- a/backends/platform/PalmOS/Src/features.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __FEATURES_H__ -#define __FEATURES_H__ - -enum { - ftrBufferOverlay = 1000, - ftrBufferBackup, - ftrBufferHotSwap -}; - -#define FREE_FTR(num) \ - { \ - UInt32 ptr; \ - FtrGet(appFileCreator, num, &ptr); \ - if (ptr) FtrPtrFree(appFileCreator, num); \ - } - -#endif diff --git a/backends/platform/PalmOS/Src/globals.h b/backends/platform/PalmOS/Src/globals.h deleted file mode 100644 index 796832df82..0000000000 --- a/backends/platform/PalmOS/Src/globals.h +++ /dev/null @@ -1,114 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef GLOBALS_H -#define GLOBALS_H - -#include <VFSMgr.h> -#include "stuffs.h" - -enum { - INIT_VIBRATOR = 1 << 0x00, - INIT_PA1LIB = 1 << 0x01, - INIT_ARM = 1 << 0x02, - INIT_AUTOOFF = 1 << 0x03, - INIT_GOLCD = 1 << 0x04 -}; - -enum { - FM_QUALITY_LOW = 0, - FM_QUALITY_MED, - FM_QUALITY_HI, - FM_QUALITY_INI -}; - -typedef struct { - // common parts - UInt32 _4B, _2B; - - // 4 bytes part - UInt32 startupMemory; - UInt32 slkVersion; - UInt32 options; - UInt32 screenPitch; - - struct { - FileRef logFile; - UInt32 cacheSize; - UInt16 volRefNum; - UInt16 dummy; - } VFS; - - // 2 bytes part - UInt16 HRrefNum; - UInt16 slkRefNum; - Coord screenWidth, screenHeight; // silkarea shown - Coord screenFullWidth, screenFullHeight; // silkarea hidden - Int16 autoSave; - struct { - Int16 on; - Int16 off; - Int16 showLED; - } indicator; - - // 1 byte part - Boolean vibrator; - Boolean stdPalette; - Boolean filter; - Boolean stylusClick; - Boolean arrowKeys; - UInt8 init; - UInt8 palmVolume; - UInt8 fmQuality; - UInt8 advancedMode; - -} GlobalsDataType, *GlobalsDataPtr; - -extern GlobalsDataPtr gVars; - -#define VARS_EXPORT() gVars->_4B = 6; \ - gVars->_2B = 12; - -#define DO_VARS(z, t, o) \ - { Int8 *tmp = (Int8 *)gVars + o + 8; \ - for (Int8 cnt = 0; cnt < gVars->z; cnt++) \ - { UInt##t val = *((UInt##t *)tmp); \ - val = ByteSwap##t(val); \ - *((UInt##t *)tmp) = val; \ - tmp += (t / 8); \ - } \ - } - -#define OPTIONS_DEF() gVars->options - -#define HWR_INIT(x) (gVars->init & (x)) -#define HWR_SET(x) gVars->init |= (x) -#define HWR_RST(x) gVars->init &= ~(x) -#define HWR_RSTALL() gVars->init = 0 -#define HWR_GET() (gVars->init) - -#define ARM(x) gVars->arm[x] - -#endif diff --git a/backends/platform/PalmOS/Src/i_zodiac.cpp b/backends/platform/PalmOS/Src/i_zodiac.cpp deleted file mode 100644 index 20b06aa61f..0000000000 --- a/backends/platform/PalmOS/Src/i_zodiac.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include <PalmOS.h> -#include "extend.h" - -#ifndef DISABLE_TAPWAVE - -#include "tapwave.h" -#include "i_zodiac.h" - -// _twBmpV3 = offscreen bitmap, must be set before this call -Err ZodiacInit(void **ptrP, Int32 w, Int32 h) { - Err e; - - TwGfxSurfaceInfoType surface = { - sizeof(TwGfxSurfaceInfoType), - w, h, w * 2, - twGfxLocationAcceleratorMemory, - twGfxPixelFormatRGB565_LE - }; - - e = SysSetOrientation(sysOrientationLandscape); - e = TwGfxOpen((TwGfxType **)&_twGfxLib, NULL); - e = TwGfxAllocSurface( (TwGfxType *)_twGfxLib, - (TwGfxSurfaceType **)&_twSrc, - &surface); - - e = TwGfxGetPalmDisplaySurface( (TwGfxType *)_twGfxLib, - (TwGfxSurfaceType **)&_twDst); - - return e; -} - -Err ZodiacRelease(void **ptrP) { - Err e = errNone; - - TwGfxFreeSurface((TwGfxSurfaceType *)_twSrc); - TwGfxClose((TwGfxType *)_twGfxLib); - - return e; -} - -#endif diff --git a/backends/platform/PalmOS/Src/i_zodiac.h b/backends/platform/PalmOS/Src/i_zodiac.h deleted file mode 100644 index 96a373a22e..0000000000 --- a/backends/platform/PalmOS/Src/i_zodiac.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _I_ZODIAC_H_ -#define _I_ZODIAC_H_ - -#define _twGfxLib ptrP[0] -#define _twSrc ptrP[1] -#define _twDst ptrP[2] -#define _twBmpV3 ptrP[3] - -Err ZodiacInit(void **ptrP, Int32 w, Int32 h); -Err ZodiacRelease(void **ptrP); - -#endif diff --git a/backends/platform/PalmOS/Src/init_golcd.cpp b/backends/platform/PalmOS/Src/init_golcd.cpp deleted file mode 100644 index b09d3b104e..0000000000 --- a/backends/platform/PalmOS/Src/init_golcd.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include <PalmOS.h> -#include <PalmGoLCD.h> - -#include "init_golcd.h" - -// you can use this handle directly -MemHandle gGoLcdH; - -Err GoLCDInit(MemHandle *goLcdH) { - if (!goLcdH) - return sysErrParamErr; - - Err e; - UInt16 refNum; - Boolean loaded = false; - *goLcdH = NULL; - - if (e = SysLibFind(goLcdLibName, &refNum)) - loaded = !(e = SysLibLoad(goLcdLibType, goLcdLibCreator, &refNum)); - - if (!e) - if ((e = GoLcdLibOpen(refNum))) - SysLibRemove(refNum); - - if (!e) { - MemHandle lcdH = MemHandleNew(sizeof(GoLCDType)); - GoLCDType *lcdP = (GoLCDType *)MemHandleLock(lcdH); - MemSet(lcdP, MemHandleSize(lcdH), 0); - lcdP->refNum = refNum; - lcdP->timeout = GoLcdGetTimeout(refNum, goLcdPenTapMode); - MemPtrUnlock(lcdP); - *goLcdH = lcdH; - } - - return e; -} - -Err GoLCDRelease(MemHandle goLcdH) { - if (!goLcdH) - return sysErrParamErr; - - Err e; - GoLCDType *lcdP = (GoLCDType *)MemHandleLock(goLcdH); - if (lcdP->refNum != sysInvalidRefNum) - if (!(e = GoLcdLibClose(lcdP->refNum))) - e = SysLibRemove(lcdP->refNum); - - MemPtrUnlock(lcdP); - MemHandleFree(goLcdH); - - return e; -} - -Boolean GoLCDPointInBounds(MemHandle goLcdH, Coord x, Coord y) { - Boolean inBounds = false; - - if (!goLcdH) - return inBounds; - - GoLCDType *lcdP = (GoLCDType *)MemHandleLock(goLcdH); - inBounds = (lcdP->active && RctPtInRectangle(x, y, &(lcdP->bounds))); - MemPtrUnlock(lcdP); - - return inBounds; -} - -void GoLCDSetInk(MemHandle goLcdH, RGBColorType *inkP) { - if (!goLcdH) - return; - - GoLCDType *lcdP = (GoLCDType *)MemHandleLock(goLcdH); - MemMove(&(lcdP->ink), inkP, sizeof(RGBColorType)); - MemPtrUnlock(lcdP); -} - -void GoLCDSetBounds(MemHandle goLcdH, RectangleType *boundsP) { - if (!goLcdH) - return; - - GoLCDType *lcdP = (GoLCDType *)MemHandleLock(goLcdH); - MemMove(&(lcdP->bounds), boundsP, sizeof(RectangleType)); - MemPtrUnlock(lcdP); -} - -void GoLCDActivate(MemHandle goLcdH, Boolean active) { - if (!goLcdH) - return; - - GoLCDType *lcdP = (GoLCDType *)MemHandleLock(goLcdH); - - if (active) { - if (!lcdP->active) { - lcdP->active = true; - GoLcdSetInkState(lcdP->refNum, goLcdInkEnabled, goLcdColorOverride, &(lcdP->ink)); - GoLcdSetBounds(lcdP->refNum, &(lcdP->bounds)); - GoLcdSetGsiState(lcdP->refNum, goLcdGsiNormal, goLcdColorDefault, 0); - GoLcdSetTimeout(lcdP->refNum, goLcdPenTapMode, lcdP->timeout); - GoLcdSetStatus(lcdP->refNum, goLcdEnabled); - } - - } else { - lcdP->active = false; - GoLcdSetInkState(lcdP->refNum, goLcdInkDisabled, goLcdColorDefault, 0); - GoLcdSetStatus(lcdP->refNum, goLcdDisabled); - } - - MemPtrUnlock(lcdP); -} - -Boolean GoLCDToggle(MemHandle goLcdH) { - if (!goLcdH) - return; - - Boolean active; - GoLCDType *lcdP = (GoLCDType *)MemHandleLock(goLcdH); - active = lcdP->active; - MemPtrUnlock(lcdP); - - GoLCDActivate(goLcdH, !active); - return (!active); -} diff --git a/backends/platform/PalmOS/Src/init_golcd.h b/backends/platform/PalmOS/Src/init_golcd.h deleted file mode 100644 index 7750a13a52..0000000000 --- a/backends/platform/PalmOS/Src/init_golcd.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef INIT_GOLCD_H -#define INIT_GOLCD_H - -typedef struct { - Boolean active; - UInt16 refNum; - RectangleType bounds; - RGBColorType ink; - UInt32 timeout; -} GoLCDType; - -extern MemHandle gGoLcdH; - -Err GoLCDInit(MemHandle *goLcdH); -Err GoLCDRelease(MemHandle goLcdH); -void GoLCDSetInk(MemHandle goLcdH, RGBColorType *inkP); -void GoLCDSetBounds(MemHandle goLcdH, RectangleType *boundsP); -void GoLCDActivate(MemHandle goLcdH, Boolean active); -Boolean GoLCDToggle(MemHandle goLcdH); -Boolean GoLCDPointInBounds(MemHandle goLcdH, Coord x, Coord y); - -#endif diff --git a/backends/platform/PalmOS/Src/init_mathlib.cpp b/backends/platform/PalmOS/Src/init_mathlib.cpp deleted file mode 100644 index 1ea39c3e0a..0000000000 --- a/backends/platform/PalmOS/Src/init_mathlib.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include <PalmOS.h> - -#include "globals.h" -#include "init_mathlib.h" -#include "mathlib.h" - -Err MathlibInit() { - Err e; - - if ((e = SysLibFind(MathLibName, &MathLibRef))) - if (e == sysErrLibNotFound) // couldn't find lib - e = SysLibLoad(LibType, MathLibCreator, &MathLibRef); - - if (e) return sysErrLibNotFound; - - e = MathLibOpen(MathLibRef, MathLibVersion); - return e; -} - -void MathlibRelease() { - UInt16 useCount; - - if (MathLibRef != sysInvalidRefNum) { - MathLibClose(MathLibRef, &useCount); - - if (!useCount) - SysLibRemove(MathLibRef); - } -} diff --git a/backends/platform/PalmOS/Src/init_mathlib.h b/backends/platform/PalmOS/Src/init_mathlib.h deleted file mode 100644 index 1901e1330d..0000000000 --- a/backends/platform/PalmOS/Src/init_mathlib.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef INIT_MATHLIB_H -#define INIT_MATHLIB_H - -Err MathlibInit(); -void MathlibRelease(); - -#endif diff --git a/backends/platform/PalmOS/Src/init_pa1lib.cpp b/backends/platform/PalmOS/Src/init_pa1lib.cpp deleted file mode 100644 index d5b0340cae..0000000000 --- a/backends/platform/PalmOS/Src/init_pa1lib.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include <PalmOS.h> -#include <Sonyclie.h> - -#include "pa1lib.h" -#include "init_pa1lib.h" - -void *sndStateOnFuncP = NULL; -void *sndStateOffFuncP = NULL; - -#define SndStateOn(a,b,c) if (sndStateOnFuncP)((sndStateOnType)(sndStateOnFuncP))(a, b, c); -#define SndStateOff(a) if (sndStateOffFuncP)((sndStateOffType)(sndStateOffFuncP))(a); - -void Pa1libInit(UInt16 vol) { - Pa1Lib_Open(); - - // Doesn't work on T4xx and T6xx series ? - FtrGet(sonySysFtrCreatorSystem, sonySysFtrNumSystemAOutSndStateOnHandlerP, (UInt32*) &sndStateOnFuncP); - FtrGet(sonySysFtrCreatorSystem, sonySysFtrNumSystemAOutSndStateOffHandlerP, (UInt32*) &sndStateOffFuncP); - - SndStateOn(aOutSndKindSp, vol, vol); - SndStateOn(aOutSndKindHp, vol, vol); - - Pa1Lib_devHpVolume(vol, vol); - Pa1Lib_devSpVolume(vol); -} - -void Pa1libRelease() { - SndStateOff(aOutSndKindSp); - SndStateOff(aOutSndKindHp); - - Pa1Lib_Close(); -} diff --git a/backends/platform/PalmOS/Src/init_pa1lib.h b/backends/platform/PalmOS/Src/init_pa1lib.h deleted file mode 100644 index d5be11d278..0000000000 --- a/backends/platform/PalmOS/Src/init_pa1lib.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef INIT_PA1LIB_H -#define INIT_PA1LIB_H - -// need to move this on a .h file -#define sonySysFileCSystem 'SsYs' /* Sony overall System */ -#define sonySysFtrCreatorSystem sonySysFileCSystem - -#define sonySysFtrNumSystemBase 10000 -#define sonySysFtrNumSystemAOutSndStateOnHandlerP (sonySysFtrNumSystemBase + 4) -#define sonySysFtrNumSystemAOutSndStateOffHandlerP (sonySysFtrNumSystemBase + 5) - -typedef void (*sndStateOnType) (UInt8 /* kind */, UInt8 /* L volume 0-31 */, UInt8 /* R volume 0-31 */); -typedef void (*sndStateOffType) (UInt8 /* kind */); - -/* kind */ -#define aOutSndKindSp (0) /* Speaker volume */ -#define aOutSndKindHp (2) /* HeadPhone volume */ - -void Pa1libInit(UInt16 vol); -void Pa1libRelease(); - -#endif diff --git a/backends/platform/PalmOS/Src/init_palmos.cpp b/backends/platform/PalmOS/Src/init_palmos.cpp deleted file mode 100644 index 3a72382362..0000000000 --- a/backends/platform/PalmOS/Src/init_palmos.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> - -#include "globals.h" -#include "init_palmos.h" - -static UInt16 autoOffDelay; - -void PalmInit(UInt8 init) { - // set screen depth - UInt32 depth = 8; - WinScreenMode(winScreenModeSet, NULL, NULL, &depth, NULL); - - if (init & INIT_AUTOOFF) { - autoOffDelay = SysSetAutoOffTime(0); - EvtResetAutoOffTimer(); - } - -} - -void PalmRelease(UInt8 init) { - if (init & INIT_AUTOOFF) { - SysSetAutoOffTime(autoOffDelay); - EvtResetAutoOffTimer(); - } -} - -Err PalmHRInit(UInt32 depth) { - Err e; - UInt32 width = 320; - UInt32 height = 320; - Boolean color = true; - - e = WinScreenMode (winScreenModeSet, &width, &height, &depth, &color); - - if (!e) { - UInt32 attr; - WinScreenGetAttribute(winScreenDensity, &attr); - e = (attr != kDensityDouble); - } - - return e; -} - -void PalmHRRelease() { - // should i do something here ? -} - -UInt8 PalmScreenSize(Coord *stdw, Coord *stdh, Coord *fullw, Coord *fullh) { - UInt32 ftr; - UInt8 mode = 0; - - Coord sw = 160; - Coord sh = 160; - - // Hi-Density present ? - if (!FtrGet(sysFtrCreator, sysFtrNumWinVersion, &ftr)) { - if (ftr >= 4) { - sw = 320; - sh = 320; - } - } - - Coord fw = sw; - Coord fh = sh; - - // if feature set, not set on Garmin iQue3600 ??? - if (!(FtrGet(sysFtrCreator, sysFtrNumInputAreaFlags, &ftr))) { - if (ftr & grfFtrInputAreaFlagCollapsible) { - UInt16 curOrientation = SysGetOrientation(); - - if (curOrientation == sysOrientationLandscape || - curOrientation == sysOrientationReverseLandscape - ) - mode = PALM_LANDSCAPE; - else - mode = PALM_PORTRAIT; - - PINSetInputTriggerState(pinInputTriggerEnabled); - PINSetInputAreaState(pinInputAreaClosed); - StatHide(); - - WinGetDisplayExtent(&fw, &fh); - fw *= 2; - fh *= 2; - - StatShow(); - PINSetInputAreaState(pinInputAreaOpen); - PINSetInputTriggerState(pinInputTriggerDisabled); - } - } - - if (stdw) *stdw = sw; - if (stdh) *stdh = sh; - if (fullw) *fullw = fw; - if (fullh) *fullh = fh; - - return mode; -} - -void PalmGetMemory(UInt32* storageMemoryP, UInt32* dynamicMemoryP, UInt32 *storageFreeP, UInt32 *dynamicFreeP) { - UInt32 free, max; - - Int16 i; - Int16 nCards; - UInt16 cardNo; - UInt16 heapID; - - UInt32 storageMemory = 0; - UInt32 dynamicMemory = 0; - UInt32 storageFree = 0; - UInt32 dynamicFree = 0; - - // Iterate through each card to support devices with multiple cards. - nCards = MemNumCards(); - - for (cardNo = 0; cardNo < nCards; cardNo++) { - // Iterate through the RAM heaps on a card (excludes ROM). - for (i=0; i< MemNumRAMHeaps(cardNo); i++) { - // Obtain the ID of the heap. - heapID = MemHeapID(cardNo, i); - // Calculate the total memory and free memory of the heap. - MemHeapFreeBytes(heapID, &free, &max); - - // If the heap is dynamic, increment the dynamic memory total. - if (MemHeapDynamic(heapID)) { - dynamicMemory += MemHeapSize(heapID); - dynamicFree += free; - - // The heap is nondynamic (storage ?). - } else { - storageMemory += MemHeapSize(heapID); - storageFree += free; - } - } - } - // Reduce the stats to KB. Round the results. - dynamicMemory = dynamicMemory / 1024L; - storageMemory = storageMemory / 1024L; - - dynamicFree = dynamicFree / 1024L; - storageFree = storageFree / 1024L; - - if (dynamicMemoryP) *dynamicMemoryP = dynamicMemory; - if (storageMemoryP) *storageMemoryP = storageMemory; - if (dynamicFreeP) *dynamicFreeP = dynamicFree; - if (storageFreeP) *storageFreeP = storageFree; -} diff --git a/backends/platform/PalmOS/Src/init_palmos.h b/backends/platform/PalmOS/Src/init_palmos.h deleted file mode 100644 index d4691dd15b..0000000000 --- a/backends/platform/PalmOS/Src/init_palmos.h +++ /dev/null @@ -1,42 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef INIT_PALMOS_H -#define INIT_PALMOS_H - -#define PALM_PORTRAIT 1 -#define PALM_LANDSCAPE 2 - -void PalmInit(UInt8 init); -void PalmRelease(UInt8 init); - -Err PalmHRInit(UInt32 depth); -void PalmHRRelease(); - - -UInt8 PalmScreenSize(Coord *stdw, Coord *stdh, Coord *fullw, Coord *fullh); -void PalmGetMemory(UInt32* storageMemoryP, UInt32* dynamicMemoryP, UInt32 *storageFreeP, UInt32 *dynamicFreeP); - -#endif diff --git a/backends/platform/PalmOS/Src/init_sony.cpp b/backends/platform/PalmOS/Src/init_sony.cpp deleted file mode 100644 index f6728d08b3..0000000000 --- a/backends/platform/PalmOS/Src/init_sony.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> -#include <SonyClie.h> -#include "init_sony.h" - -UInt16 SilkInit(UInt32 *retVersion) { - SonySysFtrSysInfoP sonySysFtrSysInfoP; - UInt32 version; - UInt16 slkRefNum; - Err e; - - // Sony HiRes+ - if (!(e = FtrGet(sonySysFtrCreator, sonySysFtrNumSysInfoP, (UInt32*)&sonySysFtrSysInfoP))) { - if (sonySysFtrSysInfoP->libr & sonySysFtrSysInfoLibrSilk) { - - if ((e = SysLibFind(sonySysLibNameSilk, &slkRefNum))) - if (e == sysErrLibNotFound) - e = SysLibLoad(sonySysFileTSilkLib, sonySysFileCSilkLib, &slkRefNum); - - if (!e) { - e = FtrGet(sonySysFtrCreator, sonySysFtrNumVskVersion, &version); - if (e) { - // v1 = NR - e = SilkLibOpen(slkRefNum); - if (!e) version = vskVersionNum1; - - } else { - // v2 = NX/NZ - // v3 = UX... - e = VskOpen(slkRefNum); - } - } - } else - e = sysErrLibNotFound; - } - - if (e) { - version = 0; - slkRefNum = sysInvalidRefNum; - } - - *retVersion = version; - return slkRefNum; -} - -void SilkRelease(UInt16 slkRefNum) { - if (slkRefNum != sysInvalidRefNum) - SilkLibClose(slkRefNum); -} - -UInt16 SonyHRInit(UInt32 depth) { - SonySysFtrSysInfoP sonySysFtrSysInfoP; - Err e; - UInt16 HRrefNum; - - // test if sonyHR is present - if (!(e = FtrGet(sonySysFtrCreator, sonySysFtrNumSysInfoP, (UInt32*)&sonySysFtrSysInfoP))) { - if (sonySysFtrSysInfoP->libr & sonySysFtrSysInfoLibrHR) { // HR available - - if ((e = SysLibFind(sonySysLibNameHR, &HRrefNum))) - if (e == sysErrLibNotFound) // can't find lib - e = SysLibLoad( 'libr', sonySysFileCHRLib, &HRrefNum); - - // Now we can use HR lib. Executes Open library. - if (!e) e = HROpen(HRrefNum); - } - } - - if (e) HRrefNum = sysInvalidRefNum; - - if (HRrefNum != sysInvalidRefNum) { - UInt32 width = hrWidth; - UInt32 height = hrHeight; - Boolean color = true; - - e = HRWinScreenMode(HRrefNum, winScreenModeSet, &width, &height, &depth, &color); - // error ? release and return an invalid reference number - if (e) { - SonyHRRelease(HRrefNum); - HRrefNum = sysInvalidRefNum; - } - } - - return HRrefNum; -} - -void SonyHRRelease(UInt16 HRrefNum) { - if (HRrefNum != sysInvalidRefNum) { - HRClose(HRrefNum); - //SysLibRemove(HRrefNum); // never call this !! - } -} - -UInt8 SonyScreenSize(UInt16 HRrefNum, Coord *stdw, Coord *stdh, Coord *fullw, Coord *fullh) { - UInt32 version; - UInt16 slkRefNum; - UInt8 mode = 0; - - Coord sw = 160; - Coord sh = 160; - Coord fw = sw; - Coord fh = sh; - - if (HRrefNum != sysInvalidRefNum) { - sw = hrWidth; - sh = hrHeight; - fw = sw; - fh = sh; - - slkRefNum = SilkInit(&version); - - if (slkRefNum != sysInvalidRefNum) { - if (version == vskVersionNum1) { - SilkLibEnableResize(slkRefNum); - SilkLibResizeDispWin(slkRefNum, silkResizeMax); - HRWinGetWindowExtent(HRrefNum, &fw, &fh); - SilkLibResizeDispWin(slkRefNum, silkResizeNormal); - SilkLibDisableResize(slkRefNum); - mode = SONY_PORTRAIT; - - } else { - VskSetState(slkRefNum, vskStateEnable, (version == vskVersionNum2 ? vskResizeVertically : vskResizeHorizontally)); - VskSetState(slkRefNum, vskStateResize, vskResizeNone); - HRWinGetWindowExtent(HRrefNum, &fw, &fh); - VskSetState(slkRefNum, vskStateResize, vskResizeMax); - VskSetState(slkRefNum, vskStateEnable, vskResizeDisable); - mode = (version == vskVersionNum3 ? SONY_LANDSCAPE : SONY_PORTRAIT); - } - SilkRelease(slkRefNum); - } - } - - *stdw = sw; - *stdh = sh; - *fullw = fw; - *fullh = fh; - - return mode; -} diff --git a/backends/platform/PalmOS/Src/init_stuffs.cpp b/backends/platform/PalmOS/Src/init_stuffs.cpp deleted file mode 100644 index 51bfe755eb..0000000000 --- a/backends/platform/PalmOS/Src/init_stuffs.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include <PalmOS.h> - -#ifndef DISABLE_SONY -#include <SonyClie.h> -#endif - -#include <PalmNavigator.h> -#include <HsExtCommon.h> -#include <HsNavCommon.h> -#include <PalmGoLCD.h> - -#include "globals.h" // for OPTIONS_DEF() -#include "init_stuffs.h" -#include "stuffs.h" - -#ifndef DISABLE_TAPWAVE -#define __TWKEYS_H__ // bad hack -#include "tapwave.h" -#endif - -#ifndef DISABLE_PA1LIB -#include "Pa1Lib.h" -#endif - -#ifndef DISABLE_LIGHTSPEED -#include "lightspeed_public.h" -#endif - -// TODO : check the depth to set correct value -// works only for 8bit for now -UInt32 StuffsGetPitch(Coord fullw) { - UInt32 pitch = 0; - - if (OPTIONS_TST(kOptModeHiDensity)) { - WinScreenGetAttribute(winScreenRowBytes, &pitch); - - // FIXME : hack for TT3 simulator (and real ?) return 28 on landscape mode - if (pitch < fullw) - pitch = fullw; - - } else { - pitch = fullw; - } - - return pitch; -} - -void *StuffsForceVG() { - // create an empty form to force the VG to be shown - FormType *frmP = FrmNewForm(4567, NULL, 0,0,0,0, false, 0, 0, 0); - FrmDrawForm(frmP); - return frmP; -} - -void StuffsReleaseVG(void *vg) { - FrmDeleteForm((FormPtr)vg); -} - -void StuffsGetFeatures() { - UInt32 ulProcessorType, manufacturer, version, depth; - Boolean color; - -#ifndef DISABLE_TAPWAVE - // Tapwave Zodiac libs ? - if (!FtrGet(sysFileCSystem, sysFtrNumOEMCompanyID, &manufacturer)) - if (manufacturer == twCreatorID) { - OPTIONS_SET(kOptDeviceZodiac); - OPTIONS_SET(kOpt5WayNavigatorV2); - } -#endif - - // Hi-Density present ? - if (!FtrGet(sysFtrCreator, sysFtrNumWinVersion, &version)) - if (version >= 4) - OPTIONS_SET(kOptModeHiDensity); - - // OS5 ? - if (!FtrGet(sysFtrCreator, sysFtrNumROMVersion, &version)) - if (version >= kOS5Version) - OPTIONS_SET(kOptDeviceOS5); - - // ARM ? - if (!FtrGet(sysFileCSystem, sysFtrNumProcessorID, &ulProcessorType)) - if (sysFtrNumProcessorIsARM(ulProcessorType)) - OPTIONS_SET(kOptDeviceARM); - else if (ulProcessorType == sysFtrNumProcessorx86) - OPTIONS_SET(kOptDeviceProcX86); - - // 5Way Navigator - if (!FtrGet(hsFtrCreator, hsFtrIDNavigationSupported, &version)) { - if (version >= 2) - OPTIONS_SET(kOpt5WayNavigatorV2); - - } else if (!FtrGet(sysFtrCreator, sysFtrNumFiveWayNavVersion, &version)) { - if (version >= 2) - OPTIONS_SET(kOpt5WayNavigatorV2); - else - OPTIONS_SET(kOpt5WayNavigatorV1); - - } else if (!FtrGet(navFtrCreator, navFtrVersion, &version)) { - if (version >= 2) - OPTIONS_SET(kOpt5WayNavigatorV2); - else - OPTIONS_SET(kOpt5WayNavigatorV1); - } - - // Palm Sound API ? - if (!FtrGet(sysFileCSoundMgr, sndFtrIDVersion, &version)) - if (version >= 1) - OPTIONS_SET(kOptPalmSoundAPI); - -#ifndef DISABLE_PA1LIB - // Sony Pa1 Sound API - if (Pa1Lib_Open()) { - OPTIONS_SET(kOptSonyPa1LibAPI); - Pa1Lib_Close(); - } -#endif - - // GoLCD - if (!FtrGet(goLcdLibCreator, goLcdLibFtrNum, &version)) - OPTIONS_SET(kOptGoLcdAPI); - -#ifndef DISABLE_LIGHTSPEED - // Lightspeed - if (LS_Installed()) - OPTIONS_SET(kOptLightspeedAPI); -#endif - - // check for 16bit mode - if (!WinScreenMode(winScreenModeGetSupportedDepths, NULL, NULL, &depth, &color)) - OPTIONS_SET(((depth & 0x8000) ? kOptMode16Bit : kOptNone)); - -} diff --git a/backends/platform/PalmOS/Src/init_stuffs.h b/backends/platform/PalmOS/Src/init_stuffs.h deleted file mode 100644 index 124510eeac..0000000000 --- a/backends/platform/PalmOS/Src/init_stuffs.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef INIT_STUFFS_H -#define INIT_STUFFS_H - -#define kOS5Version sysMakeROMVersion(5,0,0,sysROMStageRelease,0) - -void StuffsGetFeatures(); -UInt32 StuffsGetPitch(Coord fullw); -void *StuffsForceVG(); -void StuffsReleaseVG(void *vg); - -#endif diff --git a/backends/platform/PalmOS/Src/launcher/app.cpp b/backends/platform/PalmOS/Src/launcher/app.cpp deleted file mode 100644 index 9bb1c1479b..0000000000 --- a/backends/platform/PalmOS/Src/launcher/app.cpp +++ /dev/null @@ -1,360 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> -#include <SonyClie.h> -#include <SysGlue.h> - -#include "StarterRsc.h" -#include "palmdefs.h" -#include "start.h" -#include "globals.h" -#include "rumble.h" - -#include "mathlib.h" -#include "formCards.h" -#include "games.h" - -#include "modules.h" -#include "init_mathlib.h" -#include "init_sony.h" -#include "init_palmos.h" -#include "init_stuffs.h" - -/*********************************************************************** - * - * FUNCTION: AppStart - * - * DESCRIPTION: Get the current application's preferences. - * - * PARAMETERS: nothing - * - * RETURNED: Err value 0 if nothing went wrong - * - * REVISION HISTORY: - * - * - ***********************************************************************/ -static Err AppStartCheckHRmode() -{ - Err e = errNone; - UInt32 depth = (OPTIONS_TST(kOptMode16Bit) && OPTIONS_TST(kOptDeviceOS5)) ? 16 : 8; - - // try to init Sony HR mode then Palm HR mode - gVars->HRrefNum = SonyHRInit(depth); - - if (gVars->HRrefNum == sysInvalidRefNum) { - if (e = PalmHRInit(depth)) - FrmCustomAlert(FrmErrorAlert,"Your device doesn't seem to support Hi-Res or 256color mode.",0,0); - } else { - OPTIONS_SET(kOptDeviceClie); - } - - return e; -} - -static void AppStopHRMode() { - if (gVars->HRrefNum != sysInvalidRefNum) - SonyHRRelease(gVars->HRrefNum); - else - PalmHRRelease(); -} - -static Err AppStartCheckNotify() { - UInt32 romVersion; - Err err; - - err = FtrGet(sysFtrCreator, sysFtrNumNotifyMgrVersion, &romVersion); - if (!err) { - UInt16 cardNo; - LocalID dbID; - - err = SysCurAppDatabase(&cardNo, &dbID); - if (!err) { - SysNotifyRegister(cardNo, dbID, sysNotifyVolumeMountedEvent, NULL, sysNotifyNormalPriority, NULL); - SysNotifyRegister(cardNo, dbID, sysNotifyVolumeUnmountedEvent, NULL, sysNotifyNormalPriority, NULL); - SysNotifyRegister(cardNo, dbID, sonySysNotifyMsaEnforceOpenEvent, NULL, sysNotifyNormalPriority, NULL); - SysNotifyRegister(cardNo, dbID, sysNotifyDisplayResizedEvent, NULL, sysNotifyNormalPriority, NULL); - } - } - - return err; -} - -static Err AppStartLoadSkin() { - Err err = errNone; - - // if skin defined, check if the db still exists - if (gPrefs->skin.dbID) { - UInt32 type, creator; - - // check if the DB still exists - DmSearchStateType state; - UInt16 cardNo; - LocalID dbID; - Boolean found = false; - err = DmGetNextDatabaseByTypeCreator(true, &state, 'skin', appFileCreator, false, &cardNo, &dbID); - while (!err && dbID && !found) { - found = (cardNo == gPrefs->skin.cardNo && dbID == gPrefs->skin.dbID); - err = DmGetNextDatabaseByTypeCreator(false, &state, 'skin', appFileCreator, false, &cardNo, &dbID); - } - - if (found) { - // remember to check version for next revision of the skin - err = DmDatabaseInfo (gPrefs->skin.cardNo, gPrefs->skin.dbID, gPrefs->skin.nameP, 0, 0, 0, 0, 0, 0, 0,0, &type, &creator); - if (!err) - if (type != 'skin' || creator != appFileCreator) - err = dmErrInvalidParam; - } - - if (!found || err) - MemSet(&(gPrefs->skin),sizeof(SkinInfoType),0); - } - - // No skin ? try to get the first one - if (!gPrefs->skin.dbID) { - DmSearchStateType stateInfo; - - err = DmGetNextDatabaseByTypeCreator(true, &stateInfo, 'skin', appFileCreator, false, &gPrefs->skin.cardNo, &gPrefs->skin.dbID); - if (!err) - err = DmDatabaseInfo (gPrefs->skin.cardNo, gPrefs->skin.dbID, gPrefs->skin.nameP, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - } - - return err; -} - -static Err AppStartCheckMathLib() { - Err e = MathlibInit(); - - switch (e) { - case errNone: - break; - case sysErrLibNotFound: - FrmCustomAlert(FrmErrorAlert,"Can't find MathLib !",0,0); - break; - default: - FrmCustomAlert(FrmErrorAlert,"Can't open MathLib !",0,0); - break; - } - - return e; -} - -static void AppStopMathLib() { - MathlibRelease(); -} - -static void AppStartCheckScreenSize() { - Coord sw, sh, fw, fh; - UInt8 mode; - - OPTIONS_RST(kOptCollapsible); - OPTIONS_RST(kOptModeWide); - OPTIONS_RST(kOptModeLandscape); - OPTIONS_RST(kOptModeRotatable); - - // we are on a sony device - if (OPTIONS_TST(kOptDeviceClie)) { - mode = SonyScreenSize(gVars->HRrefNum, &sw, &sh, &fw, &fh); - if (mode) { - OPTIONS_SET(kOptModeWide); - OPTIONS_SET((mode == SONY_LANDSCAPE) ? kOptModeLandscape : kOptNone); - } - } else { - mode = PalmScreenSize(&sw, &sh, &fw, &fh); - if (mode) { - OPTIONS_SET(kOptCollapsible); - OPTIONS_SET(kOptModeWide); - OPTIONS_SET((mode == PALM_LANDSCAPE) ? kOptModeLandscape : kOptNone); - // TODO: doesn't work with Sony - OPTIONS_SET(SysGlueTrapExists(pinSysSetOrientation) ? kOptModeRotatable :kOptNone); - } - } - - gVars->screenWidth = sw; - gVars->screenHeight = sh; - - gVars->screenFullWidth = fw; - gVars->screenFullHeight = fh; -} - -#define max(id,value) gVars->memory[id] = (gVars->memory[id] < value ? value : gVars->memory[id]) -#define min(id,value) gVars->memory[id] = (gVars->memory[id] > value ? value : gVars->memory[id]) -#define threshold 700 - -static void AppStartSetMemory() { - UInt32 mem, def; - PalmGetMemory(0,0,0,&mem); - def = (mem > threshold) ? (mem - threshold) * 1024 : 0; - gVars->startupMemory = mem; -} - -#undef threshold -#undef min -#undef max - -Err AppStart(void) { - UInt16 dataSize, checkSize = 0; - Err error; - -#ifndef _DEBUG_ENGINE - // delete old databases - ModDelete(); -#endif - - // allocate global variables space - dataSize = sizeof(GlobalsDataType); - gVars = (GlobalsDataType *)MemPtrNew(dataSize); - MemSet(gVars, dataSize, 0); - - gVars->indicator.on = 255; - gVars->indicator.off = 0; - gVars->HRrefNum = sysInvalidRefNum; - gVars->VFS.volRefNum = vfsInvalidVolRef; - gVars->slkRefNum = sysInvalidRefNum; - gVars->options = kOptNone; - - // set memory required by the differents engines - AppStartSetMemory(); - StuffsGetFeatures(); - - // allocate prefs space - dataSize = sizeof(GlobalsPreferenceType); - gPrefs = (GlobalsPreferenceType *)MemPtrNew(dataSize); - MemSet(gPrefs, dataSize, 0); - - // Read the saved preferences / saved-state information. - if (PrefGetAppPreferences(appFileCreator, appPrefID, NULL, &checkSize, true) == noPreferenceFound || checkSize != dataSize) { - // reset all elements - MemSet(gPrefs, dataSize, 0); - - gPrefs->card.volRefNum = vfsInvalidVolRef; - gPrefs->card.cacheSize = 4096; - gPrefs->card.useCache = true; - gPrefs->card.showLED = true; - gPrefs->card.autoDetect = true; - - gPrefs->autoOff = true; - gPrefs->vibrator = RumbleExists(); - gPrefs->debug = false; - gPrefs->exitLauncher = true; - gPrefs->stdPalette = OPTIONS_TST(kOptDeviceOS5); - gPrefs->stylusClick = true; - - } else { - PrefGetAppPreferences(appFileCreator, appPrefID, gPrefs, &dataSize, true); - } - - if (!OPTIONS_TST(kOptDeviceARM)) { - error = AppStartCheckMathLib(); - if (error) return (error); - } - - error = AppStartCheckHRmode(); - if (error) return (error); - - bDirectMode = (AppStartLoadSkin() != errNone); - - // if volref previously defined, check if it's a valid one - if (gPrefs->card.volRefNum != vfsInvalidVolRef) { - VolumeInfoType volInfo; - Err err = VFSVolumeInfo(gPrefs->card.volRefNum, &volInfo); - if (err) - gPrefs->card.volRefNum = parseCards(); - } - else - gPrefs->card.volRefNum = parseCards(); - if (gPrefs->card.volRefNum != vfsInvalidVolRef) - CardSlotCreateDirs(); - - // open games database - error = GamOpenDatabase(); - if (error) return (error); - GamImportDatabase(); - - AppStartCheckScreenSize(); - AppStartCheckNotify(); // not fatal error if not avalaible - - return error; -} - -/*********************************************************************** - * - * FUNCTION: AppStop - * - * DESCRIPTION: Save the current state of the application. - * - * PARAMETERS: nothing - * - * RETURNED: nothing - * - * REVISION HISTORY: - * - * - ***********************************************************************/ -static Err AppStopCheckNotify() -{ - UInt32 romVersion; - Err err; - - err = FtrGet(sysFtrCreator, sysFtrNumNotifyMgrVersion, &romVersion); - if (!err) { - UInt16 cardNo; - LocalID dbID; - - err = SysCurAppDatabase(&cardNo, &dbID); - if (!err) { - SysNotifyUnregister(cardNo, dbID, sysNotifyVolumeUnmountedEvent, sysNotifyNormalPriority); - SysNotifyUnregister(cardNo, dbID, sysNotifyVolumeMountedEvent, sysNotifyNormalPriority); - // sonySysNotifyMsaEnforceOpenEvent - SysNotifyUnregister(cardNo, dbID, sysNotifyDisplayResizedEvent, sysNotifyNormalPriority); - } - } - - return err; -} - -void AppStop(void) { - // Close all the open forms. - FrmCloseAllForms(); - WinEraseWindow(); - WinPalette(winPaletteSetToDefault, 0, 256, NULL); - - // Close and move Game list database - GamCloseDatabase(false); - - // Write the saved preferences / saved-state information. This data - // will saved during a HotSync backup. - SavePrefs(); - - // stop all - AppStopCheckNotify(); - if (!OPTIONS_TST(kOptDeviceARM)) - AppStopMathLib(); - AppStopHRMode(); - - if (!bLaunched) - MemPtrFree(gVars); -} diff --git a/backends/platform/PalmOS/Src/launcher/forms/formCards.cpp b/backends/platform/PalmOS/Src/launcher/forms/formCards.cpp deleted file mode 100644 index eb4654ed10..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formCards.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> -#include <VFSMgr.h> -#include <PmPalmOSNVFS.h> - -#include "start.h" -#include "formTabs.h" -#include "forms.h" -#include "globals.h" - -typedef struct { - UInt16 volRefNum; - Char nameP[expCardInfoStringMaxLen+1]; - -} CardInfoType; - -static TabType *myTabP; -static UInt16 lastTab = 0; - -static void CardSlotFormExit(Boolean bSave); - -static void CardSlotFreeList() { - MemHandle cards = NULL; - MemHandle items = NULL; - - if (itemsText && itemsList) { - cards = MemPtrRecoverHandle(itemsList); - items = MemPtrRecoverHandle(itemsText); - - itemsText = NULL; - itemsList = NULL; - } - itemsType = ITEM_TYPE_UNKNOWN; - - if (items && cards) { - MemHandleUnlock(items); - MemHandleUnlock(cards); - MemHandleFree(items); - MemHandleFree(cards); - } -} - -static UInt16 CardSlotFillList(Boolean getRefNum = false) { - Err err; - UInt16 index; - UInt16 volRefNum; - UInt32 volIterator = vfsIteratorStart|vfsIncludePrivateVolumes; - UInt8 counter = 0; - UInt32 other = 1; - - MemHandle items = NULL; - MemHandle cards = NULL; - CardInfoType *cardsInfo; - - // retreive card infos - while (volIterator != vfsIteratorStop) { - err = VFSVolumeEnumerate(&volRefNum, &volIterator); - - if (!err) { - Char labelP[expCardInfoStringMaxLen+1]; - MemSet(labelP, expCardInfoStringMaxLen+1, 0); - err = VFSVolumeGetLabel(volRefNum, labelP, expCardInfoStringMaxLen+1); - - if (err || StrLen(labelP) == 0) { // if no label try to retreive card type - VolumeInfoType volInfo; - err = VFSVolumeInfo(volRefNum, &volInfo); - - if (!err) { - ExpCardInfoType info; - err = ExpCardInfo(volInfo.slotRefNum, &info); - StrCopy(labelP, info.deviceClassStr); - } - - if (err) // if err default name - StrPrintF(labelP,"Other Card %ld", other++); - } - - if (!cards) - cards = MemHandleNew(sizeof(CardInfoType)); - else - MemHandleResize(cards, MemHandleSize(cards) + sizeof(CardInfoType)); - - cardsInfo = (CardInfoType *)MemHandleLock(cards); - cardsInfo[counter].volRefNum = volRefNum; - StrCopy(cardsInfo[counter].nameP, labelP); - MemHandleUnlock(cards); - counter++; - } - } - - if (counter > 0) { - // set the list items ... - if (!getRefNum) { - for (index = 0; index < counter; index++) { - if (!items) - items = MemHandleNew(sizeof(Char *)); - else - MemHandleResize(items, MemHandleSize(items) + sizeof(Char *)); - - itemsText = (Char **)MemHandleLock(items); - itemsText[index] = cardsInfo[index].nameP; - MemHandleUnlock(items); - } - - // save globals - itemsText = (Char **)MemHandleLock(items); - itemsList = (void *)MemHandleLock(cards); - itemsType = ITEM_TYPE_CARD; - - // ... or just return a default volRefNum - } else { - UInt16 volRefNum; - - cardsInfo = (CardInfoType *)MemHandleLock(cards); - volRefNum = cardsInfo[0].volRefNum; // return the first volref - MemHandleUnlock(cards); - MemHandleFree(cards); - - return volRefNum; - } - - // no card found ? free old list in any or return invalid volref - } else { - if (!getRefNum) - CardSlotFreeList(); - else - return vfsInvalidVolRef; - } - - return counter; -} - -static void ConfigTabInit(Boolean update = false) { - ListPtr listP; - - UInt16 index; - Int16 selected = -1; - - UInt16 counter = CardSlotFillList(); - listP = (ListType *)GetObjectPtr(TabCardConfigSlotList); - - // itemsText can be NULL if counter = 0 - LstSetListChoices (listP, itemsText, counter); - if (counter > 0) { - CardInfoType *cardsInfo = (CardInfoType *)itemsList; - - for (index = 0; index < counter; index++) { - if (cardsInfo[index].volRefNum == gPrefs->card.volRefNum) { - selected = index; - break; - } - } - - LstSetSelection(listP, selected); - } - - if (!update) { - FieldType *fld1P; - Char *cacheP; - MemHandle cacheH; - - fld1P = (FieldType *)GetObjectPtr(TabCardConfigCacheSizeField); - cacheH = MemHandleNew(FldGetMaxChars(fld1P)+1); - cacheP = (Char *)MemHandleLock(cacheH); - StrIToA(cacheP, gPrefs->card.cacheSize / 1024); - MemHandleUnlock(cacheH); - - FldSetTextHandle(fld1P, cacheH); - CtlSetValue((ControlType *)GetObjectPtr(TabCardConfigCacheCheckbox), gPrefs->card.useCache); - CtlSetValue((ControlType *)GetObjectPtr(TabCardConfigLedCheckbox), gPrefs->card.showLED); - CtlSetValue((ControlType *)GetObjectPtr(TabCardConfigDetectCheckbox), gPrefs->card.autoDetect); - // update ? redraw the list - } else { - WinScreenLock(winLockCopy); - LstDrawList(listP); - WinScreenUnlock(); - } -} - -static UInt16 ConfigTabSave() { - ControlType *cckP[3]; - FieldType *fld1P; - ListPtr listP; - FormPtr frmP; - UInt16 updateCode = frmRedrawUpdateMS; - - cckP[0] = (ControlType *)GetObjectPtr(TabCardConfigCacheCheckbox); - cckP[1] = (ControlType *)GetObjectPtr(TabCardConfigLedCheckbox); - cckP[2] = (ControlType *)GetObjectPtr(TabCardConfigDetectCheckbox); - - gPrefs->card.useCache = CtlGetValue(cckP[0]); - gPrefs->card.showLED = CtlGetValue(cckP[1]); - gPrefs->card.autoDetect = CtlGetValue(cckP[2]); - - fld1P = (FieldType *)GetObjectPtr(TabCardConfigCacheSizeField); - frmP = FrmGetActiveForm(); - if (FldGetTextLength(fld1P) == 0 && CtlGetValue(cckP[0]) == 1) { - TabSetActive(frmP, myTabP, 0); - FrmSetFocus(frmP, FrmGetObjectIndex(frmP, TabCardConfigCacheSizeField)); - FrmCustomAlert(FrmWarnAlert,"You must specified a cache size.",0,0); - return 0; - } - gPrefs->card.cacheSize = StrAToI(FldGetTextPtr(fld1P)) * 1024; - - Int16 selected; - CardInfoType *cardsInfo = (CardInfoType *)itemsList; - - listP = (ListType *)GetObjectPtr(TabCardConfigSlotList); - selected = LstGetSelection(listP); - if (selected == -1) { - gPrefs->card.volRefNum = vfsInvalidVolRef; - } else if (gPrefs->card.volRefNum != cardsInfo[selected].volRefNum) { - updateCode = frmRedrawUpdateMSImport; - gPrefs->card.volRefNum = cardsInfo[selected].volRefNum; - } - - CardSlotCreateDirs(); - CardSlotFreeList(); - - return updateCode; -} - -static void GameListTabInit() { - CtlSetValue((ControlType *)GetObjectPtr(TabCardGameListMoveCheckbox), gPrefs->card.moveDB); - CtlSetValue((ControlType *)GetObjectPtr(TabCardGameListDeleteCheckbox), gPrefs->card.deleteDB); - CtlSetValue((ControlType *)GetObjectPtr(TabCardGameListConfirmCheckbox), gPrefs->card.confirmMoveDB); -} - -static void GameListTabSave() { - ControlType *cckP[3]; - - cckP[0] = (ControlType *)GetObjectPtr(TabCardGameListMoveCheckbox); - cckP[1] = (ControlType *)GetObjectPtr(TabCardGameListDeleteCheckbox); - cckP[2] = (ControlType *)GetObjectPtr(TabCardGameListConfirmCheckbox); - - gPrefs->card.moveDB = CtlGetValue(cckP[0]); - gPrefs->card.deleteDB = CtlGetValue(cckP[1]); - gPrefs->card.confirmMoveDB = CtlGetValue(cckP[2]); -} - -static void GameListTabDraw() { - ControlType *cck1P; - FormPtr frmP = FrmGetActiveForm(); - - cck1P = (ControlType *)GetObjectPtr(TabCardGameListMoveCheckbox); - if (CtlGetValue(cck1P)) { - FrmShowObject(frmP, FrmGetObjectIndex (frmP, TabCardGameListDeleteCheckbox)); - FrmShowObject(frmP, FrmGetObjectIndex (frmP, TabCardGameListConfirmCheckbox)); - } else { - FrmHideObject(frmP, FrmGetObjectIndex (frmP, TabCardGameListDeleteCheckbox)); - FrmHideObject(frmP, FrmGetObjectIndex (frmP, TabCardGameListConfirmCheckbox)); - } -} - -static void CardSlotFormInit() { - TabType *tabP; - FormType *frmP = FrmGetActiveForm(); - - tabP = TabNewTabs(2); - TabAddContent(&frmP, tabP, "Cards", TabCardConfigForm); - TabAddContent(&frmP, tabP, "Game List", TabCardGameListForm, GameListTabDraw); - - ConfigTabInit(); - GameListTabInit(); - - FrmDrawForm(frmP); - TabSetActive(frmP, tabP, lastTab); - - myTabP = tabP; -} - -static void CardSlotFormSave() { - UInt16 updateCode; - updateCode = ConfigTabSave(); - if (!updateCode) return; - GameListTabSave(); - CardSlotCreateDirs(); - - TabDeleteTabs(myTabP); - FrmReturnToMain(updateCode); -} - -static void CardSlotFormCancel() { - CardSlotFreeList(); - TabDeleteTabs(myTabP); - FrmReturnToMain(); -} - -Boolean CardSlotFormHandleEvent(EventPtr eventP) { - FormPtr frmP = FrmGetActiveForm(); - Boolean handled = false; - - switch (eventP->eType) { - case frmOpenEvent: - CardSlotFormInit(); - handled = true; - break; - - case frmCloseEvent: - CardSlotFormCancel(); - handled = true; - break; - - case ctlSelectEvent: - switch (eventP->data.ctlSelect.controlID) - { - case (CardSlotForm + 1) : - case (CardSlotForm + 2) : - lastTab = (eventP->data.ctlSelect.controlID - CardSlotForm - 1); - TabSetActive(frmP, myTabP, lastTab); - break; - - case CardSlotOkButton: - CardSlotFormSave(); - break; - - case CardSlotCancelButton: - CardSlotFormCancel(); - break; - - case TabCardGameListMoveCheckbox: - GameListTabDraw(); - break; - } - handled = true; - break; - - default: - break; - } - - return handled; -} - -void CardSlotCreateDirs() { - if (gPrefs->card.volRefNum != vfsInvalidVolRef) { - VFSDirCreate(gPrefs->card.volRefNum, "/PALM"); - VFSDirCreate(gPrefs->card.volRefNum, "/PALM/Programs"); - VFSDirCreate(gPrefs->card.volRefNum, "/PALM/Programs/ScummVM"); - VFSDirCreate(gPrefs->card.volRefNum, "/PALM/Programs/ScummVM/Games"); - VFSDirCreate(gPrefs->card.volRefNum, "/PALM/Programs/ScummVM/Saved"); - VFSDirCreate(gPrefs->card.volRefNum, "/PALM/Programs/ScummVM/Audio"); - VFSDirCreate(gPrefs->card.volRefNum, "/PALM/Programs/ScummVM/Mods"); - VFSDirCreate(gPrefs->card.volRefNum, "/PALM/Programs/ScummVM/Themes"); - } -} - -void CardSlotFormUpdate() { - if (itemsType == ITEM_TYPE_CARD) { - CardSlotFreeList(); - ConfigTabInit(true); - } -} - -UInt16 parseCards() { - UInt16 volRefNum = CardSlotFillList(true); - CardSlotFreeList(); - return volRefNum; -} diff --git a/backends/platform/PalmOS/Src/launcher/forms/formCards.h b/backends/platform/PalmOS/Src/launcher/forms/formCards.h deleted file mode 100644 index 766c4793b9..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formCards.h +++ /dev/null @@ -1,33 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef __FORMCARDS_H__ -#define __FORMCARDS_H__ - -UInt16 parseCards(); -void CardSlotFormUpdate(); -void CardSlotCreateDirs(); - -#endif diff --git a/backends/platform/PalmOS/Src/launcher/forms/formEditGame.cpp b/backends/platform/PalmOS/Src/launcher/forms/formEditGame.cpp deleted file mode 100644 index 0540c12577..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formEditGame.cpp +++ /dev/null @@ -1,612 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> -#include <VFSMgr.h> -#include <FileBrowserLibCommon.h> -#include <FileBrowserLib68K.h> - -#include "formTabs.h" -#include "forms.h" - -#include "start.h" -#include "games.h" -#include "skin.h" - -#define errBadParam 0x1000 - -static TabType *myTabP; -static UInt16 lastTab = 0; - -UInt8 gFormEditMode; - -static void GameTabInit(GameInfoType *gameInfoP) { - FieldType *fld1P, *fld2P, *fld3P; - Char *nameP, *pathP, *gameP; - MemHandle nameH, pathH, gameH; - ListType *list1P; - - list1P = (ListType *)GetObjectPtr(TabGameInfoEngineList); - - itemsText = (Char **)MemPtrNew(ENGINE_COUNT * sizeof(Char *)); - for (int i = 0; i < ENGINE_COUNT; i++) - itemsText[i] = (Char *)engines[i].nameP; - LstSetListChoices(list1P, itemsText, ENGINE_COUNT); - - fld1P = (FieldType *)GetObjectPtr(TabGameInfoEntryNameField); - fld2P = (FieldType *)GetObjectPtr(TabGameInfoPathField); - fld3P = (FieldType *)GetObjectPtr(TabGameInfoGameField); - - nameH = MemHandleNew(FldGetMaxChars(fld1P)+1); - pathH = MemHandleNew(FldGetMaxChars(fld2P)+1); - gameH = MemHandleNew(FldGetMaxChars(fld3P)+1); - - nameP = (Char *)MemHandleLock(nameH); - pathP = (Char *)MemHandleLock(pathH); - gameP = (Char *)MemHandleLock(gameH); - - if (gameInfoP) { - LstSetSelection(list1P, gameInfoP->engine); - LstSetTopItem(list1P, gameInfoP->engine); - StrCopy(nameP, gameInfoP->nameP); - StrCopy(pathP, gameInfoP->pathP); - StrCopy(gameP, gameInfoP->gameP); - } else { - LstSetSelection(list1P, 0); - MemSet(nameP,MemHandleSize(nameH),0); - MemSet(pathP,MemHandleSize(pathH),0); - MemSet(gameP,MemHandleSize(gameH),0); - } - - CtlSetLabel((ControlType *)GetObjectPtr(TabGameInfoEnginePopTrigger), LstGetSelectionText(list1P, LstGetSelection(list1P))); - - MemHandleUnlock(nameH); - MemHandleUnlock(pathH); - MemHandleUnlock(gameH); - - FldSetTextHandle(fld1P, nameH); - FldSetTextHandle(fld2P, pathH); - FldSetTextHandle(fld3P, gameH); -} - -static Err GameTabSave(GameInfoType *gameInfoP) { - FieldType *fld1P, *fld2P, *fld3P; - ListType *list1P; - - FormType *frmP = FrmGetActiveForm(); - list1P = (ListType *)GetObjectPtr(TabGameInfoEngineList); - - fld1P = (FieldType *)GetObjectPtr(TabGameInfoEntryNameField); - fld2P = (FieldType *)GetObjectPtr(TabGameInfoPathField); - fld3P = (FieldType *)GetObjectPtr(TabGameInfoGameField); - - FldTrimText(fld1P); - FldTrimText(fld2P); - FldTrimText(fld3P); - - // test case - if (!gameInfoP) { - if (FldGetTextLength(fld1P) == 0) { - FrmCustomAlert(FrmWarnAlert,"You must specify an entry name.",0,0); - TabSetActive(frmP, myTabP, 0); - FrmSetFocus(frmP, FrmGetObjectIndex(frmP, TabGameInfoEntryNameField)); - return errBadParam; - - } else if (FldGetTextLength(fld2P) == 0) { - FrmCustomAlert(FrmWarnAlert,"You must specify a path.",0,0); - TabSetActive(frmP, myTabP, 0); - FrmSetFocus(frmP, FrmGetObjectIndex(frmP, TabGameInfoPathField)); - return errBadParam; - - } else if (FldGetTextLength(fld3P) == 0) { - FrmCustomAlert(FrmWarnAlert,"You must specify a game.",0,0); - TabSetActive(frmP, myTabP, 0); - FrmSetFocus(frmP, FrmGetObjectIndex(frmP, TabGameInfoGameField)); - return errBadParam; - } - - } else { - gameInfoP->engine = LstGetSelection(list1P); - StrCopy(gameInfoP->nameP, FldGetTextPtr(fld1P)); - StrCopy(gameInfoP->pathP, FldGetTextPtr(fld2P)); - StrCopy(gameInfoP->gameP, FldGetTextPtr(fld3P)); - - if (gameInfoP->pathP[StrLen(gameInfoP->pathP)-1] != '/') - StrCat(gameInfoP->pathP, "/"); - - MemPtrFree(itemsText); - itemsText = NULL; - } - - return errNone; -} - -static void DisplayInit(GameInfoType *gameInfoP) { - ListType *list1P, *list2P; - - list1P = (ListType *)GetObjectPtr(TabGameDisplayGfxListList); - list2P = (ListType *)GetObjectPtr(TabGameDisplayRenderList); - - if (gameInfoP) { - LstSetSelection(list1P, gameInfoP->gfxMode); - LstSetSelection(list2P, gameInfoP->renderMode); - CtlSetValue((ControlType *)GetObjectPtr(TabGameDisplayFilterCheckbox), gameInfoP->filter); - CtlSetValue((ControlType *)GetObjectPtr(TabGameDisplayFullscreenCheckbox), gameInfoP->fullscreen); - CtlSetValue((ControlType *)GetObjectPtr(TabGameDisplayAspectRatioCheckbox), gameInfoP->aspectRatio); - - } else { - LstSetSelection(list1P, 0); - CtlSetValue((ControlType *)GetObjectPtr(TabGameDisplayFilterCheckbox), 0); - CtlSetValue((ControlType *)GetObjectPtr(TabGameDisplayFullscreenCheckbox), 0); - CtlSetValue((ControlType *)GetObjectPtr(TabGameDisplayAspectRatioCheckbox), 0); - } - - CtlSetLabel((ControlType *)GetObjectPtr(TabGameDisplayGfxPopupPopTrigger), LstGetSelectionText(list1P, LstGetSelection(list1P))); - CtlSetLabel((ControlType *)GetObjectPtr(TabGameDisplayRenderPopTrigger), LstGetSelectionText(list2P, LstGetSelection(list2P))); -} - -static Err DisplaySave(GameInfoType *gameInfoP) { - ListType *list1P, *list2P; - ControlType *cck6P, *cck7P, *cck8P; - - FormType *frmP = FrmGetActiveForm(); - - list1P = (ListType *)GetObjectPtr(TabGameDisplayGfxListList); - list2P = (ListType *)GetObjectPtr(TabGameDisplayRenderList); - cck6P = (ControlType *)GetObjectPtr(TabGameDisplayFilterCheckbox); - cck7P = (ControlType *)GetObjectPtr(TabGameDisplayFullscreenCheckbox); - cck8P = (ControlType *)GetObjectPtr(TabGameDisplayAspectRatioCheckbox); - - if (!gameInfoP) { - } else { - gameInfoP->gfxMode = LstGetSelection(list1P); - gameInfoP->renderMode = LstGetSelection(list2P); - gameInfoP->filter = CtlGetValue(cck6P); - gameInfoP->fullscreen = CtlGetValue(cck7P); - gameInfoP->aspectRatio = CtlGetValue(cck8P); - } - - return errNone; -} - -static void OptionsInit(GameInfoType *gameInfoP) { - ListType *list2P, *list3P; - FieldType *fld4P, *fld5P, *fld6P; - Char *loadP, *roomP, *talkP; - MemHandle loadH, roomH, talkH; - - list2P = (ListType *)GetObjectPtr(TabGameOptionsLanguageList); - list3P = (ListType *)GetObjectPtr(TabGameOptionsPlatformList); - - fld4P = (FieldType *)GetObjectPtr(TabGameOptionsLoadSlotField); - fld5P = (FieldType *)GetObjectPtr(TabGameOptionsStartRoomField); - fld6P = (FieldType *)GetObjectPtr(TabGameOptionsTalkSpeedField); - - loadH = MemHandleNew(FldGetMaxChars(fld4P)+1); - roomH = MemHandleNew(FldGetMaxChars(fld5P)+1); - talkH = MemHandleNew(FldGetMaxChars(fld6P)+1); - - loadP = (Char *)MemHandleLock(loadH); - roomP = (Char *)MemHandleLock(roomH); - talkP = (Char *)MemHandleLock(talkH); - - if (gameInfoP) { - LstSetSelection(list2P, gameInfoP->language); - LstSetTopItem(list2P, gameInfoP->language); - LstSetSelection(list3P, gameInfoP->platform); - LstSetTopItem(list3P, gameInfoP->platform); - - StrIToA(loadP, gameInfoP->loadSlot); - StrIToA(roomP, gameInfoP->bootValue); - StrIToA(talkP, gameInfoP->talkValue); - - CtlSetValue((ControlType *)GetObjectPtr(TabGameOptionsLoadSlotCheckbox), gameInfoP->autoLoad); - CtlSetValue((ControlType *)GetObjectPtr(TabGameOptionsStartRoomCheckbox), gameInfoP->bootParam); - CtlSetValue((ControlType *)GetObjectPtr(TabGameOptionsAmigaCheckbox), gameInfoP->setPlatform); - CtlSetValue((ControlType *)GetObjectPtr(TabGameOptionsSubtitlesCheckbox), gameInfoP->subtitles); - CtlSetValue((ControlType *)GetObjectPtr(TabGameOptionsTalkSpeedCheckbox), gameInfoP->talkSpeed); - - } else { - LstSetSelection(list2P, 0); - LstSetSelection(list3P, 0); - - StrIToA(loadP, 0); - StrIToA(roomP, 0); - StrIToA(talkP, 60); - - CtlSetValue((ControlType *)GetObjectPtr(TabGameOptionsLoadSlotCheckbox), 0); - CtlSetValue((ControlType *)GetObjectPtr(TabGameOptionsStartRoomCheckbox), 0); - CtlSetValue((ControlType *)GetObjectPtr(TabGameOptionsAmigaCheckbox), 0); - CtlSetValue((ControlType *)GetObjectPtr(TabGameOptionsSubtitlesCheckbox), 1); - CtlSetValue((ControlType *)GetObjectPtr(TabGameOptionsTalkSpeedCheckbox), 0); - } - - MemHandleUnlock(loadH); - MemHandleUnlock(roomH); - MemHandleUnlock(talkH); - - FldSetTextHandle(fld4P, loadH); - FldSetTextHandle(fld5P, roomH); - FldSetTextHandle(fld6P, talkH); - - CtlSetLabel((ControlType *)GetObjectPtr(TabGameOptionsLanguagePopTrigger), LstGetSelectionText(list2P, LstGetSelection(list2P))); - CtlSetLabel((ControlType *)GetObjectPtr(TabGameOptionsPlatformPopTrigger), LstGetSelectionText(list3P, LstGetSelection(list3P))); -} - -static Err OptionsSave(GameInfoType *gameInfoP) { - FieldType *fld4P, *fld5P, *fld6P; - ControlType *cck1P, *cck2P, *cck3P, *cck4P, *cck5P; - ListType *list2P, *list3P; - - FormType *frmP = FrmGetActiveForm(); - - list2P = (ListType *)GetObjectPtr(TabGameOptionsLanguageList); - list3P = (ListType *)GetObjectPtr(TabGameOptionsPlatformList); - - fld4P = (FieldType *)GetObjectPtr(TabGameOptionsLoadSlotField); - fld5P = (FieldType *)GetObjectPtr(TabGameOptionsStartRoomField); - fld6P = (FieldType *)GetObjectPtr(TabGameOptionsTalkSpeedField); - - cck1P = (ControlType *)GetObjectPtr(TabGameOptionsLoadSlotCheckbox); - cck2P = (ControlType *)GetObjectPtr(TabGameOptionsStartRoomCheckbox); - cck3P = (ControlType *)GetObjectPtr(TabGameOptionsAmigaCheckbox); - cck4P = (ControlType *)GetObjectPtr(TabGameOptionsSubtitlesCheckbox); - cck5P = (ControlType *)GetObjectPtr(TabGameOptionsTalkSpeedCheckbox); - - if (!gameInfoP) { - if (FldGetTextLength(fld5P) == 0 && CtlGetValue(cck2P) == 1) { - FrmCustomAlert(FrmWarnAlert,"You must specify a room number.",0,0); - TabSetActive(frmP, myTabP, 2); - FrmSetFocus(frmP, FrmGetObjectIndex(frmP, TabGameOptionsStartRoomField)); - return errBadParam; - - } else if (FldGetTextLength(fld6P) == 0 && CtlGetValue(cck5P) == 1) { - FrmCustomAlert(FrmWarnAlert,"You must specify a talk speed.",0,0); - TabSetActive(frmP, myTabP, 2); - FrmSetFocus(frmP, FrmGetObjectIndex(frmP, TabGameOptionsTalkSpeedField)); - return errBadParam; - } - } else { - gameInfoP->language = LstGetSelection(list2P); - gameInfoP->platform = LstGetSelection(list3P); - - gameInfoP->autoLoad = CtlGetValue(cck1P); - gameInfoP->bootParam = CtlGetValue(cck2P); - gameInfoP->setPlatform = CtlGetValue(cck3P); - gameInfoP->subtitles = (CtlGetValue(cck4P)); - gameInfoP->talkSpeed = CtlGetValue(cck5P); - - gameInfoP->loadSlot = StrAToI(FldGetTextPtr(fld4P)); - gameInfoP->bootValue = StrAToI(FldGetTextPtr(fld5P)); - gameInfoP->talkValue = StrAToI(FldGetTextPtr(fld6P)); - } - - return errNone; -} - -static void GameManInit(UInt16 index) { - TabType *tabP; - FormType *frmP = FrmGetActiveForm(); - UInt16 active = lastTab; - - tabP = TabNewTabs(3); - TabAddContent(&frmP, tabP, "Game", TabGameInfoForm); - TabAddContent(&frmP, tabP, "Display", TabGameDisplayForm); - TabAddContent(&frmP, tabP, "Options", TabGameOptionsForm); - - UInt16 refNum; - if (SysLibFind(kFileBrowserLibName, &refNum)) - FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabGameInfoBrowsePushButton)); - - if (index != dmMaxRecordIndex) { - MemHandle recordH = NULL; - GameInfoType *gameInfoP; - - recordH = DmQueryRecord(gameDB, index); - gameInfoP = (GameInfoType *)MemHandleLock(recordH); - - GameTabInit(gameInfoP); - DisplayInit(gameInfoP); - OptionsInit(gameInfoP); - - MemHandleUnlock(recordH); - CtlSetUsable((ControlType *)GetObjectPtr(GameEditDeleteButton),true); - } else { - active = 0; // new game ? start with first tab - GameTabInit(0); - DisplayInit(0); - OptionsInit(0); - CtlSetUsable((ControlType *)GetObjectPtr(GameEditDeleteButton),false); - } - - FrmSetFocus(frmP, FrmGetObjectIndex(frmP, TabGameInfoEntryNameField)); - FrmDrawForm(frmP); - TabSetActive(frmP, tabP, active); - - myTabP = tabP; -} - -static void GameManSave(UInt16 index) { - MemHandle recordH; - GameInfoType *gameInfoP, newGameInfo; - - if (GameTabSave(0) == errBadParam) return; - if (DisplaySave(0) == errBadParam) return; - if (OptionsSave(0) == errBadParam) return; - - if (index != dmMaxRecordIndex) { - recordH = DmGetRecord(gameDB, index); - gameInfoP = (GameInfoType *)MemHandleLock(recordH); - MemMove(&newGameInfo, gameInfoP, sizeof(GameInfoType)); - - } else { - index = dmMaxRecordIndex; - GamUnselect(); - recordH = DmNewRecord(gameDB, &index, sizeof(GameInfoType)); - gameInfoP = (GameInfoType *)MemHandleLock(recordH); - - MemSet(&newGameInfo, sizeof(GameInfoType), 0); - newGameInfo.version = curItemVersion; - newGameInfo.icnID = 0xFFFF; - newGameInfo.selected = true; - - // default sound data - newGameInfo.musicInfo.volume.palm = 50; - newGameInfo.musicInfo.volume.music = 192; - newGameInfo.musicInfo.volume.sfx = 192; - newGameInfo.musicInfo.volume.speech = 192; - newGameInfo.musicInfo.volume.audiocd = 50; - - newGameInfo.musicInfo.sound.tempo = 100; - newGameInfo.musicInfo.sound.defaultTrackLength = 10; - newGameInfo.musicInfo.sound.firstTrack = 1; - } - - GameTabSave(&newGameInfo); - DisplaySave(&newGameInfo); - OptionsSave(&newGameInfo); - - DmWrite(gameInfoP, 0, &newGameInfo, sizeof(GameInfoType)); - - MemHandleUnlock(recordH); - DmReleaseRecord (gameDB, index, 0); - GamSortList(); - // update list position - { - RectangleType rArea; - UInt16 posIndex, maxView; - - // get the sorted index - index = GamGetSelected(); - // if new item is out of the list bounds, change current list pos - SknGetListBounds(&rArea, NULL); - maxView = rArea.extent.y / sknInfoListItemSize; - posIndex = gPrefs->listPosition; - - // if out of the current list position - if (!(index >= posIndex && index < (posIndex + maxView))) - gPrefs->listPosition = index; // this value is corrected in SknUpdateList if needed - } - - TabDeleteTabs(myTabP); - FrmReturnToMain(); - SknUpdateList(); -} - -/*********************************************************************** - * - * FUNCTION: EditGameFormSave - * FUNCTION: EditGameFormInit - * FUNCTION: EditGameFormHandleEvent - * - * DESCRIPTION: - * - * REVISION HISTORY: - * - * - ***********************************************************************/ -void EditGameFormDelete(Boolean direct) { - UInt16 index = GamGetSelected(); - - if (index == dmMaxRecordIndex) { - FrmCustomAlert(FrmWarnAlert, "Select an entry first.",0,0); - return; - - } else if (FrmCustomAlert(FrmConfirmAlert, "Do you really want to delete this entry ?", 0, 0) == FrmConfirmYes) { - DmRemoveRecord(gameDB, index); - if (!direct) { - TabDeleteTabs(myTabP); - FrmReturnToMain(); - } - GamSortList(); - SknUpdateList(); - } -} - -static void EditGameCancel() { - if (itemsText) { - MemPtrFree(itemsText); - itemsText = NULL; - } - TabDeleteTabs(myTabP); - FrmReturnToMain(); -} - -static void EditGameBowser() { - UInt16 refNum; - Err e; - - ControlPtr butP = (ControlType *)GetObjectPtr(TabGameInfoBrowsePushButton); - CtlSetValue(butP, 0); - - e = SysLibFind (kFileBrowserLibName, &refNum); - if (!e) { - e = FileBrowserLibOpen (refNum); - if (!e) { - UInt16 volRefNum = gPrefs->card.volRefNum; - Char *textP, *pathP = (Char *)MemPtrNew(kFileBrowserLibPathBufferSize); - pathP[0] = chrNull; - - if (FileBrowserLibShowOpenDialog(refNum, &volRefNum, pathP, 0, 0, 0, "Game Data Path", kFileBrowserLibFlagNoFiles)) { - FieldPtr fldP; - MemHandle textH; - Int16 offset, copySize, maxSize; - - fldP = (FieldType *)GetObjectPtr(TabGameInfoPathField); - maxSize = FldGetMaxChars(fldP); - textH = FldGetTextHandle(fldP); - - FldSetTextHandle(fldP, NULL); - textP = (Char *)MemHandleLock(textH); - offset = 0; - copySize = StrLen(pathP); - - if (StrNCaselessCompare(pathP, "/Palm/Programs/ScummVM/Games/", 29) == 0) { - if (StrLen(pathP) == 29) { - copySize = 1; - pathP[0] = '.'; - } else { - copySize -= 29; - offset = 29; - } - } - - if (copySize > maxSize) - copySize = maxSize; - StrNCopy(textP, pathP + offset, copySize); - - MemHandleUnlock(textH); - FldSetTextHandle(fldP, textH); - FldDrawField(fldP); - FldGrabFocus(fldP); - } - - MemPtrFree(pathP); - FileBrowserLibClose(refNum); - } - } -} - -Boolean EditGameFormHandleEvent(EventPtr eventP) { - FormPtr frmP = FrmGetActiveForm(); - Boolean handled = false; - - switch (eventP->eType) { - case frmCloseEvent: - EditGameCancel(); - handled = true; - break; - - case frmOpenEvent: - switch (gFormEditMode) { - case edtModeAdd: - GameManInit(dmMaxRecordIndex); - break; - case edtModeEdit: - case edtModeParams: - default : - GameManInit(GamGetSelected()); - break; - } - handled = true; - break; - - case keyDownEvent: - switch (eventP->data.keyDown.chr) { - case chrLineFeed: - case chrCarriageReturn: - return true; - } - break; - - case ctlSelectEvent: - switch (eventP->data.ctlSelect.controlID) - { - case (GameEditForm + 1) : - case (GameEditForm + 2) : - case (GameEditForm + 3) : - lastTab = (eventP->data.ctlSelect.controlID - GameEditForm - 1); - TabSetActive(frmP, myTabP, lastTab); - break; - - case GameEditOKButton: - switch (gFormEditMode) { - case edtModeAdd: - GameManSave(dmMaxRecordIndex); - break; - case edtModeEdit: - case edtModeParams: - default : - GameManSave(GamGetSelected()); - break; - } - break; - - case GameEditCancelButton: - EditGameCancel(); - break; - - case GameEditDeleteButton: - EditGameFormDelete(false); - break; - - case TabGameInfoBrowsePushButton: - EditGameBowser(); - break; - - case TabGameInfoEnginePopTrigger: - FrmList(eventP, TabGameInfoEngineList); - FrmHideObject(frmP, FrmGetObjectIndex(frmP, TabGameInfoEngineList)); - break; - - case TabGameDisplayGfxPopupPopTrigger: - FrmList(eventP, TabGameDisplayGfxListList); - FrmHideObject(frmP, FrmGetObjectIndex(frmP, TabGameDisplayGfxListList)); - break; - - case TabGameDisplayRenderPopTrigger: - FrmList(eventP, TabGameDisplayRenderList); - FrmHideObject(frmP, FrmGetObjectIndex(frmP, TabGameDisplayRenderList)); - break; - - case TabGameOptionsLanguagePopTrigger: - FrmList(eventP, TabGameOptionsLanguageList); - FrmHideObject(frmP, FrmGetObjectIndex(frmP, TabGameOptionsLanguageList)); - break; - - case TabGameOptionsPlatformPopTrigger: - FrmList(eventP, TabGameOptionsPlatformList); - FrmHideObject(frmP, FrmGetObjectIndex(frmP, TabGameOptionsPlatformList)); - break; - } - handled = true; - break; - - default: - break; - } - - return handled; -} diff --git a/backends/platform/PalmOS/Src/launcher/forms/formMisc.cpp b/backends/platform/PalmOS/Src/launcher/forms/formMisc.cpp deleted file mode 100644 index 35b44486e9..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formMisc.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> - -#include "start.h" -#include "formTabs.h" -#include "forms.h" -#include "globals.h" - -static TabType *myTabP; -static UInt16 lastTab = 0; - -static Boolean ScummVMTabSave() { - FieldType *fld1P, *fld2P; - ControlType *cckP[11]; - FormPtr frmP; - - fld1P = (FieldType *)GetObjectPtr(TabMiscScummVMDebugLevelField); - fld2P = (FieldType *)GetObjectPtr(TabMiscScummVMAutosaveField); - - cckP[0] = (ControlType *)GetObjectPtr(TabMiscScummVMAutosaveCheckbox); - cckP[3] = (ControlType *)GetObjectPtr(TabMiscScummVMDebugCheckbox); - cckP[6] = (ControlType *)GetObjectPtr(TabMiscScummVMDemoCheckbox); - cckP[9] = (ControlType *)GetObjectPtr(TabMiscScummVMCopyProtectionCheckbox); - cckP[10]= (ControlType *)GetObjectPtr(TabMiscScummVMAltIntroCheckbox); - - frmP = FrmGetActiveForm(); - if (FldGetTextLength(fld1P) == 0 && CtlGetValue(cckP[3]) == 1) { - TabSetActive(frmP, myTabP, 1); - FrmSetFocus(frmP, FrmGetObjectIndex(frmP, TabMiscScummVMDebugLevelField)); - FrmCustomAlert(FrmWarnAlert,"You must specify a debug level.",0,0); - return false; - - } else if (FldGetTextLength(fld2P) == 0 && CtlGetValue(cckP[0]) == 1) { - TabSetActive(frmP, myTabP, 1); - FrmSetFocus(frmP, FrmGetObjectIndex(frmP, TabMiscScummVMAutosaveField)); - FrmCustomAlert(FrmWarnAlert,"You must specify a period.",0,0); - return false; - } - - gPrefs->autoSave = CtlGetValue(cckP[0]); - gPrefs->debug = CtlGetValue(cckP[3]); - gPrefs->demoMode = CtlGetValue(cckP[6]); - gPrefs->copyProtection = CtlGetValue(cckP[9]); - gPrefs->altIntro = CtlGetValue(cckP[10]); - - gPrefs->debugLevel = StrAToI(FldGetTextPtr(fld1P)); - gPrefs->autoSavePeriod = StrAToI(FldGetTextPtr(fld2P)); - - return true; -} - -static void PalmOSTabSave() { - ControlType *cckP[11]; - - if (OPTIONS_TST(kOptDeviceARM) && !OPTIONS_TST(kOptDeviceZodiac)) { - cckP[3]= (ControlType *)GetObjectPtr(TabMiscPalmOSAdvancedCheckbox); - gPrefs->advancedMode = CtlGetValue(cckP[3]); - } - - if (!OPTIONS_TST(kOptDeviceARM)) { - cckP[2] = (ControlType *)GetObjectPtr(TabMiscPalmOSStdPaletteCheckbox); - gPrefs->stdPalette = CtlGetValue(cckP[2]); - } - - cckP[0] = (ControlType *)GetObjectPtr(TabMiscPalmOSVibratorCheckbox); - cckP[1] = (ControlType *)GetObjectPtr(TabMiscPalmOSNoAutoOffCheckbox); - cckP[4] = (ControlType *)GetObjectPtr(TabMiscPalmOSLargerStackCheckbox); - cckP[5] = (ControlType *)GetObjectPtr(TabMiscPalmOSExitLauncherCheckbox); - cckP[6] = (ControlType *)GetObjectPtr(TabMiscPalmOSStylusClickCheckbox); - cckP[7] = (ControlType *)GetObjectPtr(TabMiscPalmOSArrowCheckbox); - - gPrefs->vibrator = CtlGetValue(cckP[0]); - gPrefs->autoOff = !CtlGetValue(cckP[1]); - gPrefs->setStack = CtlGetValue(cckP[4]); - gPrefs->exitLauncher = CtlGetValue(cckP[5]); - gPrefs->stylusClick = !CtlGetValue(cckP[6]); - gPrefs->arrowKeys = CtlGetValue(cckP[7]); -} - -static void ExtsTabSave() { - ControlType *cckP[2]; - - if (OPTIONS_TST(kOptLightspeedAPI)) { - ListType *list1P = (ListType *)GetObjectPtr(TabMiscExtsLightspeedList); - cckP[0] = (ControlType *)GetObjectPtr(TabMiscExtsLightspeedCheckbox); - - gPrefs->lightspeed.enable = CtlGetValue(cckP[0]); - gPrefs->lightspeed.mode = LstGetSelection(list1P); - } - if (OPTIONS_TST(kOptGoLcdAPI)) { - cckP[1] = (ControlType *)GetObjectPtr(TabMiscExtsGolcdCheckbox); - gPrefs->goLCD = CtlGetValue(cckP[1]); - } -} - -static void ScummVMTabInit() { - FieldType *fld1P, *fld2P; - Char *levelP, *periodP; - MemHandle levelH, periodH; - - CtlSetValue((ControlType *)GetObjectPtr(TabMiscScummVMAutosaveCheckbox), gPrefs->autoSave); - CtlSetValue((ControlType *)GetObjectPtr(TabMiscScummVMDebugCheckbox), gPrefs->debug); - CtlSetValue((ControlType *)GetObjectPtr(TabMiscScummVMDemoCheckbox), gPrefs->demoMode); - CtlSetValue((ControlType *)GetObjectPtr(TabMiscScummVMCopyProtectionCheckbox), gPrefs->copyProtection); - CtlSetValue((ControlType *)GetObjectPtr(TabMiscScummVMAltIntroCheckbox), gPrefs->altIntro); - - fld1P = (FieldType *)GetObjectPtr(TabMiscScummVMDebugLevelField); - fld2P = (FieldType *)GetObjectPtr(TabMiscScummVMAutosaveField); - - levelH = MemHandleNew(FldGetMaxChars(fld1P)+1); - levelP = (Char *)MemHandleLock(levelH); - StrIToA(levelP, gPrefs->debugLevel); - MemHandleUnlock(levelH); - - periodH = MemHandleNew(FldGetMaxChars(fld2P)+1); - periodP = (Char *)MemHandleLock(periodH); - StrIToA(periodP, gPrefs->autoSavePeriod); - MemHandleUnlock(periodH); - - FldSetTextHandle(fld1P, levelH); - FldSetTextHandle(fld2P, periodH); -} - -static void PalmOSTabInit() { - if (OPTIONS_TST(kOptDeviceARM) && !OPTIONS_TST(kOptDeviceZodiac)) - CtlSetValue((ControlType *)GetObjectPtr(TabMiscPalmOSAdvancedCheckbox), gPrefs->advancedMode); - - if (!OPTIONS_TST(kOptDeviceARM)) - CtlSetValue((ControlType *)GetObjectPtr(TabMiscPalmOSStdPaletteCheckbox), gPrefs->stdPalette); - - CtlSetValue((ControlType *)GetObjectPtr(TabMiscPalmOSExitLauncherCheckbox), gPrefs->exitLauncher); - CtlSetValue((ControlType *)GetObjectPtr(TabMiscPalmOSLargerStackCheckbox), gPrefs->setStack); - CtlSetValue((ControlType *)GetObjectPtr(TabMiscPalmOSVibratorCheckbox), gPrefs->vibrator); - CtlSetValue((ControlType *)GetObjectPtr(TabMiscPalmOSNoAutoOffCheckbox), !gPrefs->autoOff); - CtlSetValue((ControlType *)GetObjectPtr(TabMiscPalmOSStylusClickCheckbox), !gPrefs->stylusClick); - CtlSetValue((ControlType *)GetObjectPtr(TabMiscPalmOSArrowCheckbox), gPrefs->arrowKeys); -} - -static void ExtsTabInit() { - if (OPTIONS_TST(kOptLightspeedAPI)) { - ListType *list1P = (ListType *)GetObjectPtr(TabMiscExtsLightspeedList); - LstSetSelection(list1P, gPrefs->lightspeed.mode); - CtlSetLabel((ControlType *)GetObjectPtr(TabMiscExtsLightspeedPopTrigger), LstGetSelectionText(list1P, LstGetSelection(list1P))); - CtlSetValue((ControlType *)GetObjectPtr(TabMiscExtsLightspeedCheckbox), gPrefs->lightspeed.enable); - } - - if (OPTIONS_TST(kOptGoLcdAPI)) - CtlSetValue((ControlType *)GetObjectPtr(TabMiscExtsGolcdCheckbox), gPrefs->goLCD); -} - -static void MiscFormSave() { - if (!ScummVMTabSave()) return; - PalmOSTabSave(); - ExtsTabSave(); - - TabDeleteTabs(myTabP); - FrmReturnToMain(); -} - -static void MiscFormInit() { - TabType *tabP; - FormType *frmP = FrmGetActiveForm(); - UInt8 extsCnt = 2; - - tabP = TabNewTabs(3); - TabAddContent(&frmP, tabP, "PalmOS", TabMiscPalmOSForm); - TabAddContent(&frmP, tabP, "ScummVM", TabMiscScummVMForm); - TabAddContent(&frmP, tabP, "More ...", TabMiscExtsForm); - - if (OPTIONS_TST(kOptDeviceARM)) { - FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabMiscPalmOSStdPaletteCheckbox)); - TabMoveUpObject(frmP, TabMiscPalmOSAdvancedCheckbox, 12); - } - - if (!OPTIONS_TST(kOptDeviceARM) || OPTIONS_TST(kOptDeviceZodiac)) - FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabMiscPalmOSAdvancedCheckbox)); - - if (!OPTIONS_TST(kOptGoLcdAPI)) { - FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabMiscExtsGolcdCheckbox)); - // move lightspeed - TabMoveUpObject(frmP, TabMiscExtsLightspeedCheckbox, 12); - TabMoveUpObject(frmP, TabMiscExtsLightspeedPopTrigger, 12); - TabMoveUpObject(frmP, TabMiscExtsLightspeedList, 12); - TabMoveUpObject(frmP, TabMiscExtsNothingLabel, 12); - extsCnt--; - } - - if (!OPTIONS_TST(kOptLightspeedAPI)) { - FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabMiscExtsLightspeedCheckbox)); -// FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabMiscExtsLightspeedList)); // cannot remove this ? - FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabMiscExtsLightspeedPopTrigger)); - TabMoveUpObject(frmP, TabMiscExtsNothingLabel, 12); - extsCnt--; - } - - if (extsCnt) - FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabMiscExtsNothingLabel)); - - PalmOSTabInit(); - ScummVMTabInit(); - ExtsTabInit(); - - FrmDrawForm(frmP); - TabSetActive(frmP, tabP, lastTab); - - myTabP = tabP; -} - -Boolean MiscFormHandleEvent(EventPtr eventP) { - FormPtr frmP = FrmGetActiveForm(); - Boolean handled = false; - - switch (eventP->eType) { - case frmOpenEvent: - MiscFormInit(); - handled = true; - break; - - case ctlSelectEvent: - switch (eventP->data.ctlSelect.controlID) - { - case (MiscForm + 1) : - case (MiscForm + 2) : - case (MiscForm + 3) : - lastTab = (eventP->data.ctlSelect.controlID - MiscForm - 1); - TabSetActive(frmP, myTabP, lastTab); - break; - - case TabMiscExtsLightspeedPopTrigger: - FrmList(eventP, TabMiscExtsLightspeedList); - FrmHideObject(frmP, FrmGetObjectIndex(frmP, TabMiscExtsLightspeedList)); - break; - - case MiscOKButton: - MiscFormSave(); - break; - - case MiscCancelButton: - TabDeleteTabs(myTabP); - FrmReturnToMain(); - break; - } - handled = true; - break; - - default: - break; - } - - return handled; -} diff --git a/backends/platform/PalmOS/Src/launcher/forms/formSelect.cpp b/backends/platform/PalmOS/Src/launcher/forms/formSelect.cpp deleted file mode 100644 index bb0ac894c2..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formSelect.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> -#include "StarterRsc.h" -#include "formUtil.h" -#include "games.h" -#include "start.h" - -#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0]))) - -static Char **items = NULL; -Int16 selectedEngine = -1; - -// Supported games -static const char *engine_agos[] = { - "Demon in my Pocket", - "Elvira - Mistress of the Dark", - "Elvira II - The Jaws of Cerberus", - "Jumble", - "NoPatience", - "Simon the Sorcerer I", - "Simon the Sorcerer II", - "Swampy Adventures", - "The Feeble Files", - "Waxworks" -}; - -static const char *engine_sky[] = { - "Floppy, CD and Demo" -}; - -static const char *engine_sword1[] = { - "The Shadow of the Templars (PC/Mac)", - "The Shadow of the Templars (Demo)" -}; - -static const char *engine_sword2[] = { - "The Smoking Mirror", - "The Smoking Mirror (Demo)" -}; - -static const char *engine_cine[] = { - "Future Wars", - "Operation Stealth" -}; - -static const char *engine_queen[] = { - "Flight of the Amazon Queen" -}; - -static const char *engine_lure[] = { - "Lure of the Tempress" -}; - -static const char *engine_gob[] = { - "Bargon Attack", - "Gobliiins", - "Gobliins 2", - "Goblins Quest 3", - "The Bizarre Adventures of Woodruff and the Schnibble", - "Ween: The Prophecy", -}; - -static const char *engine_kyra[] = { - "The Legend of Kyrandia", - "The Legend of Kyrandia: The Hand of Fate", - "The Legend of Kyrandia: Malcolm's Revenge" -}; - -static const char *engine_parallaction[] = { - "Nippon Safes Inc." -}; - -static const char *engine_saga[] = { - "I Have No Mouth And I Must Scream", - "Inherit the earth" -}; - -static const char *engine_scumm[] = { - "Day of the Tentacle", - "Indiana Jones and the Fate of Atlantis", - "Indiana Jones and the Last Crusade", - "Loom", - "Maniac Mansion", - "Monkey Island 2: LeChuck's Revenge", - "Passport to Adventure", - "Sam & Max Hit the Road", - "The Secret of Monkey Island" - "Zak McKracken and the Alien Mindbenders" -}; - -static const char *engine_agi[] = { - "AGI Tetris", - "Caitlyn's Destiny", - "Donald Duck's Playground", - "Fanmade AGI game", - "Gold Rush!", - "King's Quest I: Quest for the Crown", - "King's Quest II: Romancing the Throne", - "King's Quest III: To Heir Is Human", - "King's Quest IV: The Perils of Rosella", - "Leisure Suit Larry in the Land of the Lounge Lizards", - "Mixed-Up Mother Goose", - "Manhunter 1: New York", - "Manhunter 2: San Francisco", - "Police Quest I: In Pursuit of the Death Angel", - "Serguei's Destiny 1", - "Serguei's Destiny 2", - "Space Quest 0: Replicated", - "Space Quest I: The Sarien Encounter", - "Space Quest II: Vohaul's Revenge", - "Space Quest X: The Lost Chapter", - "The Black Cauldron", - "Xmas Card" -}; - -static const char *engine_touche[] = { - "Touche: The Adventures of the Fifth Musketeer" -}; - -static const char *engine_cruise[] = { - "Cruise for a Corpse" -}; - -static const struct { - int size; - const char **listP; -} supported[] = { - { ARRAYSIZE(engine_agos), engine_agos }, - { ARRAYSIZE(engine_sky), engine_sky }, - { ARRAYSIZE(engine_sword1), engine_sword1 }, - { ARRAYSIZE(engine_sword2), engine_sword2 }, - { ARRAYSIZE(engine_cine), engine_cine }, - { ARRAYSIZE(engine_queen), engine_queen }, - { ARRAYSIZE(engine_lure), engine_lure }, - { ARRAYSIZE(engine_gob), engine_gob }, - { ARRAYSIZE(engine_kyra), engine_kyra }, - { ARRAYSIZE(engine_parallaction), engine_parallaction }, - { ARRAYSIZE(engine_saga), engine_saga }, - { ARRAYSIZE(engine_scumm), engine_scumm }, - { ARRAYSIZE(engine_agi), engine_agi }, - { ARRAYSIZE(engine_touche), engine_touche }, - { ARRAYSIZE(engine_cruise), engine_cruise } -}; - -static void SelectorSetList(Int16 sel) { - ListType *listP; - FormPtr frmP = FrmGetActiveForm(); - - Boolean toBeDrawn = (items != NULL); - if (items) - MemPtrFree(items); - - listP = (ListType *)FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, EngineSupportedList)); - items = (Char **)MemPtrNew(supported[sel].size * sizeof(Char *)); - - for (int i = 0; i < supported[sel].size; i++) - items[i] = (Char *)supported[sel].listP[i]; - - LstSetListChoices (listP, items, supported[sel].size); - LstSetTopItem(listP, 0); - LstSetSelection(listP, -1); - - if (toBeDrawn) { - WinScreenLock(winLockCopy); - LstDrawList(listP); - WinScreenUnlock(); - } -} - -static void SelectorFormInit() { - ListType *listP; - FormPtr frmP = FrmGetActiveForm(); - - listP = (ListType *)FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, EngineListList)); - itemsText = (Char **)MemPtrNew(ENGINE_COUNT * sizeof(Char *)); - - for (int i = 0; i < ENGINE_COUNT; i++) - itemsText[i] = (Char *)engines[i].nameP; - - LstSetListChoices (listP, itemsText, ENGINE_COUNT); - LstSetSelection(listP, 0); - - SelectorSetList(0); - - FrmDrawForm(frmP); -} - -static void SelectorFormFree(bool quit) { - items = NULL; - - if (!quit) { - ListType *listP = (ListType *)GetObjectPtr(EngineListList); - Int16 sel = LstGetSelection(listP); - - FrmReturnToMain(); - StartScummVM(sel); - - } else { - FrmReturnToMain(); - - if (bDirectMode) { - // force exit if nothing selected - EventType event; - event.eType = keyDownEvent; - event.data.keyDown.chr = vchrLaunch; - event.data.keyDown.modifiers = commandKeyMask; - EvtAddUniqueEventToQueue(&event, 0, true); - } - } -} - -Boolean SelectorFormHandleEvent(EventPtr eventP) { - FormPtr frmP = FrmGetActiveForm(); - Boolean handled = false; - - switch (eventP->eType) { - case frmOpenEvent: - SelectorFormInit(); - handled = true; - break; - - case frmCloseEvent: - SelectorFormFree(true); - handled = true; - break; - - case lstSelectEvent: - if (eventP->data.lstSelect.listID == EngineSupportedList) - LstSetSelection(eventP->data.lstSelect.pList, -1); - else - SelectorSetList(eventP->data.lstSelect.selection); - handled = true; - break; - - case ctlSelectEvent: - switch (eventP->data.ctlSelect.controlID) - { - case EngineOkButton: - SelectorFormFree(false); - break; - - case EngineCancelButton: - SelectorFormFree(true); - break; - } - handled = true; - break; - - default: - break; - } - - return handled; -} diff --git a/backends/platform/PalmOS/Src/launcher/forms/formSkins.cpp b/backends/platform/PalmOS/Src/launcher/forms/formSkins.cpp deleted file mode 100644 index 9566a25311..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formSkins.cpp +++ /dev/null @@ -1,267 +0,0 @@ -#include <PalmOS.h> - -#include "palmdefs.h" -#include "start.h" -#include "forms.h" -#include "skin.h" -#include "globals.h" - -static Int16 SkinsFormCompare(SkinInfoType *a, SkinInfoType *b, SortRecordInfoPtr, SortRecordInfoPtr, MemHandle) { - return StrCompare(a->nameP, b->nameP); -} - -static void SkinsFormInit(Boolean bDraw) { - MemHandle skins = NULL; - SkinInfoType *skinsInfo; - UInt16 numSkins = 0; - - FormPtr frmP; - ListType *listP; - MemHandle items = NULL; - ControlType *cck1P; - DmSearchStateType stateInfo; - UInt16 cardNo; - LocalID dbID; - - Err errInfo; - Char nameP[32]; - - itemsText = NULL; - - // parse and save skins - Err err = DmGetNextDatabaseByTypeCreator(true, &stateInfo, 'skin', appFileCreator, false, &cardNo, &dbID); - while (!err && dbID) { - errInfo = DmDatabaseInfo (cardNo, dbID, nameP, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - if (!errInfo) - { - if (!skins) - skins = MemHandleNew(sizeof(SkinInfoType)); - else - MemHandleResize(skins, MemHandleSize(skins) + sizeof(SkinInfoType)); - - skinsInfo = (SkinInfoType *)MemHandleLock(skins); - StrCopy(skinsInfo[numSkins].nameP, nameP); - skinsInfo[numSkins].cardNo = cardNo; - skinsInfo[numSkins].dbID = dbID; - MemHandleUnlock(skins); - numSkins++; - } - err = DmGetNextDatabaseByTypeCreator(false, &stateInfo, 'skin', appFileCreator, false, &cardNo, &dbID); - } - - Int16 selected = -1; - - cck1P = (ControlType *)GetObjectPtr(SkinsSoundClickCheckbox); - CtlSetValue(cck1P, gPrefs->soundClick); - - listP = (ListType *)GetObjectPtr(SkinsSkinList); - skinsInfo = (SkinInfoType *)MemHandleLock(skins); - SysQSort(skinsInfo, numSkins, sizeof(SkinInfoType), (CmpFuncPtr)SkinsFormCompare, 0); - - // create itemsText (TODO: create a custom draw function) - for (UInt16 index=0; index < numSkins; index++) - { - if (!items) - items = MemHandleNew(sizeof(Char *)); - else - MemHandleResize(items, MemHandleSize(items) + sizeof(Char *)); - - itemsText = (Char **)MemHandleLock(items); - itemsText[index] = skinsInfo[index].nameP; - MemHandleUnlock(items); - - if ( gPrefs->skin.cardNo == skinsInfo[index].cardNo && - gPrefs->skin.dbID == skinsInfo[index].dbID && - StrCompare(gPrefs->skin.nameP, skinsInfo[index].nameP) == 0) - selected = index; - } - // save globals and set list - itemsText = (Char **)MemHandleLock(items); - itemsList = (void *)skinsInfo; - itemsType = ITEM_TYPE_SKIN; - - LstSetListChoices (listP, itemsText, numSkins); - LstSetSelection(listP, selected); - - // bDraw = true -> draw whole from - // bDraw = false -> redraw list - if (bDraw) { - frmP = FrmGetActiveForm(); - FrmDrawForm(frmP); - } else { - WinScreenLock(winLockCopy); - LstDrawList(listP); - WinScreenUnlock(); -// LstSetSelection(listP, 0); - } -} - -static void SkinsFormExit(Boolean bSave) { - MemHandle skins; - MemHandle items; - SkinInfoType *skinsInfo; - - ListType *listP; - Int16 selected; - - listP = (ListType *)GetObjectPtr(SkinsSkinList); - selected = LstGetSelection(listP); - - if (bSave && selected == -1) { // may never occurred... - FrmCustomAlert(FrmWarnAlert, "You didn't select a skin.", 0, 0); - return; - } - - skinsInfo = (SkinInfoType *)itemsList; - skins = MemPtrRecoverHandle(skinsInfo); - items = MemPtrRecoverHandle(itemsText); - - itemsText = NULL; - itemsList = NULL; - itemsType = ITEM_TYPE_UNKNOWN; - - if (bSave) { - ControlType *cck1P; - - StrCopy(gPrefs->skin.nameP, skinsInfo[selected].nameP); - gPrefs->skin.cardNo = skinsInfo[selected].cardNo; - gPrefs->skin.dbID = skinsInfo[selected].dbID; - -/* DmOpenRef skinDB = SknOpenSkin(); - UInt32 depth = SknGetDepth(skinDB); - SknCloseSkin(skinDB); - - if (depth != 8 && depth != 16) depth = 8; - - if (depth == 16 && !OPTIONS_TST(kOptMode16Bit)) { - FrmCustomAlert(FrmInfoAlert, "You can only use 8bit skin on your device.", 0, 0); - gPrefs->skin.cardNo = cardNo; - gPrefs->skin.dbID = dbID; - } -*/ - cck1P = (ControlType *)GetObjectPtr(SkinsSoundClickCheckbox); - gPrefs->soundClick = CtlGetValue(cck1P); - } - - FrmReturnToMain(); - - MemHandleUnlock(items); - MemHandleUnlock(skins); - MemHandleFree(items); - MemHandleFree(skins); - - if (bSave) - SknApplySkin(); -} - -static void SkinsFormBeam() { - SkinInfoType *skinsInfo; - - ListType *listP; - Int16 selected; - Err err; - - listP = (ListType *)GetObjectPtr(SkinsSkinList); - selected = LstGetSelection(listP); - - if (selected == -1) { // may never occurred... - FrmCustomAlert(FrmWarnAlert, "You didn't select a skin.", 0, 0); - return; - } - - skinsInfo = (SkinInfoType *)itemsList; - err = SendDatabase(0, skinsInfo[selected].dbID, "skin.pdb", "\nScummVM Skin"); - -// if (err) -// FrmCustomAlert(FrmErrorAlert, "Unable to beam this skin.",0,0); -} - -static void SkinsFormDelete() { - MemHandle skins; - MemHandle items; - SkinInfoType *skinsInfo; - - ListType *listP; - Int16 selected; - - listP = (ListType *)GetObjectPtr(SkinsSkinList); - selected = LstGetSelection(listP); - - if (selected == -1) { // may never occurred... - FrmCustomAlert(FrmInfoAlert, "You didn't select a skin.", 0, 0); - return; - } - - skinsInfo = (SkinInfoType *)itemsList; - skins = MemPtrRecoverHandle(skinsInfo); - items = MemPtrRecoverHandle(itemsText); - - if ( gPrefs->skin.cardNo == skinsInfo[selected].cardNo && - gPrefs->skin.dbID == skinsInfo[selected].dbID && - StrCompare(gPrefs->skin.nameP, skinsInfo[selected].nameP) == 0) { - FrmCustomAlert(FrmInfoAlert, "You cannot delete the active skin.",0,0); - return; - - } else { - Err err = DmDeleteDatabase(0, skinsInfo[selected].dbID); - if (!err) { - - itemsText = NULL; - itemsList = NULL; - itemsType = ITEM_TYPE_UNKNOWN; - - MemHandleUnlock(items); - MemHandleUnlock(skins); - MemHandleFree(items); - MemHandleFree(skins); - - SkinsFormInit(false); - } else { - FrmCustomAlert(FrmErrorAlert, "Skin deletion failed.",0,0); - } - } - -} -Boolean SkinsFormHandleEvent(EventPtr eventP) { - Boolean handled = false; - - switch (eventP->eType) { - - case frmOpenEvent: - SkinsFormInit(true); - handled = true; - break; - - case frmCloseEvent: - SkinsFormExit(false); - handled = true; - break; - - case ctlSelectEvent: - switch (eventP->data.ctlSelect.controlID) - { - case SkinsOKButton: - SkinsFormExit(true); - break; - - case SkinsCancelButton: - SkinsFormExit(false); - break; - - case SkinsBeamButton: - SkinsFormBeam(); - break; - - case SkinsDeleteButton: - SkinsFormDelete(); - break; - } - handled = true; - break; - - default: - break; - } - - return handled; -} diff --git a/backends/platform/PalmOS/Src/launcher/forms/formUtil.cpp b/backends/platform/PalmOS/Src/launcher/forms/formUtil.cpp deleted file mode 100644 index 6d1d55e6e2..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formUtil.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include <PalmOS.h> -#include <TxtGlue.h> - -#include "forms.h" - -Char **itemsText = NULL; -void *itemsList = NULL; -Char itemsType = ITEM_TYPE_UNKNOWN; - -void FrmReturnToMain(UInt16 updateCode) { - // if there is a form loaded, prevent crash on OS5 - if (FrmGetFirstForm()) { - FrmUpdateForm(MainForm, updateCode); - FrmReturnToForm(MainForm); - } -} - -void FldTrimText(FieldPtr fldP) { - MemHandle tmpH; - Char *tmpP; - - tmpH = FldGetTextHandle(fldP); - FldSetTextHandle(fldP, NULL); - tmpP = (Char *)MemHandleLock(tmpH); - TxtGlueStripSpaces(tmpP, true, true); - MemHandleUnlock(tmpH); - FldSetTextHandle(fldP, tmpH); -} - -/*********************************************************************** - * - * FUNCTION: GetObjectPtr - * - * DESCRIPTION: This routine returns a pointer to an object in the current - * form. - * - * PARAMETERS: formId - id of the form to display - * - * RETURNED: void * - * - * REVISION HISTORY: - * - * - ***********************************************************************/ -void * GetObjectPtr(UInt16 objectID) { - FormPtr frmP; - - frmP = FrmGetActiveForm(); - return FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID)); -} - -void FrmList(EventPtr eventP, UInt16 objectID) { - ListType *listP; - UInt16 listItem; - - listP = (ListType *)GetObjectPtr(objectID); - listItem = LstPopupList(listP); - CtlSetLabel(eventP->data.ctlSelect.pControl, LstGetSelectionText(listP, LstGetSelection(listP))); -} - diff --git a/backends/platform/PalmOS/Src/launcher/forms/formUtil.h b/backends/platform/PalmOS/Src/launcher/forms/formUtil.h deleted file mode 100644 index e9b87bc49f..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formUtil.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __FORMUTIL_H__ -#define __FORMUTIL_H__ - -#define frmRedrawUpdateMS (frmRedrawUpdateCode + 1) -#define frmRedrawUpdateMSImport (frmRedrawUpdateCode + 2) - -#define NO_ENGINE -1 - -// form list draw -#define ITEM_TYPE_UNKNOWN 'U' -#define ITEM_TYPE_CARD 'C' -#define ITEM_TYPE_SKIN 'S' - -extern Char **itemsText; -extern void *itemsList; -extern Char itemsType; - -void FrmReturnToMain(UInt16 updateCode = frmRedrawUpdateMS); -void * GetObjectPtr(UInt16 objectID); -void FldTrimText(FieldPtr fldP); -void FrmList(EventPtr eventP, UInt16 objectID); - -#endif diff --git a/backends/platform/PalmOS/Src/launcher/forms/forminfo.cpp b/backends/platform/PalmOS/Src/launcher/forms/forminfo.cpp deleted file mode 100644 index 3f4ab1b28f..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/forminfo.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include <PalmOS.h> - -#include "start.h" -#include "formTabs.h" -#include "forms.h" - -#include "base/version.h" -#include "globals.h" -#include "init_palmos.h" - -/*********************************************************************** - * - * FUNCTION: MiscOptionsFormSave - * FUNCTION: MiscOptionsFormInit - * FUNCTION: MiscOptionsFormHandleEvent - * - * DESCRIPTION: Misc. Options form functions - * - * REVISION HISTORY: - * - * - ***********************************************************************/ -static TabType *myTabP; -static UInt16 lastTab = 0; - -static UInt32 GetStackSize() { - MemPtr startPP, endPP; - SysGetStackInfo(&startPP, &endPP); - - return ((Char *)endPP - (Char *)startPP) / 1024L; -} - -static void VersionTabDraw() { - WinDrawChars(gScummVMVersion, StrLen(gScummVMVersion), 47, 12 + 30); - WinDrawChars(gScummVMBuildDate, StrLen(gScummVMBuildDate), 47, 24 + 30); -} - -static void SystemTabDraw() { - Coord x; - UInt32 dm, sm, df, sf, stack; - Char num[10]; - - PalmGetMemory(&sm, &dm, &sf, 0); - stack = GetStackSize(); - df = gVars->startupMemory; - - WinSetTextColor(UIColorGetTableEntryIndex(UIObjectForeground)); - FntSetFont(stdFont); - - StrIToA(num, dm); - x = 147 - FntCharsWidth(num, StrLen(num)) + 5; - WinDrawChars(num, StrLen(num), x, 12 + 30); - - StrIToA(num, sm); - x = 147 - FntCharsWidth(num, StrLen(num)) + 5; - WinDrawChars(num, StrLen(num), x, 24 + 30); - - StrIToA(num, stack); - x = 147 - FntCharsWidth(num, StrLen(num)) + 5; - WinDrawChars(num, StrLen(num), x, 36 + 30); - - StrIToA(num, df); - x = 107 - FntCharsWidth(num, StrLen(num)) + 5; - WinDrawChars(num, StrLen(num), x, 12 + 30); - - StrIToA(num, sf); - x = 107 - FntCharsWidth(num, StrLen(num)) + 5; - WinDrawChars(num, StrLen(num), x, 24 + 30); - - StrCopy(num,"-"); - x = 107 - FntCharsWidth(num, StrLen(num)) + 5; - WinDrawChars(num, StrLen(num), x, 36 + 30); -} - -static void InfoFormSave() { - TabDeleteTabs(myTabP); - FrmReturnToMain(); -} - -static void AboutTabDraw() { - MemHandle hTemp; - BitmapPtr bmpTemp; - - hTemp = DmGetResource (bitmapRsc, 1200); - if (hTemp) { - bmpTemp = (BitmapType *)MemHandleLock(hTemp); - WinDrawBitmap(bmpTemp,3,44); - MemPtrUnlock(bmpTemp); - DmReleaseResource(hTemp); - } -} - -static void InfoFormInit() { - TabType *tabP; - FormType *frmP = FrmGetActiveForm(); - - tabP = TabNewTabs(3); - TabAddContent(&frmP, tabP, "About", TabInfoAboutForm, AboutTabDraw); - TabAddContent(&frmP, tabP, "Version", TabInfoVersionForm, VersionTabDraw); - TabAddContent(&frmP, tabP, "Memory", TabInfoSystemForm, SystemTabDraw); - - lastTab = 0; - FrmDrawForm(frmP); - TabSetActive(frmP, tabP, lastTab); - - myTabP = tabP; -} - -Boolean InfoFormHandleEvent(EventPtr eventP) { - FormPtr frmP = FrmGetActiveForm(); - Boolean handled = false; - - switch (eventP->eType) { - case frmOpenEvent: - InfoFormInit(); - handled = true; - break; - - case frmCloseEvent: - InfoFormSave(); - handled = true; - break; - - case ctlSelectEvent: - switch (eventP->data.ctlSelect.controlID) - { - case (InfoForm + 1) : - case (InfoForm + 2) : - case (InfoForm + 3) : - lastTab = (eventP->data.ctlSelect.controlID - InfoForm - 1); - TabSetActive(frmP, myTabP, lastTab); - break; - - case InfoOKButton: - InfoFormSave(); - break; - } - handled = true; - break; - - default: - break; - } - - return handled; -} diff --git a/backends/platform/PalmOS/Src/launcher/forms/formmain.cpp b/backends/platform/PalmOS/Src/launcher/forms/formmain.cpp deleted file mode 100644 index ca2e18ee6d..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formmain.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> - -#include "StarterRsc.h" -#include "start.h" -#include "skin.h" -#include "games.h" -#include "globals.h" - -#include "base/version.h" - -#include "formEditGame.h" -#include "formUtil.h" - -static UInt16 sknLastOn = skinButtonNone; - -static Err BeamMe() { - UInt16 cardNo; - LocalID dbID; - Err err; - - err = SysCurAppDatabase(&cardNo, &dbID); - if (dbID) - err = SendDatabase(0, dbID, "ScummVM.prc", "\nPlay your favorite LucasArts games"); - else - err = DmGetLastErr(); - - return err; -} - -/*********************************************************************** - * - * FUNCTION: MainFormInit - * - * DESCRIPTION: This routine initializes the MainForm form. - * - * PARAMETERS: frm - pointer to the MainForm form. - * - * RETURNED: nothing - * - * REVISION HISTORY: - * - * - ***********************************************************************/ -static void MainFormInit() -{ - SknApplySkin(); -} - -/*********************************************************************** - * - * FUNCTION: MainFormDoCommand - * - * DESCRIPTION: This routine performs the menu command specified. - * - * PARAMETERS: command - menu item id - * - * RETURNED: nothing - * - * REVISION HISTORY: - * - * - ***********************************************************************/ - -static Boolean MainFormDoCommand(UInt16 command) -{ - Boolean handled = false; - - switch (command) { - case MainGamesMemoryCard: - FrmPopupForm(CardSlotForm); - handled = true; - break; - - case MainGamesNew: - gFormEditMode = edtModeAdd; - FrmPopupForm(GameEditForm); - handled = true; - break; - - case MainGamesEdit: - gFormEditMode = edtModeEdit; - FrmPopupForm(GameEditForm); - handled = true; - break; - - case MainGamesDelete: - EditGameFormDelete(true); - handled = true; - break; - - case MainOptionsBeam: - BeamMe(); - //if (BeamMe()) - //FrmCustomAlert(FrmErrorAlert,"Unable to beam ScummVM for PalmOS.",0,0); - handled = true; - break; - - case MainOptionsAbout: - FrmPopupForm(InfoForm); - handled = true; - break; - - case MainGamesMusicSound: - FrmPopupForm(MusicForm); - handled = true; - break; - - case MainOptionsSkins: - FrmPopupForm(SkinsForm); - handled = true; - break; - - case MainOptionsMisc: - FrmPopupForm(MiscForm); - handled = true; - break; - } - - MenuEraseStatus(0); - return handled; -} - -/*********************************************************************** - * - * FUNCTION: MainFormHandleEvent - * - * DESCRIPTION: This routine is the event handler for the - * "MainForm" of this application. - * - * PARAMETERS: eventP - a pointer to an EventType structure - * - * RETURNED: true if the event has handle and should not be passed - * to a higher level handler. - * - * REVISION HISTORY: - * - * - ***********************************************************************/ - -static Boolean PenDownRepeat() { - Coord x,y; - Boolean penDown, handled = false; - EvtGetPen(&x, &y, &penDown); - - if (penDown && sknLastOn) { - RectangleType r; - DmOpenRef skinDBP; - - skinDBP = SknOpenSkin(); - SknGetObjectBounds(skinDBP, sknLastOn, &r); - - if (RctPtInRectangle(x*2, y*2, &r)) { - if (SknGetState(skinDBP, sknLastOn) != sknStateSelected) { - SknSetState(skinDBP, sknLastOn, sknStateSelected); - SknShowObject(skinDBP, sknLastOn); - } - - switch (sknLastOn) { - case skinSliderUpArrow: - case skinSliderDownArrow: - handled = SknProcessArrowAction(sknLastOn); - break; - } - - } else { - if (SknGetState(skinDBP, sknLastOn) != sknStateNormal) { - SknSetState(skinDBP, sknLastOn, sknStateNormal); - SknShowObject(skinDBP, sknLastOn); - } - } - - SknCloseSkin(skinDBP); - } - - return handled; -} - - -Boolean MainFormHandleEvent(EventPtr eventP) -{ - Boolean handled = false; - FormPtr frmP; - Coord x,y; - DmOpenRef skinDBP; - - switch (eventP->eType) { - case frmUpdateEvent: - { - RectangleType r; - UInt16 idx; - IndexedColorType bgColor = UIColorGetTableEntryIndex(UIFormFill); - frmP = FrmGetFormPtr(MainForm); - - if (gPrefs->card.volRefNum != vfsInvalidVolRef) - idx = FrmGetObjectIndex (frmP, MainMSBitMap); - else - idx = FrmGetObjectIndex (frmP, MainMSNoneBitMap); - - WinSetDrawMode(winPaint); - WinSetBackColor(bgColor); - FrmGetObjectBounds(frmP, idx, &r); - WinEraseRectangle(&r, 0); - FrmShowObject(frmP, idx); - - if (eventP->data.frmUpdate.updateCode == frmRedrawUpdateMSImport) { - GamImportDatabase(); - SknUpdateList(); - } - handled = true; - break; - } - case menuEvent: - handled = MainFormDoCommand(eventP->data.menu.itemID); - break; - - case frmOpenEvent: - MainFormInit(); - handled = true; - break; - - case ctlSelectEvent: - switch (eventP->data.ctlSelect.controlID) - { - case MainCardsButton: - //gPrefs->card.volRefNum = parseCards(true); - FrmPopupForm(CardSlotForm); - break; - - case MainAboutButton: - FrmPopupForm(InfoForm); - break; - -// case MainListTypeSelTrigger: -// FrmList(eventP, MainListTypeList); -// break; - } - handled = true; - break; - - case penUpEvent: - x = eventP->screenX; - y = eventP->screenY; - lastIndex = dmMaxRecordIndex; // enable select/unselect list item - - if (sknLastOn != skinButtonNone) { - RectangleType r; - skinDBP = SknOpenSkin(); - SknGetObjectBounds(skinDBP, sknLastOn, &r); - SknSetState(skinDBP, sknLastOn, sknStateNormal); - SknShowObject(skinDBP, sknLastOn); - SknCloseSkin(skinDBP); - - if (RctPtInRectangle(x*2, y*2, &r)) { - switch (sknLastOn) { - case skinButtonGameAdd: - gFormEditMode = edtModeAdd; - FrmPopupForm(GameEditForm); - handled = true; - break; - - case skinButtonGameAudio: - FrmPopupForm(MusicForm); - handled = true; - break; - - case skinButtonGameEdit: - case skinButtonGameParams: - gFormEditMode = edtModeParams; - FrmPopupForm(GameEditForm); - handled = true; - break; - - case skinButtonGameStart: - if (gPrefs->card.volRefNum == vfsInvalidVolRef) - FrmCustomAlert(FrmWarnAlert,"Please select/insert a memory card.", 0, 0); - else if (GamGetSelected() != dmMaxRecordIndex) - StartScummVM(); - else - FrmPopupForm(EngineForm); - handled = true; - break; - - case skinButtonGameDelete: - EditGameFormDelete(true); - break; - } - } - sknLastOn = skinButtonNone; - } - break; - - case penDownEvent: - case penMoveEvent: - if (sknLastOn == skinButtonNone) { - x = eventP->screenX; - y = eventP->screenY; - skinDBP = SknOpenSkin(); - - switch (sknLastOn = SknCheckClick(skinDBP, x,y)) { - case skinButtonNone: - break; - case skinSliderUpArrow: - case skinSliderDownArrow: - case skinButtonGameAdd: - case skinButtonGameEdit: - case skinButtonGameParams: - case skinButtonGameStart: - case skinButtonGameDelete: - case skinButtonGameAudio: - SknSetState(skinDBP, sknLastOn, sknStateSelected); - SknShowObject(skinDBP, sknLastOn); - if (gPrefs->soundClick) - SndPlaySystemSound(sndClick); - handled = true; - break; - default: - FrmCustomAlert(FrmWarnAlert,"Unknown button !",0,0); - } - SknCloseSkin(skinDBP); - SknSelect(x, y); - } - break; - - case keyDownEvent: - if ( (eventP->data.keyDown.chr >= 'a' && eventP->data.keyDown.chr <= 'z') || - (eventP->data.keyDown.chr >= 'A' && eventP->data.keyDown.chr <= 'Z')) { - if (GamJumpTo(eventP->data.keyDown.chr)) { - SknUpdateList(); - handled = true; - } - } - break; - - default: - handled = PenDownRepeat(); - } - - return handled; -} diff --git a/backends/platform/PalmOS/Src/launcher/forms/formmusic.cpp b/backends/platform/PalmOS/Src/launcher/forms/formmusic.cpp deleted file mode 100644 index 48399efa95..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formmusic.cpp +++ /dev/null @@ -1,388 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> - -#include "start.h" -#include "formTabs.h" -#include "forms.h" -#include "games.h" - -#include "globals.h" - -static TabType *myTabP; -static UInt16 lastTab = 0; - -static GameInfoType *gameInfoP = NULL; - -// Music -static Boolean MusicTabSave() { - ControlType *cck1P, *cck2P; - ListType *list1P, *list2P, *list3P; - FieldType *fld1P; - UInt16 tempo; - FormPtr frmP; - - frmP = FrmGetActiveForm(); - - cck1P = (ControlType *)GetObjectPtr(TabMusicMusicCheckbox); - cck2P = (ControlType *)GetObjectPtr(TabMusicMultiMidiCheckbox); - - list1P = (ListType *)GetObjectPtr(TabMusicDriverList); - list2P = (ListType *)GetObjectPtr(TabMusicRateList); - list3P = (ListType *)GetObjectPtr(TabMusicQualityList); - - fld1P = (FieldType *)GetObjectPtr(TabMusicTempoField); - - tempo = StrAToI(FldGetTextPtr(fld1P)); - if (tempo < 50 || tempo > 200) { - TabSetActive(frmP, myTabP, 0); - FrmSetFocus(frmP, FrmGetObjectIndex(frmP, TabMusicTempoField)); - FrmCustomAlert(FrmErrorAlert, "Invalid tempo value (50...200)", 0, 0); - return false; - } - - gameInfoP->musicInfo.sound.music = CtlGetValue(cck1P); - gameInfoP->musicInfo.sound.multiMidi = CtlGetValue(cck2P); - - gameInfoP->musicInfo.sound.drvMusic = LstGetSelection(list1P); - gameInfoP->musicInfo.sound.rate = LstGetSelection(list2P); - gameInfoP->fmQuality = LstGetSelection(list3P); - gameInfoP->musicInfo.sound.tempo = tempo; - - return true; -} - -static void MusicTabInit() { - ControlType *cck1P, *cck2P; - ListType *list1P, *list2P, *list3P; - FieldType *fld1P; - MemHandle tempoH; - Char *tempoP; - - cck1P = (ControlType *)GetObjectPtr(TabMusicMusicCheckbox); - cck2P = (ControlType *)GetObjectPtr(TabMusicMultiMidiCheckbox); - - list1P = (ListType *)GetObjectPtr(TabMusicDriverList); - list2P = (ListType *)GetObjectPtr(TabMusicRateList); - list3P = (ListType *)GetObjectPtr(TabMusicQualityList); - - fld1P = (FieldType *)GetObjectPtr(TabMusicTempoField); - - CtlSetValue(cck1P, gameInfoP->musicInfo.sound.music); - CtlSetValue(cck2P, gameInfoP->musicInfo.sound.multiMidi); - - if (gameInfoP->musicInfo.sound.drvMusic > 5) - gameInfoP->musicInfo.sound.drvMusic = 0; - - - LstSetSelection(list1P, gameInfoP->musicInfo.sound.drvMusic); - LstSetTopItem(list1P, gameInfoP->musicInfo.sound.drvMusic); - CtlSetLabel((ControlType *)GetObjectPtr(TabMusicDriverPopTrigger), LstGetSelectionText(list1P, LstGetSelection(list1P))); - - LstSetSelection(list2P, gameInfoP->musicInfo.sound.rate); - LstSetTopItem(list2P, gameInfoP->musicInfo.sound.rate); - CtlSetLabel((ControlType *)GetObjectPtr(TabMusicRatePopTrigger), LstGetSelectionText(list2P, LstGetSelection(list2P))); - - LstSetSelection(list3P, gameInfoP->fmQuality); - CtlSetLabel((ControlType *)GetObjectPtr(TabMusicQualityPopTrigger), LstGetSelectionText(list3P, LstGetSelection(list3P))); - - tempoH = MemHandleNew(FldGetMaxChars(fld1P)+1); - tempoP = (Char *)MemHandleLock(tempoH); - StrIToA(tempoP, gameInfoP->musicInfo.sound.tempo); - MemHandleUnlock(tempoH); - FldSetTextHandle(fld1P, tempoH); -} - -// Audio CD -static Boolean AudioCDTabSave() { - ControlType *cck3P; - FieldType *fld2P, *fld3P; - ListType *list1P, *list2P; - UInt16 firstTrack; - FormPtr frmP; - - frmP = FrmGetActiveForm(); - - cck3P = (ControlType *)GetObjectPtr(TabAudioCDMP3Checkbox); - fld2P = (FieldType *)GetObjectPtr(TabAudioCDLengthSecsField); - fld3P = (FieldType *)GetObjectPtr(TabAudioCDFirstTrackField); - list1P = (ListType *)GetObjectPtr(TabAudioCDDriverList); - list2P = (ListType *)GetObjectPtr(TabAudioCDFormatList); - - firstTrack = StrAToI(FldGetTextPtr(fld3P)); - if (firstTrack < 1 || firstTrack > 999) { - TabSetActive(frmP, myTabP, 2); - FrmSetFocus(frmP, FrmGetObjectIndex(frmP, TabAudioCDFirstTrackField)); - FrmCustomAlert(FrmErrorAlert, "Invalid track value (1...999)", 0, 0); - return false; - } - - gameInfoP->musicInfo.sound.CD = CtlGetValue(cck3P); - - gameInfoP->musicInfo.sound.drvCD = LstGetSelection(list1P); - gameInfoP->musicInfo.sound.frtCD = LstGetSelection(list2P); - - gameInfoP->musicInfo.sound.defaultTrackLength = StrAToI(FldGetTextPtr(fld2P)); - gameInfoP->musicInfo.sound.firstTrack = firstTrack; - - return true; -} - -static void AudioCDTabInit() { - ControlType *cck3P; - FieldType *fld2P, *fld3P; - ListType *list1P, *list2P; - MemHandle lengthH, firstTrackH; - Char *lengthP, *firstTrackP; - - cck3P = (ControlType *)GetObjectPtr(TabAudioCDMP3Checkbox); - fld2P = (FieldType *)GetObjectPtr(TabAudioCDLengthSecsField); - fld3P = (FieldType *)GetObjectPtr(TabAudioCDFirstTrackField); - list1P = (ListType *)GetObjectPtr(TabAudioCDDriverList); - list2P = (ListType *)GetObjectPtr(TabAudioCDFormatList); - - LstSetSelection(list1P, gameInfoP->musicInfo.sound.drvCD); - CtlSetLabel((ControlType *)GetObjectPtr(TabAudioCDDriverPopTrigger), LstGetSelectionText(list1P, LstGetSelection(list1P))); - - LstSetSelection(list2P, gameInfoP->musicInfo.sound.frtCD); - CtlSetLabel((ControlType *)GetObjectPtr(TabAudioCDFormatPopTrigger), LstGetSelectionText(list2P, LstGetSelection(list2P))); - - CtlSetValue(cck3P, gameInfoP->musicInfo.sound.CD); - - lengthH = MemHandleNew(FldGetMaxChars(fld2P)+1); - lengthP = (Char *)MemHandleLock(lengthH); - StrIToA(lengthP, gameInfoP->musicInfo.sound.defaultTrackLength); - MemHandleUnlock(lengthH); - FldSetTextHandle(fld2P, lengthH); - - firstTrackH = MemHandleNew(FldGetMaxChars(fld3P)+1); - firstTrackP = (Char *)MemHandleLock(firstTrackH); - StrIToA(firstTrackP, gameInfoP->musicInfo.sound.firstTrack); - MemHandleUnlock(firstTrackH); - FldSetTextHandle(fld3P, firstTrackH); -} - -// Volume -static void VolumeTabSave() { - SliderControlType *slid1P, *slid2P, *slid3P, *slid4P, *slid5P; - - slid1P = (SliderControlType *)GetObjectPtr(TabVolumePalmSliderControl); - slid2P = (SliderControlType *)GetObjectPtr(TabVolumeMusicSliderControl); - slid3P = (SliderControlType *)GetObjectPtr(TabVolumeSfxSliderControl); - slid4P = (SliderControlType *)GetObjectPtr(TabVolumeSpeechSliderControl); - slid5P = (SliderControlType *)GetObjectPtr(TabVolumeAudioCDSliderControl); - - CtlGetSliderValues ((ControlType *)slid1P, 0, 0, 0, &gameInfoP->musicInfo.volume.palm); - CtlGetSliderValues ((ControlType *)slid2P, 0, 0, 0, &gameInfoP->musicInfo.volume.music); - CtlGetSliderValues ((ControlType *)slid3P, 0, 0, 0, &gameInfoP->musicInfo.volume.sfx); - CtlGetSliderValues ((ControlType *)slid4P, 0, 0, 0, &gameInfoP->musicInfo.volume.speech); - CtlGetSliderValues ((ControlType *)slid5P, 0, 0, 0, &gameInfoP->musicInfo.volume.audiocd); -} - -static void VolumeTabInit() { - SliderControlType *slid1P, *slid2P, *slid3P, *slid4P, *slid5P; - UInt16 value; - - slid1P = (SliderControlType *)GetObjectPtr(TabVolumePalmSliderControl); - slid2P = (SliderControlType *)GetObjectPtr(TabVolumeMusicSliderControl); - slid3P = (SliderControlType *)GetObjectPtr(TabVolumeSfxSliderControl); - slid4P = (SliderControlType *)GetObjectPtr(TabVolumeSpeechSliderControl); - slid5P = (SliderControlType *)GetObjectPtr(TabVolumeAudioCDSliderControl); - - value = gameInfoP->musicInfo.volume.palm; - CtlSetSliderValues ((ControlType *)slid1P, 0, 0, 0, &value); - value = gameInfoP->musicInfo.volume.music; - CtlSetSliderValues ((ControlType *)slid2P, 0, 0, 0, &value); - value = gameInfoP->musicInfo.volume.sfx; - CtlSetSliderValues ((ControlType *)slid3P, 0, 0, 0, &value); - value = gameInfoP->musicInfo.volume.speech; - CtlSetSliderValues ((ControlType *)slid4P, 0, 0, 0, &value); - value = gameInfoP->musicInfo.volume.audiocd; - CtlSetSliderValues ((ControlType *)slid5P, 0, 0, 0, &value); -} - -static void MusicFormSave(UInt16 index) { - if (index != dmMaxRecordIndex) { - MemHandle recordH; - GameInfoType *ogameInfoP; - - if (!MusicTabSave()) return; - if (!AudioCDTabSave()) return; - VolumeTabSave(); - - recordH = DmGetRecord(gameDB, index); - ogameInfoP = (GameInfoType *)MemHandleLock(recordH); - DmWrite(ogameInfoP, 0, gameInfoP, sizeof(GameInfoType)); - MemHandleUnlock(recordH); - DmReleaseRecord (gameDB, index, 0); - } - - MemPtrFree(gameInfoP); - gameInfoP = NULL; - - TabDeleteTabs(myTabP); - FrmReturnToMain(); -} -static void MusicFormInit(UInt16 index) { - TabType *tabP; - FormType *frmP = FrmGetActiveForm(); - - if (index != dmMaxRecordIndex) { - MemHandle recordH = NULL; - GameInfoType *ogameInfoP; - - recordH = DmQueryRecord(gameDB, index); - ogameInfoP = (GameInfoType *)MemHandleLock(recordH); - - if (!ogameInfoP) { - FrmCustomAlert(FrmErrorAlert, "An error occurred.",0,0); - return; - } - - gameInfoP = (GameInfoType *)MemPtrNew(sizeof(GameInfoType)); - MemMove(gameInfoP, ogameInfoP, sizeof(GameInfoType)); - MemHandleUnlock(recordH); - - } else { - FrmCustomAlert(FrmWarnAlert, "Select an entry first.",0,0); - FrmReturnToMain(); - return; - } - - tabP = TabNewTabs(3); - TabAddContent(&frmP, tabP, "Sound", TabMusicForm); - TabAddContent(&frmP, tabP, "Volume", TabVolumeForm); - TabAddContent(&frmP, tabP, "Audio CD", TabAudioCDForm); - - MusicTabInit(); - AudioCDTabInit(); - VolumeTabInit(); - - FrmDrawForm(frmP); - TabSetActive(frmP, tabP, lastTab); - - myTabP = tabP; -} - -Boolean MusicFormHandleEvent(EventPtr eventP) { - FormPtr frmP = FrmGetActiveForm(); - Boolean handled = false; - - switch (eventP->eType) { - case frmOpenEvent: - MusicFormInit(GamGetSelected()); - handled = true; - break; - - case frmCloseEvent: - MusicFormSave(dmMaxRecordIndex); - handled = true; - break; - - case ctlSelectEvent: - switch (eventP->data.ctlSelect.controlID) - { - case (MusicForm + 1) : - case (MusicForm + 2) : - case (MusicForm + 3) : - lastTab = (eventP->data.ctlSelect.controlID - MusicForm - 1); - TabSetActive(frmP, myTabP, lastTab); - break; - - case TabMusicDriverPopTrigger: - FrmList(eventP, TabMusicDriverList); - FrmHideObject(frmP, FrmGetObjectIndex(frmP, TabMusicDriverList)); - - if (!OPTIONS_TST(kOptDeviceZodiac) && !OPTIONS_TST(kOptSonyPa1LibAPI)) { - ListType *list1P = (ListType *)GetObjectPtr(TabMusicDriverList); - - if (LstGetSelection(list1P) == 4) { - FrmCustomAlert(FrmInfoAlert, "There is no built-in MIDI support on your device.", 0, 0); - LstSetSelection(list1P, 0); - CtlSetLabel((ControlType *)GetObjectPtr(TabMusicDriverPopTrigger), LstGetSelectionText(list1P, LstGetSelection(list1P))); - } - } - break; - - case TabMusicQualityPopTrigger: - FrmList(eventP, TabMusicQualityList); - FrmHideObject(frmP, FrmGetObjectIndex(frmP, TabMusicQualityList)); - break; - - case TabMusicRatePopTrigger: - FrmList(eventP, TabMusicRateList); - FrmHideObject(frmP, FrmGetObjectIndex(frmP, TabMusicRateList)); - - if (!OPTIONS_TST(kOptPalmSoundAPI)) { - ListType *list1P = (ListType *)GetObjectPtr(TabMusicRateList); - - if (LstGetSelection(list1P) != 0) { - FrmCustomAlert(FrmInfoAlert, "You cannot use this rate on your device.", 0, 0); - LstSetSelection(list1P, 0); - CtlSetLabel((ControlType *)GetObjectPtr(TabMusicRatePopTrigger), LstGetSelectionText(list1P, LstGetSelection(list1P))); - } - } - break; - - case TabAudioCDFormatPopTrigger: - FrmList(eventP, TabAudioCDFormatList); - FrmHideObject(frmP, FrmGetObjectIndex(frmP, TabAudioCDFormatList)); - - if (LstGetSelection((ListPtr)GetObjectPtr(TabAudioCDDriverList)) == 1) { - ListType *list1P = (ListType *)GetObjectPtr(TabAudioCDFormatList); - LstSetSelection(list1P, 0); - CtlSetLabel((ControlType *)GetObjectPtr(TabAudioCDFormatPopTrigger), LstGetSelectionText(list1P, LstGetSelection(list1P))); - } - break; - - case TabAudioCDDriverPopTrigger: - FrmList(eventP, TabAudioCDDriverList); - FrmHideObject(frmP, FrmGetObjectIndex(frmP, TabAudioCDDriverList)); - - if (LstGetSelection((ListPtr)GetObjectPtr(TabAudioCDDriverList)) == 1) { - ListType *list1P = (ListType *)GetObjectPtr(TabAudioCDFormatList); - LstSetSelection(list1P, 0); - CtlSetLabel((ControlType *)GetObjectPtr(TabAudioCDFormatPopTrigger), LstGetSelectionText(list1P, LstGetSelection(list1P))); - } - break; - - case MusicOKButton: - MusicFormSave(GamGetSelected()); - break; - - case MusicCancelButton: - MusicFormSave(dmMaxRecordIndex); - break; - } - handled = true; - break; - - default: - break; - } - - return handled; -} diff --git a/backends/platform/PalmOS/Src/launcher/forms/forms.h b/backends/platform/PalmOS/Src/launcher/forms/forms.h deleted file mode 100644 index ca0089d8c1..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/forms.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __FORMS_H__ -#define __FORMS_H__ - -#include "StarterRsc.h" -#include "formUtil.h" - -#include "formEditGame.h" -#include "formCards.h" - - -#define HANDLER(x) Boolean x##FormHandleEvent(EventPtr eventP); - -HANDLER(Main) -HANDLER(EditGame) -HANDLER(SystemInfo) -HANDLER(Misc) -HANDLER(CardSlot) -HANDLER(Skins) -HANDLER(Music) -HANDLER(Info) -HANDLER(Selector) - -#endif diff --git a/backends/platform/PalmOS/Src/launcher/forms/formtabs.cpp b/backends/platform/PalmOS/Src/launcher/forms/formtabs.cpp deleted file mode 100644 index d3f18e39d7..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formtabs.cpp +++ /dev/null @@ -1,242 +0,0 @@ -#include <PalmOS.h> -#include <CtlGlue.h> -#include <FrmGlue.h> -#include <LstGlue.h> - -#include "globals.h" -#include "formTabs.h" - -TabType *TabNewTabs(UInt16 cnt) { - TabType *newP = new TabType; - - newP->count = 0; - newP->width = 0; - newP->tabs = new TabDataType[cnt]; - - return newP; -} - -void TabMoveUpObject(FormType *frmP, UInt16 objID, Coord amount) { - Coord x, y; - FrmGetObjectPosition(frmP, FrmGetObjectIndex(frmP, objID), &x, &y); - FrmSetObjectPosition(frmP, FrmGetObjectIndex(frmP, objID), x, y - amount); -} - -void TabDeleteTabs(TabType *tabP) { - UInt16 cnt, num; - num = MemPtrSize(tabP->tabs) / sizeof(TabDataType); - - for (cnt = 0; cnt < num; cnt++) - FrmDeleteForm(tabP->tabs[cnt].srcP); - - delete tabP->tabs; - delete tabP; -} - -Err TabAddContent(FormType **frmP, TabType *tabP, const Char *nameP, UInt16 rscID, TabProc *drawFunc) { - FormType *srcP; - UInt16 cnt; - void *objP, **dstP; - UInt16 objNum; - Coord x, y, w, h; - UInt16 id; - RectangleType r; - - dstP = (void **)frmP; - srcP = FrmInitForm(rscID); - - objNum = FrmGetNumberOfObjects(srcP); - - // save tab data - - // it's required to keep to source forms active - // while the tab form is not close for list data ptr (items text) - // TODO : fix this ! - tabP->tabs[tabP->count].srcP = srcP; - tabP->tabs[tabP->count].first = FrmGetObjectId(srcP, 0); - tabP->tabs[tabP->count].last = FrmGetObjectId(srcP, objNum - 1); - tabP->tabs[tabP->count].drawFunc= drawFunc; - tabP->count++; - tabP->active = tabP->count; - - // create tab - FntSetFont(stdFont); - x = 4 + tabP->width; - y = 16; - w = FntCharsWidth(nameP, StrLen(nameP)) + 6; - h = 12; - ControlType *addP = CtlNewControl(dstP, (FrmGetFormId(*frmP) + tabP->count), buttonCtl, nameP, x, y, w, h, stdFont, 0, true); - CtlGlueSetFrameStyle(addP, noButtonFrame); - tabP->width += w + 3; - - // create tab content - for (cnt = 0; cnt < objNum; cnt++) { - objP = FrmGetObjectPtr(srcP, cnt); - id = FrmGetObjectId(srcP, cnt); - FrmGetObjectBounds(srcP, cnt, &r); - x = r.topLeft.x - 2; - y = r.topLeft.y + 30; - w = r.extent.x; - h = r.extent.y; - - FrmSetObjectPosition(srcP, cnt, x, y); - - switch (FrmGetObjectType(srcP, cnt)) { - case frmListObj: { - // HOWTO : to auto link the list to a popup trigger the listID must be popupID + 1 if popup id - // desn't exist the triggerID will be 0 and the list will be shown, but take care to not define - // ListID - 1 object if you want to show the list. - ListType *newP; - Char **itemsP = LstGlueGetItemsText((ListType *)objP); - FontID font = LstGlueGetFont((ListType *)objP); - UInt16 visible = LstGetVisibleItems((ListType *)objP); - UInt16 items = LstGetNumberOfItems((ListType *)objP); - UInt16 trigger = id - 1; - trigger = (FrmGetObjectIndex((FormType *)*dstP, trigger) != frmInvalidObjectId) ? trigger : 0; - - LstNewList(dstP, id, x, y, w, h, font, visible, trigger); - newP = (ListType *)FrmGetObjectPtr((FormType *)*dstP, FrmGetObjectIndex((FormType *)*dstP, id)); - LstSetListChoices(newP, itemsP, items); - FrmHideObject((FormType *)*dstP, FrmGetObjectIndex((FormType *)*dstP, id)); - break; - } - case frmFieldObj: { - FieldAttrType attr; - FontID font = FldGetFont((FieldType *)objP); - UInt16 maxChars = FldGetMaxChars((FieldType *)objP); - FldGetAttributes((FieldType *)objP, &attr); - FldNewField(dstP, id, x, y, w, h, font, maxChars, attr.editable, attr.underlined, attr.singleLine, attr.dynamicSize, (JustificationType)attr.justification, attr.autoShift, attr.hasScrollBar, attr.numeric); - FrmHideObject((FormType *)*dstP, FrmGetObjectIndex((FormType *)*dstP, id)); - break; - } - case frmControlObj: { - const Char *textP = CtlGetLabel((ControlType *)objP); - ControlStyleType style = CtlGlueGetControlStyle((ControlType *)objP); - FontID font = CtlGlueGetFont((ControlType *)objP); - ControlType *newP = CtlNewControl(dstP, id, style, textP, x, y, w, h, font, 0, true); - FrmHideObject((FormType *)*dstP, FrmGetObjectIndex((FormType *)*dstP, id)); - switch (style) { - case sliderCtl: - { - UInt16 min, max, page, val; - CtlGetSliderValues((ControlType *)objP, &min, &max, &page, &val); - CtlSetSliderValues(newP, &min, &max, &page, &val); - break; - } - } - break; - } - case frmLabelObj: { - const Char *textP = FrmGetLabel(srcP, id); - FontID font = FrmGlueGetLabelFont(srcP, id); - FrmNewLabel((FormType **)dstP, id, textP, x, y, font); - FrmHideObject((FormType *)*dstP, FrmGetObjectIndex((FormType *)*dstP, id)); - break; - } - - case frmBitmapObj: { -/* UInt16 family = id + 1; - FrmNewBitmap((FormType **)dstP, id, id, x, y); - //FrmHideObject((FormType *)*dstP, FrmGetObjectIndex((FormType *)*dstP, id)); -*/ break; - } - } - } - - frmP = (FormType **)dstP; // save new form ptr - return errNone; -} - -void TabSetActive(FormType *frmP, TabType *tabP, UInt16 num) { - UInt16 cnt, idx; - RectangleType r; - TabDataPtr dataP; - - if (tabP->active == num) - return; - - dataP = &tabP->tabs[tabP->active]; - - // hide active tab objects - if (tabP->active != tabP->count) { - for (cnt = dataP->first; cnt <= dataP->last; cnt++) { - if ((idx = FrmGetObjectIndex(frmP, cnt)) != frmInvalidObjectId) - FrmHideObject(frmP, idx); - } - } - - // save active tab - tabP->active = num; - dataP = &tabP->tabs[num]; - - // draw tab limit - WinSetForeColor(UIColorGetTableEntryIndex(UIFormFill)); - WinDrawLine(1, 14, 154,14); - WinDrawLine(1, 15, 154,15); - RctSetRectangle(&r, 1, 30, 154, 100); - WinDrawRectangle(&r, 0); - WinSetForeColor(UIColorGetTableEntryIndex(UIObjectFrame)); - WinDrawLine(1, 28, 154,28); - - // set tabs size - for (cnt = 0; cnt < tabP->count; cnt++) { - idx = FrmGetObjectIndex (frmP, (FrmGetFormId(frmP) + cnt + 1)); - - if (idx != frmInvalidObjectId) { - FrmGetObjectBounds(frmP, idx, &r); - r.topLeft.y = (num == cnt) ? 17 : 17; - r.extent.y = (num == cnt) ? 12 : 11; - FrmSetObjectBounds(frmP, idx, &r); - - if (num == cnt) { - RGBColorType yellow = {0,255,192,0}; - - UInt8 line = /*(UIColorGetTableEntryIndex(UIFormFill) == UIColorGetTableEntryIndex(UIFieldTextHighlightBackground)) ? - WinRGBToIndex(&yellow) :*/ - UIColorGetTableEntryIndex(UIFieldTextHighlightBackground); - - r.topLeft.y -= 1; - WinSetForeColor(UIColorGetTableEntryIndex(UIObjectFrame)); - WinDrawRectangleFrame(simpleFrame, &r); - WinSetForeColor(line); - WinDrawLine(r.topLeft.x, r.topLeft.y, r.topLeft.x + r.extent.x - 1, r.topLeft.y); - FrmShowObject(frmP, idx); - - } else { - UInt8 frame = UIColorGetTableEntryIndex(UIObjectFrame); - RGBColorType light; - WinIndexToRGB(frame, &light); - light.r = (255 - light.r) > 72 ? light.r + 72 : 255; - light.g = (255 - light.g) > 72 ? light.g + 72 : 255; - light.b = (255 - light.b) > 72 ? light.b + 72 : 255; - - WinSetForeColor(WinRGBToIndex(&light)); - WinDrawRectangleFrame(simpleFrame, &r); - WinSetForeColor(frame); - WinDrawLine(r.topLeft.x - 1, r.topLeft.y + r.extent.y, r.topLeft.x + r.extent.x, r.topLeft.y + r.extent.y); - } - - // round corner - WinSetForeColor(UIColorGetTableEntryIndex(UIFormFill)); - if (OPTIONS_TST(kOptModeHiDensity)) { - WinSetCoordinateSystem(kCoordinatesNative); - WinDrawPixel((r.topLeft.x - 1) * 2, (r.topLeft.y - 1) * 2); - WinDrawPixel((r.topLeft.x + r.extent.x) * 2 + 1, (r.topLeft.y - 1) * 2); - WinSetCoordinateSystem(kCoordinatesStandard); - - } else { - // TODO - } - } - } - - // show objects - for (cnt = dataP->first; cnt <= dataP->last; cnt++) { - if ((idx = FrmGetObjectIndex(frmP, cnt)) != frmInvalidObjectId) - FrmShowObject(frmP, idx); - } - - // post draw function - if (dataP->drawFunc) - (dataP->drawFunc)(); -} diff --git a/backends/platform/PalmOS/Src/launcher/forms/formtabs.h b/backends/platform/PalmOS/Src/launcher/forms/formtabs.h deleted file mode 100644 index f14c2ff4e4..0000000000 --- a/backends/platform/PalmOS/Src/launcher/forms/formtabs.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __FORMTABS_H__ -#define __FORMTABS_H__ - -typedef void (TabProc)(); - -typedef struct { - FormPtr srcP; - UInt16 first; - UInt16 last; - TabProc *drawFunc; -} TabDataType, *TabDataPtr; - -typedef struct { - UInt16 count, active; - Coord width; - TabDataPtr tabs; -} TabType, *TabPtr; - -TabType *TabNewTabs (UInt16 cnt); -void TabDeleteTabs (TabType *tabP); -Err TabAddContent (FormType **frmP, TabType *tabP, const Char *nameP, UInt16 rscID, TabProc *drawFunc = 0); -void TabSetActive (FormType *frmP, TabType *tabP, UInt16 num); -void TabMoveUpObject (FormType *frmP, UInt16 objID, Coord amount); -#endif diff --git a/backends/platform/PalmOS/Src/launcher/games.cpp b/backends/platform/PalmOS/Src/launcher/games.cpp deleted file mode 100644 index c3f7ef3e4a..0000000000 --- a/backends/platform/PalmOS/Src/launcher/games.cpp +++ /dev/null @@ -1,548 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> -#include <VFSMgr.h> -#include <ctype.h> - -#include "globals.h" -#include "palmdefs.h" -#include "start.h" -#include "games.h" -#include "skin.h" - -#include "StarterRsc.h" - -DmOpenRef gameDB = NULL; - -static Err GamUpdateList() { - if (gameDB) { - UInt16 numRecs = DmNumRecords(gameDB); - - if (numRecs > 0) { - MemHandle tmpH; - UInt32 version, size; - UInt32 *versionP; - - // get record size and version - tmpH = DmQueryRecord(gameDB, 0); - size = MemHandleSize(tmpH); - versionP = (UInt32 *)MemHandleLock(tmpH); - version = *versionP; - MemHandleUnlock(tmpH); - - // check record - if (version != curItemVersion || size != sizeof(GameInfoType)) { - UInt16 index; - GameInfoType gitCur; - void *tmpP; - FormPtr ofmP, frmP; - - // show dialog - ofmP = FrmGetActiveForm(); - frmP = FrmInitForm(ConvertForm); - FrmSetActiveForm(frmP); - FrmDrawForm(frmP); - SysTaskDelay(1 * SysTicksPerSecond()); - - MemSet(&gitCur, sizeof(GameInfoType), 0); - - if (version == itemVersion_357 || - version == itemVersion_356 || - version == itemVersion_355 || - version == itemVersion_354 || - version == itemVersion_353 || - version == itemVersion_352 || - version == itemVersion_351 || - version == itemVersion_350 || - version == itemVersion_340 || - version == itemVersion_330 || - version == itemVersion_320 || - version == itemVersion_310 || - version == itemVersion_300 || - version == itemVersion_270 || - version == itemVersion_260 || - version == itemVersion_250) { - for (index = 0; index < numRecs; index++) { - // get old data - tmpH = DmQueryRecord(gameDB, index); - tmpP = MemHandleLock(tmpH); - MemMove(&gitCur, tmpP, MemHandleSize(tmpH)); - MemHandleUnlock(tmpH); - - // new format - gitCur.version = curItemVersion; - - if (version < itemVersion_300) { - gitCur.musicInfo.volume.palm = 50; - gitCur.musicInfo.volume.music = 192; - gitCur.musicInfo.volume.sfx = 192; - gitCur.musicInfo.volume.speech = 192; - gitCur.musicInfo.volume.audiocd = 50; - - gitCur.musicInfo.sound.tempo = 100; - gitCur.musicInfo.sound.defaultTrackLength = 10; - gitCur.musicInfo.sound.firstTrack = 1; - } - - if (version < itemVersion_310) - gitCur.engine = 0; - - if (version < itemVersion_320) - gitCur.renderMode = 0; - - if (version <= itemVersion_330) { - gitCur.fmQuality = 0; - gitCur.gfxMode = (gitCur.gfxMode == 3 ? 1 : 0); // v3.4 only 2 modes - - if (gitCur.engine == 0) gitCur.engine = 8; - else if (gitCur.engine == 1) gitCur.engine = 7; - else if (gitCur.engine == 2) gitCur.engine = 3; - else if (gitCur.engine == 3) gitCur.engine = 1; - else if (gitCur.engine == 4) gitCur.engine = 0; - else if (gitCur.engine == 5) gitCur.engine = 6; - else if (gitCur.engine == 6) gitCur.engine = 4; - else if (gitCur.engine == 7) gitCur.engine = 5; - else if (gitCur.engine == 8) gitCur.engine = 2; - - if (gitCur.renderMode == 1) gitCur.renderMode = 4; - else if (gitCur.renderMode == 2) gitCur.renderMode = 5; - else if (gitCur.renderMode == 3) gitCur.renderMode = 2; - else if (gitCur.renderMode == 4) gitCur.renderMode = 3; - else if (gitCur.renderMode == 5) gitCur.renderMode = 1; - - if (gitCur.platform == 2) gitCur.platform = 6; - else if (gitCur.platform == 5) gitCur.platform = 8; - else if (gitCur.platform == 6) gitCur.platform = 2; - - if (gitCur.language == 1) gitCur.language = 4; - else if (gitCur.language == 2) gitCur.language = 6; - else if (gitCur.language == 3) gitCur.language = 5; - else if (gitCur.language == 4) gitCur.language = 8; - else if (gitCur.language == 5) gitCur.language = 11; - else if (gitCur.language == 6) gitCur.language = 13; - else if (gitCur.language == 7) gitCur.language = 9; - else if (gitCur.language == 8) gitCur.language = 1; - else if (gitCur.language == 9) gitCur.language = 10; - else if (gitCur.language == 10) gitCur.language = 7; - else if (gitCur.language == 11) gitCur.language = 12; - else if (gitCur.language == 12) gitCur.language = 2; - else if (gitCur.language == 13) gitCur.language = 3; - - if (gitCur.musicInfo.sound.drvMusic == 1) gitCur.musicInfo.sound.drvMusic = 4; - else if (gitCur.musicInfo.sound.drvMusic == 2) gitCur.musicInfo.sound.drvMusic = 5; - else if (gitCur.musicInfo.sound.drvMusic == 4) gitCur.musicInfo.sound.drvMusic = 2; - else if (gitCur.musicInfo.sound.drvMusic == 5) gitCur.musicInfo.sound.drvMusic = 1; - } - - if (version <= itemVersion_340) { - gitCur.platform++; - - if (gitCur.language == 3) - gitCur.language = 0; - else if (gitCur.language >= 11) - gitCur.language++; - } - - if (version <= itemVersion_350) - if (gitCur.platform >= 9) - gitCur.platform++; - - if (version <= itemVersion_351) { - if (gitCur.engine >= ENGINE_LURE) // newly added engine - gitCur.engine++; - - if (gitCur.engine == ENGINE_SCUMM) // reorder - gitCur.engine = ENGINE_AGOS; - else if (gitCur.engine == ENGINE_AGOS) - gitCur.engine = ENGINE_SCUMM; - } - - if (version <= itemVersion_352) { - if (gitCur.engine >= ENGINE_CINE) // newly added engine - gitCur.engine++; - - gitCur.platform++; - } - - if (version <= itemVersion_353) - gitCur.musicInfo.sound.drvMusic++; - - if (version <= itemVersion_354) - if (gitCur.engine >= ENGINE_AGI) // newly added engine - gitCur.engine++; - - if (version <= itemVersion_355) { - gitCur.engine++; // renamed Simon -> AGOS - if (gitCur.engine == ENGINE_COUNT) - gitCur.engine = ENGINE_AGOS; - } - - if (version <= itemVersion_356) { - if (gitCur.platform >= 3) - gitCur.platform++; - } - - if (version <= itemVersion_357) - if (gitCur.engine >= ENGINE_PARALLACTION) // newly added engine - gitCur.engine++; - - if (gitCur.musicInfo.volume.palm > 100) - gitCur.musicInfo.volume.palm = 50; - - // simply resize the old record - tmpH = DmResizeRecord(gameDB, index, sizeof(GameInfoType)); // TODO : check error on resize tmpH==NULL - tmpP = MemHandleLock(tmpH); - DmWrite(tmpP, 0, &gitCur, sizeof(GameInfoType)); - MemPtrUnlock(tmpP); - } - - } else if (version == itemVersion_200) { - // need conversion from V2 -> V3.5.2 - GameInfoTypeV2 git0; - - for (index = 0; index < numRecs; index++) { - - // get old data - tmpH = DmQueryRecord(gameDB, index); - tmpP = MemHandleLock(tmpH); - MemMove(&git0, tmpP, sizeof(GameInfoTypeV2)); - MemHandleUnlock(tmpH); - - // convert to new format - gitCur.version = curItemVersion; - gitCur.icnID = 0xFFFF; - gitCur.selected = git0.selected; - StrCopy(gitCur.nameP, git0.nameP); - StrCopy(gitCur.pathP, git0.pathP); - StrCopy(gitCur.gameP, git0.gameP); - gitCur.gfxMode = (git0.gfxMode == 3 ? 1 : 0); // v3.4 only 2 modes - - gitCur.autoLoad = git0.autoLoad; - gitCur.bootParam = git0.bootParam; - gitCur.setPlatform = git0.setPlatform; - gitCur.subtitles = git0.subtitles; - gitCur.talkSpeed = git0.talkSpeed; - - gitCur.loadSlot = git0.loadSlot; - gitCur.bootValue = git0.bootValue; - gitCur.talkValue = git0.talkValue; - gitCur.platform = git0.platform; - gitCur.language = git0.language; - - gitCur.musicInfo.volume.palm = 50; - gitCur.musicInfo.volume.music = 192; - gitCur.musicInfo.volume.sfx = 192; - gitCur.musicInfo.volume.speech = 192; - gitCur.musicInfo.volume.audiocd = 50; - - gitCur.musicInfo.sound.tempo = 100; - gitCur.musicInfo.sound.defaultTrackLength = 10; - gitCur.musicInfo.sound.firstTrack = 1; - - // to V3.4 - if (gitCur.platform == 2) gitCur.platform = 6; - else if (gitCur.platform == 5) gitCur.platform = 8; - else if (gitCur.platform == 6) gitCur.platform = 2; - - if (gitCur.language == 1) gitCur.language = 4; - else if (gitCur.language == 2) gitCur.language = 6; - else if (gitCur.language == 3) gitCur.language = 5; - else if (gitCur.language == 4) gitCur.language = 8; - else if (gitCur.language == 5) gitCur.language = 11; - else if (gitCur.language == 6) gitCur.language = 13; - else if (gitCur.language == 7) gitCur.language = 9; - else if (gitCur.language == 8) gitCur.language = 1; - else if (gitCur.language == 9) gitCur.language = 10; - else if (gitCur.language == 10) gitCur.language = 7; - else if (gitCur.language == 11) gitCur.language = 12; - else if (gitCur.language == 12) gitCur.language = 2; - else if (gitCur.language == 13) gitCur.language = 3; - - if (gitCur.musicInfo.sound.drvMusic == 1) gitCur.musicInfo.sound.drvMusic = 4; - else if (gitCur.musicInfo.sound.drvMusic == 2) gitCur.musicInfo.sound.drvMusic = 5; - else if (gitCur.musicInfo.sound.drvMusic == 4) gitCur.musicInfo.sound.drvMusic = 2; - else if (gitCur.musicInfo.sound.drvMusic == 5) gitCur.musicInfo.sound.drvMusic = 1; - - // to V3.5 - gitCur.platform++; - - if (gitCur.language == 3) - gitCur.language = 0; - else if (gitCur.language >= 11) - gitCur.language++; - - // to V3.5.1 - if (gitCur.platform >= 9) - gitCur.platform++; - - //to V3.5.3 - gitCur.musicInfo.sound.drvMusic++; - - // ----- - gitCur.engine = ENGINE_SCUMM; - - tmpH = DmResizeRecord(gameDB, index, sizeof(GameInfoType)); // TODO : check error on resize tmpH==NULL - tmpP = MemHandleLock(tmpH); - DmWrite(tmpP, 0, &gitCur, sizeof(GameInfoType)); - MemPtrUnlock(tmpP); - } - } else { - // need conversion from V0 -> V3.5.2 - GameInfoTypeV0 git0; - - for (index = 0; index < numRecs; index++) { - - // get old data - tmpH = DmQueryRecord(gameDB, index); - tmpP = MemHandleLock(tmpH); - MemMove(&git0, tmpP, sizeof(GameInfoTypeV0)); - MemHandleUnlock(tmpH); - - // convert to new format - gitCur.version = curItemVersion; - gitCur.icnID = 0xFFFF; - gitCur.selected = git0.selected; - StrCopy(gitCur.nameP, git0.nameP); - StrCopy(gitCur.pathP, git0.pathP); - StrCopy(gitCur.gameP, git0.gameP); - gitCur.gfxMode = (git0.gfxMode == 3 ? 1 : 0); // v3.4 only 2 modes - - gitCur.autoLoad = git0.autoLoad; - gitCur.bootParam = git0.bootParam; - gitCur.setPlatform = git0.amiga; // amiga become platform amiga/atari-st/machintosh - gitCur.platform = 1; - gitCur.subtitles = git0.subtitles; - gitCur.talkSpeed = git0.talkSpeed; - - gitCur.loadSlot = git0.loadSlot; - gitCur.bootValue = git0.bootValue; - gitCur.talkValue = git0.talkValue; - gitCur.platform = 2; // default to amiga - gitCur.language = git0.language; - - gitCur.musicInfo.volume.palm = 50; - gitCur.musicInfo.volume.music = 192; - gitCur.musicInfo.volume.sfx = 192; - gitCur.musicInfo.volume.speech = 192; - gitCur.musicInfo.volume.audiocd = 50; - - gitCur.musicInfo.sound.tempo = 100; - gitCur.musicInfo.sound.defaultTrackLength = 10; - gitCur.musicInfo.sound.firstTrack = 1; - - gitCur.engine = ENGINE_SCUMM; - - tmpH = DmResizeRecord(gameDB, index, sizeof(GameInfoType)); // TODO : check error on resize tmpH==NULL - tmpP = MemHandleLock(tmpH); - DmWrite(tmpP, 0, &gitCur, sizeof(GameInfoType)); - MemPtrUnlock(tmpP); - } - } - - FrmEraseForm(frmP); - FrmDeleteForm(frmP); - if (ofmP) - FrmSetActiveForm(ofmP); - } - } - } - - return errNone; -} - -Err GamOpenDatabase() { - Err err = errNone; - - gameDB = DmOpenDatabaseByTypeCreator( 'DATA', appFileCreator, dmModeReadWrite); - - if (!gameDB) { - err = DmCreateDatabase(0, "ScummVM-Data", appFileCreator, 'DATA', false); - if (!err) { - gameDB = DmOpenDatabaseByTypeCreator( 'DATA', appFileCreator, dmModeReadWrite); - - if (!gameDB) - err = DmGetLastErr(); - } - } - - if (err) - FrmCustomAlert(FrmErrorAlert,"Cannot open/create games list DB !",0,0); - else - err = GamUpdateList(); - - return err; -} - -void GamImportDatabase() { - if (gPrefs->card.volRefNum != vfsInvalidVolRef && gPrefs->card.moveDB) { - FileRef file; - Err e; - - e = VFSFileOpen(gPrefs->card.volRefNum, "/Palm/Programs/ScummVM/listdata.pdb", vfsModeRead, &file); - if (!e) { - UInt16 oCardNo, nCardNo; - LocalID oDbID, nDbID; - - VFSFileClose(file); - if (gPrefs->card.confirmMoveDB) - if (FrmCustomAlert(FrmConfirmAlert, "Do you want to import games database from memory card ?", 0, 0) == FrmConfirmNo) { - // prevent to replace the file on memory card - gPrefs->card.moveDB = false; - return; - } - - // get current db info and rename it - DmOpenDatabaseInfo(gameDB, &oDbID, 0, 0, &oCardNo, 0); - GamCloseDatabase(true); - e = DmDeleteDatabase(oCardNo, oDbID); - - if (!e) - if (e = VFSImportDatabaseFromFile(gPrefs->card.volRefNum, "/Palm/Programs/ScummVM/listdata.pdb", &nCardNo, &nDbID)) - FrmCustomAlert(FrmErrorAlert, "Failed to import games database from memory card.", 0, 0); - - GamOpenDatabase(); - } - } -} - -void GamCloseDatabase(Boolean ignoreCardParams) { - if (gameDB) { - LocalID dbID; - UInt16 cardNo; - - DmOpenDatabaseInfo(gameDB, &dbID, 0, 0, &cardNo, 0); - DmCloseDatabase(gameDB); - - if (!ignoreCardParams) { - if (gPrefs->card.moveDB && gPrefs->card.volRefNum != vfsInvalidVolRef) { - VFSFileRename(gPrefs->card.volRefNum, "/Palm/Programs/ScummVM/listdata.pdb", "listdata-old.pdb"); - Err e = VFSExportDatabaseToFile(gPrefs->card.volRefNum, "/Palm/Programs/ScummVM/listdata.pdb", cardNo, dbID); - if (!e) { - VFSFileDelete(gPrefs->card.volRefNum, "/Palm/Programs/ScummVM/listdata-old.pdb"); - if (gPrefs->card.deleteDB) - DmDeleteDatabase(cardNo, dbID); - } else { - VFSFileRename(gPrefs->card.volRefNum, "/Palm/Programs/ScummVM/listdata-old.pdb", "listdata.pdb"); - } - } - } - } - gameDB = NULL; -} - -static Int16 GamCompare(GameInfoType *a, GameInfoType *b, SortRecordInfoPtr, SortRecordInfoPtr, MemHandle) { - return StrCaselessCompare(a->nameP, b->nameP); -} - -Err GamSortList() { - return DmQuickSort (gameDB, (DmComparF *)GamCompare, 0); -} - -void GamUnselect() { - GameInfoType *game; - - MemHandle recordH; - UInt16 index; - - index = GamGetSelected(); - - if (index != dmMaxRecordIndex) { - Boolean newValue; - - recordH = DmGetRecord(gameDB, index); - game = (GameInfoType *)MemHandleLock(recordH); - - newValue = false; - DmWrite(game, OffsetOf(GameInfoType,selected), &newValue, sizeof(Boolean)); - - MemHandleUnlock(recordH); - DmReleaseRecord (gameDB, index, 0); - } -} - -UInt16 GamGetSelected() { - MemHandle record; - GameInfoType *game; - Boolean selected; - UInt16 index = DmNumRecords(gameDB)-1; - - while (index != (UInt16)-1) { - record = DmQueryRecord(gameDB, index); - game = (GameInfoType *)MemHandleLock(record); - selected = game->selected; - MemHandleUnlock(record); - - if (selected) - return index; - - index--; - } - - return dmMaxRecordIndex; -} - -Boolean GamJumpTo(Char letter) { - MemHandle record; - GameInfoType *game; - Boolean found = false; - UInt16 index = 0; - UInt16 maxIndex = DmNumRecords(gameDB); - UInt16 active = GamGetSelected(); - - while (index < maxIndex) { - record = DmGetRecord(gameDB, index); - game = (GameInfoType *)MemHandleLock(record); - - if (tolower(game->nameP[0]) == tolower(letter)) { - found = true; - - if (index != active) { - RectangleType rArea; - UInt16 maxView; - Boolean newValue = true; - - SknGetListBounds(&rArea, NULL); - maxView = rArea.extent.y / sknInfoListItemSize; - - GamUnselect(); - DmWrite(game, OffsetOf(GameInfoType,selected), &newValue, sizeof(Boolean)); - - if (index < gPrefs->listPosition || index >= (gPrefs->listPosition + maxView)) - gPrefs->listPosition = index; - } - } - - MemHandleUnlock(record); - DmReleaseRecord (gameDB, index, 0); - - index++; - - if (found) - return found; - } - - return found; -} diff --git a/backends/platform/PalmOS/Src/launcher/games.h b/backends/platform/PalmOS/Src/launcher/games.h deleted file mode 100644 index 7c381a40f4..0000000000 --- a/backends/platform/PalmOS/Src/launcher/games.h +++ /dev/null @@ -1,212 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef __GAMES_H__ -#define __GAMES_H__ - -#define curItemVersion sysMakeROMVersion(3,5,8,0,0) // Parallaction engine - - -#define itemVersion_357 sysMakeROMVersion(3,5,7,0,0) // Added : Apple IIgs -#define itemVersion_356 sysMakeROMVersion(3,5,6,0,0) // Changed : Simon -> AGOS -#define itemVersion_355 sysMakeROMVersion(3,5,5,0,0) // Added : AGI engine -#define itemVersion_354 sysMakeROMVersion(3,5,4,0,0) // Added : Default/Auto music driver -#define itemVersion_353 sysMakeROMVersion(3,5,3,0,0) // Added : CinE engine and 3DO platform -#define itemVersion_352 sysMakeROMVersion(3,5,2,0,0) // Added : Lure engine -#define itemVersion_351 sysMakeROMVersion(3,5,1,0,0) // Added : Sega CD platform -#define itemVersion_350 sysMakeROMVersion(3,5,0,0,0) -#define itemVersion_340 sysMakeROMVersion(3,4,0,0,0) -#define itemVersion_330 sysMakeROMVersion(3,3,0,0,0) -#define itemVersion_320 sysMakeROMVersion(3,2,0,0,0) -#define itemVersion_310 sysMakeROMVersion(3,1,0,0,0) -#define itemVersion_300 sysMakeROMVersion(3,0,0,0,0) -#define itemVersion_270 sysMakeROMVersion(2,7,0,0,0) -#define itemVersion_260 sysMakeROMVersion(2,6,0,0,0) -#define itemVersion_250 sysMakeROMVersion(2,5,0,0,0) -#define itemVersion_200 sysMakeROMVersion(2,0,0,0,0) - -// old config structs -typedef struct { - UInt32 version; - UInt16 icnID; // icon to display on the list - Boolean selected; - - Char nameP[50]; // game name to display in list - Char pathP[150]; // path to the game files - Char gameP[10]; // scumm name of the game - UInt16 gfxMode; - - Boolean autoLoad; - UInt16 loadSlot; - Boolean bootParam; - UInt16 bootValue; - Boolean amiga; - Boolean subtitles; - Boolean talkSpeed; - UInt16 talkValue; - UInt8 language; - -} GameInfoTypeV0; - -typedef struct { - UInt32 version; - UInt16 icnID; // icon to display on the list - Boolean selected; - - Char nameP[50]; // game name to display in list - Char pathP[150]; // path to the game files - Char gameP[10]; // scumm name of the game - UInt16 gfxMode; - - Boolean autoLoad; - Boolean bootParam; - Boolean setPlatform; - Boolean subtitles; - Boolean talkSpeed; - - UInt16 loadSlot; - UInt16 bootValue; - UInt16 talkValue; - UInt8 platform; - UInt8 language; - -} GameInfoTypeV2; - - -// Current config -typedef struct { - struct { - UInt16 palm; - UInt16 music; - UInt16 sfx; // TODO : remove - UInt16 speech; - UInt16 audiocd; - } volume; - - struct { - // midi - Boolean multiMidi; - Boolean music; // TODO : rename this, it is enable audio option - UInt8 drvMusic; - UInt8 tempo; - // sound FX - Boolean sfx; // TODO : remove this - UInt8 rate; - // CD audio - Boolean CD; - UInt8 drvCD, frtCD; - UInt16 defaultTrackLength; - UInt16 firstTrack; - } sound; -} MusicInfoType; - -typedef struct { - UInt32 version; - UInt16 icnID; // icon to display on the list - Boolean selected; - - Char nameP[50]; // game name to display in list - Char pathP[150]; // path to the game files - Char gameP[15]; // scumm name of the game - UInt16 gfxMode; - - Boolean autoLoad; - Boolean bootParam; - Boolean setPlatform; - Boolean subtitles; - Boolean talkSpeed; - - UInt16 loadSlot; - UInt16 bootValue; - UInt16 talkValue; - UInt8 platform; - UInt8 language; // |- v2.5 - - Boolean filter; // v2.6 - Boolean fullscreen; // | - Boolean aspectRatio; // |- v2.7 - - MusicInfoType musicInfo;// v3.0 - - UInt8 engine; // |- v3.1 - UInt8 renderMode; // |- v3.2 -// Boolean use16Bit; // |- v3.3 // removed - UInt8 fmQuality; // |- v3.4 // replace use16Bit -} GameInfoType; - -enum { - ENGINE_AGOS = 0, - ENGINE_SKY, - ENGINE_SWORD1, - ENGINE_SWORD2, - ENGINE_CINE, - ENGINE_QUEEN, - ENGINE_LURE, - ENGINE_GOB, - ENGINE_KYRA, - ENGINE_PARALLACTION, - ENGINE_SAGA, - ENGINE_SCUMM, - ENGINE_AGI, - ENGINE_TOUCHE, - ENGINE_CRUISE, - ENGINE_DRASCULA, - ENGINE_COUNT -}; - -static const struct { - const char *fileP; - const char *nameP; -} engines[] = { - { "agos", "AGOS Engine" }, - { "sky", "Beneath a Steel Sky" }, - { "sword1", "Broken Sword I" }, - { "sword2", "Broken Sword II" }, - { "cine", "Delphine Cinematique v1.0" }, - { "queen", "Flight of the Amazon Queen" }, - { "lure", "Lure of the Tempress" }, - { "gob", "Gobliiins, Bargon Attack and more" }, - { "kyra", "Kyrandia" }, - { "parallaction", "Parallaction" }, - { "saga", "SAGA Engine" }, - { "scumm", "Scumm Games" }, - { "agi", "Sierra AGI" }, - { "touche", "Touche: The Adventures of the Fifth Musketeer" }, - { "cruise", "Beta -> Cruise for a Corpse" }, - { "drascula", "Beta -> Drascula" }, -}; - -// protos -Err GamOpenDatabase (); -void GamImportDatabase (); -void GamCloseDatabase (Boolean ignoreCardParams); -Err GamSortList (); -UInt16 GamGetSelected (); -void GamUnselect (); -Boolean GamJumpTo (Char letter); - -extern DmOpenRef gameDB; - -#endif diff --git a/backends/platform/PalmOS/Src/launcher/launch.cpp b/backends/platform/PalmOS/Src/launcher/launch.cpp deleted file mode 100644 index d83a34e94c..0000000000 --- a/backends/platform/PalmOS/Src/launcher/launch.cpp +++ /dev/null @@ -1,512 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> -#include <PmPalmOSNVFS.h> -#include "StarterRsc.h" - -#include "games.h" -#include "start.h" -#include "rumble.h" -#include "globals.h" -#include "features.h" -#include "formUtil.h" -#include "formCards.h" -#include "palmdefs.h" - -#include "init_palmos.h" -#include "init_stuffs.h" - -#include "modules.h" -#include "args.h" - - -#define BUILD_ERROR(m) \ - { StrCopy(msg, m); \ - StrCat(msg, "\n\nPlease check that all required files are installed on your card, and you have enough free storage memory."); \ - goto onError; } - -#define BUILD_FILE(h,m) \ - StrCopy(filename, "/Palm/Programs/ScummVM/Mods/"); \ - StrCat(filename, h); \ - StrCat(filename, m); - -#define FIND_FILE() \ - if (*volRefNum == vfsInvalidVolRef) \ - *volRefNum = ModFind(filename); - - -#define CHECK_FILE(m) \ - e = VFSFileOpen(*volRefNum, filename, vfsModeRead, &file); \ - if (e) \ - BUILD_ERROR(m) \ - else \ - VFSFileClose(file); - -#define IMPRT_FILE(m) \ - e = VFSImportDatabaseFromFile(*volRefNum, filename, &cardNo, &dbID); \ - if (e) \ - BUILD_ERROR(m) - -#define DELET_FILE(f) \ - del_dbID = DmFindDatabase(0, f); \ - if (del_dbID) \ - DmDeleteDatabase(0, del_dbID); - -void ModDelete() { - LocalID del_dbID; - - DELET_FILE("Glbs::Common"); - DELET_FILE("Glbs::Engine"); - DELET_FILE("ScummVM-Engine"); -} - -UInt16 ModFind(const Char *f) { - Err e; - UInt16 volRefNum; - FileRef r; - UInt32 volIterator = vfsIteratorStart|vfsIncludePrivateVolumes; - while (volIterator != vfsIteratorStop) { - e = VFSVolumeEnumerate(&volRefNum, &volIterator); - - if (!e) e = VFSFileOpen(volRefNum, f, vfsModeRead, &r); - if (!e) e = VFSFileClose(r); - if (!e) break; - } - - return volRefNum; -} - -static void ModSetStack(UInt32 newSize, UInt16 cardNo, LocalID dbID) { - DmOpenRef dbRef = DmOpenDatabase(cardNo, dbID, dmModeReadWrite); - - if (dbRef) { - MemHandle pref = DmGetResource('pref',0); - UInt32 size = 0; - - if (pref) { - SysAppPrefsType *data = (SysAppPrefsType *)MemHandleLock(pref); - size = data->stackSize; - - if (newSize) { - SysAppPrefsType newData; - MemMove(&newData, data, sizeof(SysAppPrefsType)); - newData.stackSize = newSize; - DmWrite(data, 0, &newData, sizeof(SysAppPrefsType)); - } - - MemPtrUnlock(data); - DmReleaseResource(pref); - } - - DmCloseDatabase(dbRef); - } -} - -static Err ModImport(UInt16 *volRefNum, UInt8 engine, Boolean *armP) { -#ifndef _DEBUG_ENGINE - char filename[256]; - UInt16 cardNo; - LocalID dbID; - UInt32 result; - FileRef file; -#endif - char msg[256]; - FormPtr ofmP, frmP; - Err e = errNone; - - ofmP = FrmGetActiveForm(); - frmP = FrmInitForm(ImportForm); - FrmSetActiveForm(frmP); - FrmDrawForm(frmP); - - // In debug mode, the engine files are directly uploaded to the simulator -#ifndef _DEBUG_ENGINE - // engine file ? - BUILD_FILE(engines[engine].fileP, ".engine"); - FIND_FILE (); - CHECK_FILE("ScummVM engine file was not found !"); - IMPRT_FILE("Cannot import engine file !"); - - // need more files ? - dbID = DmFindDatabase(0, "ScummVM-Engine"); // be sure to have the correct dbID - e = SysAppLaunch(cardNo, dbID, 0, sysAppLaunchCustomEngineGetInfo, 0, &result); - *armP = ((result & GET_MODEARM) == GET_MODEARM); - -/* ARM ONLY FOR NOW, NOT REQUIRED - // common file ? - if (!e && (result & GET_DATACOMMON)) { - BUILD_FILE("common", ".data"); - CHECK_FILE("Common data file was not found !"); - IMPRT_FILE("Cannot import common data file !"); - } - // data file ? - if (!e && (result & GET_DATAENGINE)) { - BUILD_FILE(engines[engine].fileP, ".data"); - CHECK_FILE("Engine data file was not found !"); - IMPRT_FILE("Cannot import engine data file !"); - } -*/ -#endif - // if error, cleanup - if (e) ModDelete(); - -onError: - FrmEraseForm(frmP); - FrmDeleteForm(frmP); - if (e) { - if (ofmP) FrmSetActiveForm(ofmP); - FrmCustomAlert(FrmErrorAlert, msg, 0, 0); - } - - return e; -} - -#undef DELET_FILE -#undef CHECK_FILE -#undef BUILD_FILE - -Boolean StartScummVM(Int16 engine) { - Char **argvP; - UInt8 lightspeed, argc = 0; - UInt32 stackSize; - Boolean toLauncher, direct, isARM; - Char num[6]; - - argvP = ArgsInit(); - direct = false; - - // start command line (exec name) - ArgsAdd(&argvP[argc], "-", NULL, &argc); - // standard path - ArgsAdd(&argvP[argc], "--themepath=", "/PALM/Programs/ScummVM/Themes", &argc); - - UInt16 index = GamGetSelected(); - // no game selected - if (index == dmMaxRecordIndex) { - if (engine == NO_ENGINE) { - // free args - ArgsFree(argvP); - return false; - } - - // default values - if (bDirectMode) - gPrefs->card.volRefNum = parseCards(); // always use the first removable card available (?) - - gVars->filter = true; - gVars->palmVolume = 50; - gVars->fmQuality = FM_QUALITY_INI; - direct = true; - - // somthing selected - } else { - Char pathP[256]; - MemHandle recordH; - GameInfoType *gameInfoP; - - recordH = DmQueryRecord(gameDB,index); - gameInfoP = (GameInfoType *)MemHandleLock(recordH); - engine = gameInfoP->engine; - - // build path - StrCopy(pathP,"/Palm/Programs/ScummVM/Games/"); - if (gameInfoP->pathP[0] == '/') - StrCopy(pathP, gameInfoP->pathP); - else if (!(gameInfoP->pathP[0] == '.' && StrLen(gameInfoP->pathP) == 1)) - StrCat(pathP, gameInfoP->pathP); - - // path - ArgsAdd(&argvP[argc], "-p", pathP, &argc); - - // language - if (gameInfoP->language > 0) { - const Char *lang = "zh\0cz\0gb\0en\0fr\0de\0hb\0it\0jp\0kr\0pl\0pt\0ru\0es\0se\0"; - ArgsAdd(&argvP[argc], "-q", (lang + (gameInfoP->language - 1) * 3), &argc); - } - - // fullscreen ? - if (gameInfoP->fullscreen) - ArgsAdd(&argvP[argc], "-f", NULL, &argc); - - // aspect-ratio ? - ArgsAdd(&argvP[argc], (gameInfoP->aspectRatio ? "--aspect-ratio" : "--no-aspect-ratio"), NULL, &argc); - - // gfx mode - gVars->filter = gameInfoP->filter; - - switch (gameInfoP->renderMode) { - case 1: - ArgsAdd(&argvP[argc], "--render-mode=", "amiga", &argc); - break; - case 2: - ArgsAdd(&argvP[argc], "--render-mode=", "cga", &argc); - break; - case 3: - ArgsAdd(&argvP[argc], "--render-mode=", "ega", &argc); - break; - case 4: - ArgsAdd(&argvP[argc], "--render-mode=", "hercAmber", &argc); - break; - case 5: - ArgsAdd(&argvP[argc], "--render-mode=", "hercGreen", &argc); - break; - } - - switch (gameInfoP->gfxMode) { - case 1: - ArgsAdd(&argvP[argc], "-g", "wide", &argc); - break; - default: - ArgsAdd(&argvP[argc], "-g", "1x", &argc); - break; - } - - // load state - if (gameInfoP->autoLoad) { - StrIToA(num, gameInfoP->loadSlot); - ArgsAdd(&argvP[argc], "-x", num, &argc); - } - // boot script parameter - if (gameInfoP->bootParam) { - StrIToA(num, gameInfoP->bootValue); - ArgsAdd(&argvP[argc], "-b", num, &argc); - } - // not a PC version - if (gameInfoP->setPlatform) { - static const char *platform[] = { - "3do", - "acorn", - "amiga", - "2gs", - "atari", - "c64", - "pc", - "fmtowns", - "linux", - "mac", - "nes", - "segacd", - "windows" - }; - ArgsAdd(&argvP[argc], "--platform=", platform[gameInfoP->platform], &argc); - } - - // subtitles - if (gameInfoP->subtitles) - ArgsAdd(&argvP[argc], "-n", NULL, &argc); - - // multi midi ? - if (gameInfoP->musicInfo.sound.multiMidi) - ArgsAdd(&argvP[argc], "--multi-midi", NULL, &argc); - - if (engine == ENGINE_SCUMM) { - // music tempo - StrIToA(num, gameInfoP->musicInfo.sound.tempo); - ArgsAdd(&argvP[argc], "--tempo=", num, &argc); - } - - // talk speed - if (gameInfoP->talkSpeed) { - StrIToA(num, gameInfoP->talkValue); - ArgsAdd(&argvP[argc], "--talkspeed=", num, &argc); - } - - // music driver - if (gameInfoP->musicInfo.sound.music) { - static char *drv[] = { - "auto", - "null", - "adlib", - "towns", - "pcjr", - "native", - "pcspk" - }; - - if (StrCompare(drv[gameInfoP->musicInfo.sound.drvMusic], "native") == 0) { - if (OPTIONS_TST(kOptDeviceZodiac)) - ArgsAdd(&argvP[argc], "-e", "zodiac", &argc); // Tapwave Zodiac - else if (OPTIONS_TST(kOptSonyPa1LibAPI)) - ArgsAdd(&argvP[argc], "-e", "ypa1", &argc); // Pa1Lib devices - else - ArgsAdd(&argvP[argc], "-e", "auto", &argc); // no driver, switch to auto - } else { - ArgsAdd(&argvP[argc], "-e", drv[gameInfoP->musicInfo.sound.drvMusic], &argc); - } - - // output rate - UInt32 rates[] = {4000, 8000, 11025, 22050, 44100}; - StrIToA(num, rates[gameInfoP->musicInfo.sound.rate]); - ArgsAdd(&argvP[argc], "--output-rate=", num, &argc); - - // FM quality - gVars->fmQuality = gameInfoP->fmQuality; - - } else { - ArgsAdd(&argvP[argc], "-e", "null", &argc); - } - - // volume control - StrIToA(num, gameInfoP->musicInfo.volume.sfx); - ArgsAdd(&argvP[argc], "-s", num, &argc); - StrIToA(num, gameInfoP->musicInfo.volume.music); - ArgsAdd(&argvP[argc], "-m", num, &argc); - StrIToA(num, gameInfoP->musicInfo.volume.speech); - ArgsAdd(&argvP[argc], "-r", num, &argc); - - // game name - ArgsAdd(&argvP[argc], gameInfoP->gameP, NULL, &argc); - - gVars->palmVolume = gameInfoP->musicInfo.sound.music ? gameInfoP->musicInfo.volume.palm : 0; - - MemHandleUnlock(recordH); - } // end no game / game selected - - // common command line options - - // debug level - if (gPrefs->debug) { - StrIToA(num, gPrefs->debugLevel); - ArgsAdd(&argvP[argc], "-d", num, &argc); - } - - if (engine == ENGINE_QUEEN || engine == ENGINE_SKY) { - // alternative intro ? - if (gPrefs->altIntro) - ArgsAdd(&argvP[argc], "--alt-intro", NULL, &argc); - } - - if (engine == ENGINE_SCUMM) { - // demo mode ? - if (gPrefs->demoMode) - ArgsAdd(&argvP[argc], "--demo-mode", NULL, &argc); - } - - // copy protection ? - if (gPrefs->copyProtection) - ArgsAdd(&argvP[argc], "--copy-protection", NULL, &argc); - - // exceed max args ? - if (argc > MAX_ARG) - FrmCustomAlert(FrmErrorAlert, "Too many parameters.",0,0); - - // set some common options - stackSize = (gPrefs->setStack ? STACK_LARGER : STACK_DEFAULT); - lightspeed= (gPrefs->lightspeed.enable ? gPrefs->lightspeed.mode : 255); - toLauncher= (gPrefs->exitLauncher); - - // gVars values - // (gVars->HRrefNum defined in checkHRmode on Clie) -#ifndef _DEBUG_ENGINE - gVars->VFS.volRefNum = (gPrefs->card.autoDetect ? vfsInvalidVolRef : gPrefs->card.volRefNum); -#else - gVars->VFS.volRefNum = gPrefs->card.volRefNum; -#endif - gVars->vibrator = gPrefs->vibrator; - gVars->stdPalette = gPrefs->stdPalette; - gVars->VFS.cacheSize = (gPrefs->card.useCache ? gPrefs->card.cacheSize : 0); - gVars->indicator.showLED= gPrefs->card.showLED; - gVars->stylusClick = gPrefs->stylusClick; - gVars->autoSave = (gPrefs->autoSave ? gPrefs->autoSavePeriod : -1); - gVars->advancedMode = gPrefs->advancedMode; - gVars->arrowKeys = gPrefs->arrowKeys; - - // user params - HWR_RSTALL(); - - if (gPrefs->goLCD) - HWR_SET(INIT_GOLCD); - else - OPTIONS_RST(kOptGoLcdAPI); - - if (!gPrefs->autoOff) - HWR_SET(INIT_AUTOOFF); - - if (gVars->vibrator) - HWR_SET(INIT_VIBRATOR); -/* ???? - if ( musicDriver == 1 || - musicDriver == 3 || - musicDriver == 4 || - musicDriver == sysInvalidRefNum) { - HWR_SET(INIT_PA1LIB); - } -*/ - if (ModImport(&gVars->VFS.volRefNum, engine, &isARM) != errNone) { - if (bDirectMode) { - // and force exit if nothing selected - EventType event; - event.eType = keyDownEvent; - event.data.keyDown.chr = vchrLaunch; - event.data.keyDown.modifiers = commandKeyMask; - EvtAddUniqueEventToQueue(&event, 0, true); - } - ArgsFree(argvP); - return false; - } - - // reset mode if screen rotation occurred (DIA only) - if (!direct && OPTIONS_TST(kOptCollapsible)) { - UInt8 mode = PalmScreenSize(0,0, &(gVars->screenFullWidth), &(gVars->screenFullHeight)); - OPTIONS_RST(kOptModeLandscape); - OPTIONS_SET((mode == PALM_LANDSCAPE) ? kOptModeLandscape : kOptNone); - } - - // free and save globals pref memory - GamCloseDatabase(false); - FrmCloseAllForms(); - SavePrefs(); - - { - UInt16 cardNo; - UInt32 dbID; - - LaunchParamType *cmdPBP = (LaunchParamType *)MemPtrNew(sizeof(LaunchParamType)); - - MemPtrSetOwner(cmdPBP, 0); - MemPtrSetOwner(gVars, 0); - ArgsSetOwner(argvP, 0); - - cardNo = 0; - dbID = DmFindDatabase(0, "ScummVM-Engine"); - - if (isARM) - FtrSet(appFileCreator, ftrStack , (stackSize * 4)); - else - ModSetStack(stackSize, cardNo, dbID); - - cmdPBP->args.argc = argc; - cmdPBP->args.argv = argvP; - cmdPBP->gVars = gVars; - cmdPBP->lightspeed = lightspeed; - cmdPBP->exitLauncher = toLauncher; - - SysUIAppSwitch(cardNo, dbID, sysAppLaunchCmdNormalLaunch, cmdPBP); - bLaunched = true; - } - - return false; -} diff --git a/backends/platform/PalmOS/Src/launcher/skin.cpp b/backends/platform/PalmOS/Src/launcher/skin.cpp deleted file mode 100644 index 4c3f722aa1..0000000000 --- a/backends/platform/PalmOS/Src/launcher/skin.cpp +++ /dev/null @@ -1,612 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> -#include <PalmOSGlue.h> -#include <SonyClie.h> - -#include "start.h" -#include "games.h" -#include "globals.h" -#include "skin.h" -#include "StarterRsc.h" - -UInt16 lastIndex = dmMaxRecordIndex; // last select index in the list to prevent flash -static WinHandle winLockH = NULL; - -MemPtr SknScreenLock(WinLockInitType initMode) { - Err e; - RectangleType r; - - WinGetBounds(WinGetDisplayWindow(), &r); - winLockH = WinCreateOffscreenWindow(r.extent.x, r.extent.y, nativeFormat, &e); - WinSetDrawWindow(winLockH); - - if (initMode == winLockCopy) - WinCopyRectangle(WinGetDisplayWindow(), winLockH, &r, 0, 0, winPaint); - - return BmpGetBits(WinGetBitmap(winLockH)); -} - -void SknScreenUnlock() { - RectangleType r; - - WinGetBounds(winLockH, &r); - WinCopyRectangle(winLockH, WinGetDisplayWindow(), &r, 0, 0, winPaint); - WinSetDrawWindow(WinGetDisplayWindow()); - WinDeleteWindow(winLockH, false); - winLockH = NULL; -} - -static void SknGetListColors(DmOpenRef skinDBP, UInt8 *text, UInt8 *selected, UInt8 *background) { - UInt16 colIndex; - MemHandle colH; - UInt8 *colTemp; - - // default - *text = UIColorGetTableEntryIndex (UIMenuForeground); - *selected = UIColorGetTableEntryIndex (UIMenuSelectedForeground); - *background = UIColorGetTableEntryIndex (UIMenuSelectedFill); - - if (skinDBP) { - colIndex = DmFindResource (skinDBP, sknColorsRsc, skinColors, NULL); - - if (colIndex != (UInt16)-1) { - colH = DmGetResourceIndex(skinDBP, colIndex); - - if (colH) { - colTemp = (UInt8 *)MemHandleLock(colH); - - *text = colTemp[0]; - *selected = colTemp[1]; - *background = colTemp[2]; - - MemPtrUnlock(colTemp); - DmReleaseResource(colH); - } - } - } -} - -static void SknCopyBits(DmOpenRef skinDBP, DmResID bitmapID, const RectangleType *srcRect, Coord destX, Coord destY) { - MemHandle hTemp; - BitmapPtr bmpTemp; - UInt16 index; - - Coord cx, cy, cw, ch, bw, bh; - RectangleType copy, old; - - if (skinDBP) { - // find the bitmap - index = DmFindResource (skinDBP, bitmapRsc, bitmapID, NULL); - - if (index != (UInt16)-1) { - hTemp = DmGetResourceIndex(skinDBP,index); - - if (hTemp) { - bmpTemp = (BitmapType *)MemHandleLock(hTemp); - BmpGlueGetDimensions(bmpTemp, &bw, &bh, 0); - - if (!srcRect) { - cx = 0; - cy = 0; - cw = bw; - ch = bh; - } else { - cx = srcRect->topLeft.x; - cy = srcRect->topLeft.y; - cw = srcRect->extent.x; - ch = srcRect->extent.y; - } - - if (ch) { - WinGetClip(&old); - if (OPTIONS_TST(kOptModeHiDensity)) { - Err e; - BitmapTypeV3 *bmp2P; - - // create an uncompressed version of the bitmap - WinHandle win = WinCreateOffscreenWindow(bw, bh, screenFormat, &e); - WinHandle old = WinGetDrawWindow(); - WinSetDrawWindow(win); - WinDrawBitmap(bmpTemp, 0, 0); - WinSetDrawWindow(old); - - bmp2P = BmpCreateBitmapV3(WinGetBitmap(win), kDensityDouble, BmpGetBits(WinGetBitmap(win)), NULL); - - copy.topLeft.x = destX / 2; - copy.topLeft.y = destY / 2; - copy.extent.x = cw / 2; - copy.extent.y = ch / 2; - - WinSetClip(©); - WinDrawBitmap((BitmapPtr)bmp2P, (destX - cx) / 2, (destY - cy) / 2); - BmpDelete((BitmapPtr)bmp2P); - WinDeleteWindow(win, false); - - } else { - copy.topLeft.x = destX; - copy.topLeft.y = destY; - copy.extent.x = cw; - copy.extent.y = ch; - - HRWinSetClip(gVars->HRrefNum, ©); - HRWinDrawBitmap(gVars->HRrefNum, bmpTemp, destX - cx, destY - cy); - } - WinSetClip(&old); - } - - MemPtrUnlock(bmpTemp); - DmReleaseResource(hTemp); - } - } - } -} - -void SknApplySkin() { - DmOpenRef skinDBP; - RectangleType r; - FormPtr frmP = FrmGetActiveForm(); - - // draw skin - FrmDrawForm(frmP); - SknScreenLock(winLockCopy); - - skinDBP = SknOpenSkin(); - - if (gPrefs->card.volRefNum != vfsInvalidVolRef) - FrmShowObject(frmP, FrmGetObjectIndex (frmP, MainMSBitMap)); - else - FrmShowObject(frmP, FrmGetObjectIndex (frmP, MainMSNoneBitMap)); - - WinSetForeColor(255); - WinSetDrawMode(winPaint); - WinDrawLine (0, 14, 159, 14); - WinDrawLine (0, 13, 159, 13); - - SknGetObjectBounds(skinDBP, skinBackgroundImageTop, &r); - SknCopyBits(skinDBP, skinBackgroundImageTop, 0, r.topLeft.x, r.topLeft.y); - SknGetObjectBounds(skinDBP, skinBackgroundImageBottom, &r); - SknCopyBits(skinDBP, skinBackgroundImageBottom, 0, r.topLeft.x, r.topLeft.y); - - for (UInt16 resID = 1100; resID <= 7000; resID += 100) { - SknSetState(skinDBP, resID, sknStateNormal); - SknShowObject(skinDBP, resID); - } - - SknCloseSkin(skinDBP); - SknScreenUnlock(); - SknUpdateList(); -} - -void SknGetObjectBounds(DmOpenRef skinDBP, DmResID resID, RectangleType *rP) { - - UInt16 bmpIndex, strIndex; - MemHandle hBmp, hStr; - BitmapType *bmpTemp; - UInt8 *strTemp; - - RctSetRectangle(rP, 0, 0, 0, 0); - - if (skinDBP) { - bmpIndex = DmFindResource (skinDBP, bitmapRsc, resID, NULL); - - if (bmpIndex != (UInt16)-1) { // if bmp exists - strIndex = DmFindResource (skinDBP, sknPosRsc, resID, NULL); - - if (strIndex != (UInt16)-1) { // if params exist - hBmp = DmGetResourceIndex(skinDBP,bmpIndex); - - if (hBmp) { - hStr = DmGetResourceIndex(skinDBP,strIndex); - - if (hStr) { - // buttons : state|x|y|w/h slider|draw mode|x1/y1 keep|x2/y2 keep slider - // list (160mode) : state|x|y|w|h| - bmpTemp = (BitmapType *)MemHandleLock(hBmp); - strTemp = (UInt8 *)MemHandleLock(hStr); - - BmpGlueGetDimensions(bmpTemp, &(rP->extent.x), &(rP->extent.y), 0); - rP->topLeft.x = strTemp[sknInfoPosX] * 2; - rP->topLeft.y = strTemp[sknInfoPosY] * 2; - - MemPtrUnlock(strTemp); - DmReleaseResource(hStr); - } - - MemPtrUnlock(bmpTemp); - DmReleaseResource(hBmp); - } - } - } - } -} - -DmOpenRef SknOpenSkin() { - return DmOpenDatabase(gPrefs->skin.cardNo, gPrefs->skin.dbID, dmModeReadOnly); -} - -void SknCloseSkin(DmOpenRef skinDBP) { - if (skinDBP) - DmCloseDatabase(skinDBP); -} - -UInt8 SknSetState(DmOpenRef skinDBP, DmResID resID, UInt8 newState) { - - UInt16 index; - MemHandle hStr; - UInt8 *strTemp; - UInt8 oldState = 0; - - if (skinDBP) { - index = DmFindResource (skinDBP, sknPosRsc, resID, NULL); - - if (index != (UInt16)-1) { - hStr = DmGetResourceIndex(skinDBP, index); - - if (hStr) { - strTemp = (UInt8 *)MemHandleLock(hStr); - oldState = strTemp[sknInfoState]; - - if (oldState != newState) { - DmWrite(strTemp, 0, &newState, 1); - } - - MemPtrUnlock(strTemp); - DmReleaseResource(hStr); - } - } - } - - return oldState; -} - -UInt8 SknGetDepth(DmOpenRef skinDBP) { - UInt16 index; - MemHandle hStr; - UInt8 *strTemp; - UInt8 depth = 8; - - if (skinDBP) { - index = DmFindResource (skinDBP, sknDepthRsc, skinDepth, NULL); - - if (index != (UInt16)-1) { - hStr = DmGetResourceIndex(skinDBP, index); - - if (hStr) { - strTemp = (UInt8 *)MemHandleLock(hStr); - depth = *strTemp; - MemPtrUnlock(strTemp); - DmReleaseResource(hStr); - } - } - } - - return depth; -} - -UInt8 SknGetState(DmOpenRef skinDBP, DmResID resID) { - UInt16 index; - MemHandle hStr; - UInt8 *strTemp; - UInt8 oldState = sknStateDisabled; - - if (skinDBP) { - index = DmFindResource (skinDBP, sknPosRsc, resID, NULL); - - if (index != (UInt16)-1) { - hStr = DmGetResourceIndex(skinDBP, index); - - if (hStr) { - strTemp = (UInt8 *)MemHandleLock(hStr); - oldState = strTemp[sknInfoState]; - MemPtrUnlock(strTemp); - DmReleaseResource(hStr); - } - } - } - - return oldState; -} - -void SknShowObject(DmOpenRef skinDBP, DmResID resID) { - RectangleType r; - UInt8 state = SknGetState(skinDBP, resID); - SknGetObjectBounds(skinDBP, resID, &r); - SknCopyBits(skinDBP, resID + state, NULL, r.topLeft.x, r.topLeft.y); -} - -void SknGetListBounds(RectangleType *rAreaP, RectangleType *rArea2xP) { - DmOpenRef skinDBP; - UInt16 strIndex; - MemHandle hStr; - UInt8 *strTemp; - UInt16 x,y,w,h; - - skinDBP = DmOpenDatabase(gPrefs->skin.cardNo, gPrefs->skin.dbID, dmModeReadOnly); - if (skinDBP) { - strIndex = DmFindResource (skinDBP, sknPosRsc, skinList, NULL); - - if (strIndex != 0xFFFF) { // if params exist - hStr = DmGetResourceIndex(skinDBP,strIndex); - if (hStr) { - strTemp = (UInt8 *)MemHandleLock(hStr); - - x = strTemp[sknInfoPosX]; - y = strTemp[sknInfoPosY]; - w = strTemp[sknInfoListWidth]; - h = strTemp[sknInfoListSize] * sknInfoListItemSize; - - if (rAreaP) - RctSetRectangle(rAreaP ,x, y, w, h); - if (rArea2xP) - RctSetRectangle(rArea2xP, x+x, y+y, w+w, h+h); - - MemHandleUnlock(hStr); - DmReleaseResource(hStr); - } - } - - DmCloseDatabase(skinDBP); - } -} - -static void SknRedrawTools(DmOpenRef skinDBP) { - if (GamGetSelected() == dmMaxRecordIndex) { - if (SknGetState(skinDBP, skinButtonGameDelete) == sknStateNormal) { - SknSetState(skinDBP, skinButtonGameDelete,sknStateDisabled); - SknShowObject(skinDBP, skinButtonGameDelete); - } - if (SknGetState(skinDBP, skinButtonGameEdit) == sknStateNormal) { - SknSetState(skinDBP, skinButtonGameEdit,sknStateDisabled); - SknShowObject(skinDBP, skinButtonGameEdit); - } - if (SknGetState(skinDBP, skinButtonGameAudio) == sknStateNormal) { - SknSetState(skinDBP, skinButtonGameAudio,sknStateDisabled); - SknShowObject(skinDBP, skinButtonGameAudio); - } - - } else { - if (SknGetState(skinDBP, skinButtonGameDelete) == sknStateDisabled) { - SknSetState(skinDBP, skinButtonGameDelete,sknStateNormal); - SknShowObject(skinDBP, skinButtonGameDelete); - } - if (SknGetState(skinDBP, skinButtonGameEdit) == sknStateDisabled) { - SknSetState(skinDBP, skinButtonGameEdit,sknStateNormal); - SknShowObject(skinDBP, skinButtonGameEdit); - } - if (SknGetState(skinDBP, skinButtonGameAudio) == sknStateDisabled) { - SknSetState(skinDBP, skinButtonGameAudio,sknStateNormal); - SknShowObject(skinDBP, skinButtonGameAudio); - } - } -} - -static void SknRedrawSlider(DmOpenRef skinDBP, UInt16 index, UInt16 maxIndex, UInt16 perPage) { - if (maxIndex <= perPage) { - if (SknGetState(skinDBP,skinSliderUpArrow) != sknStateDisabled) { - SknSetState(skinDBP,skinSliderUpArrow,sknStateDisabled); - SknShowObject(skinDBP,skinSliderUpArrow); - } - if (SknGetState(skinDBP,skinSliderDownArrow) != sknStateDisabled) { - SknSetState(skinDBP,skinSliderDownArrow,sknStateDisabled); - SknShowObject(skinDBP,skinSliderDownArrow); - } - - } else { - if (SknGetState(skinDBP,skinSliderUpArrow) == sknStateDisabled) { - SknSetState(skinDBP,skinSliderUpArrow,sknStateNormal); - SknShowObject(skinDBP,skinSliderUpArrow); - } - if (SknGetState(skinDBP,skinSliderDownArrow) == sknStateDisabled) { - SknSetState(skinDBP,skinSliderDownArrow,sknStateNormal); - SknShowObject(skinDBP,skinSliderDownArrow); - } - } -} - -void SknUpdateList() { - MemHandle record; - Int32 index, maxIndex, maxView; - GameInfoType *game; - RectangleType rArea, rField, rCopy, rArea2x; - DmOpenRef skinDBP; - - UInt8 txtColor, norColor, selColor, bkgColor; - UInt16 x,y; - - SknScreenLock(winLockCopy); - - SknGetListBounds(&rArea, &rArea2x); - skinDBP = SknOpenSkin(); - // set default bg - WinSetForeColor(UIColorGetTableEntryIndex (UIFormFill)); - WinDrawRectangle(&rArea,0); - // copy top bg - SknGetObjectBounds(skinDBP, skinBackgroundImageTop, &rField); - RctGetIntersection(&rArea2x, &rField, &rCopy); - x = rCopy.topLeft.x; - y = rCopy.topLeft.y; - rCopy.topLeft.x -= rField.topLeft.x; - rCopy.topLeft.y -= rField.topLeft.y; - SknCopyBits(skinDBP, skinBackgroundImageTop, &rCopy, x, y); - // copy bottom bg - SknGetObjectBounds(skinDBP, skinBackgroundImageBottom, &rField); - RctGetIntersection(&rArea2x, &rField, &rCopy); - x = rCopy.topLeft.x; - y = rCopy.topLeft.y; - rCopy.topLeft.x -= rField.topLeft.x; - rCopy.topLeft.y -= rField.topLeft.y; - SknCopyBits(skinDBP, skinBackgroundImageBottom, &rCopy, x, y); - - FntSetFont(stdFont); - - index = gPrefs->listPosition; - maxIndex = DmNumRecords(gameDB); - maxView = rArea.extent.y / sknInfoListItemSize; - - if (index > 0 && (index + maxView) > maxIndex) - index -= (index + maxView) - maxIndex; - - if (index < 0) - index = 0; - - gPrefs->listPosition = index; - - SknRedrawSlider(skinDBP, index, maxIndex, maxView); - SknRedrawTools(skinDBP); - SknGetListColors(skinDBP, &norColor, &selColor, &bkgColor); - - SknCloseSkin(skinDBP); - - while (index < (gPrefs->listPosition + maxView) && index < maxIndex) { - record = DmQueryRecord(gameDB, index); - game = (GameInfoType *)MemHandleLock(record); - - // text box - RctSetRectangle(&rField, rArea.topLeft.x, (rArea.topLeft.y + sknInfoListItemSize * (index - gPrefs->listPosition)), rArea.extent.x, sknInfoListItemSize); - WinSetClip(&rField); - - if (game->selected) { - WinSetDrawMode(winPaint); - WinSetForeColor(bkgColor); - WinDrawRectangle(&rField,0); - txtColor = selColor; - } - else - txtColor = norColor; - - // clipping - rField.topLeft.x += 2; - rField.extent.x -= 4; - WinSetClip(&rField); - // draw text mask - WinSetTextColor(255); - WinSetDrawMode(winMask); - WinPaintChars(game->nameP, StrLen(game->nameP), rField.topLeft.x, rField.topLeft.y); - // draw text - if (txtColor) { - WinSetTextColor(txtColor); - WinSetDrawMode(winOverlay); - WinPaintChars(game->nameP, StrLen(game->nameP), rField.topLeft.x, rField.topLeft.y); - } - - MemHandleUnlock(record); - index++; - } - - RctSetRectangle(&rArea,0,0,160,160); - WinSetClip(&rArea); - SknScreenUnlock(); -} - -UInt16 SknCheckClick(DmOpenRef skinDBP, Coord mx, Coord my) { - UInt16 resID; - RectangleType r; - - mx *= 2; - my *= 2; - - if (skinDBP) { - for (resID = 1100; resID <= 7000; resID += 100) { - if (SknGetState(skinDBP, resID) != sknStateDisabled) { - SknGetObjectBounds(skinDBP, resID, &r); - if (RctPtInRectangle(mx, my, &r)) { - return resID; - } - } - } - } - - return 0; -} - -void SknSelect(Coord x, Coord y) { - RectangleType rArea; - SknGetListBounds(&rArea,0); - - if (RctPtInRectangle(x, y, &rArea)) { - UInt16 index; - MemHandle record; - GameInfoType *game; - UInt16 oldIndex; - - index = (y - rArea.topLeft.y) / sknInfoListItemSize + gPrefs->listPosition; - - if (index == lastIndex) - return; - - if (index < DmNumRecords(gameDB)) { - Boolean newValue; - - oldIndex = GamGetSelected(); - - if (oldIndex != index && oldIndex != dmMaxRecordIndex) - GamUnselect(); - - record = DmGetRecord(gameDB, index); - game = (GameInfoType *)MemHandleLock(record); - - newValue = !game->selected; - DmWrite(game, OffsetOf(GameInfoType,selected), &newValue, sizeof(Boolean)); - - MemHandleUnlock(record); - DmReleaseRecord (gameDB, index, 0); - - lastIndex = index; - SknUpdateList(); - } - } -} - -Boolean SknProcessArrowAction(UInt16 button) { - Boolean handled = false; - - switch (button) { - case skinSliderUpArrow: - if (gPrefs->listPosition > 0) { - gPrefs->listPosition--; - SknUpdateList(); - } - handled = true; - break; - - case skinSliderDownArrow: - RectangleType rArea; - UInt16 maxView; - - SknGetListBounds(&rArea, 0); - maxView = rArea.extent.y / sknInfoListItemSize; - - if (gPrefs->listPosition < DmNumRecords(gameDB)-maxView) { - gPrefs->listPosition++; - SknUpdateList(); - } - handled = true; - break; - } - - return handled; -} diff --git a/backends/platform/PalmOS/Src/launcher/skin.h b/backends/platform/PalmOS/Src/launcher/skin.h deleted file mode 100644 index e8a81e7e2d..0000000000 --- a/backends/platform/PalmOS/Src/launcher/skin.h +++ /dev/null @@ -1,131 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef __SKIN_H__ -#define __SKIN_H__ - -// skin -#define sknInfoState 0 -#define sknInfoPosX 1 -#define sknInfoPosY 2 - -#define sknInfoMaxWOrH 3 -#define sknInfoDrawMode 4 -#define sknInfoKeepXOrY1 5 -#define sknInfoKeepXOrY2 7 - -#define sknInfoListWidth sknInfoMaxWOrH -#define sknInfoListHeight sknInfoDrawMode -#define sknInfoListSize sknInfoListHeight -#define sknInfoListItemSize 12 - -#define sknPosRsc 'sPos' -#define sknColorsRsc 'sCol' -#define sknDepthRsc 'sDep' - -#define sknStateNormal 0 -#define sknStateSelected 10 -#define sknStateDisabled 20 - -#define sknSelectedState(bmp) (bmp + sknStateSelected) -#define sknDisabledState(bmp) (bmp + sknStateDisabled) - -// skin elements -#define skinList 500 -#define skinColors 600 -#define skinDepth 700 - -#define skinButtonNone 0 - -#define skinSliderUpArrow 2000 -#define skinSliderDownArrow 2100 - -#define skinButtonGameParams 3000 -#define skinButtonGameAdd 3100 -#define skinButtonGameEdit 3200 -#define skinButtonGameAudio 3300 -#define skinButtonGameDelete 4000 -#define skinButtonGameStart 7000 - -#define skinBackgroundImageTop 1000 -#define skinBackgroundImageBottom 1010 -/// - - -#define skinToolsBackground 1100 - -#define skinListUpArrowNormal 1500 -#define skinListUpArrowOver 1510 -#define skinListUpArrowDisabled 1540 - -#define skinListDownArrowNormal 1800 -#define skinListDownArrowOver 1810 -#define skinListDownArrowDisabled 1840 - -#define skinButtonGameInfoNormal 2000 -#define skinButtonGameInfoOver 2010 -#define skinButtonGameInfoDisabled 2040 - -#define skinButtonGameParamNormal 3000 -#define skinButtonGameParamOver 3010 - -#define skinButtonGameDeleteNormal 4000 -#define skinButtonGameDeleteOver 4010 -#define skinButtonGameDeleteDisabled 4040 - -#define skinButtonVibratorNormal 5000 -#define skinButtonVibratorOver 5010 -#define skinButtonVibratorSelected 5020 -#define skinButtonVibratorSelectedOver 5030 -#define skinButtonVibratorDisabled 5040 - - -#define skinButtonSleepNormal 6000 -#define skinButtonSleepOver 6010 -#define skinButtonSleepSelected 6020 -#define skinButtonSleepSelectedOver 9030 - -#define skinButtonPlayNormal 7000 -#define skinButtonPlayOver 7010 -#define skinButtonPlayDisabled 7040 - -// protos -void SknApplySkin(); -void SknGetObjectBounds(DmOpenRef skinDBP, DmResID resID, RectangleType *rP); -DmOpenRef SknOpenSkin(); -void SknCloseSkin(DmOpenRef skinDBP); -UInt8 SknSetState(DmOpenRef skinDBP, DmResID resID, UInt8 newState); -void SknShowObject(DmOpenRef skinDBP, DmResID resID); -UInt8 SknGetState(DmOpenRef skinDBP, DmResID resID); -void SknUpdateList(); -void SknGetListBounds(RectangleType *rAreaP, RectangleType *rArea2xP); -UInt16 SknCheckClick(DmOpenRef skinDBP, Coord mx, Coord my); -void SknSelect(Coord x, Coord y); -Boolean SknProcessArrowAction(UInt16 button); -UInt8 SknGetDepth(DmOpenRef skinDBP); - -extern UInt16 lastIndex; - -#endif diff --git a/backends/platform/PalmOS/Src/launcher/start.cpp b/backends/platform/PalmOS/Src/launcher/start.cpp deleted file mode 100644 index b5e8f24884..0000000000 --- a/backends/platform/PalmOS/Src/launcher/start.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> -#include <SonyClie.h> - -#include "palmdefs.h" -#include "start.h" -#include "games.h" -#include "globals.h" -#include "modules.h" -#include "skin.h" - -#include "forms.h" - -/*********************************************************************** - * - * Global variables - * - ***********************************************************************/ -GlobalsPreferencePtr gPrefs; -GlobalsDataPtr gVars; - -Boolean bDirectMode = false; -Boolean bLaunched = false; - -/*********************************************************************** - * - * Internal Constants - * - ***********************************************************************/ - -// Define the minimum OS version we support (3.5 for now). -#define kOurMinVersion sysMakeROMVersion(3,5,0,sysROMStageRelease,0) -#define kPalmOS10Version sysMakeROMVersion(1,0,0,sysROMStageRelease,0) - -/*********************************************************************** - * - * Internal Functions - * - ***********************************************************************/ - -// Callback for ExgDBWrite to send data with Exchange Manager -static Err WriteDBData(const void* dataP, UInt32* sizeP, void* userDataP) { - Err err; - *sizeP = ExgSend((ExgSocketPtr)userDataP, (void*)dataP, *sizeP, &err); - return err; -} - -Err SendDatabase (UInt16 cardNo, LocalID dbID, Char *nameP, Char *descriptionP) { - ExgSocketType exgSocket; - Err err; - - // Create exgSocket structure - MemSet(&exgSocket, sizeof(exgSocket), 0); - exgSocket.description = descriptionP; - exgSocket.name = nameP; - - // Start an exchange put operation - err = ExgPut(&exgSocket); - if (!err) { - err = ExgDBWrite(WriteDBData, &exgSocket, NULL, dbID, cardNo); - err = ExgDisconnect(&exgSocket, err); - } - - return err; -} - - -/*********************************************************************** - * - * FUNCTION: RomVersionCompatible - * - * DESCRIPTION: This routine checks that a ROM version is meet your - * minimum requirement. - * - * PARAMETERS: requiredVersion - minimum rom version required - * (see sysFtrNumROMVersion in SystemMgr.h - * for format) - * launchFlags - flags that indicate if the application - * UI is initialized. - * - * RETURNED: error code or zero if rom is compatible - * - * REVISION HISTORY: - * - * - ***********************************************************************/ -static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) { - UInt32 romVersion; - - // See if we're on in minimum required version of the ROM or later. - FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); - if (romVersion < requiredVersion) { - if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == - (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) { - - FrmAlert (RomIncompatibleAlert); - - // Palm OS 1.0 will continuously relaunch this app unless we switch to - // another safe one. - if (romVersion <= kPalmOS10Version) - AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); - - } - return sysErrRomIncompatible; - } - - return errNone; -} - -/////////////////////////////////////////////////////////////////////// - - -void SavePrefs() { - if (gPrefs) { - PrefSetAppPreferences(appFileCreator, appPrefID, appPrefVersionNum, gPrefs, sizeof (GlobalsPreferenceType), true); - MemPtrFree(gPrefs); - gPrefs = NULL; - } -} - -/*********************************************************************** - * - * FUNCTION: AppHandleEvent - * - * DESCRIPTION: This routine loads form resources and set the event - * handler for the form loaded. - * - * PARAMETERS: event - a pointer to an EventType structure - * - * RETURNED: true if the event has handle and should not be passed - * to a higher level handler. - * - * REVISION HISTORY: - * - * - ***********************************************************************/ -static Boolean AppHandleEvent(EventPtr eventP) { - UInt16 formId; - FormPtr frmP; - - if (eventP->eType == frmLoadEvent) { - // Load the form resource. - formId = eventP->data.frmLoad.formID; - frmP = FrmInitForm(formId); - FrmSetActiveForm(frmP); - - // Set the event handler for the form. The handler of the currently - // active form is called by FrmHandleEvent each time is receives an - // event. - switch (formId) { - case MainForm: - FrmSetEventHandler(frmP, MainFormHandleEvent); - break; - - case SkinsForm: - FrmSetEventHandler(frmP, SkinsFormHandleEvent); - break; - - case GameEditForm: - FrmSetEventHandler(frmP, EditGameFormHandleEvent); - break; - - case MiscForm: - FrmSetEventHandler(frmP, MiscFormHandleEvent); - break; - - case CardSlotForm: - FrmSetEventHandler(frmP, CardSlotFormHandleEvent); - break; - - case MusicForm: - FrmSetEventHandler(frmP, MusicFormHandleEvent); - break; - - case InfoForm: - FrmSetEventHandler(frmP, InfoFormHandleEvent); - break; - - case EngineForm: - FrmSetEventHandler(frmP, SelectorFormHandleEvent); - break; - - default: -// ErrFatalDisplay("Invalid Form Load Event"); - break; - } - return true; - } - - return false; -} - -/*********************************************************************** - * - * FUNCTION: AppEventLoop - * - * DESCRIPTION: This routine is the event loop for the application. - * - * PARAMETERS: nothing - * - * RETURNED: nothing - * - * REVISION HISTORY: - * - * - ***********************************************************************/ -static void AppEventLoop(void) { - UInt16 error; - EventType event; - - do { - EvtGetEvent(&event, evtNoWait); - - if (! SysHandleEvent(&event)) - if (! MenuHandleEvent(0, &event, &error)) - if (! AppHandleEvent(&event)) - FrmDispatchEvent(&event); - - } while (event.eType != appStopEvent); -} - -/*********************************************************************** - * - * FUNCTION: ScummVMPalmMain - * - * DESCRIPTION: This is the main entry point for the application. - * - * PARAMETERS: cmd - word value specifying the launch code. - * cmdPB - pointer to a structure that is associated with the launch code. - * launchFlags - word value providing extra information about the launch. - * - * RETURNED: Result of launch - * - * REVISION HISTORY: - * - * - ***********************************************************************/ -static void AppLaunchCmdNotify(UInt16 LaunchFlags, SysNotifyParamType * pData) { - switch (pData->notifyType) { - case sysNotifyVolumeMountedEvent: - pData->handled = true; // don't switch - - if (gPrefs) { // gPrefs exists ? so we are in the palm selector - CardSlotFormUpdate(); // redraw card list if needed - - if (gPrefs->card.volRefNum == vfsInvalidVolRef) { - VFSAnyMountParamType *notifyDetailsP = (VFSAnyMountParamType *)pData->notifyDetailsP; - gPrefs->card.volRefNum = notifyDetailsP->volRefNum; - - if (FrmGetFormPtr(MainForm) == FrmGetActiveForm()) - if (gPrefs->card.volRefNum != vfsInvalidVolRef) { - CardSlotCreateDirs(); - FrmUpdateForm(MainForm, frmRedrawUpdateMSImport); - } - } - } - break; - - case sysNotifyVolumeUnmountedEvent: - if (gPrefs) { - CardSlotFormUpdate(); - - if (gPrefs->card.volRefNum == (UInt16)pData->notifyDetailsP) { - gPrefs->card.volRefNum = vfsInvalidVolRef; - - if (FrmGetFormPtr(MainForm) == FrmGetActiveForm()) - FrmUpdateForm(MainForm, frmRedrawUpdateMS); - } - } - break; - - case sysNotifyDisplayResizedEvent: - if (gVars) - if (FrmGetFormPtr(MainForm) == FrmGetActiveForm()) - SknApplySkin(); - break; - - case sonySysNotifyMsaEnforceOpenEvent: - // what am i supposed to do here ??? - break; - } -} - -static UInt32 ScummVMPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) { - Err error; - - error = RomVersionCompatible (kOurMinVersion, launchFlags); - if (error) return (error); - - switch (cmd) { - case sysAppLaunchCmdNotify: - AppLaunchCmdNotify(launchFlags, (SysNotifyParamType *) cmdPBP); - break; - - case sysAppLaunchCustomEngineDelete: -#ifndef _DEBUG_ENGINE - ModDelete(); -#endif - break; - - case sysAppLaunchCmdNormalLaunch: - error = AppStart(); - if (error) - goto end; - - if (!bDirectMode) { - FrmGotoForm(MainForm); - }else { - GamUnselect(); - FrmGotoForm(EngineForm); - } - - AppEventLoop(); -end: - AppStop(); - break; - - default: - break; - - } - return error; -} - -/*********************************************************************** - * - * FUNCTION: PilotMain - * - * DESCRIPTION: This is the main entry point for the application. - * - * PARAMETERS: cmd - word value specifying the launch code. - * cmdPB - pointer to a structure that is associated with the launch code. - * launchFlags - word value providing extra information about the launch. - * RETURNED: Result of launch - * - * REVISION HISTORY: - * - * - ***********************************************************************/ - -UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) { - return ScummVMPalmMain(cmd, cmdPBP, launchFlags); -} diff --git a/backends/platform/PalmOS/Src/launcher/start.h b/backends/platform/PalmOS/Src/launcher/start.h deleted file mode 100644 index 3ed52b465b..0000000000 --- a/backends/platform/PalmOS/Src/launcher/start.h +++ /dev/null @@ -1,98 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef __START_H__ -#define __START_H__ - -typedef struct { - Char nameP[32]; - UInt16 cardNo; - LocalID dbID; -} SkinInfoType, *SkinInfoPtr; - -typedef struct { - - //skin params - SkinInfoType skin; // card where is located the skin - Boolean soundClick; - - Boolean vibrator; - Boolean autoOff; - Boolean setStack; - Boolean exitLauncher; - Boolean goLCD; - Boolean stylusClick; - Boolean arrowKeys; - - UInt16 listPosition; - UInt16 autoSavePeriod; - - struct { - UInt16 volRefNum; - UInt32 cacheSize; - Boolean useCache; - Boolean showLED; - Boolean autoDetect; - Boolean moveDB; - Boolean deleteDB; - Boolean confirmMoveDB; - } card; - - Boolean debug; - UInt16 debugLevel; - Boolean stdPalette; - Boolean demoMode; - Boolean copyProtection; - Boolean oldarm;// TODO : free slot... - Boolean altIntro; - Boolean autoSave; - Boolean advancedMode; - - struct { - Boolean enable; - UInt8 mode; - } lightspeed; - -} GlobalsPreferenceType, *GlobalsPreferencePtr; - -extern GlobalsPreferencePtr gPrefs; - -extern Boolean bDirectMode; -extern Boolean bLaunched; - -#define appPrefID 0x00 -#define appVersionNum 0x01 -#define appPrefVersionNum 0x02 - -#define STACK_DEFAULT 8192 -#define STACK_LARGER 16384 -#define STACK_GET 0 - -Err AppStart(void); -void AppStop(void); -Boolean StartScummVM(Int16 engine = -1); -void SavePrefs(); -Err SendDatabase (UInt16 cardNo, LocalID dbID, Char *nameP, Char *descriptionP); -#endif diff --git a/backends/platform/PalmOS/Src/modules.cpp b/backends/platform/PalmOS/Src/modules.cpp deleted file mode 100644 index b16e2cf7d5..0000000000 --- a/backends/platform/PalmOS/Src/modules.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include <PalmOS.h> - -#include "palmdefs.h" -#include "args.h" -#include "globals.h" -#include "modules.h" -#include "features.h" - -#include "rumble.h" -#include "init_mathlib.h" -#include "init_pa1lib.h" -#include "init_palmos.h" -#include "init_stuffs.h" -#include "init_sony.h" -#include "init_golcd.h" - -#ifndef DISABLE_LIGHTSPEED -#include "lightspeed_public.h" -#endif - -GlobalsDataPtr gVars; - -#include "endianutils.h" -#include <PNOLoader.h> - -#ifdef COMPILE_ZODIAC -# include <tapwave.h> -# include <TwRuntime.h> -#endif - -void run(int argc, char *argv[]) { - // init args - ArgsExportInit(argv, argc, true); - - // init system - PalmHRInit(16); - PalmInit(HWR_GET()); - void *__ptr = StuffsForceVG(); - - gVars->screenPitch = StuffsGetPitch(gVars->screenFullWidth); - - // export global struct to ARM - VARS_EXPORT(); - DO_VARS(_4B, 32, 0); - DO_VARS(_2B, 16, (gVars->_4B * sizeof(UInt32))); - FtrSet(appFileCreator, ftrVars , (UInt32)gVars); - - // run the module -#ifdef COMPILE_ZODIAC - NativeFuncType *entry; - TwLoadModule(0, 0, 0, 1, twLoadFlagTNA|twLoadFlagQuickRun, &entry); -#else - PnoDescriptor pno; - PnoLoadFromResources(&pno, 'ARMC', 1, appFileCreator, 1); - PnoCall(&pno, 0); - PnoUnload(&pno); -#endif - - // reset globals - DO_VARS(_4B, 32, 0); - DO_VARS(_2B, 16, (gVars->_4B * sizeof(UInt32))); - - // release - StuffsReleaseVG(__ptr); - PalmRelease(HWR_GET()); - PalmHRRelease(); - - // free args - ArgsExportRelease(true); - ArgsFree(argv); - - // release global struct - FtrUnregister(appFileCreator, ftrVars); - FtrUnregister(appFileCreator, ftrStack); - MemPtrFree(gVars); - - // reset the palette if needed - WinPalette(winPaletteSetToDefault, 0, 256, NULL); -} - -static UInt32 ModulesPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) -{ - UInt32 result = 0; - - switch (cmd) { - case sysAppLaunchCustomEngineGetInfo: { -#ifdef PALMOS_NATIVE - result = GET_MODEARM; -#else -# if defined(ENABLE_SCUMM) || \ - defined(ENABLE_AGOS) || \ - defined(ENABLE_SWORD1) - result = GET_DATACOMMON|GET_DATAENGINE|GET_MODE68K; -# else - result = GET_DATACOMMON|GET_MODE68K; -# endif -#endif - break; - } - - case sysAppLaunchCmdNormalLaunch: { - if (cmdPBP) { - Char **argvP; - UInt16 cardNo; - LocalID dbID; - - LaunchParamType *lp = (LaunchParamType *)cmdPBP; - - gVars = lp->gVars; - argvP = lp->args.argv; - - // get the free memory on the dynamic heap - PalmGetMemory(0,0,0, &(gVars->startupMemory)); - -#ifndef DISABLE_LIGHTSPEED - switch (lp->lightspeed) { - case 0: - LS_SetCPUSpeedHigh(); - break; - case 1: - LS_SetCPUSpeedNormal(); - break; - case 2: - LS_SetCPUSpeedLow(); - break; - } -#endif - // MemPtrSetOwner(gVars, ownerID); - // ArgsSetOwner(argvP, ownerID); // will be freed by main(...) - // MemPtrFree(lp); // will be freed by the system on exit - - run(lp->args.argc, argvP); - - cardNo = 0; - dbID = DmFindDatabase(0, "ScummVM"); - if (dbID) { - if (lp->exitLauncher) - SysUIAppSwitch(cardNo, dbID, sysAppLaunchCustomEngineDelete,0); - else - SysUIAppSwitch(cardNo, dbID, sysAppLaunchCmdNormalLaunch,0); - } - } - break; - } - - default: - break; - - } - - return result; -} - -UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) { - return ModulesPalmMain(cmd, cmdPBP, launchFlags); -} diff --git a/backends/platform/PalmOS/Src/modules.h b/backends/platform/PalmOS/Src/modules.h deleted file mode 100644 index d172ad11c2..0000000000 --- a/backends/platform/PalmOS/Src/modules.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef MODULES_H -#define MODULES_H - -#include "globals.h" - -#define sysAppLaunchCode_SVMRunEngine (sysAppLaunchCmdCustomBase + 0) - -void ModDelete(); - -typedef struct { - UInt8 lightspeed; - Boolean exitLauncher; - - struct { - UInt8 argc; - Char **argv; - } args; - - GlobalsDataPtr gVars; -} LaunchParamType; - -#endif diff --git a/backends/platform/PalmOS/Src/native/oscalls.cpp b/backends/platform/PalmOS/Src/native/oscalls.cpp deleted file mode 100644 index 9bfd01393f..0000000000 --- a/backends/platform/PalmOS/Src/native/oscalls.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PenInputMgr.h> -#include "pace.h" - -GlobalsType global; - - -PACE_CLASS_WRAPPER(Err) - __68k_StatShow(void) { - PACE_PIN_EXEC_NP(pinStatShow, Err) -} - -PACE_CLASS_WRAPPER(Err) - __68k_StatHide(void) { - PACE_PIN_EXEC_NP(pinStatHide, Err) -} - -PACE_CLASS_WRAPPER(Err) - __68k_PINSetInputAreaState(UInt16 state) { - PACE_PARAMS_INIT() - PACE_PARAMS_ADD16(state) - PACE_PARAMS_END() - PACE_PIN_EXEC(pinPINSetInputAreaState, Err) -} - -PACE_CLASS_WRAPPER(UInt16) - __68k_PINGetInputAreaState(void) { - PACE_PIN_EXEC_NP(pinPINGetInputAreaState, UInt16) -} - -PACE_CLASS_WRAPPER(Err) - __68k_PINSetInputTriggerState(UInt16 state) { - PACE_PARAMS_INIT() - PACE_PARAMS_ADD16(state) - PACE_PARAMS_END() - PACE_PIN_EXEC(pinPINSetInputTriggerState, Err) -} - -PACE_CLASS_WRAPPER(UInt16) - __68k_PINGetInputTriggerState(void) { - PACE_PIN_EXEC_NP(pinPINGetInputTriggerState, UInt16) -} - -PACE_CLASS_WRAPPER(Err) - __68k_SysSetOrientation(UInt16 orientation) { - PACE_PARAMS_INIT() - PACE_PARAMS_ADD16(orientation) - PACE_PARAMS_END() - PACE_PIN_EXEC(pinSysSetOrientation, Err) -} - -PACE_CLASS_WRAPPER(UInt16) - __68k_SysGetOrientation(void) { - PACE_PIN_EXEC_NP(pinSysGetOrientation, UInt16) -} - -PACE_CLASS_WRAPPER(Err) - __68k_SysSetOrientationTriggerState(UInt16 triggerState) { - PACE_PARAMS_INIT() - PACE_PARAMS_ADD16(triggerState) - PACE_PARAMS_END() - PACE_PIN_EXEC(pinSysSetOrientationTriggerState, Err) -} - -PACE_CLASS_WRAPPER(UInt16) - __68k_SysGetOrientationTriggerState(void) { - PACE_PIN_EXEC_NP(pinSysGetOrientationTriggerState, UInt16) -} diff --git a/backends/platform/PalmOS/Src/native/oscalls.h b/backends/platform/PalmOS/Src/native/oscalls.h deleted file mode 100644 index 071b409130..0000000000 --- a/backends/platform/PalmOS/Src/native/oscalls.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef _OSCALLS_H_ -#define _OSCALLS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef PALMOS_ARM -# define __68K(a) __68k_##a -#else -# define __68K(a) a -#endif - -Err __68k_StatShow(); -Err __68k_StatHide(); - -Err __68k_PINSetInputAreaState(UInt16 state); -UInt16 __68k_PINGetInputAreaState(void); - -Err __68k_PINSetInputTriggerState(UInt16 state); -UInt16 __68k_PINGetInputTriggerState(void); - -Err __68k_SysSetOrientation(UInt16 orientation); -UInt16 __68k_SysGetOrientation(void); - -Err __68k_SysSetOrientationTriggerState(UInt16 triggerState); -UInt16 __68k_SysGetOrientationTriggerState(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/backends/platform/PalmOS/Src/native/pace.h b/backends/platform/PalmOS/Src/native/pace.h deleted file mode 100644 index 37b903b2c3..0000000000 --- a/backends/platform/PalmOS/Src/native/pace.h +++ /dev/null @@ -1,103 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef PACE_H -#define PACE_H - -#include <PceNativeCall.h> -//#include "endianutils.h" - -// local definition of the emulation state structure -typedef struct { - UInt32 instr; - UInt32 regData[8]; - UInt32 regAddress[8]; - UInt32 regPC; -} EmulStateType; - -typedef struct { - EmulStateType *emulStateP; - Call68KFuncType *call68KFuncP; -} GlobalsType; - -extern GlobalsType global; - -// TODO : check this, already defined in ARMlet_Runtime -//extern EmulStateType *g_emulStateP; -//extern Call68KFuncType *g_call68KFuncP; -#define g_emulStateP global.emulStateP -#define g_call68KFuncP global.call68KFuncP - - -#ifdef __cplusplus -# define PACE_CLASS_WRAPPER(rv) extern "C" rv -#else -# define PACE_CLASS_WRAPPER(rv) rv -#endif -#define PACE_CALLBACK_PTR g_call68KFuncP -#define PACE_EMULSTATE g_emulStateP - -#define ALIGN_4BYTE(addr) (((UInt32)(addr) + 3) & 0xFFFFFFFC) - -/****** TAKEN FROM PACEInteface.cpp (ARMlet_Runtime) ******/ -// local definition of the emulation state structure - -#define PACE_PARAMS_INIT() \ - UInt8 params[] = { - -#define PACE_PARAMS_ADD8(param) \ - (UInt8)(param), \ - 0, - -#define PACE_PARAMS_ADD16(param) \ - (UInt8)((UInt16)(param) >> 8), \ - (UInt8)(param), - -#define PACE_PARAMS_ADD32(param) \ - (UInt8)((UInt32)(param) >> 24), \ - (UInt8)((UInt32)(param) >> 16), \ - (UInt8)((UInt32)(param) >> 8), \ - (UInt8)(param), - -#define PACE_PARAMS_END() \ - }; - -// PIN -#define PACE_PIN_EXEC_NP(pinTrap, returnType) \ - PACE_EMULSTATE->regData[2] = pinTrap; \ - return ((returnType)((PACE_CALLBACK_PTR)( \ - static_cast<void *>(PACE_EMULSTATE), \ - PceNativeTrapNo(sysTrapPinsDispatch), \ - NULL, 0))); - -#define PACE_PIN_EXEC(pinTrap, returnType) \ - PACE_EMULSTATE->regData[2] = pinTrap; \ - return ((returnType)((PACE_CALLBACK_PTR)( \ - static_cast<void *>(PACE_EMULSTATE), \ - PceNativeTrapNo(sysTrapPinsDispatch), \ - ¶ms, \ - sizeof(params)))); - -#endif diff --git a/backends/platform/PalmOS/Src/native/pnoARM.c b/backends/platform/PalmOS/Src/native/pnoARM.c deleted file mode 100644 index 48c4fee972..0000000000 --- a/backends/platform/PalmOS/Src/native/pnoARM.c +++ /dev/null @@ -1,60 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifdef COMPILE_OS5 - -#include <PalmOS.h> -#include <stdlib.h> -#include "pace.h" - -// Linker still looks for ARMlet_Main as entry point, but the -// "ARMlet" name is now officially discouraged. Compare an -// contrast to "PilotMain" for 68K applications. -#define PNO_Main ARMlet_Main - -/* Prepare static initializers */ -extern long __sinit__[]; -extern void __ARMlet_Startup__(); - -/* simple function pointer */ -typedef void (*StaticInitializer)(void); - -unsigned long PNO_Main(const void *emulStateP, void *userData68KP, Call68KFuncType *call68KFuncP) { - global.emulStateP = (EmulStateType *)emulStateP; - global.call68KFuncP = call68KFuncP; - - // handle static initializers - if (__sinit__) { - long base = (long)__ARMlet_Startup__; - long s, *p; - - for (p = __sinit__; p && (s = *p) != 0; p++) - ((StaticInitializer)(s + base))(); - } - - return PilotMain(sysAppLaunchCmdNormalLaunch, userData68KP, 0); -} - -#endif diff --git a/backends/platform/PalmOS/Src/native/pnoStartup.c b/backends/platform/PalmOS/Src/native/pnoStartup.c deleted file mode 100644 index b76cac3024..0000000000 --- a/backends/platform/PalmOS/Src/native/pnoStartup.c +++ /dev/null @@ -1,28 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifdef COMPILE_OS5 -# include "(Source)/ARMlet_Startup.c" -#endif diff --git a/backends/platform/PalmOS/Src/native/zodiacARM.cpp b/backends/platform/PalmOS/Src/native/zodiacARM.cpp deleted file mode 100644 index 7323bb6d69..0000000000 --- a/backends/platform/PalmOS/Src/native/zodiacARM.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "PalmVersion.h" -#include <MSL_PalmOS.h> - -#include "globals.h" -#include "args.h" -#include "palmdefs.h" - -#include "rumble.h" - - -//#include <AdnDebugMgr.h> -//#define DEBUG_ARM - -#include "base/main.h" -#ifdef COMPILE_ZODIAC -# include "be_zodiac.h" -#endif -#include "be_os5ex.h" - -GlobalsDataType g_vars; -GlobalsDataPtr gVars = &g_vars; -UInt32 g_stackSize; - -extern "C" void __destroy_global_chain(void); -extern void DrawStatus(Boolean show); - -static void palm_main(int argc, char **argvP) { -#ifdef COMPILE_OS5 - if (gVars->advancedMode) - g_system = new OSystem_PalmOS5Ex(); - else - g_system = new OSystem_PalmOS5(); -#elif defined(COMPILE_ZODIAC) - g_system = new OSystem_PalmZodiac(); -#else - #error "No target defined." -#endif - - assert(g_system); - - scummvm_main(argc, argvP); - - g_system->quit(); // TODO: Consider removing / replacing this! -} - -static void Go() { - void *tmp; - char **argvP; - int argc; - -#ifdef DEBUG_ARM -// Tell the debugger we want to enable full debugging - UInt32 flags = AdnDebugEnableGet(); - flags |= kAdnEnableMasterSwitch | kAdnEnableFullDebugging; - AdnDebugEnableSet(flags); -// Tell the debugger where our code lives in memory: - AdnDebugNativeRegister(sysFileTApplication, appFileCreator, 'ARMC', 1); -#endif - - // get global struct - FtrGet(appFileCreator, ftrVars, (UInt32 *)&tmp); - MemMove(gVars, tmp, sizeof(GlobalsDataType)); - - // init STDIO - stdio_set_cache(0); - stdio_init(gVars->VFS.volRefNum, "/PALM/Programs/ScummVM/scumm.log"); - if (gVars->indicator.showLED) - stdio_set_led(DrawStatus); - stdio_set_cache(gVars->VFS.cacheSize); - - // get args - FtrGet(appFileCreator, ftrArgsData, (UInt32 *)&argvP); - FtrGet(appFileCreator, ftrArgsCount, (UInt32 *)&argc); - - // init system - WinSetDrawWindow(WinGetDisplayWindow()); - if (HWR_INIT(INIT_VIBRATOR)) gVars->vibrator = RumbleInit(); - - // run ... - DO_EXIT ( palm_main(argc, argvP); ) - - // release - if (HWR_INIT(INIT_VIBRATOR)) RumbleRelease(); - stdio_release(); - -#ifdef DEBUG_ARM - AdnDebugNativeUnregister(); -#endif -} - -/* Stack size */ - -Int8 *g_newStack, *g_newStackPos; -void *g_oldStack; - -static asm void *StkSwap(void *newStack ,void *dummy) { - mov r1, r13 - mov r13, r0 - mov r0, r1 - bx lr -} - -extern UInt32 PilotMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) { - if (cmd == sysAppLaunchCmdNormalLaunch) { - FtrGet(appFileCreator, ftrStack, &g_stackSize); - if (!g_stackSize) - g_stackSize = 32 * 1024; - - g_newStack = (Int8 *)malloc(g_stackSize + 8); - g_newStackPos = (g_newStack + g_stackSize); - g_newStackPos -= ((UInt32)g_newStackPos & 7); - - g_oldStack = StkSwap(g_newStackPos, 0); - - Go(); - - StkSwap(g_oldStack, 0); - free(g_newStack); - } - - // Destroy all constructed global objects - __destroy_global_chain(); - - return 0; -} diff --git a/backends/platform/PalmOS/Src/native/zodiacStartup.cpp b/backends/platform/PalmOS/Src/native/zodiacStartup.cpp deleted file mode 100644 index 7f6264c1ac..0000000000 --- a/backends/platform/PalmOS/Src/native/zodiacStartup.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifdef COMPILE_ZODIAC - -#include <TapWave.h> - -#ifndef __PALMOS_ARMLET__ -#error "__PALMOS_ARMLET__ is not defined!!!" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This variable holds the Tapwave Native Application interface - * dispatch table. General ARM API calls will go through this table. - */ -struct TwGlue* twGlue; -const void* twEmulState; -Call68KFuncType* twCall68KFunc; - -#ifdef __MWERKS__ - -#if __PALMOS_ARMLET__ < 0x120 -#error "You must use CodeWarrior for Palm OS 9.3 or later!!!" -#endif - - -UInt32 __ARMlet_Startup__(const void*, void*, Call68KFuncType*); - -/* - * These symbols aren't real, but are linker-generated symbols that - * mark the start and end of the various data sections. - */ -extern long __DataStart__[]; -extern long __sinit__[]; -extern long __RODataStart__[]; -extern long __BSSStart__[]; -extern long __BSSEnd__[]; -extern long __CodeRelocStart__[]; -extern long __CodeRelocEnd__[]; -extern long __DataRelocStart__[]; -extern long __DataRelocEnd__[]; - -/* simple function pointer */ -typedef void (*StaticInitializer)(void); - -/* - * This function performs relocation for Tapwave Native Application. - */ -static void relocate(void) -{ - // this symbol points to the very beginning of current application - long base = (long) __ARMlet_Startup__; - long *cur, *end; - - // handle static initializers - if (__sinit__) { - long s, *p; - - for (p = __sinit__; p && (s = *p) != 0; p++) - ((StaticInitializer)(s + base))(); - } - - // handle code-to-data relocation - cur = __CodeRelocStart__; - end = __CodeRelocEnd__; - for (; cur < end; cur++) { - *(long*)(base + *cur) += base; - } - - // handle data-to-data relocation - cur = __DataRelocStart__; - end = __DataRelocEnd__; - for (; cur < end; cur++) { - *(long*)(base + *cur) += base; - } -} - -/* - * This is the real entrypoint for Tapwave Native Application. It - * depends on various CodeWarrior 9.2 compiler/linker/runtime features. - */ -static SYSTEM_CALLBACK UInt32 -Startup(const void *emulStateP, void *userData68KP, Call68KFuncType *call68KFuncP) -{ - if (emulStateP) { - twEmulState = emulStateP; - twCall68KFunc = call68KFuncP; - // COMMENT: normal pace native object launch - return PilotMain(sysAppLaunchCmdNormalLaunch, userData68KP, 0); - } else { - // Setup TNA interface dispatch table - twGlue = (struct TwGlue*) userData68KP; - - // OPTIONAL: relocate data segment - relocate(); - - // OPTIONAL: initialize the floating-point library - // _fp_init(); - - return 0; - } -} - -#pragma PIC off -asm UInt32 -__ARMlet_Startup__(const void *emulStateP, void *userData68KP, Call68KFuncType *call68KFuncP) -{ - b Startup // 0 forwarding call - nop // 4 - nop // 8 - nop // 12 - nop // 16 - nop // 20 - nop // 24 - dcd 'TWNA' // 28 Tapwave Native Application - dcd 1 // 32 version 1 - dcd 'cdwr' // 36 make this section the same as the __ARMlet_Startup__ - dcd __DataStart__ // 40 used by CodeWarrior 9.2 - dcd __RODataStart__ // 44 - dcd __BSSStart__ // 48 - dcd __BSSEnd__ // 52 - dcd __CodeRelocStart__ // 56 - dcd __CodeRelocEnd__ // 60 - dcd __DataRelocStart__ // 64 - dcd __DataRelocEnd__ // 68 -} -#pragma PIC reset - -#endif // __MWERKS__ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/backends/platform/PalmOS/Src/os5_event.cpp b/backends/platform/PalmOS/Src/os5_event.cpp deleted file mode 100644 index 534c2eb4f9..0000000000 --- a/backends/platform/PalmOS/Src/os5_event.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_os5.h" - -void OSystem_PalmOS5::get_coordinates(EventPtr ev, Coord &x, Coord &y) { - Boolean dummy; - EvtGetPenNative(WinGetDisplayWindow(), &ev->screenX, &ev->screenY, &dummy); - - x = (ev->screenX - _screenOffset.x); - y = (ev->screenY - _screenOffset.y); - - if (_stretched) { - x = (x * _screenWidth) / _screenDest.w; - y = (y * _screenHeight) / _screenDest.h; - } -} - -bool OSystem_PalmOS5::check_event(Common::Event &event, EventPtr ev) { - if (ev->eType == keyUpEvent) { - switch (ev->data.keyUp.chr) { - case vchrHard3: - case vchrHard4: - // will be handled by hard keys - return true; - } - - } else if (ev->eType == keyDownEvent) { - switch (ev->data.keyDown.chr) { - - // hot swap gfx -// case 0x1B04: - case vchrHard1: - if (OPTIONS_TST(kOptCollapsible)) - hotswap_gfx_mode(_mode == GFX_WIDE ? GFX_NORMAL: GFX_WIDE); - return false; // not a key - -// case 0x1B05: - case vchrHard2: - setFeatureState(kFeatureAspectRatioCorrection, 0); - return false; // not a key - - case vchrHard3: - _keyExtraPressed |= _keyExtra.bitActionA; - event.type = Common::EVENT_LBUTTONDOWN; - event.mouse.x = _mouseCurState.x; - event.mouse.y = _mouseCurState.y; - return true; - - case vchrHard4: - _keyExtraPressed |= _keyExtra.bitActionB; - event.type = Common::EVENT_RBUTTONDOWN; - event.mouse.x = _mouseCurState.x; - event.mouse.y = _mouseCurState.y; - return true; - } - } - - return false; -} diff --git a/backends/platform/PalmOS/Src/os5_gfx.cpp b/backends/platform/PalmOS/Src/os5_gfx.cpp deleted file mode 100644 index 6a7b21e100..0000000000 --- a/backends/platform/PalmOS/Src/os5_gfx.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_os5.h" -#include "graphics/surface.h" -#include "common/config-manager.h" -#include <PenInputMgr.h> -#include <palmOneResources.h> - -#include "oscalls.h" - -void OSystem_PalmOS5::int_initSize(uint w, uint h) { -} - -WinHandle OSystem_PalmOS5::alloc_screen(Coord w, Coord h) { - Err e; - WinHandle winH; - UInt16 old = WinSetCoordinateSystem(kCoordinatesNative); - winH = WinCreateOffscreenWindow(w, h, nativeFormat, &e); - WinSetCoordinateSystem(old); - - return winH; -} - -void OSystem_PalmOS5::load_gfx_mode() { - Err e; - - if (_gfxLoaded) - return; - _gfxLoaded = true; - - // get command line config -// _fullscreen = ConfMan.getBool("fullscreen"); // TODO : (NORMAL mode) - _ratio.adjustAspect = ConfMan.getBool("aspect_ratio") ? kRatioHeight : kRatioNone; - - // precalc ratio (WIDE mode) - _ratio.width = (gVars->screenFullHeight * _screenWidth / _screenHeight); - _ratio.height = (gVars->screenFullWidth * _screenHeight / _screenWidth); - - _offScreenP = (byte *)malloc(_screenWidth * _screenHeight); - - MemSet(_offScreenP, _screenWidth * _screenHeight, 0); - MemSet(_nativePal, sizeof(_nativePal), 0); - MemSet(_currentPalette, sizeof(_currentPalette), 0); - - UInt32 depth = 16; - WinScreenMode(winScreenModeSet, NULL, NULL, &depth, NULL); - clear_screen(); - - if (OPTIONS_TST(kOptModeRotatable)) { - _sysOldOrientation = __68K(SysGetOrientation()); - _sysOldTriggerState = __68K(PINGetInputTriggerState()); - __68K(SysSetOrientation(sysOrientationLandscape)); - __68K(SysSetOrientationTriggerState(sysOrientationTriggerDisabled)); - __68K(PINSetInputTriggerState(pinInputTriggerDisabled)); - } - - gVars->indicator.on = Graphics::RGBToColor<Graphics::ColorMasks<565> >(0,255,0); - gVars->indicator.off = Graphics::RGBToColor<Graphics::ColorMasks<565> >(0,0,0); - - _overlayH = alloc_screen(_screenWidth, _screenHeight); - _overlayP = (OverlayColor *)(BmpGetBits(WinGetBitmap(_overlayH))); - - _screenH = WinGetDisplayWindow(); - _screenP = (byte *)(BmpGetBits(WinGetBitmap(_screenH))); - - _isSwitchable = OPTIONS_TST(kOptModeLandscape) && OPTIONS_TST(kOptCollapsible); - if (!_isSwitchable) - _mode = GFX_NORMAL; - - hotswap_gfx_mode(_mode); -} - -void OSystem_PalmOS5::hotswap_gfx_mode(int mode) { - Err e; - - if (_mode != GFX_NORMAL && !_isSwitchable) - return; - - if (_workScreenH) - WinDeleteWindow(_workScreenH, false); - _workScreenH = NULL; - - _screenDest.w = _screenWidth; - _screenDest.h = _screenHeight; - - // prevent bad DIA redraw (Stat part) - if (mode == GFX_NORMAL) { - _redawOSD = true; - _stretched = (_screenWidth > gVars->screenWidth); - - if (OPTIONS_TST(kOptCollapsible)) { - //AiaSetInputAreaState(aiaInputAreaShow); // For T3 ?? - __68K(StatShow()); - __68K(PINSetInputAreaState(pinInputAreaOpen)); - } - - if (_stretched) { - calc_rect(false); - } else { - // offsets - _screenOffset.x = (gVars->screenWidth - _screenWidth) / 2; - _screenOffset.y = (gVars->screenHeight - _screenHeight) / 2; - } - - } else { - _redawOSD = false; - _stretched = true; - - if (OPTIONS_TST(kOptCollapsible)) { - // T3 DIA library is 68k base, there is no possible native call - //AiaSetInputAreaState(aiaInputAreaFullScreen); - __68K(PINSetInputAreaState(pinInputAreaClosed)); - __68K(StatHide()); - } - - calc_rect(true); - } - - if (_stretched) { - OPTIONS_SET(kOptDisableOnScrDisp); - if (_screenHeight == 200 && _screenDest.h == 300) { - _render = &OSystem_PalmOS5::render_landscape15x; - } else { - _render = &OSystem_PalmOS5::render_landscapeAny; - calc_scale(); - } - } else { - OPTIONS_RST(kOptDisableOnScrDisp); - _render = &OSystem_PalmOS5::render_1x; - } - - _workScreenH = alloc_screen(_screenDest.w, _screenDest.h); - _workScreenP = (uint16 *)(BmpGetBits(WinGetBitmap(_workScreenH))); - MemSet(_workScreenP, _screenDest.w * _screenDest.h * 2, 0); - - _mode = mode; - clear_screen(); -} - -void OSystem_PalmOS5::unload_gfx_mode() { - if (!_gfxLoaded) - return; - _gfxLoaded = false; - - // mouse data freed in quit() - free(_offScreenP); - - if (_workScreenH) - WinDeleteWindow(_workScreenH, false); - if (_overlayH) - WinDeleteWindow(_overlayH, false); - - _workScreenH = NULL; - _overlayH = NULL; - - UInt32 depth = 8; - WinScreenMode(winScreenModeSet, NULL, NULL, &depth, NULL); - clear_screen(); - - if (OPTIONS_TST(kOptModeRotatable)) { - __68K(PINSetInputTriggerState(_sysOldTriggerState)); - __68K(SysSetOrientation(_sysOldOrientation)); - } - - WinSetCoordinateSystem(_sysOldCoord); -} - -void OSystem_PalmOS5::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) { - // Clip the coordinates - if (x < 0) { - w += x; - buf -= x; - x = 0; - } - - if (y < 0) { - h += y; - buf -= y * pitch; - y = 0; - } - - if (w > _screenWidth - x) - w = _screenWidth - x; - - if (h > _screenHeight - y) - h = _screenHeight - y; - - if (w <= 0 || h <= 0) - return; - - byte *dst = _offScreenP + y * _screenWidth + x; - - if (w == pitch && w == _screenWidth) { - MemMove(dst, buf, w * h); - } else { - do { - MemMove(dst, buf, w); - dst += _screenWidth; - buf += pitch; - } while (--h); - } -} - -Graphics::Surface *OSystem_PalmOS5::lockScreen() { - _framebuffer.pixels = _offScreenP; - _framebuffer.w = _screenWidth; - _framebuffer.h = _screenHeight; - _framebuffer.pitch = _screenWidth; - _framebuffer.bytesPerPixel = 1; - - return &_framebuffer; -} - -void OSystem_PalmOS5::unlockScreen() { - // The screen is always completely update anyway, so we don't have to force a full update here. -} - -void OSystem_PalmOS5::int_updateScreen() { - RectangleType r; - PointType p; - - draw_mouse(); - ((this)->*(_render))(r, p); - - _sysOldCoord = WinSetCoordinateSystem(kCoordinatesNative); - WinCopyRectangle(_workScreenH, _screenH, &r, p.x, p.y, winPaint); - WinSetCoordinateSystem(_sysOldCoord); - undraw_mouse(); -} - -void OSystem_PalmOS5::clear_screen() { - RGBColorType rgb = { 0,0,0,0 }; - WinSetDrawWindow(WinGetDisplayWindow()); - WinSetBackColorRGB(&rgb, 0); - WinEraseWindow(); -} - -void OSystem_PalmOS5::extras_palette(uint8 index, uint8 r, uint8 g, uint8 b) { - _nativePal[index] = gfxMakeDisplayRGB(r, g, b); -} - -void OSystem_PalmOS5::draw_osd(UInt16 id, Int32 x, Int32 y, Boolean show, UInt8 color) { - if (_mode != GFX_NORMAL) - return; -// MemHandle hTemp = DmGetResource(bitmapRsc, id); - MemHandle hTemp = DmGetResource('abmp', id + 100); - - if (hTemp) { - RGBColorType oldRGB; - static const RGBColorType pal[4] = { - {0,0,255,0}, - {0,255,255,0}, - {0,255,0,0}, - {0,0,0,0} - }; - - BitmapType *bmTemp; - bmTemp = (BitmapType *)MemHandleLock(hTemp); - - Coord w, h; - BmpGetDimensions(bmTemp, &w, &h, 0); - - PointType dst = { _screenOffset.x + x, _screenOffset.y + y }; - RectangleType c, r = { dst.x, dst.y, w, h }; - - UInt16 old = WinSetCoordinateSystem(kCoordinatesNative); - WinSetDrawWindow(_screenH); - WinGetClip(&c); - WinResetClip(); - - if (show) { - WinSetForeColorRGB(&pal[3], &oldRGB); - WinSetBackColorRGB(&pal[color], &oldRGB); - WinDrawBitmap(bmTemp, dst.x, dst.y); - } else { - WinSetBackColorRGB(&pal[3], &oldRGB); - WinFillRectangle(&r, 0); - } - - WinSetClip(&c); - WinSetCoordinateSystem(old); - - MemPtrUnlock(bmTemp); - DmReleaseResource(hTemp); - } -} diff --git a/backends/platform/PalmOS/Src/os5_mouse.cpp b/backends/platform/PalmOS/Src/os5_mouse.cpp deleted file mode 100644 index c019e1607d..0000000000 --- a/backends/platform/PalmOS/Src/os5_mouse.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_os5.h" - -void OSystem_PalmOS5::setCursorPalette(const byte *colors, uint start, uint num) { - for (uint i = 0; i < num; i++) { - _mousePal[i + start] = gfxMakeDisplayRGB(colors[0], colors[1], colors[2]); - colors += 4; - } - - _cursorPaletteDisabled = false; -} - -void OSystem_PalmOS5::disableCursorPalette(bool disable) { - _cursorPaletteDisabled = disable; -} - -// TODO: this code is almost the same as Zodiac version. -void OSystem_PalmOS5::draw_mouse() { - if (!_mouseDataP || _mouseDrawn || !_mouseVisible) - return; - - byte *src = _mouseDataP; - - int x = _mouseCurState.x - _mouseHotspotX; - int y = _mouseCurState.y - _mouseHotspotY; - int w = _mouseCurState.w; - int h = _mouseCurState.h; - - // clip the mouse rect - if (y < 0) { - src -= y * w; - h += y; - y = 0; - } - if (x < 0) { - src -= x; - w += x; - x = 0; - } - - if (h > _screenHeight - y) - h = _screenHeight - y; - if (w > _screenWidth - x) - w = _screenWidth - x; - - if (w <= 0 || h <= 0) - return; - - // store the bounding box so that undraw mouse can restore the area the - // mouse currently covers to its original content - _mouseOldState.x = x; - _mouseOldState.y = y; - _mouseOldState.w = w; - _mouseOldState.h = h; - - byte color; - int ww; - - if (_overlayVisible) { - uint16 *bak = (uint16 *)_mouseBackupP; - uint16 *pal = _cursorPaletteDisabled ? _nativePal : _mousePal; - uint16 *dst = _overlayP + y * _screenWidth + x; - - do { - ww = w; - do { - *bak++ = *dst; - color = *src++; - - // transparent, don't draw - if (color != _mouseKeyColor) - *dst = pal[color]; - dst++; - } while (--ww); - - src += _mouseCurState.w - w; - dst += _screenWidth - w; - } while (--h); - - } else { - byte *bak = _mouseBackupP; - byte *dst =_offScreenP + y * _screenWidth + x; - - do { - ww = w; - do { - *bak++ = *dst; - color = *src++; - - // transparent, don't draw - if (color != _mouseKeyColor) - *dst = color; - dst++; - } while (--ww); - - src += _mouseCurState.w - w; - dst += _screenWidth - w; - } while (--h); - } - - _mouseDrawn = true; -} - -void OSystem_PalmOS5::undraw_mouse() { - if (!_mouseDrawn) - return; - - int h = _mouseOldState.h; - - // no need to do clipping here, since draw_mouse() did that already - if (_overlayVisible) { - uint16 *dst = _overlayP + _mouseOldState.y * _screenWidth + _mouseOldState.x; - uint16 *bak = (uint16 *)_mouseBackupP; - - do { - MemMove(dst, bak, _mouseOldState.w * 2); - dst += _screenWidth; - bak += _mouseOldState.w; - } while (--h); - - } else { - byte *dst = _offScreenP + _mouseOldState.y * _screenWidth + _mouseOldState.x; - byte *bak = _mouseBackupP; - - do { - MemMove(dst, bak, _mouseOldState.w); - dst += _screenWidth; - bak += _mouseOldState.w; - } while (--h); - } - - _mouseDrawn = false; -} diff --git a/backends/platform/PalmOS/Src/os5_overlay.cpp b/backends/platform/PalmOS/Src/os5_overlay.cpp deleted file mode 100644 index 7e16a6b7b9..0000000000 --- a/backends/platform/PalmOS/Src/os5_overlay.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_os5.h" -#include "common/endian.h" - -void OSystem_PalmOS5::showOverlay() { - // hide fight indicator - draw_osd(kDrawFight, _screenDest.w - 34, _screenDest.h + 2, false); - - undraw_mouse(); - _overlayVisible = true; - clearOverlay(); -} - -void OSystem_PalmOS5::hideOverlay() { - undraw_mouse(); - _overlayVisible = false; - _redawOSD = true; -} - -void OSystem_PalmOS5::clearOverlay() { - if (!_overlayVisible) - return; - - byte *src = _offScreenP; - uint16 *dst = _overlayP; - int cnt = _screenWidth * _screenHeight; - do { - *dst++ = _nativePal[*src++]; - } while (--cnt); -} - -void OSystem_PalmOS5::grabOverlay(OverlayColor *buf, int pitch) { - OverlayColor *src = _overlayP; - int h = _screenHeight; - do { - memcpy(buf, src, _screenWidth * 2); - src += _screenWidth; - buf += pitch; - } while (--h); -} - -void OSystem_PalmOS5::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { - if (w == 0 || h == 0) - return; - - OverlayColor *dst = _overlayP + x + y * _screenWidth; - do { - memcpy(dst, buf, w * 2); - dst += _screenWidth; - buf += pitch; - } while (--h); -} diff --git a/backends/platform/PalmOS/Src/os5_renderer.cpp b/backends/platform/PalmOS/Src/os5_renderer.cpp deleted file mode 100644 index fea3ec28d7..0000000000 --- a/backends/platform/PalmOS/Src/os5_renderer.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_os5.h" - -void OSystem_PalmOS5::render_1x(RectangleType &r, PointType &p) { - Coord o = 0; - - if (_overlayVisible) { - uint16 *src = _overlayP; - uint16 *dst = _workScreenP; - MemMove(dst, src, _screenWidth * _screenHeight * 2); - - } else { - byte *src = _offScreenP; - uint16 *dst = _workScreenP; - int cnt = _screenWidth * _screenHeight; - o = _current_shake_pos; - - do { - *dst++ = _nativePal[*src++]; - } while (--cnt); - } - - p.x = _screenOffset.x; - p.y = _screenOffset.y + o; - RctSetRectangle(&r, 0, 0, _screenWidth, _screenHeight - o); -} - -void OSystem_PalmOS5::render_landscapeAny(RectangleType &r, PointType &p) { - Coord x, y, o = 0; - uint16 *dst = _workScreenP; - - if (_overlayVisible) { - for (y = 0; y < _screenDest.h; y++) { - uint16 *src = _overlayP + *(_scaleTableY + y); - for (x = 0; x < _screenDest.w; x++) { - *dst++ = *(src + *(_scaleTableX + x)); - } - } - - } else { - o = _current_shake_pos; - - for (y = 0; y < _screenDest.h; y++) { - byte *src = _offScreenP + *(_scaleTableY + y); - for (x = 0; x < _screenDest.w; x++) { - *dst++ = *(_nativePal + *(src + *(_scaleTableX + x))); - } - } - } - - p.x = _screenOffset.x; - p.y = _screenOffset.y + o; - RctSetRectangle(&r, 0, 0, _screenDest.w, _screenDest.h - o); -} - -void OSystem_PalmOS5::render_landscape15x(RectangleType &r, PointType &p) { - Coord x, y, o = 0; - uint16 *dst = _workScreenP; - - if (_overlayVisible) { - uint16 *src = _overlayP; - - for (y = 0; y < 100; y++) { - // draw 2 lines - for (x = 0; x < 320; x++) { - *dst++ = *src++; - *dst++ = *src; - *dst++ = *src++; - } - // copy the second to the next line - MemMove(dst, dst - 480, 480 * 2); - dst += 480; - } - } else { - byte *src = _offScreenP; - o = _current_shake_pos; - - for (y = 0; y < 100; y++) { - // draw 2 lines - for (x = 0; x < 320; x++) { - *dst++ = _nativePal[*src++]; - *dst++ = _nativePal[*src]; - *dst++ = _nativePal[*src++]; - } - // copy the second to the next line - MemMove(dst, dst - 480, 480 * 2); - dst += 480; - } - } - - p.x = _screenOffset.x; - p.y = _screenOffset.y + o; - RctSetRectangle(&r, 0, 0, 480, 300 - o); -} diff --git a/backends/platform/PalmOS/Src/os5_sound.cpp b/backends/platform/PalmOS/Src/os5_sound.cpp deleted file mode 100644 index 73ab64c0d5..0000000000 --- a/backends/platform/PalmOS/Src/os5_sound.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_os5.h" -#include "common/config-manager.h" -#include "sound/mixer_intern.h" - - -#ifdef PALMOS_ARM -# ifdef COMPILE_ZODIAC -# define SAMPLES_PER_SEC 44100 -# else -# define SAMPLES_PER_SEC 22050 -# endif -#else -# define SAMPLES_PER_SEC 8000 -#endif - - -SoundExType _soundEx; - -static Err sndCallback(void* UserDataP, SndStreamRef stream, void* bufferP, UInt32 *bufferSizeP) { - SoundExType *_soundEx = (SoundExType *)UserDataP; - SoundType *_sound = _soundEx->sound; - - if (_soundEx->set && _soundEx->size) { - MemMove(bufferP, _soundEx->dataP, _soundEx->size); - *bufferSizeP = _soundEx->size; - _soundEx->set = false; - - } else { - _soundEx->size = *bufferSizeP; - MemSet(bufferP, 128, 0); - *bufferSizeP = 128; - } - - return errNone; -} - -void OSystem_PalmOS5::sound_handler() { - if (_sound.active) { - if (_soundEx.size && !_soundEx.set) { - if (!_soundEx.dataP) - _soundEx.dataP = MemPtrNew(_soundEx.size); - - _mixerMgr->mixCallback((byte *)_soundEx.dataP, _soundEx.size); - _soundEx.set = true; - } - }// TODO : no Sound API case -} - -SndStreamVariableBufferCallback OSystem_PalmOS5::sound_callback() { - return sndCallback; -} - -bool OSystem_PalmOS5::setupMixer() { - Err e; - Boolean success = false; - - uint32 samplesPerSec; - if (ConfMan.hasKey("output_rate")) - samplesPerSec = ConfMan.getInt("output_rate"); - else - samplesPerSec = SAMPLES_PER_SEC; - - _mixerMgr = new Audio::MixerImpl(this, samplesPerSec); - - if (!_sound.active) { - if (gVars->fmQuality != FM_QUALITY_INI) { - ConfMan.setBool("FM_medium_quality", (gVars->fmQuality == FM_QUALITY_MED)); - ConfMan.setBool("FM_high_quality", (gVars->fmQuality == FM_QUALITY_HI)); - } - -#if defined (COMPILE_OS5) - CALLBACK_INIT(_soundEx); -#endif - _sound.proc = 0; - _sound.param = _mixerMgr; - _sound.active = true; // always true when we call this function, false when sound is off - - _soundEx.handle = 0; - _soundEx.size = 0; // set by the callback - _soundEx.set = false; - _soundEx.dataP = NULL; // set by the handler - - // try to create sound stream - if (OPTIONS_TST(kOptPalmSoundAPI)) { - e = SndStreamCreateExtended( - &_soundEx.handle, - sndOutput, - sndFormatPCM, - samplesPerSec, - sndInt16Little, - sndStereo, - sound_callback(), - &_soundEx, - 8192 -#ifdef COMPILE_OS5 - ,true -#endif - ); - - e = e ? e : SndStreamStart(_soundEx.handle); - e = e ? e : SndStreamSetVolume(_soundEx.handle, 1024L * gVars->palmVolume / 100); - success = (e == errNone); - - // no Sound API - } else { - _soundEx.size = 512; - _soundEx.dataP = MemPtrNew(_soundEx.size); - } - } - // if not true some scenes (indy3 256,...) may freeze (ESC to skip) - - _mixerMgr->setReady(true); - - return true; -} - -void OSystem_PalmOS5::clearSoundCallback() { - if (_sound.active) { - if (OPTIONS_TST(kOptPalmSoundAPI)) { - SndStreamStop(_soundEx.handle); - SndStreamDelete(_soundEx.handle); - } - - if (_soundEx.dataP) - MemPtrFree(_soundEx.dataP); - } - - _sound.active = false; - _soundEx.handle = NULL; - _soundEx.dataP = NULL; -} diff --git a/backends/platform/PalmOS/Src/os5ex_sound.cpp b/backends/platform/PalmOS/Src/os5ex_sound.cpp deleted file mode 100644 index f27f5a202d..0000000000 --- a/backends/platform/PalmOS/Src/os5ex_sound.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_os5ex.h" -#include "sound/mixer_intern.h" - -static SYSTEM_CALLBACK Err sndCallbackEx(void* UserDataP, SndStreamRef stream, void* bufferP, UInt32 *bufferSizeP) { - CALLBACK_PROLOGUE - SoundType *_sound = ((SoundExType *)UserDataP)->sound; -// ((SoundProc)_sound->proc)(_sound->param, (byte *)bufferP, *bufferSizeP); - - Audio::MixerImpl *_mixerMgr = ( Audio::MixerImpl *)_sound->param; - _mixerMgr->mixCallback((byte *)bufferP, *bufferSizeP); - - CALLBACK_EPILOGUE - return errNone; -} - -SndStreamVariableBufferCallback OSystem_PalmOS5Ex::sound_callback() { - return sndCallbackEx; -} diff --git a/backends/platform/PalmOS/Src/palmdefs.h b/backends/platform/PalmOS/Src/palmdefs.h deleted file mode 100644 index d37b533a21..0000000000 --- a/backends/platform/PalmOS/Src/palmdefs.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef PALMDEFS_H -#define PALMDEFS_H - -#define appFileCreator 'ScVM' -#define sysAppLaunchCustomEngineDelete (sysAppLaunchCmdCustomBase + 0) -#define sysAppLaunchCustomEngineGetInfo (sysAppLaunchCmdCustomBase + 1) - -enum { - GET_NONE = 0, - GET_DATACOMMON = 1 << 1, - GET_DATAENGINE = 1 << 2, - - GET_MODE68K = 1 << 14, - GET_MODEARM = 1 << 15, -}; - -SysAppInfoPtr SysGetAppInfo(SysAppInfoPtr *uiAppPP, SysAppInfoPtr *actionCodeAppPP) - SYS_TRAP(sysTrapSysGetAppInfo); - - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/compile.h b/backends/platform/PalmOS/Src/prefixes/compile.h deleted file mode 100644 index bb7230187a..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/compile.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef __COMPILE_H__ -#define __COMPILE_H__ - -#undef ENABLE_SCUMM -#undef ENABLE_SCUMM_7_8 -#undef ENABLE_HE - -#undef ENABLE_AGOS -#undef ENABLE_SKY -#undef ENABLE_SWORD1 -#undef ENABLE_SWORD2 -#undef ENABLE_QUEEN -#undef ENABLE_SAGA -#undef ENABLE_KYRA -#undef ENABLE_AWE -#undef ENABLE_GOB -#undef ENABLE_LURE -#undef ENABLE_CINE -#undef ENABLE_AGI -#undef ENABLE_TOUCHE -#undef ENABLE_PARALLACTION -#undef ENABLE_CRUISE -#undef ENABLE_DRASCULA - -// ScummVM -#define USE_SCALERS -#define DISABLE_FANCY_THEMES -//#define CT_NO_TRANSPARENCY -//#define REDUCE_MEMORY_USAGE - -#include "compile_base.h" - -//#define DISABLE_ADLIB -//#define DISABLE_LIGHTSPEED - -#ifdef COMPILE_ZODIAC -# undef DISABLE_FANCY_THEMES -# define USE_ZLIB -// set an external ZLIB since save/load implementation -// doesn't support built-in zodiac version which is 1.1.4 -// (seen inflateInit2 which err on "MAX_WBITS + 32") -# define USE_ZLIB_EXTERNAL -# define DISABLE_SONY -#endif - -#ifdef COMPILE_OS5 -# define DISABLE_TAPWAVE -# define USE_ZLIB -#endif - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_agi.h b/backends/platform/PalmOS/Src/prefixes/native_agi.h deleted file mode 100644 index f3feee8c70..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_agi.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_AGI STATIC_PLUGIN - -#undef USE_MAD -#undef USE_VORBIS -#undef USE_TREMOR - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_agos.h b/backends/platform/PalmOS/Src/prefixes/native_agos.h deleted file mode 100644 index 8a804e3116..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_agos.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_AGOS STATIC_PLUGIN - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_cine.h b/backends/platform/PalmOS/Src/prefixes/native_cine.h deleted file mode 100644 index 3d19d9c557..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_cine.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_CINE STATIC_PLUGIN -#define _DEBUG - -#undef USE_MAD -#undef USE_VORBIS -#undef USE_TREMOR - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_common.h b/backends/platform/PalmOS/Src/prefixes/native_common.h deleted file mode 100644 index af4db70932..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_common.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef ZNATIVE_COMMON_H -#define ZNATIVE_COMMON_H - -#include "compile.h" - -#define __TWNEW_H__ - -#define PALMOS_ARM -#define DISABLE_LIGHTSPEED - -#define USE_MAD -#define USE_TREMOR -#define USE_VORBIS -//#define USE_MPEG2 - -// enable assert -//#define _DEBUG - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_cruise.h b/backends/platform/PalmOS/Src/prefixes/native_cruise.h deleted file mode 100644 index 89e6e65a70..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_cruise.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_CRUISE STATIC_PLUGIN - -#undef USE_MAD -#undef USE_VORBIS -#undef USE_TREMOR - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_drascula.h b/backends/platform/PalmOS/Src/prefixes/native_drascula.h deleted file mode 100644 index 35bc381af4..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_drascula.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_DRASCULA STATIC_PLUGIN - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_gob.h b/backends/platform/PalmOS/Src/prefixes/native_gob.h deleted file mode 100644 index 9cb34099d0..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_gob.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_GOB STATIC_PLUGIN - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_kyra.h b/backends/platform/PalmOS/Src/prefixes/native_kyra.h deleted file mode 100644 index 3b09c63a6f..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_kyra.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_KYRA STATIC_PLUGIN - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_lure.h b/backends/platform/PalmOS/Src/prefixes/native_lure.h deleted file mode 100644 index 71835ee644..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_lure.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_LURE STATIC_PLUGIN - -#undef USE_MAD -#undef USE_VORBIS -#undef USE_TREMOR - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_m4.h b/backends/platform/PalmOS/Src/prefixes/native_m4.h deleted file mode 100644 index 3bf85460a6..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_m4.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_M4 STATIC_PLUGIN - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_made.h b/backends/platform/PalmOS/Src/prefixes/native_made.h deleted file mode 100644 index fd439ed181..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_made.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_MADE STATIC_PLUGIN - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_parallaction.h b/backends/platform/PalmOS/Src/prefixes/native_parallaction.h deleted file mode 100644 index e8d46cc382..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_parallaction.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_PARALLACTION STATIC_PLUGIN - -#undef USE_MAD -#undef USE_VORBIS -#undef USE_TREMOR - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_queen.h b/backends/platform/PalmOS/Src/prefixes/native_queen.h deleted file mode 100644 index 85bb5a0a04..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_queen.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_QUEEN STATIC_PLUGIN - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_saga.h b/backends/platform/PalmOS/Src/prefixes/native_saga.h deleted file mode 100644 index 19db05b633..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_saga.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_SAGA STATIC_PLUGIN - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_scumm.h b/backends/platform/PalmOS/Src/prefixes/native_scumm.h deleted file mode 100644 index b8433a3fa8..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_scumm.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_SCUMM STATIC_PLUGIN -#define ENABLE_SCUMM_7_8 -#define ENABLE_HE - -#define USE_ARM_GFX_ASM -#define USE_ARM_SMUSH_ASM - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_sky.h b/backends/platform/PalmOS/Src/prefixes/native_sky.h deleted file mode 100644 index 49b157471f..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_sky.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_SKY STATIC_PLUGIN - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_sword1.h b/backends/platform/PalmOS/Src/prefixes/native_sword1.h deleted file mode 100644 index 6ae7bb9050..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_sword1.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_SWORD1 STATIC_PLUGIN -#define USE_MPEG2 -#define USE_VORBIS - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_sword2.h b/backends/platform/PalmOS/Src/prefixes/native_sword2.h deleted file mode 100644 index 5e9c45b047..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_sword2.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_SWORD2 STATIC_PLUGIN -#undef _DEBUG -#define USE_MPEG2 -#define USE_VORBIS - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_touche.h b/backends/platform/PalmOS/Src/prefixes/native_touche.h deleted file mode 100644 index acf50e2787..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/native_touche.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#include "native_common.h" -#define ENABLE_TOUCHE STATIC_PLUGIN - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/prefix_frontend.h b/backends/platform/PalmOS/Src/prefixes/prefix_frontend.h deleted file mode 100644 index 8473214746..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/prefix_frontend.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -#define PALMOS_68K -#define PALMOS_MODE - -//#define _DEBUG_ENGINE - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/prefix_os5.h b/backends/platform/PalmOS/Src/prefixes/prefix_os5.h deleted file mode 100644 index 6d84c543af..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/prefix_os5.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -// PalmOS -#define PALMOS_MODE -#define PALMOS_68K -#define PALMOS_NATIVE - -#define COMPILE_OS5 -#define DISABLE_SONY -#define DISABLE_PA1LIB - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/prefix_zodiac.h b/backends/platform/PalmOS/Src/prefixes/prefix_zodiac.h deleted file mode 100644 index 49331d356f..0000000000 --- a/backends/platform/PalmOS/Src/prefixes/prefix_zodiac.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PREFIX_H -#define PREFIX_H - -// PalmOS -#define PALMOS_MODE -#define PALMOS_68K -#define PALMOS_NATIVE - -#define COMPILE_ZODIAC -#define DISABLE_SONY -#define DISABLE_PA1LIB - -#endif diff --git a/backends/platform/PalmOS/Src/rumble.cpp b/backends/platform/PalmOS/Src/rumble.cpp deleted file mode 100644 index 513152f49c..0000000000 --- a/backends/platform/PalmOS/Src/rumble.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <PalmOS.h> -#include "globals.h" -#include "vibrate.h" -#include "rumble.h" - -#ifndef DISABLE_TAPWAVE -#include "tapwave.h" - -TwDeviceHandle hRumble; -#endif - -Boolean RumbleExists() { - Boolean exists = false; - Err e; - -#ifndef DISABLE_TAPWAVE - if (OPTIONS_TST(kOptDeviceZodiac)) { - e = TwDeviceOpen(&hRumble, "vibrator0", "w"); - if (!e) { - exists = true; - TwDeviceClose(hRumble); - } - - } else -#endif - { -#ifndef PALMOS_ARM - - UInt32 romVersion; - - e = FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); - if (!e) { - if (romVersion >= sysMakeROMVersion(4,0,0,sysROMStageRelease,0)) { - Boolean active = false; - e = HwrVibrateAttributes(0, kHwrVibrateActive, &active); - exists = (!e) ? true : exists; - } - } -#endif - } - - - return exists; -} - -void RumbleRun(Boolean active) { -#ifndef DISABLE_TAPWAVE - if (OPTIONS_TST(kOptDeviceZodiac)) { - if (active) { - UInt8 buf[] = { '\64', '\100' }; - TwDeviceControl(hRumble, 'play', buf, sizeof(buf)); - } else { - TwDeviceControl(hRumble, 'stop', 0, 0); - } - - } else -#endif - { -#ifndef PALMOS_ARM - UInt32 pattern = active ? 0xFF000000 : 0x00000000; - - HwrVibrateAttributes(1, kHwrVibratePattern, &pattern); - HwrVibrateAttributes(1, kHwrVibrateActive, &active); -#endif - } - -} - -Boolean RumbleInit() { - Boolean done = false; - -#ifndef DISABLE_TAPWAVE - if (OPTIONS_TST(kOptDeviceZodiac)) { - Err e = TwDeviceOpen(&hRumble, "vibrator0", "w"); - done = (!e); - - } else -#endif - { -#ifndef PALMOS_ARM - if (RumbleExists()) { - UInt16 cycle = (SysTicksPerSecond())/2; - UInt32 pattern = 0xFF000000; - UInt16 delay = 1; - UInt16 repeat = 1; - - HwrVibrateAttributes(1, kHwrVibrateRate, &cycle); - HwrVibrateAttributes(1, kHwrVibratePattern, &pattern); - HwrVibrateAttributes(1, kHwrVibrateDelay, &delay); - HwrVibrateAttributes(1, kHwrVibrateRepeatCount, &repeat); - - done = true; - } -#endif - } - return done; -} - -void RumbleRelease() { -#ifndef DISABLE_TAPWAVE - if (OPTIONS_TST(kOptDeviceZodiac)) { - TwDeviceClose(hRumble); - - } else -#endif - { -#ifndef PALMOS_ARM - UInt32 pattern = 0x00000000; - Boolean active = false; - - HwrVibrateAttributes(1, kHwrVibratePattern, &pattern); - HwrVibrateAttributes(1, kHwrVibrateActive, &active); -#endif - } -} diff --git a/backends/platform/PalmOS/Src/rumble.h b/backends/platform/PalmOS/Src/rumble.h deleted file mode 100644 index 680c0eb164..0000000000 --- a/backends/platform/PalmOS/Src/rumble.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef __RUMBLE_H__ -#define __RUMBLE_H__ - -Boolean RumbleExists (); -void RumbleRun (Boolean active); -Boolean RumbleInit (); -void RumbleRelease (); - -#endif diff --git a/backends/platform/PalmOS/Src/snd_pa1.cpp b/backends/platform/PalmOS/Src/snd_pa1.cpp deleted file mode 100644 index ddaf6495f6..0000000000 --- a/backends/platform/PalmOS/Src/snd_pa1.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include <stdlib.h> - -#include "native.h" -#include "globals.h" - -#ifdef COMPILE_PA1SND -# include <endianutils.h> -#endif - - -static Int32 diffLookup[16] = { - 1,3,5,7,9,11,13,15, - -1,-3,-5,-7,-9,-11,-13,-15, -}; - -static Int32 indexScale[16] = { - 0x0e6, 0x0e6, 0x0e6, 0x0e6, 0x133, 0x199, 0x200, 0x266, - 0x0e6, 0x0e6, 0x0e6, 0x0e6, 0x133, 0x199, 0x200, 0x266 /* same value for speedup */ -}; - -static int limit(int val,int min,int max) { - if (val<min) return min; - else if (val>max) return max; - else return val; -} - -void pcm2adpcm(Int16 *src, UInt8 *dst, UInt32 length) { -#ifndef COMPILE_PA1SND -/* - if (OPTIONS_TST(kOptDeviceARM)) { - PnoDescriptor pno; - ARMPa1SndType userData = {src, dst, length}; - - MemPtr armP = _PnoInit(ARM_PA1SND, &pno); - _PnoCall(&pno, &userData); - _PnoFree(&pno, armP); - - return; - } -*/ - int data,val,diff; - int signal,step; -#else - long chan1, chan2; - long data,val,diff; - long signal,step; -#endif - - signal = 0; - step = 0x7F; - length >>= 3; // 16bit stereo -> 4bit mono - - do { - - // high nibble -#ifdef COMPILE_PA1SND - chan1 = ByteSwap16(*src); - src++; - chan2 = ByteSwap16(*src); - src++; - - diff = ((chan1 + chan2) >> 1) - signal; -#else - diff = ((*src++ + *src++) >> 1) - signal; -#endif - diff <<= 3; - diff /= step; - - val = abs(diff) >> 1; - - if (val > 7) val = 7; - if (diff < 0) val+= 8; - - signal+= (step * diffLookup[val]) >> 3; - signal = limit(signal, -32768, 32767); - - step = (step * indexScale[val]) >> 8; - step = limit(step, 0x7F, 0x6000); - - data = val; - - // low nibble -#ifdef COMPILE_PA1SND - chan1 = ByteSwap16(*src); - src++; - chan2 = ByteSwap16(*src); - src++; - - diff = ((chan1 + chan2) >> 1) - signal; -#else - diff = ((*src++ + *src++) >> 1) - signal; -#endif - diff <<= 3; - diff /= step; - - val = abs(diff) >> 1; - - if (val > 7) val = 7; - if (diff < 0) val+= 8; - - signal+= (step * diffLookup[val]) >> 3; - signal = limit(signal, -32768, 32767); - - step = (step * indexScale[val]) >> 8; - step = limit(step, 0x7F, 0x6000); - - data |= val << 4; - - *dst++ = (UInt8)data; - - } while (--length); - -} diff --git a/backends/platform/PalmOS/Src/stuffs.h b/backends/platform/PalmOS/Src/stuffs.h deleted file mode 100644 index 25bf17c8c6..0000000000 --- a/backends/platform/PalmOS/Src/stuffs.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef STUFFS_H -#define STUFFS_H - -enum { - kOptNone = 0, - kOptDeviceARM = 1 << 0x00, - kOptDeviceOS5 = 1 << 0x01, - kOptDeviceClie = 1 << 0x02, - kOptDeviceZodiac = 1 << 0x03, - kOptModeWide = 1 << 0x04, - kOptModeLandscape = 1 << 0x05, - kOptMode16Bit = 1 << 0x06, - kOptModeHiDensity = 1 << 0x07, - kOptCollapsible = 1 << 0x08, - kOptDisableOnScrDisp = 1 << 0x09, - kOpt5WayNavigatorV1 = 1 << 0x0A, - kOpt5WayNavigatorV2 = 1 << 0x0B, - kOptPalmSoundAPI = 1 << 0x0C, - kOptSonyPa1LibAPI = 1 << 0x0D, - kOptGoLcdAPI = 1 << 0x0E, - kOptLightspeedAPI = 1 << 0x0F, - kOptModeRotatable = 1 << 0x10, - - kOptDeviceProcX86 = 1 << 0x1F // DEBUG only -}; - -// WARNING : you need to define OPTIONS_DEF() -#define OPTIONS_TST(x) (OPTIONS_DEF() & (x)) -#define OPTIONS_SET(x) OPTIONS_DEF() |= (x) -#define OPTIONS_RST(x) OPTIONS_DEF() &= ~(x) - -#endif diff --git a/backends/platform/PalmOS/Src/vibrate.h b/backends/platform/PalmOS/Src/vibrate.h deleted file mode 100644 index 37604be5b7..0000000000 --- a/backends/platform/PalmOS/Src/vibrate.h +++ /dev/null @@ -1,61 +0,0 @@ -/********************************************************************** -** ** -** vibrate.h ** -** ** -** Definitions for setting/retrieving the state of the vibrator on ** -** PalmOS 4.x devices. These calls are not officially supported by ** -** Palm Inc and subsidiaries. It is not guaranteed that these calls ** -** will work at all or at least the same on every device. YOU ARE ** -** USING THESE ENTIRELY ON YOUR VERY OWN RISK ! ** -** ** -** Please send corrections to dseifert@dseifert.com ** -**********************************************************************/ - -#include <PalmOS.h> - -/* HwrVibrateAttributes takes three arguments: -** Boolean set Should the setting be set (1) or retrieved (0) -** UInt32 setting what should be set -** void* value pointer to the value to set, or to store the -** retrieved setting -*/ - -Err HwrVibrateAttributes(Boolean set, UInt32 setting, void *value) - SYS_TRAP(sysTrapHwrVibrateAttributes); - -/* to determine whether the vibrator is supported on a specific device, you -** need to make sure that you are running on PalmOS 4.x (so that the -** trap exists), that the attention manager exists and you need to check -** whether HwrVibrateAttributes(0, 1, &active) returns an error code of -** 0. ('active' is a Boolean). -*/ - - -/***************************************************************/ -/* For the second parameter, the following defines can be used */ -/***************************************************************/ - -/* *value points to a Boolean stating the state of the vibrator */ -#define kHwrVibrateActive 1 - -/* *value points to a UInt16, specifying the length of one cycle. -** value is in ticks (1/100 seconds) */ -#define kHwrVibrateRate 2 - -/* *value points to a UInt32, specifying the pattern of vibrating -** -** example: -** 0xFFFFFFFF stay on, no vibrating -** 0x0F0F0F0F vibrate four times in equal intervals -** 0xAAAAAAAA vibrate really fast (not recommended) -** 0x0F0F0000 vibrate twice, then pause -*/ -#define kHwrVibratePattern 3 - -/* *value points to a UInt16, specifying the delay between two -** cycles in ticks */ -#define kHwrVibrateDelay 4 - -/* *value points to a UInt16 specifying the amount of repeats. */ -#define kHwrVibrateRepeatCount 5 - diff --git a/backends/platform/PalmOS/Src/zodiac_event.cpp b/backends/platform/PalmOS/Src/zodiac_event.cpp deleted file mode 100644 index f629c4cbd6..0000000000 --- a/backends/platform/PalmOS/Src/zodiac_event.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_zodiac.h" - -bool OSystem_PalmZodiac::check_event(Common::Event &event, EventPtr ev) { - if (ev->eType == keyUpEvent) { - switch (ev->data.keyDown.chr) { - case vchrActionLeft: - event.type = Common::EVENT_LBUTTONUP; - event.mouse.x = _mouseCurState.x; - event.mouse.y = _mouseCurState.y; - return true; - - case vchrActionRight: - event.type = Common::EVENT_RBUTTONUP; - event.mouse.x = _mouseCurState.x; - event.mouse.y = _mouseCurState.y; - return true; - } - - } else if (ev->eType == keyDownEvent) { - switch (ev->data.keyDown.chr) { - // F5 = menu - case vchrThumbWheelBack: - event.type = Common::EVENT_KEYDOWN; - event.kbd.keycode = Common::KEYCODE_F5; - event.kbd.ascii = Common::ASCII_F5; - event.kbd.flags = 0; - return true; - - case vchrTriggerLeft: - hotswap_gfx_mode(_mode == GFX_WIDE ? GFX_NORMAL: GFX_WIDE); - return false; // not a key - - case vchrTriggerRight: - setFeatureState(kFeatureAspectRatioCorrection, 0); - return false; // not a key - - case vchrActionLeft: - event.type = Common::EVENT_LBUTTONDOWN; - event.mouse.x = _mouseCurState.x; - event.mouse.y = _mouseCurState.y; - return true; - - case vchrActionRight: - event.type = Common::EVENT_RBUTTONDOWN; - event.mouse.x = _mouseCurState.x; - event.mouse.y = _mouseCurState.y; - return true; - - // skip text - case vchrActionDown: - event.type = Common::EVENT_KEYDOWN; - event.kbd.keycode = Common::KEYCODE_PERIOD; - event.kbd.ascii = '.'; - event.kbd.flags = 0; - return true; - - // trun off - case vchrAutoOff: - case vchrPowerOff: - // pause the sound thread if any - if (_sound.active) - SndStreamPause(_soundEx.handle, true); - break; - - case vchrLateWakeup: - // resume the sound thread if any - if (_sound.active) - SndStreamPause(_soundEx.handle, false); - break; - } - - } - - return false; -} diff --git a/backends/platform/PalmOS/Src/zodiac_gfx.cpp b/backends/platform/PalmOS/Src/zodiac_gfx.cpp deleted file mode 100644 index 98c563e101..0000000000 --- a/backends/platform/PalmOS/Src/zodiac_gfx.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_zodiac.h" -#include "common/config-manager.h" -#include "rumble.h" - -static asm Err _TwGfxOpen(void **aResult, void *aInfoResult) { - stmfd sp!, {r4-r11,lr} - ldr r9, [r9] - ldr r9, [r9] - sub sp, sp, #0x24 - mov r6, r0 - mov r7, r1 - ldr pc, =0x200995F0 -} - -int OSystem_PalmZodiac::getDefaultGraphicsMode() const { - return GFX_WIDE; -} - -void OSystem_PalmZodiac::load_gfx_mode() { - Err e; - - if (_gfxLoaded) - return; - _gfxLoaded = true; - - // get command line config - _fullscreen = ConfMan.getBool("fullscreen"); // TODO : (NORMAL mode) - _ratio.adjustAspect = ConfMan.getBool("aspect_ratio") ? kRatioHeight : kRatioNone; - - // precalc ratio (WIDE mode) - _ratio.width = (gVars->screenFullHeight * _screenWidth / _screenHeight); - _ratio.height = (gVars->screenFullWidth * _screenHeight / _screenWidth); - - _offScreenP = (byte *)MemPtrNew(_screenWidth * _screenHeight); - - MemSet(_offScreenP, _screenWidth * _screenHeight, 0); - MemSet(_nativePal, sizeof(_nativePal), 0); - MemSet(_currentPalette, sizeof(_currentPalette), 0); - - UInt32 depth = 16; - WinScreenMode(winScreenModeSet, NULL, NULL, &depth, NULL); - - _sysOldOrientation = SysGetOrientation(); - _sysOldTriggerState = PINGetInputTriggerState(); - SysSetOrientation(sysOrientationLandscape); - SysSetOrientationTriggerState(sysOrientationTriggerDisabled); - PINSetInputTriggerState(pinInputTriggerDisabled); - - gVars->indicator.on = Graphics::RGBToColor<Graphics::ColorMasks<565> >(0,255,0); - gVars->indicator.off = Graphics::RGBToColor<Graphics::ColorMasks<565> >(0,0,0); - - _screenH = WinGetDisplayWindow(); - _screenP = (byte *)BmpGetBits(WinGetBitmap(_screenH)); - - e = _TwGfxOpen((void **)&_gfxH, 0); - e = TwGfxGetPalmDisplaySurface(_gfxH, &_palmScreenP); - - // overlay buffer - TwGfxSurfaceInfoType nfo = { - sizeof(TwGfxSurfaceInfoType), - _screenWidth, _screenHeight, _screenWidth * 2, - twGfxLocationAcceleratorMemory, - twGfxPixelFormatRGB565_LE - }; - e = TwGfxAllocSurface(_gfxH, &_overlayP, &nfo); - - // prepare main bitmap - _srcBmp.size = sizeof(TwGfxBitmapType); - _srcBmp.width = _screenWidth; - _srcBmp.height = _screenHeight; - _srcBmp.rowBytes = _screenWidth; - _srcBmp.pixelFormat = twGfxPixelFormat8bpp; - _srcBmp.data = _offScreenP; - _srcBmp.palette = (UInt16 *)_nativePal; - - _srcRect.x = 0; - _srcRect.y = 0; - _srcRect.w = _screenWidth; - _srcRect.h = _screenHeight; - - hotswap_gfx_mode(_mode); -} - -void OSystem_PalmZodiac::hotswap_gfx_mode(int mode) { - Err e; - TwGfxSetClip(_palmScreenP, 0); - WinSetDrawWindow(_screenH); - - _screenDest.w = _screenWidth; - _screenDest.h = _screenHeight; - - // prevent bad DIA redraw (Stat part) - if (mode == GFX_NORMAL) { - _redawOSD = true; - _stretched = (_screenWidth > gVars->screenWidth); - StatShow(); - PINSetInputAreaState(pinInputAreaOpen); - - if (_stretched) { - calc_rect(false); - } else { - // offsets - _screenOffset.x = (gVars->screenWidth - _screenWidth) / 2; - _screenOffset.y = (gVars->screenHeight - _screenHeight) / 2; - - // clip Tapwave API - TwGfxRectType rt = { _screenOffset.x, _screenOffset.y, _screenWidth, _screenHeight }; - TwGfxSetClip(_palmScreenP, &rt); - } - - } else { - _redawOSD = false; - _stretched = true; - PINSetInputAreaState(pinInputAreaClosed); - StatHide(); - - calc_rect(true); - } - - if (_stretched) { - OPTIONS_SET(kOptDisableOnScrDisp); - TwGfxSetClip(_palmScreenP, &_dstRect); - - if (!_tmpScreenP) { - // wide buffer - TwGfxSurfaceInfoType nfo = { - sizeof(TwGfxSurfaceInfoType), - _screenWidth, _screenHeight, _screenWidth * 2, - twGfxLocationAcceleratorMemory, - twGfxPixelFormatRGB565_LE - }; - e = TwGfxAllocSurface(_gfxH, &_tmpScreenP, &nfo); - } - } else { - OPTIONS_RST(kOptDisableOnScrDisp); - if (_tmpScreenP) { - e = TwGfxFreeSurface(_tmpScreenP); - _tmpScreenP = NULL; - } - } - - _mode = mode; - _srcPos.x = _screenOffset.x; - _srcPos.y = _screenOffset.y; - clear_screen(); -// updateScreen(); -} - -void OSystem_PalmZodiac::unload_gfx_mode() { - Err e; - - if (!_gfxLoaded) - return; - _gfxLoaded = false; - - if (_tmpScreenP) { - e = TwGfxFreeSurface(_tmpScreenP); - _tmpScreenP = NULL; - } - - e = TwGfxFreeSurface(_overlayP); - e = TwGfxClose(_gfxH); - - UInt32 depth = 8; - WinScreenMode(winScreenModeSet, NULL, NULL, &depth, NULL); - clear_screen(); - - MemPtrFree(_offScreenP); - - PINSetInputTriggerState(_sysOldTriggerState); - SysSetOrientation(_sysOldOrientation); - StatShow(); - PINSetInputAreaState(pinInputAreaOpen); -} - -static void rumblePack(Boolean active) { - if (!gVars->vibrator) - return; - - RumbleRun(active); -} - -void OSystem_PalmZodiac::int_setShakePos(int shakeOffset) { - if (shakeOffset == 0) - rumblePack(false); -} - -void OSystem_PalmZodiac::updateScreen() { - Err e; - - // draw the mouse pointer - draw_mouse(); - - // update the screen - if (_overlayVisible) { - if (_stretched) { - TwGfxRectType dst = {_dstRect.x, _dstRect.y, _dstRect.w, _dstRect.h}; - e = TwGfxStretchBlt2(_palmScreenP, &dst, _overlayP, &_srcRect, twGfxStretchFast| (gVars->filter ? twGfxStretchSmooth : 0)); - } else { - e = TwGfxBitBlt(_palmScreenP, &_srcPos, _overlayP, &_srcRect); - } - - } else { - if (_stretched) { - TwGfxPointType pos = {0, 0}; - TwGfxRectType dst = {_dstRect.x, _dstRect.y, _dstRect.w, _dstRect.h}; - - if (_new_shake_pos != _current_shake_pos) { - TwGfxRectType r = { _screenOffset.x, _screenOffset.y, _dstRect.w, _new_shake_pos }; - - if (_new_shake_pos != 0) { - TwGfxFillRect(_palmScreenP, &r, 0); - rumblePack(_new_shake_pos >= 3); - } - r.y += dst.h; - r.h = _current_shake_pos; - TwGfxFillRect(_palmScreenP, &r, 0); - - _current_shake_pos = _new_shake_pos; - dst.y += _new_shake_pos; - } - e = TwGfxDrawBitmap(_tmpScreenP, &pos, &_srcBmp); - e = TwGfxWaitForVBlank(_gfxH); - e = TwGfxStretchBlt2(_palmScreenP, &dst, _tmpScreenP, &_srcRect, twGfxStretchFast| (gVars->filter ? twGfxStretchSmooth : 0)); - - } else { - TwGfxPointType pos = {_srcPos.x, _srcPos.y}; - - if (_new_shake_pos != _current_shake_pos) { - if (_new_shake_pos != 0) { - TwGfxRectType r = { _screenOffset.x, _screenOffset.y, _screenWidth, _new_shake_pos }; - TwGfxFillRect(_palmScreenP, &r, 0); - rumblePack(_new_shake_pos >= 3); - } - _current_shake_pos = _new_shake_pos; - pos.y += _new_shake_pos; - } - e = TwGfxDrawBitmap(_palmScreenP, &pos, &_srcBmp); - } - } - - // undraw the mouse - undraw_mouse(); -} - -void OSystem_PalmZodiac::draw_osd(UInt16 id, Int32 x, Int32 y, Boolean show, UInt8 color) { - if (_mode != GFX_NORMAL) - return; - MemHandle hTemp = DmGetResource(bitmapRsc, id + 100); - - if (hTemp) { - RGBColorType oldRGB; - static const RGBColorType pal[4] = { - {0,0,255,0}, - {0,255,255,0}, - {0,255,0,0}, - {0,0,0,0} - }; - - BitmapType *bmTemp; - bmTemp = (BitmapType *)MemHandleLock(hTemp); - - Coord w, h; - WinGetBitmapDimensions(bmTemp, &w, &h); // return the size of the low density bmp - - PointType dst = { _screenOffset.x + x, _screenOffset.y + y }; - RectangleType c, r = { dst.x, dst.y, w * 2, h * 2 }; - - UInt16 old = WinSetCoordinateSystem(kCoordinatesNative); - WinSetDrawWindow(_screenH); - if (show) { - WinSetForeColorRGB(&pal[3], &oldRGB); - WinSetBackColorRGB(&pal[color], &oldRGB); - WinPaintBitmap(bmTemp, dst.x, dst.y); - } else { - WinSetBackColorRGB(&pal[3], &oldRGB); - WinFillRectangle(&r, 0); - } - WinSetCoordinateSystem(old); - - MemPtrUnlock(bmTemp); - DmReleaseResource(hTemp); - } -} diff --git a/backends/platform/PalmOS/Src/zodiac_mouse.cpp b/backends/platform/PalmOS/Src/zodiac_mouse.cpp deleted file mode 100644 index 39a789aaa1..0000000000 --- a/backends/platform/PalmOS/Src/zodiac_mouse.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_zodiac.h" - -void OSystem_PalmZodiac::draw_mouse() { - if (!_mouseDataP || _mouseDrawn || !_mouseVisible) - return; - - byte *src = _mouseDataP; - - int x = _mouseCurState.x - _mouseHotspotX; - int y = _mouseCurState.y - _mouseHotspotY; - int w = _mouseCurState.w; - int h = _mouseCurState.h; - - // clip the mouse rect - if (y < 0) { - src -= y * w; - h += y; - y = 0; - } - if (x < 0) { - src -= x; - w += x; - x = 0; - } - - if (h > _screenHeight - y) - h = _screenHeight - y; - if (w > _screenWidth - x) - w = _screenWidth - x; - - if (w <= 0 || h <= 0) - return; - - // store the bounding box so that undraw mouse can restore the area the - // mouse currently covers to its original content - _mouseOldState.x = x; - _mouseOldState.y = y; - _mouseOldState.w = w; - _mouseOldState.h = h; - - byte color; - int ww; - - if (_overlayVisible) { - uint16 *bak = (uint16 *)_mouseBackupP; - uint16 *pal = _cursorPaletteDisabled ? _nativePal : _mousePal; - uint16 *dst; - - TwGfxLockSurface(_overlayP, (void **)&dst); - dst += y * _screenWidth + x; - - do { - ww = w; - do { - *bak++ = *dst; - color = *src++; - - // transparent, don't draw - if (color != _mouseKeyColor) - *dst = pal[color]; - dst++; - } while (--ww); - - src += _mouseCurState.w - w; - dst += _screenWidth - w; - } while (--h); - - TwGfxUnlockSurface(_overlayP, true); - - } else { - byte *bak = _mouseBackupP; - byte *dst =_offScreenP + y * _screenWidth + x; - - do { - ww = w; - do { - *bak++ = *dst; - color = *src++; - - // transparent, don't draw - if (color != _mouseKeyColor) - *dst = color; - dst++; - } while (--ww); - - src += _mouseCurState.w - w; - dst += _screenWidth - w; - } while (--h); - } - - _mouseDrawn = true; -} - -void OSystem_PalmZodiac::undraw_mouse() { - if (!_mouseDrawn) - return; - - int h = _mouseOldState.h; - - // no need to do clipping here, since draw_mouse() did that already - if (_overlayVisible) { - uint16 *dst; - uint16 *bak = (uint16 *)_mouseBackupP; - - TwGfxLockSurface(_overlayP, (void **)&dst); - dst += _mouseOldState.y * _screenWidth + _mouseOldState.x; - - do { - MemMove(dst, bak, _mouseOldState.w * 2); - dst += _screenWidth; - bak += _mouseOldState.w; - } while (--h); - - TwGfxUnlockSurface(_overlayP, true); - - } else { - byte *dst = _offScreenP + _mouseOldState.y * _screenWidth + _mouseOldState.x; - byte *bak = _mouseBackupP; - - do { - MemMove(dst, bak, _mouseOldState.w); - dst += _screenWidth; - bak += _mouseOldState.w; - } while (--h); - } - - _mouseDrawn = false; -} diff --git a/backends/platform/PalmOS/Src/zodiac_overlay.cpp b/backends/platform/PalmOS/Src/zodiac_overlay.cpp deleted file mode 100644 index f8322e8fa5..0000000000 --- a/backends/platform/PalmOS/Src/zodiac_overlay.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "be_zodiac.h" -#include "common/endian.h" - -void OSystem_PalmZodiac::clearOverlay() { - if (!_overlayVisible) - return; - - Err e; - TwGfxPointType pos = {0, 0}; - TwGfxBitmapType bmp = { - sizeof(TwGfxBitmapType), - _screenWidth, _screenHeight, _screenWidth, twGfxPixelFormat8bpp, - (void *)_offScreenP, (UInt16 *)_nativePal - }; - e = TwGfxDrawBitmap(_overlayP, &pos, &bmp); -} - -void OSystem_PalmZodiac::grabOverlay(OverlayColor *buf, int pitch) { - Err e; - OverlayColor *src; - - e = TwGfxLockSurface(_overlayP, (void **)&src); - int h = _screenHeight; - do { - memcpy(buf, src, _screenWidth * 2); - src += _screenWidth; - buf += pitch; - } while (--h); - - e = TwGfxUnlockSurface(_overlayP, 0); -} - -void OSystem_PalmZodiac::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { - Err e; - TwGfxPointType pos = {x, y}; - TwGfxBitmapType bmp = { - sizeof(TwGfxBitmapType), - w, h, pitch * 2 , twGfxPixelFormatRGB565_LE, - (void *)buf, 0 - }; - e = TwGfxDrawBitmap(_overlayP, &pos, &bmp); -} diff --git a/backends/platform/PalmOS/arm.bat b/backends/platform/PalmOS/arm.bat deleted file mode 100755 index 547ae391fe..0000000000 --- a/backends/platform/PalmOS/arm.bat +++ /dev/null @@ -1,3 +0,0 @@ -as.exe --defsym PALMOS_MODE=1 ../../../sound/rate_arm_asm.s -o Obj/rate_arm_asm.o -as.exe --defsym PALMOS_MODE=1 ../../../engines/scumm/gfxARM.s -o Obj/gfxARM.o -as.exe --defsym PALMOS_MODE=1 ../../../engines/scumm/smush/codec47ARM.s -o Obj/codec47ARM.o diff --git a/backends/platform/PalmOS/scummvm.mcp b/backends/platform/PalmOS/scummvm.mcp Binary files differdeleted file mode 100644 index a01967d059..0000000000 --- a/backends/platform/PalmOS/scummvm.mcp +++ /dev/null diff --git a/backends/platform/android/README.build b/backends/platform/android/README.build index 3d1cf433a7..1c407bd469 100644 --- a/backends/platform/android/README.build +++ b/backends/platform/android/README.build @@ -67,10 +67,6 @@ toolchains around. Building ScummVM ================ -Apply the theme engine patch: - - patch -p1 < backends/platform/android/scummvm-android-themeengine.patch - (Optionally) compress scummmodern.zip: (ScummVM usually ships it uncompressed, but Android can read it more efficiently if it is compressed *before* adding it to the apk) diff --git a/backends/platform/android/module.mk b/backends/platform/android/module.mk index c7b98b996d..b457b388b1 100644 --- a/backends/platform/android/module.mk +++ b/backends/platform/android/module.mk @@ -3,11 +3,10 @@ MODULE := backends/platform/android MODULE_OBJS := \ android.o asset-archive.o video.o -MODULE_DIRS += \ - backends/platform/android/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) JAVA_SRC = \ $(MODULE)/org/inodes/gus/scummvm/ScummVM.java \ diff --git a/backends/platform/android/scummvm-android-themeengine.patch b/backends/platform/android/scummvm-android-themeengine.patch deleted file mode 100644 index 1eafe7fb62..0000000000 --- a/backends/platform/android/scummvm-android-themeengine.patch +++ /dev/null @@ -1,135 +0,0 @@ -diff -r 884e66fd1b9c gui/ThemeEngine.cpp ---- a/gui/ThemeEngine.cpp Tue Apr 13 09:30:52 2010 +1000 -+++ b/gui/ThemeEngine.cpp Fri May 28 23:24:43 2010 +1000 -@@ -390,21 +390,19 @@ - - // Try to create a Common::Archive with the files of the theme. - if (!_themeArchive && !_themeFile.empty()) { -- Common::FSNode node(_themeFile); -- if (node.getName().hasSuffix(".zip") && !node.isDirectory()) { -+ Common::ArchiveMemberPtr member = SearchMan.getMember(_themeFile); -+ if (member && member->getName().hasSuffix(".zip")) { - #ifdef USE_ZLIB -- Common::Archive *zipArchive = Common::makeZipArchive(node); -+ Common::Archive *zipArchive = Common::makeZipArchive(member->createReadStream()); - - if (!zipArchive) { -- warning("Failed to open Zip archive '%s'.", node.getPath().c_str()); -+ warning("Failed to open Zip archive '%s'.", member->getDisplayName().c_str()); - } - _themeArchive = zipArchive; - #else - warning("Trying to load theme '%s' in a Zip archive without zLib support", _themeFile.c_str()); - return false; - #endif -- } else if (node.isDirectory()) { -- _themeArchive = new Common::FSDirectory(node); - } - } - -@@ -1436,6 +1434,30 @@ - return tok.empty(); - } - -+bool ThemeEngine::themeConfigUsable(const Common::ArchiveMember &member, Common::String &themeName) { -+ Common::File stream; -+ bool foundHeader = false; -+ -+ if (member.getName().hasSuffix(".zip")) { -+#ifdef USE_ZLIB -+ Common::Archive *zipArchive = Common::makeZipArchive(member.createReadStream()); -+ -+ if (zipArchive && zipArchive->hasFile("THEMERC")) { -+ stream.open("THEMERC", *zipArchive); -+ } -+ -+ delete zipArchive; -+#endif -+ } -+ -+ if (stream.isOpen()) { -+ Common::String stxHeader = stream.readLine(); -+ foundHeader = themeConfigParseHeader(stxHeader, themeName); -+ } -+ -+ return foundHeader; -+} -+ - bool ThemeEngine::themeConfigUsable(const Common::FSNode &node, Common::String &themeName) { - Common::File stream; - bool foundHeader = false; -@@ -1493,10 +1515,6 @@ - if (ConfMan.hasKey("themepath")) - listUsableThemes(Common::FSNode(ConfMan.get("themepath")), list); - --#ifdef DATA_PATH -- listUsableThemes(Common::FSNode(DATA_PATH), list); --#endif -- - #if defined(MACOSX) || defined(IPHONE) - CFURLRef resourceUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - if (resourceUrl) { -@@ -1509,10 +1527,7 @@ - } - #endif - -- if (ConfMan.hasKey("extrapath")) -- listUsableThemes(Common::FSNode(ConfMan.get("extrapath")), list); -- -- listUsableThemes(Common::FSNode("."), list, 1); -+ listUsableThemes(SearchMan, list); - - // Now we need to strip all duplicates - // TODO: It might not be the best idea to strip duplicates. The user might -@@ -1531,6 +1546,34 @@ - output.clear(); - } - -+void ThemeEngine::listUsableThemes(Common::Archive &archive, Common::List<ThemeDescriptor> &list) { -+ ThemeDescriptor td; -+ -+#ifdef USE_ZLIB -+ Common::ArchiveMemberList fileList; -+ archive.listMatchingMembers(fileList, "*.zip"); -+ for (Common::ArchiveMemberList::iterator i = fileList.begin(); -+ i != fileList.end(); ++i) { -+ td.name.clear(); -+ if (themeConfigUsable(**i, td.name)) { -+ td.filename = (*i)->getName(); -+ td.id = (*i)->getDisplayName(); -+ -+ // If the name of the node object also contains -+ // the ".zip" suffix, we will strip it. -+ if (td.id.hasSuffix(".zip")) { -+ for (int j = 0; j < 4; ++j) -+ td.id.deleteLastChar(); -+ } -+ -+ list.push_back(td); -+ } -+ } -+ -+ fileList.clear(); -+#endif -+} -+ - void ThemeEngine::listUsableThemes(const Common::FSNode &node, Common::List<ThemeDescriptor> &list, int depth) { - if (!node.exists() || !node.isReadable() || !node.isDirectory()) - return; -diff -r 884e66fd1b9c gui/ThemeEngine.h ---- a/gui/ThemeEngine.h Tue Apr 13 09:30:52 2010 +1000 -+++ b/gui/ThemeEngine.h Fri May 28 23:24:43 2010 +1000 -@@ -560,11 +560,13 @@ - static void listUsableThemes(Common::List<ThemeDescriptor> &list); - private: - static bool themeConfigUsable(const Common::FSNode &node, Common::String &themeName); -+ static bool themeConfigUsable(const Common::ArchiveMember &member, Common::String &themeName); - static bool themeConfigParseHeader(Common::String header, Common::String &themeName); - - static Common::String getThemeFile(const Common::String &id); - static Common::String getThemeId(const Common::String &filename); - static void listUsableThemes(const Common::FSNode &node, Common::List<ThemeDescriptor> &list, int depth = -1); -+ static void listUsableThemes(Common::Archive &archive, Common::List<ThemeDescriptor> &list); - - protected: - OSystem *_system; /** Global system object. */ diff --git a/backends/platform/dc/Makefile b/backends/platform/dc/Makefile index 2dcf9b7a7c..4494e8da78 100644 --- a/backends/platform/dc/Makefile +++ b/backends/platform/dc/Makefile @@ -69,6 +69,8 @@ OBJS := dcmain.o time.o display.o audio.o input.o selector.o icon.o \ MODULE_DIRS += ./ +BACKEND := dc + include $(srcdir)/Makefile.common scummvm.bin : scummvm.elf diff --git a/backends/platform/dc/dc.h b/backends/platform/dc/dc.h index e87a0a8c90..057ab283cf 100644 --- a/backends/platform/dc/dc.h +++ b/backends/platform/dc/dc.h @@ -233,6 +233,9 @@ class OSystem_Dreamcast : private DCHardware, public BaseBackend, public Filesys Common::SaveFileManager *createSavefileManager(); + + Common::SeekableReadStream *createConfigReadStream(); + Common::WriteStream *createConfigWriteStream(); }; diff --git a/backends/platform/dc/dcmain.cpp b/backends/platform/dc/dcmain.cpp index 5a9286093f..5fde919650 100644 --- a/backends/platform/dc/dcmain.cpp +++ b/backends/platform/dc/dcmain.cpp @@ -31,6 +31,7 @@ #include "icon.h" #include "DCLauncherDialog.h" #include <common/config-manager.h> +#include <common/stream.h> #include "backends/plugins/dc/dc-provider.h" #include "sound/mixer_intern.h" @@ -206,6 +207,16 @@ void OSystem_Dreamcast::getTimeAndDate(TimeDate &td) const { td.tm_year = t.tm_year; } +Common::SeekableReadStream *OSystem_Dreamcast::createConfigReadStream() { + Common::FSNode file("/scummvm.ini"); + Common::SeekableReadStream *s = file.createReadStream(); + return s? s : new Common::MemoryReadStream((const byte *)"", 0); +} + +Common::WriteStream *OSystem_Dreamcast::createConfigWriteStream() { + return 0; +} + void DCHardware::dc_init_hardware() { #ifndef NOSERIAL diff --git a/backends/platform/dc/module.mk b/backends/platform/dc/module.mk index eecb91909c..c52ca1a474 100644 --- a/backends/platform/dc/module.mk +++ b/backends/platform/dc/module.mk @@ -3,8 +3,7 @@ MODULE := backends/platform/dc MODULE_OBJS := dcmain.o time.o display.o audio.o input.o selector.o icon.o \ label.o vmsave.o softkbd.o dcloader.o cache.o dc-fs.o -MODULE_DIRS += \ - backends/platform/dc/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) diff --git a/backends/platform/dc/selector.cpp b/backends/platform/dc/selector.cpp index 0d8e0a0188..0d9b931d2c 100644 --- a/backends/platform/dc/selector.cpp +++ b/backends/platform/dc/selector.cpp @@ -30,6 +30,7 @@ #include <base/plugins.h> #include <common/fs.h> #include <common/events.h> +#include <common/config-manager.h> #include "dc.h" #include "icon.h" #include "label.h" @@ -200,12 +201,43 @@ static bool uniqueGame(const char *base, const char *dir, return true; } -static int findGames(Game *games, int max) +static int findGames(Game *games, int max, bool use_ini) { Dir *dirs = new Dir[MAX_DIR]; - int curr_game = 0, curr_dir = 0, num_dirs = 1; - dirs[0].node = Common::FSNode(""); - while (curr_game < max && curr_dir < num_dirs) { + int curr_game = 0, curr_dir = 0, num_dirs = 0; + + if (use_ini) { + ConfMan.loadDefaultConfigFile(); + Common::ConfigManager::DomainMap &game_domains = ConfMan.getGameDomains(); + for(Common::ConfigManager::DomainMap::const_iterator i = + game_domains.begin(); curr_game < max && i != game_domains.end(); i++) { + Common::String path = (*i)._value["path"]; + if (path.size() && path.lastChar() != '/') + path += "/"; + int j; + for (j=0; j<num_dirs; j++) + if (path.equals(dirs[j].node.getPath())) + break; + if (j >= num_dirs) { + if (num_dirs >= MAX_DIR) + continue; + dirs[j = num_dirs++].node = Common::FSNode(path); + } + if (curr_game < max) { + strcpy(games[curr_game].filename_base, (*i)._key.c_str()); + strncpy(games[curr_game].dir, dirs[j].node.getPath().c_str(), 256); + games[curr_game].dir[255] = '\0'; + games[curr_game].language = Common::UNK_LANG; + games[curr_game].platform = Common::kPlatformUnknown; + strcpy(games[curr_game].text, (*i)._value["description"].c_str()); + curr_game++; + } + } + } else { + dirs[num_dirs++].node = Common::FSNode(""); + } + + while ((curr_game < max || use_ini) && curr_dir < num_dirs) { strncpy(dirs[curr_dir].name, dirs[curr_dir].node.getPath().c_str(), 252); dirs[curr_dir].name[251] = '\0'; dirs[curr_dir].deficon[0] = '\0'; @@ -214,44 +246,46 @@ static int findGames(Game *games, int max) for (Common::FSList::const_iterator entry = fslist.begin(); entry != fslist.end(); ++entry) { if (entry->isDirectory()) { - if (num_dirs < MAX_DIR && strcasecmp(entry->getDisplayName().c_str(), - "install")) { + if (!use_ini && num_dirs < MAX_DIR && + strcasecmp(entry->getDisplayName().c_str(), "install")) { dirs[num_dirs].node = *entry; num_dirs++; } } else if (isIcon(*entry)) strcpy(dirs[curr_dir-1].deficon, entry->getDisplayName().c_str()); - else + else if(!use_ini) files.push_back(*entry); } - GameList candidates = EngineMan.detectGames(files); - - for (GameList::const_iterator ge = candidates.begin(); - ge != candidates.end(); ++ge) - if (curr_game < max) { - strcpy(games[curr_game].filename_base, ge->gameid().c_str()); - strcpy(games[curr_game].dir, dirs[curr_dir-1].name); - games[curr_game].language = ge->language(); - games[curr_game].platform = ge->platform(); - if (uniqueGame(games[curr_game].filename_base, - games[curr_game].dir, - games[curr_game].language, - games[curr_game].platform, games, curr_game)) { - - strcpy(games[curr_game].text, ge->description().c_str()); + if (!use_ini) { + GameList candidates = EngineMan.detectGames(files); + + for (GameList::const_iterator ge = candidates.begin(); + ge != candidates.end(); ++ge) + if (curr_game < max) { + strcpy(games[curr_game].filename_base, ge->gameid().c_str()); + strcpy(games[curr_game].dir, dirs[curr_dir-1].name); + games[curr_game].language = ge->language(); + games[curr_game].platform = ge->platform(); + if (uniqueGame(games[curr_game].filename_base, + games[curr_game].dir, + games[curr_game].language, + games[curr_game].platform, games, curr_game)) { + + strcpy(games[curr_game].text, ge->description().c_str()); #if 0 - printf("Registered game <%s> (l:%d p:%d) in <%s> <%s> because of <%s> <*>\n", - games[curr_game].text, - (int)games[curr_game].language, - (int)games[curr_game].platform, - games[curr_game].dir, games[curr_game].filename_base, - dirs[curr_dir-1].name); + printf("Registered game <%s> (l:%d p:%d) in <%s> <%s> because of <%s> <*>\n", + games[curr_game].text, + (int)games[curr_game].language, + (int)games[curr_game].platform, + games[curr_game].dir, games[curr_game].filename_base, + dirs[curr_dir-1].name); #endif - curr_game++; + curr_game++; + } } - } + } } for (int i=0; i<curr_game; i++) @@ -426,7 +460,9 @@ bool selectGame(char *&ret, char *&dir_ret, Common::Language &lang_ret, Common:: void *mark = ta_txmark(); for (;;) { - num_games = findGames(games, MAX_GAMES); + num_games = findGames(games, MAX_GAMES, true); + if (!num_games) + num_games = findGames(games, MAX_GAMES, false); for (int i=0; i<num_games; i++) { games[i].icon.create_texture(); diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 079e23aec0..fac50178b4 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -110,7 +110,7 @@ USE_ARM_COSTUME_ASM = 1 #WRAP_MALLOC = 1 ifdef DS_BUILD_A - DEFINES = -DDS_SCUMM_BUILD -DDS_BUILD_A -DUSE_ARM_GFX_ASM -DUSE_ARM_COSTUME_ASM + DEFINES = -DDS_BUILD_A -DUSE_ARM_GFX_ASM -DUSE_ARM_COSTUME_ASM LOGO = logoa.bmp ENABLE_SCUMM = STATIC_PLUGIN USE_ARM_GFX_ASM = 1 @@ -118,7 +118,7 @@ ifdef DS_BUILD_A endif ifdef DS_BUILD_B - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_B + DEFINES = -DDS_BUILD_B LOGO = logob.bmp ENABLE_SKY = STATIC_PLUGIN ENABLE_QUEEN = STATIC_PLUGIN @@ -126,14 +126,14 @@ ifdef DS_BUILD_B endif ifdef DS_BUILD_C - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_C + DEFINES = -DDS_BUILD_C LOGO = logoc.bmp ENABLE_AGOS = STATIC_PLUGIN BUILD=scummvm-C endif ifdef DS_BUILD_D - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_D + DEFINES = -DDS_BUILD_D LOGO = logod.bmp ENABLE_GOB = STATIC_PLUGIN ENABLE_CINE = STATIC_PLUGIN @@ -142,42 +142,42 @@ ifdef DS_BUILD_D endif ifdef DS_BUILD_E - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_E + DEFINES = -DDS_BUILD_E LOGO = logoe.bmp ENABLE_SAGA = STATIC_PLUGIN BUILD=scummvm-E endif ifdef DS_BUILD_F - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_F + DEFINES = -DDS_BUILD_F LOGO = logof.bmp ENABLE_KYRA = STATIC_PLUGIN BUILD=scummvm-F endif ifdef DS_BUILD_G - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_G + DEFINES = -DDS_BUILD_G LOGO = logog.bmp ENABLE_LURE = STATIC_PLUGIN BUILD=scummvm-G endif ifdef DS_BUILD_H - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_H + DEFINES = -DDS_BUILD_H LOGO = logoh.bmp ENABLE_PARALLACTION = STATIC_PLUGIN BUILD=scummvm-H endif ifdef DS_BUILD_I - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_I + DEFINES = -DDS_BUILD_I LOGO = logoi.bmp ENABLE_MADE = STATIC_PLUGIN BUILD=scummvm-I endif ifdef DS_BUILD_K - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_K + DEFINES = -DDS_BUILD_K LOGO = logok.bmp ENABLE_CRUISE = STATIC_PLUGIN BUILD=scummvm-K @@ -185,14 +185,14 @@ endif #ifdef DS_BUILD_L -# DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_L +# DEFINES = -DDS_BUILD_L # LOGO = logog.bmp # ENABLE_DRASCULA = STATIC_PLUGIN # BUILD=scummvm-K #endif #ifdef DS_BUILD_M -# DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_M +# DEFINES = -DDS_BUILD_M # LOGO = logog.bmp # ENABLE_TUCKER = STATIC_PLUGIN # BUILD=scummvm-K @@ -251,6 +251,8 @@ ifdef WRAP_MALLOC DEFINES += -DWRAP_MALLOC endif +BACKEND := ds + INCLUDES= -I$(portdir)/$(BUILD) -I$(srcdir) -I$(srcdir)/engines \ -I$(portdir)/data -I$(portdir)/../commoninclude \ -I$(portdir)/source -I$(portdir)/source/mad \ diff --git a/backends/platform/ds/arm9/source/dsoptions.cpp b/backends/platform/ds/arm9/source/dsoptions.cpp index cc89c41017..6721a4910a 100644 --- a/backends/platform/ds/arm9/source/dsoptions.cpp +++ b/backends/platform/ds/arm9/source/dsoptions.cpp @@ -128,12 +128,6 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) { _radioButtonMode = false; -#ifdef DS_SCUMM_BUILD - if (!DS::isGBAMPAvailable()) { -// addButton(this, 100, 140, "Delete Save", 0, 'dels', 'D'); - } -#endif - // new GUI::StaticTextWidget(this, 90, 10, 130, 15, "ScummVM DS Options", Graphics::kTextAlignCenter); diff --git a/backends/platform/ds/ds.mk b/backends/platform/ds/ds.mk index 27309663d1..97f104c391 100644 --- a/backends/platform/ds/ds.mk +++ b/backends/platform/ds/ds.mk @@ -12,6 +12,11 @@ # build I: --enable-made --disable-mad # build K: --enable-cruise --disable-mad # +# However, this could be automated using a simple script, which generates +# subdirs for each build, and runs configure in those subdirs with the right +# parameters (all builds would still share the same set of source code files, +# thanks to our "out of tree" building support). +# # This does not currently take care of some things: # * It does not #define DS_BUILD_A etc. -- most uses of that should be # eliminated, though. Only usage should be for selecting the default config @@ -21,6 +26,9 @@ # too; we need to investigate those. # * It does not currently adjust the logo. Ideally, if we ever get real plugin # support, that should be necessary anymore anyway. +# * No support for USE_DEBUGGER and USE_PROFILER yet. I envision that we would +# integrate them with the --enable-debug and --enable-profiling configure options, +# I simply haven't gotten around to do that yet. # * ... # Set location of ndsdir so that we can easily refer to files in it @@ -59,6 +67,12 @@ LOGO = logoa.bmp # folder. +ifdef WRAP_MALLOC + LDFLAGS += -Wl,--wrap,malloc + DEFINES += -DWRAP_MALLOC +endif + + # Compiler options for files which should be optimised for speed OPT_SPEED := -O3 diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk index f6b69b3633..7298267db4 100644 --- a/backends/platform/ds/module.mk +++ b/backends/platform/ds/module.mk @@ -8,7 +8,6 @@ PORT_OBJS := \ arm9/source/blitters_arm.o \ arm9/source/cdaudio.o \ arm9/source/dsmain.o \ - ../../fs/ds/ds-fs.o \ arm9/source/gbampsave.o \ arm9/source/scummhelp.o \ arm9/source/osystem_ds.o \ @@ -99,11 +98,10 @@ $(MODULE)/arm9/source/touchkeyboard.o: \ MODULE_DIRS += \ - backends/platform/ds/ \ backends/platform/ds/arm7/source/ \ backends/platform/ds/arm7/source/libcartreset/ \ - backends/platform/ds/arm9/source/ \ - backends/platform/ds/arm9/source/fat/ -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) diff --git a/backends/platform/gp2x/module.mk b/backends/platform/gp2x/module.mk index 362611da9c..837ad99d7b 100644 --- a/backends/platform/gp2x/module.mk +++ b/backends/platform/gp2x/module.mk @@ -6,8 +6,7 @@ MODULE_OBJS := \ gp2x-mem.o \ gp2x.o -MODULE_DIRS += \ - backends/platform/gp2x/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) diff --git a/backends/platform/gp2xwiz/module.mk b/backends/platform/gp2xwiz/module.mk index 9e66494f27..cca77058af 100644 --- a/backends/platform/gp2xwiz/module.mk +++ b/backends/platform/gp2xwiz/module.mk @@ -5,11 +5,10 @@ MODULE_OBJS := \ gp2xwiz-main.o \ gp2xwiz-sdl.o -MODULE_DIRS += \ - backends/platform/gp2xwiz/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) # Hack to ensure the SDL backend is built so we can use OSystem_SDL. -include $(srcdir)/backends/platform/sdl/module.mk
\ No newline at end of file diff --git a/backends/platform/iphone/module.mk b/backends/platform/iphone/module.mk index 28bc8d3ac7..9768e6ded4 100644 --- a/backends/platform/iphone/module.mk +++ b/backends/platform/iphone/module.mk @@ -10,8 +10,7 @@ MODULE_OBJS := \ iphone_keyboard.o \ blit_arm.o -MODULE_DIRS += \ - backends/platform/iphone/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) diff --git a/backends/platform/linuxmoto/module.mk b/backends/platform/linuxmoto/module.mk index 23f578b841..c604d69da1 100644 --- a/backends/platform/linuxmoto/module.mk +++ b/backends/platform/linuxmoto/module.mk @@ -5,11 +5,10 @@ MODULE_OBJS := \ linuxmoto-sdl.o \ hardwarekeys.o -MODULE_DIRS += \ - backends/platform/linuxmoto/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) # HACK: The linuxmoto backend is based on the SDL one, so we load that, too. include $(srcdir)/backends/platform/sdl/module.mk diff --git a/backends/platform/n64/Makefile b/backends/platform/n64/Makefile index 914e6e9c9e..b8b2e61f77 100644 --- a/backends/platform/n64/Makefile +++ b/backends/platform/n64/Makefile @@ -64,6 +64,8 @@ ENABLE_SCUMM = $(ENABLED) OBJS := nintendo64.o osys_n64_base.o osys_n64_events.o osys_n64_utilities.o pakfs_save_manager.o framfs_save_manager.o +BACKEND := n64 + include $(srcdir)/Makefile.common MODULE_DIRS += ./ diff --git a/backends/platform/n64/module.mk b/backends/platform/n64/module.mk index 34a7badb44..8fb6ba49ab 100644 --- a/backends/platform/n64/module.mk +++ b/backends/platform/n64/module.mk @@ -3,8 +3,7 @@ MODULE := backends/platform/n64 MODULE_OBJS := \ nintendo64.o -MODULE_DIRS += \ - backends/platform/n64/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) diff --git a/backends/platform/null/module.mk b/backends/platform/null/module.mk index 12a2cbc510..30345d7ac2 100644 --- a/backends/platform/null/module.mk +++ b/backends/platform/null/module.mk @@ -3,8 +3,7 @@ MODULE := backends/platform/null MODULE_OBJS := \ null.o -MODULE_DIRS += \ - backends/platform/null/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) diff --git a/backends/platform/ps2/Makefile.gdb b/backends/platform/ps2/Makefile.gdb index 41ac58d629..53646a9546 100644 --- a/backends/platform/ps2/Makefile.gdb +++ b/backends/platform/ps2/Makefile.gdb @@ -75,6 +75,8 @@ OBJS := backends/platform/ps2/DmaPipe.o \ MODULE_DIRS += . +BACKEND := ps2 + include $(srcdir)/Makefile.common LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T $(PS2SDK)/ee/startup/linkfile diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index bf7ac0aca0..d2a8d210e4 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -75,6 +75,8 @@ OBJS := backends/platform/ps2/DmaPipe.o \ MODULE_DIRS += . +BACKEND := ps2 + include $(srcdir)/Makefile.common LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T $(PS2SDK)/ee/startup/linkfile diff --git a/backends/platform/ps2/module.mk b/backends/platform/ps2/module.mk index 86b12cb668..bf95a5501d 100644 --- a/backends/platform/ps2/module.mk +++ b/backends/platform/ps2/module.mk @@ -18,8 +18,7 @@ MODULE_OBJS := \ ps2time.o \ ps2debug.o -MODULE_DIRS += \ - backends/platform/ps2/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) diff --git a/backends/platform/psp/Makefile b/backends/platform/psp/Makefile index fed558eaad..617ef7c8cc 100644 --- a/backends/platform/psp/Makefile +++ b/backends/platform/psp/Makefile @@ -64,7 +64,6 @@ ifeq ($(PSPSDK),) $(error $$(PSPSDK) cannot be obtained.) endif - # Variables for common Scummvm makefile CXX = psp-g++ CXXFLAGS = -O3 -Wall -Wno-multichar -fno-exceptions -fno-rtti @@ -148,7 +147,10 @@ OBJS := powerman.o \ audio.o \ thread.o \ rtc.o \ - mp3.o + mp3.o \ + tests.o + +BACKEND := psp # Include common Scummvm makefile include $(srcdir)/Makefile.common diff --git a/backends/platform/psp/display_client.cpp b/backends/platform/psp/display_client.cpp index c5a6250188..71b505ec7c 100644 --- a/backends/platform/psp/display_client.cpp +++ b/backends/platform/psp/display_client.cpp @@ -340,11 +340,17 @@ void Buffer::copyFromRect(const byte *buf, uint32 pitch, int destX, int destY, u if (pitch == realWidthInBytes && pitch == recWidthInBytes) { //memcpy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth)); - Copier::copy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth), &_pixelFormat); + if (_pixelFormat.swapRB) + PspMemory::fastSwap(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth), _pixelFormat); + else + PspMemory::fastCopy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth)); } else { do { //memcpy(dst, buf, recWidthInBytes); - Copier::copy(dst, buf, recWidthInBytes, &_pixelFormat); + if (_pixelFormat.swapRB) + PspMemory::fastSwap(dst, buf, recWidthInBytes, _pixelFormat); + else + PspMemory::fastCopy(dst, buf, recWidthInBytes); buf += pitch; dst += realWidthInBytes; } while (--recHeight); @@ -363,7 +369,10 @@ void Buffer::copyToArray(byte *dst, int pitch) { do { //memcpy(dst, src, sourceWidthInBytes); - Copier::copy(dst, src, sourceWidthInBytes, &_pixelFormat); + if (_pixelFormat.swapRB) + PspMemory::fastSwap(dst, src, sourceWidthInBytes, _pixelFormat); + else + PspMemory::fastCopy(dst, src, sourceWidthInBytes); src += realWidthInBytes; dst += pitch; } while (--h); diff --git a/backends/platform/psp/memory.cpp b/backends/platform/psp/memory.cpp index e134a7d0f4..8eef223f8c 100644 --- a/backends/platform/psp/memory.cpp +++ b/backends/platform/psp/memory.cpp @@ -35,129 +35,405 @@ #include "backends/platform/psp/trace.h" -void Copier::copy(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat *format /* = NULL */) { +//#define TEST_MEMORY_COPY + +extern "C" { + +void *__wrap_memcpy(void *dst, void *src, size_t bytes) { + PspMemory::fastCopy((byte *)dst, (byte *)src, bytes); + return dst; +} + +} + +void PspMemory::copy(byte *dst, const byte *src, uint32 bytes) { DEBUG_ENTER_FUNC(); - uint32 prefixDst = (((uint32)dst) & 0x3); - prefixDst = prefixDst ? 4 - prefixDst : 0; // prefix only if we have address % 4 != 0 - uint32 prefixSrc = (((uint32)src) & 0x3); - prefixSrc = prefixSrc ? 4 - prefixSrc : 0; // prefix only if we have address % 4 != 0 - uint32 *dst32, *src32; - bool swapRB = format ? format->swapRB : false; // take swap value from pixelformat if it's given -#ifdef __PSP_DEBUG_PRINT__ +#ifdef TEST_MEMORY_COPY uint32 debugBytes = bytes; const byte *debugDst = dst, *debugSrc = src; #endif - uint32 words, remainingBytes; - - //PSP_DEBUG_PRINT("dst[%p], src[%p], bytes[%d], swap[%s], prefixDst[%u], prefixSrc[%u]\n", dst, src, bytes, swapRB ? "true" : "false", prefixDst, prefixSrc); - if (prefixDst || prefixSrc) { // we're not aligned to word boundaries - if (prefixDst != prefixSrc) { // worst case: we can never be aligned. this mode is highly inefficient. try to get engines not to use this mode too much - PSP_DEBUG_PRINT("misaligned copy of %u bytes from %p to %p\n", bytes, src, dst); - if ((prefixDst & 1) || (prefixSrc & 1)) - copy8(dst, src, bytes); // no swap is possible on 8 bit - else - copy16((uint16 *)dst, (uint16 *)src, bytes, format); - - goto test; - } + PSP_DEBUG_PRINT("copy(): dst[%p], src[%p], bytes[%d]\n", dst, src, bytes); - // Do the prefix: the part to get us aligned - if (prefixDst & 1) { // byte - copy8(dst, src, prefixDst); // no swap available - } else { // short - copy16((uint16 *)dst, (uint16 *)src, prefixDst, format); - } - if (bytes > prefixDst) // check that we can afford to subtract from bytes - bytes -= prefixDst; - else { + // align the destination pointer first + uint32 prefixDst = (((uint32)dst) & 0x3); + + if (prefixDst) { + prefixDst = 4 - prefixDst; // prefix only if we have address % 4 != 0 + PSP_DEBUG_PRINT("prefixDst[%d]\n", prefixDst); + + bytes -= prefixDst; // remember we assume bytes >= 4 + + if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY) { // check if it's worthwhile to continue + copy8(dst, src, bytes + prefixDst); +#ifdef TEST_MEMORY_COPY + testCopy(debugDst, debugSrc, debugBytes); +#endif return; } - dst32 = (uint32 *)(dst + prefixDst); - src32 = (uint32 *)(src + prefixSrc); - } else { // We're aligned to word boundaries - dst32 = (uint32 *)dst; - src32 = (uint32 *)src; + + while (prefixDst--) { + *dst++ = *src++; + } } - - words = bytes >> 2; - remainingBytes = bytes & 0x3; - - if (swapRB) { // need to swap - for (; words > 0; words--) { - *dst32 = format->swapRedBlue32(*src32); - dst32++; - src32++; - } - } else { // no swapping - for (; words > 0; words--) { - *dst32 = *src32; - dst32++; - src32++; - } + + // check the source pointer alignment now + uint32 alignSrc = (((uint32)src) & 0x3); + + if (alignSrc) { // we'll need to realign our reads + copy32Misaligned((uint32 *)dst, src, bytes, alignSrc); + } else { + copy32Aligned((uint32 *)dst, (uint32 *)src, bytes); } - // Do any remaining bytes - if (remainingBytes) { - if (remainingBytes & 1) // we have bytes left - copy8((byte *)dst32, (byte *)src32, remainingBytes); - else // 16bits left - copy16((uint16*)dst32, (uint16 *)src32, remainingBytes, format); - } +#ifdef TEST_MEMORY_COPY + testCopy(debugDst, debugSrc, debugBytes); +#endif +} -test: - // debug -#ifdef __PSP_DEBUG_PRINT__ +void PspMemory::testCopy(const byte *debugDst, const byte *debugSrc, uint32 debugBytes) { + bool mismatch = false; + PSP_INFO_PRINT("testing fastCopy..."); for (uint32 i = 0; i < debugBytes; i++) { if (debugDst[i] != debugSrc[i]) { - if (mismatch == false) { - PSP_DEBUG_PRINT_SAMELN("mismatch in copy:\n"); - PSP_DEBUG_PRINT("dst[%p], src[%p], bytes[%u], swap[%s], prefixDst[%u], prefixSrc[%u]\n", debugDst, debugSrc, debugBytes, swapRB ? "true" : "false", prefixDst, prefixSrc); + if (!mismatch) { + PSP_INFO_PRINT("**** mismatch in copy! ****\n"); + PSP_INFO_PRINT("dst[%p], src[%p], bytes[%u]\n", debugDst, debugSrc, debugBytes); mismatch = true; } - PSP_DEBUG_PRINT_SAMELN("%x!=%x ", debugSrc[i], debugDst[i]); + PSP_INFO_PRINT("[%d]%x!=%x ", i, debugSrc[i], debugDst[i]); } } - if (mismatch) - PSP_DEBUG_PRINT("\n"); + if (mismatch) { + PSP_INFO_PRINT("\n"); + } else { + PSP_INFO_PRINT("ok\n"); + } +} + +// +// used to swap red and blue +void PspMemory::swap(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) { + DEBUG_ENTER_FUNC(); + +#ifdef TEST_MEMORY_COPY + uint32 debugBytes = bytes; + const uint16 *debugDst = dst16, *debugSrc = src16; #endif + + // align the destination pointer first + uint32 prefixDst = (((uint32)dst16) & 0x3); // for swap, we can only have 2 or 0 as our prefix + + if (prefixDst) { + bytes -= prefixDst; // remember we assume bytes > 4 + *dst16++ = format.swapRedBlue16(*src16++); + + if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY) { // check if it's worthwhile to continue + swap16(dst16, src16, bytes, format); + +#ifdef TEST_MEMORY_COPY + testSwap(debugDst, debugSrc, debugBytes, format); +#endif + return; + } + } + + // check the source pointer alignment now + uint32 alignSrc = (((uint32)src16) & 0x3); + + if (alignSrc) { // we'll need to realign our reads + PSP_DEBUG_PRINT("misaligned copy of %u bytes from %p to %p\n", bytes, src16, dst16); + swap32Misaligned((uint32 *)dst16, src16, bytes, format); + } else { + swap32Aligned((uint32 *)dst16, (const uint32 *)src16, bytes, format); + } + +#ifdef TEST_MEMORY_COPY + testSwap(debugDst, debugSrc, debugBytes, format); +#endif + +} - return; // So we have something to jump to with the label +void PspMemory::testSwap(const uint16 *debugDst, const uint16 *debugSrc, uint32 debugBytes, PSPPixelFormat &format) { + + bool mismatch = false; + PSP_INFO_PRINT("testing fastSwap..."); + + uint32 shorts = debugBytes >> 1; + + for (uint32 i = 0; i < shorts; i++) { + if (debugDst[i] != format.swapRedBlue16(debugSrc[i])) { + if (!mismatch) { + PSP_INFO_PRINT("**** mismatch in swap! ****\n"); + PSP_INFO_PRINT("dst[%p], src[%p], bytes[%u]\n", debugDst, debugSrc, debugBytes); + mismatch = true; + } + PSP_INFO_PRINT("[%d]%x!=%x ", i<<1, format.swapRedBlue16(debugSrc[i]), debugDst[i]); + } + } + if (mismatch) { + PSP_INFO_PRINT("\n"); + } else { + PSP_INFO_PRINT("ok\n"); + } } -inline void Copier::copy8(byte *dst, const byte *src, uint32 bytes) { - for (; bytes > 0; bytes--) { - *dst = *src; - dst++; - src++; + +void PspMemory::copy32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes) { + PSP_DEBUG_PRINT("copy32Aligned(): dst32[%p], src32[%p], bytes[%d]\n", dst32, src32, bytes); + + int words8 = bytes >> 5; + + // try blocks of 8 words at a time + if (words8) { + while (words8--) { + uint32 a, b, c, d; + a = src32[0]; + b = src32[1]; + c = src32[2]; + d = src32[3]; + dst32[0] = a; + dst32[1] = b; + dst32[2] = c; + dst32[3] = d; + a = src32[4]; + b = src32[5]; + c = src32[6]; + d = src32[7]; + dst32[4] = a; + dst32[5] = b; + dst32[6] = c; + dst32[7] = d; + dst32 += 8; + src32 += 8; + } + } + + int words4 = (bytes & 0x1F) >> 4; + + // try blocks of 4 words at a time + if (words4) { + uint32 a, b, c, d; + a = src32[0]; + b = src32[1]; + c = src32[2]; + d = src32[3]; + dst32[0] = a; + dst32[1] = b; + dst32[2] = c; + dst32[3] = d; + dst32 += 4; + src32 += 4; + } + + int bytesLeft = (bytes & 0xF); // only look at bytes left after we did the above + int wordsLeft = bytesLeft >> 2; + + // now just do single words + while (wordsLeft) { + *dst32++ = *src32++; + wordsLeft--; + } + + bytesLeft = bytes & 0x3; // get remaining bytes + + PSP_DEBUG_PRINT("bytesLeft[%d]\n", bytesLeft); + + byte *dst = (byte *)dst32; + byte *src = (byte *)src32; + + while (bytesLeft--) { + *dst++ = *src++; } } -inline void Copier::copy16(uint16 *dst, const uint16 *src, uint32 bytes, PSPPixelFormat *format /* = NULL */) { - uint32 shorts = bytes >> 1; - uint32 remainingBytes = bytes & 1; - bool swapRB = format ? format->swapRB : false; +void PspMemory::swap32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes, PSPPixelFormat &format) { + DEBUG_ENTER_FUNC(); + int words4 = bytes >> 4; + + // try blocks of 4 words at a time + while (words4--) { + uint32 a, b, c, d; + a = format.swapRedBlue32(src32[0]); + b = format.swapRedBlue32(src32[1]); + c = format.swapRedBlue32(src32[2]); + d = format.swapRedBlue32(src32[3]); + dst32[0] = a; + dst32[1] = b; + dst32[2] = c; + dst32[3] = d; + dst32 += 4; + src32 += 4; + } + + uint32 bytesLeft = bytes & 0xF; + uint32 words = bytesLeft >> 2; + + // now just do words + while (words--) { + *dst32++ = format.swapRedBlue32(*src32++); + } + + bytesLeft = bytes & 0x3; + + if (bytesLeft) { // for swap, can only be 1 short left + *((uint16 *)dst32) = format.swapRedBlue16(*((uint16 *)src32)); + } +} + + +// More challenging -- need to shift +// Assume dst is aligned +void PspMemory::copy32Misaligned(uint32 *dst32, const byte *src, uint32 bytes, uint32 alignSrc) { + PSP_DEBUG_PRINT("copy32Misaligned: dst32[%p], src[%p], bytes[%d], alignSrc[%d]\n", dst32, src, bytes, alignSrc); + + uint32 *src32 = (uint32 *)(((uint32)src) & 0xFFFFFFFC); // remove misalignment + uint32 offset; + + switch (alignSrc) { + case 1: + offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 8, 24); + break; + case 2: + offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 16, 16); + break; + default: /* 3 */ + offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 24, 8); + break; + } + + uint32 remainingBytes = bytes & 3; + + if (remainingBytes) { + byte *dst = (byte *)dst32; + src += offset; + dst += offset; + copy8(dst, src, remainingBytes); + } +} - if (swapRB) { - for (; shorts > 0 ; shorts--) { - *dst = format->swapRedBlue16(*src); - dst++; - src++; +// returns offset in dst +uint32 PspMemory::misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes, uint32 alignSrc, const uint32 shiftValue, const uint32 lastShiftValue) { + uint32 *origDst32 = dst32; + register uint32 dstWord, srcWord; + + PSP_DEBUG_PRINT("misaligned32Detail(): alignSrc[%d], dst32[%p], src32[%p], bytes[%d]\n", alignSrc, dst32, src32, bytes); + + // Try to do groups of 4 words + uint32 words4 = bytes >> 4; + + srcWord = src32[0]; + + while (words4--) { + dstWord = srcWord >> shiftValue; + srcWord = src32[1]; + dstWord |= srcWord << lastShiftValue; + dst32[0] = dstWord; + dstWord = srcWord >> shiftValue; + srcWord = src32[2]; + dstWord |= srcWord << lastShiftValue; + dst32[1] = dstWord; + dstWord = srcWord >> shiftValue; + srcWord = src32[3]; + dstWord |= srcWord << lastShiftValue; + dst32[2] = dstWord; + dstWord = srcWord >> shiftValue; + srcWord = src32[4]; + dstWord |= srcWord << lastShiftValue; + dst32[3] = dstWord; + src32 += 4; + dst32 += 4; + } + + uint32 words = (bytes & 0xF) >> 2; + + // we read one word ahead of what we write + // setup the first read + if (words) { + src32++; // we already loaded the value, so just increment + + while (words--) { + dstWord = srcWord >> shiftValue; + srcWord = *src32++; + dstWord |= srcWord << lastShiftValue; + *dst32++ = dstWord; } - } else { - for (; shorts > 0 ; shorts--) { - *dst = *src; - dst++; - src++; + } + + return (byte *)dst32 - (byte *)origDst32; +} + +// More challenging -- need to shift +// We assume dst is aligned +void PspMemory::swap32Misaligned(uint32 *dst32, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) { + DEBUG_ENTER_FUNC(); + + const uint32 shiftValue = 16; + uint32 *src32 = (uint32 *)(((uint32)src16) & 0xFFFFFFFC); // remove misalignment + + // Try to do groups of 4 words + uint32 words4 = bytes >> 4; + uint32 srcWord = src32[0]; // preload + + while (words4--) { + uint32 dstWord = srcWord >> shiftValue; + srcWord = src32[1]; + dstWord |= srcWord << shiftValue; + dst32[0] = format.swapRedBlue32(dstWord); + dstWord = srcWord >> shiftValue; + srcWord = src32[2]; + dstWord |= srcWord << shiftValue; + dst32[1] = format.swapRedBlue32(dstWord); + dstWord = srcWord >> shiftValue; + srcWord = src32[3]; + dstWord |= srcWord << shiftValue; + dst32[2] = format.swapRedBlue32(dstWord); + dstWord = srcWord >> shiftValue; + srcWord = src32[4]; + dstWord |= srcWord << shiftValue; + dst32[3] = format.swapRedBlue32(dstWord); + src32 += 4; + dst32 += 4; + } + + uint32 words = (bytes & 0xF) >> 2; + + // we read one word ahead of what we write + // setup the first read + if (words) { + //srcWord = *src32++; // don't need this. already loaded + src32++; // we already have the value loaded in + + while (words--) { + uint32 dstWord = srcWord >> shiftValue; + srcWord = *src32++; + dstWord |= srcWord << shiftValue; + *dst32++ = format.swapRedBlue32(dstWord); } } - if (remainingBytes) - *(byte *)dst = *(byte *)src; + + uint32 bytesLeft = bytes & 3; + + if (bytesLeft) { // for swap, can only be 1 short left + *((uint16 *)dst32) = format.swapRedBlue16((uint16)(srcWord >> shiftValue)); + } } +inline void PspMemory::copy16(uint16 *dst16, const uint16 *src16, uint32 bytes) { + PSP_DEBUG_PRINT("copy16(): dst16[%p], src16[%p], bytes[%d]\n", dst16, src16, bytes); + + uint32 shorts = bytes >> 1; + uint32 remainingBytes = bytes & 1; + + for (; shorts > 0 ; shorts--) { + *dst16++ = *src16++; + } + if (remainingBytes) + *(byte *)dst16 = *(byte *)src16; +} // Class VramAllocator ----------------------------------- diff --git a/backends/platform/psp/memory.h b/backends/platform/psp/memory.h index a198095090..c9b3d21cb6 100644 --- a/backends/platform/psp/memory.h +++ b/backends/platform/psp/memory.h @@ -27,17 +27,69 @@ #ifndef PSP_MEMORY_H #define PSP_MEMORY_H +#include "backends/platform/psp/psppixelformat.h" +#include "common/list.h" + #define UNCACHED(x) ((byte *)(((uint32)(x)) | 0x40000000)) /* make an uncached access */ #define CACHED(x) ((byte *)(((uint32)(x)) & 0xBFFFFFFF)) /* make an uncached access into a cached one */ +#define MIN_AMOUNT_FOR_COMPLEX_COPY 8 +#define MIN_AMOUNT_FOR_MISALIGNED_COPY 8 + +//#define __PSP_DEBUG_PRINT__ + +#include "backends/platform/psp/trace.h" + /** * Class that does memory copying and swapping if needed */ -class Copier { -public: - static void copy(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat *format = NULL); - static void copy8(byte *dst, const byte *src, uint32 bytes); - static void copy16(uint16 *dst, const uint16 *src, uint32 bytes, PSPPixelFormat *format = NULL); +class PspMemory { +private: + static void testCopy(const byte *debugDst, const byte *debugSrc, uint32 debugBytes); + static void testSwap(const uint16 *debugDst, const uint16 *debugSrc, uint32 debugBytes, PSPPixelFormat &format); + static void copy(byte *dst, const byte *src, uint32 bytes); + static void swap(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format); + static void copy32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes); + static void swap32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes, PSPPixelFormat &format); + static void copy32Misaligned(uint32 *dst32, const byte *src, uint32 bytes, uint32 alignSrc); + static uint32 misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes, uint32 alignSrc, const uint32 shiftValue, const uint32 lastShiftValue); + static void swap32Misaligned(uint32 *dst32, const uint16 *src16, uint32 bytes, PSPPixelFormat &format); + static void copy16(uint16 *dst, const uint16 *src, uint32 bytes); + + // For swapping, we know that we have multiples of 16 bits + static void swap16(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) { + PSP_DEBUG_PRINT("swap16 called with dst16[%p], src16[%p], bytes[%d]\n", dst16, src16, bytes); + uint32 shorts = bytes >> 1; + + while (shorts--) { + *dst16++ = format.swapRedBlue16(*src16++); + } + } + + static void copy8(byte *dst, const byte *src, uint32 bytes) { + PSP_DEBUG_PRINT("copy8 called with dst[%p], src[%p], bytes[%d]\n", dst, src, bytes); + while (bytes--) { + *dst++ = *src++; + } + } + +public: + // This is the interface to the outside world + static void fastCopy(byte *dst, const byte *src, uint32 bytes) { + if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY) { + copy8(dst, src, bytes); + } else { // go to more powerful copy + copy(dst, src, bytes); + } + } + + static void fastSwap(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat &format) { + if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY * 2) { + swap16((uint16 *)dst, (uint16 *)src, bytes, format); + } else { // go to more powerful copy + swap((uint16 *)dst, (uint16 *)src, bytes, format); + } + } }; /** diff --git a/backends/platform/psp/module.mk b/backends/platform/psp/module.mk index e9c896acfd..4652189ab4 100644 --- a/backends/platform/psp/module.mk +++ b/backends/platform/psp/module.mk @@ -16,10 +16,10 @@ MODULE_OBJS := powerman.o \ audio.o \ thread.o \ rtc.o \ - mp3.o + mp3.o \ + tests.o -MODULE_DIRS += \ - backends/platform/psp/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) diff --git a/backends/platform/psp/psp_main.cpp b/backends/platform/psp/psp_main.cpp index c26aed539e..dba9a8fc2b 100644 --- a/backends/platform/psp/psp_main.cpp +++ b/backends/platform/psp/psp_main.cpp @@ -44,6 +44,7 @@ #include "backends/plugins/psp/psp-provider.h" #include "backends/platform/psp/psppixelformat.h" #include "backends/platform/psp/osys_psp.h" +#include "backends/platform/psp/tests.h" /* for unit/speed tests */ #include "backends/platform/psp/trace.h" #ifdef ENABLE_PROFILING @@ -169,6 +170,13 @@ int main(void) { PluginManager::instance().addPluginProvider(new PSPPluginProvider()); #endif +/* unit/speed tests */ +#if defined (PSP_ENABLE_UNIT_TESTS) || defined (PSP_ENABLE_SPEED_TESTS) + PSP_INFO_PRINT("running tests\n"); + psp_tests(); + sceKernelSleepThread(); // that's it. That's all we're doing +#endif + int res = scummvm_main(argc, argv); g_system->quit(); // TODO: Consider removing / replacing this! diff --git a/backends/platform/psp/tests.cpp b/backends/platform/psp/tests.cpp new file mode 100644 index 0000000000..d1bdb9e640 --- /dev/null +++ b/backends/platform/psp/tests.cpp @@ -0,0 +1,565 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $ + * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $ + * + */ + +// PSP speed and unit tests. Activate in tests.h +// You may also want to build without any engines. + +#include "backends/platform/psp/tests.h" + +#if defined (PSP_ENABLE_UNIT_TESTS) || defined (PSP_ENABLE_SPEED_TESTS) + +#include "common/scummsys.h" +#include <pspiofilemgr_fcntl.h> +#include <pspiofilemgr_stat.h> +#include <pspiofilemgr.h> +#include <pspthreadman.h> +#include <pspsdk.h> +#include <psprtc.h> +#include <stdlib.h> +#include <stdio.h> +#include <psputils.h> +#include "backends/platform/psp/rtc.h" +#include "backends/platform/psp/thread.h" +#include "backends/platform/psp/memory.h" + + +#define UNCACHED(x) ((byte *)(((uint32)(x)) | 0x40000000)) /* make an uncached access */ +#define CACHED(x) ((byte *)(((uint32)(x)) & 0xBFFFFFFF)) /* make an uncached access into a cached one */ + +//#define __PSP_DEBUG_FUNCS__ +//#define __PSP_DEBUG_PRINT__ + +// Results: (333Mhz/222Mhz) +// Getting a tick: 1-2 us +// Getting a time structure: 9/14us +// ie. using a tick and just dividing by 1000 saves us time. + +#include "backends/platform/psp/trace.h" + +class PspSpeedTests { +public: + void tickSpeed(); + void getMicrosSpeed(); + void seekSpeed(); + void msReadSpeed(); + void threadFunctionsSpeed(); + void semaphoreSpeed(); + static int threadFunc(SceSize args, void *argp); + void semaphoreManyThreadSpeed(); + void fastCopySpeed(); + +private: + enum { + MEMCPY_BUFFER_SIZE = 8192 + }; + static PspSemaphore _sem; // semaphore + + void readAndTime(uint32 bytes, char *buffer, FILE *file); + void seekAndTime(int bytes, int origin, FILE *file); + void fastCopySpecificSize(byte *dst, byte *src, uint32 bytes); + void fastCopyDifferentSizes(byte *dst, byte *src); + int getThreadIdSpeed(); + void getPrioritySpeed(); + void changePrioritySpeed(int id, int priority); +}; + +PspSemaphore PspSpeedTests::_sem(0); + +void PspSpeedTests::tickSpeed() { + uint32 ticksPerSecond = sceRtcGetTickResolution(); + PSP_INFO_PRINT("ticksPerSecond[%d]\n", ticksPerSecond); + + uint32 currentTicks1[2]; + uint32 currentTicks2[2]; + + sceRtcGetCurrentTick((u64 *)currentTicks1); + sceRtcGetCurrentTick((u64 *)currentTicks2); + PSP_INFO_PRINT("current tick[%x %x][%u %u]\n", currentTicks1[0], currentTicks1[1], currentTicks1[0], currentTicks1[1]); + PSP_INFO_PRINT("current tick[%x %x][%u %u]\n", currentTicks2[0], currentTicks2[1], currentTicks2[0], currentTicks2[1]); + + pspTime time; + sceRtcSetTick(&time, (u64 *)currentTicks2); + PSP_INFO_PRINT("current tick in time, year[%d] month[%d] day[%d] hour[%d] minutes[%d] seconds[%d] us[%d]\n", time.year, time.month, time.day, time.hour, time.minutes, time.seconds, time.microseconds); + + pspTime time1; + pspTime time2; + sceRtcGetCurrentClockLocalTime(&time1); + sceRtcGetCurrentClockLocalTime(&time2); + PSP_INFO_PRINT("time1, year[%d] month[%d] day[%d] hour[%d] minutes[%d] seconds[%d] us[%d]\n", time1.year, time1.month, time1.day, time1.hour, time1.minutes, time1.seconds, time1.microseconds); + PSP_INFO_PRINT("time2, year[%d] month[%d] day[%d] hour[%d] minutes[%d] seconds[%d] us[%d]\n", time2.year, time2.month, time2.day, time2.hour, time2.minutes, time2.seconds, time2.microseconds); +} + +void PspSpeedTests::getMicrosSpeed() { + uint32 time1, time2, time3, time4; + time1 = PspRtc::instance().getMicros(); + time2 = PspRtc::instance().getMicros(); + time3 = PspRtc::instance().getMicros(); + time4 = PspRtc::instance().getMicros(); + + PSP_INFO_PRINT("getMicros() times: %d, %d, %d\n", time4-time3, time3-time2, time2-time1); +} + +void PspSpeedTests::readAndTime(uint32 bytes, char *buffer, FILE *file) { + uint32 time1 = PspRtc::instance().getMicros(); + // test minimal read + fread(buffer, bytes, 1, file); + uint32 time2 = PspRtc::instance().getMicros(); + + PSP_INFO_PRINT("Reading %d byte takes %dus\n", bytes, time2-time1); +} + +/* + 333MHz/222MHz + Reading 1 byte takes 2590us / 3167 + Reading 10 byte takes 8us / 9 + Reading 50 byte takes 8us / 11 + Reading 100 byte takes 8us / 11 + Reading 1000 byte takes 915us / 1131 + Reading 2000 byte takes 1806us / 2,284 + Reading 3000 byte takes 2697us / 3,374 + Reading 5000 byte takes 4551us / 5,544 + Reading 6000 byte takes 5356us / 6,676 + Reading 7000 byte takes 6800us / 8,358 + Reading 8000 byte takes 6794us / 8,454 + Reading 9000 byte takes 6782us / 8,563 + Reading 10000 byte takes 8497us / 10,631 + Reading 30000 byte takes 25995us / 32,473 + Reading 80000 byte takes 68457us / 85,291 + Reading 100000 byte takes 85103us / 106,163 +*/ +// Function to test the impact of MS reads +// These tests can't be done from shell - the cache screws them up +void PspSpeedTests::msReadSpeed() { + FILE *file; + file = fopen("ms0:/psp/music/track1.mp3", "r"); + + char *buffer = (char *)malloc(2 * 1024 * 1024); + + readAndTime(1, buffer, file); + readAndTime(10, buffer, file); + readAndTime(50, buffer, file); + readAndTime(100, buffer, file); + readAndTime(1000, buffer, file); + readAndTime(2000, buffer, file); + readAndTime(3000, buffer, file); + readAndTime(5000, buffer, file); + readAndTime(6000, buffer, file); + readAndTime(7000, buffer, file); + readAndTime(8000, buffer, file); + readAndTime(9000, buffer, file); + readAndTime(10000, buffer, file); + readAndTime(30000, buffer, file); + readAndTime(50000, buffer, file); + readAndTime(80000, buffer, file); + readAndTime(100000, buffer, file); + + fclose(file); + free(buffer); +} + +void PspSpeedTests::seekAndTime(int bytes, int origin, FILE *file) { + char buffer[1000]; + + uint32 time1 = PspRtc::instance().getMicros(); + // test minimal read + fseek(file, bytes, origin); + uint32 time2 = PspRtc::instance().getMicros(); + + PSP_INFO_PRINT("Seeking %d byte from %d took %dus\n", bytes, origin, time2-time1); + + time1 = PspRtc::instance().getMicros(); + // test minimal read + fread(buffer, 1000, 1, file); + time2 = PspRtc::instance().getMicros(); + + PSP_INFO_PRINT("Reading 1000 bytes took %dus\n", time2-time1); +} + +/* +333MHz +Seeking 0 byte from 0 took 946us +Reading 1000 bytes took 1781us +Seeking 5 byte from 0 took 6us +Reading 1000 bytes took 19us +Seeking 1000 byte from 0 took 5us +Reading 1000 bytes took 913us +Seeking 100 byte from 0 took 955us +Reading 1000 bytes took 906us +Seeking 10000 byte from 0 took 963us +Reading 1000 bytes took 905us +Seeking -5 byte from 1 took 1022us +Reading 1000 bytes took 949us +Seeking -100 byte from 1 took 1040us +Reading 1000 bytes took 907us +Seeking 100 byte from 1 took 1044us +Reading 1000 bytes took 930us +Seeking 0 byte from 2 took 7211us +Reading 1000 bytes took 80us +Seeking 10000 byte from 2 took 3636us +Reading 1000 bytes took 110us +*/ + +void PspSpeedTests::seekSpeed() { + FILE *file; + file = fopen("ms0:/psp/music/track1.mp3", "r"); + + seekAndTime(0, SEEK_SET, file); + seekAndTime(5, SEEK_SET, file); + seekAndTime(1000, SEEK_SET, file); + seekAndTime(100, SEEK_SET, file); + seekAndTime(10000, SEEK_SET, file); + seekAndTime(-5, SEEK_CUR, file); + seekAndTime(-100, SEEK_CUR, file); + seekAndTime(100, SEEK_CUR, file); + seekAndTime(0, SEEK_END, file); + seekAndTime(-10000, SEEK_END, file); + + fclose(file); +} + +// 222: 5-7us +int PspSpeedTests::getThreadIdSpeed() { + uint32 time1 = PspRtc::instance().getMicros(); + int threadId = sceKernelGetThreadId(); + uint32 time2 = PspRtc::instance().getMicros(); + + PSP_INFO_PRINT("Getting thread ID %d took %dus\n", threadId, time2-time1); + + return threadId; +} + +// 222: 4-5us +void PspSpeedTests::getPrioritySpeed() { + uint32 time1 = PspRtc::instance().getMicros(); + int priority = sceKernelGetThreadCurrentPriority(); + uint32 time2 = PspRtc::instance().getMicros(); + + PSP_INFO_PRINT("Getting thread priority %d took %dus\n", priority, time2-time1); +} + +// 222: 9-10us +void PspSpeedTests::changePrioritySpeed(int id, int priority) { + uint32 time1 = PspRtc::instance().getMicros(); + sceKernelChangeThreadPriority(id, priority); + uint32 time2 = PspRtc::instance().getMicros(); + + PSP_INFO_PRINT("Changing thread priority to %d for id %d took %dus\n", priority, id, time2-time1); +} + +void PspSpeedTests::threadFunctionsSpeed() { + // very unscientific -- just ballpark + int id; + id = getThreadIdSpeed(); + getThreadIdSpeed(); + getPrioritySpeed(); + getPrioritySpeed(); + changePrioritySpeed(id, 30); + changePrioritySpeed(id, 35); + changePrioritySpeed(id, 25); + + // test context switch time + for (int i=0; i<10; i++) { + uint time1 = PspRtc::instance().getMicros(); + PspThread::delayMicros(0); + uint time2 = PspRtc::instance().getMicros(); + PSP_INFO_PRINT("poll %d. context switch Time = %dus\n", i, time2-time1); // 10-15us + } +} + +void PspSpeedTests::semaphoreSpeed() { + PspSemaphore sem(1); + + uint32 time1 = PspRtc::instance().getMicros(); + + sem.take(); + + uint32 time2 = PspRtc::instance().getMicros(); + + PSP_INFO_PRINT("taking semaphore took %d us\n", time2-time1); // 10us + + uint32 time3 = PspRtc::instance().getMicros(); + + sem.give(); + + uint32 time4 = PspRtc::instance().getMicros(); + PSP_INFO_PRINT("releasing semaphore took %d us\n", time4-time3); //10us-55us +} + +int PspSpeedTests::threadFunc(SceSize args, void *argp) { + PSP_INFO_PRINT("thread %x created.\n", sceKernelGetThreadId()); + + _sem.take(); + + PSP_INFO_PRINT("grabbed semaphore. Quitting thread\n"); + + return 0; +} + +void PspSpeedTests::semaphoreManyThreadSpeed() { + + // create 4 threads + for (int i=0; i<4; i++) { + int thid = sceKernelCreateThread("my_thread", PspSpeedTests::threadFunc, 0x18, 0x10000, THREAD_ATTR_USER, NULL); + sceKernelStartThread(thid, 0, 0); + } + + PSP_INFO_PRINT("main thread. created threads\n"); + + uint32 threads = _sem.numOfWaitingThreads(); + while (threads < 4) { + threads = _sem.numOfWaitingThreads(); + PSP_INFO_PRINT("main thread: waiting threads[%d]\n", threads); + } + + PSP_INFO_PRINT("main: semaphore value[%d]\n", _sem.getValue()); + PSP_INFO_PRINT("main thread: waiting threads[%d]\n", _sem.numOfWaitingThreads()); + + _sem.give(4); +} + +void PspSpeedTests::fastCopySpecificSize(byte *dst, byte *src, uint32 bytes) { + uint32 time1, time2; + uint32 fastcopyTime, memcpyTime; + const int iterations = 2000; + int intc; + + intc = pspSdkDisableInterrupts(); + + time1 = PspRtc::instance().getMicros(); + for (int i=0; i<iterations; i++) { + PspMemory::fastCopy(dst, src, bytes); + } + time2 = PspRtc::instance().getMicros(); + + pspSdkEnableInterrupts(intc); + + fastcopyTime = time2-time1; + + intc = pspSdkDisableInterrupts(); + + time1 = PspRtc::instance().getMicros(); + for (int i=0; i<iterations; i++) { + memcpy(dst, src, bytes); + } + time2 = PspRtc::instance().getMicros(); + + pspSdkEnableInterrupts(intc); + + memcpyTime = time2-time1; + + PSP_INFO_PRINT("%d bytes. memcpy[%d], fastcopy[%d]\n", bytes, memcpyTime, fastcopyTime); +} + +void PspSpeedTests::fastCopyDifferentSizes(byte *dst, byte *src) { + PSP_INFO_PRINT("\nsrc[%p], dst[%p]\n", src, dst); + fastCopySpecificSize(dst, src, 1); + fastCopySpecificSize(dst, src, 2); + fastCopySpecificSize(dst, src, 3); + fastCopySpecificSize(dst, src, 4); + fastCopySpecificSize(dst, src, 5); + fastCopySpecificSize(dst, src, 8); + fastCopySpecificSize(dst, src, 10); + fastCopySpecificSize(dst, src, 16); + fastCopySpecificSize(dst, src, 32); + fastCopySpecificSize(dst, src, 50); + fastCopySpecificSize(dst, src, 100); + fastCopySpecificSize(dst, src, 500); + fastCopySpecificSize(dst, src, 1024); + fastCopySpecificSize(dst, src, 2048); +} + +void PspSpeedTests::fastCopySpeed() { + PSP_INFO_PRINT("running fastCopy speed test\n"); + + uint32 *bufferSrc32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE); + uint32 *bufferDst32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE); + + // fill buffer 1 + for (int i=0; i<MEMCPY_BUFFER_SIZE/4; i++) + bufferSrc32[i] = i | (((MEMCPY_BUFFER_SIZE/4)-i)<<16); + + // print buffer + for (int i=0; i<50; i++) + PSP_INFO_PRINT("%x ", bufferSrc32[i]); + PSP_INFO_PRINT("\n"); + + byte *bufferSrc = ((byte *)bufferSrc32); + byte *bufferDst = ((byte *)bufferDst32); + + PSP_INFO_PRINT("\n\ndst and src cached: -----------------\n"); + fastCopyDifferentSizes(bufferDst, bufferSrc); + fastCopyDifferentSizes(bufferDst+1, bufferSrc+1); + fastCopyDifferentSizes(bufferDst, bufferSrc+1); + fastCopyDifferentSizes(bufferDst+1, bufferSrc); + + PSP_INFO_PRINT("\n\ndst cached, src uncached: -----------------\n"); + bufferSrc = UNCACHED(bufferSrc); + fastCopyDifferentSizes(bufferDst, bufferSrc); + fastCopyDifferentSizes(bufferDst+1, bufferSrc+1); + fastCopyDifferentSizes(bufferDst, bufferSrc+1); + fastCopyDifferentSizes(bufferDst+1, bufferSrc); + + PSP_INFO_PRINT("\n\ndst uncached, src uncached: --------------\n"); + bufferDst = UNCACHED(bufferDst); + fastCopyDifferentSizes(bufferDst, bufferSrc); + fastCopyDifferentSizes(bufferDst+1, bufferSrc+1); + fastCopyDifferentSizes(bufferDst, bufferSrc+1); + fastCopyDifferentSizes(bufferDst+1, bufferSrc); + + PSP_INFO_PRINT("\n\ndst uncached, src cached: -------------------\n"); + bufferSrc = CACHED(bufferSrc); + fastCopyDifferentSizes(bufferDst, bufferSrc); + fastCopyDifferentSizes(bufferDst+1, bufferSrc+1); + fastCopyDifferentSizes(bufferDst, bufferSrc+1); + fastCopyDifferentSizes(bufferDst+1, bufferSrc); + + + free(bufferSrc32); + free(bufferDst32); +} + +//-------Unit Tests ------------------------------- + +class PspUnitTests { +public: + void testFastCopy(); + +private: + enum { + MEMCPY_BUFFER_SIZE = 8192 + }; + + void fastCopySpecificSize(byte *dst, byte *src, uint32 bytes, bool swap = false); + void fastCopyDifferentSizes(byte *dst, byte *src, bool swap = false); +}; + +void PspUnitTests::testFastCopy() { + PSP_INFO_PRINT("running fastcopy unit test ***********\n"); + PSP_INFO_PRINT("this test requires the test flag to be on in fastCopy\n\n"); + + uint32 *bufferSrc32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE); + uint32 *bufferDst32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE); + + // fill buffer 1 + for (int i=0; i<MEMCPY_BUFFER_SIZE/4; i++) + bufferSrc32[i] = i | (((MEMCPY_BUFFER_SIZE/4)-i)<<16); + + // print buffer + for (int i=0; i<50; i++) + PSP_INFO_PRINT("%x ", bufferSrc32[i]); + PSP_INFO_PRINT("\n"); + + byte *bufferSrc = ((byte *)bufferSrc32); + byte *bufferDst = ((byte *)bufferDst32); + + fastCopyDifferentSizes(bufferDst, bufferSrc, true); + fastCopyDifferentSizes(bufferDst+1, bufferSrc+1); + fastCopyDifferentSizes(bufferDst+2, bufferSrc+2, true); + fastCopyDifferentSizes(bufferDst+3, bufferSrc+3); + fastCopyDifferentSizes(bufferDst, bufferSrc+1); + fastCopyDifferentSizes(bufferDst, bufferSrc+2, true); + fastCopyDifferentSizes(bufferDst+2, bufferSrc, true); + fastCopyDifferentSizes(bufferDst, bufferSrc+3); + fastCopyDifferentSizes(bufferDst+1, bufferSrc+2); + fastCopyDifferentSizes(bufferDst+1, bufferSrc+3); + fastCopyDifferentSizes(bufferDst+2, bufferSrc+1); + fastCopyDifferentSizes(bufferDst+2, bufferSrc+3); + fastCopyDifferentSizes(bufferDst+3, bufferSrc+1); + fastCopyDifferentSizes(bufferDst+3, bufferSrc+2); + + free(bufferSrc32); + free(bufferDst32); +} + +void PspUnitTests::fastCopyDifferentSizes(byte *dst, byte *src, bool swap) { + fastCopySpecificSize(dst, src, 1); + fastCopySpecificSize(dst, src, 2, swap); + fastCopySpecificSize(dst, src, 4, swap); + fastCopySpecificSize(dst, src, 6, swap); + fastCopySpecificSize(dst, src, 8, swap); + fastCopySpecificSize(dst, src, 9); + fastCopySpecificSize(dst, src, 10, swap); + fastCopySpecificSize(dst, src, 11); + fastCopySpecificSize(dst, src, 12, swap); + fastCopySpecificSize(dst, src, 13); + fastCopySpecificSize(dst, src, 14, swap); + fastCopySpecificSize(dst, src, 15); + fastCopySpecificSize(dst, src, 16, swap); + fastCopySpecificSize(dst, src, 17); + fastCopySpecificSize(dst, src, 18, swap); + fastCopySpecificSize(dst, src, 19); + fastCopySpecificSize(dst, src, 20, swap); + fastCopySpecificSize(dst, src, 32, swap); + fastCopySpecificSize(dst, src, 33); + fastCopySpecificSize(dst, src, 34, swap); + fastCopySpecificSize(dst, src, 35); + fastCopySpecificSize(dst, src, 36, swap); + fastCopySpecificSize(dst, src, 50, swap); + fastCopySpecificSize(dst, src, 100, swap); + fastCopySpecificSize(dst, src, 500, swap); + fastCopySpecificSize(dst, src, 1000, swap); +} + +void PspUnitTests::fastCopySpecificSize(byte *dst, byte *src, uint32 bytes, bool swap) { + memset(dst, 0, bytes); + PspMemory::fastCopy(dst, src, bytes); + + if (swap) { // test swap also + memset(dst, 0, bytes); + + // pixelformat for swap + PSPPixelFormat format; + format.set(PSPPixelFormat::Type_4444, true); + + PspMemory::fastSwap(dst, src, bytes, format); + } +} + +void psp_tests() { + PSP_INFO_PRINT("in tests\n"); + +#ifdef PSP_ENABLE_SPEED_TESTS + // Speed tests + PspSpeedTests speedTests; + speedTests.tickSpeed(); + speedTests.getMicrosSpeed(); + speedTests.msReadSpeed(); + speedTests.seekSpeed(); + speedTests.msReadSpeed(); + speedTests.threadFunctionsSpeed(); + speedTests.semaphoreSpeed(); + speedTests.semaphoreManyThreadSpeed(); + speedTests.fastCopySpeed(); +#endif + +#ifdef PSP_ENABLE_UNIT_TESTS + // Unit tests + PspUnitTests unitTests; + + unitTests.testFastCopy(); +#endif +} + +#endif /* (PSP_ENABLE_UNIT_TESTS) || defined (PSP_ENABLE_SPEED_TESTS) */
\ No newline at end of file diff --git a/backends/platform/PalmOS/Src/launcher/forms/formEditGame.h b/backends/platform/psp/tests.h index 90d271e115..1518acfb4c 100644 --- a/backends/platform/PalmOS/Src/launcher/forms/formEditGame.h +++ b/backends/platform/psp/tests.h @@ -18,22 +18,19 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL$ - * $Id$ + * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/psp_main.cpp $ + * $Id: psp_main.cpp 49155 2010-05-23 11:48:21Z Bluddy $ * */ -#ifndef __FORMEDITGAME_H__ -#define __FORMEDITGAME_H__ +#ifndef _PSP_TESTS_H_ +#define _PSP_TESTS_H_ -// edit game mode -enum { - edtModeAdd, - edtModeEdit, - edtModeParams -}; - -extern UInt8 gFormEditMode; -void EditGameFormDelete(Boolean direct); +//#define PSP_ENABLE_UNIT_TESTS // run unit tests +//#define PSP_ENABLE_SPEED_TESTS // run speed tests +#if defined (PSP_ENABLE_UNIT_TESTS) || defined (PSP_ENABLE_SPEED_TESTS) +void psp_tests(); #endif + +#endif /* _PSP_TESTS_H_ */
\ No newline at end of file diff --git a/backends/platform/psp/trace.h b/backends/platform/psp/trace.h index ade8fd7214..625aa60772 100644 --- a/backends/platform/psp/trace.h +++ b/backends/platform/psp/trace.h @@ -30,11 +30,13 @@ #include "common/str.h" +#define __PSP_PRINT_TO_FILE_AND_SCREEN__ + /* Choose to print to file/screen/both */ #ifdef __PSP_PRINT_TO_FILE__ - #define __PSP_PRINT__(format,...) PSPDebugTrace(false, format, ## __VA_ARGS__) + #define __PSP_PRINT__(format,...) PspDebugTrace(false, format, ## __VA_ARGS__) #elif defined __PSP_PRINT_TO_FILE_AND_SCREEN__ - #define __PSP_PRINT__(format,...) PSPDebugTrace(true, format, ## __VA_ARGS__) + #define __PSP_PRINT__(format,...) PspDebugTrace(true, format, ## __VA_ARGS__) #else /* default - print to screen */ #define __PSP_PRINT__(format,...) fprintf(stderr, format, ## __VA_ARGS__) #endif /* PSP_PRINT_TO_FILE/SCREEN */ diff --git a/backends/platform/samsungtv/module.mk b/backends/platform/samsungtv/module.mk index 1d3bb7aefe..36ad75da6d 100644 --- a/backends/platform/samsungtv/module.mk +++ b/backends/platform/samsungtv/module.mk @@ -4,8 +4,7 @@ MODULE_OBJS := \ main.o \ samsungtv.o -MODULE_DIRS += \ - backends/platform/samsungtv/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk index 22c2fb95a7..a26c57f46c 100644 --- a/backends/platform/sdl/module.mk +++ b/backends/platform/sdl/module.mk @@ -19,11 +19,7 @@ MODULE_OBJS += \ win32/win32.o endif -MODULE_DIRS += \ - backends/platform/sdl/ \ - backends/platform/sdl/macosx/ \ - backends/platform/sdl/posix/ \ - backends/platform/sdl/win32/ - # We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS)))
\ No newline at end of file diff --git a/backends/platform/wii/module.mk b/backends/platform/wii/module.mk index cf55a182c0..88e75fba26 100644 --- a/backends/platform/wii/module.mk +++ b/backends/platform/wii/module.mk @@ -8,8 +8,7 @@ MODULE_OBJS := \ osystem_sfx.o \ osystem_events.o -MODULE_DIRS += \ - backends/platform/wii/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) diff --git a/backends/platform/wince/module.mk b/backends/platform/wince/module.mk index 6e328b0af4..2d852670f8 100644 --- a/backends/platform/wince/module.mk +++ b/backends/platform/wince/module.mk @@ -28,8 +28,7 @@ MODULE_OBJS := \ PocketSCUMM.o \ smartLandScale.o -MODULE_DIRS += \ - backends/platform/wince/ - -# We don't use the rules.mk here on purpose -OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) +# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. +MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) +OBJS := $(MODULE_OBJS) $(OBJS) +MODULE_DIRS += $(sort $(dir $(MODULE_OBJS))) diff --git a/base/commandLine.cpp b/base/commandLine.cpp index e795b82d0a..2f4e78fd80 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -49,7 +49,7 @@ static const char USAGE_STRING[] = ; // DONT FIXME: DO NOT ORDER ALPHABETICALLY, THIS IS ORDERED BY IMPORTANCE/CATEGORY! :) -#if defined(PALMOS_MODE) || defined(__SYMBIAN32__) || defined(__GP32__) || defined(ANDROID) +#if defined(__SYMBIAN32__) || defined(__GP32__) || defined(ANDROID) static const char HELP_STRING[] = "NoUsageString"; // save more data segment space #else static const char HELP_STRING[] = @@ -944,7 +944,7 @@ Common::Error processSettings(Common::String &command, Common::StringMap &settin // environment variable. This is weaker than a --savepath on the // command line, but overrides the default savepath, hence it is // handled here, just before the command line gets parsed. -#if !defined(MACOS_CARBON) && !defined(_WIN32_WCE) && !defined(PALMOS_MODE) && !defined(__GP32__) && !defined(ANDROID) +#if !defined(_WIN32_WCE) && !defined(__GP32__) && !defined(ANDROID) if (!settings.contains("savepath")) { const char *dir = getenv("SCUMMVM_SAVEPATH"); if (dir && *dir && strlen(dir) < MAXPATHLEN) { diff --git a/base/main.cpp b/base/main.cpp index 477f2afcb1..3173f26783 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -346,7 +346,7 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { // On the other hand we cannot load the plugins before we know the file paths (in case of external plugins). if (settings.contains("music-driver")) { if (MidiDriver::getMusicType(MidiDriver::getDeviceHandle(settings["music-driver"])) == MT_INVALID) { - warning("Unrecognized music driver '%s'. Switching to default device.", settings["music-driver"].c_str()); + warning("Unrecognized music driver '%s'. Switching to default device", settings["music-driver"].c_str()); settings["music-driver"] = "auto"; } } diff --git a/base/plugins.cpp b/base/plugins.cpp index a6acd7e449..5d0be11065 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -172,10 +172,10 @@ public: #if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) LINK_PLUGIN(WINDOWS) #endif - #if defined(UNIX) && defined(USE_ALSA) + #if defined(USE_ALSA) LINK_PLUGIN(ALSA) #endif - #if defined(UNIX) && !defined(__BEOS__) && !defined(__MAEMO__) && !defined(__MINT__) && !defined(__ANDROID__) + #if defined(USE_SEQ_MIDI) LINK_PLUGIN(SEQ) #endif #if defined(__MINT__) @@ -191,13 +191,6 @@ public: LINK_PLUGIN(COREAUDIO) LINK_PLUGIN(COREMIDI) #endif - #if defined(PALMOS_MODE) - # if defined(COMPILE_CLIE) - LINK_PLUGIN(YPA1) - # elif defined(COMPILE_ZODIAC) && (!defined(ENABLE_SCUMM) || !defined(PALMOS_ARM)) - LINK_PLUGIN(ZODIAC) - # endif - #endif #ifdef USE_FLUIDSYNTH LINK_PLUGIN(FLUIDSYNTH) #endif diff --git a/base/version.cpp b/base/version.cpp index ad74c64265..17058d4a03 100644 --- a/base/version.cpp +++ b/base/version.cpp @@ -86,6 +86,10 @@ const char *gScummVMFeatures = "" "ALSA " #endif +#ifdef USE_SEQ_MIDI + "SEQ " +#endif + #ifdef USE_RGB_COLOR "RGB " #endif diff --git a/common/hashmap.h b/common/hashmap.h index db80f632ed..0d4d7663f3 100644 --- a/common/hashmap.h +++ b/common/hashmap.h @@ -68,9 +68,6 @@ template<class T> class IteratorImpl; template<class Key, class Val, class HashFunc = Hash<Key>, class EqualFunc = EqualTo<Key> > class HashMap { private: -#if defined (PALMOS_MODE) -public: -#endif typedef HashMap<Key, Val, HashFunc, EqualFunc> HM_t; diff --git a/common/ptr.h b/common/ptr.h index 25ce6dcd64..7307038936 100644 --- a/common/ptr.h +++ b/common/ptr.h @@ -242,7 +242,7 @@ public: */ operator bool() const { return _pointer != 0; } - ~ScopedPtr() { + ~ScopedPtr() { delete _pointer; } @@ -255,14 +255,14 @@ public: } /** - * Returns the plain pointer value. + * Returns the plain pointer value. * * @return the pointer the ScopedPtr manages */ PointerType get() const { return _pointer; } /** - * Returns the plain pointer value and releases ScopedPtr. + * Returns the plain pointer value and releases ScopedPtr. * After release() call you need to delete object yourself * * @return the pointer the ScopedPtr manages diff --git a/common/scummsys.h b/common/scummsys.h index 98dd47e171..96639716ea 100644 --- a/common/scummsys.h +++ b/common/scummsys.h @@ -243,27 +243,6 @@ #define SCUMM_NEED_ALIGNMENT #endif -#elif defined(__PALMOS_TRAPS__) || defined (__PALMOS_ARMLET__) - -#ifdef __PALMOS_ARMLET__ - #include <extras_string.h> -#endif - #define SCUMM_LITTLE_ENDIAN - - #define scumm_stricmp stricmp - #define scumm_strnicmp strnicmp - - #define SCUMM_NEED_ALIGNMENT - #define STRINGBUFLEN 256 - - extern const char *SCUMMVM_SAVEPATH; - - #if !defined(COMPILE_ZODIAC) && !defined(COMPILE_OS5) - # define NEWGUI_256 - #else - # undef UNUSED - #endif - #elif defined(__DC__) #define scumm_stricmp strcasecmp diff --git a/common/singleton.h b/common/singleton.h index d66fb84cc2..2f721a65f7 100644 --- a/common/singleton.h +++ b/common/singleton.h @@ -95,7 +95,7 @@ protected: * Note that you need to use this macro from the global namespace. * * This is because C++ requires initial explicit specialization - * to be placed in the same namespace as the template. + * to be placed in the same namespace as the template. * It has to be put in the global namespace to assure the correct * namespace Common is referenced. */ diff --git a/common/textconsole.cpp b/common/textconsole.cpp index 2e5a347489..0d0b0aead9 100644 --- a/common/textconsole.cpp +++ b/common/textconsole.cpp @@ -155,11 +155,6 @@ void NORETURN_PRE error(const char *s, ...) { __android_log_assert("Fatal error", "ScummVM", "%s", buf_output); #endif -#ifdef PALMOS_MODE - extern void PalmFatalError(const char *err); - PalmFatalError(buf_output); -#endif - #ifdef __SYMBIAN32__ Symbian::FatalError(buf_output); #endif @@ -167,7 +162,7 @@ void NORETURN_PRE error(const char *s, ...) { #ifdef __PSP__ PspDebugTrace(false, "%s", buf_output); // write to file #endif - + // Finally exit. quit() will terminate the program if g_system is present if (g_system) g_system->quit(); diff --git a/common/translation.cpp b/common/translation.cpp index 093f26510f..ab6a922c6e 100644 --- a/common/translation.cpp +++ b/common/translation.cpp @@ -65,7 +65,7 @@ TranslationManager::TranslationManager() { // http://msdn.microsoft.com/en-us/library/dd318101%28VS.85%29.aspx // On the other hand the locale constants used, seem to exist on Windows 98 too, // check this for that: http://msdn.microsoft.com/en-us/library/dd464799%28v=VS.85%29.aspx - // + // // I am not exactly sure what is the truth now, it might be very well that this breaks // support for systems older than Windows 2000.... // diff --git a/common/unarj.cpp b/common/unarj.cpp index c130533dc1..2b2af3c54f 100644 --- a/common/unarj.cpp +++ b/common/unarj.cpp @@ -738,7 +738,7 @@ ArjArchive::ArjArchive(const String &filename) : _arjFilename(filename) { warning("ArjArchive::ArjArchive(): Could not find the archive file"); return; } - + int32 firstHeaderOffset = findHeader(arjFile); if (firstHeaderOffset < 0) { @@ -828,7 +828,7 @@ SeekableReadStream *ArjArchive::createReadStreamForMember(const String &name) co delete decoder; } - return new Common::MemoryReadStream(uncompressedData, hdr->origSize, DisposeAfterUse::YES); + return new Common::MemoryReadStream(uncompressedData, hdr->origSize, DisposeAfterUse::YES); } Archive *makeArjArchive(const String &name) { diff --git a/common/util.cpp b/common/util.cpp index 521a12e4c7..9e36e0f161 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -345,7 +345,7 @@ const String getGameGUIOptionsDescriptionLanguage(Language lang) { uint32 parseGameGUIOptions(const String &str) { uint32 res = 0; - + for (int i = 0; g_gameOptions[i].desc; i++) if (str.contains(g_gameOptions[i].desc)) res |= g_gameOptions[i].option; @@ -119,6 +119,7 @@ _tremor=auto _flac=auto _mad=auto _alsa=auto +_seq_midi=auto _zlib=auto _mpeg2=no _fluidsynth=auto @@ -134,6 +135,7 @@ _build_scalers=yes _build_hq_scalers=yes _indeo3=auto _enable_prof=no +_unix=no # Default vkeybd/keymapper options _vkeybd=no _keymapper=no @@ -268,6 +270,10 @@ add_line_to_config_h() { '"$1" } +# Conditionally add a line of data to config.h. Takes two parameters: +# The first one can be set to 'no' to "comment out" the line, i.e. +# make it ineffective, use 'yes' otherwise. +# The second param is the line to insert. add_to_config_h_if_yes() { if test "$1" = yes ; then add_line_to_config_h "$2" @@ -288,15 +294,28 @@ add_to_config_mk_if_yes() { fi } -# Conditionally add a line of data to config.mk. Takes two parameters: -# The first one can be set to 'yes' to "comment out" the line, i.e. -# make it ineffective, use 'no' otherwise. -# The second param is the line to insert. -add_to_config_mk_if_no() { - if test "$1" = no ; then - add_line_to_config_mk "$2" +# Conditionally add a '#define' line to config.h. Takes two parameters: +# The first one can be set to 'yes' or 'no'. If 'yes' is used, then +# the line "#define $2" is added to config.h, otherwise "#undef $2". +define_in_config_h_if_yes() { + if test "$1" = yes ; then + add_line_to_config_h "#define $2" else - add_line_to_config_mk "# $2" + add_line_to_config_h "#undef $2" + fi +} + +# Conditionally add definitions to config.h and config.mk. Takes two parameters: +# The first one can be set to 'yes' or 'no'. If 'yes' is used, then +# the line "#define $2" is added to config.h and "$2 = 1" to config.mk. +# Otherwise "#undef $2" is added to config.h and "# $2 = 1" to config.mk +define_in_config_if_yes() { + if test "$1" = yes ; then + add_line_to_config_h "#define $2" + add_line_to_config_mk "$2 = 1" + else + add_line_to_config_h "#undef $2" + add_line_to_config_mk "# $2 = 1" fi } @@ -745,6 +764,8 @@ for ac_option in $@; do --disable-hq-scalers) _build_hq_scalers=no ;; --enable-alsa) _alsa=yes ;; --disable-alsa) _alsa=no ;; + --enable-seq-midi) _seq_midi=yes ;; + --disable-seq-midi) _seq_midi=no ;; --enable-vorbis) _vorbis=yes ;; --disable-vorbis) _vorbis=no ;; --enable-tremor) _tremor=yes ;; @@ -1335,41 +1356,44 @@ echo $_host_os case $_host_os in amigaos*) CXXFLAGS="$CXXFLAGS -mcrt=newlib -mstrict-align -mcpu=750 -mtune=7400" - LDFLAGS="$LDFLAGS -mcrt=newlib -use-dynld -Lsobjs:" + LDFLAGS="$LDFLAGS -mcrt=newlib -use-dynld -LSDK:Local/newib/lib" # We have to use 'long' for our 4 byte typedef because AmigaOS already typedefs (u)int32 # as (unsigned) long, and consequently we'd get a compiler error otherwise. type_4_byte='long' ;; beos*) - DEFINES="$DEFINES -DUNIX -DSYSTEM_NOT_SUPPORTING_D_TYPE" + DEFINES="$DEFINES -DSYSTEM_NOT_SUPPORTING_D_TYPE" # Needs -lbind -lsocket for the timidity MIDI driver LDFLAGS="-L/boot/home/config/lib" CFLAGS="-I/boot/home/config/include" CXXFLAGS="$CXXFLAGS -fhuge-objects" LIBS="$LIBS -lbind -lsocket" + _unix=yes + _seq_midi=no ;; bsd* | hpux* | netbsd* | openbsd* | sunos*) - DEFINES="$DEFINES -DUNIX" + _unix=yes ;; cygwin*) echo ERROR: Cygwin building is not supported by ScummVM anymore. Consider using MinGW. exit 1 ;; darwin*) - DEFINES="$DEFINES -DUNIX -DMACOSX" + DEFINES="$DEFINES -DMACOSX" CXXFLAGS="$CXXFLAGS" LIBS="$LIBS -framework AudioUnit -framework AudioToolbox -framework Carbon -framework CoreMIDI" OPENGL_CFLAGS="-I/System/Library/Frameworks/OpenGL.framework/Headers" OPENGL_LIBS="-framework OpenGL" add_line_to_config_mk 'MACOSX = 1' + _unix=yes ;; dreamcast) DEFINES="$DEFINES -D__DC__ -DNONSTANDARD_PORT" ;; freebsd*) - DEFINES="$DEFINES -DUNIX" LDFLAGS="$LDFLAGS -L/usr/local/lib" CXXFLAGS="$CXXFLAGS -I/usr/local/include" + _unix=yes ;; gamecube) CXXFLAGS="$CXXFLAGS -Os -mogc -mcpu=750 -meabi -mhard-float" @@ -1379,15 +1403,18 @@ case $_host_os in LDFLAGS="$LDFLAGS -mogc -mcpu=750 -L$DEVKITPRO/libogc/lib/cube -L$DEVKITPRO/cube/lib -logc" ;; haiku*) - DEFINES="$DEFINES -DUNIX -DSYSTEM_NOT_SUPPORTING_D_TYPE" + DEFINES="$DEFINES -DSYSTEM_NOT_SUPPORTING_D_TYPE" # Needs -lnetwork for the timidity MIDI driver LIBS="$LIBS -lnetwork" CXXFLAGS="$CXXFLAGS -fhuge-objects" + _unix=yes + _seq_midi=no ;; irix*) - DEFINES="$DEFINES -DUNIX -DIRIX -DSYSTEM_NOT_SUPPORTING_D_TYPE" + DEFINES="$DEFINES -DIRIX -DSYSTEM_NOT_SUPPORTING_D_TYPE" LIBS="$LIBS -lmd -lfastm -lm" _ranlib=: + _unix=yes ;; linux* | uclinux*) # When not cross-compiling, enable large file support, but don't @@ -1395,7 +1422,7 @@ case $_host_os in if test -z "$_host"; then CXXFLAGS="$CXXFLAGS $(getconf LFS_CFLAGS 2>/dev/null)" fi - DEFINES="$DEFINES -DUNIX" + _unix=yes ;; mingw*) DEFINES="$DEFINES -DWIN32 -D__USE_MINGW_ANSI_STDIO=0" @@ -1403,7 +1430,8 @@ case $_host_os in OBJS="$OBJS scummvmico.o" ;; mint*) - DEFINES="$DEFINES -DUNIX -DSYSTEM_NOT_SUPPORTING_D_TYPE" + DEFINES="$DEFINES -DSYSTEM_NOT_SUPPORTING_D_TYPE" + _unix=yes ;; ds) # TODO Nintendo DS @@ -1415,7 +1443,7 @@ case $_host_os in LIBS="$LIBS -lnds9" ;; os2-emx*) - DEFINES="$DEFINES -DUNIX" + _unix=yes # FIXME??? Why?? ;; ps2) # TODO ps2 @@ -1426,9 +1454,10 @@ case $_host_os in CXXFLAGS="$CXXFLAGS -O3 -I$PSPSDK/include -D_PSP_FW_VERSION=150" ;; solaris*) - DEFINES="$DEFINES -DUNIX -DSOLARIS -DSYSTEM_NOT_SUPPORTING_D_TYPE" + DEFINES="$DEFINES -DSOLARIS -DSYSTEM_NOT_SUPPORTING_D_TYPE" # Needs -lbind -lsocket for the timidity MIDI driver LIBS="$LIBS -lnsl -lsocket" + _unix=yes ;; wii) CXXFLAGS="$CXXFLAGS -Os -mrvl -mcpu=750 -meabi -mhard-float" @@ -1443,14 +1472,15 @@ case $_host_os in DEFINES="$DEFINES -DWIN32 -Dcdecl= -D__cdecl__=" ;; android) - DEFINES="$DEFINES -DUNIX" CXXFLAGS="$CXXFLAGS -Os -msoft-float -mtune=xscale -march=armv5te -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5TE__" add_line_to_config_mk "ANDROID_SDK = $ANDROID_SDK" + _unix=yes + _seq_midi=no ;; # given this is a shell script assume some type of unix *) echo "WARNING: could not establish system type, assuming unix like" - DEFINES="$DEFINES -DUNIX" + _unix=yes ;; esac @@ -1467,7 +1497,7 @@ if test -n "$_host"; then echo "Cross-compiling to $_host" case "$_host" in arm-linux|arm*-linux-gnueabi|arm-*-linux) - DEFINES="$DEFINES -DUNIX" + _unix=yes _need_memalign=yes add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' @@ -1476,7 +1506,8 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' ;; arm-riscos|linupy) - DEFINES="$DEFINES -DUNIX -DLINUPY" + DEFINES="$DEFINES -DLINUPY" + _unix=yes _need_memalign=yes ;; bfin*) @@ -1511,10 +1542,11 @@ if test -n "$_host"; then add_line_to_config_h "/* #define DEBUG_WII_GDB */" ;; gp2x) - DEFINES="$DEFINES -DUNIX -DGP2X -DNDEBUG" + DEFINES="$DEFINES -DGP2X -DNDEBUG" CXXFLAGS="$CXXFLAGS -march=armv4t" ASFLAGS="$ASFLAGS -mfloat-abi=soft" LDFLAGS="$LDFLAGS -static" + _unix=yes _need_memalign=yes add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' @@ -1525,12 +1557,14 @@ if test -n "$_host"; then _build_hq_scalers="no" _mt32emu="no" _vkeybd="yes" + _seq_midi=no _port_mk="backends/platform/gp2x/gp2x-bundle.mk" ;; gp2xwiz) - DEFINES="$DEFINES -DUNIX -DGP2XWIZ -DNDEBUG" + DEFINES="$DEFINES -DGP2XWIZ -DNDEBUG" CXXFLAGS="$CXXFLAGS -mcpu=arm926ej-s -mtune=arm926ej-s" ASFLAGS="$ASFLAGS -mfloat-abi=soft" + _unix=yes _need_memalign=yes add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' @@ -1541,22 +1575,27 @@ if test -n "$_host"; then _build_hq_scalers="no" _mt32emu="no" _vkeybd="yes" + _seq_midi=no _port_mk="backends/platform/gp2xwiz/gp2xwiz-bundle.mk" ;; iphone) - DEFINES="$DEFINES -DIPHONE -DUNIX" + DEFINES="$DEFINES -DIPHONE" + _unix=yes _need_memalign=yes add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' _backend="iphone" _build_hq_scalers="no" + _seq_midi=no ;; m68k-atari-mint) - DEFINES="$DEFINES -DUNIX -DSYSTEM_NOT_SUPPORTING_D_TYPE" + DEFINES="$DEFINES -DSYSTEM_NOT_SUPPORTING_D_TYPE" + _unix=yes _endian=big _need_memalign=yes _ranlib=m68k-atari-mint-ranlib _ar="m68k-atari-mint-ar cru" + _seq_midi=no ;; *mingw32*) _sdlconfig=$_host-sdl-config @@ -1569,8 +1608,9 @@ if test -n "$_host"; then _need_memalign=yes ;; motoezx) - DEFINES="$DEFINES -DUNIX -DMOTOEZX" + DEFINES="$DEFINES -DMOTOEZX" ASFLAGS="$ASFLAGS -mfpu=vfp" + _unix=yes _need_memalign=yes add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' @@ -1581,11 +1621,13 @@ if test -n "$_host"; then _build_hq_scalers="no" _mt32emu="no" _vkeybd="yes" + _seq_midi=no _port_mk="backends/platform/linuxmoto/linuxmoto.mk" ;; motomagx) - DEFINES="$DEFINES -DUNIX -DMOTOMAGX" + DEFINES="$DEFINES -DMOTOMAGX" ASFLAGS="$ASFLAGS -mfpu=vfp" + _unix=yes _need_memalign=yes add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' @@ -1596,6 +1638,7 @@ if test -n "$_host"; then _build_hq_scalers="no" _mt32emu="no" _vkeybd="yes" + _seq_midi=no _port_mk="backends/platform/linuxmoto/linuxmoto.mk" ;; ds) @@ -1617,7 +1660,8 @@ if test -n "$_host"; then _port_mk="backends/platform/ds/ds.mk" ;; neuros) - DEFINES="$DEFINES -DUNIX -DNEUROS" + DEFINES="$DEFINES -DNEUROS" + _unix=yes _need_memalign=yes _backend='null' _build_hq_scalers="no" @@ -1664,9 +1708,10 @@ if test -n "$_host"; then _port_mk="backends/platform/psp/psp.mk" ;; samsungtv) - DEFINES="$DEFINES -DUNIX -DSAMSUNGTV -DDISABLE_COMMAND_LINE" + DEFINES="$DEFINES -DSAMSUNGTV -DDISABLE_COMMAND_LINE" ASFLAGS="$ASFLAGS -mfpu=vfp" HOSTEXEEXT=".so" + _unix=yes _need_memalign=yes add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' @@ -1705,7 +1750,8 @@ if test -n "$_host"; then _port_mk="backends/platform/wince/wince.mk" ;; android) - DEFINES="$DEFINES -DANDROID -DUNIX -DUSE_ARM_SMUSH_ASM" + DEFINES="$DEFINES -DANDROID -DUSE_ARM_SMUSH_ASM" + _unix=yes _need_memalign=yes add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' @@ -1714,6 +1760,7 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' _backend="android" _port_mk="backends/platform/android/android.mk" + _seq_midi=no ;; *) echo "WARNING: Unknown target, continuing with auto-detected values" @@ -1791,21 +1838,25 @@ esac # case $_endian in big) - add_line_to_config_h '/* #define SCUMM_LITTLE_ENDIAN */' + add_line_to_config_h '#undef SCUMM_LITTLE_ENDIAN' add_line_to_config_h '#define SCUMM_BIG_ENDIAN' ;; little) add_line_to_config_h '#define SCUMM_LITTLE_ENDIAN' - add_line_to_config_h '/* #define SCUMM_BIG_ENDIAN */' + add_line_to_config_h '#undef SCUMM_BIG_ENDIAN' ;; *) exit 1 ;; esac -add_to_config_h_if_yes $_have_x86 '#define HAVE_X86' +define_in_config_h_if_yes $_have_x86 'HAVE_X86' -add_to_config_h_if_yes $_need_memalign '#define SCUMM_NEED_ALIGNMENT' +define_in_config_h_if_yes $_need_memalign 'SCUMM_NEED_ALIGNMENT' + +if test "$_unix" = yes ; then + DEFINES="$DEFINES -DUNIX" +fi # # Check whether to enable a verbose build @@ -1939,7 +1990,7 @@ PLUGIN_SUFFIX := .plg PLUGIN_EXTRA_DEPS = $(EXECUTABLE) CXXFLAGS += -DDYNAMIC_MODULES LDFLAGS += -Wl,-T$(srcdir)/backends/platform/psp/main_prog.ld -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(srcdir)/backends/platform/psp/plugin.syms,-T$(srcdir)/backends/platform/psp/plugin.ld -lstdc++ -lc -lm +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(srcdir)/backends/platform/psp/plugin.syms,-T$(srcdir)/backends/platform/psp/plugin.ld -lstdc++ -lc -lm -Wl,--wrap,memcpy PRE_OBJS_FLAGS := -Wl,--whole-archive POST_OBJS_FLAGS := -Wl,--no-whole-archive ' @@ -1957,40 +2008,22 @@ fi # # Check whether integrated MT-32 emulator support is requested # -if test "$_mt32emu" = no ; then - _def_mt32emu='#undef USE_MT32EMU' -else - _def_mt32emu='#define USE_MT32EMU' -fi -add_to_config_mk_if_yes "$_mt32emu" 'USE_MT32EMU = 1' +define_in_config_if_yes "$_mt32emu" 'USE_MT32EMU' # # Check whether 16bit color support is requested # -if test "$_16bit" = no ; then - _def_16bit='#undef USE_RGB_COLOR' -else - _def_16bit='#define USE_RGB_COLOR' -fi -add_to_config_mk_if_yes "$_16bit" 'USE_RGB_COLOR = 1' +define_in_config_if_yes "$_16bit" 'USE_RGB_COLOR' # # Check whether to enable the (hq) scalers # if test "$_build_scalers" = no ; then _build_hq_scalers=no - _def_scalers='#undef USE_SCALERS' -else - _def_scalers='#define USE_SCALERS' fi -add_to_config_mk_if_yes "$_build_scalers" 'USE_SCALERS = 1' +define_in_config_if_yes "$_build_scalers" 'USE_SCALERS' -if test "$_build_hq_scalers" = no ; then - _def_hq_scalers='#undef USE_HQ_SCALERS' -else - _def_hq_scalers='#define USE_HQ_SCALERS' -fi -add_to_config_mk_if_yes "$_build_hq_scalers" 'USE_HQ_SCALERS = 1' +define_in_config_if_yes "$_build_hq_scalers" 'USE_HQ_SCALERS' # # Check whether to compile the Indeo3 decoder @@ -2003,12 +2036,7 @@ if test "$_indeo3" = auto ; then _indeo3="no" fi fi -if test "$_indeo3" = no ; then - _def_indeo3='#undef USE_INDEO3' -else - _def_indeo3='#define USE_INDEO3' -fi -add_to_config_mk_if_yes "$_indeo3" 'USE_INDEO3 = 1' +define_in_config_if_yes "$_indeo3" 'USE_INDEO3' # # Check for math lib @@ -2032,13 +2060,10 @@ EOF -lvorbisfile -lvorbis -logg && _vorbis=yes fi if test "$_vorbis" = yes ; then - _def_vorbis='#define USE_VORBIS' LIBS="$LIBS $OGG_LIBS $VORBIS_LIBS -lvorbisfile -lvorbis -logg" INCLUDES="$INCLUDES $OGG_CFLAGS $VORBIS_CFLAGS" -else - _def_vorbis='#undef USE_VORBIS' fi -add_to_config_mk_if_yes "$_vorbis" 'USE_VORBIS = 1' +define_in_config_if_yes "$_vorbis" 'USE_VORBIS' echo "$_vorbis" # @@ -2055,15 +2080,15 @@ EOF _tremor=yes fi if test "$_tremor" = yes && test "$_vorbis" = no; then - _def_tremor='#define USE_TREMOR' - _def_vorbis='#define USE_VORBIS' + add_line_to_config_h '#define USE_TREMOR' + add_line_to_config_h '#define USE_VORBIS' LIBS="$LIBS $TREMOR_LIBS -lvorbisidec" INCLUDES="$INCLUDES $TREMOR_CFLAGS" else if test "$_vorbis" = yes; then _tremor="no (Ogg Vorbis/Tremor support is mutually exclusive)" fi - _def_tremor='#undef USE_TREMOR' + add_line_to_config_h '#undef USE_TREMOR' fi add_to_config_mk_if_yes "$_tremor" 'USE_TREMOR = 1' echo "$_tremor" @@ -2087,17 +2112,14 @@ EOF fi fi if test "$_flac" = yes ; then - _def_flac='#define USE_FLAC' if test "$_vorbis" = yes ; then LIBS="$LIBS $FLAC_LIBS $OGG_LIBS -lFLAC -logg" else LIBS="$LIBS $FLAC_LIBS -lFLAC" fi INCLUDES="$INCLUDES $FLAC_CFLAGS" -else - _def_flac='#undef USE_FLAC' fi -add_to_config_mk_if_yes "$_flac" 'USE_FLAC = 1' +define_in_config_if_yes "$_flac" 'USE_FLAC' echo "$_flac" # @@ -2113,13 +2135,10 @@ EOF cc_check $MAD_CFLAGS $MAD_LIBS -lmad && _mad=yes fi if test "$_mad" = yes ; then - _def_mad='#define USE_MAD' LIBS="$LIBS $MAD_LIBS -lmad" INCLUDES="$INCLUDES $MAD_CFLAGS" -else - _def_mad='#undef USE_MAD' fi -add_to_config_mk_if_yes "$_mad" 'USE_MAD = 1' +define_in_config_if_yes "$_mad" 'USE_MAD' echo "$_mad" # @@ -2135,15 +2154,26 @@ EOF cc_check $ALSA_CFLAGS $ALSA_LIBS -lasound && _alsa=yes fi if test "$_alsa" = yes ; then - _def_alsa='#define USE_ALSA' LIBS="$LIBS $ALSA_LIBS -lasound" INCLUDES="$INCLUDES $ALSA_CFLAGS" -else - _def_alsa='#undef USE_ALSA' fi +define_in_config_h_if_yes "$_alsa" 'USE_ALSA' echo "$_alsa" # +# Check for SEQ MIDI +# +echocheck "SEQ MIDI" +if test "$_seq_midi" = auto ; then + # TODO: Test for /dev/sequencer presence? Or maybe just for /dev ? + # For now, we just always enable it when "unix" mode is on (backends + # that do not want it can disable it by setting _seq_midi=no). + _seq_midi="$_unix" +fi +define_in_config_h_if_yes "$_seq_midi" 'USE_SEQ_MIDI' +echo "$_seq_midi" + +# # Check for ZLib # echocheck "zlib" @@ -2157,13 +2187,10 @@ EOF cc_check $ZLIB_CFLAGS $ZLIB_LIBS -lz && _zlib=yes fi if test "$_zlib" = yes ; then - _def_zlib='#define USE_ZLIB' LIBS="$LIBS $ZLIB_LIBS -lz" INCLUDES="$INCLUDES $ZLIB_CFLAGS" -else - _def_zlib='#undef USE_ZLIB' fi -add_to_config_mk_if_yes "$_zlib" 'USE_ZLIB = 1' +define_in_config_if_yes "$_zlib" 'USE_ZLIB' echo "$_zlib" # @@ -2203,13 +2230,10 @@ EOF fi fi if test "$_mpeg2" = yes ; then - _def_mpeg2='#define USE_MPEG2' INCLUDES="$INCLUDES $MPEG2_CFLAGS" LIBS="$LIBS $MPEG2_LIBS -lmpeg2" -else - _def_mpeg2='#undef USE_MPEG2' fi -add_to_config_mk_if_yes "$_mpeg2" 'USE_MPEG2 = 1' +define_in_config_if_yes "$_mpeg2" 'USE_MPEG2' echo "$_mpeg2" # @@ -2225,7 +2249,6 @@ EOF cc_check $FLUIDSYNTH_CFLAGS $FLUIDSYNTH_LIBS -lfluidsynth && _fluidsynth=yes fi if test "$_fluidsynth" = yes ; then - _def_fluidsynth='#define USE_FLUIDSYNTH' case $_host_os in mingw*) LIBS="$LIBS $FLUIDSYNTH_LIBS -lfluidsynth -ldsound -lwinmm" @@ -2235,9 +2258,8 @@ if test "$_fluidsynth" = yes ; then ;; esac INCLUDES="$INCLUDES $FLUIDSYNTH_CFLAGS" -else - _def_fluidsynth='#undef USE_FLUIDSYNTH' fi +define_in_config_h_if_yes "$_fluidsynth" 'USE_FLUIDSYNTH' echo "$_fluidsynth" # @@ -2257,12 +2279,13 @@ int main(void) { char *x = readline(""); } EOF - cc_check $READLINE_CFLAGS $READLINE_LIBS $_READLINE_LIBS && _readline=yes + cc_check_no_clean $READLINE_CFLAGS $READLINE_LIBS $_READLINE_LIBS && _readline=yes if test "$_readline" = no ; then _READLINE_LIBS="-lreadline -ltermcap" - cc_check $READLINE_CFLAGS $READLINE_LIBS $_READLINE_LIBS && _readline=yes + cc_check_no_clean $READLINE_CFLAGS $READLINE_LIBS $_READLINE_LIBS && _readline=yes fi fi + cc_check_clean echo "$_readline" else _readline=no @@ -2270,18 +2293,12 @@ else fi if test "$_readline" = yes ; then - _def_readline='#define USE_READLINE' LIBS="$LIBS $READLINE_LIBS $_READLINE_LIBS" INCLUDES="$INCLUDES $READLINE_CFLAGS" -else - _def_readline='#undef USE_READLINE' fi +define_in_config_h_if_yes "$_readline" 'USE_READLINE' -if test "$_text_console" = yes ; then - _def_text_console='#define USE_TEXT_CONSOLE' -else - _def_text_console='#undef USE_TEXT_CONSOLE' -fi +define_in_config_h_if_yes "$_text_console" 'USE_TEXT_CONSOLE' # # Check for OpenGL (ES) @@ -2361,8 +2378,7 @@ if test "$_have_x86" = yes ; then fi fi -add_to_config_h_if_yes $_nasm '#define USE_NASM' -add_to_config_mk_if_yes $_nasm 'USE_NASM = 1' +define_in_config_if_yes $_nasm 'USE_NASM' # # Enable vkeybd / keymapper @@ -2377,8 +2393,7 @@ fi # Check whether to build translation support # echo_n "Building translation support... " -add_to_config_mk_if_yes $_translation 'USE_TRANSLATION = 1' -add_to_config_h_if_yes $_translation '#define USE_TRANSLATION' +define_in_config_if_yes $_translation 'USE_TRANSLATION' if test "$_translation" = no ; then echo "no" else @@ -2391,7 +2406,7 @@ EOF _detectlang=no cc_check $LDFLAGS $CXXFLAGS && _detectlang=yes - add_to_config_h_if_yes $_detectlang '#define USE_DETECTLANG' + define_in_config_h_if_yes $_detectlang 'USE_DETECTLANG' if test "$_detectlang" = yes ; then echo "with runtime language detection)" else @@ -2513,6 +2528,7 @@ case $_backend in psp) DEFINES="$DEFINES -D__PSP__ -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DDISABLE_DOSBOX_OPL" LIBS="$LIBS -lpng -Wl,-Map,mapfile.txt" + LDFLAGS="$LDFLAGS -Wl,--wrap,memcpy" ;; samsungtv) find_sdlconfig @@ -2719,25 +2735,6 @@ typedef signed $type_1_byte int8; typedef signed $type_2_byte int16; typedef signed $type_4_byte int32; -/* Libs */ -$_def_vorbis -$_def_tremor -$_def_flac -$_def_mad -$_def_alsa -$_def_zlib -$_def_mpeg2 -$_def_fluidsynth -$_def_readline - -/* Options */ -$_def_text_console -$_def_mt32emu -$_def_indeo3 -$_def_16bit -$_def_scalers -$_def_hq_scalers - /* Plugin settings */ $_def_plugin diff --git a/dists/iphone/icon-72.png b/dists/iphone/icon-72.png Binary files differindex d8820f3397..9b424b4018 100644 --- a/dists/iphone/icon-72.png +++ b/dists/iphone/icon-72.png diff --git a/dists/iphone/scummvm.xcodeproj/project.pbxproj b/dists/iphone/scummvm.xcodeproj/project.pbxproj index 032470cf25..5512318918 100755 --- a/dists/iphone/scummvm.xcodeproj/project.pbxproj +++ b/dists/iphone/scummvm.xcodeproj/project.pbxproj @@ -782,7 +782,6 @@ DF0941C20F63CB26002D821E /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0D0F4870E50006E566 /* staticres.cpp */; }; DF0941C30F63CB26002D821E /* tucker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0E0F4870E50006E566 /* tucker.cpp */; }; DF0941C40F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301A0F48AF18005EF03C /* detection.cpp */; }; - DF0941C50F63CB26002D821E /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301D0F48AF18005EF03C /* game.cpp */; }; DF0941C60F63CB26002D821E /* gc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301E0F48AF18005EF03C /* gc.cpp */; }; DF0941C80F63CB26002D821E /* kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830230F48AF18005EF03C /* kernel.cpp */; }; DF0941C90F63CB26002D821E /* kevent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830260F48AF18005EF03C /* kevent.cpp */; }; @@ -960,7 +959,6 @@ DF45B1CE116628A5009B85CC /* coordadjuster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17E116628A5009B85CC /* coordadjuster.cpp */; }; DF45B1CF116628A5009B85CC /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B180116628A5009B85CC /* cursor.cpp */; }; DF45B1D0116628A5009B85CC /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B182116628A5009B85CC /* font.cpp */; }; - DF45B1D2116628A5009B85CC /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B186116628A5009B85CC /* gui.cpp */; }; DF45B1D4116628A5009B85CC /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18B116628A5009B85CC /* menu.cpp */; }; DF45B1D5116628A5009B85CC /* paint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18D116628A5009B85CC /* paint.cpp */; }; DF45B1D6116628A5009B85CC /* paint16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18F116628A5009B85CC /* paint16.cpp */; }; @@ -979,13 +977,9 @@ DF45B1E4116628A5009B85CC /* vocabulary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A9116628A5009B85CC /* vocabulary.cpp */; }; DF45B1E5116628A5009B85CC /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AC116628A5009B85CC /* audio.cpp */; }; DF45B1E6116628A5009B85CC /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AF116628A5009B85CC /* adlib.cpp */; }; - DF45B1E7116628A5009B85CC /* amiga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B0116628A5009B85CC /* amiga.cpp */; }; DF45B1E8116628A5009B85CC /* fb01.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B1116628A5009B85CC /* fb01.cpp */; }; DF45B1E9116628A5009B85CC /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B3116628A5009B85CC /* midi.cpp */; }; DF45B1EA116628A5009B85CC /* pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B5116628A5009B85CC /* pcjr.cpp */; }; - DF45B1EB116628A5009B85CC /* core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B7116628A5009B85CC /* core.cpp */; }; - DF45B1EC116628A5009B85CC /* iterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B9116628A5009B85CC /* iterator.cpp */; }; - DF45B1ED116628A5009B85CC /* songlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1BC116628A5009B85CC /* songlib.cpp */; }; DF45B1EF116628A5009B85CC /* midiparser_sci.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1BF116628A5009B85CC /* midiparser_sci.cpp */; }; DF45B1F0116628A5009B85CC /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C1116628A5009B85CC /* music.cpp */; }; DF45B1F1116628A5009B85CC /* soundcmd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C3116628A5009B85CC /* soundcmd.cpp */; }; @@ -998,7 +992,6 @@ DF45B1F8116628A5009B85CC /* coordadjuster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17E116628A5009B85CC /* coordadjuster.cpp */; }; DF45B1F9116628A5009B85CC /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B180116628A5009B85CC /* cursor.cpp */; }; DF45B1FA116628A5009B85CC /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B182116628A5009B85CC /* font.cpp */; }; - DF45B1FC116628A5009B85CC /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B186116628A5009B85CC /* gui.cpp */; }; DF45B1FE116628A5009B85CC /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18B116628A5009B85CC /* menu.cpp */; }; DF45B1FF116628A5009B85CC /* paint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18D116628A5009B85CC /* paint.cpp */; }; DF45B200116628A5009B85CC /* paint16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18F116628A5009B85CC /* paint16.cpp */; }; @@ -1017,13 +1010,9 @@ DF45B20E116628A5009B85CC /* vocabulary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A9116628A5009B85CC /* vocabulary.cpp */; }; DF45B20F116628A5009B85CC /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AC116628A5009B85CC /* audio.cpp */; }; DF45B210116628A5009B85CC /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AF116628A5009B85CC /* adlib.cpp */; }; - DF45B211116628A5009B85CC /* amiga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B0116628A5009B85CC /* amiga.cpp */; }; DF45B212116628A5009B85CC /* fb01.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B1116628A5009B85CC /* fb01.cpp */; }; DF45B213116628A5009B85CC /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B3116628A5009B85CC /* midi.cpp */; }; DF45B214116628A5009B85CC /* pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B5116628A5009B85CC /* pcjr.cpp */; }; - DF45B215116628A5009B85CC /* core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B7116628A5009B85CC /* core.cpp */; }; - DF45B216116628A5009B85CC /* iterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B9116628A5009B85CC /* iterator.cpp */; }; - DF45B217116628A5009B85CC /* songlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1BC116628A5009B85CC /* songlib.cpp */; }; DF45B219116628A5009B85CC /* midiparser_sci.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1BF116628A5009B85CC /* midiparser_sci.cpp */; }; DF45B21A116628A5009B85CC /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C1116628A5009B85CC /* music.cpp */; }; DF45B21B116628A5009B85CC /* soundcmd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C3116628A5009B85CC /* soundcmd.cpp */; }; @@ -1036,7 +1025,6 @@ DF45B222116628A5009B85CC /* coordadjuster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17E116628A5009B85CC /* coordadjuster.cpp */; }; DF45B223116628A5009B85CC /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B180116628A5009B85CC /* cursor.cpp */; }; DF45B224116628A5009B85CC /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B182116628A5009B85CC /* font.cpp */; }; - DF45B226116628A5009B85CC /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B186116628A5009B85CC /* gui.cpp */; }; DF45B228116628A5009B85CC /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18B116628A5009B85CC /* menu.cpp */; }; DF45B229116628A5009B85CC /* paint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18D116628A5009B85CC /* paint.cpp */; }; DF45B22A116628A5009B85CC /* paint16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18F116628A5009B85CC /* paint16.cpp */; }; @@ -1055,13 +1043,9 @@ DF45B238116628A5009B85CC /* vocabulary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A9116628A5009B85CC /* vocabulary.cpp */; }; DF45B239116628A5009B85CC /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AC116628A5009B85CC /* audio.cpp */; }; DF45B23A116628A5009B85CC /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AF116628A5009B85CC /* adlib.cpp */; }; - DF45B23B116628A5009B85CC /* amiga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B0116628A5009B85CC /* amiga.cpp */; }; DF45B23C116628A5009B85CC /* fb01.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B1116628A5009B85CC /* fb01.cpp */; }; DF45B23D116628A5009B85CC /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B3116628A5009B85CC /* midi.cpp */; }; DF45B23E116628A5009B85CC /* pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B5116628A5009B85CC /* pcjr.cpp */; }; - DF45B23F116628A5009B85CC /* core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B7116628A5009B85CC /* core.cpp */; }; - DF45B240116628A5009B85CC /* iterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B9116628A5009B85CC /* iterator.cpp */; }; - DF45B241116628A5009B85CC /* songlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1BC116628A5009B85CC /* songlib.cpp */; }; DF45B243116628A5009B85CC /* midiparser_sci.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1BF116628A5009B85CC /* midiparser_sci.cpp */; }; DF45B244116628A5009B85CC /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C1116628A5009B85CC /* music.cpp */; }; DF45B245116628A5009B85CC /* soundcmd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C3116628A5009B85CC /* soundcmd.cpp */; }; @@ -1249,6 +1233,45 @@ DF7E8C110ED5FCC2001CB19F /* xmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C0F0ED5FCC2001CB19F /* xmlparser.cpp */; }; DF7E8C530ED60067001CB19F /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C510ED60067001CB19F /* game.cpp */; }; DF7E8C810ED60271001CB19F /* scummmodern.zip in Resources */ = {isa = PBXBuildFile; fileRef = DF7E8C7A0ED601E5001CB19F /* scummmodern.zip */; }; + DF7F285D11FF23B700159131 /* frameout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F285C11FF23B700159131 /* frameout.cpp */; }; + DF7F285E11FF23B700159131 /* frameout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F285C11FF23B700159131 /* frameout.cpp */; }; + DF7F285F11FF23B700159131 /* frameout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F285C11FF23B700159131 /* frameout.cpp */; }; + DF7F286111FF23D500159131 /* amigamac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286011FF23D500159131 /* amigamac.cpp */; }; + DF7F286211FF23D500159131 /* amigamac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286011FF23D500159131 /* amigamac.cpp */; }; + DF7F286311FF23D500159131 /* amigamac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286011FF23D500159131 /* amigamac.cpp */; }; + DF7F286711FF23EF00159131 /* kvideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286411FF23EF00159131 /* kvideo.cpp */; }; + DF7F286811FF23EF00159131 /* workarounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286511FF23EF00159131 /* workarounds.cpp */; }; + DF7F286911FF23EF00159131 /* kvideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286411FF23EF00159131 /* kvideo.cpp */; }; + DF7F286A11FF23EF00159131 /* workarounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286511FF23EF00159131 /* workarounds.cpp */; }; + DF7F286B11FF23EF00159131 /* kvideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286411FF23EF00159131 /* kvideo.cpp */; }; + DF7F286C11FF23EF00159131 /* workarounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286511FF23EF00159131 /* workarounds.cpp */; }; + DF7F287A11FF243B00159131 /* sound_2gs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287011FF243A00159131 /* sound_2gs.cpp */; }; + DF7F287B11FF243B00159131 /* sound_coco3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287211FF243B00159131 /* sound_coco3.cpp */; }; + DF7F287C11FF243B00159131 /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287411FF243B00159131 /* sound_midi.cpp */; }; + DF7F287D11FF243B00159131 /* sound_pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287611FF243B00159131 /* sound_pcjr.cpp */; }; + DF7F287E11FF243B00159131 /* sound_sarien.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287811FF243B00159131 /* sound_sarien.cpp */; }; + DF7F287F11FF243B00159131 /* sound_2gs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287011FF243A00159131 /* sound_2gs.cpp */; }; + DF7F288011FF243B00159131 /* sound_coco3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287211FF243B00159131 /* sound_coco3.cpp */; }; + DF7F288111FF243B00159131 /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287411FF243B00159131 /* sound_midi.cpp */; }; + DF7F288211FF243B00159131 /* sound_pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287611FF243B00159131 /* sound_pcjr.cpp */; }; + DF7F288311FF243B00159131 /* sound_sarien.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287811FF243B00159131 /* sound_sarien.cpp */; }; + DF7F288411FF243B00159131 /* sound_2gs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287011FF243A00159131 /* sound_2gs.cpp */; }; + DF7F288511FF243B00159131 /* sound_coco3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287211FF243B00159131 /* sound_coco3.cpp */; }; + DF7F288611FF243B00159131 /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287411FF243B00159131 /* sound_midi.cpp */; }; + DF7F288711FF243B00159131 /* sound_pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287611FF243B00159131 /* sound_pcjr.cpp */; }; + DF7F288811FF243B00159131 /* sound_sarien.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287811FF243B00159131 /* sound_sarien.cpp */; }; + DF7F288B11FF244F00159131 /* Tooltip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F288911FF244F00159131 /* Tooltip.cpp */; }; + DF7F288C11FF244F00159131 /* Tooltip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F288911FF244F00159131 /* Tooltip.cpp */; }; + DF7F288D11FF244F00159131 /* Tooltip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F288911FF244F00159131 /* Tooltip.cpp */; }; + DF7F289311FF247300159131 /* translation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F289111FF247300159131 /* translation.cpp */; }; + DF7F289511FF247300159131 /* translation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F289111FF247300159131 /* translation.cpp */; }; + DF7F289711FF247300159131 /* translation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F289111FF247300159131 /* translation.cpp */; }; + DF7F28A011FF24B000159131 /* mac_snd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F289E11FF24B000159131 /* mac_snd.cpp */; }; + DF7F28A111FF24B000159131 /* mac_snd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F289E11FF24B000159131 /* mac_snd.cpp */; }; + DF7F28A211FF24B000159131 /* mac_snd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F289E11FF24B000159131 /* mac_snd.cpp */; }; + DF7F28A511FF24C400159131 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F28A311FF24C400159131 /* console.cpp */; }; + DF7F28A611FF24C400159131 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F28A311FF24C400159131 /* console.cpp */; }; + DF7F28A711FF24C400159131 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F28A311FF24C400159131 /* console.cpp */; }; DF841FDD0E7BA61800F5680E /* iphone_keyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = DF841FD90E7BA61800F5680E /* iphone_keyboard.m */; }; DF841FDE0E7BA61800F5680E /* iphone_video.m in Sources */ = {isa = PBXBuildFile; fileRef = DF841FDB0E7BA61800F5680E /* iphone_video.m */; }; DF84250A0E7BA6AC00F5680E /* agi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FF70E7BA6A600F5680E /* agi.cpp */; }; @@ -1881,11 +1904,8 @@ DF89C2880F62D55C00D756B6 /* sprites_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF89C2870F62D55C00D756B6 /* sprites_lol.cpp */; }; DF89C2A40F62D79E00D756B6 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF89C2A30F62D79E00D756B6 /* script.cpp */; }; DF89C2BB0F62D91000D756B6 /* timestamp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF89C2B80F62D91000D756B6 /* timestamp.cpp */; }; - DF90E9BE10AEDA9B00C8F93F /* kernel32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90E9BC10AEDA9B00C8F93F /* kernel32.cpp */; }; DF90E9BF10AEDA9B00C8F93F /* selector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90E9BD10AEDA9B00C8F93F /* selector.cpp */; }; - DF90E9C010AEDA9B00C8F93F /* kernel32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90E9BC10AEDA9B00C8F93F /* kernel32.cpp */; }; DF90E9C110AEDA9B00C8F93F /* selector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90E9BD10AEDA9B00C8F93F /* selector.cpp */; }; - DF90E9C210AEDA9B00C8F93F /* kernel32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90E9BC10AEDA9B00C8F93F /* kernel32.cpp */; }; DF90E9C310AEDA9B00C8F93F /* selector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90E9BD10AEDA9B00C8F93F /* selector.cpp */; }; DF90EAA410B0234300C8F93F /* draw_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90EAA310B0234300C8F93F /* draw_playtoons.cpp */; }; DF90EAA510B0234300C8F93F /* draw_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90EAA310B0234300C8F93F /* draw_playtoons.cpp */; }; @@ -1941,7 +1961,6 @@ DFB0579911B7549C0015AE65 /* cinepak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0579611B7549C0015AE65 /* cinepak.cpp */; }; DFB0579A11B7549C0015AE65 /* cinepak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0579611B7549C0015AE65 /* cinepak.cpp */; }; DFC831210F48AF19005EF03C /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301A0F48AF18005EF03C /* detection.cpp */; }; - DFC831230F48AF19005EF03C /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301D0F48AF18005EF03C /* game.cpp */; }; DFC831240F48AF19005EF03C /* gc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301E0F48AF18005EF03C /* gc.cpp */; }; DFC831270F48AF19005EF03C /* kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830230F48AF18005EF03C /* kernel.cpp */; }; DFC831280F48AF19005EF03C /* kevent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830260F48AF18005EF03C /* kevent.cpp */; }; @@ -2868,7 +2887,6 @@ DFF95C560FB22D5700A3EC78 /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0D0F4870E50006E566 /* staticres.cpp */; }; DFF95C570FB22D5700A3EC78 /* tucker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0E0F4870E50006E566 /* tucker.cpp */; }; DFF95C580FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301A0F48AF18005EF03C /* detection.cpp */; }; - DFF95C590FB22D5700A3EC78 /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301D0F48AF18005EF03C /* game.cpp */; }; DFF95C5A0FB22D5700A3EC78 /* gc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301E0F48AF18005EF03C /* gc.cpp */; }; DFF95C5C0FB22D5700A3EC78 /* kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830230F48AF18005EF03C /* kernel.cpp */; }; DFF95C5D0FB22D5700A3EC78 /* kevent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830260F48AF18005EF03C /* kevent.cpp */; }; @@ -3125,9 +3143,6 @@ DF45B182116628A5009B85CC /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = "<group>"; }; DF45B183116628A5009B85CC /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = "<group>"; }; DF45B185116628A5009B85CC /* frameout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = frameout.h; sourceTree = "<group>"; }; - DF45B186116628A5009B85CC /* gui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui.cpp; sourceTree = "<group>"; }; - DF45B187116628A5009B85CC /* gui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui.h; sourceTree = "<group>"; }; - DF45B189116628A5009B85CC /* gui32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui32.h; sourceTree = "<group>"; }; DF45B18A116628A5009B85CC /* helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = helpers.h; sourceTree = "<group>"; }; DF45B18B116628A5009B85CC /* menu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menu.cpp; sourceTree = "<group>"; }; DF45B18C116628A5009B85CC /* menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = menu.h; sourceTree = "<group>"; }; @@ -3162,19 +3177,11 @@ DF45B1AC116628A5009B85CC /* audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audio.cpp; sourceTree = "<group>"; }; DF45B1AD116628A5009B85CC /* audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = "<group>"; }; DF45B1AF116628A5009B85CC /* adlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adlib.cpp; sourceTree = "<group>"; }; - DF45B1B0116628A5009B85CC /* amiga.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = amiga.cpp; sourceTree = "<group>"; }; DF45B1B1116628A5009B85CC /* fb01.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fb01.cpp; sourceTree = "<group>"; }; DF45B1B2116628A5009B85CC /* map-mt32-to-gm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "map-mt32-to-gm.h"; sourceTree = "<group>"; }; DF45B1B3116628A5009B85CC /* midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi.cpp; sourceTree = "<group>"; }; DF45B1B4116628A5009B85CC /* mididriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mididriver.h; sourceTree = "<group>"; }; DF45B1B5116628A5009B85CC /* pcjr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pcjr.cpp; sourceTree = "<group>"; }; - DF45B1B7116628A5009B85CC /* core.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = core.cpp; sourceTree = "<group>"; }; - DF45B1B8116628A5009B85CC /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = core.h; sourceTree = "<group>"; }; - DF45B1B9116628A5009B85CC /* iterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iterator.cpp; sourceTree = "<group>"; }; - DF45B1BA116628A5009B85CC /* iterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iterator.h; sourceTree = "<group>"; }; - DF45B1BB116628A5009B85CC /* iterator_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iterator_internal.h; sourceTree = "<group>"; }; - DF45B1BC116628A5009B85CC /* songlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = songlib.cpp; sourceTree = "<group>"; }; - DF45B1BD116628A5009B85CC /* songlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = songlib.h; sourceTree = "<group>"; }; DF45B1BF116628A5009B85CC /* midiparser_sci.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midiparser_sci.cpp; sourceTree = "<group>"; }; DF45B1C0116628A5009B85CC /* midiparser_sci.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = midiparser_sci.h; sourceTree = "<group>"; }; DF45B1C1116628A5009B85CC /* music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = music.cpp; sourceTree = "<group>"; }; @@ -3308,6 +3315,29 @@ DF7E8C510ED60067001CB19F /* game.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game.cpp; sourceTree = "<group>"; }; DF7E8C520ED60067001CB19F /* game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = game.h; sourceTree = "<group>"; }; DF7E8C7A0ED601E5001CB19F /* scummmodern.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = scummmodern.zip; sourceTree = "<group>"; }; + DF7F285C11FF23B700159131 /* frameout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = frameout.cpp; sourceTree = "<group>"; }; + DF7F286011FF23D500159131 /* amigamac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = amigamac.cpp; sourceTree = "<group>"; }; + DF7F286411FF23EF00159131 /* kvideo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kvideo.cpp; sourceTree = "<group>"; }; + DF7F286511FF23EF00159131 /* workarounds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = workarounds.cpp; sourceTree = "<group>"; }; + DF7F286611FF23EF00159131 /* workarounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = workarounds.h; sourceTree = "<group>"; }; + DF7F286F11FF243A00159131 /* detection_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detection_tables.h; sourceTree = "<group>"; }; + DF7F287011FF243A00159131 /* sound_2gs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_2gs.cpp; sourceTree = "<group>"; }; + DF7F287111FF243A00159131 /* sound_2gs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_2gs.h; sourceTree = "<group>"; }; + DF7F287211FF243B00159131 /* sound_coco3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_coco3.cpp; sourceTree = "<group>"; }; + DF7F287311FF243B00159131 /* sound_coco3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_coco3.h; sourceTree = "<group>"; }; + DF7F287411FF243B00159131 /* sound_midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_midi.cpp; sourceTree = "<group>"; }; + DF7F287511FF243B00159131 /* sound_midi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_midi.h; sourceTree = "<group>"; }; + DF7F287611FF243B00159131 /* sound_pcjr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_pcjr.cpp; sourceTree = "<group>"; }; + DF7F287711FF243B00159131 /* sound_pcjr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_pcjr.h; sourceTree = "<group>"; }; + DF7F287811FF243B00159131 /* sound_sarien.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_sarien.cpp; sourceTree = "<group>"; }; + DF7F287911FF243B00159131 /* sound_sarien.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_sarien.h; sourceTree = "<group>"; }; + DF7F288911FF244F00159131 /* Tooltip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tooltip.cpp; sourceTree = "<group>"; }; + DF7F288A11FF244F00159131 /* Tooltip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tooltip.h; sourceTree = "<group>"; }; + DF7F289111FF247300159131 /* translation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = translation.cpp; sourceTree = "<group>"; }; + DF7F289E11FF24B000159131 /* mac_snd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mac_snd.cpp; sourceTree = "<group>"; }; + DF7F289F11FF24B000159131 /* mac_snd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mac_snd.h; sourceTree = "<group>"; }; + DF7F28A311FF24C400159131 /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; }; + DF7F28A411FF24C400159131 /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; }; DF841FD90E7BA61800F5680E /* iphone_keyboard.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = iphone_keyboard.m; sourceTree = "<group>"; }; DF841FDA0E7BA61800F5680E /* iphone_video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iphone_video.h; sourceTree = "<group>"; }; DF841FDB0E7BA61800F5680E /* iphone_video.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = iphone_video.m; sourceTree = "<group>"; }; @@ -4358,7 +4388,6 @@ DF89C2B80F62D91000D756B6 /* timestamp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timestamp.cpp; sourceTree = "<group>"; }; DF89C2B90F62D91000D756B6 /* timestamp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timestamp.h; sourceTree = "<group>"; }; DF90E9B410AEDA5300C8F93F /* detection_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detection_tables.h; sourceTree = "<group>"; }; - DF90E9BC10AEDA9B00C8F93F /* kernel32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kernel32.cpp; sourceTree = "<group>"; }; DF90E9BD10AEDA9B00C8F93F /* selector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = selector.cpp; sourceTree = "<group>"; }; DF90EAA310B0234300C8F93F /* draw_playtoons.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_playtoons.cpp; sourceTree = "<group>"; }; DF90EAAB10B0236F00C8F93F /* staticres.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = staticres.cpp; sourceTree = "<group>"; }; @@ -4399,11 +4428,9 @@ DFB0579611B7549C0015AE65 /* cinepak.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cinepak.cpp; sourceTree = "<group>"; }; DFB0579711B7549C0015AE65 /* cinepak.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cinepak.h; sourceTree = "<group>"; }; DFC8301A0F48AF18005EF03C /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; }; - DFC8301D0F48AF18005EF03C /* game.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game.cpp; sourceTree = "<group>"; }; DFC8301E0F48AF18005EF03C /* gc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gc.cpp; sourceTree = "<group>"; }; DFC8301F0F48AF18005EF03C /* gc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gc.h; sourceTree = "<group>"; }; DFC830230F48AF18005EF03C /* kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kernel.cpp; sourceTree = "<group>"; }; - DFC830250F48AF18005EF03C /* kernel_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kernel_types.h; sourceTree = "<group>"; }; DFC830260F48AF18005EF03C /* kevent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kevent.cpp; sourceTree = "<group>"; }; DFC830270F48AF18005EF03C /* kfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kfile.cpp; sourceTree = "<group>"; }; DFC830280F48AF18005EF03C /* kgraphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kgraphics.cpp; sourceTree = "<group>"; }; @@ -4444,9 +4471,7 @@ DFD518AA0DF34BA600854012 /* 2xsai.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 2xsai.cpp; sourceTree = "<group>"; }; DFD518AB0DF34BA600854012 /* aspect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aspect.cpp; sourceTree = "<group>"; }; DFD518AD0DF34BA600854012 /* hq2x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hq2x.cpp; sourceTree = "<group>"; }; - DFD518AE0DF34BA600854012 /* hq2x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hq2x.h; sourceTree = "<group>"; }; DFD518B10DF34BA600854012 /* hq3x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hq3x.cpp; sourceTree = "<group>"; }; - DFD518B20DF34BA600854012 /* hq3x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hq3x.h; sourceTree = "<group>"; }; DFD518B50DF34BA600854012 /* scale2x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scale2x.cpp; sourceTree = "<group>"; }; DFD518B60DF34BA600854012 /* scale2x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scale2x.h; sourceTree = "<group>"; }; DFD518B80DF34BA600854012 /* scale3x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scale3x.cpp; sourceTree = "<group>"; }; @@ -4550,7 +4575,7 @@ DFE4778A0D81F4E900B6D1FB /* about.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = about.h; sourceTree = "<group>"; }; DFE4778B0D81F4E900B6D1FB /* Actions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Actions.cpp; sourceTree = "<group>"; }; DFE4778C0D81F4E900B6D1FB /* Actions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Actions.h; sourceTree = "<group>"; }; - DFE4778D0D81F4E900B6D1FB /* browser.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = browser.cpp; sourceTree = "<group>"; }; + DFE4778D0D81F4E900B6D1FB /* browser.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = browser.cpp; sourceTree = "<group>"; }; DFE4778E0D81F4E900B6D1FB /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = "<group>"; }; DFE4778F0D81F4E900B6D1FB /* chooser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chooser.cpp; sourceTree = "<group>"; }; DFE477900D81F4E900B6D1FB /* chooser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chooser.h; sourceTree = "<group>"; }; @@ -4901,6 +4926,8 @@ DF45B0EB116627D9009B85CC /* decoders */ = { isa = PBXGroup; children = ( + DF7F289E11FF24B000159131 /* mac_snd.cpp */, + DF7F289F11FF24B000159131 /* mac_snd.h */, DF45B0F7116627DA009B85CC /* adpcm.cpp */, DF45B0F8116627DA009B85CC /* adpcm.h */, DF45B0FA116627DA009B85CC /* aiff.cpp */, @@ -4928,6 +4955,7 @@ DF45B175116628A5009B85CC /* graphics */ = { isa = PBXGroup; children = ( + DF7F285C11FF23B700159131 /* frameout.cpp */, DFB0578811B754570015AE65 /* maciconbar.cpp */, DFB0578911B754570015AE65 /* maciconbar.h */, DF9B924F118E46A00069C19D /* fontsjis.cpp */, @@ -4947,9 +4975,6 @@ DF45B182116628A5009B85CC /* font.cpp */, DF45B183116628A5009B85CC /* font.h */, DF45B185116628A5009B85CC /* frameout.h */, - DF45B186116628A5009B85CC /* gui.cpp */, - DF45B187116628A5009B85CC /* gui.h */, - DF45B189116628A5009B85CC /* gui32.h */, DF45B18A116628A5009B85CC /* helpers.h */, DF45B18B116628A5009B85CC /* menu.cpp */, DF45B18C116628A5009B85CC /* menu.h */, @@ -5012,8 +5037,8 @@ DF45B1AE116628A5009B85CC /* drivers */ = { isa = PBXGroup; children = ( + DF7F286011FF23D500159131 /* amigamac.cpp */, DF45B1AF116628A5009B85CC /* adlib.cpp */, - DF45B1B0116628A5009B85CC /* amiga.cpp */, DF45B1B1116628A5009B85CC /* fb01.cpp */, DF45B1B2116628A5009B85CC /* map-mt32-to-gm.h */, DF45B1B3116628A5009B85CC /* midi.cpp */, @@ -5026,13 +5051,6 @@ DF45B1B6116628A5009B85CC /* iterator */ = { isa = PBXGroup; children = ( - DF45B1B7116628A5009B85CC /* core.cpp */, - DF45B1B8116628A5009B85CC /* core.h */, - DF45B1B9116628A5009B85CC /* iterator.cpp */, - DF45B1BA116628A5009B85CC /* iterator.h */, - DF45B1BB116628A5009B85CC /* iterator_internal.h */, - DF45B1BC116628A5009B85CC /* songlib.cpp */, - DF45B1BD116628A5009B85CC /* songlib.h */, ); path = iterator; sourceTree = "<group>"; @@ -5128,6 +5146,17 @@ DF841FF60E7BA6A600F5680E /* agi */ = { isa = PBXGroup; children = ( + DF7F286F11FF243A00159131 /* detection_tables.h */, + DF7F287011FF243A00159131 /* sound_2gs.cpp */, + DF7F287111FF243A00159131 /* sound_2gs.h */, + DF7F287211FF243B00159131 /* sound_coco3.cpp */, + DF7F287311FF243B00159131 /* sound_coco3.h */, + DF7F287411FF243B00159131 /* sound_midi.cpp */, + DF7F287511FF243B00159131 /* sound_midi.h */, + DF7F287611FF243B00159131 /* sound_pcjr.cpp */, + DF7F287711FF243B00159131 /* sound_pcjr.h */, + DF7F287811FF243B00159131 /* sound_sarien.cpp */, + DF7F287911FF243B00159131 /* sound_sarien.h */, DF841FF70E7BA6A600F5680E /* agi.cpp */, DF841FF80E7BA6A600F5680E /* agi.h */, DF841FF90E7BA6A600F5680E /* checks.cpp */, @@ -5366,6 +5395,8 @@ DF8421040E7BA6A700F5680E /* drascula */ = { isa = PBXGroup; children = ( + DF7F28A311FF24C400159131 /* console.cpp */, + DF7F28A411FF24C400159131 /* console.h */, DFCDC6F611662AAB00A7D2A0 /* resource.cpp */, DF8421050E7BA6A700F5680E /* actors.cpp */, DF8421060E7BA6A700F5680E /* animation.cpp */, @@ -6490,11 +6521,13 @@ DFC8301B0F48AF18005EF03C /* engine */ = { isa = PBXGroup; children = ( + DF7F286411FF23EF00159131 /* kvideo.cpp */, + DF7F286511FF23EF00159131 /* workarounds.cpp */, + DF7F286611FF23EF00159131 /* workarounds.h */, DFCDC6D5116629CE00A7D2A0 /* features.cpp */, DFCDC6D6116629CE00A7D2A0 /* features.h */, DFCDC6D7116629CE00A7D2A0 /* kparse.cpp */, DFCDC6D8116629CE00A7D2A0 /* selector.h */, - DF90E9BC10AEDA9B00C8F93F /* kernel32.cpp */, DF90E9BD10AEDA9B00C8F93F /* selector.cpp */, DF7585F6100CB75800CC3324 /* static_selectors.cpp */, DF6118380FE3A8080042AD3F /* kmisc.cpp */, @@ -6509,11 +6542,9 @@ DF573C020F5A81EA00961A72 /* state.h */, DF573C030F5A81EA00961A72 /* vm.h */, DF573C040F5A81EA00961A72 /* vm_types.h */, - DFC8301D0F48AF18005EF03C /* game.cpp */, DFC8301E0F48AF18005EF03C /* gc.cpp */, DFC8301F0F48AF18005EF03C /* gc.h */, DFC830230F48AF18005EF03C /* kernel.cpp */, - DFC830250F48AF18005EF03C /* kernel_types.h */, DFC830260F48AF18005EF03C /* kevent.cpp */, DFC830270F48AF18005EF03C /* kfile.cpp */, DFC830280F48AF18005EF03C /* kgraphics.cpp */, @@ -6542,9 +6573,7 @@ DFD518AA0DF34BA600854012 /* 2xsai.cpp */, DFD518AB0DF34BA600854012 /* aspect.cpp */, DFD518AD0DF34BA600854012 /* hq2x.cpp */, - DFD518AE0DF34BA600854012 /* hq2x.h */, DFD518B10DF34BA600854012 /* hq3x.cpp */, - DFD518B20DF34BA600854012 /* hq3x.h */, DFD518B50DF34BA600854012 /* scale2x.cpp */, DFD518B60DF34BA600854012 /* scale2x.h */, DFD518B80DF34BA600854012 /* scale3x.cpp */, @@ -6736,6 +6765,7 @@ DFE473950D81F4E800B6D1FB /* common */ = { isa = PBXGroup; children = ( + DF7F289111FF247300159131 /* translation.cpp */, DFB0577311B753DA0015AE65 /* debug-channels.h */, DFB0577411B753DA0015AE65 /* rational.cpp */, DFB0577511B753DA0015AE65 /* rational.h */, @@ -6877,6 +6907,8 @@ DFE477880D81F4E900B6D1FB /* gui */ = { isa = PBXGroup; children = ( + DF7F288911FF244F00159131 /* Tooltip.cpp */, + DF7F288A11FF244F00159131 /* Tooltip.h */, DF9B9246118E46730069C19D /* error.cpp */, DF9B9247118E46730069C19D /* error.h */, DF2EC3E410E6490800765801 /* browser_osx.mm */, @@ -7937,7 +7969,6 @@ DF2FFD170F4870E50006E566 /* staticres.cpp in Sources */, DF2FFD180F4870E50006E566 /* tucker.cpp in Sources */, DFC831210F48AF19005EF03C /* detection.cpp in Sources */, - DFC831230F48AF19005EF03C /* game.cpp in Sources */, DFC831240F48AF19005EF03C /* gc.cpp in Sources */, DFC831270F48AF19005EF03C /* kernel.cpp in Sources */, DFC831280F48AF19005EF03C /* kevent.cpp in Sources */, @@ -8035,7 +8066,6 @@ DF6BF4FF10529F140069811F /* EventRecorder.cpp in Sources */, DF6BF50810529F540069811F /* maxtrax.cpp in Sources */, DF6BF50910529F540069811F /* tfmx.cpp in Sources */, - DF90E9C210AEDA9B00C8F93F /* kernel32.cpp in Sources */, DF90E9C310AEDA9B00C8F93F /* selector.cpp in Sources */, DF90EAA610B0234300C8F93F /* draw_playtoons.cpp in Sources */, DF90EAAF10B0236F00C8F93F /* staticres.cpp in Sources */, @@ -8066,7 +8096,6 @@ DF45B1CE116628A5009B85CC /* coordadjuster.cpp in Sources */, DF45B1CF116628A5009B85CC /* cursor.cpp in Sources */, DF45B1D0116628A5009B85CC /* font.cpp in Sources */, - DF45B1D2116628A5009B85CC /* gui.cpp in Sources */, DF45B1D4116628A5009B85CC /* menu.cpp in Sources */, DF45B1D5116628A5009B85CC /* paint.cpp in Sources */, DF45B1D6116628A5009B85CC /* paint16.cpp in Sources */, @@ -8085,13 +8114,9 @@ DF45B1E4116628A5009B85CC /* vocabulary.cpp in Sources */, DF45B1E5116628A5009B85CC /* audio.cpp in Sources */, DF45B1E6116628A5009B85CC /* adlib.cpp in Sources */, - DF45B1E7116628A5009B85CC /* amiga.cpp in Sources */, DF45B1E8116628A5009B85CC /* fb01.cpp in Sources */, DF45B1E9116628A5009B85CC /* midi.cpp in Sources */, DF45B1EA116628A5009B85CC /* pcjr.cpp in Sources */, - DF45B1EB116628A5009B85CC /* core.cpp in Sources */, - DF45B1EC116628A5009B85CC /* iterator.cpp in Sources */, - DF45B1ED116628A5009B85CC /* songlib.cpp in Sources */, DF45B1EF116628A5009B85CC /* midiparser_sci.cpp in Sources */, DF45B1F0116628A5009B85CC /* music.cpp in Sources */, DF45B1F1116628A5009B85CC /* soundcmd.cpp in Sources */, @@ -8119,6 +8144,19 @@ DFB0578B11B754570015AE65 /* maciconbar.cpp in Sources */, DFB0579211B7547D0015AE65 /* pict.cpp in Sources */, DFB0579911B7549C0015AE65 /* cinepak.cpp in Sources */, + DF7F285E11FF23B700159131 /* frameout.cpp in Sources */, + DF7F286211FF23D500159131 /* amigamac.cpp in Sources */, + DF7F286911FF23EF00159131 /* kvideo.cpp in Sources */, + DF7F286A11FF23EF00159131 /* workarounds.cpp in Sources */, + DF7F287F11FF243B00159131 /* sound_2gs.cpp in Sources */, + DF7F288011FF243B00159131 /* sound_coco3.cpp in Sources */, + DF7F288111FF243B00159131 /* sound_midi.cpp in Sources */, + DF7F288211FF243B00159131 /* sound_pcjr.cpp in Sources */, + DF7F288311FF243B00159131 /* sound_sarien.cpp in Sources */, + DF7F288C11FF244F00159131 /* Tooltip.cpp in Sources */, + DF7F289511FF247300159131 /* translation.cpp in Sources */, + DF7F28A111FF24B000159131 /* mac_snd.cpp in Sources */, + DF7F28A611FF24C400159131 /* console.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -8892,7 +8930,6 @@ DF0941C20F63CB26002D821E /* staticres.cpp in Sources */, DF0941C30F63CB26002D821E /* tucker.cpp in Sources */, DF0941C40F63CB26002D821E /* detection.cpp in Sources */, - DF0941C50F63CB26002D821E /* game.cpp in Sources */, DF0941C60F63CB26002D821E /* gc.cpp in Sources */, DF0941C80F63CB26002D821E /* kernel.cpp in Sources */, DF0941C90F63CB26002D821E /* kevent.cpp in Sources */, @@ -8993,7 +9030,6 @@ DF6BF50110529F140069811F /* EventRecorder.cpp in Sources */, DF6BF50A10529F540069811F /* maxtrax.cpp in Sources */, DF6BF50B10529F540069811F /* tfmx.cpp in Sources */, - DF90E9BE10AEDA9B00C8F93F /* kernel32.cpp in Sources */, DF90E9BF10AEDA9B00C8F93F /* selector.cpp in Sources */, DF90EAA410B0234300C8F93F /* draw_playtoons.cpp in Sources */, DF90EAAD10B0236F00C8F93F /* staticres.cpp in Sources */, @@ -9025,7 +9061,6 @@ DF45B1F8116628A5009B85CC /* coordadjuster.cpp in Sources */, DF45B1F9116628A5009B85CC /* cursor.cpp in Sources */, DF45B1FA116628A5009B85CC /* font.cpp in Sources */, - DF45B1FC116628A5009B85CC /* gui.cpp in Sources */, DF45B1FE116628A5009B85CC /* menu.cpp in Sources */, DF45B1FF116628A5009B85CC /* paint.cpp in Sources */, DF45B200116628A5009B85CC /* paint16.cpp in Sources */, @@ -9044,13 +9079,9 @@ DF45B20E116628A5009B85CC /* vocabulary.cpp in Sources */, DF45B20F116628A5009B85CC /* audio.cpp in Sources */, DF45B210116628A5009B85CC /* adlib.cpp in Sources */, - DF45B211116628A5009B85CC /* amiga.cpp in Sources */, DF45B212116628A5009B85CC /* fb01.cpp in Sources */, DF45B213116628A5009B85CC /* midi.cpp in Sources */, DF45B214116628A5009B85CC /* pcjr.cpp in Sources */, - DF45B215116628A5009B85CC /* core.cpp in Sources */, - DF45B216116628A5009B85CC /* iterator.cpp in Sources */, - DF45B217116628A5009B85CC /* songlib.cpp in Sources */, DF45B219116628A5009B85CC /* midiparser_sci.cpp in Sources */, DF45B21A116628A5009B85CC /* music.cpp in Sources */, DF45B21B116628A5009B85CC /* soundcmd.cpp in Sources */, @@ -9078,6 +9109,19 @@ DFB0578C11B754570015AE65 /* maciconbar.cpp in Sources */, DFB0579311B7547D0015AE65 /* pict.cpp in Sources */, DFB0579A11B7549C0015AE65 /* cinepak.cpp in Sources */, + DF7F285F11FF23B700159131 /* frameout.cpp in Sources */, + DF7F286311FF23D500159131 /* amigamac.cpp in Sources */, + DF7F286B11FF23EF00159131 /* kvideo.cpp in Sources */, + DF7F286C11FF23EF00159131 /* workarounds.cpp in Sources */, + DF7F288411FF243B00159131 /* sound_2gs.cpp in Sources */, + DF7F288511FF243B00159131 /* sound_coco3.cpp in Sources */, + DF7F288611FF243B00159131 /* sound_midi.cpp in Sources */, + DF7F288711FF243B00159131 /* sound_pcjr.cpp in Sources */, + DF7F288811FF243B00159131 /* sound_sarien.cpp in Sources */, + DF7F288D11FF244F00159131 /* Tooltip.cpp in Sources */, + DF7F289711FF247300159131 /* translation.cpp in Sources */, + DF7F28A211FF24B000159131 /* mac_snd.cpp in Sources */, + DF7F28A711FF24C400159131 /* console.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9856,7 +9900,6 @@ DFF95C560FB22D5700A3EC78 /* staticres.cpp in Sources */, DFF95C570FB22D5700A3EC78 /* tucker.cpp in Sources */, DFF95C580FB22D5700A3EC78 /* detection.cpp in Sources */, - DFF95C590FB22D5700A3EC78 /* game.cpp in Sources */, DFF95C5A0FB22D5700A3EC78 /* gc.cpp in Sources */, DFF95C5C0FB22D5700A3EC78 /* kernel.cpp in Sources */, DFF95C5D0FB22D5700A3EC78 /* kevent.cpp in Sources */, @@ -9954,7 +9997,6 @@ DF6BF4FD10529F140069811F /* EventRecorder.cpp in Sources */, DF6BF50610529F540069811F /* maxtrax.cpp in Sources */, DF6BF50710529F540069811F /* tfmx.cpp in Sources */, - DF90E9C010AEDA9B00C8F93F /* kernel32.cpp in Sources */, DF90E9C110AEDA9B00C8F93F /* selector.cpp in Sources */, DF90EAA510B0234300C8F93F /* draw_playtoons.cpp in Sources */, DF90EAAE10B0236F00C8F93F /* staticres.cpp in Sources */, @@ -9985,7 +10027,6 @@ DF45B222116628A5009B85CC /* coordadjuster.cpp in Sources */, DF45B223116628A5009B85CC /* cursor.cpp in Sources */, DF45B224116628A5009B85CC /* font.cpp in Sources */, - DF45B226116628A5009B85CC /* gui.cpp in Sources */, DF45B228116628A5009B85CC /* menu.cpp in Sources */, DF45B229116628A5009B85CC /* paint.cpp in Sources */, DF45B22A116628A5009B85CC /* paint16.cpp in Sources */, @@ -10004,13 +10045,9 @@ DF45B238116628A5009B85CC /* vocabulary.cpp in Sources */, DF45B239116628A5009B85CC /* audio.cpp in Sources */, DF45B23A116628A5009B85CC /* adlib.cpp in Sources */, - DF45B23B116628A5009B85CC /* amiga.cpp in Sources */, DF45B23C116628A5009B85CC /* fb01.cpp in Sources */, DF45B23D116628A5009B85CC /* midi.cpp in Sources */, DF45B23E116628A5009B85CC /* pcjr.cpp in Sources */, - DF45B23F116628A5009B85CC /* core.cpp in Sources */, - DF45B240116628A5009B85CC /* iterator.cpp in Sources */, - DF45B241116628A5009B85CC /* songlib.cpp in Sources */, DF45B243116628A5009B85CC /* midiparser_sci.cpp in Sources */, DF45B244116628A5009B85CC /* music.cpp in Sources */, DF45B245116628A5009B85CC /* soundcmd.cpp in Sources */, @@ -10038,6 +10075,19 @@ DFB0578A11B754570015AE65 /* maciconbar.cpp in Sources */, DFB0579111B7547D0015AE65 /* pict.cpp in Sources */, DFB0579811B7549C0015AE65 /* cinepak.cpp in Sources */, + DF7F285D11FF23B700159131 /* frameout.cpp in Sources */, + DF7F286111FF23D500159131 /* amigamac.cpp in Sources */, + DF7F286711FF23EF00159131 /* kvideo.cpp in Sources */, + DF7F286811FF23EF00159131 /* workarounds.cpp in Sources */, + DF7F287A11FF243B00159131 /* sound_2gs.cpp in Sources */, + DF7F287B11FF243B00159131 /* sound_coco3.cpp in Sources */, + DF7F287C11FF243B00159131 /* sound_midi.cpp in Sources */, + DF7F287D11FF243B00159131 /* sound_pcjr.cpp in Sources */, + DF7F287E11FF243B00159131 /* sound_sarien.cpp in Sources */, + DF7F288B11FF244F00159131 /* Tooltip.cpp in Sources */, + DF7F289311FF247300159131 /* translation.cpp in Sources */, + DF7F28A011FF24B000159131 /* mac_snd.cpp in Sources */, + DF7F28A511FF24C400159131 /* console.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -10181,6 +10231,7 @@ SCUMM_LITTLE_ENDIAN, UNIX, IPHONE, + ENABLE_SCI32, ENABLE_HE, ); GCC_THUMB_SUPPORT = NO; @@ -10198,7 +10249,8 @@ PREBINDING = NO; PROVISIONING_PROFILE = ""; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - SDKROOT = iphoneos3.0; + SDKROOT = iphonesimulator3.2; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -10210,6 +10262,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; FRAMEWORK_SEARCH_PATHS = ""; + GCC_C_LANGUAGE_STANDARD = c99; GCC_ENABLE_CPP_EXCEPTIONS = NO; GCC_ENABLE_CPP_RTTI = NO; GCC_INPUT_FILETYPE = automatic; @@ -10250,6 +10303,7 @@ SCUMM_LITTLE_ENDIAN, UNIX, IPHONE, + ENABLE_SCI32, ENABLE_HE, ); GCC_THUMB_SUPPORT = NO; @@ -10259,12 +10313,14 @@ ../../, ); LIBRARY_SEARCH_PATHS = ""; + ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ""; OTHER_LDFLAGS = "-lz"; PREBINDING = NO; PROVISIONING_PROFILE = ""; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - SDKROOT = iphoneos3.0; + SDKROOT = iphonesimulator3.2; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; @@ -10338,6 +10394,7 @@ "\\\"$(SRCROOT)/../../engines/m4\\\"", "\\\"$(SRCROOT)/lib\\\"", ); + ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-lSDLmain", @@ -10351,6 +10408,8 @@ ); PREBINDING = NO; PRODUCT_NAME = ScummVM; + SDKROOT = macosx10.6; + VALID_ARCHS = "i386 ppc ppc64 ppc7400 ppc970 x86_64 arm7 arm6"; }; name = Debug; }; @@ -10422,6 +10481,7 @@ "\\\"$(SRCROOT)/../../engines/m4\\\"", "\\\"$(SRCROOT)/lib\\\"", ); + ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-lSDLmain", @@ -10435,6 +10495,8 @@ ); PREBINDING = NO; PRODUCT_NAME = ScummVM; + SDKROOT = macosx10.6; + VALID_ARCHS = "i386 ppc ppc64 ppc7400 ppc970 x86_64 arm7 arm6"; WRAPPER_EXTENSION = app; }; name = Release; @@ -10454,43 +10516,13 @@ GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_PREFIX_HEADER = ""; - GCC_PREPROCESSOR_DEFINITIONS = ( - XCODE, - IPHONE_OFFICIAL, - USE_ZLIB, - SCUMMVM, - ENABLE_SCI, - ENABLE_TUCKER, - ENABLE_TOUCHE, - ENABLE_TINSEL, - ENABLE_SWORD2, - ENABLE_SWORD1, - ENABLE_SKY, - ENABLE_IHNM, - ENABLE_SAGA, - ENABLE_QUEEN, - ENABLE_PARALLACTION, - ENABLE_MADE, - ENABLE_LURE, - ENABLE_KYRA, - ENABLE_IGOR, - ENABLE_GROOVIE, - ENABLE_GOB, - ENABLE_DRASCULA, - ENABLE_CINE, - ENABLE_AGOS, - ENABLE_AGI, - ENABLE_SCUMM, - ENABLE_SCUMM_7_8, - CONFIG_H, - SCUMM_NEED_ALIGNMENT, - SCUMM_LITTLE_ENDIAN, - UNIX, - IPHONE, - ENABLE_HE, - ); GCC_THUMB_SUPPORT = NO; GCC_UNROLL_LOOPS = YES; + HEADER_SEARCH_PATHS = ( + ../../engines/, + ../../, + /opt/local/include, + ); INFOPLIST_FILE = "/Users/oystein/iphone/scummvm/dists/iphone/Info copy 2.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -10499,12 +10531,11 @@ "\\\"$(SRCROOT)/../../engines/m4\\\"", "\\\"$(SRCROOT)/lib\\\"", ); - ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; PRODUCT_NAME = ScummVM; PROVISIONING_PROFILE = "EF590570-5FAC-4346-9071-D609DE2B28D8"; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - SDKROOT = iphonesimulator2.0; + SDKROOT = iphonesimulator3.2; }; name = Debug; }; @@ -10522,43 +10553,13 @@ GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_PREFIX_HEADER = ""; - GCC_PREPROCESSOR_DEFINITIONS = ( - XCODE, - IPHONE_OFFICIAL, - USE_ZLIB, - SCUMMVM, - ENABLE_SCI, - ENABLE_TUCKER, - ENABLE_TOUCHE, - ENABLE_TINSEL, - ENABLE_SWORD2, - ENABLE_SWORD1, - ENABLE_SKY, - ENABLE_IHNM, - ENABLE_SAGA, - ENABLE_QUEEN, - ENABLE_PARALLACTION, - ENABLE_MADE, - ENABLE_LURE, - ENABLE_KYRA, - ENABLE_IGOR, - ENABLE_GROOVIE, - ENABLE_GOB, - ENABLE_DRASCULA, - ENABLE_CINE, - ENABLE_AGOS, - ENABLE_AGI, - ENABLE_SCUMM, - ENABLE_SCUMM_7_8, - CONFIG_H, - SCUMM_NEED_ALIGNMENT, - SCUMM_LITTLE_ENDIAN, - UNIX, - IPHONE, - ENABLE_HE, - ); GCC_THUMB_SUPPORT = NO; GCC_UNROLL_LOOPS = YES; + HEADER_SEARCH_PATHS = ( + ../../engines/, + ../../, + /opt/local/include, + ); INFOPLIST_FILE = "/Users/oystein/iphone/scummvm/dists/iphone/Info copy 2.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -10567,12 +10568,11 @@ "\\\"$(SRCROOT)/../../engines/m4\\\"", "\\\"$(SRCROOT)/lib\\\"", ); - ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; PRODUCT_NAME = ScummVM; PROVISIONING_PROFILE = "EF590570-5FAC-4346-9071-D609DE2B28D8"; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - SDKROOT = iphonesimulator2.0; + SDKROOT = iphonesimulator3.2; WRAPPER_EXTENSION = app; }; name = Release; diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp index 4a994b731a..e83ef4ead9 100644 --- a/engines/agi/agi.cpp +++ b/engines/agi/agi.cpp @@ -279,8 +279,7 @@ void AgiEngine::pollTimer() { while ((dm = _tickTimer - _lastTickTimer) < 5) { processEvents(); - if (_console->isAttached()) - _console->onFrame(); + _console->onFrame(); _system->delayMillis(10); _system->updateScreen(); } @@ -344,7 +343,7 @@ int AgiEngine::agiInit() { // clear view table for (i = 0; i < MAX_VIEWTABLE; i++) - memset(&_game.viewTable[i], 0, sizeof(VtEntry)); + memset(&_game.viewTable[i], 0, sizeof(struct VtEntry)); initWords(); @@ -580,7 +579,7 @@ void AgiEngine::initialize() { } else if (getPlatform() == Common::kPlatformCoCo3) { _soundemu = SOUND_EMU_COCO3; } else { - switch (MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK))) { + switch (MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK|MDT_ADLIB|MDT_PCJR|MDT_MIDI))) { case MT_PCSPK: _soundemu = SOUND_EMU_PC; break; @@ -610,6 +609,8 @@ void AgiEngine::initialize() { _renderMode = Common::kRenderEGA; break; } + } else { + _renderMode = Common::kRenderDefault; } _buttonStyle = AgiButtonStyle(_renderMode); diff --git a/engines/agi/console.cpp b/engines/agi/console.cpp index e881b092e3..e5942455e2 100644 --- a/engines/agi/console.cpp +++ b/engines/agi/console.cpp @@ -53,15 +53,6 @@ Console::Console(AgiEngine *vm) : GUI::Debugger() { DCmd_Register("bt", WRAP_METHOD(Console, Cmd_BT)); } -Console::~Console() { -} - -void Console::preEnter() { -} - -void Console::postEnter() { -} - bool Console::Cmd_SetVar(int argc, const char **argv) { if (argc != 3) { DebugPrintf("Usage: setvar <varnum> <value>\n"); diff --git a/engines/agi/console.h b/engines/agi/console.h index e8eccbe50a..e79db42054 100644 --- a/engines/agi/console.h +++ b/engines/agi/console.h @@ -46,11 +46,6 @@ struct AgiDebug { class Console : public GUI::Debugger { public: Console(AgiEngine *vm); - virtual ~Console(); - -protected: - virtual void preEnter(); - virtual void postEnter(); private: bool Cmd_SetVar(int argc, const char **argv); @@ -80,10 +75,6 @@ public: PreAGI_Console(PreAgiEngine *vm); virtual ~PreAGI_Console() {} -protected: - virtual void preEnter() {} - virtual void postEnter() {} - private: PreAgiEngine *_vm; }; @@ -94,10 +85,6 @@ public: Mickey_Console(PreAgiEngine *vm, Mickey *mickey); virtual ~Mickey_Console() {} -protected: - virtual void preEnter() {} - virtual void postEnter() {} - private: Mickey *_mickey; @@ -112,10 +99,6 @@ public: Winnie_Console(PreAgiEngine *vm, Winnie *winnie); virtual ~Winnie_Console() {} -protected: - virtual void preEnter() {} - virtual void postEnter() {} - private: Winnie *_winnie; diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp index c185c3efb3..b7eba22298 100644 --- a/engines/agi/cycle.cpp +++ b/engines/agi/cycle.cpp @@ -203,7 +203,7 @@ int AgiEngine::mainCycle() { // vars in every interpreter cycle. // // We run AGIMOUSE always as a side effect - if (getFeatures() & GF_AGIMOUSE || 1) { + if (getFeatures() & GF_AGIMOUSE || true) { _game.vars[28] = _mouse.x / 2; _game.vars[29] = _mouse.y; } @@ -318,7 +318,7 @@ int AgiEngine::playGame() { _game.lineUserInput = 22; // We run AGIMOUSE always as a side effect - if (getFeatures() & GF_AGIMOUSE || 1) + if (getFeatures() & GF_AGIMOUSE || true) report("Using AGI Mouse 1.0 protocol\n"); if (getFeatures() & GF_AGIPAL) diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp index 072ab0114f..a60080186c 100644 --- a/engines/agi/op_cmd.cpp +++ b/engines/agi/op_cmd.cpp @@ -1228,8 +1228,7 @@ void AgiEngine::cmd_quit(uint8 *p) { if (p0) { quitGame(); } else { - if (selectionBox - (" Quit the _game, or continue? \n\n\n", buttons) == 0) { + if (selectionBox(" Quit the game, or continue? \n\n\n", buttons) == 0) { quitGame(); } } @@ -1504,7 +1503,7 @@ void AgiEngine::cmd_print_at_v(uint8 *p) { void AgiEngine::cmd_push_script(uint8 *p) { // We run AGIMOUSE always as a side effect - if (getFeatures() & GF_AGIMOUSE || 1) { + if (getFeatures() & GF_AGIMOUSE || true) { _game.vars[27] = _mouse.button; _game.vars[28] = _mouse.x / 2; _game.vars[29] = _mouse.y; diff --git a/engines/agi/sprite.cpp b/engines/agi/sprite.cpp index 25118b69a6..569481d772 100644 --- a/engines/agi/sprite.cpp +++ b/engines/agi/sprite.cpp @@ -245,7 +245,7 @@ void SpritesMgr::objsRestoreArea(Sprite *s) { // WORKAROUND (see ScummVM bug #1945716) // When set.view command is called, current code cannot detect this situation while updating // Thus we force removal of the old sprite - if (s->v->viewReplaced) { + if (s->v && s->v->viewReplaced) { commitBlock(xPos, yPos, xPos + xSize, yPos + ySize); s->v->viewReplaced = false; } @@ -458,11 +458,11 @@ void SpritesMgr::blitSprites(SpriteList& l) { */ void SpritesMgr::commitUpdSprites() { - commitSprites(_sprUpd, true); + commitSprites(_sprUpd); } void SpritesMgr::commitNonupdSprites() { - commitSprites(_sprNonupd, true); + commitSprites(_sprNonupd); } // check moves in both lists @@ -679,6 +679,7 @@ void SpritesMgr::showObj(int n) { s.xSize = c->width; s.ySize = c->height; s.buffer = (uint8 *)malloc(s.xSize * s.ySize); + s.v = 0; objsSaveArea(&s); blitCel(x1, y1, 15, c, _vm->_game.views[n].agi256_2); diff --git a/engines/agi/view.cpp b/engines/agi/view.cpp index 45244bb292..fcca1e2a79 100644 --- a/engines/agi/view.cpp +++ b/engines/agi/view.cpp @@ -157,8 +157,7 @@ int AgiEngine::decodeView(int n) { return errNoLoopsInView; // allocate memory for all views - _game.views[n].loop = (ViewLoop *) - calloc(_game.views[n].numLoops, sizeof(ViewLoop)); + _game.views[n].loop = (ViewLoop *)calloc(_game.views[n].numLoops, sizeof(ViewLoop)); if (_game.views[n].loop == NULL) return errNotEnoughMemory; diff --git a/engines/agi/wagparser.cpp b/engines/agi/wagparser.cpp index 1d60524070..22de66712d 100644 --- a/engines/agi/wagparser.cpp +++ b/engines/agi/wagparser.cpp @@ -100,10 +100,8 @@ void WagProperty::setDefaults() { } void WagProperty::deleteData() { - if (_propData != NULL) { - delete _propData; - _propData = NULL; - } + delete _propData; + _propData = NULL; } WagFileParser::WagFileParser() : diff --git a/engines/agi/words.cpp b/engines/agi/words.cpp index c8b22956f4..464c218ae8 100644 --- a/engines/agi/words.cpp +++ b/engines/agi/words.cpp @@ -76,10 +76,8 @@ int AgiEngine::loadWords(const char *fname) { } void AgiEngine::unloadWords() { - if (words != NULL) { - free(words); - words = NULL; - } + free(words); + words = NULL; } /** diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 1b7802acb6..c5841ff05e 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -1038,12 +1038,21 @@ uint32 AGOSEngine::getTime() const { } void AGOSEngine::syncSoundSettings() { - _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); + // Sync the engine with the config manager + int soundVolumeMusic = ConfMan.getInt("music_volume"); + int soundVolumeSFX = ConfMan.getInt("sfx_volume"); + int soundVolumeSpeech = ConfMan.getInt("speech_volume"); + + bool mute = false; + if (ConfMan.hasKey("mute")) + mute = ConfMan.getBool("mute"); + + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, (mute ? 0 : (_musicPaused ? 0 : soundVolumeMusic))); + _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, (mute ? 0 : soundVolumeSFX)); + _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, (mute ? 0 : soundVolumeSpeech)); if (_midiEnabled) - _midi.setVolume(ConfMan.getInt("music_volume"), ConfMan.getInt("sfx_volume")); + _midi.setVolume((mute ? 0 : soundVolumeMusic), (mute ? 0 : soundVolumeSFX)); } } // End of namespace AGOS diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp index f3ec948f0f..32c26752a2 100644 --- a/engines/agos/event.cpp +++ b/engines/agos/event.cpp @@ -429,8 +429,7 @@ void AGOSEngine::delay(uint amount) { _system->getAudioCDManager()->updateCD(); - if (_debugger->isAttached()) - _debugger->onFrame(); + _debugger->onFrame(); vgaPeriod = (_fastMode) ? 10 : _vgaPeriod; if (getGameType() == GType_PP && getGameId() != GID_DIMP) { diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp index 5fc2a64416..1246149aa5 100644 --- a/engines/agos/input.cpp +++ b/engines/agos/input.cpp @@ -602,7 +602,7 @@ bool AGOSEngine::processSpecialKeys() { if (_midiEnabled) { _midi.pause(_musicPaused); } - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, (_musicPaused) ? 0 : ConfMan.getInt("music_volume")); + syncSoundSettings(); break; case 's': if (getGameId() == GID_SIMON1DOS) { diff --git a/engines/agos/midi.cpp b/engines/agos/midi.cpp index ed3e3d801b..ab5bfc4c94 100644 --- a/engines/agos/midi.cpp +++ b/engines/agos/midi.cpp @@ -346,15 +346,11 @@ void MidiPlayer::clearConstructs(MusicInfo &info) { info.num_songs = 0; } - if (info.data) { - free(info.data); - info.data = 0; - } // end if - - if (info.parser) { - delete info.parser; - info.parser = 0; - } + free(info.data); + info.data = 0; + + delete info.parser; + info.parser = 0; if (_driver) { for (i = 0; i < 16; ++i) { diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp index c50af52901..e6ac2859cf 100644 --- a/engines/cine/cine.cpp +++ b/engines/cine/cine.cpp @@ -48,10 +48,9 @@ namespace Cine { -Sound *g_sound; -Common::SaveFileManager *g_saveFileMan; +Sound *g_sound = 0; -CineEngine *g_cine; +CineEngine *g_cine = 0; CineEngine::CineEngine(OSystem *syst, const CINEGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) { DebugMan.addDebugChannel(kCineDebugScript, "Script", "Script debug level"); @@ -72,7 +71,7 @@ CineEngine::CineEngine(OSystem *syst, const CINEGameDescription *gameDesc) : Eng } CineEngine::~CineEngine() { - if (g_cine->getGameType() == Cine::GType_OS) { + if (getGameType() == Cine::GType_OS) { freeErrmessDat(); } DebugMan.clearAllDebugChannels(); @@ -82,13 +81,12 @@ Common::Error CineEngine::run() { // Initialize backend initGraphics(320, 200, false); - if (g_cine->getPlatform() == Common::kPlatformPC) { + if (getPlatform() == Common::kPlatformPC) { g_sound = new PCSound(_mixer, this); } else { // Paula chipset for Amiga and Atari versions g_sound = new PaulaSound(_mixer, this); } - g_saveFileMan = _saveFileMan; _restartRequested = false; @@ -147,9 +145,9 @@ void CineEngine::initialize() { _timerDelayMultiplier = 12; // Set default speed setupOpcodes(); - initLanguage(g_cine->getLanguage()); + initLanguage(getLanguage()); - if (g_cine->getGameType() == Cine::GType_OS) { + if (getGameType() == Cine::GType_OS) { renderer = new OSRenderer; } else { renderer = new FWRenderer; @@ -163,13 +161,13 @@ void CineEngine::initialize() { // Its size will change when loading data into it with the loadPart function. partBuffer.clear(); - if (g_cine->getGameType() == Cine::GType_OS) { + if (getGameType() == Cine::GType_OS) { readVolCnf(); } loadTextData("texte.dat"); - if (g_cine->getGameType() == Cine::GType_OS && !(g_cine->getFeatures() & GF_DEMO)) { + if (getGameType() == Cine::GType_OS && !(getFeatures() & GF_DEMO)) { loadPoldatDat("poldat.dat"); loadErrmessDat("errmess.dat"); } diff --git a/engines/cine/cine.h b/engines/cine/cine.h index 6f7b409ad7..6f2c2243e2 100644 --- a/engines/cine/cine.h +++ b/engines/cine/cine.h @@ -190,8 +190,6 @@ enum { }; -extern Common::SaveFileManager *g_saveFileMan; // TEMP - } // End of namespace Cine #endif diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp index b92ad8a0a2..9dfa2f71ea 100644 --- a/engines/cine/detection.cpp +++ b/engines/cine/detection.cpp @@ -251,7 +251,7 @@ Common::Error CineEngine::saveGameState(int slot, const char *desc) { char indexFile[80]; snprintf(indexFile, 80, "%s.dir", _targetName.c_str()); - Common::OutSaveFile *fHandle = g_saveFileMan->openForSaving(indexFile); + Common::OutSaveFile *fHandle = _saveFileMan->openForSaving(indexFile); if (!fHandle) { warning("Unable to open file %s for saving", indexFile); return Common::kUnknownError; diff --git a/engines/cine/saveload.cpp b/engines/cine/saveload.cpp index b5adebcd0b..f9dfcc7737 100644 --- a/engines/cine/saveload.cpp +++ b/engines/cine/saveload.cpp @@ -465,7 +465,7 @@ bool CineEngine::loadSaveDirectory() { char tmp[80]; snprintf(tmp, 80, "%s.dir", _targetName.c_str()); - fHandle = g_saveFileMan->openForLoading(tmp); + fHandle = _saveFileMan->openForLoading(tmp); if (!fHandle) { return false; @@ -771,7 +771,7 @@ bool CineEngine::loadPlainSaveFW(Common::SeekableReadStream &in, CineSaveGameFor } bool CineEngine::makeLoad(char *saveName) { - Common::SharedPtr<Common::InSaveFile> saveFile(g_saveFileMan->openForLoading(saveName)); + Common::SharedPtr<Common::InSaveFile> saveFile(_saveFileMan->openForLoading(saveName)); if (!saveFile) { renderer->drawString(otherMessages[0], 0); @@ -966,7 +966,7 @@ void CineEngine::makeSaveOS(Common::OutSaveFile &out) { } void CineEngine::makeSave(char *saveFileName) { - Common::SharedPtr<Common::OutSaveFile> fHandle(g_saveFileMan->openForSaving(saveFileName)); + Common::SharedPtr<Common::OutSaveFile> fHandle(_saveFileMan->openForSaving(saveFileName)); setMouseCursor(MOUSE_CURSOR_DISK); @@ -976,7 +976,7 @@ void CineEngine::makeSave(char *saveFileName) { // restoreScreen(); checkDataDisk(-1); } else { - if (g_cine->getGameType() == GType_FW) { + if (getGameType() == GType_FW) { makeSaveFW(*fHandle); } else { makeSaveOS(*fHandle); diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp index 9a10c2b5d7..82c40a2f50 100644 --- a/engines/cine/various.cpp +++ b/engines/cine/various.cpp @@ -450,7 +450,7 @@ void CineEngine::makeSystemMenu() { snprintf(tmp, 80, "%s.dir", _targetName.c_str()); - Common::OutSaveFile *fHandle = g_saveFileMan->openForSaving(tmp); + Common::OutSaveFile *fHandle = _saveFileMan->openForSaving(tmp); if (!fHandle) { warning("Unable to open file %s for saving", tmp); break; diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp index e6d0359059..2f38aa98ba 100644 --- a/engines/cruise/cruise.cpp +++ b/engines/cruise/cruise.cpp @@ -52,10 +52,6 @@ CruiseEngine *_vm; CruiseEngine::CruiseEngine(OSystem * syst, const CRUISEGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) { -#ifdef PALMOS_MODE - _currentVolumeFile = new Common::File(); -#endif - DebugMan.addDebugChannel(kCruiseDebugScript, "scripts", "Scripts debug level"); DebugMan.addDebugChannel(kCruiseDebugSound, "sound", "Sound debug level"); diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp index 14de916a84..65d8b57366 100644 --- a/engines/cruise/cruise_main.cpp +++ b/engines/cruise/cruise_main.cpp @@ -1833,19 +1833,17 @@ void CruiseEngine::mainLoop() { if (!skipEvents) skipEvents = manageEvents(); - if (playerDontAskQuit) break; + if (playerDontAskQuit) + break; - if (_vm->getDebugger()->isAttached()) - _vm->getDebugger()->onFrame(); + _vm->getDebugger()->onFrame(); } while (currentTick < lastTick + _gameSpeed); } else { manageEvents(); if (currentTick >= (lastTickDebug + 10)) { lastTickDebug = currentTick; - - if (_vm->getDebugger()->isAttached()) - _vm->getDebugger()->onFrame(); + _vm->getDebugger()->onFrame(); } } if (playerDontAskQuit) diff --git a/engines/cruise/vars.cpp b/engines/cruise/vars.cpp index 94fd00cbfd..bab5d171fd 100644 --- a/engines/cruise/vars.cpp +++ b/engines/cruise/vars.cpp @@ -64,11 +64,7 @@ int16 autoTrack; int16 currentDiskNumber = 1; -#ifdef PALMOS_MODE -Common::File *_currentVolumeFile; -#else Common::File currentVolumeFile; -#endif int16 volumeNumEntry; fileEntry *volumePtrToFileDescriptor = NULL; diff --git a/engines/cruise/vars.h b/engines/cruise/vars.h index 1e19794f3a..3cb09602cc 100644 --- a/engines/cruise/vars.h +++ b/engines/cruise/vars.h @@ -167,12 +167,7 @@ extern int16 autoTrack; extern int16 currentDiskNumber; -#ifdef PALMOS_MODE -extern Common::File *_currentVolumeFile; -#define currentVolumeFile (*_currentVolumeFile) -#else extern Common::File currentVolumeFile; -#endif extern int16 volumeNumEntry; extern fileEntry *volumePtrToFileDescriptor; diff --git a/engines/draci/module.mk b/engines/draci/module.mk index a172e4b939..1f80737135 100644 --- a/engines/draci/module.mk +++ b/engines/draci/module.mk @@ -17,9 +17,6 @@ MODULE_OBJS := \ surface.o \ walking.o -MODULE_DIRS += \ - engines/draci - # This module can be built as a plugin ifeq ($(ENABLE_DRACI), DYNAMIC_PLUGIN) PLUGIN := 1 diff --git a/engines/draci/walking.cpp b/engines/draci/walking.cpp index e57972fbc5..02612832d2 100644 --- a/engines/draci/walking.cpp +++ b/engines/draci/walking.cpp @@ -324,7 +324,7 @@ void WalkingMap::drawOverlayRectangle(const Common::Point &p, byte colour, byte } int WalkingMap::pointsBetween(const Common::Point &p1, const Common::Point &p2) { - return MAX(abs(p2.x - p1.x), abs(p2.y - p1.y)); + return MAX(ABS(p2.x - p1.x), ABS(p2.y - p1.y)); } Common::Point WalkingMap::interpolate(const Common::Point &p1, const Common::Point &p2, int i, int n) { @@ -636,7 +636,7 @@ bool WalkingState::walkOnNextEdge() { Movement WalkingState::animationForDirection(const Common::Point &here, const Common::Point &there) { const int dx = there.x - here.x; const int dy = there.y - here.y; - if (abs(dx) >= abs(dy)) { + if (ABS(dx) >= ABS(dy)) { return dx >= 0 ? kMoveRight : kMoveLeft; } else { return dy >= 0 ? kMoveDown : kMoveUp; diff --git a/engines/drascula/actors.cpp b/engines/drascula/actors.cpp index 33cb7fd478..8523b5b158 100644 --- a/engines/drascula/actors.cpp +++ b/engines/drascula/actors.cpp @@ -312,9 +312,9 @@ void DrasculaEngine::quadrant_2() { float distanceX, distanceY; if (currentChapter == 2) - distanceX = abs(curX + curWidth - roomX); + distanceX = ABS(curX + curWidth - roomX); else - distanceX = abs(curX + curWidth / 2 - roomX); + distanceX = ABS(curX + curWidth / 2 - roomX); distanceY = (curY + curHeight) - roomY; @@ -354,9 +354,9 @@ void DrasculaEngine::quadrant_4() { float distanceX, distanceY; if (currentChapter == 2) - distanceX = abs(curX + curWidth - roomX); + distanceX = ABS(curX + curWidth - roomX); else - distanceX = abs(curX + curWidth / 2 - roomX); + distanceX = ABS(curX + curWidth / 2 - roomX); distanceY = roomY - (curY + curHeight); diff --git a/engines/engine.cpp b/engines/engine.cpp index 3c85220931..627de87723 100644 --- a/engines/engine.cpp +++ b/engines/engine.cpp @@ -78,7 +78,7 @@ static void defaultErrorHandler(const char *msg) { if (isSmartphone()) debugger = 0; #endif - if (debugger && !debugger->isAttached()) { + if (debugger && !debugger->isActive()) { debugger->attach(msg); debugger->onFrame(); } diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 9c61bc1b75..03c0b1d991 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -126,8 +126,13 @@ GobEngine::GobEngine(OSystem *syst) : Engine(syst) { _pauseStart = 0; // Setup mixer - _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); + bool muteSFX = ConfMan.getBool("mute") || ConfMan.getBool("sfx_mute"); + bool muteMusic = ConfMan.getBool("mute") || ConfMan.getBool("music_mute"); + + _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, + muteSFX ? 0 : ConfMan.getInt("sfx_volume")); + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, + muteMusic ? 0 : ConfMan.getInt("music_volume")); _copyProtection = ConfMan.getBool("copy_protection"); diff --git a/engines/gob/inter_playtoons.cpp b/engines/gob/inter_playtoons.cpp index c9b962579b..142467b47f 100644 --- a/engines/gob/inter_playtoons.cpp +++ b/engines/gob/inter_playtoons.cpp @@ -362,7 +362,6 @@ void Inter_Playtoons::oPlaytoons_getObjAnimSize() { int16 objIndex; uint16 readVar[4]; uint8 i; - bool break_fl; Mult::Mult_AnimData animData; _vm->_game->_script->evalExpr(&objIndex); @@ -375,7 +374,6 @@ void Inter_Playtoons::oPlaytoons_getObjAnimSize() { return; } if (objIndex == -2) { - break_fl = false; warning("oPlaytoons_getObjAnimSize case -2 not implemented"); return; } diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 88b604023c..6acd096e58 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -1149,7 +1149,6 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir, void Mult_v2::advanceObjects(int16 index) { int16 frame; bool stop = false; - bool hasImds = false; frame = _multData->animKeysFrames[index]; if (frame == -1) @@ -1254,7 +1253,6 @@ void Mult_v2::advanceObjects(int16 index) { if ((dir != 1) && (--startFrame < 0)) startFrame = 0; - hasImds = true; playImd(imdFile, key, dir, startFrame); } } diff --git a/engines/groovie/groovie.cpp b/engines/groovie/groovie.cpp index 276b26ffe7..82eda1efe2 100644 --- a/engines/groovie/groovie.cpp +++ b/engines/groovie/groovie.cpp @@ -220,10 +220,8 @@ Common::Error GroovieEngine::run() { _system->getAudioCDManager()->openCD(cd_num); while (!shouldQuit()) { - // Show the debugger if required - if (_debugger->isAttached()) { - _debugger->onFrame(); - } + // Give the debugger a chance to act + _debugger->onFrame(); // Handle input Common::Event ev; diff --git a/engines/groovie/vdx.cpp b/engines/groovie/vdx.cpp index 1d3108a2cc..61756cb218 100644 --- a/engines/groovie/vdx.cpp +++ b/engines/groovie/vdx.cpp @@ -209,17 +209,14 @@ static const uint16 vdxBlockMapLookup[] = { }; void VDXPlayer::getDelta(Common::ReadStream *in) { - uint16 j, k, l; - uint32 offset; - uint8 currOpCode, param1, param2, param3; + uint16 k, l; // Get the size of the local palette - j = in->readUint16LE(); + uint16 palSize = in->readUint16LE(); // Load the palette if it isn't empty - if (j) { + if (palSize) { uint16 palBitField[16]; - int flag = 1, palIndex; // Load the bit field for (l = 0; l < 16; l++) { @@ -228,9 +225,9 @@ void VDXPlayer::getDelta(Common::ReadStream *in) { // Load the actual palette for (l = 0; l < 16; l++) { - flag = 1 << 15; - for (j = 0; j < 16; j++) { - palIndex = (l * 16) + j; + int flag = 1 << 15; + for (uint16 j = 0; j < 16; j++) { + int palIndex = (l * 16) + j; if (flag & palBitField[l]) { for (k = 0; k < 3; k++) { @@ -247,11 +244,12 @@ void VDXPlayer::getDelta(Common::ReadStream *in) { setPalette(_palBuf); } } - currOpCode = in->readByte(); - /* j now becomes the current block line we're dealing with */ - j = 0; - offset = 0; + uint8 currOpCode = in->readByte(); + uint8 param1, param2, param3; + + uint16 currentLine = 0; + uint32 offset = 0; while (!in->eos()) { byte colours[16]; if (currOpCode < 0x60) { @@ -277,8 +275,8 @@ void VDXPlayer::getDelta(Common::ReadStream *in) { break; case 0x61: /* Skip to the end of this line, next block is start of next */ /* Note this is used at the end of EVERY line */ - j++; - offset = j * TILE_SIZE * 640; + currentLine++; + offset = currentLine * TILE_SIZE * 640; break; case 0x62: case 0x63: @@ -382,12 +380,15 @@ void VDXPlayer::getStill(Common::ReadStream *in) { byte colours[16]; for (uint16 j = 0; j < numYTiles; j++) { - for (uint16 i = 0; i < numXTiles; i++) { /* Tile number */ + byte *currentTile = buf + j * TILE_SIZE * imageWidth; + for (uint16 i = numXTiles; i; i--) { uint8 colour1 = in->readByte(); uint8 colour0 = in->readByte(); uint16 colourMap = in->readUint16LE(); expandColourMap(colours, colourMap, colour1, colour0); - decodeBlockStill(buf + j * TILE_SIZE * imageWidth + i * TILE_SIZE, colours, 640, mask); + decodeBlockStill(currentTile, colours, 640, mask); + + currentTile += TILE_SIZE; } } @@ -425,20 +426,27 @@ void VDXPlayer::getStill(Common::ReadStream *in) { } void VDXPlayer::expandColourMap(byte *out, uint16 colourMap, uint8 colour1, uint8 colour0) { - int flag = 1 << 15; - for (int i = 0; i < 16; i++) { + // It's a bit faster to start from the end + out += 16; + for (int i = 16; i; i--) { // Set the corresponding colour - out[i] = (colourMap & flag) ? colour1 : colour0; + // The following is an optimized version of: + // *--out = (colourMap & 1) ? colour1 : colour0; + uint8 selector = -(colourMap & 1); + *--out = (selector & colour1) | (~selector & colour0); - // Update the flag to test the next colour - flag >>= 1; + // Update the flag map to test the next colour + colourMap >>= 1; } } void VDXPlayer::decodeBlockStill(byte *buf, byte *colours, uint16 imageWidth, uint8 mask) { - for (int y = 0; y < TILE_SIZE; y++) { - for (int x = 0; x < TILE_SIZE; x++) { - if (_flagOne) { + assert(TILE_SIZE == 4); + + for (int y = TILE_SIZE; y; y--) { + if (_flagOne) { + // TODO: optimize with bit logic? + for (int x = 0; x < TILE_SIZE; x++) { // 0xff pixels don't modify the buffer if (*colours != 0xff) { // Write the colour @@ -446,25 +454,28 @@ void VDXPlayer::decodeBlockStill(byte *buf, byte *colours, uint16 imageWidth, ui // Note: if the mask is 0, it paints the image // else, it paints the image's mask using 0xff } - } else { - *buf = *colours; + + // Point to the next colour + colours++; + + // Point to the next pixel + buf++; } - // Point to the next colour - colours++; + // Point to the start of the next line + buf += imageWidth - TILE_SIZE; + } else { + *((uint32 *)buf) = *((uint32 *)colours); + colours += 4; - // Point to the next pixel - buf++; + // Point to the start of the next line + buf += imageWidth; } - - // Point to the start of the next line - buf += imageWidth - TILE_SIZE; } } void VDXPlayer::decodeBlockDelta(uint32 offset, byte *colours, uint16 imageWidth) { - byte *fgBuf = (byte *)_fg->getBasePtr(0, 0) + offset; - //byte *bgBuf = (byte *)_bg->getBasePtr(0, 0) + offset; + assert(TILE_SIZE == 4); byte *dest; // TODO: Verify just the else block is required @@ -475,27 +486,38 @@ void VDXPlayer::decodeBlockDelta(uint32 offset, byte *colours, uint16 imageWidth dest = (byte *)_bg->getBasePtr(0, 0) + offset; //} - int32 off = _origX + _origY * imageWidth; - for (int y = 0; y < TILE_SIZE; y++) { - for (int x = 0; x < TILE_SIZE; x++) { - if (_flagSeven) { - if (fgBuf[off] != 0xff) { + // Move the pointers to the beginning of the current block + int32 blockOff = _origX + _origY * imageWidth; + dest += blockOff; + byte *fgBuf = 0; + if (_flagSeven) { + fgBuf = (byte *)_fg->getBasePtr(0, 0) + offset + blockOff; + //byte *bgBuf = (byte *)_bg->getBasePtr(0, 0) + offset + blockOff; + } + + for (int y = TILE_SIZE; y; y--) { + if (_flagSeven) { + // Paint mask + for (int x = 0; x < TILE_SIZE; x++) { + // TODO: this can probably be optimized with bit logic + if (fgBuf[x] != 0xff) { if (*colours == 0xff) { - dest[off] = fgBuf[off]; + dest[x] = fgBuf[x]; } else { - dest[off] = *colours; + dest[x] = *colours; } } - } else { - // Paint directly - dest[off] = *colours; + colours++; } - colours++; - off++; + fgBuf += imageWidth; + } else { + // Paint directly + *((uint32 *)dest) = *((uint32 *)colours); + colours += 4; } - // Prepare the offset of the next line - off += imageWidth - TILE_SIZE; + // Move to the next line + dest += imageWidth; } } diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp index d71f7b8b25..225b44b3f4 100644 --- a/engines/kyra/debugger.cpp +++ b/engines/kyra/debugger.cpp @@ -240,7 +240,7 @@ bool Debugger_LoK::cmd_enterRoom(int argc, const char **argv) { while (!_vm->_screen->isMouseVisible()) _vm->_screen->showMouse(); - _detach_now = true; + detach(); return false; } @@ -327,7 +327,7 @@ bool Debugger_v2::cmd_enterScene(int argc, const char **argv) { while (!_vm->screen_v2()->isMouseVisible()) _vm->screen_v2()->showMouse(); - _detach_now = true; + detach(); return false; } diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h index 390281c356..fe4cc7298f 100644 --- a/engines/kyra/detection_tables.h +++ b/engines/kyra/detection_tables.h @@ -228,7 +228,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH + Common::GUIO_NOSPEECH | Common::GUIO_MIDIGM }, KYRA1_FLOPPY_FLAGS }, diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp index c8b7e8ec4f..9a1d750391 100644 --- a/engines/kyra/gui_lok.cpp +++ b/engines/kyra/gui_lok.cpp @@ -579,7 +579,7 @@ void GUI_LoK::setupSavegames(Menu &menu, int num) { for (int i = startSlot; i < num; ++i) menu.item[i].enabled = 0; - KyraEngine_v1::SaveHeader header; + KyraEngine_LoK::SaveHeader header; for (int i = startSlot; i < num && uint(_savegameOffset + i) < _saveSlots.size(); i++) { if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset]), header))) { Common::strlcpy(savenames[i], header.description.c_str(), ARRAYSIZE(savenames[0])); diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp index ded1326110..2c86073892 100644 --- a/engines/kyra/gui_lol.cpp +++ b/engines/kyra/gui_lol.cpp @@ -2611,7 +2611,7 @@ void GUI_LoL::updateSavegameList() { if (_savegameListSize) { Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>()); - KyraEngine_v1::SaveHeader header; + LoLEngine::SaveHeader header; Common::InSaveFile *in; _savegameList = new char *[_savegameListSize]; @@ -2658,7 +2658,7 @@ int GUI_LoL::getInput() { if (_currentMenu == &_savenameMenu) { _vm->updateInput(); - for (Common::List<KyraEngine_v1::Event>::const_iterator evt = _vm->_eventList.begin(); evt != _vm->_eventList.end(); ++evt) { + for (Common::List<LoLEngine::Event>::const_iterator evt = _vm->_eventList.begin(); evt != _vm->_eventList.end(); ++evt) { if (evt->event.type == Common::EVENT_KEYDOWN) _keyPressed = evt->event.kbd; } diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp index de19228d16..fe4b54d09b 100644 --- a/engines/kyra/gui_v2.cpp +++ b/engines/kyra/gui_v2.cpp @@ -452,7 +452,7 @@ void GUI_v2::setupSavegameNames(Menu &menu, int num) { if (_isSaveMenu && _savegameOffset == 0) startSlot = 1; - KyraEngine_v1::SaveHeader header; + KyraEngine_v2::SaveHeader header; Common::InSaveFile *in; for (int i = startSlot; i < num && uint(_savegameOffset + i) < _saveSlots.size(); ++i) { if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset]), header)) != 0) { diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp index cf61b58326..159230e928 100644 --- a/engines/kyra/kyra_lok.cpp +++ b/engines/kyra/kyra_lok.cpp @@ -234,6 +234,7 @@ Common::Error KyraEngine_LoK::init() { _talkingCharNum = -1; _charSayUnk3 = -1; + _disabledTalkAnimObject = _enabledTalkAnimObject = 0; memset(_currSentenceColor, 0, 3); _startSentencePalIndex = -1; _fadeText = false; diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h index c0c9bf06c4..b37a14bad4 100644 --- a/engines/kyra/kyra_lok.h +++ b/engines/kyra/kyra_lok.h @@ -132,7 +132,7 @@ public: int _paletteChanged; int16 _northExitHeight; - typedef void (KyraEngine_LoK::*IntroProc)(); + typedef bool (KyraEngine_LoK::*IntroProc)(); // static data access const char * const *seqWSATable() { return _seq_WSATable; } @@ -157,11 +157,12 @@ protected: // -> intro void seq_intro(); - void seq_introLogos(); - void seq_introStory(); - void seq_introMalcolmTree(); - void seq_introKallakWriting(); - void seq_introKallakMalcolm(); + bool seq_introPublisherLogos(); + bool seq_introLogos(); + bool seq_introStory(); + bool seq_introMalcolmTree(); + bool seq_introKallakWriting(); + bool seq_introKallakMalcolm(); // -> ingame animations void seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly); @@ -373,20 +374,24 @@ protected: //void setTimer19(); void setupTimers(); void timerUpdateHeadAnims(int timerNum); - void timerSetFlags1(int timerNum); - void timerSetFlags2(int timerNum); - void timerSetFlags3(int timerNum); - void timerCheckAnimFlag1(int timerNum); - void timerCheckAnimFlag2(int timerNum); + void timerTulipCreator(int timerNum); + void timerRubyCreator(int timerNum); + void timerAsInvisibleTimeout(int timerNum); + void timerAsWillowispTimeout(int timerNum); void checkAmuletAnimFlags(); void timerRedrawAmulet(int timerNum); + void timerLavenderRoseCreator(int timerNum); + void timerAcornCreator(int timerNum); + void timerBlueberryCreator(int timerNum); void timerFadeText(int timerNum); - void updateAnimFlag1(int timerNum); - void updateAnimFlag2(int timerNum); + void timerWillowispFrameTimer(int timerNum); + void timerInvisibleFrameTimer(int timerNum); void drawAmulet(); void setTextFadeTimerCountdown(int16 countdown); void setWalkspeed(uint8 newSpeed); + void setItemCreationFlags(int offset, int count); + int buttonInventoryCallback(Button *caller); int buttonAmuletCallback(Button *caller); @@ -472,6 +477,8 @@ protected: int8 _charSayUnk2; int8 _charSayUnk3; int8 _currHeadShape; + int8 _disabledTalkAnimObject; + int8 _enabledTalkAnimObject; uint8 _currSentenceColor[3]; int8 _startSentencePalIndex; bool _fadeText; diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp index cf90c73dbd..61bc3708c3 100644 --- a/engines/kyra/kyra_mr.cpp +++ b/engines/kyra/kyra_mr.cpp @@ -369,9 +369,7 @@ void KyraEngine_MR::playVQA(const char *name) { VQAMovie vqa(this, _system); char filename[20]; - int size = 0; // TODO: Movie size is 0, 1 or 2. - - snprintf(filename, sizeof(filename), "%s%d.VQA", name, size); + snprintf(filename, sizeof(filename), "%s%d.VQA", name, _configVQAQuality); if (vqa.open(filename)) { for (int i = 0; i < 4; ++i) { @@ -1460,6 +1458,8 @@ void KyraEngine_MR::registerDefaultSettings() { ConfMan.registerDefault("studio_audience", true); ConfMan.registerDefault("skip_support", true); ConfMan.registerDefault("helium_mode", false); + // 0 - best, 1 - mid, 2 - low + ConfMan.registerDefault("video_quality", 0); } void KyraEngine_MR::writeSettings() { @@ -1495,6 +1495,7 @@ void KyraEngine_MR::readSettings() { _configStudio = ConfMan.getBool("studio_audience"); _configSkip = ConfMan.getBool("skip_support"); _configHelium = ConfMan.getBool("helium_mode"); + _configVQAQuality = CLIP(ConfMan.getInt("video_quality"), 0, 2); } } // End of namespace Kyra diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h index 773b0a1699..36b937f2a8 100644 --- a/engines/kyra/kyra_mr.h +++ b/engines/kyra/kyra_mr.h @@ -73,6 +73,7 @@ private: bool _configStudio; bool _configSkip; bool _configHelium; + int _configVQAQuality; void registerDefaultSettings(); void writeSettings(); diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index abe13cec2b..5db2c360d6 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -100,9 +100,7 @@ void KyraEngine_v1::pauseEngineIntern(bool pause) { Common::Error KyraEngine_v1::init() { // Setup mixer - _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); + syncSoundSettings(); if (!_flags.useDigSound) { // We prefer AdLib over MIDI in Kyra 1, since it offers MT-32 support only, most users don't have a real @@ -259,7 +257,7 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag) int keys = 0; int8 mouseWheel = 0; - while (_eventList.size()) { + while (!_eventList.empty()) { Common::Event event = *_eventList.begin(); bool breakLoop = false; @@ -283,6 +281,7 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag) if (event.kbd.keycode == Common::KEYCODE_d) { if (_debugger) _debugger->attach(); + breakLoop = true; } else if (event.kbd.keycode == Common::KEYCODE_q) { quitGame(); } @@ -336,7 +335,7 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag) break; } - if (_debugger && _debugger->isAttached()) + if (_debugger) _debugger->onFrame(); if (breakLoop) diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index b9006431d7..4708041cf7 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -84,6 +84,7 @@ MODULE_OBJS += \ sequences_lol.o \ sound_lol.o \ sprites_lol.o \ + staticres_lol.o \ text_lol.o \ timer_lol.o endif diff --git a/engines/kyra/scene_mr.cpp b/engines/kyra/scene_mr.cpp index 875200895a..bd0a1fe544 100644 --- a/engines/kyra/scene_mr.cpp +++ b/engines/kyra/scene_mr.cpp @@ -79,11 +79,9 @@ void KyraEngine_MR::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 musicUpdate(0); uint32 waitUntilTimer = 0; - bool newSoundFile = false; if (_lastMusicCommand != _sceneList[sceneId].sound) { fadeOutMusic(60); waitUntilTimer = _system->getMillis() + 60 * _tickLength; - newSoundFile = true; } _chatAltFlag = false; diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 7f3959d5fe..ade9886c2e 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -611,14 +611,6 @@ void Screen::fadePalette(const Palette &pal, int delay, const UpdateFunctor *upF _vm->delay((delayAcc >> 8) * 1000 / 60); delayAcc &= 0xFF; } - - if (_vm->shouldQuit()) { - setScreenPalette(pal); - if (upFunc && upFunc->isValid()) - (*upFunc)(); - else - _system->updateScreen(); - } } void Screen::getFadeParams(const Palette &pal, int delay, int &delayInc, int &diff) { diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp index 4ec6e7f349..20bc8abec5 100644 --- a/engines/kyra/script_tim.cpp +++ b/engines/kyra/script_tim.cpp @@ -159,7 +159,7 @@ TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpc _tim->opcodes = opcodes; IFFParser iff(*stream); - Common::Functor1Mem< Common::IFFChunk &, bool, TIMInterpreter > c(this, &TIMInterpreter::callback); + Common::Functor1Mem<Common::IFFChunk &, bool, TIMInterpreter> c(this, &TIMInterpreter::callback); iff.parse(c); if (!_tim->avtl) @@ -170,7 +170,7 @@ TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpc delete stream; - int num = (_avtlChunkSize < TIM::kCountFuncs) ? _avtlChunkSize : (int)TIM::kCountFuncs; + const int num = (_avtlChunkSize < TIM::kCountFuncs) ? _avtlChunkSize : (int)TIM::kCountFuncs; for (int i = 0; i < num; ++i) _tim->func[i].avtl = _tim->avtl + _tim->avtl[i]; diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp index 78e8ded9f7..c4bdc29f57 100644 --- a/engines/kyra/sequences_lok.cpp +++ b/engines/kyra/sequences_lok.cpp @@ -93,6 +93,7 @@ void KyraEngine_LoK::seq_intro() { _res->loadPakFile("INTRO.VRM"); static const IntroProc introProcTable[] = { + &KyraEngine_LoK::seq_introPublisherLogos, &KyraEngine_LoK::seq_introLogos, &KyraEngine_LoK::seq_introStory, &KyraEngine_LoK::seq_introMalcolmTree, @@ -114,8 +115,13 @@ void KyraEngine_LoK::seq_intro() { snd_playTheme(0, 2); _text->setTalkCoords(144); - for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) - (this->*introProcTable[i])(); + for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) { + if ((this->*introProcTable[i])() && !shouldQuit()) { + resetSkipFlag(); + _screen->fadeToBlack(); + _screen->clearPage(0); + } + } _text->setTalkCoords(136); delay(30 * _tickLength); @@ -127,18 +133,32 @@ void KyraEngine_LoK::seq_intro() { _res->unloadPakFile("INTRO.VRM"); } -void KyraEngine_LoK::seq_introLogos() { +bool KyraEngine_LoK::seq_introPublisherLogos() { if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { _screen->loadBitmap("LOGO.CPS", 3, 3, &_screen->getPalette(0)); _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); _screen->updateScreen(); _screen->fadeFromBlack(); delay(90 * _tickLength); - _screen->fadeToBlack(); - if (!_abortIntroFlag) + if (!_abortIntroFlag) { + _screen->fadeToBlack(); snd_playWanderScoreViaMap(_flags.platform == Common::kPlatformFMTowns ? 57 : 2, 0); + } + } else if (_flags.platform == Common::kPlatformMacintosh && _res->exists("MP_GOLD.CPS")) { + _screen->loadPalette("MP_GOLD.COL", _screen->getPalette(0)); + _screen->loadBitmap("MP_GOLD.CPS", 3, 3, 0); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); + _screen->updateScreen(); + _screen->fadeFromBlack(); + delay(120 * _tickLength); + if (!_abortIntroFlag) + _screen->fadeToBlack(); } + return _abortIntroFlag; +} + +bool KyraEngine_LoK::seq_introLogos() { _screen->clearPage(0); if (_flags.platform == Common::kPlatformAmiga) { @@ -159,11 +179,8 @@ void KyraEngine_LoK::seq_introLogos() { _screen->updateScreen(); _screen->fadeFromBlack(); - if (_seq->playSequence(_seq_WestwoodLogo, skipFlag()) || shouldQuit()) { - _screen->fadeToBlack(); - _screen->clearPage(0); - return; - } + if (_seq->playSequence(_seq_WestwoodLogo, skipFlag()) || shouldQuit()) + return true; delay(60 * _tickLength); @@ -174,16 +191,14 @@ void KyraEngine_LoK::seq_introLogos() { Screen::FontId of = _screen->setFont(Screen::FID_8_FNT); - if ((_seq->playSequence(_seq_KyrandiaLogo, skipFlag()) && !seq_skipSequence()) || shouldQuit()) { - _screen->fadeToBlack(); - _screen->clearPage(0); - return; - } + if (_seq->playSequence(_seq_KyrandiaLogo, skipFlag()) || shouldQuit()) + return true; + _screen->setFont(of); _screen->fillRect(0, 179, 319, 199, 0); if (shouldQuit()) - return; + return false; if (_flags.platform == Common::kPlatformAmiga) { _screen->copyPalette(0, 2); @@ -225,20 +240,20 @@ void KyraEngine_LoK::seq_introLogos() { } while (!doneFlag && !shouldQuit() && !_abortIntroFlag); } - if (shouldQuit()) - return; + if (_abortIntroFlag || shouldQuit()) + return true; - _seq->playSequence(_seq_Forest, true); + return _seq->playSequence(_seq_Forest, true); } -void KyraEngine_LoK::seq_introStory() { +bool KyraEngine_LoK::seq_introStory() { _screen->clearPage(3); _screen->clearPage(0); // HACK: The Italian fan translation uses an special text screen here // so we show it even when text is disabled if (!textEnabled() && speechEnabled() && _flags.lang != Common::IT_ITA) - return; + return false; if ((_flags.lang == Common::EN_ANY && !_flags.isTalkie && _flags.platform == Common::kPlatformPC) || _flags.platform == Common::kPlatformAmiga) _screen->loadBitmap("TEXT.CPS", 3, 3, &_screen->getPalette(0)); @@ -292,25 +307,30 @@ void KyraEngine_LoK::seq_introStory() { _screen->updateScreen(); delay(360 * _tickLength); + + return _abortIntroFlag; } -void KyraEngine_LoK::seq_introMalcolmTree() { +bool KyraEngine_LoK::seq_introMalcolmTree() { _screen->_curPage = 0; _screen->clearPage(3); - _seq->playSequence(_seq_MalcolmTree, true); + return _seq->playSequence(_seq_MalcolmTree, true); } -void KyraEngine_LoK::seq_introKallakWriting() { +bool KyraEngine_LoK::seq_introKallakWriting() { _seq->makeHandShapes(); _screen->setAnimBlockPtr(5060); _screen->_charWidth = -2; _screen->clearPage(3); - _seq->playSequence(_seq_KallakWriting, true); + const bool skipped = _seq->playSequence(_seq_KallakWriting, true); + _seq->freeHandShapes(); + + return skipped; } -void KyraEngine_LoK::seq_introKallakMalcolm() { +bool KyraEngine_LoK::seq_introKallakMalcolm() { _screen->clearPage(3); - _seq->playSequence(_seq_KallakMalcolm, true); + return _seq->playSequence(_seq_KallakMalcolm, true); } void KyraEngine_LoK::seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly) { diff --git a/engines/kyra/sound_midi.cpp b/engines/kyra/sound_midi.cpp index 7eb151a64d..026c72de26 100644 --- a/engines/kyra/sound_midi.cpp +++ b/engines/kyra/sound_midi.cpp @@ -573,8 +573,12 @@ void SoundMidiPC::updateVolumeSettings() { if (!_output) return; - int newMusVol = ConfMan.getInt("music_volume"); - _sfxVolume = ConfMan.getInt("sfx_volume"); + bool mute = false; + if (ConfMan.hasKey("mute")) + mute = ConfMan.getBool("mute"); + + const int newMusVol = (mute ? 0 : ConfMan.getInt("music_volume")); + _sfxVolume = (mute ? 0 : ConfMan.getInt("sfx_volume")); _output->setSourceVolume(0, newMusVol, newMusVol != _musicVolume); _musicVolume = newMusVol; diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp index 7a570b3100..32fbbdf1e7 100644 --- a/engines/kyra/sound_towns.cpp +++ b/engines/kyra/sound_towns.cpp @@ -596,21 +596,15 @@ Towns_EuphonyDriver::~Towns_EuphonyDriver() { MidiDriver_YM2612::removeLookupTables(); - if (_fmInstruments) { - delete[] _fmInstruments; - _fmInstruments = 0; - } + delete[] _fmInstruments; + _fmInstruments = 0; - if (_waveInstruments) { - delete[] _waveInstruments; - _waveInstruments = 0; - } + delete[] _waveInstruments; + _waveInstruments = 0; for (int i = 0; i < 10; i++) { - if (_waveSounds[i]) { - delete[] _waveSounds[i]; - _waveSounds[i] = 0; - } + delete[] _waveSounds[i]; + _waveSounds[i] = 0; } if (_queue) { @@ -1859,7 +1853,7 @@ void TownsPC98_OpnChannel::loadData(uint8 *data) { _dataPtr = data; _totalLevel = 0x7F; - uint8 *tmp = _dataPtr; + uint8 *tmp = _dataPtr; for (bool loop = true; loop; ) { uint8 cmd = *tmp++; if (cmd < 0xf0) { @@ -2507,7 +2501,7 @@ void TownsPC98_OpnSfxChannel::loadData(uint8 *data) { _ssgTl = 0xff; _algorithm = 0x80; - uint8 *tmp = _dataPtr; + uint8 *tmp = _dataPtr; for (bool loop = true; loop; ) { uint8 cmd = *tmp++; if (cmd < 0xf0) { @@ -2798,7 +2792,7 @@ void TownsPC98_OpnSquareSineSource::nextTick(int32 *buffer, uint32 bufferSize) { finOut += finOutTemp; } - finOut /= 3; + finOut /= 3; buffer[i << 1] += finOut; buffer[(i << 1) + 1] += finOut; @@ -3335,7 +3329,7 @@ void TownsPC98_OpnCore::setVolumeChannelMasks(int channelMaskA, int channelMaskB if (_ssg) _ssg->setVolumeChannelMasks(_volMaskA >> _numChan, _volMaskB >> _numChan); if (_prc) - _prc->setVolumeChannelMasks(_volMaskA >> (_numChan + _numSSG), _volMaskB >> (_numChan + _numSSG)); + _prc->setVolumeChannelMasks(_volMaskA >> (_numChan + _numSSG), _volMaskB >> (_numChan + _numSSG)); } void TownsPC98_OpnCore::generateTables() { @@ -3805,7 +3799,7 @@ void TownsPC98_OpnDriver::setSfxTempo(uint16 tempo) { void TownsPC98_OpnDriver::startSoundEffect() { int volFlags = 0; - + for (int i = 0; i < 2; i++) { if (_sfxOffsets[i]) { _ssgChannels[i + 1]->protect(); @@ -3818,7 +3812,7 @@ void TownsPC98_OpnDriver::startSoundEffect() { _updateSfxFlag &= ~_sfxChannels[i]->_idFlag; } } - + setVolumeChannelMasks(~volFlags, volFlags); _sfxData = 0; } @@ -4259,8 +4253,12 @@ void SoundPC98::updateVolumeSettings() { if (!_driver) return; - _driver->setMusicVolume(ConfMan.getInt("music_volume")); - _driver->setSoundEffectVolume(ConfMan.getInt("sfx_volume")); + bool mute = false; + if (ConfMan.hasKey("mute")) + mute = ConfMan.getBool("mute"); + + _driver->setMusicVolume((mute ? 0 : ConfMan.getInt("music_volume"))); + _driver->setSoundEffectVolume((mute ? 0 : ConfMan.getInt("sfx_volume"))); } // KYRA 2 @@ -4461,14 +4459,18 @@ void SoundTownsPC98_v2::updateVolumeSettings() { if (!_driver) return; - _driver->setMusicVolume(ConfMan.getInt("music_volume")); - _driver->setSoundEffectVolume(ConfMan.getInt("sfx_volume")); + bool mute = false; + if (ConfMan.hasKey("mute")) + mute = ConfMan.getBool("mute"); + + _driver->setMusicVolume((mute ? 0 : ConfMan.getInt("music_volume"))); + _driver->setSoundEffectVolume((mute ? 0 : ConfMan.getInt("sfx_volume"))); } // static resources const uint32 TownsPC98_OpnCore::_adtStat[] = { - 0x00010001, 0x00010001, 0x00010001, 0x01010001, + 0x00010001, 0x00010001, 0x00010001, 0x01010001, 0x00010101, 0x00010101, 0x00010101, 0x01010101, 0x01010101, 0x01010101, 0x01010102, 0x01010102, 0x01020102, 0x01020102, 0x01020202, 0x01020202, @@ -4482,14 +4484,14 @@ const uint32 TownsPC98_OpnCore::_adtStat[] = { const uint8 TownsPC98_OpnCore::_detSrc[] = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, + 0x08, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, - 0x08, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, - 0x10, 0x10, 0x10, 0x10, 0x02, 0x02, 0x02, 0x02, + 0x08, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x10, 0x10, 0x10, 0x10, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, - 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, - 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x13, 0x14, + 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x13, 0x14, 0x16, 0x16, 0x16, 0x16 }; diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 2f2acd78d1..9ad2f50619 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -27,18 +27,15 @@ #include "common/md5.h" #include "kyra/kyra_v1.h" #include "kyra/kyra_lok.h" -#include "kyra/lol.h" #include "kyra/kyra_v2.h" #include "kyra/kyra_hof.h" #include "kyra/kyra_mr.h" #include "kyra/screen.h" #include "kyra/screen_lok.h" -#include "kyra/screen_lol.h" #include "kyra/screen_hof.h" #include "kyra/screen_mr.h" #include "kyra/resource.h" #include "kyra/gui_lok.h" -#include "kyra/gui_lol.h" #include "kyra/gui_hof.h" #include "kyra/gui_mr.h" #include "kyra/sound_intern.h" @@ -305,36 +302,6 @@ const ItemAnimData_v2 *StaticResource::loadShapeAnimData_v2(int id, int &entries return (const ItemAnimData_v2 *)getData(id, k2ShpAnimDataV2, entries); } -#ifdef ENABLE_LOL -const LoLCharacter *StaticResource::loadCharData(int id, int &entries) { - return (const LoLCharacter *)getData(id, kLolCharData, entries); -} - -const SpellProperty *StaticResource::loadSpellData(int id, int &entries) { - return (const SpellProperty *)getData(id, kLolSpellData, entries); -} - -const CompassDef *StaticResource::loadCompassData(int id, int &entries) { - return (const CompassDef *)getData(id, kLolCompassData, entries); -} - -const FlyingObjectShape *StaticResource::loadFlyingObjectData(int id, int &entries) { - return (const FlyingObjectShape *)getData(id, kLolFlightShpData, entries); -} - -const uint16 *StaticResource::loadRawDataBe16(int id, int &entries) { - return (const uint16 *)getData(id, kLolRawDataBe16, entries); -} - -const uint32 *StaticResource::loadRawDataBe32(int id, int &entries) { - return (const uint32 *)getData(id, kLolRawDataBe32, entries); -} - -const ButtonDef *StaticResource::loadButtonDefs(int id, int &entries) { - return (const ButtonDef *)getData(id, kLolButtonData, entries); -} -#endif // ENABLE_LOL - bool StaticResource::prefetchId(int id) { if (id == -1) { for (DataMap::const_iterator i = _dataTable.begin(); i != _dataTable.end(); ++i) { @@ -641,160 +608,6 @@ bool StaticResource::loadShapeAnimData_v2(Common::SeekableReadStream &stream, vo return true; } -#ifdef ENABLE_LOL -bool StaticResource::loadCharData(Common::SeekableReadStream &stream, void *&ptr, int &size) { - size = stream.size() / 130; - LoLCharacter *charData = new LoLCharacter[size]; - - for (int i = 0; i < size; i++) { - LoLCharacter *t = &charData[i]; - - t->flags = stream.readUint16LE(); - stream.read(t->name, 11); - t->raceClassSex = stream.readByte(); - t->id = stream.readSint16LE(); - t->curFaceFrame = stream.readByte(); - t->tempFaceFrame = stream.readByte(); - t->screamSfx = stream.readByte(); - stream.readUint32LE(); - for (int ii = 0; ii < 8; ii++) - t->itemsMight[ii] = stream.readUint16LE(); - for (int ii = 0; ii < 8; ii++) - t->protectionAgainstItems[ii] = stream.readUint16LE(); - t->itemProtection = stream.readUint16LE(); - t->hitPointsCur = stream.readSint16LE(); - t->hitPointsMax = stream.readUint16LE(); - t->magicPointsCur = stream.readSint16LE(); - t->magicPointsMax = stream.readUint16LE(); - t->field_41 = stream.readByte(); - t->damageSuffered = stream.readUint16LE(); - t->weaponHit = stream.readUint16LE(); - t->totalMightModifier = stream.readUint16LE(); - t->totalProtectionModifier = stream.readUint16LE(); - t->might = stream.readUint16LE(); - t->protection = stream.readUint16LE(); - t->nextAnimUpdateCountdown = stream.readSint16LE(); - for (int ii = 0; ii < 11; ii++) - t->items[ii] = stream.readUint16LE(); - for (int ii = 0; ii < 3; ii++) - t->skillLevels[ii] = stream.readByte(); - for (int ii = 0; ii < 3; ii++) - t->skillModifiers[ii] = stream.readByte(); - for (int ii = 0; ii < 3; ii++) - t->experiencePts[ii] = stream.readUint32LE(); - for (int ii = 0; ii < 5; ii++) - t->characterUpdateEvents[ii] = stream.readByte(); - for (int ii = 0; ii < 5; ii++) - t->characterUpdateDelay[ii] = stream.readByte(); - }; - - ptr = charData; - return true; -} - -bool StaticResource::loadSpellData(Common::SeekableReadStream &stream, void *&ptr, int &size) { - size = stream.size() / 28; - SpellProperty *spellData = new SpellProperty[size]; - - for (int i = 0; i < size; i++) { - SpellProperty *t = &spellData[i]; - - t->spellNameCode = stream.readUint16LE(); - for (int ii = 0; ii < 4; ii++) - t->mpRequired[ii] = stream.readUint16LE(); - t->field_a = stream.readUint16LE(); - t->field_c = stream.readUint16LE(); - for (int ii = 0; ii < 4; ii++) - t->hpRequired[ii] = stream.readUint16LE(); - t->field_16 = stream.readUint16LE(); - t->field_18 = stream.readUint16LE(); - t->flags = stream.readUint16LE(); - }; - - ptr = spellData; - return true; -} - -bool StaticResource::loadCompassData(Common::SeekableReadStream &stream, void *&ptr, int &size) { - size = stream.size() / 4; - CompassDef *defs = new CompassDef[size]; - - for (int i = 0; i < size; i++) { - CompassDef *t = &defs[i]; - t->shapeIndex = stream.readByte(); - t->x = stream.readByte(); - t->y = stream.readByte(); - t->flags = stream.readByte(); - }; - - - ptr = defs; - return true; -} - -bool StaticResource::loadFlyingObjectData(Common::SeekableReadStream &stream, void *&ptr, int &size) { - size = stream.size() / 5; - FlyingObjectShape *defs = new FlyingObjectShape[size]; - - for (int i = 0; i < size; i++) { - FlyingObjectShape *t = &defs[i]; - t->shapeFront = stream.readByte(); - t->shapeBack = stream.readByte(); - t->shapeLeft = stream.readByte(); - t->drawFlags = stream.readByte(); - t->flipFlags = stream.readByte(); - }; - - ptr = defs; - return true; -} - -bool StaticResource::loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size) { - size = stream.size() >> 1; - - uint16 *r = new uint16[size]; - - for (int i = 0; i < size; i++) - r[i] = stream.readUint16BE(); - - ptr = r; - return true; -} - -bool StaticResource::loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size) { - size = stream.size() >> 2; - - uint32 *r = new uint32[size]; - - for (int i = 0; i < size; i++) - r[i] = stream.readUint32BE(); - - ptr = r; - return true; -} - -bool StaticResource::loadButtonDefs(Common::SeekableReadStream &stream, void *&ptr, int &size) { - size = stream.size() / 18; - - ButtonDef *r = new ButtonDef[size]; - - for (int i = 0; i < size; i++) { - r[i].buttonflags = stream.readUint16BE(); - r[i].keyCode = stream.readUint16BE(); - r[i].keyCode2 = stream.readUint16BE(); - r[i].x = stream.readSint16BE(); - r[i].y = stream.readSint16BE(); - r[i].w = stream.readUint16BE(); - r[i].h = stream.readUint16BE(); - r[i].index = stream.readUint16BE(); - r[i].screenDim = stream.readUint16BE(); - } - - ptr = r; - return true; -} -#endif // ENABLE_LOL - void StaticResource::freeRawData(void *&ptr, int &size) { uint8 *data = (uint8 *)ptr; delete[] data; @@ -870,58 +683,6 @@ void StaticResource::freeHofShapeAnimDataV2(void *&ptr, int &size) { size = 0; } -#ifdef ENABLE_LOL -void StaticResource::freeCharData(void *&ptr, int &size) { - LoLCharacter *d = (LoLCharacter *)ptr; - delete[] d; - ptr = 0; - size = 0; -} - -void StaticResource::freeSpellData(void *&ptr, int &size) { - SpellProperty *d = (SpellProperty *)ptr; - delete[] d; - ptr = 0; - size = 0; -} - -void StaticResource::freeCompassData(void *&ptr, int &size) { - CompassDef *d = (CompassDef *)ptr; - delete[] d; - ptr = 0; - size = 0; -} - -void StaticResource::freeFlyingObjectData(void *&ptr, int &size) { - FlyingObjectShape *d = (FlyingObjectShape *)ptr; - delete[] d; - ptr = 0; - size = 0; -} - - -void StaticResource::freeRawDataBe16(void *&ptr, int &size) { - uint16 *data = (uint16 *)ptr; - delete[] data; - ptr = 0; - size = 0; -} - -void StaticResource::freeRawDataBe32(void *&ptr, int &size) { - uint32 *data = (uint32 *)ptr; - delete[] data; - ptr = 0; - size = 0; -} - -void StaticResource::freeButtonDefs(void *&ptr, int &size) { - ButtonDef *d = (ButtonDef *)ptr; - delete[] d; - ptr = 0; - size = 0; -} -#endif // ENABLE_LOL - #pragma mark - void KyraEngine_LoK::initStaticResource() { @@ -1360,371 +1121,6 @@ void KyraEngine_MR::initStaticResource() { _itemStringMap = _staticres->loadRawData(k3ItemStringMap, _itemStringMapSize); } -#ifdef ENABLE_LOL -// TODO: move this to lol.cpp maybe? -void LoLEngine::initStaticResource() { - // assign music data - static const char *pcMusicFileListIntro[] = { "LOREINTR" }; - static const char *pcMusicFileListFinale[] = { "LOREFINL" }; - static const char *pcMusicFileListIngame[] = { "LORE%02d%c" }; - - static const char *pc98MusicFileListIntro[] = { 0, "lore84.86", "lore82.86", 0, 0, 0, "lore83.86", "lore81.86" }; - static const char *pc98MusicFileListFinale[] = { 0, 0, "lore85.86", "lore86.86", "lore87.86" }; - static const char *pc98MusicFileListIngame[] = { "lore%02d.86" }; - - memset(_soundData, 0, sizeof(_soundData)); - if (_flags.platform == Common::kPlatformPC) { - _soundData[0].fileList = pcMusicFileListIntro; - _soundData[0].fileListLen = ARRAYSIZE(pcMusicFileListIntro); - _soundData[1].fileList = pcMusicFileListIngame; - _soundData[1].fileListLen = ARRAYSIZE(pcMusicFileListIngame); - _soundData[2].fileList = pcMusicFileListFinale; - _soundData[2].fileListLen = ARRAYSIZE(pcMusicFileListFinale); - } else if (_flags.platform == Common::kPlatformPC98) { - _soundData[0].fileList = pc98MusicFileListIntro; - _soundData[0].fileListLen = ARRAYSIZE(pc98MusicFileListIntro); - _soundData[1].fileList = pc98MusicFileListIngame; - _soundData[1].fileListLen = ARRAYSIZE(pc98MusicFileListIngame); - _soundData[2].fileList = pc98MusicFileListFinale; - _soundData[2].fileListLen = ARRAYSIZE(pc98MusicFileListFinale); - } - - if (_flags.isDemo) - return; - - _pakFileList = _staticres->loadStrings(kLolIngamePakFiles, _pakFileListSize); - _charDefaults = _staticres->loadCharData(kLolCharacterDefs, _charDefaultsSize); - _ingameSoundIndex = (const uint16 *)_staticres->loadRawData(kLolIngameSfxIndex, _ingameSoundIndexSize); - _musicTrackMap = _staticres->loadRawData(kLolMusicTrackMap, _musicTrackMapSize); - _ingameGMSoundIndex = _staticres->loadRawData(kLolIngameGMSfxIndex, _ingameGMSoundIndexSize); - _ingameMT32SoundIndex = _staticres->loadRawData(kLolIngameMT32SfxIndex, _ingameMT32SoundIndexSize); - _ingamePCSpeakerSoundIndex = _staticres->loadRawData(kLolIngamePcSpkSfxIndex, _ingamePCSpeakerSoundIndexSize); - _spellProperties = _staticres->loadSpellData(kLolSpellProperties, _spellPropertiesSize); - _gameShapeMap = (const int8 *)_staticres->loadRawData(kLolGameShapeMap, _gameShapeMapSize); - _sceneItemOffs = (const int8 *)_staticres->loadRawData(kLolSceneItemOffs, _sceneItemOffsSize); - _charInvIndex = _staticres->loadRawData(kLolCharInvIndex, _charInvIndexSize); - _charInvDefs = _staticres->loadRawData(kLolCharInvDefs, _charInvDefsSize); - _charDefsMan = _staticres->loadRawDataBe16(kLolCharDefsMan, _charDefsManSize); - _charDefsWoman = _staticres->loadRawDataBe16(kLolCharDefsWoman, _charDefsWomanSize); - _charDefsKieran = _staticres->loadRawDataBe16(kLolCharDefsKieran, _charDefsKieranSize); - _charDefsAkshel = _staticres->loadRawDataBe16(kLolCharDefsAkshel, _charDefsAkshelSize); - _expRequirements = (const int32 *)_staticres->loadRawDataBe32(kLolExpRequirements, _expRequirementsSize); - _monsterModifiers = _staticres->loadRawDataBe16(kLolMonsterModifiers, _monsterModifiersSize); - _monsterShiftOffs = (const int8 *)_staticres->loadRawData(kLolMonsterShiftOffsets, _monsterShiftOffsSize); - _monsterDirFlags = _staticres->loadRawData(kLolMonsterDirFlags, _monsterDirFlagsSize); - _monsterScaleX = _staticres->loadRawData(kLolMonsterScaleX, _monsterScaleXSize); - _monsterScaleY = _staticres->loadRawData(kLolMonsterScaleY, _monsterScaleYSize); - _monsterScaleWH = _staticres->loadRawDataBe16(kLolMonsterScaleWH, _monsterScaleWHSize); - _inventorySlotDesc = _staticres->loadRawDataBe16(kLolInventoryDesc, _inventorySlotDescSize); - _levelShpList = _staticres->loadStrings(kLolLevelShpList, _levelShpListSize); - _levelDatList = _staticres->loadStrings(kLolLevelDatList, _levelDatListSize); - _compassDefs = _staticres->loadCompassData(kLolCompassDefs, _compassDefsSize); - _flyingItemShapes = _staticres->loadFlyingObjectData(kLolFlyingObjectShp, _flyingItemShapesSize); - _itemCost = _staticres->loadRawDataBe16(kLolItemPrices, _itemCostSize); - _stashSetupData = _staticres->loadRawData(kLolStashSetup, _stashSetupDataSize); - - _dscUnk1 = (const int8 *)_staticres->loadRawData(kLolDscUnk1, _dscUnk1Size); - _dscShapeIndex = (const int8 *)_staticres->loadRawData(kLolDscShapeIndex, _dscShapeIndexSize); - _dscOvlMap = _staticres->loadRawData(kLolDscOvlMap, _dscOvlMapSize); - _dscShapeScaleW = _staticres->loadRawDataBe16(kLolDscScaleWidthData, _dscShapeScaleWSize); - _dscShapeScaleH = _staticres->loadRawDataBe16(kLolDscScaleHeightData, _dscShapeScaleHSize); - _dscShapeX = (const int16 *)_staticres->loadRawDataBe16(kLolDscX, _dscShapeXSize); - _dscShapeY = (const int8 *)_staticres->loadRawData(kLolDscY, _dscShapeYSize); - _dscTileIndex = _staticres->loadRawData(kLolDscTileIndex, _dscTileIndexSize); - _dscUnk2 = _staticres->loadRawData(kLolDscUnk2, _dscUnk2Size); - _dscDoorShpIndex = _staticres->loadRawData(kLolDscDoorShapeIndex, _dscDoorShpIndexSize); - _dscDim1 = (const int8 *)_staticres->loadRawData(kLolDscDimData1, _dscDim1Size); - _dscDim2 = (const int8 *)_staticres->loadRawData(kLolDscDimData2, _dscDim2Size); - _dscBlockMap = _staticres->loadRawData(kLolDscBlockMap, _dscBlockMapSize); - _dscDimMap = _staticres->loadRawData(kLolDscDimMap, _dscDimMapSize); - _dscDoorMonsterScaleTable = _staticres->loadRawDataBe16(kLolDscDoorScale, _dscDoorMonsterScaleTableSize); - _dscShapeOvlIndex = _staticres->loadRawData(kLolDscOvlIndex, _dscShapeOvlIndexSize); - _dscDoor4 = _staticres->loadRawDataBe16(kLolDscDoor4, _dscDoor4Size); - _dscBlockIndex = (const int8 *)_staticres->loadRawData(kLolDscBlockIndex, _dscBlockIndexSize); - _dscDoor1 = _staticres->loadRawData(kLolDscDoor1, _dscDoor1Size); - _dscDoorMonsterX = (const int16 *)_staticres->loadRawDataBe16(kLolDscDoorX, _dscDoorMonsterXSize); - _dscDoorMonsterY = (const int16 *)_staticres->loadRawDataBe16(kLolDscDoorY, _dscDoorMonsterYSize); - - _scrollXTop = _staticres->loadRawData(kLolScrollXTop, _scrollXTopSize); - _scrollYTop = _staticres->loadRawData(kLolScrollYTop, _scrollYTopSize); - _scrollXBottom = _staticres->loadRawData(kLolScrollXBottom, _scrollXBottomSize); - _scrollYBottom = _staticres->loadRawData(kLolScrollYBottom, _scrollYBottomSize); - - const char *const *tmpSndList = _staticres->loadStrings(kLolIngameSfxFiles, _ingameSoundListSize); - if (tmpSndList) { - _ingameSoundList = new char *[_ingameSoundListSize]; - for (int i = 0; i < _ingameSoundListSize; i++) { - _ingameSoundList[i] = new char[strlen(tmpSndList[i]) + 1]; - strcpy(_ingameSoundList[i], tmpSndList[i]); - } - _staticres->unloadId(kLolIngameSfxFiles); - } - - _buttonData = _staticres->loadButtonDefs(kLolButtonDefs, _buttonDataSize); - _buttonList1 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList1, _buttonList1Size); - _buttonList2 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList2, _buttonList2Size); - _buttonList3 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList3, _buttonList3Size); - _buttonList4 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList4, _buttonList4Size); - _buttonList5 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList5, _buttonList5Size); - _buttonList6 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList6, _buttonList6Size); - _buttonList7 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList7, _buttonList7Size); - _buttonList8 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList8, _buttonList8Size); - - _autoMapStrings = _staticres->loadRawDataBe16(kLolMapStringId, _autoMapStringsSize); - - int tmpSize = 0; - const uint8 *tmp = _staticres->loadRawData(kLolLegendData, tmpSize); - tmpSize /= 5; - if (tmp) { - _defaultLegendData = new MapLegendData[tmpSize]; - for (int i = 0; i < tmpSize; i++) { - _defaultLegendData[i].shapeIndex = *tmp++; - _defaultLegendData[i].enable = *tmp++ ? true : false; - _defaultLegendData[i].x = (int8)*tmp++; - _defaultLegendData[i].stringId = READ_LE_UINT16(tmp); - tmp += 2; - } - _staticres->unloadId(kLolLegendData); - } - - tmp = _staticres->loadRawData(kLolMapCursorOvl, tmpSize); - _mapCursorOverlay = new uint8[tmpSize]; - memcpy(_mapCursorOverlay, tmp, tmpSize); - _staticres->unloadId(kLolMapCursorOvl); - - _updateSpellBookCoords = _staticres->loadRawData(kLolSpellbookCoords, _updateSpellBookCoordsSize); - _updateSpellBookAnimData = _staticres->loadRawData(kLolSpellbookAnim, _updateSpellBookAnimDataSize); - _healShapeFrames = _staticres->loadRawData(kLolHealShapeFrames, _healShapeFramesSize); - - tmp = _staticres->loadRawData(kLolLightningDefs, tmpSize); - if (tmp) { - _lightningProps = new LightningProperty[5]; - for (int i = 0; i < 5; i++) { - _lightningProps[i].lastFrame = tmp[i << 2]; - _lightningProps[i].frameDiv = tmp[(i << 2) + 1]; - _lightningProps[i].sfxId = READ_LE_UINT16(&tmp[(i << 2) + 2]); - } - _staticres->unloadId(kLolLightningDefs); - } - - _fireBallCoords = (const int16 *)_staticres->loadRawDataBe16(kLolFireballCoords, _fireBallCoordsSize); - - _buttonCallbacks.clear(); - _buttonCallbacks.reserve(95); -#define cb(x) _buttonCallbacks.push_back(BUTTON_FUNCTOR(LoLEngine, this, &LoLEngine::x)) - // 0x00 - cb(clickedUpArrow); - cb(clickedDownArrow); - _buttonCallbacks.push_back(_buttonCallbacks[1]); - cb(clickedLeftArrow); - - // 0x04 - cb(clickedRightArrow); - cb(clickedTurnLeftArrow); - cb(clickedTurnRightArrow); - cb(clickedAttackButton); - - // 0x08 - for (int i = 0; i < 3; ++i) - _buttonCallbacks.push_back(_buttonCallbacks[7]); - cb(clickedMagicButton); - - // 0x0C - for (int i = 0; i < 3; ++i) - _buttonCallbacks.push_back(_buttonCallbacks[11]); - cb(clickedMagicSubmenu); - - // 0x10 - cb(clickedScreen); - cb(clickedPortraitLeft); - for (int i = 0; i < 7; ++i) - _buttonCallbacks.push_back(_buttonCallbacks[17]); - - // 0x19 - cb(clickedLiveMagicBarsLeft); - for (int i = 0; i < 3; ++i) - _buttonCallbacks.push_back(_buttonCallbacks[25]); - - // 0x1D - cb(clickedPortraitEtcRight); - for (int i = 0; i < 3; ++i) - _buttonCallbacks.push_back(_buttonCallbacks[29]); - - // 0x21 - cb(clickedCharInventorySlot); - for (int i = 0; i < 10; ++i) - _buttonCallbacks.push_back(_buttonCallbacks[33]); - - // 0x2C - cb(clickedExitCharInventory); - cb(clickedSceneDropItem); - for (int i = 0; i < 3; ++i) - _buttonCallbacks.push_back(_buttonCallbacks[45]); - - // 0x31 - cb(clickedScenePickupItem); - cb(clickedInventorySlot); - for (int i = 0; i < 9; ++i) - _buttonCallbacks.push_back(_buttonCallbacks[50]); - - // 0x3C - cb(clickedInventoryScroll); - cb(clickedInventoryScroll); - cb(clickedWall); - _buttonCallbacks.push_back(_buttonCallbacks[62]); - - // 0x40 - cb(clickedSequenceWindow); - _buttonCallbacks.push_back(_buttonCallbacks[0]); - _buttonCallbacks.push_back(_buttonCallbacks[1]); - _buttonCallbacks.push_back(_buttonCallbacks[3]); - - // 0x44 - _buttonCallbacks.push_back(_buttonCallbacks[4]); - _buttonCallbacks.push_back(_buttonCallbacks[5]); - _buttonCallbacks.push_back(_buttonCallbacks[6]); - cb(clickedScroll); - - // 0x48 - for (int i = 0; i < 9; ++i) - _buttonCallbacks.push_back(_buttonCallbacks[71]); - - // 0x51 - cb(clickedSpellTargetCharacter); - for (int i = 0; i < 3; ++i) - _buttonCallbacks.push_back(_buttonCallbacks[81]); - - // 0x55 - cb(clickedSpellTargetScene); - cb(clickedSceneThrowItem); - _buttonCallbacks.push_back(_buttonCallbacks[86]); - - // 0x58 - cb(clickedOptions); - cb(clickedRestParty); - cb(clickedMoneyBox); - cb(clickedCompass); - - // 0x5C - cb(clickedAutomap); - cb(clickedLamp); - cb(clickedStatusIcon); -#undef cb -} - -void GUI_LoL::initStaticData() { - GUI_V2_BUTTON(_scrollUpButton, 20, 96, 0, 1, 1, 1, 0x4487, 0, 0, 0, 25, 16, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0); - GUI_V2_BUTTON(_scrollDownButton, 21, 98, 0, 1, 1, 1, 0x4487, 0, 0, 0, 25, 16, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0); - - for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i) - GUI_V2_BUTTON(_menuButtons[i], i, 0, 0, 0, 0, 0, 0x4487, 0, 0, 0, 0, 0, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0); - - if (_vm->gameFlags().isTalkie) - GUI_LOL_MENU(_mainMenu, 9, 0x4000, 0, 7, -1, -1, -1, -1); - else - GUI_LOL_MENU(_mainMenu, 17, 0x4000, 0, 6, -1, -1, -1, -1); - - GUI_LOL_MENU_ITEM(_mainMenu.item[0], 0x4001, 16, 23, 176, 15, 0, 0); - GUI_LOL_MENU_ITEM(_mainMenu.item[1], 0x4002, 16, 40, 176, 15, 0, 0); - GUI_LOL_MENU_ITEM(_mainMenu.item[2], 0x4003, 16, 57, 176, 15, 0, 0); - GUI_LOL_MENU_ITEM(_mainMenu.item[3], 0x4004, 16, 74, 176, 15, 0, 0); - - if (_vm->gameFlags().isTalkie) { - GUI_LOL_MENU_ITEM(_mainMenu.item[4], 0x42D9, 16, 91, 176, 15, 0, 0); - GUI_LOL_MENU_ITEM(_mainMenu.item[5], 0x4006, 16, 108, 176, 15, 0, 0); - GUI_LOL_MENU_ITEM(_mainMenu.item[6], 0x4005, 88, 127, 104, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); - } else { - GUI_LOL_MENU_ITEM(_mainMenu.item[4], 0x4006, 16, 91, 176, 15, 0, 0); - GUI_LOL_MENU_ITEM(_mainMenu.item[5], 0x4005, 88, 110, 104, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); - } - - Button::Callback mainMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedMainMenu); - for (int i = 0; i < _mainMenu.numberOfItems; ++i) - _mainMenu.item[i].callback = mainMenuFunctor; - - GUI_LOL_MENU(_loadMenu, 10, 0x400e, 1, 5, 128, 20, 128, 118); - GUI_LOL_MENU_ITEM(_loadMenu.item[0], 0xfffe, 8, 39, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_loadMenu.item[1], 0xfffd, 8, 56, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_loadMenu.item[2], 0xfffc, 8, 73, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_loadMenu.item[3], 0xfffb, 8, 90, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_loadMenu.item[4], 0x4011, 168, 118, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); - Button::Callback loadMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedLoadMenu); - for (int i = 0; i < 5; ++i) - _loadMenu.item[i].callback = loadMenuFunctor; - - GUI_LOL_MENU(_saveMenu, 10, 0x400d, 1, 5, 128, 20, 128, 118); - GUI_LOL_MENU_ITEM(_saveMenu.item[0], 0xfffe, 8, 39, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_saveMenu.item[1], 0xfffd, 8, 56, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_saveMenu.item[2], 0xfffc, 8, 73, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_saveMenu.item[3], 0xfffb, 8, 90, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_saveMenu.item[4], 0x4011, 168, 118, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); - Button::Callback saveMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedSaveMenu); - for (int i = 0; i < 5; ++i) - _saveMenu.item[i].callback = saveMenuFunctor; - - GUI_LOL_MENU(_deleteMenu, 10, 0x400f, 1, 5, 128, 20, 128, 118); - GUI_LOL_MENU_ITEM(_deleteMenu.item[0], 0xfffe, 8, 39, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_deleteMenu.item[1], 0xfffd, 8, 56, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_deleteMenu.item[2], 0xfffc, 8, 73, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_deleteMenu.item[3], 0xfffb, 8, 90, 256, 15, 0, 0); - GUI_LOL_MENU_ITEM(_deleteMenu.item[4], 0x4011, 168, 118, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); - Button::Callback deleteMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedDeleteMenu); - for (int i = 0; i < 5; ++i) - _deleteMenu.item[i].callback = deleteMenuFunctor; - - GUI_LOL_MENU(_gameOptions, 17, 0x400c, 0, 6, -1, -1, -1, -1); - if (_vm->gameFlags().isTalkie) { - GUI_LOL_MENU_ITEM(_gameOptions.item[0], 0xfff7, 120, 22, 80, 15, 0x406e, 0); - GUI_LOL_MENU_ITEM(_gameOptions.item[1], 0xfff6, 120, 39, 80, 15, 0x406c, 0); - GUI_LOL_MENU_ITEM(_gameOptions.item[2], 0xfff5, 120, 56, 80, 15, 0x406d, 0); - GUI_LOL_MENU_ITEM(_gameOptions.item[3], 0xfff4, 120, 73, 80, 15, 0x42d5, 0); - GUI_LOL_MENU_ITEM(_gameOptions.item[4], 0xfff3, 120, 90, 80, 15, 0x42d2, 0); - GUI_LOL_MENU_ITEM(_gameOptions.item[5], 0x4072, 104, 110, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); - } else { - GUI_LOL_MENU_ITEM(_gameOptions.item[0], 0xfff9, 120, 22, 80, 15, 0x406a, 0); - GUI_LOL_MENU_ITEM(_gameOptions.item[1], 0xfff8, 120, 39, 80, 15, 0x406b, 0); - GUI_LOL_MENU_ITEM(_gameOptions.item[2], 0xfff7, 120, 56, 80, 15, 0x406e, 0); - GUI_LOL_MENU_ITEM(_gameOptions.item[3], 0xfff6, 120, 73, 80, 15, 0x406c, 0); - GUI_LOL_MENU_ITEM(_gameOptions.item[4], 0xfff5, 120, 90, 80, 15, 0x406d, 0); - GUI_LOL_MENU_ITEM(_gameOptions.item[5], 0x4072, 104, 110, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); - } - Button::Callback optionsMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedOptionsMenu); - for (int i = 0; i < _gameOptions.numberOfItems; ++i) - _gameOptions.item[i].callback = optionsMenuFunctor; - - GUI_LOL_MENU(_audioOptions, 18, 0x42d9, 2, 1, -1, -1, -1, -1); - GUI_LOL_MENU_ITEM(_audioOptions.item[0], 0x4072, 152, 76, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); - GUI_LOL_MENU_ITEM(_audioOptions.item[1], 3, 128, 22, 114, 14, 0x42db, 0); - GUI_LOL_MENU_ITEM(_audioOptions.item[2], 4, 128, 39, 114, 14, 0x42da, 0); - GUI_LOL_MENU_ITEM(_audioOptions.item[3], 5, 128, 56, 114, 14, 0x42dc, 0); - Button::Callback audioMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedAudioMenu); - for (int i = 0; i < 4; ++i) - _audioOptions.item[i].callback = audioMenuFunctor; - - GUI_LOL_MENU(_deathMenu, 11, 0x4013, 0, 2, -1, -1, -1, -1); - GUI_LOL_MENU_ITEM(_deathMenu.item[0], 0x4006, 8, 30, 104, 15, 0, 0); - GUI_LOL_MENU_ITEM(_deathMenu.item[1], 0x4001, 176, 30, 104, 15, 0, 0); - Button::Callback deathMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedDeathMenu); - for (int i = 0; i < 2; ++i) - _deathMenu.item[i].callback = deathMenuFunctor; - - GUI_LOL_MENU(_savenameMenu, 7, 0x4053, 0, 2, -1, -1, -1, -1); - GUI_LOL_MENU_ITEM(_savenameMenu.item[0], 0x4012, 8, 38, 72, 15, 0, _vm->_keyMap[Common::KEYCODE_RETURN]); - GUI_LOL_MENU_ITEM(_savenameMenu.item[1], 0x4011, 176, 38, 72, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); - Button::Callback savenameMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedSavenameMenu); - for (int i = 0; i < 2; ++i) - _savenameMenu.item[i].callback = savenameMenuFunctor; - - GUI_LOL_MENU(_choiceMenu, 11, 0, 0, 2, -1, -1, -1, -1); - GUI_LOL_MENU_ITEM(_choiceMenu.item[0], 0x4007, 8, 30, 72, 15, 0, 0); - GUI_LOL_MENU_ITEM(_choiceMenu.item[1], 0x4008, 208, 30, 72, 15, 0, 0); - Button::Callback choiceMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedChoiceMenu); - for (int i = 0; i < 2; ++i) - _choiceMenu.item[i].callback = choiceMenuFunctor; -} - -#endif // ENABLE_LOL - const uint8 Screen_LoK_16::_palette16[48] = { 0x00, 0x00, 0x00, 0x02, 0x07, 0x0B, 0x0C, 0x06, 0x04, 0x0E, 0x09, 0x07, 0x00, 0x06, 0x03, 0x00, 0x0C, 0x07, @@ -2745,263 +2141,5 @@ const int8 KyraEngine_MR::_albumWSAY[] = { -1, -2, 2, 2, -6, -6, -6, 0 }; -// lands of lore static res - -#ifdef ENABLE_LOL -const ScreenDim Screen_LoL::_screenDimTable256C[] = { - { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, // Taken from Intro - { 0x08, 0x48, 0x18, 0x38, 0xFE, 0x01, 0x00, 0x00 }, - { 0x0E, 0x00, 0x16, 0x78, 0xFE, 0x01, 0x00, 0x00 }, - { 0x0B, 0x7B, 0x1C, 0x12, 0xFE, 0xFC, 0x00, 0x00 }, - { 0x0B, 0x7B, 0x1C, 0x2D, 0xFE, 0xFC, 0x00, 0x00 }, - { 0x55, 0x7B, 0xE9, 0x37, 0xFE, 0xFC, 0x00, 0x00 }, - { 0x0B, 0x8C, 0x10, 0x2B, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (4 entries) - { 0x04, 0x59, 0x20, 0x3C, 0x00, 0x00, 0x00, 0x00 }, - { 0x05, 0x6E, 0x1E, 0x0C, 0xFE, 0x01, 0x00, 0x00 }, - { 0x07, 0x19, 0x1A, 0x97, 0x00, 0x00, 0x00, 0x00 }, // Ingame main menu box CD version - { 0x03, 0x1E, 0x22, 0x8C, 0x00, 0x00, 0x00, 0x00 }, - { 0x02, 0x48, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x0E, 0x00, 0x16, 0x78, 0xFE, 0x01, 0x00, 0x00 }, - { 0x0D, 0xA2, 0x18, 0x0C, 0xFE, 0x01, 0x00, 0x00 }, - { 0x0F, 0x06, 0x14, 0x6E, 0x01, 0x00, 0x00, 0x00 }, - { 0x1A, 0xBE, 0x0A, 0x07, 0xFE, 0x01, 0x00, 0x00 }, - { 0x07, 0x21, 0x1A, 0x85, 0x00, 0x00, 0x00, 0x00 }, - { 0x03, 0x32, 0x22, 0x62, 0x00, 0x00, 0x00, 0x00 }, - { 0x0B, 0x8C, 0x10, 0x33, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (5 entries, CD version only) - { 0x0B, 0x8C, 0x10, 0x23, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (3 entries, floppy version only) - - { 0x01, 0x20, 0x26, 0x80, 0xDC, 0xFD, 0x00, 0x00 }, // Credits - { 0x09, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 }, - { 0x19, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 }, - { 0x01, 0x02, 0x26, 0x14, 0x00, 0x0F, 0x0E, 0x00 }, -}; - -const ScreenDim Screen_LoL::_screenDimTable16C[] = { - { 0x00, 0x00, 0x28, 0xC8, 0x33, 0x44, 0x00, 0x00 }, // Taken from Intro - { 0x08, 0x48, 0x18, 0x38, 0x33, 0x44, 0x00, 0x00 }, - { 0x0E, 0x00, 0x16, 0x78, 0x33, 0x44, 0x00, 0x00 }, - { 0x0B, 0x7B, 0x1C, 0x11, 0x33, 0x11, 0x00, 0x00 }, - { 0x0B, 0x7B, 0x1C, 0x2D, 0x33, 0x11, 0x00, 0x00 }, - { 0x55, 0x7B, 0xE9, 0x37, 0x33, 0x11, 0x00, 0x00 }, - { 0x0B, 0x92, 0x10, 0x2A, 0x33, 0x44, 0x00, 0x00 }, // Main menu box (4 entries) - { 0x04, 0x58, 0x20, 0x3C, 0x00, 0x00, 0x00, 0x00 }, - { 0x05, 0x6C, 0x1E, 0x0D, 0x33, 0x44, 0x00, 0x00 }, - { 0x07, 0x20, 0x1A, 0x86, 0x00, 0x00, 0x00, 0x00 }, - { 0x03, 0x20, 0x22, 0x8C, 0x00, 0x00, 0x00, 0x00 }, - { 0x02, 0x48, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x0E, 0x00, 0x16, 0x78, 0x33, 0x44, 0x00, 0x00 }, - { 0x0D, 0xA2, 0x18, 0x0C, 0x33, 0x44, 0x00, 0x00 }, - { 0x0F, 0x06, 0x14, 0x6E, 0x44, 0x00, 0x00, 0x00 }, - { 0x1A, 0xBE, 0x0A, 0x07, 0x33, 0x44, 0x00, 0x00 }, - { 0x07, 0x21, 0x1A, 0x85, 0x00, 0x00, 0x00, 0x00 }, - { 0x03, 0x32, 0x22, 0x62, 0x00, 0x00, 0x00, 0x00 }, - { 0x0B, 0x8C, 0x10, 0x33, 0x33, 0x44, 0x00, 0x00 }, // Main menu box (5 entries, not used here) - { 0x0B, 0x8C, 0x10, 0x23, 0x33, 0x44, 0x00, 0x00 }, // Main menu box (3 entries) - - { 0x01, 0x20, 0x26, 0x80, 0xDC, 0xFD, 0x00, 0x00 }, // Credits (TODO: Check this!) - { 0x09, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 }, - { 0x19, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 }, - { 0x01, 0x02, 0x26, 0x14, 0x00, 0x0F, 0x0E, 0x00 }, -}; - -const int Screen_LoL::_screenDimTableCount = ARRAYSIZE(Screen_LoL::_screenDimTable256C); - -const char * const LoLEngine::_languageExt[] = { - "ENG", - "FRE", - "GER" -}; - -const LoLEngine::CharacterPrev LoLEngine::_charPreviews[] = { - { "Ak\'shel", 0x060, 0x7F, { 0x0F, 0x08, 0x05 } }, - { "Michael", 0x09A, 0x7F, { 0x06, 0x0A, 0x0F } }, - { "Kieran", 0x0D4, 0x7F, { 0x08, 0x06, 0x08 } }, - { "Conrad", 0x10F, 0x7F, { 0x0A, 0x0C, 0x0A } } -}; - -const uint16 LoLEngine::_charPosXPC98[] = { - 92, 152, 212, 268 -}; - -const uint8 LoLEngine::_charNamesPC98[][11] = { - { 0x83, 0x41, 0x83, 0x4E, 0x83, 0x56, 0x83, 0x46, 0x83, 0x8B, 0x00 }, - { 0x83, 0x7D, 0x83, 0x43, 0x83, 0x50, 0x83, 0x8B, 0x00, 0x00, 0x00 }, - { 0x83, 0x4C, 0x81, 0x5B, 0x83, 0x89, 0x83, 0x93, 0x00, 0x00, 0x00 }, - { 0x83, 0x52, 0x83, 0x93, 0x83, 0x89, 0x83, 0x62, 0x83, 0x68, 0x00 } -}; - -const uint8 LoLEngine::_chargenFrameTableTalkie[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x04, 0x03, 0x02, 0x01, - 0x00, 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0x12 -}; - -const uint8 LoLEngine::_chargenFrameTableFloppy[] = { - 0, 1, 2, 3, 4, 5, 4, 3, 2, - 1, 0, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15 -}; - -const uint16 LoLEngine::_selectionPosTable[] = { - 0x6F, 0x00, 0x8F, 0x00, 0xAF, 0x00, 0xCF, 0x00, - 0xEF, 0x00, 0x6F, 0x20, 0x8F, 0x20, 0xAF, 0x20, - 0xCF, 0x20, 0xEF, 0x20, 0x6F, 0x40, 0x8F, 0x40, - 0xAF, 0x40, 0xCF, 0x40, 0xEF, 0x40, 0x10F, 0x00 -}; - -const uint8 LoLEngine::_selectionChar1IdxTable[] = { - 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 5, 5, - 5, 5, 5 -}; - -const uint8 LoLEngine::_selectionChar2IdxTable[] = { - 1, 1, 6, 6, 1, 1, 6, 6, - 6, 6, 6, 6, 6, 1, 1, 6, - 6, 6, 1, 1, 6, 6, 6, 6, - 6, 6, 6 -}; - -const uint8 LoLEngine::_selectionChar3IdxTable[] = { - 2, 2, 7, 7, 7, 7, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 2, - 2, 7, 7, 7, 7, 2, 2, 7, - 7, 7, 7 -}; - -const uint8 LoLEngine::_selectionChar4IdxTable[] = { - 3, 3, 8, 8, 8, 8, 3, 3, - 8, 8, 3, 3, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 3, 3, 8, - 8, 8, 8 -}; - -const uint8 LoLEngine::_reminderChar1IdxTable[] = { - 4, 4, 4, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5 -}; - -const uint8 LoLEngine::_reminderChar2IdxTable[] = { - 9, 9, 9, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6 -}; - -const uint8 LoLEngine::_reminderChar3IdxTable[] = { - 0xE, 0xE, 0xE, 0x7, 0x7, 0x7, 0x7, 0x7, - 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, - 0x7 -}; - -const uint8 LoLEngine::_reminderChar4IdxTable[] = { - 0xF, 0xF, 0xF, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x8 -}; - -const uint8 LoLEngine::_selectionAnimIndexTable[] = { - 0, 5, 1, 6, 2, 7, 3, 8 -}; - -const uint8 LoLEngine::_charInfoFrameTable[] = { - 0x0, 0x7, 0x8, 0x9, 0xA, 0xB, 0xA, 0x9, - 0x8, 0x7, 0x0, 0x0, 0x7, 0x8, 0x9, 0xA, - 0xB, 0xA, 0x9, 0x8, 0x7, 0x0, 0x0, 0x7, - 0x8, 0x9, 0xA, 0xB, 0xA, 0x9, 0x8, 0x7 -}; - -const uint8 LoLEngine::_clock2Timers[] = { - 0x00, 0x10, 0x11, 0x03, 0x04, 0x50, - 0x51, 0x52, 0x08, 0x09, 0x0A -}; - -const uint8 LoLEngine::_numClock2Timers = ARRAYSIZE(LoLEngine::_clock2Timers); - -const int8 LoLEngine::_mapCoords[12][4] = { - { 0, 7, 0, -5 }, { -5, 0, 6, 0 }, { 7, 5, 7, 1 }, - { 5, 6, 4, 6 }, { 0, 7, 0, -1 }, { -3, 0, 6, 0 }, - { 6, 7, 6, -3 }, { -3, 5, 6, 5 }, { 1, 5, 1, 1 }, - { 3, 1, 3, 1 }, { -1, 6, -1, -8 }, { -7, -1, 5, -1 } -}; - -const MistOfDoomAnimData LoLEngine::_mistAnimData[] = { - { 0, 7, 7, 13, 155 }, - { 0, 16, 16, 17, 155 }, - { 0, 24, 24, 24, 174 }, - { 0, 19, 19, 19, 174 }, - { 0, 16, 16, 17, 175 }, -}; - -const char * const LoLEngine::_outroShapeFileTable[] = { - "AMAZON.SHP", "ARCHRSLG.SHP", "AVIANWRM.SHP", "BANDIT.SHP", "BOAR.SHP", "CABAL.SHP", - "GUARD.SHP", "HAG.SHP", "HORNET.SHP", "HURZELL.SHP", "IRONGRZR.SHP", "KNOWLES.SHP", - "LIZARD.SHP", "MANTHA.SHP", "MINOTAUR.SHP", "MORIBUND.SHP", "ORC.SHP", "ORCLDR.SHP", - "PENTROG.SHP", "RATMAN.SHP", "ROCKLING.SHP", "SCAVNGR.SHP", "STARK.SHP", - "SWAMPCIT.SHP", "SWAMPMON.SHP", "THUG.SHP", "VIPER.SHP", "XEOB.SHP" -}; - -const uint8 LoLEngine::_outroFrameTable[] = { - 0, 0, 0, 0, 0, 1, 2, 3, - 0, 1, 2, 3, 8, 9, 10, 11, - 8, 9, 10, 11, 4, 5, 6, 7 -}; - -const int16 LoLEngine::_outroRightMonsterPos[] = { - 205, 55, 205, 55, 205, 55, 205, 55, - 205, 56, 207, 57, 208, 58, 210, 59, - 213, 60, 216, 61, 220, 61, 225, 61, - 230, 61, 235, 61, 240, 61, 240, 61, - 240, 61, 240, 61, 240, 61, 240, 61, - 240, 61, 265, 61, 290, 61, 315, 61 -}; - -const int16 LoLEngine::_outroLeftMonsterPos[] = { - 92, 55, 92, 55, 92, 55, 92, 55, - 92, 56, 90, 57, 85, 58, 77, 59, - 67, 60, 57, 61, 47, 61, 35, 61, - 35, 61, 35, 61, 35, 61, 35, 61, - 35, 61, 35, 61, 35, 61, 35, 61, - 35, 61, 10, 61, -20, 61, -45, 61 -}; - -const int16 LoLEngine::_outroRightDoorPos[] = { - 200, 41, 200, 29, 200, 17, 200, 5, - 200, -7, 200, -7, 200, -7, 200, -7, - 200, 5, 200, 17, 200, 29, 200, 41, - 200, 41, 200, 41, 200, 41, 200, 41, - 200, 41, 200, 41, 200, 41, 200, 41, - 200, 41, 200, 41, 200, 41, 200, 41 -}; - -const int16 LoLEngine::_outroLeftDoorPos[] = { - 72, 41, 72, 29, 72, 17, 72, 5, - 72, -7, 72, -7, 72, -7, 72, -7, - 72, 5, 72, 17, 72, 29, 72, 41, - 72, 41, 72, 41, 72, 41, 72, 41, - 72, 41, 72, 41, 72, 41, 72, 41, - 72, 41, 72, 41, 72, 41, 72, 41 -}; - -const int LoLEngine::_outroMonsterScaleTableX[] = { - 0x050, 0x050, 0x050, 0x050, 0x050, 0x05D, 0x070, 0x085, - 0x0A0, 0x0C0, 0x0E2, 0x100, 0x100, 0x100, 0x100, 0x100, - 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100 -}; - -const int LoLEngine::_outroMonsterScaleTableY[] = { - 0x04C, 0x04C, 0x04C, 0x04C, 0x04C, 0x059, 0x06B, 0x080, - 0x099, 0x0B8, 0x0D9, 0x100, 0x100, 0x100, 0x100, 0x100, - 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100 -}; - -#endif // ENABLE_LOL - } // End of namespace Kyra diff --git a/engines/kyra/staticres_lol.cpp b/engines/kyra/staticres_lol.cpp new file mode 100644 index 0000000000..dbf6808e37 --- /dev/null +++ b/engines/kyra/staticres_lol.cpp @@ -0,0 +1,882 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/resource.h" +#include "kyra/lol.h" +#include "kyra/screen_lol.h" +#include "kyra/gui_lol.h" + +#ifdef ENABLE_LOL + +namespace Kyra { + +const LoLCharacter *StaticResource::loadCharData(int id, int &entries) { + return (const LoLCharacter *)getData(id, kLolCharData, entries); +} + +const SpellProperty *StaticResource::loadSpellData(int id, int &entries) { + return (const SpellProperty *)getData(id, kLolSpellData, entries); +} + +const CompassDef *StaticResource::loadCompassData(int id, int &entries) { + return (const CompassDef *)getData(id, kLolCompassData, entries); +} + +const FlyingObjectShape *StaticResource::loadFlyingObjectData(int id, int &entries) { + return (const FlyingObjectShape *)getData(id, kLolFlightShpData, entries); +} + +const uint16 *StaticResource::loadRawDataBe16(int id, int &entries) { + return (const uint16 *)getData(id, kLolRawDataBe16, entries); +} + +const uint32 *StaticResource::loadRawDataBe32(int id, int &entries) { + return (const uint32 *)getData(id, kLolRawDataBe32, entries); +} + +const ButtonDef *StaticResource::loadButtonDefs(int id, int &entries) { + return (const ButtonDef *)getData(id, kLolButtonData, entries); +} + +bool StaticResource::loadCharData(Common::SeekableReadStream &stream, void *&ptr, int &size) { + size = stream.size() / 130; + LoLCharacter *charData = new LoLCharacter[size]; + + for (int i = 0; i < size; i++) { + LoLCharacter *t = &charData[i]; + + t->flags = stream.readUint16LE(); + stream.read(t->name, 11); + t->raceClassSex = stream.readByte(); + t->id = stream.readSint16LE(); + t->curFaceFrame = stream.readByte(); + t->tempFaceFrame = stream.readByte(); + t->screamSfx = stream.readByte(); + stream.readUint32LE(); + for (int ii = 0; ii < 8; ii++) + t->itemsMight[ii] = stream.readUint16LE(); + for (int ii = 0; ii < 8; ii++) + t->protectionAgainstItems[ii] = stream.readUint16LE(); + t->itemProtection = stream.readUint16LE(); + t->hitPointsCur = stream.readSint16LE(); + t->hitPointsMax = stream.readUint16LE(); + t->magicPointsCur = stream.readSint16LE(); + t->magicPointsMax = stream.readUint16LE(); + t->field_41 = stream.readByte(); + t->damageSuffered = stream.readUint16LE(); + t->weaponHit = stream.readUint16LE(); + t->totalMightModifier = stream.readUint16LE(); + t->totalProtectionModifier = stream.readUint16LE(); + t->might = stream.readUint16LE(); + t->protection = stream.readUint16LE(); + t->nextAnimUpdateCountdown = stream.readSint16LE(); + for (int ii = 0; ii < 11; ii++) + t->items[ii] = stream.readUint16LE(); + for (int ii = 0; ii < 3; ii++) + t->skillLevels[ii] = stream.readByte(); + for (int ii = 0; ii < 3; ii++) + t->skillModifiers[ii] = stream.readByte(); + for (int ii = 0; ii < 3; ii++) + t->experiencePts[ii] = stream.readUint32LE(); + for (int ii = 0; ii < 5; ii++) + t->characterUpdateEvents[ii] = stream.readByte(); + for (int ii = 0; ii < 5; ii++) + t->characterUpdateDelay[ii] = stream.readByte(); + }; + + ptr = charData; + return true; +} + +bool StaticResource::loadSpellData(Common::SeekableReadStream &stream, void *&ptr, int &size) { + size = stream.size() / 28; + SpellProperty *spellData = new SpellProperty[size]; + + for (int i = 0; i < size; i++) { + SpellProperty *t = &spellData[i]; + + t->spellNameCode = stream.readUint16LE(); + for (int ii = 0; ii < 4; ii++) + t->mpRequired[ii] = stream.readUint16LE(); + t->field_a = stream.readUint16LE(); + t->field_c = stream.readUint16LE(); + for (int ii = 0; ii < 4; ii++) + t->hpRequired[ii] = stream.readUint16LE(); + t->field_16 = stream.readUint16LE(); + t->field_18 = stream.readUint16LE(); + t->flags = stream.readUint16LE(); + }; + + ptr = spellData; + return true; +} + +bool StaticResource::loadCompassData(Common::SeekableReadStream &stream, void *&ptr, int &size) { + size = stream.size() / 4; + CompassDef *defs = new CompassDef[size]; + + for (int i = 0; i < size; i++) { + CompassDef *t = &defs[i]; + t->shapeIndex = stream.readByte(); + t->x = stream.readByte(); + t->y = stream.readByte(); + t->flags = stream.readByte(); + }; + + + ptr = defs; + return true; +} + +bool StaticResource::loadFlyingObjectData(Common::SeekableReadStream &stream, void *&ptr, int &size) { + size = stream.size() / 5; + FlyingObjectShape *defs = new FlyingObjectShape[size]; + + for (int i = 0; i < size; i++) { + FlyingObjectShape *t = &defs[i]; + t->shapeFront = stream.readByte(); + t->shapeBack = stream.readByte(); + t->shapeLeft = stream.readByte(); + t->drawFlags = stream.readByte(); + t->flipFlags = stream.readByte(); + }; + + ptr = defs; + return true; +} + +bool StaticResource::loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size) { + size = stream.size() >> 1; + + uint16 *r = new uint16[size]; + + for (int i = 0; i < size; i++) + r[i] = stream.readUint16BE(); + + ptr = r; + return true; +} + +bool StaticResource::loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size) { + size = stream.size() >> 2; + + uint32 *r = new uint32[size]; + + for (int i = 0; i < size; i++) + r[i] = stream.readUint32BE(); + + ptr = r; + return true; +} + +bool StaticResource::loadButtonDefs(Common::SeekableReadStream &stream, void *&ptr, int &size) { + size = stream.size() / 18; + + ButtonDef *r = new ButtonDef[size]; + + for (int i = 0; i < size; i++) { + r[i].buttonflags = stream.readUint16BE(); + r[i].keyCode = stream.readUint16BE(); + r[i].keyCode2 = stream.readUint16BE(); + r[i].x = stream.readSint16BE(); + r[i].y = stream.readSint16BE(); + r[i].w = stream.readUint16BE(); + r[i].h = stream.readUint16BE(); + r[i].index = stream.readUint16BE(); + r[i].screenDim = stream.readUint16BE(); + } + + ptr = r; + return true; +} + +void StaticResource::freeCharData(void *&ptr, int &size) { + LoLCharacter *d = (LoLCharacter *)ptr; + delete[] d; + ptr = 0; + size = 0; +} + +void StaticResource::freeSpellData(void *&ptr, int &size) { + SpellProperty *d = (SpellProperty *)ptr; + delete[] d; + ptr = 0; + size = 0; +} + +void StaticResource::freeCompassData(void *&ptr, int &size) { + CompassDef *d = (CompassDef *)ptr; + delete[] d; + ptr = 0; + size = 0; +} + +void StaticResource::freeFlyingObjectData(void *&ptr, int &size) { + FlyingObjectShape *d = (FlyingObjectShape *)ptr; + delete[] d; + ptr = 0; + size = 0; +} + + +void StaticResource::freeRawDataBe16(void *&ptr, int &size) { + uint16 *data = (uint16 *)ptr; + delete[] data; + ptr = 0; + size = 0; +} + +void StaticResource::freeRawDataBe32(void *&ptr, int &size) { + uint32 *data = (uint32 *)ptr; + delete[] data; + ptr = 0; + size = 0; +} + +void StaticResource::freeButtonDefs(void *&ptr, int &size) { + ButtonDef *d = (ButtonDef *)ptr; + delete[] d; + ptr = 0; + size = 0; +} + +void LoLEngine::initStaticResource() { + // assign music data + static const char *pcMusicFileListIntro[] = { "LOREINTR" }; + static const char *pcMusicFileListFinale[] = { "LOREFINL" }; + static const char *pcMusicFileListIngame[] = { "LORE%02d%c" }; + + static const char *pc98MusicFileListIntro[] = { 0, "lore84.86", "lore82.86", 0, 0, 0, "lore83.86", "lore81.86" }; + static const char *pc98MusicFileListFinale[] = { 0, 0, "lore85.86", "lore86.86", "lore87.86" }; + static const char *pc98MusicFileListIngame[] = { "lore%02d.86" }; + + memset(_soundData, 0, sizeof(_soundData)); + if (_flags.platform == Common::kPlatformPC) { + _soundData[0].fileList = pcMusicFileListIntro; + _soundData[0].fileListLen = ARRAYSIZE(pcMusicFileListIntro); + _soundData[1].fileList = pcMusicFileListIngame; + _soundData[1].fileListLen = ARRAYSIZE(pcMusicFileListIngame); + _soundData[2].fileList = pcMusicFileListFinale; + _soundData[2].fileListLen = ARRAYSIZE(pcMusicFileListFinale); + } else if (_flags.platform == Common::kPlatformPC98) { + _soundData[0].fileList = pc98MusicFileListIntro; + _soundData[0].fileListLen = ARRAYSIZE(pc98MusicFileListIntro); + _soundData[1].fileList = pc98MusicFileListIngame; + _soundData[1].fileListLen = ARRAYSIZE(pc98MusicFileListIngame); + _soundData[2].fileList = pc98MusicFileListFinale; + _soundData[2].fileListLen = ARRAYSIZE(pc98MusicFileListFinale); + } + + if (_flags.isDemo) + return; + + _pakFileList = _staticres->loadStrings(kLolIngamePakFiles, _pakFileListSize); + _charDefaults = _staticres->loadCharData(kLolCharacterDefs, _charDefaultsSize); + _ingameSoundIndex = (const uint16 *)_staticres->loadRawData(kLolIngameSfxIndex, _ingameSoundIndexSize); + _musicTrackMap = _staticres->loadRawData(kLolMusicTrackMap, _musicTrackMapSize); + _ingameGMSoundIndex = _staticres->loadRawData(kLolIngameGMSfxIndex, _ingameGMSoundIndexSize); + _ingameMT32SoundIndex = _staticres->loadRawData(kLolIngameMT32SfxIndex, _ingameMT32SoundIndexSize); + _ingamePCSpeakerSoundIndex = _staticres->loadRawData(kLolIngamePcSpkSfxIndex, _ingamePCSpeakerSoundIndexSize); + _spellProperties = _staticres->loadSpellData(kLolSpellProperties, _spellPropertiesSize); + _gameShapeMap = (const int8 *)_staticres->loadRawData(kLolGameShapeMap, _gameShapeMapSize); + _sceneItemOffs = (const int8 *)_staticres->loadRawData(kLolSceneItemOffs, _sceneItemOffsSize); + _charInvIndex = _staticres->loadRawData(kLolCharInvIndex, _charInvIndexSize); + _charInvDefs = _staticres->loadRawData(kLolCharInvDefs, _charInvDefsSize); + _charDefsMan = _staticres->loadRawDataBe16(kLolCharDefsMan, _charDefsManSize); + _charDefsWoman = _staticres->loadRawDataBe16(kLolCharDefsWoman, _charDefsWomanSize); + _charDefsKieran = _staticres->loadRawDataBe16(kLolCharDefsKieran, _charDefsKieranSize); + _charDefsAkshel = _staticres->loadRawDataBe16(kLolCharDefsAkshel, _charDefsAkshelSize); + _expRequirements = (const int32 *)_staticres->loadRawDataBe32(kLolExpRequirements, _expRequirementsSize); + _monsterModifiers = _staticres->loadRawDataBe16(kLolMonsterModifiers, _monsterModifiersSize); + _monsterShiftOffs = (const int8 *)_staticres->loadRawData(kLolMonsterShiftOffsets, _monsterShiftOffsSize); + _monsterDirFlags = _staticres->loadRawData(kLolMonsterDirFlags, _monsterDirFlagsSize); + _monsterScaleX = _staticres->loadRawData(kLolMonsterScaleX, _monsterScaleXSize); + _monsterScaleY = _staticres->loadRawData(kLolMonsterScaleY, _monsterScaleYSize); + _monsterScaleWH = _staticres->loadRawDataBe16(kLolMonsterScaleWH, _monsterScaleWHSize); + _inventorySlotDesc = _staticres->loadRawDataBe16(kLolInventoryDesc, _inventorySlotDescSize); + _levelShpList = _staticres->loadStrings(kLolLevelShpList, _levelShpListSize); + _levelDatList = _staticres->loadStrings(kLolLevelDatList, _levelDatListSize); + _compassDefs = _staticres->loadCompassData(kLolCompassDefs, _compassDefsSize); + _flyingItemShapes = _staticres->loadFlyingObjectData(kLolFlyingObjectShp, _flyingItemShapesSize); + _itemCost = _staticres->loadRawDataBe16(kLolItemPrices, _itemCostSize); + _stashSetupData = _staticres->loadRawData(kLolStashSetup, _stashSetupDataSize); + + _dscUnk1 = (const int8 *)_staticres->loadRawData(kLolDscUnk1, _dscUnk1Size); + _dscShapeIndex = (const int8 *)_staticres->loadRawData(kLolDscShapeIndex, _dscShapeIndexSize); + _dscOvlMap = _staticres->loadRawData(kLolDscOvlMap, _dscOvlMapSize); + _dscShapeScaleW = _staticres->loadRawDataBe16(kLolDscScaleWidthData, _dscShapeScaleWSize); + _dscShapeScaleH = _staticres->loadRawDataBe16(kLolDscScaleHeightData, _dscShapeScaleHSize); + _dscShapeX = (const int16 *)_staticres->loadRawDataBe16(kLolDscX, _dscShapeXSize); + _dscShapeY = (const int8 *)_staticres->loadRawData(kLolDscY, _dscShapeYSize); + _dscTileIndex = _staticres->loadRawData(kLolDscTileIndex, _dscTileIndexSize); + _dscUnk2 = _staticres->loadRawData(kLolDscUnk2, _dscUnk2Size); + _dscDoorShpIndex = _staticres->loadRawData(kLolDscDoorShapeIndex, _dscDoorShpIndexSize); + _dscDim1 = (const int8 *)_staticres->loadRawData(kLolDscDimData1, _dscDim1Size); + _dscDim2 = (const int8 *)_staticres->loadRawData(kLolDscDimData2, _dscDim2Size); + _dscBlockMap = _staticres->loadRawData(kLolDscBlockMap, _dscBlockMapSize); + _dscDimMap = _staticres->loadRawData(kLolDscDimMap, _dscDimMapSize); + _dscDoorMonsterScaleTable = _staticres->loadRawDataBe16(kLolDscDoorScale, _dscDoorMonsterScaleTableSize); + _dscShapeOvlIndex = _staticres->loadRawData(kLolDscOvlIndex, _dscShapeOvlIndexSize); + _dscDoor4 = _staticres->loadRawDataBe16(kLolDscDoor4, _dscDoor4Size); + _dscBlockIndex = (const int8 *)_staticres->loadRawData(kLolDscBlockIndex, _dscBlockIndexSize); + _dscDoor1 = _staticres->loadRawData(kLolDscDoor1, _dscDoor1Size); + _dscDoorMonsterX = (const int16 *)_staticres->loadRawDataBe16(kLolDscDoorX, _dscDoorMonsterXSize); + _dscDoorMonsterY = (const int16 *)_staticres->loadRawDataBe16(kLolDscDoorY, _dscDoorMonsterYSize); + + _scrollXTop = _staticres->loadRawData(kLolScrollXTop, _scrollXTopSize); + _scrollYTop = _staticres->loadRawData(kLolScrollYTop, _scrollYTopSize); + _scrollXBottom = _staticres->loadRawData(kLolScrollXBottom, _scrollXBottomSize); + _scrollYBottom = _staticres->loadRawData(kLolScrollYBottom, _scrollYBottomSize); + + const char *const *tmpSndList = _staticres->loadStrings(kLolIngameSfxFiles, _ingameSoundListSize); + if (tmpSndList) { + _ingameSoundList = new char *[_ingameSoundListSize]; + for (int i = 0; i < _ingameSoundListSize; i++) { + _ingameSoundList[i] = new char[strlen(tmpSndList[i]) + 1]; + strcpy(_ingameSoundList[i], tmpSndList[i]); + } + _staticres->unloadId(kLolIngameSfxFiles); + } + + _buttonData = _staticres->loadButtonDefs(kLolButtonDefs, _buttonDataSize); + _buttonList1 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList1, _buttonList1Size); + _buttonList2 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList2, _buttonList2Size); + _buttonList3 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList3, _buttonList3Size); + _buttonList4 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList4, _buttonList4Size); + _buttonList5 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList5, _buttonList5Size); + _buttonList6 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList6, _buttonList6Size); + _buttonList7 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList7, _buttonList7Size); + _buttonList8 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList8, _buttonList8Size); + + _autoMapStrings = _staticres->loadRawDataBe16(kLolMapStringId, _autoMapStringsSize); + + int tmpSize = 0; + const uint8 *tmp = _staticres->loadRawData(kLolLegendData, tmpSize); + tmpSize /= 5; + if (tmp) { + _defaultLegendData = new MapLegendData[tmpSize]; + for (int i = 0; i < tmpSize; i++) { + _defaultLegendData[i].shapeIndex = *tmp++; + _defaultLegendData[i].enable = *tmp++ ? true : false; + _defaultLegendData[i].x = (int8)*tmp++; + _defaultLegendData[i].stringId = READ_LE_UINT16(tmp); + tmp += 2; + } + _staticres->unloadId(kLolLegendData); + } + + tmp = _staticres->loadRawData(kLolMapCursorOvl, tmpSize); + _mapCursorOverlay = new uint8[tmpSize]; + memcpy(_mapCursorOverlay, tmp, tmpSize); + _staticres->unloadId(kLolMapCursorOvl); + + _updateSpellBookCoords = _staticres->loadRawData(kLolSpellbookCoords, _updateSpellBookCoordsSize); + _updateSpellBookAnimData = _staticres->loadRawData(kLolSpellbookAnim, _updateSpellBookAnimDataSize); + _healShapeFrames = _staticres->loadRawData(kLolHealShapeFrames, _healShapeFramesSize); + + tmp = _staticres->loadRawData(kLolLightningDefs, tmpSize); + if (tmp) { + _lightningProps = new LightningProperty[5]; + for (int i = 0; i < 5; i++) { + _lightningProps[i].lastFrame = tmp[i << 2]; + _lightningProps[i].frameDiv = tmp[(i << 2) + 1]; + _lightningProps[i].sfxId = READ_LE_UINT16(&tmp[(i << 2) + 2]); + } + _staticres->unloadId(kLolLightningDefs); + } + + _fireBallCoords = (const int16 *)_staticres->loadRawDataBe16(kLolFireballCoords, _fireBallCoordsSize); + + _buttonCallbacks.clear(); + _buttonCallbacks.reserve(95); +#define cb(x) _buttonCallbacks.push_back(BUTTON_FUNCTOR(LoLEngine, this, &LoLEngine::x)) + // 0x00 + cb(clickedUpArrow); + cb(clickedDownArrow); + _buttonCallbacks.push_back(_buttonCallbacks[1]); + cb(clickedLeftArrow); + + // 0x04 + cb(clickedRightArrow); + cb(clickedTurnLeftArrow); + cb(clickedTurnRightArrow); + cb(clickedAttackButton); + + // 0x08 + for (int i = 0; i < 3; ++i) + _buttonCallbacks.push_back(_buttonCallbacks[7]); + cb(clickedMagicButton); + + // 0x0C + for (int i = 0; i < 3; ++i) + _buttonCallbacks.push_back(_buttonCallbacks[11]); + cb(clickedMagicSubmenu); + + // 0x10 + cb(clickedScreen); + cb(clickedPortraitLeft); + for (int i = 0; i < 7; ++i) + _buttonCallbacks.push_back(_buttonCallbacks[17]); + + // 0x19 + cb(clickedLiveMagicBarsLeft); + for (int i = 0; i < 3; ++i) + _buttonCallbacks.push_back(_buttonCallbacks[25]); + + // 0x1D + cb(clickedPortraitEtcRight); + for (int i = 0; i < 3; ++i) + _buttonCallbacks.push_back(_buttonCallbacks[29]); + + // 0x21 + cb(clickedCharInventorySlot); + for (int i = 0; i < 10; ++i) + _buttonCallbacks.push_back(_buttonCallbacks[33]); + + // 0x2C + cb(clickedExitCharInventory); + cb(clickedSceneDropItem); + for (int i = 0; i < 3; ++i) + _buttonCallbacks.push_back(_buttonCallbacks[45]); + + // 0x31 + cb(clickedScenePickupItem); + cb(clickedInventorySlot); + for (int i = 0; i < 9; ++i) + _buttonCallbacks.push_back(_buttonCallbacks[50]); + + // 0x3C + cb(clickedInventoryScroll); + cb(clickedInventoryScroll); + cb(clickedWall); + _buttonCallbacks.push_back(_buttonCallbacks[62]); + + // 0x40 + cb(clickedSequenceWindow); + _buttonCallbacks.push_back(_buttonCallbacks[0]); + _buttonCallbacks.push_back(_buttonCallbacks[1]); + _buttonCallbacks.push_back(_buttonCallbacks[3]); + + // 0x44 + _buttonCallbacks.push_back(_buttonCallbacks[4]); + _buttonCallbacks.push_back(_buttonCallbacks[5]); + _buttonCallbacks.push_back(_buttonCallbacks[6]); + cb(clickedScroll); + + // 0x48 + for (int i = 0; i < 9; ++i) + _buttonCallbacks.push_back(_buttonCallbacks[71]); + + // 0x51 + cb(clickedSpellTargetCharacter); + for (int i = 0; i < 3; ++i) + _buttonCallbacks.push_back(_buttonCallbacks[81]); + + // 0x55 + cb(clickedSpellTargetScene); + cb(clickedSceneThrowItem); + _buttonCallbacks.push_back(_buttonCallbacks[86]); + + // 0x58 + cb(clickedOptions); + cb(clickedRestParty); + cb(clickedMoneyBox); + cb(clickedCompass); + + // 0x5C + cb(clickedAutomap); + cb(clickedLamp); + cb(clickedStatusIcon); +#undef cb +} + +void GUI_LoL::initStaticData() { + GUI_V2_BUTTON(_scrollUpButton, 20, 96, 0, 1, 1, 1, 0x4487, 0, 0, 0, 25, 16, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0); + GUI_V2_BUTTON(_scrollDownButton, 21, 98, 0, 1, 1, 1, 0x4487, 0, 0, 0, 25, 16, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0); + + for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i) + GUI_V2_BUTTON(_menuButtons[i], i, 0, 0, 0, 0, 0, 0x4487, 0, 0, 0, 0, 0, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0); + + if (_vm->gameFlags().isTalkie) + GUI_LOL_MENU(_mainMenu, 9, 0x4000, 0, 7, -1, -1, -1, -1); + else + GUI_LOL_MENU(_mainMenu, 17, 0x4000, 0, 6, -1, -1, -1, -1); + + GUI_LOL_MENU_ITEM(_mainMenu.item[0], 0x4001, 16, 23, 176, 15, 0, 0); + GUI_LOL_MENU_ITEM(_mainMenu.item[1], 0x4002, 16, 40, 176, 15, 0, 0); + GUI_LOL_MENU_ITEM(_mainMenu.item[2], 0x4003, 16, 57, 176, 15, 0, 0); + GUI_LOL_MENU_ITEM(_mainMenu.item[3], 0x4004, 16, 74, 176, 15, 0, 0); + + if (_vm->gameFlags().isTalkie) { + GUI_LOL_MENU_ITEM(_mainMenu.item[4], 0x42D9, 16, 91, 176, 15, 0, 0); + GUI_LOL_MENU_ITEM(_mainMenu.item[5], 0x4006, 16, 108, 176, 15, 0, 0); + GUI_LOL_MENU_ITEM(_mainMenu.item[6], 0x4005, 88, 127, 104, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); + } else { + GUI_LOL_MENU_ITEM(_mainMenu.item[4], 0x4006, 16, 91, 176, 15, 0, 0); + GUI_LOL_MENU_ITEM(_mainMenu.item[5], 0x4005, 88, 110, 104, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); + } + + Button::Callback mainMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedMainMenu); + for (int i = 0; i < _mainMenu.numberOfItems; ++i) + _mainMenu.item[i].callback = mainMenuFunctor; + + GUI_LOL_MENU(_loadMenu, 10, 0x400e, 1, 5, 128, 20, 128, 118); + GUI_LOL_MENU_ITEM(_loadMenu.item[0], 0xfffe, 8, 39, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_loadMenu.item[1], 0xfffd, 8, 56, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_loadMenu.item[2], 0xfffc, 8, 73, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_loadMenu.item[3], 0xfffb, 8, 90, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_loadMenu.item[4], 0x4011, 168, 118, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); + Button::Callback loadMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedLoadMenu); + for (int i = 0; i < 5; ++i) + _loadMenu.item[i].callback = loadMenuFunctor; + + GUI_LOL_MENU(_saveMenu, 10, 0x400d, 1, 5, 128, 20, 128, 118); + GUI_LOL_MENU_ITEM(_saveMenu.item[0], 0xfffe, 8, 39, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_saveMenu.item[1], 0xfffd, 8, 56, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_saveMenu.item[2], 0xfffc, 8, 73, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_saveMenu.item[3], 0xfffb, 8, 90, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_saveMenu.item[4], 0x4011, 168, 118, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); + Button::Callback saveMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedSaveMenu); + for (int i = 0; i < 5; ++i) + _saveMenu.item[i].callback = saveMenuFunctor; + + GUI_LOL_MENU(_deleteMenu, 10, 0x400f, 1, 5, 128, 20, 128, 118); + GUI_LOL_MENU_ITEM(_deleteMenu.item[0], 0xfffe, 8, 39, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_deleteMenu.item[1], 0xfffd, 8, 56, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_deleteMenu.item[2], 0xfffc, 8, 73, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_deleteMenu.item[3], 0xfffb, 8, 90, 256, 15, 0, 0); + GUI_LOL_MENU_ITEM(_deleteMenu.item[4], 0x4011, 168, 118, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); + Button::Callback deleteMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedDeleteMenu); + for (int i = 0; i < 5; ++i) + _deleteMenu.item[i].callback = deleteMenuFunctor; + + GUI_LOL_MENU(_gameOptions, 17, 0x400c, 0, 6, -1, -1, -1, -1); + if (_vm->gameFlags().isTalkie) { + GUI_LOL_MENU_ITEM(_gameOptions.item[0], 0xfff7, 120, 22, 80, 15, 0x406e, 0); + GUI_LOL_MENU_ITEM(_gameOptions.item[1], 0xfff6, 120, 39, 80, 15, 0x406c, 0); + GUI_LOL_MENU_ITEM(_gameOptions.item[2], 0xfff5, 120, 56, 80, 15, 0x406d, 0); + GUI_LOL_MENU_ITEM(_gameOptions.item[3], 0xfff4, 120, 73, 80, 15, 0x42d5, 0); + GUI_LOL_MENU_ITEM(_gameOptions.item[4], 0xfff3, 120, 90, 80, 15, 0x42d2, 0); + GUI_LOL_MENU_ITEM(_gameOptions.item[5], 0x4072, 104, 110, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); + } else { + GUI_LOL_MENU_ITEM(_gameOptions.item[0], 0xfff9, 120, 22, 80, 15, 0x406a, 0); + GUI_LOL_MENU_ITEM(_gameOptions.item[1], 0xfff8, 120, 39, 80, 15, 0x406b, 0); + GUI_LOL_MENU_ITEM(_gameOptions.item[2], 0xfff7, 120, 56, 80, 15, 0x406e, 0); + GUI_LOL_MENU_ITEM(_gameOptions.item[3], 0xfff6, 120, 73, 80, 15, 0x406c, 0); + GUI_LOL_MENU_ITEM(_gameOptions.item[4], 0xfff5, 120, 90, 80, 15, 0x406d, 0); + GUI_LOL_MENU_ITEM(_gameOptions.item[5], 0x4072, 104, 110, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); + } + Button::Callback optionsMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedOptionsMenu); + for (int i = 0; i < _gameOptions.numberOfItems; ++i) + _gameOptions.item[i].callback = optionsMenuFunctor; + + GUI_LOL_MENU(_audioOptions, 18, 0x42d9, 2, 1, -1, -1, -1, -1); + GUI_LOL_MENU_ITEM(_audioOptions.item[0], 0x4072, 152, 76, 96, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); + GUI_LOL_MENU_ITEM(_audioOptions.item[1], 3, 128, 22, 114, 14, 0x42db, 0); + GUI_LOL_MENU_ITEM(_audioOptions.item[2], 4, 128, 39, 114, 14, 0x42da, 0); + GUI_LOL_MENU_ITEM(_audioOptions.item[3], 5, 128, 56, 114, 14, 0x42dc, 0); + Button::Callback audioMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedAudioMenu); + for (int i = 0; i < 4; ++i) + _audioOptions.item[i].callback = audioMenuFunctor; + + GUI_LOL_MENU(_deathMenu, 11, 0x4013, 0, 2, -1, -1, -1, -1); + GUI_LOL_MENU_ITEM(_deathMenu.item[0], 0x4006, 8, 30, 104, 15, 0, 0); + GUI_LOL_MENU_ITEM(_deathMenu.item[1], 0x4001, 176, 30, 104, 15, 0, 0); + Button::Callback deathMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedDeathMenu); + for (int i = 0; i < 2; ++i) + _deathMenu.item[i].callback = deathMenuFunctor; + + GUI_LOL_MENU(_savenameMenu, 7, 0x4053, 0, 2, -1, -1, -1, -1); + GUI_LOL_MENU_ITEM(_savenameMenu.item[0], 0x4012, 8, 38, 72, 15, 0, _vm->_keyMap[Common::KEYCODE_RETURN]); + GUI_LOL_MENU_ITEM(_savenameMenu.item[1], 0x4011, 176, 38, 72, 15, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); + Button::Callback savenameMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedSavenameMenu); + for (int i = 0; i < 2; ++i) + _savenameMenu.item[i].callback = savenameMenuFunctor; + + GUI_LOL_MENU(_choiceMenu, 11, 0, 0, 2, -1, -1, -1, -1); + GUI_LOL_MENU_ITEM(_choiceMenu.item[0], 0x4007, 8, 30, 72, 15, 0, 0); + GUI_LOL_MENU_ITEM(_choiceMenu.item[1], 0x4008, 208, 30, 72, 15, 0, 0); + Button::Callback choiceMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedChoiceMenu); + for (int i = 0; i < 2; ++i) + _choiceMenu.item[i].callback = choiceMenuFunctor; +} + +const ScreenDim Screen_LoL::_screenDimTable256C[] = { + { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, // Taken from Intro + { 0x08, 0x48, 0x18, 0x38, 0xFE, 0x01, 0x00, 0x00 }, + { 0x0E, 0x00, 0x16, 0x78, 0xFE, 0x01, 0x00, 0x00 }, + { 0x0B, 0x7B, 0x1C, 0x12, 0xFE, 0xFC, 0x00, 0x00 }, + { 0x0B, 0x7B, 0x1C, 0x2D, 0xFE, 0xFC, 0x00, 0x00 }, + { 0x55, 0x7B, 0xE9, 0x37, 0xFE, 0xFC, 0x00, 0x00 }, + { 0x0B, 0x8C, 0x10, 0x2B, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (4 entries) + { 0x04, 0x59, 0x20, 0x3C, 0x00, 0x00, 0x00, 0x00 }, + { 0x05, 0x6E, 0x1E, 0x0C, 0xFE, 0x01, 0x00, 0x00 }, + { 0x07, 0x19, 0x1A, 0x97, 0x00, 0x00, 0x00, 0x00 }, // Ingame main menu box CD version + { 0x03, 0x1E, 0x22, 0x8C, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0x48, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x0E, 0x00, 0x16, 0x78, 0xFE, 0x01, 0x00, 0x00 }, + { 0x0D, 0xA2, 0x18, 0x0C, 0xFE, 0x01, 0x00, 0x00 }, + { 0x0F, 0x06, 0x14, 0x6E, 0x01, 0x00, 0x00, 0x00 }, + { 0x1A, 0xBE, 0x0A, 0x07, 0xFE, 0x01, 0x00, 0x00 }, + { 0x07, 0x21, 0x1A, 0x85, 0x00, 0x00, 0x00, 0x00 }, + { 0x03, 0x32, 0x22, 0x62, 0x00, 0x00, 0x00, 0x00 }, + { 0x0B, 0x8C, 0x10, 0x33, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (5 entries, CD version only) + { 0x0B, 0x8C, 0x10, 0x23, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (3 entries, floppy version only) + + { 0x01, 0x20, 0x26, 0x80, 0xDC, 0xFD, 0x00, 0x00 }, // Credits + { 0x09, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 }, + { 0x19, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 }, + { 0x01, 0x02, 0x26, 0x14, 0x00, 0x0F, 0x0E, 0x00 }, +}; + +const ScreenDim Screen_LoL::_screenDimTable16C[] = { + { 0x00, 0x00, 0x28, 0xC8, 0x33, 0x44, 0x00, 0x00 }, // Taken from Intro + { 0x08, 0x48, 0x18, 0x38, 0x33, 0x44, 0x00, 0x00 }, + { 0x0E, 0x00, 0x16, 0x78, 0x33, 0x44, 0x00, 0x00 }, + { 0x0B, 0x7B, 0x1C, 0x11, 0x33, 0x11, 0x00, 0x00 }, + { 0x0B, 0x7B, 0x1C, 0x2D, 0x33, 0x11, 0x00, 0x00 }, + { 0x55, 0x7B, 0xE9, 0x37, 0x33, 0x11, 0x00, 0x00 }, + { 0x0B, 0x92, 0x10, 0x2A, 0x33, 0x44, 0x00, 0x00 }, // Main menu box (4 entries) + { 0x04, 0x58, 0x20, 0x3C, 0x00, 0x00, 0x00, 0x00 }, + { 0x05, 0x6C, 0x1E, 0x0D, 0x33, 0x44, 0x00, 0x00 }, + { 0x07, 0x20, 0x1A, 0x86, 0x00, 0x00, 0x00, 0x00 }, + { 0x03, 0x20, 0x22, 0x8C, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0x48, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x0E, 0x00, 0x16, 0x78, 0x33, 0x44, 0x00, 0x00 }, + { 0x0D, 0xA2, 0x18, 0x0C, 0x33, 0x44, 0x00, 0x00 }, + { 0x0F, 0x06, 0x14, 0x6E, 0x44, 0x00, 0x00, 0x00 }, + { 0x1A, 0xBE, 0x0A, 0x07, 0x33, 0x44, 0x00, 0x00 }, + { 0x07, 0x21, 0x1A, 0x85, 0x00, 0x00, 0x00, 0x00 }, + { 0x03, 0x32, 0x22, 0x62, 0x00, 0x00, 0x00, 0x00 }, + { 0x0B, 0x8C, 0x10, 0x33, 0x33, 0x44, 0x00, 0x00 }, // Main menu box (5 entries, not used here) + { 0x0B, 0x8C, 0x10, 0x23, 0x33, 0x44, 0x00, 0x00 }, // Main menu box (3 entries) + + { 0x01, 0x20, 0x26, 0x80, 0xDC, 0xFD, 0x00, 0x00 }, // Credits (TODO: Check this!) + { 0x09, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 }, + { 0x19, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 }, + { 0x01, 0x02, 0x26, 0x14, 0x00, 0x0F, 0x0E, 0x00 }, +}; + +const int Screen_LoL::_screenDimTableCount = ARRAYSIZE(Screen_LoL::_screenDimTable256C); + +const char * const LoLEngine::_languageExt[] = { + "ENG", + "FRE", + "GER" +}; + +const LoLEngine::CharacterPrev LoLEngine::_charPreviews[] = { + { "Ak\'shel", 0x060, 0x7F, { 0x0F, 0x08, 0x05 } }, + { "Michael", 0x09A, 0x7F, { 0x06, 0x0A, 0x0F } }, + { "Kieran", 0x0D4, 0x7F, { 0x08, 0x06, 0x08 } }, + { "Conrad", 0x10F, 0x7F, { 0x0A, 0x0C, 0x0A } } +}; + +const uint16 LoLEngine::_charPosXPC98[] = { + 92, 152, 212, 268 +}; + +const uint8 LoLEngine::_charNamesPC98[][11] = { + { 0x83, 0x41, 0x83, 0x4E, 0x83, 0x56, 0x83, 0x46, 0x83, 0x8B, 0x00 }, + { 0x83, 0x7D, 0x83, 0x43, 0x83, 0x50, 0x83, 0x8B, 0x00, 0x00, 0x00 }, + { 0x83, 0x4C, 0x81, 0x5B, 0x83, 0x89, 0x83, 0x93, 0x00, 0x00, 0x00 }, + { 0x83, 0x52, 0x83, 0x93, 0x83, 0x89, 0x83, 0x62, 0x83, 0x68, 0x00 } +}; + +const uint8 LoLEngine::_chargenFrameTableTalkie[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x04, 0x03, 0x02, 0x01, + 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0x12 +}; + +const uint8 LoLEngine::_chargenFrameTableFloppy[] = { + 0, 1, 2, 3, 4, 5, 4, 3, 2, + 1, 0, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15 +}; + +const uint16 LoLEngine::_selectionPosTable[] = { + 0x6F, 0x00, 0x8F, 0x00, 0xAF, 0x00, 0xCF, 0x00, + 0xEF, 0x00, 0x6F, 0x20, 0x8F, 0x20, 0xAF, 0x20, + 0xCF, 0x20, 0xEF, 0x20, 0x6F, 0x40, 0x8F, 0x40, + 0xAF, 0x40, 0xCF, 0x40, 0xEF, 0x40, 0x10F, 0x00 +}; + +const uint8 LoLEngine::_selectionChar1IdxTable[] = { + 0, 0, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 0, 0, 5, 5, 5, + 5, 5, 5, 5, 0, 0, 5, 5, + 5, 5, 5 +}; + +const uint8 LoLEngine::_selectionChar2IdxTable[] = { + 1, 1, 6, 6, 1, 1, 6, 6, + 6, 6, 6, 6, 6, 1, 1, 6, + 6, 6, 1, 1, 6, 6, 6, 6, + 6, 6, 6 +}; + +const uint8 LoLEngine::_selectionChar3IdxTable[] = { + 2, 2, 7, 7, 7, 7, 2, 2, + 7, 7, 7, 7, 7, 7, 7, 2, + 2, 7, 7, 7, 7, 2, 2, 7, + 7, 7, 7 +}; + +const uint8 LoLEngine::_selectionChar4IdxTable[] = { + 3, 3, 8, 8, 8, 8, 3, 3, + 8, 8, 3, 3, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 3, 3, 8, + 8, 8, 8 +}; + +const uint8 LoLEngine::_reminderChar1IdxTable[] = { + 4, 4, 4, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5 +}; + +const uint8 LoLEngine::_reminderChar2IdxTable[] = { + 9, 9, 9, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6 +}; + +const uint8 LoLEngine::_reminderChar3IdxTable[] = { + 0xE, 0xE, 0xE, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x7 +}; + +const uint8 LoLEngine::_reminderChar4IdxTable[] = { + 0xF, 0xF, 0xF, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x8 +}; + +const uint8 LoLEngine::_selectionAnimIndexTable[] = { + 0, 5, 1, 6, 2, 7, 3, 8 +}; + +const uint8 LoLEngine::_charInfoFrameTable[] = { + 0x0, 0x7, 0x8, 0x9, 0xA, 0xB, 0xA, 0x9, + 0x8, 0x7, 0x0, 0x0, 0x7, 0x8, 0x9, 0xA, + 0xB, 0xA, 0x9, 0x8, 0x7, 0x0, 0x0, 0x7, + 0x8, 0x9, 0xA, 0xB, 0xA, 0x9, 0x8, 0x7 +}; + +const uint8 LoLEngine::_clock2Timers[] = { + 0x00, 0x10, 0x11, 0x03, 0x04, 0x50, + 0x51, 0x52, 0x08, 0x09, 0x0A +}; + +const uint8 LoLEngine::_numClock2Timers = ARRAYSIZE(LoLEngine::_clock2Timers); + +const int8 LoLEngine::_mapCoords[12][4] = { + { 0, 7, 0, -5 }, { -5, 0, 6, 0 }, { 7, 5, 7, 1 }, + { 5, 6, 4, 6 }, { 0, 7, 0, -1 }, { -3, 0, 6, 0 }, + { 6, 7, 6, -3 }, { -3, 5, 6, 5 }, { 1, 5, 1, 1 }, + { 3, 1, 3, 1 }, { -1, 6, -1, -8 }, { -7, -1, 5, -1 } +}; + +const MistOfDoomAnimData LoLEngine::_mistAnimData[] = { + { 0, 7, 7, 13, 155 }, + { 0, 16, 16, 17, 155 }, + { 0, 24, 24, 24, 174 }, + { 0, 19, 19, 19, 174 }, + { 0, 16, 16, 17, 175 }, +}; + +const char * const LoLEngine::_outroShapeFileTable[] = { + "AMAZON.SHP", "ARCHRSLG.SHP", "AVIANWRM.SHP", "BANDIT.SHP", "BOAR.SHP", "CABAL.SHP", + "GUARD.SHP", "HAG.SHP", "HORNET.SHP", "HURZELL.SHP", "IRONGRZR.SHP", "KNOWLES.SHP", + "LIZARD.SHP", "MANTHA.SHP", "MINOTAUR.SHP", "MORIBUND.SHP", "ORC.SHP", "ORCLDR.SHP", + "PENTROG.SHP", "RATMAN.SHP", "ROCKLING.SHP", "SCAVNGR.SHP", "STARK.SHP", + "SWAMPCIT.SHP", "SWAMPMON.SHP", "THUG.SHP", "VIPER.SHP", "XEOB.SHP" +}; + +const uint8 LoLEngine::_outroFrameTable[] = { + 0, 0, 0, 0, 0, 1, 2, 3, + 0, 1, 2, 3, 8, 9, 10, 11, + 8, 9, 10, 11, 4, 5, 6, 7 +}; + +const int16 LoLEngine::_outroRightMonsterPos[] = { + 205, 55, 205, 55, 205, 55, 205, 55, + 205, 56, 207, 57, 208, 58, 210, 59, + 213, 60, 216, 61, 220, 61, 225, 61, + 230, 61, 235, 61, 240, 61, 240, 61, + 240, 61, 240, 61, 240, 61, 240, 61, + 240, 61, 265, 61, 290, 61, 315, 61 +}; + +const int16 LoLEngine::_outroLeftMonsterPos[] = { + 92, 55, 92, 55, 92, 55, 92, 55, + 92, 56, 90, 57, 85, 58, 77, 59, + 67, 60, 57, 61, 47, 61, 35, 61, + 35, 61, 35, 61, 35, 61, 35, 61, + 35, 61, 35, 61, 35, 61, 35, 61, + 35, 61, 10, 61, -20, 61, -45, 61 +}; + +const int16 LoLEngine::_outroRightDoorPos[] = { + 200, 41, 200, 29, 200, 17, 200, 5, + 200, -7, 200, -7, 200, -7, 200, -7, + 200, 5, 200, 17, 200, 29, 200, 41, + 200, 41, 200, 41, 200, 41, 200, 41, + 200, 41, 200, 41, 200, 41, 200, 41, + 200, 41, 200, 41, 200, 41, 200, 41 +}; + +const int16 LoLEngine::_outroLeftDoorPos[] = { + 72, 41, 72, 29, 72, 17, 72, 5, + 72, -7, 72, -7, 72, -7, 72, -7, + 72, 5, 72, 17, 72, 29, 72, 41, + 72, 41, 72, 41, 72, 41, 72, 41, + 72, 41, 72, 41, 72, 41, 72, 41, + 72, 41, 72, 41, 72, 41, 72, 41 +}; + +const int LoLEngine::_outroMonsterScaleTableX[] = { + 0x050, 0x050, 0x050, 0x050, 0x050, 0x05D, 0x070, 0x085, + 0x0A0, 0x0C0, 0x0E2, 0x100, 0x100, 0x100, 0x100, 0x100, + 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100 +}; + +const int LoLEngine::_outroMonsterScaleTableY[] = { + 0x04C, 0x04C, 0x04C, 0x04C, 0x04C, 0x059, 0x06B, 0x080, + 0x099, 0x0B8, 0x0D9, 0x100, 0x100, 0x100, 0x100, 0x100, + 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100 +}; + +} // End of namespace Kyra + +#endif + diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp index 3e45c0f286..79b16bc1be 100644 --- a/engines/kyra/text_lok.cpp +++ b/engines/kyra/text_lok.cpp @@ -137,8 +137,11 @@ void KyraEngine_LoK::endCharacterChat(int8 charNum, int16 convoInitialized) { _charSayUnk3 = -1; if (charNum > 4 && charNum < 11) { - //TODO: weird _game_inventory stuff here - //warning("STUB: endCharacterChat() for high charnums"); + _animator->sprites()[_disabledTalkAnimObject].active = 1; + _sprites->_anims[_disabledTalkAnimObject].play = true; + + _animator->sprites()[_enabledTalkAnimObject].active = 0; + _sprites->_anims[_enabledTalkAnimObject].play = false; } if (convoInitialized != 0) { @@ -225,8 +228,19 @@ int KyraEngine_LoK::initCharacterChat(int8 charNum) { _animator->restoreAllObjectBackgrounds(); if (charNum > 4 && charNum < 11) { - // TODO: Fill in weird _game_inventory stuff here - //warning("STUB: initCharacterChat() for high charnums"); + const uint8 animDisableTable[] = { 3, 1, 1, 5, 0, 6 }; + const uint8 animEnableTable[] = { 4, 2, 5, 6, 1, 7 }; + + _disabledTalkAnimObject = animDisableTable[charNum - 5]; + _enabledTalkAnimObject = animEnableTable[charNum - 5]; + + _animator->sprites()[_disabledTalkAnimObject].active = 0; + _sprites->_anims[_disabledTalkAnimObject].play = false; + + _animator->sprites()[_enabledTalkAnimObject].active = 1; + _sprites->_anims[_enabledTalkAnimObject].play = true; + + _charSayUnk2 = _enabledTalkAnimObject; } _animator->flagAllObjectsForRefresh(); diff --git a/engines/kyra/timer_lok.cpp b/engines/kyra/timer_lok.cpp index 3a7d1ed0de..40426a3dfe 100644 --- a/engines/kyra/timer_lok.cpp +++ b/engines/kyra/timer_lok.cpp @@ -48,33 +48,39 @@ void KyraEngine_LoK::setupTimers() { for (int i = 10; i <= 13; ++i) _timer->addTimer(i, 0, 420, 1); - _timer->addTimer(14, TimerV1(timerCheckAnimFlag2), 600, 1); + _timer->addTimer(14, TimerV1(timerAsWillowispTimeout), 600, 1); _timer->addTimer(15, TimerV1(timerUpdateHeadAnims), 11, 1); - _timer->addTimer(16, TimerV1(timerSetFlags1), 7200, 1); - _timer->addTimer(17, 0 /*sub_15120*/, 7200, 1); - _timer->addTimer(18, TimerV1(timerCheckAnimFlag1), 600, 1); + _timer->addTimer(16, TimerV1(timerTulipCreator), 7200, 1); + _timer->addTimer(17, TimerV1(timerRubyCreator), 7200, 1); + _timer->addTimer(18, TimerV1(timerAsInvisibleTimeout), 600, 1); _timer->addTimer(19, TimerV1(timerRedrawAmulet), 600, 1); _timer->addTimer(20, 0, 7200, 1); - _timer->addTimer(21, 0/*sub_1517C*/, 18000, 1); + _timer->addTimer(21, TimerV1(timerLavenderRoseCreator), 18000, 1); _timer->addTimer(22, 0, 7200, 1); - for (int i = 23; i <= 27; ++i) - _timer->addTimer(i, 0, 10800, 1); + _timer->addTimer(23, 0, 10800, 1); + _timer->addTimer(24, TimerV1(timerAcornCreator), 10800, 1); + _timer->addTimer(25, 0, 10800, 1); + _timer->addTimer(26, TimerV1(timerBlueberryCreator), 10800, 1); + _timer->addTimer(27, 0, 10800, 1); _timer->addTimer(28, 0, 21600, 1); _timer->addTimer(29, 0, 7200, 1); _timer->addTimer(30, 0, 10800, 1); _timer->addTimer(31, TimerV1(timerFadeText), -1, 1); - _timer->addTimer(32, TimerV1(updateAnimFlag1), 9, 1); - _timer->addTimer(33, TimerV1(updateAnimFlag2), 3, 1); + _timer->addTimer(32, TimerV1(timerWillowispFrameTimer), 9, 1); + _timer->addTimer(33, TimerV1(timerInvisibleFrameTimer), 3, 1); } void KyraEngine_LoK::timerUpdateHeadAnims(int timerNum) { static int8 currentFrame = 0; - static const int8 frameTable[] = {4, 5, 4, 5, 4, 5, 0, 1, 4, 5, - 4, 4, 6, 4, 8, 1, 9, 4, -1}; + static const int8 frameTable[] = { + 4, 5, 4, 5, 4, 5, 0, 1, + 4, 5, 4, 4, 6, 4, 8, 1, + 9, 4, -1 + }; if (_talkingCharNum < 0) return; @@ -89,19 +95,51 @@ void KyraEngine_LoK::timerUpdateHeadAnims(int timerNum) { _animator->animRefreshNPC(_talkingCharNum); } -void KyraEngine_LoK::timerSetFlags1(int timerNum) { +void KyraEngine_LoK::timerTulipCreator(int timerNum) { if (_currentCharacter->sceneId == 0x1C) return; - int rndNr = _rnd.getRandomNumberRng(0, 3); + setItemCreationFlags(17, 3); +} + +void KyraEngine_LoK::timerRubyCreator(int timerNum) { + if (_currentCharacter->sceneId == 0x23) + return; + + setItemCreationFlags(22, 4); +} + +void KyraEngine_LoK::timerLavenderRoseCreator(int timerNum) { + if (_currentCharacter->sceneId == 0x06) + return; + + setItemCreationFlags(0, 4); +} - for (int i = 0; i < 4; i++) { - if (!queryGameFlag(rndNr + 17)) { - setGameFlag(rndNr + 17); +void KyraEngine_LoK::timerAcornCreator(int timerNum) { + if (_currentCharacter->sceneId == 0x1F) + return; + + setItemCreationFlags(72, 5); +} + +void KyraEngine_LoK::timerBlueberryCreator(int timerNum) { + if (_currentCharacter->sceneId == 0x28) + return; + + setItemCreationFlags(26, 7); +} + +void KyraEngine_LoK::setItemCreationFlags(int offset, int count) { + int rndNr = _rnd.getRandomNumberRng(0, count); + + for (int i = 0; i <= count; i++) { + if (!queryGameFlag(rndNr + offset)) { + setGameFlag(rndNr + offset); break; } else { rndNr++; - if (rndNr > 3) + if (rndNr > count) rndNr = 0; } } @@ -111,16 +149,14 @@ void KyraEngine_LoK::timerFadeText(int timerNum) { _fadeText = true; } -void KyraEngine_LoK::updateAnimFlag1(int timerNum) { - if (_brandonStatusBit & 2) { +void KyraEngine_LoK::timerWillowispFrameTimer(int timerNum) { + if (_brandonStatusBit & 2) _brandonStatusBit0x02Flag = 1; - } } -void KyraEngine_LoK::updateAnimFlag2(int timerNum) { - if (_brandonStatusBit & 0x20) { +void KyraEngine_LoK::timerInvisibleFrameTimer(int timerNum) { + if (_brandonStatusBit & 0x20) _brandonStatusBit0x20Flag = 1; - } } void KyraEngine_LoK::setTextFadeTimerCountdown(int16 countdown) { @@ -130,19 +166,14 @@ void KyraEngine_LoK::setTextFadeTimerCountdown(int16 countdown) { _timer->setCountdown(31, countdown*60); } -void KyraEngine_LoK::timerSetFlags2(int timerNum) { - if (!((uint32 *)(_flagsTable+0x2D))[timerNum]) - ((uint32 *)(_flagsTable+0x2D))[timerNum] = 1; -} - -void KyraEngine_LoK::timerCheckAnimFlag1(int timerNum) { +void KyraEngine_LoK::timerAsInvisibleTimeout(int timerNum) { if (_brandonStatusBit & 0x20) { checkAmuletAnimFlags(); _timer->setCountdown(18, -1); } } -void KyraEngine_LoK::timerCheckAnimFlag2(int timerNum) { +void KyraEngine_LoK::timerAsWillowispTimeout(int timerNum) { if (_brandonStatusBit & 0x2) { checkAmuletAnimFlags(); _timer->setCountdown(14, -1); diff --git a/engines/kyra/vqa.cpp b/engines/kyra/vqa.cpp index 8a598591bb..d0e54f996b 100644 --- a/engines/kyra/vqa.cpp +++ b/engines/kyra/vqa.cpp @@ -260,8 +260,8 @@ bool VQAMovie::open(const char *filename) { _header.bits = 8; } - setX((Screen::SCREEN_W - _header.width) / 2); - setY((Screen::SCREEN_H - _header.height) / 2); + _x = (Screen::SCREEN_W - _header.width) / 2; + _y = (Screen::SCREEN_H - _header.height) / 2; _frameInfo = new uint32[_header.numFrames]; _frame = new byte[_header.width * _header.height]; diff --git a/engines/kyra/vqa.h b/engines/kyra/vqa.h index c1448a4865..129d526e98 100644 --- a/engines/kyra/vqa.h +++ b/engines/kyra/vqa.h @@ -56,9 +56,6 @@ public: // It's unlikely that we ever want to change the movie position from // its default. - void setX(int x) { _x = x; } - void setY(int y) { _y = y; } - void setDrawPage(int page) { _drawPage = page; } bool open(const char *filename); diff --git a/engines/lure/debugger.cpp b/engines/lure/debugger.cpp index 3abc079a05..1cfe0804e4 100644 --- a/engines/lure/debugger.cpp +++ b/engines/lure/debugger.cpp @@ -105,7 +105,7 @@ bool Debugger::cmd_enterRoom(int argc, const char **argv) { if (!remoteFlag) res.getActiveHotspot(PLAYER_ID)->setRoomNumber(roomNumber); - _detach_now = true; + detach(); return false; } diff --git a/engines/lure/fights.cpp b/engines/lure/fights.cpp index 53539677c8..789c9d924e 100644 --- a/engines/lure/fights.cpp +++ b/engines/lure/fights.cpp @@ -132,8 +132,7 @@ void FightsManager::fightLoop() { } Screen::getReference().update(); - if (game.debugger().isAttached()) - game.debugger().onFrame(); + game.debugger().onFrame(); g_system->delayMillis(10); } diff --git a/engines/lure/game.cpp b/engines/lure/game.cpp index d0f98b9c34..e77ac25716 100644 --- a/engines/lure/game.cpp +++ b/engines/lure/game.cpp @@ -56,8 +56,6 @@ Game::Game() { _debugFlag = gDebugLevel >= ERROR_BASIC; _soundFlag = true; - _musicVolume = ConfMan.getBool("music_mute") ? 0 : MIN(255, ConfMan.getInt("music_volume")); - _sfxVolume = ConfMan.getBool("sfx_mute") ? 0 : MIN(255, ConfMan.getInt("sfx_volume")); } Game::~Game() { @@ -281,8 +279,7 @@ void Game::execute() { system.updateScreen(); system.delayMillis(10); - if (_debugger->isAttached()) - _debugger->onFrame(); + _debugger->onFrame(); } room.leaveRoom(); diff --git a/engines/lure/game.h b/engines/lure/game.h index 3864e9c205..123ac0dca7 100644 --- a/engines/lure/game.h +++ b/engines/lure/game.h @@ -48,8 +48,6 @@ class Game { private: Debugger *_debugger; bool _fastTextFlag, _soundFlag; - uint8 _sfxVolume; - uint8 _musicVolume; uint8 _state; uint16 _tellCommands[MAX_TELL_COMMANDS * 3 + 1]; int _numTellCommands; @@ -87,8 +85,6 @@ public: bool &debugFlag() { return _debugFlag; } bool fastTextFlag() { return _fastTextFlag; } bool soundFlag() { return _soundFlag; } - uint8 sfxVolume() { return ConfMan.getInt("sfx_volume"); } - uint8 musicVolume() { return ConfMan.getInt("music_volume"); } Debugger &debugger() { return *_debugger; } // Menu item support methods diff --git a/engines/lure/sound.cpp b/engines/lure/sound.cpp index cd539dfab4..a75545c330 100644 --- a/engines/lure/sound.cpp +++ b/engines/lure/sound.cpp @@ -72,6 +72,8 @@ SoundManager::SoundManager() { _channelsInner[index].volume = 90; } } + + syncSounds(); } SoundManager::~SoundManager() { @@ -288,16 +290,21 @@ uint8 SoundManager::descIndexOf(uint8 soundNumber) { // Used to sync the volume for all channels with the Config Manager // void SoundManager::syncSounds() { - Game &game = Game::getReference(); musicInterface_TidySounds(); + bool mute = false; + if (ConfMan.hasKey("mute")) + mute = ConfMan.getBool("mute"); + _musicVolume = mute ? 0 : MIN(255, ConfMan.getInt("music_volume")); + _sfxVolume = mute ? 0 : MIN(255, ConfMan.getInt("sfx_volume")); + g_system->lockMutex(_soundMutex); MusicListIterator i; for (i = _playingSounds.begin(); i != _playingSounds.end(); ++i) { if ((*i)->isMusic()) - (*i)->setVolume(game.musicVolume()); + (*i)->setVolume(_musicVolume); else - (*i)->setVolume(game.sfxVolume()); + (*i)->setVolume(_sfxVolume); } g_system->unlockMutex(_soundMutex); } @@ -599,9 +606,9 @@ MidiMusic::MidiMusic(MidiDriver *driver, ChannelEntry channels[NUM_CHANNELS], } if (_isMusic) - setVolume(ConfMan.getInt("music_volume")); + setVolume(Sound.musicVolume()); else - setVolume(ConfMan.getInt("sfx_volume")); + setVolume(Sound.sfxVolume()); _passThrough = false; @@ -658,8 +665,7 @@ void MidiMusic::setVolume(int volume) { _volume = volume; - Game &game = Game::getReference(); - volume *= _isMusic ? game.musicVolume() : game.sfxVolume(); + volume *= _isMusic ? Sound.musicVolume() : Sound.sfxVolume(); for (int i = 0; i < _numChannels; ++i) { if (_channels[_channelNumber + i].midiChannel != NULL) @@ -707,8 +713,7 @@ void MidiMusic::send(uint32 b) { // Adjust volume changes by song and master volume byte volume = (byte)((b >> 16) & 0x7F); _channels[channel].volume = volume; - Game &game = Game::getReference(); - int master_volume = _isMusic ? game.musicVolume() : game.sfxVolume(); + int master_volume = _isMusic ? Sound.musicVolume() : Sound.sfxVolume(); volume = volume * _volume * master_volume / 65025; b = (b & 0xFF00FFFF) | (volume << 16); } else if ((b & 0xF0) == 0xC0) { diff --git a/engines/lure/sound.h b/engines/lure/sound.h index c41cec48fe..6d248fbd20 100644 --- a/engines/lure/sound.h +++ b/engines/lure/sound.h @@ -105,7 +105,7 @@ public: bool isMusic() {return _isMusic; } }; -class SoundManager: public Common::Singleton<SoundManager> { +class SoundManager : public Common::Singleton<SoundManager> { private: // Outer sound interface properties MemoryBlock *_descs; @@ -128,11 +128,15 @@ private: Common::MutexRef _soundMutex; bool _paused; + uint _musicVolume; + uint _sfxVolume; + // Internal support methods void bellsBodge(); void musicInterface_TidySounds(); static void onTimer(void *data); void doTimer(); + public: SoundManager(); ~SoundManager(); @@ -156,9 +160,11 @@ public: void fadeOut(); void pause() { _paused = true; } void resume() { _paused = false; } - bool getPaused() { return _paused; } - bool hasNativeMT32() { return _nativeMT32; } - bool isRoland() { return _isRoland; } + bool getPaused() const { return _paused; } + bool hasNativeMT32() const { return _nativeMT32; } + bool isRoland() const { return _isRoland; } + uint musicVolume() const { return _musicVolume; } + uint sfxVolume() const { return _sfxVolume; } // The following methods implement the external sound player module void musicInterface_Initialise(); diff --git a/engines/m4/animation.cpp b/engines/m4/animation.cpp index 0ead57aac9..37314eff44 100644 --- a/engines/m4/animation.cpp +++ b/engines/m4/animation.cpp @@ -287,8 +287,8 @@ void MadsAnimation::load(const Common::String &filename, int abortTimers) { _abortTimers = abortTimers; _abortMode = _madsVm->scene()->_abortTimersMode2; - for (int i = 0; i < 3; ++i) - _actionNouns[i] = _madsVm->globals()->actionNouns[i]; + if (_madsVm->_scene) + _actionNouns = _madsVm->scene()->_action._action; // Initialise kernel message list for (uint i = 0; i < _messages.size(); ++i) @@ -464,8 +464,8 @@ void MadsAnimation::update() { if (_abortMode != ABORTMODE_1) { // Copy the noun list - for (int i = 0; i < 3; ++i) - _madsVm->globals()->actionNouns[i] = _actionNouns[i]; + if (_madsVm->_scene) + _madsVm->scene()->_action._action = _actionNouns; } } } diff --git a/engines/m4/animation.h b/engines/m4/animation.h index 583d829066..a7a6b57c32 100644 --- a/engines/m4/animation.h +++ b/engines/m4/animation.h @@ -104,8 +104,7 @@ private: int _messageCtr; int _abortTimers; AbortTimerMode _abortMode; - uint16 _actionNouns[3]; - + ActionDetails _actionNouns; void load1(int frameNumber); bool proc1(SpriteAsset &spriteSet, const Common::Point &pt, int frameNumber); diff --git a/engines/m4/console.cpp b/engines/m4/console.cpp index 19fbf6e852..71c70e3e1b 100644 --- a/engines/m4/console.cpp +++ b/engines/m4/console.cpp @@ -103,8 +103,8 @@ bool Console::cmdListHotSpots(int argc, const char **argv) { if (_vm->isM4()) { DebugPrintf("Scene parallax\n"); _m4Vm->scene()->getSceneResources().parallax->dump(); - DebugPrintf("Scene props\n"); - _vm->_scene->getSceneResources().props->dump(); + DebugPrintf("Scene dynamic hotspots\n"); + _vm->_scene->getSceneResources().dynamicHotspots->dump(); } return true; } @@ -400,9 +400,9 @@ bool M4Console::cmdSceneInfo(int argc, const char **argv) { DebugPrintf("Scene resources:\n"); DebugPrintf("artBase: %s\n", _m4Vm->scene()->getSceneResources().artBase); DebugPrintf("pictureBase: %s\n", _m4Vm->scene()->getSceneResources().pictureBase); - DebugPrintf("hotspotCount: %i\n", _m4Vm->scene()->getSceneResources().hotspotCount); + DebugPrintf("hotspotCount: %i\n", _m4Vm->scene()->getSceneResources().hotspots->size()); DebugPrintf("parallaxCount: %i\n", _m4Vm->scene()->getSceneResources().parallaxCount); - DebugPrintf("propsCount: %i\n", _m4Vm->scene()->getSceneResources().propsCount); + DebugPrintf("dynHotspotCount: %i\n", _m4Vm->scene()->getSceneResources().dynamicHotspots->size()); DebugPrintf("frontY: %i\n", _m4Vm->scene()->getSceneResources().frontY); DebugPrintf("backY: %i\n", _m4Vm->scene()->getSceneResources().backY); DebugPrintf("frontScale: %i\n", _m4Vm->scene()->getSceneResources().frontScale); diff --git a/engines/m4/converse.cpp b/engines/m4/converse.cpp index 11bc165811..af26a86313 100644 --- a/engines/m4/converse.cpp +++ b/engines/m4/converse.cpp @@ -858,8 +858,8 @@ void Converse::loadConversationMads(const char *convName) { if (buffer[curPos - 1] == '\0') { // end of string //printf("%s\n", buffer); - buf = new char[strlen(buffer)]; - sprintf(buf, "%s", buffer); + buf = new char[strlen(buffer) + 1]; + strcpy(buf, buffer); _convStrings.push_back(buf); curPos = 0; *buffer = 0; diff --git a/engines/m4/graphics.cpp b/engines/m4/graphics.cpp index c10ea6c9f6..423dda5e7e 100644 --- a/engines/m4/graphics.cpp +++ b/engines/m4/graphics.cpp @@ -443,7 +443,7 @@ void M4Surface::copyFrom(M4Surface *src, int destX, int destY, int depth, for (int rowCtr = 0; rowCtr < copyRect.height(); ++rowCtr) { // Copy each byte one at a time checking against the depth for (int xCtr = 0; xCtr < copyRect.width(); ++xCtr) { - if ((depthsPtr[xCtr] > depth) && (srcPtr[xCtr] != transparentColour)) + if ((depth <= (depthsPtr[xCtr] & 0x7f)) && (srcPtr[xCtr] != transparentColour)) destPtr[xCtr] = srcPtr[xCtr]; } @@ -557,7 +557,7 @@ void M4Surface::copyFrom(M4Surface *src, int destX, int destY, int depth, // Not a display pixel continue; - if ((*srcP != transparentColour) && (depth <= *depthP)) + if ((*srcP != transparentColour) && (depth <= (*depthP & 0x7f))) *destP = *srcP; ++destP; diff --git a/engines/m4/hotspot.cpp b/engines/m4/hotspot.cpp index 9849cc7416..27180c5eb8 100644 --- a/engines/m4/hotspot.cpp +++ b/engines/m4/hotspot.cpp @@ -185,9 +185,9 @@ void HotSpotList::dump() { uint32 HotSpotList::readHotSpotInteger(Common::SeekableReadStream* hotspotStream) { if (_vm->isM4()) - return hotspotStream->readUint32LE(); + return hotspotStream->readSint32LE(); else - return hotspotStream->readUint16LE(); + return hotspotStream->readSint16LE(); } void HotSpotList::loadHotSpots(Common::SeekableReadStream* hotspotStream, int hotspotCount) { @@ -196,7 +196,7 @@ void HotSpotList::loadHotSpots(Common::SeekableReadStream* hotspotStream, int ho char buffer[256]; uint32 strLength = 0; uint32 index = 0; - uint32 feetX, feetY; + int feetX, feetY; int cursorOffset = (_vm ->isM4()) ? 0 : 1; for (int i = 0; i < hotspotCount; i++) { @@ -206,6 +206,7 @@ void HotSpotList::loadHotSpots(Common::SeekableReadStream* hotspotStream, int ho y2 = readHotSpotInteger(hotspotStream); index = add(new HotSpot(x1, y1, x2, y2), i == 0); currentHotSpot = get(index); + currentHotSpot->setIndex(index); feetX = readHotSpotInteger(hotspotStream); feetY = readHotSpotInteger(hotspotStream); currentHotSpot->setFeet(feetX, feetY); diff --git a/engines/m4/hotspot.h b/engines/m4/hotspot.h index 5bb4f5888a..f650d5ff54 100644 --- a/engines/m4/hotspot.h +++ b/engines/m4/hotspot.h @@ -73,6 +73,8 @@ public: int getFeetY() { return _feetY; } int8 getArticle() const { return _articleNumber; } Common::Rect getRect() const; + int getIndex() const { return _index; } + void setIndex(int index) { _index = index; } int32 area() const { return (_rect.width() - 1) * (_rect.height() - 1); } bool pointInside(int x, int y) { return _rect.contains(x, y); } @@ -83,6 +85,7 @@ private: bool _active; int _feetX, _feetY; uint8 _facing, _cursor; + int _index; // Unused in Orion Burger, used in MADS games uint8 _syntax; @@ -101,6 +104,7 @@ public: int add(HotSpot *hotspot, bool head = false); HotSpot *get(int index) { return _hotspots[index]; } HotSpot &operator[](int idx) { return *get(idx); } + int size() const { return _hotspots.size(); } void remove(HotSpot *hotspot); void unlinkItem(HotSpot *hotspot); void clear(); diff --git a/engines/m4/m4_scene.cpp b/engines/m4/m4_scene.cpp index 79122a9564..475fdba653 100644 --- a/engines/m4/m4_scene.cpp +++ b/engines/m4/m4_scene.cpp @@ -45,7 +45,7 @@ M4Scene::M4Scene(M4Engine *vm): _sceneResources(), Scene(vm, &_sceneResources) { _sceneResources.hotspots = new HotSpotList(); _sceneResources.parallax = new HotSpotList(); - _sceneResources.props = new HotSpotList(); + _sceneResources.dynamicHotspots = new HotSpotList(); _interfaceSurface = new M4InterfaceView(vm); } @@ -74,9 +74,9 @@ void M4Scene::loadSceneResources(int sceneNumber) { if (sceneS != NULL) { sceneS->read(_sceneResources.artBase, MAX_CHK_FILENAME_SIZE); sceneS->read(_sceneResources.pictureBase, MAX_CHK_FILENAME_SIZE); - _sceneResources.hotspotCount = sceneS->readUint32LE(); + int hotspotCount = sceneS->readUint32LE(); _sceneResources.parallaxCount = sceneS->readUint32LE(); - _sceneResources.propsCount = sceneS->readUint32LE(); + int dynHotspotCount = sceneS->readUint32LE(); _sceneResources.frontY = sceneS->readUint32LE(); _sceneResources.backY = sceneS->readUint32LE(); _sceneResources.frontScale = sceneS->readUint32LE(); @@ -99,11 +99,11 @@ void M4Scene::loadSceneResources(int sceneNumber) { // Clear current hotspot lists _sceneResources.hotspots->clear(); _sceneResources.parallax->clear(); - _sceneResources.props->clear(); + _sceneResources.dynamicHotspots->clear(); - _sceneResources.hotspots->loadHotSpots(sceneS, _sceneResources.hotspotCount); + _sceneResources.hotspots->loadHotSpots(sceneS, hotspotCount); _sceneResources.parallax->loadHotSpots(sceneS, _sceneResources.parallaxCount); - _sceneResources.props->loadHotSpots(sceneS, _sceneResources.propsCount); + _sceneResources.dynamicHotspots->loadHotSpots(sceneS, dynHotspotCount); // Note that toss() deletes the MemoryReadStream _vm->res()->toss(filename); @@ -207,7 +207,7 @@ void M4Scene::leaveScene() { Scene::leaveScene(); } -void M4Scene::checkHotspotAtMousePos(int x, int y) { +void M4Scene::mouseMove(int x, int y) { if (_vm->getGameType() == GType_Riddle) return; diff --git a/engines/m4/m4_scene.h b/engines/m4/m4_scene.h index 329582caf4..2216779a3e 100644 --- a/engines/m4/m4_scene.h +++ b/engines/m4/m4_scene.h @@ -69,7 +69,7 @@ public: virtual void leaveScene(); virtual void loadSceneCodes(int sceneNumber, int index = 0); virtual void show(); - virtual void checkHotspotAtMousePos(int x, int y); + virtual void mouseMove(int x, int y); virtual void leftClick(int x, int y); virtual void rightClick(int x, int y); virtual void update(); diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp index e451a306ef..e7c20b237d 100644 --- a/engines/m4/mads_logic.cpp +++ b/engines/m4/mads_logic.cpp @@ -189,30 +189,30 @@ uint16 MadsSceneLogic::loadSpriteSet(uint16 suffixNum, uint16 sepChar) { return _madsVm->scene()->loadSceneSpriteSet(resName); } -uint16 MadsSceneLogic::startReversibleSpriteSequence(uint16 srcSpriteIdx, int v0, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) { +uint16 MadsSceneLogic::startReversibleSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) { M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(0); uint8 depth = _madsVm->_rails->getDepth(Common::Point(spriteFrame->x + (spriteFrame->width() / 2), spriteFrame->y + (spriteFrame->height() / 2))); - return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, v0, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0, + return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0, true, 100, depth - 1, 1, ANIMTYPE_REVERSIBLE, 0, 0); } -uint16 MadsSceneLogic::startCycledSpriteSequence(uint16 srcSpriteIdx, int v0, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) { +uint16 MadsSceneLogic::startCycledSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) { M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(0); uint8 depth = _madsVm->_rails->getDepth(Common::Point(spriteFrame->x + (spriteFrame->width() / 2), spriteFrame->y + (spriteFrame->height() / 2))); - return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, v0, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0, + return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0, true, 100, depth - 1, 1, ANIMTYPE_CYCLED, 0, 0); } -uint16 MadsSceneLogic::startSpriteSequence3(uint16 srcSpriteIdx, int v0, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) { +uint16 MadsSceneLogic::startSpriteSequence3(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) { M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(0); uint8 depth = _madsVm->_rails->getDepth(Common::Point(spriteFrame->x + (spriteFrame->width() / 2), spriteFrame->y + (spriteFrame->height() / 2))); - return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, v0, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0, + return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0, true, 100, depth - 1, -1, ANIMTYPE_CYCLED, 0, 0); } @@ -354,20 +354,18 @@ void MadsSceneLogic::enterScene() { _spriteIndexes[12] = loadSpriteSet(8, 'x'); _spriteIndexes[13] = loadSpriteSet(0, 'x'); - _spriteIndexes[15] = startCycledSpriteSequence(_spriteIndexes[0], 0, 5, 0, 0, 25); - - _spriteIndexes[16] = startCycledSpriteSequence(_spriteIndexes[1], 0, 4, 0, 1, 0); - _spriteIndexes[17] = startCycledSpriteSequence(_spriteIndexes[2], 0, 4, 0, 1, 0); + _spriteIndexes[15] = startCycledSpriteSequence(_spriteIndexes[0], false, 5, 0, 0, 25); + _spriteIndexes[16] = startCycledSpriteSequence(_spriteIndexes[1], false, 4, 0, 1, 0); + _spriteIndexes[17] = startCycledSpriteSequence(_spriteIndexes[2], false, 4, 0, 1, 0); _madsVm->scene()->_sequenceList.addSubEntry(_spriteIndexes[17], SM_FRAME_INDEX, 7, 70); - _spriteIndexes[18] = startReversibleSpriteSequence(_spriteIndexes[3], 0, 10, 0, 0, 60); - _spriteIndexes[19] = startCycledSpriteSequence(_spriteIndexes[4], 0, 5, 0, 1, 0); - _spriteIndexes[20] = startCycledSpriteSequence(_spriteIndexes[5], 0, 10, 0, 2, 0); - _spriteIndexes[21] = startCycledSpriteSequence(_spriteIndexes[6], 0, 6, 0, 0, 0); - - _spriteIndexes[23] = startCycledSpriteSequence(_spriteIndexes[8], 0, 6, 0, 10, 4); - _spriteIndexes[24] = startCycledSpriteSequence(_spriteIndexes[9], 0, 6, 0, 32, 47); + _spriteIndexes[18] = startReversibleSpriteSequence(_spriteIndexes[3], false, 10, 0, 0, 60); + _spriteIndexes[19] = startCycledSpriteSequence(_spriteIndexes[4], false, 5, 0, 1, 0); + _spriteIndexes[20] = startCycledSpriteSequence(_spriteIndexes[5], false, 10, 0, 2, 0); + _spriteIndexes[21] = startCycledSpriteSequence(_spriteIndexes[6], false, 6, 0, 0, 0); + _spriteIndexes[23] = startCycledSpriteSequence(_spriteIndexes[8], false, 6, 0, 10, 4); + _spriteIndexes[24] = startCycledSpriteSequence(_spriteIndexes[9], false, 6, 0, 32, 47); activateHotspot(0x137, false); // SHIELD MODULATOR // shield_panel_opened = 0; @@ -386,7 +384,7 @@ void MadsSceneLogic::enterScene() { _madsVm->_player._direction = 9; // TODO: Extra flags setting - _spriteIndexes[25] = startCycledSpriteSequence(_spriteIndexes[10], 0, 3, 0, 0, 0); + _spriteIndexes[25] = startCycledSpriteSequence(_spriteIndexes[10], false, 3, 0, 0, 0); _madsVm->scene()->_sequenceList.setAnimRange(_spriteIndexes[25], 17, 17); activateHotspot(0x47, false); // CHAIR /*timer_unk1 = */_madsVm->scene()->_dynamicHotspots.add(0x47, 0x13F /*SIT_IN*/, -1, @@ -395,7 +393,8 @@ void MadsSceneLogic::enterScene() { //if (_madsVm->globals()->previousScene == 112) // room101Check(); } else { - _spriteIndexes[26] = startCycledSpriteSequence(_spriteIndexes[11], 0, 6, 0, 0, 0); + _spriteIndexes[26] = startCycledSpriteSequence(_spriteIndexes[11], false, 6, 0, 0, 0); + _madsVm->scene()->_sequenceList.setDepth(_spriteIndexes[26], 4); } _madsVm->globals()->loadQuoteSet(0x31, 0x32, 0x37, 0x38, 0x39, -1); @@ -418,11 +417,15 @@ void MadsSceneLogic::enterScene() { lowRoomsEntrySound(); } -void MadsSceneLogic::doAction() { +void MadsSceneLogic::doPreactions() { + warning("Still to do preactions logic"); +} +void MadsSceneLogic::doAction() { + warning("Still to do actions logic"); } -void MadsSceneLogic::sceneStep() { +void MadsSceneLogic::doSceneStep() { // TODO: Sound handling switch (_madsVm->scene()->_abortTimers) { diff --git a/engines/m4/mads_logic.h b/engines/m4/mads_logic.h index 98d6df6163..ec6eff368b 100644 --- a/engines/m4/mads_logic.h +++ b/engines/m4/mads_logic.h @@ -37,9 +37,9 @@ class MadsSceneLogic { private: // Library interface methods uint16 loadSpriteSet(uint16 suffixNum, uint16 sepChar); - uint16 startReversibleSpriteSequence(uint16 srcSpriteIdx, int v0, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks); - uint16 startCycledSpriteSequence(uint16 srcSpriteIdx, int v0, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks); - uint16 startSpriteSequence3(uint16 srcSpriteIdx, int v0, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks); + uint16 startReversibleSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks); + uint16 startCycledSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks); + uint16 startSpriteSequence3(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks); void activateHotspot(int idx, bool active); void lowRoomsEntrySound(); void getPlayerSpritesPrefix(); @@ -59,8 +59,9 @@ public: void setupScene(); void enterScene(); + void doPreactions(); void doAction(); - void sceneStep(); + void doSceneStep(); }; class MadsGameLogic { diff --git a/engines/m4/mads_menus.cpp b/engines/m4/mads_menus.cpp index d7d9cf4150..810acb04fb 100644 --- a/engines/m4/mads_menus.cpp +++ b/engines/m4/mads_menus.cpp @@ -809,7 +809,7 @@ void RexDialogView::setFrame(int frameNumber, int depth) { } void RexDialogView::initVars() { - _word_8502C = -1; + _v8502C = -1; _selectedLine = -1; _lineIndex = 0; _enterFlag = false; diff --git a/engines/m4/mads_menus.h b/engines/m4/mads_menus.h index e964c5866d..a0fc6fb3bc 100644 --- a/engines/m4/mads_menus.h +++ b/engines/m4/mads_menus.h @@ -136,7 +136,7 @@ protected: int _dialogSelectedLine; Common::StringArray _saveList; - int _word_8502C; + int _v8502C; int _selectedLine; int _lineIndex; bool _enterFlag; diff --git a/engines/m4/mads_player.cpp b/engines/m4/mads_player.cpp index 8531a3ed44..de09e97640 100644 --- a/engines/m4/mads_player.cpp +++ b/engines/m4/mads_player.cpp @@ -35,20 +35,27 @@ const int MadsPlayer::_directionListIndexes[32] = { MadsPlayer::MadsPlayer() { _playerPos = Common::Point(160, 78); - _direction = 0; - _newDirection = 0; + _ticksAmount = 3; _forceRefresh = true; _stepEnabled = true; - _ticksAmount = 3; - _priorTimer = 0; _visible = true; - _priorVisible = false; - _visible3 = false; _yScale = 0; _moving = false; + _spriteListStart = 0; - _spriteListIdx = 0; + //TODO:unknown vars + _special = 0; + _next = 0; + _unk4 = false; + _spritesChanged = true; + + _direction = 0; + _newDirection = 0; + _priorTimer = 0; + _priorVisible = false; + _visible3 = false; + _spriteListIdx = 0; _currentScale = 0; strcpy(_spritesPrefix, ""); for (int idx = 0; idx < 8; ++idx) @@ -59,6 +66,8 @@ MadsPlayer::MadsPlayer() { _frameCount = 0; _frameListIndex = 0; _actionIndex = 0; + _routeCount = 0; + resetActionList(); } @@ -127,7 +136,7 @@ void MadsPlayer::update() { int yp = MIN(_playerPos.y, (int16)155); for (int idx = 1; idx < 15; ++idx) { - if (_madsVm->scene()->getSceneResources().depthTable[newDepth] >= yp) + if (_madsVm->scene()->getSceneResources()._depthBands[newDepth] >= yp) newDepth = idx + 1; } _currentDepth = newDepth; @@ -168,7 +177,7 @@ void MadsPlayer::update() { _madsVm->scene()->_spriteSlots[slotIndex] = slot; } - // TODO: Meaning of word_844c0 block + // TODO: Meaning of _v844c0 block } } @@ -325,6 +334,34 @@ void MadsPlayer::nextFrame() { } } +void MadsPlayer::setDest(int destX, int destY, int facing) { + resetActionList(); + setTicksAmount(); + _moving = true; + _destFacing = facing; + + _madsVm->scene()->getSceneResources().setRouteNode(_madsVm->scene()->getSceneResources()._nodes.size() - 2, + _playerPos, _madsVm->scene()->_depthSurface); + _madsVm->scene()->getSceneResources().setRouteNode(_madsVm->scene()->getSceneResources()._nodes.size() - 1, + Common::Point(destX, destY), _madsVm->scene()->_depthSurface); + + bool v = _madsVm->scene()->getDepthHighBit(Common::Point(destX, destY)); + setupRoute(v); + _next = 0; + + if (_routeCount > 0) { + Common::Point srcPos = _playerPos; + for (int routeCtr = _routeCount - 1; (routeCtr >= 0) && (_next == 0); --routeCtr) { + int idx = _routeIndexes[routeCtr]; + const Common::Point &pt = _madsVm->scene()->getSceneResources()._nodes[idx].pt; + + _next = scanPath(_madsVm->scene()->_depthSurface, srcPos, pt); + srcPos = pt; + } + } +} + + int MadsPlayer::getScale(int yp) { MadsSceneResources &r = _madsVm->scene()->getSceneResources(); @@ -411,7 +448,100 @@ void MadsPlayer::idle() { } void MadsPlayer::move() { - // TODO: Handle player movement + bool routeFlag = false; + + if (_moving) { + int idx = _routeCount; + while (!_v844C0 && (_destPos.x == _playerPos.x) && (_destPos.y == _playerPos.y)) { + if (idx != 0) { + --idx; + SceneNode &node = _madsVm->scene()->getSceneResources()._nodes[_routeIndexes[idx]]; + _destPos = node.pt; + routeFlag = true; + } else if (_v844BE == idx) { + // End of walking path + _routeCount = 0; + _moving = false; + turnToDestFacing(); + routeFlag = true; + idx = _routeCount; + } else { + _v844C0 = _v844BE; + _v844BC = true; + _v844BE = 0; + _stepEnabled = true; + routeFlag = false; + } + + if (!_moving) + break; + } + _routeCount = idx; + } + + if (routeFlag && _moving) + startMovement(); + + if (_newDirection != _direction) + dirChanged(); + else if (!_moving) + updateFrame(); + + int var1 = _unk1; + if (_unk4 && (_hypotenuse > 0)) { + int v1 = -(_currentScale - 100) * (_posDiff.x - 1) / _hypotenuse + _currentScale; + var1 = MAX(1, 10000 / (v1 * _currentScale * var1)); + } + + if (!_moving || (_direction != _newDirection)) + return; + + Common::Point newPos = _playerPos; + + if (_v8452E < var1) { + do { + if (_v8452C < _posDiff.x) + _v8452C += _posDiff.y; + if (_v8452C >= _posDiff.x) { + if ((_posChange.y > 0) || (_v844C0 != 0)) + newPos.y += _yDirection; + --_posChange.y; + _v8452C -= _posDiff.x; + } + + if (_v8452C < _posDiff.x) { + if ((_posChange.x > 0) || (_v844C0 != 0)) + newPos.x += _xDirection; + --_posChange.x; + } + + if ((_v844BC == 0) && (_v844C0 == 0) && (_v844BE == 0)) { + routeFlag = _madsVm->scene()->getDepthHighBit(newPos); + + if (_special == 0) + _special = _madsVm->scene()->getDepthHighBits(newPos); + } + + _v8452E += _v84530; + + } while ((_v8452E < var1) && !routeFlag && ((_posChange.x > 0) || (_posChange.y > 0) || (_v844C0 != 0))); + } + + _v8452E -= var1; + + if (routeFlag) + moveComplete(); + else { + if (!_v844C0) { + // If the move is complete, make sure the position is exactly on the given destination + if (_posChange.x == 0) + newPos.x = _destPos.x; + if (_posChange.y == 0) + newPos.y = _destPos.y; + } + + _playerPos = newPos; + } } void MadsPlayer::dirChanged() { @@ -451,4 +581,212 @@ void MadsPlayer::dirChanged() { _priorTimer += 1; } +void MadsPlayer::moveComplete() { + reset(); + //todo: Unknown flag +} + +void MadsPlayer::reset() { + _destPos = _playerPos; + _destFacing = 5; + _newDirection = _direction; + + _madsVm->scene()->_action._startWalkFlag = false; + _madsVm->scene()->_action._walkFlag = false; + _moving = false; + _v844BC = false; + _v844C0 = false; + _v844BE = 0; + _next = 0; + _routeCount = 0; +} + +/** + * Scans along an edge connecting two points within the depths/walk surface, and returns the information of the first + * pixel high nibble encountered with a non-zero value + */ +int MadsPlayer::scanPath(M4Surface *depthSurface, const Common::Point &srcPos, const Common::Point &destPos) { + // For compressed depth surfaces, always return 0 + if (_madsVm->scene()->getSceneResources()._depthStyle != 2) + return 0; + + int yDiff = destPos.y - srcPos.y; + int yAmount = MADS_SURFACE_WIDTH; + + if (yDiff < 0) { + yDiff = -yDiff; + yAmount = -yAmount; + } + + int xDiff = destPos.x - srcPos.y; + int xDirection = 1; + int xAmount = 0; + if (xDiff < 0) { + xDiff = -xDiff; + xDirection = -xDirection; + xAmount = MIN(yDiff, xDiff); + } + + ++xDiff; + ++yDiff; + + const byte *srcP = depthSurface->getBasePtr(srcPos.x, srcPos.y); + int index = xAmount; + + // Outer horizontal movement loop + for (int yIndex = 0; yIndex < yDiff; ++yIndex) { + index += yDiff; + int v = (*srcP & 0x7F) >> 4; + if (v) + return v; + + // Inner loop for handling vertical movement + while (index >= xDiff) { + index -= xDiff; + + v = (*srcP & 0x7F) >> 4; + if (v) + return v; + + srcP += yAmount; + } + + srcP += xDirection; + } + + return 0; +} + +/** + * Starts a player moving to a given destination + */ +void MadsPlayer::startMovement() { + int xDiff = _destPos.x - _playerPos.x; + int yDiff = _destPos.y - _playerPos.y; + int srcScale = getScale(_playerPos.y); + int destScale = getScale(_destPos.y); + + // Sets the X direction + if (xDiff > 0) + _xDirection = 1; + else if (xDiff < 0) + _xDirection = -1; + else + _xDirection = 0; + + // Sets the Y direction + if (yDiff > 0) + _yDirection = 1; + else if (yDiff < 0) + _yDirection = -1; + else + _yDirection = 0; + + xDiff = ABS(xDiff); + yDiff = ABS(yDiff); + int scaleDiff = ABS(srcScale - destScale); + + int xAmt100 = xDiff * 100; + int yAmt100 = yDiff * 100; + int xAmt33 = xDiff * 33; + + int scaleAmount = (_unk4 ? scaleDiff * 3 : 0) + 100 * yDiff / 100; + int scaleAmount100 = scaleAmount * 100; + + // Figure out direction that will need to be moved in + int majorDir; + if (xDiff == 0) + majorDir = 1; + else if (yDiff == 0) + majorDir = 3; + else { + if ((scaleAmount < xDiff) && ((xAmt33 / scaleAmount) >= 141)) + majorDir = 3; + else if (yDiff <= xDiff) + majorDir = 2; + else if ((scaleAmount100 / xDiff) >= 141) + majorDir = 1; + else + majorDir = 2; + } + + switch (majorDir) { + case 1: + _newDirection = (_yDirection <= 0) ? 8 : 2; + break; + case 2: { + _newDirection = ((_yDirection <= 0) ? 9 : 3) - ((_xDirection <= 0) ? 2 : 0); + break; + } + case 3: + _newDirection = (_xDirection <= 0) ? 4 : 6; + break; + default: + break; + } + + _hypotenuse = SqrtF16(xAmt100 * xAmt100 + yAmt100 * yAmt100); + _posDiff.x = xDiff + 1; + _posDiff.y = yDiff + 1; + _posChange.x = xDiff; + _posChange.y = yDiff; + + int majorChange = MAX(xDiff, yDiff); + _v84530 = (majorChange == 0) ? 0 : _hypotenuse / majorChange; + + if (_playerPos.x > _destPos.x) + _v8452C = MAX(_posChange.x, _posChange.y); + else + _v8452C = 0; + + _hypotenuse /= 100; + _v8452E = -_v84530; +} + +void MadsPlayer::turnToDestFacing() { + if (_destFacing != 5) + _newDirection = _destFacing; +} + +void MadsPlayer::setupRoute(bool bitFlag) { + // Reset the flag set of nodes in use + SceneNodeList &nodes = _madsVm->scene()->getSceneResources()._nodes; + for (uint i = 0; i < nodes.size(); ++i) + nodes[i].active = false; + + // Start constructing route node list + _routeLength = 0x3FFF; + _routeCount = 0; + + setupRouteNode(_tempRoute, nodes.size() - 1, bitFlag ? 0xC000 : 0x8000, 0); +} + +void MadsPlayer::setupRouteNode(int *routeIndexP, int nodeIndex, int flags, int routeLength) { + SceneNodeList &nodes = _madsVm->scene()->getSceneResources()._nodes; + SceneNode ¤tNode = nodes[nodeIndex]; + currentNode.active = true; + + *routeIndexP++ = nodeIndex; + + int subIndex = nodes.size() - 2; + int indexVal = nodes[nodeIndex].indexes[subIndex]; + if (indexVal & flags) { + routeLength += indexVal & 0x3FFF; + if (routeLength < _routeLength) { + // Found a new shorter route to destination, so set up the route with the found one + Common::copy(_tempRoute, routeIndexP, _routeIndexes); + _routeCount = routeIndexP - _tempRoute; + _routeLength = indexVal & 0x3FFF; + } + } else { + for (int idx = nodes.size() - 2; idx > 0; --idx) { + int nodePos = idx - 1; + if (!nodes[nodePos].active && ((currentNode.indexes[nodePos] & flags) != 0)) + setupRouteNode(routeIndexP, nodePos, 0x8000, indexVal & 0x3fff); + } + } + + currentNode.active = false; +} + } // End of namespace M4 diff --git a/engines/m4/mads_player.h b/engines/m4/mads_player.h index 65ed9ef89c..6a9b7b4ca1 100644 --- a/engines/m4/mads_player.h +++ b/engines/m4/mads_player.h @@ -27,6 +27,7 @@ #define M4_MADS_PLAYER_H #include "common/scummsys.h" +#include "m4/mads_scene.h" namespace M4 { @@ -42,12 +43,19 @@ private: void idle(); void move(); void dirChanged(); + void reset(); + int scanPath(M4Surface *depthSurface, const Common::Point &srcPos, const Common::Point &destPos); + void startMovement(); + void setupRouteNode(int *routeIndexP, int nodeIndex, int flags, int routeLength); public: char _spritesPrefix[16]; int _spriteSetCount; bool _spriteSetsPresent[8]; Common::Point _playerPos; Common::Point _destPos; + Common::Point _posChange; + Common::Point _posDiff; + int _hypotenuse; uint32 _priorTimer; uint _ticksAmount; int16 _direction, _newDirection; @@ -70,6 +78,22 @@ public: int _actionList2[12]; int _unk2; int _unk3; + int _xDirection, _yDirection; + int _destFacing; + int _special; + int _next; + int _routeCount; + int _routeOffset; + int _tempRoute[MAX_ROUTE_NODES]; + int _routeIndexes[MAX_ROUTE_NODES]; + bool _unk4; + bool _v844BC; + int _v844BE; + bool _v844C0; + int _v8452E; + int _v8452C; + int _v84530; + int _routeLength; static const int _directionListIndexes[32]; public: @@ -81,6 +105,10 @@ public: void setupFrame(); void step(); void nextFrame(); + void setDest(int destX, int destY, int facing); + void turnToDestFacing(); + void setupRoute(bool bitFlag); + void moveComplete(); }; } // End of namespace M4 diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp index e4f84aeb5a..d44fa2a753 100644 --- a/engines/m4/mads_scene.cpp +++ b/engines/m4/mads_scene.cpp @@ -48,6 +48,17 @@ static const int SCROLLER_DELAY = 200; //-------------------------------------------------------------------------- +void SceneNode::load(Common::SeekableReadStream *stream) { + // Get the next data block + pt.x = stream->readUint16LE(); + pt.y = stream->readUint16LE(); + + for (int i = 0; i < MAX_ROUTE_NODES; ++i) + indexes[i] = stream->readUint16LE(); +} + +//-------------------------------------------------------------------------- + MadsScene::MadsScene(MadsEngine *vm): _sceneResources(), Scene(vm, &_sceneResources), MadsView(this) { _vm = vm; _activeAnimation = NULL; @@ -55,6 +66,8 @@ MadsScene::MadsScene(MadsEngine *vm): _sceneResources(), Scene(vm, &_sceneResour MadsView::_bgSurface = Scene::_backgroundSurface; MadsView::_depthSurface = Scene::_walkSurface; _interfaceSurface = new MadsInterfaceView(vm); + _showMousePos = false; + _mouseMsgIndex = -1; } MadsScene::~MadsScene() { @@ -182,24 +195,21 @@ void MadsScene::loadSceneHotspots(int sceneNumber) { int hotspotCount = hotspotStream->readUint16LE(); delete hotspotStream; - _sceneResources.hotspotCount = hotspotCount; - hotspotStream = hotSpotData.getItemStream(1); // Clear current hotspot lists _sceneResources.hotspots->clear(); - - _sceneResources.hotspots->loadHotSpots(hotspotStream, _sceneResources.hotspotCount); + _sceneResources.hotspots->loadHotSpots(hotspotStream, hotspotCount); delete hotspotStream; } void MadsScene::leaveScene() { _sceneResources.hotspots->clear(); - _sceneResources.props->clear(); + _sceneResources.dynamicHotspots->clear(); delete _sceneResources.hotspots; - delete _sceneResources.props; + delete _sceneResources.dynamicHotspots; delete _walkSurface; if (_activeAnimation) { @@ -228,43 +238,28 @@ void MadsScene::loadSceneCodes(int sceneNumber, int index) { } } -void MadsScene::checkHotspotAtMousePos(int x, int y) { +void MadsScene::mouseMove(int x, int y) { HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y); if (currentHotSpot != NULL) { _vm->_mouse->setCursorNum(currentHotSpot->getCursor()); - // This is the "easy" interface, which updates the status text when the mouse is moved - // TODO: toggle this code for easy/normal interface mode - char statusText[50]; - int verbId = 0;//***DEBUG****_currentAction; - if (verbId == kVerbNone) - verbId = currentHotSpot->getVerbID(); - if (verbId == kVerbNone) - verbId = kVerbWalkTo; - - sprintf(statusText, "%s %s\n", _madsVm->globals()->getVocab(verbId), currentHotSpot->getVocab()); + _action._selectedRow = -1; + _action._actionMode = ACTMODE_NONE; + _action._actionMode2 = ACTMODE2_4; + _action._hotspotId = currentHotSpot->getIndex(); - statusText[0] = toupper(statusText[0]); // capitalize first letter - setStatusText(statusText); } else { _vm->_mouse->setCursorNum(0); - setStatusText(""); } } void MadsScene::leftClick(int x, int y) { - HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y); - if (currentHotSpot != NULL) { - char statusText[50]; - if (currentHotSpot->getVerbID() != 0) { - sprintf(statusText, "%s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab()); - } else { - sprintf(statusText, "%s %s\n", _madsVm->globals()->getVocab(kVerbWalkTo), currentHotSpot->getVocab()); - } - - statusText[0] = toupper(statusText[0]); // capitalize first letter - setStatusText(statusText); - } + // TODO: figure out the rest of Scene_leftClick, and implements relevant parts in the interface class + _action._v86F4C = -1; + _action._v86F4E = 0; + _customDest = _madsVm->_mouse->currentPos(); + _action._selectedAction = -1; + _action._v86F4A = true; } void MadsScene::rightClick(int x, int y) { @@ -280,7 +275,6 @@ void MadsScene::rightClick(int x, int y) { void MadsScene::setAction(int action, int objectId) { VALIDATE_MADS; - char statusText[50]; error("todo"); // TODO: Actually executing actions directly for objects. Also, some object actions are special in that @@ -297,7 +291,7 @@ void MadsScene::setAction(int action, int objectId) { _currentAction = action; } */ - setStatusText(statusText); +// setStatusText(statusText); } /** @@ -316,39 +310,77 @@ void MadsScene::update() { drawElements(); _action.set(); - const char *sStatusText = _action.statusText(); - - // Handle display of any status text - if (sStatusText[0]) { - // Text colors are inverted in Dragonsphere - if (_vm->getGameType() == GType_DragonSphere) - _vm->_font->current()->setColours(_vm->_palette->BLACK, _vm->_palette->WHITE, _vm->_palette->BLACK); - else - _vm->_font->current()->setColours(_vm->_palette->WHITE, _vm->_palette->BLACK, _vm->_palette->BLACK); - - _vm->_font->setFont(FONT_MAIN_MADS); - _vm->_font->current()->writeString(this, sStatusText, (width() - _vm->_font->current()->getWidth(sStatusText)) / 2, 142, 0); - } } void MadsScene::updateState() { - _madsVm->_player.update(); + if (!_abortTimers && !_madsVm->_player._unk3) { + if (_dynamicHotspots._changed) + _dynamicHotspots.refresh(); - // Step through the scene - _sceneLogic.sceneStep(); +// int v = (_madsVm->_player._stepEnabled && !_action._startWalkFlag && !_abortTimers2) ? 1 : 0; +// _screenObjects.check(v, false); + } - _madsVm->_player.step(); - _madsVm->_player._unk3 = 0; + // Handle starting off any selected action + bool doPreAction = false; + if ((_action._selectedAction != 0) && _madsVm->_player._stepEnabled && + !_action._startWalkFlag && !_abortTimers && !_madsVm->_player._unk3) { + // Start the action + _action.startAction(); - if (_abortTimersMode == ABORTMODE_1) - _abortTimers = 0; + if (_action._action.verbId == kVerbLookAt) { + _action._action.verbId = kVerbLook; + _action._savedFields.selectedRow = 0; + } + doPreAction = true; + } + if (doPreAction || ((_abortTimers != 0) && (_abortTimersMode == ABORTMODE_2))) + doPreactions(); + + checkStartWalk(); + + if (_action._inProgress && !_madsVm->_player._moving && !_action._startWalkFlag && + (_madsVm->_player._newDirection == _madsVm->_player._direction)) { + // Reached the end of action movement, so ready to actually do action + doAction(); + } else if ((_abortTimers != 0) && (_abortTimersMode == ABORTMODE_0)) + // Do an action designated by scripts + doAction(); + + bool freeFlag = false; + if (_currentScene != _nextScene) + freeFlag = true; + else { + doSceneStep(); + + if (_currentScene != _nextScene) + freeFlag = true; + else { + // Update the player + _madsVm->_player.nextFrame(); + + // Handle updating the animation + if (!_abortTimers && (_activeAnimation)) + _activeAnimation->update(); + + // Handle refreshing the mouse position display + if (_mouseMsgIndex != -1) + _madsVm->scene()->_kernelMessages.remove(_mouseMsgIndex); + if (_showMousePos) { + char buffer[20]; + sprintf(buffer, "(%d,%d)", _madsVm->_mouse->currentPos().x, _madsVm->_mouse->currentPos().y); + + _mouseMsgIndex = _madsVm->scene()->_kernelMessages.add(Common::Point(5, 5), 0x203, 0, 0, 1, buffer); + } + } + } - // Handle updating the player frame - _madsVm->_player.nextFrame(); + if (_madsVm->globals()->_config.easyMouse) + _action.refresh(); if ((_activeAnimation) && !_abortTimers) { _activeAnimation->update(); - if (((MadsAnimation *) _activeAnimation)->freeFlag()) { + if (((MadsAnimation *) _activeAnimation)->freeFlag() || freeFlag) { delete _activeAnimation; _activeAnimation = NULL; } @@ -359,8 +391,48 @@ void MadsScene::updateState() { // Remove the animation if it's been completed if ((_activeAnimation) && ((MadsAnimation *)_activeAnimation)->freeFlag()) freeAnimation(); + + if ((_action._selectedAction != 0) || !_madsVm->_player._stepEnabled) { + _action.clear(); + _action._selectedAction = 0; + } } +void MadsScene::checkStartWalk() { + if (_action._startWalkFlag && _action._walkFlag) { + _madsVm->_player.setDest(_destPos.x, _destPos.y, _destFacing); + _action._startWalkFlag = false; + } +} + +void MadsScene::doPreactions() { + if ((_screenObjects._v832EC == 0) || (_screenObjects._v832EC == 2)) { + _abortTimersMode2 = ABORTMODE_2; + _action.checkAction(); + + _sceneLogic.doPreactions(); + + if (_abortTimersMode == ABORTMODE_2) + _abortTimers = 0; + } +} + +void MadsScene::doSceneStep() { + // Step through the scene + _sceneLogic.doSceneStep(); + + _madsVm->_player.step(); + _madsVm->_player._unk3 = 0; + + if (_abortTimersMode == ABORTMODE_1) + _abortTimers = 0; +} + +void MadsScene::doAction() { + warning("TODO MadsScene::doAction"); +} + + /** * Does extra work at cleaning up the animation, and then deletes it */ @@ -503,179 +575,20 @@ void MadsScene::loadAnimation(const Common::String &animName, int abortTimers) { _activeAnimation = anim; } -/*--------------------------------------------------------------------------*/ - -MadsAction::MadsAction() { - clear(); -} - -void MadsAction::clear() { - _actionMode = ACTMODE_NONE; - _actionMode2 = ACTMODE2_0; - _word_86F42 = 0; - _word_86F4E = 0; - _articleNumber = 0; - _lookFlag = false; - _word_86F4A = 0; - _statusText[0] = '\0'; - _selectedRow = -1; - _currentHotspot = -1; - _word_86F3A = -1; - _word_86F4C = -1; - //word_86F3A/word_86F4C - _currentAction = kVerbNone; - _objectNameId = -1; - _objectDescId = -1; - _word_83334 = -1; -} - -void MadsAction::appendVocab(int vocabId, bool capitalise) { - char *s = _statusText + strlen(_statusText); - const char *vocabStr = _madsVm->globals()->getVocab(vocabId); - strcpy(s, vocabStr); - if (capitalise) - *s = toupper(*s); +bool MadsScene::getDepthHighBit(const Common::Point &pt) { + const byte *p = _depthSurface->getBasePtr(pt.x, pt.y); + if (_sceneResources._depthStyle == 2) + return ((*p << 4) & 0x80) != 0; - strcat(s, " "); + return (*p & 0x80) != 0; } -void MadsAction::set() { - int hotspotCount = _madsVm->scene()->getSceneResources().hotspotCount; - bool flag = false; - _currentAction = -1; - _objectNameId = -1; - _objectDescId = -1; - - if (_actionMode == ACTMODE_TALK) { - // Handle showing the conversation selection. Rex at least doesn't actually seem to use this - if (_selectedRow >= 0) { - const char *desc = _madsVm->_converse[_selectedRow].desc; - if (desc) - strcpy(_statusText, desc); - } - } else if (_lookFlag && (_selectedRow == 0)) { - // Two 'look' actions in succession, so the action becomes 'Look around' - strcpy(_statusText, lookAroundStr); - } else { - if ((_actionMode == ACTMODE_OBJECT) && (_selectedRow >= 0) && (_flags1 == 2) && (_flags2 == 0)) { - // Use/to action - int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject(); - MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject); - - _objectNameId = objEntry->descId; - _currentAction = objEntry->vocabList[_selectedRow].vocabId; - - // Set up the status text stirng - strcpy(_statusText, useStr); - appendVocab(_objectNameId); - strcpy(_statusText, toStr); - appendVocab(_currentAction); - } else { - // Handling for if an action has been selected - if (_selectedRow >= 0) { - if (_actionMode == ACTMODE_VERB) { - // Standard verb action - _currentAction = verbList[_selectedRow].verb; - } else { - // Selected action on an inventory object - int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject(); - MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject); - - _currentAction = objEntry->vocabList[_selectedRow].vocabId; - } - - appendVocab(_currentAction, true); - - if (_currentAction == kVerbLook) { - // Add in the word 'add' - strcat(_statusText, atStr); - strcat(_statusText, " "); - } - } - - // Handling for if a hotspot has been selected/highlighted - if ((_currentHotspot >= 0) && (_selectedRow >= 0) && (_articleNumber > 0) && (_flags1 == 2)) { - flag = true; - - strcat(_statusText, englishMADSArticleList[_articleNumber]); - strcat(_statusText, " "); - } - - if (_currentHotspot >= 0) { - if (_selectedRow < 0) { - int verbId; - - if (_currentHotspot < hotspotCount) { - // Get the verb Id from the hotspot - verbId = (*_madsVm->scene()->getSceneResources().hotspots)[_currentHotspot].getVerbID(); - } else { - // Get the verb Id from the scene object - verbId = (*_madsVm->scene()->getSceneResources().props)[_currentHotspot - hotspotCount].getVerbID(); - } - - if (verbId > 0) { - // Set the specified action - _currentAction = verbId; - appendVocab(_currentAction, true); - } else { - // Default to a standard 'walk to' - _currentAction = kVerbWalkTo; - strcat(_statusText, walkToStr); - } - } - - if ((_actionMode2 == ACTMODE2_2) || (_actionMode2 == ACTMODE2_5)) { - // Get name from given inventory object - int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_currentHotspot); - _objectNameId = _madsVm->globals()->getObject(objectId)->descId; - } else if (_currentHotspot < hotspotCount) { - // Get name from scene hotspot - _objectNameId = (*_madsVm->scene()->getSceneResources().hotspots)[_currentHotspot].getVocabID(); - } else { - // Get name from temporary scene hotspot - _objectNameId = (*_madsVm->scene()->getSceneResources().props)[_currentHotspot].getVocabID(); - } - } - } - - if ((_currentHotspot >= 0) && (_articleNumber > 0) && !flag) { - if (_articleNumber == -1) { - if (_word_86F3A >= 0) { - int articleNum = 0; - - if ((_word_86F42 == 2) || (_word_86F42 == 5)) { - int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_currentHotspot); - articleNum = _madsVm->globals()->getObject(objectId)->article; - } else if (_word_86F3A < hotspotCount) { - articleNum = (*_madsVm->scene()->getSceneResources().hotspots)[_currentHotspot].getArticle(); - } else { - - } - } - - } else if ((_articleNumber == kVerbLook) || (_vm->getGameType() != GType_RexNebular) || - (strcmp(_madsVm->globals()->getVocab(_objectDescId), fenceStr) != 0)) { - // Write out the article - strcat(_statusText, englishMADSArticleList[_articleNumber]); - } else { - // Special case for a 'fence' entry in Rex Nebular - strcat(_statusText, overStr); - } - - strcat(_statusText, " "); - } - - // Append object description if necessary - if (_word_86F3A >= 0) - appendVocab(_objectDescId); - - // Remove any trailing space character - int statusLen = strlen(_statusText); - if ((statusLen > 0) && (_statusText[statusLen - 1] == ' ')) - _statusText[statusLen - 1] = '\0'; - } +bool MadsScene::getDepthHighBits(const Common::Point &pt) { + if (_sceneResources._depthStyle == 2) + return 0; - _word_83334 = -1; + const byte *p = _depthSurface->getBasePtr(pt.x, pt.y); + return (*p & 0x70) >> 4; } /*--------------------------------------------------------------------------*/ @@ -722,7 +635,7 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su stream->skip(24); - int objectCount = stream->readUint16LE(); + int nodeCount = stream->readUint16LE(); _yBandsEnd = stream->readUint16LE(); _yBandsStart = stream->readUint16LE(); _maxScale = stream->readSint16LE(); @@ -732,14 +645,20 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su stream->skip(2); // Load in any scene objects - for (int i = 0; i < objectCount; ++i) { - MadsObject rec; + for (int i = 0; i < nodeCount; ++i) { + SceneNode rec; rec.load(stream); - _objects.push_back(rec); + _nodes.push_back(rec); } - for (int i = 0; i < 20 - objectCount; ++i) + for (int i = 0; i < 20 - nodeCount; ++i) stream->skip(48); + // Add two extra nodes in that will be used for player movement + for (int i = 0; i < 2; ++i) { + SceneNode rec; + _nodes.push_back(rec); + } + int setCount = stream->readUint16LE(); stream->readUint16LE(); for (int i = 0; i < setCount; ++i) { @@ -810,6 +729,84 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su delete depthSurface; } +void MadsSceneResources::setRouteNode(int nodeIndex, const Common::Point &pt, M4Surface *depthSurface) { + int flags, hypotenuse; + + _nodes[nodeIndex].pt = pt; + + // Recalculate inter-node lengths + for (uint idx = 0; idx < _nodes.size(); ++idx) { + int entry; + if (idx == (uint)nodeIndex) { + entry = 0x3FFF; + } else { + // Process the node + flags = getRouteFlags(pt, _nodes[idx].pt, depthSurface); + + int xDiff = ABS(_nodes[idx].pt.x - pt.x); + int yDiff = ABS(_nodes[idx].pt.y - pt.y); + hypotenuse = SqrtF16(xDiff * xDiff + yDiff * yDiff); + + if (hypotenuse >= 0x3FFF) + // Shouldn't ever be this large + hypotenuse = 0x3FFF; + + entry = hypotenuse | flags; + _nodes[idx].indexes[nodeIndex] = entry; + _nodes[nodeIndex].indexes[idx] = entry; + } + } +} + +int MadsSceneResources::getRouteFlags(const Common::Point &src, const Common::Point &dest, M4Surface *depthSurface) { + int result = 0x8000; + bool flag = false; + + int xDiff = ABS(dest.x - src.x); + int yDiff = ABS(dest.y - src.y); + int xDirection = dest.x >= src.x ? 1 : -1; + int yDirection = dest.y >= src.y ? depthSurface->width() : -depthSurface->width(); + int majorDiff = 0; + if (dest.x < src.x) + majorDiff = MAX(xDiff, yDiff); + ++xDiff; + ++yDiff; + + byte *srcP = depthSurface->getBasePtr(src.x, src.y); + + int totalCtr = majorDiff; + for (int xCtr = 0; xCtr < xDiff; ++xCtr, srcP += xDirection) { + totalCtr += yDiff; + + if ((*srcP & 0x80) == 0) + flag = false; + else if (!flag) { + flag = true; + result -= 0x4000; + if (result == 0) + break; + } + + while (totalCtr >= xDiff) { + totalCtr -= xDiff; + + if ((*srcP & 0x80) == 0) + flag = false; + else if (!flag) { + flag = true; + result -= 0x4000; + if (result == 0) + break; + } + + srcP += yDirection; + } + if (result == 0) + break; + } + + return result; +} /*--------------------------------------------------------------------------*/ @@ -1024,7 +1021,7 @@ void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) { } bool MadsInterfaceView::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) { - MadsAction &act = _madsVm->scene()->getAction(); + MadsAction &act = _madsVm->scene()->_action; // If the mouse isn't being held down, then reset the repeated scroll timer if (eventType != MEVENT_LEFT_HOLD) @@ -1071,7 +1068,7 @@ bool MadsInterfaceView::onEvent(M4EventType eventType, int32 param1, int x, int act._flags1 = obj->vocabList[1].flags1; act._flags2 = obj->vocabList[1].flags2; - act._currentHotspot = _selectedObject; + act._action.verbId = _selectedObject; act._articleNumber = act._flags2; } } @@ -1124,8 +1121,13 @@ bool MadsInterfaceView::handleCheatKey(int32 keycode) { // TODO: Move player to current destination return true; - case Common::KEYCODE_t | (Common::KEYCODE_LALT): - case Common::KEYCODE_t | (Common::KEYCODE_RALT): + case Common::KEYCODE_c | (Common::KBD_CTRL << 24): + // Toggle display of mouse position + _madsVm->scene()->_showMousePos = !_madsVm->scene()->_showMousePos; + break; + + case Common::KEYCODE_t | (Common::KEYCODE_LALT << 24): + case Common::KEYCODE_t | (Common::KEYCODE_RALT << 24): { // Teleport to room //Scene *sceneView = (Scene *)vm->_viewManager->getView(VIEWID_SCENE); diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h index e671dfb194..7723058cc7 100644 --- a/engines/m4/mads_scene.h +++ b/engines/m4/mads_scene.h @@ -36,15 +36,37 @@ namespace M4 { class MadsInterfaceView; #define DEPTH_BANDS_SIZE 15 +#define MAX_ROUTE_NODES 22 + +enum ScreenCategory {CAT_NONE = 0, CAT_ACTION = 1, CAT_INV_LIST = 2, CAT_INV_VOCAB, CAT_HOTSPOT = 4, + CAT_INV_ANIM = 6, CAT_6, CAT_INV_SCROLLER = 7, CAT_12 = 12}; + +class SceneNode { +public: + Common::Point pt; + int indexes[MAX_ROUTE_NODES]; + + bool active; + + SceneNode() { + active = false; + } + + void load(Common::SeekableReadStream *stream); +}; + +typedef Common::Array<SceneNode> SceneNodeList; class MadsSceneResources: public SceneResources { +private: + int getRouteFlags(const Common::Point &src, const Common::Point &dest, M4Surface *depthSurface); public: int _sceneId; int _artFileNum; int _depthStyle; int _width; int _height; - Common::Array<MadsObject> _objects; + SceneNodeList _nodes; Common::Array<Common::String> _setNames; int _yBandsStart, _yBandsEnd; int _maxScale, _minScale; @@ -55,52 +77,19 @@ public: void load(int sceneId, const char *resName, int v0, M4Surface *depthSurface, M4Surface *surface); int bandsRange() const { return _yBandsEnd - _yBandsStart; } int scaleRange() const { return _maxScale - _minScale; } -}; - -enum MadsActionMode {ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6}; -enum MAdsActionMode2 {ACTMODE2_0 = 0, ACTMODE2_2 = 2, ACTMODE2_5 = 5}; - -class MadsAction { -private: - char _statusText[100]; - - void appendVocab(int vocabId, bool capitalise = false); -public: - int _currentHotspot; - int _objectNameId; - int _objectDescId; - int _currentAction; - int8 _flags1, _flags2; - MadsActionMode _actionMode; - MAdsActionMode2 _actionMode2; - int _articleNumber; - bool _lookFlag; - int _selectedRow; - // Unknown fields - int16 _word_86F3A; - int16 _word_86F42; - int16 _word_86F4E; - int16 _word_86F4A; - int16 _word_83334; - int16 _word_86F4C; - -public: - MadsAction(); - - void clear(); - void set(); - const char *statusText() const { return _statusText; } + void setRouteNode(int nodeIndex, const Common::Point &pt, M4Surface *depthSurface); }; class MadsScene : public Scene, public MadsView { private: MadsEngine *_vm; MadsSceneResources _sceneResources; - MadsAction _action; Animation *_activeAnimation; MadsSceneLogic _sceneLogic; SpriteAsset *_playerSprites; + int _mouseMsgIndex; + int _highlightedHotspot; void drawElements(); void loadScene2(const char *aaName, int sceneNumber); @@ -109,8 +98,16 @@ private: void clearAction(); void appendActionVocab(int vocabId, bool capitalise); void setAction(); + void checkStartWalk(); + void doPreactions(); + void doSceneStep(); + void doAction(); public: char _aaName[100]; + bool _showMousePos; + Common::Point _destPos; + int _destFacing; + Common::Point _customDest; public: MadsScene(MadsEngine *vm); virtual ~MadsScene(); @@ -120,7 +117,7 @@ public: virtual void leaveScene(); virtual void loadSceneCodes(int sceneNumber, int index = 0); virtual void show(); - virtual void checkHotspotAtMousePos(int x, int y); + virtual void mouseMove(int x, int y); virtual void leftClick(int x, int y); virtual void rightClick(int x, int y); virtual void setAction(int action, int objectId = -1); @@ -136,8 +133,8 @@ public: MadsInterfaceView *getInterface() { return (MadsInterfaceView *)_interfaceSurface; } MadsSceneResources &getSceneResources() { return _sceneResources; } - MadsAction &getAction() { return _action; } - void setStatusText(const char *text) {}//***DEPRECATED*** + bool getDepthHighBit(const Common::Point &pt); + bool getDepthHighBits(const Common::Point &pt); }; #define CHEAT_SEQUENCE_MAX 8 diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp index d7e6435b14..3e5f0c2ac9 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -37,6 +37,307 @@ namespace M4 { +MadsAction::MadsAction(MadsView &owner): _owner(owner) { + clear(); + _currentAction = kVerbNone; + _startWalkFlag = false; + _statusTextIndex = -1; + _selectedAction = 0; + _inProgress = false; +} + +void MadsAction::clear() { + _v83338 = 1; + _actionMode = ACTMODE_NONE; + _actionMode2 = ACTMODE2_0; + _v86F42 = 0; + _v86F4E = 0; + _articleNumber = 0; + _lookFlag = false; + _v86F4A = 0; + _statusText[0] = '\0'; + _selectedRow = -1; + _hotspotId = -1; + _v86F3A = -1; + _v86F4C = -1; + _action.verbId = -1; + _action.objectNameId = -1; + _action.indirectObjectId = -1; + _textChanged = true; + _walkFlag = false; +} + +void MadsAction::appendVocab(int vocabId, bool capitalise) { + char *s = _statusText + strlen(_statusText); + const char *vocabStr = _madsVm->globals()->getVocab(vocabId); + strcpy(s, vocabStr); + if (capitalise) + *s = toupper(*s); + + strcat(s, " "); +} + +void MadsAction::set() { + int hotspotCount = _madsVm->scene()->getSceneResources().hotspots->size(); + bool flag = false; + strcpy(_statusText, ""); + + _currentAction = -1; + _action.objectNameId = -1; + _action.indirectObjectId = -1; + + if (_actionMode == ACTMODE_TALK) { + // Handle showing the conversation selection. Rex at least doesn't actually seem to use this + if (_selectedRow >= 0) { + const char *desc = _madsVm->_converse[_selectedRow].desc; + if (desc) + strcpy(_statusText, desc); + } + } else if (_lookFlag && (_selectedRow == 0)) { + // Two 'look' actions in succession, so the action becomes 'Look around' + strcpy(_statusText, lookAroundStr); + } else { + if ((_actionMode == ACTMODE_OBJECT) && (_selectedRow >= 0) && (_flags1 == 2) && (_flags2 == 0)) { + // Use/to action + int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject(); + MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject); + + _action.objectNameId = objEntry->descId; + _currentAction = objEntry->vocabList[_selectedRow].vocabId; + + // Set up the status text stirng + strcpy(_statusText, useStr); + appendVocab(_action.objectNameId); + strcpy(_statusText, toStr); + appendVocab(_currentAction); + } else { + // Handling for if an action has been selected + if (_selectedRow >= 0) { + if (_actionMode == ACTMODE_VERB) { + // Standard verb action + _currentAction = verbList[_selectedRow].verb; + } else { + // Selected action on an inventory object + int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject(); + MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject); + + _currentAction = objEntry->vocabList[_selectedRow].vocabId; + } + + appendVocab(_currentAction, true); + + if (_currentAction == kVerbLook) { + // Add in the word 'add' + strcat(_statusText, atStr); + strcat(_statusText, " "); + } + } + + // Handling for if a hotspot has been selected/highlighted + if ((_hotspotId >= 0) && (_selectedRow >= 0) && (_articleNumber > 0) && (_flags1 == 2)) { + flag = true; + + strcat(_statusText, englishMADSArticleList[_articleNumber]); + strcat(_statusText, " "); + } + + if (_hotspotId >= 0) { + if (_selectedRow < 0) { + int verbId; + + if (_hotspotId < hotspotCount) { + // Get the verb Id from the hotspot + verbId = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getVerbID(); + } else { + // Get the verb Id from the scene object + verbId = (*_madsVm->scene()->getSceneResources().dynamicHotspots)[_hotspotId - hotspotCount].getVerbID(); + } + + if (verbId > 0) { + // Set the specified action + _currentAction = verbId; + appendVocab(_currentAction, true); + } else { + // Default to a standard 'walk to' + _currentAction = kVerbWalkTo; + strcat(_statusText, walkToStr); + } + } + + if ((_actionMode2 == ACTMODE2_2) || (_actionMode2 == ACTMODE2_5)) { + // Get name from given inventory object + int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_hotspotId); + _action.objectNameId = _madsVm->globals()->getObject(objectId)->descId; + } else if (_hotspotId < hotspotCount) { + // Get name from scene hotspot + _action.objectNameId = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getVocabID(); + } else { + // Get name from temporary scene hotspot + _action.objectNameId = (*_madsVm->scene()->getSceneResources().dynamicHotspots)[_hotspotId].getVocabID(); + } + appendVocab(_action.objectNameId); + } + } + + if ((_hotspotId >= 0) && (_articleNumber > 0) && !flag) { + if (_articleNumber == -1) { + if (_v86F3A >= 0) { + int articleNum = 0; + + if ((_v86F42 == 2) || (_v86F42 == 5)) { + int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_hotspotId); + articleNum = _madsVm->globals()->getObject(objectId)->article; + } else if (_v86F3A < hotspotCount) { + articleNum = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getArticle(); + } else { + + } + } + + } else if ((_articleNumber == kVerbLook) || (_vm->getGameType() != GType_RexNebular) || + (strcmp(_madsVm->globals()->getVocab(_action.indirectObjectId), fenceStr) != 0)) { + // Write out the article + strcat(_statusText, englishMADSArticleList[_articleNumber]); + } else { + // Special case for a 'fence' entry in Rex Nebular + strcat(_statusText, overStr); + } + + strcat(_statusText, " "); + } + + // Append object description if necessary + if (_v86F3A >= 0) + appendVocab(_action.indirectObjectId); + + // Remove any trailing space character + int statusLen = strlen(_statusText); + if ((statusLen > 0) && (_statusText[statusLen - 1] == ' ')) + _statusText[statusLen - 1] = '\0'; + } + + _textChanged = true; +} + +void MadsAction::refresh() { + // Exit immediately if nothing has changed + if (!_textChanged) + return; + + // Remove any old copy of the status text + if (_statusTextIndex >= 0) { + _owner._textDisplay.expire(_statusTextIndex); + _statusTextIndex = -1; + } + + if (strlen(_statusText) != 0) { + if ((_owner._screenObjects._v832EC == 0) || (_owner._screenObjects._v832EC == 2)) { + Font *font = _madsVm->_font->getFont(FONT_MAIN_MADS); + int textSpacing = -1; + + int strWidth = font->getWidth(_statusText); + if (strWidth > 320) { + // Too large to fit, so fall back on interface font + font = _madsVm->_font->getFont(FONT_INTERFACE_MADS); + strWidth = font->getWidth(_statusText, 0); + textSpacing = 0; + } + + // Add a new text display entry to display the status text at the bottom of the screen area + uint colours = (_vm->getGameType() == GType_DragonSphere) ? 0x0300 : 0x0003; + + _statusTextIndex = _owner._textDisplay.add(160 - (strWidth / 2), + MADS_SURFACE_HEIGHT + _owner._posAdjust.y - 13, colours, textSpacing, _statusText, font); + } + } + + _textChanged = false; +} + +void MadsAction::startAction() { + _madsVm->_player.moveComplete(); + + _inProgress = true; + _v8453A = 0; + _savedFields.selectedRow = _selectedRow; + _savedFields.articleNumber = _articleNumber; + _savedFields.actionMode = _actionMode; + _savedFields.actionMode2 = _actionMode2; + _savedFields.lookFlag = _lookFlag; + int savedHotspotId = _hotspotId; + int savedV86F3A = _v86F3A; + int savedV86F42 = _v86F42; + + // Copy the action to be active + _activeAction = _action; + strcpy(_dialogTitle, _statusText); + + if ((_savedFields.actionMode2 == ACTMODE2_4) && (savedV86F42 == 0)) + _v8453A = true; + + _startWalkFlag = false; + int hotspotId = -1; + HotSpotList &dynHotspots = *_madsVm->scene()->getSceneResources().dynamicHotspots; + HotSpotList &hotspots = *_madsVm->scene()->getSceneResources().hotspots; + + if (!_savedFields.lookFlag && (_madsVm->scene()->_screenObjects._v832EC != 1)) { + if (_savedFields.actionMode2 == ACTMODE2_4) + hotspotId = savedHotspotId; + else if (savedV86F42 == 4) + hotspotId = savedV86F3A; + + if (hotspotId >= hotspots.size()) { + HotSpot &hs = dynHotspots[hotspotId - hotspots.size()]; + if ((hs.getFeetX() == -1) || (hs.getFeetX() == -3)) { + if (_v86F4A && ((hs.getFeetX() == -3) || (_savedFields.selectedRow < 0))) { + _startWalkFlag = true; + _madsVm->scene()->_destPos = _madsVm->scene()->_customDest; + } + } else if ((hs.getFeetX() >= 0) && ((_savedFields.actionMode == ACTMODE_NONE) || (hs.getCursor() < 2))) { + _startWalkFlag = true; + _madsVm->scene()->_destPos.x = hs.getFeetX(); + _madsVm->scene()->_destPos.y = hs.getFeetY(); + } + _madsVm->scene()->_destFacing = hs.getFacing(); + hotspotId = -1; + } + } + + if (hotspotId >= 0) { + HotSpot &hs = hotspots[hotspotId]; + if ((hs.getFeetX() == -1) || (hs.getFeetX() == -3)) { + if (_v86F4A && ((hs.getFeetX() == -3) || (_savedFields.selectedRow < 0))) { + _startWalkFlag = true; + _madsVm->scene()->_destPos = _madsVm->scene()->_customDest; + } + } else if ((hs.getFeetX() >= 0) && ((_savedFields.actionMode == ACTMODE_NONE) || (hs.getCursor() < 2))) { + _startWalkFlag = true; + _madsVm->scene()->_destPos.x = hs.getFeetX(); + _madsVm->scene()->_destPos.y = hs.getFeetY(); + } + _madsVm->scene()->_destFacing = hs.getFacing(); + } + + _walkFlag = _startWalkFlag; +} + +void MadsAction::checkAction() { + if (isAction(kVerbLookAt) || isAction(kVerbThrow)) + _startWalkFlag = 0; +} + +bool MadsAction::isAction(int verbId, int objectNameId, int indirectObjectId) { + if (_activeAction.verbId != verbId) + return false; + if ((objectNameId != 0) && (_activeAction.objectNameId != objectNameId)) + return false; + if ((indirectObjectId != 0) && (_activeAction.indirectObjectId != indirectObjectId)) + return false; + return true; +} + +//-------------------------------------------------------------------------- + bool MadsSpriteSlot::operator==(const SpriteSlotSubset &other) const { return (spriteListIndex == other.spriteListIndex) && (frameNumber == other.frameNumber) && (xp == other.xp) && (yp == other.yp) && (depth == other.depth) && (scale == other.scale); @@ -190,8 +491,8 @@ void MadsSpriteSlots::drawForeground(M4Surface *viewport) { // Get a list of sprite object depths for active objects for (int i = 0; i < startIndex; ++i) { - if (_entries[i].spriteType >= 0) { - DepthEntry rec(_entries[i].depth, i); + if (_entries[i].spriteType >= SPRITE_ZERO) { + DepthEntry rec(16 - _entries[i].depth, i); depthList.push_back(rec); } } @@ -618,6 +919,18 @@ void MadsKernelMessageList::processText(int msgIndex) { //-------------------------------------------------------------------------- +ScreenObjects::ScreenObjects(MadsView &owner): _owner(owner) { + _v832EC = 0; + _v7FECA = 0; + _v7FED6 = 0; + _v8332A = 0; + _yp = 0; + _v8333C = 0; + _selectedObject = 0; + _category = 0; + _objectIndex = 0; +} + /** * Clears the entries list */ @@ -670,6 +983,29 @@ void ScreenObjects::setActive(int category, int idx, bool active) { } } +void ScreenObjects::check(bool scanFlag, bool mouseClick) { + if (!mouseClick || _v832EC) + _v7FECA = 0; + + if (!_v7FED6 && !_v8332A && !_yp && (_v8333C != 0)) { + if (scanFlag) { + _category = CAT_NONE; + _selectedObject = scanBackwards(_madsVm->_mouse->currentPos().x, _madsVm->_mouse->currentPos().y, + LAYER_GUI); + + if (_selectedObject > 0) { + ScreenObjectEntry &obj = _entries[_selectedObject]; + _category = obj.category & 7; + _objectIndex = obj.index; + } + + // TODO: Other stuff related to the user interface + } + } + + _owner._action.refresh(); +} + /*--------------------------------------------------------------------------*/ MadsDynamicHotspots::MadsDynamicHotspots(MadsView &owner): _owner(owner) { @@ -678,7 +1014,7 @@ MadsDynamicHotspots::MadsDynamicHotspots(MadsView &owner): _owner(owner) { rec.active = false; _entries.push_back(rec); } - _flag = true; + _changed = true; _count = 0; } @@ -702,7 +1038,7 @@ int MadsDynamicHotspots::add(int descId, int field14, int seqIndex, const Common _entries[idx].field_17 = 0; ++_count; - _flag = true; + _changed = true; if (seqIndex >= 0) _owner._sequenceList[seqIndex].dynamicHotspotIndex = idx; @@ -734,7 +1070,7 @@ void MadsDynamicHotspots::remove(int index) { _entries[index].active = false; --_count; - _flag = true; + _changed = true; } } @@ -743,7 +1079,7 @@ void MadsDynamicHotspots::reset() { _entries[i].active = false; _count = 0; - _flag = false; + _changed = false; } /*--------------------------------------------------------------------------*/ @@ -929,7 +1265,7 @@ bool MadsSequenceList::addSubEntry(int index, SequenceSubEntryMode mode, int fra return false; } -int MadsSequenceList::add(int spriteListIndex, int v0, int frameIndex, int triggerCountdown, int delayTicks, int extraTicks, int numTicks, +int MadsSequenceList::add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks, int extraTicks, int numTicks, int msgX, int msgY, bool nonFixed, char scale, uint8 depth, int frameInc, SpriteAnimType animType, int numSprites, int frameStart) { @@ -950,7 +1286,7 @@ int MadsSequenceList::add(int spriteListIndex, int v0, int frameIndex, int trigg // Set the list entry fields _entries[seqIndex].active = true; _entries[seqIndex].spriteListIndex = spriteListIndex; - _entries[seqIndex].field_2 = v0; + _entries[seqIndex].flipped = flipped; _entries[seqIndex].frameIndex = frameIndex; _entries[seqIndex].frameStart = frameStart; _entries[seqIndex].numSprites = numSprites; @@ -996,7 +1332,7 @@ void MadsSequenceList::setSpriteSlot(int seqIndex, MadsSpriteSlot &spriteSlot) { spriteSlot.spriteType = spriteSet.isBackground() ? BACKGROUND_SPRITE : FOREGROUND_SPRITE; spriteSlot.seqIndex = seqIndex; spriteSlot.spriteListIndex = timerEntry.spriteListIndex; - spriteSlot.frameNumber = ((timerEntry.field_2 == 1) ? 0x8000 : 0) | timerEntry.frameIndex; + spriteSlot.frameNumber = (timerEntry.flipped ? 0x8000 : 0) | timerEntry.frameIndex; spriteSlot.depth = timerEntry.depth; spriteSlot.scale = timerEntry.scale; @@ -1048,7 +1384,7 @@ bool MadsSequenceList::loadSprites(int seqIndex) { dynHotspot.bounds.top = MAX(y2 - height, 0); dynHotspot.bounds.bottom = MIN(y2, 155) - dynHotspot.bounds.top; - _owner._dynamicHotspots._flag = true; + _owner._dynamicHotspots._changed = true; } } @@ -1197,6 +1533,13 @@ void MadsSequenceList::scan() { } } +/** + * Sets the depth of the specified entry in the sequence list + */ +void MadsSequenceList::setDepth(int seqIndex, int depth) { + _entries[seqIndex].depth = depth; +} + //-------------------------------------------------------------------------- Animation::Animation(MadsM4Engine *vm): _vm(vm) { @@ -1208,7 +1551,8 @@ Animation::~Animation() { //-------------------------------------------------------------------------- MadsView::MadsView(View *view): _view(view), _dynamicHotspots(*this), _sequenceList(*this), - _kernelMessages(*this), _spriteSlots(*this), _dirtyAreas(*this), _textDisplay(*this) { + _kernelMessages(*this), _spriteSlots(*this), _dirtyAreas(*this), _textDisplay(*this), + _screenObjects(*this), _action(*this) { _textSpacing = -1; _newTimeout = 0; diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index 0604ae1ee1..c93d0beda3 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -36,6 +36,69 @@ namespace M4 { class MadsView; +enum MadsActionMode {ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6}; +enum MAdsActionMode2 {ACTMODE2_0 = 0, ACTMODE2_2 = 2, ACTMODE2_4 = 4, ACTMODE2_5 = 5}; + +struct ActionDetails { + int verbId; + int objectNameId; + int indirectObjectId; +}; + +struct MadsActionSavedFields { + int articleNumber; + int actionMode; + int actionMode2; + bool lookFlag; + int selectedRow; +}; + +class MadsAction { +private: + MadsView &_owner; + char _statusText[100]; + char _dialogTitle[100]; + + void appendVocab(int vocabId, bool capitalise = false); +public: + ActionDetails _action, _activeAction; + int _currentAction; + int8 _flags1, _flags2; + MadsActionMode _actionMode; + MAdsActionMode2 _actionMode2; + int _articleNumber; + bool _lookFlag; + int _selectedRow; + bool _textChanged; + int _selectedAction; + bool _startWalkFlag; + int _statusTextIndex; + int _hotspotId; + MadsActionSavedFields _savedFields; + bool _walkFlag; + + // Unknown fields + int16 _v86F3A; + int16 _v86F42; + int16 _v86F4E; + bool _v86F4A; + int16 _v86F4C; + int _v83338; + bool _inProgress; + bool _v8453A; + +public: + MadsAction(MadsView &owner); + + void clear(); + void set(); + const char *statusText() const { return _statusText; } + void refresh(); + void startAction(); + void checkAction(); + bool isAction(int verbId, int objectNameId = 0, int indirectObjectId = 0); +}; + enum AbortTimerMode {ABORTMODE_0 = 0, ABORTMODE_1 = 1, ABORTMODE_2 = 2}; class SpriteSlotSubset { @@ -211,10 +274,20 @@ public: class ScreenObjects { private: + MadsView &_owner; Common::Array<ScreenObjectEntry> _entries; public: - ScreenObjects() {} - + int _v832EC; + int _v7FECA; + int _v7FED6; + int _v8332A; + int _yp; + int _v8333C; + int _selectedObject; + int _category; + int _objectIndex; + + ScreenObjects(MadsView &owner); ScreenObjectEntry &operator[](uint idx) { assert(idx <= _entries.size()); return _entries[idx - 1]; @@ -226,6 +299,7 @@ public: int scan(int xp, int yp, int layer); int scanBackwards(int xp, int yp, int layer); void setActive(int category, int idx, bool active); + void check(bool scanFlag, bool mouseClick); }; class DynamicHotspot { @@ -251,7 +325,7 @@ private: Common::Array<DynamicHotspot> _entries; int _count; public: - bool _flag; + bool _changed; public: MadsDynamicHotspots(MadsView &owner); @@ -261,6 +335,9 @@ public: int set17(int index, int v); void remove(int index); void reset(); + void refresh() { + // TODO + } }; class MadsDirtyArea { @@ -314,8 +391,7 @@ struct MadsSequenceSubEntries { struct MadsSequenceEntry { int8 active; int8 spriteListIndex; - - int field_2; + bool flipped; int frameIndex; int frameStart; @@ -355,9 +431,9 @@ public: MadsSequenceEntry &operator[](int index) { return _entries[index]; } void clear(); bool addSubEntry(int index, SequenceSubEntryMode mode, int frameIndex, int abortVal); - int add(int spriteListIndex, int v0, int v1, int triggerCountdown, int delayTicks, int extraTicks, int numTicks, - int msgX, int msgY, bool nonFixed, char scale, uint8 depth, int frameInc, SpriteAnimType animType, - int numSprites, int frameStart); + int add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks, + int extraTicks, int numTicks, int msgX, int msgY, bool nonFixed, char scale, uint8 depth, + int frameInc, SpriteAnimType animType, int numSprites, int frameStart); void remove(int seqIndex); void setSpriteSlot(int seqIndex, MadsSpriteSlot &spriteSlot); bool loadSprites(int seqIndex); @@ -365,6 +441,7 @@ public: void delay(uint32 v1, uint32 v2); void setAnimRange(int seqIndex, int startVal, int endVal); void scan(); + void setDepth(int seqIndex, int depth); }; class Animation { @@ -393,6 +470,7 @@ public: MadsDynamicHotspots _dynamicHotspots; MadsSequenceList _sequenceList; MadsDirtyAreas _dirtyAreas; + MadsAction _action; int _textSpacing; uint32 _newTimeout; diff --git a/engines/m4/rails.cpp b/engines/m4/rails.cpp index fbad6995eb..11b9bcdbb9 100644 --- a/engines/m4/rails.cpp +++ b/engines/m4/rails.cpp @@ -179,7 +179,7 @@ long SqrtF16(long n) { uint32 r = 0, s; uint32 v = (uint32)n; - for (int i = 15; i <= 0; i--) { + for (int i = 15; i >= 0; --i) { s = r + (1L << i * 2); r >>= 1; if (s <= v) { diff --git a/engines/m4/rails.h b/engines/m4/rails.h index a7add5a8eb..e3183c243f 100644 --- a/engines/m4/rails.h +++ b/engines/m4/rails.h @@ -93,6 +93,8 @@ private: bool isLineWalkable(int x0, int y0, int x1, int y1); }; +long SqrtF16(long n); + } // End of namespace M4 #endif diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp index e78d7f865e..8457f2087a 100644 --- a/engines/m4/scene.cpp +++ b/engines/m4/scene.cpp @@ -44,7 +44,7 @@ Scene::Scene(MadsM4Engine *vm, SceneResources *res): View(vm, Common::Rect(0, 0, _screenType = VIEWID_SCENE; _sceneResources->hotspots = new HotSpotList(); - _sceneResources->props = new HotSpotList(); + _sceneResources->dynamicHotspots = new HotSpotList(); _backgroundSurface = new M4Surface(); _walkSurface = new M4Surface(); _palData = NULL; @@ -61,6 +61,7 @@ Scene::~Scene() { void Scene::loadScene(int sceneNumber) { _previousScene = _currentScene; _currentScene = sceneNumber; + _nextScene = sceneNumber; } void Scene::leaveScene() { @@ -123,14 +124,14 @@ void Scene::showHotSpots() { HotSpot *currentHotSpot; // hotspots (green) - for (i = 0; i < _sceneResources->hotspotCount; i++) { + for (i = 0; i < _sceneResources->hotspots->size(); i++) { currentHotSpot = _sceneResources->hotspots->get(i); _backgroundSurface->frameRect(currentHotSpot->getRect(), _vm->_palette->GREEN); } - // props (red) - for (i = 0; i < _sceneResources->propsCount; i++) { - currentHotSpot = _sceneResources->props->get(i); + // Dynamic hotspots (red) + for (i = 0; i < _sceneResources->dynamicHotspots->size(); i++) { + currentHotSpot = _sceneResources->dynamicHotspots->get(i); _backgroundSurface->frameRect(currentHotSpot->getRect(), _vm->_palette->RED); } } @@ -154,8 +155,21 @@ void Scene::showCodes() { colors[255 * 4 + 2] = 255; _vm->_palette->setPalette(colors, 0, 256); } else { - // For MADS, simply copy the walk data to the background, in whatever current palette is active + // MADS handling + + // copy the walk data to the background, in whatever current palette is active _walkSurface->copyTo(_backgroundSurface); + + // Show all the scene's walk nodes + SceneNodeList &nodeList = _madsVm->scene()->getSceneResources()._nodes; + _backgroundSurface->setColour(_madsVm->_palette->WHITE); + for (uint i = 0; i < nodeList.size() - 2; ++i) { + // Draw a little cross at the node's position + _backgroundSurface->hLine(nodeList[i].pt.x - 2, nodeList[i].pt.x + 2, nodeList[i].pt.y); + _backgroundSurface->vLine(nodeList[i].pt.x, nodeList[i].pt.y - 2, nodeList[i].pt.y + 2); + } + + ((MadsScene *)this)->_spriteSlots.fullRefresh(); } } @@ -184,7 +198,7 @@ bool Scene::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &cap rightClick(x, y); break; case MEVENT_MOVE: - checkHotspotAtMousePos(x, y); + mouseMove(x, y); break; default: return false; diff --git a/engines/m4/scene.h b/engines/m4/scene.h index 633a34b549..9262a7c828 100644 --- a/engines/m4/scene.h +++ b/engines/m4/scene.h @@ -53,17 +53,16 @@ enum MADSVerbs { kVerbPull = 10, kVerbClose = 11, kVerbThrow = 12, - kVerbWalkTo = 13 + kVerbWalkTo = 13, + kVerbLookAt = 209 }; class SceneResources { public: char artBase[MAX_CHK_FILENAME_SIZE]; char pictureBase[MAX_CHK_FILENAME_SIZE]; - int32 hotspotCount; HotSpotList *hotspots; - int32 propsCount; - HotSpotList *props; + HotSpotList *dynamicHotspots; int32 frontY, backY; int32 frontScale, backScale; int16 depthTable[16]; @@ -80,6 +79,7 @@ private: protected: int _currentScene; int _previousScene; + int _nextScene; GameInterfaceView *_interfaceSurface; M4Surface *_backgroundSurface; M4Surface *_walkSurface; @@ -95,7 +95,7 @@ public: virtual void leaveScene(); virtual void loadSceneCodes(int sceneNumber, int index = 0) = 0; virtual void show(); - virtual void checkHotspotAtMousePos(int x, int y) = 0; + virtual void mouseMove(int x, int y) = 0; virtual void leftClick(int x, int y) = 0; virtual void rightClick(int x, int y) = 0; virtual void update() = 0; diff --git a/engines/made/database.cpp b/engines/made/database.cpp index ae1a08e1b5..51308cb7e5 100644 --- a/engines/made/database.cpp +++ b/engines/made/database.cpp @@ -515,6 +515,8 @@ int16 GameDatabaseV2::loadgame(const char *filename, int16 version) { _objects[i]->load(*in); } delete in; + + _objectPropertyCache.clear(); // make sure to clear cache return result; } @@ -644,6 +646,8 @@ void GameDatabaseV3::load(Common::SeekableReadStream &sourceS) { void GameDatabaseV3::reloadFromStream(Common::SeekableReadStream &sourceS) { sourceS.seek(_gameStateOffs); sourceS.read(_gameState, _gameStateSize); + + _objectPropertyCache.clear(); // make sure to clear cache } bool GameDatabaseV3::getSavegameDescription(const char *filename, Common::String &description, int16 version) { @@ -734,6 +738,9 @@ int16 GameDatabaseV3::loadgame(const char *filename, int16 version) { in->skip(64); // skip savegame description in->read(_gameState, _gameStateSize); delete in; + + _objectPropertyCache.clear(); // make sure to clear cache + return 0; } diff --git a/engines/made/detection.cpp b/engines/made/detection.cpp index dd2becd3b8..6a6a70cb30 100644 --- a/engines/made/detection.cpp +++ b/engines/made/detection.cpp @@ -76,7 +76,6 @@ using Common::GUIO_NONE; using Common::GUIO_NOSPEECH; static const MadeGameDescription gameDescriptions[] = { - { // NOTE: Return to Zork entries with *.dat are used to detect the game via rtzcd.dat, // which is packed inside rtzcd.red. Entries with *.red refer to the packed file @@ -329,6 +328,60 @@ static const MadeGameDescription gameDescriptions[] = { }, { + // Return to Zork - Japanese DOS + // This is the RTZCD.DAT in the base directory of the FM-Towns CD + { + "rtz", + "", + AD_ENTRY1("rtzcd.dat", "c4fccf67ad247f09b94c3c808b138576"), + Common::JA_JPN, + Common::kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NONE + }, + GID_RTZ, + 0, + GF_CD, + 3, + }, + + { + // Return to Zork - Japanese FM-Towns + // This is in the RTZFM folder of the FM-Towns CD + { + "rtz", + "", + AD_ENTRY1("rtzcd.dat", "e949a6a42d82daabfa7d4dc0a87a9843"), + Common::JA_JPN, + Common::kPlatformFMTowns, + ADGF_NO_FLAGS, + GUIO_NONE + }, + GID_RTZ, + 0, + GF_CD, + 3, + }, + + { + // Return to Zork - Japanese PC-98 + // This is in the RTZ9821 folder of the FM-Towns CD + { + "rtz", + "", + AD_ENTRY1("rtzcd.dat", "0c0117e98530c736a141c2aad6834dc5"), + Common::JA_JPN, + Common::kPlatformPC98, + ADGF_NO_FLAGS, + GUIO_NONE + }, + GID_RTZ, + 0, + GF_CD, + 3, + }, + + { // The Manhole: New and Enhanced { "manhole", diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp index 28d46cf4ec..cdcb49f9f9 100644 --- a/engines/made/resource.cpp +++ b/engines/made/resource.cpp @@ -50,10 +50,9 @@ PictureResource::~PictureResource() { delete _picture; _picture = 0; } - if (_picturePalette) { - delete[] _picturePalette; - _picturePalette = 0; - } + + delete[] _picturePalette; + _picturePalette = 0; } void PictureResource::load(byte *source, int size) { diff --git a/engines/made/scriptfuncs.cpp b/engines/made/scriptfuncs.cpp index b1a8b0ff84..2f069e882e 100644 --- a/engines/made/scriptfuncs.cpp +++ b/engines/made/scriptfuncs.cpp @@ -27,6 +27,7 @@ #include "common/util.h" #include "common/events.h" #include "graphics/cursorman.h" +#include "sound/softsynth/pcspk.h" #include "made/made.h" #include "made/resource.h" @@ -40,6 +41,22 @@ namespace Made { +ScriptFunctions::ScriptFunctions(MadeEngine *vm) : _vm(vm), _soundStarted(false) { + // Initialize the two tone generators + _pcSpeaker1 = new Audio::PCSpeaker(); + _pcSpeaker2 = new Audio::PCSpeaker(); + _vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_pcSpeakerHandle1, _pcSpeaker1); + _vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_pcSpeakerHandle2, _pcSpeaker2); +} + +ScriptFunctions::~ScriptFunctions() { + for (uint i = 0; i < _externalFuncs.size(); ++i) + delete _externalFuncs[i]; + + _vm->_system->getMixer()->stopHandle(_pcSpeakerHandle1); + _vm->_system->getMixer()->stopHandle(_pcSpeakerHandle2); +} + typedef Common::Functor2Mem<int16, int16*, int16, ScriptFunctions> ExternalScriptFunc; #define External(x) \ _externalFuncs.push_back(new ExternalScriptFunc(this, &ScriptFunctions::x)); \ @@ -307,36 +324,78 @@ int16 ScriptFunctions::sfFlashScreen(int16 argc, int16 *argv) { } int16 ScriptFunctions::sfPlayNote(int16 argc, int16 *argv) { - // TODO: Used in Manhole:NE, Manhole EGA - // This is used when using the piano in the desk screen inside the ship. + // This is used when using the piano in the desk screen inside the ship + // in The Manhole (EGA/NE). + // It takes 2 parameters: - // The first parameter is the key pressed + // The first parameter is the note number of the key pressed + 1 // The second parameter is some sort of modifier (volume, perhaps?), - // depending on which of the 3 keys on the right has been pressed (12 - 14) - warning("Unimplemented opcode: sfPlayNote"); + // depending on which of the 3 keys on the right has been pressed. + // This value seems to be [12, 14] in NE and [1, 3] in EGA. + + // Note frequencies based on http://www.phy.mtu.edu/~suits/notefreqs.html + static const int freqTable[] = { + 16, 17, 18, 19, 21, 22, 23, 24, 26, 28, 29, + 30, 32, 35, 37, 39, 41, 44, 46, 49, 52, 55, + 58, 62, 65, 69, 73, 77, 82, 87, 93, 98, 104, + 110, 117, 123, 131, 139, 147, 156, 165, 175, 195, + 196, 208, 220, 233, 247, 262, 277, 294, 311, 330, + 349, 370, 392, 415, 440, 466, 494, 523, 554, 587, + 622, 659, 698, 740, 784, 831, 880, 932, 988, 1047, + 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, + 1865, 1976, 2093, 2217, 2349, 2489, 2637, 2794, 2960, + 3136, 3322, 3529, 3729, 3951, 4186, 4435, 4697, 4978 + }; + + debug(4, "sfPlayNote: Note = %d, Volume(?) = %d", argv[0] - 1, argv[1]); + + _pcSpeaker1->play(Audio::PCSpeaker::kWaveFormSine, freqTable[argv[0] - 1], -1); + + // TODO: Figure out what to do with the second parameter + //_pcSpeaker1->setVolume(argv[1]); + return 0; } int16 ScriptFunctions::sfStopNote(int16 argc, int16 *argv) { - // TODO: Used in Manhole:NE, Manhole EGA // Used in the same place as sfPlayNote, with the same parameters - warning("Unimplemented opcode: sfStopNote"); + // We just stop the wave generator here + _pcSpeaker1->stop(); return 0; } int16 ScriptFunctions::sfPlayTele(int16 argc, int16 *argv) { - // TODO: Used in Manhole:NE, Manhole EGA // This is used when pressing the phone keys while using the phone in - // the desk screen inside the ship. + // the desk screen inside the ship in The Manhole (EGA/NE). // It takes 1 parameter, the key pressed (0-9, 10 for asterisk, 11 for hash) - warning("Unimplemented opcode: sfPlayTele"); + + // A telephone keypad uses a two tones for each key. + // See http://en.wikipedia.org/wiki/Telephone_keypad for more info + + static const int freqTable1[] = { + 1336, 1209, 1336, 1477, + 1209, 1336, 1477, 1209, + 1336, 1477, 1209, 1477 + }; + + static const int freqTable2[] = { + 941, 697, 697, 697, + 770, 770, 770, 852, + 852, 852, 941, 941 + }; + + debug(4, "sfPlayTele: Button = %d", argv[0]); + + _pcSpeaker1->play(Audio::PCSpeaker::kWaveFormSine, freqTable1[argv[0]], -1); + _pcSpeaker2->play(Audio::PCSpeaker::kWaveFormSine, freqTable2[argv[0]], -1); return 0; } int16 ScriptFunctions::sfStopTele(int16 argc, int16 *argv) { - // TODO: Used in Manhole:NE, Manhole EGA // Used in the same place as sfPlayTele, with the same parameters - warning("Unimplemented opcode: sfStopTele"); + // We just stop both wave generators here + _pcSpeaker1->stop(); + _pcSpeaker2->stop(); return 0; } diff --git a/engines/made/scriptfuncs.h b/engines/made/scriptfuncs.h index 5fdfb77f45..3bed27c5c8 100644 --- a/engines/made/scriptfuncs.h +++ b/engines/made/scriptfuncs.h @@ -33,6 +33,10 @@ #include "made/resource.h" +namespace Audio { + class PCSpeaker; +} + namespace Made { class MadeEngine; @@ -41,17 +45,16 @@ typedef Common::Functor2<int16, int16*, int16> ExternalFunc; class ScriptFunctions { public: - ScriptFunctions(MadeEngine *vm) : _vm(vm), _soundStarted(false) {} - virtual ~ScriptFunctions() { - for (uint i = 0; i < _externalFuncs.size(); ++i) - delete _externalFuncs[i]; - } + ScriptFunctions(MadeEngine *vm); + virtual ~ScriptFunctions(); + int16 callFunction(uint16 index, int16 argc, int16 *argv) { if (index >= _externalFuncs.size()) error("ScriptFunctions::callFunction() Invalid function index %d", index); debug(4, "%s", _externalFuncNames[index]); return (*_externalFuncs[index])(argc, argv); } + void setupExternalsTable(); const char* getFuncName(int index) { return _externalFuncNames[index]; } int getCount() const { return _externalFuncs.size(); } @@ -64,6 +67,10 @@ protected: SoundResource* _soundResource; bool _soundStarted; + // PlayNote/StopNote and PlayTele/StopTele wave generators + Audio::SoundHandle _pcSpeakerHandle1, _pcSpeakerHandle2; + Audio::PCSpeaker *_pcSpeaker1, *_pcSpeaker2; + Common::Array<const ExternalFunc*> _externalFuncs; Common::Array<const char *> _externalFuncNames; GenericResource *_musicRes; diff --git a/engines/parallaction/input.cpp b/engines/parallaction/input.cpp index 6d3f6f0b04..ca8f358158 100644 --- a/engines/parallaction/input.cpp +++ b/engines/parallaction/input.cpp @@ -148,8 +148,7 @@ void Input::readInput() { setCursorPos(e.mouse); } - if (_vm->_debugger->isAttached()) - _vm->_debugger->onFrame(); + _vm->_debugger->onFrame(); return; diff --git a/engines/queen/queen.cpp b/engines/queen/queen.cpp index 10c3d56cb4..5cda4e3208 100644 --- a/engines/queen/queen.cpp +++ b/engines/queen/queen.cpp @@ -264,9 +264,7 @@ void QueenEngine::writeOptionSettings() { } void QueenEngine::update(bool checkPlayerInput) { - if (_debugger->isAttached()) { - _debugger->onFrame(); - } + _debugger->onFrame(); _graphics->update(_logic->currentRoom()); _logic->update(); diff --git a/engines/queen/resource.cpp b/engines/queen/resource.cpp index a43141ef56..1e2eff8458 100644 --- a/engines/queen/resource.cpp +++ b/engines/queen/resource.cpp @@ -96,18 +96,7 @@ ResourceEntry *Resource::resourceEntry(const char *filename) const { entryName.toUppercase(); ResourceEntry *re = NULL; -#ifndef PALMOS_MODE re = (ResourceEntry *)bsearch(entryName.c_str(), _resourceTable, _resourceEntries, sizeof(ResourceEntry), compareResourceEntry); -#else - // PALMOS FIXME (?) : still doesn't work for me (????) use this instead - uint32 cur = 0; - do { - if (!strcmp(entryName.c_str(), _resourceTable[cur].filename)) { - re = &_resourceTable[cur]; - break; - } - } while (++cur < _resourceEntries); -#endif return re; } diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp index 8b7654d689..e4a16e27da 100644 --- a/engines/saga/music.cpp +++ b/engines/saga/music.cpp @@ -158,6 +158,8 @@ Music::Music(SagaEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) { _driver->setGM(_vm->getGameId() != GID_ITE); } else { _parser = MidiParser::createParser_SMF(); + // ITE with standalone MIDI files is General MIDI + _driver->setGM(_vm->getGameId() == GID_ITE); } free(resourceData); } @@ -177,7 +179,6 @@ Music::~Music() { _vm->getTimerManager()->removeTimerProc(&musicVolumeGaugeCallback); _mixer->stopHandle(_musicHandle); _driver->setTimerCallback(NULL, NULL); - _driver->close(); delete _driver; _parser->setMidiDriver(NULL); delete _parser; diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp index d1ab3bc9d7..1b7fa97f8d 100644 --- a/engines/saga/saga.cpp +++ b/engines/saga/saga.cpp @@ -352,8 +352,7 @@ Common::Error SagaEngine::run() { uint32 currentTicks; while (!shouldQuit()) { - if (_console->isAttached()) - _console->onFrame(); + _console->onFrame(); if (_render->getFlags() & RF_RENDERPAUSE) { // Freeze time while paused diff --git a/engines/saga/script.cpp b/engines/saga/script.cpp index 18bbca2425..5fd120ac33 100644 --- a/engines/saga/script.cpp +++ b/engines/saga/script.cpp @@ -571,9 +571,7 @@ void Script::opCall(SCRIPTOP_PARAMS) { if (iparam1 != kAddressModule) { error("Script::runThread iparam1 != kAddressModule"); } - byte *addr = thread->baseAddress(iparam1); iparam1 = scriptS->readSint16LE(); - addr += iparam1; thread->push(argumentsCount); // NOTE: The original pushes the program diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 33aa5514f2..20acbed450 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -93,6 +93,7 @@ Console::Console(SciEngine *engine) : GUI::Debugger(), DCmd_Register("sentence_fragments", WRAP_METHOD(Console, cmdSentenceFragments)); DCmd_Register("parse", WRAP_METHOD(Console, cmdParse)); DCmd_Register("set_parse_nodes", WRAP_METHOD(Console, cmdSetParseNodes)); + DCmd_Register("said", WRAP_METHOD(Console, cmdSaid)); // Resources DCmd_Register("diskdump", WRAP_METHOD(Console, cmdDiskDump)); DCmd_Register("hexdump", WRAP_METHOD(Console, cmdHexDump)); @@ -167,6 +168,7 @@ Console::Console(SciEngine *engine) : GUI::Debugger(), DCmd_Register("disasm_addr", WRAP_METHOD(Console, cmdDisassembleAddress)); DCmd_Register("send", WRAP_METHOD(Console, cmdSend)); DCmd_Register("go", WRAP_METHOD(Console, cmdGo)); + DCmd_Register("logkernel", WRAP_METHOD(Console, cmdLogKernel)); // Breakpoints DCmd_Register("bp_list", WRAP_METHOD(Console, cmdBreakpointList)); DCmd_Register("bplist", WRAP_METHOD(Console, cmdBreakpointList)); // alias @@ -306,6 +308,7 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" sentence_fragments - Shows the sentence fragments (used to build Parse trees)\n"); DebugPrintf(" parse - Parses a sequence of words and prints the resulting parse tree\n"); DebugPrintf(" set_parse_nodes - Sets the contents of all parse nodes\n"); + DebugPrintf(" said - Match a string against a said spec\n"); DebugPrintf("\n"); DebugPrintf("Resources:\n"); DebugPrintf(" diskdump - Dumps the specified resource to disk as a patch file\n"); @@ -372,6 +375,7 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" disasm_addr - Disassembles one or more commands\n"); DebugPrintf(" send - Sends a message to an object\n"); DebugPrintf(" go - Executes the script\n"); + DebugPrintf(" logkernel - Logs kernel calls\n"); DebugPrintf("\n"); DebugPrintf("Breakpoints:\n"); DebugPrintf(" bp_list / bplist / bl - Lists the current breakpoints\n"); @@ -409,6 +413,13 @@ bool Console::cmdGetVersion(int argc, const char **argv) { const char *viewTypeDesc[] = { "Unknown", "EGA", "VGA", "VGA SCI1.1", "Amiga" }; bool hasVocab997 = g_sci->getResMan()->testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS)) ? true : false; + Common::String gameVersion = "N/A"; + + Common::File versionFile; + if (versionFile.open("VERSION")) { + gameVersion = versionFile.readLine(); + versionFile.close(); + } DebugPrintf("Game ID: %s\n", _engine->getGameIdStr()); DebugPrintf("Emulated interpreter version: %s\n", getSciVersionDesc(getSciVersion())); @@ -425,6 +436,7 @@ bool Console::cmdGetVersion(int argc, const char **argv) { DebugPrintf("Resource volume version: %s\n", g_sci->getResMan()->getVolVersionDesc()); DebugPrintf("Resource map version: %s\n", g_sci->getResMan()->getMapVersionDesc()); DebugPrintf("Contains selector vocabulary (vocab.997): %s\n", hasVocab997 ? "yes" : "no"); + DebugPrintf("Game version (VERSION file): %s\n", gameVersion.c_str()); DebugPrintf("\n"); return true; @@ -1099,13 +1111,13 @@ bool Console::cmdRestoreGame(int argc, const char **argv) { return true; } - return false; + return Cmd_Exit(0, 0); } bool Console::cmdRestartGame(int argc, const char **argv) { _engine->_gamestate->abortScriptProcessing = kAbortRestartGame;; - return false; + return Cmd_Exit(0, 0); } bool Console::cmdClassTable(int argc, const char **argv) { @@ -1176,8 +1188,9 @@ bool Console::cmdParse(int argc, const char **argv) { char string[1000]; // Construct the string - strcpy(string, argv[2]); + strcpy(string, argv[1]); for (int i = 2; i < argc; i++) { + strcat(string, " "); strcat(string, argv[i]); } @@ -1209,6 +1222,122 @@ bool Console::cmdParse(int argc, const char **argv) { return true; } +bool Console::cmdSaid(int argc, const char **argv) { + if (argc < 2) { + DebugPrintf("Matches a string against a said spec\n"); + DebugPrintf("Usage: %s <string> > & <said spec>\n", argv[0]); + DebugPrintf("<string> is a sequence of actual words.\n"); + DebugPrintf("<said spec> is a sequence of hex tokens.\n"); + return true; + } + + ResultWordList words; + char *error; + char string[1000]; + byte spec[1000]; + + int p; + // Construct the string + strcpy(string, argv[1]); + for (p = 2; p < argc && strcmp(argv[p],"&") != 0; p++) { + strcat(string, " "); + strcat(string, argv[p]); + } + + if (p >= argc-1) { + DebugPrintf("Matches a string against a said spec\n"); + DebugPrintf("Usage: %s <string> > & <said spec>\n", argv[0]); + DebugPrintf("<string> is a sequence of actual words.\n"); + DebugPrintf("<said spec> is a sequence of hex tokens.\n"); + return true; + } + + // TODO: Maybe turn this into a proper said spec compiler + unsigned int len = 0; + for (p++; p < argc; p++) { + if (strcmp(argv[p], ",") == 0) { + spec[len++] = 0xf0; + } else if (strcmp(argv[p], "&") == 0) { + spec[len++] = 0xf1; + } else if (strcmp(argv[p], "/") == 0) { + spec[len++] = 0xf2; + } else if (strcmp(argv[p], "(") == 0) { + spec[len++] = 0xf3; + } else if (strcmp(argv[p], ")") == 0) { + spec[len++] = 0xf4; + } else if (strcmp(argv[p], "[") == 0) { + spec[len++] = 0xf5; + } else if (strcmp(argv[p], "]") == 0) { + spec[len++] = 0xf6; + } else if (strcmp(argv[p], "#") == 0) { + spec[len++] = 0xf7; + } else if (strcmp(argv[p], "<") == 0) { + spec[len++] = 0xf8; + } else if (strcmp(argv[p], ">") == 0) { + spec[len++] = 0xf9; + } else if (strcmp(argv[p], "[<") == 0) { + spec[len++] = 0xf5; + spec[len++] = 0xf8; + } else if (strcmp(argv[p], "[/") == 0) { + spec[len++] = 0xf5; + spec[len++] = 0xf2; + } else if (strcmp(argv[p], "!*") == 0) { + spec[len++] = 0x0f; + spec[len++] = 0xfe; + } else if (strcmp(argv[p], "[!*]") == 0) { + spec[len++] = 0xf5; + spec[len++] = 0x0f; + spec[len++] = 0xfe; + spec[len++] = 0xf6; + } else { + unsigned int s = strtol(argv[p], 0, 16); + if (s >= 0xf0 && s <= 0xff) { + spec[len++] = s; + } else { + spec[len++] = s >> 8; + spec[len++] = s & 0xFF; + } + } + } + spec[len++] = 0xFF; + + printf("Matching '%s' against:", string); + _engine->getVocabulary()->debugDecipherSaidBlock(spec); + printf("\n"); + + bool res = _engine->getVocabulary()->tokenizeString(words, string, &error); + if (res && !words.empty()) { + int syntax_fail = 0; + + _engine->getVocabulary()->synonymizeTokens(words); + + DebugPrintf("Parsed to the following blocks:\n"); + + for (ResultWordList::const_iterator i = words.begin(); i != words.end(); ++i) + DebugPrintf(" Type[%04x] Group[%04x]\n", i->_class, i->_group); + + if (_engine->getVocabulary()->parseGNF(words, true)) + syntax_fail = 1; // Building a tree failed + + if (syntax_fail) + DebugPrintf("Building a tree failed.\n"); + else { + _engine->getVocabulary()->dumpParseTree(); + _engine->getVocabulary()->parserIsValid = true; + + int ret = said(_engine->_gamestate, (byte*)spec, true); + DebugPrintf("kSaid: %s\n", (ret == SAID_NO_MATCH ? "No match" : "Match")); + } + + } else { + DebugPrintf("Unknown word: '%s'\n", error); + free(error); + } + + return true; +} + + bool Console::cmdParserNodes(int argc, const char **argv) { if (argc != 2) { DebugPrintf("Shows the specified number of nodes from the parse node tree\n"); @@ -1341,7 +1470,7 @@ bool Console::cmdPlayVideo(int argc, const char **argv) { if (filename.hasSuffix(".seq") || filename.hasSuffix(".avi") || filename.hasSuffix(".vmd")) { _videoFile = filename; _videoFrameDelay = (argc == 2) ? 10 : atoi(argv[2]); - return false; + return Cmd_Exit(0, 0); } else { DebugPrintf("Unknown video file type\n"); return true; @@ -1631,7 +1760,7 @@ bool Console::cmdShowMap(int argc, const char **argv) { DebugPrintf("Map %d is not available.\n", map); return true; } - return false; + return Cmd_Exit(0, 0); } bool Console::cmdSongLib(int argc, const char **argv) { @@ -1676,8 +1805,7 @@ bool Console::cmdStartSound(int argc, const char **argv) { } g_sci->_soundCmd->startNewSound(number); - - return false; + return Cmd_Exit(0, 0); } bool Console::cmdToggleSound(int argc, const char **argv) { @@ -2310,7 +2438,7 @@ bool Console::cmdTrace(int argc, const char **argv) { _debugState.runningStep = atoi(argv[1]) - 1; _debugState.debugging = true; - return false; + return Cmd_Exit(0, 0); } bool Console::cmdStepOver(int argc, const char **argv) { @@ -2318,14 +2446,14 @@ bool Console::cmdStepOver(int argc, const char **argv) { _debugState.seekLevel = _engine->_gamestate->_executionStack.size(); _debugState.debugging = true; - return false; + return Cmd_Exit(0, 0); } bool Console::cmdStepEvent(int argc, const char **argv) { _debugState.stopOnEvent = true; _debugState.debugging = true; - return false; + return Cmd_Exit(0, 0); } bool Console::cmdStepRet(int argc, const char **argv) { @@ -2333,7 +2461,7 @@ bool Console::cmdStepRet(int argc, const char **argv) { _debugState.seekLevel = _engine->_gamestate->_executionStack.size() - 1; _debugState.debugging = true; - return false; + return Cmd_Exit(0, 0); } bool Console::cmdStepGlobal(int argc, const char **argv) { @@ -2347,7 +2475,7 @@ bool Console::cmdStepGlobal(int argc, const char **argv) { _debugState.seekSpecial = atoi(argv[1]); _debugState.debugging = true; - return false; + return Cmd_Exit(0, 0); } bool Console::cmdStepCallk(int argc, const char **argv) { @@ -2380,7 +2508,7 @@ bool Console::cmdStepCallk(int argc, const char **argv) { } _debugState.debugging = true; - return false; + return Cmd_Exit(0, 0); } bool Console::cmdDisassemble(int argc, const char **argv) { @@ -2545,7 +2673,7 @@ bool Console::cmdSend(int argc, const char **argv) { // We call run_engine explictly so we can restore the value of r_acc // after execution. - run_vm(_engine->_gamestate, 0); + run_vm(_engine->_gamestate); } @@ -2565,6 +2693,31 @@ bool Console::cmdGo(int argc, const char **argv) { return Cmd_Exit(argc, argv); } +bool Console::cmdLogKernel(int argc, const char **argv) { + if (argc < 3) { + DebugPrintf("Logs calls to specified kernel function.\n"); + DebugPrintf("Usage: %s <kernel-function/*> <on/off>\n", argv[0]); + DebugPrintf("Example: %s StrCpy on\n", argv[0]); + return true; + } + + bool logging; + if (strcmp(argv[2], "on") == 0) + logging = true; + else if (strcmp(argv[2], "off") == 0) + logging = false; + else { + DebugPrintf("2nd parameter must be either on or off\n"); + return true; + } + + if (g_sci->getKernel()->debugSetFunctionLogging(argv[1], logging)) + DebugPrintf("Logging %s for k%s\n", logging ? "enabled" : "disabled", argv[1]); + else + DebugPrintf("Unknown kernel function %s\n", argv[1]); + return true; +} + bool Console::cmdBreakpointList(int argc, const char **argv) { int i = 0; int bpdata; @@ -2884,7 +3037,7 @@ bool Console::cmdQuit(int argc, const char **argv) { exit(0); } - return false; + return Cmd_Exit(0, 0); } bool Console::cmdAddresses(int argc, const char **argv) { @@ -3323,11 +3476,11 @@ void Console::hexDumpReg(const reg_t *data, int len, int regsPerLine, int startO } printf(" |"); for (i = 0; i < regsPerLine; i++) { - c = data[i].toUint16() >> 8; + c = data[i].toUint16() & 0xff; if (c < 32 || c >= 127) c = '.'; printf("%c", c); - c = data[i].toUint16() & 0xff; + c = data[i].toUint16() >> 8; if (c < 32 || c >= 127) c = '.'; printf("%c", c); @@ -3350,11 +3503,11 @@ void Console::hexDumpReg(const reg_t *data, int len, int regsPerLine, int startO } printf(" |"); for (i = 0; i < len; i++) { - c = data[i].toUint16() >> 8; + c = data[i].toUint16() & 0xff; if (c < 32 || c >= 127) c = '.'; printf("%c", c); - c = data[i].toUint16() & 0xff; + c = data[i].toUint16() >> 8; if (c < 32 || c >= 127) c = '.'; printf("%c", c); diff --git a/engines/sci/console.h b/engines/sci/console.h index 51f02d7168..234272bbab 100644 --- a/engines/sci/console.h +++ b/engines/sci/console.h @@ -65,6 +65,7 @@ private: bool cmdSentenceFragments(int argc, const char **argv); bool cmdParse(int argc, const char **argv); bool cmdSetParseNodes(int argc, const char **argv); + bool cmdSaid(int argc, const char **argv); // Resources bool cmdDiskDump(int argc, const char **argv); bool cmdHexDump(int argc, const char **argv); @@ -129,6 +130,7 @@ private: bool cmdDisassembleAddress(int argc, const char **argv); bool cmdSend(int argc, const char **argv); bool cmdGo(int argc, const char **argv); + bool cmdLogKernel(int argc, const char **argv); // Breakpoints bool cmdBreakpointList(int argc, const char **argv); bool cmdBreakpointDelete(int argc, const char **argv); diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index eb2c989e0d..3698964de5 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -56,7 +56,7 @@ static const PlainGameDescriptor s_sciGameTitles[] = { {"lsl2", "Leisure Suit Larry 2: Goes Looking for Love (in Several Wrong Places)"}, {"lsl3", "Leisure Suit Larry 3: Passionate Patti in Pursuit of the Pulsating Pectorals"}, {"pq2", "Police Quest II: The Vengeance"}, - {"qfg1", "Quest for Glory I: So You Want to Be a Hero"}, // EGA is SCI0, VGA SCI1.1 + {"qfg1", "Quest for Glory I: So You Want to Be a Hero"}, {"sq3", "Space Quest III: The Pirates of Pestulon"}, // === SCI01 games ======================================================== {"qfg2", "Quest for Glory II: Trial by Fire"}, @@ -89,11 +89,12 @@ static const PlainGameDescriptor s_sciGameTitles[] = { {"hoyle4", "Hoyle Classic Card Games"}, {"kq6", "King's Quest VI: Heir Today, Gone Tomorrow"}, {"laurabow2", "Laura Bow 2: The Dagger of Amon Ra"}, + {"qfg1vga", "Quest for Glory I: So You Want to Be a Hero"}, {"qfg3", "Quest for Glory III: Wages of War"}, {"sq5", "Space Quest V: The Next Mutation"}, {"islandbrain", "The Island of Dr. Brain"}, {"lsl6", "Leisure Suit Larry 6: Shape Up or Slip Out!"}, - {"mothergoose", "Mixed-Up Mother Goose"}, // floppy is SCI1.1, CD SCI2.1 + {"mothergoose", "Mixed-Up Mother Goose"}, {"pepper", "Pepper's Adventure in Time"}, {"slater", "Slater & Charlie Go Camping"}, // === SCI2 games ========================================================= @@ -106,6 +107,7 @@ static const PlainGameDescriptor s_sciGameTitles[] = { {"kq7", "King's Quest VII: The Princeless Bride"}, // TODO: King's Questions {"lsl6hires", "Leisure Suit Larry 6: Shape Up or Slip Out!"}, + {"mothergoosehires","Mixed-Up Mother Goose"}, {"phantasmagoria", "Phantasmagoria"}, {"pqswat", "Police Quest: SWAT"}, {"shivers", "Shivers"}, @@ -168,6 +170,7 @@ static const GameIdStrToEnum s_gameIdStrToEnum[] = { { "lsl6hires", GID_LSL6HIRES }, { "lsl7", GID_LSL7 }, { "mothergoose", GID_MOTHERGOOSE }, + { "mothergoosehires",GID_MOTHERGOOSEHIRES }, { "msastrochicken", GID_MSASTROCHICKEN }, { "pepper", GID_PEPPER }, { "phantasmagoria", GID_PHANTASMAGORIA }, @@ -178,6 +181,7 @@ static const GameIdStrToEnum s_gameIdStrToEnum[] = { { "pq4", GID_PQ4 }, { "pqswat", GID_PQSWAT }, { "qfg1", GID_QFG1 }, + { "qfg1vga", GID_QFG1VGA }, { "qfg2", GID_QFG2 }, { "qfg3", GID_QFG3 }, { "qfg4", GID_QFG4 }, @@ -332,7 +336,7 @@ Common::String convertSierraGameId(Common::String sierraId, uint32 *gameFlags, R // or qfg4 full (SCI2) // qfg1 VGA doesn't have view 1 if (!resMan->testResource(ResourceId(kResourceTypeView, 1))) - return "qfg1"; + return "qfg1vga"; // qfg4 full is SCI2 if (getSciVersion() == SCI_VERSION_2) @@ -587,7 +591,7 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl !strcmp(s_fallbackDesc.gameid, "sq1sci")) s_fallbackDesc.extra = "VGA Remake"; - if (!strcmp(s_fallbackDesc.gameid, "qfg1") && getSciVersion() == SCI_VERSION_1_1) + if (!strcmp(s_fallbackDesc.gameid, "qfg1vga") && getSciVersion() == SCI_VERSION_1_1) s_fallbackDesc.extra = "VGA Remake"; // Add "demo" to the description for demos @@ -624,8 +628,15 @@ bool SciMetaEngine::hasFeature(MetaEngineFeature f) const { bool SciEngine::hasFeature(EngineFeature f) const { return //(f == kSupportsRTL) || - (f == kSupportsLoadingDuringRuntime) || - (f == kSupportsSavingDuringRuntime); + (f == kSupportsLoadingDuringRuntime); // || + //(f == kSupportsSavingDuringRuntime); + // We can't allow saving through ScummVM menu, because + // a) lots of games don't like saving everywhere (e.g. castle of dr. brain) + // b) some games even dont allow saving in certain rooms (e.g. lsl6) + // c) somehow some games even get mad when doing this (execstackbase was 1 all of a sudden in lsl3) + // d) for sci0/sci01 games we should at least wait till status bar got drawn, although this may not be enough + // we can't make sure that the scripts are fine with us saving at a specific location, doing so may work sometimes + // and some other times it won't work. } SaveStateList SciMetaEngine::listSaves(const char *target) const { diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h index aa1e26e0f4..da3763b236 100644 --- a/engines/sci/detection_tables.h +++ b/engines/sci/detection_tables.h @@ -83,6 +83,19 @@ static const struct ADGameDescription SciGameDescriptions[] = { {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + // Castle of Dr. Brain - English DOS Floppy EGA (from omer_mor, bug report #3035349) + {"castlebrain", "EGA", { + {"resource.map", 0, "88d106f945f7fd9d1aeda961cfec38a9", 2646}, + {"resource.000", 0, "6e125f4ce3f4f5c35f2617c7b66c6e21", 25325}, + {"resource.001", 0, "1d806162f6d3cfbe3c0135414efe6f88", 99931}, + {"resource.002", 0, "6a41a0eb5237778427dddf92ae07cf9b", 294772}, + {"resource.003", 0, "0c6ab4efb3be4d991ae9762e19f17c92", 306378}, + {"resource.004", 0, "5e7b90949422de005f80285979972e43", 292423}, + {"resource.005", 0, "8a5ed3ba96e2eaf18e36fedfaab89419", 297838}, + {"resource.006", 0, "dceed92e709cad1bd9582809a235b0a0", 266682}, + {NULL, 0, NULL, 0}}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + // Castle of Dr. Brain - English DOS Floppy (from jvprat) // Executable scanning reports "1.000.044", Floppy label reports "1.0, 10.30.91", VERSION file reports "1.000" // SCI interpreter version 1.000.510 @@ -960,6 +973,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { // King's Quest 5 EGA (supplied by markcoolio in bug report #2829470) // SCI interpreter version 1.000.060 + // VERSION file reports "0.000.055" {"kq5", "EGA", { {"resource.map", 0, "baf888a4e4797ce0de0b19d4e183583c", 7662}, {"resource.000", 0, "a591bd4b879fc832b8095c0b3befe9e2", 394242}, @@ -973,6 +987,21 @@ static const struct ADGameDescription SciGameDescriptions[] = { {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + // King's Quest 5 EGA (supplied by omer_mor in bug report #3035421) + // VERSION file reports "0.000.062" + {"kq5", "EGA", { + {"resource.map", 0, "e17cfb38175382b9188da75c53bbab64", 7656}, + {"resource.000", 0, "a591bd4b879fc832b8095c0b3befe9e2", 394072}, + {"resource.001", 0, "c1eef048fa9fe76298c2d4705ef9549f", 561444}, + {"resource.002", 0, "076aa0bf1d8d2c147d64aeffbe2928e5", 597580}, + {"resource.003", 0, "ecb47cd04d06b2ab2f9f883667db6e81", 487633}, + {"resource.004", 0, "4d74e8094ff57cea6ee92faf63dbd0af", 620749}, + {"resource.005", 0, "3cca5b2dae8afe94532edfdc98d7edbe", 669961}, + {"resource.006", 0, "698c698570cde9015e4d51eb8d2e9db1", 666541}, + {"resource.007", 0, "703d8df30e89541af337d7706540d5c4", 541762}, + {NULL, 0, NULL, 0}}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + // King's Quest 5 - German DOS Floppy (supplied by markcoolio in bug report #2727101) // SCI interpreter version 1.000.060 {"kq5", "", { @@ -1551,7 +1580,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 5 - German DOS (from Tobis87) - // SCI interpreter version 1.000.510 (just a guess) + // SCI interpreter version T.A00.196 {"lsl5", "", { {"resource.map", 0, "c97297aa76d4dd2ed144c7b7769e2caf", 6867}, {"resource.000", 0, "4c00c14b8181ad47076a51d86097d97e", 759095}, @@ -1706,6 +1735,14 @@ static const struct ADGameDescription SciGameDescriptions[] = { {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE }, + // Larry 7 - English DOS Demo (provided by richiefs in bug report #2670691) + // SCI interpreter version 2.100.002 + {"lsl7", "Demo", { + {"ressci.000", 0, "5cc6159688b2dc03790a67c90ccc67f9", 10195878}, + {"resmap.000", 0, "6a2b2811eef82e87cde91cf1de845af8", 2695}, + {NULL, 0, NULL, 0}}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + #ifdef ENABLE_SCI3_GAMES // Larry 7 - English DOS CD (from spookypeanut) // SCI interpreter version 3.000.000 @@ -1747,14 +1784,6 @@ static const struct ADGameDescription SciGameDescriptions[] = { {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, - // Larry 7 - English DOS Demo (provided by richiefs in bug report #2670691) - // SCI interpreter version 2.100.002 - {"lsl7", "Demo", { - {"ressci.000", 0, "5cc6159688b2dc03790a67c90ccc67f9", 10195878}, - {"resmap.000", 0, "6a2b2811eef82e87cde91cf1de845af8", 2695}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, - // Lighthouse - English Windows Demo (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "1.00" {"lighthouse", "Demo", { @@ -1802,6 +1831,17 @@ static const struct ADGameDescription SciGameDescriptions[] = { {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + // Mixed-Up Fairy Tales - English DOS Floppy EGA (from omer_mor, bug report #3035350) + {"fairytales", "EGA", { + {"resource.map", 0, "daa94e9f327be6657eb97a51b490dbb1", 3219}, + {"resource.000", 0, "6dc287611e510793b72e73110bbdd45d", 17819}, + {"resource.001", 0, "5ad26e7af4d4c3a3185c66a44abd5220", 478401}, + {"resource.002", 0, "4db83250f821607b634c99d663cae74a", 663713}, + {"resource.003", 0, "509b2467ba779100d5933ed51a9ae32f", 560255}, + {"resource.004", 0, "93afc85d5ffa60ea555d6cc336d22c03", 651109}, + {NULL, 0, NULL, 0}}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + // Mixed-Up Fairy Tales v1.000 - English DOS (supplied by markcoolio in bug report #2723791) // Executable scanning reports "1.000.145" {"fairytales", "", { @@ -1835,6 +1875,14 @@ static const struct ADGameDescription SciGameDescriptions[] = { {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + // Mixed-Up Mother Goose - English DOS Floppy EGA (from omer_mor, bug report #3035354) + {"mothergoose", "EGA", { + {"resource.map", 0, "3490f85dab47e504c41b7eb3312e285e", 2598}, + {"resource.001", 0, "d893892d62b3f061357291d66775e360", 239906}, + {"resource.002", 0, "d893892d62b3f061357291d66775e360", 719398}, + {NULL, 0, NULL, 0}}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + // Mixed-Up Mother Goose v2.000 - English DOS Floppy (supplied by markcoolio in bug report #2723795) // Executable scanning reports "1.001.031" {"mothergoose", "", { @@ -1858,17 +1906,25 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "87f9dc1cafc4d4fa835fb2f00cf3a6ef", 4560}, {"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 2070072}, {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH }, #ifdef ENABLE_SCI32 // Mixed-Up Mother Goose Deluxe - English Windows/DOS CD (supplied by markcoolio in bug report #2723810) // Executable scanning reports "2.100.002" - {"mothergoose", "", { + {"mothergoosehires", "", { {"resource.map", 0, "5159a1578c4306bfe070a3e4d8c2e1d3", 4741}, {"resource.000", 0, "1926925c95d82f0999590e93b02887c5", 15150768}, {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, + + // Mixed-Up Mother Goose Deluxe - Multilingual Windows CD (English/French/German/Spanish) + // Executable scanning reports "2.100.002" + {"mothergoosehires", "", { + {"resmap.000", 0, "ef611af561898dcfea87846919ebf3eb", 4969}, + {"ressci.000", 0, "227685bc59d90821978d330713e44a7a", 17205800}, + {NULL, 0, NULL, 0}}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, #endif // ENABLE_SCI32 // Ms. Astro Chicken - English DOS @@ -2020,6 +2076,17 @@ static const struct ADGameDescription SciGameDescriptions[] = { {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + // Police Quest 2 - Japanese PC-98 + // SCI interpreter version unknown + {"pq2", "", { + {"resource.map", 0, "883804c616dca1d82373bf9fda3a71d2", 4656}, + {"resource.001", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 669319}, + {"resource.002", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 637662}, + {"resource.003", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 684395}, + {NULL, 0, NULL, 0}}, + Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH + }, // also includes english language + // Police Quest 3 - English Amiga // Executable scanning reports "1.004.024" // SCI interpreter version 1.000.784 @@ -2252,7 +2319,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { // Quest for Glory 1 VGA Remake - English DOS // Executable scanning reports "2.000.411" - {"qfg1", "VGA Remake", { + {"qfg1vga", "VGA Remake", { {"resource.map", 0, "a731fb6c9c0b282443f7027bc8694d4c", 8469}, {"resource.000", 0, "ecace1a2771846b1a8aa1afdd44111a0", 6570147}, {NULL, 0, NULL, 0}}, @@ -2261,7 +2328,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { // Quest for Glory 1 VGA Remake - English DOS Non-Interactive Demo (from FRG) // SCI interpreter version 1.001.029 - {"qfg1", "VGA Remake, Demo", { + {"qfg1vga", "VGA Remake, Demo", { {"resource.map", 0, "ac0257051c95a59c0cdc0be24d9b11fa", 729}, {"resource.000", 0, "ec6f5cf369054dd3e5392995e9975b9e", 768218}, {NULL, 0, NULL, 0}}, @@ -2270,7 +2337,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { // Quest for Glory 1 VGA Remake - English Macintosh Floppy // VERSION file reports "2.0" - {"qfg1", "VGA Remake", { + {"qfg1vga", "VGA Remake", { {"Data1", 0, "14f26bc75f24bb1ecc94532df17b5371", 1768155}, {"Data2", 0, "a7aee8bd46fc9cef7fd3bea93ef173e0", 6586422}, {NULL, 0, NULL, 0}}, @@ -3078,26 +3145,37 @@ static const struct ADGameDescription SciGameDescriptions[] = { #endif // ENABLE_SCI32 // SCI Fanmade Games - FANMADE("Al Pond 2: Island Quest", "9625372e710d1a95d2027b48f9e325af", 1506, "a0f9aa65b9bf3d8703adff5a621f243c", 889843), FANMADE("Al Pond: Island Quest 2", "4cba6a5a4c8f66f21935ed78b0511a92", 870, "876587dc9a5ec569287a3dc4b29139d8", 613769), + FANMADE("Al Pond 2: Island Quest", "9625372e710d1a95d2027b48f9e325af", 1506, "a0f9aa65b9bf3d8703adff5a621f243c", 889843), + FANMADE("Al Pond 2: Island Quest (Updated)", "64be277cdcc6aafce7d9f26e88ad31a8", 1500, "571547228a212d63315f0c114cf48d54", 885241), FANMADE("Another DG Game: I Want My C64 Back", "4a8ca7ca2abd18899ef856f47665e2e9", 588, "12ff558d20c72e42cc6adb408f34d6d8", 150513), FANMADE_L("Another DG Game: I Want My C64 Back", "13dc1d9ebc57daf8895412eee5e39fea", 576, "e2ad60b3a280171429db5c85f158f84a", 141697, Common::FR_FRA), + FANMADE("Aquarius: An Aquatic Experience", "2e23bc3b82f22a454be202ea593fb478", 480, "01555c8de683d25405bda270aa1ff014", 272372), FANMADE("Bluntman and Chronic (Politically Correct Version)", "c3ef9fa6c7c5fb840078bf28d87c7f8b", 1362, "441636a9f6f86710844868fded868ee7", 596688), FANMADE("Cascade Quest", "c94efc10d18c040b6e22a1dc6d3adfe1", 3468, "8ada33dfa945f81531e5508240b573de", 1432195), - FANMADE("Curt Quest 1.0", "b0e555370380d218968a40a68eaaaffc", 1146, "c851182cdf6fc6a81b840f4d4875f1a0", 307165), - FANMADE("Curt Quest 1.1", "54084c29346683296e45ef32d7ae74f3", 1128, "c851182cdf6fc6a81b840f4d4875f1a0", 302000), + FANMADE("Circus Quest", "35871f6b4e1df56af4113c0203a0b223", 630, "7d6f97d7935d8733f488d4cb74315e5b", 279627), + FANMADE("Curt's Quest 1.0", "b0e555370380d218968a40a68eaaaffc", 1146, "c851182cdf6fc6a81b840f4d4875f1a0", 307165), + FANMADE("Curt's Quest 1.1", "54084c29346683296e45ef32d7ae74f3", 1128, "c851182cdf6fc6a81b840f4d4875f1a0", 302000), FANMADE("Demo Quest", "c89a0c9e0a4e4af0ecedb300a3b31dbf", 384, "a32f3495ba24764cba091119cc3f1e13", 160098), FANMADE("Dr. Jummybummy's Space Adventure 2", "6ae6cb7de423f51736d9487b4ca0c6da", 810, "26e5b563f578e104d79689f36568b7cf", 394670), FANMADE_L("Grostesteing: Plus Mechant que Jamais", "ec9a97ccb134f69249f6ea8b16c13d8e", 1500, "b869f5f11bfe2ab5f67f4f0c618f2ce1", 464657, Common::FR_FRA), // FIXME: Accent - FANMADE("Jim Quest", "0af50be1d3f0cb77a09137709a76ef4f", 960, "9c042c136548b20d9183495668e03526", 496446), + FANMADE("Humanoid Demo", "97d8331293a6d57e8bad58c1efc89a63", 624, "fb354b9abe64011b12159e45d724633f", 452320), + FANMADE("Jim’s Quest 1: The Phantom Thesis", "0af50be1d3f0cb77a09137709a76ef4f", 960, "9c042c136548b20d9183495668e03526", 496446), FANMADE("Knight's Quest Demo 1.0", "5e816edf993956752ed06fccfeeae6d9", 1260, "959321f88a22905fa1f8c6d897874744", 703836), FANMADE("LockerGnome Quest", "3eeff9130206cad0c4e1551e2b9dd2c5", 420, "ae05ca90806fd90cc43f147c82d3547c", 158906), - FANMADE("New Year's Mystery", "efd1beb5120293725065c95959144f81", 714, "b3bd3c2372ed6efa28adb12403c4c31a", 305027), + FANMADE("New Year's Mystery", "e4dcab1b1d3cb4a2c070a07a9c9589e0", 708, "e00ca5e44fd4e98d8174b467b31b0f21", 295425), + FANMADE("New Year's Mystery (Updated)", "efd1beb5120293725065c95959144f81", 714, "b3bd3c2372ed6efa28adb12403c4c31a", 305027), + FANMADE("Ocean Battle", "c2304a0568e0eb84f8e9a0915f01170a", 408, "46c520c1ac9b63528854d0f58c7e1b74", 142234), FANMADE("Osama", "db8f1710453cfbecf4214b2946970043", 390, "7afd75d4620dedf97a84ae8f0a7523cf", 123827), FANMADE("Quest for the Cheat", "a359d4cf27f98264b42b55c017671214", 882, "8a943029f73c4bc85d454b7f473455ba", 455209), + FANMADE("SCI Capture the Flag", "4cd679a51d93b8b27c6b38d81be24b8b", 432, "98ae1f6ed7b4c21f88addbf643dd1d2f", 147878), FANMADE("SCI Companion Template", "ad54d4f504086cd597aa2348d0aa3b09", 354, "6798b7b601ce8154c1d1bc0f0edcdd18", 113061), + FANMADE("SCI Programming April 2010 Competition Template", "36e5c4011dd7c92e1ae4c6fede7d698d", 456, "20c87fbb7f73e2a3eb2c5dfab4d76b5a", 142221), FANMADE("SCI Studio Template 3.0", "ca0dc8d586e0a8670b7621cde090b532", 354, "58a48ee692a86c0575e6bd0b00a92b9a", 113097), FANMADE("SCI Quest", "9067e1f1e54436d2dbfce855524bc84a", 552, "ffa7d355cd9223f245289108a696bcd2", 149634), + FANMADE("SCI-Man", "3ab85bd39a86c11f85781764f9db09bb", 468, "bb8f9992f504a242bf0860e3588e150b", 131810), + FANMADE("The Farm Nightmare", "fb6cbfddaa7c055e2c3d8cf4c683a7db", 906, "50655e8b8925f717e698e08f006f40be", 338303), + FANMADE("The Gem Scenario", "ef5f61f4d2c6d31122d3e2baf89ad976", 642, "2f16be390dd90c3d7ca1c8a594ac0bfa", 244794), FANMADE("The Legend of the Lost Jewel", "ba1bca315e3818c5626eda51bcfbcccf", 636, "9b0736d69924af0cff32a0f78db96855", 300398), // FIXME: The vga demo does not have a resource.000/001 file. diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp index fee6e69da7..315c86c56c 100644 --- a/engines/sci/engine/features.cpp +++ b/engines/sci/engine/features.cpp @@ -38,6 +38,7 @@ GameFeatures::GameFeatures(SegManager *segMan, Kernel *kernel) : _segMan(segMan) _doSoundType = SCI_VERSION_NONE; _lofsType = SCI_VERSION_NONE; _gfxFunctionsType = SCI_VERSION_NONE; + _messageFunctionType = SCI_VERSION_NONE; _moveCountType = kMoveCountUninitialized; #ifdef ENABLE_SCI32 @@ -140,6 +141,10 @@ SciVersion GameFeatures::detectDoSoundType() { // This game is using early SCI0 sound code (different headers than // SCI0 late) _doSoundType = SCI_VERSION_0_EARLY; +#ifdef ENABLE_SCI32 + } else if (getSciVersion() >= SCI_VERSION_2_1) { + _doSoundType = SCI_VERSION_2_1; +#endif } else if (SELECTOR(nodePtr) == -1) { // No nodePtr selector, so this game is definitely using newer // SCI0 sound code (i.e. SCI_VERSION_0_LATE) @@ -403,6 +408,41 @@ SciVersion GameFeatures::detectGfxFunctionsType() { return _gfxFunctionsType; } +SciVersion GameFeatures::detectMessageFunctionType() { + if (_messageFunctionType != SCI_VERSION_NONE) + return _messageFunctionType; + + if (getSciVersion() > SCI_VERSION_1_1) { + _messageFunctionType = SCI_VERSION_1_1; + return _messageFunctionType; + } else if (getSciVersion() < SCI_VERSION_1_1) { + _messageFunctionType = SCI_VERSION_1_LATE; + return _messageFunctionType; + } + + Common::List<ResourceId> *resources = g_sci->getResMan()->listResources(kResourceTypeMessage, -1); + + if (resources->empty()) { + // No messages found, so this doesn't really matter anyway... + _messageFunctionType = SCI_VERSION_1_1; + return _messageFunctionType; + } + + Resource *res = g_sci->getResMan()->findResource(*resources->begin(), false); + assert(res); + + // Only v2 Message resources use the kGetMessage kernel function. + // v3-v5 use the kMessage kernel function. + + if (READ_SCI11ENDIAN_UINT32(res->data) / 1000 == 2) + _messageFunctionType = SCI_VERSION_1_LATE; + else + _messageFunctionType = SCI_VERSION_1_1; + + debugC(1, kDebugLevelVM, "Detected message function type: %s", getSciVersionDesc(_messageFunctionType)); + return _messageFunctionType; +} + #ifdef ENABLE_SCI32 bool GameFeatures::autoDetectSci21KernelType() { // First, check if the Sound object is loaded diff --git a/engines/sci/engine/features.h b/engines/sci/engine/features.h index 5b383746d8..167c207437 100644 --- a/engines/sci/engine/features.h +++ b/engines/sci/engine/features.h @@ -66,6 +66,12 @@ public: * @return Graphics functions type, SCI_VERSION_0_EARLY / SCI_VERSION_0_LATE */ SciVersion detectGfxFunctionsType(); + + /** + * Autodetects the message function used + * @return Message function type, SCI_VERSION_1_LATE / SCI_VERSION_1_1 + */ + SciVersion detectMessageFunctionType(); #ifdef ENABLE_SCI32 /** @@ -105,7 +111,7 @@ private: bool autoDetectSci21KernelType(); #endif - SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType; + SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType, _messageFunctionType; #ifdef ENABLE_SCI32 SciVersion _sci21KernelType; #endif diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index beb1d3ce35..d76199c794 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -27,619 +27,15 @@ #include "sci/engine/kernel.h" #include "sci/event.h" #include "sci/resource.h" +#include "sci/engine/features.h" +#include "sci/engine/kernel_tables.h" #include "sci/engine/state.h" +#include "sci/engine/workarounds.h" #include "common/system.h" namespace Sci { -// Uncompiled kernel signatures are formed from a string of letters. -// each corresponding to a type of a parameter (see below). -// Use small letters to indicate end of sum type. -// Use capital letters for sum types, e.g. -// "LNoLr" for a function which takes two arguments: -// (1) list, node or object -// (2) list or ref -#define KSIG_SPEC_LIST 'l' -#define KSIG_SPEC_NODE 'n' -#define KSIG_SPEC_OBJECT 'o' -#define KSIG_SPEC_REF 'r' // Said Specs and strings -#define KSIG_SPEC_ARITHMETIC 'i' -#define KSIG_SPEC_NULL 'z' -#define KSIG_SPEC_ANY '.' -#define KSIG_SPEC_ELLIPSIS '*' // Arbitrarily more TYPED arguments - -#define KSIG_SPEC_SUM_DONE ('a' - 'A') - - - -/** Default kernel name table. */ -static const char *s_defaultKernelNames[] = { - /*0x00*/ "Load", - /*0x01*/ "UnLoad", - /*0x02*/ "ScriptID", - /*0x03*/ "DisposeScript", - /*0x04*/ "Clone", - /*0x05*/ "DisposeClone", - /*0x06*/ "IsObject", - /*0x07*/ "RespondsTo", - /*0x08*/ "DrawPic", - /*0x09*/ "Dummy", // Show - /*0x0a*/ "PicNotValid", - /*0x0b*/ "Animate", - /*0x0c*/ "SetNowSeen", - /*0x0d*/ "NumLoops", - /*0x0e*/ "NumCels", - /*0x0f*/ "CelWide", - /*0x10*/ "CelHigh", - /*0x11*/ "DrawCel", - /*0x12*/ "AddToPic", - /*0x13*/ "NewWindow", - /*0x14*/ "GetPort", - /*0x15*/ "SetPort", - /*0x16*/ "DisposeWindow", - /*0x17*/ "DrawControl", - /*0x18*/ "HiliteControl", - /*0x19*/ "EditControl", - /*0x1a*/ "TextSize", - /*0x1b*/ "Display", - /*0x1c*/ "GetEvent", - /*0x1d*/ "GlobalToLocal", - /*0x1e*/ "LocalToGlobal", - /*0x1f*/ "MapKeyToDir", - /*0x20*/ "DrawMenuBar", - /*0x21*/ "MenuSelect", - /*0x22*/ "AddMenu", - /*0x23*/ "DrawStatus", - /*0x24*/ "Parse", - /*0x25*/ "Said", - /*0x26*/ "SetSynonyms", // Portrait (KQ6 hires) - /*0x27*/ "HaveMouse", - /*0x28*/ "SetCursor", - // FOpen (SCI0) - // FPuts (SCI0) - // FGets (SCI0) - // FClose (SCI0) - /*0x29*/ "SaveGame", - /*0x2a*/ "RestoreGame", - /*0x2b*/ "RestartGame", - /*0x2c*/ "GameIsRestarting", - /*0x2d*/ "DoSound", - /*0x2e*/ "NewList", - /*0x2f*/ "DisposeList", - /*0x30*/ "NewNode", - /*0x31*/ "FirstNode", - /*0x32*/ "LastNode", - /*0x33*/ "EmptyList", - /*0x34*/ "NextNode", - /*0x35*/ "PrevNode", - /*0x36*/ "NodeValue", - /*0x37*/ "AddAfter", - /*0x38*/ "AddToFront", - /*0x39*/ "AddToEnd", - /*0x3a*/ "FindKey", - /*0x3b*/ "DeleteKey", - /*0x3c*/ "Random", - /*0x3d*/ "Abs", - /*0x3e*/ "Sqrt", - /*0x3f*/ "GetAngle", - /*0x40*/ "GetDistance", - /*0x41*/ "Wait", - /*0x42*/ "GetTime", - /*0x43*/ "StrEnd", - /*0x44*/ "StrCat", - /*0x45*/ "StrCmp", - /*0x46*/ "StrLen", - /*0x47*/ "StrCpy", - /*0x48*/ "Format", - /*0x49*/ "GetFarText", - /*0x4a*/ "ReadNumber", - /*0x4b*/ "BaseSetter", - /*0x4c*/ "DirLoop", - /*0x4d*/ "CanBeHere", // CantBeHere in newer SCI versions - /*0x4e*/ "OnControl", - /*0x4f*/ "InitBresen", - /*0x50*/ "DoBresen", - /*0x51*/ "Platform", // DoAvoider (SCI0) - /*0x52*/ "SetJump", - /*0x53*/ "SetDebug", - /*0x54*/ "Dummy", // InspectObj - /*0x55*/ "Dummy", // ShowSends - /*0x56*/ "Dummy", // ShowObjs - /*0x57*/ "Dummy", // ShowFree - /*0x58*/ "MemoryInfo", - /*0x59*/ "Dummy", // StackUsage - /*0x5a*/ "Dummy", // Profiler - /*0x5b*/ "GetMenu", - /*0x5c*/ "SetMenu", - /*0x5d*/ "GetSaveFiles", - /*0x5e*/ "GetCWD", - /*0x5f*/ "CheckFreeSpace", - /*0x60*/ "ValidPath", - /*0x61*/ "CoordPri", - /*0x62*/ "StrAt", - /*0x63*/ "DeviceInfo", - /*0x64*/ "GetSaveDir", - /*0x65*/ "CheckSaveGame", - /*0x66*/ "ShakeScreen", - /*0x67*/ "FlushResources", - /*0x68*/ "SinMult", - /*0x69*/ "CosMult", - /*0x6a*/ "SinDiv", - /*0x6b*/ "CosDiv", - /*0x6c*/ "Graph", - /*0x6d*/ "Joystick", - // End of kernel function table for SCI0 - /*0x6e*/ "Dummy", // ShiftScreen - /*0x6f*/ "Palette", - /*0x70*/ "MemorySegment", - /*0x71*/ "Intersections", // MoveCursor (SCI1 late), PalVary (SCI1.1) - /*0x72*/ "Memory", - /*0x73*/ "Dummy", // ListOps - /*0x74*/ "FileIO", - /*0x75*/ "DoAudio", - /*0x76*/ "DoSync", - /*0x77*/ "AvoidPath", - /*0x78*/ "Sort", // StrSplit (SCI01) - /*0x79*/ "Dummy", // ATan - /*0x7a*/ "Lock", - /*0x7b*/ "StrSplit", - /*0x7c*/ "GetMessage", // Message (SCI1.1) - /*0x7d*/ "IsItSkip", - /*0x7e*/ "MergePoly", - /*0x7f*/ "ResCheck", - /*0x80*/ "AssertPalette", - /*0x81*/ "TextColors", - /*0x82*/ "TextFonts", - /*0x83*/ "Dummy", // Record - /*0x84*/ "Dummy", // PlayBack - /*0x85*/ "ShowMovie", - /*0x86*/ "SetVideoMode", - /*0x87*/ "SetQuitStr", - /*0x88*/ "Dummy" // DbugStr -}; - -reg_t kStub(EngineState *s, int argc, reg_t *argv) { - Kernel *kernel = g_sci->getKernel(); - int kernelCallNr = -1; - - Common::List<ExecStack>::iterator callIterator = s->_executionStack.end(); - if (callIterator != s->_executionStack.begin()) { - callIterator--; - ExecStack lastCall = *callIterator; - kernelCallNr = lastCall.debugSelector; - } - - Common::String warningMsg = "Dummy function k" + kernel->getKernelName(kernelCallNr) + - Common::String::printf("[%x]", kernelCallNr) + - " invoked. Params: " + - Common::String::printf("%d", argc) + " ("; - - for (int i = 0; i < argc; i++) { - warningMsg += Common::String::printf("%04x:%04x", PRINT_REG(argv[i])); - warningMsg += (i == argc - 1 ? ")" : ", "); - } - - warning("%s", warningMsg.c_str()); - return s->r_acc; -} - -reg_t kStubNull(EngineState *s, int argc, reg_t *argv) { - kStub(s, argc, argv); - return NULL_REG; -} - -reg_t kDummy(EngineState *s, int argc, reg_t *argv) { - kStub(s, argc, argv); - error("Kernel function was called, which was considered to be unused - see log for details"); -} - -// [io] -> either integer or object -// (io) -> optionally integer AND an object -// (i) -> optional integer -// . -> any type -// i* -> optional multiple integers -// .* -> any parameters afterwards (or none) - -// gameID, scriptNr,lvl, object-name, method-name, call, index, replace -static const SciWorkaroundEntry kAbs_workarounds[] = { - { GID_HOYLE1, 1, 0, "room1", "doit", -1, 0, { 2, 0x3e9 } }, // crazy eights - called with objects instead of integers - { GID_HOYLE1, 2, 0, "room2", "doit", -1, 0, { 2, 0x3e9 } }, // old maid - called with objects instead of integers - { GID_HOYLE1, 3, 0, "room3", "doit", -1, 0, { 2, 0x3e9 } }, // hearts - called with objects instead of integers - SCI_WORKAROUNDENTRY_TERMINATOR -}; - -// gameID, scriptNr,lvl, object-name, method-name, call, index, replace -static const SciWorkaroundEntry kDisposeScript_workarounds[] = { - { GID_QFG1, 64, 0, "rm64", "dispose", -1, 0, { 1, 0 } }, // when leaving graveyard, parameter 0 is an object - SCI_WORKAROUNDENTRY_TERMINATOR -}; - -// gameID, scriptNr,lvl, object-name, method-name, call, index, replace -static const SciWorkaroundEntry kDoSoundFade_workarounds[] = { - { GID_KQ6, 989, 0, "globalSound", "fade", -1, 0, { 0, 0 } }, // during intro, parameter 4 is an object - SCI_WORKAROUNDENTRY_TERMINATOR -}; - -// gameID, scriptNr,lvl, object-name, method-name, call, index, replace -static const SciWorkaroundEntry kGraphRestoreBox_workarounds[] = { - { GID_LSL6, 85, 0, "rScroller", "hide", -1, 0, { 0, 0 } }, // happens when restoring (sometimes), same as the one below - { GID_LSL6, 85, 0, "lScroller", "hide", -1, 0, { 0, 0 } }, // happens when restoring (sometimes), same as the one below - { GID_LSL6, 86, 0, "LL6Inv", "show", -1, 0, { 0, 0 } }, // happens when restoring, is called with hunk segment, but hunk is not allocated at that time - // ^^ TODO: check, if this is really a script error or an issue with our restore code - { GID_LSL6, 86, 0, "LL6Inv", "hide", -1, 0, { 0, 0 } }, // happens during the game, gets called with 1 extra parameter - SCI_WORKAROUNDENTRY_TERMINATOR -}; - -// gameID, scriptNr,lvl, object-name, method-name, call, index, replace -static const SciWorkaroundEntry kGraphFillBoxForeground_workarounds[] = { - { GID_LSL6, 0, 0, "LSL6", "hideControls", -1, 0, { 0, 0 } }, // happens when giving the bungee key to merrily - gets called with additional 5th parameter - SCI_WORKAROUNDENTRY_TERMINATOR -}; - -// gameID, scriptNr,lvl, object-name, method-name, call, index, replace -static const SciWorkaroundEntry kGraphFillBoxAny_workarounds[] = { - { GID_SQ4, 818, 0, "iconTextSwitch", "show", -1, 0, { 0, 0 } }, // game menu "text/speech" display - parameter 5 is missing, but the right color number is on the stack - SCI_WORKAROUNDENTRY_TERMINATOR -}; - -// gameID, scriptNr,lvl, object-name, method-name, call, index, replace -static const SciWorkaroundEntry kUnLoad_workarounds[] = { - { GID_LSL6, 130, 0, "recruitLarryScr", "changeState", -1, 0, { 1, 0 } }, // during intro, a 3rd parameter is passed by accident - { GID_LSL6, 740, 0, "showCartoon", "changeState", -1, 0, { 1, 0 } }, // during ending, 4 additional parameters are passed by accident - { GID_SQ1, 303, 0, "slotGuy", "dispose", -1, 0, { 1, 0 } }, // when leaving ulence flats bar, parameter 1 is not passed - script error - SCI_WORKAROUNDENTRY_TERMINATOR -}; - -struct SciKernelMapSubEntry { - SciVersion fromVersion; - SciVersion toVersion; - - uint16 id; - - const char *name; - KernelFunctionCall *function; - - const char *signature; - const SciWorkaroundEntry *workarounds; -}; - -#define SCI_SUBOPENTRY_TERMINATOR { SCI_VERSION_NONE, SCI_VERSION_NONE, 0, NULL, NULL, NULL, NULL } - - -#define SIG_SCIALL SCI_VERSION_NONE, SCI_VERSION_NONE -#define SIG_SCI0 SCI_VERSION_NONE, SCI_VERSION_01 -#define SIG_SCI1 SCI_VERSION_1_EGA, SCI_VERSION_1_LATE -#define SIG_SCI11 SCI_VERSION_1_1, SCI_VERSION_1_1 -#define SIG_SCI16 SCI_VERSION_NONE, SCI_VERSION_1_1 -#define SIG_SCI32 SCI_VERSION_2, SCI_VERSION_NONE - -// SCI-Sound-Version -#define SIG_SOUNDSCI0 SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE -#define SIG_SOUNDSCI1EARLY SCI_VERSION_1_EARLY, SCI_VERSION_1_EARLY -#define SIG_SOUNDSCI1LATE SCI_VERSION_1_LATE, SCI_VERSION_1_LATE - -#define SIGFOR_ALL 0x3f -#define SIGFOR_DOS 1 << 0 -#define SIGFOR_PC98 1 << 1 -#define SIGFOR_WIN 1 << 2 -#define SIGFOR_MAC 1 << 3 -#define SIGFOR_AMIGA 1 << 4 -#define SIGFOR_ATARI 1 << 5 -#define SIGFOR_PC SIGFOR_DOS|SIGFOR_WIN - -#define SIG_EVERYWHERE SIG_SCIALL, SIGFOR_ALL - -#define MAP_CALL(_name_) #_name_, k##_name_ - -// version, subId, function-mapping, signature, workarounds -static const SciKernelMapSubEntry kDoSound_subops[] = { - { SIG_SOUNDSCI0, 0, MAP_CALL(DoSoundInit), "o", NULL }, - { SIG_SOUNDSCI0, 1, MAP_CALL(DoSoundPlay), "o", NULL }, - { SIG_SOUNDSCI0, 2, MAP_CALL(DoSoundDummy), "o", NULL }, - { SIG_SOUNDSCI0, 3, MAP_CALL(DoSoundDispose), "o", NULL }, - { SIG_SOUNDSCI0, 4, MAP_CALL(DoSoundMute), "(i)", NULL }, - { SIG_SOUNDSCI0, 5, MAP_CALL(DoSoundStop), "o", NULL }, - { SIG_SOUNDSCI0, 6, MAP_CALL(DoSoundPause), "i", NULL }, - { SIG_SOUNDSCI0, 7, MAP_CALL(DoSoundResume), "", NULL }, - { SIG_SOUNDSCI0, 8, MAP_CALL(DoSoundMasterVolume), "(i)", NULL }, - { SIG_SOUNDSCI0, 9, MAP_CALL(DoSoundUpdate), "o", NULL }, - { SIG_SOUNDSCI0, 10, MAP_CALL(DoSoundFade), "o", NULL }, - { SIG_SOUNDSCI0, 11, MAP_CALL(DoSoundGetPolyphony), "", NULL }, - { SIG_SOUNDSCI0, 12, MAP_CALL(DoSoundStopAll), "", NULL }, - { SIG_SOUNDSCI1EARLY, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL }, - { SIG_SOUNDSCI1EARLY, 1, MAP_CALL(DoSoundMute), NULL, NULL }, - { SIG_SOUNDSCI1EARLY, 2, MAP_CALL(DoSoundDummy), NULL, NULL }, - { SIG_SOUNDSCI1EARLY, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL }, - { SIG_SOUNDSCI1EARLY, 4, MAP_CALL(DoSoundUpdate), NULL, NULL }, - { SIG_SOUNDSCI1EARLY, 5, MAP_CALL(DoSoundInit), NULL, NULL }, - { SIG_SOUNDSCI1EARLY, 6, MAP_CALL(DoSoundDispose), NULL, NULL }, - { SIG_SOUNDSCI1EARLY, 7, MAP_CALL(DoSoundPlay), "oi", NULL }, - { SIG_SOUNDSCI1EARLY, 8, MAP_CALL(DoSoundStop), NULL, NULL }, - { SIG_SOUNDSCI1EARLY, 9, MAP_CALL(DoSoundPause), "[o0]i", NULL }, - { SIG_SOUNDSCI1EARLY, 10, MAP_CALL(DoSoundFade), "oiiii", NULL }, - { SIG_SOUNDSCI1EARLY, 11, MAP_CALL(DoSoundUpdateCues), "o", NULL }, - { SIG_SOUNDSCI1EARLY, 12, MAP_CALL(DoSoundSendMidi), "oiiii", NULL }, - { SIG_SOUNDSCI1EARLY, 13, MAP_CALL(DoSoundReverb), "oi", NULL }, - { SIG_SOUNDSCI1EARLY, 14, MAP_CALL(DoSoundSetHold), "oi", NULL }, - { SIG_SOUNDSCI1EARLY, 15, MAP_CALL(DoSoundDummy), "", NULL }, - // ^^ Longbow demo - { SIG_SOUNDSCI1LATE, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 1, MAP_CALL(DoSoundMute), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 2, MAP_CALL(DoSoundDummy), "", NULL }, - { SIG_SOUNDSCI1LATE, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 4, MAP_CALL(DoSoundGetAudioCapability), "", NULL }, - { SIG_SOUNDSCI1LATE, 5, MAP_CALL(DoSoundSuspend), "i", NULL }, - { SIG_SOUNDSCI1LATE, 6, MAP_CALL(DoSoundInit), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 7, MAP_CALL(DoSoundDispose), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 8, MAP_CALL(DoSoundPlay), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 9, MAP_CALL(DoSoundStop), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 10, MAP_CALL(DoSoundPause), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 11, MAP_CALL(DoSoundFade), "oiiii(i)", kDoSoundFade_workarounds }, - { SIG_SOUNDSCI1LATE, 12, MAP_CALL(DoSoundSetHold), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 13, MAP_CALL(DoSoundDummy), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 14, MAP_CALL(DoSoundSetVolume), "oi", NULL }, - { SIG_SOUNDSCI1LATE, 15, MAP_CALL(DoSoundSetPriority), "oi", NULL }, - { SIG_SOUNDSCI1LATE, 16, MAP_CALL(DoSoundSetLoop), "oi", NULL }, - { SIG_SOUNDSCI1LATE, 17, MAP_CALL(DoSoundUpdateCues), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 18, MAP_CALL(DoSoundSendMidi), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 19, MAP_CALL(DoSoundReverb), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 20, MAP_CALL(DoSoundUpdate), NULL, NULL }, - SCI_SUBOPENTRY_TERMINATOR -}; - -// version, subId, function-mapping, signature, workarounds -static const SciKernelMapSubEntry kGraph_subops[] = { - { SIG_SCI32, 1, MAP_CALL(StubNull), "", NULL }, // called by gk1 sci32 right at the start - { SIG_SCIALL, 2, MAP_CALL(GraphGetColorCount), "", NULL }, - // 3 - set palette via resource - { SIG_SCIALL, 4, MAP_CALL(GraphDrawLine), "iiiii(i)(i)", NULL }, - // 5 - nop - // 6 - draw pattern - { SIG_SCIALL, 7, MAP_CALL(GraphSaveBox), "iiiii", NULL }, - { SIG_SCIALL, 8, MAP_CALL(GraphRestoreBox), "[r0!]", kGraphRestoreBox_workarounds }, - // ^ this may get called with invalid references, we check them within restoreBits() and sierra sci behaves the same - { SIG_SCIALL, 9, MAP_CALL(GraphFillBoxBackground), "iiii", NULL }, - { SIG_SCIALL, 10, MAP_CALL(GraphFillBoxForeground), "iiii", kGraphFillBoxForeground_workarounds }, - { SIG_SCIALL, 11, MAP_CALL(GraphFillBoxAny), "iiiiii(i)(i)", kGraphFillBoxAny_workarounds }, - { SIG_SCI11, 12, MAP_CALL(GraphUpdateBox), "iiii(i)(r0)", NULL }, // kq6 hires - { SIG_SCIALL, 12, MAP_CALL(GraphUpdateBox), "iiii(i)", NULL }, - { SIG_SCIALL, 13, MAP_CALL(GraphRedrawBox), "iiii", NULL }, - { SIG_SCIALL, 14, MAP_CALL(GraphAdjustPriority), "ii", NULL }, - { SIG_SCI11, 15, MAP_CALL(GraphSaveUpscaledHiresBox), "iiii", NULL }, // kq6 hires - SCI_SUBOPENTRY_TERMINATOR -}; - -// version, subId, function-mapping, signature, workarounds -static const SciKernelMapSubEntry kPalVary_subops[] = { - { SIG_SCIALL, 0, MAP_CALL(PalVaryInit), "ii(i)(i)", NULL }, - { SIG_SCIALL, 1, MAP_CALL(PalVaryReverse), "(i)(i)(i)", NULL }, - { SIG_SCIALL, 2, MAP_CALL(PalVaryGetCurrentStep), "", NULL }, - { SIG_SCIALL, 3, MAP_CALL(PalVaryDeinit), "", NULL }, - { SIG_SCIALL, 4, MAP_CALL(PalVaryChangeTarget), "i", NULL }, - { SIG_SCIALL, 5, MAP_CALL(PalVaryChangeTicks), "i", NULL }, - { SIG_SCIALL, 6, MAP_CALL(PalVaryPauseResume), "i", NULL }, - { SIG_SCI32, 8, MAP_CALL(PalVaryUnknown), "", NULL }, - SCI_SUBOPENTRY_TERMINATOR -}; - -// version, subId, function-mapping, signature, workarounds -static const SciKernelMapSubEntry kPalette_subops[] = { - { SIG_SCIALL, 1, MAP_CALL(PaletteSetFromResource), "i(i)", NULL }, - { SIG_SCIALL, 2, MAP_CALL(PaletteSetFlag), "iii", NULL }, - { SIG_SCIALL, 3, MAP_CALL(PaletteUnsetFlag), "iii", NULL }, - { SIG_SCIALL, 4, MAP_CALL(PaletteSetIntensity), "iii(i)", NULL }, - { SIG_SCIALL, 5, MAP_CALL(PaletteFindColor), "iii", NULL }, - { SIG_SCIALL, 6, MAP_CALL(PaletteAnimate), "i*", NULL }, - { SIG_SCIALL, 7, MAP_CALL(PaletteSave), "", NULL }, - { SIG_SCIALL, 8, MAP_CALL(PaletteRestore), "i", NULL }, - SCI_SUBOPENTRY_TERMINATOR -}; - -struct SciKernelMapEntry { - const char *name; - KernelFunctionCall *function; - - SciVersion fromVersion; - SciVersion toVersion; - byte forPlatform; - - const char *signature; - const SciKernelMapSubEntry *subFunctions; - const SciWorkaroundEntry *workarounds; -}; - -// name, version/platform, signature, sub-signatures, workarounds -static SciKernelMapEntry s_kernelMap[] = { - { MAP_CALL(Abs), SIG_EVERYWHERE, "i", NULL, kAbs_workarounds }, - { MAP_CALL(AddAfter), SIG_EVERYWHERE, "lnn", NULL, NULL }, - { MAP_CALL(AddMenu), SIG_EVERYWHERE, "rr", NULL, NULL }, - { MAP_CALL(AddToEnd), SIG_EVERYWHERE, "ln", NULL, NULL }, - { MAP_CALL(AddToFront), SIG_EVERYWHERE, "ln", NULL, NULL }, - { MAP_CALL(AddToPic), SIG_EVERYWHERE, "[il](iiiiii)", NULL, NULL }, - { MAP_CALL(Animate), SIG_EVERYWHERE, "(l0)(i)", NULL, NULL }, - { MAP_CALL(AssertPalette), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(AvoidPath), SIG_EVERYWHERE, "ii(.*)", NULL, NULL }, - { MAP_CALL(BaseSetter), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(CanBeHere), SIG_EVERYWHERE, "o(l)", NULL, NULL }, - { MAP_CALL(CantBeHere), SIG_EVERYWHERE, "o(l)", NULL, NULL }, - { MAP_CALL(CelHigh), SIG_EVERYWHERE, "ii(i)", NULL, NULL }, - { MAP_CALL(CelWide), SIG_EVERYWHERE, "ii(i)", NULL, NULL }, - { MAP_CALL(CheckFreeSpace), SIG_SCI32, SIGFOR_ALL, "r.*", NULL, NULL }, - { MAP_CALL(CheckFreeSpace), SIG_EVERYWHERE, "r", NULL, NULL }, - { MAP_CALL(CheckSaveGame), SIG_EVERYWHERE, ".*", NULL, NULL }, - { MAP_CALL(Clone), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(CoordPri), SIG_EVERYWHERE, "i(i)", NULL, NULL }, - { MAP_CALL(CosDiv), SIG_EVERYWHERE, "ii", NULL, NULL }, - { MAP_CALL(DeleteKey), SIG_EVERYWHERE, "l.", NULL, NULL }, - { MAP_CALL(DeviceInfo), SIG_EVERYWHERE, "i(r)(r)(i)", NULL, NULL }, // subop - { MAP_CALL(Display), SIG_EVERYWHERE, "[ir]([ir!]*)", NULL, NULL }, - // ^ we allow invalid references here, because kDisplay gets called with those in e.g. pq3 during intro - // restoreBits() checks and skips invalid handles, so that's fine. Sierra SCI behaved the same - { MAP_CALL(DirLoop), SIG_EVERYWHERE, "oi", NULL, NULL }, - { MAP_CALL(DisposeClone), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(DisposeList), SIG_EVERYWHERE, "l", NULL, NULL }, - { MAP_CALL(DisposeScript), SIG_EVERYWHERE, "i(i*)", NULL, kDisposeScript_workarounds }, - { MAP_CALL(DisposeWindow), SIG_EVERYWHERE, "i(i)", NULL, NULL }, - { MAP_CALL(DoAudio), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop - { MAP_CALL(DoAvoider), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(DoBresen), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(DoSound), SIG_EVERYWHERE, "i([io])(i)(ii[io])(i)", kDoSound_subops, NULL }, - { MAP_CALL(DoSync), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop - { MAP_CALL(DrawCel), SIG_SCI11, SIGFOR_PC, "iiiii(i)(i)(r0)", NULL, NULL }, // for kq6 hires - { MAP_CALL(DrawCel), SIG_EVERYWHERE, "iiiii(i)(i)", NULL, NULL }, - { MAP_CALL(DrawControl), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(DrawMenuBar), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(DrawPic), SIG_EVERYWHERE, "i(i)(i)(i)", NULL, NULL }, - { MAP_CALL(DrawStatus), SIG_EVERYWHERE, "[r0](i)(i)", NULL, NULL }, - { MAP_CALL(EditControl), SIG_EVERYWHERE, "[o0][o0]", NULL, NULL }, - { MAP_CALL(Empty), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(EmptyList), SIG_EVERYWHERE, "l", NULL, NULL }, - { MAP_CALL(FClose), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(FGets), SIG_EVERYWHERE, "rii", NULL, NULL }, - { MAP_CALL(FOpen), SIG_EVERYWHERE, "ri", NULL, NULL }, - { MAP_CALL(FPuts), SIG_EVERYWHERE, "ir", NULL, NULL }, - { MAP_CALL(FileIO), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop - { MAP_CALL(FindKey), SIG_EVERYWHERE, "l.", NULL, NULL }, - { MAP_CALL(FirstNode), SIG_EVERYWHERE, "[l0]", NULL, NULL }, - { MAP_CALL(FlushResources), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(Format), SIG_EVERYWHERE, "r(.*)", NULL, NULL }, - { MAP_CALL(GameIsRestarting), SIG_EVERYWHERE, "(i)", NULL, NULL }, - { MAP_CALL(GetAngle), SIG_EVERYWHERE, "iiii", NULL, NULL }, - // ^^ FIXME - occasionally KQ6 passes a 5th argument by mistake - { MAP_CALL(GetCWD), SIG_EVERYWHERE, "r", NULL, NULL }, - { MAP_CALL(GetDistance), SIG_EVERYWHERE, "ii(i)(i)(i)(i)", NULL, NULL }, - { MAP_CALL(GetEvent), SIG_SCIALL, SIGFOR_MAC, "io(i*)", NULL, NULL }, - { MAP_CALL(GetEvent), SIG_EVERYWHERE, "io", NULL, NULL }, - { MAP_CALL(GetFarText), SIG_EVERYWHERE, "ii[r0]", NULL, NULL }, - { MAP_CALL(GetMenu), SIG_EVERYWHERE, "i.", NULL, NULL }, - { MAP_CALL(GetMessage), SIG_EVERYWHERE, "iiir", NULL, NULL }, - { MAP_CALL(GetPort), SIG_EVERYWHERE, "", NULL, NULL }, - { MAP_CALL(GetSaveDir), SIG_SCI32, SIGFOR_ALL, "(r*)", NULL, NULL }, - { MAP_CALL(GetSaveDir), SIG_EVERYWHERE, "", NULL, NULL }, - { MAP_CALL(GetSaveFiles), SIG_EVERYWHERE, "rrr", NULL, NULL }, - { MAP_CALL(GetTime), SIG_EVERYWHERE, "(i)", NULL, NULL }, - { MAP_CALL(GlobalToLocal), SIG_SCI32, SIGFOR_ALL, "oo", NULL, NULL }, - { MAP_CALL(GlobalToLocal), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(Graph), SIG_EVERYWHERE, NULL, kGraph_subops, NULL }, - { MAP_CALL(HaveMouse), SIG_EVERYWHERE, "", NULL, NULL }, - { MAP_CALL(HiliteControl), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(InitBresen), SIG_EVERYWHERE, "o(i)", NULL, NULL }, - { MAP_CALL(Intersections), SIG_EVERYWHERE, "iiiiriiiri", NULL, NULL }, - { MAP_CALL(IsItSkip), SIG_EVERYWHERE, "iiiii", NULL, NULL }, - { MAP_CALL(IsObject), SIG_EVERYWHERE, ".", NULL, NULL }, - { MAP_CALL(Joystick), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop - { MAP_CALL(LastNode), SIG_EVERYWHERE, "l", NULL, NULL }, - { MAP_CALL(Load), SIG_EVERYWHERE, "ii(i*)", NULL, NULL }, - { MAP_CALL(LocalToGlobal), SIG_SCI32, SIGFOR_ALL, "oo", NULL, NULL }, - { MAP_CALL(LocalToGlobal), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(Lock), SIG_EVERYWHERE, "ii(i)", NULL, NULL }, - { MAP_CALL(MapKeyToDir), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(Memory), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop - { MAP_CALL(MemoryInfo), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(MemorySegment), SIG_EVERYWHERE, "ir(i)", NULL, NULL }, // subop - { MAP_CALL(MenuSelect), SIG_EVERYWHERE, "o(i)", NULL, NULL }, - { MAP_CALL(MergePoly), SIG_EVERYWHERE, "rli", NULL, NULL }, - { MAP_CALL(Message), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop - { MAP_CALL(MoveCursor), SIG_EVERYWHERE, "ii", NULL, NULL }, - { MAP_CALL(NewList), SIG_EVERYWHERE, "", NULL, NULL }, - { MAP_CALL(NewNode), SIG_EVERYWHERE, "..", NULL, NULL }, - { MAP_CALL(NewWindow), SIG_SCIALL, SIGFOR_MAC, ".*", NULL, NULL }, - { MAP_CALL(NewWindow), SIG_SCI0, SIGFOR_ALL, "iiii[r0]i(i)(i)(i)", NULL, NULL }, - { MAP_CALL(NewWindow), SIG_SCI1, SIGFOR_ALL, "iiii[ir]i(i)(i)([ir])(i)(i)(i)(i)", NULL, NULL }, - { MAP_CALL(NewWindow), SIG_SCI11, SIGFOR_ALL, "iiiiiiii[r0]i(i)(i)(i)", NULL, NULL }, - { MAP_CALL(NextNode), SIG_EVERYWHERE, "n", NULL, NULL }, - { MAP_CALL(NodeValue), SIG_EVERYWHERE, "[n0]", NULL, NULL }, - { MAP_CALL(NumCels), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(NumLoops), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(OnControl), SIG_EVERYWHERE, "ii(i)(i)(i)", NULL, NULL }, - { MAP_CALL(PalVary), SIG_EVERYWHERE, "i(i*)", kPalVary_subops, NULL }, - { MAP_CALL(Palette), SIG_EVERYWHERE, "i(.*)", kPalette_subops, NULL }, - { MAP_CALL(Parse), SIG_EVERYWHERE, "ro", NULL, NULL }, - { MAP_CALL(PicNotValid), SIG_EVERYWHERE, "(i)", NULL, NULL }, - { MAP_CALL(Platform), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(Portrait), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop - { MAP_CALL(PrevNode), SIG_EVERYWHERE, "n", NULL, NULL }, - { MAP_CALL(PriCoord), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(Random), SIG_EVERYWHERE, "ii", NULL, NULL }, - { MAP_CALL(ReadNumber), SIG_EVERYWHERE, "r", NULL, NULL }, - { MAP_CALL(ResCheck), SIG_EVERYWHERE, "ii(iiii)", NULL, NULL }, - { MAP_CALL(RespondsTo), SIG_EVERYWHERE, ".i", NULL, NULL }, - { MAP_CALL(RestartGame), SIG_EVERYWHERE, "", NULL, NULL }, - { MAP_CALL(RestoreGame), SIG_EVERYWHERE, "rir", NULL, NULL }, - { MAP_CALL(Said), SIG_EVERYWHERE, "[r0]", NULL, NULL }, - { MAP_CALL(SaveGame), SIG_EVERYWHERE, "rir(r)", NULL, NULL }, - { MAP_CALL(ScriptID), SIG_EVERYWHERE, "[io](i)", NULL, NULL }, - { MAP_CALL(SetCursor), SIG_EVERYWHERE, "i(i*)", NULL, NULL }, - { MAP_CALL(SetDebug), SIG_EVERYWHERE, "(i*)", NULL, NULL }, - { MAP_CALL(SetJump), SIG_EVERYWHERE, "oiii", NULL, NULL }, - { MAP_CALL(SetMenu), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, - { MAP_CALL(SetNowSeen), SIG_EVERYWHERE, "o(i)", NULL, NULL }, - { MAP_CALL(SetPort), SIG_EVERYWHERE, "i(iii)(i)(i)(i)", NULL, NULL }, - { MAP_CALL(SetQuitStr), SIG_EVERYWHERE, "r", NULL, NULL }, - { MAP_CALL(SetSynonyms), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(SetVideoMode), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(ShakeScreen), SIG_EVERYWHERE, "(i)(i)", NULL, NULL }, - { MAP_CALL(ShowMovie), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(SinDiv), SIG_EVERYWHERE, "ii", NULL, NULL }, - { MAP_CALL(Sort), SIG_EVERYWHERE, "ooo", NULL, NULL }, - { MAP_CALL(Sqrt), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(StrAt), SIG_EVERYWHERE, "ri(i)", NULL, NULL }, - { MAP_CALL(StrCat), SIG_EVERYWHERE, "rr", NULL, NULL }, - { MAP_CALL(StrCmp), SIG_EVERYWHERE, "rr(i)", NULL, NULL }, - { MAP_CALL(StrCpy), SIG_EVERYWHERE, "[r0]r(i)", NULL, NULL }, - { MAP_CALL(StrEnd), SIG_EVERYWHERE, "r", NULL, NULL }, - { MAP_CALL(StrLen), SIG_EVERYWHERE, "[r0]", NULL, NULL }, - { MAP_CALL(StrSplit), SIG_EVERYWHERE, "rr[r0]", NULL, NULL }, - { MAP_CALL(TextColors), SIG_EVERYWHERE, "(i*)", NULL, NULL }, - { MAP_CALL(TextFonts), SIG_EVERYWHERE, "(i*)", NULL, NULL }, - { MAP_CALL(TextSize), SIG_EVERYWHERE, "r[r0]i(i)(r0)", NULL, NULL }, - { MAP_CALL(TimesCos), SIG_EVERYWHERE, "ii", NULL, NULL }, - { "CosMult", kTimesCos, SIG_EVERYWHERE, "ii", NULL, NULL }, - { MAP_CALL(TimesCot), SIG_EVERYWHERE, "ii", NULL, NULL }, - { MAP_CALL(TimesSin), SIG_EVERYWHERE, "ii", NULL, NULL }, - { "SinMult", kTimesSin, SIG_EVERYWHERE, "ii", NULL, NULL }, - { MAP_CALL(TimesTan), SIG_EVERYWHERE, "ii", NULL, NULL }, - { MAP_CALL(UnLoad), SIG_EVERYWHERE, "i[ri]", NULL, kUnLoad_workarounds }, - { MAP_CALL(ValidPath), SIG_EVERYWHERE, "r", NULL, NULL }, - { MAP_CALL(Wait), SIG_EVERYWHERE, "i", NULL, NULL }, - -#ifdef ENABLE_SCI32 - // SCI2 Kernel Functions - { MAP_CALL(AddPlane), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(AddScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(Array), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(CreateTextBitmap), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, - { MAP_CALL(DeletePlane), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(DeleteScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(FrameOut), SIG_EVERYWHERE, "", NULL, NULL }, - { MAP_CALL(GetHighPlanePri), SIG_EVERYWHERE, "", NULL, NULL }, - { MAP_CALL(InPolygon), SIG_EVERYWHERE, "iio", NULL, NULL }, - { MAP_CALL(IsHiRes), SIG_EVERYWHERE, "", NULL, NULL }, - { MAP_CALL(ListAllTrue), SIG_EVERYWHERE, "li(.*)", NULL, NULL }, - { MAP_CALL(ListAt), SIG_EVERYWHERE, "li", NULL, NULL }, - { MAP_CALL(ListEachElementDo), SIG_EVERYWHERE, "li(.*)", NULL, NULL }, - { MAP_CALL(ListFirstTrue), SIG_EVERYWHERE, "li(.*)", NULL, NULL }, - { MAP_CALL(ListIndexOf), SIG_EVERYWHERE, "l[o0]", NULL, NULL }, - { MAP_CALL(OnMe), SIG_EVERYWHERE, "iio(.*)", NULL, NULL }, - { MAP_CALL(RepaintPlane), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(String), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(UpdatePlane), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(UpdateScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, - - // SCI2.1 Kernel Functions - { MAP_CALL(CD), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(IsOnMe), SIG_EVERYWHERE, "iio(.*)", NULL, NULL }, - { MAP_CALL(List), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(MulDiv), SIG_EVERYWHERE, "iii", NULL, NULL }, - { MAP_CALL(PlayVMD), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(Robot), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(Save), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(Text), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { NULL, NULL, SIG_EVERYWHERE, NULL, NULL, NULL } -#endif -}; - Kernel::Kernel(ResourceManager *resMan, SegManager *segMan) : _resMan(resMan), _segMan(segMan), _invalid("<invalid>") { loadSelectorNames(); @@ -648,16 +44,24 @@ Kernel::Kernel(ResourceManager *resMan, SegManager *segMan) Kernel::~Kernel() { for (KernelFunctionArray::iterator i = _kernelFuncs.begin(); i != _kernelFuncs.end(); ++i) - free(i->signature); + delete[] i->signature; } uint Kernel::getSelectorNamesSize() const { return _selectorNames.size(); } -const Common::String &Kernel::getSelectorName(uint selector) const { - if (selector >= _selectorNames.size()) - return _invalid; +const Common::String &Kernel::getSelectorName(uint selector) { + if (selector >= _selectorNames.size()) { + // This should only occur in games w/o a selector-table + // We need this for proper workaround tables + // TODO: maybe check, if there is a fixed selector-table and error() out in that case + for (uint loopSelector = _selectorNames.size(); loopSelector <= selector; loopSelector++) { + Common::String newSelectorName; + newSelectorName = newSelectorName.printf("<noname %d>", loopSelector); + _selectorNames.push_back(newSelectorName); + } + } return _selectorNames[selector]; } @@ -1140,7 +544,7 @@ void Kernel::mapFunctions() { _kernelFuncs[id].workarounds = NULL; _kernelFuncs[id].subFunctions = NULL; _kernelFuncs[id].subFunctionCount = 0; - _kernelFuncs[id].debugCalls = false; + _kernelFuncs[id].debugLogging = false; if (kernelName.empty()) { // No name was given -> must be an unknown opcode warning("Kernel function %x unknown", id); @@ -1246,12 +650,77 @@ void Kernel::mapFunctions() { return; } -void Kernel::setDefaultKernelNames() { +bool Kernel::debugSetFunctionLogging(const char *kernelName, bool logging) { + if (strcmp(kernelName, "*")) { + for (uint id = 0; id < _kernelFuncs.size(); id++) { + if (_kernelFuncs[id].name) { + if (strcmp(kernelName, _kernelFuncs[id].name) == 0) { + if (_kernelFuncs[id].subFunctions) { + // sub-functions available and main name matched, in that case set logging of all sub-functions + KernelSubFunction *kernelSubCall = _kernelFuncs[id].subFunctions; + uint kernelSubCallCount = _kernelFuncs[id].subFunctionCount; + for (uint subId = 0; subId < kernelSubCallCount; subId++) { + if (kernelSubCall->function) + kernelSubCall->debugLogging = logging; + kernelSubCall++; + } + return true; + } + // function name matched, set for this one and exit + _kernelFuncs[id].debugLogging = logging; + return true; + } else { + // main name was not matched + if (_kernelFuncs[id].subFunctions) { + // Sub-Functions available + KernelSubFunction *kernelSubCall = _kernelFuncs[id].subFunctions; + uint kernelSubCallCount = _kernelFuncs[id].subFunctionCount; + for (uint subId = 0; subId < kernelSubCallCount; subId++) { + if (kernelSubCall->function) { + if (strcmp(kernelName, kernelSubCall->name) == 0) { + // sub-function name matched, set for this one and exit + kernelSubCall->debugLogging = logging; + return true; + } + } + kernelSubCall++; + } + } + } + } + } + return false; + } + // Set debugLogging for all calls + for (uint id = 0; id < _kernelFuncs.size(); id++) { + if (_kernelFuncs[id].name) { + if (!_kernelFuncs[id].subFunctions) { + // No sub-functions, enable actual kernel function + _kernelFuncs[id].debugLogging = logging; + } else { + // Sub-Functions available, enable those too + KernelSubFunction *kernelSubCall = _kernelFuncs[id].subFunctions; + uint kernelSubCallCount = _kernelFuncs[id].subFunctionCount; + for (uint subId = 0; subId < kernelSubCallCount; subId++) { + if (kernelSubCall->function) + kernelSubCall->debugLogging = logging; + kernelSubCall++; + } + } + } + } + return true; +} + +void Kernel::setDefaultKernelNames(GameFeatures *features) { _kernelNames = Common::StringArray(s_defaultKernelNames, ARRAYSIZE(s_defaultKernelNames)); // Some (later) SCI versions replaced CanBeHere by CantBeHere - if (_selectorCache.cantBeHere != -1) - _kernelNames[0x4d] = "CantBeHere"; + if (_selectorCache.cantBeHere != -1) { + // hoyle 3 has cantBeHere selector but is assuming to call kCanBeHere + if (g_sci->getGameId() != GID_HOYLE3) + _kernelNames[0x4d] = "CantBeHere"; + } switch (getSciVersion()) { case SCI_VERSION_0_EARLY: @@ -1298,7 +767,11 @@ void Kernel::setDefaultKernelNames() { } _kernelNames[0x71] = "PalVary"; - _kernelNames[0x7c] = "Message"; + + // At least EcoQuest 1 demo uses kGetMessage instead of kMessage. + // Detect which function to use. + if (features->detectMessageFunctionType() == SCI_VERSION_1_1) + _kernelNames[0x7c] = "Message"; break; default: @@ -1307,6 +780,39 @@ void Kernel::setDefaultKernelNames() { } } +#ifdef ENABLE_SCI32 + +enum { + kKernelEntriesSci2 = 0x8b, + kKernelEntriesGk2Demo = 0xa0, + kKernelEntriesSci21 = 0x9d +}; + +void Kernel::setKernelNamesSci2() { + _kernelNames = Common::StringArray(sci2_default_knames, kKernelEntriesSci2); +} + +void Kernel::setKernelNamesSci21(GameFeatures *features) { + // Some SCI games use a modified SCI2 kernel table instead of the + // SCI2.1 kernel table. The GK2 demo does this as well as at least + // one version of KQ7 (1.4). We detect which version to use based on + // how kDoSound is called from Sound::play(). + + // This is interesting because they all have the same interpreter + // version (2.100.002), yet they would not be compatible with other + // games of the same interpreter. + + if (features->detectSci21KernelType() == SCI_VERSION_2) { + _kernelNames = Common::StringArray(sci2_default_knames, kKernelEntriesGk2Demo); + // OnMe is IsOnMe here, but they should be compatible + _kernelNames[0x23] = "Robot"; // Graph in SCI2 + _kernelNames[0x2e] = "Priority"; // DisposeTextBitmap in SCI2 + } else + _kernelNames = Common::StringArray(sci21_default_knames, kKernelEntriesSci21); +} + +#endif + void Kernel::loadKernelNames(GameFeatures *features) { _kernelNames.clear(); @@ -1317,7 +823,7 @@ void Kernel::loadKernelNames(GameFeatures *features) { setKernelNamesSci2(); else #endif - setDefaultKernelNames(); + setDefaultKernelNames(features); mapFunctions(); } @@ -1352,4 +858,26 @@ Common::String Kernel::lookupText(reg_t address, int index) { return NULL; } +// TODO: script_adjust_opcode_formats should probably be part of the +// constructor (?) of a VirtualMachine or a ScriptManager class. +void script_adjust_opcode_formats() { + if (g_sci->_features->detectLofsType() != SCI_VERSION_0_EARLY) { + g_opcode_formats[op_lofsa][0] = Script_Offset; + g_opcode_formats[op_lofss][0] = Script_Offset; + } + +#ifdef ENABLE_SCI32 + // In SCI32, some arguments are now words instead of bytes + if (getSciVersion() >= SCI_VERSION_2) { + g_opcode_formats[op_calle][2] = Script_Word; + g_opcode_formats[op_callk][1] = Script_Word; + g_opcode_formats[op_super][1] = Script_Word; + g_opcode_formats[op_send][0] = Script_Word; + g_opcode_formats[op_self][0] = Script_Word; + g_opcode_formats[op_call][1] = Script_Word; + g_opcode_formats[op_callb][1] = Script_Word; + } +#endif +} + } // End of namespace Sci diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index fa206e8053..285e746349 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -40,6 +40,7 @@ namespace Sci { struct Node; // from segment.h struct List; // from segment.h struct SelectorCache; // from selector.h +struct SciWorkaroundEntry; // from workarounds.h /** * @defgroup VocabularyResources Vocabulary resources in SCI @@ -100,12 +101,12 @@ struct SelectorCache; // from selector.h enum { SIG_TYPE_NULL = 0x01, // may be 0:0 [0] SIG_TYPE_INTEGER = 0x02, // may be 0:* [i], automatically also allows null - SIG_TYPE_UNINITIALIZED = 0x04, // may be FFFF:* -> not allowable, only used for comparsion + SIG_TYPE_UNINITIALIZED = 0x04, // may be FFFF:* -> not allowable, only used for comparison SIG_TYPE_OBJECT = 0x08, // may be object [o] SIG_TYPE_REFERENCE = 0x10, // may be reference [r] SIG_TYPE_LIST = 0x20, // may be list [l] SIG_TYPE_NODE = 0x40, // may be node [n] - SIG_TYPE_ERROR = 0x80, // happens, when there is a identification error - only used for comparsion + SIG_TYPE_ERROR = 0x80, // happens, when there is a identification error - only used for comparison SIG_IS_INVALID = 0x100, // ptr is invalid [!] -> invalid offset SIG_IS_OPTIONAL = 0x200, // is optional SIG_NEEDS_MORE = 0x400, // needs at least one additional parameter following @@ -120,24 +121,12 @@ enum { /* Generic description: */ typedef reg_t KernelFunctionCall(EngineState *s, int argc, reg_t *argv); -struct SciWorkaroundEntry { - SciGameId gameId; - int scriptNr; - int16 inheritanceLevel; - const char *objectName; - const char *methodName; - int localCallOffset; - int index; - reg_t newValue; -}; - -#define SCI_WORKAROUNDENTRY_TERMINATOR { (SciGameId)0, -1, 0, NULL, NULL, -1, 0, { 0, 0 } } - struct KernelSubFunction { KernelFunctionCall *function; const char *name; uint16 *signature; const SciWorkaroundEntry *workarounds; + bool debugLogging; }; struct KernelFunction { @@ -145,9 +134,9 @@ struct KernelFunction { const char *name; uint16 *signature; const SciWorkaroundEntry *workarounds; - const KernelSubFunction *subFunctions; + KernelSubFunction *subFunctions; uint16 subFunctionCount; - bool debugCalls; + bool debugLogging; }; class Kernel { @@ -159,7 +148,7 @@ public: ~Kernel(); uint getSelectorNamesSize() const; - const Common::String &getSelectorName(uint selector) const; + const Common::String &getSelectorName(uint selector); uint getKernelNamesSize() const; const Common::String &getKernelName(uint number) const; @@ -228,11 +217,16 @@ public: */ void loadKernelNames(GameFeatures *features); + /** + * Sets debugCalls flag for a kernel function + */ + bool debugSetFunctionLogging(const char *kernelName, bool debugCalls); + private: /** * Sets the default kernel function names, based on the SCI version used. */ - void setDefaultKernelNames(); + void setDefaultKernelNames(GameFeatures *features); #ifdef ENABLE_SCI32 /** @@ -423,7 +417,10 @@ reg_t kStrSplit(EngineState *s, int argc, reg_t *argv); reg_t kPlatform(EngineState *s, int argc, reg_t *argv); reg_t kTextColors(EngineState *s, int argc, reg_t *argv); reg_t kTextFonts(EngineState *s, int argc, reg_t *argv); +reg_t kDummy(EngineState *s, int argc, reg_t *argv); reg_t kEmpty(EngineState *s, int argc, reg_t *argv); +reg_t kStub(EngineState *s, int argc, reg_t *argv); +reg_t kStubNull(EngineState *s, int argc, reg_t *argv); #ifdef ENABLE_SCI32 // SCI2 Kernel Functions @@ -432,6 +429,7 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv); reg_t kListAt(EngineState *s, int argc, reg_t *argv); reg_t kString(EngineState *s, int argc, reg_t *argv); reg_t kMulDiv(EngineState *s, int argc, reg_t *argv); +reg_t kCantBeHere32(EngineState *s, int argc, reg_t *argv); // "Screen items" in SCI32 are views reg_t kAddScreenItem(EngineState *s, int argc, reg_t *argv); reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv); @@ -460,7 +458,11 @@ reg_t kRobot(EngineState *s, int argc, reg_t *argv); reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv); reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv); reg_t kCD(EngineState *s, int argc, reg_t *argv); +reg_t kAddPicAt(EngineState *s, int argc, reg_t *argv); +reg_t kAddBefore(EngineState *s, int argc, reg_t *argv); +reg_t kMoveToFront(EngineState *s, int argc, reg_t *argv); +reg_t kMoveToEnd(EngineState *s, int argc, reg_t *argv); #endif reg_t kDoSoundInit(EngineState *s, int argc, reg_t *argv); @@ -471,7 +473,7 @@ reg_t kDoSoundMute(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundStop(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundStopAll(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundPause(EngineState *s, int argc, reg_t *argv); -reg_t kDoSoundResume(EngineState *s, int argc, reg_t *argv); +reg_t kDoSoundResumeAfterRestore(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundMasterVolume(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundUpdate(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundFade(EngineState *s, int argc, reg_t *argv); @@ -516,6 +518,25 @@ reg_t kPaletteAnimate(EngineState *s, int argc, reg_t *argv); reg_t kPaletteSave(EngineState *s, int argc, reg_t *argv); reg_t kPaletteRestore(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOReadRaw(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOWriteRaw(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOReadString(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOFindFirst(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOFindNext(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv); +reg_t kFileIORename(EngineState *s, int argc, reg_t *argv); +#ifdef ENABLE_SCI32 +reg_t kFileIOReadByte(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOWriteByte(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOReadWord(EngineState *s, int argc, reg_t *argv); +reg_t kFileIOWriteWord(EngineState *s, int argc, reg_t *argv); +#endif + //@} } // End of namespace Sci diff --git a/engines/sci/engine/kernel32.cpp b/engines/sci/engine/kernel32.cpp deleted file mode 100644 index eab1b90139..0000000000 --- a/engines/sci/engine/kernel32.cpp +++ /dev/null @@ -1,932 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifdef ENABLE_SCI32 - -#include "sci/engine/features.h" -#include "sci/engine/kernel.h" -#include "sci/engine/segment.h" -#include "sci/engine/state.h" -#include "sci/engine/selector.h" -#include "sci/graphics/frameout.h" -#include "sci/graphics/screen.h" - -#include "common/system.h" - -namespace Sci { - -// NOTE: 0x72-0x79, 0x85-0x86, 0x88 are from the GK2 demo (which has debug support) and are -// just Dummy in other SCI2 games. -static const char *sci2_default_knames[] = { - /*0x00*/ "Load", - /*0x01*/ "UnLoad", - /*0x02*/ "ScriptID", - /*0x03*/ "DisposeScript", - /*0x04*/ "Lock", - /*0x05*/ "ResCheck", - /*0x06*/ "Purge", - /*0x07*/ "Clone", - /*0x08*/ "DisposeClone", - /*0x09*/ "RespondsTo", - /*0x0a*/ "SetNowSeen", - /*0x0b*/ "NumLoops", - /*0x0c*/ "NumCels", - /*0x0d*/ "CelWide", - /*0x0e*/ "CelHigh", - /*0x0f*/ "GetHighPlanePri", - /*0x10*/ "GetHighItemPri", - /*0x11*/ "ShakeScreen", - /*0x12*/ "OnMe", - /*0x13*/ "ShowMovie", - /*0x14*/ "SetVideoMode", - /*0x15*/ "AddScreenItem", - /*0x16*/ "DeleteScreenItem", - /*0x17*/ "UpdateScreenItem", - /*0x18*/ "FrameOut", - /*0x19*/ "AddPlane", - /*0x1a*/ "DeletePlane", - /*0x1b*/ "UpdatePlane", - /*0x1c*/ "RepaintPlane", - /*0x1d*/ "SetShowStyle", - /*0x1e*/ "ShowStylePercent", - /*0x1f*/ "SetScroll", - /*0x20*/ "AddMagnify", - /*0x21*/ "DeleteMagnify", - /*0x22*/ "IsHiRes", - /*0x23*/ "Graph", - /*0x24*/ "InvertRect", - /*0x25*/ "TextSize", - /*0x26*/ "Message", - /*0x27*/ "TextColors", - /*0x28*/ "TextFonts", - /*0x29*/ "Dummy", - /*0x2a*/ "SetQuitStr", - /*0x2b*/ "EditText", - /*0x2c*/ "InputText", - /*0x2d*/ "CreateTextBitmap", - /*0x2e*/ "DisposeTextBitmap", - /*0x2f*/ "GetEvent", - /*0x30*/ "GlobalToLocal", - /*0x31*/ "LocalToGlobal", - /*0x32*/ "MapKeyToDir", - /*0x33*/ "HaveMouse", - /*0x34*/ "SetCursor", - /*0x35*/ "VibrateMouse", - /*0x36*/ "SaveGame", - /*0x37*/ "RestoreGame", - /*0x38*/ "RestartGame", - /*0x39*/ "GameIsRestarting", - /*0x3a*/ "MakeSaveCatName", - /*0x3b*/ "MakeSaveFileName", - /*0x3c*/ "GetSaveFiles", - /*0x3d*/ "GetSaveDir", - /*0x3e*/ "CheckSaveGame", - /*0x3f*/ "CheckFreeSpace", - /*0x40*/ "DoSound", - /*0x41*/ "DoAudio", - /*0x42*/ "DoSync", - /*0x43*/ "NewList", - /*0x44*/ "DisposeList", - /*0x45*/ "NewNode", - /*0x46*/ "FirstNode", - /*0x47*/ "LastNode", - /*0x48*/ "EmptyList", - /*0x49*/ "NextNode", - /*0x4a*/ "PrevNode", - /*0x4b*/ "NodeValue", - /*0x4c*/ "AddAfter", - /*0x4d*/ "AddToFront", - /*0x4e*/ "AddToEnd", - /*0x4f*/ "Dummy", - /*0x50*/ "Dummy", - /*0x51*/ "FindKey", - /*0x52*/ "Dummy", - /*0x53*/ "Dummy", - /*0x54*/ "Dummy", - /*0x55*/ "DeleteKey", - /*0x56*/ "Dummy", - /*0x57*/ "Dummy", - /*0x58*/ "ListAt", - /*0x59*/ "ListIndexOf", - /*0x5a*/ "ListEachElementDo", - /*0x5b*/ "ListFirstTrue", - /*0x5c*/ "ListAllTrue", - /*0x5d*/ "Random", - /*0x5e*/ "Abs", - /*0x5f*/ "Sqrt", - /*0x60*/ "GetAngle", - /*0x61*/ "GetDistance", - /*0x62*/ "ATan", - /*0x63*/ "SinMult", - /*0x64*/ "CosMult", - /*0x65*/ "SinDiv", - /*0x66*/ "CosDiv", - /*0x67*/ "GetTime", - /*0x68*/ "Platform", - /*0x69*/ "BaseSetter", - /*0x6a*/ "DirLoop", - /*0x6b*/ "CantBeHere", - /*0x6c*/ "InitBresen", - /*0x6d*/ "DoBresen", - /*0x6e*/ "SetJump", - /*0x6f*/ "AvoidPath", - /*0x70*/ "InPolygon", - /*0x71*/ "MergePoly", - /*0x72*/ "SetDebug", - /*0x73*/ "InspectObject", - /*0x74*/ "MemoryInfo", - /*0x75*/ "Profiler", - /*0x76*/ "Record", - /*0x77*/ "PlayBack", - /*0x78*/ "MonoOut", - /*0x79*/ "SetFatalStr", - /*0x7a*/ "GetCWD", - /*0x7b*/ "ValidPath", - /*0x7c*/ "FileIO", - /*0x7d*/ "Dummy", - /*0x7e*/ "DeviceInfo", - /*0x7f*/ "Palette", - /*0x80*/ "PalVary", - /*0x81*/ "PalCycle", - /*0x82*/ "Array", - /*0x83*/ "String", - /*0x84*/ "RemapColors", - /*0x85*/ "IntegrityChecking", - /*0x86*/ "CheckIntegrity", - /*0x87*/ "ObjectIntersect", - /*0x88*/ "MarkMemory", - /*0x89*/ "TextWidth", - /*0x8a*/ "PointSize", - - // GK2 Demo only kernel functions - /*0x8b*/ "AddLine", - /*0x8c*/ "DeleteLine", - /*0x8d*/ "UpdateLine", - /*0x8e*/ "AddPolygon", - /*0x8f*/ "DeletePolygon", - /*0x90*/ "UpdatePolygon", - /*0x91*/ "Bitmap", - /*0x92*/ "ScrollWindow", - /*0x93*/ "SetFontRes", - /*0x94*/ "MovePlaneItems", - /*0x95*/ "PreloadResource", - /*0x96*/ "Dummy", - /*0x97*/ "ResourceTrack", - /*0x98*/ "CheckCDisc", - /*0x99*/ "GetSaveCDisc", - /*0x9a*/ "TestPoly", - /*0x9b*/ "WinHelp", - /*0x9c*/ "LoadChunk", - /*0x9d*/ "SetPalStyleRange", - /*0x9e*/ "AddPicAt", - /*0x9f*/ "MessageBox" -}; - -static const char *sci21_default_knames[] = { - /*0x00*/ "Load", - /*0x01*/ "UnLoad", - /*0x02*/ "ScriptID", - /*0x03*/ "DisposeScript", - /*0x04*/ "Lock", - /*0x05*/ "ResCheck", - /*0x06*/ "Purge", - /*0x07*/ "SetLanguage", - /*0x08*/ "Dummy", - /*0x09*/ "Dummy", - /*0x0a*/ "Clone", - /*0x0b*/ "DisposeClone", - /*0x0c*/ "RespondsTo", - /*0x0d*/ "FindSelector", - /*0x0e*/ "FindClass", - /*0x0f*/ "Dummy", - /*0x10*/ "Dummy", - /*0x11*/ "Dummy", - /*0x12*/ "Dummy", - /*0x13*/ "Dummy", - /*0x14*/ "SetNowSeen", - /*0x15*/ "NumLoops", - /*0x16*/ "NumCels", - /*0x17*/ "IsOnMe", - /*0x18*/ "AddMagnify", - /*0x19*/ "DeleteMagnify", - /*0x1a*/ "CelRect", - /*0x1b*/ "BaseLineSpan", - /*0x1c*/ "CelWide", - /*0x1d*/ "CelHigh", - /*0x1e*/ "AddScreenItem", - /*0x1f*/ "DeleteScreenItem", - /*0x20*/ "UpdateScreenItem", - /*0x21*/ "FrameOut", - /*0x22*/ "CelInfo", - /*0x23*/ "Bitmap", - /*0x24*/ "CelLink", - /*0x25*/ "Dummy", - /*0x26*/ "Dummy", - /*0x27*/ "Dummy", - /*0x28*/ "AddPlane", - /*0x29*/ "DeletePlane", - /*0x2a*/ "UpdatePlane", - /*0x2b*/ "RepaintPlane", - /*0x2c*/ "GetHighPlanePri", - /*0x2d*/ "GetHighItemPri", - /*0x2e*/ "SetShowStyle", - /*0x2f*/ "ShowStylePercent", - /*0x30*/ "SetScroll", - /*0x31*/ "MovePlaneItems", - /*0x32*/ "ShakeScreen", - /*0x33*/ "Dummy", - /*0x34*/ "Dummy", - /*0x35*/ "Dummy", - /*0x36*/ "Dummy", - /*0x37*/ "IsHiRes", - /*0x38*/ "SetVideoMode", - /*0x39*/ "ShowMovie", - /*0x3a*/ "Robot", - /*0x3b*/ "CreateTextBitmap", - /*0x3c*/ "Random", - /*0x3d*/ "Abs", - /*0x3e*/ "Sqrt", - /*0x3f*/ "GetAngle", - /*0x40*/ "GetDistance", - /*0x41*/ "ATan", - /*0x42*/ "SinMult", - /*0x43*/ "CosMult", - /*0x44*/ "SinDiv", - /*0x45*/ "CosDiv", - /*0x46*/ "Text", - /*0x47*/ "Dummy", - /*0x48*/ "Message", - /*0x49*/ "Font", - /*0x4a*/ "EditText", - /*0x4b*/ "InputText", - /*0x4c*/ "ScrollWindow", - /*0x4d*/ "Dummy", - /*0x4e*/ "Dummy", - /*0x4f*/ "Dummy", - /*0x50*/ "GetEvent", - /*0x51*/ "GlobalToLocal", - /*0x52*/ "LocalToGlobal", - /*0x53*/ "MapKeyToDir", - /*0x54*/ "HaveMouse", - /*0x55*/ "SetCursor", - /*0x56*/ "VibrateMouse", // NOTE: Not in SCI3, instead replaced by Dummy. - /*0x57*/ "Dummy", - /*0x58*/ "Dummy", - /*0x59*/ "Dummy", - /*0x5a*/ "List", - /*0x5b*/ "Array", - /*0x5c*/ "String", - /*0x5d*/ "FileIO", - /*0x5e*/ "BaseSetter", - /*0x5f*/ "DirLoop", - /*0x60*/ "CantBeHere", - /*0x61*/ "InitBresen", - /*0x62*/ "DoBresen", - /*0x63*/ "SetJump", - /*0x64*/ "AvoidPath", - /*0x65*/ "InPolygon", - /*0x66*/ "MergePoly", - /*0x67*/ "ObjectIntersect", - /*0x68*/ "Dummy", - /*0x69*/ "MemoryInfo", - /*0x6a*/ "DeviceInfo", - /*0x6b*/ "Palette", - /*0x6c*/ "PalVary", - /*0x6d*/ "PalCycle", - /*0x6e*/ "RemapColors", - /*0x6f*/ "AddLine", - /*0x70*/ "DeleteLine", - /*0x71*/ "UpdateLine", - /*0x72*/ "AddPolygon", - /*0x73*/ "DeletePolygon", - /*0x74*/ "UpdatePolygon", - /*0x75*/ "DoSound", - /*0x76*/ "DoAudio", - /*0x77*/ "DoSync", - /*0x78*/ "Save", - /*0x79*/ "GetTime", - /*0x7a*/ "Platform", - /*0x7b*/ "CD", - /*0x7c*/ "SetQuitStr", - /*0x7d*/ "GetConfig", - /*0x7e*/ "Table", - /*0x7f*/ "WinHelp", // Windows only - /*0x80*/ "Dummy", - /*0x81*/ "Dummy", - /*0x82*/ "Dummy", - /*0x83*/ "PrintDebug", // used by the Shivers 2 demo - /*0x84*/ "Dummy", - /*0x85*/ "Dummy", - /*0x86*/ "Dummy", - /*0x87*/ "Dummy", - /*0x88*/ "Dummy", - /*0x89*/ "Dummy", - /*0x8a*/ "LoadChunk", - /*0x8b*/ "SetPalStyleRange", - /*0x8c*/ "AddPicAt", - /*0x8d*/ "Dummy", - /*0x8e*/ "NewRoom", - /*0x8f*/ "Dummy", - /*0x90*/ "Priority", - /*0x91*/ "MorphOn", - /*0x92*/ "PlayVMD", - /*0x93*/ "SetHotRectangles", - /*0x94*/ "MulDiv", - /*0x95*/ "GetSierraProfileInt", // Windows only - /*0x96*/ "GetSierraProfileString", // Windows only - /*0x97*/ "SetWindowsOption", // Windows only - /*0x98*/ "GetWindowsOption", // Windows only - /*0x99*/ "WinDLL", // Windows only - - // SCI3 - /*0x9a*/ "Dummy", - /*0x9b*/ "Dummy", - /*0x9c*/ "DeletePic" -}; - -enum { - kKernelEntriesSci2 = 0x8b, - kKernelEntriesGk2Demo = 0xa0, - kKernelEntriesSci21 = 0x9a, - kKernelEntriesSci3 = 0x9d -}; - -void Kernel::setKernelNamesSci2() { - _kernelNames = Common::StringArray(sci2_default_knames, kKernelEntriesSci2); -} - -void Kernel::setKernelNamesSci21(GameFeatures *features) { - // Some SCI games use a modified SCI2 kernel table instead of the - // SCI2.1/SCI3 kernel table. The GK2 demo does this as well as at - // least one version of KQ7. We detect which version to use based on - // where kDoSound is called from Sound::play(). - - // This is interesting because they all have the same interpreter - // version (2.100.002), yet they would not be compatible with other - // games of the same interpreter. - - if (features->detectSci21KernelType() == SCI_VERSION_2) { - _kernelNames = Common::StringArray(sci2_default_knames, kKernelEntriesGk2Demo); - // OnMe is IsOnMe here, but they should be compatible - _kernelNames[0x23] = "Robot"; // Graph in SCI2 - _kernelNames[0x2e] = "Priority"; // DisposeTextBitmap in SCI2 - } else { - // TODO: Differentiate between SCI2.1/3 - _kernelNames = Common::StringArray(sci21_default_knames, kKernelEntriesSci3); - } -} - -// SCI2 Kernel Functions - -reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv) { - // Returns 0 if the screen width or height is less than 640 or 400, - // respectively. - if (g_system->getWidth() < 640 || g_system->getHeight() < 400) - return make_reg(0, 0); - - return make_reg(0, 1); -} - -reg_t kArray(EngineState *s, int argc, reg_t *argv) { - switch (argv[0].toUint16()) { - case 0: { // New - reg_t arrayHandle; - SciArray<reg_t> *array = s->_segMan->allocateArray(&arrayHandle); - array->setType(argv[2].toUint16()); - array->setSize(argv[1].toUint16()); - return arrayHandle; - } - case 1: { // Size - SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); - return make_reg(0, array->getSize()); - } - case 2: { // At (return value at an index) - SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); - return array->getValue(argv[2].toUint16()); - } - case 3: { // Atput (put value at an index) - SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); - - uint32 index = argv[2].toUint16(); - uint32 count = argc - 3; - - if (index + count > 65535) - break; - - if (array->getSize() < index + count) - array->setSize(index + count); - - for (uint16 i = 0; i < count; i++) - array->setValue(i + index, argv[i + 3]); - - return argv[1]; // We also have to return the handle - } - case 4: // Free - // Freeing of arrays is handled by the garbage collector - return s->r_acc; - case 5: { // Fill - SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); - uint16 index = argv[2].toUint16(); - - // A count of -1 means fill the rest of the array - uint16 count = argv[3].toSint16() == -1 ? array->getSize() - index : argv[3].toUint16(); - uint16 arraySize = array->getSize(); - - if (arraySize < index + count) - array->setSize(index + count); - - for (uint16 i = 0; i < count; i++) - array->setValue(i + index, argv[4]); - - return argv[1]; - } - case 6: { // Cpy - if (s->_segMan->getSegmentObj(argv[1].segment)->getType() != SEG_TYPE_ARRAY || - s->_segMan->getSegmentObj(argv[3].segment)->getType() != SEG_TYPE_ARRAY) { - // Happens in the RAMA demo - warning("kArray(Cpy): Request to copy a segment which isn't an array, ignoring"); - return NULL_REG; - } - - SciArray<reg_t> *array1 = s->_segMan->lookupArray(argv[1]); - SciArray<reg_t> *array2 = s->_segMan->lookupArray(argv[3]); - uint32 index1 = argv[2].toUint16(); - uint32 index2 = argv[4].toUint16(); - - // The original engine ignores bad copies too - if (index2 > array2->getSize()) - break; - - // A count of -1 means fill the rest of the array - uint32 count = argv[5].toSint16() == -1 ? array2->getSize() - index2 : argv[5].toUint16(); - - if (array1->getSize() < index1 + count) - array1->setSize(index1 + count); - - for (uint16 i = 0; i < count; i++) - array1->setValue(i + index1, array2->getValue(i + index2)); - - return argv[1]; - } - case 7: // Cmp - // Not implemented in SSCI - return s->r_acc; - case 8: { // Dup - SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); - reg_t arrayHandle; - SciArray<reg_t> *dupArray = s->_segMan->allocateArray(&arrayHandle); - - dupArray->setType(array->getType()); - dupArray->setSize(array->getSize()); - - for (uint32 i = 0; i < array->getSize(); i++) - dupArray->setValue(i, array->getValue(i)); - - return arrayHandle; - } - case 9: // Getdata - if (!s->_segMan->isHeapObject(argv[1])) - return argv[1]; - - return readSelector(s->_segMan, argv[1], SELECTOR(data)); - default: - error("Unknown kArray subop %d", argv[0].toUint16()); - } - - return NULL_REG; -} - -reg_t kText(EngineState *s, int argc, reg_t *argv) { - switch (argv[0].toUint16()) { - case 0: - return kTextSize(s, argc - 1, argv + 1); - default: - // TODO: Other subops here too, perhaps kTextColors and kTextFonts - warning("kText(%d)", argv[0].toUint16()); - break; - } - - return s->r_acc; -} - -reg_t kString(EngineState *s, int argc, reg_t *argv) { - switch (argv[0].toUint16()) { - case 0: { // New - reg_t stringHandle; - SciString *string = s->_segMan->allocateString(&stringHandle); - string->setSize(argv[1].toUint16()); - - // Make sure the first character is a null character - if (string->getSize() > 0) - string->setValue(0, 0); - - return stringHandle; - } - case 1: // Size - return make_reg(0, s->_segMan->getString(argv[1]).size()); - case 2: { // At (return value at an index) - if (argv[1].segment == s->_segMan->getStringSegmentId()) - return make_reg(0, s->_segMan->lookupString(argv[1])->getRawData()[argv[2].toUint16()]); - - return make_reg(0, s->_segMan->getString(argv[1])[argv[2].toUint16()]); - } - case 3: { // Atput (put value at an index) - SciString *string = s->_segMan->lookupString(argv[1]); - - uint32 index = argv[2].toUint16(); - uint32 count = argc - 3; - - if (index + count > 65535) - break; - - if (string->getSize() < index + count) - string->setSize(index + count); - - for (uint16 i = 0; i < count; i++) - string->setValue(i + index, argv[i + 3].toUint16()); - - return argv[1]; // We also have to return the handle - } - case 4: // Free - // Freeing of strings is handled by the garbage collector - return s->r_acc; - case 5: { // Fill - SciString *string = s->_segMan->lookupString(argv[1]); - uint16 index = argv[2].toUint16(); - - // A count of -1 means fill the rest of the array - uint16 count = argv[3].toSint16() == -1 ? string->getSize() - index : argv[3].toUint16(); - uint16 stringSize = string->getSize(); - - if (stringSize < index + count) - string->setSize(index + count); - - for (uint16 i = 0; i < count; i++) - string->setValue(i + index, argv[4].toUint16()); - - return argv[1]; - } - case 6: { // Cpy - const char *string2 = 0; - uint32 string2Size = 0; - - if (argv[3].segment == s->_segMan->getStringSegmentId()) { - SciString *string = s->_segMan->lookupString(argv[3]); - string2 = string->getRawData(); - string2Size = string->getSize(); - } else { - Common::String string = s->_segMan->getString(argv[3]); - string2 = string.c_str(); - string2Size = string.size() + 1; - } - - uint32 index1 = argv[2].toUint16(); - uint32 index2 = argv[4].toUint16(); - - // The original engine ignores bad copies too - if (index2 > string2Size) - break; - - // A count of -1 means fill the rest of the array - uint32 count = argv[5].toSint16() == -1 ? string2Size - index2 + 1 : argv[5].toUint16(); - - // We have a special case here for argv[1] being a system string - if (argv[1].segment == s->_segMan->getSysStringsSegment()) { - // Resize if necessary - const uint16 sysStringId = argv[1].toUint16(); - SystemString *sysString = s->_segMan->getSystemString(sysStringId); - assert(sysString); - if ((uint32)sysString->_maxSize < index1 + count) { - free(sysString->_value); - sysString->_maxSize = index1 + count; - sysString->_value = (char *)calloc(index1 + count, sizeof(char)); - } - - strncpy(sysString->_value + index1, string2 + index2, count); - } else { - SciString *string1 = s->_segMan->lookupString(argv[1]); - - if (string1->getSize() < index1 + count) - string1->setSize(index1 + count); - - // Note: We're accessing from c_str() here because the - // string's size ignores the trailing 0 and therefore - // triggers an assert when doing string2[i + index2]. - for (uint16 i = 0; i < count; i++) - string1->setValue(i + index1, string2[i + index2]); - } - - } return argv[1]; - case 7: { // Cmp - Common::String string1 = argv[1].isNull() ? "" : s->_segMan->getString(argv[1]); - Common::String string2 = argv[2].isNull() ? "" : s->_segMan->getString(argv[2]); - - if (argc == 4) // Strncmp - return make_reg(0, strncmp(string1.c_str(), string2.c_str(), argv[3].toUint16())); - else // Strcmp - return make_reg(0, strcmp(string1.c_str(), string2.c_str())); - } - case 8: { // Dup - const char *rawString = 0; - uint32 size = 0; - - if (argv[1].segment == s->_segMan->getStringSegmentId()) { - SciString *string = s->_segMan->lookupString(argv[1]); - rawString = string->getRawData(); - size = string->getSize(); - } else { - Common::String string = s->_segMan->getString(argv[1]); - rawString = string.c_str(); - size = string.size() + 1; - } - - reg_t stringHandle; - SciString *dupString = s->_segMan->allocateString(&stringHandle); - dupString->setSize(size); - - for (uint32 i = 0; i < size; i++) - dupString->setValue(i, rawString[i]); - - return stringHandle; - } - case 9: // Getdata - if (!s->_segMan->isHeapObject(argv[1])) - return argv[1]; - - return readSelector(s->_segMan, argv[1], SELECTOR(data)); - case 10: // Stringlen - return make_reg(0, s->_segMan->strlen(argv[1])); - case 11: { // Printf - reg_t stringHandle; - s->_segMan->allocateString(&stringHandle); - - reg_t *adjustedArgs = new reg_t[argc]; - adjustedArgs[0] = stringHandle; - memcpy(&adjustedArgs[1], argv + 1, (argc - 1) * sizeof(reg_t)); - - kFormat(s, argc, adjustedArgs); - delete[] adjustedArgs; - return stringHandle; - } - case 12: // Printf Buf - return kFormat(s, argc - 1, argv + 1); - case 13: { // atoi - Common::String string = s->_segMan->getString(argv[1]); - return make_reg(0, (uint16)atoi(string.c_str())); - } - default: - error("Unknown kString subop %d", argv[0].toUint16()); - } - - return NULL_REG; -} - -reg_t kSave(EngineState *s, int argc, reg_t *argv) { - switch (argv[0].toUint16()) { - case 2: // GetSaveDir - // Yay! Reusing the old kernel function! - return kGetSaveDir(s, argc - 1, argv + 1); - case 8: - // TODO - // This function has to return something other than 0 to proceed - return s->r_acc; - default: - warning("Unknown/unhandled kSave subop %d", argv[0].toUint16()); - } - - return NULL_REG; -} - -reg_t kAddScreenItem(EngineState *s, int argc, reg_t *argv) { - reg_t viewObj = argv[0]; - - g_sci->_gfxFrameout->kernelAddScreenItem(viewObj); - return NULL_REG; -} - -reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv) { - //reg_t viewObj = argv[0]; - - //warning("kUpdateScreenItem, object %04x:%04x, view %d, loop %d, cel %d, pri %d", PRINT_REG(viewObj), viewId, loopNo, celNo, priority); - return NULL_REG; -} - -reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv) { - reg_t viewObj = argv[0]; - - g_sci->_gfxFrameout->kernelDeleteScreenItem(viewObj); - - /* - reg_t viewObj = argv[0]; - uint16 viewId = readSelectorValue(s->_segMan, viewObj, SELECTOR(view)); - int16 loopNo = readSelectorValue(s->_segMan, viewObj, SELECTOR(loop)); - int16 celNo = readSelectorValue(s->_segMan, viewObj, SELECTOR(cel)); - //int16 leftPos = 0; - //int16 topPos = 0; - int16 priority = readSelectorValue(s->_segMan, viewObj, SELECTOR(priority)); - //int16 control = 0; - */ - - // TODO - - //warning("kDeleteScreenItem, view %d, loop %d, cel %d, pri %d", viewId, loopNo, celNo, priority); - return NULL_REG; -} - -reg_t kAddPlane(EngineState *s, int argc, reg_t *argv) { - reg_t planeObj = argv[0]; - - g_sci->_gfxFrameout->kernelAddPlane(planeObj); - warning("kAddPlane object %04x:%04x", PRINT_REG(planeObj)); - return NULL_REG; -} - -reg_t kDeletePlane(EngineState *s, int argc, reg_t *argv) { - reg_t planeObj = argv[0]; - - g_sci->_gfxFrameout->kernelDeletePlane(planeObj); - warning("kDeletePlane object %04x:%04x", PRINT_REG(planeObj)); - return NULL_REG; -} - -reg_t kUpdatePlane(EngineState *s, int argc, reg_t *argv) { - reg_t planeObj = argv[0]; - - g_sci->_gfxFrameout->kernelUpdatePlane(planeObj); - return s->r_acc; -} - -reg_t kRepaintPlane(EngineState *s, int argc, reg_t *argv) { - reg_t picObj = argv[0]; - - // TODO - - warning("kRepaintPlane object %04x:%04x", PRINT_REG(picObj)); - return NULL_REG; -} - -reg_t kGetHighPlanePri(EngineState *s, int argc, reg_t *argv) { - warning("kGetHighPlanePri: %d", g_sci->_gfxFrameout->kernelGetHighPlanePri()); - return make_reg(0, g_sci->_gfxFrameout->kernelGetHighPlanePri()); -} - -reg_t kFrameOut(EngineState *s, int argc, reg_t *argv) { - // This kernel call likely seems to be doing the screen updates, - // as its called right after a view is updated - - // TODO - g_sci->_gfxFrameout->kernelFrameout(); - - return NULL_REG; -} - -reg_t kOnMe(EngineState *s, int argc, reg_t *argv) { - // Tests if the cursor is on the passed object - - uint16 x = argv[0].toUint16(); - uint16 y = argv[1].toUint16(); - reg_t targetObject = argv[2]; - // TODO: argv[3] - it's usually 0 - Common::Rect nsRect; - - // Get the bounding rectangle of the object - nsRect.left = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsLeft)); - nsRect.top = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsTop)); - nsRect.right = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsRight)); - nsRect.bottom = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsBottom)); - uint16 itemX = readSelectorValue(s->_segMan, targetObject, SELECTOR(x)); - uint16 itemY = readSelectorValue(s->_segMan, targetObject, SELECTOR(y)); - - // If top and left are negative, we need to adjust coordinates by - // the item's x and y (e.g. happens in GK1, day 1, with detective - // Mosely's hotspot in his office) - - if (nsRect.left < 0) - nsRect.translate(itemX, 0); - - if (nsRect.top < 0) - nsRect.translate(0, itemY); - - // HACK: nsLeft and nsTop can be invalid, so try and fix them here - // using x and y (e.g. with the inventory screen in GK1) - if (nsRect.left == itemY && nsRect.top == itemX) { - // Swap the values, as they're inversed (eh???) - nsRect.left = itemX; - nsRect.top = itemY; - } - - /* - warning("kOnMe: (%d, %d) on object %04x:%04x (%s), rect (%d, %d, %d, %d), parameter %d", - argv[0].toUint16(), argv[1].toUint16(), PRINT_REG(argv[2]), s->_segMan->getObjectName(argv[2]), - nsRect.left, nsRect.top, nsRect.right, nsRect.bottom, - argv[3].toUint16()); - */ - - return make_reg(0, nsRect.contains(x, y)); -} - -reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv) { - // Tests if the cursor is on the passed object, after adjusting the - // coordinates of the object according to the object's plane - - uint16 x = argv[0].toUint16(); - uint16 y = argv[1].toUint16(); - reg_t targetObject = argv[2]; - // TODO: argv[3] - it's usually 0 - Common::Rect nsRect; - - // Get the bounding rectangle of the object - nsRect.left = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsLeft)); - nsRect.top = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsTop)); - nsRect.right = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsRight)); - nsRect.bottom = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsBottom)); - - // Get the object's plane - reg_t planeObject = readSelector(s->_segMan, targetObject, SELECTOR(plane)); - if (!planeObject.isNull()) { - uint16 itemX = readSelectorValue(s->_segMan, targetObject, SELECTOR(x)); - uint16 itemY = readSelectorValue(s->_segMan, targetObject, SELECTOR(y)); - uint16 planeResY = readSelectorValue(s->_segMan, planeObject, SELECTOR(resY)); - uint16 planeResX = readSelectorValue(s->_segMan, planeObject, SELECTOR(resX)); - uint16 planeTop = readSelectorValue(s->_segMan, planeObject, SELECTOR(top)); - uint16 planeLeft = readSelectorValue(s->_segMan, planeObject, SELECTOR(left)); - planeTop = (planeTop * g_sci->_gfxScreen->getHeight()) / planeResY; - planeLeft = (planeLeft * g_sci->_gfxScreen->getWidth()) / planeResX; - - // Adjust the bounding rectangle of the object by the object's - // actual X, Y coordinates - itemY = ((itemY * g_sci->_gfxScreen->getHeight()) / planeResY); - itemX = ((itemX * g_sci->_gfxScreen->getWidth()) / planeResX); - itemY += planeTop; - itemX += planeLeft; - - nsRect.translate(itemX, itemY); - } - - //warning("kIsOnMe: (%d, %d) on object %04x:%04x, parameter %d", argv[0].toUint16(), argv[1].toUint16(), PRINT_REG(argv[2]), argv[3].toUint16()); - - return make_reg(0, nsRect.contains(x, y)); -} - -reg_t kInPolygon(EngineState *s, int argc, reg_t *argv) { - // kAvoidPath already implements this - return kAvoidPath(s, argc, argv); -} - -reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) { - // TODO: argument 0 is usually 0, and arguments 1 and 2 are usually 1 - switch (argv[0].toUint16()) { - case 0: { - if (argc != 4) { - warning("kCreateTextBitmap(0): expected 4 arguments, got %i", argc); - return NULL_REG; - } - reg_t object = argv[3]; - Common::String text = s->_segMan->getString(readSelector(s->_segMan, object, SELECTOR(text))); - debug("kCreateTextBitmap: %s", text.c_str()); - } - default: - warning("CreateTextBitmap(%d)", argv[0].toUint16()); - } - - return NULL_REG; -} - -reg_t kCD(EngineState *s, int argc, reg_t *argv) { - // TODO: Stub - switch (argv[0].toUint16()) { - case 0: - // Return whether the contents of disc argv[1] is available. - return TRUE_REG; - default: - warning("CD(%d)", argv[0].toUint16()); - } - - return NULL_REG; -} - -} // End of namespace Sci - -#endif // ENABLE_SCI32 diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h new file mode 100644 index 0000000000..886e918fd8 --- /dev/null +++ b/engines/sci/engine/kernel_tables.h @@ -0,0 +1,1030 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef SCI_ENGINE_KERNEL_TABLES_H +#define SCI_ENGINE_KERNEL_TABLES_H + +#include "sci/engine/workarounds.h" + +namespace Sci { + +// [io] -> either integer or object +// (io) -> optionally integer AND an object +// (i) -> optional integer +// . -> any type +// i* -> optional multiple integers +// .* -> any parameters afterwards (or none) + +struct SciKernelMapSubEntry { + SciVersion fromVersion; + SciVersion toVersion; + + uint16 id; + + const char *name; + KernelFunctionCall *function; + + const char *signature; + const SciWorkaroundEntry *workarounds; +}; + +#define SCI_SUBOPENTRY_TERMINATOR { SCI_VERSION_NONE, SCI_VERSION_NONE, 0, NULL, NULL, NULL, NULL } + + +#define SIG_SCIALL SCI_VERSION_NONE, SCI_VERSION_NONE +#define SIG_SCI0 SCI_VERSION_NONE, SCI_VERSION_01 +#define SIG_SCI1 SCI_VERSION_1_EGA, SCI_VERSION_1_LATE +#define SIG_SCI11 SCI_VERSION_1_1, SCI_VERSION_1_1 +#define SIG_SINCE_SCI11 SCI_VERSION_1_1, SCI_VERSION_NONE +#define SIG_SCI21 SCI_VERSION_2_1, SCI_VERSION_2_1 + +#define SIG_SCI16 SCI_VERSION_NONE, SCI_VERSION_1_1 +#define SIG_SCI32 SCI_VERSION_2, SCI_VERSION_NONE + +// SCI-Sound-Version +#define SIG_SOUNDSCI0 SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE +#define SIG_SOUNDSCI1EARLY SCI_VERSION_1_EARLY, SCI_VERSION_1_EARLY +#define SIG_SOUNDSCI1LATE SCI_VERSION_1_LATE, SCI_VERSION_1_LATE +#define SIG_SOUNDSCI21 SCI_VERSION_2_1, SCI_VERSION_2_1 + +#define SIGFOR_ALL 0x3f +#define SIGFOR_DOS 1 << 0 +#define SIGFOR_PC98 1 << 1 +#define SIGFOR_WIN 1 << 2 +#define SIGFOR_MAC 1 << 3 +#define SIGFOR_AMIGA 1 << 4 +#define SIGFOR_ATARI 1 << 5 +#define SIGFOR_PC SIGFOR_DOS|SIGFOR_WIN + +#define SIG_EVERYWHERE SIG_SCIALL, SIGFOR_ALL + +#define MAP_CALL(_name_) #_name_, k##_name_ + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kDoSound_subops[] = { + { SIG_SOUNDSCI0, 0, MAP_CALL(DoSoundInit), "o", NULL }, + { SIG_SOUNDSCI0, 1, MAP_CALL(DoSoundPlay), "o", NULL }, + { SIG_SOUNDSCI0, 2, MAP_CALL(DoSoundDummy), "(o)", NULL }, + { SIG_SOUNDSCI0, 3, MAP_CALL(DoSoundDispose), "o", NULL }, + { SIG_SOUNDSCI0, 4, MAP_CALL(DoSoundMute), "(i)", NULL }, + { SIG_SOUNDSCI0, 5, MAP_CALL(DoSoundStop), "o", NULL }, + { SIG_SOUNDSCI0, 6, MAP_CALL(DoSoundPause), "i", NULL }, + { SIG_SOUNDSCI0, 7, MAP_CALL(DoSoundResumeAfterRestore), "", NULL }, + { SIG_SOUNDSCI0, 8, MAP_CALL(DoSoundMasterVolume), "(i)", NULL }, + { SIG_SOUNDSCI0, 9, MAP_CALL(DoSoundUpdate), "o", NULL }, + { SIG_SOUNDSCI0, 10, MAP_CALL(DoSoundFade), "o", kDoSoundFade_workarounds }, + { SIG_SOUNDSCI0, 11, MAP_CALL(DoSoundGetPolyphony), "", NULL }, + { SIG_SOUNDSCI0, 12, MAP_CALL(DoSoundStopAll), "", NULL }, + { SIG_SOUNDSCI1EARLY, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL }, + { SIG_SOUNDSCI1EARLY, 1, MAP_CALL(DoSoundMute), NULL, NULL }, + { SIG_SOUNDSCI1EARLY, 2, MAP_CALL(DoSoundDummy), NULL, NULL }, + { SIG_SOUNDSCI1EARLY, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL }, + { SIG_SOUNDSCI1EARLY, 4, MAP_CALL(DoSoundUpdate), NULL, NULL }, + { SIG_SOUNDSCI1EARLY, 5, MAP_CALL(DoSoundInit), NULL, NULL }, + { SIG_SOUNDSCI1EARLY, 6, MAP_CALL(DoSoundDispose), NULL, NULL }, + { SIG_SOUNDSCI1EARLY, 7, MAP_CALL(DoSoundPlay), "oi", NULL }, + // ^^ TODO: In SCI1-SCI1.1 DoSound (play) is called by 2 methods of the Sound object: play and + // playBed. The methods are the same, apart from the second integer parameter: it's 0 in + // play and 1 in playBed, to distinguish the caller. It's passed on, we should find out what + // it actually does internally + { SIG_SOUNDSCI1EARLY, 8, MAP_CALL(DoSoundStop), NULL, NULL }, + { SIG_SOUNDSCI1EARLY, 9, MAP_CALL(DoSoundPause), "[o0]i", NULL }, + { SIG_SOUNDSCI1EARLY, 10, MAP_CALL(DoSoundFade), "oiiii", NULL }, + { SIG_SOUNDSCI1EARLY, 11, MAP_CALL(DoSoundUpdateCues), "o", NULL }, + { SIG_SOUNDSCI1EARLY, 12, MAP_CALL(DoSoundSendMidi), "oiii", NULL }, + { SIG_SOUNDSCI1EARLY, 13, MAP_CALL(DoSoundReverb), "i", NULL }, + { SIG_SOUNDSCI1EARLY, 14, MAP_CALL(DoSoundSetHold), "oi", NULL }, + { SIG_SOUNDSCI1EARLY, 15, MAP_CALL(DoSoundDummy), "", NULL }, + // ^^ Longbow demo + { SIG_SOUNDSCI1LATE, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 1, MAP_CALL(DoSoundMute), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 2, MAP_CALL(DoSoundDummy), "", NULL }, + { SIG_SOUNDSCI1LATE, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 4, MAP_CALL(DoSoundGetAudioCapability), "", NULL }, + { SIG_SOUNDSCI1LATE, 5, MAP_CALL(DoSoundSuspend), "i", NULL }, + { SIG_SOUNDSCI1LATE, 6, MAP_CALL(DoSoundInit), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 7, MAP_CALL(DoSoundDispose), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 8, MAP_CALL(DoSoundPlay), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 9, MAP_CALL(DoSoundStop), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 10, MAP_CALL(DoSoundPause), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 11, MAP_CALL(DoSoundFade), "oiiii(i)", kDoSoundFade_workarounds }, + { SIG_SOUNDSCI1LATE, 12, MAP_CALL(DoSoundSetHold), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 13, MAP_CALL(DoSoundDummy), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 14, MAP_CALL(DoSoundSetVolume), "oi", NULL }, + { SIG_SOUNDSCI1LATE, 15, MAP_CALL(DoSoundSetPriority), "oi", NULL }, + { SIG_SOUNDSCI1LATE, 16, MAP_CALL(DoSoundSetLoop), "oi", NULL }, + { SIG_SOUNDSCI1LATE, 17, MAP_CALL(DoSoundUpdateCues), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 18, MAP_CALL(DoSoundSendMidi), "oiii(i)", NULL }, + { SIG_SOUNDSCI1LATE, 19, MAP_CALL(DoSoundReverb), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 20, MAP_CALL(DoSoundUpdate), NULL, NULL }, +#ifdef ENABLE_SCI32 + { SIG_SOUNDSCI21, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL }, + { SIG_SOUNDSCI21, 1, MAP_CALL(DoSoundMute), NULL, NULL }, + { SIG_SOUNDSCI21, 2, MAP_CALL(DoSoundDummy), NULL, NULL }, + { SIG_SOUNDSCI21, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL }, + { SIG_SOUNDSCI21, 4, MAP_CALL(DoSoundGetAudioCapability), NULL, NULL }, + { SIG_SOUNDSCI21, 5, MAP_CALL(DoSoundSuspend), NULL, NULL }, + { SIG_SOUNDSCI21, 6, MAP_CALL(DoSoundInit), NULL, NULL }, + { SIG_SOUNDSCI21, 7, MAP_CALL(DoSoundDispose), NULL, NULL }, + { SIG_SOUNDSCI21, 8, MAP_CALL(DoSoundPlay), "o(i)", NULL }, + // ^^ TODO: if this is really the only change between SCI1LATE AND SCI21, we could rename the + // SIG_SOUNDSCI1LATE #define to SIG_SINCE_SOUNDSCI1LATE and make it being SCI1LATE+. Although + // I guess there are many more changes somewhere + // TODO: Quest for Glory 4 (SCI2.1) uses the old scheme, we need to detect it accordingly + // signature for SCI21 should be "o" + { SIG_SOUNDSCI21, 9, MAP_CALL(DoSoundStop), NULL, NULL }, + { SIG_SOUNDSCI21, 10, MAP_CALL(DoSoundPause), NULL, NULL }, + { SIG_SOUNDSCI21, 11, MAP_CALL(DoSoundFade), NULL, NULL }, + { SIG_SOUNDSCI21, 12, MAP_CALL(DoSoundSetHold), NULL, NULL }, + { SIG_SOUNDSCI21, 13, MAP_CALL(DoSoundDummy), NULL, NULL }, + { SIG_SOUNDSCI21, 14, MAP_CALL(DoSoundSetVolume), NULL, NULL }, + { SIG_SOUNDSCI21, 15, MAP_CALL(DoSoundSetPriority), NULL, NULL }, + { SIG_SOUNDSCI21, 16, MAP_CALL(DoSoundSetLoop), NULL, NULL }, + { SIG_SOUNDSCI21, 17, MAP_CALL(DoSoundUpdateCues), NULL, NULL }, + { SIG_SOUNDSCI21, 18, MAP_CALL(DoSoundSendMidi), NULL, NULL }, + { SIG_SOUNDSCI21, 19, MAP_CALL(DoSoundReverb), NULL, NULL }, + { SIG_SOUNDSCI21, 20, MAP_CALL(DoSoundUpdate), NULL, NULL }, +#endif + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kGraph_subops[] = { + { SIG_SCI32, 1, MAP_CALL(StubNull), "", NULL }, // called by gk1 sci32 right at the start + { SIG_SCIALL, 2, MAP_CALL(GraphGetColorCount), "", NULL }, + // 3 - set palette via resource + { SIG_SCIALL, 4, MAP_CALL(GraphDrawLine), "iiiii(i)(i)", kGraphDrawLine_workarounds }, + // 5 - nop + // 6 - draw pattern + { SIG_SCIALL, 7, MAP_CALL(GraphSaveBox), "iiiii", kGraphSaveBox_workarounds }, + { SIG_SCIALL, 8, MAP_CALL(GraphRestoreBox), "[r0!]", kGraphRestoreBox_workarounds }, + // ^ this may get called with invalid references, we check them within restoreBits() and sierra sci behaves the same + { SIG_SCIALL, 9, MAP_CALL(GraphFillBoxBackground), "iiii", NULL }, + { SIG_SCIALL, 10, MAP_CALL(GraphFillBoxForeground), "iiii", kGraphFillBoxForeground_workarounds }, + { SIG_SCIALL, 11, MAP_CALL(GraphFillBoxAny), "iiiiii(i)(i)", kGraphFillBoxAny_workarounds }, + { SIG_SCI11, 12, MAP_CALL(GraphUpdateBox), "iiii(i)(r0)", NULL }, // kq6 hires + { SIG_SCIALL, 12, MAP_CALL(GraphUpdateBox), "iiii(i)", NULL }, + { SIG_SCIALL, 13, MAP_CALL(GraphRedrawBox), "iiii", kGraphRedrawBox_workarounds }, + { SIG_SCIALL, 14, MAP_CALL(GraphAdjustPriority), "ii", NULL }, + { SIG_SCI11, 15, MAP_CALL(GraphSaveUpscaledHiresBox), "iiii", NULL }, // kq6 hires + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kPalVary_subops[] = { + { SIG_SCI21, 0, MAP_CALL(PalVaryInit), "ii(i)(i)(i)", NULL }, + { SIG_SCIALL, 0, MAP_CALL(PalVaryInit), "ii(i)(i)", NULL }, + { SIG_SCIALL, 1, MAP_CALL(PalVaryReverse), "(i)(i)(i)", NULL }, + { SIG_SCIALL, 2, MAP_CALL(PalVaryGetCurrentStep), "", NULL }, + { SIG_SCIALL, 3, MAP_CALL(PalVaryDeinit), "", NULL }, + { SIG_SCIALL, 4, MAP_CALL(PalVaryChangeTarget), "i", NULL }, + { SIG_SCIALL, 5, MAP_CALL(PalVaryChangeTicks), "i", NULL }, + { SIG_SCIALL, 6, MAP_CALL(PalVaryPauseResume), "i", NULL }, + { SIG_SCI32, 8, MAP_CALL(PalVaryUnknown), "i", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kPalette_subops[] = { + { SIG_SCIALL, 1, MAP_CALL(PaletteSetFromResource), "i(i)", NULL }, + { SIG_SCIALL, 2, MAP_CALL(PaletteSetFlag), "iii", NULL }, + { SIG_SCIALL, 3, MAP_CALL(PaletteUnsetFlag), "iii", kPaletteUnsetFlag_workarounds }, + { SIG_SCIALL, 4, MAP_CALL(PaletteSetIntensity), "iii(i)", NULL }, + { SIG_SCIALL, 5, MAP_CALL(PaletteFindColor), "iii", NULL }, + { SIG_SCIALL, 6, MAP_CALL(PaletteAnimate), "i*", NULL }, + { SIG_SCIALL, 7, MAP_CALL(PaletteSave), "", NULL }, + { SIG_SCIALL, 8, MAP_CALL(PaletteRestore), "[r0]", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +static const SciKernelMapSubEntry kFileIO_subops[] = { + { SIG_SCI32, 0, MAP_CALL(FileIOOpen), "r(i)", NULL }, + { SIG_SCIALL, 0, MAP_CALL(FileIOOpen), "ri", NULL }, + { SIG_SCIALL, 1, MAP_CALL(FileIOClose), "i", NULL }, + { SIG_SCIALL, 2, MAP_CALL(FileIOReadRaw), "iri", NULL }, + { SIG_SCIALL, 3, MAP_CALL(FileIOWriteRaw), "iri", NULL }, + { SIG_SCIALL, 4, MAP_CALL(FileIOUnlink), "r", NULL }, + { SIG_SCIALL, 5, MAP_CALL(FileIOReadString), "rii", NULL }, + { SIG_SCIALL, 6, MAP_CALL(FileIOWriteString), "ir", NULL }, + { SIG_SCIALL, 7, MAP_CALL(FileIOSeek), "iii", NULL }, + { SIG_SCIALL, 8, MAP_CALL(FileIOFindFirst), "rri", NULL }, + { SIG_SCIALL, 9, MAP_CALL(FileIOFindNext), "r", NULL }, + { SIG_SCIALL, 10, MAP_CALL(FileIOExists), "r", NULL }, + { SIG_SINCE_SCI11, 11, MAP_CALL(FileIORename), "rr", NULL }, +#ifdef ENABLE_SCI32 + { SIG_SCI32, 13, MAP_CALL(FileIOReadByte), "i", NULL }, + { SIG_SCI32, 14, MAP_CALL(FileIOWriteByte), "ii", NULL }, + { SIG_SCI32, 15, MAP_CALL(FileIOReadWord), "i", NULL }, + { SIG_SCI32, 16, MAP_CALL(FileIOWriteWord), "ii", NULL }, + { SIG_SCI32, 19, MAP_CALL(Stub), "r", NULL }, // for Torin / Torin demo +#endif + SCI_SUBOPENTRY_TERMINATOR +}; + +#ifdef ENABLE_SCI32 +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kList_subops[] = { + { SIG_SCI21, 0, MAP_CALL(NewList), "", NULL }, + { SIG_SCI21, 1, MAP_CALL(DisposeList), "l", NULL }, + { SIG_SCI21, 2, MAP_CALL(NewNode), ".", NULL }, + { SIG_SCI21, 3, MAP_CALL(FirstNode), "[l0]", NULL }, + { SIG_SCI21, 4, MAP_CALL(LastNode), "l", NULL }, + { SIG_SCI21, 5, MAP_CALL(EmptyList), "l", NULL }, + { SIG_SCI21, 6, MAP_CALL(NextNode), "n", NULL }, + { SIG_SCI21, 7, MAP_CALL(PrevNode), "n", NULL }, + { SIG_SCI21, 8, MAP_CALL(NodeValue), "[n0]", NULL }, + { SIG_SCI21, 9, MAP_CALL(AddAfter), "lnn.", NULL }, + { SIG_SCI21, 10, MAP_CALL(AddToFront), "ln.", NULL }, + { SIG_SCI21, 11, MAP_CALL(AddToEnd), "ln.", NULL }, + { SIG_SCI21, 12, MAP_CALL(AddBefore), "ln.", NULL }, + { SIG_SCI21, 13, MAP_CALL(MoveToFront), "ln", NULL }, + { SIG_SCI21, 14, MAP_CALL(MoveToEnd), "ln", NULL }, + { SIG_SCI21, 15, MAP_CALL(FindKey), "l.", NULL }, + { SIG_SCI21, 16, MAP_CALL(DeleteKey), "l.", NULL }, + { SIG_SCI21, 17, MAP_CALL(ListAt), "li", NULL }, + // FIXME: This doesn't seem to be ListIndexOf. In Torin demo, an index is + // passed as a second parameter instead of an object. Thus, it seems to + // be something like ListAt instead... If we swap the two subops though, + // Torin demo crashes complaining that it tried to send to a non-object, + // therefore the semantics might be different here (signature was l[o0]) + // In SQ6 object is passed right when skipping the intro + { SIG_SCI21, 18, MAP_CALL(StubNull), "l[io]", NULL }, + { SIG_SCI21, 19, MAP_CALL(ListEachElementDo), "li(.*)", NULL }, + { SIG_SCI21, 20, MAP_CALL(ListFirstTrue), "li(.*)", NULL }, + { SIG_SCI21, 21, MAP_CALL(ListAllTrue), "li(.*)", NULL }, + { SIG_SCI21, 22, MAP_CALL(Sort), "ooo", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; +#endif + +struct SciKernelMapEntry { + const char *name; + KernelFunctionCall *function; + + SciVersion fromVersion; + SciVersion toVersion; + byte forPlatform; + + const char *signature; + const SciKernelMapSubEntry *subFunctions; + const SciWorkaroundEntry *workarounds; +}; + +// name, version/platform, signature, sub-signatures, workarounds +static SciKernelMapEntry s_kernelMap[] = { + { MAP_CALL(Abs), SIG_EVERYWHERE, "i", NULL, kAbs_workarounds }, + { MAP_CALL(AddAfter), SIG_EVERYWHERE, "lnn", NULL, NULL }, + { MAP_CALL(AddMenu), SIG_EVERYWHERE, "rr", NULL, NULL }, + { MAP_CALL(AddToEnd), SIG_EVERYWHERE, "ln", NULL, NULL }, + { MAP_CALL(AddToFront), SIG_EVERYWHERE, "ln", NULL, NULL }, + { MAP_CALL(AddToPic), SIG_EVERYWHERE, "[il](iiiiii)", NULL, NULL }, + { MAP_CALL(Animate), SIG_EVERYWHERE, "(l0)(i)", NULL, NULL }, + { MAP_CALL(AssertPalette), SIG_EVERYWHERE, "i", NULL, NULL }, + { MAP_CALL(AvoidPath), SIG_EVERYWHERE, "ii(.*)", NULL, NULL }, + { MAP_CALL(BaseSetter), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(CanBeHere), SIG_EVERYWHERE, "o(l)", NULL, NULL }, +#ifdef ENABLE_SCI32 + { "CantBeHere", kCantBeHere32, SIG_SCI32, SIGFOR_ALL, "ol", NULL, NULL }, +#endif + { MAP_CALL(CantBeHere), SIG_EVERYWHERE, "o(l)", NULL, NULL }, + { MAP_CALL(CelHigh), SIG_EVERYWHERE, "ii(i)", NULL, kCelHigh_workarounds }, + { MAP_CALL(CelWide), SIG_EVERYWHERE, "ii(i)", NULL, kCelWide_workarounds }, + { MAP_CALL(CheckFreeSpace), SIG_SCI32, SIGFOR_ALL, "r.*", NULL, NULL }, + { MAP_CALL(CheckFreeSpace), SIG_SCI11, SIGFOR_ALL, "r(i)", NULL, NULL }, + { MAP_CALL(CheckFreeSpace), SIG_EVERYWHERE, "r", NULL, NULL }, + { MAP_CALL(CheckSaveGame), SIG_EVERYWHERE, ".*", NULL, NULL }, + { MAP_CALL(Clone), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(CoordPri), SIG_EVERYWHERE, "i(i)", NULL, NULL }, + { MAP_CALL(CosDiv), SIG_EVERYWHERE, "ii", NULL, NULL }, + { MAP_CALL(DeleteKey), SIG_EVERYWHERE, "l.", NULL, NULL }, + { MAP_CALL(DeviceInfo), SIG_EVERYWHERE, "i(r)(r)(i)", NULL, NULL }, // subop + { MAP_CALL(Display), SIG_EVERYWHERE, "[ir]([ir!]*)", NULL, NULL }, + // ^ we allow invalid references here, because kDisplay gets called with those in e.g. pq3 during intro + // restoreBits() checks and skips invalid handles, so that's fine. Sierra SCI behaved the same + { MAP_CALL(DirLoop), SIG_EVERYWHERE, "oi", NULL, NULL }, + { MAP_CALL(DisposeClone), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(DisposeList), SIG_EVERYWHERE, "l", NULL, NULL }, + { MAP_CALL(DisposeScript), SIG_EVERYWHERE, "i(i*)", NULL, kDisposeScript_workarounds }, + { MAP_CALL(DisposeWindow), SIG_EVERYWHERE, "i(i)", NULL, NULL }, + { MAP_CALL(DoAudio), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop + { MAP_CALL(DoAvoider), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(DoBresen), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(DoSound), SIG_EVERYWHERE, "i(.*)", kDoSound_subops, NULL }, + { MAP_CALL(DoSync), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop + { MAP_CALL(DrawCel), SIG_SCI11, SIGFOR_PC, "iiiii(i)(i)([ri])", NULL, NULL }, // reference for kq6 hires + { MAP_CALL(DrawCel), SIG_EVERYWHERE, "iiiii(i)(i)", NULL, NULL }, + { MAP_CALL(DrawControl), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(DrawMenuBar), SIG_EVERYWHERE, "i", NULL, NULL }, + { MAP_CALL(DrawPic), SIG_EVERYWHERE, "i(i)(i)(i)", NULL, NULL }, + { MAP_CALL(DrawStatus), SIG_EVERYWHERE, "[r0](i)(i)", NULL, NULL }, + { MAP_CALL(EditControl), SIG_EVERYWHERE, "[o0][o0]", NULL, NULL }, + { MAP_CALL(Empty), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(EmptyList), SIG_EVERYWHERE, "l", NULL, NULL }, + { MAP_CALL(FClose), SIG_EVERYWHERE, "i", NULL, NULL }, + { MAP_CALL(FGets), SIG_EVERYWHERE, "rii", NULL, NULL }, + { MAP_CALL(FOpen), SIG_EVERYWHERE, "ri", NULL, NULL }, + { MAP_CALL(FPuts), SIG_EVERYWHERE, "ir", NULL, NULL }, + { MAP_CALL(FileIO), SIG_EVERYWHERE, "i(.*)", kFileIO_subops, NULL }, + { MAP_CALL(FindKey), SIG_EVERYWHERE, "l.", NULL, kFindKey_workarounds }, + { MAP_CALL(FirstNode), SIG_EVERYWHERE, "[l0]", NULL, NULL }, + { MAP_CALL(FlushResources), SIG_EVERYWHERE, "i", NULL, NULL }, + { MAP_CALL(Format), SIG_EVERYWHERE, "r(.*)", NULL, NULL }, + { MAP_CALL(GameIsRestarting), SIG_EVERYWHERE, "(i)", NULL, NULL }, + { MAP_CALL(GetAngle), SIG_EVERYWHERE, "iiii", NULL, kGetAngle_workarounds }, + { MAP_CALL(GetCWD), SIG_EVERYWHERE, "r", NULL, NULL }, + { MAP_CALL(GetDistance), SIG_EVERYWHERE, "ii(i)(i)(i)(i)", NULL, NULL }, + { MAP_CALL(GetEvent), SIG_SCIALL, SIGFOR_MAC, "io(i*)", NULL, NULL }, + { MAP_CALL(GetEvent), SIG_EVERYWHERE, "io", NULL, NULL }, + { MAP_CALL(GetFarText), SIG_EVERYWHERE, "ii[r0]", NULL, NULL }, + { MAP_CALL(GetMenu), SIG_EVERYWHERE, "i.", NULL, NULL }, + { MAP_CALL(GetMessage), SIG_EVERYWHERE, "iiir", NULL, NULL }, + { MAP_CALL(GetPort), SIG_EVERYWHERE, "", NULL, NULL }, + { MAP_CALL(GetSaveDir), SIG_SCI32, SIGFOR_ALL, "(r*)", NULL, NULL }, + { MAP_CALL(GetSaveDir), SIG_EVERYWHERE, "", NULL, NULL }, + { MAP_CALL(GetSaveFiles), SIG_EVERYWHERE, "rrr", NULL, NULL }, + { MAP_CALL(GetTime), SIG_EVERYWHERE, "(i)", NULL, NULL }, + { MAP_CALL(GlobalToLocal), SIG_SCI32, SIGFOR_ALL, "oo", NULL, NULL }, + { MAP_CALL(GlobalToLocal), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(Graph), SIG_EVERYWHERE, NULL, kGraph_subops, NULL }, + { MAP_CALL(HaveMouse), SIG_EVERYWHERE, "", NULL, NULL }, + { MAP_CALL(HiliteControl), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(InitBresen), SIG_EVERYWHERE, "o(i)", NULL, NULL }, + { MAP_CALL(Intersections), SIG_EVERYWHERE, "iiiiriiiri", NULL, NULL }, + { MAP_CALL(IsItSkip), SIG_EVERYWHERE, "iiiii", NULL, NULL }, + { MAP_CALL(IsObject), SIG_EVERYWHERE, ".", NULL, kIsObject_workarounds }, + { MAP_CALL(Joystick), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop + { MAP_CALL(LastNode), SIG_EVERYWHERE, "l", NULL, NULL }, + { MAP_CALL(Load), SIG_EVERYWHERE, "ii(i*)", NULL, NULL }, + { MAP_CALL(LocalToGlobal), SIG_SCI32, SIGFOR_ALL, "oo", NULL, NULL }, + { MAP_CALL(LocalToGlobal), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(Lock), SIG_EVERYWHERE, "ii(i)", NULL, NULL }, + { MAP_CALL(MapKeyToDir), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(Memory), SIG_EVERYWHERE, "i(.*)", NULL, kMemory_workarounds }, // subop + { MAP_CALL(MemoryInfo), SIG_EVERYWHERE, "i", NULL, NULL }, + { MAP_CALL(MemorySegment), SIG_EVERYWHERE, "ir(i)", NULL, NULL }, // subop + { MAP_CALL(MenuSelect), SIG_EVERYWHERE, "o(i)", NULL, NULL }, + { MAP_CALL(MergePoly), SIG_EVERYWHERE, "rli", NULL, NULL }, + { MAP_CALL(Message), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop + { MAP_CALL(MoveCursor), SIG_EVERYWHERE, "ii", NULL, NULL }, + { MAP_CALL(NewList), SIG_EVERYWHERE, "", NULL, NULL }, + { MAP_CALL(NewNode), SIG_EVERYWHERE, "..", NULL, NULL }, + { MAP_CALL(NewWindow), SIG_SCIALL, SIGFOR_MAC, ".*", NULL, NULL }, + { MAP_CALL(NewWindow), SIG_SCI0, SIGFOR_ALL, "iiii[r0]i(i)(i)(i)", NULL, NULL }, + { MAP_CALL(NewWindow), SIG_SCI1, SIGFOR_ALL, "iiii[ir]i(i)(i)([ir])(i)(i)(i)(i)", NULL, NULL }, + { MAP_CALL(NewWindow), SIG_SCI11, SIGFOR_ALL, "iiiiiiii[r0]i(i)(i)(i)", NULL, kNewWindow_workarounds }, + { MAP_CALL(NextNode), SIG_EVERYWHERE, "n", NULL, NULL }, + { MAP_CALL(NodeValue), SIG_EVERYWHERE, "[n0]", NULL, NULL }, + { MAP_CALL(NumCels), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(NumLoops), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(OnControl), SIG_EVERYWHERE, "ii(i)(i)(i)", NULL, NULL }, + { MAP_CALL(PalVary), SIG_EVERYWHERE, "i(i*)", kPalVary_subops, NULL }, + { MAP_CALL(Palette), SIG_EVERYWHERE, "i(.*)", kPalette_subops, NULL }, + { MAP_CALL(Parse), SIG_EVERYWHERE, "ro", NULL, NULL }, + { MAP_CALL(PicNotValid), SIG_EVERYWHERE, "(i)", NULL, NULL }, + { MAP_CALL(Platform), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(Portrait), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop + { MAP_CALL(PrevNode), SIG_EVERYWHERE, "n", NULL, NULL }, + { MAP_CALL(PriCoord), SIG_EVERYWHERE, "i", NULL, NULL }, + { MAP_CALL(Random), SIG_EVERYWHERE, "i(i)(i)", NULL, NULL }, + { MAP_CALL(ReadNumber), SIG_EVERYWHERE, "r", NULL, NULL }, + { MAP_CALL(ResCheck), SIG_EVERYWHERE, "ii(iiii)", NULL, NULL }, + { MAP_CALL(RespondsTo), SIG_EVERYWHERE, ".i", NULL, NULL }, + { MAP_CALL(RestartGame), SIG_EVERYWHERE, "", NULL, NULL }, + { MAP_CALL(RestoreGame), SIG_EVERYWHERE, "rir", NULL, NULL }, + { MAP_CALL(Said), SIG_EVERYWHERE, "[r0]", NULL, NULL }, + { MAP_CALL(SaveGame), SIG_EVERYWHERE, "rir(r)", NULL, NULL }, + { MAP_CALL(ScriptID), SIG_EVERYWHERE, "[io](i)", NULL, NULL }, + { MAP_CALL(SetCursor), SIG_SCI21, SIGFOR_ALL, "i(i)([io])(i*)", NULL, NULL }, + // TODO: SCI2.1 may supply an object optionally (mother goose sci21 right on startup) - find out why + { MAP_CALL(SetCursor), SIG_EVERYWHERE, "i(i*)", NULL, NULL }, + { MAP_CALL(SetDebug), SIG_EVERYWHERE, "(i*)", NULL, NULL }, + { MAP_CALL(SetJump), SIG_EVERYWHERE, "oiii", NULL, NULL }, + { MAP_CALL(SetMenu), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, + { MAP_CALL(SetNowSeen), SIG_EVERYWHERE, "o(i)", NULL, NULL }, + { MAP_CALL(SetPort), SIG_EVERYWHERE, "i(iiiii)(i)", NULL, kSetPort_workarounds }, + { MAP_CALL(SetQuitStr), SIG_EVERYWHERE, "r", NULL, NULL }, + { MAP_CALL(SetSynonyms), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(SetVideoMode), SIG_EVERYWHERE, "i", NULL, NULL }, + { MAP_CALL(ShakeScreen), SIG_EVERYWHERE, "(i)(i)", NULL, NULL }, + { MAP_CALL(ShowMovie), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(SinDiv), SIG_EVERYWHERE, "ii", NULL, NULL }, + { MAP_CALL(Sort), SIG_EVERYWHERE, "ooo", NULL, NULL }, + { MAP_CALL(Sqrt), SIG_EVERYWHERE, "i", NULL, NULL }, + { MAP_CALL(StrAt), SIG_EVERYWHERE, "ri(i)", NULL, NULL }, + { MAP_CALL(StrCat), SIG_EVERYWHERE, "rr", NULL, NULL }, + { MAP_CALL(StrCmp), SIG_EVERYWHERE, "rr(i)", NULL, NULL }, + { MAP_CALL(StrCpy), SIG_EVERYWHERE, "r[r0](i)", NULL, NULL }, + { MAP_CALL(StrEnd), SIG_EVERYWHERE, "r", NULL, NULL }, + { MAP_CALL(StrLen), SIG_EVERYWHERE, "[r0]", NULL, NULL }, + { MAP_CALL(StrSplit), SIG_EVERYWHERE, "rr[r0]", NULL, NULL }, + { MAP_CALL(TextColors), SIG_EVERYWHERE, "(i*)", NULL, NULL }, + { MAP_CALL(TextFonts), SIG_EVERYWHERE, "(i*)", NULL, NULL }, + { MAP_CALL(TextSize), SIG_SCIALL, SIGFOR_MAC, "r[r0]i(i)(r0)(i)", NULL, NULL }, + { MAP_CALL(TextSize), SIG_EVERYWHERE, "r[r0]i(i)(r0)", NULL, NULL }, + { MAP_CALL(TimesCos), SIG_EVERYWHERE, "ii", NULL, NULL }, + { "CosMult", kTimesCos, SIG_EVERYWHERE, "ii", NULL, NULL }, + { MAP_CALL(TimesCot), SIG_EVERYWHERE, "ii", NULL, NULL }, + { MAP_CALL(TimesSin), SIG_EVERYWHERE, "ii", NULL, NULL }, + { "SinMult", kTimesSin, SIG_EVERYWHERE, "ii", NULL, NULL }, + { MAP_CALL(TimesTan), SIG_EVERYWHERE, "ii", NULL, NULL }, + { MAP_CALL(UnLoad), SIG_EVERYWHERE, "i[ri]", NULL, kUnLoad_workarounds }, + { MAP_CALL(ValidPath), SIG_EVERYWHERE, "r", NULL, NULL }, + { MAP_CALL(Wait), SIG_EVERYWHERE, "i", NULL, NULL }, + +#ifdef ENABLE_SCI32 + // SCI2 Kernel Functions + { MAP_CALL(AddPlane), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(AddScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(Array), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(CreateTextBitmap), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, + { MAP_CALL(DeletePlane), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(DeleteScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(FrameOut), SIG_EVERYWHERE, "", NULL, NULL }, + { MAP_CALL(GetHighPlanePri), SIG_EVERYWHERE, "", NULL, NULL }, + { MAP_CALL(InPolygon), SIG_EVERYWHERE, "iio", NULL, NULL }, + { MAP_CALL(IsHiRes), SIG_EVERYWHERE, "", NULL, NULL }, + { MAP_CALL(ListAllTrue), SIG_EVERYWHERE, "li(.*)", NULL, NULL }, + { MAP_CALL(ListAt), SIG_EVERYWHERE, "li", NULL, NULL }, + { MAP_CALL(ListEachElementDo), SIG_EVERYWHERE, "li(.*)", NULL, NULL }, + { MAP_CALL(ListFirstTrue), SIG_EVERYWHERE, "li(.*)", NULL, NULL }, + { MAP_CALL(ListIndexOf), SIG_EVERYWHERE, "l[o0]", NULL, NULL }, + { MAP_CALL(OnMe), SIG_EVERYWHERE, "iio(.*)", NULL, NULL }, + { MAP_CALL(RepaintPlane), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(String), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(UpdatePlane), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(UpdateScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, + + // SCI2.1 Kernel Functions + { MAP_CALL(CD), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(IsOnMe), SIG_EVERYWHERE, "iio(.*)", NULL, NULL }, + { MAP_CALL(List), SIG_SCI21, SIGFOR_ALL, "(.*)", kList_subops, NULL }, + { MAP_CALL(MulDiv), SIG_EVERYWHERE, "iii", NULL, NULL }, + { MAP_CALL(PlayVMD), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(Robot), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(Save), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(Text), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(AddPicAt), SIG_EVERYWHERE, "oiii", NULL, NULL }, + { NULL, NULL, SIG_EVERYWHERE, NULL, NULL, NULL } +#endif +}; + +/** Default kernel name table. */ +static const char *s_defaultKernelNames[] = { + /*0x00*/ "Load", + /*0x01*/ "UnLoad", + /*0x02*/ "ScriptID", + /*0x03*/ "DisposeScript", + /*0x04*/ "Clone", + /*0x05*/ "DisposeClone", + /*0x06*/ "IsObject", + /*0x07*/ "RespondsTo", + /*0x08*/ "DrawPic", + /*0x09*/ "Dummy", // Show + /*0x0a*/ "PicNotValid", + /*0x0b*/ "Animate", + /*0x0c*/ "SetNowSeen", + /*0x0d*/ "NumLoops", + /*0x0e*/ "NumCels", + /*0x0f*/ "CelWide", + /*0x10*/ "CelHigh", + /*0x11*/ "DrawCel", + /*0x12*/ "AddToPic", + /*0x13*/ "NewWindow", + /*0x14*/ "GetPort", + /*0x15*/ "SetPort", + /*0x16*/ "DisposeWindow", + /*0x17*/ "DrawControl", + /*0x18*/ "HiliteControl", + /*0x19*/ "EditControl", + /*0x1a*/ "TextSize", + /*0x1b*/ "Display", + /*0x1c*/ "GetEvent", + /*0x1d*/ "GlobalToLocal", + /*0x1e*/ "LocalToGlobal", + /*0x1f*/ "MapKeyToDir", + /*0x20*/ "DrawMenuBar", + /*0x21*/ "MenuSelect", + /*0x22*/ "AddMenu", + /*0x23*/ "DrawStatus", + /*0x24*/ "Parse", + /*0x25*/ "Said", + /*0x26*/ "SetSynonyms", // Portrait (KQ6 hires) + /*0x27*/ "HaveMouse", + /*0x28*/ "SetCursor", + // FOpen (SCI0) + // FPuts (SCI0) + // FGets (SCI0) + // FClose (SCI0) + /*0x29*/ "SaveGame", + /*0x2a*/ "RestoreGame", + /*0x2b*/ "RestartGame", + /*0x2c*/ "GameIsRestarting", + /*0x2d*/ "DoSound", + /*0x2e*/ "NewList", + /*0x2f*/ "DisposeList", + /*0x30*/ "NewNode", + /*0x31*/ "FirstNode", + /*0x32*/ "LastNode", + /*0x33*/ "EmptyList", + /*0x34*/ "NextNode", + /*0x35*/ "PrevNode", + /*0x36*/ "NodeValue", + /*0x37*/ "AddAfter", + /*0x38*/ "AddToFront", + /*0x39*/ "AddToEnd", + /*0x3a*/ "FindKey", + /*0x3b*/ "DeleteKey", + /*0x3c*/ "Random", + /*0x3d*/ "Abs", + /*0x3e*/ "Sqrt", + /*0x3f*/ "GetAngle", + /*0x40*/ "GetDistance", + /*0x41*/ "Wait", + /*0x42*/ "GetTime", + /*0x43*/ "StrEnd", + /*0x44*/ "StrCat", + /*0x45*/ "StrCmp", + /*0x46*/ "StrLen", + /*0x47*/ "StrCpy", + /*0x48*/ "Format", + /*0x49*/ "GetFarText", + /*0x4a*/ "ReadNumber", + /*0x4b*/ "BaseSetter", + /*0x4c*/ "DirLoop", + /*0x4d*/ "CanBeHere", // CantBeHere in newer SCI versions + /*0x4e*/ "OnControl", + /*0x4f*/ "InitBresen", + /*0x50*/ "DoBresen", + /*0x51*/ "Platform", // DoAvoider (SCI0) + /*0x52*/ "SetJump", + /*0x53*/ "SetDebug", + /*0x54*/ "Dummy", // InspectObj + /*0x55*/ "Dummy", // ShowSends + /*0x56*/ "Dummy", // ShowObjs + /*0x57*/ "Dummy", // ShowFree + /*0x58*/ "MemoryInfo", + /*0x59*/ "Dummy", // StackUsage + /*0x5a*/ "Dummy", // Profiler + /*0x5b*/ "GetMenu", + /*0x5c*/ "SetMenu", + /*0x5d*/ "GetSaveFiles", + /*0x5e*/ "GetCWD", + /*0x5f*/ "CheckFreeSpace", + /*0x60*/ "ValidPath", + /*0x61*/ "CoordPri", + /*0x62*/ "StrAt", + /*0x63*/ "DeviceInfo", + /*0x64*/ "GetSaveDir", + /*0x65*/ "CheckSaveGame", + /*0x66*/ "ShakeScreen", + /*0x67*/ "FlushResources", + /*0x68*/ "SinMult", + /*0x69*/ "CosMult", + /*0x6a*/ "SinDiv", + /*0x6b*/ "CosDiv", + /*0x6c*/ "Graph", + /*0x6d*/ "Joystick", + // End of kernel function table for SCI0 + /*0x6e*/ "Dummy", // ShiftScreen + /*0x6f*/ "Palette", + /*0x70*/ "MemorySegment", + /*0x71*/ "Intersections", // MoveCursor (SCI1 late), PalVary (SCI1.1) + /*0x72*/ "Memory", + /*0x73*/ "Dummy", // ListOps + /*0x74*/ "FileIO", + /*0x75*/ "DoAudio", + /*0x76*/ "DoSync", + /*0x77*/ "AvoidPath", + /*0x78*/ "Sort", // StrSplit (SCI01) + /*0x79*/ "Dummy", // ATan + /*0x7a*/ "Lock", + /*0x7b*/ "StrSplit", + /*0x7c*/ "GetMessage", // Message (SCI1.1) + /*0x7d*/ "IsItSkip", + /*0x7e*/ "MergePoly", + /*0x7f*/ "ResCheck", + /*0x80*/ "AssertPalette", + /*0x81*/ "TextColors", + /*0x82*/ "TextFonts", + /*0x83*/ "Dummy", // Record + /*0x84*/ "Dummy", // PlayBack + /*0x85*/ "ShowMovie", + /*0x86*/ "SetVideoMode", + /*0x87*/ "SetQuitStr", + /*0x88*/ "Dummy" // DbugStr +}; + +#ifdef ENABLE_SCI32 + +// NOTE: 0x72-0x79, 0x85-0x86, 0x88 are from the GK2 demo (which has debug support) and are +// just Dummy in other SCI2 games. +static const char *sci2_default_knames[] = { + /*0x00*/ "Load", + /*0x01*/ "UnLoad", + /*0x02*/ "ScriptID", + /*0x03*/ "DisposeScript", + /*0x04*/ "Lock", + /*0x05*/ "ResCheck", + /*0x06*/ "Purge", + /*0x07*/ "Clone", + /*0x08*/ "DisposeClone", + /*0x09*/ "RespondsTo", + /*0x0a*/ "SetNowSeen", + /*0x0b*/ "NumLoops", + /*0x0c*/ "NumCels", + /*0x0d*/ "CelWide", + /*0x0e*/ "CelHigh", + /*0x0f*/ "GetHighPlanePri", + /*0x10*/ "GetHighItemPri", + /*0x11*/ "ShakeScreen", + /*0x12*/ "OnMe", + /*0x13*/ "ShowMovie", + /*0x14*/ "SetVideoMode", + /*0x15*/ "AddScreenItem", + /*0x16*/ "DeleteScreenItem", + /*0x17*/ "UpdateScreenItem", + /*0x18*/ "FrameOut", + /*0x19*/ "AddPlane", + /*0x1a*/ "DeletePlane", + /*0x1b*/ "UpdatePlane", + /*0x1c*/ "RepaintPlane", + /*0x1d*/ "SetShowStyle", + /*0x1e*/ "ShowStylePercent", + /*0x1f*/ "SetScroll", + /*0x20*/ "AddMagnify", + /*0x21*/ "DeleteMagnify", + /*0x22*/ "IsHiRes", + /*0x23*/ "Graph", + /*0x24*/ "InvertRect", + /*0x25*/ "TextSize", + /*0x26*/ "Message", + /*0x27*/ "TextColors", + /*0x28*/ "TextFonts", + /*0x29*/ "Dummy", + /*0x2a*/ "SetQuitStr", + /*0x2b*/ "EditText", + /*0x2c*/ "InputText", + /*0x2d*/ "CreateTextBitmap", + /*0x2e*/ "DisposeTextBitmap", + /*0x2f*/ "GetEvent", + /*0x30*/ "GlobalToLocal", + /*0x31*/ "LocalToGlobal", + /*0x32*/ "MapKeyToDir", + /*0x33*/ "HaveMouse", + /*0x34*/ "SetCursor", + /*0x35*/ "VibrateMouse", + /*0x36*/ "SaveGame", + /*0x37*/ "RestoreGame", + /*0x38*/ "RestartGame", + /*0x39*/ "GameIsRestarting", + /*0x3a*/ "MakeSaveCatName", + /*0x3b*/ "MakeSaveFileName", + /*0x3c*/ "GetSaveFiles", + /*0x3d*/ "GetSaveDir", + /*0x3e*/ "CheckSaveGame", + /*0x3f*/ "CheckFreeSpace", + /*0x40*/ "DoSound", + /*0x41*/ "DoAudio", + /*0x42*/ "DoSync", + /*0x43*/ "NewList", + /*0x44*/ "DisposeList", + /*0x45*/ "NewNode", + /*0x46*/ "FirstNode", + /*0x47*/ "LastNode", + /*0x48*/ "EmptyList", + /*0x49*/ "NextNode", + /*0x4a*/ "PrevNode", + /*0x4b*/ "NodeValue", + /*0x4c*/ "AddAfter", + /*0x4d*/ "AddToFront", + /*0x4e*/ "AddToEnd", + /*0x4f*/ "Dummy", + /*0x50*/ "Dummy", + /*0x51*/ "FindKey", + /*0x52*/ "Dummy", + /*0x53*/ "Dummy", + /*0x54*/ "Dummy", + /*0x55*/ "DeleteKey", + /*0x56*/ "Dummy", + /*0x57*/ "Dummy", + /*0x58*/ "ListAt", + /*0x59*/ "ListIndexOf", + /*0x5a*/ "ListEachElementDo", + /*0x5b*/ "ListFirstTrue", + /*0x5c*/ "ListAllTrue", + /*0x5d*/ "Random", + /*0x5e*/ "Abs", + /*0x5f*/ "Sqrt", + /*0x60*/ "GetAngle", + /*0x61*/ "GetDistance", + /*0x62*/ "ATan", + /*0x63*/ "SinMult", + /*0x64*/ "CosMult", + /*0x65*/ "SinDiv", + /*0x66*/ "CosDiv", + /*0x67*/ "GetTime", + /*0x68*/ "Platform", + /*0x69*/ "BaseSetter", + /*0x6a*/ "DirLoop", + /*0x6b*/ "CantBeHere", + /*0x6c*/ "InitBresen", + /*0x6d*/ "DoBresen", + /*0x6e*/ "SetJump", + /*0x6f*/ "AvoidPath", + /*0x70*/ "InPolygon", + /*0x71*/ "MergePoly", + /*0x72*/ "SetDebug", + /*0x73*/ "InspectObject", + /*0x74*/ "MemoryInfo", + /*0x75*/ "Profiler", + /*0x76*/ "Record", + /*0x77*/ "PlayBack", + /*0x78*/ "MonoOut", + /*0x79*/ "SetFatalStr", + /*0x7a*/ "GetCWD", + /*0x7b*/ "ValidPath", + /*0x7c*/ "FileIO", + /*0x7d*/ "Dummy", + /*0x7e*/ "DeviceInfo", + /*0x7f*/ "Palette", + /*0x80*/ "PalVary", + /*0x81*/ "PalCycle", + /*0x82*/ "Array", + /*0x83*/ "String", + /*0x84*/ "RemapColors", + /*0x85*/ "IntegrityChecking", + /*0x86*/ "CheckIntegrity", + /*0x87*/ "ObjectIntersect", + /*0x88*/ "MarkMemory", + /*0x89*/ "TextWidth", + /*0x8a*/ "PointSize", + + // GK2 Demo (and similar) only kernel functions + /*0x8b*/ "AddLine", + /*0x8c*/ "DeleteLine", + /*0x8d*/ "UpdateLine", + /*0x8e*/ "AddPolygon", + /*0x8f*/ "DeletePolygon", + /*0x90*/ "UpdatePolygon", + /*0x91*/ "Bitmap", + /*0x92*/ "ScrollWindow", + /*0x93*/ "SetFontRes", + /*0x94*/ "MovePlaneItems", + /*0x95*/ "PreloadResource", + /*0x96*/ "Dummy", + /*0x97*/ "ResourceTrack", + /*0x98*/ "CheckCDisc", + /*0x99*/ "GetSaveCDisc", + /*0x9a*/ "TestPoly", + /*0x9b*/ "WinHelp", + /*0x9c*/ "LoadChunk", + /*0x9d*/ "SetPalStyleRange", + /*0x9e*/ "AddPicAt", + /*0x9f*/ "MessageBox" +}; + +static const char *sci21_default_knames[] = { + /*0x00*/ "Load", + /*0x01*/ "UnLoad", + /*0x02*/ "ScriptID", + /*0x03*/ "DisposeScript", + /*0x04*/ "Lock", + /*0x05*/ "ResCheck", + /*0x06*/ "Purge", + /*0x07*/ "SetLanguage", + /*0x08*/ "Dummy", + /*0x09*/ "Dummy", + /*0x0a*/ "Clone", + /*0x0b*/ "DisposeClone", + /*0x0c*/ "RespondsTo", + /*0x0d*/ "FindSelector", + /*0x0e*/ "FindClass", + /*0x0f*/ "Dummy", + /*0x10*/ "Dummy", + /*0x11*/ "Dummy", + /*0x12*/ "Dummy", + /*0x13*/ "Dummy", + /*0x14*/ "SetNowSeen", + /*0x15*/ "NumLoops", + /*0x16*/ "NumCels", + /*0x17*/ "IsOnMe", + /*0x18*/ "AddMagnify", + /*0x19*/ "DeleteMagnify", + /*0x1a*/ "CelRect", + /*0x1b*/ "BaseLineSpan", + /*0x1c*/ "CelWide", + /*0x1d*/ "CelHigh", + /*0x1e*/ "AddScreenItem", + /*0x1f*/ "DeleteScreenItem", + /*0x20*/ "UpdateScreenItem", + /*0x21*/ "FrameOut", + /*0x22*/ "CelInfo", + /*0x23*/ "Bitmap", + /*0x24*/ "CelLink", + /*0x25*/ "Dummy", + /*0x26*/ "Dummy", + /*0x27*/ "Dummy", + /*0x28*/ "AddPlane", + /*0x29*/ "DeletePlane", + /*0x2a*/ "UpdatePlane", + /*0x2b*/ "RepaintPlane", + /*0x2c*/ "GetHighPlanePri", + /*0x2d*/ "GetHighItemPri", + /*0x2e*/ "SetShowStyle", + /*0x2f*/ "ShowStylePercent", + /*0x30*/ "SetScroll", + /*0x31*/ "MovePlaneItems", + /*0x32*/ "ShakeScreen", + /*0x33*/ "Dummy", + /*0x34*/ "Dummy", + /*0x35*/ "Dummy", + /*0x36*/ "Dummy", + /*0x37*/ "IsHiRes", + /*0x38*/ "SetVideoMode", + /*0x39*/ "ShowMovie", + /*0x3a*/ "Robot", + /*0x3b*/ "CreateTextBitmap", + /*0x3c*/ "Random", + /*0x3d*/ "Abs", + /*0x3e*/ "Sqrt", + /*0x3f*/ "GetAngle", + /*0x40*/ "GetDistance", + /*0x41*/ "ATan", + /*0x42*/ "SinMult", + /*0x43*/ "CosMult", + /*0x44*/ "SinDiv", + /*0x45*/ "CosDiv", + /*0x46*/ "Text", + /*0x47*/ "Dummy", + /*0x48*/ "Message", + /*0x49*/ "Font", + /*0x4a*/ "EditText", + /*0x4b*/ "InputText", + /*0x4c*/ "ScrollWindow", + /*0x4d*/ "Dummy", + /*0x4e*/ "Dummy", + /*0x4f*/ "Dummy", + /*0x50*/ "GetEvent", + /*0x51*/ "GlobalToLocal", + /*0x52*/ "LocalToGlobal", + /*0x53*/ "MapKeyToDir", + /*0x54*/ "HaveMouse", + /*0x55*/ "SetCursor", + /*0x56*/ "VibrateMouse", + /*0x57*/ "Dummy", + /*0x58*/ "Dummy", + /*0x59*/ "Dummy", + /*0x5a*/ "List", + /*0x5b*/ "Array", + /*0x5c*/ "String", + /*0x5d*/ "FileIO", + /*0x5e*/ "BaseSetter", + /*0x5f*/ "DirLoop", + /*0x60*/ "CantBeHere", + /*0x61*/ "InitBresen", + /*0x62*/ "DoBresen", + /*0x63*/ "SetJump", + /*0x64*/ "AvoidPath", + /*0x65*/ "InPolygon", + /*0x66*/ "MergePoly", + /*0x67*/ "ObjectIntersect", + /*0x68*/ "Dummy", + /*0x69*/ "MemoryInfo", + /*0x6a*/ "DeviceInfo", + /*0x6b*/ "Palette", + /*0x6c*/ "PalVary", + /*0x6d*/ "PalCycle", + /*0x6e*/ "RemapColors", + /*0x6f*/ "AddLine", + /*0x70*/ "DeleteLine", + /*0x71*/ "UpdateLine", + /*0x72*/ "AddPolygon", + /*0x73*/ "DeletePolygon", + /*0x74*/ "UpdatePolygon", + /*0x75*/ "DoSound", + /*0x76*/ "DoAudio", + /*0x77*/ "DoSync", + /*0x78*/ "Save", + /*0x79*/ "GetTime", + /*0x7a*/ "Platform", + /*0x7b*/ "CD", + /*0x7c*/ "SetQuitStr", + /*0x7d*/ "GetConfig", + /*0x7e*/ "Table", + /*0x7f*/ "WinHelp", // Windows only + /*0x80*/ "Dummy", + /*0x81*/ "Dummy", + /*0x82*/ "Dummy", + /*0x83*/ "PrintDebug", // used by Shivers 2 (demo and full) + /*0x84*/ "Dummy", + /*0x85*/ "Dummy", + /*0x86*/ "Dummy", + /*0x87*/ "Dummy", + /*0x88*/ "Dummy", + /*0x89*/ "Dummy", + /*0x8a*/ "LoadChunk", + /*0x8b*/ "SetPalStyleRange", + /*0x8c*/ "AddPicAt", + /*0x8d*/ "Dummy", + /*0x8e*/ "NewRoom", + /*0x8f*/ "Dummy", + /*0x90*/ "Priority", + /*0x91*/ "MorphOn", + /*0x92*/ "PlayVMD", + /*0x93*/ "SetHotRectangles", + /*0x94*/ "MulDiv", + /*0x95*/ "GetSierraProfileInt", // Windows only + /*0x96*/ "GetSierraProfileString", // Windows only + /*0x97*/ "SetWindowsOption", // Windows only + /*0x98*/ "GetWindowsOption", // Windows only + /*0x99*/ "WinDLL", // Windows only + /*0x9a*/ "Dummy", + /*0x9b*/ "Dummy", + /*0x9c*/ "DeletePic" +}; + +#endif + +#define END Script_None + +opcode_format g_opcode_formats[128][4] = { + /*00*/ + {Script_None}, {Script_None}, {Script_None}, {Script_None}, + /*04*/ + {Script_None}, {Script_None}, {Script_None}, {Script_None}, + /*08*/ + {Script_None}, {Script_None}, {Script_None}, {Script_None}, + /*0C*/ + {Script_None}, {Script_None}, {Script_None}, {Script_None}, + /*10*/ + {Script_None}, {Script_None}, {Script_None}, {Script_None}, + /*14*/ + {Script_None}, {Script_None}, {Script_None}, {Script_SRelative, END}, + /*18*/ + {Script_SRelative, END}, {Script_SRelative, END}, {Script_SVariable, END}, {Script_None}, + /*1C*/ + {Script_SVariable, END}, {Script_None}, {Script_None}, {Script_Variable, END}, + /*20*/ + {Script_SRelative, Script_Byte, END}, {Script_Variable, Script_Byte, END}, {Script_Variable, Script_Byte, END}, {Script_Variable, Script_SVariable, Script_Byte, END}, + /*24 (24=ret)*/ + {Script_End}, {Script_Byte, END}, {Script_Invalid}, {Script_Invalid}, + /*28*/ + {Script_Variable, END}, {Script_Invalid}, {Script_Byte, END}, {Script_Variable, Script_Byte, END}, + /*2C*/ + {Script_SVariable, END}, {Script_SVariable, Script_Variable, END}, {Script_None}, {Script_Invalid}, + /*30*/ + {Script_None}, {Script_Property, END}, {Script_Property, END}, {Script_Property, END}, + /*34*/ + {Script_Property, END}, {Script_Property, END}, {Script_Property, END}, {Script_Property, END}, + /*38*/ + {Script_Property, END}, {Script_SRelative, END}, {Script_SRelative, END}, {Script_None}, + /*3C*/ + {Script_None}, {Script_None}, {Script_None}, {Script_Word}, + /*40-4F*/ + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + /*50-5F*/ + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + /*60-6F*/ + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + /*70-7F*/ + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, + {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END} +}; +#undef END + +} // End of namespace Sci + +#endif // SCI_ENGINE_KERNEL_TABLES_H diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index 7547ad5ab6..3395811700 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -50,6 +50,10 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) { // Limit the mouse cursor position, if necessary g_sci->_gfxCursor->refreshPosition(); mousePos = g_sci->_gfxCursor->getPosition(); +#ifdef ENABLE_SCI32 + if (getSciVersion() >= SCI_VERSION_2_1) + g_sci->_gfxCoordAdjuster->fromDisplayToScript(mousePos.y, mousePos.x); +#endif // If there's a simkey pending, and the game wants a keyboard event, use the // simkey instead of a normal event @@ -150,11 +154,11 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) { } if (g_sci->_features->detectDoSoundType() <= SCI_VERSION_0_LATE) { - // If we're running a SCI0 game, update the sound cues, to compensate - // for the fact that SCI0 does not poll to update the sound cues itself, - // like SCI01 and later do with cmdUpdateSoundCues. kGetEvent is called - // quite often, so emulate the SCI01 behavior of cmdUpdateSoundCues with - // this call + // If we're running a sound-SCI0 game, update the sound cues, to + // compensate for the fact that sound-SCI0 does not poll to update + // the sound cues itself, like sound-SCI1 and later do with + // cmdUpdateSoundCues. kGetEvent is called quite often, so emulate + // the sound-SCI1 behavior of cmdUpdateSoundCues with this call g_sci->_soundCmd->updateSci0Cues(); } @@ -215,7 +219,7 @@ reg_t kMapKeyToDir(EngineState *s, int argc, reg_t *argv) { } reg_t kGlobalToLocal(EngineState *s, int argc, reg_t *argv) { - reg_t obj = argc ? argv[0] : NULL_REG; // Can this really happen? Lars + reg_t obj = argv[0]; reg_t planeObject = argc > 1 ? argv[1] : NULL_REG; // SCI32 SegManager *segMan = s->_segMan; @@ -234,7 +238,7 @@ reg_t kGlobalToLocal(EngineState *s, int argc, reg_t *argv) { } reg_t kLocalToGlobal(EngineState *s, int argc, reg_t *argv) { - reg_t obj = argc ? argv[0] : NULL_REG; // Can this really happen? Lars + reg_t obj = argv[0]; reg_t planeObject = argc > 1 ? argv[1] : NULL_REG; // SCI32 SegManager *segMan = s->_segMan; diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 807edc63a5..d4ba467b25 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -98,7 +98,7 @@ enum { -void file_open(EngineState *s, const char *filename, int mode) { +reg_t file_open(EngineState *s, const char *filename, int mode) { // QfG3 character import prepends /\ to the filenames. if (filename[0] == '/' && filename[1] == '\\') filename += 2; @@ -132,17 +132,17 @@ void file_open(EngineState *s, const char *filename, int mode) { } if (!inFile) - warning(" -> file_open(_K_FILE_MODE_OPEN_OR_FAIL): failed to open file '%s'", englishName.c_str()); + debugC(2, kDebugLevelFile, " -> file_open(_K_FILE_MODE_OPEN_OR_FAIL): failed to open file '%s'", englishName.c_str()); } else if (mode == _K_FILE_MODE_CREATE) { // Create the file, destroying any content it might have had outFile = saveFileMan->openForSaving(wrappedName); if (!outFile) - warning(" -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str()); + debugC(2, kDebugLevelFile, " -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str()); } else if (mode == _K_FILE_MODE_OPEN_OR_CREATE) { // Try to open file, create it if it doesn't exist outFile = saveFileMan->openForSaving(wrappedName); if (!outFile) - warning(" -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str()); + debugC(2, kDebugLevelFile, " -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str()); // QfG1 opens the character export file with _K_FILE_MODE_CREATE first, // closes it immediately and opens it again with this here. Perhaps // other games use this for read access as well. I guess changing this @@ -154,8 +154,7 @@ void file_open(EngineState *s, const char *filename, int mode) { if (!inFile && !outFile) { // Failed debugC(2, kDebugLevelFile, " -> file_open() failed"); - s->r_acc = SIGNAL_REG; - return; + return SIGNAL_REG; } // Find a free file handle @@ -172,9 +171,8 @@ void file_open(EngineState *s, const char *filename, int mode) { s->_fileHandles[handle]._out = outFile; s->_fileHandles[handle]._name = englishName; - s->r_acc = make_reg(0, handle); - debugC(2, kDebugLevelFile, " -> opened file '%s' with handle %d", englishName.c_str(), handle); + return make_reg(0, handle); } reg_t kFOpen(EngineState *s, int argc, reg_t *argv) { @@ -182,8 +180,7 @@ reg_t kFOpen(EngineState *s, int argc, reg_t *argv) { int mode = argv[1].toUint16(); debugC(2, kDebugLevelFile, "kFOpen(%s,0x%x)", name.c_str(), mode); - file_open(s, name.c_str(), mode); - return s->r_acc; + return file_open(s, name.c_str(), mode); } static FileHandle *getFileFromHandle(EngineState *s, uint handle) { @@ -368,11 +365,25 @@ reg_t kGetSaveDir(EngineState *s, int argc, reg_t *argv) { } reg_t kCheckFreeSpace(EngineState *s, int argc, reg_t *argv) { -#ifdef ENABLE_SCI32 - // TODO: SCI32 uses a parameter here. - if (argc > 1) - warning("kCheckFreeSpace called with %d parameter(s): %04x:%04x", argc, PRINT_REG(argv[1])); -#endif + if (argc > 1) { + // SCI1.1/SCI32 + // TODO: don't know if those are right for SCI32 as well + // Please note that sierra sci supported both calls either w/ or w/o opcode in SCI1.1 + switch (argv[1].toUint16()) { + case 0: // return saved game size + return make_reg(0, 0); // we return 0 + + case 1: // return free harddisc space (shifted right somehow) + return make_reg(0, 0x7fff); // we return maximum + + case 2: // same as call w/o opcode + break; + return make_reg(0, 1); + + default: + error("kCheckFreeSpace: called with unknown sub-op %d", argv[1].toUint16()); + } + } Common::String path = s->_segMan->getString(argv[0]); @@ -534,6 +545,12 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { debug(3, "kSaveGame(%s,%d,%s,%s)", game_id.c_str(), virtualId, game_description.c_str(), version.c_str()); + // We check here, we don't want to delete a users save in case we are within a kernel function + if (s->executionStackBase) { + warning("kSaveGame - won't save from within kernel function"); + return NULL_REG; + } + Common::Array<SavegameDesc> saves; listSavegames(saves); @@ -541,7 +558,7 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { if ((virtualId >= SAVEGAMEID_OFFICIALRANGE_START) && (virtualId <= SAVEGAMEID_OFFICIALRANGE_END)) { // savegameId is an actual Id, so search for it just to make sure savegameId = virtualId - SAVEGAMEID_OFFICIALRANGE_START; - if (findSavegame(saves, savegameId) != -1) + if (findSavegame(saves, savegameId) == -1) return NULL_REG; } else if (virtualId < SAVEGAMEID_OFFICIALRANGE_START) { // virtualId is low, we assume that scripts expect us to create new slot @@ -603,11 +620,15 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { debug(3, "kRestoreGame(%s,%d)", game_id.c_str(), savegameId); - if ((savegameId < 1000) || (savegameId > 1999)) { - warning("Savegame ID %d is not allowed", savegameId); - return TRUE_REG; + if (argv[0].isNull()) { + // Loading from the launcher, don't adjust the ID of the saved game + } else { + if ((savegameId < 1000) || (savegameId > 1999)) { + warning("Savegame ID %d is not allowed", savegameId); + return TRUE_REG; + } + savegameId -= 1000; } - savegameId -= 1000; Common::Array<SavegameDesc> saves; listSavegames(saves); @@ -643,28 +664,6 @@ reg_t kValidPath(EngineState *s, int argc, reg_t *argv) { return make_reg(0, 1); } -enum { - K_FILEIO_OPEN = 0, - K_FILEIO_CLOSE = 1, - K_FILEIO_READ_RAW = 2, - K_FILEIO_WRITE_RAW = 3, - K_FILEIO_UNLINK = 4, - K_FILEIO_READ_STRING = 5, - K_FILEIO_WRITE_STRING = 6, - K_FILEIO_SEEK = 7, - K_FILEIO_FIND_FIRST = 8, - K_FILEIO_FIND_NEXT = 9, - K_FILEIO_FILE_EXISTS = 10, - // SCI1.1 - K_FILEIO_RENAME = 11, - // SCI32 - // 12? - K_FILEIO_READ_BYTE = 13, - K_FILEIO_WRITE_BYTE = 14, - K_FILEIO_READ_WORD = 15, - K_FILEIO_WRITE_WORD = 16 -}; - reg_t DirSeeker::firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan) { // Verify that we are given a valid buffer if (!buffer.segment) { @@ -705,263 +704,298 @@ reg_t DirSeeker::nextFile(SegManager *segMan) { } reg_t kFileIO(EngineState *s, int argc, reg_t *argv) { - int func_nr = argv[0].toUint16(); + if (!s) + return make_reg(0, getSciVersion()); + error("not supposed to call this"); +} - switch (func_nr) { - case K_FILEIO_OPEN : { - Common::String name = s->_segMan->getString(argv[1]); +reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { + Common::String name = s->_segMan->getString(argv[0]); - // SCI32 can call K_FILEIO_OPEN with only two arguments. It seems to - // just be checking if it exists. - int mode = (argc < 3) ? (int)_K_FILE_MODE_OPEN_OR_FAIL : argv[2].toUint16(); + // SCI32 can call K_FILEIO_OPEN with only one argument. It seems to + // just be checking if it exists. + int mode = (argc < 2) ? (int)_K_FILE_MODE_OPEN_OR_FAIL : argv[1].toUint16(); - // SQ4 floppy prepends /\ to the filenames - if (name.hasPrefix("/\\")) { - name.deleteChar(0); - name.deleteChar(0); - } + // SQ4 floppy prepends /\ to the filenames + if (name.hasPrefix("/\\")) { + name.deleteChar(0); + name.deleteChar(0); + } - // SQ4 floppy attempts to update the savegame index file sq4sg.dir when - // deleting saved games. We don't use an index file for saving or - // loading, so just stop the game from modifying the file here in order - // to avoid having it saved in the ScummVM save directory. - if (name == "sq4sg.dir") { - debugC(2, kDebugLevelFile, "Not opening unused file sq4sg.dir"); - return SIGNAL_REG; - } + // SQ4 floppy attempts to update the savegame index file sq4sg.dir when + // deleting saved games. We don't use an index file for saving or + // loading, so just stop the game from modifying the file here in order + // to avoid having it saved in the ScummVM save directory. + if (name == "sq4sg.dir") { + debugC(2, kDebugLevelFile, "Not opening unused file sq4sg.dir"); + return SIGNAL_REG; + } - if (name.empty()) { - warning("Attempted to open a file with an empty filename"); - return SIGNAL_REG; - } - debugC(2, kDebugLevelFile, "kFileIO(open): %s, 0x%x", name.c_str(), mode); - file_open(s, name.c_str(), mode); - break; + if (name.empty()) { + warning("Attempted to open a file with an empty filename"); + return SIGNAL_REG; } - case K_FILEIO_CLOSE : { - debugC(2, kDebugLevelFile, "kFileIO(close): %d", argv[1].toUint16()); + debugC(2, kDebugLevelFile, "kFileIO(open): %s, 0x%x", name.c_str(), mode); + return file_open(s, name.c_str(), mode); +} - FileHandle *f = getFileFromHandle(s, argv[1].toUint16()); - if (f) - f->close(); - break; +reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv) { + debugC(2, kDebugLevelFile, "kFileIO(close): %d", argv[0].toUint16()); + + FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); + if (f) { + f->close(); + return SIGNAL_REG; } - case K_FILEIO_READ_RAW : { - int handle = argv[1].toUint16(); - int size = argv[3].toUint16(); - char *buf = new char[size]; - debugC(2, kDebugLevelFile, "kFileIO(readRaw): %d, %d", handle, size); + return NULL_REG; +} + +reg_t kFileIOReadRaw(EngineState *s, int argc, reg_t *argv) { + int handle = argv[0].toUint16(); + int size = argv[2].toUint16(); + int bytesRead = 0; + char *buf = new char[size]; + debugC(2, kDebugLevelFile, "kFileIO(readRaw): %d, %d", handle, size); - FileHandle *f = getFileFromHandle(s, handle); - if (f) { - s->r_acc = make_reg(0, f->_in->read(buf, size)); - s->_segMan->memcpy(argv[2], (const byte*)buf, size); - } + FileHandle *f = getFileFromHandle(s, handle); + if (f) { + bytesRead = f->_in->read(buf, size); + s->_segMan->memcpy(argv[1], (const byte*)buf, size); + } - delete[] buf; - break; + delete[] buf; + return make_reg(0, bytesRead); +} + +reg_t kFileIOWriteRaw(EngineState *s, int argc, reg_t *argv) { + int handle = argv[0].toUint16(); + int size = argv[2].toUint16(); + char *buf = new char[size]; + bool success = false; + s->_segMan->memcpy((byte*)buf, argv[1], size); + debugC(2, kDebugLevelFile, "kFileIO(writeRaw): %d, %d", handle, size); + + FileHandle *f = getFileFromHandle(s, handle); + if (f) { + f->_out->write(buf, size); + success = true; } - case K_FILEIO_WRITE_RAW : { - int handle = argv[1].toUint16(); - int size = argv[3].toUint16(); - char *buf = new char[size]; - s->_segMan->memcpy((byte*)buf, argv[2], size); - debugC(2, kDebugLevelFile, "kFileIO(writeRaw): %d, %d", handle, size); - FileHandle *f = getFileFromHandle(s, handle); - if (f) - f->_out->write(buf, size); + delete[] buf; + if (success) + return NULL_REG; + return make_reg(0, 6); // DOS - invalid handle +} - delete[] buf; - break; +reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv) { + Common::String name = s->_segMan->getString(argv[0]); + Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); + bool result; + + // SQ4 floppy prepends /\ to the filenames + if (name.hasPrefix("/\\")) { + name.deleteChar(0); + name.deleteChar(0); + } + + // Special case for SQ4 floppy: This game has hardcoded names for all of + // its savegames, and they are all named "sq4sg.xxx", where xxx is the + // slot. We just take the slot number here, and delete the appropriate + // save game. + if (name.hasPrefix("sq4sg.")) { + // Special handling for SQ4... get the slot number and construct the + // save game name. + int slotNum = atoi(name.c_str() + name.size() - 3); + Common::Array<SavegameDesc> saves; + listSavegames(saves); + int savedir_nr = saves[slotNum].id; + name = g_sci->getSavegameName(savedir_nr); + result = saveFileMan->removeSavefile(name); + } else { + const Common::String wrappedName = g_sci->wrapFilename(name); + result = saveFileMan->removeSavefile(wrappedName); } - case K_FILEIO_UNLINK : { - Common::String name = s->_segMan->getString(argv[1]); - Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); - // SQ4 floppy prepends /\ to the filenames - if (name.hasPrefix("/\\")) { - name.deleteChar(0); - name.deleteChar(0); - } - // Special case for SQ4 floppy: This game has hardcoded names for all of - // its savegames, and they are all named "sq4sg.xxx", where xxx is the - // slot. We just take the slot number here, and delete the appropriate - // save game. - if (name.hasPrefix("sq4sg.")) { - // Special handling for SQ4... get the slot number and construct the - // save game name. - int slotNum = atoi(name.c_str() + name.size() - 3); - Common::Array<SavegameDesc> saves; - listSavegames(saves); - int savedir_nr = saves[slotNum].id; - name = g_sci->getSavegameName(savedir_nr); - saveFileMan->removeSavefile(name); - } else { - const Common::String wrappedName = g_sci->wrapFilename(name); - saveFileMan->removeSavefile(wrappedName); - } + debugC(2, kDebugLevelFile, "kFileIO(unlink): %s", name.c_str()); + if (result) + return NULL_REG; + return make_reg(0, 2); // DOS - file not found error code +} - debugC(2, kDebugLevelFile, "kFileIO(unlink): %s", name.c_str()); +reg_t kFileIOReadString(EngineState *s, int argc, reg_t *argv) { + int size = argv[1].toUint16(); + char *buf = new char[size]; + int handle = argv[2].toUint16(); + debugC(2, kDebugLevelFile, "kFileIO(readString): %d, %d", handle, size); - // TODO/FIXME: Should we return something (like, a bool indicating - // whether deleting the save succeeded or failed)? - break; - } - case K_FILEIO_READ_STRING : { - int size = argv[2].toUint16(); - char *buf = new char[size]; - int handle = argv[3].toUint16(); - debugC(2, kDebugLevelFile, "kFileIO(readString): %d, %d", handle, size); + fgets_wrapper(s, buf, size, handle); + s->_segMan->memcpy(argv[0], (const byte*)buf, size); + delete[] buf; + return argv[0]; +} - fgets_wrapper(s, buf, size, handle); - s->_segMan->memcpy(argv[1], (const byte*)buf, size); - delete[] buf; - return argv[1]; - } - case K_FILEIO_WRITE_STRING : { - int handle = argv[1].toUint16(); - int size = argv[3].toUint16(); - Common::String str = s->_segMan->getString(argv[2]); - debugC(2, kDebugLevelFile, "kFileIO(writeString): %d, %d", handle, size); - - // CHECKME: Is the size parameter used at all? - // In the LSL5 password protection it is zero, and we should - // then write a full string. (Not sure if it should write the - // terminating zero.) - - FileHandle *f = getFileFromHandle(s, handle); - if (f) - f->_out->write(str.c_str(), str.size()); - break; - } - case K_FILEIO_SEEK : { - int handle = argv[1].toUint16(); - int offset = argv[2].toUint16(); - int whence = argv[3].toUint16(); - debugC(2, kDebugLevelFile, "kFileIO(seek): %d, %d, %d", handle, offset, whence); +reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) { + int handle = argv[0].toUint16(); + Common::String str = s->_segMan->getString(argv[1]); + debugC(2, kDebugLevelFile, "kFileIO(writeString): %d", handle); + + FileHandle *f = getFileFromHandle(s, handle); + if (f) + f->_out->write(str.c_str(), str.size()); + return NULL_REG; + return make_reg(0, 6); // DOS - invalid handle +} + +reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv) { + int handle = argv[0].toUint16(); + int offset = argv[1].toUint16(); + int whence = argv[2].toUint16(); + debugC(2, kDebugLevelFile, "kFileIO(seek): %d, %d, %d", handle, offset, whence); - FileHandle *f = getFileFromHandle(s, handle); - if (f) - s->r_acc = make_reg(0, f->_in->seek(offset, whence)); - break; - } - case K_FILEIO_FIND_FIRST : { - Common::String mask = s->_segMan->getString(argv[1]); - reg_t buf = argv[2]; - int attr = argv[3].toUint16(); // We won't use this, Win32 might, though... - debugC(2, kDebugLevelFile, "kFileIO(findFirst): %s, 0x%x", mask.c_str(), attr); - - // We remove ".*". mask will get prefixed, so we will return all additional files for that gameid - if (mask == "*.*") - mask = "*"; - - // QfG3 uses this mask for the character import - if (mask == "/\\*.*") - mask = "*"; -//#ifndef WIN32 -// if (mask == "*.*") -// mask = "*"; // For UNIX -//#endif - s->r_acc = s->_dirseeker.firstFile(mask, buf, s->_segMan); + FileHandle *f = getFileFromHandle(s, handle); + if (f) + s->r_acc = make_reg(0, f->_in->seek(offset, whence)); + return SIGNAL_REG; +} - break; - } - case K_FILEIO_FIND_NEXT : { - debugC(2, kDebugLevelFile, "kFileIO(findNext)"); - s->r_acc = s->_dirseeker.nextFile(s->_segMan); - break; +reg_t kFileIOFindFirst(EngineState *s, int argc, reg_t *argv) { + Common::String mask = s->_segMan->getString(argv[0]); + reg_t buf = argv[1]; + int attr = argv[2].toUint16(); // We won't use this, Win32 might, though... + debugC(2, kDebugLevelFile, "kFileIO(findFirst): %s, 0x%x", mask.c_str(), attr); + + // QfG3 uses "/\*.*" for the character import, QfG4 uses "/\*" + if (mask.hasPrefix("/\\")) { + mask.deleteChar(0); + mask.deleteChar(0); } - case K_FILEIO_FILE_EXISTS : { - Common::String name = s->_segMan->getString(argv[1]); - // Check for regular file - bool exists = Common::File::exists(name); - Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); - const Common::String wrappedName = g_sci->wrapFilename(name); + // We remove ".*". mask will get prefixed, so we will return all additional files for that gameid + if (mask == "*.*") + mask = "*"; + return s->_dirseeker.firstFile(mask, buf, s->_segMan); +} - if (!exists) - exists = !saveFileMan->listSavefiles(name).empty(); +reg_t kFileIOFindNext(EngineState *s, int argc, reg_t *argv) { + debugC(2, kDebugLevelFile, "kFileIO(findNext)"); + return s->_dirseeker.nextFile(s->_segMan); +} - if (!exists) { - // Try searching for the file prepending target- - Common::SeekableReadStream *inFile = saveFileMan->openForLoading(wrappedName); - exists = (inFile != 0); - delete inFile; - } +reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) { + Common::String name = s->_segMan->getString(argv[0]); - // Special case for non-English versions of LSL5: The English version of - // LSL5 calls kFileIO(), case K_FILEIO_OPEN for reading to check if - // memory.drv exists (which is where the game's password is stored). If - // it's not found, it calls kFileIO() again, case K_FILEIO_OPEN for - // writing and creates a new file. Non-English versions call kFileIO(), - // case K_FILEIO_FILE_EXISTS instead, and fail if memory.drv can't be - // found. We create a default memory.drv file with no password, so that - // the game can continue. - if (!exists && name == "memory.drv") { - // Create a new file, and write the bytes for the empty password - // string inside - byte defaultContent[] = { 0xE9, 0xE9, 0xEB, 0xE1, 0x0D, 0x0A, 0x31, 0x30, 0x30, 0x30 }; - Common::WriteStream *outFile = saveFileMan->openForSaving(wrappedName); - for (int i = 0; i < 10; i++) - outFile->writeByte(defaultContent[i]); - outFile->finalize(); - delete outFile; - exists = true; - } + // Check for regular file + bool exists = Common::File::exists(name); + Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); + const Common::String wrappedName = g_sci->wrapFilename(name); + + if (!exists) + exists = !saveFileMan->listSavefiles(name).empty(); + + if (!exists) { + // Try searching for the file prepending target- + Common::SeekableReadStream *inFile = saveFileMan->openForLoading(wrappedName); + exists = (inFile != 0); + delete inFile; + } + + // Special case for non-English versions of LSL5: The English version of + // LSL5 calls kFileIO(), case K_FILEIO_OPEN for reading to check if + // memory.drv exists (which is where the game's password is stored). If + // it's not found, it calls kFileIO() again, case K_FILEIO_OPEN for + // writing and creates a new file. Non-English versions call kFileIO(), + // case K_FILEIO_FILE_EXISTS instead, and fail if memory.drv can't be + // found. We create a default memory.drv file with no password, so that + // the game can continue. + if (!exists && name == "memory.drv") { + // Create a new file, and write the bytes for the empty password + // string inside + byte defaultContent[] = { 0xE9, 0xE9, 0xEB, 0xE1, 0x0D, 0x0A, 0x31, 0x30, 0x30, 0x30 }; + Common::WriteStream *outFile = saveFileMan->openForSaving(wrappedName); + for (int i = 0; i < 10; i++) + outFile->writeByte(defaultContent[i]); + outFile->finalize(); + delete outFile; + exists = true; + } + + debugC(2, kDebugLevelFile, "kFileIO(fileExists) %s -> %d", name.c_str(), exists); + return make_reg(0, exists); +} - debugC(2, kDebugLevelFile, "kFileIO(fileExists) %s -> %d", name.c_str(), exists); - return make_reg(0, exists); - } - case K_FILEIO_RENAME: { - Common::String oldName = s->_segMan->getString(argv[1]); - Common::String newName = s->_segMan->getString(argv[2]); +reg_t kFileIORename(EngineState *s, int argc, reg_t *argv) { + Common::String oldName = s->_segMan->getString(argv[0]); + Common::String newName = s->_segMan->getString(argv[1]); + + // SCI1.1 returns 0 on success and a DOS error code on fail. SCI32 + // returns -1 on fail. We just return -1 for all versions. + if (g_engine->getSaveFileManager()->renameSavefile(oldName, newName)) + return NULL_REG; + else + return SIGNAL_REG; +} - // SCI1.1 returns 0 on success and a DOS error code on fail. SCI32 - // returns -1 on fail. We just return -1 for all versions. - if (g_engine->getSaveFileManager()->renameSavefile(oldName, newName)) - return NULL_REG; - else - return SIGNAL_REG; - } #ifdef ENABLE_SCI32 - case K_FILEIO_READ_BYTE: { - // Read the byte into the low byte of the accumulator - FileHandle *f = getFileFromHandle(s, argv[1].toUint16()); - if (!f) - return NULL_REG; - - return make_reg(0, (s->r_acc.toUint16() & 0xff00) | f->_in->readByte()); - } - case K_FILEIO_WRITE_BYTE: { - FileHandle *f = getFileFromHandle(s, argv[1].toUint16()); - if (f) - f->_out->writeByte(argv[2].toUint16() & 0xff); - break; - } - case K_FILEIO_READ_WORD: { - FileHandle *f = getFileFromHandle(s, argv[1].toUint16()); - if (!f) - return NULL_REG; - - return make_reg(0, f->_in->readUint16LE()); - } - case K_FILEIO_WRITE_WORD: { - FileHandle *f = getFileFromHandle(s, argv[1].toUint16()); - if (f) - f->_out->writeUint16LE(argv[2].toUint16()); - break; +reg_t kFileIOReadByte(EngineState *s, int argc, reg_t *argv) { + // Read the byte into the low byte of the accumulator + FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); + if (!f) + return NULL_REG; + return make_reg(0, (s->r_acc.toUint16() & 0xff00) | f->_in->readByte()); +} + +reg_t kFileIOWriteByte(EngineState *s, int argc, reg_t *argv) { + FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); + if (f) + f->_out->writeByte(argv[1].toUint16() & 0xff); + return s->r_acc; // FIXME: does this really doesn't return anything? +} + +reg_t kFileIOReadWord(EngineState *s, int argc, reg_t *argv) { + FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); + if (!f) + return NULL_REG; + return make_reg(0, f->_in->readUint16LE()); +} + +reg_t kFileIOWriteWord(EngineState *s, int argc, reg_t *argv) { + FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); + if (f) + f->_out->writeUint16LE(argv[1].toUint16()); + return s->r_acc; // FIXME: does this really doesn't return anything? +} + +reg_t kCD(EngineState *s, int argc, reg_t *argv) { + // TODO: Stub + switch (argv[0].toUint16()) { + case 0: + // Return whether the contents of disc argv[1] is available. + return TRUE_REG; + default: + warning("CD(%d)", argv[0].toUint16()); } - case 19: - // TODO: Torin's Passage uses this early on in the Sierra logo - warning("kFileIO(19)"); - break; -#endif + + return NULL_REG; +} + +reg_t kSave(EngineState *s, int argc, reg_t *argv) { + switch (argv[0].toUint16()) { + case 0: // Called by kq7 when starting chapters + return SIGNAL_REG; + case 2: // GetSaveDir + // Yay! Reusing the old kernel function! + return kGetSaveDir(s, argc - 1, argv + 1); + case 8: + // TODO + // This function has to return something other than 0 to proceed + return s->r_acc; default: - error("kFileIO(): unknown sub-command: %d", func_nr); + warning("Unknown/unhandled kSave subop %d", argv[0].toUint16()); } - return s->r_acc; + return NULL_REG; } +#endif + } // End of namespace Sci diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 29f7565ef9..56518f10bf 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -23,16 +23,15 @@ * */ +#include "common/system.h" + #include "engines/util.h" #include "graphics/cursorman.h" -#include "graphics/video/avi_decoder.h" -#include "graphics/video/qt_decoder.h" #include "graphics/surface.h" #include "sci/sci.h" #include "sci/debug.h" // for g_debug_sleeptime_factor #include "sci/resource.h" -#include "sci/video/seq_decoder.h" #include "sci/engine/features.h" #include "sci/engine/state.h" #include "sci/engine/selector.h" @@ -44,12 +43,14 @@ #include "sci/graphics/cursor.h" #include "sci/graphics/palette.h" #include "sci/graphics/paint16.h" +#include "sci/graphics/picture.h" #include "sci/graphics/ports.h" +#include "sci/graphics/robot.h" #include "sci/graphics/screen.h" #include "sci/graphics/text16.h" #include "sci/graphics/view.h" #ifdef ENABLE_SCI32 -#include "sci/video/vmd_decoder.h" +#include "sci/graphics/frameout.h" #endif namespace Sci { @@ -129,9 +130,10 @@ static reg_t kSetCursorSci11(EngineState *s, int argc, reg_t *argv) { break; case -1: // TODO: Special case at least in kq6, check disassembly + // Does something with magCursor, which is set on argc = 10, which we don't support break; case -2: - // TODO: Special case at least in kq6, check disassembly + g_sci->_gfxCursor->kernelResetMoveZone(); break; default: g_sci->_gfxCursor->kernelShow(); @@ -145,14 +147,22 @@ static reg_t kSetCursorSci11(EngineState *s, int argc, reg_t *argv) { g_sci->_gfxCursor->kernelSetPos(pos); break; case 4: { - int16 top = argv[0].toSint16(); - int16 left = argv[1].toSint16(); - int16 bottom = argv[2].toSint16(); - int16 right = argv[3].toSint16(); + int16 top, left, bottom, right; - // In SCI32, the right parameter seems to be divided by 2 - if (getSciVersion() >= SCI_VERSION_2) - right *= 2; + if (getSciVersion() >= SCI_VERSION_2) { + top = argv[1].toSint16(); + left = argv[0].toSint16(); + bottom = argv[3].toSint16(); + right = argv[2].toSint16(); + } else { + top = argv[0].toSint16(); + left = argv[1].toSint16(); + bottom = argv[2].toSint16(); + right = argv[3].toSint16(); + } + // bottom/right needs to be included into our movezone, because we compare it like any regular Common::Rect + bottom++; + right++; if ((right >= left) && (bottom >= top)) { Common::Rect rect = Common::Rect(left, top, right, bottom); @@ -250,7 +260,7 @@ reg_t kGraphDrawLine(EngineState *s, int argc, reg_t *argv) { reg_t kGraphSaveBox(EngineState *s, int argc, reg_t *argv) { Common::Rect rect = getGraphRect(argv); - uint16 screenMask = (argc > 4) ? argv[4].toUint16() : 0; + uint16 screenMask = argv[4].toUint16() & GFX_SCREEN_MASK_ALL; return g_sci->_gfxPaint16->kernelGraphSaveBox(rect, screenMask); } @@ -382,17 +392,16 @@ reg_t kCanBeHere(EngineState *s, int argc, reg_t *argv) { reg_t curObject = argv[0]; reg_t listReference = (argc > 1) ? argv[1] : NULL_REG; - bool canBeHere = g_sci->_gfxCompare->kernelCanBeHere(curObject, listReference); - return make_reg(0, canBeHere); + reg_t canBeHere = g_sci->_gfxCompare->kernelCanBeHere(curObject, listReference); + return make_reg(0, canBeHere.isNull() ? 1 : 0); } -// kCantBeHere does the same thing as kCanBeHere, except that it returns the opposite result. reg_t kCantBeHere(EngineState *s, int argc, reg_t *argv) { reg_t curObject = argv[0]; reg_t listReference = (argc > 1) ? argv[1] : NULL_REG; - bool canBeHere = g_sci->_gfxCompare->kernelCanBeHere(curObject, listReference); - return make_reg(0, !canBeHere); + reg_t canBeHere = g_sci->_gfxCompare->kernelCanBeHere(curObject, listReference); + return canBeHere; } reg_t kIsItSkip(EngineState *s, int argc, reg_t *argv) { @@ -518,14 +527,6 @@ reg_t kBaseSetter(EngineState *s, int argc, reg_t *argv) { reg_t object = argv[0]; g_sci->_gfxCompare->kernelBaseSetter(object); - - // WORKAROUND for a problem in LSL1VGA. This allows the casino door to be opened, - // till the actual problem is found - if (s->currentRoomNumber() == 300 && g_sci->getGameId() == GID_LSL1) { - int top = readSelectorValue(s->_segMan, object, SELECTOR(brTop)); - writeSelectorValue(s->_segMan, object, SELECTOR(brTop), top + 2); - } - return s->r_acc; } @@ -615,16 +616,16 @@ reg_t kPaletteAnimate(EngineState *s, int argc, reg_t *argv) { reg_t kPaletteSave(EngineState *s, int argc, reg_t *argv) { if (g_sci->getResMan()->isVGA()) { - warning("kPalette(7), save palette to heap STUB"); + return g_sci->_gfxPalette->kernelSave(); } return NULL_REG; } reg_t kPaletteRestore(EngineState *s, int argc, reg_t *argv) { if (g_sci->getResMan()->isVGA()) { - warning("kPalette(8), restore palette from heap STUB"); + g_sci->_gfxPalette->kernelRestore(argv[0]); } - return s->r_acc; + return argv[0]; } reg_t kPalVary(EngineState *s, int argc, reg_t *argv) { @@ -889,8 +890,8 @@ reg_t kDrawControl(EngineState *s, int argc, reg_t *argv) { reg_t textReference = readSelector(s->_segMan, controlObject, SELECTOR(text)); if (!textReference.isNull()) { Common::String text = s->_segMan->getString(textReference); - if (text == "a:hq1_hero.sav") { - // Remove "a:" from hero quest export default filename + if ((text == "a:hq1_hero.sav") || (text == "a:glory1.sav") || (text == "a:glory2.sav") || (text == "a:glory3.sav")) { + // Remove "a:" from hero quest / quest for glory export default filenames text.deleteChar(0); text.deleteChar(0); s->_segMan->strcpy(textReference, text.c_str()); @@ -974,14 +975,13 @@ reg_t kSetPort(EngineState *s, int argc, reg_t *argv) { case 7: initPriorityBandsFlag = true; - case 4: case 6: picRect.top = argv[0].toSint16(); picRect.left = argv[1].toSint16(); picRect.bottom = argv[2].toSint16(); picRect.right = argv[3].toSint16(); - picTop = (argc >= 6) ? argv[4].toSint16() : 0; - picLeft = (argc >= 6) ? argv[5].toSint16() : 0; + picTop = argv[4].toSint16(); + picLeft = argv[5].toSint16(); g_sci->_gfxPorts->kernelSetPicWindow(picRect, picTop, picLeft, initPriorityBandsFlag); break; @@ -1000,10 +1000,26 @@ reg_t kDrawCel(EngineState *s, int argc, reg_t *argv) { uint16 y = argv[4].toUint16(); int16 priority = (argc > 5) ? argv[5].toSint16() : -1; uint16 paletteNo = (argc > 6) ? argv[6].toUint16() : 0; - bool hiresMode = (argc > 7) ? true : false; - reg_t upscaledHiresHandle = (argc > 7) ? argv[7] : NULL_REG; + bool hiresMode = false; + reg_t upscaledHiresHandle = NULL_REG; + uint16 scaleX = 128; + uint16 scaleY = 128; + + if (argc > 7) { + // this is either kq6 hires or scaling + if (paletteNo > 0) { + // it's scaling + scaleX = argv[6].toUint16(); + scaleY = argv[7].toUint16(); + paletteNo = 0; + } else { + // KQ6 hires + hiresMode = true; + upscaledHiresHandle = argv[7]; + } + } - g_sci->_gfxPaint16->kernelDrawCel(viewId, loopNo, celNo, x, y, priority, paletteNo, hiresMode, upscaledHiresHandle); + g_sci->_gfxPaint16->kernelDrawCel(viewId, loopNo, celNo, x, y, priority, paletteNo, scaleX, scaleY, hiresMode, upscaledHiresHandle); return s->r_acc; } @@ -1075,153 +1091,264 @@ reg_t kDisplay(EngineState *s, int argc, reg_t *argv) { return g_sci->_gfxPaint16->kernelDisplay(g_sci->strSplit(text.c_str()).c_str(), argc, argv); } -void playVideo(Graphics::VideoDecoder *videoDecoder) { - if (!videoDecoder) - return; +reg_t kSetVideoMode(EngineState *s, int argc, reg_t *argv) { + // This call is used for KQ6's intro. It has one parameter, which is 1 when + // the intro begins, and 0 when it ends. It is suspected that this is + // actually a flag to enable video planar memory access, as the video + // decoder in KQ6 is specifically written for the planar memory model. + // Planar memory mode access was used for VGA "Mode X" (320x240 resolution, + // although the intro in KQ6 is 320x200). + // Refer to http://en.wikipedia.org/wiki/Mode_X - byte *scaleBuffer = 0; - uint16 width = videoDecoder->getWidth(); - uint16 height = videoDecoder->getHeight(); - uint16 screenWidth = g_system->getWidth(); - uint16 screenHeight = g_system->getHeight(); - - if (screenWidth == 640 && width <= 320 && height <= 240) { - assert(videoDecoder->getPixelFormat().bytesPerPixel == 1); - width *= 2; - height *= 2; - scaleBuffer = new byte[width * height]; - } + //warning("STUB: SetVideoMode %d", argv[0].toUint16()); + return s->r_acc; +} - uint16 x = (screenWidth - width) / 2; - uint16 y = (screenHeight - height) / 2; - bool skipVideo = false; - - while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) { - if (videoDecoder->needsUpdate()) { - Graphics::Surface *frame = videoDecoder->decodeNextFrame(); - if (frame) { - if (scaleBuffer) { - // TODO: Probably should do aspect ratio correction in e.g. GK1 Windows - g_sci->_gfxScreen->scale2x((byte *)frame->pixels, scaleBuffer, videoDecoder->getWidth(), videoDecoder->getHeight()); - g_system->copyRectToScreen(scaleBuffer, width, x, y, width, height); - } else - g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, width, height); - - if (videoDecoder->hasDirtyPalette()) - videoDecoder->setSystemPalette(); - - g_system->updateScreen(); - } - } +// New calls for SCI11. Using those is only needed when using text-codes so that +// one is able to change font and/or color multiple times during kDisplay and +// kDrawControl +reg_t kTextFonts(EngineState *s, int argc, reg_t *argv) { + g_sci->_gfxText16->kernelTextFonts(argc, argv); + return s->r_acc; +} - Common::Event event; - while (g_system->getEventManager()->pollEvent(event)) { - if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP) - skipVideo = true; - } +reg_t kTextColors(EngineState *s, int argc, reg_t *argv) { + g_sci->_gfxText16->kernelTextColors(argc, argv); + return s->r_acc; +} - g_system->delayMillis(10); - } +#ifdef ENABLE_SCI32 - delete[] scaleBuffer; - delete videoDecoder; +reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv) { + // Returns 0 if the screen width or height is less than 640 or 400, + // respectively. + if (g_system->getWidth() < 640 || g_system->getHeight() < 400) + return make_reg(0, 0); + + return make_reg(0, 1); } -reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) { - // Hide the cursor if it's showing and then show it again if it was - // previously visible. - bool reshowCursor = g_sci->_gfxCursor->isVisible(); - if (reshowCursor) - g_sci->_gfxCursor->kernelHide(); +// SCI32 variant, can't work like sci16 variants +reg_t kCantBeHere32(EngineState *s, int argc, reg_t *argv) { +// reg_t curObject = argv[0]; +// reg_t listReference = (argc > 1) ? argv[1] : NULL_REG; + + return NULL_REG; +} - uint16 screenWidth = g_system->getWidth(); - uint16 screenHeight = g_system->getHeight(); - - Graphics::VideoDecoder *videoDecoder = 0; +reg_t kAddScreenItem(EngineState *s, int argc, reg_t *argv) { + reg_t viewObj = argv[0]; - if (argv[0].segment != 0) { - Common::String filename = s->_segMan->getString(argv[0]); + g_sci->_gfxFrameout->kernelAddScreenItem(viewObj); + return NULL_REG; +} - if (g_sci->getPlatform() == Common::kPlatformMacintosh) { - // Mac QuickTime - // The only argument is the string for the video +reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv) { + //reg_t viewObj = argv[0]; - // HACK: Switch to 16bpp graphics for Cinepak. - initGraphics(screenWidth, screenHeight, screenWidth > 320, NULL); + //warning("kUpdateScreenItem, object %04x:%04x, view %d, loop %d, cel %d, pri %d", PRINT_REG(viewObj), viewId, loopNo, celNo, priority); + return NULL_REG; +} - if (g_system->getScreenFormat().bytesPerPixel == 1) { - error("This video requires >8bpp color to be displayed, but could not switch to RGB color mode."); - return NULL_REG; - } +reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv) { + reg_t viewObj = argv[0]; - videoDecoder = new Graphics::QuickTimeDecoder(); - if (!videoDecoder->loadFile(filename)) - error("Could not open '%s'", filename.c_str()); - } else { - // DOS SEQ - // SEQ's are called with no subops, just the string and delay - SeqDecoder *seqDecoder = new SeqDecoder(); - seqDecoder->setFrameDelay(argv[1].toUint16()); // Time between frames in ticks - videoDecoder = seqDecoder; - - if (!videoDecoder->loadFile(filename)) { - warning("Failed to open movie file %s", filename.c_str()); - delete videoDecoder; - videoDecoder = 0; - } - } - } else { - // Windows AVI - // TODO: This appears to be some sort of subop. case 0 contains the string - // for the video, so we'll just play it from there for now. + g_sci->_gfxFrameout->kernelDeleteScreenItem(viewObj); -#ifdef ENABLE_SCI32 - if (getSciVersion() >= SCI_VERSION_2_1) { - // SCI2.1 always has argv[0] as 1, the rest of the arguments seem to - // follow SCI1.1/2. - if (argv[0].toUint16() != 1) - error("SCI2.1 kShowMovie argv[0] not 1"); - argv++; - argc--; - } -#endif - switch (argv[0].toUint16()) { - case 0: { - Common::String filename = s->_segMan->getString(argv[1]); - videoDecoder = new Graphics::AviDecoder(g_system->getMixer()); - - if (!videoDecoder->loadFile(filename.c_str())) { - warning("Failed to open movie file %s", filename.c_str()); - delete videoDecoder; - videoDecoder = 0; - } - break; - } - default: - warning("Unhandled SCI kShowMovie subop %d", argv[1].toUint16()); - } + /* + reg_t viewObj = argv[0]; + uint16 viewId = readSelectorValue(s->_segMan, viewObj, SELECTOR(view)); + int16 loopNo = readSelectorValue(s->_segMan, viewObj, SELECTOR(loop)); + int16 celNo = readSelectorValue(s->_segMan, viewObj, SELECTOR(cel)); + //int16 leftPos = 0; + //int16 topPos = 0; + int16 priority = readSelectorValue(s->_segMan, viewObj, SELECTOR(priority)); + //int16 control = 0; + */ + + // TODO + + //warning("kDeleteScreenItem, view %d, loop %d, cel %d, pri %d", viewId, loopNo, celNo, priority); + return NULL_REG; +} + +reg_t kAddPlane(EngineState *s, int argc, reg_t *argv) { + reg_t planeObj = argv[0]; + + g_sci->_gfxFrameout->kernelAddPlane(planeObj); + return NULL_REG; +} + +reg_t kDeletePlane(EngineState *s, int argc, reg_t *argv) { + reg_t planeObj = argv[0]; + + g_sci->_gfxFrameout->kernelDeletePlane(planeObj); + return NULL_REG; +} + +reg_t kUpdatePlane(EngineState *s, int argc, reg_t *argv) { + reg_t planeObj = argv[0]; + + g_sci->_gfxFrameout->kernelUpdatePlane(planeObj); + return s->r_acc; +} + +reg_t kRepaintPlane(EngineState *s, int argc, reg_t *argv) { + reg_t picObj = argv[0]; + + // TODO + + warning("kRepaintPlane object %04x:%04x", PRINT_REG(picObj)); + return NULL_REG; +} + +reg_t kAddPicAt(EngineState *s, int argc, reg_t *argv) { + reg_t planeObj = argv[0]; + GuiResourceId pictureId = argv[1].toUint16(); + int16 forWidth = argv[2].toSint16(); + // argv[3] seems to be 0 most of the time + + g_sci->_gfxFrameout->kernelAddPicAt(planeObj, forWidth, pictureId); + return s->r_acc; +} + +reg_t kGetHighPlanePri(EngineState *s, int argc, reg_t *argv) { + return make_reg(0, g_sci->_gfxFrameout->kernelGetHighPlanePri()); +} + +reg_t kFrameOut(EngineState *s, int argc, reg_t *argv) { + // This kernel call likely seems to be doing the screen updates, + // as its called right after a view is updated + + // TODO + g_sci->_gfxFrameout->kernelFrameout(); + + return NULL_REG; +} + +reg_t kOnMe(EngineState *s, int argc, reg_t *argv) { + // Tests if the cursor is on the passed object + + uint16 x = argv[0].toUint16(); + uint16 y = argv[1].toUint16(); + reg_t targetObject = argv[2]; + uint16 illegalBits = argv[3].offset; + Common::Rect nsRect; + + // we assume that x, y are local coordinates + + // Get the bounding rectangle of the object + nsRect.left = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsLeft)); + nsRect.top = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsTop)); + nsRect.right = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsRight)); + nsRect.bottom = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsBottom)); + + // nsRect top/left may be negative, adjust accordingly + Common::Rect checkRect = nsRect; + if (checkRect.top < 0) + checkRect.top = 0; + if (checkRect.left < 0) + checkRect.left = 0; + + bool contained = checkRect.contains(x, y); + if (contained && illegalBits) { + // If illegalbits are set, we check the color of the pixel that got clicked on + // for now, we return false if the pixel is transparent + // although illegalBits may get differently set, don't know yet how this really works out + uint16 viewId = readSelectorValue(s->_segMan, targetObject, SELECTOR(view)); + int16 loopNo = readSelectorValue(s->_segMan, targetObject, SELECTOR(loop)); + int16 celNo = readSelectorValue(s->_segMan, targetObject, SELECTOR(cel)); + if (g_sci->_gfxCompare->kernelIsItSkip(viewId, loopNo, celNo, Common::Point(x - nsRect.left, y - nsRect.top))) + contained = false; + } +// these hacks shouldn't be needed anymore +// uint16 itemX = readSelectorValue(s->_segMan, targetObject, SELECTOR(x)); +// uint16 itemY = readSelectorValue(s->_segMan, targetObject, SELECTOR(y)); + + // If top and left are negative, we need to adjust coordinates by + // the item's x and y (e.g. happens in GK1, day 1, with detective + // Mosely's hotspot in his office) + +// if (nsRect.left < 0) +// nsRect.translate(itemX, 0); +// +// if (nsRect.top < 0) +// nsRect.translate(0, itemY); + +// // HACK: nsLeft and nsTop can be invalid, so try and fix them here +// // using x and y (e.g. with the inventory screen in GK1) +// if (nsRect.left == itemY && nsRect.top == itemX) { +// // Swap the values, as they're inversed (eh???) +// nsRect.left = itemX; +// nsRect.top = itemY; +// } + + return make_reg(0, contained); +} + +reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv) { + // Tests if the cursor is on the passed object, after adjusting the + // coordinates of the object according to the object's plane + + uint16 x = argv[0].toUint16(); + uint16 y = argv[1].toUint16(); + reg_t targetObject = argv[2]; + // TODO: argv[3] - it's usually 0 + Common::Rect nsRect; + + // Get the bounding rectangle of the object + nsRect.left = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsLeft)); + nsRect.top = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsTop)); + nsRect.right = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsRight)); + nsRect.bottom = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsBottom)); + + // Get the object's plane +#if 0 + reg_t planeObject = readSelector(s->_segMan, targetObject, SELECTOR(plane)); + if (!planeObject.isNull()) { + //uint16 itemX = readSelectorValue(s->_segMan, targetObject, SELECTOR(x)); + //uint16 itemY = readSelectorValue(s->_segMan, targetObject, SELECTOR(y)); + uint16 planeResY = readSelectorValue(s->_segMan, planeObject, SELECTOR(resY)); + uint16 planeResX = readSelectorValue(s->_segMan, planeObject, SELECTOR(resX)); + uint16 planeTop = readSelectorValue(s->_segMan, planeObject, SELECTOR(top)); + uint16 planeLeft = readSelectorValue(s->_segMan, planeObject, SELECTOR(left)); + planeTop = (planeTop * g_sci->_gfxScreen->getHeight()) / planeResY; + planeLeft = (planeLeft * g_sci->_gfxScreen->getWidth()) / planeResX; + + // Adjust the bounding rectangle of the object by the object's + // actual X, Y coordinates + nsRect.top = ((nsRect.top * g_sci->_gfxScreen->getHeight()) / planeResY); + nsRect.left = ((nsRect.left * g_sci->_gfxScreen->getWidth()) / planeResX); + nsRect.bottom = ((nsRect.bottom * g_sci->_gfxScreen->getHeight()) / planeResY); + nsRect.right = ((nsRect.right * g_sci->_gfxScreen->getWidth()) / planeResX); + + nsRect.translate(planeLeft, planeTop); } +#endif + //warning("kIsOnMe: (%d, %d) on object %04x:%04x, parameter %d", argv[0].toUint16(), argv[1].toUint16(), PRINT_REG(argv[2]), argv[3].toUint16()); - if (videoDecoder) { - playVideo(videoDecoder); + return make_reg(0, nsRect.contains(x, y)); +} - // HACK: Switch back to 8bpp if we played a QuickTime video. - // We also won't be copying the screen to the SCI screen... - if (g_system->getScreenFormat().bytesPerPixel != 1) - initGraphics(screenWidth, screenHeight, screenWidth > 320); - else { - g_sci->_gfxScreen->kernelSyncWithFramebuffer(); - g_sci->_gfxPalette->kernelSyncScreenPalette(); +reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) { + // TODO: argument 0 is usually 0, and arguments 1 and 2 are usually 1 + switch (argv[0].toUint16()) { + case 0: { + if (argc != 4) { + warning("kCreateTextBitmap(0): expected 4 arguments, got %i", argc); + return NULL_REG; } + reg_t object = argv[3]; + Common::String text = s->_segMan->getString(readSelector(s->_segMan, object, SELECTOR(text))); + break; + } + default: + warning("CreateTextBitmap(%d)", argv[0].toUint16()); } - if (reshowCursor) - g_sci->_gfxCursor->kernelShow(); - - return s->r_acc; + return NULL_REG; } -#ifdef ENABLE_SCI32 reg_t kRobot(EngineState *s, int argc, reg_t *argv) { int16 subop = argv[0].toUint16(); @@ -1234,6 +1361,10 @@ reg_t kRobot(EngineState *s, int argc, reg_t *argv) { int16 x = argv[4].toUint16(); int16 y = argv[5].toUint16(); warning("kRobot(init), id %d, obj %04x:%04x, flag %d, x=%d, y=%d", id, PRINT_REG(obj), flag, x, y); + GfxRobot *test = new GfxRobot(g_sci->getResMan(), g_sci->_gfxScreen, id); + test->draw(); + delete test; + } break; case 1: // LSL6 hires (startup) @@ -1255,140 +1386,6 @@ reg_t kRobot(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } -reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) { - uint16 operation = argv[0].toUint16(); - Graphics::VideoDecoder *videoDecoder = 0; - bool reshowCursor = g_sci->_gfxCursor->isVisible(); - Common::String fileName, warningMsg; - - switch (operation) { - case 0: // init - // This is actually meant to init the video file, but we play it instead - fileName = s->_segMan->derefString(argv[1]); - // TODO: argv[2] (usually null). When it exists, it points to an "Event" object, - // that holds no data initially (e.g. in the intro of Phantasmagoria 1 demo). - // Perhaps it's meant for syncing - if (argv[2] != NULL_REG) - warning("kPlayVMD: third parameter isn't 0 (it's %04x:%04x - %s)", PRINT_REG(argv[2]), s->_segMan->getObjectName(argv[2])); - - videoDecoder = new VMDDecoder(g_system->getMixer()); - - if (reshowCursor) - g_sci->_gfxCursor->kernelHide(); - - if (videoDecoder && videoDecoder->loadFile(fileName)) - playVideo(videoDecoder); - - if (reshowCursor) - g_sci->_gfxCursor->kernelShow(); - break; - case 1: - { - // Set VMD parameters. Called with a maximum of 6 parameters: - // - // x, y, flags, gammaBoost, gammaFirst, gammaLast - // - // Flags are as follows: - // bit 0 doubled - // bit 1 "drop frames"? - // bit 2 insert black lines - // bit 3 unknown - // bit 4 gamma correction - // bit 5 hold black frame - // bit 6 hold last frame - // bit 7 unknown - // bit 8 stretch - - // gammaBoost boosts palette colors in the range gammaFirst to - // gammaLast, but only if bit 4 in flags is set. Percent value such that - // 0% = no amplification These three parameters are optional if bit 4 is - // clear. Also note that the x, y parameters play subtle games if used - // with subfx 21. The subtleness has to do with creation of temporary - // planes and positioning relative to such planes. - - int flags = argv[3].offset; - Common::String flagspec; - - if (argc > 3) { - if (flags & 1) - flagspec += "doubled "; - if (flags & 2) - flagspec += "dropframes "; - if (flags & 4) - flagspec += "blacklines "; - if (flags & 8) - flagspec += "bit3 "; - if (flags & 16) - flagspec += "gammaboost "; - if (flags & 32) - flagspec += "holdblack "; - if (flags & 64) - flagspec += "holdlast "; - if (flags & 128) - flagspec += "bit7 "; - if (flags & 256) - flagspec += "stretch"; - - warning("VMDFlags: %s", flagspec.c_str()); - } - - warning("x, y: %d, %d", argv[1].offset, argv[2].offset); - - if (argc > 4 && flags & 16) - warning("gammaBoost: %d%% between palette entries %d and %d", argv[4].offset, argv[5].offset, argv[6].offset); - break; - } - case 6: - // Play, perhaps? Or stop? This is the last call made, and takes no extra parameters - case 14: - // Takes an additional integer parameter (e.g. 3) - case 16: - // Takes an additional parameter, usually 0 - case 21: - // Looks to be setting the video size and position. Called with 4 extra integer - // parameters (e.g. 86, 41, 235, 106) - default: - warningMsg = "PlayVMD - unsupported subop. Params: " + - Common::String::printf("%d", argc) + " ("; - - for (int i = 0; i < argc; i++) { - warningMsg += Common::String::printf("%04x:%04x", PRINT_REG(argv[i])); - warningMsg += (i == argc - 1 ? ")" : ", "); - } - - warning("%s", warningMsg.c_str()); - break; - } - - return s->r_acc; -} - #endif -reg_t kSetVideoMode(EngineState *s, int argc, reg_t *argv) { - // This call is used for KQ6's intro. It has one parameter, which is 1 when - // the intro begins, and 0 when it ends. It is suspected that this is - // actually a flag to enable video planar memory access, as the video - // decoder in KQ6 is specifically written for the planar memory model. - // Planar memory mode access was used for VGA "Mode X" (320x240 resolution, - // although the intro in KQ6 is 320x200). - // Refer to http://en.wikipedia.org/wiki/Mode_X - - //warning("STUB: SetVideoMode %d", argv[0].toUint16()); - return s->r_acc; -} - -// New calls for SCI11. Using those is only needed when using text-codes so that -// one is able to change font and/or color multiple times during kDisplay and -// kDrawControl -reg_t kTextFonts(EngineState *s, int argc, reg_t *argv) { - g_sci->_gfxText16->kernelTextFonts(argc, argv); - return s->r_acc; -} - -reg_t kTextColors(EngineState *s, int argc, reg_t *argv) { - g_sci->_gfxText16->kernelTextColors(argc, argv); - return s->r_acc; -} - } // End of namespace Sci diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp index 0701883a9b..93e95099f5 100644 --- a/engines/sci/engine/klists.cpp +++ b/engines/sci/engine/klists.cpp @@ -34,10 +34,15 @@ static bool isSaneNodePointer(SegManager *segMan, reg_t addr) { reg_t prev = addr; do { - Node *node = segMan->lookupNode(addr); + Node *node = segMan->lookupNode(addr, false); if (!node) { - error("isSaneNodePointer: Node at %04x:%04x wasn't found", PRINT_REG(addr)); + if ((g_sci->getGameId() == GID_ICEMAN) && (g_sci->getEngineState()->currentRoomNumber() == 40)) { + // ICEMAN: when plotting course, unDrawLast is called by startPlot::changeState + // there is no previous entry so we get 0 in here + } else { + error("isSaneNodePointer: Node at %04x:%04x wasn't found", PRINT_REG(addr)); + } return false; } @@ -70,8 +75,8 @@ static void checkListPointer(SegManager *segMan, reg_t addr) { // Empty list is fine } else if (!list->first.isNull() && !list->last.isNull()) { // Normal list - Node *node_a = segMan->lookupNode(list->first); - Node *node_z = segMan->lookupNode(list->last); + Node *node_a = segMan->lookupNode(list->first, false); + Node *node_z = segMan->lookupNode(list->last, false); if (!node_a) { error("checkListPointer (list %04x:%04x): missing first node", PRINT_REG(addr)); @@ -251,6 +256,19 @@ reg_t kNodeValue(EngineState *s, int argc, reg_t *argv) { reg_t kAddToFront(EngineState *s, int argc, reg_t *argv) { addToFront(s, argv[0], argv[1]); + + if (argc == 3) + s->_segMan->lookupNode(argv[1])->key = argv[2]; + + return s->r_acc; +} + +reg_t kAddToEnd(EngineState *s, int argc, reg_t *argv) { + addToEnd(s, argv[0], argv[1]); + + if (argc == 3) + s->_segMan->lookupNode(argv[1])->key = argv[2]; + return s->r_acc; } @@ -294,11 +312,6 @@ reg_t kAddAfter(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } -reg_t kAddToEnd(EngineState *s, int argc, reg_t *argv) { - addToEnd(s, argv[0], argv[1]); - return s->r_acc; -} - reg_t kFindKey(EngineState *s, int argc, reg_t *argv) { reg_t node_pos; reg_t key = argv[1]; @@ -580,65 +593,134 @@ reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } -// In SCI2.1, all the list functions were merged in one reg_t kList(EngineState *s, int argc, reg_t *argv) { + if (!s) + return make_reg(0, getSciVersion()); + error("not supposed to call this"); +} + +reg_t kAddBefore(EngineState *s, int argc, reg_t *argv) { + error("Unimplemented function kAddBefore called"); + return s->r_acc; +} + +reg_t kMoveToFront(EngineState *s, int argc, reg_t *argv) { + error("Unimplemented function kMoveToFront called"); + return s->r_acc; +} + +reg_t kMoveToEnd(EngineState *s, int argc, reg_t *argv) { + error("Unimplemented function kMoveToEnd called"); + return s->r_acc; +} + +reg_t kArray(EngineState *s, int argc, reg_t *argv) { switch (argv[0].toUint16()) { - case 0: - return kNewList(s, argc - 1, argv + 1); - case 1: - return kDisposeList(s, argc - 1, argv + 1); - case 2: - return kNewNode(s, argc - 1, argv + 1); - case 3: - return kFirstNode(s, argc - 1, argv + 1); - case 4: - return kLastNode(s, argc - 1, argv + 1); - case 5: - return kEmptyList(s, argc - 1, argv + 1); - case 6: - return kNextNode(s, argc - 1, argv + 1); - case 7: - return kPrevNode(s, argc - 1, argv + 1); - case 8: - return kNodeValue(s, argc - 1, argv + 1); - case 9: - return kAddAfter(s, argc - 1, argv + 1); - case 10: - return kAddToFront(s, argc - 1, argv + 1); - case 11: - return kAddToEnd(s, argc - 1, argv + 1); - case 12: - error("kList: unimplemented subfunction kAddBefore"); - //return kAddBefore(s, argc - 1, argv + 1); - return NULL_REG; - case 13: - error("kList: unimplemented subfunction kMoveToFront"); - //return kMoveToFront(s, argc - 1, argv + 1); - return NULL_REG; - case 14: - error("kList: unimplemented subfunction kMoveToEnd"); - //return kMoveToEnd(s, argc - 1, argv + 1); - return NULL_REG; - case 15: - return kFindKey(s, argc - 1, argv + 1); - case 16: - return kDeleteKey(s, argc - 1, argv + 1); - case 17: - return kListAt(s, argc - 1, argv + 1); - case 18: - return kListIndexOf(s, argc - 1, argv + 1); - case 19: - return kListEachElementDo(s, argc - 1, argv + 1); - case 20: - return kListFirstTrue(s, argc - 1, argv + 1); - case 21: - return kListAllTrue(s, argc - 1, argv + 1); - case 22: - return kSort(s, argc - 1, argv + 1); + case 0: { // New + reg_t arrayHandle; + SciArray<reg_t> *array = s->_segMan->allocateArray(&arrayHandle); + array->setType(argv[2].toUint16()); + array->setSize(argv[1].toUint16()); + return arrayHandle; + } + case 1: { // Size + SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); + return make_reg(0, array->getSize()); + } + case 2: { // At (return value at an index) + SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); + return array->getValue(argv[2].toUint16()); + } + case 3: { // Atput (put value at an index) + SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); + + uint32 index = argv[2].toUint16(); + uint32 count = argc - 3; + + if (index + count > 65535) + break; + + if (array->getSize() < index + count) + array->setSize(index + count); + + for (uint16 i = 0; i < count; i++) + array->setValue(i + index, argv[i + 3]); + + return argv[1]; // We also have to return the handle + } + case 4: // Free + // Freeing of arrays is handled by the garbage collector + return s->r_acc; + case 5: { // Fill + SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); + uint16 index = argv[2].toUint16(); + + // A count of -1 means fill the rest of the array + uint16 count = argv[3].toSint16() == -1 ? array->getSize() - index : argv[3].toUint16(); + uint16 arraySize = array->getSize(); + + if (arraySize < index + count) + array->setSize(index + count); + + for (uint16 i = 0; i < count; i++) + array->setValue(i + index, argv[4]); + + return argv[1]; + } + case 6: { // Cpy + if (s->_segMan->getSegmentObj(argv[1].segment)->getType() != SEG_TYPE_ARRAY || + s->_segMan->getSegmentObj(argv[3].segment)->getType() != SEG_TYPE_ARRAY) { + // Happens in the RAMA demo + warning("kArray(Cpy): Request to copy a segment which isn't an array, ignoring"); + return NULL_REG; + } + + SciArray<reg_t> *array1 = s->_segMan->lookupArray(argv[1]); + SciArray<reg_t> *array2 = s->_segMan->lookupArray(argv[3]); + uint32 index1 = argv[2].toUint16(); + uint32 index2 = argv[4].toUint16(); + + // The original engine ignores bad copies too + if (index2 > array2->getSize()) + break; + + // A count of -1 means fill the rest of the array + uint32 count = argv[5].toSint16() == -1 ? array2->getSize() - index2 : argv[5].toUint16(); + + if (array1->getSize() < index1 + count) + array1->setSize(index1 + count); + + for (uint16 i = 0; i < count; i++) + array1->setValue(i + index1, array2->getValue(i + index2)); + + return argv[1]; + } + case 7: // Cmp + // Not implemented in SSCI + return s->r_acc; + case 8: { // Dup + SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); + reg_t arrayHandle; + SciArray<reg_t> *dupArray = s->_segMan->allocateArray(&arrayHandle); + + dupArray->setType(array->getType()); + dupArray->setSize(array->getSize()); + + for (uint32 i = 0; i < array->getSize(); i++) + dupArray->setValue(i, array->getValue(i)); + + return arrayHandle; + } + case 9: // Getdata + if (!s->_segMan->isHeapObject(argv[1])) + return argv[1]; + + return readSelector(s->_segMan, argv[1], SELECTOR(data)); default: - error("kList: Unhandled case %d", argv[0].toUint16()); - return NULL_REG; + error("Unknown kArray subop %d", argv[0].toUint16()); } + + return NULL_REG; } #endif diff --git a/engines/sci/engine/kmath.cpp b/engines/sci/engine/kmath.cpp index eab964d624..bdc705cae3 100644 --- a/engines/sci/engine/kmath.cpp +++ b/engines/sci/engine/kmath.cpp @@ -29,10 +29,27 @@ namespace Sci { reg_t kRandom(EngineState *s, int argc, reg_t *argv) { - int fromNumber = argv[0].toUint16(); - int toNumber = argv[1].toUint16(); - double randomNumber = fromNumber + ((toNumber + 1.0 - fromNumber) * (rand() / (RAND_MAX + 1.0))); - return make_reg(0, (int)randomNumber); + switch (argc) { + case 1: // set seed to argv[0] + // SCI0/SCI01 just reset the seed to 0 instead of using argv[0] at all + return NULL_REG; + + case 2: { // get random number + int fromNumber = argv[0].toUint16(); + int toNumber = argv[1].toUint16(); + double randomNumber = fromNumber + ((toNumber + 1.0 - fromNumber) * (rand() / (RAND_MAX + 1.0))); + return make_reg(0, (int)randomNumber); + } + + case 3: // get seed + // SCI0/01 did not support this at all + // Actually we would have to return the previous seed + error("kRandom: scripts asked for previous seed"); + break; + + default: + error("kRandom: unsupported argc"); + } } reg_t kAbs(EngineState *s, int argc, reg_t *argv) { diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index b8c62210f9..305e202ae9 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -368,4 +368,39 @@ reg_t kEmpty(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } +reg_t kStub(EngineState *s, int argc, reg_t *argv) { + Kernel *kernel = g_sci->getKernel(); + int kernelCallNr = -1; + + Common::List<ExecStack>::iterator callIterator = s->_executionStack.end(); + if (callIterator != s->_executionStack.begin()) { + callIterator--; + ExecStack lastCall = *callIterator; + kernelCallNr = lastCall.debugSelector; + } + + Common::String warningMsg = "Dummy function k" + kernel->getKernelName(kernelCallNr) + + Common::String::printf("[%x]", kernelCallNr) + + " invoked. Params: " + + Common::String::printf("%d", argc) + " ("; + + for (int i = 0; i < argc; i++) { + warningMsg += Common::String::printf("%04x:%04x", PRINT_REG(argv[i])); + warningMsg += (i == argc - 1 ? ")" : ", "); + } + + warning("%s", warningMsg.c_str()); + return s->r_acc; +} + +reg_t kStubNull(EngineState *s, int argc, reg_t *argv) { + kStub(s, argc, argv); + return NULL_REG; +} + +reg_t kDummy(EngineState *s, int argc, reg_t *argv) { + kStub(s, argc, argv); + error("Kernel function was called, which was considered to be unused - see log for details"); +} + } // End of namespace Sci diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp index ccef3d862a..114b6eb755 100644 --- a/engines/sci/engine/kmovement.cpp +++ b/engines/sci/engine/kmovement.cpp @@ -267,6 +267,15 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) { bdelta = (int16)readSelectorValue(segMan, mover, SELECTOR(b_incr)); axis = (int16)readSelectorValue(segMan, mover, SELECTOR(b_xAxis)); + if ((getSciVersion() >= SCI_VERSION_1_LATE)) { + // Mixed-Up Fairy Tales has no xLast/yLast selectors + if (SELECTOR(xLast) != -1) { + // save last position into mover + writeSelectorValue(segMan, mover, SELECTOR(xLast), x); + writeSelectorValue(segMan, mover, SELECTOR(yLast), y); + } + } + //printf("movecnt %d, move speed %d\n", movcnt, max_movcnt); if (g_sci->_features->handleMoveCount()) { @@ -316,14 +325,24 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) { debugC(2, kDebugLevelBresen, "New data: (x,y)=(%d,%d), di=%d", x, y, bdi); + bool collision = false; + reg_t cantBeHere = NULL_REG; + if (SELECTOR(cantBeHere) != -1) { + // adding this here for hoyle 3 to get happy. CantBeHere is a dummy in hoyle 3 and acc is != 0 so we would + // get a collision otherwise + s->r_acc = NULL_REG; invokeSelector(s, client, SELECTOR(cantBeHere), argc, argv); - s->r_acc = make_reg(0, !s->r_acc.offset); + if (!s->r_acc.isNull()) + collision = true; + cantBeHere = s->r_acc; } else { invokeSelector(s, client, SELECTOR(canBeHere), argc, argv); + if (s->r_acc.isNull()) + collision = true; } - if (!s->r_acc.offset) { // Contains the return value + if (collision) { signal = readSelectorValue(segMan, client, SELECTOR(signal)); writeSelectorValue(segMan, client, SELECTOR(x), oldx); @@ -331,13 +350,16 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) { writeSelectorValue(segMan, client, SELECTOR(signal), (signal | kSignalHitObstacle)); debugC(2, kDebugLevelBresen, "Finished mover %04x:%04x by collision", PRINT_REG(mover)); - completed = 1; + // We shall not set completed in this case, sierra sci also doesn't do it + // if we set call .moveDone in those cases qfg1 vga gate at the castle and lsl1 casino door will not work } if ((getSciVersion() >= SCI_VERSION_1_EGA)) if (completed) invokeSelector(s, mover, SELECTOR(moveDone), argc, argv); + if (SELECTOR(cantBeHere) != -1) + return cantBeHere; return make_reg(0, completed); } diff --git a/engines/sci/engine/kparse.cpp b/engines/sci/engine/kparse.cpp index 45493a95d2..552e425906 100644 --- a/engines/sci/engine/kparse.cpp +++ b/engines/sci/engine/kparse.cpp @@ -31,6 +31,8 @@ #include "sci/engine/message.h" #include "sci/engine/kernel.h" +//#define DEBUG_PARSER + namespace Sci { /*************************************************************/ @@ -60,8 +62,8 @@ reg_t kSaid(EngineState *s, int argc, reg_t *argv) { } #ifdef DEBUG_PARSER - debugC(2, kDebugLevelParser, "Said block:", 0); - s->_voc->decipherSaidBlock(said_block); + printf("Said block: "); + g_sci->getVocabulary()->debugDecipherSaidBlock(said_block); #endif if (voc->parser_event.isNull() || (readSelectorValue(s->_segMan, voc->parser_event, SELECTOR(claimed)))) { @@ -93,6 +95,7 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) { char *error; ResultWordList words; reg_t event = argv[1]; + g_sci->checkVocabularySwitch(); Vocabulary *voc = g_sci->getVocabulary(); voc->parser_event = event; reg_t params[2] = { voc->parser_base, stringpos }; @@ -106,7 +109,7 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) { s->r_acc = make_reg(0, 1); #ifdef DEBUG_PARSER - debugC(2, kDebugLevelParser, "Parsed to the following blocks:", 0); + debugC(2, kDebugLevelParser, "Parsed to the following blocks:"); for (ResultWordList::const_iterator i = words.begin(); i != words.end(); ++i) debugC(2, kDebugLevelParser, " Type[%04x] Group[%04x]", i->_class, i->_group); diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp index fdaae3e121..fdebc0599c 100644 --- a/engines/sci/engine/kpathing.cpp +++ b/engines/sci/engine/kpathing.cpp @@ -933,9 +933,11 @@ static Common::Point *fixup_start_point(PathfindingState *s, const Common::Point case POLY_NEAREST_ACCESS: if (cont == CONT_INSIDE) { if (s->_prependPoint != NULL) { - // We shouldn't get here twice + // We shouldn't get here twice. + // We need to break in this case, otherwise we'll end in an infinite + // loop. warning("AvoidPath: start point is contained in multiple polygons"); - continue; + break; } if (s->findNearPoint(start, (*it), new_start) != PF_OK) { @@ -944,7 +946,7 @@ static Common::Point *fixup_start_point(PathfindingState *s, const Common::Point } if ((type == POLY_BARRED_ACCESS) || (type == POLY_CONTAINED_ACCESS)) - warning("AvoidPath: start position at unreachable location"); + debugC(2, kDebugLevelAvoidPath, "AvoidPath: start position at unreachable location"); // The original start position is in an invalid location, so we // use the moved point and add the original one to the final path @@ -987,9 +989,14 @@ static Common::Point *fixup_end_point(PathfindingState *s, const Common::Point & case POLY_NEAREST_ACCESS: if (cont != CONT_OUTSIDE) { if (s->_appendPoint != NULL) { - // We shouldn't get here twice + // We shouldn't get here twice. + // Happens in LB2CD, inside the speakeasy when walking from the + // speakeasy (room 310) into the bathroom (room 320), after having + // consulted the notebook (bug #3036299). + // We need to break in this case, otherwise we'll end in an infinite + // loop. warning("AvoidPath: end point is contained in multiple polygons"); - continue; + break; } // The original end position is in an invalid location, so we move the point @@ -1315,7 +1322,7 @@ static void AStar(PathfindingState *s) { } if (openSet.empty()) - warning("[avoidpath] End point (%i, %i) is unreachable", s->vertex_end->v.x, s->vertex_end->v.y); + debugC(2, kDebugLevelAvoidPath, "AvoidPath: End point (%i, %i) is unreachable", s->vertex_end->v.x, s->vertex_end->v.y); } static reg_t allocateOutputArray(SegManager *segMan, int size) { @@ -1770,4 +1777,13 @@ reg_t kMergePoly(EngineState *s, int argc, reg_t *argv) { return output; } +#ifdef ENABLE_SCI32 + +reg_t kInPolygon(EngineState *s, int argc, reg_t *argv) { + // kAvoidPath already implements this + return kAvoidPath(s, argc, argv); +} + +#endif + } // End of namespace Sci diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 029943b070..e211867ef9 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -38,7 +38,7 @@ namespace Sci { // Loads arbitrary resources of type 'restype' with resource numbers 'resnrs' // This implementation ignores all resource numbers except the first one. reg_t kLoad(EngineState *s, int argc, reg_t *argv) { - ResourceType restype = (ResourceType)(argv[0].toUint16() & 0x7f); + ResourceType restype = g_sci->getResMan()->convertResType(argv[0].toUint16()); int resnr = argv[1].toUint16(); // Request to dynamically allocate hunk memory for later use @@ -53,7 +53,7 @@ reg_t kLoad(EngineState *s, int argc, reg_t *argv) { // 1 or 3+ parameters is not right according to sierra sci reg_t kUnLoad(EngineState *s, int argc, reg_t *argv) { if (argc >= 2) { - ResourceType restype = (ResourceType)(argv[0].toUint16() & 0x7f); + ResourceType restype = g_sci->getResMan()->convertResType(argv[0].toUint16()); reg_t resnr = argv[1]; // WORKAROUND for a broken script in room 320 in Castle of Dr. Brain. @@ -73,7 +73,7 @@ reg_t kUnLoad(EngineState *s, int argc, reg_t *argv) { reg_t kLock(EngineState *s, int argc, reg_t *argv) { int state = argc > 2 ? argv[2].toUint16() : 1; - ResourceType type = (ResourceType)(argv[0].toUint16() & 0x7f); + ResourceType type = g_sci->getResMan()->convertResType(argv[0].toUint16()); ResourceId id = ResourceId(type, argv[1].toUint16()); Resource *which; @@ -104,8 +104,10 @@ reg_t kLock(EngineState *s, int argc, reg_t *argv) { if (id.getType() == kResourceTypeInvalid) warning("[resMan] Attempt to unlock resource %i of invalid type %i", id.getNumber(), type); else - // Happens in CD games (e.g. LSL6CD) with the message resource - warning("[resMan] Attempt to unlock non-existant resource %s", id.toString().c_str()); + // Happens in CD games (e.g. LSL6CD) with the message + // resource. It isn't fatal, and it's usually caused + // by leftover scripts. + debugC(2, kDebugLevelResMan, "[resMan] Attempt to unlock non-existant resource %s", id.toString().c_str()); } } break; @@ -115,7 +117,7 @@ reg_t kLock(EngineState *s, int argc, reg_t *argv) { reg_t kResCheck(EngineState *s, int argc, reg_t *argv) { Resource *res = NULL; - ResourceType restype = (ResourceType)(argv[0].toUint16() & 0x7f); + ResourceType restype = g_sci->getResMan()->convertResType(argv[0].toUint16()); if (restype == kResourceTypeVMD) { char fileName[10]; diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index 69ae68674b..4e5ddc5e96 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -54,7 +54,7 @@ CREATE_DOSOUND_FORWARD(DoSoundMute) CREATE_DOSOUND_FORWARD(DoSoundStop) CREATE_DOSOUND_FORWARD(DoSoundStopAll) CREATE_DOSOUND_FORWARD(DoSoundPause) -CREATE_DOSOUND_FORWARD(DoSoundResume) +CREATE_DOSOUND_FORWARD(DoSoundResumeAfterRestore) CREATE_DOSOUND_FORWARD(DoSoundMasterVolume) CREATE_DOSOUND_FORWARD(DoSoundUpdate) CREATE_DOSOUND_FORWARD(DoSoundFade) diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index f2f9543ad2..9254bce9c1 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -566,7 +566,7 @@ reg_t kMessage(EngineState *s, int argc, reg_t *argv) { } reg_t kSetQuitStr(EngineState *s, int argc, reg_t *argv) { - Common::String quitStr = s->_segMan->getString(argv[0]); + //Common::String quitStr = s->_segMan->getString(argv[0]); //debug("Setting quit string to '%s'", quitStr.c_str()); return s->r_acc; } @@ -592,4 +592,193 @@ reg_t kStrSplit(EngineState *s, int argc, reg_t *argv) { return argv[0]; } +#ifdef ENABLE_SCI32 + +reg_t kText(EngineState *s, int argc, reg_t *argv) { + switch (argv[0].toUint16()) { + case 0: + return kTextSize(s, argc - 1, argv + 1); + default: + // TODO: Other subops here too, perhaps kTextColors and kTextFonts + warning("kText(%d)", argv[0].toUint16()); + break; + } + + return s->r_acc; +} + +reg_t kString(EngineState *s, int argc, reg_t *argv) { + switch (argv[0].toUint16()) { + case 0: { // New + reg_t stringHandle; + SciString *string = s->_segMan->allocateString(&stringHandle); + string->setSize(argv[1].toUint16()); + + // Make sure the first character is a null character + if (string->getSize() > 0) + string->setValue(0, 0); + + return stringHandle; + } + case 1: // Size + return make_reg(0, s->_segMan->getString(argv[1]).size()); + case 2: { // At (return value at an index) + if (argv[1].segment == s->_segMan->getStringSegmentId()) + return make_reg(0, s->_segMan->lookupString(argv[1])->getRawData()[argv[2].toUint16()]); + + return make_reg(0, s->_segMan->getString(argv[1])[argv[2].toUint16()]); + } + case 3: { // Atput (put value at an index) + SciString *string = s->_segMan->lookupString(argv[1]); + + uint32 index = argv[2].toUint16(); + uint32 count = argc - 3; + + if (index + count > 65535) + break; + + if (string->getSize() < index + count) + string->setSize(index + count); + + for (uint16 i = 0; i < count; i++) + string->setValue(i + index, argv[i + 3].toUint16()); + + return argv[1]; // We also have to return the handle + } + case 4: // Free + // Freeing of strings is handled by the garbage collector + return s->r_acc; + case 5: { // Fill + SciString *string = s->_segMan->lookupString(argv[1]); + uint16 index = argv[2].toUint16(); + + // A count of -1 means fill the rest of the array + uint16 count = argv[3].toSint16() == -1 ? string->getSize() - index : argv[3].toUint16(); + uint16 stringSize = string->getSize(); + + if (stringSize < index + count) + string->setSize(index + count); + + for (uint16 i = 0; i < count; i++) + string->setValue(i + index, argv[4].toUint16()); + + return argv[1]; + } + case 6: { // Cpy + const char *string2 = 0; + uint32 string2Size = 0; + + if (argv[3].segment == s->_segMan->getStringSegmentId()) { + SciString *string = s->_segMan->lookupString(argv[3]); + string2 = string->getRawData(); + string2Size = string->getSize(); + } else { + Common::String string = s->_segMan->getString(argv[3]); + string2 = string.c_str(); + string2Size = string.size() + 1; + } + + uint32 index1 = argv[2].toUint16(); + uint32 index2 = argv[4].toUint16(); + + // The original engine ignores bad copies too + if (index2 > string2Size) + break; + + // A count of -1 means fill the rest of the array + uint32 count = argv[5].toSint16() == -1 ? string2Size - index2 + 1 : argv[5].toUint16(); + + // We have a special case here for argv[1] being a system string + if (argv[1].segment == s->_segMan->getSysStringsSegment()) { + // Resize if necessary + const uint16 sysStringId = argv[1].toUint16(); + SystemString *sysString = s->_segMan->getSystemString(sysStringId); + assert(sysString); + if ((uint32)sysString->_maxSize < index1 + count) { + free(sysString->_value); + sysString->_maxSize = index1 + count; + sysString->_value = (char *)calloc(index1 + count, sizeof(char)); + } + + strncpy(sysString->_value + index1, string2 + index2, count); + } else { + SciString *string1 = s->_segMan->lookupString(argv[1]); + + if (string1->getSize() < index1 + count) + string1->setSize(index1 + count); + + // Note: We're accessing from c_str() here because the + // string's size ignores the trailing 0 and therefore + // triggers an assert when doing string2[i + index2]. + for (uint16 i = 0; i < count; i++) + string1->setValue(i + index1, string2[i + index2]); + } + + } return argv[1]; + case 7: { // Cmp + Common::String string1 = argv[1].isNull() ? "" : s->_segMan->getString(argv[1]); + Common::String string2 = argv[2].isNull() ? "" : s->_segMan->getString(argv[2]); + + if (argc == 4) // Strncmp + return make_reg(0, strncmp(string1.c_str(), string2.c_str(), argv[3].toUint16())); + else // Strcmp + return make_reg(0, strcmp(string1.c_str(), string2.c_str())); + } + case 8: { // Dup + const char *rawString = 0; + uint32 size = 0; + + if (argv[1].segment == s->_segMan->getStringSegmentId()) { + SciString *string = s->_segMan->lookupString(argv[1]); + rawString = string->getRawData(); + size = string->getSize(); + } else { + Common::String string = s->_segMan->getString(argv[1]); + rawString = string.c_str(); + size = string.size() + 1; + } + + reg_t stringHandle; + SciString *dupString = s->_segMan->allocateString(&stringHandle); + dupString->setSize(size); + + for (uint32 i = 0; i < size; i++) + dupString->setValue(i, rawString[i]); + + return stringHandle; + } + case 9: // Getdata + if (!s->_segMan->isHeapObject(argv[1])) + return argv[1]; + + return readSelector(s->_segMan, argv[1], SELECTOR(data)); + case 10: // Stringlen + return make_reg(0, s->_segMan->strlen(argv[1])); + case 11: { // Printf + reg_t stringHandle; + s->_segMan->allocateString(&stringHandle); + + reg_t *adjustedArgs = new reg_t[argc]; + adjustedArgs[0] = stringHandle; + memcpy(&adjustedArgs[1], argv + 1, (argc - 1) * sizeof(reg_t)); + + kFormat(s, argc, adjustedArgs); + delete[] adjustedArgs; + return stringHandle; + } + case 12: // Printf Buf + return kFormat(s, argc - 1, argv + 1); + case 13: { // atoi + Common::String string = s->_segMan->getString(argv[1]); + return make_reg(0, (uint16)atoi(string.c_str())); + } + default: + error("Unknown kString subop %d", argv[0].toUint16()); + } + + return NULL_REG; +} + +#endif + } // End of namespace Sci diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp new file mode 100644 index 0000000000..cd103dade7 --- /dev/null +++ b/engines/sci/engine/kvideo.cpp @@ -0,0 +1,300 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "engines/util.h" +#include "sci/engine/state.h" +#include "sci/graphics/helpers.h" +#include "sci/graphics/cursor.h" +#include "sci/graphics/palette.h" +#include "sci/graphics/screen.h" +#include "graphics/cursorman.h" +#include "graphics/video/avi_decoder.h" +#include "graphics/video/qt_decoder.h" +#include "sci/video/seq_decoder.h" +#ifdef ENABLE_SCI32 +#include "sci/video/vmd_decoder.h" +#endif + +namespace Sci { + +void playVideo(Graphics::VideoDecoder *videoDecoder) { + if (!videoDecoder) + return; + + byte *scaleBuffer = 0; + uint16 width = videoDecoder->getWidth(); + uint16 height = videoDecoder->getHeight(); + uint16 screenWidth = g_system->getWidth(); + uint16 screenHeight = g_system->getHeight(); + + if (screenWidth == 640 && width <= 320 && height <= 240) { + assert(videoDecoder->getPixelFormat().bytesPerPixel == 1); + width *= 2; + height *= 2; + scaleBuffer = new byte[width * height]; + } + + uint16 x = (screenWidth - width) / 2; + uint16 y = (screenHeight - height) / 2; + bool skipVideo = false; + + while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) { + if (videoDecoder->needsUpdate()) { + Graphics::Surface *frame = videoDecoder->decodeNextFrame(); + if (frame) { + if (scaleBuffer) { + // TODO: Probably should do aspect ratio correction in e.g. GK1 Windows + g_sci->_gfxScreen->scale2x((byte *)frame->pixels, scaleBuffer, videoDecoder->getWidth(), videoDecoder->getHeight()); + g_system->copyRectToScreen(scaleBuffer, width, x, y, width, height); + } else + g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, width, height); + + if (videoDecoder->hasDirtyPalette()) + videoDecoder->setSystemPalette(); + + g_system->updateScreen(); + } + } + + Common::Event event; + while (g_system->getEventManager()->pollEvent(event)) { + if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP) + skipVideo = true; + } + + g_system->delayMillis(10); + } + + delete[] scaleBuffer; + delete videoDecoder; +} + +reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) { + // Hide the cursor if it's showing and then show it again if it was + // previously visible. + bool reshowCursor = g_sci->_gfxCursor->isVisible(); + if (reshowCursor) + g_sci->_gfxCursor->kernelHide(); + + uint16 screenWidth = g_system->getWidth(); + uint16 screenHeight = g_system->getHeight(); + + Graphics::VideoDecoder *videoDecoder = 0; + + if (argv[0].segment != 0) { + Common::String filename = s->_segMan->getString(argv[0]); + + if (g_sci->getPlatform() == Common::kPlatformMacintosh) { + // Mac QuickTime + // The only argument is the string for the video + + // HACK: Switch to 16bpp graphics for Cinepak. + initGraphics(screenWidth, screenHeight, screenWidth > 320, NULL); + + if (g_system->getScreenFormat().bytesPerPixel == 1) { + error("This video requires >8bpp color to be displayed, but could not switch to RGB color mode."); + return NULL_REG; + } + + videoDecoder = new Graphics::QuickTimeDecoder(); + if (!videoDecoder->loadFile(filename)) + error("Could not open '%s'", filename.c_str()); + } else { + // DOS SEQ + // SEQ's are called with no subops, just the string and delay + SeqDecoder *seqDecoder = new SeqDecoder(); + seqDecoder->setFrameDelay(argv[1].toUint16()); // Time between frames in ticks + videoDecoder = seqDecoder; + + if (!videoDecoder->loadFile(filename)) { + warning("Failed to open movie file %s", filename.c_str()); + delete videoDecoder; + videoDecoder = 0; + } + } + } else { + // Windows AVI + // TODO: This appears to be some sort of subop. case 0 contains the string + // for the video, so we'll just play it from there for now. + +#ifdef ENABLE_SCI32 + if (getSciVersion() >= SCI_VERSION_2_1) { + // SCI2.1 always has argv[0] as 1, the rest of the arguments seem to + // follow SCI1.1/2. + if (argv[0].toUint16() != 1) + error("SCI2.1 kShowMovie argv[0] not 1"); + argv++; + argc--; + } +#endif + switch (argv[0].toUint16()) { + case 0: { + Common::String filename = s->_segMan->getString(argv[1]); + videoDecoder = new Graphics::AviDecoder(g_system->getMixer()); + + if (!videoDecoder->loadFile(filename.c_str())) { + warning("Failed to open movie file %s", filename.c_str()); + delete videoDecoder; + videoDecoder = 0; + } + break; + } + default: + warning("Unhandled SCI kShowMovie subop %d", argv[1].toUint16()); + } + } + + if (videoDecoder) { + playVideo(videoDecoder); + + // HACK: Switch back to 8bpp if we played a QuickTime video. + // We also won't be copying the screen to the SCI screen... + if (g_system->getScreenFormat().bytesPerPixel != 1) + initGraphics(screenWidth, screenHeight, screenWidth > 320); + else { + g_sci->_gfxScreen->kernelSyncWithFramebuffer(); + g_sci->_gfxPalette->kernelSyncScreenPalette(); + } + } + + if (reshowCursor) + g_sci->_gfxCursor->kernelShow(); + + return s->r_acc; +} + +#ifdef ENABLE_SCI32 + +reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) { + uint16 operation = argv[0].toUint16(); + Graphics::VideoDecoder *videoDecoder = 0; + bool reshowCursor = g_sci->_gfxCursor->isVisible(); + Common::String fileName, warningMsg; + + switch (operation) { + case 0: // init + // This is actually meant to init the video file, but we play it instead + fileName = s->_segMan->derefString(argv[1]); + // TODO: argv[2] (usually null). When it exists, it points to an "Event" object, + // that holds no data initially (e.g. in the intro of Phantasmagoria 1 demo). + // Perhaps it's meant for syncing + if (argv[2] != NULL_REG) + warning("kPlayVMD: third parameter isn't 0 (it's %04x:%04x - %s)", PRINT_REG(argv[2]), s->_segMan->getObjectName(argv[2])); + + videoDecoder = new VMDDecoder(g_system->getMixer()); + + if (reshowCursor) + g_sci->_gfxCursor->kernelHide(); + + if (videoDecoder && videoDecoder->loadFile(fileName)) + playVideo(videoDecoder); + + if (reshowCursor) + g_sci->_gfxCursor->kernelShow(); + break; + case 1: + { + // Set VMD parameters. Called with a maximum of 6 parameters: + // + // x, y, flags, gammaBoost, gammaFirst, gammaLast + // + // Flags are as follows: + // bit 0 doubled + // bit 1 "drop frames"? + // bit 2 insert black lines + // bit 3 unknown + // bit 4 gamma correction + // bit 5 hold black frame + // bit 6 hold last frame + // bit 7 unknown + // bit 8 stretch + + // gammaBoost boosts palette colors in the range gammaFirst to + // gammaLast, but only if bit 4 in flags is set. Percent value such that + // 0% = no amplification These three parameters are optional if bit 4 is + // clear. Also note that the x, y parameters play subtle games if used + // with subfx 21. The subtleness has to do with creation of temporary + // planes and positioning relative to such planes. + + int flags = argv[3].offset; + Common::String flagspec; + + if (argc > 3) { + if (flags & 1) + flagspec += "doubled "; + if (flags & 2) + flagspec += "dropframes "; + if (flags & 4) + flagspec += "blacklines "; + if (flags & 8) + flagspec += "bit3 "; + if (flags & 16) + flagspec += "gammaboost "; + if (flags & 32) + flagspec += "holdblack "; + if (flags & 64) + flagspec += "holdlast "; + if (flags & 128) + flagspec += "bit7 "; + if (flags & 256) + flagspec += "stretch"; + + warning("VMDFlags: %s", flagspec.c_str()); + } + + warning("x, y: %d, %d", argv[1].offset, argv[2].offset); + + if (argc > 4 && flags & 16) + warning("gammaBoost: %d%% between palette entries %d and %d", argv[4].offset, argv[5].offset, argv[6].offset); + break; + } + case 6: + // Play, perhaps? Or stop? This is the last call made, and takes no extra parameters + case 14: + // Takes an additional integer parameter (e.g. 3) + case 16: + // Takes an additional parameter, usually 0 + case 21: + // Looks to be setting the video size and position. Called with 4 extra integer + // parameters (e.g. 86, 41, 235, 106) + default: + warningMsg = "PlayVMD - unsupported subop. Params: " + + Common::String::printf("%d", argc) + " ("; + + for (int i = 0; i < argc; i++) { + warningMsg += Common::String::printf("%04x:%04x", PRINT_REG(argv[i])); + warningMsg += (i == argc - 1 ? ")" : ", "); + } + + warning("%s", warningMsg.c_str()); + break; + } + + return s->r_acc; +} + +#endif + +} // End of namespace Sci diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp index 18e60eb521..cdecc556e8 100644 --- a/engines/sci/engine/message.cpp +++ b/engines/sci/engine/message.cpp @@ -380,7 +380,14 @@ void MessageState::outputString(reg_t buf, const Common::String &str) { if ((unsigned)buffer_r.maxSize >= str.size() + 1) { _segMan->strcpy(buf, str.c_str()); } else { - warning("Message: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(buf), str.size() + 1, str.c_str()); + // LSL6 sets an exit text here, but the buffer size allocated + // is too small. Don't display a warning in this case, as we + // don't use the exit text anyway - bug report #3035533 + if (g_sci->getGameId() == GID_LSL6 && str.hasPrefix("\r\n(c) 1993 Sierra On-Line, Inc")) { + // LSL6 buggy exit text, don't show warning + } else { + warning("Message: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(buf), str.size() + 1, str.c_str()); + } // Set buffer to empty string if possible if (buffer_r.maxSize > 0) diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 0fe5f2088a..806c8893b4 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -40,6 +40,7 @@ #include "sci/engine/selector.h" #include "sci/engine/vm_types.h" #include "sci/engine/script.h" // for SCI_OBJ_EXPORTS and SCI_OBJ_SYNONYMS +#include "sci/graphics/palette.h" #include "sci/graphics/ports.h" #include "sci/sound/audio.h" #include "sci/sound/music.h" @@ -64,47 +65,20 @@ const uint32 INTMAPPER_MAGIC_KEY = 0xDEADBEEF; #define DEFROBNICATE_HANDLE(handle) (make_reg((handle >> 16) & 0xffff, handle & 0xffff)) void MusicEntry::saveLoadWithSerializer(Common::Serializer &s) { - if (s.getVersion() < 14) { - // Old sound system data. This data is only loaded, never saved (as we're never - // saving in the older version format) - uint32 handle = 0; - s.syncAsSint32LE(handle); - soundObj = DEFROBNICATE_HANDLE(handle); - s.syncAsSint32LE(resourceId); - s.syncAsSint32LE(priority); - s.syncAsSint32LE(status); - s.skip(4); // restoreBehavior - uint32 restoreTime = 0; - s.syncAsSint32LE(restoreTime); - ticker = restoreTime * 60 / 1000; - s.syncAsSint32LE(loop); - s.syncAsSint32LE(hold); - // volume and dataInc will be synced from the sound objects - // when the sound list is reconstructed in gamestate_restore() - volume = MUSIC_VOLUME_MAX; - dataInc = 0; - // No fading info - fadeTo = 0; - fadeStep = 0; - fadeTicker = 0; - fadeTickerStep = 0; - } else { - // A bit more optimized saving - soundObj.saveLoadWithSerializer(s); - s.syncAsSint16LE(resourceId); - s.syncAsSint16LE(dataInc); - s.syncAsSint16LE(ticker); - s.syncAsSint16LE(signal, VER(17)); - s.syncAsByte(priority); - s.syncAsSint16LE(loop, VER(17)); - s.syncAsByte(volume); - s.syncAsByte(hold, VER(17)); - s.syncAsByte(fadeTo); - s.syncAsSint16LE(fadeStep); - s.syncAsSint32LE(fadeTicker); - s.syncAsSint32LE(fadeTickerStep); - s.syncAsByte(status); - } + soundObj.saveLoadWithSerializer(s); + s.syncAsSint16LE(resourceId); + s.syncAsSint16LE(dataInc); + s.syncAsSint16LE(ticker); + s.syncAsSint16LE(signal, VER(17)); + s.syncAsByte(priority); + s.syncAsSint16LE(loop, VER(17)); + s.syncAsByte(volume); + s.syncAsByte(hold, VER(17)); + s.syncAsByte(fadeTo); + s.syncAsSint16LE(fadeStep); + s.syncAsSint32LE(fadeTicker); + s.syncAsSint32LE(fadeTickerStep); + s.syncAsByte(status); // pMidiParser and pStreamAud will be initialized when the // sound list is reconstructed in gamestate_restore() @@ -181,7 +155,7 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { if (s.isLoading()) resetSegMan(); - s.skip(4, VER(12), VER(18)); // OBSOLETE: Used to be _exportsAreWide + s.skip(4, VER(14), VER(18)); // OBSOLETE: Used to be _exportsAreWide if (s.isLoading()) { // Reset _scriptSegMap, to be restored below @@ -256,40 +230,9 @@ static void sync_SavegameMetadata(Common::Serializer &s, SavegameMetadata &obj) void EngineState::saveLoadWithSerializer(Common::Serializer &s) { Common::String tmp; - s.syncString(tmp, VER(12), VER(23)); // OBSOLETE: Used to be game_version - - // OBSOLETE: Saved menus. Skip all of the saved data - if (s.getVersion() < 14) { - int totalMenus = 0; - s.syncAsUint32LE(totalMenus); - - // Now iterate through the obsolete saved menu data - for (int i = 0; i < totalMenus; i++) { - s.syncString(tmp); // OBSOLETE: Used to be _title - s.skip(4, VER(12), VER(12)); // OBSOLETE: Used to be _titleWidth - s.skip(4, VER(12), VER(12)); // OBSOLETE: Used to be _width - - int menuLength = 0; - s.syncAsUint32LE(menuLength); - - for (int j = 0; j < menuLength; j++) { - s.skip(4, VER(12), VER(12)); // OBSOLETE: Used to be _type - s.syncString(tmp); // OBSOLETE: Used to be _keytext - - s.skip(4, VER(12), VER(12)); // OBSOLETE: Used to be _flags - s.skip(64, VER(12), VER(12)); // OBSOLETE: Used to be MENU_SAID_SPEC_SIZE - s.skip(4, VER(12), VER(12)); // OBSOLETE: Used to be _saidPos - s.syncString(tmp); // OBSOLETE: Used to be _text - s.skip(4, VER(12), VER(12)); // OBSOLETE: Used to be _textPos - s.skip(4 * 4, VER(12), VER(12)); // OBSOLETE: Used to be _modifiers, _key, _enabled and _tag - } - } - } + s.syncString(tmp, VER(14), VER(23)); // OBSOLETE: Used to be game_version - s.skip(4, VER(12), VER(12)); // obsolete: used to be status_bar_foreground - s.skip(4, VER(12), VER(12)); // obsolete: used to be status_bar_background - - if (s.getVersion() >= 13 && getSciVersion() <= SCI_VERSION_1_1) { + if (getSciVersion() <= SCI_VERSION_1_1) { // Save/Load picPort as well for SCI0-SCI1.1. Necessary for Castle of Dr. Brain, // as the picPort has been changed when loading during the intro int16 picPortTop, picPortLeft; @@ -312,6 +255,7 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) { _segMan->saveLoadWithSerializer(s); g_sci->_soundCmd->syncPlayList(s); + g_sci->_gfxPalette->saveLoadWithSerializer(s); } void LocalVariables::saveLoadWithSerializer(Common::Serializer &s) { @@ -323,7 +267,6 @@ void LocalVariables::saveLoadWithSerializer(Common::Serializer &s) { void Object::saveLoadWithSerializer(Common::Serializer &s) { s.syncAsSint32LE(_flags); _pos.saveLoadWithSerializer(s); - s.skip(4, VER(12), VER(12)); // OBSOLETE: Used to be variable_names_nr s.syncAsSint32LE(_methodCount); // that's actually a uint16 syncArray<reg_t>(s, _variables); @@ -449,12 +392,12 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) { if (s.isLoading()) init(_nr, g_sci->getResMan()); - s.skip(4, VER(12), VER(22)); // OBSOLETE: Used to be _bufSize - s.skip(4, VER(12), VER(22)); // OBSOLETE: Used to be _scriptSize - s.skip(4, VER(12), VER(22)); // OBSOLETE: Used to be _heapSize + s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _bufSize + s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _scriptSize + s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _heapSize - s.skip(4, VER(12), VER(19)); // OBSOLETE: Used to be _numExports - s.skip(4, VER(12), VER(19)); // OBSOLETE: Used to be _numSynonyms + s.skip(4, VER(14), VER(19)); // OBSOLETE: Used to be _numExports + s.skip(4, VER(14), VER(19)); // OBSOLETE: Used to be _numSynonyms s.syncAsSint32LE(_lockers); // Sync _objects. This is a hashmap, and we use the following on disk format: @@ -482,7 +425,7 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) { } } - s.skip(4, VER(12), VER(20)); // OBSOLETE: Used to be _localsOffset + s.skip(4, VER(14), VER(20)); // OBSOLETE: Used to be _localsOffset s.syncAsSint32LE(_localsSegment); s.syncAsSint32LE(_markedAsDeleted); @@ -599,14 +542,6 @@ void SoundCommandParser::reconstructPlayList(int savegame_version) { (*i)->soundRes = 0; } if ((*i)->status == kSoundPlaying) { - if (savegame_version < 14) { - (*i)->dataInc = readSelectorValue(_segMan, (*i)->soundObj, SELECTOR(dataInc)); - (*i)->signal = readSelectorValue(_segMan, (*i)->soundObj, SELECTOR(signal)); - - if (_soundVersion >= SCI_VERSION_1_LATE) - (*i)->volume = readSelectorValue(_segMan, (*i)->soundObj, SELECTOR(vol)); - } - processPlaySound((*i)->soundObj); } } @@ -628,6 +563,42 @@ void StringTable::saveLoadWithSerializer(Common::Serializer &ser) { } #endif +void GfxPalette::palVarySaveLoadPalette(Common::Serializer &s, Palette *palette) { + s.syncBytes(palette->mapping, 256); + s.syncAsUint32LE(palette->timestamp); + for (int i = 0; i < 256; i++) { + s.syncAsByte(palette->colors[i].used); + s.syncAsByte(palette->colors[i].r); + s.syncAsByte(palette->colors[i].g); + s.syncAsByte(palette->colors[i].b); + } + s.syncBytes(palette->intensity, 256); +} + +void GfxPalette::saveLoadWithSerializer(Common::Serializer &s) { + if (s.getVersion() < 24) + return; + + if (s.isLoading() && _palVaryResourceId != -1) + palVaryRemoveTimer(); + + s.syncAsSint32LE(_palVaryResourceId); + if (_palVaryResourceId != -1) { + palVarySaveLoadPalette(s, &_palVaryOriginPalette); + palVarySaveLoadPalette(s, &_palVaryTargetPalette); + s.syncAsSint16LE(_palVaryStep); + s.syncAsSint16LE(_palVaryStepStop); + s.syncAsSint16LE(_palVaryDirection); + s.syncAsUint16LE(_palVaryTicks); + s.syncAsSint32LE(_palVaryPaused); + } + + if (s.isLoading() && _palVaryResourceId != -1) { + _palVarySignal = 0; + palVaryInstallTimer(); + } +} + void SegManager::reconstructStack(EngineState *s) { DataStack *stack = (DataStack *)(_heap[findSegmentByType(SEG_TYPE_STACK)]); s->stack_base = stack->_entries; @@ -722,6 +693,7 @@ bool gamestate_save(EngineState *s, Common::WriteStream *fh, const char* savenam meta.script0_size = script0->size; meta.game_object_offset = g_sci->getGameObject().offset; + // Checking here again if (s->executionStackBase) { warning("Cannot save from below kernel function"); return false; @@ -804,7 +776,6 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { s->_msgState = new MessageState(s->_segMan); s->abortScriptProcessing = kAbortLoadGame; - s->shrinkStackToBase(); } bool get_savegame_metadata(Common::SeekableReadStream *stream, SavegameMetadata *meta) { diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h index 9a882f2bf7..fc254ba33d 100644 --- a/engines/sci/engine/savegame.h +++ b/engines/sci/engine/savegame.h @@ -36,8 +36,8 @@ namespace Sci { struct EngineState; enum { - CURRENT_SAVEGAME_VERSION = 23, - MINIMUM_SAVEGAME_VERSION = 12 + CURRENT_SAVEGAME_VERSION = 24, + MINIMUM_SAVEGAME_VERSION = 14 }; // Savegame metadata diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index a293f81d2f..645094d9ec 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -434,13 +434,19 @@ void Script::initialiseClasses(SegManager *segMan) { } if (isClass) { - // WORKAROUND for an invalid species access in the demo of LSL2 + // WORKAROUNDs for off-by-one script errors if (g_sci->getGameId() == GID_LSL2 && g_sci->isDemo() && species == (int)segMan->classTableSize()) segMan->resizeClassTable(segMan->classTableSize() + 1); + if (g_sci->getGameId() == GID_LSL3 && !g_sci->isDemo() && _nr == 500 && species == (int)segMan->classTableSize()) + segMan->resizeClassTable(segMan->classTableSize() + 1); + if (g_sci->getGameId() == GID_SQ3 && !g_sci->isDemo() && _nr == 93 && species == (int)segMan->classTableSize()) + segMan->resizeClassTable(segMan->classTableSize() + 1); + if (g_sci->getGameId() == GID_SQ3 && !g_sci->isDemo() && _nr == 99 && species == (int)segMan->classTableSize()) + segMan->resizeClassTable(segMan->classTableSize() + 1); if (species < 0 || species >= (int)segMan->classTableSize()) - error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d\n", - species, species, segMan->classTableSize(), _nr); + error("Invalid species %d(0x%x) unknown max %d(0x%x) while instantiating script %d\n", + species, species, segMan->classTableSize(), segMan->classTableSize(), _nr); SegmentId segmentId = segMan->getScriptSegment(_nr); segMan->setClassOffset(species, make_reg(segmentId, classpos)); @@ -468,8 +474,10 @@ void Script::initialiseObjectsSci0(SegManager *segMan, SegmentId segmentId) { obj->initSpecies(segMan, addr); if (!obj->initBaseObject(segMan, addr)) { - if (_nr == 202 && g_sci->getGameId() == GID_KQ5 && g_sci->getSciLanguage() == K_LANG_FRENCH) { - // Script 202 of KQ5 French has an invalid object. This is non-fatal. + if (_nr == 202 && g_sci->getGameId() == GID_KQ5) { + // WORKAROUND: Script 202 of KQ5 French and German + // (perhaps Spanish too?) has an invalid object. + // This is non-fatal. Refer to bug #3035396. } else { error("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr)); } diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 915a6fa994..9c08526fbb 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -488,48 +488,7 @@ void Kernel::dissectScript(int scriptNumber, Vocabulary *vocab) { Common::hexdump(script->data + seeker, objsize - 4, 16, seeker); printf("%04x: ", seeker); - while (seeker < _seeker) { - unsigned char nextitem = script->data [seeker++]; - if (nextitem == 0xFF) - printf("\n%04x: ", seeker); - else if (nextitem >= 0xF0) { - switch (nextitem) { - case 0xf0: - printf(", "); - break; - case 0xf1: - printf("& "); - break; - case 0xf2: - printf("/ "); - break; - case 0xf3: - printf("( "); - break; - case 0xf4: - printf(") "); - break; - case 0xf5: - printf("[ "); - break; - case 0xf6: - printf("] "); - break; - case 0xf7: - printf("# "); - break; - case 0xf8: - printf("< "); - break; - case 0xf9: - printf("> "); - break; - } - } else { - nextitem = nextitem << 8 | script->data [seeker++]; - printf("%s[%03x] ", vocab->getAnyWordFromGroup(nextitem), nextitem); - } - } + vocab->debugDecipherSaidBlock(script->data + seeker); printf("\n"); break; diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index ef2279e492..25cf1d069f 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -508,7 +508,7 @@ List *SegManager::lookupList(reg_t addr) { return &(lt->_table[addr.offset]); } -Node *SegManager::lookupNode(reg_t addr) { +Node *SegManager::lookupNode(reg_t addr, bool stopOnDiscarded) { if (addr.isNull()) return NULL; // Non-error null @@ -522,6 +522,9 @@ Node *SegManager::lookupNode(reg_t addr) { NodeTable *nt = (NodeTable *)_heap[addr.segment]; if (!nt->isValidEntry(addr.offset)) { + if (!stopOnDiscarded) + return NULL; + error("Attempt to use invalid or discarded reference %04x:%04x as list node", PRINT_REG(addr)); return NULL; } diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index a7f5f8517f..e0808dbb1b 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -232,7 +232,7 @@ public: * @param addr The address to resolve * @return The list node referenced, or NULL on error */ - Node *lookupNode(reg_t addr); + Node *lookupNode(reg_t addr, bool stopOnDiscarded = true); // 8. Hunk Memory diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index 00480743cc..f5eb9eb73a 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -104,6 +104,8 @@ void Kernel::mapSelectors() { FIND_SELECTOR2(b_incr, "b-incr"); FIND_SELECTOR(xStep); FIND_SELECTOR(yStep); + FIND_SELECTOR(xLast); + FIND_SELECTOR(yLast); FIND_SELECTOR(moveSpeed); FIND_SELECTOR(canBeHere); // cantBeHere FIND_SELECTOR(heading); @@ -176,6 +178,13 @@ void Kernel::mapSelectors() { FIND_SELECTOR(dimmed); FIND_SELECTOR(fore); FIND_SELECTOR(back); + FIND_SELECTOR(fixPriority); + FIND_SELECTOR(mirrored); + FIND_SELECTOR(useInsetRect); + FIND_SELECTOR(inTop); + FIND_SELECTOR(inLeft); + FIND_SELECTOR(inBottom); + FIND_SELECTOR(inRight); #endif } @@ -236,7 +245,7 @@ void invokeSelector(EngineState *s, reg_t object, int selectorId, xstack->sp += argc + 2; xstack->fp += argc + 2; - run_vm(s, false); // Start a new vm + run_vm(s); // Start a new vm } SelectorType lookupSelector(SegManager *segMan, reg_t obj_location, Selector selectorId, ObjVarRef *varp, reg_t *fptr) { diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h index acb7912d8d..661290f58c 100644 --- a/engines/sci/engine/selector.h +++ b/engines/sci/engine/selector.h @@ -69,6 +69,7 @@ struct SelectorCache { Selector dx, dy; ///< Deltas Selector b_movCnt, b_i1, b_i2, b_di, b_xAxis, b_incr; ///< Various Bresenham vars Selector xStep, yStep; ///< BR adjustments + Selector xLast, yLast; ///< BR last position of client Selector moveSpeed; ///< Used for DoBresen Selector canBeHere; ///< Funcselector: Checks for movement validity in SCI0 Selector heading, mover; ///< Used in DoAvoider @@ -141,6 +142,12 @@ struct SelectorCache { Selector fore; Selector back; Selector dimmed; + + Selector fixPriority; + Selector mirrored; + + Selector useInsetRect; + Selector inTop, inLeft, inBottom, inRight; #endif }; diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 36b03c0ad9..a069344d61 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -324,4 +324,17 @@ Common::String SciEngine::strSplit(const char *str, const char *sep) { return retval; } +void SciEngine::checkVocabularySwitch() { + uint16 parserLanguage = 1; + if (SELECTOR(parseLang) != -1) + parserLanguage = readSelectorValue(_gamestate->_segMan, _gameObj, SELECTOR(parseLang)); + + if (parserLanguage != _vocabularyLanguage) { + delete _vocabulary; + _vocabulary = new Vocabulary(_resMan, parserLanguage > 1 ? true : false); + _vocabulary->reset(); + _vocabularyLanguage = parserLanguage; + } +} + } // End of namespace Sci diff --git a/engines/sci/engine/static_selectors.cpp b/engines/sci/engine/static_selectors.cpp index 85089e74c8..55e18613e0 100644 --- a/engines/sci/engine/static_selectors.cpp +++ b/engines/sci/engine/static_selectors.cpp @@ -168,6 +168,20 @@ Common::StringArray Kernel::checkStaticSelectorNames() { names[274] = "syncTime"; names[275] = "syncCue"; + } else if (g_sci->getGameId() == GID_ISLANDBRAIN) { + // The demo of Island of Dr. Brain needs the init selector set to match up with the full + // game's workaround - bug #3035033 + if (names.size() < 111) + names.resize(111); + + names[110] = "init"; + } else if (g_sci->getGameId() == GID_LAURABOW2) { + // The floppy of version needs the open selector set to match up with the CD version's + // workaround - bug #3035694 + if (names.size() < 190) + names.resize(190); + + names[189] = "open"; } #ifdef ENABLE_SCI32 diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 8108440102..b7f6896a48 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -38,6 +38,7 @@ #include "sci/engine/seg_manager.h" #include "sci/engine/selector.h" // for SELECTOR #include "sci/engine/gc.h" +#include "sci/engine/workarounds.h" namespace Sci { @@ -48,86 +49,6 @@ const reg_t TRUE_REG = {0, 1}; #define SCI_XS_CALLEE_LOCALS ((SegmentId)-1) -#define END Script_None - -opcode_format g_opcode_formats[128][4] = { - /*00*/ - {Script_None}, {Script_None}, {Script_None}, {Script_None}, - /*04*/ - {Script_None}, {Script_None}, {Script_None}, {Script_None}, - /*08*/ - {Script_None}, {Script_None}, {Script_None}, {Script_None}, - /*0C*/ - {Script_None}, {Script_None}, {Script_None}, {Script_None}, - /*10*/ - {Script_None}, {Script_None}, {Script_None}, {Script_None}, - /*14*/ - {Script_None}, {Script_None}, {Script_None}, {Script_SRelative, END}, - /*18*/ - {Script_SRelative, END}, {Script_SRelative, END}, {Script_SVariable, END}, {Script_None}, - /*1C*/ - {Script_SVariable, END}, {Script_None}, {Script_None}, {Script_Variable, END}, - /*20*/ - {Script_SRelative, Script_Byte, END}, {Script_Variable, Script_Byte, END}, {Script_Variable, Script_Byte, END}, {Script_Variable, Script_SVariable, Script_Byte, END}, - /*24 (24=ret)*/ - {Script_End}, {Script_Byte, END}, {Script_Invalid}, {Script_Invalid}, - /*28*/ - {Script_Variable, END}, {Script_Invalid}, {Script_Byte, END}, {Script_Variable, Script_Byte, END}, - /*2C*/ - {Script_SVariable, END}, {Script_SVariable, Script_Variable, END}, {Script_None}, {Script_Invalid}, - /*30*/ - {Script_None}, {Script_Property, END}, {Script_Property, END}, {Script_Property, END}, - /*34*/ - {Script_Property, END}, {Script_Property, END}, {Script_Property, END}, {Script_Property, END}, - /*38*/ - {Script_Property, END}, {Script_SRelative, END}, {Script_SRelative, END}, {Script_None}, - /*3C*/ - {Script_None}, {Script_None}, {Script_None}, {Script_Word}, - /*40-4F*/ - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - /*50-5F*/ - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - /*60-6F*/ - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - /*70-7F*/ - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END}, - {Script_Global, END}, {Script_Local, END}, {Script_Temp, END}, {Script_Param, END} -}; -#undef END - -// TODO: script_adjust_opcode_formats should probably be part of the -// constructor (?) of a VirtualMachine or a ScriptManager class. -void script_adjust_opcode_formats() { - if (g_sci->_features->detectLofsType() != SCI_VERSION_0_EARLY) { - g_opcode_formats[op_lofsa][0] = Script_Offset; - g_opcode_formats[op_lofss][0] = Script_Offset; - } - -#ifdef ENABLE_SCI32 - // In SCI32, some arguments are now words instead of bytes - if (getSciVersion() >= SCI_VERSION_2) { - g_opcode_formats[op_calle][2] = Script_Word; - g_opcode_formats[op_callk][1] = Script_Word; - g_opcode_formats[op_super][1] = Script_Word; - g_opcode_formats[op_send][0] = Script_Word; - g_opcode_formats[op_self][0] = Script_Word; - g_opcode_formats[op_call][1] = Script_Word; - g_opcode_formats[op_callb][1] = Script_Word; - } -#endif -} - /** * Adds an entry to the top of the execution stack. * @@ -248,7 +169,7 @@ static bool validate_variable(reg_t *r, reg_t *stack_base, int type, int max, in } else { // WORKAROUND: Mixed-Up Mother Goose tries to use an invalid parameter in Event::new(). // Just skip around it here so we don't error out in validate_arithmetic. - if (g_sci->getGameId() == GID_MOTHERGOOSE && getSciVersion() <= SCI_VERSION_1_1 && type == VAR_PARAM && index == 1) + if (g_sci->getGameId() == GID_MOTHERGOOSE && type == VAR_PARAM && index == 1) return false; debugC(2, kDebugLevelVM, "%s", txt.c_str()); @@ -262,109 +183,33 @@ static bool validate_variable(reg_t *r, reg_t *stack_base, int type, int max, in return true; } -struct SciTrackOriginReply { - int scriptNr; - Common::String objectName; - Common::String methodName; - int localCallOffset; -}; - -static reg_t trackOriginAndFindWorkaround(int index, const SciWorkaroundEntry *workaroundList, SciTrackOriginReply *trackOrigin) { - EngineState *state = g_sci->getEngineState(); - ExecStack *lastCall = state->xs; - Script *local_script = state->_segMan->getScriptIfLoaded(lastCall->local_segment); - int curScriptNr = local_script->getScriptNumber(); - - if (lastCall->debugLocalCallOffset != -1) { - // if lastcall was actually a local call search back for a real call - Common::List<ExecStack>::iterator callIterator = state->_executionStack.end(); - while (callIterator != state->_executionStack.begin()) { - callIterator--; - ExecStack loopCall = *callIterator; - if ((loopCall.debugSelector != -1) || (loopCall.debugExportId != -1)) { - lastCall->debugSelector = loopCall.debugSelector; - lastCall->debugExportId = loopCall.debugExportId; - break; - } - } - } - - Common::String curObjectName = state->_segMan->getObjectName(lastCall->sendp); - Common::String curMethodName; - const SciGameId gameId = g_sci->getGameId(); - - if (lastCall->type == EXEC_STACK_TYPE_CALL) { - if (lastCall->debugSelector != -1) { - curMethodName = g_sci->getKernel()->getSelectorName(lastCall->debugSelector); - } else if (lastCall->debugExportId != -1) { - curObjectName = ""; - curMethodName = curMethodName.printf("export %d", lastCall->debugExportId); - } - } - - if (workaroundList) { - // Search if there is a workaround for this one - const SciWorkaroundEntry *workaround; - int16 inheritanceLevel = 0; - Common::String searchObjectName = curObjectName; - reg_t searchObject = lastCall->sendp; - do { - workaround = workaroundList; - while (workaround->objectName) { - if (workaround->gameId == gameId && workaround->scriptNr == curScriptNr - && ((workaround->inheritanceLevel == -1) || (workaround->inheritanceLevel == inheritanceLevel)) - && (workaround->objectName == searchObjectName) - && workaround->methodName == curMethodName && workaround->localCallOffset == lastCall->debugLocalCallOffset && workaround->index == index) { - // Workaround found - return workaround->newValue; - } - workaround++; - } - - // Go back to the parent - inheritanceLevel++; - searchObject = state->_segMan->getObject(searchObject)->getSuperClassSelector(); - if (!searchObject.isNull()) - searchObjectName = state->_segMan->getObjectName(searchObject); - } while (!searchObject.isNull()); // no parent left? - } +static bool validate_unsignedInteger(reg_t reg, uint16 &integer) { + if (reg.segment) + return false; + integer = reg.offset; + return true; +} - // give caller origin data - trackOrigin->objectName = curObjectName; - trackOrigin->methodName = curMethodName; - trackOrigin->scriptNr = curScriptNr; - trackOrigin->localCallOffset = lastCall->debugLocalCallOffset; - return make_reg(0xFFFF, 0xFFFF); +static bool validate_signedInteger(reg_t reg, int16 &integer) { + if (reg.segment) + return false; + integer = (int16)reg.offset; + return true; } -// gameID, scriptNr,lvl, object-name, method-name, call, index, replace -static const SciWorkaroundEntry uninitializedReadWorkarounds[] = { - { GID_LAURABOW2, 24, 0, "gcWin", "open", -1, 5, { 0, 0xf } }, // is used as priority for game menu - { GID_FREDDYPHARKAS, 24, 0, "gcWin", "open", -1, 5, { 0, 0xf } }, // is used as priority for game menu - { GID_FREDDYPHARKAS, 31, 0, "quitWin", "open", -1, 5, { 0, 0xf } }, // is used as priority for game menu - { GID_GK2, 11, 0, "", "export 10", -1, 3, { 0, 0 } }, // called when the game starts - { GID_JONES, 232, 0, "weekendText", "draw", 0x3d3, 0, { 0, 0 } }, // jones/cd only - gets called during the game - { GID_JONES, 255, 0, "", "export 0", -1, 13, { 0, 0 } }, // jones/ega&vga only - called when the game starts - { GID_JONES, 255, 0, "", "export 0", -1, 14, { 0, 0 } }, // jones/ega&vga only - called when the game starts - { GID_LSL1, 720, 0, "rm720", "init", -1, 0, { 0, 0 } }, // age check room - { GID_LSL3, 997, 0, "TheMenuBar", "handleEvent", -1, 1, { 0, 0xf } }, // when setting volume the first time, this temp is used to set volume on entry (normally it would have been initialized to 's') - { GID_LSL6, 928, -1, "Narrator", "startText", -1, 0, { 0, 0 } }, // used by various objects that are even translated in foreign versions, that's why we use the base-class - { GID_ISLANDBRAIN, 140, 0, "piece", "init", -1, 3, { 0, 1 } }, // first puzzle right at the start, some initialization variable. bnt is done on it, and it should be non-0 - { GID_ISLANDBRAIN, 268, 0, "anElement", "select", -1, 0, { 0, 0 } }, // elements puzzle, gets used before super TextIcon - { GID_KQ5, 0, 0, "", "export 29", -1, 3, { 0, 0 } }, // called when playing harp for the harpies, is used for kDoAudio - { GID_KQ5, 25, 0, "rm025", "doit", -1, 0, { 0, 0 } }, // inside witch forest, where the walking rock is - { GID_KQ6, 903, 0, "controlWin", "open", -1, 4, { 0, 0 } }, // when opening the controls window (save, load etc) - { GID_KQ6, 500, 0, "rm500", "init", -1, 0, { 0, 0 } }, // going to island of the beast - { GID_KQ6, 520, 0, "rm520", "init", -1, 0, { 0, 0 } }, // going to boiling water trap on beast isle - { GID_KQ6, 30, 0, "rats", "changeState", -1, 0, { 0, 0 } }, // rats in the catacombs - { GID_LSL6, 85, 0, "washcloth", "doVerb", -1, 0, { 0, 0 } }, // washcloth in inventory - { GID_SQ1, 703, 0, "", "export 1", -1, 0, { 0, 0 } }, // sub that's called from several objects while on sarien battle cruiser - { GID_SQ1, 703, 0, "firePulsar", "changeState", 0x18a, 0, { 0, 0 } }, // export 1, but called locally (when shooting at aliens) - { GID_SQ4, 928, 0, "Narrator", "startText", -1, 1000, { 0, 1 } }, // sq4cd: method returns this to the caller - { GID_SQ6, 0, 0, "SQ6", "init", -1, 2, { 0, 0 } }, // called when the game starts - { GID_SQ6, 64950, 0, "View", "handleEvent", -1, 0, { 0, 0 } }, // called when pressing "Start game" in the main menu - SCI_WORKAROUNDENTRY_TERMINATOR -}; +extern const char *opcodeNames[]; // from scriptdebug.cpp + +static reg_t arithmetic_lookForWorkaround(const byte opcode, const SciWorkaroundEntry *workaroundList, reg_t value1, reg_t value2) { + SciTrackOriginReply originReply; + SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, workaroundList, &originReply); + if (solution.type == WORKAROUND_NONE) + error("%s on non-integer (%04x:%04x, %04x:%04x) from method %s::%s (script %d, room %d, localCall %x)", + opcodeNames[opcode], PRINT_REG(value1), PRINT_REG(value2), originReply.objectName.c_str(), + originReply.methodName.c_str(), originReply.scriptNr, g_sci->getEngineState()->currentRoomNumber(), + originReply.localCallOffset); + assert(solution.type == WORKAROUND_FAKE); + return make_reg(0, solution.value); +} static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, int index, reg_t default_value) { if (validate_variable(r, stack_base, type, max, index)) { @@ -374,9 +219,13 @@ static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, i // Uninitialized read on a temp // We need to find correct replacements for each situation manually SciTrackOriginReply originReply; - r[index] = trackOriginAndFindWorkaround(index, uninitializedReadWorkarounds, &originReply); - if ((r[index].segment == 0xFFFF) && (r[index].offset == 0xFFFF)) - error("Uninitialized read for temp %d from method %s::%s (script %d, localCall %x)", index, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, originReply.localCallOffset); + SciWorkaroundSolution solution = trackOriginAndFindWorkaround(index, uninitializedReadWorkarounds, &originReply); + if (solution.type == WORKAROUND_NONE) + error("Uninitialized read for temp %d from method %s::%s (script %d, room %d, localCall %x)", + index, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, + g_sci->getEngineState()->currentRoomNumber(), originReply.localCallOffset); + assert(solution.type == WORKAROUND_FAKE); + r[index] = make_reg(0, solution.value); break; } case VAR_PARAM: @@ -440,12 +289,9 @@ static void validate_write_var(reg_t *r, reg_t *stack_base, int type, int max, i #define WRITE_VAR(type, index, value) validate_write_var(s->variables[type], s->stack_base, type, s->variablesMax[type], index, value, s->_segMan, g_sci->getKernel()) #define WRITE_VAR16(type, index, value) WRITE_VAR(type, index, make_reg(0, value)); -#define ACC_ARITHMETIC_L(op) make_reg(0, (op validate_arithmetic(s->r_acc))) - // Operating on the stack // 16 bit: #define PUSH(v) PUSH32(make_reg(0, v)) -#define POP() (validate_arithmetic(POP32())) // 32 bit: #define PUSH32(a) (*(validate_stack_addr(s, (s->xs->sp)++)) = (a)) #define POP32() (*(validate_stack_addr(s, --(s->xs->sp)))) @@ -618,29 +464,17 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt if (argc > 1) { // argc can indeed be bigger than 1 in some cases, and it's usually the - // result of a script bug + // result of a script bug. Usually these aren't fatal. const char *objectName = s->_segMan->getObjectName(send_obj); - if (!strcmp(objectName, "Sq4GlobalNarrator") && selector == 606) { - // SQ4 has a script bug in the Sq4GlobalNarrator object when invoking the - // returnVal selector, which doesn't affect gameplay, thus don't diplay it - } else if (!strcmp(objectName, "longSong") && selector == 3 && g_sci->getGameId() == GID_QFG1) { - // QFG1VGA has a script bug in the longSong object when invoking the - // loop selector, which doesn't affect gameplay, thus don't diplay it - } else if (!strcmp(objectName, "PuzPiece") && selector == 77 && g_sci->getGameId() == GID_CASTLEBRAIN) { - // Castle of Dr. Brain has a script bug in the PuzPiece object when invoking - // the value selector, which doesn't affect gameplay, thus don't display it - } else { - // Unknown script bug, show it. Usually these aren't fatal. - reg_t oldReg = *varp.getPointer(s->_segMan); - reg_t newReg = argp[1]; - const char *selectorName = g_sci->getKernel()->getSelectorName(selector).c_str(); - warning("send_selector(): argc = %d while modifying variable selector " - "%x (%s) of object %04x:%04x (%s) from %04x:%04x to %04x:%04x", - argc, selector, selectorName, PRINT_REG(send_obj), - objectName, PRINT_REG(oldReg), PRINT_REG(newReg)); - } + reg_t oldReg = *varp.getPointer(s->_segMan); + reg_t newReg = argp[1]; + const char *selectorName = g_sci->getKernel()->getSelectorName(selector).c_str(); + debug(2, "send_selector(): argc = %d while modifying variable selector " + "%x (%s) of object %04x:%04x (%s) from %04x:%04x to %04x:%04x", + argc, selector, selectorName, PRINT_REG(send_obj), + objectName, PRINT_REG(oldReg), PRINT_REG(newReg)); } { @@ -813,6 +647,61 @@ static void addKernelCallToExecStack(EngineState *s, int kernelCallNr, int argc, xstack->type = EXEC_STACK_TYPE_KERNEL; } +static void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *kernelSubCall, EngineState *s, int argc, reg_t *argv, reg_t result) { + Kernel *kernel = g_sci->getKernel(); + if (!kernelSubCall) { + printf("k%s: ", kernelCall->name); + } else { + int callNameLen = strlen(kernelCall->name); + if (strncmp(kernelCall->name, kernelSubCall->name, callNameLen) == 0) { + const char *subCallName = kernelSubCall->name + callNameLen; + printf("k%s(%s): ", kernelCall->name, subCallName); + } else { + printf("k%s(%s): ", kernelCall->name, kernelSubCall->name); + } + } + for (int parmNr = 0; parmNr < argc; parmNr++) { + if (parmNr) + printf(", "); + uint16 regType = kernel->findRegType(argv[parmNr]); + if (regType & SIG_TYPE_NULL) + printf("0"); + else if (regType & SIG_TYPE_UNINITIALIZED) + printf("UNINIT"); + else if (regType & SIG_IS_INVALID) + printf("INVALID"); + else if (regType & SIG_TYPE_INTEGER) + printf("%d", argv[parmNr].offset); + else { + printf("%04x:%04x", PRINT_REG(argv[parmNr])); + switch (regType) { + case SIG_TYPE_OBJECT: + printf(" (%s)", s->_segMan->getObjectName(argv[parmNr])); + break; + case SIG_TYPE_REFERENCE: + if (kernelCall->function == kSaid) { + SegmentRef saidSpec = s->_segMan->dereference(argv[parmNr]); + if (saidSpec.isRaw) { + printf(" ('"); + g_sci->getVocabulary()->debugDecipherSaidBlock(saidSpec.raw); + printf("')"); + } else { + printf(" (non-raw said-spec)"); + } + } else { + printf(" ('%s')", s->_segMan->getString(argv[parmNr]).c_str()); + } + default: + break; + } + } + } + if (result.segment) + printf(" = %04x:%04x\n", PRINT_REG(result)); + else + printf(" = %d\n", result.offset); +} + static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) { Kernel *kernel = g_sci->getKernel(); @@ -826,17 +715,24 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) { && !kernel->signatureMatch(kernelCall.signature, argc, argv)) { // signature mismatch, check if a workaround is available SciTrackOriginReply originReply; - reg_t workaround; - workaround = trackOriginAndFindWorkaround(0, kernelCall.workarounds, &originReply); - if ((workaround.segment == 0xFFFF) && (workaround.offset == 0xFFFF)) { + SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, kernelCall.workarounds, &originReply); + switch (solution.type) { + case WORKAROUND_NONE: kernel->signatureDebug(kernelCall.signature, argc, argv); - error("[VM] k%s[%x]: signature mismatch via method %s::%s (script %d, localCall %x)", kernelCall.name, kernelCallNr, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, originReply.localCallOffset); - } - // FIXME: implement some real workaround type logic - ignore call, still do call etc. - if (workaround.segment == 2) - s->r_acc = make_reg(0, workaround.offset); - if (workaround.segment) + error("[VM] k%s[%x]: signature mismatch via method %s::%s (script %d, room %d, localCall 0x%x)", + kernelCall.name, kernelCallNr, originReply.objectName.c_str(), originReply.methodName.c_str(), + originReply.scriptNr, s->currentRoomNumber(), originReply.localCallOffset); + break; + case WORKAROUND_IGNORE: // don't do kernel call, leave acc alone + return; + case WORKAROUND_STILLCALL: // call kernel anyway + break; + case WORKAROUND_FAKE: // don't do kernel call, fake acc + s->r_acc = make_reg(0, solution.value); return; + default: + error("unknown workaround type"); + } } @@ -844,6 +740,9 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) { if (!kernelCall.subFunctionCount) { addKernelCallToExecStack(s, kernelCallNr, argc, argv); s->r_acc = kernelCall.function(s, argc, argv); + + if (kernelCall.debugLogging) + logKernelCall(&kernelCall, NULL, s, argc, argv, s->r_acc); } else { // Sub-functions available, check signature and call that one directly if (argc < 1) @@ -860,43 +759,41 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) { if (kernelSubCall.signature && !kernel->signatureMatch(kernelSubCall.signature, argc, argv)) { // Signature mismatch SciTrackOriginReply originReply; - reg_t workaround; - workaround = trackOriginAndFindWorkaround(0, kernelSubCall.workarounds, &originReply); - if ((workaround.segment == 0xFFFF) && (workaround.offset == 0xFFFF)) { + SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, kernelSubCall.workarounds, &originReply); + switch (solution.type) { + case WORKAROUND_NONE: { kernel->signatureDebug(kernelSubCall.signature, argc, argv); int callNameLen = strlen(kernelCall.name); if (strncmp(kernelCall.name, kernelSubCall.name, callNameLen) == 0) { const char *subCallName = kernelSubCall.name + callNameLen; - error("[VM] k%s(%s): signature mismatch via method %s::%s (script %d, localCall %x)", kernelCall.name, subCallName, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, originReply.localCallOffset); + error("[VM] k%s(%s): signature mismatch via method %s::%s (script %d, room %d, localCall %x)", + kernelCall.name, subCallName, originReply.objectName.c_str(), originReply.methodName.c_str(), + originReply.scriptNr, s->currentRoomNumber(), originReply.localCallOffset); } - error("[VM] k%s: signature mismatch via method %s::%s (script %d, localCall %x)", kernelSubCall.name, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, originReply.localCallOffset); + error("[VM] k%s: signature mismatch via method %s::%s (script %d, room %d, localCall %x)", + kernelSubCall.name, originReply.objectName.c_str(), originReply.methodName.c_str(), + originReply.scriptNr, s->currentRoomNumber(), originReply.localCallOffset); + break; } - // FIXME: implement some real workaround type logic - ignore call, still do call etc. - if (workaround.segment == 2) - s->r_acc = make_reg(0, workaround.offset); - if (workaround.segment) + case WORKAROUND_IGNORE: // don't do kernel call, leave acc alone + return; + case WORKAROUND_STILLCALL: // call kernel anyway + break; + case WORKAROUND_FAKE: // don't do kernel call, fake acc + s->r_acc = make_reg(0, solution.value); return; + default: + error("unknown workaround type"); + } } if (!kernelSubCall.function) error("[VM] k%s: subfunction-id %d requested, but not available", kernelCall.name, subId); addKernelCallToExecStack(s, kernelCallNr, argc, argv); s->r_acc = kernelSubCall.function(s, argc, argv); - } - -#if 0 - // Used for debugging - Common::String debugMsg = Common::String::printf("%s [0x%x]", kernelCall.name, kernelCallNr) + - Common::String::printf(", %d params: ", argc) + - " ("; - for (int i = 0; i < argc; i++) { - debugMsg += Common::String::printf("%04x:%04x", PRINT_REG(argv[i])); - debugMsg += (i == argc - 1 ? ")" : ", "); - } - - debugMsg += ", result: " + Common::String::printf("%04x:%04x", PRINT_REG(s->r_acc)); - debug("%s", debugMsg.c_str()); -#endif + if (kernelSubCall.debugLogging) + logKernelCall(&kernelCall, &kernelSubCall, s, argc, argv, s->r_acc); + } // Remove callk stack frame again, if there's still an execution stack if (s->_executionStack.begin() != s->_executionStack.end()) @@ -978,7 +875,7 @@ int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4]) return offset; } -void run_vm(EngineState *s, bool restoring) { +void run_vm(EngineState *s) { assert(s); int temp; @@ -999,8 +896,7 @@ void run_vm(EngineState *s, bool restoring) { if (!local_script) error("run_vm(): program counter gone astray (local_script pointer is null)"); - if (!restoring) - s->executionStackBase = s->_executionStack.size() - 1; + s->executionStackBase = s->_executionStack.size() - 1; s->variablesSegment[VAR_TEMP] = s->variablesSegment[VAR_PARAM] = s->_segMan->findSegmentByType(SEG_TYPE_STACK); s->variablesBase[VAR_TEMP] = s->variablesBase[VAR_PARAM] = s->stack_base; @@ -1059,9 +955,7 @@ void run_vm(EngineState *s, bool restoring) { g_sci->_debugState.breakpointWasHit = false; } Console *con = g_sci->getSciDebugger(); - if (con->isAttached()) { - con->onFrame(); - } + con->onFrame(); if (s->xs->sp < s->xs->fp) error("run_vm(): stack underflow, sp: %04x:%04x, fp: %04x:%04x", @@ -1080,10 +974,15 @@ void run_vm(EngineState *s, bool restoring) { switch (opcode) { - case op_bnot: // 0x00 (00) + case op_bnot: { // 0x00 (00) // Binary not - s->r_acc = ACC_ARITHMETIC_L(0xffff ^ /*acc*/); + int16 value; + if (validate_signedInteger(s->r_acc, value)) + s->r_acc = make_reg(0, 0xffff ^ value); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, s->r_acc, NULL_REG); break; + } case op_add: // 0x01 (01) r_temp = POP32(); @@ -1148,45 +1047,96 @@ void run_vm(EngineState *s, bool restoring) { } break; - case op_mul: // 0x03 (03) - s->r_acc = ACC_ARITHMETIC_L(((int16)POP()) * (int16)/*acc*/); + case op_mul: { // 0x03 (03) + r_temp = POP32(); + int16 value1, value2; + if (validate_signedInteger(s->r_acc, value1) && validate_signedInteger(r_temp, value2)) + s->r_acc = make_reg(0, value1 * value2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, s->r_acc, r_temp); break; + } case op_div: { // 0x04 (04) - int16 divisor = signed_validate_arithmetic(s->r_acc); - s->r_acc = make_reg(0, (divisor != 0 ? ((int16)POP()) / divisor : 0)); + r_temp = POP32(); + int16 divisor, dividend; + if (validate_signedInteger(s->r_acc, divisor) && validate_signedInteger(r_temp, dividend)) + s->r_acc = make_reg(0, (divisor != 0 ? dividend / divisor : 0)); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, opcodeDivWorkarounds, s->r_acc, r_temp); break; } + case op_mod: { // 0x05 (05) - int16 modulo = signed_validate_arithmetic(s->r_acc); - s->r_acc = make_reg(0, (modulo != 0 ? ((int16)POP()) % modulo : 0)); + r_temp = POP32(); + int16 modulo, value; + if (validate_signedInteger(s->r_acc, modulo) && validate_signedInteger(r_temp, value)) + s->r_acc = make_reg(0, (modulo != 0 ? value % modulo : 0)); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, s->r_acc, r_temp); break; } - case op_shr: // 0x06 (06) + + case op_shr: { // 0x06 (06) // Shift right logical - s->r_acc = ACC_ARITHMETIC_L(((uint16)POP()) >> /*acc*/); + r_temp = POP32(); + uint16 value, shiftCount; + if (validate_unsignedInteger(r_temp, value) && validate_unsignedInteger(s->r_acc, shiftCount)) + s->r_acc = make_reg(0, value >> shiftCount); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); break; + } - case op_shl: // 0x07 (07) + case op_shl: { // 0x07 (07) // Shift left logical - s->r_acc = ACC_ARITHMETIC_L(((uint16)POP()) << /*acc*/); + r_temp = POP32(); + uint16 value, shiftCount; + if (validate_unsignedInteger(r_temp, value) && validate_unsignedInteger(s->r_acc, shiftCount)) + s->r_acc = make_reg(0, value << shiftCount); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); break; + } - case op_xor: // 0x08 (08) - s->r_acc = ACC_ARITHMETIC_L(POP() ^ /*acc*/); + case op_xor: { // 0x08 (08) + r_temp = POP32(); + uint16 value1, value2; + if (validate_unsignedInteger(r_temp, value1) && validate_unsignedInteger(s->r_acc, value2)) + s->r_acc = make_reg(0, value1 ^ value2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); break; + } - case op_and: // 0x09 (09) - s->r_acc = ACC_ARITHMETIC_L(POP() & /*acc*/); + case op_and: { // 0x09 (09) + r_temp = POP32(); + uint16 value1, value2; + if (validate_unsignedInteger(r_temp, value1) && validate_unsignedInteger(s->r_acc, value2)) + s->r_acc = make_reg(0, value1 & value2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); break; + } - case op_or: // 0x0a (10) - s->r_acc = ACC_ARITHMETIC_L(POP() | /*acc*/); + case op_or: { // 0x0a (10) + r_temp = POP32(); + uint16 value1, value2; + if (validate_unsignedInteger(r_temp, value1) && validate_unsignedInteger(s->r_acc, value2)) + s->r_acc = make_reg(0, value1 | value2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, opcodeOrWorkarounds, r_temp, s->r_acc); break; + } - case op_neg: // 0x0b (11) - s->r_acc = ACC_ARITHMETIC_L(-/*acc*/); + case op_neg: { // 0x0b (11) + int16 value; + if (validate_signedInteger(s->r_acc, value)) + s->r_acc = make_reg(0, -value); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, s->r_acc, NULL_REG); break; + } case op_not: // 0x0c (12) s->r_acc = make_reg(0, !(s->r_acc.offset || s->r_acc.segment)); @@ -1220,12 +1170,17 @@ void run_vm(EngineState *s, bool restoring) { s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset > s->r_acc.offset); } else if (r_temp.segment && !s->r_acc.segment) { if (s->r_acc.offset >= 1000) - error("[VM] op_gt: comparsion between a pointer and number"); - // Pseudo-WORKAROUND: sierra allows any pointer <-> value comparsion + error("[VM] op_gt: comparison between a pointer and number"); + // Pseudo-WORKAROUND: Sierra allows any pointer <-> value comparison // Happens in SQ1, room 28, when throwing the water at Orat s->r_acc = make_reg(0, 1); - } else - s->r_acc = ACC_ARITHMETIC_L(signed_validate_arithmetic(r_temp) > (int16)/*acc*/); + } else { + int16 compare1, compare2; + if (validate_signedInteger(r_temp, compare1) && validate_signedInteger(s->r_acc, compare2)) + s->r_acc = make_reg(0, compare1 > compare2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); + } break; case op_ge_: // 0x10 (16) @@ -1236,8 +1191,13 @@ void run_vm(EngineState *s, bool restoring) { if (r_temp.segment != s->r_acc.segment) warning("[VM] Comparing pointers in different segments (%04x:%04x vs. %04x:%04x)", PRINT_REG(r_temp), PRINT_REG(s->r_acc)); s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset >= s->r_acc.offset); - } else - s->r_acc = ACC_ARITHMETIC_L(signed_validate_arithmetic(r_temp) >= (int16)/*acc*/); + } else { + int16 compare1, compare2; + if (validate_signedInteger(r_temp, compare1) && validate_signedInteger(s->r_acc, compare2)) + s->r_acc = make_reg(0, compare1 >= compare2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); + } break; case op_lt_: // 0x11 (17) @@ -1250,12 +1210,17 @@ void run_vm(EngineState *s, bool restoring) { s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset < s->r_acc.offset); } else if (r_temp.segment && !s->r_acc.segment) { if (s->r_acc.offset >= 1000) - error("[VM] op_lt: comparsion between a pointer and number"); - // Pseudo-WORKAROUND: sierra allows any pointer <-> value comparsion + error("[VM] op_lt: comparison between a pointer and number"); + // Pseudo-WORKAROUND: Sierra allows any pointer <-> value comparison // Happens in SQ1, room 58, when giving id-card to robot s->r_acc = make_reg(0, 1); - } else - s->r_acc = ACC_ARITHMETIC_L(signed_validate_arithmetic(r_temp) < (int16)/*acc*/); + } else { + int16 compare1, compare2; + if (validate_signedInteger(r_temp, compare1) && validate_signedInteger(s->r_acc, compare2)) + s->r_acc = make_reg(0, compare1 < compare2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); + } break; case op_le_: // 0x12 (18) @@ -1266,8 +1231,13 @@ void run_vm(EngineState *s, bool restoring) { if (r_temp.segment != s->r_acc.segment) warning("[VM] Comparing pointers in different segments (%04x:%04x vs. %04x:%04x)", PRINT_REG(r_temp), PRINT_REG(s->r_acc)); s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset <= s->r_acc.offset); - } else - s->r_acc = ACC_ARITHMETIC_L(signed_validate_arithmetic(r_temp) <= (int16)/*acc*/); + } else { + int16 compare1, compare2; + if (validate_signedInteger(r_temp, compare1) && validate_signedInteger(s->r_acc, compare2)) + s->r_acc = make_reg(0, compare1 <= compare2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); + } break; case op_ugt_: // 0x13 (19) @@ -1289,8 +1259,13 @@ void run_vm(EngineState *s, bool restoring) { s->r_acc = make_reg(0, 1); else if (r_temp.segment && s->r_acc.segment) s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset > s->r_acc.offset); - else - s->r_acc = ACC_ARITHMETIC_L(validate_arithmetic(r_temp) > /*acc*/); + else { + uint16 compare1, compare2; + if (validate_unsignedInteger(r_temp, compare1) && validate_unsignedInteger(s->r_acc, compare2)) + s->r_acc = make_reg(0, compare1 > compare2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); + } break; case op_uge_: // 0x14 (20) @@ -1303,8 +1278,13 @@ void run_vm(EngineState *s, bool restoring) { s->r_acc = make_reg(0, 1); else if (r_temp.segment && s->r_acc.segment) s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset >= s->r_acc.offset); - else - s->r_acc = ACC_ARITHMETIC_L(validate_arithmetic(r_temp) >= /*acc*/); + else { + uint16 compare1, compare2; + if (validate_unsignedInteger(r_temp, compare1) && validate_unsignedInteger(s->r_acc, compare2)) + s->r_acc = make_reg(0, compare1 >= compare2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); + } break; case op_ult_: // 0x15 (21) @@ -1313,12 +1293,18 @@ void run_vm(EngineState *s, bool restoring) { r_temp = POP32(); // See above - if (r_temp.segment && (s->r_acc == make_reg(0, 1000))) + // PQ2 japanese compares pointers to 2000 to find out if its a pointer or a resourceid + if (r_temp.segment && (s->r_acc == make_reg(0, 1000) || (s->r_acc == make_reg(0, 2000)))) s->r_acc = NULL_REG; else if (r_temp.segment && s->r_acc.segment) s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset < s->r_acc.offset); - else - s->r_acc = ACC_ARITHMETIC_L(validate_arithmetic(r_temp) < /*acc*/); + else { + uint16 compare1, compare2; + if (validate_unsignedInteger(r_temp, compare1) && validate_unsignedInteger(s->r_acc, compare2)) + s->r_acc = make_reg(0, compare1 < compare2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); + } break; case op_ule_: // 0x16 (22) @@ -1331,8 +1317,13 @@ void run_vm(EngineState *s, bool restoring) { s->r_acc = NULL_REG; else if (r_temp.segment && s->r_acc.segment) s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset <= s->r_acc.offset); - else - s->r_acc = ACC_ARITHMETIC_L(validate_arithmetic(r_temp) <= /*acc*/); + else { + uint16 compare1, compare2; + if (validate_unsignedInteger(r_temp, compare1) && validate_unsignedInteger(s->r_acc, compare2)) + s->r_acc = make_reg(0, compare1 <= compare2); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); + } break; case op_bt: // 0x17 (23) @@ -1647,32 +1638,55 @@ void run_vm(EngineState *s, bool restoring) { validate_property(obj, (opparams[0] >> 1)) = POP32(); break; - case op_ipToa: // 0x35 (53) - // Incement Property and copy To Accumulator - s->r_acc = validate_property(obj, (opparams[0] >> 1)); - s->r_acc = validate_property(obj, (opparams[0] >> 1)) = ACC_ARITHMETIC_L(1 + /*acc*/); + case op_ipToa: { // 0x35 (53) + // Increment Property and copy To Accumulator + reg_t &opProperty = validate_property(obj, opparams[0] >> 1); + uint16 valueProperty; + if (validate_unsignedInteger(opProperty, valueProperty)) + s->r_acc = make_reg(0, valueProperty + 1); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, opProperty, NULL_REG); + opProperty = s->r_acc; break; + } case op_dpToa: { // 0x36 (54) // Decrement Property and copy To Accumulator - s->r_acc = validate_property(obj, (opparams[0] >> 1)); - s->r_acc = validate_property(obj, (opparams[0] >> 1)) = ACC_ARITHMETIC_L(-1 + /*acc*/); + reg_t &opProperty = validate_property(obj, opparams[0] >> 1); + uint16 valueProperty; + if (validate_unsignedInteger(opProperty, valueProperty)) + s->r_acc = make_reg(0, valueProperty - 1); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, opcodeDptoaWorkarounds, opProperty, NULL_REG); + opProperty = s->r_acc; break; } - case op_ipTos: // 0x37 (55) + case op_ipTos: { // 0x37 (55) // Increment Property and push to Stack - validate_arithmetic(validate_property(obj, (opparams[0] >> 1))); - temp = ++validate_property(obj, (opparams[0] >> 1)).offset; - PUSH(temp); + reg_t &opProperty = validate_property(obj, opparams[0] >> 1); + uint16 valueProperty; + if (validate_unsignedInteger(opProperty, valueProperty)) + valueProperty++; + else + valueProperty = arithmetic_lookForWorkaround(opcode, NULL, opProperty, NULL_REG).offset; + opProperty = make_reg(0, valueProperty); + PUSH(valueProperty); break; + } - case op_dpTos: // 0x38 (56) + case op_dpTos: { // 0x38 (56) // Decrement Property and push to Stack - validate_arithmetic(validate_property(obj, (opparams[0] >> 1))); - temp = --validate_property(obj, (opparams[0] >> 1)).offset; - PUSH(temp); + reg_t &opProperty = validate_property(obj, opparams[0] >> 1); + uint16 valueProperty; + if (validate_unsignedInteger(opProperty, valueProperty)) + valueProperty--; + else + valueProperty = arithmetic_lookForWorkaround(opcode, NULL, opProperty, NULL_REG).offset; + opProperty = make_reg(0, valueProperty); + PUSH(valueProperty); break; + } case op_lofsa: // 0x39 (57) // Load Offset to Accumulator diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 81ec4f1c61..ee22e03310 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -315,9 +315,8 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, * It executes the code on s->heap[pc] until it hits a 'ret' operation * while (stack_base == stack_pos). Requires s to be set up correctly. * @param[in] s The state to use - * @param[in] restoring true if s has just been restored, false otherwise */ -void run_vm(EngineState *s, bool restoring); +void run_vm(EngineState *s); /** * Debugger functionality diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp new file mode 100644 index 0000000000..0db73e34d5 --- /dev/null +++ b/engines/sci/engine/workarounds.cpp @@ -0,0 +1,357 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "sci/engine/kernel.h" +#include "sci/engine/state.h" +#include "sci/engine/vm.h" +#include "sci/engine/workarounds.h" + +#define SCI_WORKAROUNDENTRY_TERMINATOR { (SciGameId)0, -1, -1, 0, NULL, NULL, -1, 0, { WORKAROUND_NONE, 0 } } + +namespace Sci { + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry opcodeDivWorkarounds[] = { + { GID_QFG1VGA, 301, 928, 0, "Blink", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // when entering inn, gets called with 1 parameter, but 2nd parameter is used for div which happens to be an object + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry opcodeOrWorkarounds[] = { + { GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xcc6, 0, { WORKAROUND_FAKE, 0 } }, // when giving the papers to the customs officer, gets called against a pointer instead of a number - bug #3034464 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call, index, workaround +const SciWorkaroundEntry opcodeDptoaWorkarounds[] = { + { GID_LSL6, 360, 938, 0, "ROsc", "cycleDone", -1, 0, { WORKAROUND_FAKE, 1 } }, // when looking through tile in the shower room initial cycles get set to an object instead of 2, we fix this by setting 1 after decrease + { GID_LSL6HIRES, 360,64938, 0, "ROsc", "cycleDone", -1, 0, { WORKAROUND_FAKE, 1 } }, // when looking through tile in the shower room initial cycles get set to an object instead of 2, we fix this by setting 1 after decrease + { GID_SQ5, 200, 939, 0, "Osc", "cycleDone", -1, 0, { WORKAROUND_FAKE, 1 } }, // when going back to bridge the crew is goofing off, we get an object as cycle count + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry uninitializedReadWorkarounds[] = { + { GID_CNICK_KQ, 200, 0, 1, "Character", "<noname 446>", -1, 504, { WORKAROUND_FAKE, 0 } }, // checkers, like in hoyle 3 + { GID_CNICK_KQ, 200, 0, 1, "Character", "<noname 446>", -1, 505, { WORKAROUND_FAKE, 0 } }, // checkers, like in hoyle 3 + { GID_CNICK_KQ, -1, 700, 0, "gcWindow", "<noname 183>", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu, like in hoyle 3 + { GID_CNICK_LONGBOW, 0, 0, 0, "RH Budget", "<noname 110>", -1, 1, { WORKAROUND_FAKE, 0 } }, // when starting the game + { GID_ECOQUEST, -1, -1, 0, NULL, "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // almost clicking anywhere triggers this in almost all rooms + { GID_FREDDYPHARKAS, -1, 24, 0, "gcWin", "open", -1, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu + { GID_FREDDYPHARKAS, -1, 31, 0, "quitWin", "open", -1, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu + { GID_GK1, -1, 64950, 1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // sometimes when walk-clicking + { GID_GK2, -1, 11, 0, "", "export 10", -1, 3, { WORKAROUND_FAKE, 0 } }, // called when the game starts + { GID_GK2, -1, 11, 0, "", "export 10", -1, 4, { WORKAROUND_FAKE, 0 } }, // called during the game + { GID_HOYLE1, 4, 104, 0, "GinRummyCardList", "calcRuns", -1, 4, { WORKAROUND_FAKE, 0 } }, // Gin Rummy / right when the game starts + { GID_HOYLE1, 5, 204, 0, "tableau", "checkRuns", -1, 2, { WORKAROUND_FAKE, 0 } }, // Cribbage / during the game + { GID_HOYLE3, -1, 0, 1, "Character", "say", -1, 504, { WORKAROUND_FAKE, 0 } }, // when starting checkers or dominoes, first time a character says something + { GID_HOYLE3, -1, 0, 1, "Character", "say", -1, 505, { WORKAROUND_FAKE, 0 } }, // when starting checkers or dominoes, first time a character says something + { GID_HOYLE3, -1, 700, 0, "gcWindow", "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu + { GID_ISLANDBRAIN, 140, 140, 0, "piece", "init", -1, 3, { WORKAROUND_FAKE, 1 } }, // first puzzle right at the start, some initialization variable. bnt is done on it, and it should be non-0 + { GID_ISLANDBRAIN, 200, 268, 0, "anElement", "select", -1, 0, { WORKAROUND_FAKE, 0 } }, // elements puzzle, gets used before super TextIcon + { GID_JONES, 1, 232, 0, "weekendText", "draw", 0x3d3, 0, { WORKAROUND_FAKE, 0 } }, // jones/cd only - gets called during the game + { GID_JONES, 1, 255, 0, "", "export 0", -1, 13, { WORKAROUND_FAKE, 0 } }, // jones/cd only - called when a game ends + { GID_JONES, 1, 255, 0, "", "export 0", -1, 14, { WORKAROUND_FAKE, 0 } }, // jones/cd only - called when a game ends + { GID_JONES, 764, 255, 0, "", "export 0", -1, 13, { WORKAROUND_FAKE, 0 } }, // jones/ega&vga only - called when the game starts + { GID_JONES, 764, 255, 0, "", "export 0", -1, 14, { WORKAROUND_FAKE, 0 } }, // jones/ega&vga only - called when the game starts + { GID_KQ5, -1, 0, 0, "", "export 29", -1, 3, { WORKAROUND_FAKE, 0 } }, // called when playing harp for the harpies or when aborting dialog in toy shop, is used for kDoAudio - bug #3034700 + { GID_KQ5, 25, 25, 0, "rm025", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // inside witch forest, when going to the room where the walking rock is + { GID_KQ6, -1, 30, 0, "rats", "changeState", -1, -1, { WORKAROUND_FAKE, 0 } }, // rats in the catacombs (temps 1 - 5) - bugs #3034597, #3035495, #3035824 + { GID_KQ6, 210, 210, 0, "rm210", "scriptCheck", -1, 0, { WORKAROUND_FAKE, 1 } }, // using inventory in that room - bug #3034565 + { GID_KQ6, 500, 500, 0, "rm500", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // going to island of the beast + { GID_KQ6, 520, 520, 0, "rm520", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // going to boiling water trap on beast isle + { GID_KQ6, -1, 903, 0, "controlWin", "open", -1, 4, { WORKAROUND_FAKE, 0 } }, // when opening the controls window (save, load etc) + { GID_KQ7, 30, 64996, 0, "User", "handleEvent", -1, 1, { WORKAROUND_FAKE, 0 } }, // called when pushing a keyboard key + { GID_LAURABOW, 44, 967, 0, "myIcon", "cycle", -1, 1, { WORKAROUND_FAKE, 0 } }, // second dialog box after the intro, when talking with Lillian - bug #3034985 + { GID_LAURABOW2, -1, 24, 0, "gcWin", "open", -1, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu + { GID_LAURABOW2, -1, 21, 0, "dropCluesCode", "doit", -1, 1, { WORKAROUND_FAKE, 0 } }, // when asking some questions (e.g. the reporter about the burglary, or the policeman about Ziggy) - bugs #3035068, #3036274 + { GID_LAURABOW2, 240, 240, 0, "sSteveAnimates", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // Steve Dorian's idle animation at the docks - bug #3036291 + { GID_LONGBOW, -1, 213, 0, "clear", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // When giving an aswer using the druid hand sign code in any room + { GID_LONGBOW, -1, 213, 0, "letter", "handleEvent", 0xa8, 1, { WORKAROUND_FAKE, 0 } }, // When using the druid hand sign code in any room - bug #3036601 + { GID_LSL1, 250, 250, 0, "increase", "handleEvent", -1, 2, { WORKAROUND_FAKE, 0 } }, // casino, playing game, increasing bet + { GID_LSL1, 720, 720, 0, "rm720", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // age check room + { GID_LSL2, 38, 38, 0, "cloudScript", "changeState", -1, 1, { WORKAROUND_FAKE, 0 } }, // entering the room in the middle deck of the ship - bug #3036483 + { GID_LSL3, 340, 340, 0, "ComicScript", "changeState", -1, -1, { WORKAROUND_FAKE, 0 } }, // right after entering the 3 ethnic groups inside comedy club (temps 200, 201, 202, 203) + { GID_LSL3, -1, 997, 0, "TheMenuBar", "handleEvent", -1, 1, { WORKAROUND_FAKE, 0xf } }, // when setting volume the first time, this temp is used to set volume on entry (normally it would have been initialized to 's') + { GID_LSL6, -1, 85, 0, "washcloth", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // washcloth in inventory + { GID_LSL6, -1, 928, -1, "Narrator", "startText", -1, 0, { WORKAROUND_FAKE, 0 } }, // used by various objects that are even translated in foreign versions, that's why we use the base-class + { GID_LSL6HIRES, 0, 85, 0, "LL6Inv", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // on startup + { GID_LSL6HIRES, -1, 64950, 1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // at least when entering swimming pool area + { GID_LSL6HIRES, -1, 64964, 0, "DPath", "init", -1, 1, { WORKAROUND_FAKE, 0 } }, // during the game + { GID_MOTHERGOOSE, 18, 992, 0, "AIPath", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // DEMO: Called when walking north from mother goose's house two screens + { GID_MOTHERGOOSEHIRES,-1,64950, 1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // right when clicking on a child at the start and probably also later + { GID_MOTHERGOOSEHIRES,-1,64950, 1, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // see above + { GID_QFG2, -1, 71, 0, "theInvSheet", "doit", -1, 1, { WORKAROUND_FAKE, 0 } }, // accessing the inventory + { GID_QFG2, -1, 701, 0, "Alley", "at", -1, 0, { WORKAROUND_FAKE, 0 } }, // when walking inside the alleys in the town - bug #3035835 + { GID_QFG3, 330, 330, 0, "rajahTeller", "doChild", -1, 0, { WORKAROUND_FAKE, 0 } }, // when talking to King Rajah about "Tarna" + { GID_QFG3, 330, 330, 0, "rajahTeller", "doChild", -1, 1, { WORKAROUND_FAKE, 0 } }, // when talking to King Rajah about "Rajah" - bug #3036390 + { GID_SQ1, 103, 103, 0, "hand", "internalEvent", -1, 1, { WORKAROUND_FAKE, 0 } }, // spanish (and maybe early versions?) only: when moving cursor over input pad + { GID_SQ1, 103, 103, 0, "hand", "internalEvent", -1, 2, { WORKAROUND_FAKE, 0 } }, // spanish (and maybe early versions?) only: when moving cursor over input pad + { GID_SQ1, -1, 703, 0, "", "export 1", -1, 0, { WORKAROUND_FAKE, 0 } }, // sub that's called from several objects while on sarien battle cruiser + { GID_SQ1, -1, 703, 0, "firePulsar", "changeState", 0x18a, 0, { WORKAROUND_FAKE, 0 } }, // export 1, but called locally (when shooting at aliens) + { GID_SQ4, -1, 398, 0, "showBox", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // sq4cd: called when rummaging in Software Excess bargain bin + { GID_SQ4, -1, 928, 0, "Narrator", "startText", -1, 1000, { WORKAROUND_FAKE, 1 } }, // sq4cd: method returns this to the caller + { GID_SQ6, 100, 0, 0, "SQ6", "init", -1, 2, { WORKAROUND_FAKE, 0 } }, // called when the game starts + { GID_SQ6, 100, 64950, 0, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // called when pressing "Start game" in the main menu + { GID_SQ6, -1, 64964, 0, "DPath", "init", -1, 1, { WORKAROUND_FAKE, 0 } }, // during the game + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kAbs_workarounds[] = { + { GID_HOYLE1, 1, 1, 0, "room1", "doit", -1, 0, { WORKAROUND_FAKE, 0x3e9 } }, // crazy eights - called with objects instead of integers + { GID_HOYLE1, 2, 2, 0, "room2", "doit", -1, 0, { WORKAROUND_FAKE, 0x3e9 } }, // old maid - called with objects instead of integers + { GID_HOYLE1, 3, 3, 0, "room3", "doit", -1, 0, { WORKAROUND_FAKE, 0x3e9 } }, // hearts - called with objects instead of integers + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kCelHigh_workarounds[] = { + { GID_SQ1, 1, 255, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // DEMO: Called with 2nd/3rd parameters as objects when clicking on the menu + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kCelWide_workarounds[] = { + { GID_SQ1, 1, 255, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // DEMO: Called with 2nd/3rd parameters as objects when clicking on the menu - bug #3035720 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kDisplay_workarounds[] = { + { GID_ISLANDBRAIN, 300, 300, 0, "geneDude", "show", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the gene explanation chart - a parameter is an object + { GID_SQ4, 391, 391, 0, "doCatalog", "mode", 0x84, 0, { WORKAROUND_IGNORE, 0 } }, // clicking on catalog in roboter sale - a parameter is an object + { GID_SQ4, 391, 391, 0, "choosePlug", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // ordering connector in roboter sale - a parameter is an object + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kDisposeScript_workarounds[] = { + { GID_LAURABOW, 777, 777, 0, "myStab", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: after the will is signed, parameter 0 is an object - bug #3034907 + { GID_QFG1, -1, 64, 0, "rm64", "dispose", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when leaving graveyard, parameter 0 is an object + { GID_SQ4, 150, 151, 0, "fightScript", "dispose", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during fight with vohaul, parameter 0 is an object + { GID_SQ4, 150, 152, 0, "driveCloseUp", "dispose", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when choosing "beam download", parameter 0 is an object + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kDoSoundFade_workarounds[] = { + { GID_CAMELOT, -1, 989, 0, "rmMusic", "fade", -1, 0, { WORKAROUND_IGNORE, 0 } }, // gets called frequently with a NULL reference (i.e. 0:0) - bug #3035149 + { GID_KQ1, -1, 989, 0, "gameSound", "fade", -1, 0, { WORKAROUND_IGNORE, 0 } }, // gets called in several scenes (e.g. graham cracker) with 0:0 + { GID_KQ6, 105, 989, 0, "globalSound", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // floppy: during intro, parameter 4 is an object + { GID_KQ6, 460, 989, 0, "globalSound2", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // after pulling the black widow's web on the isle of wonder, parameter 4 is an object - bug #3034567 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kGetAngle_workarounds[] = { + { GID_KQ6, 740, 752, 0, "throwDazzle", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // after the Genie is exposed in the Palace (short and long ending), it starts shooting lightning bolts around. An extra 5th parameter is passed - bug #3034610 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kFindKey_workarounds[] = { + { GID_ECOQUEST2, 100, 999, 0, "myList", "contains", -1, 0, { WORKAROUND_FAKE, 0 } }, // When Noah Greene gives Adam the Ecorder, and just before the game gives a demonstration, a null reference to a list is passed - bug #3035186 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kGraphDrawLine_workarounds[] = { + { GID_ISLANDBRAIN, 300, 300, 0, "dudeViewer", "show", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when looking at the gene explanation chart, gets called with 1 extra parameter + { GID_SQ1, 43, 43, 0, "someoneDied", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when ordering beer, gets called with 1 extra parameter + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kGraphSaveBox_workarounds[] = { + { GID_CASTLEBRAIN, 420, 427, 0, "alienIcon", "select", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when selecting a card during the alien card game, gets called with 1 extra parameter + { GID_ISLANDBRAIN, 290, 291, 0, "upElevator", "changeState",0x201f, 0, { WORKAROUND_STILLCALL, 0 } }, // when testing in the elevator puzzle, gets called with 1 argument less - 15 is on stack - bug #3034485 + { GID_ISLANDBRAIN, 290, 291, 0, "downElevator", "changeState",0x201f, 0, { WORKAROUND_STILLCALL, 0 } }, // see above + { GID_ISLANDBRAIN, 290, 291, 0, "correctElevator", "changeState",0x201f, 0, { WORKAROUND_STILLCALL, 0 } }, // see above (when testing the correct solution) + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kGraphRestoreBox_workarounds[] = { + { GID_LSL6, -1, 85, 0, "rScroller", "hide", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // happens when restoring (sometimes), same as the one below + { GID_LSL6, -1, 85, 0, "lScroller", "hide", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // happens when restoring (sometimes), same as the one below + { GID_LSL6, -1, 86, 0, "LL6Inv", "show", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // happens when restoring, is called with hunk segment, but hunk is not allocated at that time + // ^^ TODO: check, if this is really a script error or an issue with our restore code + { GID_LSL6, -1, 86, 0, "LL6Inv", "hide", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // happens during the game, gets called with 1 extra parameter + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kGraphFillBoxForeground_workarounds[] = { + { GID_LSL6, -1, 0, 0, "LSL6", "hideControls", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // happens when giving the bungee key to merrily (room 240) and at least in room 650 too - gets called with additional 5th parameter + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kGraphFillBoxAny_workarounds[] = { + { GID_SQ4, -1, 818, 0, "iconTextSwitch", "show", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // game menu "text/speech" display - parameter 5 is missing, but the right color number is on the stack + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kGraphRedrawBox_workarounds[] = { + { GID_SQ4, 405, 405, 0, "swimAfterEgo", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified + { GID_SQ4, 406, 406, 0, "swimAndShoot", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified + { GID_SQ4, 410, 410, 0, "swimAfterEgo", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified + { GID_SQ4, 411, 411, 0, "swimAndShoot", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified + { GID_SQ4, -1, 704, 0, "shootEgo", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // When shot by Droid in Super Computer Maze (Rooms 500, 505, 510...) - accidental additional parameter specified + { GID_KQ5, -1, 981, 0, "myWindow", "dispose", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // Happens in the floppy version, when closing any dialog box, accidental additional parameter specified - bug #3036331 + { GID_KQ5, -1, 995, 0, "invW", "doit", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // Happens in the floppy version, when closing the inventory window, accidental additional parameter specified + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kIsObject_workarounds[] = { + { GID_GK1, 50, 999, 0, "List", "eachElementDo", -1, 0, { WORKAROUND_FAKE, 0 } }, // GK1 demo, when asking Grace for messages it gets called with an invalid parameter (type "error") - bug #3034519 + { GID_ISLANDBRAIN, -1, 999, 0, "List", "eachElementDo", -1, 0, { WORKAROUND_FAKE, 0 } }, // when going to the game options, choosing "Info" and selecting anything from the list, gets called with an invalid parameter (type "error") - bug #3035262 + { GID_QFG3, -1, 999, 0, "List", "eachElementDo", -1, 0, { WORKAROUND_FAKE, 0 } }, // when asking for something, gets called with type error parameter + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kMemory_workarounds[] = { + { GID_LAURABOW2, -1, 999, 0, "", "export 6", -1, 0, { WORKAROUND_FAKE, 0 } }, // during the intro, when exiting the train, talking to Mr. Augustini, etc. - bug #3034490 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kNewWindow_workarounds[] = { + { GID_ECOQUEST, -1, 981, 0, "SysWindow", "<noname 178>", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // EcoQuest 1 demo uses an in-between interpreter from SCI1 to SCI1.1. It's SCI1.1, but uses the SCI1 semantics for this call - bug #3035057 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[] = { + { GID_QFG4, 100, 100, 0, "doMovie", "<noname 144>", -1, 0, { WORKAROUND_IGNORE, 0 } }, // after the Sierra logo, no flags are passed, thus the call is meaningless - bug #3034506 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kSetPort_workarounds[] = { + { GID_LSL6, 740, 740, 0, "rm740", "drawPic", -1, 0, { WORKAROUND_IGNORE, 0 } }, // ending scene, is called with additional 3 (!) parameters + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kUnLoad_workarounds[] = { + { GID_CAMELOT, 921, 921, 1, "Script", "changeState", 0x36, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: While showing Camelot (and other places), the reference is invalid - bug #3035000 + { GID_CAMELOT, 921, 921, 1, "Script", "init", 0x36, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: When being attacked by the boar (and other places), the reference is invalid - bug #3035000 + { GID_CASTLEBRAIN, 320, 377, 0, "SWord", "upDate", -1, 0, { WORKAROUND_IGNORE, 0 } }, // after solving the cross-word-puzzle, trying to unload invalid reference + { GID_CASTLEBRAIN, 320, 377, 0, "theWord", "show", -1, 0, { WORKAROUND_IGNORE, 0 } }, // 2nd word puzzle, when exiting before solving, trying to unload invalid reference - bug #3034473 + { GID_ECOQUEST, 380, 61, 0, "gotIt", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // after talking to the dolphin the first time + { GID_LAURABOW2, 1, 1, 0, "sCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during the intro, a 3rd parameter is passed by accident - bug #3034902 + { GID_LAURABOW2, 2, 2, 0, "sCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during the intro, a 3rd parameter is passed by accident - bug #3034902 + { GID_LAURABOW2, 4, 4, 0, "sCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: inside the museum, a 3rd parameter is passed by accident - bug #3034902 + { GID_LAURABOW2, 6, 6, 0, "sCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: after the murder, a 3rd parameter is passed by accident - bug #3034902 + { GID_LAURABOW2, 7, 7, 0, "sCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: after the logo is shown, a 3rd parameter is passed by accident - bug #3034902 + { GID_LSL6, 130, 130, 0, "recruitLarryScr", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident + { GID_LSL6, 740, 740, 0, "showCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during ending, 4 additional parameters are passed by accident + { GID_LSL6HIRES, 130, 130, 0, "recruitLarryScr", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident + { GID_SQ1, 43, 303, 0, "slotGuy", "dispose", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when leaving ulence flats bar, parameter 1 is not passed - script error + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroundEntry *workaroundList, SciTrackOriginReply *trackOrigin) { + EngineState *state = g_sci->getEngineState(); + ExecStack *lastCall = state->xs; + Script *local_script = state->_segMan->getScriptIfLoaded(lastCall->local_segment); + int curScriptNr = local_script->getScriptNumber(); + + if (lastCall->debugLocalCallOffset != -1) { + // if lastcall was actually a local call search back for a real call + Common::List<ExecStack>::iterator callIterator = state->_executionStack.end(); + while (callIterator != state->_executionStack.begin()) { + callIterator--; + ExecStack loopCall = *callIterator; + if ((loopCall.debugSelector != -1) || (loopCall.debugExportId != -1)) { + lastCall->debugSelector = loopCall.debugSelector; + lastCall->debugExportId = loopCall.debugExportId; + break; + } + } + } + + Common::String curObjectName = state->_segMan->getObjectName(lastCall->sendp); + Common::String curMethodName; + const SciGameId gameId = g_sci->getGameId(); + const int curRoomNumber = state->currentRoomNumber(); + + if (lastCall->type == EXEC_STACK_TYPE_CALL) { + if (lastCall->debugSelector != -1) { + curMethodName = g_sci->getKernel()->getSelectorName(lastCall->debugSelector); + } else if (lastCall->debugExportId != -1) { + curObjectName = ""; + curMethodName = curMethodName.printf("export %d", lastCall->debugExportId); + } + } + + if (workaroundList) { + // Search if there is a workaround for this one + const SciWorkaroundEntry *workaround; + int16 inheritanceLevel = 0; + Common::String searchObjectName = curObjectName; + reg_t searchObject = lastCall->sendp; + do { + workaround = workaroundList; + while (workaround->methodName) { + if (workaround->gameId == gameId + && ((workaround->scriptNr == -1) || (workaround->scriptNr == curScriptNr)) + && ((workaround->roomNr == -1) || (workaround->roomNr == curRoomNumber)) + && ((workaround->inheritanceLevel == -1) || (workaround->inheritanceLevel == inheritanceLevel)) + && ((workaround->objectName == NULL) || (workaround->objectName == searchObjectName)) + && workaround->methodName == curMethodName && workaround->localCallOffset == lastCall->debugLocalCallOffset + && ((workaround->index == -1) || (workaround->index == index))) { + // Workaround found + return workaround->newValue; + } + workaround++; + } + + // Go back to the parent + inheritanceLevel++; + searchObject = state->_segMan->getObject(searchObject)->getSuperClassSelector(); + if (!searchObject.isNull()) + searchObjectName = state->_segMan->getObjectName(searchObject); + } while (!searchObject.isNull()); // no parent left? + } + + // give caller origin data + trackOrigin->objectName = curObjectName; + trackOrigin->methodName = curMethodName; + trackOrigin->scriptNr = curScriptNr; + trackOrigin->localCallOffset = lastCall->debugLocalCallOffset; + + SciWorkaroundSolution noneFound; + noneFound.type = WORKAROUND_NONE; + noneFound.value = 0; + return noneFound; +} + +} // End of namespace Sci diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h new file mode 100644 index 0000000000..d509d300d7 --- /dev/null +++ b/engines/sci/engine/workarounds.h @@ -0,0 +1,100 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef SCI_ENGINE_WORKAROUNDS_H +#define SCI_ENGINE_WORKAROUNDS_H + +#include "sci/engine/vm_types.h" +#include "sci/sci.h" + +namespace Sci { + +enum SciWorkaroundType { + WORKAROUND_NONE, // only used by terminator or when no workaround was found + WORKAROUND_IGNORE, // ignore kernel call + WORKAROUND_STILLCALL, // still do kernel call + WORKAROUND_FAKE // fake kernel call / replace temp value / fake opcode +}; + +struct SciTrackOriginReply { + int scriptNr; + Common::String objectName; + Common::String methodName; + int localCallOffset; +}; + +struct SciWorkaroundSolution { + SciWorkaroundType type; + uint16 value; +}; + +/** + * A structure describing a 'workaround' for a SCI script bug. + * + * Arrays of SciWorkaroundEntry instances are terminated by + * a fake entry in which "objectName" is NULL. + */ +struct SciWorkaroundEntry { + SciGameId gameId; + int roomNr; + int scriptNr; + int16 inheritanceLevel; + const char *objectName; + const char *methodName; + int localCallOffset; + int index; + SciWorkaroundSolution newValue; +}; + +extern const SciWorkaroundEntry opcodeDivWorkarounds[]; +extern const SciWorkaroundEntry opcodeOrWorkarounds[]; +extern const SciWorkaroundEntry opcodeDptoaWorkarounds[]; +extern const SciWorkaroundEntry uninitializedReadWorkarounds[]; +extern const SciWorkaroundEntry kAbs_workarounds[]; +extern const SciWorkaroundEntry kCelHigh_workarounds[]; +extern const SciWorkaroundEntry kCelWide_workarounds[]; +extern const SciWorkaroundEntry kDisplay_workarounds[]; +extern const SciWorkaroundEntry kDisposeScript_workarounds[]; +extern const SciWorkaroundEntry kDoSoundFade_workarounds[]; +extern const SciWorkaroundEntry kFindKey_workarounds[]; +extern const SciWorkaroundEntry kGetAngle_workarounds[]; +extern const SciWorkaroundEntry kGraphDrawLine_workarounds[]; +extern const SciWorkaroundEntry kGraphSaveBox_workarounds[]; +extern const SciWorkaroundEntry kGraphRestoreBox_workarounds[]; +extern const SciWorkaroundEntry kGraphFillBoxForeground_workarounds[]; +extern const SciWorkaroundEntry kGraphFillBoxAny_workarounds[]; +extern const SciWorkaroundEntry kGraphRedrawBox_workarounds[]; +extern const SciWorkaroundEntry kIsObject_workarounds[]; +extern const SciWorkaroundEntry kMemory_workarounds[]; +extern const SciWorkaroundEntry kNewWindow_workarounds[]; +extern const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[]; +extern const SciWorkaroundEntry kSetPort_workarounds[]; +extern const SciWorkaroundEntry kUnLoad_workarounds[]; + +extern SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroundEntry *workaroundList, SciTrackOriginReply *trackOrigin); + +} // End of namespace Sci + +#endif // SCI_ENGINE_WORKAROUNDS_H diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp index a100dda27c..5923e501cf 100644 --- a/engines/sci/event.cpp +++ b/engines/sci/event.cpp @@ -313,6 +313,10 @@ SciEvent EventManager::getScummVMEvent() { input.type = SCI_EVENT_MOUSE_PRESS; input.data = 2; break; + case Common::EVENT_MBUTTONDOWN: + input.type = SCI_EVENT_MOUSE_PRESS; + input.data = 3; + break; case Common::EVENT_LBUTTONUP: input.type = SCI_EVENT_MOUSE_RELEASE; input.data = 1; @@ -321,6 +325,10 @@ SciEvent EventManager::getScummVMEvent() { input.type = SCI_EVENT_MOUSE_RELEASE; input.data = 2; break; + case Common::EVENT_MBUTTONUP: + input.type = SCI_EVENT_MOUSE_RELEASE; + input.data = 3; + break; // Misc events case Common::EVENT_QUIT: @@ -335,16 +343,20 @@ SciEvent EventManager::getScummVMEvent() { return input; } -SciEvent EventManager::getSciEvent(unsigned int mask) { - //sci_event_t error_event = { SCI_EVT_ERROR, 0, 0, 0 }; - SciEvent event = { 0, 0, 0, 0 }; - +void EventManager::updateScreen() { // Update the screen here, since it's called very often. // Throttle the screen update rate to 60fps. if (g_system->getMillis() - g_sci->getEngineState()->_screenUpdateTime >= 1000 / 60) { g_system->updateScreen(); g_sci->getEngineState()->_screenUpdateTime = g_system->getMillis(); } +} + +SciEvent EventManager::getSciEvent(unsigned int mask) { + //sci_event_t error_event = { SCI_EVT_ERROR, 0, 0, 0 }; + SciEvent event = { 0, 0, 0, 0 }; + + EventManager::updateScreen(); // Get all queued events from graphics driver do { diff --git a/engines/sci/event.h b/engines/sci/event.h index 30098b0f6e..fade7dd337 100644 --- a/engines/sci/event.h +++ b/engines/sci/event.h @@ -114,6 +114,7 @@ public: EventManager(bool fontIsExtended); ~EventManager(); + void updateScreen(); SciEvent getSciEvent(unsigned int mask); bool getUsesNewKeyboardDirectionType(); diff --git a/engines/sci/graphics/animate.cpp b/engines/sci/graphics/animate.cpp index 6fb427500d..c637ef8374 100644 --- a/engines/sci/graphics/animate.cpp +++ b/engines/sci/graphics/animate.cpp @@ -28,6 +28,7 @@ #include "graphics/primitives.h" #include "sci/sci.h" +#include "sci/event.h" #include "sci/engine/kernel.h" #include "sci/engine/state.h" #include "sci/engine/selector.h" @@ -98,8 +99,12 @@ bool GfxAnimate::invoke(List *list, int argc, reg_t *argv) { if (_s->abortScriptProcessing != kAbortNone || g_engine->shouldQuit()) return true; // Stop processing - // Lookup node again, since the nodetable it was in may have been reallocated - curNode = _s->_segMan->lookupNode(curAddress); + // Lookup node again, since the nodetable it was in may have been reallocated. + // The node might have been deallocated at this point (e.g. LSL2, room 42), + // in which case the node reference will be null and the loop will stop below. + // If the node is deleted from kDeleteKey, it won't have a successor node, thus + // list processing will stop here (which is what SSCI does). + curNode = _s->_segMan->lookupNode(curAddress, false); } if (curNode) { @@ -538,9 +543,6 @@ void GfxAnimate::animateShowPic() { _transitions->doit(picRect); if (previousCursorState) _cursor->kernelShow(); - - // We set SCI1.1 priority band information here - _ports->priorityBandsRecall(); } void GfxAnimate::kernelAnimate(reg_t listReference, bool cycle, int argc, reg_t *argv) { @@ -596,6 +598,10 @@ void GfxAnimate::kernelAnimate(reg_t listReference, bool cycle, int argc, reg_t if (_lastCastData.size() > 1) _s->_throttleTrigger = true; + // We update the screen here as well, some scenes like EQ1 credits run w/o calling kGetEvent thus we wouldn't update + // screen at all + g_sci->getEventManager()->updateScreen(); + _ports->setPort(oldPort); } diff --git a/engines/sci/graphics/cache.cpp b/engines/sci/graphics/cache.cpp index 8caa28b3a1..25475c727f 100644 --- a/engines/sci/graphics/cache.cpp +++ b/engines/sci/graphics/cache.cpp @@ -90,11 +90,11 @@ GfxView *GfxCache::getView(GuiResourceId viewId) { } int16 GfxCache::kernelViewGetCelWidth(GuiResourceId viewId, int16 loopNo, int16 celNo) { - return getView(viewId)->getCelInfo(loopNo, celNo)->width; + return getView(viewId)->getCelInfo(loopNo, celNo)->scriptWidth; } int16 GfxCache::kernelViewGetCelHeight(GuiResourceId viewId, int16 loopNo, int16 celNo) { - return getView(viewId)->getCelInfo(loopNo, celNo)->height; + return getView(viewId)->getCelInfo(loopNo, celNo)->scriptHeight; } int16 GfxCache::kernelViewGetLoopCount(GuiResourceId viewId) { diff --git a/engines/sci/graphics/compare.cpp b/engines/sci/graphics/compare.cpp index 31c2b210ce..0a186115d0 100644 --- a/engines/sci/graphics/compare.cpp +++ b/engines/sci/graphics/compare.cpp @@ -70,7 +70,7 @@ uint16 GfxCompare::isOnControl(uint16 screenMask, const Common::Rect &rect) { return result; } -bool GfxCompare::canBeHereCheckRectList(reg_t checkObject, const Common::Rect &checkRect, List *list) { +reg_t GfxCompare::canBeHereCheckRectList(reg_t checkObject, const Common::Rect &checkRect, List *list) { reg_t curAddress = list->first; Node *curNode = _segMan->lookupNode(curAddress); reg_t curObject; @@ -96,14 +96,14 @@ bool GfxCompare::canBeHereCheckRectList(reg_t checkObject, const Common::Rect &c curRect.left < checkRect.right && curRect.bottom > checkRect.top && curRect.top < checkRect.bottom) { - return false; + return curObject; } } } curAddress = curNode->succ; curNode = _segMan->lookupNode(curAddress); } - return true; + return NULL_REG; } uint16 GfxCompare::kernelOnControl(byte screenMask, const Common::Rect &rect) { @@ -132,15 +132,39 @@ void GfxCompare::kernelSetNowSeen(reg_t objectReference) { view = _cache->getView(viewId); - if (view->isSci2Hires()) - _screen->adjustToUpscaledCoordinates(y, x); +#ifdef ENABLE_SCI32 + switch (getSciVersion()) { + case SCI_VERSION_2: + if (view->isSci2Hires()) + _screen->adjustToUpscaledCoordinates(y, x); + break; + case SCI_VERSION_2_1: + _coordAdjuster->fromScriptToDisplay(y, x); + break; + default: + break; + } +#endif view->getCelRect(loopNo, celNo, x, y, z, celRect); - if (view->isSci2Hires()) { - _screen->adjustBackUpscaledCoordinates(celRect.top, celRect.left); - _screen->adjustBackUpscaledCoordinates(celRect.bottom, celRect.right); +#ifdef ENABLE_SCI32 + switch (getSciVersion()) { + case SCI_VERSION_2: + if (view->isSci2Hires()) { + _screen->adjustBackUpscaledCoordinates(celRect.top, celRect.left); + _screen->adjustBackUpscaledCoordinates(celRect.bottom, celRect.right); + } + break; + case SCI_VERSION_2_1: { + _coordAdjuster->fromDisplayToScript(celRect.top, celRect.left); + _coordAdjuster->fromDisplayToScript(celRect.bottom, celRect.right); + break; + } + default: + break; } +#endif if (lookupSelector(_segMan, objectReference, SELECTOR(nsTop), NULL, NULL) == kSelectorVariable) { writeSelectorValue(_segMan, objectReference, SELECTOR(nsLeft), celRect.left); @@ -150,11 +174,11 @@ void GfxCompare::kernelSetNowSeen(reg_t objectReference) { } } -bool GfxCompare::kernelCanBeHere(reg_t curObject, reg_t listReference) { +reg_t GfxCompare::kernelCanBeHere(reg_t curObject, reg_t listReference) { Common::Rect checkRect; Common::Rect adjustedRect; uint16 signal, controlMask; - bool result; + uint16 result; checkRect.left = readSelectorValue(_segMan, curObject, SELECTOR(brLeft)); checkRect.top = readSelectorValue(_segMan, curObject, SELECTOR(brTop)); @@ -163,22 +187,22 @@ bool GfxCompare::kernelCanBeHere(reg_t curObject, reg_t listReference) { if (!checkRect.isValidRect()) { // can occur in Iceman - HACK? TODO: is this really occuring in sierra sci? check this warning("kCan(t)BeHere - invalid rect %d, %d -> %d, %d", checkRect.left, checkRect.top, checkRect.right, checkRect.bottom); - return false; + return NULL_REG; } adjustedRect = _coordAdjuster->onControl(checkRect); signal = readSelectorValue(_segMan, curObject, SELECTOR(signal)); controlMask = readSelectorValue(_segMan, curObject, SELECTOR(illegalBits)); - result = (isOnControl(GFX_SCREEN_MASK_CONTROL, adjustedRect) & controlMask) ? false : true; - if ((result) && (signal & (kSignalIgnoreActor | kSignalRemoveView)) == 0) { + result = isOnControl(GFX_SCREEN_MASK_CONTROL, adjustedRect) & controlMask; + if ((!result) && (signal & (kSignalIgnoreActor | kSignalRemoveView)) == 0) { List *list = _segMan->lookupList(listReference); if (!list) error("kCanBeHere called with non-list as parameter"); - result = canBeHereCheckRectList(curObject, checkRect, list); + return canBeHereCheckRectList(curObject, checkRect, list); } - return result; + return make_reg(0, result); } bool GfxCompare::kernelIsItSkip(GuiResourceId viewId, int16 loopNo, int16 celNo, Common::Point position) { @@ -205,21 +229,39 @@ void GfxCompare::kernelBaseSetter(reg_t object) { if (viewId == 0xFFFF) // invalid view return; - GfxView *tmpView = _cache->getView(viewId); + // must be something wrong with this TODO check - currently it breaks qfg3 right after the intro + //uint16 scaleSignal = 0; + //if (getSciVersion() >= SCI_VERSION_1_1) { + // scaleSignal = readSelectorValue(_segMan, object, SELECTOR(scaleSignal)) & kScaleSignalDoScaling; + // if (scaleSignal) { + // int16 scaleY = readSelectorValue(_segMan, object, SELECTOR(scaleY)); + // if (scaleY < 64) + // scaleSignal = 0; + // } + //} + Common::Rect celRect; - if (tmpView->isSci2Hires()) - _screen->adjustToUpscaledCoordinates(y, x); + //if (!scaleSignal) { + GfxView *tmpView = _cache->getView(viewId); + if (tmpView->isSci2Hires()) + _screen->adjustToUpscaledCoordinates(y, x); - tmpView->getCelRect(loopNo, celNo, x, y, z, celRect); + tmpView->getCelRect(loopNo, celNo, x, y, z, celRect); - if (tmpView->isSci2Hires()) { - _screen->adjustBackUpscaledCoordinates(celRect.top, celRect.left); - _screen->adjustBackUpscaledCoordinates(celRect.bottom, celRect.right); - } + if (tmpView->isSci2Hires()) { + _screen->adjustBackUpscaledCoordinates(celRect.top, celRect.left); + _screen->adjustBackUpscaledCoordinates(celRect.bottom, celRect.right); + } - celRect.bottom = y + 1; - celRect.top = celRect.bottom - yStep; + celRect.bottom = y + 1; + celRect.top = celRect.bottom - yStep; + //} else { + // celRect.left = readSelectorValue(_segMan, object, SELECTOR(nsLeft)); + // celRect.right = readSelectorValue(_segMan, object, SELECTOR(nsRight)); + // celRect.top = readSelectorValue(_segMan, object, SELECTOR(nsTop)); + // celRect.bottom = readSelectorValue(_segMan, object, SELECTOR(nsBottom)); + //} writeSelectorValue(_segMan, object, SELECTOR(brLeft), celRect.left); writeSelectorValue(_segMan, object, SELECTOR(brRight), celRect.right); diff --git a/engines/sci/graphics/compare.h b/engines/sci/graphics/compare.h index be461cdc5b..1079f5f98c 100644 --- a/engines/sci/graphics/compare.h +++ b/engines/sci/graphics/compare.h @@ -42,7 +42,7 @@ public: uint16 kernelOnControl(byte screenMask, const Common::Rect &rect); void kernelSetNowSeen(reg_t objectReference); - bool kernelCanBeHere(reg_t curObject, reg_t listReference); + reg_t kernelCanBeHere(reg_t curObject, reg_t listReference); bool kernelIsItSkip(GuiResourceId viewId, int16 loopNo, int16 celNo, Common::Point position); void kernelBaseSetter(reg_t object); @@ -60,7 +60,7 @@ private: * *different* from checkObject, has a brRect which is contained inside * checkRect. */ - bool canBeHereCheckRectList(reg_t checkObject, const Common::Rect &checkRect, List *list); + reg_t canBeHereCheckRectList(reg_t checkObject, const Common::Rect &checkRect, List *list); }; } // End of namespace Sci diff --git a/engines/sci/graphics/controls.cpp b/engines/sci/graphics/controls.cpp index ff5a91eed4..5891413be8 100644 --- a/engines/sci/graphics/controls.cpp +++ b/engines/sci/graphics/controls.cpp @@ -75,7 +75,9 @@ void GfxControls::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, // draw UP/DOWN arrows // we draw UP arrow one pixel lower than sierra did, because it looks nicer. Also the DOWN arrow has one pixel // line inbetween as well - workerRect.top++; + // They "fixed" this in SQ4 by having the arrow character start one pixel line later, we don't adjust there + if (g_sci->getGameId() != GID_SQ4) + workerRect.top++; _text16->Box(controlListUpArrow, 0, workerRect, SCI_TEXT16_ALIGNMENT_CENTER, 0); workerRect.top = workerRect.bottom - 10; _text16->Box(controlListDownArrow, 0, workerRect, SCI_TEXT16_ALIGNMENT_CENTER, 0); @@ -89,7 +91,7 @@ void GfxControls::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, _text16->SetFont(fontId); fontSize = _ports->_curPort->fontHeight; _ports->penColor(_ports->_curPort->penClr); _ports->backColor(_ports->_curPort->backClr); - workerRect.bottom = workerRect.top + 9; + workerRect.bottom = workerRect.top + fontSize; lastYpos = rect.bottom - fontSize; // Write actual text diff --git a/engines/sci/graphics/coordadjuster.cpp b/engines/sci/graphics/coordadjuster.cpp index 9481a68f13..bbeade87b5 100644 --- a/engines/sci/graphics/coordadjuster.cpp +++ b/engines/sci/graphics/coordadjuster.cpp @@ -31,6 +31,7 @@ #include "sci/engine/selector.h" #include "sci/graphics/coordadjuster.h" #include "sci/graphics/ports.h" +#include "sci/graphics/screen.h" namespace Sci { @@ -88,32 +89,41 @@ Common::Rect GfxCoordAdjuster16::pictureGetDisplayArea() { #ifdef ENABLE_SCI32 GfxCoordAdjuster32::GfxCoordAdjuster32(SegManager *segMan) : _segMan(segMan) { + scriptsRunningWidth = 0; + scriptsRunningHeight = 0; } GfxCoordAdjuster32::~GfxCoordAdjuster32() { } void GfxCoordAdjuster32::kernelGlobalToLocal(int16 &x, int16 &y, reg_t planeObject) { - //int16 resY = readSelectorValue(_s->_segMan, planeObj, SELECTOR(resY)); - //int16 resX = readSelectorValue(_s->_segMan, planeObj, SELECTOR(resX)); - //*x = ( *x * _screen->getWidth()) / resX; - //*y = ( *y * _screen->getHeight()) / resY; - x -= readSelectorValue(_segMan, planeObject, SELECTOR(left)); - y -= readSelectorValue(_segMan, planeObject, SELECTOR(top)); + uint16 planeTop = readSelectorValue(_segMan, planeObject, SELECTOR(top)); + uint16 planeLeft = readSelectorValue(_segMan, planeObject, SELECTOR(left)); + + y -= planeTop; + x -= planeLeft; } void GfxCoordAdjuster32::kernelLocalToGlobal(int16 &x, int16 &y, reg_t planeObject) { - //int16 resY = readSelectorValue(_s->_segMan, planeObj, SELECTOR(resY)); - //int16 resX = readSelectorValue(_s->_segMan, planeObj, SELECTOR(resX)); - x += readSelectorValue(_segMan, planeObject, SELECTOR(left)); - y += readSelectorValue(_segMan, planeObject, SELECTOR(top)); - //*x = ( *x * resX) / _screen->getWidth(); - //*y = ( *y * resY) / _screen->getHeight(); + uint16 planeTop = readSelectorValue(_segMan, planeObject, SELECTOR(top)); + uint16 planeLeft = readSelectorValue(_segMan, planeObject, SELECTOR(left)); + + x += planeLeft; + y += planeTop; } -Common::Rect GfxCoordAdjuster32::onControl(Common::Rect rect) { - Common::Rect adjustedRect = rect; - adjustedRect.translate(0, 10); - return adjustedRect; +void GfxCoordAdjuster32::setScriptsResolution(uint16 width, uint16 height) { + scriptsRunningWidth = width; + scriptsRunningHeight = height; +} + +void GfxCoordAdjuster32::fromDisplayToScript(int16 &y, int16 &x) { + y = ((y * scriptsRunningHeight) / g_sci->_gfxScreen->getHeight()); + x = ((x * scriptsRunningWidth) / g_sci->_gfxScreen->getWidth()); +} + +void GfxCoordAdjuster32::fromScriptToDisplay(int16 &y, int16 &x) { + y = ((y * g_sci->_gfxScreen->getHeight()) / scriptsRunningHeight); + x = ((x * g_sci->_gfxScreen->getWidth()) / scriptsRunningWidth); } void GfxCoordAdjuster32::pictureSetDisplayArea(Common::Rect displayArea) { diff --git a/engines/sci/graphics/coordadjuster.h b/engines/sci/graphics/coordadjuster.h index 9b2bef48f1..59afd1dcb7 100644 --- a/engines/sci/graphics/coordadjuster.h +++ b/engines/sci/graphics/coordadjuster.h @@ -50,6 +50,10 @@ public: virtual void setCursorPos(Common::Point &pos) { } virtual void moveCursor(Common::Point &pos) { } + virtual void setScriptsResolution(uint16 width, uint16 height) { } + virtual void fromScriptToDisplay(int16 &y, int16 &x) { } + virtual void fromDisplayToScript(int16 &y, int16 &x) { } + virtual Common::Rect pictureGetDisplayArea() { return Common::Rect(0, 0); } private: }; @@ -83,7 +87,9 @@ public: void kernelGlobalToLocal(int16 &x, int16 &y, reg_t planeObject = NULL_REG); void kernelLocalToGlobal(int16 &x, int16 &y, reg_t planeObject = NULL_REG); - Common::Rect onControl(Common::Rect rect); + void setScriptsResolution(uint16 width, uint16 height); + void fromScriptToDisplay(int16 &y, int16 &x); + void fromDisplayToScript(int16 &y, int16 &x); void pictureSetDisplayArea(Common::Rect displayArea); Common::Rect pictureGetDisplayArea(); @@ -92,6 +98,9 @@ private: SegManager *_segMan; Common::Rect _pictureDisplayArea; + + uint16 scriptsRunningWidth; + uint16 scriptsRunningHeight; }; #endif diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp index e1c05c97da..f6e2077cb3 100644 --- a/engines/sci/graphics/cursor.cpp +++ b/engines/sci/graphics/cursor.cpp @@ -47,7 +47,7 @@ GfxCursor::GfxCursor(ResourceManager *resMan, GfxPalette *palette, GfxScreen *sc // center mouse cursor setPosition(Common::Point(_screen->getWidth() / 2, _screen->getHeight() / 2)); - kernelSetMoveZone(Common::Rect(0, 0, _screen->getDisplayWidth(), _screen->getDisplayHeight())); + _moveZoneActive = false; } GfxCursor::~GfxCursor() { @@ -283,32 +283,39 @@ Common::Point GfxCursor::getPosition() { } void GfxCursor::refreshPosition() { - bool clipped = false; - Common::Point mousePoint = getPosition(); - - if (mousePoint.x < _moveZone.left) { - mousePoint.x = _moveZone.left; - clipped = true; - } else if (mousePoint.x >= _moveZone.right) { - mousePoint.x = _moveZone.right - 1; - clipped = true; - } + if (_moveZoneActive) { + bool clipped = false; + Common::Point mousePoint = getPosition(); + + if (mousePoint.x < _moveZone.left) { + mousePoint.x = _moveZone.left; + clipped = true; + } else if (mousePoint.x >= _moveZone.right) { + mousePoint.x = _moveZone.right - 1; + clipped = true; + } - if (mousePoint.y < _moveZone.top) { - mousePoint.y = _moveZone.top; - clipped = true; - } else if (mousePoint.y >= _moveZone.bottom) { - mousePoint.y = _moveZone.bottom - 1; - clipped = true; + if (mousePoint.y < _moveZone.top) { + mousePoint.y = _moveZone.top; + clipped = true; + } else if (mousePoint.y >= _moveZone.bottom) { + mousePoint.y = _moveZone.bottom - 1; + clipped = true; + } + + // FIXME: Do this only when mouse is grabbed? + if (clipped) + setPosition(mousePoint); } +} - // FIXME: Do this only when mouse is grabbed? - if (clipped) - setPosition(mousePoint); +void GfxCursor::kernelResetMoveZone() { + _moveZoneActive = false; } void GfxCursor::kernelSetMoveZone(Common::Rect zone) { - _moveZone = zone; + _moveZone = zone; + _moveZoneActive = true; } void GfxCursor::kernelSetPos(Common::Point pos) { diff --git a/engines/sci/graphics/cursor.h b/engines/sci/graphics/cursor.h index 7acd14acd9..787841f5be 100644 --- a/engines/sci/graphics/cursor.h +++ b/engines/sci/graphics/cursor.h @@ -58,6 +58,11 @@ public: void refreshPosition(); /** + * Removes limit for mouse movement + */ + void kernelResetMoveZone(); + + /** * Limits the mouse movement to a given rectangle. * * @param[in] rect The rectangle @@ -78,6 +83,7 @@ private: int _upscaledHires; + bool _moveZoneActive; Common::Rect _moveZone; // Rectangle in which the pointer can move CursorCache _cachedCursors; diff --git a/engines/sci/graphics/font.h b/engines/sci/graphics/font.h index 90f18e426d..b9bee0fa9e 100644 --- a/engines/sci/graphics/font.h +++ b/engines/sci/graphics/font.h @@ -32,14 +32,14 @@ namespace Sci { class GfxFont { public: - GfxFont() {}; - virtual ~GfxFont() {}; - - virtual GuiResourceId getResourceId() { return 0; }; - virtual byte getHeight() { return 0; }; - virtual bool isDoubleByte(uint16 chr) { return false; }; - virtual byte getCharWidth(uint16 chr) { return 0; }; - virtual void draw(uint16 chr, int16 top, int16 left, byte color, bool greyedOutput) {}; + GfxFont() {} + virtual ~GfxFont() {} + + virtual GuiResourceId getResourceId() { return 0; } + virtual byte getHeight() { return 0; } + virtual bool isDoubleByte(uint16 chr) { return false; } + virtual byte getCharWidth(uint16 chr) { return 0; } + virtual void draw(uint16 chr, int16 top, int16 left, byte color, bool greyedOutput) {} }; diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index 9ce4474ee3..06dce6d111 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -48,24 +48,92 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd : _segMan(segMan), _resMan(resMan), _cache(cache), _screen(screen), _palette(palette), _paint32(paint32) { _coordAdjuster = (GfxCoordAdjuster32 *)coordAdjuster; + scriptsRunningWidth = 320; + scriptsRunningHeight = 200; } GfxFrameout::~GfxFrameout() { } void GfxFrameout::kernelAddPlane(reg_t object) { - _planes.push_back(object); - sortPlanes(); + PlaneEntry newPlane; + + if (_planes.empty()) { + // There has to be another way for sierra sci to do this or maybe script resolution is compiled into + // interpreter (TODO) + scriptsRunningHeight = readSelectorValue(_segMan, object, SELECTOR(resY)); + scriptsRunningWidth = readSelectorValue(_segMan, object, SELECTOR(resX)); + _coordAdjuster->setScriptsResolution(scriptsRunningWidth, scriptsRunningHeight); + } + + newPlane.object = object; + newPlane.pictureId = 0xFFFF; + newPlane.lastPriority = 0xFFFF; // hidden + _planes.push_back(newPlane); + + kernelUpdatePlane(object); } void GfxFrameout::kernelUpdatePlane(reg_t object) { - sortPlanes(); + for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) { + if (it->object == object) { + // Read some information + it->priority = readSelectorValue(_segMan, object, SELECTOR(priority)); + GuiResourceId lastPictureId = it->pictureId; + it->pictureId = readSelectorValue(_segMan, object, SELECTOR(picture)); + if (lastPictureId != it->pictureId) { + // picture got changed, load new picture + deletePlanePictures(object); + if ((it->pictureId != 0xFFFF) && (it->pictureId != 0xFFFE)) { + // SQ6 gives us a bad picture number for the control menu + if (_resMan->testResource(ResourceId(kResourceTypePic, it->pictureId))) + addPlanePicture(object, it->pictureId, 0); + } + } + sortPlanes(); + return; + } + } + error("kUpdatePlane called on plane that wasn't added before"); } void GfxFrameout::kernelDeletePlane(reg_t object) { - for (Common::List<reg_t>::iterator it = _planes.begin(); it != _planes.end(); it++) { - if (object == *it) { + deletePlanePictures(object); + for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) { + if (it->object == object) { _planes.erase(it); + Common::Rect planeRect; + planeRect.top = readSelectorValue(_segMan, object, SELECTOR(top)); + planeRect.left = readSelectorValue(_segMan, object, SELECTOR(left)); + planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)) + 1; + planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)) + 1; + + planeRect.top = (planeRect.top * _screen->getHeight()) / scriptsRunningHeight; + planeRect.left = (planeRect.left * _screen->getWidth()) / scriptsRunningWidth; + planeRect.bottom = (planeRect.bottom * _screen->getHeight()) / scriptsRunningHeight; + planeRect.right = (planeRect.right * _screen->getWidth()) / scriptsRunningWidth; + // Blackout removed plane rect + _paint32->fillRect(planeRect, 0); + return; + } + } +} + +void GfxFrameout::addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 startX) { + PlanePictureEntry newPicture; + newPicture.object = object; + newPicture.pictureId = pictureId; + newPicture.picture = new GfxPicture(_resMan, _coordAdjuster, 0, _screen, _palette, pictureId, false); + newPicture.startX = startX; + _planePictures.push_back(newPicture); +} + +void GfxFrameout::deletePlanePictures(reg_t object) { + for (PlanePictureList::iterator it = _planePictures.begin(); it != _planePictures.end(); it++) { + if (it->object == object) { + delete it->picture; + _planePictures.erase(it); + deletePlanePictures(object); return; } } @@ -73,7 +141,6 @@ void GfxFrameout::kernelDeletePlane(reg_t object) { void GfxFrameout::kernelAddScreenItem(reg_t object) { _screenItems.push_back(object); - warning("addScreenItem %X:%X (%s)", object.segment, object.offset, _segMan->getObjectName(object)); } void GfxFrameout::kernelDeleteScreenItem(reg_t object) { @@ -87,32 +154,42 @@ void GfxFrameout::kernelDeleteScreenItem(reg_t object) { int16 GfxFrameout::kernelGetHighPlanePri() { sortPlanes(); - return readSelectorValue(g_sci->getEngineState()->_segMan, _planes.back(), SELECTOR(priority)); + return readSelectorValue(g_sci->getEngineState()->_segMan, _planes.back().object, SELECTOR(priority)); +} + +// No idea yet how to implement this +void GfxFrameout::kernelAddPicAt(reg_t planeObj, int16 forWidth, GuiResourceId pictureId) { + addPlanePicture(planeObj, pictureId, forWidth); } bool sortHelper(const FrameoutEntry* entry1, const FrameoutEntry* entry2) { - return (entry1->priority == entry2->priority) ? (entry1->y < entry2->y) : (entry1->priority < entry2->priority); + if (entry1->priority == entry2->priority) { + if (entry1->y == entry2->y) + return (entry1->givenOrderNr < entry2->givenOrderNr); + return (entry1->y < entry2->y); + } + return (entry1->priority < entry2->priority); } -bool planeSortHelper(const reg_t entry1, const reg_t entry2) { - SegManager *segMan = g_sci->getEngineState()->_segMan; +bool planeSortHelper(const PlaneEntry &entry1, const PlaneEntry &entry2) { +// SegManager *segMan = g_sci->getEngineState()->_segMan; - uint16 plane1Priority = readSelectorValue(segMan, entry1, SELECTOR(priority)); - uint16 plane2Priority = readSelectorValue(segMan, entry2, SELECTOR(priority)); +// uint16 plane1Priority = readSelectorValue(segMan, entry1, SELECTOR(priority)); +// uint16 plane2Priority = readSelectorValue(segMan, entry2, SELECTOR(priority)); - if (plane1Priority == 0xffff) + if (entry1.priority == 0xffff) return true; - if (plane2Priority == 0xffff) + if (entry2.priority == 0xffff) return false; - return plane1Priority < plane2Priority; + return entry1.priority < entry2.priority; } void GfxFrameout::sortPlanes() { // First, remove any invalid planes - for (Common::List<reg_t>::iterator it = _planes.begin(); it != _planes.end();) { - if (!_segMan->isObject(*it)) + for (PlaneList::iterator it = _planes.begin(); it != _planes.end();) { + if (!_segMan->isObject(it->object)) it = _planes.erase(it); else it++; @@ -126,45 +203,72 @@ void GfxFrameout::kernelFrameout() { _palette->palVaryUpdate(); // Allocate enough space for all screen items - FrameoutEntry *itemData = (FrameoutEntry *)malloc(_screenItems.size() * sizeof(FrameoutEntry)); + FrameoutEntry *itemData = new FrameoutEntry[_screenItems.size()]; - const SciGameId gameId = g_sci->getGameId(); - - for (Common::List<reg_t>::iterator it = _planes.begin(); it != _planes.end(); it++) { - reg_t planeObject = *it; - uint16 planePriority = readSelectorValue(_segMan, planeObject, SELECTOR(priority)); - - if (planePriority == 0xffff) // Plane currently not meant to be shown - continue; + for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) { + reg_t planeObject = it->object; + uint16 planeLastPriority = it->lastPriority; Common::Rect planeRect; planeRect.top = readSelectorValue(_segMan, planeObject, SELECTOR(top)); planeRect.left = readSelectorValue(_segMan, planeObject, SELECTOR(left)); - planeRect.bottom = readSelectorValue(_segMan, planeObject, SELECTOR(bottom)); - planeRect.right = readSelectorValue(_segMan, planeObject, SELECTOR(right)); - int16 planeResY = readSelectorValue(_segMan, planeObject, SELECTOR(resY)); - int16 planeResX = readSelectorValue(_segMan, planeObject, SELECTOR(resX)); + planeRect.bottom = readSelectorValue(_segMan, planeObject, SELECTOR(bottom)) + 1; + planeRect.right = readSelectorValue(_segMan, planeObject, SELECTOR(right)) + 1; + + // Update priority here, sq6 sets it w/o UpdatePlane + uint16 planePriority = it->priority = readSelectorValue(_segMan, planeObject, SELECTOR(priority)); - planeRect.top = (planeRect.top * _screen->getHeight()) / planeResY; - planeRect.left = (planeRect.left * _screen->getWidth()) / planeResX; - planeRect.bottom = (planeRect.bottom * _screen->getHeight()) / planeResY; - planeRect.right = (planeRect.right * _screen->getWidth()) / planeResX; + planeRect.top = (planeRect.top * _screen->getHeight()) / scriptsRunningHeight; + planeRect.left = (planeRect.left * _screen->getWidth()) / scriptsRunningWidth; + planeRect.bottom = (planeRect.bottom * _screen->getHeight()) / scriptsRunningHeight; + planeRect.right = (planeRect.right * _screen->getWidth()) / scriptsRunningWidth; + + int16 planeOffsetX = 0; + + // We get negative left in kq7 in scrolling rooms + if (planeRect.left < 0) { + planeOffsetX = -planeRect.left; + planeRect.left = 0; + } + if (planeRect.top < 0) + planeRect.top = 0; + // We get bad plane-bottom in sq6 + if (planeRect.right > _screen->getWidth()) + planeRect.right = _screen->getWidth(); + if (planeRect.bottom > _screen->getHeight()) + planeRect.bottom = _screen->getHeight(); + + it->lastPriority = planePriority; + if (planePriority == 0xffff) { // Plane currently not meant to be shown + // If plane was shown before, delete plane rect + if (planePriority != planeLastPriority) + _paint32->fillRect(planeRect, 0); + continue; + } + + Common::Rect planeClipRect(planeRect.width(), planeRect.height()); + + Common::Rect upscaledPlaneRect = planeRect; + Common::Rect upscaledPlaneClipRect = planeClipRect; + if (_screen->getUpscaledHires()) { + _screen->adjustToUpscaledCoordinates(upscaledPlaneRect.top, upscaledPlaneRect.left); + _screen->adjustToUpscaledCoordinates(upscaledPlaneRect.bottom, upscaledPlaneRect.right); + _screen->adjustToUpscaledCoordinates(upscaledPlaneClipRect.top, upscaledPlaneClipRect.left); + _screen->adjustToUpscaledCoordinates(upscaledPlaneClipRect.bottom, upscaledPlaneClipRect.right); + } byte planeBack = readSelectorValue(_segMan, planeObject, SELECTOR(back)); if (planeBack) _paint32->fillRect(planeRect, planeBack); - GuiResourceId planePictureNr = readSelectorValue(_segMan, planeObject, SELECTOR(picture)); - GfxPicture *planePicture = 0; - int16 planePictureCels = 0; + GuiResourceId planeMainPictureId = it->pictureId; - if ((planePictureNr != 0xFFFF) && (planePictureNr != 0xFFFE)) { - planePicture = new GfxPicture(_resMan, _coordAdjuster, 0, _screen, _palette, planePictureNr, false); - planePictureCels = planePicture->getSci32celCount(); + bool planePictureMirrored = false; + if (readSelectorValue(_segMan, planeObject, SELECTOR(mirrored))) + planePictureMirrored = true; - _coordAdjuster->pictureSetDisplayArea(planeRect); - _palette->drewPicture(planePictureNr); - } + _coordAdjuster->pictureSetDisplayArea(planeRect); + _palette->drewPicture(planeMainPictureId); // Fill our itemlist for this plane int16 itemCount = 0; @@ -191,27 +295,14 @@ void GfxFrameout::kernelFrameout() { itemEntry->y = readSelectorValue(_segMan, itemObject, SELECTOR(y)); itemEntry->z = readSelectorValue(_segMan, itemObject, SELECTOR(z)); itemEntry->priority = readSelectorValue(_segMan, itemObject, SELECTOR(priority)); - if (gameId == GID_GK1) { - if ((itemEntry->viewId == 11000) && (itemEntry->loopNo == 0) && (itemEntry->celNo == 0) && (itemEntry->priority == 1)) { - itemEntry->priority = 0; // HACK for gk1 hires main menu - } - if ((itemEntry->viewId == 10100) && (itemEntry->priority == 0)) { - itemEntry->priority = 1; // HACK for gk1 hires main menu - } - } + if (readSelectorValue(_segMan, itemObject, SELECTOR(fixPriority)) == 0) + itemEntry->priority = itemEntry->y; + itemEntry->signal = readSelectorValue(_segMan, itemObject, SELECTOR(signal)); itemEntry->scaleX = readSelectorValue(_segMan, itemObject, SELECTOR(scaleX)); itemEntry->scaleY = readSelectorValue(_segMan, itemObject, SELECTOR(scaleY)); itemEntry->object = itemObject; - - itemEntry->y = ((itemEntry->y * _screen->getHeight()) / planeResY); - itemEntry->x = ((itemEntry->x * _screen->getWidth()) / planeResX); - itemEntry->y += planeRect.top; - itemEntry->x += planeRect.left; - - if (!(itemEntry->signal & 0x0010)) { // kSignalFixedPriority - // TODO: Change priority of this item - } + itemEntry->givenOrderNr = itemNr; itemList.push_back(itemEntry); itemEntry++; @@ -219,32 +310,139 @@ void GfxFrameout::kernelFrameout() { } } + for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) { + if (pictureIt->object == planeObject) { + GfxPicture *planePicture = pictureIt->picture; + // Allocate memory for picture cels + pictureIt->pictureCels = new FrameoutEntry[planePicture->getSci32celCount()]; + + // Add following cels to the itemlist + FrameoutEntry *picEntry = pictureIt->pictureCels; + int planePictureCels = planePicture->getSci32celCount(); + for (int pictureCelNr = 0; pictureCelNr < planePictureCels; pictureCelNr++) { + picEntry->celNo = pictureCelNr; + picEntry->object = NULL_REG; + picEntry->picture = planePicture; + picEntry->y = planePicture->getSci32celY(pictureCelNr); + picEntry->x = planePicture->getSci32celX(pictureCelNr); + picEntry->picStartX = pictureIt->startX; + + picEntry->priority = planePicture->getSci32celPriority(pictureCelNr); + + itemList.push_back(picEntry); + picEntry++; + } + } + } + // Now sort our itemlist Common::sort(itemList.begin(), itemList.end(), sortHelper); // Now display itemlist - int16 planePictureCel = 0; itemEntry = itemData; +// warning("Plane %s", _segMan->getObjectName(planeObject)); + for (FrameoutList::iterator listIterator = itemList.begin(); listIterator != itemList.end(); listIterator++) { itemEntry = *listIterator; - if (planePicture) { - while ((planePictureCel <= itemEntry->priority) && (planePictureCel < planePictureCels)) { - planePicture->drawSci32Vga(planePictureCel); - planePictureCel++; + + if (itemEntry->object.isNull()) { + // Picture cel data + itemEntry->y = ((itemEntry->y * _screen->getHeight()) / scriptsRunningHeight); + itemEntry->x = ((itemEntry->x * _screen->getWidth()) / scriptsRunningWidth); + itemEntry->picStartX = ((itemEntry->picStartX * _screen->getWidth()) / scriptsRunningWidth); + + // Out of view + int16 pictureCelStartX = itemEntry->picStartX + itemEntry->x; + int16 pictureCelEndX = pictureCelStartX + itemEntry->picture->getSci32celWidth(itemEntry->celNo); + int16 planeStartX = planeOffsetX; + int16 planeEndX = planeStartX + planeRect.width(); + if (pictureCelEndX < planeStartX) + continue; + if (pictureCelStartX > planeEndX) + continue; + + int16 pictureOffsetX = planeOffsetX; + int16 pictureX = itemEntry->x; + if (planeOffsetX) { + if (planeOffsetX <= itemEntry->picStartX) { + pictureX += itemEntry->picStartX - planeOffsetX; + pictureOffsetX = 0; + } else { + pictureOffsetX = planeOffsetX - itemEntry->picStartX; + } } - } - if (itemEntry->viewId != 0xFFFF) { + itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, planePictureMirrored); +// warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority); + + } else if (itemEntry->viewId != 0xFFFF) { GfxView *view = _cache->getView(itemEntry->viewId); - if (view->isSci2Hires()) - _screen->adjustToUpscaledCoordinates(itemEntry->y, itemEntry->x); +// warning("view %s %04x:%04x", _segMan->getObjectName(itemEntry->object), PRINT_REG(itemEntry->object)); - if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) - view->getCelRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->celRect); - else - view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX, itemEntry->scaleY, itemEntry->celRect); + switch (getSciVersion()) { + case SCI_VERSION_2: + if (view->isSci2Hires()) { + int16 dummyX = 0; + _screen->adjustToUpscaledCoordinates(itemEntry->y, itemEntry->x); + _screen->adjustToUpscaledCoordinates(itemEntry->z, dummyX); + } + break; + case SCI_VERSION_2_1: + itemEntry->y = (itemEntry->y * _screen->getHeight()) / scriptsRunningHeight; + itemEntry->x = (itemEntry->x * _screen->getWidth()) / scriptsRunningWidth; + itemEntry->z = (itemEntry->z * _screen->getHeight()) / scriptsRunningHeight; + break; + default: + break; + } + // Adjust according to current scroll position + itemEntry->x -= planeOffsetX; + + uint16 useInsetRect = readSelectorValue(_segMan, itemEntry->object, SELECTOR(useInsetRect)); + if (useInsetRect) { + itemEntry->celRect.top = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inTop)); + itemEntry->celRect.left = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inLeft)); + itemEntry->celRect.bottom = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inBottom)) + 1; + itemEntry->celRect.right = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inRight)) + 1; + if (view->isSci2Hires()) { + _screen->adjustToUpscaledCoordinates(itemEntry->celRect.top, itemEntry->celRect.left); + _screen->adjustToUpscaledCoordinates(itemEntry->celRect.bottom, itemEntry->celRect.right); + } + itemEntry->celRect.translate(itemEntry->x, itemEntry->y); + // TODO: maybe we should clip the cels rect with this, i'm not sure + // the only currently known usage is game menu of gk1 + } else { + if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) + view->getCelRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->celRect); + else + view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX, itemEntry->scaleY, itemEntry->celRect); + + Common::Rect nsRect = itemEntry->celRect; + // Translate back to actual coordinate within scrollable plane + nsRect.translate(planeOffsetX, 0); + switch (getSciVersion()) { + case SCI_VERSION_2: + if (view->isSci2Hires()) { + _screen->adjustBackUpscaledCoordinates(nsRect.top, nsRect.left); + _screen->adjustBackUpscaledCoordinates(nsRect.bottom, nsRect.right); + } + break; + case SCI_VERSION_2_1: + nsRect.top = (nsRect.top * scriptsRunningHeight) / _screen->getHeight(); + nsRect.left = (nsRect.left * scriptsRunningWidth) / _screen->getWidth(); + nsRect.bottom = (nsRect.bottom * scriptsRunningHeight) / _screen->getHeight(); + nsRect.right = (nsRect.right * scriptsRunningWidth) / _screen->getWidth(); + break; + default: + break; + } + writeSelectorValue(_segMan, itemEntry->object, SELECTOR(nsLeft), nsRect.left); + writeSelectorValue(_segMan, itemEntry->object, SELECTOR(nsTop), nsRect.top); + writeSelectorValue(_segMan, itemEntry->object, SELECTOR(nsRight), nsRect.right); + writeSelectorValue(_segMan, itemEntry->object, SELECTOR(nsBottom), nsRect.bottom); + } int16 screenHeight = _screen->getHeight(); int16 screenWidth = _screen->getWidth(); @@ -253,27 +451,30 @@ void GfxFrameout::kernelFrameout() { screenWidth = _screen->getDisplayWidth(); } - if (itemEntry->celRect.top < 0 || itemEntry->celRect.top >= screenHeight) + if (itemEntry->celRect.bottom < 0 || itemEntry->celRect.top >= screenHeight) continue; - if (itemEntry->celRect.left < 0 || itemEntry->celRect.left >= screenWidth) + if (itemEntry->celRect.right < 0 || itemEntry->celRect.left >= screenWidth) continue; - Common::Rect clipRect; + Common::Rect clipRect, translatedClipRect; clipRect = itemEntry->celRect; if (view->isSci2Hires()) { - Common::Rect upscaledPlaneRect = planeRect; - _screen->adjustToUpscaledCoordinates(upscaledPlaneRect.top, upscaledPlaneRect.left); - _screen->adjustToUpscaledCoordinates(upscaledPlaneRect.bottom, upscaledPlaneRect.right); - clipRect.clip(upscaledPlaneRect); + clipRect.clip(upscaledPlaneClipRect); + translatedClipRect = clipRect; + translatedClipRect.translate(upscaledPlaneRect.left, upscaledPlaneRect.top); } else { - clipRect.clip(planeRect); + clipRect.clip(planeClipRect); + translatedClipRect = clipRect; + translatedClipRect.translate(planeRect.left, planeRect.top); } - if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) - view->draw(itemEntry->celRect, clipRect, clipRect, itemEntry->loopNo, itemEntry->celNo, 255, 0, view->isSci2Hires()); - else - view->drawScaled(itemEntry->celRect, clipRect, clipRect, itemEntry->loopNo, itemEntry->celNo, 255, itemEntry->scaleX, itemEntry->scaleY); + if (!clipRect.isEmpty()) { + if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) + view->draw(itemEntry->celRect, clipRect, translatedClipRect, itemEntry->loopNo, itemEntry->celNo, 255, 0, view->isSci2Hires()); + else + view->drawScaled(itemEntry->celRect, clipRect, translatedClipRect, itemEntry->loopNo, itemEntry->celNo, 255, itemEntry->scaleX, itemEntry->scaleY); + } } else { // Most likely a text entry // This draws text the "SCI0-SCI11" way. In SCI2, text is prerendered in kCreateTextBitmap @@ -283,8 +484,12 @@ void GfxFrameout::kernelFrameout() { GfxFont *font = _cache->getFont(readSelectorValue(_segMan, itemEntry->object, SELECTOR(font))); bool dimmed = readSelectorValue(_segMan, itemEntry->object, SELECTOR(dimmed)); uint16 foreColor = readSelectorValue(_segMan, itemEntry->object, SELECTOR(fore)); - uint16 curX = itemEntry->x; - uint16 curY = itemEntry->y; + + itemEntry->y = ((itemEntry->y * _screen->getHeight()) / scriptsRunningHeight); + itemEntry->x = ((itemEntry->x * _screen->getWidth()) / scriptsRunningWidth); + + uint16 curX = itemEntry->x + planeRect.left; + uint16 curY = itemEntry->y + planeRect.top; for (uint32 i = 0; i < text.size(); i++) { unsigned char curChar = text[i]; // TODO: proper text splitting... this is a hack @@ -300,18 +505,17 @@ void GfxFrameout::kernelFrameout() { } } - if (planePicture) { - while (planePictureCel < planePictureCels) { - planePicture->drawSci32Vga(planePictureCel); - planePictureCel++; + for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) { + if (pictureIt->object == planeObject) { + delete[] pictureIt->pictureCels; } - delete planePicture; - planePicture = 0; } } - free(itemData); + delete[] itemData; _screen->copyToScreen(); + + g_sci->getEngineState()->_throttleTrigger = true; } } // End of namespace Sci diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index e4568ad602..f8f7e54a27 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -28,7 +28,17 @@ namespace Sci { +struct PlaneEntry { + reg_t object; + uint16 priority; + uint16 lastPriority; + GuiResourceId pictureId; +}; + +typedef Common::List<PlaneEntry> PlaneList; + struct FrameoutEntry { + uint16 givenOrderNr; reg_t object; GuiResourceId viewId; int16 loopNo; @@ -40,10 +50,22 @@ struct FrameoutEntry { int16 scaleX; int16 scaleY; Common::Rect celRect; + GfxPicture *picture; + int16 picStartX; }; typedef Common::List<FrameoutEntry *> FrameoutList; +struct PlanePictureEntry { + reg_t object; + int16 startX; + GuiResourceId pictureId; + GfxPicture *picture; + FrameoutEntry *pictureCels; // temporary +}; + +typedef Common::List<PlanePictureEntry> PlanePictureList; + class GfxCache; class GfxCoordAdjuster32; class GfxPaint32; @@ -63,8 +85,12 @@ public: void kernelAddScreenItem(reg_t object); void kernelDeleteScreenItem(reg_t object); int16 kernelGetHighPlanePri(); + void kernelAddPicAt(reg_t planeObj, int16 forWidth, GuiResourceId pictureId); void kernelFrameout(); + void addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 startX); + void deletePlanePictures(reg_t object); + private: SegManager *_segMan; ResourceManager *_resMan; @@ -75,9 +101,13 @@ private: GfxPaint32 *_paint32; Common::Array<reg_t> _screenItems; - Common::List<reg_t> _planes; + PlaneList _planes; + PlanePictureList _planePictures; void sortPlanes(); + + uint16 scriptsRunningWidth; + uint16 scriptsRunningHeight; }; } // End of namespace Sci diff --git a/engines/sci/graphics/helpers.h b/engines/sci/graphics/helpers.h index f0ffecfb59..8f26ca296b 100644 --- a/engines/sci/graphics/helpers.h +++ b/engines/sci/graphics/helpers.h @@ -28,6 +28,7 @@ #include "common/endian.h" // for READ_LE_UINT16 #include "common/rect.h" +#include "common/serializer.h" #include "sci/engine/vm_types.h" namespace Sci { diff --git a/engines/sci/graphics/menu.cpp b/engines/sci/graphics/menu.cpp index bfe58e03d5..630626c128 100644 --- a/engines/sci/graphics/menu.cpp +++ b/engines/sci/graphics/menu.cpp @@ -271,8 +271,15 @@ GuiMenuItemEntry *GfxMenu::findItem(uint16 menuId, uint16 itemId) { void GfxMenu::kernelSetAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value) { GuiMenuItemEntry *itemEntry = findItem(menuId, itemId); - if (!itemEntry) - error("Tried to setAttribute() on non-existant menu-item %d:%d", menuId, itemId); + + if (!itemEntry) { + // PQ2 demo calls this, for example, but has no menus (bug report #3034507). Some SCI + // fan games (Al Pond 2, Aquarius) call this too on non-existent menu items. The + // original interpreter ignored these as well. + debugC(2, kDebugLevelGraphics, "Tried to setAttribute() on non-existent menu-item %d:%d", menuId, itemId); + return; + } + switch (attributeId) { case SCI_MENU_ATTRIBUTE_ENABLED: itemEntry->enabled = value.isNull() ? false : true; @@ -391,7 +398,6 @@ reg_t GfxMenu::kernelSelect(reg_t eventObject, bool pauseSound) { GuiMenuItemEntry *itemEntry = NULL; bool forceClaimed = false; EngineState *s; - byte saidSpec[64]; switch (eventType) { case SCI_EVENT_KEYBOARD: @@ -431,8 +437,13 @@ reg_t GfxMenu::kernelSelect(reg_t eventObject, bool pauseSound) { itemEntry = *itemIterator; if (!itemEntry->saidVmPtr.isNull()) { - // TODO: get a pointer to saidVmPtr or make said() work on VmPtrs - _segMan->memcpy(saidSpec, itemEntry->saidVmPtr, 64); + byte *saidSpec = _segMan->derefBulkPtr(itemEntry->saidVmPtr, 0); + + if (!saidSpec) { + warning("Could not dereference saidSpec"); + continue; + } + if (said(s, saidSpec, 0) != SAID_NO_MATCH) break; } @@ -467,8 +478,10 @@ reg_t GfxMenu::kernelSelect(reg_t eventObject, bool pauseSound) { _paint16->bitsShow(_ports->_menuRect); _barSaveHandle = NULL_REG; } - if (_oldPort) + if (_oldPort) { _ports->setPort(_oldPort); + _oldPort = NULL; + } if ((itemEntry) || (forceClaimed)) writeSelector(_segMan, eventObject, SELECTOR(claimed), make_reg(0, 1)); diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp index 90b05c68a6..bb3975e9ef 100644 --- a/engines/sci/graphics/paint16.cpp +++ b/engines/sci/graphics/paint16.cpp @@ -32,6 +32,7 @@ #include "sci/engine/features.h" #include "sci/engine/state.h" #include "sci/engine/selector.h" +#include "sci/engine/workarounds.h" #include "sci/graphics/cache.h" #include "sci/graphics/coordadjuster.h" #include "sci/graphics/ports.h" @@ -382,11 +383,11 @@ void GfxPaint16::kernelDrawPicture(GuiResourceId pictureId, int16 animationNr, b _ports->setPort(oldPort); } -void GfxPaint16::kernelDrawCel(GuiResourceId viewId, int16 loopNo, int16 celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, bool hiresMode, reg_t upscaledHiresHandle) { +void GfxPaint16::kernelDrawCel(GuiResourceId viewId, int16 loopNo, int16 celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, uint16 scaleX, uint16 scaleY, bool hiresMode, reg_t upscaledHiresHandle) { // some calls are hiresMode even under kq6 DOS, that's why we check for // upscaled hires here if ((!hiresMode) || (!_screen->getUpscaledHires())) { - drawCelAndShow(viewId, loopNo, celNo, leftPos, topPos, priority, paletteNo); + drawCelAndShow(viewId, loopNo, celNo, leftPos, topPos, priority, paletteNo, scaleX, scaleY); } else { drawHiresCelAndShow(viewId, loopNo, celNo, leftPos, topPos, priority, paletteNo, upscaledHiresHandle); } @@ -463,7 +464,7 @@ void GfxPaint16::kernelGraphRedrawBox(Common::Rect rect) { #define SCI_DISPLAY_DONTSHOWBITS 121 reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) { - int displayArg; + reg_t displayArg; TextAlignment alignment = SCI_TEXT16_ALIGNMENT_LEFT; int16 colorPen = -1, colorBack = -1, width = -1, bRedraw = 1; bool doSaveUnder = false; @@ -480,9 +481,11 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) { _ports->textGreyedOutput(false); // processing codes in argv while (argc > 0) { - displayArg = argv[0].toUint16(); + displayArg = argv[0]; + if (displayArg.segment) + displayArg.offset = 0xFFFF; argc--; argv++; - switch (displayArg) { + switch (displayArg.offset) { case SCI_DISPLAY_MOVEPEN: _ports->moveTo(argv[0].toUint16(), argv[1].toUint16()); argc -= 2; argv += 2; @@ -531,8 +534,8 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) { case SCI_DISPLAY_DUMMY1: case SCI_DISPLAY_DUMMY2: if (!((g_sci->getGameId() == GID_LONGBOW) && (g_sci->isDemo()))) - error("Unknown kDisplay argument %X", displayArg); - if (displayArg == SCI_DISPLAY_DUMMY2) { + error("Unknown kDisplay argument %X", displayArg.offset); + if (displayArg.offset == SCI_DISPLAY_DUMMY2) { if (argc) { argc--; argv++; } else { @@ -541,9 +544,11 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) { } break; default: - if ((g_sci->getGameId() == GID_ISLANDBRAIN) && (g_sci->getEngineState()->currentRoomNumber() == 300)) - break; // WORKAROUND: we are called there with an forwarded 0 as additional parameter (script bug) - error("Unknown kDisplay argument %X", displayArg); + SciTrackOriginReply originReply; + SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, kDisplay_workarounds, &originReply); + if (solution.type == WORKAROUND_NONE) + error("Unknown kDisplay argument (%04x:%04x) from method %s::%s (script %d, localCall %x)", PRINT_REG(displayArg), originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, originReply.localCallOffset); + assert(solution.type == WORKAROUND_IGNORE); break; } } diff --git a/engines/sci/graphics/paint16.h b/engines/sci/graphics/paint16.h index 4c3ac255c4..edffa8da6e 100644 --- a/engines/sci/graphics/paint16.h +++ b/engines/sci/graphics/paint16.h @@ -73,7 +73,7 @@ public: void bitsFree(reg_t memoryHandle); void kernelDrawPicture(GuiResourceId pictureId, int16 animationNr, bool animationBlackoutFlag, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo); - void kernelDrawCel(GuiResourceId viewId, int16 loopNo, int16 celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, bool hiresMode, reg_t upscaledHiresHandle); + void kernelDrawCel(GuiResourceId viewId, int16 loopNo, int16 celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, uint16 scaleX, uint16 scaleY, bool hiresMode, reg_t upscaledHiresHandle); void kernelGraphFillBoxForeground(const Common::Rect &rect); void kernelGraphFillBoxBackground(const Common::Rect &rect); diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp index 957199f8b9..5c17f76558 100644 --- a/engines/sci/graphics/palette.cpp +++ b/engines/sci/graphics/palette.cpp @@ -60,18 +60,20 @@ GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen, bool useMergi _sysPaletteChanged = false; - // Pseudo-WORKAROUND - // Quest for Glory 3 demo, Eco Quest 1 demo, Laura Bow 2 demo, Police Quest 1 vga and all Nick's Picks - // all use an inbetween interpreter, some parts are SCI1.1, some parts are SCI1 - // It's not using the SCI1.1 palette merging (copying over all the colors) but the real merging - // If we use the copying over, we will get issues because some views have marked all colors as being used - // and those will overwrite the current palette in that case + // Quest for Glory 3 demo, Eco Quest 1 demo, Laura Bow 2 demo, Police Quest + // 1 vga and all Nick's Picks all use the older palette format and thus are + // not using the SCI1.1 palette merging (copying over all the colors) but + // the real merging done in earlier games. If we use the copying over, we + // will get issues because some views have marked all colors as being used + // and those will overwrite the current palette in that case _useMerging = useMerging; palVaryInit(); } GfxPalette::~GfxPalette() { + if (_palVaryResourceId != -1) + palVaryRemoveTimer(); } bool GfxPalette::isMerging() { @@ -106,9 +108,11 @@ void GfxPalette::createFromData(byte *data, int bytesLeft, Palette *paletteOut) if (bytesLeft < 37) { // This happens when loading palette of picture 0 in sq5 - the resource is broken and doesn't contain a full // palette - warning("GfxPalette::createFromData() - not enough bytes in resource, expected palette header"); + debugC(2, "GfxPalette::createFromData() - not enough bytes in resource (%d), expected palette header", bytesLeft); return; } + // palette formats in here are not really version exclusive, we can not use sci-version to differentiate between them + // they were just called that way, because they started appearing in sci1.1 for example if ((data[0] == 0 && data[1] == 1) || (data[0] == 0 && data[1] == 0 && READ_LE_UINT16(data + 29) == 0)) { // SCI0/SCI1 palette palFormat = SCI_PAL_FORMAT_VARIABLE; // CONSTANT; @@ -484,6 +488,42 @@ void GfxPalette::kernelAnimateSet() { setOnScreen(); } +reg_t GfxPalette::kernelSave() { + SegManager *segMan = g_sci->getEngineState()->_segMan; + reg_t memoryId = segMan->allocateHunkEntry("kPalette(save)", 1024); + byte *memoryPtr = segMan->getHunkPointer(memoryId); + if (memoryPtr) { + for (int colorNr = 0; colorNr < 256; colorNr++) { + *memoryPtr++ = _sysPalette.colors[colorNr].used; + *memoryPtr++ = _sysPalette.colors[colorNr].r; + *memoryPtr++ = _sysPalette.colors[colorNr].g; + *memoryPtr++ = _sysPalette.colors[colorNr].b; + } + } + return memoryId; +} + +void GfxPalette::kernelRestore(reg_t memoryHandle) { + SegManager *segMan = g_sci->getEngineState()->_segMan; + if (!memoryHandle.isNull()) { + byte *memoryPtr = segMan->getHunkPointer(memoryHandle); + if (!memoryPtr) + error("Bad handle used for kPalette(restore)"); + + Palette restoredPalette; + + restoredPalette.timestamp = 0; + for (int colorNr = 0; colorNr < 256; colorNr++) { + restoredPalette.colors[colorNr].used = *memoryPtr++; + restoredPalette.colors[colorNr].r = *memoryPtr++; + restoredPalette.colors[colorNr].g = *memoryPtr++; + restoredPalette.colors[colorNr].b = *memoryPtr++; + } + + set(&restoredPalette, true); + } +} + void GfxPalette::kernelAssertPalette(GuiResourceId resourceId) { // Sometimes invalid viewIds are asked for, ignore those (e.g. qfg1vga) //if (!_resMan->testResource(ResourceId(kResourceTypeView, resourceId))) diff --git a/engines/sci/graphics/palette.h b/engines/sci/graphics/palette.h index 6af1d5a490..e10c10718d 100644 --- a/engines/sci/graphics/palette.h +++ b/engines/sci/graphics/palette.h @@ -34,7 +34,7 @@ class Screen; /** * Palette class, handles palette operations like changing intensity, setting up the palette, merging different palettes */ -class GfxPalette { +class GfxPalette : public Common::Serializable { public: GfxPalette(ResourceManager *resMan, GfxScreen *screen, bool useMerging); ~GfxPalette(); @@ -63,6 +63,8 @@ public: int16 kernelFindColor(uint16 r, uint16 g, uint16 b); bool kernelAnimate(byte fromColor, byte toColor, int speed); void kernelAnimateSet(); + reg_t kernelSave(); + void kernelRestore(reg_t memoryHandle); void kernelAssertPalette(GuiResourceId resourceId); void kernelSyncScreenPalette(); @@ -80,6 +82,9 @@ public: Palette _sysPalette; + virtual void saveLoadWithSerializer(Common::Serializer &s); + void palVarySaveLoadPalette(Common::Serializer &s, Palette *palette); + private: void palVaryInit(); void palVaryInstallTimer(); diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp index 7cd37b6f46..e568316919 100644 --- a/engines/sci/graphics/picture.cpp +++ b/engines/sci/graphics/picture.cpp @@ -43,10 +43,11 @@ GfxPicture::GfxPicture(ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, } GfxPicture::~GfxPicture() { + _resMan->unlockResource(_resource); } void GfxPicture::initData(GuiResourceId resourceId) { - _resource = _resMan->findResource(ResourceId(kResourceTypePic, resourceId), false); + _resource = _resMan->findResource(ResourceId(kResourceTypePic, resourceId), true); if (!_resource) { error("picture resource %d not found", resourceId); } @@ -56,7 +57,9 @@ GuiResourceId GfxPicture::getResourceId() { return _resourceId; } -// TODO: subclass this +// differentiation between various picture formats can NOT get done using sci-version checks. +// Games like PQ1 use the "old" vector data picture format, but are actually SCI1.1 +// We should leave this that way to decide the format on-the-fly instead of hardcoding it in any way void GfxPicture::draw(int16 animationNr, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo) { uint16 headerSize; @@ -70,14 +73,12 @@ void GfxPicture::draw(int16 animationNr, bool mirroredFlag, bool addToFlag, int1 switch (headerSize) { case 0x26: // SCI 1.1 VGA picture _resourceType = SCI_PICTURE_TYPE_SCI11; - if (_addToFlag) - _priority = 15; drawSci11Vga(); break; #ifdef ENABLE_SCI32 case 0x0e: // SCI32 VGA picture _resourceType = SCI_PICTURE_TYPE_SCI32; - drawSci32Vga(); + //drawSci32Vga(); break; #endif default: @@ -99,28 +100,46 @@ void GfxPicture::reset() { void GfxPicture::drawSci11Vga() { byte *inbuffer = _resource->data; int size = _resource->size; - int has_cel = READ_LE_UINT16(inbuffer + 4); - int vector_dataPos = READ_LE_UINT16(inbuffer + 16); + int priorityBandsCount = inbuffer[3]; + int has_cel = inbuffer[4]; + int vector_dataPos = READ_LE_UINT32(inbuffer + 16); int vector_size = size - vector_dataPos; - int palette_data_ptr = READ_LE_UINT16(inbuffer + 28); - int cel_headerPos = READ_LE_UINT16(inbuffer + 32); - int cel_RlePos = READ_LE_UINT16(inbuffer + cel_headerPos + 24); - int cel_LiteralPos = READ_LE_UINT16(inbuffer + cel_headerPos + 28); + int palette_data_ptr = READ_LE_UINT32(inbuffer + 28); + int cel_headerPos = READ_LE_UINT32(inbuffer + 32); + int cel_RlePos = READ_LE_UINT32(inbuffer + cel_headerPos + 24); + int cel_LiteralPos = READ_LE_UINT32(inbuffer + cel_headerPos + 28); Palette palette; + // Header + // [headerSize:WORD] [unknown:BYTE] [priorityBandCount:BYTE] [hasCel:BYTE] [unknown:BYTE] + // [unknown:WORD] [unknown:WORD] [unknown:WORD] [unknown:WORD] [unknown:WORD] + // Offset 16 + // [vectorDataOffset:DWORD] [unknown:DWORD] [unknown:DWORD] [paletteDataOffset:DWORD] + // Offset 32 + // [celHeaderOffset:DWORD] [unknown:DWORD] + // [priorityBandData:WORD] * priorityBandCount + // [priority:BYTE] [unknown:BYTE] + // Create palette and set it _palette->createFromData(inbuffer + palette_data_ptr, size - palette_data_ptr, &palette); _palette->set(&palette, true); + // priority bands are supposed to be 14 for sci1.1 pictures + assert(priorityBandsCount == 14); + + if (_addToFlag) { + _priority = inbuffer[40 + priorityBandsCount * 2] & 0xF; + } + // display Cel-data if (has_cel) - drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0); + drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0, 0); // process vector data drawVectorData(inbuffer + vector_dataPos, vector_size); - // Remember priority band information for later - _ports->priorityBandsRemember(inbuffer + 40); + // Set priority band information + _ports->priorityBandsInitSci11(inbuffer + 40); } #ifdef ENABLE_SCI32 @@ -129,45 +148,80 @@ int16 GfxPicture::getSci32celCount() { return inbuffer[2]; } -void GfxPicture::drawSci32Vga(int16 celNo) { +int16 GfxPicture::getSci32celY(int16 celNo) { + byte *inbuffer = _resource->data; + int header_size = READ_LE_UINT16(inbuffer); + int cel_headerPos = header_size + 42 * celNo; + return READ_LE_UINT16(inbuffer + cel_headerPos + 40); +} + +int16 GfxPicture::getSci32celX(int16 celNo) { + byte *inbuffer = _resource->data; + int header_size = READ_LE_UINT16(inbuffer); + int cel_headerPos = header_size + 42 * celNo; + return READ_LE_UINT16(inbuffer + cel_headerPos + 38); +} + +int16 GfxPicture::getSci32celWidth(int16 celNo) { + byte *inbuffer = _resource->data; + int header_size = READ_LE_UINT16(inbuffer); + int cel_headerPos = header_size + 42 * celNo; + return READ_LE_UINT16(inbuffer + cel_headerPos + 0); +} + +int16 GfxPicture::getSci32celPriority(int16 celNo) { + byte *inbuffer = _resource->data; + int header_size = READ_LE_UINT16(inbuffer); + int cel_headerPos = header_size + 42 * celNo; + return READ_LE_UINT16(inbuffer + cel_headerPos + 36); +} + +void GfxPicture::drawSci32Vga(int16 celNo, int16 drawX, int16 drawY, int16 pictureX, bool mirrored) { byte *inbuffer = _resource->data; int size = _resource->size; int header_size = READ_LE_UINT16(inbuffer); int palette_data_ptr = READ_LE_UINT16(inbuffer + 6); - int celCount = inbuffer[2]; +// int celCount = inbuffer[2]; int cel_headerPos = header_size; int cel_RlePos, cel_LiteralPos; - int cel_relXpos, cel_relYpos; Palette palette; // HACK - _mirroredFlag = false; + _mirroredFlag = mirrored; _addToFlag = false; _resourceType = SCI_PICTURE_TYPE_SCI32; - if ((celNo == -1) || (celNo == 0)) { + if (celNo == 0) { // Create palette and set it _palette->createFromData(inbuffer + palette_data_ptr, size - palette_data_ptr, &palette); _palette->set(&palette, true); } - if (celNo != -1) { - cel_headerPos += 42 * celNo; - celCount = 1; - } - while (celCount > 0) { - cel_RlePos = READ_LE_UINT32(inbuffer + cel_headerPos + 24); - cel_LiteralPos = READ_LE_UINT32(inbuffer + cel_headerPos + 28); - cel_relXpos = READ_LE_UINT16(inbuffer + cel_headerPos + 38); - cel_relYpos = READ_LE_UINT16(inbuffer + cel_headerPos + 40); - drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, cel_relXpos, cel_relYpos); - cel_headerPos += 42; - celCount--; + // Header + // [headerSize:WORD] [celCount:BYTE] [Unknown:BYTE] [Unknown:WORD] [paletteOffset:DWORD] [Unknown:DWORD] + // cel-header follow afterwards, each is 42 bytes + // Cel-Header + // [width:WORD] [height:WORD] [displaceX:WORD] [displaceY:WORD] [clearColor:BYTE] [compressed:BYTE] + // offset 10-23 is unknown + // [rleOffset:DWORD] [literalOffset:DWORD] [Unknown:WORD] [Unknown:WORD] [priority:WORD] [relativeXpos:WORD] [relativeYpos:WORD] + + cel_headerPos += 42 * celNo; + + if (mirrored) { + // switch around relativeXpos + Common::Rect displayArea = _coordAdjuster->pictureGetDisplayArea(); + drawX = displayArea.width() - drawX - READ_LE_UINT16(inbuffer + cel_headerPos + 0); } + + cel_RlePos = READ_LE_UINT32(inbuffer + cel_headerPos + 24); + cel_LiteralPos = READ_LE_UINT32(inbuffer + cel_headerPos + 28); + + drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, drawX, drawY, pictureX); + cel_headerPos += 42; } #endif -void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 callerX, int16 callerY) { +void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX) { byte *celBitmap = NULL; byte *ptr = NULL; byte *headerPtr = inbuffer + headerPos; @@ -295,52 +349,71 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos Common::Rect displayArea = _coordAdjuster->pictureGetDisplayArea(); - y = callerY + displayArea.top; - lastY = MIN<int16>(height + y, displayArea.bottom); - leftX = callerX + displayArea.left; - rightX = MIN<int16>(width + leftX, displayArea.right); - - // Change clearcolor to white, if we dont add to an existing picture. That way we will paint everything on screen - // but white and that wont matter because the screen is supposed to be already white. It seems that most (if not all) - // SCI1.1 games use color 0 as transparency and SCI1 games use color 255 as transparency. Sierra SCI seems to paint - // the whole data to screen and wont skip over transparent pixels. So this will actually make it work like Sierra - if (!_addToFlag) - clearColor = _screen->getColorWhite(); - - ptr = celBitmap; - if (!_mirroredFlag) { - // Draw bitmap to screen - x = leftX; - while (y < lastY) { - curByte = *ptr++; - if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y))) - _screen->putPixel(x, y, GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY, curByte, priority, 0); - - x++; - - if (x >= rightX) { - if (width > rightX - leftX) // Skip extra pixels at the end of the row - ptr += width - (rightX - leftX); - x = leftX; - y++; - } + uint16 skipCelBitmapPixels = 0; + int16 displayWidth = width; + if (pictureX) { + // scroll position for picture active, we need to adjust drawX accordingly + drawX -= pictureX; + if (drawX < 0) { + skipCelBitmapPixels = -drawX; + displayWidth -= skipCelBitmapPixels; + drawX = 0; } - } else { - // Draw bitmap to screen (mirrored) - x = rightX - 1; - while (y < lastY) { - curByte = *ptr++; - if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y))) - _screen->putPixel(x, y, GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY, curByte, priority, 0); - - if (x == leftX) { - if (width > rightX - leftX) // Skip extra pixels at the end of the row - ptr += width - (rightX - leftX); - x = rightX; - y++; + } + + if (displayWidth > 0) { + y = displayArea.top + drawY; + lastY = MIN<int16>(height + y, displayArea.bottom); + leftX = displayArea.left + drawX; + rightX = MIN<int16>(displayWidth + leftX, displayArea.right); + + uint16 sourcePixelSkipPerRow = 0; + if (width > rightX - leftX) + sourcePixelSkipPerRow = width - (rightX - leftX); + + // Change clearcolor to white, if we dont add to an existing picture. That way we will paint everything on screen + // but white and that wont matter because the screen is supposed to be already white. It seems that most (if not all) + // SCI1.1 games use color 0 as transparency and SCI1 games use color 255 as transparency. Sierra SCI seems to paint + // the whole data to screen and wont skip over transparent pixels. So this will actually make it work like Sierra + if (!_addToFlag) + clearColor = _screen->getColorWhite(); + + byte drawMask = priority == 255 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY; + + ptr = celBitmap; + ptr += skipCelBitmapPixels; + if (!_mirroredFlag) { + // Draw bitmap to screen + x = leftX; + while (y < lastY) { + curByte = *ptr++; + if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y))) + _screen->putPixel(x, y, drawMask, curByte, priority, 0); + + x++; + + if (x >= rightX) { + ptr += sourcePixelSkipPerRow; + x = leftX; + y++; + } } + } else { + // Draw bitmap to screen (mirrored) + x = rightX - 1; + while (y < lastY) { + curByte = *ptr++; + if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y))) + _screen->putPixel(x, y, drawMask, curByte, priority, 0); + + if (x == leftX) { + ptr += sourcePixelSkipPerRow; + x = rightX; + y++; + } - x--; + x--; + } } } @@ -537,6 +610,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { // This picture includes garbage data, first a set pattern w/o parameter and then short pattern // I guess that garbage is a left over from the sq4-floppy (sci1) to sq4-cd (sci1.1) conversion switch (_resourceId) { + case 35: case 381: case 376: return; @@ -618,7 +692,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { vectorGetAbsCoordsNoMirror(data, curPos, x, y); size = READ_LE_UINT16(data + curPos); curPos += 2; _priority = pic_priority; // set global priority so the cel gets drawn using current priority as well - drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y); + drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0); curPos += size; break; case PIC_OPX_EGA_SET_PRIORITY_TABLE: @@ -658,9 +732,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { vectorGetAbsCoordsNoMirror(data, curPos, x, y); size = READ_LE_UINT16(data + curPos); curPos += 2; _priority = pic_priority; // set global priority so the cel gets drawn using current priority as well - if (pic_priority == 255) - _priority = 0; // if priority not set, use priority 0 - drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y); + drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0); curPos += size; break; case PIC_OPX_VGA_PRIORITY_TABLE_EQDIST: diff --git a/engines/sci/graphics/picture.h b/engines/sci/graphics/picture.h index 5a86539b37..7cd0d71b67 100644 --- a/engines/sci/graphics/picture.h +++ b/engines/sci/graphics/picture.h @@ -56,14 +56,18 @@ public: #ifdef ENABLE_SCI32 int16 getSci32celCount(); - void drawSci32Vga(int16 celNo = -1); + int16 getSci32celY(int16 celNo); + int16 getSci32celX(int16 celNo); + int16 getSci32celWidth(int16 celNo); + int16 getSci32celPriority(int16 celNo); + void drawSci32Vga(int16 celNo, int16 callerX, int16 callerY, int16 pictureX, bool mirrored); #endif private: void initData(GuiResourceId resourceId); void reset(); void drawSci11Vga(); - void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 callerX, int16 callerY); + void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX); void drawVectorData(byte *data, int size); bool vectorIsNonOpcode(byte pixel); void vectorGetAbsCoords(byte *data, int &curPos, int16 &x, int16 &y); diff --git a/engines/sci/graphics/ports.cpp b/engines/sci/graphics/ports.cpp index 611db1061a..9268888b6c 100644 --- a/engines/sci/graphics/ports.cpp +++ b/engines/sci/graphics/ports.cpp @@ -134,8 +134,6 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te if (g_sci->_features->usesOldGfxFunctions()) _picWind->top = offTop; - priorityBandsMemoryActive = false; - kernelInitPriorityBands(); } @@ -173,7 +171,7 @@ reg_t GfxPorts::kernelGetActive() { reg_t GfxPorts::kernelNewWindow(Common::Rect dims, Common::Rect restoreRect, uint16 style, int16 priority, int16 colorPen, int16 colorBack, const char *title) { Window *wnd = NULL; - if (restoreRect.top != 0 && restoreRect.left != 0 && restoreRect.height() != 0 && restoreRect.width() != 0) + if (restoreRect.bottom != 0 && restoreRect.right != 0) wnd = newWindow(dims, &restoreRect, title, style, priority, false); else wnd = newWindow(dims, NULL, title, style, priority, false); @@ -250,9 +248,10 @@ Window *GfxPorts::newWindow(const Common::Rect &dims, const Common::Rect *restor r = dims; if (r.width() > _screen->getWidth()) { - // We get invalid dimensions at least at the end of sq3 (script bug!) - // same happens very often in lsl5, sierra sci didnt fix it but it looked awful - warning("fixing too large window, given left&right was %d, %d", dims.left, dims.right); + // We get invalid dimensions at least at the end of sq3 (script bug!). + // Same happens very often in lsl5, sierra sci didnt fix it but it looked awful. + // Also happens frequently in the demo of GK1. + warning("Fixing too large window, left: %d, right: %d", dims.left, dims.right); r.left = 0; r.right = _screen->getWidth() - 1; if ((style != _styleUser) && !(style & SCI_WINDOWMGR_STYLE_NOFRAME)) @@ -367,7 +366,7 @@ void GfxPorts::drawWindow(Window *pWnd) { if (!(wndStyle & SCI_WINDOWMGR_STYLE_TRANSPARENT)) _paint16->fillRect(r, GFX_SCREEN_MASK_VISUAL, pWnd->backClr); - _paint16->bitsShow(pWnd->restoreRect); + _paint16->bitsShow(pWnd->dims); } setPort(oldport); } @@ -540,22 +539,14 @@ void GfxPorts::priorityBandsInit(byte *data) { _priorityBands[i++] = inx; } -// Gets used by picture class to remember priority bands data from sci1.1 pictures that need to get applied when -// transitioning to that picture -void GfxPorts::priorityBandsRemember(byte *data) { - int bandNo; - for (bandNo = 0; bandNo < 14; bandNo++) { - priorityBandsMemory[bandNo] = READ_LE_UINT16(data); +// Gets used to read priority bands data from sci1.1 pictures +void GfxPorts::priorityBandsInitSci11(byte *data) { + byte priorityBands[14]; + for (int bandNo = 0; bandNo < 14; bandNo++) { + priorityBands[bandNo] = READ_LE_UINT16(data); data += 2; } - priorityBandsMemoryActive = true; -} - -void GfxPorts::priorityBandsRecall() { - if (priorityBandsMemoryActive) { - priorityBandsInit((byte *)&priorityBandsMemory); - priorityBandsMemoryActive = false; - } + priorityBandsInit(priorityBands); } void GfxPorts::kernelInitPriorityBands() { diff --git a/engines/sci/graphics/ports.h b/engines/sci/graphics/ports.h index 818f92f44f..d10bc6772f 100644 --- a/engines/sci/graphics/ports.h +++ b/engines/sci/graphics/ports.h @@ -81,8 +81,7 @@ public: void priorityBandsInit(int16 bandCount, int16 top, int16 bottom); void priorityBandsInit(byte *data); - void priorityBandsRemember(byte *data); - void priorityBandsRecall(); + void priorityBandsInitSci11(byte *data); void kernelInitPriorityBands(); void kernelGraphAdjustPriority(int top, int bottom); @@ -121,9 +120,6 @@ private: // Priority Bands related variables int16 _priorityTop, _priorityBottom, _priorityBandCount; byte _priorityBands[200]; - - byte priorityBandsMemory[14]; - bool priorityBandsMemoryActive; }; } // End of namespace Sci diff --git a/engines/sci/graphics/robot.cpp b/engines/sci/graphics/robot.cpp index d926e037f4..1572a0a9ec 100644 --- a/engines/sci/graphics/robot.cpp +++ b/engines/sci/graphics/robot.cpp @@ -28,6 +28,8 @@ #include "sci/graphics/screen.h" #include "sci/graphics/robot.h" +#include "common/file.h" + namespace Sci { #ifdef ENABLE_SCI32 @@ -35,18 +37,33 @@ GfxRobot::GfxRobot(ResourceManager *resMan, GfxScreen *screen, GuiResourceId res : _resMan(resMan), _screen(screen), _resourceId(resourceId) { assert(resourceId != -1); initData(resourceId); + _resourceData = 0; } GfxRobot::~GfxRobot() { - _resMan->unlockResource(_resource); + delete[] _resourceData; } void GfxRobot::initData(GuiResourceId resourceId) { - _resource = _resMan->findResource(ResourceId(kResourceTypeRobot, resourceId), true); - if (!_resource) { - error("robot resource %d not found", resourceId); + char fileName[10]; + sprintf(fileName, "%d.rbt", resourceId); + + Common::File robotFile; + if (robotFile.open(fileName)) { + _resourceData = new byte[robotFile.size()]; + robotFile.read(_resourceData, robotFile.size()); + robotFile.close(); + } else { + warning("Unable to open robot file %s", fileName); + return; + } + + byte version = _resourceData[6]; + + if (version != 4 && version != 5) { + warning("Robot version %d isn't supported yet", version); + return; } - _resourceData = _resource->data; // sample data: // Header - 14 bytes @@ -152,8 +169,11 @@ void GfxRobot::initData(GuiResourceId resourceId) { // ^ ?? // 00000120: 70 70 70 70 70 70 70 70-70 70 70 70 70 70 70 70 pppppppppppppppp - _frameCount = READ_LE_UINT16(_resourceData + 12); - _frameSize = READ_LE_UINT32(_resourceData + 34); + _frameCount = READ_LE_UINT16(_resourceData + 14); + //_frameSize = READ_LE_UINT32(_resourceData + 34); + byte hasSound = _resourceData[25]; + + debug("Robot %d, %d frames, sound: %d\n", resourceId, _frameCount, hasSound); } // TODO: just trying around in here... diff --git a/engines/sci/graphics/robot.h b/engines/sci/graphics/robot.h index 80dae95f95..3ea9a7f735 100644 --- a/engines/sci/graphics/robot.h +++ b/engines/sci/graphics/robot.h @@ -45,7 +45,6 @@ private: GfxScreen *_screen; GuiResourceId _resourceId; - Resource *_resource; byte *_resourceData; uint16 _width; diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp index 488bb83ab3..131a3d2eb8 100644 --- a/engines/sci/graphics/screen.cpp +++ b/engines/sci/graphics/screen.cpp @@ -127,7 +127,7 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) { // the icon bar. Of course, both KQ6 and QFG1 VGA differ in size. if (g_sci->getGameId() == GID_KQ6) initGraphics(_displayWidth, _displayHeight + 26, _displayWidth > 320); - else if (g_sci->getGameId() == GID_QFG1) + else if (g_sci->getGameId() == GID_QFG1VGA) initGraphics(_displayWidth, _displayHeight + 20, _displayWidth > 320); else error("Unknown SCI1.1 Mac game"); diff --git a/engines/sci/graphics/text16.cpp b/engines/sci/graphics/text16.cpp index 4aa2346aed..08be203230 100644 --- a/engines/sci/graphics/text16.cpp +++ b/engines/sci/graphics/text16.cpp @@ -289,6 +289,8 @@ int16 GfxText16::Size(Common::Rect &rect, const char *text, GuiResourceId fontId if (fontId != -1) SetFont(fontId); + else + fontId = oldFontId; if (g_sci->getLanguage() == Common::JA_JPN) SwitchToFont900OnSjis(text); @@ -296,7 +298,7 @@ int16 GfxText16::Size(Common::Rect &rect, const char *text, GuiResourceId fontId rect.top = rect.left = 0; if (maxWidth < 0) { // force output as single line - StringWidth(text, oldFontId, textWidth, textHeight); + StringWidth(text, fontId, textWidth, textHeight); rect.bottom = textHeight; rect.right = textWidth; } else { @@ -308,7 +310,7 @@ int16 GfxText16::Size(Common::Rect &rect, const char *text, GuiResourceId fontId charCount = GetLongest(curPos, rect.right, oldFontId); if (charCount == 0) break; - Width(curPos, 0, charCount, oldFontId, textWidth, textHeight); + Width(curPos, 0, charCount, fontId, textWidth, textHeight); maxTextWidth = MAX(textWidth, maxTextWidth); totalHeight += textHeight; curPos += charCount; @@ -390,6 +392,8 @@ void GfxText16::Box(const char *text, int16 bshow, const Common::Rect &rect, Tex if (fontId != -1) SetFont(fontId); + else + fontId = orgFontId; if (g_sci->getLanguage() == Common::JA_JPN) { if (SwitchToFont900OnSjis(text)) @@ -420,9 +424,9 @@ void GfxText16::Box(const char *text, int16 bshow, const Common::Rect &rect, Tex _ports->moveTo(rect.left + offset, rect.top + hline); if (bshow) { - Show(text, 0, charCount, orgFontId, orgPenColor); + Show(text, 0, charCount, fontId, orgPenColor); } else { - Draw(text, 0, charCount, orgFontId, orgPenColor); + Draw(text, 0, charCount, fontId, orgPenColor); } hline += textHeight; diff --git a/engines/sci/graphics/transitions.cpp b/engines/sci/graphics/transitions.cpp index c1f626449f..abb5e74cbd 100644 --- a/engines/sci/graphics/transitions.cpp +++ b/engines/sci/graphics/transitions.cpp @@ -407,39 +407,39 @@ void GfxTransitions::straight(int16 number, bool blackoutFlag) { } } +void GfxTransitions::scrollCopyOldToScreen(Common::Rect screenRect, int16 x, int16 y) { + byte *oldScreenPtr = _oldScreen; + int16 screenWidth = _screen->getDisplayWidth(); + if (_screen->getUpscaledHires()) { + _screen->adjustToUpscaledCoordinates(screenRect.top, screenRect.left); + _screen->adjustToUpscaledCoordinates(screenRect.bottom, screenRect.right); + _screen->adjustToUpscaledCoordinates(y, x); + } + oldScreenPtr += screenRect.left + screenRect.top * screenWidth; + g_system->copyRectToScreen(oldScreenPtr, screenWidth, x, y, screenRect.width(), screenRect.height()); +} + // Scroll old screen (up/down/left/right) and insert new screen that way - works // on _picRect area only. void GfxTransitions::scroll(int16 number) { int16 screenWidth, screenHeight; - byte *oldScreenPtr; int16 stepNr = 0; Common::Rect oldMoveRect = _picRect; + Common::Rect oldScreenRect = _picRect; Common::Rect newMoveRect = _picRect; Common::Rect newScreenRect = _picRect; _screen->copyFromScreen(_oldScreen); screenWidth = _screen->getDisplayWidth(); screenHeight = _screen->getDisplayHeight(); - oldScreenPtr = _oldScreen + _picRect.left + _picRect.top * screenWidth; - if (_screen->getUpscaledHires()) { - oldScreenPtr += _picRect.left + _picRect.top * screenWidth; - } - switch (number) { case SCI_TRANSITIONS_SCROLL_LEFT: newScreenRect.right = newScreenRect.left; newMoveRect.left = newMoveRect.right; while (oldMoveRect.left < oldMoveRect.right) { - oldScreenPtr++; - if (_screen->getUpscaledHires()) - oldScreenPtr++; - oldMoveRect.right--; - if (oldMoveRect.right > oldMoveRect.left) { - if (!_screen->getUpscaledHires()) - g_system->copyRectToScreen(oldScreenPtr, screenWidth, oldMoveRect.left, oldMoveRect.top, oldMoveRect.width(), oldMoveRect.height()); - else - g_system->copyRectToScreen(oldScreenPtr, screenWidth, oldMoveRect.left * 2, oldMoveRect.top * 2, oldMoveRect.width() * 2, oldMoveRect.height() * 2); - } + oldMoveRect.right--; oldScreenRect.left++; + if (oldMoveRect.right > oldMoveRect.left) + scrollCopyOldToScreen(oldScreenRect, oldMoveRect.left, oldMoveRect.top); newScreenRect.right++; newMoveRect.left--; _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); if ((stepNr & 1) == 0) { @@ -458,13 +458,9 @@ void GfxTransitions::scroll(int16 number) { case SCI_TRANSITIONS_SCROLL_RIGHT: newScreenRect.left = newScreenRect.right; while (oldMoveRect.left < oldMoveRect.right) { - oldMoveRect.left++; - if (oldMoveRect.right > oldMoveRect.left) { - if (!_screen->getUpscaledHires()) - g_system->copyRectToScreen(oldScreenPtr, screenWidth, oldMoveRect.left, oldMoveRect.top, oldMoveRect.width(), oldMoveRect.height()); - else - g_system->copyRectToScreen(oldScreenPtr, screenWidth, oldMoveRect.left * 2, oldMoveRect.top * 2, oldMoveRect.width() * 2, oldMoveRect.height() * 2); - } + oldMoveRect.left++; oldScreenRect.right--; + if (oldMoveRect.right > oldMoveRect.left) + scrollCopyOldToScreen(oldScreenRect, oldMoveRect.left, oldMoveRect.top); newScreenRect.left--; _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); if ((stepNr & 1) == 0) { @@ -484,16 +480,9 @@ void GfxTransitions::scroll(int16 number) { newScreenRect.bottom = newScreenRect.top; newMoveRect.top = newMoveRect.bottom; while (oldMoveRect.top < oldMoveRect.bottom) { - oldScreenPtr += screenWidth; - if (_screen->getUpscaledHires()) - oldScreenPtr += screenWidth; - oldMoveRect.top++; - if (oldMoveRect.top < oldMoveRect.bottom) { - if (!_screen->getUpscaledHires()) - g_system->copyRectToScreen(oldScreenPtr, screenWidth, _picRect.left, _picRect.top, oldMoveRect.width(), oldMoveRect.height()); - else - g_system->copyRectToScreen(oldScreenPtr, screenWidth, _picRect.left * 2, _picRect.top * 2, oldMoveRect.width() * 2, oldMoveRect.height() * 2); - } + oldMoveRect.top++; oldScreenRect.top++; + if (oldMoveRect.top < oldMoveRect.bottom) + scrollCopyOldToScreen(oldScreenRect, _picRect.left, _picRect.top); newScreenRect.bottom++; newMoveRect.top--; _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); updateScreenAndWait(3); @@ -503,13 +492,9 @@ void GfxTransitions::scroll(int16 number) { case SCI_TRANSITIONS_SCROLL_DOWN: newScreenRect.top = newScreenRect.bottom; while (oldMoveRect.top < oldMoveRect.bottom) { - oldMoveRect.top++; - if (oldMoveRect.top < oldMoveRect.bottom) { - if (!_screen->getUpscaledHires()) - g_system->copyRectToScreen(oldScreenPtr, screenWidth, oldMoveRect.left, oldMoveRect.top, oldMoveRect.width(), oldMoveRect.height()); - else - g_system->copyRectToScreen(oldScreenPtr, screenWidth, oldMoveRect.left * 2, oldMoveRect.top * 2, oldMoveRect.width() * 2, oldMoveRect.height() * 2); - } + oldMoveRect.top++; oldScreenRect.bottom--; + if (oldMoveRect.top < oldMoveRect.bottom) + scrollCopyOldToScreen(oldScreenRect, oldMoveRect.left, oldMoveRect.top); newScreenRect.top--; _screen->copyRectToScreen(newScreenRect, _picRect.left, _picRect.top); updateScreenAndWait(3); @@ -539,7 +524,7 @@ void GfxTransitions::verticalRollFromCenter(bool blackoutFlag) { // only void GfxTransitions::verticalRollToCenter(bool blackoutFlag) { Common::Rect leftRect = Common::Rect(_picRect.left, _picRect.top, _picRect.left + 1, _picRect.bottom); - Common::Rect rightRect = Common::Rect(leftRect.right - 1, _picRect.top, leftRect.right, _picRect.bottom); + Common::Rect rightRect = Common::Rect(_picRect.right - 1, _picRect.top, _picRect.right, _picRect.bottom); while (leftRect.left < rightRect.right) { copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(1, 0); diff --git a/engines/sci/graphics/transitions.h b/engines/sci/graphics/transitions.h index 788cefabca..233638ffda 100644 --- a/engines/sci/graphics/transitions.h +++ b/engines/sci/graphics/transitions.h @@ -83,6 +83,7 @@ private: void pixelation(bool blackoutFlag); void blocks(bool blackoutFlag); void straight(int16 number, bool blackoutFlag); + void scrollCopyOldToScreen(Common::Rect screenRect, int16 x, int16 y); void scroll(int16 number); void verticalRollFromCenter(bool blackoutFlag); void verticalRollToCenter(bool blackoutFlag); diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp index 93df45820c..d32e60335f 100644 --- a/engines/sci/graphics/view.cpp +++ b/engines/sci/graphics/view.cpp @@ -28,6 +28,7 @@ #include "sci/engine/state.h" #include "sci/graphics/screen.h" #include "sci/graphics/palette.h" +#include "sci/graphics/coordadjuster.h" #include "sci/graphics/view.h" namespace Sci { @@ -35,6 +36,7 @@ namespace Sci { GfxView::GfxView(ResourceManager *resMan, GfxScreen *screen, GfxPalette *palette, GuiResourceId resourceId) : _resMan(resMan), _screen(screen), _palette(palette), _resourceId(resourceId) { assert(resourceId != -1); + _coordAdjuster = g_sci->_gfxCoordAdjuster; initData(resourceId); } @@ -160,8 +162,8 @@ void GfxView::initData(GuiResourceId resourceId) { // For EGA // Width:WORD Height:WORD DisplaceX:BYTE DisplaceY:BYTE ClearKey:BYTE EGAData starts now directly cel = &_loop[loopNo].cel[celNo]; - cel->width = READ_LE_UINT16(celData); - cel->height = READ_LE_UINT16(celData + 2); + cel->scriptWidth = cel->width = READ_LE_UINT16(celData); + cel->scriptHeight = cel->height = READ_LE_UINT16(celData + 2); cel->displaceX = (signed char)celData[4]; cel->displaceY = celData[5]; cel->clearKey = celData[6]; @@ -231,8 +233,8 @@ void GfxView::initData(GuiResourceId resourceId) { _loop[loopNo].cel = new CelInfo[celCount]; for (celNo = 0; celNo < celCount; celNo++) { cel = &_loop[loopNo].cel[celNo]; - cel->width = READ_SCI11ENDIAN_UINT16(celData); - cel->height = READ_SCI11ENDIAN_UINT16(celData + 2); + cel->scriptWidth = cel->width = READ_SCI11ENDIAN_UINT16(celData); + cel->scriptHeight = cel->height = READ_SCI11ENDIAN_UINT16(celData + 2); cel->displaceX = READ_SCI11ENDIAN_UINT16(celData + 4); cel->displaceY = READ_SCI11ENDIAN_UINT16(celData + 6); @@ -253,6 +255,29 @@ void GfxView::initData(GuiResourceId resourceId) { celData += celSize; } } +#ifdef ENABLE_SCI32 + // adjust width/height returned to scripts + switch (getSciVersion()) { + case SCI_VERSION_2: + if (_isSci2Hires) { + for (loopNo = 0; loopNo < _loopCount; loopNo++) { + for (celNo = 0; celNo < _loop[loopNo].celCount; celNo++) { + _screen->adjustBackUpscaledCoordinates(_loop[loopNo].cel[celNo].scriptWidth, _loop[loopNo].cel[celNo].scriptHeight); + } + } + } + break; + + case SCI_VERSION_2_1: + for (loopNo = 0; loopNo < _loopCount; loopNo++) { + for (celNo = 0; celNo < _loop[loopNo].celCount; celNo++) { + _coordAdjuster->fromDisplayToScript(_loop[loopNo].cel[celNo].scriptHeight, _loop[loopNo].cel[celNo].scriptWidth); + } + } + default: + break; + } +#endif break; default: diff --git a/engines/sci/graphics/view.h b/engines/sci/graphics/view.h index 6eb1830b99..25e110ad13 100644 --- a/engines/sci/graphics/view.h +++ b/engines/sci/graphics/view.h @@ -30,6 +30,7 @@ namespace Sci { struct CelInfo { int16 width, height; + int16 scriptWidth, scriptHeight; int16 displaceX; int16 displaceY; byte clearKey; @@ -81,6 +82,7 @@ private: void unditherBitmap(byte *bitmap, int16 width, int16 height, byte clearKey); ResourceManager *_resMan; + GfxCoordAdjuster *_coordAdjuster; GfxScreen *_screen; GfxPalette *_palette; diff --git a/engines/sci/module.mk b/engines/sci/module.mk index 85988b8f1b..dae2807cc2 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -25,6 +25,7 @@ MODULE_OBJS := \ engine/kscripts.o \ engine/ksound.o \ engine/kstring.o \ + engine/kvideo.o \ engine/message.o \ engine/savegame.o \ engine/script.o \ @@ -35,6 +36,7 @@ MODULE_OBJS := \ engine/state.o \ engine/static_selectors.o \ engine/vm.o \ + engine/workarounds.o \ graphics/animate.o \ graphics/cache.o \ graphics/compare.o \ @@ -63,7 +65,7 @@ MODULE_OBJS := \ sound/music.o \ sound/soundcmd.o \ sound/drivers/adlib.o \ - sound/drivers/amiga.o \ + sound/drivers/amigamac.o \ sound/drivers/fb01.o \ sound/drivers/midi.o \ sound/drivers/pcjr.o \ @@ -72,7 +74,6 @@ MODULE_OBJS := \ ifdef ENABLE_SCI32 MODULE_OBJS += \ - engine/kernel32.o \ graphics/frameout.o \ graphics/paint32.o \ graphics/robot.o \ diff --git a/engines/sci/parser/grammar.cpp b/engines/sci/parser/grammar.cpp index 070e6767cf..6f37b49919 100644 --- a/engines/sci/parser/grammar.cpp +++ b/engines/sci/parser/grammar.cpp @@ -422,44 +422,44 @@ ParseRuleList *Vocabulary::buildGNF(bool verbose) { return tlist; } -static int _vbpt_pareno(parse_tree_node_t *nodes, int *pos, int base) { +static int _vbpt_pareno(ParseTreeNode *nodes, int *pos, int base) { // Opens parentheses - nodes[base].content.branches[0] = (*pos) + 1; + nodes[base].left = &nodes[(*pos) + 1]; nodes[++(*pos)].type = kParseTreeBranchNode; - nodes[*pos].content.branches[0] = 0; - nodes[*pos].content.branches[1] = 0; + nodes[*pos].left = 0; + nodes[*pos].right = 0; return *pos; } -static int _vbpt_parenc(parse_tree_node_t *nodes, int *pos, int paren) { +static int _vbpt_parenc(ParseTreeNode *nodes, int *pos, int paren) { // Closes parentheses for appending - nodes[paren].content.branches[1] = ++(*pos); + nodes[paren].right = &nodes[++(*pos)]; nodes[*pos].type = kParseTreeBranchNode; - nodes[*pos].content.branches[0] = 0; - nodes[*pos].content.branches[1] = 0; + nodes[*pos].left = 0; + nodes[*pos].right = 0; return *pos; } -static int _vbpt_append(parse_tree_node_t *nodes, int *pos, int base, int value) { +static int _vbpt_append(ParseTreeNode *nodes, int *pos, int base, int value) { // writes one value to an existing base node and creates a successor node for writing - nodes[base].content.branches[0] = ++(*pos); + nodes[base].left = &nodes[++(*pos)]; nodes[*pos].type = kParseTreeLeafNode; - nodes[*pos].content.value = value; - nodes[base].content.branches[1] = ++(*pos); + nodes[*pos].value = value; + nodes[base].right = &nodes[++(*pos)]; nodes[*pos].type = kParseTreeBranchNode; - nodes[*pos].content.branches[0] = 0; - nodes[*pos].content.branches[1] = 0; + nodes[*pos].left = 0; + nodes[*pos].right = 0; return *pos; } -static int _vbpt_terminate(parse_tree_node_t *nodes, int *pos, int base, int value) { +static int _vbpt_terminate(ParseTreeNode *nodes, int *pos, int base, int value) { // Terminates, overwriting a nextwrite forknode nodes[base].type = kParseTreeLeafNode; - nodes[base].content.value = value; + nodes[base].value = value; return *pos; } -static int _vbpt_write_subexpression(parse_tree_node_t *nodes, int *pos, ParseRule *rule, uint rulepos, int writepos) { +static int _vbpt_write_subexpression(ParseTreeNode *nodes, int *pos, ParseRule *rule, uint rulepos, int writepos) { uint token; while ((token = ((rulepos < rule->_data.size()) ? rule->_data[rulepos++] : TOKEN_CPAREN)) != TOKEN_CPAREN) { @@ -565,15 +565,15 @@ int Vocabulary::parseGNF(const ResultWordList &words, bool verbose) { int temp, pos; _parserNodes[0].type = kParseTreeBranchNode; - _parserNodes[0].content.branches[0] = 1; - _parserNodes[0].content.branches[1] = 2; + _parserNodes[0].left = &_parserNodes[1]; + _parserNodes[0].right = &_parserNodes[2]; _parserNodes[1].type = kParseTreeLeafNode; - _parserNodes[1].content.value = 0x141; + _parserNodes[1].value = 0x141; _parserNodes[2].type = kParseTreeBranchNode; - _parserNodes[2].content.branches[0] = 0; - _parserNodes[2].content.branches[1] = 0; + _parserNodes[2].left = 0; + _parserNodes[2].right = 0; pos = 2; diff --git a/engines/sci/parser/said.cpp b/engines/sci/parser/said.cpp index f49704372a..9c07be2dff 100644 --- a/engines/sci/parser/said.cpp +++ b/engines/sci/parser/said.cpp @@ -1,111 +1,3 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.3" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - WGROUP = 258, - YY_COMMA = 259, - YY_AMP = 260, - YY_SLASH = 261, - YY_PARENO = 262, - YY_PARENC = 263, - YY_BRACKETSO = 264, - YY_BRACKETSC = 265, - YY_HASH = 266, - YY_LT = 267, - YY_GT = 268, - YY_BRACKETSO_LT = 269, - YY_BRACKETSO_SLASH = 270, - YY_LT_BRACKETSO = 271, - YY_LT_PARENO = 272 - }; -#endif -/* Tokens. */ -#define WGROUP 258 -#define YY_COMMA 259 -#define YY_AMP 260 -#define YY_SLASH 261 -#define YY_PARENO 262 -#define YY_PARENC 263 -#define YY_BRACKETSO 264 -#define YY_BRACKETSC 265 -#define YY_HASH 266 -#define YY_LT 267 -#define YY_GT 268 -#define YY_BRACKETSO_LT 269 -#define YY_BRACKETSO_SLASH 270 -#define YY_LT_BRACKETSO 271 -#define YY_LT_PARENO 272 - - - - -/* Copy the first part of user declarations. */ - - /* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names @@ -133,14 +25,6 @@ #include "sci/engine/state.h" - -// Bison generates an empty switch statement that gives a warning in MSVC. -// This disables that warning. -#ifdef _MSC_VER -#pragma warning(disable:4065) -#endif - - namespace Sci { #define SAID_BRANCH_NULL 0 @@ -150,25 +34,8 @@ namespace Sci { // Maximum number of words to be expected in a parsed sentence #define AUGMENT_MAX_WORDS 64 - -#define ANYWORD 0xfff - -#define WORD_TYPE_BASE 0x141 -#define WORD_TYPE_REF 0x144 -#define WORD_TYPE_SYNTACTIC_SUGAR 0x145 - -#define AUGMENT_SENTENCE_PART_BRACKETS 0x152 - -// Minor numbers -#define AUGMENT_SENTENCE_MINOR_MATCH_PHRASE 0x14c -#define AUGMENT_SENTENCE_MINOR_MATCH_WORD 0x153 -#define AUGMENT_SENTENCE_MINOR_RECURSE 0x144 -#define AUGMENT_SENTENCE_MINOR_PARENTHESES 0x14f - - -#undef YYDEBUG /*1*/ -//#define SAID_DEBUG*/ -//#define SCI_DEBUG_PARSE_TREE_AUGMENTATION // uncomment to debug parse tree augmentation +// uncomment to debug parse tree augmentation +//#define SCI_DEBUG_PARSE_TREE_AUGMENTATION #ifdef SCI_DEBUG_PARSE_TREE_AUGMENTATION @@ -179,1840 +46,622 @@ void print_nothing(...) { } #endif -static char *said_parse_error; - static int said_token; static int said_tokens_nr; static int said_tokens[MAX_SAID_TOKENS]; -static int said_blessed; // increminated by said_top_branch - -static int said_tree_pos; // Set to 0 if we're out of space -#define SAID_TREE_START 4; // Reserve space for the 4 top nodes - -#define VALUE_IGNORE -424242 - -static parse_tree_node_t said_tree[VOCAB_TREE_NODES]; - -typedef int wgroup_t; -typedef int tree_t; -typedef int said_spec_t; - -static tree_t said_aug_branch(int, int, tree_t, tree_t); -static tree_t said_attach_branch(tree_t, tree_t); -/* -static tree_t said_wgroup_branch(wgroup_t); -*/ -static said_spec_t said_top_branch(tree_t); -static tree_t said_paren(tree_t, tree_t); -static tree_t said_value(int, tree_t); -static tree_t said_terminal(int); - -static int yylex(); - -static int yyerror(const char *s) { - said_parse_error = strdup(s); - return 1; /* Abort */ -} - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef int YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 216 of yacc.c. */ - - -#ifdef short -# undef short -#endif -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int i) -#else -static int -YYID (i) - int i; -#endif -{ - return i; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 23 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 80 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 18 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 13 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 35 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 69 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 272 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 6, 10, 15, 16, 18, 19, 21, - 24, 29, 31, 34, 39, 41, 43, 45, 49, 51, - 55, 59, 64, 70, 73, 75, 77, 79, 83, 88, - 92, 97, 100, 105, 109, 112 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 19, 0, -1, 21, 20, -1, 21, 22, 20, -1, - 21, 22, 23, 20, -1, -1, 13, -1, -1, 27, - -1, 6, 27, -1, 15, 6, 27, 10, -1, 6, - -1, 6, 27, -1, 15, 6, 27, 10, -1, 6, - -1, 3, -1, 26, -1, 9, 26, 10, -1, 24, - -1, 7, 27, 8, -1, 26, 4, 26, -1, 26, - 14, 29, 10, -1, 26, 4, 9, 26, 10, -1, - 25, 28, -1, 25, -1, 28, -1, 29, -1, 14, - 29, 10, -1, 29, 14, 29, 10, -1, 12, 24, - 30, -1, 17, 7, 27, 8, -1, 12, 26, -1, - 16, 9, 26, 10, -1, 12, 26, 30, -1, 12, - 26, -1, 17, 7, 27, 8, -1 +static int said_tree_pos; +#define SAID_TREE_START 4 // Reserve space for the 4 top nodes + +enum SaidToken { + TOKEN_COMMA = 0xF000, + TOKEN_AMP = 0xF100, + TOKEN_SLASH = 0xF200, + TOKEN_PARENO = 0xF300, + TOKEN_PARENC = 0xF400, + TOKEN_BRACKETO = 0xF500, + TOKEN_BRACKETC = 0xF600, + TOKEN_HASH = 0xF700, + TOKEN_LT = 0xF800, + TOKEN_GT = 0xF900, + TOKEN_TERM = 0xFF00 }; -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = -{ - 0, 130, 130, 132, 134, 140, 141, 148, 149, 155, - 157, 159, 165, 167, 169, 174, 179, 181, 186, 188, - 190, 192, 194, 199, 201, 203, 208, 210, 212, 217, - 219, 221, 223, 228, 230, 232 +enum SaidWord { + WORD_NONE = 0x0ffe, + WORD_ANY = 0x0fff }; -#endif -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "WGROUP", "YY_COMMA", "YY_AMP", - "YY_SLASH", "YY_PARENO", "YY_PARENC", "YY_BRACKETSO", "YY_BRACKETSC", - "YY_HASH", "YY_LT", "YY_GT", "YY_BRACKETSO_LT", "YY_BRACKETSO_SLASH", - "YY_LT_BRACKETSO", "YY_LT_PARENO", "$accept", "saidspec", "optcont", - "leftspec", "midspec", "rightspec", "word", "cwordset", "wordset", - "expr", "cwordrefset", "wordrefset", "recref", 0 -}; -#endif -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272 -}; -# endif -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 18, 19, 19, 19, 20, 20, 21, 21, 22, - 22, 22, 23, 23, 23, 24, 25, 25, 26, 26, - 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, - 29, 29, 29, 30, 30, 30 -}; +// TODO: maybe turn this into a proper n-ary tree instead of an +// n-ary tree implemented in terms of a binary tree. +// (Together with _parserNodes in Vocabulary) -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 2, 3, 4, 0, 1, 0, 1, 2, - 4, 1, 2, 4, 1, 1, 1, 3, 1, 3, - 3, 4, 5, 2, 1, 1, 1, 3, 4, 3, - 4, 2, 4, 3, 2, 4 -}; +static ParseTreeNode said_tree[VOCAB_TREE_NODES]; -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 7, 15, 0, 0, 0, 0, 0, 0, 0, 5, - 18, 24, 16, 8, 25, 26, 0, 0, 18, 31, - 0, 0, 0, 1, 11, 6, 0, 2, 5, 23, - 0, 0, 0, 19, 17, 0, 0, 29, 27, 0, - 0, 9, 0, 14, 0, 3, 5, 0, 20, 0, - 0, 34, 0, 32, 30, 0, 12, 0, 4, 0, - 21, 28, 33, 0, 10, 0, 22, 35, 13 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 8, 27, 9, 28, 46, 10, 11, 12, 13, - 14, 15, 37 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -24 -static const yytype_int8 yypact[] = -{ - -1, -24, -1, 62, 62, 54, 1, 5, 18, 38, - -24, 47, 3, -24, -24, 12, 23, 15, -3, 3, - 28, 62, -1, -24, -1, -24, 42, -24, 39, -24, - 53, 54, 54, -24, -24, 62, 50, -24, -24, 29, - 41, -24, -1, -1, 52, -24, 55, 62, 3, 57, - 63, 20, -1, -24, -24, 64, -24, -1, -24, 32, - -24, -24, -24, 67, -24, 66, -24, -24, -24 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -24, -24, -23, -24, -24, -24, 68, -24, 0, -2, - 69, -4, 26 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 16, 20, 1, 17, 19, 45, 2, 30, 3, 35, - 21, 4, 22, 5, 36, 6, 7, 31, 23, 30, - 40, 39, 41, 58, 30, 34, 32, 49, 50, 31, - 48, 33, 35, 30, 31, 51, 30, 36, 38, 53, - 55, 56, 66, 31, 24, 43, 31, 59, 42, 54, - 63, 25, 25, 26, 44, 65, 1, 52, 57, 4, - 2, 5, 47, 6, 7, 1, 4, 60, 25, 2, - 6, 7, 18, 61, 64, 67, 68, 62, 0, 0, - 29 -}; - -static const yytype_int8 yycheck[] = -{ - 2, 5, 3, 3, 4, 28, 7, 4, 9, 12, - 9, 12, 7, 14, 17, 16, 17, 14, 0, 4, - 22, 21, 24, 46, 4, 10, 14, 31, 32, 14, - 30, 8, 12, 4, 14, 35, 4, 17, 10, 10, - 42, 43, 10, 14, 6, 6, 14, 47, 6, 8, - 52, 13, 13, 15, 15, 57, 3, 7, 6, 12, - 7, 14, 9, 16, 17, 3, 12, 10, 13, 7, - 16, 17, 4, 10, 10, 8, 10, 51, -1, -1, - 11 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 3, 7, 9, 12, 14, 16, 17, 19, 21, - 24, 25, 26, 27, 28, 29, 27, 26, 24, 26, - 29, 9, 7, 0, 6, 13, 15, 20, 22, 28, - 4, 14, 14, 8, 10, 12, 17, 30, 10, 26, - 27, 27, 6, 6, 15, 20, 23, 9, 26, 29, - 29, 26, 7, 10, 8, 27, 27, 6, 20, 26, - 10, 10, 30, 27, 10, 27, 10, 8, 10 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif +typedef int wgroup_t; +typedef int said_spec_t; -/* YYLEX -- calling `yylex' with the right arguments. */ -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif +static ParseTreeNode* said_next_node() { + assert(said_tree_pos > 0 && said_tree_pos < VOCAB_TREE_NODES); -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } + return &said_tree[said_tree_pos++]; } +static ParseTreeNode* said_leaf_node(ParseTreeNode* pos, int value) { + pos->type = kParseTreeLeafNode; + pos->value = value; -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); + return pos; } -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ +static ParseTreeNode* said_word_node(ParseTreeNode* pos, int value) { + pos->type = kParseTreeWordNode; + pos->value = value; -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) -#else -static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); + return pos; } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - +static ParseTreeNode* said_branch_node(ParseTreeNode* pos, + ParseTreeNode* left, + ParseTreeNode* right) { + pos->type = kParseTreeBranchNode; + pos->left = left; + pos->right = right; -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - fprintf (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - fprintf (stderr, "\n"); - } + return pos; } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif +static ParseTreeNode* said_branch_attach_left(ParseTreeNode* pos, + ParseTreeNode* left) { + pos->type = kParseTreeBranchNode; + pos->left = left; -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif + return pos; - +} -#if YYERROR_VERBOSE +static ParseTreeNode* said_branch_attach_right(ParseTreeNode* pos, + ParseTreeNode* right) { + pos->type = kParseTreeBranchNode; + pos->right = right; -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; + return pos; } -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - while ((*yyd++ = *yys++) != '\0') - continue; - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - YYUSE (yyvaluep); +/* + pos + / \ + . \ + * + / \ + / 0 + * + / \ + / \ + / subtree + major / \ + / . + minor + + . = unchanged child node + * = new branch node + 0 = NULL child node. (Location for future siblings of the subtree) - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); +*/ - switch (yytype) - { +static bool said_attach_subtree(ParseTreeNode* pos, int major, int minor, + ParseTreeNode* subtree) { + bool retval = true; - default: - break; - } -} - + said_branch_attach_right(pos, + said_branch_node(said_next_node(), + said_branch_node(said_next_node(), + said_leaf_node(said_next_node(), major), + said_branch_attach_left(subtree, + said_leaf_node(said_next_node(), minor))), + 0)); -/* Prevent warnings from -Wmissing-prototypes. */ + return retval; +} -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ -/* The look-ahead symbol. */ -int yychar; +/*****************/ +/**** Parsing ****/ +/*****************/ -/* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval; +static bool parseSpec(ParseTreeNode* parentNode); +static bool parsePart2(ParseTreeNode* parentNode, bool& nonempty); +static bool parsePart3(ParseTreeNode* parentNode, bool& nonempty); +static bool parseSlash(ParseTreeNode* parentNode); +static bool parseExpr(ParseTreeNode* parentNode); +static bool parseRef(ParseTreeNode* parentNode); +static bool parseComma(ParseTreeNode* parentNode); +static bool parseList(ParseTreeNode* parentNode); +static bool parseListEntry(ParseTreeNode* parentNode); +static bool parseWord(ParseTreeNode* parentNode); -/* Number of syntax errors so far. */ -int yynerrs; +static bool parseWord(ParseTreeNode* parentNode) +{ + int token = said_tokens[said_token]; + if (token & 0x8000) + return false; + said_token++; + ParseTreeNode* newNode = said_word_node(said_next_node(), token); -/*----------. -| yyparse. | -`----------*/ + parentNode->right = newNode; -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void) -#else -int -yyparse () + return true; +} -#endif -#endif +static bool parsePart2(ParseTreeNode* parentNode, bool& nonempty) { - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif + // Store current state for rolling back if we fail + int curToken = said_token; + int curTreePos = said_tree_pos; + ParseTreeNode* curRightChild = parentNode->right; - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + ParseTreeNode* newNode = said_branch_node(said_next_node(), 0, 0); - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; + nonempty = true; + bool found; - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; + found = parseSlash(newNode); - YYDPRINTF ((stderr, "Starting parse\n")); + if (found) { - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + said_attach_subtree(parentNode, 0x142, 0x14a, newNode); - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ + return true; - yyssp = yyss; - yyvsp = yyvs; + } else if (said_tokens[said_token] == TOKEN_BRACKETO) { + said_token++; + + found = parsePart2(newNode, nonempty); - goto yysetstate; + if (found) { -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to look-ahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a look-ahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } + if (said_tokens[said_token] == TOKEN_BRACKETC) { + said_token++; - if (yyn == YYFINAL) - YYACCEPT; + said_attach_subtree(parentNode, 0x152, 0x142, newNode); - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; + return true; + } + } - /* Shift the look-ahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + } - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + // CHECKME: this doesn't look right if the [] section matched partially + // Should the below 'if' be an 'else if' ? - yystate = yyn; - *++yyvsp = yylval; + if (said_tokens[said_token] == TOKEN_SLASH) { + said_token++; - goto yynewstate; + nonempty = false; + return true; -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; + } + // Rollback + said_token = curToken; + said_tree_pos = curTreePos; + parentNode->right = curRightChild; + return false; +} -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; +static bool parsePart3(ParseTreeNode* parentNode, bool& nonempty) +{ + // Store current state for rolling back if we fail + int curToken = said_token; + int curTreePos = said_tree_pos; + ParseTreeNode* curRightChild = parentNode->right; - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. + ParseTreeNode* newNode = said_branch_node(said_next_node(), 0, 0); - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; + bool found; + nonempty = true; - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: + found = parseSlash(newNode); - { (yyval) = said_top_branch(said_attach_branch((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]))); ;} - break; + if (found) { - case 3: + said_attach_subtree(parentNode, 0x143, 0x14a, newNode); - { (yyval) = said_top_branch(said_attach_branch((yyvsp[(1) - (3)]), said_attach_branch((yyvsp[(2) - (3)]), (yyvsp[(3) - (3)])))); ;} - break; + return true; - case 4: + } else if (said_tokens[said_token] == TOKEN_BRACKETO) { + said_token++; + + found = parsePart3(newNode, nonempty); - { (yyval) = said_top_branch(said_attach_branch((yyvsp[(1) - (4)]), said_attach_branch((yyvsp[(2) - (4)]), said_attach_branch((yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]))))); ;} - break; + if (found) { - case 5: + if (said_tokens[said_token] == TOKEN_BRACKETC) { + said_token++; - { (yyval) = SAID_BRANCH_NULL; ;} - break; + said_attach_subtree(parentNode, 0x152, 0x143, newNode); - case 6: + return true; + } + } - { (yyval) = said_paren(said_value(0x14b, said_value(0xf900, said_terminal(0xf900))), SAID_BRANCH_NULL); ;} - break; + } - case 7: + // CHECKME: this doesn't look right if the [] section matched partially + // Should the below 'if' be an 'else if' ? - { (yyval) = SAID_BRANCH_NULL; ;} - break; + if (said_tokens[said_token] == TOKEN_SLASH) { + said_token++; - case 8: + nonempty = false; - { (yyval) = said_paren(said_value(0x141, said_value(0x149, (yyvsp[(1) - (1)]))), SAID_BRANCH_NULL); ;} - break; + return true; - case 9: + } - { (yyval) = said_aug_branch(0x142, 0x14a, (yyvsp[(2) - (2)]), SAID_BRANCH_NULL); ;} - break; + // Rollback + said_token = curToken; + said_tree_pos = curTreePos; + parentNode->right = curRightChild; + return false; +} - case 10: - { (yyval) = said_aug_branch(0x152, 0x142, said_aug_branch(0x142, 0x14a, (yyvsp[(3) - (4)]), SAID_BRANCH_NULL), SAID_BRANCH_NULL); ;} - break; +static bool parseSlash(ParseTreeNode* parentNode) +{ + // Store current state for rolling back if we fail + int curToken = said_token; + int curTreePos = said_tree_pos; + ParseTreeNode* curRightChild = parentNode->right; - case 11: + if (said_tokens[said_token] == TOKEN_SLASH) { + said_token++; - { (yyval) = SAID_BRANCH_NULL; ;} - break; + bool found = parseExpr(parentNode); - case 12: + if (found) + return true; - { (yyval) = said_aug_branch(0x143, 0x14a, (yyvsp[(2) - (2)]), SAID_BRANCH_NULL); ;} - break; + } - case 13: + // Rollback + said_token = curToken; + said_tree_pos = curTreePos; + parentNode->right = curRightChild; + return false; +} - { (yyval) = said_aug_branch(0x152, 0x143, said_aug_branch(0x143, 0x14a, (yyvsp[(3) - (4)]), SAID_BRANCH_NULL), SAID_BRANCH_NULL); ;} - break; - case 14: +static bool parseRef(ParseTreeNode* parentNode) +{ + // Store current state for rolling back if we fail + int curToken = said_token; + int curTreePos = said_tree_pos; + ParseTreeNode* curRightChild = parentNode->right; - { (yyval) = SAID_BRANCH_NULL; ;} - break; + ParseTreeNode* newNode = said_branch_node(said_next_node(), 0, 0); - case 15: + ParseTreeNode* newParent = parentNode; - { (yyval) = said_paren(said_value(0x141, said_value(0x153, said_terminal((yyvsp[(1) - (1)])))), SAID_BRANCH_NULL); ;} - break; + bool found; - case 16: + if (said_tokens[said_token] == TOKEN_LT) { + said_token++; - { (yyval) = said_aug_branch(0x141, 0x14f, (yyvsp[(1) - (1)]), SAID_BRANCH_NULL); ;} - break; + found = parseList(newNode); - case 17: + if (found) { - { (yyval) = said_aug_branch(0x141, 0x14f, said_aug_branch(0x152, 0x14c, said_aug_branch(0x141, 0x14f, (yyvsp[(2) - (3)]), SAID_BRANCH_NULL), SAID_BRANCH_NULL), SAID_BRANCH_NULL); ;} - break; + said_attach_subtree(newParent, 0x144, 0x14f, newNode); - case 18: + newParent = newParent->right; + + newNode = said_branch_node(said_next_node(), 0, 0); - { (yyval) = (yyvsp[(1) - (1)]); ;} - break; + found = parseRef(newNode); - case 19: + if (found) { - { (yyval) = said_aug_branch(0x141, 0x14c, (yyvsp[(2) - (3)]), SAID_BRANCH_NULL); ;} - break; + said_attach_subtree(newParent, 0x141, 0x144, newNode); - case 20: + } - { (yyval) = said_attach_branch((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); ;} - break; + return true; - case 21: + } - { (yyval) = said_attach_branch((yyvsp[(1) - (4)]), (yyvsp[(3) - (4)])); ;} - break; + } - case 22: + // NB: This is not an "else if'. + // If there is a "< [ ... ]", that is parsed as "< ..." - { (yyval) = said_attach_branch((yyvsp[(1) - (5)]), (yyvsp[(3) - (5)])); ;} - break; + if (said_tokens[said_token] == TOKEN_BRACKETO) { + said_token++; + + found = parseRef(newNode); - case 23: + if (found) { - { (yyval) = said_attach_branch((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])); ;} - break; + if (said_tokens[said_token] == TOKEN_BRACKETC) { + said_token++; - case 24: + said_attach_subtree(parentNode, 0x152, 0x144, newNode); - { (yyval) = (yyvsp[(1) - (1)]); ;} - break; + return true; + } + } - case 25: + } - { (yyval) = (yyvsp[(1) - (1)]); ;} - break; + // Rollback + said_token = curToken; + said_tree_pos = curTreePos; + parentNode->right = curRightChild; + return false; +} - case 26: +static bool parseComma(ParseTreeNode* parentNode) +{ + // Store current state for rolling back if we fail + int curToken = said_token; + int curTreePos = said_tree_pos; + ParseTreeNode* curRightChild = parentNode->right; - { (yyval) = (yyvsp[(1) - (1)]); ;} - break; + if (said_tokens[said_token] == TOKEN_COMMA) { + said_token++; - case 27: + bool found = parseList(parentNode); - { (yyval) = said_aug_branch(0x152, 0x144, (yyvsp[(2) - (3)]), SAID_BRANCH_NULL); ;} - break; + if (found) + return true; - case 28: + } - { (yyval) = said_attach_branch((yyvsp[(1) - (4)]), said_aug_branch(0x152, 0x144, (yyvsp[(3) - (4)]), SAID_BRANCH_NULL)); ;} - break; + // Rollback + said_token = curToken; + said_tree_pos = curTreePos; + parentNode->right = curRightChild; + return false; +} - case 29: +static bool parseListEntry(ParseTreeNode* parentNode) +{ + // Store current state for rolling back if we fail + int curToken = said_token; + int curTreePos = said_tree_pos; + ParseTreeNode* curRightChild = parentNode->right; - { (yyval) = said_aug_branch(0x144, 0x14f, (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)])); ;} - break; + ParseTreeNode* newNode = said_branch_node(said_next_node(), 0, 0); - case 30: + bool found; - { (yyval) = said_aug_branch(0x144, 0x14f, said_aug_branch(0x141, 0x144, (yyvsp[(2) - (4)]), SAID_BRANCH_NULL), SAID_BRANCH_NULL); ;} - break; + if (said_tokens[said_token] == TOKEN_BRACKETO) { + said_token++; - case 31: + found = parseExpr(newNode); - { (yyval) = said_aug_branch(0x144, 0x14f, (yyvsp[(2) - (2)]), SAID_BRANCH_NULL); ;} - break; + if (found) { - case 32: + if (said_tokens[said_token] == TOKEN_BRACKETC) { + said_token++; - { (yyval) = said_aug_branch(0x152, 0x144, said_aug_branch(0x144, 0x14f, (yyvsp[(3) - (4)]), SAID_BRANCH_NULL), SAID_BRANCH_NULL); ;} - break; + said_attach_subtree(parentNode, 0x152, 0x14c, newNode); - case 33: + return true; + } + } - { (yyval) = said_aug_branch(0x141, 0x144, said_aug_branch(0x144, 0x14f, (yyvsp[(2) - (3)]), SAID_BRANCH_NULL), (yyvsp[(3) - (3)])); ;} - break; + } else if (said_tokens[said_token] == TOKEN_PARENO) { + said_token++; - case 34: + found = parseExpr(newNode); - { (yyval) = said_aug_branch(0x141, 0x144, said_aug_branch(0x144, 0x14f, (yyvsp[(2) - (2)]), SAID_BRANCH_NULL), SAID_BRANCH_NULL); ;} - break; + if (found) { - case 35: + if (said_tokens[said_token] == TOKEN_PARENC) { + said_token++; - { (yyval) = said_aug_branch(0x141, 0x14c, (yyvsp[(2) - (4)]), SAID_BRANCH_NULL); ;} - break; + said_attach_subtree(parentNode, 0x141, 0x14c, newNode); + return true; + } + } -/* Line 1267 of yacc.c. */ + } else if (parseWord(newNode)) { - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + said_attach_subtree(parentNode, 0x141, 0x153, newNode); - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); + return true; - *++yyvsp = yyval; + } - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ + // Rollback + said_token = curToken; + said_tree_pos = curTreePos; + parentNode->right = curRightChild; + return false; +} - yyn = yyr1[yyn]; +static bool parseList(ParseTreeNode* parentNode) +{ + // Store current state for rolling back if we fail + int curToken = said_token; + int curTreePos = said_tree_pos; + ParseTreeNode* curRightChild = parentNode->right; - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; + bool found; - goto yynewstate; + ParseTreeNode* newParent = parentNode; + found = parseListEntry(newParent); -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (yymsg); - } - else - { - yyerror (YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } + if (found) { + newParent = newParent->right; + found = parseComma(newParent); - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ + return true; - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse look-ahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } } - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; + // Rollback + said_token = curToken; + said_tree_pos = curTreePos; + parentNode->right = curRightChild; + return false; +} +static bool parseExpr(ParseTreeNode* parentNode) +{ + // Store current state for rolling back if we fail + int curToken = said_token; + int curTreePos = said_tree_pos; + ParseTreeNode* curRightChild = parentNode->right; - yydestruct ("Error: popping", - yystos[yystate], yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } + ParseTreeNode* newNode = said_branch_node(said_next_node(), 0, 0); - if (yyn == YYFINAL) - YYACCEPT; + bool ret = false; + bool found; - *++yyvsp = yylval; + ParseTreeNode* newParent = parentNode; + found = parseList(newNode); - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + if (found) { + ret = true; - yystate = yyn; - goto yynewstate; + said_attach_subtree(newParent, 0x141, 0x14F, newNode); + newParent = newParent->right; -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; + } -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; + found = parseRef(newParent); -#ifndef yyoverflow -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif + if (found || ret) + return true; -yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); + // Rollback + said_token = curToken; + said_tree_pos = curTreePos; + parentNode->right = curRightChild; + return false; } +static bool parseSpec(ParseTreeNode* parentNode) +{ + // Store current state for rolling back if we fail + int curToken = said_token; + int curTreePos = said_tree_pos; + ParseTreeNode* curRightChild = parentNode->right; + ParseTreeNode* newNode = said_branch_node(said_next_node(), 0, 0); + bool ret = false; + bool found; -int parse_yy_token_lookup[] = {YY_COMMA, YY_AMP, YY_SLASH, YY_PARENO, YY_PARENC, YY_BRACKETSO, YY_BRACKETSC, YY_HASH, YY_LT, YY_GT}; + ParseTreeNode* newParent = parentNode; -static int yylex() { - int retval = said_tokens[said_token++]; + found = parseExpr(newNode); - if (retval < SAID_LONG(SAID_FIRST)) { - yylval = retval; - retval = WGROUP; - } else { - retval >>= 8; - - if (retval == SAID_TERM) - retval = 0; - else { - assert(retval >= SAID_FIRST); - retval = parse_yy_token_lookup[retval - SAID_FIRST]; - if (retval == YY_BRACKETSO) { - if ((said_tokens[said_token] >> 8) == SAID_LT) - retval = YY_BRACKETSO_LT; - else - if ((said_tokens[said_token] >> 8) == SAID_SLASH) - retval = YY_BRACKETSO_SLASH; - } else if (retval == YY_LT && (said_tokens[said_token] >> 8) == SAID_BRACKO) { - retval = YY_LT_BRACKETSO; - } else if (retval == YY_LT && (said_tokens[said_token] >> 8) == SAID_PARENO) { - retval = YY_LT_PARENO; - } - } - } + if (found) { + // Sentence part 1 found + said_attach_subtree(newParent, 0x141, 0x149, newNode); - return retval; -} + newParent = newParent->right; -static int said_next_node() { - return ((said_tree_pos == 0) || (said_tree_pos >= VOCAB_TREE_NODES)) ? said_tree_pos = 0 : said_tree_pos++; -} + ret = true; + } -#define SAID_NEXT_NODE said_next_node() + bool nonempty; -static int said_leaf_node(tree_t pos, int value) { - said_tree[pos].type = kParseTreeLeafNode; + found = parsePart2(newParent, nonempty); - if (value != VALUE_IGNORE) - said_tree[pos].content.value = value; + if (found) { - return pos; -} + ret = true; -static int said_branch_node(tree_t pos, int left, int right) { - said_tree[pos].type = kParseTreeBranchNode; + if (nonempty) // non-empty part found + newParent = newParent->right; - if (left != VALUE_IGNORE) - said_tree[pos].content.branches[0] = left; - if (right != VALUE_IGNORE) - said_tree[pos].content.branches[1] = right; + found = parsePart3(newParent, nonempty); - return pos; -} + if (found) { -static tree_t said_paren(tree_t t1, tree_t t2) { - if (t1) - return said_branch_node(SAID_NEXT_NODE, t1, t2); - else - return t2; -} + if (nonempty) + newParent = newParent->right; + } + } -static tree_t said_value(int val, tree_t t) { - return said_branch_node(SAID_NEXT_NODE, said_leaf_node(SAID_NEXT_NODE, val), t); + if (said_tokens[said_token] == TOKEN_GT) { + said_token++; -} + newNode = said_branch_node(said_next_node(), 0, + said_leaf_node(said_next_node(), TOKEN_GT)); -static tree_t said_terminal(int val) { - return said_leaf_node(SAID_NEXT_NODE, val); -} + said_attach_subtree(newParent, 0x14B, TOKEN_GT, newNode); -static tree_t said_aug_branch(int n1, int n2, tree_t t1, tree_t t2) { - int retval; + } - retval = said_branch_node(SAID_NEXT_NODE, - said_branch_node(SAID_NEXT_NODE, - said_leaf_node(SAID_NEXT_NODE, n1), - said_branch_node(SAID_NEXT_NODE, - said_leaf_node(SAID_NEXT_NODE, n2), - t1) - ), - t2); - -#ifdef SAID_DEBUG - fprintf(stderr, "AUG(0x%x, 0x%x, [%04x], [%04x]) = [%04x]\n", n1, n2, t1, t2, retval); -#endif - return retval; + if (ret) + return true; + + // Rollback + said_token = curToken; + said_tree_pos = curTreePos; + parentNode->right = curRightChild; + return false; } -static tree_t said_attach_branch(tree_t base, tree_t attacheant) { -#ifdef SAID_DEBUG - fprintf(stderr, "ATT2([%04x], [%04x]) = [%04x]\n", base, attacheant, base); -#endif - if (!attacheant) - return base; - if (!base) - return attacheant; +static bool buildSaidTree() { + said_branch_node(said_tree, &said_tree[1], &said_tree[2]); + said_leaf_node(&said_tree[1], 0x141); // Magic number #1 + said_branch_node(&said_tree[2], &said_tree[3], 0); + said_leaf_node(&said_tree[3], 0x13f); // Magic number #2 - if (!base) - return 0; // Happens if we're out of space + said_tree_pos = SAID_TREE_START; - said_branch_node(base, VALUE_IGNORE, attacheant); + bool ret = parseSpec(&said_tree[2]); - return base; -} + if (!ret) + return false; -static said_spec_t said_top_branch(tree_t first) { -#ifdef SAID_DEBUG - fprintf(stderr, "TOP([%04x])\n", first); -#endif - said_branch_node(0, 1, 2); - said_leaf_node(1, 0x141); // Magic number #1 - said_branch_node(2, 3, first); - said_leaf_node(3, 0x13f); // Magic number #2 + if (said_tokens[said_token] != TOKEN_TERM) { + // No terminator, so parse error. - ++said_blessed; + // Rollback + said_tree[2].right = 0; + said_token = 0; + said_tree_pos = SAID_TREE_START; + return false; + } - return 0; + return true; } -static int said_parse_spec(byte *spec) { +static int said_parse_spec(const byte *spec) { int nextitem; - said_parse_error = NULL; said_token = 0; said_tokens_nr = 0; - said_blessed = 0; said_tree_pos = SAID_TREE_START; @@ -2025,26 +674,13 @@ static int said_parse_spec(byte *spec) { } while ((nextitem != SAID_TERM) && (said_tokens_nr < MAX_SAID_TOKENS)); - if (nextitem == SAID_TERM) - yyparse(); - else { + if (nextitem != SAID_TERM) { warning("SAID spec is too long"); return 1; } - if (said_parse_error) { - warning("Error while parsing SAID spec: %s", said_parse_error); - free(said_parse_error); - return 1; - } - - if (said_tree_pos == 0) { - warning("Out of tree space while parsing SAID spec"); - return 1; - } - - if (said_blessed != 1) { - warning("Found multiple top branches"); + if (!buildSaidTree()) { + warning("Error while parsing SAID spec"); return 1; } @@ -2055,385 +691,304 @@ static int said_parse_spec(byte *spec) { /**** Augmentation ****/ /**********************/ -// primitive functions +static bool dontclaim; +static int outputDepth; -#define AUG_READ_BRANCH(a, br, p) \ - if (tree[p].type != kParseTreeBranchNode) \ - return 0; \ - a = tree[p].content.branches[br]; +enum ScanSaidType { + SCAN_SAID_AND = 0, + SCAN_SAID_OR = 1 +}; -#define AUG_READ_VALUE(a, p) \ - if (tree[p].type != kParseTreeLeafNode) \ - return 0; \ - a = tree[p].content.value; +static int matchTrees(ParseTreeNode* parseT, ParseTreeNode* saidT); +static int scanSaidChildren(ParseTreeNode* parseT, ParseTreeNode* saidT, + ScanSaidType type); +static int scanParseChildren(ParseTreeNode* parseT, ParseTreeNode* saidT); -#define AUG_ASSERT(i) \ - if (!i) return 0; -static int aug_get_next_sibling(parse_tree_node_t *tree, int pos, int *first, int *second) { - // Returns the next sibling relative to the specified position in 'tree', - // sets *first and *second to its augment node values, returns the new position - // or 0 if there was no next sibling - int seek, valpos; +static int node_major(ParseTreeNode* node) { + assert(node->type == kParseTreeBranchNode); + assert(node->left->type == kParseTreeLeafNode); + return node->left->value; +} +static int node_minor(ParseTreeNode* node) { + assert(node->type == kParseTreeBranchNode); + assert(node->right->type == kParseTreeBranchNode); + assert(node->right->left->type == kParseTreeLeafNode); + return node->right->left->value; +} +static bool node_is_terminal(ParseTreeNode* node) { + return (node->right->right && + node->right->right->type != kParseTreeBranchNode); +} +static int node_terminal_value(ParseTreeNode* node) { + assert(node_is_terminal(node)); + return node->right->right->value; +} +#ifdef SCI_DEBUG_PARSE_TREE_AUGMENTATION +static void node_print_desc(ParseTreeNode* node) { + assert(node); + assert(node->left); + if (node->left->type == kParseTreeBranchNode) { + scidprintf("< "); + node_print_desc(node->left); + scidprintf(", ...>"); + } else { + if (node_is_terminal(node)) { + scidprintf("(%03x %03x %03x)", node_major(node), + node_minor(node), + node_terminal_value(node)); + } else { + scidprintf("(%03x %03x <...>)", node_major(node), + node_minor(node)); + } + } +} +#else +static void node_print_desc(ParseTreeNode*) { } +#endif - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(seek, 0, pos); - AUG_ASSERT(seek); - // Now retrieve first value - AUG_READ_BRANCH(valpos, 0, seek); - AUG_ASSERT(valpos); - AUG_READ_VALUE(*first, valpos); - // Get second value - AUG_READ_BRANCH(seek, 1, seek); - AUG_ASSERT(seek); - AUG_READ_BRANCH(valpos, 0, seek); - AUG_ASSERT(valpos); - AUG_READ_VALUE(*second, valpos); - return pos; -} +static int matchTrees(ParseTreeNode* parseT, ParseTreeNode* saidT) +{ + outputDepth++; + scidprintf("%*smatchTrees on ", outputDepth, ""); + node_print_desc(parseT); + scidprintf(" and "); + node_print_desc(saidT); + scidprintf("\n"); -static int aug_get_wgroup(parse_tree_node_t *tree, int pos) { - // Returns 0 if pos in tree is not the root of a 3-element list, otherwise - // it returns the last element (which, in practice, is the word group - int val; + bool inParen = node_minor(saidT) == 0x14F || node_minor(saidT) == 0x150; + bool inBracket = node_major(saidT) == 0x152; - AUG_READ_BRANCH(pos, 0, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); - AUG_READ_VALUE(val, pos); + int ret; - return val; -} + if (node_major(parseT) != 0x141 && + node_major(saidT) != 0x141 && node_major(saidT) != 0x152 && + node_major(saidT) != node_major(parseT)) + { + ret = -1; + } -static int aug_get_base_node(parse_tree_node_t *tree) { - int startpos = 0; - AUG_READ_BRANCH(startpos, 1, startpos); + // parse major is 0x141 and/or + // said major is 0x141/0x152 and/or + // said major is parse major - return startpos; -} + else if (node_is_terminal(saidT) && node_is_terminal(parseT) ) { -// semi-primitive functions + // both saidT and parseT are terminals -static int aug_get_first_child(parse_tree_node_t *tree, int pos, int *first, int *second) { - // like aug_get_next_sibling, except that it recurses into the tree and - // finds the first child (usually *not* Ayanami Rei) of the current branch - // rather than its next sibling. - AUG_READ_BRANCH(pos, 0, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); + int said_val = node_terminal_value(saidT); + int parse_val = node_terminal_value(parseT); - return aug_get_next_sibling(tree, pos, first, second); -} + if (said_val != WORD_NONE && + (said_val == parse_val || said_val == WORD_ANY || + parse_val == WORD_ANY)) + ret = 1; + else + ret = -1; -static void aug_find_words_recursively(parse_tree_node_t *tree, int startpos, int *base_words, int *base_words_nr, - int *ref_words, int *ref_words_nr, int maxwords, int refbranch) { - // Finds and lists all base (141) and reference (144) words */ - int major, minor; - int word; - int pos = aug_get_first_child(tree, startpos, &major, &minor); + scidprintf("%*smatchTrees matching terminals: %03x vs %03x (%d)\n", + outputDepth, "", parse_val, said_val, ret); - //if (major == WORD_TYPE_REF) - // refbranch = 1; + } else if (node_is_terminal(saidT) && !node_is_terminal(parseT)) { - while (pos) { - if ((word = aug_get_wgroup(tree, pos))) { // found a word - if (!refbranch && major == WORD_TYPE_BASE) { - if ((*base_words_nr) == maxwords) { - warning("Out of regular words"); - return; // return gracefully - } + // saidT is a terminal, but parseT isn't - base_words[*base_words_nr] = word; // register word - ++(*base_words_nr); + if (node_major(parseT) == 0x141 || + node_major(parseT) == node_major(saidT)) + ret = scanParseChildren(parseT->right->right, saidT); + else + ret = 0; - } - if (major == WORD_TYPE_REF || refbranch) { - if ((*ref_words_nr) == maxwords) { - warning("Out of reference words"); - return; // return gracefully - } + } else if (node_is_terminal(parseT)) { - ref_words[*ref_words_nr] = word; // register word - ++(*ref_words_nr); + // parseT is a terminal, but saidT isn't - } - if (major != WORD_TYPE_SYNTACTIC_SUGAR && major != WORD_TYPE_BASE && major != WORD_TYPE_REF) - warning("aug_find_words_recursively(): Unknown word type %03x", major); + if (node_major(saidT) == 0x141 || node_major(saidT) == 0x152 || + node_major(saidT) == node_major(parseT)) + ret = scanSaidChildren(parseT, saidT->right->right, + inParen ? SCAN_SAID_OR : SCAN_SAID_AND ); + else + ret = 0; - } else // Did NOT find a word group: Attempt to recurse - aug_find_words_recursively(tree, pos, base_words, base_words_nr, - ref_words, ref_words_nr, maxwords, refbranch || major == WORD_TYPE_REF); + } else if (node_major(saidT) != 0x141 && node_major(saidT) != 0x152 && + node_major(saidT) != node_major(parseT)) { - pos = aug_get_next_sibling(tree, pos, &major, &minor); - } -} + // parseT and saidT both aren't terminals + // said major is not 0x141 or 0x152 or parse major + ret = scanParseChildren(parseT->right->right, saidT); -static void aug_find_words(parse_tree_node_t *tree, int startpos, int *base_words, int *base_words_nr, - int *ref_words, int *ref_words_nr, int maxwords) { - // initializing wrapper for aug_find_words_recursively() - *base_words_nr = 0; - *ref_words_nr = 0; + } else { - aug_find_words_recursively(tree, startpos, base_words, base_words_nr, ref_words, ref_words_nr, maxwords, 0); -} + // parseT and saidT are both not terminals, + // said major 0x141 or 0x152 or equal to parse major + ret = scanSaidChildren(parseT->right->right, saidT->right->right, + inParen ? SCAN_SAID_OR : SCAN_SAID_AND); -static int aug_contains_word(int *list, int length, int word) { - int i; + } - if (word == ANYWORD) - return (length); + if (inBracket && ret == 0) { + scidprintf("%*smatchTrees changing ret to 1 due to brackets\n", + outputDepth, ""); + ret = 1; + } - for (i = 0; i < length; i++) - if (list[i] == word) - return 1; + scidprintf("%*smatchTrees returning %d\n", outputDepth, "", ret); + outputDepth--; - return 0; + return ret; } -static int augment_sentence_expression(parse_tree_node_t *saidt, int augment_pos, parse_tree_node_t *parset, - int parse_branch, int major, int minor, int *base_words, int base_words_nr, - int *ref_words, int ref_words_nr); +static int scanSaidChildren(ParseTreeNode* parseT, ParseTreeNode* saidT, + ScanSaidType type) { + outputDepth++; + scidprintf("%*sscanSaid(%s) on ", outputDepth, "", + type == SCAN_SAID_OR ? "OR" : "AND"); + node_print_desc(parseT); + scidprintf(" and "); + node_print_desc(saidT); + scidprintf("\n"); -static int augment_match_expression_p(parse_tree_node_t *saidt, int augment_pos, parse_tree_node_t *parset, - int parse_basepos, int major, int minor, - int *base_words, int base_words_nr, int *ref_words, int ref_words_nr) { - int cmajor, cminor, cpos; - cpos = aug_get_first_child(saidt, augment_pos, &cmajor, &cminor); - if (!cpos) { - warning("augment_match_expression_p(): Empty condition"); - return 1; - } + int ret = 1; - scidprintf("Attempting to match (%03x %03x (%03x %03x\n", major, minor, cmajor, cminor); - - if ((major == WORD_TYPE_BASE) && (minor == AUGMENT_SENTENCE_MINOR_RECURSE)) - return augment_match_expression_p(saidt, cpos, parset, parse_basepos, cmajor, cminor, - base_words, base_words_nr, ref_words, ref_words_nr); - - switch (major) { - - case WORD_TYPE_BASE: - while (cpos) { - if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_WORD) { - int word = aug_get_wgroup(saidt, cpos); - scidprintf("Looking for word %03x\n", word); - - if (aug_contains_word(base_words, base_words_nr, word)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_PHRASE) { - if (augment_sentence_expression(saidt, cpos, parset, parse_basepos, cmajor, cminor, - base_words, base_words_nr, ref_words, ref_words_nr)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_PARENTHESES) { - int gc_major, gc_minor; - int gchild = aug_get_first_child(saidt, cpos, &gc_major, &gc_minor); - - while (gchild) { - if (augment_match_expression_p(saidt, cpos, parset, parse_basepos, major, - minor, base_words, base_words_nr, - ref_words, ref_words_nr)) - return 1; - gchild = aug_get_next_sibling(saidt, gchild, &gc_major, &gc_minor); - } - } else - warning("augment_match_expression_p(): Unknown type 141 minor number %3x", cminor); - - cpos = aug_get_next_sibling(saidt, cpos, &cmajor, &cminor); + assert(!(type == SCAN_SAID_OR && !saidT)); - } - break; - - case WORD_TYPE_REF: - while (cpos) { - if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_WORD) { - int word = aug_get_wgroup(saidt, cpos); - scidprintf("Looking for refword %03x\n", word); - - if (aug_contains_word(ref_words, ref_words_nr, word)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_PHRASE) { - if (augment_match_expression_p(saidt, cpos, parset, parse_basepos, cmajor, cminor, - base_words, base_words_nr, ref_words, ref_words_nr)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_PARENTHESES) { - int gc_major, gc_minor; - int gchild = aug_get_first_child(saidt, cpos, &gc_major, &gc_minor); - - while (gchild) { - if (augment_match_expression_p(saidt, cpos, parset, parse_basepos, major, - minor, base_words, base_words_nr, - ref_words, ref_words_nr)) - return 1; - gchild = aug_get_next_sibling(saidt, gchild, &gc_major, &gc_minor); - } - } else - warning("augment_match_expression_p(): Unknown type 144 minor number %3x", cminor); - - cpos = aug_get_next_sibling(saidt, cpos, &cmajor, &cminor); + while (saidT) { + assert(saidT->type == kParseTreeBranchNode); - } - break; + ParseTreeNode* saidChild = saidT->left; + assert(saidChild); - case AUGMENT_SENTENCE_PART_BRACKETS: - if (augment_match_expression_p(saidt, cpos, parset, parse_basepos, cmajor, cminor, - base_words, base_words_nr, ref_words, ref_words_nr)) - return 1; + if (node_major(saidChild) != 0x145) { - scidprintf("Didn't match subexpression; checking sub-bracked predicate %03x\n", cmajor); + ret = scanParseChildren(parseT, saidChild); - switch (cmajor) { - case WORD_TYPE_BASE: - if (!base_words_nr) - return 1; - break; + if (type == SCAN_SAID_AND && ret != 1) + break; - case WORD_TYPE_REF: - if (!ref_words_nr) - return 1; - break; + if (type == SCAN_SAID_OR && ret == 1) + break; - default: - warning("augment_match_expression_p(): (subp1) Unkonwn sub-bracket predicate %03x", cmajor); } - break; + saidT = saidT->right; - default: - warning("augment_match_expression_p(): Unknown predicate %03x", major); + } + scidprintf("%*sscanSaid returning %d\n", outputDepth, "", ret); + outputDepth--; + return ret; +} + + +static int scanParseChildren(ParseTreeNode* parseT, ParseTreeNode* saidT) { + + outputDepth++; + scidprintf("%*sscanParse on ", outputDepth, ""); + node_print_desc(parseT); + scidprintf(" and "); + node_print_desc(saidT); + scidprintf("\n"); + + if (node_major(saidT) == 0x14B) { + dontclaim = true; + scidprintf("%*sscanParse returning 1 (0x14B)\n", outputDepth, ""); + outputDepth--; + return 1; } - scidprintf("augment_match_expression_p(): Generic failure\n"); + bool inParen = node_minor(saidT) == 0x14F || node_minor(saidT) == 0x150; + bool inBracket = node_major(saidT) == 0x152; - return 0; -} + int ret; -static int augment_sentence_expression(parse_tree_node_t *saidt, int augment_pos, parse_tree_node_t *parset, - int parse_branch, int major, int minor, int *base_words, int base_words_nr, - int *ref_words, int ref_words_nr) { - int check_major, check_minor; - int check_pos = aug_get_first_child(saidt, augment_pos, &check_major, &check_minor); - do { - if (!(augment_match_expression_p(saidt, check_pos, parset, parse_branch, check_major, check_minor, - base_words, base_words_nr, ref_words, ref_words_nr))) - return 0; - } while ((check_pos = aug_get_next_sibling(saidt, check_pos, &check_major, &check_minor))); + // descend further down saidT before actually scanning parseT + if ((node_major(saidT) == 0x141 || node_major(saidT) == 0x152) && + !node_is_terminal(saidT)) { - return 1; -} + ret = scanSaidChildren(parseT, saidT->right->right, + inParen ? SCAN_SAID_OR : SCAN_SAID_AND ); -static int augment_sentence_part(parse_tree_node_t *saidt, int augment_pos, parse_tree_node_t *parset, int parse_basepos, int major, int minor) { - int pmajor, pminor; - int parse_branch = parse_basepos; - int optional = 0; - int foundwords = 0; + } else if (parseT && parseT->left->type == kParseTreeBranchNode) { - scidprintf("Augmenting (%03x %03x\n", major, minor); + ret = 0; + int subresult = 0; - if (major == AUGMENT_SENTENCE_PART_BRACKETS) { // '[/ foo]' is true if '/foo' or if there - // exists no x for which '/x' is true - if ((augment_pos = aug_get_first_child(saidt, augment_pos, &major, &minor))) { - scidprintf("Optional part: Now augmenting (%03x %03x\n", major, minor); - optional = 1; - } else { - scidprintf("Matched empty optional expression\n"); - return 1; - } - } + while (parseT) { + assert(parseT->type == kParseTreeBranchNode); - if ((major < 0x141) || (major > 0x143)) { - scidprintf("augment_sentence_part(): Unexpected sentence part major number %03x\n", major); - return 0; - } + ParseTreeNode* parseChild = parseT->left; + assert(parseChild); - while ((parse_branch = aug_get_next_sibling(parset, parse_branch, &pmajor, &pminor))) { - if (pmajor == major) { // found matching sentence part - int success; - int base_words_nr; - int ref_words_nr; - int base_words[AUGMENT_MAX_WORDS]; - int ref_words[AUGMENT_MAX_WORDS]; -#ifdef SCI_DEBUG_PARSE_TREE_AUGMENTATION - int i; -#endif + scidprintf("%*sscanning next: ", outputDepth, ""); + node_print_desc(parseChild); + scidprintf("\n"); - scidprintf("Found match with pminor = %03x\n", pminor); - aug_find_words(parset, parse_branch, base_words, &base_words_nr, ref_words, &ref_words_nr, AUGMENT_MAX_WORDS); - foundwords |= (ref_words_nr | base_words_nr); -#ifdef SCI_DEBUG_PARSE_TREE_AUGMENTATION - printf("%d base words:", base_words_nr); - for (i = 0; i < base_words_nr; i++) - printf(" %03x", base_words[i]); - printf("\n%d reference words:", ref_words_nr); - for (i = 0; i < ref_words_nr; i++) - printf(" %03x", ref_words[i]); - printf("\n"); -#endif + if (node_major(parseChild) == node_major(saidT) || + node_major(parseChild) == 0x141) + subresult = matchTrees(parseChild, saidT); - success = augment_sentence_expression(saidt, augment_pos, parset, parse_basepos, major, minor, - base_words, base_words_nr, ref_words, ref_words_nr); + if (subresult != 0) + ret = subresult; + + if (ret == 1) + break; + + parseT = parseT->right; - if (success) { - scidprintf("SUCCESS on augmenting (%03x %03x\n", major, minor); - return 1; - } } + + // ret is now: + // 1 if ANY matchTrees(parseSibling, saidTree) returned 1 + // ELSE: -1 if ANY returned -1 + // ELSE: 0 + + } else { + + ret = matchTrees(parseT, saidT); + } - if (optional && (foundwords == 0)) { - scidprintf("Found no words and optional branch => SUCCESS on augmenting (%03x %03x\n", major, minor); - return 1; + if (inBracket && ret == 0) { + scidprintf("%*sscanParse changing ret to 1 due to brackets\n", + outputDepth, ""); + ret = 1; } - scidprintf("FAILURE on augmenting (%03x %03x\n", major, minor); - return 0; + scidprintf("%*sscanParse returning %d\n", outputDepth, "", ret); + outputDepth--; + + return ret; } -static int augment_parse_nodes(parse_tree_node_t *parset, parse_tree_node_t *saidt) { - int augment_basepos = 0; - int parse_basepos; - int major, minor; - int dontclaim = 0; - parse_basepos = aug_get_base_node(parset); - if (!parse_basepos) { - warning("augment_parse_nodes(): Parse tree is corrupt"); - return 0; - } - augment_basepos = aug_get_base_node(saidt); - if (!augment_basepos) { - warning("augment_parse_nodes(): Said tree is corrupt"); - return 0; - } +static int augment_parse_nodes(ParseTreeNode *parseT, ParseTreeNode *saidT) { + outputDepth = 0; + scidprintf("augment_parse_nodes on "); + node_print_desc(parseT); + scidprintf(" and "); + node_print_desc(saidT); + scidprintf("\n"); - while ((augment_basepos = aug_get_next_sibling(saidt, augment_basepos, &major, &minor))) { - if ((major == 0x14b) && (minor == SAID_LONG(SAID_GT))) - dontclaim = 1; // special case - else // normal sentence part - if (!(augment_sentence_part(saidt, augment_basepos, parset, parse_basepos, major, minor))) { - scidprintf("Returning failure\n"); - return 0; // fail - } - } + dontclaim = false; + + int ret = matchTrees(parseT, saidT); + + scidprintf("matchTrees returned %d\n", ret); - scidprintf("Returning success with dontclaim=%d\n", dontclaim); + if (ret != 1) + return 0; if (dontclaim) return SAID_PARTIAL_MATCH; - else - return 1; // full match + + return 1; } @@ -2441,22 +996,19 @@ static int augment_parse_nodes(parse_tree_node_t *parset, parse_tree_node_t *sai /**** Main code ****/ /*******************/ -int said(EngineState *s, byte *spec, bool verbose) { +int said(EngineState *s, const byte *spec, bool verbose) { int retval; Vocabulary *voc = g_sci->getVocabulary(); - parse_tree_node_t *parse_tree_ptr = voc->_parserNodes; + ParseTreeNode *parse_tree_ptr = voc->_parserNodes; if (voc->parserIsValid) { - if (said_parse_spec(spec)) { - printf("Offending spec was: "); - voc->decipherSaidBlock(spec); + if (said_parse_spec(spec)) return SAID_NO_MATCH; - } if (verbose) - vocab_dump_parse_tree("Said-tree", said_tree); // Nothing better to do yet - retval = augment_parse_nodes(parse_tree_ptr, &(said_tree[0])); + vocab_dump_parse_tree("Said-tree", said_tree); + retval = augment_parse_nodes(parse_tree_ptr, said_tree); if (!retval) return SAID_NO_MATCH; @@ -2470,15 +1022,108 @@ int said(EngineState *s, byte *spec, bool verbose) { } -#ifdef SAID_DEBUG_PROGRAM -int main (int argc, char *argv) { - byte block[] = {0x01, 0x00, 0xf8, 0xf5, 0x02, 0x01, 0xf6, 0xf2, 0x02, 0x01, 0xf2, 0x01, 0x03, 0xff}; - EngineState s; +/* + +Some test expressions for in the ScummVM debugging console, using +Codename: ICEMAN's vocabulary: + + + +said green board & [!*] / 8af < 1f6 +True + +said get green board & [!*] / 8af < 1f6 +False + +said green board & [!*] / 8af [< 1f6 ] +True + +said climb up & 19b , 426 [< 142 ] [/ 81e ] +True + +said climb up ladder & 19b , 426 [< 142 ] [/ 81e ] +True + +said climb down & 19b , 426 [< 142 ] [/ 81e ] +False + +said climb up tree & 19b , 426 [< 142 ] [/ 81e ] +False + +said climb up & 19b , 446 , 426 [< 143 ] [/ 81e ] +False + +said climb down & 19b , 446 , 426 [< 143 ] [/ 81e ] +True + +said use green device & 1a5 / 8c1 [< 21d ] +False + +said use electronic device & 1a5 / 8c1 [< 21d ] +True + +said use device & 1a5 / 8c1 [< 21d ] +True + +said eat & 429 [/ !* ] +True + +said eat ladder & 429 [/ !* ] +False + +said look at the ladder & 3f8 / 81e [< !* ] +True + +said look at the green ladder & 3f8 / 81e [< !* ] +False + +said look green book & / 7f6 [< 8d2 ] +False + +said look green book & 3f8 [< ca ] +True + +said get a blue board for the green ladder & 3f9 / 8af [ < 1f6 ] / 81e < 1f6 +False + +said get a board for the green ladder & 3f9 / 8af [ < 1f6 ] / 81e < 1f6 +True + +said get a blue board & 3f9 / 8af [ < 1f6 ] +False + +said get up & ( 3f8 , 3f9 ) [ < ( 142 , 143 ) ] +True + +said get left & ( 3f8 , 3f9 ) [ < ( 142 , 143 ) ] +False + +said look down & ( 3f8 , 3f9 ) [ < ( 142 , 143 ) ] +True + +said get & ( 3f8 , 3f9 ) [ < ( 142 , 143 ) ] +True + +said put washer on shaft & 455 , ( 3fa < cb ) / 8c6 +True + +said depth correct & [!*] < 8b1 / 22 +True + +said depth acknowledged & / 46d , 460 , 44d < 8b1 +True + +said depth confirmed & / 46d , 460 , 44d < 8b1 +True + +said depth attained & / 46d , 460 , 44d < 8b1 +True + + +*/ + + - s.parser_valid = 1; - said(&s, block); -} -#endif } // End of namespace Sci diff --git a/engines/sci/parser/said.y b/engines/sci/parser/said.y deleted file mode 100644 index cbb2ff3e62..0000000000 --- a/engines/sci/parser/said.y +++ /dev/null @@ -1,839 +0,0 @@ -%{ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/engine/state.h" - - -// Bison generates an empty switch statement that gives a warning in MSVC. -// This disables that warning. -#ifdef _MSC_VER -#pragma warning(disable:4065) -#endif - - -namespace Sci { - -#define SAID_BRANCH_NULL 0 - -#define MAX_SAID_TOKENS 128 - -// Maximum number of words to be expected in a parsed sentence -#define AUGMENT_MAX_WORDS 64 - - -#define ANYWORD 0xfff - -#define WORD_TYPE_BASE 0x141 -#define WORD_TYPE_REF 0x144 -#define WORD_TYPE_SYNTACTIC_SUGAR 0x145 - -#define AUGMENT_SENTENCE_PART_BRACKETS 0x152 - -// Minor numbers -#define AUGMENT_SENTENCE_MINOR_MATCH_PHRASE 0x14c -#define AUGMENT_SENTENCE_MINOR_MATCH_WORD 0x153 -#define AUGMENT_SENTENCE_MINOR_RECURSE 0x144 -#define AUGMENT_SENTENCE_MINOR_PARENTHESES 0x14f - - -#undef YYDEBUG /*1*/ -//#define SAID_DEBUG*/ -//#define SCI_DEBUG_PARSE_TREE_AUGMENTATION // uncomment to debug parse tree augmentation - - -#ifdef SCI_DEBUG_PARSE_TREE_AUGMENTATION -#define scidprintf printf -#else -void print_nothing(...) { } -#define scidprintf print_nothing -#endif - - -static char *said_parse_error; - -static int said_token; -static int said_tokens_nr; -static int said_tokens[MAX_SAID_TOKENS]; -static int said_blessed; // increminated by said_top_branch - -static int said_tree_pos; // Set to 0 if we're out of space -#define SAID_TREE_START 4; // Reserve space for the 4 top nodes - -#define VALUE_IGNORE -424242 - -static parse_tree_node_t said_tree[VOCAB_TREE_NODES]; - -typedef int wgroup_t; -typedef int tree_t; -typedef int said_spec_t; - -static tree_t said_aug_branch(int, int, tree_t, tree_t); -static tree_t said_attach_branch(tree_t, tree_t); -/* -static tree_t said_wgroup_branch(wgroup_t); -*/ -static said_spec_t said_top_branch(tree_t); -static tree_t said_paren(tree_t, tree_t); -static tree_t said_value(int, tree_t); -static tree_t said_terminal(int); - -static int yylex(); - -static int yyerror(const char *s) { - said_parse_error = strdup(s); - return 1; /* Abort */ -} - -%} - -%token WGROUP /* Word group */ -%token YY_COMMA /* 0xf0 */ -%token YY_AMP /* 0xf1 */ -%token YY_SLASH /* 0xf2 */ -%token YY_PARENO /* 0xf3 */ -%token YY_PARENC /* 0xf4 */ -%token YY_BRACKETSO /* 0xf5 */ -%token YY_BRACKETSC /* 0xf6 */ -%token YY_HASH /* 0xf7 */ -%token YY_LT /* 0xf8 */ -%token YY_GT /* 0xf9 */ -%token YY_BRACKETSO_LT /* special token used to imitate LR(2) behaviour */ -%token YY_BRACKETSO_SLASH /* special token used to imitate LR(2) behaviour */ -%token YY_LT_BRACKETSO /* special token used to imitate LR(2) behaviour */ -%token YY_LT_PARENO /* special token used to imitate LR(2) behaviour */ - -%% - -saidspec : leftspec optcont - { $$ = said_top_branch(said_attach_branch($1, $2)); } - | leftspec midspec optcont - { $$ = said_top_branch(said_attach_branch($1, said_attach_branch($2, $3))); } - | leftspec midspec rightspec optcont - { $$ = said_top_branch(said_attach_branch($1, said_attach_branch($2, said_attach_branch($3, $4)))); } - ; - - -optcont : /* empty */ - { $$ = SAID_BRANCH_NULL; } - | YY_GT - { $$ = said_paren(said_value(0x14b, said_value(0xf900, said_terminal(0xf900))), SAID_BRANCH_NULL); } - ; - - - -leftspec : /* empty */ - { $$ = SAID_BRANCH_NULL; } - | expr - { $$ = said_paren(said_value(0x141, said_value(0x149, $1)), SAID_BRANCH_NULL); } - ; - - - -midspec : YY_SLASH expr - { $$ = said_aug_branch(0x142, 0x14a, $2, SAID_BRANCH_NULL); } - | YY_BRACKETSO_SLASH YY_SLASH expr YY_BRACKETSC - { $$ = said_aug_branch(0x152, 0x142, said_aug_branch(0x142, 0x14a, $3, SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - | YY_SLASH - { $$ = SAID_BRANCH_NULL; } - ; - - - -rightspec : YY_SLASH expr - { $$ = said_aug_branch(0x143, 0x14a, $2, SAID_BRANCH_NULL); } - | YY_BRACKETSO_SLASH YY_SLASH expr YY_BRACKETSC - { $$ = said_aug_branch(0x152, 0x143, said_aug_branch(0x143, 0x14a, $3, SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - | YY_SLASH - { $$ = SAID_BRANCH_NULL; } - ; - - -word : WGROUP - { $$ = said_paren(said_value(0x141, said_value(0x153, said_terminal($1))), SAID_BRANCH_NULL); } - ; - - -cwordset : wordset - { $$ = said_aug_branch(0x141, 0x14f, $1, SAID_BRANCH_NULL); } - | YY_BRACKETSO wordset YY_BRACKETSC - { $$ = said_aug_branch(0x141, 0x14f, said_aug_branch(0x152, 0x14c, said_aug_branch(0x141, 0x14f, $2, SAID_BRANCH_NULL), SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - ; - - -wordset : word - { $$ = $1; } - | YY_PARENO expr YY_PARENC - { $$ = said_aug_branch(0x141, 0x14c, $2, SAID_BRANCH_NULL); } - | wordset YY_COMMA wordset - { $$ = said_attach_branch($1, $3); } - | wordset YY_BRACKETSO_LT wordrefset YY_BRACKETSC - { $$ = said_attach_branch($1, $3); } - | wordset YY_COMMA YY_BRACKETSO wordset YY_BRACKETSC - { $$ = said_attach_branch($1, $3); } - ; - - -expr : cwordset cwordrefset - { $$ = said_attach_branch($1, $2); } - | cwordset - { $$ = $1; } - | cwordrefset - { $$ = $1; } - ; - - -cwordrefset : wordrefset - { $$ = $1; } - | YY_BRACKETSO_LT wordrefset YY_BRACKETSC - { $$ = said_aug_branch(0x152, 0x144, $2, SAID_BRANCH_NULL); } - | wordrefset YY_BRACKETSO_LT wordrefset YY_BRACKETSC - { $$ = said_attach_branch($1, said_aug_branch(0x152, 0x144, $3, SAID_BRANCH_NULL)); } - ; - - -wordrefset : YY_LT word recref - { $$ = said_aug_branch(0x144, 0x14f, $2, $3); } - | YY_LT_PARENO YY_PARENO expr YY_PARENC - { $$ = said_aug_branch(0x144, 0x14f, said_aug_branch(0x141, 0x144, $2, SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - | YY_LT wordset - { $$ = said_aug_branch(0x144, 0x14f, $2, SAID_BRANCH_NULL); } - | YY_LT_BRACKETSO YY_BRACKETSO wordset YY_BRACKETSC - { $$ = said_aug_branch(0x152, 0x144, said_aug_branch(0x144, 0x14f, $3, SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - ; - - -recref : YY_LT wordset recref - { $$ = said_aug_branch(0x141, 0x144, said_aug_branch(0x144, 0x14f, $2, SAID_BRANCH_NULL), $3); } - | YY_LT wordset - { $$ = said_aug_branch(0x141, 0x144, said_aug_branch(0x144, 0x14f, $2, SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - | YY_LT_PARENO YY_PARENO expr YY_PARENC - { $$ = said_aug_branch(0x141, 0x14c, $2, SAID_BRANCH_NULL); } - ; - -%% - -int parse_yy_token_lookup[] = {YY_COMMA, YY_AMP, YY_SLASH, YY_PARENO, YY_PARENC, YY_BRACKETSO, YY_BRACKETSC, YY_HASH, YY_LT, YY_GT}; - -static int yylex() { - int retval = said_tokens[said_token++]; - - if (retval < SAID_LONG(SAID_FIRST)) { - yylval = retval; - retval = WGROUP; - } else { - retval >>= 8; - - if (retval == SAID_TERM) - retval = 0; - else { - assert(retval >= SAID_FIRST); - retval = parse_yy_token_lookup[retval - SAID_FIRST]; - if (retval == YY_BRACKETSO) { - if ((said_tokens[said_token] >> 8) == SAID_LT) - retval = YY_BRACKETSO_LT; - else - if ((said_tokens[said_token] >> 8) == SAID_SLASH) - retval = YY_BRACKETSO_SLASH; - } else if (retval == YY_LT && (said_tokens[said_token] >> 8) == SAID_BRACKO) { - retval = YY_LT_BRACKETSO; - } else if (retval == YY_LT && (said_tokens[said_token] >> 8) == SAID_PARENO) { - retval = YY_LT_PARENO; - } - } - } - - return retval; -} - -static int said_next_node() { - return ((said_tree_pos == 0) || (said_tree_pos >= VOCAB_TREE_NODES)) ? said_tree_pos = 0 : said_tree_pos++; -} - -#define SAID_NEXT_NODE said_next_node() - -static int said_leaf_node(tree_t pos, int value) { - said_tree[pos].type = kParseTreeLeafNode; - - if (value != VALUE_IGNORE) - said_tree[pos].content.value = value; - - return pos; -} - -static int said_branch_node(tree_t pos, int left, int right) { - said_tree[pos].type = kParseTreeBranchNode; - - if (left != VALUE_IGNORE) - said_tree[pos].content.branches[0] = left; - - if (right != VALUE_IGNORE) - said_tree[pos].content.branches[1] = right; - - return pos; -} - -static tree_t said_paren(tree_t t1, tree_t t2) { - if (t1) - return said_branch_node(SAID_NEXT_NODE, t1, t2); - else - return t2; -} - -static tree_t said_value(int val, tree_t t) { - return said_branch_node(SAID_NEXT_NODE, said_leaf_node(SAID_NEXT_NODE, val), t); - -} - -static tree_t said_terminal(int val) { - return said_leaf_node(SAID_NEXT_NODE, val); -} - -static tree_t said_aug_branch(int n1, int n2, tree_t t1, tree_t t2) { - int retval; - - retval = said_branch_node(SAID_NEXT_NODE, - said_branch_node(SAID_NEXT_NODE, - said_leaf_node(SAID_NEXT_NODE, n1), - said_branch_node(SAID_NEXT_NODE, - said_leaf_node(SAID_NEXT_NODE, n2), - t1) - ), - t2); - -#ifdef SAID_DEBUG - fprintf(stderr, "AUG(0x%x, 0x%x, [%04x], [%04x]) = [%04x]\n", n1, n2, t1, t2, retval); -#endif - - return retval; -} - -static tree_t said_attach_branch(tree_t base, tree_t attacheant) { -#ifdef SAID_DEBUG - fprintf(stderr, "ATT2([%04x], [%04x]) = [%04x]\n", base, attacheant, base); -#endif - - if (!attacheant) - return base; - if (!base) - return attacheant; - - if (!base) - return 0; // Happens if we're out of space - - said_branch_node(base, VALUE_IGNORE, attacheant); - - return base; -} - -static said_spec_t said_top_branch(tree_t first) { -#ifdef SAID_DEBUG - fprintf(stderr, "TOP([%04x])\n", first); -#endif - said_branch_node(0, 1, 2); - said_leaf_node(1, 0x141); // Magic number #1 - said_branch_node(2, 3, first); - said_leaf_node(3, 0x13f); // Magic number #2 - - ++said_blessed; - - return 0; -} - -static int said_parse_spec(byte *spec) { - int nextitem; - - said_parse_error = NULL; - said_token = 0; - said_tokens_nr = 0; - said_blessed = 0; - - said_tree_pos = SAID_TREE_START; - - do { - nextitem = *spec++; - if (nextitem < SAID_FIRST) - said_tokens[said_tokens_nr++] = nextitem << 8 | *spec++; - else - said_tokens[said_tokens_nr++] = SAID_LONG(nextitem); - - } while ((nextitem != SAID_TERM) && (said_tokens_nr < MAX_SAID_TOKENS)); - - if (nextitem == SAID_TERM) - yyparse(); - else { - warning("SAID spec is too long"); - return 1; - } - - if (said_parse_error) { - warning("Error while parsing SAID spec: %s", said_parse_error); - free(said_parse_error); - return 1; - } - - if (said_tree_pos == 0) { - warning("Out of tree space while parsing SAID spec"); - return 1; - } - - if (said_blessed != 1) { - warning("Found multiple top branches"); - return 1; - } - - return 0; -} - -/**********************/ -/**** Augmentation ****/ -/**********************/ - -// primitive functions - -#define AUG_READ_BRANCH(a, br, p) \ - if (tree[p].type != kParseTreeBranchNode) \ - return 0; \ - a = tree[p].content.branches[br]; - -#define AUG_READ_VALUE(a, p) \ - if (tree[p].type != kParseTreeLeafNode) \ - return 0; \ - a = tree[p].content.value; - -#define AUG_ASSERT(i) \ - if (!i) return 0; - -static int aug_get_next_sibling(parse_tree_node_t *tree, int pos, int *first, int *second) { - // Returns the next sibling relative to the specified position in 'tree', - // sets *first and *second to its augment node values, returns the new position - // or 0 if there was no next sibling - int seek, valpos; - - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(seek, 0, pos); - AUG_ASSERT(seek); - - // Now retrieve first value - AUG_READ_BRANCH(valpos, 0, seek); - AUG_ASSERT(valpos); - AUG_READ_VALUE(*first, valpos); - - // Get second value - AUG_READ_BRANCH(seek, 1, seek); - AUG_ASSERT(seek); - AUG_READ_BRANCH(valpos, 0, seek); - AUG_ASSERT(valpos); - AUG_READ_VALUE(*second, valpos); - - return pos; -} - -static int aug_get_wgroup(parse_tree_node_t *tree, int pos) { - // Returns 0 if pos in tree is not the root of a 3-element list, otherwise - // it returns the last element (which, in practice, is the word group - int val; - - AUG_READ_BRANCH(pos, 0, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); - AUG_READ_VALUE(val, pos); - - return val; -} - -static int aug_get_base_node(parse_tree_node_t *tree) { - int startpos = 0; - AUG_READ_BRANCH(startpos, 1, startpos); - - return startpos; -} - -// semi-primitive functions - -static int aug_get_first_child(parse_tree_node_t *tree, int pos, int *first, int *second) { - // like aug_get_next_sibling, except that it recurses into the tree and - // finds the first child (usually *not* Ayanami Rei) of the current branch - // rather than its next sibling. - AUG_READ_BRANCH(pos, 0, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); - - return aug_get_next_sibling(tree, pos, first, second); -} - -static void aug_find_words_recursively(parse_tree_node_t *tree, int startpos, int *base_words, int *base_words_nr, - int *ref_words, int *ref_words_nr, int maxwords, int refbranch) { - // Finds and lists all base (141) and reference (144) words */ - int major, minor; - int word; - int pos = aug_get_first_child(tree, startpos, &major, &minor); - - //if (major == WORD_TYPE_REF) - // refbranch = 1; - - while (pos) { - if ((word = aug_get_wgroup(tree, pos))) { // found a word - if (!refbranch && major == WORD_TYPE_BASE) { - if ((*base_words_nr) == maxwords) { - warning("Out of regular words"); - return; // return gracefully - } - - base_words[*base_words_nr] = word; // register word - ++(*base_words_nr); - - } - if (major == WORD_TYPE_REF || refbranch) { - if ((*ref_words_nr) == maxwords) { - warning("Out of reference words"); - return; // return gracefully - } - - ref_words[*ref_words_nr] = word; // register word - ++(*ref_words_nr); - - } - if (major != WORD_TYPE_SYNTACTIC_SUGAR && major != WORD_TYPE_BASE && major != WORD_TYPE_REF) - warning("aug_find_words_recursively(): Unknown word type %03x", major); - - } else // Did NOT find a word group: Attempt to recurse - aug_find_words_recursively(tree, pos, base_words, base_words_nr, - ref_words, ref_words_nr, maxwords, refbranch || major == WORD_TYPE_REF); - - pos = aug_get_next_sibling(tree, pos, &major, &minor); - } -} - - -static void aug_find_words(parse_tree_node_t *tree, int startpos, int *base_words, int *base_words_nr, - int *ref_words, int *ref_words_nr, int maxwords) { - // initializing wrapper for aug_find_words_recursively() - *base_words_nr = 0; - *ref_words_nr = 0; - - aug_find_words_recursively(tree, startpos, base_words, base_words_nr, ref_words, ref_words_nr, maxwords, 0); -} - - -static int aug_contains_word(int *list, int length, int word) { - int i; - - if (word == ANYWORD) - return (length); - - for (i = 0; i < length; i++) - if (list[i] == word) - return 1; - - return 0; -} - - -static int augment_sentence_expression(parse_tree_node_t *saidt, int augment_pos, parse_tree_node_t *parset, - int parse_branch, int major, int minor, int *base_words, int base_words_nr, - int *ref_words, int ref_words_nr); - -static int augment_match_expression_p(parse_tree_node_t *saidt, int augment_pos, parse_tree_node_t *parset, - int parse_basepos, int major, int minor, - int *base_words, int base_words_nr, int *ref_words, int ref_words_nr) { - int cmajor, cminor, cpos; - cpos = aug_get_first_child(saidt, augment_pos, &cmajor, &cminor); - if (!cpos) { - warning("augment_match_expression_p(): Empty condition"); - return 1; - } - - scidprintf("Attempting to match (%03x %03x (%03x %03x\n", major, minor, cmajor, cminor); - - if ((major == WORD_TYPE_BASE) && (minor == AUGMENT_SENTENCE_MINOR_RECURSE)) - return augment_match_expression_p(saidt, cpos, parset, parse_basepos, cmajor, cminor, - base_words, base_words_nr, ref_words, ref_words_nr); - - switch (major) { - - case WORD_TYPE_BASE: - while (cpos) { - if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_WORD) { - int word = aug_get_wgroup(saidt, cpos); - scidprintf("Looking for word %03x\n", word); - - if (aug_contains_word(base_words, base_words_nr, word)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_PHRASE) { - if (augment_sentence_expression(saidt, cpos, parset, parse_basepos, cmajor, cminor, - base_words, base_words_nr, ref_words, ref_words_nr)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_PARENTHESES) { - int gc_major, gc_minor; - int gchild = aug_get_first_child(saidt, cpos, &gc_major, &gc_minor); - - while (gchild) { - if (augment_match_expression_p(saidt, cpos, parset, parse_basepos, major, - minor, base_words, base_words_nr, - ref_words, ref_words_nr)) - return 1; - gchild = aug_get_next_sibling(saidt, gchild, &gc_major, &gc_minor); - } - } else - warning("augment_match_expression_p(): Unknown type 141 minor number %3x", cminor); - - cpos = aug_get_next_sibling(saidt, cpos, &cmajor, &cminor); - - } - break; - - case WORD_TYPE_REF: - while (cpos) { - if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_WORD) { - int word = aug_get_wgroup(saidt, cpos); - scidprintf("Looking for refword %03x\n", word); - - if (aug_contains_word(ref_words, ref_words_nr, word)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_PHRASE) { - if (augment_match_expression_p(saidt, cpos, parset, parse_basepos, cmajor, cminor, - base_words, base_words_nr, ref_words, ref_words_nr)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_PARENTHESES) { - int gc_major, gc_minor; - int gchild = aug_get_first_child(saidt, cpos, &gc_major, &gc_minor); - - while (gchild) { - if (augment_match_expression_p(saidt, cpos, parset, parse_basepos, major, - minor, base_words, base_words_nr, - ref_words, ref_words_nr)) - return 1; - gchild = aug_get_next_sibling(saidt, gchild, &gc_major, &gc_minor); - } - } else - warning("augment_match_expression_p(): Unknown type 144 minor number %3x", cminor); - - cpos = aug_get_next_sibling(saidt, cpos, &cmajor, &cminor); - - } - break; - - case AUGMENT_SENTENCE_PART_BRACKETS: - if (augment_match_expression_p(saidt, cpos, parset, parse_basepos, cmajor, cminor, - base_words, base_words_nr, ref_words, ref_words_nr)) - return 1; - - scidprintf("Didn't match subexpression; checking sub-bracked predicate %03x\n", cmajor); - - switch (cmajor) { - case WORD_TYPE_BASE: - if (!base_words_nr) - return 1; - break; - - case WORD_TYPE_REF: - if (!ref_words_nr) - return 1; - break; - - default: - warning("augment_match_expression_p(): (subp1) Unkonwn sub-bracket predicate %03x", cmajor); - } - - break; - - default: - warning("augment_match_expression_p(): Unknown predicate %03x", major); - - } - - scidprintf("augment_match_expression_p(): Generic failure\n"); - - return 0; -} - -static int augment_sentence_expression(parse_tree_node_t *saidt, int augment_pos, parse_tree_node_t *parset, - int parse_branch, int major, int minor, int *base_words, int base_words_nr, - int *ref_words, int ref_words_nr) { - int check_major, check_minor; - int check_pos = aug_get_first_child(saidt, augment_pos, &check_major, &check_minor); - do { - if (!(augment_match_expression_p(saidt, check_pos, parset, parse_branch, check_major, check_minor, - base_words, base_words_nr, ref_words, ref_words_nr))) - return 0; - } while ((check_pos = aug_get_next_sibling(saidt, check_pos, &check_major, &check_minor))); - - return 1; -} - -static int augment_sentence_part(parse_tree_node_t *saidt, int augment_pos, parse_tree_node_t *parset, int parse_basepos, int major, int minor) { - int pmajor, pminor; - int parse_branch = parse_basepos; - int optional = 0; - int foundwords = 0; - - scidprintf("Augmenting (%03x %03x\n", major, minor); - - if (major == AUGMENT_SENTENCE_PART_BRACKETS) { // '[/ foo]' is true if '/foo' or if there - // exists no x for which '/x' is true - if ((augment_pos = aug_get_first_child(saidt, augment_pos, &major, &minor))) { - scidprintf("Optional part: Now augmenting (%03x %03x\n", major, minor); - optional = 1; - } else { - scidprintf("Matched empty optional expression\n"); - return 1; - } - } - - if ((major < 0x141) || (major > 0x143)) { - scidprintf("augment_sentence_part(): Unexpected sentence part major number %03x\n", major); - return 0; - } - - while ((parse_branch = aug_get_next_sibling(parset, parse_branch, &pmajor, &pminor))) { - if (pmajor == major) { // found matching sentence part - int success; - int base_words_nr; - int ref_words_nr; - int base_words[AUGMENT_MAX_WORDS]; - int ref_words[AUGMENT_MAX_WORDS]; -#ifdef SCI_DEBUG_PARSE_TREE_AUGMENTATION - int i; -#endif - - scidprintf("Found match with pminor = %03x\n", pminor); - aug_find_words(parset, parse_branch, base_words, &base_words_nr, ref_words, &ref_words_nr, AUGMENT_MAX_WORDS); - foundwords |= (ref_words_nr | base_words_nr); -#ifdef SCI_DEBUG_PARSE_TREE_AUGMENTATION - printf("%d base words:", base_words_nr); - for (i = 0; i < base_words_nr; i++) - printf(" %03x", base_words[i]); - printf("\n%d reference words:", ref_words_nr); - for (i = 0; i < ref_words_nr; i++) - printf(" %03x", ref_words[i]); - printf("\n"); -#endif - - success = augment_sentence_expression(saidt, augment_pos, parset, parse_basepos, major, minor, - base_words, base_words_nr, ref_words, ref_words_nr); - - if (success) { - scidprintf("SUCCESS on augmenting (%03x %03x\n", major, minor); - return 1; - } - } - } - - if (optional && (foundwords == 0)) { - scidprintf("Found no words and optional branch => SUCCESS on augmenting (%03x %03x\n", major, minor); - return 1; - } - scidprintf("FAILURE on augmenting (%03x %03x\n", major, minor); - - return 0; -} - -static int augment_parse_nodes(parse_tree_node_t *parset, parse_tree_node_t *saidt) { - int augment_basepos = 0; - int parse_basepos; - int major, minor; - int dontclaim = 0; - - parse_basepos = aug_get_base_node(parset); - if (!parse_basepos) { - warning("augment_parse_nodes(): Parse tree is corrupt"); - return 0; - } - - augment_basepos = aug_get_base_node(saidt); - if (!augment_basepos) { - warning("augment_parse_nodes(): Said tree is corrupt"); - return 0; - } - - while ((augment_basepos = aug_get_next_sibling(saidt, augment_basepos, &major, &minor))) { - if ((major == 0x14b) && (minor == SAID_LONG(SAID_GT))) - dontclaim = 1; // special case - else // normal sentence part - if (!(augment_sentence_part(saidt, augment_basepos, parset, parse_basepos, major, minor))) { - scidprintf("Returning failure\n"); - return 0; // fail - } - } - - scidprintf("Returning success with dontclaim=%d\n", dontclaim); - - if (dontclaim) - return SAID_PARTIAL_MATCH; - else - return 1; // full match -} - - -/*******************/ -/**** Main code ****/ -/*******************/ - -int said(EngineState *s, byte *spec, bool verbose) { - int retval; - Vocabulary *voc = g_sci->getVocabulary(); - - parse_tree_node_t *parse_tree_ptr = voc->_parserNodes; - - if (voc->parserIsValid) { - if (said_parse_spec(spec)) { - printf("Offending spec was: "); - voc->decipherSaidBlock(spec); - return SAID_NO_MATCH; - } - - if (verbose) - vocab_dump_parse_tree("Said-tree", said_tree); // Nothing better to do yet - retval = augment_parse_nodes(parse_tree_ptr, &(said_tree[0])); - - if (!retval) - return SAID_NO_MATCH; - else if (retval != SAID_PARTIAL_MATCH) - return SAID_FULL_MATCH; - else - return SAID_PARTIAL_MATCH; - } - - return SAID_NO_MATCH; -} - - -#ifdef SAID_DEBUG_PROGRAM -int main (int argc, char *argv) { - byte block[] = {0x01, 0x00, 0xf8, 0xf5, 0x02, 0x01, 0xf6, 0xf2, 0x02, 0x01, 0xf2, 0x01, 0x03, 0xff}; - EngineState s; - - s.parser_valid = 1; - said(&s, block); -} -#endif - -} // End of namespace Sci diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp index e48a9cdfda..20436d5b30 100644 --- a/engines/sci/parser/vocabulary.cpp +++ b/engines/sci/parser/vocabulary.cpp @@ -33,18 +33,34 @@ namespace Sci { -Vocabulary::Vocabulary(ResourceManager *resMan) : _resMan(resMan) { +Vocabulary::Vocabulary(ResourceManager *resMan, bool foreign) : _resMan(resMan), _foreign(foreign) { _parserRules = NULL; - _vocabVersion = kVocabularySCI0; memset(_parserNodes, 0, sizeof(_parserNodes)); // Mark parse tree as unused _parserNodes[0].type = kParseTreeLeafNode; - _parserNodes[0].content.value = 0; + _parserNodes[0].value = 0; _synonyms.clear(); // No synonyms debug(2, "Initializing vocabulary"); + if (_resMan->testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB))) { + _vocabVersion = kVocabularySCI0; + _resourceIdWords = VOCAB_RESOURCE_SCI0_MAIN_VOCAB; + _resourceIdSuffixes = VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB; + _resourceIdBranches = VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES; + } else { + _vocabVersion = kVocabularySCI1; + _resourceIdWords = VOCAB_RESOURCE_SCI1_MAIN_VOCAB; + _resourceIdSuffixes = VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB; + _resourceIdBranches = VOCAB_RESOURCE_SCI1_PARSE_TREE_BRANCHES; + } + + if (_foreign) { + _resourceIdWords += 10; + _resourceIdSuffixes += 10; + _resourceIdBranches += 10; + } if (getSciVersion() <= SCI_VERSION_1_EGA && loadParserWords()) { loadSuffixes(); @@ -66,27 +82,46 @@ Vocabulary::~Vocabulary() { freeSuffixes(); } -bool Vocabulary::loadParserWords() { +void Vocabulary::reset() { + parserIsValid = false; // Invalidate parser + parser_event = NULL_REG; // Invalidate parser event + parser_base = make_reg(g_sci->getEngineState()->_segMan->getSysStringsSegment(), SYS_STRING_PARSER_BASE); +} - char currentword[256] = ""; // They're not going to use words longer than 255 ;-) - int currentwordpos = 0; +bool Vocabulary::loadParserWords() { + char currentWord[VOCAB_MAX_WORDLENGTH] = ""; + int currentWordPos = 0; // First try to load the SCI0 vocab resource. - Resource *resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB), 0); + Resource *resource = _resMan->findResource(ResourceId(kResourceTypeVocab, _resourceIdWords), 0); if (!resource) { - warning("SCI0: Could not find a main vocabulary, trying SCI01"); - resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB), 0); - _vocabVersion = kVocabularySCI1; + warning("Could not find a main vocabulary"); + return false; // NOT critical: SCI1 games and some demos don't have one! } - if (!resource) { - warning("SCI1: Could not find a main vocabulary"); - return false; // NOT critical: SCI1 games and some demos don't have one! + VocabularyVersions resourceType = _vocabVersion; + + if (resourceType == kVocabularySCI0) { + if (resource->size < 26 * 2) { + warning("Invalid main vocabulary encountered: Much too small"); + return false; + } + // Check the alphabet-offset table for any content + int alphabetNr; + for (alphabetNr = 0; alphabetNr < 26; alphabetNr++) { + if (READ_LE_UINT16(resource->data + alphabetNr * 2)) + break; + } + // If all of them were empty, we are definitely seeing SCI01 vocab in disguise (e.g. pq2 japanese) + if (alphabetNr == 26) { + warning("SCI0: Found SCI01 vocabulary in disguise"); + resourceType = kVocabularySCI1; + } } unsigned int seeker; - if (_vocabVersion == kVocabularySCI1) + if (resourceType == kVocabularySCI1) seeker = 255 * 2; // vocab.900 starts with 255 16-bit pointers which we don't use else seeker = 26 * 2; // vocab.000 starts with 26 16-bit pointers which we don't use @@ -102,13 +137,13 @@ bool Vocabulary::loadParserWords() { while (seeker < resource->size) { byte c; - currentwordpos = resource->data[seeker++]; // Parts of previous words may be re-used + currentWordPos = resource->data[seeker++]; // Parts of previous words may be re-used - if (_vocabVersion == kVocabularySCI1) { + if (resourceType == kVocabularySCI1) { c = 1; - while (seeker < resource->size && currentwordpos < 255 && c) { + while (seeker < resource->size && currentWordPos < 255 && c) { c = resource->data[seeker++]; - currentword[currentwordpos++] = c; + currentWord[currentWordPos++] = c; } if (seeker == resource->size) { warning("SCI1: Vocabulary not usable, disabling"); @@ -118,11 +153,11 @@ bool Vocabulary::loadParserWords() { } else { do { c = resource->data[seeker++]; - currentword[currentwordpos++] = c & 0x7f; // 0x80 is used to terminate the string + currentWord[currentWordPos++] = c & 0x7f; // 0x80 is used to terminate the string } while (c < 0x80); } - currentword[currentwordpos] = 0; + currentWord[currentWordPos] = 0; // Now decode class and group: c = resource->data[seeker + 1]; @@ -131,7 +166,7 @@ bool Vocabulary::loadParserWords() { newWord._group = (resource->data[seeker + 2]) | ((c & 0x0f) << 8); // Add the word to the list - _parserWords[currentword] = newWord; + _parserWords[currentWord] = newWord; seeker += 3; } @@ -142,23 +177,20 @@ bool Vocabulary::loadParserWords() { const char *Vocabulary::getAnyWordFromGroup(int group) { if (group == VOCAB_MAGIC_NUMBER_GROUP) return "{number}"; + if (group == VOCAB_MAGIC_NOTHING_GROUP) + return "{nothing}"; - for (WordMap::const_iterator i = _parserWords.begin(); i != _parserWords.end(); ++i) + for (WordMap::const_iterator i = _parserWords.begin(); i != _parserWords.end(); ++i) { if (i->_value._group == group) return i->_key.c_str(); + } return "{invalid}"; } bool Vocabulary::loadSuffixes() { // Determine if we can find a SCI1 suffix vocabulary first - Resource* resource = NULL; - - if (_vocabVersion == kVocabularySCI0) - resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB), 1); - else - resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB), 1); - + Resource* resource = _resMan->findResource(ResourceId(kResourceTypeVocab, _resourceIdSuffixes), 1); if (!resource) return false; // No vocabulary found @@ -171,7 +203,7 @@ bool Vocabulary::loadSuffixes() { suffix.alt_suffix_length = strlen(suffix.alt_suffix); seeker += suffix.alt_suffix_length + 1; // Hit end of string - suffix.class_mask = (int16)READ_BE_UINT16(resource->data + seeker); + suffix.result_class = (int16)READ_BE_UINT16(resource->data + seeker); seeker += 2; // Beginning of next string - skip leading '*' @@ -181,7 +213,7 @@ bool Vocabulary::loadSuffixes() { suffix.word_suffix_length = strlen(suffix.word_suffix); seeker += suffix.word_suffix_length + 1; - suffix.result_class = (int16)READ_BE_UINT16(resource->data + seeker); + suffix.class_mask = (int16)READ_BE_UINT16(resource->data + seeker); seeker += 3; // Next entry _parserSuffixes.push_back(suffix); @@ -191,13 +223,7 @@ bool Vocabulary::loadSuffixes() { } void Vocabulary::freeSuffixes() { - Resource* resource = NULL; - - if (_vocabVersion == kVocabularySCI0) - resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB), 0); - else - resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB), 0); - + Resource* resource = _resMan->findResource(ResourceId(kResourceTypeVocab, _resourceIdSuffixes), 0); if (resource) _resMan->unlockResource(resource); @@ -205,12 +231,7 @@ void Vocabulary::freeSuffixes() { } bool Vocabulary::loadBranches() { - Resource *resource = NULL; - - if (_vocabVersion == kVocabularySCI0) - resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES), 0); - else - resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_PARSE_TREE_BRANCHES), 0); + Resource *resource = _resMan->findResource(ResourceId(kResourceTypeVocab, _resourceIdBranches), 0); _parserBranches.clear(); @@ -243,7 +264,7 @@ bool Vocabulary::loadBranches() { return true; } - +// we assume that *word points to an already lowercased word ResultWord Vocabulary::lookupWord(const char *word, int word_len) { Common::String tempword(word, word_len); @@ -270,7 +291,7 @@ ResultWord Vocabulary::lookupWord(const char *word, int word_len) { int suff_index = word_len - suffix->alt_suffix_length; // Offset of the start of the suffix - if (scumm_strnicmp(suffix->alt_suffix, word + suff_index, suffix->alt_suffix_length) == 0) { // Suffix matched! + if (strncmp(suffix->alt_suffix, word + suff_index, suffix->alt_suffix_length) == 0) { // Suffix matched! // Terminate word at suffix start position...: Common::String tempword2(word, MIN(word_len, suff_index)); @@ -300,82 +321,109 @@ ResultWord Vocabulary::lookupWord(const char *word, int word_len) { return retval; } -void Vocabulary::decipherSaidBlock(byte *addr) { - byte nextitem; +void Vocabulary::debugDecipherSaidBlock(const byte *addr) { + bool first = true; + uint16 nextItem; do { - nextitem = *addr++; - - if (nextitem < 0xf0) { - nextitem = nextitem << 8 | *addr++; - printf(" %s[%03x]", getAnyWordFromGroup(nextitem), nextitem); - - nextitem = 42; // Make sure that group 0xff doesn't abort - } else switch (nextitem) { - case 0xf0: - printf(" ,"); - break; - case 0xf1: - printf(" &"); - break; - case 0xf2: - printf(" /"); - break; - case 0xf3: - printf(" ("); - break; - case 0xf4: - printf(" )"); - break; - case 0xf5: - printf(" ["); - break; - case 0xf6: - printf(" ]"); - break; - case 0xf7: - printf(" #"); - break; - case 0xf8: - printf(" <"); - break; - case 0xf9: - printf(" >"); - break; - case 0xff: - break; + nextItem = *addr++; + if (nextItem != 0xff) { + if ((!first) && (nextItem != 0xf0)) + printf(" "); + first = false; + + if (nextItem < 0xf0) { + nextItem = nextItem << 8 | *addr++; + printf("%s{%03x}", getAnyWordFromGroup(nextItem), nextItem); + + nextItem = 0; // Make sure that group 0xff doesn't abort + } else switch (nextItem) { + case 0xf0: + printf(","); + break; + case 0xf1: + printf("&"); + break; + case 0xf2: + printf("/"); + break; + case 0xf3: + printf("("); + break; + case 0xf4: + printf(")"); + break; + case 0xf5: + printf("["); + break; + case 0xf6: + printf("]"); + break; + case 0xf7: + printf("#"); + break; + case 0xf8: + printf("<"); + break; + case 0xf9: + printf(">"); + break; + case 0xff: + break; } - } while (nextitem != 0xff); - - printf("\n"); + } + } while (nextItem != 0xff); } +static const byte lowerCaseMap[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // 0x00 + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, // 0x10 + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, // 0x20 + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // 0x30 + 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', // 0x40 + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, // 0x50 + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, // 0x60 + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, // 0x70 + 0x87, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x84, 0x86, // 0x80 + //^^ ^^^^ ^^^^ + 0x82, 0x91, 0x91, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x94, 0x81, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, // 0x90 + //^^ ^^^^ ^^^^ ^^^^ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, // 0xa0 + // ^^^^ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, // 0xb0 + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, // 0xc0 + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, // 0xd0 + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, // 0xe0 + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff // 0xf0 +}; + bool Vocabulary::tokenizeString(ResultWordList &retval, const char *sentence, char **error) { - const char *lastword = sentence; + char currentWord[VOCAB_MAX_WORDLENGTH] = ""; int pos_in_sentence = 0; - char c; - int wordlen = 0; + unsigned char c; + int wordLen = 0; *error = NULL; do { c = sentence[pos_in_sentence++]; - - if (isalnum(c) || (c == '-' && wordlen)) - ++wordlen; + if (isalnum(c) || (c == '-' && wordLen) || (c >= 0x80)) { + currentWord[wordLen] = lowerCaseMap[c]; + ++wordLen; + } // Continue on this word */ // Words may contain a '-', but may not // start with one. else { - if (wordlen) { // Finished a word? + if (wordLen) { // Finished a word? - ResultWord lookup_result = lookupWord(lastword, wordlen); + ResultWord lookup_result = lookupWord(currentWord, wordLen); // Look it up if (lookup_result._class == -1) { // Not found? - *error = (char *)calloc(wordlen + 1, 1); - strncpy(*error, lastword, wordlen); // Set the offending word + *error = (char *)calloc(wordLen + 1, 1); + strncpy(*error, currentWord, wordLen); // Set the offending word retval.clear(); return false; // And return with error } @@ -384,8 +432,7 @@ bool Vocabulary::tokenizeString(ResultWordList &retval, const char *sentence, ch retval.push_back(lookup_result); } - lastword = sentence + pos_in_sentence; - wordlen = 0; + wordLen = 0; } } while (c); // Until terminator is hit @@ -394,7 +441,7 @@ bool Vocabulary::tokenizeString(ResultWordList &retval, const char *sentence, ch } void Vocabulary::printSuffixes() const { - char word_buf[256], alt_buf[256]; + char word_buf[VOCAB_MAX_WORDLENGTH], alt_buf[VOCAB_MAX_WORDLENGTH]; Console *con = g_sci->getSciDebugger(); int i = 0; @@ -423,30 +470,25 @@ void Vocabulary::printParserWords() const { con->DebugPrintf("\n"); } -void _vocab_recursive_ptree_dump_treelike(parse_tree_node_t *nodes, int nr, int prevnr) { - if ((nr > VOCAB_TREE_NODES)/* || (nr < prevnr)*/) { - printf("Error(%04x)", nr); - return; - } +void _vocab_recursive_ptree_dump_treelike(ParseTreeNode *tree) { + assert(tree); - if (nodes[nr].type == kParseTreeLeafNode) - //printf("[%03x]%04x", nr, nodes[nr].content.value); - printf("%x", nodes[nr].content.value); + if (tree->type == kParseTreeLeafNode) + printf("%x", tree->value); else { - int lbranch = nodes[nr].content.branches[0]; - int rbranch = nodes[nr].content.branches[1]; - //printf("<[%03x]", nr); + ParseTreeNode* lbranch = tree->left; + ParseTreeNode* rbranch = tree->right; printf("<"); if (lbranch) - _vocab_recursive_ptree_dump_treelike(nodes, lbranch, nr); + _vocab_recursive_ptree_dump_treelike(lbranch); else printf("NULL"); printf(","); if (rbranch) - _vocab_recursive_ptree_dump_treelike(nodes, rbranch, nr); + _vocab_recursive_ptree_dump_treelike(rbranch); else printf("NULL"); @@ -454,55 +496,52 @@ void _vocab_recursive_ptree_dump_treelike(parse_tree_node_t *nodes, int nr, int } } -void _vocab_recursive_ptree_dump(parse_tree_node_t *nodes, int nr, int prevnr, int blanks) { - int lbranch = nodes[nr].content.branches[0]; - int rbranch = nodes[nr].content.branches[1]; - int i; +void _vocab_recursive_ptree_dump(ParseTreeNode *tree, int blanks) { + assert(tree); - if (nodes[nr].type == kParseTreeLeafNode) { - printf("vocab_dump_parse_tree: Error: consp is nil for element %03x\n", nr); - return; - } + ParseTreeNode* lbranch = tree->left; + ParseTreeNode* rbranch = tree->right; + int i; - if ((nr > VOCAB_TREE_NODES)/* || (nr < prevnr)*/) { - printf("Error(%04x))", nr); + if (tree->type == kParseTreeLeafNode) { + printf("vocab_dump_parse_tree: Error: consp is nil\n"); return; } if (lbranch) { - if (nodes[lbranch].type == kParseTreeBranchNode) { + if (lbranch->type == kParseTreeBranchNode) { printf("\n"); for (i = 0; i < blanks; i++) printf(" "); printf("("); - _vocab_recursive_ptree_dump(nodes, lbranch, nr, blanks + 1); + _vocab_recursive_ptree_dump(lbranch, blanks + 1); printf(")\n"); for (i = 0; i < blanks; i++) printf(" "); } else - printf("%x", nodes[lbranch].content.value); + printf("%x", lbranch->value); printf(" "); }/* else printf ("nil");*/ if (rbranch) { - if (nodes[rbranch].type == kParseTreeBranchNode) - _vocab_recursive_ptree_dump(nodes, rbranch, nr, blanks); + if (rbranch->type == kParseTreeBranchNode) + _vocab_recursive_ptree_dump(rbranch, blanks); else - printf("%x", nodes[rbranch].content.value); + printf("%x", rbranch->value); }/* else printf("nil");*/ } -void vocab_dump_parse_tree(const char *tree_name, parse_tree_node_t *nodes) { +void vocab_dump_parse_tree(const char *tree_name, ParseTreeNode *nodes) { //_vocab_recursive_ptree_dump_treelike(nodes, 0, 0); printf("(setq %s \n'(", tree_name); - _vocab_recursive_ptree_dump(nodes, 0, 0, 1); + _vocab_recursive_ptree_dump(nodes, 1); printf("))\n"); } void Vocabulary::dumpParseTree() { //_vocab_recursive_ptree_dump_treelike(nodes, 0, 0); printf("(setq parse-tree \n'("); - _vocab_recursive_ptree_dump(_parserNodes, 0, 0, 1); + _vocab_recursive_ptree_dump(_parserNodes, 1); printf("))\n"); } @@ -522,10 +561,10 @@ void Vocabulary::printParserNodes(int num) { for (int i = 0; i < num; i++) { con->DebugPrintf(" Node %03x: ", i); if (_parserNodes[i].type == kParseTreeLeafNode) - con->DebugPrintf("Leaf: %04x\n", _parserNodes[i].content.value); + con->DebugPrintf("Leaf: %04x\n", _parserNodes[i].value); else - con->DebugPrintf("Branch: ->%04x, ->%04x\n", _parserNodes[i].content.branches[0], - _parserNodes[i].content.branches[1]); + con->DebugPrintf("Branch: ->%04x, ->%04x\n", _parserNodes[i].left, + _parserNodes[i].right); } } @@ -538,7 +577,7 @@ int Vocabulary::parseNodes(int *i, int *pos, int type, int nr, int argc, const c if (type == kParseNumber) { _parserNodes[*pos += 1].type = kParseTreeLeafNode; - _parserNodes[*pos].content.value = nr; + _parserNodes[*pos].value = nr; return *pos; } if (type == kParseEndOfInput) { @@ -570,7 +609,15 @@ int Vocabulary::parseNodes(int *i, int *pos, int type, int nr, int argc, const c } } - if ((newPos = _parserNodes[oldPos].content.branches[j] = parseNodes(i, pos, nextToken, nextValue, argc, argv)) == -1) + newPos = parseNodes(i, pos, nextToken, nextValue, argc, argv); + + if (j == 0) + _parserNodes[oldPos].left = &_parserNodes[newPos]; + else + _parserNodes[oldPos].right = &_parserNodes[newPos]; + + + if (newPos == -1) return -1; } diff --git a/engines/sci/parser/vocabulary.h b/engines/sci/parser/vocabulary.h index dccef0f5f3..d4df8af715 100644 --- a/engines/sci/parser/vocabulary.h +++ b/engines/sci/parser/vocabulary.h @@ -73,13 +73,16 @@ enum { kParseNumber = 4 }; +#define VOCAB_MAX_WORDLENGTH 256 + /* Anywords are ignored by the parser */ #define VOCAB_CLASS_ANYWORD 0xff /* This word class is used for numbers */ #define VOCAB_MAGIC_NUMBER_GROUP 0xffd /* 0xffe ? */ +#define VOCAB_MAGIC_NOTHING_GROUP 0xffe -/* Number of nodes for each parse_tree_node structure */ +/* Number of nodes for each ParseTreeNode structure */ #define VOCAB_TREE_NODES 500 #define VOCAB_TREE_NODE_LAST_WORD_STORAGE 0x140 @@ -115,7 +118,7 @@ struct ResultWord { typedef Common::List<ResultWord> ResultWordList; -typedef Common::HashMap<Common::String, ResultWord, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> WordMap; +typedef Common::HashMap<Common::String, ResultWord, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> WordMap; struct ParseRuleList; @@ -149,16 +152,16 @@ struct parse_tree_branch_t { }; enum ParseTypes { - kParseTreeLeafNode = 0, - kParseTreeBranchNode = 1 + kParseTreeWordNode = 4, + kParseTreeLeafNode = 5, + kParseTreeBranchNode = 6 }; -struct parse_tree_node_t { +struct ParseTreeNode { ParseTypes type; /**< leaf or branch */ - union { - int value; /**< For leaves */ - short branches[2]; /**< For branches */ - } content; + int value; /**< For leaves */ + ParseTreeNode* left; /**< Left child, for branches */ + ParseTreeNode* right; /**< Right child, for branches */ }; enum VocabularyVersions { @@ -168,9 +171,12 @@ enum VocabularyVersions { class Vocabulary { public: - Vocabulary(ResourceManager *resMan); + Vocabulary(ResourceManager *resMan, bool foreign); ~Vocabulary(); + // reset parser status + void reset(); + /** * Gets any word from the specified group. For debugging only. * @param group Group number @@ -229,7 +235,7 @@ public: * For debugging only. * @param pos pointer to the data to dump */ - void decipherSaidBlock(byte *pos); + void debugDecipherSaidBlock(const byte *pos); /** * Prints the parser suffixes to the debug console. @@ -301,6 +307,11 @@ private: ResourceManager *_resMan; VocabularyVersions _vocabVersion; + bool _foreign; + uint16 _resourceIdWords; + uint16 _resourceIdSuffixes; + uint16 _resourceIdBranches; + // Parser-related lists SuffixList _parserSuffixes; ParseRuleList *_parserRules; /**< GNF rules used in the parser algorithm */ @@ -310,7 +321,7 @@ private: public: // Accessed by said() - parse_tree_node_t _parserNodes[VOCAB_TREE_NODES]; /**< The parse tree */ + ParseTreeNode _parserNodes[VOCAB_TREE_NODES]; /**< The parse tree */ // Parser data: reg_t parser_base; /**< Base address for the parser error reporting mechanism */ @@ -323,7 +334,7 @@ public: * @param tree_name Name of the tree to dump (free-form) * @param nodes The nodes containing the parse tree */ -void vocab_dump_parse_tree(const char *tree_name, parse_tree_node_t *nodes); +void vocab_dump_parse_tree(const char *tree_name, ParseTreeNode *nodes); @@ -334,7 +345,7 @@ void vocab_dump_parse_tree(const char *tree_name, parse_tree_node_t *nodes); * @param verbose Whether to display the parse tree after building it * @return 1 on a match, 0 otherwise */ -int said(EngineState *s, byte *spec, bool verbose); +int said(EngineState *s, const byte *spec, bool verbose); } // End of namespace Sci diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 2958ca1e3b..111bf6ad9b 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -108,30 +108,79 @@ static const char *sci_error_types[] = { "SCI version is unsupported" }; -// These are the 20 resource types supported by SCI1.1 -static const char *resourceTypeNames[] = { +static const char *s_resourceTypeNames[] = { "view", "pic", "script", "text", "sound", "memory", "vocab", "font", "cursor", "patch", "bitmap", "palette", "cdaudio", "audio", "sync", "message", "map", "heap", - "audio36", "sync36", "", "", "robot", "vmd" + "audio36", "sync36", "xlate", "robot", "vmd", + "chunk", "macibin", "macibis", "macpict" }; -static const char *resourceTypeSuffixes[] = { +static const char *s_resourceTypeSuffixes[] = { "v56", "p56", "scr", "tex", "snd", - " ", "voc", "fon", "cur", "pat", + "", "voc", "fon", "cur", "pat", "bit", "pal", "cda", "aud", "syn", - "msg", "map", "hep", "aud", "syn", - "trn", " ", "rbt", "vmd" -}; + "msg", "map", "hep", "", "", + "trn", "rbt", "vmd", "chk", "", + "", "" +}; const char *getResourceTypeName(ResourceType restype) { if (restype != kResourceTypeInvalid) - return resourceTypeNames[restype]; + return s_resourceTypeNames[restype]; else return "invalid"; } +static const ResourceType s_resTypeMapSci0[] = { + kResourceTypeView, kResourceTypePic, kResourceTypeScript, kResourceTypeText, // 0x00-0x03 + kResourceTypeSound, kResourceTypeMemory, kResourceTypeVocab, kResourceTypeFont, // 0x04-0x07 + kResourceTypeCursor, kResourceTypePatch, kResourceTypeBitmap, kResourceTypePalette, // 0x08-0x0B + kResourceTypeCdAudio, kResourceTypeAudio, kResourceTypeSync, kResourceTypeMessage, // 0x0C-0x0F + kResourceTypeMap, kResourceTypeHeap, kResourceTypeAudio36, kResourceTypeSync36, // 0x10-0x13 + kResourceTypeTranslation // 0x14 +}; + +#ifdef ENABLE_SCI32 +// TODO: 12 should be "Wave", but SCI seems to just store it in Audio resources +static const ResourceType s_resTypeMapSci21[] = { + kResourceTypeView, kResourceTypePic, kResourceTypeScript, kResourceTypeText, // 0x00-0x03 + kResourceTypeSound, kResourceTypeMemory, kResourceTypeVocab, kResourceTypeFont, // 0x04-0x07 + kResourceTypeCursor, kResourceTypePatch, kResourceTypeBitmap, kResourceTypePalette, // 0x08-0x0B + kResourceTypeInvalid, kResourceTypeAudio, kResourceTypeSync, kResourceTypeMessage, // 0x0C-0x0F + kResourceTypeMap, kResourceTypeHeap, kResourceTypeChunk, kResourceTypeAudio36, // 0x10-0x13 + kResourceTypeSync36, kResourceTypeTranslation, kResourceTypeRobot, kResourceTypeVMD // 0x14-0x17 +}; +#endif + +ResourceType ResourceManager::convertResType(byte type) { + type &= 0x7f; + + if (_mapVersion != kResVersionSci32) { + // SCI0 - SCI2 + if (type < ARRAYSIZE(s_resTypeMapSci0)) + return s_resTypeMapSci0[type]; + } else { + // SCI2.1+ +#ifdef ENABLE_SCI32 + if (type < ARRAYSIZE(s_resTypeMapSci21)) { + // LSL6 hires doesn't have the chunk resource type, to match + // the resource types of the lowres version, thus we use the + // older resource types here + if (g_sci && g_sci->getGameId() == GID_LSL6HIRES) + return s_resTypeMapSci0[type]; + else + return s_resTypeMapSci21[type]; + } +#else + error("SCI32 support not compiled in"); +#endif + } + + return kResourceTypeInvalid; +} + //-- Resource main functions -- Resource::Resource(ResourceId id) : _id(id) { data = NULL; @@ -337,7 +386,7 @@ void MacResourceForkResourceSource::loadResource(ResourceManager *resMan, Resour Common::SeekableReadStream *stream = _macResMan->getResource(resTypeToMacTag(res->getType()), res->getNumber()); if (!stream) - error("Could not get Mac resource fork resource: %d %d", res->getType(), res->getNumber()); + error("Could not get Mac resource fork resource: %s %d", getResourceTypeName(res->getType()), res->getNumber()); int error = res->decompress(resMan->getVolVersion(), stream); if (error) { @@ -527,9 +576,13 @@ int ResourceManager::addAppropriateSources() { #endif addPatchDir("."); + if (Common::File::exists("message.map")) addSource(new VolumeResourceSource("resource.msg", addExternalMap("message.map"), 0)); + if (Common::File::exists("altres.map")) + addSource(new VolumeResourceSource("altres.000", addExternalMap("altres.map"), 0)); + return 1; } @@ -1093,7 +1146,7 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType resource return; } - byte patchType = fileStream->readByte() & 0x7F; + byte patchType = convertResType(fileStream->readByte()); byte patchDataOffset = fileStream->readByte(); delete fileStream; @@ -1231,7 +1284,11 @@ void ResourceManager::readResourcePatches() { const char *szResType; ResourceSource *psrcPatch; - for (int i = kResourceTypeView; i <= kResourceTypeHeap; ++i) { + for (int i = kResourceTypeView; i < kResourceTypeInvalid; ++i) { + // Ignore the types that can't be patched (and Robot/VMD is handled externally for now) + if (!s_resourceTypeSuffixes[i] || i == kResourceTypeRobot || i == kResourceTypeVMD) + continue; + files.clear(); szResType = getResourceTypeName((ResourceType)i); // SCI0 naming - type.nnn @@ -1240,7 +1297,7 @@ void ResourceManager::readResourcePatches() { SearchMan.listMatchingMembers(files, mask); // SCI1 and later naming - nnn.typ mask = "*."; - mask += resourceTypeSuffixes[i]; + mask += s_resourceTypeSuffixes[i]; SearchMan.listMatchingMembers(files, mask); for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) { @@ -1304,7 +1361,7 @@ int ResourceManager::readResourceMapSCI0(ResourceSource *map) { if (offset == 0xFFFFFFFF) break; - type = (ResourceType)(id >> 11); + type = convertResType(id >> 11); number = id & 0x7FF; ResourceId resId = ResourceId(type, number); // adding a new resource @@ -1389,14 +1446,20 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) { warning("Error while reading %s", map->getLocationName().c_str()); return SCI_ERROR_RESMAP_NOT_FOUND; } - resId = ResourceId((ResourceType)type, number); + resId = ResourceId(convertResType(type), number); // adding new resource only if it does not exist if (_resMap.contains(resId) == false) { // NOTE: We add the map's volume number here to the specified volume number // for SCI2.1 and SCI3 maps that are not resmap.000. The resmap.* files' numbers // need to be used in concurrence with the volume specified in the map to get // the actual resource file. - addResource(resId, findVolume(map, volume_nr + map->_volumeNumber), off); + int mapVolumeNr = volume_nr + map->_volumeNumber; + ResourceSource *source = findVolume(map, mapVolumeNr); + // FIXME: this code has serious issues with multiple RESMAP.* files (like in unmodified gk2) + // adding a resource with source == NULL would crash later on + if (!source) + error("Unable to find volume for map %s volumeNr %d", map->getLocationName().c_str(), mapVolumeNr); + addResource(resId, source, off); } } } @@ -1875,14 +1938,18 @@ void ResourceManager::detectSciVersion() { return; } - // New decompressors. It's either SCI_VERSION_1_EGA or SCI_VERSION_1_EARLY. - if (hasSci1Voc900()) { - s_sciVersion = SCI_VERSION_1_EGA; - return; + // New decompressors. It's either SCI_VERSION_0_LATE, SCI_VERSION_1_EGA or SCI_VERSION_1_EARLY. + if (testResource(ResourceId(kResourceTypeVocab, 900))) { + if (hasSci1Voc900()) { + s_sciVersion = SCI_VERSION_1_EGA; + return; + } else { + s_sciVersion = SCI_VERSION_0_LATE; + return; + } } - // SCI_VERSION_1_EARLY EGA versions seem to be lacking a valid vocab.900. - // If this turns out to be unreliable, we could do some pic resource checks instead. + // SCI_VERSION_1_EARLY EGA versions lack the parser vocab s_sciVersion = SCI_VERSION_1_EARLY; return; case kResVersionSci1Middle: diff --git a/engines/sci/resource.h b/engines/sci/resource.h index f66b5b3956..f1ea2f15f9 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -95,22 +95,21 @@ enum ResourceType { kResourceTypeHeap, kResourceTypeAudio36, kResourceTypeSync36, - kResourceTypeUnknown1, // Translation, currently unsupported - kResourceTypeUnknown2, + kResourceTypeTranslation, // Currently unsupported kResourceTypeRobot, kResourceTypeVMD, - kResourceTypeInvalid, + kResourceTypeChunk, - // Mac-only resources, these resource types are self-defined - // Numbers subject to change - kResourceTypeMacIconBarPictN = -1, // IBIN resources (icon bar, not selected) - kResourceTypeMacIconBarPictS = -2, // IBIS resources (icon bar, selected) - kResourceTypeMacPict = -3 // PICT resources (inventory) + // Mac-only resources + kResourceTypeMacIconBarPictN, // IBIN resources (icon bar, not selected) + kResourceTypeMacIconBarPictS, // IBIS resources (icon bar, selected) + kResourceTypeMacPict, // PICT resources (inventory) + + kResourceTypeInvalid }; const char *getResourceTypeName(ResourceType restype); - enum ResVersion { kResVersionUnknown, kResVersionSci0Sci1Early, @@ -126,7 +125,7 @@ class ResourceSource; class ResourceId { static inline ResourceType fixupType(ResourceType type) { - if (type < kResourceTypeMacPict || type > kResourceTypeInvalid) + if (type >= kResourceTypeInvalid) return kResourceTypeInvalid; return type; } @@ -150,11 +149,11 @@ public: Common::String toString() const { char buf[32]; - snprintf(buf, 32, "%s.%i", getResourceTypeName(_type), _number); + snprintf(buf, 32, "%s.%d", getResourceTypeName(_type), _number); Common::String retStr = buf; if (_tuple != 0) { - snprintf(buf, 32, "(%i, %i, %i, %i)", _tuple >> 24, (_tuple >> 16) & 0xff, (_tuple >> 8) & 0xff, _tuple & 0xff); + snprintf(buf, 32, "(%d, %d, %d, %d)", _tuple >> 24, (_tuple >> 16) & 0xff, (_tuple >> 8) & 0xff, _tuple & 0xff); retStr += buf; } @@ -344,6 +343,13 @@ public: */ reg_t findGameObject(bool addSci11ScriptOffset = true); + /** + * Converts a map resource type to our type + * @param sciType The type from the map/patch + * @return The ResourceType + */ + ResourceType convertResType(byte type); + protected: // Maximum number of bytes to allow being allocated for resources // Note: maxMemory will not be interpreted as a hard limit, only as a restriction diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp index 13aa81cb24..08e05f5ccd 100644 --- a/engines/sci/resource_audio.cpp +++ b/engines/sci/resource_audio.cpp @@ -543,6 +543,7 @@ SoundResource::SoundResource(uint32 resourceNr, ResourceManager *resMan, SciVers case SCI_VERSION_1_EARLY: case SCI_VERSION_1_LATE: + case SCI_VERSION_2_1: data = resource->data; // Count # of tracks _trackCount = 0; diff --git a/engines/sci/resource_intern.h b/engines/sci/resource_intern.h index 45421dd722..73986444a4 100644 --- a/engines/sci/resource_intern.h +++ b/engines/sci/resource_intern.h @@ -73,7 +73,7 @@ public: */ virtual ResourceSource *findVolume(ResourceSource *map, int volNum) { return NULL; - }; + } /** * Scan this source for TODO. @@ -122,7 +122,7 @@ public: if (_associatedMap == map && _volumeNumber == volNum) return this; return NULL; - }; + } }; class ExtMapResourceSource : public ResourceSource { diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 1ebc6a2ba3..f07cc257bd 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -54,6 +54,7 @@ #include "sci/graphics/menu.h" #include "sci/graphics/paint16.h" #include "sci/graphics/paint32.h" +#include "sci/graphics/picture.h" #include "sci/graphics/ports.h" #include "sci/graphics/palette.h" #include "sci/graphics/screen.h" @@ -85,6 +86,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam _gamestate = 0; _kernel = 0; _vocabulary = 0; + _vocabularyLanguage = 1; // we load english vocabulary on startup _eventMan = 0; _console = 0; @@ -120,6 +122,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam SearchMan.addSubDirectoryMatching(gameDataDir, "avi"); // AVI movie files for Windows versions SearchMan.addSubDirectoryMatching(gameDataDir, "seq"); // SEQ movie files for DOS versions SearchMan.addSubDirectoryMatching(gameDataDir, "robot"); // robot movie files + SearchMan.addSubDirectoryMatching(gameDataDir, "robots"); // robot movie files SearchMan.addSubDirectoryMatching(gameDataDir, "movies"); // vmd movie files SearchMan.addSubDirectoryMatching(gameDataDir, "vmd"); // vmd movie files @@ -202,7 +205,7 @@ Common::Error SciEngine::run() { _kernel = new Kernel(_resMan, segMan); _features = new GameFeatures(segMan, _kernel); // Only SCI0 and SCI01 games used a parser - _vocabulary = (getSciVersion() <= SCI_VERSION_1_EGA) ? new Vocabulary(_resMan) : NULL; + _vocabulary = (getSciVersion() <= SCI_VERSION_1_EGA) ? new Vocabulary(_resMan, false) : NULL; _audio = new AudioPlayer(_resMan); _gamestate = new EngineState(segMan); _eventMan = new EventManager(_resMan->detectFontExtended()); @@ -275,10 +278,6 @@ bool SciEngine::initGame() { } _gamestate->initGlobals(); - - if (_gamestate->abortScriptProcessing == kAbortRestartGame && _gfxMenu) - _gfxMenu->reset(); - _gamestate->_segMan->initSysStrings(); _gamestate->r_acc = _gamestate->r_prev = NULL_REG; @@ -300,9 +299,7 @@ bool SciEngine::initGame() { // Reset parser if (_vocabulary) { - _vocabulary->parserIsValid = false; // Invalidate parser - _vocabulary->parser_event = NULL_REG; // Invalidate parser event - _vocabulary->parser_base = make_reg(_gamestate->_segMan->getSysStringsSegment(), SYS_STRING_PARSER_BASE); + _vocabulary->reset(); } _gamestate->gameStartTime = _gamestate->lastWaitTime = _gamestate->_screenUpdateTime = g_system->getMillis(); @@ -411,7 +408,7 @@ void SciEngine::runGame() { do { _gamestate->_executionStackPosChanged = false; - run_vm(_gamestate, (_gamestate->abortScriptProcessing == kAbortLoadGame)); + run_vm(_gamestate); exitGame(); if (_gamestate->abortScriptProcessing == kAbortRestartGame) { @@ -419,9 +416,15 @@ void SciEngine::runGame() { initGame(); initStackBaseWithSelector(SELECTOR(play)); _gamestate->gameWasRestarted = true; + if (_gfxMenu) + _gfxMenu->reset(); + _gamestate->abortScriptProcessing = kAbortNone; } else if (_gamestate->abortScriptProcessing == kAbortLoadGame) { _gamestate->abortScriptProcessing = kAbortNone; + _gamestate->_executionStack.clear(); initStackBaseWithSelector(SELECTOR(replay)); + _gamestate->shrinkStackToBase(); + _gamestate->abortScriptProcessing = kAbortNone; } else { break; // exit loop } @@ -497,8 +500,11 @@ Common::String SciEngine::getFilePrefix() const { // Quest for Glory 3 wants to read files from Quest for Glory 2 to import character data if (_gamestate->currentRoomNumber() == 54) return "qfg2"; + } else if (_gameId == GID_QFG4) { + // Quest for Glory 4 wants to read files from Quest for Glory 3 to import character data + if (_gamestate->currentRoomNumber() == 54) + return "qfg3"; } - // TODO: Implement the same for qfg4, when sci32 is good enough return _targetName; } diff --git a/engines/sci/sci.h b/engines/sci/sci.h index c15f87e4e2..13c9d03614 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -143,6 +143,7 @@ enum SciGameId { GID_LSL6HIRES, // We have a separate ID for LSL6 SCI32, because it's actually a completely different game GID_LSL7, GID_MOTHERGOOSE, + GID_MOTHERGOOSEHIRES, // We have a separate ID for Mother Goose SCI32, because it's actually a completely different game GID_MSASTROCHICKEN, GID_PEPPER, GID_PHANTASMAGORIA, @@ -153,6 +154,7 @@ enum SciGameId { GID_PQ4, GID_PQSWAT, GID_QFG1, + GID_QFG1VGA, GID_QFG2, GID_QFG3, GID_QFG4, @@ -266,6 +268,9 @@ public: Common::String getSciLanguageString(const char *str, kLanguage lang, kLanguage *lang2 = NULL) const; + // Check if vocabulary needs to get switched (in multilingual parser games) + void checkVocabularySwitch(); + // Initializes ports and paint16 for non-sci32 games, also sets default palette void initGraphics(); @@ -331,6 +336,7 @@ private: EngineState *_gamestate; Kernel *_kernel; Vocabulary *_vocabulary; + int16 _vocabularyLanguage; EventManager *_eventMan; reg_t _gameObj; /**< Pointer to the game object */ Console *_console; diff --git a/engines/sci/sound/audio.cpp b/engines/sci/sound/audio.cpp index d9e9d2e8db..640273c20e 100644 --- a/engines/sci/sound/audio.cpp +++ b/engines/sci/sound/audio.cpp @@ -35,6 +35,7 @@ #include "sound/audiostream.h" #include "sound/decoders/aiff.h" #include "sound/decoders/flac.h" +#include "sound/decoders/mac_snd.h" #include "sound/decoders/mp3.h" #include "sound/decoders/raw.h" #include "sound/decoders/vorbis.h" @@ -337,19 +338,9 @@ Audio::RewindableAudioStream *AudioPlayer::getAudioStream(uint32 number, uint32 } else if (audioRes->size > 14 && READ_BE_UINT16(audioRes->data) == 1 && READ_BE_UINT16(audioRes->data + 2) == 1 && READ_BE_UINT16(audioRes->data + 4) == 5 && READ_BE_UINT32(audioRes->data + 10) == 0x00018051) { // Mac snd detected - // See http://developer.apple.com/legacy/mac/library/documentation/mac/Sound/Sound-60.html#HEADING60-15 for more details + Common::MemoryReadStream *sndStream = new Common::MemoryReadStream(audioRes->data, audioRes->size, DisposeAfterUse::NO); - uint32 soundHeaderOffset = READ_BE_UINT32(audioRes->data + 16); - assert(READ_BE_UINT32(audioRes->data + soundHeaderOffset) == 0); - size = READ_BE_UINT32(audioRes->data + soundHeaderOffset + 4); - _audioRate = READ_BE_UINT16(audioRes->data + soundHeaderOffset + 8); // Really floating point, but we're just truncating - - if (*(audioRes->data + soundHeaderOffset + 20) != 0) - error("Unhandled Mac snd extended/compressed header"); - - data = (byte *)malloc(size); - memcpy(data, audioRes->data + soundHeaderOffset + 22, size); - flags = Audio::FLAG_UNSIGNED; + audioSeekStream = Audio::makeMacSndStream(sndStream, DisposeAfterUse::YES); } else { // SCI1 raw audio size = audioRes->size; diff --git a/engines/sci/sound/drivers/amiga.cpp b/engines/sci/sound/drivers/amigamac.cpp index 0413dbb79e..4fb9146b53 100644 --- a/engines/sci/sound/drivers/amiga.cpp +++ b/engines/sci/sound/drivers/amigamac.cpp @@ -25,6 +25,7 @@ #include "sound/softsynth/emumidi.h" #include "sci/sound/drivers/mididriver.h" +#include "sci/resource.h" #include "common/file.h" #include "common/frac.h" @@ -34,35 +35,14 @@ namespace Sci { /* #define DEBUG */ -// Frequencies for every note -// FIXME Store only one octave -static const int freq_table[] = { - 58, 62, 65, 69, 73, 78, 82, 87, - 92, 98, 104, 110, 117, 124, 131, 139, - 147, 156, 165, 175, 185, 196, 208, 220, - 234, 248, 262, 278, 294, 312, 331, 350, - 371, 393, 417, 441, 468, 496, 525, 556, - 589, 625, 662, 701, 743, 787, 834, 883, - 936, 992, 1051, 1113, 1179, 1250, 1324, 1403, - 1486, 1574, 1668, 1767, 1872, 1984, 2102, 2227, - 2359, 2500, 2648, 2806, 2973, 3149, 3337, 3535, - 3745, 3968, 4204, 4454, 4719, 5000, 5297, 5612, - 5946, 6299, 6674, 7071, 7491, 7937, 8408, 8908, - 9438, 10000, 10594, 11224, 11892, 12599, 13348, 14142, - 14983, 15874, 16817, 17817, 18877, 20000, 21189, 22449, - 23784, 25198, 26696, 28284, 29966, 31748, 33635, 35635, - 37754, 40000, 42378, 44898, 47568, 50396, 53393, 56568, - 59932, 63496, 67271, 71271, 75509, 80000, 84757, 89796 -}; - -class MidiDriver_Amiga : public MidiDriver_Emulated { +class MidiDriver_AmigaMac : public MidiDriver_Emulated { public: enum { kVoices = 4 }; - MidiDriver_Amiga(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer), _playSwitch(true), _masterVolume(15) { } - virtual ~MidiDriver_Amiga() { } + MidiDriver_AmigaMac(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer), _playSwitch(true), _masterVolume(15) { } + virtual ~MidiDriver_AmigaMac() { } // MidiDriver int open(); @@ -99,6 +79,7 @@ private: int instrument; int volume; int pan; + uint16 pitch; }; struct Envelope { @@ -121,7 +102,7 @@ private: frac_t rate; }; - struct Instrument { + struct InstrumentSample { char name[30]; int mode; int size; // Size of non-looping part in bytes @@ -130,35 +111,55 @@ private: Envelope envelope[4]; // Envelope int8 *samples; int8 *loop; + int16 startNote; + int16 endNote; + bool isUnsigned; + uint16 baseFreq; + uint16 baseNote; + int16 fixedNote; + }; + + class Instrument : public Common::Array<InstrumentSample *> { + public: + char name[30]; }; struct Bank { char name[30]; uint size; - Instrument *instruments[256]; + Common::Array<Instrument> instruments; }; + bool _isSci1; bool _playSwitch; int _masterVolume; int _frequency; Envelope _envDecay; Bank _bank; // Instrument bank + double _freqTable[48]; Channel _channels[MIDI_CHANNELS]; /* Internal channels */ Voice _voices[kChannels]; void setEnvelope(Voice *channel, Envelope *envelope, int phase); - int interpolate(int8 *samples, frac_t offset); + void setOutputFrac(int voice); + int interpolate(int8 *samples, frac_t offset, bool isUnsigned); void playInstrument(int16 *dest, Voice *channel, int count); void changeInstrument(int channel, int instrument); void stopChannel(int ch); void stopNote(int ch, int note); void startNote(int ch, int note, int velocity); - Instrument *readInstrument(Common::File &file, int *id); + InstrumentSample *findInstrument(int instrument, int note); + void pitchWheel(int ch, uint16 pitch); + + bool loadInstrumentsSCI0(Common::File &file); + bool loadInstrumentsSCI0Mac(Common::SeekableReadStream &file); + InstrumentSample *readInstrumentSCI0(Common::SeekableReadStream &file, int *id); + bool loadInstrumentsSCI1(Common::SeekableReadStream &file); }; -void MidiDriver_Amiga::setEnvelope(Voice *channel, Envelope *envelope, int phase) { +void MidiDriver_AmigaMac::setEnvelope(Voice *channel, Envelope *envelope, int phase) { channel->envelope = phase; channel->envelope_samples = envelope[phase].length; @@ -168,25 +169,32 @@ void MidiDriver_Amiga::setEnvelope(Voice *channel, Envelope *envelope, int phase channel->velocity = envelope[phase - 1].target; } -int MidiDriver_Amiga::interpolate(int8 *samples, frac_t offset) { +int MidiDriver_AmigaMac::interpolate(int8 *samples, frac_t offset, bool isUnsigned) { int x = fracToInt(offset); - int diff = (samples[x + 1] - samples[x]) << 8; + if (isUnsigned) { + int s1 = (byte)samples[x] - 0x80; + int s2 = (byte)samples[x + 1] - 0x80; + int diff = (s2 - s1) << 8; + return (s1 << 8) + fracToInt(diff * (offset & FRAC_LO_MASK)); + } + + int diff = (samples[x + 1] - samples[x]) << 8; return (samples[x] << 8) + fracToInt(diff * (offset & FRAC_LO_MASK)); } -void MidiDriver_Amiga::playInstrument(int16 *dest, Voice *channel, int count) { +void MidiDriver_AmigaMac::playInstrument(int16 *dest, Voice *channel, int count) { int index = 0; int vol = _channels[channel->hw_channel].volume; - Instrument *instrument = _bank.instruments[channel->instrument]; + InstrumentSample *instrument = findInstrument(channel->instrument, channel->note); while (1) { /* Available source samples until end of segment */ frac_t lin_avail; - int seg_end, rem, i, amount; + uint32 seg_end, rem, i, amount; int8 *samples; - if (channel->looping) { + if (channel->looping && instrument->loop) { samples = instrument->loop; seg_end = instrument->loop_size; } else { @@ -208,11 +216,11 @@ void MidiDriver_Amiga::playInstrument(int16 *dest, Voice *channel, int count) { amount = rem; /* Stop at next envelope event */ - if ((channel->envelope_samples != -1) && (amount > channel->envelope_samples)) + if ((channel->envelope_samples != -1) && (amount > (uint32)channel->envelope_samples)) amount = channel->envelope_samples; for (i = 0; i < amount; i++) { - dest[index++] = interpolate(samples, channel->offset) * channel->velocity / 64 * channel->note_velocity * vol / (127 * 127); + dest[index++] = interpolate(samples, channel->offset, instrument->isUnsigned) * channel->velocity / 64 * channel->note_velocity * vol / (127 * 127); channel->offset += channel->rate; } @@ -263,7 +271,7 @@ void MidiDriver_Amiga::playInstrument(int16 *dest, Voice *channel, int count) { if (index == count) break; - if (fracToInt(channel->offset) >= seg_end) { + if ((uint32)fracToInt(channel->offset) >= seg_end) { if (instrument->mode & kModeLoop) { /* Loop the samples */ channel->offset -= intToFrac(seg_end); @@ -277,9 +285,9 @@ void MidiDriver_Amiga::playInstrument(int16 *dest, Voice *channel, int count) { } } -void MidiDriver_Amiga::changeInstrument(int channel, int instrument) { +void MidiDriver_AmigaMac::changeInstrument(int channel, int instrument) { #ifdef DEBUG - if (_bank.instruments[instrument]) + if (_bank.instruments[instrument][0]) printf("[sfx:seq:amiga] Setting channel %i to \"%s\" (%i)\n", channel, _bank.instruments[instrument]->name, instrument); else warning("[sfx:seq:amiga] instrument %i does not exist (channel %i)", instrument, channel); @@ -287,7 +295,7 @@ void MidiDriver_Amiga::changeInstrument(int channel, int instrument) { _channels[channel].instrument = instrument; } -void MidiDriver_Amiga::stopChannel(int ch) { +void MidiDriver_AmigaMac::stopChannel(int ch) { int i; /* Start decay phase for note on this hw channel, if any */ @@ -300,9 +308,16 @@ void MidiDriver_Amiga::stopChannel(int ch) { } } -void MidiDriver_Amiga::stopNote(int ch, int note) { +void MidiDriver_AmigaMac::pitchWheel(int ch, uint16 pitch) { + _channels[ch].pitch = pitch; + + for (int i = 0; i < kChannels; i++) + if (_voices[i].note != -1 && _voices[i].hw_channel == ch) + setOutputFrac(i); +} + +void MidiDriver_AmigaMac::stopNote(int ch, int note) { int channel; - Instrument *instrument; for (channel = 0; channel < kChannels; channel++) if (_voices[channel].note == note && _voices[channel].hw_channel == ch && !_voices[channel].decay) @@ -315,15 +330,75 @@ void MidiDriver_Amiga::stopNote(int ch, int note) { return; } - instrument = _bank.instruments[_voices[channel].instrument]; + InstrumentSample *instrument = findInstrument(_voices[channel].instrument, note); + + // FIXME: SCI1 envelope support is not perfect yet /* Start the envelope phases for note-off if looping is on and envelope is enabled */ if ((instrument->mode & kModeLoop) && (instrument->envelope[0].length != 0)) setEnvelope(&_voices[channel], instrument->envelope, 2); } -void MidiDriver_Amiga::startNote(int ch, int note, int velocity) { - Instrument *instrument; +MidiDriver_AmigaMac::InstrumentSample *MidiDriver_AmigaMac::findInstrument(int instrument, int note) { + if ((uint)instrument >= _bank.instruments.size()) + return 0; + + for (uint32 i = 0; i < _bank.instruments[instrument].size(); i++) { + InstrumentSample *sample = _bank.instruments[instrument][i]; + if (note >= sample->startNote && note <= sample->endNote) + return sample; + } + + return 0; +} + +void MidiDriver_AmigaMac::setOutputFrac(int voice) { + InstrumentSample *instrument = findInstrument(_voices[voice].instrument, _voices[voice].note); + + int fnote = 0; + + if (instrument->fixedNote == -1) { + fnote = _voices[voice].note; + + // Handle SCI0-style transposing here + if (!_isSci1) + fnote += instrument->transpose; + + if (fnote < 0 || fnote > 127) { + warning("[sfx:seq:amiga] illegal note %i", fnote); + return; + } + } else + fnote = instrument->fixedNote; + + // Compute rate for note + int mulFact = 1, divFact = 1; + + fnote -= instrument->baseNote; + fnote *= 4; + // FIXME: check how SSCI maps this + fnote += (_channels[_voices[voice].hw_channel].pitch - 0x2000) / 169; + + while (fnote < 0) { + divFact *= 2; + fnote += 12 * 4; + } + + while (fnote >= 12 * 4) { + mulFact *= 2; + fnote -= 12 * 4; + } + + double freq = _freqTable[fnote] * instrument->baseFreq * mulFact / divFact; + + // Handle SCI1-style transposing here + if (instrument->transpose && _isSci1) + freq = freq + ((_freqTable[4] - 1.0) * freq * (double)instrument->transpose / (double)16); + + _voices[voice].rate = doubleToFrac(freq / _frequency); +} + +void MidiDriver_AmigaMac::startNote(int ch, int note, int velocity) { int channel; if (_channels[ch].instrument < 0 || _channels[ch].instrument > 255) { @@ -331,7 +406,7 @@ void MidiDriver_Amiga::startNote(int ch, int note, int velocity) { return; } - instrument = _bank.instruments[_channels[ch].instrument]; + InstrumentSample *instrument = findInstrument(_channels[ch].instrument, note); if (!instrument) { warning("[sfx:seq:amiga] instrument %i does not exist", _channels[ch].instrument); @@ -349,19 +424,6 @@ void MidiDriver_Amiga::startNote(int ch, int note, int velocity) { stopChannel(ch); - if (instrument->mode & kModePitch) { - int fnote = note + instrument->transpose; - - if (fnote < 0 || fnote > 127) { - warning("[sfx:seq:amiga] illegal note %i\n", fnote); - return; - } - - /* Compute rate for note */ - _voices[channel].rate = doubleToFrac(freq_table[fnote] / (double) _frequency); - } else - _voices[channel].rate = doubleToFrac(kBaseFreq / (double) _frequency); - _voices[channel].instrument = _channels[ch].instrument; _voices[channel].note = note; _voices[channel].note_velocity = velocity; @@ -377,30 +439,34 @@ void MidiDriver_Amiga::startNote(int ch, int note, int velocity) { _voices[channel].hw_channel = ch; _voices[channel].decay = 0; _voices[channel].looping = 0; + setOutputFrac(channel); } -MidiDriver_Amiga::Instrument *MidiDriver_Amiga::readInstrument(Common::File &file, int *id) { - Instrument *instrument; +MidiDriver_AmigaMac::InstrumentSample *MidiDriver_AmigaMac::readInstrumentSCI0(Common::SeekableReadStream &file, int *id) { byte header[61]; - int size; - int seg_size[3]; - int loop_offset; - int i; if (file.read(header, 61) < 61) { warning("[sfx:seq:amiga] failed to read instrument header"); return NULL; } - instrument = new Instrument; - + int seg_size[3]; seg_size[0] = READ_BE_UINT16(header + 35) * 2; seg_size[1] = READ_BE_UINT16(header + 41) * 2; seg_size[2] = READ_BE_UINT16(header + 47) * 2; + InstrumentSample *instrument = new InstrumentSample; + + instrument->startNote = 0; + instrument->endNote = 127; + instrument->isUnsigned = false; + instrument->baseFreq = kBaseFreq; + instrument->baseNote = 101; + instrument->fixedNote = 101; + instrument->mode = header[33]; instrument->transpose = (int8) header[34]; - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { int length = (int8) header[49 + i]; if (length == 0 && i > 0) @@ -413,13 +479,14 @@ MidiDriver_Amiga::Instrument *MidiDriver_Amiga::readInstrument(Common::File &fil /* Final target must be 0 */ instrument->envelope[3].target = 0; - loop_offset = READ_BE_UINT32(header + 37) & ~1; - size = seg_size[0] + seg_size[1] + seg_size[2]; + int loop_offset = READ_BE_UINT32(header + 37) & ~1; + int size = seg_size[0] + seg_size[1] + seg_size[2]; *id = READ_BE_UINT16(header); strncpy(instrument->name, (char *) header + 2, 29); instrument->name[29] = 0; + #ifdef DEBUG printf("[sfx:seq:amiga] Reading instrument %i: \"%s\" (%i bytes)\n", *id, instrument->name, size); @@ -429,6 +496,7 @@ MidiDriver_Amiga::Instrument *MidiDriver_Amiga::readInstrument(Common::File &fil printf(" Segment sizes: %i %i %i\n", seg_size[0], seg_size[1], seg_size[2]); printf(" Segment offsets: 0 %i %i\n", loop_offset, read_int32(header + 43)); #endif + instrument->samples = (int8 *) malloc(size + 1); if (file.read(instrument->samples, size) < (unsigned int)size) { warning("[sfx:seq:amiga] failed to read instrument samples"); @@ -437,6 +505,9 @@ MidiDriver_Amiga::Instrument *MidiDriver_Amiga::readInstrument(Common::File &fil return NULL; } + if (instrument->mode & kModePitch) + instrument->fixedNote = -1; + if (instrument->mode & kModeLoop) { if (loop_offset + seg_size[1] > size) { #ifdef DEBUG @@ -463,6 +534,7 @@ MidiDriver_Amiga::Instrument *MidiDriver_Amiga::readInstrument(Common::File &fil instrument->loop[instrument->loop_size] = instrument->loop[0]; } else { instrument->loop = NULL; + instrument->loop_size = 0; instrument->size = size; instrument->samples[instrument->size] = 0; } @@ -470,7 +542,7 @@ MidiDriver_Amiga::Instrument *MidiDriver_Amiga::readInstrument(Common::File &fil return instrument; } -uint32 MidiDriver_Amiga::property(int prop, uint32 param) { +uint32 MidiDriver_AmigaMac::property(int prop, uint32 param) { switch(prop) { case MIDI_PROP_MASTER_VOLUME: if (param != 0xffff) @@ -482,28 +554,17 @@ uint32 MidiDriver_Amiga::property(int prop, uint32 param) { return 0; } -int MidiDriver_Amiga::open() { +int MidiDriver_AmigaMac::open() { + _isSci1 = false; + + for (int i = 0; i < 48; i++) + _freqTable[i] = pow(2, i / (double)48); + _frequency = _mixer->getOutputRate(); _envDecay.length = _frequency / (32 * 64); _envDecay.delta = 1; _envDecay.target = 0; - Common::File file; - byte header[40]; - - if (!file.open("bank.001")) { - warning("[sfx:seq:amiga] file bank.001 not found"); - return Common::kUnknownError; - } - - if (file.read(header, 40) < 40) { - warning("[sfx:seq:amiga] failed to read header of file bank.001"); - return Common::kUnknownError; - } - - for (uint i = 0; i < 256; i++) - _bank.instruments[i] = NULL; - for (uint i = 0; i < kChannels; i++) { _voices[i].note = -1; _voices[i].hw_channel = 0; @@ -513,32 +574,46 @@ int MidiDriver_Amiga::open() { _channels[i].instrument = -1; _channels[i].volume = 127; _channels[i].pan = (i % 4 == 0 || i % 4 == 3 ? kPanLeft : kPanRight); + _channels[i].pitch = 0x2000; } - _bank.size = READ_BE_UINT16(header + 38); - strncpy(_bank.name, (char *) header + 8, 29); - _bank.name[29] = 0; -#ifdef DEBUG - printf("[sfx:seq:amiga] Reading %i instruments from bank \"%s\"\n", _bank.size, _bank.name); -#endif - - for (uint i = 0; i < _bank.size; i++) { - int id; - Instrument *instrument = readInstrument(file, &id); + Common::File file; - if (!instrument) { - warning("[sfx:seq:amiga] failed to read bank.001"); + if (file.open("bank.001")) { + if (!loadInstrumentsSCI0(file)) { + file.close(); return Common::kUnknownError; } + file.close(); + } else { + ResourceManager *resMan = g_sci->getResMan(); - if (id < 0 || id > 255) { - warning("[sfx:seq:amiga] Error: instrument ID out of bounds"); + Resource *resource = resMan->findResource(ResourceId(kResourceTypePatch, 7), false); + if (!resource) + resource = resMan->findResource(ResourceId(kResourceTypePatch, 9), false); + + // If we have a patch by this point, it's SCI1 + if (resource) + _isSci1 = true; + + // Check for the SCI0 Mac patch + if (!resource) + resource = resMan->findResource(ResourceId(kResourceTypePatch, 200), false); + + if (!resource) { + warning("Could not open patch for Amiga sound driver"); return Common::kUnknownError; } - _bank.instruments[id] = instrument; - } + Common::MemoryReadStream stream(resource->data, resource->size); + if (_isSci1) { + if (!loadInstrumentsSCI1(stream)) + return Common::kUnknownError; + } else if (!loadInstrumentsSCI0Mac(stream)) + return Common::kUnknownError; + } + MidiDriver_Emulated::open(); _mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, _mixer->kMaxChannelVolume, 0, DisposeAfterUse::NO); @@ -546,28 +621,30 @@ int MidiDriver_Amiga::open() { return Common::kNoError; } -void MidiDriver_Amiga::close() { +void MidiDriver_AmigaMac::close() { _mixer->stopHandle(_mixerSoundHandle); for (uint i = 0; i < _bank.size; i++) { - if (_bank.instruments[i]) { - if (_bank.instruments[i]->loop) - free(_bank.instruments[i]->loop); - free(_bank.instruments[i]->samples); - delete _bank.instruments[i]; + for (uint32 j = 0; j < _bank.instruments[i].size(); j++) { + if (_bank.instruments[i][j]) { + if (_bank.instruments[i][j]->loop) + free(_bank.instruments[i][j]->loop); + free(_bank.instruments[i][j]->samples); + delete _bank.instruments[i][j]; + } } } } -void MidiDriver_Amiga::playSwitch(bool play) { +void MidiDriver_AmigaMac::playSwitch(bool play) { _playSwitch = play; } -void MidiDriver_Amiga::setVolume(byte volume_) { +void MidiDriver_AmigaMac::setVolume(byte volume_) { _masterVolume = volume_; } -void MidiDriver_Amiga::send(uint32 b) { +void MidiDriver_AmigaMac::send(uint32 b) { byte command = b & 0xf0; byte channel = b & 0xf; byte op1 = (b >> 8) & 0xff; @@ -603,12 +680,15 @@ void MidiDriver_Amiga::send(uint32 b) { case 0xc0: changeInstrument(channel, op1); break; + case 0xe0: + pitchWheel(channel, (op2 << 7) | op1); + break; default: warning("[sfx:seq:amiga] unknown event %02x", command); } } -void MidiDriver_Amiga::generateSamples(int16 *data, int len) { +void MidiDriver_AmigaMac::generateSamples(int16 *data, int len) { if (len == 0) return; @@ -651,24 +731,256 @@ void MidiDriver_Amiga::generateSamples(int16 *data, int len) { free(buffers); } -class MidiPlayer_Amiga : public MidiPlayer { +bool MidiDriver_AmigaMac::loadInstrumentsSCI0(Common::File &file) { + _isSci1 = false; + + byte header[40]; + + if (file.read(header, 40) < 40) { + warning("[sfx:seq:amiga] failed to read header of file bank.001"); + return false; + } + + _bank.size = READ_BE_UINT16(header + 38); + strncpy(_bank.name, (char *) header + 8, 29); + _bank.name[29] = 0; +#ifdef DEBUG + printf("[sfx:seq:amiga] Reading %i instruments from bank \"%s\"\n", _bank.size, _bank.name); +#endif + + for (uint i = 0; i < _bank.size; i++) { + int id; + InstrumentSample *instrument = readInstrumentSCI0(file, &id); + + if (!instrument) { + warning("[sfx:seq:amiga] failed to read bank.001"); + return false; + } + + if (id < 0 || id > 255) { + warning("[sfx:seq:amiga] Error: instrument ID out of bounds"); + return false; + } + + if ((uint)id >= _bank.instruments.size()) + _bank.instruments.resize(id + 1); + + _bank.instruments[id].push_back(instrument); + memcpy(_bank.instruments[id].name, instrument->name, sizeof(instrument->name)); + } + + return true; +} + +bool MidiDriver_AmigaMac::loadInstrumentsSCI0Mac(Common::SeekableReadStream &file) { + byte header[40]; + + if (file.read(header, 40) < 40) { + warning("[sfx:seq:amiga] failed to read header of file patch.200"); + return false; + } + + _bank.size = 128; + strncpy(_bank.name, (char *) header + 8, 29); + _bank.name[29] = 0; +#ifdef DEBUG + printf("[sfx:seq:amiga] Reading %i instruments from bank \"%s\"\n", _bank.size, _bank.name); +#endif + + Common::Array<uint32> instrumentOffsets; + instrumentOffsets.resize(_bank.size); + _bank.instruments.resize(_bank.size); + + for (uint32 i = 0; i < _bank.size; i++) + instrumentOffsets[i] = file.readUint32BE(); + + for (uint i = 0; i < _bank.size; i++) { + // 0 signifies it doesn't exist + if (instrumentOffsets[i] == 0) + continue; + + file.seek(instrumentOffsets[i]); + + uint16 id = file.readUint16BE(); + if (id != i) + error("Instrument number mismatch"); + + InstrumentSample *instrument = new InstrumentSample; + + instrument->startNote = 0; + instrument->endNote = 127; + instrument->isUnsigned = true; + instrument->baseFreq = kBaseFreq; + instrument->baseNote = 101; + instrument->fixedNote = 101; + instrument->mode = file.readUint16BE(); + + // Read in the offsets + int32 seg_size[3]; + seg_size[0] = file.readUint32BE(); + seg_size[1] = file.readUint32BE(); + seg_size[2] = file.readUint32BE(); + + instrument->transpose = file.readUint16BE(); + + for (byte j = 0; j < 4; j++) { + int length = (int8)file.readByte(); + + if (length == 0 && j > 0) + length = 256; + + instrument->envelope[j].length = length * _frequency / 60; + instrument->envelope[j].delta = (int8)file.readByte(); + instrument->envelope[j].target = file.readByte(); + } + + // Final target must be 0 + instrument->envelope[3].target = 0; + + file.read(instrument->name, 30); + + if (instrument->mode & kModePitch) + instrument->fixedNote = -1; + + uint32 size = seg_size[2]; + uint32 loop_offset = seg_size[0]; + + instrument->samples = (int8 *)malloc(size + 1); + if (file.read(instrument->samples, size) < size) { + warning("[sfx:seq:amiga] failed to read instrument sample"); + free(instrument->samples); + delete instrument; + continue; + } + + if (instrument->mode & kModeLoop) { + instrument->size = seg_size[0]; + instrument->loop_size = seg_size[1] - seg_size[0]; + + instrument->loop = (int8*)malloc(instrument->loop_size + 1); + memcpy(instrument->loop, instrument->samples + loop_offset, instrument->loop_size); + + instrument->samples[instrument->size] = instrument->loop[0]; + instrument->loop[instrument->loop_size] = instrument->loop[0]; + } else { + instrument->loop = NULL; + instrument->loop_size = 0; + instrument->size = size; + instrument->samples[instrument->size] = (int8)0x80; + } + + _bank.instruments[id].push_back(instrument); + memcpy(_bank.instruments[id].name, instrument->name, sizeof(instrument->name)); + } + + return true; +} + +bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file) { + _bank.size = 128; + + Common::Array<uint32> instrumentOffsets; + instrumentOffsets.resize(_bank.size); + _bank.instruments.resize(_bank.size); + + for (uint32 i = 0; i < _bank.size; i++) + instrumentOffsets[i] = file.readUint32BE(); + + for (uint32 i = 0; i < _bank.size; i++) { + // 0 signifies it doesn't exist + if (instrumentOffsets[i] == 0) + continue; + + file.seek(instrumentOffsets[i]); + + // Read in the instrument name + file.read(_bank.instruments[i].name, 10); // last two bytes are always 0 + + for (uint32 j = 0; ; j++) { + InstrumentSample *sample = new InstrumentSample; + memset(sample, 0, sizeof(InstrumentSample)); + + sample->startNote = file.readSint16BE(); + + // startNote being -1 signifies we're done with this instrument + if (sample->startNote == -1) { + delete sample; + break; + } + + sample->endNote = file.readSint16BE(); + uint32 samplePtr = file.readUint32BE(); + sample->transpose = file.readSint16BE(); + for (int env = 0; env < 3; env++) { + sample->envelope[env].length = file.readByte() * _frequency / 60; + sample->envelope[env].delta = (env == 0 ? 10 : -10); + sample->envelope[env].target = file.readByte(); + } + + sample->envelope[3].length = 0; + sample->fixedNote = file.readSint16BE(); + int16 loop = file.readSint16BE(); + uint32 nextSamplePos = file.pos(); + + file.seek(samplePtr); + 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(); + uint32 sampleDataPos = file.pos(); + + sample->size = phase1End - phase1Offset + 1; + sample->loop_size = phase2End - phase2Offset + 1; + + sample->samples = (int8 *)malloc(sample->size + 1); + file.seek(phase1Offset + sampleDataPos); + file.read(sample->samples, sample->size); + sample->samples[sample->size] = (sample->isUnsigned ? (int8)0x80 : 0); + + if (loop == 0 && sample->loop_size > 1) { + sample->loop = (int8 *)malloc(sample->loop_size + 1); + file.seek(phase2Offset + sampleDataPos); + file.read(sample->loop, sample->loop_size); + sample->mode |= kModeLoop; + sample->samples[sample->size] = sample->loop[0]; + sample->loop[sample->loop_size] = sample->loop[0]; + } + + _bank.instruments[i].push_back(sample); + + file.seek(periodTableOffset + 0xe0); + sample->baseFreq = file.readUint16BE(); + + file.seek(nextSamplePos); + } + } + + return true; +} + +class MidiPlayer_AmigaMac : public MidiPlayer { public: - MidiPlayer_Amiga(SciVersion version) : MidiPlayer(version) { _driver = new MidiDriver_Amiga(g_system->getMixer()); } + MidiPlayer_AmigaMac(SciVersion version) : MidiPlayer(version) { _driver = new MidiDriver_AmigaMac(g_system->getMixer()); } byte getPlayId(); - int getPolyphony() const { return MidiDriver_Amiga::kVoices; } + int getPolyphony() const { return MidiDriver_AmigaMac::kVoices; } bool hasRhythmChannel() const { return false; } - void setVolume(byte volume) { static_cast<MidiDriver_Amiga *>(_driver)->setVolume(volume); } - void playSwitch(bool play) { static_cast<MidiDriver_Amiga *>(_driver)->playSwitch(play); } + void setVolume(byte volume) { static_cast<MidiDriver_AmigaMac *>(_driver)->setVolume(volume); } + void playSwitch(bool play) { static_cast<MidiDriver_AmigaMac *>(_driver)->playSwitch(play); } void loadInstrument(int idx, byte *data); }; -MidiPlayer *MidiPlayer_Amiga_create(SciVersion version) { - return new MidiPlayer_Amiga(version); +MidiPlayer *MidiPlayer_AmigaMac_create(SciVersion version) { + return new MidiPlayer_AmigaMac(version); } -byte MidiPlayer_Amiga::getPlayId() { - if (_version != SCI_VERSION_0_LATE) - error("Amiga sound support not available for this SCI version"); +byte MidiPlayer_AmigaMac::getPlayId() { + if (_version > SCI_VERSION_0_LATE) + return 0x06; return 0x40; } diff --git a/engines/sci/sound/drivers/mididriver.h b/engines/sci/sound/drivers/mididriver.h index 58803db260..2db6f25c70 100644 --- a/engines/sci/sound/drivers/mididriver.h +++ b/engines/sci/sound/drivers/mididriver.h @@ -86,7 +86,7 @@ public: virtual byte getPlayId() = 0; virtual int getPolyphony() const = 0; - virtual int getFirstChannel() { return 0; }; + virtual int getFirstChannel() { return 0; } virtual void setVolume(byte volume) { if(_driver) @@ -113,7 +113,7 @@ protected: }; extern MidiPlayer *MidiPlayer_AdLib_create(SciVersion version); -extern MidiPlayer *MidiPlayer_Amiga_create(SciVersion version); +extern MidiPlayer *MidiPlayer_AmigaMac_create(SciVersion version); extern MidiPlayer *MidiPlayer_PCJr_create(SciVersion version); extern MidiPlayer *MidiPlayer_PCSpeaker_create(SciVersion version); extern MidiPlayer *MidiPlayer_Midi_create(SciVersion version); diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp index cc09ba79f0..e58fa5120b 100644 --- a/engines/sci/sound/midiparser_sci.cpp +++ b/engines/sci/sound/midiparser_sci.cpp @@ -475,7 +475,7 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) { // on tick 0. Signal isn't set at that point by sierra sci and it would cause the castle daventry text to // get immediately removed, so we currently filter it. // Sierra SCI ignores them as well at that time - if (_position._play_tick) { + if ((_position._play_tick) || (info.delta)) { _signalSet = true; _signalToSet = info.basic.param1; } @@ -516,10 +516,11 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) { break; case SCI_VERSION_1_EARLY: case SCI_VERSION_1_LATE: + case SCI_VERSION_2_1: _dataincToAdd = 1; break; default: - break; + error("unsupported _soundVersion"); } break; case kResetOnPause: @@ -672,6 +673,7 @@ void MidiParser_SCI::setVolume(byte volume) { case SCI_VERSION_1_EARLY: case SCI_VERSION_1_LATE: + case SCI_VERSION_2_1: // Send previous channel volumes again to actually update the volume for (int i = 0; i < 15; i++) if (_channelRemap[i] != -1) diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp index 55a7e1fdc4..c3315bd2b5 100644 --- a/engines/sci/sound/music.cpp +++ b/engines/sci/sound/music.cpp @@ -63,23 +63,15 @@ void SciMusic::init() { // SCI sound init _dwTempo = 0; - // Default to MIDI in SCI32 games, as many don't have AdLib support. - // WORKAROUND: Default to MIDI in Amiga SCI1_EGA+ games as we don't support - // those patches yet. We also don't yet support the 7.pat file of SCI1+ Mac - // games or SCI0 Mac patches, so we default to MIDI in those games to let - // them run. + // Default to MIDI in SCI2.1+ games, as many don't have AdLib support. Common::Platform platform = g_sci->getPlatform(); - uint32 dev = MidiDriver::detectDevice( - (getSciVersion() >= SCI_VERSION_2 || platform == Common::kPlatformMacintosh || - (platform == Common::kPlatformAmiga && getSciVersion() >= SCI_VERSION_1_EGA)) - ? (MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM) - : (MDT_PCSPK | MDT_ADLIB | MDT_MIDI)); + uint32 dev = MidiDriver::detectDevice((getSciVersion() >= SCI_VERSION_2_1) ? (MDT_PCSPK | MDT_PCJR | MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM) : (MDT_PCSPK | MDT_PCJR | MDT_ADLIB | MDT_MIDI)); switch (MidiDriver::getMusicType(dev)) { case MT_ADLIB: // FIXME: There's no Amiga sound option, so we hook it up to AdLib - if (g_sci->getPlatform() == Common::kPlatformAmiga) - _pMidiDrv = MidiPlayer_Amiga_create(_soundVersion); + if (g_sci->getPlatform() == Common::kPlatformAmiga || platform == Common::kPlatformMacintosh) + _pMidiDrv = MidiPlayer_AmigaMac_create(_soundVersion); else _pMidiDrv = MidiPlayer_AdLib_create(_soundVersion); break; @@ -410,6 +402,8 @@ void SciMusic::soundStop(MusicEntry *pSnd) { pSnd->pMidiParser->mainThreadEnd(); _mutex.unlock(); } + + pSnd->fadeStep = 0; // end fading, if fading was in progress } void SciMusic::soundSetVolume(MusicEntry *pSnd, byte volume) { @@ -604,7 +598,7 @@ MusicEntry::MusicEntry() { priority = 0; loop = 0; volume = MUSIC_VOLUME_DEFAULT; - hold = 0; + hold = -1; pauseCounter = 0; sampleLoopCounter = 0; diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h index 943a5bd2a8..37e3c30030 100644 --- a/engines/sci/sound/music.h +++ b/engines/sci/sound/music.h @@ -71,7 +71,7 @@ public: byte priority; uint16 loop; int16 volume; - byte hold; + int16 hold; int16 pauseCounter; uint sampleLoopCounter; diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp index 51832af09f..bd88a5fca8 100644 --- a/engines/sci/sound/soundcmd.cpp +++ b/engines/sci/sound/soundcmd.cpp @@ -33,9 +33,6 @@ namespace Sci { -#define SCI1_SOUND_FLAG_MAY_PAUSE 1 /* Only here for completeness; The interpreter doesn't touch this bit */ -#define SCI1_SOUND_FLAG_SCRIPTED_PRI 2 /* but does touch this */ - SoundCommandParser::SoundCommandParser(ResourceManager *resMan, SegManager *segMan, Kernel *kernel, AudioPlayer *audio, SciVersion soundVersion) : _resMan(resMan), _segMan(segMan), _kernel(kernel), _audio(audio), _soundVersion(soundVersion) { @@ -48,6 +45,7 @@ SoundCommandParser::~SoundCommandParser() { } reg_t SoundCommandParser::kDoSoundInit(int argc, reg_t *argv, reg_t acc) { + debugC(2, kDebugLevelSound, "kDoSound(init): %04x:%04x", PRINT_REG(argv[0])); processInitSound(argv[0]); return acc; } @@ -73,8 +71,8 @@ void SoundCommandParser::processInitSound(reg_t obj) { if (_soundVersion >= SCI_VERSION_1_EARLY) newSound->volume = CLIP<int>(readSelectorValue(_segMan, obj, SELECTOR(vol)), 0, MUSIC_VOLUME_MAX); - debugC(2, kDebugLevelSound, "kDoSound(init): number %d, loop %d, prio %d, vol %d", resourceId, - newSound->loop, newSound->priority, newSound->volume); + debugC(2, kDebugLevelSound, "kDoSound(init): %04x:%04x number %d, loop %d, prio %d, vol %d", PRINT_REG(obj), + resourceId, newSound->loop, newSound->priority, newSound->volume); // In SCI1.1 games, sound effects are started from here. If we can find // a relevant audio resource, play it, otherwise switch to synthesized @@ -105,6 +103,7 @@ void SoundCommandParser::processInitSound(reg_t obj) { } reg_t SoundCommandParser::kDoSoundPlay(int argc, reg_t *argv, reg_t acc) { + debugC(2, kDebugLevelSound, "kDoSound(play): %04x:%04x", PRINT_REG(argv[0])); processPlaySound(argv[0]); return acc; } @@ -142,8 +141,8 @@ void SoundCommandParser::processPlaySound(reg_t obj) { if (_soundVersion >= SCI_VERSION_1_EARLY) musicSlot->volume = readSelectorValue(_segMan, obj, SELECTOR(vol)); - debugC(2, kDebugLevelSound, "kDoSound(play): number %d, loop %d, prio %d, vol %d", resourceId, - musicSlot->loop, musicSlot->priority, musicSlot->volume); + debugC(2, kDebugLevelSound, "kDoSound(play): %04x:%04x number %d, loop %d, prio %d, vol %d", PRINT_REG(obj), + resourceId, musicSlot->loop, musicSlot->priority, musicSlot->volume); _music->soundPlay(musicSlot); } @@ -154,6 +153,7 @@ reg_t SoundCommandParser::kDoSoundDummy(int argc, reg_t *argv, reg_t acc) { } reg_t SoundCommandParser::kDoSoundDispose(int argc, reg_t *argv, reg_t acc) { + debugC(2, kDebugLevelSound, "kDoSound(dispose): %04x:%04x", PRINT_REG(argv[0])); processDisposeSound(argv[0]); return acc; } @@ -176,6 +176,7 @@ void SoundCommandParser::processDisposeSound(reg_t obj) { } reg_t SoundCommandParser::kDoSoundStop(int argc, reg_t *argv, reg_t acc) { + debugC(2, kDebugLevelSound, "kDoSound(stop): %04x:%04x", PRINT_REG(argv[0])); processStopSound(argv[0], false); return acc; } @@ -209,6 +210,11 @@ void SoundCommandParser::processStopSound(reg_t obj, bool sampleFinishedPlaying) } reg_t SoundCommandParser::kDoSoundPause(int argc, reg_t *argv, reg_t acc) { + if (argc == 1) + debugC(2, kDebugLevelSound, "kDoSound(pause): %04x:%04x", PRINT_REG(argv[0])); + else + debugC(2, kDebugLevelSound, "kDoSound(pause): %04x:%04x, %04x:%04x", PRINT_REG(argv[0]), PRINT_REG(argv[1])); + if (_soundVersion <= SCI_VERSION_0_LATE) { // SCI0 games give us 0/1 for either resuming or pausing the current music // this one doesn't count, so pausing 2 times and resuming once means here that we are supposed to resume @@ -250,26 +256,18 @@ reg_t SoundCommandParser::kDoSoundPause(int argc, reg_t *argv, reg_t acc) { } // SCI0 only command -reg_t SoundCommandParser::kDoSoundResume(int argc, reg_t *argv, reg_t acc) { - // this doesn't seem to do what we think it's doing - // it's called with no arguments at all (just restore a game in qfg1) - return acc; - reg_t obj = argv[0]; - - MusicEntry *musicSlot = _music->getSlot(obj); - if (!musicSlot) { - warning("kDoSound(resume):: Slot not found (%04x:%04x)", PRINT_REG(obj)); - return acc; - } - - writeSelectorValue(_segMan, musicSlot->soundObj, SELECTOR(state), kSoundPlaying); - _music->soundResume(musicSlot); +// It's called right after restoring a game - it's responsible to kick off playing music again +// we don't need this at all, so we don't do anything here +reg_t SoundCommandParser::kDoSoundResumeAfterRestore(int argc, reg_t *argv, reg_t acc) { return acc; } reg_t SoundCommandParser::kDoSoundMute(int argc, reg_t *argv, reg_t acc) { - if (argc > 0) + if (argc > 0) { + debugC(2, kDebugLevelSound, "kDoSound(mute): %d", argv[0].toUint16()); _music->soundSetSoundOn(argv[0].toUint16()); + } + return make_reg(0, _music->soundGetSoundOn()); } @@ -300,7 +298,7 @@ reg_t SoundCommandParser::kDoSoundFade(int argc, reg_t *argv, reg_t acc) { // If sound is not playing currently, set signal directly if (musicSlot->status != kSoundPlaying) { - debugC(2, kDebugLevelSound, "kDoSound(fade): fading requested, but sound is currently not playing"); + debugC(2, kDebugLevelSound, "kDoSound(fade): %04x:%04x fading requested, but sound is currently not playing", PRINT_REG(obj)); writeSelectorValue(_segMan, obj, SELECTOR(signal), SIGNAL_OFFSET); return acc; } @@ -328,7 +326,7 @@ reg_t SoundCommandParser::kDoSoundFade(int argc, reg_t *argv, reg_t acc) { error("kDoSound(fade): unsupported argc %d", argc); } - debugC(2, kDebugLevelSound, "kDoSound(fade): to %d, step %d, ticker %d", musicSlot->fadeTo, musicSlot->fadeStep, musicSlot->fadeTickerStep); + debugC(2, kDebugLevelSound, "kDoSound(fade): %04x:%04x to %d, step %d, ticker %d", PRINT_REG(obj), musicSlot->fadeTo, musicSlot->fadeStep, musicSlot->fadeTickerStep); return acc; } @@ -339,6 +337,8 @@ reg_t SoundCommandParser::kDoSoundGetPolyphony(int argc, reg_t *argv, reg_t acc) reg_t SoundCommandParser::kDoSoundUpdate(int argc, reg_t *argv, reg_t acc) { reg_t obj = argv[0]; + debugC(2, kDebugLevelSound, "kDoSound(update): %04x:%04x", PRINT_REG(argv[0])); + MusicEntry *musicSlot = _music->getSlot(obj); if (!musicSlot) { warning("kDoSound(update): Slot not found (%04x:%04x)", PRINT_REG(obj)); @@ -379,9 +379,13 @@ void SoundCommandParser::processUpdateCues(reg_t obj) { musicSlot->loop -= currentLoopCounter - musicSlot->sampleLoopCounter; musicSlot->sampleLoopCounter = currentLoopCounter; } - if ((!_music->soundIsActive(musicSlot)) && (musicSlot->status != kSoundPaused)) { - processStopSound(obj, true); - } else { + if (musicSlot->status == kSoundPlaying) { + if (!_music->soundIsActive(musicSlot)) { + processStopSound(obj, true); + } else { + _music->updateAudioStreamTicker(musicSlot); + } + } else if (musicSlot->status == kSoundPaused) { _music->updateAudioStreamTicker(musicSlot); } // We get a flag from MusicEntry::doFade() here to set volume for the stream @@ -443,9 +447,15 @@ reg_t SoundCommandParser::kDoSoundSendMidi(int argc, reg_t *argv, reg_t acc) { byte channel = argv[1].toUint16() & 0xf; byte midiCmd = argv[2].toUint16() & 0xff; + // TODO: first there is a 4-parameter variant of this call which needs to get reversed + // second the current code isn't 100% accurate, sierra sci does checks on the 4th parameter + if (argc == 4) + return acc; + uint16 controller = argv[3].toUint16(); uint16 param = argv[4].toUint16(); + debugC(2, kDebugLevelSound, "kDoSound(sendMidi): %04x:%04x, %d, %d, %d, %d", PRINT_REG(obj), channel, midiCmd, controller, param); if (channel) channel--; // channel is given 1-based, we are using 0-based @@ -464,6 +474,7 @@ reg_t SoundCommandParser::kDoSoundSendMidi(int argc, reg_t *argv, reg_t acc) { } reg_t SoundCommandParser::kDoSoundReverb(int argc, reg_t *argv, reg_t acc) { + debugC(2, kDebugLevelSound, "doSoundReverb: %d", argv[0].toUint16() & 0xF); _music->setReverb(argv[0].toUint16() & 0xF); return acc; } @@ -471,6 +482,8 @@ reg_t SoundCommandParser::kDoSoundReverb(int argc, reg_t *argv, reg_t acc) { reg_t SoundCommandParser::kDoSoundSetHold(int argc, reg_t *argv, reg_t acc) { reg_t obj = argv[0]; + debugC(2, kDebugLevelSound, "doSoundSetHold: %04x:%04x, %d", PRINT_REG(argv[0]), argv[1].toUint16()); + MusicEntry *musicSlot = _music->getSlot(obj); if (!musicSlot) { warning("kDoSound(setHold): Slot not found (%04x:%04x)", PRINT_REG(obj)); @@ -488,6 +501,11 @@ reg_t SoundCommandParser::kDoSoundGetAudioCapability(int argc, reg_t *argv, reg_ } reg_t SoundCommandParser::kDoSoundStopAll(int argc, reg_t *argv, reg_t acc) { + // TODO: this can't be right, this gets called in kq1 - e.g. being in witch house, getting the note + // now the point jingle plays and after a messagebox they call this - and would stop the background effects with it + // this doesn't make sense, so i disable it for now + return acc; + Common::StackLock(_music->_mutex); const MusicList::iterator end = _music->getPlayListEnd(); @@ -535,6 +553,8 @@ reg_t SoundCommandParser::kDoSoundSetPriority(int argc, reg_t *argv, reg_t acc) reg_t obj = argv[0]; int16 value = argv[1].toSint16(); + debugC(2, kDebugLevelSound, "kDoSound(setPriority): %04x:%04x, %d", PRINT_REG(obj), value); + MusicEntry *musicSlot = _music->getSlot(obj); if (!musicSlot) { warning("kDoSound(setPriority): Slot not found (%04x:%04x)", PRINT_REG(obj)); @@ -565,6 +585,8 @@ reg_t SoundCommandParser::kDoSoundSetLoop(int argc, reg_t *argv, reg_t acc) { reg_t obj = argv[0]; int16 value = argv[1].toSint16(); + debugC(2, kDebugLevelSound, "kDoSound(setLoop): %04x:%04x, %d", PRINT_REG(obj), value); + MusicEntry *musicSlot = _music->getSlot(obj); if (!musicSlot) { // Apparently, it's perfectly normal for a game to call cmdSetSoundLoop diff --git a/engines/sci/sound/soundcmd.h b/engines/sci/sound/soundcmd.h index a8bc1eb280..10915e8ea9 100644 --- a/engines/sci/sound/soundcmd.h +++ b/engines/sci/sound/soundcmd.h @@ -85,7 +85,7 @@ public: reg_t kDoSoundDummy(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundMute(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundPause(int argc, reg_t *argv, reg_t acc); - reg_t kDoSoundResume(int argc, reg_t *argv, reg_t acc); + reg_t kDoSoundResumeAfterRestore(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundStop(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundStopAll(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundDispose(int argc, reg_t *argv, reg_t acc); diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp index ea29e25a1f..b5a4070f0b 100644 --- a/engines/scumm/debugger.cpp +++ b/engines/scumm/debugger.cpp @@ -62,8 +62,6 @@ ScummDebugger::ScummDebugger(ScummEngine *s) _vm = s; // Register variables - DVar_Register("debug_countdown", &_frame_countdown, DVAR_INT, 0); - DVar_Register("scumm_speed", &_vm->_fastMode, DVAR_BYTE, 0); DVar_Register("scumm_room", &_vm->_currentRoom, DVAR_BYTE, 0); DVar_Register("scumm_roomresource", &_vm->_roomResource, DVAR_INT, 0); @@ -128,7 +126,7 @@ void ScummDebugger::postEnter() { bool ScummDebugger::Cmd_Restart(int argc, const char **argv) { _vm->restart(); - _detach_now = true; + detach(); return false; } @@ -202,7 +200,7 @@ bool ScummDebugger::Cmd_LoadGame(int argc, const char **argv) { _vm->requestLoad(slot); - _detach_now = true; + detach(); return false; } @@ -867,7 +865,7 @@ bool ScummDebugger::Cmd_Passcode(int argc, const char **argv) { } _vm->_bootParam = 0; - _detach_now = true; + detach(); } else { DebugPrintf("Current Passcode is %d \nUse 'passcode <SEGA CD Passcode>'\n",_vm->_scummVars[411]); @@ -878,9 +876,7 @@ bool ScummDebugger::Cmd_Passcode(int argc, const char **argv) { bool ScummDebugger::Cmd_ResetCursors(int argc, const char **argv) { _vm->resetCursors(); - - _detach_now = true; - + detach(); return false; } diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index 298917477f..7b0d4909d6 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -1482,7 +1482,7 @@ void GdiV2::prepareDrawBitmap(const byte *ptr, VirtScreen *vs, // Since V3, all graphics data was encoded in strips, which is very efficient // for redrawing only parts of the screen. However, V2 is different: here // the whole graphics are encoded as one big chunk. That makes it rather - // dificult to draw only parts of a room/object. We handle the V2 graphics + // difficult to draw only parts of a room/object. We handle the V2 graphics // differently from all other (newer) graphic formats for this reason. // StripTable *table = (_objectMode ? 0 : _roomStrips); @@ -2823,7 +2823,7 @@ void GdiPCEngine::decodePCEngineObject(const byte *ptr, int xpos, int ypos, int free(stripOffsets); } -void setTileData(byte *tile, int index, byte byte0, byte byte1) { +void GdiPCEngine::setTileData(byte *tile, int index, byte byte0, byte byte1) { int row = index % 8; int plane = (index / 8) * 2; int plane02Bit, plane13Bit; diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h index 108fd4555d..cdb473a67c 100644 --- a/engines/scumm/gfx.h +++ b/engines/scumm/gfx.h @@ -322,6 +322,7 @@ protected: protected: void decodePCEngineGfx(const byte *room); void decodeStrip(const byte *ptr, uint16 *tiles, byte *colors, uint16 *masks, int numRows, bool isObject); + void setTileData(byte *tile, int index, byte byte0, byte byte1); void decodePCEngineTileData(const byte *ptr); void decodePCEngineMaskData(const byte *ptr); void decodePCEngineObject(const byte *ptr, int xpos, int ypos, int width, int height); diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 86ec8c4748..7e2db22c5b 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1840,8 +1840,7 @@ Common::Error ScummEngine::go() { while (!shouldQuit()) { - if (_debugger->isAttached()) - _debugger->onFrame(); + _debugger->onFrame(); // Randomize the PRNG by calling it at regular intervals. This ensures // that it will be in a different state each time you run the program. diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp index 62fdf48440..30281cb565 100644 --- a/engines/scumm/string.cpp +++ b/engines/scumm/string.cpp @@ -1110,6 +1110,8 @@ int ScummEngine::convertMessageToString(const byte *msg, byte *dst, int dstSize) } num += (_game.version == 8) ? 4 : 2; } + } else if (_game.id == GID_DIG && (chr == 1 || chr == 2 || chr == 3 || chr == 8)) { + // Skip these characters } else { if (!(chr == '@') || (_game.id == GID_CMI && _language == Common::ZH_TWN) || (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine && _language == Common::JA_JPN)) diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp index 45b3cab947..edf96f8e8c 100644 --- a/engines/sky/sky.cpp +++ b/engines/sky/sky.cpp @@ -185,8 +185,7 @@ Common::Error SkyEngine::go() { uint32 delayCount = _system->getMillis(); while (!shouldQuit()) { - if (_debugger->isAttached()) - _debugger->onFrame(); + _debugger->onFrame(); if (shouldPerformAutoSave(_lastSaveTime)) { if (_skyControl->loadSaveAllowed()) { diff --git a/engines/sword1/memman.h b/engines/sword1/memman.h index 845a8638a2..b489eae2f9 100644 --- a/engines/sword1/memman.h +++ b/engines/sword1/memman.h @@ -42,11 +42,7 @@ struct MemHandle { #define MEM_CAN_FREE 1 #define MEM_DONT_FREE 2 -#ifdef PALMOS_MODE -#define MAX_ALLOC (3*1024*1024) // max amount of mem we want to alloc(). -#else #define MAX_ALLOC (6*1024*1024) // max amount of mem we want to alloc(). -#endif class MemMan { public: diff --git a/engines/sword2/anims.cpp b/engines/sword2/anims.cpp index 1bf3967047..7fd36fcc86 100644 --- a/engines/sword2/anims.cpp +++ b/engines/sword2/anims.cpp @@ -56,8 +56,6 @@ int Router::doAnimate(byte *ob_logic, byte *ob_graph, int32 animRes, bool revers ObjectGraphic obGraph(ob_graph); if (obLogic.getLooping() == 0) { - byte *ptr; - // This is the start of the anim - set up the first frame // For testing all anims! @@ -75,12 +73,8 @@ int Router::doAnimate(byte *ob_logic, byte *ob_graph, int32 animRes, bool revers return IR_STOP; } - ptr = _vm->_resman->openResource(animRes); - // if it's not an animation file if (_vm->_resman->fetchType(animRes) != ANIMATION_FILE) { - _vm->_resman->closeResource(animRes); - // switch off the sprite // don't animate - just continue // script next cycle @@ -88,8 +82,6 @@ int Router::doAnimate(byte *ob_logic, byte *ob_graph, int32 animRes, bool revers return IR_STOP; } - _vm->_resman->closeResource(animRes); - // switch on the sprite setSpriteStatus(ob_graph, SORT_SPRITE); } diff --git a/engines/sword2/music.cpp b/engines/sword2/music.cpp index a68baed097..c052aa6b46 100644 --- a/engines/sword2/music.cpp +++ b/engines/sword2/music.cpp @@ -136,10 +136,8 @@ static Audio::AudioStream *getAudioStream(SoundFileHandle *fh, const char *base, return NULL; } if (fh->fileSize != fh->file.size()) { - if (fh->idxTab) { - free(fh->idxTab); - fh->idxTab = NULL; - } + free(fh->idxTab); + fh->idxTab = NULL; } } else alreadyOpen = true; diff --git a/engines/sword2/resman.h b/engines/sword2/resman.h index 72bdf73b98..dcc79927ea 100644 --- a/engines/sword2/resman.h +++ b/engines/sword2/resman.h @@ -32,11 +32,7 @@ namespace Common { class File; } -#ifdef PALMOS_MODE -#define MAX_MEM_CACHE (4 * 1024 * 1024) // 4 seems to be enough, 8 = out of memory -#else #define MAX_MEM_CACHE (8 * 1024 * 1024) // we keep up to 8 megs of resource data files in memory -#endif #define MAX_res_files 20 namespace Sword2 { diff --git a/engines/sword2/sword2.cpp b/engines/sword2/sword2.cpp index 29f567d7ef..3cdab2bd2b 100644 --- a/engines/sword2/sword2.cpp +++ b/engines/sword2/sword2.cpp @@ -326,12 +326,20 @@ void Sword2Engine::registerDefaultSettings() { } void Sword2Engine::syncSoundSettings() { - // Sound settings. At the time of writing, not all of these can be set - // by the global options dialog, but it seems silly to split them up. _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); setSubtitles(ConfMan.getBool("subtitles")); + + // Our own settings dialog can mute the music, speech and sound effects + // individually. ScummVM's settings dialog has one master mute setting. + + if (ConfMan.getBool("mute")) { + ConfMan.setBool("music_mute", true); + ConfMan.setBool("speech_mute", true); + ConfMan.setBool("sfx_mute", true); + } + _sound->muteMusic(ConfMan.getBool("music_mute")); _sound->muteSpeech(ConfMan.getBool("speech_mute")); _sound->muteFx(ConfMan.getBool("sfx_mute")); @@ -356,6 +364,13 @@ void Sword2Engine::writeSettings() { ConfMan.setBool("object_labels", _mouse->getObjectLabels()); ConfMan.setInt("reverse_stereo", _sound->isReverseStereo()); + // If even one sound type is unmuted, we can't say that all sound is + // muted. + + if (!_sound->isMusicMute() || !_sound->isSpeechMute() || !_sound->isFxMute()) { + ConfMan.setBool("mute", false); + } + ConfMan.flushToDisk(); } @@ -458,8 +473,7 @@ Common::Error Sword2Engine::run() { _screen->initialiseRenderCycle(); while (1) { - if (_debugger->isAttached()) - _debugger->onFrame(); + _debugger->onFrame(); #ifdef SWORD2_DEBUG if (_stepOneCycle) { diff --git a/engines/teenagent/module.mk b/engines/teenagent/module.mk index 2c04c99376..01ba3c79cb 100644 --- a/engines/teenagent/module.mk +++ b/engines/teenagent/module.mk @@ -1,23 +1,23 @@ MODULE := engines/teenagent MODULE_OBJS := \ + actor.o \ + animation.o \ + callbacks.o \ + console.o \ detection.o \ - teenagent.o \ - resources.o \ + dialog.o \ + font.o \ + inventory.o \ + music.o \ + objects.o \ pack.o \ - segment.o \ + resources.o \ scene.o \ - animation.o \ - font.o \ + segment.o \ surface.o \ surface_list.o \ - actor.o \ - callbacks.o \ - inventory.o \ - objects.o \ - music.o \ - console.o \ - dialog.o + teenagent.o # This module can be built as a plugin ifeq ($(ENABLE_TEENAGENT), DYNAMIC_PLUGIN) diff --git a/engines/teenagent/teenagent.cpp b/engines/teenagent/teenagent.cpp index 838275670b..f1527fc78d 100644 --- a/engines/teenagent/teenagent.cpp +++ b/engines/teenagent/teenagent.cpp @@ -617,9 +617,7 @@ Common::Error TeenAgentEngine::run() { _system->updateScreen(); - if (console->isAttached()) { - console->onFrame(); - } + console->onFrame(); uint32 next_tick = MIN(game_timer, mark_timer); if (next_tick > 0) { diff --git a/engines/tinsel/actors.cpp b/engines/tinsel/actors.cpp index efcefb442c..3577f4e0cc 100644 --- a/engines/tinsel/actors.cpp +++ b/engines/tinsel/actors.cpp @@ -197,10 +197,8 @@ void RegisterActors(int num) { } void FreeActors() { - if (actorInfo) { - free(actorInfo); - actorInfo = NULL; - } + free(actorInfo); + actorInfo = NULL; } /** diff --git a/engines/tinsel/bmv.cpp b/engines/tinsel/bmv.cpp index 938507c3f9..b13de103c0 100644 --- a/engines/tinsel/bmv.cpp +++ b/engines/tinsel/bmv.cpp @@ -730,16 +730,12 @@ void BMVPlayer::FinishBMV() { stream.close(); // Release the data buffer - if (bigBuffer != NULL) { - free(bigBuffer); - bigBuffer = NULL; - } + free(bigBuffer); + bigBuffer = NULL; // Release the screen buffer - if (screenBuffer != NULL) { - free(screenBuffer); - screenBuffer = NULL; - } + free(screenBuffer); + screenBuffer = NULL; // Ditch any text objects for (i = 0; i < 2; i++) { diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp index 60eb08a2dd..fdc4484a7c 100644 --- a/engines/tinsel/handle.cpp +++ b/engines/tinsel/handle.cpp @@ -175,22 +175,18 @@ void SetupHandleTable() { } void FreeHandleTable() { - if (handleTable) { - free(handleTable); - handleTable = NULL; - } - if (cdGraphStream) { - delete cdGraphStream; - cdGraphStream = 0; - } + free(handleTable); + handleTable = NULL; + + delete cdGraphStream; + cdGraphStream = NULL; } /** * Loads a memory block as a file. */ void OpenCDGraphFile() { - if (cdGraphStream) - delete cdGraphStream; + delete cdGraphStream; // As the theory goes, the right CD will be in there! diff --git a/engines/tinsel/object.cpp b/engines/tinsel/object.cpp index f91e37a063..7a93a0b30a 100644 --- a/engines/tinsel/object.cpp +++ b/engines/tinsel/object.cpp @@ -49,10 +49,8 @@ static int maxObj = 0; #endif void FreeObjectList() { - if (objectList) { - free(objectList); - objectList = NULL; - } + free(objectList); + objectList = NULL; } /** diff --git a/engines/tinsel/savescn.cpp b/engines/tinsel/savescn.cpp index 50231d34bb..2b5c815d3c 100644 --- a/engines/tinsel/savescn.cpp +++ b/engines/tinsel/savescn.cpp @@ -162,10 +162,8 @@ void InitialiseSaveScenes() { } void FreeSaveScenes() { - if (ssData) { - free(ssData); - ssData = NULL; - } + free(ssData); + ssData = NULL; } /** diff --git a/engines/tinsel/strres.cpp b/engines/tinsel/strres.cpp index 8f9f72f446..2416d6a8fa 100644 --- a/engines/tinsel/strres.cpp +++ b/engines/tinsel/strres.cpp @@ -88,11 +88,9 @@ void ChangeLanguage(LANGUAGE newLang) { textLanguage = newLang; sampleLanguage = newLang; - if (textBuffer) { - // free the previous buffer - free(textBuffer); - textBuffer = NULL; - } + // free the previous buffer + free(textBuffer); + textBuffer = NULL; // Try and open the specified language file. If it fails, and the language // isn't English, try falling back on opening 'english.txt' - some foreign @@ -355,10 +353,8 @@ int SubStringCount(int id) { void FreeTextBuffer() { - if (textBuffer) { - free(textBuffer); - textBuffer = NULL; - } + free(textBuffer); + textBuffer = NULL; } /** diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp index 3a4191227a..dc706c82d9 100644 --- a/engines/tinsel/tinsel.cpp +++ b/engines/tinsel/tinsel.cpp @@ -1000,8 +1000,7 @@ Common::Error TinselEngine::run() { uint32 timerVal = 0; while (!shouldQuit()) { assert(_console); - if (_console->isAttached()) - _console->onFrame(); + _console->onFrame(); // Check for time to do next game cycle if ((g_system->getMillis() > timerVal + GAME_FRAME_DELAY)) { diff --git a/graphics/video/codecs/cinepak.cpp b/graphics/video/codecs/cinepak.cpp index d3448bb8f7..9892f9d966 100644 --- a/graphics/video/codecs/cinepak.cpp +++ b/graphics/video/codecs/cinepak.cpp @@ -53,8 +53,11 @@ CinepakDecoder::CinepakDecoder() : Codec() { } CinepakDecoder::~CinepakDecoder() { - if (_curFrame.surface) + if (_curFrame.surface) { _curFrame.surface->free(); + delete _curFrame.surface; + } + delete[] _curFrame.strips; } diff --git a/graphics/video/dxa_decoder.h b/graphics/video/dxa_decoder.h index 0312828195..d61346324f 100644 --- a/graphics/video/dxa_decoder.h +++ b/graphics/video/dxa_decoder.h @@ -45,7 +45,7 @@ public: bool load(Common::SeekableReadStream &stream); void close(); - + bool isVideoLoaded() const { return _fileStream != 0; } uint16 getWidth() const { return _width; } uint16 getHeight() const { return _height; } diff --git a/graphics/video/flic_decoder.cpp b/graphics/video/flic_decoder.cpp index bb5b4f219b..b07e369cd8 100644 --- a/graphics/video/flic_decoder.cpp +++ b/graphics/video/flic_decoder.cpp @@ -57,7 +57,7 @@ bool FlicDecoder::load(Common::SeekableReadStream &stream) { return false; } - + _frameCount = _fileStream->readUint16LE(); uint16 width = _fileStream->readUint16LE(); uint16 height = _fileStream->readUint16LE(); @@ -265,7 +265,7 @@ Surface *FlicDecoder::decodeNextFrame() { delete[] data; } } - + _curFrame++; if (_curFrame == 0) diff --git a/graphics/video/mpeg_player.h b/graphics/video/mpeg_player.h index 70754fb5ed..4dedf12f57 100644 --- a/graphics/video/mpeg_player.h +++ b/graphics/video/mpeg_player.h @@ -52,10 +52,8 @@ typedef signed long int32_t; typedef unsigned long uint32_t; #endif -#elif !defined(PALMOS_MODE) -# include <inttypes.h> #else -# include <stdint.h> +# include <inttypes.h> #endif extern "C" { diff --git a/graphics/video/qt_decoder.cpp b/graphics/video/qt_decoder.cpp index a95243ba6a..61b0f5166d 100644 --- a/graphics/video/qt_decoder.cpp +++ b/graphics/video/qt_decoder.cpp @@ -206,7 +206,7 @@ void QuickTimeDecoder::stopAudio() { void QuickTimeDecoder::pauseVideoIntern(bool pause) { if (_audStream) - g_system->getMixer()->pauseHandle(_audHandle, pause); + g_system->getMixer()->pauseHandle(_audHandle, pause); } Surface *QuickTimeDecoder::decodeNextFrame() { diff --git a/graphics/video/video_decoder.cpp b/graphics/video/video_decoder.cpp index fe4a5848f3..9733afc5cc 100644 --- a/graphics/video/video_decoder.cpp +++ b/graphics/video/video_decoder.cpp @@ -64,7 +64,7 @@ void VideoDecoder::setSystemPalette() { delete[] sysPalette; } -bool VideoDecoder::needsUpdate() const { +bool VideoDecoder::needsUpdate() const { return !endOfVideo() && getTimeToNextFrame() == 0; } diff --git a/gui/GuiManager.cpp b/gui/GuiManager.cpp index ff747c6e92..ab370425ab 100644 --- a/gui/GuiManager.cpp +++ b/gui/GuiManager.cpp @@ -45,11 +45,12 @@ namespace GUI { enum { kDoubleClickDelay = 500, // milliseconds - kCursorAnimateDelay = 250 + kCursorAnimateDelay = 250, + kTooltipDelay = 1250 }; // Constructor -GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), +GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), _tooltipCheck(false), _stateIsSaved(false), _cursorAnimateCounter(0), _cursorAnimateTimer(0) { _theme = 0; _useStdCursor = false; @@ -77,7 +78,7 @@ GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), } } - _tooltip = new Tooltip(this); + _tooltip = 0; } GuiManager::~GuiManager() { @@ -224,13 +225,6 @@ Dialog *GuiManager::getTopDialog() const { return _dialogStack.top(); } -static void tooltipCallback(void *ref) { - GuiManager *guiManager = (GuiManager *)ref; - - guiManager->getTooltip()->setVisible(true); - g_system->getTimerManager()->removeTimerProc(&tooltipCallback); -} - void GuiManager::runLoop() { Dialog *activeDialog = getTopDialog(); bool didSaveState = false; @@ -321,7 +315,14 @@ void GuiManager::runLoop() { break; case Common::EVENT_MOUSEMOVE: activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); - _tooltip->setMouseXY(mouse.x, mouse.y); + + if (mouse.x != _lastMousePosition.x || mouse.y != _lastMousePosition.y) { + _lastMousePosition.x = mouse.x; + _lastMousePosition.y = mouse.y; + _lastMousePosition.time = _system->getMillis(); + } + + _tooltipCheck = true; eventTookplace = true; break; // We don't distinguish between mousebuttons (for now at least) @@ -367,11 +368,16 @@ void GuiManager::runLoop() { } } - if (eventTookplace) { - _tooltip->setVisible(false); + if (_tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis()) { + if (_tooltip == 0) + _tooltip = new Tooltip(); + + _tooltipCheck = false; + _tooltip->tooltipModal(_lastMousePosition.x, _lastMousePosition.y); + } - _system->getTimerManager()->removeTimerProc(&tooltipCallback); - _system->getTimerManager()->installTimerProc(&tooltipCallback, 2*1000000, this); + if (eventTookplace && _tooltip) { + _tooltip->mustClose(); } // Delay for a moment diff --git a/gui/GuiManager.h b/gui/GuiManager.h index 2a187a92f9..ee1351dc9b 100644 --- a/gui/GuiManager.h +++ b/gui/GuiManager.h @@ -33,6 +33,7 @@ #include "graphics/font.h" #include "gui/widget.h" +#include "gui/Tooltip.h" #include "gui/ThemeEngine.h" class OSystem; @@ -93,8 +94,6 @@ public: */ bool checkScreenChange(); - Tooltip *getTooltip() { return _tooltip; } - protected: enum RedrawStatus { kRedrawDisabled = 0, @@ -119,13 +118,14 @@ protected: bool _useStdCursor; Tooltip *_tooltip; + bool _tooltipCheck; // position and time of last mouse click (used to detect double clicks) struct { int16 x, y; // Position of mouse when the click occurred uint32 time; // Time int count; // How often was it already pressed? - } _lastClick; + } _lastClick, _lastMousePosition; // mouse cursor state int _cursorAnimateCounter; diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp index e08bc09b0b..4447b62244 100644 --- a/gui/ListWidget.cpp +++ b/gui/ListWidget.cpp @@ -439,11 +439,6 @@ bool ListWidget::handleKeyDown(Common::KeyState state) { _scrollBar->draw(); } -#if !defined(PALMOS_MODE) - // not done on PalmOS because keyboard is emulated and keyup is not generated - _currentKeyDown = state.keycode; -#endif - return handled; } diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 30bacbb617..b491b12065 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -44,10 +44,6 @@ #include "gui/ThemeEval.h" #include "gui/ThemeParser.h" -#if defined(MACOSX) || defined(IPHONE) -#include <CoreFoundation/CoreFoundation.h> -#endif - #define GUI_ENABLE_BUILTIN_THEME namespace GUI { @@ -169,6 +165,7 @@ static const DrawDataInfo kDrawDataDefaults[] = { {kDDMainDialogBackground, "mainmenu_bg", true, kDDNone}, {kDDSpecialColorBackground, "special_bg", true, kDDNone}, {kDDPlainColorBackground, "plain_bg", true, kDDNone}, + {kDDTooltipBackground, "tooltip_bg", true, kDDNone}, {kDDDefaultBackground, "default_bg", true, kDDNone}, {kDDTextSelectionBackground, "text_selection", false, kDDNone}, {kDDTextSelectionFocusBackground, "text_selection_focus", false, kDDNone}, @@ -396,15 +393,23 @@ bool ThemeEngine::init() { // Try to create a Common::Archive with the files of the theme. if (!_themeArchive && !_themeFile.empty()) { Common::FSNode node(_themeFile); - if (node.getName().hasSuffix(".zip") && !node.isDirectory()) { - Common::Archive *zipArchive = Common::makeZipArchive(node); - - if (!zipArchive) { - warning("Failed to open Zip archive '%s'.", node.getPath().c_str()); - } - _themeArchive = zipArchive; - } else if (node.isDirectory()) { + if (node.isDirectory()) { _themeArchive = new Common::FSDirectory(node); + } else if (_themeFile.hasSuffix(".zip")) { + // TODO: Also use "node" directly? + // Look for the zip file via SearchMan + Common::ArchiveMemberPtr member = SearchMan.getMember(_themeFile); + if (member) { + _themeArchive = Common::makeZipArchive(member->createReadStream()); + if (!_themeArchive) { + warning("Failed to open Zip archive '%s'.", member->getDisplayName().c_str()); + } + } else { + _themeArchive = Common::makeZipArchive(node); + if (!_themeArchive) { + warning("Failed to open Zip archive '%s'.", node.getPath().c_str()); + } + } } } @@ -980,6 +985,10 @@ void ThemeEngine::drawDialogBackground(const Common::Rect &r, DialogBackground b queueDD(kDDPlainColorBackground, r); break; + case kDialogBackgroundTooltip: + queueDD(kDDTooltipBackground, r); + break; + case kDialogBackgroundDefault: queueDD(kDDDefaultBackground, r); break; @@ -1058,12 +1067,16 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co if (i == active) continue; + if (r.left + i * tabWidth > r.right || r.left + (i + 1) * tabWidth > r.right) + continue; + Common::Rect tabRect(r.left + i * tabWidth, r.top, r.left + (i + 1) * tabWidth, r.top + tabHeight); queueDD(kDDTabInactive, tabRect); queueDDText(getTextData(kDDTabInactive), getTextColor(kDDTabInactive), tabRect, tabs[i], false, false, _widgets[kDDTabInactive]->_textAlignH, _widgets[kDDTabInactive]->_textAlignV); } - if (active >= 0) { + if (active >= 0 && + (r.left + active * tabWidth < r.right) && (r.left + (active + 1) * tabWidth < r.right)) { Common::Rect tabRect(r.left + active * tabWidth, r.top, r.left + (active + 1) * tabWidth, r.top + tabHeight); const uint16 tabLeft = active * tabWidth; const uint16 tabRight = MAX(r.right - tabRect.right, 0); @@ -1225,7 +1238,7 @@ void ThemeEngine::restoreState(StoredState *state) { src += state->backBuffer.pitch; dst += _backBuffer.pitch; } - + addDirtyRect(state->r); } @@ -1553,6 +1566,28 @@ bool ThemeEngine::themeConfigParseHeader(Common::String header, Common::String & return tok.empty(); } +bool ThemeEngine::themeConfigUsable(const Common::ArchiveMember &member, Common::String &themeName) { + Common::File stream; + bool foundHeader = false; + + if (member.getName().hasSuffix(".zip")) { + Common::Archive *zipArchive = Common::makeZipArchive(member.createReadStream()); + + if (zipArchive && zipArchive->hasFile("THEMERC")) { + stream.open("THEMERC", *zipArchive); + } + + delete zipArchive; + } + + if (stream.isOpen()) { + Common::String stxHeader = stream.readLine(); + foundHeader = themeConfigParseHeader(stxHeader, themeName); + } + + return foundHeader; +} + bool ThemeEngine::themeConfigUsable(const Common::FSNode &node, Common::String &themeName) { Common::File stream; bool foundHeader = false; @@ -1608,26 +1643,7 @@ void ThemeEngine::listUsableThemes(Common::List<ThemeDescriptor> &list) { if (ConfMan.hasKey("themepath")) listUsableThemes(Common::FSNode(ConfMan.get("themepath")), list); -#ifdef DATA_PATH - listUsableThemes(Common::FSNode(DATA_PATH), list); -#endif - -#if defined(MACOSX) || defined(IPHONE) - CFURLRef resourceUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - if (resourceUrl) { - char buf[256]; - if (CFURLGetFileSystemRepresentation(resourceUrl, true, (UInt8 *)buf, 256)) { - Common::FSNode resourcePath(buf); - listUsableThemes(resourcePath, list); - } - CFRelease(resourceUrl); - } -#endif - - if (ConfMan.hasKey("extrapath")) - listUsableThemes(Common::FSNode(ConfMan.get("extrapath")), list); - - listUsableThemes(Common::FSNode("."), list, 1); + listUsableThemes(SearchMan, list); // Now we need to strip all duplicates // TODO: It might not be the best idea to strip duplicates. The user might @@ -1646,6 +1662,32 @@ void ThemeEngine::listUsableThemes(Common::List<ThemeDescriptor> &list) { output.clear(); } +void ThemeEngine::listUsableThemes(Common::Archive &archive, Common::List<ThemeDescriptor> &list) { + ThemeDescriptor td; + + Common::ArchiveMemberList fileList; + archive.listMatchingMembers(fileList, "*.zip"); + for (Common::ArchiveMemberList::iterator i = fileList.begin(); + i != fileList.end(); ++i) { + td.name.clear(); + if (themeConfigUsable(**i, td.name)) { + td.filename = (*i)->getName(); + td.id = (*i)->getDisplayName(); + + // If the name of the node object also contains + // the ".zip" suffix, we will strip it. + if (td.id.hasSuffix(".zip")) { + for (int j = 0; j < 4; ++j) + td.id.deleteLastChar(); + } + + list.push_back(td); + } + } + + fileList.clear(); +} + void ThemeEngine::listUsableThemes(const Common::FSNode &node, Common::List<ThemeDescriptor> &list, int depth) { if (!node.exists() || !node.isReadable() || !node.isDirectory()) return; diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index f0d4e2585d..f736559def 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -61,6 +61,7 @@ enum DrawData { kDDMainDialogBackground, kDDSpecialColorBackground, kDDPlainColorBackground, + kDDTooltipBackground, kDDDefaultBackground, kDDTextSelectionBackground, kDDTextSelectionFocusBackground, @@ -162,6 +163,7 @@ public: kDialogBackgroundMain, kDialogBackgroundSpecial, kDialogBackgroundPlain, + kDialogBackgroundTooltip, kDialogBackgroundDefault }; @@ -583,11 +585,13 @@ public: static void listUsableThemes(Common::List<ThemeDescriptor> &list); private: static bool themeConfigUsable(const Common::FSNode &node, Common::String &themeName); + static bool themeConfigUsable(const Common::ArchiveMember &member, Common::String &themeName); static bool themeConfigParseHeader(Common::String header, Common::String &themeName); static Common::String getThemeFile(const Common::String &id); static Common::String getThemeId(const Common::String &filename); static void listUsableThemes(const Common::FSNode &node, Common::List<ThemeDescriptor> &list, int depth = -1); + static void listUsableThemes(Common::Archive &archive, Common::List<ThemeDescriptor> &list); protected: OSystem *_system; /** Global system object. */ diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index 4cabf6ad2e..c809447cbd 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -365,10 +365,8 @@ bool ThemeParser::parserCallback_drawdata(ParserNode *node) { if (_theme->addDrawData(node->values["id"], cached) == false) return parserError("Error adding Draw Data set: Invalid DrawData name."); - if (_defaultStepLocal) { - delete _defaultStepLocal; - _defaultStepLocal = 0; - } + delete _defaultStepLocal; + _defaultStepLocal = 0; return true; } diff --git a/gui/Tooltip.cpp b/gui/Tooltip.cpp new file mode 100644 index 0000000000..64c34688df --- /dev/null +++ b/gui/Tooltip.cpp @@ -0,0 +1,101 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + */ + +#include "common/util.h" +#include "graphics/fontman.h" +#include "gui/widget.h" +#include "gui/dialog.h" +#include "gui/GuiManager.h" + +#include "gui/Tooltip.h" +#include "gui/ThemeEval.h" + +namespace GUI { + + +Tooltip::Tooltip() : + Dialog(-1, -1, -1, -1), _maxWidth(-1) { + + _backgroundType = GUI::ThemeEngine::kDialogBackgroundTooltip; +} + +void Tooltip::mustClose() { + if (isVisible()) + Dialog::close(); +} + +bool Tooltip::tooltipModal(int x, int y) { + Widget *wdg; + + if (!g_gui.getTopDialog()) + return false; + + wdg = g_gui.getTopDialog()->findWidget(x, y); + + if (!wdg || !wdg->getTooltip()) + return false; + + if (_maxWidth == -1) { + _maxWidth = g_gui.xmlEval()->getVar("Globals.Tooltip.MaxWidth", 100); + _xdelta = g_gui.xmlEval()->getVar("Globals.Tooltip.XDelta", 0); + _ydelta = g_gui.xmlEval()->getVar("Globals.Tooltip.YDelta", 0); + } + + const Graphics::Font *tooltipFont = g_gui.theme()->getFont(ThemeEngine::kFontStyleTooltip); + + _wrappedLines.clear(); + _w = tooltipFont->wordWrapText(wdg->getTooltip(), _maxWidth - 4, _wrappedLines); + _h = (tooltipFont->getFontHeight() + 2) * _wrappedLines.size(); + + _x = MIN<int16>(g_gui.getTopDialog()->_x + x + _xdelta, g_gui.getWidth() - _w - 3); + _y = MIN<int16>(g_gui.getTopDialog()->_y + y + _ydelta, g_gui.getHeight() - _h - 3); + + open(); + g_gui.runLoop(); + + return true; +} + +void Tooltip::drawDialog() { + int num = 0; + int h = g_gui.theme()->getFontHeight(ThemeEngine::kFontStyleTooltip) + 2; + + Dialog::drawDialog(); + + for (Common::StringArray::const_iterator i = _wrappedLines.begin(); i != _wrappedLines.end(); ++i, ++num) { + g_gui.theme()->drawText( + Common::Rect(_x + 1, _y + 1 + num * h, _x + 1 +_w, _y + 1+ (num + 1) * h), *i, + ThemeEngine::kStateEnabled, + Graphics::kTextAlignLeft, + ThemeEngine::kTextInversionNone, + 0, + false, + ThemeEngine::kFontStyleTooltip, + ThemeEngine::kFontColorNormal, + false + ); + } +} + +} diff --git a/backends/platform/PalmOS/Src/init_sony.h b/gui/Tooltip.h index 86224283f6..60f3cf3a19 100644 --- a/backends/platform/PalmOS/Src/init_sony.h +++ b/gui/Tooltip.h @@ -8,33 +8,43 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * $URL$ * $Id$ - * */ -#ifndef INIT_SONY_H -#define INIT_SONY_H +#ifndef GUI_TOOLTIP_H +#define GUI_TOOLTIP_H + +#include "gui/dialog.h" -#define SONY_PORTRAIT 1 -#define SONY_LANDSCAPE 2 +namespace GUI { -UInt16 SilkInit(UInt32 *retVersion); -void SilkRelease(UInt16 slkRefNum); +class Tooltip : public Dialog { +public: + Tooltip(); + ~Tooltip() {} + + void drawDialog(); + bool tooltipModal(int x, int y); + void mustClose(); -UInt16 SonyHRInit(UInt32 depth); -void SonyHRRelease(UInt16 HRrefNum); +protected: + Common::String _text; + int _maxWidth; + int _xdelta, _ydelta; -UInt8 SonyScreenSize(UInt16 HRrefNum, Coord *stdw, Coord *stdh, Coord *fullw, Coord *fullh); + Common::StringArray _wrappedLines; +}; +} #endif diff --git a/gui/console.cpp b/gui/console.cpp index a2aa56f5b3..a53e97888b 100644 --- a/gui/console.cpp +++ b/gui/console.cpp @@ -669,11 +669,7 @@ int ConsoleDialog::printf(const char *format, ...) { } int ConsoleDialog::vprintf(const char *format, va_list argptr) { -#ifdef PALMOS_MODE - char buf[256]; -#else char buf[2048]; -#endif #if defined(WIN32) int count = _vsnprintf(buf, sizeof(buf), format, argptr); diff --git a/gui/credits.h b/gui/credits.h index ae658e1196..c0e1870226 100644 --- a/gui/credits.h +++ b/gui/credits.h @@ -213,9 +213,6 @@ static const char *credits[] = { "C1""Nintendo DS", "C0""Neil Millstone", "", -"C1""PalmOS", -"C0""Chris Apers", -"", "C1""PocketPC / WinCE", "C0""Nicolas Bacca", "C2""(retired)", @@ -286,6 +283,8 @@ static const char *credits[] = { "C2""Wiki editor", "", "C1""Retired Team Members", +"C0""Chris Apers", +"C2""Former PalmOS porter", "C0""Ralph Brorsen", "C2""Help with GUI implementation", "C0""Jamieson Christian", diff --git a/gui/debugger.cpp b/gui/debugger.cpp index 13dc02452d..9bd3b35915 100644 --- a/gui/debugger.cpp +++ b/gui/debugger.cpp @@ -39,9 +39,8 @@ namespace GUI { Debugger::Debugger() { - _frame_countdown = 0; - _detach_now = false; - _isAttached = false; + _frameCountdown = 0; + _isActive = false; _errStr = NULL; _firstTime = true; #ifndef USE_TEXT_CONSOLE @@ -50,6 +49,10 @@ Debugger::Debugger() { _debuggerDialog->setCompletionCallback(debuggerCompletionCallback, this); #endif + // Register variables + DVar_Register("debug_countdown", &_frameCountdown, DVAR_INT, 0); + + // Register commands //DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); DCmd_Register("exit", WRAP_METHOD(Debugger, Cmd_Exit)); DCmd_Register("quit", WRAP_METHOD(Debugger, Cmd_Exit)); @@ -84,40 +87,32 @@ int Debugger::DebugPrintf(const char *format, ...) { } void Debugger::attach(const char *entry) { - g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); - if (entry) { - _errStr = strdup(entry); - } + // Set error string (if any) + free(_errStr); + _errStr = entry ? strdup(entry) : 0; - _frame_countdown = 1; - _detach_now = false; - _isAttached = true; + // Reset frame countdown (i.e. attach immediately) + _frameCountdown = 1; } void Debugger::detach() { g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); - - _detach_now = false; - _isAttached = false; } // Temporary execution handler void Debugger::onFrame() { - if (_frame_countdown == 0) - return; - --_frame_countdown; - - if (!_frame_countdown) { - - preEnter(); - enter(); - postEnter(); - - // Detach if we're finished with the debugger - if (_detach_now) - detach(); + // Count down until 0 is reached + if (_frameCountdown > 0) { + --_frameCountdown; + if (_frameCountdown == 0) { + _isActive = true; + preEnter(); + enter(); + postEnter(); + _isActive = false; + } } } @@ -250,8 +245,8 @@ bool Debugger::parseCommand(const char *inputOrig) { } else { int element = atoi(chr+1); int32 *var = *(int32 **)_dvars[i].variable; - if (element >= _dvars[i].optional) { - DebugPrintf("%s is out of range (array is %d elements big)\n", param[0], _dvars[i].optional); + if (element >= _dvars[i].arraySize) { + DebugPrintf("%s is out of range (array is %d elements big)\n", param[0], _dvars[i].arraySize); } else { var[element] = atoi(param[1]); DebugPrintf("(int)%s = %d\n", param[0], var[element]); @@ -281,8 +276,8 @@ bool Debugger::parseCommand(const char *inputOrig) { } else { int element = atoi(chr+1); const int32 *var = *(const int32 **)_dvars[i].variable; - if (element >= _dvars[i].optional) { - DebugPrintf("%s is out of range (array is %d elements big)\n", param[0], _dvars[i].optional); + if (element >= _dvars[i].arraySize) { + DebugPrintf("%s is out of range (array is %d elements big)\n", param[0], _dvars[i].arraySize); } else { DebugPrintf("(int)%s = %d\n", param[0], var[element]); } @@ -383,7 +378,7 @@ char *Debugger::readlineComplete(const char *input, int state) { #endif // Variable registration function -void Debugger::DVar_Register(const Common::String &varname, void *pointer, int type, int optional) { +void Debugger::DVar_Register(const Common::String &varname, void *pointer, VarType type, int arraySize) { // TODO: Filter out duplicates // TODO: Sort this list? Then we can do binary search later on when doing lookups. assert(pointer); @@ -392,7 +387,7 @@ void Debugger::DVar_Register(const Common::String &varname, void *pointer, int t tmp.name = varname; tmp.type = type; tmp.variable = pointer; - tmp.optional = optional; + tmp.arraySize = arraySize; _dvars.push_back(tmp); } @@ -406,7 +401,7 @@ void Debugger::DCmd_Register(const Common::String &cmdname, Debuglet *debuglet) // Detach ("exit") the debugger bool Debugger::Cmd_Exit(int argc, const char **argv) { - _detach_now = true; + detach(); return false; } diff --git a/gui/debugger.h b/gui/debugger.h index 07fdddb808..6f06befdf1 100644 --- a/gui/debugger.h +++ b/gui/debugger.h @@ -43,20 +43,46 @@ public: int DebugPrintf(const char *format, ...); + /** + * The onFrame() method should be invoked by the engine at regular + * intervals (usually once per main loop iteration) whenever the + * debugger is attached. + * This will open up the console and accept user input if certain + * preconditions are met, such as the frame countdown having + * reached zero. + * + * Subclasses can override this to e.g. check for breakpoints being + * triggered. + */ virtual void onFrame(); + /** + * 'Attach' the debugger. This ensures that the next time onFrame() + * is invoked, the debugger will activate and accept user input. + */ virtual void attach(const char *entry = 0); - bool isAttached() const { return _isAttached; } + + /** + * Return true if the debugger is currently active (i.e. executing + * a command or waiting for use input). + */ + bool isActive() const { return _isActive; } protected: typedef Common::Functor2<int, const char **, bool> Debuglet; - // Convenience macro for registering a method of a debugger class - // as the current command. + /** + * Convenience macro that makes it either to register a method + * of a debugger subclass as a command. + * Usage example: + * DCmd_Register("COMMAND", WRAP_METHOD(MyDebugger, MyCmd)); + * would register the method MyDebugger::MyCmd(int, const char **) + * under the command name "COMMAND". + */ #define WRAP_METHOD(cls, method) \ new Common::Functor2Mem<int, const char **, bool, cls>(this, &cls::method) - enum { + enum VarType { DVAR_BYTE, DVAR_INT, DVAR_BOOL, @@ -67,50 +93,100 @@ protected: struct DVar { Common::String name; void *variable; - int type; - int optional; + VarType type; + int arraySize; }; - int _frame_countdown; - bool _detach_now; + + /** + * Register a variable with the debugger. This allows the user to read and modify + * this variable. + * @param varname the identifier with which the user may access the variable + * @param variable pointer to the actual storage of the variable + * @param type the type of the variable (byte, int, bool, ...) + * @paral arraySize for type DVAR_INTARRAY this specifies the size of the array + * + * @todo replace this single method by type safe variants. + */ + void DVar_Register(const Common::String &varname, void *variable, VarType type, int arraySize); + void DCmd_Register(const Common::String &cmdname, Debuglet *debuglet); + private: + /** + * The frame countdown specifies a number of frames that must pass + * until the console will show up. This value is decremented by one + * each time onFrame() is called, until it reaches 0, at which point + * onFrame() will open the console and handle input into it. + * + * The user can modify this value using the debug_countdown command. + * + * Note: The console must be in *attached* state, otherwise, it + * won't show up (and the countdown won't count down either). + */ + uint _frameCountdown; + Common::Array<DVar> _dvars; typedef Common::HashMap<Common::String, Common::SharedPtr<Debuglet>, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> CommandsMap; CommandsMap _cmds; - bool _isAttached; + /** + * True if the debugger is currently active (i.e. executing + * a command or waiting for use input). + */ + bool _isActive; + char *_errStr; + + /** + * Initially true, set to false when Debugger::enter is called + * the first time. We use this flag to show a greeting message + * to the user once, when he opens the debugger for the first + * time. + */ bool _firstTime; + #ifndef USE_TEXT_CONSOLE GUI::ConsoleDialog *_debuggerDialog; #endif protected: - // Hook for subclasses: Called just before enter() is run + /** + * Hook for subclasses which is called just before enter() is run. + * A typical usage example is pausing music and sound effects. + */ virtual void preEnter() {} - // Hook for subclasses: Called just after enter() was run + /** + * Hook for subclasses which is called just after enter() was run. + * A typical usage example is resuming music and sound effects. + */ virtual void postEnter() {} - // Hook for subclasses: Process the given command line. - // Should return true if and only if argv[0] is a known command and was - // handled, false otherwise. - virtual bool handleCommand(int argc, const char **argv, bool &keepRunning); - + /** + * Subclasses should invoke the detach() method in their Cmd_FOO methods + * if that command will resume execution of the program (as opposed to + * executing, say, a "single step through code" command). + * + * This currently only hides the virtual keyboard, if any. + */ + void detach(); private: - void detach(); void enter(); bool parseCommand(const char *input); bool tabComplete(const char *input, Common::String &completion) const; -protected: - void DVar_Register(const Common::String &varname, void *pointer, int type, int optional); - void DCmd_Register(const Common::String &cmdname, Debuglet *debuglet); + /** + * Process the given command line. + * Returns true if and only if argv[0] is a known command and was + * handled, false otherwise. + */ + virtual bool handleCommand(int argc, const char **argv, bool &keepRunning); +protected: bool Cmd_Exit(int argc, const char **argv); bool Cmd_Help(int argc, const char **argv); bool Cmd_DebugFlagsList(int argc, const char **argv); diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 1daf9ffd50..d50e7ce578 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -72,6 +72,7 @@ enum { kCmdGlobalGraphicsOverride = 'OGFX', kCmdGlobalAudioOverride = 'OSFX', kCmdGlobalMIDIOverride = 'OMID', + kCmdGlobalMT32Override = 'OM32', kCmdGlobalVolumeOverride = 'OVOL', kCmdChooseSoundFontCmd = 'chsf', @@ -144,6 +145,7 @@ protected: CheckboxWidget *_globalGraphicsOverride; CheckboxWidget *_globalAudioOverride; CheckboxWidget *_globalMIDIOverride; + CheckboxWidget *_globalMT32Override; CheckboxWidget *_globalVolumeOverride; }; @@ -199,7 +201,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc) } // - // 3) The graphics tab + // 2) The graphics tab // _graphicsTabId = tab->addTab(g_system->getOverlayWidth() > 320 ? _("Graphics") : _("GFX")); @@ -208,7 +210,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc) addGraphicControls(tab, "GameOptions_Graphics."); // - // 4) The audio tab + // 3) The audio tab // tab->addTab(_("Audio")); @@ -218,7 +220,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc) addSubtitleControls(tab, "GameOptions_Audio."); // - // 5) The volume tab + // 4) The volume tab // tab->addTab(_("Volume")); @@ -227,7 +229,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc) addVolumeControls(tab, "GameOptions_Volume."); // - // 6) The MIDI tab + // 5) The MIDI tab // tab->addTab(_("MIDI")); @@ -239,7 +241,19 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc) addMIDIControls(tab, "GameOptions_MIDI."); // - // 2) The 'Path' tab + // 6) The MT-32 tab + // + tab->addTab(_("MT-32")); + + _globalMT32Override = new CheckboxWidget(tab, "GameOptions_MT32.EnableTabCheckbox", _("Override global MT-32 settings"), 0, kCmdGlobalMT32Override); + + //if (_guioptions & Common::GUIO_NOMIDI) + // _globalMT32Override->setEnabled(false); + + addMT32Controls(tab, "GameOptions_MT32."); + + // + // 7) The Paths tab // tab->addTab(_("Paths")); @@ -305,11 +319,13 @@ void EditGameDialog::open() { e = ConfMan.hasKey("soundfont", _domain) || ConfMan.hasKey("multi_midi", _domain) || - ConfMan.hasKey("native_mt32", _domain) || - ConfMan.hasKey("enable_gs", _domain) || ConfMan.hasKey("midi_gain", _domain); _globalMIDIOverride->setState(e); + e = ConfMan.hasKey("native_mt32", _domain) || + ConfMan.hasKey("enable_gs", _domain); + _globalMT32Override->setState(e); + // TODO: game path const Common::Language lang = Common::parseLanguage(ConfMan.get("language", _domain)); @@ -383,6 +399,10 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat setMIDISettingsState(data != 0); draw(); break; + case kCmdGlobalMT32Override: + setMT32SettingsState(data != 0); + draw(); + break; case kCmdGlobalVolumeOverride: setVolumeSettingsState(data != 0); draw(); diff --git a/gui/module.mk b/gui/module.mk index 9bf1a08d4b..72b5fa18f3 100644 --- a/gui/module.mk +++ b/gui/module.mk @@ -25,6 +25,7 @@ MODULE_OBJS := \ ThemeEval.o \ ThemeLayout.o \ ThemeParser.o \ + Tooltip.o \ widget.o ifdef MACOSX diff --git a/gui/options.cpp b/gui/options.cpp index 856eb668fa..d3bda228a7 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -100,13 +100,14 @@ void OptionsDialog::init() { _aspectCheckbox = 0; _enableAudioSettings = false; _midiPopUp = 0; - _mt32DevicePopUp = 0; - _gmDevicePopUp = 0; _oplPopUp = 0; _outputRatePopUp = 0; _enableMIDISettings = false; + _gmDevicePopUp = 0; _multiMidiCheckbox = 0; + _enableMT32Settings = false; _mt32Checkbox = 0; + _mt32DevicePopUp = 0; _enableGSCheckbox = 0; _enableVolumeSettings = false; _musicVolumeDesc = 0; @@ -197,24 +198,6 @@ void OptionsDialog::open() { if (!loadMusicDeviceSetting(_midiPopUp, "music_driver")) _midiPopUp->setSelected(0); - if (!loadMusicDeviceSetting(_mt32DevicePopUp, "mt32_device")) { - if (_domain.equals(Common::ConfigManager::kApplicationDomain)) { - if (!loadMusicDeviceSetting(_mt32DevicePopUp, Common::String(), MT_MT32)) - _mt32DevicePopUp->setSelected(0); - } else { - _mt32DevicePopUp->setSelected(0); - } - } - - if (!loadMusicDeviceSetting(_gmDevicePopUp, "gm_device")) { - if (_domain.equals(Common::ConfigManager::kApplicationDomain)) { - if (!loadMusicDeviceSetting(_gmDevicePopUp, Common::String(), MT_GM)) - _gmDevicePopUp->setSelected(0); - } else { - _gmDevicePopUp->setSelected(0); - } - } - if (_oplPopUp) { OPL::Config::DriverId id = MAX<OPL::Config::DriverId>(OPL::Config::parse(ConfMan.get("opl_driver", _domain)), 0); _oplPopUp->setSelectedTag(id); @@ -230,16 +213,18 @@ void OptionsDialog::open() { } if (_multiMidiCheckbox) { + if (!loadMusicDeviceSetting(_gmDevicePopUp, "gm_device")) { + if (_domain.equals(Common::ConfigManager::kApplicationDomain)) { + if (!loadMusicDeviceSetting(_gmDevicePopUp, Common::String(), MT_GM)) + _gmDevicePopUp->setSelected(0); + } else { + _gmDevicePopUp->setSelected(0); + } + } // Multi midi setting _multiMidiCheckbox->setState(ConfMan.getBool("multi_midi", _domain)); - // Native mt32 setting - _mt32Checkbox->setState(ConfMan.getBool("native_mt32", _domain)); - - // GS extensions setting - _enableGSCheckbox->setState(ConfMan.getBool("enable_gs", _domain)); - Common::String soundFont(ConfMan.get("soundfont", _domain)); if (soundFont.empty() || !ConfMan.hasKey("soundfont", _domain)) { _soundFont->setLabel(_("None")); @@ -257,6 +242,24 @@ void OptionsDialog::open() { _midiGainLabel->setLabel(buf); } + // MT-32 options + if (_mt32DevicePopUp) { + if (!loadMusicDeviceSetting(_mt32DevicePopUp, "mt32_device")) { + if (_domain.equals(Common::ConfigManager::kApplicationDomain)) { + if (!loadMusicDeviceSetting(_mt32DevicePopUp, Common::String(), MT_MT32)) + _mt32DevicePopUp->setSelected(0); + } else { + _mt32DevicePopUp->setSelected(0); + } + } + + // Native mt32 setting + _mt32Checkbox->setState(ConfMan.getBool("native_mt32", _domain)); + + // GS extensions setting + _enableGSCheckbox->setState(ConfMan.getBool("enable_gs", _domain)); + } + // Volume options if (_musicVolumeSlider) { int vol; @@ -353,12 +356,8 @@ void OptionsDialog::close() { if (_midiPopUp) { if (_enableAudioSettings) { saveMusicDeviceSetting(_midiPopUp, "music_driver"); - saveMusicDeviceSetting(_mt32DevicePopUp, "mt32_device"); - saveMusicDeviceSetting(_gmDevicePopUp, "gm_device"); } else { ConfMan.removeKey("music_driver", _domain); - ConfMan.removeKey("mt32_device", _domain); - ConfMan.removeKey("gm_device", _domain); } } @@ -391,9 +390,9 @@ void OptionsDialog::close() { // MIDI options if (_multiMidiCheckbox) { if (_enableMIDISettings) { + saveMusicDeviceSetting(_gmDevicePopUp, "gm_device"); + ConfMan.setBool("multi_midi", _multiMidiCheckbox->getState(), _domain); - ConfMan.setBool("native_mt32", _mt32Checkbox->getState(), _domain); - ConfMan.setBool("enable_gs", _enableGSCheckbox->getState(), _domain); ConfMan.setInt("midi_gain", _midiGainSlider->getValue(), _domain); Common::String soundFont(_soundFont->getLabel()); @@ -402,14 +401,26 @@ void OptionsDialog::close() { else ConfMan.removeKey("soundfont", _domain); } else { + ConfMan.removeKey("gm_device", _domain); ConfMan.removeKey("multi_midi", _domain); - ConfMan.removeKey("native_mt32", _domain); - ConfMan.removeKey("enable_gs", _domain); ConfMan.removeKey("midi_gain", _domain); ConfMan.removeKey("soundfont", _domain); } } + // MT-32 options + if (_mt32DevicePopUp) { + if (_enableMT32Settings) { + saveMusicDeviceSetting(_mt32DevicePopUp, "mt32_device"); + ConfMan.setBool("native_mt32", _mt32Checkbox->getState(), _domain); + ConfMan.setBool("enable_gs", _enableGSCheckbox->getState(), _domain); + } else { + ConfMan.removeKey("mt32_device", _domain); + ConfMan.removeKey("native_mt32", _domain); + ConfMan.removeKey("enable_gs", _domain); + } + } + // Subtitle options if (_subToggleGroup) { if (_enableSubtitleSettings) { @@ -513,10 +524,6 @@ void OptionsDialog::setAudioSettingsState(bool enabled) { _enableAudioSettings = enabled; _midiPopUpDesc->setEnabled(enabled); _midiPopUp->setEnabled(enabled); - _mt32DevicePopUpDesc->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); - _mt32DevicePopUp->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); - _gmDevicePopUpDesc->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); - _gmDevicePopUp->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); uint32 allFlags = MidiDriver::musicType2GUIO((uint32)-1); @@ -537,6 +544,9 @@ void OptionsDialog::setMIDISettingsState(bool enabled) { if (_guioptions & Common::GUIO_NOMIDI) enabled = false; + _gmDevicePopUpDesc->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); + _gmDevicePopUp->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); + _enableMIDISettings = enabled; _soundFontButton->setEnabled(enabled); @@ -548,13 +558,21 @@ void OptionsDialog::setMIDISettingsState(bool enabled) { _soundFontClearButton->setEnabled(false); _multiMidiCheckbox->setEnabled(enabled); - _mt32Checkbox->setEnabled(enabled); - _enableGSCheckbox->setEnabled(enabled); _midiGainDesc->setEnabled(enabled); _midiGainSlider->setEnabled(enabled); _midiGainLabel->setEnabled(enabled); } +void OptionsDialog::setMT32SettingsState(bool enabled) { + _enableMT32Settings = enabled; + + _mt32DevicePopUpDesc->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); + _mt32DevicePopUp->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); + + _mt32Checkbox->setEnabled(enabled); + _enableGSCheckbox->setEnabled(enabled); +} + void OptionsDialog::setVolumeSettingsState(bool enabled) { bool ena; @@ -645,11 +663,6 @@ void OptionsDialog::addAudioControls(GuiObject *boss, const Common::String &pref _midiPopUpDesc = new StaticTextWidget(boss, prefix + "auMidiPopupDesc", _domain == Common::ConfigManager::kApplicationDomain ? _("Preferred Device:") : _("Music Device:"), _domain == Common::ConfigManager::kApplicationDomain ? _("Specifies preferred sound device or sound card emulator") : _("Specifies output sound device or sound card emulator")); _midiPopUp = new PopUpWidget(boss, prefix + "auMidiPopup", _("Specifies output sound device or sound card emulator")); - _mt32DevicePopUpDesc = new StaticTextWidget(boss, prefix + "auPrefMt32PopupDesc", _("MT-32 Device:"), _("Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output")); - _mt32DevicePopUp = new PopUpWidget(boss, prefix + "auPrefMt32Popup"); - _gmDevicePopUpDesc = new StaticTextWidget(boss, prefix + "auPrefGmPopupDesc", _("GM Device:"), _("Specifies default sound device for General MIDI output")); - _gmDevicePopUp = new PopUpWidget(boss, prefix + "auPrefGmPopup"); - // Populate it uint32 allFlags = MidiDriver::musicType2GUIO((uint32)-1); @@ -657,27 +670,20 @@ void OptionsDialog::addAudioControls(GuiObject *boss, const Common::String &pref for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { MusicDevices i = (**m)->getDevices(); for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + const uint32 deviceGuiOption = MidiDriver::musicType2GUIO(d->getMusicType()); + if ((_domain == Common::ConfigManager::kApplicationDomain && d->getMusicType() != MT_TOWNS) // global dialog - skip useless FM-Towns option there || (_domain != Common::ConfigManager::kApplicationDomain && !(_guioptions & allFlags)) // No flags are specified - || _guioptions & (MidiDriver::musicType2GUIO(d->getMusicType())) // flag is present + || (_guioptions & deviceGuiOption) // flag is present + // HACK/FIXME: For now we have to show GM devices, even when the game only has GUIO_MIDIMT32 set, + // else we would not show for example external devices connected via ALSA, since they are always + // marked as General MIDI device. + || (deviceGuiOption == Common::GUIO_MIDIGM && (_guioptions & Common::GUIO_MIDIMT32)) || d->getMusicDriverId() == "auto" || d->getMusicDriverId() == "null") // always add default and null device _midiPopUp->appendEntry(d->getCompleteName(), d->getHandle()); - - if (d->getMusicType() >= MT_GM || d->getMusicDriverId() == "auto") { - _mt32DevicePopUp->appendEntry(d->getCompleteName(), d->getHandle()); - if (d->getMusicType() != MT_MT32) - _gmDevicePopUp->appendEntry(d->getCompleteName(), d->getHandle()); - } } } - if (!_domain.equals(Common::ConfigManager::kApplicationDomain)) { - _mt32DevicePopUpDesc->setEnabled(false); - _mt32DevicePopUp->setEnabled(false); - _gmDevicePopUpDesc->setEnabled(false); - _gmDevicePopUp->setEnabled(false); - } - // The OPL emulator popup & a label _oplPopUpDesc = new StaticTextWidget(boss, prefix + "auOPLPopupDesc", _("AdLib emulator:"), _("AdLib is used for music in many games")); _oplPopUp = new PopUpWidget(boss, prefix + "auOPLPopup", _("AdLib is used for music in many games")); @@ -701,6 +707,26 @@ void OptionsDialog::addAudioControls(GuiObject *boss, const Common::String &pref } void OptionsDialog::addMIDIControls(GuiObject *boss, const Common::String &prefix) { + _gmDevicePopUpDesc = new StaticTextWidget(boss, prefix + "auPrefGmPopupDesc", _("GM Device:"), _("Specifies default sound device for General MIDI output")); + _gmDevicePopUp = new PopUpWidget(boss, prefix + "auPrefGmPopup"); + + // Populate + const MusicPlugin::List p = MusicMan.getPlugins(); + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + if (d->getMusicType() >= MT_GM || d->getMusicDriverId() == "auto") { + if (d->getMusicType() != MT_MT32) + _gmDevicePopUp->appendEntry(d->getCompleteName(), d->getHandle()); + } + } + } + + if (!_domain.equals(Common::ConfigManager::kApplicationDomain)) { + _gmDevicePopUpDesc->setEnabled(false); + _gmDevicePopUp->setEnabled(false); + } + // SoundFont _soundFontButton = new ButtonWidget(boss, prefix + "mcFontButton", _("SoundFont:"), _("SoundFont is supported by some audio cards, Fluidsynth and Timidity"), kChooseSoundFontCmd); _soundFont = new StaticTextWidget(boss, prefix + "mcFontPath", _("None"), _("SoundFont is supported by some audio cards, Fluidsynth and Timidity")); @@ -709,12 +735,6 @@ void OptionsDialog::addMIDIControls(GuiObject *boss, const Common::String &prefi // Multi midi setting _multiMidiCheckbox = new CheckboxWidget(boss, prefix + "mcMixedCheckbox", _("Mixed AdLib/MIDI mode"), _("Use both MIDI and AdLib sound generation")); - // Native mt32 setting - _mt32Checkbox = new CheckboxWidget(boss, prefix + "mcMt32Checkbox", _("True Roland MT-32 (disable GM emulation)"), _("Check if you want to use your real hardware Roland-compatible sound device connected to your computer")); - - // GS Extensions setting - _enableGSCheckbox = new CheckboxWidget(boss, prefix + "mcGSCheckbox", _("Enable Roland GS Mode"), _("Turns off General MIDI mapping for games with Roland MT-32 soundtrack")); - // MIDI gain setting (FluidSynth uses this) _midiGainDesc = new StaticTextWidget(boss, prefix + "mcMidiGainText", _("MIDI gain:")); _midiGainSlider = new SliderWidget(boss, prefix + "mcMidiGainSlider", 0, kMidiGainChanged); @@ -725,6 +745,34 @@ void OptionsDialog::addMIDIControls(GuiObject *boss, const Common::String &prefi _enableMIDISettings = true; } +void OptionsDialog::addMT32Controls(GuiObject *boss, const Common::String &prefix) { + _mt32DevicePopUpDesc = new StaticTextWidget(boss, prefix + "auPrefMt32PopupDesc", _("MT-32 Device:"), _("Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output")); + _mt32DevicePopUp = new PopUpWidget(boss, prefix + "auPrefMt32Popup"); + + // Native mt32 setting + _mt32Checkbox = new CheckboxWidget(boss, prefix + "mcMt32Checkbox", _("True Roland MT-32 (disable GM emulation)"), _("Check if you want to use your real hardware Roland-compatible sound device connected to your computer")); + + // GS Extensions setting + _enableGSCheckbox = new CheckboxWidget(boss, prefix + "mcGSCheckbox", _("Enable Roland GS Mode"), _("Turns off General MIDI mapping for games with Roland MT-32 soundtrack")); + + const MusicPlugin::List p = MusicMan.getPlugins(); + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + if (d->getMusicType() >= MT_GM || d->getMusicDriverId() == "auto") { + _mt32DevicePopUp->appendEntry(d->getCompleteName(), d->getHandle()); + } + } + } + + if (!_domain.equals(Common::ConfigManager::kApplicationDomain)) { + _mt32DevicePopUpDesc->setEnabled(false); + _mt32DevicePopUp->setEnabled(false); + } + + _enableMIDISettings = true; +} + // The function has an extra slider range parameter, since both the launcher and SCUMM engine // make use of the widgets. The launcher range is 0-255. SCUMM's 0-9 void OptionsDialog::addSubtitleControls(GuiObject *boss, const Common::String &prefix, int maxSliderVal) { @@ -790,7 +838,7 @@ bool OptionsDialog::loadMusicDeviceSetting(PopUpWidget *popup, Common::String se return true; if (_domain != Common::ConfigManager::kApplicationDomain || ConfMan.hasKey(setting, _domain) || preferredType) { - const Common::String drv = ConfMan.get(setting, (_domain != Common::ConfigManager::kApplicationDomain && !ConfMan.hasKey(setting, _domain)) ? Common::ConfigManager::kApplicationDomain : _domain); + const Common::String drv = ConfMan.get(setting, (_domain != Common::ConfigManager::kApplicationDomain && !ConfMan.hasKey(setting, _domain)) ? Common::ConfigManager::kApplicationDomain : _domain); const MusicPlugin::List p = MusicMan.getPlugins(); for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { @@ -810,7 +858,7 @@ bool OptionsDialog::loadMusicDeviceSetting(PopUpWidget *popup, Common::String se void OptionsDialog::saveMusicDeviceSetting(PopUpWidget *popup, Common::String setting) { if (!popup || !_enableAudioSettings) return; - + const MusicPlugin::List p = MusicMan.getPlugins(); bool found = false; for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end() && !found; ++m) { @@ -886,7 +934,13 @@ GlobalOptionsDialog::GlobalOptionsDialog() addMIDIControls(tab, "GlobalOptions_MIDI."); // - // 4) The miscellaneous tab + // 4) The MT-32 tab + // + tab->addTab(_("MT-32")); + addMT32Controls(tab, "GlobalOptions_MT32."); + + // + // 5) The Paths tab // tab->addTab(_("Paths")); @@ -910,6 +964,9 @@ GlobalOptionsDialog::GlobalOptionsDialog() #endif #endif + // + // 6) The miscellaneous tab + // tab->addTab(_("Misc")); new ButtonWidget(tab, "GlobalOptions_Misc.ThemeButton", _("Theme:"), 0, kChooseThemeCmd); diff --git a/gui/options.h b/gui/options.h index 235cb24462..c05f263d00 100644 --- a/gui/options.h +++ b/gui/options.h @@ -68,6 +68,7 @@ protected: void addGraphicControls(GuiObject *boss, const Common::String &prefix); void addAudioControls(GuiObject *boss, const Common::String &prefix); void addMIDIControls(GuiObject *boss, const Common::String &prefix); + void addMT32Controls(GuiObject *boss, const Common::String &prefix); void addVolumeControls(GuiObject *boss, const Common::String &prefix); // The default value is the launcher's non-scaled talkspeed value. When SCUMM uses the widget, // it uses its own scale @@ -76,6 +77,7 @@ protected: void setGraphicSettingsState(bool enabled); void setAudioSettingsState(bool enabled); void setMIDISettingsState(bool enabled); + void setMT32SettingsState(bool enabled); void setVolumeSettingsState(bool enabled); void setSubtitleSettingsState(bool enabled); @@ -120,13 +122,18 @@ private: // bool _enableMIDISettings; CheckboxWidget *_multiMidiCheckbox; - CheckboxWidget *_mt32Checkbox; - CheckboxWidget *_enableGSCheckbox; StaticTextWidget *_midiGainDesc; SliderWidget *_midiGainSlider; StaticTextWidget *_midiGainLabel; // + // MT-32 controls + // + bool _enableMT32Settings; + CheckboxWidget *_mt32Checkbox; + CheckboxWidget *_enableGSCheckbox; + + // // Subtitle controls // int getSubtitleMode(bool subtitles, bool speech_mute); diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 086fecc123..f03b3fc61e 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -1,5 +1,5 @@ "<?xml version = '1.0'?>" -"<layout_info resolution='320xY,256x240,Xx272'> " +"<layout_info resolution='320xY,256x240,Xx272,Xx350'> " "<globals> " "<def var='Line.Height' value='12' /> " "<def var='Font.Height' value='10' /> " @@ -57,11 +57,11 @@ "padding='0,0,2,0' " "/> " "<widget name='TabWidget.Body' " -"padding='0,0,0,0' " +"padding='0,0,0,-8' " "/> " "<widget name='TabWidget.NavButton' " "size='32,18' " -"padding='0,3,4,0' " +"padding='0,0,1,0' " "/> " "</globals> " "<dialog name='Launcher' overlays='screen'> " @@ -190,22 +190,6 @@ "/> " "</layout> " "<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " -"<widget name='auPrefMt32PopupDesc' " -"type='OptionsLabel' " -"/> " -"<widget name='auPrefMt32Popup' " -"type='PopUp' " -"/> " -"</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " -"<widget name='auPrefGmPopupDesc' " -"type='OptionsLabel' " -"/> " -"<widget name='auPrefGmPopup' " -"type='PopUp' " -"/> " -"</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auOPLPopupDesc' " "type='OptionsLabel' " "/> " @@ -293,6 +277,14 @@ "</dialog> " "<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<widget name='auPrefGmPopupDesc' " +"type='OptionsLabel' " +"/> " +"<widget name='auPrefGmPopup' " +"type='PopUp' " +"/> " +"</layout> " "<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='mcFontButton' " "type='Button' " @@ -308,12 +300,6 @@ "<widget name='mcMixedCheckbox' " "type='Checkbox' " "/> " -"<widget name='mcMt32Checkbox' " -"type='Checkbox' " -"/> " -"<widget name='mcGSCheckbox' " -"type='Checkbox' " -"/> " "<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='mcMidiGainText' " "type='OptionsLabel' " @@ -328,6 +314,24 @@ "</layout> " "</layout> " "</dialog> " +"<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<widget name='auPrefMt32PopupDesc' " +"type='OptionsLabel' " +"/> " +"<widget name='auPrefMt32Popup' " +"type='PopUp' " +"/> " +"</layout> " +"<widget name='mcMt32Checkbox' " +"type='Checkbox' " +"/> " +"<widget name='mcGSCheckbox' " +"type='Checkbox' " +"/> " +"</layout> " +"</dialog> " "<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<layout type='horizontal' padding='0,0,0,0' spacing='16'> " @@ -471,6 +475,14 @@ "<import layout='Dialog.GlobalOptions_MIDI' /> " "</layout> " "</dialog> " +"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<widget name='EnableTabCheckbox' " +"type='Checkbox' " +"/> " +"<import layout='Dialog.GlobalOptions_MT32' /> " +"</layout> " +"</dialog> " "<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " @@ -776,440 +788,7 @@ "</layout> " "</dialog> " "</layout_info> " -"<render_info> " -"<palette> " -"<color name='black' " -"rgb='0,0,0' " -"/> " -"<color name='lightgrey' " -"rgb='104,104,104' " -"/> " -"<color name='darkgrey' " -"rgb='64,64,64' " -"/> " -"<color name='green' " -"rgb='32,160,32' " -"/> " -"<color name='green2' " -"rgb='0,255,0' " -"/> " -"</palette> " -"<fonts> " -"<font id='text_default' " -"file='helvb12.bdf' " -"/> " -"<font resolution='320xY,256x240' " -"id='text_default' " -"file='clR6x12.bdf' " -"/> " -"<font id='text_button' " -"file='helvb12.bdf' " -"/> " -"<font resolution='320xY,256x240' " -"id='text_button' " -"file='clR6x12.bdf' " -"/> " -"<font id='text_normal' " -"file='helvb12.bdf' " -"/> " -"<font resolution='320xY,256x240' " -"id='text_normal' " -"file='clR6x12.bdf' " -"/> " -"<font id='tooltip_normal' " -"file='fixed5x8.bdf' " -"/> " -"<text_color id='color_normal' " -"color='green' " -"/> " -"<text_color id='color_normal_inverted' " -"color='black' " -"/> " -"<text_color id='color_normal_hover' " -"color='green2' " -"/> " -"<text_color id='color_normal_disabled' " -"color='lightgrey' " -"/> " -"<text_color id='color_alternative' " -"color='lightgrey' " -"/> " -"<text_color id='color_alternative_inverted' " -"color='255,255,255' " -"/> " -"<text_color id='color_alternative_hover' " -"color='176,176,176' " -"/> " -"<text_color id='color_alternative_disabled' " -"color='darkgrey' " -"/> " -"<text_color id='color_button' " -"color='green' " -"/> " -"<text_color id='color_button_hover' " -"color='green2' " -"/> " -"<text_color id='color_button_disabled' " -"color='lightgrey' " -"/> " -"</fonts> " -"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/> " -"<drawdata id='text_selection' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='lightgrey' " -"/> " -"</drawdata> " -"<drawdata id='text_selection_focus' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='mainmenu_bg' cache='false'> " -"<drawstep func='fill' " -"fill='foreground' " -"fg_color='black' " -"/> " -"</drawdata> " -"<drawdata id='special_bg' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='separator' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"height='2' " -"ypos='center' " -"fg_color='lightgrey' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_base' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_handle_hover' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green2' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_handle_idle' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_button_idle' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green' " -"fill='foreground' " -"width='auto' " -"height='auto' " -"xpos='center' " -"ypos='center' " -"orientation='top' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_button_hover' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green2' " -"fill='foreground' " -"width='auto' " -"height='auto' " -"xpos='center' " -"ypos='center' " -"orientation='top' " -"/> " -"</drawdata> " -"<drawdata id='tab_active' cache='false'> " -"<text font='text_default' " -"text_color='color_normal_hover' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='tab' " -"bevel='2' " -"radius='0' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='tab_inactive' cache='false'> " -"<text font='text_default' " -"text_color='color_normal' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='tab' " -"bevel='2' " -"radius='0' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='tab_background' cache='false'> " -"</drawdata> " -"<drawdata id='widget_slider' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='slider_disabled' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='lightgrey' " -"/> " -"</drawdata> " -"<drawdata id='slider_full' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='slider_hover' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green2' " -"/> " -"</drawdata> " -"<drawdata id='widget_small' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='popup_idle' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green' " -"fill='foreground' " -"width='height' " -"height='auto' " -"xpos='right' " -"ypos='center' " -"orientation='bottom' " -"/> " -"<text font='text_default' " -"text_color='color_normal' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"</drawdata> " -"<drawdata id='popup_disabled' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='lightgrey' " -"fill='foreground' " -"width='height' " -"height='auto' " -"xpos='right' " -"ypos='center' " -"orientation='bottom' " -"/> " -"<text font='text_default' " -"text_color='color_normal_disabled' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"</drawdata> " -"<drawdata id='popup_hover' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green2' " -"fill='foreground' " -"width='height' " -"height='auto' " -"xpos='right' " -"ypos='center' " -"orientation='bottom' " -"/> " -"<text font='text_default' " -"text_color='color_normal_hover' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"</drawdata> " -"<drawdata id='widget_textedit' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='plain_bg' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='caret' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='lightgrey' " -"/> " -"</drawdata> " -"<drawdata id='default_bg' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='button_idle' cache='false'> " -"<text font='text_button' " -"text_color='color_button' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='button_hover' cache='false'> " -"<text font='text_button' " -"text_color='color_button_hover' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='button_disabled' cache='false'> " -"<text font='text_button' " -"text_color='color_button_disabled' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='checkbox_disabled' cache='false'> " -"<text font='text_default' " -"text_color='color_normal_disabled' " -"vertical_align='top' " -"horizontal_align='left' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='checkbox_selected' cache='false'> " -"<text font='text_default' " -"text_color='color_normal' " -"vertical_align='top' " -"horizontal_align='left' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='cross' " -"fill='foreground' " -"stroke='2' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='checkbox_default' cache='false'> " -"<text font='text_default' " -"text_color='color_normal' " -"vertical_align='top' " -"horizontal_align='left' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='radiobutton_default' cache='false'> " -"<text font='text_default' " -"text_color='color_normal' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"<drawstep func='circle' " -"width='7' " -"height='7' " -"radius='7' " -"fill='background' " -"bg_color='darkgrey' " -"xpos='0' " -"ypos='0' " -"/> " -"</drawdata> " -"<drawdata id='radiobutton_selected' cache='false'> " -"<text font='text_default' " -"text_color='color_normal' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"<drawstep func='circle' " -"width='7' " -"height='7' " -"radius='7' " -"fg_color='darkgrey' " -"fill='none' " -"xpos='0' " -"ypos='0' " -"/> " -"<drawstep func='circle' " -"width='7' " -"height='7' " -"radius='5' " -"fg_color='green' " -"fill='foreground' " -"xpos='2' " -"ypos='2' " -"/> " -"</drawdata> " -"<drawdata id='radiobutton_disabled' cache='false'> " -"<text font='text_default' " -"text_color='color_normal_disabled' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"<drawstep func='circle' " -"width='7' " -"height='7' " -"radius='7' " -"bg_color='lightgrey' " -"fill='background' " -"xpos='0' " -"ypos='0' " -"/> " -"</drawdata> " -"<drawdata id='widget_default' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='widget_small' cache='false'> " -"<drawstep func='square' " -"stroke='0' " -"/> " -"</drawdata> " -"</render_info> " -"<layout_info resolution='-320xY,-256x240,-Xx272'> " +"<layout_info resolution='-320xY,-256x240,-Xx272,-Xx350'> " "<globals> " "<def var='Line.Height' value='16' /> " "<def var='Font.Height' value='16' /> " @@ -1404,22 +983,6 @@ "/> " "</layout> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " -"<widget name='auPrefMt32PopupDesc' " -"type='OptionsLabel' " -"/> " -"<widget name='auPrefMt32Popup' " -"type='PopUp' " -"/> " -"</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " -"<widget name='auPrefGmPopupDesc' " -"type='OptionsLabel' " -"/> " -"<widget name='auPrefGmPopup' " -"type='PopUp' " -"/> " -"</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auOPLPopupDesc' " "type='OptionsLabel' " "/> " @@ -1509,6 +1072,14 @@ "<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<widget name='auPrefGmPopupDesc' " +"type='OptionsLabel' " +"/> " +"<widget name='auPrefGmPopup' " +"type='PopUp' " +"/> " +"</layout> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='mcFontButton' " "type='Button' " "/> " @@ -1523,12 +1094,6 @@ "<widget name='mcMixedCheckbox' " "type='Checkbox' " "/> " -"<widget name='mcMt32Checkbox' " -"type='Checkbox' " -"/> " -"<widget name='mcGSCheckbox' " -"type='Checkbox' " -"/> " "<layout type='horizontal' padding='0,0,0,0'> " "<widget name='mcMidiGainText' " "type='OptionsLabel' " @@ -1543,6 +1108,24 @@ "</layout> " "</layout> " "</dialog> " +"<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<widget name='auPrefMt32PopupDesc' " +"type='OptionsLabel' " +"/> " +"<widget name='auPrefMt32Popup' " +"type='PopUp' " +"/> " +"</layout> " +"<widget name='mcMt32Checkbox' " +"type='Checkbox' " +"/> " +"<widget name='mcGSCheckbox' " +"type='Checkbox' " +"/> " +"</layout> " +"</dialog> " "<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " @@ -1680,6 +1263,14 @@ "<import layout='Dialog.GlobalOptions_MIDI' /> " "</layout> " "</dialog> " +"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<widget name='EnableTabCheckbox' " +"type='Checkbox' " +"/> " +"<import layout='Dialog.GlobalOptions_MT32' /> " +"</layout> " +"</dialog> " "<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " @@ -1984,3 +1575,443 @@ "</layout> " "</dialog> " "</layout_info> " +"<render_info> " +"<palette> " +"<color name='black' " +"rgb='0,0,0' " +"/> " +"<color name='lightgrey' " +"rgb='104,104,104' " +"/> " +"<color name='darkgrey' " +"rgb='64,64,64' " +"/> " +"<color name='green' " +"rgb='32,160,32' " +"/> " +"<color name='green2' " +"rgb='0,255,0' " +"/> " +"</palette> " +"<fonts> " +"<font id='text_default' " +"file='helvb12.bdf' " +"/> " +"<font resolution='320xY,256x240' " +"id='text_default' " +"file='clR6x12.bdf' " +"/> " +"<font id='text_button' " +"file='helvb12.bdf' " +"/> " +"<font resolution='320xY,256x240' " +"id='text_button' " +"file='clR6x12.bdf' " +"/> " +"<font id='text_normal' " +"file='helvb12.bdf' " +"/> " +"<font resolution='320xY,256x240' " +"id='text_normal' " +"file='clR6x12.bdf' " +"/> " +"<font id='tooltip_normal' " +"file='fixed5x8.bdf' " +"/> " +"<text_color id='color_normal' " +"color='green' " +"/> " +"<text_color id='color_normal_inverted' " +"color='black' " +"/> " +"<text_color id='color_normal_hover' " +"color='green2' " +"/> " +"<text_color id='color_normal_disabled' " +"color='lightgrey' " +"/> " +"<text_color id='color_alternative' " +"color='lightgrey' " +"/> " +"<text_color id='color_alternative_inverted' " +"color='255,255,255' " +"/> " +"<text_color id='color_alternative_hover' " +"color='176,176,176' " +"/> " +"<text_color id='color_alternative_disabled' " +"color='darkgrey' " +"/> " +"<text_color id='color_button' " +"color='green' " +"/> " +"<text_color id='color_button_hover' " +"color='green2' " +"/> " +"<text_color id='color_button_disabled' " +"color='lightgrey' " +"/> " +"</fonts> " +"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/> " +"<drawdata id='text_selection' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='text_selection_focus' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='mainmenu_bg' cache='false'> " +"<drawstep func='fill' " +"fill='foreground' " +"fg_color='black' " +"/> " +"</drawdata> " +"<drawdata id='special_bg' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='tooltip_bg' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='foreground' " +"fg_color='black' " +"/> " +"</drawdata> " +"<drawdata id='separator' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"height='2' " +"ypos='center' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_base' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_handle_hover' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green2' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_handle_idle' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_button_idle' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green' " +"fill='foreground' " +"width='auto' " +"height='auto' " +"xpos='center' " +"ypos='center' " +"orientation='top' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_button_hover' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green2' " +"fill='foreground' " +"width='auto' " +"height='auto' " +"xpos='center' " +"ypos='center' " +"orientation='top' " +"/> " +"</drawdata> " +"<drawdata id='tab_active' cache='false'> " +"<text font='text_default' " +"text_color='color_normal_hover' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='tab' " +"bevel='2' " +"radius='0' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='tab_inactive' cache='false'> " +"<text font='text_default' " +"text_color='color_normal' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='tab' " +"bevel='2' " +"radius='0' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='tab_background' cache='false'> " +"</drawdata> " +"<drawdata id='widget_slider' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='slider_disabled' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='slider_full' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='slider_hover' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green2' " +"/> " +"</drawdata> " +"<drawdata id='widget_small' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='popup_idle' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green' " +"fill='foreground' " +"width='height' " +"height='auto' " +"xpos='right' " +"ypos='center' " +"orientation='bottom' " +"/> " +"<text font='text_default' " +"text_color='color_normal' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"</drawdata> " +"<drawdata id='popup_disabled' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='lightgrey' " +"fill='foreground' " +"width='height' " +"height='auto' " +"xpos='right' " +"ypos='center' " +"orientation='bottom' " +"/> " +"<text font='text_default' " +"text_color='color_normal_disabled' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"</drawdata> " +"<drawdata id='popup_hover' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green2' " +"fill='foreground' " +"width='height' " +"height='auto' " +"xpos='right' " +"ypos='center' " +"orientation='bottom' " +"/> " +"<text font='text_default' " +"text_color='color_normal_hover' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"</drawdata> " +"<drawdata id='widget_textedit' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='plain_bg' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='caret' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='default_bg' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='button_idle' cache='false'> " +"<text font='text_button' " +"text_color='color_button' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='button_hover' cache='false'> " +"<text font='text_button' " +"text_color='color_button_hover' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='button_disabled' cache='false'> " +"<text font='text_button' " +"text_color='color_button_disabled' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='checkbox_disabled' cache='false'> " +"<text font='text_default' " +"text_color='color_normal_disabled' " +"vertical_align='top' " +"horizontal_align='left' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='checkbox_selected' cache='false'> " +"<text font='text_default' " +"text_color='color_normal' " +"vertical_align='top' " +"horizontal_align='left' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='cross' " +"fill='foreground' " +"stroke='2' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='checkbox_default' cache='false'> " +"<text font='text_default' " +"text_color='color_normal' " +"vertical_align='top' " +"horizontal_align='left' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='radiobutton_default' cache='false'> " +"<text font='text_default' " +"text_color='color_normal' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"<drawstep func='circle' " +"width='7' " +"height='7' " +"radius='7' " +"fill='background' " +"bg_color='darkgrey' " +"xpos='0' " +"ypos='0' " +"/> " +"</drawdata> " +"<drawdata id='radiobutton_selected' cache='false'> " +"<text font='text_default' " +"text_color='color_normal' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"<drawstep func='circle' " +"width='7' " +"height='7' " +"radius='7' " +"fg_color='darkgrey' " +"fill='none' " +"xpos='0' " +"ypos='0' " +"/> " +"<drawstep func='circle' " +"width='7' " +"height='7' " +"radius='5' " +"fg_color='green' " +"fill='foreground' " +"xpos='2' " +"ypos='2' " +"/> " +"</drawdata> " +"<drawdata id='radiobutton_disabled' cache='false'> " +"<text font='text_default' " +"text_color='color_normal_disabled' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"<drawstep func='circle' " +"width='7' " +"height='7' " +"radius='7' " +"bg_color='lightgrey' " +"fill='background' " +"xpos='0' " +"ypos='0' " +"/> " +"</drawdata> " +"<drawdata id='widget_default' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='widget_small' cache='false'> " +"<drawstep func='square' " +"stroke='0' " +"/> " +"</drawdata> " +"</render_info> " diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip Binary files differindex b5866337ad..299bc41339 100644 --- a/gui/themes/scummclassic.zip +++ b/gui/themes/scummclassic.zip diff --git a/gui/themes/scummclassic/classic_gfx.stx b/gui/themes/scummclassic/classic_gfx.stx index 8c03aa932c..d672db2540 100644 --- a/gui/themes/scummclassic/classic_gfx.stx +++ b/gui/themes/scummclassic/classic_gfx.stx @@ -142,6 +142,14 @@ /> </drawdata> + <drawdata id = 'tooltip_bg' cache = 'false'> + <drawstep func = 'bevelsq' + bevel = '2' + fill = 'foreground' + fg_color = 'black' + /> + </drawdata> + <drawdata id = 'separator' cache = 'false'> <drawstep func = 'square' fill = 'foreground' diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx index 80bc4bf41e..74b8bf4b2c 100644 --- a/gui/themes/scummclassic/classic_layout.stx +++ b/gui/themes/scummclassic/classic_layout.stx @@ -23,7 +23,7 @@ - $Id$ - --> -<layout_info resolution = '-320xY, -256x240, -Xx272'> +<layout_info resolution = '-320xY, -256x240, -Xx272, -Xx350'> <globals> <def var = 'Line.Height' value = '16' /> <def var = 'Font.Height' value = '16' /> @@ -232,22 +232,6 @@ /> </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> - <widget name = 'auPrefMt32PopupDesc' - type = 'OptionsLabel' - /> - <widget name = 'auPrefMt32Popup' - type = 'PopUp' - /> - </layout> - <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> - <widget name = 'auPrefGmPopupDesc' - type = 'OptionsLabel' - /> - <widget name = 'auPrefGmPopup' - type = 'PopUp' - /> - </layout> - <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> <widget name = 'auOPLPopupDesc' type = 'OptionsLabel' /> @@ -339,6 +323,14 @@ <dialog name = 'GlobalOptions_MIDI' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> + <widget name = 'auPrefGmPopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefGmPopup' + type = 'PopUp' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> <widget name = 'mcFontButton' type = 'Button' /> @@ -353,12 +345,6 @@ <widget name = 'mcMixedCheckbox' type = 'Checkbox' /> - <widget name = 'mcMt32Checkbox' - type = 'Checkbox' - /> - <widget name = 'mcGSCheckbox' - type = 'Checkbox' - /> <layout type = 'horizontal' padding = '0, 0, 0, 0'> <widget name = 'mcMidiGainText' type = 'OptionsLabel' @@ -374,6 +360,25 @@ </layout> </dialog> + <dialog name = 'GlobalOptions_MT32' overlays = 'Dialog.GlobalOptions.TabWidget'> + <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> + <widget name = 'auPrefMt32PopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefMt32Popup' + type = 'PopUp' + /> + </layout> + <widget name = 'mcMt32Checkbox' + type = 'Checkbox' + /> + <widget name = 'mcGSCheckbox' + type = 'Checkbox' + /> + </layout> + </dialog> + <dialog name = 'GlobalOptions_Paths' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> @@ -518,6 +523,15 @@ </layout> </dialog> + <dialog name = 'GameOptions_MT32' overlays = 'Dialog.GlobalOptions.TabWidget'> + <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> + <widget name = 'EnableTabCheckbox' + type = 'Checkbox' + /> + <import layout = 'Dialog.GlobalOptions_MT32' /> + </layout> + </dialog> + <dialog name = 'GameOptions_Volume' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> <widget name = 'EnableTabCheckbox' diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx index 64ac6e200a..622c23439e 100644 --- a/gui/themes/scummclassic/classic_layout_lowres.stx +++ b/gui/themes/scummclassic/classic_layout_lowres.stx @@ -23,7 +23,7 @@ - $Id$ - --> -<layout_info resolution = "320xY, 256x240, Xx272"> +<layout_info resolution = "320xY, 256x240, Xx272, Xx350"> <globals> <def var = 'Line.Height' value = '12' /> <def var = 'Font.Height' value = '10' /> @@ -90,11 +90,11 @@ padding = '0, 0, 2, 0' /> <widget name = 'TabWidget.Body' - padding = '0, 0, 0, 0' + padding = '0, 0, 0, -8' /> <widget name = 'TabWidget.NavButton' size = '32, 18' - padding = '0, 3, 4, 0' + padding = '0, 0, 1, 0' /> </globals> @@ -230,22 +230,6 @@ /> </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> - <widget name = 'auPrefMt32PopupDesc' - type = 'OptionsLabel' - /> - <widget name = 'auPrefMt32Popup' - type = 'PopUp' - /> - </layout> - <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> - <widget name = 'auPrefGmPopupDesc' - type = 'OptionsLabel' - /> - <widget name = 'auPrefGmPopup' - type = 'PopUp' - /> - </layout> - <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> <widget name = 'auOPLPopupDesc' type = 'OptionsLabel' /> @@ -335,6 +319,14 @@ <dialog name = 'GlobalOptions_MIDI' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> + <widget name = 'auPrefGmPopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefGmPopup' + type = 'PopUp' + /> + </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'> <widget name = 'mcFontButton' type = 'Button' @@ -350,12 +342,6 @@ <widget name = 'mcMixedCheckbox' type = 'Checkbox' /> - <widget name = 'mcMt32Checkbox' - type = 'Checkbox' - /> - <widget name = 'mcGSCheckbox' - type = 'Checkbox' - /> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> <widget name = 'mcMidiGainText' type = 'OptionsLabel' @@ -371,6 +357,25 @@ </layout> </dialog> + <dialog name = 'GlobalOptions_MT32' overlays = 'Dialog.GlobalOptions.TabWidget'> + <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> + <widget name = 'auPrefMt32PopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefMt32Popup' + type = 'PopUp' + /> + </layout> + <widget name = 'mcMt32Checkbox' + type = 'Checkbox' + /> + <widget name = 'mcGSCheckbox' + type = 'Checkbox' + /> + </layout> + </dialog> + <dialog name = 'GlobalOptions_Paths' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16'> @@ -521,6 +526,15 @@ </layout> </dialog> + <dialog name = 'GameOptions_MT32' overlays = 'Dialog.GlobalOptions.TabWidget'> + <layout type = 'vertical' padding = '8, 8, 8, 8' spacing = '6'> + <widget name = 'EnableTabCheckbox' + type = 'Checkbox' + /> + <import layout = 'Dialog.GlobalOptions_MT32' /> + </layout> + </dialog> + <dialog name = 'GameOptions_Volume' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '8, 8, 8, 8' spacing = '6'> <widget name = 'EnableTabCheckbox' diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip Binary files differindex aba0c944c3..cd24d781bb 100644 --- a/gui/themes/scummmodern.zip +++ b/gui/themes/scummmodern.zip diff --git a/gui/themes/scummmodern/helvr12-l1.fcc b/gui/themes/scummmodern/helvb12-iso-8859-1.fcc Binary files differindex 651a25934a..651a25934a 100644 --- a/gui/themes/scummmodern/helvr12-l1.fcc +++ b/gui/themes/scummmodern/helvb12-iso-8859-1.fcc diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx index ad41475a96..cfe00a7016 100644 --- a/gui/themes/scummmodern/scummmodern_gfx.stx +++ b/gui/themes/scummmodern/scummmodern_gfx.stx @@ -516,6 +516,15 @@ /> </drawdata> + <!-- Tooltip --> + <drawdata id = 'tooltip_bg' cache = 'false'> + <drawstep func = 'square' + fill = 'foreground' + fg_color = 'blandyellow' + shadow = '3' + /> + </drawdata> + <!-- Idle button --> <drawdata id = 'button_idle' cache = 'false'> <text font = 'text_button' diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx index 796d4d9a94..484dd15429 100644 --- a/gui/themes/scummmodern/scummmodern_layout.stx +++ b/gui/themes/scummmodern/scummmodern_layout.stx @@ -23,7 +23,7 @@ - $Id$ - --> -<layout_info resolution = '-320xY, -256x240, -Xx272'> +<layout_info resolution = '-320xY, -256x240, -Xx272, -Xx350'> <globals> <def var = 'Line.Height' value = '16' /> <def var = 'Font.Height' value = '16' /> @@ -247,22 +247,6 @@ /> </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> - <widget name = 'auPrefMt32PopupDesc' - type = 'OptionsLabel' - /> - <widget name = 'auPrefMt32Popup' - type = 'PopUp' - /> - </layout> - <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> - <widget name = 'auPrefGmPopupDesc' - type = 'OptionsLabel' - /> - <widget name = 'auPrefGmPopup' - type = 'PopUp' - /> - </layout> - <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> <widget name = 'auOPLPopupDesc' type = 'OptionsLabel' /> @@ -354,6 +338,14 @@ <dialog name = 'GlobalOptions_MIDI' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> + <widget name = 'auPrefGmPopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefGmPopup' + type = 'PopUp' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> <widget name = 'mcFontButton' type = 'Button' /> @@ -368,12 +360,6 @@ <widget name = 'mcMixedCheckbox' type = 'Checkbox' /> - <widget name = 'mcMt32Checkbox' - type = 'Checkbox' - /> - <widget name = 'mcGSCheckbox' - type = 'Checkbox' - /> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> <widget name = 'mcMidiGainText' type = 'OptionsLabel' @@ -389,6 +375,25 @@ </layout> </dialog> + <dialog name = 'GlobalOptions_MT32' overlays = 'Dialog.GlobalOptions.TabWidget'> + <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> + <widget name = 'auPrefMt32PopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefMt32Popup' + type = 'PopUp' + /> + </layout> + <widget name = 'mcMt32Checkbox' + type = 'Checkbox' + /> + <widget name = 'mcGSCheckbox' + type = 'Checkbox' + /> + </layout> + </dialog> + <dialog name = 'GlobalOptions_Paths' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> @@ -533,6 +538,15 @@ </layout> </dialog> + <dialog name = 'GameOptions_MT32' overlays = 'Dialog.GlobalOptions.TabWidget'> + <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> + <widget name = 'EnableTabCheckbox' + type = 'Checkbox' + /> + <import layout = 'Dialog.GlobalOptions_MT32' /> + </layout> + </dialog> + <dialog name = 'GameOptions_Volume' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> <widget name = 'EnableTabCheckbox' diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx index 8bb31e9f8a..5998c50b60 100644 --- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx +++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx @@ -23,7 +23,7 @@ - $Id$ - --> -<layout_info resolution = "320xY, 256x240, Xx272"> +<layout_info resolution = "320xY, 256x240, Xx272, Xx350"> <globals> <def var = 'Line.Height' value = '12' /> <def var = 'Font.Height' value = '10' /> @@ -88,11 +88,11 @@ padding = '0, 0, 2, 0' /> <widget name = 'TabWidget.Body' - padding = '0, 0, 0, 0' + padding = '0, 0, 0, -8' /> <widget name = 'TabWidget.NavButton' size = '32, 18' - padding = '0, 3, 4, 0' + padding = '0, 0, 2, 0' /> </globals> @@ -228,22 +228,6 @@ /> </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> - <widget name = 'auPrefMt32PopupDesc' - type = 'OptionsLabel' - /> - <widget name = 'auPrefMt32Popup' - type = 'PopUp' - /> - </layout> - <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> - <widget name = 'auPrefGmPopupDesc' - type = 'OptionsLabel' - /> - <widget name = 'auPrefGmPopup' - type = 'PopUp' - /> - </layout> - <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> <widget name = 'auOPLPopupDesc' type = 'OptionsLabel' /> @@ -333,6 +317,14 @@ <dialog name = 'GlobalOptions_MIDI' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> + <widget name = 'auPrefGmPopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefGmPopup' + type = 'PopUp' + /> + </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'> <widget name = 'mcFontButton' type = 'Button' @@ -348,12 +340,6 @@ <widget name = 'mcMixedCheckbox' type = 'Checkbox' /> - <widget name = 'mcMt32Checkbox' - type = 'Checkbox' - /> - <widget name = 'mcGSCheckbox' - type = 'Checkbox' - /> <layout type = 'horizontal' padding = '0, 0, 0, 0' center = 'true'> <widget name = 'mcMidiGainText' type = 'OptionsLabel' @@ -369,6 +355,25 @@ </layout> </dialog> + <dialog name = 'GlobalOptions_MT32' overlays = 'Dialog.GlobalOptions.TabWidget'> + <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> + <widget name = 'auPrefMt32PopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefMt32Popup' + type = 'PopUp' + /> + </layout> + <widget name = 'mcMt32Checkbox' + type = 'Checkbox' + /> + <widget name = 'mcGSCheckbox' + type = 'Checkbox' + /> + </layout> + </dialog> + <dialog name = 'GlobalOptions_Paths' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'> @@ -519,6 +524,15 @@ </layout> </dialog> + <dialog name = 'GameOptions_MT32' overlays = 'Dialog.GlobalOptions.TabWidget'> + <layout type = 'vertical' padding = '8, 8, 8, 8' spacing = '6'> + <widget name = 'EnableTabCheckbox' + type = 'Checkbox' + /> + <import layout = 'Dialog.GlobalOptions_MT32' /> + </layout> + </dialog> + <dialog name = 'GameOptions_Volume' overlays = 'Dialog.GlobalOptions.TabWidget'> <layout type = 'vertical' padding = '8, 8, 8, 8' spacing = '6'> <widget name = 'EnableTabCheckbox' diff --git a/gui/widget.cpp b/gui/widget.cpp index 14cb61006b..07cf4407a2 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -218,85 +218,8 @@ Common::String Widget::cleanupHotkey(const Common::String &label) { for (uint i = 0; i < label.size() ; i++) if (label[i] != '~') res = res + label[i]; - - return res; -} - -#pragma mark - - -Tooltip::Tooltip(GuiManager *guiManager) : GuiObject(0, 0, 0, 0) { - _guiManager = guiManager; - - _visible = false; - _maxWidth = -1; - _storedState = 0; -} - -void Tooltip::draw() { - int num = 0; - int h = g_gui.theme()->getFontHeight(ThemeEngine::kFontStyleTooltip) + 2; - - // Make Rect bigger for compensating the shadow - _storedState = g_gui.theme()->storeState(Common::Rect(_x - 5, _y - 5, _x + _w + 5, _y + _h + 5)); - - g_gui.theme()->startBuffering(); - g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x + _w, _y + _h), 0, ThemeEngine::kWidgetBackgroundBorderSmall); - - for (Common::StringArray::const_iterator i = _wrappedLines.begin(); i != _wrappedLines.end(); ++i, ++num) { - g_gui.theme()->drawText(Common::Rect(_x + 1, _y + 1 + num * h, _x + 1 +_w, _y + 1+ (num + 1) * h), *i, ThemeEngine::kStateEnabled, Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, 0, false, ThemeEngine::kFontStyleTooltip, ThemeEngine::kFontColorNormal, false); - } - g_gui.theme()->finishBuffering(); -} - -void Tooltip::reflowLayout() { -} - -void Tooltip::setMouseXY(int x, int y) { - _mouseX = x; - _mouseY = y; -} -void Tooltip::setVisible(bool state) { - if (state == _visible) - return; - - if (state) { - if (!_guiManager->getTopDialog()) - return; - - Widget *wdg = _guiManager->getTopDialog()->findWidget(_mouseX, _mouseY); - - if (!wdg) - return; - - if (wdg->getTooltip()) { - _visible = state; - - // Cache config values. - // NOTE: we cannot do it in the consturctor - if (_maxWidth == -1) { - _maxWidth = g_gui.xmlEval()->getVar("Globals.Tooltip.MaxWidth", 100); - _xdelta = g_gui.xmlEval()->getVar("Globals.Tooltip.XDelta", 0); - _ydelta = g_gui.xmlEval()->getVar("Globals.Tooltip.YDelta", 0); - } - - const Graphics::Font *tooltipFont = g_gui.theme()->getFont(ThemeEngine::kFontStyleTooltip); - - _wrappedLines.clear(); - _w = tooltipFont->wordWrapText(wdg->getTooltip(), _maxWidth - 4, _wrappedLines); - _h = (tooltipFont->getFontHeight() + 2) * _wrappedLines.size(); - - _x = MIN<int16>(_guiManager->getTopDialog()->_x + _mouseX + _xdelta, g_gui.getWidth() - _w - 3); - _y = MIN<int16>(_guiManager->getTopDialog()->_y + _mouseY + _ydelta, g_gui.getHeight() - _h - 3); - - draw(); - } - } else { - _visible = state; - - g_gui.theme()->restoreState(_storedState); - delete _storedState; - } + return res; } #pragma mark - @@ -361,7 +284,7 @@ ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Co } ButtonWidget::ButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey) - : StaticTextWidget(boss, name, cleanupHotkey(label), tooltip), CommandSender(boss), + : StaticTextWidget(boss, name, cleanupHotkey(label), tooltip), CommandSender(boss), _cmd(cmd) { if (hotkey == 0) _hotkey = parseHotkey(label); diff --git a/gui/widget.h b/gui/widget.h index 7b5fe9253f..92bfbf8256 100644 --- a/gui/widget.h +++ b/gui/widget.h @@ -159,31 +159,6 @@ protected: void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { assert(_boss); _boss->handleCommand(sender, cmd, data); } }; -class GuiManager; - -class Tooltip : public GuiObject { -public: - Tooltip(GuiManager *guiManager); - - bool isVisible() const { return _visible; } - void draw(); - void reflowLayout(); - void releaseFocus() {} - void setVisible(bool state); - void setMouseXY(int x, int y); - -protected: - Common::String _text; - GuiManager *_guiManager; - bool _visible; - int _mouseX, _mouseY; - int _maxWidth; - int _xdelta, _ydelta; - - Common::StringArray _wrappedLines; - ThemeEngine::StoredState *_storedState; -}; - /* StaticTextWidget */ class StaticTextWidget : public Widget { protected: @@ -272,7 +247,7 @@ class RadiobuttonWidget : public ButtonWidget { protected: bool _state; int _value; - + public: RadiobuttonWidget(GuiObject *boss, int x, int y, int w, int h, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip = 0, uint8 hotkey = 0); RadiobuttonWidget(GuiObject *boss, const Common::String &name, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip = 0, uint8 hotkey = 0); diff --git a/sound/audiostream.cpp b/sound/audiostream.cpp index a092e6c29d..b3efb2cefe 100644 --- a/sound/audiostream.cpp +++ b/sound/audiostream.cpp @@ -393,7 +393,7 @@ Timestamp convertTimeToStreamPos(const Timestamp &where, int rate, bool isStereo // // An example is when converting the timestamp 500ms to a 11025 Hz based // stream. It would have an internal frame counter of 5512.5. Now when - // doing calculations at frame precision, this might lead to unexpected + // doing calculations at frame precision, this might lead to unexpected // results: The frame difference between a timestamp 1000ms and the above // mentioned timestamp (both with 11025 as framerate) would be 5512, // instead of 5513, which is what a frame-precision based code would expect. diff --git a/sound/decoders/aiff.cpp b/sound/decoders/aiff.cpp index b76410f8d1..ce8c6ad32c 100644 --- a/sound/decoders/aiff.cpp +++ b/sound/decoders/aiff.cpp @@ -175,7 +175,9 @@ SeekableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, data = (byte *)malloc(size); assert(data); stream->read(data, size); - delete stream; + + if (disposeAfterUse == DisposeAfterUse::YES) + delete stream; // Since we allocated our own buffer for the data, we must specify DisposeAfterUse::YES. return makeRawStream(data, size, rate, flags); diff --git a/sound/decoders/mac_snd.cpp b/sound/decoders/mac_snd.cpp new file mode 100644 index 0000000000..d6894f1144 --- /dev/null +++ b/sound/decoders/mac_snd.cpp @@ -0,0 +1,116 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +/* + * The code in this file is based on information found at + * http://developer.apple.com/legacy/mac/library/documentation/mac/Sound/Sound-60.html#HEADING60-15 + * + * We implement both type 1 and type 2 snd resources, but only those that are sampled + */ + +#include "common/util.h" +#include "common/stream.h" + +#include "sound/decoders/mac_snd.h" +#include "sound/audiostream.h" +#include "sound/decoders/raw.h" + +namespace Audio { + +SeekableAudioStream *makeMacSndStream(Common::SeekableReadStream *stream, + DisposeAfterUse::Flag disposeAfterUse) { + + uint16 sndType = stream->readUint16BE(); + + if (sndType == 1) { + // "normal" snd resources + if (stream->readUint16BE() != 1) { + warning("makeMacSndStream(): Unsupported data type count"); + return 0; + } + + if (stream->readUint16BE() != 5) { + // 5 == sampled + warning("makeMacSndStream(): Unsupported data type"); + return 0; + } + + stream->readUint32BE(); // initialization option + } else if (sndType == 2) { + // old HyperCard snd resources + stream->readUint16BE(); // reference count (unused) + } else { + warning("makeMacSndStream(): Unknown format type %d", sndType); + return 0; + } + + // We really should never get this as long as we have sampled data only + if (stream->readUint16BE() != 1) { + warning("makeMacSndStream(): Unsupported command count"); + return 0; + } + + uint16 command = stream->readUint16BE(); + + // 0x8050 - soundCmd (with dataOffsetFlag set): install a sampled sound as a voice + // 0x8051 - bufferCmd (with dataOffsetFlag set): play a sample sound + if (command != 0x8050 && command != 0x8051) { + warning("makeMacSndStream(): Unsupported command %04x", command); + return 0; + } + + stream->readUint16BE(); // 0 + uint32 soundHeaderOffset = stream->readUint32BE(); + + stream->seek(soundHeaderOffset); + + uint32 soundDataOffset = stream->readUint32BE(); + uint32 size = stream->readUint32BE(); + uint16 rate = stream->readUint32BE() >> 16; // Really fixed point, but we only support integer rates + stream->readUint32BE(); // loop start + stream->readUint32BE(); // loop end + byte encoding = stream->readByte(); + stream->readByte(); // base frequency + + if (encoding != 0) { + // 0 == PCM + warning("makeMacSndStream(): Unsupported compression %d", encoding); + return 0; + } + + stream->skip(soundDataOffset); + + byte *data = (byte *)malloc(size); + assert(data); + stream->read(data, size); + + if (disposeAfterUse == DisposeAfterUse::YES) + delete stream; + + // Since we allocated our own buffer for the data, we must specify DisposeAfterUse::YES. + return makeRawStream(data, size, rate, Audio::FLAG_UNSIGNED); +} + +} // End of namespace Audio diff --git a/backends/fs/palmos/palmos-fs-factory.h b/sound/decoders/mac_snd.h index 72729c570d..198a61333e 100644 --- a/backends/fs/palmos/palmos-fs-factory.h +++ b/sound/decoders/mac_snd.h @@ -8,42 +8,51 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * $URL$ * $Id$ + * + */ + +/** + * @file + * Sound decoder used in engines: + * - sci */ -#ifndef PALMOS_FILESYSTEM_FACTORY_H -#define PALMOS_FILESYSTEM_FACTORY_H +#ifndef SOUND_MAC_SND_H +#define SOUND_MAC_SND_H + +#include "common/scummsys.h" +#include "common/types.h" -#include "common/singleton.h" -#include "backends/fs/fs-factory.h" +namespace Common { class SeekableReadStream; } + +namespace Audio { + +class SeekableAudioStream; /** - * Creates PalmOSFilesystemNode objects. + * Try to load a Mac snd resource from the given seekable stream and create a SeekableAudioStream + * from that data. * - * Parts of this class are documented in the base interface class, FilesystemFactory. + * @param stream the SeekableReadStream from which to read the snd data + * @param disposeAfterUse whether to delete the stream after use + * @return a new SeekableAudioStream, or NULL, if an error occurred */ -class PalmOSFilesystemFactory : public FilesystemFactory, public Common::Singleton<PalmOSFilesystemFactory> { -public: - virtual AbstractFSNode *makeRootFileNode() const; - virtual AbstractFSNode *makeCurrentDirectoryFileNode() const; - virtual AbstractFSNode *makeFileNodePath(const Common::String &path) const; - -protected: - PalmOSFilesystemFactory() {}; +SeekableAudioStream *makeMacSndStream( + Common::SeekableReadStream *stream, + DisposeAfterUse::Flag disposeAfterUse); -private: - friend class Common::Singleton<SingletonBaseType>; -}; +} // End of namespace Audio -#endif /*PALMOS_FILESYSTEM_FACTORY_H*/ +#endif diff --git a/sound/decoders/mp3.cpp b/sound/decoders/mp3.cpp index 2f0419d35e..e54d646b0a 100644 --- a/sound/decoders/mp3.cpp +++ b/sound/decoders/mp3.cpp @@ -348,13 +348,13 @@ int MP3Stream::readBuffer(int16 *buffer, const int numSamples) { SeekableAudioStream *makeMP3Stream( Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) { - + #if defined(__PSP__) SeekableAudioStream *s = 0; - + if (Mp3PspStream::isOkToCreateStream()) s = new Mp3PspStream(stream, disposeAfterUse); - + if (!s) // go to regular MAD mp3 stream if ME fails s = new MP3Stream(stream, disposeAfterUse); #else diff --git a/sound/mididrv.cpp b/sound/mididrv.cpp index aaff78bf92..c7587992e0 100644 --- a/sound/mididrv.cpp +++ b/sound/mididrv.cpp @@ -94,7 +94,7 @@ MusicType MidiDriver::getMusicType(MidiDriver::DeviceHandle handle) { } } } - + return MT_INVALID; } @@ -139,7 +139,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { if (flags & MDT_PCJR) return hdl; break; - + case MT_CMS: if (flags & MDT_CMS) return hdl; @@ -149,7 +149,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { if (flags & MDT_ADLIB) return hdl; break; - + case MT_TOWNS: if (flags & MDT_TOWNS) return hdl; @@ -261,12 +261,15 @@ MidiDriver::DeviceHandle MidiDriver::getDeviceHandle(const Common::String &ident const MusicPlugin::List p = MusicMan.getPlugins(); if (p.begin() == p.end()) - error("Music plugins must be loaded prior to calling this method."); + error("Music plugins must be loaded prior to calling this method"); for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { MusicDevices i = (**m)->getDevices(); for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { - if (identifier.equals(d->getCompleteId()) || identifier.equals(d->getCompleteName())) { + // The music driver id isn't unique, but it will match + // driver's first device. This is useful when selecting + // the driver from the command line. + if (identifier.equals(d->getMusicDriverId()) || identifier.equals(d->getCompleteId()) || identifier.equals(d->getCompleteName())) { return d->getHandle(); } } diff --git a/sound/mididrv.h b/sound/mididrv.h index 5fffd430fb..1184adee6c 100644 --- a/sound/mididrv.h +++ b/sound/mididrv.h @@ -124,7 +124,7 @@ public: /** Returns device handle based on the present devices and the flags parameter. */ static DeviceHandle detectDevice(int flags); - + /** Find the music driver matching the given driver name/description. */ static DeviceHandle getDeviceHandle(const Common::String &identifier); diff --git a/sound/midiparser.cpp b/sound/midiparser.cpp index d58471765e..929b1d8b12 100644 --- a/sound/midiparser.cpp +++ b/sound/midiparser.cpp @@ -333,7 +333,7 @@ void MidiParser::hangAllActiveNotes() { uint32 advance_tick = _position._last_event_tick; while (true) { - int i, j; + int i; for (i = 0; i < 128; ++i) if (temp_active[i] != 0) break; @@ -349,7 +349,7 @@ void MidiParser::hangAllActiveNotes() { } else if (_next_event.event == 0xFF && _next_event.ext.type == 0x2F) { // warning("MidiParser::hangAllActiveNotes(): Hit End of Track with active notes left"); for (i = 0; i < 128; ++i) { - for (j = 0; j < 16; ++j) { + for (int j = 0; j < 16; ++j) { if (temp_active[i] & (1 << j)) { activeNote(j, i, false); sendToDriver(0x80 | j, i, 0); diff --git a/sound/midiparser_smf.cpp b/sound/midiparser_smf.cpp index 4261b1d770..a9c6f1eb3b 100644 --- a/sound/midiparser_smf.cpp +++ b/sound/midiparser_smf.cpp @@ -230,10 +230,8 @@ bool MidiParser_SMF::loadMusic(byte *data, uint32 size) { // If this is a Type 1 MIDI, we need to now compress // our tracks down into a single Type 0 track. - if (_buffer) { - free(_buffer); - _buffer = 0; - } + free(_buffer); + _buffer = 0; if (midi_type == 1) { // FIXME: Doubled the buffer size to prevent crashes with the diff --git a/sound/module.mk b/sound/module.mk index a578e2894a..a3fa4027c9 100644 --- a/sound/module.mk +++ b/sound/module.mk @@ -16,6 +16,7 @@ MODULE_OBJS := \ decoders/aiff.o \ decoders/flac.o \ decoders/iff_sound.o \ + decoders/mac_snd.o \ decoders/mp3.o \ decoders/raw.o \ decoders/vag.o \ diff --git a/sound/musicplugin.h b/sound/musicplugin.h index 3823f2fd3d..bbb4ed778c 100644 --- a/sound/musicplugin.h +++ b/sound/musicplugin.h @@ -50,7 +50,7 @@ public: * device name (if it isn't the default one) and the name of the driver. */ Common::String getCompleteName(); - + /** * Returns a user readable string that contains the name of the current * device name (if it isn't the default one) and the id of the driver. diff --git a/sound/rate_arm_asm.s b/sound/rate_arm_asm.s index a0e116f8f7..9431ae0649 100644 --- a/sound/rate_arm_asm.s +++ b/sound/rate_arm_asm.s @@ -212,9 +212,6 @@ SimpleRate_M_end: SimpleRate_M_read: LDR r0, [r13,#8] @ r0 = sr (8 = 4*2) ADD r0, r0, #16 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf @@ -229,9 +226,6 @@ SimpleRate_M_read: SUBS r1, r0, #1 @ r1 = inLen-1 LDMFD r13!,{r0,r2-r3,r12,r14} BLT SimpleRate_M_end - .ifdef PALMOS_MODE - MOV r10,#0 - .endif SUBS r2, r2, #1 @ r2 = opos-- ADDGE r0, r0, #2 @ if (r2 >= 0) { sr.inPtr++ BGE SimpleRate_M_loop @ and loop } @@ -297,9 +291,6 @@ SimpleRate_S_end: SimpleRate_S_read: LDR r0, [r13,#8] @ r0 = sr (8 = 4*2) ADD r0, r0, #16 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5) @@ -313,9 +304,6 @@ SimpleRate_S_read: SUBS r1, r0, #2 @ r1 = inLen-2 LDMFD r13!,{r0,r2-r3,r12,r14} BLT SimpleRate_S_end - .ifdef PALMOS_MODE - MOV r10,#0 - .endif SUBS r2, r2, #1 @ r2 = opos-- ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2 BGE SimpleRate_S_loop @ and loop } @@ -382,9 +370,6 @@ SimpleRate_R_end: SimpleRate_R_read: LDR r0, [r13,#8] @ r0 = sr (8 = 4*2) ADD r0, r0, #16 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf @@ -399,9 +384,6 @@ SimpleRate_R_read: SUBS r1, r0, #2 @ r1 = inLen-2 LDMFD r13!,{r0,r2-r3,r12,r14} BLT SimpleRate_R_end - .ifdef PALMOS_MODE - MOV r10,#0 - .endif SUBS r2, r2, #1 @ r2 = opos-- ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2 BGE SimpleRate_R_loop @ and loop } @@ -484,9 +466,6 @@ LinearRate_M_end: LDMFD r13!,{r4-r11,PC} LinearRate_M_read: ADD r0, r2, #28 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf @@ -501,9 +480,6 @@ LinearRate_M_read: SUBS r1, r0, #1 @ r1 = inLen-1 LDMFD r13!,{r0,r2-r3,r12,r14} BLT LinearRate_M_end - .ifdef PALMOS_MODE - MOV r10,#0 - .endif B LinearRate_M_read_return _ARM_LinearRate_S: @@ -592,9 +568,6 @@ LinearRate_S_end: LDMFD r13!,{r4-r11,PC} LinearRate_S_read: ADD r0, r2, #28 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf @@ -697,9 +670,6 @@ LinearRate_R_end: LDMFD r13!,{r4-r11,PC} LinearRate_R_read: ADD r0, r2, #28 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf diff --git a/sound/softsynth/mt32.cpp b/sound/softsynth/mt32.cpp index 95263a040d..54366a4300 100644 --- a/sound/softsynth/mt32.cpp +++ b/sound/softsynth/mt32.cpp @@ -149,7 +149,7 @@ static void drawProgress(float progress) { Common::Rect r(x, y, x + w, y + h); uint32 col; - + if (screenFormat.bytesPerPixel > 1) col = screenFormat.RGBToColor(0, 171, 0); else @@ -184,7 +184,7 @@ static void drawMessage(int offset, const Common::String &text) { uint16 y = g_system->getHeight() / 2 - h / 2 + offset * (h + 1); uint32 col; - + if (screenFormat.bytesPerPixel > 1) col = screenFormat.RGBToColor(0, 0, 0); else diff --git a/sound/softsynth/opl/dbopl.cpp b/sound/softsynth/opl/dbopl.cpp index db07eaf8cc..857ed78436 100644 --- a/sound/softsynth/opl/dbopl.cpp +++ b/sound/softsynth/opl/dbopl.cpp @@ -418,7 +418,7 @@ Bits Operator::TemplateVolume( ) { } //In sustain phase, but not sustaining, do regular release case RELEASE: - vol += RateForward( releaseAdd );; + vol += RateForward( releaseAdd ); if ( GCC_UNLIKELY(vol >= ENV_MAX) ) { volume = ENV_MAX; SetState( OFF ); diff --git a/sound/softsynth/opl/mame.cpp b/sound/softsynth/opl/mame.cpp index 9e7cbfe3dc..f6da659918 100644 --- a/sound/softsynth/opl/mame.cpp +++ b/sound/softsynth/opl/mame.cpp @@ -33,7 +33,7 @@ #include "mame.h" -#if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__) || defined(__N64__) +#if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__) || defined(__N64__) #include "common/config-manager.h" #endif @@ -1212,7 +1212,7 @@ FM_OPL *makeAdLibOPL(int rate) { // We need to emulate one YM3812 chip int env_bits = FMOPL_ENV_BITS_HQ; int eg_ent = FMOPL_EG_ENT_HQ; -#if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__) || defined (__MINT__) || defined(__N64__) +#if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__) || defined (__MINT__) || defined(__N64__) if (ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) { env_bits = FMOPL_ENV_BITS_HQ; eg_ent = FMOPL_EG_ENT_HQ; diff --git a/test/common/tokenizer.h b/test/common/tokenizer.h index 3420b562aa..9c14875b81 100644 --- a/test/common/tokenizer.h +++ b/test/common/tokenizer.h @@ -5,7 +5,7 @@ class TokenizerTestSuite : public CxxTest::TestSuite { public: void test_nextToken() { - + // test normal behavior Common::StringTokenizer strTokenizer("Now, this is a test!", " ,!"); Common::String tokenArray[] = {"Now", "this", "is", "a", "test"}; @@ -17,7 +17,7 @@ public: TS_ASSERT(strTokenizer.empty()); // Test edge cases: - + // empty string Common::StringTokenizer s1(""); TS_ASSERT_EQUALS("", s1.nextToken()); @@ -37,7 +37,7 @@ public: TS_ASSERT_EQUALS("af", s4.nextToken()); } - void test_resetAndEmpty() { + void test_resetAndEmpty() { Common::StringTokenizer strTokenizer("Just, another test!", " ,!"); // test reset() @@ -48,10 +48,10 @@ public: TS_ASSERT_EQUALS(token2, "Just"); // test empty() - TS_ASSERT(!strTokenizer.empty()); + TS_ASSERT(!strTokenizer.empty()); strTokenizer.nextToken(); //another strTokenizer.nextToken(); //test - TS_ASSERT(strTokenizer.empty()); + TS_ASSERT(strTokenizer.empty()); } }; diff --git a/tools/convbdf.c b/tools/convbdf.c index ad0d9d2373..fc13cff6ce 100644 --- a/tools/convbdf.c +++ b/tools/convbdf.c @@ -919,7 +919,7 @@ int gen_c_source(struct font* pf, char *path) { bbuf, pf->defaultchar); - fprintf(ofp, "\n" "#if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))\n"); + fprintf(ofp, "\n" "#if !(defined(__GP32__))\n"); fprintf(ofp, "extern const NewFont g_sysfont(desc);\n"); fprintf(ofp, "#else\n"); fprintf(ofp, "DEFINE_FONT(g_sysfont)\n"); diff --git a/tools/create_msvc/create_msvc.cpp b/tools/create_msvc/create_msvc.cpp index ace5ba8d6f..f7dba20486 100644 --- a/tools/create_msvc/create_msvc.cpp +++ b/tools/create_msvc/create_msvc.cpp @@ -210,8 +210,9 @@ public: * @param bits Number of bits the platform supports. * @param defines Defines the platform needs to have set. * @param prefix File prefix, used to add additional include paths. + * @param isWin32 Bitness of property file */ - virtual void outputGlobalPropFile(std::ofstream &properties, int bits, const std::string &defines, const std::string &prefix) = 0; + virtual void outputGlobalPropFile(std::ofstream &properties, int bits, const std::string &defines, const std::string &prefix, bool isWin32) = 0; /** * Generates the project properties for debug and release settings. @@ -282,7 +283,7 @@ public: void writeReferences(std::ofstream &output); - void outputGlobalPropFile(std::ofstream &properties, int bits, const std::string &defines, const std::string &prefix); + void outputGlobalPropFile(std::ofstream &properties, int bits, const std::string &defines, const std::string &prefix, bool isWin32); void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32); @@ -305,7 +306,7 @@ public: void writeReferences(std::ofstream &output); - void outputGlobalPropFile(std::ofstream &properties, int bits, const std::string &defines, const std::string &prefix); + void outputGlobalPropFile(std::ofstream &properties, int bits, const std::string &defines, const std::string &prefix, bool isWin32); void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32); @@ -1330,7 +1331,7 @@ void ProjectProvider::createGlobalProp(const BuildSetup &setup) { defines += *i; } - outputGlobalPropFile(properties, 32, defines, convertPathToWin(setup.filePrefix)); + outputGlobalPropFile(properties, 32, defines, convertPathToWin(setup.filePrefix), true); properties.close(); properties.open((setup.outputDir + '/' + "ScummVM_Global64" + getPropertiesExtension()).c_str()); @@ -1352,7 +1353,7 @@ void ProjectProvider::createGlobalProp(const BuildSetup &setup) { defines += *i; } - outputGlobalPropFile(properties, 64, defines, convertPathToWin(setup.filePrefix)); + outputGlobalPropFile(properties, 64, defines, convertPathToWin(setup.filePrefix), false); } void ProjectProvider::addFilesToProject(const std::string &dir, std::ofstream &projectFile, @@ -1655,7 +1656,7 @@ void VisualStudioProvider::writeReferences(std::ofstream &output) { output << "\tEndProjectSection\n"; } -void VisualStudioProvider::outputGlobalPropFile(std::ofstream &properties, int bits, const std::string &defines, const std::string &prefix) { +void VisualStudioProvider::outputGlobalPropFile(std::ofstream &properties, int bits, const std::string &defines, const std::string &prefix, bool isWin32) { properties << "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n" "<VisualStudioPropertySheet\n" "\tProjectType=\"Visual C++\"\n" @@ -1668,7 +1669,7 @@ void VisualStudioProvider::outputGlobalPropFile(std::ofstream &properties, int b "\t\tName=\"VCCLCompilerTool\"\n" "\t\tDisableLanguageExtensions=\"true\"\n" "\t\tDisableSpecificWarnings=\"" << _globalWarnings << "\"\n" - "\t\tAdditionalIncludeDirectories=\"" << prefix << ";" << prefix << "\\engines\"\n" + "\t\tAdditionalIncludeDirectories=\"" << prefix << ";" << prefix << "\\engines;%(SCUMMVM_LIBS)\\include\"\n" "\t\tPreprocessorDefinitions=\"" << defines << "\"\n" "\t\tExceptionHandling=\"0\"\n" "\t\tRuntimeTypeInfo=\"false\"\n" @@ -1685,6 +1686,7 @@ void VisualStudioProvider::outputGlobalPropFile(std::ofstream &properties, int b "\t\tIgnoreDefaultLibraryNames=\"\"\n" "\t\tSubSystem=\"1\"\n" "\t\tEntryPointSymbol=\"WinMainCRTStartup\"\n" + "\t\tAdditionalLibraryDirectories=\"%(SCUMMVM_LIBS)\\libs\\" << (isWin32 ? "x86" : "x64") << "\"\n" "\t/>\n" "\t<Tool\n" "\t\tName=\"VCResourceCompilerTool\"\n" @@ -1903,12 +1905,6 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri // Project version number project << "\t<PropertyGroup>\n" "\t\t<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\n"; - - if (name == "scummvm") - project << "<ExecutablePath>$(SCUMMVM_LIBS)\\bin;$(VCInstallDir)bin;$(WindowsSdkDir)bin\\NETFX 4.0 Tools;$(WindowsSdkDir)bin;$(VSInstallDir)Common7\\Tools\\bin;$(VSInstallDir)Common7\\tools;$(VSInstallDir)Common7\\ide;$(ProgramFiles)\\HTML Help Workshop;$(FrameworkSDKDir)\\bin;$(MSBuildToolsPath32);$(VSInstallDir);$(SystemRoot)\\SysWow64;$(FxCopDir);$(PATH)</ExecutablePath>\n" - "<IncludePath>$(SCUMMVM_LIBS)\\include;$(VCInstallDir)include;$(VCInstallDir)atlmfc\\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\\include;</IncludePath>\n" - "<LibraryPath>$(SCUMMVM_LIBS)\\lib;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\\lib</LibraryPath>\n"; - project << "\t</PropertyGroup>\n"; // Project-specific settings @@ -2053,38 +2049,41 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s project << "\t</ItemDefinitionGroup>\n"; } -void MSBuildProvider::outputGlobalPropFile(std::ofstream &properties, int bits, const std::string &defines, const std::string &prefix) { +void MSBuildProvider::outputGlobalPropFile(std::ofstream &properties, int bits, const std::string &defines, const std::string &prefix, bool isWin32) { properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" - "<PropertyGroup>\n" - "<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\n" - "<_PropertySheetDisplayName>ScummVM_Global</_PropertySheetDisplayName>\n" - "<OutDir>$(Configuration)" << bits << "\\</OutDir>\n" - "<IntDir>$(Configuration)" << bits << "/$(ProjectName)\\</IntDir>\n" - "</PropertyGroup>\n" - "<ItemDefinitionGroup>\n" - "<ClCompile>\n" - "<DisableLanguageExtensions>true</DisableLanguageExtensions>\n" - "<DisableSpecificWarnings>" << _globalWarnings << ";%(DisableSpecificWarnings)</DisableSpecificWarnings>\n" - "<AdditionalIncludeDirectories>" << prefix << ";" << prefix << "\\engines;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" - "<PreprocessorDefinitions>" << defines << ";%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" - "<ExceptionHandling>\n" - "</ExceptionHandling>\n" - "<RuntimeTypeInfo>false</RuntimeTypeInfo>\n" - "<WarningLevel>Level4</WarningLevel>\n" - "<TreatWarningAsError>false</TreatWarningAsError>\n" - "<CompileAs>Default</CompileAs>\n" - "</ClCompile>\n" - "<Link>\n" - "<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\n" - "<SubSystem>Console</SubSystem>\n" - "<EntryPointSymbol>WinMainCRTStartup</EntryPointSymbol>\n" - "</Link>\n" - "<ResourceCompile>\n" - "<PreprocessorDefinitions>HAS_INCLUDE_SET;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" - "<AdditionalIncludeDirectories>" << prefix << ";%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" - "</ResourceCompile>\n" - "</ItemDefinitionGroup>\n" + "\t<PropertyGroup>\n" + "\t\t<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\n" + "\t\t<_PropertySheetDisplayName>ScummVM_Global</_PropertySheetDisplayName>\n" + "\t\t<ExecutablePath>$(SCUMMVM_LIBS)\\bin;$(ExecutablePath)</ExecutablePath>\n" + "\t\t<LibraryPath>$(SCUMMVM_LIBS)\\libs\\" << (isWin32 ? "x86" : "x64") << ";$(LibraryPath)</LibraryPath>\n" + "\t\t<IncludePath>$(SCUMMVM_LIBS)\\include;$(IncludePath)</IncludePath>\n" + "\t\t<OutDir>$(Configuration)" << bits << "\\</OutDir>\n" + "\t\t<IntDir>$(Configuration)" << bits << "/$(ProjectName)\\</IntDir>\n" + "\t</PropertyGroup>\n" + "\t<ItemDefinitionGroup>\n" + "\t\t<ClCompile>\n" + "\t\t\t<DisableLanguageExtensions>true</DisableLanguageExtensions>\n" + "\t\t\t<DisableSpecificWarnings>" << _globalWarnings << ";%(DisableSpecificWarnings)</DisableSpecificWarnings>\n" + "\t\t\t<AdditionalIncludeDirectories>" << prefix << ";" << prefix << "\\engines;$(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" + "\t\t\t<PreprocessorDefinitions>" << defines << ";%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" + "\t\t\t<ExceptionHandling>\n" + "\t\t\t</ExceptionHandling>\n" + "\t\t\t<RuntimeTypeInfo>false</RuntimeTypeInfo>\n" + "\t\t\t<WarningLevel>Level4</WarningLevel>\n" + "\t\t\t<TreatWarningAsError>false</TreatWarningAsError>\n" + "\t\t\t<CompileAs>Default</CompileAs>\n" + "\t\t</ClCompile>\n" + "\t\t<Link>\n" + "\t\t\t<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\n" + "\t\t\t<SubSystem>Console</SubSystem>\n" + "\t\t\t<EntryPointSymbol>WinMainCRTStartup</EntryPointSymbol>\n" + "\t\t</Link>\n" + "\t\t<ResourceCompile>\n" + "\t\t\t<PreprocessorDefinitions>HAS_INCLUDE_SET;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" + "\t\t\t<AdditionalIncludeDirectories>" << prefix << ";%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" + "\t\t</ResourceCompile>\n" + "\t</ItemDefinitionGroup>\n" "</Project>\n"; properties.flush(); @@ -2111,6 +2110,8 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b "\t<ItemDefinitionGroup>\n" "\t\t<ClCompile>\n"; + + if (isRelease) { properties << "\t\t\t<IntrinsicFunctions>true</IntrinsicFunctions>\n" "\t\t\t<WholeProgramOptimization>true</WholeProgramOptimization>\n" diff --git a/tools/credits.pl b/tools/credits.pl index 02a42c12cc..cf9becc9b5 100755 --- a/tools/credits.pl +++ b/tools/credits.pl @@ -698,10 +698,6 @@ begin_credits("Credits"); add_person("Neil Millstone", "agent-q", ""); end_section(); - begin_section("PalmOS"); - add_person("Chris Apers", "chrilith ", ""); - end_section(); - begin_section("PocketPC / WinCE"); add_person("Nicolas Bacca", "arisme", "(retired)"); add_person("Kostas Nakos", "Jubanka", ""); @@ -775,6 +771,7 @@ begin_credits("Credits"); begin_section("Retired Team Members"); begin_persons(); + add_person("Chris Apers", "chrilith ", "Former PalmOS porter"); add_person("Ralph Brorsen", "painelf", "Help with GUI implementation"); add_person("Jamieson Christian", "jamieson630", "iMUSE, MIDI, all things musical"); add_person("Felix Jakschitsch", "yot", "Zak256 reverse engineering"); |