aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohndoe1232012-10-12 19:19:24 +0000
committerWillem Jan Palenstijn2013-05-08 20:47:06 +0200
commitb8d939a94b364a8d992a5053b527a822babccd37 (patch)
treee750ae72e42da5aee1f0ed2a2fcb7bb1ab9af18d
parent111b6d32c6c8e6aaafdb6e5efaeea0a0ae4aa998 (diff)
downloadscummvm-rg350-b8d939a94b364a8d992a5053b527a822babccd37.tar.gz
scummvm-rg350-b8d939a94b364a8d992a5053b527a822babccd37.tar.bz2
scummvm-rg350-b8d939a94b364a8d992a5053b527a822babccd37.zip
NEVERHOOD: Implement Scene2802 (radio tuning scene)
- Handle mouse button up events - Use the SmackerDecoder's rewind - Implement SmackerPlayer::gotoFrame (slow but better than nothing)
-rw-r--r--engines/neverhood/gamemodule.cpp39
-rw-r--r--engines/neverhood/gamemodule.h2
-rw-r--r--engines/neverhood/module2800.cpp215
-rw-r--r--engines/neverhood/module2800.h22
-rw-r--r--engines/neverhood/neverhood.cpp4
-rw-r--r--engines/neverhood/smackerplayer.cpp60
-rw-r--r--engines/neverhood/smackerplayer.h5
7 files changed, 304 insertions, 43 deletions
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index 0c2e0907a7..a85d8a90e5 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -46,6 +46,27 @@
namespace Neverhood {
+static const uint32 kScene2801MusicFileHashes[] = {
+ 0x82B22000,
+ 0x02B22004,
+ 0x42B22000,
+ 0x03322008,
+ 0x02B22001,
+ 0x02B22008,
+ 0x02B22020,
+ 0x03322001,
+ 0x03322002,
+ 0x03322004,
+ 0x03322040,
+ 0x02B22002,
+ 0x02B22010,
+ 0x03322010,
+ 0x02B22040,
+ 0x43322000,
+ 0x83322000,
+ 0x03322020
+};
+
GameModule::GameModule(NeverhoodEngine *vm)
: Module(vm, NULL), _moduleNum(-1) {
@@ -85,6 +106,16 @@ void GameModule::handleMouseDown(int16 x, int16 y) {
}
}
+void GameModule::handleMouseUp(int16 x, int16 y) {
+ if (_childObject) {
+ NPoint mousePos;
+ mousePos.x = x;
+ mousePos.y = y;
+ debug(2, "GameModule::handleMouseUp(%d, %d)", x, y);
+ sendPointMessage(_childObject, 2, mousePos);
+ }
+}
+
void GameModule::handleSpaceKey() {
if (_childObject) {
debug(2, "GameModule::handleSpaceKey()");
@@ -279,6 +310,12 @@ void GameModule::initScene3009Vars() {
}
}
+uint32 GameModule::getScene2802MusicFileHash() {
+ uint musicNum = getGlobalVar(0x08CC0828);
+ return (musicNum % 5 != 0) ? 0 : kScene2801MusicFileHashes[CLIP<uint>(musicNum / 5, 0, 17)];
+}
+
+
uint32 GameModule::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Module::handleMessage(messageNum, param, sender);
switch (messageNum) {
@@ -321,7 +358,7 @@ void GameModule::startup() {
#if 1
_vm->gameState().which = 0;
_vm->gameState().sceneNum = 1;
- createModule(3000, -1);
+ createModule(2800, -1);
#endif
#if 0
_vm->gameState().sceneNum = 0;
diff --git a/engines/neverhood/gamemodule.h b/engines/neverhood/gamemodule.h
index 7031bbbe16..82e6fa57c8 100644
--- a/engines/neverhood/gamemodule.h
+++ b/engines/neverhood/gamemodule.h
@@ -37,6 +37,7 @@ public:
void startup();
void handleMouseMove(int16 x, int16 y);
void handleMouseDown(int16 x, int16 y);
+ void handleMouseUp(int16 x, int16 y);
void handleSpaceKey();
void initScene1307Vars();
void initScene1405Vars();
@@ -44,6 +45,7 @@ public:
void initScene2808Vars1();
void initScene2808Vars2();
void initScene3009Vars();
+ uint32 getScene2802MusicFileHash();
protected:
Entity *_prevChildObject;
bool _someFlag1;
diff --git a/engines/neverhood/module2800.cpp b/engines/neverhood/module2800.cpp
index 4232b794df..1a51571fa3 100644
--- a/engines/neverhood/module2800.cpp
+++ b/engines/neverhood/module2800.cpp
@@ -31,9 +31,9 @@
namespace Neverhood {
Module2800::Module2800(NeverhoodEngine *vm, Module *parentModule, int which)
- : Module(vm, parentModule) {
+ : Module(vm, parentModule), _musicResource(NULL) {
- _fileHash = 0;
+ _currentMusicFileHash = 0;
// TODO music stuff
_vm->_soundMan->addMusic(0x64210814, 0xD2FA4D14);
setGlobalVar(0x28D8C940, 1);
@@ -51,7 +51,10 @@ Module2800::Module2800(NeverhoodEngine *vm, Module *parentModule, int which)
}
Module2800::~Module2800() {
- // TODO music stuff
+ if (_musicResource) {
+ _musicResource->unload();
+ delete _musicResource;
+ }
_vm->_soundMan->deleteGroup(0x64210814);
}
@@ -65,6 +68,11 @@ void Module2800::createScene(int sceneNum, int which) {
break;
case 1:
_vm->_soundMan->stopMusic(0xD2FA4D14, 0, 0);
+
+ // TODO!!
+
+ _childObject = new Scene2802(_vm, this, which);
+
#if 0
_flag = true; // DEBUG!
if (_flag) {
@@ -180,10 +188,10 @@ void Module2800::createScene(int sceneNum, int which) {
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new DiskplayerScene(_vm, this, 4);
break;
- //
case 1001:
+ _vm->_soundMan->stopMusic(0xD2FA4D14, 0, 0);
+ createSmackerScene(0x00800801, true, true, false);
break;
- // TODO ...
}
SetUpdateHandler(&Module2800::updateScene);
_childObject->handleUpdate();
@@ -351,22 +359,51 @@ void Module2800::updateScene() {
case 26:
createScene(11, 2);
break;
- //
case 1001:
+ createScene(1, -1);
break;
}
} else {
switch (_vm->gameState().sceneNum) {
case 0:
- // TODO Module2800_updateMusic(true);
+ updateMusic(true);
break;
case 1:
- // TODO Module2800_updateMusic(false);
+ updateMusic(false);
break;
}
}
}
+void Module2800::updateMusic(bool halfVolume) {
+
+ uint32 newMusicFileHash = _vm->_gameModule->getScene2802MusicFileHash();
+
+ if (!_musicResource)
+ _musicResource = new MusicResource(_vm);
+
+ if (newMusicFileHash != _currentMusicFileHash) {
+ _currentMusicFileHash = newMusicFileHash;
+ if (_currentMusicFileHash != 0) {
+ _musicResource->load(_currentMusicFileHash);
+ _musicResource->setVolume(halfVolume ? 60 : 100);
+ _musicResource->play(0);
+ } else {
+ _musicResource->stop(0);
+ }
+ } else if (_currentMusicFileHash != 0) {
+ if (!_musicResource->isPlaying()) {
+ _musicResource->setVolume(halfVolume ? 60 : 100);
+ _musicResource->play(0);
+ } else {
+ _musicResource->setVolume(halfVolume ? 60 : 100);
+ }
+ } else {
+ _musicResource->stop(0);
+ }
+
+}
+
Scene2801::Scene2801(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule, true) {
@@ -475,6 +512,168 @@ uint32 Scene2801::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
+Scene2802::Scene2802(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true), _countdownType(0), _countdown1(0), _countdown2(0) {
+
+ //DEBUG>>> Disable video
+ setGlobalVar(0x28D8C940, 0);
+ //DEBUG<<<
+
+ _surfaceFlag = true;
+ SetMessageHandler(&Scene2802::handleMessage);
+ SetUpdateHandler(&Scene2802::update);
+ insertMouse435(0x008810A8, 20, 620);
+ _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, 0x8284C100, true, true, true));
+ _smackerFrameNumber = getGlobalVar(0x08CC0828);
+ _smackerPlayer->gotoFrame(_smackerFrameNumber);
+ _vm->_soundMan->addSound(0x04360A18, 0x422630C2);
+ _vm->_soundMan->addSound(0x04360A18, 0x00632252);
+ _vm->_soundMan->addSound(0x04360A18, 0x00372241);
+ _vm->_soundMan->setSoundVolume(0x00372241, 60);
+ changeCountdownType(0, 0);
+ _vm->_soundMan->playSoundLooping(0x00372241);
+}
+
+Scene2802::~Scene2802() {
+ _vm->_soundMan->deleteSoundGroup(0x04360A18);
+ if (_smackerFrameNumber == 0) {
+ setGlobalVar(0x09880D40, 1);
+ setGlobalVar(0x08180ABC, 0);
+ } else if (_smackerFrameNumber == getGlobalVar(0x88880915)) {
+ setGlobalVar(0x09880D40, 0);
+ setGlobalVar(0x08180ABC, 1);
+ } else {
+ setGlobalVar(0x09880D40, 0);
+ setGlobalVar(0x08180ABC, 0);
+ }
+ setGlobalVar(0x08CC0828, _smackerFrameNumber);
+}
+
+void Scene2802::update() {
+ int prevCountdownType = _countdownType;
+ uint prevSmackerFrameNumber = _smackerFrameNumber;
+
+ Scene::update();
+ if (_countdown1 > 0)
+ --_countdown1;
+ else if (_countdownType == 1)
+ _countdownType = 3;
+ else if (_countdownType == 4)
+ _countdownType = 6;
+
+ switch (_countdownType) {
+ case 2:
+ if (_smackerFrameNumber < 90)
+ incSmackerFrameNumber(+1);
+ _countdownType = 0;
+ break;
+ case 3:
+ if (_countdown2 > 0)
+ --_countdown2;
+ else if (_smackerFrameNumber < 90) {
+ incSmackerFrameNumber(+1);
+ _countdown2 = 1;
+ } else
+ _countdownType = 0;
+ break;
+ case 5:
+ if (_smackerFrameNumber > 0)
+ incSmackerFrameNumber(-1);
+ _countdownType = 0;
+ break;
+ case 6:
+ if (_countdown2 > 0)
+ --_countdown2;
+ else if (_smackerFrameNumber > 0) {
+ incSmackerFrameNumber(-1);
+ _countdown2 = 1;
+ } else
+ _countdownType = 0;
+ break;
+
+ }
+
+ if (prevSmackerFrameNumber != _smackerFrameNumber)
+ _smackerPlayer->gotoFrame(_smackerFrameNumber);
+
+ if (prevCountdownType != _countdownType)
+ changeCountdownType(prevCountdownType, _countdownType);
+
+ if (getGlobalVar(0x28D8C940) && prevCountdownType != _countdownType && _smackerFrameNumber != 0) {
+ setGlobalVar(0x28D8C940, 0);
+ leaveScene(1);
+ }
+
+}
+
+uint32 Scene2802::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ int prevCountdownType = _countdownType;
+ Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x0001:
+ if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
+ leaveScene(0);
+ } else if (_countdownType == 0) {
+ if (param.asPoint().x > 180 && param.asPoint().x < 300 &&
+ param.asPoint().y > 130 && param.asPoint().y < 310) {
+ _countdownType = 4;
+ } else if (param.asPoint().x > 300 && param.asPoint().x < 400 &&
+ param.asPoint().y > 130 && param.asPoint().y < 310) {
+ _countdownType = 1;
+ }
+ if (_countdownType == 1 || _countdownType == 4) {
+ _countdown1 = 8;
+ changeCountdownType(0, _countdownType);
+ }
+ }
+ break;
+ case 0x0002: // TODO Implement button up event
+ if (_countdown1 == 0)
+ _countdownType = 0;
+ else {
+ if (_countdownType == 1)
+ _countdownType = 2;
+ else if (_countdownType == 4)
+ _countdownType = 5;
+ else
+ _countdownType = 0;
+ _countdown1 = 0;
+ }
+ if (prevCountdownType != _countdownType)
+ changeCountdownType(prevCountdownType, _countdownType);
+ break;
+ case 0x000D:
+ // DEBUG message
+ break;
+ }
+ return 0;
+}
+
+void Scene2802::incSmackerFrameNumber(int delta) {
+ _smackerFrameNumber += delta;
+ setGlobalVar(0x08CC0828, _smackerFrameNumber);
+}
+
+void Scene2802::changeCountdownType(int prevCountdownType, int newCountdownType) {
+
+ if (prevCountdownType == 3 || prevCountdownType == 6) {
+ _vm->_soundMan->stopSound(0x422630C2);
+ _vm->_soundMan->stopSound(0x00632252);
+ }
+
+ if (newCountdownType == 0) {
+ if (_vm->_gameModule->getScene2802MusicFileHash() != 0) {
+ _vm->_soundMan->stopSound(0x00632252);
+ }
+ else
+ _vm->_soundMan->playSoundLooping(0x00632252);
+ } else if (newCountdownType == 3 || newCountdownType == 6) {
+ _vm->_soundMan->playSoundLooping(0x422630C2);
+ _vm->_soundMan->playSoundLooping(0x00632252);
+ }
+
+}
+
AsScene2803LightCord::AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y)
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _fileHash1(fileHash1), _fileHash2(fileHash2),
_isPulled(false), _isBusy(false) {
diff --git a/engines/neverhood/module2800.h b/engines/neverhood/module2800.h
index f0403f4990..ca8b058ca1 100644
--- a/engines/neverhood/module2800.h
+++ b/engines/neverhood/module2800.h
@@ -37,15 +37,17 @@ public:
virtual ~Module2800();
protected:
bool _flag;
- uint32 _fileHash;
+ uint32 _currentMusicFileHash;
+ MusicResource *_musicResource;
void createScene(int sceneNum, int which);
void updateScene();
+ void updateMusic(bool halfVolume);
};
class Scene2801 : public Scene {
public:
Scene2801(NeverhoodEngine *vm, Module *parentModule, int which);
- ~Scene2801();
+ virtual ~Scene2801();
protected:
Sprite *_sprite1;
Sprite *_sprite2;
@@ -54,6 +56,22 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
+class Scene2802 : public Scene {
+public:
+ Scene2802(NeverhoodEngine *vm, Module *parentModule, int which);
+ virtual ~Scene2802();
+protected:
+ SmackerPlayer *_smackerPlayer;
+ uint _smackerFrameNumber;
+ int _countdownType;
+ int _countdown1;
+ int _countdown2;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void incSmackerFrameNumber(int delta);
+ void changeCountdownType(int prevCountdownType, int newCountdownType);
+};
+
class AsScene2803LightCord : public AnimatedSprite {
public:
AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y);
diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp
index 4b75f68c3e..cfeaf927d3 100644
--- a/engines/neverhood/neverhood.cpp
+++ b/engines/neverhood/neverhood.cpp
@@ -136,6 +136,10 @@ Common::Error NeverhoodEngine::run() {
case Common::EVENT_RBUTTONDOWN:
_gameModule->handleMouseDown(event.mouse.x, event.mouse.y);
break;
+ case Common::EVENT_LBUTTONUP:
+ case Common::EVENT_RBUTTONUP:
+ _gameModule->handleMouseUp(event.mouse.x, event.mouse.y);
+ break;
case Common::EVENT_QUIT:
_system->quit();
break;
diff --git a/engines/neverhood/smackerplayer.cpp b/engines/neverhood/smackerplayer.cpp
index 0ed6748e45..b491bc5789 100644
--- a/engines/neverhood/smackerplayer.cpp
+++ b/engines/neverhood/smackerplayer.cpp
@@ -65,8 +65,8 @@ void SmackerDoubleSurface::draw() {
// SmackerPlayer
-SmackerPlayer::SmackerPlayer(NeverhoodEngine *vm, Scene *scene, uint32 fileHash, bool doubleSurface, bool flag)
- : Entity(vm, 0), _scene(scene), _doubleSurface(doubleSurface), _dirtyFlag(false), _videoDone(false),
+SmackerPlayer::SmackerPlayer(NeverhoodEngine *vm, Scene *scene, uint32 fileHash, bool doubleSurface, bool flag, bool paused)
+ : Entity(vm, 0), _scene(scene), _doubleSurface(doubleSurface), _dirtyFlag(false), _videoDone(false), _paused(paused),
_palette(NULL), _smackerDecoder(NULL), _smackerSurface(NULL), _stream(NULL), _smackerFirst(true),
_drawX(-1), _drawY(-1) {
@@ -104,7 +104,8 @@ void SmackerPlayer::open(uint32 fileHash, bool keepLastFrame) {
_palette = new Palette(_vm);
_palette->usePalette();
- _smackerDecoder->start();
+ if (!_paused)
+ _smackerDecoder->start();
}
@@ -121,8 +122,14 @@ void SmackerPlayer::close() {
_smackerSurface = NULL;
}
-void SmackerPlayer::gotoFrame(uint frameNumber) {
- // TODO?
+void SmackerPlayer::gotoFrame(int frameNumber) {
+ // NOTE Slow as hell but only used in Scene2802
+ if (frameNumber != _smackerDecoder->getCurFrame()) {
+ if (frameNumber < _smackerDecoder->getCurFrame())
+ rewind();
+ while (_smackerDecoder->getCurFrame() != frameNumber)
+ updateFrame();
+ }
}
uint32 SmackerPlayer::getFrameCount() {
@@ -147,20 +154,8 @@ void SmackerPlayer::setDrawPos(int16 x, int16 y) {
}
void SmackerPlayer::rewind() {
-
- // TODO Quite dirty, try to implement this in the decoder
-
- delete _smackerDecoder;
- _smackerDecoder = NULL;
- _stream = NULL;
-
- _smackerFirst = true;
-
- _stream = _vm->_res->createStream(_fileHash);
-
- _smackerDecoder = new Video::SmackerDecoder();
- _smackerDecoder->loadStream(_stream);
-
+ if (_smackerDecoder)
+ _smackerDecoder->rewind();
}
void SmackerPlayer::update() {
@@ -174,17 +169,22 @@ void SmackerPlayer::update() {
_dirtyFlag = false;
}
- if (!_smackerDecoder->endOfVideo()) {
- updateFrame();
- } else if (!_keepLastFrame) {
- // Inform the scene about the end of the video playback
- if (_scene)
- sendMessage(_scene, 0x3002, 0);
- _videoDone = true;
+ if (_paused) {
+ if (_smackerFirst)
+ updateFrame();
} else {
- rewind();
- updateFrame();
- _videoDone = false;
+ if (!_smackerDecoder->endOfVideo()) {
+ updateFrame();
+ } else if (!_keepLastFrame) {
+ // Inform the scene about the end of the video playback
+ if (_scene)
+ sendMessage(_scene, 0x3002, 0);
+ _videoDone = true;
+ } else {
+ rewind();
+ updateFrame();
+ _videoDone = false;
+ }
}
}
@@ -214,7 +214,7 @@ void SmackerPlayer::updateFrame() {
// TODO _vm->_screen->_skipUpdate = true;
_dirtyFlag = true;
-
+
if (_smackerDecoder->hasDirtyPalette())
updatePalette();
diff --git a/engines/neverhood/smackerplayer.h b/engines/neverhood/smackerplayer.h
index c480c2d8d8..63c9ebb774 100644
--- a/engines/neverhood/smackerplayer.h
+++ b/engines/neverhood/smackerplayer.h
@@ -49,12 +49,12 @@ public:
class SmackerPlayer : public Entity {
public:
- SmackerPlayer(NeverhoodEngine *vm, Scene *scene, uint32 fileHash, bool doubleSurface, bool flag);
+ SmackerPlayer(NeverhoodEngine *vm, Scene *scene, uint32 fileHash, bool doubleSurface, bool flag, bool paused = false);
~SmackerPlayer();
BaseSurface *getSurface() { return _smackerSurface; }
void open(uint32 fileHash, bool keepLastFrame);
void close();
- void gotoFrame(uint frameNumber);
+ void gotoFrame(int frameNumber);
uint32 getFrameCount();
uint32 getFrameNumber();
uint getStatus();
@@ -74,6 +74,7 @@ protected:
bool _keepLastFrame;
bool _videoDone;
bool _dirtyFlag;
+ bool _paused;
int _drawX, _drawY;
void update();
void updateFrame();