aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/kyra/gui.cpp19
-rw-r--r--engines/kyra/gui.h9
-rw-r--r--engines/kyra/kyra_hof.cpp63
-rw-r--r--engines/kyra/kyra_hof.h2
-rw-r--r--engines/kyra/kyra_mr.cpp6
-rw-r--r--engines/kyra/lol.cpp211
-rw-r--r--engines/kyra/lol.h18
-rw-r--r--engines/kyra/module.mk1
-rw-r--r--engines/kyra/sequences_hof.cpp6
-rw-r--r--engines/kyra/staticres.cpp14
10 files changed, 260 insertions, 89 deletions
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index b316d727bd..f03f028b98 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -441,10 +441,11 @@ int MainMenu::handle(int dim) {
memset(colorMap, 0, sizeof(colorMap));
_screen->setTextColorMap(colorMap);
- Screen::FontId oldFont = _screen->setFont(Screen::FID_8_FNT);
+ Screen::FontId oldFont = _screen->setFont(_static.font);
int charWidthBackUp = _screen->_charWidth;
- _screen->_charWidth = -2;
+ if (_vm->game() != GI_LOL)
+ _screen->_charWidth = -2;
_screen->setScreenDim(dim);
while (!_screen->isMouseVisible())
@@ -473,7 +474,7 @@ int MainMenu::handle(int dim) {
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);
+ Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * _static.menuTable[3]);
while (!_vm->shouldQuit()) {
updateAnimation();
@@ -484,18 +485,18 @@ int MainMenu::handle(int dim) {
int item = (mouse.y - menuRect.top) / fh;
if (item != selected) {
- printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.colorNormal, 0, 5);
- printString(_static.strings[item], textPos, menuRect.top + item * fh, _static.colorFlash, 0, 5);
+ printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5);
+ printString(_static.strings[item], textPos, menuRect.top + item * fh, _static.menuTable[6], 0, 5);
selected = item;
}
if (mousePressed) {
for (int i = 0; i < 3; i++) {
- printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.colorNormal, 0, 5);
+ printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5);
_screen->updateScreen();
_system->delayMillis(50);
- printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.colorFlash, 0, 5);
+ printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[6], 0, 5);
_screen->updateScreen();
_system->delayMillis(50);
}
@@ -562,8 +563,8 @@ void MainMenu::printString(const char *format, int x, int y, int col1, int col2,
x -= _screen->getTextWidth(string);
if (flags & 4) {
- _screen->printText(string, x - 1, y, 240, col2);
- _screen->printText(string, x, y + 1, 240, col2);
+ _screen->printText(string, x - 1, y, _static.altColor, col2);
+ _screen->printText(string, x, y + 1, _static.altColor, col2);
}
if (flags & 8) {
diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h
index 8115d91e7a..2ee764bfbe 100644
--- a/engines/kyra/gui.h
+++ b/engines/kyra/gui.h
@@ -27,6 +27,7 @@
#define KYRA_GUI_H
#include "kyra/kyra_v1.h"
+#include "kyra/screen.h"
#include "common/ptr.h"
#include "common/array.h"
@@ -217,11 +218,13 @@ public:
};
struct StaticData {
- const char *strings[4];
+ const char *strings[5];
- uint8 menuTable[11];
+ uint8 menuTable[7];
uint8 colorTable[4];
- uint8 colorNormal, colorFlash;
+
+ Screen::FontId font;
+ uint8 altColor;
};
void init(StaticData data, Animation anim);
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index efe3394885..316e341a14 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -34,6 +34,7 @@
#include "kyra/text_hof.h"
#include "kyra/timer.h"
#include "kyra/debugger.h"
+#include "kyra/util.h"
#include "common/system.h"
#include "common/config-manager.h"
@@ -888,8 +889,8 @@ char *KyraEngine_HoF::getTableString(int id, uint8 *buffer, int decode) {
char *string = (char*)getTableEntry(buffer, id);
if (decode && _flags.lang != Common::JA_JPN) {
- decodeString1(string, _internStringBuf);
- decodeString2(_internStringBuf, _internStringBuf);
+ Util::decodeString1(string, _internStringBuf);
+ Util::decodeString2(_internStringBuf, _internStringBuf);
string = _internStringBuf;
}
@@ -903,64 +904,6 @@ const char *KyraEngine_HoF::getChapterString(int id) {
return getTableString(id, _chapterBuffer, 1);
}
-int KyraEngine_HoF::decodeString1(const char *src, char *dst) {
- static const uint8 decodeTable1[] = {
- 0x20, 0x65, 0x74, 0x61, 0x69, 0x6E, 0x6F, 0x73, 0x72, 0x6C, 0x68,
- 0x63, 0x64, 0x75, 0x70, 0x6D
- };
-
- static const uint8 decodeTable2[] = {
- 0x74, 0x61, 0x73, 0x69, 0x6F, 0x20, 0x77, 0x62, 0x20, 0x72, 0x6E,
- 0x73, 0x64, 0x61, 0x6C, 0x6D, 0x68, 0x20, 0x69, 0x65, 0x6F, 0x72,
- 0x61, 0x73, 0x6E, 0x72, 0x74, 0x6C, 0x63, 0x20, 0x73, 0x79, 0x6E,
- 0x73, 0x74, 0x63, 0x6C, 0x6F, 0x65, 0x72, 0x20, 0x64, 0x74, 0x67,
- 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x72, 0x20, 0x75, 0x66, 0x6D, 0x73,
- 0x77, 0x20, 0x74, 0x65, 0x70, 0x2E, 0x69, 0x63, 0x61, 0x65, 0x20,
- 0x6F, 0x69, 0x61, 0x64, 0x75, 0x72, 0x20, 0x6C, 0x61, 0x65, 0x69,
- 0x79, 0x6F, 0x64, 0x65, 0x69, 0x61, 0x20, 0x6F, 0x74, 0x72, 0x75,
- 0x65, 0x74, 0x6F, 0x61, 0x6B, 0x68, 0x6C, 0x72, 0x20, 0x65, 0x69,
- 0x75, 0x2C, 0x2E, 0x6F, 0x61, 0x6E, 0x73, 0x72, 0x63, 0x74, 0x6C,
- 0x61, 0x69, 0x6C, 0x65, 0x6F, 0x69, 0x72, 0x61, 0x74, 0x70, 0x65,
- 0x61, 0x6F, 0x69, 0x70, 0x20, 0x62, 0x6D
- };
-
- int size = 0;
- uint cChar = 0;
- while ((cChar = *src++) != 0) {
- if (cChar & 0x80) {
- cChar &= 0x7F;
- int index = (cChar & 0x78) >> 3;
- *dst++ = decodeTable1[index];
- ++size;
- assert(cChar < sizeof(decodeTable2));
- cChar = decodeTable2[cChar];
- }
-
- *dst++ = cChar;
- ++size;
- }
-
- *dst++ = 0;
- return size;
-}
-
-void KyraEngine_HoF::decodeString2(const char *src, char *dst) {
- if (!src || !dst)
- return;
-
- char out = 0;
- while ((out = *src) != 0) {
- if (*src == 0x1B) {
- ++src;
- out = *src + 0x7F;
- }
- *dst++ = out;
- ++src;
- }
-
- *dst = 0;
-}
-
#pragma mark -
void KyraEngine_HoF::showMessageFromCCode(int id, int16 palIndex, int) {
diff --git a/engines/kyra/kyra_hof.h b/engines/kyra/kyra_hof.h
index a3f78b8465..31dc38b110 100644
--- a/engines/kyra/kyra_hof.h
+++ b/engines/kyra/kyra_hof.h
@@ -551,8 +551,6 @@ protected:
uint8 *getTableEntry(uint8 *buffer, int id);
char *getTableString(int id, uint8 *buffer, int decode);
const char *getChapterString(int id);
- int decodeString1(const char *src, char *dst);
- void decodeString2(const char *src, char *dst);
void changeFileExtension(char *buffer);
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index 823b253534..6e5bba3dc0 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -337,10 +337,10 @@ void KyraEngine_MR::initMainMenu() {
_menu = new MainMenu(this);
MainMenu::StaticData data = {
- { _mainMenuStrings[_lang*4+0], _mainMenuStrings[_lang*4+1], _mainMenuStrings[_lang*4+2], _mainMenuStrings[_lang*4+3] },
- { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF, 0x00, 0x01, 0x02, 0x03 },
+ { _mainMenuStrings[_lang*4+0], _mainMenuStrings[_lang*4+1], _mainMenuStrings[_lang*4+2], _mainMenuStrings[_lang*4+3], 0 },
+ { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF },
{ 0x16, 0x19, 0x1A, 0x16 },
- 0x80, 0xFF
+ Screen::FID_8_FNT, 240
};
if (_flags.lang == Common::ES_ESP) {
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 9dfb7994e1..1c70fe96d3 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -27,6 +27,7 @@
#include "kyra/screen_lol.h"
#include "kyra/resource.h"
#include "kyra/sound.h"
+#include "kyra/util.h"
#include "common/endian.h"
@@ -55,13 +56,19 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_lang = 0;
break;
}
+
+ memset(_shapes, 0, sizeof(_shapes));
_chargenWSA = 0;
+ _lastUsedStringBuffer = 0;
}
LoLEngine::~LoLEngine() {
setupPrologueData(false);
+ for (uint i = 0; i < ARRAYSIZE(_shapes); ++i)
+ delete[] _shapes[i];
+
delete _screen;
delete _tim;
@@ -94,20 +101,206 @@ Common::Error LoLEngine::init() {
}
Common::Error LoLEngine::go() {
- setupPrologueData(true);
- showIntro();
- _sound->playTrack(6);
- /*int character = */chooseCharacter();
- _sound->playTrack(1);
- _screen->fadeToBlack();
- setupPrologueData(false);
+ bool hasSave = saveFileLoadable(0);
+
+ if (!hasSave) {
+ setupPrologueData(true);
+ showIntro();
+ setupPrologueData(false);
+ }
+
+ preInit();
+
+ int processSelection = -1;
+ while (!shouldQuit() && processSelection == -1) {
+ _screen->loadBitmap("TITLE.CPS", 2, 2, _screen->getPalette(0));
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->fadePalette(_screen->getPalette(0), 0x1E);
+
+ int selection = mainMenu();
+
+ switch (selection) {
+ case 0: // New game
+ processSelection = 0;
+ break;
+
+ case 1: // Show intro
+ setupPrologueData(true);
+ _screen->hideMouse();
+ showIntro();
+ _screen->showMouse();
+ setupPrologueData(false);
+ break;
+
+ case 2: // "Lore of the Lands"
+ break;
+
+ case 3: // Load game
+ // For now fall through
+ //processSelection = 3;
+ //break;
+
+ case 4: // Quit game
+ default:
+ quitGame();
+ break;
+ }
+ }
+
+ if (processSelection == -1)
+ return Common::kNoError;
+
+ if (processSelection == 0) {
+ // Unlike the original, we add a nice fade to black
+ memset(_screen->getPalette(0), 0, 768);
+ _screen->fadePalette(_screen->getPalette(0), 0x54);
+
+ setupPrologueData(true);
+ _sound->loadSoundFile("LOREINTR");
+ _sound->playTrack(6);
+ /*int character = */chooseCharacter();
+ _sound->playTrack(1);
+ _screen->fadeToBlack();
+ setupPrologueData(false);
+ } else if (processSelection == 3) {
+ //XXX
+ }
return Common::kNoError;
}
+#pragma mark - Initialization
+
+void LoLEngine::preInit() {
+ debugC(9, kDebugLevelMain, "LoLEngine::preInit()");
+
+ _res->loadFileList("FILEDATA.FDT");
+ _screen->loadFont(Screen::FID_9_FNT, "FONT9P.FNT");
+ _screen->loadFont(Screen::FID_6_FNT, "FONT6P.FNT");
+
+ uint8 *pal = _screen->getPalette(0);
+ memset(pal, 0, 768);
+ _screen->setScreenPalette(pal);
+
+ /*if (_sound->getMusicType() == Sound::kMidiMT32 || _sound->getSfxType() == Sound::kMidiMT32) {
+ _sound->loadSoundFile("LOLSYSEX");
+ _sound->playTrack(0);
+
+ while (_sound->isPlaying() && !shouldQuit())
+ delay(10);
+ }*/
+
+ if (shouldQuit())
+ return;
+
+ _eventList.clear();
+
+ //loadTalkFile(0);
+
+ char filename[32];
+ snprintf(filename, sizeof(filename), "LANDS.%s", _languageExt[_lang]);
+ _landsFile = _res->fileData(filename, 0);
+
+ initializeCursors();
+
+ /*_screen->setFont(Screen::FID_6_FNT);
+ _screen->fprintString("V CD1.02 D", 260, 301, 0x67, 0x00, 0x04);*/
+ _screen->setFont(Screen::FID_9_FNT);
+}
+
+void LoLEngine::initializeCursors() {
+ debugC(9, kDebugLevelMain, "LoLEngine::initializeCursors()");
+
+ _screen->loadBitmap("ITEMICN.SHP", 3, 3, 0);
+ _shapes[0] = _screen->makeShapeCopy(_screen->getCPagePtr(3), 0);
+ _screen->setMouseCursor(0, 0, _shapes[0]);
+}
+
+
+int LoLEngine::mainMenu() {
+ debugC(9, kDebugLevelMain, "LoLEngine::mainMenu()");
+
+ bool hasSave = saveFileLoadable(0);
+
+ MainMenu::StaticData data = {
+ { 0, 0, 0, 0, 0 },
+ { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x3D, 0x9F },
+ { 0x2C, 0x19, 0x48, 0x2C },
+ Screen::FID_9_FNT, 1
+ };
+
+ if (hasSave)
+ ++data.menuTable[3];
+
+ static const uint16 mainMenuStrings[2][5] = {
+ { 0x4248, 0x4249, 0x42DD, 0x424A, 0x0000 },
+ { 0x4248, 0x4249, 0x42DD, 0x4001, 0x424A }
+ };
+
+ for (int i = 0; i < 5; ++i) {
+ if (hasSave)
+ data.strings[i] = getLangString(mainMenuStrings[1][i]);
+ else
+ data.strings[i] = getLangString(mainMenuStrings[0][i]);
+ }
+
+ MainMenu *menu = new MainMenu(this);
+ assert(menu);
+ menu->init(data, MainMenu::Animation());
+
+ int selection = menu->handle(hasSave ? 12 : 6);
+ delete menu;
+
+ if (!hasSave && selection == 3)
+ selection = 4;
+
+ return selection;
+}
+
+#pragma mark - Localization
+
+const char *LoLEngine::getLangString(uint16 id) {
+ debugC(9, kDebugLevelMain, "LoLEngine::getLangString(0x%.04X)", id);
+
+ if (id == 0xFFFF)
+ return 0;
+
+ uint16 realId = id & 0x3FFF;
+ uint8 *buffer = 0;
+
+ if (id & 0x4000)
+ buffer = _landsFile;
+ else
+ buffer = 0; // TODO
+
+ if (!buffer)
+ return 0;
+
+ const char *string = (const char *)getTableEntry(buffer, realId);
+
+ char *srcBuffer = _stringBuffer[_lastUsedStringBuffer];
+ Util::decodeString1(string, srcBuffer);
+ Util::decodeString2(srcBuffer, srcBuffer);
+
+ ++_lastUsedStringBuffer;
+ _lastUsedStringBuffer %= ARRAYSIZE(_stringBuffer);
+
+ return srcBuffer;
+}
+
+uint8 *LoLEngine::getTableEntry(uint8 *buffer, uint16 id) {
+ debugC(9, kDebugLevelMain, "LoLEngine::getTableEntry(%p, %d)", (const void *)buffer, id);
+ if (!buffer)
+ return 0;
+
+ return buffer + READ_LE_UINT16(buffer + (id<<1));
+}
+
#pragma mark - Intro
void LoLEngine::setupPrologueData(bool load) {
+ debugC(9, kDebugLevelMain, "LoLEngine::setupPrologueData(%d)", load);
+
static const char * const fileList[] = {
"GENERAL.PAK", "INTROVOC.PAK", "STARTUP.PAK", "INTRO1.PAK",
"INTRO2.PAK", "INTRO3.PAK", "INTRO4.PAK", "INTRO5.PAK",
@@ -132,6 +325,9 @@ void LoLEngine::setupPrologueData(bool load) {
_res->unloadPakFile(filename);
}
}
+
+ _screen->clearPage(0);
+ _screen->clearPage(3);
if (load) {
_chargenWSA = new WSAMovie_v2(this, _screen);
@@ -189,7 +385,6 @@ void LoLEngine::showIntro() {
_screen->showMouse();
_sound->voiceStop();
- // HACK: Remove all input events
_eventList.clear();
_tim->unload(intro);
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 9e5f29902e..a984fdc36f 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -50,6 +50,13 @@ private:
Common::Error init();
Common::Error go();
+ // initialization
+ void preInit();
+
+ void initializeCursors();
+
+ int mainMenu();
+
// intro
void setupPrologueData(bool load);
@@ -118,7 +125,18 @@ private:
// translation
int _lang;
+ uint8 *_landsFile;
+
+ int _lastUsedStringBuffer;
+ char _stringBuffer[5][512]; // TODO: The original used a size of 512, it looks a bit large.
+ // Maybe we can someday reduce the size.
+ const char *getLangString(uint16 id);
+ uint8 *getTableEntry(uint8 *buffer, uint16 id);
+
static const char * const _languageExt[];
+
+ // graphics
+ uint8 *_shapes[138];
// unneeded
void setWalkspeed(uint8) {}
diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk
index 8169b7b33f..18ab2ecdb5 100644
--- a/engines/kyra/module.mk
+++ b/engines/kyra/module.mk
@@ -67,6 +67,7 @@ MODULE_OBJS := \
timer_lok.o \
timer_hof.o \
timer_mr.o \
+ util.o \
vqa.o \
wsamovie.o
diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp
index 718c8dadfa..7d0feaed16 100644
--- a/engines/kyra/sequences_hof.cpp
+++ b/engines/kyra/sequences_hof.cpp
@@ -2853,10 +2853,10 @@ void KyraEngine_HoF::seq_init() {
} while (getShapePtr(numShp));
} else {
MainMenu::StaticData data = {
- { _sequenceStrings[97], _sequenceStrings[96], _sequenceStrings[95], _sequenceStrings[98] },
- { 0x01, 0x04, 0x0C, 0x04, 0x00, 0xd7, 0xd6, 0x00, 0x01, 0x02, 0x03 },
+ { _sequenceStrings[97], _sequenceStrings[96], _sequenceStrings[95], _sequenceStrings[98], 0 },
+ { 0x01, 0x04, 0x0C, 0x04, 0x00, 0xd7, 0xd6 },
{ 0xd8, 0xda, 0xd9, 0xd8 },
- 0xd7, 0xd6
+ Screen::FID_8_FNT, 240
};
_menu = new MainMenu(this);
_menu->init(data, MainMenu::Animation());
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index bd94fe3f25..ca03451201 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -2357,7 +2357,19 @@ const int8 KyraEngine_MR::_albumWSAY[] = {
// lands of lore static res
const ScreenDim Screen_LoL::_screenDimTable[] = {
- { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }
+ { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, // Taken from Intro
+ { 0x08, 0x48, 0x18, 0x38, 0xFE, 0x01, 0x00, 0x00 },
+ { 0x0E, 0x00, 0x16, 0x78, 0xFE, 0x01, 0x00, 0x00 },
+ { 0x0B, 0x7B, 0x1C, 0x12, 0xFE, 0xFC, 0x00, 0x00 },
+ { 0x0B, 0x7B, 0x1C, 0x2D, 0xFE, 0xFC, 0x00, 0x00 },
+ { 0x55, 0x7B, 0xE9, 0x37, 0xFE, 0xFC, 0x00, 0x00 },
+ { 0x0B, 0x8C, 0x10, 0x2B, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (3 entries)
+ { 0x04, 0x59, 0x20, 0x3C, 0x00, 0x00, 0x00, 0x00 },
+ { 0x05, 0x6E, 0x1E, 0x0C, 0xFE, 0x01, 0x00, 0x00 },
+ { 0x07, 0x19, 0x1A, 0x97, 0x00, 0x00, 0x00, 0x00 },
+ { 0x03, 0x1E, 0x22, 0x8C, 0x00, 0x00, 0x00, 0x00 },
+ { 0x02, 0x48, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00 },
+ { 0x0B, 0x8C, 0x10, 0x33, 0x3D, 0x01, 0x00, 0x00 } // Main menu box (4 entries)
};
const int Screen_LoL::_screenDimTableCount = ARRAYSIZE(Screen_LoL::_screenDimTable);