From 4293bd59a6882b872fbdd2606f01c565b50c7846 Mon Sep 17 00:00:00 2001 From: Pawel Kolodziejski Date: Sat, 27 Jun 2009 19:37:57 +0000 Subject: [PATCH] * disable imuse for now in gf demo * initial smush support for gf demo --- dists/msvc8/grim.vcproj | 8 ++ dists/msvc9/grim.vcproj | 8 ++ engines/grim/grim.cpp | 3 + engines/grim/imuse/imuse_sndmgr.cpp | 4 + engines/grim/lua_v1.cpp | 3 - engines/grim/smush/module.mk | 1 + engines/grim/smush/smush.cpp | 142 ++++++++++++++++++++++++++-- engines/grim/smush/smush.h | 10 ++ 8 files changed, 166 insertions(+), 13 deletions(-) diff --git a/dists/msvc8/grim.vcproj b/dists/msvc8/grim.vcproj index 5d32680db2f..4d080ad8bf5 100644 --- a/dists/msvc8/grim.vcproj +++ b/dists/msvc8/grim.vcproj @@ -421,6 +421,14 @@ RelativePath="..\..\engines\grim\smush\blocky16.h" > + + + + diff --git a/dists/msvc9/grim.vcproj b/dists/msvc9/grim.vcproj index fb0bce27a6a..26a489e101e 100644 --- a/dists/msvc9/grim.vcproj +++ b/dists/msvc9/grim.vcproj @@ -422,6 +422,14 @@ RelativePath="..\..\engines\grim\smush\blocky16.h" > + + + + diff --git a/engines/grim/grim.cpp b/engines/grim/grim.cpp index 01422fc3376..9be8a26267a 100644 --- a/engines/grim/grim.cpp +++ b/engines/grim/grim.cpp @@ -352,6 +352,9 @@ Common::Error GrimEngine::run() { error("gfx backend doesn't support hardware rendering"); #endif + if (g_grim->getGameFlags() & GF_DEMO) + Common::File::addDefaultDirectory(_gameDataDir.getChild("Movies")); + g_driver->setupScreen(640, 480, fullscreen); Bitmap *splash_bm = NULL; diff --git a/engines/grim/imuse/imuse_sndmgr.cpp b/engines/grim/imuse/imuse_sndmgr.cpp index c49d43ff865..f5cdd3cf9d3 100644 --- a/engines/grim/imuse/imuse_sndmgr.cpp +++ b/engines/grim/imuse/imuse_sndmgr.cpp @@ -25,6 +25,7 @@ #include "common/endian.h" +#include "engines/grim/grim.h" #include "engines/grim/resource.h" #include "engines/grim/imuse/imuse_sndmgr.h" @@ -162,6 +163,9 @@ ImuseSndMgr::SoundDesc *ImuseSndMgr::openSound(const char *soundName, int volGro byte *ptr = NULL; int headerSize = 0; + if (g_grim->getGameFlags() & GF_DEMO) + return FALSE; + SoundDesc *sound = allocSlot(); if (!sound) { error("ImuseSndMgr::openSound() Can't alloc free sound slot"); diff --git a/engines/grim/lua_v1.cpp b/engines/grim/lua_v1.cpp index 80b3ce5fdb8..73bc120e975 100644 --- a/engines/grim/lua_v1.cpp +++ b/engines/grim/lua_v1.cpp @@ -3013,9 +3013,6 @@ static void GetSpeechMode() { static void StartFullscreenMovie() { bool looping = getbool(2); - // don't start smush for GF demo for now - if (g_grim->getGameFlags() & GF_DEMO) - return; lua_Object name = lua_getparam(1); if (!lua_isstring(name)) { lua_pushnil(); diff --git a/engines/grim/smush/module.mk b/engines/grim/smush/module.mk index 38d0fbecdbd..f04829d883c 100644 --- a/engines/grim/smush/module.mk +++ b/engines/grim/smush/module.mk @@ -1,6 +1,7 @@ MODULE := engines/grim/smush MODULE_OBJS := \ + blocky8.o \ blocky16.o \ smush.o \ vima.o diff --git a/engines/grim/smush/smush.cpp b/engines/grim/smush/smush.cpp index a8222bd99b8..4ace743cded 100644 --- a/engines/grim/smush/smush.cpp +++ b/engines/grim/smush/smush.cpp @@ -41,7 +41,10 @@ Smush *g_smush; static uint16 smushDestTable[5786]; void Smush::timerCallback(void *) { - g_smush->handleFrame(); + if (g_grim->getGameFlags() & GF_DEMO) + g_smush->handleFrameDemo(); + else + g_smush->handleFrame(); } Smush::Smush() { @@ -79,10 +82,15 @@ void Smush::init() { assert(!_internalBuffer); assert(!_externalBuffer); - _internalBuffer = new byte[_width * _height * 2]; - _externalBuffer = new byte[_width * _height * 2]; + if (g_grim->getGameFlags() & GF_DEMO) { + _internalBuffer = new byte[_width * _height]; + _externalBuffer = new byte[_width * _height * 2]; + } else { + _internalBuffer = new byte[_width * _height * 2]; + _externalBuffer = new byte[_width * _height * 2]; + vimaInit(smushDestTable); + } - vimaInit(smushDestTable); g_system->getTimerManager()->installTimerProc(&timerCallback, _speed, NULL); } @@ -110,7 +118,10 @@ void Smush::deinit() { _videoLooping = false; _videoFinished = true; _videoPause = true; - _file.close(); + if (g_grim->getGameFlags() & GF_DEMO) + _f.close(); + else + _file.close(); } void Smush::handleWave(const byte *src, uint32 size) { @@ -224,6 +235,70 @@ void Smush::handleFrame() { } } +static byte delta_color(byte org_color, int16 delta_color) { + int t = (org_color * 129 + delta_color) / 128; + return CLIP(t, 0, 255); +} + +void Smush::handleDeltaPalette(byte *src, int32 size) { + if (size == 0x300 * 3 + 4) { + for (int i = 0; i < 0x300; i++) + _deltaPal[i] = READ_LE_UINT16(src + (i * 2) + 4); + memcpy(_pal, src + 0x600 + 4, 0x300); + } else if (size == 6) { + for (int i = 0; i < 0x300; i++) + _pal[i] = delta_color(_pal[i], _deltaPal[i]); + } else { + error("Smush::handleDeltaPalette() Wrong size for DeltaPalette"); + } +} + +void Smush::handleFrameDemo() { + uint32 tag; + int32 size; + int pos = 0; + + if (_videoPause) + return; + + if (_videoFinished) { + _videoPause = true; + return; + } + + tag = _f.readUint32BE(); + assert(tag == MKID_BE('FRME')); + size = _f.readUint32BE(); + byte *frame = new byte[size]; + _f.read(frame, size); + + do { + if (READ_BE_UINT32(frame + pos) == MKID_BE('FOBJ')) { + _blocky8.decode(_internalBuffer, frame + pos + 8 + 14); + pos += READ_BE_UINT32(frame + pos + 4) + 8; + } else if (READ_BE_UINT32(frame + pos) == MKID_BE('IACT')) { + pos += READ_BE_UINT32(frame + pos + 4) + 8; + } else if (READ_BE_UINT32(frame + pos) == MKID_BE('XPAL')) { + handleDeltaPalette(frame + pos + 8, READ_BE_UINT32(frame + pos + 4)); + pos += READ_BE_UINT32(frame + pos + 4) + 8; + } else { + error("Smush::handleFrame() unknown tag"); + } + } while (pos < size); + delete[] frame; + + memcpy(_externalBuffer, _internalBuffer, _width * _height); + _updateNeeded = true; + + _frame++; + _movieTime += _speed / 1000; + if (_frame == _nbframes) { + _videoFinished = true; + g_grim->setMode(ENGINE_MODE_NORMAL); + return; + } +} + void Smush::handleFramesHeader() { uint32 tag; int32 size; @@ -249,6 +324,47 @@ void Smush::handleFramesHeader() { delete[] f_header; } +bool Smush::setupAnimDemo(const char *file) { + uint32 tag; + int32 size; + + if (!_f.open(file)) + return false; + + tag = _f.readUint32BE(); + assert(tag == MKID_BE('ANIM')); + size = _f.readUint32BE(); + + tag = _f.readUint32BE(); + assert(tag == MKID_BE('AHDR')); + size = _f.readUint32BE(); + + _f.readUint16BE(); // version + _nbframes = _f.readUint16LE(); + _f.readUint16BE(); // unknown + + for (int l = 0; l < 0x300; l++) { + _pal[l] = _f.readByte(); + } + _f.readUint32BE(); + _f.readUint32BE(); + _f.readUint32BE(); + _f.readUint32BE(); + _f.readUint32BE(); + + _blocky8.init(640, 480); + + _x = 0; + _y = 0; + _width = 640; + _height = 480; + _videoLooping = false; + _startPos = NULL; + _speed = 66667; + + return true; +} + bool Smush::setupAnim(const char *file, bool looping, int x, int y) { uint32 tag; int32 size; @@ -259,11 +375,11 @@ bool Smush::setupAnim(const char *file, bool looping, int x, int y) { tag = _file.readUint32BE(); assert(tag == MKID_BE('SANM')); - size = _file.readUint32BE(); + _nbframes = _file.readUint32BE(); + tag = _file.readUint32BE(); assert(tag == MKID_BE('SHDR')); - size = _file.readUint32BE(); byte *s_header = new byte[size]; _file.read(s_header, size); @@ -316,10 +432,16 @@ bool Smush::play(const char *filename, bool looping, int x, int y) { printf("Playing video '%s'.\n", filename); // Load the video - if (!setupAnim(filename, looping, x, y)) - return false; + if (g_grim->getGameFlags() & GF_DEMO) { + if (!setupAnimDemo(filename)) + return false; + } else { + if (!setupAnim(filename, looping, x, y)) + return false; + + handleFramesHeader(); + } - handleFramesHeader(); if (_videoLooping) _startPos = _file.getPos(); init(); diff --git a/engines/grim/smush/smush.h b/engines/grim/smush/smush.h index 1dda4444112..f78077a3b45 100644 --- a/engines/grim/smush/smush.h +++ b/engines/grim/smush/smush.h @@ -32,6 +32,9 @@ #include #endif +#include "common/file.h" + +#include "engines/grim/smush/blocky8.h" #include "engines/grim/smush/blocky16.h" #include "sound/mixer.h" @@ -72,8 +75,10 @@ public: class Smush { private: int32 _nbframes; + Blocky8 _blocky8; Blocky16 _blocky16; zlibFile _file; + Common::File _f; Audio::SoundHandle _soundHandle; Audio::AppendableAudioStream *_stream; @@ -90,6 +95,8 @@ private: int _x, _y; int _width, _height; byte *_internalBuffer, *_externalBuffer; + byte _pal[0x300]; + int16 _deltaPal[0x300]; public: Smush(); @@ -112,13 +119,16 @@ public: private: static void timerCallback(void *ptr); void parseNextFrame(); + void handleDeltaPalette(byte *src, int32 size); void handleFramesHeader(); + void handleFrameDemo(); void handleFrame(); void handleBlocky16(byte *src); void handleWave(const byte *src, uint32 size); void init(); void deinit(); bool setupAnim(const char *file, bool looping, int x, int y); + bool setupAnimDemo(const char *file); void updateGLScreen(); };