Adds some framework for the Kyra2 intro, expands it a little bit and adds some static resources (strings, etc). Also

adding a modified version of eriktorbjorn's '[1531929] KYRA: Kyra 2 & 3 main menu unification', with added mouse pointer and sundry.

svn-id: r23766
This commit is contained in:
Oystein Eftevaag 2006-08-26 22:17:30 +00:00
parent 89e75ae218
commit c47a957fb3
14 changed files with 618 additions and 281 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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;
}
@ -120,6 +96,8 @@ Movie *KyraEngine_v3::createWSAMovie() {
int KyraEngine_v3::init() {
KyraEngine::init();
gui_initMainMenu();
_soundDigital = new SoundDigital(this, _mixer);
assert(_soundDigital);
if (!_soundDigital->init())
@ -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;
void KyraEngine_v3::gui_initMainMenu() {
KyraEngine::gui_initMainMenu();
_mainMenuFrame = 29;
_mainMenuFrameAdd = 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;
void KyraEngine_v3::gui_updateMainMenuAnimation() {
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::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]);
_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;
char string[512];
va_list vaList;
va_start(vaList, flags);
vsprintf(string, format, vaList);
va_end(vaList);
// yes 2 * _tickLength here not 3 * like in the first draw
nextRun = now + 2 * _tickLength;
if (flags & 1) {
x -= _screen->getTextWidth(string) >> 1;
_mainMenuLogo->displayFrame(_mainMenuFrame);
_screen->updateScreen();
_mainMenuFrame += _mainMenuFrameAdd;
if (_mainMenuFrame < 29) {
_mainMenuFrame = 29;
_mainMenuFrameAdd = 1;
} else if (_mainMenuFrame > 63) {
_mainMenuFrame = 64;
_mainMenuFrameAdd = -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);
// XXX
}
#pragma mark -

View file

@ -52,8 +52,6 @@ private:
SoundDigital *_soundDigital;
int _lang;
// sound specific
private:
void playMenuAudioFile();
@ -71,14 +69,8 @@ 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:
@ -96,6 +88,11 @@ private:
uint8 *_unkShapeTable[20];
// main menu
Movie *_mainMenuLogo;
int _mainMenuFrame;
int _mainMenuFrameAdd;
// translation stuff
uint8 *_scoreFile;
uint8 *_cCodeFile;

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -30,74 +30,163 @@
namespace Kyra {
void KyraEngine_v2::seq_menu() {
debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_menu()");
void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) {
if (endSeq == -1)
endSeq = startSeq;
_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();
assert(startSeq >= 0 && endSeq < 4 && startSeq <= endSeq);
if (_quitFlag)
return;
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;
memset(pal, 0, sizeof(pal));
_screen->setScreenPalette(pal);
WSAMovieV2 *title = new WSAMovieV2(this);
title->setDrawPage(0);
for (int i = startSeq; i <= endSeq; i++) {
uint32 seqDelay = 0;
int seqNum = 0;
title->open("WESTWOOD.WSA", 0, pal);
assert(title->opened());
_screen->clearPage(0);
title->setX(0); title->setY(0);
title->displayFrame(0);
_screen->updateScreen();
_screen->fadePalette(pal, 0x54);
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;
}
_sound->playTrack(2);
if (sequences[i].callback)
(*this.*sequences[i].callback)(seqNum++);
for (i = 1; i < 18 && !_quitFlag; ++i) {
uint32 nextRun = _system->getMillis() + 6 * _tickLength;
title->displayFrame(i);
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;
}
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;
}
title->close();
return -1;
}
_screen->fadeToBlack();
_screen->clearCurPage();
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;
}
title->setX(0); title->setY(0);
title->displayFrame(0);
_screen->updateScreen();
_screen->fadePalette(pal, 0x54);
int KyraEngine_v2::seq_introWestwood(int seqNum) {
if (seqNum == 0)
_sound->playTrack(2);
_sound->playTrack(3);
return -1;
}
for (i = 1; i < 26 && !_quitFlag; ++i) {
uint32 nextRun = _system->getMillis() + 6 * _tickLength;
title->displayFrame(i);
_screen->updateScreen();
delayUntil(nextRun);
void KyraEngine_v2::seq_playWSAs() {
uint32 currTime = _system->getMillis();
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

View file

@ -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",

View file

@ -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

View file

@ -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,7 +94,7 @@ 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; }