aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorathrxx2019-12-05 22:47:07 +0100
committerathrxx2019-12-18 20:50:46 +0100
commitf01d432c2529e2a47dcbc2438356b00706b41b68 (patch)
tree39982b89db66605de53e6a6e78c2058cfb070ef5
parentfde59250370cb4c1550621a33bf2b5c449e2bcdb (diff)
downloadscummvm-rg350-f01d432c2529e2a47dcbc2438356b00706b41b68.tar.gz
scummvm-rg350-f01d432c2529e2a47dcbc2438356b00706b41b68.tar.bz2
scummvm-rg350-f01d432c2529e2a47dcbc2438356b00706b41b68.zip
KYRA: (EOB/PC98) - implement ending sequence
(The PC-98 version has its own unique ending sequence)
-rw-r--r--engines/kyra/engine/eob.cpp1
-rw-r--r--engines/kyra/engine/eob.h2
-rw-r--r--engines/kyra/engine/eobcommon.cpp4
-rw-r--r--engines/kyra/graphics/screen.cpp1
-rw-r--r--engines/kyra/graphics/screen_eob.cpp62
-rw-r--r--engines/kyra/graphics/screen_eob.h11
-rw-r--r--engines/kyra/sequence/sequences_eob.cpp576
7 files changed, 636 insertions, 21 deletions
diff --git a/engines/kyra/engine/eob.cpp b/engines/kyra/engine/eob.cpp
index bb8627fb04..cdd49a75fd 100644
--- a/engines/kyra/engine/eob.cpp
+++ b/engines/kyra/engine/eob.cpp
@@ -46,6 +46,7 @@ EoBEngine::EoBEngine(OSystem *system, const GameFlags &flags)
_dscDoorCoordsExt = 0;
_useMainMenuGUISettings = false;
_ttlCfg = 0;
+ _xdth = false;
}
EoBEngine::~EoBEngine() {
diff --git a/engines/kyra/engine/eob.h b/engines/kyra/engine/eob.h
index 174f9b9c7a..5b06e30f95 100644
--- a/engines/kyra/engine/eob.h
+++ b/engines/kyra/engine/eob.h
@@ -33,6 +33,7 @@ class EoBEngine : public EoBCoreEngine {
friend class GUI_EoB;
friend class EoBSeqPlayerCommon;
friend class EoBIntroPlayer;
+friend class EoBPC98FinalePlayer;
friend class EoBAmigaFinalePlayer;
public:
EoBEngine(OSystem *system, const GameFlags &flags);
@@ -86,6 +87,7 @@ private:
void seq_xdeath();
const char *const *_finBonusStrings;
+ bool _xdth;
// characters
void drawNpcScene(int npcIndex);
diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp
index 7e180ca8cc..729e59b749 100644
--- a/engines/kyra/engine/eobcommon.cpp
+++ b/engines/kyra/engine/eobcommon.cpp
@@ -425,7 +425,7 @@ Common::Error EoBCoreEngine::init() {
assert(_sound);
_sound->init();
- // This if for EOB1 / PC98 only
+ // This if for EOB1 PC-98 only
_sound->loadSfxFile("EFECT.OBJ");
// Setup volume settings (and read in all ConfigManager settings)
@@ -450,7 +450,7 @@ Common::Error EoBCoreEngine::init() {
assert(_inf);
_debugger = new Debugger_EoB(this);
assert(_debugger);
-
+
if (_flags.platform == Common::kPlatformAmiga) {
if (_res->exists("EOBF6.FONT"))
_screen->loadFont(Screen::FID_6_FNT, "EOBF6.FONT");
diff --git a/engines/kyra/graphics/screen.cpp b/engines/kyra/graphics/screen.cpp
index dd22507c3e..cd8f9404cc 100644
--- a/engines/kyra/graphics/screen.cpp
+++ b/engines/kyra/graphics/screen.cpp
@@ -178,6 +178,7 @@ bool Screen::init() {
}
if (_vm->game() == GI_EOB2 && _vm->gameFlags().platform == Common::kPlatformFMTowns) {
+ assert(_fonts[FID_SJIS_FNT]);
_fonts[FID_SJIS_FNT]->setStyle(Font::kFSFat);
_fonts[FID_SJIS_LARGE_FNT] = new SJISFontLarge(font);
}
diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp
index 371b673760..dd794e2fb6 100644
--- a/engines/kyra/graphics/screen_eob.cpp
+++ b/engines/kyra/graphics/screen_eob.cpp
@@ -63,8 +63,9 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system,
_cgaMappingDefault = 0;
_cgaDitheringTables[0] = _cgaDitheringTables[1] = 0;
_useHiResEGADithering = _dualPaletteMode = false;
- _decodeTempBuffer = 0;
+ _cyclePalette = 0;
_cpsFilePattern = "%s.";
+ _activePalCycle = 0;
for (int i = 0; i < 10; ++i)
_palette16c[i] = 0;
}
@@ -78,7 +79,7 @@ Screen_EoB::~Screen_EoB() {
delete[] _egaDitheringTempPage;
delete[] _cgaDitheringTables[0];
delete[] _cgaDitheringTables[1];
- delete[] _decodeTempBuffer;
+ delete[] _cyclePalette;
}
bool Screen_EoB::init() {
@@ -125,7 +126,8 @@ bool Screen_EoB::init() {
int ci = 0;
if (_vm->game() == GI_EOB1) {
if (_vm->gameFlags().platform == Common::kPlatformPC98) {
- _decodeTempBuffer = new uint8[2048];
+ _cyclePalette = new uint8[48];
+ memset(_cyclePalette, 0, 48);
ci = 3;
} else if (_renderMode == Common::kRenderEGA || _renderMode == Common::kRenderCGA) {
ci = 1;
@@ -246,8 +248,10 @@ void Screen_EoB::printShadedText(const char *string, int x, int y, int col1, int
fillRect(x, y, x + getTextWidth(string) - 1, y + getFontHeight() - 1, col2);
}
- if (_vm->gameFlags().use16ColorMode)
+ if (_vm->gameFlags().use16ColorMode) {
+ assert(_fonts[_currentFont]);
_fonts[_currentFont]->setStyle(Font::kFSLeftShadow);
+ }
printText(string, x, y, col1, 0);
@@ -268,7 +272,7 @@ void Screen_EoB::loadBitmap(const char *filename, int tempPage, int dstPage, Pal
str->skip(2);
uint16 imgSize = str->readUint16LE();
assert(imgSize == str->size() - 4);
- uint8 *buf = new uint8[SCREEN_W * SCREEN_H];
+ uint8 *buf = new uint8[MAX<uint16>(imgSize, SCREEN_W * SCREEN_H)];
str->read(buf, imgSize);
delete str;
@@ -1594,7 +1598,7 @@ void Screen_EoB::selectPC98Palette(int paletteIndex, Palette &dest, int brightne
void Screen_EoB::decodeBIN(const uint8 *src, uint8 *dst, uint16 inSize) {
const uint8 *end = src + inSize;
- memset(_decodeTempBuffer, 0, 2048);
+ memset(_dsTempPage, 0, 2048);
int tmpDstOffs = 0;
while (src < end) {
@@ -1608,12 +1612,12 @@ void Screen_EoB::decodeBIN(const uint8 *src, uint8 *dst, uint16 inSize) {
const uint8 *tmpSrc2 = dst;
for (int len2 = len; len2; len2--) {
- *dst++ = _decodeTempBuffer[tmpSrcOffs++];
+ *dst++ = _dsTempPage[tmpSrcOffs++];
tmpSrcOffs &= 0x7FF;
}
while (len--) {
- _decodeTempBuffer[tmpDstOffs++] = *tmpSrc2++;
+ _dsTempPage[tmpDstOffs++] = *tmpSrc2++;
tmpDstOffs &= 0x7FF;
}
@@ -1626,14 +1630,14 @@ void Screen_EoB::decodeBIN(const uint8 *src, uint8 *dst, uint16 inSize) {
int planes = ((code >> 3) & 3) + 1;
while (len--) {
for (int i = 0; i < planes; ++i) {
- *dst++ = _decodeTempBuffer[tmpDstOffs++] = src[i];
+ *dst++ = _dsTempPage[tmpDstOffs++] = src[i];
tmpDstOffs &= 0x7FF;
}
}
src += planes;
} else {
for (int len = (code & 0x3F) + 1; len; len--) {
- *dst++ = _decodeTempBuffer[tmpDstOffs++] = *src++;
+ *dst++ = _dsTempPage[tmpDstOffs++] = *src++;
tmpDstOffs &= 0x7FF;
}
}
@@ -1664,6 +1668,44 @@ void Screen_EoB::decodePC98PlanarBitmap(uint8 *srcDstBuffer, uint8 *tmpBuffer, u
}
}
+void Screen_EoB::initPC98PaletteCycle(int paletteIndex, PalCycleData *data) {
+ if (!_use16ColorMode || !_cyclePalette)
+ return;
+
+ _activePalCycle = data;
+
+ if (data)
+ memcpy(_cyclePalette, _palette16c[paletteIndex], 48);
+ else
+ memset(_cyclePalette, 0, 48);
+}
+
+void Screen_EoB::updatePC98PaletteCycle(int brightness) {
+ if (_activePalCycle) {
+ for (int i = 0; i < 48; ++i) {
+ if (--_activePalCycle[i].delay)
+ continue;
+ for (int8 in = 32; in == 32; ) {
+ in = *_activePalCycle[i].data++;
+ if (in < 16 && in > -16) {
+ _cyclePalette[i] += in;
+ _activePalCycle[i].delay = *_activePalCycle[i].data++;
+ } else if (in < 32) {
+ _cyclePalette[i] = in - 16;
+ _activePalCycle[i].delay = *_activePalCycle[i].data++;
+ } else if (in == 32)
+ _activePalCycle[i].data += READ_BE_INT16(_activePalCycle[i].data);
+ }
+ }
+ }
+
+ uint8 pal[48];
+ for (int i = 0; i < 48; ++i)
+ pal[i] = CLIP<int>(_cyclePalette[i] + brightness, 0, 15);
+ loadPalette(pal, *_palettes[0], 48);
+ setScreenPalette(*_palettes[0]);
+}
+
static uint32 _decodeFrameAmiga_x = 0;
bool decodeFrameAmiga_readNextBit(const uint8 *&data, uint32 &code, uint32 &chk) {
diff --git a/engines/kyra/graphics/screen_eob.h b/engines/kyra/graphics/screen_eob.h
index 9c6e17caad..2b0622c679 100644
--- a/engines/kyra/graphics/screen_eob.h
+++ b/engines/kyra/graphics/screen_eob.h
@@ -95,7 +95,16 @@ public:
void decodeBIN(const uint8 *src, uint8 *dst, uint16 inSize);
void decodePC98PlanarBitmap(uint8 *srcDstBuffer, uint8 *tmpBuffer, uint16 size = 64000);
- uint8 *_decodeTempBuffer;
+ struct PalCycleData {
+ const int8 *data;
+ uint8 delay;
+ };
+
+ void initPC98PaletteCycle(int paletteIndex, PalCycleData *data);
+ void updatePC98PaletteCycle(int brightness);
+
+ PalCycleData *_activePalCycle;
+ uint8 *_cyclePalette;
// Amiga specific
void loadSpecialAmigaCPS(const char *fileName, int destPage, bool isGraphics);
diff --git a/engines/kyra/sequence/sequences_eob.cpp b/engines/kyra/sequence/sequences_eob.cpp
index 8bfc393894..6754d364e7 100644
--- a/engines/kyra/sequence/sequences_eob.cpp
+++ b/engines/kyra/sequence/sequences_eob.cpp
@@ -36,19 +36,26 @@ namespace Kyra {
class EoBSeqPlayerCommon {
public:
EoBSeqPlayerCommon(EoBEngine *vm, Screen_EoB *screen);
- virtual ~EoBSeqPlayerCommon() {}
+ virtual ~EoBSeqPlayerCommon();
protected:
void boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH, int fillColor = -1);
void printSubtitle(const char *str, int textmodeX, int textmodeY, int col, int mode = 0);
+ void releaseShapes();
+ void clearTextField();
const uint8 _fillColor1;
const uint8 _fillColor2;
+ uint8 **_shapes;
+
EoBEngine *_vm;
Screen_EoB *_screen;
+ const uint8 _tickLength;
private:
+ virtual void wait(uint32 ticks) { _vm->delay(ticks * _tickLength); }
+ Common::Array<Common::Rect> _textFields;
uint8 _textColor;
};
@@ -109,6 +116,48 @@ private:
const uint8 *_tvlH;
};
+class EoBPC98FinalePlayer : public EoBSeqPlayerCommon {
+public:
+ EoBPC98FinalePlayer(EoBEngine *vm, Screen_EoB *screen);
+ virtual ~EoBPC98FinalePlayer();
+
+ void start(bool xdt);
+
+private:
+ void beholder(bool xdt);
+ void teleport();
+ void king();
+ void inspection();
+ void congratulation();
+ void credits();
+ void bonus();
+
+ template<int brStart, int brEnd, int inc> void pc98FadePalette(int palId, uint32 del);
+ void fadeToBlack(int palId, uint32 delay) { pc98FadePalette<0, -16, -1>(palId, delay); }
+ void fadeFromBlack(int palId, uint32 delay) { pc98FadePalette<-15, 1, 1>(palId, delay); }
+ void fadeToWhite(int palId, uint32 delay) { pc98FadePalette<0, 16, 1>(palId, delay); }
+ void fadeFromWhite(int palId, uint32 delay) { pc98FadePalette<15, -1, -1>(palId, delay); }
+
+ void startPaletteCycle(int palId, int style);
+ void stopPaletteCycle();
+ void resetPaletteCycle();
+
+ virtual void wait(uint32 millis);
+
+ const char *const *_strings;
+ const uint8 *_eyesAnimData;
+ const int16 *_handsAnimData;
+ const int16 *_handsAnimData2;
+ const int8 *_handsAnimData3;
+ const uint8 *_creditsStrings;
+ const uint8 *_creditsCharWdth;
+
+ bool _updatePalCycle;
+ Screen_EoB::PalCycleData *_palCycleType1, *_palCycleType2;
+ const uint8 _palCycleDelay;
+};
+
+
class EoBAmigaFinalePlayer : public EoBSeqPlayerCommon {
public:
EoBAmigaFinalePlayer(EoBEngine *vm, Screen_EoB *screen);
@@ -142,7 +191,14 @@ private:
EoBSeqPlayerCommon::EoBSeqPlayerCommon(EoBEngine *vm, Screen_EoB *screen) : _vm(vm), _screen(screen), _textColor(0xE1),
_fillColor1(vm->gameFlags().platform == Common::kPlatformAmiga ? 19 : (vm->gameFlags().platform == Common::kPlatformPC98 ? 0 : 12)),
- _fillColor2(vm->gameFlags().platform == Common::kPlatformAmiga ? 10 : 157) {
+ _fillColor2(vm->gameFlags().platform == Common::kPlatformAmiga ? 10 : 157), _tickLength(16) {
+ _shapes = new uint8*[64];
+ memset(_shapes, 0, 64 * sizeof(uint8*));
+}
+
+EoBSeqPlayerCommon::~EoBSeqPlayerCommon() {
+ releaseShapes();
+ delete[] _shapes;
}
void EoBSeqPlayerCommon::boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH, int fillColor) {
@@ -221,6 +277,9 @@ void EoBSeqPlayerCommon::printSubtitle(const char *str, int textmodeX, int textm
Screen::FontId of = _screen->setFont(Screen::FID_SJIS_TEXTMODE_FNT);
int cp = _screen->setCurPage(0);
+ int x1 = textmodeX << 2;
+ int y1 = textmodeY << 3;
+
for (int i = 0; str[i] &&!_vm->shouldQuit() && !_vm->skipFlag(); ) {
uint8 c = str[i++];
if (c == 13) {
@@ -229,8 +288,11 @@ void EoBSeqPlayerCommon::printSubtitle(const char *str, int textmodeX, int textm
} else if (c == 10) {
_textColor = str[i++];
} else if (c == 7) {
- _vm->delay(960);
- _screen->fillRect(0, 160, 319, 199, _fillColor1, 0);
+ wait(120);
+ int x22 = ((textmodeX << 2) + (curX << 3)) + _screen->getFontWidth() - 1;
+ int y22 = (textmodeY << 3) + _screen->getFontHeight() - 1;
+ _textFields.push_back(Common::Rect(x1, y1, x22, y22));
+ clearTextField();
curX = 0;
}
@@ -245,20 +307,40 @@ void EoBSeqPlayerCommon::printSubtitle(const char *str, int textmodeX, int textm
}
if (mode == 0) {
- _vm->_system->delayMillis(40);
+ wait(5);
_screen->updateScreen();
} else if (mode == 1) {
- _vm->delay(40);
+ wait(5);
_screen->updateScreen();
}
}
+ int x2 = ((textmodeX << 2) + (curX << 3)) + _screen->getFontWidth() - 1;
+ int y2 = (textmodeY << 3) + _screen->getFontHeight() - 1;
+ _textFields.push_back(Common::Rect(x1, y1, x2, y2));
+
if (mode == 2)
_screen->updateScreen();
_screen->setFont(of);
_screen->setCurPage(cp);
}
+void EoBSeqPlayerCommon::releaseShapes() {
+ for (int i = 0; i < 64; ++i) {
+ delete[] _shapes[i];
+ _shapes[i] = 0;
+ }
+}
+void EoBSeqPlayerCommon::clearTextField() {
+ for (Common::Array<Common::Rect>::iterator i = _textFields.begin(); i != _textFields.end(); ++i)
+ _screen->fillRect(i->left, i->top, i->right, i->bottom, 0);
+ _textFields.clear();
+
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ _screen->clearPage(0);
+
+ _screen->updateScreen();
+}
EoBIntroPlayer::EoBIntroPlayer(EoBEngine *vm, Screen_EoB *screen) : EoBSeqPlayerCommon(vm, screen) {
int temp = 0;
@@ -1105,7 +1187,7 @@ void EoBIntroPlayer::tunnel() {
_screen->setCurPage(0);
_screen->updateScreen();
- _vm->delay((_vm->gameFlags().platform == Common::kPlatformPC98 ? 130 : 50) * _vm->_tickLength);
+ _vm->delay(50 * _vm->_tickLength);
}
void EoBIntroPlayer::loadAndSetPalette(const char *dosPaletteFile, int pc98PaletteID) {
@@ -1206,6 +1288,478 @@ void EoBIntroPlayer::whirlTransition() {
}
}
+EoBPC98FinalePlayer::EoBPC98FinalePlayer(EoBEngine *vm, Screen_EoB *screen) : EoBSeqPlayerCommon(vm, screen), _palCycleDelay(16) {
+ int temp = 0;
+ _strings = _vm->staticres()->loadStrings(kEoB1FinaleStrings, temp);
+ _eyesAnimData = _vm->staticres()->loadRawData(kEoB1FinaleEyesAnim, temp);
+ _handsAnimData = (const int16*)_vm->staticres()->loadRawDataBe16(kEoB1FinaleHandsAnim, temp);
+ _handsAnimData2 = (const int16*)_vm->staticres()->loadRawDataBe16(kEoB1FinaleHandsAnim2, temp);
+ _handsAnimData3 = (const int8*)_vm->staticres()->loadRawData(kEoB1FinaleHandsAnim3, temp);
+ _creditsStrings = _vm->staticres()->loadRawData(kEoB1CreditsStrings, temp);
+ _creditsCharWdth = _vm->staticres()->loadRawData(kEoB1CreditsCharWdth, temp);
+
+ _palCycleType1 = new Screen_EoB::PalCycleData[48];
+ _palCycleType2 = new Screen_EoB::PalCycleData[48];
+ _updatePalCycle = false;
+
+ resetPaletteCycle();
+}
+
+EoBPC98FinalePlayer::~EoBPC98FinalePlayer() {
+ delete[] _palCycleType1;
+ delete[] _palCycleType2;
+}
+
+void EoBPC98FinalePlayer::start(bool xdt) {
+ uint32 tick = _vm->_system->getMillis() + 60 * _vm->_tickLength;
+ _screen->hideMouse();
+
+ _screen->fadeToBlack();
+ _screen->clearPage(2);
+ _screen->clearPage(0);
+ _screen->setScreenDim(0);
+
+ _vm->delayUntil(tick);
+ _vm->_eventList.clear();
+ _vm->_allowSkip = true;
+
+ _vm->snd_playSong(1);
+
+ beholder(xdt);
+ teleport();
+ king();
+ inspection();
+ congratulation();
+ credits();
+ bonus();
+
+ while (!_vm->skipFlag() && !_vm->shouldQuit()) {
+ _vm->updateInput();
+ _vm->delay(10);
+ }
+
+ _vm->_allowSkip = false;
+ _vm->_eventList.clear();
+
+ _screen->fadeToBlack();
+}
+
+void EoBPC98FinalePlayer::beholder(bool xdt) {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ if (xdt) {
+ _screen->loadBitmap("END1.BIN", 3, 5, 0);
+ _screen->convertPage(5, 2, 0);
+ _screen->copyRegion(0, 0, 56, 0, 216, 200, 2, 0, Screen::CR_NO_P_CHECK);
+ startPaletteCycle(5, 0);
+ fadeFromBlack(5, 3);
+ printSubtitle(_strings[0], 8, 24, 225);
+ } else {
+ printSubtitle(_strings[1], 23, 10, 225);
+ printSubtitle(_strings[2], 15, 12, 225);
+ printSubtitle(_strings[3], 27, 14, 225);
+ }
+
+ wait(150);
+ clearTextField();
+ fadeToBlack(5, 3);
+ stopPaletteCycle();
+}
+
+void EoBPC98FinalePlayer::teleport() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ _screen->loadBitmap("END2.BIN", 3, 5, 0);
+ _screen->convertPage(5, 2, 0);
+ _screen->copyRegion(0, 0, 56, 0, 216, 200, 2, 0, Screen::CR_NO_P_CHECK);
+ startPaletteCycle(6, 1);
+ fadeFromBlack(6, 3);
+ printSubtitle(_strings[4], 14, 24, 225);
+ wait(150);
+ fadeToWhite(6, 3);
+ stopPaletteCycle();
+ clearTextField();
+}
+
+void EoBPC98FinalePlayer::king() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ uint32 xylen = 0;
+ uint8 *xydata = _vm->resource()->fileData("xytbl.dat", &xylen);
+ xylen >>= 1;
+
+ _screen->loadBitmap("KING.BIN", 3, 5, 0);
+ _screen->convertPage(5, 2, 0);
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+
+ _screen->loadBitmap("KG.BIN", 3, 4, 0);
+ _screen->setCurPage(4);
+
+ _shapes[0] = _screen->encodeShape(32, 0, 8, 128);
+ for (int i = 0; i < 4; ++i) {
+ _shapes[2 + i] = _screen->encodeShape(i << 3, 0, 8, 80);
+ if (i < 3)
+ _shapes[6 + i] = _screen->encodeShape(i << 3, 80, 8, 120);
+ }
+ _screen->setCurPage(2);
+
+ _screen->drawShape(2, _shapes[0], 0, 0);
+ _screen->drawShape(2, _shapes[2], 0, 48);
+ _screen->copyRegion(0, 0, 128, 16, 64, 128, 2, 0, Screen::CR_NO_P_CHECK);
+ fadeFromWhite(3, 4);
+
+ _screen->loadBitmap("ADVENTUR.BIN", 3, 5, 0);
+ _screen->convertPage(5, 2, 0);
+ _shapes[1] = _screen->encodeShape(8, 0, 8, 64);
+
+ static uint8 xOff[] = { 0, 48, 96, 152 };
+ static uint8 maxW[] = { 48, 48, 56, 48 };
+
+ for (int i = 0; i < 4 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
+ const uint8 *xypos = xydata;
+ uint16 cx = xOff[i];
+ uint32 nextDelay = _vm->_system->getMillis() + 5;
+ for (uint32 ii = 0; ii < xylen && !_vm->skipFlag() && !_vm->shouldQuit(); ++ii) {
+ uint8 x = *xypos++;
+ uint8 y = *xypos++;
+ uint8 col = _screen->getPagePixel(2, cx + x, y);
+ if (!col || maxW[i] <= x)
+ continue;
+ if (col)
+ _screen->setPagePixel(0, cx + x + 64, y + 84, col);
+ if (ii % 48 == 0) {
+ _screen->updateScreen();
+ uint32 cur = _vm->_system->getMillis();
+ if (nextDelay > cur)
+ _vm->_system->delayMillis(nextDelay - cur);
+ nextDelay += 5;
+ }
+ }
+ _screen->updateScreen();
+ }
+
+ printSubtitle(_strings[5], 9, 24, 225);
+ printSubtitle(_strings[6], 18, 24, 225);
+ printSubtitle(_strings[7], 23, 24, 225);
+ printSubtitle(_strings[8], 8, 24, 225);
+
+ wait(60);
+ clearTextField();
+
+ for (int i = 0; i < 7 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
+ uint32 end = _vm->_system->getMillis() + 12 * _tickLength;
+ _screen->fillRect(0, 0, 64, 128, 0, 2);
+ _screen->drawShape(2, _shapes[0], 0, 0);
+ _screen->drawShape(2, _shapes[2 + i], 0, i < 4 ? 48 : 16);
+ _screen->drawShape(2, _shapes[1], 0, 68);
+ _screen->copyRegion(0, 0, 128, 16, 64, 128, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ wait(150);
+ fadeToBlack(3, 3);
+
+ delete[] xydata;
+ releaseShapes();
+}
+
+void EoBPC98FinalePlayer::inspection() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ _screen->clearPage(0);
+ _screen->setCurPage(4);
+ _screen->loadBitmap("CLB.BIN", 3, 5, 0);
+
+ _shapes[2] = _screen->encodeShape(24, 29, 16, 80);
+ _shapes[1] = _screen->encodeShape(0, 0, 8, 40);
+ _shapes[0] = _screen->encodeShape(0, 40, 12, 120);
+ for (int i = 0; i < 5; ++i)
+ _shapes[3 + i] = _screen->encodeShape(8 + (i << 2), 0, 4, 24);
+
+ _screen->drawShape(2, _shapes[2], 0, 0);
+ _screen->copyRegion(0, 0, 88, 50, 128, 80, 2, 0, Screen::CR_NO_P_CHECK);
+ fadeFromBlack(8, 2);
+ wait(180);
+ fadeToBlack(8, 0);
+
+ _screen->clearPage(0);
+ _screen->clearPage(2);
+ _screen->drawShape(2, _shapes[1], 0, 0);
+ _screen->drawShape(2, _shapes[1], 64, 0, -1, 1);
+ _screen->copyRegion(0, 0, 88, 90, 128, 40, 2, 0, Screen::CR_NO_P_CHECK);
+ fadeFromBlack(7, 0);
+
+ for (const uint8 *e = _eyesAnimData; *e != 100 && !_vm->skipFlag() && !_vm->shouldQuit(); ) {
+ _screen->drawShape(2, _shapes[3 + *e], 16, 8);
+ _screen->drawShape(2, _shapes[3 + *e++], 80, 8, -1, 1);
+ _screen->copyRegion(0, 0, 88, 90, 128, 40, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ wait(*e++);
+ }
+
+ wait(30);
+ fadeToBlack(7, 1);
+
+ _screen->clearPage(0);
+ _screen->drawShape(2, _shapes[0], 0, 0);
+ _screen->copyRegion(0, 0, 104, 30, 96, 120, 2, 0, Screen::CR_NO_P_CHECK);
+ fadeFromBlack(7, 1);
+
+ wait(30);
+
+ printSubtitle(_strings[12], 2, 22, 225);
+ printSubtitle(_strings[13], 18, 22, 225);
+ printSubtitle(_strings[14], 14, 22, 225);
+ printSubtitle(_strings[15], 10, 22, 225);
+ printSubtitle(_strings[16], 3, 22, 225);
+
+ wait(60);
+ clearTextField();
+ fadeToBlack(7, 3);
+ releaseShapes();
+}
+
+void EoBPC98FinalePlayer::congratulation() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ _screen->clearPage(0);
+ _screen->setCurPage(4);
+ _shapes[0] = _screen->encodeShape(12, 24, 12, 64);
+ _shapes[1] = _screen->encodeShape(12, 88, 12, 67);
+ _shapes[2] = _screen->encodeShape(24, 109, 16, 63);
+ fadeFromBlack(7, 0);
+
+ for (int i = 0; _handsAnimData[i] != 777 && !_vm->skipFlag() && !_vm->shouldQuit(); i += 2) {
+ uint32 end = _vm->_system->getMillis() + 60;
+ _screen->fillRect(40, 20, 240, 180, 0, 2);
+ _screen->drawShape(2, _shapes[1], 80 + _handsAnimData2[i], 20 + _handsAnimData2[i + 1]);
+ _screen->drawShape(2, _shapes[0], 80 + _handsAnimData[i], 20 + _handsAnimData[i + 1]);
+ _screen->copyRegion(80, 20, 88, 20, 160, 140, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ for (int i = 0; i < 32 && !_vm->skipFlag() && !_vm->shouldQuit(); i++) {
+ uint32 end = _vm->_system->getMillis() + 120;
+ _screen->fillRect(40, 20, 240, 180, 0, 2);
+ _screen->drawShape(2, _shapes[2], 80, 60 + _handsAnimData3[i]);
+ _screen->copyRegion(80, 20, 88, 20, 160, 140, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ fadeToBlack(7, 7);
+ releaseShapes();
+}
+
+void EoBPC98FinalePlayer::credits() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ _screen->clearPage(0);
+ _screen->setCurPage(4);
+ _screen->loadBitmap("NEWTEXT.BIN", 3, 5, 0);
+
+ for (int i = 0; i < 64; ++i)
+ _shapes[i] = _screen->encodeShape((i % 8) << 1, (i / 8) << 4, 2, 16);
+
+ _screen->loadBitmap("CLC-2.BIN", 3, 5, 0);
+ _screen->convertPage(5, 4, 0);
+ _screen->copyRegion(0, 0, 88, 10, 128, 80, 4, 0, Screen::CR_NO_P_CHECK);
+ fadeFromBlack(9, 2);
+
+ _screen->setCurPage(2);
+ _screen->clearPage(2);
+ int x = 50;
+ int y = 100;
+ bool skipPageReset = false;
+
+ for (const uint8 *pos = _creditsStrings; *pos && !_vm->skipFlag() && !_vm->shouldQuit(); ++pos) {
+ switch (*pos) {
+ case 8:
+ x = 50;
+ y += 8;
+ if (y > 183)
+ y = 0;
+ break;
+
+ case 9:
+ x = 100;
+ break;
+
+ case 12:
+ _screen->crossFadeRegion(50, 100, 50, 100, 200, 17, 2, 0);
+ _screen->fillRect(50, 100, 249, 116, 0, 2);
+ _screen->crossFadeRegion(50, 125, 50, 125, 230, 51, 2, 0);
+ _screen->fillRect(50, 125, 279, 175, 0, 2);
+ if (!skipPageReset) {
+ wait(360);
+ _screen->crossFadeRegion(50, 100, 50, 100, 236, 85, 2, 0);
+ _screen->fillRect(50, 100, 285, 184, 0, 2);
+ wait(60);
+ x = 50;
+ y = 100;
+ }
+ break;
+
+ case 13:
+ x = 50;
+ y += 17;
+ if (y > 183)
+ y = 0;
+ break;
+
+ case 32:
+ x += 12;
+ break;
+
+ case 64:
+ skipPageReset = true;
+ break;
+
+ default:
+ if (*pos >= 65) {
+ _screen->drawShape(2, _shapes[*pos - 65], x, y);
+ x += _creditsCharWdth[*pos - 65];
+ }
+ break;
+ }
+ }
+
+ wait(120);
+ _screen->copyRegion(128, 0, 88, 10, 128, 80, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ wait(20);
+ _screen->copyRegion(0, 88, 88, 10, 128, 80, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ releaseShapes();
+}
+
+void EoBPC98FinalePlayer::bonus() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ wait(300);
+ if (!_vm->checkScriptFlags(0x1FFE))
+ return;
+
+ fadeToBlack(9, 3);
+ _screen->setCurPage(0);
+ _screen->clearCurPage();
+ _vm->gui_drawBox(40, 30, 241, 151, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, _vm->guiSettings()->colors.fill);
+ _screen->printShadedText(_strings[9], 132, 40, _vm->guiSettings()->colors.guiColorWhite, 0, 0);
+ _screen->printShadedText(_strings[10], 72, 52, _vm->guiSettings()->colors.guiColorWhite, 0, 0);
+ _screen->printShadedText(_strings[11], 120, 70, _vm->guiSettings()->colors.guiColorWhite, 0, 0);
+ _screen->printShadedText(_vm->_finBonusStrings[0], 72, 82, _vm->guiSettings()->colors.guiColorWhite, 0, 0);
+
+ int cnt = 0;
+ for (int i = 0; i < 6; i++) {
+ if (_vm->_characters[i].flags & 1) {
+ _screen->printShadedText(_vm->_characters[i].name, 78 + (cnt / 3) * 90, 104 + (cnt % 3) * 15, _vm->guiSettings()->colors.guiColorLightRed, 0, 0);
+ cnt++;
+ }
+ }
+
+ uint32 password = 0;
+ for (int i = 0; i < 6; i++) {
+ if (!(_vm->_characters[i].flags & 1))
+ continue;
+
+ int len = strlen(_vm->_characters[i].name);
+ for (int ii = 0; ii < len; ii++) {
+ uint32 c = _vm->_characters[i].name[ii];
+ password += (c * c);
+ }
+ }
+
+ _screen->printShadedText(Common::String::format(_vm->_finBonusStrings[2], password).c_str(), 120, 156, _vm->guiSettings()->colors.guiColorWhite, 0, 0);
+ fadeFromBlack(0, 3);
+}
+
+template<int brStart, int brEnd, int brInc> void EoBPC98FinalePlayer::pc98FadePalette(int palId, uint32 del) {
+ if (_vm->gameFlags().platform != Common::kPlatformPC98)
+ return;
+
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ del = del * _tickLength;
+
+ for (int i = brStart; i != brEnd && !_vm->skipFlag() && !_vm->shouldQuit(); i += brInc) {
+ uint32 end = _vm->_system->getMillis() + del;
+ if (_updatePalCycle) {
+ for (uint32 cur = _vm->_system->getMillis(); end > cur; cur = _vm->_system->getMillis()) {
+ _screen->updatePC98PaletteCycle(i);
+ _screen->updateScreen();
+ int step = MIN<int>(end - cur, _palCycleDelay);
+ if (step > 0)
+ _vm->delay(step);
+ }
+ } else {
+ _screen->selectPC98Palette(palId, _screen->getPalette(0), i, true);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+ }
+
+ if (_vm->skipFlag() || _vm->shouldQuit()) {
+ _screen->selectPC98Palette(palId, _screen->getPalette(0), brEnd, true);
+ _screen->updateScreen();
+ }
+}
+
+void EoBPC98FinalePlayer::startPaletteCycle(int palId, int style) {
+ if (style == 0)
+ _screen->initPC98PaletteCycle(palId, _palCycleType1);
+ else if (style == 1)
+ _screen->initPC98PaletteCycle(palId, _palCycleType2);
+
+ if (style == 0 || style == 1)
+ resetPaletteCycle();
+
+ _updatePalCycle = true;
+}
+
+void EoBPC98FinalePlayer::stopPaletteCycle() {
+ _updatePalCycle = false;
+ _screen->initPC98PaletteCycle(0, 0);
+}
+
+void EoBPC98FinalePlayer::resetPaletteCycle() {
+ int temp = 0;
+ const uint8 *data = _vm->staticres()->loadRawData(kEoB1PalCycleData, temp);
+ const uint16 *stl1 = _vm->staticres()->loadRawDataBe16(kEoB1PalCycleStyle1, temp);
+ const uint16 *stl2 = _vm->staticres()->loadRawDataBe16(kEoB1PalCycleStyle2, temp);
+
+ for (int i = 0; i < 48; ++i) {
+ _palCycleType1[i].data = (const int8*)(data + stl1[i * 2]);
+ _palCycleType1[i].delay = stl1[i * 2 + 1];
+ _palCycleType2[i].data = (const int8*)(data + stl2[i * 2]);
+ _palCycleType2[i].delay = stl2[i * 2 + 1];
+ }
+}
+
+void EoBPC98FinalePlayer::wait(uint32 ticks) {
+ uint32 millis = ticks * _tickLength;
+ uint32 end = _vm->_system->getMillis() + millis;
+ for (uint32 cur = _vm->_system->getMillis(); end > cur && !_vm->skipFlag() && !_vm->shouldQuit(); cur = _vm->_system->getMillis()) {
+ if (_updatePalCycle) {
+ _screen->updatePC98PaletteCycle(0);
+ _screen->updateScreen();
+ }
+ int step = MIN<int>(end - cur, _palCycleDelay);
+ if (step > 0)
+ _vm->delay(step);
+ }
+}
+
EoBAmigaFinalePlayer::EoBAmigaFinalePlayer(EoBEngine *vm, Screen_EoB *screen) : EoBSeqPlayerCommon(vm, screen) {
_animCurFrame = 0;
int size = 0;
@@ -1248,7 +1802,7 @@ void EoBAmigaFinalePlayer::start() {
_vm->_eventList.clear();
_vm->_allowSkip = true;
- _vm->sound()->playTrack(0);
+ _vm->snd_playSong(0);
entry();
delivery();
@@ -1724,6 +2278,11 @@ void EoBEngine::seq_playIntro(int part) {
}
void EoBEngine::seq_playFinale() {
+ if (_flags.platform == Common::kPlatformPC98) {
+ EoBPC98FinalePlayer(this, _screen).start(_xdth);
+ return;
+ }
+
Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
_screen->loadFileDataToPage(s, 5, 32000);
delete s;
@@ -1768,6 +2327,7 @@ void EoBEngine::seq_playFinale() {
void EoBEngine::seq_xdeath() {
uint8 *shapes1[5];
uint8 *shapes2;
+ _xdth = true;
_screen->loadShapeSetBitmap("XDEATH2", 5, 3);
for (int i = 0; i < 4; i++)