aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorjohndoe1232011-07-14 19:03:09 +0000
committerWillem Jan Palenstijn2013-05-08 20:38:48 +0200
commit0bfb52df74ac47a4842c66d40fd0ae5efc5d6af6 (patch)
treef622a0837b322356bbcdbe84a4c282b1d5b2addb /engines
parentdb9e45706caa2a4d2eddcb0c63532b3f6429a73e (diff)
downloadscummvm-rg350-0bfb52df74ac47a4842c66d40fd0ae5efc5d6af6.tar.gz
scummvm-rg350-0bfb52df74ac47a4842c66d40fd0ae5efc5d6af6.tar.bz2
scummvm-rg350-0bfb52df74ac47a4842c66d40fd0ae5efc5d6af6.zip
NEVERHOOD: Implement NavigationScene
- Work on the SmackerDecoder, create the surface immediately when a file is opened
Diffstat (limited to 'engines')
-rw-r--r--engines/neverhood/module.mk1
-rw-r--r--engines/neverhood/module1000.cpp2
-rw-r--r--engines/neverhood/navigationscene.cpp212
-rw-r--r--engines/neverhood/navigationscene.h56
-rw-r--r--engines/neverhood/neverhood.cpp7
-rw-r--r--engines/neverhood/neverhood.h2
-rw-r--r--engines/neverhood/smackerplayer.cpp35
-rw-r--r--engines/neverhood/smackerplayer.h5
-rw-r--r--engines/neverhood/smackerscene.cpp1
9 files changed, 307 insertions, 14 deletions
diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk
index e39041e24d..af03c075cc 100644
--- a/engines/neverhood/module.mk
+++ b/engines/neverhood/module.mk
@@ -13,6 +13,7 @@ MODULE_OBJS = \
module1000.o \
module1500.o \
mouse.o \
+ navigationscene.o \
neverhood.o \
palette.o \
resource.o \
diff --git a/engines/neverhood/module1000.cpp b/engines/neverhood/module1000.cpp
index bb15998063..bc898621af 100644
--- a/engines/neverhood/module1000.cpp
+++ b/engines/neverhood/module1000.cpp
@@ -21,6 +21,7 @@
*/
#include "neverhood/module1000.h"
+#include "neverhood/navigationscene.h"//###
namespace Neverhood {
@@ -77,6 +78,7 @@ void Module1000::createScene1001(int which) {
void Module1000::createScene1002(int which) {
_vm->gameState().sceneNum = 1;
_childObject = new Scene1002(_vm, this, which);
+ // DEBUG _childObject = new NavigationScene(_vm, this, 0x004B67B8, 0, NULL);
// TODO ResourceTable_multiLoad(&_resourceTable3, &_resourceTable4, &_resourceTable1);
// TODO Music18hList_play(0x061880C6, 0, 0, 1);
SetUpdateHandler(&Module1000::updateScene1002);
diff --git a/engines/neverhood/navigationscene.cpp b/engines/neverhood/navigationscene.cpp
new file mode 100644
index 0000000000..81af71fe17
--- /dev/null
+++ b/engines/neverhood/navigationscene.cpp
@@ -0,0 +1,212 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/navigationscene.h"
+#include "neverhood/mouse.h"
+
+namespace Neverhood {
+
+NavigationScene::NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint32 navigationListId, int navigationIndex, byte *itemsTypes)
+ : Scene(vm, parentModule, true), _itemsTypes(itemsTypes), _navigationIndex(navigationIndex), _smackerDone(false),
+ _soundFlag1(false), _soundFlag2(false), _smackerFileHash(0), _interactive(true), _done(false) {
+
+ _navigationList = _vm->_staticData->getNavigationList(navigationListId);
+ for (NavigationList::iterator it = _navigationList->begin(); it != _navigationList->end(); it++) {
+ debug("%08X %08X %08X %08X %d %d %08X", (*it).fileHash, (*it).leftSmackerFileHash, (*it).rightSmackerFileHash,
+ (*it).middleSmackerFileHash, (*it).interactive, (*it).middleFlag, (*it).mouseCursorFileHash);
+ }
+
+ if (_navigationIndex < 0) {
+ _navigationIndex = (int)getGlobalVar(0x4200189E);
+ if (_navigationIndex >= (int)_navigationList->size())
+ _navigationIndex = 0;
+ }
+ setGlobalVar(0x4200189E, _navigationIndex);
+
+ SetUpdateHandler(&NavigationScene::update);
+ SetMessageHandler(&NavigationScene::handleMessage);
+
+ _smackerPlayer = new SmackerPlayer(_vm, this, (*_navigationList)[_navigationIndex].fileHash, true, true);
+
+ addEntity(_smackerPlayer);
+
+ addSurface(_smackerPlayer->getSurface());
+
+ createMouseCursor();
+
+ _vm->_screen->clear();
+
+ _parentModule->sendMessage(0x100A, _navigationIndex, this);
+
+}
+
+NavigationScene::~NavigationScene() {
+ // TODO Sound1ChList_sub_4080B0(0);
+ // TODO Sound1ChList_sub_408110(0);
+}
+
+byte NavigationScene::getNavigationAreaType() {
+ return 0; // TODO
+}
+
+void NavigationScene::update() {
+ if (_smackerFileHash != 0) {
+ _mouseCursor->getSurface()->setVisible(false);
+ _smackerPlayer->open(_smackerFileHash, false);
+ _vm->_screen->clear();
+ _smackerDone = false;
+ _smackerFileHash = 0;
+ } else if (_smackerDone) {
+ if (_done) {
+ _parentModule->sendMessage(0x1009, _navigationIndex, this);
+ } else {
+ const NavigationItem &navigationItem = (*_navigationList)[_navigationIndex];
+ createMouseCursor();
+ _mouseCursor->getSurface()->setVisible(true);
+ _soundFlag2 = false;
+ _soundFlag1 = false;
+ _interactive = true;
+ // TODO Sound1ChList_sub_4080B0(0);
+ // TODO Sound1ChList_sub_408110(0);
+ _smackerDone = false;
+ _smackerPlayer->open(navigationItem.fileHash, true);
+ _vm->_screen->clear();
+ _parentModule->sendMessage(0x100A, _navigationIndex, this);
+ }
+ }
+ Scene::update();
+}
+
+uint32 NavigationScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ switch (messageNum) {
+ case 0x0000:
+ _mouseCursor->sendMessage(0x4002, param, this);
+ break;
+ case 0x0001:
+ handleNavigation(param.asPoint());
+ break;
+ case 0x0009:
+ if (!_interactive)
+ _smackerDone = true;
+ break;
+ case 0x3002:
+ _smackerDone = true;
+ break;
+ }
+ return 0;
+}
+
+void NavigationScene::createMouseCursor() {
+
+ const NavigationItem &navigationItem = (*_navigationList)[_navigationIndex];
+ uint32 mouseCursorFileHash;
+ int areaType;
+
+ if (_mouseCursor) {
+ deleteSprite(&_mouseCursor);
+ }
+
+ mouseCursorFileHash = navigationItem.mouseCursorFileHash;
+ // TODO: Check the resource...
+ if (mouseCursorFileHash == 0)
+ mouseCursorFileHash = 0x63A40028;
+
+ if (_itemsTypes) {
+ areaType = _itemsTypes[_navigationIndex];
+ } else if (navigationItem.middleSmackerFileHash != 0 || navigationItem.middleFlag) {
+ areaType = 0;
+ } else {
+ areaType = 1;
+ }
+
+ _mouseCursor = addSprite(new NavigationMouse(_vm, mouseCursorFileHash, areaType));
+ _mouseCursor->sendPointMessage(0x4002, _vm->getMousePos(), this);
+
+}
+
+void NavigationScene::handleNavigation(const NPoint &mousePos) {
+
+ const NavigationItem &navigationItem = (*_navigationList)[_navigationIndex];
+ bool oldSoundFlag1 = _soundFlag1;
+ bool oldSoundFlag2 = _soundFlag2;
+ uint32 direction = _mouseCursor->sendPointMessage(0x2064, mousePos, this);
+
+ switch (direction) {
+ // TODO: Merge cases 0 and 1?
+ case 0:
+ if (navigationItem.leftSmackerFileHash != 0) {
+ _smackerFileHash = navigationItem.leftSmackerFileHash;
+ _interactive = false;
+ _soundFlag1 = false;
+ _soundFlag2 = true;
+ do {
+ _navigationIndex--;
+ if (_navigationIndex < 0)
+ _navigationIndex = _navigationList->size() - 1;
+ } while (!(*_navigationList)[_navigationIndex].interactive);
+ setGlobalVar(0x4200189E, _navigationIndex);
+ } else {
+ _parentModule->sendMessage(0x1009, _navigationIndex, this);
+ }
+ break;
+ case 1:
+ if (navigationItem.rightSmackerFileHash != 0) {
+ _smackerFileHash = navigationItem.rightSmackerFileHash;
+ _interactive = false;
+ _soundFlag1 = false;
+ _soundFlag2 = true;
+ do {
+ _navigationIndex++;
+ if (_navigationIndex >= (int)_navigationList->size())
+ _navigationIndex = 0;
+ } while (!(*_navigationList)[_navigationIndex].interactive);
+ setGlobalVar(0x4200189E, _navigationIndex);
+ } else {
+ _parentModule->sendMessage(0x1009, _navigationIndex, this);
+ }
+ break;
+ case 2:
+ case 3:
+ case 4:
+ if (navigationItem.middleFlag) {
+ _parentModule->sendMessage(0x1009, _navigationIndex, this);
+ } else if (navigationItem.middleSmackerFileHash != 0) {
+ _smackerFileHash = navigationItem.middleSmackerFileHash;
+ _interactive = false;
+ _soundFlag1 = true;
+ _soundFlag2 = false;
+ _done = true;
+ }
+ break;
+ }
+
+ if (oldSoundFlag2 != _soundFlag2) {
+ // TODO Sound1ChList_sub_408110(_soundFlag2);
+ }
+
+ if (oldSoundFlag1 != _soundFlag1) {
+ // TODO Sound1ChList_sub_4080B0(_soundFlag1);
+ }
+
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/navigationscene.h b/engines/neverhood/navigationscene.h
new file mode 100644
index 0000000000..08aefb7cc4
--- /dev/null
+++ b/engines/neverhood/navigationscene.h
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_NAVIGATIONSCENE_H
+#define NEVERHOOD_NAVIGATIONSCENE_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/resourceman.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class NavigationScene : public Scene {
+public:
+ NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint32 navigationListId, int navigationIndex, byte *itemsTypes);
+ virtual ~NavigationScene();
+ byte getNavigationAreaType();
+protected:
+ SmackerPlayer *_smackerPlayer;
+ bool _smackerDone;
+ NavigationList *_navigationList;
+ int _navigationIndex;
+ uint32 _smackerFileHash;
+ bool _interactive;
+ bool _soundFlag1;
+ bool _soundFlag2;
+ bool _done;
+ byte *_itemsTypes;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void createMouseCursor();
+ void handleNavigation(const NPoint &mousePos);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_NAVIGATIONSCENE_H */
diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp
index 9e1475fe03..4440a05dd6 100644
--- a/engines/neverhood/neverhood.cpp
+++ b/engines/neverhood/neverhood.cpp
@@ -208,4 +208,11 @@ Common::Error NeverhoodEngine::run() {
return Common::kNoError;
}
+NPoint NeverhoodEngine::getMousePos() {
+ NPoint pt;
+ pt.x = _mouseX;
+ pt.y = _mouseY;
+ return pt;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h
index 38d773a324..86f7a0ad33 100644
--- a/engines/neverhood/neverhood.h
+++ b/engines/neverhood/neverhood.h
@@ -45,6 +45,7 @@ class GameVars;
class ResourceMan;
class Screen;
class StaticData;
+struct NPoint;
struct GameState {
int sceneNum;
@@ -119,6 +120,7 @@ public:
GameState& gameState() { return _gameState; }
int16 getMouseX() const { return _mouseX; }
int16 getMouseY() const { return _mouseY; }
+ NPoint getMousePos();
public:
diff --git a/engines/neverhood/smackerplayer.cpp b/engines/neverhood/smackerplayer.cpp
index bbb0db144c..f0b30084cc 100644
--- a/engines/neverhood/smackerplayer.cpp
+++ b/engines/neverhood/smackerplayer.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "graphics/palette.h"
#include "neverhood/smackerplayer.h"
#include "neverhood/palette.h"
#include "neverhood/resourceman.h"
@@ -68,26 +69,37 @@ void SmackerDoubleSurface::draw() {
SmackerPlayer::SmackerPlayer(NeverhoodEngine *vm, Scene *scene, uint32 fileHash, bool doubleSurface, bool flag)
: Entity(vm, 0), _scene(scene), _doubleSurface(doubleSurface), _dirtyFlag(false), _flag2(false),
- _palette(NULL), _smackerDecoder(NULL), _smackerSurface(NULL), _stream(NULL) {
+ _palette(NULL), _smackerDecoder(NULL), _smackerSurface(NULL), _stream(NULL), _smackerFirst(true) {
+
+ debug("_smackerSurface = %p", (void*)_smackerSurface);
SetUpdateHandler(&SmackerPlayer::update);
+
open(fileHash, flag);
}
SmackerPlayer::~SmackerPlayer() {
close();
-}
+}
-void SmackerPlayer::open(uint32 fileHash, bool flag1) {
+void SmackerPlayer::open(uint32 fileHash, bool keepLastFrame) {
debug("SmackerPlayer::open(%08X)", fileHash);
- _flag1 = flag1;
+ _keepLastFrame = keepLastFrame;
close();
+ if (_doubleSurface) {
+ _smackerSurface = new SmackerDoubleSurface(_vm);
+ } else {
+ _smackerSurface = new SmackerSurface(_vm);
+ }
+
+ _smackerFirst = true;
+
_stream = _vm->_res->createStream(fileHash);
- // TODO: _flag1 stuff
+ // TODO: _keepLastFrame stuff
_smackerDecoder = new Video::SmackerDecoder(_vm->_mixer);
_smackerDecoder->loadStream(_stream);
@@ -117,6 +129,8 @@ uint SmackerPlayer::getStatus() {
void SmackerPlayer::update() {
+ debug(8, "SmackerPlayer::update()");
+
if (!_smackerDecoder)
return;
@@ -129,20 +143,17 @@ void SmackerPlayer::update() {
const Graphics::Surface *smackerFrame = _smackerDecoder->decodeNextFrame();
- if (!_smackerSurface) {
+ if (_smackerFirst) {
if (_doubleSurface) {
- // TODO: Use SmackerDoubleSurface
- _smackerSurface = new SmackerDoubleSurface(_vm);
_smackerSurface->getDrawRect().x = 320 - _smackerDecoder->getWidth();
_smackerSurface->getDrawRect().y = 240 - _smackerDecoder->getHeight();
- // TODO DoubleDrawSurface.field_28 = false;
_smackerSurface->setSmackerFrame(smackerFrame);
} else {
- _smackerSurface = new SmackerSurface(_vm);
_smackerSurface->getDrawRect().x = (640 - _smackerDecoder->getWidth()) / 2;
_smackerSurface->getDrawRect().y = (480 - _smackerDecoder->getHeight()) / 2;
_smackerSurface->setSmackerFrame(smackerFrame);
}
+ _smackerFirst = false;
}
if (_doubleSurface) {
@@ -153,10 +164,12 @@ void SmackerPlayer::update() {
_dirtyFlag = true;
if (_smackerDecoder->hasDirtyPalette()) {
+ debug("updatePalette()");
updatePalette();
}
- if (_smackerDecoder->endOfVideo() && !_flag1) {
+ if (_smackerDecoder->endOfVideo() && !_keepLastFrame) {
+ // Inform the scene about the end of the video playback
if (_scene) {
_scene->sendMessage(0x3002, 0, this);
}
diff --git a/engines/neverhood/smackerplayer.h b/engines/neverhood/smackerplayer.h
index d923bbdf6b..2262277956 100644
--- a/engines/neverhood/smackerplayer.h
+++ b/engines/neverhood/smackerplayer.h
@@ -52,7 +52,7 @@ public:
SmackerPlayer(NeverhoodEngine *vm, Scene *scene, uint32 fileHash, bool doubleSurface, bool flag);
~SmackerPlayer();
BaseSurface *getSurface() { return _smackerSurface; }
- void open(uint32 fileHash, bool flag1);
+ void open(uint32 fileHash, bool keepLastFrame);
void close();
void gotoFrame(uint frameNumber);
uint getStatus();
@@ -61,9 +61,10 @@ protected:
Palette *_palette;
Video::SmackerDecoder *_smackerDecoder;
SmackerSurface *_smackerSurface;
+ bool _smackerFirst;
bool _doubleSurface;
Common::SeekableReadStream *_stream;
- bool _flag1;
+ bool _keepLastFrame;
bool _flag2;
bool _dirtyFlag;
void update();
diff --git a/engines/neverhood/smackerscene.cpp b/engines/neverhood/smackerscene.cpp
index 1584ac32d9..ace77f9284 100644
--- a/engines/neverhood/smackerscene.cpp
+++ b/engines/neverhood/smackerscene.cpp
@@ -92,7 +92,6 @@ void SmackerScene::nextVideo() {
_parentModule->sendMessage(0x1009, 0, this);
}
-
}
void SmackerScene::update() {