aboutsummaryrefslogtreecommitdiff
path: root/engines/neverhood
diff options
context:
space:
mode:
authorjohndoe1232013-01-03 22:38:56 +0000
committerWillem Jan Palenstijn2013-05-08 20:47:38 +0200
commit060287a4f85189cce3bb3b1b864b85cd81ee5c2f (patch)
tree62d539c5a9cbd345efd88e97e769563f2a1ebc05 /engines/neverhood
parent99e15e400537d85ff9f68cc10973b6d2c36c1776 (diff)
downloadscummvm-rg350-060287a4f85189cce3bb3b1b864b85cd81ee5c2f.tar.gz
scummvm-rg350-060287a4f85189cce3bb3b1b864b85cd81ee5c2f.tar.bz2
scummvm-rg350-060287a4f85189cce3bb3b1b864b85cd81ee5c2f.zip
NEVERHOOD: Improve frame-exact seeking for Scene2802
Thanks to clone2727 for his help!
Diffstat (limited to 'engines/neverhood')
-rw-r--r--engines/neverhood/gamemodule.cpp6
-rw-r--r--engines/neverhood/module2800.cpp3
-rw-r--r--engines/neverhood/smackerplayer.cpp34
-rw-r--r--engines/neverhood/smackerplayer.h9
4 files changed, 39 insertions, 13 deletions
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index dacac9861e..7d5932be42 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -362,7 +362,7 @@ void GameModule::startup() {
setGlobalVar(V_SHRINK_LIGHTS_ON, 0);
// <<<DEBUG
-#if 1
+#if 0
/*
//DEBUG>>>
createScene(_vm->gameState().sceneNum, _vm->gameState().which);
@@ -417,8 +417,8 @@ void GameModule::startup() {
_vm->gameState().sceneNum = 1;
createModule(2700, -1);
#endif
-#if 0
- _vm->gameState().sceneNum = 2;
+#if 1
+ _vm->gameState().sceneNum = 1;
createModule(2800, -1);
#endif
#if 0
diff --git a/engines/neverhood/module2800.cpp b/engines/neverhood/module2800.cpp
index f97d0719f0..e40890a882 100644
--- a/engines/neverhood/module2800.cpp
+++ b/engines/neverhood/module2800.cpp
@@ -540,6 +540,9 @@ Scene2802::Scene2802(NeverhoodEngine *vm, Module *parentModule, int which)
insertMouse435(0x008810A8, 20, 620);
_smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, 0x8284C100, true, true, true));
_currRadioMusicIndex = getGlobalVar(V_CURR_RADIO_MUSIC_INDEX);
+ // Need to go to the first frame first to load up the palette
+ _smackerPlayer->gotoFrame(0);
+ // Now we can actually set the current radio frame
_smackerPlayer->gotoFrame(_currRadioMusicIndex);
_vm->_soundMan->addSound(0x04360A18, 0x422630C2);
_vm->_soundMan->addSound(0x04360A18, 0x00632252);
diff --git a/engines/neverhood/smackerplayer.cpp b/engines/neverhood/smackerplayer.cpp
index 85319dcf26..7c14edf48b 100644
--- a/engines/neverhood/smackerplayer.cpp
+++ b/engines/neverhood/smackerplayer.cpp
@@ -62,6 +62,28 @@ void SmackerDoubleSurface::draw() {
_vm->_screen->drawDoubleSurface2(_smackerFrame, _drawRect);
}
+void NeverhoodSmackerDecoder::forceSeekToFrame(uint frame) {
+ if (!isVideoLoaded())
+ return;
+
+ if (frame >= getFrameCount())
+ error("Can't force Smacker seek to invalid frame %d", frame);
+
+ if (_header.audioInfo[0].hasAudio)
+ error("Can't force Smacker frame seek with audio");
+ if (!rewind())
+ error("Failed to rewind");
+
+ SmackerVideoTrack *videoTrack = (SmackerVideoTrack *)getTrack(0);
+ uint32 offset = 0;
+ for (uint32 i = 0; i < frame; i++) {
+ videoTrack->increaseCurFrame();
+ offset += _frameSizes[i] & ~3;
+ }
+
+ _fileStream->seek(offset, SEEK_CUR);
+}
+
// SmackerPlayer
SmackerPlayer::SmackerPlayer(NeverhoodEngine *vm, Scene *scene, uint32 fileHash, bool doubleSurface, bool flag, bool paused)
@@ -95,7 +117,7 @@ void SmackerPlayer::open(uint32 fileHash, bool keepLastFrame) {
_stream = _vm->_res->createStream(fileHash);
- _smackerDecoder = new Video::SmackerDecoder();
+ _smackerDecoder = new NeverhoodSmackerDecoder();
_smackerDecoder->loadStream(_stream);
_palette = new Palette(_vm);
@@ -120,12 +142,9 @@ void SmackerPlayer::close() {
}
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)
- _smackerDecoder->decodeNextFrame();
+ if (_smackerDecoder) {
+ _smackerDecoder->forceSeekToFrame(frameNumber);
+ _smackerDecoder->decodeNextFrame();
}
}
@@ -156,7 +175,6 @@ void SmackerPlayer::rewind() {
}
void SmackerPlayer::update() {
- debug(8, "SmackerPlayer::update()");
if (!_smackerDecoder)
return;
diff --git a/engines/neverhood/smackerplayer.h b/engines/neverhood/smackerplayer.h
index b4d8ddbe69..26ebff5d33 100644
--- a/engines/neverhood/smackerplayer.h
+++ b/engines/neverhood/smackerplayer.h
@@ -47,6 +47,11 @@ public:
virtual void draw();
};
+class NeverhoodSmackerDecoder : public Video::SmackerDecoder {
+public:
+ void forceSeekToFrame(uint frame);
+};
+
class SmackerPlayer : public Entity {
public:
SmackerPlayer(NeverhoodEngine *vm, Scene *scene, uint32 fileHash, bool doubleSurface, bool flag, bool paused = false);
@@ -61,11 +66,11 @@ public:
void setDrawPos(int16 x, int16 y);
void rewind();
bool isDone() { return getFrameNumber() + 1 == getFrameCount(); }
- Video::SmackerDecoder *getSmackerDecoder() const { return _smackerDecoder; }
+ NeverhoodSmackerDecoder *getSmackerDecoder() const { return _smackerDecoder; }
protected:
Scene *_scene;
Palette *_palette;
- Video::SmackerDecoder *_smackerDecoder;
+ NeverhoodSmackerDecoder *_smackerDecoder;
SmackerSurface *_smackerSurface;
uint32 _fileHash;
bool _smackerFirst;