aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMatthew Hoops2012-05-04 23:32:29 -0400
committerMatthew Hoops2012-05-04 23:32:29 -0400
commite80d622fa5b3a834faff22ac777838388c0cdf10 (patch)
treef19d5a4b8725796a8bad28dad9b29c7313e5c2ff /engines
parent68438a2919df2756942193d9b1b77496828fd45a (diff)
parente5808c740a62cb87a1ceeef7873af3b21e912c73 (diff)
downloadscummvm-rg350-e80d622fa5b3a834faff22ac777838388c0cdf10.tar.gz
scummvm-rg350-e80d622fa5b3a834faff22ac777838388c0cdf10.tar.bz2
scummvm-rg350-e80d622fa5b3a834faff22ac777838388c0cdf10.zip
Merge remote branch 'upstream/master' into pegasus
Diffstat (limited to 'engines')
-rw-r--r--engines/agi/saveload.cpp3
-rw-r--r--engines/configure.engines4
-rw-r--r--engines/cruise/cruise_main.cpp107
-rw-r--r--engines/dreamweb/detection_tables.h16
-rw-r--r--engines/dreamweb/dreamweb.cpp20
-rw-r--r--engines/dreamweb/module.mk1
-rw-r--r--engines/dreamweb/mouse.cpp171
-rw-r--r--engines/dreamweb/stubs.cpp142
-rw-r--r--engines/kyra/screen.cpp19
-rw-r--r--engines/sci/detection_tables.h13
-rw-r--r--engines/sci/engine/features.cpp3
-rw-r--r--engines/sci/engine/features.h7
-rw-r--r--engines/sci/graphics/cursor.cpp8
-rw-r--r--engines/sci/sound/music.cpp6
-rw-r--r--engines/scumm/detection.cpp10
-rw-r--r--engines/scumm/scumm-md5.h3
-rw-r--r--engines/sword25/script/luabindhelper.cpp2
-rw-r--r--engines/tinsel/detection_tables.h2
-rw-r--r--engines/tinsel/music.cpp94
-rw-r--r--engines/tinsel/music.h6
-rw-r--r--engines/tinsel/tinlib.cpp2
21 files changed, 389 insertions, 250 deletions
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index 8e524c8d9a..d58e55a6b9 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -831,6 +831,9 @@ int AgiEngine::scummVMSaveLoadDialog(bool isSave) {
delete dialog;
+ if (slot < 0)
+ return true;
+
if (isSave)
return doSave(slot, desc);
else
diff --git a/engines/configure.engines b/engines/configure.engines
index 93c349378d..91e5e82506 100644
--- a/engines/configure.engines
+++ b/engines/configure.engines
@@ -7,11 +7,11 @@ add_engine agos "AGOS" yes "agos2"
add_engine agos2 "AGOS 2 games" yes
add_engine cge "CGE" yes
add_engine cine "Cinematique evo 1" yes
-add_engine composer "Magic Composer" no
+add_engine composer "Magic Composer" yes
add_engine cruise "Cinematique evo 2" yes
add_engine draci "Dragon History" yes
add_engine drascula "Drascula: The Vampire Strikes Back" yes
-add_engine dreamweb "Dreamweb" no
+add_engine dreamweb "Dreamweb" yes
add_engine gob "Gobli*ns" yes
add_engine groovie "Groovie" yes "groovie2"
add_engine groovie2 "Groovie 2 games" no
diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp
index 6e2847d6d7..911041c1a4 100644
--- a/engines/cruise/cruise_main.cpp
+++ b/engines/cruise/cruise_main.cpp
@@ -1799,32 +1799,60 @@ void CruiseEngine::mainLoop() {
// Handle frame delay
uint32 currentTick = g_system->getMillis();
- if (!bFastMode) {
- // Delay for the specified amount of time, but still respond to events
- bool skipEvents = false;
+ // Delay for the specified amount of time, but still respond to events
+ bool skipEvents = false;
- do {
- g_system->updateScreen();
+ do {
+ if (userEnabled && !userWait && !autoTrack) {
+ if (currentActiveMenu == -1) {
+ static int16 oldMouseX = -1;
+ static int16 oldMouseY = -1;
- g_system->delayMillis(10);
- currentTick = g_system->getMillis();
+ getMouseStatus(&main10, &mouseX, &mouseButton, &mouseY);
- if (!skipEvents)
- skipEvents = manageEvents();
+ if (mouseX != oldMouseX || mouseY != oldMouseY) {
+ int objectType;
+ int newCursor1;
+ int newCursor2;
- if (playerDontAskQuit)
- break;
+ oldMouseX = mouseX;
+ oldMouseY = mouseY;
- _vm->getDebugger()->onFrame();
- } while (currentTick < lastTick + _gameSpeed);
- } else {
- manageEvents();
+ objectType = findObject(mouseX, mouseY, &newCursor1, &newCursor2);
- if (currentTick >= (lastTickDebug + 10)) {
- lastTickDebug = currentTick;
- _vm->getDebugger()->onFrame();
+ if (objectType == 9) {
+ changeCursor(CURSOR_EXIT);
+ } else if (objectType != -1) {
+ changeCursor(CURSOR_MAGNIFYING_GLASS);
+ } else {
+ changeCursor(CURSOR_WALK);
+ }
+ }
+ } else {
+ changeCursor(CURSOR_NORMAL);
+ }
+ } else {
+ changeCursor(CURSOR_NORMAL);
}
- }
+
+ g_system->updateScreen();
+
+ if (!skipEvents || bFastMode)
+ skipEvents = manageEvents();
+
+ if (bFastMode) {
+ if (currentTick >= (lastTickDebug + 10))
+ lastTickDebug = currentTick;
+ } else {
+ g_system->delayMillis(10);
+ currentTick = g_system->getMillis();
+ }
+
+ if (playerDontAskQuit)
+ break;
+
+ _vm->getDebugger()->onFrame();
+ } while (currentTick < lastTick + _gameSpeed && !bFastMode);
if (playerDontAskQuit)
break;
@@ -1844,6 +1872,14 @@ void CruiseEngine::mainLoop() {
// readKeyboard();
bool isUserWait = userWait != 0;
+ // WORKAROUND: This prevents hotspots responding during
+ // delays i.e. Menu opening if you click fast on another
+ // hotspot after trying to open a locked door, which
+ // occurred with the original interpreter.
+ if (userDelay) {
+ currentMouseButton = 0;
+ }
+
playerDontAskQuit = processInput();
if (playerDontAskQuit)
break;
@@ -1855,7 +1891,6 @@ void CruiseEngine::mainLoop() {
if (userDelay && !userWait) {
userDelay--;
- continue;
}
if (isUserWait & !userWait) {
@@ -1918,38 +1953,6 @@ void CruiseEngine::mainLoop() {
mainDraw(userWait);
flipScreen();
- if (userEnabled && !userWait && !autoTrack) {
- if (currentActiveMenu == -1) {
- static int16 oldMouseX = -1;
- static int16 oldMouseY = -1;
-
- getMouseStatus(&main10, &mouseX, &mouseButton, &mouseY);
-
- if (mouseX != oldMouseX || mouseY != oldMouseY) {
- int objectType;
- int newCursor1;
- int newCursor2;
-
- oldMouseX = mouseX;
- oldMouseY = mouseY;
-
- objectType = findObject(mouseX, mouseY, &newCursor1, &newCursor2);
-
- if (objectType == 9) {
- changeCursor(CURSOR_EXIT);
- } else if (objectType != -1) {
- changeCursor(CURSOR_MAGNIFYING_GLASS);
- } else {
- changeCursor(CURSOR_WALK);
- }
- }
- } else {
- changeCursor(CURSOR_NORMAL);
- }
- } else {
- changeCursor(CURSOR_NORMAL);
- }
-
if (userWait == 1) {
// Waiting for press - original wait loop has been integrated into the
// main event loop
diff --git a/engines/dreamweb/detection_tables.h b/engines/dreamweb/detection_tables.h
index 8ca24d1724..d54b2402c8 100644
--- a/engines/dreamweb/detection_tables.h
+++ b/engines/dreamweb/detection_tables.h
@@ -45,7 +45,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_UNSTABLE,
+ ADGF_TESTING,
GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_BRIGHTPALETTE)
},
},
@@ -62,7 +62,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_CD | ADGF_UNSTABLE,
+ ADGF_CD | ADGF_TESTING,
GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_BRIGHTPALETTE)
},
},
@@ -96,7 +96,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
},
Common::FR_FRA,
Common::kPlatformPC,
- ADGF_CD | ADGF_UNSTABLE,
+ ADGF_CD | ADGF_TESTING,
GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_BRIGHTPALETTE)
},
},
@@ -113,7 +113,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_UNSTABLE,
+ ADGF_TESTING,
GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_BRIGHTPALETTE)
},
},
@@ -130,7 +130,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_CD | ADGF_UNSTABLE,
+ ADGF_CD | ADGF_TESTING,
GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_BRIGHTPALETTE)
},
},
@@ -147,7 +147,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
},
Common::ES_ESP,
Common::kPlatformPC,
- ADGF_UNSTABLE,
+ ADGF_TESTING,
GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_BRIGHTPALETTE)
},
},
@@ -164,7 +164,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
},
Common::ES_ESP,
Common::kPlatformPC,
- ADGF_CD | ADGF_UNSTABLE,
+ ADGF_CD | ADGF_TESTING,
GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_BRIGHTPALETTE)
},
},
@@ -181,7 +181,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
},
Common::IT_ITA,
Common::kPlatformPC,
- ADGF_UNSTABLE,
+ ADGF_TESTING,
GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_BRIGHTPALETTE)
},
},
diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp
index 2e9c7bb2b8..299dd74b53 100644
--- a/engines/dreamweb/dreamweb.cpp
+++ b/engines/dreamweb/dreamweb.cpp
@@ -422,25 +422,6 @@ void DreamWebEngine::keyPressed(uint16 ascii) {
DreamWeb::g_keyBuffer[in] = ascii;
}
-void DreamWebEngine::mouseCall(uint16 *x, uint16 *y, uint16 *state) {
- processEvents();
- Common::Point pos = _eventMan->getMousePos();
- if (pos.x > 298)
- pos.x = 298;
- if (pos.x < 15)
- pos.x = 15;
- if (pos.y < 15)
- pos.y = 15;
- if (pos.y > 184)
- pos.y = 184;
- *x = pos.x;
- *y = pos.y;
-
- unsigned newState = _eventMan->getButtonState();
- *state = (newState == _oldMouseState? 0 : newState);
- _oldMouseState = newState;
-}
-
void DreamWebEngine::getPalette(uint8 *data, uint start, uint count) {
_system->getPaletteManager()->grabPalette(data, start, count);
while (count--)
@@ -541,6 +522,7 @@ uint8 DreamWebEngine::modifyChar(uint8 c) const {
return c;
}
case Common::FR_FRA:
+ case Common::IT_ITA:
switch(c) {
case 133:
return 'Z' + 1;
diff --git a/engines/dreamweb/module.mk b/engines/dreamweb/module.mk
index 6bc4f8728e..3e367c6fdf 100644
--- a/engines/dreamweb/module.mk
+++ b/engines/dreamweb/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS := \
dreamweb.o \
keypad.o \
monitor.o \
+ mouse.o \
newplace.o \
object.o \
pathfind.o \
diff --git a/engines/dreamweb/mouse.cpp b/engines/dreamweb/mouse.cpp
new file mode 100644
index 0000000000..77d907611d
--- /dev/null
+++ b/engines/dreamweb/mouse.cpp
@@ -0,0 +1,171 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/events.h"
+#include "dreamweb/dreamweb.h"
+
+namespace DreamWeb {
+
+void DreamWebEngine::mouseCall(uint16 *x, uint16 *y, uint16 *state) {
+ processEvents();
+ Common::Point pos = _eventMan->getMousePos();
+ *x = CLIP<int16>(pos.x, 15, 298);
+ *y = CLIP<int16>(pos.y, 15, 184);
+
+ unsigned newState = _eventMan->getButtonState();
+ *state = (newState == _oldMouseState ? 0 : newState);
+ _oldMouseState = newState;
+}
+
+void DreamWebEngine::readMouse() {
+ _oldButton = _mouseButton;
+ _mouseButton = readMouseState();
+}
+
+uint16 DreamWebEngine::readMouseState() {
+ _oldX = _mouseX;
+ _oldY = _mouseY;
+ uint16 x, y, state;
+ mouseCall(&x, &y, &state);
+ _mouseX = x;
+ _mouseY = y;
+ return state;
+}
+
+void DreamWebEngine::dumpPointer() {
+ dumpBlink();
+ multiDump(_delHereX, _delHereY, _delXS, _delYS);
+ if ((_oldPointerX != _delHereX) || (_oldPointerY != _delHereY))
+ multiDump(_oldPointerX, _oldPointerY, _pointerXS, _pointerYS);
+}
+
+void DreamWebEngine::showPointer() {
+ showBlink();
+ uint16 x = _mouseX;
+ _oldPointerX = _mouseX;
+ uint16 y = _mouseY;
+ _oldPointerY = _mouseY;
+ if (_pickUp == 1) {
+ const GraphicsFile *frames;
+ if (_objectType != kExObjectType)
+ frames = &_freeFrames;
+ else
+ frames = &_exFrames;
+ const Frame *frame = &frames->_frames[(3 * _itemFrame + 1)];
+
+ uint8 width = MAX<uint8>(frame->width, 12);
+ uint8 height = MAX<uint8>(frame->height, 12);
+ _pointerXS = width;
+ _pointerYS = height;
+ uint16 xMin = (x >= width / 2) ? x - width / 2 : 0;
+ uint16 yMin = (y >= height / 2) ? y - height / 2 : 0;
+ _oldPointerX = xMin;
+ _oldPointerY = yMin;
+ multiGet(_pointerBack, xMin, yMin, width, height);
+ showFrame(*frames, x, y, 3 * _itemFrame + 1, 128);
+ showFrame(_icons1, x, y, 3, 128);
+ } else {
+ const Frame *frame = &_icons1._frames[_pointerFrame + 20];
+ uint8 width = MAX<uint8>(frame->width, 12);
+ uint8 height = MAX<uint8>(frame->height, 12);
+ _pointerXS = width;
+ _pointerYS = height;
+ multiGet(_pointerBack, x, y, width, height);
+ showFrame(_icons1, x, y, _pointerFrame + 20, 0);
+ }
+}
+
+void DreamWebEngine::delPointer() {
+ if (_oldPointerX == 0xffff)
+ return;
+ _delHereX = _oldPointerX;
+ _delHereY = _oldPointerY;
+ _delXS = _pointerXS;
+ _delYS = _pointerYS;
+ multiPut(_pointerBack, _delHereX, _delHereY, _pointerXS, _pointerYS);
+}
+
+void DreamWebEngine::animPointer() {
+ if (_pointerMode == 2) {
+ _pointerFrame = 0;
+ if ((_realLocation == 14) && (_commandType == 211))
+ _pointerFrame = 5;
+ return;
+ } else if (_pointerMode == 3) {
+ if (_pointerSpeed != 0) {
+ --_pointerSpeed;
+ } else {
+ _pointerSpeed = 5;
+ ++_pointerCount;
+ if (_pointerCount == 16)
+ _pointerCount = 0;
+ }
+ _pointerFrame = (_pointerCount <= 8) ? 1 : 2;
+ return;
+ }
+ if (_vars._watchingTime != 0) {
+ _pointerFrame = 11;
+ return;
+ }
+ _pointerFrame = 0;
+ if (_inMapArea == 0)
+ return;
+ if (_pointerFirstPath == 0)
+ return;
+ uint8 flag, flagEx;
+ getFlagUnderP(&flag, &flagEx);
+ if (flag < 2)
+ return;
+ if (flag >= 128)
+ return;
+ if (flag & 4) {
+ _pointerFrame = 3;
+ return;
+ }
+ if (flag & 16) {
+ _pointerFrame = 4;
+ return;
+ }
+ if (flag & 2) {
+ _pointerFrame = 5;
+ return;
+ }
+ if (flag & 8) {
+ _pointerFrame = 6;
+ return;
+ }
+ _pointerFrame = 8;
+}
+
+void DreamWebEngine::checkCoords(const RectWithCallback *rectWithCallbacks) {
+ if (_newLocation != 0xff)
+ return;
+ const RectWithCallback *r;
+ for (r = rectWithCallbacks; r->_xMin != 0xffff; ++r) {
+ if (r->contains(_mouseX, _mouseY)) {
+ (this->*(r->_callback))();
+ return;
+ }
+ }
+}
+
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp
index 5a53b82510..750dafe7b4 100644
--- a/engines/dreamweb/stubs.cpp
+++ b/engines/dreamweb/stubs.cpp
@@ -876,22 +876,6 @@ void DreamWebEngine::hangOnCurs(uint16 frameCount) {
}
}
-void DreamWebEngine::readMouse() {
- _oldButton = _mouseButton;
- uint16 state = readMouseState();
- _mouseButton = state;
-}
-
-uint16 DreamWebEngine::readMouseState() {
- _oldX = _mouseX;
- _oldY = _mouseY;
- uint16 x, y, state;
- mouseCall(&x, &y, &state);
- _mouseX = x;
- _mouseY = y;
- return state;
-}
-
void DreamWebEngine::dumpTextLine() {
if (_newTextLine != 1)
return;
@@ -1513,16 +1497,6 @@ void DreamWebEngine::obName(uint8 command, uint8 commandType) {
}
}
-void DreamWebEngine::delPointer() {
- if (_oldPointerX == 0xffff)
- return;
- _delHereX = _oldPointerX;
- _delHereY = _oldPointerY;
- _delXS = _pointerXS;
- _delYS = _pointerYS;
- multiPut(_pointerBack, _delHereX, _delHereY, _pointerXS, _pointerYS);
-}
-
void DreamWebEngine::showBlink() {
if (_manIsOffScreen == 1)
return;
@@ -1554,110 +1528,6 @@ void DreamWebEngine::dumpBlink() {
multiDump(44, 32, 16, 12);
}
-void DreamWebEngine::dumpPointer() {
- dumpBlink();
- multiDump(_delHereX, _delHereY, _delXS, _delYS);
- if ((_oldPointerX != _delHereX) || (_oldPointerY != _delHereY))
- multiDump(_oldPointerX, _oldPointerY, _pointerXS, _pointerYS);
-}
-
-void DreamWebEngine::showPointer() {
- showBlink();
- uint16 x = _mouseX;
- _oldPointerX = _mouseX;
- uint16 y = _mouseY;
- _oldPointerY = _mouseY;
- if (_pickUp == 1) {
- const GraphicsFile *frames;
- if (_objectType != kExObjectType)
- frames = &_freeFrames;
- else
- frames = &_exFrames;
- const Frame *frame = &frames->_frames[(3 * _itemFrame + 1)];
-
- uint8 width = frame->width;
- uint8 height = frame->height;
- if (width < 12)
- width = 12;
- if (height < 12)
- height = 12;
- _pointerXS = width;
- _pointerYS = height;
- uint16 xMin = (x >= width / 2) ? x - width / 2 : 0;
- uint16 yMin = (y >= height / 2) ? y - height / 2 : 0;
- _oldPointerX = xMin;
- _oldPointerY = yMin;
- multiGet(_pointerBack, xMin, yMin, width, height);
- showFrame(*frames, x, y, 3 * _itemFrame + 1, 128);
- showFrame(_icons1, x, y, 3, 128);
- } else {
- const Frame *frame = &_icons1._frames[_pointerFrame + 20];
- uint8 width = frame->width;
- uint8 height = frame->height;
- if (width < 12)
- width = 12;
- if (height < 12)
- height = 12;
- _pointerXS = width;
- _pointerYS = height;
- multiGet(_pointerBack, x, y, width, height);
- showFrame(_icons1, x, y, _pointerFrame + 20, 0);
- }
-}
-
-void DreamWebEngine::animPointer() {
-
- if (_pointerMode == 2) {
- _pointerFrame = 0;
- if ((_realLocation == 14) && (_commandType == 211))
- _pointerFrame = 5;
- return;
- } else if (_pointerMode == 3) {
- if (_pointerSpeed != 0) {
- --_pointerSpeed;
- } else {
- _pointerSpeed = 5;
- ++_pointerCount;
- if (_pointerCount == 16)
- _pointerCount = 0;
- }
- _pointerFrame = (_pointerCount <= 8) ? 1 : 2;
- return;
- }
- if (_vars._watchingTime != 0) {
- _pointerFrame = 11;
- return;
- }
- _pointerFrame = 0;
- if (_inMapArea == 0)
- return;
- if (_pointerFirstPath == 0)
- return;
- uint8 flag, flagEx;
- getFlagUnderP(&flag, &flagEx);
- if (flag < 2)
- return;
- if (flag >= 128)
- return;
- if (flag & 4) {
- _pointerFrame = 3;
- return;
- }
- if (flag & 16) {
- _pointerFrame = 4;
- return;
- }
- if (flag & 2) {
- _pointerFrame = 5;
- return;
- }
- if (flag & 8) {
- _pointerFrame = 6;
- return;
- }
- _pointerFrame = 8;
-}
-
void DreamWebEngine::printMessage(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered) {
const uint8 *string = (const uint8 *)_commandText.getString(index);
printDirect(string, x, y, maxWidth, centered);
@@ -3183,16 +3053,4 @@ void DreamWebEngine::purgeAnItem() {
}
}
-void DreamWebEngine::checkCoords(const RectWithCallback *rectWithCallbacks) {
- if (_newLocation != 0xff)
- return;
- const RectWithCallback *r;
- for (r = rectWithCallbacks; r->_xMin != 0xffff; ++r) {
- if (r->contains(_mouseX, _mouseY)) {
- (this->*(r->_callback))();
- return;
- }
- }
-}
-
} // End of namespace DreamWeb
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index d3b4d6f943..711fe15348 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -95,8 +95,23 @@ bool Screen::init() {
_use16ColorMode = _vm->gameFlags().use16ColorMode;
_isAmiga = (_vm->gameFlags().platform == Common::kPlatformAmiga);
- if (ConfMan.hasKey("render_mode"))
- _renderMode = Common::parseRenderMode(ConfMan.get("render_mode"));
+ // We only check the "render_mode" setting for both Eye of the Beholder
+ // games here, since all the other games do not support the render_mode
+ // setting or handle it differently, like Kyra 1 PC-98. This avoids
+ // graphics glitches and crashes in other games, when the user sets his
+ // global render_mode setting to EGA for example.
+ // TODO/FIXME: It would be nice not to hardcode this. But there is no
+ // trivial/non annoying way to do mode checks in an easy fashion right
+ // now.
+ // In a more general sense, we might want to think about a way to only
+ // pass valid config values, as in values which the engine can work with,
+ // to the engines. We already limit the selection via our GUIO flags in
+ // the game specific settings, but this is not enough due to global
+ // settings allowing everything.
+ if (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2) {
+ if (ConfMan.hasKey("render_mode"))
+ _renderMode = Common::parseRenderMode(ConfMan.get("render_mode"));
+ }
// CGA and EGA modes use additional pages to do the CGA/EGA specific graphics conversions.
if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderEGA) {
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index d741bb801f..ff78d4f18b 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -3445,6 +3445,19 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformPC, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Space Quest 4 1.000 - French DOS Floppy (supplied by misterhands in bug report #3515247)
+ {"sq4", "", {
+
+ {"resource.map", 0, "1fd6f356f6a59ad2057686ce6573caeb", 6159},
+ {"resource.000", 0, "8000a55aebc50a68b7cce07a8c33758c", 205287},
+ {"resource.001", 0, "99a6df6d366b3f061271ff3450ac0d32", 1269850},
+ {"resource.002", 0, "a6a8d7a24dbb7a266a26b084e7275e89", 1242668},
+ {"resource.003", 0, "482a99c8103b4bcb5706e5969d1c1193", 1323083},
+ {"resource.004", 0, "b2cca3afcf2e013b8ce86b64155af766", 1254353},
+ {"resource.005", 0, "9e520577e035547c4b5149a6d12ef85b", 1098814},
+ AD_LISTEND},
+ Common::FR_FRA, Common::kPlatformPC, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Space Quest 4 1.000 - English DOS Floppy (from abevi, bug report #2612718)
{"sq4", "", {
{"resource.map", 0, "8f08b97ca093f370c56d99715b015554", 6153},
diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp
index cad95b1c18..8a932232f8 100644
--- a/engines/sci/engine/features.cpp
+++ b/engines/sci/engine/features.cpp
@@ -45,6 +45,7 @@ GameFeatures::GameFeatures(SegManager *segMan, Kernel *kernel) : _segMan(segMan)
_usesCdTrack = Common::File::exists("cdaudio.map");
if (!ConfMan.getBool("use_cdaudio"))
_usesCdTrack = false;
+ _forceDOSTracks = false;
}
reg_t GameFeatures::getDetectionAddr(const Common::String &objName, Selector slc, int methodNum) {
@@ -642,7 +643,7 @@ MoveCountType GameFeatures::detectMoveCountType() {
}
bool GameFeatures::useAltWinGMSound() {
- if (g_sci && g_sci->getPlatform() == Common::kPlatformWindows && g_sci->isCD()) {
+ if (g_sci && g_sci->getPlatform() == Common::kPlatformWindows && g_sci->isCD() && !_forceDOSTracks) {
SciGameId id = g_sci->getGameId();
return (id == GID_ECOQUEST ||
id == GID_JONES ||
diff --git a/engines/sci/engine/features.h b/engines/sci/engine/features.h
index 4592c5be9c..f6bb0b5759 100644
--- a/engines/sci/engine/features.h
+++ b/engines/sci/engine/features.h
@@ -117,6 +117,12 @@ public:
*/
bool useAltWinGMSound();
+ /**
+ * Forces DOS soundtracks in Windows CD versions when the user hasn't
+ * selected a MIDI output device
+ */
+ void forceDOSTracks() { _forceDOSTracks = true; }
+
private:
reg_t getDetectionAddr(const Common::String &objName, Selector slc, int methodNum = -1);
@@ -137,6 +143,7 @@ private:
MoveCountType _moveCountType;
bool _usesCdTrack;
+ bool _forceDOSTracks;
SegManager *_segMan;
Kernel *_kernel;
diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp
index 71f4598afc..14ffa69f91 100644
--- a/engines/sci/graphics/cursor.cpp
+++ b/engines/sci/graphics/cursor.cpp
@@ -148,11 +148,13 @@ void GfxCursor::kernelSetShape(GuiResourceId resourceId) {
colorMapping[1] = _screen->getColorWhite(); // White is also hardcoded
colorMapping[2] = SCI_CURSOR_SCI0_TRANSPARENCYCOLOR;
colorMapping[3] = _palette->matchColor(170, 170, 170); // Grey
- // Special case for the magnifier cursor in LB1 (bug #3487092).
- // No other SCI0 game has a cursor resource of 1, so this is handled
- // specifically for LB1.
+ // TODO: Figure out if the grey color is hardcoded
+ // HACK for the magnifier cursor in LB1, fixes its color (bug #3487092)
if (g_sci->getGameId() == GID_LAURABOW && resourceId == 1)
colorMapping[3] = _screen->getColorWhite();
+ // HACK for Longbow cursors, fixes the shade of grey they're using (bug #3489101)
+ if (g_sci->getGameId() == GID_LONGBOW)
+ colorMapping[3] = _palette->matchColor(223, 223, 223); // Light Grey
// Seek to actual data
resourceData += 4;
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 09cab75c39..918b045cb9 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -88,6 +88,12 @@ void SciMusic::init() {
uint32 dev = MidiDriver::detectDevice(deviceFlags);
_musicType = MidiDriver::getMusicType(dev);
+ if (g_sci->_features->useAltWinGMSound() && _musicType != MT_GM) {
+ warning("A Windows CD version with an alternate MIDI soundtrack has been chosen, "
+ "but no MIDI music device has been selected. Reverting to the DOS soundtrack");
+ g_sci->_features->forceDOSTracks();
+ }
+
switch (_musicType) {
case MT_ADLIB:
// FIXME: There's no Amiga sound option, so we hook it up to AdLib
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index b47982af00..2da0abb5df 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -589,11 +589,11 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
file.c_str(), md5str.c_str(), filesize);
// Sanity check: We *should* have found a matching gameid / variant at this point.
- // If not, then there's a bug in our data tables...
- assert(dr.game.gameid != 0);
-
- // Add it to the list of detected games
- results.push_back(dr);
+ // If not, we may have #ifdef'ed the entry out in our detection_tables.h because we
+ // don't have the required stuff compiled in, or there's a bug in our data tables...
+ if (dr.game.gameid != 0)
+ // Add it to the list of detected games
+ results.push_back(dr);
}
}
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index c25c875616..3957c7c42d 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Mon Apr 9 12:23:48 2012
+ This file was generated by the md5table tool on Tue Apr 24 03:50:58 2012
DO NOT EDIT MANUALLY!
*/
@@ -621,6 +621,7 @@ static const MD5Table md5table[] = {
{ "f40a7f495f59188ca57a9d1d50301bb6", "puttputt", "HE 60", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "f5228b0cc1c19e6ea8268ba2eeb61f60", "freddi", "HE 73", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "f73883f13b5a302749a5bad31d909780", "tentacle", "", "CD", -1, Common::DE_DEU, Common::kPlatformMacintosh },
+ { "f7635a0e2ab82c9a0f9ace5f232a488f", "catalog", "HE 72", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "f7711f9264d4d43c2a1518ec7c10a607", "pajama3", "", "", 79382, Common::EN_USA, Common::kPlatformUnknown },
{ "f79e60c17cca601e411f1f75e8ee9b5a", "spyfox2", "", "", 51286, Common::UNK_LANG, Common::kPlatformUnknown },
{ "f8be685007a8b425ba2a455da732f59f", "pajama2", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
diff --git a/engines/sword25/script/luabindhelper.cpp b/engines/sword25/script/luabindhelper.cpp
index 8fbbe7e272..6900305f5c 100644
--- a/engines/sword25/script/luabindhelper.cpp
+++ b/engines/sword25/script/luabindhelper.cpp
@@ -412,7 +412,7 @@ Common::String LuaBindhelper::stackDump(lua_State *L) {
oss += "------------------- Stack Dump -------------------\n";
while (i) {
- oss += i + ": " + getLuaValueInfo(L, i) + "\n";
+ oss += Common::String::format("%d: ", i) + getLuaValueInfo(L, i) + "\n";
i--;
}
diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h
index be44b1c462..b6b19f6ee7 100644
--- a/engines/tinsel/detection_tables.h
+++ b/engines/tinsel/detection_tables.h
@@ -397,7 +397,7 @@ static const TinselGameDescription gameDescriptions[] = {
{ // multilanguage PSX demo
{
"dw",
- "CD demo",
+ "CD Demo",
{
{"french.txt", 0, "e7020d35f58d0d187052ac406d86cc87", 273914},
{"german.txt", 0, "52f0a01e0ff0d340b02a36fd5109d705", 263942},
diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index 781a378f13..fa5334a033 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -131,11 +131,6 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
g_currentMidi = dwFileOffset;
g_currentLoop = bLoop;
- // Tinsel V1 PSX uses a different music format, so i
- // disable it here.
- // TODO: Maybe this should be moved to a better place...
- if (TinselV1PSX) return false;
-
if (_vm->_config->_musicVolume != 0) {
bool mute = false;
if (ConfMan.hasKey("mute"))
@@ -231,14 +226,14 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
_vm->_midiMusic->send(0x7F07B0 | 13);
}
- _vm->_midiMusic->playXMIDI(g_midiBuffer.pDat, dwSeqLen, bLoop);
+ _vm->_midiMusic->playMIDI(dwSeqLen, bLoop);
// Store the length
//dwLastSeqLen = dwSeqLen;
} else {
// dwFileOffset == dwLastMidiIndex
_vm->_midiMusic->stop();
- _vm->_midiMusic->playXMIDI(g_midiBuffer.pDat, dwSeqLen, bLoop);
+ _vm->_midiMusic->playMIDI(dwSeqLen, bLoop);
}
return true;
@@ -314,8 +309,7 @@ void OpenMidiFiles() {
Common::File midiStream;
// Demo version has no midi file
- // Also, Discworld PSX uses still unsupported psx SEQ format for music...
- if ((_vm->getFeatures() & GF_DEMO) || (TinselVersion == TINSEL_V2) || TinselV1PSX)
+ if ((_vm->getFeatures() & GF_DEMO) || (TinselVersion == TINSEL_V2))
return;
if (g_midiBuffer.pDat)
@@ -412,7 +406,7 @@ void MidiMusicPlayer::send(uint32 b) {
}
}
-void MidiMusicPlayer::playXMIDI(byte *midiData, uint32 size, bool loop) {
+void MidiMusicPlayer::playMIDI(uint32 size, bool loop) {
Common::StackLock lock(_mutex);
if (_isPlaying)
@@ -420,6 +414,13 @@ void MidiMusicPlayer::playXMIDI(byte *midiData, uint32 size, bool loop) {
stop();
+ if (TinselV1PSX)
+ playSEQ(size, loop);
+ else
+ playXMIDI(size, loop);
+}
+
+void MidiMusicPlayer::playXMIDI(uint32 size, bool loop) {
// It seems like not all music (the main menu music, for instance) set
// all the instruments explicitly. That means the music will sound
// different, depending on which music played before it. This appears
@@ -433,7 +434,78 @@ void MidiMusicPlayer::playXMIDI(byte *midiData, uint32 size, bool loop) {
// Load XMID resource data
MidiParser *parser = MidiParser::createParser_XMIDI();
- if (parser->loadMusic(midiData, size)) {
+ if (parser->loadMusic(g_midiBuffer.pDat, size)) {
+ parser->setTrack(0);
+ parser->setMidiDriver(this);
+ parser->setTimerRate(getBaseTempo());
+ parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+ parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);
+
+ _parser = parser;
+
+ _isLooping = loop;
+ _isPlaying = true;
+ } else {
+ delete parser;
+ }
+}
+
+void MidiMusicPlayer::playSEQ(uint32 size, bool loop) {
+ // MIDI.DAT holds the file names in DW1 PSX
+ Common::String baseName((char *)g_midiBuffer.pDat, size);
+ Common::String seqName = baseName + ".SEQ";
+
+ // TODO: Load the instrument bank (<baseName>.VB and <baseName>.VH)
+
+ Common::File seqFile;
+ if (!seqFile.open(seqName))
+ error("Failed to open SEQ file '%s'", seqName.c_str());
+
+ if (seqFile.readUint32LE() != MKTAG('S', 'E', 'Q', 'p'))
+ error("Failed to find SEQp tag");
+
+ // Make sure we don't have a SEP file (with multiple SEQ's inside)
+ if (seqFile.readUint32BE() != 1)
+ error("Can only play SEQ files, not SEP");
+
+ uint16 ppqn = seqFile.readUint16BE();
+ uint32 tempo = seqFile.readUint16BE() << 8;
+ tempo |= seqFile.readByte();
+ /* uint16 beat = */ seqFile.readUint16BE();
+
+ // SEQ is directly based on SMF and we'll use that to our advantage here
+ // and convert to SMF and then use the SMF MidiParser.
+
+ // Calculate the SMF size we'll need
+ uint32 dataSize = seqFile.size() - 15;
+ uint32 actualSize = dataSize + 7 + 22;
+
+ // Resize the buffer if necessary
+ if (g_midiBuffer.size < actualSize) {
+ g_midiBuffer.pDat = (byte *)realloc(g_midiBuffer.pDat, actualSize);
+ assert(g_midiBuffer.pDat);
+ }
+
+ // Now construct the header
+ WRITE_BE_UINT32(g_midiBuffer.pDat, MKTAG('M', 'T', 'h', 'd'));
+ WRITE_BE_UINT32(g_midiBuffer.pDat + 4, 6); // header size
+ WRITE_BE_UINT16(g_midiBuffer.pDat + 8, 0); // type 0
+ WRITE_BE_UINT16(g_midiBuffer.pDat + 10, 1); // one track
+ WRITE_BE_UINT16(g_midiBuffer.pDat + 12, ppqn);
+ WRITE_BE_UINT32(g_midiBuffer.pDat + 14, MKTAG('M', 'T', 'r', 'k'));
+ WRITE_BE_UINT32(g_midiBuffer.pDat + 18, dataSize + 7); // SEQ data size + tempo change event size
+
+ // Add in a fake tempo change event
+ WRITE_BE_UINT32(g_midiBuffer.pDat + 22, 0x00FF5103); // no delta, meta event, tempo change, param size = 3
+ WRITE_BE_UINT16(g_midiBuffer.pDat + 26, tempo >> 8);
+ g_midiBuffer.pDat[28] = tempo & 0xFF;
+
+ // Now copy in the rest of the events
+ seqFile.read(g_midiBuffer.pDat + 29, dataSize);
+ seqFile.close();
+
+ MidiParser *parser = MidiParser::createParser_SMF();
+ if (parser->loadMusic(g_midiBuffer.pDat, actualSize)) {
parser->setTrack(0);
parser->setMidiDriver(this);
parser->setTimerRate(getBaseTempo());
diff --git a/engines/tinsel/music.h b/engines/tinsel/music.h
index d43fed268d..121bf3d79b 100644
--- a/engines/tinsel/music.h
+++ b/engines/tinsel/music.h
@@ -64,7 +64,7 @@ public:
virtual void setVolume(int volume);
- void playXMIDI(byte *midiData, uint32 size, bool loop);
+ void playMIDI(uint32 size, bool loop);
// void stop();
void pause();
@@ -76,6 +76,10 @@ public:
// The original sets the "sequence timing" to 109 Hz, whatever that
// means. The default is 120.
uint32 getBaseTempo() { return _driver ? (109 * _driver->getBaseTempo()) / 120 : 0; }
+
+private:
+ void playXMIDI(uint32 size, bool loop);
+ void playSEQ(uint32 size, bool loop);
};
class PCMMusicPlayer : public Audio::AudioStream {
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index c652abca25..cd65a4ec32 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -1626,7 +1626,7 @@ static void Play(CORO_PARAM, SCNHANDLE hFilm, int x, int y, bool bComplete, int
*/
static void PlayMidi(CORO_PARAM, SCNHANDLE hMidi, int loop, bool complete) {
// FIXME: This is a workaround for the FIXME below
- if (GetMidiVolume() == 0 || TinselV1PSX)
+ if (GetMidiVolume() == 0)
return;
CORO_BEGIN_CONTEXT;