diff options
author | Gregory Montoir | 2005-08-19 22:12:09 +0000 |
---|---|---|
committer | Gregory Montoir | 2005-08-19 22:12:09 +0000 |
commit | 24265fd3dd1681835f63e3c901158adef1ec5bc5 (patch) | |
tree | 36a28654b271ca5d8f12006f95f4990deaf371f8 /kyra | |
parent | ed2a18569a68d5be78d5a893d66979eef9fe06cd (diff) | |
download | scummvm-rg350-24265fd3dd1681835f63e3c901158adef1ec5bc5.tar.gz scummvm-rg350-24265fd3dd1681835f63e3c901158adef1ec5bc5.tar.bz2 scummvm-rg350-24265fd3dd1681835f63e3c901158adef1ec5bc5.zip |
some WIP code to start introduction (with glitches) in Kyrandia 1 :
- the decoders have been rewritten due to crashes I encountered with the previous ones in Compression::
- the wsa code loader for v1 have been rewritten too, to handle the same flags as the original
- some cleanup
- this has only been tested with the floppy version
svn-id: r18704
Diffstat (limited to 'kyra')
-rw-r--r-- | kyra/codecs.cpp | 260 | ||||
-rw-r--r-- | kyra/codecs.h | 43 | ||||
-rw-r--r-- | kyra/cpsimage.cpp | 26 | ||||
-rw-r--r-- | kyra/font.cpp | 2 | ||||
-rw-r--r-- | kyra/kyra.cpp | 700 | ||||
-rw-r--r-- | kyra/kyra.h | 114 | ||||
-rw-r--r-- | kyra/module.mk | 3 | ||||
-rw-r--r-- | kyra/palette.cpp | 33 | ||||
-rw-r--r-- | kyra/resource.cpp | 45 | ||||
-rw-r--r-- | kyra/resource.h | 23 | ||||
-rw-r--r-- | kyra/screen.cpp | 393 | ||||
-rw-r--r-- | kyra/screen.h | 88 | ||||
-rw-r--r-- | kyra/script.cpp | 7 | ||||
-rw-r--r-- | kyra/script_v1.cpp | 1 | ||||
-rw-r--r-- | kyra/sound.cpp | 261 | ||||
-rw-r--r-- | kyra/staticres.cpp | 368 | ||||
-rw-r--r-- | kyra/wsamovie.cpp | 533 | ||||
-rw-r--r-- | kyra/wsamovie.h | 115 |
18 files changed, 1828 insertions, 1187 deletions
diff --git a/kyra/codecs.cpp b/kyra/codecs.cpp deleted file mode 100644 index 1853fc85b4..0000000000 --- a/kyra/codecs.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2005 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * $Header$ - * - */ - -#include "common/stdafx.h" -#include "kyra/codecs.h" - -/***************************************************************************** - * decode.c - Decoding routines for format80, format40, format20 - * and format3 type graphics - * Author: Olaf van der spek - * Modified for FreeCNC by Kareem Dana - * Modified for Kyra by Jack Burton - * Format3 decoding added by Jack Burton - * Modified for ScummVM by Johannes Schickel - ****************************************************************************/ - -namespace Kyra { - -/** decompress format 80 compressed data. - * @param image_in compressed data. - * @param image_out pointer to output uncompressed data. - * @returns size of uncompressed data. - */ -int Compression::decode80(const uint8* image_in, uint8* image_out) { - /* - 0 copy 0cccpppp p - 1 copy 10cccccc - 2 copy 11cccccc p p - 3 fill 11111110 c c v - 4 copy 11111111 c c p p - */ - - const uint8* copyp; - const uint8* readp = image_in; - uint8* writep = image_out; - uint16 code; - uint16 count; - - while (1) { - code = *readp++; - if (~code & 0x80) { - //bit 7 = 0 - //command 0 (0cccpppp p): copy - count = (code >> 4) + 3; - copyp = writep - (((code & 0xf) << 8) + *readp++); - while (count--) - *writep++ = *copyp++; - } else { - //bit 7 = 1 - count = code & 0x3f; - if (~code & 0x40) { - //bit 6 = 0 - if (!count) - //end of image - break; - //command 1 (10cccccc): copy - while (count--) - *writep++ = *readp++; - } else { - //bit 6 = 1 - if (count < 0x3e) { - //command 2 (11cccccc p p): copy - count += 3; - - copyp = (const uint8*)&image_out[READ_LE_UINT16(readp)]; - readp += 2; - - // FIXME: Using memmove sometimes segfaults - // (reproducably for Ender), which suggests something Bad here - //memmove(writep, copyp, count); - //writep += count; - //copyp += count; - while (count--) - *writep++ = *copyp++; - } else if (count == 0x3e) { - //command 3 (11111110 c c v): fill - - count = READ_LE_UINT16(readp); - readp += 2; - code = *readp++; - memset(writep, code, count); - writep += count; - } else { - //command 4 (copy 11111111 c c p p): copy - - count = READ_LE_UINT16(readp); - readp += 2; - - copyp = (const uint8*)&image_out[READ_LE_UINT16(readp)]; - readp += 2; - while (count--) - *writep++ = *copyp++; - } - } - } - } - - return (writep - image_out); -} - -/** decompress format 40 compressed data. - * @param image_in compressed data. - * @param image_out pointer to put uncompressed data in. - * @returns size of uncompressed data. - */ -int Compression::decode40(const uint8* image_in, uint8* image_out) { - /* - 0 fill 00000000 c v - 1 copy 0ccccccc - 2 skip 10000000 c 0ccccccc - 3 copy 10000000 c 10cccccc - 4 fill 10000000 c 11cccccc v - 5 skip 1ccccccc - */ - - const uint8* readp = image_in; - uint8* writep = image_out; - uint16 code; - uint16 count; - - while (1) { - code = *readp++; - if (~code & 0x80) { - //bit 7 = 0 - if (!code) { - //command 0 (00000000 c v): fill - count = *readp++; - code = *readp++; - while (count--) - *writep++ ^= code; - } else { - //command 1 (0ccccccc): copy - count = code; - while (count--) - *writep++ ^= *readp++; - } - - } else { - //bit 7 = 1 - if (!(count = code & 0x7f)) { - - count = READ_LE_UINT16(readp); - readp += 2; - code = count >> 8; - if (~code & 0x80) { - //bit 7 = 0 - //command 2 (10000000 c 0ccccccc): skip - if (!count) - // end of image - break; - writep += count; - } else { - //bit 7 = 1 - count &= 0x3fff; - if (~code & 0x40) { - //bit 6 = 0 - //command 3 (10000000 c 10cccccc): copy - while (count--) - *writep++ ^= *readp++; - } else { - //bit 6 = 1 - //command 4 (10000000 c 11cccccc v): fill - code = *readp++; - while (count--) - *writep++ ^= code; - } - } - } else //command 5 (1ccccccc): skip - writep += count; - } - } - return (writep - image_out); -} - -/** decompress format 3 compressed data. - * @param image_in compressed data. - * @param image_out pointer to put uncompressed data in. - * @param size of uncompressed image. - */ -int Compression::decode3(const uint8* image_in, uint8* image_out, int size) { - /* Untested on BIG-Endian machines */ - - /* - 0 copy - 1 fill - 2 fill - */ - const uint8* readp = image_in; - uint8* writep = image_out; - int16 code; - int16 count; - - do { - code = *const_cast<int8*>((const int8*)readp++); - if (code > 0) { // Copy - count = code ; - while (count--) - *writep++ = *readp++; - } else if (code == 0) { // Fill(1) - count = READ_BE_UINT16(readp); - - readp += 2; - code = *readp++; - while (count--) - *writep++ = (uint8)code; - } else if (code < 0) { // Fill (2) - count = -code; - code = *readp++; - while (count--) - *writep++ = (uint8)code; - } - } while ((writep - image_out) < size); - - //and, to be uniform to other decomp. functions... - return (writep - image_out); -} - -/** decompress format 20 compressed data. - * @param s compressed data. - * @param d pointer to pu uncompressed data in. - * @param cb_s size of compressed data? - * @returns size of uncompressed data? - */ -int Compression::decode2(const uint8* s, uint8* d, int cb_s) { - const uint8* r = s; - const uint8* r_end = s + cb_s; - uint8* w = d; - while (r < r_end) { - int v = *r++; - if (v) - *w++ = v; - else { - v = *r++; - memset(w, 0, v); - w += v; - } - } - return w - d; - -} -} // end of namespace Kyra - diff --git a/kyra/codecs.h b/kyra/codecs.h deleted file mode 100644 index cb0cb13f74..0000000000 --- a/kyra/codecs.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2005 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * $Header$ - * - */ - -/* Various decompression routines */ -#ifndef CODECS_H -#define CODECS_H - -// THIS CODE WAS TAKEN FROM FreeKyra Tools Module - -#include "common/stdafx.h" -#include "common/scummsys.h" - -namespace Kyra { -class Compression -{ -public: - static int decode80(const uint8* image_in, uint8* image_out); - static int decode40(const uint8* image_in, uint8* image_out); - static int decode3(const uint8* image_in, uint8* image_out, int s); - static int decode2(const uint8* s, uint8* d, int cb_s); -}; -} // end of namespace Kyra - -#endif - diff --git a/kyra/cpsimage.cpp b/kyra/cpsimage.cpp index 3e72d7d52e..db4df6ea1b 100644 --- a/kyra/cpsimage.cpp +++ b/kyra/cpsimage.cpp @@ -20,10 +20,9 @@ */ #include "common/stdafx.h" -#include "kyra/resource.h" -#include "kyra/codecs.h" - #include "common/stream.h" +#include "kyra/resource.h" +#include "kyra/screen.h" namespace Kyra { @@ -78,13 +77,18 @@ CPSImage::CPSImage(uint8* buffer, uint32 size) { uint8* imagebuffer = &buffer[bufferstream.pos()]; assert(imagebuffer); - - if (_cpsHeader._format == 4) { - Compression::decode80(imagebuffer, _image); - } else if (_cpsHeader._format == 3) { - Compression::decode3(imagebuffer, _image, _cpsHeader._imagesize); - } else { - error("unknown CPS format %d", _cpsHeader._format); + switch (_cpsHeader._format) { + case 0: + memcpy(_image, imagebuffer, _cpsHeader._imagesize); + break; + case 3: + Screen::decodeFrame3(imagebuffer, _image, _cpsHeader._imagesize); + break; + case 4: + Screen::decodeFrame4(imagebuffer, _image, _cpsHeader._imagesize); + break; + default: + break; } int16 width = getWidthFromCPSRes(_cpsHeader._imagesize); @@ -181,5 +185,5 @@ void CPSImage::drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, } } } -} // end of namespace Kyra +} // end of namespace Kyra diff --git a/kyra/font.cpp b/kyra/font.cpp index a4d4ded4dd..45c57198c4 100644 --- a/kyra/font.cpp +++ b/kyra/font.cpp @@ -20,9 +20,9 @@ */ #include "common/stdafx.h" -#include "kyra/resource.h" #include "common/stream.h" #include "common/array.h" +#include "kyra/resource.h" #ifdef DUMP_FILES #include <cstdio> diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp index b73d102b93..39741a961c 100644 --- a/kyra/kyra.cpp +++ b/kyra/kyra.cpp @@ -21,21 +21,26 @@ #include "common/stdafx.h" -#include "common/system.h" +#include "backends/fs/fs.h" + #include "base/gameDetector.h" #include "base/plugins.h" -#include "backends/fs/fs.h" -#include "sound/mixer.h" -#include "common/file.h" #include "common/config-manager.h" +#include "common/file.h" +#include "common/system.h" + +#include "sound/mixer.h" #include "sound/mididrv.h" #include "kyra/kyra.h" #include "kyra/resource.h" +#include "kyra/screen.h" #include "kyra/script.h" -#include "kyra/wsamovie.h" #include "kyra/sound.h" +#include "kyra/wsamovie.h" + +using namespace Kyra; struct KyraGameSettings { const char *name; @@ -49,23 +54,21 @@ struct KyraGameSettings { }; static const KyraGameSettings kyra_settings[] = { - {"kyra1", "Legend of Kyrandia (Floppy)", GF_FLOPPY | GF_KYRA1, "INTRO.SND"}, - {"kyra1cd", "Legend of Kyrandia (CD)", GF_TALKIE | GF_KYRA1, "CHAPTER1.VRM"}, - {"kyra2", "Hand of Fate (Floppy)", GF_FLOPPY | GF_KYRA2, 0 }, - {"kyra2cd", "Hand of Fate (CD)", GF_TALKIE | GF_KYRA2, "AUDIO.PAK"}, - {"kyra3", "Malcolm's Revenge", GF_TALKIE | GF_KYRA3, "K3INTRO0.VQA"}, - {0, 0, 0, 0} + { "kyra1", "Legend of Kyrandia (Floppy)", GF_FLOPPY | GF_KYRA1, "INTRO.SND" }, + { "kyra1cd", "Legend of Kyrandia (CD)", GF_TALKIE | GF_KYRA1, "CHAPTER1.VRM" }, +// { "kyra2", "Hand of Fate (Floppy)", GF_FLOPPY | GF_KYRA2, 0 }, +// { "kyra2cd", "Hand of Fate (CD)", GF_TALKIE | GF_KYRA2, "AUDIO.PAK" }, +// { "kyra3", "Malcolm's Revenge", GF_TALKIE | GF_KYRA3, "K3INTRO0.VQA" }, + { 0, 0, 0, 0 } }; GameList Engine_KYRA_gameList() { GameList games; const KyraGameSettings *g = kyra_settings; - while (g->name) { games.push_back(g->toGameSettings()); g++; } - return games; } @@ -91,15 +94,16 @@ DetectedGameList Engine_KYRA_detectGames(const FSList &fslist) { return detectedGames; } -Engine *Engine_KYRA_create(GameDetector *detector, OSystem *syst) { - return new Kyra::KyraEngine(detector, syst); +Engine *Engine_KYRA_create(GameDetector *detector, OSystem *system) { + return new KyraEngine(detector, system); } REGISTER_PLUGIN(KYRA, "Legend of Kyrandia Engine") namespace Kyra { -KyraEngine::KyraEngine(GameDetector *detector, OSystem *syst) - : Engine(syst) { + +KyraEngine::KyraEngine(GameDetector *detector, OSystem *system) + : Engine(system) { // Setup mixer if (!_mixer->isReady()) { @@ -111,15 +115,17 @@ KyraEngine::KyraEngine(GameDetector *detector, OSystem *syst) // gets the game if (detector->_game.features & GF_KYRA1) { - if (detector->_game.features & GF_FLOPPY) + if (detector->_game.features & GF_FLOPPY) { _game = KYRA1; - else + } else { _game = KYRA1CD; + } } else if (detector->_game.features & GF_KYRA2) { - if (detector->_game.features & GF_FLOPPY) + if (detector->_game.features & GF_FLOPPY) { _game = KYRA2; - else + } else { _game = KYRA2CD; + } } else if (detector->_game.features & GF_KYRA3) { _game = KYRA3; } else { @@ -128,16 +134,11 @@ KyraEngine::KyraEngine(GameDetector *detector, OSystem *syst) } int KyraEngine::init(GameDetector &detector) { - - // Initialize backen _system->beginGFXTransaction(); initCommonGFX(detector); _system->initSize(320, 200); _system->endGFXTransaction(); - _screen = new uint8[320*200]; - memset(_screen, 0, sizeof(uint8) * 320 * 200); - int midiDrv = MidiDriver::detectMusicDriver(MDT_NATIVE | MDT_ADLIB | MDT_PREFER_NATIVE); bool native_mt32 = (ConfMan.getBool("native_mt32") || (midiDrv == MD_MT32)); @@ -146,49 +147,32 @@ int KyraEngine::init(GameDetector &detector) { // In this case we should play the Adlib tracks, but for now // the automagic MIDI-to-Adlib conversion will do. driver = MidiDriver_ADLIB_create(_mixer); - } else if (native_mt32) + } else if (native_mt32) { driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); + } - _midiDriver = new MusicPlayer(driver, this); - assert(_midiDriver); - _midiDriver->hasNativeMT32(native_mt32); - _midiDriver->setVolume(255); - - _resMgr = new Resourcemanager(this); - assert(_resMgr); - - setCurrentPalette(_resMgr->loadPalette("PALETTE.COL")); - - // loads the 2 cursors - _mouse = _resMgr->loadImage("MOUSE.CPS"); - _items = _resMgr->loadImage("ITEMS.CPS"); - - // loads the Font - _font = _resMgr->loadFont("8FAT.FNT"); - - _npcScript = _resMgr->loadScript("_NPC.EMC"); + _midi = new MusicPlayer(driver, this); + assert(_midi); + _midi->hasNativeMT32(native_mt32); + _midi->setVolume(255); - // loads the scripts (only Kyrandia 1) - if (_game == KYRA1 || _game == KYRA1CD) { - _currentScript = _resMgr->loadScript("_STARTUP.EMC"); - } else { - error("game start files not known"); - } + _res = new Resource(this); + assert(_res); + _screen = new Screen(this, _system); + assert(_screen); - assert(_npcScript); - assert(_currentScript); + _fastMode = false; + _talkCoords.y = 0x88; + _talkCoords.x = 0; + _talkCoords.w = 0; return 0; } KyraEngine::~KyraEngine() { - delete _resMgr; - delete[] _screen; - delete _mouse; - delete _items; - delete _npcScript; - delete _currentScript; - delete _font; + delete _screen; + delete _res; + delete _midi; } void KyraEngine::errorString(const char *buf1, char *buf2) { @@ -196,109 +180,543 @@ void KyraEngine::errorString(const char *buf1, char *buf2) { } int KyraEngine::go() { - warning("Kyrandia Engine ::go()"); - // starts the init script -/* if (!_currentScript->startScript(kSetupScene)) { - error("couldn't init '_STARTUP.EMC' script"); - } - - if (_currentScript->contScript() != kScriptStopped) { - if (_currentScript->state() == kScriptError) { - error("couldn't run script"); - } else { - warning("init script returned: %d", _currentScript->state()); - } - }*/ - - Movie* movie = _resMgr->loadMovie("MAL-KAL.WSA"); - assert(movie); - CPSImage* image = _resMgr->loadImage("GEMCUT.CPS"); - assert(image); - - int16 currentFrame = 0; - uint32 lastFrameChange = 0; - - image->transparency(0); - image->drawToPlane(_screen, 320, 200, 0, 0, 0, 0, 320, 136); - movie->setImageBackground(_screen, 320, 200); - movie->position(16, 58); - - setCurrentPalette(_resMgr->loadPalette("MAL-KAL.COL")); + _quitFlag = false; + seq_intro(); + return 0; +} - uint8* _buffer = new uint8[320 * 200]; - assert(_buffer); - memcpy(_buffer, _screen, 320 * 200); - movie->renderFrame(_buffer, 320, 200, movie->countFrames() - 1); +void KyraEngine::setTalkCoords(uint16 y) { + _talkCoords.y = y; +} - if (_midiDriver) { - _midiDriver->playMusic("KYRA2A.XMI"); - _midiDriver->playTrack(3); +void KyraEngine::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData) { + debug(9, "KyraEngine::copyBitmap('%s', %d, %d, 0x%X)", filename, tempPage, dstPage, palData); + uint32 fileSize; + uint8 *srcData = _res->fileData(filename, &fileSize); + uint8 compType = srcData[2]; + uint32 imgSize = READ_LE_UINT32(srcData + 4); + uint16 palSize = READ_LE_UINT16(srcData + 8); + if (palData && palSize) { + memcpy(palData, srcData + 10, palSize); } + srcData += 10 + palSize; + + uint8 *dstData = _screen->getPagePtr(dstPage); + switch (compType) { + case 0: + memcpy(dstData, srcData, imgSize); + break; + case 3: + Screen::decodeFrame3(srcData, dstData, imgSize); + break; + case 4: + Screen::decodeFrame4(srcData, dstData, imgSize); + break; + default: + error("Unhandled bitmap compression %d", compType); + break; + } + delete[] srcData; +} - while (true) { - OSystem::Event event; - //if (_debugger->isAttached()) - // _debugger->onFrame(); - - memcpy(_screen, _buffer, 320 * 200); - if (lastFrameChange + movie->frameChange() < _system->getMillis()) { - lastFrameChange = _system->getMillis(); - ++currentFrame; +void KyraEngine::restoreTalkTextMessageBkgd(int srcPage, int dstPage) { + debug(9, "KyraEngine::printTalkTextMessage(%d, %d)", srcPage, dstPage); + warning("KyraEngine::restoreTalkTextMessageBkgd() UNIMPLEMENTED"); +} - if (currentFrame >= (int16)movie->countFrames()) { - currentFrame = 0; - } - } +void KyraEngine::printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage) { + debug(9, "KyraEngine::printTalkTextMessage('%s', %d, %d, %d, %d, %d)", text, x, y, color, srcPage, dstPage); + warning("KyraEngine::printTalkTextMessage() UNIMPLEMENTED"); +} - movie->renderFrame(_screen, 320, 200, currentFrame); - _font->drawStringToPlane("This is only a test!", _screen, 320, 200, 75, 179, 136); - _font->drawStringToPlane("Nothing scripted!", _screen, 320, 200, 85, 189, 136); - updateScreen(); - while (g_system->pollEvent(event)) { +void KyraEngine::waitTicks(int ticks) { + debug(9, "KyraEngine::waitTicks(%d)", ticks); + const uint32 end = _system->getMillis() + ticks * 1000 / 60; + do { + OSystem::Event event; + while (_system->pollEvent(event)) { switch (event.type) { - case OSystem::EVENT_QUIT: - g_system->quit(); - break; - default: - break; + case OSystem::EVENT_QUIT: + _quitFlag = true; + break; + case OSystem::EVENT_KEYDOWN: + if (event.kbd.flags == OSystem::KBD_CTRL) { + if (event.kbd.keycode == 'f') { + _fastMode = !_fastMode; + } + } + break; + default: + break; } } _system->delayMillis(10); + } while (!_fastMode && _system->getMillis() < end); +} + +void KyraEngine::seq_intro() { + debug(9, "KyraEngine::seq_intro()"); + _skipIntroFlag = true; // only true if user already played the game once + _seq_copyViewOffs = 1; + +// snd_kyraPlayTheme(0); + setTalkCoords(0x90); + + memset(_screen->_palette1, 0, 768); + _screen->setScreenPalette(_screen->_palette1); + + seq_introLogos(); + if (!seq_skipSequence()) { +// loadBitmap("MAIN_ENG.CPS", 3, 3, 0); + _screen->clearPage(0); // XXX + if (!seq_skipSequence()) { + _screen->_curPage = 0; + _screen->clearPage(3); + seq_playSpecialSequence(_seq_introData_MalcomTree, true); + seq_makeHandShapes(); + uint8 *p = (uint8 *)malloc(5060); + _screen->setAnimBlockPtr(p, 5060); + _screen->_charWidth = -2; + _screen->clearPage(3); + seq_playSpecialSequence(_seq_introData_KallakWriting, true); + free(p); + seq_freeHandShapes(); + _screen->clearPage(3); + seq_playSpecialSequence(_seq_introData_KallakMalcom, true); + setTalkCoords(0x88); + waitTicks(0x1E); + _seq_copyViewOffs = 0; + } } +} - delete movie; - delete image; - delete [] _buffer; +void KyraEngine::seq_introLogos() { + debug(9, "KyraEngine::seq_introLogos()"); + _screen->clearPage(0); + loadBitmap("TOP.CPS", 7, 7, _screen->_palette1); + loadBitmap("BOTTOM.CPS", 5, 5, _screen->_palette1); + _screen->_curPage = 0; + _screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0); + _screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0); + _screen->fadeFromBlack(); + + if (seq_playSpecialSequence(_seq_introData_WestwoodLogo, _skipIntroFlag)) { + _screen->fadeToBlack(); + _screen->clearPage(0); + return; + } + waitTicks(60); + if (seq_playSpecialSequence(_seq_introData_KyrandiaLogo, _skipIntroFlag)) { + _screen->fadeToBlack(); + _screen->clearPage(0); + return; + } + _screen->fillRect(0, 179, 319, 199, 0); + + int y1 = 8; + int h1 = 175; + int y2 = 176; + int h2 = 0; + _screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 2); + _screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 2); + do { + if (h1 > 0) { + _screen->copyRegion(0, y1, 0, 8, 320, h1, 2, 0); + } + ++y1; + --h1; + if (h2 > 0) { + _screen->copyRegion(0, 64, 0, y2, 320, h2, 4, 0); + } + --y2; + ++h2; + _screen->updateScreen(); + waitTicks(1); + } while (y2 >= 64); - return 0; + seq_playSpecialSequence(_seq_introData_Forest, true); } -void KyraEngine::shutdown() { - _system->quit(); +uint8 *KyraEngine::seq_setPanPages(int pageNum, int shape) { + debug(9, "KyraEngine::seq_setPanPages(%d, %d)", pageNum, shape); + uint8 *panPage = 0; + const uint8 *data = _screen->getPagePtr(pageNum); + uint16 numShapes = READ_LE_UINT16(data); + if (shape < numShapes) { + uint16 offs = READ_LE_UINT16(data + 2 + shape * 2); + if (offs != 0) { + data += offs; + uint16 sz = READ_LE_UINT16(data + 6); + panPage = (uint8 *)malloc(sz); + if (panPage) { + memcpy(panPage, data, sz); + } + } + } + return panPage; } -void KyraEngine::updateScreen(void) { - _system->copyRectToScreen(_screen, 320, 0, 0, 320, 200); - _system->updateScreen(); +void KyraEngine::seq_makeHandShapes() { + debug(9, "KyraEngine::seq_makeHandShapes()"); + loadBitmap("WRITING.CPS", 3, 3, 0); + for (int i = 0; i < 3; ++i) { + _seq_handShapes[i] = seq_setPanPages(3, i); + } } -void KyraEngine::setCurrentPalette(Palette* pal, bool delNextTime) { - if (!pal) - return; - -// if (_delPalNextTime) -// delete _currentPal; - -// _delPalNextTime = delNextTime; - -// _currentPal = pal; +void KyraEngine::seq_freeHandShapes() { + debug(9, "KyraEngine::seq_freeHandShapes()"); + for (int i = 0; i < 3; ++i) { + free(_seq_handShapes[i]); + _seq_handShapes[i] = 0; + } +} - if (pal->getData()) { - _system->setPalette(pal->getData(), 0, 256); +void KyraEngine::seq_copyView() { + debug(9, "KyraEngine::seq_copyView()"); + int y = 128; + if (_seq_copyViewOffs == 0) { + y -= 8; + } + if (_seq_specialSequenceTempBuffer) { + _screen->copyToPage0(16, y, 3, _seq_specialSequenceTempBuffer); } else { - warning("palette contains no data"); + _screen->copyRegion(0, 16, 0, 16, 320, y, 2, 0); } } -} // End of namespace KYRA +bool KyraEngine::seq_skipSequence() const { + return _quitFlag; +} + +bool KyraEngine::seq_playSpecialSequence(const uint8 *seqData, bool skipSeq) { + debug(9, "KyraEngine::seq_playSpecialSequence(0x%X, %d)", seqData, skipSeq); + WSAMovieV1 *wsaMovieTable[12]; + uint32 displayedTextTimer = 0xFFFFFFFF; + bool displayTextFlag = false; + bool seqSkippedFlag = false; + uint16 displayedTextX = 0; + uint8 displayedText = 0; + uint8 displayedChar = 0; + int16 wsaCurFramesTable[12]; + uint16 wsaYPosTable[12]; + uint16 wsaXPosTable[12]; + bool talkTextRestored = false; + bool talkTextPrinted = false; + int16 wsaNumFramesTable[12]; + bool quitFlag = false; + uint16 wsaCurDecodePage = 0; + uint32 wsaDecodePage[12]; + SeqLoop seqLoopTable[20]; + + for (int i = 0; i < 20; ++i) { + seqLoopTable[i].ptr = 0; + seqLoopTable[i].count = 0xFFFF; + } + memset(wsaMovieTable, 0, sizeof(wsaMovieTable)); + _seq_specialSequenceTempBuffer = 0; + + _screen->_curPage = 0; + while (!quitFlag) { + if (skipSeq && seq_skipSequence()) { + while (1) { + uint8 code = *seqData; + if (code == 29 || code == 19) { + break; + } + seqData += _seq_codeSizeTable[code] + 1; + } + skipSeq = false; + seqSkippedFlag = true; + } + // used in Kallak writing intro + if (displayTextFlag && displayedTextTimer != 0xFFFFFFFF) { + if (displayedTextTimer < _system->getMillis()) { + char charStr[2]; + charStr[0] = _seq_textsTableEN[displayedText][displayedChar]; + charStr[1] = '\0'; + _screen->printText(charStr, displayedTextX, 180, 0xF, 0xC); + displayedTextX += _screen->getCharWidth(charStr[0]); + ++displayedChar; + if (_seq_textsTableEN[displayedText][displayedChar] == '\0') { + displayedTextTimer = 0xFFFFFFFF; + } + } else { + displayedTextTimer = _system->getMillis() + 1000 / 60; + } + } + uint8 seqCode = *seqData++; + debug(5, "seqCode = %d", seqCode); + switch (seqCode) { + case 0: { + uint8 wsaObj = *seqData++; + assert(wsaObj < 12); + uint8 offscreenDecode = *seqData++; + wsaCurDecodePage = wsaDecodePage[wsaObj] = (offscreenDecode == 0) ? 0 : 3; + wsaMovieTable[wsaObj] = wsa_open(_seq_WSATable[wsaObj], offscreenDecode, 0); + wsaCurFramesTable[wsaObj] = 0; + wsaNumFramesTable[wsaObj] = wsa_getNumFrames(wsaMovieTable[wsaObj]) - 1; + } + break; + case 1: { + uint8 wsaObj = *seqData++; + assert(wsaObj < 12); + if (wsaMovieTable[wsaObj]) { + wsa_close(wsaMovieTable[wsaObj]); + wsaMovieTable[wsaObj] = 0; + } + } + break; + case 2: { + uint8 wsaObj = *seqData++; + assert(wsaObj < 12); + int16 frame = (int8)*seqData++; + wsaXPosTable[wsaObj] = READ_LE_UINT16(seqData); seqData += 2; + wsaYPosTable[wsaObj] = *seqData++; + wsa_play(wsaMovieTable[wsaObj], frame, wsaXPosTable[wsaObj], wsaYPosTable[wsaObj], wsaDecodePage[wsaObj]); + wsaCurFramesTable[wsaObj] = frame; + } + break; + case 3: { + uint8 wsaObj = *seqData++; + assert(wsaObj < 12); + ++wsaCurFramesTable[wsaObj]; + int16 frame = wsaCurFramesTable[wsaObj]; + if (frame > wsaNumFramesTable[wsaObj]) { + frame = 0; + wsaCurFramesTable[wsaObj] = 0; + } + wsa_play(wsaMovieTable[wsaObj], frame, wsaXPosTable[wsaObj], wsaYPosTable[wsaObj], wsaDecodePage[wsaObj]); + } + break; + case 4: { + uint8 wsaObj = *seqData++; + assert(wsaObj < 12); + --wsaCurFramesTable[wsaObj]; + int16 frame = wsaCurFramesTable[wsaObj]; + if (wsaCurFramesTable[wsaObj] < 0) { + frame = wsaNumFramesTable[wsaObj]; + wsaCurFramesTable[wsaObj] = wsaNumFramesTable[wsaObj]; + } else { + wsa_play(wsaMovieTable[wsaObj], frame, wsaXPosTable[wsaObj], wsaYPosTable[wsaObj], wsaDecodePage[wsaObj]); + } + } + break; + case 5: { + uint8 shapeNum = *seqData++; + int x = READ_LE_UINT16(seqData); seqData += 2; + int y = *seqData++; + _screen->drawShape(2, _seq_handShapes[shapeNum], x, y, 0, 0, 0); + } + break; + case 6: + case 7: { + if (seqCode == 7) { + seq_copyView(); + } + uint16 ticks = READ_LE_UINT16(seqData); seqData += 2; + waitTicks(ticks); + } + break; + case 8: + warning("Sequence opcode 8 skipped"); + break; + case 9: + seq_copyView(); + break; + case 10: { + uint8 seqLoop = *seqData++; + if (seqLoop < 20) { + seqLoopTable[seqLoop].ptr = seqData; + } else { + quitFlag = true; + } + } + break; + case 11: { + uint8 seqLoop = *seqData++; + uint16 seqLoopCount = READ_LE_UINT16(seqData); seqData += 2; + if (seqLoopTable[seqLoop].count == 0xFFFF) { + seqLoopTable[seqLoop].count = seqLoopCount - 1; + seqData = seqLoopTable[seqLoop].ptr; + } else if (seqLoopTable[seqLoop].count == 0) { + seqLoopTable[seqLoop].count = 0xFFFF; + seqLoopTable[seqLoop].ptr = 0; + } else { + --seqLoopTable[seqLoop].count; + seqData = seqLoopTable[seqLoop].ptr; + } + } + break; + case 12: { + uint8 colNum = *seqData++; + uint32 fileSize; + uint8 *srcData = _res->fileData(_seq_COLTable[colNum], &fileSize); + memcpy(_screen->_palette1, srcData, fileSize); + delete[] srcData; + } + break; + case 13: { + uint8 cpsNum = *seqData++; + loadBitmap(_seq_CPSTable[cpsNum], 3, 3, 0); + } + break; + case 14: + _screen->fadeToBlack(); + break; + case 15: { + static const uint8 colorMap[] = { 0, 0, 0, 0, 12, 12, 12, 0, 0, 0, 0, 0 }; + uint8 txt = *seqData++; + _screen->fillRect(0, 180, 319, 195, 12); + _screen->setTextColorMap(colorMap); + if (!displayTextFlag) { + const char *str = _seq_textsTableEN[txt]; + int x = (Screen::SCREEN_W - _screen->getTextWidth(str)) / 2; + _screen->printText(str, x, 180, 0xF, 0xC); + } else { + displayedTextTimer = _system->getMillis() + 1000 / 60; + displayedText = txt; + displayedChar = 0; + const char *str = _seq_textsTableEN[displayedText]; + displayedTextX = (Screen::SCREEN_W - _screen->getTextWidth(str)) / 2; + } + } + warning("Sequence opcode 15 skipped"); + break; + case 16: { + uint8 txt = *seqData++; + int x = READ_LE_UINT16(seqData); seqData += 2; + int y = *seqData++; + uint8 fillColor = *seqData++; + int b; + if (talkTextPrinted && !talkTextRestored) { + if (!_seq_specialSequenceTempBuffer && wsaCurDecodePage != 0) { + b = 2; + } else { + b = 0; + } + restoreTalkTextMessageBkgd(2, b); + } + talkTextPrinted = true; + talkTextRestored = false; + if (!_seq_specialSequenceTempBuffer && wsaCurDecodePage != 0) { + b = 2; + } else { + b = 0; + } + printTalkTextMessage(_seq_textsTableEN[txt], x, y, fillColor, b, 2); + } + break; + case 17: + if (talkTextPrinted && !talkTextRestored) { + int b; + if (!_seq_specialSequenceTempBuffer && wsaCurDecodePage != 0) { + b = 2; + } else { + b = 0; + } + restoreTalkTextMessageBkgd(2, b); + talkTextRestored = true; + } + break; + case 18: + _screen->fillRect(10, 180, 319, 196, 0xC); + break; + case 19: + break; + case 20: + _screen->fadeFromBlack(); + break; + case 21: { + uint8 srcPage = *seqData++; + uint8 dstPage = *seqData++; + _screen->copyRegion(0, 0, 0, 0, 320, 200, srcPage, dstPage); + } + break; + case 22: { + uint8 so = *seqData++; + switch (so) { + case 0: + _screen->copyRegion(0, 0, 0, 47, 320, 77, 2, 0); + break; + case 1: + _screen->copyRegion(0, 0, 0, 47, 320, 56, 2, 0); + break; + case 2: + _screen->copyRegion(107, 72, 107, 72, 43, 87, 2, 0); + _screen->copyRegion(130, 159, 130, 159, 35, 17, 2, 0); + _screen->copyRegion(165, 105, 165, 105, 32, 9, 2, 0); + _screen->copyRegion(206, 83, 206, 83, 94, 93, 2, 0); + break; + case 3: + _screen->copyRegion(152, 56, 152, 56, 48, 48, 2, 0); + break; + case 4: { + static const uint8 colorMap[] = { 0, 0, 0, 0, 0, 12, 12, 0, 0, 0, 0, 0 }; + _screen->_charWidth = -2; + const char *copyStr = "Copyright (c) 1992 Westwood Studios"; + _screen->setTextColorMap(colorMap); + const int x = (Screen::SCREEN_W - _screen->getTextWidth(copyStr)) / 2; + const int y = 179; + _screen->printText(copyStr, x + 1, y + 1, 0xB, 0xC); + _screen->printText(copyStr, x, y, 0xF, 0xC); + } + break; + case 5: + _screen->_curPage = 2; + break; + default: + error("Invalid subopcode %d for sequence opcode 22", so); + break; + } + } + break; + case 23: { + int x1 = READ_LE_UINT16(seqData); seqData += 2; + int y1 = *seqData++; + int x2 = READ_LE_UINT16(seqData); seqData += 2; + int y2 = *seqData++; + uint8 color = *seqData++; + uint8 page = *seqData++; + _screen->fillRect(x1, y1, x2, y2, color, page); + } + break; + case 24: { // sound related + seqData++; + warning("Sequence opcode 24 skipped"); + } + break; + case 25: { // sound related + seqData++; + warning("Sequence opcode 25 skipped"); + } + break; + case 26: + if (!_seq_specialSequenceTempBuffer) { + _seq_specialSequenceTempBuffer = (uint8 *)malloc(320 * 128); + } + if (_seq_specialSequenceTempBuffer) { + memset(_seq_specialSequenceTempBuffer, 0, 320 * 128); + } + break; + case 27: + displayTextFlag = true; + break; + case 28: + displayTextFlag = false; + break; + case 29: + quitFlag = true; + break; + default: + error("Invalid sequence opcode %d", seqCode); + break; + } + _screen->updateScreen(); + } + free(_seq_specialSequenceTempBuffer); + _seq_specialSequenceTempBuffer = 0; + return seqSkippedFlag; +} +} // End of namespace Kyra diff --git a/kyra/kyra.h b/kyra/kyra.h index f3b67dd9d6..457b460bb1 100644 --- a/kyra/kyra.h +++ b/kyra/kyra.h @@ -22,65 +22,107 @@ #ifndef KYRA_H #define KYRA_H -//#include "common/scummsys.h" #include "base/engine.h" -#include "base/gameDetector.h" #include "common/util.h" +namespace Kyra { + enum { - GF_FLOPPY = 1 << 0, - GF_TALKIE = 1 << 1, - GF_KYRA1 = 1 << 2, - GF_KYRA2 = 1 << 3, - GF_KYRA3 = 1 << 4, - GF_AUDIOCD = 1 << 5 // FM-Towns versions seems to use audio CD + GF_FLOPPY = 1 << 0, + GF_TALKIE = 1 << 1, + GF_KYRA1 = 1 << 2, + GF_KYRA2 = 1 << 3, + GF_KYRA3 = 1 << 4, + GF_AUDIOCD = 1 << 5 // FM-Towns versions seems to use audio CD }; enum { - KYRA1 = 0, + KYRA1 = 0, KYRA1CD = 1, - KYRA2 = 2, + KYRA2 = 2, KYRA2CD = 3, - KYRA3 = 4 + KYRA3 = 4 }; -namespace Kyra { -class Resourcemanager; -class CPSImage; -class Font; -class Palette; -class VMContext; +struct TalkCoords { + uint16 y, x, w; +}; + +struct SeqLoop { + const uint8 *ptr; + uint16 count; +}; + +struct WSAMovieV1; + class MusicPlayer; +class Resource; +class Screen; class KyraEngine : public Engine { public: - KyraEngine(GameDetector *detector, OSystem *syst); - ~KyraEngine(); - void errorString( const char *buf_input, char *buf_output); - void updateScreen(void); - void setCurrentPalette(Palette* pal, bool delNextTime = true); + KyraEngine(GameDetector *detector, OSystem *system); + ~KyraEngine(); + + void errorString(const char *buf_input, char *buf_output); - Resourcemanager* resManager(void) { return _resMgr; } - MusicPlayer* midiDriver(void) { return _midiDriver; } + Resource *resource() { return _res; } + Screen *screen() { return _screen; } - uint8 game(void) { return _game; } + uint8 game() const { return _game; } protected: + int go(); int init(GameDetector &detector); - void shutdown(); - Resourcemanager* _resMgr; - MusicPlayer* _midiDriver; - uint8 *_screen; - uint8 _game; - - Font* _font; - CPSImage* _mouse; - CPSImage* _items; - VMContext* _currentScript; // our current script - VMContext* _npcScript; // script from NPCs + void setTalkCoords(uint16 y); + void loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData); + void restoreTalkTextMessageBkgd(int srcPage, int dstPage); + void printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage); + void waitTicks(int ticks); + + void seq_intro(); + void seq_introLogos(); + uint8 *seq_setPanPages(int pageNum, int shape); + void seq_makeHandShapes(); + void seq_freeHandShapes(); + void seq_copyView(); + bool seq_skipSequence() const; + bool seq_playSpecialSequence(const uint8 *seqData, bool skipSeq); + + WSAMovieV1 *wsa_open(const char *filename, int offscreenDecode, uint8 *palBuf); + void wsa_close(WSAMovieV1 *wsa); + uint16 wsa_getNumFrames(WSAMovieV1 *wsa) const; + void wsa_play(WSAMovieV1 *wsa, int frameNum, int x, int y, int pageNum); + void wsa_processFrame(WSAMovieV1 *wsa, int frameNum, uint8 *dst); + + uint8 _game; + bool _fastMode; + bool _quitFlag; + bool _skipIntroFlag; + TalkCoords _talkCoords; + + int _seq_copyViewOffs; + uint8 *_seq_handShapes[3]; + uint8 *_seq_specialSequenceTempBuffer; + + MusicPlayer *_midi; + Resource *_res; + Screen *_screen; + + static const uint8 _seq_introData_Forest[]; + static const uint8 _seq_introData_KallakWriting[]; + static const uint8 _seq_introData_KyrandiaLogo[]; + static const uint8 _seq_introData_KallakMalcom[]; + static const uint8 _seq_introData_MalcomTree[]; + static const uint8 _seq_introData_WestwoodLogo[]; + static const uint8 _seq_codeSizeTable[]; + static const char *_seq_WSATable[]; + static const char *_seq_CPSTable[]; + static const char *_seq_COLTable[]; + static const char *_seq_textsTableEN[]; }; } // End of namespace Kyra diff --git a/kyra/module.mk b/kyra/module.mk index 1026f29468..96b84702ad 100644 --- a/kyra/module.mk +++ b/kyra/module.mk @@ -1,15 +1,16 @@ MODULE := kyra MODULE_OBJS := \ - kyra/codecs.o \ kyra/cpsimage.o \ kyra/font.o \ kyra/kyra.o \ kyra/palette.o \ kyra/resource.o \ + kyra/screen.o \ kyra/script_v1.o \ kyra/script.o \ kyra/sound.o \ + kyra/staticres.o \ kyra/wsamovie.o MODULE_DIRS += \ diff --git a/kyra/palette.cpp b/kyra/palette.cpp index b1099f72dc..65de51e652 100644 --- a/kyra/palette.cpp +++ b/kyra/palette.cpp @@ -20,10 +20,9 @@ */ #include "common/stdafx.h" -#include "kyra/resource.h" - #include "common/stream.h" -#include "kyra/codecs.h" +#include "kyra/resource.h" +#include "kyra/screen.h" namespace Kyra { @@ -47,33 +46,11 @@ Palette::Palette(uint8* data, uint32 size) { assert(_palette); // made decompression - if (Compression::decode80(data + 10, _palette) != 768) { - error("decode80 decompressesize != 768 bytes"); - } - + Screen::decodeFrame4(data + 10, _palette, imageSize); delete [] data; - data = _palette; + } else { + _palette = data; } - - // hmm.. common/system.h Docu is wrong or SDL Backend has a bug :) - // a palette should have this order: - // R1-G1-B1-A1-R2-G2-B2-A2-... - // so we need 4 bytes per color - _palette = new uint8[256 * 4]; - - uint8* currentpossrc = &data[0]; - uint8* currentposdst = &_palette[0]; - - // creates the original pallette (only first 6 bits are used) - for (uint32 i = 0; i < 256; i++) { - currentposdst[0] = currentpossrc[0] << 2; - currentposdst[1] = currentpossrc[1] << 2; - currentposdst[2] = currentpossrc[2] << 2; - currentpossrc += 3; - currentposdst += 4; - } - - delete [] data; } } // end of namespace Kyra diff --git a/kyra/resource.cpp b/kyra/resource.cpp index 7da8772db3..ea2dd35055 100644 --- a/kyra/resource.cpp +++ b/kyra/resource.cpp @@ -20,14 +20,13 @@ */ #include "common/stdafx.h" -#include "kyra/resource.h" -#include "kyra/wsamovie.h" - #include "common/file.h" +#include "kyra/resource.h" #include "kyra/script.h" +#include "kyra/wsamovie.h" namespace Kyra { -Resourcemanager::Resourcemanager(KyraEngine* engine) { +Resource::Resource(KyraEngine* engine) { _engine = engine; // prefetches all PAK Files @@ -79,7 +78,7 @@ Resourcemanager::Resourcemanager(KyraEngine* engine) { } } -Resourcemanager::~Resourcemanager() { +Resource::~Resource() { Common::List<PAKFile*>::iterator start = _pakfiles.begin(); for (;start != _pakfiles.end(); ++start) { @@ -88,7 +87,7 @@ Resourcemanager::~Resourcemanager() { } } -uint8* Resourcemanager::fileData(const char* file, uint32* size) { +uint8* Resource::fileData(const char* file, uint32* size) { uint8* buffer = 0; Common::File file_; @@ -131,10 +130,9 @@ uint8* Resourcemanager::fileData(const char* file, uint32* size) { return buffer; } -Palette* Resourcemanager::loadPalette(const char* file) { +Palette* Resource::loadPalette(const char* file) { uint32 size = 0; - uint8* buffer = 0; - buffer = fileData(file, &size); + uint8 *buffer = fileData(file, &size); if (!buffer) { warning("ResMgr: Failed loading palette %s", file); return 0; @@ -142,38 +140,23 @@ Palette* Resourcemanager::loadPalette(const char* file) { return new Palette(buffer, size); } -CPSImage* Resourcemanager::loadImage(const char* file) { +CPSImage* Resource::loadImage(const char* file) { uint32 size = 0; - uint8* buffer = 0; - buffer = fileData(file, &size); + uint8 *buffer = fileData(file, &size); if (!buffer) return 0; return new CPSImage(buffer, size); } -Font* Resourcemanager::loadFont(const char* file) { +Font* Resource::loadFont(const char* file) { uint32 size = 0; - uint8* buffer = 0; - buffer = fileData(file, &size); + uint8 *buffer = fileData(file, &size); if (!buffer) return 0; return new Font(buffer, size); } -Movie* Resourcemanager::loadMovie(const char* file) { - // TODO: we have to check the Extenion to create the right movie - uint32 size = 0; - uint8* buffer = 0; - buffer = fileData(file, &size); - if (!buffer || !size) - return 0; - if (_engine->game() == KYRA1 || _engine->game() == KYRA1CD) - return new WSAMovieV1(buffer, size, _engine->game()); - else - return new WSAMovieV2(buffer, size); -} - -VMContext* Resourcemanager::loadScript(const char* file) { +VMContext* Resource::loadScript(const char* file) { VMContext* context = new VMContext(_engine); context->loadScript(file); return context; @@ -182,12 +165,12 @@ VMContext* Resourcemanager::loadScript(const char* file) { /////////////////////////////////////////// // Pak file manager #define PAKFile_Iterate Common::List<PakChunk*>::iterator start=_files.begin();start != _files.end(); ++start -PAKFile::PAKFile(/*const Common::String &path, */const Common::String& file) { +PAKFile::PAKFile(const Common::String& file) { Common::File pakfile; _buffer = 0; _open = false; - if (!pakfile.open(file.c_str())){ /*, Common::File::kFileReadMode, path.c_str())) {*/ + if (!pakfile.open(file.c_str())) { printf("pakfile couldn't open %s\n", file.c_str()); return; } diff --git a/kyra/resource.h b/kyra/resource.h index d8dd82d966..c0559e9876 100644 --- a/kyra/resource.h +++ b/kyra/resource.h @@ -48,9 +48,11 @@ public: const uint8* getFile(const char* file); uint32 getFileSize(const char* file); - bool isValid(void) {return (_buffer != 0);} - bool isOpen(void) {return _open;} + bool isValid(void) const { return (_buffer != 0); } + bool isOpen(void) const { return _open; } + private: + bool _open; uint8* _buffer; // the whole file Common::List<PakChunk*> _files; // the entries @@ -63,32 +65,26 @@ class Font; class Movie; class VMContext; -// out resource manager -class Resourcemanager { - typedef Common::String string; - +class Resource { public: - Resourcemanager(KyraEngine* engine); - virtual ~Resourcemanager(); + Resource(KyraEngine* engine); + ~Resource(); uint8* fileData(const char* file, uint32* size); Palette* loadPalette(const char* file); CPSImage* loadImage(const char* file); Font* loadFont(const char* file); - Movie* loadMovie(const char* file); VMContext* loadScript(const char* file); protected: - KyraEngine* _engine; + KyraEngine* _engine; Common::List<PAKFile*> _pakfiles; - }; class Palette { - public: Palette(uint8* data, uint32 size); @@ -99,11 +95,9 @@ public: protected: uint8* _palette; - }; class CPSImage { - public: CPSImage(uint8* buffer, uint32 size); @@ -141,7 +135,6 @@ protected: }; class Font { - public: Font(uint8* buffer, uint32 size); diff --git a/kyra/screen.cpp b/kyra/screen.cpp new file mode 100644 index 0000000000..cdab6c5999 --- /dev/null +++ b/kyra/screen.cpp @@ -0,0 +1,393 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003-2005 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "common/stdafx.h" +#include "common/system.h" +#include "kyra/screen.h" +#include "kyra/kyra.h" + +namespace Kyra { + +Screen::Screen(KyraEngine *vm, OSystem *system) + : _system(system), _vm(vm) { + _curPage = 0; + for (int pageNum = 0; pageNum < PAGE_NUM; pageNum += 2) { + uint8 *pagePtr = (uint8 *)malloc(PAGE_SIZE); + if (pagePtr) { + memset(pagePtr, 0, PAGE_SIZE); + _pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = pagePtr; + } + } + _palette1 = (uint8 *)malloc(768); + if (_palette1) { + memset(_palette1, 0, 768); + } +} + +Screen::~Screen() { + for (int pageNum = 0; pageNum < PAGE_NUM; pageNum += 2) { + free(_pagePtrs[pageNum]); + _pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = 0; + } + free(_palette1); +} + +void Screen::updateScreen() { + debug(9, "Screen::updateScreen()"); + _system->copyRectToScreen(getPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H); + _system->updateScreen(); +} + +uint8 *Screen::getPagePtr(int pageNum) { + debug(9, "Screen::getPagePtr(%d)", pageNum); + assert(pageNum < PAGE_NUM); + return _pagePtrs[pageNum]; +} + +void Screen::clearPage(int pageNum) { + debug(9, "Screen::clearPage(%d)", pageNum); + assert(pageNum < PAGE_NUM); + memset(getPagePtr(pageNum), 0, PAGE_SIZE); +} + +int Screen::setCurPage(int pageNum) { + debug(9, "Screen::setCurPage(%d)", pageNum); + int previousPage = _curPage; + _curPage = pageNum; + return previousPage; +} + +void Screen::clearCurPage() { + debug(9, "Screen::clearCurPage()"); + memset(getPagePtr(_curPage), 0, PAGE_SIZE); +} + +void Screen::fadeFromBlack() { + debug(9, "Screen::fadeFromBlack()"); + setScreenPalette(_palette1); + warning("Screen::fadeFromBlack() UNIMPLEMENTED"); +} + +void Screen::fadeToBlack() { + debug(9, "Screen::fadeToBlack()"); + warning("Screen::fadeToBlack() UNIMPLEMENTED"); +} + +void Screen::setScreenPalette(const uint8 *palData) { + debug(9, "Screen::setScreenPalette(0x%X)", palData); + uint8 screenPal[256 * 4]; + for (int i = 0; i < 256; ++i) { + screenPal[4 * i + 0] = (palData[0] << 2) | (palData[0] & 3); + screenPal[4 * i + 1] = (palData[1] << 2) | (palData[1] & 3); + screenPal[4 * i + 2] = (palData[2] << 2) | (palData[2] & 3); + screenPal[4 * i + 3] = 0; + palData += 3; + } + _system->setPalette(screenPal, 0, 256); +} + +void Screen::copyToPage0(int y, int h, uint8 page, uint8 *seqBuf) { + debug(9, "Screen::copyToPage0(%d, %d, %d, 0x%X)", y, h, page, seqBuf); + assert(y + h <= SCREEN_H); + const uint8 *src = getPagePtr(page) + y * SCREEN_W; + memcpy(seqBuf, src, h * SCREEN_W); + memcpy(getPagePtr(0) + y * SCREEN_W, src, h * SCREEN_W); +} + +void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage) { + debug(9, "Screen::copyRegion(%d, %d, %d, %d, %d, %d, %d, %d)", x1, y1, x2, y2, w, h, srcPage, dstPage); + assert(x1 + w <= SCREEN_W && y1 + h <= SCREEN_H); + const uint8 *src = getPagePtr(srcPage) + y1 * SCREEN_W + x1; + assert(x2 + w <= SCREEN_W && y2 + h <= SCREEN_H); + uint8 *dst = getPagePtr(dstPage) + y2 * SCREEN_W + x2; + while (h--) { + for (int i = 0; i < w; ++i) { + if (src[i]) { + dst[i] = src[i]; + } + } + src += SCREEN_W; + dst += SCREEN_W; + } +} + +void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint8 *src) { + debug(9, "Screen::copyBlockToPage(%d, %d, %d, %d, %d, 0x%X)", pageNum, x, y, w, h, src); + assert(x >= 0 && x < Screen::SCREEN_W && y >= 0 && y < Screen::SCREEN_H); + uint8 *dst = getPagePtr(pageNum) + y * Screen::SCREEN_W + x; + while (h--) { + for (int i = 0; i < w; ++i) { + dst[i] = src[i]; + } + dst += Screen::SCREEN_W; + src += w; + } +} + +void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum) { + debug(9, "Screen::fillRect(%d, %d, %d, %d, %d, %d)", x1, y1, x2, y2, color, pageNum); + assert(x2 < SCREEN_W && y2 < SCREEN_H); + if (pageNum == -1) { + pageNum = _curPage; + } + uint8 *dst = getPagePtr(pageNum); + for (; y1 <= y2; ++y1) { + for (; x1 <= x2; ++x1) { + *(dst + y1 * SCREEN_W + x1) = color; + } + } +} + +void Screen::setAnimBlockPtr(uint8 *p, int size) { + debug(9, "Screen::setAnimBlockPtr(0x%X, %d)", p, size); + _animBlockPtr = p; + _animBlockSize = size; +} + +void Screen::setTextColorMap(const uint8 *cmap) { + debug(9, "Screen::setTextColorMap(0x%X)", cmap); + setTextColor(cmap, 0, 15); +} + +void Screen::setTextColor(const uint8 *cmap, int a, int b) { + debug(9, "Screen::setTextColor(0x%X, %d, %d)", cmap, a, b); + for (int i = a; i <= b; ++i) { + _textColorsMap[i] = *cmap++; + } +} + +int Screen::getCharWidth(uint8 c) const { + debug(9, "Screen::getCharWidth(%c)", c); + warning("Screen::getCharWidth() UNIMPLEMENTED"); + return 0; +} + +int Screen::getTextWidth(const char *str) const { + debug(9, "Screen::getTextWidth('%s')", str); + warning("Screen::getTextWidth() UNIMPLEMENTED"); + return 0; +} + +void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2) { + debug(9, "Screen::printText('%s', %d, %d, 0x%X, 0x%X)", str, x, y, color1, color2); + warning("Screen::printText() UNIMPLEMENTED"); +} + +void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, int *flagsTable) { + debug(9, "Screen::drawShape(%d, %d, %d, %d, %d)", pageNum, x, y, sd, flags); + warning("Screen::drawShape() UNIMPLEMENTED"); +} + +void Screen::decodeFrame3(const uint8 *src, uint8 *dst, uint32 size) { + debug(9, "Screen::decodeFrame3(0x%X, 0x%X, %d)", src, dst, size); + const uint8 *dstEnd = dst + size; + while (dst < dstEnd) { + int8 code = *src++; + if (code == 0) { + uint16 sz = READ_BE_UINT16(src); + src += 2; + memset(dst, *src++, sz); + dst += sz; + } else if (code < 0) { + memset(dst, *src++, -code); + dst -= code; + } else { + memcpy(dst, src, code); + dst += code; + src += code; + } + } +} + +void Screen::decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize) { + debug(9, "Screen::decodeFrame4(0x%X, 0x%X, %d)", src, dst, dstSize); + uint8 *dstOrig = dst; + uint8 *dstEnd = dst + dstSize; + while (1) { + int count = dstEnd - dst; + if (count == 0) { + break; + } + uint8 code = *src++; + if (!(code & 0x80)) { + int len = MIN(count, (code >> 4) + 3); + int offs = ((code & 0xF) << 8) | *src++; + const uint8 *dstOffs = dst - offs; + while (len--) { + *dst++ = *dstOffs++; + } + } else if (code & 0x40) { + int len = (code & 0x3F) + 3; + if (code == 0xFE) { + len = READ_LE_UINT16(src); src += 2; + if (len > count) { + len = count; + } + memset(dst, *src++, len); dst += len; + } else { + if (code == 0xFF) { + len = READ_LE_UINT16(src); src += 2; + } + int offs = READ_LE_UINT16(src); src += 2; + if (len > count) { + len = count; + } + const uint8 *dstOffs = dstOrig + offs; + while (len--) { + *dst++ = *dstOffs++; + } + } + } else if (code != 0x80) { + int len = MIN(count, code & 0x3F); + while (len--) { + *dst++ = *src++; + } + } else { + break; + } + } +} + +void Screen::decodeFrameDelta(uint8 *dst, const uint8 *src) { + debug(9, "Screen::decodeFrameDelta(0x%X, 0x%X)", dst, src); + while (1) { + uint8 code = *src++; + if (code == 0) { + uint8 len = *src++; + code = *src++; + while (len--) { + *dst++ ^= code; + } + } else if (code & 0x80) { + code -= 0x80; + if (code != 0) { + dst += code; + } else { + uint16 subcode = READ_LE_UINT16(src); src += 2; + if (subcode == 0) { + break; + } else if (subcode & 0x8000) { + subcode -= 0x8000; + if (subcode & 0x4000) { + uint16 len = subcode - 0x4000; + code = *src++; + while (len--) { + *dst++ ^= code; + } + } else { + while (subcode--) { + *dst++ ^= *src++; + } + } + } else { + dst += subcode; + } + } + } else { + while (code--) { + *dst++ ^= *src++; + } + } + } +} + +void Screen::decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch) { + debug(9, "Screen::decodeFrameDeltaPage(0x%X, 0x%X, %d)", dst, src, pitch); + int count = 0; + uint8 *dstNext = dst; + while (1) { + uint8 code = *src++; + if (code == 0) { + uint8 len = *src++; + code = *src++; + while (len--) { + *dst++ ^= code; + if (++count == pitch) { + count = 0; + dstNext += SCREEN_W; + dst = dstNext; + } + } + } else if (code & 0x80) { + code -= 0x80; + if (code != 0) { + dst += code; + + count += code; + while (count >= pitch) { + count -= pitch; + dstNext += SCREEN_W; + dst = dstNext + count; + } + + } else { + uint16 subcode = READ_LE_UINT16(src); src += 2; + if (subcode == 0) { + break; + } else if (subcode & 0x8000) { + subcode -= 0x8000; + if (subcode & 0x4000) { + uint16 len = subcode - 0x4000; + code = *src++; + while (len--) { + *dst++ ^= code; + if (++count == pitch) { + count = 0; + dstNext += SCREEN_W; + dst = dstNext; + } + } + } else { + while (subcode--) { + *dst++ ^= *src++; + if (++count == pitch) { + count = 0; + dstNext += SCREEN_W; + dst = dstNext; + } + } + } + } else { + dst += subcode; + + count += subcode; + while (count >= pitch) { + count -= pitch; + dstNext += SCREEN_W; + dst = dstNext + count; + } + + } + } + } else { + while (code--) { + *dst++ ^= *src++; + if (++count == pitch) { + count = 0; + dstNext += 320; + dst = dstNext; + } + } + } + } +} + +} // End of namespace Kyra diff --git a/kyra/screen.h b/kyra/screen.h new file mode 100644 index 0000000000..6ce4fa5569 --- /dev/null +++ b/kyra/screen.h @@ -0,0 +1,88 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003-2005 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef KYRASCREEN_H +#define KYRASCREEN_H + +#include "common/util.h" + +class OSystem; + +namespace Kyra { + +class CPSImage; +class KyraEngine; + +class Screen { +public: + + Screen(KyraEngine *vm, OSystem *system); + ~Screen(); + + void updateScreen(); + uint8 *getPagePtr(int pageNum); + void clearPage(int pageNum); + int setCurPage(int pageNum); + void clearCurPage(); + void fadeFromBlack(); + void fadeToBlack(); + void setScreenPalette(const uint8 *palData); + void copyToPage0(int y, int h, uint8 page, uint8 *seqBuf); + void copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage); + void copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint8 *src); + void fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum = -1); + void setAnimBlockPtr(uint8 *p, int size); + void setTextColorMap(const uint8 *cmap); + void setTextColor(const uint8 *cmap, int a, int b); + int getCharWidth(uint8 c) const; + int getTextWidth(const char *str) const; + void printText(const char *str, int x, int y, uint8 color1, uint8 color2); + void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, int *flagsTable); + static void decodeFrame3(const uint8 *src, uint8 *dst, uint32 size); + static void decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize); + static void decodeFrameDelta(uint8 *dst, const uint8 *src); + static void decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch); + + int _charOffset; + int _charWidth; + int _curPage; + uint8 *_palette1; + + enum { + SCREEN_W = 320, + SCREEN_H = 200, + PAGE_SIZE = 320 * 200 + 1024, + PAGE_NUM = 16 + }; + +private: + + uint8 _textColorsMap[16]; + uint8 *_animBlockPtr; + int _animBlockSize; + uint8 *_pagePtrs[16]; + OSystem *_system; + KyraEngine *_vm; +}; + +} // End of namespace Kyra + +#endif diff --git a/kyra/script.cpp b/kyra/script.cpp index 5a52aca711..358d65b1bb 100644 --- a/kyra/script.cpp +++ b/kyra/script.cpp @@ -20,13 +20,12 @@ */ #include "common/stdafx.h" +#include "common/stream.h" +#include "common/util.h" #include "kyra/kyra.h" #include "kyra/script.h" #include "kyra/resource.h" -#include "common/stream.h" -#include "common/util.h" - #define COMMAND(x) { &VMContext::x, #x } #define OPCODE(x) { &VMContext::x, #x } @@ -402,7 +401,7 @@ void VMContext::loadScript(const char* file) { memset(_stack, 0, sizeof(int32) * ARRAYSIZE(_stack)); // loads the new file - _scriptFile = _engine->resManager()->fileData(file, &_scriptFileSize); + _scriptFile = _engine->resource()->fileData(file, &_scriptFileSize); if (!_scriptFileSize || !_scriptFile) { error("couldn't load script file '%s'", file); diff --git a/kyra/script_v1.cpp b/kyra/script_v1.cpp index 7cc3bdcf31..7ae03be931 100644 --- a/kyra/script_v1.cpp +++ b/kyra/script_v1.cpp @@ -20,7 +20,6 @@ */ #include "common/stdafx.h" - #include "kyra/kyra.h" #include "kyra/script.h" diff --git a/kyra/sound.cpp b/kyra/sound.cpp index 495b5f458e..8448726c75 100644 --- a/kyra/sound.cpp +++ b/kyra/sound.cpp @@ -19,163 +19,162 @@ * */ -#include "kyra/sound.h" +#include "common/stdafx.h" #include "kyra/resource.h" +#include "kyra/sound.h" namespace Kyra { - MusicPlayer::MusicPlayer(MidiDriver* driver, KyraEngine* engine) { - _engine = engine; - _driver = driver; - _passThrough = false; - _isPlaying = _nativeMT32 = false; - - memset(_channel, 0, sizeof(MidiChannel*) * 16); - memset(_channelVolume, 255, sizeof(uint8) * 16); - _volume = 0; - - int ret = open(); - if (ret != MERR_ALREADY_OPEN && ret != 0) { - error("couldn't open midi driver"); - } - } - MusicPlayer::~MusicPlayer() { - _driver->setTimerCallback(NULL, NULL); - close(); - } +MusicPlayer::MusicPlayer(MidiDriver* driver, KyraEngine* engine) { + _engine = engine; + _driver = driver; + _passThrough = false; + _isPlaying = _nativeMT32 = false; - void MusicPlayer::setVolume(int volume) { - if (volume < 0) - volume = 0; - else if (volume > 255) - volume = 255; + memset(_channel, 0, sizeof(MidiChannel*) * 16); + memset(_channelVolume, 255, sizeof(uint8) * 16); + _volume = 0; - if (_volume == volume) - return; - - _volume = volume; - - for (int i = 0; i < 16; ++i) { - if (_channel[i]) { - _channel[i]->volume(_channelVolume[i] * _volume / 255); - } - } + int ret = open(); + if (ret != MERR_ALREADY_OPEN && ret != 0) { + error("couldn't open midi driver"); } - - int MusicPlayer::open() { - // Don't ever call open without first setting the output driver! - if (!_driver) - return 255; - - int ret = _driver->open(); - if (ret) - return ret; - - _driver->setTimerCallback(this, &onTimer); - return 0; +} + +MusicPlayer::~MusicPlayer() { + _driver->setTimerCallback(NULL, NULL); + close(); +} + +void MusicPlayer::setVolume(int volume) { + if (volume < 0) + volume = 0; + else if (volume > 255) + volume = 255; + + if (_volume == volume) + return; + + _volume = volume; + for (int i = 0; i < 16; ++i) { + if (_channel[i]) { + _channel[i]->volume(_channelVolume[i] * _volume / 255); + } } - - void MusicPlayer::close() { - if (_driver) - _driver->close(); - _driver = 0; +} + +int MusicPlayer::open() { + // Don't ever call open without first setting the output driver! + if (!_driver) + return 255; + + int ret = _driver->open(); + if (ret) + return ret; + + _driver->setTimerCallback(this, &onTimer); + return 0; +} + +void MusicPlayer::close() { + if (_driver) + _driver->close(); + _driver = 0; +} + +void MusicPlayer::send(uint32 b) { + if (_passThrough) { + _driver->send(b); + return; } - void MusicPlayer::send(uint32 b) { - if (_passThrough) { - _driver->send(b); - return; - } - - uint8 channel = (byte)(b & 0x0F); - if ((b & 0xFFF0) == 0x07B0) { - // Adjust volume changes by master volume - uint8 volume = (uint8)((b >> 16) & 0x7F); - _channelVolume[channel] = volume; - volume = volume * _volume / 255; - b = (b & 0xFF00FFFF) | (volume << 16); - } else if ((b & 0xF0) == 0xC0 && !_nativeMT32) { - b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8; - } else if ((b & 0xFFF0) == 0x007BB0) { - //Only respond to All Notes Off if this channel - //has currently been allocated - if (!_channel[channel]) - return; - } - + uint8 channel = (byte)(b & 0x0F); + if ((b & 0xFFF0) == 0x07B0) { + // Adjust volume changes by master volume + uint8 volume = (uint8)((b >> 16) & 0x7F); + _channelVolume[channel] = volume; + volume = volume * _volume / 255; + b = (b & 0xFF00FFFF) | (volume << 16); + } else if ((b & 0xF0) == 0xC0 && !_nativeMT32) { + b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8; + } else if ((b & 0xFFF0) == 0x007BB0) { + //Only respond to All Notes Off if this channel + //has currently been allocated if (!_channel[channel]) - _channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); + return; + } - if (_channel[channel]) - _channel[channel]->send(b); + if (!_channel[channel]) + _channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); + if (_channel[channel]) + _channel[channel]->send(b); +} + +void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) { + switch (type) { + case 0x2F: // End of Track + _parser->jumpToTick(0); + break; + default: + warning("Unhandled meta event: 0x%02x", type); + break; } +} - void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) { - switch (type) { - case 0x2F: // End of Track - _parser->jumpToTick(0); - break; - default: - warning("Unhandled meta event: 0x%02x", type); - break; - } +void MusicPlayer::playMusic(const char* file) { + uint32 size; + uint8 *data = (_engine->resource())->fileData(file, &size); + + if (!data) { + warning("couldn't load '%s'", file); + return; } - void MusicPlayer::playMusic(const char* file) { - uint32 size; - uint8* data = 0; + playMusic(data, size); +} - data = (_engine->resManager())->fileData(file, &size); +void MusicPlayer::playMusic(uint8* data, uint32 size) { + if (_isPlaying) + stopMusic(); - if (!data) { - warning("couldn't load '%s'", file); - return; - } + _parser = MidiParser::createParser_XMIDI(); + assert(_parser); - playMusic(data, size); + if (!_parser->loadMusic(data, size)) { + warning("Error reading track!"); + delete _parser; + _parser = 0; + return; } - void MusicPlayer::playMusic(uint8* data, uint32 size) { - if (_isPlaying) - stopMusic(); + _parser->setTrack(0); + _parser->setMidiDriver(this); + _parser->setTimerRate(getBaseTempo()); - _parser = MidiParser::createParser_XMIDI(); - assert(_parser); + _isPlaying = true; +} - if (!_parser->loadMusic(data, size)) { - warning("Error reading track!"); - delete _parser; - _parser = 0; - return; - } - - _parser->setTrack(0); - _parser->setMidiDriver(this); - _parser->setTimerRate(getBaseTempo()); - - _isPlaying = true; +void MusicPlayer::stopMusic() { + _isPlaying = false; + if (_parser) { + _parser->unloadMusic(); + delete _parser; + _parser = NULL; } +} - void MusicPlayer::stopMusic() { - _isPlaying = false; - if (_parser) { - _parser->unloadMusic(); - delete _parser; - _parser = NULL; - } - } +void MusicPlayer::onTimer(void *refCon) { + MusicPlayer *music = (MusicPlayer *)refCon; + if (music->_isPlaying) + music->_parser->onTimer(); +} - void MusicPlayer::onTimer(void *refCon) { - MusicPlayer *music = (MusicPlayer *)refCon; - if (music->_isPlaying) - music->_parser->onTimer(); +void MusicPlayer::playTrack(uint8 track) { + if (_parser) { + _isPlaying = true; + _parser->setTrack(track); + _parser->jumpToTick(0); } +} - void MusicPlayer::playTrack(uint8 track) { - if (_parser) { - _isPlaying = true; - _parser->setTrack(track); - _parser->jumpToTick(0); - } - } } // end of namespace Kyra diff --git a/kyra/staticres.cpp b/kyra/staticres.cpp new file mode 100644 index 0000000000..ec4a1f0375 --- /dev/null +++ b/kyra/staticres.cpp @@ -0,0 +1,368 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004-2005 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "common/stdafx.h" +#include "kyra/kyra.h" + +namespace Kyra { + +const uint8 KyraEngine::_seq_introData_Forest[] = { + 0x00, 0x05, 0x01, 0x00, 0x07, 0x01, 0x1A, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x02, 0x05, 0x00, + 0x98, 0x00, 0x38, 0x0A, 0x00, 0x03, 0x07, 0x16, 0x02, 0x06, 0x09, 0x00, 0x0B, 0x00, 0x41, 0x00, + 0x18, 0x16, 0x03, 0x07, 0x02, 0x05, 0x01, 0x98, 0x00, 0x38, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, + 0x00, 0x03, 0x07, 0x02, 0x05, 0x03, 0x98, 0x00, 0x38, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, + 0x03, 0x07, 0x02, 0x05, 0x01, 0x98, 0x00, 0x38, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, 0x03, + 0x07, 0x02, 0x05, 0x00, 0x98, 0x00, 0x38, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, 0x0A, 0x05, + 0x03, 0x07, 0x16, 0x02, 0x06, 0x09, 0x00, 0x0B, 0x05, 0x0E, 0x00, 0x18, 0x16, 0x03, 0x07, 0x02, + 0x05, 0x01, 0x98, 0x00, 0x38, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, 0x03, 0x07, 0x02, 0x05, + 0x03, 0x98, 0x00, 0x38, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, 0x03, 0x07, 0x02, 0x05, 0x01, + 0x98, 0x00, 0x38, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, 0x03, 0x07, 0x02, 0x05, 0x04, 0x98, + 0x00, 0x38, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, 0x03, 0x07, 0x16, 0x02, 0x06, 0x09, 0x00, + 0x03, 0x07, 0x16, 0x02, 0x06, 0x09, 0x00, 0x03, 0x07, 0x02, 0x05, 0x05, 0x98, 0x00, 0x38, 0x16, + 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, 0x03, 0x07, 0x16, 0x02, 0x06, 0x09, 0x00, 0x03, 0x07, 0x16, + 0x02, 0x06, 0x09, 0x00, 0x03, 0x07, 0x02, 0x05, 0x06, 0x98, 0x00, 0x38, 0x16, 0x02, 0x16, 0x03, + 0x06, 0x09, 0x00, 0x03, 0x07, 0x16, 0x02, 0x06, 0x09, 0x00, 0x03, 0x07, 0x16, 0x02, 0x06, 0x09, + 0x00, 0x18, 0x25, 0x0A, 0x00, 0x03, 0x07, 0x03, 0x05, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, + 0x0B, 0x00, 0x09, 0x00, 0x0A, 0x06, 0x03, 0x07, 0x16, 0x02, 0x06, 0x09, 0x00, 0x0B, 0x06, 0x0E, + 0x00, 0x18, 0x17, 0x0A, 0x01, 0x03, 0x07, 0x03, 0x05, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, + 0x0B, 0x01, 0x0D, 0x00, 0x18, 0x25, 0x0A, 0x07, 0x03, 0x07, 0x16, 0x02, 0x06, 0x09, 0x00, 0x0B, + 0x07, 0x0E, 0x00, 0x18, 0x18, 0x03, 0x07, 0x03, 0x05, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, + 0x03, 0x07, 0x03, 0x05, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, 0x03, 0x07, 0x03, 0x05, 0x16, + 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, 0x03, 0x07, 0x03, 0x05, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, + 0x00, 0x03, 0x07, 0x03, 0x05, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, 0x06, 0x12, 0x00, 0x18, + 0x25, 0x0A, 0x02, 0x03, 0x07, 0x03, 0x05, 0x16, 0x02, 0x16, 0x03, 0x06, 0x09, 0x00, 0x0B, 0x02, + 0x07, 0x00, 0x0A, 0x03, 0x03, 0x07, 0x16, 0x02, 0x06, 0x09, 0x00, 0x0B, 0x03, 0x0F, 0x00, 0x13, + 0x13, 0x01, 0x07, 0x01, 0x05, 0x1D +}; + +const uint8 KyraEngine::_seq_introData_KallakWriting[] = { + 0x00, 0x00, 0x01, 0x0E, 0x1A, 0x1B, 0x17, 0x00, 0x00, 0x00, 0x3F, 0x01, 0xC7, 0x0C, 0x00, 0x0C, + 0x00, 0x19, 0x39, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0x95, 0x00, 0x20, 0x09, 0x14, + 0x0F, 0x2E, 0x02, 0x00, 0x01, 0x00, 0x00, 0x10, 0x05, 0x01, 0x94, 0x00, 0x1B, 0x07, 0x06, 0x00, + 0x18, 0x1D, 0x02, 0x00, 0x02, 0x00, 0x00, 0x10, 0x05, 0x02, 0x93, 0x00, 0x14, 0x07, 0x06, 0x00, + 0x02, 0x00, 0x03, 0x00, 0x00, 0x10, 0x05, 0x01, 0x90, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, + 0x04, 0x00, 0x00, 0x10, 0x05, 0x00, 0x8D, 0x00, 0x20, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x10, 0x05, 0x01, 0x8A, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, + 0x00, 0x10, 0x05, 0x02, 0x88, 0x00, 0x14, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x07, 0x00, + 0x00, 0x10, 0x05, 0x01, 0x85, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x10, + 0x05, 0x00, 0x82, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, 0x10, 0x05, 0x01, + 0x7F, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x05, 0x02, 0x7C, 0x00, + 0x14, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x05, 0x01, 0x79, 0x00, + 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x0C, 0x00, 0x00, 0x10, 0x05, 0x00, 0x76, 0x00, 0x20, 0x07, + 0x06, 0x00, 0x02, 0x00, 0x0D, 0x00, 0x00, 0x10, 0x05, 0x01, 0x73, 0x00, 0x1B, 0x07, 0x06, 0x00, + 0x18, 0x1D, 0x02, 0x00, 0x0E, 0x00, 0x00, 0x10, 0x05, 0x02, 0x70, 0x00, 0x14, 0x07, 0x06, 0x00, + 0x02, 0x00, 0x0F, 0x00, 0x00, 0x10, 0x05, 0x01, 0x6D, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, + 0x10, 0x00, 0x00, 0x10, 0x05, 0x00, 0x6A, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x11, 0x00, + 0x00, 0x10, 0x05, 0x01, 0x67, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x12, 0x00, + 0x00, 0x10, 0x05, 0x02, 0x65, 0x00, 0x14, 0x07, 0x06, 0x00, 0x02, 0x00, 0x13, 0x00, 0x00, 0x10, + 0x05, 0x01, 0x63, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x10, 0x05, 0x00, + 0x63, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x15, 0x00, 0x00, 0x10, 0x05, 0x00, 0x65, 0x00, + 0x1F, 0x07, 0x06, 0x00, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10, 0x05, 0x00, 0x6A, 0x00, 0x1D, 0x07, + 0x06, 0x00, 0x02, 0x00, 0x17, 0x00, 0x00, 0x10, 0x05, 0x00, 0x70, 0x00, 0x19, 0x07, 0x06, 0x00, + 0x02, 0x00, 0x18, 0x00, 0x00, 0x10, 0x05, 0x00, 0x76, 0x00, 0x17, 0x07, 0x06, 0x00, 0x02, 0x00, + 0x19, 0x00, 0x00, 0x10, 0x05, 0x00, 0x7C, 0x00, 0x16, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1A, 0x00, + 0x00, 0x10, 0x05, 0x00, 0x82, 0x00, 0x17, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1B, 0x00, 0x00, 0x10, + 0x05, 0x00, 0x88, 0x00, 0x19, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x05, 0x00, + 0x8D, 0x00, 0x1D, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1D, 0x00, 0x00, 0x10, 0x05, 0x00, 0x93, 0x00, + 0x1F, 0x07, 0x06, 0x00, 0x1C, 0x1B, 0x0F, 0x2F, 0x02, 0x00, 0x01, 0x00, 0x00, 0x10, 0x05, 0x01, + 0x94, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x10, 0x05, 0x01, 0x94, 0x00, + 0x1B, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x02, 0x00, 0x00, 0x10, 0x05, 0x02, 0x93, 0x00, + 0x14, 0x07, 0x06, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x10, 0x05, 0x02, 0x93, 0x00, 0x14, 0x07, + 0x06, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x10, 0x05, 0x01, 0x90, 0x00, 0x1B, 0x07, 0x06, 0x00, + 0x02, 0x00, 0x04, 0x00, 0x00, 0x10, 0x05, 0x00, 0x8D, 0x00, 0x20, 0x07, 0x06, 0x00, 0x18, 0x1D, + 0x02, 0x00, 0x05, 0x00, 0x00, 0x10, 0x05, 0x01, 0x8A, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x10, 0x05, 0x01, 0x8A, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, + 0x00, 0x10, 0x05, 0x02, 0x88, 0x00, 0x14, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x07, 0x00, + 0x00, 0x10, 0x05, 0x01, 0x85, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x10, + 0x05, 0x00, 0x82, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, 0x10, 0x05, 0x01, + 0x7F, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x05, 0x02, 0x7C, 0x00, + 0x14, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x05, 0x01, 0x79, 0x00, + 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x0C, 0x00, 0x00, 0x10, 0x05, 0x00, 0x76, 0x00, 0x20, 0x07, + 0x06, 0x00, 0x02, 0x00, 0x0D, 0x00, 0x00, 0x10, 0x05, 0x01, 0x73, 0x00, 0x1B, 0x07, 0x06, 0x00, + 0x18, 0x1D, 0x02, 0x00, 0x0E, 0x00, 0x00, 0x10, 0x05, 0x02, 0x70, 0x00, 0x14, 0x07, 0x06, 0x00, + 0x02, 0x00, 0x0F, 0x00, 0x00, 0x10, 0x05, 0x01, 0x6D, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, + 0x10, 0x00, 0x00, 0x10, 0x05, 0x00, 0x6A, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x11, 0x00, + 0x00, 0x10, 0x05, 0x01, 0x67, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x12, 0x00, + 0x00, 0x10, 0x05, 0x02, 0x65, 0x00, 0x14, 0x07, 0x06, 0x00, 0x02, 0x00, 0x13, 0x00, 0x00, 0x10, + 0x05, 0x01, 0x63, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x10, 0x05, 0x00, + 0x63, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x15, 0x00, 0x00, 0x10, 0x05, 0x00, 0x65, 0x00, + 0x1F, 0x07, 0x06, 0x00, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10, 0x05, 0x00, 0x6A, 0x00, 0x1D, 0x07, + 0x06, 0x00, 0x02, 0x00, 0x17, 0x00, 0x00, 0x10, 0x05, 0x00, 0x70, 0x00, 0x19, 0x07, 0x06, 0x00, + 0x02, 0x00, 0x18, 0x00, 0x00, 0x10, 0x05, 0x00, 0x76, 0x00, 0x17, 0x07, 0x06, 0x00, 0x02, 0x00, + 0x19, 0x00, 0x00, 0x10, 0x05, 0x00, 0x7C, 0x00, 0x16, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1A, 0x00, + 0x00, 0x10, 0x05, 0x00, 0x82, 0x00, 0x17, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1B, 0x00, 0x00, 0x10, + 0x05, 0x00, 0x88, 0x00, 0x19, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x05, 0x00, + 0x8D, 0x00, 0x1D, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1D, 0x00, 0x00, 0x10, 0x05, 0x00, 0x93, 0x00, + 0x1F, 0x07, 0x06, 0x00, 0x1C, 0x1B, 0x0F, 0x30, 0x02, 0x00, 0x01, 0x00, 0x00, 0x10, 0x05, 0x01, + 0x94, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x10, 0x05, 0x01, 0x94, 0x00, + 0x1B, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x02, 0x00, 0x00, 0x10, 0x05, 0x02, 0x93, 0x00, + 0x14, 0x07, 0x06, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x10, 0x05, 0x02, 0x93, 0x00, 0x14, 0x07, + 0x06, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x10, 0x05, 0x02, 0x93, 0x00, 0x14, 0x07, 0x06, 0x00, + 0x02, 0x00, 0x03, 0x00, 0x00, 0x10, 0x05, 0x01, 0x90, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, + 0x03, 0x00, 0x00, 0x10, 0x05, 0x01, 0x90, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x04, 0x00, + 0x00, 0x10, 0x05, 0x00, 0x8D, 0x00, 0x20, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x05, 0x00, + 0x00, 0x10, 0x05, 0x01, 0x8A, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x10, + 0x05, 0x02, 0x88, 0x00, 0x14, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x07, 0x00, 0x00, 0x10, + 0x05, 0x01, 0x85, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x10, 0x05, 0x00, + 0x82, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, 0x10, 0x05, 0x01, 0x7F, 0x00, + 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x05, 0x02, 0x7C, 0x00, 0x14, 0x07, + 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x05, 0x01, 0x79, 0x00, 0x1B, 0x07, + 0x06, 0x00, 0x02, 0x00, 0x0C, 0x00, 0x00, 0x10, 0x05, 0x00, 0x76, 0x00, 0x20, 0x07, 0x06, 0x00, + 0x02, 0x00, 0x0D, 0x00, 0x00, 0x10, 0x05, 0x01, 0x73, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x18, 0x1D, + 0x02, 0x00, 0x0E, 0x00, 0x00, 0x10, 0x05, 0x02, 0x70, 0x00, 0x14, 0x07, 0x06, 0x00, 0x02, 0x00, + 0x0F, 0x00, 0x00, 0x10, 0x05, 0x01, 0x6D, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x10, 0x00, + 0x00, 0x10, 0x05, 0x00, 0x6A, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x10, + 0x05, 0x01, 0x67, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x12, 0x00, 0x00, 0x10, + 0x05, 0x02, 0x65, 0x00, 0x14, 0x07, 0x06, 0x00, 0x02, 0x00, 0x13, 0x00, 0x00, 0x10, 0x05, 0x01, + 0x63, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x10, 0x05, 0x00, 0x63, 0x00, + 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x15, 0x00, 0x00, 0x10, 0x05, 0x00, 0x65, 0x00, 0x1F, 0x07, + 0x06, 0x00, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10, 0x05, 0x00, 0x6A, 0x00, 0x1D, 0x07, 0x06, 0x00, + 0x02, 0x00, 0x17, 0x00, 0x00, 0x10, 0x05, 0x00, 0x70, 0x00, 0x19, 0x07, 0x06, 0x00, 0x02, 0x00, + 0x18, 0x00, 0x00, 0x10, 0x05, 0x00, 0x76, 0x00, 0x17, 0x07, 0x06, 0x00, 0x02, 0x00, 0x19, 0x00, + 0x00, 0x10, 0x05, 0x00, 0x7C, 0x00, 0x16, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1A, 0x00, 0x00, 0x10, + 0x05, 0x00, 0x82, 0x00, 0x17, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1B, 0x00, 0x00, 0x10, 0x05, 0x00, + 0x88, 0x00, 0x19, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x05, 0x00, 0x8D, 0x00, + 0x1D, 0x07, 0x06, 0x00, 0x02, 0x00, 0x1D, 0x00, 0x00, 0x10, 0x05, 0x00, 0x93, 0x00, 0x1F, 0x07, + 0x06, 0x00, 0x1C, 0x06, 0x3C, 0x00, 0x1B, 0x0F, 0x31, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05, + 0x00, 0x95, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0x95, + 0x00, 0x20, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x01, 0x00, 0x00, 0x10, 0x05, 0x01, 0x94, + 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x10, 0x05, 0x01, 0x94, 0x00, 0x1B, + 0x07, 0x06, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x10, 0x05, 0x02, 0x93, 0x00, 0x14, 0x07, 0x06, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x10, 0x05, 0x02, 0x93, 0x00, 0x14, 0x07, 0x06, 0x00, 0x18, + 0x1D, 0x02, 0x00, 0x03, 0x00, 0x00, 0x10, 0x05, 0x01, 0x90, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, + 0x00, 0x04, 0x00, 0x00, 0x10, 0x05, 0x00, 0x8D, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x05, + 0x00, 0x00, 0x10, 0x05, 0x01, 0x8A, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x06, + 0x00, 0x00, 0x10, 0x05, 0x02, 0x88, 0x00, 0x14, 0x07, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, + 0x10, 0x05, 0x01, 0x85, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x05, 0x00, 0x82, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, 0x10, 0x05, + 0x01, 0x7F, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x05, 0x02, 0x7C, + 0x00, 0x14, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x05, 0x01, 0x79, + 0x00, 0x1B, 0x07, 0x06, 0x00, 0x02, 0x00, 0x0C, 0x00, 0x00, 0x10, 0x05, 0x00, 0x76, 0x00, 0x20, + 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, 0x00, 0x0D, 0x00, 0x00, 0x10, 0x05, 0x01, 0x73, 0x00, 0x1B, + 0x07, 0x06, 0x00, 0x02, 0x00, 0x0E, 0x00, 0x00, 0x10, 0x05, 0x02, 0x70, 0x00, 0x14, 0x07, 0x06, + 0x00, 0x02, 0x00, 0x0F, 0x00, 0x00, 0x10, 0x05, 0x01, 0x6D, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x18, + 0x1D, 0x02, 0x00, 0x10, 0x00, 0x00, 0x10, 0x05, 0x00, 0x6A, 0x00, 0x20, 0x07, 0x06, 0x00, 0x02, + 0x00, 0x11, 0x00, 0x00, 0x10, 0x05, 0x01, 0x67, 0x00, 0x1B, 0x07, 0x06, 0x00, 0x18, 0x1D, 0x02, + 0x00, 0x12, 0x00, 0x00, 0x10, 0x05, 0x02, 0x65, 0x00, 0x14, 0x07, 0x06, 0x00, 0x06, 0x3C, 0x00, + 0x02, 0x00, 0x1E, 0x00, 0x00, 0x10, 0x08, 0x12, 0x06, 0x1E, 0x00, 0x0A, 0x01, 0x02, 0x00, 0x1F, + 0x00, 0x00, 0x10, 0x07, 0x0A, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x10, 0x07, 0x0A, 0x00, 0x02, + 0x00, 0x21, 0x00, 0x00, 0x10, 0x07, 0x0A, 0x00, 0x02, 0x00, 0x22, 0x00, 0x00, 0x10, 0x07, 0x0A, + 0x00, 0x0B, 0x01, 0x02, 0x00, 0x18, 0x1F, 0x06, 0x0A, 0x00, 0x02, 0x00, 0x23, 0x00, 0x00, 0x10, + 0x07, 0x14, 0x00, 0x18, 0x1E, 0x02, 0x00, 0x24, 0x00, 0x00, 0x10, 0x07, 0x14, 0x00, 0x02, 0x00, + 0x25, 0x00, 0x00, 0x10, 0x07, 0x14, 0x00, 0x18, 0x1F, 0x02, 0x00, 0x26, 0x00, 0x00, 0x10, 0x07, + 0x14, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00, 0x10, 0x07, 0x14, 0x00, 0x18, 0x1E, 0x02, 0x00, 0x28, + 0x00, 0x00, 0x10, 0x08, 0x06, 0x3C, 0x00, 0x18, 0x1E, 0x03, 0x00, 0x07, 0x06, 0x00, 0x18, 0x1E, + 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, + 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x18, 0x1E, + 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, + 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, + 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x18, 0x1E, 0x03, + 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, + 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, + 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x18, 0x1E, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, + 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, + 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, + 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x03, 0x00, 0x07, 0x06, 0x00, 0x13, 0x1C, 0x19, 0x01, 0x0E, + 0x06, 0x3C, 0x00, 0x13, 0x01, 0x00, 0x1D +}; + +const uint8 KyraEngine::_seq_introData_KyrandiaLogo[] = { + 0x15, 0x00, 0x02, 0x00, 0x06, 0x01, 0x1A, 0x02, 0x06, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x06, + 0x06, 0x00, 0x18, 0x14, 0x16, 0x04, 0x0A, 0x00, 0x03, 0x06, 0x16, 0x00, 0x0B, 0x00, 0x0B, 0x00, + 0x06, 0x3C, 0x00, 0x18, 0x27, 0x0A, 0x01, 0x03, 0x06, 0x16, 0x00, 0x0B, 0x01, 0x0F, 0x00, 0x06, + 0x3C, 0x00, 0x18, 0x27, 0x0A, 0x02, 0x04, 0x06, 0x16, 0x00, 0x0B, 0x02, 0x0F, 0x00, 0x02, 0x06, + 0x0D, 0x00, 0x00, 0x00, 0x16, 0x00, 0x06, 0x06, 0x00, 0x06, 0x78, 0x00, 0x18, 0x14, 0x0A, 0x02, + 0x04, 0x06, 0x16, 0x00, 0x0B, 0x02, 0x0C, 0x00, 0x13, 0x01, 0x06, 0x1D +}; + +const uint8 KyraEngine::_seq_introData_KallakMalcom[] = { + 0x00, 0x04, 0x01, 0x1A, 0x0E, 0x17, 0x00, 0x00, 0x00, 0x3F, 0x01, 0xC7, 0x0C, 0x00, 0x0C, 0x03, + 0x0D, 0x00, 0x17, 0x00, 0x00, 0x88, 0x3F, 0x01, 0xC7, 0x0C, 0x02, 0x19, 0x00, 0x02, 0x04, 0x00, + 0x10, 0x00, 0x3A, 0x09, 0x19, 0x00, 0x19, 0x3A, 0x14, 0x18, 0x23, 0x0A, 0x00, 0x03, 0x04, 0x07, + 0x07, 0x00, 0x0B, 0x00, 0x22, 0x00, 0x10, 0x02, 0x50, 0x00, 0x3A, 0x05, 0x0A, 0x01, 0x03, 0x04, + 0x07, 0x07, 0x00, 0x0B, 0x01, 0x07, 0x00, 0x06, 0x3C, 0x00, 0x10, 0x03, 0x50, 0x00, 0x3A, 0x05, + 0x0A, 0x02, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, 0x02, 0x17, 0x00, 0x06, 0x3C, 0x00, 0x10, 0x04, + 0x50, 0x00, 0x3A, 0x05, 0x0A, 0x03, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, 0x03, 0x0A, 0x00, 0x06, + 0x3C, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, + 0x00, 0x10, 0x05, 0xF0, 0x00, 0x3A, 0x0F, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, + 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x06, 0x3C, 0x00, 0x10, 0x06, + 0xF0, 0x00, 0x3A, 0x0F, 0x0A, 0x04, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, 0x04, 0x12, 0x00, 0x06, + 0x3C, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, + 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x06, 0x78, 0x00, 0x10, 0x07, 0xF0, 0x00, 0x3A, 0x0F, 0x0A, + 0x05, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, 0x05, 0x11, 0x00, 0x06, 0x3C, 0x00, 0x03, 0x04, 0x07, + 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x10, 0x08, 0x50, 0x00, 0x3A, 0x05, 0x0A, 0x06, 0x03, + 0x04, 0x07, 0x07, 0x00, 0x0B, 0x06, 0x07, 0x00, 0x06, 0x3C, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, + 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x10, 0x09, 0x50, 0x00, 0x3A, 0x05, + 0x0A, 0x07, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, 0x07, 0x0A, 0x00, 0x06, 0x3C, 0x00, 0x03, 0x04, + 0x07, 0x07, 0x00, 0x10, 0x0A, 0x50, 0x00, 0x3A, 0x05, 0x0A, 0x08, 0x03, 0x04, 0x07, 0x07, 0x00, + 0x0B, 0x08, 0x10, 0x00, 0x06, 0x3C, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x10, 0x0B, 0xF0, 0x00, + 0x3A, 0x0F, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, + 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, + 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x06, 0x3C, 0x00, 0x03, 0x04, 0x07, + 0x07, 0x00, 0x10, 0x0C, 0xF0, 0x00, 0x3A, 0x0F, 0x0A, 0x09, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, + 0x09, 0x0E, 0x00, 0x06, 0x3C, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, + 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x03, + 0x04, 0x07, 0x07, 0x00, 0x10, 0x0D, 0x50, 0x00, 0x3A, 0x05, 0x0A, 0x0A, 0x03, 0x04, 0x07, 0x07, + 0x00, 0x0B, 0x0A, 0x0E, 0x00, 0x06, 0x3C, 0x00, 0x0A, 0x0B, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, + 0x0B, 0x02, 0x00, 0x18, 0x20, 0x0A, 0x0C, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, 0x0C, 0x06, 0x00, + 0x18, 0x21, 0x0A, 0x0D, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, 0x0D, 0x0C, 0x00, 0x18, 0x22, 0x0A, + 0x0E, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, 0x0E, 0x0B, 0x00, 0x10, 0x0E, 0x50, 0x00, 0x3A, 0x05, + 0x0A, 0x0F, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, 0x0F, 0x09, 0x00, 0x06, 0x3C, 0x00, 0x03, 0x04, + 0x07, 0x07, 0x00, 0x10, 0x0F, 0x50, 0x00, 0x3A, 0x05, 0x0A, 0x10, 0x03, 0x04, 0x07, 0x07, 0x00, + 0x0B, 0x10, 0x09, 0x00, 0x06, 0x3C, 0x00, 0x03, 0x04, 0x07, 0x07, 0x00, 0x10, 0x10, 0x50, 0x00, + 0x3A, 0x05, 0x0A, 0x11, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, 0x11, 0x0F, 0x00, 0x06, 0x3C, 0x00, + 0x03, 0x04, 0x07, 0x07, 0x00, 0x10, 0x11, 0x50, 0x00, 0x3A, 0x05, 0x0A, 0x12, 0x03, 0x04, 0x07, + 0x07, 0x00, 0x0B, 0x12, 0x14, 0x00, 0x06, 0x3C, 0x00, 0x0A, 0x13, 0x03, 0x04, 0x07, 0x07, 0x00, + 0x0B, 0x13, 0x06, 0x00, 0x18, 0x23, 0x0A, 0x13, 0x03, 0x04, 0x07, 0x07, 0x00, 0x0B, 0x13, 0x07, + 0x00, 0x11, 0x06, 0x3C, 0x00, 0x13, 0x19, 0x01, 0x0E, 0x13, 0x01, 0x04, 0x1D +}; + +const uint8 KyraEngine::_seq_introData_MalcomTree[] = { + 0x00, 0x01, 0x00, 0x1A, 0x0E, 0x17, 0x00, 0x00, 0x00, 0x3F, 0x01, 0xC7, 0x0C, 0x00, 0x0C, 0x01, + 0x0D, 0x01, 0x09, 0x02, 0x01, 0x00, 0x00, 0x00, 0x10, 0x19, 0x38, 0x09, 0x18, 0x1E, 0x14, 0x18, + 0x1F, 0x0A, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x0B, 0x00, 0x1F, 0x00, 0x18, 0x19, 0x0A, 0x01, + 0x03, 0x01, 0x06, 0x06, 0x00, 0x0B, 0x01, 0x0F, 0x00, 0x18, 0x26, 0x10, 0x1F, 0x50, 0x00, 0x2D, + 0x05, 0x0A, 0x02, 0x03, 0x01, 0x06, 0x06, 0x00, 0x0B, 0x02, 0x10, 0x00, 0x11, 0x18, 0x1F, 0x03, + 0x01, 0x06, 0x06, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x18, 0x24, + 0x18, 0x1F, 0x03, 0x01, 0x06, 0x06, 0x00, 0x18, 0x1E, 0x0A, 0x03, 0x03, 0x01, 0x06, 0x06, 0x00, + 0x0B, 0x03, 0x15, 0x00, 0x10, 0x16, 0x50, 0x00, 0x2D, 0x05, 0x18, 0x1F, 0x03, 0x01, 0x06, 0x06, + 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x18, 0x1E, 0x03, 0x01, 0x06, 0x06, 0x00, 0x03, 0x01, 0x06, + 0x06, 0x00, 0x18, 0x1F, 0x03, 0x01, 0x06, 0x06, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x03, 0x01, + 0x06, 0x06, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x18, 0x1E, 0x03, 0x01, 0x06, 0x06, 0x00, 0x18, + 0x1A, 0x18, 0x1E, 0x0A, 0x05, 0x03, 0x01, 0x06, 0x06, 0x00, 0x0B, 0x05, 0x09, 0x00, 0x11, 0x0A, + 0x06, 0x03, 0x01, 0x06, 0x06, 0x00, 0x0B, 0x06, 0x14, 0x00, 0x18, 0x1A, 0x18, 0x1F, 0x10, 0x17, + 0x50, 0x00, 0x2D, 0x05, 0x06, 0x3C, 0x00, 0x0A, 0x07, 0x03, 0x01, 0x06, 0x06, 0x00, 0x0B, 0x07, + 0x06, 0x00, 0x18, 0x1E, 0x06, 0x1E, 0x00, 0x10, 0x18, 0x50, 0x00, 0x2D, 0x05, 0x03, 0x01, 0x06, + 0x06, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x0A, 0x08, 0x04, 0x01, + 0x06, 0x06, 0x00, 0x04, 0x01, 0x06, 0x06, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x03, 0x01, 0x06, + 0x06, 0x00, 0x0B, 0x08, 0x01, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x06, 0x78, 0x00, 0x0A, 0x09, + 0x03, 0x01, 0x06, 0x06, 0x00, 0x0B, 0x09, 0x04, 0x00, 0x18, 0x1B, 0x0A, 0x0A, 0x03, 0x01, 0x06, + 0x06, 0x00, 0x0B, 0x0A, 0x09, 0x00, 0x06, 0x14, 0x00, 0x10, 0x19, 0x50, 0x00, 0x2D, 0x05, 0x03, + 0x01, 0x06, 0x06, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x0A, 0x0B, 0x03, 0x01, 0x06, 0x06, 0x00, + 0x04, 0x01, 0x06, 0x06, 0x00, 0x04, 0x01, 0x06, 0x06, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x03, + 0x01, 0x06, 0x06, 0x00, 0x0B, 0x0B, 0x01, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x03, 0x01, 0x06, + 0x06, 0x00, 0x03, 0x01, 0x06, 0x06, 0x00, 0x10, 0x1A, 0x50, 0x00, 0x2D, 0x05, 0x0A, 0x0C, 0x03, + 0x01, 0x06, 0x06, 0x00, 0x0B, 0x0C, 0x12, 0x00, 0x03, 0x01, 0x01, 0x01, 0x11, 0x15, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1C, 0x50, 0x00, 0x2D, 0x05, 0x06, + 0x3C, 0x00, 0x03, 0x02, 0x03, 0x02, 0x06, 0x06, 0x00, 0x11, 0x18, 0x1C, 0x0A, 0x0F, 0x03, 0x02, + 0x06, 0x06, 0x00, 0x0B, 0x0F, 0x0D, 0x00, 0x10, 0x1D, 0x50, 0x00, 0x2D, 0x05, 0x0A, 0x10, 0x03, + 0x02, 0x06, 0x06, 0x00, 0x03, 0x02, 0x06, 0x06, 0x00, 0x03, 0x02, 0x06, 0x06, 0x00, 0x04, 0x02, + 0x06, 0x06, 0x00, 0x04, 0x02, 0x06, 0x06, 0x00, 0x04, 0x02, 0x06, 0x06, 0x00, 0x0B, 0x10, 0x02, + 0x00, 0x10, 0x1E, 0x50, 0x00, 0x2D, 0x05, 0x0A, 0x11, 0x03, 0x02, 0x06, 0x06, 0x00, 0x03, 0x02, + 0x06, 0x06, 0x00, 0x03, 0x02, 0x06, 0x06, 0x00, 0x04, 0x02, 0x06, 0x06, 0x00, 0x04, 0x02, 0x06, + 0x06, 0x00, 0x04, 0x02, 0x06, 0x06, 0x00, 0x0B, 0x11, 0x02, 0x00, 0x06, 0xB4, 0x00, 0x13, 0x19, + 0x01, 0x0E, 0x01, 0x01, 0x13, 0x01, 0x02, 0x1D +}; + +const uint8 KyraEngine::_seq_introData_WestwoodLogo[] = { + 0x00, 0x03, 0x01, 0x1A, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x16, 0x01, 0x06, 0x06, 0x00, 0x06, + 0x3C, 0x00, 0x18, 0x14, 0x0A, 0x00, 0x03, 0x03, 0x16, 0x01, 0x0B, 0x00, 0x08, 0x00, 0x06, 0x3C, + 0x00, 0x18, 0x27, 0x0A, 0x01, 0x03, 0x03, 0x16, 0x01, 0x0B, 0x01, 0x0B, 0x00, 0x06, 0x78, 0x00, + 0x18, 0x14, 0x02, 0x03, 0x0A, 0x00, 0x00, 0x00, 0x16, 0x01, 0x06, 0x06, 0x00, 0x0A, 0x02, 0x04, + 0x03, 0x16, 0x01, 0x0B, 0x02, 0x09, 0x00, 0x13, 0x01, 0x03, 0x1D +}; + +const uint8 KyraEngine::_seq_codeSizeTable[] = { + 2, 1, 5, 1, 1, 4, 2, 2, 0, 0, 1, 3, 1, 1, 0, 1, + 5, 0, 0, 0, 0, 2, 1, 8, 1, 1, 0, 0, 0, 0, 0, 0 +}; + +const char *KyraEngine::_seq_WSATable[] = { + "kallak.wsa", + "tree1.wsa", + "tree2.wsa", + "westwood.wsa", + "mal-kal.wsa", + "destruct.wsa", + "kyrandia.wsa", + "shore.wsa", + "reunion.wsa", + "reuniont.wsa", + "latern.wsa" +}; + +const char *KyraEngine::_seq_CPSTable[] = { + "gemcut.cps", + "tree.cps" +}; + +const char *KyraEngine::_seq_COLTable[] = { + "kallak.col", + "tree_exp.col", + "ww.col", + "mal-kal.col" +}; + +const char *KyraEngine::_seq_textsTableEN[] = { + "This is a text test - 1", + "This is a text test - 2", + "Greetings, Kallak...", + "...Powerful leader of the Royal Mystics!", + "Did I frighten you?", + "Malcolm!", + "I heard yesterday of your escape.", + "And have expected you before now.", + "Why would I rush?", + "I rule this land!", + "Your puny curse restrains me naught.", + "So, slay me now!", + "I have little magic left.", + "I mean to harm you, have no doubt...", + "...Now you are stone...", + "...Yet I leave your eyes.", + "I shed no tears for Kyrandia...", + "...But cannot deny you yours.", + "Malcolm the Jester has broken free!", + "He now controls the Kyragem...", + "...source of all magic in Kyrandia!", + "", + "How dare you trip ME!", + "But no, something special for you...", + "A humorous hex!", + "But I shall give fair warning.", + "Don't jump on THAT tree!", + "Don't climb up THAT tree little squirrel!", + "Boo!", + "Tis funnier that way...", + "...Is it not?", + "Ha ha ha...", + "Aren't fingers wonderful?", + "It's great to be alive!", + "Brandon!", + "Grandfather! We did it!", + "No! YOU did it!", + "Long live King Brandon!", + "Long live the Royal Mystics!", + "Now, let's go put Kyrandia back together!", + "Good idea!", + "As my first Royal Proclamation...", + "I name sandals as the official footwear of Kyrandia!", + "Well done, Brandon!", + "The Land no longer weeps...", + "And your friends have been restored!", + "Dear Brynn...", + "Malcolm has broken free!", + "Soon he will come for me.", + "Please help Brandon...", + "" +}; + +} // End of namespace Kyra diff --git a/kyra/wsamovie.cpp b/kyra/wsamovie.cpp index 7c8a57abb1..e2ab2242e3 100644 --- a/kyra/wsamovie.cpp +++ b/kyra/wsamovie.cpp @@ -20,421 +20,186 @@ */ #include "common/stdafx.h" +#include "kyra/kyra.h" +#include "kyra/screen.h" #include "kyra/wsamovie.h" -#include "kyra/codecs.h" -#include "common/stream.h" - -#ifdef DUMP_FILES -#include <stdio.h> -#endif namespace Kyra { -WSAMovieV1::WSAMovieV1(uint8* data, uint32 size, uint8 gameid) { - if (!data) { - error("resource created without data"); - } - - _background = 0; - _currentFrame = 0; - _ownPalette = 0; - _offsetTable = 0; - _prefetchedFrame = 0xFFFE; - _buffer = data; - - // I like these Streams .... =) - Common::MemoryReadStream datastream(data, size); - - _wsaHeader._numFrames = datastream.readUint16LE(); - _wsaHeader._width = datastream.readUint16LE(); - _wsaHeader._height = datastream.readUint16LE(); - _wsaHeader._xPos = datastream.readByte(); - _wsaHeader._yPos = datastream.readByte(); - _wsaHeader._delta = datastream.readUint16LE(); - _wsaHeader._type = datastream.readUint16LE(); - -#ifdef DUMP_FILES - // TODO: make Linux/BSD conform - FILE* wsaheader = fopen("dumps/wsaheader.txt", "w+"); - - if (wsaheader) { - for (uint32 pos = 0; pos < sizeof(_wsaHeader); ++pos) - fprintf(wsaheader, "%d pos. byte: %d\n", pos + 1, ((uint8*)&_wsaHeader)[pos]); - fprintf(wsaheader, "\n"); - for (uint32 pos = 0; pos < sizeof(_wsaHeader) / 2; ++pos) - fprintf(wsaheader, "%d pos. word: %d\n", pos + 1, ((uint16*)&_wsaHeader)[pos]); - fprintf(wsaheader, "\n"); - for (uint32 pos = 0; pos < sizeof(_wsaHeader) / 4; ++pos) - fprintf(wsaheader, "%d pos. dword: %d\n", pos + 1, ((uint32*)&_wsaHeader)[pos]); - } - fclose(wsaheader); -#endif - - if (gameid == KYRA1CD) { - uint16 tmp = _wsaHeader._delta; - _wsaHeader._delta = _wsaHeader._type; - _wsaHeader._type = tmp; - - // skip 2 bytes - datastream.readUint16LE(); - } - - debug("_wsaHeader._numFrames = %d", _wsaHeader._numFrames); - debug("_wsaHeader._width = %d", _wsaHeader._width); - debug("_wsaHeader._height = %d", _wsaHeader._height); - debug("_wsaHeader._xPos = %d", _wsaHeader._xPos); - debug("_wsaHeader._yPos = %d", _wsaHeader._yPos); - debug("_wsaHeader._delta = %d", _wsaHeader._delta); - debug("_wsaHeader._type = %d", _wsaHeader._type); - - // check for version - if (_wsaHeader._type) { - error("loading a WSA version 2 with the WSA version 1 loader"); - } - - uint16 offsetAdd = 0; - // checks now for own palette - if (_wsaHeader._type % 2) { - // don't now if this will work right, because a few lines before we use - // _wsaHeader._type for detect the version of the WSA movie, - // but this code was from FreeKyra Tools so I think it will work - - // if this is a packed palette we have a problem :) - offsetAdd = 768 /* 0x300 */; - } - - // last frame seems every time to be a empty one - _frameCount = _wsaHeader._numFrames - 1; - _offsetTable = new uint32[_wsaHeader._numFrames + 2]; - assert(_offsetTable); - - // loads the offset table - for (uint32 tmp = 0; tmp < (uint32)_wsaHeader._numFrames + 2; ++tmp) { - _offsetTable[tmp] = datastream.readUint32LE() + offsetAdd; +WSAMovieV1 *KyraEngine::wsa_open(const char *filename, int offscreenDecode, uint8 *palBuf) { + debug(9, "KyraEngine::wsa_open('%s', %d, 0x%X)", filename, offscreenDecode, palBuf); + uint32 flags = 0; + uint32 fileSize; + uint8 *p = _res->fileData(filename, &fileSize); + + WSAMovieV1 *wsa = new WSAMovieV1; + const uint8 *wsaData = p; + wsa->numFrames = READ_LE_UINT16(wsaData); wsaData += 2; + wsa->width = READ_LE_UINT16(wsaData); wsaData += 2; + wsa->height = READ_LE_UINT16(wsaData); wsaData += 2; + wsa->deltaBufferSize = READ_LE_UINT16(wsaData); wsaData += 2; + wsa->flags = 0; + if (_game == KYRA1CD) { + flags = READ_LE_UINT16(wsaData); wsaData += 2; + } + + uint32 offsPal = 0; + if (flags & 1) { + offsPal = 0x300; + wsa->flags |= WF_HAS_PALETTE; + if (palBuf) { + memcpy(palBuf, wsaData + (wsa->numFrames + 2) * 4, 0x300); + } } + + if (offscreenDecode) { + wsa->flags |= WF_OFFSCREEN_DECODE; + const int offscreenBufferSize = wsa->width * wsa->height; + wsa->offscreenBuffer = (uint8 *)malloc(offscreenBufferSize); + memset(wsa->offscreenBuffer, 0, offscreenBufferSize); + } + + if (wsa->numFrames & 0x8000) { + warning("Unhandled wsa flags 0x80"); + wsa->flags |= 0x80; + wsa->numFrames &= 0x7FFF; + } + wsa->currentFrame = wsa->numFrames; + + wsa->deltaBuffer = (uint8 *)malloc(wsa->deltaBufferSize); + memset(wsa->deltaBuffer, 0, wsa->deltaBufferSize); + + // read frame offsets + wsa->frameOffsTable = (uint32 *)malloc((wsa->numFrames + 2) * 4); + wsa->frameOffsTable[0] = 0; + uint32 frameDataOffs = READ_LE_UINT32(wsaData); wsaData += 4; + bool firstFrame = true; + if (frameDataOffs == 0) { + firstFrame = false; + frameDataOffs = READ_LE_UINT32(wsaData); + wsa->flags |= WF_NO_FIRST_FRAME; + } + for (int i = 1; i < wsa->numFrames + 2; ++i) { + wsa->frameOffsTable[i] = READ_LE_UINT32(wsaData) - frameDataOffs; + wsaData += 4; + } + + // skip palette + wsaData += offsPal; + + // read frame data + const int frameDataSize = p + fileSize - wsaData; + wsa->frameData = (uint8 *)malloc(frameDataSize); + memcpy(wsa->frameData, wsaData, frameDataSize); + + // decode first frame + if (firstFrame) { + Screen::decodeFrame4(wsa->frameData, wsa->deltaBuffer, wsa->deltaBufferSize); + } + + delete[] p; + return wsa; +} - if (offsetAdd) { - uint8* palbuffer = new uint8[offsetAdd]; - assert(palbuffer); - - datastream.read(palbuffer, offsetAdd); - - _ownPalette = new Palette(palbuffer, offsetAdd); - assert(_ownPalette); +void KyraEngine::wsa_close(WSAMovieV1 *wsa) { + debug(9, "KyraEngine::wsa_close(0x%X)", wsa); + if (wsa) { + free(wsa->deltaBuffer); + free(wsa->offscreenBuffer); + free(wsa->frameOffsTable); + delete wsa; } - - // FIXME: Confirm the default value here? - // LordHoto: What is the 'default' value? 0? - _transparency = -1; } -WSAMovieV1::~WSAMovieV1() { - delete [] _buffer; - delete [] _offsetTable; - delete [] _currentFrame; - delete _ownPalette; +uint16 KyraEngine::wsa_getNumFrames(WSAMovieV1 *wsa) const { + debug(9, "KyraEngine::wsa_getNumFrames(0x%X)", wsa); + uint16 n = 0; + if (wsa) { + n = wsa->numFrames; + } + return n; } -const uint8* WSAMovieV1::loadFrame(uint16 frame, uint16* width, uint16* height) { - if (width) *width = _wsaHeader._width; - if (height) *height = _wsaHeader._height; +void KyraEngine::wsa_play(WSAMovieV1 *wsa, int frameNum, int x, int y, int pageNum) { + debug(9, "KyraEngine::wsa_play(0x%X, %d, %d, %d, %d)", wsa, frameNum, x, y, pageNum); + assert(frameNum <= wsa->numFrames); - if (frame == _prefetchedFrame) { - return _currentFrame; + uint8 *dst; + if (wsa->flags & WF_OFFSCREEN_DECODE) { + dst = wsa->offscreenBuffer; } else { - if (!_currentFrame) { - _currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height]; - assert(_currentFrame); - memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height); - } - - if (frame >= _wsaHeader._numFrames) - return 0; - - uint8* frameData = 0; - static uint8 image40[64000]; // I think this will crash on Plam OS :) - memset(image40, 0, ARRAYSIZE(image40)); - - if (frame == _prefetchedFrame + 1) { - frameData = _buffer + _offsetTable[frame]; - Compression::decode80(frameData, image40); - Compression::decode40(image40, _currentFrame); - } else { - if (_background) { - setImageBackground(_background, _backWidth, _backHeight); + dst = _screen->getPagePtr(pageNum) + y * Screen::SCREEN_W + x; + } + + if (wsa->currentFrame == wsa->numFrames) { + if (!(wsa->flags & WF_NO_FIRST_FRAME)) { + if (wsa->flags & WF_OFFSCREEN_DECODE) { + Screen::decodeFrameDelta(dst, wsa->deltaBuffer); } else { - memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height); - } - - for (uint32 i = 0; i <= frame; ++i) - { - frameData = _buffer + _offsetTable[i]; - Compression::decode80(frameData, image40); - Compression::decode40(image40, _currentFrame); + Screen::decodeFrameDeltaPage(dst, wsa->deltaBuffer, wsa->width); } } - - _prefetchedFrame = frame; - return _currentFrame; + wsa->currentFrame = 0; } - return 0; -} - -void WSAMovieV1::renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame) { - if (!loadFrame(frame, 0, 0)) - return; - - uint8* src = _currentFrame; - uint8* dst = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos]; - uint32 copysize = planepitch - _wsaHeader._xPos; - - if (copysize > _wsaHeader._width) - copysize = _wsaHeader._width; - - if (_transparency == -1) { - for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < planeheight; ++y_) { - memcpy(dst, src, copysize * sizeof(uint8)); - dst += planepitch; - src += _wsaHeader._width; + // try to reduce the number of needed frame operations + int diffCount = ABS(wsa->currentFrame - frameNum); + int frameStep = 1; + int frameCount; + if (wsa->currentFrame < frameNum) { + frameCount = wsa->numFrames - frameNum + wsa->currentFrame; + if (diffCount > frameCount) { + frameStep = -1; + } else { + frameCount = diffCount; } } else { - for (uint16 yadd = 0; yadd < _wsaHeader._height; ++yadd) { - for (uint16 xadd = 0; xadd < copysize; ++xadd) { - if (*src == _transparency) { - ++dst; - ++src; - } else { - *dst++ = *src++; - } - } - - src += _wsaHeader._width - copysize; - dst += planepitch - copysize; + frameCount = wsa->numFrames - wsa->currentFrame + frameNum; + if (frameCount >= diffCount) { + frameStep = -1; + frameCount = diffCount; } } -} - -void WSAMovieV1::setImageBackground(uint8* plane, uint16 planepitch, uint16 height) { - assert(plane); - - _background = plane; - _backWidth = planepitch; _backHeight = height; - - if (!_currentFrame) { - _currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height]; - assert(_currentFrame); - } - - memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height); - - uint8* src = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos]; - uint8* dst = _currentFrame; - uint32 copysize = planepitch - _wsaHeader._xPos; - - if (copysize > _wsaHeader._width) - copysize = _wsaHeader._width; - - // now copy the rect of the plane - for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) { - memcpy(dst, src, copysize * sizeof(uint8)); - dst += _wsaHeader._width; - src += planepitch; - } - - for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) { - for (uint16 x = 0; x < _wsaHeader._width; ++x) { - _currentFrame[y_ * _wsaHeader._width + x] ^= 0; - } - } - - _prefetchedFrame = 0xFFFE; -} - -// Kyrandia 2+ Movies -WSAMovieV2::WSAMovieV2(uint8* data, uint32 size) { - if (!data) { - error("resource created without data"); - } - - _background = 0; - _currentFrame = 0; - _ownPalette = 0; - _offsetTable = 0; - _prefetchedFrame = 0xFFFE; - _looping = false; - _buffer = data; - - // I like these Streams .... =) - Common::MemoryReadStream datastream(data, size); - - datastream.read(&_wsaHeader, sizeof(_wsaHeader)); - - // check for version - if (!_wsaHeader._type) { - error("loading a WSA version 1 with the WSA version 2 loader"); - } - - uint16 offsetAdd = 0; - - // checks now for own palette - if (_wsaHeader._type % 2) { - // don't now if this will work right, because a few lines before we use - // _wsaHeader._type for detect the version of the WSA movie, - // but this code was from FreeKyra Tools so I think it will work - - // if this is a packed palette we have a problem :) - offsetAdd = 768 /* 0x300 */; - } - - _offsetTable = new uint32[_wsaHeader._numFrames + 2]; - assert(_offsetTable); - - // loads the offset table - for (uint32 tmp = 0; tmp < (uint32)_wsaHeader._numFrames + 2; ++tmp) { - _offsetTable[tmp] = datastream.readUint32LE() + offsetAdd; - } - - if (offsetAdd) { - uint8* palbuffer = new uint8[offsetAdd]; - assert(palbuffer); - - datastream.read(palbuffer, offsetAdd); - - _ownPalette = new Palette(palbuffer, offsetAdd); - assert(_ownPalette); - } - - if (_offsetTable[_wsaHeader._numFrames + 1] - offsetAdd) { - ++_wsaHeader._numFrames; - _looping = true; - } - - _frameCount = _wsaHeader._numFrames; -} - -WSAMovieV2::~WSAMovieV2() { - delete [] _buffer; - delete [] _offsetTable; - delete [] _currentFrame; - delete _ownPalette; -} - -const uint8* WSAMovieV2::loadFrame(uint16 frame, uint16* width, uint16* height) { - if (width) *width = _wsaHeader._width; - if (height) *height = _wsaHeader._height; - - if (frame == _prefetchedFrame) { - return _currentFrame; - } else { - if (!_currentFrame) { - _currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height]; - assert(_currentFrame); - memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height); - } - - if (frame >= _wsaHeader._numFrames) - return 0; - - uint8* frameData = 0; - static uint8 image40[64000]; // I think this will crash on Plam OS :) - memset(image40, 0, ARRAYSIZE(image40)); - - if (frame == _prefetchedFrame + 1) { - frameData = _buffer + _offsetTable[frame]; - Compression::decode80(frameData, image40); - Compression::decode40(image40, _currentFrame); - } else { - if (_background) { - setImageBackground(_background, _backWidth, _backHeight); - } else { - memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height); - } - - for (uint32 i = 0; i <= frame; ++i) - { - frameData = _buffer + _offsetTable[i]; - Compression::decode80(frameData, image40); - Compression::decode40(image40, _currentFrame); + + // process + if (frameStep > 0) { + uint16 cf = wsa->currentFrame; + while (frameCount--) { + cf += frameStep; + wsa_processFrame(wsa, cf, dst); + if (cf == wsa->numFrames) { + cf = 0; } } - - _prefetchedFrame = frame; - return _currentFrame; - } - - return 0; -} - -void WSAMovieV2::renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame) { - if (!loadFrame(frame, 0, 0)) - return; - - uint8* src = _currentFrame; - uint8* dst = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos]; - uint32 copysize = planepitch - _wsaHeader._xPos; - - if (copysize > _wsaHeader._width) - copysize = _wsaHeader._width; - - if (_transparency == -1) { - for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < planeheight; ++y_) { - memcpy(dst, src, copysize * sizeof(uint8)); - dst += planepitch; - src += _wsaHeader._width; - } } else { - for (uint16 yadd = 0; yadd < _wsaHeader._height; ++yadd) { - for (uint16 xadd = 0; xadd < copysize; ++xadd) { - if (*src == _transparency) { - ++dst; - ++src; - } else { - *dst++ = *src++; - } + uint16 cf = wsa->currentFrame; + while (frameCount--) { + if (cf == 0) { + cf = wsa->numFrames; } - - src += _wsaHeader._width - copysize; - dst += planepitch - copysize; + wsa_processFrame(wsa, cf, dst); + cf += frameStep; } } -} - -void WSAMovieV2::setImageBackground(uint8* plane, uint16 planepitch, uint16 height) { - assert(plane); - - _background = plane; - _backWidth = planepitch; _backHeight = height; - - if (!_currentFrame) { - _currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height]; - assert(_currentFrame); - } - - memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height); - - uint8* src = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos]; - uint8* dst = _currentFrame; - uint32 copysize = planepitch - _wsaHeader._xPos; - - if (copysize > _wsaHeader._width) - copysize = _wsaHeader._width; - - // now copy the rect of the plane - for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) { - memcpy(dst, src, copysize * sizeof(uint8)); - dst += _wsaHeader._width; - src += planepitch; + + // display + wsa->currentFrame = frameNum; + if (wsa->flags & WF_OFFSCREEN_DECODE) { + _screen->copyBlockToPage(pageNum, x, y, wsa->width, wsa->height, wsa->offscreenBuffer); } +} - for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) { - for (uint16 x = 0; x < _wsaHeader._width; ++x) { - _currentFrame[y_ * _wsaHeader._width + x] ^= 0; - } +void KyraEngine::wsa_processFrame(WSAMovieV1 *wsa, int frameNum, uint8 *dst) { + debug(9, "KyraEngine::wsa_processFrame(0x%X, %d, 0x%X)", wsa, frameNum, dst); + assert(frameNum <= wsa->numFrames); + const uint8 *src = wsa->frameData + wsa->frameOffsTable[frameNum]; + Screen::decodeFrame4(src, wsa->deltaBuffer, wsa->deltaBufferSize); + if (wsa->flags & WF_OFFSCREEN_DECODE) { + Screen::decodeFrameDelta(dst, wsa->deltaBuffer); + } else { + Screen::decodeFrameDeltaPage(dst, wsa->deltaBuffer, wsa->width); } - - _prefetchedFrame = 0xFFFE; } + } // end of namespace Kyra - diff --git a/kyra/wsamovie.h b/kyra/wsamovie.h index 34de2e540d..626acdca58 100644 --- a/kyra/wsamovie.h +++ b/kyra/wsamovie.h @@ -26,110 +26,25 @@ namespace Kyra { -// a generic movie -class Movie { - -public: - - virtual ~Movie() { _transparency = -1; _ownPalette = 0; _frameCount = 0; } - - virtual void renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame) = 0; - virtual const uint8* loadFrame(uint16 frame, uint16* width = 0, uint16* height = 0) = 0; - virtual uint16 countFrames(void) { return _frameCount; } - - // could be deleted(not imdiantly maybe it's needed sometime) - virtual void transparency(int16 color) { _transparency = color; } - virtual void position(uint16 x, uint16 y) = 0; - - virtual bool hasPalette(void) { return (_ownPalette != 0); } - virtual Palette* palette(void) { return _ownPalette; } - - virtual bool looping(void) { return false; } - virtual uint32 frameChange(void) { return 100; } - virtual void setImageBackground(uint8* plane, uint16 planepitch, uint16 height) {}; - -protected: - int16 _transparency; - uint16 _frameCount; - Palette* _ownPalette; +enum WSAFlags { + WF_OFFSCREEN_DECODE = 0x10, + WF_NO_FIRST_FRAME = 0x40, + WF_HAS_PALETTE = 0x100 }; -// movie format for Kyrandia 1 -class WSAMovieV1 : public Movie { - -public: - - WSAMovieV1(uint8* data, uint32 size, uint8 gameid); - ~WSAMovieV1(); - - void renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame); - const uint8* loadFrame(uint16 frame, uint16* width, uint16* height); - void setImageBackground(uint8* plane, uint16 planepitch, uint16 height); - - void position(uint16 x, uint16 y) { _wsaHeader._xPos = x; _wsaHeader._yPos = y; } -protected: - - uint8* _buffer; - -#pragma START_PACK_STRUCTS - struct WSAHeader { - uint16 _numFrames; // All right - uint16 _width; // All right - uint16 _height; // All right - uint8 _xPos; // is wrong - uint8 _yPos; // is wrong - uint16 _delta; // is wrong - uint16 _type; // is wrong - } GCC_PACK _wsaHeader; -#pragma END_PACK_STRUCTS - - uint32* _offsetTable; - - uint8* _currentFrame; - uint16 _prefetchedFrame; - - uint8* _background; // only a pointer to the screen - uint16 _backWidth, _backHeight; +struct WSAMovieV1 { + uint16 currentFrame; + uint16 numFrames; + uint16 width; + uint16 height; + uint16 flags; + uint8 *deltaBuffer; + uint32 deltaBufferSize; + uint8 *offscreenBuffer; + uint32 *frameOffsTable; + uint8 *frameData; }; -// movie format for Kyrandia 2+ -class WSAMovieV2 : public Movie { - -public: - WSAMovieV2(uint8* data, uint32 size); - ~WSAMovieV2(); - - void renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame); - const uint8* loadFrame(uint16 frame, uint16* width, uint16* height); - void setImageBackground(uint8* plane, uint16 planepitch, uint16 height); - - void position(uint16 x, uint16 y) { _wsaHeader._xPos = x; _wsaHeader._yPos = y; } - bool looping(void) { return _looping; } -protected: - - uint8* _buffer; - - struct WSAHeader { - uint16 _numFrames; // All right - uint16 _width; // should be right - uint16 _height; // should be right - uint16 _xPos; // could be wrong - uint16 _yPos; // could be wrong - uint16 _delta; // could be wrong - uint16 _type; // should be right - } GCC_PACK _wsaHeader; - - uint32* _offsetTable; - - uint8* _currentFrame; - uint16 _prefetchedFrame; - - uint8* _background; // only a pointer to the screen - uint16 _backWidth, _backHeight; - - bool _looping; -}; } // end of namespace Kyra #endif - |