diff options
author | Paul Gilbert | 2015-05-31 14:45:10 -0400 |
---|---|---|
committer | Paul Gilbert | 2015-05-31 14:45:10 -0400 |
commit | e5296ebf8dd09f603499b1894a33865ec71bb28f (patch) | |
tree | d7de032efd54dfdb3159cbc778a0c9ce8cd8aa91 /engines/groovie | |
parent | 673537bad93f0b440172a0cc263ebf19cc95ffc0 (diff) | |
parent | 141ff4d08dc24b6bb17098bd71801e2a58e6a38f (diff) | |
download | scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.tar.gz scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.tar.bz2 scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.zip |
Merge branch 'master' into phantom
Diffstat (limited to 'engines/groovie')
-rw-r--r-- | engines/groovie/graphics.cpp | 25 | ||||
-rw-r--r-- | engines/groovie/graphics.h | 2 | ||||
-rw-r--r-- | engines/groovie/roq.cpp | 76 | ||||
-rw-r--r-- | engines/groovie/roq.h | 6 | ||||
-rw-r--r-- | engines/groovie/script.cpp | 69 | ||||
-rw-r--r-- | engines/groovie/script.h | 1 |
6 files changed, 142 insertions, 37 deletions
diff --git a/engines/groovie/graphics.cpp b/engines/groovie/graphics.cpp index b85277fac7..e0c198f377 100644 --- a/engines/groovie/graphics.cpp +++ b/engines/groovie/graphics.cpp @@ -63,7 +63,7 @@ void GraphicsMan::update() { // Clear the buffer when ending the fade out if (_fading == 2) - _foreground.fillRect(Common::Rect(640, 320), 0); + _foreground.fillRect(Common::Rect(640, _foreground.h), 0); } } @@ -74,6 +74,22 @@ void GraphicsMan::update() { } } +void GraphicsMan::switchToFullScreen(bool fullScreen) { + _foreground.free(); + _background.free(); + + if (fullScreen) { + _foreground.create(640, 480, _vm->_pixelFormat); + _background.create(640, 480, _vm->_pixelFormat); + } else { + _vm->_system->fillScreen(0); + _foreground.create(640, 320, _vm->_pixelFormat); + _background.create(640, 320, _vm->_pixelFormat); + } + + _changed = true; +} + void GraphicsMan::change() { _changed = true; } @@ -84,7 +100,7 @@ void GraphicsMan::mergeFgAndBg() { countf = (byte *)_foreground.getPixels(); countb = (byte *)_background.getPixels(); - for (i = 640 * 320; i; i--) { + for (i = 640 * _foreground.h; i; i--) { if (255 == *(countf)) { *(countf) = *(countb); } @@ -94,7 +110,10 @@ void GraphicsMan::mergeFgAndBg() { } void GraphicsMan::updateScreen(Graphics::Surface *source) { - _vm->_system->copyRectToScreen(source->getPixels(), 640, 0, 80, 640, 320); + if (!isFullScreen()) + _vm->_system->copyRectToScreen(source->getPixels(), source->pitch, 0, 80, 640, 320); + else + _vm->_system->copyRectToScreen(source->getPixels(), source->pitch, 0, 0, 640, 480); change(); } diff --git a/engines/groovie/graphics.h b/engines/groovie/graphics.h index 72ab01deb6..69934f9d68 100644 --- a/engines/groovie/graphics.h +++ b/engines/groovie/graphics.h @@ -38,6 +38,8 @@ public: void update(); void change(); void mergeFgAndBg(); + void switchToFullScreen(bool fullScreen); + bool isFullScreen() { return (_foreground.h == 480); } void updateScreen(Graphics::Surface *source); Graphics::Surface _foreground; // The main surface that most things are drawn to Graphics::Surface _background; // Used occasionally, mostly (only?) in puzzles diff --git a/engines/groovie/roq.cpp b/engines/groovie/roq.cpp index 379fcabc07..f14cacd6b8 100644 --- a/engines/groovie/roq.cpp +++ b/engines/groovie/roq.cpp @@ -28,6 +28,7 @@ #include "groovie/groovie.h" #include "common/debug.h" +#include "common/debug-channels.h" #include "common/rect.h" #include "common/substream.h" #include "common/textconsole.h" @@ -46,6 +47,7 @@ namespace Groovie { ROQPlayer::ROQPlayer(GroovieEngine *vm) : VideoPlayer(vm), _codingTypeCount(0), + _fg(&_vm->_graphicsMan->_foreground), _bg(&_vm->_graphicsMan->_background), _firstFrame(true) { @@ -63,6 +65,22 @@ ROQPlayer::~ROQPlayer() { } uint16 ROQPlayer::loadInternal() { + if (DebugMan.isDebugChannelEnabled(kDebugVideo)) { + int8 i; + debugN(1, "Groovie::ROQ: New ROQ: bitflags are "); + for (i = 15; i >= 0; i--) { + debugN(1, "%d", _flags & (1 << i)? 1 : 0); + if (i % 4 == 0) { + debugN(1, " "); + } + } + debug(1, " <- 0 "); + } + + // Flags: + // - 2 For overlay videos, show the whole video + _flagTwo = ((_flags & (1 << 2)) != 0); + // Begin reading the file debugC(1, kDebugVideo, "Groovie::ROQ: Loading video"); @@ -106,13 +124,23 @@ uint16 ROQPlayer::loadInternal() { } void ROQPlayer::buildShowBuf() { + if (_alpha) + _fg->copyFrom(*_bg); + for (int line = 0; line < _bg->h; line++) { - uint32 *out = (uint32 *)_bg->getBasePtr(0, line); + uint32 *out = _alpha ? (uint32 *)_fg->getBasePtr(0, line) : (uint32 *)_bg->getBasePtr(0, line); uint32 *in = (uint32 *)_currBuf->getBasePtr(0, line / _scaleY); for (int x = 0; x < _bg->w; x++) { - // Copy a pixel - *out++ = *in; + // Copy a pixel, checking the alpha channel first + if (_alpha && !(*in & 0xFF)) + out++; + else if (_fg->h == 480 && *in == _vm->_pixelFormat.RGBToColor(255, 255, 255)) + // Handle transparency in Gamepad videos + // TODO: For now, we detect these videos by checking for full screen + out++; + else + *out++ = *in; // Skip to the next pixel if (!(x % _scaleX)) @@ -145,19 +173,27 @@ bool ROQPlayer::playFrameInternal() { } // Wait until the current frame can be shown - waitFrame(); + // Don't wait if we're just showing one frame + if (!playFirstFrame()) + waitFrame(); if (_dirty) { // Update the screen - _syst->copyRectToScreen(_bg->getPixels(), _bg->pitch, 0, (_syst->getHeight() - _bg->h) / 2, _bg->w, _bg->h); + void *src = (_alpha) ? _fg->getPixels() : _bg->getPixels(); + _syst->copyRectToScreen(src, _bg->pitch, 0, (_syst->getHeight() - _bg->h) / 2, _bg->w, _bg->h); _syst->updateScreen(); + // For overlay videos, set the background buffer when the video ends + if (_alpha && (!_flagTwo || (_flagTwo && _file->eos()))) + _bg->copyFrom(*_fg); + // Clear the dirty flag _dirty = false; } - // Return whether the video has ended - return _file->eos(); + // Report the end of the video if we reached the end of the file or if we + // just wanted to play one frame. + return _file->eos() || playFirstFrame(); } bool ROQPlayer::readBlockHeader(ROQBlockHeader &blockHeader) { @@ -277,9 +313,17 @@ bool ROQPlayer::processBlockInfo(ROQBlockHeader &blockHeader) { _prevBuf->create(width, height, _vm->_pixelFormat); } + // Switch from/to fullscreen, if needed + if (_bg->h != 480 && height == 480) + _vm->_graphicsMan->switchToFullScreen(true); + else if (_bg->h == 480 && height != 480) + _vm->_graphicsMan->switchToFullScreen(false); + // Clear the buffers with black - _currBuf->fillRect(Common::Rect(width, height), _vm->_pixelFormat.RGBToColor(0, 0, 0)); - _prevBuf->fillRect(Common::Rect(width, height), _vm->_pixelFormat.RGBToColor(0, 0, 0)); + if (!_alpha) { + _currBuf->fillRect(Common::Rect(width, height), _vm->_pixelFormat.RGBToColor(0, 0, 0)); + _prevBuf->fillRect(Common::Rect(width, height), _vm->_pixelFormat.RGBToColor(0, 0, 0)); + } return true; } @@ -448,7 +492,7 @@ bool ROQPlayer::processBlockSoundMono(ROQBlockHeader &blockHeader) { } // Initialize the audio stream if needed - if (!_audioStream) { + if (!_audioStream && !playFirstFrame()) { _audioStream = Audio::makeQueuingAudioStream(22050, false); Audio::SoundHandle sound_handle; g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &sound_handle, _audioStream); @@ -477,7 +521,10 @@ bool ROQPlayer::processBlockSoundMono(ROQBlockHeader &blockHeader) { #ifdef SCUMM_LITTLE_ENDIAN flags |= Audio::FLAG_LITTLE_ENDIAN; #endif - _audioStream->queueBuffer((byte *)buffer, blockHeader.size * 2, DisposeAfterUse::YES, flags); + if (!playFirstFrame()) + _audioStream->queueBuffer((byte *)buffer, blockHeader.size * 2, DisposeAfterUse::YES, flags); + else + free(buffer); return true; } @@ -491,7 +538,7 @@ bool ROQPlayer::processBlockSoundStereo(ROQBlockHeader &blockHeader) { } // Initialize the audio stream if needed - if (!_audioStream) { + if (!_audioStream && !playFirstFrame()) { _audioStream = Audio::makeQueuingAudioStream(22050, true); Audio::SoundHandle sound_handle; g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &sound_handle, _audioStream); @@ -533,7 +580,10 @@ bool ROQPlayer::processBlockSoundStereo(ROQBlockHeader &blockHeader) { #ifdef SCUMM_LITTLE_ENDIAN flags |= Audio::FLAG_LITTLE_ENDIAN; #endif - _audioStream->queueBuffer((byte *)buffer, blockHeader.size * 2, DisposeAfterUse::YES, flags); + if (!playFirstFrame()) + _audioStream->queueBuffer((byte *)buffer, blockHeader.size * 2, DisposeAfterUse::YES, flags); + else + free(buffer); return true; } diff --git a/engines/groovie/roq.h b/engines/groovie/roq.h index 7e7d38580e..ce1a3a2d58 100644 --- a/engines/groovie/roq.h +++ b/engines/groovie/roq.h @@ -57,6 +57,7 @@ private: bool processBlockSoundMono(ROQBlockHeader &blockHeader); bool processBlockSoundStereo(ROQBlockHeader &blockHeader); bool processBlockAudioContainer(ROQBlockHeader &blockHeader); + bool playFirstFrame() { return _alpha && !_flagTwo; } void paint2(byte i, int destx, int desty); void paint4(byte i, int destx, int desty); @@ -74,8 +75,11 @@ private: uint32 _codebook2[256 * 4]; byte _codebook4[256 * 4]; + // Flags + bool _flagTwo; + // Buffers - Graphics::Surface *_bg; + Graphics::Surface *_fg, *_bg; Graphics::Surface *_currBuf, *_prevBuf; void buildShowBuf(); byte _scaleX, _scaleY; diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp index 7625151082..eef97b6ff9 100644 --- a/engines/groovie/script.cpp +++ b/engines/groovie/script.cpp @@ -179,12 +179,20 @@ void Script::directGameLoad(int slot) { // TODO: Return to the main script, likely reusing most of o_returnscript() - // HACK: We set variable 0x19 to the slot to load, and set the current - // instruction to the one that actually loads the saved game specified - // in that variable. This will change in other versions of the game and - // in other games. - setVariable(0x19, slot); - _currentInstruction = 0x287; + // HACK: We set the slot to load in the appropriate variable, and set the + // current instruction to the one that actually loads the saved game + // specified in that variable. This differs depending on the game and its + // version. + if (_version == kGroovieT7G) { + // 7th Guest + setVariable(0x19, slot); + _currentInstruction = 0x287; + } else { + // 11th Hour + setVariable(0xF, slot); + // FIXME: This bypasses a lot of the game's initialization procedure + _currentInstruction = 0xE78E; + } // TODO: We'll probably need to start by running the beginning of the // script to let it do the soundcard initialization and then do the @@ -350,9 +358,10 @@ bool Script::hotspot(Common::Rect rect, uint16 address, uint8 cursor) { // Show hotspots when debugging if (DebugMan.isDebugChannelEnabled(kDebugHotspots)) { - rect.translate(0, -80); + if (!_vm->_graphicsMan->isFullScreen()) + rect.translate(0, -80); _vm->_graphicsMan->_foreground.frameRect(rect, 250); - _vm->_system->copyRectToScreen(_vm->_graphicsMan->_foreground.getPixels(), _vm->_graphicsMan->_foreground.pitch, 0, 80, 640, 320); + _vm->_graphicsMan->updateScreen(&_vm->_graphicsMan->_foreground); _vm->_system->updateScreen(); } @@ -962,7 +971,7 @@ void Script::o_strcmpnejmp_var() { // 0x21 void Script::o_copybgtofg() { // 0x22 debugC(1, kDebugScript, "COPY_BG_TO_FG"); - memcpy(_vm->_graphicsMan->_foreground.getPixels(), _vm->_graphicsMan->_background.getPixels(), 640 * 320); + memcpy(_vm->_graphicsMan->_foreground.getPixels(), _vm->_graphicsMan->_background.getPixels(), 640 * _vm->_graphicsMan->_foreground.h); } void Script::o_strcmpeqjmp() { // 0x23 @@ -1198,6 +1207,7 @@ void Script::o_copyrecttobg() { // 0x37 uint16 top = readScript16bits(); uint16 right = readScript16bits(); uint16 bottom = readScript16bits(); + uint16 baseTop = (!_vm->_graphicsMan->isFullScreen()) ? 80 : 0; // Sanity checks to prevent bad pointer access crashes if (left > right) { @@ -1216,9 +1226,9 @@ void Script::o_copyrecttobg() { // 0x37 bottom = top; top = j; } - if (top < 80) { - warning("COPYRECT top < 80... clamping"); - top = 80; + if (top < baseTop) { + warning("COPYRECT top < baseTop... clamping"); + top = baseTop; } if (top >= 480) { warning("COPYRECT top >= 480... clamping"); @@ -1243,13 +1253,13 @@ void Script::o_copyrecttobg() { // 0x37 debugC(1, kDebugScript, "COPYRECT((%d,%d)->(%d,%d))", left, top, right, bottom); - fg = (byte *)_vm->_graphicsMan->_foreground.getBasePtr(left, top - 80); - bg = (byte *)_vm->_graphicsMan->_background.getBasePtr(left, top - 80); + fg = (byte *)_vm->_graphicsMan->_foreground.getBasePtr(left, top - baseTop); + bg = (byte *)_vm->_graphicsMan->_background.getBasePtr(left, top - baseTop); for (i = 0; i < height; i++) { memcpy(bg + offset, fg + offset, width); offset += 640; } - _vm->_system->copyRectToScreen(_vm->_graphicsMan->_background.getBasePtr(left, top - 80), 640, left, top, width, height); + _vm->_system->copyRectToScreen(_vm->_graphicsMan->_background.getBasePtr(left, top - baseTop), 640, left, top, width, height); _vm->_graphicsMan->change(); } @@ -1595,8 +1605,7 @@ void Script::o_hotspot_outrect() { bool contained = rect.contains(mousepos); if (!contained) { - error("hotspot-outrect unimplemented"); - // TODO: what to do with address? + _currentInstruction = address; } } @@ -1670,15 +1679,29 @@ void Script::o2_vdxtransition() { void Script::o2_copyscreentobg() { uint16 val = readScript16bits(); + // TODO: Parameter + if (val) + warning("o2_copyscreentobg: Param is %d", val); + + Graphics::Surface *screen = _vm->_system->lockScreen(); + _vm->_graphicsMan->_background.copyFrom(screen->getSubArea(Common::Rect(0, 80, 640, 320))); + _vm->_system->unlockScreen(); + debugC(1, kDebugScript, "CopyScreenToBG3: 0x%04X", val); - error("Unimplemented Opcode 0x4F"); } void Script::o2_copybgtoscreen() { uint16 val = readScript16bits(); + // TODO: Parameter + if (val) + warning("o2_copybgtoscreen: Param is %d", val); + + Graphics::Surface *screen = _vm->_system->lockScreen(); + _vm->_graphicsMan->_background.copyRectToSurface(*screen, 0, 80, Common::Rect(0, 0, 640, 320 - 80)); + _vm->_system->unlockScreen(); + debugC(1, kDebugScript, "CopyBG3ToScreen: 0x%04X", val); - error("Unimplemented Opcode 0x50"); } void Script::o2_setvideoskip() { @@ -1686,6 +1709,12 @@ void Script::o2_setvideoskip() { debugC(1, kDebugScript, "SetVideoSkip (0x%04X)", _videoSkipAddress); } +void Script::o2_stub42() { + uint8 arg = readScript8bits(); + // TODO: Switch with 5 cases (0 - 5). Anything above 5 is a NOP + debugC(1, kDebugScript, "STUB42 (0x%02X)", arg); +} + void Script::o2_stub52() { uint8 arg = readScript8bits(); debugC(1, kDebugScript, "STUB52 (0x%02X)", arg); @@ -1859,7 +1888,7 @@ Script::OpcodeFunc Script::_opcodesV2[NUM_OPCODES] = { &Script::o_loadscript, &Script::o_setvideoorigin, // 0x40 &Script::o_sub, - &Script::o_cellmove, + &Script::o2_stub42, &Script::o_returnscript, &Script::o_sethotspotright, // 0x44 &Script::o_sethotspotleft, diff --git a/engines/groovie/script.h b/engines/groovie/script.h index 35e52593de..a9f6143509 100644 --- a/engines/groovie/script.h +++ b/engines/groovie/script.h @@ -238,6 +238,7 @@ private: void o2_setvideoskip(); void o2_copyscreentobg(); void o2_copybgtoscreen(); + void o2_stub42(); void o2_stub52(); void o2_setscriptend(); }; |