KYRA: (EOB/SegaCD) - fix various sequences and gameover screen

(xdeath sequence, portal sequence, npc sequences)
This commit is contained in:
athrxx 2020-04-13 01:51:33 +02:00
parent 5bffb5b9de
commit b48a37dc2f
21 changed files with 559 additions and 229 deletions

View File

@ -169,7 +169,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
gui_drawDialogueBox();
_txt->printDialogueText(4, 0);
int r = runDialogue(-1, 2, _npcStrings[0][0], _npcStrings[0][1]) - 1;
int r = runDialogue(-1, 2, -1, _npcStrings[0][0], _npcStrings[0][1]) - 1;
if (r == 0) {
snd_stopSound();
@ -185,7 +185,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
gui_drawDialogueBox();
_txt->printDialogueText(8, 0);
int r = runDialogue(-1, 2, _npcStrings[1][0], _npcStrings[1][1]) - 1;
int r = runDialogue(-1, 2, -1, _npcStrings[1][0], _npcStrings[1][1]) - 1;
if (r == 0) {
if (rollDice(1, 2, -1))
@ -717,7 +717,7 @@ int DarkMoonEngine::resurrectionSelectDialogue() {
_rrNames[_rrCount] = _abortStrings[0];
_rrId[_rrCount++] = 99;
int r = _rrId[runDialogue(-1, 9, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
int r = _rrId[runDialogue(-1, 9, -1, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
if (r == 99)
return 0;
@ -745,7 +745,7 @@ int DarkMoonEngine::charSelectDialogue() {
namesList[cnt++] = _abortStrings[0];
int r = runDialogue(-1, 7, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6]) - 1;
int r = runDialogue(-1, 7, -1, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6]) - 1;
if (r == cnt - 1)
return 99;

View File

@ -214,6 +214,7 @@ void EoBEngine::loadItemsAndDecorationsShapes() {
loadAndConvertShapes(1, 0, _smallItemShapes, _numSmallItemShapes, 32, 24, 768);
loadAndConvertShapes(2, 0, _largeItemShapes, _numLargeItemShapes, 64, 24, 1472);
loadAndConvertShapes(3, 0, _sparkShapes, 3, 16, 16, 128);
loadAndConvertShapes(11, 0, _thrownItemShapes, _numThrownItemShapes, 32, 24, 768);
int offset1 = 0, offset2 = 0;
for (int i = 0; i < 3; ++i) {
@ -230,16 +231,7 @@ void EoBEngine::loadItemsAndDecorationsShapes() {
loadSpritesAndEncodeToShapes(5, 480, _weaponSlotShapes, 6, 32, 16);
loadSpritesAndEncodeToShapes(6, 0, _invSmallDigits, 32, 16, 8);
/*
// CAMP MENU
str = _sres->resStreamEndian(8);
_screen->sega_getRenderer()->loadStreamToVRAM(str, 0x20, true);
delete str;
_screen->sega_getRenderer()->fillRectWithTiles(0, 0, 0, 22, 15, 0);
_screen->sega_getRenderer()->fillRectWithTiles(1, 0, 0, 22, 21, 0x4001, true);
_screen->sega_getRenderer()->render(0);
_screen->sega_selectPalette(40, 2, true);
*/
int cp = _screen->setCurPage(Screen_EoB::kSegaInitShapesPage);
for (int i = 0; i < 4; ++i)
@ -366,23 +358,27 @@ void EoBEngine::encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY) {
delete[] shp;
}
#define DLG2(txt, buttonstr) (runDialogue(txt, 2, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1]) - 1)
#define DLG3(txt, buttonstr) (runDialogue(txt, 3, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1], _npcStrings[buttonstr][2]) - 1)
#define DLG2A3(cond, txt, buttonstr1, buttonstr2) ((cond) ? (DLG2(txt, buttonstr1) ? 2 : 0) : DLG3(txt, buttonstr2))
#define TXT(txt) _txt->printDialogueText(txt, _moreStrings[0])
#define DLG2(txt, buttonstr, repeat) ((_flags.platform == Common::kPlatformSegaCD && repeat ? runDialogue(txt, 3, 3, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1], _npcStrings[buttonstr][2]) : runDialogue(txt, 2, -1, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1])) - 1)
#define DLG3(txt, buttonstr, repeat) ((_flags.platform == Common::kPlatformSegaCD && repeat ? runDialogue(txt, 4, 4, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1], _npcStrings[buttonstr][2], _npcStrings[buttonstr][3]) : runDialogue(txt, 3, -1, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1], _npcStrings[buttonstr][2])) - 1)
#define DLG2A3(cond, txt, buttonstr1, buttonstr2) ((cond) ? (DLG2(txt, buttonstr1, 0) ? 2 : 0) : DLG3(txt, buttonstr2, 0))
#define TXT(txt) _txt->printDialogueText(txt, _moreStrings[0], _flags.platform == Common::kPlatformSegaCD ? _moreStrings[1] : 0)
#define TXTNB(txt) _txt->printDialogueText(txt, _flags.platform == Common::kPlatformSegaCD ? 0 : _moreStrings[0])
#define JOIN(npc, txt_query, txt_conf, txt_deny) npcJoinDialogue(npc, txt_query, _flags.platform == Common::kPlatformSegaCD ? -1 : txt_conf, _flags.platform == Common::kPlatformSegaCD ? -1 : txt_deny)
void EoBEngine::runNpcDialogue(int npcIndex) {
int r = 0;
int a = 0;
Item itm = 0;
seq_segaSetupSequence(0);
switch (npcIndex) {
case 0:
for (r = 1; r == 1;) {
gui_drawDialogueBox();
if (_flags.platform != Common::kPlatformSegaCD)
gui_drawDialogueBox();
r = DLG2A3(checkScriptFlags(0x2000), 8, 2, 1);
if (r == 1) {
TXT(1);
TXTNB(1);
setScriptFlags(0x2000);
} else if (r == 0) {
npcJoinDialogue(6, 12, 23, 2);
@ -397,11 +393,11 @@ void EoBEngine::runNpcDialogue(int npcIndex) {
a = 13;
} else {
setScriptFlags(0x8000);
r = DLG2(3, 3);
r = DLG2(3, 3, 1);
a = 4;
}
if (!r)
r = DLG2(a, 4);
r = DLG2(a, 4, 1);
if (!r) {
for (a = 0; a < 6; a++)
@ -409,9 +405,9 @@ void EoBEngine::runNpcDialogue(int npcIndex) {
createItemOnCurrentBlock(62);
setScriptFlags(0x10000);
TXT(6);
npcJoinDialogue(7, 7, 29, 30);
JOIN(7, 7, 29, 30);
} else {
TXT(5);
TXTNB(5);
}
r = 1;
}
@ -423,7 +419,8 @@ void EoBEngine::runNpcDialogue(int npcIndex) {
}
if (a != 6) {
TXT(25);
TXT(26);
if (_flags.platform != Common::kPlatformSegaCD)
TXT(26);
setScriptFlags(0x80000);
r = 1;
}
@ -440,15 +437,19 @@ void EoBEngine::runNpcDialogue(int npcIndex) {
}
}
if (!r)
_txt->printDialogueText(_npcStrings[0][0], true);
if (!r) {
if (_flags.platform == Common::kPlatformSegaCD)
TXTNB(44);
else
_txt->printDialogueText(_npcStrings[0][0], true);
}
break;
case 2:
if (checkScriptFlags(0x10000)) {
if (checkScriptFlags(0x20000)) {
TXT(11);
TXTNB(11);
} else {
r = DLG2A3(!countResurrectionCandidates(), 9, 5, 6);
if (r < 2) {
@ -460,12 +461,12 @@ void EoBEngine::runNpcDialogue(int npcIndex) {
}
}
} else {
TXT(24);
TXTNB(24);
}
break;
case 3:
if (!DLG2(18, 7)) {
if (!DLG2(18, 7, 0)) {
setScriptFlags(0x8400000);
for (a = 0; a < 30; a++) {
if (_monsters[a].mode == 8)
@ -480,7 +481,7 @@ void EoBEngine::runNpcDialogue(int npcIndex) {
break;
case 4:
r = DLG3(14, 8);
r = DLG3(14, 8, 1);
if (r == 0)
setScriptFlags(0x200000);
else if (r == 1)
@ -489,8 +490,9 @@ void EoBEngine::runNpcDialogue(int npcIndex) {
break;
case 5:
if (!DLG2(16, 9)) {
TXT(17);
if (!DLG2(16, 9, 1)) {
if (_flags.platform != Common::kPlatformSegaCD)
TXT(17);
for (a = 0; a < 6; a++) {
for (r = 0; r < 2; r++) {
itm = _characters[a].inventory[r];
@ -510,10 +512,10 @@ void EoBEngine::runNpcDialogue(int npcIndex) {
break;
case 7:
r = DLG3(22, 10);
if (r < 2) {
r = DLG3(22, 10, 1);
if (r < 2) {
if (r == 0)
npcJoinDialogue(8, 27, 44, 45);
JOIN(8, 27, 44, 45);
else
TXT(31);
setScriptFlags(0x4000000);
@ -523,8 +525,16 @@ void EoBEngine::runNpcDialogue(int npcIndex) {
default:
break;
}
seq_segaRestoreAfterSequence();
setLevelPalettes(_currentLevel);
_levelCurTrack = -1;
if (_flags.platform == Common::kPlatformSegaCD)
snd_playLevelScore();
}
#undef JOIN
#undef TXTNB
#undef TXT
#undef DLG2
#undef DLG3
@ -975,12 +985,12 @@ void EoBEngine::displayParchment(int id) {
int temp = 0;
const char *const *strings = _staticres->loadStrings(kEoB1ParchmentStrings, temp);
_sceneShakeCountdown = 0;
gui_resetAnimations();
for (int i = 0; i < 6; i++) {
if (!testCharacter(i, 1))
continue;
_characters[i].damageTaken = 0;
_characters[i].slotStatus[0] = _characters[i].slotStatus[1] = _characters[i].gfxUpdateCountdown = 0;
_characters[i].slotStatus[0] = _characters[i].slotStatus[1] = 0;
gui_drawCharPortraitWithStats(i);
}
@ -1027,25 +1037,137 @@ void EoBEngine::displayParchment(int id) {
_totalPlaySecs += ((_system->getMillis() - startTime) / 1000);
}
void EoBEngine::drawParchmentPage(int page) {
const uint8 **EoBEngine::makePortalShapes() {
if (_flags.platform != Common::kPlatformSegaCD) {
return EoBCoreEngine::makePortalShapes();
}
gui_resetAnimations();
gui_updateAnimations();
snd_stopSound();
uint8 *data = _res->fileData("PORT", 0);
const uint8 *in = data;
const uint8 **shapes = new const uint8*[16];
for (int i = 0; i < 10; ++i) {
shapes[1 + i] = _screen->sega_convertShape(in, 24, 80, 2);
in += 960;
}
for (int i = 0; i < 5; ++i) {
shapes[11 + i] = _screen->sega_convertShape(in, 120, 24, 2);
in += 1440;
}
shapes[0] = _screen->sega_convertShape(in, 64, 80, 2);
in += 2560;
_screen->clearPage(2);
for (int i = 0; i < 10; ++i) {
uint8 *shp = _screen->sega_convertShape(in, 64, 80, 2);
_screen->drawShape(2, shp, (i % 5) << 6, (i / 5) * 77, 0);
in += 2560;
}
delete[] data;
return shapes;
}
bool EoBEngine::checkPartyStatusExtra() {
_screen->copyPage(0, Screen_EoB::kDefeatMsgBackupPage);
int cd = _screen->curDimIndex();
gui_drawBox(0, 121, 320, 80, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
_txt->setupField(9, false);
_txt->printMessage(_menuStringsDefeat[0]);
while (!shouldQuit()) {
removeInputTop();
if (checkInput(0, false, 0) & 0xFF)
break;
if (_flags.platform == Common::kPlatformSegaCD) {
_screen->sega_fadeToBlack(4);
gui_resetAnimations();
gui_updateAnimations();
snd_stopSound();
Common::SeekableReadStreamEndian *in = _res->createEndianAwareReadStream("GO");
SegaRenderer *r = _screen->sega_getRenderer();
r->loadStreamToVRAM(in, 0x20);
delete in;
_screen->hideMouse();
_screen->sega_selectPalette(51, 0);
_screen->sega_selectPalette(52, 1);
_screen->sega_selectPalette(53, 2);
_screen->sega_selectPalette(7, 3);
r->fillRectWithTiles(0, 0, 0, 40, 28, 0);
r->fillRectWithTiles(1, 0, 0, 40, 28, 0);
r->fillRectWithTiles(0, 0, 3, 32, 16, 1, true);
r->fillRectWithTiles(0, 32, 3, 8, 16, 0x201, true);
r->fillRectWithTiles(1, 0, 3, 32, 16, 0x2281, true);
r->fillRectWithTiles(1, 32, 3, 8, 16, 0x2481, true);
int cs = _screen->setFontStyles(_screen->_currentFont, _flags.lang == Common::JA_JPN ? Font::kStyleFixedWidth : Font::kStyleForceTwoByte | Font::kStyleFat);
_screen->sega_clearTextBuffer(0);
_txt->printShadowedText(_menuStringsDefeat[0], 12, 0, 0xff, 0xcc, 304, 48, 0, false);
_txt->printShadowedText(_menuStringsDefeat[1], 20, 16, 0xff, 0xcc, 304, 48, 0, false);
_txt->printShadowedText(_menuStringsDefeat[2], 20, 32, 0xff, 0xcc, 304, 48, 0, false);
_screen->setFontStyles(_screen->_currentFont, cs);
_screen->sega_loadTextBufferToVRAM(0, 0xA3A0, 7296);
r->fillRectWithTiles(0, 1, 20, 38, 6, 0x651D, true);
r->render(0);
snd_playSoundEffect(0x5086);
_screen->sega_paletteOps(0, 0, 5);
_screen->sega_paletteOps(1, 0, 5);
uint32 del = _system->getMillis() + 1333;
for (uint32 cur = _system->getMillis(); cur < del; cur = _system->getMillis()) {
_screen->sega_updatePaletteFaders(0);
_screen->sega_updatePaletteFaders(1);
delay(MIN<uint32>(8, del - cur));
}
_screen->sega_paletteOps(3, 0, 6);
del = _system->getMillis() + 1600;
for (uint32 cur = _system->getMillis(); cur < del; cur = _system->getMillis()) {
_screen->sega_updatePaletteFaders(3);
delay(MIN<uint32>(8, del - cur));
}
for (int i = 0; i < 7; ++i)
_screen->sega_getAnimator()->initSprite(i, 104 + (i << 4), 80, 0x4501 + (i << 2), 5);
_screen->sega_getAnimator()->update();
r->render(0);
_screen->sega_paletteOps(2, 0, 5);
resetSkipFlag();
_allowSkip = true;
while (!(shouldQuit() || skipFlag())) {
_screen->sega_updatePaletteFaders(2);
delay(8);
}
_allowSkip = false;
resetSkipFlag();
_screen->sega_fadeToBlack(4);
_screen->sega_getAnimator()->clearSprites();
_screen->sega_getAnimator()->update();
snd_playSoundEffect(0x5087);
_screen->showMouse();
} else {
gui_drawBox(0, 121, 320, 80, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
_txt->setupField(9, false);
_txt->printMessage(_menuStringsDefeat[0]);
while (!shouldQuit()) {
removeInputTop();
if (checkInput(0, false, 0) & 0xFF)
break;
}
}
_screen->copyPage(Screen_EoB::kDefeatMsgBackupPage, 0);
_eventList.clear();
_screen->setScreenDim(cd);
_txt->removePageBreakFlag();
return true;
}
@ -1053,13 +1175,29 @@ int EoBEngine::resurrectionSelectDialogue() {
gui_drawDialogueBox();
_txt->printDialogueText(_npcStrings[0][1]);
int r = _rrId[runDialogue(-1, 9, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
if (_flags.platform == Common::kPlatformSegaCD) {
resetSkipFlag();
_allowSkip = true;
while (!(shouldQuit() || skipFlag()))
delay(20);
_allowSkip = false;
resetSkipFlag();
_rrNames[_rrCount] = _abortStrings[0];
_rrId[_rrCount++] = 99;
}
int r = _rrId[runDialogue(-1, 9, -1, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
if (r == 99)
return 0;
if (r < 0) {
r = -r;
deletePartyItems(33, r);
_npcSequenceSub = r - 1;
drawNpcScene(2);
if (_flags.platform != Common::kPlatformSegaCD)
drawNpcScene(2);
npcJoinDialogue(_npcSequenceSub, 32 + (_npcSequenceSub << 1), -1, 33 + (_npcSequenceSub << 1));
} else {
_characters[r].hitPointsCur = _characters[r].hitPointsMax;

View File

@ -37,6 +37,7 @@ friend class EoBSeqPlayerCommon;
friend class EoBIntroPlayer;
friend class EoBPC98FinalePlayer;
friend class EoBAmigaFinalePlayer;
friend class TextDisplayer_SegaCD;
friend class SegaSequencePlayer;
public:
EoBEngine(OSystem *system, const GameFlags &flags);
@ -98,7 +99,7 @@ private:
void seq_segaSetupSequence(int sequenceId);
void seq_segaRestoreAfterSequence();
bool seq_segaPlaySequence(int sequenceId, bool init = false);
bool seq_segaPlaySequence(int sequenceId, bool setupScreen = false);
const char *const *_finBonusStrings;
SegaSequencePlayer *_seqPlayer;
@ -177,7 +178,7 @@ private:
// Misc
void displayParchment(int id) override;
void drawParchmentPage(int page);
const uint8 **makePortalShapes() override;
bool checkPartyStatusExtra() override;
int resurrectionSelectDialogue() override;
void healParty();
@ -187,11 +188,6 @@ private:
uint8 *_shakeBackBuffer1;
uint8 *_shakeBackBuffer2;
// Map
const char *const *_mapStrings1;
const char *const *_mapStrings2;
const char *const *_mapStrings3;
// Resource
SegaCDResource *_sres;
@ -203,13 +199,15 @@ private:
void gui_drawCharacterStatsPage() override;
void gui_displayMap() override;
void gui_updateAnimations() override;
void gui_resetAnimations();
void makeNameShapes() override;
void makeFaceShapes() override;
void makeNameShapes(int charId = -1) override;
void makeFaceShapes(int charId = -1) override;
void printStatsString(const char *str, int x, int y);
void drawMapButton(const char *str, int x, int y);
void drawMapPage(int level);
void drawMapSpots(int level, int animState);
void drawDialogueButtons() override;
const KyraRpgGUISettings *guiSettings() const override;
void useMainMenuGUISettings(bool toggle) override { _useMainMenuGUISettings = toggle; }
@ -223,9 +221,11 @@ private:
bool _compassAnimDone;
uint8 *_compassData;
const char *const *_mapStrings1;
const char *const *_mapStrings2;
const char *const *_mapStrings3;
const uint8 **_invSmallDigits;
const uint8 **_weaponSlotShapes;
const uint16 *_addrTbl1;
const uint16 *_textFieldPattern;
const uint16 *_playFldPattern1;
@ -244,6 +244,8 @@ private:
static const uint8 _egaDefaultPalette[];
static const uint8 _redGridTile[8];
static const int8 _sceneShakeOffsets[66];
static const uint16 _dlgButtonPosX_Sega[18];
static const uint8 _dlgButtonPosY_Sega[18];
bool _useMainMenuGUISettings;
};

View File

@ -402,9 +402,8 @@ Common::Error EoBCoreEngine::init() {
if (!_staticres->init())
error("_staticres->init() failed");
// We start the respective sound driver even if "No Music" has
// been selected, because we don't have a null driver class (and
// don't really need one). We just disable the sound here.
// We start the respective sound driver even if "No Music" has been selected, because we
// don't have a null driver class (and don't really need one). We just disable the sound here.
MidiDriver::DeviceHandle dev = 0;
switch (_flags.platform) {
case Common::kPlatformDOS: {
@ -1301,26 +1300,28 @@ void EoBCoreEngine::neutralizePoison(int character) {
}
void EoBCoreEngine::npcSequence(int npcIndex) {
_screen->loadShapeSetBitmap("OUTTAKE", 5, 3);
_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
if (_flags.platform != Common::kPlatformSegaCD) {
_screen->loadShapeSetBitmap("OUTTAKE", 5, 3);
_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
drawNpcScene(npcIndex);
drawNpcScene(npcIndex);
Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
if (s) {
_screen->loadFileDataToPage(s, 5, 32000);
} else {
s = _res->createReadStream("TEXT.CPS");
if (s->readSint32BE() + 12 == s->size())
_screen->loadSpecialAmigaCPS("TEXT.CPS", 5, false);
else
_screen->loadBitmap("TEXT.CPS", 5, 5, 0, true);
}
delete s;
Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
if (s) {
_screen->loadFileDataToPage(s, 5, 32000);
} else {
s = _res->createReadStream("TEXT.CPS");
if (s->readSint32BE() + 12 == s->size())
_screen->loadSpecialAmigaCPS("TEXT.CPS", 5, false);
else
_screen->loadBitmap("TEXT.CPS", 5, 5, 0, true);
}
delete s;
gui_drawBox(0, 121, 320, 79, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
_txt->setupField(9, true);
_txt->resetPageBreakString();
gui_drawBox(0, 121, 320, 79, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
_txt->setupField(9, true);
_txt->resetPageBreakString();
}
runNpcDialogue(npcIndex);
@ -1341,24 +1342,19 @@ void EoBCoreEngine::initNpc(int npcIndex) {
delete[] c->faceShape;
memcpy(c, &_npcPreset[npcIndex], sizeof(EoBCharacter));
recalcArmorClass(i);
makeFaceShapes(i);
makeNameShapes(i);
for (i = 0; i < 25; i++) {
if (!c->inventory[i])
continue;
c->inventory[i] = duplicateItem(c->inventory[i]);
}
_screen->loadShapeSetBitmap(_flags.gameID == GI_EOB2 ? "OUTPORTS" : "OUTTAKE", 3, 3);
_screen->_curPage = 2;
c->faceShape = _screen->encodeShape(npcIndex << 2, _flags.gameID == GI_EOB2 ? 0 : 160, 4, 32, true, _cgaMappingDefault);
_screen->_curPage = 0;
}
int EoBCoreEngine::npcJoinDialogue(int npcIndex, int queryJoinTextId, int confirmJoinTextId, int noJoinTextId) {
gui_drawDialogueBox();
_txt->printDialogueText(queryJoinTextId, 0);
int r = runDialogue(-1, 2, _yesNoStrings[0], _yesNoStrings[1]) - 1;
int r = runDialogue(queryJoinTextId, _flags.platform == Common::kPlatformSegaCD ? 3 : 2, _flags.platform == Common::kPlatformSegaCD ? 3 : -1, _yesNoStrings[0], _yesNoStrings[1], _flags.platform == Common::kPlatformSegaCD ? _yesNoStrings[2] : 0) - 1;
if (r == 0) {
if (confirmJoinTextId == -1) {
Common::String tmp = Common::String::format(_npcJoinStrings[0], _npcPreset[npcIndex].name);
@ -1370,7 +1366,7 @@ int EoBCoreEngine::npcJoinDialogue(int npcIndex, int queryJoinTextId, int confir
if (prepareForNewPartyMember(33, npcIndex + 1))
initNpc(npcIndex);
} else if (r == 1) {
} else if (r == 1 && noJoinTextId != -1) {
_txt->printDialogueText(noJoinTextId, _okStrings[0]);
}
@ -1389,8 +1385,17 @@ int EoBCoreEngine::prepareForNewPartyMember(int16 itemType, int16 itemValue) {
_screen->set16bitShadingLevel(4);
_txt->printDialogueText(_npcMaxStrings[0]);
_screen->set16bitShadingLevel(0);
int r = runDialogue(-1, 7, _characters[0].name, _characters[1].name, _characters[2].name, _characters[3].name,
_characters[4].name, _characters[5].name, _abortStrings[0]) - 1;
if (_flags.platform == Common::kPlatformSegaCD) {
resetSkipFlag();
_allowSkip = true;
while (!(shouldQuit() || skipFlag()))
delay(20);
_allowSkip = false;
resetSkipFlag();
}
int r = runDialogue(-1, 7, -1, _characters[0].name, _characters[1].name, _characters[2].name, _characters[3].name, _characters[4].name, _characters[5].name, _abortStrings[0]) - 1;
if (r == 6)
return 0;
@ -1527,15 +1532,13 @@ void EoBCoreEngine::setupDialogueButtons(int presetfirst, int numStr, va_list &a
_dialogueNumButtons = numStr = i;
}
static const uint16 prsX[] = { 59, 166, 4, 112, 220, 4, 112, 220, 4, 112, 220, 4, 112, 220 };
static const uint8 prsY[] = { 0, 0, 0, 0, 0, 12, 12, 12, 24, 24, 24, 36, 36, 36 };
const ScreenDim *dm = screen()->_curDim;
int yOffs = (_txt->lineCount() + 1) * _screen->getFontHeight() + dm->sy + 4;
_dialogueButtonPosX = &prsX[presetfirst];
_dialogueButtonPosY = &prsY[presetfirst];
_dialogueButtonYoffs = yOffs;
_dialogueButtonPosX = &guiSettings()->buttons.posX[presetfirst];
_dialogueButtonPosY = &guiSettings()->buttons.posY[presetfirst];
_dialogueButtonXoffs = (_flags.platform == Common::kPlatformSegaCD) ? 8 : 0;
_dialogueButtonYoffs = (_flags.platform == Common::kPlatformSegaCD) ? 160 : yOffs;
drawDialogueButtons();
@ -1644,23 +1647,29 @@ void EoBCoreEngine::drawSequenceBitmap(const char *file, int destRect, int x1, i
_screen->updateScreen();
}
int EoBCoreEngine::runDialogue(int dialogueTextId, int numStr, ...) {
if (dialogueTextId != -1)
txt()->printDialogueText(dialogueTextId, 0);
int EoBCoreEngine::runDialogue(int dialogueTextId, int numStr, int loopButtonId, ...) {
int res;
do {
res = 0;
if (dialogueTextId != -1)
txt()->printDialogueText(dialogueTextId, 0);
va_list args;
va_start(args, numStr);
if (numStr > 2)
setupDialogueButtons(2, numStr, args);
else
setupDialogueButtons(0, numStr, args);
va_end(args);
va_list args;
va_start(args, loopButtonId);
if (_flags.platform == Common::kPlatformSegaCD && numStr > 3)
setupDialogueButtons(numStr == 4 ? 14 : 5, numStr, args);
else if (numStr > 2)
setupDialogueButtons(2, numStr, args);
else
setupDialogueButtons(0, numStr, args);
va_end(args);
int res = 0;
while (res == 0 && !shouldQuit())
res = processDialogue();
while (res == 0 && !shouldQuit())
res = processDialogue();
} while (res == loopButtonId && !shouldQuit());
gui_drawDialogueBox();
if (_flags.platform != Common::kPlatformSegaCD)
gui_drawDialogueBox();
return res;
}
@ -1874,72 +1883,84 @@ int EoBCoreEngine::countResurrectionCandidates() {
}
void EoBCoreEngine::seq_portal() {
uint8 *shapes1[5];
uint8 *shapes2[5];
uint8 *shapes3[5];
uint8 *shape0;
const uint8 **shapes = makePortalShapes();
assert(shapes);
_screen->loadShapeSetBitmap("PORTALA", 5, 3);
for (int i = 0; i < 5; i++) {
shapes1[i] = _screen->encodeShape(i * 3, 0, 3, 75, false, _cgaMappingDefault);
shapes2[i] = _screen->encodeShape(i * 3, 80, 3, 75, false, _cgaMappingDefault);
shapes3[i] = _screen->encodeShape(15, i * 18, 15, 18, false, _cgaMappingDefault);
}
shape0 = _screen->encodeShape(30, 0, 8, 77, false, _cgaMappingDefault);
_screen->loadEoBBitmap("PORTALB", _cgaMappingDefault, 5, 3, 2);
snd_playSoundEffect(33);
snd_playSoundEffect(19);
_screen->copyRegion(24, 0, 24, 0, 144, 104, 2, 5, Screen::CR_NO_P_CHECK);
_screen->copyRegion(24, 0, 24, 0, 144, 104, 0, 2, Screen::CR_NO_P_CHECK);
_screen->drawShape(2, shapes3[0], 28, 9, 0);
_screen->drawShape(2, shapes1[0], 34, 28, 0);
_screen->drawShape(2, shapes2[0], 120, 28, 0);
_screen->drawShape(2, shape0, 56, 27, 0);
_screen->crossFadeRegion(24, 0, 24, 0, 144, 104, 2, 0);
_screen->drawShape(2, shapes[11], 28, 9, 0);
_screen->drawShape(2, shapes[1], 34, 28, 0);
_screen->drawShape(2, shapes[6], 120, 28, 0);
_screen->drawShape(2, shapes[0], 56, 27, 0);
if (_flags.platform == Common::kPlatformSegaCD) {
snd_playSoundEffect(19);
_screen->copyRegion(24, 0, 24, 0, 144, 104, 2, 0, Screen::CR_NO_P_CHECK);
_screen->updateScreen();
} else {
snd_playSoundEffect(33);
snd_playSoundEffect(19);
_screen->crossFadeRegion(24, 0, 24, 0, 144, 104, 2, 0);
delay(30 * _tickLength);
}
_screen->copyRegion(24, 0, 24, 0, 144, 104, 5, 2, Screen::CR_NO_P_CHECK);
delay(30 * _tickLength);
for (const int8 *pos = _portalSeq; *pos > -1 && !shouldQuit();) {
int s = *pos++;
_screen->drawShape(0, shapes3[s], 28, 9, 0);
_screen->drawShape(0, shapes1[s], 34, 28, 0);
_screen->drawShape(0, shapes2[s], 120, 28, 0);
_screen->drawShape(0, shapes[11 + s], 28, 9, 0);
_screen->drawShape(0, shapes[1 + s], 34, 28, 0);
_screen->drawShape(0, shapes[6 + s], 120, 28, 0);
if ((s == 1) && (pos >= _portalSeq + 3)) {
if (*(pos - 3) == 0) {
snd_playSoundEffect(24);
snd_playSoundEffect(86);
if (_flags.platform != Common::kPlatformSegaCD) {
if ((s == 1) && (pos >= _portalSeq + 3)) {
if (*(pos - 3) == 0) {
snd_playSoundEffect(24);
snd_playSoundEffect(86);
}
}
}
s = *pos++;
if (s == 0) {
_screen->drawShape(0, shape0, 56, 27, 0);
_screen->drawShape(0, shapes[0], 56, 27, 0);
} else {
s--;
_screen->copyRegion((s % 5) << 6, s / 5 * 77, 56, 27, 64, 77, 2, 0, Screen::CR_NO_P_CHECK);
}
if (s == 1)
snd_playSoundEffect(31);
else if (s == 3) {
if (*(pos - 2) == 3)
snd_playSoundEffect(90);
if (_flags.platform != Common::kPlatformSegaCD) {
if (s == 1)
snd_playSoundEffect(31);
else if (s == 3) {
if (*(pos - 2) == 3)
snd_playSoundEffect(90);
}
}
_screen->updateScreen();
delay(2 * _tickLength);
}
for (int i = 0; i < 16; i++)
delete[] shapes[i];
delete[] shapes;
}
const uint8 **EoBCoreEngine::makePortalShapes() {
const uint8 **shapes = new const uint8*[16];
_screen->loadShapeSetBitmap("PORTALA", 5, 3);
delete[] shape0;
for (int i = 0; i < 5; i++) {
delete[] shapes1[i];
delete[] shapes2[i];
delete[] shapes3[i];
shapes[1 + i] = _screen->encodeShape(i * 3, 0, 3, 75, false, _cgaMappingDefault);
shapes[6 + i] = _screen->encodeShape(i * 3, 80, 3, 75, false, _cgaMappingDefault);
shapes[11 + i] = _screen->encodeShape(15, i * 18, 15, 18, false, _cgaMappingDefault);
}
shapes[0] = _screen->encodeShape(30, 0, 8, 77, false, _cgaMappingDefault);
_screen->loadEoBBitmap("PORTALB", _cgaMappingDefault, 5, 3, 2);
return shapes;
}
bool EoBCoreEngine::checkPassword() {

View File

@ -846,7 +846,7 @@ protected:
void initDialogueSequence();
void restoreAfterDialogueSequence();
void drawSequenceBitmap(const char *file, int destRect, int x1, int y1, int flags);
int runDialogue(int dialogueTextId, int numStr, ...);
int runDialogue(int dialogueTextId, int numStr, int loopButtonId, ...);
char _dialogueLastBitmap[13];
int _moveCounter;
@ -904,6 +904,7 @@ protected:
int countResurrectionCandidates();
void seq_portal();
virtual const uint8 **makePortalShapes();
bool seq_playSegaSequence(int id) { return true; }
bool checkPassword();
@ -934,8 +935,8 @@ protected:
Common::Error loadGameState(int slot) override;
Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) override;
virtual void makeNameShapes() {}
virtual void makeFaceShapes();
virtual void makeNameShapes(int charId = -1) {}
virtual void makeFaceShapes(int charId = -1);
// Default parameters will import all present original save files and push them to the top of the save dialog.
bool importOriginalSaveFile(int destSlot, const char *sourceFile = 0);
Common::String readOriginalSaveFile(Common::String &file);

View File

@ -241,6 +241,9 @@ int EoBCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
if (item < 0)
return 0;
if (slot == 27)
return 1;
if (slot == 17 && item && !itemUsableByCharacter(charIndex, item)) {
_txt->printMessage(_validateArmorString[0], -1, _characters[charIndex].name);
return 0;

View File

@ -114,7 +114,7 @@ KyraRpgEngine::KyraRpgEngine(OSystem *system, const GameFlags &flags) : KyraEngi
memset(_dialogueButtonString, 0, 3 * sizeof(const char *));
_dialogueButtonPosX = 0;
_dialogueButtonPosY = 0;
_dialogueNumButtons = _dialogueButtonYoffs = _dialogueHighlightedButton = 0;
_dialogueNumButtons = _dialogueButtonXoffs = _dialogueButtonYoffs = _dialogueHighlightedButton = 0;
_currentControlMode = 0;
_specialSceneFlag = 0;
_updateCharNum = -1;
@ -277,7 +277,7 @@ uint16 KyraRpgEngine::processDialogue() {
int res = 0;
for (int i = 0; i < _dialogueNumButtons; i++) {
int x = _dialogueButtonPosX[i];
int x = _dialogueButtonPosX[i] + _dialogueButtonXoffs;
int y = ((_flags.gameID == GI_LOL && _flags.use16ColorMode) ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i]));
Common::Point p = getMousePos();
if (posWithinRect(p.x, p.y, x, y, x + _dialogueButtonWidth, y + guiSettings()->buttons.height)) {

View File

@ -89,6 +89,8 @@ struct EoBFlyingObject {
struct KyraRpgGUISettings {
struct DialogueButtons {
const uint16 *posX;
const uint8 *posY;
uint8 labelColor1;
uint8 labelColor2;
uint16 width;
@ -393,7 +395,7 @@ protected:
static const uint8 _dropItemDirIndex[];
// text
void drawDialogueButtons();
virtual void drawDialogueButtons();
uint16 processDialogue();
TextDisplayer_rpg *_txt;
@ -406,6 +408,7 @@ protected:
const char *_dialogueButtonString[9];
const uint16 *_dialogueButtonPosX;
const uint8 *_dialogueButtonPosY;
int16 _dialogueButtonXoffs;
int16 _dialogueButtonYoffs;
uint16 _dialogueButtonWidth;
int _dialogueNumButtons;
@ -417,6 +420,9 @@ protected:
const char *const *_moreStrings;
static const uint16 _dlgButtonPosX_Def[14];
static const uint8 _dlgButtonPosY_Def[14];
// misc
void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false) override = 0;
void delayUntil(uint32 time, bool unused = false, bool doUpdate = false, bool isMainLoop = false) override;

View File

@ -1257,13 +1257,11 @@ const uint8 *SegaCDFont::getGlyphData(uint16 c, uint8 &charWidth, uint8 &charHei
charHeight = pitch = 12;
res = &_data[0x19A0 + 18 * c];
} else if (_style == 2) {
assert(c < 188);
charWidth = _widthTable3[c];
charWidth = (!_fixedWidth && (c < 188)) ? _widthTable3[c] : 12;
charHeight = pitch = 12;
res = &_data[0x3410 + 18 * c];
} else {
assert(c < 188);
charWidth = _widthTable2[c];
charWidth = (!_fixedWidth && (c < 188)) ? _widthTable2[c] : 12;
charHeight = 12;
pitch = 8;
res = &_data[0x800 + 12 * c];

View File

@ -82,6 +82,16 @@ void EoBEngine::gui_drawPlayField(bool refresh) {
str = _sres->resStreamEndian(9);
r->loadStreamToVRAM(str, 0xA4A0, false);
delete str;
/*
// CAMP MENU
str = _sres->resStreamEndian(8);
_screen->sega_getRenderer()->loadStreamToVRAM(str, 0x20, true);
delete str;
_screen->sega_getRenderer()->fillRectWithTiles(0, 0, 0, 22, 15, 0);
_screen->sega_getRenderer()->fillRectWithTiles(1, 0, 0, 22, 21, 0x4001, true);
_screen->sega_getRenderer()->render(0);
_screen->sega_selectPalette(40, 2, true);
*/
gui_setupPlayFieldHelperPages();
@ -110,6 +120,11 @@ void EoBEngine::gui_drawPlayField(bool refresh) {
}
void EoBEngine::gui_setupPlayFieldHelperPages() {
if (_flags.platform != Common::kPlatformSegaCD) {
EoBCoreEngine::gui_setupPlayFieldHelperPages();
return;
}
_txt->clearDim(0);
SegaRenderer *r = _screen->sega_getRenderer();
r->fillRectWithTiles(0, 22, 0, 18, 21, 0);
@ -203,12 +218,12 @@ void EoBEngine::gui_displayMap() {
_screen->sega_fadeToBlack(2);
_sceneShakeCountdown = 0;
gui_resetAnimations();
for (int i = 0; i < 6; i++) {
if (!testCharacter(i, 1))
continue;
_characters[i].damageTaken = 0;
_characters[i].slotStatus[0] = _characters[i].slotStatus[1] = _characters[i].gfxUpdateCountdown = 0;
_characters[i].slotStatus[0] = _characters[i].slotStatus[1] = 0;
gui_drawCharPortraitWithStats(i);
}
@ -321,12 +336,12 @@ void EoBEngine::gui_updateAnimations() {
if (_compassAnimSwitch) {
_compassAnimPhase = (_compassAnimPhase + _compassAnimStep) & 0x0F;
_compassAnimDelayCounter = 6;
redrawCompass = true;
_compassAnimStep = -_compassAnimStep;
_compassAnimSwitch = false;
} else {
_compassAnimDone = _compassAnimSwitch = true;
}
redrawCompass = true;
}
}
if (redrawCompass) {
@ -373,28 +388,44 @@ void EoBEngine::gui_updateAnimations() {
// All shapes except monsters and items
drawSceneShapes(0, 0xFF & ~0x2A);
_shapeShakeOffsetX = _shapeShakeOffsetY = 0;
// Monsters and items
drawSceneShapes(0, 0x2A);
// Monsters and items
drawSceneShapes(0, 0x2A);
_screen->copyRegion(0, 0, 0, 0, 179, 123, _sceneDrawPage1, 0, Screen::CR_NO_P_CHECK);
updScreen = true;
_screen->copyRegion(0, 0, 0, 0, 179, 123, _sceneDrawPage1, 0, Screen::CR_NO_P_CHECK);
updScreen = true;
}
if (updScreen)
_screen->updateScreen();
}
void EoBEngine::makeNameShapes() {
void EoBEngine::gui_resetAnimations() {
if (_flags.platform != Common::kPlatformSegaCD)
return;
for (int i = 0; i < 6; ++i)
_characters[i].gfxUpdateCountdown = 1;
_sceneShakeCountdown = 1;
_compassAnimDelayCounter = _compassAnimSwitch = 0;
_compassAnimPhase = _compassAnimDest;
}
void EoBEngine::makeNameShapes(int charId) {
if (_flags.platform != Common::kPlatformSegaCD)
return;
int first = 0;
int last = 5;
if (charId != -1)
first = last = charId;
int cd = _txt->clearDim(4);
int cp = _screen->setCurPage(2);
_screen->sega_getRenderer()->fillRectWithTiles(1, 0, 0, 40, 28, 0x2000);
_screen->sega_getRenderer()->fillRectWithTiles(0, 0, 0, 30, 28, 0x600A, true);
_screen->sega_clearTextBuffer(0);
for (int i = 0; i < 6; ++i) {
for (int i = first; i <= last; ++i) {
if (!_characters[i].flags)
continue;
_txt->printShadowedText(_characters[i].name, 0, i << 4, 0xFF, 0xCC);
@ -402,7 +433,7 @@ void EoBEngine::makeNameShapes() {
_screen->sega_getRenderer()->render(_screen->_curPage);
for (int i = 0; i < 6; ++i) {
for (int i = first; i <= last; ++i) {
if (!_characters[i].flags)
continue;
delete[] _characters[i].nameShape;
@ -417,9 +448,19 @@ void EoBEngine::makeNameShapes() {
_txt->clearDim(cd);
}
void EoBEngine::makeFaceShapes() {
void EoBEngine::makeFaceShapes(int charId) {
if (_flags.platform != Common::kPlatformSegaCD) {
EoBCoreEngine::makeFaceShapes();
return;
}
int first = 0;
int last = 5;
if (charId != -1)
first = last = charId;
uint8 *in = _res->fileData("FACE", 0);
for (int i = 0; i < 6; i++) {
for (int i = first; i <= last; i++) {
EoBCharacter *c = &_characters[i];
if (!c->flags)
continue;
@ -444,7 +485,7 @@ void EoBEngine::drawMapButton(const char *str, int x, int y) {
void EoBEngine::drawMapPage(int level) {
int temp = 0;
_screen->sega_clearTextBuffer(0);
int cs = _screen->setFontStyles(_screen->_currentFont, _flags.lang == Common::JA_JPN ? Font::kStyleFixedWidth : Font::kStyleForceTwoByte | Font::kStyleFat | Font::kStyleNarrow1);
int cs = _screen->setFontStyles(_screen->_currentFont, (_flags.lang == Common::JA_JPN ? Font::kStyleFixedWidth : Font::kStyleForceTwoByte | Font::kStyleFat) | Font::kStyleNarrow1);
_txt->printShadowedText(_mapStrings3[level - 1], 0, 0, 0xCC, 0, 48, 16, 0, false);
_screen->setFontStyles(_screen->_currentFont, cs);
_screen->sega_loadTextBufferToVRAM(0, 0x7920, 384);
@ -481,6 +522,30 @@ void EoBEngine::drawMapSpots(int level, int animState) {
a->update();
}
void EoBEngine::drawDialogueButtons() {
if (_flags.platform != Common::kPlatformSegaCD) {
KyraRpgEngine::drawDialogueButtons();
return;
}
_screen->sega_clearTextBuffer(0);
for (int i = 0; i < _dialogueNumButtons; i++) {
int cs = _screen->setFontStyles(_screen->_currentFont, (_flags.lang == Common::JA_JPN ? Font::kStyleFixedWidth : Font::kStyleForceTwoByte | Font::kStyleFat) | Font::kStyleNarrow2);
if (_screen->getTextWidth(_dialogueButtonString[i]) > 90)
_screen->setFontStyles(_screen->_currentFont, (_flags.lang == Common::JA_JPN ? Font::kStyleFixedWidth : Font::kStyleForceTwoByte | Font::kStyleFat) | Font::kStyleNarrow1);
_screen->sega_drawClippedLine(38, 6, _dialogueButtonPosX[i], _dialogueButtonPosY[i], 90, 14, 0x99);
_screen->sega_drawClippedLine(38, 6, _dialogueButtonPosX[i], _dialogueButtonPosY[i] + 1, 89, 13, 0xBB);
_screen->sega_drawClippedLine(38, 6, _dialogueButtonPosX[i] + 1, _dialogueButtonPosY[i] + 1, 88, 12, 0xAA);
_txt->printShadowedText(_dialogueButtonString[i], _dialogueButtonPosX[i] + (_dialogueButtonWidth >> 1) - MIN<int>(_dialogueButtonWidth, _screen->getTextWidth(_dialogueButtonString[i])) / 2,
_dialogueButtonPosY[i] + 1, _dialogueHighlightedButton == i ? _dialogueButtonLabelColor1 : _dialogueButtonLabelColor2, 0xEE, 304, 48, 0, false);
_screen->setFontStyles(_screen->_currentFont, cs);
}
_screen->sega_loadTextBufferToVRAM(0, 0xA380, 7296);
_screen->sega_getRenderer()->render(0);
}
} // End of namespace Kyra
#endif // ENABLE_EOB

View File

@ -544,9 +544,14 @@ Common::Error EoBCoreEngine::saveGameStateIntern(int slot, const char *saveName,
return Common::kNoError;
}
void EoBCoreEngine::makeFaceShapes() {
void EoBCoreEngine::makeFaceShapes(int charId) {
int first = 0;
int last = 5;
if (charId != -1)
first = last = charId;
_screen->loadShapeSetBitmap("CHARGENA", 3, 3);
for (int i = 0; i < 6; i++) {
for (int i = first; i <= last; i++) {
EoBCharacter *c = &_characters[i];
if (!c->flags || c->portrait < 0)
continue;
@ -554,7 +559,7 @@ void EoBCoreEngine::makeFaceShapes() {
}
_screen->loadShapeSetBitmap(_flags.gameID == GI_EOB2 ? "OUTPORTS" : "OUTTAKE", 3, 3);
for (int i = 0; i < 6; i++) {
for (int i = first; i <= last; i++) {
EoBCharacter *c = &_characters[i];
if (!c->flags || c->portrait >= 0)
continue;

View File

@ -1453,7 +1453,7 @@ void EoBEngine::initSpells() {
}
const KyraRpgGUISettings EoBEngine::_guiSettingsVGA = {
{ 9, 15, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 135, 130, 132, 180, 133, 17, 23, 20, 184, 177, 180, 184, 177, 180, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@ -1464,7 +1464,7 @@ const KyraRpgGUISettings EoBEngine::_guiSettingsVGA = {
};
const KyraRpgGUISettings EoBEngine::_guiSettingsEGA = {
{ 9, 15, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 13, 9, 2, 14, 2, 6, 13, 8, 13, 15, 14, 13, 15, 14, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@ -1475,7 +1475,7 @@ const KyraRpgGUISettings EoBEngine::_guiSettingsEGA = {
};
const KyraRpgGUISettings EoBEngine::_guiSettingsPC98 = {
{ 9, 15, 95, 11, 1, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, 95, 11, 1, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 13, 9, 2, 14, 2, 6, 13, 8, 13, 15, 14, 13, 15, 14, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@ -1486,7 +1486,7 @@ const KyraRpgGUISettings EoBEngine::_guiSettingsPC98 = {
};
const KyraRpgGUISettings EoBEngine::_guiSettingsAmiga = {
{ 28, 31, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ _dlgButtonPosX_Def, _dlgButtonPosY_Def, 28, 31, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 18, 17, 10, 17, 11, 24, 22, 25, 18, 9, 10, 18, 9, 10, 31, 24, 25, 28, 29, 7, 26, 27, 19 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@ -1497,7 +1497,7 @@ const KyraRpgGUISettings EoBEngine::_guiSettingsAmiga = {
};
const KyraRpgGUISettings EoBEngine::_guiSettingsAmigaMainMenu = {
{ 28, 31, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ _dlgButtonPosX_Def, _dlgButtonPosY_Def, 28, 31, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 22, 28, 30, 17, 11, 24, 22, 25, 18, 9, 10, 18, 9, 10, 31, 24, 25, 28, 29, 7, 26, 27, 19 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@ -1508,7 +1508,7 @@ const KyraRpgGUISettings EoBEngine::_guiSettingsAmigaMainMenu = {
};
const KyraRpgGUISettings EoBEngine::_guiSettingsSegaCD = {
{ 9, 15, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ _dlgButtonPosX_Sega, _dlgButtonPosY_Sega, 0x66, 0xFF, 90, 14, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 135, 130, 132, 180, 0x00, 17, 23, 20, 184, 177, 180, 184, 177, 180, 15, 6, 0x31, 9, 2, 0x35, 4, 0x33, 12 },
{ { 184, 256, -1}, { 1, 57, 113 }, 64, 55,
{ 8, 80, -1 }, { 16, 72, 128 }, { 184, -1, -1 }, { 8, -1, -1 },
@ -1540,6 +1540,10 @@ const uint8 EoBEngine::_monsterAcHitChanceTbl2[] = {
2, 1, 1, 1
};
const uint16 EoBEngine::_dlgButtonPosX_Sega[18] = { 59, 166, 4, 104, 204, 4, 104, 204, 4, 104, 204, 4, 104, 204, 4, 104, 204, 4 };
const uint8 EoBEngine::_dlgButtonPosY_Sega[18] = { 16, 16, 16, 16, 16, 0, 0, 0, 16, 16, 16, 32, 32, 32, 16, 16, 16, 32 };
const EoBEngine::RenderModePalFile EoBEngine::_renderModePalFiles[3] = {
{ Common::kRenderDefault, "EOBPAL.COL" },
{ Common::kRenderVGA, "EOBPAL.COL" },
@ -1722,7 +1726,7 @@ void DarkMoonEngine::initSpells() {
}
const KyraRpgGUISettings DarkMoonEngine::_guiSettingsFMTowns = {
{ 9, 15, 95, 11, 1, 7, { 221, 76 }, { 187, 162 }, { 95, 95 } },
{ _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, 95, 11, 1, 7, { 221, 76 }, { 187, 162 }, { 95, 95 } },
{ 186, 181, 183, 183, 184, 17, 23, 20, 186, 181, 183, 182, 177, 180, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@ -1733,7 +1737,7 @@ const KyraRpgGUISettings DarkMoonEngine::_guiSettingsFMTowns = {
};
const KyraRpgGUISettings DarkMoonEngine::_guiSettingsDOS = {
{ 9, 15, 95, 9, 2, 7, { 221, 76 }, { 189, 162 }, { 95, 95 } },
{ _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, 95, 9, 2, 7, { 221, 76 }, { 189, 162 }, { 95, 95 } },
{ 186, 181, 183, 183, 184, 17, 23, 20, 186, 181, 183, 182, 177, 180, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@ -1744,7 +1748,7 @@ const KyraRpgGUISettings DarkMoonEngine::_guiSettingsDOS = {
};
const KyraRpgGUISettings DarkMoonEngine::_guiSettingsAmiga = {
{ 28, 31, 95, 9, 2, 7, { 221, 76 }, { 189, 162 }, { 95, 95 } },
{ _dlgButtonPosX_Def, _dlgButtonPosY_Def, 28, 31, 95, 9, 2, 7, { 221, 76 }, { 189, 162 }, { 95, 95 } },
{ 18, 17, 10, 17, 11, 10, 12, 25, 18, 9, 10, 18, 9, 10, 31, 24, 25, 28, 29, 7, 26, 27, 19 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },

View File

@ -781,7 +781,7 @@ const int8 LoLEngine::_mapCoords[12][4] = {
// And it is hardly worth the time to add any usage for this, since the only significant version difference would
// be the PC-98 16 color version. That said, I have filled all the unused parts of the struct with zeroes.
const KyraRpgGUISettings LoLEngine::_guiSettings = {
{ 144, 254, 74, 9, 2, 80, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ _dlgButtonPosX_Def, _dlgButtonPosY_Def, 144, 254, 74, 9, 2, 80, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ 136, 251, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ { 0, 0, 0 }, { 0, 0, 0 }, 0, 0,
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },

View File

@ -78,6 +78,10 @@ const uint16 KyraRpgEngine::_vmpOffsetsDefault[9] = { 102, 97, 129, 117, 81, 159
const uint16 KyraRpgEngine::_vmpOffsetsSegaCD[9] = { 0, 15, 20, 50, 62, 78, 158, 194, 386 };
const uint16 KyraRpgEngine::_dlgButtonPosX_Def[14] = { 59, 166, 4, 112, 220, 4, 112, 220, 4, 112, 220, 4, 112, 220 };
const uint8 KyraRpgEngine::_dlgButtonPosY_Def[14] = { 0, 0, 0, 0, 0, 12, 12, 12, 24, 24, 24, 36, 36, 36 };
void KyraRpgEngine::initStaticResource() {
int temp;
_dscShapeX = (const int16 *)_staticres->loadRawDataBe16(kRpgCommonDscX, temp);

View File

@ -1582,7 +1582,7 @@ int EoBInfProcessor::oeob_dialogue(int8 *data) {
break;
case -40:
_dlgResult = _vm->runDialogue(READ_LE_UINT16(pos), READ_LE_UINT16(pos + 6) == 0xFFFF ? 2 : 3, getString(READ_LE_UINT16(pos + 2)), getString(READ_LE_UINT16(pos + 4)), getString(READ_LE_UINT16(pos + 6)));
_dlgResult = _vm->runDialogue(READ_LE_UINT16(pos), READ_LE_UINT16(pos + 6) == 0xFFFF ? 2 : 3, -1, getString(READ_LE_UINT16(pos + 2)), getString(READ_LE_UINT16(pos + 4)), getString(READ_LE_UINT16(pos + 6)));
pos += 8;
break;

View File

@ -127,7 +127,10 @@ SegaSequencePlayer::~SegaSequencePlayer() {
}
bool SegaSequencePlayer::play(int id) {
_renderer->render(0);
_screen->sega_fadeToBlack(2);
_screen->clearPage(0);
_animator->clearSprites();
_scrollManager->setVScrollTimers(0, 1, 0, 0, 1, 0);
_scrollManager->setHScrollTimers(0, 1, 0, 0, 1, 0);
@ -215,7 +218,7 @@ bool SegaSequencePlayer::play(int id) {
if (_vm->shouldQuit() || _vm->skipFlag()) {
if (!(_playingID == 55 || _playingID == 56))
_vm->snd_stopSound();
_screen->sega_fadeToBlack(5);
_screen->clearPage(0);
}
_scrollManager->setVScrollTimers(0, 1, 0, 0, 1, 0);
@ -255,6 +258,7 @@ void SegaSequencePlayer::run(const uint8 *data) {
for (uint16 timeStamp2 = timeStamp; timeStamp2 == timeStamp; ) {
uint16 op = READ_BE_UINT16(data + 4);
_opcodes[op]->run(data + 6);
_screen->clearPage(0);
frameSize = READ_BE_UINT16(data);
data += (frameSize & ~1);

View File

@ -2283,6 +2283,7 @@ void EoBEngine::seq_playFinale() {
EoBPC98FinalePlayer(this, _screen).start(_xdth);
return;
} else if (_flags.platform == Common::kPlatformSegaCD) {
_screen->hideMouse();
seq_segaPlaySequence(_xdth ? 55 : 56, true);
seq_segaFinalCredits();
seq_segaShowStats();
@ -2332,44 +2333,76 @@ void EoBEngine::seq_playFinale() {
}
void EoBEngine::seq_xdeath() {
uint8 *shapes1[5];
uint8 *shapes1[4];
uint8 *shapes2;
memset(shapes1, 0, sizeof(shapes1));
_xdth = true;
_totalEnemiesKilled++;
_screen->loadShapeSetBitmap("XDEATH2", 5, 3);
for (int i = 0; i < 4; i++)
shapes1[i] = _screen->encodeShape(i / 2 * 14, i / 2 * 88, 14, 88, true, _cgaMappingDefault);
_screen->loadShapeSetBitmap("XDEATH3", 5, 3);
shapes2 = _screen->encodeShape(22, 0, 16, 95, true, _cgaMappingDefault);
_screen->loadEoBBitmap("XDEATH1", _cgaMappingDefault, 5, 3, -1);
_screen->convertPage(3, 2, _cgaMappingDefault);
_screen->setCurPage(0);
if (_flags.platform == Common::kPlatformSegaCD) {
_screen->sega_selectPalette(57, 2, true);
snd_stopSound();
uint8 *in = _res->fileData("XD", 0);
_sceneShakeCountdown = 1;
for (int i = 0; i < 10; i++) {
if (i == 2)
snd_playSoundEffect(72);
else if (i == 4 || i == 6)
snd_playSoundEffect(54);
else
snd_playSoundEffect(34);
if (i < 6) {
_screen->copyRegion((i % 3) * 104, i / 3 * 88, 32, 10, 104, 88, 2, 0, Screen::CR_NO_P_CHECK);
} else {
snd_playSoundEffect(42);
_screen->drawShape(0, shapes1[i - 6], 32, 10, 0);
snd_playSoundEffect(0x502d);
for (int i = 0; i < 10 && !shouldQuit(); i++) {
uint32 del = _system->getMillis() + 4 * _tickLength;
shapes2 = _screen->sega_convertShape(in + 6144 + i * 4928, 112, 88, 2);
_screen->copyBlockToPage(2, 0, 0, 176, 120, _sceneWindowBuffer);
drawDecorations(13);
_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
_screen->drawShape(0, shapes2, 32, 10, 0);
_screen->updateScreen();
updateAnimTimers();
delete[] shapes2;
for (uint32 cur = _system->getMillis(); cur < del; cur = _system->getMillis()) {
updateAnimTimers();
delay(MIN<uint32>(8, del - cur));
}
}
_screen->updateScreen();
delay(4 * _tickLength);
snd_playSoundEffect(0x500e);
shapes2 = _screen->sega_convertShape(in, 128, 96, 2);
delete[] in;
} else {
_screen->loadShapeSetBitmap("XDEATH2", 5, 3);
for (int i = 0; i < 4; i++)
shapes1[i] = _screen->encodeShape(i / 2 * 14, i / 2 * 88, 14, 88, true, _cgaMappingDefault);
_screen->loadShapeSetBitmap("XDEATH3", 5, 3);
shapes2 = _screen->encodeShape(22, 0, 16, 95, true, _cgaMappingDefault);
_screen->loadEoBBitmap("XDEATH1", _cgaMappingDefault, 5, 3, -1);
_screen->convertPage(3, 2, _cgaMappingDefault);
_screen->setCurPage(0);
for (int i = 0; i < 10 && !shouldQuit(); i++) {
if (i == 2)
snd_playSoundEffect(72);
else if (i == 4 || i == 6)
snd_playSoundEffect(54);
else
snd_playSoundEffect(34);
if (i < 6) {
_screen->copyRegion((i % 3) * 104, i / 3 * 88, 32, 10, 104, 88, 2, 0, Screen::CR_NO_P_CHECK);
} else {
snd_playSoundEffect(42);
_screen->drawShape(0, shapes1[i - 6], 32, 10, 0);
}
_screen->updateScreen();
delay(4 * _tickLength);
}
}
const ScreenDim *dm = _screen->getScreenDim(5);
_screen->modifyScreenDim(5, dm->sx, 8, dm->w, dm->h);
_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 5, Screen::CR_NO_P_CHECK);
for (int i = 0; i < 19; i++) {
snd_playSoundEffect(119);
for (int i = 0; i < 19 && !shouldQuit(); i++) {
if (_flags.platform != Common::kPlatformSegaCD)
snd_playSoundEffect(119);
_screen->copyRegion(0, 0, 0, 0, 176, 120, 5, 2, Screen::CR_NO_P_CHECK);
_screen->drawShape(2, shapes2, 24, i * 5 - 90, 5);
_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
@ -2379,14 +2412,17 @@ void EoBEngine::seq_xdeath() {
_screen->modifyScreenDim(5, dm->sx, 0, dm->w, dm->h);
snd_playSoundEffect(5);
snd_playSoundEffect(_flags.platform == Common::kPlatformSegaCD ? 0x5002 : 5);
delay(60 * _tickLength);
for (int i = 0; i < 4; i++)
delete[] shapes1[i];
delete[] shapes2;
gui_drawPlayField(false);
if (_flags.platform == Common::kPlatformSegaCD)
_screen->sega_fadeToBlack(7);
else
gui_drawPlayField(false);
gui_drawAllCharPortraitsWithStats();
}
@ -2698,13 +2734,18 @@ void EoBEngine::seq_segaSetupSequence(int sequenceId) {
if (_flags.platform != Common::kPlatformSegaCD || sequenceId == -1)
return;
_screen->sega_fadeToBlack(1);
for (int i = 0; i < 6; i++) {
_characters[i].damageTaken = 0;
_characters[i].slotStatus[0] = _characters[i].slotStatus[1] = 0;
gui_drawCharPortraitWithStats(i);
if (sequenceId != 53 && sequenceId != 54) {
gui_resetAnimations();
for (int i = 0; i < 6; i++) {
_characters[i].damageTaken = 0;
_characters[i].slotStatus[0] = _characters[i].slotStatus[1] = 0;
gui_drawCharPortraitWithStats(i);
}
}
_screen->sega_fadeToBlack(1);
_screen->clearPage(0);
// transposeScreenOutputY(0);
_screen->sega_getRenderer()->setupWindowPlane(0, (sequenceId == 53 || sequenceId == 54) ? 23 : 18, SegaRenderer::kWinToRight, SegaRenderer::kWinToBottom);
_screen->sega_getRenderer()->memsetVRAM(0xD840, 0xEE, 512);
@ -2713,6 +2754,9 @@ void EoBEngine::seq_segaSetupSequence(int sequenceId) {
}
void EoBEngine::seq_segaRestoreAfterSequence() {
if (_flags.platform != Common::kPlatformSegaCD)
return;
SegaRenderer *r = _screen->sega_getRenderer();
_screen->sega_fadeToBlack(1);
_screen->sega_getAnimator()->clearSprites();
@ -2723,14 +2767,14 @@ void EoBEngine::seq_segaRestoreAfterSequence() {
_screen->clearPage(0);
}
bool EoBEngine::seq_segaPlaySequence(int sequenceId, bool init) {
bool EoBEngine::seq_segaPlaySequence(int sequenceId, bool setupScreen) {
if (_flags.platform != Common::kPlatformSegaCD)
return true;
_allowSkip = true;
resetSkipFlag();
if (init)
if (setupScreen)
seq_segaSetupSequence(sequenceId);
_allowSkip = false;
@ -2739,7 +2783,9 @@ bool EoBEngine::seq_segaPlaySequence(int sequenceId, bool init) {
if (!_seqPlayer->play(sequenceId))
return false;
seq_segaRestoreAfterSequence();
if (setupScreen)
seq_segaRestoreAfterSequence();
return true;
}

View File

@ -29,7 +29,7 @@
namespace Kyra {
TextDisplayer_SegaCD::TextDisplayer_SegaCD(EoBEngine *engine, Screen_EoB *scr) : TextDisplayer_rpg(engine, scr), _screen(scr), _renderer(scr->sega_getRenderer()),
TextDisplayer_SegaCD::TextDisplayer_SegaCD(EoBEngine *engine, Screen_EoB *scr) : TextDisplayer_rpg(engine, scr), _engine(engine), _screen(scr), _renderer(scr->sega_getRenderer()),
_curDim(0), _textColor(0xFF), _curPosY(0), _curPosX(0) {
assert(_renderer);
}
@ -37,6 +37,35 @@ TextDisplayer_SegaCD::TextDisplayer_SegaCD(EoBEngine *engine, Screen_EoB *scr) :
TextDisplayer_SegaCD::~TextDisplayer_SegaCD() {
}
void TextDisplayer_SegaCD::printDialogueText(int id, const char *string1, const char *string2) {
if (string1 && string2) {
_engine->runDialogue(id, 2, 2, string1, string2);
} else {
_screen->hideMouse();
_engine->seq_segaPlaySequence(id);
_screen->showMouse();
}
}
void TextDisplayer_SegaCD::printDialogueText(const char *str, bool wait) {
int cs = _screen->setFontStyles(Screen::FID_8_FNT, _vm->gameFlags().lang == Common::JA_JPN ? Font::kStyleFixedWidth : Font::kStyleFat | Font::kStyleForceTwoByte);
clearDim(_curDim);
if (wait) {
printShadowedText(str, 32, 12);
_engine->resetSkipFlag();
_renderer->render(0);
_screen->updateScreen();
_engine->delay(500);
} else {
printShadowedText(str, 0, 0);
_renderer->render(0);
_screen->updateScreen();
}
_screen->setFontStyles(Screen::FID_8_FNT, cs);
}
void TextDisplayer_SegaCD::printShadowedText(const char *str, int x, int y, int textColor, int shadowColor, int pitchW, int pitchH, int marginRight, bool screenUpdate) {
const ScreenDim *s = &_dimTable[_curDim];
if (x == -1)

View File

@ -37,6 +37,8 @@ public:
TextDisplayer_SegaCD(EoBEngine *engine, Screen_EoB *scr);
virtual ~TextDisplayer_SegaCD();
void printDialogueText(int id, const char *string1, const char *string2) override;
void printDialogueText(const char *str, bool wait = false) override;
void printShadowedText(const char *str, int x = -1, int y = -1, int textColor = -1, int shadowColor = -1, int pitchW = -1, int pitchH = -1, int marginRight = 0, bool screenUpdate = true) override;
int clearDim(int dim) override;
@ -47,6 +49,8 @@ private:
Screen_EoB *_screen;
SegaRenderer *_renderer;
EoBEngine *_engine;
int _curDim;
int _curPosY;
int _curPosX;

View File

@ -537,7 +537,7 @@ void TextDisplayer_rpg::printLine(char *str) {
printLine(str);
}
void TextDisplayer_rpg::printDialogueText(int stringId, const char *pageBreakString) {
void TextDisplayer_rpg::printDialogueText(int stringId, const char *pageBreakString, const char*) {
const char *str = (const char *)(_screen->getCPagePtr(5) + READ_LE_UINT16(&_screen->getCPagePtr(5)[(stringId - 1) << 1]));
assert(strlen(str) < kEoBTextBufferSize);
Common::strlcpy(_dialogueBuffer, str, kEoBTextBufferSize);

View File

@ -39,8 +39,8 @@ public:
void setupField(int dim, bool mode);
void printDialogueText(int stringId, const char *pageBreakString);
void printDialogueText(const char *str, bool wait = false);
virtual void printDialogueText(int stringId, const char *pageBreakString, const char *pageBreakString2 = 0);
virtual void printDialogueText(const char *str, bool wait = false);
void printMessage(const char *str, int textColor = -1, ...);
virtual void printShadowedText(const char *str, int x = -1, int y = -1, int textColor = -1, int shadowColor = -1, int pitchW = -1, int pitchH = -1, int marginRight = 0, bool screenUpdate = true) {}