diff options
author | Scott Thomas | 2009-08-21 13:57:03 +0000 |
---|---|---|
committer | Scott Thomas | 2009-08-21 13:57:03 +0000 |
commit | 58f8ec5d5789375b6f7f1b2b84748fc6256e8e54 (patch) | |
tree | 7fbc635e4febb062f2726de3de7f1017e4f79308 | |
parent | aad7d1536f867b1335ea1aa389ccc29d4d073f64 (diff) | |
download | scummvm-rg350-58f8ec5d5789375b6f7f1b2b84748fc6256e8e54.tar.gz scummvm-rg350-58f8ec5d5789375b6f7f1b2b84748fc6256e8e54.tar.bz2 scummvm-rg350-58f8ec5d5789375b6f7f1b2b84748fc6256e8e54.zip |
Groovie: Sync changes from 16bpp branch. Hopefully no regressions sneak in here
svn-id: r43598
-rw-r--r-- | engines/groovie/graphics.cpp | 4 | ||||
-rw-r--r-- | engines/groovie/groovie.cpp | 22 | ||||
-rw-r--r-- | engines/groovie/groovie.h | 2 | ||||
-rw-r--r-- | engines/groovie/roq.cpp | 162 | ||||
-rw-r--r-- | engines/groovie/script.cpp | 90 | ||||
-rw-r--r-- | engines/groovie/script.h | 7 |
6 files changed, 191 insertions, 96 deletions
diff --git a/engines/groovie/graphics.cpp b/engines/groovie/graphics.cpp index 647eaa913b..1e54f0e79b 100644 --- a/engines/groovie/graphics.cpp +++ b/engines/groovie/graphics.cpp @@ -31,8 +31,8 @@ namespace Groovie { GraphicsMan::GraphicsMan(GroovieEngine *vm) : _vm(vm), _changed(false), _fading(0) { // Create the game surfaces - _foreground.create(640, 320, 1); - _background.create(640, 320, 1); + _foreground.create(640, 320, _vm->_pixelFormat.bytesPerPixel); + _background.create(640, 320, _vm->_pixelFormat.bytesPerPixel); } GraphicsMan::~GraphicsMan() { diff --git a/engines/groovie/groovie.cpp b/engines/groovie/groovie.cpp index 9381b5b47c..bb4e142196 100644 --- a/engines/groovie/groovie.cpp +++ b/engines/groovie/groovie.cpp @@ -70,7 +70,20 @@ GroovieEngine::~GroovieEngine() { Common::Error GroovieEngine::run() { // Initialize the graphics - initGraphics(640, 480, true); + switch (_gameDescription->version) { + case kGroovieV2: + // Request the mode with the highest precision available + initGraphics(640, 480, true, NULL); + + // Save the enabled mode as it can be both an RGB mode or CLUT8 + _pixelFormat = _system->getScreenFormat(); + _mode8bit = (_pixelFormat == Graphics::PixelFormat::createFormatCLUT8()); + break; + case kGroovieT7G: + initGraphics(640, 480, true); + _pixelFormat = Graphics::PixelFormat::createFormatCLUT8(); + break; + } // Create debugger. It requires GFX to be initialized _debugger = new Debugger(this); @@ -204,13 +217,18 @@ Common::Error GroovieEngine::run() { case Common::EVENT_LBUTTONDOWN: // Send the event to the scripts - _script.setMouseClick(); + _script.setMouseClick(1); // Continue the script execution to handle // the click _waitingForInput = false; break; + case Common::EVENT_RBUTTONDOWN: + // Send the event to the scripts (to skip the video) + _script.setMouseClick(2); + break; + case Common::EVENT_QUIT: quitGame(); break; diff --git a/engines/groovie/groovie.h b/engines/groovie/groovie.h index a137193adf..bf57ae77de 100644 --- a/engines/groovie/groovie.h +++ b/engines/groovie/groovie.h @@ -85,6 +85,8 @@ protected: public: void waitForInput(); + Graphics::PixelFormat _pixelFormat; + bool _mode8bit; Script _script; ResMan *_resMan; GrvCursorMan *_grvCursorMan; diff --git a/engines/groovie/roq.cpp b/engines/groovie/roq.cpp index dcb8eafcb8..538b1b7111 100644 --- a/engines/groovie/roq.cpp +++ b/engines/groovie/roq.cpp @@ -29,6 +29,12 @@ #include "groovie/groovie.h" #include "groovie/roq.h" +#include "graphics/jpeg.h" + +#ifdef ENABLE_RGB_COLOR +// Required for the YUV to RGB conversion +#include "graphics/conversion.h" +#endif #include "sound/mixer.h" namespace Groovie { @@ -43,50 +49,52 @@ ROQPlayer::ROQPlayer(GroovieEngine *vm) : _currBuf = new Graphics::Surface(); _prevBuf = new Graphics::Surface(); - byte pal[256 * 4]; + if (_vm->_mode8bit) { + byte pal[256 * 4]; #ifdef DITHER - byte pal3[256 * 3]; - // Initialize to a black palette - for (int i = 0; i < 256 * 3; i++) { - pal3[i] = 0; - } - - // Build a basic color palette - for (int r = 0; r < 4; r++) { - for (int g = 0; g < 4; g++) { - for (int b = 0; b < 4; b++) { - byte col = (r << 4) | (g << 2) | (b << 0); - pal3[3 * col + 0] = r << 6; - pal3[3 * col + 1] = g << 6; - pal3[3 * col + 2] = b << 6; + byte pal3[256 * 3]; + // Initialize to a black palette + for (int i = 0; i < 256 * 3; i++) { + pal3[i] = 0; + } + + // Build a basic color palette + for (int r = 0; r < 4; r++) { + for (int g = 0; g < 4; g++) { + for (int b = 0; b < 4; b++) { + byte col = (r << 4) | (g << 2) | (b << 0); + pal3[3 * col + 0] = r << 6; + pal3[3 * col + 1] = g << 6; + pal3[3 * col + 2] = b << 6; + } } } - } - // Initialize the dithering algorithm - _paletteLookup = new Graphics::PaletteLUT(8, Graphics::PaletteLUT::kPaletteYUV); - _paletteLookup->setPalette(pal3, Graphics::PaletteLUT::kPaletteRGB, 8); - for (int i = 0; (i < 64) && !_vm->shouldQuit(); i++) { - debug("Groovie::ROQ: Building palette table: %02d/63", i); - _paletteLookup->buildNext(); - } + // Initialize the dithering algorithm + _paletteLookup = new Graphics::PaletteLUT(8, Graphics::PaletteLUT::kPaletteYUV); + _paletteLookup->setPalette(pal3, Graphics::PaletteLUT::kPaletteRGB, 8); + for (int i = 0; (i < 64) && !_vm->shouldQuit(); i++) { + debug("Groovie::ROQ: Building palette table: %02d/63", i); + _paletteLookup->buildNext(); + } - // Prepare the palette to show - for (int i = 0; i < 256; i++) { - pal[(i * 4) + 0] = pal3[(i * 3) + 0]; - pal[(i * 4) + 1] = pal3[(i * 3) + 1]; - pal[(i * 4) + 2] = pal3[(i * 3) + 2]; - } -#else - // Set a grayscale palette - for (int i = 0; i < 256; i++) { - pal[(i * 4) + 0] = i; - pal[(i * 4) + 1] = i; - pal[(i * 4) + 2] = i; - } -#endif + // Prepare the palette to show + for (int i = 0; i < 256; i++) { + pal[(i * 4) + 0] = pal3[(i * 3) + 0]; + pal[(i * 4) + 1] = pal3[(i * 3) + 1]; + pal[(i * 4) + 2] = pal3[(i * 3) + 2]; + } +#else // !DITHER + // Set a grayscale palette + for (int i = 0; i < 256; i++) { + pal[(i * 4) + 0] = i; + pal[(i * 4) + 1] = i; + pal[(i * 4) + 2] = i; + } +#endif // DITHER - _syst->setPalette(pal, 0, 256); + _syst->setPalette(pal, 0, 256); + } } ROQPlayer::~ROQPlayer() { @@ -152,22 +160,39 @@ void ROQPlayer::buildShowBuf() { for (int line = 0; line < _showBuf.h; line++) { byte *out = (byte *)_showBuf.getBasePtr(0, line); - byte *in = (byte *)_prevBuf->getBasePtr(0, line / _scaleY); + byte *in = (byte *)_currBuf->getBasePtr(0, line / _scaleY); for (int x = 0; x < _showBuf.w; x++) { + if (_vm->_mode8bit) { #ifdef DITHER - *out = _dither->dither(*in, *(in + 1), *(in + 2), x); + *out = _dither->dither(*in, *(in + 1), *(in + 2), x); #else - // Just use the luminancy component - *out = *in; -#endif - out++; + // Just use the luminancy component + *out = *in; +#endif // DITHER +#ifdef ENABLE_RGB_COLOR + } else { + // Do the format conversion (YUV -> RGB -> Screen format) + byte r, g, b; + Graphics::YUV2RGB(*in, *(in + 1), *(in + 2), r, g, b); + // FIXME: this is fixed to 16bit + *(uint16 *)out = (uint16)_vm->_pixelFormat.RGBToColor(r, g, b); +#endif // ENABLE_RGB_COLOR + } + + // Skip to the next pixel + out += _vm->_pixelFormat.bytesPerPixel; if (!(x % _scaleX)) - in += _prevBuf->bytesPerPixel; + in += _currBuf->bytesPerPixel; } #ifdef DITHER _dither->nextLine(); #endif } + + // Swap buffers + Graphics::Surface *tmp = _prevBuf; + _prevBuf = _currBuf; + _currBuf = tmp; } bool ROQPlayer::playFrameInternal() { @@ -180,7 +205,7 @@ bool ROQPlayer::playFrameInternal() { } if (_dirty) { - // Build the show buffer from the previous (back) buffer + // Build the show buffer from the current buffer buildShowBuf(); } @@ -189,7 +214,7 @@ bool ROQPlayer::playFrameInternal() { if (_dirty) { // Update the screen - _syst->copyRectToScreen((byte *)_showBuf.getBasePtr(0, 0), _showBuf.w, 0, (_syst->getHeight() - _showBuf.h) / 2, _showBuf.pitch, _showBuf.h); + _syst->copyRectToScreen((byte *)_showBuf.getBasePtr(0, 0), _showBuf.pitch, 0, (_syst->getHeight() - _showBuf.h) / 2, _showBuf.w, _showBuf.h); _syst->updateScreen(); // Clear the dirty flag @@ -240,19 +265,15 @@ bool ROQPlayer::processBlock() { case 0x1002: // Quad codebook definition ok = processBlockQuadCodebook(blockHeader); break; - case 0x1011: { // Quad vector quantised video frame + case 0x1011: // Quad vector quantised video frame ok = processBlockQuadVector(blockHeader); _dirty = true; endframe = true; - - // Swap buffers - Graphics::Surface *tmp = _prevBuf; - _prevBuf = _currBuf; - _currBuf = tmp; break; - } case 0x1012: // Still image (JPEG) ok = processBlockStill(blockHeader); + _dirty = true; + endframe = true; break; case 0x1013: // Hang assert(blockHeader.size == 0 && blockHeader.param == 0); @@ -317,7 +338,19 @@ bool ROQPlayer::processBlockInfo(ROQBlockHeader &blockHeader) { // Allocate new buffers _currBuf->create(width, height, 3); _prevBuf->create(width, height, 3); - _showBuf.create(width * _scaleX, height * _scaleY, 1); + _showBuf.create(width * _scaleX, height * _scaleY, _vm->_pixelFormat.bytesPerPixel); + + // Clear the buffers with black YUV values + byte *ptr1 = (byte *)_currBuf->getBasePtr(0, 0); + byte *ptr2 = (byte *)_prevBuf->getBasePtr(0, 0); + for (int i = 0; i < width * height; i++) { + *ptr1++ = 0; + *ptr1++ = 128; + *ptr1++ = 128; + *ptr2++ = 0; + *ptr2++ = 128; + *ptr2++ = 128; + } #ifdef DITHER // Reset the dithering algorithm with the new width @@ -456,10 +489,23 @@ void ROQPlayer::processBlockQuadVectorBlockSub(int baseX, int baseY, int8 Mx, in bool ROQPlayer::processBlockStill(ROQBlockHeader &blockHeader) { debugC(5, kGroovieDebugVideo | kGroovieDebugAll, "Groovie::ROQ: Processing still (JPEG) block"); - warning("Groovie::ROQ: JPEG frame (unimplemented)"); - memset(_prevBuf->getBasePtr(0, 0), 0, _prevBuf->w * _prevBuf->h * _prevBuf->bytesPerPixel); + warning("Groovie::ROQ: JPEG frame (unfinshed)"); + + Graphics::JPEG *jpg = new Graphics::JPEG(); + jpg->read(_file); + byte *y = (byte *)jpg->getComponent(1)->getBasePtr(0, 0); + byte *u = (byte *)jpg->getComponent(2)->getBasePtr(0, 0); + byte *v = (byte *)jpg->getComponent(3)->getBasePtr(0, 0); + + byte *ptr = (byte *)_currBuf->getBasePtr(0, 0); + for (int i = 0; i < _currBuf->w * _currBuf->h; i++) { + *ptr++ = *y++; + *ptr++ = *u++; + *ptr++ = *v++; + } + memcpy(_prevBuf->getBasePtr(0, 0), _currBuf->getBasePtr(0, 0), _prevBuf->w * _prevBuf->h * 3); - _file->skip(blockHeader.size); + delete jpg; return true; } diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp index 5ee58184f2..2ef3df56a1 100644 --- a/engines/groovie/script.cpp +++ b/engines/groovie/script.cpp @@ -102,6 +102,7 @@ Script::Script(GroovieEngine *vm, EngineVersion version) : _hotspotSlot = (uint16)-1; _oldInstruction = (uint16)-1; + _videoSkipAddress = 0; } Script::~Script() { @@ -235,8 +236,8 @@ void Script::step() { (this->*op)(); } -void Script::setMouseClick() { - _eventMouseClicked = true; +void Script::setMouseClick(uint8 button) { + _eventMouseClicked = button; } void Script::setKbdChar(uint8 c) { @@ -359,7 +360,7 @@ bool Script::hotspot(Common::Rect rect, uint16 address, uint8 cursor) { Common::isDebugChannelEnabled(kGroovieDebugAll)) { rect.translate(0, -80); _vm->_graphicsMan->_foreground.frameRect(rect, 250); - _vm->_system->copyRectToScreen((byte*)_vm->_graphicsMan->_foreground.getBasePtr(0, 0), 640, 0, 80, 640, 320); + _vm->_system->copyRectToScreen((byte*)_vm->_graphicsMan->_foreground.getBasePtr(0, 0), _vm->_graphicsMan->_foreground.pitch, 0, 80, 640, 320); _vm->_system->updateScreen(); } @@ -559,6 +560,21 @@ bool Script::playvideofromref(uint32 fileref) { } _bitflags = 0; + + // Reset the clicked mouse events + _eventMouseClicked = 0; + } + + // Check if the user wants to skip the video + if ((_eventMouseClicked == 2) && (_videoSkipAddress != 0)) { + // Jump to the given address + _currentInstruction = _videoSkipAddress; + + // Reset the skip address + _videoSkipAddress = 0; + + // End the playback + return true; } // Video available, play one frame @@ -573,7 +589,7 @@ bool Script::playvideofromref(uint32 fileref) { _videoRef = 0; // Clear the input events while playing the video - _eventMouseClicked = false; + _eventMouseClicked = 0; _eventKbdChar = 0; // Newline @@ -604,8 +620,8 @@ void Script::o_inputloopstart() { //0x0B _inputLoopAddress = _currentInstruction - 1; // Save the current mouse state for the whole loop - _mouseClicked = _eventMouseClicked; - _eventMouseClicked = false; + _mouseClicked = (_eventMouseClicked == 1); + _eventMouseClicked = 0; // Save the current pressed character for the whole loop _kbdChar = _eventKbdChar; @@ -1535,20 +1551,19 @@ void Script::o_stub59() { debugScript(1, true, "STUB59: 0x%04X 0x%02X", val1, val2); } -void Script::o2_playsong(){ +void Script::o2_playsong() { uint32 fileref = readScript32bits(); debugScript(1, true, "PlaySong(0x%08X): Play xmidi file", fileref); _vm->_musicPlayer->playSong(fileref); - } -void Script::o2_setbackgroundsong(){ +void Script::o2_setbackgroundsong() { uint32 fileref = readScript32bits(); debugScript(1, true, "SetBackgroundSong(0x%08X)", fileref); _vm->_musicPlayer->setBackgroundSong(fileref); } -void Script::o2_videofromref(){ +void Script::o2_videofromref() { uint32 fileref = readScript32bits(); // Show the debug information just when starting the playback @@ -1556,6 +1571,7 @@ void Script::o2_videofromref(){ debugScript(1, true, "VIDEOFROMREF(0x%08X) (Not fully imp): Play video file from ref", fileref); debugC(5, kGroovieDebugVideo | kGroovieDebugAll, "Playing video 0x%08X via 0x09", fileref); } + // Play the video if (!playvideofromref(fileref)) { // Move _currentInstruction back @@ -1563,7 +1579,7 @@ void Script::o2_videofromref(){ } } -void Script::o2_vdxtransition(){ +void Script::o2_vdxtransition() { uint32 fileref = readScript32bits(); // Show the debug information just when starting the playback @@ -1587,11 +1603,21 @@ void Script::o2_vdxtransition(){ } } -void Script::o2_stub52(){ +void Script::o2_setvideoskip() { + _videoSkipAddress = readScript16bits(); + debugScript(1, true, "SetVideoSkip (0x%04X)", _videoSkipAddress); +} + +void Script::o2_stub52() { uint8 arg = readScript8bits(); debugScript(1, true, "STUB52 (0x%02X)", arg); } +void Script::o2_setscriptend() { + uint16 arg = readScript16bits(); + debugScript(1, true, "SetScriptEnd (0x%04X)", arg); +} + Script::OpcodeFunc Script::_opcodesT7G[NUM_OPCODES] = { &Script::o_nop, // 0x00 &Script::o_nop, @@ -1692,11 +1718,11 @@ Script::OpcodeFunc Script::_opcodesV2[NUM_OPCODES] = { &Script::o_invalid, // 0x00 &Script::o_nop, &Script::o2_playsong, - &Script::o_bf9on, - &Script::o_palfadeout, // 0x04 - &Script::o_bf8on, - &Script::o_bf6on, - &Script::o_bf7on, + &Script::o_nop, + &Script::o_nop, // 0x04 + &Script::o_nop, + &Script::o_nop, + &Script::o_nop, &Script::o2_setbackgroundsong, // 0x08 &Script::o2_videofromref, &Script::o_bf5on, @@ -1719,7 +1745,7 @@ Script::OpcodeFunc Script::_opcodesV2[NUM_OPCODES] = { &Script::o_xor_obfuscate, &Script::o2_vdxtransition, // 0x1C &Script::o_swap, - &Script::o_nop8, + &Script::o_invalid, &Script::o_inc, &Script::o_dec, // 0x20 &Script::o_strcmpnejmp_var, @@ -1729,10 +1755,10 @@ Script::OpcodeFunc Script::_opcodesV2[NUM_OPCODES] = { &Script::o_add, &Script::o_videofromstring1, &Script::o_videofromstring2, - &Script::o_nop16, // 0x28 - &Script::o_stopmidi, - &Script::o_endscript, + &Script::o_invalid, // 0x28 &Script::o_nop, + &Script::o_endscript, + &Script::o_invalid, &Script::o_sethotspottop, // 0x2C &Script::o_sethotspotbottom, &Script::o_loadgame, @@ -1759,22 +1785,22 @@ Script::OpcodeFunc Script::_opcodesV2[NUM_OPCODES] = { &Script::o_returnscript, &Script::o_sethotspotright, // 0x44 &Script::o_sethotspotleft, - &Script::o_nop, - &Script::o_nop, - &Script::o_nop8, // 0x48 - &Script::o_nop, - &Script::o_nop16, - &Script::o_nop8, - &Script::o_getcd, // 0x4C - &Script::o_playcd, + &Script::o_invalid, + &Script::o_invalid, + &Script::o_invalid, // 0x48 + &Script::o_invalid, &Script::o_nop16, + &Script::o_invalid, + &Script::o_invalid, // 0x4C + &Script::o_invalid, + &Script::o_invalid, &Script::o_nop16, &Script::o_nop16, // 0x50 - &Script::o_nop16, + &Script::o2_setvideoskip, &Script::o2_stub52, &Script::o_hotspot_outrect, - &Script::o_nop, // 0x54 - &Script::o_nop16, + &Script::o_invalid, // 0x54 + &Script::o2_setscriptend, &Script::o_stub56, &Script::o_invalid, &Script::o_invalid, // 0x58 diff --git a/engines/groovie/script.h b/engines/groovie/script.h index e9e0be69ec..9e35d6fcde 100644 --- a/engines/groovie/script.h +++ b/engines/groovie/script.h @@ -58,7 +58,7 @@ public: void directGameLoad(int slot); void step(); - void setMouseClick(); + void setMouseClick(uint8 button); void setKbdChar(uint8 c); Common::String &getContext(); @@ -96,7 +96,7 @@ private: // Input bool _mouseClicked; - bool _eventMouseClicked; + uint8 _eventMouseClicked; uint8 _kbdChar; uint8 _eventKbdChar; uint16 _inputLoopAddress; @@ -115,6 +115,7 @@ private: Common::SeekableReadStream *_videoFile; uint32 _videoRef; uint16 _bitflags; + uint16 _videoSkipAddress; // Debugging Debugger *_debugger; @@ -228,7 +229,9 @@ private: void o2_setbackgroundsong(); void o2_videofromref(); void o2_vdxtransition(); + void o2_setvideoskip(); void o2_stub52(); + void o2_setscriptend(); }; } // End of Groovie namespace |