aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Thomas2009-08-21 13:57:03 +0000
committerScott Thomas2009-08-21 13:57:03 +0000
commit58f8ec5d5789375b6f7f1b2b84748fc6256e8e54 (patch)
tree7fbc635e4febb062f2726de3de7f1017e4f79308
parentaad7d1536f867b1335ea1aa389ccc29d4d073f64 (diff)
downloadscummvm-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.cpp4
-rw-r--r--engines/groovie/groovie.cpp22
-rw-r--r--engines/groovie/groovie.h2
-rw-r--r--engines/groovie/roq.cpp162
-rw-r--r--engines/groovie/script.cpp90
-rw-r--r--engines/groovie/script.h7
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