aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devtools/scumm-md5.txt9
-rw-r--r--engines/bladerunner/actor.cpp4
-rw-r--r--engines/bladerunner/bladerunner.cpp29
-rw-r--r--engines/bladerunner/bladerunner.h2
-rw-r--r--engines/bladerunner/dialogue_menu.cpp359
-rw-r--r--engines/bladerunner/dialogue_menu.h103
-rw-r--r--engines/bladerunner/font.cpp2
-rw-r--r--engines/bladerunner/module.mk1
-rw-r--r--engines/bladerunner/mouse.cpp5
-rw-r--r--engines/bladerunner/mouse.h2
-rw-r--r--engines/bladerunner/script/ai.cpp9
-rw-r--r--engines/bladerunner/script/ai.h3
-rw-r--r--engines/bladerunner/script/script.cpp39
-rw-r--r--engines/bladerunner/script/script.h2
-rw-r--r--engines/bladerunner/shape.h3
-rw-r--r--engines/saga/music.cpp2
-rw-r--r--engines/saga/saveload.cpp6
-rw-r--r--engines/scumm/detection_tables.h1
-rw-r--r--engines/scumm/scumm-md5.h11
-rw-r--r--engines/sludge/builtin.cpp28
-rw-r--r--engines/sludge/cursors.cpp13
-rw-r--r--engines/sludge/cursors.h3
-rw-r--r--engines/sludge/detection_tables.h116
-rw-r--r--engines/sludge/event.cpp16
-rw-r--r--engines/sludge/event.h4
-rw-r--r--engines/sludge/fileset.cpp24
-rw-r--r--engines/sludge/fileset.h13
-rw-r--r--engines/sludge/floor.cpp20
-rw-r--r--engines/sludge/fonttext.cpp52
-rw-r--r--engines/sludge/fonttext.h9
-rw-r--r--engines/sludge/graphics.cpp37
-rw-r--r--engines/sludge/graphics.h7
-rw-r--r--engines/sludge/imgloader.cpp2
-rw-r--r--engines/sludge/language.cpp22
-rw-r--r--engines/sludge/language.h12
-rw-r--r--engines/sludge/main_loop.cpp33
-rw-r--r--engines/sludge/main_loop.h2
-rw-r--r--engines/sludge/moreio.cpp1
-rw-r--r--engines/sludge/newfatal.cpp4
-rw-r--r--engines/sludge/newfatal.h1
-rw-r--r--engines/sludge/objtypes.cpp14
-rw-r--r--engines/sludge/objtypes.h6
-rw-r--r--engines/sludge/region.cpp8
-rw-r--r--engines/sludge/sludge.cpp5
-rw-r--r--engines/sludge/sludge.h1
-rw-r--r--engines/sludge/sludger.cpp96
-rw-r--r--engines/sludge/sludger.h5
-rw-r--r--engines/sludge/sound.cpp32
-rw-r--r--engines/sludge/sound.h1
-rw-r--r--engines/sludge/sprites.cpp14
-rw-r--r--engines/sludge/sprites.h29
-rw-r--r--engines/sludge/talk.cpp3
-rw-r--r--engines/sludge/variable.cpp8
-rw-r--r--engines/titanic/game/maitred/maitred_prod_receptor.cpp24
-rw-r--r--engines/titanic/game/maitred/maitred_prod_receptor.h8
-rw-r--r--engines/titanic/npcs/parrot.cpp30
-rw-r--r--engines/titanic/npcs/parrot.h5
-rw-r--r--engines/titanic/pet_control/pet_control.cpp21
-rw-r--r--engines/titanic/pet_control/pet_conversations.cpp2
-rw-r--r--engines/titanic/pet_control/pet_real_life.cpp3
-rw-r--r--engines/titanic/true_talk/maitred_script.cpp52
-rw-r--r--engines/titanic/true_talk/maitred_script.h14
-rw-r--r--engines/wage/detection_tables.h1
-rw-r--r--engines/wage/gui.cpp2
-rw-r--r--engines/wage/world.cpp4
-rw-r--r--graphics/macgui/macfontmanager.cpp4
-rw-r--r--graphics/macgui/macmenu.cpp9
-rw-r--r--graphics/macgui/macmenu.h2
-rw-r--r--graphics/macgui/mactextwindow.cpp39
-rw-r--r--graphics/macgui/mactextwindow.h2
-rw-r--r--graphics/macgui/macwindowmanager.cpp6
71 files changed, 1147 insertions, 314 deletions
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index d3bc3c04a7..f28a51661a 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -517,6 +517,7 @@ freddi Freddi Fish 1: The Case of the Missing Kelp Seeds
c7c492a107ec520d7a7943037d0ca54a -1 nl Windows HE 71 Demo - DarthBo
084ed0fa98a6d1e9368d67fe9cfbd417 -1 en Windows HE 71 Demo - khalek
+ e3f1f2b6ca7b55076782872cb8ff0985 9779 en Windows HE 71 Demo - Ben Castricum
c8aac5e3e701874e2fa4117896f9e1b1 -1 en Mac HE 73 Demo - khalek, sev
0855496dde35356b1a9691e22ba84cdc -1 en Windows HE 73 Demo - khalek
566165a7338fa11029e7c14d94fa70d0 9800 en Windows HE 73 Demo - khalek
@@ -617,6 +618,7 @@ FreddisFunShop Freddi Fish's One-Stop Fun Shop
catalog Humongous Interactive Catalog
11e6e244078ff09b0f3832e35420e0a7 -1 en Windows - Demo - khalek, sev
+ c13fdcdd2ecaa346f80d1c61782208be 28539 en Windows - Demo - Ben Castricum
037385a953789190298494d92b89b3d0 -1 en Windows HE 72 Demo - khalek, sev
f7635a0e2ab82c9a0f9ace5f232a488f -1 en Windows HE 72 Demo - Kirben
a56e8d9d4281c53c3f63c9bd22a59e21 10978342 en All HE CUP Preview George Kormendi
@@ -645,6 +647,7 @@ farm Let's Explore the Farm with Buzzy
39fd6db10d0222d817025c4d3346e3b4 -1 en Mac - Demo - Joachim Eberhard
6c375c2236d99f56e6c2cf540e74e474 34333 nl Windows - Demo - Kirben
+ 03173f0df12062d84721062666155efa 34312 en Windows HE 71 Demo - Ben Castricum
bf8b52fdd9a69c67f34e8e9fec72661c -1 en Windows HE 71 Demo - khalek, sev
0557df19f046a84c2fdc63507c6616cb -1 nl Windows HE 72 Demo - adutchguy
8d479e36f35e80257dfc102cf4b8a912 34333 en Windows HE 72 Demo - khalek, sev
@@ -880,6 +883,7 @@ PuttsFunShop Putt-Putt's One-Stop Fun Shop
spyfox SPY Fox 1: Dry Cereal
6bf70eee5de3d24d2403e0dd3d267e8a 49221 All Windows - - - khalek (US and ???)
100b4c8403ad6a83d4bf7dbf83e44dc4 -1 fr Windows - - - gist974
+ 68e4bf77136cb3165e65d5c197ce65bd 49221 de Windows - - - Ben Castricum
9bda5fee51d2fda5253d02c642016bf4 -1 nl All HE 98.5 - - daniel9, joostp
58436e634f4fae1d9973591c2ffa1fcb -1 en All HE 99 Updated - Joachim Eberhard (GB or US?)
a28135a7ade38cc0208b04507c46efd1 -1 de All HE 99 - - nachbarnebenan
@@ -890,6 +894,11 @@ spyfox SPY Fox 1: Dry Cereal
23394c8d29cc63c61313959431a12476 -1 en Windows HE 100 Updated - Jonathan (GB or US?)
50b831f11b8c4b83784cf81f4dcc69ea -1 en Wii HE 101 - - sanguinehearts (GB or US?)
15878e3bee2e1e759184abee98589eaa -1 en iOS HE 100 - - clone2727 (GB or US?)
+ e441af0b65983c1a4b3a52f9c7b15484 49742 us Wii HE 100 - - Ben Castricum
+ 1b3a7f67d688f44d0e54da839923d3a3 49742 nl Wii HE 100 - - Ben Castricum
+ 2f7583da072d027057983c43bb3fa53f 49742 gb Wii HE 100 - - Ben Castricum
+ afd74ce452df9cca6ebc023276b4772a 49742 de Wii HE 100 - - Ben Castricum
+ 6f4d64ce1b44470536cae2eb6fe8aefd 49742 fr Wii HE 100 - - Ben Castricum
53e94115b55dd51d4b8ff0871aa1df1e 20103 us All - Demo - khalek, sev
fbdd947d21e8f5bac6d6f7a316af1c5a 15693 us All - Demo - sev
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp
index 6265a0480a..85c5d89240 100644
--- a/engines/bladerunner/actor.cpp
+++ b/engines/bladerunner/actor.cpp
@@ -1062,7 +1062,11 @@ void Actor::addClueToDatabase(int clueId, int weight, bool clueAcquired, bool un
}
void Actor::acquireClue(int clueId, bool unknownFlag, int fromActorId) {
+ bool hasAlready = hasClue(clueId);
_clues->acquire(clueId, unknownFlag, fromActorId);
+ if (!hasAlready) {
+ _vm->_aiScripts->ReceivedClue(_id, clueId, fromActorId);
+ }
}
void Actor::loseClue(int clueId) {
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 76c0c3f7ea..3622130b45 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -30,6 +30,7 @@
#include "bladerunner/chapters.h"
#include "bladerunner/combat.h"
#include "bladerunner/crimes_database.h"
+#include "bladerunner/dialogue_menu.h"
#include "bladerunner/font.h"
#include "bladerunner/gameflags.h"
#include "bladerunner/gameinfo.h"
@@ -280,7 +281,9 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
if (!_textOptions->open("OPTIONS"))
return false;
- // TODO: Dialogue Menu (DLGMENU.TRE)
+ _dialogueMenu = new DialogueMenu(this);
+ if (!_dialogueMenu->loadText("DLGMENU"))
+ return false;
_suspectsDatabase = new SuspectsDatabase(this, _gameInfo->getSuspectsDatabaseSize());
@@ -602,8 +605,12 @@ void BladeRunnerEngine::gameTick() {
if (_scene->didPlayerWalkIn()) {
_sceneScript->PlayerWalkedIn();
}
- // TODO: Gun range announcements
+ bool inDialogueMenu = _dialogueMenu->isVisible();
+ if (!inDialogueMenu) {
+ // TODO: actors combat-tick
+ }
+ // TODO: Gun range announcements
_zbuffer->clean();
_ambientSounds->tick();
@@ -621,8 +628,9 @@ void BladeRunnerEngine::gameTick() {
// TODO: Render overlays
- //if (!dialogueMenu)
+ if (!inDialogueMenu) {
actorsUpdate();
+ }
if (_settings->getNewScene() == -1 || _sceneScript->IsInsideScript() || _aiScripts->IsInsideScript()) {
_sliceRenderer->setView(*_view);
@@ -645,9 +653,13 @@ void BladeRunnerEngine::gameTick() {
_itemPickup->tick();
_itemPickup->draw();
- // TODO: Draw dialogue menu
-
Common::Point p = getMousePos();
+
+ if (_dialogueMenu->isVisible()) {
+ _dialogueMenu->tick(p.x, p.y);
+ _dialogueMenu->draw();
+ }
+
_mouse->tick(p.x, p.y);
_mouse->draw(_surfaceGame, p.x, p.y);
@@ -833,6 +845,13 @@ void BladeRunnerEngine::handleMouseAction(int x, int y, bool buttonLeft, bool bu
return;
}
+ if (_dialogueMenu->waitingForInput()) {
+ if (buttonLeft && !buttonDown) {
+ _dialogueMenu->mouseUp();
+ }
+ return;
+ }
+
Vector3 mousePosition = _mouse->getXYZ(x, y);
int isClickable;
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index fd654ac5fb..405952595a 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -54,6 +54,7 @@ class AudioSpeech;
class Chapters;
class CrimesDatabase;
class Combat;
+class DialogueMenu;
class Font;
class GameFlags;
class GameInfo;
@@ -92,6 +93,7 @@ public:
Chapters *_chapters;
CrimesDatabase *_crimesDatabase;
Combat *_combat;
+ DialogueMenu *_dialogueMenu;
GameFlags *_gameFlags;
GameInfo *_gameInfo;
ItemPickup *_itemPickup;
diff --git a/engines/bladerunner/dialogue_menu.cpp b/engines/bladerunner/dialogue_menu.cpp
new file mode 100644
index 0000000000..2ef137f9d4
--- /dev/null
+++ b/engines/bladerunner/dialogue_menu.cpp
@@ -0,0 +1,359 @@
+/* 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 "bladerunner/dialogue_menu.h"
+
+#include "bladerunner/bladerunner.h"
+
+#include "bladerunner/font.h"
+#include "bladerunner/mouse.h"
+#include "bladerunner/shape.h"
+#include "bladerunner/text_resource.h"
+
+#include "common/debug.h"
+#include "common/util.h"
+
+#define LINE_HEIGHT 9
+#define BORDER_SIZE 10
+
+namespace BladeRunner {
+
+DialogueMenu::DialogueMenu(BladeRunnerEngine *vm)
+ : _vm(vm)
+{
+ reset();
+ _textResource = new TextResource(_vm);
+ _shapes.reserve(8);
+ for (int i = 0; i != 8; ++i) {
+ _shapes.push_back(Shape(_vm));
+ bool r = _shapes[i].readFromContainer("DIALOG.SHP", i);
+ assert(r);
+ (void)r;
+ }
+}
+
+DialogueMenu::~DialogueMenu() {
+ delete _textResource;
+}
+
+bool DialogueMenu::loadText(const char *name) {
+ bool r = _textResource->open(name);
+ if (!r) {
+ error("Failed to load dialogue menu text");
+ }
+ return r;
+}
+
+bool DialogueMenu::show() {
+ int x, y;
+
+ _vm->_mouse->getXY(&x, &y);
+
+ return showAt(x, y);
+}
+
+bool DialogueMenu::showAt(int x, int y) {
+ debug("DialogueMenu::showAt %d %d %d", _isVisible, x, y);
+ if (_isVisible) {
+ return false;
+ }
+
+ _isVisible = true;
+ _selectedItemIndex = 0;
+ _centerX = x;
+ _centerY = y;
+ calculatePosition(x, y);
+
+ return true;
+}
+
+bool DialogueMenu::hide() {
+ _waitingForInput = 0;
+ if (!_isVisible) {
+ return false;
+ }
+
+ _isVisible = false;
+ return true;
+}
+
+bool DialogueMenu::clearList() {
+ _selectedItemIndex = -1;
+ _listSize = 0;
+ return true;
+}
+
+bool DialogueMenu::addToList(int answer, int a3, int a4, int a5, int a6) {
+ if (_listSize >= 10)
+ return false;
+ if (getAnswerIndex(answer) != -1)
+ return false;
+
+ const char *text = _textResource->getText(answer);
+ if (!text || strlen(text) >= 50)
+ return false;
+
+ int index = _listSize++;
+ strcpy(_items[index].text, text);
+ _items[index].answerValue = answer;
+ _items[index].field_36 = 0;
+ _items[index].field_46 = a3;
+ _items[index].field_3A = a4;
+ _items[index].field_3E = a5;
+ _items[index].field_42 = a6;
+
+ // CHECK(madmoose): BLADE.EXE calls this needlessly
+ // calculatePosition();
+
+ return true;
+}
+
+bool DialogueMenu::addToListNeverRepeatOnceSelected(int answer, int a3, int a4, int a5) {
+ for (int i = 0; i != _neverRepeatListSize; ++i) {
+ if (answer == _neverRepeatValues[i] && _neverRepeatWasSelected[i]) {
+ return true;
+ }
+ }
+
+ _neverRepeatValues[_neverRepeatListSize] = answer;
+ _neverRepeatWasSelected[_neverRepeatListSize] = false;
+ ++_neverRepeatListSize;
+ return addToList(answer, 0, a3, a4, a5);
+}
+
+int DialogueMenu::queryInput() {
+ if (!_isVisible || _listSize == 0)
+ return -1;
+
+ int answer = -1;
+ if (_listSize == 1) {
+ _selectedItemIndex = 0;
+ answer = _items[0].answerValue;
+ } else if (_listSize == 2) {
+ if (_items[0].field_46) {
+ _selectedItemIndex = 1;
+ answer = _items[0].answerValue;
+ } else if (_items[0].field_46) {
+ _selectedItemIndex = 0;
+ answer = _items[1].answerValue;
+ }
+ }
+
+ if (answer == -1) {
+ int agenda = 4; //_vm->_settings.getPlayerAgenda();
+ if (agenda == 4) {
+ _waitingForInput = true;
+ do {
+ // if (!_vm->_gameRunning)
+ // break;
+
+ while (!_vm->playerHasControl()) {
+ _vm->playerGainsControl();
+ }
+
+ while (_vm->_mouse->isDisabled()) {
+ _vm->_mouse->enable();
+ }
+
+ _vm->gameTick();
+ } while (_waitingForInput);
+
+ } else if (agenda == 3) {
+ int tries = 0;
+ bool searching = true;
+ int i;
+ do {
+ i = _vm->_rnd.getRandomNumber(_listSize - 1);
+ if (!_items[i].field_46) {
+ searching = false;
+ } else if (++tries > 1000) {
+ searching = false;
+ i = 0;
+ }
+ } while (searching);
+ _selectedItemIndex = i;
+ } else {
+ error("unimplemented...");
+ }
+ }
+
+ answer = _items[_selectedItemIndex].answerValue;
+ for (int i = 0; i != _neverRepeatListSize; ++i) {
+ if (answer == _neverRepeatValues[i]) {
+ _neverRepeatWasSelected[i] = true;
+ break;
+ }
+ }
+
+ if (_selectedItemIndex >= 0) {
+ debug("DM Query Input: %d %s", answer, _items[_selectedItemIndex].text);
+ }
+
+ return answer;
+}
+
+int DialogueMenu::listSize() {
+ return _listSize;
+}
+
+bool DialogueMenu::isVisible() {
+ return _isVisible;
+}
+
+bool DialogueMenu::isOpen() {
+ return _isVisible || _waitingForInput;
+}
+
+void DialogueMenu::tick(int x, int y) {
+ if (!_isVisible || _listSize == 0) {
+ return;
+ }
+
+ int line = (y - (_screenY + BORDER_SIZE)) / LINE_HEIGHT;
+ line = CLIP(line, 0, _listSize - 1);
+
+ _selectedItemIndex = line;
+}
+
+void DialogueMenu::draw() {
+ if (!_isVisible || _listSize == 0)
+ return;
+
+ for (int i = 0; i != _listSize; ++i) {
+ if (i == _selectedItemIndex) {
+ _items[i].field_36 = 31;
+ } else {
+ _items[i].field_36 = 16;
+ }
+
+ // TODO(madmoose): There's more logic here
+ }
+
+ const int x1 = _screenX;
+ const int y1 = _screenY;
+ const int x2 = _screenX + BORDER_SIZE + _maxItemWidth;
+ const int y2 = _screenY + BORDER_SIZE + _listSize * LINE_HEIGHT;
+
+ Graphics::Surface &s = _vm->_surfaceGame;
+
+ darkenRect(s, x1 + 8, y1 + 8, x2 + 2, y2 + 2);
+
+ _shapes[0].draw(s, x1, y1);
+ _shapes[3].draw(s, x2, y1);
+ _shapes[2].draw(s, x1, y2);
+ _shapes[5].draw(s, x2, y2);
+
+ int x = x1 + BORDER_SIZE;
+ int y = y1 + BORDER_SIZE;
+ for (int i = 0; i != _listSize; ++i) {
+ _shapes[1].draw(s, x1, y);
+ _shapes[4].draw(s, x2, y);
+ uint16 color = ((_items[i].field_36 >> 1) << 10) | ((_items[i].field_36 >> 1) << 6) | _items[i].field_36;
+ _vm->_mainFont->drawColor(_items[i].text, s, x, y, color);
+ y += LINE_HEIGHT;
+ }
+ for (; x != x2; ++x) {
+ _shapes[6].draw(s, x, y1);
+ _shapes[7].draw(s, x, y2);
+ }
+}
+
+int DialogueMenu::getAnswerIndex(int answer) {
+ for (int i = 0; i != _listSize; ++i) {
+ if (_items[i].answerValue == answer) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+const char *DialogueMenu::getText(int id) {
+ return _textResource->getText((uint32)id);
+}
+
+void DialogueMenu::calculatePosition(int unusedX, int unusedY) {
+ _maxItemWidth = 0;
+ for (int i = 0; i != _listSize; ++i) {
+ _maxItemWidth = MAX(_maxItemWidth, _vm->_mainFont->getTextWidth(_items[i].text));
+ }
+ _maxItemWidth += 2;
+
+ int w = BORDER_SIZE + _shapes[4].getWidth() + _maxItemWidth;
+ int h = BORDER_SIZE + _shapes[7].getHeight() + LINE_HEIGHT * _listSize;
+
+ _screenX = _centerX - w / 2;
+ _screenY = _centerY - h / 2;
+
+ _screenX = CLIP(_screenX, 0, 640 - w);
+ _screenY = CLIP(_screenY, 0, 480 - h);
+
+ debug("calculatePosition: %d %d %d %d %d", _screenX, _screenY, _centerX, _centerY, _maxItemWidth);
+}
+
+void DialogueMenu::mouseUp() {
+ _waitingForInput = false;
+}
+
+bool DialogueMenu::waitingForInput() {
+ return _waitingForInput;
+}
+
+void DialogueMenu::clear() {
+ _isVisible = false;
+ _waitingForInput = false;
+ _selectedItemIndex = 0;
+ _listSize = 0;
+ for (int i = 0; i != 10; ++i) {
+ _items[0].text[0] = '\0';
+ _items[0].answerValue = -1;
+ _items[0].field_36 = 0;
+ _items[0].field_42 = -1;
+ _items[0].field_3A = -1;
+ _items[0].field_3E = -1;
+ _items[0].field_46 = 0;
+ }
+ _neverRepeatListSize = 0;
+ for (int i = 0; i != 100; ++i) {
+ _neverRepeatValues[i] = -1;
+ _neverRepeatWasSelected[i] = false;
+ }
+ _centerX = 0;
+ _centerY = 0;
+}
+
+void DialogueMenu::reset() {
+ clear();
+ _textResource = nullptr;
+}
+
+void DialogueMenu::darkenRect(Graphics::Surface &s, int x1, int y1, int x2, int y2) {
+ for (int y = y1; y != y2; ++y) {
+ for (int x = x1; x != x2; ++x) {
+ // TODO(madmoose)
+ uint16 *p = (uint16*)s.getBasePtr(x, y);
+ *p = 0;
+ }
+ }
+}
+
+} // End of namespace BladeRunner
diff --git a/engines/bladerunner/dialogue_menu.h b/engines/bladerunner/dialogue_menu.h
new file mode 100644
index 0000000000..7a6b99e967
--- /dev/null
+++ b/engines/bladerunner/dialogue_menu.h
@@ -0,0 +1,103 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BLADERUNNER_DIALOGUE_MENU_H
+#define BLADERUNNER_DIALOGUE_MENU_H
+
+#include "bladerunner/shape.h"
+
+#include "common/array.h"
+
+#include "graphics/surface.h"
+
+namespace BladeRunner {
+
+class BladeRunnerEngine;
+class TextResource;
+
+struct DialogueItem {
+ char text[50];
+ int answerValue;
+ int field_36;
+ int field_3A;
+ int field_3E;
+ int field_42;
+ int field_46;
+};
+
+class DialogueMenu {
+ BladeRunnerEngine *_vm;
+
+ TextResource *_textResource;
+ Common::Array<Shape> _shapes;
+ bool _isVisible;
+ bool _waitingForInput;
+ int _selectedItemIndex;
+ int _listSize;
+
+ // These track whether a dialogue option
+ // has previously been selected
+ int _neverRepeatListSize;
+ int _neverRepeatValues[100];
+ bool _neverRepeatWasSelected[100];
+
+ int _centerX;
+ int _centerY;
+ int _screenX;
+ int _screenY;
+ int _maxItemWidth;
+ DialogueItem _items[10];
+
+public:
+ DialogueMenu(BladeRunnerEngine *vm);
+ ~DialogueMenu();
+
+ bool loadText(const char *name);
+
+ bool show();
+ bool showAt(int x, int y);
+ bool hide();
+ bool clearList();
+ bool addToList(int answer, int a3, int a4, int a5, int a6);
+ bool addToListNeverRepeatOnceSelected(int answer, int a3, int a4, int a5);
+ int queryInput();
+ int listSize();
+ bool isVisible();
+ bool isOpen();
+ void tick(int x, int y);
+ void draw();
+ int getAnswerIndex(int answer);
+ const char *getText(int id);
+ void calculatePosition(int unusedX = 0, int unusedY = 0);
+
+ void mouseUp();
+ bool waitingForInput();
+
+ void clear();
+ void reset();
+
+ static void darkenRect(Graphics::Surface &s, int x1, int y1, int x2, int y2);
+};
+
+} // End of namespace BladeRunner
+
+#endif
diff --git a/engines/bladerunner/font.cpp b/engines/bladerunner/font.cpp
index fd8b9f204d..8ab5cfab13 100644
--- a/engines/bladerunner/font.cpp
+++ b/engines/bladerunner/font.cpp
@@ -130,7 +130,7 @@ int Font::getTextWidth(const Common::String &text) {
return 0;
}
while (*character != 0) {
- totalWidth = _spacing1 + _characters[*character + 1]._width;
+ totalWidth += _spacing1 + _characters[*character + 1]._width;
character++;
}
return totalWidth - _spacing1;
diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk
index 9a43ef4457..3e496ff3b5 100644
--- a/engines/bladerunner/module.mk
+++ b/engines/bladerunner/module.mk
@@ -20,6 +20,7 @@ MODULE_OBJS = \
decompress_lcw.o \
decompress_lzo.o \
detection.o \
+ dialogue_menu.o \
fog.o \
font.o \
gameflags.o \
diff --git a/engines/bladerunner/mouse.cpp b/engines/bladerunner/mouse.cpp
index be114dc1bb..4c5a9b91a0 100644
--- a/engines/bladerunner/mouse.cpp
+++ b/engines/bladerunner/mouse.cpp
@@ -146,6 +146,11 @@ void Mouse::setCursor(int cursor) {
}
}
+void Mouse::getXY(int *x, int *y) {
+ *x = _x;
+ *y = _y;
+}
+
void Mouse::disable() {
++_disabledCounter;
}
diff --git a/engines/bladerunner/mouse.h b/engines/bladerunner/mouse.h
index 8fb5f324a2..214089fed6 100644
--- a/engines/bladerunner/mouse.h
+++ b/engines/bladerunner/mouse.h
@@ -52,6 +52,8 @@ public:
void setCursor(int cursor);
+ void getXY(int *x, int *y);
+
void disable();
void enable();
bool isDisabled();
diff --git a/engines/bladerunner/script/ai.cpp b/engines/bladerunner/script/ai.cpp
index 492abc0974..c695886a61 100644
--- a/engines/bladerunner/script/ai.cpp
+++ b/engines/bladerunner/script/ai.cpp
@@ -91,6 +91,15 @@ void AIScripts::CompletedMovementTrack(int actor) {
}
}
+void AIScripts::ReceivedClue(int actor, int clueId, int fromActorId) {
+ assert(actor < _actorsCount);
+ _inScriptCounter++;
+ if (_AIScripts[actor]) {
+ _AIScripts[actor]->ReceivedClue(clueId, fromActorId);
+ }
+ _inScriptCounter--;
+}
+
void AIScripts::EnteredScene(int actor, int setId) {
assert(actor < _actorsCount);
_inScriptCounter++;
diff --git a/engines/bladerunner/script/ai.h b/engines/bladerunner/script/ai.h
index 00a9f8e819..c3fec411e9 100644
--- a/engines/bladerunner/script/ai.h
+++ b/engines/bladerunner/script/ai.h
@@ -104,7 +104,7 @@ DECLARE_SCRIPT(McCoy)
float off_45A100;
float flt_462710;
float flt_462714;
-
+
void sub_4053E0();
void sub_4054F0();
void sub_405660();
@@ -170,6 +170,7 @@ public:
void Update(int actor);
void TimerExpired(int actor, int timer);
void CompletedMovementTrack(int actor);
+ void ReceivedClue(int actor, int clueId, int fromActorId);
void EnteredScene(int actor, int setId);
void OtherAgentEnteredThisScene(int actor, int otherActorId);
void OtherAgentExitedThisScene(int actor, int otherActorId);
diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp
index ba78a42b4c..32528c9728 100644
--- a/engines/bladerunner/script/script.cpp
+++ b/engines/bladerunner/script/script.cpp
@@ -32,6 +32,7 @@
#include "bladerunner/audio_speech.h"
#include "bladerunner/crimes_database.h"
#include "bladerunner/combat.h"
+#include "bladerunner/dialogue_menu.h"
#include "bladerunner/gameflags.h"
#include "bladerunner/gameinfo.h"
#include "bladerunner/items.h"
@@ -896,47 +897,44 @@ void ScriptBase::Setup_Scene_Information(float actorX, float actorY, float actor
}
bool ScriptBase::Dialogue_Menu_Appear(int x, int y) {
- //TODO
- warning("Dialogue_Menu_Appear(%d, %d)", x, y);
+ if (!_vm->_dialogueMenu->isVisible()) {
+ return _vm->_dialogueMenu->show();
+ }
return false;
}
bool ScriptBase::Dialogue_Menu_Disappear() {
- //TODO
- warning("Dialogue_Menu_Disappear()");
+ if (_vm->_dialogueMenu->isVisible()) {
+ return _vm->_dialogueMenu->hide();
+ }
return false;
}
bool ScriptBase::Dialogue_Menu_Clear_List() {
- //TODO
- warning("Dialogue_Menu_Clear_List()");
+ _vm->_dialogueMenu->clearList();
return false;
}
bool ScriptBase::Dialogue_Menu_Add_To_List(int answer) {
- //TODO
- warning("Dialogue_Menu_Add_To_List(%d)", answer);
+ _vm->_dialogueMenu->addToList(answer, 0, 5, 5, 5);
return false;
}
bool ScriptBase::Dialogue_Menu_Add_DONE_To_List(int answerValue) {
- //TODO
- warning("Dialogue_Menu_Add_DONE_To_List(%d)", answerValue);
+ _vm->_dialogueMenu->addToList(answerValue, 1, 0, 0, 0);
return false;
}
-// Dialogue_Menu_Add_To_List_Never_Repeat_Once_Selected
+bool ScriptBase::Dialogue_Menu_Add_To_List_Never_Repeat_Once_Selected(int answer) {
+ return _vm->_dialogueMenu->addToListNeverRepeatOnceSelected(answer, 5, 5, 5);
+}
bool ScriptBase::DM_Add_To_List(int answer, int a2, int a3, int a4) {
- //TODO
- warning("DM_Add_To_List(%d, %d, %d, %d)", answer, a2, a3, a4);
- return false;
+ return _vm->_dialogueMenu->addToList(answer, 0, a2, a3, a4);
}
bool ScriptBase::DM_Add_To_List_Never_Repeat_Once_Selected(int answer, int a2, int a3, int a4) {
- //TODO
- warning("DM_Add_To_List_Never_Repeat_Once_Selected(%d, %d, %d, %d)", answer, a2, a3, a4);
- return false;
+ return _vm->_dialogueMenu->addToListNeverRepeatOnceSelected(answer, a2, a3, a4);
}
void ScriptBase::Dialogue_Menu_Remove_From_List(int answer) {
@@ -946,14 +944,11 @@ void ScriptBase::Dialogue_Menu_Remove_From_List(int answer) {
int ScriptBase::Dialogue_Menu_Query_Input() {
//TODO
- warning("Dialogue_Menu_Query_Input()");
- return 0;
+ return _vm->_dialogueMenu->queryInput();
}
int ScriptBase::Dialogue_Menu_Query_List_Size() {
- //TODO
- warning("Dialogue_Menu_Query_List_Size()");
- return 0;
+ return _vm->_dialogueMenu->listSize();
}
void ScriptBase::Scene_Exit_Add_2D_Exit(int index, int left, int top, int right, int down, int type) {
diff --git a/engines/bladerunner/script/script.h b/engines/bladerunner/script/script.h
index 94112a9e42..93c955dedd 100644
--- a/engines/bladerunner/script/script.h
+++ b/engines/bladerunner/script/script.h
@@ -587,7 +587,7 @@ protected:
bool Dialogue_Menu_Clear_List();
bool Dialogue_Menu_Add_To_List(int answer);
bool Dialogue_Menu_Add_DONE_To_List(int answer);
- // Dialogue_Menu_Add_To_List_Never_Repeat_Once_Selected
+ bool Dialogue_Menu_Add_To_List_Never_Repeat_Once_Selected(int answer);
bool DM_Add_To_List(int answer, int a2, int a3, int a4);
bool DM_Add_To_List_Never_Repeat_Once_Selected(int answer, int a2, int a3, int a4);
void Dialogue_Menu_Remove_From_List(int answer);
diff --git a/engines/bladerunner/shape.h b/engines/bladerunner/shape.h
index e2e77b1a76..cd06e79a24 100644
--- a/engines/bladerunner/shape.h
+++ b/engines/bladerunner/shape.h
@@ -47,6 +47,9 @@ public:
bool readFromContainer(const Common::String &container, int index);
void draw(Graphics::Surface &surface, int x, int y);
+
+ int getWidth() const { return _width; }
+ int getHeight() const { return _height; }
};
} // End of namespace BladeRunner
diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp
index 0bc1e8a2a0..2d3566c222 100644
--- a/engines/saga/music.cpp
+++ b/engines/saga/music.cpp
@@ -129,7 +129,6 @@ void MusicDriver::play(SagaEngine *vm, ByteArray *buffer, bool loop) {
// Handle music looping
_parser->property(MidiParser::mpAutoLoop, loop);
-// _isLooping = loop;
_isPlaying = true;
}
@@ -150,7 +149,6 @@ void MusicDriver::playQuickTime(const Common::String &musicName, bool loop) {
// Handle music looping
_parser->property(MidiParser::mpAutoLoop, loop);
-// _isLooping = loop;
_isPlaying = true;
}
diff --git a/engines/saga/saveload.cpp b/engines/saga/saveload.cpp
index 1a131bf5cc..a687a68046 100644
--- a/engines/saga/saveload.cpp
+++ b/engines/saga/saveload.cpp
@@ -381,6 +381,12 @@ void SagaEngine::load(const char *fileName) {
_music->setVolume(volume);
_interface->draw();
+
+ // Abort any scene entry protagonist animations and auto-cue speeches.
+ // Fixes bug #10009.
+ _actor->abortAllSpeeches();
+ _actor->_protagonist->_location = _actor->_protagonist->_finalTarget;
+ _actor->actorEndWalk(ID_PROTAG, true);
}
} // End of namespace Saga
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 89179dac97..8ec1575af0 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -904,6 +904,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "spyfox", "spyfox", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "spyfox", "Fuchsdem", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 },
+ { "spyfox", "FUCHS", kGenHEPC, Common::DE_DEU, Common::kPlatformWindows, 0 },
{ "spyfox", "FUCHSDEM", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "spyfox", "FoxDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "spyfox", "foxdemo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 5b552841e3..6cc2fbdc04 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 Wed Aug 09 23:27:38 2017
+ This file was generated by the md5table tool on Mon Aug 21 13:35:07 2017
DO NOT EDIT MANUALLY!
*/
@@ -17,6 +17,7 @@ static const MD5Table md5table[] = {
{ "008e76ec3ae58d0add637ea7aa299a2c", "freddi3", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "02cae0e7ff8504f73618391873d5781a", "freddi3", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "0305e850382b812fec6e5998ef88a966", "pajama", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
+ { "03173f0df12062d84721062666155efa", "farm", "HE 71", "Demo", 34312, Common::EN_ANY, Common::kPlatformWindows },
{ "0354ee0d14cde1264ec762261c04c14a", "loom", "Steam", "Steam", 585728, Common::EN_ANY, Common::kPlatformWindows },
{ "035deab53b47bc43abc763560d0f8d4b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformDOS },
{ "037385a953789190298494d92b89b3d0", "catalog", "HE 72", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
@@ -96,6 +97,7 @@ static const MD5Table md5table[] = {
{ "19bf6938a94698296bcb0c99c31c91a7", "spyfox2", "", "Demo", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "1a6e5ae2777a6a33f06ffc0226210934", "atlantis", "", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "1af4eb581a33d808707d66d50e084dca", "pajama2", "HE 99", "", -1, Common::HE_ISR, Common::kPlatformWindows },
+ { "1b3a7f67d688f44d0e54da839923d3a3", "spyfox", "HE 100", "", 49742, Common::NL_NLD, Common::kPlatformWii },
{ "1b720def35ecfa07032ddf1efb34c368", "dog", "", "", 19681, Common::NL_NLD, Common::kPlatformUnknown },
{ "1c792d28376d45e145cb916bca0400a2", "spyfox2", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "1c7e7db2cfab1ad62746ab680a634204", "maniac", "NES", "", -1, Common::FR_FRA, Common::kPlatformNES },
@@ -148,6 +150,7 @@ static const MD5Table md5table[] = {
{ "2d9d46f23cb07bbc90b8ad464d3e4ff8", "atlantis", "", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "2e85f7aa054930c692a5b1bed1dfc295", "football2002", "", "Patched", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "2e8a1f76ea33bc5e04347646feee173d", "pajama3", "", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
+ { "2f7583da072d027057983c43bb3fa53f", "spyfox", "HE 100", "", 49742, Common::EN_GRB, Common::kPlatformWii },
{ "2fe369ad70f52a8cf7ad6077ee64f81a", "loom", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformAmiga },
{ "305d3dd57c96c65b017bc70c8c7cfb5e", "monkey", "CD", "CD", 8955, Common::DE_DEU, Common::kPlatformDOS },
{ "30ba1e825d4ad2b448143ae8df18482a", "pajama2", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
@@ -307,6 +310,7 @@ static const MD5Table md5table[] = {
{ "68530d2e15f339fbbf3150b78b4d2ffb", "freddi", "HE 73", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "688328c5bdc4c8ec4145688dfa077bf2", "freddi4", "HE 99", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "6886e5d08cee329b1f2e743ae2e3ceed", "monkey2", "", "", 11135, Common::DE_DEU, Common::kPlatformDOS },
+ { "68e4bf77136cb3165e65d5c197ce65bd", "spyfox", "", "", 49221, Common::DE_DEU, Common::kPlatformWindows },
{ "695fe0b3963333b7e15b37514db3c745", "thinkerk", "", "Demo", 29789, Common::EN_USA, Common::kPlatformUnknown },
{ "697c9b7c55a05d8199c48b48e379d2c8", "puttmoon", "", "", -1, Common::HE_ISR, Common::kPlatformDOS },
{ "69d70269fafc4445adbb0d223e4f9a3f", "indy3", "EGA", "EGA", 5361, Common::EN_ANY, Common::kPlatformDOS },
@@ -332,6 +336,7 @@ static const MD5Table md5table[] = {
{ "6e959d65358eedf9b68b81e304b97fa4", "tentacle", "", "CD", 7932, Common::DE_DEU, Common::kPlatformUnknown },
{ "6ea966b4d660c870b9ee790d1fbfc535", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformAmiga },
{ "6f0be328c64d689bb606d22a389e1b0f", "loom", "No AdLib", "EGA", 5748, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "6f4d64ce1b44470536cae2eb6fe8aefd", "spyfox", "HE 100", "", 49742, Common::FR_FRA, Common::kPlatformWii },
{ "6f6ef668c608c7f534fea6e6d3878dde", "indy3", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformDOS },
{ "6f8a22bfa397be1f7ed4b74aba0e397e", "loom", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformDOS },
{ "701246819d1a70573f41bf33fc19214f", "soccer", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -507,6 +512,7 @@ static const MD5Table md5table[] = {
{ "aef415cc5dc063e3668359c2657169f3", "PuttTime", "HE 99", "Mini Game", 18458, Common::DE_DEU, Common::kPlatformWindows },
{ "aefa244ea034b7cd2041f0a44be7d9ba", "pajama3", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "af2bd1a43b50b55915d87994e093203d", "freddi", "HE 99", "Updated", 34829, Common::DE_DEU, Common::kPlatformWindows },
+ { "afd74ce452df9cca6ebc023276b4772a", "spyfox", "HE 100", "", 49742, Common::DE_DEU, Common::kPlatformWii },
{ "b100abf7ff83146df50db78dbd5e9cfa", "freddicove", "HE 100", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "b23f7cd7c304d7dff08e92a96120d5b4", "zak", "V1", "V1", -1, Common::EN_ANY, Common::kPlatformDOS },
{ "b250d0f9cc83f80ced56fe11a4fb057c", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformDOS },
@@ -535,6 +541,7 @@ static const MD5Table md5table[] = {
{ "c0039ad982999c92d0de81910d640fa0", "freddi", "HE 71", "", 26159, Common::NL_NLD, Common::kPlatformWindows },
{ "c0c9de81fb965e6cbe77f6e5631ca705", "monkey", "SE Talkie", "Unofficial SE Talkie v1.02", 9135, Common::EN_ANY, Common::kPlatformDOS },
{ "c13225cb1bbd3bc9fe578301696d8021", "monkey", "SEGA", "", -1, Common::EN_ANY, Common::kPlatformSegaCD },
+ { "c13fdcdd2ecaa346f80d1c61782208be", "catalog", "", "Demo", 28539, Common::EN_ANY, Common::kPlatformWindows },
{ "c20848f53c2d48bfacdc840993843765", "freddi2", "HE 80", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "c225bec1b6c0798a2b8c89ac226dc793", "pajama", "HE 101", "", -1, Common::EN_ANY, Common::kPlatformWii },
{ "c24c490373aeb48fbd54caa8e7ae376d", "loom", "No AdLib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST },
@@ -627,7 +634,9 @@ static const MD5Table md5table[] = {
{ "e1c9998826ce7fa8bde5cc3a5023edec", "moonbase", "1.1", "1.1", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "e246e02db9630533a40d99c9f54a8e01", "monkey2", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "e361a7058ed8e8ebb462663c0a3ae8d6", "puttputt", "HE 62", "", -1, Common::HE_ISR, Common::kPlatformDOS },
+ { "e3f1f2b6ca7b55076782872cb8ff0985", "freddi", "HE 71", "Demo", 9779, Common::EN_ANY, Common::kPlatformWindows },
{ "e41de1c2a15abbcdbf9977e2d7e8a340", "freddi2", "HE 100", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows },
+ { "e441af0b65983c1a4b3a52f9c7b15484", "spyfox", "HE 100", "", 49742, Common::EN_USA, Common::kPlatformWii },
{ "e44ea295a3f8fe4f41983080dab1e9ce", "freddi", "HE 90", "Updated", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "e534d29afb3c6e0ee9dc3d53c5956714", "atlantis", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga },
{ "e5563c8358443c4352fcddf7402a5e0a", "pajama2", "HE 98.5", "", -1, Common::FR_FRA, Common::kPlatformWindows },
diff --git a/engines/sludge/builtin.cpp b/engines/sludge/builtin.cpp
index d63eb972b5..9b4c1b7622 100644
--- a/engines/sludge/builtin.cpp
+++ b/engines/sludge/builtin.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "common/config-manager.h"
#include "common/savefile.h"
#include "sludge/allfiles.h"
@@ -2412,11 +2413,29 @@ builtIn(_rem_launchWith) {
UNUSEDALL
trimStack(fun->stack);
+
+ // To support some windows only games
+ Common::String filename = getTextFromAnyVar(fun->stack->thisVar);
trimStack(fun->stack);
- setVariable(fun->reg, SVT_INT, false);
- return BR_CONTINUE;
+ if (filename.hasSuffix(".exe")) {
+ const Common::FSNode gameDataDir(ConfMan.get("path"));
+ Common::FSList files;
+ gameDataDir.getChildren(files, Common::FSNode::kListFilesOnly);
+
+ for (Common::FSList::const_iterator file = files.begin(); file != files.end(); ++file) {
+ Common::String fileName = file->getName();
+ fileName.toLowercase();
+ if (fileName.hasSuffix(".dat") || fileName == "data") {
+ g_sludge->launchNext = file->getName();
+ return BR_CONTINUE;
+ }
+ }
+ }
+ g_sludge->launchNext.clear();
+ setVariable(fun->reg, SVT_INT, false);
+ return BR_CONTINUE;
}
builtIn(getFramesPerSecond) {
@@ -2577,8 +2596,9 @@ BuiltReturn callBuiltIn(int whichFunc, int numParams, LoadedFunction *fun) {
}
if (builtInFunctionArray[whichFunc].func) {
- debugC(1, kSludgeDebugBuiltin, "Run built-in function : %s",
- (whichFunc < numBIFNames) ? allBIFNames[whichFunc].c_str() : "Unknown");
+ debugC(3, kSludgeDebugBuiltin,
+ "Run built-in function %i : %s",
+ whichFunc, (whichFunc < numBIFNames) ? allBIFNames[whichFunc].c_str() : "Unknown");
return builtInFunctionArray[whichFunc].func(numParams, fun);
}
}
diff --git a/engines/sludge/cursors.cpp b/engines/sludge/cursors.cpp
index 7c16e8fa19..0c7745e9ff 100644
--- a/engines/sludge/cursors.cpp
+++ b/engines/sludge/cursors.cpp
@@ -36,13 +36,22 @@ namespace Sludge {
CursorManager::CursorManager(SludgeEngine *vm) {
_vm = vm;
+ init();
+}
+
+CursorManager::~CursorManager() {
+ kill();
+}
+
+void CursorManager::init() {
_mouseCursorAnim = makeNullAnim();
_mouseCursorFrameNum = 0;
_mouseCursorCountUp = 0;
}
-CursorManager::~CursorManager() {
-
+void CursorManager::kill() {
+ deleteAnim(_mouseCursorAnim);
+ _mouseCursorAnim = nullptr;
}
void CursorManager::pickAnimCursor(PersonaAnimation *pp) {
diff --git a/engines/sludge/cursors.h b/engines/sludge/cursors.h
index 5fd1885f69..4229900a94 100644
--- a/engines/sludge/cursors.h
+++ b/engines/sludge/cursors.h
@@ -34,6 +34,9 @@ public:
CursorManager(SludgeEngine *vm);
virtual ~CursorManager();
+ void init();
+ void kill();
+
// cursor
void pickAnimCursor(struct PersonaAnimation *pp);
void displayCursor();
diff --git a/engines/sludge/detection_tables.h b/engines/sludge/detection_tables.h
index abdfde51ae..c5bf3d6185 100644
--- a/engines/sludge/detection_tables.h
+++ b/engines/sludge/detection_tables.h
@@ -127,15 +127,13 @@ static const SludgeGameDescription gameDescriptions[] = {
0
},
- // TODO: the games down here are windows-only and can't be successfully run by
- // sludge engine nor scummvm, need to solve it
{
{
"tgttpoacs",
"",
AD_ENTRY1s("gamedata", "d5ec4d7d8440f7744335d25d25e1e943", 40368),
Common::EN_ANY,
- Common::kPlatformUnknown,
+ Common::kPlatformWindows,
ADGF_NO_FLAGS,
GUIO0()
},
@@ -144,11 +142,11 @@ static const SludgeGameDescription gameDescriptions[] = {
{
{
- "mandy",
+ "tgttpoacs",
"",
- AD_ENTRY1s("gamedata", "bb51eea418d87071c98f4e050ccf6387", 589),
+ AD_ENTRY1s("tgttpoacs.dat", "e61d3d050793689d55487d3ad01b6693", 23817174),
Common::EN_ANY,
- Common::kPlatformUnknown,
+ Common::kPlatformLinux,
ADGF_NO_FLAGS,
GUIO0()
},
@@ -157,17 +155,121 @@ static const SludgeGameDescription gameDescriptions[] = {
{
{
+ "mandy",
+ "",
+ AD_ENTRY1s("data", "705f6ca5f5da0c40c1f547231dd5139f", 7141292),
+ Common::CZ_CZE,
+ Common::kPlatformLinux,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+ 0
+ },
+
+ {
+ {
+ "mandy",
+ "",
+ AD_ENTRY1s("data", "705f6ca5f5da0c40c1f547231dd5139f", 7141292),
+ Common::EN_ANY,
+ Common::kPlatformLinux,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+ 1
+ },
+
+ {
+ {
+ "mandy",
+ "",
+ AD_ENTRY1s("data", "705f6ca5f5da0c40c1f547231dd5139f", 7141292),
+ Common::IT_ITA,
+ Common::kPlatformLinux,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+ 2
+ },
+
+ {
+ {
+ "mandy",
+ "",
+ AD_ENTRY1s("data", "705f6ca5f5da0c40c1f547231dd5139f", 7141292),
+ Common::PL_POL,
+ Common::kPlatformLinux,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+ 3
+ },
+
+ {
+ {
"cubert",
"",
AD_ENTRY1s("gamedata", "0078eb54f63cc0a22e50f17d904fcfde", 26799),
Common::UNK_LANG,
- Common::kPlatformUnknown,
+ Common::kPlatformWindows,
ADGF_NO_FLAGS,
GUIO0()
},
0
},
+ {
+ {
+ "cubert",
+ "",
+ AD_ENTRY1s("cubert.dat", "e70050692a0ab96e8753109793157ccd", 19677815),
+ Common::EN_ANY,
+ Common::kPlatformLinux,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+ 0
+ },
+
+ {
+ {
+ "cubert",
+ "",
+ AD_ENTRY1s("cubert.dat", "e70050692a0ab96e8753109793157ccd", 19677815),
+ Common::IT_ITA,
+ Common::kPlatformLinux,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+ 1
+ },
+
+ {
+ {
+ "cubert",
+ "",
+ AD_ENTRY1s("cubert.dat", "e70050692a0ab96e8753109793157ccd", 19677815),
+ Common::SE_SWE,
+ Common::kPlatformLinux,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+ 2
+ },
+
+ {
+ {
+ "cubert",
+ "",
+ AD_ENTRY1s("cubert.dat", "e70050692a0ab96e8753109793157ccd", 19677815),
+ Common::DE_DEU,
+ Common::kPlatformLinux,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+ 3
+ },
+
{ AD_TABLE_END_MARKER, 0 }
};
diff --git a/engines/sludge/event.cpp b/engines/sludge/event.cpp
index c2997be078..d5c453bdc1 100644
--- a/engines/sludge/event.cpp
+++ b/engines/sludge/event.cpp
@@ -41,21 +41,31 @@ extern ScreenRegion *lastRegion;
EventManager::EventManager(SludgeEngine *vm) {
_vm = vm;
+ _currentEvents = new EventHandlers;
+ init();
+}
+EventManager::~EventManager() {
+ kill();
+ if (_currentEvents) {
+ delete _currentEvents;
+ _currentEvents = nullptr;
+ }
+}
+
+void EventManager::init() {
_weAreDoneSoQuit = 0;
_reallyWantToQuit = false;
_input.leftClick = _input.rightClick = _input.justMoved = _input.leftRelease = _input.rightRelease = false;
_input.keyPressed = 0;
- _currentEvents = new EventHandlers;
for (uint i = 0; i < EVENT_FUNC_NB; ++i) {
_currentEvents->func[i] = 0;
}
}
-EventManager::~EventManager() {
-
+void EventManager::kill() {
}
void EventManager::checkInput() {
diff --git a/engines/sludge/event.h b/engines/sludge/event.h
index 691a0daa82..015e9ea1cb 100644
--- a/engines/sludge/event.h
+++ b/engines/sludge/event.h
@@ -56,6 +56,9 @@ public:
EventManager(SludgeEngine *vm);
virtual ~EventManager();
+ void init();
+ void kill();
+
// Input
void checkInput();
bool handleInput();
@@ -73,6 +76,7 @@ public:
void restore(FrozenStuffStruct *frozenStuff);
// Quit
+ void startGame() { _weAreDoneSoQuit = false; }
void quitGame() { _weAreDoneSoQuit = true; /* _reallyWantToQuit = true; */ }
bool quit() { return _weAreDoneSoQuit; }
diff --git a/engines/sludge/fileset.cpp b/engines/sludge/fileset.cpp
index c9cdefd512..b04c68c1cb 100644
--- a/engines/sludge/fileset.cpp
+++ b/engines/sludge/fileset.cpp
@@ -31,6 +31,30 @@
namespace Sludge {
+ResourceManager::ResourceManager() {
+ init();
+}
+
+ResourceManager::~ResourceManager() {
+ kill();
+}
+
+void ResourceManager::init() {
+ _sliceBusy = true;
+ _bigDataFile = nullptr;
+ _startOfDataIndex = 0;
+ _startOfTextIndex = 0;
+ _startOfSubIndex = 0;
+ _startOfObjectIndex = 0;
+ _startIndex = 0;
+}
+void ResourceManager::kill() {
+ if (_bigDataFile) {
+ delete _bigDataFile;
+ _bigDataFile = nullptr;
+ }
+}
+
bool ResourceManager::openSubSlice(int num) {
if (_sliceBusy) {
fatal("Can't read from data file", "I'm already reading something");
diff --git a/engines/sludge/fileset.h b/engines/sludge/fileset.h
index 9cde705a55..3ba0a2bc48 100644
--- a/engines/sludge/fileset.h
+++ b/engines/sludge/fileset.h
@@ -29,14 +29,11 @@ namespace Sludge {
class ResourceManager {
public:
- ResourceManager():
- _sliceBusy(true),
- _bigDataFile(0),
- _startOfDataIndex(0),
- _startOfTextIndex(0),
- _startOfSubIndex(0),
- _startOfObjectIndex(0),
- _startIndex(0) {}
+ ResourceManager();
+ ~ResourceManager();
+
+ void init();
+ void kill();
void setData(Common::File *readStream);
void setFileIndices(uint, uint);
diff --git a/engines/sludge/floor.cpp b/engines/sludge/floor.cpp
index dff6980c7c..45a7501470 100644
--- a/engines/sludge/floor.cpp
+++ b/engines/sludge/floor.cpp
@@ -105,16 +105,18 @@ bool initFloor() {
}
void killFloor() {
- for (int i = 0; i < currentFloor->numPolygons; i++) {
- delete []currentFloor->polygon[i].vertexID;
- delete []currentFloor->matrix[i];
+ if (currentFloor) {
+ for (int i = 0; i < currentFloor->numPolygons; i++) {
+ delete []currentFloor->polygon[i].vertexID;
+ delete []currentFloor->matrix[i];
+ }
+ delete []currentFloor->polygon;
+ currentFloor->polygon = NULL;
+ delete []currentFloor->vertex;
+ currentFloor->vertex = NULL;
+ delete []currentFloor->matrix;
+ currentFloor->matrix = NULL;
}
- delete []currentFloor->polygon;
- currentFloor->polygon = NULL;
- delete []currentFloor->vertex;
- currentFloor->vertex = NULL;
- delete []currentFloor->matrix;
- currentFloor->matrix = NULL;
}
void setFloorNull() {
diff --git a/engines/sludge/fonttext.cpp b/engines/sludge/fonttext.cpp
index 4c273fec22..787e95e6f3 100644
--- a/engines/sludge/fonttext.cpp
+++ b/engines/sludge/fonttext.cpp
@@ -32,6 +32,14 @@
namespace Sludge {
TextManager::TextManager() {
+ init();
+}
+
+TextManager::~TextManager() {
+ kill();
+}
+
+void TextManager::init() {
_theFont.total = 0;
_theFont.sprites = nullptr;
@@ -40,20 +48,15 @@ TextManager::TextManager() {
_loadedFontNum = 0;
_fontSpace = -1;
- _fontTable = nullptr;
- _fontTableSize = 0;
+ _fontTable.clear();
}
-TextManager::~TextManager() {
- if (_fontTable) {
- delete []_fontTable;
- _fontTable = nullptr;
- }
-
+void TextManager::kill() {
+ GraphicsManager::forgetSpriteBank(_theFont);
}
bool TextManager::isInFont(const Common::String &theText) {
- if (!_fontTableSize)
+ if (_fontTable.empty())
return 0;
if (theText.empty())
return 0;
@@ -78,7 +81,7 @@ int TextManager::stringLength(const Common::String &theText) {
int TextManager::stringWidth(const Common::String &theText) {
int xOff = 0;
- if (!_fontTableSize)
+ if (_fontTable.empty())
return 0;
Common::U32String str32 = UTF8Converter::convertUtf8ToUtf32(theText);
@@ -92,7 +95,7 @@ int TextManager::stringWidth(const Common::String &theText) {
}
void TextManager::pasteString(const Common::String &theText, int xOff, int y, SpritePalette &thePal) {
- if (!_fontTableSize)
+ if (_fontTable.empty())
return;
xOff += (int)((float)(_fontSpace >> 1) / g_sludge->_gfxMan->getCamZoom());
@@ -108,7 +111,7 @@ void TextManager::pasteString(const Common::String &theText, int xOff, int y, Sp
}
void TextManager::pasteStringToBackdrop(const Common::String &theText, int xOff, int y, SpritePalette &thePal) {
- if (!_fontTableSize)
+ if (_fontTable.empty())
return;
Common::U32String str32 = UTF8Converter::convertUtf8ToUtf32(theText);
@@ -123,7 +126,7 @@ void TextManager::pasteStringToBackdrop(const Common::String &theText, int xOff,
}
void TextManager::burnStringToBackdrop(const Common::String &theText, int xOff, int y, SpritePalette &thePal) {
- if (!_fontTableSize)
+ if (_fontTable.empty())
return;
Common::U32String str32 = UTF8Converter::convertUtf8ToUtf32(theText);
@@ -152,25 +155,10 @@ bool TextManager::loadFont(int filenum, const Common::String &charOrder, int h)
// get max value among all utf8 chars
Common::U32String fontOrderString = _fontOrder.getU32String();
- _fontTableSize = 0;
- for (uint32 i = 0; i < fontOrderString.size(); ++i) {
- uint32 c = fontOrderString[i];
- if (c > _fontTableSize)
- _fontTableSize = c;
- }
- _fontTableSize++;
// create an index table from utf8 char to the index
- if (_fontTable) {
- delete []_fontTable;
- _fontTable = nullptr;
- }
- _fontTable = new uint32[_fontTableSize];
- if (!checkNew(_fontTable))
- return false;
-
- for (uint i = 0; i < _fontTableSize; i++) {
- _fontTable[i] = 0;
+ if (!_fontTable.empty()) {
+ _fontTable.clear();
}
for (uint i = 0; i < fontOrderString.size(); ++i) {
@@ -190,8 +178,8 @@ bool TextManager::loadFont(int filenum, const Common::String &charOrder, int h)
// load & save
void TextManager::saveFont(Common::WriteStream *stream) {
- stream->writeByte(_fontTableSize > 0);
- if (_fontTableSize > 0) {
+ stream->writeByte(!_fontTable.empty());
+ if (!_fontTable.empty() > 0) {
stream->writeUint16BE(_loadedFontNum);
stream->writeUint16BE(_fontHeight);
writeString(_fontOrder.getUTF8String(), stream);
diff --git a/engines/sludge/fonttext.h b/engines/sludge/fonttext.h
index 3170a3e12f..26b12d9f11 100644
--- a/engines/sludge/fonttext.h
+++ b/engines/sludge/fonttext.h
@@ -22,6 +22,7 @@
#ifndef SLUDGE_FONTTEXT_H
#define SLUDGE_FONTTEXT_H
+#include "common/hashmap.h"
#include "common/ustr.h"
#include "sludge/sprites.h"
@@ -37,6 +38,9 @@ public:
TextManager();
virtual ~TextManager();
+ void init();
+ void kill();
+
int stringWidth(const Common::String &theText);
int stringLength(const Common::String &theText);
@@ -59,10 +63,9 @@ private:
UTF8Converter _fontOrder;
int16 _fontSpace;
- uint32 *_fontTable;
- uint _fontTableSize;
+ Common::HashMap<uint32, uint32> _fontTable;
- inline uint32 fontInTable(uint32 x) { return ((x < _fontTableSize) ? _fontTable[x] : 0); }
+ inline uint32 fontInTable(uint32 x) { return _fontTable[x]; }
};
diff --git a/engines/sludge/graphics.cpp b/engines/sludge/graphics.cpp
index eecf52231f..3bcb5aa043 100644
--- a/engines/sludge/graphics.cpp
+++ b/engines/sludge/graphics.cpp
@@ -37,7 +37,14 @@ namespace Sludge {
GraphicsManager::GraphicsManager(SludgeEngine *vm) {
_vm = vm;
+ init();
+}
+GraphicsManager::~GraphicsManager() {
+ kill();
+}
+
+void GraphicsManager::init() {
// Init screen surface
_winWidth = _sceneWidth = 640;
_winHeight = _sceneHeight = 480;
@@ -78,11 +85,13 @@ GraphicsManager::GraphicsManager(SludgeEngine *vm) {
_currentBurnB = 0;
}
-GraphicsManager::~GraphicsManager() {
+void GraphicsManager::kill() {
// kill parallax
- killParallax();
- delete _parallaxStuff;
- _parallaxStuff = nullptr;
+ if (_parallaxStuff) {
+ _parallaxStuff->kill();
+ delete _parallaxStuff;
+ _parallaxStuff = nullptr;
+ }
// kill frozen stuff
FrozenStuffStruct *killMe = _frozenStuff;
@@ -98,9 +107,11 @@ GraphicsManager::~GraphicsManager() {
}
// kill sprite layers
- killSpriteLayers();
- delete _spriteLayers;
- _spriteLayers = nullptr;
+ if (_spriteLayers) {
+ killSpriteLayers();
+ delete _spriteLayers;
+ _spriteLayers = nullptr;
+ }
// kill sprite banks
LoadedSpriteBanks::iterator it;
@@ -111,9 +122,11 @@ GraphicsManager::~GraphicsManager() {
_allLoadedBanks.clear();
// kill zbuffer
- killZBuffer();
- delete _zBuffer;
- _zBuffer = nullptr;
+ if (_zBuffer) {
+ killZBuffer();
+ delete _zBuffer;
+ _zBuffer = nullptr;
+ }
// kill surfaces
if (_renderSurface.getPixels())
@@ -129,13 +142,15 @@ GraphicsManager::~GraphicsManager() {
_origBackdropSurface.free();
}
-bool GraphicsManager::init() {
+bool GraphicsManager::initGfx() {
initGraphics(_winWidth, _winHeight, true, _vm->getScreenPixelFormat());
_renderSurface.create(_winWidth, _winHeight, *_vm->getScreenPixelFormat());
if (!killResizeBackdrop(_winWidth, _winHeight))
return fatal("Couldn't allocate memory for backdrop");
+ blankAllScreen();
+
return true;
}
diff --git a/engines/sludge/graphics.h b/engines/sludge/graphics.h
index c5914c712b..16973a1658 100644
--- a/engines/sludge/graphics.h
+++ b/engines/sludge/graphics.h
@@ -57,9 +57,12 @@ public:
GraphicsManager(SludgeEngine *vm);
virtual ~GraphicsManager();
+ void init();
+ void kill();
+
// graphics
void setWindowSize(uint winWidth, uint winHeight) { _winWidth = winWidth; _winHeight = winHeight; }
- bool init();
+ bool initGfx();
void display();
void clear();
@@ -125,7 +128,7 @@ public:
bool isFrozen() { return (_frozenStuff != nullptr); }
// Sprites
- void forgetSpriteBank(SpriteBank &forgetme);
+ static void forgetSpriteBank(SpriteBank &forgetme);
bool loadSpriteBank(char *filename, SpriteBank &loadhere);
bool loadSpriteBank(int fileNum, SpriteBank &loadhere, bool isFont);
diff --git a/engines/sludge/imgloader.cpp b/engines/sludge/imgloader.cpp
index 64c8d7806f..c909ad5b62 100644
--- a/engines/sludge/imgloader.cpp
+++ b/engines/sludge/imgloader.cpp
@@ -33,7 +33,7 @@
namespace Sludge {
bool ImgLoader::loadImage(Common::SeekableReadStream *stream, Graphics::Surface *dest, int reserve) {
- debugC(3, kSludgeDebugDataLoad, "Loading image at position: %i", stream->pos());
+ debugC(3, kSludgeDebugGraphics, "Loading image at position: %i", stream->pos());
int32 start_ptr = stream->pos();
if (!loadPNGImage(stream, dest)) {
stream->seek(start_ptr);
diff --git a/engines/sludge/language.cpp b/engines/sludge/language.cpp
index 858c44dd19..8bd9d51493 100644
--- a/engines/sludge/language.cpp
+++ b/engines/sludge/language.cpp
@@ -32,19 +32,35 @@
namespace Sludge {
+LanguageManager::LanguageManager() {
+ init();
+}
+
LanguageManager::~LanguageManager() {
+ kill();
+}
+
+void LanguageManager::init() {
+ _languageID = 0;
+ _languageIdx = -1;
+ _numLanguages = 0;
+ _languageTable = nullptr;
+ _languageNames = nullptr;
+}
+
+void LanguageManager::kill() {
if (_languageTable) {
delete []_languageTable;
- _languageTable = NULL;
+ _languageTable = nullptr;
}
if (_languageNames) {
delete []_languageNames;
- _languageNames = NULL;
+ _languageNames = nullptr;
}
}
-void LanguageManager::init(Common::File *fp) {
+void LanguageManager::createTable(Common::File *fp) {
// get number of languages
_numLanguages =
(gameVersion >= VERSION(1, 3)) ? (fp->readByte()) : 0;
diff --git a/engines/sludge/language.h b/engines/sludge/language.h
index 9d3f2d2d12..26b57ad76e 100644
--- a/engines/sludge/language.h
+++ b/engines/sludge/language.h
@@ -30,15 +30,13 @@ namespace Sludge {
class LanguageManager {
public:
- LanguageManager() :
- _languageID(0),
- _languageIdx(-1),
- _numLanguages(0),
- _languageTable(0),
- _languageNames(0) {}
+ LanguageManager();
~LanguageManager();
- void init(Common::File *table);
+ void init();
+ void kill();
+
+ void createTable(Common::File *table);
void setLanguageID(uint id);
void saveLanguageSetting(Common::WriteStream *writeStream);
void loadLanguageSetting(Common::SeekableReadStream *readStream);
diff --git a/engines/sludge/main_loop.cpp b/engines/sludge/main_loop.cpp
index 708d4df910..fc164dfd57 100644
--- a/engines/sludge/main_loop.cpp
+++ b/engines/sludge/main_loop.cpp
@@ -20,7 +20,6 @@
*
*/
-#include "common/config-manager.h"
#include "common/debug.h"
#include "graphics/surface.h"
@@ -34,6 +33,7 @@
#include "sludge/newfatal.h"
#include "sludge/objtypes.h"
#include "sludge/people.h"
+#include "sludge/region.h"
#include "sludge/statusba.h"
#include "sludge/sound.h"
#include "sludge/sludge.h"
@@ -48,33 +48,17 @@ extern VariableStack *noStack;
int dialogValue = 0;
-int main_loop(const char *filename) {
+int main_loop(Common::String filename) {
if (!initSludge(filename)) {
return 0;
}
- g_sludge->_gfxMan->init();
-
- registerWindowForFatal();
-
- g_sludge->_gfxMan->blankAllScreen();
- if (!initPeople())
- return fatal("Couldn't initialise people stuff");
- if (!initFloor())
- return fatal("Couldn't initialise floor stuff");
- if (!g_sludge->_objMan->initObjectTypes())
- return fatal("Couldn't initialise object type stuff");
- initSpeech();
- initStatusBar();
- resetRandW();
-
- if (!ConfMan.hasKey("mute") || !ConfMan.getBool("mute")) {
- g_sludge->_soundMan->initSoundStuff();
- }
+ g_sludge->_gfxMan->initGfx();
startNewFunctionNum(0, 0, NULL, noStack);
+ g_sludge->_evtMan->startGame();
g_sludge->_timer.init();
while (!g_sludge->_evtMan->quit()) {
@@ -88,7 +72,14 @@ int main_loop(const char *filename) {
g_sludge->_timer.waitFrame();
}
- g_sludge->_soundMan->killSoundStuff();
+ killSludge();
+
+ // Load next game
+ if (!g_sludge->launchNext.empty()) {
+ Common::String name = g_sludge->launchNext;
+ g_sludge->launchNext.clear();
+ main_loop(name);
+ }
return (0);
}
diff --git a/engines/sludge/main_loop.h b/engines/sludge/main_loop.h
index b287c8105e..3fe522c925 100644
--- a/engines/sludge/main_loop.h
+++ b/engines/sludge/main_loop.h
@@ -24,7 +24,7 @@
namespace Sludge {
-int main_loop(const char *filename);
+int main_loop(Common::String filename);
} // End of namespace Sludge
diff --git a/engines/sludge/moreio.cpp b/engines/sludge/moreio.cpp
index 4a57000549..1512574207 100644
--- a/engines/sludge/moreio.cpp
+++ b/engines/sludge/moreio.cpp
@@ -46,7 +46,6 @@ Common::String readString(Common::SeekableReadStream *stream) {
for (int a = 0; a < len; a++) {
res += (char)(stream->readByte() - 1);
}
- debugC(3, kSludgeDebugDataLoad, "Read string of length %i: %s", len, res.c_str());
return res;
}
diff --git a/engines/sludge/newfatal.cpp b/engines/sludge/newfatal.cpp
index 673fc023c8..70f6bd9209 100644
--- a/engines/sludge/newfatal.cpp
+++ b/engines/sludge/newfatal.cpp
@@ -53,10 +53,6 @@ bool hasFatal() {
return false;
}
-void registerWindowForFatal() {
- g_sludge->fatalInfo = "There's an error with this SLUDGE game! If you're designing this game, please turn on verbose error messages in the project manager and recompile. If not, please contact the author saying where and how this problem occured.";
-}
-
int inFatal(const Common::String &str) {
g_sludge->_soundMan->killSoundStuff();
error("%s", str.c_str());
diff --git a/engines/sludge/newfatal.h b/engines/sludge/newfatal.h
index eb65db065b..fc91110758 100644
--- a/engines/sludge/newfatal.h
+++ b/engines/sludge/newfatal.h
@@ -33,7 +33,6 @@ bool hasFatal();
int fatal(const Common::String &str);
int fatal(const Common::String &str1, const Common::String &str2);
int checkNew(const void *mem);
-void registerWindowForFatal();
void setFatalInfo(const Common::String &userFunc, const Common::String &BIF);
void setResourceForFatal(int n);
const Common::String resourceNameFromNum(int i);
diff --git a/engines/sludge/objtypes.cpp b/engines/sludge/objtypes.cpp
index 3bea21a943..dc41249ab7 100644
--- a/engines/sludge/objtypes.cpp
+++ b/engines/sludge/objtypes.cpp
@@ -32,16 +32,22 @@
namespace Sludge {
ObjectManager::~ObjectManager() {
+ kill();
+}
+
+bool ObjectManager::init() {
+ _allObjectTypes.clear();
+ return true;
+}
+
+void ObjectManager::kill() {
ObjectTypeList::iterator it;
for (it = _allObjectTypes.begin(); it != _allObjectTypes.end(); ++it) {
delete [](*it)->allCombis;
delete (*it);
(*it) = nullptr;
}
-}
-
-bool ObjectManager::initObjectTypes() {
- return true;
+ _allObjectTypes.clear();
}
ObjectType *ObjectManager::findObjectType(int i) {
diff --git a/engines/sludge/objtypes.h b/engines/sludge/objtypes.h
index f0f5125884..a348fa123d 100644
--- a/engines/sludge/objtypes.h
+++ b/engines/sludge/objtypes.h
@@ -44,10 +44,12 @@ typedef Common::List<ObjectType *> ObjectTypeList;
class ObjectManager {
public:
- ObjectManager(SludgeEngine *vm) : _vm(vm) {}
+ ObjectManager(SludgeEngine *vm) : _vm(vm) { init(); }
~ObjectManager();
- bool initObjectTypes();
+ bool init();
+ void kill();
+
ObjectType *findObjectType(int i);
ObjectType *loadObjectType(int i);
int getCombinationFunction(int a, int b);
diff --git a/engines/sludge/region.cpp b/engines/sludge/region.cpp
index af9e2b8cac..7593fe4aee 100644
--- a/engines/sludge/region.cpp
+++ b/engines/sludge/region.cpp
@@ -33,8 +33,9 @@
namespace Sludge {
-ScreenRegion *allScreenRegions = NULL;
-ScreenRegion *overRegion = NULL;
+ScreenRegion *allScreenRegions = nullptr;
+ScreenRegion *overRegion = nullptr;
+ScreenRegion *lastRegion = nullptr;
void showBoxes() {
ScreenRegion*huntRegion = allScreenRegions;
@@ -121,7 +122,8 @@ void killAllRegions() {
g_sludge->_objMan->removeObjectType(killRegion->thisType);
delete killRegion;
}
- overRegion = NULL;
+ overRegion = nullptr;
+ lastRegion = nullptr;
}
bool addScreenRegion(int x1, int y1, int x2, int y2, int sX, int sY, int di,
diff --git a/engines/sludge/sludge.cpp b/engines/sludge/sludge.cpp
index 9976652c48..97904e191f 100644
--- a/engines/sludge/sludge.cpp
+++ b/engines/sludge/sludge.cpp
@@ -55,7 +55,8 @@ SludgeEngine::SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc)
DebugMan.addDebugChannel(kSludgeDebugZBuffer, "ZBuffer", "ZBuffer debug level");
DebugMan.addDebugChannel(kSludgeDebugSound, "Sound", "Sound debug level");
- DebugMan.enableDebugChannel("Sound");
+ DebugMan.enableDebugChannel("Data Load");
+ DebugMan.enableDebugChannel("Built-in");
// init graphics
_origFormat = new Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
@@ -63,10 +64,10 @@ SludgeEngine::SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc)
// Init Strings
launchMe = "";
+ launchNext = "";
loadNow = "";
gamePath = "";
bundleFolder = "";
-
fatalMessage = "";
fatalInfo = "Initialisation error! Something went wrong before we even got started!";
diff --git a/engines/sludge/sludge.h b/engines/sludge/sludge.h
index d868754014..240045db57 100644
--- a/engines/sludge/sludge.h
+++ b/engines/sludge/sludge.h
@@ -67,6 +67,7 @@ protected:
public:
// global String variables
Common::String launchMe;
+ Common::String launchNext;
Common::String loadNow;
Common::String gamePath;
Common::String bundleFolder;
diff --git a/engines/sludge/sludger.cpp b/engines/sludge/sludger.cpp
index 8e49b32465..69e6966e74 100644
--- a/engines/sludge/sludger.cpp
+++ b/engines/sludge/sludger.cpp
@@ -20,12 +20,14 @@
*
*/
+#include "common/config-manager.h"
#include "common/debug.h"
#include "sludge/allfiles.h"
#include "sludge/backdrop.h"
#include "sludge/builtin.h"
#include "sludge/cursors.h"
+#include "sludge/event.h"
#include "sludge/fonttext.h"
#include "sludge/freeze.h"
#include "sludge/floor.h"
@@ -54,7 +56,6 @@
namespace Sludge {
extern int dialogValue;
-extern Variable *launchResult;
int numBIFNames = 0;
Common::String *allBIFNames;
@@ -74,11 +75,20 @@ extern SpeechStruct *speech;
extern LoadedFunction *saverFunc;
LoadedFunction *allRunningFunctions = NULL;
-ScreenRegion *lastRegion = NULL;
VariableStack *noStack = NULL;
Variable *globalVars;
-int numGlobals;
+int numGlobals = 0;
+
+extern SpritePalette pastePalette;
+extern int speechMode;
+extern float speechSpeed;
+extern Variable *launchResult;
+extern int lastFramesPerSecond, thumbWidth, thumbHeight;
+
+extern bool allowAnyFilename;
+extern byte fadeMode;
+extern uint16 saveEncoding;
const char *sludgeText[] = { "?????", "RETURN", "BRANCH", "BR_ZERO",
"SET_GLOBAL", "SET_LOCAL", "LOAD_GLOBAL", "LOAD_LOCAL", "PLUS", "MINUS",
@@ -138,9 +148,69 @@ Common::File *openAndVerify(const Common::String &filename, char extra1, char ex
return fp;
}
+void initSludge() {
+ g_sludge->_languageMan->init();
+ g_sludge->_gfxMan->init();
+ g_sludge->_resMan->init();
+ initPeople();
+ initFloor();
+ g_sludge->_objMan->init();
+ initSpeech();
+ initStatusBar();
+ resetRandW();
+ g_sludge->_evtMan->init();
+ g_sludge->_txtMan->init();
+ g_sludge->_cursorMan->init();
+
+ g_sludge->_soundMan->init();
+ if (!ConfMan.hasKey("mute") || !ConfMan.getBool("mute")) {
+ g_sludge->_soundMan->initSoundStuff();
+ }
+
+ // global variables
+ numGlobals = 0;
+ speechMode = 0;
+ launchResult = nullptr;
+
+ lastFramesPerSecond = -1;
+ thumbWidth = thumbHeight = 0;
+ allowAnyFilename = true;
+ captureAllKeys = false;
+ noStack = nullptr;
+ numBIFNames = numUserFunc = 0;
+ allUserFunc = allBIFNames = nullptr;
+ speechSpeed = 1;
+ brightnessLevel = 255;
+ fadeMode = 2;
+ saveEncoding = false;
+}
+
+void killSludge() {
+ killAllFunctions();
+ killAllPeople();
+ killAllRegions();
+ setFloorNull();
+ killAllSpeech();
+ g_sludge->_languageMan->kill();
+ g_sludge->_gfxMan->kill();
+ g_sludge->_resMan->kill();
+ g_sludge->_objMan->kill();
+ g_sludge->_soundMan->killSoundStuff();
+ g_sludge->_evtMan->kill();
+ g_sludge->_txtMan->kill();
+ g_sludge->_cursorMan->kill();
+
+ // global variables
+ pastePalette.reset();
+ numBIFNames = numUserFunc = 0;
+ delete []allUserFunc;
+ delete []allBIFNames;
+}
+
bool initSludge(const Common::String &filename) {
- int a = 0;
+ initSludge();
+ int a = 0;
Common::File *fp = openAndVerify(filename, 'G', 'E', ERROR_BAD_HEADER, gameVersion);
if (!fp)
return false;
@@ -203,7 +273,7 @@ bool initSludge(const Common::String &filename) {
Common::String dataFol = (gameVersion >= VERSION(1, 3)) ? readString(fp) : "";
debugC(2, kSludgeDebugDataLoad, "dataFol : %s", dataFol.c_str());
- g_sludge->_languageMan->init(fp);
+ g_sludge->_languageMan->createTable(fp);
if (gameVersion >= VERSION(1, 6)) {
fp->readByte();
@@ -407,27 +477,16 @@ bool continueFunction(LoadedFunction *fun) {
return true;
}
-// if (numBIFNames) newDebug ("*** Function:", allUserFunc[fun->originalNumber]);
-
- //debugOut ("SLUDGER: continueFunction\n");
-
while (keepLooping) {
advanceNow = true;
debugC(1, kSludgeDebugStackMachine, "Executing command line %i : ", fun->runThisLine);
param = fun->compiledLines[fun->runThisLine].param;
com = fun->compiledLines[fun->runThisLine].theCommand;
-// fprintf (stderr, "com: %d param: %d (%s)\n", com, param,
-// (com < numSludgeCommands) ? sludgeText[com] : ERROR_UNKNOWN_MCODE); fflush(stderr);
if (numBIFNames) {
setFatalInfo((fun->originalNumber < numUserFunc) ? allUserFunc[fun->originalNumber] : "Unknown user function", (com < numSludgeCommands) ? sludgeText[com] : ERROR_UNKNOWN_MCODE);
-// newDebug (
-// (com < numSludgeCommands) ? sludgeText[com] : "Unknown SLUDGE machine code",
-// param);
}
- //debugOut ("SLUDGER: continueFunction - in da loop: %s\n", sludgeText[com]);
-
switch (com) {
case SLU_RETURN:
if (fun->calledBy) {
@@ -913,6 +972,11 @@ bool runSludge() {
return true;
}
+void killAllFunctions() {
+ while (allRunningFunctions)
+ finishFunction(allRunningFunctions);
+}
+
bool loadFunctionCode(LoadedFunction *newFunc) {
uint numLines, numLinesRead;
diff --git a/engines/sludge/sludger.h b/engines/sludge/sludger.h
index 91efb24ce9..8f554f83cb 100644
--- a/engines/sludge/sludger.h
+++ b/engines/sludge/sludger.h
@@ -60,12 +60,17 @@ struct LoadedFunction {
bool initSludge(const Common::String &);
bool runSludge();
+
+void initSludge();
+void killSludge();
+
void displayBase();
void sludgeDisplay();
int startNewFunctionNum(uint, uint, LoadedFunction *, VariableStack*&, bool = true);
bool handleInput();
void restartFunction(LoadedFunction *fun);
bool loadFunctionCode(LoadedFunction *newFunc);
+void killAllFunctions();
void finishFunction(LoadedFunction *fun);
void abortFunction(LoadedFunction *fun);
diff --git a/engines/sludge/sound.cpp b/engines/sludge/sound.cpp
index 6820ae14be..25caa0b9de 100644
--- a/engines/sludge/sound.cpp
+++ b/engines/sludge/sound.cpp
@@ -43,24 +43,13 @@ const int SoundManager::MAX_SAMPLES = 8;
const int SoundManager::MAX_MODS = 3;
SoundManager::SoundManager() {
- // there's possibility that several sound list played at the same time
- _soundListHandles.clear();
-
- _soundOK = false;
- _silenceIKillYou = false;
- _isHandlingSoundList = false;
-
_soundCache = nullptr;
_soundCache = new SoundThing[MAX_SAMPLES];
_modCache = nullptr;
_modCache = new SoundThing[MAX_MODS];
- _defVol = 128;
- _defSoundVol = 255;
- _modLoudness = 0.95f;
-
- _emptySoundSlot = 0;
+ init();
}
SoundManager::~SoundManager() {
@@ -73,14 +62,29 @@ SoundManager::~SoundManager() {
_modCache = nullptr;
}
+void SoundManager::init() {
+ // there's possibility that several sound list played at the same time
+ _soundListHandles.clear();
+
+ _soundOK = false;
+ _silenceIKillYou = false;
+ _isHandlingSoundList = false;
+
+ _defVol = 128;
+ _defSoundVol = 255;
+ _modLoudness = 0.95f;
+
+ _emptySoundSlot = 0;
+}
+
bool SoundManager::initSoundStuff() {
- for (int a = 0; a < MAX_SAMPLES; a ++) {
+ for (int a = 0; a < MAX_SAMPLES; ++a) {
_soundCache[a].fileLoaded = -1;
_soundCache[a].looping = false;
_soundCache[a].inSoundList = false;
}
- for (int a = 0; a < MAX_MODS; a ++) {
+ for (int a = 0; a < MAX_MODS; ++a) {
_soundCache[a].fileLoaded = -1;
_soundCache[a].looping = false;
_soundCache[a].inSoundList = false;
diff --git a/engines/sludge/sound.h b/engines/sludge/sound.h
index 1e1a2a47e4..dd9a0179d9 100644
--- a/engines/sludge/sound.h
+++ b/engines/sludge/sound.h
@@ -50,6 +50,7 @@ public:
void handleSoundLists(); // to produce the same effects as end of stream call back functions
// GENERAL...
+ void init();
bool initSoundStuff();
void killSoundStuff();
diff --git a/engines/sludge/sprites.cpp b/engines/sludge/sprites.cpp
index c37c4a1905..81769ccb97 100644
--- a/engines/sludge/sprites.cpp
+++ b/engines/sludge/sprites.cpp
@@ -54,13 +54,15 @@ void GraphicsManager::forgetSpriteBank(SpriteBank &forgetme) {
forgetme.myPalette.b = NULL;
}
- for (int i = 0; i < forgetme.total; ++i) {
- forgetme.sprites[i].surface.free();
- forgetme.sprites[i].burnSurface.free();
- }
+ if (forgetme.sprites) {
+ for (int i = 0; i < forgetme.total; ++i) {
+ forgetme.sprites[i].surface.free();
+ forgetme.sprites[i].burnSurface.free();
+ }
- delete []forgetme.sprites;
- forgetme.sprites = NULL;
+ delete []forgetme.sprites;
+ forgetme.sprites = NULL;
+ }
}
bool GraphicsManager::reserveSpritePal(SpritePalette &sP, int n) {
diff --git a/engines/sludge/sprites.h b/engines/sludge/sprites.h
index 521fb5298d..e138c6f14f 100644
--- a/engines/sludge/sprites.h
+++ b/engines/sludge/sprites.h
@@ -41,15 +41,32 @@ public:
byte *b;
byte originalRed, originalGreen, originalBlue, total;
- SpritePalette() : pal(0), r(0), g(0), b(0), total(0) {
+ SpritePalette() { init(); }
+
+ ~SpritePalette() { kill(); }
+
+ void reset() {
+ kill();
+ init();
+ }
+
+private:
+ void init() {
+ pal = nullptr;
+ r = g = b = nullptr;
+ total = 0;
originalRed = originalGreen = originalBlue = 255;
}
- ~SpritePalette() {
- delete[] pal;
- delete[] r;
- delete[] g;
- delete[] b;
+ void kill() {
+ if (pal)
+ delete[] pal;
+ if (r)
+ delete[] r;
+ if (g)
+ delete[] g;
+ if (b)
+ delete[] b;
}
};
diff --git a/engines/sludge/talk.cpp b/engines/sludge/talk.cpp
index 531fb42fd8..4bb1d222b6 100644
--- a/engines/sludge/talk.cpp
+++ b/engines/sludge/talk.cpp
@@ -53,6 +53,9 @@ void initSpeech() {
}
void killAllSpeech() {
+ if (!speech)
+ return;
+
if (speech->lastFile != -1) {
g_sludge->_soundMan->huntKillSound(speech->lastFile);
speech->lastFile = -1;
diff --git a/engines/sludge/variable.cpp b/engines/sludge/variable.cpp
index fb4f191025..510c6f4607 100644
--- a/engines/sludge/variable.cpp
+++ b/engines/sludge/variable.cpp
@@ -430,14 +430,6 @@ bool makeFastArrayFromStack(Variable &to, const StackHandler *stacky) {
return true;
}
-/*
- bool moveVariable (Variable & from, Variable & to) {
- unlinkVar (to);
- memcpy (& to, & from, sizeof (variable));
- from.varType = SVT_NULL;
- }
- */
-
bool addVarToStack(const Variable &va, VariableStack *&thisStack) {
VariableStack *newStack = new VariableStack;
if (!checkNew(newStack))
diff --git a/engines/titanic/game/maitred/maitred_prod_receptor.cpp b/engines/titanic/game/maitred/maitred_prod_receptor.cpp
index c727366993..f8e540dde2 100644
--- a/engines/titanic/game/maitred/maitred_prod_receptor.cpp
+++ b/engines/titanic/game/maitred/maitred_prod_receptor.cpp
@@ -34,24 +34,24 @@ END_MESSAGE_MAP()
void CMaitreDProdReceptor::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldBC, indent);
+ file->writeNumberLine(_prodSource, indent);
file->writeNumberLine(_counter, indent);
- file->writeNumberLine(_fieldC4, indent);
+ file->writeNumberLine(_proddable, indent);
CGameObject::save(file, indent);
}
void CMaitreDProdReceptor::load(SimpleFile *file) {
file->readNumber();
- _fieldBC = file->readNumber();
+ _prodSource = (ProdSource)file->readNumber();
_counter = file->readNumber();
- _fieldC4 = file->readNumber();
+ _proddable = file->readNumber();
CGameObject::load(file);
}
bool CMaitreDProdReceptor::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
- if (_fieldBC == 2 && static_cast<CGameObject *>(getParent())->hasActiveMovie()) {
+ if (_prodSource == MAITRED_BUTTOCKS && static_cast<CGameObject *>(getParent())->hasActiveMovie()) {
return false;
} else {
CProdMaitreDMsg prodMsg(126);
@@ -63,7 +63,7 @@ bool CMaitreDProdReceptor::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
bool CMaitreDProdReceptor::MouseMoveMsg(CMouseMoveMsg *msg) {
if (!getDraggingObject())
return true;
- if (_fieldBC == 2 && static_cast<CGameObject *>(getParent())->hasActiveMovie())
+ if (_prodSource == MAITRED_BUTTOCKS && static_cast<CGameObject *>(getParent())->hasActiveMovie())
return false;
else if (++_counter < 20)
return true;
@@ -90,20 +90,20 @@ bool CMaitreDProdReceptor::MouseMoveMsg(CMouseMoveMsg *msg) {
}
bool CMaitreDProdReceptor::ProdMaitreDMsg(CProdMaitreDMsg *msg) {
- if (_fieldC4) {
+ if (_proddable) {
CMaitreD *maitreD = static_cast<CMaitreD *>(findRoomObject("MaitreD"));
if (maitreD->_speechCounter == 0) {
CViewItem *view = findView();
startTalking(maitreD, msg->_value, view);
- switch (_fieldBC) {
- case 1:
+ switch (_prodSource) {
+ case MAITRED_LEGS:
startTalking(maitreD, 128, view);
break;
- case 2:
+ case MAITRED_BUTTOCKS:
startTalking(maitreD, 129, view);
break;
- case 3:
+ case MAITRED_GENERAL:
startTalking(maitreD, 127, view);
break;
default:
@@ -117,7 +117,7 @@ bool CMaitreDProdReceptor::ProdMaitreDMsg(CProdMaitreDMsg *msg) {
}
bool CMaitreDProdReceptor::DisableMaitreDProdReceptor(CDisableMaitreDProdReceptor *msg) {
- _fieldC4 = 0;
+ _proddable = false;
return true;
}
diff --git a/engines/titanic/game/maitred/maitred_prod_receptor.h b/engines/titanic/game/maitred/maitred_prod_receptor.h
index 0b00ce0014..e862668d00 100644
--- a/engines/titanic/game/maitred/maitred_prod_receptor.h
+++ b/engines/titanic/game/maitred/maitred_prod_receptor.h
@@ -27,6 +27,8 @@
namespace Titanic {
+enum ProdSource { MAITRED_BODY = 0, MAITRED_LEGS = 1, MAITRED_BUTTOCKS = 2, MAITRED_GENERAL = 3 };
+
class CMaitreDProdReceptor : public CGameObject {
DECLARE_MESSAGE_MAP;
bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
@@ -34,13 +36,13 @@ class CMaitreDProdReceptor : public CGameObject {
bool ProdMaitreDMsg(CProdMaitreDMsg *msg);
bool DisableMaitreDProdReceptor(CDisableMaitreDProdReceptor *msg);
protected:
- int _fieldBC;
+ ProdSource _prodSource;
int _counter;
- int _fieldC4;
+ bool _proddable;
public:
CLASSDEF;
CMaitreDProdReceptor() : CGameObject(),
- _fieldBC(0), _counter(0), _fieldC4(1) {}
+ _prodSource(MAITRED_BODY), _counter(0), _proddable(true) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/npcs/parrot.cpp b/engines/titanic/npcs/parrot.cpp
index a0f80ca69b..dd033abbae 100644
--- a/engines/titanic/npcs/parrot.cpp
+++ b/engines/titanic/npcs/parrot.cpp
@@ -122,12 +122,8 @@ bool CParrot::ActMsg(CActMsg *msg) {
if (msg->_action == "Chicken") {
// Nothing to do
} else if (msg->_action == "CarryParrotLeftView") {
- if (!_takeOff) {
- _eatingChicken = false;
- CStatusChangeMsg statusMsg;
- statusMsg._newStatus = 1;
- statusMsg.execute("PerchCoreHolder");
- }
+ if (!_takeOff)
+ setEatingChicken(false);
} else if (msg->_action == "StartChickenDrag") {
if (_state == PARROT_IN_CAGE) {
stopMovie();
@@ -258,11 +254,7 @@ bool CParrot::MovieEndMsg(CMovieEndMsg *msg) {
playClip("Eat Chicken 2", MOVIE_NOTIFY_OBJECT);
if (chicken) {
- _eatingChicken = true;
-
- CStatusChangeMsg statusMsg;
- statusMsg._newStatus = 0;
- statusMsg.execute("PerchCoreHolder");
+ setEatingChicken(true);
CTrueTalkTriggerActionMsg actionMsg;
actionMsg._action = 280266;
@@ -280,11 +272,7 @@ bool CParrot::MovieEndMsg(CMovieEndMsg *msg) {
if (clipExistsByEnd("Eat Chicken 2", msg->_endFrame)) {
// Parrot has finished eating Chicken
- _eatingChicken = false;
-
- CStatusChangeMsg statusMsg;
- statusMsg._newStatus = 1;
- statusMsg.execute("PerchCoreHolder");
+ setEatingChicken(false);
if (_takeOff) {
// Perch has been taken, so take off
@@ -587,6 +575,10 @@ bool CParrot::FrameMsg(CFrameMsg *msg) {
_npcFlags |= NPCFLAG_MOVING | NPCFLAG_MOVE_START;
if (_newXc >= xp) {
+ // WORKAROUND: Original did not properly reset the eating chicken
+ // flag when the player turns away from the cage
+ setEatingChicken(false);
+
setPosition(Point(_bounds.left + 30, _bounds.top));
_npcFlags |= NPCFLAG_MOVE_RIGHT;
playClip("Walk Right Intro", MOVIE_NOTIFY_OBJECT);
@@ -744,5 +736,11 @@ bool CParrot::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg) {
return CTrueTalkNPC::TrueTalkNotifySpeechEndedMsg(msg);
}
+void CParrot::setEatingChicken(bool eating) {
+ _eatingChicken = eating;
+ CStatusChangeMsg statusMsg;
+ statusMsg._newStatus = eating ? 0 : 1;
+ statusMsg.execute("PerchCoreHolder");
+}
} // End of namespace Titanic
diff --git a/engines/titanic/npcs/parrot.h b/engines/titanic/npcs/parrot.h
index c3ba5a5fd6..6fc4d6a182 100644
--- a/engines/titanic/npcs/parrot.h
+++ b/engines/titanic/npcs/parrot.h
@@ -69,6 +69,11 @@ private:
bool _triedEatChicken;
int _eatOffsetX;
CMovePlayerTo *_panTarget;
+private:
+ /**
+ * Called for the Parrot to start or finish eating
+ */
+ void setEatingChicken(bool eating);
public:
CLASSDEF;
CParrot();
diff --git a/engines/titanic/pet_control/pet_control.cpp b/engines/titanic/pet_control/pet_control.cpp
index a62377bfb8..73f6df58a0 100644
--- a/engines/titanic/pet_control/pet_control.cpp
+++ b/engines/titanic/pet_control/pet_control.cpp
@@ -331,7 +331,22 @@ bool CPetControl::KeyCharMsg(CKeyCharMsg *msg) {
return false;
makeDirty();
- return _sections[_currentArea]->KeyCharMsg(msg);
+ bool result = _sections[_currentArea]->KeyCharMsg(msg);
+
+ if (!result) {
+ switch (msg->_key) {
+ case Common::KEYCODE_TAB:
+ if (isAreaUnlocked()) {
+ setArea(PET_INVENTORY);
+ result = true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ return result;
}
bool CPetControl::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) {
@@ -344,11 +359,11 @@ bool CPetControl::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) {
switch (msg->_keyState.keycode) {
case Common::KEYCODE_F1:
result = true;
- setArea(PET_INVENTORY);
+ setArea(PET_CONVERSATION);
break;
case Common::KEYCODE_F2:
+ setArea(PET_INVENTORY);
result = true;
- setArea(PET_CONVERSATION);
break;
case Common::KEYCODE_F3:
result = true;
diff --git a/engines/titanic/pet_control/pet_conversations.cpp b/engines/titanic/pet_control/pet_conversations.cpp
index 0a31f44bbf..c228c30fa5 100644
--- a/engines/titanic/pet_control/pet_conversations.cpp
+++ b/engines/titanic/pet_control/pet_conversations.cpp
@@ -478,7 +478,7 @@ bool CPetConversations::handleKey(const Common::KeyState &keyState) {
scrollToBottom();
return true;
default:
- if (keyState.ascii > 0 && keyState.ascii <= 127) {
+ if (keyState.ascii <= 127 && keyState.ascii != Common::KEYCODE_TAB) {
if (_textInput.handleKey(keyState.ascii))
// Text line finished, so process line
textLineEntered(_textInput.getText());
diff --git a/engines/titanic/pet_control/pet_real_life.cpp b/engines/titanic/pet_control/pet_real_life.cpp
index b9e1990dd2..57d81c739e 100644
--- a/engines/titanic/pet_control/pet_real_life.cpp
+++ b/engines/titanic/pet_control/pet_real_life.cpp
@@ -71,8 +71,7 @@ bool CPetRealLife::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
}
bool CPetRealLife::KeyCharMsg(CKeyCharMsg *msg) {
- _glyphs.KeyCharMsg(msg->_key);
- return true;
+ return _glyphs.KeyCharMsg(msg->_key);
}
bool CPetRealLife::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) {
diff --git a/engines/titanic/true_talk/maitred_script.cpp b/engines/titanic/true_talk/maitred_script.cpp
index 26adb474a7..98a4b42e70 100644
--- a/engines/titanic/true_talk/maitred_script.cpp
+++ b/engines/titanic/true_talk/maitred_script.cpp
@@ -78,7 +78,7 @@ int MaitreDScript::process(const TTroomScript *roomScript, const TTsentence *sen
setState(0);
if (getValue(12) == 0) {
- trigger12(false);
+ stopFighting(false);
_answerCtr = 0;
if (sentence->contains("restaurant at the end of the universe")
@@ -113,13 +113,13 @@ int MaitreDScript::process(const TTroomScript *roomScript, const TTsentence *sen
|| sentence->contains("i give up") || sentence->contains("i give in")
|| sentence->contains("i surrender") || sentence->contains("i submit")) {
_answerCtr = 0;
- trigger12(false);
+ stopFighting(false);
addResponse(getDialogueId(260063));
} else if (sentence->localWord("not") && sentence->localWord("fight") &&
(sentence->localWord("feel") || sentence->localWord("want")
|| sentence->localWord("do") || sentence->localWord("will"))) {
_answerCtr = 0;
- trigger12(false);
+ stopFighting(false);
addResponse(getDialogueId(260678));
} else if (sentence->contains("touche") || sentence->contains("toushe")) {
addResponse(getDialogueId(260098));
@@ -165,7 +165,7 @@ ScriptChangedResult MaitreDScript::scriptChanged(const TTroomScript *roomScript,
case 110:
addResponse(getDialogueId(260118));
applyResponse();
- trigger12(true);
+ stopFighting(true);
CTrueTalkManager::setFlags(8, 1);
CTrueTalkManager::setFlags(9, 1);
break;
@@ -207,7 +207,7 @@ ScriptChangedResult MaitreDScript::scriptChanged(const TTroomScript *roomScript,
case 117:
CTrueTalkManager::setFlags(8, 0);
CTrueTalkManager::setFlags(9, 0);
- setFlags12();
+ startFighting();
break;
case 132:
@@ -291,7 +291,7 @@ ScriptChangedResult MaitreDScript::scriptChanged(const TTroomScript *roomScript,
break;
case 13:
- setFlags12();
+ startFighting();
addResponse(getDialogueId(260131));
applyResponse();
break;
@@ -533,7 +533,7 @@ int MaitreDScript::updateState(uint oldId, uint newId, int index) {
if (newId == 260076 || newId == 260181 || newId == 261010) {
CTrueTalkManager::setFlags(14, 1);
- trigger12(true);
+ stopFighting(true);
setFlags10(newId, index);
return newId;
}
@@ -547,7 +547,7 @@ int MaitreDScript::updateState(uint oldId, uint newId, int index) {
for (uint idx = 0; FLAG_IDS[idx]; ++idx) {
if (FLAG_IDS[idx] == newId) {
- setFlags12();
+ startFighting();
break;
}
}
@@ -634,12 +634,11 @@ uint MaitreDScript::getStateDialogueId(uint oldId, uint newId) {
}
}
-
-void MaitreDScript::setFlags12() {
- int val = getValue(12);
+void MaitreDScript::startFighting() {
+ bool isFighting = getValue(12);
CTrueTalkManager::setFlags(12, 1);
- if (!val) {
+ if (!isFighting) {
CTrueTalkManager::triggerAction(8, 0);
resetRange(260121);
resetRange(260122);
@@ -650,6 +649,16 @@ void MaitreDScript::setFlags12() {
}
}
+void MaitreDScript::stopFighting(bool flag) {
+ bool isFighting = getValue(12);
+ CTrueTalkManager::setFlags(12, 0);
+
+ if (isFighting) {
+ // Surrender
+ CTrueTalkManager::triggerAction(flag ? 10 : 9, 0);
+ }
+}
+
void MaitreDScript::setFlags10(uint newId, uint index) {
int val = 28;
for (uint idx = 0; idx < _states.size(); ++idx) {
@@ -663,15 +672,6 @@ void MaitreDScript::setFlags10(uint newId, uint index) {
CTrueTalkManager::setFlags(10, val);
}
-void MaitreDScript::trigger12(bool flag) {
- int val = getValue(12);
- CTrueTalkManager::setFlags(12, 0);
-
- if (val) {
- CTrueTalkManager::triggerAction(flag ? 10 : 9, 0);
- }
-}
-
int MaitreDScript::preprocess(const TTroomScript *roomScript, const TTsentence *sentence) {
if (!roomScript || !sentence || getValue(8))
return 1;
@@ -739,18 +739,18 @@ int MaitreDScript::preprocess(const TTroomScript *roomScript, const TTsentence *
case 8:
if (sentence->_category == 11 || sentence->_category == 13) {
- trigger12(false);
+ stopFighting(false);
addResponse(getDialogueId(260094));
CTrueTalkManager::setFlags(11, 1);
} else {
- setFlags12();
+ startFighting();
addResponse(getDialogueId(260131));
}
applyFlag = true;
break;
case 9:
- setFlags12();
+ startFighting();
break;
case 11:
@@ -835,7 +835,7 @@ int MaitreDScript::preprocess(const TTroomScript *roomScript, const TTsentence *
applyFlag = true;
stateFlag = false;
} else {
- setFlags12();
+ startFighting();
addResponse(getDialogueId(260221));
applyFlag = true;
stateFlag = false;
@@ -1026,7 +1026,7 @@ int MaitreDScript::preprocess(const TTroomScript *roomScript, const TTsentence *
case 29:
if (sentence->_category == 11) {
- setFlags12();
+ startFighting();
addResponse(getDialogueId(260131));
} else {
addResponse(getDialogueId(260966));
diff --git a/engines/titanic/true_talk/maitred_script.h b/engines/titanic/true_talk/maitred_script.h
index 0472050d20..bbeee403e7 100644
--- a/engines/titanic/true_talk/maitred_script.h
+++ b/engines/titanic/true_talk/maitred_script.h
@@ -44,20 +44,20 @@ private:
uint getStateDialogueId(uint oldId, uint newId);
/**
- * Sets flags 12 and resets some ranges
+ * Starts the MaitreD fighting, if he isn't already
*/
- void setFlags12();
+ void startFighting();
/**
- * Sets flags 10 to different values based on the passed
- * dialogue Id
+ * Stops the MaitreD fighting
*/
- void setFlags10(uint newId, uint index);
+ void stopFighting(bool flag);
/**
- * Trigers 12
+ * Sets flags 10 to different values based on the passed
+ * dialogue Id
*/
- void trigger12(bool flag);
+ void setFlags10(uint newId, uint index);
/**
* Does preprocessing for the sentence
diff --git a/engines/wage/detection_tables.h b/engines/wage/detection_tables.h
index bde10785df..4c29967f7a 100644
--- a/engines/wage/detection_tables.h
+++ b/engines/wage/detection_tables.h
@@ -109,6 +109,7 @@ static const ADGameDescription gameDescriptions[] = {
FANGAME("Minitorian", "c728dfccdca12571e275a4113b3db343", 586464),
FANGAME("M'Lord's Warrior", "e0a0622ce2023984e3118141a9688ec5", 465639), // Original file name is "M'Lord's Warrior †"
FANGAMEN("Mormonoids from the Deep", "Mormonoids 1.25", "4730d0c47d13401d73353e980f91a304", 645318),
+ FANGAMEN("Mormonoids from the Deep", "Mormonoids 1.25", "1a7ee052b375f0c0a4c18836c978ce5b", 645333), // Alt version
// Unhandled comparison case
FANGAME("Mountain of Mayhem", "634211b004371635d191ae0687035501", 750003), // Original file name "Mountain of Mayhem †"
// No way to pass through the first screen
diff --git a/engines/wage/gui.cpp b/engines/wage/gui.cpp
index 53f83bb97c..ffc4e41e66 100644
--- a/engines/wage/gui.cpp
+++ b/engines/wage/gui.cpp
@@ -199,7 +199,7 @@ bool Gui::processSceneEvents(WindowClick click, Common::Event &event) {
// Menu stuff
////////////////
void Gui::regenCommandsMenu() {
- _menu->createSubMenuFromString(_commandsMenuId, _engine->_world->_commandsMenu.c_str());
+ _menu->createSubMenuFromString(_commandsMenuId, _engine->_world->_commandsMenu.c_str(), kMenuActionCommand);
}
void Gui::regenWeaponsMenu() {
diff --git a/engines/wage/world.cpp b/engines/wage/world.cpp
index 4e92af2501..df9fcaf022 100644
--- a/engines/wage/world.cpp
+++ b/engines/wage/world.cpp
@@ -114,9 +114,9 @@ bool World::loadWorld(Common::MacResManager *resMan) {
Common::MacResIDArray::const_iterator iter;
// Dumping interpreter code
-#if 1
+#if 0
res = resMan->getResource(MKTAG('C','O','D','E'), 1);
- warning("code size: %d", res->size());
+ warning("Dumping interpreter code size: %d", res->size());
byte *buf = (byte *)malloc(res->size());
res->read(buf, res->size());
Common::DumpFile out;
diff --git a/graphics/macgui/macfontmanager.cpp b/graphics/macgui/macfontmanager.cpp
index 81349551d8..c3a96dc8fb 100644
--- a/graphics/macgui/macfontmanager.cpp
+++ b/graphics/macgui/macfontmanager.cpp
@@ -209,7 +209,7 @@ void MacFontManager::loadFonts(Common::MacResManager *fontFile) {
Common::Array<Graphics::MacFontFamily::AsscEntry> *assoc = fontFamily->getAssocTable();
for (uint i = 0; i < assoc->size(); i++) {
- debug("size: %d style: %d id: %d", (*assoc)[i]._fontSize, (*assoc)[i]._fontStyle,
+ debug(8, "size: %d style: %d id: %d", (*assoc)[i]._fontSize, (*assoc)[i]._fontStyle,
(*assoc)[i]._fontID);
Common::SeekableReadStream *fontstream;
@@ -222,7 +222,7 @@ void MacFontManager::loadFonts(Common::MacResManager *fontFile) {
fontstream = fontFile->getResource(MKTAG('F', 'O', 'N', 'T'), (*assoc)[i]._fontID);
if (!fontstream) {
- warning("Unknown FontId: %d", (*assoc)[i]._fontID);
+ warning("MacFontManager: Unknown FontId: %d", (*assoc)[i]._fontID);
continue;
}
diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp
index dcf2e20470..cecdcabcea 100644
--- a/graphics/macgui/macmenu.cpp
+++ b/graphics/macgui/macmenu.cpp
@@ -56,11 +56,6 @@ enum {
kFontStyleExtended = 64
};
-enum {
- kMenuActionCommand
-};
-
-
struct MacMenuSubItem {
Common::String text;
int action;
@@ -216,7 +211,7 @@ void MacMenu::clearSubMenu(int id) {
menu->subitems.clear();
}
-void MacMenu::createSubMenuFromString(int id, const char *str) {
+void MacMenu::createSubMenuFromString(int id, const char *str, int commandId) {
clearSubMenu(id);
MacMenuItem *menu = _items[id];
@@ -278,7 +273,7 @@ void MacMenu::createSubMenuFromString(int id, const char *str) {
}
}
- menu->subitems.push_back(new MacMenuSubItem(item.c_str(), kMenuActionCommand, style, shortcut, enabled));
+ menu->subitems.push_back(new MacMenuSubItem(item.c_str(), commandId, style, shortcut, enabled));
}
item.clear();
diff --git a/graphics/macgui/macmenu.h b/graphics/macgui/macmenu.h
index a25b65afbc..8b3e8ff258 100644
--- a/graphics/macgui/macmenu.h
+++ b/graphics/macgui/macmenu.h
@@ -52,7 +52,7 @@ public:
int addMenuItem(const char *name);
void addMenuSubItem(int id, const char *text, int action, int style = 0, char shortcut = 0, bool enabled = true);
- void createSubMenuFromString(int id, const char *string);
+ void createSubMenuFromString(int id, const char *string, int commandId);
void clearSubMenu(int id);
bool draw(ManagedSurface *g, bool forceRedraw = false);
diff --git a/graphics/macgui/mactextwindow.cpp b/graphics/macgui/mactextwindow.cpp
index 85a07b975e..c05468c2e3 100644
--- a/graphics/macgui/mactextwindow.cpp
+++ b/graphics/macgui/mactextwindow.cpp
@@ -279,6 +279,10 @@ bool MacTextWindow::processEvent(Common::Event &event) {
if (event.type == Common::EVENT_KEYDOWN) {
_wm->setActive(getId());
+ if (event.kbd.flags & (Common::KBD_ALT | Common::KBD_CTRL | Common::KBD_META)) {
+ return false;
+ }
+
switch (event.kbd.keycode) {
case Common::KEYCODE_BACKSPACE:
if (!_inputText.empty()) {
@@ -309,6 +313,16 @@ bool MacTextWindow::processEvent(Common::Event &event) {
if (hasAllFocus())
return MacWindow::processEvent(event); // Pass it to upstream
+ if (event.type == Common::EVENT_WHEELUP) {
+ scroll(-2);
+ return true;
+ }
+
+ if (event.type == Common::EVENT_WHEELDOWN) {
+ scroll(2);
+ return true;
+ }
+
if (click == kBorderScrollUp || click == kBorderScrollDown) {
if (event.type == Common::EVENT_LBUTTONDOWN) {
int consoleHeight = getInnerDimensions().height();
@@ -320,22 +334,12 @@ bool MacTextWindow::processEvent(Common::Event &event) {
return true;
} else if (event.type == Common::EVENT_LBUTTONUP) {
- int oldScrollPos = _scrollPos;
-
switch (click) {
case kBorderScrollUp:
- _scrollPos = MAX<int>(0, _scrollPos - kConScrollStep);
- undrawCursor();
- _cursorY -= (_scrollPos - oldScrollPos);
- _contentIsDirty = true;
- _borderIsDirty = true;
+ scroll(-1);
break;
case kBorderScrollDown:
- _scrollPos = MIN<int>(_mactext->getTextHeight() - kConScrollStep, _scrollPos + kConScrollStep);
- undrawCursor();
- _cursorY -= (_scrollPos - oldScrollPos);
- _contentIsDirty = true;
- _borderIsDirty = true;
+ scroll(1);
break;
default:
return false;
@@ -385,6 +389,17 @@ bool MacTextWindow::processEvent(Common::Event &event) {
return MacWindow::processEvent(event);
}
+void MacTextWindow::scroll(int delta) {
+ int oldScrollPos = _scrollPos;
+
+ _scrollPos += delta * kConScrollStep;
+ _scrollPos = CLIP<int>(_scrollPos, 0, _mactext->getTextHeight() - kConScrollStep);
+ undrawCursor();
+ _cursorY -= (_scrollPos - oldScrollPos);
+ _contentIsDirty = true;
+ _borderIsDirty = true;
+}
+
void MacTextWindow::startMarking(int x, int y) {
x -= getInnerDimensions().left - 2;
y -= getInnerDimensions().top;
diff --git a/graphics/macgui/mactextwindow.h b/graphics/macgui/mactextwindow.h
index 6dd464e9af..5791da3496 100644
--- a/graphics/macgui/mactextwindow.h
+++ b/graphics/macgui/mactextwindow.h
@@ -77,6 +77,8 @@ public:
private:
bool isCutAllowed();
+ void scroll(int delta);
+
void undrawInput();
void drawInput();
void drawSelection();
diff --git a/graphics/macgui/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp
index 8eaf8e9f5b..9e5e8b76c9 100644
--- a/graphics/macgui/macwindowmanager.cpp
+++ b/graphics/macgui/macwindowmanager.cpp
@@ -304,14 +304,10 @@ void MacWindowManager::draw() {
}
bool MacWindowManager::processEvent(Common::Event &event) {
- // Menu gets events first fir shortcuts and menu bar
+ // Menu gets events first for shortcuts and menu bar
if (_menu && _menu->processEvent(event))
return true;
- if (event.type != Common::EVENT_MOUSEMOVE && event.type != Common::EVENT_LBUTTONDOWN &&
- event.type != Common::EVENT_LBUTTONUP && event.type != Common::EVENT_KEYDOWN)
- return false;
-
if (_windows[_activeWindow]->isEditable() && _windows[_activeWindow]->getType() == kWindowWindow &&
((MacWindow *)_windows[_activeWindow])->getInnerDimensions().contains(event.mouse.x, event.mouse.y)) {
if (_cursorIsArrow) {