[Scummvm-cvs-logs] SF.net SVN: scummvm:[55362] scummvm/trunk/engines/mohawk
fuzzie at users.sourceforge.net
fuzzie at users.sourceforge.net
Thu Jan 20 22:35:00 CET 2011
Revision: 55362
http://scummvm.svn.sourceforge.net/scummvm/?rev=55362&view=rev
Author: fuzzie
Date: 2011-01-20 21:35:00 +0000 (Thu, 20 Jan 2011)
Log Message:
-----------
MOHAWK: Add CSTime engine.
Modified Paths:
--------------
scummvm/trunk/engines/mohawk/console.cpp
scummvm/trunk/engines/mohawk/console.h
scummvm/trunk/engines/mohawk/detection.cpp
scummvm/trunk/engines/mohawk/graphics.cpp
scummvm/trunk/engines/mohawk/graphics.h
scummvm/trunk/engines/mohawk/module.mk
Added Paths:
-----------
scummvm/trunk/engines/mohawk/cstime.cpp
scummvm/trunk/engines/mohawk/cstime.h
scummvm/trunk/engines/mohawk/cstime_cases.cpp
scummvm/trunk/engines/mohawk/cstime_cases.h
scummvm/trunk/engines/mohawk/cstime_game.cpp
scummvm/trunk/engines/mohawk/cstime_game.h
scummvm/trunk/engines/mohawk/cstime_ui.cpp
scummvm/trunk/engines/mohawk/cstime_ui.h
scummvm/trunk/engines/mohawk/cstime_view.cpp
scummvm/trunk/engines/mohawk/cstime_view.h
Modified: scummvm/trunk/engines/mohawk/console.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/console.cpp 2011-01-20 21:34:19 UTC (rev 55361)
+++ scummvm/trunk/engines/mohawk/console.cpp 2011-01-20 21:35:00 UTC (rev 55362)
@@ -31,6 +31,7 @@
#include "mohawk/riven.h"
#include "mohawk/riven_external.h"
#include "mohawk/livingbooks.h"
+#include "mohawk/cstime.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
@@ -703,4 +704,54 @@
return true;
}
+CSTimeConsole::CSTimeConsole(MohawkEngine_CSTime *vm) : GUI::Debugger(), _vm(vm) {
+ DCmd_Register("playSound", WRAP_METHOD(CSTimeConsole, Cmd_PlaySound));
+ DCmd_Register("stopSound", WRAP_METHOD(CSTimeConsole, Cmd_StopSound));
+ DCmd_Register("drawImage", WRAP_METHOD(CSTimeConsole, Cmd_DrawImage));
+ DCmd_Register("drawSubimage", WRAP_METHOD(CSTimeConsole, Cmd_DrawSubimage));
+}
+
+CSTimeConsole::~CSTimeConsole() {
+}
+
+bool CSTimeConsole::Cmd_PlaySound(int argc, const char **argv) {
+ if (argc == 1) {
+ DebugPrintf("Usage: playSound <value>\n");
+ return true;
+ }
+
+ _vm->_sound->stopSound();
+ _vm->_sound->playSound((uint16)atoi(argv[1]));
+ return false;
+}
+
+bool CSTimeConsole::Cmd_StopSound(int argc, const char **argv) {
+ DebugPrintf("Stopping Sound\n");
+
+ _vm->_sound->stopSound();
+ return true;
+}
+
+bool CSTimeConsole::Cmd_DrawImage(int argc, const char **argv) {
+ if (argc == 1) {
+ DebugPrintf("Usage: drawImage <value>\n");
+ return true;
+ }
+
+ _vm->_gfx->copyAnimImageToScreen((uint16)atoi(argv[1]));
+ _vm->_system->updateScreen();
+ return false;
+}
+
+bool CSTimeConsole::Cmd_DrawSubimage(int argc, const char **argv) {
+ if (argc < 3) {
+ DebugPrintf("Usage: drawSubimage <value> <subimage>\n");
+ return true;
+ }
+
+ _vm->_gfx->copyAnimSubImageToScreen((uint16)atoi(argv[1]), (uint16)atoi(argv[2]));
+ _vm->_system->updateScreen();
+ return false;
+}
+
} // End of namespace Mohawk
Modified: scummvm/trunk/engines/mohawk/console.h
===================================================================
--- scummvm/trunk/engines/mohawk/console.h 2011-01-20 21:34:19 UTC (rev 55361)
+++ scummvm/trunk/engines/mohawk/console.h 2011-01-20 21:35:00 UTC (rev 55362)
@@ -33,6 +33,7 @@
class MohawkEngine_Myst;
class MohawkEngine_Riven;
class MohawkEngine_LivingBooks;
+class MohawkEngine_CSTime;
class MystConsole : public GUI::Debugger {
public:
@@ -99,6 +100,20 @@
bool Cmd_ChangePage(int argc, const char **argv);
};
+class CSTimeConsole : public GUI::Debugger {
+public:
+ CSTimeConsole(MohawkEngine_CSTime *vm);
+ virtual ~CSTimeConsole(void);
+
+private:
+ MohawkEngine_CSTime *_vm;
+
+ bool Cmd_PlaySound(int argc, const char **argv);
+ bool Cmd_StopSound(int argc, const char **argv);
+ bool Cmd_DrawImage(int argc, const char **argv);
+ bool Cmd_DrawSubimage(int argc, const char **argv);
+};
+
} // End of namespace Mohawk
#endif
Added: scummvm/trunk/engines/mohawk/cstime.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/cstime.cpp (rev 0)
+++ scummvm/trunk/engines/mohawk/cstime.cpp 2011-01-20 21:35:00 UTC (rev 55362)
@@ -0,0 +1,529 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "mohawk/cstime.h"
+#include "mohawk/cstime_cases.h"
+#include "mohawk/cstime_game.h"
+#include "mohawk/cstime_ui.h"
+#include "mohawk/cstime_view.h"
+#include "mohawk/resource.h"
+#include "mohawk/cursors.h"
+#include "mohawk/sound.h"
+#include "mohawk/video.h"
+
+#include "common/events.h"
+#include "common/EventRecorder.h"
+
+#include "engines/util.h"
+
+namespace Mohawk {
+
+MohawkEngine_CSTime::MohawkEngine_CSTime(OSystem *syst, const MohawkGameDescription *gamedesc) : MohawkEngine(syst, gamedesc) {
+ _rnd = new Common::RandomSource();
+ g_eventRec.registerRandomSource(*_rnd, "cstime");
+
+ _state = kCSTStateStartup;
+
+ reset();
+}
+
+MohawkEngine_CSTime::~MohawkEngine_CSTime() {
+ delete _interface;
+ delete _view;
+ delete _console;
+ delete _gfx;
+ delete _rnd;
+}
+
+Common::Error MohawkEngine_CSTime::run() {
+ MohawkEngine::run();
+
+ _console = new CSTimeConsole(this);
+ _gfx = new CSTimeGraphics(this);
+ _cursor = new DefaultCursorManager(this, ID_CURS);
+
+ _interface = new CSTimeInterface(this);
+
+ _view = new CSTimeView(this);
+ _view->setupView();
+ _view->setModule(new CSTimeModule(this));
+
+ while (!shouldQuit()) {
+ switch (_state) {
+ case kCSTStateStartup:
+ // We just jump straight to the case for now.
+ _state = kCSTStateNewCase;
+ break;
+
+ case kCSTStateNewCase:
+ initCase();
+ _state = kCSTStateNewScene;
+ break;
+
+ case kCSTStateNewScene:
+ nextScene();
+ _state = kCSTStateNormal;
+ break;
+
+ case kCSTStateNormal:
+ update();
+ break;
+ }
+ }
+
+ return Common::kNoError;
+}
+
+void MohawkEngine_CSTime::update() {
+ Common::Event event;
+ while (_eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_MOUSEMOVE:
+ _interface->mouseMove(event.mouse);
+ _needsUpdate = true;
+ break;
+
+ case Common::EVENT_LBUTTONUP:
+ _interface->mouseUp(event.mouse);
+ break;
+
+ case Common::EVENT_LBUTTONDOWN:
+ _interface->mouseDown(event.mouse);
+ break;
+
+ case Common::EVENT_RBUTTONDOWN:
+ // (All of this case is only run if the relevant option is enabled.)
+
+ // FIXME: Don't do these if the options are open.
+ if (_case->getCurrScene()->_activeChar->_flappingState != 0xffff)
+ _case->getCurrScene()->_activeChar->interruptFlapping();
+ if (getCurrentEventType() == kCSTimeEventWaitForClick)
+ mouseClicked();
+
+ // TODO: This is always run, even if not in-game.
+ //pauseCurrentNIS();
+ //stopSound();
+ // FIXME: There's some more stuff here.
+ break;
+
+ case Common::EVENT_KEYDOWN:
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_d:
+ if (event.kbd.flags & Common::KBD_CTRL) {
+ _console->attach();
+ _console->onFrame();
+ }
+ break;
+
+ case Common::KEYCODE_SPACE:
+ pauseGame();
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ _needsUpdate = true;
+
+ if (_video->updateMovies())
+ _needsUpdate = true;
+
+ if (_needsUpdate) {
+ _view->_needsUpdate = true;
+ _needsUpdate = false;
+ }
+
+ eventIdle();
+ _interface->idle();
+
+ // Cut down on CPU usage
+ _system->delayMillis(10);
+}
+
+void MohawkEngine_CSTime::initCase() {
+ _interface->openResFile();
+ _interface->install();
+ _interface->cursorInstall();
+ // TODO: _interface->paletteOff(true);
+ _interface->cursorActivate(true);
+ _interface->cursorSetShape(1, false);
+ for (uint i = 0; i < 19; i++)
+ _haveInvItem[i] = 0;
+ _interface->getInventoryDisplay()->clearDisplay();
+ _interface->getCarmenNote()->clearPieces();
+ // TODO: fixup book rect for case 20
+ for (uint i = 0; i < 20; i++)
+ _caseVariable[i] = 0;
+ _case = new CSTimeCase1(this); // TODO
+ _interface->getInventoryDisplay()->install();
+ _nextSceneId = 1;
+}
+
+void MohawkEngine_CSTime::nextScene() {
+ _case->setCurrScene(_nextSceneId);
+ CSTimeScene *scene = _case->getCurrScene();
+ // TODO: scene->setState(1);
+ scene->installGroup();
+
+ _interface->draw();
+ scene->buildScene();
+ scene->setupAmbientAnims();
+ _interface->cursorSetShape(1, false);
+
+ addEvent(CSTimeEvent(kCSTimeEventWait, 0xffff, 500));
+ scene->idleAmbientAnims();
+ // TODO: startEnvironmentSound();
+ // TODO: queue one of the scene event queues, depending on whether a value is <= 1 or not
+ addEventList(scene->getEvents(false));
+ _view->idleView();
+ // TODO: maybe startMusic();
+}
+
+void MohawkEngine_CSTime::loadResourceFile(Common::String name) {
+ MohawkArchive *archive = new MohawkArchive();
+ if (!archive->open(name + ".mhk"))
+ error("failed to open %s.mhk", name.c_str());
+ _mhk.push_back(archive);
+}
+
+void MohawkEngine_CSTime::addEvent(const CSTimeEvent &event) {
+ _events.push_back(event);
+}
+
+void MohawkEngine_CSTime::addEventList(const Common::Array<CSTimeEvent> &list) {
+ for (uint i = 0; i < list.size(); i++)
+ addEvent(list[i]);
+}
+
+void MohawkEngine_CSTime::insertEventAtFront(const CSTimeEvent &event) {
+ if (_events.empty())
+ _events.push_front(event);
+ else
+ _events.insert(++_events.begin(), event);
+}
+
+uint16 MohawkEngine_CSTime::getCurrentEventType() {
+ if (_events.empty())
+ return 0xffff;
+ else
+ return _events.front().type;
+}
+
+void MohawkEngine_CSTime::eventIdle() {
+ bool done = false;
+ while (_events.size() && !done && true /* TODO: !_options->getState() */) {
+ _lastTimeout = ~0;
+
+ bool advanceQueue = true;
+ bool processEvent = true;
+ CSTimeEvent &event = _events.front();
+
+ switch (event.type) {
+ case kCSTimeEventCharPlayNIS:
+ if (_NISRunning) {
+ CSTimeChar *chr = _case->getCurrScene()->getChar(event.param1);
+ if (chr->NISIsDone()) {
+ chr->removeNIS();
+ _NISRunning = false;
+ chr->setupAmbientAnims(true);
+ _events.pop_front();
+ processEvent = false;
+ } else {
+ done = true;
+ }
+ } else {
+ advanceQueue = false;
+ }
+ break;
+
+ case kCSTimeEventNewScene:
+ if (_processingEvent) {
+ processEvent = false;
+ _events.pop_front();
+ _processingEvent = false;
+ // FIXME: check skip global, if set:
+ // stopMusic(), stopEnvironmentSound(), set scene to _nextSceneId,
+ // set scene state to 1, set state to idle loop
+ } else {
+ triggerEvent(event);
+ done = true;
+ _processingEvent = true;
+ }
+ break;
+
+ case kCSTimeEventCharStartFlapping:
+ assert(_case->getCurrScene()->_activeChar);
+ switch (_case->getCurrScene()->_activeChar->_flappingState) {
+ case 0xffff:
+ // FIXME: check skip global, if set, processEvent = false and pop event
+ advanceQueue = false;
+ break;
+ case 0:
+ _case->getCurrScene()->_activeChar->_flappingState = 0xffff;
+ _events.pop_front();
+ processEvent = false;
+ break;
+ default:
+ done = true;
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (!done && processEvent) {
+ _interface->cursorSetWaitCursor();
+ triggerEvent(event);
+ if (advanceQueue)
+ _events.pop_front();
+ }
+
+ if (!_events.size()) {
+ Common::Point pos = _system->getEventManager()->getMousePos();
+ if (_interface->_sceneRect.contains(pos))
+ _case->getCurrScene()->setCursorForCurrentPoint();
+ else
+ _interface->setCursorForCurrentPoint();
+ _interface->mouseMove(pos);
+ resetTimeout();
+ }
+ }
+}
+
+void MohawkEngine_CSTime::resetTimeout() {
+ _lastTimeout = _system->getMillis();
+}
+
+void MohawkEngine_CSTime::mouseClicked() {
+ // TODO
+}
+
+bool MohawkEngine_CSTime::NISIsRunning() {
+ if (_NISRunning || (!_events.empty() && _events.front().type == kCSTimeEventUnused63))
+ return true;
+
+ return false;
+}
+
+void MohawkEngine_CSTime::reset() {
+ _NISRunning = false;
+ _lastTimeout = ~0;
+ _processingEvent = false;
+}
+
+void MohawkEngine_CSTime::triggerEvent(CSTimeEvent &event) {
+ debug("triggerEvent: type %d, param1 %d, param2 %d", event.type, event.param1, event.param2);
+
+ switch (event.type) {
+ case kCSTimeEventNothing:
+ case kCSTimeEventUnused8:
+ case kCSTimeEventUnused21:
+ case kCSTimeEventUnused63:
+ break;
+
+ case kCSTimeEventCondition:
+ _case->handleConditionalEvent(event);
+ break;
+
+ case kCSTimeEventCharPlayNIS:
+ _case->getCurrScene()->getChar(event.param1)->playNIS(event.param2);
+ _NISRunning = true;
+ break;
+
+ case kCSTimeEventStartConversation:
+ _case->setConversation(event.param2);
+ _case->getCurrConversation()->setSourceChar(event.param1);
+ _case->getCurrConversation()->incrementTalkCount();
+ _case->getCurrConversation()->start();
+ break;
+
+ case kCSTimeEventNewScene:
+ if (_case->getCurrConversation()->getState() != (uint)~0)
+ _case->getCurrConversation()->end(false);
+ _interface->clearTextLine();
+ // TODO: _interface->fadeDown();
+ _interface->cursorSetShape(1);
+ // TODO: swap cursor
+ // TODO: unloadPreloadedSounds?
+ if (_interface->getInventoryDisplay()->getState() == 4) {
+ _interface->getInventoryDisplay()->hide();
+ _interface->getInventoryDisplay()->setState(0);
+ }
+ // TODO: stupid case 20 handling
+ _case->getCurrScene()->leave();
+ // TODO: set dim palette(true)
+ _view->_needsUpdate = true;
+ _view->idleView();
+ // TODO: set dim palette(false)
+ _nextSceneId = event.param2;
+ _state = kCSTStateNewScene;
+ break;
+
+ case kCSTimeEventCharStartFlapping:
+ {
+ CSTimeChar *chr = _case->getCurrScene()->getChar(event.param1);
+ if (!chr->_enabled) {
+ // FIXME
+ warning("chr not enabled in kCSTimeEventCharStartFlapping");
+ break;
+ }
+
+ chr->startFlapping(event.param2);
+ if (event.param2)
+ _interface->drawTextIdToBubble(event.param2);
+
+ CSTimeEvent newEvent;
+ newEvent.param1 = 0xffff;
+ newEvent.param2 = 0xffff;
+
+ newEvent.type = kCSTimeEventUnknown70;
+ insertEventAtFront(newEvent);
+
+ newEvent.type = kCSTimeEventUpdateBubble;
+ insertEventAtFront(newEvent);
+
+ newEvent.type = kCSTimeEventUnknown69;
+ insertEventAtFront(newEvent);
+ }
+ break;
+
+ case kCSTimeEventDropItemInInventory:
+ _interface->dropItemInInventory(event.param2);
+ break;
+
+ case kCSTimeEventAddNotePiece:
+ _interface->clearTextLine();
+ _interface->getCarmenNote()->addPiece(event.param2, event.param1);
+ break;
+
+ case kCSTimeEventDisableHotspot:
+ _case->getCurrScene()->getHotspot(event.param2).state = 0;
+ break;
+
+ case kCSTimeEventDisableFeature:
+ if (!_case->getCurrScene()->_objectFeatures[event.param2])
+ break;
+ _view->removeFeature(_case->getCurrScene()->_objectFeatures[event.param2], true);
+ _case->getCurrScene()->_objectFeatures[event.param2] = NULL;
+ break;
+
+ case kCSTimeEventAddFeature:
+ // TODO: merge this with buildScene somehow?
+ if (_case->getCurrScene()->_objectFeatures[event.param2]) {
+ _case->getCurrScene()->_objectFeatures[event.param2]->resetFeatureScript(1, 0);
+ break;
+ }
+ {
+ uint32 flags = kFeatureSortStatic | kFeatureNewNoLoop | kFeatureNewDisableOnReset;
+ _case->getCurrScene()->_objectFeatures[event.param2] = _view->installViewFeature(_case->getCurrScene()->getSceneId() + event.param2, flags, NULL);
+ // FIXME: a mess of priority stuff
+ }
+ break;
+
+ case kCSTimeEventEnableHotspot:
+ _case->getCurrScene()->getHotspot(event.param2).state = 1;
+ break;
+
+ case kCSTimeEventSetAsked:
+ uint qar, entry;
+ qar = event.param2 / 5;
+ entry = event.param2 % 5;
+ if (qar > 7)
+ error("SetAsked event out of range");
+ _case->getCurrConversation()->setAsked(qar, entry);
+ break;
+
+ case kCSTimeEventShowBigNote:
+ _interface->getCarmenNote()->drawBigNote();
+ break;
+
+ case kCSTimeEventActivateCuffs:
+ _interface->getInventoryDisplay()->activateCuffs(true);
+ break;
+
+ case kCSTimeEventUnknown25:
+ _case->getCurrScene()->getChar(event.param1)->_unknown2 = 1;
+ break;
+
+ case kCSTimeEventUnknown26:
+ _case->getCurrScene()->getChar(event.param1)->_unknown2 = 0;
+ break;
+
+ case kCSTimeEventWait:
+ warning("ignoring wait");
+ // FIXME
+ break;
+
+ case kCSTimeEventUpdateBubble:
+ switch (event.param2) {
+ case 0:
+ // FIXME
+ warning("ignoring bubble update (queue events)");
+ break;
+ case 1:
+ // FIXME
+ warning("ignoring bubble update (install)");
+ break;
+ default:
+ _interface->closeBubble();
+ break;
+ }
+ break;
+
+ case kCSTimeEventInitScene:
+ _interface->displayTextLine("");
+
+ // FIXME: install palette
+
+ // FIXME: swapCursor(true)
+ break;
+
+ case kCSTimeEventUnknown69:
+ // TODO: if persistent text, insert a kCSTimeEventWaitForClick in front of the queue
+ break;
+
+ case kCSTimeEventUnknown70:
+ if (_case->getCurrConversation()->getState() != 0xffff && _case->getCurrConversation()->getState()) {
+ _case->getCurrConversation()->finishProcessingQaR();
+ } else {
+ // FIXME: handle help stuff
+ warning("ignoring unknown 70");
+ }
+ break;
+
+ default:
+ error("unknown scene event type %d", event.type);
+ }
+}
+
+} // End of namespace Mohawk
Property changes on: scummvm/trunk/engines/mohawk/cstime.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/mohawk/cstime.h
===================================================================
--- scummvm/trunk/engines/mohawk/cstime.h (rev 0)
+++ scummvm/trunk/engines/mohawk/cstime.h 2011-01-20 21:35:00 UTC (rev 55362)
@@ -0,0 +1,191 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef MOHAWK_CSTIME_H
+#define MOHAWK_CSTIME_H
+
+#include "mohawk/mohawk.h"
+#include "mohawk/console.h"
+#include "mohawk/graphics.h"
+
+#include "common/random.h"
+#include "common/list.h"
+
+#include "sound/mixer.h"
+
+namespace Mohawk {
+
+class CSTimeCase;
+class CSTimeInterface;
+class CSTimeView;
+
+enum {
+ kCSTimeEventNothing = 0xffff,
+ kCSTimeEventCondition = 1,
+ kCSTimeEventCharPlayNIS = 2,
+ kCSTimeEventStartConversation = 3,
+ kCSTimeEventNewScene = 4,
+ kCSTimeEventCharStartFlapping = 5,
+ kCSTimeEventSetCaseVariable = 6,
+ kCSTimeEventSetupAmbientAnims = 7,
+ kCSTimeEventUnused8 = 8,
+ kCSTimeEventDropItemInInventory = 9,
+ kCSTimeEventRemoveItemFromInventory = 10,
+ kCSTimeEventAddNotePiece = 11,
+ kCSTimeEventDisableHotspot = 12,
+ kCSTimeEventDisableFeature = 13,
+ kCSTimeEventAddFeature = 14,
+ kCSTimeEventStartMusic = 15,
+ kCSTimeEventStopMusic = 16,
+ kCSTimeEventEnableHotspot = 17,
+ kCSTimeEventSetAsked = 18,
+ kCSTimeEventStartHelp = 19,
+ kCSTimeEventPlaySound = 20,
+ kCSTimeEventUnused21 = 21,
+ kCSTimeEventShowBigNote = 22,
+ kCSTimeEventActivateCuffs = 23,
+ kCSTimeEventSetupRestPos = 24, // TODO
+ kCSTimeEventUnknown25 = 25,
+ kCSTimeEventUnknown26 = 26,
+ kCSTimeEventRemoveChar = 27,
+ kCSTimeEventUnknown28 = 28,
+ kCSTimeEventUnknown29 = 29,
+ kCSTimeEventUnknown30 = 30,
+ kCSTimeEventUnknown31 = 31,
+ kCSTimeEventCharSomeNIS32 = 32,
+ kCSTimeEventCharResetNIS = 33,
+ kCSTimeEventUnknown34 = 34,
+ kCSTimeEventCharPauseAmbients = 35,
+ kCSTimeEventCharUnauseAmbients = 36,
+ kCSTimeEventCharDisableAmbients = 37,
+ kCSTimeEventStopAmbientAnims = 38,
+ kCSTimeEventUnknown39 = 39,
+ kCSTimeEventWait = 40,
+ kCSTimeEventSpeech = 41,
+ kCSTimeEventUnknown42 = 42,
+ kCSTimeEventUnknown43 = 43,
+ kCSTimeEventCharSetupRestPos = 44, // TODO
+ kCSTimeEventCharStopAmbients = 45,
+ kCSTimeEventCharRestartAmbients = 46,
+ kCSTimeEventStopEnvironmentSound = 47,
+ kCSTimeEventWaitForClick = 48,
+ kCSTimeEventSetMusic = 49,
+ kCSTimeEventStartEnvironmentSound = 50,
+ kCSTimeEventPreloadSound = 51,
+ kCSTimeEventPlayPreloadedSound = 52,
+ kCSTimeEventUnknown53 = 53,
+ kCSTimeEventSetEnvironmentSound = 54,
+ kCSTimeEventCharSomeNIS55 = 55,
+ kCSTimeEventUnknown56 = 56,
+ kCSTimeEventUpdateBubble = 57,
+ kCSTimeEventCharSurfAndFlap = 58,
+ kCSTimeEventInitScene = 59,
+ kCSTimeEventFadeDown = 60,
+ kCSTimeEventCharSomeNIS61 = 61,
+ kCSTimeEventCharPlaySimultaneousAnim = 62,
+ kCSTimeEventUnused63 = 63,
+ kCSTimeEventUnknown64 = 64,
+ kCSTimeEventPrepareSave = 65,
+ kCSTimeEventSave = 66,
+ kCSTimeEventQuit = 67,
+ kCSTimeEventPlayMovie = 68,
+ kCSTimeEventUnknown69 = 69, // queues Unknown48
+ kCSTimeEventUnknown70 = 70 // conv/QaR cleanup
+};
+
+struct CSTimeEvent {
+ CSTimeEvent() { }
+ CSTimeEvent(uint16 t, uint16 p1, uint16 p2) : type(t), param1(p1), param2(p2) { }
+
+ uint16 type;
+ uint16 param1;
+ uint16 param2;
+};
+
+enum CSTimeState {
+ kCSTStateStartup,
+ kCSTStateNewCase,
+ kCSTStateNewScene,
+ kCSTStateNormal
+};
+
+class MohawkEngine_CSTime : public MohawkEngine {
+protected:
+ Common::Error run();
+
+public:
+ MohawkEngine_CSTime(OSystem *syst, const MohawkGameDescription *gamedesc);
+ virtual ~MohawkEngine_CSTime();
+
+ Common::RandomSource *_rnd;
+
+ CSTimeGraphics *_gfx;
+ bool _needsUpdate;
+
+ GUI::Debugger *getDebugger() { return _console; }
+ CSTimeView *getView() { return _view; }
+ CSTimeCase *getCase() { return _case; }
+ CSTimeInterface *getInterface() { return _interface; }
+
+ void loadResourceFile(Common::String name);
+
+ void addEvent(const CSTimeEvent &event);
+ void addEventList(const Common::Array<CSTimeEvent> &list);
+ void insertEventAtFront(const CSTimeEvent &event);
+ uint16 getCurrentEventType();
+ void eventIdle();
+ void resetTimeout();
+ void mouseClicked();
+ bool NISIsRunning();
+
+ uint16 _haveInvItem[19];
+ uint16 _caseVariable[20];
+
+private:
+ CSTimeCase *_case;
+ CSTimeConsole *_console;
+ CSTimeInterface *_interface;
+ CSTimeView *_view;
+
+ CSTimeState _state;
+
+ void initCase();
+ void nextScene();
+ void update();
+
+ uint16 _nextSceneId;
+
+ bool _processingEvent;
+ bool _NISRunning;
+ uint32 _lastTimeout;
+ void reset();
+
+ Common::List<CSTimeEvent> _events;
+ void triggerEvent(CSTimeEvent &event);
+};
+
+} // End of namespace Mohawk
+
+#endif
Property changes on: scummvm/trunk/engines/mohawk/cstime.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/mohawk/cstime_cases.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/cstime_cases.cpp (rev 0)
+++ scummvm/trunk/engines/mohawk/cstime_cases.cpp 2011-01-20 21:35:00 UTC (rev 55362)
@@ -0,0 +1,241 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "mohawk/cstime_cases.h"
+#include "mohawk/cstime_ui.h"
+
+namespace Mohawk {
+
+CSTimeCase1::CSTimeCase1(MohawkEngine_CSTime *vm) : CSTimeCase(vm, 1) {
+}
+
+CSTimeCase1::~CSTimeCase1() {
+}
+
+bool CSTimeCase1::checkConvCondition(uint16 conditionId) {
+ const Common::Array<CSTimeHotspot> &hotspots = getCurrScene()->getHotspots();
+
+ bool gotTorch = _vm->_haveInvItem[1];
+
+ // These are all for conversations in the first scene (with the boatman).
+ switch (conditionId) {
+ case 0:
+ // Got the torch?
+ return (gotTorch);
+ case 1:
+ // Is the bag still on land?
+ return (hotspots[5].state == 1);
+ case 2:
+ // Is the bag on the boat, but player hasn't taken the torch?
+ return (hotspots[5].state != 1 && !gotTorch);
+ }
+
+ return false;
+}
+
+bool CSTimeCase1::checkAmbientCondition(uint16 charId, uint16 ambientId) {
+ return true;
+}
+
+bool CSTimeCase1::checkObjectCondition(uint16 objectId) {
+ const Common::Array<CSTimeHotspot> &hotspots = getCurrScene()->getHotspots();
+
+ switch (_currScene) {
+ case 1:
+ switch (objectId) {
+ case 1:
+ // Hide bag on boat if it's not there.
+ return (hotspots[5].state == 1);
+ case 2:
+ // Hide bag on land if it's not there.
+ return (hotspots[5].state != 1);
+ case 3:
+ // Hide torch if it's been picked up.
+ return (hotspots[4].state == 1);
+ }
+ break;
+
+ case 2:
+ // The first note piece.
+ return !_vm->getInterface()->getCarmenNote()->havePiece(0);
+
+ case 3:
+ // The features representing different stages in the body sequence.
+ if (objectId == 6 && _vm->_caseVariable[3] != 0)
+ return false;
+ else if (objectId == 7 && _vm->_caseVariable[3] != 1)
+ return false;
+ else if (objectId == 8 && _vm->_caseVariable[3] != 2)
+ return false;
+ break;
+
+ case 4:
+ // The second note piece?
+ if (objectId == 0)
+ return (hotspots[0].state > 0);
+ break;
+
+ case 5:
+ // The third note piece.
+ if (objectId == 1)
+ return !_vm->getInterface()->getCarmenNote()->havePiece(2);
+ }
+
+ return true;
+}
+
+void CSTimeCase1::selectHelpStrings() {
+ if (_currScene == 1) {
+ if (_vm->_haveInvItem[1]) {
+ // Got the torch, ready to leave.
+ // FIXME
+ } else {
+ // Still don't have the torch.
+ // FIXME
+ }
+ } else {
+ // FIXME
+ }
+
+ // FIXME
+}
+
+void CSTimeCase1::handleConditionalEvent(const CSTimeEvent &event) {
+ CSTimeEvent newEvent;
+
+ switch (event.param2) {
+ case 0:
+ // Trying to enter the first room of the tomb.
+ if (!_conversations[1]->getAsked(2, 0)) {
+ // We need a plan first.
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, getCurrScene()->getHelperId(), 12352));
+ } else if (!_vm->getInterface()->getCarmenNote()->havePiece(0)) {
+ // Shouldn't we take a look at that note?
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, getCurrScene()->getHelperId(), 10355));
+ } else {
+ // Onward!
+ _vm->addEvent(CSTimeEvent(kCSTimeEventNewScene, event.param1, 3));
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, 1, 12551));
+ }
+ break;
+
+ case 1:
+ // Poking at the jars. The response depends on whether the hieroglyphs on the tomb wall
+ // have been seen yet or not.
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, getCurrScene()->getHelperId(),
+ _vm->_caseVariable[2] ? 14304 : 14303));
+ break;
+
+ case 2:
+ // FIXME: Leaving the mummy-preparing room?
+ error("cond event 2");
+ break;
+
+ case 3:
+ // FIXME: Body sequence stuff.
+ error("cond event 3");
+ break;
+
+ case 4:
+ // Woven bag dragged.
+ if (_conversations[0]->getAsked(2, 1)) {
+ // We were asked to move it.
+ if (event.param1 == 5) {
+ // Yay, the player got it on the boat!
+ // Congratulate the player and enable the torch.
+ _vm->insertEventAtFront(CSTimeEvent(kCSTimeEventCharStartFlapping, 2, 10551));
+ getCurrScene()->getHotspot(4).invObjId = 1;
+ _vm->insertEventAtFront(CSTimeEvent(kCSTimeEventEnableHotspot, 2, 6));
+ _vm->insertEventAtFront(CSTimeEvent(kCSTimeEventAddFeature, 2, 2));
+ } else {
+ assert(event.param1 < 7);
+ // It didn't get dropped onto the boat, so we complain about it.
+ newEvent.type = kCSTimeEventCharStartFlapping;
+ // Does the Good Guide complain (if we gave it to her, or put it in the inventory)?
+ newEvent.param1 = (event.param1 == 1 || event.param1 == 6) ? getCurrScene()->getHelperId() : 2;
+ // Which string?
+ static const uint16 strings[7] = { 30201, 30103, 30202, 30203, 30203, 0, 10352};
+ newEvent.param2 = strings[event.param1];
+ _vm->insertEventAtFront(newEvent);
+ }
+ } else {
+ // We're just randomly moving the woven bag!
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, getCurrScene()->getHelperId(), 10351));
+
+ if (event.param1 == 5) {
+ // This went onto the boat hotspot, so the bag was removed; put it back.
+ _vm->insertEventAtFront(CSTimeEvent(kCSTimeEventEnableHotspot, 0xffff, 5));
+ _vm->insertEventAtFront(CSTimeEvent(kCSTimeEventAddFeature, 0xffff, 1));
+ }
+ }
+ break;
+
+ case 5:
+ // We're ready to shove off!
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, getCurrScene()->getHelperId(), 10356));
+ break;
+
+ case 6:
+ // Trying to leave the first scene by walking.
+ if (_vm->_haveInvItem[1]) {
+ // If you have the torch, the Good Guide prods you to use the boat.
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, getCurrScene()->getHelperId(), 10305));
+ } else {
+ // Otherwise, the boatman tells you that you can't leave yet.
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, 2, 10506));
+ }
+ break;
+
+ case 7:
+ // Clicking on the woven bag.
+ if (_conversations[0]->getAsked(2, 0)) {
+ // If we were asked to move it, the Good Guide prods us to try dragging.
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, getCurrScene()->getHelperId(), 10306));
+ } else {
+ // Otherwise, the boatman tells us what it is.
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, 2, 10502));
+ }
+ break;
+
+ case 8:
+ // One-time-only reminder that you can re-ask questions.
+ if (_vm->_caseVariable[7])
+ break;
+ _vm->_caseVariable[7] = 1;
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, 0, 12359));
+ break;
+
+ case 9:
+ // Trying to give the torch to the Good Guide; you get a different message
+ // depending on whether it's already in your inventory or not.
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, 0, _vm->_haveInvItem[1] ? 9906 : 30119));
+ break;
+
+ default:
+ error("unknown Conditional Event type %d for case 1", event.param2);
+ }
+}
+
+} // End of namespace Mohawk
Property changes on: scummvm/trunk/engines/mohawk/cstime_cases.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/mohawk/cstime_cases.h
===================================================================
--- scummvm/trunk/engines/mohawk/cstime_cases.h (rev 0)
+++ scummvm/trunk/engines/mohawk/cstime_cases.h 2011-01-20 21:35:00 UTC (rev 55362)
@@ -0,0 +1,47 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef MOHAWK_CSTIME_CASES_H
+#define MOHAWK_CSTIME_CASES_H
+
+#include "mohawk/cstime_game.h"
+
+namespace Mohawk {
+
+class CSTimeCase1 : public CSTimeCase {
+public:
+ CSTimeCase1(MohawkEngine_CSTime *vm);
+ ~CSTimeCase1();
+
+ bool checkConvCondition(uint16 conditionId);
+ bool checkAmbientCondition(uint16 charId, uint16 ambientId);
+ bool checkObjectCondition(uint16 objectId);
+ void selectHelpStrings();
+ void handleConditionalEvent(const CSTimeEvent &event);
+};
+
+} // End of namespace Mohawk
+
+#endif
Property changes on: scummvm/trunk/engines/mohawk/cstime_cases.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/mohawk/cstime_game.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/cstime_game.cpp (rev 0)
+++ scummvm/trunk/engines/mohawk/cstime_game.cpp 2011-01-20 21:35:00 UTC (rev 55362)
@@ -0,0 +1,1236 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "mohawk/cstime_game.h"
+#include "mohawk/cstime_ui.h"
+#include "mohawk/cstime_view.h"
+#include "mohawk/resource.h"
+#include "mohawk/sound.h"
+#include "common/events.h"
+
+namespace Mohawk {
+
+// read a null-terminated string from a stream
+static Common::String readString(Common::SeekableReadStream *stream) {
+ Common::String ret;
+ while (!stream->eos()) {
+ byte in = stream->readByte();
+ if (!in)
+ break;
+ ret += in;
+ }
+ return ret;
+}
+
+// read a rect from a stream
+Common::Rect readRect(Common::SeekableReadStream *stream) {
+ Common::Rect rect;
+
+ rect.left = stream->readSint16BE();
+ rect.top = stream->readSint16BE();
+ rect.right = stream->readSint16BE();
+ rect.bottom = stream->readSint16BE();
+
+ return rect;
+}
+
+void Region::loadFrom(Common::SeekableReadStream *stream) {
+ uint16 rectCount = stream->readUint16BE();
+ if (!rectCount) {
+ // TODO: why this?
+ stream->skip(2);
+ rectCount = stream->readUint16BE();
+ }
+ for (uint i = 0; i < rectCount; i++) {
+ Common::Rect rect = readRect(stream);
+ if (!rect.isValidRect())
+ continue;
+ _rects.push_back(rect);
+ }
+}
+
+bool Region::containsPoint(Common::Point &pos) const {
+ for (uint i = 0; i < _rects.size(); i++)
+ if (_rects[i].contains(pos))
+ return true;
+
+ return false;
+}
+
+CSTimeChar::CSTimeChar(MohawkEngine_CSTime *vm, CSTimeScene *scene, uint id) : _vm(vm), _scene(scene), _id(id) {
+ _resting = true;
+ _flappingState = 0xffff;
+ _surfingState = 0;
+
+ _NIS = NULL;
+ _restFeature = NULL;
+ _talkFeature = NULL;
+
+ _talkFeature1 = NULL;
+ _talkFeature2 = NULL;
+ _talkFeature3 = NULL;
+ _lastTime1 = 0;
+ _lastTime2 = 0;
+ _lastTime3 = 0;
+
+ _playingWaveId = 0;
+}
+
+CSTimeChar::~CSTimeChar() {
+}
+
+void CSTimeChar::idle() {
+ if (!_unknown2)
+ return;
+
+ if (_flappingState == 1) {
+ idleTalk();
+ return;
+ }
+
+ if (!_NIS)
+ idleAmbients();
+}
+
+void CSTimeChar::setupAmbientAnims(bool onetime) {
+ CSTimeConversation *conv = _vm->getCase()->getCurrConversation();
+ if (_unknown1 == 0xffff || !_unknown2 || !_ambients.size() || !_resting || !_enabled ||
+ (conv->getState() != (uint)~0 && conv->getSourceChar() == _id)) {
+ setupRestPos();
+ _resting = true;
+ return;
+ }
+
+ removeChr();
+ for (uint i = 0; i < _ambients.size(); i++) {
+ // FIXME: check ambient condition
+ uint32 flags = kFeatureSortStatic;
+ if (_ambients[i].delay != 0xffff) {
+ flags |= kFeatureNewNoLoop;
+ if (onetime)
+ flags |= kFeatureNewDisableOnReset;
+ }
+ installAmbientAnim(i, flags);
+ }
+}
+
+void CSTimeChar::idleAmbients() {
+ if (_flappingState != 0xffff)
+ return;
+
+ for (uint i = 0; i < _ambients.size(); i++) {
+ if (!_ambients[i].feature)
+ continue;
+ uint16 delay = _ambients[i].delay;
+ if (delay == 0xffff)
+ continue;
+ uint32 now = _vm->_system->getMillis();
+ if (now < _ambients[i].nextTime)
+ continue;
+ _ambients[i].feature->resetFeatureScript(1, 0);
+ _ambients[i].nextTime = now + delay;
+ }
+}
+
+void CSTimeChar::stopAmbients(bool restpos) {
+ for (uint i = 0; i < _ambients.size(); i++) {
+ if (!_ambients[i].feature)
+ continue;
+ _vm->getView()->removeFeature(_ambients[i].feature, true);
+ _ambients[i].feature = NULL;
+ }
+
+ if (restpos)
+ setupRestPos();
+}
+
+void CSTimeChar::setupRestPos() {
+ if (_unknown1 == 0xffff || !_unknown1 || !_unknown2)
+ return;
+
+ if (!_restFeature) {
+ uint id = 0; // FIXME
+ uint32 flags = kFeatureSortStatic | kFeatureNewNoLoop | kFeatureNewDisableOnReset;
+ Feature *feature = _vm->getView()->installViewFeature(getChrBaseId() + id, flags, NULL);
+ // FIXME: fix priorities
+ _restFeature = feature;
+ } else {
+ _restFeature->resetFeatureScript(1, 0);
+ }
+
+ // FIXME: fix more priorities
+}
+
+void CSTimeChar::removeChr() {
+ if (_unknown1 == 0xffff || !_unknown1)
+ return;
+
+ if (_talkFeature) {
+ _vm->getView()->removeFeature(_talkFeature, true);
+ _vm->getView()->removeFeature(_talkFeature3, true);
+ if (_talkFeature1)
+ _vm->getView()->removeFeature(_talkFeature1, true);
+ if (_unknown1 > 1)
+ _vm->getView()->removeFeature(_talkFeature2, true);
+ }
+
+ if (_restFeature)
+ _vm->getView()->removeFeature(_restFeature, true);
+
+ _talkFeature1 = NULL;
+ _talkFeature2 = NULL;
+ _talkFeature3 = NULL;
+
+ _talkFeature = NULL;
+ _restFeature = NULL;
+}
+
+uint16 CSTimeChar::getChrBaseId() {
+ return _scene->getSceneId() + (_id + 1) * 200;
+}
+
+uint CSTimeChar::getScriptCount() {
+ static uint bases[4] = { 0, 10, 13, 21 };
+ assert(_unknown1 < 4);
+ return bases[_unknown1] + _ambients.size() + _unknown3;
+}
+
+void CSTimeChar::playNIS(uint16 id) {
+ if (_NIS)
+ removeNIS();
+ stopAmbients(false);
+ removeChr();
+ uint32 flags = kFeatureSortStatic | kFeatureNewNoLoop;
+ _NIS = _vm->getView()->installViewFeature(getChrTypeScriptBase() + id + _ambients.size(), flags, NULL);
+ // FIXME: fix priorities
+}
+
+bool CSTimeChar::NISIsDone() {
+ return (_NIS->_data.paused || !_NIS->_data.enabled);
+}
+
+void CSTimeChar::removeNIS() {
+ if (!_NIS)
+ return;
+ _vm->getView()->removeFeature(_NIS, true);
+ _NIS = NULL;
+}
+
+void CSTimeChar::startFlapping(uint16 id) {
+ if (!_unknown2)
+ return;
+
+ _scene->_activeChar = this;
+ if (_restFeature) {
+ _vm->getView()->removeFeature(_restFeature, true);
+ _restFeature = NULL;
+ }
+ stopAmbients(false);
+ setupTalk();
+ _flappingState = 1;
+ playFlapWave(id);
+}
+
+void CSTimeChar::interruptFlapping() {
+ if (_playingWaveId)
+ _vm->_sound->stopSound(_playingWaveId);
+ // TODO: kill any other (preload) sound
+ _waveStatus = 'q';
+}
+
+void CSTimeChar::installAmbientAnim(uint id, uint32 flags) {
+ Feature *feature = _vm->getView()->installViewFeature(getChrTypeScriptBase() + id, flags, NULL);
+ // FIXME: fix priorities
+
+ _ambients[id].feature = feature;
+ _ambients[id].nextTime = _vm->_system->getMillis() + _ambients[id].delay;
+}
+
+uint16 CSTimeChar::getChrTypeScriptBase() {
+ static uint bases[4] = { 0, 10, 13, 21 };
+ assert(_unknown1 < 4);
+ return bases[_unknown1] + getChrBaseId();
+}
+
+void CSTimeChar::playFlapWave(uint16 id) {
+ _playingWaveId = id;
+ _vm->_sound->playSound(id, Audio::Mixer::kMaxChannelVolume, false, &_cueList);
+ _nextCue = 0;
+ _waveStatus = 'b';
+}
+
+void CSTimeChar::updateWaveStatus() {
+ // This is a callback in the original, handling audio events.
+ assert(_playingWaveId);
+
+ // FIXME: state 's' for .. something? stopped?
+ if (!_vm->_sound->isPlaying(_playingWaveId)) {
+ _waveStatus = 'q';
+ return;
+ }
+
+ uint samples = _vm->_sound->getNumSamplesPlayed(_playingWaveId);
+ for (uint i = _nextCue; i < _cueList.pointCount; i++) {
+ if (_cueList.points[i].sampleFrame > samples)
+ return;
+ if (_cueList.points[i].name.empty())
+ warning("cue %d reached but was empty", i);
+ else
+ _waveStatus = _cueList.points[i].name[0];
+ _nextCue = i + 1;
+ }
+}
+
+void CSTimeChar::setupTalk() {
+ if (_unknown1 == 0xffff || !_unknown1 || !_unknown2 || _talkFeature)
+ return;
+
+ uint32 flags = kFeatureSortStatic | kFeatureNewNoLoop | kFeatureNewDisableOnReset;
+ _talkFeature = _vm->getView()->installViewFeature(getChrBaseId() + (_enabled ? 1 : 14), flags, NULL);
+
+ _talkFeature3 = _vm->getView()->installViewFeature(getChrBaseId() + (_enabled ? 4 : 15), flags, NULL);
+ if (_enabled) {
+ _talkFeature1 = _vm->getView()->installViewFeature(getChrBaseId() + 2, flags, NULL);
+ if (_unknown1 > 1) {
+ _talkFeature2 = _vm->getView()->installViewFeature(getChrBaseId() + 10, flags, NULL);
+ }
+ }
+ // FIXME: fix priorities
+}
+
+void CSTimeChar::idleTalk() {
+ updateWaveStatus();
+
+ if (_waveStatus == 'q') {
+ if (_surfingState) {
+ // FIXME
+ _surfingState = 0;
+ } else {
+ // FIXME
+ _playingWaveId = 0;
+ }
+ stopFlapping();
+ return;
+ }
+
+ if (_waveStatus == 's' && _surfingState) {
+ // FIXME
+ _waveStatus = 'q';
+ return;
+ }
+
+ CSTimeView *view = _vm->getView();
+
+ if (_enabled && view->getTime() > _lastTime1) {
+ _lastTime1 = view->getTime() + 2000 + _vm->_rnd->getRandomNumberRng(0, 1000);
+ if (_talkFeature1)
+ _talkFeature1->resetFeatureScript(1, getChrBaseId() + 2 + _vm->_rnd->getRandomNumberRng(0, 1));
+ }
+
+ if (_enabled && view->getTime() > _lastTime2) {
+ _lastTime2 = view->getTime() + 3000 + _vm->_rnd->getRandomNumberRng(0, 1000);
+ if (_talkFeature2)
+ _talkFeature2->resetFeatureScript(1, getChrBaseId() + 10 + _vm->_rnd->getRandomNumberRng(0, 2));
+ }
+
+ if (_waveStatus == 'c') {
+ if (_talkFeature3)
+ _talkFeature3->resetFeatureScript(1, getChrBaseId() + (_enabled ? 4 : 15));
+ } else if (view->getTime() > _lastTime3) {
+ _lastTime3 = view->getTime() + 100;
+ if (_talkFeature3)
+ _talkFeature3->resetFeatureScript(1, getChrBaseId() + (_enabled ? 4 : 15) + _vm->_rnd->getRandomNumberRng(1, 5));
+ }
+
+ // FIXME: more animations
+}
+
+void CSTimeChar::stopFlapping() {
+ _flappingState = 0;
+ removeChr();
+ // FIXME: stupid hardcoded hack for case 5
+ setupAmbientAnims(true);
+}
+
+CSTimeConversation::CSTimeConversation(MohawkEngine_CSTime *vm, uint id) : _vm(vm), _id(id) {
+ clear();
+
+ Common::SeekableReadStream *convStream = _vm->getResource(ID_CONV, id * 10 + 500);
+
+ _nameId = convStream->readUint16BE();
+ _greeting = convStream->readUint16BE();
+ _greeting2 = convStream->readUint16BE();
+
+ uint16 qarIds[8];
+ for (uint i = 0; i < 8; i++)
+ qarIds[i] = convStream->readUint16BE();
+
+ delete convStream;
+
+ for (uint i = 0; i < 8; i++) {
+ // FIXME: are they always in order?
+ if (qarIds[i] == 0xffff)
+ continue;
+ _qars.push_back(CSTimeQaR());
+ CSTimeQaR &qar = _qars.back();
+ loadQaR(qar, qarIds[i]);
+ }
+}
+
+void CSTimeConversation::start() {
+ uint16 greeting = _greeting;
+
+ if (_talkCount > 1)
+ greeting = _greeting2;
+
+ _state = 2;
+
+ if (greeting == 0xffff) {
+ finishProcessingQaR();
+ return;
+ }
+
+ CSTimeEvent event;
+ event.type = kCSTimeEventCharStartFlapping;
+ event.param1 = _sourceChar;
+ event.param2 = greeting;
+ _vm->addEvent(event);
+}
+
+void CSTimeConversation::finishProcessingQaR() {
+ if (_state == 2) {
+ _vm->getInterface()->getInventoryDisplay()->hide();
+ _vm->getInterface()->clearTextLine();
+ selectItemsToDisplay();
+ display();
+ return;
+ }
+
+ if (_nextToProcess == 0xffff)
+ return;
+
+ uint qarIndex = _itemsToDisplay[_nextToProcess];
+ CSTimeQaR &qar = _qars[qarIndex];
+
+ if (!qar.nextQaRsId) {
+ end(true);
+ _nextToProcess = 0xffff;
+ return;
+ }
+
+ if (qar.responseStringId != 0xffff) {
+ _vm->addEventList(qar.events);
+ }
+
+ if (qar.nextQaRsId == 0xffff) {
+ _qars.remove_at(qarIndex);
+ _vm->getInterface()->clearDialogLine(_nextToProcess);
+ _nextToProcess = 0xffff;
+ return;
+ }
+
+ loadQaR(qar, qar.nextQaRsId);
+ if (qar.unknown2)
+ qar.finished = true;
+ _vm->getInterface()->displayDialogLine(qar.questionStringId, _nextToProcess, qar.finished ? 13 : 32);
+
+ _nextToProcess = 0xffff;
+}
+
+void CSTimeConversation::end(bool useLastClicked, bool runEvents) {
+ if (runEvents) {
+ uint entry = _currEntry;
+ if (!useLastClicked)
+ entry = _itemsToDisplay.size() - 1;
+ CSTimeQaR &qar = _qars[_itemsToDisplay[entry]];
+ _vm->addEventList(qar.events);
+ if (_sourceChar != 0xffff)
+ _vm->getCase()->getCurrScene()->getChar(_sourceChar)->setupAmbientAnims(true);
+ }
+
+ CSTimeInterface *interface = _vm->getInterface();
+ CSTimeInventoryDisplay *invDisplay = interface->getInventoryDisplay();
+ if (invDisplay->getState() == 4) {
+ invDisplay->hide();
+ invDisplay->setState(0);
+ }
+
+ setState(~0);
+ _currHover = ~0;
+
+ interface->clearTextLine();
+ interface->clearDialogArea();
+ invDisplay->show();
+
+ // TODO: stupid case 20 stuff
+}
+
+void CSTimeConversation::display() {
+ _vm->getInterface()->clearDialogArea();
+
+ for (uint i = 0; i < _itemsToDisplay.size(); i++) {
+ // FIXME: some rect stuff?
+
+ CSTimeQaR &qar = _qars[_itemsToDisplay[i]];
+ _vm->getInterface()->displayDialogLine(qar.questionStringId, i, qar.finished ? 13 : 32);
+ }
+
+ _state = 1;
+}
+
+void CSTimeConversation::selectItemsToDisplay() {
+ _itemsToDisplay.clear();
+
+ for (uint i = 0; i < _qars.size(); i++) {
+ if (_qars[i].unknown1 != 0xffff && !_vm->getCase()->checkConvCondition(_qars[i].unknown1))
+ continue;
+ if (_itemsToDisplay.size() == 5)
+ error("Too many conversation paths");
+ _itemsToDisplay.push_back(i);
+ }
+}
+
+void CSTimeConversation::mouseDown(Common::Point &pos) {
+ if (_vm->getInterface()->getInventoryDisplay()->getState() == 4)
+ return;
+
+ // TODO: case 20 rect check
+
+ for (uint i = 0; i < _itemsToDisplay.size(); i++) {
+ Common::Rect thisRect = _vm->getInterface()->_dialogTextRect;
+ thisRect.top += 1 + i*15;
+ thisRect.bottom = thisRect.top + 15;
+ if (!thisRect.contains(pos))
+ continue;
+
+ _currEntry = i;
+ highlightLine(i);
+ _vm->getInterface()->cursorSetShape(5, true);
+ break;
+ }
+}
+
+void CSTimeConversation::mouseMove(Common::Point &pos) {
+ // TODO: case 20 rect check
+
+ bool mouseIsDown = _vm->getEventManager()->getButtonState() & 1;
+
+ for (uint i = 0; i < _itemsToDisplay.size(); i++) {
+ Common::Rect thisRect = _vm->getInterface()->_dialogTextRect;
+ thisRect.top += 1 + i*15;
+ thisRect.bottom = thisRect.top + 15;
+ if (!thisRect.contains(pos))
+ continue;
+
+ if (mouseIsDown) {
+ if (i != _currEntry)
+ break;
+ highlightLine(i);
+ }
+
+ _vm->getInterface()->cursorOverHotspot();
+ _currHover = i;
+ return;
+ }
+
+ if (_currHover != (uint)~0) {
+ if (_vm->getInterface()->cursorGetState() != 3) {
+ _vm->getInterface()->cursorSetShape(1, true);
+ if (_vm->getInterface()->getInventoryDisplay()->getState() != 4)
+ unhighlightLine(_currHover);
+ }
+ _currHover = ~0;
+ }
+}
+
+void CSTimeConversation::mouseUp(Common::Point &pos) {
+ if (_vm->getInterface()->getInventoryDisplay()->getState() == 4)
+ return;
+
+ if (_currEntry == (uint)~0)
+ return;
+
+ // TODO: case 20 rect check
+
+ CSTimeQaR &qar = _qars[_itemsToDisplay[_currEntry]];
+ Common::Rect thisRect = _vm->getInterface()->_dialogTextRect;
+ thisRect.top += 1 + _currEntry*15;
+ thisRect.bottom = thisRect.top + 15;
+ if (!thisRect.contains(pos))
+ return;
+
+ if (qar.responseStringId != 0xffff) {
+ CSTimeEvent newEvent;
+ newEvent.type = kCSTimeEventCharStartFlapping;
+ newEvent.param1 = _sourceChar;
+ newEvent.param2 = qar.responseStringId;
+ _vm->addEvent(newEvent);
+ _nextToProcess = _currEntry;
+ return;
+ }
+
+ if (!qar.nextQaRsId) {
+ _vm->getInterface()->cursorChangeShape(1);
+ end(true);
+ return;
+ }
+
+ _vm->addEventList(qar.events);
+ _nextToProcess = _currEntry;
+}
+
+void CSTimeConversation::setAsked(uint qar, uint entry) {
+ assert(qar < 8 && entry < 5);
+ _asked[qar][entry] = true;
+}
+
+void CSTimeConversation::clear() {
+ _state = ~0;
+ _talkCount = 0;
+ _sourceChar = 0xffff;
+ _currHover = ~0;
+ _currEntry = ~0;
+ _nextToProcess = 0xffff;
+ for (uint i = 0; i < 8; i++)
+ for (uint j = 0; j < 5; j++)
+ _asked[i][j] = false;
+}
+
+void CSTimeConversation::loadQaR(CSTimeQaR &qar, uint16 id) {
+ Common::SeekableReadStream *qarsStream = _vm->getResource(ID_QARS, id);
+ qar.finished = false;
+ qar.unknown1 = qarsStream->readUint16BE();
+ qar.questionStringId = qarsStream->readUint16BE();
+ qar.responseStringId = qarsStream->readUint16BE();
+ qar.unknown2 = qarsStream->readUint16BE();
+ qar.nextQaRsId = qarsStream->readUint16BE();
+ uint16 numEvents = qarsStream->readUint16BE();
+ for (uint j = 0; j < numEvents; j++) {
+ CSTimeEvent event;
+ event.type = qarsStream->readUint16BE();
+ event.param1 = qarsStream->readUint16BE();
+ event.param2 = qarsStream->readUint16BE();
+ qar.events.push_back(event);
+ }
+}
+
+void CSTimeConversation::highlightLine(uint line) {
+ CSTimeQaR &qar = _qars[_itemsToDisplay[line]];
+ _vm->getInterface()->displayDialogLine(qar.questionStringId, line, 244);
+}
+
+void CSTimeConversation::unhighlightLine(uint line) {
+ CSTimeQaR &qar = _qars[_itemsToDisplay[line]];
+ _vm->getInterface()->displayDialogLine(qar.questionStringId, line, qar.finished ? 13 : 32);
+}
+
+CSTimeCase::CSTimeCase(MohawkEngine_CSTime *vm, uint id) : _vm(vm), _id(id) {
+ _vm->loadResourceFile(Common::String::format("Cases/C%dText", id));
+ // We load this early, so we can use the text for debugging.
+ loadRolloverText();
+
+ _vm->loadResourceFile(Common::String::format("Cases/C%dInfo", id));
+ Common::SeekableReadStream *caseInfoStream = _vm->getResource(ID_CINF, 1);
+ uint16 numScenes = caseInfoStream->readUint16BE();
+ uint16 numInvObjs = caseInfoStream->readUint16BE();
+ uint16 numConversations = caseInfoStream->readUint16BE();
+ for (uint i = 0; i < 3; i++)
+ _noteFeatureId[i] = caseInfoStream->readUint16BE();
+ delete caseInfoStream;
+
+ debug("Loading %d inventory objects...", numInvObjs);
+ for (uint i = 0; i < numInvObjs; i++)
+ _inventoryObjs.push_back(loadInventoryObject(i));
+
+ _vm->loadResourceFile(Common::String::format("Cases/C%dArt", id));
+ _vm->loadResourceFile(Common::String::format("Cases/C%dDlog", id));
+
+ debug("Loading %d scenes...", numScenes);
+ for (uint i = 0; i < numScenes; i++)
+ _scenes.push_back(new CSTimeScene(_vm, this, i + 1));
+
+ debug("Loading %d conversations...", numConversations);
+ for (uint i = 0; i < numConversations; i++)
+ _conversations.push_back(new CSTimeConversation(_vm, i));
+
+ assert(!_conversations.empty());
+ _currConv = _conversations[0];
+
+ _currScene = ~0;
+}
+
+CSTimeCase::~CSTimeCase() {
+}
+
+void CSTimeCase::loadRolloverText() {
+ Common::SeekableReadStream *stringStream = _vm->getResource(ID_STRL, 9100);
+ while (stringStream->pos() < stringStream->size())
+ _rolloverText.push_back(readString(stringStream));
+ for (uint i = 0; i < _rolloverText.size(); i++)
+ debug("string %d: '%s'", i, _rolloverText[i].c_str());
+ delete stringStream;
+}
+
+CSTimeInventoryObject *CSTimeCase::loadInventoryObject(uint id) {
+ CSTimeInventoryObject *invObj = new CSTimeInventoryObject;
+ invObj->feature = NULL;
+ invObj->id = id;
+
+ Common::SeekableReadStream *invObjStream = _vm->getResource(ID_INVO, id + 1);
+ uint16 numHotspots = invObjStream->readUint16BE();
+ invObj->stringId = invObjStream->readUint16BE();
+ invObj->hotspotId = invObjStream->readUint16BE();
+ invObj->featureId = invObjStream->readUint16BE();
+ invObj->canTake = invObjStream->readUint16BE();
+ debug(" invobj '%s', hotspot id %d, feature id %d, can take %d", _rolloverText[invObj->stringId].c_str(), invObj->hotspotId, invObj->featureId, invObj->canTake);
+ uint16 numConsumableLocations = invObjStream->readUint16BE();
+ debug(" Loading %d consumable locations...", numConsumableLocations);
+ for (uint i = 0; i < numConsumableLocations; i++) {
+ CSTimeLocation location;
+ location.sceneId = invObjStream->readUint16BE();
+ location.hotspotId = invObjStream->readUint16BE();
+ invObj->locations.push_back(location);
+ }
+ uint16 numEvents = invObjStream->readUint16BE();
+ debug(" Loading %d events...", numEvents);
+ for (uint i = 0; i < numEvents; i++) {
+ CSTimeEvent event;
+ event.type = invObjStream->readUint16BE();
+ event.param1 = invObjStream->readUint16BE();
+ event.param2 = invObjStream->readUint16BE();
+ invObj->events.push_back(event);
+ }
+ debug(" Loading %d hotspots...", numHotspots);
+ for (uint i = 0; i < numHotspots; i++) {
+ CSTimeInventoryHotspot hotspot;
+ hotspot.sceneId = invObjStream->readUint16BE();
+ hotspot.hotspotId = invObjStream->readUint16BE();
+ hotspot.stringId = invObjStream->readUint16BE();
+ uint16 numHotspotEvents = invObjStream->readUint16BE();
+ debug(" scene %d, hotspot %d, string id %d, with %d hotspot events", hotspot.sceneId, hotspot.hotspotId, hotspot.stringId, numHotspotEvents);
+ for (uint j = 0; j < numHotspotEvents; j++) {
+ CSTimeEvent event;
+ event.type = invObjStream->readUint16BE();
+ event.param1 = invObjStream->readUint16BE();
+ event.param2 = invObjStream->readUint16BE();
+ hotspot.events.push_back(event);
+ }
+ invObj->hotspots.push_back(hotspot);
+ }
+ delete invObjStream;
+
+ return invObj;
+}
+
+CSTimeScene *CSTimeCase::getCurrScene() {
+ return _scenes[_currScene - 1];
+}
+
+CSTimeScene::CSTimeScene(MohawkEngine_CSTime *vm, CSTimeCase *case_, uint id) : _vm(vm), _case(case_), _id(id) {
+ _activeChar = NULL;
+ _currHotspot = ~0;
+ _hoverHotspot = ~0;
+ load();
+}
+
+void CSTimeScene::load() {
+ Common::SeekableReadStream *sceneStream = _vm->getResource(ID_SCEN, _id + 1000);
+ _unknown1 = sceneStream->readUint16BE();
+ _unknown2 = sceneStream->readUint16BE();
+ _helperId = sceneStream->readUint16BE();
+ _bubbleType = sceneStream->readUint16BE();
+ uint16 numHotspots = sceneStream->readUint16BE();
+ _numObjects = sceneStream->readUint16BE();
+ debug("Scene: unknowns %d, %d, %d, bubble type %d, %d objects", _unknown1, _unknown2, _helperId, _bubbleType, _numObjects);
+
+ uint16 numChars = sceneStream->readUint16BE();
+ uint16 numEvents = sceneStream->readUint16BE();
+ debug(" Loading %d events...", numEvents);
+ for (uint i = 0; i < numEvents; i++) {
+ CSTimeEvent event;
+ event.type = sceneStream->readUint16BE();
+ event.param1 = sceneStream->readUint16BE();
+ event.param2 = sceneStream->readUint16BE();
+ _events.push_back(event);
+ }
+ uint16 numEvents2 = sceneStream->readUint16BE();
+ debug(" Loading %d events2...", numEvents2);
+ for (uint i = 0; i < numEvents2; i++) {
+ CSTimeEvent event;
+ event.type = sceneStream->readUint16BE();
+ event.param1 = sceneStream->readUint16BE();
+ event.param2 = sceneStream->readUint16BE();
+ _events2.push_back(event);
+ }
+ debug(" Loading %d chars...", numChars);
+ for (uint i = 0; i < numChars; i++) {
+ CSTimeChar *chr = new CSTimeChar(_vm, this, i);
+ if (!_activeChar)
+ _activeChar = chr;
+ chr->_enabled = true;
+ chr->_unknown1 = sceneStream->readUint16BE();
+ chr->_unknown2 = sceneStream->readUint16BE();
+ uint16 numAmbients = sceneStream->readUint16BE();
+ chr->_unknown3 = sceneStream->readUint16BE();
+ debug(" unknowns %d, %d, %d, with %d ambients", chr->_unknown1, chr->_unknown2, chr->_unknown3, numAmbients);
+ for (uint j = 0; j < numAmbients; j++) {
+ CSTimeAmbient ambient;
+ ambient.delay = sceneStream->readUint16BE();
+ ambient.feature = NULL;
+ chr->_ambients.push_back(ambient);
+ }
+ _chars.push_back(chr);
+ }
+ debug(" Loading %d hotspots...", numHotspots);
+ for (uint i = 0; i < numHotspots; i++) {
+ CSTimeHotspot hotspot;
+ hotspot.stringId = sceneStream->readUint16BE();
+ hotspot.invObjId = sceneStream->readUint16BE();
+ hotspot.cursor = sceneStream->readUint16BE();
+ hotspot.state = sceneStream->readUint16BE();
+ uint16 numHotspotEvents = sceneStream->readUint16BE();
+ debug(" hotspot '%s', inv obj %d, cursor %d, state %d, with %d hotspot events", _case->getRolloverText(hotspot.stringId).c_str(), hotspot.invObjId, hotspot.cursor, hotspot.state, numHotspotEvents);
+ for (uint j = 0; j < numHotspotEvents; j++) {
+ CSTimeEvent event;
+ event.type = sceneStream->readUint16BE();
+ event.param1 = sceneStream->readUint16BE();
+ event.param2 = sceneStream->readUint16BE();
+ hotspot.events.push_back(event);
+ }
+ _hotspots.push_back(hotspot);
+ }
+ delete sceneStream;
+
+ Common::SeekableReadStream *hotspotStream = _vm->getResource(ID_HOTS, _id + 1100);
+ for (uint i = 0; i < _hotspots.size(); i++) {
+ _hotspots[i].region.loadFrom(hotspotStream);
+ }
+ delete hotspotStream;
+}
+
+void CSTimeScene::installGroup() {
+ uint16 resourceId = getSceneId();
+ _vm->getView()->installGroup(resourceId, _numObjects, 0, true, resourceId);
+
+ for (uint i = 0; i < _chars.size(); i++) {
+ uint count = _chars[i]->getScriptCount();
+ if (!count)
+ continue;
+ _vm->getView()->installGroup(resourceId, count, 0, true, _chars[i]->getChrBaseId());
+ }
+}
+
+void CSTimeScene::buildScene() {
+ uint16 resourceId = getSceneId();
+
+ _vm->getView()->installBG(resourceId);
+
+ for (uint i = 0; i < _numObjects; i++) {
+ if (!_case->checkObjectCondition(i)) {
+ _objectFeatures.push_back(NULL);
+ continue;
+ }
+
+ // FIXME: reset object if it already exists
+ // FIXME: deal with NULL
+ uint32 flags = kFeatureSortStatic | kFeatureNewNoLoop | kFeatureNewDisableOnReset;
+ assert(flags == 0x4C00000);
+ Feature *feature = _vm->getView()->installViewFeature(resourceId + i, flags, NULL);
+ _objectFeatures.push_back(feature);
+ }
+}
+
+void CSTimeScene::leave() {
+ for (uint i = 0; i < _objectFeatures.size(); i++) {
+ if (_objectFeatures[i] == NULL)
+ continue;
+ _vm->getView()->removeFeature(_objectFeatures[i], true);
+ _objectFeatures[i] = NULL;
+ }
+
+ for (uint i = 0; i < _chars.size(); i++) {
+ _chars[i]->stopAmbients(false);
+ _chars[i]->removeChr();
+ _chars[i]->removeNIS();
+ }
+
+ _vm->getView()->removeGroup(getSceneId());
+}
+
+uint16 CSTimeScene::getSceneId() {
+ // FIXME: there are a lot of special cases
+ uint16 resourceId = 10000 + 2000 * (_id - 1);
+ return resourceId;
+}
+
+void CSTimeScene::mouseDown(Common::Point &pos) {
+ CSTimeConversation *conv = _vm->getCase()->getCurrConversation();
+ bool convActive = (conv->getState() != (uint)~0);
+ bool helpActive = (_vm->getInterface()->getHelp()->getState() != (uint)~0);
+ if (convActive || helpActive) {
+ bool foundPoint = false;
+ for (uint i = 0; i < _hotspots.size(); i++) {
+ CSTimeHotspot &hotspot = _hotspots[i];
+ if (!hotspot.region.containsPoint(pos))
+ continue;
+ foundPoint = true;
+
+ if (!convActive) {
+ // In help mode, we ignore clicks on any help hotspot.
+ if (!hotspotContainsEvent(i, kCSTimeEventStartHelp))
+ break;
+ _currHotspot = ~0;
+ return;
+ }
+
+ // In conversation mode, we ignore clicks which would restart the current conversation.
+ for (uint j = 0; j < hotspot.events.size(); j++) {
+ if (hotspot.events[j].type != kCSTimeEventStartConversation)
+ continue;
+ // FIXME: check that the conversation *is* the current one
+ _currHotspot = ~0;
+ return;
+ }
+
+ break;
+ }
+
+ if (foundPoint) {
+ // We found a valid hotspot and we didn't ignore it, stop the conversation/help.
+ if (convActive) {
+ conv->end(false);
+ } else {
+ _vm->getInterface()->getHelp()->end();
+ }
+ }
+ } else {
+ // FIXME: check symbols
+ }
+
+ // FIXME: return if sailing puzzle
+
+ _currHotspot = ~0;
+ for (uint i = 0; i < _hotspots.size(); i++) {
+ CSTimeHotspot &hotspot = _hotspots[i];
+ if (!hotspot.region.containsPoint(pos))
+ continue;
+ if (hotspot.state != 1)
+ continue;
+ mouseDownOnHotspot(i);
+ break;
+ }
+
+ if (_currHotspot == (uint)~0)
+ _vm->getInterface()->cursorSetShape(4, false);
+}
+
+void CSTimeScene::mouseMove(Common::Point &pos) {
+ // TODO: if we're in sailing puzzle, return
+
+ bool mouseIsDown = _vm->getEventManager()->getButtonState() & 1;
+
+ if (_vm->getInterface()->getState() == kCSTimeInterfaceStateDragStart) {
+ Common::Point grabPoint = _vm->getInterface()->getGrabPoint();
+ if (mouseIsDown && (abs(grabPoint.x - pos.x) > 2 || abs(grabPoint.y - pos.y) > 2)) {
+ if (_vm->getInterface()->grabbedFromInventory()) {
+ _vm->getInterface()->startDragging(_vm->getInterface()->getInventoryDisplay()->getLastDisplayedClicked());
+ } else {
+ CSTimeHotspot &hotspot = _hotspots[_currHotspot];
+ if (_vm->_haveInvItem[hotspot.invObjId]) {
+ _vm->getInterface()->setState(kCSTimeInterfaceStateNormal);
+ } else {
+ // FIXME: special-casing for cases 9, 13, 15, 18 19
+
+ CSTimeInventoryObject *invObj = _vm->getCase()->_inventoryObjs[hotspot.invObjId];
+ if (invObj->feature)
+ error("Inventory object already had feature when dragging from scene");
+ uint16 id = 9000 + (invObj->id - 1);
+ // FIXME: 0x2000 is set! help?
+ uint32 flags = kFeatureNewNoLoop | 0x2000;
+ invObj->feature = _vm->getView()->installViewFeature(id, flags, &grabPoint);
+ _vm->getInterface()->startDragging(hotspot.invObjId);
+ }
+ }
+ }
+ }
+
+ for (uint i = 0; i < _hotspots.size(); i++) {
+ CSTimeHotspot &hotspot = _hotspots[i];
+ if (hotspot.state != 1)
+ continue;
+ if (!hotspot.region.containsPoint(pos))
+ continue;
+
+ if (_vm->getInterface()->getState() == kCSTimeInterfaceStateDragging) {
+ // Only show a hotspot here if the dragged object can be dropped onto it.
+ CSTimeInventoryObject *invObj = _vm->getCase()->_inventoryObjs[_vm->getInterface()->getDraggedNum()];
+ bool showText = false;
+ for (uint j = 0; j < invObj->hotspots.size(); j++) {
+ if (invObj->hotspots[j].sceneId != _id)
+ continue;
+ if (invObj->hotspots[j].hotspotId != i)
+ continue;
+ showText = true;
+ }
+ if (!showText)
+ continue;
+ } else {
+ // If we're not dragging but the mouse is down, ignore all hotspots
+ // except the one which was clicked on.
+ if (mouseIsDown && (i != _currHotspot))
+ continue;
+ }
+
+ if (i != _hoverHotspot);
+ _vm->getInterface()->clearTextLine();
+ cursorOverHotspot(i);
+ _hoverHotspot = i;
+ return;
+ }
+
+ if (_vm->getInterface()->getState() != kCSTimeInterfaceStateDragging) {
+ switch (_vm->getInterface()->cursorGetShape()) {
+ case 2:
+ case 13:
+ _vm->getInterface()->cursorSetShape(1);
+ break;
+ case 5:
+ case 14:
+ _vm->getInterface()->cursorSetShape(4);
+ break;
+ case 11:
+ _vm->getInterface()->cursorSetShape(10);
+ break;
+ }
+ }
+
+ if (_hoverHotspot == (uint)~0)
+ return;
+
+ CSTimeConversation *conv = _case->getCurrConversation();
+ CSTimeHelp *help = _vm->getInterface()->getHelp();
+ if (conv->getState() != (uint)~0 && conv->getState() != 0) {
+ Common::String text = "Talking to " + _case->getRolloverText(conv->getNameId());
+ _vm->getInterface()->displayTextLine(text);
+ } else if (help->getState() != (uint)~0 && help->getState() != 0) {
+ Common::String text = "Talking to " + _case->getRolloverText(0);
+ _vm->getInterface()->displayTextLine(text);
+ } else if (_vm->getInterface()->getState() == kCSTimeInterfaceStateDragging) {
+ // TODO: check symbols before this
+ CSTimeInventoryObject *invObj = _vm->getCase()->_inventoryObjs[_vm->getInterface()->getDraggedNum()];
+ Common::String text = "Holding " + _case->getRolloverText(invObj->stringId);
+ _vm->getInterface()->displayTextLine(text);
+ } else {
+ _vm->getInterface()->clearTextLine();
+ }
+
+ _hoverHotspot = (uint)~0;
+}
+
+void CSTimeScene::mouseUp(Common::Point &pos) {
+ // TODO: if sailing puzzle is active, return
+
+ if (_currHotspot == (uint)~0) {
+ if (_vm->getInterface()->cursorGetShape() == 4)
+ _vm->getInterface()->cursorChangeShape(1);
+ return;
+ }
+
+ if (_vm->getInterface()->getState() == kCSTimeInterfaceStateDragStart)
+ _vm->getInterface()->setState(kCSTimeInterfaceStateNormal);
+
+ CSTimeHotspot &hotspot = _hotspots[_currHotspot];
+ if (hotspot.region.containsPoint(pos) && hotspot.state == 1) {
+ mouseUpOnHotspot(_currHotspot);
+ } else {
+ if (_vm->getInterface()->cursorGetShape() == 4 || _vm->getInterface()->cursorGetShape() == 14)
+ _vm->getInterface()->cursorChangeShape(1);
+ }
+}
+
+void CSTimeScene::idle() {
+ // TODO: if sailing puzzle is active, idle it instead
+
+ for (uint i = 0; i < _chars.size(); i++)
+ _chars[i]->idle();
+}
+
+void CSTimeScene::setupAmbientAnims() {
+ for (uint i = 0; i < _chars.size(); i++)
+ _chars[i]->setupAmbientAnims(false);
+}
+
+void CSTimeScene::idleAmbientAnims() {
+ if (_vm->NISIsRunning())
+ return;
+
+ for (uint i = 0; i < _chars.size(); i++)
+ _chars[i]->idleAmbients();
+}
+
+bool CSTimeScene::eventIsActive() {
+ return _vm->NISIsRunning() /* TODO || _vm->soundIsPlaying()*/ || _vm->getCurrentEventType() == kCSTimeEventWaitForClick
+ || _activeChar->_flappingState != 0xffff || _vm->getInterface()->getState() == 4;
+}
+
+void CSTimeScene::cursorOverHotspot(uint id) {
+ CSTimeHotspot &hotspot = _hotspots[id];
+
+ if (!_vm->getInterface()->cursorGetState())
+ return;
+
+ if (_vm->getInterface()->getState() == kCSTimeInterfaceStateDragging) {
+ uint16 stringId = 0xffff;
+
+ uint16 draggedId = _vm->getInterface()->getDraggedNum();
+ CSTimeInventoryObject *invObj = _vm->getCase()->_inventoryObjs[draggedId];
+ for (uint j = 0; j < invObj->hotspots.size(); j++) {
+ if (invObj->hotspots[j].sceneId != _id)
+ continue;
+ if (invObj->hotspots[j].hotspotId != id)
+ continue;
+ stringId = invObj->hotspots[j].stringId;
+ break;
+ }
+
+ if (hotspot.stringId != 0xFFFF) {
+ Common::String textLine;
+ if (false) {
+ // FIXME: special-case time cuffs
+ } else {
+ bool isChar = (hotspot.cursor == 1) && (draggedId != TIME_CUFFS_ID);
+ textLine = (isChar ? "Give " : "Use ");
+ textLine += _case->getRolloverText(invObj->stringId);
+ textLine += (isChar ? " to " : " on ");
+ textLine += _case->getRolloverText(stringId);
+ }
+ _vm->getInterface()->displayTextLine(textLine);
+ }
+ } else {
+ if (hotspot.stringId != 0xFFFF)
+ _vm->getInterface()->displayTextLine(_case->getRolloverText(hotspot.stringId));
+ }
+
+ if (_vm->getEventManager()->getButtonState() & 1) {
+ if (_vm->getInterface()->getState() != kCSTimeInterfaceStateDragStart && _vm->getInterface()->getState() != kCSTimeInterfaceStateDragging) {
+ CSTimeHotspot &currHotspot = _hotspots[_currHotspot];
+ if (currHotspot.cursor == 2)
+ _vm->getInterface()->cursorSetShape(14);
+ else
+ _vm->getInterface()->cursorSetShape(5);
+ }
+ } else {
+ if (hotspot.cursor == 2)
+ _vm->getInterface()->cursorSetShape(13);
+ else if (_vm->getInterface()->cursorGetShape() != 8 && _vm->getInterface()->cursorGetShape() != 11)
+ _vm->getInterface()->cursorSetShape(2);
+ }
+}
+
+void CSTimeScene::mouseDownOnHotspot(uint id) {
+ CSTimeHotspot &hotspot = _hotspots[id];
+
+ _currHotspot = id;
+
+ if (hotspot.invObjId == 0xffff || _vm->_haveInvItem[hotspot.invObjId]) {
+ if (hotspot.cursor == 2)
+ _vm->getInterface()->cursorChangeShape(14);
+ else
+ _vm->getInterface()->cursorChangeShape(5);
+ return;
+ }
+
+ _vm->getInterface()->cursorSetShape(8, true);
+ _vm->getInterface()->setGrabPoint();
+ _vm->getInterface()->setState(kCSTimeInterfaceStateDragStart);
+
+ CSTimeInventoryObject *invObj = _vm->getCase()->_inventoryObjs[hotspot.invObjId];
+ _vm->getInterface()->displayTextLine("Pick up " + _case->getRolloverText(invObj->stringId));
+}
+
+void CSTimeScene::mouseUpOnHotspot(uint id) {
+ CSTimeHotspot &hotspot = _hotspots[id];
+
+ _vm->addEventList(hotspot.events);
+ if (_vm->getInterface()->cursorGetShape() == 8 || (!hotspot.events.empty() && _vm->getInterface()->cursorGetShape() == 11))
+ return;
+ if (hotspot.cursor == 2)
+ _vm->getInterface()->cursorChangeShape(13);
+ else
+ _vm->getInterface()->cursorChangeShape(2);
+}
+
+bool CSTimeScene::hotspotContainsEvent(uint id, uint16 eventType) {
+ CSTimeHotspot &hotspot = _hotspots[id];
+
+ for (uint i = 0; i < hotspot.events.size(); i++)
+ if (hotspot.events[i].type == eventType)
+ return true;
+
+ return false;
+}
+
+void CSTimeScene::setCursorForCurrentPoint() {
+ Common::Point mousePos = _vm->getEventManager()->getMousePos();
+
+ for (uint i = 0; i < _hotspots.size(); i++) {
+ if (!_hotspots[i].region.containsPoint(mousePos))
+ continue;
+ if (_hotspots[i].state != 1)
+ continue;
+ if (_hotspots[i].cursor == 2) {
+ _vm->getInterface()->cursorSetShape(13);
+ } else switch (_vm->getInterface()->cursorGetShape()) {
+ case 8:
+ break;
+ case 12:
+ _vm->getInterface()->cursorSetShape(11);
+ break;
+ default:
+ _vm->getInterface()->cursorSetShape(2);
+ break;
+ }
+ return;
+ }
+
+ _vm->getInterface()->cursorSetShape(1);
+}
+
+void CSTimeScene::drawHotspots() {
+ for (uint i = 0; i < _hotspots.size(); i++) {
+ for (uint j = 0; j < _hotspots[i].region._rects.size(); j++) {
+ _vm->_gfx->drawRect(_hotspots[i].region._rects[j], 10 + 5*i);
+ }
+ }
+}
+
+const Common::Array<CSTimeEvent> &CSTimeScene::getEvents(bool second) {
+ if (second)
+ return _events2;
+ else
+ return _events;
+}
+
+} // End of namespace Mohawk
Property changes on: scummvm/trunk/engines/mohawk/cstime_game.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/mohawk/cstime_game.h
===================================================================
--- scummvm/trunk/engines/mohawk/cstime_game.h (rev 0)
+++ scummvm/trunk/engines/mohawk/cstime_game.h 2011-01-20 21:35:00 UTC (rev 55362)
@@ -0,0 +1,287 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef MOHAWK_CSTIME_GAME_H
+#define MOHAWK_CSTIME_GAME_H
+
+#include "mohawk/cstime.h"
+#include "mohawk/sound.h" // CueList
+
+namespace Mohawk {
+
+class Feature;
+class CSTimeCase;
+class CSTimeScene;
+
+class Region {
+public:
+ void loadFrom(Common::SeekableReadStream *stream);
+ bool containsPoint(Common::Point &pos) const;
+
+ Common::Array<Common::Rect> _rects;
+};
+
+struct CSTimeAmbient {
+ uint16 delay;
+ Feature *feature;
+ uint32 nextTime;
+};
+
+class CSTimeChar {
+public:
+ CSTimeChar(MohawkEngine_CSTime *vm, CSTimeScene *scene, uint id);
+ ~CSTimeChar();
+
+ void idle();
+ void setupAmbientAnims(bool onetime);
+ void idleAmbients();
+ void stopAmbients(bool restpos);
+ void setupRestPos();
+ void removeChr();
+ uint16 getChrBaseId();
+ uint getScriptCount();
+ void playNIS(uint16 id);
+ bool NISIsDone();
+ void removeNIS();
+ void startFlapping(uint16 id);
+ void interruptFlapping();
+
+ uint16 _unknown1, _unknown2, _unknown3;
+ Common::Array<CSTimeAmbient> _ambients;
+ bool _enabled;
+ uint16 _flappingState;
+
+protected:
+ MohawkEngine_CSTime *_vm;
+ CSTimeScene *_scene;
+ uint _id;
+
+ Feature *_NIS;
+ Feature *_restFeature;
+ Feature *_talkFeature;
+ Feature *_talkFeature1, *_talkFeature2, *_talkFeature3;
+
+ uint16 _playingWaveId;
+ CueList _cueList;
+ uint _nextCue;
+ uint32 _lastTime1, _lastTime2, _lastTime3;
+
+ bool _resting;
+ byte _waveStatus;
+ byte _surfingState;
+
+ void installAmbientAnim(uint id, uint32 flags);
+ uint16 getChrTypeScriptBase();
+ void playFlapWave(uint16 id);
+ void updateWaveStatus();
+ void setupTalk();
+ void idleTalk();
+ void stopFlapping();
+};
+
+struct CSTimeHotspot {
+ uint16 stringId;
+ uint16 state;
+ uint16 invObjId;
+ uint16 cursor;
+ Common::Array<CSTimeEvent> events;
+ Region region;
+};
+
+struct CSTimeLocation {
+ uint16 sceneId, hotspotId;
+};
+
+struct CSTimeInventoryHotspot {
+ uint16 sceneId, hotspotId, stringId;
+ Common::Array<CSTimeEvent> events;
+};
+
+#define TIME_CUFFS_ID 0
+struct CSTimeInventoryObject {
+ uint16 id, stringId, hotspotId, featureId, canTake;
+ Feature *feature;
+ Common::Array<CSTimeLocation> locations;
+ Common::Array<CSTimeInventoryHotspot> hotspots;
+ Common::Array<CSTimeEvent> events;
+};
+
+struct CSTimeQaR {
+ bool finished;
+ uint16 id;
+ uint16 unknown1;
+ uint16 questionStringId;
+ uint16 responseStringId;
+ uint16 unknown2;
+ uint16 nextQaRsId;
+ Common::Array<CSTimeEvent> events;
+};
+
+class CSTimeConversation {
+public:
+ CSTimeConversation(MohawkEngine_CSTime *vm, uint id);
+ ~CSTimeConversation();
+
+ void start();
+ void finishProcessingQaR();
+ void end(bool useLastClicked, bool runEvents = true);
+ void display();
+ void selectItemsToDisplay();
+
+ void mouseDown(Common::Point &pos);
+ void mouseMove(Common::Point &pos);
+ void mouseUp(Common::Point &pos);
+
+ void incrementTalkCount() { _talkCount++; }
+ uint16 getNameId() { return _nameId; }
+ uint16 getSourceChar() { return _sourceChar; }
+ void setSourceChar(uint16 source) { _sourceChar = source; }
+ void setAsked(uint qar, uint entry);
+ bool getAsked(uint qar, uint entry) { return _asked[qar][entry]; }
+
+ void setState(uint state) { _state = state; }
+ uint getState() { return _state; }
+
+protected:
+ MohawkEngine_CSTime *_vm;
+ uint _id;
+
+ uint _state;
+
+ uint16 _nameId;
+ uint16 _greeting, _greeting2;
+
+ uint _talkCount;
+ uint16 _sourceChar;
+
+ uint _currEntry, _currHover;
+ uint16 _nextToProcess;
+
+ bool _asked[8][5];
+ Common::Array<CSTimeQaR> _qars;
+ Common::Array<uint> _itemsToDisplay;
+
+ void clear();
+ void loadQaR(CSTimeQaR &qar, uint16 id);
+
+ void highlightLine(uint line);
+ void unhighlightLine(uint line);
+};
+
+class CSTimeScene {
+public:
+ CSTimeScene(MohawkEngine_CSTime *vm, CSTimeCase *case_, uint id);
+ ~CSTimeScene();
+
+ void installGroup();
+ void buildScene();
+ void leave();
+ uint16 getSceneId();
+ void mouseDown(Common::Point &pos);
+ void mouseMove(Common::Point &pos);
+ void mouseUp(Common::Point &pos);
+ void idle();
+ void setupAmbientAnims();
+ void idleAmbientAnims();
+ bool eventIsActive();
+
+ void setCursorForCurrentPoint();
+ void drawHotspots(); // debugging
+
+ uint16 getBubbleType() { return _bubbleType; }
+ const Common::Array<CSTimeEvent> &getEvents(bool second);
+ const Common::Array<CSTimeHotspot> &getHotspots() { return _hotspots; }
+ CSTimeHotspot &getHotspot(uint id) { return _hotspots[id]; }
+ uint16 getInvObjForCurrentHotspot() { return _hotspots[_currHotspot].invObjId; }
+ CSTimeChar *getChar(uint id) { return _chars[id]; }
+ uint16 getHelperId() { return _helperId; }
+ uint getId() { return _id; }
+
+ CSTimeChar *_activeChar;
+
+ Common::Array<Feature *> _objectFeatures;
+
+protected:
+ MohawkEngine_CSTime *_vm;
+ CSTimeCase *_case;
+ uint _id;
+
+ uint _currHotspot;
+ uint _hoverHotspot;
+
+ void load();
+ void cursorOverHotspot(uint id);
+ void mouseDownOnHotspot(uint id);
+ void mouseUpOnHotspot(uint id);
+ bool hotspotContainsEvent(uint id, uint16 eventType);
+
+ uint16 _unknown1, _unknown2, _helperId;
+ uint16 _bubbleType;
+ uint16 _numObjects;
+ Common::Array<CSTimeEvent> _events, _events2;
+ Common::Array<CSTimeChar *> _chars;
+ Common::Array<CSTimeHotspot> _hotspots;
+};
+
+class CSTimeCase {
+public:
+ CSTimeCase(MohawkEngine_CSTime *vm, uint id);
+ virtual ~CSTimeCase();
+
+ uint getId() { return _id; }
+ Common::String &getRolloverText(uint id) { return _rolloverText[id]; }
+ CSTimeScene *getCurrScene();
+ void setCurrScene(uint id) { _currScene = id; }
+ void setConversation(uint id) { _currConv = _conversations[id]; }
+ CSTimeConversation *getCurrConversation() { return _currConv; }
+ uint16 getNoteFeatureId(uint16 id) { return _noteFeatureId[id]; }
+
+ // Hard-coded per-case logic, implemented in subclasses.
+ virtual bool checkConvCondition(uint16 conditionId) = 0;
+ virtual bool checkAmbientCondition(uint16 charId, uint16 ambientId) = 0;
+ virtual bool checkObjectCondition(uint16 objectId) = 0;
+ virtual void selectHelpStrings() = 0;
+ virtual void handleConditionalEvent(const CSTimeEvent &event) = 0;
+
+ Common::Array<CSTimeInventoryObject *> _inventoryObjs;
+
+protected:
+ MohawkEngine_CSTime *_vm;
+ uint _id;
+
+ uint _currScene;
+ uint16 _noteFeatureId[3];
+ Common::Array<Common::String> _rolloverText;
+ Common::Array<CSTimeScene *> _scenes;
+ Common::Array<CSTimeConversation *> _conversations;
+ CSTimeConversation *_currConv;
+
+ void loadRolloverText();
+ CSTimeInventoryObject *loadInventoryObject(uint id);
+};
+
+} // End of namespace Mohawk
+
+#endif
Property changes on: scummvm/trunk/engines/mohawk/cstime_game.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/mohawk/cstime_ui.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/cstime_ui.cpp (rev 0)
+++ scummvm/trunk/engines/mohawk/cstime_ui.cpp 2011-01-20 21:35:00 UTC (rev 55362)
@@ -0,0 +1,1186 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "mohawk/cstime_game.h"
+#include "mohawk/cstime_ui.h"
+#include "mohawk/cstime_view.h"
+#include "mohawk/resource.h"
+#include "common/events.h"
+
+namespace Mohawk {
+
+// read a null-terminated string from a stream
+static Common::String readString(Common::SeekableReadStream *stream) {
+ Common::String ret;
+ while (!stream->eos()) {
+ byte in = stream->readByte();
+ if (!in)
+ break;
+ ret += in;
+ }
+ return ret;
+}
+
+CSTimeInterface::CSTimeInterface(MohawkEngine_CSTime *vm) : _vm(vm) {
+ _sceneRect = Common::Rect(0, 0, 640, 340);
+ _uiRect = Common::Rect(0, 340, 640, 480);
+
+ _bookRect = Common::Rect(_uiRect.right - 95, _uiRect.top + 32, _uiRect.right - 25, _uiRect.top + 122);
+ _noteRect = Common::Rect(_uiRect.left + 27, _uiRect.top + 31, _uiRect.left + 103, _uiRect.top + 131);
+ _dialogTextRect = Common::Rect(0 + 125, 340 + 40, 640 - 125, 480 - 20);
+
+ _cursorActive = false;
+ _cursorShapes[0] = 0xFFFF;
+ _cursorShapes[1] = 0xFFFF;
+ _cursorShapes[2] = 0xFFFF;
+ _cursorNextTime = 0;
+
+ _help = new CSTimeHelp(_vm);
+ _inventoryDisplay = new CSTimeInventoryDisplay(_vm, _dialogTextRect);
+ _book = new CSTimeBook(_vm);
+ _note = new CSTimeCarmenNote(_vm);
+ _options = new CSTimeOptions(_vm);
+
+ if (!_normalFont.loadFromFON("95instal/EvP14.fon"))
+ error("failed to load normal font");
+ if (!_dialogFont.loadFromFON("95instal/Int1212.fon"))
+ error("failed to load dialog font");
+ if (!_rolloverFont.loadFromFON("95instal/Int1818.fon"))
+ error("failed to load rollover font");
+
+ _uiFeature = NULL;
+ _dialogTextFeature = NULL;
+ _rolloverTextFeature = NULL;
+ _bubbleTextFeature = NULL;
+
+ _mouseWasInScene = false;
+ _state = kCSTimeInterfaceStateNormal;
+
+ _dialogLines.resize(5);
+ _dialogLineColors.resize(5);
+}
+
+CSTimeInterface::~CSTimeInterface() {
+ delete _help;
+ delete _inventoryDisplay;
+ delete _book;
+ delete _note;
+ delete _options;
+}
+
+void CSTimeInterface::cursorInstall() {
+ _vm->getView()->loadBitmapCursors(200);
+}
+
+void CSTimeInterface::cursorIdle() {
+ if (!_cursorActive || _cursorShapes[1] == 0xFFFF)
+ return;
+
+ if (_vm->_system->getMillis() <= _cursorNextTime + 250)
+ return;
+
+ cursorSetShape(_cursorShapes[1], false);
+ _cursorShapes[1] = _cursorShapes[2];
+ _cursorShapes[2] = 0xFFFF;
+}
+
+void CSTimeInterface::cursorActivate(bool state) {
+ _cursorActive = state;
+}
+
+void CSTimeInterface::cursorChangeShape(uint16 id) {
+ if (_cursorShapes[1] == 0xFFFF)
+ _cursorShapes[1] = id;
+ else
+ _cursorShapes[2] = id;
+}
+
+uint16 CSTimeInterface::cursorGetShape() {
+ if (_cursorShapes[2] != 0xFFFF)
+ return _cursorShapes[2];
+ else if (_cursorShapes[1] != 0xFFFF)
+ return _cursorShapes[1];
+ else
+ return _cursorShapes[0];
+}
+
+void CSTimeInterface::cursorSetShape(uint16 id, bool reset) {
+ if (_cursorShapes[0] != id) {
+ _cursorShapes[0] = id;
+ _vm->getView()->setBitmapCursor(id);
+ _cursorNextTime = _vm->_system->getMillis();
+ }
+}
+
+void CSTimeInterface::cursorSetWaitCursor() {
+ uint16 shape = cursorGetShape();
+ switch (shape) {
+ case 8:
+ cursorChangeShape(9);
+ break;
+ case 9:
+ break;
+ case 11:
+ cursorChangeShape(12);
+ break;
+ case 13:
+ cursorChangeShape(15);
+ break;
+ default:
+ cursorChangeShape(3);
+ break;
+ }
+}
+
+void CSTimeInterface::openResFile() {
+ _vm->loadResourceFile("data/iface");
+}
+
+void CSTimeInterface::install() {
+ uint16 resourceId = 100; // TODO
+ _vm->getView()->installGroup(resourceId, 16, 0, true, 100);
+
+ // TODO: store/reset these
+
+ _dialogTextFeature = _vm->getView()->installViewFeature(0, 0, NULL);
+ _dialogTextFeature->_data.bounds = _dialogTextRect;
+ _dialogTextFeature->_data.bitmapIds[0] = 0;
+ // We don't set a port.
+ _dialogTextFeature->_moveProc = (Module::FeatureProc)&CSTimeModule::dialogTextMoveProc;
+ _dialogTextFeature->_drawProc = (Module::FeatureProc)&CSTimeModule::dialogTextDrawProc;
+ _dialogTextFeature->_timeProc = NULL;
+ _dialogTextFeature->_flags = kFeatureOldSortForeground; // FIXME: not in original
+
+ _rolloverTextFeature = _vm->getView()->installViewFeature(0, 0, NULL);
+ _rolloverTextFeature->_data.bounds = Common::Rect(0 + 100, 340 + 5, 640 - 100, 480 - 25);
+ _rolloverTextFeature->_data.bitmapIds[0] = 0;
+ _rolloverTextFeature->_moveProc = (Module::FeatureProc)&CSTimeModule::rolloverTextMoveProc;
+ _rolloverTextFeature->_drawProc = (Module::FeatureProc)&CSTimeModule::rolloverTextDrawProc;
+ _rolloverTextFeature->_timeProc = NULL;
+ _rolloverTextFeature->_flags = kFeatureOldSortForeground; // FIXME: not in original
+}
+
+void CSTimeInterface::draw() {
+ // TODO
+ if (!_uiFeature) {
+ uint32 flags = kFeatureSortStatic | kFeatureNewNoLoop;
+ assert(flags == 0x4800000);
+ uint16 resourceId = 100; // TODO
+ _uiFeature = _vm->getView()->installViewFeature(resourceId, flags, NULL);
+ // TODO: special-case for case 20
+ } else {
+ _uiFeature->resetFeatureScript(1, 0);
+ // TODO: special-case for case 20
+ }
+
+ // TODO: special-case for cases 19 and 20
+
+ _note->drawSmallNote();
+ _book->drawSmallBook();
+ _inventoryDisplay->draw();
+}
+
+void CSTimeInterface::idle() {
+ // TODO: inv sound handling
+
+ _vm->getCase()->getCurrScene()->idle();
+ _inventoryDisplay->idle();
+ cursorIdle();
+
+ _vm->getView()->idleView();
+}
+
+void CSTimeInterface::mouseDown(Common::Point pos) {
+ _vm->resetTimeout();
+
+ if (_options->getState()) {
+ // TODO: _options->mouseDown(pos);
+ return;
+ }
+
+ if (!cursorGetState())
+ return;
+ if (_vm->getCase()->getCurrScene()->eventIsActive())
+ return;
+
+ switch (cursorGetShape()) {
+ case 1:
+ cursorChangeShape(4);
+ break;
+ case 2:
+ cursorChangeShape(5);
+ break;
+ case 13:
+ cursorChangeShape(14);
+ break;
+ }
+
+ if (_book->getState() == 2) {
+ // TODO: _book->mouseDown(pos);
+ return;
+ }
+
+ // TODO: if in sailing puzzle, sailing puzzle mouse down, return
+
+ if (_note->getState() > 0) {
+ return;
+ }
+
+ if (_sceneRect.contains(pos)) {
+ _vm->getCase()->getCurrScene()->mouseDown(pos);
+ return;
+ }
+
+ // TODO: case 20 ui craziness is handled seperately..
+
+ CSTimeConversation *conv = _vm->getCase()->getCurrConversation();
+ if (_bookRect.contains(pos) || (_noteRect.contains(pos) && _note->havePiece(0xffff))) {
+ if (conv->getState() != (uint)~0)
+ conv->end(false);
+ if (_help->getState() != (uint)~0)
+ _help->end();
+ return;
+ }
+
+ if (_help->getState() != (uint)~0) {
+ // FIXME: _help->mouseDown(pos);
+ return;
+ }
+
+ if (conv->getState() != (uint)~0) {
+ conv->mouseDown(pos);
+ return;
+ }
+
+ // TODO: handle symbols
+
+ if (_inventoryDisplay->_invRect.contains(pos)) {
+ // TODO: special handling for case 6
+
+ _inventoryDisplay->mouseDown(pos);
+ }
+}
+
+void CSTimeInterface::mouseMove(Common::Point pos) {
+ if (_options->getState()) {
+ // TODO: _options->mouseMove(pos);
+ return;
+ }
+
+ if (!cursorGetState())
+ return;
+
+ if (_mouseWasInScene && _uiRect.contains(pos)) {
+ clearTextLine();
+ _mouseWasInScene = false;
+ }
+
+ if (_book->getState() == 2) {
+ // TODO: _book->mouseMove(pos);
+ return;
+ }
+
+ if (_note->getState() == 2)
+ return;
+
+ // TODO: case 20 ui craziness is handled seperately..
+
+ if (_sceneRect.contains(pos) && !_vm->getCase()->getCurrScene()->eventIsActive()) {
+ _vm->getCase()->getCurrScene()->mouseMove(pos);
+ _mouseWasInScene = true;
+ return;
+ }
+
+ if (cursorGetShape() == 13) {
+ cursorSetShape(1);
+ return;
+ } else if (cursorGetShape() == 14) {
+ cursorSetShape(4);
+ return;
+ }
+
+ bool mouseIsDown = _vm->getEventManager()->getButtonState() & 1;
+
+ if (_book->getState() == 1 && !_bookRect.contains(pos)) {
+ if (_state != kCSTimeInterfaceStateDragging) {
+ clearTextLine();
+ cursorSetShape(mouseIsDown ? 4 : 1);
+ _book->setState(0);
+ }
+ return;
+ }
+
+ // TODO: case 20 ui craziness again
+
+ if (_note->getState() == 1 && !_noteRect.contains(pos)) {
+ if (_state != kCSTimeInterfaceStateDragging) {
+ clearTextLine();
+ cursorSetShape(mouseIsDown ? 4 : 1);
+ _note->setState(0);
+ }
+ return;
+ }
+
+ // TODO: handle symbols
+
+ if (_bookRect.contains(pos)) {
+ if (_state != kCSTimeInterfaceStateDragging) {
+ displayTextLine("Open Chronopedia");
+ cursorSetShape(mouseIsDown ? 5 : 2);
+ _book->setState(1);
+ }
+ return;
+ }
+
+ if (_noteRect.contains(pos)) {
+ if (_state != kCSTimeInterfaceStateDragging && _note->havePiece(0xffff) && !_note->getState()) {
+ displayTextLine("Look at Note");
+ cursorSetShape(mouseIsDown ? 5 : 2);
+ _note->setState(1);
+ }
+ return;
+ }
+
+ if (_vm->getCase()->getCurrConversation()->getState() != (uint)~0) {
+ _vm->getCase()->getCurrConversation()->mouseMove(pos);
+ return;
+ }
+
+ if (_help->getState() != (uint)~0) {
+ // FIXME: _help->mouseMove(pos);
+ return;
+ }
+
+ if (_state == kCSTimeInterfaceStateDragging) {
+ // FIXME: dragging
+ return;
+ }
+
+ // FIXME: if case is 20, we're done, return
+
+ if (_inventoryDisplay->_invRect.contains(pos)) {
+ _inventoryDisplay->mouseMove(pos);
+ }
+}
+
+void CSTimeInterface::mouseUp(Common::Point pos) {
+ if (_options->getState()) {
+ // TODO: options->mouseUp(pos);
+ return;
+ }
+
+ if (!cursorGetState())
+ return;
+
+ if (_state == kCSTimeInterfaceStateDragging) {
+ stopDragging();
+ return;
+ }
+
+ if (_state == kCSTimeInterfaceStateDragStart)
+ _state = kCSTimeInterfaceStateNormal;
+
+ switch (cursorGetShape()) {
+ case 4:
+ cursorChangeShape(1);
+ break;
+ case 5:
+ cursorChangeShape(2);
+ break;
+ case 14:
+ cursorChangeShape(13);
+ break;
+ }
+
+ if (_vm->getCase()->getCurrScene()->eventIsActive()) {
+ if (_vm->getCurrentEventType() == kCSTimeEventWaitForClick)
+ _vm->mouseClicked();
+ return;
+ }
+
+ if (_book->getState() == 2) {
+ // TODO: _book->mouseUp(pos);
+ return;
+ }
+
+ if (_note->getState() == 2) {
+ // TODO: _note->closeNote();
+ mouseMove(pos);
+ return;
+ }
+
+ // TODO: if in sailing puzzle, sailing puzzle mouse up, return
+
+ // TODO: case 20 ui craziness is handled seperately..
+
+ if (_sceneRect.contains(pos)) {
+ _vm->getCase()->getCurrScene()->mouseUp(pos);
+ return;
+ }
+
+ if (_vm->getCase()->getCurrConversation()->getState() != (uint)~0) {
+ _vm->getCase()->getCurrConversation()->mouseUp(pos);
+ return;
+ }
+
+ if (_help->getState() != (uint)~0) {
+ // FIXME: _help->mouseUp(pos);
+ return;
+ }
+
+ // TODO: handle symbols
+
+ if (_bookRect.contains(pos)) {
+ // TODO: handle flashing cuffs
+ // TODO: _book->open();
+ return;
+ }
+
+ if (_noteRect.contains(pos)) {
+ // TODO: special-casing for case 19
+ if (_note->havePiece(0xffff))
+ _note->drawBigNote();
+ }
+
+ if (_inventoryDisplay->_invRect.contains(pos)) {
+ // TODO: special-casing for case 6
+ _inventoryDisplay->mouseUp(pos);
+ }
+}
+
+void CSTimeInterface::cursorOverHotspot() {
+ if (cursorGetState() != 1)
+ return;
+ if (_state == kCSTimeInterfaceStateDragStart || _state == kCSTimeInterfaceStateDragging)
+ return;
+ if (cursorGetShape() == 3 || cursorGetShape() == 9)
+ return;
+
+ bool mouseIsDown = _vm->getEventManager()->getButtonState() & 1;
+ if (mouseIsDown)
+ cursorSetShape(5);
+ else if (cursorGetShape() == 1)
+ cursorChangeShape(2);
+}
+
+void CSTimeInterface::setCursorForCurrentPoint() {
+ uint16 shape = 1;
+
+ Common::Point mousePos = _vm->getEventManager()->getMousePos();
+ if (_bookRect.contains(mousePos)) {
+ shape = 2;
+ } else {
+ uint convState = _vm->getCase()->getCurrConversation()->getState();
+ uint helpState = _help->getState();
+ // TODO: symbols too
+ if (convState == (uint)~0 || convState == 0 || helpState == (uint)~0 || helpState == 0) {
+ // FIXME: set cursor to 2 if inventory display occupied
+ } else if (convState == 1 || helpState == 1) {
+ // FIXME: set cursor to 2 if over conversation rect
+ }
+ }
+
+ cursorSetShape(shape);
+}
+
+void CSTimeInterface::clearTextLine() {
+ _rolloverText.clear();
+}
+
+void CSTimeInterface::displayTextLine(Common::String text) {
+ _rolloverText = text;
+}
+
+void CSTimeInterface::clearDialogArea() {
+ _dialogLines.clear();
+ _dialogLines.resize(5);
+ // TODO: dirty feature
+}
+
+void CSTimeInterface::clearDialogLine(uint line) {
+ _dialogLines[line].clear();
+ // TODO: dirty feature
+}
+
+void CSTimeInterface::displayDialogLine(uint16 id, uint line, byte color) {
+ Common::SeekableReadStream *stream = _vm->getResource(ID_STRI, id);
+ Common::String text = readString(stream);
+ delete stream;
+
+ _dialogLines[line] = text;
+ _dialogLineColors[line] = color;
+ // TODO: dirty feature
+}
+
+void CSTimeInterface::drawTextIdToBubble(uint16 id) {
+ Common::SeekableReadStream *stream = _vm->getResource(ID_STRI, id);
+ Common::String text = readString(stream);
+ delete stream;
+
+ drawTextToBubble(&text);
+}
+
+void CSTimeInterface::drawTextToBubble(Common::String *text) {
+ if (_bubbleTextFeature)
+ error("Attempt to display two text objects");
+ if (!text)
+ text = &_bubbleText;
+ if (text->empty())
+ return;
+
+ _currentBubbleText = *text;
+
+ uint bubbleId = _vm->getCase()->getCurrScene()->getBubbleType();
+ Common::Rect bounds;
+ switch (bubbleId) {
+ case 0:
+ bounds = Common::Rect(15, 7, 625, 80);
+ break;
+ case 1:
+ bounds = Common::Rect(160, 260, 625, 333);
+ break;
+ case 2:
+ bounds = Common::Rect(356, 3, 639, 90);
+ break;
+ case 3:
+ bounds = Common::Rect(10, 7, 380, 80);
+ break;
+ case 4:
+ bounds = Common::Rect(15, 270, 625, 328);
+ break;
+ case 5:
+ bounds = Common::Rect(15, 7, 550, 70);
+ break;
+ case 6:
+ bounds = Common::Rect(0, 0, 313, 76);
+ break;
+ case 7:
+ bounds = Common::Rect(200, 25, 502, 470);
+ break;
+ default:
+ error("unknown bubble type %d in drawTextToBubble", bubbleId);
+ }
+
+ _bubbleTextFeature = _vm->getView()->installViewFeature(0, 0, NULL);
+ _bubbleTextFeature->_data.bounds = bounds;
+ _bubbleTextFeature->_data.bitmapIds[0] = 0;
+ _bubbleTextFeature->_moveProc = (Module::FeatureProc)&CSTimeModule::bubbleTextMoveProc;
+ _bubbleTextFeature->_drawProc = (Module::FeatureProc)&CSTimeModule::bubbleTextDrawProc;
+ _bubbleTextFeature->_timeProc = NULL;
+ _bubbleTextFeature->_flags = kFeatureOldSortForeground; // FIXME: not in original
+}
+
+void CSTimeInterface::closeBubble() {
+ if (_bubbleTextFeature)
+ _vm->getView()->removeFeature(_bubbleTextFeature, true);
+ _bubbleTextFeature = NULL;
+}
+
+void CSTimeInterface::startDragging(uint16 id) {
+ CSTimeInventoryObject *invObj = _vm->getCase()->_inventoryObjs[id];
+
+ cursorSetShape(11);
+ _draggedItem = id;
+
+ if (_draggedItem == TIME_CUFFS_ID) {
+ if (_inventoryDisplay->getCuffsShape() == 11) {
+ _inventoryDisplay->setCuffsFlashing();
+ _vm->getView()->idleView();
+ }
+ }
+
+ uint32 dragFlags = (grabbedFromInventory() ? 0x800 : 0x600);
+ _vm->getView()->dragFeature((NewFeature *)invObj->feature, _grabPoint, 4, dragFlags, NULL);
+
+ if (_vm->getCase()->getId() == 1 && id == 2) {
+ // Hardcoded behaviour for the torch in the first case.
+ if (_vm->getCase()->getCurrScene()->getId() == 4) {
+ // This is the dark tomb.
+ // FIXME: apply torch hack
+ _vm->_caseVariable[2]++;
+ } else {
+ // FIXME: unapply torch hack
+ }
+ }
+
+ _state = kCSTimeInterfaceStateDragging;
+
+ if (grabbedFromInventory())
+ return;
+
+ // Hide the associated scene feature, if there is one.
+ if (invObj->featureId != 0xffff) {
+ CSTimeEvent event;
+ event.type = kCSTimeEventDisableFeature;
+ event.param2 = invObj->featureId;
+ _vm->addEvent(event);
+ }
+
+ _vm->addEventList(invObj->events);
+}
+
+void CSTimeInterface::stopDragging() {
+ CSTimeScene *scene = _vm->getCase()->getCurrScene();
+ CSTimeInventoryObject *invObj = _vm->getCase()->_inventoryObjs[_draggedItem];
+
+ Common::Point mousePos = _vm->_system->getEventManager()->getMousePos();
+ _state = kCSTimeInterfaceStateNormal;
+
+ if (_sceneRect.contains(mousePos))
+ scene->setCursorForCurrentPoint();
+ else
+ setCursorForCurrentPoint();
+
+ // Find the inventory object hotspot which is topmost for this drop, if any.
+ uint foundInvObjHotspot = ~0;
+ const Common::Array<CSTimeHotspot> &hotspots = scene->getHotspots();
+ for (uint i = 0; i < hotspots.size(); i++) {
+ if (hotspots[i].state != 1)
+ continue;
+ if (!hotspots[i].region.containsPoint(mousePos))
+ continue;
+ for (uint j = 0; j < invObj->hotspots.size(); j++) {
+ if (invObj->hotspots[j].sceneId != scene->getId())
+ continue;
+ if (invObj->hotspots[j].hotspotId != i)
+ continue;
+ if (foundInvObjHotspot != (uint)~0 && invObj->hotspots[foundInvObjHotspot].hotspotId < invObj->hotspots[j].hotspotId)
+ continue;
+ foundInvObjHotspot = j;
+ }
+ }
+
+ // Work out if we're going to consume (nom-nom) the object after the drop.
+ bool consumeObj = false;
+ bool runConsumeEvents = false;
+ if (foundInvObjHotspot != (uint)~0) {
+ CSTimeInventoryHotspot &hotspot = invObj->hotspots[foundInvObjHotspot];
+
+ clearTextLine();
+ for (uint i = 0; i < invObj->locations.size(); i++) {
+ if (invObj->locations[i].sceneId != hotspot.sceneId)
+ continue;
+ if (invObj->locations[i].hotspotId != hotspot.hotspotId)
+ continue;
+ consumeObj = true;
+ break;
+ }
+
+ if (_draggedItem == TIME_CUFFS_ID && !_inventoryDisplay->getCuffsState()) {
+ consumeObj = false;
+ // Nuh-uh, they're not activated yet.
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, _vm->getCase()->getCurrScene()->getHelperId(), 9902));
+ } else {
+ // FIXME: ding();
+ runConsumeEvents = true;
+ }
+ }
+
+ // Deal with the actual drop.
+ if (grabbedFromInventory()) {
+ if (!consumeObj) {
+ _vm->getView()->dragFeature((NewFeature *)invObj->feature, mousePos, 2, 0x800, NULL);
+ // TODO: playSound(151);
+ } else if (_draggedItem != TIME_CUFFS_ID) {
+ _vm->getView()->dragFeature((NewFeature *)invObj->feature, mousePos, 2, 0x800, NULL);
+ _vm->_haveInvItem[_draggedItem] = 0;
+ // FIXME: the original sets the feature to -2 here, see comment below
+ invObj->feature = NULL;
+ _inventoryDisplay->removeItem(_draggedItem);
+ } else if (!_inventoryDisplay->getCuffsState()) {
+ // Inactive cuffs.
+ _vm->getView()->dragFeature((NewFeature *)invObj->feature, mousePos, 2, 0x800, NULL);
+ invObj->feature = NULL;
+ } else {
+ // Active cuffs.
+ _vm->getView()->dragFeature((NewFeature *)invObj->feature, mousePos, 2, 0x600, NULL);
+ _vm->_haveInvItem[_draggedItem] = 0;
+ // FIXME: the original sets the feature to -2 here, see comment below
+ invObj->feature = NULL;
+ }
+
+ if (runConsumeEvents) {
+ _vm->addEventList(invObj->hotspots[foundInvObjHotspot].events);
+ }
+
+ _inventoryDisplay->draw();
+ } else {
+ uint32 dragFlags = 0x600;
+ _vm->getView()->dragFeature((NewFeature *)invObj->feature, mousePos, 2, dragFlags, NULL);
+
+ if (_inventoryDisplay->_invRect.contains(mousePos)) {
+ // Dropped into the inventory.
+ invObj->feature = NULL;
+ if (invObj->canTake) {
+ dropItemInInventory(_draggedItem);
+ if (invObj->hotspotId)
+ _vm->addEvent(CSTimeEvent(kCSTimeEventDisableHotspot, 0xffff, invObj->hotspotId));
+ } else {
+ if (invObj->featureId)
+ _vm->addEvent(CSTimeEvent(kCSTimeEventAddFeature, 0xffff, invObj->featureId));
+ }
+
+ for (uint i = 0; i < invObj->hotspots.size(); i++) {
+ if (invObj->hotspots[i].sceneId != scene->getId())
+ continue;
+ if (invObj->hotspots[i].hotspotId != 0xffff)
+ continue;
+ _vm->addEventList(invObj->hotspots[i].events);
+ }
+ } else {
+ // Dropped into the scene.
+
+ CSTimeEvent event;
+ event.param1 = 0xffff;
+ if (consumeObj) {
+ // FIXME: the original sets the feature to -2 here, which is used in the inventory display drawing
+ // so it knows not to draw the object. we should replace that with a flag.
+ invObj->feature = NULL;
+ event.type = kCSTimeEventDisableHotspot;
+ event.param2 = invObj->hotspotId;
+ } else {
+ invObj->feature = NULL;
+ event.type = kCSTimeEventAddFeature;
+ event.param2 = invObj->featureId;
+ }
+ _vm->addEvent(event);
+
+ if (runConsumeEvents) {
+ _vm->addEventList(invObj->hotspots[foundInvObjHotspot].events);
+ } else {
+ for (uint i = 0; i < invObj->hotspots.size(); i++) {
+ if (invObj->hotspots[i].sceneId != scene->getId())
+ continue;
+ if (invObj->hotspots[i].hotspotId != 0xfffe)
+ continue;
+ _vm->addEventList(invObj->hotspots[i].events);
+ }
+ }
+ }
+ }
+
+ if (_vm->getCase()->getId() == 1 && _vm->getCase()->getCurrScene()->getId() == 4) {
+ // Hardcoded behaviour for torches in the dark tomb, in the first case.
+ if (_draggedItem == 1 && foundInvObjHotspot == (uint)~0) {
+ // Trying to drag an unlit torch around?
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, 0, 16352));
+ } else if (_draggedItem == 2 && _vm->_caseVariable[2] == 1) {
+ // This the first time we tried dragging the lit torch around.
+ _vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, 0, 16354));
+ }
+ }
+
+ // TODO: Is this necessary?
+ _draggedItem = 0xffff;
+}
+
+void CSTimeInterface::setGrabPoint() {
+ _grabPoint = _vm->_system->getEventManager()->getMousePos();
+}
+
+bool CSTimeInterface::grabbedFromInventory() {
+ return (_inventoryDisplay->_invRect.contains(_grabPoint));
+}
+
+void CSTimeInterface::dropItemInInventory(uint16 id) {
+ if (_vm->_haveInvItem[id])
+ return;
+
+ _vm->_haveInvItem[id] = 1;
+ _vm->getCase()->_inventoryObjs[id]->feature = NULL;
+
+ _inventoryDisplay->insertItemInDisplay(id);
+
+ // TODO: deal with symbols
+
+ if (_vm->getCase()->getCurrConversation()->getState() == (uint)~0 || _vm->getCase()->getCurrConversation()->getState() == 0) {
+ // FIXME: additional check here
+ // FIXME: play sound 151?
+ _inventoryDisplay->draw();
+ return;
+ }
+
+ // FIXME: ding();
+ clearDialogArea();
+ _inventoryDisplay->show();
+ _inventoryDisplay->draw();
+ _inventoryDisplay->setState(4);
+}
+
+CSTimeHelp::CSTimeHelp(MohawkEngine_CSTime *vm) : _vm(vm) {
+ _state = ~0;
+}
+
+CSTimeHelp::~CSTimeHelp() {
+}
+
+void CSTimeHelp::end(bool runEvents) {
+ // FIXME
+}
+
+CSTimeInventoryDisplay::CSTimeInventoryDisplay(MohawkEngine_CSTime *vm, Common::Rect baseRect) : _vm(vm) {
+ _state = 0;
+ _cuffsState = false;
+ _cuffsShape = 10;
+
+ _invRect = baseRect;
+
+ for (uint i = 0; i < MAX_DISPLAYED_ITEMS; i++) {
+ _itemRect[i].left = baseRect.left + 15 + i * 92;
+ _itemRect[i].top = baseRect.top + 5;
+ _itemRect[i].right = _itemRect[i].left + 90;
+ _itemRect[i].bottom = _itemRect[i].top + 70;
+ }
+}
+
+CSTimeInventoryDisplay::~CSTimeInventoryDisplay() {
+}
+
+void CSTimeInventoryDisplay::install() {
+ uint count = _vm->getCase()->_inventoryObjs.size() - 1;
+
+ // FIXME: some cases have hard-coded counts
+
+ _vm->getView()->installGroup(9000, count, 0, true, 9000);
+}
+
+void CSTimeInventoryDisplay::draw() {
+ for (uint i = 0; i < MAX_DISPLAYED_ITEMS; i++) {
+ if (_displayedItems[i] == (uint)~0)
+ continue;
+ CSTimeInventoryObject *invObj = _vm->getCase()->_inventoryObjs[_displayedItems[i]];
+
+ // FIXME: ignore on -2 feature (see CSTimeInterface::stopDragging)
+
+ if (invObj->feature) {
+ invObj->feature->resetFeatureScript(1, 0);
+ continue;
+ }
+
+ // TODO: 0x2000 is set! help?
+ uint32 flags = kFeatureSortStatic | kFeatureNewNoLoop | 0x2000;
+ if (i == TIME_CUFFS_ID) {
+ // Time Cuffs are handled differently.
+ // TODO: Can we not use _cuffsShape here?
+ uint16 id = 100 + 10;
+ if (_cuffsState) {
+ id = 100 + 12;
+ flags &= ~kFeatureNewNoLoop;
+ }
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list