diff options
author | johndoe123 | 2011-07-14 19:03:09 +0000 |
---|---|---|
committer | Willem Jan Palenstijn | 2013-05-08 20:38:48 +0200 |
commit | 0bfb52df74ac47a4842c66d40fd0ae5efc5d6af6 (patch) | |
tree | f622a0837b322356bbcdbe84a4c282b1d5b2addb /engines | |
parent | db9e45706caa2a4d2eddcb0c63532b3f6429a73e (diff) | |
download | scummvm-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.mk | 1 | ||||
-rw-r--r-- | engines/neverhood/module1000.cpp | 2 | ||||
-rw-r--r-- | engines/neverhood/navigationscene.cpp | 212 | ||||
-rw-r--r-- | engines/neverhood/navigationscene.h | 56 | ||||
-rw-r--r-- | engines/neverhood/neverhood.cpp | 7 | ||||
-rw-r--r-- | engines/neverhood/neverhood.h | 2 | ||||
-rw-r--r-- | engines/neverhood/smackerplayer.cpp | 35 | ||||
-rw-r--r-- | engines/neverhood/smackerplayer.h | 5 | ||||
-rw-r--r-- | engines/neverhood/smackerscene.cpp | 1 |
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 ¶m, 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 ¶m, 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() { |