diff options
118 files changed, 1232 insertions, 455 deletions
diff --git a/Makefile.common b/Makefile.common index 6b23bd5b1c..aec033f0c7 100644 --- a/Makefile.common +++ b/Makefile.common @@ -265,6 +265,9 @@ endif ifdef ENABLE_TEENAGENT DIST_FILES_ENGINEDATA+=teenagent.dat endif +ifdef ENABLE_TONY +DIST_FILES_ENGINEDATA+=tony.dat +endif ifdef ENABLE_TOON DIST_FILES_ENGINEDATA+=toon.dat endif @@ -1,7 +1,10 @@ For a more comprehensive changelog of the latest experimental code, see: https://github.com/scummvm/scummvm/commits/ -1.6.0 (????-??-??) +1.7.0 (????-??-??) + + +1.6.0 (2013-05-31) New Games: - Added support for 3 Skulls of the Toltecs. - Added support for Eye of the Beholder. diff --git a/backends/audiocd/audiocd.h b/backends/audiocd/audiocd.h index 0afc6af991..76c3998862 100644 --- a/backends/audiocd/audiocd.h +++ b/backends/audiocd/audiocd.h @@ -110,7 +110,7 @@ public: /** * Initialize the specified CD drive for audio playback. * @param drive the drive id - * @return true if the CD drive was inited succesfully + * @return true if the CD drive was inited successfully */ virtual bool openCD(int drive) = 0; diff --git a/backends/fs/abstract-fs.h b/backends/fs/abstract-fs.h index 54e3958972..2b66a6e6e1 100644 --- a/backends/fs/abstract-fs.h +++ b/backends/fs/abstract-fs.h @@ -100,7 +100,7 @@ public: * @param mode Mode to use while listing the directory. * @param hidden Whether to include hidden files or not in the results. * - * @return true if succesful, false otherwise (e.g. when the directory does not exist). + * @return true if successful, false otherwise (e.g. when the directory does not exist). */ virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const = 0; diff --git a/backends/keymapper/keymapper.h b/backends/keymapper/keymapper.h index 1e8d1c08c3..a54a2acbdc 100644 --- a/backends/keymapper/keymapper.h +++ b/backends/keymapper/keymapper.h @@ -128,7 +128,7 @@ public: * @param name name of the keymap to push * @param transparent if true keymapper will iterate down the * stack if it cannot find a key in the new map - * @return true if succesful + * @return true if successful */ bool pushKeymap(const String& name, bool transparent = false); diff --git a/backends/platform/maemo/debian/changelog b/backends/platform/maemo/debian/changelog index ea44574e96..568edd0282 100644 --- a/backends/platform/maemo/debian/changelog +++ b/backends/platform/maemo/debian/changelog @@ -1,8 +1,14 @@ -scummvm (1.6.0~git) unstable; urgency=low +scummvm (1.7.0~git) unstable; urgency=low * Development snapshot - -- Tarek Soliman <tsoliman@scummvm.org> Tue, 10 Jul 2012 23:02:00 -0500 + -- Tarek Soliman <tsoliman@scummvm.org> Sat, 01 Jun 2013 21:03:52 -0500 + +scummvm (1.6.0) unstable; urgency=low + + * 1.6.0 release + + -- Tarek Soliman <tsoliman@scummvm.org> Fri, 31 May 2013 23:02:00 -0500 scummvm (1.5.0) unstable; urgency=low diff --git a/common/archive.cpp b/common/archive.cpp index 1323f14805..57ebeb2ca6 100644 --- a/common/archive.cpp +++ b/common/archive.cpp @@ -118,7 +118,7 @@ void SearchSet::addDirectory(const String &name, const FSNode &dir, int priority add(name, new FSDirectory(dir, depth, flat), priority); } -void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority) { +void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority, int depth, bool flat) { FSList subDirs; if (!directory.getChildren(subDirs)) return; @@ -161,9 +161,9 @@ void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String origPa } if (nextPattern.empty()) - addDirectory(name, *i, priority); + addDirectory(name, *i, priority, depth, flat); else - addSubDirectoriesMatching(*i, nextPattern, ignoreCase, priority); + addSubDirectoriesMatching(*i, nextPattern, ignoreCase, priority, depth, flat); } } } diff --git a/common/archive.h b/common/archive.h index ffd86d786d..2f9736f032 100644 --- a/common/archive.h +++ b/common/archive.h @@ -184,8 +184,8 @@ public: * to assume that this method is using anything other than a simple case insensitive compare. * Thus do not use any tokens like '*' or '?' in the "caselessName" parameter of this function! */ - void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority = 0) { - addSubDirectoriesMatching(directory, caselessName, true, priority); + void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority = 0, int depth = 1, bool flat = false) { + addSubDirectoriesMatching(directory, caselessName, true, priority, depth, flat); } /** @@ -208,7 +208,7 @@ public: * * @see Common::matchString */ - void addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority = 0); + void addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority = 0, int depth = 1, bool flat = false); /** * Remove an archive from the searchable set. diff --git a/common/cosinetables.cpp b/common/cosinetables.cpp index fe8f454e14..3b245750fa 100644 --- a/common/cosinetables.cpp +++ b/common/cosinetables.cpp @@ -34,10 +34,10 @@ CosineTable::CosineTable(int bitPrecision) { int m = 1 << _bitPrecision; double freq = 2 * M_PI / m; - _table = new float[m]; + _table = new float[m / 2]; - // Table contains cos(2*pi*x/n) for 0<=x<=n/4, - // followed by its reverse + // Table contains cos(2*pi*i/m) for 0<=i<m/4, + // followed by 3m/4<=i<m for (int i = 0; i <= m / 4; i++) _table[i] = cos(i * freq); diff --git a/common/cosinetables.h b/common/cosinetables.h index f9fb6fd59a..f5c95ec003 100644 --- a/common/cosinetables.h +++ b/common/cosinetables.h @@ -36,7 +36,14 @@ public: ~CosineTable(); /** - * Get pointer to table + * Get pointer to table. + * + * This table contains 2^bitPrecision/2 entries. + * The layout of this table is as follows: + * - Entries 0 up to (excluding) 2^bitPrecision/4: + * cos(0) till (excluding) cos(1/2*pi) + * - Entries 2^bitPrecision/4 up to (excluding) 2^bitPrecision/2: + * cos(3/2*pi) till (excluding) cos(2*pi) */ const float *getTable() { return _table; } diff --git a/common/rdft.h b/common/rdft.h index 3386940404..76e95c363a 100644 --- a/common/rdft.h +++ b/common/rdft.h @@ -20,7 +20,7 @@ * */ -// Based on eos' (I)RDFT code which is in turn +// Based on xoreos' (I)RDFT code which is in turn // Based upon the (I)RDFT code in FFmpeg // Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com> @@ -44,6 +44,40 @@ namespace Common { * * Used in engines: * - scumm + * + * + * It has four modes: + * + * Below, n = 1 << bits + * + * (I)DFT_R2C: + * input: + * n real floats + * output: + * n/2 complex floats (stored as real part followed by imag part). + * + * The output represents the first half of the (I)DFT of the input. + * If F is the complex (I)DFT of the input, then + * output[0] = F[0] + i * F[n/2] and + * output[k] = F[k] for k = 1 .. n/2-1. + * Note that F[0] and F[k] are real since the input is real, and + * the remaining values of F can be reconstructed from symmetry if desired. + * + * (I)DFT_C2R: + * input: + * n/2 complex floats + * output: + * n real floats + * + * The input encodes a complex vector x of length n that has the + * required symmetry to have a real (I)DFT: + * x[0] = Re(input[0]) + * x[k] = input[k] for k = 1 .. n/2-1 + * x[n/2] = Im(input[0]) + * x[k] = conj(input[n-k]) for k = n/2+1 .. n-1 + * The output is then the real (I)DFT of x, divided by 2. + * + * TODO: Is this division by 2 intentional? */ class RDFT { diff --git a/common/sinetables.cpp b/common/sinetables.cpp index a6ec99469d..7338166d39 100644 --- a/common/sinetables.cpp +++ b/common/sinetables.cpp @@ -34,15 +34,15 @@ SineTable::SineTable(int bitPrecision) { int m = 1 << _bitPrecision; double freq = 2 * M_PI / m; - _table = new float[m]; + _table = new float[m / 2]; - // Table contains sin(2*pi*x/n) for 0<=x<=n/4, - // followed by its reverse - for (int i = 0; i <= m / 4; i++) + // Table contains sin(2*pi*i/m) for 0<=i<m/4, + // followed by m/2<=i<3m/4 + for (int i = 0; i < m / 4; i++) _table[i] = sin(i * freq); - for (int i = 1; i < m / 4; i++) - _table[m / 2 - i] = _table[i]; + for (int i = 0; i < m / 4; i++) + _table[m / 4 + i] = -_table[i]; } SineTable::~SineTable() { diff --git a/common/sinetables.h b/common/sinetables.h index 16e203f26d..3489663661 100644 --- a/common/sinetables.h +++ b/common/sinetables.h @@ -37,6 +37,13 @@ public: /** * Get pointer to table + * + * This table contains 2^bitPrecision/2 entries. + * The layout of this table is as follows: + * - Entries 0 up to (excluding) 2^bitPrecision/4: + * sin(0) till (excluding) sin(1/2*pi) + * - Entries 2^bitPrecision/4 up to (excluding) 2^bitPrecision/2: + * sin(pi) till (excluding) sin(3/2*pi) */ const float *getTable() { return _table; } diff --git a/common/winexe.cpp b/common/winexe.cpp index 7cfc140452..877ab6baa1 100644 --- a/common/winexe.cpp +++ b/common/winexe.cpp @@ -73,7 +73,7 @@ String WinResourceID::toString() const { if (_idType == kIDTypeString) return _name; else if (_idType == kIDTypeNumerical) - return String::format("%08x", _id); + return String::format("0x%08x", _id); return ""; } diff --git a/common/winexe_ne.cpp b/common/winexe_ne.cpp index 8690f6795b..6bb40e0980 100644 --- a/common/winexe_ne.cpp +++ b/common/winexe_ne.cpp @@ -187,8 +187,8 @@ uint32 NEResources::getResourceTableOffset() { static const char *s_resTypeNames[] = { "", "cursor", "bitmap", "icon", "menu", "dialog", "string", "font_dir", "font", "accelerator", "rc_data", "msg_table", - "group_cursor", "group_icon", "version", "dlg_include", - "plug_play", "vxd", "ani_cursor", "ani_icon", "html", + "group_cursor", "group_icon", "", "", "version", "dlg_include", + "", "plug_play", "vxd", "ani_cursor", "ani_icon", "html", "manifest" }; @@ -200,9 +200,16 @@ bool NEResources::readResourceTable(uint32 offset) { return false; uint32 align = 1 << _exe->readUint16LE(); - uint16 typeID = _exe->readUint16LE(); + while (typeID != 0) { + // High bit of the type means integer type + WinResourceID type; + if (typeID & 0x8000) + type = typeID & 0x7FFF; + else + type = getResourceString(*_exe, offset + typeID); + uint16 resCount = _exe->readUint16LE(); _exe->skip(4); // reserved @@ -218,17 +225,18 @@ bool NEResources::readResourceTable(uint32 offset) { res.handle = _exe->readUint16LE(); res.usage = _exe->readUint16LE(); - res.type = typeID; + res.type = type; - if ((id & 0x8000) == 0) - res.id = getResourceString(*_exe, offset + id); - else + // High bit means integer type + if (id & 0x8000) res.id = id & 0x7FFF; + else + res.id = getResourceString(*_exe, offset + id); - if (typeID & 0x8000 && ((typeID & 0x7FFF) < ARRAYSIZE(s_resTypeNames))) + if (typeID & 0x8000 && ((typeID & 0x7FFF) < ARRAYSIZE(s_resTypeNames)) && s_resTypeNames[typeID & 0x7FFF][0] != 0) debug(2, "Found resource %s %s", s_resTypeNames[typeID & 0x7FFF], res.id.toString().c_str()); else - debug(2, "Found resource %04x %s", typeID, res.id.toString().c_str()); + debug(2, "Found resource %s %s", type.toString().c_str(), res.id.toString().c_str()); _resources.push_back(res); } @@ -257,7 +265,7 @@ String NEResources::getResourceString(SeekableReadStream &exe, uint32 offset) { return string; } -const NEResources::Resource *NEResources::findResource(uint16 type, WinResourceID id) const { +const NEResources::Resource *NEResources::findResource(const WinResourceID &type, const WinResourceID &id) const { for (List<Resource>::const_iterator it = _resources.begin(); it != _resources.end(); ++it) if (it->type == type && it->id == id) return &*it; @@ -265,7 +273,7 @@ const NEResources::Resource *NEResources::findResource(uint16 type, WinResourceI return 0; } -SeekableReadStream *NEResources::getResource(uint16 type, WinResourceID id) { +SeekableReadStream *NEResources::getResource(const WinResourceID &type, const WinResourceID &id) { const Resource *res = findResource(type, id); if (!res) @@ -275,7 +283,7 @@ SeekableReadStream *NEResources::getResource(uint16 type, WinResourceID id) { return _exe->readStream(res->size); } -const Array<WinResourceID> NEResources::getIDList(uint16 type) const { +const Array<WinResourceID> NEResources::getIDList(const WinResourceID &type) const { Array<WinResourceID> idArray; for (List<Resource>::const_iterator it = _resources.begin(); it != _resources.end(); ++it) diff --git a/common/winexe_ne.h b/common/winexe_ne.h index 4a1b2343df..f00941412f 100644 --- a/common/winexe_ne.h +++ b/common/winexe_ne.h @@ -34,27 +34,27 @@ class SeekableReadStream; /** The default Windows resources. */ enum NEResourceType { - kNECursor = 0x8001, - kNEBitmap = 0x8002, - kNEIcon = 0x8003, - kNEMenu = 0x8004, - kNEDialog = 0x8005, - kNEString = 0x8006, - kNEFontDir = 0x8007, - kNEFont = 0x8008, - kNEAccelerator = 0x8009, - kNERCData = 0x800A, - kNEMessageTable = 0x800B, - kNEGroupCursor = 0x800C, - kNEGroupIcon = 0x800D, - kNEVersion = 0x8010, - kNEDlgInclude = 0x8011, - kNEPlugPlay = 0x8013, - kNEVXD = 0x8014, - kNEAniCursor = 0x8015, - kNEAniIcon = 0x8016, - kNEHTML = 0x8017, - kNEManifest = 0x8018 + kNECursor = 0x01, + kNEBitmap = 0x02, + kNEIcon = 0x03, + kNEMenu = 0x04, + kNEDialog = 0x05, + kNEString = 0x06, + kNEFontDir = 0x07, + kNEFont = 0x08, + kNEAccelerator = 0x09, + kNERCData = 0x0A, + kNEMessageTable = 0x0B, + kNEGroupCursor = 0x0C, + kNEGroupIcon = 0x0D, + kNEVersion = 0x10, + kNEDlgInclude = 0x11, + kNEPlugPlay = 0x13, + kNEVXD = 0x14, + kNEAniCursor = 0x15, + kNEAniIcon = 0x16, + kNEHTML = 0x17, + kNEManifest = 0x18 }; /** @@ -81,17 +81,17 @@ public: bool loadFromEXE(SeekableReadStream *stream); /** Return a list of resources for a given type. */ - const Array<WinResourceID> getIDList(uint16 type) const; + const Array<WinResourceID> getIDList(const WinResourceID &type) const; /** Return a stream to the specified resource (or 0 if non-existent). */ - SeekableReadStream *getResource(uint16 type, WinResourceID id); + SeekableReadStream *getResource(const WinResourceID &type, const WinResourceID &id); private: /** A resource. */ struct Resource { WinResourceID id; - uint16 type; ///< Type of the resource. + WinResourceID type; ///< Type of the resource. uint32 offset; ///< Offset within the EXE. uint32 size; ///< Size of the data. @@ -112,7 +112,7 @@ private: bool readResourceTable(uint32 offset); /** Find a specific resource. */ - const Resource *findResource(uint16 type, WinResourceID id) const; + const Resource *findResource(const WinResourceID &type, const WinResourceID &id) const; /** Read a resource string. */ static String getResourceString(SeekableReadStream &exe, uint32 offset); @@ -2915,7 +2915,7 @@ case $_host_os in amigaos* | cygwin* | dreamcast | ds | gamecube | mingw* | n64 | ps2 | ps3 | psp | wii | wince) _posix=no ;; - android | beos* | bsd* | darwin* | freebsd* | gph-linux | haiku* | hpux* | iphone | irix* | linux* | maemo | mint* | netbsd* | openbsd* | solaris* | sunos* | uclinux* | webos) + android | beos* | bsd* | darwin* | freebsd* | gnu* | gph-linux | haiku* | hpux* | iphone | irix*| k*bsd*-gnu* | linux* | maemo | mint* | netbsd* | openbsd* | solaris* | sunos* | uclinux* | webos) _posix=yes ;; os2-emx*) @@ -3071,7 +3071,7 @@ POST_OBJS_FLAGS := -Wl,-no-whole-archive ' ;; - linux*) + linux* | gnu* | k*bsd*-gnu*) _plugin_prefix="lib" _plugin_suffix=".so" CXXFLAGS="$CXXFLAGS -fPIC" diff --git a/devtools/create_neverhood/create_neverhood.cpp b/devtools/create_neverhood/create_neverhood.cpp index 323066d8b1..f34f20882c 100644 --- a/devtools/create_neverhood/create_neverhood.cpp +++ b/devtools/create_neverhood/create_neverhood.cpp @@ -32,10 +32,16 @@ #include <vector> #include "create_neverhood.h" +#include "md5.h" #include "tables.h" const int DAT_VERSION = 0; +// The MD5 hash of the nhc.exe used to extract the tables from +const uint8 kNhcExeMd5[16] = { + 0x37, 0xD6, 0x54, 0xA2, 0xA7, 0xBB, 0xB0, 0x1F, + 0x8C, 0x41, 0x9A, 0xB8, 0x49, 0xFF, 0x29, 0xD4}; + uint32 dataSize; byte *data; uint32 dataStart = 0x004AE000; @@ -48,12 +54,33 @@ class NavigationList; void addMessageList(uint32 messageListCount, uint32 messageListOffset); -void loadExe(const char *filename) { +bool loadExe(const char *filename) { FILE *exe = fopen(filename, "rb"); + if (!exe) { + printf("Could not open nhc.exe for reading! Quitting...\n"); + return false; + } dataSize = fileSize(exe); data = new byte[dataSize]; fread(data, dataSize, 1, exe); fclose(exe); + return true; +} + +bool validateMd5() { + uint8 digest[16]; + + md5_buffer(data, dataSize, digest); + + printf("MD5 of nhc.exe is %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], + digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15]); + + if (memcmp(kNhcExeMd5, digest, 16)) { + printf("MD5 hash of nhc.exe doesn't match the expected value! Quitting...\n"); + return false; + } + return true; } byte *getData(uint32 offset) { @@ -506,9 +533,11 @@ void addMessageList(uint32 messageListCount, uint32 messageListOffset) { int main(int argc, char *argv[]) { - FILE *datFile; + if (!loadExe("nhc.exe") || + !validateMd5()) + return 1; - loadExe("nhc.exe"); + FILE *datFile; hitRectLists.loadListVector(hitRectListOffsets); rectLists.loadListVector(rectListOffsets); @@ -516,7 +545,7 @@ int main(int argc, char *argv[]) { navigationLists.loadListVector(navigationListOffsets); sceneInfo140Items.loadVector(sceneInfo140Offsets); sceneInfo2700Items.loadVector(sceneInfo2700Offsets); - + datFile = fopen("neverhood.dat", "wb"); writeUint32LE(datFile, 0x11223344); // Some magic diff --git a/devtools/create_neverhood/md5.cpp b/devtools/create_neverhood/md5.cpp new file mode 100644 index 0000000000..50f7406a47 --- /dev/null +++ b/devtools/create_neverhood/md5.cpp @@ -0,0 +1,273 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "md5.h" + +#define GET_UINT32(n, b, i) (n) = READ_LE_UINT32(b + i) +#define PUT_UINT32(n, b, i) WRITE_LE_UINT32(b + i, n) + +void md5_starts(md5_context *ctx) { + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +static void md5_process(md5_context *ctx, const uint8 data[64]) { + uint32 X[16], A, B, C, D; + + GET_UINT32(X[0], data, 0); + GET_UINT32(X[1], data, 4); + GET_UINT32(X[2], data, 8); + GET_UINT32(X[3], data, 12); + GET_UINT32(X[4], data, 16); + GET_UINT32(X[5], data, 20); + GET_UINT32(X[6], data, 24); + GET_UINT32(X[7], data, 28); + GET_UINT32(X[8], data, 32); + GET_UINT32(X[9], data, 36); + GET_UINT32(X[10], data, 40); + GET_UINT32(X[11], data, 44); + GET_UINT32(X[12], data, 48); + GET_UINT32(X[13], data, 52); + GET_UINT32(X[14], data, 56); + GET_UINT32(X[15], data, 60); + +#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define P(a, b, c, d, k, s, t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x, y, z) (z ^ (x & (y ^ z))) + + P(A, B, C, D, 0, 7, 0xD76AA478); + P(D, A, B, C, 1, 12, 0xE8C7B756); + P(C, D, A, B, 2, 17, 0x242070DB); + P(B, C, D, A, 3, 22, 0xC1BDCEEE); + P(A, B, C, D, 4, 7, 0xF57C0FAF); + P(D, A, B, C, 5, 12, 0x4787C62A); + P(C, D, A, B, 6, 17, 0xA8304613); + P(B, C, D, A, 7, 22, 0xFD469501); + P(A, B, C, D, 8, 7, 0x698098D8); + P(D, A, B, C, 9, 12, 0x8B44F7AF); + P(C, D, A, B, 10, 17, 0xFFFF5BB1); + P(B, C, D, A, 11, 22, 0x895CD7BE); + P(A, B, C, D, 12, 7, 0x6B901122); + P(D, A, B, C, 13, 12, 0xFD987193); + P(C, D, A, B, 14, 17, 0xA679438E); + P(B, C, D, A, 15, 22, 0x49B40821); + +#undef F + +#define F(x, y, z) (y ^ (z & (x ^ y))) + + P(A, B, C, D, 1, 5, 0xF61E2562); + P(D, A, B, C, 6, 9, 0xC040B340); + P(C, D, A, B, 11, 14, 0x265E5A51); + P(B, C, D, A, 0, 20, 0xE9B6C7AA); + P(A, B, C, D, 5, 5, 0xD62F105D); + P(D, A, B, C, 10, 9, 0x02441453); + P(C, D, A, B, 15, 14, 0xD8A1E681); + P(B, C, D, A, 4, 20, 0xE7D3FBC8); + P(A, B, C, D, 9, 5, 0x21E1CDE6); + P(D, A, B, C, 14, 9, 0xC33707D6); + P(C, D, A, B, 3, 14, 0xF4D50D87); + P(B, C, D, A, 8, 20, 0x455A14ED); + P(A, B, C, D, 13, 5, 0xA9E3E905); + P(D, A, B, C, 2, 9, 0xFCEFA3F8); + P(C, D, A, B, 7, 14, 0x676F02D9); + P(B, C, D, A, 12, 20, 0x8D2A4C8A); + +#undef F + +#define F(x, y, z) (x ^ y ^ z) + + P(A, B, C, D, 5, 4, 0xFFFA3942); + P(D, A, B, C, 8, 11, 0x8771F681); + P(C, D, A, B, 11, 16, 0x6D9D6122); + P(B, C, D, A, 14, 23, 0xFDE5380C); + P(A, B, C, D, 1, 4, 0xA4BEEA44); + P(D, A, B, C, 4, 11, 0x4BDECFA9); + P(C, D, A, B, 7, 16, 0xF6BB4B60); + P(B, C, D, A, 10, 23, 0xBEBFBC70); + P(A, B, C, D, 13, 4, 0x289B7EC6); + P(D, A, B, C, 0, 11, 0xEAA127FA); + P(C, D, A, B, 3, 16, 0xD4EF3085); + P(B, C, D, A, 6, 23, 0x04881D05); + P(A, B, C, D, 9, 4, 0xD9D4D039); + P(D, A, B, C, 12, 11, 0xE6DB99E5); + P(C, D, A, B, 15, 16, 0x1FA27CF8); + P(B, C, D, A, 2, 23, 0xC4AC5665); + +#undef F + +#define F(x, y, z) (y ^ (x | ~z)) + + P(A, B, C, D, 0, 6, 0xF4292244); + P(D, A, B, C, 7, 10, 0x432AFF97); + P(C, D, A, B, 14, 15, 0xAB9423A7); + P(B, C, D, A, 5, 21, 0xFC93A039); + P(A, B, C, D, 12, 6, 0x655B59C3); + P(D, A, B, C, 3, 10, 0x8F0CCC92); + P(C, D, A, B, 10, 15, 0xFFEFF47D); + P(B, C, D, A, 1, 21, 0x85845DD1); + P(A, B, C, D, 8, 6, 0x6FA87E4F); + P(D, A, B, C, 15, 10, 0xFE2CE6E0); + P(C, D, A, B, 6, 15, 0xA3014314); + P(B, C, D, A, 13, 21, 0x4E0811A1); + P(A, B, C, D, 4, 6, 0xF7537E82); + P(D, A, B, C, 11, 10, 0xBD3AF235); + P(C, D, A, B, 2, 15, 0x2AD7D2BB); + P(B, C, D, A, 9, 21, 0xEB86D391); + +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +void md5_update(md5_context *ctx, const uint8 *input, uint32 length) { + uint32 left, fill; + + if (!length) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += length; + ctx->total[0] &= 0xFFFFFFFF; + + if (ctx->total[0] < length) + ctx->total[1]++; + + if (left && length >= fill) { + memcpy((void *)(ctx->buffer + left), (const void *)input, fill); + md5_process(ctx, ctx->buffer); + length -= fill; + input += fill; + left = 0; + } + + while (length >= 64) { + md5_process(ctx, input); + length -= 64; + input += 64; + } + + if (length) { + memcpy((void *)(ctx->buffer + left), (const void *)input, length); + } +} + +static const uint8 md5_padding[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void md5_finish(md5_context *ctx, uint8 digest[16]) { + uint32 last, padn; + uint32 high, low; + uint8 msglen[8]; + + high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); + + PUT_UINT32(low, msglen, 0); + PUT_UINT32(high, msglen, 4); + + last = ctx->total[0] & 0x3F; + padn = (last < 56) ? (56 - last) : (120 - last); + + md5_update(ctx, md5_padding, padn); + md5_update(ctx, msglen, 8); + + PUT_UINT32(ctx->state[0], digest, 0); + PUT_UINT32(ctx->state[1], digest, 4); + PUT_UINT32(ctx->state[2], digest, 8); + PUT_UINT32(ctx->state[3], digest, 12); +} + +bool md5_file(const char *name, uint8 digest[16], uint32 length) { + FILE *f; + + f = fopen(name, "rb"); + if (f == NULL) { + printf("md5_file couldn't open '%s'\n", name); + return false; + } + + md5_context ctx; + uint32 i; + unsigned char buf[1000]; + bool restricted = (length != 0); + int readlen; + + if (!restricted || sizeof(buf) <= length) + readlen = sizeof(buf); + else + readlen = length; + + md5_starts(&ctx); + + + while ((i = (uint32)fread(buf, 1, readlen, f)) > 0) { + md5_update(&ctx, buf, i); + + length -= i; + if (restricted && length == 0) + break; + + if (restricted && sizeof(buf) > length) + readlen = length; + } + + md5_finish(&ctx, digest); + fclose(f); + return true; +} + +void md5_buffer(byte *buf, uint32 len, uint8 digest[16]) { + md5_context ctx; + + md5_starts(&ctx); + md5_update(&ctx, buf, len); + md5_finish(&ctx, digest); +} + diff --git a/devtools/create_neverhood/md5.h b/devtools/create_neverhood/md5.h new file mode 100644 index 0000000000..81bc03ff83 --- /dev/null +++ b/devtools/create_neverhood/md5.h @@ -0,0 +1,41 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef COMMON_MD5_H +#define COMMON_MD5_H + +#include "util.h" + +typedef struct { + uint32 total[2]; + uint32 state[4]; + uint8 buffer[64]; +} md5_context; + +void md5_starts(md5_context *ctx); +void md5_update(md5_context *ctx, const uint8 *input, uint32 length); +void md5_finish(md5_context *ctx, uint8 digest[16]); + +bool md5_file(const char *name, uint8 digest[16], uint32 length = 0); +void md5_buffer(byte *buf, uint32 len, uint8 digest[16]); + +#endif diff --git a/devtools/create_neverhood/module.mk b/devtools/create_neverhood/module.mk index 284e19105d..8e263559b5 100644 --- a/devtools/create_neverhood/module.mk +++ b/devtools/create_neverhood/module.mk @@ -3,6 +3,7 @@ MODULE := devtools/create_neverhood MODULE_OBJS := \ create_neverhood.o \ + md5.o \ util.o # Set the name of the executable diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt index 414a25e906..6e3bae1d7e 100644 --- a/devtools/scumm-md5.txt +++ b/devtools/scumm-md5.txt @@ -346,7 +346,8 @@ ft Full Throttle 4bedb49943df95a9c900a5a82ccbe9de -1 fr All? - - - cyx 8bdb0bf87b5e303dd35693afb9351215 -1 de All? - - - dhewg 55518cd73cf9c6d23ea29c51ee06bdfe -1 it All? - - - delfino - 55e4cc866ff9046824e1c638ba2b8c7f -1 ru All? - - - sev + 55e4cc866ff9046824e1c638ba2b8c7f -1 ru All? - Akella - sev + 291fb06071e65897f755846611f5ad40 19697 ru All? - 7-Wolf - sev e72bb4c2b613db2cf50f89ff6350e70a -1 es All? - - - fe381e45117878b1e942cb876b050fd6 513243679 en Mac - - Mac bundle Fingolfin 04401d747f1a2c1c4b388daff71ed378 535405461 de Mac - - Mac bundle Fingolfin diff --git a/dists/redhat/scummvm.spec b/dists/redhat/scummvm.spec index 823b74df5e..33622ffb9b 100644 --- a/dists/redhat/scummvm.spec +++ b/dists/redhat/scummvm.spec @@ -72,6 +72,7 @@ install -m644 -D dists/engine-data/sky.cpt %{buildroot}%{_datadir}/scummvm/sky.c install -m644 -D dists/engine-data/drascula.dat %{buildroot}%{_datadir}/scummvm/drascula.dat install -m644 -D dists/engine-data/teenagent.dat %{buildroot}%{_datadir}/scummvm/teenagent.dat install -m644 -D dists/engine-data/hugo.dat %{buildroot}%{_datadir}/scummvm/hugo.dat +install -m644 -D dists/engine-data/tony.dat %{buildroot}%{_datadir}/scummvm/tony.dat install -m644 -D dists/engine-data/toon.dat %{buildroot}%{_datadir}/scummvm/toon.dat desktop-file-install --vendor scummvm --dir=%{buildroot}/%{_datadir}/applications dists/scummvm.desktop @@ -111,6 +112,7 @@ fi %{_datadir}/scummvm/drascula.dat %{_datadir}/scummvm/teenagent.dat %{_datadir}/scummvm/hugo.dat +%{_datadir}/scummvm/tony.dat %{_datadir}/scummvm/toon.dat %{_mandir}/man6/scummvm.6* diff --git a/dists/redhat/scummvm.spec.in b/dists/redhat/scummvm.spec.in index 9dbd8add5b..5db2807d0e 100644 --- a/dists/redhat/scummvm.spec.in +++ b/dists/redhat/scummvm.spec.in @@ -72,6 +72,7 @@ install -m644 -D dists/engine-data/sky.cpt %{buildroot}%{_datadir}/scummvm/sky.c install -m644 -D dists/engine-data/drascula.dat %{buildroot}%{_datadir}/scummvm/drascula.dat install -m644 -D dists/engine-data/teenagent.dat %{buildroot}%{_datadir}/scummvm/teenagent.dat install -m644 -D dists/engine-data/hugo.dat %{buildroot}%{_datadir}/scummvm/hugo.dat +install -m644 -D dists/engine-data/tony.dat %{buildroot}%{_datadir}/scummvm/tony.dat install -m644 -D dists/engine-data/toon.dat %{buildroot}%{_datadir}/scummvm/toon.dat desktop-file-install --vendor scummvm --dir=%{buildroot}/%{_datadir}/applications dists/scummvm.desktop @@ -111,6 +112,7 @@ fi %{_datadir}/scummvm/drascula.dat %{_datadir}/scummvm/teenagent.dat %{_datadir}/scummvm/hugo.dat +%{_datadir}/scummvm/tony.dat %{_datadir}/scummvm/toon.dat %{_mandir}/man6/scummvm.6* diff --git a/dists/scummvm.rc b/dists/scummvm.rc index 56848be9e9..f3fa14c95a 100644 --- a/dists/scummvm.rc +++ b/dists/scummvm.rc @@ -44,6 +44,9 @@ sky.cpt FILE "dists/engine-data/sky.cpt" #if ENABLE_TEENAGENT == STATIC_PLUGIN teenagent.dat FILE "dists/engine-data/teenagent.dat" #endif +#if ENABLE_TONY == STATIC_PLUGIN +tony.dat FILE "dists/engine-data/tony.dat" +#endif #if ENABLE_TOON == STATIC_PLUGIN toon.dat FILE "dists/engine-data/toon.dat" #endif diff --git a/dists/scummvm.rc.in b/dists/scummvm.rc.in index 4bbfb47116..b7a87f4e3d 100644 --- a/dists/scummvm.rc.in +++ b/dists/scummvm.rc.in @@ -44,6 +44,9 @@ sky.cpt FILE "dists/engine-data/sky.cpt" #if ENABLE_TEENAGENT == STATIC_PLUGIN teenagent.dat FILE "dists/engine-data/teenagent.dat" #endif +#if ENABLE_TONY == STATIC_PLUGIN +tony.dat FILE "dists/engine-data/tony.dat" +#endif #if ENABLE_TOON == STATIC_PLUGIN toon.dat FILE "dists/engine-data/toon.dat" #endif diff --git a/engines/agi/wagparser.cpp b/engines/agi/wagparser.cpp index 8dee6545c0..644ca7c103 100644 --- a/engines/agi/wagparser.cpp +++ b/engines/agi/wagparser.cpp @@ -178,7 +178,7 @@ bool WagFileParser::parse(const Common::FSNode &node) { _parsedOk = false; // We haven't parsed the file yet stream = node.createReadStream(); // Open the file - if (stream) { // Check that opening the file was succesful + if (stream) { // Check that opening the file was successful if (checkWagVersion(*stream)) { // Check that WinAGI version string is valid // It seems we've got a valid *.wag file so let's parse its properties from the start. stream->seek(0); // Rewind the stream diff --git a/engines/cruise/cruise.h b/engines/cruise/cruise.h index 9782df8f09..3e49e77770 100644 --- a/engines/cruise/cruise.h +++ b/engines/cruise/cruise.h @@ -43,10 +43,6 @@ */ namespace Cruise { -enum CruiseGameType { - GType_CRUISE = 1 -}; - #define GAME_FRAME_DELAY_1 50 #define GAME_FRAME_DELAY_2 100 diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp index b632e4ea7a..bce3f184db 100644 --- a/engines/cruise/detection.cpp +++ b/engines/cruise/detection.cpp @@ -20,8 +20,6 @@ * */ - - #include "base/plugins.h" #include "common/savefile.h" #include "common/system.h" @@ -34,21 +32,12 @@ namespace Cruise { struct CRUISEGameDescription { ADGameDescription desc; - - int gameType; - uint32 features; }; const char *CruiseEngine::getGameId() const { return _gameDescription->desc.gameid; } -int CruiseEngine::getGameType() const { - return _gameDescription->gameType; -} -uint32 CruiseEngine::getFeatures() const { - return _gameDescription->features; -} Common::Language CruiseEngine::getLanguage() const { return _gameDescription->desc.language; } @@ -77,8 +66,6 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, { { @@ -90,8 +77,6 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, { { @@ -103,8 +88,6 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, { { @@ -116,8 +99,6 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, { { @@ -129,8 +110,6 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, { { @@ -142,8 +121,6 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, { { @@ -155,8 +132,6 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, { // Amiga English US GOLD edition. { @@ -168,8 +143,6 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, { // Amiga Italian US GOLD edition. { @@ -181,8 +154,6 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, { // AtariST English KixxXL edition. { @@ -194,8 +165,6 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, { { @@ -207,8 +176,6 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, { { @@ -220,10 +187,8 @@ static const CRUISEGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO0() }, - GType_CRUISE, - 0, }, - {AD_TABLE_END_MARKER, 0, 0} + {AD_TABLE_END_MARKER} }; } diff --git a/engines/hopkins/hopkins.cpp b/engines/hopkins/hopkins.cpp index b023a2fedb..b773808c50 100644 --- a/engines/hopkins/hopkins.cpp +++ b/engines/hopkins/hopkins.cpp @@ -35,12 +35,9 @@ namespace Hopkins { -HopkinsEngine *g_vm; - HopkinsEngine::HopkinsEngine(OSystem *syst, const HopkinsGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _randomSource("Hopkins") { DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); - g_vm = this; _animMan = new AnimationManager(this); _computer = new ComputerManager(this); _dialog = new DialogsManager(this); @@ -156,12 +153,7 @@ bool HopkinsEngine::runWin95Demo() { _events->_rateCounter = 0; _globals->_eventMode = EVENTMODE_IGNORE; _globals->_speed = 1; - - for (int i = 1; i < 50; i++) { - _graphicsMan->copySurface(_graphicsMan->_backBuffer, 0, 0, 640, 440, _graphicsMan->_frontBuffer, 0, 0); - _events->refreshScreenAndEvents(); - } - + _events->delay(500); _globals->_eventMode = EVENTMODE_DEFAULT; if (_events->_rateCounter > 475) _globals->_speed = 2; @@ -169,7 +161,7 @@ bool HopkinsEngine::runWin95Demo() { _globals->_speed = 3; if (_startGameSlot == -1) - _graphicsMan->fadeOutLong(); + _graphicsMan->fadeOutShort(); _globals->_eventMode = EVENTMODE_IGNORE; _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); @@ -206,12 +198,15 @@ bool HopkinsEngine::runWin95Demo() { switch (_globals->_exitId) { case 1: + // Handles room: Apartment _linesMan->setMaxLineIdx(40); _globals->_characterMaxPosY = 435; _objectsMan->sceneControl2("IM01", "IM01", "ANIM01", "IM01", 2, true); break; case 3: + // - Displays bank attack when leaving the apartment + // - Handles room: bottom of the apartment if (!_globals->_saveData->_data[svBankAttackAnimPlayedFl]) { _soundMan->playSound(3); if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS) @@ -240,7 +235,7 @@ bool HopkinsEngine::runWin95Demo() { _soundMan->removeSample(2); _soundMan->removeSample(3); _soundMan->removeSample(4); - _graphicsMan->fadeOutLong(); + _graphicsMan->fadeOutShort(); _globals->_saveData->_data[svBankAttackAnimPlayedFl] = 1; } _linesMan->setMaxLineIdx(5); @@ -249,12 +244,14 @@ bool HopkinsEngine::runWin95Demo() { break; case 4: + // Handle room: City map _globals->_disableInventFl = true; _objectsMan->handleCityMap(); _globals->_disableInventFl = false; break; case 5: + // Handle room: Outside the bank _linesMan->setMaxLineIdx(5); _globals->_characterMaxPosY = 455; @@ -798,14 +795,14 @@ bool HopkinsEngine::runFull() { if (_startGameSlot == -1) { if (getPlatform() == Common::kPlatformLinux) { - _graphicsMan->loadImage("H2"); - _graphicsMan->fadeInLong(); - _events->delay(500); - _graphicsMan->fadeOutLong(); - _globals->_speed = 2; - _globals->_eventMode = EVENTMODE_IGNORE; - _graphicsMan->_fadingFl = true; - _animMan->playAnim("MP.ANM", "MP.ANM", 10, 16, 200); + _graphicsMan->loadImage("H2"); + _graphicsMan->fadeInLong(); + _events->delay(500); + _graphicsMan->fadeOutLong(); + _globals->_speed = 2; + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->_fadingFl = true; + _animMan->playAnim("MP.ANM", "MP.ANM", 10, 16, 200); } else { _animMan->playAnim("MP.ANM", "MP.ANM", 10, 16, 200); _graphicsMan->fadeOutLong(); @@ -1138,12 +1135,14 @@ bool HopkinsEngine::runFull() { break; case 30: + // Shooting _linesMan->setMaxLineIdx(15); _globals->_characterMaxPosY = 440; _objectsMan->sceneControl2("IM30", "IM30", "ANIM30", "IM30", 24, false); break; case 31: + // Shooting target _objectsMan->sceneControl("IM31", "IM31", "ANIM31", "IM31", 10, true); break; @@ -1158,6 +1157,7 @@ bool HopkinsEngine::runFull() { break; case 34: + // In the airport, before the flight cut-scene _objectsMan->sceneControl("IM34", "IM34", "ANIM34", "IM34", 2, false); break; @@ -1188,6 +1188,7 @@ bool HopkinsEngine::runFull() { } case 50: + // Flight cut scene playPlaneCutscene(); _globals->_exitId = 51; break; @@ -1647,8 +1648,8 @@ void HopkinsEngine::playIntro() { _graphicsMan->setColorPercentage(253, 100, 100, 100); _graphicsMan->setColorPercentage(251, 100, 100, 100); _graphicsMan->setColorPercentage(254, 0, 0, 0); - for (int i = 0; i <= 4; i++) - _events->refreshScreenAndEvents(); + + _events->delay(500); _globals->_eventMode = EVENTMODE_IGNORE; _graphicsMan->fadeInLong(); @@ -1909,10 +1910,7 @@ void HopkinsEngine::bombExplosion() { } void HopkinsEngine::restoreSystem() { - // If the game isn't alerady trying to quit, flag that quitting is needed - if (!shouldQuit()) - quitGame(); - + quitGame(); _events->refreshEvents(); } @@ -2237,6 +2235,8 @@ void HopkinsEngine::playPlaneCutscene() { if (!_events->_escKeyFl) { _graphicsMan->_fadingFl = true; _animMan->playAnim("PARA00A.ANM", "PARA00.ANM", 9, 9, 9); + } else { + _graphicsMan->fadeOutShort(); } _events->_escKeyFl = false; diff --git a/engines/hopkins/hopkins.h b/engines/hopkins/hopkins.h index 777fd1c335..398e41a4d2 100644 --- a/engines/hopkins/hopkins.h +++ b/engines/hopkins/hopkins.h @@ -183,9 +183,6 @@ public: virtual void syncSoundSettings(); }; -// Global reference to the HopkinsEngine object -extern HopkinsEngine *g_vm; - } // End of namespace Hopkins #endif /* HOPKINS_HOPKINS_H */ diff --git a/engines/hopkins/saveload.cpp b/engines/hopkins/saveload.cpp index 45b4885c90..98fb15046e 100644 --- a/engines/hopkins/saveload.cpp +++ b/engines/hopkins/saveload.cpp @@ -43,12 +43,12 @@ SaveLoadManager::SaveLoadManager(HopkinsEngine *vm) { } bool SaveLoadManager::save(const Common::String &file, const void *buf, size_t n) { - Common::OutSaveFile *f = g_system->getSavefileManager()->openForSaving(file); + Common::OutSaveFile *savefile = g_system->getSavefileManager()->openForSaving(file); - if (f) { - size_t bytesWritten = f->write(buf, n); - f->finalize(); - delete f; + if (savefile) { + size_t bytesWritten = savefile->write(buf, n); + savefile->finalize(); + delete savefile; return bytesWritten == n; } else @@ -69,13 +69,13 @@ void SaveLoadManager::initSaves() { } void SaveLoadManager::load(const Common::String &file, byte *buf) { - Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(file); - if (f == NULL) - error("Error openinig file - %s", file.c_str()); + Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(file); + if (savefile == NULL) + error("Error opening file - %s", file.c_str()); - int32 filesize = f->size(); - f->read(buf, filesize); - delete f; + int32 filesize = savefile->size(); + savefile->read(buf, filesize); + delete savefile; } bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header) { @@ -215,13 +215,13 @@ Common::Error SaveLoadManager::loadGame(int slot) { bool SaveLoadManager::readSavegameHeader(int slot, hopkinsSavegameHeader &header) { // Try and open the save file for reading - Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( - g_vm->generateSaveName(slot)); - if (!saveFile) + Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading( + _vm->generateSaveName(slot)); + if (!savefile) return false; - bool result = readSavegameHeader(saveFile, header); - delete saveFile; + bool result = readSavegameHeader(savefile, header); + delete savefile; return result; } diff --git a/engines/hopkins/saveload.h b/engines/hopkins/saveload.h index 221a445fd2..6fee814180 100644 --- a/engines/hopkins/saveload.h +++ b/engines/hopkins/saveload.h @@ -63,7 +63,7 @@ public: static bool readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header); void writeSavegameHeader(Common::OutSaveFile *out, hopkinsSavegameHeader &header); - static bool readSavegameHeader(int slot, hopkinsSavegameHeader &header); + bool readSavegameHeader(int slot, hopkinsSavegameHeader &header); Common::Error saveGame(int slot, const Common::String &saveName); Common::Error loadGame(int slot); diff --git a/engines/hopkins/script.cpp b/engines/hopkins/script.cpp index c39273203d..7e150624b8 100644 --- a/engines/hopkins/script.cpp +++ b/engines/hopkins/script.cpp @@ -536,6 +536,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { break; case 12: + // Bank - negotiations between Hopkins and one of the killers _vm->_fontMan->hideText(9); _vm->_events->refreshScreenAndEvents(); _vm->_events->refreshScreenAndEvents(); @@ -543,6 +544,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { break; case 13: + // Bank - after negotiations, Hopkins enters the bank _vm->_events->_mouseButton = _vm->_events->_curMouseButton; _vm->_globals->_disableInventFl = true; _vm->_graphicsMan->fadeOutLong(); @@ -553,9 +555,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { _vm->_graphicsMan->endDisplayBob(); _vm->_objectsMan->clearScreen(); - if ((_vm->getPlatform() == Common::kPlatformWindows) && _vm->getIsDemo()) { - _vm->_graphicsMan->fadeOutLong(); - } else { + if ((_vm->getPlatform() != Common::kPlatformWindows) || !_vm->getIsDemo()) { _vm->_soundMan->playSoundFile("SOUND17.WAV"); _vm->_graphicsMan->_fadingFl = true; _vm->_animMan->playSequence2("HELICO.SEQ", 10, 4, 10); @@ -615,10 +615,6 @@ int ScriptManager::handleOpcode(const byte *dataP) { _vm->_graphicsMan->_fadingFl = true; _vm->_animMan->playSequence2("ASSOM.SEQ", 10, 4, 500); _vm->_soundMan->_specialSoundNum = 0; - - if ((_vm->getPlatform() == Common::kPlatformWindows) && _vm->getIsDemo()) - _vm->_graphicsMan->fadeOutLong(); - _vm->_globals->_disableInventFl = false; _vm->_objectsMan->_helicopterFl = true; break; @@ -1221,6 +1217,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { break; case 88: + // Shooting target - Shooting at target if (_vm->_globals->_saveData->_data[svField183] == 1) { _vm->_objectsMan->setBobAnimDataIdx(1, 0); _vm->_objectsMan->setBobAnimDataIdx(2, 0); @@ -1298,6 +1295,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { break; case 90: + // Shooting target - Using the level _vm->_soundMan->playSoundFile("SOUND52.WAV"); if (!_vm->_globals->_saveData->_data[svField186]) { _vm->_animMan->playSequence("CIB5A.SEQ", 1, 12, 1, false, false); @@ -1984,6 +1982,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { break; case 216: + // Discuss with pilot just before Flight cutscene _vm->_globals->_introSpeechOffFl = true; _vm->_talkMan->startAnimatedCharacterDialogue("aviat1.pe2"); _vm->_globals->_introSpeechOffFl = false; diff --git a/engines/lure/debugger.cpp b/engines/lure/debugger.cpp index 3fbbf84469..92f07a566e 100644 --- a/engines/lure/debugger.cpp +++ b/engines/lure/debugger.cpp @@ -337,11 +337,11 @@ bool Debugger::cmd_hotspot(int argc, const char **argv) { } else if (strcmp(argv[2], "activate") == 0) { // Activate the hotspot res.activateHotspot(hs->hotspotId); - hs->flags &= !HOTSPOTFLAG_MENU_EXCLUSION; + hs->flags &= ~HOTSPOTFLAG_MENU_EXCLUSION; DebugPrintf("Activated\n"); } else if (strcmp(argv[2], "deactivate") == 0) { - // Activate the hotspot + // Deactivate the hotspot res.deactivateHotspot(hs->hotspotId); hs->flags |= HOTSPOTFLAG_MENU_EXCLUSION; DebugPrintf("Deactivated\n"); diff --git a/engines/lure/menu.cpp b/engines/lure/menu.cpp index 93deecdcd6..7564ce91a0 100644 --- a/engines/lure/menu.cpp +++ b/engines/lure/menu.cpp @@ -47,6 +47,7 @@ MenuRecord::MenuRecord(const MenuRecordBounds *bounds, int numParams, ...) { va_start(params, numParams); for (int index = 0; index < _numEntries; ++index) _entries[index] = va_arg(params, const char *); + va_end(params); // Store position data _hsxstart = bounds->left; _hsxend = bounds->right; @@ -458,7 +459,7 @@ Action PopupMenu::Show(int numEntries, Action *actions) { strList[index] = stringList.getString(*actionPtr++); uint16 result = Show(numEntries, strList); - delete strList; + Memory::dealloc(strList); if (result == 0xffff) return NONE; else return actions[result]; } diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp index f80dbfacbd..efa0dd3fd3 100644 --- a/engines/mohawk/livingbooks.cpp +++ b/engines/mohawk/livingbooks.cpp @@ -148,16 +148,10 @@ MohawkEngine_LivingBooks::MohawkEngine_LivingBooks(OSystem *syst, const MohawkGa const Common::FSNode gameDataDir(ConfMan.get("path")); // Rugrats - const Common::FSNode ProgPath = gameDataDir.getChild("program"); - if (ProgPath.exists()) - SearchMan.addDirectory(ProgPath.getPath(), ProgPath, 0, 2); - const Common::FSNode RugPath = gameDataDir.getChild("Rugrats Adventure Game"); - if (RugPath.exists()) - SearchMan.addDirectory(RugPath.getPath(), RugPath, 0, 2); + SearchMan.addSubDirectoryMatching(gameDataDir, "program", 0, 2); + SearchMan.addSubDirectoryMatching(gameDataDir, "Rugrats Adventure Game", 0, 2); // CarmenTQ - const Common::FSNode CTQPath = gameDataDir.getChild("95instal"); - if (CTQPath.exists()) - SearchMan.addDirectory(CTQPath.getPath(), CTQPath, 0, 4); + SearchMan.addSubDirectoryMatching(gameDataDir, "95instal", 0, 4); } MohawkEngine_LivingBooks::~MohawkEngine_LivingBooks() { diff --git a/engines/neverhood/background.cpp b/engines/neverhood/background.cpp index 0a80bd8390..e9e5325e77 100644 --- a/engines/neverhood/background.cpp +++ b/engines/neverhood/background.cpp @@ -45,7 +45,7 @@ Background::~Background() { } void Background::createSurface(int surfacePriority, int16 width, int16 height) { - _surface = new BaseSurface(_vm, surfacePriority, width, height); + _surface = new BaseSurface(_vm, surfacePriority, width, height, "background"); _surface->setTransparent(false); _spriteResource.getPosition().x = width; _spriteResource.getPosition().y = height; diff --git a/engines/neverhood/console.cpp b/engines/neverhood/console.cpp new file mode 100644 index 0000000000..7b5add65c7 --- /dev/null +++ b/engines/neverhood/console.cpp @@ -0,0 +1,172 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "neverhood/console.h" +#include "gui/debugger.h" +#include "neverhood/neverhood.h" +#include "neverhood/gamemodule.h" +#include "neverhood/scene.h" +#include "neverhood/modules/module1600.h" + +namespace Neverhood { + +Console::Console(NeverhoodEngine *vm) : GUI::Debugger(), _vm(vm) { + DCmd_Register("cheat", WRAP_METHOD(Console, Cmd_Cheat)); + DCmd_Register("dumpvars", WRAP_METHOD(Console, Cmd_Dumpvars)); + DCmd_Register("room", WRAP_METHOD(Console, Cmd_Room)); + DCmd_Register("surfaces", WRAP_METHOD(Console, Cmd_Surfaces)); +} + +Console::~Console() { +} + +bool Console::Cmd_Room(int argc, const char **argv) { + int currentModule = _vm->_gameModule->getCurrentModuleNum(); + int previousModule = _vm->_gameModule->getPreviousModuleNum(); + int scene = _vm->gameState().sceneNum; + + DebugPrintf("Current module: %d, previous module: %d, scene %d\n", currentModule, previousModule, scene); + + if (argc != 3) { + DebugPrintf("Use room <module> <scene> to change rooms\n"); + DebugPrintf("Modules are incremental by 100, from 1000 to 3000\n"); + } else { + int newModule = atoi(argv[1]); + int newScene = atoi(argv[2]); + + _vm->gameState().sceneNum = newScene; + _vm->_gameModule->createModule(newModule, -1); + } + + return true; +} + +bool Console::Cmd_Surfaces(int argc, const char **argv) { + if (_vm->_gameModule->_childObject) { + ((Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject)->printSurfaces(this); + } + return true; +} + +bool Console::Cmd_Cheat(int argc, const char **argv) { + if (argc < 2) { + DebugPrintf("Cheats for various puzzles in the game\n"); + DebugPrintf("Use %s <cheatname> to use a cheat.\n", argv[0]); + DebugPrintf("Cheats:\n-------\n"); + DebugPrintf(" buttons - enables all 3 buttons on the door in the purple building, module 3000, scene 9\n"); + DebugPrintf(" cannon - sets the correct cannon combination in module 3000, scene 8\n"); + DebugPrintf(" dice - shows the correct dice combination in the teddy bear puzzle, module 1100, scene 6\n"); + DebugPrintf(" memory - solves the memory puzzle, module 1400, scene 4\n"); + DebugPrintf(" music - shows the correct index in the radio music puzzle, module 2800, scene 1\n"); + DebugPrintf(" radio - enables the radio, module 3000, scene 9 - same as pulling the rightmost cord in the flytrap room\n"); + DebugPrintf(" symbols - solves the symbols puzzle, module 1600, scene 8. Only available in that room\n"); + DebugPrintf(" tubes - shows the correct test tube combination in module 2800, scenes 7 and 10, can be used anywhere\n"); + return true; + } + + Common::String cheatName = argv[1]; + int moduleNum = _vm->_gameModule->getCurrentModuleNum(); + int sceneNum = _vm->gameState().sceneNum; + + if (cheatName == "buttons") { + Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject; + + scene->setSubVar(VA_LOCKS_DISABLED, 0x304008D2, 1); // kScene3010ButtonNameHashes[0] + scene->setSubVar(VA_LOCKS_DISABLED, 0x40119852, 1); // kScene3010ButtonNameHashes[1] + scene->setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1); // kScene3010ButtonNameHashes[2] + + DebugPrintf("All 3 door buttons have been enabled\n"); + } else if (cheatName == "cannon") { + Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject; + + for (int i = 0; i < 3; i++) + scene->setSubVar(VA_CURR_CANNON_SYMBOLS, i, scene->getSubVar(VA_GOOD_CANNON_SYMBOLS_1, i)); + + for (int i = 3; i < 6; i++) + scene->setSubVar(VA_CURR_CANNON_SYMBOLS, i, scene->getSubVar(VA_GOOD_CANNON_SYMBOLS_2, i - 3)); + + DebugPrintf("Puzzle solved\n"); + } else if (cheatName == "dice") { + Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject; + DebugPrintf("Good: (%d %d %d), current: (%d %d %d)\n", + scene->getSubVar(VA_GOOD_DICE_NUMBERS, 0), scene->getSubVar(VA_GOOD_DICE_NUMBERS, 1), scene->getSubVar(VA_GOOD_DICE_NUMBERS, 2), + scene->getSubVar(VA_CURR_DICE_NUMBERS, 0), scene->getSubVar(VA_CURR_DICE_NUMBERS, 1), scene->getSubVar(VA_CURR_DICE_NUMBERS, 2) + ); + } else if (cheatName == "memory") { + Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject; + + // Autosolve all tiles and leave only two matching tiles closed + for (int i = 0; i < 48; i++) + scene->setSubVar(VA_IS_TILE_MATCH, i, 1); + + // Close the top left tile + scene->setSubVar(VA_IS_TILE_MATCH, 0, 0); + + // Find and close the pair of the top left tile + for (int i = 0; i < 48; i++) { + if (i != 0 && scene->getSubVar(VA_TILE_SYMBOLS, i) == scene->getSubVar(VA_TILE_SYMBOLS, 0)) { + scene->setSubVar(VA_IS_TILE_MATCH, i, 0); + break; + } + } + + DebugPrintf("Puzzle solved\n"); + } else if (cheatName == "music") { + Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject; + DebugPrintf("Good music index: %d, current radio music index: %d\n", scene->getGlobalVar(V_CURR_RADIO_MUSIC_INDEX), scene->getGlobalVar(V_GOOD_RADIO_MUSIC_INDEX)); + } else if (cheatName == "radio") { + Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject; + scene->setGlobalVar(V_RADIO_ENABLED, 1); + + DebugPrintf("The radio has been enabled\n"); + } else if (cheatName == "symbols") { + if (moduleNum == 1600 && sceneNum == 8) { + Scene1609 *scene = ((Scene1609 *)((Module1600 *)_vm->_gameModule->_childObject)->_childObject); + + for (int index = 0; index < 12; index++) { + scene->_asSymbols[index]->change((int)scene->getSubVar(VA_CODE_SYMBOLS, index) + 12, index == (int)scene->getSubVar(VA_CODE_SYMBOLS, scene->_noisySymbolIndex)); + } + + scene->_changeCurrentSymbol = false; + scene->_symbolPosition = 11; + scene->_countdown1 = 36; + + DebugPrintf("Puzzle solved\n"); + } else { + DebugPrintf("Only available in module 1600, scene 8\n"); + } + } else if (cheatName == "tubes") { + Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject; + DebugPrintf("Tube set 1: %d %d %d\n", scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 1), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 2)); + DebugPrintf("Tube set 2: %d %d %d\n", scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 0), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 1), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 2)); + } + + return true; +} + +bool Console::Cmd_Dumpvars(int argc, const char **argv) { + _vm->_gameVars->dumpVars(this); + + return true; +} + +} // End of namespace Neverhood diff --git a/engines/neverhood/console.h b/engines/neverhood/console.h new file mode 100644 index 0000000000..40c11b50e3 --- /dev/null +++ b/engines/neverhood/console.h @@ -0,0 +1,47 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef NEVERHOOD_CONSOLE_H +#define NEVERHOOD_CONSOLE_H + +#include "gui/debugger.h" + +namespace Neverhood { + +class NeverhoodEngine; + +class Console : public GUI::Debugger { +public: + Console(NeverhoodEngine *vm); + virtual ~Console(void); + +private: + NeverhoodEngine *_vm; + + bool Cmd_Room(int argc, const char **argv); + bool Cmd_Surfaces(int argc, const char **argv); + bool Cmd_Cheat(int argc, const char **argv); + bool Cmd_Dumpvars(int argc, const char **argv); +}; + +} // End of namespace Neverhood +#endif diff --git a/engines/neverhood/diskplayerscene.cpp b/engines/neverhood/diskplayerscene.cpp index d972943759..94a68a7526 100644 --- a/engines/neverhood/diskplayerscene.cpp +++ b/engines/neverhood/diskplayerscene.cpp @@ -354,9 +354,7 @@ DiskplayerScene::DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int insertPuzzleMouse(0x000408A8, 20, 620); showMouse(false); - _diskSmackerPlayer = new SmackerPlayer(_vm, this, 0x08288103, false, true); - addEntity(_diskSmackerPlayer); - addSurface(_diskSmackerPlayer->getSurface()); + _diskSmackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, 0x08288103, false, true)); _diskSmackerPlayer->setDrawPos(154, 86); _vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder()); @@ -473,36 +471,34 @@ uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam ¶m, return 0; } -void DiskplayerScene::stop() { - _diskSmackerPlayer->open(0x08288103, true); +void DiskplayerScene::openSmacker(uint32 fileHash, bool keepLastFrame) { + _diskSmackerPlayer->open(fileHash, keepLastFrame); _vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder()); _palette->usePalette(); +} + +void DiskplayerScene::stop() { + openSmacker(0x08288103, true); _ssPlayButton->release(); _updateStatus = kUSStopped; _diskSlots[_diskIndex]->activate(); } void DiskplayerScene::tuneIn() { - _diskSmackerPlayer->open(0x900001C1, false); - _vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder()); - _palette->usePalette(); + openSmacker(0x900001C1, false); _ssPlayButton->release(); _updateStatus = kUSTuningIn; _diskSlots[_diskIndex]->activate(); } void DiskplayerScene::playDisk() { - _diskSmackerPlayer->open(kDiskplayerSmackerFileHashes[_diskIndex], false); - _vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder()); - _palette->usePalette(); + openSmacker(kDiskplayerSmackerFileHashes[_diskIndex], false); _updateStatus = kUSPlaying; _diskSlots[_diskIndex]->play(); } void DiskplayerScene::playStatic() { - _diskSmackerPlayer->open(0x90000101, false); - _vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder()); - _palette->usePalette(); + openSmacker(0x90000101, false); _ssPlayButton->release(); _updateStatus = kUSPlaying; _diskSlots[_diskIndex]->activate(); diff --git a/engines/neverhood/diskplayerscene.h b/engines/neverhood/diskplayerscene.h index f3fd9ea874..4afaf8af9f 100644 --- a/engines/neverhood/diskplayerscene.h +++ b/engines/neverhood/diskplayerscene.h @@ -99,6 +99,7 @@ protected: bool _dropKey; void update(); uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); + void openSmacker(uint32 fileHash, bool keepLastFrame); void stop(); void tuneIn(); void playDisk(); diff --git a/engines/neverhood/entity.h b/engines/neverhood/entity.h index fb8941ae43..cba1bb9a7f 100644 --- a/engines/neverhood/entity.h +++ b/engines/neverhood/entity.h @@ -60,14 +60,18 @@ protected: // TODO: Disable heavy debug stuff in release mode #define SetUpdateHandler(handler) \ - _updateHandlerCb = static_cast <void (Entity::*)(void)> (handler); \ - debug(5, "SetUpdateHandler(" #handler ")"); \ - _updateHandlerCbName = #handler + do { \ + _updateHandlerCb = static_cast <void (Entity::*)(void)> (handler); \ + debug(5, "SetUpdateHandler(" #handler ")"); \ + _updateHandlerCbName = #handler; \ + } while (0) #define SetMessageHandler(handler) \ - _messageHandlerCb = static_cast <uint32 (Entity::*)(int messageNum, const MessageParam ¶m, Entity *sender)> (handler); \ - debug(5, "SetMessageHandler(" #handler ")"); \ - _messageHandlerCbName = #handler + do { \ + _messageHandlerCb = static_cast <uint32 (Entity::*)(int messageNum, const MessageParam ¶m, Entity *sender)> (handler); \ + debug(5, "SetMessageHandler(" #handler ")"); \ + _messageHandlerCbName = #handler; \ + } while (0) const uint kMaxSoundResources = 16; diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp index 49682b0d29..96e8cc13a6 100644 --- a/engines/neverhood/gamemodule.cpp +++ b/engines/neverhood/gamemodule.cpp @@ -194,21 +194,6 @@ void GameModule::initMemoryPuzzle() { tileSymbolIndex = 0; } setSubVar(VA_IS_PUZZLE_INIT, 0xC8606803, 1); - - // DEBUG Enable to autosolve all tiles and leave only two matching tiles open -#if 0 - for (int i = 0; i < 48; i++) - setSubVar(VA_IS_TILE_MATCH, i, 1); - int debugIndex = 0; - setSubVar(VA_IS_TILE_MATCH, debugIndex, 0); - for (int i = 0; i < 48; i++) { - if (i != debugIndex && getSubVar(VA_TILE_SYMBOLS, i) == getSubVar(VA_TILE_SYMBOLS, debugIndex)) { - setSubVar(VA_IS_TILE_MATCH, i, 0); - break; - } - } -#endif - } } @@ -426,6 +411,8 @@ void GameModule::checkRequests() { } if (_restoreGameRequested) { _restoreGameRequested = false; + _vm->_audioResourceMan->stopAllSounds(); + _vm->_soundMan->stopAllSounds(); delete _childObject; delete _prevChildObject; _childObject = NULL; @@ -438,8 +425,11 @@ void GameModule::checkRequests() { } void GameModule::createModule(int moduleNum, int which) { - debug("GameModule::createModule(%d, %d)", moduleNum, which); + debug(1, "GameModule::createModule(%d, %d)", moduleNum, which); _moduleNum = moduleNum; + + delete _childObject; + switch (_moduleNum) { case 1000: setGlobalVar(V_MODULE_NAME, 0x03294419); @@ -539,7 +529,7 @@ void GameModule::createModule(int moduleNum, int which) { } void GameModule::createModuleByHash(uint32 nameHash) { - debug("GameModule::createModuleByHash(%08X)", nameHash); + debug(1, "GameModule::createModuleByHash(%08X)", nameHash); switch (nameHash) { case 0x03294419: createModule(1000, -1); @@ -684,7 +674,7 @@ void GameModule::updateModule() { createModule(2300, 1); break; case 2300: - debug("module 23000 _moduleResult : %d", _moduleResult); + debug(1, "module 23000 _moduleResult : %d", _moduleResult); if (_moduleResult == 2) createModule(1200, 0); else if (_moduleResult == 0) diff --git a/engines/neverhood/gamemodule.h b/engines/neverhood/gamemodule.h index 8101d38009..1fb3557b81 100644 --- a/engines/neverhood/gamemodule.h +++ b/engines/neverhood/gamemodule.h @@ -55,6 +55,10 @@ public: void initCubeSymbolsPuzzle(); void initCrystalColorsPuzzle(); uint32 getCurrRadioMusicFileHash(); + int getCurrentModuleNum() { return _moduleNum; } + int getPreviousModuleNum() { return _moduleNum; } + + void createModule(int moduleNum, int which); protected: int _moduleNum; Entity *_prevChildObject; @@ -64,7 +68,6 @@ protected: bool _canRequestMainMenu; bool _mainMenuRequested; uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); - void createModule(int moduleNum, int which); void createModuleByHash(uint32 nameHash); void updateModule(); void openMainMenu(); diff --git a/engines/neverhood/gamevars.cpp b/engines/neverhood/gamevars.cpp index 87f5fe6dd9..dc25f74e56 100644 --- a/engines/neverhood/gamevars.cpp +++ b/engines/neverhood/gamevars.cpp @@ -20,6 +20,7 @@ * */ +#include "neverhood/console.h" #include "neverhood/gamevars.h" namespace Neverhood { @@ -123,10 +124,10 @@ int16 GameVars::getSubVarIndex(int16 varIndex, uint32 subNameHash) { return subVarIndex; } -void GameVars::dumpVars() { +void GameVars::dumpVars(Console *con) { for (Common::Array<GameVar>::iterator it = _vars.begin(); it != _vars.end(); ++it) { GameVar gameVar = *it; - debug("%08X %08X %3d %3d", gameVar.nameHash, gameVar.value, gameVar.firstIndex, gameVar.nextIndex); + con->DebugPrintf("hash: %08X, var: %08X, first index: %3d, next index: %3d\n", gameVar.nameHash, gameVar.value, gameVar.firstIndex, gameVar.nextIndex); } } diff --git a/engines/neverhood/gamevars.h b/engines/neverhood/gamevars.h index 5337c13394..de9ffb8ec5 100644 --- a/engines/neverhood/gamevars.h +++ b/engines/neverhood/gamevars.h @@ -169,6 +169,8 @@ struct GameVar { int16 firstIndex, nextIndex; }; +class Console; + class GameVars { public: GameVars(); @@ -179,7 +181,7 @@ public: void setGlobalVar(uint32 nameHash, uint32 value); uint32 getSubVar(uint32 nameHash, uint32 subNameHash); void setSubVar(uint32 nameHash, uint32 subNameHash, uint32 value); - void dumpVars(); + void dumpVars(Console *con); protected: Common::Array<GameVar> _vars; int16 addVar(uint32 nameHash, uint32 value); diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp index 5099c7a00e..66a7999e59 100644 --- a/engines/neverhood/graphics.cpp +++ b/engines/neverhood/graphics.cpp @@ -26,9 +26,9 @@ namespace Neverhood { -BaseSurface::BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height) +BaseSurface::BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, Common::String name) : _vm(vm), _priority(priority), _visible(true), _transparent(true), - _clipRects(NULL), _clipRectsCount(0), _version(0) { + _clipRects(NULL), _clipRectsCount(0), _version(0), _name(name) { _drawRect.x = 0; _drawRect.y = 0; @@ -130,7 +130,7 @@ void BaseSurface::copyFrom(Graphics::Surface *sourceSurface, int16 x, int16 y, N // ShadowSurface ShadowSurface::ShadowSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, BaseSurface *shadowSurface) - : BaseSurface(vm, priority, width, height), _shadowSurface(shadowSurface) { + : BaseSurface(vm, priority, width, height, "shadow"), _shadowSurface(shadowSurface) { // Empty } @@ -143,7 +143,7 @@ void ShadowSurface::draw() { // FontSurface FontSurface::FontSurface(NeverhoodEngine *vm, NPointArray *tracking, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight) - : BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows), _charsPerRow(charsPerRow), _numRows(numRows), + : BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows, "font"), _charsPerRow(charsPerRow), _numRows(numRows), _firstChar(firstChar), _charWidth(charWidth), _charHeight(charHeight), _tracking(NULL) { _tracking = new NPointArray(); @@ -152,7 +152,7 @@ FontSurface::FontSurface(NeverhoodEngine *vm, NPointArray *tracking, uint charsP } FontSurface::FontSurface(NeverhoodEngine *vm, uint32 fileHash, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight) - : BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows), _charsPerRow(charsPerRow), _numRows(numRows), + : BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows, "font"), _charsPerRow(charsPerRow), _numRows(numRows), _firstChar(firstChar), _charWidth(charWidth), _charHeight(charHeight), _tracking(NULL) { SpriteResource fontSpriteResource(_vm); @@ -343,7 +343,7 @@ void unpackSpriteNormal(const byte *source, int width, int height, byte *dest, i int calcDistance(int16 x1, int16 y1, int16 x2, int16 y2) { const int16 deltaX = ABS(x1 - x2); const int16 deltaY = ABS(y1 - y2); - return sqrt((double)(deltaX * deltaX + deltaY * deltaY)); + return (int)sqrt((double)(deltaX * deltaX + deltaY * deltaY)); } } // End of namespace Neverhood diff --git a/engines/neverhood/graphics.h b/engines/neverhood/graphics.h index a0ac1f09d5..9ab0d87ab9 100644 --- a/engines/neverhood/graphics.h +++ b/engines/neverhood/graphics.h @@ -83,7 +83,7 @@ class MouseCursorResource; class BaseSurface { public: - BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height); + BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, Common::String name); virtual ~BaseSurface(); virtual void draw(); void clear(); @@ -104,10 +104,12 @@ public: void setVisible(bool value) { _visible = value; } void setTransparent(bool value) { _transparent = value; } Graphics::Surface *getSurface() { return _surface; } + const Common::String getName() const { return _name; } protected: NeverhoodEngine *_vm; int _priority; bool _visible; + Common::String _name; Graphics::Surface *_surface; NDrawRect _drawRect; NDrawRect _sysRect; diff --git a/engines/neverhood/klaymen.cpp b/engines/neverhood/klaymen.cpp index 06d606e18d..70567806fa 100644 --- a/engines/neverhood/klaymen.cpp +++ b/engines/neverhood/klaymen.cpp @@ -434,7 +434,7 @@ void Klaymen::stopWalking() { } void Klaymen::startIdleAnimation(uint32 fileHash, AnimationCb callback) { - debug("startIdleAnimation(%08X)", fileHash); + debug(1, "startIdleAnimation(%08X)", fileHash); NextState(callback); SetUpdateHandler(&Klaymen::upIdleAnimation); } diff --git a/engines/neverhood/menumodule.cpp b/engines/neverhood/menumodule.cpp index a8631cb0d6..accdaca63f 100644 --- a/engines/neverhood/menumodule.cpp +++ b/engines/neverhood/menumodule.cpp @@ -73,12 +73,14 @@ MenuModule::MenuModule(NeverhoodEngine *vm, Module *parentModule, int which) _savedPaletteData = _vm->_screen->getPaletteData(); _vm->_mixer->pauseAll(true); + _vm->toggleSoundUpdate(false); createScene(MAIN_MENU, -1); } MenuModule::~MenuModule() { _vm->_mixer->pauseAll(false); + _vm->toggleSoundUpdate(true); _vm->_screen->setPaletteData(_savedPaletteData); } @@ -608,7 +610,7 @@ void TextEditWidget::initialize() { _textLabelWidget->initialize(); if (_cursorFileHash != 0) { cursorSpriteResource.load(_cursorFileHash, true); - _cursorSurface = new BaseSurface(_vm, 0, cursorSpriteResource.getDimensions().width, cursorSpriteResource.getDimensions().height); + _cursorSurface = new BaseSurface(_vm, 0, cursorSpriteResource.getDimensions().width, cursorSpriteResource.getDimensions().height, "cursor"); _cursorSurface->drawSpriteResourceEx(cursorSpriteResource, false, false, cursorSpriteResource.getDimensions().width, cursorSpriteResource.getDimensions().height); _cursorSurface->setVisible(!_readOnly); } @@ -821,7 +823,7 @@ void SavegameListBox::scrollUp() { } void SavegameListBox::scrollDown() { - if (_lastVisibleItem < (int)_textLabelItems.size()) { + if (_lastVisibleItem < (int)_textLabelItems.size() - 1) { ++_firstVisibleItem; ++_lastVisibleItem; refresh(); @@ -838,7 +840,7 @@ void SavegameListBox::pageUp() { } void SavegameListBox::pageDown() { - int amount = MIN((int)_textLabelItems.size() - _lastVisibleItem, _maxVisibleItemsCount); + int amount = MIN((int)_textLabelItems.size() - _lastVisibleItem - 1, _maxVisibleItemsCount); if (amount > 0) { _firstVisibleItem += amount; _lastVisibleItem += amount; diff --git a/engines/neverhood/module.h b/engines/neverhood/module.h index e98012cbea..ba1e1fa3db 100644 --- a/engines/neverhood/module.h +++ b/engines/neverhood/module.h @@ -48,9 +48,10 @@ public: Module(NeverhoodEngine *vm, Module *parentModule); virtual ~Module(); virtual void draw(); + + Entity *_childObject; protected: Module *_parentModule; - Entity *_childObject; bool _done; uint32 _moduleResult; SceneType _sceneType; diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk index 714fc3079b..030c78a407 100644 --- a/engines/neverhood/module.mk +++ b/engines/neverhood/module.mk @@ -3,6 +3,7 @@ MODULE := engines/neverhood MODULE_OBJS = \ background.o \ blbarchive.o \ + console.o \ detection.o \ diskplayerscene.o \ entity.o \ diff --git a/engines/neverhood/modules/module1000.cpp b/engines/neverhood/modules/module1000.cpp index 415d0f72b1..a28d934cf6 100644 --- a/engines/neverhood/modules/module1000.cpp +++ b/engines/neverhood/modules/module1000.cpp @@ -27,8 +27,6 @@ namespace Neverhood { Module1000::Module1000(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - debug("Create Module1000(%d)", which); - _musicFileHash = getGlobalVar(V_ENTRANCE_OPEN) ? 0x81106480 : 0x00103144; _vm->_soundMan->addMusic(0x03294419, 0x061880C6); @@ -48,7 +46,7 @@ Module1000::~Module1000() { } void Module1000::createScene(int sceneNum, int which) { - debug("Module1000::createScene(%d, %d)", sceneNum, which); + debug(1, "Module1000::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module1100.cpp b/engines/neverhood/modules/module1100.cpp index 5a5e52e5b0..dbd8c60210 100644 --- a/engines/neverhood/modules/module1100.cpp +++ b/engines/neverhood/modules/module1100.cpp @@ -64,7 +64,8 @@ Module1100::~Module1100() { void Module1100::createScene(int sceneNum, int which) { static const uint32 kSmackerFileHashList06[] = {0x10880805, 0x1088081D, 0}; static const uint32 kSmackerFileHashList07[] = {0x00290321, 0x01881000, 0}; - debug("Module1100::createScene(%d, %d)", sceneNum, which); + static const byte kNavigationTypes02[] = {1, 0, 4, 1}; + debug(1, "Module1100::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: @@ -80,9 +81,9 @@ void Module1100::createScene(int sceneNum, int which) { case 2: _vm->gameState().sceneNum = 2; if (getGlobalVar(V_ROBOT_TARGET)) { - createNavigationScene(0x004B84F0, which); + createNavigationScene(0x004B84F0, which, kNavigationTypes02); } else { - createNavigationScene(0x004B8490, which); + createNavigationScene(0x004B8490, which, kNavigationTypes02); } break; case 3: @@ -465,7 +466,7 @@ uint32 Scene1105::handleMessage(int messageNum, const MessageParam ¶m, Entit _backgroundIndex = 15; SetUpdateHandler(&Scene1105::upClosePanel); } else - _isPanelOpen = true; + _isClosePanelDone = true; _leaveResult = 0; } } @@ -625,13 +626,6 @@ void Scene1105::upClosePanel() { } void Scene1105::update() { - - // DEBUG: Show the correct code - debug("(%d, %d) (%d, %d) (%d, %d)", - getSubVar(VA_GOOD_DICE_NUMBERS, 0), getSubVar(VA_CURR_DICE_NUMBERS, 0), - getSubVar(VA_GOOD_DICE_NUMBERS, 1), getSubVar(VA_CURR_DICE_NUMBERS, 1), - getSubVar(VA_GOOD_DICE_NUMBERS, 2), getSubVar(VA_CURR_DICE_NUMBERS, 2)); - Scene::update(); if (_countdown != 0 && (--_countdown == 0)) createObjects(); diff --git a/engines/neverhood/modules/module1200.cpp b/engines/neverhood/modules/module1200.cpp index 3be3635645..3e67ddb35a 100644 --- a/engines/neverhood/modules/module1200.cpp +++ b/engines/neverhood/modules/module1200.cpp @@ -45,7 +45,7 @@ Module1200::~Module1200() { } void Module1200::createScene(int sceneNum, int which) { - debug("Module1200::createScene(%d, %d)", sceneNum, which); + debug(1, "Module1200::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module1300.cpp b/engines/neverhood/modules/module1300.cpp index 8dbfcf616c..cc5c22085c 100644 --- a/engines/neverhood/modules/module1300.cpp +++ b/engines/neverhood/modules/module1300.cpp @@ -109,7 +109,7 @@ Module1300::~Module1300() { } void Module1300::createScene(int sceneNum, int which) { - debug("Module1300::createScene(%d, %d)", sceneNum, which); + debug(1, "Module1300::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 1: @@ -1711,6 +1711,7 @@ Scene1317::Scene1317(NeverhoodEngine *vm, Module *parentModule) void Scene1317::update() { if (_smackerFileHash) { _smackerPlayer->open(_smackerFileHash, _keepLastSmackerFrame); + _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder()); _smackerFileHash = 0; } Scene::update(); @@ -1733,6 +1734,7 @@ void Scene1317::upChooseKing() { if (_smackerFileHash) { _smackerPlayer->open(_smackerFileHash, _keepLastSmackerFrame); + _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder()); _smackerFileHash = 0; } diff --git a/engines/neverhood/modules/module1400.cpp b/engines/neverhood/modules/module1400.cpp index 4f69637ee0..56c6ca5f13 100644 --- a/engines/neverhood/modules/module1400.cpp +++ b/engines/neverhood/modules/module1400.cpp @@ -47,7 +47,7 @@ Module1400::~Module1400() { } void Module1400::createScene(int sceneNum, int which) { - debug("Module1400::createScene(%d, %d)", sceneNum, which); + debug(1, "Module1400::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module1500.cpp b/engines/neverhood/modules/module1500.cpp index 2a9597b1fd..00d64a8c2d 100644 --- a/engines/neverhood/modules/module1500.cpp +++ b/engines/neverhood/modules/module1500.cpp @@ -35,7 +35,7 @@ Module1500::Module1500(NeverhoodEngine *vm, Module *parentModule, int which) } void Module1500::createScene(int sceneNum, int which) { - debug("Module1500::createScene(%d, %d)", sceneNum, which); + debug(1, "Module1500::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module1600.cpp b/engines/neverhood/modules/module1600.cpp index f7e3c37d84..40faa1e82d 100644 --- a/engines/neverhood/modules/module1600.cpp +++ b/engines/neverhood/modules/module1600.cpp @@ -59,7 +59,7 @@ Module1600::~Module1600() { } void Module1600::createScene(int sceneNum, int which) { - debug("Module1600::createScene(%d, %d)", sceneNum, which); + debug(1, "Module1600::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module1600.h b/engines/neverhood/modules/module1600.h index 0bf44ff7b8..5f0da528ab 100644 --- a/engines/neverhood/modules/module1600.h +++ b/engines/neverhood/modules/module1600.h @@ -26,6 +26,7 @@ #include "neverhood/neverhood.h" #include "neverhood/module.h" #include "neverhood/scene.h" +#include "neverhood/console.h" #include "neverhood/modules/module3000.h" namespace Neverhood { @@ -162,6 +163,7 @@ protected: }; class Scene1609 : public Scene { + friend class Console; public: Scene1609(NeverhoodEngine *vm, Module *parentModule); protected: diff --git a/engines/neverhood/modules/module1700.cpp b/engines/neverhood/modules/module1700.cpp index 3a6d1f80cb..38ed561d51 100644 --- a/engines/neverhood/modules/module1700.cpp +++ b/engines/neverhood/modules/module1700.cpp @@ -58,7 +58,7 @@ Module1700::~Module1700() { } void Module1700::createScene(int sceneNum, int which) { - debug("Module1700::createScene(%d, %d)", sceneNum, which); + debug(1, "Module1700::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module1800.cpp b/engines/neverhood/modules/module1800.cpp index 2a6057f9c8..b7371c9a4a 100644 --- a/engines/neverhood/modules/module1800.cpp +++ b/engines/neverhood/modules/module1800.cpp @@ -61,7 +61,7 @@ Module1800::~Module1800() { void Module1800::createScene(int sceneNum, int which) { static const byte kNavigationTypes00[] = {1, 0, 2, 0}; static const byte kNavigationTypes01[] = {5}; - debug("Module1800::createScene(%d, %d)", sceneNum, which); + debug(1, "Module1800::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module1900.cpp b/engines/neverhood/modules/module1900.cpp index 1a9ffa127b..7f08b01d3f 100644 --- a/engines/neverhood/modules/module1900.cpp +++ b/engines/neverhood/modules/module1900.cpp @@ -52,7 +52,7 @@ Module1900::~Module1900() { } void Module1900::createScene(int sceneNum, int which) { - debug("Module1900::createScene(%d, %d)", sceneNum, which); + debug(1, "Module1900::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module2000.cpp b/engines/neverhood/modules/module2000.cpp index 5039da1b01..644b7c479a 100644 --- a/engines/neverhood/modules/module2000.cpp +++ b/engines/neverhood/modules/module2000.cpp @@ -43,7 +43,7 @@ Module2000::~Module2000() { } void Module2000::createScene(int sceneNum, int which) { - debug("Module2000::createScene(%d, %d)", sceneNum, which); + debug(1, "Module2000::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module2100.cpp b/engines/neverhood/modules/module2100.cpp index 0d7f3dd22a..b664e93dde 100644 --- a/engines/neverhood/modules/module2100.cpp +++ b/engines/neverhood/modules/module2100.cpp @@ -47,7 +47,7 @@ Module2100::~Module2100() { } void Module2100::createScene(int sceneNum, int which) { - debug("Module2100::createScene(%d, %d)", sceneNum, which); + debug(1, "Module2100::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module2200.cpp b/engines/neverhood/modules/module2200.cpp index 4f2d9e8fd2..08ed274eb3 100644 --- a/engines/neverhood/modules/module2200.cpp +++ b/engines/neverhood/modules/module2200.cpp @@ -31,8 +31,6 @@ namespace Neverhood { Module2200::Module2200(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - debug("Create Module2200(%d)", which); - _vm->_soundMan->addMusic(0x11391412, 0x601C908C); if (which < 0) @@ -47,7 +45,7 @@ Module2200::~Module2200() { } void Module2200::createScene(int sceneNum, int which) { - debug("Module2200::createScene(%d, %d)", sceneNum, which); + debug(1, "Module2200::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: @@ -2142,17 +2140,17 @@ Scene2208::Scene2208(NeverhoodEngine *vm, Module *parentModule, int which) _fontSurface = FontSurface::createFontSurface(_vm, 0x0800090C); - _backgroundSurface = new BaseSurface(_vm, 0, 640, 480); + _backgroundSurface = new BaseSurface(_vm, 0, 640, 480, "background"); spriteResource.load(0x08100289, true); _backgroundSurface->drawSpriteResourceEx(spriteResource, false, false, 0, 0); - _topBackgroundSurface = new BaseSurface(_vm, 0, 640, 192); + _topBackgroundSurface = new BaseSurface(_vm, 0, 640, 192, "top background"); spriteResource.load(!getGlobalVar(V_COLUMN_BACK_NAME) ? kScene2208FileHashes1[getGlobalVar(V_CLICKED_COLUMN_INDEX) % 6] : getGlobalVar(V_COLUMN_BACK_NAME), true); _topBackgroundSurface->drawSpriteResourceEx(spriteResource, false, false, 0, 0); - _bottomBackgroundSurface = new BaseSurface(_vm, 0, 640, 192); + _bottomBackgroundSurface = new BaseSurface(_vm, 0, 640, 192, "bottom background"); spriteResource.load(kScene2208FileHashes2[getGlobalVar(V_CLICKED_COLUMN_INDEX) % 6], true); _bottomBackgroundSurface->drawSpriteResourceEx(spriteResource, false, false, 0, 0); diff --git a/engines/neverhood/modules/module2300.cpp b/engines/neverhood/modules/module2300.cpp index 34eca14bea..b434fb98c0 100644 --- a/engines/neverhood/modules/module2300.cpp +++ b/engines/neverhood/modules/module2300.cpp @@ -68,7 +68,7 @@ Module2300::~Module2300() { } void Module2300::createScene(int sceneNum, int which) { - debug("Module2300::createScene(%d, %d)", sceneNum, which); + debug(1, "Module2300::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module2400.cpp b/engines/neverhood/modules/module2400.cpp index 450812a5f3..47f842b939 100644 --- a/engines/neverhood/modules/module2400.cpp +++ b/engines/neverhood/modules/module2400.cpp @@ -41,7 +41,7 @@ Module2400::~Module2400() { } void Module2400::createScene(int sceneNum, int which) { - debug("Module2400::createScene(%d, %d)", sceneNum, which); + debug(1, "Module2400::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module2500.cpp b/engines/neverhood/modules/module2500.cpp index a997b5aab1..e3a3b74280 100644 --- a/engines/neverhood/modules/module2500.cpp +++ b/engines/neverhood/modules/module2500.cpp @@ -73,7 +73,7 @@ Module2500::~Module2500() { } void Module2500::createScene(int sceneNum, int which) { - debug("Module2500::createScene(%d, %d)", sceneNum, which); + debug(1, "Module2500::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module2600.cpp b/engines/neverhood/modules/module2600.cpp index b8dbf7bff1..56b4c65f8d 100644 --- a/engines/neverhood/modules/module2600.cpp +++ b/engines/neverhood/modules/module2600.cpp @@ -54,7 +54,7 @@ Module2600::~Module2600() { } void Module2600::createScene(int sceneNum, int which) { - debug("Module2600::createScene(%d, %d)", sceneNum, which); + debug(1, "Module2600::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module2700.cpp b/engines/neverhood/modules/module2700.cpp index 8b69bc050e..19655d128b 100644 --- a/engines/neverhood/modules/module2700.cpp +++ b/engines/neverhood/modules/module2700.cpp @@ -111,7 +111,7 @@ Module2700::~Module2700() { } void Module2700::createScene(int sceneNum, int which) { - debug("Module2700::createScene(%d, %d)", sceneNum, which); + debug(1, "Module2700::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module2800.cpp b/engines/neverhood/modules/module2800.cpp index 183de8e6b2..3d76d05762 100644 --- a/engines/neverhood/modules/module2800.cpp +++ b/engines/neverhood/modules/module2800.cpp @@ -58,7 +58,7 @@ Module2800::~Module2800() { } void Module2800::createScene(int sceneNum, int which) { - debug("Module2800::createScene(%d, %d)", sceneNum, which); + debug(1, "Module2800::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: @@ -616,10 +616,6 @@ void Scene2802::update() { if (prevTuneStatus != _currTuneStatus) changeTuneStatus(prevTuneStatus, _currTuneStatus); - //DEBUG>>> - //debug("_currRadioMusicIndex = %d; V_GOOD_RADIO_MUSIC_INDEX = %d", _currRadioMusicIndex, getGlobalVar(V_GOOD_RADIO_MUSIC_INDEX)); - //DEBUG<<< - if (getGlobalVar(V_RADIO_MOVE_DISH_VIDEO) && prevTuneStatus != _currTuneStatus && _currRadioMusicIndex != 0) { setGlobalVar(V_RADIO_MOVE_DISH_VIDEO, 0); leaveScene(1); @@ -1929,8 +1925,6 @@ Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which) Sprite *tempSprite; - which = 3; - SetMessageHandler(&Scene2806::handleMessage); SetUpdateHandler(&Scene2806::update); @@ -2445,18 +2439,6 @@ uint32 Scene2808::handleMessage(int messageNum, const MessageParam ¶m, Entit } void Scene2808::update() { - - // DEBUG>>> Show correct values - #if 1 - debug("---------------"); - if (_testTubeSetNum == 0) - debug("%03d %03d %03d", getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0), getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 1), getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 2)); - else - debug("%03d %03d %03d", getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 0), getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 1), getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 2)); - debug("%03d %03d %03d", _asTestTubes[0]->getFillLevel(), _asTestTubes[1]->getFillLevel(), _asTestTubes[2]->getFillLevel()); - #endif - // DEBUG<<< - Scene::update(); if (_countdown != 0 && (--_countdown) == 0) { leaveScene(_leaveResult); diff --git a/engines/neverhood/modules/module2900.cpp b/engines/neverhood/modules/module2900.cpp index bd95b82f4c..248fb81bdc 100644 --- a/engines/neverhood/modules/module2900.cpp +++ b/engines/neverhood/modules/module2900.cpp @@ -42,7 +42,7 @@ Module2900::Module2900(NeverhoodEngine *vm, Module *parentModule, int which) } void Module2900::createScene(int sceneNum, int which) { - debug("Module2900::createScene(%d, %d)", sceneNum, which); + debug(1, "Module2900::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: diff --git a/engines/neverhood/modules/module3000.cpp b/engines/neverhood/modules/module3000.cpp index 2bdb9f0497..373bfb57f6 100644 --- a/engines/neverhood/modules/module3000.cpp +++ b/engines/neverhood/modules/module3000.cpp @@ -75,7 +75,7 @@ Module3000::~Module3000() { void Module3000::createScene(int sceneNum, int which) { static const byte kNavigationTypes05[] = {3, 0}; static const byte kNavigationTypes06[] = {5}; - debug("Module3000::createScene(%d, %d)", sceneNum, which); + debug(1, "Module3000::createScene(%d, %d)", sceneNum, which); _vm->gameState().sceneNum = sceneNum; switch (_vm->gameState().sceneNum) { case 1: @@ -786,8 +786,8 @@ Scene3009::Scene3009(NeverhoodEngine *vm, Module *parentModule, int which) } } - _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, kScene3009CannonScopeVideos[_cannonTargetStatus], false, _keepVideo)); - _smackerPlayer->setDrawPos(89, 37); + _cannonSmackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, kScene3009CannonScopeVideos[_cannonTargetStatus], false, _keepVideo)); + _cannonSmackerPlayer->setDrawPos(89, 37); _palette->usePalette(); // Use it again since the SmackerPlayer overrides the usage insertStaticSprite(0x8540252C, 400); @@ -807,42 +807,39 @@ Scene3009::Scene3009(NeverhoodEngine *vm, Module *parentModule, int which) SetMessageHandler(&Scene3009::handleMessage); SetUpdateHandler(&Scene3009::update); +} - // DEBUG Enable to set the correct code -#if 0 - for (int i = 0; i < 6; i++) - setSubVar(VA_CURR_CANNON_SYMBOLS, i, _correctSymbols[i]); - sendMessage(this, 0x2003, 0); -#endif +Scene3009::~Scene3009() { +} +void Scene3009::openSmacker(uint32 fileHash, bool keepLastFrame) { + _cannonSmackerPlayer->open(fileHash, keepLastFrame); + //_vm->_screen->setSmackerDecoder(_cannonSmackerPlayer->getSmackerDecoder()); + _palette->usePalette(); } void Scene3009::update() { Scene::update(); - if (!_keepVideo && _smackerPlayer->isDone() && _cannonTargetStatus <= kCTSCount) { + if (!_keepVideo && _cannonSmackerPlayer->isDone() && _cannonTargetStatus <= kCTSCount) { switch (_cannonTargetStatus) { case kCTSNull: case kCTSLowerCannon: - _smackerPlayer->open(0x340A0049, true); - _palette->usePalette(); + openSmacker(0x340A0049, true); _keepVideo = true; break; case kCTSRightRobotNoTarget: - _smackerPlayer->open(0x0082080D, true); - _palette->usePalette(); + openSmacker(0x0082080D, true); _keepVideo = true; _isTurning = false; break; case kCTSRightRobotIsTarget: - _smackerPlayer->open(0x0282080D, true); - _palette->usePalette(); + openSmacker(0x0282080D, true); _keepVideo = true; _isTurning = false; break; case kCTSRightNoRobot: - _smackerPlayer->open(0x0882080D, true); - _palette->usePalette(); + openSmacker(0x0882080D, true); _keepVideo = true; _isTurning = false; break; @@ -851,12 +848,11 @@ void Scene3009::update() { case kCTSLeftNoRobot: if (_moveCannonLeftFirst) { if (_cannonTargetStatus == kCTSLeftRobotNoTarget) - _smackerPlayer->open(0x110A000F, false); + openSmacker(0x110A000F, false); else if (_cannonTargetStatus == kCTSLeftRobotIsTarget) - _smackerPlayer->open(0x500B004F, false); + openSmacker(0x500B004F, false); else if (_cannonTargetStatus == kCTSLeftNoRobot) - _smackerPlayer->open(0x100B010E, false); - _palette->usePalette(); + openSmacker(0x100B010E, false); _moveCannonLeftFirst = false; _asHorizontalIndicator->stMoveLeft(); } else { @@ -955,15 +951,14 @@ uint32 Scene3009::handleMessage(int messageNum, const MessageParam ¶m, Entit // Cannon is at the right position if (!getGlobalVar(V_ROBOT_TARGET)) { _cannonTargetStatus = kCTSLeftRobotNoTarget; - _smackerPlayer->open(0x108A000F, false); + openSmacker(0x108A000F, false); } else if (!getGlobalVar(V_ROBOT_HIT)) { _cannonTargetStatus = kCTSLeftRobotIsTarget; - _smackerPlayer->open(0x500B002F, false); + openSmacker(0x500B002F, false); } else { _cannonTargetStatus = kCTSLeftNoRobot; - _smackerPlayer->open(0x100B008E, false); + openSmacker(0x100B008E, false); } - _palette->usePalette(); _moveCannonLeftFirst = true; _isTurning = true; _keepVideo = false; @@ -1224,13 +1219,6 @@ Scene3010::Scene3010(NeverhoodEngine *vm, Module *parentModule, int which) int initCountdown = 0; - // DEBUG Enable to activate all buttons -#if 0 - setSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[0], 1); - setSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[1], 1); - setSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[2], 1); -#endif - setBackground(0x80802626); setPalette(0x80802626); diff --git a/engines/neverhood/modules/module3000.h b/engines/neverhood/modules/module3000.h index 7634360d7c..797be1885f 100644 --- a/engines/neverhood/modules/module3000.h +++ b/engines/neverhood/modules/module3000.h @@ -128,11 +128,12 @@ protected: class Scene3009 : public Scene { public: Scene3009(NeverhoodEngine *vm, Module *parentModule, int which); + virtual ~Scene3009(); bool isTurning(); protected: int _lockSymbolsPart1Countdown; int _lockSymbolsPart2Countdown; - SmackerPlayer *_smackerPlayer; + SmackerPlayer *_cannonSmackerPlayer; Sprite *_ssFireCannonButton; SsScene3009SymbolEdges *_ssSymbolEdges[2]; SsScene3009TargetLine *_ssTargetLines[2]; @@ -149,6 +150,7 @@ protected: void playActionVideo(); bool isSymbolsPart1Solved(); bool isSymbolsPart2Solved(); + void openSmacker(uint32 fileHash, bool keepLastFrame); }; // Scene3010 diff --git a/engines/neverhood/navigationscene.cpp b/engines/neverhood/navigationscene.cpp index 9752ee618c..33e2a264a8 100644 --- a/engines/neverhood/navigationscene.cpp +++ b/engines/neverhood/navigationscene.cpp @@ -41,9 +41,7 @@ NavigationScene::NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint SetUpdateHandler(&NavigationScene::update); SetMessageHandler(&NavigationScene::handleMessage); - _smackerPlayer = new SmackerPlayer(_vm, this, (*_navigationList)[_navigationIndex].fileHash, true, true); - addEntity(_smackerPlayer); - addSurface(_smackerPlayer->getSurface()); + _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, (*_navigationList)[_navigationIndex].fileHash, true, true)); createMouseCursor(); @@ -69,7 +67,7 @@ int NavigationScene::getNavigationAreaType() { void NavigationScene::update() { if (_smackerFileHash != 0) { showMouse(false); - openSmacker(_smackerFileHash, false); + _smackerPlayer->open(_smackerFileHash, false); _vm->_screen->clear(); _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder()); _smackerDone = false; @@ -92,7 +90,7 @@ void NavigationScene::update() { _vm->_soundMan->setTwoSoundsPlayFlag(false); _vm->_soundMan->setSoundThreePlayFlag(false); _smackerDone = false; - openSmacker(navigationItem.fileHash, true); + _smackerPlayer->open(navigationItem.fileHash, true); _vm->_screen->clear(); _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder()); sendMessage(_parentModule, 0x100A, _navigationIndex); @@ -101,13 +99,6 @@ void NavigationScene::update() { Scene::update(); } -void NavigationScene::openSmacker(uint32 fileHash, bool keepLastFrame) { - // The old Smacker surface is deleted when a new Smacker is opened. - removeSurface(_smackerPlayer->getSurface()); - _smackerPlayer->open(fileHash, keepLastFrame); - addSurface(_smackerPlayer->getSurface()); -} - uint32 NavigationScene::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { switch (messageNum) { case 0x0000: diff --git a/engines/neverhood/navigationscene.h b/engines/neverhood/navigationscene.h index 767b3f5d20..ebe9a3597c 100644 --- a/engines/neverhood/navigationscene.h +++ b/engines/neverhood/navigationscene.h @@ -50,7 +50,6 @@ protected: bool _leaveSceneAfter; const byte *_itemsTypes; void update(); - void openSmacker(uint32 fileHash, bool keepLastFrame); uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); void createMouseCursor(); void handleNavigation(const NPoint &mousePos); diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp index 6b27343d03..d60d8b760f 100644 --- a/engines/neverhood/neverhood.cpp +++ b/engines/neverhood/neverhood.cpp @@ -22,12 +22,18 @@ #include "common/file.h" #include "common/config-manager.h" +#include "common/textconsole.h" + #include "base/plugins.h" #include "base/version.h" + #include "graphics/cursorman.h" + #include "engines/util.h" + #include "neverhood/neverhood.h" #include "neverhood/blbarchive.h" +#include "neverhood/console.h" #include "neverhood/gamemodule.h" #include "neverhood/gamevars.h" #include "neverhood/graphics.h" @@ -76,7 +82,8 @@ Common::Error NeverhoodEngine::run() { _gameVars = new GameVars(); _screen = new Screen(this); _res = new ResourceMan(); - + _console = new Console(this); + if (isDemo()) { _res->addArchive("a.blb"); _res->addArchive("nevdemo.blb"); @@ -98,7 +105,8 @@ Common::Error NeverhoodEngine::run() { _gameModule = new GameModule(this); _isSaveAllowed = true; - + _updateSound = true; + if (isDemo()) { // Adjust this navigation list for the demo version NavigationList *navigationList = _staticData->getNavigationList(0x004B67E8); @@ -123,6 +131,7 @@ Common::Error NeverhoodEngine::run() { delete _soundMan; delete _audioResourceMan; + delete _console; delete _res; delete _screen; @@ -140,6 +149,11 @@ void NeverhoodEngine::mainLoop() { while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: + if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_d) { + // Open debugger console + _console->attach(); + continue; + } _gameModule->handleKeyDown(event.kbd.keycode); _gameModule->handleAsciiKey(event.kbd.ascii); break; @@ -169,11 +183,16 @@ void NeverhoodEngine::mainLoop() { _gameModule->checkRequests(); _gameModule->handleUpdate(); _gameModule->draw(); + _console->onFrame(); _screen->update(); nextFrameTime = _screen->getNextFrameTime(); }; - _soundMan->update(); - _audioResourceMan->updateMusic(); + + if (_updateSound) { + _soundMan->update(); + _audioResourceMan->updateMusic(); + } + _system->updateScreen(); _system->delayMillis(10); } diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h index 577fbd7a66..39bc9cef2c 100644 --- a/engines/neverhood/neverhood.h +++ b/engines/neverhood/neverhood.h @@ -48,6 +48,7 @@ class Screen; class SoundMan; class AudioResourceMan; class StaticData; +class Console; struct NPoint; struct GameState { @@ -86,7 +87,8 @@ public: ResourceMan *_res; GameModule *_gameModule; StaticData *_staticData; - + Console *_console; + SoundMan *_soundMan; AudioResourceMan *_audioResourceMan; @@ -132,7 +134,10 @@ public: int16 getMouseY() const { return _mouseY; } NPoint getMousePos(); -public: + void toggleSoundUpdate(bool state) { _updateSound = state; } + +private: + bool _updateSound; }; diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp index 07d41754c9..80a2b69169 100644 --- a/engines/neverhood/scene.cpp +++ b/engines/neverhood/scene.cpp @@ -20,6 +20,7 @@ * */ +#include "neverhood/console.h" #include "neverhood/scene.h" namespace Neverhood { @@ -58,6 +59,8 @@ Scene::Scene(NeverhoodEngine *vm, Module *parentModule) Scene::~Scene() { + _vm->_screen->setSmackerDecoder(NULL); + if (_palette) { removeEntity(_palette); delete _palette; @@ -135,6 +138,18 @@ bool Scene::removeSurface(BaseSurface *surface) { return false; } +void Scene::printSurfaces(Console *con) { + for (uint index = 0; index < _surfaces.size(); index++) { + NDrawRect drawRect = _surfaces[index]->getDrawRect(); + NRect clipRect = _surfaces[index]->getClipRect(); + int priority = _surfaces[index]->getPriority(); + con->DebugPrintf("%d ('%s'): Priority %d, draw rect (%d, %d, %d, %d), clip rect (%d, %d, %d, %d)\n", + index, _surfaces[index]->getName().c_str(), priority, + drawRect.x, drawRect.y, drawRect.x2(), drawRect.y2(), + clipRect.x1, clipRect.y1, clipRect.x2, clipRect.y2); + } +} + Sprite *Scene::addSprite(Sprite *sprite) { addEntity(sprite); addSurface(sprite->getSurface()); diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h index 1abcbfb964..813ffba0bb 100644 --- a/engines/neverhood/scene.h +++ b/engines/neverhood/scene.h @@ -37,6 +37,8 @@ namespace Neverhood { +class Console; + class Scene : public Entity { public: Scene(NeverhoodEngine *vm, Module *parentModule); @@ -46,6 +48,7 @@ public: bool removeEntity(Entity *entity); void addSurface(BaseSurface *surface); bool removeSurface(BaseSurface *surface); + void printSurfaces(Console *con); Sprite *addSprite(Sprite *sprite); void removeSprite(Sprite *sprite); void setSurfacePriority(BaseSurface *surface, int priority); diff --git a/engines/neverhood/smackerplayer.cpp b/engines/neverhood/smackerplayer.cpp index b67c8db9fc..21d8851f48 100644 --- a/engines/neverhood/smackerplayer.cpp +++ b/engines/neverhood/smackerplayer.cpp @@ -31,7 +31,7 @@ namespace Neverhood { // SmackerSurface SmackerSurface::SmackerSurface(NeverhoodEngine *vm) - : BaseSurface(vm, 0, 0, 0), _smackerFrame(NULL) { + : BaseSurface(vm, 0, 0, 0, "smacker"), _smackerFrame(NULL) { } void SmackerSurface::draw() { @@ -51,6 +51,18 @@ void SmackerSurface::setSmackerFrame(const Graphics::Surface *smackerFrame) { _smackerFrame = smackerFrame; } +void SmackerSurface::unsetSmackerFrame() { + _drawRect.x = 0; + _drawRect.y = 0; + _drawRect.width = 0; + _drawRect.height = 0; + _sysRect.x = 0; + _sysRect.y = 0; + _sysRect.width = 0; + _sysRect.height = 0; + _smackerFrame = NULL; +} + // SmackerDoubleSurface SmackerDoubleSurface::SmackerDoubleSurface(NeverhoodEngine *vm) @@ -62,6 +74,8 @@ void SmackerDoubleSurface::draw() { _vm->_screen->drawDoubleSurface2(_smackerFrame, _drawRect); } +// NeverhoodSmackerDecoder + void NeverhoodSmackerDecoder::forceSeekToFrame(uint frame) { if (!isVideoLoaded()) return; @@ -92,11 +106,20 @@ SmackerPlayer::SmackerPlayer(NeverhoodEngine *vm, Scene *scene, uint32 fileHash, _drawX(-1), _drawY(-1) { SetUpdateHandler(&SmackerPlayer::update); + + if (_doubleSurface) { + _smackerSurface = new SmackerDoubleSurface(_vm); + } else { + _smackerSurface = new SmackerSurface(_vm); + } + open(fileHash, flag); } SmackerPlayer::~SmackerPlayer() { close(); + delete _smackerSurface; + _smackerSurface = NULL; } void SmackerPlayer::open(uint32 fileHash, bool keepLastFrame) { @@ -107,12 +130,6 @@ void SmackerPlayer::open(uint32 fileHash, bool keepLastFrame) { close(); - if (_doubleSurface) { - _smackerSurface = new SmackerDoubleSurface(_vm); - } else { - _smackerSurface = new SmackerSurface(_vm); - } - _smackerFirst = true; _stream = _vm->_res->createStream(fileHash); @@ -134,11 +151,10 @@ void SmackerPlayer::close() { delete _smackerDecoder; delete _palette; // NOTE The SmackerDecoder deletes the _stream - delete _smackerSurface; _smackerDecoder = NULL; _palette = NULL; _stream = NULL; - _smackerSurface = NULL; + _smackerSurface->unsetSmackerFrame(); } void SmackerPlayer::gotoFrame(int frameNumber) { @@ -200,6 +216,10 @@ void SmackerPlayer::update() { } void SmackerPlayer::updateFrame() { + + if (!_smackerDecoder || !_smackerSurface) + return; + const Graphics::Surface *smackerFrame = _smackerDecoder->decodeNextFrame(); if (_smackerFirst) { diff --git a/engines/neverhood/smackerplayer.h b/engines/neverhood/smackerplayer.h index 26ebff5d33..f13b653757 100644 --- a/engines/neverhood/smackerplayer.h +++ b/engines/neverhood/smackerplayer.h @@ -37,6 +37,7 @@ public: SmackerSurface(NeverhoodEngine *vm); virtual void draw(); void setSmackerFrame(const Graphics::Surface *smackerFrame); + void unsetSmackerFrame(); protected: const Graphics::Surface *_smackerFrame; }; diff --git a/engines/neverhood/sound.cpp b/engines/neverhood/sound.cpp index c84b751e44..46ec8007b0 100644 --- a/engines/neverhood/sound.cpp +++ b/engines/neverhood/sound.cpp @@ -254,10 +254,26 @@ SoundMan::SoundMan(NeverhoodEngine *vm) } SoundMan::~SoundMan() { - for (uint i = 0; i < _soundItems.size(); ++i) - delete _soundItems[i]; - for (uint i = 0; i < _musicItems.size(); ++i) - delete _musicItems[i]; + stopAllSounds(); +} + +void SoundMan::stopAllSounds() { + for (uint i = 0; i < _soundItems.size(); ++i) { + if (_soundItems[i]) { + _soundItems[i]->stopSound(); + delete _soundItems[i]; + _soundItems[i] = NULL; + } + } + for (uint i = 0; i < _musicItems.size(); ++i) { + if (_musicItems[i]) { + _musicItems[i]->stopMusic(0, 0); + delete _musicItems[i]; + _musicItems[i] = NULL; + } + } + + _soundIndex1 = _soundIndex2 = _soundIndex3 = -1; } void SoundMan::addMusic(uint32 groupNameHash, uint32 musicFileHash) { @@ -708,11 +724,25 @@ AudioResourceMan::AudioResourceMan(NeverhoodEngine *vm) : _vm(vm) { } +void AudioResourceMan::stopAllSounds() { + for (uint i = 0; i < _soundItems.size(); ++i) { + if (_soundItems[i]) { + _soundItems[i]->stopSound(); + delete _soundItems[i]; + _soundItems[i] = NULL; + } + } + for (uint i = 0; i < _musicItems.size(); ++i) { + if (_musicItems[i]) { + _musicItems[i]->stopMusic(0); + delete _musicItems[i]; + _musicItems[i] = NULL; + } + } +} + AudioResourceMan::~AudioResourceMan() { - for (uint i = 0; i < _soundItems.size(); ++i) - delete _soundItems[i]; - for (uint i = 0; i < _musicItems.size(); ++i) - delete _musicItems[i]; + stopAllSounds(); } int16 AudioResourceMan::addSound(uint32 fileHash) { diff --git a/engines/neverhood/sound.h b/engines/neverhood/sound.h index d3318998db..aa5da284ea 100644 --- a/engines/neverhood/sound.h +++ b/engines/neverhood/sound.h @@ -129,6 +129,8 @@ public: SoundMan(NeverhoodEngine *vm); ~SoundMan(); + void stopAllSounds(); + // Music void addMusic(uint32 groupNameHash, uint32 musicFileHash); void deleteMusic(uint32 musicFileHash); @@ -262,6 +264,8 @@ public: AudioResourceMan(NeverhoodEngine *vm); ~AudioResourceMan(); + void stopAllSounds(); + int16 addSound(uint32 fileHash); void removeSound(int16 soundIndex); diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp index 45d131fd3c..50880089f9 100644 --- a/engines/neverhood/sprite.cpp +++ b/engines/neverhood/sprite.cpp @@ -83,7 +83,7 @@ void Sprite::loadDataResource(uint32 fileHash) { } void Sprite::createSurface(int surfacePriority, int16 width, int16 height) { - _surface = new BaseSurface(_vm, surfacePriority, width, height); + _surface = new BaseSurface(_vm, surfacePriority, width, height, "sprite"); } int16 Sprite::defFilterY(int16 y) { @@ -398,7 +398,7 @@ void AnimatedSprite::updateFrameInfo() { void AnimatedSprite::createSurface1(uint32 fileHash, int surfacePriority) { NDimensions dimensions = _animResource.loadSpriteDimensions(fileHash); - _surface = new BaseSurface(_vm, surfacePriority, dimensions.width, dimensions.height); + _surface = new BaseSurface(_vm, surfacePriority, dimensions.width, dimensions.height, "animated sprite"); } void AnimatedSprite::createShadowSurface1(BaseSurface *shadowSurface, uint32 fileHash, int surfacePriority) { diff --git a/engines/neverhood/sprite.h b/engines/neverhood/sprite.h index 80da1768bd..1d17bf0e70 100644 --- a/engines/neverhood/sprite.h +++ b/engines/neverhood/sprite.h @@ -30,9 +30,24 @@ namespace Neverhood { -#define SetSpriteUpdate(callback) _spriteUpdateCb = static_cast <void (Sprite::*)(void)> (callback); debug(2, "SetSpriteUpdate(" #callback ")"); _spriteUpdateCbName = #callback -#define SetFilterX(callback) _filterXCb = static_cast <int16 (Sprite::*)(int16)> (callback); debug(2, "SetFilterX(" #callback ")") -#define SetFilterY(callback) _filterYCb = static_cast <int16 (Sprite::*)(int16)> (callback); debug(2, "SetFilterY(" #callback ")") +#define SetSpriteUpdate(callback) \ + do { \ + _spriteUpdateCb = static_cast <void (Sprite::*)(void)> (callback); \ + debug(2, "SetSpriteUpdate(" #callback ")"); \ + _spriteUpdateCbName = #callback; \ + } while (0) + +#define SetFilterX(callback) \ + do { \ + _filterXCb = static_cast <int16 (Sprite::*)(int16)> (callback); \ + debug(2, "SetFilterX(" #callback ")"); \ + } while (0) + +#define SetFilterY(callback) \ + do { \ + _filterYCb = static_cast <int16 (Sprite::*)(int16)> (callback); \ + debug(2, "SetFilterY(" #callback ")"); \ + } while (0) const int16 kDefPosition = -32768; @@ -113,7 +128,11 @@ protected: #define AnimationCallback(callback) static_cast <void (AnimatedSprite::*)()> (callback) #define GotoState(callback) gotoState(static_cast <void (AnimatedSprite::*)()> (callback)) -#define NextState(callback) _nextStateCb = static_cast <void (AnimatedSprite::*)(void)> (callback); debug(2, "NextState(" #callback ")"); _nextStateCbName = #callback +#define NextState(callback) \ + do { \ + _nextStateCb = static_cast <void (AnimatedSprite::*)(void)> (callback); \ + debug(2, "NextState(" #callback ")"); _nextStateCbName = #callback; \ + } while (0) #define FinalizeState(callback) setFinalizeState(static_cast <void (AnimatedSprite::*)()> (callback)); const int STICK_LAST_FRAME = -2; diff --git a/engines/saga/events.cpp b/engines/saga/events.cpp index d98cef0740..c5842f4998 100644 --- a/engines/saga/events.cpp +++ b/engines/saga/events.cpp @@ -533,6 +533,7 @@ int Events::handleOneShot(Event *event) { default: break; } + break; #ifdef ENABLE_IHNM case kCutawayEvent: switch (event->op) { @@ -545,6 +546,7 @@ int Events::handleOneShot(Event *event) { default: break; } + break; #endif case kActorEvent: switch (event->op) { @@ -554,6 +556,7 @@ int Events::handleOneShot(Event *event) { default: break; } + break; default: break; } diff --git a/engines/saga/shorten.cpp b/engines/saga/shorten.cpp index 69c27b6a6b..619ffc243e 100644 --- a/engines/saga/shorten.cpp +++ b/engines/saga/shorten.cpp @@ -196,11 +196,13 @@ byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, by break; case kTypeS16LH: flags |= Audio::FLAG_LITTLE_ENDIAN; + // fallthrough case kTypeS16HL: flags |= Audio::FLAG_16BITS; break; case kTypeU16LH: flags |= Audio::FLAG_LITTLE_ENDIAN; + // fallthrough case kTypeU16HL: flags |= Audio::FLAG_16BITS; flags |= Audio::FLAG_UNSIGNED; diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index 6af6326042..6f0b34b457 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -249,6 +249,7 @@ const SciWorkaroundEntry kDoSoundFade_workarounds[] = { { 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 { GID_QFG4, -1, 64989, 0, "longSong", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // CD version: many places, parameter 4 is an object (longSong) + { GID_SQ5, 800, 989, 0, "sq5Music1", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when cutting the wrong part of Goliath with the laser - bug #3614145 SCI_WORKAROUNDENTRY_TERMINATOR }; diff --git a/engines/sci/graphics/ports.cpp b/engines/sci/graphics/ports.cpp index 527e2ae973..6d9dc03195 100644 --- a/engines/sci/graphics/ports.cpp +++ b/engines/sci/graphics/ports.cpp @@ -116,7 +116,7 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te setPort(_wmgrPort); // SCI0 games till kq4 (.502 - not including) did not adjust against _wmgrPort in kNewWindow // We leave _wmgrPort top at 0, so the adjustment wont get done - if (!g_sci->_features->usesOldGfxFunctions()) { + if (!_usesOldGfxFunctions) { setOrigin(0, offTop); _wmgrPort->rect.bottom = _screen->getHeight() - offTop; } else { @@ -131,7 +131,7 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te _picWind = addWindow(Common::Rect(0, offTop, _screen->getWidth(), _screen->getHeight()), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true); // For SCI0 games till kq4 (.502 - not including) we set _picWind top to offTop instead // Because of the menu/status bar - if (g_sci->_features->usesOldGfxFunctions()) + if (_usesOldGfxFunctions) _picWind->top = offTop; kernelInitPriorityBands(); diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp index daba976f50..b0102a002b 100644 --- a/engines/sci/sound/soundcmd.cpp +++ b/engines/sci/sound/soundcmd.cpp @@ -530,17 +530,21 @@ void SoundCommandParser::processUpdateCues(reg_t obj) { } reg_t SoundCommandParser::kDoSoundSendMidi(int argc, reg_t *argv, reg_t acc) { + // The 4 parameter variant of this call is used in at least LSL1VGA, room + // 110 (Lefty's bar), to distort the music when Larry is drunk and stands + // up - bug #3614447. reg_t obj = argv[0]; byte channel = argv[1].toUint16() & 0xf; - byte midiCmd = argv[2].toUint16() & 0xff; + byte midiCmd = (argc == 5) ? argv[2].toUint16() & 0xff : 0xB0; // 0xB0: controller + uint16 controller = (argc == 5) ? argv[3].toUint16() : argv[2].toUint16(); + uint16 param = (argc == 5) ? argv[4].toUint16() : argv[3].toUint16(); - // 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(); + if (argc == 4 && controller == 0xFF) { + midiCmd = 0xE0; // 0xE0: pitch wheel + uint16 pitch = CLIP<uint16>(argv[3].toSint16() + 0x2000, 0x0000, 0x3FFF); + controller = pitch & 0x7F; + param = pitch >> 7; + } debugC(kDebugLevelSound, "kDoSound(sendMidi): %04x:%04x, %d, %d, %d, %d", PRINT_REG(obj), channel, midiCmd, controller, param); if (channel) diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h index fc5e4bcdf0..a674288775 100644 --- a/engines/scumm/he/intern_he.h +++ b/engines/scumm/he/intern_he.h @@ -628,7 +628,6 @@ public: void parseEvents(); - bool _quit; OSystem *_syst; GameSettings _game; diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp index a875702383..12ebfef9b7 100644 --- a/engines/scumm/imuse/imuse.cpp +++ b/engines/scumm/imuse/imuse.cpp @@ -46,7 +46,6 @@ namespace Scumm { IMuseInternal::IMuseInternal() : _native_mt32(false), _enable_gs(false), - _sc55(false), _midi_adlib(NULL), _midi_native(NULL), _sysex(NULL), @@ -495,12 +494,9 @@ uint32 IMuseInternal::property(int prop, uint32 value) { case IMuse::PROP_GS: _enable_gs = (value > 0); - // If True Roland MT-32 is not selected, run in GM or GS mode. - // If it is selected, change the Roland GS synth to MT-32 mode. - if (_midi_native && !_native_mt32) - initGM(_midi_native); - else if (_midi_native && _native_mt32 && _enable_gs) { - _sc55 = true; + // GS Mode emulates MT-32 on a GS device, so _native_mt32 should always be true + if (_midi_native && _enable_gs) { + _native_mt32 = true; initGM(_midi_native); } break; @@ -1499,7 +1495,7 @@ void IMuseInternal::initGM(MidiDriver *midi) { if (_enable_gs) { // All GS devices recognize the GS Reset command, - // even with Roland's ID. It is impractical to + // even using Roland's ID. It is impractical to // support other manufacturers' devices for // further GS settings, as there are limitless // numbers of them out there that would each @@ -1513,30 +1509,28 @@ void IMuseInternal::initGM(MidiDriver *midi) { midi->sysEx(buffer, 9); debug(2, "GS SysEx: GS Reset"); _system->delayMillis(200); + + // Set global Master Tune to 442.0kHz, as on the MT-32 + memcpy(&buffer[4], "\x40\x00\x00\x00\x04\x04\x0F\x29", 8); + midi->sysEx(buffer, 12); + debug(2, "GS SysEx: Master Tune set to 442.0kHz"); - if (_sc55) { - // This mode is for GS devices that support an MT-32-compatible - // Map, such as the Roland Sound Canvas line of modules. It - // will allow them to work with True MT-32 mode, but will - // obviously still ignore MT-32 SysEx (and thus custom - // instruments). - - // Set Channels 1-16 to SC-55 Map, then CM-64/32L Variation - for (i = 0; i < 16; ++i) { - midi->send((127 << 16) | (0 << 8) | (0xB0 | i)); - midi->send((1 << 16) | (32 << 8) | (0xB0 | i)); - midi->send((0 << 16) | (0 << 8) | (0xC0 | i)); - } - debug(2, "GS Program Change: CM-64/32L Map Selected"); - - // Set Percussion Channel to SC-55 Map (CC#32, 01H), then - // Switch Drum Map to CM-64/32L (MT-32 Compatible Drums) - midi->getPercussionChannel()->controlChange(0, 0); - midi->getPercussionChannel()->controlChange(32, 1); - midi->send(127 << 8 | 0xC0 | 9); - debug(2, "GS Program Change: Drum Map is CM-64/32L"); + // Note: All Roland GS devices support CM-64/32L maps + // Set Channels 1-16 to SC-55 Map, then CM-64/32L Variation + for (i = 0; i < 16; ++i) { + midi->send((127 << 16) | (0 << 8) | (0xB0 | i)); + midi->send((1 << 16) | (32 << 8) | (0xB0 | i)); + midi->send((0 << 16) | (0 << 8) | (0xC0 | i)); } + debug(2, "GS Program Change: CM-64/32L Map Selected"); + + // Set Percussion Channel to SC-55 Map (CC#32, 01H), then + // Switch Drum Map to CM-64/32L (MT-32 Compatible Drums) + midi->getPercussionChannel()->controlChange(0, 0); + midi->getPercussionChannel()->controlChange(32, 1); + midi->send(127 << 8 | 0xC0 | 9); + debug(2, "GS Program Change: Drum Map is CM-64/32L"); // Set Master Chorus to 0. The MT-32 has no chorus capability. memcpy(&buffer[4], "\x40\x01\x3A\x00\x05", 5); diff --git a/engines/scumm/imuse/imuse_internal.h b/engines/scumm/imuse/imuse_internal.h index 6be564a517..d17d4ed28b 100644 --- a/engines/scumm/imuse/imuse_internal.h +++ b/engines/scumm/imuse/imuse_internal.h @@ -390,7 +390,6 @@ class IMuseInternal : public IMuse { protected: bool _native_mt32; bool _enable_gs; - bool _sc55; MidiDriver *_midi_adlib; MidiDriver *_midi_native; TimerCallbackInfo _timer_info_adlib; diff --git a/engines/scumm/imuse_digi/dimuse.cpp b/engines/scumm/imuse_digi/dimuse.cpp index eb3717494f..a737539c44 100644 --- a/engines/scumm/imuse_digi/dimuse.cpp +++ b/engines/scumm/imuse_digi/dimuse.cpp @@ -275,9 +275,12 @@ void IMuseDigital::callback() { feedSize &= ~1; if (channels == 2) feedSize &= ~3; - } else { + } else if (bits == 8) { if (channels == 2) feedSize &= ~1; + } else { + warning("IMuseDigita::callback: Unexpected sample width, %d bits", bits); + continue; } if (feedSize == 0) diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index 6aad52578d..db8da21bbc 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Thu May 2 21:27:50 2013 + This file was generated by the md5table tool on Sun Jun 23 22:18:47 2013 DO NOT EDIT MANUALLY! */ @@ -124,6 +124,7 @@ static const MD5Table md5table[] = { { "28d24a33448fab6795850bc9f159a4a2", "atlantis", "FM-TOWNS", "Demo", 11170, Common::JA_JPN, Common::kPlatformFMTowns }, { "28ef68ee3ed76d7e2ee8ee13c15fbd5b", "loom", "EGA", "EGA", 5748, Common::EN_ANY, Common::kPlatformDOS }, { "28f07458f1b6c24e118a1ea056827701", "lost", "HE 99", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, + { "291fb06071e65897f755846611f5ad40", "ft", "", "7-Wolf", 19697, Common::RU_RUS, Common::kPlatformUnknown }, { "2a208ffbcd0e83e86f4356e6f64aa6e1", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformDOS }, { "2a41b53cf1a90b6e6f26c10cc6041084", "tentacle", "", "Demo", 2439158, Common::EN_ANY, Common::kPlatformMacintosh }, { "2a446817ffcabfef8716e0c456ecaf81", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformWindows }, @@ -238,7 +239,7 @@ static const MD5Table md5table[] = { { "53e94115b55dd51d4b8ff0871aa1df1e", "spyfox", "", "Demo", 20103, Common::EN_ANY, Common::kPlatformUnknown }, { "54a936ad06161ff7bfefcb96200f7bff", "monkey", "VGA", "VGA Demo", 7617, Common::EN_ANY, Common::kPlatformAmiga }, { "55518cd73cf9c6d23ea29c51ee06bdfe", "ft", "", "", -1, Common::IT_ITA, Common::kPlatformUnknown }, - { "55e4cc866ff9046824e1c638ba2b8c7f", "ft", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown }, + { "55e4cc866ff9046824e1c638ba2b8c7f", "ft", "", "Akella", -1, Common::RU_RUS, Common::kPlatformUnknown }, { "55f4e9402bec2bded383843123f37c5c", "pajama2", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformWindows }, { "566165a7338fa11029e7c14d94fa70d0", "freddi", "HE 73", "Demo", 9800, Common::EN_ANY, Common::kPlatformWindows }, { "56b5922751be7ffd771b38dda56b028b", "freddi", "HE 100", "", 34837, Common::NL_NLD, Common::kPlatformWii }, diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp index fd90015aa3..4c47dfafc7 100644 --- a/engines/sky/sky.cpp +++ b/engines/sky/sky.cpp @@ -187,9 +187,14 @@ Common::Error SkyEngine::go() { } if (!shouldQuit()) { - _skyLogic->initScreen0(); + // restartGame() takes us to the first scene, without showing the + // initial animation where Foster is being chased. initScreen0() + // shows the first scene together with that animation. We can't + // call both, as they both load the same scene. if (introSkipped) _skyControl->restartGame(); + else + _skyLogic->initScreen0(); } } diff --git a/engines/testbed/midi.cpp b/engines/testbed/midi.cpp index 70ede406d5..33fab03a5e 100644 --- a/engines/testbed/midi.cpp +++ b/engines/testbed/midi.cpp @@ -103,7 +103,7 @@ TestExitStatus MidiTests::playMidiMusic() { return kTestFailed; } - Testsuite::logDetailedPrintf("Info! Midi: Succesfully opened the driver\n"); + Testsuite::logDetailedPrintf("Info! Midi: Successfully opened the driver\n"); Common::MemoryWriteStreamDynamic ws(DisposeAfterUse::YES); loadMusicInMemory(&ws); diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp index 2e4be33e53..a7ba8b28cb 100644 --- a/engines/tinsel/detection.cpp +++ b/engines/tinsel/detection.cpp @@ -67,7 +67,7 @@ bool TinselEngine::getIsADGFDemo() const { return (bool)(_gameDescription->desc.flags & ADGF_DEMO); } -bool TinselEngine::isCD() const { +bool TinselEngine::isV1CD() const { return (bool)(_gameDescription->desc.flags & ADGF_CD); } diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h index f05f39b319..a945672da2 100644 --- a/engines/tinsel/detection_tables.h +++ b/engines/tinsel/detection_tables.h @@ -34,6 +34,8 @@ static const TinselGameDescription gameDescriptions[] = { // TINSEL_V2: The Discworld 2 game used this updated version of the Tinsel 1 engine, // and as far as we know there aren't any variations of this engine. + // ==== Discworld 1 early (TinselV0) entries ============================== + { // Floppy Demo V0 from http://www.adventure-treff.de/specials/dl_demos.php { "dw", @@ -51,6 +53,8 @@ static const TinselGameDescription gameDescriptions[] = { TINSEL_V0, }, + // ==== Discworld 1 entries =============================================== + { // CD Demo V1 version, with *.gra files { "dw", @@ -553,6 +557,9 @@ static const TinselGameDescription gameDescriptions[] = { TINSEL_V1, }, + // ==== Discworld 2 entries =============================================== + // Note: All Discworld 2 versions are CD only, therefore we don't add the ADGF_CD flag + { // English Discworld 2 demo { "dw2", @@ -564,7 +571,7 @@ static const TinselGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformDOS, - ADGF_DEMO | ADGF_CD, + ADGF_DEMO, GUIO1(GUIO_NOASPECT) }, GID_DW2, @@ -584,7 +591,7 @@ static const TinselGameDescription gameDescriptions[] = { }, Common::EN_GRB, Common::kPlatformDOS, - ADGF_CD, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, GID_DW2, @@ -604,7 +611,7 @@ static const TinselGameDescription gameDescriptions[] = { }, Common::EN_USA, Common::kPlatformDOS, - ADGF_CD, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, GID_DW2, @@ -624,7 +631,7 @@ static const TinselGameDescription gameDescriptions[] = { }, Common::FR_FRA, Common::kPlatformDOS, - ADGF_CD, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, GID_DW2, @@ -644,7 +651,7 @@ static const TinselGameDescription gameDescriptions[] = { }, Common::DE_DEU, Common::kPlatformDOS, - ADGF_CD, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, GID_DW2, @@ -665,7 +672,7 @@ static const TinselGameDescription gameDescriptions[] = { }, Common::IT_ITA, Common::kPlatformDOS, - ADGF_CD, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, GID_DW2, @@ -685,7 +692,7 @@ static const TinselGameDescription gameDescriptions[] = { }, Common::ES_ESP, Common::kPlatformDOS, - ADGF_CD, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, GID_DW2, @@ -706,7 +713,7 @@ static const TinselGameDescription gameDescriptions[] = { }, Common::RU_RUS, Common::kPlatformDOS, - ADGF_CD, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, GID_DW2, diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp index b652e394a0..17cb23b98f 100644 --- a/engines/tinsel/scene.cpp +++ b/engines/tinsel/scene.cpp @@ -130,14 +130,14 @@ const SCENE_STRUC *GetSceneStruc(const byte *pStruc) { const byte *p = pStruc; memset(&g_tempStruc, 0, sizeof(SCENE_STRUC)); - g_tempStruc.numEntrance = FROM_LE_32(READ_32(p)); p += sizeof(uint32); - g_tempStruc.numPoly = FROM_LE_32(READ_32(p)); p += sizeof(uint32); - g_tempStruc.numTaggedActor = FROM_LE_32(READ_32(p)); p += sizeof(uint32); - g_tempStruc.defRefer = FROM_LE_32(READ_32(p)); p += sizeof(uint32); - g_tempStruc.hSceneScript = FROM_LE_32(READ_32(p)); p += sizeof(uint32); - g_tempStruc.hEntrance = FROM_LE_32(READ_32(p)); p += sizeof(uint32); - g_tempStruc.hPoly = FROM_LE_32(READ_32(p)); p += sizeof(uint32); - g_tempStruc.hTaggedActor = FROM_LE_32(READ_32(p)); p += sizeof(uint32); + g_tempStruc.numEntrance = READ_32(p); p += sizeof(uint32); + g_tempStruc.numPoly = READ_32(p); p += sizeof(uint32); + g_tempStruc.numTaggedActor = READ_32(p); p += sizeof(uint32); + g_tempStruc.defRefer = READ_32(p); p += sizeof(uint32); + g_tempStruc.hSceneScript = READ_32(p); p += sizeof(uint32); + g_tempStruc.hEntrance = READ_32(p); p += sizeof(uint32); + g_tempStruc.hPoly = READ_32(p); p += sizeof(uint32); + g_tempStruc.hTaggedActor = READ_32(p); p += sizeof(uint32); return &g_tempStruc; } diff --git a/engines/tinsel/sound.cpp b/engines/tinsel/sound.cpp index cadc754de6..416ee74127 100644 --- a/engines/tinsel/sound.cpp +++ b/engines/tinsel/sound.cpp @@ -75,7 +75,7 @@ SoundManager::~SoundManager() { // playSample for DiscWorld 1 bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::SoundHandle *handle) { // Floppy version has no sample file. - if (!_vm->isCD()) + if (!_vm->isV1CD()) return false; // no sample driver? @@ -207,10 +207,6 @@ void SoundManager::playDW1MacMusic(Common::File &s, uint32 length) { bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int priority, Audio::Mixer::SoundType type, Audio::SoundHandle *handle) { - // Floppy version has no sample file - if (!_vm->isCD()) - return false; - // no sample driver? if (!_vm->_mixer->isReady()) return false; @@ -501,8 +497,8 @@ void SoundManager::showSoundError(const char *errorMsg, const char *soundFile) { * Opens and inits all sound sample files. */ void SoundManager::openSampleFiles() { - // Floppy and demo versions have no sample files, except for the Discworld 2 demo - if (!_vm->isCD()) + // V1 Floppy and V0 demo versions have no sample files + if (TinselV0 || (TinselV1 && !_vm->isV1CD())) return; TinselFile f; diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h index ec504b69cd..5eb3b7d7b8 100644 --- a/engines/tinsel/tinsel.h +++ b/engines/tinsel/tinsel.h @@ -184,7 +184,7 @@ public: uint32 getFlags() const; Common::Platform getPlatform() const; bool getIsADGFDemo() const; - bool isCD() const; + bool isV1CD() const; const char *getSampleIndex(LANGUAGE lang); const char *getSampleFile(LANGUAGE lang); @@ -226,7 +226,11 @@ public: Graphics::Surface &screen() { return _screenSurface; } Common::Point getMousePosition() const { return _mousePos; } - void setMousePosition(const Common::Point &pt) { + void setMousePosition(Common::Point pt) { + // Clip mouse position to be within the screen coordinates + pt.x = CLIP<int16>(pt.x, 0, SCREEN_WIDTH - 1); + pt.y = CLIP<int16>(pt.y, 0, SCREEN_HEIGHT - 1); + int yOffset = TinselV2 ? (g_system->getHeight() - _screenSurface.h) / 2 : 0; g_system->warpMouse(pt.x, pt.y + yOffset); _mousePos = pt; diff --git a/engines/tony/detection_tables.h b/engines/tony/detection_tables.h index ee137927dc..ca16495903 100644 --- a/engines/tony/detection_tables.h +++ b/engines/tony/detection_tables.h @@ -196,6 +196,40 @@ static const TonyGameDescription gameDescriptions[] = { }, }, + { + // Tony Tough English Unpacked + { + "tony", + 0, + { + {"roasted.mpr", 0, "06203dbbc85fdd1e6dc8fc211c1a6207", 135911071}, + {"roasted.mpc", 0, "57c4a3860cf899443c357e0078ea6f49", 366773}, + AD_LISTEND + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + }, + + { + // Tony Tough German "Shoe Box", reported in bug #3582420 + { + "tony", + 0, + { + {"roasted.mpr", 0, "06203dbbc85fdd1e6dc8fc211c1a6207", 135911071}, + {"roasted.mpc", 0, "bc3471f098e591dc509dcad401a8d8a5", 389554}, + AD_LISTEND + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + }, + { AD_TABLE_END_MARKER } }; diff --git a/engines/tony/gfxengine.cpp b/engines/tony/gfxengine.cpp index cb27e20ab1..7bb25f59b9 100644 --- a/engines/tony/gfxengine.cpp +++ b/engines/tony/gfxengine.cpp @@ -530,7 +530,10 @@ void RMGfxEngine::disableMouse() { #define TONY_SAVEGAME_VERSION 8 void RMGfxEngine::saveState(const Common::String &fn, byte *curThumb, const Common::String &name) { - Common::OutSaveFile *f; + Common::OutSaveFile *f = g_system->getSavefileManager()->openForSaving(fn); + if (f == NULL) + return; + byte *state; char buf[4]; RMPoint tp = _tony.position(); @@ -549,10 +552,6 @@ void RMGfxEngine::saveState(const Common::String &fn, byte *curThumb, const Comm buf[2] = 'S'; buf[3] = TONY_SAVEGAME_VERSION; - f = g_system->getSavefileManager()->openForSaving(fn); - if (f == NULL) - return; - f->write(buf, 4); f->writeUint32LE(thumbsize); f->write(curThumb, thumbsize); diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp index 1a24c5a576..fff8676a89 100644 --- a/engines/tony/mpal/mpal.cpp +++ b/engines/tony/mpal/mpal.cpp @@ -521,14 +521,15 @@ static LpItem getItemData(uint32 nOrdItem) { dat += dim; } - // Check if we've got to the end of the file int i = READ_LE_UINT16(dat); - if (i != 0xABCD) - return NULL; globalUnlock(hDat); globalFree(hDat); + // Check if we've got to the end of the file + if (i != 0xABCD) + return NULL; + return ret; } @@ -1875,14 +1876,11 @@ MpalHandle mpalQueryHANDLE(uint16 wQueryType, ...) { * @remarks This is the specialised version of the original single mpalQuery * method that needs to run within a co-routine context. */ -void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet, ...) { +void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet) { CORO_BEGIN_CONTEXT; uint32 dwRet; CORO_END_CONTEXT(_ctx); - va_list v; - va_start(v, dwRet); - CORO_BEGIN_CODE(_ctx); if (wQueryType == MPQ_DIALOG_WAITFORCHOICE) { @@ -1908,8 +1906,6 @@ void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet, ...) { } CORO_END_CODE; - - va_end(v); } /** diff --git a/engines/tony/mpal/mpal.h b/engines/tony/mpal/mpal.h index 779bdd6188..2d22ee8faf 100644 --- a/engines/tony/mpal/mpal.h +++ b/engines/tony/mpal/mpal.h @@ -417,7 +417,7 @@ MpalHandle mpalQueryHANDLE(uint16 wQueryType, ...); * @remarks This is the specialised version of the original single mpalQuery * method that needs to run within a co-routine context. */ -void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet, ...); +void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet); /** * Execute a script. The script runs on multitasking by a thread. diff --git a/engines/tsage/blue_force/blueforce_scenes9.cpp b/engines/tsage/blue_force/blueforce_scenes9.cpp index 1cb8191640..52115b95fe 100644 --- a/engines/tsage/blue_force/blueforce_scenes9.cpp +++ b/engines/tsage/blue_force/blueforce_scenes9.cpp @@ -705,6 +705,10 @@ void Scene900::process(Event &event) { void Scene900::dispatch() { SceneExt::dispatch(); + // WORKAROUND:: Fix for invalid data in the Blue Force floppy version when opening gate + if (_sceneMode == 9006 && (g_vm->getFeatures() & GF_FLOPPY) && BF_GLOBALS._player._endFrame == 8) + BF_GLOBALS._player._endFrame = 6; + if (BF_GLOBALS.getFlag(fWithLyle) && _lyle.isNoMover()) { _lyle.updateAngle(BF_GLOBALS._player._position); } diff --git a/engines/wintermute/base/base_file_manager.cpp b/engines/wintermute/base/base_file_manager.cpp index 4c7c31562d..7d59b03684 100644 --- a/engines/wintermute/base/base_file_manager.cpp +++ b/engines/wintermute/base/base_file_manager.cpp @@ -192,7 +192,7 @@ bool BaseFileManager::registerPackages() { Common::FSList files; for (Common::FSList::iterator it = _packagePaths.begin(); it != _packagePaths.end(); ++it) { debugC(kWintermuteDebugFileAccess, "Should register folder: %s %s", (*it).getPath().c_str(), (*it).getName().c_str()); - if ((*it).getChildren(files, Common::FSNode::kListFilesOnly)) { + if (!(*it).getChildren(files, Common::FSNode::kListFilesOnly)) { warning("getChildren() failed for path: %s", (*it).getDisplayName().c_str()); } for (Common::FSList::iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) { diff --git a/engines/wintermute/base/scriptables/script_ext_math.cpp b/engines/wintermute/base/scriptables/script_ext_math.cpp index d816fbec65..f4c6be2d6c 100644 --- a/engines/wintermute/base/scriptables/script_ext_math.cpp +++ b/engines/wintermute/base/scriptables/script_ext_math.cpp @@ -31,7 +31,6 @@ #include "engines/wintermute/base/scriptables/script_value.h" #include "engines/wintermute/persistent.h" #include "common/math.h" -#include <math.h> namespace Wintermute { diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h index 00ec51a715..09426c9307 100644 --- a/engines/wintermute/detection_tables.h +++ b/engines/wintermute/detection_tables.h @@ -27,6 +27,7 @@ namespace Wintermute { static const PlainGameDescriptor wintermuteGames[] = { {"5ld", "Five Lethal Demons"}, {"5ma", "Five Magical Amulets"}, + {"bthreshold", "Beyond the Threshold"}, {"actualdest", "Actual Destination"}, {"carolreed4", "Carol Reed 4 - East Side Story"}, {"carolreed5", "Carol Reed 5 - The Colour of Murder"}, @@ -36,17 +37,20 @@ static const PlainGameDescriptor wintermuteGames[] = { {"carolreed9", "Carol Reed 9 - Cold Case Summer"}, {"chivalry", "Chivalry is Not Dead"}, {"deadcity", "Dead City"}, + {"dreaming", "Des Reves Elastiques Avec Mille Insectes Nommes Georges"}, {"dirtysplit", "Dirty Split"}, {"dreamscape", "Dreamscape"}, {"ghostsheet", "Ghost in the Sheet"}, {"hamlet", "Hamlet or the last game without MMORPS features, shaders and product placement"}, + {"jamesperis", "James Peris: No License Nor Control"}, {"julia", "J.U.L.I.A."}, {"mirage", "Mirage"}, {"pigeons", "Pigeons in the Park"}, {"reversion1", "Reversion: The Escape"}, - {"reversion2", "Reversion: The Meeting"}, + {"reversion2", "Reversion: The Meeting"}, {"rosemary", "Rosemary"}, {"thebox", "The Box"}, + {"tradestory", "The Trader of Stories"}, {"twc", "the white chamber"}, {"wintermute", "Wintermute engine game"}, {0, 0} @@ -83,6 +87,16 @@ static const ADGameDescription gameDescriptions[] = { ADGF_UNSTABLE, GUIO0() }, + // Beyond the Threshold + { + "bthreshold", + "", + AD_ENTRY1s("data.dcp", "d49bf9ccb2e74507447c82d6ad3e2bc4", 12773712), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, // Carol Reed 4 - East Side Story (Demo) { "carolreed4", @@ -237,6 +251,16 @@ static const ADGameDescription gameDescriptions[] = { ADGF_UNSTABLE, GUIO0() }, + // Des Reves Elastiques Avec Mille Insectes Nommes Georges + { + "dreaming", + "", + AD_ENTRY1s("data.dcp", "4af26d97ea063fc1277ce30ae431de90", 8804073), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, // Dreamscape { "dreamscape", @@ -268,6 +292,17 @@ static const ADGameDescription gameDescriptions[] = { ADGF_UNSTABLE, GUIO0() }, + // James Peris: No License Nor Control + { + "jamesperis", + "Demo", + AD_ENTRY1s("data.dcp", "edb9f9c7a08993c1e28f4e477b5f9830", 116113507), + Common::UNK_LANG, // No solution in place to select language + Common::kPlatformWindows, + ADGF_UNSTABLE | + ADGF_DEMO, + GUIO0() + }, // J.U.L.I.A. (English) { "julia", @@ -289,6 +324,17 @@ static const ADGameDescription gameDescriptions[] = { ADGF_DEMO, GUIO0() }, + // J.U.L.I.A. (English) (Greenlight Demo) + { + "julia", + "Greenlight Demo", + AD_ENTRY1s("data.dcp", "4befd448d36b0dae9c3ab1aa7cb8b78d", 7271886), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_UNSTABLE | + ADGF_DEMO, + GUIO0() + }, // Mirage { "mirage", @@ -545,6 +591,17 @@ static const ADGameDescription gameDescriptions[] = { ADGF_UNSTABLE, GUIO0() }, + // The Trader of Stories + { + "tradestory", + "Demo", + AD_ENTRY1s("data.dcp", "0a0b51191636cc8ead89b905281c3218", 40401902), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_UNSTABLE | + ADGF_DEMO, + GUIO0() + }, // the white chamber (multi-language) { "twc", diff --git a/engines/wintermute/math/math_util.cpp b/engines/wintermute/math/math_util.cpp index 31af77538a..0aa0f841ac 100644 --- a/engines/wintermute/math/math_util.cpp +++ b/engines/wintermute/math/math_util.cpp @@ -27,7 +27,7 @@ */ #include "engines/wintermute/math/math_util.h" -#include <math.h> +#include "common/scummsys.h" namespace Wintermute { diff --git a/engines/wintermute/math/matrix4.cpp b/engines/wintermute/math/matrix4.cpp index ca1eae8813..a50514457e 100644 --- a/engines/wintermute/math/matrix4.cpp +++ b/engines/wintermute/math/matrix4.cpp @@ -28,7 +28,7 @@ #include "engines/wintermute/math/matrix4.h" #include "engines/wintermute/math/vector2.h" -#include <math.h> +#include "common/scummsys.h" namespace Wintermute { diff --git a/engines/wintermute/math/vector2.cpp b/engines/wintermute/math/vector2.cpp index 74c5586d62..98dca70b44 100644 --- a/engines/wintermute/math/vector2.cpp +++ b/engines/wintermute/math/vector2.cpp @@ -27,7 +27,7 @@ */ #include "engines/wintermute/math/vector2.h" -#include <math.h> +#include "common/scummsys.h" namespace Wintermute { diff --git a/gui/options.cpp b/gui/options.cpp index fb57c15d98..a9fdc19274 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -887,7 +887,7 @@ void OptionsDialog::addMT32Controls(GuiObject *boss, const Common::String &prefi _mt32Checkbox = new CheckboxWidget(boss, prefix + "mcMt32Checkbox", _c("True Roland MT-32 (no GM emulation)", "lowres"), _("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", _("Roland GS Mode (disable GM mapping)"), _("Turns off General MIDI mapping for games with Roland MT-32 soundtrack")); + _enableGSCheckbox = new CheckboxWidget(boss, prefix + "mcGSCheckbox", _("Roland GS Device (enable MT-32 mappings)"), _("Check if you want to enable patch mappings to emulate an MT-32 on a Roland GS device")); const MusicPlugin::List p = MusicMan.getPlugins(); // Make sure the null device is the first one in the list to avoid undesired diff --git a/video/smk_decoder.cpp b/video/smk_decoder.cpp index 4e18268e72..b622a0ab61 100644 --- a/video/smk_decoder.cpp +++ b/video/smk_decoder.cpp @@ -821,8 +821,9 @@ void SmackerDecoder::SmackerAudioTrack::queueCompressedBuffer(byte *buffer, uint // (the exact opposite to the base values) if (!is16Bits) { for (int k = 0; k < (isStereo ? 2 : 1); k++) { - bases[k] += (int8) ((int16) audioTrees[k]->getCode(audioBS)); - *curPointer++ = CLIP<int>(bases[k], 0, 255) ^ 0x80; + int8 delta = (int8) ((int16) audioTrees[k]->getCode(audioBS)); + bases[k] = (bases[k] + delta) & 0xFF; + *curPointer++ = bases[k] ^ 0x80; curPos++; } } else { |