aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--NEWS3
-rw-r--r--common/cosinetables.cpp6
-rw-r--r--common/cosinetables.h9
-rw-r--r--common/rdft.h36
-rw-r--r--common/sinetables.cpp12
-rw-r--r--common/sinetables.h7
-rw-r--r--common/winexe.cpp2
-rw-r--r--common/winexe_ne.cpp32
-rw-r--r--common/winexe_ne.h50
-rw-r--r--devtools/create_neverhood/create_neverhood.cpp37
-rw-r--r--devtools/create_neverhood/md5.cpp273
-rw-r--r--devtools/create_neverhood/md5.h41
-rw-r--r--devtools/create_neverhood/module.mk1
-rw-r--r--devtools/create_project/create_project.cpp8
-rw-r--r--devtools/create_project/msbuild.cpp15
-rw-r--r--devtools/create_project/msvc12/create_project.sln20
-rw-r--r--devtools/create_project/msvc12/create_project.vcxproj132
-rw-r--r--devtools/create_project/msvc12/create_project.vcxproj.filters71
-rw-r--r--devtools/scumm-md5.txt3
-rw-r--r--dists/msvc12/create_msvc12.bat95
-rw-r--r--dists/msvc12/readme.txt6
-rw-r--r--engines/cruise/cruise.h4
-rw-r--r--engines/cruise/detection.cpp37
-rw-r--r--engines/gob/surface.cpp16
-rw-r--r--engines/hopkins/hopkins.cpp39
-rw-r--r--engines/hopkins/hopkins.h3
-rw-r--r--engines/hopkins/saveload.cpp32
-rw-r--r--engines/hopkins/saveload.h2
-rw-r--r--engines/hopkins/script.cpp13
-rw-r--r--engines/lure/debugger.cpp4
-rw-r--r--engines/neverhood/background.cpp2
-rw-r--r--engines/neverhood/console.cpp172
-rw-r--r--engines/neverhood/console.h47
-rw-r--r--engines/neverhood/detection.cpp16
-rw-r--r--engines/neverhood/diskplayerscene.cpp24
-rw-r--r--engines/neverhood/diskplayerscene.h1
-rw-r--r--engines/neverhood/gamemodule.cpp27
-rw-r--r--engines/neverhood/gamemodule.h5
-rw-r--r--engines/neverhood/gamevars.cpp5
-rw-r--r--engines/neverhood/gamevars.h4
-rw-r--r--engines/neverhood/graphics.cpp12
-rw-r--r--engines/neverhood/graphics.h4
-rw-r--r--engines/neverhood/klaymen.cpp2
-rw-r--r--engines/neverhood/menumodule.cpp85
-rw-r--r--engines/neverhood/menumodule.h2
-rw-r--r--engines/neverhood/module.h3
-rw-r--r--engines/neverhood/module.mk1
-rw-r--r--engines/neverhood/modules/module1000.cpp4
-rw-r--r--engines/neverhood/modules/module1100.cpp14
-rw-r--r--engines/neverhood/modules/module1200.cpp4
-rw-r--r--engines/neverhood/modules/module1300.cpp6
-rw-r--r--engines/neverhood/modules/module1400.cpp2
-rw-r--r--engines/neverhood/modules/module1500.cpp2
-rw-r--r--engines/neverhood/modules/module1600.cpp2
-rw-r--r--engines/neverhood/modules/module1600.h2
-rw-r--r--engines/neverhood/modules/module1700.cpp2
-rw-r--r--engines/neverhood/modules/module1800.cpp2
-rw-r--r--engines/neverhood/modules/module1900.cpp2
-rw-r--r--engines/neverhood/modules/module2000.cpp2
-rw-r--r--engines/neverhood/modules/module2100.cpp4
-rw-r--r--engines/neverhood/modules/module2200.cpp11
-rw-r--r--engines/neverhood/modules/module2300.cpp2
-rw-r--r--engines/neverhood/modules/module2400.cpp4
-rw-r--r--engines/neverhood/modules/module2500.cpp2
-rw-r--r--engines/neverhood/modules/module2600.cpp2
-rw-r--r--engines/neverhood/modules/module2700.cpp2
-rw-r--r--engines/neverhood/modules/module2800.cpp20
-rw-r--r--engines/neverhood/modules/module2900.cpp2
-rw-r--r--engines/neverhood/modules/module3000.cpp77
-rw-r--r--engines/neverhood/modules/module3000.h4
-rw-r--r--engines/neverhood/navigationscene.cpp39
-rw-r--r--engines/neverhood/navigationscene.h1
-rw-r--r--engines/neverhood/neverhood.cpp37
-rw-r--r--engines/neverhood/neverhood.h13
-rw-r--r--engines/neverhood/saveload.cpp19
-rw-r--r--engines/neverhood/scene.cpp15
-rw-r--r--engines/neverhood/scene.h3
-rw-r--r--engines/neverhood/smackerplayer.cpp38
-rw-r--r--engines/neverhood/smackerplayer.h1
-rw-r--r--engines/neverhood/sound.cpp46
-rw-r--r--engines/neverhood/sound.h4
-rw-r--r--engines/neverhood/sprite.cpp4
-rw-r--r--engines/saga/shorten.cpp2
-rw-r--r--engines/sci/graphics/ports.cpp4
-rw-r--r--engines/sci/sound/soundcmd.cpp20
-rw-r--r--engines/scumm/scumm-md5.h5
-rw-r--r--engines/sky/sky.cpp7
-rw-r--r--engines/tinsel/scene.cpp16
-rw-r--r--engines/tinsel/tinsel.h6
-rw-r--r--engines/tony/detection_tables.h34
-rw-r--r--engines/tony/mpal/mpal.cpp7
-rw-r--r--engines/tony/mpal/mpal.h2
-rw-r--r--engines/toon/character.cpp9
-rw-r--r--engines/toon/character.h1
-rw-r--r--engines/tsage/blue_force/blueforce_scenes9.cpp4
-rw-r--r--engines/wintermute/base/scriptables/script_ext_math.cpp1
-rw-r--r--engines/wintermute/detection_tables.h59
-rw-r--r--engines/wintermute/math/math_util.cpp2
-rw-r--r--engines/wintermute/math/matrix4.cpp2
-rw-r--r--engines/wintermute/math/vector2.cpp2
-rw-r--r--engines/wintermute/wintermute.cpp1
-rw-r--r--graphics/yuv_to_rgb.h15
-rw-r--r--po/POTFILES2
-rw-r--r--video/codecs/indeo3.cpp119
-rw-r--r--video/coktel_decoder.cpp8
-rw-r--r--video/smk_decoder.cpp5
107 files changed, 1653 insertions, 499 deletions
diff --git a/.gitignore b/.gitignore
index b834214a00..a046909bbf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -161,6 +161,10 @@ ipch/
#Ignore default Visual Studio build folders
[Dd]ebug/
[Rr]elease/
+[Dd]ebug32/
+[Rr]elease32/
+[Dd]ebug64/
+[Rr]elease64/
#Ignore Qt Creator project files
ScummVM.config
diff --git a/NEWS b/NEWS
index cf9a07e8cb..c31be14c25 100644
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,8 @@ For a more comprehensive changelog of the latest experimental code, see:
https://github.com/scummvm/scummvm/commits/
1.7.0 (????-??-??)
-
+ Gob:
+ - Improved video quality in Urban Runner
1.6.0 (2013-05-31)
New Games:
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);
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/create_project/create_project.cpp b/devtools/create_project/create_project.cpp
index a8e09ff5eb..84a6185eda 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -189,7 +189,7 @@ int main(int argc, char *argv[]) {
msvcVersion = atoi(argv[++i]);
- if (msvcVersion != 8 && msvcVersion != 9 && msvcVersion != 10 && msvcVersion != 11) {
+ if (msvcVersion != 8 && msvcVersion != 9 && msvcVersion != 10 && msvcVersion != 11 && msvcVersion != 12) {
std::cerr << "ERROR: Unsupported version: \"" << msvcVersion << "\" passed to \"--msvc-version\"!\n";
return -1;
}
@@ -609,9 +609,9 @@ void displayHelp(const char *exe) {
" (default: false)\n"
" --installer Create NSIS installer after the build (implies --build-events)\n"
" (default: false)\n"
- " --tools Create project files for the devtools\n"
- " (ignores --build-events and --installer, as well as engine settings)\n"
- " (default: false)\n"
+ " --tools Create project files for the devtools\n"
+ " (ignores --build-events and --installer, as well as engine settings)\n"
+ " (default: false)\n"
"\n"
"Engines settings:\n"
" --list-engines list all available engines and their default state\n"
diff --git a/devtools/create_project/msbuild.cpp b/devtools/create_project/msbuild.cpp
index 0f77d91852..dd9917e4ee 100644
--- a/devtools/create_project/msbuild.cpp
+++ b/devtools/create_project/msbuild.cpp
@@ -52,6 +52,9 @@ int MSBuildProvider::getVisualStudioVersion() {
if (_version == 11)
return 2012;
+ if (_version == 12)
+ return 2013;
+
error("Unsupported version passed to getVisualStudioVersion");
}
@@ -88,7 +91,7 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri
error("Could not open \"" + projectFile + "\" for writing");
project << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
+ "<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
"\t<ItemGroup Label=\"ProjectConfigurations\">\n";
outputConfiguration(project, "Debug", "Win32");
@@ -105,7 +108,7 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri
"\t\t<ProjectGuid>{" << uuid << "}</ProjectGuid>\n"
"\t\t<RootNamespace>" << name << "</RootNamespace>\n"
"\t\t<Keyword>Win32Proj</Keyword>\n"
- "\t\t<VCTargetsPath Condition=\"'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''\">$(VCTargetsPath11)</VCTargetsPath>\n"
+ "\t\t<VCTargetsPath Condition=\"'$(VCTargetsPath" << _version << ")' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''\">$(VCTargetsPath" << _version << ")</VCTargetsPath>\n"
"\t</PropertyGroup>\n";
// Shared configuration
@@ -184,7 +187,7 @@ void MSBuildProvider::createFiltersFile(const BuildSetup &setup, const std::stri
error("Could not open \"" + filtersFile + "\" for writing");
filters << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n";
+ "<Project ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n";
// Output the list of filters
filters << "\t<ItemGroup>\n";
@@ -314,9 +317,8 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea
definesList += REVISION_DEFINE ";";
properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
+ "<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
"\t<PropertyGroup>\n"
- "\t\t<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n"
"\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_Global</_PropertySheetDisplayName>\n"
"\t\t<ExecutablePath>$(" << LIBS_DEFINE << ")\\bin;$(ExecutablePath)</ExecutablePath>\n"
"\t\t<LibraryPath>$(" << LIBS_DEFINE << ")\\lib\\" << (bits == 32 ? "x86" : "x64") << ";$(LibraryPath)</LibraryPath>\n"
@@ -368,12 +370,11 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b
error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing");
properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
+ "<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
"\t<ImportGroup Label=\"PropertySheets\">\n"
"\t\t<Import Project=\"" << setup.projectDescription << "_Global" << (isWin32 ? "" : "64") << ".props\" />\n"
"\t</ImportGroup>\n"
"\t<PropertyGroup>\n"
- "\t\t<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n"
"\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_" << outputType << outputBitness << "</_PropertySheetDisplayName>\n"
"\t\t<LinkIncremental>" << (isRelease ? "false" : "true") << "</LinkIncremental>\n"
"\t</PropertyGroup>\n"
diff --git a/devtools/create_project/msvc12/create_project.sln b/devtools/create_project/msvc12/create_project.sln
new file mode 100644
index 0000000000..759d5430f5
--- /dev/null
+++ b/devtools/create_project/msvc12/create_project.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "create_project", "create_project.vcxproj", "{CF177559-077D-4A08-AABE-BE0FD35F6C63}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.Build.0 = Debug|Win32
+ {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.ActiveCfg = Release|Win32
+ {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/devtools/create_project/msvc12/create_project.vcxproj b/devtools/create_project/msvc12/create_project.vcxproj
new file mode 100644
index 0000000000..c26b1e5f45
--- /dev/null
+++ b/devtools/create_project/msvc12/create_project.vcxproj
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{CF177559-077D-4A08-AABE-BE0FD35F6C63}</ProjectGuid>
+ <RootNamespace>create_project</RootNamespace>
+ <VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''">$(VCTargetsPath11)</VCTargetsPath>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <WarningLevel>Level4</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableLanguageExtensions>false</DisableLanguageExtensions>
+ <DisableSpecificWarnings>4003;4512;4127</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <PostBuildEvent>
+ <Command>@echo off
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc12\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc11\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc10\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc9\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc8\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\codeblocks\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4003;4512;4127</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ <PostBuildEvent>
+ <Command>@echo off
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc12\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc11\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc10\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc9\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc8\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\codeblocks\"
+xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command>
+ </PostBuildEvent>
+ <PreBuildEvent>
+ <Command>
+ </Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\codeblocks.cpp" />
+ <ClCompile Include="..\create_project.cpp" />
+ <ClCompile Include="..\msbuild.cpp" />
+ <ClCompile Include="..\msvc.cpp" />
+ <ClCompile Include="..\visualstudio.cpp" />
+ <ClCompile Include="..\xcode.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\codeblocks.h" />
+ <ClInclude Include="..\config.h" />
+ <ClInclude Include="..\create_project.h" />
+ <ClInclude Include="..\msbuild.h" />
+ <ClInclude Include="..\msvc.h" />
+ <ClInclude Include="..\visualstudio.h" />
+ <ClInclude Include="..\xcode.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\scripts\installer.vbs" />
+ <None Include="..\scripts\postbuild.cmd" />
+ <None Include="..\scripts\prebuild.cmd" />
+ <None Include="..\scripts\revision.vbs" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/devtools/create_project/msvc12/create_project.vcxproj.filters b/devtools/create_project/msvc12/create_project.vcxproj.filters
new file mode 100644
index 0000000000..436d1d3436
--- /dev/null
+++ b/devtools/create_project/msvc12/create_project.vcxproj.filters
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{2e3580c8-ec3a-4c81-8351-b668c668db2a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{31aaf58c-d3cb-4ed6-8eca-163b4a9b31a6}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="scripts">
+ <UniqueIdentifier>{f980f6fb-41b6-4161-b035-58b200c85cad}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\codeblocks.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\create_project.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\msvc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\msbuild.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\visualstudio.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\xcode.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\config.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\codeblocks.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\create_project.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\msvc.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\msbuild.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\visualstudio.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xcode.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\scripts\prebuild.cmd">
+ <Filter>scripts</Filter>
+ </None>
+ <None Include="..\scripts\revision.vbs">
+ <Filter>scripts</Filter>
+ </None>
+ <None Include="..\scripts\postbuild.cmd">
+ <Filter>scripts</Filter>
+ </None>
+ <None Include="..\scripts\installer.vbs">
+ <Filter>scripts</Filter>
+ </None>
+ </ItemGroup>
+</Project>
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/msvc12/create_msvc12.bat b/dists/msvc12/create_msvc12.bat
new file mode 100644
index 0000000000..fe12a9b288
--- /dev/null
+++ b/dists/msvc12/create_msvc12.bat
@@ -0,0 +1,95 @@
+@echo off
+
+echo.
+echo Automatic creation of the MSVC12 project files
+echo.
+
+if "%~1"=="/stable" goto stable
+if "%~1"=="/STABLE" goto stable
+if "%~1"=="/all" goto all
+if "%~1"=="/ALL" goto all
+if "%~1"=="/tools" goto tools
+if "%~1"=="/TOOLS" goto tools
+if "%~1"=="/clean" goto clean_check
+if "%~1"=="/CLEAN" goto clean_check
+if "%~1"=="/help" goto command_help
+if "%~1"=="/HELP" goto command_help
+if "%~1"=="/?" goto command_help
+
+if "%~1"=="" goto check_tool
+
+echo Invalid command parameter: %~1
+echo.
+
+:command_help
+echo Valid command parameters are:
+echo stable Generated stable engines project files
+echo all Generate all engines project files
+echo tools Generate project files for the devtools
+echo clean Clean generated project files
+echo help Show help message
+goto done
+
+:check_tool
+if not exist create_project.exe goto no_tool
+
+:question
+echo.
+set batchanswer=S
+set /p batchanswer="Enable stable engines only, or all engines? (S/a)"
+if "%batchanswer%"=="s" goto stable
+if "%batchanswer%"=="S" goto stable
+if "%batchanswer%"=="a" goto all
+if "%batchanswer%"=="A" goto all
+goto question
+
+:no_tool
+echo create_project.exe not found in the current folder.
+echo You need to build it first and copy it in this
+echo folder
+goto done
+
+:all
+echo.
+echo Creating project files with all engines enabled (stable and unstable)
+echo.
+create_project ..\.. --enable-all-engines --msvc --msvc-version 12 --build-events
+goto done
+
+:stable
+echo.
+echo Creating normal project files, with only the stable engines enabled
+echo.
+create_project ..\.. --msvc --msvc-version 12
+goto done
+
+:tools
+echo.
+echo Creating tools project files
+echo.
+create_project ..\.. --tools --msvc --msvc-version 12
+goto done
+
+:clean_check
+echo.
+set cleananswer=N
+set /p cleananswer="This will remove all project files. Are you sure you want to continue? (N/y)"
+if "%cleananswer%"=="n" goto done
+if "%cleananswer%"=="N" goto done
+if "%cleananswer%"=="y" goto clean
+if "%cleananswer%"=="Y" goto clean
+goto clean_check
+
+:clean
+echo.
+echo Removing all project files
+del /Q *.vcxproj* > NUL 2>&1
+del /Q *.props > NUL 2>&1
+del /Q *.sln* > NUL 2>&1
+del /Q scummvm* > NUL 2>&1
+del /Q devtools* > NUL 2>&1
+goto done
+
+:done
+echo.
+pause
diff --git a/dists/msvc12/readme.txt b/dists/msvc12/readme.txt
new file mode 100644
index 0000000000..760f9ff601
--- /dev/null
+++ b/dists/msvc12/readme.txt
@@ -0,0 +1,6 @@
+The Visual Studio project files can now be created automatically from the GCC
+files using the create_project tool inside the /devtools/create_project folder.
+
+To create the default project files, build create_project.exe, copy it inside
+this folder and run the create_msvc12.bat file for a default build. You can run
+create_project.exe with no parameters to check the possible command-line options
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/gob/surface.cpp b/engines/gob/surface.cpp
index 6b65eb6ab9..839378a412 100644
--- a/engines/gob/surface.cpp
+++ b/engines/gob/surface.cpp
@@ -45,7 +45,7 @@ static void plotPixel(int x, int y, int color, void *data) {
Pixel::Pixel(byte *vidMem, uint8 bpp, byte *min, byte *max) :
_vidMem(vidMem), _bpp(bpp), _min(min), _max(max) {
- assert((_bpp == 1) || (_bpp == 2));
+ assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4));
assert(_vidMem >= _min);
assert(_vidMem < _max);
}
@@ -91,6 +91,8 @@ uint32 Pixel::get() const {
return *((byte *) _vidMem);
if (_bpp == 2)
return *((uint16 *) _vidMem);
+ if (_bpp == 4)
+ return *((uint32 *) _vidMem);
return 0;
}
@@ -103,6 +105,8 @@ void Pixel::set(uint32 p) {
*((byte *) _vidMem) = (byte) p;
if (_bpp == 2)
*((uint16 *) _vidMem) = (uint16) p;
+ if (_bpp == 4)
+ *((uint32 *) _vidMem) = (uint32) p;
}
bool Pixel::isValid() const {
@@ -113,7 +117,7 @@ bool Pixel::isValid() const {
ConstPixel::ConstPixel(const byte *vidMem, uint8 bpp, const byte *min, const byte *max) :
_vidMem(vidMem), _bpp(bpp), _min(min), _max(max) {
- assert((_bpp == 1) || (_bpp == 2));
+ assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4));
assert(_vidMem >= _min);
assert(_vidMem < _max);
}
@@ -159,6 +163,8 @@ uint32 ConstPixel::get() const {
return *((const byte *) _vidMem);
if (_bpp == 2)
return *((const uint16 *) _vidMem);
+ if (_bpp == 4)
+ return *((const uint32 *) _vidMem);
return 0;
}
@@ -172,7 +178,7 @@ Surface::Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem) :
_width(width), _height(height), _bpp(bpp), _vidMem(vidMem) {
assert((_width > 0) && (_height > 0));
- assert((_bpp == 1) || (_bpp == 2));
+ assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4));
if (!_vidMem) {
_vidMem = new byte[_bpp * _width * _height];
@@ -187,7 +193,7 @@ Surface::Surface(uint16 width, uint16 height, uint8 bpp, const byte *vidMem) :
_width(width), _height(height), _bpp(bpp), _vidMem(0) {
assert((_width > 0) && (_height > 0));
- assert((_bpp == 1) || (_bpp == 2));
+ assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4));
_vidMem = new byte[_bpp * _width * _height];
_ownVidMem = true;
@@ -504,7 +510,7 @@ void Surface::fillRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uin
return;
}
- assert(_bpp == 2);
+ assert((_bpp == 2) || (_bpp == 4));
// Otherwise, we have to fill by pixel
diff --git a/engines/hopkins/hopkins.cpp b/engines/hopkins/hopkins.cpp
index 407f264116..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);
@@ -164,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");
@@ -201,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)
@@ -235,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);
@@ -244,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;
@@ -793,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();
@@ -1133,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;
@@ -1153,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;
@@ -1183,6 +1188,7 @@ bool HopkinsEngine::runFull() {
}
case 50:
+ // Flight cut scene
playPlaneCutscene();
_globals->_exitId = 51;
break;
@@ -1904,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();
}
@@ -2232,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/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..a4dd50ce4b
--- /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\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/detection.cpp b/engines/neverhood/detection.cpp
index 5f860f8519..3de087051a 100644
--- a/engines/neverhood/detection.cpp
+++ b/engines/neverhood/detection.cpp
@@ -24,6 +24,7 @@
#include "engines/advancedDetector.h"
#include "common/file.h"
+#include "common/translation.h"
#include "neverhood/neverhood.h"
@@ -143,6 +144,13 @@ static const NeverhoodGameDescription gameDescriptions[] = {
} // End of namespace Neverhood
+static const ExtraGuiOption neverhoodExtraGuiOption = {
+ _s("Use original save/load screens"),
+ _s("Use the original save/load screens, instead of the ScummVM ones"),
+ "originalsaveload",
+ false
+};
+
class NeverhoodMetaEngine : public AdvancedMetaEngine {
public:
NeverhoodMetaEngine() : AdvancedMetaEngine(Neverhood::gameDescriptions, sizeof(Neverhood::NeverhoodGameDescription), neverhoodGames) {
@@ -160,7 +168,7 @@ public:
virtual bool hasFeature(MetaEngineFeature f) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
-
+ virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const;
SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
void removeSaveState(const char *target, int slot) const;
@@ -194,6 +202,12 @@ bool NeverhoodMetaEngine::createInstance(OSystem *syst, Engine **engine, const A
return gd != 0;
}
+const ExtraGuiOptions NeverhoodMetaEngine::getExtraGuiOptions(const Common::String &target) const {
+ ExtraGuiOptions options;
+ options.push_back(neverhoodExtraGuiOption);
+ return options;
+}
+
SaveStateList NeverhoodMetaEngine::listSaves(const char *target) const {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Neverhood::NeverhoodEngine::SaveHeader header;
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 &param,
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 &param, Entity *sender);
+ void openSmacker(uint32 fileHash, bool keepLastFrame);
void stop();
void tuneIn();
void playDisk();
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index 49682b0d29..b3589837df 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)
@@ -796,6 +786,7 @@ void GameModule::openMainMenu() {
createModule(1000, 0);
}
_vm->_screen->saveParams();
+ _vm->_screen->update();
_mainMenuRequested = false;
createMenuModule();
}
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 &param, 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..8814401f5e 100644
--- a/engines/neverhood/menumodule.cpp
+++ b/engines/neverhood/menumodule.cpp
@@ -20,6 +20,11 @@
*
*/
+#include "common/config-manager.h"
+#include "common/translation.h"
+
+#include "gui/saveload.h"
+
#include "neverhood/menumodule.h"
#include "neverhood/gamemodule.h"
@@ -73,12 +78,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);
}
@@ -191,24 +198,26 @@ uint32 MenuModule::handleMessage(int messageNum, const MessageParam &param, Enti
}
void MenuModule::createLoadGameMenu() {
- _savegameSlot = -1;
- _savegameList = new SavegameList();
- loadSavegameList();
+ refreshSaveGameList();
_childObject = new LoadGameMenu(_vm, this, _savegameList);
}
void MenuModule::createSaveGameMenu() {
- _savegameSlot = -1;
- _savegameList = new SavegameList();
- loadSavegameList();
+ refreshSaveGameList();
_childObject = new SaveGameMenu(_vm, this, _savegameList);
}
void MenuModule::createDeleteGameMenu() {
+ refreshSaveGameList();
+ _childObject = new DeleteGameMenu(_vm, this, _savegameList);
+}
+
+void MenuModule::refreshSaveGameList() {
_savegameSlot = -1;
+ delete _savegameList;
+ _savegameList = NULL;
_savegameList = new SavegameList();
loadSavegameList();
- _childObject = new DeleteGameMenu(_vm, this, _savegameList);
}
void MenuModule::handleLoadGameMenuAction(bool doLoad) {
@@ -608,7 +617,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 +830,7 @@ void SavegameListBox::scrollUp() {
}
void SavegameListBox::scrollDown() {
- if (_lastVisibleItem < (int)_textLabelItems.size()) {
+ if (_lastVisibleItem < (int)_textLabelItems.size() - 1) {
++_firstVisibleItem;
++_lastVisibleItem;
refresh();
@@ -838,7 +847,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;
@@ -846,6 +855,36 @@ void SavegameListBox::pageDown() {
}
}
+int GameStateMenu::scummVMSaveLoadDialog(bool isSave, Common::String &saveDesc) {
+ const EnginePlugin *plugin = NULL;
+ EngineMan.findGame(ConfMan.get("gameid"), &plugin);
+ GUI::SaveLoadChooser *dialog;
+ Common::String desc;
+ int slot;
+
+ if (isSave) {
+ dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
+
+ slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ desc = dialog->getResultString();
+
+ if (desc.empty())
+ desc = dialog->createDefaultSaveDescription(slot);
+
+ if (desc.size() > 29)
+ desc = Common::String(desc.c_str(), 29);
+
+ saveDesc = desc;
+ } else {
+ dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
+ slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ }
+
+ delete dialog;
+
+ return slot;
+}
+
GameStateMenu::GameStateMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList,
const uint32 *buttonFileHashes, const NRect *buttonCollisionBounds,
uint32 backgroundFileHash, uint32 fontFileHash,
@@ -855,8 +894,29 @@ GameStateMenu::GameStateMenu(NeverhoodEngine *vm, Module *parentModule, Savegame
uint32 textFileHash1, uint32 textFileHash2)
: Scene(vm, parentModule), _currWidget(NULL), _savegameList(savegameList) {
+ bool isSave = (textEditCursorFileHash != 0);
+
_fontSurface = new FontSurface(_vm, fontFileHash, 32, 7, 32, 11, 17);
-
+
+ if (!ConfMan.getBool("originalsaveload")) {
+ Common::String saveDesc;
+ int saveCount = savegameList->size();
+ int slot = scummVMSaveLoadDialog(isSave, saveDesc);
+
+ if (slot >= 0) {
+ if (!isSave) {
+ ((MenuModule*)_parentModule)->setLoadgameInfo(slot);
+ } else {
+ ((MenuModule*)_parentModule)->setSavegameInfo(saveDesc,
+ slot, slot >= saveCount);
+ }
+ leaveScene(0);
+ } else {
+ leaveScene(1);
+ }
+ return;
+ }
+
setBackground(backgroundFileHash);
setPalette(backgroundFileHash);
insertScreenMouse(mouseFileHash, mouseRect);
@@ -869,7 +929,7 @@ GameStateMenu::GameStateMenu(NeverhoodEngine *vm, Module *parentModule, Savegame
_textEditWidget = new TextEditWidget(_vm, textEditX, textEditY, this, 29,
_fontSurface, textEditBackgroundFileHash, textEditRect);
- if (textEditCursorFileHash != 0)
+ if (isSave)
_textEditWidget->setCursor(textEditCursorFileHash, 2, 13);
else
_textEditWidget->setReadOnly(true);
@@ -884,7 +944,6 @@ GameStateMenu::GameStateMenu(NeverhoodEngine *vm, Module *parentModule, Savegame
SetUpdateHandler(&Scene::update);
SetMessageHandler(&GameStateMenu::handleMessage);
-
}
GameStateMenu::~GameStateMenu() {
diff --git a/engines/neverhood/menumodule.h b/engines/neverhood/menumodule.h
index 08858ad204..6ee990de67 100644
--- a/engines/neverhood/menumodule.h
+++ b/engines/neverhood/menumodule.h
@@ -45,6 +45,7 @@ public:
void setLoadgameInfo(uint index);
void setSavegameInfo(const Common::String &description, uint index, bool newSavegame);
void setDeletegameInfo(uint index);
+ void refreshSaveGameList();
protected:
int _sceneNum;
byte *_savedPaletteData;
@@ -229,6 +230,7 @@ protected:
Common::String _savegameDescription;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
virtual void performAction();
+ int scummVMSaveLoadDialog(bool isSave, Common::String &saveDesc);
};
class SaveGameMenu : public GameStateMenu {
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 c4d90b5562..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:
@@ -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..ae84d59113 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:
@@ -133,7 +133,7 @@ SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 poi
if (x < 300)
loadSprite(kScene1201TntFileHashList1[elemIndex], kSLFDefDrawOffset | kSLFDefPosition, 50);
else
- loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y);
+ loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y - 20);
setClipRect(0, 0, 640, clipY2);
}
diff --git a/engines/neverhood/modules/module1300.cpp b/engines/neverhood/modules/module1300.cpp
index 8dbfcf616c..062434f064 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:
@@ -800,7 +800,7 @@ void AsScene1306Elevator::update() {
if (_isUp && _countdown != 0 && (--_countdown == 0))
stGoingDown();
AnimatedSprite::update();
- if (_currFrameIndex == 7) {
+ if (_currFrameIndex == 7 && _asElevatorDoor->getVisible()) {
playSound(1);
_asElevatorDoor->setVisible(false);
}
@@ -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..7f9ca94430 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:
@@ -210,7 +210,7 @@ Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which)
_ssFloorButton = insertSprite<SsCommonFloorButton>(this, 0x72427010, 0x32423010, 200, 0);
_asTape1 = insertSprite<AsScene1201Tape>(this, 18, 1100, 412, 443, 0x9148A011);
addCollisionSprite(_asTape1);
- _asTape2 = insertSprite<AsScene1201Tape>(this, 11, 1100, 441, 443, 0x9148A011);
+ _asTape2 = insertSprite<AsScene1201Tape>(this, 11, 1100, 441, 443, 0x9048A093);
addCollisionSprite(_asTape2);
if (which < 0) {
diff --git a/engines/neverhood/modules/module2200.cpp b/engines/neverhood/modules/module2200.cpp
index 4f2d9e8fd2..04e3f0bfee 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,11 +45,12 @@ 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:
_vm->gameState().sceneNum = 0;
+ _vm->_soundMan->startMusic(0x601C908C, 0, 2);
_childObject = new Scene2201(_vm, this, which);
break;
case 1:
@@ -2142,17 +2141,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..8d3b763f72 100644
--- a/engines/neverhood/modules/module2400.cpp
+++ b/engines/neverhood/modules/module2400.cpp
@@ -30,7 +30,7 @@ Module2400::Module2400(NeverhoodEngine *vm, Module *parentModule, int which)
_vm->_soundMan->addMusic(0x202D1010, 0xB110382D);
if (which < 0)
- createScene(_vm->gameState().sceneNum, _vm->gameState().which);
+ createScene(_vm->gameState().sceneNum, -1);
else
createScene(0, 0);
@@ -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 26df0aefa5..7ab732b4ac 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);
@@ -2443,18 +2439,6 @@ uint32 Scene2808::handleMessage(int messageNum, const MessageParam &param, 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);
@@ -3136,7 +3120,7 @@ Scene2822::Scene2822(NeverhoodEngine *vm, Module *parentModule, int which)
addBackground(_background);
_background->getSurface()->getDrawRect().y = -10;
setPalette(0xD542022E);
- insertPuzzleMouse(0x0028D089, 20, 620);
+ insertPuzzleMouse(0x2022AD5C, 20, 620);
_ssButton = insertStaticSprite(0x1A4D4120, 1100);
_ssButton->setVisible(false);
loadSound(2, 0x19044E72);
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..f483e0c95f 100644
--- a/engines/neverhood/modules/module3000.cpp
+++ b/engines/neverhood/modules/module3000.cpp
@@ -49,7 +49,7 @@ Module3000::Module3000(NeverhoodEngine *vm, Module *parentModule, int which)
_isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0;
- if (_isWallBroken) {
+ if (!_isWallBroken) {
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 0);
_vm->_soundMan->playSoundLooping(0x90F0D1C3);
}
@@ -73,15 +73,16 @@ Module3000::~Module3000() {
}
void Module3000::createScene(int sceneNum, int which) {
- static const byte kNavigationTypes05[] = {3, 0};
+ static const byte kNavigationTypes05[] = {2, 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;
+ _isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0;
switch (_vm->gameState().sceneNum) {
case 1:
if (!getGlobalVar(V_BOLT_DOOR_OPEN)) {
createNavigationScene(0x004B7C80, which);
- } else if (getGlobalVar(V_WALL_BROKEN)) {
+ } else if (_isWallBroken) {
createNavigationScene(0x004B7CE0, which);
} else {
createNavigationScene(0x004B7CB0, which);
@@ -89,11 +90,11 @@ void Module3000::createScene(int sceneNum, int which) {
break;
case 2:
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
- if (_isWallBroken) {
+ if (!_isWallBroken) {
_soundVolume = 90;
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 90);
}
- if (getGlobalVar(V_WALL_BROKEN)) {
+ if (_isWallBroken) {
createNavigationScene(0x004B7D58, which);
} else {
createNavigationScene(0x004B7D10, which);
@@ -102,7 +103,7 @@ void Module3000::createScene(int sceneNum, int which) {
case 3:
if (getGlobalVar(V_STAIRS_DOWN))
createNavigationScene(0x004B7E60, which);
- else if (getGlobalVar(V_WALL_BROKEN))
+ else if (_isWallBroken)
createNavigationScene(0x004B7DA0, which);
else
createNavigationScene(0x004B7E00, which);
@@ -150,12 +151,12 @@ void Module3000::createScene(int sceneNum, int which) {
// NOTE: Newly introduced sceneNums
case 1001:
if (!getGlobalVar(V_BOLT_DOOR_OPEN))
- if (getGlobalVar(V_WALL_BROKEN))
+ if (_isWallBroken)
createSmackerScene(0x00940021, true, true, false);
else
createSmackerScene(0x01140021, true, true, false);
else
- if (getGlobalVar(V_WALL_BROKEN))
+ if (_isWallBroken)
createSmackerScene(0x001011B1, true, true, false);
else
createSmackerScene(0x001021B1, true, true, false);
@@ -299,7 +300,7 @@ void Module3000::updateScene() {
} else if (frameNumber == 10) {
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
}
- if (_isWallBroken && _soundVolume < 90 && frameNumber % 2) {
+ if (!_isWallBroken && _soundVolume < 90 && frameNumber % 2) {
if (frameNumber == 0)
_soundVolume = 40;
else
@@ -313,7 +314,7 @@ void Module3000::updateScene() {
if (navigationScene()->isWalkingForward()) {
uint32 frameNumber = navigationScene()->getFrameNumber();
int navigationIndex = navigationScene()->getNavigationIndex();
- if (_isWallBroken && _soundVolume > 1 && frameNumber % 2) {
+ if (!_isWallBroken && _soundVolume > 1 && frameNumber % 2) {
_soundVolume--;
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _soundVolume);
}
@@ -338,7 +339,7 @@ void Module3000::updateScene() {
if (frameNumber == 40) {
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
}
- if (_isWallBroken && _soundVolume < 90 && frameNumber % 2) {
+ if (!_isWallBroken && _soundVolume < 90 && frameNumber % 2) {
if (frameNumber == 0)
_soundVolume = 40;
else
@@ -786,8 +787,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 +808,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 +849,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 +952,14 @@ uint32 Scene3009::handleMessage(int messageNum, const MessageParam &param, 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 +1220,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..073d18f47b 100644
--- a/engines/neverhood/navigationscene.cpp
+++ b/engines/neverhood/navigationscene.cpp
@@ -25,6 +25,11 @@
namespace Neverhood {
+enum AreaType {
+ kAreaCanMoveForward = 0,
+ kAreaCannotMoveForward = 1
+};
+
NavigationScene::NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint32 navigationListId, int navigationIndex, const byte *itemsTypes)
: Scene(vm, parentModule), _itemsTypes(itemsTypes), _navigationIndex(navigationIndex), _smackerDone(false),
_isWalkingForward(false), _isTurning(false), _smackerFileHash(0), _interactive(true), _leaveSceneAfter(false) {
@@ -41,9 +46,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();
@@ -51,7 +54,6 @@ NavigationScene::NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint
_vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
sendMessage(_parentModule, 0x100A, _navigationIndex);
-
}
NavigationScene::~NavigationScene() {
@@ -69,7 +71,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 +94,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 +103,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 &param, Entity *sender) {
switch (messageNum) {
case 0x0000:
@@ -130,34 +125,29 @@ uint32 NavigationScene::handleMessage(int messageNum, const MessageParam &param,
}
void NavigationScene::createMouseCursor() {
-
const NavigationItem &navigationItem = (*_navigationList)[_navigationIndex];
uint32 mouseCursorFileHash;
int areaType;
- if (_mouseCursor) {
+ if (_mouseCursor)
deleteSprite((Sprite**)&_mouseCursor);
- }
mouseCursorFileHash = navigationItem.mouseCursorFileHash;
if (mouseCursorFileHash == 0)
mouseCursorFileHash = 0x63A40028;
- if (_itemsTypes) {
+ if (_itemsTypes)
areaType = _itemsTypes[_navigationIndex];
- } else if (navigationItem.middleSmackerFileHash != 0 || navigationItem.middleFlag) {
- areaType = 0;
- } else {
- areaType = 1;
- }
+ else if (navigationItem.middleSmackerFileHash != 0 || navigationItem.middleFlag)
+ areaType = kAreaCanMoveForward;
+ else
+ areaType = kAreaCannotMoveForward;
insertNavigationMouse(mouseCursorFileHash, areaType);
sendPointMessage(_mouseCursor, 0x4002, _vm->getMousePos());
-
}
void NavigationScene::handleNavigation(const NPoint &mousePos) {
-
const NavigationItem &navigationItem = (*_navigationList)[_navigationIndex];
bool oldIsWalkingForward = _isWalkingForward;
bool oldIsTurning = _isTurning;
@@ -219,7 +209,6 @@ void NavigationScene::handleNavigation(const NPoint &mousePos) {
if (oldIsWalkingForward != _isWalkingForward)
_vm->_soundMan->setTwoSoundsPlayFlag(_isWalkingForward);
-
}
} // End of namespace Neverhood
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 &param, Entity *sender);
void createMouseCursor();
void handleNavigation(const NPoint &mousePos);
diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp
index 6b27343d03..e7c9f32d45 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"
@@ -71,12 +77,16 @@ Common::Error NeverhoodEngine::run() {
_gameState.sceneNum = 0;
_gameState.which = 0;
+ // Assign default values to the config manager, in case settings are missing
+ ConfMan.registerDefault("originalsaveload", "false");
+
_staticData = new StaticData();
_staticData->load("neverhood.dat");
_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 +108,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);
@@ -112,9 +123,10 @@ Common::Error NeverhoodEngine::run() {
(*navigationList)[5].middleFlag = 1;
}
- if (ConfMan.hasKey("save_slot"))
- loadGameState(ConfMan.getInt("save_slot"));
- else
+ if (ConfMan.hasKey("save_slot")) {
+ if (loadGameState(ConfMan.getInt("save_slot")).getCode() != Common::kNoError)
+ _gameModule->startup();
+ } else
_gameModule->startup();
mainLoop();
@@ -123,6 +135,7 @@ Common::Error NeverhoodEngine::run() {
delete _soundMan;
delete _audioResourceMan;
+ delete _console;
delete _res;
delete _screen;
@@ -140,6 +153,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 +187,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..773e80df7d 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;
@@ -120,8 +122,8 @@ public:
Common::Error loadGameState(int slot);
Common::Error saveGameState(int slot, const Common::String &description);
Common::Error removeGameState(int slot);
- void savegame(const char *filename, const char *description);
- void loadgame(const char *filename);
+ bool savegame(const char *filename, const char *description);
+ bool loadgame(const char *filename);
const char *getSavegameFilename(int num);
static Common::String getSavegameFilename(const Common::String &target, int num);
static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header);
@@ -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/saveload.cpp b/engines/neverhood/saveload.cpp
index 578d9858ff..ae93a0cea4 100644
--- a/engines/neverhood/saveload.cpp
+++ b/engines/neverhood/saveload.cpp
@@ -61,12 +61,12 @@ NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::Se
return ((in->eos() || in->err()) ? kRSHEIoError : kRSHENoError);
}
-void NeverhoodEngine::savegame(const char *filename, const char *description) {
+bool NeverhoodEngine::savegame(const char *filename, const char *description) {
Common::OutSaveFile *out;
if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
warning("Can't create file '%s', game not saved", filename);
- return;
+ return false;
}
TimeDate curTime;
@@ -99,13 +99,14 @@ void NeverhoodEngine::savegame(const char *filename, const char *description) {
out->finalize();
delete out;
+ return true;
}
-void NeverhoodEngine::loadgame(const char *filename) {
+bool NeverhoodEngine::loadgame(const char *filename) {
Common::InSaveFile *in;
if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
warning("Can't open file '%s', game not loaded", filename);
- return;
+ return false;
}
SaveHeader header;
@@ -115,7 +116,7 @@ void NeverhoodEngine::loadgame(const char *filename) {
if (errorCode != kRSHENoError) {
warning("Error loading savegame '%s'", filename);
delete in;
- return;
+ return false;
}
g_engine->setTotalPlayTime(header.playTime * 1000);
@@ -128,18 +129,20 @@ void NeverhoodEngine::loadgame(const char *filename) {
_gameModule->requestRestoreGame();
delete in;
-
+ return true;
}
Common::Error NeverhoodEngine::loadGameState(int slot) {
const char *fileName = getSavegameFilename(slot);
- loadgame(fileName);
+ if (!loadgame(fileName))
+ return Common::kReadingFailed;
return Common::kNoError;
}
Common::Error NeverhoodEngine::saveGameState(int slot, const Common::String &description) {
const char *fileName = getSavegameFilename(slot);
- savegame(fileName, description.c_str());
+ if (!savegame(fileName, description.c_str()))
+ return Common::kWritingFailed;
return Common::kNoError;
}
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/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/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/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/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/tinsel.h b/engines/tinsel/tinsel.h
index 56fed3007f..5eb3b7d7b8 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -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/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index 1de5c6850c..fff8676a89 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -1876,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) {
@@ -1909,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/toon/character.cpp b/engines/toon/character.cpp
index 479f4965f3..83c9e3ec70 100644
--- a/engines/toon/character.cpp
+++ b/engines/toon/character.cpp
@@ -58,6 +58,7 @@ Character::Character(ToonEngine *vm) : _vm(vm) {
_animSpecialDefaultId = 0;
_currentPathNode = 0;
_currentWalkStamp = 0;
+ _currentFacingStamp = 0;
_visible = true;
_speed = 150; // 150 = nominal drew speed
_lastWalkTime = 0;
@@ -99,6 +100,9 @@ void Character::setFacing(int32 facing) {
if (_blockingWalk) {
_flags |= 2;
+ _currentFacingStamp++;
+ int32 localFacingStamp = _currentFacingStamp;
+
int32 dir = 0;
_lastWalkTime = _vm->_system->getMillis();
@@ -127,6 +131,11 @@ void Character::setFacing(int32 facing) {
else
playWalkAnim(0, 0);
_vm->doFrame();
+
+ if (_currentFacingStamp != localFacingStamp) {
+ // another setFacing was started in doFrame, we need to cancel this one.
+ return;
+ }
};
_flags &= ~2;
diff --git a/engines/toon/character.h b/engines/toon/character.h
index d33c314bf7..b248e7ccf2 100644
--- a/engines/toon/character.h
+++ b/engines/toon/character.h
@@ -143,6 +143,7 @@ protected:
Common::Array<Common::Point> _currentPath;
uint32 _currentPathNode;
int32 _currentWalkStamp;
+ int32 _currentFacingStamp;
};
} // End of namespace Toon
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/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/engines/wintermute/wintermute.cpp b/engines/wintermute/wintermute.cpp
index 92381742de..89a6f1b3e0 100644
--- a/engines/wintermute/wintermute.cpp
+++ b/engines/wintermute/wintermute.cpp
@@ -292,6 +292,7 @@ bool WintermuteEngine::getGameInfo(const Common::FSList &fslist, Common::String
Common::SeekableReadStream *stream = nullptr;
// Quick-fix, instead of possibly breaking the persistence-system, let's just roll with it
BaseFileManager *fileMan = new BaseFileManager(Common::UNK_LANG, true);
+ fileMan->registerPackages(fslist);
stream = fileMan->openFile("startup.settings", false, false);
// The process is as follows: Check the "GAME=" tag in startup.settings, to decide where the
diff --git a/graphics/yuv_to_rgb.h b/graphics/yuv_to_rgb.h
index f785422c5a..a1e61ec705 100644
--- a/graphics/yuv_to_rgb.h
+++ b/graphics/yuv_to_rgb.h
@@ -22,10 +22,17 @@
/**
* @file
- * YUV to RGB conversion used in engines:
- * - mohawk
- * - scumm (he)
- * - sword25
+ * YUV to RGB conversion.
+ *
+ * Used in graphics:
+ * - JPEGDecoder
+ *
+ * Used in video:
+ * - BinkDecoder
+ * - Indeo3Decoder
+ * - PSXStreamDecoder
+ * - TheoraDecoder
+ * - SVQ1Decoder
*/
#ifndef GRAPHICS_YUV_TO_RGB_H
diff --git a/po/POTFILES b/po/POTFILES
index c2f67e288b..b812620c25 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -48,6 +48,8 @@ engines/groovie/script.cpp
engines/kyra/detection.cpp
engines/kyra/lol.cpp
engines/kyra/sound_midi.cpp
+engines/neverhood/detection.cpp
+engines/neverhood/menumodule.cpp
engines/queen/queen.cpp
engines/sky/compact.cpp
engines/sky/detection.cpp
diff --git a/video/codecs/indeo3.cpp b/video/codecs/indeo3.cpp
index 7bf7fc8235..28e1a9c620 100644
--- a/video/codecs/indeo3.cpp
+++ b/video/codecs/indeo3.cpp
@@ -32,8 +32,9 @@
#include "common/endian.h"
#include "common/stream.h"
#include "common/textconsole.h"
+#include "common/util.h"
-#include "graphics/conversion.h"
+#include "graphics/yuv_to_rgb.h"
#include "video/codecs/indeo3.h"
@@ -260,91 +261,61 @@ const Graphics::Surface *Indeo3Decoder::decodeImage(Common::SeekableReadStream *
delete[] inData;
- // Blit the frame onto the surface
const byte *srcY = _cur_frame->Ybuf;
const byte *srcU = _cur_frame->Ubuf;
const byte *srcV = _cur_frame->Vbuf;
- byte *dest = (byte *)_surface->pixels;
-
- const byte *srcUP = srcU;
- const byte *srcVP = srcV;
- const byte *srcUN = srcU + chromaWidth;
- const byte *srcVN = srcV + chromaWidth;
-
- uint32 scaleWidth = _surface->w / fWidth;
- uint32 scaleHeight = _surface->h / fHeight;
- for (uint32 y = 0; y < fHeight; y++) {
- byte *rowDest = dest;
-
- for (uint32 sH = 0; sH < scaleHeight; sH++) {
- for (uint32 x = 0; x < fWidth; x++) {
- uint32 xP = MAX<int32>((x >> 2) - 1, 0);
- uint32 xN = MIN<int32>((x >> 2) + 1, chromaWidth - 1);
-
- byte cY = srcY[x];
- byte cU = srcU[x >> 2];
- byte cV = srcV[x >> 2];
-
- if (((x % 4) == 0) && ((y % 4) == 0)) {
- cU = (((uint32) cU) + ((uint32) srcUP[xP])) / 2;
- cV = (((uint32) cV) + ((uint32) srcVP[xP])) / 2;
- } else if (((x % 4) == 3) && ((y % 4) == 0)) {
- cU = (((uint32) cU) + ((uint32) srcUP[xN])) / 2;
- cV = (((uint32) cV) + ((uint32) srcVP[xN])) / 2;
- } else if (((x % 4) == 0) && ((y % 4) == 3)) {
- cU = (((uint32) cU) + ((uint32) srcUN[xP])) / 2;
- cV = (((uint32) cV) + ((uint32) srcVN[xP])) / 2;
- } else if (((x % 4) == 3) && ((y % 4) == 3)) {
- cU = (((uint32) cU) + ((uint32) srcUN[xN])) / 2;
- cV = (((uint32) cV) + ((uint32) srcVN[xN])) / 2;
- } else if ( (x % 4) == 0) {
- cU = (((uint32) cU) + ((uint32) srcU[xP])) / 2;
- cV = (((uint32) cV) + ((uint32) srcV[xP])) / 2;
- } else if ( (x % 4) == 3) {
- cU = (((uint32) cU) + ((uint32) srcU[xN])) / 2;
- cV = (((uint32) cV) + ((uint32) srcV[xN])) / 2;
- } else if ( (y % 4) == 0) {
- cU = (((uint32) cU) + ((uint32) srcUP[x >> 2])) / 2;
- cV = (((uint32) cV) + ((uint32) srcVP[x >> 2])) / 2;
- } else if ( (y % 4) == 3) {
- cU = (((uint32) cU) + ((uint32) srcUN[x >> 2])) / 2;
- cV = (((uint32) cV) + ((uint32) srcVN[x >> 2])) / 2;
- }
+ // Create buffers for U/V with an extra row/column copied from the second-to-last
+ // row/column.
+ byte *tempU = new byte[(chromaWidth + 1) * (chromaHeight + 1)];
+ byte *tempV = new byte[(chromaWidth + 1) * (chromaHeight + 1)];
- byte r = 0, g = 0, b = 0;
- Graphics::YUV2RGB(cY, cU, cV, r, g, b);
+ for (uint i = 0; i < chromaHeight; i++) {
+ memcpy(tempU + (chromaWidth + 1) * i, srcU + chromaWidth * i, chromaWidth);
+ memcpy(tempV + (chromaWidth + 1) * i, srcV + chromaWidth * i, chromaWidth);
+ tempU[(chromaWidth + 1) * i + chromaWidth] = srcU[chromaWidth * (i + 1) - 1];
+ tempV[(chromaWidth + 1) * i + chromaWidth] = srcV[chromaWidth * (i + 1) - 1];
+ }
- const uint32 color = _pixelFormat.RGBToColor(r, g, b);
+ memcpy(tempU + (chromaWidth + 1) * chromaHeight, tempU + (chromaWidth + 1) * (chromaHeight - 1),
+ chromaWidth + 1);
+ memcpy(tempV + (chromaWidth + 1) * chromaHeight, tempV + (chromaWidth + 1) * (chromaHeight - 1),
+ chromaWidth + 1);
- for (uint32 sW = 0; sW < scaleWidth; sW++, rowDest += _surface->format.bytesPerPixel) {
- if (_surface->format.bytesPerPixel == 1)
- *((uint8 *)rowDest) = (uint8)color;
- else if (_surface->format.bytesPerPixel == 2)
- *((uint16 *)rowDest) = (uint16)color;
- }
- }
+ // Blit the frame onto the surface
+ uint32 scaleWidth = _surface->w / fWidth;
+ uint32 scaleHeight = _surface->h / fHeight;
- dest += _surface->pitch;
+ if (scaleWidth == 1 && scaleHeight == 1) {
+ // Shortcut: Don't need to scale so we can decode straight to the surface
+ YUVToRGBMan.convert410(_surface, Graphics::YUVToRGBManager::kScaleITU, srcY, tempU, tempV,
+ fWidth, fHeight, fWidth, chromaWidth + 1);
+ } else {
+ // Need to upscale, so decode to a temp surface first
+ Graphics::Surface tempSurface;
+ tempSurface.create(fWidth, fHeight, _surface->format);
+
+ YUVToRGBMan.convert410(&tempSurface, Graphics::YUVToRGBManager::kScaleITU, srcY, tempU, tempV,
+ fWidth, fHeight, fWidth, chromaWidth + 1);
+
+ // Upscale
+ for (int y = 0; y < _surface->h; y++) {
+ for (int x = 0; x < _surface->w; x++) {
+ if (_surface->format.bytesPerPixel == 1)
+ *((byte *)_surface->getBasePtr(x, y)) = *((byte *)tempSurface.getBasePtr(x / scaleWidth, y / scaleHeight));
+ else if (_surface->format.bytesPerPixel == 2)
+ *((uint16 *)_surface->getBasePtr(x, y)) = *((uint16 *)tempSurface.getBasePtr(x / scaleWidth, y / scaleHeight));
+ else if (_surface->format.bytesPerPixel == 4)
+ *((uint32 *)_surface->getBasePtr(x, y)) = *((uint32 *)tempSurface.getBasePtr(x / scaleWidth, y / scaleHeight));
+ }
}
- srcY += fWidth;
-
- if ((y & 3) == 3) {
- srcU += chromaWidth;
- srcV += chromaWidth;
-
- if (y > 0) {
- srcUP += chromaWidth;
- srcVP += chromaWidth;
- }
- if (y < (fHeight - 4U)) {
- srcUN += chromaWidth;
- srcVN += chromaWidth;
- }
- }
+ tempSurface.free();
}
+ delete[] tempU;
+ delete[] tempV;
+
return _surface;
}
diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp
index d24a021f3b..4c3b6f8414 100644
--- a/video/coktel_decoder.cpp
+++ b/video/coktel_decoder.cpp
@@ -2426,8 +2426,10 @@ void VMDDecoder::blit16(const Graphics::Surface &srcSurf, Common::Rect &rect) {
if ((r == 0) && (g == 0) && (b == 0))
c = 0;
- if (_surface.format.bytesPerPixel == 2)
+ if (_surface.format.bytesPerPixel == 2)
*((uint16 *)dstRow) = (uint16) c;
+ else if (_surface.format.bytesPerPixel == 4)
+ *((uint32 *)dstRow) = (uint32) c;
}
src += srcSurf .pitch;
@@ -2462,8 +2464,10 @@ void VMDDecoder::blit24(const Graphics::Surface &srcSurf, Common::Rect &rect) {
if ((r == 0) && (g == 0) && (b == 0))
c = 0;
- if (_surface.format.bytesPerPixel == 2)
+ if (_surface.format.bytesPerPixel == 2)
*((uint16 *)dstRow) = (uint16) c;
+ else if (_surface.format.bytesPerPixel == 4)
+ *((uint32 *)dstRow) = (uint32) c;
}
src += srcSurf .pitch;
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 {