diff options
Diffstat (limited to 'engines/kyra')
-rw-r--r-- | engines/kyra/gui.cpp | 172 | ||||
-rw-r--r-- | engines/kyra/kyra.cpp | 24 | ||||
-rw-r--r-- | engines/kyra/kyra.h | 13 | ||||
-rw-r--r-- | engines/kyra/kyra2.cpp | 67 | ||||
-rw-r--r-- | engines/kyra/kyra2.h | 51 | ||||
-rw-r--r-- | engines/kyra/kyra3.cpp | 240 | ||||
-rw-r--r-- | engines/kyra/kyra3.h | 19 | ||||
-rw-r--r-- | engines/kyra/plugin.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/screen.cpp | 12 | ||||
-rw-r--r-- | engines/kyra/screen.h | 4 | ||||
-rw-r--r-- | engines/kyra/sequences_v2.cpp | 195 | ||||
-rw-r--r-- | engines/kyra/staticres.cpp | 88 | ||||
-rw-r--r-- | engines/kyra/wsamovie.cpp | 14 | ||||
-rw-r--r-- | engines/kyra/wsamovie.h | 8 |
14 files changed, 623 insertions, 286 deletions
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index f59f1811a1..9fb2fd3a02 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -1471,6 +1471,178 @@ void KyraEngine::gui_restorePalette() { _screen->fadePalette(_screen->_currentPalette, 2); } +#pragma mark - + +// Kyra 2 and 3 main menu + +void KyraEngine::gui_updateMainMenuAnimation() { + _screen->updateScreen(); +} + +bool KyraEngine::gui_mainMenuGetInput() { + OSystem::Event event; + + while (_system->pollEvent(event)) { + switch (event.type) { + case OSystem::EVENT_QUIT: + quitGame(); + break; + case OSystem::EVENT_MOUSEMOVE: + _mouseX = event.mouse.x; + _mouseY = event.mouse.y; + break; + case OSystem::EVENT_LBUTTONUP: + return true; + default: + break; + } + } + return false; +} + +int KyraEngine::gui_handleMainMenu() { + debugC(9, kDebugLevelMain, "KyraEngine::gui_handleMainMenu()"); + int command = -1; + + uint8 colorMap[16]; + memset(colorMap, 0, sizeof(colorMap)); + _screen->setTextColorMap(colorMap); + + const char * const *strings = &_mainMenuStrings[_lang << 2]; + Screen::FontId oldFont = _screen->setFont(Screen::FID_8_FNT); + int charWidthBackUp = _screen->_charWidth; + + _screen->_charWidth = -2; + _screen->setScreenDim(3); + int backUpX = _screen->_curDim->sx; + int backUpY = _screen->_curDim->sy; + int backUpWidth = _screen->_curDim->w; + int backUpHeight = _screen->_curDim->h; + _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 0, 3); + + int x = _screen->_curDim->sx << 3; + int y = _screen->_curDim->sy; + int width = _screen->_curDim->w << 3; + int height = _screen->_curDim->h; + + gui_drawMainBox(x, y, width, height, 1); + gui_drawMainBox(x + 1, y + 1, width - 2, height - 2, 0); + + int selected = 0; + + gui_drawMainMenu(strings, selected); + + _screen->showMouse(); + + int fh = _screen->getFontHeight(); + int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3; + + Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * 4); + + while (!_quitFlag) { + gui_updateMainMenuAnimation(); + bool mousePressed = gui_mainMenuGetInput(); + + if (menuRect.contains(mouseX(), mouseY())) { + int item = (mouseY() - menuRect.top) / fh; + + if (item != selected) { + gui_printString(strings[selected], textPos, menuRect.top + selected * fh, 0x80, 0, 5); + gui_printString(strings[item], textPos, menuRect.top + item * fh, 0xFF, 0, 5); + + selected = item; + } + + if (mousePressed) { + // TODO: Flash the text + command = item; + break; + } + } + _system->delayMillis(10); + } + + if (_quitFlag) + command = -1; + + _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 3, 0); + _screen->_charWidth = charWidthBackUp; + _screen->setFont(oldFont); + + return command; +} + +void KyraEngine::gui_drawMainMenu(const char * const *strings, int select) { + debugC(9, kDebugLevelMain, "KyraEngine::gui_drawMainMenu(%p)", (const void*)strings); + static const uint16 menuTable[] = { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF, 0x00, 0x01, 0x02, 0x03 }; + + int top = _screen->_curDim->sy; + top += menuTable[1]; + + for (int i = 0; i < menuTable[3]; ++i) { + int curY = top + i * _screen->getFontHeight(); + int color = (i == select) ? menuTable[6] : menuTable[5]; + gui_printString(strings[i], ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5); + } +} + +void KyraEngine::gui_drawMainBox(int x, int y, int w, int h, int fill) { + debugC(9, kDebugLevelMain, "KyraEngine::gui_drawMainBox(%d, %d, %d, %d, %d)", x, y, w, h, fill); + static const uint8 kyra3ColorTable[] = { 0x16, 0x19, 0x1A, 0x16 }; + static const uint8 kyra2ColorTable[] = { 0x0, 0x19, 0x28, 0xc8 }; + + const uint8 *colorTable; + if (_game == GI_KYRA3) + colorTable = kyra3ColorTable; + else + colorTable = kyra2ColorTable; + + --w; --h; + + if (fill) { + _screen->fillRect(x, y, x+w, y+h, colorTable[0]); + } + + _screen->drawClippedLine(x, y+h, x+w, y+h, colorTable[1]); + _screen->drawClippedLine(x+w, y, x+w, y+h, colorTable[1]); + _screen->drawClippedLine(x, y, x+w, y, colorTable[2]); + _screen->drawClippedLine(x, y, x, y+h, colorTable[2]); + + _screen->setPagePixel(_screen->_curPage, x, y+h, colorTable[3]); + _screen->setPagePixel(_screen->_curPage, x+w, y, colorTable[3]); +} + +void KyraEngine::gui_printString(const char *format, int x, int y, int col1, int col2, int flags, ...) { + debugC(9, kDebugLevelMain, "KyraEngine::gui_printString('%s', %d, %d, %d, %d, %d, ...)", format, x, y, col1, col2, flags); + if (!format) + return; + + char string[512]; + va_list vaList; + va_start(vaList, flags); + vsprintf(string, format, vaList); + va_end(vaList); + + if (flags & 1) { + x -= _screen->getTextWidth(string) >> 1; + } + + if (flags & 2) { + x -= _screen->getTextWidth(string); + } + + if (flags & 4) { + _screen->printText(string, x - 1, y, 240, col2); + _screen->printText(string, x, y + 1, 240, col2); + } + + if (flags & 8) { + _screen->printText(string, x - 1, y, 227, col2); + _screen->printText(string, x, y + 1, 227, col2); + } + + _screen->printText(string, x, y, col1, col2); +} } // end of namespace Kyra diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp index f67da7fa4d..241296173a 100644 --- a/engines/kyra/kyra.cpp +++ b/engines/kyra/kyra.cpp @@ -319,6 +319,30 @@ int KyraEngine::init() { _gameSpeed = 60; _tickLength = (uint8)(1000.0 / _gameSpeed); + _lang = 0; + Common::Language lang = Common::parseLanguage(ConfMan.get("language")); + + switch (lang) { + case Common::EN_ANY: + case Common::EN_USA: + case Common::EN_GRB: + _lang = 0; + break; + + case Common::FR_FRA: + _lang = 1; + break; + + case Common::DE_DEU: + _lang = 2; + break; + + default: + warning("unsupported language, switching back to English"); + _lang = 0; + break; + } + return 0; } diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h index 1dd4289907..2290e9eb36 100644 --- a/engines/kyra/kyra.h +++ b/engines/kyra/kyra.h @@ -696,6 +696,18 @@ protected: void gui_restorePalette(); void gui_setupControls(Menu &menu); + // Kyra 2 and 3 main menu + + static const char *_mainMenuStrings[]; + virtual void gui_initMainMenu() {}; + int gui_handleMainMenu(); + virtual void gui_updateMainMenuAnimation(); + void gui_drawMainMenu(const char * const *strings, int select); + void gui_drawMainBox(int x, int y, int w, int h, int fill); + bool gui_mainMenuGetInput(); + + void gui_printString(const char *string, int x, int y, int col1, int col2, int flags, ...); + uint8 _game; bool _quitFlag; bool _skipFlag; @@ -711,6 +723,7 @@ protected: uint16 _gameSpeed; uint16 _tickLength; uint32 _features; + int _lang; int _mouseX, _mouseY; int8 _itemInHand; int _mouseState; diff --git a/engines/kyra/kyra2.cpp b/engines/kyra/kyra2.cpp index a29965e6ac..a4c74ad21d 100644 --- a/engines/kyra/kyra2.cpp +++ b/engines/kyra/kyra2.cpp @@ -22,22 +22,79 @@ #include "kyra/kyra.h" #include "kyra/kyra2.h" +#include "kyra/screen.h" +#include "kyra/resource.h" +#include "kyra/wsamovie.h" +#include "kyra/sound.h" #include "common/system.h" namespace Kyra { -KyraEngine_v2::KyraEngine_v2(OSystem *system) - : KyraEngine(system) { +KyraEngine_v2::KyraEngine_v2(OSystem *system) : KyraEngine(system) { + + memset(_gameShapes, 0, sizeof(_gameShapes)); + _mouseSHPBuf = 0; } KyraEngine_v2::~KyraEngine_v2() { + delete [] _mouseSHPBuf; } -int KyraEngine_v2::go() { - seq_menu(); - waitForEvent(); +int KyraEngine_v2::init() { + KyraEngine::init(); + _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); + _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); + _screen->loadFont(Screen::FID_BOOKFONT_FNT, "BOOKFONT.FNT"); + _screen->setAnimBlockPtr(3500); + _screen->setScreenDim(0); + + _mouseSHPBuf = _res->fileData("PWGMOUSE.SHP", 0); + assert(_mouseSHPBuf); + + for (int i = 0; i < 2; i++) { + _gameShapes[i] = _screen->getPtrToShape(_mouseSHPBuf, i); + assert(_gameShapes[i]); + } + + _screen->setMouseCursor(0, 0, _gameShapes[0]); + return 0; +} + +int KyraEngine_v2::go() { + _sound->loadMusicFile("K2INTRO"); + // Temporary measure to work around the fact that there's two files called DRAGON.WSA. + _res->unloadPakFile("OUTFARM.PAK"); + + seq_playSequences(kSequenceVirgin, kSequenceWestwood); + mainMenu(); + return 0; } +void KyraEngine_v2::mainMenu() { + bool running = true; + + while (running && !_quitFlag) { + seq_playSequences(kSequenceTitle); + _screen->showMouse(); + + switch (gui_handleMainMenu()) { + case 0: + break; + case 1: + seq_playSequences(kSequenceOverview); + break; + case 2: + break; + case 3: + running = false; + break; + default: + break; + } + _screen->hideMouse(); + } +} + } // end of namespace Kyra diff --git a/engines/kyra/kyra2.h b/engines/kyra/kyra2.h index 27f4b5ce44..3f0122cd67 100644 --- a/engines/kyra/kyra2.h +++ b/engines/kyra/kyra2.h @@ -25,6 +25,34 @@ namespace Kyra { +enum kSequences { + kSequenceVirgin = 0, + kSequenceWestwood = 1, + kSequenceTitle = 2, + kSequenceOverview = 3 +}; + +class WSAMovieV2; +class KyraEngine_v2; +struct ActiveWSA { + WSAMovieV2 *movie; + uint16 currentFrame; + uint16 endFrame; + uint16 frameDelay; + uint32 nextFrame; +}; + +struct Sequence { + uint8 type; + const char *filename; + int (KyraEngine_v2::*callback)(int); + uint8 frameDelay; + uint16 duration; + uint8 numFrames; + bool timeOut; + bool fadeOut; +}; + class KyraEngine_v2 : public KyraEngine { public: KyraEngine_v2(OSystem *system); @@ -34,8 +62,27 @@ public: int go(); -protected: - void seq_menu(); +private: + void seq_playSequences(int startSeq, int endSeq = -1); + int seq_introWestwood(int seqNum); + int seq_introTitle(int seqNum); + int seq_introOverview(int seqNum); + void seq_loadWSA(int wsaNum, const char *filename, int frameDelay); + void seq_unloadWSA(int wsaNum); + void seq_playWSAs(); + + void mainMenu(); + int init(); + + ActiveWSA *_activeWSA; + uint8 *_gameShapes[50]; + uint8 *_mouseSHPBuf; + + static const char *_introSoundList[]; + static const int _introSoundListSize; + static const char *_introStrings[]; + static const int _introStringsSize; + }; } // end of namespace Kyra diff --git a/engines/kyra/kyra3.cpp b/engines/kyra/kyra3.cpp index 37c6fd4775..83b71b035c 100644 --- a/engines/kyra/kyra3.cpp +++ b/engines/kyra/kyra3.cpp @@ -86,30 +86,6 @@ KyraEngine_v3::~KyraEngine_v3() { int KyraEngine_v3::setupGameFlags() { _game = GI_KYRA3; - _lang = 0; - Common::Language lang = Common::parseLanguage(ConfMan.get("language")); - - switch (lang) { - case Common::EN_ANY: - case Common::EN_USA: - case Common::EN_GRB: - _lang = 0; - break; - - case Common::FR_FRA: - _lang = 1; - break; - - case Common::DE_DEU: - _lang = 2; - break; - - default: - warning("unsupported language, switching back to English"); - _lang = 0; - break; - } - return 0; } @@ -119,6 +95,8 @@ Movie *KyraEngine_v3::createWSAMovie() { int KyraEngine_v3::init() { KyraEngine::init(); + + gui_initMainMenu(); _soundDigital = new SoundDigital(this, _mixer); assert(_soundDigital); @@ -159,10 +137,10 @@ int KyraEngine_v3::go() { uint8 *pal = _screen->getPalette(1); assert(pal); - Movie *logo = createWSAMovie(); - assert(logo); - logo->open("REVENGE.WSA", 1, pal); - assert(logo->opened()); + _mainMenuLogo = createWSAMovie(); + assert(_mainMenuLogo); + _mainMenuLogo->open("REVENGE.WSA", 1, pal); + assert(_mainMenuLogo->opened()); bool running = true; while (running && !_quitFlag) { @@ -176,27 +154,27 @@ int KyraEngine_v3::go() { // XXX playMenuAudioFile(); - logo->setX(0); logo->setY(0); - logo->setDrawPage(0); + _mainMenuLogo->setX(0); _mainMenuLogo->setY(0); + _mainMenuLogo->setDrawPage(0); for (int i = 0; i < 64 && !_quitFlag; ++i) { uint32 nextRun = _system->getMillis() + 3 * _tickLength; - logo->displayFrame(i); + _mainMenuLogo->displayFrame(i); _screen->updateScreen(); delayUntil(nextRun); } for (int i = 64; i > 29 && !_quitFlag; --i) { uint32 nextRun = _system->getMillis() + 3 * _tickLength; - logo->displayFrame(i); + _mainMenuLogo->displayFrame(i); _screen->updateScreen(); delayUntil(nextRun); } - - switch (handleMainMenu(logo)) { + + switch (gui_handleMainMenu()) { case 0: - delete logo; - logo = 0; + delete _mainMenuLogo; + _mainMenuLogo = 0; preinit(); realInit(); // XXX @@ -208,13 +186,17 @@ int KyraEngine_v3::go() { break; case 2: - //delete logo; - //logo = 0; + //delete _mainMenuLogo; + //_mainMenuLogo = 0; //show load dialog //running = false; break; case 3: + _soundDigital->beginFadeOut(_musicSoundChannel); + _screen->fadeToBlack(); + _soundDigital->stopSound(_musicSoundChannel); + _musicSoundChannel = -1; running = false; break; @@ -222,7 +204,7 @@ int KyraEngine_v3::go() { break; } } - delete logo; + delete _mainMenuLogo; return 0; } @@ -347,169 +329,35 @@ int KyraEngine_v3::musicUpdate(int forceRestart) { #pragma mark - -int KyraEngine_v3::handleMainMenu(Movie *logo) { - debugC(9, kDebugLevelMain, "KyraEngine::handleMainMenu(%p)", (const void*)logo); - int command = -1; - - uint8 colorMap[16]; - memset(colorMap, 0, sizeof(colorMap)); - _screen->setTextColorMap(colorMap); - - const char * const *strings = &_mainMenuStrings[_lang << 2]; - Screen::FontId oldFont = _screen->setFont(Screen::FID_8_FNT); - int charWidthBackUp = _screen->_charWidth; - - _screen->_charWidth = -2; - _screen->setScreenDim(3); - int backUpX = _screen->_curDim->sx; - int backUpY = _screen->_curDim->sy; - int backUpWidth = _screen->_curDim->w; - int backUpHeight = _screen->_curDim->h; - _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 0, 3); - - int x = _screen->_curDim->sx << 3; - int y = _screen->_curDim->sy; - int width = _screen->_curDim->w << 3; - int height = _screen->_curDim->h; - - drawMainBox(x, y, width, height, 1); - drawMainBox(x + 1, y + 1, width - 2, height - 2, 0); - - int curFrame = 29, frameAdd = 1; - uint32 nextRun = 0; - - int selected = 0; - - drawMainMenu(strings, selected); - - _system->warpMouse(300, 180); - _screen->showMouse(); - - int fh = _screen->getFontHeight(); - int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3; - - Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * 4); - - while (command == -1 && !_quitFlag) { - // yes 2 * _tickLength here not 3 * like in the first draw - nextRun = _system->getMillis() + 2 * _tickLength; - logo->displayFrame(curFrame); - _screen->updateScreen(); - - curFrame += frameAdd; - if (curFrame < 29) { - curFrame = 29; - frameAdd = 1; - } else if (curFrame > 63) { - curFrame = 64; - frameAdd = -1; - } - - // XXX - - while (_system->getMillis() < nextRun) { - // XXX - _screen->updateScreen(); - if ((int32)nextRun - (int32)_system->getMillis() >= 10) - delay(10); - } - - if (menuRect.contains(mouseX(), mouseY())) { - int item = (mouseY() - menuRect.top) / fh; - - if (item != selected) { - gui_printString(strings[selected], textPos, menuRect.top + selected * fh, 0x80, 0, 5); - gui_printString(strings[item], textPos, menuRect.top + item * fh, 0xFF, 0, 5); - - selected = item; - } - - if (_mousePressFlag) { - // TODO: Flash the text - command = item; - } - } - } - - if (_quitFlag) - command = -1; - - _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 3, 0); - _screen->_charWidth = charWidthBackUp; - _screen->setFont(oldFont); - - if (command == 3) { - _soundDigital->beginFadeOut(_musicSoundChannel); - _screen->fadeToBlack(); - _soundDigital->stopSound(_musicSoundChannel); - _musicSoundChannel = -1; - } - - return command; -} - -void KyraEngine_v3::drawMainMenu(const char * const *strings, int select) { - debugC(9, kDebugLevelMain, "KyraEngine::drawMainMenu(%p)", (const void*)strings); - static const uint16 menuTable[] = { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF, 0x00, 0x01, 0x02, 0x03 }; - - int top = _screen->_curDim->sy; - top += menuTable[1]; - - for (int i = 0; i < menuTable[3]; ++i) { - int curY = top + i * _screen->getFontHeight(); - int color = (i == select) ? menuTable[6] : menuTable[5]; - gui_printString(strings[i], ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5); - } +void KyraEngine_v3::gui_initMainMenu() { + KyraEngine::gui_initMainMenu(); + _mainMenuFrame = 29; + _mainMenuFrameAdd = 1; } -void KyraEngine_v3::drawMainBox(int x, int y, int w, int h, int fill) { - debugC(9, kDebugLevelMain, "KyraEngine::drawMainBox(%d, %d, %d, %d, %d)", x, y, w, h, fill); - static const uint8 colorTable[] = { 0x16, 0x19, 0x1A, 0x16 }; - --w; --h; - - if (fill) { - _screen->fillRect(x, y, x+w, y+h, colorTable[0]); - } - - _screen->drawClippedLine(x, y+h, x+w, y+h, colorTable[1]); - _screen->drawClippedLine(x+w, y, x+w, y+h, colorTable[1]); - _screen->drawClippedLine(x, y, x+w, y, colorTable[2]); - _screen->drawClippedLine(x, y, x, y+h, colorTable[2]); +void KyraEngine_v3::gui_updateMainMenuAnimation() { + uint32 nextRun = 0; - _screen->setPagePixel(_screen->_curPage, x, y+h, colorTable[3]); - _screen->setPagePixel(_screen->_curPage, x+w, y, colorTable[3]); -} - -void KyraEngine_v3::gui_printString(const char *format, int x, int y, int col1, int col2, int flags, ...) { - debugC(9, kDebugLevelMain, "KyraEngine::gui_printString('%s', %d, %d, %d, %d, %d, ...)", format, x, y, col1, col2, flags); - if (!format) + uint32 now = _system->getMillis(); + if (now < nextRun) return; + + // yes 2 * _tickLength here not 3 * like in the first draw + nextRun = now + 2 * _tickLength; - char string[512]; - va_list vaList; - va_start(vaList, flags); - vsprintf(string, format, vaList); - va_end(vaList); - - if (flags & 1) { - x -= _screen->getTextWidth(string) >> 1; - } - - if (flags & 2) { - x -= _screen->getTextWidth(string); - } - - if (flags & 4) { - _screen->printText(string, x - 1, y, 240, col2); - _screen->printText(string, x, y + 1, 240, col2); - } - - if (flags & 8) { - _screen->printText(string, x - 1, y, 227, col2); - _screen->printText(string, x, y + 1, 227, col2); + _mainMenuLogo->displayFrame(_mainMenuFrame); + _screen->updateScreen(); + + _mainMenuFrame += _mainMenuFrameAdd; + if (_mainMenuFrame < 29) { + _mainMenuFrame = 29; + _mainMenuFrameAdd = 1; + } else if (_mainMenuFrame > 63) { + _mainMenuFrame = 64; + _mainMenuFrameAdd = -1; } - - _screen->printText(string, x, y, col1, col2); + + // XXX } #pragma mark - diff --git a/engines/kyra/kyra3.h b/engines/kyra/kyra3.h index e15f195a85..6663e0dccd 100644 --- a/engines/kyra/kyra3.h +++ b/engines/kyra/kyra3.h @@ -52,8 +52,6 @@ private: SoundDigital *_soundDigital; - int _lang; - // sound specific private: void playMenuAudioFile(); @@ -71,17 +69,11 @@ private: int musicUpdate(int forceRestart); - // gui/menu specific -private: - static const char *_mainMenuStrings[]; - int handleMainMenu(Movie *logo); - void drawMainMenu(const char * const *strings, int select); - void drawMainBox(int x, int y, int w, int h, int fill); - - void gui_printString(const char *string, int x, int y, int col1, int col2, int flags, ...); + virtual void gui_initMainMenu(); + virtual void gui_updateMainMenuAnimation(); // unknown -private: +private: uint8 *_unkPage1; uint8 *_unkPage2; @@ -96,6 +88,11 @@ private: uint8 *_unkShapeTable[20]; + // main menu + Movie *_mainMenuLogo; + int _mainMenuFrame; + int _mainMenuFrameAdd; + // translation stuff uint8 *_scoreFile; uint8 *_cCodeFile; diff --git a/engines/kyra/plugin.cpp b/engines/kyra/plugin.cpp index d9908c396e..0ed245cebb 100644 --- a/engines/kyra/plugin.cpp +++ b/engines/kyra/plugin.cpp @@ -84,7 +84,7 @@ const GameSettings kyra_games[] = { "fb722947d94897512b13b50cc84fd648", "DEMO1.WSA" }, // kyra 2 games - { "kyra2", "The Legend of Kyrandia: The Hand of Fate", GI_KYRA2, GF_ENGLISH, // CD version? Floppy version? + { "kyra2", "The Legend of Kyrandia: The Hand of Fate", GI_KYRA2, GF_ENGLISH | GF_TALKIE, "28cbad1c5bf06b2d3825ae57d760d032", "FATE.PAK" }, // kyra 3 games diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 0e62402181..b01116ce3a 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -188,16 +188,16 @@ void Screen::setPagePixel(int pageNum, int x, int y, uint8 color) { _pagePtrs[pageNum][y * SCREEN_W + x] = color; } -void Screen::fadeFromBlack() { +void Screen::fadeFromBlack(int delay) { debugC(9, kDebugLevelScreen, "Screen::fadeFromBlack()"); - fadePalette(_currentPalette, 0x54); + fadePalette(_currentPalette, delay); } -void Screen::fadeToBlack() { +void Screen::fadeToBlack(int delay) { debugC(9, kDebugLevelScreen, "Screen::fadeToBlack()"); uint8 blackPal[768]; memset(blackPal, 0, 768); - fadePalette(blackPal, 0x54); + fadePalette(blackPal, delay); } void Screen::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) { @@ -793,7 +793,7 @@ void Screen::drawChar(uint8 c, int x, int y) { void Screen::setScreenDim(int dim) { debugC(9, kDebugLevelScreen, "setScreenDim(%d)", dim); - if (_vm->game() != GI_KYRA3) { + if (_vm->game() == GI_KYRA1) { assert(dim < _screenDimTableCount); _curDim = &_screenDimTable[dim]; } else { @@ -1900,7 +1900,7 @@ void Screen::setMouseCursor(int x, int y, byte *shape) { int mouseHeight = *(shape+2); int mouseWidth = (READ_LE_UINT16(shape + 3)) + 2; - if (_vm->features() & GF_TALKIE) + if (_vm->game() & GI_KYRA1 && _vm->features() & GF_TALKIE) shape -= 2; uint8 *cursor = (uint8 *)malloc(mouseHeight * mouseWidth); diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index 541ced494a..01e8b03437 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -100,8 +100,8 @@ public: void clearCurPage(); uint8 getPagePixel(int pageNum, int x, int y); void setPagePixel(int pageNum, int x, int y, uint8 color); - void fadeFromBlack(); - void fadeToBlack(); + void fadeFromBlack(int delay=0x54); + void fadeToBlack(int delay=0x54); void fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime); void fadePalette(const uint8 *palData, int delay); void setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue); diff --git a/engines/kyra/sequences_v2.cpp b/engines/kyra/sequences_v2.cpp index 45757f6ba2..e94b850e8d 100644 --- a/engines/kyra/sequences_v2.cpp +++ b/engines/kyra/sequences_v2.cpp @@ -30,74 +30,163 @@ namespace Kyra { -void KyraEngine_v2::seq_menu() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_menu()"); - - _sound->loadMusicFile("K2INTRO"); - _screen->loadBitmap("VIRGIN.CPS", 7, 7, _screen->_currentPalette); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0); - _screen->updateScreen(); - _screen->fadeFromBlack(); - delay(60 * _tickLength); - _screen->fadeToBlack(); - _screen->clearCurPage(); - - if (_quitFlag) - return; +void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) { + if (endSeq == -1) + endSeq = startSeq; + + assert(startSeq >= 0 && endSeq < 4 && startSeq <= endSeq); + + static const Sequence sequences[] = { + // type, filename, callback, framedelay, duration, numframes, fadeOut, timeOut + {2, "virgin.cps", 0, 100, 0, 1, true, true}, + {1, "westwood.wsa", &KyraEngine_v2::seq_introWestwood, 6, 160, 18, true, true}, + {1, "title.wsa", &KyraEngine_v2::seq_introTitle, 6, 10, 26, false, false}, + {2, "over.cps", &KyraEngine_v2::seq_introOverview, 16, 30, 1, false, true} + }; + + _activeWSA = new ActiveWSA[8]; + assert(_activeWSA); + memset(_activeWSA, 0, sizeof(ActiveWSA) * 8); + + _screen->hideMouse(); uint8 pal[768]; - int i; - - WSAMovieV2 *title = new WSAMovieV2(this); - title->setDrawPage(0); - - title->open("WESTWOOD.WSA", 0, pal); - assert(title->opened()); - - title->setX(0); title->setY(0); - title->displayFrame(0); - _screen->updateScreen(); - _screen->fadePalette(pal, 0x54); - - _sound->playTrack(2); - - for (i = 1; i < 18 && !_quitFlag; ++i) { - uint32 nextRun = _system->getMillis() + 6 * _tickLength; - title->displayFrame(i); + memset(pal, 0, sizeof(pal)); + _screen->setScreenPalette(pal); + + for (int i = startSeq; i <= endSeq; i++) { + uint32 seqDelay = 0; + int seqNum = 0; + + _screen->clearPage(0); + + if (sequences[i].type == 2) { + _screen->loadBitmap(sequences[i].filename, 0, 0, _screen->_currentPalette); + _screen->updateScreen(); + seqDelay = sequences[i].frameDelay * _tickLength; + } else if(sequences[i].type == 1) { + seq_loadWSA(0, sequences[i].filename, sequences[i].frameDelay); + seqDelay = sequences[i].duration * _tickLength; + } + + if (sequences[i].callback) + (*this.*sequences[i].callback)(seqNum++); + + seq_playWSAs(); _screen->updateScreen(); - delayUntil(nextRun); + _screen->fadeFromBlack(40); + + seqDelay += _system->getMillis(); + bool mayEndLoop = sequences[i].timeOut; + + while(1) { + uint32 startTime = _system->getMillis(); + + if (sequences[i].callback) { + int newTime = (*this.*sequences[i].callback)(seqNum++); + if (newTime != -1) { + seqDelay = newTime * _tickLength + _system->getMillis(); + mayEndLoop = true; + } + } + + seq_playWSAs(); + _screen->updateScreen(); + + uint32 currTime = _system->getMillis(); + if (seqDelay <= currTime && mayEndLoop) + break; + else { + uint32 loopTime = currTime - startTime; + delay(loopTime > _tickLength ? loopTime : _tickLength); + } + } + + if (sequences[i].fadeOut) + _screen->fadeToBlack(40); + + if (sequences[i].type == 1) + seq_unloadWSA(0); } + _screen->showMouse(); + delete[] _activeWSA; +} - title->close(); +int KyraEngine_v2::seq_introOverview(int seqNum) { + switch (seqNum) { + case 0: + _sound->playTrack(4); + break; + case 40: + seq_loadWSA(1, "over1.wsa", 10); + break; + case 60: + seq_loadWSA(2, "over2.wsa", 9); + break; + case 282: + seq_loadWSA(3, "forest.wsa", 6); + break; + case 434: + seq_loadWSA(4, "dragon.wsa", 6); + break; + case 540: + seq_unloadWSA(1); + seq_unloadWSA(2); + seq_unloadWSA(3); + seq_unloadWSA(4); + return 0; + break; + } - _screen->fadeToBlack(); - _screen->clearCurPage(); + return -1; +} - if (_quitFlag) { - delete title; - return; +int KyraEngine_v2::seq_introTitle(int seqNum) { + if (seqNum == 1) + _sound->playTrack(3); + else if (seqNum == 25) { + // XXX: handle menu + return 200; } - title->open("TITLE.WSA", 0, pal); - assert(title->opened()); + return -1; +} + +int KyraEngine_v2::seq_introWestwood(int seqNum) { + if (seqNum == 0) + _sound->playTrack(2); - title->setX(0); title->setY(0); - title->displayFrame(0); - _screen->updateScreen(); - _screen->fadePalette(pal, 0x54); + return -1; +} - _sound->playTrack(3); +void KyraEngine_v2::seq_playWSAs() { + uint32 currTime = _system->getMillis(); - for (i = 1; i < 26 && !_quitFlag; ++i) { - uint32 nextRun = _system->getMillis() + 6 * _tickLength; - title->displayFrame(i); - _screen->updateScreen(); - delayUntil(nextRun); + for (int i = 0; i < 8; i++) { + if (_activeWSA[i].movie && currTime >= _activeWSA[i].nextFrame && _activeWSA[i].currentFrame < _activeWSA[i].endFrame) { + _activeWSA[i].movie->displayFrame(_activeWSA[i].currentFrame++); + _activeWSA[i].nextFrame = currTime + _activeWSA[i].frameDelay * _tickLength; + } } +} - title->close(); +void KyraEngine_v2::seq_loadWSA(int wsaNum, const char *filename, int frameDelay) { + _activeWSA[wsaNum].movie = new WSAMovieV2(this); + assert(_activeWSA[wsaNum].movie); + _activeWSA[wsaNum].endFrame = _activeWSA[wsaNum].movie->open(filename, 0, _screen->_currentPalette); + assert(_activeWSA[wsaNum].movie->opened()); + _activeWSA[wsaNum].currentFrame = 0; + _activeWSA[wsaNum].frameDelay = frameDelay; + _activeWSA[wsaNum].nextFrame = _system->getMillis(); + _activeWSA[wsaNum].movie->setX(0); + _activeWSA[wsaNum].movie->setY(0); + _activeWSA[wsaNum].movie->setDrawPage(0); +} - delete title; +void KyraEngine_v2::seq_unloadWSA(int wsaNum) { + assert(_activeWSA[wsaNum].movie); + _activeWSA[wsaNum].movie->close(); + delete _activeWSA[wsaNum].movie; } } // end of namespace Kyra diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index e58517e7bd..67c49dd50c 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -23,6 +23,7 @@ #include "common/stdafx.h" #include "common/endian.h" #include "kyra/kyra.h" +#include "kyra/kyra2.h" #include "kyra/kyra3.h" #include "kyra/screen.h" #include "kyra/resource.h" @@ -1225,8 +1226,9 @@ const uint16 KyraEngine::_amuletY[] = { 170, 170, 159, 181 }; const uint16 KyraEngine::_amuletX2[] = { 0x000, 0x0FD, 0x0E7, 0x0FD, 0x113, 0x000 }; const uint16 KyraEngine::_amuletY2[] = { 0x000, 0x09F, 0x0AA, 0x0B5, 0x0AA, 0x000 }; -// kyra 3 static res -const char *KyraEngine_v3::_mainMenuStrings[] = { +// Kyra 2 and 3 main menu + +const char *KyraEngine::_mainMenuStrings[] = { "Start a new game", "Introduction", "Load a game", @@ -1242,6 +1244,88 @@ const char *KyraEngine_v3::_mainMenuStrings[] = { 0 }; +// kyra 2 static res + +const char *KyraEngine_v2::_introStrings[] = { + "Kyrandia is disappearing!", + "Rock by rock...", + "...and tree by tree.", + "Kyrandia ceases to exist!", + "The Royal Mystics are baffled.", + "Every reference has been consulted.", + "Even Marko and his new valet have been allowed into the conference.", + "Luckily, the Hand was experienced in these matters.", + "And finally a plan was approved...", + "...that required a magic Anchor Stone...", + "...to be retrieved from the center of the world.", + "Zanthia, youngest of the Kyrandian Mystics, has been selected to retrieve the Stone.", + "Thank you for playing The Hand of Fate.", + "This should be enough blueberries to open a portal to the center of the world.", + " DUMMY STRING... ", + " DUMMY STRING... ", + "Hey! All my equipment has been stolen!", + " DUMMY STRING... ", + "If they think I'm going to walk all the way down there, they're nuts!", + " DUMMY STRING... ", + "Hurry up faun!" +}; + +const int KyraEngine_v2::_introStringsSize = ARRAYSIZE(KyraEngine_v2::_introStrings); + +const char *KyraEngine_v2::_introSoundList[] = { + "eintro1.voc", + "eintro2.voc", + "eintro3.voc", + "eintro4.voc", + "eintro5.voc", + "eintro6.voc", + "eintro7.voc", + "eintro8.voc", + "eintro9.voc", + "eintro10.voc", + "eintro11voc", + "eintro12.voc", + "eglow.voc", + "0000210.voc", + "0000130.voc", + "0000180.voc", + "0000160.voc", + "asong.voc", + "crowcaw.voc", + "eyerub2.voc", + "pluck3.voc", + "rodnreel.voc", + "frog1.voc", + "scavmov2.voc", + "lambmom3.voc", + "lambkid1.voc", + "thunder2.voc", + "tunder3.voc", + "wind6.voc", + "h2odrop2.voc", + "gasleak.voc", + "polgulp1.voc", + "hndslap1.voc", + "burp1.voc", + "0000220.voc", + "0000230.voc", + "0000250.voc", + "0000260.voc", + "0000270.voc", + "0000280.voc", + "0000290.voc", + "0000300.voc", + "0000310.voc", + "0000320.voc", + "0000330.voc", + "scream1.voc", + "theend.voc" +}; + +const int KyraEngine_v2::_introSoundListSize = ARRAYSIZE(KyraEngine_v2::_introSoundList); + +// kyra 3 static res + const char *KyraEngine_v3::_soundList[] = { "ARREST1.AUD", "BATH1.AUD", diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp index f29875d931..3aa5425d5f 100644 --- a/engines/kyra/wsamovie.cpp +++ b/engines/kyra/wsamovie.cpp @@ -22,6 +22,8 @@ #include "common/stdafx.h" #include "common/endian.h" +#include "common/system.h" + #include "kyra/kyra.h" #include "kyra/kyra3.h" #include "kyra/screen.h" @@ -32,7 +34,7 @@ namespace Kyra { WSAMovieV1::WSAMovieV1(KyraEngine *vm) : Movie(vm) {} WSAMovieV1::~WSAMovieV1() { close(); } -void WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { +int WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { debugC(9, kDebugLevelMovie, "WSAMovieV1::open('%s', %d, %p)", filename, offscreenDecode, (const void *)palBuf); close(); @@ -40,7 +42,7 @@ void WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) uint32 fileSize; uint8 *p = _vm->resource()->fileData(filename, &fileSize); if (!p) - return; + return 0; const uint8 *wsaData = p; _numFrames = READ_LE_UINT16(wsaData); wsaData += 2; @@ -109,6 +111,8 @@ void WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) delete [] p; _opened = true; + + return _numFrames; } void WSAMovieV1::close() { @@ -210,7 +214,7 @@ void WSAMovieV1::processFrame(int frameNum, uint8 *dst) { WSAMovieV2::WSAMovieV2(KyraEngine *vm) : WSAMovieV1(vm), _xAdd(0), _yAdd(0) {} -void WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { +int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { debugC(9, kDebugLevelMovie, "WSAMovieV3::open('%s', %d, %p)", filename, unk1, (const void *)palBuf); close(); @@ -219,7 +223,7 @@ void WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { uint8 *p = _vm->resource()->fileData(filename, &fileSize); if (!p) { warning("couldn't load wsa file: '%s'", filename); - return; + return 0; } const uint8 *wsaData = p; @@ -281,6 +285,8 @@ void WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { delete [] p; _opened = true; + + return _numFrames; } } // end of namespace Kyra diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h index f543af9668..8f5069ddb7 100644 --- a/engines/kyra/wsamovie.h +++ b/engines/kyra/wsamovie.h @@ -40,7 +40,7 @@ public: virtual bool opened() { return _opened; } - virtual void open(const char *filename, int offscreen, uint8 *palette) = 0; + virtual int open(const char *filename, int offscreen, uint8 *palette) = 0; virtual void close() = 0; virtual int frames() = 0; @@ -63,7 +63,7 @@ public: WSAMovieV1(KyraEngine *vm); virtual ~WSAMovieV1(); - virtual void open(const char *filename, int offscreen, uint8 *palette); + virtual int open(const char *filename, int offscreen, uint8 *palette); virtual void close(); virtual int frames() { return _opened ? _numFrames : -1; } @@ -94,8 +94,8 @@ class WSAMovieV2 : public WSAMovieV1 { public: WSAMovieV2(KyraEngine *vm); - void open(const char *filename, int unk1, uint8 *palette); - + int open(const char *filename, int unk1, uint8 *palette); + void setX(int x) { _x = x + _xAdd; } void setY(int y) { _y = y + _yAdd; } |