aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--README4
-rw-r--r--backends/midi/coreaudio.cpp44
-rwxr-xr-xbackends/platform/sdl/macosx/appmenu_osx.mm44
-rw-r--r--common/zlib.cpp9
-rw-r--r--common/zlib.h33
-rwxr-xr-xconfigure53
-rw-r--r--dists/debian/copyright2
-rw-r--r--dists/macosx/DS_Storebin12292 -> 12292 bytes
-rw-r--r--dists/win32/ScummVM.iss2
-rw-r--r--engines/draci/barchive.cpp6
-rw-r--r--engines/dreamweb/dreamweb.cpp1
-rw-r--r--engines/dreamweb/dreamweb.h6
-rw-r--r--engines/dreamweb/saveload.cpp48
-rw-r--r--engines/kyra/animator_hof.cpp11
-rw-r--r--engines/kyra/animator_mr.cpp9
-rw-r--r--engines/kyra/debugger.cpp3
-rw-r--r--engines/kyra/kyra_hof.cpp6
-rw-r--r--engines/kyra/kyra_hof.h4
-rw-r--r--engines/kyra/kyra_lok.cpp9
-rw-r--r--engines/kyra/kyra_mr.h2
-rw-r--r--engines/kyra/kyra_v2.h4
-rw-r--r--engines/kyra/resource.h8
-rw-r--r--engines/kyra/sequences_hof.cpp10
-rw-r--r--engines/kyra/staticres.cpp18
-rw-r--r--engines/lure/hotspots.cpp6
-rw-r--r--engines/sci/engine/kernel_tables.h6
-rw-r--r--engines/sci/engine/kgraphics.cpp100
-rw-r--r--engines/sci/engine/script_patches.cpp62
-rw-r--r--engines/sci/graphics/frameout.cpp25
-rw-r--r--engines/sci/graphics/frameout.h1
-rw-r--r--engines/sci/graphics/text32.cpp3
-rw-r--r--engines/sci/graphics/transitions.cpp10
-rw-r--r--engines/scumm/script.cpp12
-rw-r--r--engines/sword2/sprite.cpp8
-rw-r--r--engines/tsage/globals.cpp48
-rw-r--r--engines/tsage/globals.h8
-rw-r--r--engines/tsage/graphics.cpp16
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.cpp11
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.h1
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.cpp2192
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.h259
-rw-r--r--engines/tsage/staticres.cpp23
-rw-r--r--engines/tsage/staticres.h3
-rw-r--r--gui/browser_osx.mm6
-rw-r--r--gui/themes/scummmodern.zipbin193364 -> 193298 bytes
-rw-r--r--gui/themes/scummmodern/eraser.bmpbin890 -> 824 bytes
-rw-r--r--ports.mk8
-rw-r--r--video/bink_decoder.cpp46
-rw-r--r--video/bink_decoder.h15
50 files changed, 3046 insertions, 161 deletions
diff --git a/NEWS b/NEWS
index 7c5504baca..426889c944 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,8 @@ For a more comprehensive changelog of the latest experimental code, see:
- The option to toggle sound effect types between digitized and synthesized
has been disabled until a more user-friendly GUI option is possible.
Digital sound effects are always preferred for now.
+ - Fixed a case where starting a new song didn't fully reset its channels,
+ thus some notes sounded wrong.
1.4.0 (2011-11-11)
New Games:
diff --git a/README b/README
index cb9da386df..35af23e8c2 100644
--- a/README
+++ b/README
@@ -2039,6 +2039,10 @@ The Legend of Kyrandia adds the following non-standard keyword:
walkspeed int The walk speed (0-4)
+The 7th Guest adds the following non-standard keyword:
+
+ t7g_speed string Video playback speed (normal, tweaked, im_an_ios)
+
9.0) Compiling:
---- ----------
diff --git a/backends/midi/coreaudio.cpp b/backends/midi/coreaudio.cpp
index 4b707eace6..6a4a9fa909 100644
--- a/backends/midi/coreaudio.cpp
+++ b/backends/midi/coreaudio.cpp
@@ -27,22 +27,36 @@
#ifdef MACOSX
-// HACK to disable deprecated warnings under Mac OS X 10.5. Apple deprecated the
+// With the release of Mac OS X 10.5 in October 2007, Apple deprecated the
// AUGraphNewNode & AUGraphGetNodeInfo APIs in favor of the new AUGraphAddNode &
// AUGraphNodeInfo APIs. While it is easy to switch to those, it breaks
// compatibility with all pre-10.5 systems.
-// If you want to retain compatibility with old systems, enable the following
-// switch. But Apple will eventually remove these APIs, at which point the
-// switch needs to be disabled.
//
-// Also note that only the new API is available on the iPhone!
-#define USE_DEPRECATED_COREAUDIO_API
-
+// Since 10.5 was the last system to support PowerPC, we use the old, deprecated
+// APIs on PowerPC based systems by default. On all other systems (such as Mac
+// OS X running on Intel hardware, or iOS running on ARM), we use the new API by
+// default.
+//
+// This leaves Mac OS X 10.4 running on x86 processors as the only system
+// combination that this code will not support by default. It seems quite
+// reasonable to assume that anybody with an Intel system has since then moved
+// on to a newer Mac OS X release. But if for some reason you absolutely need to
+// build an x86 version of this code using the old, deprecated API, you can
+// simply do so by manually enable the USE_DEPRECATED_COREAUDIO_API switch (e.g.
+// by adding setting it suitably in CPPFLAGS).
+#if !defined(USE_DEPRECATED_COREAUDIO_API)
+ #if TARGET_CPU_PPC || TARGET_CPU_PPC64 || !defined(MAC_OS_X_VERSION_10_6)
+ #define USE_DEPRECATED_COREAUDIO_API 1
+ #else
+ #define USE_DEPRECATED_COREAUDIO_API 0
+ #endif
+#endif
-#ifdef USE_DEPRECATED_COREAUDIO_API
-#include <AvailabilityMacros.h>
-#undef DEPRECATED_ATTRIBUTE
-#define DEPRECATED_ATTRIBUTE
+#if USE_DEPRECATED_COREAUDIO_API
+ #include <AvailabilityMacros.h>
+ // Try to silence warnings about use of deprecated APIs
+ #undef DEPRECATED_ATTRIBUTE
+ #define DEPRECATED_ATTRIBUTE
#endif
@@ -114,7 +128,7 @@ int MidiDriver_CORE::open() {
RequireNoErr(NewAUGraph(&_auGraph));
AUNode outputNode, synthNode;
-#ifdef USE_DEPRECATED_COREAUDIO_API
+#if USE_DEPRECATED_COREAUDIO_API
ComponentDescription desc;
#else
AudioComponentDescription desc;
@@ -126,7 +140,7 @@ int MidiDriver_CORE::open() {
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
-#ifdef USE_DEPRECATED_COREAUDIO_API
+#if USE_DEPRECATED_COREAUDIO_API
RequireNoErr(AUGraphNewNode(_auGraph, &desc, 0, NULL, &outputNode));
#else
RequireNoErr(AUGraphAddNode(_auGraph, &desc, &outputNode));
@@ -136,7 +150,7 @@ int MidiDriver_CORE::open() {
desc.componentType = kAudioUnitType_MusicDevice;
desc.componentSubType = kAudioUnitSubType_DLSSynth;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
-#ifdef USE_DEPRECATED_COREAUDIO_API
+#if USE_DEPRECATED_COREAUDIO_API
RequireNoErr(AUGraphNewNode(_auGraph, &desc, 0, NULL, &synthNode));
#else
RequireNoErr(AUGraphAddNode(_auGraph, &desc, &synthNode));
@@ -150,7 +164,7 @@ int MidiDriver_CORE::open() {
RequireNoErr(AUGraphInitialize(_auGraph));
// Get the music device from the graph.
-#ifdef USE_DEPRECATED_COREAUDIO_API
+#if USE_DEPRECATED_COREAUDIO_API
RequireNoErr(AUGraphGetNodeInfo(_auGraph, synthNode, NULL, NULL, NULL, &_synth));
#else
RequireNoErr(AUGraphNodeInfo(_auGraph, synthNode, NULL, &_synth));
diff --git a/backends/platform/sdl/macosx/appmenu_osx.mm b/backends/platform/sdl/macosx/appmenu_osx.mm
index bb089a6b61..97c7edba3e 100755
--- a/backends/platform/sdl/macosx/appmenu_osx.mm
+++ b/backends/platform/sdl/macosx/appmenu_osx.mm
@@ -35,6 +35,11 @@
- (void)setAppleMenu:(NSMenu *)menu;
@end
+NSString *constructNSStringFromCString(const char* rawCString, NSStringEncoding stringEncoding) {
+ NSData *nsData = [NSData dataWithBytes:rawCString length:strlen(rawCString)];
+ return [[NSString alloc] initWithData:nsData encoding:stringEncoding];
+}
+
void replaceApplicationMenuItems() {
// Code mainly copied and adapted from SDLmain.m
@@ -50,34 +55,47 @@ void replaceApplicationMenuItems() {
// Create new application menu
appleMenu = [[NSMenu alloc] initWithTitle:@""];
+ NSString *nsString = NULL;
+
// Get current encoding
#ifdef USE_TRANSLATION
- NSStringEncoding stringEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)[NSString stringWithCString:(TransMan.getCurrentCharset()).c_str() encoding:NSASCIIStringEncoding]));
+ nsString = constructNSStringFromCString((TransMan.getCurrentCharset()).c_str(), NSASCIIStringEncoding);
+ NSStringEncoding stringEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)nsString));
+ [nsString release];
#else
NSStringEncoding stringEncoding = NSASCIIStringEncoding;
#endif
-
+
// Add "About ScummVM" menu item
- [appleMenu addItemWithTitle:[NSString stringWithCString:_("About ScummVM") encoding:stringEncoding] action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+ nsString = constructNSStringFromCString(_("About ScummVM"), stringEncoding);
+ [appleMenu addItemWithTitle:nsString action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+ [nsString release];
// Add separator
[appleMenu addItem:[NSMenuItem separatorItem]];
// Add "Hide ScummVM" menu item
- [appleMenu addItemWithTitle:[NSString stringWithCString:_("Hide ScummVM") encoding:stringEncoding] action:@selector(hide:) keyEquivalent:@"h"];
+ nsString = constructNSStringFromCString(_("Hide ScummVM"), stringEncoding);
+ [appleMenu addItemWithTitle:nsString action:@selector(hide:) keyEquivalent:@"h"];
+ [nsString release];
// Add "Hide Others" menu item
- menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:[NSString stringWithCString:_("Hide Others") encoding:stringEncoding] action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
+ nsString = constructNSStringFromCString(_("Hide Others"), stringEncoding);
+ menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:nsString action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
// Add "Show All" menu item
- [appleMenu addItemWithTitle:[NSString stringWithCString:_("Show All") encoding:stringEncoding] action:@selector(unhideAllApplications:) keyEquivalent:@""];
+ nsString = constructNSStringFromCString(_("Show All"), stringEncoding);
+ [appleMenu addItemWithTitle:nsString action:@selector(unhideAllApplications:) keyEquivalent:@""];
+ [nsString release];
// Add separator
[appleMenu addItem:[NSMenuItem separatorItem]];
// Add "Quit ScummVM" menu item
- [appleMenu addItemWithTitle:[NSString stringWithCString:_("Quit ScummVM") encoding:stringEncoding] action:@selector(terminate:) keyEquivalent:@"q"];
+ nsString = constructNSStringFromCString(_("Quit ScummVM"), stringEncoding);
+ [appleMenu addItemWithTitle:nsString action:@selector(terminate:) keyEquivalent:@"q"];
+ [nsString release];
// Put application menu into the menubar
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
@@ -89,16 +107,22 @@ void replaceApplicationMenuItems() {
// Create new "Window" menu
- windowMenu = [[NSMenu alloc] initWithTitle:[NSString stringWithCString:_("Window") encoding:stringEncoding]];
+ nsString = constructNSStringFromCString(_("Window"), stringEncoding);
+ windowMenu = [[NSMenu alloc] initWithTitle:nsString];
+ [nsString release];
// Add "Minimize" menu item
- menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithCString:_("Minimize") encoding:stringEncoding] action:@selector(performMiniaturize:) keyEquivalent:@"m"];
+ nsString = constructNSStringFromCString(_("Minimize"), stringEncoding);
+ menuItem = [[NSMenuItem alloc] initWithTitle:nsString action:@selector(performMiniaturize:) keyEquivalent:@"m"];
[windowMenu addItem:menuItem];
+ [nsString release];
// Put menu into the menubar
- menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithCString:_("Window") encoding:stringEncoding] action:nil keyEquivalent:@""];
+ nsString = constructNSStringFromCString(_("Window"), stringEncoding);
+ menuItem = [[NSMenuItem alloc] initWithTitle:nsString action:nil keyEquivalent:@""];
[menuItem setSubmenu:windowMenu];
[[NSApp mainMenu] addItem:menuItem];
+ [nsString release];
// Tell the application object that this is now the window menu.
[NSApp setWindowsMenu:windowMenu];
diff --git a/common/zlib.cpp b/common/zlib.cpp
index 70133fea30..7d765fc539 100644
--- a/common/zlib.cpp
+++ b/common/zlib.cpp
@@ -49,7 +49,7 @@ bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long
return Z_OK == ::uncompress(dst, dstLen, src, srcLen);
}
-bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen) {
+bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen, const byte *dict, uint dictLen) {
if (!dst || !dstLen || !src || !srcLen)
return false;
@@ -68,6 +68,13 @@ bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen)
if (err != Z_OK)
return false;
+ // Set the dictionary, if provided
+ if (dict != 0) {
+ err = inflateSetDictionary(&stream, const_cast<byte *>(dict), dictLen);
+ if (err != Z_OK)
+ return false;
+ }
+
err = inflate(&stream, Z_SYNC_FLUSH);
if (err != Z_OK && err != Z_STREAM_END) {
inflateEnd(&stream);
diff --git a/common/zlib.h b/common/zlib.h
index 7af7df0da8..61322c286a 100644
--- a/common/zlib.h
+++ b/common/zlib.h
@@ -37,7 +37,19 @@ class WriteStream;
* it possible to uncompress data in engines without being forced to link
* them against zlib, thus simplifying the build system.
*
- * @return true on success (i.e. Z_OK), false otherwise
+ * Taken from the zlib manual:
+ * Decompresses the src buffer into the dst buffer.
+ * srcLen is the byte length of the source buffer. Upon entry, dstLen is the
+ * total size of the destination buffer, which must be large enough to hold
+ * the entire uncompressed data. Upon exit, dstLen is the actual size of the
+ * compressed buffer.
+ *
+ * @param dst the buffer to store into.
+ * @param dstLen a pointer to the size of the destination buffer.
+ * @param src the data to be decompressed.
+ * @param srcLen the size of the compressed data.
+ *
+ * @return true on success (i.e. Z_OK), false otherwise.
*/
bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen);
@@ -46,9 +58,24 @@ bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long
* necessary inflate functions to uncompress data compressed with deflate
* but *not* with the standard zlib header.
*
- * @return true on success (Z_OK or Z_STREAM_END), false otherwise
+ * Decompresses the src buffer into the dst buffer.
+ * srcLen is the byte length of the source buffer, dstLen is the byte
+ * length of the output buffer.
+ * It decompress as much data as possible, up to dstLen bytes.
+ * If a dictionary is provided through the dict buffer, uses it to initializes
+ * the internal decompression dictionary, before the decompression takes place.
+ *
+ * @param dst the buffer to store into.
+ * @param dstLen the size of the destination buffer.
+ * @param src the data to be decompressed.
+ * @param dstLen the size of the compressed data.
+ * @param dict (optional) a decompress dictionary.
+ * @param dictLen (optional) the size of the dictionary.
+ * Mandatory if dict is not 0.
+ *
+ * @return true on success (Z_OK or Z_STREAM_END), false otherwise.
*/
-bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen);
+bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen, const byte *dict = 0, uint dictLen = 0);
#endif
diff --git a/configure b/configure
index f01c009999..5b0e857fae 100755
--- a/configure
+++ b/configure
@@ -1682,7 +1682,7 @@ esac
# Determine a data type with the given length
#
find_type_with_size() {
- for datatype in int short char long unknown; do
+ for datatype in int short char long "long long" unknown; do
cat > tmp_find_type_with_size.cpp << EOF
typedef $datatype ac__type_sizeof_;
int main() {
@@ -1706,6 +1706,35 @@ EOF
}
#
+# Check whether the system is 32-bit
+#
+pointer_is_32bit() {
+ cat > tmp_pointer_is_32bit.cpp << EOF
+int main() {
+ static int test_array[1 - 2 * !(sizeof(void *) == 4)];
+ test_array[0] = 0;
+ return 0;
+}
+EOF
+ $CXX $CXXFLAGS -c -o $TMPO.o tmp_pointer_is_32bit.cpp 2>/dev/null
+ status=$?
+ cc_check_clean tmp_pointer_is_32bit.cpp
+ return $status
+}
+
+echo_n "Checking 64-bitness... "
+pointer_is_32bit
+if test $? -eq 0; then
+ type_ptr=int32
+ echo "no"
+ add_line_to_config_h "/* #define SCUMM_64BITS */"
+else
+ type_ptr=int64
+ echo "yes"
+ add_line_to_config_h "#define SCUMM_64BITS"
+fi
+
+#
# Determine data type sizes
#
echo_n "Type with 1 byte... "
@@ -1726,6 +1755,17 @@ TMPR="$?"
echo "$type_4_byte"
test $TMPR -eq 0 || exit 1 # check exit code of subshell
+echo_n "Type with 8 bytes... "
+type_8_byte=`find_type_with_size 8`
+TMPR="$?"
+echo "$type_8_byte"
+if test $TMPR -eq 0; then
+ _def_64bit_type_signed="typedef signed $type_8_byte int64;"
+ _def_64bit_type_unsigned="typedef unsigned $type_8_byte uint64;"
+fi
+# force cleanup after check for 8 bytes type
+cc_check_clean tmp_find_type_with_size.cpp
+
#
# Check whether memory alignment is required
#
@@ -3853,6 +3893,17 @@ typedef signed $type_1_byte int8;
typedef signed $type_2_byte int16;
typedef signed $type_4_byte int32;
+/* 64-bit stuff */
+$_def_64bit_type_signed
+#if defined(__APPLE__) && !defined(__ppc__)
+#ifndef _UINT64
+#define _UINT64
+$_def_64bit_type_unsigned
+#endif
+#else
+$_def_64bit_type_unsigned
+#endif
+
#endif /* CONFIG_H */
EOF
diff --git a/dists/debian/copyright b/dists/debian/copyright
index e0885ae9e6..318c06f62b 100644
--- a/dists/debian/copyright
+++ b/dists/debian/copyright
@@ -7,7 +7,7 @@ It was downloaded from <http://www.scummvm.org/>.
Upstream Authors: see `/usr/share/doc/scummvm/AUTHORS'.
-Scummvm is Copyright © 2002-2010 The ScummVM Project
+Scummvm is Copyright © 2002-2012 The ScummVM Project
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
diff --git a/dists/macosx/DS_Store b/dists/macosx/DS_Store
index 2d4193a6af..7ad5a19d61 100644
--- a/dists/macosx/DS_Store
+++ b/dists/macosx/DS_Store
Binary files differ
diff --git a/dists/win32/ScummVM.iss b/dists/win32/ScummVM.iss
index 7f3359f530..14536d0cbf 100644
--- a/dists/win32/ScummVM.iss
+++ b/dists/win32/ScummVM.iss
@@ -1,5 +1,5 @@
[Setup]
-AppCopyright=2011
+AppCopyright=2012
AppName=ScummVM
AppVerName=ScummVM Git
AppPublisher=The ScummVM Team
diff --git a/engines/draci/barchive.cpp b/engines/draci/barchive.cpp
index 154073250c..31dfe62dee 100644
--- a/engines/draci/barchive.cpp
+++ b/engines/draci/barchive.cpp
@@ -212,7 +212,8 @@ void BArchive::openArchive(const Common::String &path) {
_files[i]._offset = fileOffset; // Offset of file from start
- assert(_f.readByte() == 0 &&
+ byte compressionType = _f.readByte();
+ assert(compressionType == 0 &&
"Compression type flag is non-zero (file is compressed)");
_files[i]._crc = _f.readByte(); // CRC checksum of the file
@@ -221,7 +222,8 @@ void BArchive::openArchive(const Common::String &path) {
}
// Last footer item should be equal to footerOffset
- assert(reader.readUint32LE() == footerOffset && "Footer offset mismatch");
+ uint32 footerOffset2 = reader.readUint32LE();
+ assert(footerOffset2 == footerOffset && "Footer offset mismatch");
// Indicate that the archive has been successfully opened
_opened = true;
diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp
index 91aabc89d9..79c5e0d7be 100644
--- a/engines/dreamweb/dreamweb.cpp
+++ b/engines/dreamweb/dreamweb.cpp
@@ -195,6 +195,7 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam
_timedX = 0;
_needToDumpTimed = 0;
_loadingOrSave = 0;
+ _saveLoadPage = 0;
_currentSlot = 0;
_cursorPos = 0;
_colourPos = 0;
diff --git a/engines/dreamweb/dreamweb.h b/engines/dreamweb/dreamweb.h
index e261010902..b9623f54fa 100644
--- a/engines/dreamweb/dreamweb.h
+++ b/engines/dreamweb/dreamweb.h
@@ -227,8 +227,8 @@ protected:
Common::Point _lineData[200]; // Output of Bresenham
// from saveload.cpp
- char _saveNames[17*7];
- char _saveNamesOld[17*7];
+ char _saveNames[17*21];
+ char _saveNamesOld[17*21];
// from vgagrafx.cpp
uint8 _workspace[(0x1000 + 2) * 16];
@@ -421,6 +421,7 @@ public:
uint8 _timedX;
uint8 _needToDumpTimed;
uint8 _loadingOrSave;
+ uint8 _saveLoadPage;
uint8 _currentSlot;
uint8 _cursorPos;
uint8 _colourPos;
@@ -692,6 +693,7 @@ public:
void loadSaveBox();
void showNames();
void checkInput();
+ void selectSaveLoadPage();
void selectSlot();
void showSlots();
void showOpBox();
diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp
index 386319db34..761ce7696f 100644
--- a/engines/dreamweb/saveload.cpp
+++ b/engines/dreamweb/saveload.cpp
@@ -143,6 +143,7 @@ void DreamWebEngine::doLoad(int savegameId) {
{ kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamWebEngine::getBackToOps },
{ kOpsx+128,kOpsx+190,kOpsy+12,kOpsy+100,&DreamWebEngine::actualLoad },
{ kOpsx+2,kOpsx+92,kOpsy+4,kOpsy+81,&DreamWebEngine::selectSlot },
+ { kOpsx+158,kOpsx+158+(18*3),kOpsy-17,kOpsy-1,&DreamWebEngine::selectSaveLoadPage },
{ 0,320,0,200,&DreamWebEngine::blank },
{ 0xFFFF,0,0,0,0 }
};
@@ -234,6 +235,7 @@ void DreamWebEngine::saveGame() {
{ kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamWebEngine::getBackToOps },
{ kOpsx+128,kOpsx+190,kOpsy+12,kOpsy+100,&DreamWebEngine::actualSave },
{ kOpsx+2,kOpsx+92,kOpsy+4,kOpsy+81,&DreamWebEngine::selectSlot },
+ { kOpsx+158,kOpsx+158+(18*3),kOpsy-17,kOpsy-1,&DreamWebEngine::selectSaveLoadPage },
{ 0,320,0,200,&DreamWebEngine::blank },
{ 0xFFFF,0,0,0,0 }
};
@@ -286,11 +288,11 @@ void DreamWebEngine::saveGame() {
}
void DreamWebEngine::namesToOld() {
- memcpy(_saveNamesOld, _saveNames, 17*7);
+ memcpy(_saveNamesOld, _saveNames, 17*21);
}
void DreamWebEngine::oldToNames() {
- memcpy(_saveNames, _saveNamesOld, 17*7);
+ memcpy(_saveNames, _saveNamesOld, 17*21);
}
void DreamWebEngine::saveLoad() {
@@ -440,7 +442,7 @@ void DreamWebEngine::actualSave() {
if (!(_mouseButton & 1))
return;
- unsigned int slot = _currentSlot;
+ unsigned int slot = _currentSlot + 7 * _saveLoadPage;
const char *desc = &_saveNames[17*slot];
if (desc[1] == 0) // The actual description string starts at desc[1]
@@ -464,13 +466,13 @@ void DreamWebEngine::actualLoad() {
if (_mouseButton == _oldButton || _mouseButton != 1)
return;
- unsigned int slot = _currentSlot;
+ unsigned int slot = _currentSlot + 7 * _saveLoadPage;
const char *desc = &_saveNames[17*slot];
if (desc[1] == 0) // The actual description string starts at desc[1]
return;
- loadPosition(_currentSlot);
+ loadPosition(slot);
_getBack = 1;
}
@@ -582,10 +584,10 @@ void DreamWebEngine::loadPosition(unsigned int slot) {
if (len[0] != 17)
::error("Error loading save: description buffer isn't 17 bytes");
- if (slot < 7) {
+ if (slot < 21) {
inSaveFile->read(&_saveNames[17*slot], len[0]);
} else {
- // The savenames buffer only has room for 7 descriptions
+ // The savenames buffer only has room for 21 descriptions
uint8 namebuf[17];
inSaveFile->read(namebuf, 17);
}
@@ -644,8 +646,10 @@ void DreamWebEngine::loadPosition(unsigned int slot) {
// Count number of save files, and load their descriptions into _saveNames
uint DreamWebEngine::scanForNames() {
- // Initialize the first 7 slots (like the original code expects)
- for (unsigned int slot = 0; slot < 7; ++slot) {
+ // There are 21 save slots, each of which are 17 bytes. The first byte
+ // doesn't seem to be used. The name starts at the second byte. All the
+ // slots are initialized to be empty.
+ for (unsigned int slot = 0; slot < 21; ++slot) {
_saveNames[17 * slot + 0] = 2;
_saveNames[17 * slot + 1] = 0;
for (int i = 2; i < 17; ++i)
@@ -670,7 +674,7 @@ uint DreamWebEngine::scanForNames() {
int slotNum = atoi(file.c_str() + file.size() - 2);
SaveStateDescriptor sd(slotNum, name);
saveList.push_back(sd);
- if (slotNum < 7)
+ if (slotNum < 21)
Common::strlcpy(&_saveNames[17 * slotNum + 1], name, 16); // the first character is unused
}
@@ -709,9 +713,10 @@ void DreamWebEngine::loadSaveBox() {
// show savegame names (original interface), and set kCursorpos
void DreamWebEngine::showNames() {
+ unsigned int offset = 7 * _saveLoadPage;
for (int slot = 0; slot < 7; ++slot) {
// The first character of the savegame name is unused
- Common::String name(&_saveNames[17*slot + 1]);
+ Common::String name(&_saveNames[17 * (slot + offset) + 1]);
if (slot != _currentSlot) {
printDirect((const uint8 *)name.c_str(), kOpsx + 21, kOpsy + 10*slot + 10, 200, false);
@@ -737,8 +742,10 @@ void DreamWebEngine::checkInput() {
readKey();
+ unsigned int slot = _currentSlot + 7 * _saveLoadPage;
+
// The first character of the savegame name is unused
- char *name = &_saveNames[17*_currentSlot + 1];
+ char *name = &_saveNames[17*slot + 1];
if (_currentKey == 0) {
return;
@@ -768,6 +775,21 @@ void DreamWebEngine::checkInput() {
workToScreenM();
}
+void DreamWebEngine::selectSaveLoadPage() {
+ commandOnlyCond(31, 254);
+
+ if (_mouseButton != 1 || _mouseButton == _oldButton)
+ return;
+ uint saveLoadPage = (_mouseX - (kOpsx + 158)) / 18;
+ if (saveLoadPage != _saveLoadPage) {
+ _saveLoadPage = saveLoadPage;
+ // This will also make the first slot the selected one, based
+ // on the mouse Y position. I can't decide if this is a feature
+ // or not.
+ selectSlot();
+ }
+}
+
void DreamWebEngine::selectSlot() {
commandOnlyCond(45, 244);
@@ -798,6 +820,8 @@ void DreamWebEngine::selectSlot() {
}
void DreamWebEngine::showSlots() {
+ showFrame(_icons1, kOpsx + 158, kOpsy - 11, 12, 0);
+ showFrame(_icons1, kOpsx + 158 + 18 * _saveLoadPage, kOpsy - 11, 13 + _saveLoadPage, 0);
showFrame(_tempGraphics, kOpsx + 7, kOpsy + 8, 2, 0);
uint16 y = kOpsy + 11;
diff --git a/engines/kyra/animator_hof.cpp b/engines/kyra/animator_hof.cpp
index 741e358143..5a2378f4d0 100644
--- a/engines/kyra/animator_hof.cpp
+++ b/engines/kyra/animator_hof.cpp
@@ -115,15 +115,14 @@ void KyraEngine_HoF::refreshAnimObjects(int force) {
void KyraEngine_HoF::updateItemAnimations() {
bool nextFrame = false;
- if (_itemAnimData[0].itemIndex == -1 || _inventorySaved)
+ if (_itemAnimDefinition[0].itemIndex == -1 || _inventorySaved)
return;
- const ItemAnimData_v2 *s = &_itemAnimData[_nextAnimItem];
+ const ItemAnimDefinition *s = &_itemAnimDefinition[_nextAnimItem];
ActiveItemAnim *a = &_activeItemAnim[_nextAnimItem];
- _nextAnimItem = (_nextAnimItem + 1) % _itemAnimDataSize;
+ _nextAnimItem = (_nextAnimItem + 1) % _itemAnimDefinitionSize;
- uint32 ctime = _system->getMillis();
- if (ctime < a->nextFrame)
+ if (_system->getMillis() < a->nextFrameTime)
return;
uint16 shpIdx = s->frames[a->currentFrame].index + 64;
@@ -164,7 +163,7 @@ void KyraEngine_HoF::updateItemAnimations() {
}
if (nextFrame) {
- a->nextFrame = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength);
+ a->nextFrameTime = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength);
a->currentFrame = (a->currentFrame + 1) % s->numFrames;
}
}
diff --git a/engines/kyra/animator_mr.cpp b/engines/kyra/animator_mr.cpp
index 31c5cd1a53..29fa3aba80 100644
--- a/engines/kyra/animator_mr.cpp
+++ b/engines/kyra/animator_mr.cpp
@@ -187,15 +187,14 @@ void KyraEngine_MR::refreshAnimObjects(int force) {
void KyraEngine_MR::updateItemAnimations() {
bool nextFrame = false;
- if (_itemAnimData[0].itemIndex == -1)
+ if (_itemAnimDefinition[0].itemIndex == -1)
return;
- const ItemAnimData_v2 *s = &_itemAnimData[_nextAnimItem];
+ const ItemAnimDefinition *s = &_itemAnimDefinition[_nextAnimItem];
ActiveItemAnim *a = &_activeItemAnim[_nextAnimItem];
_nextAnimItem = (_nextAnimItem + 1) % 10;
- uint32 ctime = _system->getMillis();
- if (ctime < a->nextFrame)
+ if (_system->getMillis() < a->nextFrameTime)
return;
uint16 shpIdx = s->frames[a->currentFrame].index + 248;
@@ -230,7 +229,7 @@ void KyraEngine_MR::updateItemAnimations() {
}
if (nextFrame) {
- a->nextFrame = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength);
+ a->nextFrameTime = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength);
a->currentFrame = (a->currentFrame + 1) % s->numFrames;
}
}
diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp
index 95c6162c36..6514984b93 100644
--- a/engines/kyra/debugger.cpp
+++ b/engines/kyra/debugger.cpp
@@ -205,6 +205,7 @@ void Debugger_LoK::initialize() {
DCmd_Register("scenes", WRAP_METHOD(Debugger_LoK, cmd_listScenes));
DCmd_Register("give", WRAP_METHOD(Debugger_LoK, cmd_giveItem));
DCmd_Register("birthstones", WRAP_METHOD(Debugger_LoK, cmd_listBirthstones));
+ Debugger::initialize();
}
bool Debugger_LoK::cmd_enterRoom(int argc, const char **argv) {
@@ -295,6 +296,7 @@ void Debugger_v2::initialize() {
DCmd_Register("scene_info", WRAP_METHOD(Debugger_v2, cmd_sceneInfo));
DCmd_Register("scene_to_facing", WRAP_METHOD(Debugger_v2, cmd_sceneToFacing));
DCmd_Register("give", WRAP_METHOD(Debugger_v2, cmd_giveItem));
+ Debugger::initialize();
}
bool Debugger_v2::cmd_enterScene(int argc, const char **argv) {
@@ -445,6 +447,7 @@ Debugger_HoF::Debugger_HoF(KyraEngine_HoF *vm) : Debugger_v2(vm), _vm(vm) {
void Debugger_HoF::initialize() {
DCmd_Register("pass_codes", WRAP_METHOD(Debugger_HoF, cmd_passcodes));
+ Debugger_v2::initialize();
}
bool Debugger_HoF::cmd_passcodes(int argc, const char **argv) {
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index c3c4e6083c..fd2c1870a8 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -88,7 +88,7 @@ KyraEngine_HoF::KyraEngine_HoF(OSystem *system, const GameFlags &flags) : KyraEn
_currentTalkSections.ENDTim = 0;
memset(&_invWsa, 0, sizeof(_invWsa));
- _itemAnimData = 0;
+ _itemAnimDefinition = 0;
_demoAnimData = 0;
_nextAnimItem = 0;
@@ -211,8 +211,8 @@ void KyraEngine_HoF::pauseEngineIntern(bool pause) {
_nextIdleAnim += pausedTime;
- for (int x = 0; x < _itemAnimDataSize; x++)
- _activeItemAnim[x].nextFrame += pausedTime;
+ for (int x = 0; x < _itemAnimDefinitionSize; x++)
+ _activeItemAnim[x].nextFrameTime += pausedTime;
_tim->refreshTimersAfterPause(pausedTime);
}
diff --git a/engines/kyra/kyra_hof.h b/engines/kyra/kyra_hof.h
index 4b8303b2e4..320f930b56 100644
--- a/engines/kyra/kyra_hof.h
+++ b/engines/kyra/kyra_hof.h
@@ -874,8 +874,8 @@ protected:
const char * const *_ingameTimJpStr;
int _ingameTimJpStrSize;
const HofSeqData *_sequences;
- const ItemAnimData_v2 *_itemAnimData;
- int _itemAnimDataSize;
+ const ItemAnimDefinition *_itemAnimDefinition;
+ int _itemAnimDefinitionSize;
const ItemAnimData_v1 *_demoAnimData;
int _demoAnimSize;
diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp
index c195f0275a..74db67d22b 100644
--- a/engines/kyra/kyra_lok.cpp
+++ b/engines/kyra/kyra_lok.cpp
@@ -510,7 +510,14 @@ void KyraEngine_LoK::delay(uint32 amount, bool update, bool isMainLoop) {
updateTextFade();
updateMousePointer();
} else {
- _screen->updateScreen();
+ // We call OSystem::updateScreen here and not Screen::updateScreen
+ // to avoid new graphics changes to be copied to the screen.
+ // This assures the workaround of bug #1498221
+ // "KYRA1: Glitches when meeting Zanthia" is working correctly.
+ // Since we only call updateScreen here to let systems with frame
+ // update count limitations not miss any graphics updates it
+ // should not cause any problems.
+ _system->updateScreen();
}
_isSaveAllowed = isMainLoop;
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index 38ff271037..7c022534a2 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -219,7 +219,7 @@ private:
bool _nextIdleType;
void showIdleAnim();
- const ItemAnimData_v2 *_itemAnimData;
+ const ItemAnimDefinition *_itemAnimDefinition;
ActiveItemAnim _activeItemAnim[10];
int _nextAnimItem;
diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h
index 3d7b9c4997..72d743710d 100644
--- a/engines/kyra/kyra_v2.h
+++ b/engines/kyra/kyra_v2.h
@@ -38,7 +38,7 @@ struct FrameControl {
uint16 delay;
};
-struct ItemAnimData_v2 {
+struct ItemAnimDefinition {
Item itemIndex;
uint8 numFrames;
const FrameControl *frames;
@@ -46,7 +46,7 @@ struct ItemAnimData_v2 {
struct ActiveItemAnim {
uint16 currentFrame;
- uint32 nextFrame;
+ uint32 nextFrameTime;
};
class Screen_v2;
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 5b0af9840d..5de1577943 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -744,7 +744,7 @@ public:
const Room *loadRoomTable(int id, int &entries);
const HofSeqData *loadHofSequenceData(int id, int &entries);
const ItemAnimData_v1 *loadShapeAnimData_v1(int id, int &entries);
- const ItemAnimData_v2 *loadShapeAnimData_v2(int id, int &entries);
+ const ItemAnimDefinition *loadItemAnimDefinition(int id, int &entries);
#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
const uint16 *loadRawDataBe16(int id, int &entries);
const uint32 *loadRawDataBe32(int id, int &entries);
@@ -787,7 +787,7 @@ private:
bool loadRoomTable(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadHofSequenceData(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadShapeAnimData_v1(Common::SeekableReadStream &stream, void *&ptr, int &size);
- bool loadShapeAnimData_v2(Common::SeekableReadStream &stream, void *&ptr, int &size);
+ bool loadItemAnimDefinition(Common::SeekableReadStream &stream, void *&ptr, int &size);
#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
bool loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size);
@@ -813,7 +813,7 @@ private:
void freeRoomTable(void *&ptr, int &size);
void freeHofSequenceData(void *&ptr, int &size);
void freeHofShapeAnimDataV1(void *&ptr, int &size);
- void freeHofShapeAnimDataV2(void *&ptr, int &size);
+ void freeItemAnimDefinition(void *&ptr, int &size);
#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
void freeRawDataBe16(void *&ptr, int &size);
void freeRawDataBe32(void *&ptr, int &size);
@@ -840,7 +840,7 @@ private:
k2SeqData = 5,
k2ShpAnimDataV1 = 6,
- k2ShpAnimDataV2 = 7,
+ k2ItemAnimDefinition = 7,
kLoLCharData = 8,
kLoLSpellData = 9,
diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp
index b27f0df137..686c3c9320 100644
--- a/engines/kyra/sequences_hof.cpp
+++ b/engines/kyra/sequences_hof.cpp
@@ -234,6 +234,8 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
int32 dly = _tickLength - (now - _seqSubFrameStartTime);
if (dly > 0)
delay(MIN<uint32>(dly, tdiff));
+ else
+ updateInput();
}
}
@@ -263,6 +265,8 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
int32 dly = _tickLength - (now - _seqSubFrameStartTime);
if (dly > 0)
delay(MIN<uint32>(dly, tdiff));
+ else
+ updateInput();
}
seq_sequenceCommand(cseq.finalCommand);
@@ -2773,15 +2777,15 @@ void KyraEngine_HoF::seq_init() {
return;
if (_flags.isDemo && !_flags.isTalkie) {
- _demoAnimData = _staticres->loadShapeAnimData_v1(k2SeqplayShapeAnimData, _itemAnimDataSize);
+ _demoAnimData = _staticres->loadShapeAnimData_v1(k2SeqplayShapeAnimData, _itemAnimDefinitionSize);
uint8 *shp = _res->fileData("icons.shp", 0);
uint32 outsize = READ_LE_UINT16(shp + 4);
_animShapeFiledata = new uint8[outsize];
Screen::decodeFrame4(shp + 10, _animShapeFiledata, outsize);
delete[] shp;
- for (int numShp = 0; getShapePtr(numShp); ++numShp)
- addShapeToPool(_screen->getPtrToShape(_animShapeFiledata, numShp), numShp);
+ for (int i = 0; i < 20; i++)
+ addShapeToPool(_screen->getPtrToShape(_animShapeFiledata, i), i);
} else {
const MainMenu::StaticData data = {
{ _sequenceStrings[97], _sequenceStrings[96], _sequenceStrings[95], _sequenceStrings[98], 0 },
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 6c95451c5f..99ad6ea7aa 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -247,7 +247,7 @@ bool StaticResource::init() {
{ k2SeqData, proc(loadHofSequenceData), proc(freeHofSequenceData) },
{ k2ShpAnimDataV1, proc(loadShapeAnimData_v1), proc(freeHofShapeAnimDataV1) },
- { k2ShpAnimDataV2, proc(loadShapeAnimData_v2), proc(freeHofShapeAnimDataV2) },
+ { k2ItemAnimDefinition, proc(loadItemAnimDefinition), proc(freeItemAnimDefinition) },
#ifdef ENABLE_LOL
{ kLoLCharData, proc(loadCharData), proc(freeCharData) },
@@ -316,8 +316,8 @@ const ItemAnimData_v1 *StaticResource::loadShapeAnimData_v1(int id, int &entries
return (const ItemAnimData_v1 *)getData(id, k2ShpAnimDataV1, entries);
}
-const ItemAnimData_v2 *StaticResource::loadShapeAnimData_v2(int id, int &entries) {
- return (const ItemAnimData_v2 *)getData(id, k2ShpAnimDataV2, entries);
+const ItemAnimDefinition *StaticResource::loadItemAnimDefinition(int id, int &entries) {
+ return (const ItemAnimDefinition *)getData(id, k2ItemAnimDefinition, entries);
}
bool StaticResource::prefetchId(int id) {
@@ -610,9 +610,9 @@ bool StaticResource::loadShapeAnimData_v1(Common::SeekableReadStream &stream, vo
return true;
}
-bool StaticResource::loadShapeAnimData_v2(Common::SeekableReadStream &stream, void *&ptr, int &size) {
+bool StaticResource::loadItemAnimDefinition(Common::SeekableReadStream &stream, void *&ptr, int &size) {
size = stream.readByte();
- ItemAnimData_v2 *loadTo = new ItemAnimData_v2[size];
+ ItemAnimDefinition *loadTo = new ItemAnimDefinition[size];
assert(loadTo);
for (int i = 0; i < size; i++) {
@@ -699,8 +699,8 @@ void StaticResource::freeHofShapeAnimDataV1(void *&ptr, int &size) {
size = 0;
}
-void StaticResource::freeHofShapeAnimDataV2(void *&ptr, int &size) {
- ItemAnimData_v2 *d = (ItemAnimData_v2 *)ptr;
+void StaticResource::freeItemAnimDefinition(void *&ptr, int &size) {
+ ItemAnimDefinition *d = (ItemAnimDefinition *)ptr;
for (int i = 0; i < size; i++)
delete[] d[i].frames;
delete[] d;
@@ -1007,7 +1007,7 @@ void KyraEngine_HoF::initStaticResource() {
_cdaTrackTableFinale = _staticres->loadRawData(k2SeqplayFinaleCDA, _cdaTrackTableFinaleSize);
_ingameTalkObjIndex = (const uint16 *)_staticres->loadRawData(k2IngameTalkObjIndex, _ingameTalkObjIndexSize);
_ingameTimJpStr = _staticres->loadStrings(k2IngameTimJpStrings, _ingameTimJpStrSize);
- _itemAnimData = _staticres->loadShapeAnimData_v2(k2IngameShapeAnimData, _itemAnimDataSize);
+ _itemAnimDefinition = _staticres->loadItemAnimDefinition(k2IngameShapeAnimData, _itemAnimDefinitionSize);
// replace sequence talkie files with localized versions
const char *const *seqSoundList = _staticres->loadStrings(k2SeqplaySfxFiles, _sequenceSoundListSize);
@@ -1143,7 +1143,7 @@ void KyraEngine_MR::initStaticResource() {
_scoreTable = _staticres->loadRawData(k3ScoreTable, _scoreTableSize);
_sfxFileList = _staticres->loadStrings(k3SfxFiles, _sfxFileListSize);
_sfxFileMap = _staticres->loadRawData(k3SfxMap, _sfxFileMapSize);
- _itemAnimData = _staticres->loadShapeAnimData_v2(k3ItemAnimData, tmp);
+ _itemAnimDefinition = _staticres->loadItemAnimDefinition(k3ItemAnimData, tmp);
_itemMagicTable = _staticres->loadRawData(k3ItemMagicTable, tmp);
_itemStringMap = _staticres->loadRawData(k3ItemStringMap, _itemStringMapSize);
}
diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp
index 2f6d0f23aa..c7e7e81900 100644
--- a/engines/lure/hotspots.cpp
+++ b/engines/lure/hotspots.cpp
@@ -2334,9 +2334,11 @@ void Hotspot::saveToStream(Common::WriteStream *stream) {
void Hotspot::loadFromStream(Common::ReadStream *stream) {
if (_data)
_data->npcSchedule.loadFromStream(stream);
- else
+ else {
// Dummy read of terminator for empty actions list
- assert(stream->readByte() == 0xff);
+ byte dummy = stream->readByte();
+ assert(dummy == 0xff);
+ }
_pathFinder.loadFromStream(stream);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index fe0c9fc2ef..622511c906 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -610,6 +610,12 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_DUMMY(DeletePic), SIG_EVERYWHERE, "(.*)", NULL, NULL },
{ MAP_DUMMY(GetSierraProfileString), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ // Unused / debug functions in the in-between SCI2.1 interpreters
+ { MAP_DUMMY(PreloadResource), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ { MAP_DUMMY(CheckCDisc), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ { MAP_DUMMY(GetSaveCDisc), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ { MAP_DUMMY(TestPoly), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+
// SCI2.1 unmapped functions - TODO!
// MovePlaneItems - used by SQ6 to scroll through the inventory via the up/down buttons
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 76c6778f0a..cfeaaaa803 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -25,6 +25,7 @@
#include "engines/util.h"
#include "graphics/cursorman.h"
#include "graphics/surface.h"
+#include "graphics/palette.h" // temporary, for the fadeIn()/fadeOut() functions below
#include "gui/message.h"
@@ -1212,7 +1213,8 @@ reg_t kRemapColors(EngineState *s, int argc, reg_t *argv) {
switch (operation) {
case 0: { // Set remapping to base. 0 turns remapping off.
int16 base = (argc >= 2) ? argv[1].toSint16() : 0;
- warning("kRemapColors: Set remapping to base %d", base);
+ if (base != 0) // 0 is the default behavior when changing rooms in GK1, thus silencing the warning
+ warning("kRemapColors: Set remapping to base %d", base);
}
break;
case 1: { // unknown
@@ -1440,6 +1442,46 @@ reg_t kWinHelp(EngineState *s, int argc, reg_t *argv) {
return s->r_acc;
}
+// Taken from the SCI16 GfxTransitions class
+static void fadeOut() {
+ byte oldPalette[3 * 256], workPalette[3 * 256];
+ int16 stepNr, colorNr;
+ // Sierra did not fade in/out color 255 for sci1.1, but they used it in
+ // several pictures (e.g. qfg3 demo/intro), so the fading looked weird
+ int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
+
+ g_system->getPaletteManager()->grabPalette(oldPalette, 0, 256);
+
+ for (stepNr = 100; stepNr >= 0; stepNr -= 10) {
+ for (colorNr = 1; colorNr <= tillColorNr; colorNr++) {
+ if (g_sci->_gfxPalette->colorIsFromMacClut(colorNr)) {
+ workPalette[colorNr * 3 + 0] = oldPalette[colorNr * 3];
+ workPalette[colorNr * 3 + 1] = oldPalette[colorNr * 3 + 1];
+ workPalette[colorNr * 3 + 2] = oldPalette[colorNr * 3 + 2];
+ } else {
+ workPalette[colorNr * 3 + 0] = oldPalette[colorNr * 3] * stepNr / 100;
+ workPalette[colorNr * 3 + 1] = oldPalette[colorNr * 3 + 1] * stepNr / 100;
+ workPalette[colorNr * 3 + 2] = oldPalette[colorNr * 3 + 2] * stepNr / 100;
+ }
+ }
+ g_system->getPaletteManager()->setPalette(workPalette + 3, 1, tillColorNr);
+ g_sci->getEngineState()->wait(2);
+ }
+}
+
+// Taken from the SCI16 GfxTransitions class
+static void fadeIn() {
+ int16 stepNr;
+ // Sierra did not fade in/out color 255 for sci1.1, but they used it in
+ // several pictures (e.g. qfg3 demo/intro), so the fading looked weird
+ int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
+
+ for (stepNr = 0; stepNr <= 100; stepNr += 10) {
+ g_sci->_gfxPalette->kernelSetIntensity(1, tillColorNr + 1, stepNr, true);
+ g_sci->getEngineState()->wait(2);
+ }
+}
+
/**
* Used for scene transitions, replacing (but reusing parts of) the old
* transition code.
@@ -1450,31 +1492,65 @@ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) {
// tables inside graphics/transitions.cpp
uint16 showStyle = argv[0].toUint16(); // 0 - 15
reg_t planeObj = argv[1]; // the affected plane
- //argv[2] // seconds that the transition lasts
- //argv[3] // back color to be used(?)
- //int16 priority = argv[4].toSint16();
- //argv[5] // boolean, animate or not while the transition lasts
- //argv[6] // refFrame
+ uint16 seconds = argv[2].toUint16(); // seconds that the transition lasts
+ uint16 backColor = argv[3].toUint16(); // target back color(?). When fading out, it's 0x0000. When fading in, it's 0xffff
+ int16 priority = argv[4].toSint16(); // always 0xc8 (200) when fading in/out
+ uint16 animate = argv[5].toUint16(); // boolean, animate or not while the transition lasts
+ uint16 refFrame = argv[6].toUint16(); // refFrame, always 0 when fading in/out
+ int16 divisions;
// If the game has the pFadeArray selector, another parameter is used here,
// before the optional last parameter
- /*bool hasFadeArray = g_sci->getKernel()->findSelector("pFadeArray") > 0;
+ bool hasFadeArray = g_sci->getKernel()->findSelector("pFadeArray") > 0;
if (hasFadeArray) {
// argv[7]
- //int16 unk7 = (argc >= 9) ? argv[8].toSint16() : 0; // divisions (transition steps?)
+ divisions = (argc >= 9) ? argv[8].toSint16() : -1; // divisions (transition steps?)
} else {
- //int16 unk7 = (argc >= 8) ? argv[7].toSint16() : 0; // divisions (transition steps?)
- }*/
+ divisions = (argc >= 8) ? argv[7].toSint16() : -1; // divisions (transition steps?)
+ }
if (showStyle > 15) {
warning("kSetShowStyle: Illegal style %d for plane %04x:%04x", showStyle, PRINT_REG(planeObj));
return s->r_acc;
}
+ // TODO: Proper implementation. This is a very basic version. I'm not even
+ // sure if the rest of the styles will work with this mechanism.
+
+ // Check if the passed parameters are the ones we expect
+ if (showStyle == 13 || showStyle == 14) { // fade out / fade in
+ if (seconds != 1)
+ warning("kSetShowStyle(fade): seconds isn't 1, it's %d", seconds);
+ if (backColor != 0 && backColor != 0xFFFF)
+ warning("kSetShowStyle(fade): backColor isn't 0 or 0xFFFF, it's %d", backColor);
+ if (priority != 200)
+ warning("kSetShowStyle(fade): priority isn't 200, it's %d", priority);
+ if (animate != 0)
+ warning("kSetShowStyle(fade): animate isn't 0, it's %d", animate);
+ if (refFrame != 0)
+ warning("kSetShowStyle(fade): refFrame isn't 0, it's %d", refFrame);
+ if (divisions >= 0 && divisions != 20)
+ warning("kSetShowStyle(fade): divisions isn't 20, it's %d", divisions);
+ }
+
// TODO: Check if the plane is in the list of planes to draw
- // TODO: This is all a stub/skeleton, thus we're invoking kStub() for now
- kStub(s, argc, argv);
+ switch (showStyle) {
+ //case 0: // no transition, perhaps? (like in the previous SCI versions)
+ case 13: // fade out
+ // TODO: Temporary implementation, which ignores all additional parameters
+ fadeOut();
+ break;
+ case 14: // fade in
+ // TODO: Temporary implementation, which ignores all additional parameters
+ g_sci->_gfxFrameout->kernelFrameout(); // draw new scene before fading in
+ fadeIn();
+ break;
+ default:
+ // TODO: This is all a stub/skeleton, thus we're invoking kStub() for now
+ kStub(s, argc, argv);
+ break;
+ }
return s->r_acc;
}
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 7efcb42f4b..187f1ce021 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -366,7 +366,7 @@ const uint16 freddypharkasPatchLadderEvent[] = {
// script, description, magic DWORD, adjust
const SciScriptSignature freddypharkasSignatures[] = {
{ 0, "CD: score early disposal", 1, PATCH_MAGICDWORD(0x39, 0x0d, 0x43, 0x75), -3, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal },
- { 235, "CD: canister pickup hang", 3, PATCH_MAGICDWORD(0x39, 0x07, 0x39, 0x08), -4, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang },
+ { 235, "CD: canister pickup hang", 3, PATCH_MAGICDWORD(0x39, 0x07, 0x39, 0x08), -4, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang },
{ 320, "ladder event issue", 2, PATCH_MAGICDWORD(0x6d, 0x76, 0x38, 0xf5), -1, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -437,8 +437,68 @@ const uint16 gk1PatchDay5PhoneFreeze[] = {
PATCH_END
};
+// Floppy version: Interrogation::dispose() compares an object reference
+// (stored in the view selector) with a number, leading to a crash (this kind
+// of comparison was not used in SCI32). The view selector is used to store
+// both a view number (in some cases), and a view reference (in other cases).
+// In the floppy version, the checks are in the wrong order, so there is a
+// comparison between a number an an object. In the CD version, the checks are
+// in the correct order, thus the comparison is correct, thus we use the code
+// from the CD version in the floppy one.
+const byte gk1SignatureInterrogationBug[] = {
+ 43,
+ 0x65, 0x4c, // aTop 4c
+ 0x67, 0x50, // pTos 50
+ 0x34, 0x10, 0x27, // ldi 2710
+ 0x1e, // gt?
+ 0x31, 0x08, // bnt 08 [05a0]
+ 0x67, 0x50, // pTos 50
+ 0x34, 0x10, 0x27, // ldi 2710
+ 0x04, // sub
+ 0x65, 0x50, // aTop 50
+ 0x63, 0x50, // pToa 50
+ 0x31, 0x15, // bnt 15 [05b9]
+ 0x39, 0x0e, // pushi 0e
+ 0x76, // push0
+ 0x4a, 0x04, 0x00, // send 0004
+ 0xa5, 0x00, // sat 00
+ 0x38, 0x93, 0x00, // pushi 0093
+ 0x76, // push0
+ 0x63, 0x50, // pToa 50
+ 0x4a, 0x04, 0x00, // send 0004
+ 0x85, 0x00, // lat 00
+ 0x65, 0x50, // aTop 50
+ 0
+};
+
+const uint16 gk1PatchInterrogationBug[] = {
+ 0x65, 0x4c, // aTop 4c
+ 0x63, 0x50, // pToa 50
+ 0x31, 0x15, // bnt 15 [05b9]
+ 0x39, 0x0e, // pushi 0e
+ 0x76, // push0
+ 0x4a, 0x04, 0x00, // send 0004
+ 0xa5, 0x00, // sat 00
+ 0x38, 0x93, 0x00, // pushi 0093
+ 0x76, // push0
+ 0x63, 0x50, // pToa 50
+ 0x4a, 0x04, 0x00, // send 0004
+ 0x85, 0x00, // lat 00
+ 0x65, 0x50, // aTop 50
+ 0x67, 0x50, // pTos 50
+ 0x34, 0x10, 0x27, // ldi 2710
+ 0x1e, // gt?
+ 0x31, 0x08, // bnt 08 [05b9]
+ 0x67, 0x50, // pTos 50
+ 0x34, 0x10, 0x27, // ldi 2710
+ 0x04, // sub
+ 0x65, 0x50, // aTop 50
+ PATCH_END
+};
+
// script, description, magic DWORD, adjust
const SciScriptSignature gk1Signatures[] = {
+ { 51, "interrogation bug", 1, PATCH_MAGICDWORD(0x65, 0x4c, 0x67, 0x50), 0, gk1SignatureInterrogationBug, gk1PatchInterrogationBug },
{ 212, "day 5 phone freeze", 1, PATCH_MAGICDWORD(0x35, 0x03, 0x65, 0x1a), 0, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
{ 230, "day 6 police beignet timer issue", 1, PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -16, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
{ 230, "day 6 police sleep timer issue", 1, PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -5, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index 7bb4162020..e3fac80f7c 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -101,7 +101,7 @@ void GfxFrameout::kernelAddPlane(reg_t object) {
}
void GfxFrameout::kernelUpdatePlane(reg_t object) {
- for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) {
+ for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); ++it) {
if (it->object == object) {
// Read some information
it->priority = readSelectorValue(_segMan, object, SELECTOR(priority));
@@ -178,8 +178,10 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) {
}
void GfxFrameout::kernelDeletePlane(reg_t object) {
+ deletePlaneItems(object);
deletePlanePictures(object);
- for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) {
+
+ for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); ++it) {
if (it->object == object) {
_planes.erase(it);
Common::Rect planeRect;
@@ -193,10 +195,6 @@ void GfxFrameout::kernelDeletePlane(reg_t object) {
planeRect.left = (planeRect.left * screenRect.width()) / _scriptsRunningWidth;
planeRect.bottom = (planeRect.bottom * screenRect.height()) / _scriptsRunningHeight;
planeRect.right = (planeRect.right * screenRect.width()) / _scriptsRunningWidth;
- planeRect.clip(screenRect); // we need to do this, at least in gk1 on cemetary we get bottom right -> 201, 321
- // FIXME: The code above incorrectly added 1 pixel to the plane's
- // bottom and right, so probably the plane clipping code is no
- // longer necessary
// Blackout removed plane rect
_paint32->fillRect(planeRect, 0);
return;
@@ -276,6 +274,18 @@ void GfxFrameout::kernelDeleteScreenItem(reg_t object) {
_screenItems.remove(itemEntry);
}
+void GfxFrameout::deletePlaneItems(reg_t planeObject) {
+ FrameoutList::iterator listIterator = _screenItems.begin();
+
+ while (listIterator != _screenItems.end()) {
+ reg_t itemPlane = readSelector(_segMan, (*listIterator)->object, SELECTOR(plane));
+ if (planeObject == itemPlane)
+ listIterator = _screenItems.erase(listIterator);
+ else
+ ++listIterator;
+ }
+}
+
FrameoutEntry *GfxFrameout::findScreenItem(reg_t object) {
for (FrameoutList::iterator listIterator = _screenItems.begin(); listIterator != _screenItems.end(); listIterator++) {
FrameoutEntry *itemEntry = *listIterator;
@@ -498,7 +508,8 @@ void GfxFrameout::kernelFrameout() {
// There is a race condition lurking in SQ6, which causes the game to hang in the intro, when teleporting to Polysorbate LX.
// Since I first wrote the patch, the race has stopped occurring for me though.
// I'll leave this for investigation later, when someone can reproduce.
- if (it->pictureId == 0xffff)
+ //if (it->pictureId == 0xffff) // FIXME: This is what SSCI does, and fixes the intro of LSL7, but breaks the dialogs in GK1 (adds black boxes)
+ if (it->planeBack)
_paint32->fillRect(it->planeRect, it->planeBack);
GuiResourceId planeMainPictureId = it->pictureId;
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h
index a4a0a853e4..8c3cc261d5 100644
--- a/engines/sci/graphics/frameout.h
+++ b/engines/sci/graphics/frameout.h
@@ -94,6 +94,7 @@ public:
void kernelAddScreenItem(reg_t object);
void kernelUpdateScreenItem(reg_t object);
void kernelDeleteScreenItem(reg_t object);
+ void deletePlaneItems(reg_t planeObject);
FrameoutEntry *findScreenItem(reg_t object);
int16 kernelGetHighPlanePri();
void kernelAddPicAt(reg_t planeObj, GuiResourceId pictureId, int16 pictureX, int16 pictureY);
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index 000bb691dc..e7595fbdaf 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -175,6 +175,7 @@ void GfxText32::disposeTextBitmap(reg_t hunkId) {
void GfxText32::drawTextBitmap(uint16 x, uint16 y, Common::Rect planeRect, reg_t textObject) {
reg_t hunkId = readSelector(_segMan, textObject, SELECTOR(bitmap));
+ uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back));
// Sanity check: Check if the hunk is set. If not, either the game scripts
// didn't set it, or an old saved game has been loaded, where it wasn't set.
if (hunkId.isNull())
@@ -204,7 +205,7 @@ void GfxText32::drawTextBitmap(uint16 x, uint16 y, Common::Rect planeRect, reg_t
for (int curY = 0; curY < height; curY++) {
for (int curX = 0; curX < width; curX++) {
byte pixel = surface[curByte++];
- if (pixel != skipColor)
+ if (pixel != skipColor && pixel != backColor)
_screen->putFontPixel(textY, curX + textX, curY, pixel);
}
}
diff --git a/engines/sci/graphics/transitions.cpp b/engines/sci/graphics/transitions.cpp
index d047eb10a1..438cf376a5 100644
--- a/engines/sci/graphics/transitions.cpp
+++ b/engines/sci/graphics/transitions.cpp
@@ -295,12 +295,12 @@ void GfxTransitions::fadeOut() {
int16 stepNr, colorNr;
// Sierra did not fade in/out color 255 for sci1.1, but they used it in
// several pictures (e.g. qfg3 demo/intro), so the fading looked weird
- int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 256 : 255;
+ int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
g_system->getPaletteManager()->grabPalette(oldPalette, 0, 256);
for (stepNr = 100; stepNr >= 0; stepNr -= 10) {
- for (colorNr = 1; colorNr < tillColorNr; colorNr++) {
+ for (colorNr = 1; colorNr <= tillColorNr; colorNr++) {
if (_palette->colorIsFromMacClut(colorNr)) {
workPalette[colorNr * 3 + 0] = oldPalette[colorNr * 3];
workPalette[colorNr * 3 + 1] = oldPalette[colorNr * 3 + 1];
@@ -311,7 +311,7 @@ void GfxTransitions::fadeOut() {
workPalette[colorNr * 3 + 2] = oldPalette[colorNr * 3 + 2] * stepNr / 100;
}
}
- g_system->getPaletteManager()->setPalette(workPalette + 3, 1, 254);
+ g_system->getPaletteManager()->setPalette(workPalette + 3, 1, tillColorNr);
g_sci->getEngineState()->wait(2);
}
}
@@ -322,10 +322,10 @@ void GfxTransitions::fadeIn() {
int16 stepNr;
// Sierra did not fade in/out color 255 for sci1.1, but they used it in
// several pictures (e.g. qfg3 demo/intro), so the fading looked weird
- int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 256 : 255;
+ int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
for (stepNr = 0; stepNr <= 100; stepNr += 10) {
- _palette->kernelSetIntensity(1, tillColorNr, stepNr, true);
+ _palette->kernelSetIntensity(1, tillColorNr + 1, stepNr, true);
g_sci->getEngineState()->wait(2);
}
}
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index cfc4b3c419..37ea3a9a9f 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -29,6 +29,7 @@
#include "scumm/resource.h"
#include "scumm/util.h"
#include "scumm/scumm_v2.h"
+#include "scumm/sound.h"
#include "scumm/verbs.h"
namespace Scumm {
@@ -935,6 +936,17 @@ void ScummEngine::runExitScript() {
}
if (VAR_EXIT_SCRIPT2 != 0xFF && VAR(VAR_EXIT_SCRIPT2))
runScript(VAR(VAR_EXIT_SCRIPT2), 0, 0, 0);
+
+#ifdef ENABLE_SCUMM_7_8
+ // WORKAROUND: The spider lair (room 44) will optionally play the sound
+ // of trickling water (sound 215), but it never stops it. The same sound
+ // effect is also used in room 33, so let's do the same fade out that it
+ // does in that room's exit script.
+ if (_game.id == GID_DIG && _currentRoom == 44) {
+ int scriptCmds[] = { 14, 215, 0x600, 0, 30, 0, 0, 0 };
+ _sound->soundKludge(scriptCmds, ARRAYSIZE(scriptCmds));
+ }
+#endif
}
void ScummEngine::runEntryScript() {
diff --git a/engines/sword2/sprite.cpp b/engines/sword2/sprite.cpp
index 73a4eca8bd..cb0923cc2f 100644
--- a/engines/sword2/sprite.cpp
+++ b/engines/sword2/sprite.cpp
@@ -772,14 +772,18 @@ int32 Screen::drawSprite(SpriteInfo *s) {
src = sprite + rs.top * srcPitch + rs.left;
dst = _buffer + _screenWide * rd.top + rd.left;
- if (s->type & RDSPR_BLEND && !Sword2Engine::isPsx()) { // Blending is unavailable in PSX version
+ if (s->type & RDSPR_BLEND) {
// The original code had two different blending cases. One for
// s->blend & 0x01 and one for s->blend & 0x02. However, the
// only values that actually appear in the cluster files are
// 0, 513 and 1025 so the s->blend & 0x02 case was never used.
// Which is just as well since that code made no sense to me.
- if (!(_renderCaps & RDBLTFX_SPRITEBLEND)) {
+ // TODO: In PSX version, blending is done through hardware transparency.
+ // The only correct way to simulate this would be using 16-bit mode.
+ // As this is not yet available for this engine, fake transparency is used
+ // as placeholder.
+ if (!(_renderCaps & RDBLTFX_SPRITEBLEND) || Sword2Engine::isPsx()) {
for (i = 0; i < rs.height(); i++) {
for (j = 0; j < rs.width(); j++) {
if (src[j] && ((i & 1) == (j & 1)))
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index ad7d0d1e0c..1ac426518d 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -381,27 +381,49 @@ void Ringworld2Globals::reset() {
_v5657C = 0;
_v565F5 = 0;
_v565AE = 0;
- for (int i = 0; i < 14; i++)
- _v56605[i] = 0;
+
+ _v56605[0] = 0;
+ _v56605[1] = 3;
+ _v56605[2] = 5;
+ _v56605[3] = 1;
+ _v56605[4] = 2;
+ _v56605[5] = 5;
+ _v56605[6] = 9;
+ _v56605[7] = 14;
+ _v56605[8] = 15;
+ _v56605[9] = 18;
+ _v56605[10] = 20;
+ _v56605[11] = 25;
+ _v56605[12] = 27;
+ _v56605[13] = 31;
+
_v566A6 = 3800;
- _v566A8 = 0;
+ _v566A8 = 5;
_v566A9 = 0;
_v566AA = 0;
for (int i = 0; i < 1000; i++)
_v566AB[i] = 0;
- _v56A93 = 0;
- _v56A99 = 0;
+ _v56A93 = -1;
+ _v56A99 = 5;
_v56A9E = 0;
_v56AA0 = 0;
_v56AA1 = 0;
+ _v56AA2 = 60;
+ _v56AA4 = 660;
+ _v56AA6 = 1;
+ _v56AA7 = 1;
+ _v56AA8 = 1;
_v56AAB = 0;
_v57C2C = 0;
_v58CE2 = 0;
- Common::fill(&_v565F1[0], &_v565F1[MAX_CHARACTERS], 0);
+ _v565EC[0] = 0;
+ _v565EC[1] = 27;
+ _v565EC[2] = 27;
+ _v565EC[3] = 4;
+ _v565EC[4] = 4;
+ Common::fill(&_v565F1[0], &_v565F1[MAX_CHARACTERS], 1);
_speechSubtitles = SPEECH_VOICE | SPEECH_TEXT;
_insetUp = 0;
-
- Common::fill(&_v565F1[0], &_v565F1[MAX_CHARACTERS], 0);
Common::fill(&_stripManager_lookupList[0], &_stripManager_lookupList[12], 0);
_stripManager_lookupList[0] = 1;
_stripManager_lookupList[1] = 1;
@@ -434,13 +456,18 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsSint16LE(_v566A6);
s.syncAsSint16LE(_v56A93);
s.syncAsSint16LE(_v56A9E);
+ s.syncAsSint16LE(_v56AA2);
+ s.syncAsSint16LE(_v56AA4);
s.syncAsSint16LE(_v56AAB);
s.syncAsSint16LE(_v57C2C);
s.syncAsSint16LE(_v58CE2);
s.syncAsSint16LE(_speechSubtitles);
+ for (i = 0; i < 5; i++)
+ s.syncAsByte(_v565EC[i]);
+
for (i = 0; i < MAX_CHARACTERS; ++i)
- s.syncAsSint16LE(_v565F1[i]);
+ s.syncAsByte(_v565F1[i]);
s.syncAsByte(_v565AE);
s.syncAsByte(_v566A8);
@@ -448,6 +475,9 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsByte(_v566AA);
s.syncAsByte(_v56AA0);
s.syncAsByte(_v56AA1);
+ s.syncAsByte(_v56AA6);
+ s.syncAsByte(_v56AA7);
+ s.syncAsByte(_v56AA8);
for (i = 0; i < 14; ++i)
s.syncAsByte(_v56605[i]);
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index 227058f1d6..9d00e618a4 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -265,11 +265,17 @@ public:
int _v56A9E;
byte _v56AA0;
byte _v56AA1;
+ int _v56AA2;
+ int _v56AA4;
+ byte _v56AA6;
+ byte _v56AA7;
+ byte _v56AA8;
int _v56AAB;
int _v57C2C;
int _v58CE2;
int _speechSubtitles;
- int _v565F1[4];
+ byte _v565EC[5];
+ byte _v565F1[4];
byte _stripManager_lookupList[12];
virtual void reset();
diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp
index 8436afe2e8..5acd191b11 100644
--- a/engines/tsage/graphics.cpp
+++ b/engines/tsage/graphics.cpp
@@ -259,6 +259,12 @@ void GfxSurface::updateScreen() {
for (Common::List<Rect>::iterator i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) {
Rect r = *i;
+ // Make sure that there is something to update. If not, skip this
+ // rectangle. An example case is the speedbike closeup at the beginning
+ // of Ringworld (third screen).
+ if (r.isEmpty())
+ continue;
+
const byte *srcP = (const byte *)_customSurface->getBasePtr(r.left, r.top);
g_system->copyRectToScreen(srcP, _customSurface->pitch, r.left, r.top,
r.width(), r.height());
@@ -1302,19 +1308,29 @@ int GfxManager::getAngle(const Common::Point &p1, const Common::Point &p2) {
}
}
+// FIXME: The two checks for screenSurface inside these two copyFrom() methods
+// are meant for Ringworld 2, but the corresponding setBounds cases cause
+// issues with the popup menus when right clicking in all games (e.g. the popup
+// menu is always shown on the top left of the screen). Therefore, these two
+// code fragments are disabled for now, till the glitches they cause are fixed.
void GfxManager::copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion) {
+#if 0
if (&_surface == &(GLOBALS._screenSurface))
_surface.setBounds(Rect(0, 0, _bounds.width(), _bounds.height()));
else
+#endif
_surface.setBounds(_bounds);
_surface.copyFrom(src, destBounds, priorityRegion);
}
+
void GfxManager::copyFrom(GfxSurface &src, int destX, int destY) {
+#if 0
if (&_surface == &(GLOBALS._screenSurface))
_surface.setBounds(Rect(0, 0, _bounds.width(), _bounds.height()));
else
+#endif
_surface.setBounds(_bounds);
_surface.copyFrom(src, destX, destY);
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp
index fa7895f407..2f537c4ebe 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.cpp
+++ b/engines/tsage/ringworld2/ringworld2_logic.cpp
@@ -36,6 +36,8 @@ namespace TsAGE {
namespace Ringworld2 {
Scene *Ringworld2Game::createScene(int sceneNumber) {
+ warning("Switching to scene %d", sceneNumber);
+
switch (sceneNumber) {
/* Scene group #0 */
case 50:
@@ -102,11 +104,20 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
case 1100:
return new Scene1100();
case 1200:
+ return new Scene1200();
case 1330:
+ error("Missing scene %d from group 1", sceneNumber);
case 1500:
+ // Cutscene: Ship landing
+ return new Scene1500();
case 1525:
+ // Cutscene - Ship
+ return new Scene1525();
case 1530:
+ // Cutscene - Elevator
+ return new Scene1530();
case 1550:
+ return new Scene1550();
case 1575:
case 1580:
case 1625:
diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h
index bb6aa25f85..9b64063803 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.h
+++ b/engines/tsage/ringworld2/ringworld2_logic.h
@@ -265,6 +265,7 @@ public:
int _state;
SceneActorExt() { _state = 0; }
+
virtual Common::String getClassName() { return "SceneActorExt"; }
virtual void synchronize(Serializer &s) {
SceneActor::synchronize(s);
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.cpp b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
index e773c52805..45aec17fbf 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
@@ -856,5 +856,2197 @@ void Scene1100::saveCharacter(int characterIndex) {
R2_GLOBALS._sound1.fadeOut2(NULL);
SceneExt::saveCharacter(characterIndex);
}
+
+/*--------------------------------------------------------------------------
+ * Scene 1200 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1200::Scene1200() {
+ _field412 = 0;
+ _field414 = 0;
+ _field416 = 0;
+ _field418 = 0;
+ _field41A = 0;
+ _field41C = 1; //CHECKME: Only if fixup_flag == 6??
+}
+
+void Scene1200::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_field418);
+ s.syncAsSint16LE(_field41A);
+ s.syncAsSint16LE(_field41C);
+}
+
+Scene1200::Area1::Area1() {
+ _field20 = 0;
+}
+
+void Scene1200::Area1::synchronize(Serializer &s) {
+ SceneArea::synchronize(s);
+
+ s.syncAsByte(_field20);
+}
+
+void Scene1200::Area1::Actor3::init(int state) {
+ _state = state;
+
+ SceneActor::postInit();
+ setup(1003, 1, 1);
+ fixPriority(255);
+
+ switch (_state) {
+ case 1:
+ switch (R2_GLOBALS._v56AA6) {
+ case 1:
+ setFrame2(2);
+ setPosition(Common::Point(129, 101));
+ break;
+ case 2:
+ setFrame2(3);
+ setPosition(Common::Point(135, 95));
+ break;
+ default:
+ break;
+ }
+ case 2:
+ switch (R2_GLOBALS._v56AA7) {
+ case 1:
+ setFrame2(2);
+ setPosition(Common::Point(152, 101));
+ break;
+ case 2:
+ setFrame2(3);
+ setPosition(Common::Point(158, 122));
+ break;
+ case 3:
+ setFrame2(3);
+ setPosition(Common::Point(135, 122));
+ break;
+ default:
+ break;
+ }
+ case 3:
+ switch (R2_GLOBALS._v56AA8) {
+ case 1:
+ setFrame2(3);
+ setPosition(Common::Point(158, 95));
+ break;
+ case 2:
+ setFrame2(2);
+ setPosition(Common::Point(175, 101));
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+
+ setDetails(1200, 12, -1, -1, 2, (SceneItem *) NULL);
+}
+
+bool Scene1200::Area1::Actor3::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._sound2.play(260);
+ switch (_state) {
+ case 1:
+ if (R2_GLOBALS._v56AA6 == 1) {
+ R2_GLOBALS._v56AA6 = 2;
+ setFrame2(3);
+ setPosition(Common::Point(135, 95));
+ } else {
+ R2_GLOBALS._v56AA6 = 1;
+ setFrame2(2);
+ setPosition(Common::Point(129, 101));
+ }
+ break;
+ case 2:
+ ++R2_GLOBALS._v56AA7;
+ if (R2_GLOBALS._v56AA7 == 4)
+ R2_GLOBALS._v56AA7 = 1;
+
+ switch (R2_GLOBALS._v56AA7) {
+ case 1:
+ setFrame2(1);
+ setPosition(Common::Point(152, 101));
+ break;
+ case 2:
+ setFrame2(3);
+ setPosition(Common::Point(158, 122));
+ break;
+ case 3:
+ setFrame2(3);
+ setPosition(Common::Point(135, 122));
+ break;
+ default:
+ break;
+ }
+ break;
+ case 3:
+ if (R2_GLOBALS._v56AA8 == 1) {
+ R2_GLOBALS._v56AA8 = 2;
+ setFrame2(2);
+ setPosition(Common::Point(175, 101));
+ } else {
+ R2_GLOBALS._v56AA8 = 1;
+ setFrame2(3);
+ setPosition(Common::Point(158, 95));
+ }
+ break;
+ default:
+ break;
+ }
+
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+ scene->_field418 = 0;
+
+ if ((R2_GLOBALS._v56AA6 == 1) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ scene->_field418 = 1;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ scene->_field418 = 2;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 2))
+ scene->_field418 = 3;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 3) && (R2_GLOBALS._v56AA8 == 1))
+ scene->_field418 = 4;
+
+ return true;
+}
+
+void Scene1200::Area1::postInit() {
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_field41A = 1;
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ proc12(1003, 1, 1, 100, 40);
+ proc13(1200, 11, -1, -1);
+ R2_GLOBALS._sound2.play(259);
+ _actor3.init(1);
+ _actor4.init(2);
+ _actor5.init(3);
+
+ R2_GLOBALS._player._canWalk = false;
+}
+
+void Scene1200::Area1::remove() {
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_field41A = 0;
+ warning("Unexpected _sceneAreas.remove() call");
+// scene->_sceneAreas.remove(&_actor3);
+// scene->_sceneAreas.remove(&_actor4);
+// scene->_sceneAreas.remove(&_actor5);
+ _actor3.remove();
+ _actor4.remove();
+ _actor5.remove();
+
+ // sub201EA
+ R2_GLOBALS._sceneItems.remove((SceneItem *)this);
+ _actor2.remove();
+ SceneArea::remove();
+ R2_GLOBALS._insetUp--;
+ //
+
+ R2_GLOBALS._player._canWalk = true;
+}
+
+void Scene1200::Area1::process(Event &event) {
+ if (_field20 != R2_GLOBALS._insetUp)
+ return;
+
+ CursorType cursor = R2_GLOBALS._events.getCursor();
+
+ if (_actor2._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
+ if (cursor == _cursorNum)
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ } else if (event.mousePos.y < 168) {
+ if (cursor != _cursorNum) {
+ _savedCursorNum = cursor;
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(CURSOR_INVALID);
+ }
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ event.handled = true;
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ remove();
+ }
+ }
+}
+
+void Scene1200::Area1::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+
+ _actor2.postInit();
+ _actor2.setup(visage, stripFrameNum, frameNum);
+ _actor2.setPosition(Common::Point(posX, posY));
+ _actor2.fixPriority(250);
+ _cursorNum = CURSOR_INVALID;
+ scene->_sceneAreas.push_front(this);
+ ++R2_GLOBALS._insetUp;
+ _field20 = R2_GLOBALS._insetUp;
+}
+
+void Scene1200::Area1::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+ _actor2.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
+}
+
+Scene1200::Object1::Object1() {
+ _field16 = _field26 = _field28 = _field2A = _field2C = _field2E = _field30 = 0;
+}
+
+void Scene1200::Object1::synchronize(Serializer &s) {
+ SavedObject::synchronize(s);
+
+ s.syncAsSint16LE(_field16);
+ s.syncAsSint16LE(_field26);
+ s.syncAsSint16LE(_field28);
+ s.syncAsSint16LE(_field2A);
+ s.syncAsSint16LE(_field2C);
+ s.syncAsSint16LE(_field2E);
+ s.syncAsSint16LE(_field30);
+}
+
+int Scene1200::Object1::sub51AF8(Common::Point pt) {
+ if (!_rect1.contains(pt))
+ return -1;
+
+ int tmp1 = (pt.x - _rect1.left + _field2E) / _field2A;
+ int tmp2 = (pt.y - _rect1.top + _field30) / _field2C;
+
+ if ((tmp1 >= 0) && (tmp2 >= 0) && (_field26 > tmp1) && (_field28 > tmp2))
+ return _field16 + (((_field26 * tmp2) + tmp1)* 2);
+
+ return -1;
+}
+
+bool Scene1200::Object1::sub51AFD(Common::Point pt) {
+ int retval = false;
+
+ _field2E = pt.x;
+ _field30 = pt.y;
+
+ if (_field2E < _rect2.top) {
+ _field2E = _rect2.top;
+ retval = true;
+ }
+
+ if (_field30 < _rect2.left) {
+ _field30 = _rect2.left;
+ retval = true;
+ }
+
+ if (_field2E + _rect1.width() > _rect2.right) {
+ _field2E = _rect2.right - _rect1.width();
+ retval = true;
+ }
+
+ if (_field30 + _rect1.height() > _rect2.bottom) {
+ _field30 = _rect2.bottom - _rect1.height();
+ retval = true;
+ }
+
+ return retval;
+}
+
+void Scene1200::Object1::sub9EDE8(Rect rect) {
+ _rect1 = rect;
+ warning("FIXME: Scene1200::Object1::sub9EDE8()");
+// _rect1.clip(g_globals->gfxManager()._bounds);
+}
+
+void Scene1200::postInit(SceneObjectList *OwnerList) {
+ Rect tmpRect;
+
+ loadScene(1200);
+ SceneExt::postInit();
+
+ if (R2_GLOBALS._sceneManager._previousScene < 3200)
+ R2_GLOBALS._sound1.play(257);
+
+ _field412 = 1;
+ _field414 = 0;
+ _field416 = 0;
+ _field418 = 0;
+ _field41A = 0;
+ _field41C = 0;
+
+ if ((R2_GLOBALS._v56AA6 == 1) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ _field418 = 1;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ _field418 = 2;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 2))
+ _field418 = 3;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 3) && (R2_GLOBALS._v56AA8 == 1))
+ _field418 = 4;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.setup(3156, 1, 6);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player._oldCharacterScene[3] = 1200;
+
+ _actor1.postInit();
+ _actor1.hide();
+
+ tmpRect.set(110, 20, 210, 120);
+ _object1.sub9EDE8(tmpRect);
+
+ warning("_object1.sub51AE9(1);");
+ _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4));
+ warning("int unk = set_pane_p(_paneNumber);");
+ warning("_object1.sub51B02();");
+ warning("set_pane_p(unk);");
+
+ R2_GLOBALS._player.enableControl();
+ _item1.setDetails(Rect(0, 0, 320, 200), 1200, 0, 1, 2, 1, NULL);
+}
+
+void Scene1200::signal() {
+ switch (_sceneMode++) {
+ case 1:
+ // No break on purpose
+ case 1200:
+ // No break on purpose
+ case 1201:
+ // No break on purpose
+ case 1202:
+ // No break on purpose
+ case 1203:
+ R2_GLOBALS._player.enableControl();
+ warning("_eventManager.waitEvent()");
+ _sceneMode = 2;
+ break;
+ case 10:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(1);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 11:
+ // No break on purpose
+ case 21:
+ // No break on purpose
+ case 31:
+ // No break on purpose
+ case 41:
+ _field416 = 0;
+ break;
+ case 12:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 1, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 13:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 23:
+ // No break on purpose
+ case 26:
+ // No break on purpose
+ case 33:
+ // No break on purpose
+ case 36:
+ // No break on purpose
+ case 43:
+ // No break on purpose
+ case 46:
+ R2_GLOBALS._player.setFrame(4);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 15:
+ // No break on purpose
+ case 25:
+ // No break on purpose
+ case 35:
+ // No break on purpose
+ case 45:
+ _field414 = 20;
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 20:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(2);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 22:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 2, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 30:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 32:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 3, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 40:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(4);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 42:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 4, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 50:
+ // No break on purpose
+ case 55:
+ // No break on purpose
+ case 60:
+ R2_GLOBALS._player.setup(3156, 5, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 51:
+ // No break on purpose
+ case 56:
+ // No break on purpose
+ case 117:
+ R2_GLOBALS._player.setup(3157, 1, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 52:
+ // No break on purpose
+ case 82:
+ // No break on purpose
+ case 118:
+ R2_GLOBALS._player.setup(3156, 3, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 57:
+ // No break on purpose
+ case 91:
+ // No break on purpose
+ case 96:
+ R2_GLOBALS._player.setup(3157, 2, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 58:
+ // No break on purpose
+ case 92:
+ // No break on purpose
+ case 122:
+ R2_GLOBALS._player.setup(3156, 2, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 61:
+ R2_GLOBALS._player.setup(3157, 4, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 62:
+ // No break on purpose
+ case 72:
+ // No break on purpose
+ case 98:
+ R2_GLOBALS._player.setup(3156, 4, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 70:
+ // No break on purpose
+ case 75:
+ // No break on purpose
+ case 80:
+ R2_GLOBALS._player.setup(3156, 6, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 71:
+ // No break on purpose
+ case 76:
+ // No break on purpose
+ case 97:
+ R2_GLOBALS._player.setup(3157, 3, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 77:
+ // No break on purpose
+ case 111:
+ // No break on purpose
+ case 116:
+ R2_GLOBALS._player.setup(3157, 3, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 78:
+ // No break on purpose
+ case 102:
+ // No break on purpose
+ case 112:
+ R2_GLOBALS._player.setup(3156, 1, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 81:
+ R2_GLOBALS._player.setup(3157, 2, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 90:
+ // No break on purpose
+ case 95:
+ // No break on purpose
+ case 100:
+ R2_GLOBALS._player.setup(3156, 7, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 101:
+ R2_GLOBALS._player.setup(3157, 1, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 110:
+ // No break on purpose
+ case 115:
+ // No break on purpose
+ case 120:
+ R2_GLOBALS._player.setup(3156, 8, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 121:
+ R2_GLOBALS._player.setup(3157, 3, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ default:
+ warning("_eventManager.waitEvent()");
+ _sceneMode = 2;
+ break;
+ }
+}
+
+void Scene1200::process(Event &event) {
+ if (_field414 != 0)
+ return;
+
+ Scene::process(event);
+
+ if (!R2_GLOBALS._player._canWalk)
+ return;
+
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ warning("_object1.sub9EE22(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4);");
+ int unk = _object1.sub51AF8(event.mousePos);
+ switch (R2_GLOBALS._events.getCursor()) {
+ case CURSOR_ARROW:
+ event.handled = true;
+ if ((event.mousePos.x > 179) && (event.mousePos.x < 210) && (event.mousePos.y > 50) && (event.mousePos.y < 89))
+ warning("sub9DAD6(1);");
+
+ if ((event.mousePos.x > 109) && (event.mousePos.x < 140) && (event.mousePos.y > 50) && (event.mousePos.y < 89))
+ warning("sub9DAD6(2);");
+
+ if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 89) && (event.mousePos.y < 120))
+ warning("sub9DAD6(3);");
+
+ if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 19) && (event.mousePos.y < 50))
+ warning("sub9DAD6(4);");
+ break;
+ case CURSOR_USE:
+ if (unk > 36) {
+ if ( ((R2_GLOBALS._v56AA2 == 3) && (R2_GLOBALS._v56AA4 == 33))
+ || ((R2_GLOBALS._v56AA2 == 7) && (R2_GLOBALS._v56AA4 == 33))
+ || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 41))
+ || ((R2_GLOBALS._v56AA2 == 5) && (R2_GLOBALS._v56AA4 == 5))
+ || ((R2_GLOBALS._v56AA2 == 13) && (R2_GLOBALS._v56AA4 == 21))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 21))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 5))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 9))
+ || ((R2_GLOBALS._v56AA2 == 29) && (R2_GLOBALS._v56AA4 == 17))
+ || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 17))
+ || ((R2_GLOBALS._v56AA2 == 35) && (R2_GLOBALS._v56AA4 == 17))
+ || ((R2_GLOBALS._v56AA2 == 41) && (R2_GLOBALS._v56AA4 == 21)) ) {
+ _area1.postInit();
+ event.handled = true;
+ }
+ }
+
+ if ((unk == 1) || (unk == 4) || (unk == 11) || (unk == 14)) {
+ if ( ((R2_GLOBALS._v56AA2 == 3) && (R2_GLOBALS._v56AA4 == 9))
+ || ((R2_GLOBALS._v56AA2 == 11) && (R2_GLOBALS._v56AA4 == 27))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 7))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 27))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 33))
+ || (R2_GLOBALS._v56AA2 == 33) ) {
+ switch (R2_GLOBALS._v56AA2) {
+ case 3:
+ R2_GLOBALS._sceneManager.changeScene(3150);
+ break;
+ case 33:
+ if (R2_GLOBALS._v56AA1 >= 4)
+ R2_GLOBALS._sceneManager.changeScene(3250);
+ else
+ SceneItem::display(1200, 6, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ break;
+ default:
+ SceneItem::display(1200, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ break;
+ }
+ event.handled = true;
+ }
+ }
+ break;
+ case CURSOR_LOOK:
+ if ((unk == 1) || (unk == 4) || (unk == 11) || (unk == 14)) {
+ event.handled = true;
+ switch (R2_GLOBALS._v56AA2) {
+ case 3:
+ SceneItem::display(1200, 8, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 9:
+ R2_GLOBALS._sceneManager.changeScene(3240);
+ break;
+ case 11:
+ if (R2_GLOBALS._v56AA4 == 27)
+ R2_GLOBALS._sceneManager.changeScene(3210);
+ else
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 17:
+ switch (R2_GLOBALS._v56AA4) {
+ case 5:
+ R2_GLOBALS._sceneManager.changeScene(3230);
+ break;
+ case 21:
+ R2_GLOBALS._sceneManager.changeScene(3220);
+ break;
+ case 33:
+ R2_GLOBALS._sceneManager.changeScene(3200);
+ break;
+ default:
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ }
+ case 33:
+ R2_GLOBALS._sceneManager.changeScene(3245);
+ break;
+ default:
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ }
+ }
+ if (unk > 36) {
+ event.handled = true;
+ SceneItem::display(1200, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ }
+ break;
+ case CURSOR_TALK:
+ event.handled = true;
+ break;
+ default:
+ return;
+ }
+ } else if (event.eventType == EVENT_KEYPRESS) {
+ if (_field414 == 0) {
+ event.handled = false;
+ return;
+ }
+
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_1:
+ warning("FIXME: keycode = 0x4800");
+ warning("sub9DAD6(4);");
+ break;
+ case Common::KEYCODE_2:
+ warning("FIXME: keycode = 0x4B00");
+ warning("sub9DAD6(2);");
+ break;
+ case Common::KEYCODE_3:
+ warning("FIXME: keycode = 0x4D00");
+ warning("sub9DAD6(1);");
+ break;
+ case Common::KEYCODE_4:
+ warning("FIXME: keycode = 0x5000");
+ warning("sub9DAD6(3);");
+ break;
+ default:
+ event.handled = false;
+ return;
+ break;
+ }
+ } else {
+ return;
+ }
+}
+
+void Scene1200::dispatch() {
+ Rect tmpRect;
+ Scene::dispatch();
+ if (_field41C != 0) {
+ _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4));
+ warning("int unk = set_pane_p(_paneNumber);");
+ warning("_object1.sub51B02();");
+ warning("_gfxManager.sub294AC(unk);");
+ warning("tmpRect.sub14DF3();");
+ _field41C = 0;
+ }
+
+ if (_field414 != 0) {
+ tmpRect.set(110, 20, 210, 120);
+ _field414--;
+ switch (_field412 - 1) {
+ case 0:
+ R2_GLOBALS._v56AA2 += 2;
+ break;
+ case 1:
+ R2_GLOBALS._v56AA2 -= 2;
+ break;
+ case 2:
+ R2_GLOBALS._v56AA4 += 2;
+ break;
+ case 3:
+ R2_GLOBALS._v56AA4 -= 2;
+ break;
+ default:
+ break;
+ }
+ _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4));
+ warning("int unk = set_pane_p(_paneNumber);");
+ warning("_object1.sub51B02();");
+ warning("_gfxManager.sub294AC(unk);");
+ warning("tmpRect.sub14DF3();");
+
+ if (_field416 != 0) {
+ switch(_field412 - 1) {
+ case 0:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x - 2, R2_GLOBALS._player._position.y));
+ break;
+ case 1:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x + 2, R2_GLOBALS._player._position.y));
+ break;
+ case 2:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y - 2));
+ break;
+ case 3:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 2));
+ break;
+ default:
+ break;
+ }
+ }
+ if (_field414 == 0) {
+ if (_field416 == 0)
+ R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
+ signal();
+ }
+ }
+}
+
+void Scene1200::saveCharacter(int characterIndex) {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::saveCharacter(characterIndex);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1500 - Cutscene: Ship landing
+ *
+ *--------------------------------------------------------------------------*/
+void Scene1500::postInit(SceneObjectList *OwnerList) {
+ loadScene(1500);
+ R2_GLOBALS._v58CE2 = 0;
+ R2_GLOBALS._v5589E.top = 0;
+ R2_GLOBALS._v5589E.bottom = 200;
+ setZoomPercents(170, 13, 240, 100);
+ SceneExt::postInit();
+ scalePalette(65, 65, 65);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _actor2.postInit();
+ _actor2.setup(1401, 1, 1);
+ _actor2._effect = 5;
+ _actor2.fixPriority(10);
+ _actor2._field9C = _field312;
+
+ _actor1.postInit();
+ _actor1.setup(1400, 1, 1);
+ _actor1._moveDiff = Common::Point(1, 1);
+ _actor1._linkedActor = &_actor2;
+
+ if (R2_GLOBALS._sceneManager._previousScene != 1010) {
+ _actor4.postInit();
+ _actor4.setup(1401, 2, 1);
+ _actor4._effect = 5;
+ _actor4.fixPriority(10);
+ _actor4._field9C = _field312;
+
+ _actor3.postInit();
+ _actor3._moveRate = 30;
+ _actor3._moveDiff = Common::Point(1, 1);
+ _actor3._linkedActor = &_actor4;
+ }
+
+ if (R2_GLOBALS._sceneManager._previousScene == 300) {
+ _actor1.setPosition(Common::Point(189, 139), 5);
+
+ _actor3.setup(1400, 1, 2);
+ _actor3.setPosition(Common::Point(148, 108), 0);
+
+ _sceneMode = 20;
+ R2_GLOBALS._sound1.play(110);
+ } else if (R2_GLOBALS._sceneManager._previousScene == 1550) {
+ _actor1.setPosition(Common::Point(189, 139), 5);
+
+ _actor3.setup(1400, 2, 1);
+ _actor3.changeZoom(-1);
+ _actor3.setPosition(Common::Point(298, 258), 5);
+
+ _sceneMode = 10;
+ R2_GLOBALS._sound1.play(106);
+ } else {
+ _actor1.setPosition(Common::Point(289, 239), -30);
+ _sceneMode = 0;
+ R2_GLOBALS._sound1.play(102);
+ }
+ signal();
+}
+
+void Scene1500::remove() {
+ R2_GLOBALS._v5589E.top = 3;
+ R2_GLOBALS._v5589E.bottom = 168;
+ R2_GLOBALS._v58CE2 = 1;
+
+ SceneExt::remove();
+}
+
+void Scene1500::signal() {
+ switch(_sceneMode++) {
+ case 0:
+ R2_GLOBALS.setFlag(25);
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ // No break on purpose
+ case 1:
+ if (_actor1._yDiff < 50) {
+ _actor1.setPosition(Common::Point(289, 239), _actor1._yDiff + 1);
+ _sceneMode = 1;
+ }
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 2: {
+ Common::Point pt(189, 139);
+ NpcMover *mover = new NpcMover();
+ _actor1.addMover(mover, &pt, this);
+ }
+ break;
+ case 3:
+ if (_actor1._yDiff > 5) {
+ _actor1.setPosition(Common::Point(189, 139), _actor1._yDiff - 1);
+ _sceneMode = 3;
+ }
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 13:
+ R2_GLOBALS._player._characterIndex = R2_MIRANDA;
+ // No break on purpose
+ case 4:
+ R2_GLOBALS._sceneManager.changeScene(300);
+ break;
+ case 10:
+ // No break on purpose
+ case 20:
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 11: {
+ Common::Point pt(148, 108);
+ NpcMover *mover = new NpcMover();
+ _actor3.addMover(mover, &pt, this);
+ }
+ break;
+ case 12:
+ setAction(&_sequenceManager, this, 2, &R2_GLOBALS._player, NULL);
+ break;
+ case 21: {
+ Common::Point pt(-2, -42);
+ NpcMover *mover = new NpcMover();
+ _actor3.addMover(mover, &pt, NULL);
+ signal();
+ }
+ break;
+ case 22:
+ if (_actor1._yDiff < 50) {
+ _actor1.setPosition(Common::Point(189, 139), _actor1._yDiff + 1);
+ _sceneMode = 22;
+ }
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 23: {
+ Common::Point pt(-13, -61);
+ NpcMover *mover = new NpcMover();
+ _actor1.addMover(mover, &pt, this);
+ }
+ break;
+ case 24:
+ R2_GLOBALS._sceneManager.changeScene(300);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1500::dispatch() {
+ if (_sceneMode > 10) {
+ float yDiff = sqrt((float) (_actor3._position.x * _actor3._position.x) + (_actor3._position.y * _actor3._position.y));
+ if (yDiff > 6)
+ _actor3.setPosition(_actor3._position, (int) yDiff);
+ }
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1525 - Cutscene - Ship
+ *
+ *--------------------------------------------------------------------------*/
+void Scene1525::postInit(SceneObjectList *OwnerList) {
+ loadScene(1525);
+ R2_GLOBALS._v58CE2 = 0;
+ SceneExt::postInit();
+
+ R2_GLOBALS._player.postInit();
+ if (R2_GLOBALS._sceneManager._previousScene == 525)
+ R2_GLOBALS._player.setup(1525, 1, 1);
+ else
+ R2_GLOBALS._player.setup(1525, 1, 16);
+ R2_GLOBALS._player.setPosition(Common::Point(244, 148));
+ R2_GLOBALS._player.disableControl();
+
+ _sceneMode = 0;
+ setAction(&_sequenceManager, this, 2, &R2_GLOBALS._player, NULL);
+}
+
+void Scene1525::signal() {
+ switch (_sceneMode++) {
+ case 0:
+ if (R2_GLOBALS._sceneManager._previousScene == 525)
+ setAction(&_sequenceManager, this, 1525, &R2_GLOBALS._player, NULL);
+ else
+ setAction(&_sequenceManager, this, 1526, &R2_GLOBALS._player, NULL);
+ break;
+ case 1:
+ setAction(&_sequenceManager, this, 2, &R2_GLOBALS._player, NULL);
+ break;
+ case 2:
+ if (R2_GLOBALS._sceneManager._previousScene == 1530)
+ R2_GLOBALS._sceneManager.changeScene(1550);
+ else
+ R2_GLOBALS._sceneManager.changeScene(1530);
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1530 - Cutscene - Elevator
+ *
+ *--------------------------------------------------------------------------*/
+void Scene1530::postInit(SceneObjectList *OwnerList) {
+ if (R2_GLOBALS._sceneManager._previousScene == 1000)
+ loadScene(1650);
+ else if (R2_GLOBALS._sceneManager._previousScene == 1580)
+ loadScene(1550);
+ else
+ loadScene(1530);
+
+ R2_GLOBALS._v58CE2 = 0;
+ SceneExt::postInit();
+
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 1000) {
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(538, this);
+ R2_GLOBALS._sound1.play(114);
+
+ _sceneMode = 3;
+ } else if (R2_GLOBALS._sceneManager._previousScene == 1580) {
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ R2_GLOBALS._player.setObjectWrapper(NULL);
+ R2_GLOBALS._player.setup(1516, 6, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 125));
+ R2_GLOBALS._player._moveRate = 30;
+ R2_GLOBALS._player._moveDiff = Common::Point(4, 1);
+
+ _actor2.postInit();
+ _actor2.setup(1516, 7, 1);
+ _actor2.setPosition(Common::Point(121, 41));
+ _actor2.animate(ANIM_MODE_2, NULL);
+
+ _actor3.postInit();
+ _actor3.setup(1516, 8, 1);
+ _actor3.setPosition(Common::Point(107, 116));
+ _actor3.animate(ANIM_MODE_2, NULL);
+
+ R2_GLOBALS._player.disableControl();
+ Common::Point pt(480, 75);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ R2_GLOBALS._sound1.play(111);
+
+ _sceneMode = 1;
+ } else {
+ _actor1.postInit();
+ _actor1._effect = 1;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ setAction(&_sequenceManager, this, 1530, &R2_GLOBALS._player, &_actor1, NULL);
+
+ _sceneMode = 2;
+ }
+
+}
+
+void Scene1530::signal() {
+ switch (_sceneMode - 1) {
+ case 0:
+ R2_GLOBALS._sceneManager.changeScene(1000);
+ break;
+ case 1:
+ R2_GLOBALS._sceneManager.changeScene(1525);
+ break;
+ case 2:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 4;
+ R2_GLOBALS._player.show();
+ setAction(&_sequenceManager, this, 1650, &R2_GLOBALS._player, NULL);
+ break;
+ case 3:
+ R2_GLOBALS._sceneManager.changeScene(1700);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1530::dispatch() {
+ int16 x = R2_GLOBALS._player._position.x;
+ int16 y = R2_GLOBALS._player._position.y;
+
+ _actor2.setPosition(Common::Point(x - 39, y - 85));
+ _actor3.setPosition(Common::Point(x - 53, y - 9));
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1550 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1550::UnkObj15501::UnkObj15501() {
+ _fieldA4 = _fieldA6 = 0;
+}
+
+void Scene1550::UnkObj15501::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_fieldA6);
+}
+
+bool Scene1550::UnkObj15501::startAction(CursorType action, Event &event) {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (_visage == 1561) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 40;
+ Common::Point pt(_position.x + 5, _position.y + 20);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case CURSOR_LOOK:
+ if (_visage == 1561) {
+ switch (_frame) {
+ case 2:
+ SceneItem::display(1550, 23, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 3:
+ SceneItem::display(1550, 26, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 4:
+ SceneItem::display(1550, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch ((((_strip - 1) * 5) + _frame) % 3) {
+ case 0:
+ SceneItem::display(1550, 62, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 1:
+ SceneItem::display(1550, 53, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 2:
+ SceneItem::display(1550, 76, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+}
+
+Scene1550::UnkObj15502::UnkObj15502() {
+ _fieldA4 = 0;
+}
+
+void Scene1550::UnkObj15502::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+}
+
+bool Scene1550::UnkObj15502::startAction(CursorType action, Event &event) {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (_fieldA4 == 8) {
+ scene->_field412 = 1;
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1576;
+ else
+ scene->_sceneMode = 1584;
+ // strcpy(scene->_arrUnkObj15502[7]._actorName, 'hatch');
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[7], NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case CURSOR_LOOK:
+ if (_fieldA4 == 8)
+ SceneItem::display(1550, 75, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ else if (_frame == 1)
+ SceneItem::display(1550, 70, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ else
+ SceneItem::display(1550, 71, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ break;
+ case R2_17:
+ scene->_field412 = 1;
+ if (_fieldA4 == 6) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1574;
+ else
+ scene->_sceneMode = 1582;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[5], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_18:
+ scene->_field412 = 1;
+ if (_fieldA4 == 3) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1571;
+ else
+ scene->_sceneMode = 1581;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[2], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_22:
+ scene->_field412 = 1;
+ if (_fieldA4 == 1) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1569;
+ else
+ scene->_sceneMode = 1579;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[0], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_23:
+ scene->_field412 = 1;
+ if (_fieldA4 == 4) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1572;
+ scene->_actor1.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[3], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_25:
+ scene->_field412 = 1;
+ if (_fieldA4 == 2) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1570;
+ else
+ scene->_sceneMode = 1580;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[1], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_27:
+ scene->_field412 = 1;
+ if (_fieldA4 == 5) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1573;
+ scene->_actor1.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[4], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_45:
+ scene->_field412 = 1;
+ if (_fieldA4 == 7) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1575;
+ else
+ scene->_sceneMode = 1583;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[6], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+}
+
+Scene1550::UnkObj15503::UnkObj15503() {
+ _fieldA4 = 0;
+}
+
+void Scene1550::UnkObj15503::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+}
+
+bool Scene1550::UnkObj15503::startAction(CursorType action, Event &event) {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+ switch (_fieldA4) {
+ case 1:
+ if (scene->_actor13._frame == 5) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 25;
+ if (scene->_actor4._frame == 1) {
+ scene->setAction(&scene->_sequenceManager1, scene, 1560, &scene->_actor4, NULL);
+ R2_GLOBALS.setFlag(20);
+ setFrame(2);
+ } else {
+ scene->setAction(&scene->_sequenceManager1, scene, 1561, &scene->_actor4, NULL);
+ R2_GLOBALS.clearFlag(20);
+ setFrame(1);
+ }
+ scene->_unkArea1.remove();
+ }
+ break;
+ case 2:
+ R2_GLOBALS._player.disableControl();
+ if (scene->_actor13._frame == 1) {
+ scene->_sceneMode = 23;
+ scene->setAction(&scene->_sequenceManager1, scene, 1560, this, NULL);
+ } else {
+ if (scene->_actor4._frame == 1)
+ scene->_sceneMode = 24;
+ else
+ scene->_sceneMode = 22;
+ scene->setAction(&scene->_sequenceManager1, scene, 1561, this, NULL);
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+void Scene1550::UnkArea1550::remove() {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ _unkObj155031.remove();
+ _unkObj155032.remove();
+ // sub201EA is a common part with UnkArea1200
+ R2_GLOBALS._sceneItems.remove((SceneItem *)this);
+ _areaActor.remove();
+ SceneArea::remove();
+ R2_GLOBALS._insetUp--;
+ //
+ if ((scene->_sceneMode >= 20) and (scene->_sceneMode <= 29))
+ return;
+
+ R2_GLOBALS._player.disableControl();
+ if (scene->_actor4._frame == 1) {
+ scene->_sceneMode = 1559;
+ scene->setAction(&scene->_sequenceManager1, scene, 1559, &R2_GLOBALS._player, NULL);
+ } else {
+ scene->_sceneMode = 1562;
+ scene->setAction(&scene->_sequenceManager1, scene, 1562, &R2_GLOBALS._player, NULL);
+ }
+}
+void Scene1550::UnkArea1550::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+ warning("Scene1550::UnkArea1550::proc12() should be based on Scene1550::UnkArea1200::proc12()");
+}
+
+bool Scene1550::Hotspot1::startAction(CursorType action, Event &event) {
+ return SceneHotspot::startAction(action, event);
+}
+
+bool Scene1550::Hotspot3::startAction(CursorType action, Event &event) {
+ // Arrays related to this scene are all hacky in the origina: they are based on the impossibility to use Miranda
+ assert ((R2_GLOBALS._player._characterIndex == 1) || (R2_GLOBALS._player._characterIndex == 2));
+ // The original contains a debug message when CURSOR_TALK is used.
+ if (action == CURSOR_TALK)
+ warning("Location: %d/%d - %d", R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex], R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2], _v5A4D6[(R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] * 30)] + R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]);
+
+ return SceneHotspot::startAction(action, event);
+}
+
+bool Scene1550::Actor6::startAction(CursorType action, Event &event) {
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene1550::Actor7::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+ scene->_sceneMode = 80;
+ scene->signal();
+
+ return true;
+}
+
+bool Scene1550::Actor8::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+ scene->_field412 = 1;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1552;
+ else
+ scene->_sceneMode = 1588;
+
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor8, NULL);
+ return true;
+}
+
+bool Scene1550::Actor9::startAction(CursorType action, Event &event) {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ scene->_sceneMode = 50;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_stripManager.start(518, scene);
+ else
+ scene->_stripManager.start(520, scene);
+ return true;
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display(1550, 41, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene1550::Actor10::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1555;
+ else
+ scene->_sceneMode = 1589;
+
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor10, NULL);
+ return true;
+}
+
+bool Scene1550::Actor11::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+ R2_GLOBALS._player.disableControl();
+ scene->_field412 = 1;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1586;
+ else
+ scene->_sceneMode = 1587;
+
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor11, NULL);
+ return true;
+}
+
+bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1585;
+ scene->setAction(&scene->_sequenceManager1, scene, 1585, &R2_GLOBALS._player, NULL);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ switch(scene->_field415) {
+ case 0:
+ scene->_actor13.fixPriority(168);
+ scene->_actor4.fixPriority(125);
+ scene->_sceneMode = 1558;
+ scene->setAction(&scene->_sequenceManager1, scene, 1558, &R2_GLOBALS._player, NULL);
+ break;
+ case 1:
+ return SceneActor::startAction(action, event);
+ break;
+ case 2:
+ scene->_field415 = 1;
+ scene->_sceneMode = 1563;
+ scene->setAction(&scene->_sequenceManager1, scene, 1563, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+
+}
+
+bool Scene1550::Actor13::startAction(CursorType action, Event &event) {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (scene->_field415 != 2)
+ return SceneActor::startAction(action, event);
+
+ if (R2_INVENTORY.getObjectScene(R2_45) == 1550) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1564;
+ scene->setAction(&scene->_sequenceManager1, scene, 1564, &R2_GLOBALS._player, NULL);
+ } else
+ SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ break;
+ case CURSOR_LOOK:
+ if (scene->_field415 != 2)
+ return SceneActor::startAction(action, event);
+
+ if (R2_INVENTORY.getObjectScene(R2_45) == 1550) {
+ SceneItem::display(1550, 74, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ } else
+ SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+}
+
+Scene1550::Scene1550() {
+ _field412 = 0;
+ _field414 = 0;
+ _field415 = 0;
+ _field417 = 0;
+ _field419 = 0;
+}
+
+void Scene1550::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsByte(_field414);
+ s.syncAsSint16LE(_field415);
+ s.syncAsSint16LE(_field417);
+ s.syncAsSint16LE(_field419);
+}
+
+void Scene1550::postInit(SceneObjectList *OwnerList) {
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11))
+ loadScene(1234);
+ else
+ loadScene(1550);
+
+ scalePalette(65, 65, 65);
+ setZoomPercents(30, 75, 170, 100);
+ _field417 = 1550;
+ _field419 = 0;
+ SceneExt::postInit();
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
+ R2_GLOBALS.setFlag(R2_16);
+
+ if ((R2_GLOBALS._player._characterScene[1] != 1550) && (R2_GLOBALS._player._characterScene[1] != 1580)) {
+ R2_GLOBALS._player._characterScene[1] = 1550;
+ R2_GLOBALS._player._characterScene[2] = 1550;
+ }
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player._effect = 6;
+
+ if (R2_GLOBALS._player._characterIndex == 1)
+ R2_GLOBALS._player.setup(1500, 3, 1);
+ else
+ R2_GLOBALS._player.setup(1505, 3, 1);
+
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11))
+ R2_GLOBALS._player.setPosition(Common::Point(157, 135));
+ else
+ R2_GLOBALS._player.setPosition(Common::Point(160, 100));
+
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _field414 = 0;
+ _actor7.changeZoom(-1);
+ R2_GLOBALS._player.changeZoom(-1);
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 1530:
+ R2_GLOBALS._v565AE = 0;
+ // No break on purpose
+ case 300:
+ // No break on purpose
+ case 1500:
+ // No break on purpose
+ case 3150:
+ R2_GLOBALS._sound1.play(105);
+ break;
+ case 1580:
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1580) {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
+
+ _field412 = 1;
+
+ _actor1.postInit();
+ warning("_arrUnkObj15502[7].subA5CDF()");
+ _arrUnkObj15502[7].hide();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 1577;
+ else
+ _sceneMode = 1578;
+
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor1, &_arrUnkObj15502[7], NULL);
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1550;
+ } else {
+ R2_GLOBALS._player.enableControl();
+ }
+ break;
+ default:
+ break;
+ }
+ warning("subA2B2F();");
+ _item1.setDetails(16, 1550, 10, -1, -1);
+ _item2.setDetails(24, 1550, 10, -1, -1);
+ _item3.setDetails(Rect(0, 0, 320, 200), 1550, 0, 1, -1, 1, NULL);
+
+ if ((R2_GLOBALS._sceneManager._previousScene == 1500) && (R2_GLOBALS.getFlag(16))) {
+ _sceneMode = 70;
+ if (!R2_GLOBALS._sceneObjects->contains(&_actor7))
+ _actor7.postInit();
+
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _actor7.setVisage(1505);
+ else
+ _actor7.setVisage(1500);
+
+ _actor7.changeZoom(77);
+ _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+
+ warning("R2_GLOBALS._walkRegions.enableRegion(R2_GLOBALS._v14A72[_field419]);");
+ setAction(&_sequenceManager1, this, 1590, &_actor7, NULL);
+ } else if ((_sceneMode != 1577) && (_sceneMode != 1578))
+ R2_GLOBALS._player.enableControl();
+}
+
+void Scene1550::signal() {
+ switch (_sceneMode) {
+ case 1:
+ // No break on purpose
+ case 3:
+ // No break on purpose
+ case 5:
+ // No break on purpose
+ case 7:
+ _field412 = 0;
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ case 20:
+ // No break on purpose
+ case 21:
+ // No break on purpose
+ case 25:
+ // No break on purpose
+ case 1563:
+ R2_GLOBALS.clearFlag(20);
+ _unkArea1.proc12(1559, 1, 1, 160, 125);
+ R2_GLOBALS._player.enableControl();
+ _sceneMode = 0;
+ break;
+ case 22:
+ _unkArea1.remove();
+ _sceneMode = 24;
+ setAction(&_sequenceManager1, this, 1561, &_actor4, NULL);
+ R2_GLOBALS.clearFlag(20);
+ break;
+ case 23:
+ _unkArea1.remove();
+ _sceneMode = 20;
+ setAction(&_sequenceManager1, this, 1566, &_actor13, &_actor5, NULL);
+ R2_GLOBALS.setFlag(21);
+ break;
+ case 24:
+ _unkArea1.remove();
+ _sceneMode = 21;
+ setAction(&_sequenceManager1, this, 1567, &_actor13, &_actor5, NULL);
+ R2_GLOBALS.clearFlag(19);
+ break;
+ case 30:
+ // No break on purpose
+ case 1556:
+ // No break on purpose
+ case 1557:
+ // Nothing on purpose
+ break;
+ case 40: {
+ _sceneMode = 41;
+ Common::Point pt(_arrUnkObj15501[0]._position.x, _arrUnkObj15501[0]._position.y + 20);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 41:
+ _sceneMode = 42;
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setup(1502, 8, 1);
+ } else {
+ R2_GLOBALS._player.changeZoom(R2_GLOBALS._player._percent + 14);
+ R2_GLOBALS._player.setup(1516, 4, 1);
+ }
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 42:
+ _sceneMode = 43;
+ warning("TODO: unknown use of arrUnkObj15501[0]._fieldA6");
+ switch (_arrUnkObj15501[0]._frame - 1) {
+ case 0:
+ R2_INVENTORY.setObjectScene(26, R2_GLOBALS._player._characterIndex);
+ break;
+ case 1:
+ R2_INVENTORY.setObjectScene(17, R2_GLOBALS._player._characterIndex);
+ break;
+ case 2:
+ R2_INVENTORY.setObjectScene(22, R2_GLOBALS._player._characterIndex);
+ break;
+ case 3:
+ R2_INVENTORY.setObjectScene(25, R2_GLOBALS._player._characterIndex);
+ break;
+ case 4:
+ R2_INVENTORY.setObjectScene(45, R2_GLOBALS._player._characterIndex);
+ break;
+ case 5:
+ R2_INVENTORY.setObjectScene(28, R2_GLOBALS._player._characterIndex);
+ break;
+ default:
+ break;
+ }
+ _arrUnkObj15501[0].remove();
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 43:
+ warning("TODO: unknown use of arrUnkObj15501[0]._fieldA6");
+ if (R2_GLOBALS._player._characterIndex == 1)
+ R2_GLOBALS._player.setVisage(1500);
+ else {
+ R2_GLOBALS._player.changeZoom(-1);
+ R2_GLOBALS._player.setVisage(1505);
+ }
+ R2_GLOBALS._player.animate(ANIM_MODE_1, this);
+ R2_GLOBALS._player.setStrip(8);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 50:
+ warning("STUB: sub_1D227()");
+ ++_sceneMode;
+ setAction(&_sequenceManager1, this, 1591, &R2_GLOBALS._player, NULL);
+ if (g_globals->_sceneObjects->contains(&_actor7))
+ signal();
+ else {
+ _actor7.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _actor7.setVisage(1505);
+ else
+ _actor7.setVisage(1500);
+ _actor7.changeZoom(77);
+ _actor7.setAction(&_sequenceManager2, this, 1590, &_actor7, NULL);
+ _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ }
+ break;
+ case 51:
+ ++_sceneMode;
+ break;
+ case 52:
+ _actor7.changeZoom(-1);
+ _sceneMode = 1592;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ setAction(&_sequenceManager1, this, 1592, &R2_GLOBALS._player, &_actor7, &_arrUnkObj15501[0], &_actor9, NULL);
+ else
+ setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_actor7, &_arrUnkObj15501[0], &_actor9, NULL);
+ break;
+ case 61:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ _field415 = 2;
+ break;
+ case 62:
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ if (_field415 == 2) {
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ }
+ break;
+ case 70:
+ R2_GLOBALS._v565EC[2] = R2_GLOBALS._v565EC[1];
+ R2_GLOBALS._v565EC[4] = R2_GLOBALS._v565EC[3];
+ R2_GLOBALS._v565EC[0] = 1;
+ _sceneMode = 60;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(500, this);
+ break;
+ case 80:
+ if (R2_GLOBALS.getFlag(16)) {
+ _sceneMode = 60;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (R2_GLOBALS._v565AE >= 3) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _stripManager.start(572, this);
+ else
+ _stripManager.start(573, this);
+ } else {
+ ++R2_GLOBALS._v565AE;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _stripManager.start(499 + R2_GLOBALS._v565AE, this);
+ else
+ _stripManager.start(502 + R2_GLOBALS._v565AE, this);
+ }
+ } else {
+ _sceneMode = 60;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (R2_GLOBALS._v565AE >= 4) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _stripManager.start(572, this);
+ else
+ _stripManager.start(573, this);
+ } else {
+ ++R2_GLOBALS._v565AE;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _stripManager.start(563 + R2_GLOBALS._v565AE, this);
+ else
+ _stripManager.start(567 + R2_GLOBALS._v565AE, this);
+ }
+ }
+ break;
+ case 1550:
+ R2_GLOBALS._sceneManager.changeScene(1525);
+ break;
+ case 1552:
+ // No break on purpose
+ case 1588:
+ R2_INVENTORY.setObjectScene(R2_19, R2_GLOBALS._player._characterIndex);
+ _actor8.remove();
+ _field412 = 0;
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1553:
+ R2_GLOBALS._sceneManager.changeScene(1575);
+ break;
+ case 1554:
+ R2_GLOBALS._player.enableControl();
+ _field412 = 0;
+ break;
+ case 1555:
+ // No break on purpose
+ case 1589:
+ R2_INVENTORY.setObjectScene(R2_18, R2_GLOBALS._player._characterIndex);
+ _actor10.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1558:
+ _actor13.fixPriority(124);
+ _field415 = 1;
+ _unkArea1.proc12(1559, 1, 1, 160, 125);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1559:
+ _actor13.fixPriority(168);
+ _actor4.fixPriority(169);
+ R2_GLOBALS._player.fixPriority(-1);
+ R2_GLOBALS._player.changeZoom(-1);
+ _field415 = 0;
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1562:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field415 = 2;
+ break;
+ case 1564:
+ R2_INVENTORY.setObjectScene(R2_45, 1);
+ _sceneMode = 1565;
+ setAction(&_sequenceManager1, this, 1565, &R2_GLOBALS._player, NULL);
+ break;
+ case 1565:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 1569:
+ // No break on purpose
+ case 1579:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_22, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1570:
+ // No break on purpose
+ case 1580:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_25, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1571:
+ // No break on purpose
+ case 1581:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_18, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1572:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_23, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1573:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_27, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1574:
+ // No break on purpose
+ case 1582:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_17, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1575:
+ // No break on purpose
+ case 1583:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_45, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1576:
+ // No break on purpose
+ case 1584:
+ R2_GLOBALS._sceneManager.changeScene(1580);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1577:
+ // No break on purpose
+ case 1578:
+ _sceneMode = 0;
+ _actor1.remove();
+ _field412 = 0;
+ R2_GLOBALS._player.fixPriority(-1);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1585:
+ SceneItem::display(1550, 66, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1586:
+ // No break on purpose
+ case 1587:
+ R2_INVENTORY.setObjectScene(R2_28, R2_GLOBALS._player._characterIndex);
+ _actor1.remove();
+ _field412 = 0;
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1592:
+ _actor9.remove();
+ R2_INVENTORY.setObjectScene(R2_26, 1);
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._v565EC[2] = R2_GLOBALS._v565EC[1];
+ R2_GLOBALS._v565EC[4] = R2_GLOBALS._v565EC[3];
+ } else {
+ R2_GLOBALS._v565EC[1] = R2_GLOBALS._v565EC[2];
+ R2_GLOBALS._v565EC[3] = R2_GLOBALS._v565EC[4];
+ }
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ _sceneMode = 62;
+ setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ }
+}
+
+void Scene1550::process(Event &event) {
+ if ((!R2_GLOBALS._player._canWalk) && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN) && (event.eventType == EVENT_BUTTON_DOWN) && (this->_screenNumber == 1234)) {
+ int curReg = R2_GLOBALS._sceneRegions.indexOf(event.mousePos);
+ if (curReg == 0)
+ _field412 = 1;
+ else if (((R2_GLOBALS._player._position.y < 90) && (event.mousePos.y > 90)) || ((R2_GLOBALS._player._position.y > 90) && (event.mousePos.y < 90)))
+ _field412 = 1;
+ else
+ _field412 = 0;
+
+ if ((curReg == 13) || (curReg == 14))
+ _field412 = 0;
+ }
+
+ Scene::process(event);
+}
+
+void Scene1550::dispatch() {
+ Scene::dispatch();
+
+ // Arrays related to this scene are all hacky in the origina: they are based on the impossibility to use Miranda
+ assert ((R2_GLOBALS._player._characterIndex == 1) || (R2_GLOBALS._player._characterIndex == 2));
+
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 15) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 16)) {
+ R2_GLOBALS._player._shade = 0;
+ // Original game contains a switch based on an uninitialised variable.
+ // Until we understand what should really happen there, this code is unused on purpose
+ int missingVariable = 0;
+ switch (missingVariable) {
+ case 144:
+ // No break on purpose
+ case 146:
+ _actor13._frame = 5;
+ R2_GLOBALS._player._shade = 3;
+ break;
+ case 148:
+ // No break on purpose
+ case 149:
+ _actor13._frame = 1;
+ // No break on purpose
+ case 147:
+ // No break on purpose
+ case 150:
+ R2_GLOBALS._player._shade = 3;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (_field412 != 0)
+ return;
+
+ switch (R2_GLOBALS._player.getRegionIndex() - 11) {
+ case 0:
+ // No break on purpose
+ case 5:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1;
+ _field412 = 1;
+ --R2_GLOBALS._v565EC[2 + R2_GLOBALS._player._characterIndex];
+ warning("subA2B2F();");
+ R2_GLOBALS._player.setPosition(Common::Point( 160 - (((((160 - R2_GLOBALS._player._position.x) * 100) / 108) * 172) / 100), 145));
+ if (R2_GLOBALS._player._position.x < 160) {
+ Common::Point pt(R2_GLOBALS._player._position.x + 5, 135);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if (R2_GLOBALS._player._position.x <= 160) { // the check is really in the original...
+ Common::Point pt(R2_GLOBALS._player._position.x, 135);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ Common::Point pt(R2_GLOBALS._player._position.x - 5, 135);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 1:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 3;
+ _field412 = 1;
+ ++R2_GLOBALS._v565EC[2 + R2_GLOBALS._player._characterIndex];
+ warning("subA2B2F();");
+ R2_GLOBALS._player.setPosition(Common::Point( 160 - (((((160 - R2_GLOBALS._player._position.x) * 100) / 172) * 108) / 100), 19));
+ if (R2_GLOBALS._player._position.x < 160) {
+ Common::Point pt(R2_GLOBALS._player._position.x + 5, 29);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if (R2_GLOBALS._player._position.x <= 160) { // the check is really in the original...
+ Common::Point pt(R2_GLOBALS._player._position.x, 29);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ Common::Point pt(R2_GLOBALS._player._position.x - 5, 29);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 2:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 5;
+ _field412 = 1;
+ ++R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex];
+ warning("subA2B2F();");
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
+ if (R2_GLOBALS._player._position.y >= 85) {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 10));
+ Common::Point pt(R2_GLOBALS._player._position.x + 30, R2_GLOBALS._player._position.y + 20);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y - 10));
+ Common::Point pt(R2_GLOBALS._player._position.x + 30, R2_GLOBALS._player._position.y - 20);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y));
+ Common::Point pt(R2_GLOBALS._player._position.x + 10, R2_GLOBALS._player._position.y);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 7;
+ _field412 = 1;
+ --R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex];
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 24) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11)) {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y / 2));
+ Common::Point pt(265, 29);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
+ if (R2_GLOBALS._player._position.y >= 85) {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 10));
+ Common::Point pt(R2_GLOBALS._player._position.x - 30, R2_GLOBALS._player._position.y + 20);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y - 10));
+ Common::Point pt(R2_GLOBALS._player._position.x - 30, R2_GLOBALS._player._position.y - 20);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y));
+ Common::Point pt(R2_GLOBALS._player._position.x - 10, R2_GLOBALS._player._position.y);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1550::saveCharacter(int characterIndex) {
+ if (R2_GLOBALS._player._characterIndex == 3)
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+
+ SceneExt::saveCharacter(characterIndex);
+}
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.h b/engines/tsage/ringworld2/ringworld2_scenes1.h
index a21869b6ad..6d2bd3b084 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.h
@@ -59,15 +59,15 @@ public:
class Scene1100 : public SceneExt {
class Actor16 : public SceneActor {
public:
- bool startAction(CursorType action, Event &event);
+ virtual bool startAction(CursorType action, Event &event);
};
class Actor17 : public SceneActor {
public:
- bool startAction(CursorType action, Event &event);
+ virtual bool startAction(CursorType action, Event &event);
};
class Actor18 : public SceneActor {
public:
- bool startAction(CursorType action, Event &event);
+ virtual bool startAction(CursorType action, Event &event);
};
public:
@@ -117,6 +117,259 @@ public:
virtual void saveCharacter(int characterIndex);
};
+class Scene1200 : public SceneExt {
+ class Area1: public SceneArea {
+ public:
+ class Actor3 : public SceneActorExt {
+ public:
+ void init(int state);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ SceneActor _actor2;
+ Actor3 _actor3;
+ Actor3 _actor4;
+ Actor3 _actor5;
+
+ byte _field20;
+
+ Area1();
+ void synchronize(Serializer &s);
+
+ virtual void postInit();
+ virtual void remove();
+ virtual void process(Event &event);
+ virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
+ virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
+ };
+
+ class Object1 : public SavedObject {
+ public:
+ Rect _rect1;
+ Rect _rect2;
+
+ int _field16;
+ int _field26;
+ int _field28;
+ int _field2A;
+ int _field2C;
+ int _field2E;
+ int _field30;
+
+ Object1();
+ void synchronize(Serializer &s);
+
+ int sub51AF8(Common::Point pt);
+ bool sub51AFD(Common::Point pt);
+ void sub9EDE8(Rect rect);
+ virtual Common::String getClassName() { return "UnkObject1200"; }
+ };
+
+public:
+ NamedHotspot _item1;
+ SceneActor _actor1;
+ Area1 _area1;
+ Object1 _object1;
+ SequenceManager _sequenceManager;
+
+ int _field412;
+ int _field414;
+ int _field416;
+ int _field418;
+ int _field41A;
+ int _field41C;
+
+ Scene1200();
+ void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void saveCharacter(int characterIndex);
+};
+
+class Scene1500 : public SceneExt {
+public:
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene1525 : public SceneExt {
+public:
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene1530 : public SceneExt {
+public:
+ SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker _seekerSpeaker;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene1550 : public SceneExt {
+ class UnkObj15501 : public SceneActor {
+ public:
+ int _fieldA4;
+ int _fieldA6;
+
+ UnkObj15501();
+ void synchronize(Serializer &s);
+
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class UnkObj15502 : public SceneActor {
+ public:
+ int _fieldA4;
+
+ UnkObj15502();
+ void synchronize(Serializer &s);
+
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class UnkObj15503 : public SceneActor {
+ public:
+ int _fieldA4;
+
+ UnkObj15503();
+ void synchronize(Serializer &s);
+
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class UnkArea1550 : public SceneArea {
+ public:
+ byte _field20;
+ SceneActor _areaActor;
+ UnkObj15503 _unkObj155031;
+ UnkObj15503 _unkObj155032;
+
+ virtual void remove();
+ virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
+ };
+
+ class Hotspot1 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Hotspot3 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor6 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor7 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor8 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor9 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor10 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor11 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor12 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor13 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor14 : public SceneActor {
+ // Nothing specific found in the original
+ // TODO: check if it's an useless class
+ };
+
+public:
+ SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker _seekerSpeaker;
+ Hotspot1 _item1;
+ Hotspot1 _item2;
+ Hotspot3 _item3;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ Actor6 _actor6;
+ Actor7 _actor7;
+ Actor8 _actor8;
+ Actor9 _actor9;
+ Actor10 _actor10;
+ Actor11 _actor11;
+ Actor12 _actor12;
+ Actor13 _actor13;
+ UnkObj15501 _arrUnkObj15501[8];
+ Actor14 _actor14;
+ Actor14 _actor15;
+ Actor14 _actor16;
+ Actor14 _actor17;
+ Actor14 _actor18;
+ Actor14 _actor19;
+ UnkObj15502 _arrUnkObj15502[8];
+ UnkArea1550 _unkArea1;
+ SequenceManager _sequenceManager1;
+ SequenceManager _sequenceManager2;
+
+ int _field412;
+ byte _field414;
+ int _field415;
+ int _field417;
+ int _field419;
+
+ Scene1550();
+ void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void saveCharacter(int characterIndex);
+};
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp
index cc93c4f35f..1251b6d262 100644
--- a/engines/tsage/staticres.cpp
+++ b/engines/tsage/staticres.cpp
@@ -237,6 +237,29 @@ char const *const F7 = "F7";
char const *const F8 = "F8";
char const *const F10 = "F10";
+const byte _v5A4D6[] = {
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 16, 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, 18,
+ 17, 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, 19,
+ 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 11, 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, 12,
+ 13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14
+};
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h
index 5b6f4393c4..ae2aa28aeb 100644
--- a/engines/tsage/staticres.h
+++ b/engines/tsage/staticres.h
@@ -190,6 +190,9 @@ extern char const *const F7;
extern char const *const F8;
extern char const *const F10;
+// Scene 1550 map
+extern const byte _v5A4D6[];
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/gui/browser_osx.mm b/gui/browser_osx.mm
index 017b31b9a8..b8aa7c50ee 100644
--- a/gui/browser_osx.mm
+++ b/gui/browser_osx.mm
@@ -62,11 +62,7 @@ int BrowserDialog::runModal() {
NSOpenPanel * panel = [NSOpenPanel openPanel];
[panel setCanChooseDirectories:YES];
if ([panel runModalForTypes:nil] == NSOKButton) {
-#ifdef __POWERPC__
- const char *filename = [[panel filename] cString];
-#else
- const char *filename = [[panel filename] cStringUsingEncoding:NSUTF8StringEncoding];
-#endif
+ const char *filename = [[panel filename] UTF8String];
_choice = Common::FSNode(filename);
choiceMade = true;
}
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index cba92201d3..867cf91c5b 100644
--- a/gui/themes/scummmodern.zip
+++ b/gui/themes/scummmodern.zip
Binary files differ
diff --git a/gui/themes/scummmodern/eraser.bmp b/gui/themes/scummmodern/eraser.bmp
index 782b13dc62..b927a6384f 100644
--- a/gui/themes/scummmodern/eraser.bmp
+++ b/gui/themes/scummmodern/eraser.bmp
Binary files differ
diff --git a/ports.mk b/ports.mk
index 5f63d560ef..82239f458d 100644
--- a/ports.mk
+++ b/ports.mk
@@ -110,7 +110,7 @@ OSX_STATIC_LIBS += $(STATICLIBPATH)/lib/libfaad.a
endif
ifdef USE_ZLIB
-OSX_ZLIB ?= -lz
+OSX_ZLIB ?= $(STATICLIBPATH)/lib/libz.a
endif
ifdef USE_SPARKLE
@@ -165,10 +165,10 @@ osxsnap: bundle
mkdir ScummVM-snapshot/doc/it
cp $(srcdir)/doc/it/GuidaRapida ./ScummVM-snapshot/doc/it/GuidaRapida
mkdir ScummVM-snapshot/doc/no-nb
- cp $(srcdir)doc/no-nb/HurtigStart ./ScummVM-snapshot/doc/no-nb/HurtigStart
+ cp $(srcdir)/doc/no-nb/HurtigStart ./ScummVM-snapshot/doc/no-nb/HurtigStart
mkdir ScummVM-snapshot/doc/se
- cp $(srcdir)doc/se/LasMig ./ScummVM-snapshot/doc/se/LasMig
- cp $(srcdir)doc/se/Snabbstart ./ScummVM-snapshot/doc/se/Snabbstart
+ cp $(srcdir)/doc/se/LasMig ./ScummVM-snapshot/doc/se/LasMig
+ cp $(srcdir)/doc/se/Snabbstart ./ScummVM-snapshot/doc/se/Snabbstart
/Developer/Tools/SetFile -t ttro -c ttxt ./ScummVM-snapshot/*
xattr -w "com.apple.TextEncoding" "utf-8;134217984" ./ScummVM-snapshot/doc/cz/*
xattr -w "com.apple.TextEncoding" "utf-8;134217984" ./ScummVM-snapshot/doc/de/*
diff --git a/video/bink_decoder.cpp b/video/bink_decoder.cpp
index 46ac8ac386..c5dc5f280b 100644
--- a/video/bink_decoder.cpp
+++ b/video/bink_decoder.cpp
@@ -113,23 +113,33 @@ BinkDecoder::BinkDecoder() {
}
_audioStream = 0;
- _audioStarted = false;
}
-BinkDecoder::~BinkDecoder() {
- close();
-}
+void BinkDecoder::startAudio() {
+ if (_audioTrack < _audioTracks.size()) {
+ const AudioTrack &audio = _audioTracks[_audioTrack];
-void BinkDecoder::close() {
- reset();
+ _audioStream = Audio::makeQueuingAudioStream(audio.outSampleRate, audio.outChannels == 2);
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream);
+ } // else no audio
+}
+void BinkDecoder::stopAudio() {
if (_audioStream) {
- // Stop audio
g_system->getMixer()->stopHandle(_audioHandle);
_audioStream = 0;
}
+}
+
+BinkDecoder::~BinkDecoder() {
+ close();
+}
- _audioStarted = false;
+void BinkDecoder::close() {
+ reset();
+
+ // Stop audio
+ stopAudio();
for (int i = 0; i < 4; i++) {
delete[] _curPlanes[i]; _curPlanes[i] = 0;
@@ -173,7 +183,7 @@ void BinkDecoder::close() {
uint32 BinkDecoder::getElapsedTime() const {
if (_audioStream && g_system->getMixer()->isSoundHandleActive(_audioHandle))
- return g_system->getMixer()->getSoundElapsedTime(_audioHandle);
+ return g_system->getMixer()->getSoundElapsedTime(_audioHandle) + _audioStartOffset;
return g_system->getMillis() - _startTime;
}
@@ -241,11 +251,6 @@ const Graphics::Surface *BinkDecoder::decodeNextFrame() {
if (_curFrame == 0)
_startTime = g_system->getMillis();
- if (!_audioStarted && _audioStream) {
- _audioStarted = true;
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream);
- }
-
return &_surface;
}
@@ -510,6 +515,11 @@ void BinkDecoder::mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *
}
bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
+ Graphics::PixelFormat format = g_system->getScreenFormat();
+ return loadStream(stream, format);
+}
+
+bool BinkDecoder::loadStream(Common::SeekableReadStream *stream, const Graphics::PixelFormat &format) {
close();
_id = stream->readUint32BE();
@@ -589,7 +599,6 @@ bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
_hasAlpha = _videoFlags & kVideoFlagAlpha;
_swapPlanes = (_id == kBIKhID) || (_id == kBIKiID); // BIKh and BIKi swap the chroma planes
- Graphics::PixelFormat format = g_system->getScreenFormat();
_surface.create(width, height, format);
// Give the planes a bit extra space
@@ -618,11 +627,8 @@ bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
initBundles();
initHuffman();
- if (_audioTrack < _audioTracks.size()) {
- const AudioTrack &audio = _audioTracks[_audioTrack];
-
- _audioStream = Audio::makeQueuingAudioStream(audio.outSampleRate, audio.outChannels == 2);
- }
+ startAudio();
+ _audioStartOffset = 0;
return true;
}
diff --git a/video/bink_decoder.h b/video/bink_decoder.h
index dd1b7ca67d..3d5e882dd7 100644
--- a/video/bink_decoder.h
+++ b/video/bink_decoder.h
@@ -76,7 +76,9 @@ public:
// FixedRateVideoDecoder
Common::Rational getFrameRate() const { return _frameRate; }
-private:
+ // Bink specific
+ bool loadStream(Common::SeekableReadStream *stream, const Graphics::PixelFormat &format);
+protected:
static const int kAudioChannelsMax = 2;
static const int kAudioBlockSizeMax = (kAudioChannelsMax << 11);
@@ -221,15 +223,13 @@ private:
Audio::SoundHandle _audioHandle;
Audio::QueuingAudioStream *_audioStream;
- bool _audioStarted;
+ int32 _audioStartOffset;
uint32 _videoFlags; ///< Video frame features.
bool _hasAlpha; ///< Do video frames have alpha?
bool _swapPlanes; ///< Are the planes ordered (A)YVU instead of (A)YUV?
- uint32 _audioFrame;
-
Common::Array<AudioTrack> _audioTracks; ///< All audio tracks.
Common::Array<VideoFrame> _frames; ///< All video frames.
@@ -259,7 +259,7 @@ private:
/** Decode an audio packet. */
void audioPacket(AudioTrack &audio);
/** Decode a video packet. */
- void videoPacket(VideoFrame &video);
+ virtual void videoPacket(VideoFrame &video);
/** Decode a plane. */
void decodePlane(VideoFrame &video, int planeIdx, bool isChroma);
@@ -327,6 +327,11 @@ private:
void IDCT(int16 *block);
void IDCTPut(DecodeContext &ctx, int16 *block);
void IDCTAdd(DecodeContext &ctx, int16 *block);
+
+ /** Start playing the audio track */
+ void startAudio();
+ /** Stop playing the audio track */
+ void stopAudio();
};
} // End of namespace Video