From 8b618e46df21d90a1a5ad62633a2b9d3c1da0317 Mon Sep 17 00:00:00 2001 From: athrxx Date: Sun, 11 Dec 2011 12:29:09 +0100 Subject: KYRA: (EOB/LOL) - cleanup common code (rename some stuff and move EOB/LOL common code to separate files) --- engines/kyra/chargen.cpp | 4 +- engines/kyra/detection.cpp | 2 +- engines/kyra/eob1.cpp | 16 +- engines/kyra/eob1.h | 6 +- engines/kyra/eob2.cpp | 2 +- engines/kyra/eobcommon.cpp | 36 +-- engines/kyra/eobcommon.h | 22 +- engines/kyra/gui_eob.cpp | 262 +++++---------- engines/kyra/gui_eob.h | 6 +- engines/kyra/gui_rpg.cpp | 134 ++++++++ engines/kyra/items_eob.cpp | 36 +-- engines/kyra/kyra_rpg.cpp | 361 +++++++++++++++++++++ engines/kyra/kyra_rpg.h | 355 +++++++++++++++++++++ engines/kyra/lol.cpp | 18 +- engines/kyra/lol.h | 6 +- engines/kyra/loleobbase.cpp | 361 --------------------- engines/kyra/loleobbase.h | 355 --------------------- engines/kyra/magic_eob.cpp | 30 +- engines/kyra/module.mk | 24 +- engines/kyra/saveload_eob.cpp | 110 +------ engines/kyra/saveload_lol.cpp | 2 +- engines/kyra/saveload_rpg.cpp | 127 ++++++++ engines/kyra/scene_eob.cpp | 598 +--------------------------------- engines/kyra/scene_rpg.cpp | 614 +++++++++++++++++++++++++++++++++++ engines/kyra/screen_eob.cpp | 20 +- engines/kyra/screen_eob.h | 2 +- engines/kyra/script_eob.cpp | 4 +- engines/kyra/script_eob.h | 2 +- engines/kyra/sequences_eob1.cpp | 48 +-- engines/kyra/sequences_eob2.cpp | 12 +- engines/kyra/sound_lol.cpp | 2 +- engines/kyra/sprites_eob.cpp | 25 +- engines/kyra/sprites_rpg.cpp | 46 +++ engines/kyra/staticres_eob.cpp | 95 +----- engines/kyra/staticres_rpg.cpp | 97 ++++++ engines/kyra/text_eob.cpp | 688 ---------------------------------------- engines/kyra/text_eob.h | 115 ------- engines/kyra/text_lol.cpp | 6 +- engines/kyra/text_lol.h | 6 +- engines/kyra/text_rpg.cpp | 688 ++++++++++++++++++++++++++++++++++++++++ engines/kyra/text_rpg.h | 115 +++++++ engines/kyra/timer_eob.cpp | 65 +--- engines/kyra/timer_rpg.cpp | 90 ++++++ 43 files changed, 2888 insertions(+), 2725 deletions(-) create mode 100644 engines/kyra/gui_rpg.cpp create mode 100644 engines/kyra/kyra_rpg.cpp create mode 100644 engines/kyra/kyra_rpg.h delete mode 100644 engines/kyra/loleobbase.cpp delete mode 100644 engines/kyra/loleobbase.h create mode 100644 engines/kyra/saveload_rpg.cpp create mode 100644 engines/kyra/scene_rpg.cpp create mode 100644 engines/kyra/sprites_rpg.cpp create mode 100644 engines/kyra/staticres_rpg.cpp delete mode 100644 engines/kyra/text_eob.cpp delete mode 100644 engines/kyra/text_eob.h create mode 100644 engines/kyra/text_rpg.cpp create mode 100644 engines/kyra/text_rpg.h create mode 100644 engines/kyra/timer_rpg.cpp (limited to 'engines/kyra') diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp index f7a546091d..b190e111c7 100644 --- a/engines/kyra/chargen.cpp +++ b/engines/kyra/chargen.cpp @@ -169,7 +169,7 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) { for (bool loop = true; loop && (!_vm->shouldQuit()); ) { _vm->_gui->updateBoxFrameHighLight(_activeBox + 6); - int inputFlag = getInput(_vm->_activeButtons); + int inputFlag = getInput(_vm->_activeButtons); _vm->removeInputTop(); if (inputFlag) { @@ -434,7 +434,7 @@ int CharacterGenerator::viewDeleteCharacter() { } void CharacterGenerator::createPartyMember() { - _screen->setScreenDim(2); + _screen->setScreenDim(2); assert(_vm->_gui); for (int i = 0; i != 3 && !_vm->shouldQuit(); i++) { diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index dd67c3e715..abb6a70f42 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -163,7 +163,7 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const { // Skip automatic final saves made by EOB for the purpose of party transfer if (!scumm_stricmp(file->c_str() + file->size() - 3, "fin")) continue; - + // Obtain the last 3 digits of the filename, since they correspond to the save slot int slotNum = atoi(file->c_str() + file->size() - 3); diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp index ae24b14efb..c87118918a 100644 --- a/engines/kyra/eob1.cpp +++ b/engines/kyra/eob1.cpp @@ -173,7 +173,7 @@ void EobEngine::runNpcDialogue(int npcIndex) { int r = 0; int a = 0; Item itm = 0; - + switch (npcIndex) { case 0: for (r = 1; r == 1; ) { @@ -199,7 +199,7 @@ void EobEngine::runNpcDialogue(int npcIndex) { } if (!r) r = DLG2(a ? 13 : 4, 4); - + if (!r) { for (a = 0; a < 6; a++) createItemOnCurrentBlock(55); @@ -230,7 +230,7 @@ void EobEngine::runNpcDialogue(int npcIndex) { if (deletePartyItems(6, -1)) { //_npcSequenceSub = 0; //drawNpcScene(npcIndex); - TXT(28); + TXT(28); createItemOnCurrentBlock(32); setScriptFlags(0x100000); r = 1; @@ -254,7 +254,7 @@ void EobEngine::runNpcDialogue(int npcIndex) { else resurrectionSelectDialogue(); setScriptFlags(0x20000); - } + } } } else { TXT(24); @@ -476,7 +476,7 @@ void EobEngine::turnUndeadAuto() { for (int i = 0; i < 6; i++) { if (!testCharacter(i, 0x0d)) continue; - + EobCharacter *c = &_characters[i]; if (_itemTypes[_items[c->inventory[0]].type].extraProperties != 6 && _itemTypes[_items[c->inventory[1]].type].extraProperties != 6) @@ -553,13 +553,13 @@ void EobEngine::healParty() { for (int i = 0; i < 6 && cnt; i++) { if (testCharacter(i, 3)) continue; - + _characters[i].flags &= ~4; neutralizePoison(i); - + if (_characters[i].hitPointsCur >= _characters[i].hitPointsMax) continue; - + cnt--; _characters[i].hitPointsCur += rollDice(1, 8, 9); if (_characters[i].hitPointsCur > _characters[i].hitPointsMax) diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h index 00583e9330..2dfccca94e 100644 --- a/engines/kyra/eob1.h +++ b/engines/kyra/eob1.h @@ -61,7 +61,7 @@ private: void seq_king(); void seq_hands(); void seq_waterdeepExit(); - void seq_tunnel(); + void seq_tunnel(); void seq_xdeath(); @@ -69,7 +69,7 @@ private: void copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step); 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); void whirlTransition(); - + const char *const *_introFilesOpening; const char *const *_introFilesTower; const char *const *_introFilesOrb; @@ -90,7 +90,7 @@ private: const uint8 *_introTvlY2; const uint8 *_introTvlW; const uint8 *_introTvlH; - + const char *const *_finBonusStrings; // characters diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp index 60df8f8520..64e394a717 100644 --- a/engines/kyra/eob2.cpp +++ b/engines/kyra/eob2.cpp @@ -387,7 +387,7 @@ void DarkMoonEngine::restParty_npc() { bool DarkMoonEngine::restParty_extraAbortCondition() { if (_currentLevel != 3) return false; - + seq_nightmare(); return true; diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp index 389a0e9947..dfa465c789 100644 --- a/engines/kyra/eobcommon.cpp +++ b/engines/kyra/eobcommon.cpp @@ -22,7 +22,7 @@ #ifdef ENABLE_EOB -#include "kyra/loleobbase.h" +#include "kyra/kyra_rpg.h" #include "kyra/resource.h" #include "kyra/sound_intern.h" #include "kyra/script_eob.h" @@ -36,7 +36,7 @@ namespace Kyra { -EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBaseEngine(system, flags), _numLargeItemShapes(flags.gameID == GI_EOB1 ? 14 : 11), +EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : KyraRpgEngine(system, flags), _numLargeItemShapes(flags.gameID == GI_EOB1 ? 14 : 11), _numSmallItemShapes(flags.gameID == GI_EOB1 ? 23 : 26), _numThrownItemShapes(flags.gameID == GI_EOB1 ? 12 : 9), _numItemIconShapes(flags.gameID == GI_EOB1 ? 89 : 112), _teleporterWallId(flags.gameID == GI_EOB1 ? 52 : 44) { _screen = 0; @@ -164,7 +164,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa _monsterProximityTable = _findBlockMonstersTable = _wallOfForceDsY = _wallOfForceDsNumW = _wallOfForceDsNumH = _wallOfForceShpId = _wllFlagPreset = _teleporterShapeCoords = 0; _monsterCloseAttUnkTable = _monsterFrmOffsTable1 = _monsterFrmOffsTable2 = _monsterDirChangeTable = _portalSeq = 0; _wallOfForceDsX = 0; - _expObjectAnimTbl1Size = _expObjectAnimTbl2Size = _expObjectAnimTbl3Size = _wllFlagPresetSize = _scriptTimersCount = _buttonList1Size = _buttonList2Size = + _expObjectAnimTbl1Size = _expObjectAnimTbl2Size = _expObjectAnimTbl3Size = _wllFlagPresetSize = _scriptTimersCount = _buttonList1Size = _buttonList2Size = _buttonList3Size = _buttonList4Size = _buttonList5Size = _buttonList6Size = _buttonList7Size = _buttonList8Size = 0; _inventorySlotsY = _mnDef = 0; _buttonDefs = 0; @@ -310,7 +310,7 @@ Common::Error EobCoreEngine::init() { //MidiDriverType midiDriver = MidiDriver::detectDevice(MDT_PCSPK | MDT_ADLIB); _sound = new SoundAdLibPC(this, _mixer); assert(_sound); - _sound->init(); + _sound->init(); syncSoundSettings(); @@ -335,7 +335,7 @@ Common::Error EobCoreEngine::init() { setupKeyMap(); _gui = new GUI_Eob(this); assert(_gui); - _txt = new TextDisplayer_Eob(this, _screen); + _txt = new TextDisplayer_rpg(this, _screen); assert(_txt); _inf = new EobInfProcessor(this, _screen); assert(_inf); @@ -345,7 +345,7 @@ Common::Error EobCoreEngine::init() { _screen->loadFont(Screen::FID_6_FNT, "FONT6.FNT"); _screen->loadFont(Screen::FID_8_FNT, "FONT8.FNT"); - Common::Error err = LolEobBaseEngine::init(); + Common::Error err = KyraRpgEngine::init(); if (err.getCode() != Common::kNoError) return err; @@ -522,7 +522,7 @@ void EobCoreEngine::startupNew() { } void EobCoreEngine::runLoop() { - _envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength); + _envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength); _flashShapeTimer = 0; _drawSceneTimer = _system->getMillis(); @@ -566,7 +566,7 @@ bool EobCoreEngine::checkPartyStatus(bool handleDeath) { if (!handleDeath) return true; - + gui_drawAllCharPortraitsWithStats(); if (checkPartyStatusExtra()) { @@ -1172,7 +1172,7 @@ void EobCoreEngine::dropCharacter(int charIndex) { return; removeCharacterFromParty(charIndex); - + if (charIndex < 5) exchangeCharacters(charIndex, testCharacter(5, 1) ? 5 : 4); @@ -1439,7 +1439,7 @@ bool EobCoreEngine::restParty_updateMonsters() { return true; } } - + _sound->enableSFX(sfxEnabled); _sound->enableMusic(musicEnabled); return false; @@ -1468,7 +1468,7 @@ bool EobCoreEngine::restParty_checkHealSpells(int charIndex) { static const uint8 eob2healSpells[] = { 3, 16, 20 }; const uint8 *spells = _flags.gameID == GI_EOB1 ? eob1healSpells : eob2healSpells; const int8 *list = _characters[charIndex].clericSpells; - + for (int i = 0; i < 80; i++) { int s = list[i] < 0 ? -list[i] : list[i]; if (s == spells[0] || s == spells[1] || s == spells[2]) @@ -1551,7 +1551,7 @@ void EobCoreEngine::displayParchment(int id) { int EobCoreEngine::countResurrectionCandidates() { _rrCount = 0; - memset(_rrNames, 0, 10 * sizeof(const char*)); + memset(_rrNames, 0, 10 * sizeof(const char*)); for (int i = 0; i < 6; i++) { if (!testCharacter(i, 1)) @@ -1646,11 +1646,11 @@ void EobCoreEngine::seq_portal() { if (*(pos - 2) == 3) snd_playSoundEffect(90); } - + _screen->updateScreen(); delay(2 * _tickLength); } - + delete[] shape0; for (int i = 0; i < 5; i++) { delete[] shapes1[i]; @@ -1663,12 +1663,12 @@ bool EobCoreEngine::checkPassword() { char answ[20]; Screen::FontId of = _screen->setFont(Screen::FID_8_FNT); _screen->copyPage(0, 10); - + _screen->setScreenDim(13); gui_drawBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, _color1_1, _color2_1, -1); gui_drawBox((_screen->_curDim->sx << 3) + 1, _screen->_curDim->sy + 1, (_screen->_curDim->w << 3) - 2, _screen->_curDim->h - 2, _color1_1, _color2_1, _bkgColor_1); _screen->modifyScreenDim(13, _screen->_curDim->sx + 1, _screen->_curDim->sy + 2, _screen->_curDim->w - 2, _screen->_curDim->h - 16); - + for (int i = 0; i < 3; i++) { _screen->fillRect(_screen->_curDim->sx << 3, _screen->_curDim->sy, ((_screen->_curDim->sx + _screen->_curDim->w) << 3) - 1, (_screen->_curDim->sy + _screen->_curDim->h) - 1, _bkgColor_1); int c = rollDice(1, _mnNumWord - 1, -1); @@ -1678,7 +1678,7 @@ bool EobCoreEngine::checkPassword() { _screen->printShadedText(Common::String::format(_mnPrompt[0], _mnDef[(c << 2) + 1], _mnDef[(c << 2) + 2]).c_str(), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy, _screen->_curDim->unk8, _bkgColor_1); memset(answ, 0, 20); gui_drawBox(76, 100, 133, 14, _color2_1, _color1_1, -1); - gui_drawBox(77, 101, 131, 12, _color2_1, _color1_1, -1); + gui_drawBox(77, 101, 131, 12, _color2_1, _color1_1, -1); if (_gui->getTextInput(answ, 10, 103, 15, _screen->_curDim->unk8, _bkgColor_1, 8) < 0) i = 3; if (!scumm_stricmp(_mnWord[c], answ)) @@ -1812,7 +1812,7 @@ int EobCoreEngine::projectileWeaponAttack(int charIndex, Item item) { SWAP(ammoItem, _characters[charIndex].inventory[1]); else if (_characters[charIndex].inventory[16]) ammoItem = getQueuedItem(&_characters[charIndex].inventory[16], 0, -1); - + } else { for (int i = 0; i < 27; i++) { if (_items[_characters[charIndex].inventory[i]].type == t) { diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h index 93db0b3623..3b1230830e 100644 --- a/engines/kyra/eobcommon.h +++ b/engines/kyra/eobcommon.h @@ -24,7 +24,7 @@ #define KYRA_EOBCOMMON_H #if defined(ENABLE_EOB) || defined(ENABLE_LOL) -#include "kyra/loleobbase.h" +#include "kyra/kyra_rpg.h" #endif // (ENABLE_EOB || ENABLE_LOL) #ifdef ENABLE_EOB @@ -239,8 +239,8 @@ struct EobMenuButtonDef { class EobInfProcessor; -class EobCoreEngine : public LolEobBaseEngine { -friend class TextDisplayer_Eob; +class EobCoreEngine : public KyraRpgEngine { +friend class TextDisplayer_rpg; friend class GUI_Eob; friend class EobInfProcessor; friend class DarkmoonSequenceHelper; @@ -328,7 +328,7 @@ protected: static const uint8 _charClassModifier[]; const uint8 *_classModifierFlags; - + const uint8 *_transferConvertTable; const uint32 *_transferExpTable; @@ -550,7 +550,7 @@ protected: const uint8 *_monsterProximityTable; const uint8 *_findBlockMonstersTable; const char *const *_monsterDustStrings; - + const uint8 *_enemyMageSpellList; const uint8 *_enemyMageSfx; const uint8 *_beholderSpellList; @@ -798,9 +798,9 @@ protected: const char *const *_validateCursedString; const char *const *_validateNoDropString; const char *const *_potionStrings; - const char *const *_wandStrings; - const char *const *_itemMisuseStrings; - + const char *const *_wandStrings; + const char *const *_itemMisuseStrings; + const char *const *_suffixStringsRings; const char *const *_suffixStringsPotions; const char *const *_suffixStringsWands; @@ -832,7 +832,7 @@ protected: void seq_portal(); bool checkPassword(); - + virtual int resurrectionSelectDialogue() = 0; virtual void useHorn(int charIndex, int weaponSlot) {} virtual bool checkPartyStatusExtra() = 0; @@ -900,7 +900,7 @@ protected: int getDexHitChanceModifier(int charIndex); int getMonsterAcHitChanceModifier(int charIndex, int monsterAc); void explodeMonster(EobMonsterInPlay *m); - + int _dstMonsterIndex; bool _preventMonsterFlash; int16 _foundMonstersArray[5]; @@ -940,7 +940,7 @@ protected: void destroyWallOfForce(int index); int findSingleSpellTarget(int dist); - + int findFirstCharacterSpellTarget(); int findNextCharacterSpellTarget(int curCharIndex); int charDeathSavingThrow(int charIndex, int div); diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp index 7d8e9250cd..6d13b17a5f 100644 --- a/engines/kyra/gui_eob.cpp +++ b/engines/kyra/gui_eob.cpp @@ -20,12 +20,12 @@ * */ -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) +#ifdef ENABLE_EOB #include "kyra/eobcommon.h" #include "kyra/gui_eob.h" #include "kyra/script_eob.h" -#include "kyra/text_eob.h" +#include "kyra/text_rpg.h" #include "kyra/timer.h" #include "kyra/util.h" @@ -35,110 +35,6 @@ namespace Kyra { -void LolEobBaseEngine::removeInputTop() { - if (!_eventList.empty()) { - if (_eventList.begin()->event.type == Common::EVENT_LBUTTONDOWN) - _mouseClick = 1; - else if (_eventList.begin()->event.type == Common::EVENT_RBUTTONDOWN) - _mouseClick = 2; - else - _mouseClick = 0; - - _eventList.erase(_eventList.begin()); - } -} - -void LolEobBaseEngine::gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) { - w--; h--; - if (fillColor != -1) - screen()->fillRect(x + 1, y + 1, x + w - 1, y + h - 1, fillColor); - - screen()->drawClippedLine(x + 1, y, x + w, y, frameColor2); - screen()->drawClippedLine(x + w, y, x + w, y + h - 1, frameColor2); - screen()->drawClippedLine(x, y, x, y + h, frameColor1); - screen()->drawClippedLine(x, y + h, x + w, y + h, frameColor1); -} - -void LolEobBaseEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 cur, int32 max, int col1, int col2) { - if (max < 1) - return; - if (cur < 0) - cur = 0; - - int32 e = MIN(cur, max); - - if (!--w) - return; - if (!--h) - return; - - int32 t = (e * w) / max; - - if (!t && e) - t++; - - if (t) - screen()->fillRect(x, y, x + t - 1, y + h, col1); - - if (t < w && col2) - screen()->fillRect(x + t, y, x + w, y + h, col2); -} - -void LolEobBaseEngine::gui_initButtonsFromList(const int16 *list) { - while (*list != -1) - gui_initButton(*list++); -} - -void LolEobBaseEngine::gui_resetButtonList() { - for (uint i = 0; i < ARRAYSIZE(_activeButtonData); ++i) - _activeButtonData[i].nextButton = 0; - - gui_notifyButtonListChanged(); - _activeButtons = 0; -} - -void LolEobBaseEngine::gui_notifyButtonListChanged() { - if (gui()) { - if (!_buttonListChanged && !_preserveEvents) - removeInputTop(); - _buttonListChanged = true; - } -} - -bool LolEobBaseEngine::clickedShape(int shapeIndex) { - if (_clickedSpecialFlag != 0x40) - return true; - - for (; shapeIndex; shapeIndex = _levelDecorationProperties[shapeIndex].next) { - if (_flags.gameID != GI_LOL) - shapeIndex--; - - uint16 s = _levelDecorationProperties[shapeIndex].shapeIndex[1]; - - if (s == 0xffff) - continue; - - int w = _flags.gameID == GI_LOL ? _levelDecorationShapes[s][3] : (_levelDecorationShapes[s][2] << 3); - int h = _levelDecorationShapes[s][_flags.gameID == GI_LOL ? 2 : 1]; - int x = _levelDecorationProperties[shapeIndex].shapeX[1] + _clickedShapeXOffs; - int y = _levelDecorationProperties[shapeIndex].shapeY[1] + _clickedShapeYOffs; - - if (_levelDecorationProperties[shapeIndex].flags & 1) { - if (_flags.gameID == GI_LOL) - w <<= 1; - else - x = 176 - x - w; - } - - if (posWithinRect(_mouseX, _mouseY, x - 4, y - 4, x + w + 8, y + h + 8)) - return true; - } - - return false; -} - -#ifdef ENABLE_EOB - Button *EobCoreEngine::gui_getButton(Button *buttonList, int index) { while (buttonList) { if (buttonList->index == index) @@ -159,7 +55,7 @@ void EobCoreEngine::gui_drawPlayField(bool refresh) { _screen->setCurPage(cp); _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); - + if (!_loading) _screen->updateScreen(); @@ -397,7 +293,7 @@ void EobCoreEngine::gui_drawWeaponSlot(int charIndex, int slot) { void EobCoreEngine::gui_drawWeaponSlotStatus(int x, int y, int status) { Common::String tmpStr; Common::String tmpStr2; - + if (status > -3 || status == -5) _screen->drawShape(_screen->_curPage, _greenSplatShape, x - 1, y, 0); else @@ -507,7 +403,7 @@ void EobCoreEngine::gui_drawFoodStatusGraph(int index) { void EobCoreEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2) { gui_drawBox(x - 1, y - 1, w + 3, h + 2, _color2_1, _color1_1, -1); - LolEobBaseEngine::gui_drawHorizontalBarGraph(x, y, w + 2, h, curVal, maxVal, col1, col2); + KyraRpgEngine::gui_drawHorizontalBarGraph(x, y, w + 2, h, curVal, maxVal, col1, col2); } void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) { @@ -858,7 +754,7 @@ int EobCoreEngine::clickedCamp(Button *button) { _screen->copyPage(0, 7); _screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 12, Screen::CR_NO_P_CHECK); - + _gui->runCampMenu(); _screen->copyRegion(0, 0, 0, 120, 176, 24, 12, 2, Screen::CR_NO_P_CHECK); @@ -870,7 +766,7 @@ int EobCoreEngine::clickedCamp(Button *button) { _screen->setCurPage(0); const ScreenDim *dm = _screen->getScreenDim(10); - _screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); @@ -1457,7 +1353,7 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) { _progress = 0; _prcButtonUnk3 = 1; _cflag = 0xffff; - + _menuLineSpacing = 0; _menuLastInFlags = 0; _menuCur = 0; @@ -1471,7 +1367,7 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) { memset(_numAssignedSpellsOfType, 0, 72); _charSelectRedraw = false; - + _updateBoxIndex = -1; _highLightBoxTimer = 0; _updateBoxColorIndex = 0; @@ -1978,7 +1874,7 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8 if (!result) result = inputFlags; - + return result; } @@ -2093,10 +1989,10 @@ void GUI_Eob::simpleMenu_flashSelection(const char *str, int x, int y, int color void GUI_Eob::runCampMenu() { Screen::FontId of = _screen->setFont(Screen::FID_8_FNT); - + Button *highlightButton = 0; Button *prevHighlightButton = 0; - + int newMenu = 0; int lastMenu = -1; bool redrawPortraits = false; @@ -2108,7 +2004,7 @@ void GUI_Eob::runCampMenu() { for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) { if (newMenu == 2) updateOptionsStrings(); - + if (newMenu != -1) { releaseButtons(buttonList); @@ -2117,7 +2013,7 @@ void GUI_Eob::runCampMenu() { _vm->_menuDefs[2].titleStrId = 57; else if (newMenu == 1) _vm->_menuDefs[1].titleStrId = 58; - + buttonList = initMenu(newMenu); if (newMenu != lastMenu) { @@ -2128,10 +2024,10 @@ void GUI_Eob::runCampMenu() { lastMenu = newMenu; newMenu = -1; } - + int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff; _vm->removeInputTop(); - + if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) inputFlag = 0x8007; else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) { @@ -2175,7 +2071,7 @@ void GUI_Eob::runCampMenu() { highlightButton = _vm->gui_getButton(buttonList, s); } - + } else if (inputFlag > 0x8000 && inputFlag < 0x8010) { int i = 0; int cnt = 0; @@ -2284,7 +2180,7 @@ void GUI_Eob::runCampMenu() { } lastMenu = -1; - + } else { Common::Point p = _vm->getMousePos(); for (Button *b = buttonList; b; b = b->nextButton) { @@ -2292,7 +2188,7 @@ void GUI_Eob::runCampMenu() { highlightButton = b; } } - + if (_charSelectRedraw || redrawPortraits) { for (int i = 0; i < 6; i++) { _vm->gui_drawCharPortraitWithStats(i); @@ -2320,10 +2216,10 @@ bool GUI_Eob::runLoadMenu(int x, int y) { int xo = dm->sx; int yo = dm->sy; bool result = false; - + _screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h); - - for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) { + + for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) { int slot = selectSaveSlotDialogue(x, y, 1); if (slot > 5) { runLoop = result = false; @@ -2356,7 +2252,7 @@ bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) { int16 y = _screen->_curDim->sy + _screen->_curDim->h - 21; int newHighlight = deflt ^ 1; int lastHighlight = -1; - + for (int i = 0; i < 2; i++) drawMenuButtonBox(x[i], y, 32, 14, false, false); @@ -2391,7 +2287,7 @@ bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) { } if (newHighlight != lastHighlight) { - for (int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) _screen->printShadedText(_vm->_menuYesNoStrings[i], x[i] + 16 - (strlen(_vm->_menuYesNoStrings[i]) << 2) + 1, y + 3, i == newHighlight ? 6 : 15, 0); _screen->updateScreen(); lastHighlight = newHighlight; @@ -2407,7 +2303,7 @@ bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) { _screen->copyRegion(0, _screen->_curDim->h, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK); _screen->setFont(of); _screen->setScreenDim(od); - + return newHighlight ? false : true; } @@ -2417,7 +2313,7 @@ void GUI_Eob::messageDialogue2(int dim, int id, int buttonTextCol) { _screen->_curPage = 2; _screen->setClearScreenDim(dim); drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false); - _screen->printShadedText(getMenuString(id), (_screen->_curDim->sx << 3) + 5, _screen->_curDim->sy + 5, 15, 0); + _screen->printShadedText(getMenuString(id), (_screen->_curDim->sx << 3) + 5, _screen->_curDim->sy + 5, 15, 0); _screen->_curPage = 0; _screen->copyRegion(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK); @@ -2628,10 +2524,10 @@ bool GUI_Eob::runSaveMenu(int x, int y) { int xo = dm->sx; int yo = dm->sy; bool result = false; - + _screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h); - - for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) { + + for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) { int slot = selectSaveSlotDialogue(x, y, 0); if (slot > 5) { runLoop = result = false; @@ -2641,13 +2537,13 @@ bool GUI_Eob::runSaveMenu(int x, int y) { _saveSlotStringsTemp[slot][0] = 0; else useSlot = confirmDialogue2(11, 55, 1); - + if (!useSlot) continue; int fx = (x + 1) << 3; int fy = y + slot * 17 + 23; - + for (int in = -1; in == -1 && !_vm->shouldQuit(); ) { _screen->fillRect(fx - 2, fy, fx + 160, fy + 8, _vm->_bkgColor_1); in = getTextInput(_saveSlotStringsTemp[slot], x + 1, fy, 19, 2, 0, 8); @@ -2665,12 +2561,12 @@ bool GUI_Eob::runSaveMenu(int x, int y) { Common::Error err = _vm->saveGameStateIntern(_savegameOffset + slot, _saveSlotStringsTemp[slot], &thumb); thumb.free(); - if (err.getCode() == Common::kNoError) + if (err.getCode() == Common::kNoError) result = true; else messageDialogue(11, 15, 6); - runLoop = false; + runLoop = false; } } @@ -2683,7 +2579,7 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) { _saveSlotX = _saveSlotY = 0; _screen->setCurPage(2); - + updateSaveSlotsList(); _savegameOffset = 0; @@ -2701,7 +2597,7 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) { int newHighlight = 0; int slot = -1; - for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) { + for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) { int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff; _vm->removeInputTop(); @@ -2768,7 +2664,7 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) { if (lastHighlight != newHighlight) { drawSaveSlotButton(lastHighlight, 0, 15); drawSaveSlotButton(newHighlight, 0, 6); - + // Display highlighted slot index in the bottom left corner to avoid people getting lost with the 990 save slots _screen->setFont(Screen::FID_6_FNT); int sli = (newHighlight == 6) ? _savegameOffset : (_savegameOffset + newHighlight); @@ -2798,7 +2694,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) { uint32 avltyFlags = 0; int li = 0; int lv = 0; - + EobCharacter *c = &_vm->_characters[charIndex]; int8 wm = c->wisdomCur - 12; if (wm < 0) @@ -2806,10 +2702,10 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) { if (spellType) { li = _vm->getCharacterLevelIndex(2, c->cClass); - + if (li == -1) { li = _vm->getCharacterLevelIndex(4, c->cClass); - + if (li != -1) { lv = c->level[li] - 1; if (lv < 0) @@ -2817,7 +2713,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) { for (int i = 0; i < _numPages; i++) np[i] = _vm->_numSpellsPal[lv * _numPages + i]; - + avltyFlags = _paladinSpellAvltyFlags; } @@ -2878,7 +2774,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) { for (int i = 0; i < 32; i++) { if (!(avltyFlags & (1 << i))) continue; - + int d = lh[i] - 1; if (d < 0) continue; @@ -2931,7 +2827,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) { if (updateDesc) { updateDesc = false; - _screen->printShadedText(Common::String::format(_vm->_menuStringsMgc[1], np[lastHighLightButton] - numAssignedSpellsPerBookPage[lastHighLightButton], np[lastHighLightButton]).c_str(), 8, 38, 9, _vm->_bkgColor_1); + _screen->printShadedText(Common::String::format(_vm->_menuStringsMgc[1], np[lastHighLightButton] - numAssignedSpellsPerBookPage[lastHighLightButton], np[lastHighLightButton]).c_str(), 8, 38, 9, _vm->_bkgColor_1); } if (newHighLightText < 0) @@ -2939,13 +2835,13 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) { if (menuSpellMap[lastHighLightButton * 11] <= newHighLightText) newHighLightText = 0; - + if (newHighLightText != lastHighLightText) { memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1], lastHighLightText, spellType, true, false); memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + newHighLightText + 1], newHighLightText, spellType, true, true); lastHighLightText = newHighLightText; } - + int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff; _vm->removeInputTop(); @@ -2961,7 +2857,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) { newHighLightText = (p.y - 50 ) / 9; if (menuSpellMap[lastHighLightButton * 11] - 1 < newHighLightText) newHighLightText = menuSpellMap[lastHighLightButton * 11] - 1; - } + } } if (inputFlag & 0x8000) { @@ -2999,7 +2895,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) { newHighLightText = 0; } else if (inputFlag == 0x8017) { if (numAssignedSpellsPerBookPage[lastHighLightButton]) { - for (int i = 1; i <= menuSpellMap[lastHighLightButton * 11]; i++) { + for (int i = 1; i <= menuSpellMap[lastHighLightButton * 11]; i++) { numAssignedSpellsPerBookPage[lastHighLightButton] -= _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + i] * 2 - 2]; _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + i] * 2 - 2] = 0; } @@ -3087,7 +2983,7 @@ void GUI_Eob::scribeScrollDialogue() { if (numScrolls) { int csel = selectCharacterDialogue(49); if (csel != -1) { - + EobCharacter *c = &_vm->_characters[csel]; int s = 0; @@ -3128,7 +3024,7 @@ void GUI_Eob::scribeScrollDialogue() { redraw = false; lastHighLight = -1; newHighLight = 0; - } + } if (lastHighLight != newHighLight) { if (lastHighLight >= 0) @@ -3152,7 +3048,7 @@ void GUI_Eob::scribeScrollDialogue() { } else if (inputFlag == 0x8023 || inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) { s = 0; } else if (inputFlag == 0x8024) { - newHighLight = (_vm->_mouseY - 50) / 9; + newHighLight = (_vm->_mouseY - 50) / 9; if (newHighLight >= 0 && newHighLight < s) { inputFlag = _vm->_keyMap[Common::KEYCODE_SPACE]; } else { @@ -3193,7 +3089,7 @@ bool GUI_Eob::restParty() { static const int8 eob1healSpells[] = { 2, 15, 20, 24 }; static const int8 eob2healSpells[] = { 3, 16, 20, 28 }; const int8 *spells = _vm->game() == GI_EOB1 ? eob1healSpells : eob2healSpells; - + uint8 crs[6]; memset(crs, 0, 6); int hours = 0; @@ -3243,7 +3139,7 @@ bool GUI_Eob::restParty() { useHealers = confirmDialogue(40); break; } - } + } } _screen->setClearScreenDim(7); @@ -3269,14 +3165,14 @@ bool GUI_Eob::restParty() { for (int ii = 0; ii < 80; ii++) { if ((ii / 10 + 48) >= crs[i]) break; - + if (*list >= 0) { list++; continue; } *list *= -1; - crs[i] = 48; + crs[i] = 48; _vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[0], _vm->_characters[i].name, _vm->_spells[_vm->_clericSpellOffset + *list].name).c_str()); _vm->delay(80); break; @@ -3289,14 +3185,14 @@ bool GUI_Eob::restParty() { for (int ii = 0; ii < 80; ii++) { if ((ii / 6 + 48) >= crs[i]) break; - + if (*list >= 0) { list++; continue; } *list *= -1; - crs[i] = 48; + crs[i] = 48; _vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[1], _vm->_characters[i].name, _vm->_spells[*list].name).c_str()); _vm->delay(80); break; @@ -3311,7 +3207,7 @@ bool GUI_Eob::restParty() { continue; if (_vm->checkInventoryForItem(i, 30, -1) == -1) continue; - + list = 0; if (crs[i] >= 48) { for (int ii = 0; !list && ii < 3; ii++) @@ -3416,7 +3312,7 @@ bool GUI_Eob::restParty() { _vm->gui_drawCharPortraitWithStats(i); } } - + if (starving) { if (!confirmDialogue(47)) { restContinue = false; @@ -3475,7 +3371,7 @@ bool GUI_Eob::confirmDialogue(int id) { Screen::FontId of = _screen->setFont(Screen::FID_8_FNT); Button *buttonList = initMenu(5); - + _screen->printShadedText(getMenuString(id), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy + 4, 15, 0); int newHighlight = 0; @@ -3490,7 +3386,7 @@ bool GUI_Eob::confirmDialogue(int id) { _screen->updateScreen(); lastHighlight = newHighlight; } - + int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff; _vm->removeInputTop(); @@ -3539,7 +3435,7 @@ void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) { drawTextBox(dim, id); const ScreenDim *dm = _screen->getScreenDim(dim); - + int bx = ((dm->sx + dm->w) << 3) - ((strlen(_vm->_menuOkString) << 3) + 16); int by = dm->sy + dm->h - 19; int bw = (strlen(_vm->_menuOkString) << 3) + 7; @@ -3565,7 +3461,7 @@ void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) { _vm->_system->delayMillis(80); drawMenuButtonBox(bx, by, bw, 14, false, true); _screen->updateScreen(); - + _screen->copyRegion(0, dm->h, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK); _screen->setScreenDim(od); _screen->setFont(of); @@ -3576,7 +3472,7 @@ int GUI_Eob::selectCharacterDialogue(int id) { uint8 flags = (id == 26) ? (_vm->game() == GI_EOB1 ? 0x04 : 0x14) : 0x02; _vm->removeInputTop(); - _charSelectRedraw = false; + _charSelectRedraw = false; bool abort = false; int count = 0; int result = -1; @@ -3584,20 +3480,20 @@ int GUI_Eob::selectCharacterDialogue(int id) { for (int i = 0; i < 6; i++) { found[i] = -1; - + if (!_vm->testCharacter(i, 1)) continue; - + if (!(_vm->_classModifierFlags[_vm->_characters[i].cClass] & flags) && (id != 53)) continue; - + if (id != 53 && (!_vm->_characters[i].food || !_vm->testCharacter(i, 4))) { abort = true; } else { found[i] = 0; result = i; count++; - } + } } if (!count) { @@ -3627,7 +3523,7 @@ int GUI_Eob::selectCharacterDialogue(int id) { _charSelectRedraw = true; } - if (count == 1) { + if (count == 1) { int l = _vm->getCharacterLevelIndex(4, _vm->_characters[result].cClass); if (l == -1) @@ -3650,7 +3546,7 @@ int GUI_Eob::selectCharacterDialogue(int id) { while (result == -2 && !_vm->shouldQuit()) { int inputFlag = _vm->checkInput(buttonList, false, 0); _vm->removeInputTop(); - + updateBoxFrameHighLight(hlCur); if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8] || inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_a] || inputFlag == _vm->_keyMap[Common::KEYCODE_w]) { @@ -3757,7 +3653,7 @@ Button *GUI_Eob::initMenu(int id) { const ScreenDim *dm = _screen->getScreenDim(m->dim); _screen->fillRect(dm->sx << 3, dm->sy, ((dm->sx + dm->w) << 3) - 1, (dm->sy + dm->h) - 1, _vm->_bkgColor_1); _screen->setScreenDim(m->dim); - drawMenuButtonBox(dm->sx << 3, dm->sy, dm->w << 3, dm->h, false, false); + drawMenuButtonBox(dm->sx << 3, dm->sy, dm->w << 3, dm->h, false, false); } _screen->printShadedText(getMenuString(m->titleStrId), 5, 5, m->titleCol, 0); @@ -3798,7 +3694,7 @@ Button *GUI_Eob::initMenu(int id) { void GUI_Eob::drawMenuButton(Button *b, bool clicked, bool highlight, bool noFill) { if (!b) return; - + EobMenuButtonDef *d = (EobMenuButtonDef*)b->extButtonDef; if (d->flags & 1) @@ -3806,7 +3702,7 @@ void GUI_Eob::drawMenuButton(Button *b, bool clicked, bool highlight, bool noFil if (d->labelId) { const char *s = getMenuString(d->labelId); - + int xOffs = 4; int yOffs = 3; @@ -3825,7 +3721,7 @@ void GUI_Eob::drawMenuButton(Button *b, bool clicked, bool highlight, bool noFil void GUI_Eob::drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool noFill) { uint8 col1 = _vm->_color1_1; uint8 col2 = _vm->_color2_1; - + if (clicked) col1 = col2 = _vm->_bkgColor_1; @@ -3859,7 +3755,7 @@ void GUI_Eob::drawSaveSlotButton(int slot, int redrawBox, int textCol) { return; int x = _saveSlotX + 4; - int y = _saveSlotY + slot * 17 + 20; + int y = _saveSlotY + slot * 17 + 20; int w = 167; const char *s = (slot < 6) ?_saveSlotStringsTemp[slot] : _vm->_saveLoadStrings[0]; @@ -3867,8 +3763,8 @@ void GUI_Eob::drawSaveSlotButton(int slot, int redrawBox, int textCol) { x = _saveSlotX + 118; y = _saveSlotY + 126; w = 53; - } - + } + if (redrawBox) drawMenuButtonBox(x, y, w, 14, (redrawBox - 1) ? true : false, false); @@ -3997,7 +3893,7 @@ void GUI_Eob::setupSaveMenuSlots() { int GUI_Eob::getHighlightSlot() { int res = -1; Common::Point p = _vm->getMousePos(); - + for (int i = 0; i < 6; i++) { int y = _saveSlotY + i * 17 + 20; if (_vm->posWithinRect(p.x, p.y, _saveSlotX + 4, y, _saveSlotX + 167, y + 14)) { @@ -4034,7 +3930,7 @@ void GUI_Eob::restParty_updateRestTime(int hours, bool init) { _screen->setCurPage(0); _screen->copyRegion(((_screen->_curDim->sx + 1) << 3) - 1, _screen->_curDim->sy + 20, ((_screen->_curDim->sx + 1) << 3) - 1, _screen->_curDim->sy + 20, 144, 8, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); - + _vm->delay(160); _screen->setScreenDim(od); @@ -4064,9 +3960,7 @@ const EobRect16 GUI_Eob::_updateBoxFrameHighLights[] = { { 0x00A3, 0x0068, 0x00C3, 0x0089 } }; -#endif // ENABLE_EOB - } // End of namespace Kyra -#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL) +#endif // ENABLE_EOB diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h index a0ac509026..46d36b97b7 100644 --- a/engines/kyra/gui_eob.h +++ b/engines/kyra/gui_eob.h @@ -56,7 +56,7 @@ public: // Non button based menu handling (main menu, character generation) void simpleMenu_setup(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing); - int simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk); + int simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk); // Button based menus (camp menu, load menu) void runCampMenu(); @@ -87,8 +87,8 @@ private: void messageDialogue(int dim, int id, int buttonTextCol); int selectCharacterDialogue(int id); void displayTextBox(int id); - - Button *initMenu(int id); + + Button *initMenu(int id); void drawMenuButton(Button *b, bool clicked, bool highlight, bool noFill); void drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool noFill); void drawTextBox(int dim, int id); diff --git a/engines/kyra/gui_rpg.cpp b/engines/kyra/gui_rpg.cpp new file mode 100644 index 0000000000..8b2a593d6b --- /dev/null +++ b/engines/kyra/gui_rpg.cpp @@ -0,0 +1,134 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#if defined(ENABLE_EOB) || defined(ENABLE_LOL) + +#include "kyra/kyra_rpg.h" + +namespace Kyra { + +void KyraRpgEngine::removeInputTop() { + if (!_eventList.empty()) { + if (_eventList.begin()->event.type == Common::EVENT_LBUTTONDOWN) + _mouseClick = 1; + else if (_eventList.begin()->event.type == Common::EVENT_RBUTTONDOWN) + _mouseClick = 2; + else + _mouseClick = 0; + + _eventList.erase(_eventList.begin()); + } +} + +void KyraRpgEngine::gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) { + w--; h--; + if (fillColor != -1) + screen()->fillRect(x + 1, y + 1, x + w - 1, y + h - 1, fillColor); + + screen()->drawClippedLine(x + 1, y, x + w, y, frameColor2); + screen()->drawClippedLine(x + w, y, x + w, y + h - 1, frameColor2); + screen()->drawClippedLine(x, y, x, y + h, frameColor1); + screen()->drawClippedLine(x, y + h, x + w, y + h, frameColor1); +} + +void KyraRpgEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 cur, int32 max, int col1, int col2) { + if (max < 1) + return; + if (cur < 0) + cur = 0; + + int32 e = MIN(cur, max); + + if (!--w) + return; + if (!--h) + return; + + int32 t = (e * w) / max; + + if (!t && e) + t++; + + if (t) + screen()->fillRect(x, y, x + t - 1, y + h, col1); + + if (t < w && col2) + screen()->fillRect(x + t, y, x + w, y + h, col2); +} + +void KyraRpgEngine::gui_initButtonsFromList(const int16 *list) { + while (*list != -1) + gui_initButton(*list++); +} + +void KyraRpgEngine::gui_resetButtonList() { + for (uint i = 0; i < ARRAYSIZE(_activeButtonData); ++i) + _activeButtonData[i].nextButton = 0; + + gui_notifyButtonListChanged(); + _activeButtons = 0; +} + +void KyraRpgEngine::gui_notifyButtonListChanged() { + if (gui()) { + if (!_buttonListChanged && !_preserveEvents) + removeInputTop(); + _buttonListChanged = true; + } +} + +bool KyraRpgEngine::clickedShape(int shapeIndex) { + if (_clickedSpecialFlag != 0x40) + return true; + + for (; shapeIndex; shapeIndex = _levelDecorationProperties[shapeIndex].next) { + if (_flags.gameID != GI_LOL) + shapeIndex--; + + uint16 s = _levelDecorationProperties[shapeIndex].shapeIndex[1]; + + if (s == 0xffff) + continue; + + int w = _flags.gameID == GI_LOL ? _levelDecorationShapes[s][3] : (_levelDecorationShapes[s][2] << 3); + int h = _levelDecorationShapes[s][_flags.gameID == GI_LOL ? 2 : 1]; + int x = _levelDecorationProperties[shapeIndex].shapeX[1] + _clickedShapeXOffs; + int y = _levelDecorationProperties[shapeIndex].shapeY[1] + _clickedShapeYOffs; + + if (_levelDecorationProperties[shapeIndex].flags & 1) { + if (_flags.gameID == GI_LOL) + w <<= 1; + else + x = 176 - x - w; + } + + if (posWithinRect(_mouseX, _mouseY, x - 4, y - 4, x + w + 8, y + h + 8)) + return true; + } + + return false; +} + +} // End of namespace Kyra + +#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL) + diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp index 44f3a7ef3d..454e56a845 100644 --- a/engines/kyra/items_eob.cpp +++ b/engines/kyra/items_eob.cpp @@ -179,7 +179,7 @@ void EobCoreEngine::deleteBlockItem(uint16 block, int type) { return; _levelBlockProperties[block].drawObjects = 0; - + for (uint16 i2 = itm, i = 0; itm != i2 || !i; i++ ) { if (type == _items[itm].type || type == -1) { _items[itm].block = -1; @@ -224,13 +224,13 @@ int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl int EobCoreEngine::stripPartyItems(int16 itemType, int16 itemValue, int handleValueMode, int numItems) { int itemsLeft = numItems; - + for (bool runloop = true; runloop && itemsLeft; ) { runloop = false; for (int i = 0; i < 6 && itemsLeft; i++) { if (!testCharacter(i, 1)) continue; - + for (int ii = 0; ii < 27 && itemsLeft; ii++) { if (ii == 16) continue; @@ -293,18 +293,18 @@ int EobCoreEngine::itemUsableByCharacter(int charIndex, Item item) { int EobCoreEngine::countQueuedItems(Item itemQueue, int16 id, int16 type, int count, int includeFlyingItems) { uint16 o1 = itemQueue; uint16 o2 = o1; - + if (!o1) return 0; int res = 0; - + for (bool forceLoop = true; o1 != o2 || forceLoop; o1 = _items[o1].prev) { EobItem *itm = &_items[o1]; forceLoop = false; if (id != -1 || type != -1) { if (((id != -1) || (id == -1 && type != itm->type)) && ((type != -1) || (type == -1 && id != o1))) - continue; + continue; } if (!includeFlyingItems) { @@ -314,8 +314,8 @@ int EobCoreEngine::countQueuedItems(Item itemQueue, int16 id, int16 type, int co if (!count) return o1; - - res++; + + res++; } return res; @@ -329,13 +329,13 @@ int EobCoreEngine::getQueuedItem(Item *items, int pos, int id) { return 0; EobItem *itm = &_items[o1]; - + for (bool forceLoop = true; o1 != o2 || forceLoop; o1 = itm->prev) { itm = &_items[o1]; forceLoop = false; if ((id != -1 || (id == -1 && itm->pos != pos)) && id != o1) continue; - + Item n = itm->next; Item p = itm->prev; _items[n].prev = p; @@ -359,10 +359,10 @@ void EobCoreEngine::printFullItemName(Item item) { const char *nameId = _itemNames[itm->nameId]; uint8 f = _itemTypes[itm->type].extraProperties & 0x7f; int8 v = itm->value; - + const char *tstr2 = 0; const char *tstr3 = 0; - + bool correctSuffixCase = false; Common::String tmpString; @@ -422,7 +422,7 @@ void EobCoreEngine::printFullItemName(Item item) { tmpString = nameUnid; break; } - + if (tstr3) { if (!tstr2) { @@ -511,7 +511,7 @@ void EobCoreEngine::eatItemInHand(int charIndex) { gui_drawFoodStatusGraph(charIndex); _screen->updateScreen(); snd_playSoundEffect(9); - } + } } bool EobCoreEngine::launchObject(int charIndex, Item item, uint16 startBlock, int startPos, int dir, int type) { @@ -540,7 +540,7 @@ bool EobCoreEngine::launchObject(int charIndex, Item item, uint16 startBlock, in t->attackerId = charIndex; t->callBackIndex = 0; - snd_playSoundEffect(type == 7 ? 26 : 11); + snd_playSoundEffect(type == 7 ? 26 : 11); return true; } @@ -579,7 +579,7 @@ bool EobCoreEngine::updateObjectFlight(EobFlyingObject *fo, int block, int pos) setItemPosition((Item*)&_levelBlockProperties[block].drawObjects, block, fo->item, pos | 4); fo->curBlock = block; fo->curPos = pos; - fo->distance--; + fo->distance--; return true; } else { @@ -594,7 +594,7 @@ bool EobCoreEngine::updateObjectFlight(EobFlyingObject *fo, int block, int pos) fo->curBlock = block; fo->curPos = pos; if (fo->distance != 255) - fo->distance--; + fo->distance--; } return true; } @@ -653,7 +653,7 @@ void EobCoreEngine::explodeObject(EobFlyingObject *fo, int block, Item item) { int16 x2 = 0; setLevelShapesDim(tl, x1, x2, 5); - + if (x2 < x1) return; diff --git a/engines/kyra/kyra_rpg.cpp b/engines/kyra/kyra_rpg.cpp new file mode 100644 index 0000000000..4a0db7b78d --- /dev/null +++ b/engines/kyra/kyra_rpg.cpp @@ -0,0 +1,361 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#if defined(ENABLE_EOB) || defined(ENABLE_LOL) + +#include "kyra/kyra_rpg.h" +#include "kyra/sound.h" + +#include "common/system.h" + +namespace Kyra { + +KyraRpgEngine::KyraRpgEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags), _numFlyingObjects(_flags.gameID == GI_LOL ? 8 : 10) { + _txt = 0; + _mouseClick = 0; + _preserveEvents = _buttonListChanged = false; + + _sceneXoffset = 0; + _sceneShpDim = 5; + + _activeButtons = 0; + + _currentLevel = 0; + + _vmpPtr = 0; + _vcnBlocks = 0; + _vcfBlocks = 0; + _vcnShift = 0; + _vcnExpTable = 0; + _vmpPtr = 0; + _blockBrightness = _wllVcnOffset = 0; + _blockDrawingBuffer = 0; + _sceneWindowBuffer = 0; + _monsterShapes = _monsterPalettes = 0; + + _doorShapes = 0; + + _levelDecorationProperties = 0; + _levelDecorationData = 0; + _levelDecorationShapes = 0; + _decorationCount = 0; + _mappedDecorationsCount = 0; + memset(_visibleBlockIndex, 0, sizeof(_visibleBlockIndex)); + + _lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0; + _levelBlockProperties = 0; + _hasTempDataFlags = 0; + + _wllVmpMap = _specialWallTypes = _wllWallFlags = 0; + _wllShapeMap = 0; + + _sceneDrawVarDown = _sceneDrawVarRight = _sceneDrawVarLeft = _wllProcessFlag = 0; + + _currentBlock = 0; + _currentDirection = 0; + _compassDirection = -1; + _updateFlags = _clickedSpecialFlag = 0; + _sceneDefaultUpdate = 0; + _sceneUpdateRequired = false; + + _flyingObjectsPtr = 0; + _flyingObjectStructSize = sizeof(EobFlyingObject); + + _clickedShapeXOffs = _clickedShapeYOffs = 0; + + _dscShapeX = 0; + _dscTileIndex = 0; + _dscUnk2 = 0; + _dscDim1 = 0; + _dscDim2 = 0; + _dscBlockMap = 0; + _dscBlockIndex = 0; + _dscShapeIndex = 0; + _dscDimMap = 0; + _dscDoorShpIndex = 0; + _dscDoorY2 = 0; + + _shpDmX1 = _shpDmX2 = 0; + + memset(_openDoorState, 0, sizeof(_openDoorState)); + memset(_dialogueButtonString, 0, 3 * sizeof(const char *)); + _dialogueButtonPosX = 0; + _dialogueButtonPosY = 0; + _dialogueNumButtons = _dialogueButtonYoffs = _dialogueHighlightedButton = 0; + _currentControlMode = 0; + _specialSceneFlag = 0; + _dialogueButtonLabelCol1 = 0; + _dialogueButtonLabelCol2 = 0; + _dialogueButtonW = 0; + _dialogueButtonH = 0; + _waitButtonPresX = 0; + _waitButtonPresY = 0; + _waitButtonPresW = 0; + _waitButtonReverveW = 0; + + _updateCharNum = -1; + _activeVoiceFileTotalTime = 0; + _updatePortraitSpeechAnimDuration = _resetPortraitAfterSpeechAnim = _needSceneRestore = 0; + _fadeText = false; + + memset(_lvlTempData, 0, sizeof(_lvlTempData)); + + _dialogueField = false; + + _environmentSfx = _environmentSfxVol = _envSfxDistThreshold = 0; + _monsterStepCounter = _monsterStepMode = 0; +} + +KyraRpgEngine::~KyraRpgEngine() { + delete[] _wllVmpMap; + delete[] _wllShapeMap; + delete[] _specialWallTypes; + delete[] _wllWallFlags; + + delete[] _vmpPtr; + delete[] _vcnExpTable; + delete[] _vcnBlocks; + delete[] _vcfBlocks; + delete[] _vcnShift; + delete[] _blockDrawingBuffer; + delete[] _sceneWindowBuffer; + + delete[] _lvlShapeTop; + delete[] _lvlShapeBottom; + delete[] _lvlShapeLeftRight; + + delete[] _doorShapes; + + delete[] _levelDecorationShapes; + delete[] _levelDecorationData; + delete[] _levelDecorationProperties; + delete[] _levelBlockProperties; +} + +Common::Error KyraRpgEngine::init() { + gui_resetButtonList(); + + _levelDecorationProperties = new LevelDecorationProperty[100]; + memset(_levelDecorationProperties, 0, 100 * sizeof(LevelDecorationProperty)); + _levelDecorationShapes = new uint8*[400]; + memset(_levelDecorationShapes, 0, 400 * sizeof(uint8*)); + _levelBlockProperties = new LevelBlockProperty[1025]; + memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty)); + + _wllVmpMap = new uint8[256]; + memset(_wllVmpMap, 0, 256); + _wllShapeMap = new int8[256]; + memset(_wllShapeMap, 0, 256); + _specialWallTypes = new uint8[256]; + memset(_specialWallTypes, 0, 256); + _wllWallFlags = new uint8[256]; + memset(_wllWallFlags, 0, 256); + + _blockDrawingBuffer = new uint16[1320]; + memset(_blockDrawingBuffer, 0, 1320 * sizeof(uint16)); + _sceneWindowBuffer = new uint8[21120]; + memset(_sceneWindowBuffer, 0, 21120); + + _lvlShapeTop = new int16[18]; + memset(_lvlShapeTop, 0, 18 * sizeof(int16)); + _lvlShapeBottom = new int16[18]; + memset(_lvlShapeBottom, 0, 18 * sizeof(int16)); + _lvlShapeLeftRight = new int16[36]; + memset(_lvlShapeLeftRight, 0, 36 * sizeof(int16)); + + _vcnExpTable = new uint8[128]; + for (int i = 0; i < 128; i++) + _vcnExpTable[i] = i & 0x0f; + + _doorShapes = new uint8*[6]; + memset(_doorShapes, 0, 6 * sizeof(uint8*)); + + initStaticResource(); + + _envSfxDistThreshold = (_sound->getSfxType() == Sound::kAdLib || _sound->getSfxType() == Sound::kPCSpkr) ? 15 : 3; + + return Common::kNoError; +} + +bool KyraRpgEngine::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2) { + if (posX < x1 || posX > x2 || posY < y1 || posY > y2) + return false; + return true; +} + +void KyraRpgEngine::drawDialogueButtons() { + int cp = screen()->setCurPage(0); + Screen::FontId of = screen()->setFont(gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT); + + for (int i = 0; i < _dialogueNumButtons; i++) { + int x = _dialogueButtonPosX[i]; + if (gameFlags().use16ColorMode) { + gui_drawBox(x, ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1, 74, 10, 0xee, 0xcc, -1); + screen()->printText(_dialogueButtonString[i], (x + 37 - (screen()->getTextWidth(_dialogueButtonString[i])) / 2) & ~3, + ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2) & ~7, _dialogueHighlightedButton == i ? 0xc1 : 0xe1, 0); + } else { + gui_drawBox(x, (_dialogueButtonYoffs + _dialogueButtonPosY[i]), _dialogueButtonW, _dialogueButtonH, _color1_1, _color2_1, _bkgColor_1); + screen()->printText(_dialogueButtonString[i], x + (_dialogueButtonW >> 1) - (screen()->getTextWidth(_dialogueButtonString[i])) / 2, + (_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2, _dialogueHighlightedButton == i ? _dialogueButtonLabelCol1 : _dialogueButtonLabelCol2, 0); + } + } + screen()->setFont(of); + screen()->setCurPage(cp); +} + +uint16 KyraRpgEngine::processDialogue() { + int df = _dialogueHighlightedButton; + int res = 0; + + for (int i = 0; i < _dialogueNumButtons; i++) { + int x = _dialogueButtonPosX[i]; + int y = (gameFlags().use16ColorMode ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i])); + Common::Point p = getMousePos(); + if (posWithinRect(p.x, p.y, x, y, x + _dialogueButtonW, y + _dialogueButtonH)) { + _dialogueHighlightedButton = i; + break; + } + } + + if (_dialogueNumButtons == 0) { + int e = checkInput(0, false) & 0xFF; + removeInputTop(); + + if (e) { + gui_notifyButtonListChanged(); + + if (e == _keyMap[Common::KEYCODE_SPACE] || e == _keyMap[Common::KEYCODE_RETURN]) { + snd_stopSpeech(true); + } + } + + if (snd_updateCharacterSpeech() != 2) { + res = 1; + if (!shouldQuit()) { + removeInputTop(); + gui_notifyButtonListChanged(); + } + } + } else { + int e = checkInput(0, false, 0) & 0xFF; + removeInputTop(); + if (e) + gui_notifyButtonListChanged(); + + if ((_flags.gameID == GI_LOL && (e == 200 || e == 202)) || (_flags.gameID != GI_LOL && (e == 199 || e == 201))) { + for (int i = 0; i < _dialogueNumButtons; i++) { + int x = _dialogueButtonPosX[i]; + int y = (gameFlags().use16ColorMode ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i])); + Common::Point p = getMousePos(); + if (posWithinRect(p.x, p.y, x, y, x + _dialogueButtonW, y + _dialogueButtonH)) { + _dialogueHighlightedButton = i; + res = _dialogueHighlightedButton + 1; + break; + } + } + } else if (e == _keyMap[Common::KEYCODE_SPACE] || e == _keyMap[Common::KEYCODE_RETURN]) { + snd_stopSpeech(true); + res = _dialogueHighlightedButton + 1; + } else if (e == _keyMap[Common::KEYCODE_LEFT] || e == _keyMap[Common::KEYCODE_DOWN]) { + if (_dialogueNumButtons > 1 && _dialogueHighlightedButton > 0) + _dialogueHighlightedButton--; + } else if (e == _keyMap[Common::KEYCODE_RIGHT] || e == _keyMap[Common::KEYCODE_UP]) { + if (_dialogueNumButtons > 1 && _dialogueHighlightedButton < (_dialogueNumButtons - 1)) + _dialogueHighlightedButton++; + } + } + + if (df != _dialogueHighlightedButton) + drawDialogueButtons(); + + screen()->updateScreen(); + + if (res == 0) + return 0; + + stopPortraitSpeechAnim(); + + if (game() == GI_LOL) { + if (!textEnabled() && _currentControlMode) { + screen()->setScreenDim(5); + const ScreenDim *d = screen()->getScreenDim(5); + screen()->fillRect(d->sx, d->sy + d->h - 9, d->sx + d->w - 1, d->sy + d->h - 1, d->unkA); + } else { + const ScreenDim *d = screen()->_curDim; + if (gameFlags().use16ColorMode) + screen()->fillRect(d->sx, d->sy, d->sx + d->w - 3, d->sy + d->h - 2, d->unkA); + else + screen()->fillRect(d->sx, d->sy, d->sx + d->w - 2, d->sy + d->h - 1, d->unkA); + txt()->clearDim(4); + txt()->resetDimTextPositions(4); + } + } + + return res; +} + +void KyraRpgEngine::delayUntil(uint32 time, bool doUpdate, bool isMainLoop) { + uint32 curTime = _system->getMillis(); + if (time > curTime) + delay(time - curTime, doUpdate, isMainLoop); +} + +int KyraRpgEngine::rollDice(int times, int pips, int inc) { + if (times <= 0 || pips <= 0) + return inc; + + int res = 0; + while (times--) + res += _rnd.getRandomNumberRng(1, pips); + + return res + inc; +} + +bool KyraRpgEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) { + if (!_sound->sfxEnabled() || shouldQuit()) + return false; + + if (_environmentSfx) + snd_playSoundEffect(_environmentSfx, _environmentSfxVol); + + int dist = 0; + if (block) { + dist = getBlockDistance(_currentBlock, block); + if (dist > _envSfxDistThreshold) { + _environmentSfx = 0; + return false; + } + } + + _environmentSfx = soundId; + _environmentSfxVol = (15 - ((block || (_flags.gameID == GI_LOL && dist < 2)) ? dist : 0)) << 4; + + return true; +} + +void KyraRpgEngine::updateEnvironmentalSfx(int soundId) { + snd_processEnvironmentalSoundEffect(soundId, _currentBlock); +} + +} // End of namespace Kyra + +#endif // ENABLE_EOB || ENABLE_LOL diff --git a/engines/kyra/kyra_rpg.h b/engines/kyra/kyra_rpg.h new file mode 100644 index 0000000000..9acc6ff0dc --- /dev/null +++ b/engines/kyra/kyra_rpg.h @@ -0,0 +1,355 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef KYRA_RPG_H +#define KYRA_RPG_H + +#if defined(ENABLE_EOB) || defined(ENABLE_LOL) + +#include "kyra/kyra_v1.h" +#include "kyra/screen_eob.h" +#include "kyra/gui_eob.h" +#include "kyra/text_lol.h" + +namespace Kyra { + +struct LevelDecorationProperty { + uint16 shapeIndex[10]; + uint8 scaleFlag[10]; + int16 shapeX[10]; + int16 shapeY[10]; + int8 next; + uint8 flags; +}; + +struct LevelBlockProperty { + uint8 walls[4]; + uint16 assignedObjects; + uint16 drawObjects; + uint8 direction; + uint16 flags; +}; + +struct OpenDoorState { + uint16 block; + int8 wall; + int8 state; +}; + +struct LevelTempData { + uint8 *wallsXorData; + uint16 *flags; + void *monsters; + void *flyingObjects; + void *wallsOfForce; + uint8 monsterDifficulty; +}; + +struct EobFlyingObject { + uint8 enable; + uint8 objectType; + int16 attackerId; + Item item; + uint16 curBlock; + uint16 u2; + uint8 u1; + uint8 direction; + uint8 distance; + int8 callBackIndex; + uint8 curPos; + uint8 flags; + uint8 unused; +}; + +class KyraRpgEngine : public KyraEngine_v1 { +friend class TextDisplayer_rpg; +public: + KyraRpgEngine(OSystem *system, const GameFlags &flags); + virtual ~KyraRpgEngine(); + + virtual Screen *screen() = 0; + virtual GUI *gui() const = 0; + +protected: + // Startup + virtual Common::Error init(); + virtual Common::Error go() = 0; + + // Init + void initStaticResource(); + + const uint8 **_itemIconShapes; + + // Main loop + virtual void update() = 0; + void updateEnvironmentalSfx(int soundId); + + // timers + virtual void setupTimers() = 0; + void enableSysTimer(int sysTimer); + void disableSysTimer(int sysTimer); + void enableTimer(int id); + virtual uint8 getClock2Timer(int index) = 0; + virtual uint8 getNumClock2Timers() = 0; + + void timerProcessDoors(int timerNum); + + // mouse + bool posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2); + virtual void setHandItem(Item itemIndex) = 0; + + // Characters + int _updateCharNum; + int _updatePortraitSpeechAnimDuration; + bool _fadeText; + int _resetPortraitAfterSpeechAnim; + int _needSceneRestore; + + // Items + int _itemInHand; + + // Monsters + int getBlockDistance(uint16 block1, uint16 block2); + + uint8 **_monsterPalettes; + uint8 **_monsterShapes; + + int16 _shpDmX1; + int16 _shpDmX2; + + int _monsterStepCounter; + int _monsterStepMode; + + // Level + virtual void addLevelItems() = 0; + virtual void loadBlockProperties(const char *file) = 0; + + virtual void drawScene(int pageNum) = 0; + virtual void drawSceneShapes(int start) = 0; + virtual void drawDecorations(int index) = 0; + + virtual const uint8 *getBlockFileData(int levelIndex) = 0; + void setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim); + void scaleLevelShapesDim(int index, int16 &y1, int16 &y2, int dim); + void drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2); + void generateBlockDrawingBuffer(); + void generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY); + void generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY); + bool hasWall(int index); + void assignVisibleBlocks(int block, int direction); + bool checkSceneUpdateNeed(int block); + void drawVcnBlocks(); + uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction); + + virtual int clickedDoorSwitch(uint16 block, uint16 direction) = 0; + int clickedWallShape(uint16 block, uint16 direction); + int clickedLeverOn(uint16 block, uint16 direction); + int clickedLeverOff(uint16 block, uint16 direction); + int clickedWallOnlyScript(uint16 block); + virtual int clickedNiche(uint16 block, uint16 direction) = 0; + + void processDoorSwitch(uint16 block, int openClose); + void openCloseDoor(int block, int openClose); + void completeDoorOperations(); + + uint8 *_wllVmpMap; + int8 *_wllShapeMap; + uint8 *_specialWallTypes; + uint8 *_wllWallFlags; + + int _sceneXoffset; + int _sceneShpDim; + + LevelBlockProperty *_levelBlockProperties; + LevelBlockProperty *_visibleBlocks[18]; + LevelDecorationProperty *_levelDecorationData; + uint16 _levelDecorationDataSize; + LevelDecorationProperty *_levelDecorationProperties; + uint8 **_levelDecorationShapes; + uint16 _decorationCount; + int16 _mappedDecorationsCount; + uint16 *_vmpPtr; + uint8 *_vcnBlocks; + uint8 *_vcfBlocks; + uint8 *_vcnShift; + uint8 *_vcnExpTable; + uint16 *_blockDrawingBuffer; + uint8 *_sceneWindowBuffer; + uint8 _blockBrightness; + uint8 _wllVcnOffset; + + uint8 **_doorShapes; + + uint8 _currentLevel; + uint16 _currentBlock; + uint16 _currentDirection; + int _sceneDefaultUpdate; + bool _sceneUpdateRequired; + + int16 _visibleBlockIndex[18]; + int16 *_lvlShapeLeftRight; + int16 *_lvlShapeTop; + int16 *_lvlShapeBottom; + + char _lastBlockDataFile[13]; + uint32 _hasTempDataFlags; + + int16 _sceneDrawVarDown; + int16 _sceneDrawVarRight; + int16 _sceneDrawVarLeft; + int _wllProcessFlag; + + OpenDoorState _openDoorState[3]; + + int _sceneDrawPage1; + int _sceneDrawPage2; + + const int8 *_dscShapeIndex; + const uint8 *_dscDimMap; + const int8 *_dscDim1; + const int8 *_dscDim2; + const int16 *_dscShapeX; + const uint8 *_dscUnk2; + const uint8 *_dscBlockMap; + const int8 *_dscBlockIndex; + const uint8 *_dscTileIndex; + + const uint8 *_dscDoorShpIndex; + int _dscDoorShpIndexSize; + const uint8 *_dscDoorY2; + + // Script + virtual void runLevelScript(int block, int flags) = 0; + + // Gui + void removeInputTop(); + void gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor); + virtual void gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2); + void gui_initButtonsFromList(const int16 *list); + virtual void gui_initButton(int index, int x = -1, int y = -1, int val = -1) = 0; + void gui_resetButtonList(); + void gui_notifyButtonListChanged(); + + bool clickedShape(int shapeIndex); + + int _clickedShapeXOffs; + int _clickedShapeYOffs; + + Button *_activeButtons; + Button _activeButtonData[70]; + Common::Array _buttonCallbacks; + //bool _processingButtons; + + uint8 _mouseClick; + bool _preserveEvents; + bool _buttonListChanged; + + int _updateFlags; + int _clickedSpecialFlag; + + int _compassDirection; + + static const uint8 _dropItemDirIndex[]; + + // text + void drawDialogueButtons(); + uint16 processDialogue(); + + TextDisplayer_rpg *_txt; + virtual TextDisplayer_rpg *txt() { return _txt; } + + bool _dialogueField; + + const char *_dialogueButtonString[9]; + const uint16 *_dialogueButtonPosX; + const uint8 *_dialogueButtonPosY; + int16 _dialogueButtonYoffs; + uint16 _dialogueButtonW; + uint16 _dialogueButtonH; + const uint16 *_waitButtonPresX; + const uint8 *_waitButtonPresY; + const uint16 *_waitButtonPresW; + int _waitButtonReverveW; + int _dialogueNumButtons; + int _dialogueHighlightedButton; + int _currentControlMode; + int _specialSceneFlag; + uint8 _dialogueButtonLabelCol1; + uint8 _dialogueButtonLabelCol2; + + int _bkgColor_1; + uint8 _color1_1; + uint8 _color2_1; + + const char *const *_moreStrings; + + // misc + virtual void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false) = 0; + void delayUntil(uint32 time, bool doUpdate = false, bool isMainLoop = false); + int rollDice(int times, int pips, int inc = 0); + + virtual Common::Error loadGameState(int slot) = 0; + virtual Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) = 0; + + void generateTempData(); + virtual void restoreBlockTempData(int levelIndex); + void releaseTempData(); + virtual void *generateMonsterTempData(LevelTempData *tmp) = 0; + virtual void restoreMonsterTempData(LevelTempData *tmp) = 0; + virtual void releaseMonsterTempData(LevelTempData *tmp) = 0; + void restoreFlyingObjectTempData(LevelTempData *tmp); + void *generateFlyingObjectTempData(LevelTempData *tmp); + void releaseFlyingObjectTempData(LevelTempData *tmp); + virtual void *generateWallOfForceTempData(LevelTempData *tmp) { return 0; } + virtual void restoreWallOfForceTempData(LevelTempData *tmp) {} + virtual void releaseWallOfForceTempData(LevelTempData *tmp) {} + + LevelTempData *_lvlTempData[29]; + const int _numFlyingObjects; + uint32 _flyingObjectStructSize; + void *_flyingObjectsPtr; + + // sound + virtual bool snd_processEnvironmentalSoundEffect(int soundId, int block); + virtual void snd_stopSpeech(bool) {} + virtual int snd_updateCharacterSpeech() { return 0; } + virtual void stopPortraitSpeechAnim() {} + virtual void setupOpcodeTable() {} + virtual void snd_playVoiceFile(int) {} + + int _environmentSfx; + int _environmentSfxVol; + int _envSfxDistThreshold; + + uint32 _activeVoiceFileTotalTime; + + // unused + void setWalkspeed(uint8) {} + void removeHandItem() {} + bool lineIsPassable(int, int) { return false; } +}; + +} // End of namespace Kyra + +#endif // ENABLE_EOB || ENABLE_LOL + +#endif \ No newline at end of file diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index a8dfeb5b52..8561b5e071 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -42,7 +42,7 @@ namespace Kyra { const char *const LoLEngine::kKeymapName = "lol"; -LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : LolEobBaseEngine(system, flags) { +LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraRpgEngine(system, flags) { _screen = 0; _gui = 0; _tim = 0; @@ -154,9 +154,9 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : LolEobBaseEngine _dscWalls = 0; _dscOvlMap = 0; _dscShapeScaleW = 0; - _dscShapeScaleH = 0; + _dscShapeScaleH = 0; _dscShapeY = 0; - _dscShapeOvlIndex = 0; + _dscShapeOvlIndex = 0; _dscDoorMonsterX = _dscDoorMonsterY = 0; _dscDoor4 = 0; @@ -409,8 +409,8 @@ Common::Error LoLEngine::init() { if (!_sound->init()) error("Couldn't init sound"); - LolEobBaseEngine::init(); - + KyraRpgEngine::init(); + _wllAutomapData = new uint8[80]; memset(_wllAutomapData, 0, 80); @@ -1091,7 +1091,7 @@ int LoLEngine::decodeCyrillic(const char *src, char *dst) { assert(cChar < sizeof(decodeTable2)); cChar = decodeTable2[cChar]; } else if (cChar >= 0x70) { - cChar = *src++; + cChar = *src++; } else if (cChar >= 0x30) { if (cChar < 0x60) cChar -= 0x30; @@ -1929,7 +1929,7 @@ void LoLEngine::setupDialogueButtons(int numStr, const char *s1, const char *s2, _dialogueButtonString[1] = s2; _dialogueButtonString[2] = s3; _dialogueHighlightedButton = 0; - + const ScreenDim *d = screen()->getScreenDim(5); static uint16 posX[3]; @@ -1945,8 +1945,8 @@ void LoLEngine::setupDialogueButtons(int numStr, const char *s1, const char *s2, } else { int xOffs = d->w / numStr; posX[0] = d->sx + (xOffs >> 1) - 37; - posX[1] = posX[0] + xOffs; - posX[2] = posX[1] + xOffs; + posX[1] = posX[0] + xOffs; + posX[2] = posX[1] + xOffs; } drawDialogueButtons(); diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 7bd67686e6..dabc141775 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -25,7 +25,7 @@ #ifndef KYRA_LOL_H #define KYRA_LOL_H -#include "kyra/loleobbase.h" +#include "kyra/kyra_rpg.h" #include "kyra/script_tim.h" #include "kyra/script.h" #include "kyra/gui_lol.h" @@ -265,7 +265,7 @@ struct MistOfDoomAnimData { uint8 sound; }; -class LoLEngine : public LolEobBaseEngine { +class LoLEngine : public KyraRpgEngine { friend class GUI_LoL; friend class TextDisplayer_LoL; friend class TIMInterpreter_LoL; @@ -577,7 +577,7 @@ private: void setupDialogueButtons(int numStr, const char *s1, const char *s2, const char *s3); TextDisplayer_LoL *_txt; - TextDisplayer_Eob *txt() { return _txt; } + TextDisplayer_rpg *txt() { return _txt; } // emc scripts void runInitScript(const char *filename, int optionalFunc); diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp deleted file mode 100644 index bcab2781a0..0000000000 --- a/engines/kyra/loleobbase.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) - -#include "kyra/loleobbase.h" -#include "kyra/sound.h" - -#include "common/system.h" - -namespace Kyra { - -LolEobBaseEngine::LolEobBaseEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags), _numFlyingObjects(_flags.gameID == GI_LOL ? 8 : 10) { - _txt = 0; - _mouseClick = 0; - _preserveEvents = _buttonListChanged = false; - - _sceneXoffset = 0; - _sceneShpDim = 5; - - _activeButtons = 0; - - _currentLevel = 0; - - _vmpPtr = 0; - _vcnBlocks = 0; - _vcfBlocks = 0; - _vcnShift = 0; - _vcnExpTable = 0; - _vmpPtr = 0; - _blockBrightness = _wllVcnOffset = 0; - _blockDrawingBuffer = 0; - _sceneWindowBuffer = 0; - _monsterShapes = _monsterPalettes = 0; - - _doorShapes = 0; - - _levelDecorationProperties = 0; - _levelDecorationData = 0; - _levelDecorationShapes = 0; - _decorationCount = 0; - _mappedDecorationsCount = 0; - memset(_visibleBlockIndex, 0, sizeof(_visibleBlockIndex)); - - _lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0; - _levelBlockProperties = 0; - _hasTempDataFlags = 0; - - _wllVmpMap = _specialWallTypes = _wllWallFlags = 0; - _wllShapeMap = 0; - - _sceneDrawVarDown = _sceneDrawVarRight = _sceneDrawVarLeft = _wllProcessFlag = 0; - - _currentBlock = 0; - _currentDirection = 0; - _compassDirection = -1; - _updateFlags = _clickedSpecialFlag = 0; - _sceneDefaultUpdate = 0; - _sceneUpdateRequired = false; - - _flyingObjectsPtr = 0; - _flyingObjectStructSize = sizeof(EobFlyingObject); - - _clickedShapeXOffs = _clickedShapeYOffs = 0; - - _dscShapeX = 0; - _dscTileIndex = 0; - _dscUnk2 = 0; - _dscDim1 = 0; - _dscDim2 = 0; - _dscBlockMap = 0; - _dscBlockIndex = 0; - _dscShapeIndex = 0; - _dscDimMap = 0; - _dscDoorShpIndex = 0; - _dscDoorY2 = 0; - - _shpDmX1 = _shpDmX2 = 0; - - memset(_openDoorState, 0, sizeof(_openDoorState)); - memset(_dialogueButtonString, 0, 3 * sizeof(const char *)); - _dialogueButtonPosX = 0; - _dialogueButtonPosY = 0; - _dialogueNumButtons = _dialogueButtonYoffs = _dialogueHighlightedButton = 0; - _currentControlMode = 0; - _specialSceneFlag = 0; - _dialogueButtonLabelCol1 = 0; - _dialogueButtonLabelCol2 = 0; - _dialogueButtonW = 0; - _dialogueButtonH = 0; - _waitButtonPresX = 0; - _waitButtonPresY = 0; - _waitButtonPresW = 0; - _waitButtonReverveW = 0; - - _updateCharNum = -1; - _activeVoiceFileTotalTime = 0; - _updatePortraitSpeechAnimDuration = _resetPortraitAfterSpeechAnim = _needSceneRestore = 0; - _fadeText = false; - - memset(_lvlTempData, 0, sizeof(_lvlTempData)); - - _dialogueField = false; - - _environmentSfx = _environmentSfxVol = _envSfxDistThreshold = 0; - _monsterStepCounter = _monsterStepMode = 0; -} - -LolEobBaseEngine::~LolEobBaseEngine() { - delete[] _wllVmpMap; - delete[] _wllShapeMap; - delete[] _specialWallTypes; - delete[] _wllWallFlags; - - delete[] _vmpPtr; - delete[] _vcnExpTable; - delete[] _vcnBlocks; - delete[] _vcfBlocks; - delete[] _vcnShift; - delete[] _blockDrawingBuffer; - delete[] _sceneWindowBuffer; - - delete[] _lvlShapeTop; - delete[] _lvlShapeBottom; - delete[] _lvlShapeLeftRight; - - delete[] _doorShapes; - - delete[] _levelDecorationShapes; - delete[] _levelDecorationData; - delete[] _levelDecorationProperties; - delete[] _levelBlockProperties; -} - -Common::Error LolEobBaseEngine::init() { - gui_resetButtonList(); - - _levelDecorationProperties = new LevelDecorationProperty[100]; - memset(_levelDecorationProperties, 0, 100 * sizeof(LevelDecorationProperty)); - _levelDecorationShapes = new uint8*[400]; - memset(_levelDecorationShapes, 0, 400 * sizeof(uint8*)); - _levelBlockProperties = new LevelBlockProperty[1025]; - memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty)); - - _wllVmpMap = new uint8[256]; - memset(_wllVmpMap, 0, 256); - _wllShapeMap = new int8[256]; - memset(_wllShapeMap, 0, 256); - _specialWallTypes = new uint8[256]; - memset(_specialWallTypes, 0, 256); - _wllWallFlags = new uint8[256]; - memset(_wllWallFlags, 0, 256); - - _blockDrawingBuffer = new uint16[1320]; - memset(_blockDrawingBuffer, 0, 1320 * sizeof(uint16)); - _sceneWindowBuffer = new uint8[21120]; - memset(_sceneWindowBuffer, 0, 21120); - - _lvlShapeTop = new int16[18]; - memset(_lvlShapeTop, 0, 18 * sizeof(int16)); - _lvlShapeBottom = new int16[18]; - memset(_lvlShapeBottom, 0, 18 * sizeof(int16)); - _lvlShapeLeftRight = new int16[36]; - memset(_lvlShapeLeftRight, 0, 36 * sizeof(int16)); - - _vcnExpTable = new uint8[128]; - for (int i = 0; i < 128; i++) - _vcnExpTable[i] = i & 0x0f; - - _doorShapes = new uint8*[6]; - memset(_doorShapes, 0, 6 * sizeof(uint8*)); - - initStaticResource(); - - _envSfxDistThreshold = (_sound->getSfxType() == Sound::kAdLib || _sound->getSfxType() == Sound::kPCSpkr) ? 15 : 3; - - return Common::kNoError; -} - -bool LolEobBaseEngine::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2) { - if (posX < x1 || posX > x2 || posY < y1 || posY > y2) - return false; - return true; -} - -void LolEobBaseEngine::drawDialogueButtons() { - int cp = screen()->setCurPage(0); - Screen::FontId of = screen()->setFont(gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT); - - for (int i = 0; i < _dialogueNumButtons; i++) { - int x = _dialogueButtonPosX[i]; - if (gameFlags().use16ColorMode) { - gui_drawBox(x, ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1, 74, 10, 0xee, 0xcc, -1); - screen()->printText(_dialogueButtonString[i], (x + 37 - (screen()->getTextWidth(_dialogueButtonString[i])) / 2) & ~3, - ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2) & ~7, _dialogueHighlightedButton == i ? 0xc1 : 0xe1, 0); - } else { - gui_drawBox(x, (_dialogueButtonYoffs + _dialogueButtonPosY[i]), _dialogueButtonW, _dialogueButtonH, _color1_1, _color2_1, _bkgColor_1); - screen()->printText(_dialogueButtonString[i], x + (_dialogueButtonW >> 1) - (screen()->getTextWidth(_dialogueButtonString[i])) / 2, - (_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2, _dialogueHighlightedButton == i ? _dialogueButtonLabelCol1 : _dialogueButtonLabelCol2, 0); - } - } - screen()->setFont(of); - screen()->setCurPage(cp); -} - -uint16 LolEobBaseEngine::processDialogue() { - int df = _dialogueHighlightedButton; - int res = 0; - - for (int i = 0; i < _dialogueNumButtons; i++) { - int x = _dialogueButtonPosX[i]; - int y = (gameFlags().use16ColorMode ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i])); - Common::Point p = getMousePos(); - if (posWithinRect(p.x, p.y, x, y, x + _dialogueButtonW, y + _dialogueButtonH)) { - _dialogueHighlightedButton = i; - break; - } - } - - if (_dialogueNumButtons == 0) { - int e = checkInput(0, false) & 0xFF; - removeInputTop(); - - if (e) { - gui_notifyButtonListChanged(); - - if (e == _keyMap[Common::KEYCODE_SPACE] || e == _keyMap[Common::KEYCODE_RETURN]) { - snd_stopSpeech(true); - } - } - - if (snd_updateCharacterSpeech() != 2) { - res = 1; - if (!shouldQuit()) { - removeInputTop(); - gui_notifyButtonListChanged(); - } - } - } else { - int e = checkInput(0, false, 0) & 0xFF; - removeInputTop(); - if (e) - gui_notifyButtonListChanged(); - - if ((_flags.gameID == GI_LOL && (e == 200 || e == 202)) || (_flags.gameID != GI_LOL && (e == 199 || e == 201))) { - for (int i = 0; i < _dialogueNumButtons; i++) { - int x = _dialogueButtonPosX[i]; - int y = (gameFlags().use16ColorMode ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i])); - Common::Point p = getMousePos(); - if (posWithinRect(p.x, p.y, x, y, x + _dialogueButtonW, y + _dialogueButtonH)) { - _dialogueHighlightedButton = i; - res = _dialogueHighlightedButton + 1; - break; - } - } - } else if (e == _keyMap[Common::KEYCODE_SPACE] || e == _keyMap[Common::KEYCODE_RETURN]) { - snd_stopSpeech(true); - res = _dialogueHighlightedButton + 1; - } else if (e == _keyMap[Common::KEYCODE_LEFT] || e == _keyMap[Common::KEYCODE_DOWN]) { - if (_dialogueNumButtons > 1 && _dialogueHighlightedButton > 0) - _dialogueHighlightedButton--; - } else if (e == _keyMap[Common::KEYCODE_RIGHT] || e == _keyMap[Common::KEYCODE_UP]) { - if (_dialogueNumButtons > 1 && _dialogueHighlightedButton < (_dialogueNumButtons - 1)) - _dialogueHighlightedButton++; - } - } - - if (df != _dialogueHighlightedButton) - drawDialogueButtons(); - - screen()->updateScreen(); - - if (res == 0) - return 0; - - stopPortraitSpeechAnim(); - - if (game() == GI_LOL) { - if (!textEnabled() && _currentControlMode) { - screen()->setScreenDim(5); - const ScreenDim *d = screen()->getScreenDim(5); - screen()->fillRect(d->sx, d->sy + d->h - 9, d->sx + d->w - 1, d->sy + d->h - 1, d->unkA); - } else { - const ScreenDim *d = screen()->_curDim; - if (gameFlags().use16ColorMode) - screen()->fillRect(d->sx, d->sy, d->sx + d->w - 3, d->sy + d->h - 2, d->unkA); - else - screen()->fillRect(d->sx, d->sy, d->sx + d->w - 2, d->sy + d->h - 1, d->unkA); - txt()->clearDim(4); - txt()->resetDimTextPositions(4); - } - } - - return res; -} - -void LolEobBaseEngine::delayUntil(uint32 time, bool doUpdate, bool isMainLoop) { - uint32 curTime = _system->getMillis(); - if (time > curTime) - delay(time - curTime, doUpdate, isMainLoop); -} - -int LolEobBaseEngine::rollDice(int times, int pips, int inc) { - if (times <= 0 || pips <= 0) - return inc; - - int res = 0; - while (times--) - res += _rnd.getRandomNumberRng(1, pips); - - return res + inc; -} - -bool LolEobBaseEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) { - if (!_sound->sfxEnabled() || shouldQuit()) - return false; - - if (_environmentSfx) - snd_playSoundEffect(_environmentSfx, _environmentSfxVol); - - int dist = 0; - if (block) { - dist = getBlockDistance(_currentBlock, block); - if (dist > _envSfxDistThreshold) { - _environmentSfx = 0; - return false; - } - } - - _environmentSfx = soundId; - _environmentSfxVol = (15 - ((block || (_flags.gameID == GI_LOL && dist < 2)) ? dist : 0)) << 4; - - return true; -} - -void LolEobBaseEngine::updateEnvironmentalSfx(int soundId) { - snd_processEnvironmentalSoundEffect(soundId, _currentBlock); -} - -} // End of namespace Kyra - -#endif // ENABLE_EOB || ENABLE_LOL diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h deleted file mode 100644 index 06d0688058..0000000000 --- a/engines/kyra/loleobbase.h +++ /dev/null @@ -1,355 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef KYRA_LOLEOBBASE_H -#define KYRA_LOLEOBBASE_H - -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) - -#include "kyra/kyra_v1.h" -#include "kyra/screen_eob.h" -#include "kyra/gui_eob.h" -#include "kyra/text_lol.h" - -namespace Kyra { - -struct LevelDecorationProperty { - uint16 shapeIndex[10]; - uint8 scaleFlag[10]; - int16 shapeX[10]; - int16 shapeY[10]; - int8 next; - uint8 flags; -}; - -struct LevelBlockProperty { - uint8 walls[4]; - uint16 assignedObjects; - uint16 drawObjects; - uint8 direction; - uint16 flags; -}; - -struct OpenDoorState { - uint16 block; - int8 wall; - int8 state; -}; - -struct LevelTempData { - uint8 *wallsXorData; - uint16 *flags; - void *monsters; - void *flyingObjects; - void *wallsOfForce; - uint8 monsterDifficulty; -}; - -struct EobFlyingObject { - uint8 enable; - uint8 objectType; - int16 attackerId; - Item item; - uint16 curBlock; - uint16 u2; - uint8 u1; - uint8 direction; - uint8 distance; - int8 callBackIndex; - uint8 curPos; - uint8 flags; - uint8 unused; -}; - -class LolEobBaseEngine : public KyraEngine_v1 { -friend class TextDisplayer_Eob; -public: - LolEobBaseEngine(OSystem *system, const GameFlags &flags); - virtual ~LolEobBaseEngine(); - - virtual Screen *screen() = 0; - virtual GUI *gui() const = 0; - -protected: - // Startup - virtual Common::Error init(); - virtual Common::Error go() = 0; - - // Init - void initStaticResource(); - - const uint8 **_itemIconShapes; - - // Main loop - virtual void update() = 0; - void updateEnvironmentalSfx(int soundId); - - // timers - virtual void setupTimers() = 0; - void enableSysTimer(int sysTimer); - void disableSysTimer(int sysTimer); - void enableTimer(int id); - virtual uint8 getClock2Timer(int index) = 0; - virtual uint8 getNumClock2Timers() = 0; - - void timerProcessDoors(int timerNum); - - // mouse - bool posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2); - virtual void setHandItem(Item itemIndex) = 0; - - // Characters - int _updateCharNum; - int _updatePortraitSpeechAnimDuration; - bool _fadeText; - int _resetPortraitAfterSpeechAnim; - int _needSceneRestore; - - // Items - int _itemInHand; - - // Monsters - int getBlockDistance(uint16 block1, uint16 block2); - - uint8 **_monsterPalettes; - uint8 **_monsterShapes; - - int16 _shpDmX1; - int16 _shpDmX2; - - int _monsterStepCounter; - int _monsterStepMode; - - // Level - virtual void addLevelItems() = 0; - virtual void loadBlockProperties(const char *file) = 0; - - virtual void drawScene(int pageNum) = 0; - virtual void drawSceneShapes(int start) = 0; - virtual void drawDecorations(int index) = 0; - - virtual const uint8 *getBlockFileData(int levelIndex) = 0; - void setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim); - void scaleLevelShapesDim(int index, int16 &y1, int16 &y2, int dim); - void drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2); - void generateBlockDrawingBuffer(); - void generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY); - void generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY); - bool hasWall(int index); - void assignVisibleBlocks(int block, int direction); - bool checkSceneUpdateNeed(int block); - void drawVcnBlocks(); - uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction); - - virtual int clickedDoorSwitch(uint16 block, uint16 direction) = 0; - int clickedWallShape(uint16 block, uint16 direction); - int clickedLeverOn(uint16 block, uint16 direction); - int clickedLeverOff(uint16 block, uint16 direction); - int clickedWallOnlyScript(uint16 block); - virtual int clickedNiche(uint16 block, uint16 direction) = 0; - - void processDoorSwitch(uint16 block, int openClose); - void openCloseDoor(int block, int openClose); - void completeDoorOperations(); - - uint8 *_wllVmpMap; - int8 *_wllShapeMap; - uint8 *_specialWallTypes; - uint8 *_wllWallFlags; - - int _sceneXoffset; - int _sceneShpDim; - - LevelBlockProperty *_levelBlockProperties; - LevelBlockProperty *_visibleBlocks[18]; - LevelDecorationProperty *_levelDecorationData; - uint16 _levelDecorationDataSize; - LevelDecorationProperty *_levelDecorationProperties; - uint8 **_levelDecorationShapes; - uint16 _decorationCount; - int16 _mappedDecorationsCount; - uint16 *_vmpPtr; - uint8 *_vcnBlocks; - uint8 *_vcfBlocks; - uint8 *_vcnShift; - uint8 *_vcnExpTable; - uint16 *_blockDrawingBuffer; - uint8 *_sceneWindowBuffer; - uint8 _blockBrightness; - uint8 _wllVcnOffset; - - uint8 **_doorShapes; - - uint8 _currentLevel; - uint16 _currentBlock; - uint16 _currentDirection; - int _sceneDefaultUpdate; - bool _sceneUpdateRequired; - - int16 _visibleBlockIndex[18]; - int16 *_lvlShapeLeftRight; - int16 *_lvlShapeTop; - int16 *_lvlShapeBottom; - - char _lastBlockDataFile[13]; - uint32 _hasTempDataFlags; - - int16 _sceneDrawVarDown; - int16 _sceneDrawVarRight; - int16 _sceneDrawVarLeft; - int _wllProcessFlag; - - OpenDoorState _openDoorState[3]; - - int _sceneDrawPage1; - int _sceneDrawPage2; - - const int8 *_dscShapeIndex; - const uint8 *_dscDimMap; - const int8 *_dscDim1; - const int8 *_dscDim2; - const int16 *_dscShapeX; - const uint8 *_dscUnk2; - const uint8 *_dscBlockMap; - const int8 *_dscBlockIndex; - const uint8 *_dscTileIndex; - - const uint8 *_dscDoorShpIndex; - int _dscDoorShpIndexSize; - const uint8 *_dscDoorY2; - - // Script - virtual void runLevelScript(int block, int flags) = 0; - - // Gui - void removeInputTop(); - void gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor); - virtual void gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2); - void gui_initButtonsFromList(const int16 *list); - virtual void gui_initButton(int index, int x = -1, int y = -1, int val = -1) = 0; - void gui_resetButtonList(); - void gui_notifyButtonListChanged(); - - bool clickedShape(int shapeIndex); - - int _clickedShapeXOffs; - int _clickedShapeYOffs; - - Button *_activeButtons; - Button _activeButtonData[70]; - Common::Array _buttonCallbacks; - //bool _processingButtons; - - uint8 _mouseClick; - bool _preserveEvents; - bool _buttonListChanged; - - int _updateFlags; - int _clickedSpecialFlag; - - int _compassDirection; - - static const uint8 _dropItemDirIndex[]; - - // text - void drawDialogueButtons(); - uint16 processDialogue(); - - TextDisplayer_Eob *_txt; - virtual TextDisplayer_Eob *txt() { return _txt; } - - bool _dialogueField; - - const char *_dialogueButtonString[9]; - const uint16 *_dialogueButtonPosX; - const uint8 *_dialogueButtonPosY; - int16 _dialogueButtonYoffs; - uint16 _dialogueButtonW; - uint16 _dialogueButtonH; - const uint16 *_waitButtonPresX; - const uint8 *_waitButtonPresY; - const uint16 *_waitButtonPresW; - int _waitButtonReverveW; - int _dialogueNumButtons; - int _dialogueHighlightedButton; - int _currentControlMode; - int _specialSceneFlag; - uint8 _dialogueButtonLabelCol1; - uint8 _dialogueButtonLabelCol2; - - int _bkgColor_1; - uint8 _color1_1; - uint8 _color2_1; - - const char *const *_moreStrings; - - // misc - virtual void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false) = 0; - void delayUntil(uint32 time, bool doUpdate = false, bool isMainLoop = false); - int rollDice(int times, int pips, int inc = 0); - - virtual Common::Error loadGameState(int slot) = 0; - virtual Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) = 0; - - void generateTempData(); - virtual void restoreBlockTempData(int levelIndex); - void releaseTempData(); - virtual void *generateMonsterTempData(LevelTempData *tmp) = 0; - virtual void restoreMonsterTempData(LevelTempData *tmp) = 0; - virtual void releaseMonsterTempData(LevelTempData *tmp) = 0; - void restoreFlyingObjectTempData(LevelTempData *tmp); - void *generateFlyingObjectTempData(LevelTempData *tmp); - void releaseFlyingObjectTempData(LevelTempData *tmp); - virtual void *generateWallOfForceTempData(LevelTempData *tmp) { return 0; } - virtual void restoreWallOfForceTempData(LevelTempData *tmp) {} - virtual void releaseWallOfForceTempData(LevelTempData *tmp) {} - - LevelTempData *_lvlTempData[29]; - const int _numFlyingObjects; - uint32 _flyingObjectStructSize; - void *_flyingObjectsPtr; - - // sound - virtual bool snd_processEnvironmentalSoundEffect(int soundId, int block); - virtual void snd_stopSpeech(bool) {} - virtual int snd_updateCharacterSpeech() { return 0; } - virtual void stopPortraitSpeechAnim() {} - virtual void setupOpcodeTable() {} - virtual void snd_playVoiceFile(int) {} - - int _environmentSfx; - int _environmentSfxVol; - int _envSfxDistThreshold; - - uint32 _activeVoiceFileTotalTime; - - // unused - void setWalkspeed(uint8) {} - void removeHandItem() {} - bool lineIsPassable(int, int) { return false; } -}; - -} // End of namespace Kyra - -#endif // ENABLE_EOB || ENABLE_LOL - -#endif \ No newline at end of file diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp index 21bb10a1de..e3428fb3c7 100644 --- a/engines/kyra/magic_eob.cpp +++ b/engines/kyra/magic_eob.cpp @@ -158,7 +158,7 @@ void EobCoreEngine::useWand(int charIndex, int weaponSlot) { uint16 bl2 = calcNewBlockPosition(bl1, _currentDirection); snd_playSoundEffect(98); sparkEffectOffensive(); - + if ((_wllWallFlags[_levelBlockProperties[bl2].walls[_currentDirection ^ 2]] & 4) && !(_levelBlockProperties[bl2].flags & 7) && (_levelBlockProperties[bl1].flags & 7)) { for (int i = 0; i < 30; i++) { if (_monsters[i].block != bl1) @@ -574,9 +574,9 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try if (trySavingThrow(m, 0, p->level, mod, 6)) return false; - + int para = 0; - + switch (type) { case 0: case 1: @@ -631,7 +631,7 @@ bool EobCoreEngine::turnUndeadHit(EobMonsterInPlay *m, int hitChance, int caster m->mode = 0; m->flags |= 8; m->spellStatusLeft = 40; - m->dir = (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1; + m->dir = (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1; } return true; @@ -647,7 +647,7 @@ void EobCoreEngine::causeWounds(int dcTimes, int dcPips, int dcOffs) { if (d != -1) { if (!characterAttackHitTest(_openBookChar, d, 0, 1)) return; - + if (dcTimes == -1) { dcOffs = _monsters[d].hitPointsMax - rollDice(1, 4); dcTimes = dcPips = 0; @@ -802,7 +802,7 @@ void EobCoreEngine::spellCallback_start_burningHands() { drawBlockObject(i & 1, 0, _firebeamShapes[(5 - i) >> 1], bX[i], bY[i], 0); _screen->updateScreen(); delay(2 * _tickLength); - + int cl = getMageLevel(_openBookChar); int bl = calcNewBlockPosition(_currentBlock, _currentDirection); @@ -915,7 +915,7 @@ void EobCoreEngine::spellCallback_start_holdPerson() { bool EobCoreEngine::spellCallback_end_holdPerson(void *obj) { EobFlyingObject *fo = (EobFlyingObject*)obj; bool res = false; - + if (_flags.gameID == GI_EOB2 && fo->curBlock == _currentBlock) { // party hit int numChar = rollDice(1, 4, 0); @@ -1011,7 +1011,7 @@ void EobCoreEngine::spellCallback_start_removeCurse() { void EobCoreEngine::spellCallback_start_coneOfCold() { const int8 *dirTables[] = { _coneOfColdDest1, _coneOfColdDest2, _coneOfColdDest3, _coneOfColdDest4 }; - + int cl = getMageLevel(_openBookChar); _screen->setCurPage(2); @@ -1022,11 +1022,11 @@ void EobCoreEngine::spellCallback_start_coneOfCold() { disableSysTimer(2); _screen->drawVortex(150, 50, 10, 1, 100, _coneOfColdGfxTbl, _coneOfColdGfxTblSize); enableSysTimer(2); - + const int8 *tbl = dirTables[_currentDirection]; _preventMonsterFlash = true; - for (int i = 0; i < 7; i++) { + for (int i = 0; i < 7; i++) { for (const int16 *m = findBlockMonsters((_currentBlock + tbl[i]) & 0x3ff, 4, _currentDirection, 1, 1); *m != -1; m++) calcAndInflictMonsterDamage(&_monsters[*m], cl, 4, cl, 0x41, 5, 0); } @@ -1265,12 +1265,12 @@ void EobCoreEngine::spellCallback_start_turnUndead() { uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection); if (!(_levelBlockProperties[bl].flags & 7)) return; - + int cl = _openBookCasterLevel ? _openBookCasterLevel : getClericPaladinLevel(_openBookChar); int r = rollDice(1, 20); bool hit = false; - for (const int16 *m = findBlockMonsters(bl, 4, 4, 1, 1); *m != -1; m++) { + for (const int16 *m = findBlockMonsters(bl, 4, 4, 1, 1); *m != -1; m++) { if ((_monsterProps[_monsters[*m].type].typeFlags & 4) && !(_monsters[*m].flags & 0x10)) { _preventMonsterFlash = true; _monsters[*m].flags |= 0x10; @@ -1333,7 +1333,7 @@ bool EobCoreEngine::spellCallback_end_monster_disintegrate(void *obj) { EobFlyingObject *fo = (EobFlyingObject*)obj; if (fo->curBlock != _currentBlock) return false; - + int d = findFirstCharacterSpellTarget(); if (d != -1) { if (!charDeathSavingThrow(d, 1)) { @@ -1363,7 +1363,7 @@ bool EobCoreEngine::spellCallback_end_monster_fleshToStone(void *obj) { EobFlyingObject *fo = (EobFlyingObject*)obj; if (fo->curBlock != _currentBlock) return false; - + int d = findFirstCharacterSpellTarget(); while (d != -1) { if (!charDeathSavingThrow(d, 2)) { @@ -1373,7 +1373,7 @@ bool EobCoreEngine::spellCallback_end_monster_fleshToStone(void *obj) { d = findNextCharacterSpellTarget(d); } } - + return true; } diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index 6eed6daae4..23aee52465 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -74,14 +74,14 @@ MODULE_OBJS := \ wsamovie.o KYRARPG_COMMON_OBJ = \ - gui_eob.o \ - loleobbase.o \ - saveload_eob.o \ - scene_eob.o \ - sprites_eob.o \ - staticres_eob.o \ - text_eob.o \ - timer_eob.o + gui_rpg.o \ + kyra_rpg.o \ + saveload_rpg.o \ + scene_rpg.o \ + sprites_rpg.o \ + staticres_rpg.o \ + text_rpg.o \ + timer_rpg.o ifdef ENABLE_LOL MODULE_OBJS += \ @@ -111,12 +111,18 @@ MODULE_OBJS += \ eobcommon.o \ eob1.o \ eob2.o \ + gui_eob.o \ items_eob.o \ magic_eob.o \ + saveload_eob.o \ + scene_eob.o \ screen_eob.o \ script_eob.o \ sequences_eob1.o \ - sequences_eob2.o + sequences_eob2.o \ + sprites_eob.o \ + staticres_eob.o \ + timer_eob.o endif # This module can be built as a plugin diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp index ec89fca5e2..091b3201bd 100644 --- a/engines/kyra/saveload_eob.cpp +++ b/engines/kyra/saveload_eob.cpp @@ -20,9 +20,8 @@ * */ -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) +#ifdef ENABLE_EOB -#include "kyra/eobcommon.h" #include "kyra/resource.h" #include "kyra/script_eob.h" @@ -32,99 +31,6 @@ namespace Kyra { -void LolEobBaseEngine::generateTempData() { - int l = _currentLevel - 1; - if (_lvlTempData[l]) { - delete[] _lvlTempData[l]->wallsXorData; - delete[] _lvlTempData[l]->flags; - releaseMonsterTempData(_lvlTempData[l]); - releaseFlyingObjectTempData(_lvlTempData[l]); - releaseWallOfForceTempData(_lvlTempData[l]); - delete _lvlTempData[l]; - } - - _lvlTempData[l] = new LevelTempData; - - _lvlTempData[l]->wallsXorData = new uint8[4096]; - _lvlTempData[l]->flags = new uint16[1024]; - - const uint8 *p = getBlockFileData(_currentLevel); - uint16 len = READ_LE_UINT16(p + 4); - p += 6; - - memset(_lvlTempData[l]->wallsXorData, 0, 4096); - memset(_lvlTempData[l]->flags, 0, 1024 * sizeof(uint16)); - uint8 *d = _lvlTempData[l]->wallsXorData; - uint16 *df = _lvlTempData[l]->flags; - - for (int i = 0; i < 1024; i++) { - for (int ii = 0; ii < 4; ii++) - *d++ = p[i * len + ii] ^ _levelBlockProperties[i].walls[ii]; - *df++ = _levelBlockProperties[i].flags; - } - - _lvlTempData[l]->monsters = generateMonsterTempData(_lvlTempData[l]); - _lvlTempData[l]->flyingObjects = generateFlyingObjectTempData(_lvlTempData[l]); - _lvlTempData[l]->wallsOfForce = generateWallOfForceTempData(_lvlTempData[l]); - - _hasTempDataFlags |= (1 << l); -} - -void LolEobBaseEngine::restoreBlockTempData(int levelIndex) { - int l = levelIndex - 1; - const uint8 *p = getBlockFileData(levelIndex); - uint16 len = READ_LE_UINT16(p + 4); - p += 6; - - memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty)); - - uint8 *t = _lvlTempData[l]->wallsXorData; - uint16 *t2 = _lvlTempData[l]->flags; - - for (int i = 0; i < 1024; i++) { - for (int ii = 0; ii < 4; ii++) - _levelBlockProperties[i].walls[ii] = p[i * len + ii] ^ *t++; - _levelBlockProperties[i].flags = *t2++; - } - - restoreMonsterTempData(_lvlTempData[l]); - restoreFlyingObjectTempData(_lvlTempData[l]); - restoreWallOfForceTempData(_lvlTempData[l]); -} - -void LolEobBaseEngine::releaseTempData() { - for (int i = 0; i < 29; i++) { - if (_lvlTempData[i]) { - delete[] _lvlTempData[i]->wallsXorData; - delete[] _lvlTempData[i]->flags; - releaseMonsterTempData(_lvlTempData[i]); - releaseFlyingObjectTempData(_lvlTempData[i]); - releaseWallOfForceTempData(_lvlTempData[i]); - delete _lvlTempData[i]; - _lvlTempData[i] = 0; - } - } -} - -void *LolEobBaseEngine::generateFlyingObjectTempData(LevelTempData *tmp) { - assert(_flyingObjectStructSize == sizeof(EobFlyingObject)); - EobFlyingObject *f = new EobFlyingObject[_numFlyingObjects]; - memcpy(f, _flyingObjectsPtr, sizeof(EobFlyingObject) * _numFlyingObjects); - return f; -} - -void LolEobBaseEngine::restoreFlyingObjectTempData(LevelTempData *tmp) { - assert(_flyingObjectStructSize == sizeof(EobFlyingObject)); - memcpy(_flyingObjectsPtr, tmp->flyingObjects, sizeof(EobFlyingObject) * _numFlyingObjects); -} - -void LolEobBaseEngine::releaseFlyingObjectTempData(LevelTempData *tmp) { - EobFlyingObject *p = (EobFlyingObject*)tmp->flyingObjects; - delete[] p; -} - -#ifdef ENABLE_EOB - Common::Error EobCoreEngine::loadGameState(int slot) { const char *fileName = 0; @@ -221,7 +127,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) { _itemInHand = in.readSint16BE(); _hasTempDataFlags = in.readUint32BE(); _partyEffectFlags = in.readUint32BE(); - + _updateFlags = in.readUint16BE(); _compassDirection = in.readUint16BE(); _currentControlMode = in.readUint16BE(); @@ -294,7 +200,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) { EobFlyingObject *lf = new EobFlyingObject[_numFlyingObjects]; l->flyingObjects = lf; WallOfForce *lw = new WallOfForce[5]; - l->wallsOfForce = lw; + l->wallsOfForce = lw; in.read(l->wallsXorData, 4096); for (int ii = 0; ii < 1024; ii++) @@ -364,7 +270,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) { } _screen->setCurPage(0); - gui_drawPlayField(false); + gui_drawPlayField(false); if (_currentControlMode) _screen->copyRegion(176, 0, 0, 0, 144, 168, 0, 5, Screen::CR_NO_P_CHECK); @@ -474,7 +380,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName, out->writeSint16BE(_itemInHand); out->writeUint32BE(_hasTempDataFlags); out->writeUint32BE(_partyEffectFlags); - + out->writeUint16BE(_updateFlags); out->writeUint16BE(_compassDirection); out->writeUint16BE(_currentControlMode); @@ -529,7 +435,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName, LevelTempData *l = _lvlTempData[i]; if (!l || !(_hasTempDataFlags & (1 << i))) continue; - + out->write(l->wallsXorData, 4096); for (int ii = 0; ii < 1024; ii++) out->writeByte(l->flags[ii] & 0xff); @@ -643,8 +549,6 @@ void EobCoreEngine::releaseWallOfForceTempData(LevelTempData *tmp) { delete[] p; } -#endif // ENABLE_EOB - } // End of namespace Kyra -#endif // ENABLE_EOB || ENABLE_LOL +#endif // ENABLE_EOB diff --git a/engines/kyra/saveload_lol.cpp b/engines/kyra/saveload_lol.cpp index e5977dd915..c7fb107f35 100644 --- a/engines/kyra/saveload_lol.cpp +++ b/engines/kyra/saveload_lol.cpp @@ -479,7 +479,7 @@ Graphics::Surface *LoLEngine::generateSaveThumbnail() const { void LoLEngine::restoreBlockTempData(int levelIndex) { memset(_tempBuffer5120, 0, 5120); - LolEobBaseEngine::restoreBlockTempData(levelIndex); + KyraRpgEngine::restoreBlockTempData(levelIndex); restoreTempDataAdjustMonsterStrength(levelIndex - 1); } diff --git a/engines/kyra/saveload_rpg.cpp b/engines/kyra/saveload_rpg.cpp new file mode 100644 index 0000000000..4553570f46 --- /dev/null +++ b/engines/kyra/saveload_rpg.cpp @@ -0,0 +1,127 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#if defined(ENABLE_EOB) || defined(ENABLE_LOL) + +#include "kyra/resource.h" +#include "kyra/script_eob.h" + +#include "common/system.h" +#include "common/savefile.h" +#include "common/substream.h" + +namespace Kyra { + +void KyraRpgEngine::generateTempData() { + int l = _currentLevel - 1; + if (_lvlTempData[l]) { + delete[] _lvlTempData[l]->wallsXorData; + delete[] _lvlTempData[l]->flags; + releaseMonsterTempData(_lvlTempData[l]); + releaseFlyingObjectTempData(_lvlTempData[l]); + releaseWallOfForceTempData(_lvlTempData[l]); + delete _lvlTempData[l]; + } + + _lvlTempData[l] = new LevelTempData; + + _lvlTempData[l]->wallsXorData = new uint8[4096]; + _lvlTempData[l]->flags = new uint16[1024]; + + const uint8 *p = getBlockFileData(_currentLevel); + uint16 len = READ_LE_UINT16(p + 4); + p += 6; + + memset(_lvlTempData[l]->wallsXorData, 0, 4096); + memset(_lvlTempData[l]->flags, 0, 1024 * sizeof(uint16)); + uint8 *d = _lvlTempData[l]->wallsXorData; + uint16 *df = _lvlTempData[l]->flags; + + for (int i = 0; i < 1024; i++) { + for (int ii = 0; ii < 4; ii++) + *d++ = p[i * len + ii] ^ _levelBlockProperties[i].walls[ii]; + *df++ = _levelBlockProperties[i].flags; + } + + _lvlTempData[l]->monsters = generateMonsterTempData(_lvlTempData[l]); + _lvlTempData[l]->flyingObjects = generateFlyingObjectTempData(_lvlTempData[l]); + _lvlTempData[l]->wallsOfForce = generateWallOfForceTempData(_lvlTempData[l]); + + _hasTempDataFlags |= (1 << l); +} + +void KyraRpgEngine::restoreBlockTempData(int levelIndex) { + int l = levelIndex - 1; + const uint8 *p = getBlockFileData(levelIndex); + uint16 len = READ_LE_UINT16(p + 4); + p += 6; + + memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty)); + + uint8 *t = _lvlTempData[l]->wallsXorData; + uint16 *t2 = _lvlTempData[l]->flags; + + for (int i = 0; i < 1024; i++) { + for (int ii = 0; ii < 4; ii++) + _levelBlockProperties[i].walls[ii] = p[i * len + ii] ^ *t++; + _levelBlockProperties[i].flags = *t2++; + } + + restoreMonsterTempData(_lvlTempData[l]); + restoreFlyingObjectTempData(_lvlTempData[l]); + restoreWallOfForceTempData(_lvlTempData[l]); +} + +void KyraRpgEngine::releaseTempData() { + for (int i = 0; i < 29; i++) { + if (_lvlTempData[i]) { + delete[] _lvlTempData[i]->wallsXorData; + delete[] _lvlTempData[i]->flags; + releaseMonsterTempData(_lvlTempData[i]); + releaseFlyingObjectTempData(_lvlTempData[i]); + releaseWallOfForceTempData(_lvlTempData[i]); + delete _lvlTempData[i]; + _lvlTempData[i] = 0; + } + } +} + +void *KyraRpgEngine::generateFlyingObjectTempData(LevelTempData *tmp) { + assert(_flyingObjectStructSize == sizeof(EobFlyingObject)); + EobFlyingObject *f = new EobFlyingObject[_numFlyingObjects]; + memcpy(f, _flyingObjectsPtr, sizeof(EobFlyingObject) * _numFlyingObjects); + return f; +} + +void KyraRpgEngine::restoreFlyingObjectTempData(LevelTempData *tmp) { + assert(_flyingObjectStructSize == sizeof(EobFlyingObject)); + memcpy(_flyingObjectsPtr, tmp->flyingObjects, sizeof(EobFlyingObject) * _numFlyingObjects); +} + +void KyraRpgEngine::releaseFlyingObjectTempData(LevelTempData *tmp) { + EobFlyingObject *p = (EobFlyingObject*)tmp->flyingObjects; + delete[] p; +} + +} // End of namespace Kyra + +#endif // ENABLE_EOB || ENABLE_LOL diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp index e2a2e794ff..1927df79c1 100644 --- a/engines/kyra/scene_eob.cpp +++ b/engines/kyra/scene_eob.cpp @@ -20,7 +20,7 @@ * */ -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) +#ifdef ENABLE_EOB #include "kyra/eobcommon.h" #include "kyra/resource.h" @@ -30,590 +30,6 @@ #include "common/system.h" -namespace Kyra { - -void LolEobBaseEngine::setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim) { - if (_lvlShapeLeftRight[index << 1] == -1) { - x1 = 0; - x2 = 22; - - int16 y1 = 0; - int16 y2 = 120; - - int m = index * 18; - - for (int i = 0; i < 18; i++) { - uint8 d = _visibleBlocks[i]->walls[_sceneDrawVarDown]; - uint8 a = _wllWallFlags[d]; - - if (a & 8) { - int t = _dscDim2[(m + i) << 1]; - - if (t > x1) { - x1 = t; - if (!(a & 0x10)) - scaleLevelShapesDim(index, y1, y2, -1); - } - - t = _dscDim2[((m + i) << 1) + 1]; - - if (t < x2) { - x2 = t; - if (!(a & 0x10)) - scaleLevelShapesDim(index, y1, y2, -1); - } - } else { - int t = _dscDim1[m + i]; - - if (!_wllVmpMap[d] || t == -40) - continue; - - if (t == -41) { - x1 = 22; - x2 = 0; - break; - } - - if (t > 0 && x2 > t) - x2 = t; - - if (t < 0 && x1 < -t) - x1 = -t; - } - - if (x2 < x1) - break; - } - - x1 += (_sceneXoffset >> 3); - x2 += (_sceneXoffset >> 3); - - - _lvlShapeTop[index] = y1; - _lvlShapeBottom[index] = y2; - _lvlShapeLeftRight[index << 1] = x1; - _lvlShapeLeftRight[(index << 1) + 1] = x2; - } else { - x1 = _lvlShapeLeftRight[index << 1]; - x2 = _lvlShapeLeftRight[(index << 1) + 1]; - } - - drawLevelModifyScreenDim(dim, x1, 0, x2, 15); -} - -void LolEobBaseEngine::scaleLevelShapesDim(int index, int16 &y1, int16 &y2, int dim) { - static const int8 dscY1[] = { 0x1E, 0x18, 0x10, 0x00 }; - static const int8 dscY2[] = { 0x3B, 0x47, 0x56, 0x78 }; - - uint8 a = _dscDimMap[index]; - - if (dim == -1 && a != 3) - a++; - - y1 = dscY1[a]; - y2 = dscY2[a]; - - if (dim == -1) - return; - - const ScreenDim *cDim = screen()->getScreenDim(dim); - - screen()->modifyScreenDim(dim, cDim->sx, y1, cDim->w, y2 - y1); -} - -void LolEobBaseEngine::drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2) { - screen()->modifyScreenDim(dim, x1, y1 << 3, x2 - x1, (y2 - y1) << 3); -} - -void LolEobBaseEngine::generateBlockDrawingBuffer() { - _sceneDrawVarDown = _dscBlockMap[_currentDirection]; - _sceneDrawVarRight = _dscBlockMap[_currentDirection + 4]; - _sceneDrawVarLeft = _dscBlockMap[_currentDirection + 8]; - - /******************************************* - * _visibleBlocks map * - * * - * | | | | | | * - * 00 | 01 | 02 | 03 | 04 | 05 | 06 * - * ____|_____|_____|_____|_____|_____|_____ * - * | | | | | | * - * | 07 | 08 | 09 | 10 | 11 | * - * |_____|_____|_____|_____|_____| * - * | | | | * - * | 12 | 13 | 14 | * - * |_____|_____|_____| * - * | | * - * 15 | 16 | 17 * - * | (P) | * - ********************************************/ - - memset(_blockDrawingBuffer, 0, 660 * sizeof(uint16)); - - _wllProcessFlag = ((_currentBlock >> 5) + (_currentBlock & 0x1f) + _currentDirection) & 1; - - if (_wllProcessFlag) // floor and ceiling - generateVmpTileDataFlipped(0, 15, 1, -330, 22, 15); - else - generateVmpTileData(0, 15, 1, -330, 22, 15); - - assignVisibleBlocks(_currentBlock, _currentDirection); - - uint8 t = _visibleBlocks[0]->walls[_sceneDrawVarRight]; - if (t) - generateVmpTileData(-2, 3, t, 102, 3, 5); - - t = _visibleBlocks[6]->walls[_sceneDrawVarLeft]; - if (t) - generateVmpTileDataFlipped(21, 3, t, 102, 3, 5); - - t = _visibleBlocks[1]->walls[_sceneDrawVarRight]; - uint8 t2 = _visibleBlocks[2]->walls[_sceneDrawVarDown]; - - if (hasWall(t) && !(_wllWallFlags[t2] & 8)) - generateVmpTileData(2, 3, t, 102, 3, 5); - else if (t && (_wllWallFlags[t2] & 8)) - generateVmpTileData(2, 3, t2, 102, 3, 5); - - t = _visibleBlocks[5]->walls[_sceneDrawVarLeft]; - t2 = _visibleBlocks[4]->walls[_sceneDrawVarDown]; - - if (hasWall(t) && !(_wllWallFlags[t2] & 8)) - generateVmpTileDataFlipped(17, 3, t, 102, 3, 5); - else if (t && (_wllWallFlags[t2] & 8)) - generateVmpTileDataFlipped(17, 3, t2, 102, 3, 5); - - t = _visibleBlocks[2]->walls[_sceneDrawVarRight]; - if (t) - generateVmpTileData(8, 3, t, 97, 1, 5); - - t = _visibleBlocks[4]->walls[_sceneDrawVarLeft]; - if (t) - generateVmpTileDataFlipped(13, 3, t, 97, 1, 5); - - t = _visibleBlocks[1]->walls[_sceneDrawVarDown]; - if (hasWall(t)) - generateVmpTileData(-4, 3, t, 129, 6, 5); - - t = _visibleBlocks[5]->walls[_sceneDrawVarDown]; - if (hasWall(t)) - generateVmpTileData(20, 3, t, 129, 6, 5); - - t = _visibleBlocks[2]->walls[_sceneDrawVarDown]; - if (hasWall(t)) - generateVmpTileData(2, 3, t, 129, 6, 5); - - t = _visibleBlocks[4]->walls[_sceneDrawVarDown]; - if (hasWall(t)) - generateVmpTileData(14, 3, t, 129, 6, 5); - - t = _visibleBlocks[3]->walls[_sceneDrawVarDown]; - if (t) - generateVmpTileData(8, 3, t, 129, 6, 5); - - t = _visibleBlocks[7]->walls[_sceneDrawVarRight]; - if (t) - generateVmpTileData(0, 3, t, 117, 2, 6); - - t = _visibleBlocks[11]->walls[_sceneDrawVarLeft]; - if (t) - generateVmpTileDataFlipped(20, 3, t, 117, 2, 6); - - t = _visibleBlocks[8]->walls[_sceneDrawVarRight]; - if (t) - generateVmpTileData(6, 2, t, 81, 2, 8); - - t = _visibleBlocks[10]->walls[_sceneDrawVarLeft]; - if (t) - generateVmpTileDataFlipped(14, 2, t, 81, 2, 8); - - t = _visibleBlocks[8]->walls[_sceneDrawVarDown]; - if (hasWall(t)) - generateVmpTileData(-4, 2, t, 159, 10, 8); - - t = _visibleBlocks[10]->walls[_sceneDrawVarDown]; - if (hasWall(t)) - generateVmpTileData(16, 2, t, 159, 10, 8); - - t = _visibleBlocks[9]->walls[_sceneDrawVarDown]; - if (t) - generateVmpTileData(6, 2, t, 159, 10, 8); - - t = _visibleBlocks[12]->walls[_sceneDrawVarRight]; - if (t) - generateVmpTileData(3, 1, t, 45, 3, 12); - - t = _visibleBlocks[14]->walls[_sceneDrawVarLeft]; - if (t) - generateVmpTileDataFlipped(16, 1, t, 45, 3, 12); - - t = _visibleBlocks[12]->walls[_sceneDrawVarDown]; - if (!(_wllWallFlags[t] & 8)) - generateVmpTileData(-13, 1, t, 239, 16, 12); - - t = _visibleBlocks[14]->walls[_sceneDrawVarDown]; - if (!(_wllWallFlags[t] & 8)) - generateVmpTileData(19, 1, t, 239, 16, 12); - - t = _visibleBlocks[13]->walls[_sceneDrawVarDown]; - if (t) - generateVmpTileData(3, 1, t, 239, 16, 12); - - t = _visibleBlocks[15]->walls[_sceneDrawVarRight]; - t2 = _visibleBlocks[17]->walls[_sceneDrawVarLeft]; - if (t) - generateVmpTileData(0, 0, t, 0, 3, 15); - if (t2) - generateVmpTileDataFlipped(19, 0, t2, 0, 3, 15); -} - -void LolEobBaseEngine::generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) { - if (!_wllVmpMap[vmpMapIndex]) - return; - - uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330]; - - for (int i = 0; i < numBlocksY; i++) { - uint16 *bl = &_blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX]; - for (int ii = 0; ii < numBlocksX; ii++) { - if ((startBlockX + ii >= 0) && (startBlockX + ii < 22) && *vmp) - *bl = *vmp; - bl++; - vmp++; - } - } -} - -void LolEobBaseEngine::generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) { - if (!_wllVmpMap[vmpMapIndex]) - return; - - uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330]; - - for (int i = 0; i < numBlocksY; i++) { - for (int ii = 0; ii < numBlocksX; ii++) { - if ((startBlockX + ii) < 0 || (startBlockX + ii) > 21) - continue; - - uint16 v = vmp[i * numBlocksX + (numBlocksX - 1 - ii)]; - if (!v) - continue; - - if (v & 0x4000) - v -= 0x4000; - else - v |= 0x4000; - - _blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX + ii] = v; - } - } -} - -bool LolEobBaseEngine::hasWall(int index) { - if (!index || (_wllWallFlags[index] & 8)) - return false; - return true; -} - -void LolEobBaseEngine::assignVisibleBlocks(int block, int direction) { - for (int i = 0; i < 18; i++) { - uint16 t = (block + _dscBlockIndex[direction * 18 + i]) & 0x3ff; - _visibleBlockIndex[i] = t; - - _visibleBlocks[i] = &_levelBlockProperties[t]; - _lvlShapeLeftRight[i] = _lvlShapeLeftRight[18 + i] = -1; - } -} - -bool LolEobBaseEngine::checkSceneUpdateNeed(int block) { - if (_sceneUpdateRequired) - return true; - - for (int i = 0; i < 15; i++) { - if (_visibleBlockIndex[i] == block) { - _sceneUpdateRequired = true; - return true; - } - } - - if (_currentBlock == block){ - _sceneUpdateRequired = true; - return true; - } - - return false; -} - -void LolEobBaseEngine::drawVcnBlocks() { - uint8 *d = _sceneWindowBuffer; - uint16 *bdb = _blockDrawingBuffer; - - for (int y = 0; y < 15; y++) { - for (int x = 0; x < 22; x++) { - bool horizontalFlip = false; - int remainder = 0; - - uint16 vcnOffset = *bdb++; - int wllVcnOffset = 0; - int wllVcnRmdOffset = 0; - - if (vcnOffset & 0x8000) { - // this renders a wall block over the transparent pixels of a floor/ceiling block - remainder = vcnOffset - 0x8000; - vcnOffset = 0; - wllVcnRmdOffset = _wllVcnOffset; - } - - if (vcnOffset & 0x4000) { - horizontalFlip = true; - vcnOffset &= 0x3fff; - } - - uint8 *src = 0; - if (vcnOffset) { - src = &_vcnBlocks[vcnOffset << 5]; - wllVcnOffset = _wllVcnOffset; - } else { - // floor/ceiling blocks - vcnOffset = bdb[329]; - if (vcnOffset & 0x4000) { - horizontalFlip = true; - vcnOffset &= 0x3fff; - } - - src = (_vcfBlocks ? _vcfBlocks : _vcnBlocks) + (vcnOffset << 5); - } - - uint8 shift = _vcnShift ? _vcnShift[vcnOffset] : _blockBrightness; - - if (horizontalFlip) { - for (int blockY = 0; blockY < 8; blockY++) { - src += 3; - for (int blockX = 0; blockX < 4; blockX++) { - uint8 t = *src--; - *d++ = _vcnExpTable[((t & 0x0f) + wllVcnOffset) | shift]; - *d++ = _vcnExpTable[((t >> 4) + wllVcnOffset) | shift]; - } - src += 5; - d += 168; - } - } else { - for (int blockY = 0; blockY < 8; blockY++) { - for (int blockX = 0; blockX < 4; blockX++) { - uint8 t = *src++; - *d++ = _vcnExpTable[((t >> 4) + wllVcnOffset) | shift]; - *d++ = _vcnExpTable[((t & 0x0f) + wllVcnOffset) | shift]; - } - d += 168; - } - } - d -= 1400; - - if (remainder) { - d -= 8; - horizontalFlip = false; - - if (remainder & 0x4000) { - remainder &= 0x3fff; - horizontalFlip = true; - } - - shift = _vcnShift ? _vcnShift[remainder] : _blockBrightness; - src = &_vcnBlocks[remainder << 5]; - - if (horizontalFlip) { - for (int blockY = 0; blockY < 8; blockY++) { - src += 3; - for (int blockX = 0; blockX < 4; blockX++) { - uint8 t = *src--; - uint8 h = _vcnExpTable[((t & 0x0f) + wllVcnRmdOffset) | shift]; - uint8 l = _vcnExpTable[((t >> 4) + wllVcnRmdOffset) | shift]; - if (h) - *d = h; - d++; - if (l) - *d = l; - d++; - } - src += 5; - d += 168; - } - } else { - for (int blockY = 0; blockY < 8; blockY++) { - for (int blockX = 0; blockX < 4; blockX++) { - uint8 t = *src++; - uint8 h = _vcnExpTable[((t >> 4) + wllVcnRmdOffset) | shift]; - uint8 l = _vcnExpTable[((t & 0x0f) + wllVcnRmdOffset) | shift]; - if (h) - *d = h; - d++; - if (l) - *d = l; - d++; - } - d += 168; - } - } - d -= 1400; - } - } - d += 1232; - } - - screen()->copyBlockToPage(_sceneDrawPage1, _sceneXoffset, 0, 176, 120, _sceneWindowBuffer); -} - -uint16 LolEobBaseEngine::calcNewBlockPosition(uint16 curBlock, uint16 direction) { - static const int16 blockPosTable[] = { -32, 1, 32, -1 }; - return (curBlock + blockPosTable[direction]) & 0x3ff; -} - -int LolEobBaseEngine::clickedWallShape(uint16 block, uint16 direction) { - uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]]; - if (!clickedShape(v)) - return 0; - - snd_stopSpeech(true); - runLevelScript(block, 0x40); - - return 1; -} - -int LolEobBaseEngine::clickedLeverOn(uint16 block, uint16 direction) { - uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]]; - if (!clickedShape(v)) - return 0; - - _levelBlockProperties[block].walls[direction]++; - _sceneUpdateRequired = true; - - if (_flags.gameID == GI_LOL) - snd_playSoundEffect(30, -1); - - runLevelScript(block, _clickedSpecialFlag); - - return 1; -} - -int LolEobBaseEngine::clickedLeverOff(uint16 block, uint16 direction) { - uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]]; - if (!clickedShape(v)) - return 0; - - _levelBlockProperties[block].walls[direction]--; - _sceneUpdateRequired = true; - - if (_flags.gameID == GI_LOL) - snd_playSoundEffect(29, -1); - - runLevelScript(block, _clickedSpecialFlag); - return 1; -} - -int LolEobBaseEngine::clickedWallOnlyScript(uint16 block) { - runLevelScript(block, _clickedSpecialFlag); - return 1; -} - -void LolEobBaseEngine::processDoorSwitch(uint16 block, int openClose) { - if (block == _currentBlock) - return; - - if ((_flags.gameID == GI_LOL && (_levelBlockProperties[block].assignedObjects & 0x8000)) || (_flags.gameID != GI_LOL && (_levelBlockProperties[block].flags & 7))) - return; - - if (openClose == 0) { - for (int i = 0; i < 3; i++) { - if (_openDoorState[i].block != block) - continue; - openClose = -_openDoorState[i].state; - break; - } - } - - if (openClose == 0) { - openClose = (_wllWallFlags[_levelBlockProperties[block].walls[_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8 ? 0 : 1]] & 1) ? 1 : -1; - if (_flags.gameID != GI_LOL) - openClose *= -1; - } - - openCloseDoor(block, openClose); -} - -void LolEobBaseEngine::openCloseDoor(int block, int openClose) { - int s1 = -1; - int s2 = -1; - - int c = (_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8) ? 0 : 1; - int v = _levelBlockProperties[block].walls[c]; - int flg = (openClose == 1) ? 0x10 : (openClose == -1 ? 0x20 : 0); - - if (_wllWallFlags[v] & flg) - return; - - for (int i = 0; i < 3; i++) { - if (_openDoorState[i].block == block) { - s1 = i; - break; - } else if (_openDoorState[i].block == 0 && s2 == -1) { - s2 = i; - } - } - - if (s1 != -1 || s2 != -1) { - if (s1 == -1) - s1 = s2; - - _openDoorState[s1].block = block; - _openDoorState[s1].state = openClose; - _openDoorState[s1].wall = c; - - flg = (-openClose == 1) ? 0x10 : (-openClose == -1 ? 0x20 : 0); - - if (_wllWallFlags[v] & flg) { - _levelBlockProperties[block].walls[c] += openClose; - _levelBlockProperties[block].walls[c ^ 2] += openClose; - - int snd = (openClose == -1) ? 4 : 3; - if (_flags.gameID == GI_LOL) { - snd_processEnvironmentalSoundEffect(snd + 28, _currentBlock); - if (!checkSceneUpdateNeed(block)) - updateEnvironmentalSfx(0); - } else { - updateEnvironmentalSfx(snd); - } - } - - enableTimer(_flags.gameID == GI_LOL ? 0 : 4); - - } else { - while (!(flg & _wllWallFlags[v])) - v += openClose; - - _levelBlockProperties[block].walls[c] = _levelBlockProperties[block].walls[c ^ 2] = v; - checkSceneUpdateNeed(block); - } -} - -void LolEobBaseEngine::completeDoorOperations() { - for (int i = 0; i < 3; i++) { - if (!_openDoorState[i].block) - continue; - - uint16 b = _openDoorState[i].block; - - do { - _levelBlockProperties[b].walls[_openDoorState[i].wall] += _openDoorState[i].state; - _levelBlockProperties[b].walls[_openDoorState[i].wall ^ 2] += _openDoorState[i].state; - } while (!(_wllWallFlags[_levelBlockProperties[b].walls[_openDoorState[i].wall]] & 0x30)); - - _openDoorState[i].block = 0; - } -} - -} // End of namespace Kyra - -#endif // ENABLE_EOB || ENABLE_LOL -#ifdef ENABLE_EOB namespace Kyra { @@ -625,7 +41,7 @@ void EobCoreEngine::loadLevel(int level, int sub) { Common::String file; Common::SeekableReadStream *s = 0; static const char *suffix[] = { "INF", "DRO", "ELO", 0 }; - + for (const char *const *sf = suffix; *sf && !s; sf++) { file = Common::String::format("LEVEL%d.%s", level, *sf); s = _res->createReadStream(file); @@ -649,11 +65,11 @@ void EobCoreEngine::loadLevel(int level, int sub) { } Common::String gfxFile; - // Work around for issue with corrupt (incomplete) monster property data + // Work around for issue with corrupt (incomplete) monster property data // when loading a savegame saved in a sub level for (int i = 0; i <= sub; i++) gfxFile = initLevelData(i); - + const uint8 *data = _screen->getCPagePtr(5); const uint8 *pos = data + READ_LE_UINT16(data); uint16 len = READ_LE_UINT16(pos); @@ -744,7 +160,7 @@ Common::String EobCoreEngine::initLevelData(int sub){ _screen->setShapeFadeMode(0, false); _screen->setShapeFadeMode(1, false); } - + _screen->loadPalette(tmpStr.c_str(), _screen->getPalette(0)); Palette backupPal(256); @@ -850,7 +266,7 @@ void EobCoreEngine::addLevelItems() { void EobCoreEngine::loadVcnData(const char *file, const char*/*nextFile*/) { if (file) strcpy(_lastBlockDataFile, file); - + _screen->loadBitmap(Common::String::format("%s.VCN", _lastBlockDataFile).c_str(), 3, 3, 0); const uint8 *v = _screen->getCPagePtr(2); uint32 tlen = READ_LE_UINT16(v) << 5; @@ -1212,7 +628,7 @@ int EobCoreEngine::clickedDoorSwitch(uint16 block, uint16 direction) { else x1 += ((v - _dscDoorXE[v]) * 9); } - + if (!posWithinRect(_mouseX, _mouseY, x1, y1, x1 + (d->shp[2] << 3) + 8, y1 + d->shp[1] + 8) && (_clickedSpecialFlag == 0x40)) return clickedDoorNoPry(block, direction); diff --git a/engines/kyra/scene_rpg.cpp b/engines/kyra/scene_rpg.cpp new file mode 100644 index 0000000000..07a7a879b1 --- /dev/null +++ b/engines/kyra/scene_rpg.cpp @@ -0,0 +1,614 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#if defined(ENABLE_EOB) || defined(ENABLE_LOL) + +#include "kyra/kyra_rpg.h" +#include "kyra/resource.h" +#include "kyra/timer.h" +#include "kyra/sound.h" + +#include "common/system.h" + +namespace Kyra { + +void KyraRpgEngine::setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim) { + if (_lvlShapeLeftRight[index << 1] == -1) { + x1 = 0; + x2 = 22; + + int16 y1 = 0; + int16 y2 = 120; + + int m = index * 18; + + for (int i = 0; i < 18; i++) { + uint8 d = _visibleBlocks[i]->walls[_sceneDrawVarDown]; + uint8 a = _wllWallFlags[d]; + + if (a & 8) { + int t = _dscDim2[(m + i) << 1]; + + if (t > x1) { + x1 = t; + if (!(a & 0x10)) + scaleLevelShapesDim(index, y1, y2, -1); + } + + t = _dscDim2[((m + i) << 1) + 1]; + + if (t < x2) { + x2 = t; + if (!(a & 0x10)) + scaleLevelShapesDim(index, y1, y2, -1); + } + } else { + int t = _dscDim1[m + i]; + + if (!_wllVmpMap[d] || t == -40) + continue; + + if (t == -41) { + x1 = 22; + x2 = 0; + break; + } + + if (t > 0 && x2 > t) + x2 = t; + + if (t < 0 && x1 < -t) + x1 = -t; + } + + if (x2 < x1) + break; + } + + x1 += (_sceneXoffset >> 3); + x2 += (_sceneXoffset >> 3); + + + _lvlShapeTop[index] = y1; + _lvlShapeBottom[index] = y2; + _lvlShapeLeftRight[index << 1] = x1; + _lvlShapeLeftRight[(index << 1) + 1] = x2; + } else { + x1 = _lvlShapeLeftRight[index << 1]; + x2 = _lvlShapeLeftRight[(index << 1) + 1]; + } + + drawLevelModifyScreenDim(dim, x1, 0, x2, 15); +} + +void KyraRpgEngine::scaleLevelShapesDim(int index, int16 &y1, int16 &y2, int dim) { + static const int8 dscY1[] = { 0x1E, 0x18, 0x10, 0x00 }; + static const int8 dscY2[] = { 0x3B, 0x47, 0x56, 0x78 }; + + uint8 a = _dscDimMap[index]; + + if (dim == -1 && a != 3) + a++; + + y1 = dscY1[a]; + y2 = dscY2[a]; + + if (dim == -1) + return; + + const ScreenDim *cDim = screen()->getScreenDim(dim); + + screen()->modifyScreenDim(dim, cDim->sx, y1, cDim->w, y2 - y1); +} + +void KyraRpgEngine::drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2) { + screen()->modifyScreenDim(dim, x1, y1 << 3, x2 - x1, (y2 - y1) << 3); +} + +void KyraRpgEngine::generateBlockDrawingBuffer() { + _sceneDrawVarDown = _dscBlockMap[_currentDirection]; + _sceneDrawVarRight = _dscBlockMap[_currentDirection + 4]; + _sceneDrawVarLeft = _dscBlockMap[_currentDirection + 8]; + + /******************************************* + * _visibleBlocks map * + * * + * | | | | | | * + * 00 | 01 | 02 | 03 | 04 | 05 | 06 * + * ____|_____|_____|_____|_____|_____|_____ * + * | | | | | | * + * | 07 | 08 | 09 | 10 | 11 | * + * |_____|_____|_____|_____|_____| * + * | | | | * + * | 12 | 13 | 14 | * + * |_____|_____|_____| * + * | | * + * 15 | 16 | 17 * + * | (P) | * + ********************************************/ + + memset(_blockDrawingBuffer, 0, 660 * sizeof(uint16)); + + _wllProcessFlag = ((_currentBlock >> 5) + (_currentBlock & 0x1f) + _currentDirection) & 1; + + if (_wllProcessFlag) // floor and ceiling + generateVmpTileDataFlipped(0, 15, 1, -330, 22, 15); + else + generateVmpTileData(0, 15, 1, -330, 22, 15); + + assignVisibleBlocks(_currentBlock, _currentDirection); + + uint8 t = _visibleBlocks[0]->walls[_sceneDrawVarRight]; + if (t) + generateVmpTileData(-2, 3, t, 102, 3, 5); + + t = _visibleBlocks[6]->walls[_sceneDrawVarLeft]; + if (t) + generateVmpTileDataFlipped(21, 3, t, 102, 3, 5); + + t = _visibleBlocks[1]->walls[_sceneDrawVarRight]; + uint8 t2 = _visibleBlocks[2]->walls[_sceneDrawVarDown]; + + if (hasWall(t) && !(_wllWallFlags[t2] & 8)) + generateVmpTileData(2, 3, t, 102, 3, 5); + else if (t && (_wllWallFlags[t2] & 8)) + generateVmpTileData(2, 3, t2, 102, 3, 5); + + t = _visibleBlocks[5]->walls[_sceneDrawVarLeft]; + t2 = _visibleBlocks[4]->walls[_sceneDrawVarDown]; + + if (hasWall(t) && !(_wllWallFlags[t2] & 8)) + generateVmpTileDataFlipped(17, 3, t, 102, 3, 5); + else if (t && (_wllWallFlags[t2] & 8)) + generateVmpTileDataFlipped(17, 3, t2, 102, 3, 5); + + t = _visibleBlocks[2]->walls[_sceneDrawVarRight]; + if (t) + generateVmpTileData(8, 3, t, 97, 1, 5); + + t = _visibleBlocks[4]->walls[_sceneDrawVarLeft]; + if (t) + generateVmpTileDataFlipped(13, 3, t, 97, 1, 5); + + t = _visibleBlocks[1]->walls[_sceneDrawVarDown]; + if (hasWall(t)) + generateVmpTileData(-4, 3, t, 129, 6, 5); + + t = _visibleBlocks[5]->walls[_sceneDrawVarDown]; + if (hasWall(t)) + generateVmpTileData(20, 3, t, 129, 6, 5); + + t = _visibleBlocks[2]->walls[_sceneDrawVarDown]; + if (hasWall(t)) + generateVmpTileData(2, 3, t, 129, 6, 5); + + t = _visibleBlocks[4]->walls[_sceneDrawVarDown]; + if (hasWall(t)) + generateVmpTileData(14, 3, t, 129, 6, 5); + + t = _visibleBlocks[3]->walls[_sceneDrawVarDown]; + if (t) + generateVmpTileData(8, 3, t, 129, 6, 5); + + t = _visibleBlocks[7]->walls[_sceneDrawVarRight]; + if (t) + generateVmpTileData(0, 3, t, 117, 2, 6); + + t = _visibleBlocks[11]->walls[_sceneDrawVarLeft]; + if (t) + generateVmpTileDataFlipped(20, 3, t, 117, 2, 6); + + t = _visibleBlocks[8]->walls[_sceneDrawVarRight]; + if (t) + generateVmpTileData(6, 2, t, 81, 2, 8); + + t = _visibleBlocks[10]->walls[_sceneDrawVarLeft]; + if (t) + generateVmpTileDataFlipped(14, 2, t, 81, 2, 8); + + t = _visibleBlocks[8]->walls[_sceneDrawVarDown]; + if (hasWall(t)) + generateVmpTileData(-4, 2, t, 159, 10, 8); + + t = _visibleBlocks[10]->walls[_sceneDrawVarDown]; + if (hasWall(t)) + generateVmpTileData(16, 2, t, 159, 10, 8); + + t = _visibleBlocks[9]->walls[_sceneDrawVarDown]; + if (t) + generateVmpTileData(6, 2, t, 159, 10, 8); + + t = _visibleBlocks[12]->walls[_sceneDrawVarRight]; + if (t) + generateVmpTileData(3, 1, t, 45, 3, 12); + + t = _visibleBlocks[14]->walls[_sceneDrawVarLeft]; + if (t) + generateVmpTileDataFlipped(16, 1, t, 45, 3, 12); + + t = _visibleBlocks[12]->walls[_sceneDrawVarDown]; + if (!(_wllWallFlags[t] & 8)) + generateVmpTileData(-13, 1, t, 239, 16, 12); + + t = _visibleBlocks[14]->walls[_sceneDrawVarDown]; + if (!(_wllWallFlags[t] & 8)) + generateVmpTileData(19, 1, t, 239, 16, 12); + + t = _visibleBlocks[13]->walls[_sceneDrawVarDown]; + if (t) + generateVmpTileData(3, 1, t, 239, 16, 12); + + t = _visibleBlocks[15]->walls[_sceneDrawVarRight]; + t2 = _visibleBlocks[17]->walls[_sceneDrawVarLeft]; + if (t) + generateVmpTileData(0, 0, t, 0, 3, 15); + if (t2) + generateVmpTileDataFlipped(19, 0, t2, 0, 3, 15); +} + +void KyraRpgEngine::generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) { + if (!_wllVmpMap[vmpMapIndex]) + return; + + uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330]; + + for (int i = 0; i < numBlocksY; i++) { + uint16 *bl = &_blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX]; + for (int ii = 0; ii < numBlocksX; ii++) { + if ((startBlockX + ii >= 0) && (startBlockX + ii < 22) && *vmp) + *bl = *vmp; + bl++; + vmp++; + } + } +} + +void KyraRpgEngine::generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) { + if (!_wllVmpMap[vmpMapIndex]) + return; + + uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330]; + + for (int i = 0; i < numBlocksY; i++) { + for (int ii = 0; ii < numBlocksX; ii++) { + if ((startBlockX + ii) < 0 || (startBlockX + ii) > 21) + continue; + + uint16 v = vmp[i * numBlocksX + (numBlocksX - 1 - ii)]; + if (!v) + continue; + + if (v & 0x4000) + v -= 0x4000; + else + v |= 0x4000; + + _blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX + ii] = v; + } + } +} + +bool KyraRpgEngine::hasWall(int index) { + if (!index || (_wllWallFlags[index] & 8)) + return false; + return true; +} + +void KyraRpgEngine::assignVisibleBlocks(int block, int direction) { + for (int i = 0; i < 18; i++) { + uint16 t = (block + _dscBlockIndex[direction * 18 + i]) & 0x3ff; + _visibleBlockIndex[i] = t; + + _visibleBlocks[i] = &_levelBlockProperties[t]; + _lvlShapeLeftRight[i] = _lvlShapeLeftRight[18 + i] = -1; + } +} + +bool KyraRpgEngine::checkSceneUpdateNeed(int block) { + if (_sceneUpdateRequired) + return true; + + for (int i = 0; i < 15; i++) { + if (_visibleBlockIndex[i] == block) { + _sceneUpdateRequired = true; + return true; + } + } + + if (_currentBlock == block){ + _sceneUpdateRequired = true; + return true; + } + + return false; +} + +void KyraRpgEngine::drawVcnBlocks() { + uint8 *d = _sceneWindowBuffer; + uint16 *bdb = _blockDrawingBuffer; + + for (int y = 0; y < 15; y++) { + for (int x = 0; x < 22; x++) { + bool horizontalFlip = false; + int remainder = 0; + + uint16 vcnOffset = *bdb++; + int wllVcnOffset = 0; + int wllVcnRmdOffset = 0; + + if (vcnOffset & 0x8000) { + // this renders a wall block over the transparent pixels of a floor/ceiling block + remainder = vcnOffset - 0x8000; + vcnOffset = 0; + wllVcnRmdOffset = _wllVcnOffset; + } + + if (vcnOffset & 0x4000) { + horizontalFlip = true; + vcnOffset &= 0x3fff; + } + + uint8 *src = 0; + if (vcnOffset) { + src = &_vcnBlocks[vcnOffset << 5]; + wllVcnOffset = _wllVcnOffset; + } else { + // floor/ceiling blocks + vcnOffset = bdb[329]; + if (vcnOffset & 0x4000) { + horizontalFlip = true; + vcnOffset &= 0x3fff; + } + + src = (_vcfBlocks ? _vcfBlocks : _vcnBlocks) + (vcnOffset << 5); + } + + uint8 shift = _vcnShift ? _vcnShift[vcnOffset] : _blockBrightness; + + if (horizontalFlip) { + for (int blockY = 0; blockY < 8; blockY++) { + src += 3; + for (int blockX = 0; blockX < 4; blockX++) { + uint8 t = *src--; + *d++ = _vcnExpTable[((t & 0x0f) + wllVcnOffset) | shift]; + *d++ = _vcnExpTable[((t >> 4) + wllVcnOffset) | shift]; + } + src += 5; + d += 168; + } + } else { + for (int blockY = 0; blockY < 8; blockY++) { + for (int blockX = 0; blockX < 4; blockX++) { + uint8 t = *src++; + *d++ = _vcnExpTable[((t >> 4) + wllVcnOffset) | shift]; + *d++ = _vcnExpTable[((t & 0x0f) + wllVcnOffset) | shift]; + } + d += 168; + } + } + d -= 1400; + + if (remainder) { + d -= 8; + horizontalFlip = false; + + if (remainder & 0x4000) { + remainder &= 0x3fff; + horizontalFlip = true; + } + + shift = _vcnShift ? _vcnShift[remainder] : _blockBrightness; + src = &_vcnBlocks[remainder << 5]; + + if (horizontalFlip) { + for (int blockY = 0; blockY < 8; blockY++) { + src += 3; + for (int blockX = 0; blockX < 4; blockX++) { + uint8 t = *src--; + uint8 h = _vcnExpTable[((t & 0x0f) + wllVcnRmdOffset) | shift]; + uint8 l = _vcnExpTable[((t >> 4) + wllVcnRmdOffset) | shift]; + if (h) + *d = h; + d++; + if (l) + *d = l; + d++; + } + src += 5; + d += 168; + } + } else { + for (int blockY = 0; blockY < 8; blockY++) { + for (int blockX = 0; blockX < 4; blockX++) { + uint8 t = *src++; + uint8 h = _vcnExpTable[((t >> 4) + wllVcnRmdOffset) | shift]; + uint8 l = _vcnExpTable[((t & 0x0f) + wllVcnRmdOffset) | shift]; + if (h) + *d = h; + d++; + if (l) + *d = l; + d++; + } + d += 168; + } + } + d -= 1400; + } + } + d += 1232; + } + + screen()->copyBlockToPage(_sceneDrawPage1, _sceneXoffset, 0, 176, 120, _sceneWindowBuffer); +} + +uint16 KyraRpgEngine::calcNewBlockPosition(uint16 curBlock, uint16 direction) { + static const int16 blockPosTable[] = { -32, 1, 32, -1 }; + return (curBlock + blockPosTable[direction]) & 0x3ff; +} + +int KyraRpgEngine::clickedWallShape(uint16 block, uint16 direction) { + uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]]; + if (!clickedShape(v)) + return 0; + + snd_stopSpeech(true); + runLevelScript(block, 0x40); + + return 1; +} + +int KyraRpgEngine::clickedLeverOn(uint16 block, uint16 direction) { + uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]]; + if (!clickedShape(v)) + return 0; + + _levelBlockProperties[block].walls[direction]++; + _sceneUpdateRequired = true; + + if (_flags.gameID == GI_LOL) + snd_playSoundEffect(30, -1); + + runLevelScript(block, _clickedSpecialFlag); + + return 1; +} + +int KyraRpgEngine::clickedLeverOff(uint16 block, uint16 direction) { + uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]]; + if (!clickedShape(v)) + return 0; + + _levelBlockProperties[block].walls[direction]--; + _sceneUpdateRequired = true; + + if (_flags.gameID == GI_LOL) + snd_playSoundEffect(29, -1); + + runLevelScript(block, _clickedSpecialFlag); + return 1; +} + +int KyraRpgEngine::clickedWallOnlyScript(uint16 block) { + runLevelScript(block, _clickedSpecialFlag); + return 1; +} + +void KyraRpgEngine::processDoorSwitch(uint16 block, int openClose) { + if (block == _currentBlock) + return; + + if ((_flags.gameID == GI_LOL && (_levelBlockProperties[block].assignedObjects & 0x8000)) || (_flags.gameID != GI_LOL && (_levelBlockProperties[block].flags & 7))) + return; + + if (openClose == 0) { + for (int i = 0; i < 3; i++) { + if (_openDoorState[i].block != block) + continue; + openClose = -_openDoorState[i].state; + break; + } + } + + if (openClose == 0) { + openClose = (_wllWallFlags[_levelBlockProperties[block].walls[_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8 ? 0 : 1]] & 1) ? 1 : -1; + if (_flags.gameID != GI_LOL) + openClose *= -1; + } + + openCloseDoor(block, openClose); +} + +void KyraRpgEngine::openCloseDoor(int block, int openClose) { + int s1 = -1; + int s2 = -1; + + int c = (_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8) ? 0 : 1; + int v = _levelBlockProperties[block].walls[c]; + int flg = (openClose == 1) ? 0x10 : (openClose == -1 ? 0x20 : 0); + + if (_wllWallFlags[v] & flg) + return; + + for (int i = 0; i < 3; i++) { + if (_openDoorState[i].block == block) { + s1 = i; + break; + } else if (_openDoorState[i].block == 0 && s2 == -1) { + s2 = i; + } + } + + if (s1 != -1 || s2 != -1) { + if (s1 == -1) + s1 = s2; + + _openDoorState[s1].block = block; + _openDoorState[s1].state = openClose; + _openDoorState[s1].wall = c; + + flg = (-openClose == 1) ? 0x10 : (-openClose == -1 ? 0x20 : 0); + + if (_wllWallFlags[v] & flg) { + _levelBlockProperties[block].walls[c] += openClose; + _levelBlockProperties[block].walls[c ^ 2] += openClose; + + int snd = (openClose == -1) ? 4 : 3; + if (_flags.gameID == GI_LOL) { + snd_processEnvironmentalSoundEffect(snd + 28, _currentBlock); + if (!checkSceneUpdateNeed(block)) + updateEnvironmentalSfx(0); + } else { + updateEnvironmentalSfx(snd); + } + } + + enableTimer(_flags.gameID == GI_LOL ? 0 : 4); + + } else { + while (!(flg & _wllWallFlags[v])) + v += openClose; + + _levelBlockProperties[block].walls[c] = _levelBlockProperties[block].walls[c ^ 2] = v; + checkSceneUpdateNeed(block); + } +} + +void KyraRpgEngine::completeDoorOperations() { + for (int i = 0; i < 3; i++) { + if (!_openDoorState[i].block) + continue; + + uint16 b = _openDoorState[i].block; + + do { + _levelBlockProperties[b].walls[_openDoorState[i].wall] += _openDoorState[i].state; + _levelBlockProperties[b].walls[_openDoorState[i].wall ^ 2] += _openDoorState[i].state; + } while (!(_wllWallFlags[_levelBlockProperties[b].walls[_openDoorState[i].wall]] & 0x30)); + + _openDoorState[i].block = 0; + } +} + +} // End of namespace Kyra + +#endif // ENABLE_EOB || ENABLE_LOL diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 0b877b7247..ca44a8a771 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -189,7 +189,7 @@ void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int delete s; } } - + if (copyToPage == -1) { return; } else if (copyToPage == 0) { @@ -248,7 +248,7 @@ uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b uint8 *lineEnd = src + (w << 3); do { uint8 val = *src++; - if (!val) { + if (!val) { *dst++ = 0; uint8 *startZeroPos = src; @@ -563,9 +563,9 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, addDirtyRect(rX, rY, rW, rH); while (dH--) { - int16 xpos = (int16) marginLeft; + int16 xpos = (int16) marginLeft; - if (flags & 1) { + if (flags & 1) { for (int i = 0; i < w2; i++) { if (*src++ == 0) { i += (*src - 1); @@ -636,7 +636,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, dstL += 320; dst = dstL; - if (flags & 1) + if (flags & 1) src = src2 + 1; } } @@ -751,7 +751,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS int rY1 = dm->sy; int rX2 = rX1 + (dm->w << 3); int rY2 = rY1 + dm->h - 1; - + int16 gx2 = _gfxX; int16 gy2 = _gfxY; @@ -783,7 +783,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS py = ymax; if (posWithinRect(px, py, rX1, rY1, rX2, rY2)) setPagePixel(0, px, py, ptr6[i]); - } + } } l = 0; @@ -798,7 +798,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS ptr5[i] += 5; ptr3[i] += ptr5[i]; ptr8[i] += ptr7[i]; - + int16 px = ((ptr2[i] >> 6) >> scale) + gx2; int16 py = ((ptr3[i] >> 6) >> scale) + gy2; if (py >= ymax || py < ymin) @@ -808,7 +808,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS if (py > ymax) py = ymax; - + int pxVal1 = 0; if (posWithinRect(px, py, 0, 0, 319, 199)) { pxVal1 = getPagePixel(2, px, py); @@ -833,7 +833,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS } } } - + showMouse(); } diff --git a/engines/kyra/screen_eob.h b/engines/kyra/screen_eob.h index d2d888107a..78361ebaa6 100644 --- a/engines/kyra/screen_eob.h +++ b/engines/kyra/screen_eob.h @@ -100,7 +100,7 @@ private: static const int _screenDimTableCount; ScreenDim **_customDimTable; - int _curDimIndex; + int _curDimIndex; }; } // End of namespace Kyra diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp index 4123e89a14..c59c66b04f 100644 --- a/engines/kyra/script_eob.cpp +++ b/engines/kyra/script_eob.cpp @@ -737,7 +737,7 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) { debugC(5, kDebugLevelScript, " - check if whole party is invisible - PUSH result: '%d'", a); break; - case 1: + case 1: _stack[_stackIndex++] = _vm->rollDice(pos[0], pos[1], pos[2]); debugC(9, kDebugLevelScript, " - throw dice(s): num = '%d', pips = '%d', offset = '%d' - PUSH result: '%d'", pos[0], pos[1], pos[2], _stack[_stackIndex - 1]); pos += 3; @@ -1478,7 +1478,7 @@ int EobInfProcessor::oeob_sequence(int8 *data) { return 0; case -2: - _vm->seq_portal(); + _vm->seq_portal(); break; case -1: diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h index 8f883fd712..a561568336 100644 --- a/engines/kyra/script_eob.h +++ b/engines/kyra/script_eob.h @@ -32,7 +32,7 @@ namespace Kyra { -class LolEobBaseEngine; +class KyraRpgEngine; class EobInfProcessor { public: diff --git a/engines/kyra/sequences_eob1.cpp b/engines/kyra/sequences_eob1.cpp index 2ff4a3aa9f..b25de5ccd2 100644 --- a/engines/kyra/sequences_eob1.cpp +++ b/engines/kyra/sequences_eob1.cpp @@ -38,7 +38,7 @@ int EobEngine::mainMenu() { _menuChoiceInit = 0; Screen::FontId of = _screen->_currentFont; - + while (menuChoice >= 0 && !shouldQuit()) { switch (menuChoice) { case 0: @@ -162,25 +162,25 @@ void EobEngine::seq_playFinale() { delete s; snd_playSoundEffect(20); - + _txt->resetPageBreakString(); _txt->setWaitButtonMode(1); _txt->setupField(12, true); gui_drawBox(0, 0, 176, 175, _color1_1, _color2_1, _bkgColor_1); _txt->printDialogueText(51, _moreStrings[0]); - + if (!checkScriptFlags(0x1ffe)) { _screen->fadeToBlack(); return; } - + _txt->printDialogueText(_finBonusStrings[0]); for (int i = 0; i < 6; i++) { _txt->printDialogueText(_finBonusStrings[1]); if (_characters[i].flags & 1) _txt->printDialogueText(_characters[i].name); } - + uint32 password = 0; for (int i = 0; i < 4; i++) { if (!(_characters[i].flags & 1)) @@ -200,7 +200,7 @@ void EobEngine::seq_playFinale() { void EobEngine::seq_tower() { if (shouldQuit() || skipFlag()) return; - + _screen->loadBitmap(_introFilesTower[1], 5, 3, 0); _screen->setCurPage(2); uint8 *shp = _screen->encodeShape(0, 0, 16, 56, true); @@ -239,7 +239,7 @@ void EobEngine::seq_tower() { _screen->copyRegion(104, 79 - i, 200, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK); _screen->copyRegion(24, 110, 120, i + 31, 80, 34, 4, 0, Screen::CR_NO_P_CHECK); _screen->copyRegion(152, 0, 120, 32, 80, i + 1, 4, 0, Screen::CR_NO_P_CHECK); - _screen->copyRegion(0, 0, 96, 65 + i, 128, 103 - i, 2, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, 0, 96, 65 + i, 128, 103 - i, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); delayUntil(end); } @@ -282,18 +282,18 @@ void EobEngine::seq_orb() { shp[4] = _screen->encodeShape(0, 0, 20, 136, true); _screen->loadBitmap(_introFilesOrb[1], 5, 3, 0); shp[3] = _screen->encodeShape(16, 0, 16, 104, true); - + _screen->fillRect(0, 0, 127, 103, 12); for (int i = 1; i < 4; i++) { copyBlurRegion(128, 0, 0, 0, 128, 104, i); shp[3 - i] = _screen->encodeShape(0, 0, 16, 104, true); } - + _screen->fillRect(0, 0, 159, 135, 12); _screen->setCurPage(0); _screen->copyPage(3, 4); _screen->clearCurPage(); - + _sound->playTrack(6); for (int i = -1; i < 4 && !shouldQuit() && !skipFlag(); i++) { @@ -467,7 +467,7 @@ void EobEngine::seq_king() { static const uint8 advEncX[] = { 0, 6, 12, 19 }; static const uint8 advEncW[] = { 6, 6, 7, 6 }; static const int8 modY[] = { -4, -8, -2, -2, 1, 0, 0, 0 }; - + _screen->loadBitmap(_introFilesKing[1], 5, 3, 0); _screen->setCurPage(2); for (int i = 0; i < 4; i++) { @@ -481,7 +481,7 @@ void EobEngine::seq_king() { for (bool runloop = true; runloop && !shouldQuit() && !skipFlag(); ) { runloop = false; uint32 end = _system->getMillis() + 2 * _tickLength; - + for (int i = 0; i < 4; i++) { if (dy[i] <= 82) continue; @@ -527,7 +527,7 @@ void EobEngine::seq_hands() { _screen->fillRect(0, 160, 319, 199, 12, 0); _screen->fillRect(0, 0, 191, 63, 157, 2); _screen->drawShape(2, shp1, 0, 4, 0); - _screen->drawShape(2, shp2, 151, 4, 0); + _screen->drawShape(2, shp2, 151, 4, 0); boxMorphTransition(25, 8, 18, 4, 3, 0, 21, 8, 6, 0, 28, 23); _screen->copyRegion(0, 128, 0, 176, 320, 16, 6, 0, Screen::CR_NO_P_CHECK); @@ -540,7 +540,7 @@ void EobEngine::seq_hands() { _screen->fillRect(0, 0, 167, 63, 157); _screen->drawShape(2, shp1, i, 4, 0); _screen->drawShape(2, shp1, 105 - i, 4, 0); - _screen->copyRegion(0, 0, 144, 32, 168, 64, 2, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, 0, 144, 32, 168, 64, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); delayUntil(end); } @@ -555,7 +555,7 @@ void EobEngine::seq_hands() { shp1 = _screen->encodeShape(17, 0, 11, 120, true); shp2 = _screen->encodeShape(28, 112, 1, 31, true); uint8 *shp3 = _screen->encodeShape(9, 138, 14, 54, true); - + _screen->setCurPage(2); _screen->fillRect(0, 0, 135, 63, 157); _screen->drawShape(2, shp1, 32, -80, 0); @@ -568,7 +568,7 @@ void EobEngine::seq_hands() { _screen->fillRect(0, 0, 135, 63, 157); _screen->drawShape(2, shp1, 32, i, 0); _screen->drawShape(2, shp2, 40, i + 64, 0); - _screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); delayUntil(end); } @@ -581,7 +581,7 @@ void EobEngine::seq_hands() { _screen->fillRect(0, 0, 135, 63, 157); _screen->drawShape(2, shp3, 12, 64 + i, 0); _screen->drawShape(2, shp1, 32, i, 0); - _screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); delayUntil(end); } @@ -608,7 +608,7 @@ void EobEngine::seq_hands() { _screen->fillRect(0, 0, 143, 95, 157); _screen->drawShape(2, shp1, i, i, 0); _screen->drawShape(2, shp2, (i == -8) ? 55 : 52, (i == -8) ? 52 : 49, 0); - _screen->copyRegion(0, 0, 0, 0, 144, 96, 2, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, 0, 0, 0, 144, 96, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); delayUntil(end); } @@ -633,7 +633,7 @@ void EobEngine::seq_hands() { uint32 end = _system->getMillis() + _tickLength; _screen->fillRect(0, 0, 87, 112, 157); _screen->drawShape(2, shp2, 0, dy, 0); - _screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); delayUntil(end); dy -= 5; @@ -645,7 +645,7 @@ void EobEngine::seq_hands() { uint32 end = _system->getMillis() + _tickLength; _screen->fillRect(0, 0, 87, 39, 157); _screen->drawShape(2, shp1, 0, i, 0); - _screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); delayUntil(end); } @@ -837,7 +837,7 @@ void EobEngine::seq_tunnel() { _sound->playTrack(9); for (int i = 0; i < 6 && !shouldQuit() && !skipFlag(); i++) { - uint32 end = _system->getMillis() + _tickLength; + uint32 end = _system->getMillis() + _tickLength; _screen->copyRegion(_introTvlX1[i] << 3, _introTvlY1[i], _introTvlX2[i] << 3, _introTvlY2[i], _introTvlW[i] << 3, _introTvlH[i], 4, 2, Screen::CR_NO_P_CHECK); for (int ii = 0; ii < 4 && !shouldQuit() && !skipFlag(); ii++) { _screen->updateScreen(); @@ -864,13 +864,13 @@ void EobEngine::seq_tunnel() { _screen->copyRegion(0, 176, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK); _screen->setCurPage(0); _screen->updateScreen(); - delay(50 * _tickLength); + delay(50 * _tickLength); } void EobEngine::seq_xdeath() { uint8 *shapes1[5]; uint8 *shapes2; - + _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); @@ -910,7 +910,7 @@ void EobEngine::seq_xdeath() { _screen->updateScreen(); delay(2 * _tickLength); } - + _screen->modifyScreenDim(5, dm->sx, 0, dm->w, dm->h); snd_playSoundEffect(5); diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp index 597d84d81c..433ee4ae1f 100644 --- a/engines/kyra/sequences_eob2.cpp +++ b/engines/kyra/sequences_eob2.cpp @@ -1278,7 +1278,7 @@ void DarkMoonEngine::seq_nightmare() { initDialogueSequence(); gui_drawDialogueBox(); - + _txt->printDialogueText(99, 0); snd_playSoundEffect(54); @@ -1292,7 +1292,7 @@ void DarkMoonEngine::seq_nightmare() { } _txt->printDialogueText(20, _okStrings[0]); - + restoreAfterDialogueSequence(); _screen->setFont(of); @@ -1303,7 +1303,7 @@ void DarkMoonEngine::seq_kheldran() { initDialogueSequence(); gui_drawDialogueBox(); - + static const char file[] = "KHELDRAN"; _txt->printDialogueText(_kheldranStrings[0]); drawSequenceBitmap(file, 0, 0, 0, 0); @@ -1316,7 +1316,7 @@ void DarkMoonEngine::seq_kheldran() { drawSequenceBitmap(file, 0, 20, 96, 0); delay(7 * _tickLength); _txt->printDialogueText(76, _okStrings[0]); - + restoreAfterDialogueSequence(); _screen->setFont(of); @@ -1327,7 +1327,7 @@ void DarkMoonEngine::seq_dranDragonTransformation() { initDialogueSequence(); gui_drawDialogueBox(); - + static const char file[] = "DRANX"; drawSequenceBitmap(file, 0, 0, 0, 0); _txt->printDialogueText(120, _moreStrings[0]); @@ -1338,7 +1338,7 @@ void DarkMoonEngine::seq_dranDragonTransformation() { delay(7 * _tickLength); drawSequenceBitmap(file, 0, 20, 96, 0); delay(18 * _tickLength); - + restoreAfterDialogueSequence(); _screen->setFont(of); diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp index a37ec9f674..cb9be43b07 100644 --- a/engines/kyra/sound_lol.cpp +++ b/engines/kyra/sound_lol.cpp @@ -198,7 +198,7 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) { } bool LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) { - if (!LolEobBaseEngine::snd_processEnvironmentalSoundEffect(soundId, block)) + if (!KyraRpgEngine::snd_processEnvironmentalSoundEffect(soundId, block)) return false; if (block != _currentBlock) { diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp index 6d8776f3b0..9adf84d1ad 100644 --- a/engines/kyra/sprites_eob.cpp +++ b/engines/kyra/sprites_eob.cpp @@ -20,7 +20,7 @@ * */ -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) +#ifdef ENABLE_EOB #include "kyra/eobcommon.h" #include "kyra/script_eob.h" @@ -29,31 +29,10 @@ #include "common/system.h" -namespace Kyra { - -int LolEobBaseEngine::getBlockDistance(uint16 block1, uint16 block2) { - int b1x = block1 & 0x1f; - int b1y = block1 >> 5; - int b2x = block2 & 0x1f; - int b2y = block2 >> 5; - - uint8 dy = ABS(b2y - b1y); - uint8 dx = ABS(b2x - b1x); - - if (dx > dy) - SWAP(dx, dy); - - return (dx >> 1) + dy; -} - -} // namespace Kyra - -#endif -#ifdef ENABLE_EOB namespace Kyra { -void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) { +void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) { _screen->loadShapeSetBitmap(filename, 3, 3); const uint16 *enc = &_encodeMonsterShpTable[encodeTableIndex << 2]; diff --git a/engines/kyra/sprites_rpg.cpp b/engines/kyra/sprites_rpg.cpp new file mode 100644 index 0000000000..0c4fcb09ab --- /dev/null +++ b/engines/kyra/sprites_rpg.cpp @@ -0,0 +1,46 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#if defined(ENABLE_EOB) || defined(ENABLE_LOL) + +#include "kyra/kyra_rpg.h" + +namespace Kyra { + +int KyraRpgEngine::getBlockDistance(uint16 block1, uint16 block2) { + int b1x = block1 & 0x1f; + int b1y = block1 >> 5; + int b2x = block2 & 0x1f; + int b2y = block2 >> 5; + + uint8 dy = ABS(b2y - b1y); + uint8 dx = ABS(b2x - b1x); + + if (dx > dy) + SWAP(dx, dy); + + return (dx >> 1) + dy; +} + +} // namespace Kyra + +#endif diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp index 7433fbf126..faa2591163 100644 --- a/engines/kyra/staticres_eob.cpp +++ b/engines/kyra/staticres_eob.cpp @@ -22,23 +22,11 @@ */ #include "kyra/eob1.h" -#include "kyra/eob2.h" #include "kyra/resource.h" namespace Kyra { - -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) -const uint16 *StaticResource::loadRawDataBe16(int id, int &entries) { - return (const uint16 *)getData(id, kLolRawDataBe16, entries); -} - -const uint32 *StaticResource::loadRawDataBe32(int id, int &entries) { - return (const uint32 *)getData(id, kLolRawDataBe32, entries); -} -#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL) - #ifdef ENABLE_EOB const EobSequenceStep *StaticResource::loadEob2SeqData(int id, int &entries) { return (const EobSequenceStep *)getData(id, kEob2SequenceData, entries); @@ -51,35 +39,7 @@ const EobShapeDef *StaticResource::loadEob2ShapeData(int id, int &entries) { const EobCharacter *StaticResource::loadEobNpcData(int id, int &entries) { return (const EobCharacter *)getData(id, kEobNpcData, entries); } -#endif // ENABLE_EOB - -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) -bool StaticResource::loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size) { - size = stream.size() >> 1; - - uint16 *r = new uint16[size]; - - for (int i = 0; i < size; i++) - r[i] = stream.readUint16BE(); - - ptr = r; - return true; -} - -bool StaticResource::loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size) { - size = stream.size() >> 2; - - uint32 *r = new uint32[size]; - - for (int i = 0; i < size; i++) - r[i] = stream.readUint32BE(); - - ptr = r; - return true; -} -#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL) -#ifdef ENABLE_EOB bool StaticResource::loadEob2SeqData(Common::SeekableReadStream &stream, void *&ptr, int &size) { size = stream.size() / 11; @@ -165,25 +125,7 @@ bool StaticResource::loadEobNpcData(Common::SeekableReadStream &stream, void *&p ptr = e; return true; } -#endif // ENABLE_EOB -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) -void StaticResource::freeRawDataBe16(void *&ptr, int &size) { - uint16 *data = (uint16 *)ptr; - delete[] data; - ptr = 0; - size = 0; -} - -void StaticResource::freeRawDataBe32(void *&ptr, int &size) { - uint32 *data = (uint32 *)ptr; - delete[] data; - ptr = 0; - size = 0; -} -#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL) - -#ifdef ENABLE_EOB void StaticResource::freeEob2SeqData(void *&ptr, int &size) { EobSequenceStep *d = (EobSequenceStep *)ptr; delete[] d; @@ -238,29 +180,6 @@ const ScreenDim Screen_Eob::_screenDimTable[] = { }; const int Screen_Eob::_screenDimTableCount = ARRAYSIZE(Screen_Eob::_screenDimTable); -#endif - -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) -const uint8 LolEobBaseEngine::_dropItemDirIndex[] = { 0, 1, 2, 3, 1, 3, 0, 2, 3, 2, 1, 0, 2, 0, 3, 1 }; - -void LolEobBaseEngine::initStaticResource() { - int temp; - _dscShapeX = (const int16 *)_staticres->loadRawDataBe16(kLolEobCommonDscX, temp); - _dscShapeIndex = (const int8 *)_staticres->loadRawData(kLolEobCommonDscShapeIndex, temp); - _dscTileIndex = _staticres->loadRawData(kLolEobCommonDscTileIndex, temp); - _dscDim1 = (const int8 *)_staticres->loadRawData(kLolEobCommonDscDimData1, temp); - _dscDim2 = (const int8 *)_staticres->loadRawData(kLolEobCommonDscDimData2, temp); - _dscUnk2 = _staticres->loadRawData(kLolEobCommonDscUnk2, temp); - _dscBlockMap = _staticres->loadRawData(kLolEobCommonDscBlockMap, temp); - _dscBlockIndex = (const int8 *)_staticres->loadRawData(kLolEobCommonDscBlockIndex, temp); - _dscDimMap = _staticres->loadRawData(kLolEobCommonDscDimMap, temp); - _dscDoorShpIndex = _staticres->loadRawData(kLolEobCommonDscDoorShapeIndex, _dscDoorShpIndexSize); - _dscDoorY2 = _staticres->loadRawData(kLolEobCommonDscDoorY2, temp); - _moreStrings = _staticres->loadStrings(kLolEobCommonMoreStrings, temp); -} - -#endif // (ENABLE_EOB || ENABLE_LOL) -#ifdef ENABLE_EOB const uint8 EobCoreEngine::_hpIncrPerLevel[] = { 10, 4, 8, 6, 10, 10, 9, 10, 9, 10, 9, 9, 3, 1, 2, 2, 3, 3 }; @@ -373,7 +292,7 @@ void EobCoreEngine::initStaticResource() { _potionStrings = _staticres->loadStrings(kEobBasePotionStrings, temp); _wandStrings = _staticres->loadStrings(kEobBaseWandStrings, temp); _itemMisuseStrings = _staticres->loadStrings(kEobBaseItemMisuseStrings, temp); - + _takenStrings = _staticres->loadStrings(kEobBaseTakenStrings, temp); _potionEffectStrings = _staticres->loadStrings(kEobBasePotionEffectStrings, temp); @@ -559,7 +478,7 @@ void EobCoreEngine::initStaticResource() { " Spielstände müssen\r einen Namen haben!", 0 }; - + _saveLoadStrings = saveLoadStrings[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)]; _errorSlotEmptyString = errorSlotEmptyString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)]; _errorSlotNoNameString = errorSlotNoNameString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)]; @@ -587,7 +506,7 @@ void EobCoreEngine::initButtonData() { { 0, 0, 0x1100, 288, 62, 31, 33, 3 }, { 368, 0, 0x1000, 184, 2, 63, 8, 0 }, { 369, 0, 0x1000, 256, 2, 63, 8, 1 }, - { 370, 0, 0x1000, 184, 54, 63, 8, 2 }, + { 370, 0, 0x1000, 184, 54, 63, 8, 2 }, { 371, 0, 0x1000, 256, 54, 63, 8, 3 }, { 0, 0, 0x1100, 230, 116, 16, 16, 0 }, { 0, 0, 0x1100, 278, 116, 16, 16, 1 }, @@ -597,7 +516,7 @@ void EobCoreEngine::initButtonData() { { 0, 0, 0x1100, 199, 58, 16, 16, 5 }, { 0, 0, 0x1100, 181, 76, 16, 16, 6 }, { 0, 0, 0x1100, 199, 76, 16, 16, 7 }, - { 0, 0, 0x1100, 181, 94, 16, 16, 8 }, + { 0, 0, 0x1100, 181, 94, 16, 16, 8 }, { 0, 0, 0x1100, 199, 94, 16, 16, 9 }, { 0, 0, 0x1100, 181, 112, 16, 16, 10 }, { 0, 0, 0x1100, 199, 112, 16, 16, 11 }, @@ -785,7 +704,7 @@ void EobCoreEngine::initMenus() { delete[] _menuDefs; _menuDefs = new EobMenuDef[ARRAYSIZE(menuDefs)]; memcpy(_menuDefs, menuDefs, sizeof(menuDefs)); - + if (_flags.gameID == GI_EOB1) { // assign EOB 1 style memorize/pray menu _menuDefs[4].numButtons = 8; @@ -1061,7 +980,7 @@ void EobCoreEngine::initSpells() { ec2(monster_fleshToStone); _spells = new EobSpell[_numSpells]; - memset(_spells, 0, _numSpells * sizeof(EobSpell)); + memset(_spells, 0, _numSpells * sizeof(EobSpell)); for (int i = 0, n = 0; i < _numSpells; i++, n++) { EobSpell *s = &_spells[i]; @@ -1103,7 +1022,7 @@ void EobEngine::initStaticResource() { int temp; _mainMenuStrings = _staticres->loadStrings(kEob1MainMenuStrings, temp); _finBonusStrings = _staticres->loadStrings(kEob1BonusStrings, temp); - + _introFilesOpening = _staticres->loadStrings(kEob1IntroFilesOpening, temp); _introFilesTower = _staticres->loadStrings(kEob1IntroFilesTower, temp); _introFilesOrb = _staticres->loadStrings(kEob1IntroFilesOrb, temp); diff --git a/engines/kyra/staticres_rpg.cpp b/engines/kyra/staticres_rpg.cpp new file mode 100644 index 0000000000..49a55fc9b8 --- /dev/null +++ b/engines/kyra/staticres_rpg.cpp @@ -0,0 +1,97 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * + */ + +#include "kyra/resource.h" + + +namespace Kyra { + +#if defined(ENABLE_EOB) || defined(ENABLE_LOL) +const uint16 *StaticResource::loadRawDataBe16(int id, int &entries) { + return (const uint16 *)getData(id, kLolRawDataBe16, entries); +} + +const uint32 *StaticResource::loadRawDataBe32(int id, int &entries) { + return (const uint32 *)getData(id, kLolRawDataBe32, entries); +} + +bool StaticResource::loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size) { + size = stream.size() >> 1; + + uint16 *r = new uint16[size]; + + for (int i = 0; i < size; i++) + r[i] = stream.readUint16BE(); + + ptr = r; + return true; +} + +bool StaticResource::loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size) { + size = stream.size() >> 2; + + uint32 *r = new uint32[size]; + + for (int i = 0; i < size; i++) + r[i] = stream.readUint32BE(); + + ptr = r; + return true; +} + +void StaticResource::freeRawDataBe16(void *&ptr, int &size) { + uint16 *data = (uint16 *)ptr; + delete[] data; + ptr = 0; + size = 0; +} + +void StaticResource::freeRawDataBe32(void *&ptr, int &size) { + uint32 *data = (uint32 *)ptr; + delete[] data; + ptr = 0; + size = 0; +} + +const uint8 KyraRpgEngine::_dropItemDirIndex[] = { 0, 1, 2, 3, 1, 3, 0, 2, 3, 2, 1, 0, 2, 0, 3, 1 }; + +void KyraRpgEngine::initStaticResource() { + int temp; + _dscShapeX = (const int16 *)_staticres->loadRawDataBe16(kLolEobCommonDscX, temp); + _dscShapeIndex = (const int8 *)_staticres->loadRawData(kLolEobCommonDscShapeIndex, temp); + _dscTileIndex = _staticres->loadRawData(kLolEobCommonDscTileIndex, temp); + _dscDim1 = (const int8 *)_staticres->loadRawData(kLolEobCommonDscDimData1, temp); + _dscDim2 = (const int8 *)_staticres->loadRawData(kLolEobCommonDscDimData2, temp); + _dscUnk2 = _staticres->loadRawData(kLolEobCommonDscUnk2, temp); + _dscBlockMap = _staticres->loadRawData(kLolEobCommonDscBlockMap, temp); + _dscBlockIndex = (const int8 *)_staticres->loadRawData(kLolEobCommonDscBlockIndex, temp); + _dscDimMap = _staticres->loadRawData(kLolEobCommonDscDimMap, temp); + _dscDoorShpIndex = _staticres->loadRawData(kLolEobCommonDscDoorShapeIndex, _dscDoorShpIndexSize); + _dscDoorY2 = _staticres->loadRawData(kLolEobCommonDscDoorY2, temp); + _moreStrings = _staticres->loadStrings(kLolEobCommonMoreStrings, temp); +} + +#endif // (ENABLE_EOB || ENABLE_LOL) + +} // End of namespace Kyra + diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp deleted file mode 100644 index 1c0c7e5d41..0000000000 --- a/engines/kyra/text_eob.cpp +++ /dev/null @@ -1,688 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) - -#include "kyra/loleobbase.h" -#include "kyra/screen.h" -#include "kyra/timer.h" - -#include "common/system.h" - -namespace Kyra { - -enum { - kEobTextBufferSize = 2048 -}; - -TextDisplayer_Eob::TextDisplayer_Eob(LolEobBaseEngine *engine, Screen *sScreen) : _vm(engine), _screen(sScreen), - _lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true), - _numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false), _waitButtonMode(1) { - - _dialogueBuffer = new char[kEobTextBufferSize]; - memset(_dialogueBuffer, 0, kEobTextBufferSize); - - _currentLine = new char[85]; - memset(_currentLine, 0, 85); - - _textDimData = new TextDimData[_screen->screenDimTableCount()]; - - for (int i = 0; i < _screen->screenDimTableCount(); i++){ - const ScreenDim *d = _screen->getScreenDim(i); - _textDimData[i].color1 = d->unk8; - _textDimData[i].color2 = d->unkA; - _textDimData[i].line = d->unkC; - _textDimData[i].column = d->unkE; - } - - _table1 = new char[128]; - memset(_table1, 0, 128); - _table2 = new char[16]; - memset(_table2, 0, 16); - - _waitButtonSpace = 0; -} - -TextDisplayer_Eob::~TextDisplayer_Eob() { - delete[] _dialogueBuffer; - delete[] _currentLine; - delete[] _textDimData; - delete[] _table1; - delete[] _table2; -} - -void TextDisplayer_Eob::setupField(int dim, bool mode) { - setPageBreakFlag(); - - _textDimData[dim].color2 = _vm->_bkgColor_1; - _screen->setScreenDim(dim); - - if (mode) - clearCurDim(); - else - resetDimTextPositions(dim); -} - -void TextDisplayer_Eob::resetDimTextPositions(int dim) { - _textDimData[dim].column = 0; - _textDimData[dim].line = 0; -} - -void TextDisplayer_Eob::resetPageBreakString() { - if (vm()->_moreStrings) - strcpy(_pageBreakString, vm()->_moreStrings[0]); -} - -void TextDisplayer_Eob::setPageBreakFlag() { - _allowPageBreak = true; - _lineCount = 0; -} - -void TextDisplayer_Eob::removePageBreakFlag() { - _allowPageBreak = false; -} - -void TextDisplayer_Eob::displayText(char *str, ...) { - const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98); - - _printFlag = false; - - _lineWidth = 0; - _numCharsLeft = 0; - _numCharsPrinted = 0; - - _tempString1 = str; - _tempString2 = 0; - - _currentLine[0] = 0; - - memset(_ctrl, 0, 3); - - char c = parseCommand(); - - va_list args; - va_start(args, str); - - const ScreenDim *sd = _screen->_curDim; - int sdx = _screen->curDimIndex(); - - bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false; - uint16 charsPerLine = (sd->w << 3) / (_screen->getFontWidth() + _screen->_charWidth); - - while (c) { - char a = tolower(_ctrl[1]); - - if (!_tempString2 && c == '%') { - if (a == 'd') { - strcpy(_scriptParaString, Common::String::format("%d", va_arg(args, int)).c_str()); - _tempString2 = _scriptParaString; - } else if (a == 's') { - _tempString2 = va_arg(args, char *); - } else { - break; - } - - _ctrl[0] = _ctrl[2]; - _ctrl[2] = _ctrl[1] = 0; - c = parseCommand(); - } - - if (isPc98) { - uint8 cu = (uint8) c; - if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) { - _currentLine[_numCharsLeft++] = c; - _currentLine[_numCharsLeft++] = parseCommand(); - _currentLine[_numCharsLeft] = '\0'; - _lineWidth += 8; - if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3)) - printLine(_currentLine); - c = parseCommand(); - continue; - } - } - - uint16 dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth); - - switch (c - 1) { - case 0: - printLine(_currentLine); - textPageBreak(); - _numCharsPrinted = 0; - break; - - case 1: - printLine(_currentLine); - _textDimData[sdx].color2 = parseCommand(); - break; - - case 5: - printLine(_currentLine); - _textDimData[sdx].color1 = parseCommand(); - break; - - case 8: - printLine(_currentLine); - dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth); - dv = ((dv + 8) & 0xfff8) - 1; - if (dv >= charsPerLine) - dv = 0; - _textDimData[sdx].column = (_screen->getFontWidth() + _screen->_charWidth) * dv; - break; - - case 11: - _sjisLineBreakFlag=_sjisLineBreakFlag; - // TODO (UNUSED) - break; - - case 12: - if (isPc98) - _sjisLineBreakFlag = true; - printLine(_currentLine); - _sjisLineBreakFlag = false; - _lineCount++; - _textDimData[sdx].column = 0; - _textDimData[sdx].line++; - break; - - case 18: - _sjisLineBreakFlag=_sjisLineBreakFlag; - // TODO (UNUSED) - break; - - case 23: - _sjisLineBreakFlag=_sjisLineBreakFlag; - // TODO (UNUSED) - break; - - case 24: - _sjisLineBreakFlag=_sjisLineBreakFlag; - // TODO (UNUSED) - break; - - case 26: - _sjisLineBreakFlag=_sjisLineBreakFlag; - // TODO (UNUSED) - break; - - case 28: - _sjisLineBreakFlag=_sjisLineBreakFlag; - // TODO (UNUSED) - break; - - default: - if (_vm->game() == GI_LOL || c > 30) { - _lineWidth += (pc98PrintFlag ? 4 : _screen->getCharWidth((uint8)c)); - _currentLine[_numCharsLeft++] = c; - _currentLine[_numCharsLeft] = 0; - - if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3)) - printLine(_currentLine); - } - } - - c = parseCommand(); - } - - va_end(args); - - if (_numCharsLeft) - printLine(_currentLine); -} - -char TextDisplayer_Eob::parseCommand() { - if (!_ctrl[1]) - readNextPara(); - - char res = _ctrl[1]; - _ctrl[1] = _ctrl[2]; - _ctrl[2] = 0; - - if (!_ctrl[1]) - readNextPara(); - - return res; -} - -void TextDisplayer_Eob::readNextPara() { - char c = 0; - char d = 0; - - if (_tempString2) { - if (*_tempString2) { - d = *_tempString2++; - } else { - _tempString2 = 0; - d = _ctrl[0]; - } - } - - if (!d && _tempString1) { - if (*_tempString1) - d = *_tempString1++; - else - _tempString1 = 0; - } - - if ((_vm->game() != GI_LOL) && (d & 0x80)) { - d &= 0x7f; - c = d & 7; - d = (d & 0x78) >> 3; - uint8 l = d; - c = _table1[(l << 3) + c]; - d = _table2[l]; - } - - _ctrl[1] = d; - _ctrl[2] = c; -} - -void TextDisplayer_Eob::printLine(char *str) { - const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98); - const ScreenDim *sd = _screen->_curDim; - int sdx = _screen->curDimIndex(); - bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false; - - int fh = (_screen->_currentFont == Screen::FID_SJIS_FNT) ? 9 : (_screen->getFontHeight() + _screen->_charOffset); - int lines = (sd->h - _screen->_charOffset) / fh; - - while (_textDimData[sdx].line >= lines) { - if ((lines - _waitButtonSpace) <= _lineCount && _allowPageBreak) { - _lineCount = 0; - textPageBreak(); - _numCharsPrinted = 0; - } - - int h1 = ((sd->h / fh) - 1) * fh; - int h2 = sd->h - fh; - - if (h2) - _screen->copyRegion(sd->sx << 3, sd->sy + fh, sd->sx << 3, sd->sy, sd->w << 3, h2, _screen->_curPage, _screen->_curPage, Screen::CR_NO_P_CHECK); - - _screen->fillRect(sd->sx << 3, sd->sy + h1, ((sd->sx + sd->w) << 3) - 1, sd->sy + sd->h - 1, _textDimData[sdx].color2); - if (_textDimData[sdx].line) - _textDimData[sdx].line--; - } - - int x1 = (sd->sx << 3) + _textDimData[sdx].column; - int y = sd->sy + (pc98PrintFlag ? (_textDimData[sdx].line << 3) : (fh * _textDimData[sdx].line)); - int w = sd->w << 3; - int lw = _lineWidth; - int s = _numCharsLeft; - char c = 0; - - if (pc98PrintFlag) { - bool ct = true; - - if ((lw + _textDimData[sdx].column) > w) { - if ((lines - 1 - (_waitButtonSpace << 1)) <= _lineCount) - // cut off line to leave space for "MORE" button - w -= vm()->_waitButtonReverveW; - } else { - if (!_sjisLineBreakFlag || (_lineCount + 1 < lines - 1)) - ct = false; - else - // cut off line to leave space for "MORE" button - w -= vm()->_waitButtonReverveW; - } - - if (ct) { - w -= _textDimData[sdx].column; - - int n2 = 0; - int n1 = (w / 4) - 1; - - while (n2 < n1 && n2 < s) { - c = str[n2]; - uint8 cu = (uint8) c; - if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) - n2++; - n2++; - } - s = n2; - } - } else { - if ((lw + _textDimData[sdx].column) > w) { - if ((lines - 1) <= _lineCount && _allowPageBreak) - // cut off line to leave space for "MORE" button - w -= vm()->_waitButtonReverveW; - - w -= _textDimData[sdx].column; - - int n2 = 0; - int n1 = s - 1; - - while (n1 > 0) { - //cut off line after last space - c = str[n1]; - - lw -= _screen->getCharWidth((uint8)c); - - if (!n2 && lw <= w) - n2 = n1; - - if (n2 && c == ' ') { - s = n1; - _printFlag = false; - break; - } - n1--; - } - - if (!n1) { - if (_textDimData[sdx].column && !_printFlag) { - s = lw = 0; - _printFlag = true; - } else { - s = n2; - } - } - } - } - - c = str[s]; - str[s] = 0; - - uint8 col = _textDimData[sdx].color1; - if (isPc98 && (sdx == 2 || sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) { - switch (_textDimData[sdx].color1) { - case 0x88: - col = 0x41; - break; - case 0x55: - col = 0x81; - break; - case 0xaa: - col = 0x21; - break; - case 0x99: - col = 0xa1; - break; - case 0x33: - col = 0xe1; - break; - case 0x18: - col = 0x61; - break; - default: - col = 1; - break; - } - _screen->printText(str, x1 & ~3, (y + 8) & ~7, col, 0); - } else { - _screen->printText(str, x1, y, col, _textDimData[sdx].color2); - } - - _textDimData[sdx].column += lw; - _numCharsPrinted += strlen(str); - - str[s] = c; - - if (c == ' ') - s++; - - if (str[s] == ' ') - s++; - - uint32 len = strlen(&str[s]); - for (uint32 i = 0; i < len; i++) - str[i] = str[s + i]; - str[len] = 0; - - _numCharsLeft = strlen(str); - _lineWidth = pc98PrintFlag ? (_numCharsLeft << 2) : _screen->getTextWidth(str); - - if (!_numCharsLeft && _textDimData[sdx].column < (sd->w << 3)) - return; - - _textDimData[sdx].column = 0; - _textDimData[sdx].line++; - _lineCount++; - - printLine(str); -} - -void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakString) { - 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); - - displayText(_dialogueBuffer); - - if (pageBreakString) { - if (pageBreakString[0]) { - strcpy(_pageBreakString, pageBreakString); - displayWaitButton(); - resetPageBreakString(); - } - } -} - -void TextDisplayer_Eob::printDialogueText(const char *str, bool wait) { - assert (strlen(str) < kEobTextBufferSize); - Common::strlcpy(_dialogueBuffer, str, kEobTextBufferSize); - - strcpy(_dialogueBuffer, str); - displayText(_dialogueBuffer); - if (wait) - displayWaitButton(); -} - -void TextDisplayer_Eob::printMessage(const char *str, int textColor, ...) { - int tc = _textDimData[screen()->curDimIndex()].color1; - - if (textColor != -1) - _textDimData[screen()->curDimIndex()].color1 = textColor; - - va_list args; - va_start(args, textColor); - vsnprintf(_dialogueBuffer, kEobTextBufferSize - 1, str, args); - va_end(args); - - displayText(_dialogueBuffer); - - if (vm()->game() != GI_EOB1) - _textDimData[screen()->curDimIndex()].color1 = tc; - - if (!screen()->_curPage) - screen()->updateScreen(); -} - -int TextDisplayer_Eob::clearDim(int dim) { - int res = screen()->curDimIndex(); - screen()->setScreenDim(dim); - _textDimData[dim].color1 = screen()->_curDim->unk8; - _textDimData[dim].color2 = vm()->game() == GI_LOL ? screen()->_curDim->unkA : vm()->_bkgColor_1; - clearCurDim(); - return res; -} - -void TextDisplayer_Eob::clearCurDim() { - int d = screen()->curDimIndex(); - const ScreenDim *tmp = screen()->getScreenDim(d); - if (vm()->gameFlags().use16ColorMode) { - screen()->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 2, (tmp->sy + tmp->h) - 2, _textDimData[d].color2); - } else - screen()->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, _textDimData[d].color2); - - _lineCount = 0; - _textDimData[d].column = _textDimData[d].line = 0; -} - -void TextDisplayer_Eob::textPageBreak() { - if (vm()->game() != GI_LOL) - SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2); - - int cp = _screen->setCurPage(0); - Screen::FontId cf = screen()->setFont(vm()->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT); - - if (vm()->game() == GI_LOL) - vm()->_timer->pauseSingleTimer(11, true); - - vm()->_fadeText = false; - int resetPortraitAfterSpeechAnim = 0; - int updatePortraitSpeechAnimDuration = 0; - - if (vm()->_updateCharNum != -1) { - resetPortraitAfterSpeechAnim = vm()->_resetPortraitAfterSpeechAnim; - vm()->_resetPortraitAfterSpeechAnim = 0; - updatePortraitSpeechAnimDuration = vm()->_updatePortraitSpeechAnimDuration; - if (vm()->_updatePortraitSpeechAnimDuration > 36) - vm()->_updatePortraitSpeechAnimDuration = 36; - } - - uint32 speechPartTime = 0; - if (vm()->speechEnabled() && vm()->_activeVoiceFileTotalTime && _numCharsTotal) - speechPartTime = vm()->_system->getMillis() + ((_numCharsPrinted * vm()->_activeVoiceFileTotalTime) / _numCharsTotal); - - const ScreenDim *dim = screen()->getScreenDim(screen()->curDimIndex()); - - int x = ((dim->sx + dim->w) << 3) - (_vm->_dialogueButtonW + 3); - int y = 0; - int w = vm()->_dialogueButtonW; - - if (vm()->game() == GI_LOL) { - if (vm()->_needSceneRestore && (vm()->_updateFlags & 2)) { - if (vm()->_currentControlMode || !(vm()->_updateFlags & 2)) { - y = dim->sy + dim->h - 5; - } else { - x += 6; - y = dim->sy + dim->h - 2; - } - } else { - y = dim->sy + dim->h - 10; - } - } else { - y = vm()->_waitButtonPresY[_waitButtonMode]; - x = vm()->_waitButtonPresX[_waitButtonMode]; - w = vm()->_waitButtonPresW[_waitButtonMode]; - } - - if (vm()->gameFlags().use16ColorMode) { - vm()->gui_drawBox(x + 8, (y & ~7) - 1, 66, 10, 0xee, 0xcc, -1); - screen()->printText(_pageBreakString, (x + 37 - (strlen(_pageBreakString) << 1) + 4) & ~3, (y + 2) & ~7, 0xc1, 0); - } else { - vm()->gui_drawBox(x, y, w, vm()->_dialogueButtonH, vm()->_color1_1, vm()->_color2_1, vm()->_bkgColor_1); - screen()->printText(_pageBreakString, x + (w >> 1) - (vm()->screen()->getTextWidth(_pageBreakString) >> 1), y + 2, vm()->_dialogueButtonLabelCol1, 0); - } - - vm()->removeInputTop(); - - bool loop = true; - bool target = false; - - do { - int inputFlag = vm()->checkInput(0, false) & 0xFF; - vm()->removeInputTop(); - - while (!inputFlag && !_vm->shouldQuit()) { - vm()->update(); - - if (vm()->speechEnabled()) { - if (((vm()->_system->getMillis() > speechPartTime) || (vm()->snd_updateCharacterSpeech() != 2)) && speechPartTime) { - loop = false; - inputFlag = vm()->_keyMap[Common::KEYCODE_RETURN]; - break; - } - } - - inputFlag = vm()->checkInput(0, false) & 0xFF; - vm()->removeInputTop(); - } - - vm()->gui_notifyButtonListChanged(); - - if (inputFlag == vm()->_keyMap[Common::KEYCODE_SPACE] || inputFlag == vm()->_keyMap[Common::KEYCODE_RETURN]) { - loop = false; - } else if (inputFlag == 199 || inputFlag == 201) { - if (vm()->posWithinRect(vm()->_mouseX, vm()->_mouseY, x, y, x + w, y + 9)) { - if (_vm->game() == GI_LOL) - target = true; - else - loop = false; - } - } else if (inputFlag == 200 || inputFlag == 202) { - if (target) - loop = false; - } - } while (loop && !_vm->shouldQuit()); - - if (vm()->gameFlags().use16ColorMode) - screen()->fillRect(x + 8, y, x + 57, y + 9, _textDimData[screen()->curDimIndex()].color2); - else - screen()->fillRect(x, y, x + w - 1, y + 8, _textDimData[screen()->curDimIndex()].color2); - - clearCurDim(); - _screen->updateScreen(); - - if (vm()->game() == GI_LOL) - vm()->_timer->pauseSingleTimer(11, false); - - if (vm()->_updateCharNum != -1) { - vm()->_resetPortraitAfterSpeechAnim = resetPortraitAfterSpeechAnim; - if (updatePortraitSpeechAnimDuration > 36) - updatePortraitSpeechAnimDuration -= 36; - else - updatePortraitSpeechAnimDuration >>= 1; - - vm()->_updatePortraitSpeechAnimDuration = updatePortraitSpeechAnimDuration; - } - - screen()->setFont(cf); - screen()->setCurPage(cp); - - if (vm()->game() != GI_LOL) - SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2); - - vm()->removeInputTop(); -} - -void TextDisplayer_Eob::displayWaitButton() { - vm()->_dialogueNumButtons = 1; - vm()->_dialogueButtonString[0] = _pageBreakString; - vm()->_dialogueButtonString[1] = 0; - vm()->_dialogueButtonString[2] = 0; - vm()->_dialogueHighlightedButton = 0; - - vm()->_dialogueButtonPosX = &vm()->_waitButtonPresX[_waitButtonMode]; - vm()->_dialogueButtonPosY = &vm()->_waitButtonPresY[_waitButtonMode]; - vm()->_dialogueButtonW = vm()->_waitButtonPresW[_waitButtonMode]; - vm()->_dialogueButtonYoffs = 0; - - SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2); - vm()->drawDialogueButtons(); - - if (!vm()->shouldQuit()) - vm()->removeInputTop(); - - while (!vm()->processDialogue() && !vm()->shouldQuit()) {} - - _screen->fillRect(vm()->_dialogueButtonPosX[0], vm()->_dialogueButtonPosY[0], vm()->_dialogueButtonPosX[0] + vm()->_dialogueButtonW - 1, vm()->_dialogueButtonPosY[0] + vm()->_dialogueButtonH - 1, vm()->_bkgColor_1); - _screen->updateScreen(); - vm()->_dialogueButtonW = 95; - SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2); - clearCurDim(); -} - -} // End of namespace Kyra - -#endif // (ENABLE_EOB || ENABLE_LOL) diff --git a/engines/kyra/text_eob.h b/engines/kyra/text_eob.h deleted file mode 100644 index 9409ac43f0..0000000000 --- a/engines/kyra/text_eob.h +++ /dev/null @@ -1,115 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are to numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) - -#ifndef KYRA_TEXT_EOB_H -#define KYRA_TEXT_EOB_H - -#include "common/scummsys.h" - -namespace Kyra { - -class Screen; -class LolEobBaseEngine; - -class TextDisplayer_Eob { -public: - TextDisplayer_Eob(LolEobBaseEngine *engine, Screen *sScreen); - virtual ~TextDisplayer_Eob(); - - virtual void setupField(int dim, bool mode); - - void printDialogueText(int stringId, const char *pageBreakString); - void printDialogueText(const char *str, bool wait = false); - void printMessage(const char *str, int textColor = -1, ...); - - int clearDim(int dim); - void clearCurDim(); - - void resetDimTextPositions(int dim); - void resetPageBreakString(); - void setPageBreakFlag(); - void removePageBreakFlag(); - - void allowPageBreak(bool mode) { _allowPageBreak = mode; } - void setWaitButtonMode(int mode) { _waitButtonMode = mode; } - int lineCount() { return _lineCount; } - -protected: - virtual LolEobBaseEngine *vm() { return _vm; } - virtual Screen *screen() { return _screen; } - - void displayText(char *str, ...); - char parseCommand(); - void readNextPara(); - void printLine(char *str); - virtual void textPageBreak(); - void displayWaitButton(); - - char *_dialogueBuffer; - - char *_tempString1; - char *_tempString2; - char *_currentLine; - char _ctrl[3]; - - uint16 _lineWidth; - uint32 _numCharsTotal; - uint32 _numCharsLeft; - uint32 _numCharsPrinted; - - bool _printFlag; - bool _sjisLineBreakFlag; - - char _pageBreakString[20]; - char _scriptParaString[11]; - int _lineCount; - - bool _allowPageBreak; - int _waitButtonSpace; - int _waitButtonMode; - - static const char _pageBreakDefault[3][5]; - - struct TextDimData { - uint8 color1; - uint8 color2; - uint16 column; - uint8 line; - }; - - TextDimData *_textDimData; - -private: - LolEobBaseEngine *_vm; - Screen *_screen; - - char *_table1; - char *_table2; -}; - -} // End of namespace Kyra - -#endif - -#endif // ENABLE_EOB || ENABLE_LOL diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp index da1efa37fe..d07956b3ff 100644 --- a/engines/kyra/text_lol.cpp +++ b/engines/kyra/text_lol.cpp @@ -32,7 +32,7 @@ namespace Kyra { -TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL) : TextDisplayer_Eob(engine, engine->screen()), +TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL) : TextDisplayer_rpg(engine, engine->screen()), _vm(engine), _screen(screenLoL), _scriptTextParameter(0) { memset(_stringParameters, 0, 15 * sizeof(char *)); @@ -333,7 +333,7 @@ void TextDisplayer_LoL::preprocessString(char *str, EMCState *script, const uint *dst = 0; } -LolEobBaseEngine *TextDisplayer_LoL::vm() { +KyraRpgEngine *TextDisplayer_LoL::vm() { return _vm; } @@ -343,7 +343,7 @@ Screen *TextDisplayer_LoL::screen() { void TextDisplayer_LoL::textPageBreak() { strcpy(_pageBreakString, _vm->getLangString(0x4073)); - TextDisplayer_Eob::textPageBreak(); + TextDisplayer_rpg::textPageBreak(); } } // End of namespace Kyra diff --git a/engines/kyra/text_lol.h b/engines/kyra/text_lol.h index 0dcc4b73b3..6da217e30e 100644 --- a/engines/kyra/text_lol.h +++ b/engines/kyra/text_lol.h @@ -24,7 +24,7 @@ #define KYRA_TEXT_LOL_H #if defined(ENABLE_EOB) || defined(ENABLE_LOL) -#include "kyra/text_eob.h" +#include "kyra/text_rpg.h" #endif #include "common/scummsys.h" @@ -36,7 +36,7 @@ class Screen_LoL; class LoLEngine; struct EMCState; -class TextDisplayer_LoL : public TextDisplayer_Eob { +class TextDisplayer_LoL : public TextDisplayer_rpg { public: TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL); ~TextDisplayer_LoL(); @@ -50,7 +50,7 @@ public: int16 _scriptTextParameter; private: - LolEobBaseEngine *vm(); + KyraRpgEngine *vm(); Screen *screen(); void preprocessString(char *str, EMCState *script, const uint16 *paramList, int16 paramIndex); diff --git a/engines/kyra/text_rpg.cpp b/engines/kyra/text_rpg.cpp new file mode 100644 index 0000000000..bbc3cdbd98 --- /dev/null +++ b/engines/kyra/text_rpg.cpp @@ -0,0 +1,688 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * + */ + +#if defined(ENABLE_EOB) || defined(ENABLE_LOL) + +#include "kyra/kyra_rpg.h" +#include "kyra/screen.h" +#include "kyra/timer.h" + +#include "common/system.h" + +namespace Kyra { + +enum { + kEobTextBufferSize = 2048 +}; + +TextDisplayer_rpg::TextDisplayer_rpg(KyraRpgEngine *engine, Screen *sScreen) : _vm(engine), _screen(sScreen), + _lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true), + _numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false), _waitButtonMode(1) { + + _dialogueBuffer = new char[kEobTextBufferSize]; + memset(_dialogueBuffer, 0, kEobTextBufferSize); + + _currentLine = new char[85]; + memset(_currentLine, 0, 85); + + _textDimData = new TextDimData[_screen->screenDimTableCount()]; + + for (int i = 0; i < _screen->screenDimTableCount(); i++){ + const ScreenDim *d = _screen->getScreenDim(i); + _textDimData[i].color1 = d->unk8; + _textDimData[i].color2 = d->unkA; + _textDimData[i].line = d->unkC; + _textDimData[i].column = d->unkE; + } + + _table1 = new char[128]; + memset(_table1, 0, 128); + _table2 = new char[16]; + memset(_table2, 0, 16); + + _waitButtonSpace = 0; +} + +TextDisplayer_rpg::~TextDisplayer_rpg() { + delete[] _dialogueBuffer; + delete[] _currentLine; + delete[] _textDimData; + delete[] _table1; + delete[] _table2; +} + +void TextDisplayer_rpg::setupField(int dim, bool mode) { + setPageBreakFlag(); + + _textDimData[dim].color2 = _vm->_bkgColor_1; + _screen->setScreenDim(dim); + + if (mode) + clearCurDim(); + else + resetDimTextPositions(dim); +} + +void TextDisplayer_rpg::resetDimTextPositions(int dim) { + _textDimData[dim].column = 0; + _textDimData[dim].line = 0; +} + +void TextDisplayer_rpg::resetPageBreakString() { + if (vm()->_moreStrings) + strcpy(_pageBreakString, vm()->_moreStrings[0]); +} + +void TextDisplayer_rpg::setPageBreakFlag() { + _allowPageBreak = true; + _lineCount = 0; +} + +void TextDisplayer_rpg::removePageBreakFlag() { + _allowPageBreak = false; +} + +void TextDisplayer_rpg::displayText(char *str, ...) { + const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98); + + _printFlag = false; + + _lineWidth = 0; + _numCharsLeft = 0; + _numCharsPrinted = 0; + + _tempString1 = str; + _tempString2 = 0; + + _currentLine[0] = 0; + + memset(_ctrl, 0, 3); + + char c = parseCommand(); + + va_list args; + va_start(args, str); + + const ScreenDim *sd = _screen->_curDim; + int sdx = _screen->curDimIndex(); + + bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false; + uint16 charsPerLine = (sd->w << 3) / (_screen->getFontWidth() + _screen->_charWidth); + + while (c) { + char a = tolower(_ctrl[1]); + + if (!_tempString2 && c == '%') { + if (a == 'd') { + strcpy(_scriptParaString, Common::String::format("%d", va_arg(args, int)).c_str()); + _tempString2 = _scriptParaString; + } else if (a == 's') { + _tempString2 = va_arg(args, char *); + } else { + break; + } + + _ctrl[0] = _ctrl[2]; + _ctrl[2] = _ctrl[1] = 0; + c = parseCommand(); + } + + if (isPc98) { + uint8 cu = (uint8) c; + if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) { + _currentLine[_numCharsLeft++] = c; + _currentLine[_numCharsLeft++] = parseCommand(); + _currentLine[_numCharsLeft] = '\0'; + _lineWidth += 8; + if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3)) + printLine(_currentLine); + c = parseCommand(); + continue; + } + } + + uint16 dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth); + + switch (c - 1) { + case 0: + printLine(_currentLine); + textPageBreak(); + _numCharsPrinted = 0; + break; + + case 1: + printLine(_currentLine); + _textDimData[sdx].color2 = parseCommand(); + break; + + case 5: + printLine(_currentLine); + _textDimData[sdx].color1 = parseCommand(); + break; + + case 8: + printLine(_currentLine); + dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth); + dv = ((dv + 8) & 0xfff8) - 1; + if (dv >= charsPerLine) + dv = 0; + _textDimData[sdx].column = (_screen->getFontWidth() + _screen->_charWidth) * dv; + break; + + case 11: + _sjisLineBreakFlag=_sjisLineBreakFlag; + // TODO (UNUSED) + break; + + case 12: + if (isPc98) + _sjisLineBreakFlag = true; + printLine(_currentLine); + _sjisLineBreakFlag = false; + _lineCount++; + _textDimData[sdx].column = 0; + _textDimData[sdx].line++; + break; + + case 18: + _sjisLineBreakFlag=_sjisLineBreakFlag; + // TODO (UNUSED) + break; + + case 23: + _sjisLineBreakFlag=_sjisLineBreakFlag; + // TODO (UNUSED) + break; + + case 24: + _sjisLineBreakFlag=_sjisLineBreakFlag; + // TODO (UNUSED) + break; + + case 26: + _sjisLineBreakFlag=_sjisLineBreakFlag; + // TODO (UNUSED) + break; + + case 28: + _sjisLineBreakFlag=_sjisLineBreakFlag; + // TODO (UNUSED) + break; + + default: + if (_vm->game() == GI_LOL || c > 30) { + _lineWidth += (pc98PrintFlag ? 4 : _screen->getCharWidth((uint8)c)); + _currentLine[_numCharsLeft++] = c; + _currentLine[_numCharsLeft] = 0; + + if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3)) + printLine(_currentLine); + } + } + + c = parseCommand(); + } + + va_end(args); + + if (_numCharsLeft) + printLine(_currentLine); +} + +char TextDisplayer_rpg::parseCommand() { + if (!_ctrl[1]) + readNextPara(); + + char res = _ctrl[1]; + _ctrl[1] = _ctrl[2]; + _ctrl[2] = 0; + + if (!_ctrl[1]) + readNextPara(); + + return res; +} + +void TextDisplayer_rpg::readNextPara() { + char c = 0; + char d = 0; + + if (_tempString2) { + if (*_tempString2) { + d = *_tempString2++; + } else { + _tempString2 = 0; + d = _ctrl[0]; + } + } + + if (!d && _tempString1) { + if (*_tempString1) + d = *_tempString1++; + else + _tempString1 = 0; + } + + if ((_vm->game() != GI_LOL) && (d & 0x80)) { + d &= 0x7f; + c = d & 7; + d = (d & 0x78) >> 3; + uint8 l = d; + c = _table1[(l << 3) + c]; + d = _table2[l]; + } + + _ctrl[1] = d; + _ctrl[2] = c; +} + +void TextDisplayer_rpg::printLine(char *str) { + const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98); + const ScreenDim *sd = _screen->_curDim; + int sdx = _screen->curDimIndex(); + bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false; + + int fh = (_screen->_currentFont == Screen::FID_SJIS_FNT) ? 9 : (_screen->getFontHeight() + _screen->_charOffset); + int lines = (sd->h - _screen->_charOffset) / fh; + + while (_textDimData[sdx].line >= lines) { + if ((lines - _waitButtonSpace) <= _lineCount && _allowPageBreak) { + _lineCount = 0; + textPageBreak(); + _numCharsPrinted = 0; + } + + int h1 = ((sd->h / fh) - 1) * fh; + int h2 = sd->h - fh; + + if (h2) + _screen->copyRegion(sd->sx << 3, sd->sy + fh, sd->sx << 3, sd->sy, sd->w << 3, h2, _screen->_curPage, _screen->_curPage, Screen::CR_NO_P_CHECK); + + _screen->fillRect(sd->sx << 3, sd->sy + h1, ((sd->sx + sd->w) << 3) - 1, sd->sy + sd->h - 1, _textDimData[sdx].color2); + if (_textDimData[sdx].line) + _textDimData[sdx].line--; + } + + int x1 = (sd->sx << 3) + _textDimData[sdx].column; + int y = sd->sy + (pc98PrintFlag ? (_textDimData[sdx].line << 3) : (fh * _textDimData[sdx].line)); + int w = sd->w << 3; + int lw = _lineWidth; + int s = _numCharsLeft; + char c = 0; + + if (pc98PrintFlag) { + bool ct = true; + + if ((lw + _textDimData[sdx].column) > w) { + if ((lines - 1 - (_waitButtonSpace << 1)) <= _lineCount) + // cut off line to leave space for "MORE" button + w -= vm()->_waitButtonReverveW; + } else { + if (!_sjisLineBreakFlag || (_lineCount + 1 < lines - 1)) + ct = false; + else + // cut off line to leave space for "MORE" button + w -= vm()->_waitButtonReverveW; + } + + if (ct) { + w -= _textDimData[sdx].column; + + int n2 = 0; + int n1 = (w / 4) - 1; + + while (n2 < n1 && n2 < s) { + c = str[n2]; + uint8 cu = (uint8) c; + if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) + n2++; + n2++; + } + s = n2; + } + } else { + if ((lw + _textDimData[sdx].column) > w) { + if ((lines - 1) <= _lineCount && _allowPageBreak) + // cut off line to leave space for "MORE" button + w -= vm()->_waitButtonReverveW; + + w -= _textDimData[sdx].column; + + int n2 = 0; + int n1 = s - 1; + + while (n1 > 0) { + //cut off line after last space + c = str[n1]; + + lw -= _screen->getCharWidth((uint8)c); + + if (!n2 && lw <= w) + n2 = n1; + + if (n2 && c == ' ') { + s = n1; + _printFlag = false; + break; + } + n1--; + } + + if (!n1) { + if (_textDimData[sdx].column && !_printFlag) { + s = lw = 0; + _printFlag = true; + } else { + s = n2; + } + } + } + } + + c = str[s]; + str[s] = 0; + + uint8 col = _textDimData[sdx].color1; + if (isPc98 && (sdx == 2 || sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) { + switch (_textDimData[sdx].color1) { + case 0x88: + col = 0x41; + break; + case 0x55: + col = 0x81; + break; + case 0xaa: + col = 0x21; + break; + case 0x99: + col = 0xa1; + break; + case 0x33: + col = 0xe1; + break; + case 0x18: + col = 0x61; + break; + default: + col = 1; + break; + } + _screen->printText(str, x1 & ~3, (y + 8) & ~7, col, 0); + } else { + _screen->printText(str, x1, y, col, _textDimData[sdx].color2); + } + + _textDimData[sdx].column += lw; + _numCharsPrinted += strlen(str); + + str[s] = c; + + if (c == ' ') + s++; + + if (str[s] == ' ') + s++; + + uint32 len = strlen(&str[s]); + for (uint32 i = 0; i < len; i++) + str[i] = str[s + i]; + str[len] = 0; + + _numCharsLeft = strlen(str); + _lineWidth = pc98PrintFlag ? (_numCharsLeft << 2) : _screen->getTextWidth(str); + + if (!_numCharsLeft && _textDimData[sdx].column < (sd->w << 3)) + return; + + _textDimData[sdx].column = 0; + _textDimData[sdx].line++; + _lineCount++; + + printLine(str); +} + +void TextDisplayer_rpg::printDialogueText(int stringId, const char *pageBreakString) { + 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); + + displayText(_dialogueBuffer); + + if (pageBreakString) { + if (pageBreakString[0]) { + strcpy(_pageBreakString, pageBreakString); + displayWaitButton(); + resetPageBreakString(); + } + } +} + +void TextDisplayer_rpg::printDialogueText(const char *str, bool wait) { + assert (strlen(str) < kEobTextBufferSize); + Common::strlcpy(_dialogueBuffer, str, kEobTextBufferSize); + + strcpy(_dialogueBuffer, str); + displayText(_dialogueBuffer); + if (wait) + displayWaitButton(); +} + +void TextDisplayer_rpg::printMessage(const char *str, int textColor, ...) { + int tc = _textDimData[screen()->curDimIndex()].color1; + + if (textColor != -1) + _textDimData[screen()->curDimIndex()].color1 = textColor; + + va_list args; + va_start(args, textColor); + vsnprintf(_dialogueBuffer, kEobTextBufferSize - 1, str, args); + va_end(args); + + displayText(_dialogueBuffer); + + if (vm()->game() != GI_EOB1) + _textDimData[screen()->curDimIndex()].color1 = tc; + + if (!screen()->_curPage) + screen()->updateScreen(); +} + +int TextDisplayer_rpg::clearDim(int dim) { + int res = screen()->curDimIndex(); + screen()->setScreenDim(dim); + _textDimData[dim].color1 = screen()->_curDim->unk8; + _textDimData[dim].color2 = vm()->game() == GI_LOL ? screen()->_curDim->unkA : vm()->_bkgColor_1; + clearCurDim(); + return res; +} + +void TextDisplayer_rpg::clearCurDim() { + int d = screen()->curDimIndex(); + const ScreenDim *tmp = screen()->getScreenDim(d); + if (vm()->gameFlags().use16ColorMode) { + screen()->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 2, (tmp->sy + tmp->h) - 2, _textDimData[d].color2); + } else + screen()->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, _textDimData[d].color2); + + _lineCount = 0; + _textDimData[d].column = _textDimData[d].line = 0; +} + +void TextDisplayer_rpg::textPageBreak() { + if (vm()->game() != GI_LOL) + SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2); + + int cp = _screen->setCurPage(0); + Screen::FontId cf = screen()->setFont(vm()->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT); + + if (vm()->game() == GI_LOL) + vm()->_timer->pauseSingleTimer(11, true); + + vm()->_fadeText = false; + int resetPortraitAfterSpeechAnim = 0; + int updatePortraitSpeechAnimDuration = 0; + + if (vm()->_updateCharNum != -1) { + resetPortraitAfterSpeechAnim = vm()->_resetPortraitAfterSpeechAnim; + vm()->_resetPortraitAfterSpeechAnim = 0; + updatePortraitSpeechAnimDuration = vm()->_updatePortraitSpeechAnimDuration; + if (vm()->_updatePortraitSpeechAnimDuration > 36) + vm()->_updatePortraitSpeechAnimDuration = 36; + } + + uint32 speechPartTime = 0; + if (vm()->speechEnabled() && vm()->_activeVoiceFileTotalTime && _numCharsTotal) + speechPartTime = vm()->_system->getMillis() + ((_numCharsPrinted * vm()->_activeVoiceFileTotalTime) / _numCharsTotal); + + const ScreenDim *dim = screen()->getScreenDim(screen()->curDimIndex()); + + int x = ((dim->sx + dim->w) << 3) - (_vm->_dialogueButtonW + 3); + int y = 0; + int w = vm()->_dialogueButtonW; + + if (vm()->game() == GI_LOL) { + if (vm()->_needSceneRestore && (vm()->_updateFlags & 2)) { + if (vm()->_currentControlMode || !(vm()->_updateFlags & 2)) { + y = dim->sy + dim->h - 5; + } else { + x += 6; + y = dim->sy + dim->h - 2; + } + } else { + y = dim->sy + dim->h - 10; + } + } else { + y = vm()->_waitButtonPresY[_waitButtonMode]; + x = vm()->_waitButtonPresX[_waitButtonMode]; + w = vm()->_waitButtonPresW[_waitButtonMode]; + } + + if (vm()->gameFlags().use16ColorMode) { + vm()->gui_drawBox(x + 8, (y & ~7) - 1, 66, 10, 0xee, 0xcc, -1); + screen()->printText(_pageBreakString, (x + 37 - (strlen(_pageBreakString) << 1) + 4) & ~3, (y + 2) & ~7, 0xc1, 0); + } else { + vm()->gui_drawBox(x, y, w, vm()->_dialogueButtonH, vm()->_color1_1, vm()->_color2_1, vm()->_bkgColor_1); + screen()->printText(_pageBreakString, x + (w >> 1) - (vm()->screen()->getTextWidth(_pageBreakString) >> 1), y + 2, vm()->_dialogueButtonLabelCol1, 0); + } + + vm()->removeInputTop(); + + bool loop = true; + bool target = false; + + do { + int inputFlag = vm()->checkInput(0, false) & 0xFF; + vm()->removeInputTop(); + + while (!inputFlag && !_vm->shouldQuit()) { + vm()->update(); + + if (vm()->speechEnabled()) { + if (((vm()->_system->getMillis() > speechPartTime) || (vm()->snd_updateCharacterSpeech() != 2)) && speechPartTime) { + loop = false; + inputFlag = vm()->_keyMap[Common::KEYCODE_RETURN]; + break; + } + } + + inputFlag = vm()->checkInput(0, false) & 0xFF; + vm()->removeInputTop(); + } + + vm()->gui_notifyButtonListChanged(); + + if (inputFlag == vm()->_keyMap[Common::KEYCODE_SPACE] || inputFlag == vm()->_keyMap[Common::KEYCODE_RETURN]) { + loop = false; + } else if (inputFlag == 199 || inputFlag == 201) { + if (vm()->posWithinRect(vm()->_mouseX, vm()->_mouseY, x, y, x + w, y + 9)) { + if (_vm->game() == GI_LOL) + target = true; + else + loop = false; + } + } else if (inputFlag == 200 || inputFlag == 202) { + if (target) + loop = false; + } + } while (loop && !_vm->shouldQuit()); + + if (vm()->gameFlags().use16ColorMode) + screen()->fillRect(x + 8, y, x + 57, y + 9, _textDimData[screen()->curDimIndex()].color2); + else + screen()->fillRect(x, y, x + w - 1, y + 8, _textDimData[screen()->curDimIndex()].color2); + + clearCurDim(); + _screen->updateScreen(); + + if (vm()->game() == GI_LOL) + vm()->_timer->pauseSingleTimer(11, false); + + if (vm()->_updateCharNum != -1) { + vm()->_resetPortraitAfterSpeechAnim = resetPortraitAfterSpeechAnim; + if (updatePortraitSpeechAnimDuration > 36) + updatePortraitSpeechAnimDuration -= 36; + else + updatePortraitSpeechAnimDuration >>= 1; + + vm()->_updatePortraitSpeechAnimDuration = updatePortraitSpeechAnimDuration; + } + + screen()->setFont(cf); + screen()->setCurPage(cp); + + if (vm()->game() != GI_LOL) + SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2); + + vm()->removeInputTop(); +} + +void TextDisplayer_rpg::displayWaitButton() { + vm()->_dialogueNumButtons = 1; + vm()->_dialogueButtonString[0] = _pageBreakString; + vm()->_dialogueButtonString[1] = 0; + vm()->_dialogueButtonString[2] = 0; + vm()->_dialogueHighlightedButton = 0; + + vm()->_dialogueButtonPosX = &vm()->_waitButtonPresX[_waitButtonMode]; + vm()->_dialogueButtonPosY = &vm()->_waitButtonPresY[_waitButtonMode]; + vm()->_dialogueButtonW = vm()->_waitButtonPresW[_waitButtonMode]; + vm()->_dialogueButtonYoffs = 0; + + SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2); + vm()->drawDialogueButtons(); + + if (!vm()->shouldQuit()) + vm()->removeInputTop(); + + while (!vm()->processDialogue() && !vm()->shouldQuit()) {} + + _screen->fillRect(vm()->_dialogueButtonPosX[0], vm()->_dialogueButtonPosY[0], vm()->_dialogueButtonPosX[0] + vm()->_dialogueButtonW - 1, vm()->_dialogueButtonPosY[0] + vm()->_dialogueButtonH - 1, vm()->_bkgColor_1); + _screen->updateScreen(); + vm()->_dialogueButtonW = 95; + SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2); + clearCurDim(); +} + +} // End of namespace Kyra + +#endif // (ENABLE_EOB || ENABLE_LOL) diff --git a/engines/kyra/text_rpg.h b/engines/kyra/text_rpg.h new file mode 100644 index 0000000000..fcafcc0f4d --- /dev/null +++ b/engines/kyra/text_rpg.h @@ -0,0 +1,115 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are to numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#if defined(ENABLE_EOB) || defined(ENABLE_LOL) + +#ifndef KYRA_TEXT_EOB_H +#define KYRA_TEXT_EOB_H + +#include "common/scummsys.h" + +namespace Kyra { + +class Screen; +class KyraRpgEngine; + +class TextDisplayer_rpg { +public: + TextDisplayer_rpg(KyraRpgEngine *engine, Screen *sScreen); + virtual ~TextDisplayer_rpg(); + + virtual void setupField(int dim, bool mode); + + void printDialogueText(int stringId, const char *pageBreakString); + void printDialogueText(const char *str, bool wait = false); + void printMessage(const char *str, int textColor = -1, ...); + + int clearDim(int dim); + void clearCurDim(); + + void resetDimTextPositions(int dim); + void resetPageBreakString(); + void setPageBreakFlag(); + void removePageBreakFlag(); + + void allowPageBreak(bool mode) { _allowPageBreak = mode; } + void setWaitButtonMode(int mode) { _waitButtonMode = mode; } + int lineCount() { return _lineCount; } + +protected: + virtual KyraRpgEngine *vm() { return _vm; } + virtual Screen *screen() { return _screen; } + + void displayText(char *str, ...); + char parseCommand(); + void readNextPara(); + void printLine(char *str); + virtual void textPageBreak(); + void displayWaitButton(); + + char *_dialogueBuffer; + + char *_tempString1; + char *_tempString2; + char *_currentLine; + char _ctrl[3]; + + uint16 _lineWidth; + uint32 _numCharsTotal; + uint32 _numCharsLeft; + uint32 _numCharsPrinted; + + bool _printFlag; + bool _sjisLineBreakFlag; + + char _pageBreakString[20]; + char _scriptParaString[11]; + int _lineCount; + + bool _allowPageBreak; + int _waitButtonSpace; + int _waitButtonMode; + + static const char _pageBreakDefault[3][5]; + + struct TextDimData { + uint8 color1; + uint8 color2; + uint16 column; + uint8 line; + }; + + TextDimData *_textDimData; + +private: + KyraRpgEngine *_vm; + Screen *_screen; + + char *_table1; + char *_table2; +}; + +} // End of namespace Kyra + +#endif + +#endif // ENABLE_EOB || ENABLE_LOL diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp index 3b56b793d5..b80563bd11 100644 --- a/engines/kyra/timer_eob.cpp +++ b/engines/kyra/timer_eob.cpp @@ -20,74 +20,11 @@ * */ -#if defined(ENABLE_EOB) || defined(ENABLE_LOL) - #include "kyra/eobcommon.h" #include "kyra/timer.h" #include "common/system.h" -namespace Kyra { - -void LolEobBaseEngine::enableSysTimer(int sysTimer) { - if (sysTimer != 2) - return; - - for (int i = 0; i < getNumClock2Timers(); i++) - _timer->pauseSingleTimer(getClock2Timer(i), false); -} - -void LolEobBaseEngine::disableSysTimer(int sysTimer) { - if (sysTimer != 2) - return; - - for (int i = 0; i < getNumClock2Timers(); i++) - _timer->pauseSingleTimer(getClock2Timer(i), true); -} - -void LolEobBaseEngine::enableTimer(int id) { - _timer->enable(id); - _timer->setCountdown(id, _timer->getDelay(id)); -} - -void LolEobBaseEngine::timerProcessDoors(int timerNum) { - for (int i = 0; i < 3; i++) { - uint16 b = _openDoorState[i].block; - if (!b) - continue; - - int v = _openDoorState[i].state; - int c = _openDoorState[i].wall; - - _levelBlockProperties[b].walls[c] += v; - _levelBlockProperties[b].walls[c ^ 2] += v; - - int snd = 3; - int flg = _wllWallFlags[_levelBlockProperties[b].walls[c]]; - if (flg & 0x20) - snd = 5; - else if (v == -1) - snd = 4; - - if (_flags.gameID == GI_LOL) { - if (!(_updateFlags & 1)) { - snd_processEnvironmentalSoundEffect(snd + 28, b); - if (!checkSceneUpdateNeed(b)) - updateEnvironmentalSfx(0); - } - } else { - checkSceneUpdateNeed(b); - updateEnvironmentalSfx(snd); - } - - if (flg & 0x30) - _openDoorState[i].block = 0; - } -} - -} // namespace Kyra - -#endif #ifdef ENABLE_EOB namespace Kyra { @@ -370,7 +307,7 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) { _screen->setScreenDim(od); _screen->setFont(of); - } + } uint32 nextTimer = 0xffffffff; for (int i = 0; i < 10; i++) { diff --git a/engines/kyra/timer_rpg.cpp b/engines/kyra/timer_rpg.cpp new file mode 100644 index 0000000000..02c2669436 --- /dev/null +++ b/engines/kyra/timer_rpg.cpp @@ -0,0 +1,90 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#if defined(ENABLE_EOB) || defined(ENABLE_LOL) + +#include "kyra/kyra_rpg.h" +#include "kyra/timer.h" + +#include "common/system.h" + +namespace Kyra { + +void KyraRpgEngine::enableSysTimer(int sysTimer) { + if (sysTimer != 2) + return; + + for (int i = 0; i < getNumClock2Timers(); i++) + _timer->pauseSingleTimer(getClock2Timer(i), false); +} + +void KyraRpgEngine::disableSysTimer(int sysTimer) { + if (sysTimer != 2) + return; + + for (int i = 0; i < getNumClock2Timers(); i++) + _timer->pauseSingleTimer(getClock2Timer(i), true); +} + +void KyraRpgEngine::enableTimer(int id) { + _timer->enable(id); + _timer->setCountdown(id, _timer->getDelay(id)); +} + +void KyraRpgEngine::timerProcessDoors(int timerNum) { + for (int i = 0; i < 3; i++) { + uint16 b = _openDoorState[i].block; + if (!b) + continue; + + int v = _openDoorState[i].state; + int c = _openDoorState[i].wall; + + _levelBlockProperties[b].walls[c] += v; + _levelBlockProperties[b].walls[c ^ 2] += v; + + int snd = 3; + int flg = _wllWallFlags[_levelBlockProperties[b].walls[c]]; + if (flg & 0x20) + snd = 5; + else if (v == -1) + snd = 4; + + if (_flags.gameID == GI_LOL) { + if (!(_updateFlags & 1)) { + snd_processEnvironmentalSoundEffect(snd + 28, b); + if (!checkSceneUpdateNeed(b)) + updateEnvironmentalSfx(0); + } + } else { + checkSceneUpdateNeed(b); + updateEnvironmentalSfx(snd); + } + + if (flg & 0x30) + _openDoorState[i].block = 0; + } +} + +} // namespace Kyra + +#endif -- cgit v1.2.3