mirror of
https://github.com/libretro/scummvm.git
synced 2024-11-27 03:10:37 +00:00
KYRA: (EOB) - initial code base commit
This commit is contained in:
parent
9feb674e11
commit
540d081a6f
3
configure
vendored
3
configure
vendored
@ -94,8 +94,9 @@ add_engine gob "Gobli*ns" yes
|
||||
add_engine groovie "Groovie" yes "groovie2"
|
||||
add_engine groovie2 "Groovie 2 games" no
|
||||
add_engine hugo "Hugo Trilogy" yes
|
||||
add_engine kyra "Legend of Kyrandia" yes "lol"
|
||||
add_engine kyra "Legend of Kyrandia" yes "lol eob"
|
||||
add_engine lol "Lands of Lore" yes
|
||||
add_engine eob "Eye of the Beholder" no
|
||||
add_engine lastexpress "The Last Express" no
|
||||
add_engine lure "Lure of the Temptress" yes
|
||||
add_engine made "MADE" yes
|
||||
|
@ -87,6 +87,10 @@ MODULES += engines/kyra
|
||||
ifdef ENABLE_LOL
|
||||
DEFINES += -DENABLE_LOL
|
||||
endif
|
||||
|
||||
ifdef ENABLE_EOB
|
||||
DEFINES += -DENABLE_EOB
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef ENABLE_LASTEXPRESS
|
||||
|
1495
engines/kyra/chargen.cpp
Normal file
1495
engines/kyra/chargen.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -17,12 +17,15 @@
|
||||
* 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/kyra_lok.h"
|
||||
#include "kyra/lol.h"
|
||||
#include "kyra/kyra_hof.h"
|
||||
#include "kyra/kyra_mr.h"
|
||||
#include "kyra/eob1.h"
|
||||
#include "kyra/eob2.h"
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/system.h"
|
||||
@ -129,6 +132,14 @@ bool KyraMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame
|
||||
*engine = new Kyra::LoLEngine(syst, flags);
|
||||
break;
|
||||
#endif // ENABLE_LOL
|
||||
#ifdef ENABLE_EOB
|
||||
case Kyra::GI_EOB1:
|
||||
*engine = new Kyra::EobEngine(syst, flags);
|
||||
break;
|
||||
case Kyra::GI_EOB2:
|
||||
*engine = new Kyra::DarkMoonEngine(syst, flags);
|
||||
break;
|
||||
#endif // ENABLE_EOB
|
||||
default:
|
||||
res = false;
|
||||
warning("Kyra engine: unknown gameID");
|
||||
|
@ -57,6 +57,9 @@ namespace {
|
||||
#define LOL_DEMO_FLAGS FLAGS(true, true, false, false, false, false, false, false, Kyra::GI_LOL)
|
||||
#define LOL_KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
|
||||
|
||||
#define EOB_FLAGS FLAGS(false, false, false, false, false, false, false, false, Kyra::GI_EOB1)
|
||||
#define EOB2_FLAGS FLAGS(false, false, false, false, false, false, false, false, Kyra::GI_EOB2)
|
||||
|
||||
const KYRAGameDescription adGameDescs[] = {
|
||||
/* disable these targets until they get supported
|
||||
{
|
||||
@ -1439,6 +1442,73 @@ const KYRAGameDescription adGameDescs[] = {
|
||||
LOL_KYRA2_DEMO_FLAGS
|
||||
},
|
||||
#endif // ENABLE_LOL
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
{
|
||||
{
|
||||
"eob",
|
||||
0,
|
||||
{
|
||||
{ "EOBDATA2.PAK", 0, "feaf0345086b3a1d931352f4b0ad8feb", -1 },
|
||||
{ 0, 0, 0, 0 }
|
||||
},
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformPC,
|
||||
ADGF_NO_FLAGS,
|
||||
GUIO3(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK)
|
||||
},
|
||||
EOB_FLAGS
|
||||
},
|
||||
|
||||
{
|
||||
{
|
||||
"eob",
|
||||
0,
|
||||
{
|
||||
{ "SHINDIA.CPS", 0, "383b0c7ba0903eae5d04cad28ce90aaf", -1 },
|
||||
{ 0, 0, 0, 0 }
|
||||
},
|
||||
Common::DE_DEU,
|
||||
Common::kPlatformPC,
|
||||
ADGF_NO_FLAGS,
|
||||
GUIO3(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK)
|
||||
},
|
||||
EOB_FLAGS
|
||||
},
|
||||
|
||||
{
|
||||
{
|
||||
"eob2",
|
||||
0,
|
||||
{
|
||||
{ "LEVEL15.INF", 0, "10f19eab75c73d0476dc58bcf70fff7a", -1 },
|
||||
{ 0, 0, 0, 0 }
|
||||
},
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformPC,
|
||||
ADGF_NO_FLAGS,
|
||||
GUIO3(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK)
|
||||
},
|
||||
EOB2_FLAGS
|
||||
},
|
||||
|
||||
{
|
||||
{
|
||||
"eob2",
|
||||
0,
|
||||
{
|
||||
{ "LEVEL15.INF", 0, "ce54243ad1ca4447f521340428da2c91", -1 },
|
||||
{ 0, 0, 0, 0 }
|
||||
},
|
||||
Common::DE_DEU,
|
||||
Common::kPlatformPC,
|
||||
ADGF_NO_FLAGS,
|
||||
GUIO3(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK)
|
||||
},
|
||||
EOB2_FLAGS
|
||||
},
|
||||
#endif // ENABLE_EOB
|
||||
|
||||
{ AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0) }
|
||||
};
|
||||
|
||||
@ -1449,6 +1519,10 @@ const PlainGameDescriptor gameList[] = {
|
||||
#ifdef ENABLE_LOL
|
||||
{ "lol", "Lands of Lore: The Throne of Chaos" },
|
||||
#endif // ENABLE_LOL
|
||||
#ifdef ENABLE_EOB
|
||||
{ "eob", "Eye of the Beholder" },
|
||||
{ "eob2", "Eye of the Beholder II: The Legend of Darkmoon" },
|
||||
#endif // ENABLE_EOB
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
242
engines/kyra/eob1.cpp
Normal file
242
engines/kyra/eob1.cpp
Normal file
@ -0,0 +1,242 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#include "kyra/eob1.h"
|
||||
#include "kyra/resource.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
EobEngine::EobEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
|
||||
_numSpells = 53;
|
||||
}
|
||||
|
||||
EobEngine::~EobEngine() {
|
||||
delete[] _itemsOverlay;
|
||||
}
|
||||
|
||||
Common::Error EobEngine::init() {
|
||||
Common::Error err = EobCoreEngine::init();
|
||||
if (err.getCode() != Common::kNoError)
|
||||
return err;
|
||||
|
||||
initStaticResource();
|
||||
|
||||
_itemsOverlay = _res->fileData("ITEMRMP.VGA", 0);
|
||||
|
||||
_bkgColor_1 = 132;
|
||||
_color1_1 = 135;
|
||||
_color2_1 = 130;
|
||||
_color4 = 133;
|
||||
_color5 = 133;
|
||||
_color6 = 180;
|
||||
_color7 = 177;
|
||||
_color8 = 184;
|
||||
|
||||
_color14 = _color8;
|
||||
_color13 = _color7;
|
||||
_color12 = _color6;
|
||||
|
||||
_screen->modifyScreenDim(7, 0x01, 0xB3, 0x22, 0x12);
|
||||
_screen->modifyScreenDim(9, 0x01, 0x7D, 0x26, 0x3F);
|
||||
_screen->modifyScreenDim(12, 0x01, 0x04, 0x14, 0xA0);
|
||||
|
||||
_scriptTimersCount = 1;
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
void EobEngine::startupNew() {
|
||||
_currentLevel = 1;
|
||||
_currentSub = 0;
|
||||
loadLevel(1, 0);
|
||||
_currentBlock = 490;
|
||||
_currentDirection = 0;
|
||||
setHandItem(0);
|
||||
}
|
||||
|
||||
void EobEngine::startupLoad() {
|
||||
updateHandItemCursor();
|
||||
loadLevel(_currentLevel, _currentSub);
|
||||
_saveLoadMode = 0;
|
||||
}
|
||||
|
||||
void EobEngine::npcSequence(int npcIndex) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void EobEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
|
||||
EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
|
||||
if (itm->type == 48) {
|
||||
int charges = itm->flags & 0x3f;
|
||||
if (--charges)
|
||||
--itm->flags;
|
||||
else
|
||||
deleteInventoryItem(charIndex, slot);
|
||||
} else if (itm->type == 34 || itm->type == 35) {
|
||||
deleteInventoryItem(charIndex, slot);
|
||||
}
|
||||
}
|
||||
|
||||
void EobEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
|
||||
if (_levelBlockProperties[block].flags & 7)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (_monsters[i].hitPointsCur <= 0) {
|
||||
initMonster(i, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EobEngine::loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {
|
||||
_screen->loadEobBitmap("DOOR", 5, 3);
|
||||
_screen->_curPage = 2;
|
||||
|
||||
if (doorType1 != 0xff) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
const uint8 *enc = &_doorShapeEncodeDefs[(doorType1 * 3 + i) << 2];
|
||||
_doorShapes[shapeId1 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
|
||||
enc = &_doorSwitchShapeEncodeDefs[(doorType1 * 3 + i) << 2];
|
||||
_doorSwitches[shapeId1 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
|
||||
_doorSwitches[shapeId1 + i].x = _doorSwitchCoords[doorType1 << 1];
|
||||
_doorSwitches[shapeId1 + i].y = _doorSwitchCoords[(doorType1 << 1) + 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (doorType2 != 0xff) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
const uint8 *enc = &_doorShapeEncodeDefs[(doorType2 * 3 + i) << 2];
|
||||
_doorShapes[shapeId2 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
|
||||
enc = &_doorSwitchShapeEncodeDefs[(doorType2 * 3 + i) << 2];
|
||||
_doorSwitches[shapeId2 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
|
||||
_doorSwitches[shapeId2 + i].x = _doorSwitchCoords[doorType2 << 1];
|
||||
_doorSwitches[shapeId2 + i].y = _doorSwitchCoords[(doorType2 << 1) + 1];
|
||||
}
|
||||
}
|
||||
|
||||
_screen->_curPage = 0;
|
||||
}
|
||||
|
||||
void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2) {
|
||||
int shapeIndex = type + 2 - mDim;
|
||||
uint8 *shp = _doorShapes[shapeIndex];
|
||||
|
||||
int d1 = 0;
|
||||
int d2 = 0;
|
||||
int v = 0;
|
||||
const ScreenDim *td = _screen->getScreenDim(5);
|
||||
|
||||
switch (_currentLevel) {
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
y = _dscDoorY2[mDim] - shp[1];
|
||||
d1 = _dscDoorCoordsExt[index << 1] >> 3;
|
||||
d2 = _dscDoorCoordsExt[(index << 1) + 1] >> 3;
|
||||
if (_shpDmX1 > d1)
|
||||
d1 = _shpDmX1;
|
||||
if (_shpDmX2 < d2)
|
||||
d2 = _shpDmX2;
|
||||
_screen->modifyScreenDim(5, d1, td->sy, d2 - d1, td->h);
|
||||
v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult3[mDim] : _dscDoorScaleMult4[mDim]) * -1;
|
||||
v -= (shp[2] << 3);
|
||||
drawBlockObject(0, 2, shp, x + v, y, 5);
|
||||
v += (shp[2] << 3);
|
||||
drawBlockObject(1, 2, shp, x - v, y, 5);
|
||||
if (_wllShapeMap[wall] == -1)
|
||||
drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w - v, _doorSwitches[shapeIndex].y, 5);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
y = _dscDoorY3[mDim] - _doorShapes[shapeIndex + 3][1];
|
||||
d1 = x - (_doorShapes[shapeIndex + 3][2] << 2);
|
||||
x -= (shp[2] << 2);
|
||||
drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], d1, y, 5);
|
||||
scaleLevelShapesDim(index, y1, y2, 5);
|
||||
y = _dscDoorY3[mDim] - ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim] : _dscDoorScaleMult2[mDim]);
|
||||
drawBlockObject(0, 2, shp, x, y, 5);
|
||||
if (_wllShapeMap[wall] == -1)
|
||||
drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
case 11:
|
||||
v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult5[mDim] : _dscDoorScaleMult6[mDim]) * -1;
|
||||
x -= (shp[2] << 2);
|
||||
y = _dscDoorY3[mDim] + v;
|
||||
drawBlockObject(0, 2, shp, x, y + v, 5);
|
||||
v >>= 4;
|
||||
y = _dscDoorY5[mDim];
|
||||
drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], x, y - v, 5);
|
||||
if (_wllShapeMap[wall] == -1)
|
||||
drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
|
||||
break;
|
||||
|
||||
default:
|
||||
y = (_currentLevel == 12 ? _dscDoorY6[mDim] : _dscDoorY1[mDim]) - shp[1];
|
||||
x -= (shp[2] << 2);
|
||||
y -= (wall >= 30 ? _dscDoorScaleMult2[mDim] : (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim]);
|
||||
drawBlockObject(0, 2, shp, x, y, 5);
|
||||
|
||||
if (_wllShapeMap[wall] == -1)
|
||||
drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 EobEngine::convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility) {
|
||||
uint32 res = 0;
|
||||
if (flag & 0x01)
|
||||
res |= 0x20;
|
||||
if (flag & 0x02)
|
||||
res |= 0x400;
|
||||
if (flag & 0x04)
|
||||
res |= 0x80;
|
||||
if (flag & 0x08)
|
||||
res |= 0x40;
|
||||
if (ignoreInvisibility)
|
||||
res |= 0x100;
|
||||
return res;
|
||||
}
|
||||
|
||||
uint32 EobEngine::convertCharacterEffectFlagToEob2Format(uint32 flag) {
|
||||
uint32 res = 0;
|
||||
if (flag & 0x02)
|
||||
res |= 0x08;
|
||||
if (flag & 0x04)
|
||||
res |= 0x40;
|
||||
if (flag & 0x80)
|
||||
res |= 0x2000;
|
||||
if (flag & 0x100)
|
||||
res |= 0x4000;
|
||||
return res;
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
96
engines/kyra/eob1.h
Normal file
96
engines/kyra/eob1.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#ifndef KYRA_EOB1_H
|
||||
#define KYRA_EOB1_H
|
||||
|
||||
#include "kyra/eobcommon.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
class EobEngine : public EobCoreEngine {
|
||||
friend class GUI_Eob;
|
||||
public:
|
||||
EobEngine(OSystem *system, const GameFlags &flags);
|
||||
~EobEngine();
|
||||
|
||||
private:
|
||||
// Init / Release
|
||||
Common::Error init();
|
||||
void initStaticResource();
|
||||
void initSpells();
|
||||
|
||||
// Main Menu
|
||||
int mainMenu();
|
||||
int mainMenuLoop();
|
||||
|
||||
// Main loop
|
||||
void startupNew();
|
||||
void startupLoad();
|
||||
|
||||
// Intro/Outro
|
||||
void seq_playOpeningCredits();
|
||||
void seq_playIntro();
|
||||
void seq_playFinale();
|
||||
|
||||
// characters
|
||||
void npcSequence(int npcIndex);
|
||||
|
||||
//const char *const *_npc1Strings;
|
||||
//const char *const *_npc2Strings;
|
||||
|
||||
// items
|
||||
void updateUsedCharacterHandItem(int charIndex, int slot);
|
||||
|
||||
// Monsters
|
||||
void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
|
||||
|
||||
// Level
|
||||
void loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2);
|
||||
void drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2);
|
||||
|
||||
const int16 *_dscDoorCoordsExt;
|
||||
const uint8 *_dscDoorScaleMult4;
|
||||
const uint8 *_dscDoorScaleMult5;
|
||||
const uint8 *_dscDoorScaleMult6;
|
||||
const uint8 *_dscDoorY3;
|
||||
const uint8 *_dscDoorY4;
|
||||
const uint8 *_dscDoorY5;
|
||||
const uint8 *_dscDoorY6;
|
||||
|
||||
const uint8 *_doorShapeEncodeDefs;
|
||||
const uint8 *_doorSwitchShapeEncodeDefs;
|
||||
const uint8 *_doorSwitchCoords;
|
||||
|
||||
// Misc
|
||||
uint32 convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility);
|
||||
uint32 convertCharacterEffectFlagToEob2Format(uint32 flag);
|
||||
};
|
||||
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_EOB
|
437
engines/kyra/eob2.cpp
Normal file
437
engines/kyra/eob2.cpp
Normal file
@ -0,0 +1,437 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#include "kyra/eob2.h"
|
||||
#include "kyra/resource.h"
|
||||
#include "kyra/sound.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
DarkMoonEngine::DarkMoonEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
|
||||
_seqIntro = _seqFinale = 0;
|
||||
_shapesIntro = _shapesFinale = 0;
|
||||
_dscDoorType5Offs = 0;
|
||||
_numSpells = 70;
|
||||
}
|
||||
|
||||
DarkMoonEngine::~DarkMoonEngine() {
|
||||
delete[] _seqIntro;
|
||||
delete[] _seqFinale;
|
||||
delete[] _shapesIntro;
|
||||
delete[] _shapesFinale;
|
||||
}
|
||||
|
||||
Common::Error DarkMoonEngine::init() {
|
||||
Common::Error err = EobCoreEngine::init();
|
||||
if (err.getCode() != Common::kNoError)
|
||||
return err;
|
||||
|
||||
initStaticResource();
|
||||
|
||||
_monsterProps = new EobMonsterProperty[10];
|
||||
|
||||
_bkgColor_1 = 183;
|
||||
_color1_1 = 186;
|
||||
_color2_1 = 181;
|
||||
_color4 = 133;
|
||||
_color5 = 184;
|
||||
_color6 = 183;
|
||||
_color7 = 181;
|
||||
_color8 = 186;
|
||||
_color12 = 180;
|
||||
_color13 = 177;
|
||||
_color14 = 182;
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
void DarkMoonEngine::startupNew() {
|
||||
_currentLevel = 4;
|
||||
_currentSub = 0;
|
||||
loadLevel(4, 0);
|
||||
_currentBlock = 171;
|
||||
_currentDirection = 2;
|
||||
setHandItem(0);
|
||||
}
|
||||
|
||||
void DarkMoonEngine::startupLoad() {
|
||||
updateHandItemCursor();
|
||||
loadLevel(_currentLevel, _currentSub);
|
||||
_saveLoadMode = 0;
|
||||
}
|
||||
|
||||
void DarkMoonEngine::npcSequence(int npcIndex) {
|
||||
_screen->loadEobBitmap("OUTTAKE", 5, 3);
|
||||
_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
|
||||
const uint8 *shpDef = &_npcShpData[npcIndex << 3];
|
||||
|
||||
for (int i = npcIndex; i != 255; i = shpDef[7]) {
|
||||
shpDef = &_npcShpData[i << 3];
|
||||
_screen->_curPage = 2;
|
||||
const uint8 *shp = _screen->encodeShape(READ_LE_UINT16(shpDef), shpDef[2], shpDef[3], shpDef[4]);
|
||||
_screen->_curPage = 0;
|
||||
_screen->drawShape(0, shp, 88 + shpDef[5] - (shp[2] << 2), 104 + shpDef[6] - shp[1], 5);
|
||||
delete[] shp;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
|
||||
_screen->loadFileDataToPage(s, 5, 32000);
|
||||
delete s;
|
||||
|
||||
gui_drawBox(0, 121, 320, 79, _color1_1, _color2_1, _bkgColor_1);
|
||||
_txt->setupField(9, true);
|
||||
_txt->resetPageBreakString();
|
||||
|
||||
if (npcIndex == 0) {
|
||||
snd_playSoundEffect(57);
|
||||
if (npcJoinDialogue(0, 1, 3, 2))
|
||||
setScriptFlag(0x40);
|
||||
} else if (npcIndex == 1) {
|
||||
snd_playSoundEffect(53);
|
||||
gui_drawDialogueBox();
|
||||
|
||||
_txt->printDialogueText(4, 0);
|
||||
int r = runDialogue(-1, 0, _npc1Strings[0], _npc1Strings[1]) - 1;
|
||||
|
||||
if (r == 0) {
|
||||
_sound->playTrack(0);
|
||||
delay(3 * _tickLength);
|
||||
snd_playSoundEffect(91);
|
||||
npcJoinDialogue(1, 5, 6, 7);
|
||||
} else if (r == 1) {
|
||||
setScriptFlag(0x20);
|
||||
}
|
||||
|
||||
} else if (npcIndex == 2) {
|
||||
snd_playSoundEffect(55);
|
||||
gui_drawDialogueBox();
|
||||
|
||||
_txt->printDialogueText(8, 0);
|
||||
int r = runDialogue(-1, 0, _npc2Strings[0], _npc2Strings[1]) - 1;
|
||||
|
||||
if (r == 0) {
|
||||
if (rollDice(1, 2, -1))
|
||||
_txt->printDialogueText(9, _okStrings[0]);
|
||||
else
|
||||
npcJoinDialogue(2, 102, 103, 104);
|
||||
setScriptFlag(8);
|
||||
} else if (r == 1) {
|
||||
_currentDirection = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_txt->removePageBreakFlag();
|
||||
gui_restorePlayField();
|
||||
}
|
||||
|
||||
void DarkMoonEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
|
||||
EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
|
||||
if (itm->type == 48 || itm->type == 62) {
|
||||
if (itm->value == 5)
|
||||
return;
|
||||
int charges = itm->flags & 0x3f;
|
||||
if (--charges)
|
||||
--itm->flags;
|
||||
else
|
||||
deleteInventoryItem(charIndex, slot);
|
||||
} else if (itm->type == 26 || itm->type == 34 || itm->type == 35) {
|
||||
deleteInventoryItem(charIndex, slot);
|
||||
}
|
||||
}
|
||||
|
||||
void DarkMoonEngine::generateMonsterPalettes(const char *file, int16 monsterIndex) {
|
||||
int cp = _screen->setCurPage(2);
|
||||
_screen->loadEobBitmap(file, 3, 3);
|
||||
uint8 tmpPal[16];
|
||||
uint8 newPal[16];
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int dci = monsterIndex + i;
|
||||
memcpy(tmpPal, _monsterShapes[dci] + 4, 16);
|
||||
int colx = 302 + 3 * i;
|
||||
|
||||
for (int ii = 0; ii < 16; ii++) {
|
||||
uint8 col = _screen->getPagePixel(_screen->_curPage, colx, 184 + ii);
|
||||
|
||||
int iii = 0;
|
||||
for (; iii < 16; iii++) {
|
||||
if (tmpPal[iii] == col) {
|
||||
newPal[ii] = iii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (iii == 16)
|
||||
newPal[ii] = 0;
|
||||
}
|
||||
|
||||
for (int ii = 1; ii < 3; ii++) {
|
||||
memcpy(tmpPal, _monsterShapes[dci] + 4, 16);
|
||||
|
||||
for (int iii = 0; iii < 16; iii++) {
|
||||
uint8 col = _screen->getPagePixel(_screen->_curPage, colx + ii, 184 + iii);
|
||||
if (newPal[iii])
|
||||
tmpPal[newPal[iii]] = col;
|
||||
}
|
||||
|
||||
int c = i;
|
||||
if (monsterIndex >= 18)
|
||||
c += 6;
|
||||
|
||||
c = (c << 1) + (ii - 1);
|
||||
memcpy(_monsterPalettes[c], tmpPal, 16);
|
||||
}
|
||||
}
|
||||
|
||||
_screen->setCurPage(cp);
|
||||
}
|
||||
|
||||
void DarkMoonEngine::loadMonsterDecoration(const char *file, int16 monsterIndex) {
|
||||
char filename[13];
|
||||
snprintf(filename, 13, "%s.dcr", file);
|
||||
|
||||
Common::SeekableReadStream *s = _res->createReadStream(filename);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
int len = s->readUint16LE();
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
for (int ii = 0; ii < 6; ii++) {
|
||||
uint8 dc[6];
|
||||
s->read(dc, 6);
|
||||
if (!dc[2] || !dc[3])
|
||||
continue;
|
||||
|
||||
SpriteDecoration *m = &_monsterDecorations[i * 6 + ii + monsterIndex];
|
||||
|
||||
m->shp = _screen->encodeShape(dc[0], dc[1], dc[2], dc[3]);
|
||||
m->x = dc[4];
|
||||
m->y = dc[5];
|
||||
}
|
||||
}
|
||||
|
||||
delete s;
|
||||
}
|
||||
|
||||
void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
|
||||
uint8 flg = _levelBlockProperties[block].flags & 7;
|
||||
|
||||
if (flg == 7 || _currentBlock == block || (flg && (_monsterProps[type].u30 || pos == 4)))
|
||||
return;
|
||||
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (_monsters[i].block != block)
|
||||
continue;
|
||||
if (_monsters[i].pos == 4 || _monsterProps[_monsters[i].type].u30)
|
||||
return;
|
||||
}
|
||||
|
||||
int index = -1;
|
||||
int maxDist = 0;
|
||||
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (_monsters[i].hitPointsCur <= 0) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_monsters[i].flags & 0x40)
|
||||
continue;
|
||||
|
||||
int dist = getBlockDistance(_monsters[i].block, _currentBlock);
|
||||
|
||||
if (dist > maxDist) {
|
||||
maxDist = dist;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
if (_monsters[index].hitPointsCur > 0)
|
||||
killMonster(&_monsters[index], false);
|
||||
|
||||
initMonster(index, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);
|
||||
}
|
||||
|
||||
const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs) {
|
||||
_screen->loadEobBitmap(filename, 3, 3);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
_doorShapes[doorIndex * 3 + i] = _screen->encodeShape(READ_LE_UINT16(shapeDefs), READ_LE_UINT16(shapeDefs + 2), READ_LE_UINT16(shapeDefs + 4), READ_LE_UINT16(shapeDefs + 6));
|
||||
shapeDefs += 8;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
_doorSwitches[doorIndex * 3 + i].shp = _screen->encodeShape(READ_LE_UINT16(shapeDefs), READ_LE_UINT16(shapeDefs + 2), READ_LE_UINT16(shapeDefs + 4), READ_LE_UINT16(shapeDefs + 6));
|
||||
shapeDefs += 8;
|
||||
_doorSwitches[doorIndex * 3 + i].x = *shapeDefs;
|
||||
shapeDefs += 2;
|
||||
_doorSwitches[doorIndex * 3 + i]. y= *shapeDefs;
|
||||
shapeDefs += 2;
|
||||
}
|
||||
_screen->_curPage = 0;
|
||||
return shapeDefs;
|
||||
}
|
||||
|
||||
void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16) {
|
||||
int shapeIndex = type * 3 + 2 - mDim;
|
||||
uint8 *shp = _doorShapes[shapeIndex];
|
||||
|
||||
if ((_doorType[type] == 0) || (_doorType[type] == 1)) {
|
||||
y = _dscDoorY1[mDim] - shp[1];
|
||||
x -= (shp[2] << 2);
|
||||
|
||||
if (_doorType[type] == 1) {
|
||||
drawBlockObject(0, 2, shp, x, y, 5);
|
||||
shp = _doorShapes[3 + shapeIndex];
|
||||
}
|
||||
|
||||
y -= ((wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim]);
|
||||
|
||||
if (_specialWallTypes[wall] == 5)
|
||||
y -= _dscDoorType5Offs[shapeIndex];
|
||||
|
||||
} else if (_doorType[type] == 2) {
|
||||
x -= (shp[2] << 2);
|
||||
y = _dscDoorY2[mDim] - ((wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult3[mDim]);
|
||||
}
|
||||
|
||||
drawBlockObject(0, 2, shp, x, y, 5);
|
||||
|
||||
if (_wllShapeMap[wall] == -1 && !_noDoorSwitch[type])
|
||||
drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
|
||||
}
|
||||
|
||||
void DarkMoonEngine::drawLightningColumn() {
|
||||
int f = rollDice(1, 2, -1);
|
||||
int y = 0;
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
f ^= 1;
|
||||
drawBlockObject(f, 2, _lightningColumnShape, 72, y, 5);
|
||||
y += 64;
|
||||
}
|
||||
}
|
||||
|
||||
int DarkMoonEngine::resurrectionSelectDialogue() {
|
||||
int cnt = 0;
|
||||
const char *namesList[10];
|
||||
memset(namesList, 0, 10 * sizeof(const char*));
|
||||
int8 indexList[10];
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 1))
|
||||
continue;
|
||||
if (_characters[i].hitPointsCur != -10)
|
||||
continue;
|
||||
|
||||
namesList[cnt] = _characters[i].name;
|
||||
indexList[cnt++] = i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 1))
|
||||
continue;
|
||||
|
||||
for (int ii = 0; ii < 27; ii++) {
|
||||
uint16 inv = _characters[i].inventory[ii];
|
||||
if (!inv)
|
||||
continue;
|
||||
|
||||
if (_items[inv].type != 33)
|
||||
continue;
|
||||
|
||||
namesList[cnt] = _npcPreset[_items[inv].value - 1].name;
|
||||
indexList[cnt++] = -_items[inv].value;
|
||||
}
|
||||
}
|
||||
|
||||
if (_itemInHand) {
|
||||
if (_items[_itemInHand].type == 33) {
|
||||
namesList[cnt] = _npcPreset[_items[_itemInHand].value - 1].name;
|
||||
indexList[cnt++] = -_items[_itemInHand].value;
|
||||
}
|
||||
}
|
||||
|
||||
namesList[cnt] = _abortStrings[0];
|
||||
indexList[cnt++] = 99;
|
||||
|
||||
int r = indexList[runDialogue(-1, 1, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6], namesList[7], namesList[8]) - 1];
|
||||
if (r == 99)
|
||||
return 0;
|
||||
|
||||
if (r < 0) {
|
||||
r = -r;
|
||||
if (prepareForNewPartyMember(33, r))
|
||||
initNpc(r - 1);
|
||||
} else {
|
||||
_characters[r].hitPointsCur = 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int DarkMoonEngine::charSelectDialogue() {
|
||||
int cnt = 0;
|
||||
const char *namesList[7];
|
||||
memset(namesList, 0, 7 * sizeof(const char*));
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 3))
|
||||
continue;
|
||||
namesList[cnt++] = _characters[i].name;
|
||||
}
|
||||
|
||||
namesList[cnt++] = _abortStrings[0];
|
||||
|
||||
int r = runDialogue(-1, 1, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6], 0) - 1;
|
||||
if (r == cnt - 1)
|
||||
return 99;
|
||||
|
||||
for (cnt = 0; cnt < 6; cnt++) {
|
||||
if (!testCharacter(cnt, 3))
|
||||
continue;
|
||||
if (--r < 0)
|
||||
break;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void DarkMoonEngine::characterLevelGain(int charIndex) {
|
||||
EobCharacter *c = &_characters[charIndex];
|
||||
int s = _numLevelsPerClass[c->cClass];
|
||||
for (int i = 0; i < s; i++) {
|
||||
uint32 er = getRequiredExperience(c->cClass, i, c->level[i] + 1);
|
||||
if (er == 0xffffffff)
|
||||
continue;
|
||||
|
||||
increaseCharacterExperience(charIndex, er - c->experience[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
119
engines/kyra/eob2.h
Normal file
119
engines/kyra/eob2.h
Normal file
@ -0,0 +1,119 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#ifndef KYRA_EOB2_H
|
||||
#define KYRA_EOB2_H
|
||||
|
||||
#include "kyra/eobcommon.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
class DarkmoonSequenceHelper;
|
||||
|
||||
struct EobSequenceStep {
|
||||
uint8 command;
|
||||
uint8 obj;
|
||||
int16 x1;
|
||||
uint8 y1;
|
||||
uint8 delay;
|
||||
uint8 pal;
|
||||
uint8 x2;
|
||||
uint8 y2;
|
||||
uint8 w;
|
||||
uint8 h;
|
||||
};
|
||||
|
||||
class DarkMoonEngine : public EobCoreEngine {
|
||||
friend class GUI_Eob;
|
||||
friend class DarkmoonSequenceHelper;
|
||||
public:
|
||||
DarkMoonEngine(OSystem *system, const GameFlags &flags);
|
||||
~DarkMoonEngine();
|
||||
|
||||
private:
|
||||
// Init / Release
|
||||
Common::Error init();
|
||||
void initStaticResource();
|
||||
void initSpells();
|
||||
|
||||
// Main Menu
|
||||
int mainMenu();
|
||||
int mainMenuLoop();
|
||||
|
||||
// Main loop
|
||||
void startupNew();
|
||||
void startupLoad();
|
||||
|
||||
// Intro/Outro
|
||||
void seq_playIntro();
|
||||
void seq_playFinale();
|
||||
void seq_playCredits(DarkmoonSequenceHelper *sq, const uint8 *data, int sd, int backupPage, int tempPage, int speed);
|
||||
|
||||
const char * const*_introStrings;
|
||||
const char * const *_cpsFilesIntro;
|
||||
const EobSequenceStep **_seqIntro;
|
||||
const EobShapeDef **_shapesIntro;
|
||||
|
||||
const char * const*_finaleStrings;
|
||||
const uint8 *_creditsData;
|
||||
const char * const *_cpsFilesFinale;
|
||||
const EobSequenceStep **_seqFinale;
|
||||
const EobShapeDef **_shapesFinale;
|
||||
|
||||
static const char *_palFilesIntro[];
|
||||
static const char *_palFilesFinale[];
|
||||
|
||||
// characters
|
||||
void npcSequence(int npcIndex);
|
||||
|
||||
const uint8 *_npcShpData;
|
||||
const char *const *_npc1Strings;
|
||||
const char *const *_npc2Strings;
|
||||
|
||||
// items
|
||||
void updateUsedCharacterHandItem(int charIndex, int slot);
|
||||
|
||||
// Monsters
|
||||
void generateMonsterPalettes(const char *file, int16 monsterIndex);
|
||||
void loadMonsterDecoration(const char *file, int16 monsterIndex);
|
||||
void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
|
||||
|
||||
// Level
|
||||
const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs);
|
||||
void drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16);
|
||||
|
||||
const uint8 *_dscDoorType5Offs;
|
||||
|
||||
// misc
|
||||
void drawLightningColumn();
|
||||
int resurrectionSelectDialogue();
|
||||
int charSelectDialogue();
|
||||
void characterLevelGain(int charIndex);
|
||||
};
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_EOB
|
1845
engines/kyra/eobcommon.cpp
Normal file
1845
engines/kyra/eobcommon.cpp
Normal file
File diff suppressed because it is too large
Load Diff
977
engines/kyra/eobcommon.h
Normal file
977
engines/kyra/eobcommon.h
Normal file
@ -0,0 +1,977 @@
|
||||
/* 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_EOBCOMMON_H
|
||||
#define KYRA_EOBCOMMON_H
|
||||
|
||||
#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
|
||||
#include "kyra/loleobbase.h"
|
||||
#endif // (ENABLE_EOB || ENABLE_LOL)
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
struct EobShapeDef {
|
||||
int16 index;
|
||||
uint8 x, y, w, h;
|
||||
};
|
||||
|
||||
struct CreatePartyModButton {
|
||||
uint8 encodeLabelX;
|
||||
uint8 encodeLabelY;
|
||||
uint8 labelW;
|
||||
uint8 labelH;
|
||||
uint8 labelX;
|
||||
uint8 labelY;
|
||||
uint8 bodyIndex;
|
||||
uint8 destX;
|
||||
uint8 destY;
|
||||
};
|
||||
|
||||
struct EobRect8 {
|
||||
uint8 x;
|
||||
uint8 y;
|
||||
uint8 w;
|
||||
uint8 h;
|
||||
};
|
||||
|
||||
struct EobRect16 {
|
||||
int16 x1;
|
||||
int16 y1;
|
||||
uint16 x2;
|
||||
uint16 y2;
|
||||
};
|
||||
|
||||
struct EobChargenButtonDef {
|
||||
uint8 x;
|
||||
uint8 y;
|
||||
uint8 w;
|
||||
uint8 h;
|
||||
uint8 keyCode;
|
||||
};
|
||||
|
||||
struct EobGuiButtonDef {
|
||||
uint8 keyCode;
|
||||
uint8 keyCode2;
|
||||
uint16 flags;
|
||||
uint16 x;
|
||||
uint8 y;
|
||||
uint16 w;
|
||||
uint8 h;
|
||||
Button::Callback buttonCallback;
|
||||
uint16 arg;
|
||||
};
|
||||
|
||||
struct EobCharacter {
|
||||
uint8 id;
|
||||
uint8 flags;
|
||||
char name[11];
|
||||
int8 strengthCur;
|
||||
int8 strengthMax;
|
||||
int8 strengthExtCur;
|
||||
int8 strengthExtMax;
|
||||
int8 intelligenceCur;
|
||||
int8 intelligenceMax;
|
||||
int8 wisdomCur;
|
||||
int8 wisdomMax;
|
||||
int8 dexterityCur;
|
||||
int8 dexterityMax;
|
||||
int8 constitutionCur;
|
||||
int8 constitutionMax;
|
||||
int8 charismaCur;
|
||||
int8 charismaMax;
|
||||
int16 hitPointsCur;
|
||||
int16 hitPointsMax;
|
||||
int8 armorClass;
|
||||
uint8 disabledSlots;
|
||||
uint8 raceSex;
|
||||
uint8 cClass;
|
||||
uint8 alignment;
|
||||
int8 portrait;
|
||||
uint8 food;
|
||||
uint8 level[3];
|
||||
uint32 experience[3];
|
||||
uint8 *faceShape;
|
||||
|
||||
int8 mageSpells[80];
|
||||
int8 clericSpells[80];
|
||||
uint32 mageSpellsAvailabilityFlags;
|
||||
|
||||
Item inventory[27];
|
||||
uint32 timers[10];
|
||||
int8 events[10];
|
||||
uint8 effectsRemainder[4];
|
||||
uint32 effectFlags;
|
||||
uint8 damageTaken;
|
||||
int8 slotStatus[5];
|
||||
};
|
||||
|
||||
struct EobItem {
|
||||
uint8 nameUnid;
|
||||
uint8 nameId;
|
||||
uint8 flags;
|
||||
int8 icon;
|
||||
int8 type;
|
||||
int8 pos;
|
||||
int16 block;
|
||||
Item next;
|
||||
Item prev;
|
||||
uint8 level;
|
||||
int8 value;
|
||||
};
|
||||
|
||||
struct EobItemType {
|
||||
uint16 invFlags;
|
||||
uint16 handFlags;
|
||||
int8 armorClass;
|
||||
int8 allowedClasses;
|
||||
int8 requiredHands;
|
||||
int8 dmgNumDiceS;
|
||||
int8 dmgNumPipsS;
|
||||
int8 dmgIncS;
|
||||
int8 dmgNumDiceL;
|
||||
int8 dmgNumPipsL;
|
||||
int8 dmgIncL;
|
||||
uint8 unk1;
|
||||
uint16 extraProperties;
|
||||
};
|
||||
|
||||
struct SpriteDecoration {
|
||||
uint8 *shp;
|
||||
uint8 x;
|
||||
uint8 y;
|
||||
};
|
||||
|
||||
struct EobMonsterProperty {
|
||||
int8 armorClass;
|
||||
int8 hitChance;
|
||||
uint8 level;
|
||||
uint8 hpDcTimes;
|
||||
uint8 hpDcPips;
|
||||
uint8 hpDcBase;
|
||||
uint8 attacksPerRound;
|
||||
struct DmgDc {
|
||||
uint8 times;
|
||||
uint8 pips;
|
||||
int8 base;
|
||||
} dmgDc[3];
|
||||
uint16 statusFlags;
|
||||
uint16 flags;
|
||||
int32 u22;
|
||||
int32 experience;
|
||||
|
||||
uint8 u30;
|
||||
uint8 sound1;
|
||||
uint8 sound2;
|
||||
uint8 numRemoteAttacks;
|
||||
uint8 remoteWeaponChangeMode;
|
||||
uint8 numRemoteWeapons;
|
||||
|
||||
int8 remoteWeapons[5];
|
||||
|
||||
uint8 u41;
|
||||
uint8 dmgModifierEvade;
|
||||
|
||||
uint8 decorations[3];
|
||||
};
|
||||
|
||||
struct EobMonsterInPlay {
|
||||
uint8 type;
|
||||
uint8 unit;
|
||||
uint16 block;
|
||||
uint8 pos;
|
||||
int8 dir;
|
||||
uint8 animStep;
|
||||
uint8 shpIndex;
|
||||
int8 mode;
|
||||
int8 f_9;
|
||||
int8 curAttackFrame;
|
||||
uint8 f_b;
|
||||
int16 hitPointsMax;
|
||||
int16 hitPointsCur;
|
||||
uint16 dest;
|
||||
uint16 randItem;
|
||||
uint16 fixedItem;
|
||||
uint8 flags;
|
||||
uint8 idleAnimState;
|
||||
uint8 curRemoteWeapon;
|
||||
uint8 numRemoteAttacks;
|
||||
int8 palette;
|
||||
uint8 directionChanged;
|
||||
uint8 stepsTillRemoteAttack;
|
||||
uint8 sub;
|
||||
};
|
||||
|
||||
struct ScriptTimer {
|
||||
uint16 func;
|
||||
uint16 ticks;
|
||||
uint32 next;
|
||||
};
|
||||
|
||||
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 EobInfProcessor;
|
||||
|
||||
class EobCoreEngine : public LolEobBaseEngine {
|
||||
friend class TextDisplayer_Eob;
|
||||
friend class GUI_Eob;
|
||||
friend class EobInfProcessor;
|
||||
friend class DarkmoonSequenceHelper;
|
||||
friend class CharacterGenerator;
|
||||
public:
|
||||
EobCoreEngine(OSystem *system, const GameFlags &flags);
|
||||
virtual ~EobCoreEngine();
|
||||
|
||||
Screen *screen() { return _screen; }
|
||||
GUI *gui() const { return _gui; }
|
||||
|
||||
protected:
|
||||
// Startup
|
||||
virtual Common::Error init();
|
||||
Common::Error go();
|
||||
|
||||
// Main Menu, Intro, Finale
|
||||
virtual int mainMenu() = 0;
|
||||
virtual void seq_playFinale() = 0;
|
||||
bool _playFinale;
|
||||
|
||||
//Init
|
||||
void loadItemsAndDecorationsShapes();
|
||||
void releaseItemsAndDecorationsShapes();
|
||||
|
||||
void initButtonData();
|
||||
void initStaticResource();
|
||||
virtual void initSpells();
|
||||
|
||||
const uint8 **_largeItemShapes;
|
||||
const uint8 **_smallItemShapes;
|
||||
const uint8 **_thrownItemShapes;
|
||||
const int _numLargeItemShapes;
|
||||
const int _numSmallItemShapes;
|
||||
const int _numThrownItemShapes;
|
||||
const int _numItemIconShapes;
|
||||
|
||||
const uint8 **_spellShapes;
|
||||
const uint8 **_firebeamShapes;
|
||||
const uint8 *_redSplatShape;
|
||||
const uint8 *_greenSplatShape;
|
||||
const uint8 **_wallOfForceShapes;
|
||||
const uint8 **_teleporterShapes;
|
||||
const uint8 **_sparkShapes;
|
||||
const uint8 *_deadCharShape;
|
||||
const uint8 *_disabledCharGrid;
|
||||
const uint8 *_blackBoxSmallGrid;
|
||||
const uint8 *_weaponSlotGrid;
|
||||
const uint8 *_blackBoxWideGrid;
|
||||
const uint8 *_lightningColumnShape;
|
||||
|
||||
uint8 *_tempIconShape;
|
||||
uint8 *_itemsOverlay;
|
||||
|
||||
static const uint8 _teleporterShapeDefs[];
|
||||
static const uint8 _wallOfForceShapeDefs[];
|
||||
|
||||
const char *const *_mainMenuStrings;
|
||||
|
||||
// Main loop
|
||||
virtual void startupNew() = 0;
|
||||
virtual void startupLoad() = 0;
|
||||
void runLoop();
|
||||
void update() { screen()->updateScreen(); }
|
||||
bool updateCharacterEvents(bool a);
|
||||
|
||||
bool _runFlag;
|
||||
//int _runLoopUnk2;
|
||||
|
||||
// Create Party
|
||||
void startCharacterGeneration();
|
||||
|
||||
uint8 **_faceShapes;
|
||||
|
||||
static const int8 _classHpIncreaseType[];
|
||||
static const uint8 _hpIncrPerLevel[];
|
||||
static const uint8 _numLevelsPerClass[];
|
||||
static const int16 _hpConstModifiers[];
|
||||
static const uint8 _charClassModUnk[];
|
||||
|
||||
const uint8 *_classModifierFlags;
|
||||
|
||||
// timers
|
||||
void setupTimers();
|
||||
void setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer);
|
||||
void deleteCharEventTimer(int charIndex, int evnt);
|
||||
void setupCharacterTimers();
|
||||
|
||||
void timerProcessMonsters(int timerNum);
|
||||
void timerSpecialCharacterUpdate(int timerNum);
|
||||
void timerProcessFlyingObjects(int timerNum);
|
||||
void timerProcessCharacterExchange(int timerNum);
|
||||
void timerUpdateTeleporters(int timerNum);
|
||||
void timerUpdateFoodStatus(int timerNum);
|
||||
void timerUpdateMonsterIdleAnim(int timerNum);
|
||||
|
||||
uint8 getClock2Timer(int index) { return index < _numClock2Timers ? _clock2Timers[index] : 0; }
|
||||
uint8 getNumClock2Timers() { return _numClock2Timers; }
|
||||
|
||||
static const uint8 _clock2Timers[];
|
||||
static const uint8 _numClock2Timers;
|
||||
|
||||
// Mouse
|
||||
void setHandItem(Item itemIndex);
|
||||
void updateHandItemCursor() { _updateHandItemCursor = true; }
|
||||
bool _updateHandItemCursor;
|
||||
|
||||
// Characters
|
||||
int getDexterityArmorClassModifier(int dexterity);
|
||||
int generateCharacterHitpointsByLevel(int charIndex, int levelIndex);
|
||||
int getClassAndConstHitpointsModifier(int cclass, int constitution);
|
||||
int getClassHpIncreaseType(int cclass, int levelIndex);
|
||||
int getModifiedHpLimits(int hpModifier, int constModifier, int level, bool mode);
|
||||
const char *getCharStrength(int str, int strExt);
|
||||
int testCharacter(int index, int flags);
|
||||
int getNextValidCharIndex(int curCharIndex, int searchStep);
|
||||
|
||||
void recalcArmorClass(int index);
|
||||
int validateWeaponSlotItem(int index, int slot);
|
||||
int getCharacterClericPaladinLevel(int index);
|
||||
int getCharacterMageLevel(int index);
|
||||
int getLevelIndexForHpIncType(int unk, int cClass);
|
||||
|
||||
int countCharactersWithSpecificItems(int16 itemType, int16 itemValue);
|
||||
int checkCharacterInventoryForItem(int character, int16 itemType, int16 itemValue);
|
||||
void modifyCharacterHitpoints(int character, int16 points);
|
||||
void neutralizePoison(int character);
|
||||
|
||||
virtual void npcSequence(int npcIndex) = 0;
|
||||
void initNpc(int npcIndex);
|
||||
int npcJoinDialogue(int npcIndex, int queryJoinTextId, int confirmJoinTextId, int noJoinTextId);
|
||||
int prepareForNewPartyMember(int16 itemType, int16 itemValue);
|
||||
void removeCharacterFromParty(int charIndex);
|
||||
|
||||
void increasePartyExperience(int16 points);
|
||||
void increaseCharacterExperience(int charIndex, int32 points);
|
||||
uint32 getRequiredExperience(int cClass, int levelIndex, int level);
|
||||
void increaseCharacterLevel(int charIndex, int levelIndex);
|
||||
|
||||
void setWeaponSlotStatus(int charIndex, int mode, int slot);
|
||||
|
||||
EobCharacter *_characters;
|
||||
char _strenghtStr[6];
|
||||
int _castScrollSlot;
|
||||
int _exchangeCharacterId;
|
||||
|
||||
const char *const *_levelGainStrings;
|
||||
const uint32 *_expRequirementTables[6];
|
||||
|
||||
const uint8 *_constModTables[6];
|
||||
const uint8 *_constModLevelIndex;
|
||||
const uint8 *_constModDiv;
|
||||
const uint8 *_constModExt;
|
||||
|
||||
const EobCharacter *_npcPreset;
|
||||
bool _partyResting;
|
||||
|
||||
// Items
|
||||
void loadItemDefs();
|
||||
Item duplicateItem(Item itemIndex);
|
||||
void setItemPosition(Item *itemQueue, int block, Item item, int pos);
|
||||
void createInventoryItem(EobCharacter *c, Item itemIndex, int itemValue, int preferedInventorySlot);
|
||||
int deleteInventoryItem(int charIndex, int slot);
|
||||
void deleteBlockItem(uint16 block, int type);
|
||||
int validateInventorySlotForItem(Item item, int charIndex, int slot);
|
||||
void deletePartyItem(Item itemType, int16 itemValue);
|
||||
virtual void updateUsedCharacterHandItem(int charIndex, int slot) = 0;
|
||||
int itemUsableByCharacter(int charIndex, Item item);
|
||||
int countQueuedItems(Item itemQueue, int16 id, int16 type, int count, int includeFlyingItems);
|
||||
int getQueuedItem(Item *items, int pos, int id);
|
||||
void printFullItemName(Item item);
|
||||
void identifyQueuedItems(Item itemQueue);
|
||||
void drawItemIconShape(int pageNum, Item itemId, int x, int y);
|
||||
bool isMagicWeapon(Item itemIndex);
|
||||
bool checkInventoryForRings(int charIndex, int itemValue);
|
||||
void eatItemInHand(int charIndex);
|
||||
|
||||
bool launchObject(int charIndex, Item item, uint16 startBlock, int startPos, int dir, int type);
|
||||
void launchMagicObject(int charIndex, int type, uint16 startBlock, int startPos, int dir);
|
||||
bool updateObjectFlight(EobFlyingObject *fo, int block, int pos);
|
||||
bool updateFlyingObjectHitTest(EobFlyingObject *fo, int block, int pos);
|
||||
void updateFlyingObject_s3(EobFlyingObject *fo);
|
||||
void endObjectFlight(EobFlyingObject *fo);
|
||||
void checkFlyingObjects();
|
||||
|
||||
void reloadWeaponSlot(int charIndex, int slotIndex, int itemType, int arrowOrDagger);
|
||||
|
||||
EobItem *_items;
|
||||
uint16 _numItems;
|
||||
EobItemType *_itemTypes;
|
||||
char **_itemNames;
|
||||
uint16 _numItemNames;
|
||||
uint32 _partyEffectFlags;
|
||||
Item _lastUsedItem;
|
||||
|
||||
const uint16 *_slotValidationFlags;
|
||||
|
||||
EobFlyingObject *_flyingObjects;
|
||||
const uint8 *_drawObjPosIndex;
|
||||
const uint8 *_flightObjFlipIndex;
|
||||
const int8 *_flightObjShpMap;
|
||||
const int8 *_flightObjSclIndex;
|
||||
|
||||
// Monsters
|
||||
void loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex);
|
||||
void releaseMonsterShapes(int first, int num);
|
||||
virtual void generateMonsterPalettes(const char *file, int16 monsterIndex) {}
|
||||
virtual void loadMonsterDecoration(const char *file, int16 monsterIndex) {}
|
||||
const uint8 *loadMonsterProperties(const uint8 *data);
|
||||
const uint8 *loadActiveMonsterData(const uint8 *data, int level);
|
||||
void initMonster(int index, int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int i, int randItem, int fixedItem);
|
||||
void placeMonster(EobMonsterInPlay *m, uint16 block, int dir);
|
||||
virtual void replaceMonster(int b, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) = 0;
|
||||
void killMonster(EobMonsterInPlay *m, bool giveExperience);
|
||||
int countSpecificMonsters(int type);
|
||||
void updateAttackingMonsterFlags();
|
||||
|
||||
const int8 *getMonsterBlockPositions(uint16 block);
|
||||
int getClosestMonsterPos(int charIndex, int block);
|
||||
|
||||
bool blockHasMonsters(uint16 block);
|
||||
bool isMonsterOnPos(EobMonsterInPlay *m, uint16 block, int pos, int checkPos4);
|
||||
const int16 *findBlockMonsters(uint16 block, int pos, int dir, int blockDamage, int singleTargetCheckAdjacent);
|
||||
|
||||
void drawBlockObject(int flipped, int page, const uint8 *shape, int x, int y, int sd, uint8 *ovl = 0);
|
||||
void drawMonsterShape(const uint8 *shape, int x, int y, int flipped, int flags, int palIndex);
|
||||
void flashMonsterShape(EobMonsterInPlay *m);
|
||||
void updateAllMonsterShapes();
|
||||
void drawBlockItems(int index);
|
||||
void drawDoor(int index);
|
||||
virtual void drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2) = 0;
|
||||
void drawMonsters(int index);
|
||||
void drawWallOfForce(int index);
|
||||
void drawFlyingObjects(int index);
|
||||
void drawTeleporter(int index);
|
||||
|
||||
void updateMonsters(int unit);
|
||||
void updateMonsterDest(EobMonsterInPlay *m);
|
||||
void updateMonsterDest2(EobMonsterInPlay *m);
|
||||
void turnFriendlyMonstersHostile();
|
||||
int getNextMonsterDirection(int curBlock, int destBlock);
|
||||
int getNextMonsterPos(EobMonsterInPlay *m, int block);
|
||||
int findFreeMonsterPos(int block, int size);
|
||||
void updateMoveMonster(EobMonsterInPlay *m);
|
||||
bool updateMonsterTryDistanceAttack(EobMonsterInPlay *m);
|
||||
bool updateMonsterTryCloseAttack(EobMonsterInPlay *m, int block);
|
||||
void walkMonster(EobMonsterInPlay *m, int destBlock);
|
||||
bool walkMonsterNextStep(EobMonsterInPlay *m, int destBlock, int direction);
|
||||
void updateMonsterFollowPath(EobMonsterInPlay *m, int turnSteps);
|
||||
void updateMonstersStraying(EobMonsterInPlay *m, int a);
|
||||
void updateMonsters_mode710(EobMonsterInPlay *m);
|
||||
void setBlockMonsterDirection(int block, int dir);
|
||||
|
||||
uint8 *_monsterOvl1;
|
||||
uint8 *_monsterOvl2;
|
||||
|
||||
SpriteDecoration *_monsterDecorations;
|
||||
EobMonsterProperty *_monsterProps;
|
||||
|
||||
EobMonsterInPlay *_monsters;
|
||||
|
||||
const int8 *_monsterStepTable0;
|
||||
const int8 *_monsterStepTable1;
|
||||
const int8 *_monsterStepTable2;
|
||||
const int8 *_monsterStepTable3;
|
||||
const uint8 *_monsterCloseAttPosTable1;
|
||||
const uint8 *_monsterCloseAttPosTable2;
|
||||
const int8 *_monsterCloseAttUnkTable;
|
||||
const uint8 *_monsterCloseAttChkTable1;
|
||||
const uint8 *_monsterCloseAttChkTable2;
|
||||
const uint8 *_monsterCloseAttDstTable1;
|
||||
const uint8 *_monsterCloseAttDstTable2;
|
||||
|
||||
const uint8 *_monsterProximityTable;
|
||||
const uint8 *_findBlockMonstersTable;
|
||||
const char *const *_monsterDustStrings;
|
||||
|
||||
const uint8 *_monsterDistAttType10;
|
||||
const uint8 *_monsterDistAttSfx10;
|
||||
const uint8 *_monsterDistAttType17;
|
||||
const uint8 *_monsterDistAttSfx17;
|
||||
const char *const *_monsterSpecAttStrings;
|
||||
|
||||
const int8 *_monsterFrmOffsTable1;
|
||||
const int8 *_monsterFrmOffsTable2;
|
||||
|
||||
const uint16 *_encodeMonsterShpTable;
|
||||
const uint8 _teleporterWallId;
|
||||
|
||||
const int8 *_monsterDirChangeTable;
|
||||
|
||||
// Level
|
||||
void loadLevel(int level, int func);
|
||||
const char *initLevelData(int func);
|
||||
void addLevelItems();
|
||||
void loadVcnData(const char *file, const char */*nextFile*/);
|
||||
void loadBlockProperties(const char *mazFile);
|
||||
void loadDecorations(const char *cpsFile, const char *decFile);
|
||||
void assignWallsAndDecorations(int wallIndex, int vmpIndex, int decDataIndex, int specialType, int flags);
|
||||
void releaseDecorations();
|
||||
void releaseDoorShapes();
|
||||
void toggleWallState(int wall, int flags);
|
||||
virtual void loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {}
|
||||
virtual const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8*shapeDefs) { return (const uint8*)filename; }
|
||||
|
||||
void drawScene(int update);
|
||||
void drawSceneShapes();
|
||||
void drawDecorations(int index);
|
||||
|
||||
int calcNewBlockPositionAndTestPassability(uint16 curBlock, uint16 direction);
|
||||
void notifyBlockNotPassable();
|
||||
void moveParty(uint16 block);
|
||||
|
||||
int clickedDoorSwitch(uint16 block, uint16 direction);
|
||||
int clickedDoorPry(uint16 block, uint16 direction);
|
||||
int clickedDoorNoPry(uint16 block, uint16 direction);
|
||||
int clickedNiche(uint16 block, uint16 direction);
|
||||
|
||||
int specialWallAction(int block, int direction);
|
||||
|
||||
void openDoor(int block);
|
||||
void closeDoor(int block);
|
||||
|
||||
int16 _doorType[2];
|
||||
int16 _noDoorSwitch[2];
|
||||
|
||||
EobRect8 *_levelDecorationRects;
|
||||
SpriteDecoration *_doorSwitches;
|
||||
|
||||
int8 _currentSub;
|
||||
char _curGfxFile[13];
|
||||
|
||||
uint32 _drawSceneTimer;
|
||||
uint32 _flashShapeTimer;
|
||||
uint32 _envAudioTimer;
|
||||
uint16 _teleporterPulse;
|
||||
|
||||
const int16 *_dscShapeCoords;
|
||||
|
||||
const uint8 *_dscItemPosIndex;
|
||||
const int16 *_dscItemShpX;
|
||||
const uint8 *_dscItemScaleIndex;
|
||||
const uint8 *_dscItemTileIndex;
|
||||
const uint8 *_dscItemShapeMap;
|
||||
|
||||
const uint8 *_dscDoorScaleOffs;
|
||||
const uint8 *_dscDoorScaleMult1;
|
||||
const uint8 *_dscDoorScaleMult2;
|
||||
const uint8 *_dscDoorScaleMult3;
|
||||
const uint8 *_dscDoorY1;
|
||||
|
||||
const uint8 *_wllFlagPreset;
|
||||
int _wllFlagPresetSize;
|
||||
const uint8 *_teleporterShapeCoords;
|
||||
|
||||
// Script
|
||||
void runLevelScript(int block, int flags);
|
||||
void setScriptFlag(int flag);
|
||||
bool checkScriptFlag(int flag);
|
||||
|
||||
const uint8 *initScriptTimers(const uint8 *pos);
|
||||
void updateScriptTimers();
|
||||
|
||||
EobInfProcessor *_inf;
|
||||
int _stepCounter;
|
||||
int _stepsUntilScriptCall;
|
||||
ScriptTimer _scriptTimers[5];
|
||||
int _scriptTimersCount;
|
||||
uint8 _scriptTimersMode;
|
||||
|
||||
// Gui
|
||||
void gui_drawPlayField(int pageNum);
|
||||
void gui_restorePlayField();
|
||||
void gui_drawAllCharPortraitsWithStats();
|
||||
void gui_drawCharPortraitWithStats(int index);
|
||||
void gui_drawFaceShape(int index);
|
||||
void gui_drawWeaponSlot(int charIndex, int slot);
|
||||
void gui_drawWeaponSlotStatus(int x, int y, int status);
|
||||
void gui_drawHitpoints(int index);
|
||||
void gui_drawFoodStatusGraph(int index);
|
||||
void gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2);
|
||||
void gui_drawCharPortraitStatusFrame(int index);
|
||||
void gui_drawInventoryItem(int slot, int special, int pageNum);
|
||||
void gui_drawCompass(bool force);
|
||||
void gui_drawDialogueBox();
|
||||
void gui_drawSpellbook();
|
||||
void gui_drawSpellbookScrollArrow(int x, int y, int direction);
|
||||
void gui_updateSlotAfterScrollUse();
|
||||
void gui_updateControls();
|
||||
void gui_toggleButtons();
|
||||
void gui_setPlayFieldButtons();
|
||||
void gui_setInventoryButtons();
|
||||
void gui_setStatsListButtons();
|
||||
void gui_setSwapCharacterButtons();
|
||||
void gui_setCastOnWhomButtons();
|
||||
void gui_initButton(int index, int x = -1, int y = -1, int val = -1);
|
||||
Button *gui_getButton(Button *buttonList, int index);
|
||||
|
||||
int clickedInventoryNextPage(Button *button);
|
||||
int clickedPortraitRestore(Button *button);
|
||||
int clickedCharPortraitDefault(Button *button);
|
||||
int clickedCamp(Button *button);
|
||||
int clickedSceneDropPickupItem(Button *button);
|
||||
int clickedCharPortrait2(Button *button);
|
||||
int clickedWeaponSlot(Button *button);
|
||||
int clickedCharNameLabelRight(Button *button);
|
||||
int clickedInventorySlot(Button *button);
|
||||
int clickedEatItem(Button *button);
|
||||
int clickedInventoryPrevChar(Button *button);
|
||||
int clickedInventoryNextChar(Button *button);
|
||||
int clickedSpellbookTab(Button *button);
|
||||
int clickedSpellbookList(Button *button);
|
||||
int clickedCastSpellOnCharacter(Button *button);
|
||||
int clickedUpArrow(Button *button);
|
||||
int clickedDownArrow(Button *button);
|
||||
int clickedLeftArrow(Button *button);
|
||||
int clickedRightArrow(Button *button);
|
||||
int clickedTurnLeftArrow(Button *button);
|
||||
int clickedTurnRightArrow(Button *button);
|
||||
int clickedAbortCharSwitch(Button *button);
|
||||
int clickedSceneThrowItem(Button *button);
|
||||
int clickedSceneSpecial(Button *button);
|
||||
int clickedSpellbookAbort(Button *button);
|
||||
int clickedSpellbookScroll(Button *button);
|
||||
int clickedUnk(Button *button);
|
||||
|
||||
void gui_processCharPortraitClick(int index);
|
||||
void gui_processWeaponSlotClickLeft(int charIndex, int slotIndex);
|
||||
void gui_processWeaponSlotClickRight(int charIndex, int slotIndex);
|
||||
void gui_processInventorySlotClick(int slot);
|
||||
|
||||
static const int16 _buttonList1[];
|
||||
int _buttonList1Size;
|
||||
static const int16 _buttonList2[];
|
||||
int _buttonList2Size;
|
||||
static const int16 _buttonList3[];
|
||||
int _buttonList3Size;
|
||||
static const int16 _buttonList4[];
|
||||
int _buttonList4Size;
|
||||
static const int16 _buttonList5[];
|
||||
int _buttonList5Size;
|
||||
static const int16 _buttonList6[];
|
||||
int _buttonList6Size;
|
||||
static const int16 _buttonList7[];
|
||||
int _buttonList7Size;
|
||||
static const int16 _buttonList8[];
|
||||
int _buttonList8Size;
|
||||
|
||||
const EobGuiButtonDef *_buttonDefs;
|
||||
const char *const *_characterGuiStringsHp;
|
||||
const char *const *_characterGuiStringsWp;
|
||||
const char *const *_characterGuiStringsWr;
|
||||
const char *const *_characterGuiStringsSt;
|
||||
const char *const *_characterGuiStringsIn;
|
||||
|
||||
const char *const *_characterStatusStrings7;
|
||||
const char *const *_characterStatusStrings8;
|
||||
const char *const *_characterStatusStrings9;
|
||||
const char *const *_characterStatusStrings12;
|
||||
const char *const *_characterStatusStrings13;
|
||||
|
||||
const uint16 *_inventorySlotsX;
|
||||
const uint8 *_inventorySlotsY;
|
||||
const uint8 **_compassShapes;
|
||||
uint8 _charExchangeSwap;
|
||||
bool _hpBarGraphs;
|
||||
|
||||
// text
|
||||
void setupDialogueButtons(int presetfirst, int numStr, const char *str1, ...);
|
||||
void initDialogueSequence();
|
||||
void restoreAfterDialogueSequence();
|
||||
void drawSequenceBitmap(const char *file, int destRect, int x1, int y1, int flags);
|
||||
int runDialogue(int dialogueTextId, int style, const char *button1, ...);
|
||||
|
||||
char _dialogueLastBitmap[13];
|
||||
int _dlgUnk1;
|
||||
int _moveCounter;
|
||||
|
||||
uint8 _color4;
|
||||
uint8 _color5;
|
||||
uint8 _color6;
|
||||
uint8 _color7;
|
||||
uint8 _color8;
|
||||
uint8 _color9;
|
||||
uint8 _color10;
|
||||
uint8 _color11;
|
||||
uint8 _color12;
|
||||
uint8 _color13;
|
||||
uint8 _color14;
|
||||
|
||||
const char *const *_chargenStatStrings;
|
||||
const char *const *_chargenRaceSexStrings;
|
||||
const char *const *_chargenClassStrings;
|
||||
const char *const *_chargenAlignmentStrings;
|
||||
|
||||
const char *const *_pryDoorStrings;
|
||||
const char *const *_warningStrings;
|
||||
const char *const *_itemExtraStrings;
|
||||
const char *const *_itemSuffixStrings;
|
||||
const char *const *_takenStrings;
|
||||
const char *const *_potionEffectStrings;
|
||||
|
||||
const char *const *_yesNoStrings;
|
||||
const char *const *_npcMaxStrings;
|
||||
const char *const *_okStrings;
|
||||
const char *const *_npcJoinStrings;
|
||||
const char *const *_cancelStrings;
|
||||
const char *const *_abortStrings;
|
||||
|
||||
// misc
|
||||
void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
|
||||
void displayParchment(int id);
|
||||
|
||||
virtual void drawLightningColumn() {}
|
||||
virtual int resurrectionSelectDialogue() { return -1; }
|
||||
virtual int charSelectDialogue() { return -1; }
|
||||
virtual void characterLevelGain(int charIndex) {}
|
||||
|
||||
Common::Error loadGameState(int slot);
|
||||
Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail);
|
||||
|
||||
void *generateMonsterTempData(LevelTempData *tmp);
|
||||
void *generateFlyingObjectTempData(LevelTempData *tmp);
|
||||
void restoreMonsterTempData(LevelTempData *tmp);
|
||||
void restoreFlyingObjectTempData(LevelTempData *tmp);
|
||||
void releaseMonsterTempData(LevelTempData *tmp);
|
||||
void releaseFlyingObjectTempData(LevelTempData *tmp);
|
||||
|
||||
int _saveLoadMode;
|
||||
|
||||
Screen_Eob *_screen;
|
||||
GUI_Eob *_gui;
|
||||
|
||||
// fight
|
||||
void useSlotWeapon(int charIndex, int slotIndex, int item);
|
||||
int closeDistanceAttack(int charIndex, int item);
|
||||
int thrownAttack(int charIndex, int slotIndex, int item);
|
||||
int bowAttack(int charIndex, int item);
|
||||
|
||||
void inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool giveExperience);
|
||||
void calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType);
|
||||
void calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType);
|
||||
int calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType) ;
|
||||
void inflictCharacterDamage(int charIndex, int damage);
|
||||
|
||||
bool characterAttackHitTest(int charIndex, int monsterIndex, int item, int attackType);
|
||||
bool monsterAttackHitTest(EobMonsterInPlay *m, int charIndex);
|
||||
bool flyingObjectMonsterHit(EobFlyingObject *fo, int monsterIndex);
|
||||
bool flyingObjectPartyHit(EobFlyingObject *fo);
|
||||
|
||||
void monsterCloseAttack(EobMonsterInPlay *m);
|
||||
void monsterSpellCast(EobMonsterInPlay *m, int type);
|
||||
void statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int a, uint32 effectDuration, int restoreEvent, int noRefresh);
|
||||
|
||||
int calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType);
|
||||
int calcDamageModifers(int charIndex, EobMonsterInPlay *m, int item, int itemType, int useStrModifier);
|
||||
bool checkUnkConstModifiers(void *target, int hpModifier, int level, int b, int race);
|
||||
bool specialAttackConstTest(int charIndex, int b);
|
||||
int getConstModifierTableValue(int hpModifier, int level, int b);
|
||||
bool calcDamageCheckItemType(int itemType);
|
||||
int recalcDamageModifier(int damageType, int dmgModifier);
|
||||
bool checkMonsterDamageEvasion(EobMonsterInPlay *m);
|
||||
int getStrHitChanceModifier(int charIndex);
|
||||
int getStrDamageModifier(int charIndex);
|
||||
int getDexHitChanceModifier(int charIndex);
|
||||
int getMonsterAcHitChanceModifier(int charIndex, int monsterAc);
|
||||
void inflictMonsterDamage_s1(EobMonsterInPlay *m);
|
||||
|
||||
int _dstMonsterIndex;
|
||||
int _inflictMonsterDamageUnk;
|
||||
int16 _foundMonstersArray[5];
|
||||
|
||||
// magic
|
||||
void useMagicBookOrSymbol(int charIndex, int type);
|
||||
void useMagicScroll(int charIndex, int type, int weaponSlot);
|
||||
void usePotion(int charIndex, int weaponSlot);
|
||||
|
||||
void castSpell(int spell, int weaponSlot);
|
||||
void removeCharacterEffect(int spell, int charIndex, int showWarning);
|
||||
void removeAllCharacterEffects(int charIndex);
|
||||
void castOnWhomDialogue();
|
||||
void startSpell(int spell);
|
||||
|
||||
void sparkEffectDefensive(int charIndex);
|
||||
void sparkEffectOffensive();
|
||||
void setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer);
|
||||
|
||||
bool magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
|
||||
|
||||
void spellCallback_start_empty() {}
|
||||
bool spellCallback_end_empty(EobFlyingObject *fo) { return true; }
|
||||
void spellCallback_start_armor();
|
||||
void spellCallback_start_burningHands();
|
||||
void spellCallback_start_detectMagic();
|
||||
bool spellCallback_end_detectMagic(EobFlyingObject *fo);
|
||||
void spellCallback_start_magicMissile();
|
||||
bool spellCallback_end_magicMissile(EobFlyingObject *fo);
|
||||
void spellCallback_start_shockingGrasp();
|
||||
bool spellCallback_end_shockingGraspFlameBlade(EobFlyingObject *fo);
|
||||
void spellCallback_start_improvedIdentify();
|
||||
void spellCallback_start_melfsAcidArrow();
|
||||
bool spellCallback_end_melfsAcidArrow(EobFlyingObject *fo);
|
||||
void spellCallback_start_dispelMagic();
|
||||
void spellCallback_start_fireball();
|
||||
bool spellCallback_end_fireball(EobFlyingObject *fo);
|
||||
void spellCallback_start_flameArrow();
|
||||
bool spellCallback_end_flameArrow(EobFlyingObject *fo);
|
||||
void spellCallback_start_holdPerson();
|
||||
bool spellCallback_end_holdPerson(EobFlyingObject *fo);
|
||||
void spellCallback_start_lightningBolt();
|
||||
bool spellCallback_end_lightningBolt(EobFlyingObject *fo);
|
||||
void spellCallback_start_vampiricTouch();
|
||||
bool spellCallback_end_vampiricTouch(EobFlyingObject *fo);
|
||||
void spellCallback_start_fear();
|
||||
void spellCallback_start_iceStorm();
|
||||
bool spellCallback_end_iceStorm(EobFlyingObject *fo);
|
||||
void spellCallback_start_removeCurse();
|
||||
void spellCallback_start_coneOfCold();
|
||||
void spellCallback_start_holdMonster();
|
||||
bool spellCallback_end_holdMonster(EobFlyingObject *fo);
|
||||
void spellCallback_start_wallOfForce();
|
||||
void spellCallback_start_disintegrate();
|
||||
void spellCallback_start_fleshToStone();
|
||||
void spellCallback_start_stoneToFlesh();
|
||||
void spellCallback_start_trueSeeing();
|
||||
bool spellCallback_end_trueSeeing(EobFlyingObject *fo);
|
||||
void spellCallback_start_slayLiving();
|
||||
void spellCallback_start_powerWordStun();
|
||||
void spellCallback_start_causeLightWounds();
|
||||
void spellCallback_start_cureLightWounds();
|
||||
void spellCallback_start_aid();
|
||||
bool spellCallback_end_aid(EobFlyingObject *fo);
|
||||
void spellCallback_start_flameBlade();
|
||||
void spellCallback_start_slowPoison();
|
||||
bool spellCallback_end_slowPoison(EobFlyingObject *fo);
|
||||
void spellCallback_start_createFood();
|
||||
void spellCallback_start_removeParalysis();
|
||||
void spellCallback_start_causeSeriousWounds();
|
||||
void spellCallback_start_cureSeriousWounds();
|
||||
void spellCallback_start_neutralizePoison();
|
||||
void spellCallback_start_causeCriticalWounds();
|
||||
void spellCallback_start_cureCriticalWounds();
|
||||
void spellCallback_start_flameStrike();
|
||||
bool spellCallback_end_flameStrike(EobFlyingObject *fo);
|
||||
void spellCallback_start_raiseDead();
|
||||
void spellCallback_start_harm();
|
||||
void spellCallback_start_heal();
|
||||
void spellCallback_start_layOnHands();
|
||||
void spellCallback_start_turnUndead();
|
||||
bool spellCallback_end_unk1Passive(EobFlyingObject *fo);
|
||||
bool spellCallback_end_unk2Passive(EobFlyingObject *fo);
|
||||
bool spellCallback_end_deathSpellPassive(EobFlyingObject *fo);
|
||||
bool spellCallback_end_disintegratePassive(EobFlyingObject *fo);
|
||||
bool spellCallback_end_causeCriticalWoundsPassive(EobFlyingObject *fo);
|
||||
bool spellCallback_end_fleshToStonePassive(EobFlyingObject *fo);
|
||||
|
||||
int8 _openBookSpellLevel;
|
||||
int8 _openBookSpellSelectedItem;
|
||||
int8 _openBookSpellListOffset;
|
||||
uint8 _openBookChar;
|
||||
uint8 _openBookType;
|
||||
uint8 _openBookCharBackup;
|
||||
uint8 _openBookTypeBackup;
|
||||
const char *const *_openBookSpellList;
|
||||
int8 *_openBookAvailableSpells;
|
||||
uint8 _activeSpellCaster;
|
||||
uint8 _activeSpellCasterPos;
|
||||
uint8 _activeSpell;
|
||||
bool _returnAfterSpellCallback;
|
||||
|
||||
typedef void (EobCoreEngine::*SpellStartCallback)();
|
||||
typedef bool (EobCoreEngine::*SpellEndCallback)(EobFlyingObject *fo);
|
||||
|
||||
struct EobSpell {
|
||||
const char *name;
|
||||
SpellStartCallback startCallback;
|
||||
uint16 flags;
|
||||
const uint16 *timingPara;
|
||||
SpellEndCallback endCallback;
|
||||
uint8 sound;
|
||||
uint32 effectFlags;
|
||||
uint16 damageFlags;
|
||||
};
|
||||
|
||||
EobSpell *_spells;
|
||||
int _numSpells;
|
||||
|
||||
const char *const *_bookNumbers;
|
||||
const char *const *_mageSpellList;
|
||||
int _mageSpellListSize;
|
||||
int _clericSpellOffset;
|
||||
const char *const *_clericSpellList;
|
||||
const char *const *_spellNames;
|
||||
const char *const *_magicStrings1;
|
||||
const char *const *_magicStrings2;
|
||||
const char *const *_magicStrings3;
|
||||
const char *const *_magicStrings4;
|
||||
const char *const *_magicStrings5;
|
||||
const char *const *_magicStrings6;
|
||||
const char *const *_magicStrings7;
|
||||
const char *const *_magicStrings8;
|
||||
|
||||
uint8 *_spellAnimBuffer;
|
||||
|
||||
const uint8 *_sparkEffectDefSteps;
|
||||
const uint8 *_sparkEffectDefSubSteps;
|
||||
const uint8 *_sparkEffectDefShift;
|
||||
const uint8 *_sparkEffectDefAdd;
|
||||
const uint8 *_sparkEffectDefX;
|
||||
const uint8 *_sparkEffectDefY;
|
||||
const uint32 *_sparkEffectOfFlags1;
|
||||
const uint32 *_sparkEffectOfFlags2;
|
||||
const uint8 *_sparkEffectOfShift;
|
||||
const uint8 *_sparkEffectOfX;
|
||||
const uint8 *_sparkEffectOfY;
|
||||
|
||||
const uint8 *_magicFlightObjectProperties;
|
||||
|
||||
// sound
|
||||
void snd_playSoundEffect(int id, int volume=0xFF);
|
||||
};
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
||||
|
||||
#endif
|
@ -40,10 +40,10 @@ struct Button {
|
||||
typedef Common::Functor1<Button *, int> CallbackFunctor;
|
||||
typedef Common::SharedPtr<CallbackFunctor> Callback;
|
||||
|
||||
Button() : nextButton(0), index(0), keyCode(0), keyCode2(0), data0Val1(0), data1Val1(0), data2Val1(0), flags(0),
|
||||
Button() : nextButton(0), index(0), keyCode(0), keyCode2(0), data0Val1(0), data1Val1(0), data2Val1(0), data3Val1(0), flags(0),
|
||||
data0ShapePtr(0), data1ShapePtr(0), data2ShapePtr(0), data0Callback(), data1Callback(), data2Callback(),
|
||||
dimTableIndex(0), x(0), y(0), width(0), height(0), data0Val2(0), data0Val3(0), data1Val2(0), data1Val3(0),
|
||||
data2Val2(0), data2Val3(0), flags2(0), mouseWheel(0), buttonCallback(), arg(0) {}
|
||||
data2Val2(0), data2Val3(0), data3Val2(0), data3Val3(0), flags2(0), mouseWheel(0), buttonCallback(), arg(0) {}
|
||||
|
||||
Button *nextButton;
|
||||
uint16 index;
|
||||
@ -54,6 +54,7 @@ struct Button {
|
||||
byte data0Val1;
|
||||
byte data1Val1;
|
||||
byte data2Val1;
|
||||
byte data3Val1;
|
||||
|
||||
uint16 flags;
|
||||
|
||||
@ -78,6 +79,9 @@ struct Button {
|
||||
uint8 data2Val2;
|
||||
uint8 data2Val3;
|
||||
|
||||
uint8 data3Val2;
|
||||
uint8 data3Val3;
|
||||
|
||||
uint16 flags2;
|
||||
|
||||
int8 mouseWheel;
|
||||
|
2165
engines/kyra/gui_eob.cpp
Normal file
2165
engines/kyra/gui_eob.cpp
Normal file
File diff suppressed because it is too large
Load Diff
130
engines/kyra/gui_eob.h
Normal file
130
engines/kyra/gui_eob.h
Normal file
@ -0,0 +1,130 @@
|
||||
/* 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)
|
||||
|
||||
#ifndef KYRA_GUI_EOB_H
|
||||
#define KYRA_GUI_EOB_H
|
||||
|
||||
#include "kyra/gui.h"
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
class DarkMoonEngine;
|
||||
class Screen_Eob;
|
||||
|
||||
class GUI_Eob : public GUI {
|
||||
friend class EobCoreEngine;
|
||||
friend class CharacterGenerator;
|
||||
public:
|
||||
GUI_Eob(EobCoreEngine *vm);
|
||||
|
||||
void initStaticData() {}
|
||||
|
||||
// button specific
|
||||
void processButton(Button *button);
|
||||
int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel);
|
||||
|
||||
int redrawShadedButtonCallback(Button *button) { return 0; }
|
||||
int redrawButtonCallback(Button *button) { return 0; }
|
||||
|
||||
void setupMenu(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing);
|
||||
int handleMenu(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk);
|
||||
int getMenuItem(int index, int32 menuItemsMask, int unk);
|
||||
void menuFlashSelection(const char *str, int x, int y, int color1, int color2, int color3);
|
||||
|
||||
int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
|
||||
|
||||
//int runMenu(Menu &menu);
|
||||
|
||||
// utilities for thumbnail creation
|
||||
void createScreenThumbnail(Graphics::Surface &dst) {}
|
||||
|
||||
private:
|
||||
void initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk);
|
||||
|
||||
//void backupPage0();
|
||||
//void restorePage0();
|
||||
|
||||
//void setupSavegameNames(Menu &menu, int num);
|
||||
//void printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 flags);
|
||||
|
||||
//int getMenuCenterStringX(const char *str, int x1, int x2);
|
||||
|
||||
int getInput();
|
||||
|
||||
Button *getButtonListData() { return _menuButtons; }
|
||||
Button *getScrollUpButton() { return &_scrollUpButton; }
|
||||
Button *getScrollDownButton() { return &_scrollDownButton; }
|
||||
|
||||
Button::Callback getScrollUpButtonHandler() const { return _scrollUpFunctor; }
|
||||
Button::Callback getScrollDownButtonHandler() const { return _scrollDownFunctor; }
|
||||
|
||||
uint8 defaultColor1() const { return 0xFE; }
|
||||
uint8 defaultColor2() const { return 0x00; }
|
||||
|
||||
const char *getMenuTitle(const Menu &menu) { return 0; }
|
||||
const char *getMenuItemTitle(const MenuItem &menuItem) { return 0; }
|
||||
const char *getMenuItemLabel(const MenuItem &menuItem) { return 0; }
|
||||
|
||||
Button _menuButtons[10];
|
||||
Button _scrollUpButton;
|
||||
Button _scrollDownButton;
|
||||
//Menu _mainMenu, _gameOptions, _audioOptions, _choiceMenu, _loadMenu, _saveMenu, _deleteMenu, _savenameMenu, _deathMenu;
|
||||
//Menu *_currentMenu, *_lastMenu, *_newMenu;
|
||||
//int _menuResult;
|
||||
//char *_saveDescription;
|
||||
|
||||
EobCoreEngine *_vm;
|
||||
Screen_Eob *_screen;
|
||||
|
||||
bool _pressFlag;
|
||||
|
||||
Button *_specialProcessButton;
|
||||
Button *_backupButtonList;
|
||||
uint16 _flagsMouseLeft;
|
||||
uint16 _flagsMouseRight;
|
||||
uint16 _flagsModifier;
|
||||
uint16 _progress;
|
||||
uint16 _prcButtonUnk3; /// ALWAYS 1?? REMOVE ??
|
||||
uint16 _cflag;
|
||||
|
||||
Button::Callback _scrollUpFunctor;
|
||||
Button::Callback _scrollDownFunctor;
|
||||
|
||||
int _menuLineSpacing;
|
||||
int _menuUnk1;
|
||||
int _menuLastInFlags;
|
||||
|
||||
int _menuCur;
|
||||
int _menuNumItems;
|
||||
};
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
||||
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_EOB || ENABLE_LOL
|
@ -32,6 +32,7 @@
|
||||
#include "common/savefile.h"
|
||||
#include "common/system.h"
|
||||
#include "common/config-manager.h"
|
||||
|
||||
#include "graphics/scaler.h"
|
||||
|
||||
#include "base/version.h"
|
||||
@ -213,9 +214,9 @@ void LoLEngine::gui_displayCharInventory(int charNum) {
|
||||
}
|
||||
|
||||
if (_flags.use16ColorMode)
|
||||
gui_drawBarGraph(154, 66 + i * 8, 34, 5, b, e, 0x88, 0);
|
||||
gui_drawHorizontalBarGraph(154, 66 + i * 8, 34, 5, b, e, 0x88, 0);
|
||||
else
|
||||
gui_drawBarGraph(154, 64 + i * 10, 34, 5, b, e, 132, 0);
|
||||
gui_drawHorizontalBarGraph(154, 64 + i * 10, 34, 5, b, e, 132, 0);
|
||||
}
|
||||
|
||||
_screen->drawClippedLine(14, 120, 194, 120, 1);
|
||||
@ -343,31 +344,6 @@ void LoLEngine::gui_drawCharInventoryItem(int itemIndex) {
|
||||
_screen->drawShape(_screen->_curPage, getItemIconShapePtr(i), x + 1, y + 1, 0, 0);
|
||||
}
|
||||
|
||||
void LoLEngine::gui_drawBarGraph(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 LoLEngine::gui_drawAllCharPortraitsWithStats() {
|
||||
int numChars = countActiveCharacters();
|
||||
if (!numChars)
|
||||
@ -460,17 +436,6 @@ void LoLEngine::gui_drawCharPortraitWithStats(int charNum) {
|
||||
_screen->setFont(tmpFid);
|
||||
}
|
||||
|
||||
void LoLEngine::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 LoLEngine::gui_drawCharFaceShape(int charNum, int x, int y, int pageNum) {
|
||||
if (_characters[charNum].curFaceFrame < 7 && _characters[charNum].tempFaceFrame)
|
||||
_characters[charNum].curFaceFrame = _characters[charNum].tempFaceFrame;
|
||||
@ -853,19 +818,6 @@ void LoLEngine::gui_triggerEvent(int eventType) {
|
||||
_preserveEvents = true;
|
||||
}
|
||||
|
||||
void LoLEngine::removeInputTop() {
|
||||
if (!_eventList.empty()) {
|
||||
if (_eventList.begin()->event.type == Common::EVENT_LBUTTONDOWN)
|
||||
_gui->_mouseClick = 1;
|
||||
else if (_eventList.begin()->event.type == Common::EVENT_RBUTTONDOWN)
|
||||
_gui->_mouseClick = 2;
|
||||
else
|
||||
_gui->_mouseClick = 0;
|
||||
|
||||
_eventList.erase(_eventList.begin());
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::gui_enableDefaultPlayfieldButtons() {
|
||||
gui_resetButtonList();
|
||||
gui_initButtonsFromList(_buttonList1);
|
||||
@ -911,19 +863,6 @@ void LoLEngine::gui_enableCharInventoryButtons(int charNum) {
|
||||
gui_setFaceFramesControlButtons(21, 0);
|
||||
}
|
||||
|
||||
void LoLEngine::gui_resetButtonList() {
|
||||
for (uint i = 0; i < ARRAYSIZE(_activeButtonData); ++i)
|
||||
_activeButtonData[i].nextButton = 0;
|
||||
|
||||
gui_notifyButtonListChanged();
|
||||
_activeButtons = 0;
|
||||
}
|
||||
|
||||
void LoLEngine::gui_initButtonsFromList(const int16 *list) {
|
||||
while (*list != -1)
|
||||
gui_initButton(*list++);
|
||||
}
|
||||
|
||||
void LoLEngine::gui_setFaceFramesControlButtons(int index, int xOffs) {
|
||||
int c = countActiveCharacters();
|
||||
for (int i = 0; i < c; i++)
|
||||
@ -1009,14 +948,6 @@ void LoLEngine::gui_initButton(int index, int x, int y, int val) {
|
||||
b->buttonCallback = _buttonCallbacks[index];
|
||||
}
|
||||
|
||||
void LoLEngine::gui_notifyButtonListChanged() {
|
||||
if (_gui) {
|
||||
if (!_gui->_buttonListChanged && !_preserveEvents)
|
||||
removeInputTop();
|
||||
_gui->_buttonListChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
int LoLEngine::clickedUpArrow(Button *button) {
|
||||
if (button->arg && !_floatingCursorsEnabled)
|
||||
return 0;
|
||||
@ -1333,7 +1264,6 @@ int LoLEngine::clickedExitCharInventory(Button *button) {
|
||||
int LoLEngine::clickedSceneDropItem(Button *button) {
|
||||
static const uint8 offsX[] = { 0x40, 0xC0, 0x40, 0xC0 };
|
||||
static const uint8 offsY[] = { 0x40, 0x40, 0xC0, 0xC0 };
|
||||
static const uint8 dirIndex[] = { 0, 1, 2, 3, 1, 3, 0, 2, 3, 2, 1, 0, 2, 0, 3, 1 };
|
||||
|
||||
if ((_updateFlags & 1) || !_itemInHand)
|
||||
return 0;
|
||||
@ -1348,7 +1278,7 @@ int LoLEngine::clickedSceneDropItem(Button *button) {
|
||||
|
||||
uint16 x = 0;
|
||||
uint16 y = 0;
|
||||
int i = dirIndex[(_currentDirection << 2) + button->arg];
|
||||
int i = _dropItemDirIndex[(_currentDirection << 2) + button->arg];
|
||||
|
||||
calcCoordinates(x, y, block, offsX[i], offsY[i]);
|
||||
setItemPosition(_itemInHand, x, y, 0, 1);
|
||||
@ -1917,9 +1847,7 @@ GUI_LoL::GUI_LoL(LoLEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
|
||||
|
||||
_specialProcessButton = _backUpButtonList = 0;
|
||||
_flagsModifier = 0;
|
||||
_mouseClick = 0;
|
||||
_sliderSfx = 11;
|
||||
_buttonListChanged = false;
|
||||
_savegameList = 0;
|
||||
_savegameListSize = 0;
|
||||
}
|
||||
@ -2015,18 +1943,18 @@ int GUI_LoL::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseW
|
||||
if (!buttonList)
|
||||
return inputFlag & 0x7FFF;
|
||||
|
||||
if (_backUpButtonList != buttonList || _buttonListChanged) {
|
||||
if (_backUpButtonList != buttonList || _vm->_buttonListChanged) {
|
||||
_specialProcessButton = 0;
|
||||
|
||||
_flagsModifier = 0;
|
||||
if (_mouseClick == 1)
|
||||
if (_vm->_mouseClick == 1)
|
||||
_flagsModifier |= 0x200;
|
||||
if (_mouseClick == 2)
|
||||
if (_vm->_mouseClick == 2)
|
||||
_flagsModifier |= 0x2000;
|
||||
_mouseClick = 0;
|
||||
_vm->_mouseClick = 0;
|
||||
|
||||
_backUpButtonList = buttonList;
|
||||
_buttonListChanged = false;
|
||||
_vm->_buttonListChanged = false;
|
||||
|
||||
while (buttonList) {
|
||||
processButton(buttonList);
|
||||
|
@ -162,9 +162,7 @@ private:
|
||||
|
||||
Button *_specialProcessButton;
|
||||
Button *_backUpButtonList;
|
||||
bool _buttonListChanged;
|
||||
uint16 _flagsModifier;
|
||||
uint8 _mouseClick;
|
||||
|
||||
int _savegameOffset;
|
||||
int _sliderSfx;
|
||||
|
614
engines/kyra/items_eob.cpp
Normal file
614
engines/kyra/items_eob.cpp
Normal file
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#include "kyra/eobcommon.h"
|
||||
#include "kyra/resource.h"
|
||||
#include "kyra/sound.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
void EobCoreEngine::loadItemDefs() {
|
||||
Common::SeekableReadStream *s = _res->createReadStream("item.dat");
|
||||
_numItems = s->readUint16LE();
|
||||
|
||||
for (int i = 0; i < 600; i++)
|
||||
_items[i].block = -1;
|
||||
|
||||
for (int i = 0; i < _numItems; i++) {
|
||||
_items[i].nameUnid = s->readByte();
|
||||
_items[i].nameId = s->readByte();
|
||||
_items[i].flags = s->readByte();
|
||||
_items[i].icon = s->readSByte();
|
||||
_items[i].type = s->readSByte();
|
||||
_items[i].pos = s->readSByte();
|
||||
_items[i].block = s->readSint16LE();
|
||||
_items[i].next = s->readSint16LE();
|
||||
_items[i].prev = s->readSint16LE();
|
||||
_items[i].level = s->readSByte();
|
||||
_items[i].value = s->readSByte();
|
||||
}
|
||||
|
||||
_numItemNames = s->readUint16LE();
|
||||
for (int i = 0; i < _numItemNames; i++)
|
||||
s->read(_itemNames[i], 35);
|
||||
|
||||
delete s;
|
||||
|
||||
s = _res->createReadStream("itemtype.dat");
|
||||
uint16 numTypes = s->readUint16LE();
|
||||
|
||||
_itemTypes = new EobItemType[numTypes];
|
||||
memset(_itemTypes, 0, sizeof(EobItemType) * numTypes);
|
||||
|
||||
for (int i = 0; i < numTypes; i++) {
|
||||
_itemTypes[i].invFlags = s->readUint16LE();
|
||||
_itemTypes[i].handFlags = s->readUint16LE();
|
||||
_itemTypes[i].armorClass = s->readSByte();
|
||||
_itemTypes[i].allowedClasses = s->readSByte();
|
||||
_itemTypes[i].requiredHands = s->readSByte();
|
||||
_itemTypes[i].dmgNumDiceS = s->readSByte();
|
||||
_itemTypes[i].dmgNumPipsS = s->readSByte();
|
||||
_itemTypes[i].dmgIncS = s->readSByte();
|
||||
_itemTypes[i].dmgNumDiceL = s->readSByte();
|
||||
_itemTypes[i].dmgNumPipsL = s->readSByte();
|
||||
_itemTypes[i].dmgIncL = s->readSByte();
|
||||
_itemTypes[i].unk1 = s->readByte();
|
||||
_itemTypes[i].extraProperties = s->readUint16LE();
|
||||
}
|
||||
|
||||
delete s;
|
||||
}
|
||||
|
||||
Kyra::Item EobCoreEngine::duplicateItem(Item itemIndex) {
|
||||
EobItem *itm = &_items[itemIndex];
|
||||
|
||||
if (itm->block == -1)
|
||||
return 0;
|
||||
|
||||
Item i = 1;
|
||||
bool foundSlot = false;
|
||||
|
||||
for (; i < 600; i++) {
|
||||
if (_items[i].block == -1) {
|
||||
foundSlot = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundSlot)
|
||||
return 0;
|
||||
|
||||
memcpy(&_items[i], &_items[itemIndex], sizeof(EobItem));
|
||||
return i;
|
||||
}
|
||||
|
||||
void EobCoreEngine::setItemPosition(Item *itemQueue, int block, Item item, int pos) {
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
EobItem *itm = &_items[item];
|
||||
itm->pos = pos;
|
||||
itm->block = block;
|
||||
itm->level = block < 0 ? 0xff : _currentLevel;
|
||||
|
||||
if (!*itemQueue) {
|
||||
*itemQueue = itm->next = itm->prev = item;
|
||||
} else {
|
||||
EobItem *itmQ = &_items[*itemQueue];
|
||||
EobItem *itmQN = &_items[itmQ->next];
|
||||
itm->prev = itmQN->prev;
|
||||
itm->next = itmQ->next;
|
||||
*itemQueue = itmQN->prev = itmQ->next = item;
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::createInventoryItem(EobCharacter *c, Item itemIndex, int itemValue, int preferedInventorySlot) {
|
||||
if (itemIndex <= 0)
|
||||
return;
|
||||
|
||||
itemIndex = duplicateItem(itemIndex);
|
||||
_items[itemIndex].flags |= 0x40;
|
||||
|
||||
if (itemValue != -1)
|
||||
_items[itemIndex].value = itemValue;
|
||||
|
||||
if (itemValue && ((_itemTypes[_items[itemIndex].type].extraProperties & 0x7f) < 4))
|
||||
_items[itemIndex].flags |= 0x80;
|
||||
|
||||
if (c->inventory[preferedInventorySlot]) {
|
||||
for (int i = 2; i < 16; i++) {
|
||||
if (!c->inventory[i]) {
|
||||
c->inventory[i] = itemIndex;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
c->inventory[preferedInventorySlot] = itemIndex;
|
||||
}
|
||||
}
|
||||
|
||||
int EobCoreEngine::deleteInventoryItem(int charIndex, int slot) {
|
||||
int itm = (slot == -1) ? _itemInHand : _characters[charIndex].inventory[slot];
|
||||
_items[itm].block = -1;
|
||||
|
||||
if (slot == -1) {
|
||||
setHandItem(0);
|
||||
} else {
|
||||
_characters[charIndex].inventory[slot] = 0;
|
||||
|
||||
if (_currentControlMode == 1)
|
||||
gui_drawInventoryItem(slot, 1, 0);
|
||||
|
||||
if (_currentControlMode == 0)
|
||||
gui_drawCharPortraitWithStats(charIndex);
|
||||
}
|
||||
|
||||
return _items[itm].value;
|
||||
}
|
||||
|
||||
void EobCoreEngine::deleteBlockItem(uint16 block, int type) {
|
||||
uint16 itm = _levelBlockProperties[block].drawObjects;
|
||||
if (!itm)
|
||||
return;
|
||||
|
||||
for (uint16 i2 = itm, i = 0; itm != i2 || !i; i++ ) {
|
||||
if (type == _items[itm].type || type == -1) {
|
||||
_items[itm].block = -1;
|
||||
_items[itm].level = 0;
|
||||
uint16 i3 = itm;
|
||||
itm = _items[itm].prev;
|
||||
_items[i3].prev = _items[i3].next = 0;
|
||||
} else {
|
||||
uint16 i3 = itm;
|
||||
itm = _items[itm].prev;
|
||||
_items[i3].prev = _items[i3].next = 0;
|
||||
setItemPosition((Item*)&_levelBlockProperties[block].drawObjects, block, i3, _items[i3].pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int slot) {
|
||||
if (item < 0)
|
||||
return 0;
|
||||
|
||||
int offset = (_flags.gameID == GI_EOB1) ? 11 : (_flags.lang == Common::DE_DEU ? 16 : 12);
|
||||
|
||||
if (slot == 17 && item && !itemUsableByCharacter(charIndex, item)) {
|
||||
_txt->printMessage(_itemExtraStrings[offset], -1, _characters[charIndex].name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int itm = _characters[charIndex].inventory[slot];
|
||||
int ex = _itemTypes[_items[itm].type].extraProperties & 0x7f;
|
||||
|
||||
if (slot < 2 && _items[itm].flags & 0x20 && ex > 0 && ex < 4) {
|
||||
_txt->printMessage(_itemExtraStrings[offset + 1], -1, _characters[charIndex].name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 v = item ? _itemTypes[_items[item].type].invFlags : 0xffff;
|
||||
if (v & _slotValidationFlags[slot])
|
||||
return 1;
|
||||
|
||||
_txt->printMessage(_itemExtraStrings[offset + (_flags.gameID == GI_EOB1 ? 1 : 2)]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EobCoreEngine::deletePartyItem(Item itemType, int16 itemValue) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 1))
|
||||
continue;
|
||||
|
||||
EobCharacter *c = &_characters[i];
|
||||
int slot = checkCharacterInventoryForItem(i, itemType, itemValue);
|
||||
|
||||
if (slot == -1)
|
||||
continue;
|
||||
|
||||
int itm = c->inventory[slot];
|
||||
_items[itm].block = -1;
|
||||
c->inventory[slot] = 0;
|
||||
|
||||
if (_currentControlMode == 0 && slot < 2 && i < 5)
|
||||
gui_drawWeaponSlot(i, slot);
|
||||
|
||||
if (_currentControlMode == 1 && i == _updateCharNum)
|
||||
gui_drawInventoryItem(slot, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int EobCoreEngine::itemUsableByCharacter(int charIndex, Item item) {
|
||||
if (!item)
|
||||
return 1;
|
||||
|
||||
return (_itemTypes[_items[item].type].allowedClasses & _classModifierFlags[_characters[charIndex].cClass]);
|
||||
}
|
||||
|
||||
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) || (id != o1))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!includeFlyingItems) {
|
||||
if (itm->pos > 3 && itm->pos < 8)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return o1;
|
||||
|
||||
res++;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int EobCoreEngine::getQueuedItem(Item *items, int pos, int id) {
|
||||
Item o1 = *items;
|
||||
Item o2 = o1;
|
||||
|
||||
if (!o1)
|
||||
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;
|
||||
_items[p].next = n;
|
||||
itm->next = itm->prev = itm->block = 0;
|
||||
itm->level = 0;
|
||||
if (o1 == *items)
|
||||
*items = p;
|
||||
if (o1 == *items)
|
||||
*items = 0;
|
||||
|
||||
return o1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EobCoreEngine::printFullItemName(Item item) {
|
||||
EobItem *itm = &_items[item];
|
||||
const char *nameUnid = _itemNames[itm->nameUnid];
|
||||
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;
|
||||
int e = 0;
|
||||
|
||||
char tmpString[61];
|
||||
|
||||
if ((itm->flags & 0x40) && !strlen(nameId)) {
|
||||
switch (f) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
if (v == 0)
|
||||
strcpy(tmpString, nameUnid);
|
||||
else if (v < 0)
|
||||
sprintf(tmpString, _itemExtraStrings[3], v, nameUnid);
|
||||
else
|
||||
sprintf(tmpString, _itemExtraStrings[4], v, nameUnid);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
tstr2 = _itemExtraStrings[5];
|
||||
tstr3 = _spells[v].name;
|
||||
e = 1;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
tstr2 = _itemExtraStrings[6];
|
||||
tstr3 = _spells[_flags.gameID == GI_EOB1 ? (_clericSpellOffset + v) : v].name;
|
||||
e = 1;
|
||||
break;
|
||||
|
||||
case 14:
|
||||
tstr2 = _itemExtraStrings[8];
|
||||
tstr3 = _itemSuffixStrings[8];
|
||||
break;
|
||||
|
||||
case 16:
|
||||
tstr2 = _itemExtraStrings[7];
|
||||
tstr3 = _itemSuffixStrings[v + 6];
|
||||
e = 0;
|
||||
break;
|
||||
|
||||
case 18:
|
||||
if (v == 5) {
|
||||
tstr2 = _itemExtraStrings[_flags.lang == Common::EN_ANY ? 9 : 10];
|
||||
e = 1;
|
||||
} else {
|
||||
tstr2 = _itemExtraStrings[9];
|
||||
e = 0;
|
||||
}
|
||||
tstr3 = _itemSuffixStrings[v + (_flags.lang == Common::EN_ANY ? 11 : 15)];
|
||||
break;
|
||||
|
||||
default:
|
||||
strcpy(tmpString, nameUnid);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (tstr3) {
|
||||
if (!tstr2) {
|
||||
sprintf(tmpString, _itemExtraStrings[_flags.lang == Common::EN_ANY ? 10 : 11], tstr3);
|
||||
} else {
|
||||
if (e == 1) {
|
||||
if (tstr2 == _itemExtraStrings[12])
|
||||
sprintf(tmpString, _itemExtraStrings[_flags.lang == Common::EN_ANY ? 11 : 14], tstr2, tstr3);
|
||||
else
|
||||
sprintf(tmpString, _itemExtraStrings[_flags.gameID == GI_EOB1 ? 10 : (_flags.lang == Common::EN_ANY ? 11 : 13)], tstr2, tstr3);
|
||||
} else {
|
||||
sprintf(tmpString, _itemExtraStrings[_flags.gameID == GI_EOB1 ? 10 : (_flags.lang == Common::EN_ANY ? 11 : 15)], tstr2, tstr3);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
strcpy(tmpString, (itm->flags & 0x40) ? nameId : nameUnid);
|
||||
}
|
||||
|
||||
_txt->printMessage(tmpString);
|
||||
}
|
||||
|
||||
void EobCoreEngine::identifyQueuedItems(Item itemQueue) {
|
||||
if (!itemQueue)
|
||||
return;
|
||||
|
||||
Item first = itemQueue;
|
||||
do {
|
||||
_items[itemQueue].flags |= 0x40;
|
||||
itemQueue = _items[itemQueue].prev;
|
||||
|
||||
} while (first != itemQueue);
|
||||
}
|
||||
|
||||
void EobCoreEngine::drawItemIconShape(int pageNum, Item itemId, int x, int y) {
|
||||
int icn = _items[itemId].icon;
|
||||
bool applyBluePal = ((_partyEffectFlags & 2) && (_items[itemId].flags & 0x80)) ? true : false;
|
||||
|
||||
if (applyBluePal) {
|
||||
_screen->setFadeTableIndex(3);
|
||||
_screen->setShapeFadeMode(1, true);
|
||||
}
|
||||
|
||||
_screen->drawShape(pageNum, _itemIconShapes[icn], x, y, 0);
|
||||
|
||||
if (applyBluePal) {
|
||||
_screen->setFadeTableIndex(4);
|
||||
_screen->setShapeFadeMode(1, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool EobCoreEngine::isMagicWeapon(Item itemIndex) {
|
||||
return (_items[itemIndex].type > 10 && _items[itemIndex].type < 18);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::checkInventoryForRings(int charIndex, int itemValue) {
|
||||
for (int i = 25; i <= 26; i++) {
|
||||
int itm = _characters[charIndex].inventory[i];
|
||||
if (itm && _items[itm].type == 47 && _items[itm].value == itemValue)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EobCoreEngine::eatItemInHand(int charIndex) {
|
||||
EobCharacter *c = &_characters[charIndex];
|
||||
if (!testCharacter(charIndex, 5)) {
|
||||
_txt->printMessage(_warningStrings[1], -1, c->name);
|
||||
} else if (_itemInHand && _items[_itemInHand].type != 31) {
|
||||
_txt->printMessage(_warningStrings[3]);
|
||||
} else if (_items[_itemInHand].value == -1) {
|
||||
_txt->printMessage(_warningStrings[2]);
|
||||
snd_playSoundEffect(79);
|
||||
} else {
|
||||
c->food += _items[_itemInHand].value;
|
||||
if (c->food > 100)
|
||||
c->food = 100;
|
||||
|
||||
_items[_itemInHand].block = -1;
|
||||
setHandItem(0);
|
||||
gui_drawFoodStatusGraph(charIndex);
|
||||
_screen->updateScreen();
|
||||
snd_playSoundEffect(9);
|
||||
}
|
||||
}
|
||||
|
||||
bool EobCoreEngine::launchObject(int charIndex, Item item, uint16 startBlock, int startPos, int dir, int type) {
|
||||
EobFlyingObject *t = _flyingObjects;
|
||||
int slot = 0;
|
||||
for (; slot < 10; slot++) {
|
||||
if (!t->enable)
|
||||
break;
|
||||
t++;
|
||||
}
|
||||
|
||||
if (slot == 10)
|
||||
return false;
|
||||
|
||||
setItemPosition((Item*)&_levelBlockProperties[startBlock].drawObjects, startBlock, item, startPos | 4);
|
||||
|
||||
t->enable = 1;
|
||||
t->u2 = 1;
|
||||
t->flags = 0;
|
||||
t->direction = dir;
|
||||
t->distance = 12;
|
||||
t->curBlock = startBlock;
|
||||
t->curPos = startPos;
|
||||
t->item = item;
|
||||
t->objectType = type;
|
||||
t->attackerId = charIndex;
|
||||
t->callBackIndex = 0;
|
||||
|
||||
snd_playSoundEffect(type == 7 ? 26 : 11);
|
||||
return true;
|
||||
}
|
||||
|
||||
void EobCoreEngine::launchMagicObject(int charIndex, int type, uint16 startBlock, int startPos, int dir) {
|
||||
EobFlyingObject *t = _flyingObjects;
|
||||
int slot = 0;
|
||||
for (; slot < 10; slot++) {
|
||||
if (!t->enable)
|
||||
break;
|
||||
t++;
|
||||
}
|
||||
|
||||
if (slot == 10)
|
||||
return;
|
||||
|
||||
t->enable = 2;
|
||||
t->u2 = 1;
|
||||
t->flags = _magicFlightObjectProperties[(type << 2) + 2];
|
||||
t->direction = dir;
|
||||
t->distance = _magicFlightObjectProperties[(type << 2) + 1];
|
||||
t->curBlock = startBlock;
|
||||
t->curPos = startPos;
|
||||
t->item = type;
|
||||
t->objectType = _magicFlightObjectProperties[(type << 2) + 3];
|
||||
t->attackerId = charIndex;
|
||||
t->u2 = 1;
|
||||
t->callBackIndex = _magicFlightObjectProperties[type << 2];
|
||||
_sceneUpdateRequired = true;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::updateObjectFlight(EobFlyingObject *fo, int block, int pos) {
|
||||
uint8 wallFlags = _wllWallFlags[_levelBlockProperties[block].walls[fo->direction ^ 2]];
|
||||
if (fo->enable == 1) {
|
||||
if ((wallFlags & 1) || (fo->u2) || ((wallFlags & 2) && (_dscItemShapeMap[_items[fo->item].icon] >= 15))) {
|
||||
getQueuedItem((Item*)&_levelBlockProperties[fo->curBlock].drawObjects, 0, fo->item);
|
||||
setItemPosition((Item*)&_levelBlockProperties[block].drawObjects, block, fo->item, pos | 4);
|
||||
fo->curBlock = block;
|
||||
fo->curPos = pos;
|
||||
fo->distance--;
|
||||
return true;
|
||||
|
||||
} else {
|
||||
_clickedSpecialFlag = 0x10;
|
||||
specialWallAction(block, fo->direction);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!(wallFlags & 1) && (fo->curBlock != block))
|
||||
return false;
|
||||
fo->curBlock = block;
|
||||
fo->curPos = pos;
|
||||
if (fo->distance != 255)
|
||||
fo->distance--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::updateFlyingObjectHitTest(EobFlyingObject *fo, int block, int pos) {
|
||||
if (fo->u2 && (fo->curBlock != _currentBlock || fo->attackerId >= 0) && (!blockHasMonsters(block) || fo->attackerId < 0))
|
||||
return false;
|
||||
|
||||
if (fo->enable == 2) {
|
||||
if (fo->callBackIndex)
|
||||
return (this->*_spells[fo->callBackIndex].endCallback)(fo);
|
||||
}
|
||||
|
||||
if (blockHasMonsters(block)) {
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (!isMonsterOnPos(&_monsters[i], block, pos, 1))
|
||||
continue;
|
||||
if (flyingObjectMonsterHit(fo, i))
|
||||
return true;
|
||||
}
|
||||
|
||||
} else if (block == _currentBlock) {
|
||||
return flyingObjectPartyHit(fo);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void EobCoreEngine::updateFlyingObject_s3(EobFlyingObject *fo) {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::endObjectFlight(EobFlyingObject *fo) {
|
||||
if (fo->enable == 1) {
|
||||
_items[fo->item].pos &= 3;
|
||||
runLevelScript(fo->curBlock, 4);
|
||||
updateEnvironmentalSfx(18);
|
||||
}
|
||||
memset(fo, 0, sizeof(EobFlyingObject));
|
||||
}
|
||||
|
||||
void EobCoreEngine::checkFlyingObjects() {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
EobFlyingObject *fo = &_flyingObjects[i];
|
||||
if (!fo->enable)
|
||||
continue;
|
||||
if (updateFlyingObjectHitTest(fo, fo->curBlock, fo->curPos))
|
||||
endObjectFlight(fo);
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::reloadWeaponSlot(int charIndex, int slotIndex, int itemType, int arrowOrDagger) {
|
||||
if (arrowOrDagger && _characters[charIndex].inventory[16]) {
|
||||
_characters[charIndex].inventory[slotIndex] = getQueuedItem(&_characters[charIndex].inventory[16], 0, -1);
|
||||
} else {
|
||||
for (int i = 24; i >= 22; i--) {
|
||||
if (!_characters[charIndex].inventory[i])
|
||||
continue;
|
||||
if (_items[_characters[charIndex].inventory[i]].type == itemType && itemType != -1)
|
||||
continue;
|
||||
_characters[charIndex].inventory[slotIndex] = _characters[charIndex].inventory[i];
|
||||
_characters[charIndex].inventory[i] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
||||
|
@ -171,7 +171,7 @@ KyraEngine_HoF::~KyraEngine_HoF() {
|
||||
delete[] _conversationState[i];
|
||||
delete[] _conversationState;
|
||||
|
||||
for (Common::Array<const TIMOpcode *>::iterator i = _timOpcodes.begin(); i != _timOpcodes.end(); ++i)
|
||||
for (Common::Array<const TIMOpcode*>::iterator i = _timOpcodes.begin(); i != _timOpcodes.end(); ++i)
|
||||
delete *i;
|
||||
_timOpcodes.clear();
|
||||
}
|
||||
|
@ -656,7 +656,7 @@ protected:
|
||||
int t2_resetChat(const TIM *tim, const uint16 *param);
|
||||
int t2_playSoundEffect(const TIM *tim, const uint16 *param);
|
||||
|
||||
Common::Array<const TIMOpcode *> _timOpcodes;
|
||||
Common::Array<const TIMOpcode*> _timOpcodes;
|
||||
|
||||
// sound
|
||||
int _oldTalkFile;
|
||||
|
@ -183,7 +183,7 @@ KyraEngine_MR::~KyraEngine_MR() {
|
||||
delete[] _sceneStrings;
|
||||
delete[] _talkObjectList;
|
||||
|
||||
for (Common::Array<const Opcode *>::iterator i = _opcodesDialog.begin(); i != _opcodesDialog.end(); ++i)
|
||||
for (Common::Array<const Opcode*>::iterator i = _opcodesDialog.begin(); i != _opcodesDialog.end(); ++i)
|
||||
delete *i;
|
||||
_opcodesDialog.clear();
|
||||
|
||||
|
@ -463,7 +463,7 @@ private:
|
||||
|
||||
void npcChatSequence(const char *str, int object, int vocHigh, int vocLow);
|
||||
|
||||
Common::Array<const Opcode *> _opcodesDialog;
|
||||
Common::Array<const Opcode*> _opcodesDialog;
|
||||
|
||||
int o3d_updateAnim(EMCState *script);
|
||||
int o3d_delay(EMCState *script);
|
||||
|
@ -211,7 +211,7 @@ Common::Error KyraEngine_v1::init() {
|
||||
}
|
||||
|
||||
KyraEngine_v1::~KyraEngine_v1() {
|
||||
for (Common::Array<const Opcode *>::iterator i = _opcodes.begin(); i != _opcodes.end(); ++i)
|
||||
for (Common::Array<const Opcode*>::iterator i = _opcodes.begin(); i != _opcodes.end(); ++i)
|
||||
delete *i;
|
||||
_opcodes.clear();
|
||||
_keyMap.clear();
|
||||
@ -354,14 +354,14 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
|
||||
}
|
||||
|
||||
void KyraEngine_v1::setupKeyMap() {
|
||||
struct KeyMapEntry {
|
||||
struct KeyCodeMapEntry {
|
||||
Common::KeyCode kcScummVM;
|
||||
int16 kcDOS;
|
||||
int16 kcPC98;
|
||||
};
|
||||
|
||||
#define KC(x) Common::KEYCODE_##x
|
||||
static const KeyMapEntry keys[] = {
|
||||
static const KeyCodeMapEntry keys[] = {
|
||||
{ KC(SPACE), 61, 53 },
|
||||
{ KC(RETURN), 43, 29 },
|
||||
{ KC(UP), 96, 68 },
|
||||
@ -377,13 +377,48 @@ void KyraEngine_v1::setupKeyMap() {
|
||||
{ KC(KP7), 91, 67 },
|
||||
{ KC(PAGEUP), 101, 69 },
|
||||
{ KC(KP9), 101, 69 },
|
||||
{ KC(END), 93, 0/*unknown*/ },
|
||||
{ KC(KP1), 93, 0/*unknown*/ },
|
||||
{ KC(PAGEDOWN), 103, 0/*unknown*/ },
|
||||
{ KC(KP3), 103, 0/*unknown*/ },
|
||||
{ KC(F1), 112, 99 },
|
||||
{ KC(F2), 113, 100 },
|
||||
{ KC(F3), 114, 101 },
|
||||
{ KC(F4), 115, 102 },
|
||||
{ KC(F5), 116, 103 },
|
||||
{ KC(F6), 117, 104 },
|
||||
{ KC(a), 31, 31 },
|
||||
{ KC(b), 50, 50 },
|
||||
{ KC(c), 48, 48 },
|
||||
{ KC(d), 33, 33 },
|
||||
{ KC(e), 19, 19 },
|
||||
{ KC(f), 34, 34 },
|
||||
{ KC(i), 24, 24 },
|
||||
{ KC(k), 38, 38 },
|
||||
{ KC(m), 52, 52 },
|
||||
{ KC(n), 51, 51 },
|
||||
{ KC(o), 25, 25 },
|
||||
{ KC(p), 26, 26 },
|
||||
{ KC(r), 20, 20 },
|
||||
{ KC(s), 32, 32 },
|
||||
{ KC(w), 18, 18 },
|
||||
{ KC(y), 22, 22 },
|
||||
{ KC(z), 46, 46 },
|
||||
{ KC(1), 2, 0/*unknown*/ },
|
||||
{ KC(2), 3, 0/*unknown*/ },
|
||||
{ KC(3), 4, 0/*unknown*/ },
|
||||
{ KC(4), 5, 0/*unknown*/ },
|
||||
{ KC(5), 6, 0/*unknown*/ },
|
||||
{ KC(6), 7, 0/*unknown*/ },
|
||||
{ KC(7), 8, 0/*unknown*/ },
|
||||
{ KC(SLASH), 55, 55 },
|
||||
{ KC(ESCAPE), 110, 1 },
|
||||
{ KC(MINUS), 12, 0/*unknown*/ },
|
||||
{ KC(KP_MINUS), 105, 0/*unknown*/ },
|
||||
{ KC(PLUS), 13, 0/*unknown*/ },
|
||||
{ KC(KP_PLUS), 106, 0/*unknown*/ },
|
||||
{ KC(COMMA), 53, 0/*unknown*/ },
|
||||
{ KC(PERIOD), 54, 0/*unknown*/ }
|
||||
};
|
||||
#undef KC
|
||||
|
||||
|
@ -323,7 +323,7 @@ protected:
|
||||
|
||||
// opcode
|
||||
virtual void setupOpcodeTable() = 0;
|
||||
Common::Array<const Opcode *> _opcodes;
|
||||
Common::Array<const Opcode*> _opcodes;
|
||||
|
||||
int o1_queryGameFlag(EMCState *script);
|
||||
int o1_setGameFlag(EMCState *script);
|
||||
|
@ -252,7 +252,7 @@ protected:
|
||||
virtual void uninitAnimationShapes(int count, uint8 *filedata) = 0;
|
||||
|
||||
// Shapes
|
||||
typedef Common::HashMap<int, uint8 *> ShapeMap;
|
||||
typedef Common::HashMap<int, uint8*> ShapeMap;
|
||||
ShapeMap _gameShapes;
|
||||
|
||||
uint8 *getShapePtr(int index) const;
|
||||
|
@ -42,10 +42,9 @@ namespace Kyra {
|
||||
|
||||
const char *const LoLEngine::kKeymapName = "lol";
|
||||
|
||||
LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags) {
|
||||
LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : LolEobBaseEngine(system, flags) {
|
||||
_screen = 0;
|
||||
_gui = 0;
|
||||
_txt = 0;
|
||||
_tim = 0;
|
||||
|
||||
_lang = 0;
|
||||
@ -97,15 +96,11 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
|
||||
memset(_inventory, 0, sizeof(_inventory));
|
||||
memset(_charStatusFlags, 0, sizeof(_charStatusFlags));
|
||||
_inventoryCurItem = 0;
|
||||
_currentControlMode = 0;
|
||||
_specialSceneFlag = 0;
|
||||
_lastCharInventory = -1;
|
||||
_emcLastItem = -1;
|
||||
|
||||
_itemIconShapes = _itemShapes = _gameShapes = _thrownShapes = _effectShapes = _fireballShapes = _healShapes = _healiShapes = 0;
|
||||
_levelShpList = _levelDatList = 0;
|
||||
_monsterShapes = _monsterPalettes = 0;
|
||||
_monsterShapesEx = 0;
|
||||
_gameShapeMap = 0;
|
||||
memset(_monsterAnimType, 0, 3);
|
||||
_healOverlay = 0;
|
||||
@ -116,10 +111,8 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
|
||||
_charSelection = -1;
|
||||
_characters = 0;
|
||||
_spellProperties = 0;
|
||||
_updateFlags = 0;
|
||||
_selectedSpell = 0;
|
||||
_updateCharNum = _updatePortraitSpeechAnimDuration = _portraitSpeechAnimMode = _resetPortraitAfterSpeechAnim = _textColorFlag = _needSceneRestore = 0;
|
||||
_fadeText = false;
|
||||
_updateCharNum = _portraitSpeechAnimMode = _textColorFlag = 0;
|
||||
_palUpdateTimer = _updatePortraitNext = 0;
|
||||
_lampStatusTimer = 0xffffffff;
|
||||
|
||||
@ -128,66 +121,42 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
|
||||
_lastButtonShape = 0;
|
||||
_buttonPressTimer = 0;
|
||||
_selectedCharacter = 0;
|
||||
_suspendScript = _sceneUpdateRequired = false;
|
||||
_suspendScript = false;
|
||||
_scriptDirection = 0;
|
||||
_currentDirection = 0;
|
||||
_currentBlock = 0;
|
||||
_compassDirection = _compassDirectionIndex = -1;
|
||||
_compassDirectionIndex = -1;
|
||||
_compassStep = 0;
|
||||
memset(_visibleBlockIndex, 0, sizeof(_visibleBlockIndex));
|
||||
|
||||
_smoothScrollModeNormal = 1;
|
||||
_wllVmpMap = _specialWallTypes = _wllBuffer4 = _wllWallFlags = 0;
|
||||
_wllShapeMap = 0;
|
||||
_lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0;
|
||||
_levelBlockProperties = 0;
|
||||
_wllAutomapData = 0;
|
||||
_sceneXoffset = 112;
|
||||
_sceneShpDim = 13;
|
||||
_monsters = 0;
|
||||
_monsterProperties = 0;
|
||||
_lvlBlockIndex = _lvlShapeIndex = 0;
|
||||
_lvlShapeIndex = 0;
|
||||
_partyAwake = true;
|
||||
_vcnBlocks = 0;
|
||||
_vcnShift = 0;
|
||||
_vcnExpTable = 0;
|
||||
_vmpPtr = 0;
|
||||
_vcfBlocks = 0;
|
||||
_transparencyTable2 = 0;
|
||||
_transparencyTable1 = 0;
|
||||
_levelShapeProperties = 0;
|
||||
_levelShapes = 0;
|
||||
_specialGuiShape = 0;
|
||||
_specialGuiShapeX = _specialGuiShapeY = _specialGuiShapeMirrorFlag = 0;
|
||||
_blockDrawingBuffer = 0;
|
||||
_sceneWindowBuffer = 0;
|
||||
memset(_doorShapes, 0, sizeof(_doorShapes));
|
||||
memset(_characterFaceShapes, 0, sizeof(_characterFaceShapes));
|
||||
|
||||
_lampEffect = _brightness = _lampOilStatus = 0;
|
||||
_lampStatusSuspended = false;
|
||||
_blockBrightness = 0;
|
||||
_tempBuffer5120 = 0;
|
||||
_flyingObjects = 0;
|
||||
_monsters = 0;
|
||||
_lastMouseRegion = 0;
|
||||
_objectLastDirection = _monsterStepCounter = _monsterStepMode = 0;
|
||||
_objectLastDirection = 0;
|
||||
_monsterCurBlock = 0;
|
||||
_seqWindowX1 = _seqWindowY1 = _seqWindowX2 = _seqWindowY2 = _seqTrigger = 0;
|
||||
_spsWindowX = _spsWindowY = _spsWindowW = _spsWindowH = 0;
|
||||
|
||||
_dscUnk1 = 0;
|
||||
_dscShapeIndex = 0;
|
||||
_dscWalls = 0;
|
||||
_dscOvlMap = 0;
|
||||
_dscShapeScaleW = 0;
|
||||
_dscShapeScaleH = 0;
|
||||
_dscShapeX = 0;
|
||||
_dscShapeScaleH = 0;
|
||||
_dscShapeY = 0;
|
||||
_dscTileIndex = 0;
|
||||
_dscUnk2 = 0;
|
||||
_dscDoorShpIndex = 0;
|
||||
_dscDim1 = 0;
|
||||
_dscDim2 = 0;
|
||||
_dscBlockMap = _dscDoor1 = _dscShapeOvlIndex = 0;
|
||||
_dscBlockIndex = 0;
|
||||
_dscDimMap = 0;
|
||||
_dscShapeOvlIndex = 0;
|
||||
_dscDoorMonsterX = _dscDoorMonsterY = 0;
|
||||
_dscDoor4 = 0;
|
||||
|
||||
@ -198,29 +167,24 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
|
||||
_curMusicTheme = -1;
|
||||
_curMusicFileExt = 0;
|
||||
_curMusicFileIndex = -1;
|
||||
_environmentSfx = _environmentSfxVol = _envSfxDistThreshold = 0;
|
||||
_envSfxUseQueue = false;
|
||||
_envSfxNumTracksInQueue = 0;
|
||||
memset(_envSfxQueuedTracks, 0, sizeof(_envSfxQueuedTracks));
|
||||
memset(_envSfxQueuedBlocks, 0, sizeof(_envSfxQueuedBlocks));
|
||||
|
||||
_sceneDrawVarDown = _sceneDrawVarRight = _sceneDrawVarLeft = _wllProcessFlag = 0;
|
||||
_partyPosX = _partyPosY = 0;
|
||||
_shpDmX = _shpDmY = _dmScaleW = _dmScaleH = 0;
|
||||
|
||||
_floatingCursorControl = _currentFloatingCursor = 0;
|
||||
|
||||
memset(_activeTim, 0, sizeof(_activeTim));
|
||||
memset(_openDoorState, 0, sizeof(_openDoorState));
|
||||
memset(&_activeSpell, 0, sizeof(_activeSpell));
|
||||
|
||||
_activeVoiceFileTotalTime = 0;
|
||||
_pageBuffer1 = _pageBuffer2 = 0;
|
||||
|
||||
memset(_charStatsTemp, 0, sizeof(_charStatsTemp));
|
||||
|
||||
_compassBroken = _drainMagic = 0;
|
||||
_dialogueField = false;
|
||||
|
||||
_buttonData = 0;
|
||||
_activeButtons = 0;
|
||||
@ -228,8 +192,6 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
|
||||
_preserveEvents = false;
|
||||
_buttonList1 = _buttonList2 = _buttonList3 = _buttonList4 = _buttonList5 = _buttonList6 = _buttonList7 = _buttonList8 = 0;
|
||||
|
||||
memset(_lvlTempData, 0, sizeof(_lvlTempData));
|
||||
|
||||
_mapOverlay = 0;
|
||||
_automapShapes = 0;
|
||||
_defaultLegendData = 0;
|
||||
@ -250,6 +212,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
|
||||
|
||||
LoLEngine::~LoLEngine() {
|
||||
setupPrologueData(false);
|
||||
releaseTempData();
|
||||
|
||||
#ifdef ENABLE_KEYMAPPER
|
||||
_eventMan->getKeymapper()->cleanupGameKeymaps();
|
||||
@ -264,8 +227,6 @@ LoLEngine::~LoLEngine() {
|
||||
_gui = 0;
|
||||
delete _tim;
|
||||
_tim = 0;
|
||||
delete _txt;
|
||||
_txt = 0;
|
||||
|
||||
delete[] _itemsInPlay;
|
||||
delete[] _itemProperties;
|
||||
@ -322,64 +283,47 @@ LoLEngine::~LoLEngine() {
|
||||
delete[] _healiShapes;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
releaseMonsterShapes(i);
|
||||
if (_monsterDecorationShapes) {
|
||||
for (int i = 0; i < 3; i++)
|
||||
releaseMonsterShapes(i);
|
||||
|
||||
delete[] _monsterShapes;
|
||||
delete[] _monsterPalettes;
|
||||
delete[] _monsterShapesEx;
|
||||
delete[] _monsterShapes;
|
||||
_monsterShapes = 0;
|
||||
delete[] _monsterPalettes;
|
||||
_monsterPalettes = 0;
|
||||
delete[] _monsterDecorationShapes;
|
||||
_monsterDecorationShapes = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
delete[] _doorShapes[i];
|
||||
_doorShapes[i] = 0;
|
||||
}
|
||||
|
||||
delete[] _automapShapes;
|
||||
|
||||
for (Common::Array<const TIMOpcode *>::iterator i = _timIntroOpcodes.begin(); i != _timIntroOpcodes.end(); ++i)
|
||||
for (Common::Array<const TIMOpcode*>::iterator i = _timIntroOpcodes.begin(); i != _timIntroOpcodes.end(); ++i)
|
||||
delete *i;
|
||||
_timIntroOpcodes.clear();
|
||||
|
||||
for (Common::Array<const TIMOpcode *>::iterator i = _timOutroOpcodes.begin(); i != _timOutroOpcodes.end(); ++i)
|
||||
for (Common::Array<const TIMOpcode*>::iterator i = _timOutroOpcodes.begin(); i != _timOutroOpcodes.end(); ++i)
|
||||
delete *i;
|
||||
_timOutroOpcodes.clear();
|
||||
|
||||
for (Common::Array<const TIMOpcode *>::iterator i = _timIngameOpcodes.begin(); i != _timIngameOpcodes.end(); ++i)
|
||||
for (Common::Array<const TIMOpcode*>::iterator i = _timIngameOpcodes.begin(); i != _timIngameOpcodes.end(); ++i)
|
||||
delete *i;
|
||||
_timIngameOpcodes.clear();
|
||||
|
||||
|
||||
delete[] _wllVmpMap;
|
||||
delete[] _wllShapeMap;
|
||||
delete[] _specialWallTypes;
|
||||
delete[] _wllBuffer4;
|
||||
delete[] _wllWallFlags;
|
||||
delete[] _lvlShapeTop;
|
||||
delete[] _lvlShapeBottom;
|
||||
delete[] _lvlShapeLeftRight;
|
||||
delete[] _wllAutomapData;
|
||||
delete[] _tempBuffer5120;
|
||||
delete[] _flyingObjects;
|
||||
delete[] _monsters;
|
||||
delete[] _levelBlockProperties;
|
||||
delete[] _monsterProperties;
|
||||
|
||||
delete[] _levelFileData;
|
||||
delete[] _vcnExpTable;
|
||||
delete[] _vcnBlocks;
|
||||
delete[] _vcnShift;
|
||||
delete[] _vmpPtr;
|
||||
delete[] _vcfBlocks;
|
||||
delete[] _transparencyTable2;
|
||||
delete[] _transparencyTable1;
|
||||
delete[] _levelShapeProperties;
|
||||
delete[] _blockDrawingBuffer;
|
||||
delete[] _sceneWindowBuffer;
|
||||
delete[] _lightningProps;
|
||||
|
||||
if (_levelShapes) {
|
||||
for (int i = 0; i < 400; i++)
|
||||
delete[] _levelShapes[i];
|
||||
delete[] _levelShapes;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
delete[] _doorShapes[i];
|
||||
|
||||
delete _lvlShpFileHandle;
|
||||
|
||||
if (_ingameSoundList) {
|
||||
@ -388,16 +332,6 @@ LoLEngine::~LoLEngine() {
|
||||
delete[] _ingameSoundList;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 29; i++) {
|
||||
if (_lvlTempData[i]) {
|
||||
delete[] _lvlTempData[i]->wallsXorData;
|
||||
delete[] _lvlTempData[i]->flags;
|
||||
delete[] _lvlTempData[i]->monsters;
|
||||
delete[] _lvlTempData[i]->flyingObjects;
|
||||
delete _lvlTempData[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int ii = 0; ii < 40; ii++)
|
||||
delete[] _characterFaceShapes[ii][i];
|
||||
@ -409,7 +343,7 @@ LoLEngine::~LoLEngine() {
|
||||
delete[] _mapCursorOverlay;
|
||||
delete[] _mapOverlay;
|
||||
|
||||
for (Common::Array<const SpellProc *>::iterator i = _spellProcs.begin(); i != _spellProcs.end(); ++i)
|
||||
for (Common::Array<const SpellProc*>::iterator i = _spellProcs.begin(); i != _spellProcs.end(); ++i)
|
||||
delete *i;
|
||||
_spellProcs.clear();
|
||||
|
||||
@ -440,13 +374,18 @@ Common::Error LoLEngine::init() {
|
||||
KyraEngine_v1::init();
|
||||
initStaticResource();
|
||||
|
||||
_envSfxDistThreshold = _sound->getSfxType() == Sound::kAdLib ? 15 : 3;
|
||||
|
||||
_gui = new GUI_LoL(this);
|
||||
assert(_gui);
|
||||
_gui->initStaticData();
|
||||
|
||||
_txt = new TextDisplayer_LoL(this, _screen);
|
||||
_dialogueButtonLabelCol1 = 144;
|
||||
_dialogueButtonLabelCol2 = 254;
|
||||
_dialogueButtonW = 74;
|
||||
_dialogueButtonH = 9;
|
||||
_bkgColor_1 = -1;
|
||||
_color1_1 = 136;
|
||||
_color2_1 = 251;
|
||||
|
||||
_screen->setAnimBlockPtr(10000);
|
||||
_screen->setScreenDim(0);
|
||||
@ -465,41 +404,15 @@ Common::Error LoLEngine::init() {
|
||||
if (!_sound->init())
|
||||
error("Couldn't init sound");
|
||||
|
||||
_wllVmpMap = new uint8[80];
|
||||
memset(_wllVmpMap, 0, 80);
|
||||
_wllShapeMap = new int8[80];
|
||||
memset(_wllShapeMap, 0, 80);
|
||||
_specialWallTypes = new uint8[80];
|
||||
memset(_specialWallTypes, 0, 80);
|
||||
_wllBuffer4 = new uint8[80];
|
||||
memset(_wllBuffer4, 0, 80);
|
||||
_wllWallFlags = new uint8[80];
|
||||
memset(_wllWallFlags, 0, 80);
|
||||
_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));
|
||||
_levelShapeProperties = new LevelShapeProperty[100];
|
||||
memset(_levelShapeProperties, 0, 100 * sizeof(LevelShapeProperty));
|
||||
_levelShapes = new uint8 *[400];
|
||||
memset(_levelShapes, 0, 400 * sizeof(uint8 *));
|
||||
_blockDrawingBuffer = new uint16[1320];
|
||||
memset(_blockDrawingBuffer, 0, 1320 * sizeof(uint16));
|
||||
_sceneWindowBuffer = new uint8[21120];
|
||||
memset(_sceneWindowBuffer, 0, 21120);
|
||||
LolEobBaseEngine::init();
|
||||
|
||||
_wllAutomapData = new uint8[80];
|
||||
memset(_wllAutomapData, 0, 80);
|
||||
|
||||
_levelBlockProperties = new LevelBlockProperty[1025];
|
||||
memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty));
|
||||
_monsters = new MonsterInPlay[30];
|
||||
memset(_monsters, 0, 30 * sizeof(MonsterInPlay));
|
||||
_monsterProperties = new MonsterProperty[5];
|
||||
memset(_monsterProperties, 0, 5 * sizeof(MonsterProperty));
|
||||
|
||||
_vcnExpTable = new uint8[128];
|
||||
for (int i = 0; i < 128; i++)
|
||||
_vcnExpTable[i] = i & 0x0f;
|
||||
_monsters = new LolMonsterInPlay[30];
|
||||
memset(_monsters, 0, 30 * sizeof(LolMonsterInPlay));
|
||||
_monsterProperties = new LolMonsterProperty[5];
|
||||
memset(_monsterProperties, 0, 5 * sizeof(LolMonsterProperty));
|
||||
|
||||
_tempBuffer5120 = new uint8[5120];
|
||||
memset(_tempBuffer5120, 0, 5120);
|
||||
@ -509,25 +422,26 @@ Common::Error LoLEngine::init() {
|
||||
|
||||
memset(_globalScriptVars, 0, sizeof(_globalScriptVars));
|
||||
|
||||
_levelFileData = 0;
|
||||
_lvlShpFileHandle = 0;
|
||||
|
||||
_sceneDrawPage1 = 2;
|
||||
_sceneDrawPage2 = 6;
|
||||
|
||||
_monsterShapes = new uint8 *[48];
|
||||
memset(_monsterShapes, 0, 48 * sizeof(uint8 *));
|
||||
_monsterPalettes = new uint8 *[48];
|
||||
memset(_monsterPalettes, 0, 48 * sizeof(uint8 *));
|
||||
_clickedShapeXOffs = 136;
|
||||
_clickedShapeYOffs = 8;
|
||||
_clickedSpecialFlag = 0x40;
|
||||
|
||||
_monsterShapesEx = new uint8 *[576];
|
||||
memset(_monsterShapesEx, 0, 576 * sizeof(uint8 *));
|
||||
_monsterShapes = new uint8*[48];
|
||||
memset(_monsterShapes, 0, 48 * sizeof(uint8*));
|
||||
_monsterPalettes = new uint8*[48];
|
||||
memset(_monsterPalettes, 0, 48 * sizeof(uint8*));
|
||||
_monsterDecorationShapes = new uint8*[576];
|
||||
memset(_monsterDecorationShapes, 0, 576 * sizeof(uint8*));
|
||||
memset(&_scriptData, 0, sizeof(EMCData));
|
||||
|
||||
_hasTempDataFlags = 0;
|
||||
_activeMagicMenu = -1;
|
||||
|
||||
_automapShapes = new const uint8 *[109];
|
||||
_automapShapes = new const uint8*[109];
|
||||
_mapOverlay = new uint8[256];
|
||||
|
||||
memset(_availableSpells, -1, 8);
|
||||
@ -687,7 +601,7 @@ void LoLEngine::loadItemIconShapes() {
|
||||
_screen->loadBitmap("ITEMICN.SHP", 3, 3, 0);
|
||||
const uint8 *shp = _screen->getCPagePtr(3);
|
||||
_numItemIconShapes = READ_LE_UINT16(shp);
|
||||
_itemIconShapes = new uint8 *[_numItemIconShapes];
|
||||
_itemIconShapes = new uint8*[_numItemIconShapes];
|
||||
for (int i = 0; i < _numItemIconShapes; i++)
|
||||
_itemIconShapes[i] = _screen->makeShapeCopy(shp, i);
|
||||
|
||||
@ -697,7 +611,7 @@ void LoLEngine::loadItemIconShapes() {
|
||||
_screen->loadBitmap("GAMESHP.SHP", 3, 3, 0);
|
||||
shp = _screen->getCPagePtr(3);
|
||||
_numGameShapes = READ_LE_UINT16(shp);
|
||||
_gameShapes = new uint8 *[_numGameShapes];
|
||||
_gameShapes = new uint8*[_numGameShapes];
|
||||
for (int i = 0; i < _numGameShapes; i++)
|
||||
_gameShapes[i] = _screen->makeShapeCopy(shp, i);
|
||||
}
|
||||
@ -717,12 +631,6 @@ void LoLEngine::setMouseCursorToItemInHand() {
|
||||
_screen->setMouseCursor(o, o, getItemIconShapePtr(_itemInHand));
|
||||
}
|
||||
|
||||
bool LoLEngine::posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, int y2) {
|
||||
if (mouseX < x1 || mouseX > x2 || mouseY < y1 || mouseY > y2)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoLEngine::checkFloatingPointerRegions() {
|
||||
if (!_floatingCursorsEnabled)
|
||||
return;
|
||||
@ -877,42 +785,42 @@ void LoLEngine::startup() {
|
||||
_screen->loadBitmap("ITEMSHP.SHP", 3, 3, 0);
|
||||
const uint8 *shp = _screen->getCPagePtr(3);
|
||||
_numItemShapes = READ_LE_UINT16(shp);
|
||||
_itemShapes = new uint8 *[_numItemShapes];
|
||||
_itemShapes = new uint8*[_numItemShapes];
|
||||
for (int i = 0; i < _numItemShapes; i++)
|
||||
_itemShapes[i] = _screen->makeShapeCopy(shp, i);
|
||||
|
||||
_screen->loadBitmap("THROWN.SHP", 3, 3, 0);
|
||||
shp = _screen->getCPagePtr(3);
|
||||
_numThrownShapes = READ_LE_UINT16(shp);
|
||||
_thrownShapes = new uint8 *[_numThrownShapes];
|
||||
_thrownShapes = new uint8*[_numThrownShapes];
|
||||
for (int i = 0; i < _numThrownShapes; i++)
|
||||
_thrownShapes[i] = _screen->makeShapeCopy(shp, i);
|
||||
|
||||
_screen->loadBitmap("ICE.SHP", 3, 3, 0);
|
||||
shp = _screen->getCPagePtr(3);
|
||||
_numEffectShapes = READ_LE_UINT16(shp);
|
||||
_effectShapes = new uint8 *[_numEffectShapes];
|
||||
_effectShapes = new uint8*[_numEffectShapes];
|
||||
for (int i = 0; i < _numEffectShapes; i++)
|
||||
_effectShapes[i] = _screen->makeShapeCopy(shp, i);
|
||||
|
||||
_screen->loadBitmap("FIREBALL.SHP", 3, 3, 0);
|
||||
shp = _screen->getCPagePtr(3);
|
||||
_numFireballShapes = READ_LE_UINT16(shp);
|
||||
_fireballShapes = new uint8 *[_numFireballShapes];
|
||||
_fireballShapes = new uint8*[_numFireballShapes];
|
||||
for (int i = 0; i < _numFireballShapes; i++)
|
||||
_fireballShapes[i] = _screen->makeShapeCopy(shp, i);
|
||||
|
||||
_screen->loadBitmap("HEAL.SHP", 3, 3, 0);
|
||||
shp = _screen->getCPagePtr(3);
|
||||
_numHealShapes = READ_LE_UINT16(shp);
|
||||
_healShapes = new uint8 *[_numHealShapes];
|
||||
_healShapes = new uint8*[_numHealShapes];
|
||||
for (int i = 0; i < _numHealShapes; i++)
|
||||
_healShapes[i] = _screen->makeShapeCopy(shp, i);
|
||||
|
||||
_screen->loadBitmap("HEALI.SHP", 3, 3, 0);
|
||||
shp = _screen->getCPagePtr(3);
|
||||
_numHealiShapes = READ_LE_UINT16(shp);
|
||||
_healiShapes = new uint8 *[_numHealiShapes];
|
||||
_healiShapes = new uint8*[_numHealiShapes];
|
||||
for (int i = 0; i < _numHealiShapes; i++)
|
||||
_healiShapes[i] = _screen->makeShapeCopy(shp, i);
|
||||
|
||||
@ -969,10 +877,9 @@ void LoLEngine::runLoop() {
|
||||
|
||||
enableSysTimer(2);
|
||||
|
||||
bool _runFlag = true;
|
||||
_flagsTable[73] |= 0x08;
|
||||
|
||||
while (!shouldQuit() && _runFlag) {
|
||||
while (!shouldQuit()) {
|
||||
if (_gameToLoad != -1) {
|
||||
// FIXME: Instead of throwing away the error returned by
|
||||
// loadGameState, we should use it / augment it.
|
||||
@ -1784,44 +1691,6 @@ void LoLEngine::fadeText() {
|
||||
_fadeText = false;
|
||||
}
|
||||
|
||||
void LoLEngine::transformRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage) {
|
||||
uint16 *p1 = (uint16 *)_tempBuffer5120;
|
||||
uint16 *p2 = (uint16 *)(_tempBuffer5120 + 640);
|
||||
|
||||
for (int i = 0; i < w; i++)
|
||||
p1[i] = i;
|
||||
|
||||
for (int i = 0; i < h; i++)
|
||||
p2[i] = i;
|
||||
|
||||
for (int i = 0; i < w; i++)
|
||||
SWAP(p1[_rnd.getRandomNumberRng(0, w - 1)], p1[i]);
|
||||
|
||||
for (int i = 0; i < h; i++)
|
||||
SWAP(p2[_rnd.getRandomNumberRng(0, h - 1)], p2[i]);
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int i2 = i;
|
||||
|
||||
for (int ii = 0; ii < w; ii++) {
|
||||
int dx1 = x1 + p1[ii];
|
||||
int dy1 = y1 + p2[i2];
|
||||
int dx2 = x2 + p1[ii];
|
||||
int dy2 = y2 + p2[i2];
|
||||
|
||||
if (++i2 == h)
|
||||
i2 = 0;
|
||||
|
||||
_screen->setPagePixel(dstPage, dx2, dy2, _screen->getPagePixel(srcPage, dx1, dy1));
|
||||
}
|
||||
|
||||
if (!dstPage && (i & 5) == 5) {
|
||||
updateInput();
|
||||
_screen->updateScreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::setPaletteBrightness(const Palette &srcPal, int brightness, int modifier) {
|
||||
generateBrightnessPalette(srcPal, _screen->getPalette(1), brightness, modifier);
|
||||
_screen->fadePalette(_screen->getPalette(1), 5, 0);
|
||||
@ -2040,7 +1909,46 @@ int LoLEngine::playCharacterScriptChat(int charId, int mode, int restorePortrait
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LoLEngine::giveItemToMonster(MonsterInPlay *monster, Item item) {
|
||||
void LoLEngine::setupDialogueButtons(int numStr, const char *s1, const char *s2, const char *s3) {
|
||||
screen()->setScreenDim(5);
|
||||
|
||||
if (numStr == 1 && speechEnabled()) {
|
||||
_dialogueNumButtons = 0;
|
||||
_dialogueButtonString[0] = _dialogueButtonString[1] = _dialogueButtonString[2] = 0;
|
||||
} else {
|
||||
_dialogueNumButtons = numStr;
|
||||
_dialogueButtonString[0] = s1;
|
||||
_dialogueButtonString[1] = s2;
|
||||
_dialogueButtonString[2] = s3;
|
||||
_dialogueHighlightedButton = 0;
|
||||
|
||||
const ScreenDim *d = screen()->getScreenDim(5);
|
||||
|
||||
static uint16 posX[3];
|
||||
static uint8 posY[3];
|
||||
|
||||
memset(posY, d->sy + d->h - 9, 3);
|
||||
|
||||
_dialogueButtonPosX = posX;
|
||||
_dialogueButtonPosY = posY;
|
||||
|
||||
if (numStr == 1) {
|
||||
posX[0] = posX[1] = posX[2] = d->sx + d->w - (_dialogueButtonW + 3);
|
||||
} else {
|
||||
int xOffs = d->w / numStr;
|
||||
posX[0] = d->sx + (xOffs >> 1) - 37;
|
||||
posX[1] = posX[0] + xOffs;
|
||||
posX[2] = posX[1] + xOffs;
|
||||
}
|
||||
|
||||
drawDialogueButtons();
|
||||
}
|
||||
|
||||
if (!shouldQuit())
|
||||
removeInputTop();
|
||||
}
|
||||
|
||||
void LoLEngine::giveItemToMonster(LolMonsterInPlay *monster, Item item) {
|
||||
uint16 *c = &monster->assignedItems;
|
||||
while (*c)
|
||||
c = &_itemsInPlay[*c].nextAssignedObject;
|
||||
@ -2049,7 +1957,7 @@ void LoLEngine::giveItemToMonster(MonsterInPlay *monster, Item item) {
|
||||
}
|
||||
|
||||
const uint16 *LoLEngine::getCharacterOrMonsterStats(int id) {
|
||||
return (id & 0x8000) ? (const uint16 *)_monsters[id & 0x7fff].properties->fightingStats : _characters[id].defaultModifiers;
|
||||
return (id & 0x8000) ? (const uint16*)_monsters[id & 0x7fff].properties->fightingStats : _characters[id].defaultModifiers;
|
||||
}
|
||||
|
||||
uint16 *LoLEngine::getCharacterOrMonsterItemsMight(int id) {
|
||||
@ -2073,21 +1981,6 @@ void LoLEngine::delay(uint32 millis, bool doUpdate, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
int LoLEngine::rollDice(int times, int pips) {
|
||||
if (times <= 0 || pips <= 0)
|
||||
return 0;
|
||||
|
||||
int res = 0;
|
||||
while (times--)
|
||||
res += _rnd.getRandomNumberRng(1, pips);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void LoLEngine::updateEnvironmentalSfx(int soundId) {
|
||||
snd_processEnvironmentalSoundEffect(soundId, _currentBlock);
|
||||
}
|
||||
|
||||
// spells
|
||||
|
||||
int LoLEngine::castSpell(int charNum, int spellType, int spellLevel) {
|
||||
@ -2502,7 +2395,7 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
|
||||
int might = rollDice(iceDamageMin[spellLevel], iceDamageMax[spellLevel]) + iceDamageAdd[spellLevel];
|
||||
int dmg = calcInflictableDamagePerItem(charNum, 0, might, 3, 2);
|
||||
|
||||
MonsterInPlay *m = &_monsters[o & 0x7fff];
|
||||
LolMonsterInPlay *m = &_monsters[o & 0x7fff];
|
||||
if (m->hitPoints <= dmg) {
|
||||
increaseExperience(charNum, 2, m->hitPoints);
|
||||
o = m->nextAssignedObject;
|
||||
@ -2581,7 +2474,7 @@ int LoLEngine::processMagicFireball(int charNum, int spellLevel) {
|
||||
while (o & 0x8000) {
|
||||
static const uint8 fireballDamage[] = { 20, 40, 80, 100 };
|
||||
int dmg = calcInflictableDamagePerItem(charNum, o, fireballDamage[spellLevel], 4, 1);
|
||||
MonsterInPlay *m = &_monsters[o & 0x7fff];
|
||||
LolMonsterInPlay *m = &_monsters[o & 0x7fff];
|
||||
o = m->nextAssignedObject;
|
||||
_envSfxUseQueue = true;
|
||||
inflictDamage(m->id | 0x8000, dmg, charNum, 2, 4);
|
||||
@ -2746,7 +2639,7 @@ int LoLEngine::processMagicHandOfFate(int spellLevel) {
|
||||
uint16 o = _levelBlockProperties[b1].assignedObjects;
|
||||
while (o & 0x8000) {
|
||||
uint16 o2 = o;
|
||||
MonsterInPlay *m = &_monsters[o & 0x7fff];
|
||||
LolMonsterInPlay *m = &_monsters[o & 0x7fff];
|
||||
o = findObject(o)->nextAssignedObject;
|
||||
int nX = 0;
|
||||
int nY = 0;
|
||||
@ -3015,7 +2908,7 @@ int LoLEngine::processMagicVaelansCube() {
|
||||
|
||||
uint16 o = _levelBlockProperties[bl].assignedObjects;
|
||||
while (o & 0x8000) {
|
||||
MonsterInPlay *m = &_monsters[o & 0x7fff];
|
||||
LolMonsterInPlay *m = &_monsters[o & 0x7fff];
|
||||
if (m->properties->flags & 0x1000) {
|
||||
inflictDamage(o, 100, 0xffff, 0, 0x80);
|
||||
v = 1;
|
||||
@ -3495,7 +3388,7 @@ int LoLEngine::calcInflictableDamage(int16 attacker, int16 target, int hitType)
|
||||
}
|
||||
|
||||
int LoLEngine::inflictDamage(uint16 target, int damage, uint16 attacker, int skill, int flags) {
|
||||
MonsterInPlay *m = 0;
|
||||
LolMonsterInPlay *m = 0;
|
||||
LoLCharacter *c = 0;
|
||||
|
||||
if (target & 0x8000) {
|
||||
@ -3712,7 +3605,7 @@ void LoLEngine::checkForPartyDeath() {
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, int16 damage) {
|
||||
void LoLEngine::applyMonsterAttackSkill(LolMonsterInPlay *monster, int16 target, int16 damage) {
|
||||
if (rollDice(1, 100) > monster->properties->attackSkillChance)
|
||||
return;
|
||||
|
||||
@ -3782,7 +3675,7 @@ void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, in
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::applyMonsterDefenseSkill(MonsterInPlay *monster, int16 attacker, int flags, int skill, int damage) {
|
||||
void LoLEngine::applyMonsterDefenseSkill(LolMonsterInPlay *monster, int16 attacker, int flags, int skill, int damage) {
|
||||
if (rollDice(1, 100) > monster->properties->defenseSkillChance)
|
||||
return;
|
||||
|
||||
@ -4041,7 +3934,7 @@ uint16 LoLEngine::getNearestMonsterFromCharacterForBlock(uint16 block, int charN
|
||||
int o = _levelBlockProperties[block].assignedObjects;
|
||||
|
||||
while (o & 0x8000) {
|
||||
MonsterInPlay *m = &_monsters[o & 0x7fff];
|
||||
LolMonsterInPlay *m = &_monsters[o & 0x7fff];
|
||||
if (m->mode >= 13) {
|
||||
o = m->nextAssignedObject;
|
||||
continue;
|
||||
@ -4107,7 +4000,7 @@ void LoLEngine::displayAutomap() {
|
||||
|
||||
_currentMapLevel = _currentLevel;
|
||||
uint8 *tmpWll = new uint8[80];
|
||||
memcpy(tmpWll, _wllBuffer4, 80);
|
||||
memcpy(tmpWll, _wllAutomapData, 80);
|
||||
|
||||
_screen->loadBitmap("parch.cps", 2, 2, &_screen->getPalette(3));
|
||||
_screen->loadBitmap("autobut.shp", 3, 5, 0);
|
||||
@ -4188,7 +4081,7 @@ void LoLEngine::displayAutomap() {
|
||||
|
||||
_screen->fadeToBlack(10);
|
||||
loadLevelWallData(_currentLevel, false);
|
||||
memcpy(_wllBuffer4, tmpWll, 80);
|
||||
memcpy(_wllAutomapData, tmpWll, 80);
|
||||
delete[] tmpWll;
|
||||
restoreBlockTempData(_currentLevel);
|
||||
addLevelItems();
|
||||
@ -4229,7 +4122,7 @@ bool LoLEngine::updateAutoMapIntern(uint16 block, uint16 x, uint16 y, int16 xOff
|
||||
uint16 b = block + blockPosTable[6 + xOffs];
|
||||
|
||||
if (fx != -1) {
|
||||
if (_wllBuffer4[_levelBlockProperties[b].walls[fx]] & 0xc0)
|
||||
if (_wllAutomapData[_levelBlockProperties[b].walls[fx]] & 0xc0)
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4237,13 +4130,13 @@ bool LoLEngine::updateAutoMapIntern(uint16 block, uint16 x, uint16 y, int16 xOff
|
||||
b = block + blockPosTable[9 + yOffs];
|
||||
|
||||
if (fy != -1) {
|
||||
if (_wllBuffer4[_levelBlockProperties[b].walls[fy]] & 0xc0)
|
||||
if (_wllAutomapData[_levelBlockProperties[b].walls[fy]] & 0xc0)
|
||||
return false;
|
||||
}
|
||||
|
||||
b = block + blockPosTable[6 + xOffs] + blockPosTable[9 + yOffs];
|
||||
|
||||
if ((fx != -1) && (fy != -1) && (_wllBuffer4[_levelBlockProperties[b].walls[fx]] & 0xc0) && (_wllBuffer4[_levelBlockProperties[b].walls[fy]] & 0xc0))
|
||||
if ((fx != -1) && (fy != -1) && (_wllAutomapData[_levelBlockProperties[b].walls[fx]] & 0xc0) && (_wllAutomapData[_levelBlockProperties[b].walls[fy]] & 0xc0))
|
||||
return false;
|
||||
|
||||
_levelBlockProperties[b].flags |= 7;
|
||||
@ -4252,7 +4145,7 @@ bool LoLEngine::updateAutoMapIntern(uint16 block, uint16 x, uint16 y, int16 xOff
|
||||
}
|
||||
|
||||
void LoLEngine::loadMapLegendData(int level) {
|
||||
uint16 *legendData = (uint16 *)_tempBuffer5120;
|
||||
uint16 *legendData= (uint16*)_tempBuffer5120;
|
||||
for (int i = 0; i < 32; i++) {
|
||||
legendData[i * 6] = 0xffff;
|
||||
legendData[i * 6 + 5] = 0xffff;
|
||||
@ -4306,7 +4199,7 @@ void LoLEngine::drawMapPage(int pageNum) {
|
||||
|
||||
for (; bl < 1024; bl++) {
|
||||
uint8 *w = _levelBlockProperties[bl].walls;
|
||||
if ((_levelBlockProperties[bl].flags & 7) == 7 && (!(_wllBuffer4[w[0]] & 0xc0)) && (!(_wllBuffer4[w[2]] & 0xc0)) && (!(_wllBuffer4[w[1]] & 0xc0))&& (!(_wllBuffer4[w[3]] & 0xc0))) {
|
||||
if ((_levelBlockProperties[bl].flags & 7) == 7 && (!(_wllAutomapData[w[0]] & 0xc0)) && (!(_wllAutomapData[w[2]] & 0xc0)) && (!(_wllAutomapData[w[1]] & 0xc0))&& (!(_wllAutomapData[w[3]] & 0xc0))) {
|
||||
uint16 b0 = calcNewBlockPosition(bl, 0);
|
||||
uint16 b2 = calcNewBlockPosition(bl, 2);
|
||||
uint16 b1 = calcNewBlockPosition(bl, 1);
|
||||
@ -4323,25 +4216,25 @@ void LoLEngine::drawMapPage(int pageNum) {
|
||||
// draw north wall
|
||||
drawMapBlockWall(b3, w31, sx, sy, 3);
|
||||
drawMapShape(w31, sx, sy, 3);
|
||||
if (_wllBuffer4[w31] & 0xc0)
|
||||
if (_wllAutomapData[w31] & 0xc0)
|
||||
_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx, sy, _screen->_curPage, sx, sy, 1, 6, 0, _mapOverlay);
|
||||
|
||||
// draw west wall
|
||||
drawMapBlockWall(b1, w13, sx, sy, 1);
|
||||
drawMapShape(w13, sx, sy, 1);
|
||||
if (_wllBuffer4[w13] & 0xc0)
|
||||
if (_wllAutomapData[w13] & 0xc0)
|
||||
_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx + 6, sy, _screen->_curPage, sx + 6, sy, 1, 6, 0, _mapOverlay);
|
||||
|
||||
// draw east wall
|
||||
drawMapBlockWall(b0, w02, sx, sy, 0);
|
||||
drawMapShape(w02, sx, sy, 0);
|
||||
if (_wllBuffer4[w02] & 0xc0)
|
||||
if (_wllAutomapData[w02] & 0xc0)
|
||||
_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx, sy, _screen->_curPage, sx, sy, 7, 1, 0, _mapOverlay);
|
||||
|
||||
//draw south wall
|
||||
drawMapBlockWall(b2, w20, sx, sy, 2);
|
||||
drawMapShape(w20, sx, sy, 2);
|
||||
if (_wllBuffer4[w20] & 0xc0)
|
||||
if (_wllAutomapData[w20] & 0xc0)
|
||||
_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx, sy + 5, _screen->_curPage, sx, sy + 5, 7, 1, 0, _mapOverlay);
|
||||
}
|
||||
|
||||
@ -4362,7 +4255,7 @@ void LoLEngine::drawMapPage(int pageNum) {
|
||||
sx = mapGetStartPosX();
|
||||
sy = mapGetStartPosY();
|
||||
|
||||
uint16 *legendData = (uint16 *)_tempBuffer5120;
|
||||
uint16 *legendData = (uint16*)_tempBuffer5120;
|
||||
uint8 yOffset = _flags.use16ColorMode ? 4 : 0;
|
||||
|
||||
for (int ii = 0; ii < 32; ii++) {
|
||||
@ -4508,7 +4401,7 @@ void LoLEngine::redrawMapCursor() {
|
||||
}
|
||||
|
||||
void LoLEngine::drawMapBlockWall(uint16 block, uint8 wall, int x, int y, int direction) {
|
||||
if (((1 << direction) & _levelBlockProperties[block].flags) || ((_wllBuffer4[wall] & 0x1f) != 13))
|
||||
if (((1 << direction) & _levelBlockProperties[block].flags) || ((_wllAutomapData[wall] & 0x1f) != 13))
|
||||
return;
|
||||
|
||||
int cp = _screen->_curPage;
|
||||
@ -4518,7 +4411,7 @@ void LoLEngine::drawMapBlockWall(uint16 block, uint8 wall, int x, int y, int dir
|
||||
}
|
||||
|
||||
void LoLEngine::drawMapShape(uint8 wall, int x, int y, int direction) {
|
||||
int l = _wllBuffer4[wall] & 0x1f;
|
||||
int l = _wllAutomapData[wall] & 0x1f;
|
||||
if (l == 0x1f)
|
||||
return;
|
||||
|
||||
@ -4611,48 +4504,7 @@ void LoLEngine::printMapExitButtonText() {
|
||||
_screen->setCurPage(cp);
|
||||
}
|
||||
|
||||
void LoLEngine::generateTempData() {
|
||||
int l = _currentLevel - 1;
|
||||
if (_lvlTempData[l]) {
|
||||
delete[] _lvlTempData[l]->wallsXorData;
|
||||
delete[] _lvlTempData[l]->flags;
|
||||
delete[] _lvlTempData[l]->monsters;
|
||||
delete[] _lvlTempData[l]->flyingObjects;
|
||||
delete _lvlTempData[l];
|
||||
}
|
||||
|
||||
_lvlTempData[l] = new LevelTempData;
|
||||
|
||||
_lvlTempData[l]->wallsXorData = new uint8[4096];
|
||||
_lvlTempData[l]->flags = new uint8[1024];
|
||||
_lvlTempData[l]->monsters = new MonsterInPlay[30];
|
||||
_lvlTempData[l]->flyingObjects = new FlyingObject[8];
|
||||
|
||||
Common::String filename = Common::String::format("LEVEL%d.CMZ", _currentLevel);
|
||||
|
||||
_screen->loadBitmap(filename.c_str(), 15, 15, 0);
|
||||
const uint8 *p = _screen->getCPagePtr(14);
|
||||
uint16 len = READ_LE_UINT16(p + 4);
|
||||
p += 6;
|
||||
|
||||
memset(_lvlTempData[l]->wallsXorData, 0, 4096);
|
||||
memset(_lvlTempData[l]->flags, 0, 1024);
|
||||
uint8 *d = _lvlTempData[l]->wallsXorData;
|
||||
uint8 *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;
|
||||
}
|
||||
|
||||
memcpy(_lvlTempData[l]->monsters, _monsters, sizeof(MonsterInPlay) * 30);
|
||||
memcpy(_lvlTempData[l]->flyingObjects, _flyingObjects, sizeof(FlyingObject) * 8);
|
||||
|
||||
_lvlTempData[l]->monsterDifficulty =_monsterDifficulty;
|
||||
|
||||
_hasTempDataFlags |= (1 << l);
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#ifndef KYRA_LOL_H
|
||||
#define KYRA_LOL_H
|
||||
|
||||
#include "kyra/kyra_v1.h"
|
||||
#include "kyra/loleobbase.h"
|
||||
#include "kyra/script_tim.h"
|
||||
#include "kyra/script.h"
|
||||
#include "kyra/gui_lol.h"
|
||||
@ -86,15 +86,7 @@ struct SpellProperty {
|
||||
uint16 flags;
|
||||
};
|
||||
|
||||
struct LevelBlockProperty {
|
||||
uint8 walls[4];
|
||||
uint16 assignedObjects;
|
||||
uint16 drawObjects;
|
||||
uint8 direction;
|
||||
uint8 flags;
|
||||
};
|
||||
|
||||
struct MonsterProperty {
|
||||
struct LolMonsterProperty {
|
||||
uint8 shapeIndex;
|
||||
uint8 maxWidth;
|
||||
uint16 fightingStats[9];
|
||||
@ -116,7 +108,7 @@ struct MonsterProperty {
|
||||
uint8 sounds[3];
|
||||
};
|
||||
|
||||
struct MonsterInPlay {
|
||||
struct LolMonsterInPlay {
|
||||
uint16 nextAssignedObject;
|
||||
uint16 nextDrawObject;
|
||||
uint8 flyingHeight;
|
||||
@ -142,7 +134,7 @@ struct MonsterInPlay {
|
||||
int16 hitPoints;
|
||||
uint8 speedTick;
|
||||
uint8 type;
|
||||
MonsterProperty *properties;
|
||||
LolMonsterProperty *properties;
|
||||
uint8 numDistAttacks;
|
||||
uint8 curDistWeapon;
|
||||
int8 distAttackTick;
|
||||
@ -179,15 +171,6 @@ struct ItemProperty {
|
||||
uint8 unkD;
|
||||
};
|
||||
|
||||
struct LevelShapeProperty {
|
||||
uint16 shapeIndex[10];
|
||||
uint8 scaleFlag[10];
|
||||
int16 shapeX[10];
|
||||
int16 shapeY[10];
|
||||
int8 next;
|
||||
uint8 flags;
|
||||
};
|
||||
|
||||
struct CompassDef {
|
||||
uint8 shapeIndex;
|
||||
int8 x;
|
||||
@ -195,7 +178,7 @@ struct CompassDef {
|
||||
uint8 flags;
|
||||
};
|
||||
|
||||
struct ButtonDef {
|
||||
struct LoLButtonDef {
|
||||
uint16 buttonflags;
|
||||
uint16 keyCode;
|
||||
uint16 keyCode2;
|
||||
@ -207,12 +190,6 @@ struct ButtonDef {
|
||||
uint16 screenDim;
|
||||
};
|
||||
|
||||
struct OpenDoorState {
|
||||
uint16 block;
|
||||
int8 wall;
|
||||
int8 state;
|
||||
};
|
||||
|
||||
struct ActiveSpell {
|
||||
uint8 spell;
|
||||
const SpellProperty *p;
|
||||
@ -245,14 +222,6 @@ struct FlyingObjectShape {
|
||||
uint8 flipFlags;
|
||||
};
|
||||
|
||||
struct LevelTempData {
|
||||
uint8 *wallsXorData;
|
||||
uint8 *flags;
|
||||
MonsterInPlay *monsters;
|
||||
FlyingObject *flyingObjects;
|
||||
uint8 monsterDifficulty;
|
||||
};
|
||||
|
||||
struct MapLegendData {
|
||||
uint8 shapeIndex;
|
||||
bool enable;
|
||||
@ -296,7 +265,7 @@ struct MistOfDoomAnimData {
|
||||
uint8 sound;
|
||||
};
|
||||
|
||||
class LoLEngine : public KyraEngine_v1 {
|
||||
class LoLEngine : public LolEobBaseEngine {
|
||||
friend class GUI_LoL;
|
||||
friend class TextDisplayer_LoL;
|
||||
friend class TIMInterpreter_LoL;
|
||||
@ -305,7 +274,7 @@ friend class Debugger_LoL;
|
||||
friend class HistoryPlayer;
|
||||
public:
|
||||
LoLEngine(OSystem *system, const GameFlags &flags);
|
||||
~LoLEngine();
|
||||
virtual ~LoLEngine();
|
||||
|
||||
virtual void initKeymap();
|
||||
|
||||
@ -348,13 +317,11 @@ private:
|
||||
// main loop
|
||||
void runLoop();
|
||||
void update();
|
||||
void updateEnvironmentalSfx(int soundId);
|
||||
|
||||
// mouse
|
||||
void setMouseCursorToIcon(int icon);
|
||||
void setMouseCursorToItemInHand();
|
||||
uint8 *getItemIconShapePtr(int index);
|
||||
bool posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, int y2);
|
||||
|
||||
void checkFloatingPointerRegions();
|
||||
int _floatingCursorControl;
|
||||
@ -443,11 +410,7 @@ private:
|
||||
|
||||
// timers
|
||||
void setupTimers();
|
||||
void enableTimer(int id);
|
||||
void enableSysTimer(int sysTimer);
|
||||
void disableSysTimer(int sysTimer);
|
||||
|
||||
void timerProcessDoors(int timerNum);
|
||||
void timerProcessMonsters(int timerNum);
|
||||
void timerSpecialCharacterUpdate(int timerNum);
|
||||
void timerProcessFlyingObjects(int timerNum);
|
||||
@ -457,6 +420,9 @@ private:
|
||||
void timerUpdateLampState(int timerNum);
|
||||
void timerFadeMessageText(int timerNum);
|
||||
|
||||
uint8 getClock2Timer(int index) { return index < _numClock2Timers ? _clock2Timers[index] : 0; }
|
||||
uint8 getNumClock2Timers() { return _numClock2Timers; }
|
||||
|
||||
static const uint8 _clock2Timers[];
|
||||
static const uint8 _numClock2Timers;
|
||||
|
||||
@ -470,7 +436,7 @@ private:
|
||||
int snd_updateCharacterSpeech();
|
||||
void snd_stopSpeech(bool setFlag);
|
||||
void snd_playSoundEffect(int track, int volume);
|
||||
void snd_processEnvironmentalSoundEffect(int soundId, int block);
|
||||
bool snd_processEnvironmentalSoundEffect(int soundId, int block);
|
||||
void snd_queueEnvironmentalSoundEffect(int soundId, int block);
|
||||
void snd_playQueuedEffects();
|
||||
void snd_loadSoundFile(int track);
|
||||
@ -479,21 +445,17 @@ private:
|
||||
|
||||
int _lastSpeechId;
|
||||
int _lastSpeaker;
|
||||
uint32 _activeVoiceFileTotalTime;
|
||||
int _lastSfxTrack;
|
||||
int _lastMusicTrack;
|
||||
int _curMusicFileIndex;
|
||||
char _curMusicFileExt;
|
||||
int _environmentSfx;
|
||||
int _environmentSfxVol;
|
||||
int _envSfxDistThreshold;
|
||||
bool _envSfxUseQueue;
|
||||
int _envSfxNumTracksInQueue;
|
||||
uint16 _envSfxQueuedTracks[10];
|
||||
uint16 _envSfxQueuedBlocks[10];
|
||||
int _nextSpeechId;
|
||||
int _nextSpeaker;
|
||||
typedef Common::List<Audio::SeekableAudioStream *> SpeechList;
|
||||
typedef Common::List<Audio::SeekableAudioStream*> SpeechList;
|
||||
SpeechList _speechList;
|
||||
|
||||
int _curTlkFile;
|
||||
@ -502,9 +464,7 @@ private:
|
||||
int _ingameSoundListSize;
|
||||
|
||||
const uint8 *_musicTrackMap;
|
||||
int _musicTrackMapSize;
|
||||
const uint16 *_ingameSoundIndex;
|
||||
int _ingameSoundIndexSize;
|
||||
const uint8 *_ingameGMSoundIndex;
|
||||
int _ingameGMSoundIndexSize;
|
||||
const uint8 *_ingameMT32SoundIndex;
|
||||
@ -519,7 +479,6 @@ private:
|
||||
void gui_drawScene(int pageNum);
|
||||
void gui_drawAllCharPortraitsWithStats();
|
||||
void gui_drawCharPortraitWithStats(int charNum);
|
||||
void gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor);
|
||||
void gui_drawCharFaceShape(int charNum, int x, int y, int pageNum);
|
||||
void gui_highlightPortraitFrame(int charNum);
|
||||
void gui_drawLiveMagicBar(int x, int y, int curPoints, int unk, int maxPoints, int w, int h, int col1, int col2, int flag);
|
||||
@ -534,7 +493,6 @@ private:
|
||||
void gui_printCharacterStats(int index, int redraw, int value);
|
||||
void gui_changeCharacterStats(int charNum);
|
||||
void gui_drawCharInventoryItem(int itemIndex);
|
||||
void gui_drawBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2);
|
||||
|
||||
int gui_enableControls();
|
||||
int gui_disableControls(int controlMode);
|
||||
@ -548,37 +506,27 @@ private:
|
||||
int _lastButtonShape;
|
||||
uint32 _buttonPressTimer;
|
||||
int _selectedCharacter;
|
||||
int _compassDirection;
|
||||
int _compassStep;
|
||||
int _compassDirectionIndex;
|
||||
uint32 _compassTimer;
|
||||
int _charInventoryUnk;
|
||||
|
||||
const CompassDef *_compassDefs;
|
||||
int _compassDefsSize;
|
||||
|
||||
void gui_updateInput();
|
||||
void gui_triggerEvent(int eventType);
|
||||
void removeInputTop();
|
||||
void gui_enableDefaultPlayfieldButtons();
|
||||
void gui_enableSequenceButtons(int x, int y, int w, int h, int enableFlags);
|
||||
void gui_specialSceneRestoreButtons();
|
||||
void gui_enableCharInventoryButtons(int charNum);
|
||||
|
||||
void gui_resetButtonList();
|
||||
void gui_initButtonsFromList(const int16 *list);
|
||||
void gui_setFaceFramesControlButtons(int index, int xOffs);
|
||||
void gui_initCharInventorySpecialButtons(int charNum);
|
||||
void gui_initMagicScrollButtons();
|
||||
void gui_initMagicSubmenu(int charNum);
|
||||
void gui_initButton(int index, int x = -1, int y = -1, int val = -1);
|
||||
void gui_notifyButtonListChanged();
|
||||
|
||||
Common::Array<Button::Callback> _buttonCallbacks;
|
||||
Button *_activeButtons;
|
||||
Button _activeButtonData[70];
|
||||
ButtonDef _sceneWindowButton;
|
||||
bool _preserveEvents;
|
||||
LoLButtonDef _sceneWindowButton;
|
||||
|
||||
int clickedUpArrow(Button *button);
|
||||
int clickedDownArrow(Button *button);
|
||||
@ -613,45 +561,34 @@ private:
|
||||
int clickedLamp(Button *button);
|
||||
int clickedStatusIcon(Button *button);
|
||||
|
||||
const ButtonDef *_buttonData;
|
||||
int _buttonDataSize;
|
||||
Common::Array<Button::Callback> _buttonCallbacks;
|
||||
const LoLButtonDef *_buttonData;
|
||||
const int16 *_buttonList1;
|
||||
int _buttonList1Size;
|
||||
const int16 *_buttonList2;
|
||||
int _buttonList2Size;
|
||||
const int16 *_buttonList3;
|
||||
int _buttonList3Size;
|
||||
const int16 *_buttonList4;
|
||||
int _buttonList4Size;
|
||||
const int16 *_buttonList5;
|
||||
int _buttonList5Size;
|
||||
const int16 *_buttonList6;
|
||||
int _buttonList6Size;
|
||||
const int16 *_buttonList7;
|
||||
int _buttonList7Size;
|
||||
const int16 *_buttonList8;
|
||||
int _buttonList8Size;
|
||||
|
||||
// text
|
||||
int characterSays(int track, int charId, bool redraw);
|
||||
int playCharacterScriptChat(int charId, int mode, int restorePortrait, char *str, EMCState *script, const uint16 *paramList, int16 paramIndex);
|
||||
void setupDialogueButtons(int numStr, const char *s1, const char *s2, const char *s3);
|
||||
|
||||
TextDisplayer_LoL *_txt;
|
||||
TextDisplayer_Eob *txt() { return _txt; }
|
||||
|
||||
// emc scripts
|
||||
void runInitScript(const char *filename, int optionalFunc);
|
||||
void runInfScript(const char *filename);
|
||||
void runLevelScript(int block, int flags);
|
||||
void runLevelScriptCustom(int block, int flags, int charNum, int item, int reg3, int reg4);
|
||||
bool checkSceneUpdateNeed(int func);
|
||||
|
||||
EMCData _scriptData;
|
||||
bool _suspendScript;
|
||||
uint16 _scriptDirection;
|
||||
uint16 _currentDirection;
|
||||
uint16 _currentBlock;
|
||||
bool _sceneUpdateRequired;
|
||||
int16 _visibleBlockIndex[18];
|
||||
int16 _globalScriptVars[24];
|
||||
|
||||
// emc opcode
|
||||
@ -702,7 +639,7 @@ private:
|
||||
int olol_checkEquippedItemScriptFlags(EMCState *script);
|
||||
int olol_setDoorState(EMCState *script);
|
||||
int olol_updateBlockAnimations(EMCState *script);
|
||||
int olol_mapShapeToBlock(EMCState *script);
|
||||
int olol_assignLevelDecorationShape(EMCState *script);
|
||||
int olol_resetBlockShapeAssignment(EMCState *script);
|
||||
int olol_copyRegion(EMCState *script);
|
||||
int olol_initMonster(EMCState *script);
|
||||
@ -716,7 +653,7 @@ private:
|
||||
int olol_battleHitSkillTest(EMCState *script);
|
||||
int olol_inflictDamage(EMCState *script);
|
||||
int olol_moveMonster(EMCState *script);
|
||||
int olol_dialogueBox(EMCState *script);
|
||||
int olol_setupDialogueButtons(EMCState *script);
|
||||
int olol_giveTakeMoney(EMCState *script);
|
||||
int olol_checkMoney(EMCState *script);
|
||||
int olol_setScriptTimer(EMCState *script);
|
||||
@ -792,7 +729,7 @@ private:
|
||||
int olol_assignCustomSfx(EMCState *script);
|
||||
int olol_findAssignedMonster(EMCState *script);
|
||||
int olol_checkBlockForMonster(EMCState *script);
|
||||
int olol_transformRegion(EMCState *script);
|
||||
int olol_crossFadeRegion(EMCState *script);
|
||||
int olol_calcCoordinatesAddDirectionOffset(EMCState *script);
|
||||
int olol_resetPortraitsAndDisableSysTimer(EMCState *script);
|
||||
int olol_enableSysTimer(EMCState *script);
|
||||
@ -820,7 +757,7 @@ private:
|
||||
int olol_shakeScene(EMCState *script);
|
||||
int olol_gasExplosion(EMCState *script);
|
||||
int olol_calcNewBlockPosition(EMCState *script);
|
||||
int olol_fadeScene(EMCState *script);
|
||||
int olol_crossFadeScene(EMCState *script);
|
||||
int olol_updateDrawPage2(EMCState *script);
|
||||
int olol_setMouseCursor(EMCState *script);
|
||||
int olol_characterSays(EMCState *script);
|
||||
@ -834,14 +771,14 @@ private:
|
||||
// tim opcode
|
||||
void setupOpcodeTable();
|
||||
|
||||
Common::Array<const TIMOpcode *> _timIntroOpcodes;
|
||||
Common::Array<const TIMOpcode*> _timIntroOpcodes;
|
||||
int tlol_setupPaletteFade(const TIM *tim, const uint16 *param);
|
||||
int tlol_loadPalette(const TIM *tim, const uint16 *param);
|
||||
int tlol_setupPaletteFadeEx(const TIM *tim, const uint16 *param);
|
||||
int tlol_processWsaFrame(const TIM *tim, const uint16 *param);
|
||||
int tlol_displayText(const TIM *tim, const uint16 *param);
|
||||
|
||||
Common::Array<const TIMOpcode *> _timOutroOpcodes;
|
||||
Common::Array<const TIMOpcode*> _timOutroOpcodes;
|
||||
int tlol_fadeInScene(const TIM *tim, const uint16 *param);
|
||||
int tlol_unusedResourceFunc(const TIM *tim, const uint16 *param);
|
||||
int tlol_fadeInPalette(const TIM *tim, const uint16 *param);
|
||||
@ -850,7 +787,7 @@ private:
|
||||
int tlol_delayForChat(const TIM *tim, const uint16 *param);
|
||||
int tlol_fadeOutSound(const TIM *tim, const uint16 *param);
|
||||
|
||||
Common::Array<const TIMOpcode *> _timIngameOpcodes;
|
||||
Common::Array<const TIMOpcode*> _timIngameOpcodes;
|
||||
int tlol_initSceneWindowDialogue(const TIM *tim, const uint16 *param);
|
||||
int tlol_restoreAfterSceneWindowDialogue(const TIM *tim, const uint16 *param);
|
||||
int tlol_giveItem(const TIM *tim, const uint16 *param);
|
||||
@ -900,7 +837,6 @@ private:
|
||||
void createTransparencyTables();
|
||||
void updateSequenceBackgroundAnimations();
|
||||
|
||||
bool _dialogueField;
|
||||
uint8 **_itemIconShapes;
|
||||
int _numItemIconShapes;
|
||||
uint8 **_itemShapes;
|
||||
@ -913,7 +849,6 @@ private:
|
||||
int _numEffectShapes;
|
||||
|
||||
const int8 *_gameShapeMap;
|
||||
int _gameShapeMapSize;
|
||||
|
||||
uint8 *_characterFaceShapes[40][3];
|
||||
|
||||
@ -942,19 +877,13 @@ private:
|
||||
|
||||
LoLCharacter *_characters;
|
||||
uint16 _activeCharsXpos[3];
|
||||
int _updateFlags;
|
||||
int _updateCharNum;
|
||||
int _updatePortraitSpeechAnimDuration;
|
||||
|
||||
int _portraitSpeechAnimMode;
|
||||
int _resetPortraitAfterSpeechAnim;
|
||||
int _textColorFlag;
|
||||
bool _fadeText;
|
||||
int _needSceneRestore;
|
||||
uint32 _palUpdateTimer;
|
||||
uint32 _updatePortraitNext;
|
||||
|
||||
int _loadLevelFlag;
|
||||
int _hasTempDataFlags;
|
||||
int _activeMagicMenu;
|
||||
uint16 _scriptCharacterCycle;
|
||||
int _charStatsTemp[5];
|
||||
@ -963,15 +892,10 @@ private:
|
||||
int _charDefaultsSize;
|
||||
|
||||
const uint16 *_charDefsMan;
|
||||
int _charDefsManSize;
|
||||
const uint16 *_charDefsWoman;
|
||||
int _charDefsWomanSize;
|
||||
const uint16 *_charDefsKieran;
|
||||
int _charDefsKieranSize;
|
||||
const uint16 *_charDefsAkshel;
|
||||
int _charDefsAkshelSize;
|
||||
const int32 *_expRequirements;
|
||||
int _expRequirementsSize;
|
||||
|
||||
// lamp
|
||||
void resetLampStatus();
|
||||
@ -983,16 +907,14 @@ private:
|
||||
int _lampOilStatus;
|
||||
uint32 _lampStatusTimer;
|
||||
bool _lampStatusSuspended;
|
||||
uint8 _blockBrightness;
|
||||
|
||||
// level
|
||||
void loadLevel(int index);
|
||||
void addLevelItems();
|
||||
void loadLevelWallData(int index, bool mapShapes);
|
||||
void loadLevelWallData(int fileIndex, bool mapShapes);
|
||||
void assignBlockObject(LevelBlockProperty *l, uint16 item);
|
||||
int assignLevelShapes(int index);
|
||||
uint8 *getLevelShapes(int index);
|
||||
void restoreBlockTempData(int index);
|
||||
int assignLevelDecorationShapes(int index);
|
||||
uint8 *getLevelDecorationShapes(int index);
|
||||
void restoreTempDataAdjustMonsterStrength(int index);
|
||||
void loadBlockProperties(const char *cmzFile);
|
||||
void loadLevelShpDat(const char *shpFile, const char *datFile, bool flag);
|
||||
@ -1006,17 +928,7 @@ private:
|
||||
|
||||
void drawScene(int pageNum);
|
||||
|
||||
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);
|
||||
|
||||
void drawVcnBlocks();
|
||||
void drawSceneShapes();
|
||||
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 drawDecorations(int index);
|
||||
void drawBlockEffects(int index, int type);
|
||||
void drawSpecialGuiShape(int pageNum);
|
||||
@ -1033,27 +945,17 @@ private:
|
||||
void updateCompass();
|
||||
|
||||
void moveParty(uint16 direction, int unk1, int unk2, int buttonShape);
|
||||
bool checkBlockPassability(uint16 block, uint16 direction);
|
||||
void notifyBlockNotPassable(int scrollFlag);
|
||||
virtual bool checkBlockPassability(uint16 block, uint16 direction);
|
||||
|
||||
uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction);
|
||||
uint16 calcBlockIndex(uint16 x, uint16 y);
|
||||
void calcCoordinates(uint16 &x, uint16 &y, int block, uint16 xOffs, uint16 yOffs);
|
||||
void calcCoordinatesForSingleCharacter(int charNum, uint16 &x, uint16 &y);
|
||||
void calcCoordinatesAddDirectionOffset(uint16 &x, uint16 &y, int direction);
|
||||
|
||||
int clickedWallShape(uint16 block, uint16 direction);
|
||||
int clickedLeverOn(uint16 block, uint16 direction);
|
||||
int clickedLeverOff(uint16 block, uint16 direction);
|
||||
int clickedWallOnlyScript(uint16 block);
|
||||
int clickedDoorSwitch(uint16 block, uint16 direction);
|
||||
int clickedNiche(uint16 block, uint16 direction);
|
||||
|
||||
bool clickedShape(int shapeIndex);
|
||||
void processDoorSwitch(uint16 block, int unk);
|
||||
void openCloseDoor(uint16 block, int openClose);
|
||||
void completeDoorOperations();
|
||||
|
||||
void movePartySmoothScrollBlocked(int speed);
|
||||
void movePartySmoothScrollUp(int speed);
|
||||
void movePartySmoothScrollDown(int speed);
|
||||
@ -1069,79 +971,40 @@ private:
|
||||
|
||||
int smoothScrollDrawSpecialGuiShape(int pageNum);
|
||||
|
||||
OpenDoorState _openDoorState[3];
|
||||
int _blockDoor;
|
||||
|
||||
int _smoothScrollModeNormal;
|
||||
|
||||
const uint8 *_scrollXTop;
|
||||
int _scrollXTopSize;
|
||||
const uint8 *_scrollYTop;
|
||||
int _scrollYTopSize;
|
||||
const uint8 *_scrollXBottom;
|
||||
int _scrollXBottomSize;
|
||||
const uint8 *_scrollYBottom;
|
||||
int _scrollYBottomSize;
|
||||
|
||||
int _nextScriptFunc;
|
||||
uint8 _currentLevel;
|
||||
int _sceneDefaultUpdate;
|
||||
int _lvlBlockIndex;
|
||||
int _lvlShapeIndex;
|
||||
bool _partyAwake;
|
||||
uint8 *_vcnBlocks;
|
||||
uint8 *_vcnShift;
|
||||
uint8 *_vcnExpTable;
|
||||
uint16 *_vmpPtr;
|
||||
uint8 *_vcfBlocks;
|
||||
uint16 *_blockDrawingBuffer;
|
||||
uint8 *_sceneWindowBuffer;
|
||||
LevelShapeProperty *_levelShapeProperties;
|
||||
uint8 **_levelShapes;
|
||||
|
||||
uint8 *_specialGuiShape;
|
||||
uint16 _specialGuiShapeX;
|
||||
uint16 _specialGuiShapeY;
|
||||
uint16 _specialGuiShapeMirrorFlag;
|
||||
|
||||
char _lastBlockDataFile[12];
|
||||
char _lastOverridePalFile[12];
|
||||
char *_lastOverridePalFilePtr;
|
||||
int _lastSpecialColor;
|
||||
int _lastSpecialColorWeight;
|
||||
|
||||
int _sceneDrawVarDown;
|
||||
int _sceneDrawVarRight;
|
||||
int _sceneDrawVarLeft;
|
||||
int _wllProcessFlag;
|
||||
|
||||
uint8 *_transparencyTable2;
|
||||
uint8 *_transparencyTable1;
|
||||
|
||||
int _loadSuppFilesFlag;
|
||||
|
||||
uint8 *_wllVmpMap;
|
||||
int8 *_wllShapeMap;
|
||||
uint8 *_specialWallTypes;
|
||||
uint8 *_wllBuffer4;
|
||||
uint8 *_wllWallFlags;
|
||||
|
||||
int16 *_lvlShapeTop;
|
||||
int16 *_lvlShapeBottom;
|
||||
int16 *_lvlShapeLeftRight;
|
||||
|
||||
LevelBlockProperty *_levelBlockProperties;
|
||||
LevelBlockProperty *_visibleBlocks[18];
|
||||
uint8 *_wllAutomapData;
|
||||
|
||||
uint16 _partyPosX;
|
||||
uint16 _partyPosY;
|
||||
|
||||
Common::SeekableReadStream *_lvlShpFileHandle;
|
||||
uint16 _lvlShpNum;
|
||||
uint16 _levelFileDataSize;
|
||||
LevelShapeProperty *_levelFileData;
|
||||
|
||||
uint8 *_doorShapes[2];
|
||||
int _shpDmX;
|
||||
int _shpDmY;
|
||||
uint16 _dmScaleW;
|
||||
@ -1154,55 +1017,20 @@ private:
|
||||
uint8 *_tempBuffer5120;
|
||||
|
||||
const char * const *_levelDatList;
|
||||
int _levelDatListSize;
|
||||
const char * const *_levelShpList;
|
||||
int _levelShpListSize;
|
||||
|
||||
const int8 *_dscUnk1;
|
||||
int _dscUnk1Size;
|
||||
const int8 *_dscShapeIndex;
|
||||
int _dscShapeIndexSize;
|
||||
const int8 *_dscWalls;
|
||||
|
||||
const uint8 *_dscOvlMap;
|
||||
int _dscOvlMapSize;
|
||||
const uint16 *_dscShapeScaleW;
|
||||
int _dscShapeScaleWSize;
|
||||
const uint16 *_dscShapeScaleH;
|
||||
int _dscShapeScaleHSize;
|
||||
const int16 *_dscShapeX;
|
||||
int _dscShapeXSize;
|
||||
const int8 *_dscShapeY;
|
||||
int _dscShapeYSize;
|
||||
const uint8 *_dscTileIndex;
|
||||
int _dscTileIndexSize;
|
||||
const uint8 *_dscUnk2;
|
||||
int _dscUnk2Size;
|
||||
const uint8 *_dscDoorShpIndex;
|
||||
int _dscDoorShpIndexSize;
|
||||
const int8 *_dscDim1;
|
||||
int _dscDim1Size;
|
||||
const int8 *_dscDim2;
|
||||
int _dscDim2Size;
|
||||
const uint8 *_dscBlockMap;
|
||||
int _dscBlockMapSize;
|
||||
const uint8 *_dscDimMap;
|
||||
int _dscDimMapSize;
|
||||
const uint16 *_dscDoorMonsterScaleTable;
|
||||
int _dscDoorMonsterScaleTableSize;
|
||||
const uint16 *_dscDoor4;
|
||||
int _dscDoor4Size;
|
||||
const uint8 *_dscShapeOvlIndex;
|
||||
int _dscShapeOvlIndexSize;
|
||||
const int8 *_dscBlockIndex;
|
||||
int _dscBlockIndexSize;
|
||||
const uint8 *_dscDoor1;
|
||||
int _dscDoor1Size;
|
||||
const int16 *_dscDoorMonsterX;
|
||||
int _dscDoorMonsterXSize;
|
||||
const int16 *_dscDoorMonsterY;
|
||||
int _dscDoorMonsterYSize;
|
||||
const uint16 *_dscShapeScaleW;
|
||||
const uint16 *_dscShapeScaleH;
|
||||
const int8 *_dscShapeY;
|
||||
|
||||
int _sceneDrawPage1;
|
||||
int _sceneDrawPage2;
|
||||
const uint16 *_dscDoorMonsterScaleTable;
|
||||
const uint16 *_dscDoor4;
|
||||
const int16 *_dscDoorMonsterX;
|
||||
const int16 *_dscDoorMonsterY;
|
||||
|
||||
// items
|
||||
void giveCredits(int credits, int redraw);
|
||||
@ -1239,8 +1067,7 @@ private:
|
||||
Item _itemInHand;
|
||||
Item _inventory[48];
|
||||
Item _inventoryCurItem;
|
||||
int _currentControlMode;
|
||||
int _specialSceneFlag;
|
||||
|
||||
int _lastCharInventory;
|
||||
uint16 _charStatusFlags[3];
|
||||
int _emcLastItem;
|
||||
@ -1250,34 +1077,27 @@ private:
|
||||
EMCData _itemScript;
|
||||
|
||||
const uint8 *_charInvIndex;
|
||||
int _charInvIndexSize;
|
||||
const uint8 *_charInvDefs;
|
||||
int _charInvDefsSize;
|
||||
const uint16 *_inventorySlotDesc;
|
||||
int _inventorySlotDescSize;
|
||||
const uint16 *_itemCost;
|
||||
int _itemCostSize;
|
||||
const uint8 *_stashSetupData;
|
||||
int _stashSetupDataSize;
|
||||
const int8 *_sceneItemOffs;
|
||||
int _sceneItemOffsSize;
|
||||
const FlyingObjectShape *_flyingItemShapes;
|
||||
int _flyingItemShapesSize;
|
||||
|
||||
// monsters
|
||||
void loadMonsterShapes(const char *file, int monsterIndex, int b);
|
||||
void releaseMonsterShapes(int monsterIndex);
|
||||
int deleteMonstersFromBlock(int block);
|
||||
void setMonsterMode(MonsterInPlay *monster, int mode);
|
||||
bool updateMonsterAdjustBlocks(MonsterInPlay *monster);
|
||||
void placeMonster(MonsterInPlay *monster, uint16 x, uint16 y);
|
||||
void setMonsterMode(LolMonsterInPlay *monster, int mode);
|
||||
bool updateMonsterAdjustBlocks(LolMonsterInPlay *monster);
|
||||
void placeMonster(LolMonsterInPlay *monster, uint16 x, uint16 y);
|
||||
int calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2);
|
||||
void setMonsterDirection(MonsterInPlay *monster, int dir);
|
||||
void monsterDropItems(MonsterInPlay *monster);
|
||||
void setMonsterDirection(LolMonsterInPlay *monster, int dir);
|
||||
void monsterDropItems(LolMonsterInPlay *monster);
|
||||
void removeAssignedObjectFromBlock(LevelBlockProperty *l, uint16 id);
|
||||
void removeDrawObjectFromBlock(LevelBlockProperty *l, uint16 id);
|
||||
void assignMonsterToBlock(uint16 *assignedBlockObjects, uint16 id);
|
||||
void giveItemToMonster(MonsterInPlay *monster, Item item);
|
||||
void giveItemToMonster(LolMonsterInPlay *monster, Item item);
|
||||
int checkBlockBeforeObjectPlacement(uint16 x, uint16 y, uint16 objectWidth, uint16 testFlag, uint16 wallFlag);
|
||||
int checkBlockForWallsAndSufficientSpace(int block, int x, int y, int objectWidth, int testFlag, int wallFlag);
|
||||
int calcMonsterSkillLevel(int id, int a);
|
||||
@ -1288,7 +1108,7 @@ private:
|
||||
|
||||
void drawBlockObjects(int blockArrayIndex);
|
||||
void drawMonster(uint16 id);
|
||||
int getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags);
|
||||
int getMonsterCurFrame(LolMonsterInPlay *m, uint16 dirFlags);
|
||||
void reassignDrawObjects(uint16 direction, uint16 itemIndex, LevelBlockProperty *l, bool flag);
|
||||
void redrawSceneItem();
|
||||
int calcItemMonsterPosition(ItemInPlay *i, uint16 direction);
|
||||
@ -1298,47 +1118,35 @@ private:
|
||||
uint8 *drawItemOrMonster(uint8 *shape, uint8 *monsterPalette, int x, int y, int fineX, int fineY, int flags, int tblValue, bool vflip);
|
||||
int calcDrawingLayerParameters(int srcX, int srcY, int &x2, int &y2, uint16 &w, uint16 &h, uint8 *shape, int vflip);
|
||||
|
||||
void updateMonster(MonsterInPlay *monster);
|
||||
void moveMonster(MonsterInPlay *monster);
|
||||
void walkMonster(MonsterInPlay *monster);
|
||||
bool chasePartyWithDistanceAttacks(MonsterInPlay *monster);
|
||||
void chasePartyWithCloseAttacks(MonsterInPlay *monster);
|
||||
int walkMonsterCalcNextStep(MonsterInPlay *monster);
|
||||
int getMonsterDistance(uint16 block1, uint16 block2);
|
||||
void updateMonster(LolMonsterInPlay *monster);
|
||||
void moveMonster(LolMonsterInPlay *monster);
|
||||
void walkMonster(LolMonsterInPlay *monster);
|
||||
bool chasePartyWithDistanceAttacks(LolMonsterInPlay *monster);
|
||||
void chasePartyWithCloseAttacks(LolMonsterInPlay *monster);
|
||||
int walkMonsterCalcNextStep(LolMonsterInPlay *monster);
|
||||
int checkForPossibleDistanceAttack(uint16 monsterBlock, int direction, int distance, uint16 curBlock);
|
||||
int walkMonsterCheckDest(int x, int y, MonsterInPlay *monster, int unk);
|
||||
int walkMonsterCheckDest(int x, int y, LolMonsterInPlay *monster, int unk);
|
||||
void getNextStepCoords(int16 monsterX, int16 monsterY, int &newX, int &newY, uint16 direction);
|
||||
void rearrangeAttackingMonster(MonsterInPlay *monster);
|
||||
void moveStrayingMonster(MonsterInPlay *monster);
|
||||
void killMonster(MonsterInPlay *monster);
|
||||
void rearrangeAttackingMonster(LolMonsterInPlay *monster);
|
||||
void moveStrayingMonster(LolMonsterInPlay *monster);
|
||||
void killMonster(LolMonsterInPlay *monster);
|
||||
|
||||
MonsterInPlay *_monsters;
|
||||
MonsterProperty *_monsterProperties;
|
||||
uint8 **_monsterShapes;
|
||||
uint8 **_monsterPalettes;
|
||||
uint8 **_monsterShapesEx;
|
||||
LolMonsterInPlay *_monsters;
|
||||
LolMonsterProperty *_monsterProperties;
|
||||
uint8 **_monsterDecorationShapes;
|
||||
uint8 _monsterAnimType[3];
|
||||
uint16 _monsterCurBlock;
|
||||
int _objectLastDirection;
|
||||
int _monsterStepCounter;
|
||||
int _monsterStepMode;
|
||||
|
||||
const uint16 *_monsterModifiers;
|
||||
int _monsterModifiersSize;
|
||||
const int8 *_monsterShiftOffs;
|
||||
int _monsterShiftOffsSize;
|
||||
const uint8 *_monsterDirFlags;
|
||||
int _monsterDirFlagsSize;
|
||||
const uint8 *_monsterScaleX;
|
||||
int _monsterScaleXSize;
|
||||
const uint8 *_monsterScaleY;
|
||||
int _monsterScaleYSize;
|
||||
const uint16 *_monsterScaleWH;
|
||||
int _monsterScaleWHSize;
|
||||
|
||||
// misc
|
||||
void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
|
||||
int rollDice(int times, int pips);
|
||||
|
||||
uint8 _compassBroken;
|
||||
uint8 _drainMagic;
|
||||
@ -1349,7 +1157,7 @@ private:
|
||||
|
||||
// spells
|
||||
typedef Common::Functor1Mem<ActiveSpell *, int, LoLEngine> SpellProc;
|
||||
Common::Array<const SpellProc *> _spellProcs;
|
||||
Common::Array<const SpellProc*> _spellProcs;
|
||||
typedef void (LoLEngine::*SpellProcCallback)(WSAMovie_v2 *, int, int);
|
||||
|
||||
int castSpell(int charNum, int spellType, int spellLevel);
|
||||
@ -1398,7 +1206,7 @@ private:
|
||||
int8 _availableSpells[8];
|
||||
int _selectedSpell;
|
||||
const SpellProperty *_spellProperties;
|
||||
int _spellPropertiesSize;
|
||||
//int _spellPropertiesSize;
|
||||
int _subMenuIndex;
|
||||
|
||||
LightningProperty *_lightningProps;
|
||||
@ -1420,13 +1228,9 @@ private:
|
||||
static const MistOfDoomAnimData _mistAnimData[];
|
||||
|
||||
const uint8 *_updateSpellBookCoords;
|
||||
int _updateSpellBookCoordsSize;
|
||||
const uint8 *_updateSpellBookAnimData;
|
||||
int _updateSpellBookAnimDataSize;
|
||||
const uint8 *_healShapeFrames;
|
||||
int _healShapeFramesSize;
|
||||
const int16 *_fireBallCoords;
|
||||
int _fireBallCoordsSize;
|
||||
|
||||
// fight
|
||||
int battleHitSkillTest(int16 attacker, int16 target, int skill);
|
||||
@ -1437,8 +1241,8 @@ private:
|
||||
int calcInflictableDamagePerItem(int16 attacker, int16 target, uint16 itemMight, int index, int hitType);
|
||||
void checkForPartyDeath();
|
||||
|
||||
void applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, int16 damage);
|
||||
void applyMonsterDefenseSkill(MonsterInPlay *monster, int16 attacker, int flags, int skill, int damage);
|
||||
void applyMonsterAttackSkill(LolMonsterInPlay *monster, int16 target, int16 damage);
|
||||
void applyMonsterDefenseSkill(LolMonsterInPlay *monster, int16 attacker, int flags, int skill, int damage);
|
||||
int removeCharacterItem(int charNum, int itemFlags);
|
||||
int paralyzePoisonCharacter(int charNum, int typeFlag, int immunityFlags, int hitChance, int redraw);
|
||||
void paralyzePoisonAllCharacters(int typeFlag, int immunityFlags, int hitChance);
|
||||
@ -1478,7 +1282,6 @@ private:
|
||||
uint8 *_mapOverlay;
|
||||
const uint8 **_automapShapes;
|
||||
const uint16 *_autoMapStrings;
|
||||
int _autoMapStringsSize;
|
||||
MapLegendData *_defaultLegendData;
|
||||
uint8 *_mapCursorOverlay;
|
||||
uint8 _automapTopLeftX;
|
||||
@ -1495,10 +1298,15 @@ private:
|
||||
Common::Error loadGameState(int slot);
|
||||
Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail);
|
||||
|
||||
Graphics::Surface *generateSaveThumbnail() const;
|
||||
void *generateMonsterTempData(LevelTempData *tmp);
|
||||
void *generateFlyingObjectTempData(LevelTempData *tmp);
|
||||
void restoreBlockTempData(int levelIndex);
|
||||
void restoreMonsterTempData(LevelTempData *tmp);
|
||||
void restoreFlyingObjectTempData(LevelTempData *tmp);
|
||||
void releaseMonsterTempData(LevelTempData *tmp);
|
||||
void releaseFlyingObjectTempData(LevelTempData *tmp);
|
||||
|
||||
void generateTempData();
|
||||
LevelTempData *_lvlTempData[29];
|
||||
Graphics::Surface *generateSaveThumbnail() const;
|
||||
};
|
||||
|
||||
class HistoryPlayer {
|
||||
|
354
engines/kyra/loleobbase.cpp
Normal file
354
engines/kyra/loleobbase.cpp
Normal file
@ -0,0 +1,354 @@
|
||||
/* 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) {
|
||||
_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;
|
||||
|
||||
_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 = 9;
|
||||
_dialogueButtonLabelCol2 = 15;
|
||||
_dialogueButtonW = 95;
|
||||
_dialogueButtonH = 9;
|
||||
|
||||
_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;
|
||||
|
||||
delete _txt;
|
||||
_txt = 0;
|
||||
}
|
||||
|
||||
Common::Error LolEobBaseEngine::init() {
|
||||
_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[255];
|
||||
memset(_wllVmpMap, 0, 255);
|
||||
_wllShapeMap = new int8[255];
|
||||
memset(_wllShapeMap, 0, 255);
|
||||
_specialWallTypes = new uint8[255];
|
||||
memset(_specialWallTypes, 0, 255);
|
||||
_wllWallFlags = new uint8[255];
|
||||
memset(_wllWallFlags, 0, 255);
|
||||
|
||||
_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 mouseX, int mouseY, int x1, int y1, int x2, int y2) {
|
||||
if (mouseX < x1 || mouseX > x2 || mouseY < y1 || mouseY > 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) & 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
|
324
engines/kyra/loleobbase.h
Normal file
324
engines/kyra/loleobbase.h
Normal file
@ -0,0 +1,324 @@
|
||||
/* 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;
|
||||
uint8 monsterDifficulty;
|
||||
};
|
||||
|
||||
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 mouseX, int mouseY, 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() = 0;
|
||||
virtual void drawDecorations(int index) = 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;
|
||||
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];
|
||||
|
||||
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;
|
||||
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();
|
||||
void restoreBlockTempData(int levelIndex);
|
||||
void releaseTempData();
|
||||
virtual void *generateMonsterTempData(LevelTempData *tmp) = 0;
|
||||
virtual void *generateFlyingObjectTempData(LevelTempData *tmp) = 0;
|
||||
virtual void restoreMonsterTempData(LevelTempData *tmp) = 0;
|
||||
virtual void restoreFlyingObjectTempData(LevelTempData *tmp) = 0;
|
||||
virtual void releaseMonsterTempData(LevelTempData *tmp) = 0;
|
||||
virtual void releaseFlyingObjectTempData(LevelTempData *tmp) = 0;
|
||||
|
||||
LevelTempData *_lvlTempData[29];
|
||||
|
||||
// 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
|
780
engines/kyra/magic_eob.cpp
Normal file
780
engines/kyra/magic_eob.cpp
Normal file
@ -0,0 +1,780 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#include "kyra/eobcommon.h"
|
||||
#include "kyra/resource.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
void EobCoreEngine::useMagicBookOrSymbol(int charIndex, int type) {
|
||||
EobCharacter *c = &_characters[charIndex];
|
||||
_openBookSpellLevel = c->slotStatus[3];
|
||||
_openBookSpellSelectedItem = c->slotStatus[2];
|
||||
_openBookSpellListOffset = c->slotStatus[4];
|
||||
_openBookChar = charIndex;
|
||||
_openBookType = type;
|
||||
_openBookSpellList = (type == 1) ? _clericSpellList : _mageSpellList;
|
||||
_openBookAvailableSpells = (type == 1) ? c->clericSpells : c->mageSpells;
|
||||
int8 *tmp = _openBookAvailableSpells + _openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem;
|
||||
|
||||
if (*tmp <= 0) {
|
||||
for (bool loop = true; loop && _openBookSpellSelectedItem < 10; ) {
|
||||
tmp = _openBookAvailableSpells + _openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem;
|
||||
if (*tmp > 0) {
|
||||
if (_openBookSpellSelectedItem > 5) {
|
||||
_openBookSpellListOffset = 6;
|
||||
_openBookSpellSelectedItem -= 6;
|
||||
}
|
||||
loop = false;
|
||||
} else {
|
||||
_openBookSpellSelectedItem++;
|
||||
}
|
||||
}
|
||||
|
||||
if (_openBookSpellSelectedItem == 10) {
|
||||
_openBookSpellListOffset = 0;
|
||||
_openBookSpellSelectedItem = 6;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_updateFlags)
|
||||
_screen->copyRegion(64, 121, 0, 0, 112, 56, 0, 10, Screen::CR_NO_P_CHECK);
|
||||
_updateFlags = 1;
|
||||
gui_setPlayFieldButtons();
|
||||
gui_drawSpellbook();
|
||||
}
|
||||
|
||||
void EobCoreEngine::useMagicScroll(int charIndex, int type, int weaponSlot) {
|
||||
_openBookCharBackup = _openBookChar;
|
||||
_openBookTypeBackup = _openBookType;
|
||||
_castScrollSlot = weaponSlot + 1;
|
||||
_openBookChar = charIndex;
|
||||
_openBookType = type <= _clericSpellOffset ? 0 : 1;
|
||||
castSpell(type, weaponSlot);
|
||||
}
|
||||
|
||||
void EobCoreEngine::usePotion(int charIndex, int weaponSlot) {
|
||||
EobCharacter *c = &_characters[_openBookChar];
|
||||
int offset = (_flags.gameID == GI_EOB1) ? 13 : (_flags.lang == Common::DE_DEU ? 19 : 15);
|
||||
|
||||
int val = deleteInventoryItem(charIndex, weaponSlot);
|
||||
snd_playSoundEffect(10);
|
||||
|
||||
switch (val) {
|
||||
case 0:
|
||||
sparkEffectDefensive(charIndex);
|
||||
c->strengthCur = 22;
|
||||
c->strengthExtCur = 0;
|
||||
setCharEventTimer(charIndex, 546 * rollDice(1, 4, 4), 7, 1);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
sparkEffectDefensive(charIndex);
|
||||
modifyCharacterHitpoints(charIndex, rollDice(2, 4, 2));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
sparkEffectDefensive(charIndex);
|
||||
modifyCharacterHitpoints(charIndex, rollDice(3, 8, 3));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
statusAttack(charIndex, 2, _itemExtraStrings[offset], 0, 1, 8, 1);
|
||||
c->effectFlags &= ~0x2000;
|
||||
if (c->flags & 2)
|
||||
return;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
sparkEffectDefensive(charIndex);
|
||||
c->food = 100;
|
||||
if (_currentControlMode)
|
||||
gui_drawCharPortraitWithStats(charIndex);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
sparkEffectDefensive(charIndex);
|
||||
c->effectFlags |= 0x10000;
|
||||
setCharEventTimer(charIndex, 546 * rollDice(1, 4, 4), 12, 1);
|
||||
snd_playSoundEffect(100);
|
||||
gui_drawCharPortraitWithStats(charIndex);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
sparkEffectDefensive(charIndex);
|
||||
c->effectFlags |= 0x40;
|
||||
gui_drawCharPortraitWithStats(charIndex);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
sparkEffectDefensive(charIndex);
|
||||
neutralizePoison(charIndex);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_txt->printMessage(_itemExtraStrings[offset + 1], -1, c->name, _potionEffectStrings[val]);
|
||||
}
|
||||
|
||||
void EobCoreEngine::castSpell(int spell, int weaponSlot) {
|
||||
EobSpell *s = &_spells[spell];
|
||||
EobCharacter *c = &_characters[_openBookChar];
|
||||
_activeSpell = spell;
|
||||
|
||||
if ((s->flags & 0x100) && (c->effectFlags & 0x40))
|
||||
// remove invisibility effect
|
||||
removeCharacterEffect(10, _openBookChar, 1);
|
||||
|
||||
int ci = _openBookChar;
|
||||
if (ci > 3)
|
||||
ci -= 2;
|
||||
|
||||
_activeSpellCasterPos = _dropItemDirIndex[(_currentDirection << 2) + ci];
|
||||
|
||||
if (s->flags & 0x400) {
|
||||
if (c->inventory[0] && c->inventory[1]) {
|
||||
_txt->printMessage(_magicStrings1[2]);
|
||||
snd_playSoundEffect(79);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMagicWeapon(c->inventory[0]) || isMagicWeapon(c->inventory[1])) {
|
||||
_txt->printMessage(_magicStrings1[3]);
|
||||
snd_playSoundEffect(79);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(_flags.gameID == GI_EOB2 && _activeSpell == 62)) {
|
||||
if (!_castScrollSlot) {
|
||||
int8 tmp = _openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem];
|
||||
if (_openBookSpellListOffset + _openBookSpellSelectedItem < 8)
|
||||
memmove(&_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem], &_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem + 1], 8 - (_openBookSpellListOffset + _openBookSpellSelectedItem));
|
||||
_openBookAvailableSpells[_openBookSpellLevel * 10 + 8] = -tmp;
|
||||
if (_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem] < 0) {
|
||||
if (--_openBookSpellSelectedItem == -1)
|
||||
if (_openBookSpellListOffset) {
|
||||
_openBookSpellListOffset = 0;
|
||||
_openBookSpellSelectedItem = 5;
|
||||
} else {
|
||||
_openBookSpellSelectedItem = 6;
|
||||
}
|
||||
}
|
||||
} else if (weaponSlot != -1) {
|
||||
updateUsedCharacterHandItem(_openBookChar, weaponSlot);
|
||||
}
|
||||
}
|
||||
|
||||
_txt->printMessage(_magicStrings1[4], -1, c->name, s->name);
|
||||
|
||||
if (s->flags & 0x20) {
|
||||
castOnWhomDialogue();
|
||||
return;
|
||||
}
|
||||
|
||||
_activeSpellCaster = _openBookChar;
|
||||
startSpell(spell);
|
||||
}
|
||||
|
||||
void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarning) {
|
||||
EobCharacter *c = &_characters[charIndex];
|
||||
EobSpell *s = &_spells[spell];
|
||||
|
||||
if (showWarning) {
|
||||
_txt->printMessage(_magicStrings3[2], -1, c->name, s->name);
|
||||
snd_playSoundEffect(79);
|
||||
}
|
||||
|
||||
if (s->endCallback)
|
||||
(this->*s->endCallback)(0);
|
||||
|
||||
if (s->flags & 1)
|
||||
c->effectFlags &= ~s->effectFlags;
|
||||
|
||||
if (s->flags & 4)
|
||||
_partyEffectFlags &= ~s->effectFlags;
|
||||
|
||||
if (s->flags & 0x200) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 1))
|
||||
continue;
|
||||
if (!testCharacter(i, 2) && !(s->flags & 0x800))
|
||||
continue;
|
||||
_characters[i].effectFlags &= ~s->effectFlags;
|
||||
}
|
||||
}
|
||||
|
||||
if (s->flags & 0x2)
|
||||
recalcArmorClass(_activeSpellCaster);
|
||||
|
||||
if (showWarning) {
|
||||
if (s->flags & 0x20A0)
|
||||
gui_drawCharPortraitWithStats(charIndex);
|
||||
else if (s->flags & 0x20A0)
|
||||
gui_drawAllCharPortraitsWithStats();
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::removeAllCharacterEffects(int charIndex) {
|
||||
EobCharacter *c = &_characters[charIndex];
|
||||
memset(c->effectsRemainder, 0, 4);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (c->events[i] < 0)
|
||||
removeCharacterEffect(-c->events[i], charIndex, 0);
|
||||
c->timers[i] = 0;
|
||||
c->events[i] = 0;
|
||||
}
|
||||
|
||||
setupCharacterTimers();
|
||||
recalcArmorClass(charIndex);
|
||||
c->disabledSlots = 0;
|
||||
c->slotStatus[0] = c->slotStatus[1] = 0;
|
||||
c->damageTaken = 0;
|
||||
c->strengthCur = c->strengthMax;
|
||||
c->strengthExtCur = c->strengthExtMax;
|
||||
gui_drawAllCharPortraitsWithStats();
|
||||
}
|
||||
|
||||
void EobCoreEngine::castOnWhomDialogue() {
|
||||
_txt->printMessage(_magicStrings3[0]);
|
||||
snd_playSoundEffect(79);
|
||||
gui_setCastOnWhomButtons();
|
||||
}
|
||||
|
||||
void EobCoreEngine::startSpell(int spell) {
|
||||
EobSpell *s = &_spells[spell];
|
||||
EobCharacter *c = &_characters[_activeSpellCaster];
|
||||
snd_playSoundEffect(s->sound);
|
||||
|
||||
if (s->flags & 0xa0)
|
||||
sparkEffectDefensive(_activeSpellCaster);
|
||||
else if (s->flags & 0x40)
|
||||
sparkEffectDefensive(-1);
|
||||
else if (s->flags & 0x1000)
|
||||
sparkEffectOffensive();
|
||||
|
||||
if (s->flags & 0x20) {
|
||||
_txt->printMessage(c->name);
|
||||
_txt->printMessage(_magicStrings1[5]);
|
||||
}
|
||||
|
||||
if ((s->flags & 0x30) && (s->effectFlags & c->effectFlags)) {
|
||||
_txt->printMessage(_magicStrings7[0], -1, c->name, s->name);
|
||||
snd_playSoundEffect(79);
|
||||
} else if ((s->flags & 0x50) && (s->effectFlags & _partyEffectFlags)) {
|
||||
_txt->printMessage(_magicStrings7[1], -1, s->name);
|
||||
snd_playSoundEffect(79);
|
||||
} else {
|
||||
if (s->flags & 8)
|
||||
setSpellEventTimer(spell, s->timingPara[0], s->timingPara[1], s->timingPara[2], s->timingPara[3]);
|
||||
|
||||
_returnAfterSpellCallback = false;
|
||||
if (s->startCallback)
|
||||
(this->*s->startCallback)();
|
||||
if (_returnAfterSpellCallback)
|
||||
return;
|
||||
|
||||
if (s->flags & 1)
|
||||
c->effectFlags |= s->effectFlags;
|
||||
if (s->flags & 4)
|
||||
_partyEffectFlags |= s->effectFlags;
|
||||
|
||||
if (s->flags & 0x200) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 1))
|
||||
continue;
|
||||
if (!testCharacter(i, 2) && !(s->flags & 0x800))
|
||||
continue;
|
||||
_characters[i].effectFlags |= s->effectFlags;
|
||||
}
|
||||
}
|
||||
|
||||
if (s->flags & 2)
|
||||
recalcArmorClass(_activeSpellCaster);
|
||||
|
||||
if (s->flags & 0x20A0)
|
||||
gui_drawCharPortraitWithStats(_activeSpellCaster);
|
||||
if (s->flags & 0x40)
|
||||
gui_drawAllCharPortraitsWithStats();
|
||||
}
|
||||
|
||||
if (_castScrollSlot) {
|
||||
gui_updateSlotAfterScrollUse();
|
||||
} else {
|
||||
c->disabledSlots |= 4;
|
||||
setCharEventTimer(_openBookChar, 72, 11, 1);
|
||||
gui_toggleButtons();
|
||||
gui_drawSpellbook();
|
||||
}
|
||||
|
||||
if (_flags.gameID == GI_EOB2) {
|
||||
//_castSpellWd1 = spell;
|
||||
runLevelScript(_currentBlock, 0x800);
|
||||
//_castSpellWd1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::sparkEffectDefensive(int charIndex) {
|
||||
int first = charIndex;
|
||||
int last = charIndex;
|
||||
if (charIndex == -1) {
|
||||
first = 0;
|
||||
last = 5;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int ii = first; ii <= last; ii++) {
|
||||
if (!testCharacter(ii, 1) || (_currentControlMode && ii != _updateCharNum))
|
||||
continue;
|
||||
|
||||
gui_drawCharPortraitWithStats(ii);
|
||||
|
||||
for (int iii = 0; iii < 4; iii++) {
|
||||
int shpIndex = ((_sparkEffectDefSteps[i] & _sparkEffectDefSubSteps[iii]) >> _sparkEffectDefShift[iii]);
|
||||
if (!shpIndex)
|
||||
continue;
|
||||
int x = _sparkEffectDefAdd[iii * 2] - 8;
|
||||
int y = _sparkEffectDefAdd[iii * 2 + 1];
|
||||
if (_currentControlMode) {
|
||||
x += 181;
|
||||
y += 3;
|
||||
} else {
|
||||
x += (_sparkEffectDefX[ii] << 3);
|
||||
y += _sparkEffectDefY[ii];
|
||||
}
|
||||
_screen->drawShape(0, _sparkShapes[shpIndex - 1], x, y, 0);
|
||||
_screen->updateScreen();
|
||||
}
|
||||
}
|
||||
resetSkipFlag();
|
||||
delay(2 * _tickLength);
|
||||
}
|
||||
|
||||
for (int i = first; i < last; i++)
|
||||
gui_drawCharPortraitWithStats(i);
|
||||
}
|
||||
|
||||
void EobCoreEngine::sparkEffectOffensive() {
|
||||
disableSysTimer(2);
|
||||
_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 2, Screen::CR_NO_P_CHECK);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
_screen->copyRegionToBuffer(0, _sparkEffectOfX[i], _sparkEffectOfY[i], 16, 16, &_spellAnimBuffer[i << 8]);
|
||||
_screen->updateScreen();
|
||||
|
||||
for (int i = 0; i < 11; i++) {
|
||||
for (int ii = 0; ii < 16; ii++)
|
||||
_screen->copyBlockToPage(2, _sparkEffectOfX[ii], _sparkEffectOfY[ii], 16, 16, &_spellAnimBuffer[ii << 8]);
|
||||
|
||||
for (int ii = 0; ii < 16; ii++) {
|
||||
int shpIndex = (_sparkEffectOfFlags1[i] & _sparkEffectOfFlags2[ii]) >> _sparkEffectOfShift[ii];
|
||||
if (shpIndex)
|
||||
_screen->drawShape(2, _sparkShapes[shpIndex - 1], _sparkEffectOfX[ii], _sparkEffectOfY[ii], 0);
|
||||
}
|
||||
resetSkipFlag();
|
||||
delay(2 * _tickLength);
|
||||
_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
|
||||
_screen->updateScreen();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
_screen->copyBlockToPage(0, _sparkEffectOfX[i], _sparkEffectOfY[i], 16, 16, &_spellAnimBuffer[i << 8]);
|
||||
|
||||
_screen->updateScreen();
|
||||
enableSysTimer(2);
|
||||
}
|
||||
|
||||
void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer) {
|
||||
int l = _openBookType == 1 ? getCharacterClericPaladinLevel(_openBookChar) : getCharacterMageLevel(_openBookChar);
|
||||
uint32 countdown = timerLength * timerBaseFactor + timerLength * l * timerLevelFactor;
|
||||
setCharEventTimer(_activeSpellCaster, countdown, -spell, updateExistingTimer);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level) {
|
||||
int ignoreAttackerId = fo->flags & 0x10;
|
||||
int singleTargetCheckAdjacent = fo->flags & 1;
|
||||
int blockDamage = fo->flags & 2;
|
||||
int hitTest = fo->flags & 4;
|
||||
|
||||
int s = 5;
|
||||
int dmgType = 3;
|
||||
if (fo->flags & 8) {
|
||||
s = 4;
|
||||
dmgType = 0;
|
||||
}
|
||||
|
||||
int dmgFlag = _spells[fo->callBackIndex].damageFlags;
|
||||
if (fo->attackerId >= 0)
|
||||
dmgFlag |= 0x800;
|
||||
|
||||
bool res = false;
|
||||
if (!level)
|
||||
level = 1;
|
||||
|
||||
if ((_levelBlockProperties[fo->curBlock].flags & 7) && (fo->attackerId >= 0 || ignoreAttackerId)) {
|
||||
_inflictMonsterDamageUnk = 1;
|
||||
|
||||
for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, blockDamage, singleTargetCheckAdjacent); *m != -1; m++) {
|
||||
int dmg = rollDice(dcTimes, dcPips, dcOffs) * level;
|
||||
|
||||
if (hitTest) {
|
||||
if (!characterAttackHitTest(fo->attackerId, *m, 0, 0))
|
||||
continue;
|
||||
}
|
||||
|
||||
calcAndInflictMonsterDamage(&_monsters[*m], 0, 0, dmg, dmgFlag, s, dmgType);
|
||||
res = true;
|
||||
}
|
||||
updateAllMonsterShapes();
|
||||
|
||||
} else if (fo->curBlock == _currentBlock && (fo->attackerId < 0 || ignoreAttackerId)) {
|
||||
if (blockDamage) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 1))
|
||||
continue;
|
||||
if (hitTest && !monsterAttackHitTest(&_monsters[0], i))
|
||||
continue;
|
||||
|
||||
int dmg = rollDice(dcTimes, dcPips, dcOffs) * level;
|
||||
res = true;
|
||||
|
||||
calcAndInflictCharacterDamage(i, 0, 0, dmg, dmgFlag, s, dmgType);
|
||||
}
|
||||
} else {
|
||||
int c = _dscItemPosIndex[(_currentDirection << 2) + (fo->curPos & 3)];
|
||||
if ((c > 2) && (testCharacter(5, 1) || testCharacter(6, 1)) && rollDice(1, 2, -1))
|
||||
c += 2;
|
||||
|
||||
if (!fo->item && (_characters[c].effectFlags & 8)) {
|
||||
res = true;
|
||||
} else {
|
||||
if ((_characters[c].flags & 1) && hitTest && !monsterAttackHitTest(&_monsters[0], c)) {
|
||||
int dmg = rollDice(dcTimes, dcPips, dcOffs) * level;
|
||||
res = true;
|
||||
calcAndInflictCharacterDamage(c, 0, 0, dmg, dmgFlag, s, dmgType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (res && (fo->flags & 0x40))
|
||||
updateFlyingObject_s3(fo);
|
||||
else if ((_flags.gameID == GI_EOB1 && fo->item == 5) || (_flags.gameID == GI_EOB2 && fo->item == 4))
|
||||
res = false;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_armor() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_burningHands() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_detectMagic() {
|
||||
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_detectMagic(EobFlyingObject*) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_magicMissile() {
|
||||
launchMagicObject(_openBookChar, 0, _currentBlock, _activeSpellCasterPos, _currentDirection);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_magicMissile(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 1, 4, 1, (getCharacterMageLevel(fo->attackerId) - 1) >> 1);
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_shockingGrasp() {
|
||||
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_shockingGraspFlameBlade(EobFlyingObject*) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_improvedIdentify() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_melfsAcidArrow() {
|
||||
launchMagicObject(_openBookChar, 1, _currentBlock, _activeSpellCasterPos, _currentDirection);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_melfsAcidArrow(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 2, 4, 0, getCharacterMageLevel(fo->attackerId) / 3);
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_dispelMagic() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_fireball() {
|
||||
launchMagicObject(_openBookChar, 2, _currentBlock, _activeSpellCasterPos, _currentDirection);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_fireball(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_flameArrow() {
|
||||
launchMagicObject(_openBookChar, 3, _currentBlock, _activeSpellCasterPos, _currentDirection);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_flameArrow(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 5, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_holdPerson() {
|
||||
launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 4 : 3, _currentBlock, _activeSpellCasterPos, _currentDirection);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_holdPerson(EobFlyingObject *fo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_lightningBolt() {
|
||||
launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 5 : 4, _currentBlock, _activeSpellCasterPos, _currentDirection);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_lightningBolt(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_vampiricTouch() {
|
||||
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_vampiricTouch(EobFlyingObject*) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_fear() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_iceStorm() {
|
||||
launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 6 : 5, _currentBlock, _activeSpellCasterPos, _currentDirection);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_iceStorm(EobFlyingObject *fo) {
|
||||
static int8 blockAdv[] = { -32, 32, 1, -1 };
|
||||
bool res = magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
if (res) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
uint16 bl = fo->curBlock;
|
||||
fo->curBlock = (fo->curBlock + blockAdv[i]) & 0x3ff;
|
||||
magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
fo->curBlock = bl;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_removeCurse() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_coneOfCold() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_holdMonster() {
|
||||
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_holdMonster(EobFlyingObject *fo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_wallOfForce() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_disintegrate() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_fleshToStone() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_stoneToFlesh() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_trueSeeing() {
|
||||
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_trueSeeing(EobFlyingObject*) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_slayLiving() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_powerWordStun() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_causeLightWounds() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_cureLightWounds() {
|
||||
modifyCharacterHitpoints(_activeSpellCaster, rollDice(1, 8));
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_aid() {
|
||||
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_aid(EobFlyingObject*) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_flameBlade() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_slowPoison() {
|
||||
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_slowPoison(EobFlyingObject*) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_createFood() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 3))
|
||||
continue;
|
||||
_characters[_activeSpellCaster].food = 100;
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_removeParalysis() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_causeSeriousWounds() {
|
||||
modifyCharacterHitpoints(_activeSpellCaster, rollDice(2, 8, 1));
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_cureSeriousWounds() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_neutralizePoison() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_causeCriticalWounds() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_cureCriticalWounds() {
|
||||
modifyCharacterHitpoints(_activeSpellCaster, rollDice(3, 8, 3));
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_flameStrike() {
|
||||
launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 8 : 7, _currentBlock, _activeSpellCasterPos, _currentDirection);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_flameStrike(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 6, 8, 0, 0);
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_raiseDead() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_harm() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_heal() {
|
||||
EobCharacter *c = &_characters[_activeSpellCaster];
|
||||
if (c->hitPointsMax <= c->hitPointsCur) {
|
||||
_txt->printMessage(_magicStrings4[0]);
|
||||
snd_playSoundEffect(79);
|
||||
} else {
|
||||
modifyCharacterHitpoints(_activeSpellCaster, c->hitPointsMax - c->hitPointsCur);
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_layOnHands() {
|
||||
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_turnUndead() {
|
||||
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_unk1Passive(EobFlyingObject *fo) {
|
||||
bool res = false;
|
||||
if (_partyEffectFlags & 0x20000) {
|
||||
res = magicObjectHit(fo, 4, 10, 6, 0);
|
||||
if (res) {
|
||||
gui_drawAllCharPortraitsWithStats();
|
||||
_partyEffectFlags &= ~0x20000;
|
||||
}
|
||||
} else {
|
||||
res = magicObjectHit(fo, 12, 10, 6, 0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_unk2Passive(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 0, 0, 18, 0);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_deathSpellPassive(EobFlyingObject *fo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_disintegratePassive(EobFlyingObject *fo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_causeCriticalWoundsPassive(EobFlyingObject *fo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_fleshToStonePassive(EobFlyingObject *fo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
@ -72,8 +72,19 @@ MODULE_OBJS := \
|
||||
vqa.o \
|
||||
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
|
||||
|
||||
ifdef ENABLE_LOL
|
||||
MODULE_OBJS += \
|
||||
$(KYRARPG_COMMON_OBJ) \
|
||||
gui_lol.o \
|
||||
items_lol.o \
|
||||
lol.o \
|
||||
@ -89,6 +100,24 @@ MODULE_OBJS += \
|
||||
timer_lol.o
|
||||
endif
|
||||
|
||||
ifdef ENABLE_EOB
|
||||
ifndef ENABLE_LOL
|
||||
MODULE_OBJS += \
|
||||
$(KYRARPG_COMMON_OBJ)
|
||||
endif
|
||||
MODULE_OBJS += \
|
||||
chargen.o \
|
||||
eobcommon.o \
|
||||
eob1.o \
|
||||
eob2.o \
|
||||
items_eob.o \
|
||||
magic_eob.o \
|
||||
screen_eob.o \
|
||||
script_eob.o \
|
||||
sequences_eob1.o \
|
||||
sequences_eob2.o
|
||||
endif
|
||||
|
||||
# This module can be built as a plugin
|
||||
ifeq ($(ENABLE_KYRA), DYNAMIC_PLUGIN)
|
||||
PLUGIN := 1
|
||||
|
@ -59,7 +59,7 @@ bool Resource::reset() {
|
||||
if (!dir.exists() || !dir.isDirectory())
|
||||
error("invalid game path '%s'", dir.getPath().c_str());
|
||||
|
||||
if (_vm->game() == GI_KYRA1) {
|
||||
if (_vm->game() == GI_KYRA1 || _vm->game() == GI_EOB1) {
|
||||
// We only need kyra.dat for the demo.
|
||||
if (_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie)
|
||||
return true;
|
||||
@ -128,7 +128,7 @@ bool Resource::reset() {
|
||||
|
||||
loadProtectedFiles(list);
|
||||
}
|
||||
} else {
|
||||
} else if (_vm->game() != GI_EOB2) {
|
||||
error("Unknown game id: %d", _vm->game());
|
||||
return false; // for compilers that don't support NORETURN
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "common/archive.h"
|
||||
|
||||
#include "kyra/kyra_v1.h"
|
||||
#include "kyra/eob2.h"
|
||||
#include "kyra/lol.h"
|
||||
#include "kyra/kyra_hof.h"
|
||||
|
||||
@ -250,7 +251,264 @@ enum KyraResources {
|
||||
k3ItemMagicTable,
|
||||
k3ItemStringMap,
|
||||
|
||||
#ifdef ENABLE_LOL
|
||||
#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
|
||||
kLolEobCommonMoreStrings,
|
||||
kLolEobCommonDscShapeIndex,
|
||||
kLolEobCommonDscX,
|
||||
kLolEobCommonDscTileIndex,
|
||||
kLolEobCommonDscUnk2,
|
||||
kLolEobCommonDscDoorShapeIndex,
|
||||
kLolEobCommonDscDimData1,
|
||||
kLolEobCommonDscDimData2,
|
||||
kLolEobCommonDscBlockMap,
|
||||
kLolEobCommonDscDimMap,
|
||||
kLolEobCommonDscDoorY2,
|
||||
kLolEobCommonDscBlockIndex,
|
||||
|
||||
kEobBaseChargenStrings1,
|
||||
kEobBaseChargenStrings2,
|
||||
kEobBaseChargenStartLevels,
|
||||
kEobBaseChargenStatStrings,
|
||||
kEobBaseChargenRaceSexStrings,
|
||||
kEobBaseChargenClassStrings,
|
||||
kEobBaseChargenAlignmentStrings,
|
||||
kEobBaseChargenEnterGameStrings,
|
||||
kEobBaseChargenClassMinStats,
|
||||
kEobBaseChargenRaceMinStats,
|
||||
kEobBaseChargenRaceMaxStats,
|
||||
|
||||
kEobBaseConstModTable1,
|
||||
kEobBaseConstModTable2,
|
||||
kEobBaseConstModTable3,
|
||||
kEobBaseConstModTable4,
|
||||
kEobBaseConstModLvlIndex,
|
||||
kEobBaseConstModDiv,
|
||||
kEobBaseConstModExt,
|
||||
|
||||
kEobBasePryDoorStrings,
|
||||
kEobBaseWarningStrings,
|
||||
kEobBaseItemSuffixStrings,
|
||||
kEobBaseItemExtraStrings,
|
||||
kEobBaseTakenStrings,
|
||||
kEobBasePotionEffectStrings,
|
||||
|
||||
kEobBaseYesNoStrings,
|
||||
kEobBaseNpcMaxStrings,
|
||||
kEobBaseOkStrings,
|
||||
kEobBaseNpcJoinStrings,
|
||||
kEobBaseCancelStrings,
|
||||
kEobBaseAbortStrings,
|
||||
|
||||
kEobBaseCharGuiStringsHp,
|
||||
kEobBaseCharGuiStringsWp1,
|
||||
kEobBaseCharGuiStringsWp2,
|
||||
kEobBaseCharGuiStringsWr,
|
||||
kEobBaseCharGuiStringsSt1,
|
||||
kEobBaseCharGuiStringsSt2,
|
||||
kEobBaseCharGuiStringsIn,
|
||||
|
||||
kEobBaseCharStatusStrings7,
|
||||
kEobBaseCharStatusStrings81,
|
||||
kEobBaseCharStatusStrings82,
|
||||
kEobBaseCharStatusStrings9,
|
||||
kEobBaseCharStatusStrings12,
|
||||
kEobBaseCharStatusStrings131,
|
||||
kEobBaseCharStatusStrings132,
|
||||
|
||||
kEobBaseLevelGainStrings,
|
||||
kEobBaseExperienceTable0,
|
||||
kEobBaseExperienceTable1,
|
||||
kEobBaseExperienceTable2,
|
||||
kEobBaseExperienceTable3,
|
||||
kEobBaseExperienceTable4,
|
||||
|
||||
kEobBaseClassModifierFlags,
|
||||
|
||||
kEobBaseMonsterStepTable01,
|
||||
kEobBaseMonsterStepTable02,
|
||||
kEobBaseMonsterStepTable1,
|
||||
kEobBaseMonsterStepTable2,
|
||||
kEobBaseMonsterStepTable3,
|
||||
kEobBaseMonsterCloseAttPosTable1,
|
||||
kEobBaseMonsterCloseAttPosTable21,
|
||||
kEobBaseMonsterCloseAttPosTable22,
|
||||
kEobBaseMonsterCloseAttUnkTable,
|
||||
kEobBaseMonsterCloseAttChkTable1,
|
||||
kEobBaseMonsterCloseAttChkTable2,
|
||||
kEobBaseMonsterCloseAttDstTable1,
|
||||
kEobBaseMonsterCloseAttDstTable2,
|
||||
|
||||
kEobBaseMonsterProximityTable,
|
||||
kEobBaseFindBlockMonstersTable,
|
||||
kEobBaseMonsterDirChangeTable,
|
||||
kEobBaseMonsterDistAttStrings,
|
||||
|
||||
kEobBaseEncodeMonsterDefs,
|
||||
kEobBaseNpcPresets,
|
||||
|
||||
kEobBaseWllFlagPreset,
|
||||
kEobBaseDscShapeCoords,
|
||||
|
||||
kEobBaseDscDoorScaleOffs,
|
||||
kEobBaseDscDoorScaleMult1,
|
||||
kEobBaseDscDoorScaleMult2,
|
||||
kEobBaseDscDoorScaleMult3,
|
||||
kEobBaseDscDoorScaleMult4,
|
||||
kEobBaseDscDoorScaleMult5,
|
||||
kEobBaseDscDoorScaleMult6,
|
||||
kEobBaseDscDoorType5Offs,
|
||||
kEobBaseDscDoorY1,
|
||||
kEobBaseDscDoorY3,
|
||||
kEobBaseDscDoorY4,
|
||||
kEobBaseDscDoorY5,
|
||||
kEobBaseDscDoorY6,
|
||||
kEobBaseDscDoorCoordsExt,
|
||||
|
||||
kEobBaseDscItemPosIndex,
|
||||
kEobBaseDscItemShpX,
|
||||
kEobBaseDscItemScaleIndex,
|
||||
kEobBaseDscItemTileIndex,
|
||||
kEobBaseDscItemShapeMap,
|
||||
|
||||
kEobBaseDscMonsterFrmOffsTbl1,
|
||||
kEobBaseDscMonsterFrmOffsTbl2,
|
||||
|
||||
kEobBaseInvSlotX,
|
||||
kEobBaseInvSlotY,
|
||||
kEobBaseSlotValidationFlags,
|
||||
kEobBaseDrawObjPosIndex,
|
||||
kEobBaseFlightObjFlipIndex,
|
||||
kEobBaseFlightObjShpMap,
|
||||
kEobBaseFlightObjSclIndex,
|
||||
|
||||
kEobBaseDscTelptrShpCoords,
|
||||
|
||||
kEobBaseBookNumbers,
|
||||
kEobBaseMageSpellsList,
|
||||
kEobBaseClericSpellsList,
|
||||
kEobBaseSpellNames,
|
||||
kEobBaseMagicStrings1,
|
||||
kEobBaseMagicStrings2,
|
||||
kEobBaseMagicStrings3,
|
||||
kEobBaseMagicStrings4,
|
||||
kEobBaseMagicStrings5,
|
||||
kEobBaseMagicStrings6,
|
||||
kEobBaseMagicStrings7,
|
||||
kEobBaseMagicStrings8,
|
||||
|
||||
kEobBaseSparkDefSteps,
|
||||
kEobBaseSparkDefSubSteps,
|
||||
kEobBaseSparkDefShift,
|
||||
kEobBaseSparkDefAdd,
|
||||
kEobBaseSparkDefX,
|
||||
kEobBaseSparkDefY,
|
||||
kEobBaseSparkOfFlags1,
|
||||
kEobBaseSparkOfFlags2,
|
||||
kEobBaseSparkOfShift,
|
||||
kEobBaseSparkOfX,
|
||||
kEobBaseSparkOfY,
|
||||
|
||||
kEobBaseSpellProperties,
|
||||
kEobBaseMagicFlightProps,
|
||||
|
||||
kEob1MainMenuStrings,
|
||||
kEob1DoorShapeDefs,
|
||||
kEob1DoorSwitchShapeDefs,
|
||||
kEob1DoorSwitchCoords,
|
||||
kEob1MonsterProperties,
|
||||
|
||||
kEob1MonsterDistAttType10,
|
||||
kEob1MonsterDistAttSfx10,
|
||||
kEob1MonsterDistAttType17,
|
||||
kEob1MonsterDistAttSfx17,
|
||||
|
||||
kEob2MainMenuStrings,
|
||||
kEob2IntroStrings,
|
||||
kEob2IntroCPSFiles,
|
||||
kEob2IntroSeqData00,
|
||||
kEob2IntroSeqData01,
|
||||
kEob2IntroSeqData02,
|
||||
kEob2IntroSeqData03,
|
||||
kEob2IntroSeqData04,
|
||||
kEob2IntroSeqData05,
|
||||
kEob2IntroSeqData06,
|
||||
kEob2IntroSeqData07,
|
||||
kEob2IntroSeqData08,
|
||||
kEob2IntroSeqData09,
|
||||
kEob2IntroSeqData10,
|
||||
kEob2IntroSeqData11,
|
||||
kEob2IntroSeqData12,
|
||||
kEob2IntroSeqData13,
|
||||
kEob2IntroSeqData14,
|
||||
kEob2IntroSeqData15,
|
||||
kEob2IntroSeqData16,
|
||||
kEob2IntroSeqData17,
|
||||
kEob2IntroSeqData18,
|
||||
kEob2IntroSeqData19,
|
||||
kEob2IntroSeqData20,
|
||||
kEob2IntroSeqData21,
|
||||
kEob2IntroSeqData22,
|
||||
kEob2IntroSeqData23,
|
||||
kEob2IntroSeqData24,
|
||||
kEob2IntroSeqData25,
|
||||
kEob2IntroSeqData26,
|
||||
kEob2IntroSeqData27,
|
||||
kEob2IntroSeqData28,
|
||||
kEob2IntroSeqData29,
|
||||
kEob2IntroSeqData30,
|
||||
kEob2IntroSeqData31,
|
||||
kEob2IntroSeqData32,
|
||||
kEob2IntroSeqData33,
|
||||
kEob2IntroSeqData34,
|
||||
kEob2IntroSeqData35,
|
||||
kEob2IntroSeqData36,
|
||||
kEob2IntroSeqData37,
|
||||
kEob2IntroSeqData38,
|
||||
kEob2IntroSeqData39,
|
||||
kEob2IntroSeqData40,
|
||||
kEob2IntroSeqData41,
|
||||
kEob2IntroSeqData42,
|
||||
kEob2IntroSeqData43,
|
||||
kEob2IntroShapes00,
|
||||
kEob2IntroShapes01,
|
||||
kEob2IntroShapes04,
|
||||
kEob2IntroShapes07,
|
||||
|
||||
kEob2FinaleStrings,
|
||||
kEob2CreditsData,
|
||||
kEob2FinaleCPSFiles,
|
||||
kEob2FinaleSeqData00,
|
||||
kEob2FinaleSeqData01,
|
||||
kEob2FinaleSeqData02,
|
||||
kEob2FinaleSeqData03,
|
||||
kEob2FinaleSeqData04,
|
||||
kEob2FinaleSeqData05,
|
||||
kEob2FinaleSeqData06,
|
||||
kEob2FinaleSeqData07,
|
||||
kEob2FinaleSeqData08,
|
||||
kEob2FinaleSeqData09,
|
||||
kEob2FinaleSeqData10,
|
||||
kEob2FinaleSeqData11,
|
||||
kEob2FinaleSeqData12,
|
||||
kEob2FinaleSeqData13,
|
||||
kEob2FinaleSeqData14,
|
||||
kEob2FinaleSeqData15,
|
||||
kEob2FinaleSeqData16,
|
||||
kEob2FinaleSeqData17,
|
||||
kEob2FinaleSeqData18,
|
||||
kEob2FinaleSeqData19,
|
||||
kEob2FinaleSeqData20,
|
||||
kEob2FinaleShapes00,
|
||||
kEob2FinaleShapes03,
|
||||
kEob2FinaleShapes07,
|
||||
kEob2FinaleShapes09,
|
||||
kEob2FinaleShapes10,
|
||||
|
||||
kEob2NpcShapeData,
|
||||
kEob2Npc1Strings,
|
||||
kEob2Npc2Strings,
|
||||
kEob2MonsterDustStrings,
|
||||
|
||||
kLolIngamePakFiles,
|
||||
kLolCharacterDefs,
|
||||
kLolIngameSfxFiles,
|
||||
@ -284,27 +542,17 @@ enum KyraResources {
|
||||
kLolItemPrices,
|
||||
kLolStashSetup,
|
||||
|
||||
kLolDscUnk1,
|
||||
kLolDscShapeIndex,
|
||||
kLolDscWalls,
|
||||
kLolDscOvlMap,
|
||||
kLolDscScaleWidthData,
|
||||
kLolDscScaleHeightData,
|
||||
kLolDscX,
|
||||
kLolDscY,
|
||||
kLolDscTileIndex,
|
||||
kLolDscUnk2,
|
||||
kLolDscDoorShapeIndex,
|
||||
kLolDscDimData1,
|
||||
kLolDscDimData2,
|
||||
kLolDscBlockMap,
|
||||
kLolDscDimMap,
|
||||
kLolDscDoor1,
|
||||
kLolBaseDscY,
|
||||
|
||||
kLolDscDoorScale,
|
||||
kLolDscDoor4,
|
||||
kLolDscDoorX,
|
||||
kLolDscDoorY,
|
||||
kLolDscOvlIndex,
|
||||
kLolDscBlockIndex,
|
||||
|
||||
kLolScrollXTop,
|
||||
kLolScrollYTop,
|
||||
@ -334,7 +582,7 @@ enum KyraResources {
|
||||
kLolCredits,
|
||||
|
||||
kLolHistory,
|
||||
#endif
|
||||
#endif // ENABLE_EOB || ENABLE_LOL
|
||||
|
||||
kMaxResIDs
|
||||
};
|
||||
@ -363,15 +611,22 @@ public:
|
||||
const HofSeqData *loadHofSequenceData(int id, int &entries);
|
||||
const ItemAnimData_v1 *loadShapeAnimData_v1(int id, int &entries);
|
||||
const ItemAnimData_v2 *loadShapeAnimData_v2(int id, int &entries);
|
||||
#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
|
||||
const uint16 *loadRawDataBe16(int id, int &entries);
|
||||
const uint32 *loadRawDataBe32(int id, int &entries);
|
||||
#endif // (ENABLE_EOB || ENABLE_LOL)
|
||||
#ifdef ENABLE_LOL
|
||||
const LoLCharacter *loadCharData(int id, int &entries);
|
||||
const SpellProperty *loadSpellData(int id, int &entries);
|
||||
const CompassDef *loadCompassData(int id, int &entries);
|
||||
const FlyingObjectShape *loadFlyingObjectData(int id, int &entries);
|
||||
const uint16 *loadRawDataBe16(int id, int &entries);
|
||||
const uint32 *loadRawDataBe32(int id, int &entries);
|
||||
const ButtonDef *loadButtonDefs(int id, int &entries);
|
||||
const LoLButtonDef *loadButtonDefs(int id, int &entries);
|
||||
#endif // ENABLE_LOL
|
||||
#ifdef ENABLE_EOB
|
||||
const EobSequenceStep *loadEob2SeqData(int id, int &entries);
|
||||
const EobShapeDef *loadEob2ShapeData(int id, int &entries);
|
||||
const EobCharacter *loadEobNpcData(int id, int &entries);
|
||||
#endif // ENABLE_EOB
|
||||
|
||||
// use '-1' to prefetch/unload all ids
|
||||
// prefetchId retruns false if only on of the resources
|
||||
@ -398,15 +653,22 @@ private:
|
||||
bool loadHofSequenceData(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
bool loadShapeAnimData_v1(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
bool loadShapeAnimData_v2(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
|
||||
bool loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
bool loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
#endif // (ENABLE_LOL || ENABLE_EOB)
|
||||
#ifdef ENABLE_LOL
|
||||
bool loadCharData(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
bool loadSpellData(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
bool loadCompassData(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
bool loadFlyingObjectData(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
bool loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
bool loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
bool loadButtonDefs(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
#endif // ENABLE_LOL
|
||||
#ifdef ENABLE_EOB
|
||||
bool loadEob2SeqData(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
bool loadEob2ShapeData(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
bool loadEobNpcData(Common::SeekableReadStream &stream, void *&ptr, int &size);
|
||||
#endif // ENABLE_EOB
|
||||
|
||||
void freeRawData(void *&ptr, int &size);
|
||||
void freeStringTable(void *&ptr, int &size);
|
||||
@ -416,15 +678,22 @@ private:
|
||||
void freeHofSequenceData(void *&ptr, int &size);
|
||||
void freeHofShapeAnimDataV1(void *&ptr, int &size);
|
||||
void freeHofShapeAnimDataV2(void *&ptr, int &size);
|
||||
#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
|
||||
void freeRawDataBe16(void *&ptr, int &size);
|
||||
void freeRawDataBe32(void *&ptr, int &size);
|
||||
#endif // (ENABLE_EOB || ENABLE_LOL)
|
||||
#ifdef ENABLE_LOL
|
||||
void freeCharData(void *&ptr, int &size);
|
||||
void freeSpellData(void *&ptr, int &size);
|
||||
void freeCompassData(void *&ptr, int &size);
|
||||
void freeFlyingObjectData(void *&ptr, int &size);
|
||||
void freeRawDataBe16(void *&ptr, int &size);
|
||||
void freeRawDataBe32(void *&ptr, int &size);
|
||||
void freeButtonDefs(void *&ptr, int &size);
|
||||
#endif // ENABLE_LOL
|
||||
#ifdef ENABLE_EOB
|
||||
void freeEob2SeqData(void *&ptr, int &size);
|
||||
void freeEob2ShapeData(void *&ptr, int &size);
|
||||
void freeEobNpcData(void *&ptr, int &size);
|
||||
#endif // ENABLE_EOB
|
||||
|
||||
enum ResTypes {
|
||||
kStringList = 0,
|
||||
@ -443,7 +712,11 @@ private:
|
||||
kLolFlightShpData = 11,
|
||||
kLolButtonData = 12,
|
||||
kLolRawDataBe16 = 13,
|
||||
kLolRawDataBe32 = 14
|
||||
kLolRawDataBe32 = 14,
|
||||
|
||||
kEob2SequenceData = 15,
|
||||
kEob2ShapeData = 16,
|
||||
kEobNpcData = 17
|
||||
};
|
||||
|
||||
struct FileType {
|
||||
|
@ -254,6 +254,8 @@ bool ResLoaderPak::isLoadable(const Common::String &filename, Common::SeekableRe
|
||||
offset = SWAP_BYTES_32(offset);
|
||||
}
|
||||
|
||||
int32 firstOffset = offset;
|
||||
|
||||
Common::String file;
|
||||
while (!stream.eos()) {
|
||||
// The start offset of a file should never be in the filelist
|
||||
@ -276,7 +278,7 @@ bool ResLoaderPak::isLoadable(const Common::String &filename, Common::SeekableRe
|
||||
firstFile = false;
|
||||
offset = switchEndian ? stream.readUint32BE() : stream.readUint32LE();
|
||||
|
||||
if (!offset || offset == filesize)
|
||||
if (!offset || offset == filesize || firstOffset == stream.pos())
|
||||
break;
|
||||
}
|
||||
|
||||
@ -297,6 +299,7 @@ Common::Archive *ResLoaderPak::load(Common::ArchiveMemberPtr memberFile, Common:
|
||||
bool firstFile = true;
|
||||
|
||||
startoffset = stream.readUint32LE();
|
||||
int32 firstOffset = startoffset;
|
||||
if (startoffset > filesize || startoffset < 0) {
|
||||
switchEndian = true;
|
||||
startoffset = SWAP_BYTES_32(startoffset);
|
||||
@ -330,12 +333,12 @@ Common::Archive *ResLoaderPak::load(Common::ArchiveMemberPtr memberFile, Common:
|
||||
firstFile = false;
|
||||
endoffset = switchEndian ? stream.readUint32BE() : stream.readUint32LE();
|
||||
|
||||
if (endoffset < 0) {
|
||||
if (endoffset < 0 && stream.pos() != firstOffset) {
|
||||
warning("PAK file '%s' is corrupted", memberFile->getDisplayName().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!endoffset)
|
||||
if (!endoffset || stream.pos() == firstOffset)
|
||||
endoffset = filesize;
|
||||
|
||||
if (startoffset != endoffset)
|
||||
@ -493,7 +496,7 @@ public:
|
||||
void advSrcBitsBy1();
|
||||
void advSrcBitsByIndex(uint8 newIndex);
|
||||
|
||||
uint8 getKeyLower() { return _key & 0xff; }
|
||||
uint8 getKeyLower() const { return _key & 0xff; }
|
||||
void setIndex(uint8 index) { _index = index; }
|
||||
uint16 getKeyMasked(uint8 newIndex);
|
||||
uint16 keyMaskedAlign(uint16 val);
|
||||
|
549
engines/kyra/saveload_eob.cpp
Normal file
549
engines/kyra/saveload_eob.cpp
Normal file
@ -0,0 +1,549 @@
|
||||
/* 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/eobcommon.h"
|
||||
#include "kyra/resource.h"
|
||||
#include "kyra/script_eob.h"
|
||||
|
||||
#include "common/system.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/substream.h"
|
||||
|
||||
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]);
|
||||
delete _lvlTempData[l];
|
||||
}
|
||||
|
||||
_lvlTempData[l] = new LevelTempData;
|
||||
|
||||
_lvlTempData[l]->wallsXorData = new uint8[4096];
|
||||
_lvlTempData[l]->flags = new uint16[1024];
|
||||
|
||||
char filename[13];
|
||||
const uint8 *p = 0;
|
||||
const uint8 *p2 = 0;
|
||||
if (_flags.gameID == GI_LOL) {
|
||||
snprintf(filename, sizeof(filename), "LEVEL%d.CMZ", _currentLevel);
|
||||
screen()->loadBitmap(filename, 15, 15, 0);
|
||||
p = screen()->getCPagePtr(14);
|
||||
} else {
|
||||
snprintf(filename, sizeof(filename), "LEVEL%d.MAZ", _currentLevel);
|
||||
p2 = p = _res->fileData(filename, 0);
|
||||
}
|
||||
|
||||
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]);
|
||||
|
||||
_hasTempDataFlags |= (1 << l);
|
||||
delete[] p2;
|
||||
}
|
||||
|
||||
void LolEobBaseEngine::restoreBlockTempData(int levelIndex) {
|
||||
int l = levelIndex - 1;
|
||||
char filename[13];
|
||||
const uint8 *p = 0;
|
||||
const uint8 *p2 = 0;
|
||||
if (_flags.gameID == GI_LOL) {
|
||||
snprintf(filename, sizeof(filename), "LEVEL%d.CMZ", levelIndex);
|
||||
screen()->loadBitmap(filename, 3, 3, 0);
|
||||
p = screen()->getCPagePtr(2);
|
||||
} else {
|
||||
snprintf(filename, sizeof(filename), "LEVEL%d.MAZ", levelIndex);
|
||||
p2 = p = _res->fileData(filename, 0);
|
||||
}
|
||||
|
||||
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]);
|
||||
|
||||
delete[] p2;
|
||||
}
|
||||
|
||||
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]);
|
||||
delete _lvlTempData[i];
|
||||
_lvlTempData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
Common::Error EobCoreEngine::loadGameState(int slot) {
|
||||
const char *fileName = getSavegameFilename(slot);
|
||||
|
||||
SaveHeader header;
|
||||
Common::InSaveFile *saveFile = openSaveForReading(fileName, header);
|
||||
if (!saveFile) {
|
||||
//_txt->printMessage(2, "%s", getLangString(0x425d));
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
EobCharacter *c = &_characters[i];
|
||||
c->id = in.readByte();
|
||||
c->flags = in.readByte();
|
||||
in.read(c->name, 11);
|
||||
c->strengthCur = in.readSByte();
|
||||
c->strengthMax = in.readSByte();
|
||||
c->strengthExtCur = in.readSByte();
|
||||
c->strengthExtMax = in.readSByte();
|
||||
c->intelligenceCur = in.readSByte();
|
||||
c->intelligenceMax = in.readSByte();
|
||||
c->wisdomCur = in.readSByte();
|
||||
c->wisdomMax = in.readSByte();
|
||||
c->dexterityCur = in.readSByte();
|
||||
c->dexterityMax = in.readSByte();
|
||||
c->constitutionCur = in.readSByte();
|
||||
c->constitutionMax = in.readSByte();
|
||||
c->charismaCur = in.readSByte();
|
||||
c->charismaMax = in.readSByte();
|
||||
c->hitPointsCur = in.readSint16BE();
|
||||
c->hitPointsMax = in.readSint16BE();
|
||||
c->armorClass = in.readSByte();
|
||||
c->disabledSlots = in.readByte();
|
||||
c->raceSex = in.readByte();
|
||||
c->cClass = in.readByte();
|
||||
c->alignment = in.readByte();
|
||||
c->portrait = in.readSByte();
|
||||
c->food = in.readByte();
|
||||
in.read(c->level, 3);
|
||||
for (int ii = 0; ii < 3; ii++)
|
||||
c->experience[ii] = in.readUint32BE();
|
||||
delete[] c->faceShape;
|
||||
c->faceShape = 0;
|
||||
in.read(c->mageSpells, 80);
|
||||
in.read(c->clericSpells, 80);
|
||||
c->mageSpellsAvailabilityFlags = in.readUint32BE();
|
||||
for (int ii = 0; ii < 27; ii++)
|
||||
c->inventory[ii] = in.readSint16BE();
|
||||
uint32 ct = _system->getMillis();
|
||||
for (int ii = 0; ii < 10; ii++) {
|
||||
c->timers[ii] = in.readUint32BE();
|
||||
if (c->timers[ii])
|
||||
c->timers[ii] += ct;
|
||||
}
|
||||
in.read(c->events, 10);
|
||||
in.read(c->effectsRemainder, 4);
|
||||
c->effectFlags = in.readUint32BE();
|
||||
c->damageTaken = in.readByte();
|
||||
in.read(c->slotStatus, 5);
|
||||
}
|
||||
|
||||
setupCharacterTimers();
|
||||
|
||||
_screen->loadEobBitmap("CHARGENA", 3, 3);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
EobCharacter *c = &_characters[i];
|
||||
if (!c->flags || c->portrait < 0)
|
||||
continue;
|
||||
c->faceShape = _screen->encodeShape((c->portrait % 10) << 2, (c->portrait / 10) << 5, 4, 32, true);
|
||||
}
|
||||
|
||||
_screen->loadEobBitmap(_flags.gameID == GI_EOB2 ? "OUTPORTS" : "OUTTAKE", 3, 3);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
EobCharacter *c = &_characters[i];
|
||||
if (!c->flags || c->portrait >= 0)
|
||||
continue;
|
||||
c->faceShape = _screen->encodeShape(-(c->portrait + 1), _flags.gameID == GI_EOB2 ? 0 : 160, 4, 32, true);
|
||||
}
|
||||
_screen->_curPage = 0;
|
||||
|
||||
_currentLevel = in.readByte();
|
||||
_currentSub = in.readSByte();
|
||||
_currentBlock = in.readUint16BE();
|
||||
_currentDirection = in.readUint16BE();
|
||||
_itemInHand = in.readSint16BE();
|
||||
_hasTempDataFlags = in.readUint32BE();
|
||||
_partyEffectFlags = in.readUint32BE();
|
||||
_inf->loadState(in);
|
||||
|
||||
for (int i = 0; i < 600; i++) {
|
||||
EobItem *t = &_items[i];
|
||||
t->nameUnid = in.readByte();
|
||||
t->nameId = in.readByte();
|
||||
t->flags = in.readByte();
|
||||
t->icon = in.readSByte();
|
||||
t->type = in.readSByte();
|
||||
t->pos = in.readSByte();
|
||||
t->block = in.readSint16BE();
|
||||
t->next = in.readSint16BE();
|
||||
t->prev = in.readSint16BE();
|
||||
t->level = in.readByte();
|
||||
t->value = in.readSByte();
|
||||
}
|
||||
|
||||
for (int i = 51; i < 65; i++) {
|
||||
EobItemType *t = &_itemTypes[i];
|
||||
t->invFlags = in.readUint16BE();
|
||||
t->handFlags = in.readUint16BE();
|
||||
t->armorClass = in.readSByte();
|
||||
t->allowedClasses = in.readSByte();
|
||||
t->requiredHands = in.readSByte();
|
||||
t->dmgNumDiceS = in.readSByte();
|
||||
t->dmgNumPipsS = in.readSByte();
|
||||
t->dmgIncS = in.readSByte();
|
||||
t->dmgNumDiceL = in.readSByte();
|
||||
t->dmgNumPipsL = in.readSByte();
|
||||
t->dmgIncL = in.readSByte();
|
||||
t->unk1 = in.readByte();
|
||||
t->extraProperties = in.readUint16BE();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 18; i++) {
|
||||
if (!(_hasTempDataFlags & (1 << i)))
|
||||
continue;
|
||||
|
||||
if (_lvlTempData[i]) {
|
||||
delete[] _lvlTempData[i]->wallsXorData;
|
||||
delete[] _lvlTempData[i]->flags;
|
||||
releaseMonsterTempData(_lvlTempData[i]);
|
||||
releaseFlyingObjectTempData(_lvlTempData[i]);
|
||||
delete _lvlTempData[i];
|
||||
}
|
||||
|
||||
_lvlTempData[i] = new LevelTempData;
|
||||
_lvlTempData[i]->wallsXorData = new uint8[4096];
|
||||
_lvlTempData[i]->flags = new uint16[1024];
|
||||
EobMonsterInPlay *lm = new EobMonsterInPlay[30];
|
||||
_lvlTempData[i]->monsters = lm;
|
||||
EobFlyingObject *lf = new EobFlyingObject[10];
|
||||
_lvlTempData[i]->flyingObjects = lf;
|
||||
LevelTempData *l = _lvlTempData[i];
|
||||
|
||||
in.read(l->wallsXorData, 4096);
|
||||
for (int ii = 0; ii < 1024; ii++)
|
||||
l->flags[ii] = in.readByte();
|
||||
|
||||
for (int ii = 0; ii < 30; ii++) {
|
||||
EobMonsterInPlay *m = &lm[ii];
|
||||
m->type = in.readByte();
|
||||
m->unit = in.readByte();
|
||||
m->block = in.readUint16BE();
|
||||
m->pos = in.readByte();
|
||||
m->dir = in.readSByte();
|
||||
m->animStep = in.readByte();
|
||||
m->shpIndex = in.readByte();
|
||||
m->mode = in.readSByte();
|
||||
m->f_9 = in.readSByte();
|
||||
m->curAttackFrame = in.readSByte();
|
||||
m->f_b = in.readByte();
|
||||
m->hitPointsMax = in.readSint16BE();
|
||||
m->hitPointsCur = in.readSint16BE();
|
||||
m->dest = in.readUint16BE();
|
||||
m->randItem = in.readUint16BE();
|
||||
m->fixedItem = in.readUint16BE();
|
||||
m->flags = in.readByte();
|
||||
m->idleAnimState = in.readByte();
|
||||
m->curRemoteWeapon = in.readByte();
|
||||
m->numRemoteAttacks = in.readByte();
|
||||
m->palette = in.readSByte();
|
||||
m->directionChanged = in.readByte();
|
||||
m->stepsTillRemoteAttack = in.readByte();
|
||||
m->sub = in.readByte();
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < 10; ii++) {
|
||||
EobFlyingObject *m = &lf[ii];
|
||||
m->enable = in.readByte();
|
||||
m->objectType = in.readByte();
|
||||
m->attackerId = in.readSint16BE();
|
||||
m->item = in.readSint16BE();
|
||||
m->curBlock = in.readUint16BE();
|
||||
m->u2 = in.readUint16BE();
|
||||
m->u1 = in.readByte();
|
||||
m->direction = in.readByte();
|
||||
m->distance = in.readByte();
|
||||
m->callBackIndex = in.readSByte();
|
||||
m->curPos = in.readByte();
|
||||
m->flags = in.readByte();
|
||||
m->unused = in.readByte();
|
||||
}
|
||||
}
|
||||
|
||||
if (_saveLoadMode != -1) {
|
||||
loadLevel(_currentLevel, _currentSub);
|
||||
gui_drawPlayField(0);
|
||||
_sceneUpdateRequired = true;
|
||||
_screen->setCurPage(0);
|
||||
_screen->setFont(Screen::FID_6_FNT);
|
||||
gui_drawAllCharPortraitsWithStats();
|
||||
updateHandItemCursor();
|
||||
_saveLoadMode = 1;
|
||||
}
|
||||
|
||||
while (!_screen->isMouseVisible())
|
||||
_screen->showMouse();
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) {
|
||||
const Common::String finSuffix(".FIN");
|
||||
const char *fileName = (slot != -1) ? getSavegameFilename(slot) : (_targetName + finSuffix).c_str();
|
||||
|
||||
Common::OutSaveFile *out = openSaveForWriting(fileName, saveName, thumbnail);
|
||||
if (!out)
|
||||
return _saveFileMan->getError();
|
||||
|
||||
completeDoorOperations();
|
||||
generateTempData();
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
timerSpecialCharacterUpdate(0x30 + i);
|
||||
uint32 ct = _system->getMillis();
|
||||
EobCharacter *c = &_characters[i];
|
||||
|
||||
out->writeByte(c->id);
|
||||
out->writeByte(c->flags);
|
||||
out->write(c->name, 11);
|
||||
out->writeSByte(c->strengthCur);
|
||||
out->writeSByte(c->strengthMax);
|
||||
out->writeSByte(c->strengthExtCur);
|
||||
out->writeSByte(c->strengthExtMax);
|
||||
out->writeSByte(c->intelligenceCur);
|
||||
out->writeSByte(c->intelligenceMax);
|
||||
out->writeSByte(c->wisdomCur);
|
||||
out->writeSByte(c->wisdomMax);
|
||||
out->writeSByte(c->dexterityCur);
|
||||
out->writeSByte(c->dexterityMax);
|
||||
out->writeSByte(c->constitutionCur);
|
||||
out->writeSByte(c->constitutionMax);
|
||||
out->writeSByte(c->charismaCur);
|
||||
out->writeSByte(c->charismaMax);
|
||||
out->writeSint16BE(c->hitPointsCur);
|
||||
out->writeSint16BE(c->hitPointsMax);
|
||||
out->writeSByte(c->armorClass);
|
||||
out->writeByte(c->disabledSlots);
|
||||
out->writeByte(c->raceSex);
|
||||
out->writeByte(c->cClass);
|
||||
out->writeByte(c->alignment);
|
||||
out->writeByte(c->portrait);
|
||||
out->writeByte(c->food);
|
||||
out->write(c->level, 3);
|
||||
for (int ii = 0; ii < 3; ii++)
|
||||
out->writeUint32BE(c->experience[ii]);
|
||||
out->write(c->mageSpells, 80);
|
||||
out->write(c->clericSpells, 80);
|
||||
out->writeUint32BE(c->mageSpellsAvailabilityFlags);
|
||||
for (int ii = 0; ii < 27; ii++)
|
||||
out->writeSint16BE(c->inventory[ii]);
|
||||
for (int ii = 0; ii < 10; ii++)
|
||||
out->writeUint32BE(c->timers[ii] ? c->timers[ii] - ct : 0);
|
||||
|
||||
out->write(c->events, 10);
|
||||
out->write(c->effectsRemainder, 4);
|
||||
out->writeUint32BE(c->effectFlags);
|
||||
out->writeByte(c->damageTaken);
|
||||
out->write(c->slotStatus, 5);
|
||||
}
|
||||
|
||||
out->writeByte(_currentLevel);
|
||||
out->writeSByte(_currentSub);
|
||||
out->writeUint16BE(_currentBlock);
|
||||
out->writeUint16BE(_currentDirection);
|
||||
out->writeSint16BE(_itemInHand);
|
||||
out->writeUint32BE(_hasTempDataFlags);
|
||||
out->writeUint32BE(_partyEffectFlags);
|
||||
_inf->saveState(out);
|
||||
|
||||
for (int i = 0; i < 600; i++) {
|
||||
EobItem *t = &_items[i];
|
||||
out->writeByte(t->nameUnid);
|
||||
out->writeByte(t->nameId);
|
||||
out->writeByte(t->flags);
|
||||
out->writeSByte(t->icon);
|
||||
out->writeSByte(t->type);
|
||||
out->writeSByte(t->pos);
|
||||
out->writeSint16BE(t->block);
|
||||
out->writeSint16BE(t->next);
|
||||
out->writeSint16BE(t->prev);
|
||||
out->writeByte(t->level);
|
||||
out->writeSByte(t->value);
|
||||
}
|
||||
|
||||
for (int i = 51; i < 65; i++) {
|
||||
EobItemType *t = &_itemTypes[i];
|
||||
out->writeUint16BE(t->invFlags);
|
||||
out->writeUint16BE(t->handFlags);
|
||||
out->writeSByte(t->armorClass);
|
||||
out->writeSByte(t->allowedClasses);
|
||||
out->writeSByte(t->requiredHands);
|
||||
out->writeSByte(t->dmgNumDiceS);
|
||||
out->writeSByte(t->dmgNumPipsS);
|
||||
out->writeSByte(t->dmgIncS);
|
||||
out->writeSByte(t->dmgNumDiceL);
|
||||
out->writeSByte(t->dmgNumPipsL);
|
||||
out->writeSByte(t->dmgIncL);
|
||||
out->writeByte(t->unk1);
|
||||
out->writeUint16BE(t->extraProperties);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 18; i++) {
|
||||
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);
|
||||
|
||||
EobMonsterInPlay *lm = (EobMonsterInPlay*)_lvlTempData[i]->monsters;
|
||||
EobFlyingObject *lf = (EobFlyingObject*)_lvlTempData[i]->flyingObjects;
|
||||
|
||||
for (int ii = 0; ii < 30; ii++) {
|
||||
EobMonsterInPlay *m = &lm[ii];
|
||||
out->writeByte(m->type);
|
||||
out->writeByte(m->unit);
|
||||
out->writeUint16BE(m->block);
|
||||
out->writeByte(m->pos);
|
||||
out->writeSByte(m->dir);
|
||||
out->writeByte(m->animStep);
|
||||
out->writeByte(m->shpIndex);
|
||||
out->writeSByte(m->mode);
|
||||
out->writeSByte(m->f_9);
|
||||
out->writeSByte(m->curAttackFrame);
|
||||
out->writeByte(m->f_b);
|
||||
out->writeSint16BE(m->hitPointsMax);
|
||||
out->writeSint16BE(m->hitPointsCur);
|
||||
out->writeUint16BE(m->dest);
|
||||
out->writeUint16BE(m->randItem);
|
||||
out->writeUint16BE(m->fixedItem);
|
||||
out->writeByte(m->flags);
|
||||
out->writeByte(m->idleAnimState);
|
||||
out->writeByte(m->curRemoteWeapon);
|
||||
out->writeByte(m->numRemoteAttacks);
|
||||
out->writeSByte(m->palette);
|
||||
out->writeByte(m->directionChanged);
|
||||
out->writeByte(m->stepsTillRemoteAttack);
|
||||
out->writeByte(m->sub);
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < 10; ii++) {
|
||||
EobFlyingObject *m = &lf[ii];
|
||||
out->writeByte(m->enable);
|
||||
out->writeByte(m->objectType);
|
||||
out->writeSint16BE(m->attackerId);
|
||||
out->writeSint16BE(m->item);
|
||||
out->writeUint16BE(m->curBlock);
|
||||
out->writeUint16BE(m->u2);
|
||||
out->writeByte(m->u1);
|
||||
out->writeByte(m->direction);
|
||||
out->writeByte(m->distance);
|
||||
out->writeSByte(m->callBackIndex);
|
||||
out->writeByte(m->curPos);
|
||||
out->writeByte(m->flags);
|
||||
out->writeByte(m->unused);
|
||||
}
|
||||
}
|
||||
|
||||
out->finalize();
|
||||
|
||||
// check for errors
|
||||
if (out->err()) {
|
||||
warning("Can't write file '%s'. (Disk full?)", fileName);
|
||||
return Common::kUnknownError;
|
||||
} else {
|
||||
debugC(1, kDebugLevelMain, "Saved game '%s.'", saveName);
|
||||
}
|
||||
|
||||
delete out;
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
void *EobCoreEngine::generateMonsterTempData(LevelTempData *tmp) {
|
||||
EobMonsterInPlay *m = new EobMonsterInPlay[30];
|
||||
memcpy(m, _monsters, sizeof(EobMonsterInPlay) * 30);
|
||||
return m;
|
||||
}
|
||||
|
||||
void *EobCoreEngine::generateFlyingObjectTempData(LevelTempData *tmp) {
|
||||
EobFlyingObject *f = new EobFlyingObject[10];
|
||||
memcpy(f, _flyingObjects, sizeof(EobFlyingObject) * 10);
|
||||
return f;
|
||||
}
|
||||
|
||||
void EobCoreEngine::restoreMonsterTempData(LevelTempData *tmp) {
|
||||
memcpy(_monsters, tmp->monsters, sizeof(EobMonsterInPlay) * 30);
|
||||
}
|
||||
|
||||
void EobCoreEngine::restoreFlyingObjectTempData(LevelTempData *tmp) {
|
||||
memcpy(_flyingObjects, tmp->flyingObjects, sizeof(EobFlyingObject) * 10);
|
||||
}
|
||||
|
||||
void EobCoreEngine::releaseMonsterTempData(LevelTempData *tmp) {
|
||||
EobMonsterInPlay *p = (EobMonsterInPlay*)tmp->monsters;
|
||||
delete[] p;
|
||||
}
|
||||
|
||||
void EobCoreEngine::releaseFlyingObjectTempData(LevelTempData *tmp) {
|
||||
|
||||
}
|
||||
|
||||
#endif // ENABLE_EOB
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB || ENABLE_LOL
|
@ -96,7 +96,7 @@ Common::Error LoLEngine::loadGameState(int slot) {
|
||||
}
|
||||
}
|
||||
|
||||
in.read(_wllBuffer4, 80);
|
||||
in.read(_wllAutomapData, 80);
|
||||
|
||||
_currentBlock = in.readUint16BE();
|
||||
_partyPosX = in.readUint16BE();
|
||||
@ -185,23 +185,26 @@ Common::Error LoLEngine::loadGameState(int slot) {
|
||||
if (_lvlTempData[i]) {
|
||||
delete[] _lvlTempData[i]->wallsXorData;
|
||||
delete[] _lvlTempData[i]->flags;
|
||||
delete[] _lvlTempData[i]->monsters;
|
||||
delete[] _lvlTempData[i]->flyingObjects;
|
||||
releaseMonsterTempData(_lvlTempData[i]);
|
||||
releaseFlyingObjectTempData(_lvlTempData[i]);
|
||||
delete _lvlTempData[i];
|
||||
}
|
||||
|
||||
_lvlTempData[i] = new LevelTempData;
|
||||
_lvlTempData[i]->wallsXorData = new uint8[4096];
|
||||
_lvlTempData[i]->flags = new uint8[1024];
|
||||
_lvlTempData[i]->monsters = new MonsterInPlay[30];
|
||||
_lvlTempData[i]->flyingObjects = new FlyingObject[8];
|
||||
_lvlTempData[i]->flags = new uint16[1024];
|
||||
LolMonsterInPlay *lm = new LolMonsterInPlay[30];
|
||||
_lvlTempData[i]->monsters = lm;
|
||||
FlyingObject *lf = new FlyingObject[8];
|
||||
_lvlTempData[i]->flyingObjects = lf;
|
||||
LevelTempData *l = _lvlTempData[i];
|
||||
|
||||
in.read(l->wallsXorData, 4096);
|
||||
in.read(l->flags, 1024);
|
||||
for (int ii = 0; ii < 1024; ii++)
|
||||
l->flags[ii] = in.readByte();
|
||||
|
||||
for (int ii = 0; ii < 30; ii++) {
|
||||
MonsterInPlay *m = &l->monsters[ii];
|
||||
LolMonsterInPlay *m = &lm[ii];
|
||||
m->nextAssignedObject = in.readUint16BE();
|
||||
m->nextDrawObject = in.readUint16BE();
|
||||
m->flyingHeight = in.readByte();
|
||||
@ -234,7 +237,7 @@ Common::Error LoLEngine::loadGameState(int slot) {
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < 8; ii++) {
|
||||
FlyingObject *m = &l->flyingObjects[ii];
|
||||
FlyingObject *m = &lf[ii];
|
||||
m->enable = in.readByte();
|
||||
m->objectType = in.readByte();
|
||||
m->attackerId = in.readUint16BE();
|
||||
@ -319,7 +322,7 @@ Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, con
|
||||
out->writeByte(c->characterUpdateDelay[ii]);
|
||||
}
|
||||
|
||||
out->write(_wllBuffer4, 80);
|
||||
out->write(_wllAutomapData, 80);
|
||||
|
||||
out->writeUint16BE(_currentBlock);
|
||||
out->writeUint16BE(_partyPosX);
|
||||
@ -379,10 +382,14 @@ Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, con
|
||||
continue;
|
||||
|
||||
out->write(l->wallsXorData, 4096);
|
||||
out->write(l->flags, 1024);
|
||||
for (int ii = 0; ii < 1024; ii++)
|
||||
out->writeByte(l->flags[ii] & 0xff);
|
||||
|
||||
LolMonsterInPlay *lm = (LolMonsterInPlay*)_lvlTempData[i]->monsters;
|
||||
FlyingObject *lf = (FlyingObject*)_lvlTempData[i]->flyingObjects;
|
||||
|
||||
for (int ii = 0; ii < 30; ii++) {
|
||||
MonsterInPlay *m = &l->monsters[ii];
|
||||
LolMonsterInPlay *m = &lm[ii];
|
||||
out->writeUint16BE(m->nextAssignedObject);
|
||||
out->writeUint16BE(m->nextDrawObject);
|
||||
out->writeByte(m->flyingHeight);
|
||||
@ -414,7 +421,7 @@ Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, con
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < 8; ii++) {
|
||||
FlyingObject *m = &l->flyingObjects[ii];
|
||||
FlyingObject *m = &lf[ii];
|
||||
out->writeByte(m->enable);
|
||||
out->writeByte(m->objectType);
|
||||
out->writeUint16BE(m->attackerId);
|
||||
@ -469,6 +476,69 @@ Graphics::Surface *LoLEngine::generateSaveThumbnail() const {
|
||||
return dst;
|
||||
}
|
||||
|
||||
void LoLEngine::restoreBlockTempData(int levelIndex) {
|
||||
memset(_tempBuffer5120, 0, 5120);
|
||||
LolEobBaseEngine::restoreBlockTempData(levelIndex);
|
||||
restoreTempDataAdjustMonsterStrength(levelIndex - 1);
|
||||
}
|
||||
|
||||
void *LoLEngine::generateMonsterTempData(LevelTempData *tmp) {
|
||||
LolMonsterInPlay *m = new LolMonsterInPlay[30];
|
||||
memcpy(m, _monsters, sizeof(LolMonsterInPlay) * 30);
|
||||
tmp->monsterDifficulty = _monsterDifficulty;
|
||||
return m;
|
||||
}
|
||||
|
||||
void *LoLEngine::generateFlyingObjectTempData(LevelTempData *tmp) {
|
||||
FlyingObject *f = new FlyingObject[8];
|
||||
memcpy(f, _flyingObjects, sizeof(FlyingObject) * 8);
|
||||
return f;
|
||||
}
|
||||
|
||||
void LoLEngine::restoreTempDataAdjustMonsterStrength(int index) {
|
||||
if (_lvlTempData[index]->monsterDifficulty == _monsterDifficulty)
|
||||
return;
|
||||
|
||||
uint16 d = (_monsterModifiers[_lvlTempData[index]->monsterDifficulty] << 8) / _monsterModifiers[_monsterDifficulty];
|
||||
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (_monsters[i].mode >= 14 || _monsters[i].block == 0 || _monsters[i].hitPoints <= 0)
|
||||
continue;
|
||||
|
||||
_monsters[i].hitPoints = (d * _monsters[i].hitPoints) >> 8;
|
||||
if (_monsterDifficulty < _lvlTempData[index]->monsterDifficulty)
|
||||
_monsters[i].hitPoints++;
|
||||
if (_monsters[i].hitPoints == 0)
|
||||
_monsters[i].hitPoints = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::restoreMonsterTempData(LevelTempData *tmp) {
|
||||
memcpy(_monsters, tmp->monsters, sizeof(LolMonsterInPlay) * 30);
|
||||
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (_monsters[i].block) {
|
||||
_monsters[i].block = 0;
|
||||
_monsters[i].properties = &_monsterProperties[_monsters[i].type];
|
||||
placeMonster(&_monsters[i], _monsters[i].x, _monsters[i].y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::restoreFlyingObjectTempData(LevelTempData *tmp) {
|
||||
memcpy(_flyingObjects, tmp->flyingObjects, sizeof(FlyingObject) * 8);
|
||||
}
|
||||
|
||||
void LoLEngine::releaseMonsterTempData(LevelTempData *tmp) {
|
||||
LolMonsterInPlay *p = (LolMonsterInPlay*)tmp->monsters;
|
||||
delete[] p;
|
||||
}
|
||||
|
||||
void LoLEngine::releaseFlyingObjectTempData(LevelTempData *tmp) {
|
||||
FlyingObject *p = (FlyingObject*)tmp->flyingObjects;
|
||||
delete[] p;
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_LOL
|
||||
|
1350
engines/kyra/scene_eob.cpp
Normal file
1350
engines/kyra/scene_eob.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -42,8 +42,8 @@ void LoLEngine::loadLevel(int index) {
|
||||
stopPortraitSpeechAnim();
|
||||
|
||||
for (int i = 0; i < 400; i++) {
|
||||
delete[] _levelShapes[i];
|
||||
_levelShapes[i] = 0;
|
||||
delete[] _levelDecorationShapes[i];
|
||||
_levelDecorationShapes[i] = 0;
|
||||
}
|
||||
_emc->unload(&_scriptData);
|
||||
|
||||
@ -160,7 +160,7 @@ void LoLEngine::loadLevelWallData(int index, bool mapShapes) {
|
||||
if (mapShapes) {
|
||||
int16 sh = (int16) READ_LE_UINT16(d);
|
||||
if (sh > 0)
|
||||
_wllShapeMap[c] = assignLevelShapes(sh);
|
||||
_wllShapeMap[c] = assignLevelDecorationShapes(sh);
|
||||
else
|
||||
_wllShapeMap[c] = *d;
|
||||
}
|
||||
@ -169,7 +169,7 @@ void LoLEngine::loadLevelWallData(int index, bool mapShapes) {
|
||||
d += 2;
|
||||
_wllWallFlags[c] = *d;
|
||||
d += 2;
|
||||
_wllBuffer4[c] = *d;
|
||||
_wllAutomapData[c] = *d;
|
||||
d += 2;
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ void LoLEngine::loadLevelWallData(int index, bool mapShapes) {
|
||||
_lvlShpFileHandle = 0;
|
||||
}
|
||||
|
||||
int LoLEngine::assignLevelShapes(int index) {
|
||||
int LoLEngine::assignLevelDecorationShapes(int index) {
|
||||
uint16 *p1 = (uint16 *)_tempBuffer5120;
|
||||
uint16 *p2 = (uint16 *)(_tempBuffer5120 + 4000);
|
||||
|
||||
@ -187,34 +187,34 @@ int LoLEngine::assignLevelShapes(int index) {
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
uint16 o = _lvlBlockIndex++;
|
||||
uint16 o = _mappedDecorationsCount++;
|
||||
|
||||
memcpy(&_levelShapeProperties[o], &_levelFileData[index], sizeof(LevelShapeProperty));
|
||||
memcpy(&_levelDecorationProperties[o], &_levelDecorationData[index], sizeof(LevelDecorationProperty));
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
uint16 t = _levelShapeProperties[o].shapeIndex[i];
|
||||
uint16 t = _levelDecorationProperties[o].shapeIndex[i];
|
||||
if (t == 0xffff)
|
||||
continue;
|
||||
|
||||
uint16 pv = p1[t];
|
||||
if (pv) {
|
||||
_levelShapeProperties[o].shapeIndex[i] = pv;
|
||||
_levelDecorationProperties[o].shapeIndex[i] = pv;
|
||||
} else {
|
||||
_levelShapes[_lvlShapeIndex] = getLevelShapes(t);
|
||||
_levelDecorationShapes[_lvlShapeIndex] = getLevelDecorationShapes(t);
|
||||
p1[t] = _lvlShapeIndex;
|
||||
_levelShapeProperties[o].shapeIndex[i] = _lvlShapeIndex++;
|
||||
_levelDecorationProperties[o].shapeIndex[i] = _lvlShapeIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
p2[index] = o;
|
||||
if (_levelShapeProperties[o].next)
|
||||
_levelShapeProperties[o].next = assignLevelShapes(_levelShapeProperties[o].next);
|
||||
if (_levelDecorationProperties[o].next)
|
||||
_levelDecorationProperties[o].next = assignLevelDecorationShapes(_levelDecorationProperties[o].next);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
uint8 *LoLEngine::getLevelShapes(int shapeIndex) {
|
||||
if (_lvlShpNum <= shapeIndex)
|
||||
uint8 *LoLEngine::getLevelDecorationShapes(int shapeIndex) {
|
||||
if (_decorationCount <= shapeIndex)
|
||||
return 0;
|
||||
|
||||
_lvlShpFileHandle->seek(shapeIndex * 4 + 2, SEEK_SET);
|
||||
@ -232,60 +232,6 @@ uint8 *LoLEngine::getLevelShapes(int shapeIndex) {
|
||||
return res;
|
||||
}
|
||||
|
||||
void LoLEngine::restoreBlockTempData(int index) {
|
||||
memset(_tempBuffer5120, 0, 5120);
|
||||
int l = index - 1;
|
||||
|
||||
memcpy(_monsters, _lvlTempData[l]->monsters, sizeof(MonsterInPlay) * 30);
|
||||
memcpy(_flyingObjects, _lvlTempData[l]->flyingObjects, sizeof(FlyingObject) * 8);
|
||||
|
||||
Common::String filename = Common::String::format("LEVEL%d.CMZ", index);
|
||||
|
||||
_screen->loadBitmap(filename.c_str(), 3, 3, 0);
|
||||
const uint8 *p = _screen->getCPagePtr(2);
|
||||
uint16 len = READ_LE_UINT16(p + 4);
|
||||
p += 6;
|
||||
|
||||
memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty));
|
||||
|
||||
uint8 *t = _lvlTempData[l]->wallsXorData;
|
||||
uint8 *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++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (_monsters[i].block) {
|
||||
_monsters[i].block = 0;
|
||||
_monsters[i].properties = &_monsterProperties[_monsters[i].type];
|
||||
placeMonster(&_monsters[i], _monsters[i].x, _monsters[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
restoreTempDataAdjustMonsterStrength(l);
|
||||
}
|
||||
|
||||
void LoLEngine::restoreTempDataAdjustMonsterStrength(int index) {
|
||||
if (_lvlTempData[index]->monsterDifficulty == _monsterDifficulty)
|
||||
return;
|
||||
|
||||
uint16 d = (_monsterModifiers[_lvlTempData[index]->monsterDifficulty] << 8) / _monsterModifiers[_monsterDifficulty];
|
||||
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (_monsters[i].mode >= 14 || _monsters[i].block == 0 || _monsters[i].hitPoints <= 0)
|
||||
continue;
|
||||
|
||||
_monsters[i].hitPoints = (d * _monsters[i].hitPoints) >> 8;
|
||||
if (_monsterDifficulty < _lvlTempData[index]->monsterDifficulty)
|
||||
_monsters[i].hitPoints++;
|
||||
if (_monsters[i].hitPoints == 0)
|
||||
_monsters[i].hitPoints = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::loadBlockProperties(const char *cmzFile) {
|
||||
memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty));
|
||||
_screen->loadBitmap(cmzFile, 2, 2, 0);
|
||||
@ -299,7 +245,7 @@ void LoLEngine::loadBlockProperties(const char *cmzFile) {
|
||||
|
||||
_levelBlockProperties[i].direction = 5;
|
||||
|
||||
if (_wllBuffer4[_levelBlockProperties[i].walls[0]] == 17) {
|
||||
if (_wllAutomapData[_levelBlockProperties[i].walls[0]] == 17) {
|
||||
_levelBlockProperties[i].flags &= 0xef;
|
||||
_levelBlockProperties[i].flags |= 0x20;
|
||||
}
|
||||
@ -310,15 +256,15 @@ void LoLEngine::loadLevelShpDat(const char *shpFile, const char *datFile, bool f
|
||||
memset(_tempBuffer5120, 0, 5120);
|
||||
|
||||
_lvlShpFileHandle = _res->createReadStream(shpFile);
|
||||
_lvlShpNum = _lvlShpFileHandle->readUint16LE();
|
||||
_decorationCount = _lvlShpFileHandle->readUint16LE();
|
||||
|
||||
Common::SeekableReadStream *s = _res->createReadStream(datFile);
|
||||
|
||||
_levelFileDataSize = s->readUint16LE();
|
||||
delete[] _levelFileData;
|
||||
_levelFileData = new LevelShapeProperty[_levelFileDataSize];
|
||||
for (int i = 0; i < _levelFileDataSize; i++) {
|
||||
LevelShapeProperty * l = &_levelFileData[i];
|
||||
_levelDecorationDataSize = s->readUint16LE();
|
||||
delete[] _levelDecorationData;
|
||||
_levelDecorationData = new LevelDecorationProperty[_levelDecorationDataSize];
|
||||
for (int i = 0; i < _levelDecorationDataSize; i++) {
|
||||
LevelDecorationProperty * l = &_levelDecorationData[i];
|
||||
for (int ii = 0; ii < 10; ii++)
|
||||
l->shapeIndex[ii] = s->readUint16LE();
|
||||
for (int ii = 0; ii < 10; ii++)
|
||||
@ -334,7 +280,7 @@ void LoLEngine::loadLevelShpDat(const char *shpFile, const char *datFile, bool f
|
||||
delete s;
|
||||
|
||||
if (!flag) {
|
||||
_lvlBlockIndex = 1;
|
||||
_mappedDecorationsCount = 1;
|
||||
_lvlShapeIndex = 1;
|
||||
}
|
||||
}
|
||||
@ -515,10 +461,10 @@ void LoLEngine::resetItems(int flag) {
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
_levelBlockProperties[i].direction = 5;
|
||||
uint16 id = _levelBlockProperties[i].assignedObjects;
|
||||
MonsterInPlay *r = 0;
|
||||
LolMonsterInPlay *r = 0;
|
||||
|
||||
while (id & 0x8000) {
|
||||
r = (MonsterInPlay *)findObject(id);
|
||||
r = (LolMonsterInPlay *)findObject(id);
|
||||
id = r->nextAssignedObject;
|
||||
}
|
||||
|
||||
@ -537,7 +483,7 @@ void LoLEngine::resetItems(int flag) {
|
||||
}
|
||||
|
||||
void LoLEngine::disableMonsters() {
|
||||
memset(_monsters, 0, 30 * sizeof(MonsterInPlay));
|
||||
memset(_monsters, 0, 30 * sizeof(LolMonsterInPlay));
|
||||
for (int i = 0; i < 30; i++)
|
||||
_monsters[i].mode = 0x10;
|
||||
}
|
||||
@ -751,11 +697,6 @@ void LoLEngine::moveParty(uint16 direction, int unk1, int unk2, int buttonShape)
|
||||
updateAutoMap(_currentBlock);
|
||||
}
|
||||
|
||||
uint16 LoLEngine::calcNewBlockPosition(uint16 curBlock, uint16 direction) {
|
||||
static const int16 blockPosTable[] = { -32, 1, 32, -1 };
|
||||
return (curBlock + blockPosTable[direction]) & 0x3ff;
|
||||
}
|
||||
|
||||
uint16 LoLEngine::calcBlockIndex(uint16 x, uint16 y) {
|
||||
return (((y & 0xff00) >> 3) | (x >> 8)) & 0x3ff;
|
||||
}
|
||||
@ -827,51 +768,6 @@ void LoLEngine::notifyBlockNotPassable(int scrollFlag) {
|
||||
snd_playSoundEffect(19, -1);
|
||||
}
|
||||
|
||||
int LoLEngine::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 LoLEngine::clickedLeverOn(uint16 block, uint16 direction) {
|
||||
uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
|
||||
if (!clickedShape(v))
|
||||
return 0;
|
||||
|
||||
_levelBlockProperties[block].walls[direction]++;
|
||||
_sceneUpdateRequired = true;
|
||||
|
||||
snd_playSoundEffect(30, -1);
|
||||
|
||||
runLevelScript(block, 0x40);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoLEngine::clickedLeverOff(uint16 block, uint16 direction) {
|
||||
uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
|
||||
if (!clickedShape(v))
|
||||
return 0;
|
||||
|
||||
_levelBlockProperties[block].walls[direction]--;
|
||||
_sceneUpdateRequired = true;
|
||||
|
||||
snd_playSoundEffect(29, -1);
|
||||
|
||||
runLevelScript(block, 0x40);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoLEngine::clickedWallOnlyScript(uint16 block) {
|
||||
runLevelScript(block, 0x40);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoLEngine::clickedDoorSwitch(uint16 block, uint16 direction) {
|
||||
uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
|
||||
if (!clickedShape(v))
|
||||
@ -903,119 +799,6 @@ int LoLEngine::clickedNiche(uint16 block, uint16 direction) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool LoLEngine::clickedShape(int shapeIndex) {
|
||||
while (shapeIndex) {
|
||||
uint16 s = _levelShapeProperties[shapeIndex].shapeIndex[1];
|
||||
|
||||
if (s == 0xffff) {
|
||||
shapeIndex = _levelShapeProperties[shapeIndex].next;
|
||||
continue;
|
||||
}
|
||||
|
||||
int w = _levelShapes[s][3];
|
||||
int h = _levelShapes[s][2];
|
||||
int x = _levelShapeProperties[shapeIndex].shapeX[1] + 136;
|
||||
int y = _levelShapeProperties[shapeIndex].shapeY[1] + 8;
|
||||
|
||||
if (_levelShapeProperties[shapeIndex].flags & 1)
|
||||
w <<= 1;
|
||||
|
||||
if (posWithinRect(_mouseX, _mouseY, x - 4, y - 4, x + w + 8, y + h + 8))
|
||||
return true;
|
||||
|
||||
shapeIndex = _levelShapeProperties[shapeIndex].next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LoLEngine::processDoorSwitch(uint16 block, int openClose) {
|
||||
if ((block == _currentBlock) || (_levelBlockProperties[block].assignedObjects & 0x8000))
|
||||
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;
|
||||
|
||||
openCloseDoor(block, openClose);
|
||||
}
|
||||
|
||||
void LoLEngine::openCloseDoor(uint16 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) ? 32 : 31;
|
||||
|
||||
snd_processEnvironmentalSoundEffect(snd, block);
|
||||
if (!checkSceneUpdateNeed(block))
|
||||
updateEnvironmentalSfx(0);
|
||||
}
|
||||
|
||||
enableTimer(0);
|
||||
|
||||
} else {
|
||||
while (!(flg & _wllWallFlags[v]))
|
||||
v += openClose;
|
||||
|
||||
_levelBlockProperties[block].walls[c] = _levelBlockProperties[block].walls[c ^ 2] = v;
|
||||
checkSceneUpdateNeed(block);
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::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;
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::movePartySmoothScrollBlocked(int speed) {
|
||||
if (!_smoothScrollingEnabled || (_smoothScrollingEnabled && _needSceneRestore))
|
||||
return;
|
||||
@ -1447,7 +1230,7 @@ void LoLEngine::setWallType(int block, int wall, int val) {
|
||||
if (wall == -1) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
_levelBlockProperties[block].walls[i] = val;
|
||||
if (_wllBuffer4[val] == 17) {
|
||||
if (_wllAutomapData[val] == 17) {
|
||||
_levelBlockProperties[block].flags &= 0xef;
|
||||
_levelBlockProperties[block].flags |= 0x20;
|
||||
} else {
|
||||
@ -1603,334 +1386,20 @@ void LoLEngine::setDefaultButtonState() {
|
||||
_lampStatusSuspended = false;
|
||||
}
|
||||
|
||||
void LoLEngine::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 LoLEngine::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 LoLEngine::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 LoLEngine::hasWall(int index) {
|
||||
if (!index || (_wllWallFlags[index] & 8))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoLEngine::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;
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::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++;
|
||||
|
||||
if (vcnOffset & 0x8000) {
|
||||
// this renders a wall block over the transparent pixels of a floor/ceiling block
|
||||
remainder = vcnOffset - 0x8000;
|
||||
vcnOffset = 0;
|
||||
}
|
||||
|
||||
if (vcnOffset & 0x4000) {
|
||||
horizontalFlip = true;
|
||||
vcnOffset &= 0x3fff;
|
||||
}
|
||||
|
||||
uint8 *src = 0;
|
||||
if (vcnOffset) {
|
||||
src = &_vcnBlocks[vcnOffset << 5];
|
||||
} 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) | shift];
|
||||
*d++ = _vcnExpTable[(t >> 4) | 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) | shift];
|
||||
*d++ = _vcnExpTable[(t & 0x0f) | 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) | shift];
|
||||
uint8 l = _vcnExpTable[(t >> 4) | 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) | shift];
|
||||
uint8 l = _vcnExpTable[(t & 0x0f) | shift];
|
||||
if (h)
|
||||
*d = h;
|
||||
d++;
|
||||
if (l)
|
||||
*d = l;
|
||||
d++;
|
||||
}
|
||||
d += 168;
|
||||
}
|
||||
}
|
||||
d -= 1400;
|
||||
}
|
||||
}
|
||||
d += 1232;
|
||||
}
|
||||
|
||||
_screen->copyBlockToPage(_sceneDrawPage1, 112, 0, 176, 120, _sceneWindowBuffer);
|
||||
}
|
||||
|
||||
void LoLEngine::drawSceneShapes() {
|
||||
for (int i = 0; i < 18; i++) {
|
||||
uint8 t = _dscTileIndex[i];
|
||||
uint8 s = _visibleBlocks[t]->walls[_sceneDrawVarDown];
|
||||
|
||||
int16 x1 = 0;
|
||||
int16 x2 = 0;
|
||||
_shpDmX1 = 0;
|
||||
_shpDmX2 = 0;
|
||||
|
||||
int16 dimY1 = 0;
|
||||
int16 dimY2 = 0;
|
||||
|
||||
setLevelShapesDim(t, x1, x2, 13);
|
||||
setLevelShapesDim(t, _shpDmX1, _shpDmX2, _sceneShpDim);
|
||||
|
||||
if (x2 <= x1)
|
||||
if (_shpDmX2 <= _shpDmX1)
|
||||
continue;
|
||||
|
||||
drawDecorations(t);
|
||||
@ -1954,104 +1423,12 @@ void LoLEngine::drawSceneShapes() {
|
||||
if (v > 80)
|
||||
v = 80;
|
||||
|
||||
scaleLevelShapesDim(t, dimY1, dimY2, 13);
|
||||
scaleLevelShapesDim(t, dimY1, dimY2, _sceneShpDim);
|
||||
drawDoor(_doorShapes[(s < 23 ? _dscDoorShpIndex[s] : 0)], 0, t, 10, 0, -v, 2);
|
||||
setLevelShapesDim(t, dimY1, dimY2, 13);
|
||||
setLevelShapesDim(t, dimY1, dimY2, _sceneShpDim);
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::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 += 14;
|
||||
x2 += 14;
|
||||
|
||||
_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 LoLEngine::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 LoLEngine::drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2) {
|
||||
_screen->modifyScreenDim(dim, x1, y1 << 3, x2 - x1, (y2 - y1) << 3);
|
||||
}
|
||||
|
||||
void LoLEngine::drawDecorations(int index) {
|
||||
for (int i = 1; i >= 0; i--) {
|
||||
int s = index * 2 + i;
|
||||
@ -2066,7 +1443,7 @@ void LoLEngine::drawDecorations(int index) {
|
||||
if (!scaleW || !scaleH)
|
||||
continue;
|
||||
|
||||
uint8 d = (_currentDirection + _dscUnk1[s]) & 3;
|
||||
uint8 d = (_currentDirection + _dscWalls[s]) & 3;
|
||||
int8 l = _wllShapeMap[_visibleBlocks[index]->walls[d]];
|
||||
|
||||
uint8 *shapeData = 0;
|
||||
@ -2076,21 +1453,21 @@ void LoLEngine::drawDecorations(int index) {
|
||||
int flags = 0;
|
||||
|
||||
while (l > 0) {
|
||||
if ((_levelShapeProperties[l].flags & 8) && index != 3 && index != 9 && index != 13) {
|
||||
l = _levelShapeProperties[l].next;
|
||||
if ((_levelDecorationProperties[l].flags & 8) && index != 3 && index != 9 && index != 13) {
|
||||
l = _levelDecorationProperties[l].next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_dscOvlMap[shpIx] == 1 && ((_levelShapeProperties[l].flags & 2) || ((_levelShapeProperties[l].flags & 4) && _wllProcessFlag)))
|
||||
if (_dscOvlMap[shpIx] == 1 && ((_levelDecorationProperties[l].flags & 2) || ((_levelDecorationProperties[l].flags & 4) && _wllProcessFlag)))
|
||||
ix = -ix;
|
||||
|
||||
int xOffs = 0;
|
||||
int yOffs = 0;
|
||||
uint8 *ovl = 0;
|
||||
|
||||
if (_levelShapeProperties[l].scaleFlag[shpIx] & 1) {
|
||||
xOffs = _levelShapeProperties[l].shapeX[shpIx];
|
||||
yOffs = _levelShapeProperties[l].shapeY[shpIx];
|
||||
if (_levelDecorationProperties[l].scaleFlag[shpIx] & 1) {
|
||||
xOffs = _levelDecorationProperties[l].shapeX[shpIx];
|
||||
yOffs = _levelDecorationProperties[l].shapeY[shpIx];
|
||||
shpIx = _dscOvlMap[shpIx];
|
||||
int ov = ovlIndex;
|
||||
if (_flags.use16ColorMode) {
|
||||
@ -2100,8 +1477,8 @@ void LoLEngine::drawDecorations(int index) {
|
||||
else
|
||||
ov = 0;
|
||||
}
|
||||
ovl = _screen->getLevelOverlay(ov);
|
||||
} else if (_levelShapeProperties[l].shapeIndex[shpIx] != 0xffff) {
|
||||
ovl = screen()->getLevelOverlay(ov);
|
||||
} else if (_levelDecorationProperties[l].shapeIndex[shpIx] != 0xffff) {
|
||||
scaleW = scaleH = 0x100;
|
||||
int ov = 7;
|
||||
if (_flags.use16ColorMode) {
|
||||
@ -2111,37 +1488,37 @@ void LoLEngine::drawDecorations(int index) {
|
||||
else
|
||||
ov = 0;
|
||||
}
|
||||
ovl = _screen->getLevelOverlay(ov);
|
||||
ovl = screen()->getLevelOverlay(ov);
|
||||
}
|
||||
|
||||
if (_levelShapeProperties[l].shapeIndex[shpIx] != 0xffff) {
|
||||
shapeData = _levelShapes[_levelShapeProperties[l].shapeIndex[shpIx]];
|
||||
if (_levelDecorationProperties[l].shapeIndex[shpIx] != 0xffff) {
|
||||
shapeData = _levelDecorationShapes[_levelDecorationProperties[l].shapeIndex[shpIx]];
|
||||
if (shapeData) {
|
||||
if (ix < 0) {
|
||||
x = _dscShapeX[s] + xOffs + ((_levelShapeProperties[l].shapeX[shpIx] * scaleW) >> 8);
|
||||
x = _dscShapeX[s] + xOffs + ((_levelDecorationProperties[l].shapeX[shpIx] * scaleW) >> 8);
|
||||
if (ix == _dscShapeIndex[s]) {
|
||||
x = _dscShapeX[s] - ((_levelShapeProperties[l].shapeX[shpIx] * scaleW) >> 8) -
|
||||
_screen->getShapeScaledWidth(shapeData, scaleW) - xOffs;
|
||||
x = _dscShapeX[s] - ((_levelDecorationProperties[l].shapeX[shpIx] * scaleW) >> 8) -
|
||||
screen()->getShapeScaledWidth(shapeData, scaleW) - xOffs;
|
||||
}
|
||||
flags = 0x105;
|
||||
} else {
|
||||
x = _dscShapeX[s] + xOffs + ((_levelShapeProperties[l].shapeX[shpIx] * scaleW) >> 8);
|
||||
x = _dscShapeX[s] + xOffs + ((_levelDecorationProperties[l].shapeX[shpIx] * scaleW) >> 8);
|
||||
flags = 0x104;
|
||||
}
|
||||
|
||||
y = _dscShapeY[s] + yOffs + ((_levelShapeProperties[l].shapeY[shpIx] * scaleH) >> 8);
|
||||
_screen->drawShape(_sceneDrawPage1, shapeData, x + 112, y, 13, flags, ovl, 1, scaleW, scaleH);
|
||||
y = _dscShapeY[s] + yOffs + ((_levelDecorationProperties[l].shapeY[shpIx] * scaleH) >> 8);
|
||||
screen()->drawShape(_sceneDrawPage1, shapeData, x + 112, y, _sceneShpDim, flags, ovl, 1, scaleW, scaleH);
|
||||
|
||||
if ((_levelShapeProperties[l].flags & 1) && shpIx < 4) {
|
||||
if ((_levelDecorationProperties[l].flags & 1) && shpIx < 4) {
|
||||
//draw shadow
|
||||
x += (_screen->getShapeScaledWidth(shapeData, scaleW));
|
||||
x += (screen()->getShapeScaledWidth(shapeData, scaleW));
|
||||
flags ^= 1;
|
||||
_screen->drawShape(_sceneDrawPage1, shapeData, x + 112, y, 13, flags, ovl, 1, scaleW, scaleH);
|
||||
screen()->drawShape(_sceneDrawPage1, shapeData, x + 112, y, _sceneShpDim, flags, ovl, 1, scaleW, scaleH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
l = _levelShapeProperties[l].next;
|
||||
l = _levelDecorationProperties[l].next;
|
||||
shpIx = (_dscShapeIndex[s] < 0) ? -_dscShapeIndex[s] : _dscShapeIndex[s];
|
||||
}
|
||||
}
|
||||
|
@ -976,6 +976,58 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum,
|
||||
}
|
||||
}
|
||||
|
||||
void Screen::crossFadeRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage) {
|
||||
if (srcPage > 13 || dstPage > 13)
|
||||
error("Screen::crossFadeRegion: attempting to use temp page as source or dest page.");
|
||||
|
||||
hideMouse();
|
||||
|
||||
uint16 *wB = (uint16*)_pagePtrs[14];
|
||||
uint8 *hB = _pagePtrs[14] + 640;
|
||||
|
||||
for (int i = 0; i < w; i++)
|
||||
wB[i] = i;
|
||||
|
||||
for (int i = 0; i < h; i++)
|
||||
hB[i] = i;
|
||||
|
||||
for (int i = 0; i < w; i++)
|
||||
SWAP(wB[_vm->_rnd.getRandomNumberRng(0, w - 1)], wB[i]);
|
||||
|
||||
for (int i = 0; i < h; i++)
|
||||
SWAP(hB[_vm->_rnd.getRandomNumberRng(0, h - 1)], hB[i]);
|
||||
|
||||
uint8 *s = _pagePtrs[srcPage];
|
||||
uint8 *d = _pagePtrs[dstPage];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int iH = i;
|
||||
uint32 end = _system->getMillis() + 1;
|
||||
for (int ii = 0; ii < w; ii++) {
|
||||
int sX = x1 + wB[ii];
|
||||
int sY = y1 + hB[iH];
|
||||
int dX = x2 + wB[ii];
|
||||
int dY = y2 + hB[iH];
|
||||
|
||||
if (++iH >= h)
|
||||
iH = 0;
|
||||
|
||||
d[dY * 320 + dX] = s[sY * 320 + sX];
|
||||
addDirtyRect(dX, dY, 1, 1);
|
||||
}
|
||||
|
||||
// This tries to speed things up, to get similiar speeds as in DOSBox etc.
|
||||
if ((i & 5) == 5)
|
||||
updateScreen();
|
||||
|
||||
uint32 cur = _system->getMillis();
|
||||
if (end > cur)
|
||||
_system->delayMillis(end - cur);
|
||||
}
|
||||
|
||||
showMouse();
|
||||
}
|
||||
|
||||
void Screen::drawBox(int x1, int y1, int x2, int y2, int color) {
|
||||
drawClippedLine(x1, y1, x2, y1, color);
|
||||
drawClippedLine(x1, y1, x1, y2, color);
|
||||
@ -1088,6 +1140,10 @@ bool Screen::loadFont(FontId fontId, const char *filename) {
|
||||
if (!fnt) {
|
||||
if (_isAmiga)
|
||||
fnt = new AMIGAFont();
|
||||
#ifdef ENABLE_EOB
|
||||
else if (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2)
|
||||
fnt = new OldDOSFont();
|
||||
#endif // ENABLE_EOB
|
||||
else
|
||||
fnt = new DOSFont();
|
||||
|
||||
@ -2859,7 +2915,7 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette
|
||||
|
||||
const char *ext = filename + strlen(filename) - 3;
|
||||
uint8 compType = srcData[2];
|
||||
uint32 imgSize = scumm_stricmp(ext, "CMP") ? READ_LE_UINT32(srcData + 4) : READ_LE_UINT16(srcData);
|
||||
uint32 imgSize = (_vm->game() == GI_KYRA2 && !scumm_stricmp(ext, "CMP")) ? READ_LE_UINT16(srcData) : READ_LE_UINT32(srcData + 4);
|
||||
uint16 palSize = READ_LE_UINT16(srcData + 8);
|
||||
|
||||
if (pal && palSize)
|
||||
|
@ -137,6 +137,37 @@ private:
|
||||
uint16 *_bitmapOffsets;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
/**
|
||||
* Implementation of the Font interface for old DOS fonts used
|
||||
* in EOB and EOB II.
|
||||
*
|
||||
*/
|
||||
class OldDOSFont : public Font {
|
||||
public:
|
||||
OldDOSFont();
|
||||
~OldDOSFont() { unload(); }
|
||||
|
||||
bool load(Common::SeekableReadStream &file);
|
||||
int getHeight() const { return _height; }
|
||||
int getWidth() const { return _width; }
|
||||
int getCharWidth(uint16 c) const;
|
||||
void setColorMap(const uint8 *src) { _colorMap = src; }
|
||||
void drawChar(uint16 c, byte *dst, int pitch) const;
|
||||
|
||||
private:
|
||||
void unload();
|
||||
|
||||
uint8 *_data;
|
||||
uint16 *_bitmapOffsets;
|
||||
|
||||
int _width, _height;
|
||||
const uint8 *_colorMap;
|
||||
|
||||
int _numGlyphs;
|
||||
};
|
||||
#endif // ENABLE_EOB
|
||||
|
||||
/**
|
||||
* Implementation of the Font interface for AMIGA fonts.
|
||||
*/
|
||||
@ -369,6 +400,8 @@ public:
|
||||
void shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPage, int ticks, bool transparent);
|
||||
void fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum = -1, bool xored = false);
|
||||
|
||||
void crossFadeRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage);
|
||||
|
||||
void clearPage(int pageNum);
|
||||
|
||||
uint8 getPagePixel(int pageNum, int x, int y);
|
||||
@ -420,6 +453,8 @@ public:
|
||||
|
||||
virtual void setScreenDim(int dim) = 0;
|
||||
virtual const ScreenDim *getScreenDim(int dim) = 0;
|
||||
virtual int curDimIndex() const { return 0; }
|
||||
virtual void modifyScreenDim(int dim, int x, int y, int w, int h) {}
|
||||
virtual int screenDimTableCount() const = 0;
|
||||
|
||||
const ScreenDim *_curDim;
|
||||
@ -430,13 +465,15 @@ public:
|
||||
int setNewShapeHeight(uint8 *shape, int height);
|
||||
int resetShapeHeight(uint8 *shape);
|
||||
|
||||
void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...);
|
||||
virtual int getShapeScaledWidth( const uint8*, int) { return 0; }
|
||||
|
||||
virtual void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...);
|
||||
|
||||
// mouse handling
|
||||
void hideMouse();
|
||||
void showMouse();
|
||||
bool isMouseVisible() const;
|
||||
void setMouseCursor(int x, int y, const byte *shape);
|
||||
virtual void setMouseCursor(int x, int y, const byte *shape);
|
||||
|
||||
// rect handling
|
||||
virtual int getRectSize(int w, int h) = 0;
|
||||
@ -463,6 +500,8 @@ public:
|
||||
void blockInRegion(int x, int y, int width, int height);
|
||||
void blockOutRegion(int x, int y, int width, int height);
|
||||
|
||||
virtual uint8 *getLevelOverlay(int) { return 0; }
|
||||
|
||||
int _charWidth;
|
||||
int _charOffset;
|
||||
int _curPage;
|
||||
@ -514,7 +553,7 @@ protected:
|
||||
uint8 _sjisInvisibleColor;
|
||||
|
||||
Palette *_screenPalette;
|
||||
Common::Array<Palette *> _palettes;
|
||||
Common::Array<Palette*> _palettes;
|
||||
Palette *_internFadePalette;
|
||||
|
||||
Font *_fonts[FID_NUM];
|
||||
|
965
engines/kyra/screen_eob.cpp
Normal file
965
engines/kyra/screen_eob.cpp
Normal file
@ -0,0 +1,965 @@
|
||||
/* 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)
|
||||
#include "kyra/screen.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#include "kyra/eobcommon.h"
|
||||
#include "kyra/resource.h"
|
||||
|
||||
#include "common/system.h"
|
||||
|
||||
#include "graphics/cursorman.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
Screen_Eob::Screen_Eob(EobCoreEngine *vm, OSystem *system) : Screen(vm, system) {
|
||||
_shapeFadeMode[0] = _shapeFadeMode[1] = 0;
|
||||
_shapeFadeInternal = 0;
|
||||
_fadeData = 0;
|
||||
_fadeDataIndex = 0;
|
||||
_dsX1 = _dsX2 = _dsY1 = _dsY2 = 0;
|
||||
_customDimTable = 0;
|
||||
_dsTempPage = 0;
|
||||
}
|
||||
|
||||
Screen_Eob::~Screen_Eob() {
|
||||
delete[] _fadeData;
|
||||
delete[] _customDimTable;
|
||||
delete[] _dsTempPage;
|
||||
}
|
||||
|
||||
bool Screen_Eob::init() {
|
||||
if (Screen::init()) {
|
||||
_customDimTable = new ScreenDim*[_screenDimTableCount];
|
||||
memset(_customDimTable, 0, sizeof(ScreenDim *)* _screenDimTableCount);
|
||||
|
||||
_fadeData = _vm->resource()->fileData("FADING.DAT", 0);
|
||||
|
||||
if (!_fadeData) {
|
||||
_fadeData = new uint8[0x700];
|
||||
memset(_fadeData, 0, 0x700);
|
||||
uint8 *pal = _vm->resource()->fileData("palette1.pal", 0); // EGA: palette0.pal
|
||||
for (int i = 0; i < 7; i++)
|
||||
createFadeTable(pal, &_fadeData[i << 8], 18, (i + 1) * 36);
|
||||
delete[] pal;
|
||||
}
|
||||
|
||||
_dsTempPage = new uint8[6000];
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Screen_Eob::setScreenDim(int dim) {
|
||||
assert(dim < _screenDimTableCount);
|
||||
_curDim = _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];
|
||||
_curDimIndex = dim;
|
||||
}
|
||||
|
||||
const ScreenDim *Screen_Eob::getScreenDim(int dim) {
|
||||
assert(dim < _screenDimTableCount);
|
||||
return _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];
|
||||
}
|
||||
|
||||
void Screen_Eob::modifyScreenDim(int dim, int x, int y, int w, int h) {
|
||||
delete _customDimTable[dim];
|
||||
_customDimTable[dim] = new ScreenDim;
|
||||
memcpy(_customDimTable[dim], &_screenDimTable[dim], sizeof(ScreenDim));
|
||||
_customDimTable[dim]->sx = x;
|
||||
_customDimTable[dim]->sy = y;
|
||||
_customDimTable[dim]->w = w;
|
||||
_customDimTable[dim]->h = h;
|
||||
if (dim == _curDimIndex)
|
||||
setScreenDim(dim);
|
||||
}
|
||||
|
||||
void Screen_Eob::setClearScreenDim(int dim) {
|
||||
setScreenDim(dim);
|
||||
clearCurDim();
|
||||
}
|
||||
|
||||
void Screen_Eob::clearCurDim() {
|
||||
fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _curDim->unkA);
|
||||
}
|
||||
|
||||
void Screen_Eob::setMouseCursor(int x, int y, const byte *shape) {
|
||||
if (!shape)
|
||||
return;
|
||||
int mouseW = shape[2] << 3;
|
||||
int mouseH = shape[3];
|
||||
uint8 *cursor = new uint8[mouseW * mouseH];
|
||||
fillRect(0, 0, mouseW, mouseH, _cursorColorKey, 8);
|
||||
drawShape(8, shape, 0, 0, 0);
|
||||
CursorMan.showMouse(false);
|
||||
copyRegionToBuffer(8, 0, 0, mouseW, mouseH, cursor);
|
||||
CursorMan.replaceCursor(cursor, mouseW, mouseH, x, y, _cursorColorKey);
|
||||
if (isMouseVisible())
|
||||
CursorMan.showMouse(true);
|
||||
delete[] cursor;
|
||||
|
||||
// makes sure that the cursor is drawn
|
||||
// we do not use Screen::updateScreen here
|
||||
// so we can be sure that changes to page 0
|
||||
// are NOT updated on the real screen here
|
||||
_system->updateScreen();
|
||||
}
|
||||
|
||||
void Screen_Eob::loadFileDataToPage(Common::SeekableReadStream *s, int pageNum, uint32 size) {
|
||||
s->read(_pagePtrs[pageNum], size);
|
||||
}
|
||||
|
||||
void Screen_Eob::printShadedText(const char *string, int x, int y, int col1, int col2) {
|
||||
printText(string, x - 1, y, 12, col2);
|
||||
printText(string, x, y + 1, 12, 0);
|
||||
printText(string, x - 1, y + 1, 12, 0);
|
||||
printText(string, x, y, col1, 0);
|
||||
}
|
||||
|
||||
void Screen_Eob::loadEobBitmap(const char *file, int tempPage, int destPage) {
|
||||
loadEobCpsFileToPage(file, 0, tempPage, destPage, -1);
|
||||
_curPage = 2;
|
||||
}
|
||||
|
||||
void Screen_Eob::loadEobCpsFileToPage(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) {
|
||||
char tmp[13];
|
||||
sprintf(tmp, "%s.CPS", file);
|
||||
|
||||
Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp);
|
||||
bool loadAlternative = false;
|
||||
if (s) {
|
||||
// This additional check is necessary since some localized versions of EOB II seem to contain invalid (size zero) cps files
|
||||
if (s->size())
|
||||
loadBitmap(tmp, tempPage, destPage, 0);
|
||||
else
|
||||
loadAlternative = true;
|
||||
|
||||
delete s;
|
||||
} else {
|
||||
loadAlternative = true;
|
||||
}
|
||||
|
||||
if (loadAlternative) {
|
||||
tmp[0] = 'X';
|
||||
s = _vm->resource()->createReadStream(tmp);
|
||||
if (!s)
|
||||
error("Screen_Eob::loadEobCpsFileToPage(): CPS file loading failed.");
|
||||
s->seek(768);
|
||||
loadFileDataToPage(s, destPage, 64000);
|
||||
delete s;
|
||||
}
|
||||
|
||||
if (copyToPage == -1) {
|
||||
return;
|
||||
} else if (copyToPage == 0) {
|
||||
copyPage(destPage, 2);
|
||||
copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
|
||||
} else {
|
||||
copyPage(destPage, copyToPage);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag) {
|
||||
uint8 *shp = 0;
|
||||
uint16 shapesize = 0;
|
||||
|
||||
uint8 *srcPage = getPagePtr(_curPage) + y * 320 + (x << 3);
|
||||
uint8 *src = srcPage;
|
||||
|
||||
if (flag) {
|
||||
uint16 h1 = h;
|
||||
while (h1--) {
|
||||
uint8 *lineEnd = src + (w << 3);
|
||||
do {
|
||||
if (!*src++) {
|
||||
shapesize++;
|
||||
uint8 *startZeroPos = src;
|
||||
while (src != lineEnd && *src == 0)
|
||||
src++;
|
||||
|
||||
uint16 numZero = src - startZeroPos + 1;
|
||||
if (numZero >> 8)
|
||||
shapesize += 2;
|
||||
}
|
||||
shapesize++;
|
||||
} while (src != lineEnd);
|
||||
|
||||
srcPage += 320;
|
||||
src = srcPage;
|
||||
}
|
||||
|
||||
shapesize += 4;
|
||||
|
||||
shp = new uint8[shapesize];
|
||||
memset (shp, 0, shapesize);
|
||||
uint8 *dst = shp;
|
||||
|
||||
*dst++ = 0;
|
||||
*dst++ = (h & 0xff);
|
||||
*dst++ = (w & 0xff);
|
||||
*dst++ = (h & 0xff);
|
||||
|
||||
srcPage = getPagePtr(_curPage) + y * 320 + (x << 3);
|
||||
src = srcPage;
|
||||
|
||||
h1 = h;
|
||||
while (h1--) {
|
||||
uint8 *lineEnd = src + (w << 3);
|
||||
do {
|
||||
uint8 val = *src++;
|
||||
if (!val) {
|
||||
*dst++ = val;
|
||||
uint8 *startZeroPos = src;
|
||||
while (src != lineEnd && *src == 0)
|
||||
src++;
|
||||
|
||||
uint16 numZero = src - startZeroPos + 1;
|
||||
if (numZero >> 8) {
|
||||
numZero -= 0xff;
|
||||
*dst++ = 0xff;
|
||||
*dst++ = 0;
|
||||
}
|
||||
val = (numZero & 0xff);
|
||||
}
|
||||
*dst++ = val;
|
||||
} while (src != lineEnd);
|
||||
|
||||
srcPage += 320;
|
||||
src = srcPage;
|
||||
}
|
||||
|
||||
} else {
|
||||
uint8 nib = 0, col = 0;
|
||||
uint8 *colorMap = new uint8[0x100];
|
||||
memset (colorMap, 0xff, 0x100);
|
||||
|
||||
shapesize = h * (w << 2) + 0x14;
|
||||
shp = new uint8[shapesize];
|
||||
memset (shp, 0, shapesize);
|
||||
uint8 *dst = shp;
|
||||
|
||||
*dst++ = 1;
|
||||
*dst++ = (h & 0xff);
|
||||
*dst++ = (w & 0xff);
|
||||
*dst++ = (h & 0xff);
|
||||
memset (dst, 0xff, 0x10);
|
||||
|
||||
uint8 *pal = dst;
|
||||
dst += 0x10;
|
||||
|
||||
srcPage = getPagePtr(_curPage) + y * 320 + (x << 3);
|
||||
src = srcPage;
|
||||
nib = col = 0;
|
||||
|
||||
uint16 h1 = h;
|
||||
while (h1--) {
|
||||
uint16 w1 = w << 3;
|
||||
while (w1--) {
|
||||
uint8 s = *src++;
|
||||
uint8 c = colorMap[s];
|
||||
if (c == 0xff) {
|
||||
if (col < 0x10) {
|
||||
*pal++ = s;
|
||||
c = colorMap[s] = col++;
|
||||
if (!col)
|
||||
c = 0;
|
||||
} else {
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(++nib & 1) {
|
||||
*dst = c << 4;
|
||||
} else {
|
||||
*dst++ |= c;
|
||||
}
|
||||
}
|
||||
srcPage += 320;
|
||||
src = srcPage;
|
||||
}
|
||||
delete [] colorMap;
|
||||
}
|
||||
|
||||
return shp;
|
||||
}
|
||||
|
||||
void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) {
|
||||
uint8 *dst = getPagePtr(pageNum);
|
||||
const uint8 *src = shapeData;
|
||||
|
||||
if (!src)
|
||||
return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, flags);
|
||||
uint8 *ovl = (flags & 2) ? va_arg(args, uint8*) : 0;
|
||||
va_end(args);
|
||||
|
||||
if (sd != -1) {
|
||||
const ScreenDim *dm = getScreenDim(sd);
|
||||
setShapeFrame(dm->sx, dm->sy, dm->sx + dm->w, dm->sy + dm->h);
|
||||
x += (_dsX1 << 3);
|
||||
y += _dsY1;
|
||||
}
|
||||
|
||||
dst += (_dsX1 << 3);
|
||||
int16 dX = x - (_dsX1 << 3);
|
||||
int16 dY = y;
|
||||
int16 dW = _dsX2 - _dsX1;
|
||||
uint8 flag = *src++;
|
||||
|
||||
uint16 dH = *src++;
|
||||
uint16 width = (*src++) << 3;
|
||||
src++;
|
||||
|
||||
int rX = x;
|
||||
int rY = y;
|
||||
int rW = width + 8;
|
||||
int rH = dH;
|
||||
|
||||
uint16 w2 = width;
|
||||
int d = dY - _dsY1;
|
||||
|
||||
int pixelStep = (flags & 1) ? -1 : 1;
|
||||
|
||||
if (flag) {
|
||||
const uint8 *pal = ovl ? ovl : src;
|
||||
src += 16;
|
||||
|
||||
if (d < 0) {
|
||||
d = -d;
|
||||
if (d >= dH)
|
||||
return;
|
||||
src += (d * (width >> 1));
|
||||
d = dY + dH - _dsY1;
|
||||
if (d >=0) {
|
||||
dH = d;
|
||||
dY = _dsY1;
|
||||
d = _dsY2 - dY;
|
||||
}
|
||||
} else {
|
||||
d = _dsY2 - dY;
|
||||
}
|
||||
|
||||
if (d < 1)
|
||||
return;
|
||||
|
||||
if (d < dH)
|
||||
dH = d;
|
||||
|
||||
int16 cnt1 = 0;
|
||||
int16 cnt2 = 0;
|
||||
int16 dXbit1 = dX & 1;
|
||||
|
||||
if (dX < 0) {
|
||||
width += dX;
|
||||
d = -dX;
|
||||
if ((flags & 1))
|
||||
src -= (d >> 1);
|
||||
else
|
||||
src += (d >> 1);
|
||||
|
||||
if (d >= w2)
|
||||
return;
|
||||
|
||||
dX = 0;
|
||||
cnt1++;
|
||||
}
|
||||
|
||||
d = (dW << 3) - dX;
|
||||
|
||||
if (d < 1)
|
||||
return;
|
||||
|
||||
if (d < width) {
|
||||
width = d;
|
||||
cnt2++;
|
||||
}
|
||||
|
||||
dst += (dY * 320 + dX);
|
||||
|
||||
if (pageNum == 0 || pageNum == 1)
|
||||
addDirtyRect(rX, rY, rW, rH);
|
||||
|
||||
int w3 = w2;
|
||||
dY = 320 - width;
|
||||
width >>= 1;
|
||||
w2 >>= 1;
|
||||
if ((flags & 1))
|
||||
src += (w2 - 1);
|
||||
|
||||
int16 w1shr = width;
|
||||
|
||||
if (cnt1 && (dXbit1 & 1)) {
|
||||
w1shr++;
|
||||
w2++;
|
||||
if (!cnt2)
|
||||
dY += 2;
|
||||
}
|
||||
|
||||
if (cnt2 && (dXbit1 & 1))
|
||||
w1shr++;
|
||||
|
||||
int lineSrcStep = (w2 - w1shr);
|
||||
if ((flags & 1))
|
||||
lineSrcStep = w3 - lineSrcStep;
|
||||
|
||||
while (dH--) {
|
||||
int16 hpos = width;
|
||||
uint8 col = 0;
|
||||
uint8 b = 0;
|
||||
uint8 nextloop = 0;
|
||||
|
||||
if (cnt1 && dXbit1) {
|
||||
if (!hpos)
|
||||
return;
|
||||
b = *src;
|
||||
src += pixelStep;
|
||||
nextloop = 2;
|
||||
} else {
|
||||
nextloop = hpos ? 1 : 3;
|
||||
}
|
||||
|
||||
while (nextloop) {
|
||||
switch (nextloop) {
|
||||
case 1:
|
||||
b = *src;
|
||||
src += pixelStep;
|
||||
col = pal[(flags & 1) ? (b & 0x0f) : (b >> 4)];
|
||||
if (col)
|
||||
drawShapeSetPixel(dst, col);
|
||||
dst++;
|
||||
|
||||
case 2:
|
||||
col = pal[(flags & 1) ? (b >> 4) : (b & 0x0f)];
|
||||
|
||||
if (!col) {
|
||||
nextloop = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
drawShapeSetPixel(dst++, col);
|
||||
nextloop = --hpos ? 1 : 3;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (cnt2 && dXbit1) {
|
||||
col = pal[(flags & 1) ? (*src & 0x0f) : (*src >> 4)];
|
||||
src += pixelStep;
|
||||
if (col)
|
||||
drawShapeSetPixel(dst, col);
|
||||
dst++;
|
||||
}
|
||||
|
||||
src += lineSrcStep;
|
||||
dst += dY;
|
||||
nextloop = 0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
dst++;
|
||||
nextloop = --hpos ? 1 : 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint16 marginLeft = 0;
|
||||
uint16 marginRight = 0;
|
||||
|
||||
if (d < 0) {
|
||||
dH += d;
|
||||
if (dH <= 0)
|
||||
return;
|
||||
d = -d;
|
||||
|
||||
for (int ii = 0; ii < d; ii++) {
|
||||
marginLeft = width;
|
||||
int i = 0;
|
||||
do {
|
||||
for (i = 0; i < marginLeft; i++)
|
||||
if (!*src++)
|
||||
break;
|
||||
|
||||
if (!*(src-1) || i < marginLeft)
|
||||
marginLeft = ++marginLeft - *src++;
|
||||
else
|
||||
marginLeft = 0;
|
||||
|
||||
} while (marginLeft);
|
||||
}
|
||||
dY = _dsY1;
|
||||
}
|
||||
|
||||
d = _dsY2 - dY;
|
||||
|
||||
if (d < 1)
|
||||
return;
|
||||
|
||||
if (d < dH)
|
||||
dH = d;
|
||||
|
||||
marginLeft = 0;
|
||||
|
||||
if (dX < 0) {
|
||||
width += dX;
|
||||
marginLeft = -dX;
|
||||
|
||||
if (marginLeft >= w2)
|
||||
return;
|
||||
|
||||
dX = 0;
|
||||
}
|
||||
|
||||
marginRight = 0;
|
||||
d = (dW << 3) - dX;
|
||||
|
||||
if (d < 1)
|
||||
return;
|
||||
|
||||
if (d < width) {
|
||||
width = d;
|
||||
marginRight = w2 - marginLeft - width;
|
||||
}
|
||||
|
||||
dst += (y * 320 + dX);
|
||||
uint8 * dstL = dst;
|
||||
|
||||
if (pageNum == 0 || pageNum == 1)
|
||||
addDirtyRect(rX, rY, rW, rH);
|
||||
|
||||
while (dH--) {
|
||||
int16 xpos = (int16) marginLeft;
|
||||
|
||||
if (xpos) {
|
||||
do {
|
||||
while (*src && xpos) {
|
||||
src++;
|
||||
xpos--;
|
||||
}
|
||||
|
||||
if (!*src) {
|
||||
uint8 bt = *++src;
|
||||
src++;
|
||||
xpos = xpos - bt;
|
||||
}
|
||||
} while (xpos > 0);
|
||||
}
|
||||
|
||||
dst -= xpos;
|
||||
xpos += width;
|
||||
|
||||
while (xpos > 0) {
|
||||
uint8 c = *src++;
|
||||
|
||||
if (c) {
|
||||
drawShapeSetPixel(dst++, c);
|
||||
xpos--;
|
||||
} else {
|
||||
dst += *src;
|
||||
xpos -= *src++;
|
||||
}
|
||||
}
|
||||
xpos += marginRight;
|
||||
|
||||
if (xpos) {
|
||||
do {
|
||||
while (*src && xpos) {
|
||||
src++;
|
||||
xpos--;
|
||||
}
|
||||
|
||||
if (!*src) {
|
||||
uint8 bt = *++src;
|
||||
src++;
|
||||
xpos = xpos - bt;
|
||||
}
|
||||
} while (xpos > 0);
|
||||
}
|
||||
|
||||
dstL += 320;
|
||||
dst = dstL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Screen_Eob::drawShapeSetPixel(uint8 * dst, uint8 c) {
|
||||
if (_shapeFadeMode[0]) {
|
||||
if (_shapeFadeMode[1]) {
|
||||
c = *dst;
|
||||
} else {
|
||||
_shapeFadeInternal &= 7;
|
||||
c = *(dst + _shapeFadeInternal++);
|
||||
}
|
||||
}
|
||||
|
||||
if (_shapeFadeMode[1]) {
|
||||
uint8 cnt = _shapeFadeMode[1];
|
||||
while (cnt--)
|
||||
c = _fadeData[_fadeDataIndex + c];
|
||||
}
|
||||
|
||||
*dst = c;
|
||||
}
|
||||
|
||||
const uint8 *Screen_Eob::scaleShape(const uint8 *shapeData, int steps) {
|
||||
setShapeFadeMode(1, steps ? true : false);
|
||||
|
||||
while (shapeData && steps--)
|
||||
shapeData = scaleShapeStep(shapeData);
|
||||
|
||||
return shapeData;
|
||||
}
|
||||
|
||||
const uint8 *Screen_Eob::scaleShapeStep(const uint8 *shp) {
|
||||
uint8 *d = _dsTempPage;
|
||||
*d++ = *shp++;
|
||||
|
||||
uint16 h = (*shp++) + 1;
|
||||
d[0] = d[2] = (h << 1) / 3;
|
||||
d++;
|
||||
|
||||
uint16 w = *shp++;
|
||||
uint16 w2 = w << 2;
|
||||
uint16 t = ((w << 1) % 3) ? 1 : 0;
|
||||
*d++ = ((w << 1) / 3) + t;
|
||||
|
||||
shp++;
|
||||
d++;
|
||||
|
||||
int i = 0;
|
||||
while (i < 16) {
|
||||
if (!shp[i]) {
|
||||
i = -i;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i >= 0)
|
||||
i = 0;
|
||||
else
|
||||
i = -i;
|
||||
|
||||
_dsScaleTmp = (i << 4) | (i & 0x0f);
|
||||
memcpy(d, shp, 16);
|
||||
d += 16;
|
||||
shp += 16;
|
||||
|
||||
_dsDiv = w2 / 3;
|
||||
_dsRem = w2 % 3;
|
||||
|
||||
do {
|
||||
scaleShapeProcessLine(d, shp);
|
||||
if (!--h)
|
||||
break;
|
||||
scaleShapeProcessLine(d, shp);
|
||||
if (!--h)
|
||||
break;
|
||||
shp += w2;
|
||||
} while (--h);
|
||||
|
||||
return (const uint8 *) _dsTempPage;
|
||||
}
|
||||
|
||||
void Screen_Eob::replaceShapePalette(uint8 *shp, const uint8 *pal) {
|
||||
if (*shp != 1)
|
||||
return;
|
||||
shp += 4;
|
||||
memcpy(shp, pal, 16);
|
||||
}
|
||||
|
||||
void Screen_Eob::applyShapeOverlay(uint8 *shp, int ovlIndex) {
|
||||
if (*shp != 1)
|
||||
return;
|
||||
shp += 4;
|
||||
uint8 *ovl = getFadeTable(ovlIndex);
|
||||
for (int i = 0; i < 16; i++)
|
||||
shp[i] = ovl[shp[i]];
|
||||
}
|
||||
|
||||
void Screen_Eob::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) {
|
||||
for (int i = 0; i < _dsDiv; i++) {
|
||||
*dst++ = *src++;
|
||||
*dst++ = READ_BE_UINT16(src) >> 4;
|
||||
src += 2;
|
||||
}
|
||||
|
||||
if (_dsRem == 1) {
|
||||
*dst++ = *src++;
|
||||
*dst++ = _dsScaleTmp;
|
||||
|
||||
} if (_dsRem == 2) {
|
||||
*dst++ = (src[0] & 0xf0) | (src[1] >> 4);
|
||||
src += 2;
|
||||
*dst++ = _dsScaleTmp;
|
||||
*dst++ = _dsScaleTmp;
|
||||
*dst++ = _dsScaleTmp;
|
||||
}
|
||||
}
|
||||
|
||||
void Screen_Eob::fadeTextColor(Palette *pal, int color1, int rate) {
|
||||
uint8 *col = pal->getData();
|
||||
|
||||
for (bool loop = true; loop; ) {
|
||||
loop = true;
|
||||
uint32 end = _system->getMillis() + 16;
|
||||
|
||||
loop = false;
|
||||
for (int ii = 0; ii < 3; ii++) {
|
||||
uint8 c = col[color1 * 3 + ii];
|
||||
if (c > rate) {
|
||||
col[color1 * 3 + ii] -= rate;
|
||||
loop = true;
|
||||
} else if (c) {
|
||||
col[color1 * 3 + ii] = 0;
|
||||
loop = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (loop) {
|
||||
setScreenPalette(*pal);
|
||||
updateScreen();
|
||||
uint32 cur = _system->getMillis();
|
||||
if (end > cur)
|
||||
_system->delayMillis(end - cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Screen_Eob::delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate) {
|
||||
bool res = false;
|
||||
|
||||
uint8 *s = fadePal->getData();
|
||||
uint8 *d = destPal->getData();
|
||||
|
||||
for (int i = 0; i < 765; i++) {
|
||||
int fadeVal = *s++;
|
||||
int dstCur = *d;
|
||||
int diff = ABS(fadeVal - dstCur);
|
||||
|
||||
if (diff == 0) {
|
||||
d++;
|
||||
continue;
|
||||
}
|
||||
|
||||
res = true;
|
||||
diff = MIN(diff, rate);
|
||||
|
||||
if (dstCur < fadeVal)
|
||||
*d += diff;
|
||||
else
|
||||
*d -= diff;
|
||||
d++;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Screen_Eob::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight) {
|
||||
if (!palData)
|
||||
return;
|
||||
|
||||
uint8 *src = palData + 3 * rootColor;
|
||||
uint8 r = *src++;
|
||||
uint8 g = *src++;
|
||||
uint8 b = *src;
|
||||
uint8 tr, tg, tb;
|
||||
src = palData + 3;
|
||||
|
||||
*dst++ = 0;
|
||||
weight >>= 1;
|
||||
|
||||
for (uint8 i = 1; i; i++) {
|
||||
uint16 tmp = (uint16)((*src - r) * weight) << 1;
|
||||
tr = *src++ - ((tmp >> 8) & 0xff);
|
||||
tmp = (uint16)((*src - g) * weight) << 1;
|
||||
tg = *src++ - ((tmp >> 8) & 0xff);
|
||||
tmp = (uint16)((*src - b) * weight) << 1;
|
||||
tb = *src++ - ((tmp >> 8) & 0xff);
|
||||
|
||||
uint8 * d = palData + 3;
|
||||
uint16 v = 0xffff;
|
||||
uint8 col = rootColor;
|
||||
|
||||
for (uint8 ii = 1; ii; ii++) {
|
||||
int a = *d++ - tr;
|
||||
int t = a * a;
|
||||
a = *d++ - tg;
|
||||
t += (a * a);
|
||||
a = *d++ - tb;
|
||||
t += (a * a);
|
||||
|
||||
if (t <= v && (ii == rootColor || ii != i)) {
|
||||
v = t;
|
||||
col = ii ;
|
||||
}
|
||||
}
|
||||
*dst++ = col;
|
||||
}
|
||||
}
|
||||
|
||||
OldDOSFont::OldDOSFont() {
|
||||
_data = 0;
|
||||
_width = _height = _numGlyphs = 0;
|
||||
_bitmapOffsets = 0;
|
||||
}
|
||||
|
||||
bool OldDOSFont::load(Common::SeekableReadStream &file) {
|
||||
unload();
|
||||
|
||||
_data = new uint8[file.size()];
|
||||
assert(_data);
|
||||
|
||||
file.read(_data, file.size());
|
||||
if (file.err())
|
||||
return false;
|
||||
|
||||
if (file.size() - 2 != READ_LE_UINT16(_data))
|
||||
return false;
|
||||
|
||||
_width = _data[0x103];
|
||||
_height = _data[0x102];
|
||||
_numGlyphs = 255;
|
||||
|
||||
_bitmapOffsets = (uint16 *)(_data + 2);
|
||||
|
||||
for (int i = 0; i < _numGlyphs; ++i)
|
||||
_bitmapOffsets[i] = READ_LE_UINT16(&_bitmapOffsets[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int OldDOSFont::getCharWidth(uint16 c) const {
|
||||
if (c >= _numGlyphs)
|
||||
return 0;
|
||||
return _width;
|
||||
}
|
||||
|
||||
void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const {
|
||||
static const uint8 renderMaskTable6[] = { 0xFC, 0x00, 0x7E, 0x00, 0x3F, 0x00, 0x1F, 0x80, 0x0F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8 };
|
||||
static const uint8 renderMaskTable8[] = { 0xFF, 0x00, 0x7F, 0x80, 0x3F, 0xC0, 0x1F, 0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0x03, 0xFC, 0x01, 0xFE };
|
||||
|
||||
if (_width != 8 && _width != 6)
|
||||
error("EOB font rendering not implemented for other font widths than 6 and 8.");
|
||||
|
||||
if (_width == 6) {
|
||||
switch (c) {
|
||||
case 0x81:
|
||||
case 0x9a:
|
||||
c = 0x5d;
|
||||
break;
|
||||
case 0x84:
|
||||
case 0x8e:
|
||||
c = 0x5b;
|
||||
break;
|
||||
case 0x94:
|
||||
case 0x99:
|
||||
c = 0x40;
|
||||
case 0xe1:
|
||||
// TODO: recheck this: no conversion for 'ß' ?
|
||||
break;
|
||||
}
|
||||
} else if (_width == 8){
|
||||
switch (c) {
|
||||
case 0x81:
|
||||
case 0x9a:
|
||||
case 0x5d:
|
||||
c = 0x1d;
|
||||
break;
|
||||
case 0x84:
|
||||
case 0x5b:
|
||||
c = 0x1e;
|
||||
break;
|
||||
case 0x94:
|
||||
case 0x40:
|
||||
c = 0x1f;
|
||||
break;
|
||||
case 0x8e:
|
||||
c = 0x1b;
|
||||
break;
|
||||
case 0x99:
|
||||
c = 0x1c;
|
||||
break;
|
||||
case 0xe1:
|
||||
c = 0x19;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const uint8 *src = &_data[_bitmapOffsets[c]];
|
||||
|
||||
int w = (_width - 1) >> 3;
|
||||
pitch -= _width;
|
||||
|
||||
uint8 color1 = _colorMap[1];
|
||||
uint8 color2 = _colorMap[0];
|
||||
|
||||
int cH = _height;
|
||||
while (cH--) {
|
||||
int cW = w;
|
||||
const uint8 *mtbl = _width == 8 ? renderMaskTable8 : renderMaskTable6;
|
||||
|
||||
for (bool runWidthLoop = true; runWidthLoop; ) {
|
||||
uint8 s = *src++;
|
||||
uint8 m = *mtbl++;
|
||||
|
||||
for (uint8 i = 0x80; i; i >>= 1) {
|
||||
if (!(m & i)) {
|
||||
runWidthLoop = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (s & i) {
|
||||
if (color1)
|
||||
*dst = color1;
|
||||
} else if (color2) {
|
||||
*dst = color2;
|
||||
}
|
||||
dst++;
|
||||
}
|
||||
|
||||
if (cW)
|
||||
cW--;
|
||||
else
|
||||
runWidthLoop = false;
|
||||
}
|
||||
|
||||
dst += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void OldDOSFont::unload() {
|
||||
delete[] _data;
|
||||
_data = 0;
|
||||
_width = _height = _numGlyphs = 0;
|
||||
_bitmapOffsets = 0;
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
105
engines/kyra/screen_eob.h
Normal file
105
engines/kyra/screen_eob.h
Normal file
@ -0,0 +1,105 @@
|
||||
/* 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_SCREEN_EOB_H
|
||||
#define KYRA_SCREEN_EOB_H
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#include "kyra/screen.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
class EobCoreEngine;
|
||||
class Screen_Eob : public Screen{
|
||||
public:
|
||||
Screen_Eob(EobCoreEngine *vm, OSystem *system);
|
||||
virtual ~Screen_Eob();
|
||||
|
||||
bool init();
|
||||
|
||||
void setScreenDim(int dim);
|
||||
const ScreenDim *getScreenDim(int dim);
|
||||
int curDimIndex() const { return _curDimIndex; }
|
||||
void modifyScreenDim(int dim, int x, int y, int w, int h);
|
||||
int screenDimTableCount() const { return _screenDimTableCount; }
|
||||
|
||||
void setClearScreenDim(int dim);
|
||||
void clearCurDim();
|
||||
|
||||
void setMouseCursor(int x, int y, const byte *shape);
|
||||
|
||||
void loadFileDataToPage(Common::SeekableReadStream *s, int pageNum, uint32 size);
|
||||
|
||||
void printShadedText(const char *string, int x, int y, int col1, int col2);
|
||||
void loadEobCpsFileToPage(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage);
|
||||
void loadEobBitmap(const char *file, int tempPage, int destPage);
|
||||
|
||||
uint8 *encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag = false);
|
||||
void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd = -1, int flags = 0, ...);
|
||||
const uint8 *scaleShape(const uint8 *shapeData, int blockDistance);
|
||||
const uint8 *scaleShapeStep(const uint8 *shp);
|
||||
void replaceShapePalette(uint8 *shp, const uint8 *pal);
|
||||
void applyShapeOverlay(uint8 *shp, int ovlIndex);
|
||||
|
||||
void setShapeFrame(int x1, int y1, int x2, int y2) { _dsX1 = x1; _dsY1 = y1; _dsX2 = x2; _dsY2 = y2; }
|
||||
void setShapeFadeMode (uint8 i, bool b) { if (!i || i == 1) _shapeFadeMode[i] = b; }
|
||||
|
||||
void fadeTextColor(Palette *pal, int color1, int fadeTextColor);
|
||||
bool delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate);
|
||||
|
||||
void setTextColorMap(const uint8 *cmap) {}
|
||||
int getRectSize(int w, int h) { return w * h; }
|
||||
|
||||
void setFadeTableIndex(int index) { _fadeDataIndex = (CLIP(index, 0, 7) << 8); }
|
||||
void createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight);
|
||||
uint8 *getFadeTable(int index) { return (index >= 0 && index < 5) ? &_fadeData[index << 8] : 0; }
|
||||
|
||||
protected:
|
||||
int16 _dsX1, _dsX2, _dsY1, _dsY2;
|
||||
bool _shapeFadeMode[2];
|
||||
uint16 _shapeFadeInternal;
|
||||
uint8 *_fadeData;
|
||||
int _fadeDataIndex;
|
||||
|
||||
uint8 *_dsTempPage;
|
||||
|
||||
static const ScreenDim _screenDimTable[];
|
||||
static const int _screenDimTableCount;
|
||||
|
||||
ScreenDim **_customDimTable;
|
||||
int _curDimIndex;
|
||||
|
||||
private:
|
||||
void drawShapeSetPixel(uint8 *dst, uint8 c);
|
||||
void scaleShapeProcessLine(uint8 *&dst, const uint8 *&src);
|
||||
|
||||
int _dsDiv, _dsRem, _dsScaleTmp;
|
||||
};
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -95,7 +95,7 @@ bool EMCInterpreter::callback(Common::IFFChunk &chunk) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EMCInterpreter::load(const char *filename, EMCData *scriptData, const Common::Array<const Opcode *> *opcodes) {
|
||||
bool EMCInterpreter::load(const char *filename, EMCData *scriptData, const Common::Array<const Opcode*> *opcodes) {
|
||||
Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename);
|
||||
if (!stream) {
|
||||
error("Couldn't open script file '%s'", filename);
|
||||
|
@ -41,7 +41,7 @@ struct EMCData {
|
||||
uint16 *ordr;
|
||||
uint16 dataSize;
|
||||
|
||||
const Common::Array<const Opcode *> *sysFuncs;
|
||||
const Common::Array<const Opcode*> *sysFuncs;
|
||||
};
|
||||
|
||||
struct EMCState {
|
||||
@ -92,7 +92,7 @@ class EMCInterpreter {
|
||||
public:
|
||||
EMCInterpreter(KyraEngine_v1 *vm);
|
||||
|
||||
bool load(const char *filename, EMCData *data, const Common::Array<const Opcode *> *opcodes);
|
||||
bool load(const char *filename, EMCData *data, const Common::Array<const Opcode*> *opcodes);
|
||||
void unload(EMCData *data);
|
||||
|
||||
void init(EMCState *scriptState, const EMCData *data);
|
||||
|
1528
engines/kyra/script_eob.cpp
Normal file
1528
engines/kyra/script_eob.cpp
Normal file
File diff suppressed because it is too large
Load Diff
121
engines/kyra/script_eob.h
Normal file
121
engines/kyra/script_eob.h
Normal file
@ -0,0 +1,121 @@
|
||||
/* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#ifndef KYRA_SCRIPT_EOB_H
|
||||
#define KYRA_SCRIPT_EOB_H
|
||||
|
||||
#include "common/func.h"
|
||||
#include "common/substream.h"
|
||||
#include "common/savefile.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
class LolEobBaseEngine;
|
||||
|
||||
class EobInfProcessor {
|
||||
public:
|
||||
EobInfProcessor(EobCoreEngine *engine, Screen_Eob *_screen);
|
||||
~EobInfProcessor();
|
||||
|
||||
void loadData(const uint8 *data, uint32 dataSize);
|
||||
void run(int func, int sub);
|
||||
|
||||
void setFlag(int flag) { _flagTable[17] |= flag; }
|
||||
bool checkFlag(int flag) { return (_flagTable[17] & flag) ? true : false; }
|
||||
|
||||
void loadState(Common::SeekableSubReadStreamEndian &in);
|
||||
void saveState(Common::OutSaveFile *out);
|
||||
|
||||
private:
|
||||
const char *getString(uint16 index);
|
||||
|
||||
int oeob_setWallType(int8 *data);
|
||||
int oeob_toggleWallState(int8 *data);
|
||||
int oeob_openDoor(int8 *data);
|
||||
int oeob_closeDoor(int8 *data);
|
||||
int oeob_replaceMonster(int8 *data);
|
||||
int oeob_movePartyOrObject(int8 *data);
|
||||
int oeob_moveInventoryItemToBlock(int8 *data);
|
||||
int oeob_printMessage_v1(int8 *data);
|
||||
int oeob_printMessage_v2(int8 *data);
|
||||
int oeob_setFlags(int8 *data);
|
||||
int oeob_playSoundEffect(int8 *data);
|
||||
int oeob_removeFlags(int8 *data);
|
||||
int oeob_modifyCharacterHitPoints(int8 *data);
|
||||
int oeob_calcAndInflictCharacterDamage(int8 *data);
|
||||
int oeob_jump(int8 *data);
|
||||
int oeob_end(int8 *data);
|
||||
int oeob_popPosAndReturn(int8 *data);
|
||||
int oeob_pushPosAndJump(int8 *data);
|
||||
int oeob_eval_v1(int8 *data);
|
||||
int oeob_eval_v2(int8 *data);
|
||||
int oeob_deleteItem(int8 *data);
|
||||
int oeob_loadNewLevelOrMonsters(int8 *data);
|
||||
int oeob_increasePartyExperience(int8 *data);
|
||||
int oeob_createItem_v1(int8 *data);
|
||||
int oeob_createItem_v2(int8 *data);
|
||||
int oeob_launchObject(int8 *data);
|
||||
int oeob_changeDirection(int8 *data);
|
||||
int oeob_identifyItems(int8 *data);
|
||||
int oeob_sequence(int8 *data);
|
||||
int oeob_delay(int8 *data);
|
||||
int oeob_drawScene(int8 *data);
|
||||
int oeob_dialogue(int8 *data);
|
||||
int oeob_specialEvent(int8 *data);
|
||||
|
||||
EobCoreEngine *_vm;
|
||||
Screen_Eob *_screen;
|
||||
|
||||
typedef Common::Functor1Mem<int8*, int, EobInfProcessor> InfProc;
|
||||
Common::Array<const InfProc*> _opcodes;
|
||||
|
||||
int8 *_scriptData;
|
||||
|
||||
uint8 _abortScript;
|
||||
uint16 _abortAfterSubroutine;
|
||||
int _dlgResult;
|
||||
uint8 _script2;
|
||||
|
||||
uint16 _lastScriptFunc;
|
||||
uint16 _lastScriptSub;
|
||||
|
||||
int8 **_scriptPosStack;
|
||||
int _scriptPosStackIndex;
|
||||
|
||||
uint32 *_flagTable;
|
||||
|
||||
int16 *_stack;
|
||||
int _stackIndex;
|
||||
|
||||
int8 _activeCharacter;
|
||||
|
||||
const int _commandMin;
|
||||
};
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_EOB
|
@ -1480,7 +1480,7 @@ typedef Common::Functor2Mem<const TIM *, const uint16 *, int, KyraEngine_HoF> TI
|
||||
#define OpcodeTimUnImpl() _timOpcodes.push_back(new TIMOpcodeV2(this, 0))
|
||||
|
||||
void KyraEngine_HoF::setupOpcodeTable() {
|
||||
Common::Array<const Opcode *> *table = 0;
|
||||
Common::Array<const Opcode*> *table = 0;
|
||||
|
||||
_opcodes.reserve(176);
|
||||
SetOpcodeTable(_opcodes);
|
||||
|
@ -1754,7 +1754,7 @@ typedef Common::Functor1Mem<EMCState *, int, KyraEngine_LoK> OpcodeV1;
|
||||
#define SetOpcodeTable(x) table = &x;
|
||||
#define Opcode(x) table->push_back(new OpcodeV1(this, &KyraEngine_LoK::x))
|
||||
void KyraEngine_LoK::setupOpcodeTable() {
|
||||
Common::Array<const Opcode *> *table = 0;
|
||||
Common::Array<const Opcode*> *table = 0;
|
||||
|
||||
_opcodes.reserve(157);
|
||||
SetOpcodeTable(_opcodes);
|
||||
|
@ -93,25 +93,6 @@ void LoLEngine::runLevelScriptCustom(int block, int flags, int charNum, int item
|
||||
checkSceneUpdateNeed(block);
|
||||
}
|
||||
|
||||
bool LoLEngine::checkSceneUpdateNeed(int func) {
|
||||
if (_sceneUpdateRequired)
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < 15; i++) {
|
||||
if (_visibleBlockIndex[i] == func) {
|
||||
_sceneUpdateRequired = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_currentBlock == func){
|
||||
_sceneUpdateRequired = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int LoLEngine::olol_setWallType(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setWallType(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
|
||||
if (stackPos(2) != -1) {
|
||||
@ -796,9 +777,9 @@ int LoLEngine::olol_updateBlockAnimations(EMCState *script) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LoLEngine::olol_mapShapeToBlock(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_mapShapeToBlock(%p) (%d)", (const void *)script, stackPos(0));
|
||||
return assignLevelShapes(stackPos(0));
|
||||
int LoLEngine::olol_assignLevelDecorationShape(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_assignLevelDecorationShape(%p) (%d)", (const void *)script, stackPos(0));
|
||||
return assignLevelDecorationShapes(stackPos(0));
|
||||
}
|
||||
|
||||
int LoLEngine::olol_resetBlockShapeAssignment(EMCState *script) {
|
||||
@ -830,11 +811,11 @@ int LoLEngine::olol_initMonster(EMCState *script) {
|
||||
return -1;
|
||||
|
||||
for (uint8 i = 0; i < 30; i++) {
|
||||
MonsterInPlay *l = &_monsters[i];
|
||||
LolMonsterInPlay *l = &_monsters[i];
|
||||
if (l->hitPoints || l->mode == 13)
|
||||
continue;
|
||||
|
||||
memset(l, 0, sizeof(MonsterInPlay));
|
||||
memset(l, 0, sizeof(LolMonsterInPlay));
|
||||
l->id = i;
|
||||
l->x = x;
|
||||
l->y = y;
|
||||
@ -945,7 +926,7 @@ int LoLEngine::olol_loadMonsterProperties(EMCState *script) {
|
||||
stackPos(28), stackPos(29), stackPos(30), stackPos(31), stackPos(32), stackPos(33), stackPos(34),
|
||||
stackPos(35), stackPos(36), stackPos(37), stackPos(38), stackPos(39), stackPos(40), stackPos(41));
|
||||
|
||||
MonsterProperty *l = &_monsterProperties[stackPos(0)];
|
||||
LolMonsterProperty *l = &_monsterProperties[stackPos(0)];
|
||||
l->shapeIndex = stackPos(1) & 0xff;
|
||||
|
||||
int shpWidthMax = 0;
|
||||
@ -1017,7 +998,7 @@ int LoLEngine::olol_inflictDamage(EMCState *script) {
|
||||
|
||||
int LoLEngine::olol_moveMonster(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveMonster(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
|
||||
MonsterInPlay *m = &_monsters[stackPos(0)];
|
||||
LolMonsterInPlay *m = &_monsters[stackPos(0)];
|
||||
|
||||
if (m->mode == 1 || m->mode == 2) {
|
||||
calcCoordinates(m->destX, m->destY, stackPos(1), stackPos(2), stackPos(3));
|
||||
@ -1029,10 +1010,9 @@ int LoLEngine::olol_moveMonster(EMCState *script) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoLEngine::olol_dialogueBox(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_dialogueBox(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
|
||||
|
||||
_tim->drawDialogueBox(stackPos(0), getLangString(stackPos(1)), getLangString(stackPos(2)), getLangString(stackPos(3)));
|
||||
int LoLEngine::olol_setupDialogueButtons(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setupDialogueButtons(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
|
||||
setupDialogueButtons(stackPos(0), getLangString(stackPos(1)), getLangString(stackPos(2)), getLangString(stackPos(3)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1194,7 +1174,7 @@ int LoLEngine::olol_playSoundEffect(EMCState *script) {
|
||||
|
||||
int LoLEngine::olol_processDialogue(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_processDialogue(%p)", (const void *)script);
|
||||
return _tim->processDialogue();
|
||||
return processDialogue();
|
||||
}
|
||||
|
||||
int LoLEngine::olol_stopTimScript(EMCState *script) {
|
||||
@ -1213,7 +1193,7 @@ int LoLEngine::olol_changeMonsterStat(EMCState *script) {
|
||||
if (stackPos(0) == -1)
|
||||
return 1;
|
||||
|
||||
MonsterInPlay *m = &_monsters[stackPos(0) & 0x7fff];
|
||||
LolMonsterInPlay *m = &_monsters[stackPos(0) & 0x7fff];
|
||||
|
||||
int16 d = stackPos(2);
|
||||
uint16 x = 0;
|
||||
@ -1254,7 +1234,7 @@ int LoLEngine::olol_getMonsterStat(EMCState *script) {
|
||||
if (stackPos(0) == -1)
|
||||
return 0;
|
||||
|
||||
MonsterInPlay *m = &_monsters[stackPos(0) & 0x7fff];
|
||||
LolMonsterInPlay *m = &_monsters[stackPos(0) & 0x7fff];
|
||||
int d = stackPos(1);
|
||||
|
||||
switch (d) {
|
||||
@ -1567,7 +1547,7 @@ int LoLEngine::olol_moveBlockObjects(EMCState *script) {
|
||||
|
||||
l &= 0x7fff;
|
||||
|
||||
MonsterInPlay *m = &_monsters[l];
|
||||
LolMonsterInPlay *m = &_monsters[l];
|
||||
|
||||
setMonsterMode(m, 14);
|
||||
checkSceneUpdateNeed(m->block);
|
||||
@ -1582,8 +1562,8 @@ int LoLEngine::olol_moveBlockObjects(EMCState *script) {
|
||||
placeMoveLevelItem(l, level, destBlock, _itemsInPlay[l].x & 0xff, _itemsInPlay[l].y & 0xff, _itemsInPlay[l].flyingHeight);
|
||||
res = 1;
|
||||
|
||||
if (!runScript || level != _currentLevel)
|
||||
continue;
|
||||
if (!runScript || level != _currentLevel)
|
||||
continue;
|
||||
|
||||
runLevelScriptCustom(destBlock, 0x80, -1, l, 0, 0);
|
||||
}
|
||||
@ -1638,7 +1618,7 @@ int LoLEngine::olol_dummy1(EMCState *script) {
|
||||
|
||||
int LoLEngine::olol_suspendMonster(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_suspendMonster(%p) (%d)", (const void *)script, stackPos(0));
|
||||
MonsterInPlay *m = &_monsters[stackPos(0) & 0x7fff];
|
||||
LolMonsterInPlay *m = &_monsters[stackPos(0) & 0x7fff];
|
||||
setMonsterMode(m, 14);
|
||||
checkSceneUpdateNeed(m->block);
|
||||
placeMonster(m, 0, 0);
|
||||
@ -1889,9 +1869,9 @@ int LoLEngine::olol_checkBlockForMonster(EMCState *script) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int LoLEngine::olol_transformRegion(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_transformRegion(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
|
||||
transformRegion(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
|
||||
int LoLEngine::olol_crossFadeRegion(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_crossFadeRegion(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
|
||||
_screen->crossFadeRegion(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1984,7 +1964,7 @@ int LoLEngine::olol_getAnimationLastPart(EMCState *script) {
|
||||
int LoLEngine::olol_assignSpecialGuiShape(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_assignSpecialGuiShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
|
||||
if (stackPos(0)) {
|
||||
_specialGuiShape = _levelShapes[_levelShapeProperties[_wllShapeMap[stackPos(0)]].shapeIndex[stackPos(1)]];
|
||||
_specialGuiShape = _levelDecorationShapes[_levelDecorationProperties[_wllShapeMap[stackPos(0)]].shapeIndex[stackPos(1)]];
|
||||
_specialGuiShapeX = stackPos(2);
|
||||
_specialGuiShapeY = stackPos(3);
|
||||
_specialGuiShapeMirrorFlag = stackPos(4);
|
||||
@ -2291,10 +2271,10 @@ int LoLEngine::olol_calcNewBlockPosition(EMCState *script) {
|
||||
return calcNewBlockPosition(stackPos(0), stackPos(1));
|
||||
}
|
||||
|
||||
int LoLEngine::olol_fadeScene(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_fadeScene(%p)", (const void *)script);
|
||||
int LoLEngine::olol_crossFadeScene(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_crossFadeScene(%p)", (const void *)script);
|
||||
gui_drawScene(2);
|
||||
transformRegion(112, 0, 112, 0, 176, 120, 2, 0);
|
||||
_screen->crossFadeRegion(112, 0, 112, 0, 176, 120, 2, 0);
|
||||
updateDrawPage2();
|
||||
return 1;
|
||||
}
|
||||
@ -2700,7 +2680,7 @@ typedef Common::Functor2Mem<const TIM *, const uint16 *, int, LoLEngine> TIMOpco
|
||||
#define OpcodeTimUnImpl() timTable->push_back(new TIMOpcodeLoL(this, 0))
|
||||
|
||||
void LoLEngine::setupOpcodeTable() {
|
||||
Common::Array<const Opcode *> *table = 0;
|
||||
Common::Array<const Opcode*> *table = 0;
|
||||
|
||||
_opcodes.reserve(192);
|
||||
SetOpcodeTable(_opcodes);
|
||||
@ -2784,7 +2764,7 @@ void LoLEngine::setupOpcodeTable() {
|
||||
|
||||
// 0x34
|
||||
Opcode(olol_updateBlockAnimations);
|
||||
Opcode(olol_mapShapeToBlock);
|
||||
Opcode(olol_assignLevelDecorationShape);
|
||||
Opcode(olol_resetBlockShapeAssignment);
|
||||
Opcode(olol_copyRegion);
|
||||
|
||||
@ -2808,7 +2788,7 @@ void LoLEngine::setupOpcodeTable() {
|
||||
|
||||
// 0x44
|
||||
Opcode(olol_moveMonster);
|
||||
Opcode(olol_dialogueBox);
|
||||
Opcode(olol_setupDialogueButtons);
|
||||
Opcode(olol_giveTakeMoney);
|
||||
Opcode(olol_checkMoney);
|
||||
|
||||
@ -2933,7 +2913,7 @@ void LoLEngine::setupOpcodeTable() {
|
||||
Opcode(olol_checkBlockForMonster);
|
||||
|
||||
// 0x98
|
||||
Opcode(olol_transformRegion);
|
||||
Opcode(olol_crossFadeRegion);
|
||||
Opcode(olol_calcCoordinatesAddDirectionOffset);
|
||||
Opcode(olol_resetPortraitsAndDisableSysTimer);
|
||||
Opcode(olol_enableSysTimer);
|
||||
@ -2981,7 +2961,7 @@ void LoLEngine::setupOpcodeTable() {
|
||||
Opcode(olol_calcNewBlockPosition);
|
||||
|
||||
// 0xB8
|
||||
Opcode(olol_fadeScene);
|
||||
Opcode(olol_crossFadeScene);
|
||||
Opcode(olol_updateDrawPage2);
|
||||
Opcode(olol_setMouseCursor);
|
||||
Opcode(olol_characterSays);
|
||||
@ -2992,7 +2972,7 @@ void LoLEngine::setupOpcodeTable() {
|
||||
Opcode(olol_getLanguage);
|
||||
Opcode(olol_dummy0);
|
||||
|
||||
Common::Array<const TIMOpcode *> *timTable = 0;
|
||||
Common::Array<const TIMOpcode*> *timTable = 0;
|
||||
|
||||
_timIntroOpcodes.reserve(8);
|
||||
SetTimOpcodeTable(_timIntroOpcodes);
|
||||
|
@ -1129,7 +1129,7 @@ typedef Common::Functor1Mem<EMCState *, int, KyraEngine_MR> OpcodeV3;
|
||||
#define Opcode(x) table->push_back(new OpcodeV3(this, &KyraEngine_MR::x))
|
||||
#define OpcodeUnImpl() table->push_back(new OpcodeV3(this, 0))
|
||||
void KyraEngine_MR::setupOpcodeTable() {
|
||||
Common::Array<const Opcode *> *table = 0;
|
||||
Common::Array<const Opcode*> *table = 0;
|
||||
|
||||
_opcodes.reserve(176);
|
||||
SetOpcodeTable(_opcodes);
|
||||
|
@ -135,7 +135,7 @@ bool TIMInterpreter::callback(Common::IFFChunk &chunk) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpcode *> *opcodes) {
|
||||
TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes) {
|
||||
if (!_vm->resource()->exists(filename))
|
||||
return 0;
|
||||
|
||||
@ -833,18 +833,6 @@ int TIMInterpreter::cmd_stopFuncNow(const uint16 *param) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int TIMInterpreter::cmd_stopAllFuncs(const uint16 *param) {
|
||||
while (_currentTim->dlgFunc == -1 && _currentTim->clickedButton == 0 && !_vm->shouldQuit()) {
|
||||
update();
|
||||
_currentTim->clickedButton = processDialogue();
|
||||
}
|
||||
|
||||
for (int i = 0; i < TIM::kCountFuncs; ++i)
|
||||
_currentTim->func[i].ip = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: Consider moving to another file
|
||||
|
||||
#ifdef ENABLE_LOL
|
||||
@ -908,9 +896,6 @@ TIMInterpreter_LoL::TIMInterpreter_LoL(LoLEngine *engine, Screen_v2 *screen_v2,
|
||||
_animator = new TimAnimator(engine, screen_v2, system, true);
|
||||
|
||||
_drawPage2 = 0;
|
||||
|
||||
memset(_dialogueButtonString, 0, 3 * sizeof(const char *));
|
||||
_dialogueButtonPosX = _dialogueButtonPosY = _dialogueNumButtons = _dialogueButtonXoffs = _dialogueHighlightedButton = 0;
|
||||
}
|
||||
|
||||
int TIMInterpreter_LoL::initAnimStruct(int index, const char *filename, int x, int y, int frameDelay, int, uint16 wsaFlags) {
|
||||
@ -978,157 +963,12 @@ void TIMInterpreter_LoL::advanceToOpcode(int opcode) {
|
||||
f->nextTime = _system->getMillis();
|
||||
}
|
||||
|
||||
void TIMInterpreter_LoL::drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {
|
||||
_screen->setScreenDim(5);
|
||||
|
||||
if (numStr == 1 && _vm->speechEnabled()) {
|
||||
_dialogueNumButtons = 0;
|
||||
_dialogueButtonString[0] = _dialogueButtonString[1] = _dialogueButtonString[2] = 0;
|
||||
} else {
|
||||
_dialogueNumButtons = numStr;
|
||||
_dialogueButtonString[0] = s1;
|
||||
_dialogueButtonString[1] = s2;
|
||||
_dialogueButtonString[2] = s3;
|
||||
_dialogueHighlightedButton = 0;
|
||||
|
||||
const ScreenDim *d = _screen->getScreenDim(5);
|
||||
_dialogueButtonPosY = d->sy + d->h - 9;
|
||||
|
||||
if (numStr == 1) {
|
||||
_dialogueButtonXoffs = 0;
|
||||
_dialogueButtonPosX = d->sx + d->w - 77;
|
||||
} else {
|
||||
_dialogueButtonXoffs = d->w / numStr;
|
||||
_dialogueButtonPosX = d->sx + (_dialogueButtonXoffs >> 1) - 37;
|
||||
}
|
||||
|
||||
drawDialogueButtons();
|
||||
}
|
||||
|
||||
if (!_vm->shouldQuit())
|
||||
_vm->removeInputTop();
|
||||
}
|
||||
|
||||
void TIMInterpreter_LoL::drawDialogueButtons() {
|
||||
int cp = _screen->setCurPage(0);
|
||||
Screen::FontId of = _screen->setFont(_vm->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
|
||||
|
||||
int x = _dialogueButtonPosX;
|
||||
|
||||
for (int i = 0; i < _dialogueNumButtons; i++) {
|
||||
if (_vm->gameFlags().use16ColorMode) {
|
||||
_vm->gui_drawBox(x, (_dialogueButtonPosY & ~7) - 1, 74, 10, 0xee, 0xcc, -1);
|
||||
_screen->printText(_dialogueButtonString[i], (x + 37 - (_screen->getTextWidth(_dialogueButtonString[i])) / 2) & ~3,
|
||||
(_dialogueButtonPosY + 2) & ~7, _dialogueHighlightedButton == i ? 0xc1 : 0xe1, 0);
|
||||
} else {
|
||||
_vm->gui_drawBox(x, _dialogueButtonPosY, 74, 9, 136, 251, -1);
|
||||
_screen->printText(_dialogueButtonString[i], x + 37 - (_screen->getTextWidth(_dialogueButtonString[i])) / 2,
|
||||
_dialogueButtonPosY + 2, _dialogueHighlightedButton == i ? 144 : 254, 0);
|
||||
}
|
||||
|
||||
x += _dialogueButtonXoffs;
|
||||
}
|
||||
_screen->setFont(of);
|
||||
_screen->setCurPage(cp);
|
||||
}
|
||||
|
||||
uint16 TIMInterpreter_LoL::processDialogue() {
|
||||
int df = _dialogueHighlightedButton;
|
||||
int res = 0;
|
||||
int x = _dialogueButtonPosX;
|
||||
int y = (_vm->gameFlags().use16ColorMode ? (_dialogueButtonPosY & ~7) - 1 : _dialogueButtonPosY);
|
||||
|
||||
for (int i = 0; i < _dialogueNumButtons; i++) {
|
||||
Common::Point p = _vm->getMousePos();
|
||||
if (_vm->posWithinRect(p.x, p.y, x, y, x + 74, y + 9)) {
|
||||
_dialogueHighlightedButton = i;
|
||||
break;
|
||||
}
|
||||
x += _dialogueButtonXoffs;
|
||||
}
|
||||
|
||||
if (_dialogueNumButtons == 0) {
|
||||
int e = _vm->checkInput(0, false) & 0xFF;
|
||||
_vm->removeInputTop();
|
||||
|
||||
if (e) {
|
||||
_vm->gui_notifyButtonListChanged();
|
||||
|
||||
if (e == 43 || e == 61) {
|
||||
_vm->snd_stopSpeech(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (_vm->snd_updateCharacterSpeech() != 2) {
|
||||
res = 1;
|
||||
if (!_vm->shouldQuit()) {
|
||||
_vm->removeInputTop();
|
||||
_vm->gui_notifyButtonListChanged();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int e = _vm->checkInput(0, false) & 0xFF;
|
||||
_vm->removeInputTop();
|
||||
if (e)
|
||||
_vm->gui_notifyButtonListChanged();
|
||||
|
||||
if (e == 200 || e == 202) {
|
||||
x = _dialogueButtonPosX;
|
||||
|
||||
for (int i = 0; i < _dialogueNumButtons; i++) {
|
||||
Common::Point p = _vm->getMousePos();
|
||||
if (_vm->posWithinRect(p.x, p.y, x, y, x + 74, y + 9)) {
|
||||
_dialogueHighlightedButton = i;
|
||||
res = _dialogueHighlightedButton + 1;
|
||||
break;
|
||||
}
|
||||
x += _dialogueButtonXoffs;
|
||||
}
|
||||
} else if (e == _vm->_keyMap[Common::KEYCODE_SPACE] || e == _vm->_keyMap[Common::KEYCODE_RETURN]) {
|
||||
_vm->snd_stopSpeech(true);
|
||||
res = _dialogueHighlightedButton + 1;
|
||||
} else if (e == _vm->_keyMap[Common::KEYCODE_LEFT] || e == _vm->_keyMap[Common::KEYCODE_DOWN]) {
|
||||
if (_dialogueNumButtons > 1 && _dialogueHighlightedButton > 0)
|
||||
_dialogueHighlightedButton--;
|
||||
} else if (e == _vm->_keyMap[Common::KEYCODE_RIGHT] || e == _vm->_keyMap[Common::KEYCODE_UP]) {
|
||||
if (_dialogueNumButtons > 1 && _dialogueHighlightedButton < (_dialogueNumButtons - 1))
|
||||
_dialogueHighlightedButton++;
|
||||
}
|
||||
}
|
||||
|
||||
if (df != _dialogueHighlightedButton)
|
||||
drawDialogueButtons();
|
||||
|
||||
_screen->updateScreen();
|
||||
|
||||
if (res == 0)
|
||||
return 0;
|
||||
|
||||
_vm->stopPortraitSpeechAnim();
|
||||
|
||||
if (!_vm->textEnabled() && _vm->_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 (_vm->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);
|
||||
_vm->_txt->clearDim(4);
|
||||
_vm->_txt->resetDimTextPositions(4);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void TIMInterpreter_LoL::resetDialogueState(TIM *tim) {
|
||||
if (!tim)
|
||||
return;
|
||||
|
||||
tim->procFunc = 0;
|
||||
tim->procParam = _dialogueNumButtons ? _dialogueNumButtons : 1;
|
||||
tim->procParam = _vm->_dialogueNumButtons ? _vm->_dialogueNumButtons : 1;
|
||||
tim->clickedButton = 0;
|
||||
tim->dlgFunc = -1;
|
||||
}
|
||||
@ -1168,6 +1008,18 @@ int TIMInterpreter_LoL::execCommand(int cmd, const uint16 *param) {
|
||||
return (this->*_commands[cmd].proc)(param);
|
||||
}
|
||||
|
||||
int TIMInterpreter_LoL::cmd_stopAllFuncs(const uint16 *param) {
|
||||
while (_currentTim->dlgFunc == -1 && _currentTim->clickedButton == 0 && !_vm->shouldQuit()) {
|
||||
update();
|
||||
_currentTim->clickedButton = _vm->processDialogue();
|
||||
}
|
||||
|
||||
for (int i = 0; i < TIM::kCountFuncs; ++i)
|
||||
_currentTim->func[i].ip = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int TIMInterpreter_LoL::cmd_setLoopIp(const uint16 *param) {
|
||||
if (_vm->speechEnabled()) {
|
||||
if (_vm->snd_updateCharacterSpeech() == 2)
|
||||
@ -1201,7 +1053,7 @@ int TIMInterpreter_LoL::cmd_continueLoop(const uint16 *param) {
|
||||
}
|
||||
|
||||
int TIMInterpreter_LoL::cmd_processDialogue(const uint16 *param) {
|
||||
int res = processDialogue();
|
||||
int res = _vm->processDialogue();
|
||||
if (!res || !_currentTim->procParam)
|
||||
return res;
|
||||
|
||||
@ -1238,7 +1090,7 @@ int TIMInterpreter_LoL::cmd_dialogueBox(const uint16 *param) {
|
||||
}
|
||||
}
|
||||
|
||||
drawDialogueBox(cnt, tmpStr[0], tmpStr[1], tmpStr[2]);
|
||||
_vm->setupDialogueButtons(cnt, tmpStr[0], tmpStr[1], tmpStr[2]);
|
||||
_vm->gui_notifyButtonListChanged();
|
||||
|
||||
return -3;
|
||||
|
@ -146,7 +146,7 @@ struct TIM {
|
||||
uint16 *avtl;
|
||||
uint8 *text;
|
||||
|
||||
const Common::Array<const TIMOpcode *> *opcodes;
|
||||
const Common::Array<const TIMOpcode*> *opcodes;
|
||||
|
||||
// TODO: Get rid of this ugly HACK to allow the
|
||||
// Lands of Lore outro to be working properly.
|
||||
@ -159,7 +159,7 @@ public:
|
||||
TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSystem *system);
|
||||
virtual ~TIMInterpreter();
|
||||
|
||||
TIM *load(const char *filename, const Common::Array<const TIMOpcode *> *opcodes);
|
||||
TIM *load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes);
|
||||
void unload(TIM *&tim) const;
|
||||
|
||||
bool callback(Common::IFFChunk &chunk);
|
||||
@ -186,8 +186,6 @@ public:
|
||||
void displayText(uint16 textId, int16 flags, uint8 color);
|
||||
void setupTextPalette(uint index, int fadePalette);
|
||||
|
||||
virtual void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {}
|
||||
virtual uint16 processDialogue() { return 1; }
|
||||
virtual void resetDialogueState(TIM *tim) {}
|
||||
|
||||
int _drawPage2;
|
||||
@ -255,7 +253,6 @@ protected:
|
||||
int cmd_execOpcode(const uint16 *param);
|
||||
int cmd_initFuncNow(const uint16 *param);
|
||||
int cmd_stopFuncNow(const uint16 *param);
|
||||
int cmd_stopAllFuncs(const uint16 *param);
|
||||
#define cmd_return(n, v) \
|
||||
int cmd_return_##n(const uint16 *){ return v; }
|
||||
cmd_return( 1, 1)
|
||||
@ -273,8 +270,6 @@ public:
|
||||
int initAnimStruct(int index, const char *filename, int x, int y, int frameDelay, int, uint16 wsaCopyParams);
|
||||
int freeAnimStruct(int index);
|
||||
|
||||
void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3);
|
||||
uint16 processDialogue();
|
||||
void resetDialogueState(TIM *tim);
|
||||
|
||||
private:
|
||||
@ -284,18 +279,9 @@ private:
|
||||
char *getTableString(int id);
|
||||
void advanceToOpcode(int opcode);
|
||||
|
||||
void drawDialogueButtons();
|
||||
|
||||
LoLEngine *_vm;
|
||||
Screen_LoL *_screen;
|
||||
|
||||
const char *_dialogueButtonString[3];
|
||||
uint16 _dialogueButtonPosX;
|
||||
uint16 _dialogueButtonPosY;
|
||||
int _dialogueNumButtons;
|
||||
uint16 _dialogueButtonXoffs;
|
||||
int _dialogueHighlightedButton;
|
||||
|
||||
virtual int execCommand(int cmd, const uint16 *param);
|
||||
|
||||
typedef int (TIMInterpreter_LoL::*CommandProc)(const uint16 *);
|
||||
@ -307,6 +293,7 @@ private:
|
||||
const CommandEntry *_commands;
|
||||
int _commandsSize;
|
||||
|
||||
int cmd_stopAllFuncs(const uint16 *param);
|
||||
int cmd_setLoopIp(const uint16 *param);
|
||||
int cmd_continueLoop(const uint16 *param);
|
||||
int cmd_processDialogue(const uint16 *param);
|
||||
|
140
engines/kyra/sequences_eob1.cpp
Normal file
140
engines/kyra/sequences_eob1.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#include "kyra/eob1.h"
|
||||
#include "kyra/screen_eob.h"
|
||||
#include "kyra/resource.h"
|
||||
#include "kyra/sound.h"
|
||||
|
||||
#include "common/system.h"
|
||||
|
||||
#include "base/version.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
int EobEngine::mainMenu() {
|
||||
int menuChoice = 4;
|
||||
|
||||
Screen::FontId of = _screen->_currentFont;
|
||||
Common::SeekableReadStream *s = 0;
|
||||
|
||||
while (menuChoice >= 0 && !shouldQuit()) {
|
||||
switch (menuChoice) {
|
||||
case 0:
|
||||
_screen->loadPalette("EOBPAL.COL", _screen->getPalette(0));
|
||||
_screen->loadEobCpsFileToPage("INTRO", 0, 5, 3, 2);
|
||||
_screen->setScreenPalette(_screen->getPalette(0));
|
||||
_screen->_curPage = 2;
|
||||
of = _screen->setFont(Screen::FID_6_FNT);
|
||||
_screen->printText(gScummVMVersion, 280 - strlen(gScummVMVersion) * 6, 153, _screen->getPagePixel(2, 0, 0), 0);
|
||||
_screen->setFont(of);
|
||||
_screen->fillRect(0, 159, 319, 199, _screen->getPagePixel(2, 0, 0));
|
||||
gui_drawBox(77, 165, 173, 29, 13, 14, 12);
|
||||
gui_drawBox(76, 164, 175, 31, 13, 14, -1);
|
||||
_screen->_curPage = 0;
|
||||
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
|
||||
_screen->updateScreen();
|
||||
menuChoice = mainMenuLoop();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// load game in progress
|
||||
//
|
||||
menuChoice = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// create new party
|
||||
menuChoice = -2;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// quit
|
||||
menuChoice = -5;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// intro
|
||||
_sound->loadSoundFile("SOUND");
|
||||
_screen->hideMouse();
|
||||
seq_playOpeningCredits();
|
||||
seq_playIntro();
|
||||
_screen->showMouse();
|
||||
_sound->loadSoundFile("ADLIB");
|
||||
menuChoice = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return shouldQuit() ? -5 : menuChoice;
|
||||
}
|
||||
|
||||
int EobEngine::mainMenuLoop() {
|
||||
int sel = -1;
|
||||
do {
|
||||
_screen->setScreenDim(28);
|
||||
_gui->setupMenu(8, 0, _mainMenuStrings, -1, 0, 0);
|
||||
|
||||
while (sel == -1 && !shouldQuit())
|
||||
sel = _gui->handleMenu(8, _mainMenuStrings, 0, -1, 0);
|
||||
} while ((sel < 0 || sel > 5) && !shouldQuit());
|
||||
|
||||
return sel + 1;
|
||||
}
|
||||
|
||||
void EobEngine::seq_playOpeningCredits() {
|
||||
static const char *cmpList[] = { "WESTWOOD.CMP", "AND.CMP", "SSI.CMP", "PRESENT.CMP", "DAND.CMP" };
|
||||
static const uint8 frameDelay[] = { 140, 50, 100, 50, 140 };
|
||||
|
||||
_screen->loadPalette("WESTWOOD.COL", _screen->getPalette(0));
|
||||
_screen->setScreenPalette(_screen->getPalette(0));
|
||||
|
||||
_screen->loadBitmap(cmpList[0], 5, 3, 0);
|
||||
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
|
||||
_screen->updateScreen();
|
||||
|
||||
_sound->playTrack(1);
|
||||
delay(frameDelay[0] * _tickLength);
|
||||
|
||||
for (int i = 1; i < 5 && !shouldQuit() && !skipFlag(); i++) {
|
||||
_screen->loadBitmap(cmpList[i], 5, 3, 0);
|
||||
uint32 nextFrameTimer = _system->getMillis() + frameDelay[i] * _tickLength;
|
||||
_screen->crossFadeRegion(0, 50, 0, 50, 320, 102, 2, 0);
|
||||
delayUntil(nextFrameTimer);
|
||||
}
|
||||
|
||||
delay(50 * _tickLength);
|
||||
}
|
||||
|
||||
void EobEngine::seq_playIntro() {
|
||||
//_sound->playTrack(2);
|
||||
}
|
||||
|
||||
void EobEngine::seq_playFinale() {
|
||||
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
1277
engines/kyra/sequences_eob2.cpp
Normal file
1277
engines/kyra/sequences_eob2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -266,7 +266,7 @@ void KyraEngine_v1::snd_playTheme(int file, int track) {
|
||||
}
|
||||
|
||||
void KyraEngine_v1::snd_playSoundEffect(int track, int volume) {
|
||||
_sound->playSoundEffect(track);
|
||||
_sound->playSoundEffect(track, volume);
|
||||
}
|
||||
|
||||
void KyraEngine_v1::snd_playWanderScoreViaMap(int command, int restart) {
|
||||
|
@ -197,24 +197,9 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) {
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
|
||||
if (!_sound->sfxEnabled() || shouldQuit())
|
||||
return;
|
||||
|
||||
if (_environmentSfx)
|
||||
snd_playSoundEffect(_environmentSfx, _environmentSfxVol);
|
||||
|
||||
int dist = 0;
|
||||
if (block) {
|
||||
dist = getMonsterDistance(_currentBlock, block);
|
||||
if (dist > _envSfxDistThreshold) {
|
||||
_environmentSfx = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_environmentSfx = soundId;
|
||||
_environmentSfxVol = (15 - ((block || dist < 2) ? dist : 0)) << 4;
|
||||
bool LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
|
||||
if (!LolEobBaseEngine::snd_processEnvironmentalSoundEffect(soundId, block))
|
||||
return false;
|
||||
|
||||
if (block != _currentBlock) {
|
||||
static const int8 blockShiftTable[] = { -32, -31, 1, 33, 32, 31, -1, -33 };
|
||||
@ -231,9 +216,9 @@ void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
|
||||
}
|
||||
|
||||
if (!soundId || _sceneUpdateRequired)
|
||||
return;
|
||||
return false;
|
||||
|
||||
snd_processEnvironmentalSoundEffect(0, 0);
|
||||
return snd_processEnvironmentalSoundEffect(0, 0);
|
||||
}
|
||||
|
||||
void LoLEngine::snd_queueEnvironmentalSoundEffect(int soundId, int block) {
|
||||
|
1249
engines/kyra/sprites_eob.cpp
Normal file
1249
engines/kyra/sprites_eob.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -59,7 +59,7 @@ void LoLEngine::loadMonsterShapes(const char *file, int monsterIndex, int animTy
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int ii = 0; ii < 16; ii++) {
|
||||
uint8 **of = &_monsterShapesEx[monsterIndex * 192 + i * 48 + ii * 3];
|
||||
uint8 **of = &_monsterDecorationShapes[monsterIndex * 192 + i * 48 + ii * 3];
|
||||
int s = (i << 4) + ii + 17;
|
||||
of[0] = _screen->makeShapeCopy(p, s);
|
||||
of[1] = _screen->makeShapeCopy(p, s + 1);
|
||||
@ -140,9 +140,9 @@ void LoLEngine::releaseMonsterShapes(int monsterIndex) {
|
||||
|
||||
for (int i = 0; i < 192; i++) {
|
||||
int pos = (monsterIndex * 192) + i;
|
||||
if (_monsterShapesEx[pos]) {
|
||||
delete[] _monsterShapesEx[pos];
|
||||
_monsterShapesEx[pos] = 0;
|
||||
if (_monsterDecorationShapes[pos]) {
|
||||
delete[] _monsterDecorationShapes[pos];
|
||||
_monsterDecorationShapes[pos] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -159,7 +159,7 @@ int LoLEngine::deleteMonstersFromBlock(int block) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MonsterInPlay *m = &_monsters[i & 0x7fff];
|
||||
LolMonsterInPlay *m = &_monsters[i & 0x7fff];
|
||||
|
||||
cnt++;
|
||||
setMonsterMode(m, 14);
|
||||
@ -173,7 +173,7 @@ int LoLEngine::deleteMonstersFromBlock(int block) {
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void LoLEngine::setMonsterMode(MonsterInPlay *monster, int mode) {
|
||||
void LoLEngine::setMonsterMode(LolMonsterInPlay *monster, int mode) {
|
||||
if (monster->mode == 13 && mode != 14)
|
||||
return;
|
||||
|
||||
@ -210,7 +210,7 @@ void LoLEngine::setMonsterMode(MonsterInPlay *monster, int mode) {
|
||||
}
|
||||
}
|
||||
|
||||
bool LoLEngine::updateMonsterAdjustBlocks(MonsterInPlay *monster) {
|
||||
bool LoLEngine::updateMonsterAdjustBlocks(LolMonsterInPlay *monster) {
|
||||
static const uint8 dims[] = { 0, 13, 9, 3 };
|
||||
if (monster->properties->flags & 8)
|
||||
return true;
|
||||
@ -251,7 +251,7 @@ bool LoLEngine::updateMonsterAdjustBlocks(MonsterInPlay *monster) {
|
||||
return (fx1 >= fx2) ? false : true;
|
||||
}
|
||||
|
||||
void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) {
|
||||
void LoLEngine::placeMonster(LolMonsterInPlay *monster, uint16 x, uint16 y) {
|
||||
bool cont = true;
|
||||
int t = monster->block;
|
||||
if (monster->block) {
|
||||
@ -329,7 +329,7 @@ int LoLEngine::calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2)
|
||||
return retVal[r];
|
||||
}
|
||||
|
||||
void LoLEngine::setMonsterDirection(MonsterInPlay *monster, int dir) {
|
||||
void LoLEngine::setMonsterDirection(LolMonsterInPlay *monster, int dir) {
|
||||
monster->direction = dir;
|
||||
|
||||
if (!(dir & 1) || ((monster->direction - (monster->facing << 1)) >= 2))
|
||||
@ -338,7 +338,7 @@ void LoLEngine::setMonsterDirection(MonsterInPlay *monster, int dir) {
|
||||
checkSceneUpdateNeed(monster->block);
|
||||
}
|
||||
|
||||
void LoLEngine::monsterDropItems(MonsterInPlay *monster) {
|
||||
void LoLEngine::monsterDropItems(LolMonsterInPlay *monster) {
|
||||
uint16 a = monster->assignedItems;
|
||||
while (a) {
|
||||
uint16 b = a;
|
||||
@ -503,7 +503,7 @@ int LoLEngine::checkBlockForWallsAndSufficientSpace(int block, int x, int y, int
|
||||
|
||||
uint16 b = _levelBlockProperties[block].assignedObjects;
|
||||
while (b & 0x8000) {
|
||||
MonsterInPlay *monster = &_monsters[b & 0x7fff];
|
||||
LolMonsterInPlay *monster = &_monsters[b & 0x7fff];
|
||||
|
||||
if (monster->mode < 13) {
|
||||
int r = checkDrawObjectSpace(x, y, monster->x, monster->y);
|
||||
@ -645,7 +645,7 @@ void LoLEngine::drawBlockObjects(int blockArrayIndex) {
|
||||
}
|
||||
|
||||
void LoLEngine::drawMonster(uint16 id) {
|
||||
MonsterInPlay *m = &_monsters[id];
|
||||
LolMonsterInPlay *m = &_monsters[id];
|
||||
int16 flg = _monsterDirFlags[(_currentDirection << 2) + m->facing];
|
||||
int curFrm = getMonsterCurFrame(m, flg & 0xffef);
|
||||
uint8 *shp = 0;
|
||||
@ -670,7 +670,7 @@ void LoLEngine::drawMonster(uint16 id) {
|
||||
if (v == -1)
|
||||
break;
|
||||
|
||||
uint8 *shp2 = _monsterShapesEx[m->properties->shapeIndex * 192 + v * 48 + curFrm * 3];
|
||||
uint8 *shp2 = _monsterDecorationShapes[m->properties->shapeIndex * 192 + v * 48 + curFrm * 3];
|
||||
if (!shp2)
|
||||
continue;
|
||||
|
||||
@ -721,7 +721,7 @@ void LoLEngine::drawMonster(uint16 id) {
|
||||
delete[] tbl;
|
||||
}
|
||||
|
||||
int LoLEngine::getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags) {
|
||||
int LoLEngine::getMonsterCurFrame(LolMonsterInPlay *m, uint16 dirFlags) {
|
||||
int tmp = 0;
|
||||
switch (_monsterAnimType[m->properties->shapeIndex]) {
|
||||
case 0:
|
||||
@ -901,7 +901,7 @@ void LoLEngine::drawDoor(uint8 *shape, uint8 *doorPalette, int index, int unk2,
|
||||
if (!shape)
|
||||
return;
|
||||
|
||||
uint8 c = _dscDoor1[(_currentDirection << 5) + unk2];
|
||||
uint8 c = _dscDoorY2[(_currentDirection << 5) + unk2];
|
||||
int r = (c / 5) + 5 * _dscDimMap[index];
|
||||
uint16 d = _dscShapeOvlIndex[r];
|
||||
uint16 t = (index << 5) + c;
|
||||
@ -1080,7 +1080,7 @@ int LoLEngine::calcDrawingLayerParameters(int x1, int y1, int &x2, int &y2, uint
|
||||
return l;
|
||||
}
|
||||
|
||||
void LoLEngine::updateMonster(MonsterInPlay *monster) {
|
||||
void LoLEngine::updateMonster(LolMonsterInPlay *monster) {
|
||||
static const uint8 flags[] = { 1, 0, 1, 3, 3, 0, 0, 3, 4, 1, 0, 0, 4, 0, 0 };
|
||||
if (monster->mode > 14)
|
||||
return;
|
||||
@ -1228,7 +1228,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
|
||||
monster->flags &= 0xffef;
|
||||
}
|
||||
|
||||
void LoLEngine::moveMonster(MonsterInPlay *monster) {
|
||||
void LoLEngine::moveMonster(LolMonsterInPlay *monster) {
|
||||
static const int8 turnPos[] = { 0, 2, 6, 6, 0, 2, 4, 4, 2, 2, 4, 6, 0, 0, 4, 6, 0 };
|
||||
if (monster->x != monster->destX || monster->y != monster->destY) {
|
||||
walkMonster(monster);
|
||||
@ -1238,7 +1238,7 @@ void LoLEngine::moveMonster(MonsterInPlay *monster) {
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::walkMonster(MonsterInPlay *monster) {
|
||||
void LoLEngine::walkMonster(LolMonsterInPlay *monster) {
|
||||
if (monster->properties->flags & 0x400)
|
||||
return;
|
||||
|
||||
@ -1253,7 +1253,7 @@ void LoLEngine::walkMonster(MonsterInPlay *monster) {
|
||||
} else {
|
||||
setMonsterDirection(monster, s);
|
||||
if (monster->numDistAttacks) {
|
||||
if (getMonsterDistance(monster->block, _currentBlock) >= 2) {
|
||||
if (getBlockDistance(monster->block, _currentBlock) >= 2) {
|
||||
if (checkForPossibleDistanceAttack(monster->block, monster->direction, 3, _currentBlock) != 5) {
|
||||
if (monster->distAttackTick)
|
||||
return;
|
||||
@ -1269,7 +1269,7 @@ void LoLEngine::walkMonster(MonsterInPlay *monster) {
|
||||
placeMonster(monster, fx, fy);
|
||||
}
|
||||
|
||||
bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
|
||||
bool LoLEngine::chasePartyWithDistanceAttacks(LolMonsterInPlay *monster) {
|
||||
if (!monster->numDistAttacks)
|
||||
return false;
|
||||
|
||||
@ -1295,7 +1295,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
|
||||
int flyingObject = monster->properties->distWeapons[s];
|
||||
|
||||
if (flyingObject & 0xc000) {
|
||||
if (getMonsterDistance(monster->block, _currentBlock) > 1) {
|
||||
if (getBlockDistance(monster->block, _currentBlock) > 1) {
|
||||
int type = flyingObject & 0x4000 ? 0 : 1;
|
||||
flyingObject = makeItem(flyingObject & 0x3fff, 0, 0);
|
||||
|
||||
@ -1305,7 +1305,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
|
||||
}
|
||||
}
|
||||
} else if (!(flyingObject & 0x2000)) {
|
||||
if (getMonsterDistance(monster->block, _currentBlock) > 1)
|
||||
if (getBlockDistance(monster->block, _currentBlock) > 1)
|
||||
return false;
|
||||
|
||||
if (flyingObject == 1) {
|
||||
@ -1326,7 +1326,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
|
||||
} else if (flyingObject == 3) {
|
||||
// shriek
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (getMonsterDistance(monster->block, _monsters[i].block) < 7)
|
||||
if (getBlockDistance(monster->block, _monsters[i].block) < 7)
|
||||
setMonsterMode(monster, 7);
|
||||
}
|
||||
_txt->printMessage(2, "%s", getLangString(0x401a));
|
||||
@ -1347,7 +1347,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) {
|
||||
void LoLEngine::chasePartyWithCloseAttacks(LolMonsterInPlay *monster) {
|
||||
if (!(monster->flags & 8)) {
|
||||
int dir = calcMonsterDirection(monster->x & 0xff00, monster->y & 0xff00, _partyPosX & 0xff00, _partyPosY & 0xff00);
|
||||
int x1 = _partyPosX;
|
||||
@ -1389,7 +1389,7 @@ void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) {
|
||||
}
|
||||
}
|
||||
|
||||
int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
|
||||
int LoLEngine::walkMonsterCalcNextStep(LolMonsterInPlay *monster) {
|
||||
static const int8 walkMonsterTable1[] = { 7, -6, 5, -4, 3, -2, 1, 0 };
|
||||
static const int8 walkMonsterTable2[] = { -7, 6, -5, 4, -3, 2, -1, 0 };
|
||||
|
||||
@ -1445,23 +1445,8 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int LoLEngine::getMonsterDistance(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;
|
||||
}
|
||||
|
||||
int LoLEngine::checkForPossibleDistanceAttack(uint16 monsterBlock, int direction, int distance, uint16 curBlock) {
|
||||
int mdist = getMonsterDistance(curBlock, monsterBlock);
|
||||
int mdist = getBlockDistance(curBlock, monsterBlock);
|
||||
|
||||
if (mdist > distance)
|
||||
return 5;
|
||||
@ -1494,7 +1479,7 @@ int LoLEngine::checkForPossibleDistanceAttack(uint16 monsterBlock, int direction
|
||||
return 5;
|
||||
}
|
||||
|
||||
int LoLEngine::walkMonsterCheckDest(int x, int y, MonsterInPlay *monster, int unk) {
|
||||
int LoLEngine::walkMonsterCheckDest(int x, int y, LolMonsterInPlay *monster, int unk) {
|
||||
uint8 m = monster->mode;
|
||||
monster->mode = 15;
|
||||
|
||||
@ -1512,7 +1497,7 @@ void LoLEngine::getNextStepCoords(int16 srcX, int16 srcY, int &newX, int &newY,
|
||||
newY = (srcY + shiftTableY[direction]) & 0x1fff;
|
||||
}
|
||||
|
||||
void LoLEngine::rearrangeAttackingMonster(MonsterInPlay *monster) {
|
||||
void LoLEngine::rearrangeAttackingMonster(LolMonsterInPlay *monster) {
|
||||
int t = (monster->direction >> 1);
|
||||
uint16 mx = monster->x;
|
||||
uint16 my = monster->y;
|
||||
@ -1579,7 +1564,7 @@ void LoLEngine::rearrangeAttackingMonster(MonsterInPlay *monster) {
|
||||
placeMonster(monster, mx, my);
|
||||
}
|
||||
|
||||
void LoLEngine::moveStrayingMonster(MonsterInPlay *monster) {
|
||||
void LoLEngine::moveStrayingMonster(LolMonsterInPlay *monster) {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
@ -1616,13 +1601,13 @@ void LoLEngine::moveStrayingMonster(MonsterInPlay *monster) {
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::killMonster(MonsterInPlay *monster) {
|
||||
void LoLEngine::killMonster(LolMonsterInPlay *monster) {
|
||||
setMonsterMode(monster, 14);
|
||||
monsterDropItems(monster);
|
||||
checkSceneUpdateNeed(monster->block);
|
||||
|
||||
uint8 w = _levelBlockProperties[monster->block].walls[0];
|
||||
uint8 f = _levelBlockProperties[monster->block].flags;
|
||||
uint16 f = _levelBlockProperties[monster->block].flags;
|
||||
if (_wllVmpMap[w] == 0 && _wllShapeMap[w] == 0 && !(f & 0x40) && !(monster->properties->flags & 0x1000))
|
||||
_levelBlockProperties[monster->block].flags |= 0x80;
|
||||
|
||||
|
@ -75,7 +75,9 @@ const IndexTable iGameTable[] = {
|
||||
{ GI_KYRA1, 0 },
|
||||
{ GI_KYRA2, 1 },
|
||||
{ GI_KYRA3, 2 },
|
||||
{ GI_LOL, 3 },
|
||||
{ GI_EOB1, 3 },
|
||||
{ GI_EOB2, 4 },
|
||||
{ GI_LOL, 5 },
|
||||
{ -1, -1 }
|
||||
};
|
||||
|
||||
@ -257,6 +259,12 @@ bool StaticResource::init() {
|
||||
{ kLolButtonData, proc(loadButtonDefs), proc(freeButtonDefs) },
|
||||
#endif // ENABLE_LOL
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
{ kEob2SequenceData, proc(loadEob2SeqData), proc(freeEob2SeqData) },
|
||||
{ kEob2ShapeData, proc(loadEob2ShapeData), proc(freeEob2ShapeData) },
|
||||
{ kEobNpcData, proc(loadEobNpcData), proc(freeEobNpcData) },
|
||||
#endif // ENABLE_EOB
|
||||
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
#undef proc
|
||||
@ -503,9 +511,9 @@ bool StaticResource::loadHofSequenceData(Common::SeekableReadStream &stream, voi
|
||||
|
||||
tmp_s[i].flags = stream.readUint16BE();
|
||||
tmp_s[i].wsaFile = new char[14];
|
||||
stream.read(const_cast<char *>(tmp_s[i].wsaFile), 14);
|
||||
stream.read(const_cast<char*>(tmp_s[i].wsaFile), 14);
|
||||
tmp_s[i].cpsFile = new char[14];
|
||||
stream.read(const_cast<char *>(tmp_s[i].cpsFile), 14);
|
||||
stream.read(const_cast<char*>(tmp_s[i].cpsFile), 14);
|
||||
tmp_s[i].startupCommand = stream.readByte();
|
||||
tmp_s[i].finalCommand = stream.readByte();
|
||||
tmp_s[i].stringIndex1 = stream.readUint16BE();
|
||||
@ -529,7 +537,7 @@ bool StaticResource::loadHofSequenceData(Common::SeekableReadStream &stream, voi
|
||||
|
||||
tmp_n[i].flags = stream.readUint16BE();
|
||||
tmp_n[i].wsaFile = new char[14];
|
||||
stream.read(const_cast<char *>(tmp_n[i].wsaFile), 14);
|
||||
stream.read(const_cast<char*>(tmp_n[i].wsaFile), 14);
|
||||
tmp_n[i].startframe = stream.readUint16BE();
|
||||
tmp_n[i].endFrame = stream.readUint16BE();
|
||||
tmp_n[i].frameDelay = stream.readUint16BE();
|
||||
|
1062
engines/kyra/staticres_eob.cpp
Normal file
1062
engines/kyra/staticres_eob.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -45,16 +45,8 @@ const FlyingObjectShape *StaticResource::loadFlyingObjectData(int id, int &entri
|
||||
return (const FlyingObjectShape *)getData(id, kLolFlightShpData, entries);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
const ButtonDef *StaticResource::loadButtonDefs(int id, int &entries) {
|
||||
return (const ButtonDef *)getData(id, kLolButtonData, entries);
|
||||
const LoLButtonDef *StaticResource::loadButtonDefs(int id, int &entries) {
|
||||
return (const LoLButtonDef *)getData(id, kLolButtonData, entries);
|
||||
}
|
||||
|
||||
bool StaticResource::loadCharData(Common::SeekableReadStream &stream, void *&ptr, int &size) {
|
||||
@ -164,34 +156,10 @@ bool StaticResource::loadFlyingObjectData(Common::SeekableReadStream &stream, vo
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool StaticResource::loadButtonDefs(Common::SeekableReadStream &stream, void *&ptr, int &size) {
|
||||
size = stream.size() / 18;
|
||||
|
||||
ButtonDef *r = new ButtonDef[size];
|
||||
LoLButtonDef *r = new LoLButtonDef[size];
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
r[i].buttonflags = stream.readUint16BE();
|
||||
@ -237,23 +205,8 @@ void StaticResource::freeFlyingObjectData(void *&ptr, int &size) {
|
||||
size = 0;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void StaticResource::freeButtonDefs(void *&ptr, int &size) {
|
||||
ButtonDef *d = (ButtonDef *)ptr;
|
||||
LoLButtonDef *d = (LoLButtonDef *)ptr;
|
||||
delete[] d;
|
||||
ptr = 0;
|
||||
size = 0;
|
||||
@ -289,67 +242,59 @@ void LoLEngine::initStaticResource() {
|
||||
if (_flags.isDemo)
|
||||
return;
|
||||
|
||||
int tempSize;
|
||||
_pakFileList = _staticres->loadStrings(kLolIngamePakFiles, _pakFileListSize);
|
||||
_charDefaults = _staticres->loadCharData(kLolCharacterDefs, _charDefaultsSize);
|
||||
_ingameSoundIndex = (const uint16 *)_staticres->loadRawData(kLolIngameSfxIndex, _ingameSoundIndexSize);
|
||||
_musicTrackMap = _staticres->loadRawData(kLolMusicTrackMap, _musicTrackMapSize);
|
||||
_ingameSoundIndex = (const uint16 *)_staticres->loadRawData(kLolIngameSfxIndex, tempSize);
|
||||
_musicTrackMap = _staticres->loadRawData(kLolMusicTrackMap, tempSize);
|
||||
_ingameGMSoundIndex = _staticres->loadRawData(kLolIngameGMSfxIndex, _ingameGMSoundIndexSize);
|
||||
_ingameMT32SoundIndex = _staticres->loadRawData(kLolIngameMT32SfxIndex, _ingameMT32SoundIndexSize);
|
||||
_ingamePCSpeakerSoundIndex = _staticres->loadRawData(kLolIngamePcSpkSfxIndex, _ingamePCSpeakerSoundIndexSize);
|
||||
_spellProperties = _staticres->loadSpellData(kLolSpellProperties, _spellPropertiesSize);
|
||||
_gameShapeMap = (const int8 *)_staticres->loadRawData(kLolGameShapeMap, _gameShapeMapSize);
|
||||
_sceneItemOffs = (const int8 *)_staticres->loadRawData(kLolSceneItemOffs, _sceneItemOffsSize);
|
||||
_charInvIndex = _staticres->loadRawData(kLolCharInvIndex, _charInvIndexSize);
|
||||
_charInvDefs = _staticres->loadRawData(kLolCharInvDefs, _charInvDefsSize);
|
||||
_charDefsMan = _staticres->loadRawDataBe16(kLolCharDefsMan, _charDefsManSize);
|
||||
_charDefsWoman = _staticres->loadRawDataBe16(kLolCharDefsWoman, _charDefsWomanSize);
|
||||
_charDefsKieran = _staticres->loadRawDataBe16(kLolCharDefsKieran, _charDefsKieranSize);
|
||||
_charDefsAkshel = _staticres->loadRawDataBe16(kLolCharDefsAkshel, _charDefsAkshelSize);
|
||||
_expRequirements = (const int32 *)_staticres->loadRawDataBe32(kLolExpRequirements, _expRequirementsSize);
|
||||
_monsterModifiers = _staticres->loadRawDataBe16(kLolMonsterModifiers, _monsterModifiersSize);
|
||||
_monsterShiftOffs = (const int8 *)_staticres->loadRawData(kLolMonsterShiftOffsets, _monsterShiftOffsSize);
|
||||
_monsterDirFlags = _staticres->loadRawData(kLolMonsterDirFlags, _monsterDirFlagsSize);
|
||||
_monsterScaleX = _staticres->loadRawData(kLolMonsterScaleX, _monsterScaleXSize);
|
||||
_monsterScaleY = _staticres->loadRawData(kLolMonsterScaleY, _monsterScaleYSize);
|
||||
_monsterScaleWH = _staticres->loadRawDataBe16(kLolMonsterScaleWH, _monsterScaleWHSize);
|
||||
_inventorySlotDesc = _staticres->loadRawDataBe16(kLolInventoryDesc, _inventorySlotDescSize);
|
||||
_levelShpList = _staticres->loadStrings(kLolLevelShpList, _levelShpListSize);
|
||||
_levelDatList = _staticres->loadStrings(kLolLevelDatList, _levelDatListSize);
|
||||
_compassDefs = _staticres->loadCompassData(kLolCompassDefs, _compassDefsSize);
|
||||
_flyingItemShapes = _staticres->loadFlyingObjectData(kLolFlyingObjectShp, _flyingItemShapesSize);
|
||||
_itemCost = _staticres->loadRawDataBe16(kLolItemPrices, _itemCostSize);
|
||||
_stashSetupData = _staticres->loadRawData(kLolStashSetup, _stashSetupDataSize);
|
||||
_spellProperties = _staticres->loadSpellData(kLolSpellProperties, tempSize);
|
||||
_gameShapeMap = (const int8 *)_staticres->loadRawData(kLolGameShapeMap, tempSize);
|
||||
_sceneItemOffs = (const int8 *)_staticres->loadRawData(kLolSceneItemOffs, tempSize);
|
||||
_charInvIndex = _staticres->loadRawData(kLolCharInvIndex, tempSize);
|
||||
_charInvDefs = _staticres->loadRawData(kLolCharInvDefs, tempSize);
|
||||
_charDefsMan = _staticres->loadRawDataBe16(kLolCharDefsMan, tempSize);
|
||||
_charDefsWoman = _staticres->loadRawDataBe16(kLolCharDefsWoman, tempSize);
|
||||
_charDefsKieran = _staticres->loadRawDataBe16(kLolCharDefsKieran, tempSize);
|
||||
_charDefsAkshel = _staticres->loadRawDataBe16(kLolCharDefsAkshel, tempSize);
|
||||
_expRequirements = (const int32 *)_staticres->loadRawDataBe32(kLolExpRequirements, tempSize);
|
||||
_monsterModifiers = _staticres->loadRawDataBe16(kLolMonsterModifiers, tempSize);
|
||||
_monsterShiftOffs = (const int8 *)_staticres->loadRawData(kLolMonsterShiftOffsets, tempSize);
|
||||
_monsterDirFlags = _staticres->loadRawData(kLolMonsterDirFlags, tempSize);
|
||||
_monsterScaleX = _staticres->loadRawData(kLolMonsterScaleX, tempSize);
|
||||
_monsterScaleY = _staticres->loadRawData(kLolMonsterScaleY, tempSize);
|
||||
_monsterScaleWH = _staticres->loadRawDataBe16(kLolMonsterScaleWH, tempSize);
|
||||
_inventorySlotDesc = _staticres->loadRawDataBe16(kLolInventoryDesc, tempSize);
|
||||
_levelShpList = _staticres->loadStrings(kLolLevelShpList, tempSize);
|
||||
_levelDatList = _staticres->loadStrings(kLolLevelDatList, tempSize);
|
||||
_compassDefs = _staticres->loadCompassData(kLolCompassDefs, tempSize);
|
||||
_flyingItemShapes = _staticres->loadFlyingObjectData(kLolFlyingObjectShp, tempSize);
|
||||
_itemCost = _staticres->loadRawDataBe16(kLolItemPrices, tempSize);
|
||||
_stashSetupData = _staticres->loadRawData(kLolStashSetup, tempSize);
|
||||
|
||||
_dscUnk1 = (const int8 *)_staticres->loadRawData(kLolDscUnk1, _dscUnk1Size);
|
||||
_dscShapeIndex = (const int8 *)_staticres->loadRawData(kLolDscShapeIndex, _dscShapeIndexSize);
|
||||
_dscOvlMap = _staticres->loadRawData(kLolDscOvlMap, _dscOvlMapSize);
|
||||
_dscShapeScaleW = _staticres->loadRawDataBe16(kLolDscScaleWidthData, _dscShapeScaleWSize);
|
||||
_dscShapeScaleH = _staticres->loadRawDataBe16(kLolDscScaleHeightData, _dscShapeScaleHSize);
|
||||
_dscShapeX = (const int16 *)_staticres->loadRawDataBe16(kLolDscX, _dscShapeXSize);
|
||||
_dscShapeY = (const int8 *)_staticres->loadRawData(kLolDscY, _dscShapeYSize);
|
||||
_dscTileIndex = _staticres->loadRawData(kLolDscTileIndex, _dscTileIndexSize);
|
||||
_dscUnk2 = _staticres->loadRawData(kLolDscUnk2, _dscUnk2Size);
|
||||
_dscDoorShpIndex = _staticres->loadRawData(kLolDscDoorShapeIndex, _dscDoorShpIndexSize);
|
||||
_dscDim1 = (const int8 *)_staticres->loadRawData(kLolDscDimData1, _dscDim1Size);
|
||||
_dscDim2 = (const int8 *)_staticres->loadRawData(kLolDscDimData2, _dscDim2Size);
|
||||
_dscBlockMap = _staticres->loadRawData(kLolDscBlockMap, _dscBlockMapSize);
|
||||
_dscDimMap = _staticres->loadRawData(kLolDscDimMap, _dscDimMapSize);
|
||||
_dscDoorMonsterScaleTable = _staticres->loadRawDataBe16(kLolDscDoorScale, _dscDoorMonsterScaleTableSize);
|
||||
_dscShapeOvlIndex = _staticres->loadRawData(kLolDscOvlIndex, _dscShapeOvlIndexSize);
|
||||
_dscDoor4 = _staticres->loadRawDataBe16(kLolDscDoor4, _dscDoor4Size);
|
||||
_dscBlockIndex = (const int8 *)_staticres->loadRawData(kLolDscBlockIndex, _dscBlockIndexSize);
|
||||
_dscDoor1 = _staticres->loadRawData(kLolDscDoor1, _dscDoor1Size);
|
||||
_dscDoorMonsterX = (const int16 *)_staticres->loadRawDataBe16(kLolDscDoorX, _dscDoorMonsterXSize);
|
||||
_dscDoorMonsterY = (const int16 *)_staticres->loadRawDataBe16(kLolDscDoorY, _dscDoorMonsterYSize);
|
||||
_dscWalls = (const int8 *)_staticres->loadRawData(kLolDscWalls, tempSize);
|
||||
|
||||
_scrollXTop = _staticres->loadRawData(kLolScrollXTop, _scrollXTopSize);
|
||||
_scrollYTop = _staticres->loadRawData(kLolScrollYTop, _scrollYTopSize);
|
||||
_scrollXBottom = _staticres->loadRawData(kLolScrollXBottom, _scrollXBottomSize);
|
||||
_scrollYBottom = _staticres->loadRawData(kLolScrollYBottom, _scrollYBottomSize);
|
||||
_dscOvlMap = _staticres->loadRawData(kLolDscOvlMap, tempSize);
|
||||
_dscShapeOvlIndex = _staticres->loadRawData(kLolDscOvlIndex, tempSize);
|
||||
_dscShapeScaleW = _staticres->loadRawDataBe16(kLolDscScaleWidthData, tempSize);
|
||||
_dscShapeScaleH = _staticres->loadRawDataBe16(kLolDscScaleHeightData, tempSize);
|
||||
_dscShapeY = (const int8 *)_staticres->loadRawData(kLolBaseDscY, tempSize);
|
||||
|
||||
_dscDoorMonsterScaleTable = _staticres->loadRawDataBe16(kLolDscDoorScale, tempSize);
|
||||
_dscDoor4 = _staticres->loadRawDataBe16(kLolDscDoor4, tempSize);
|
||||
_dscDoorMonsterX = (const int16 *)_staticres->loadRawDataBe16(kLolDscDoorX, tempSize);
|
||||
_dscDoorMonsterY = (const int16 *)_staticres->loadRawDataBe16(kLolDscDoorY, tempSize);
|
||||
|
||||
_scrollXTop = _staticres->loadRawData(kLolScrollXTop, tempSize);
|
||||
_scrollYTop = _staticres->loadRawData(kLolScrollYTop, tempSize);
|
||||
_scrollXBottom = _staticres->loadRawData(kLolScrollXBottom, tempSize);
|
||||
_scrollYBottom = _staticres->loadRawData(kLolScrollYBottom, tempSize);
|
||||
|
||||
const char *const *tmpSndList = _staticres->loadStrings(kLolIngameSfxFiles, _ingameSoundListSize);
|
||||
if (tmpSndList) {
|
||||
_ingameSoundList = new char *[_ingameSoundListSize];
|
||||
_ingameSoundList = new char*[_ingameSoundListSize];
|
||||
for (int i = 0; i < _ingameSoundListSize; i++) {
|
||||
_ingameSoundList[i] = new char[strlen(tmpSndList[i]) + 1];
|
||||
strcpy(_ingameSoundList[i], tmpSndList[i]);
|
||||
@ -357,19 +302,18 @@ void LoLEngine::initStaticResource() {
|
||||
_staticres->unloadId(kLolIngameSfxFiles);
|
||||
}
|
||||
|
||||
_buttonData = _staticres->loadButtonDefs(kLolButtonDefs, _buttonDataSize);
|
||||
_buttonList1 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList1, _buttonList1Size);
|
||||
_buttonList2 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList2, _buttonList2Size);
|
||||
_buttonList3 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList3, _buttonList3Size);
|
||||
_buttonList4 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList4, _buttonList4Size);
|
||||
_buttonList5 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList5, _buttonList5Size);
|
||||
_buttonList6 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList6, _buttonList6Size);
|
||||
_buttonList7 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList7, _buttonList7Size);
|
||||
_buttonList8 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList8, _buttonList8Size);
|
||||
_buttonData = _staticres->loadButtonDefs(kLolButtonDefs, tempSize);
|
||||
_buttonList1 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList1, tempSize);
|
||||
_buttonList2 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList2, tempSize);
|
||||
_buttonList3 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList3, tempSize);
|
||||
_buttonList4 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList4, tempSize);
|
||||
_buttonList5 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList5, tempSize);
|
||||
_buttonList6 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList6, tempSize);
|
||||
_buttonList7 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList7, tempSize);
|
||||
_buttonList8 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList8, tempSize);
|
||||
|
||||
_autoMapStrings = _staticres->loadRawDataBe16(kLolMapStringId, _autoMapStringsSize);
|
||||
_autoMapStrings = _staticres->loadRawDataBe16(kLolMapStringId, tempSize);
|
||||
|
||||
int tempSize;
|
||||
const uint8 *tmp = _staticres->loadRawData(kLolLegendData, tempSize);
|
||||
uint8 entrySize = tempSize / 12;
|
||||
tempSize /= entrySize;
|
||||
@ -386,13 +330,15 @@ void LoLEngine::initStaticResource() {
|
||||
}
|
||||
|
||||
tmp = _staticres->loadRawData(kLolMapCursorOvl, tempSize);
|
||||
_mapCursorOverlay = new uint8[tempSize];
|
||||
memcpy(_mapCursorOverlay, tmp, tempSize);
|
||||
_staticres->unloadId(kLolMapCursorOvl);
|
||||
if (tmp) {
|
||||
_mapCursorOverlay = new uint8[tempSize];
|
||||
memcpy(_mapCursorOverlay, tmp, tempSize);
|
||||
_staticres->unloadId(kLolMapCursorOvl);
|
||||
}
|
||||
|
||||
_updateSpellBookCoords = _staticres->loadRawData(kLolSpellbookCoords, _updateSpellBookCoordsSize);
|
||||
_updateSpellBookAnimData = _staticres->loadRawData(kLolSpellbookAnim, _updateSpellBookAnimDataSize);
|
||||
_healShapeFrames = _staticres->loadRawData(kLolHealShapeFrames, _healShapeFramesSize);
|
||||
_updateSpellBookCoords = _staticres->loadRawData(kLolSpellbookCoords, tempSize);
|
||||
_updateSpellBookAnimData = _staticres->loadRawData(kLolSpellbookAnim, tempSize);
|
||||
_healShapeFrames = _staticres->loadRawData(kLolHealShapeFrames, tempSize);
|
||||
|
||||
tmp = _staticres->loadRawData(kLolLightningDefs, tempSize);
|
||||
if (tmp) {
|
||||
@ -405,7 +351,7 @@ void LoLEngine::initStaticResource() {
|
||||
_staticres->unloadId(kLolLightningDefs);
|
||||
}
|
||||
|
||||
_fireBallCoords = (const int16 *)_staticres->loadRawDataBe16(kLolFireballCoords, _fireBallCoordsSize);
|
||||
_fireBallCoords = (const int16*)_staticres->loadRawDataBe16(kLolFireballCoords, tempSize);
|
||||
|
||||
_buttonCallbacks.clear();
|
||||
_buttonCallbacks.reserve(95);
|
||||
|
649
engines/kyra/text_eob.cpp
Normal file
649
engines/kyra/text_eob.cpp
Normal file
@ -0,0 +1,649 @@
|
||||
/* 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 {
|
||||
|
||||
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[1024];
|
||||
memset(_dialogueBuffer, 0, 1024);
|
||||
|
||||
_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;
|
||||
}
|
||||
|
||||
_waitButtonSpace = 0;
|
||||
}
|
||||
|
||||
TextDisplayer_Eob::~TextDisplayer_Eob() {
|
||||
delete[] _dialogueBuffer;
|
||||
delete[] _currentLine;
|
||||
delete[] _textDimData;
|
||||
}
|
||||
|
||||
void TextDisplayer_Eob::setupField(int dim, bool mode) {
|
||||
setPageBreakFlag();
|
||||
|
||||
_textDimData[dim].color2 = _vm->_bkgColor_1;
|
||||
_screen->setScreenDim(dim);
|
||||
|
||||
if (mode)
|
||||
clearCurDim();
|
||||
else
|
||||
resetDimTextPositions(dim);
|
||||
|
||||
//_textPageBreakFunc = textPageBreakMore; + 0x25
|
||||
}
|
||||
|
||||
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') {
|
||||
snprintf(_scriptParaString, 11, "%d", va_arg(args, int));
|
||||
_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:
|
||||
_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 d = 0;
|
||||
|
||||
if (_tempString2) {
|
||||
if (*_tempString2) {
|
||||
d = *_tempString2++;
|
||||
} else {
|
||||
_tempString2 = 0;
|
||||
d = _ctrl[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (!d && _tempString1) {
|
||||
if (*_tempString1)
|
||||
d = *_tempString1++;
|
||||
else
|
||||
_tempString1 = 0;
|
||||
}
|
||||
|
||||
_ctrl[1] = d;
|
||||
_ctrl[2] = 0;
|
||||
}
|
||||
|
||||
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 -= 80;
|
||||
} else {
|
||||
if (!_sjisLineBreakFlag || (_lineCount + 1 < lines - 1))
|
||||
ct = false;
|
||||
else
|
||||
// cut off line to leave space for "MORE" button
|
||||
w -= 80;
|
||||
}
|
||||
|
||||
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 -= (10 * (_screen->getFontWidth() + _screen->_charWidth));
|
||||
|
||||
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) {
|
||||
strcpy(_dialogueBuffer, (const char *)(screen()->getCPagePtr(5) + READ_LE_UINT16(&screen()->getCPagePtr(5)[(stringId - 1) << 1])));
|
||||
displayText(_dialogueBuffer);
|
||||
|
||||
if (pageBreakString) {
|
||||
strcpy(_pageBreakString, pageBreakString);
|
||||
displayWaitButton();
|
||||
resetPageBreakString();
|
||||
}
|
||||
}
|
||||
|
||||
void TextDisplayer_Eob::printDialogueText(const char *str, bool wait) {
|
||||
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, 240, str, args);
|
||||
va_end(args);
|
||||
|
||||
displayText(_dialogueBuffer);
|
||||
|
||||
//if (textColor != -1)
|
||||
_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);
|
||||
|
||||
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;
|
||||
|
||||
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 if (vm()->game() == GI_LOL) {
|
||||
y = dim->sy + dim->h - 10;
|
||||
} else {
|
||||
y = _waitButtonMode ? 162 : 189;
|
||||
x = _waitButtonMode ? 76 : 221;
|
||||
}
|
||||
|
||||
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, vm()->_dialogueButtonW, vm()->_dialogueButtonH, vm()->_color1_1, vm()->_color2_1, vm()->_bkgColor_1);
|
||||
screen()->printText(_pageBreakString, x + (vm()->_dialogueButtonW >> 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()->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 + _vm->_dialogueButtonW, y + 9)) {
|
||||
if (_vm->game() == GI_LOL)
|
||||
target = true;
|
||||
else
|
||||
loop = false;
|
||||
}
|
||||
} else if (inputFlag == 200 || inputFlag == 202) {
|
||||
if (target)
|
||||
loop = false;
|
||||
}
|
||||
} while (loop);
|
||||
|
||||
if (vm()->gameFlags().use16ColorMode)
|
||||
screen()->fillRect(x + 8, y, x + 57, y + 9, _textDimData[screen()->curDimIndex()].color2);
|
||||
else
|
||||
screen()->fillRect(x, y, x + 73, y + 8, _textDimData[screen()->curDimIndex()].color2);
|
||||
|
||||
clearCurDim();
|
||||
|
||||
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;
|
||||
|
||||
static const uint16 posX[] = { 221, 76 };
|
||||
static const uint8 posY[] = { 189, 162 };
|
||||
|
||||
vm()->_dialogueButtonPosX = &posX[_waitButtonMode];
|
||||
vm()->_dialogueButtonPosY = &posY[_waitButtonMode];
|
||||
vm()->_dialogueButtonYoffs = 0;
|
||||
|
||||
SWAP(_vm->_dialogueButtonLabelCol1, _vm->_dialogueButtonLabelCol2);
|
||||
vm()->drawDialogueButtons();
|
||||
|
||||
if (!vm()->shouldQuit())
|
||||
vm()->removeInputTop();
|
||||
|
||||
while (!vm()->processDialogue() && !vm()->shouldQuit()) {}
|
||||
SWAP(_vm->_dialogueButtonLabelCol1, _vm->_dialogueButtonLabelCol2);
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // (ENABLE_EOB || ENABLE_LOL)
|
112
engines/kyra/text_eob.h
Normal file
112
engines/kyra/text_eob.h
Normal file
@ -0,0 +1,112 @@
|
||||
/* 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;
|
||||
};
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_EOB || ENABLE_LOL
|
@ -32,36 +32,18 @@
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen) : _vm(vm), _screen(screen),
|
||||
_scriptTextParameter(0), _lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0),
|
||||
_numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false) {
|
||||
TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL) : TextDisplayer_Eob(engine, engine->screen()),
|
||||
_vm(engine), _screen(screenLoL), _scriptTextParameter(0) {
|
||||
|
||||
memset(_stringParameters, 0, 15 * sizeof(char *));
|
||||
_buffer = new char[600];
|
||||
memset(_buffer, 0, 600);
|
||||
|
||||
_dialogueBuffer = new char[1024];
|
||||
memset(_dialogueBuffer, 0, 1024);
|
||||
|
||||
_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;
|
||||
}
|
||||
_waitButtonSpace = 0;
|
||||
}
|
||||
|
||||
TextDisplayer_LoL::~TextDisplayer_LoL() {
|
||||
delete[] _buffer;
|
||||
delete[] _dialogueBuffer;
|
||||
delete[] _currentLine;
|
||||
delete[] _textDimData;
|
||||
}
|
||||
|
||||
void TextDisplayer_LoL::setupField(bool mode) {
|
||||
@ -151,20 +133,6 @@ void TextDisplayer_LoL::expandField() {
|
||||
}
|
||||
}
|
||||
|
||||
int TextDisplayer_LoL::clearDim(int dim) {
|
||||
int res = _screen->curDimIndex();
|
||||
_screen->setScreenDim(dim);
|
||||
_textDimData[dim].color1 = _screen->_curDim->unk8;
|
||||
_textDimData[dim].color2 = _screen->_curDim->unkA;
|
||||
clearCurDim();
|
||||
return res;
|
||||
}
|
||||
|
||||
void TextDisplayer_LoL::resetDimTextPositions(int dim) {
|
||||
_textDimData[dim].column = 0;
|
||||
_textDimData[dim].line = 0;
|
||||
}
|
||||
|
||||
void TextDisplayer_LoL::printDialogueText(int dim, char *str, EMCState *script, const uint16 *paramList, int16 paramIndex) {
|
||||
int oldDim = 0;
|
||||
|
||||
@ -201,10 +169,9 @@ void TextDisplayer_LoL::printDialogueText(int dim, char *str, EMCState *script,
|
||||
displayText(_dialogueBuffer);
|
||||
|
||||
_screen->setScreenDim(oldDim);
|
||||
_lineCount = 0;
|
||||
_screen->setCurPage(cp);
|
||||
_screen->setFont(of);
|
||||
|
||||
_lineCount = 0;
|
||||
_vm->_fadeText = false;
|
||||
}
|
||||
|
||||
@ -366,465 +333,17 @@ void TextDisplayer_LoL::preprocessString(char *str, EMCState *script, const uint
|
||||
*dst = 0;
|
||||
}
|
||||
|
||||
void TextDisplayer_LoL::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') {
|
||||
snprintf(_scriptParaString, 11, "%d", va_arg(args, int));
|
||||
_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:
|
||||
// TODO (UNUSED)
|
||||
break;
|
||||
|
||||
case 12:
|
||||
if (isPc98)
|
||||
_sjisLineBreakFlag = true;
|
||||
printLine(_currentLine);
|
||||
_sjisLineBreakFlag = false;
|
||||
_lineCount++;
|
||||
_textDimData[sdx].column = 0;
|
||||
_textDimData[sdx].line++;
|
||||
break;
|
||||
|
||||
case 18:
|
||||
// TODO (UNUSED)
|
||||
break;
|
||||
|
||||
case 23:
|
||||
// TODO (UNUSED)
|
||||
break;
|
||||
|
||||
case 24:
|
||||
// TODO (UNUSED)
|
||||
break;
|
||||
|
||||
case 26:
|
||||
// TODO (UNUSED)
|
||||
break;
|
||||
|
||||
case 28:
|
||||
// TODO (UNUSED)
|
||||
break;
|
||||
|
||||
default:
|
||||
_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);
|
||||
LolEobBaseEngine *TextDisplayer_LoL::vm() {
|
||||
return _vm;
|
||||
}
|
||||
|
||||
char TextDisplayer_LoL::parseCommand() {
|
||||
if (!_ctrl[1])
|
||||
readNextPara();
|
||||
|
||||
char res = _ctrl[1];
|
||||
_ctrl[1] = _ctrl[2];
|
||||
_ctrl[2] = 0;
|
||||
|
||||
if (!_ctrl[1])
|
||||
readNextPara();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void TextDisplayer_LoL::readNextPara() {
|
||||
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;
|
||||
}
|
||||
|
||||
_ctrl[1] = d;
|
||||
_ctrl[2] = 0;
|
||||
}
|
||||
|
||||
void TextDisplayer_LoL::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 <= _lineCount) {
|
||||
_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 - 1) << 3, 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) <= _lineCount)
|
||||
// cut off line to leave space for "MORE" button
|
||||
w -= 80;
|
||||
} else {
|
||||
if (!_sjisLineBreakFlag || (_lineCount + 1 < lines - 1))
|
||||
ct = false;
|
||||
else
|
||||
// cut off line to leave space for "MORE" button
|
||||
w -= 80;
|
||||
}
|
||||
|
||||
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)
|
||||
// cut off line to leave space for "MORE" button
|
||||
w -= (10 * (_screen->getFontWidth() + _screen->_charWidth));
|
||||
|
||||
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);
|
||||
Screen *TextDisplayer_LoL::screen() {
|
||||
return _screen;
|
||||
}
|
||||
|
||||
void TextDisplayer_LoL::textPageBreak() {
|
||||
int cp = _screen->setCurPage(0);
|
||||
Screen::FontId cf = _screen->setFont(_vm->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
|
||||
|
||||
_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) - 77;
|
||||
int y = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
char *txt = _vm->getLangString(0x4073);
|
||||
if (_vm->gameFlags().use16ColorMode) {
|
||||
_vm->gui_drawBox(x + 8, (y & ~7) - 1, 66, 10, 0xee, 0xcc, -1);
|
||||
_vm->_screen->printText(txt, (x + 37 - (strlen(txt) << 1) + 4) & ~3, (y + 2) & ~7, 0xc1, 0);
|
||||
} else {
|
||||
_vm->gui_drawBox(x, y, 74, 9, 136, 251, -1);
|
||||
_vm->_screen->printText(txt, x + 37 - (_vm->_screen->getTextWidth(txt) >> 1), y + 2, 144, 0);
|
||||
}
|
||||
|
||||
_vm->removeInputTop();
|
||||
|
||||
bool loop = true;
|
||||
bool target = false;
|
||||
|
||||
do {
|
||||
int inputFlag = _vm->checkInput(0, false) & 0xFF;
|
||||
_vm->removeInputTop();
|
||||
|
||||
while (!inputFlag) {
|
||||
_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 + 74, y + 9))
|
||||
target = true;
|
||||
} else if (inputFlag == 200 || inputFlag == 202) {
|
||||
if (target)
|
||||
loop = false;
|
||||
}
|
||||
} while (loop);
|
||||
|
||||
|
||||
if (_vm->gameFlags().use16ColorMode)
|
||||
_screen->fillRect(x + 8, y, x + 57, y + 9, _textDimData[_screen->curDimIndex()].color2);
|
||||
else
|
||||
_screen->fillRect(x, y, x + 73, y + 8, _textDimData[_screen->curDimIndex()].color2);
|
||||
|
||||
clearCurDim();
|
||||
|
||||
_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);
|
||||
_vm->removeInputTop();
|
||||
}
|
||||
|
||||
void TextDisplayer_LoL::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;
|
||||
strcpy(_pageBreakString, _vm->getLangString(0x4073));
|
||||
TextDisplayer_Eob::textPageBreak();
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
@ -20,80 +20,52 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_LOL
|
||||
|
||||
#ifndef KYRA_TEXT_LOL_H
|
||||
#define KYRA_TEXT_LOL_H
|
||||
|
||||
#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
|
||||
#include "kyra/text_eob.h"
|
||||
#endif
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#ifdef ENABLE_LOL
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
class Screen_LoL;
|
||||
class LoLEngine;
|
||||
struct EMCState;
|
||||
|
||||
class TextDisplayer_LoL {
|
||||
friend class LoLEngine;
|
||||
class TextDisplayer_LoL : public TextDisplayer_Eob {
|
||||
public:
|
||||
TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen);
|
||||
TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL);
|
||||
~TextDisplayer_LoL();
|
||||
|
||||
void setupField(bool mode);
|
||||
void expandField();
|
||||
|
||||
int clearDim(int dim);
|
||||
void resetDimTextPositions(int dim);
|
||||
|
||||
void printDialogueText(int dim, char *str, EMCState *script, const uint16 *paramList, int16 paramIndex);
|
||||
void printMessage(uint16 type, const char *str, ...) GCC_PRINTF(3, 4);
|
||||
|
||||
int16 _scriptTextParameter;
|
||||
|
||||
private:
|
||||
void displayText(char *str, ...);
|
||||
char parseCommand();
|
||||
void readNextPara();
|
||||
void printLine(char *str);
|
||||
LolEobBaseEngine *vm();
|
||||
Screen *screen();
|
||||
|
||||
void preprocessString(char *str, EMCState *script, const uint16 *paramList, int16 paramIndex);
|
||||
void textPageBreak();
|
||||
|
||||
void clearCurDim();
|
||||
|
||||
char *_stringParameters[15];
|
||||
char *_buffer;
|
||||
char *_dialogueBuffer;
|
||||
char *_tempString1;
|
||||
char *_tempString2;
|
||||
char *_currentLine;
|
||||
char _ctrl[3];
|
||||
|
||||
char _scriptParaString[11];
|
||||
|
||||
uint16 _lineWidth;
|
||||
int _lineCount;
|
||||
uint32 _numCharsTotal;
|
||||
uint32 _numCharsLeft;
|
||||
uint32 _numCharsPrinted;
|
||||
|
||||
bool _printFlag;
|
||||
bool _sjisLineBreakFlag;
|
||||
|
||||
LoLEngine *_vm;
|
||||
Screen_LoL *_screen;
|
||||
|
||||
struct TextDimData {
|
||||
uint8 color1;
|
||||
uint8 color2;
|
||||
uint16 column;
|
||||
uint8 line;
|
||||
};
|
||||
|
||||
TextDimData *_textDimData;
|
||||
};
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_LOL
|
||||
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_LOL
|
||||
|
@ -217,7 +217,7 @@ void TimerManager::pauseSingleTimer(uint8 id, bool p) {
|
||||
bool TimerManager::isEnabled(uint8 id) const {
|
||||
CIterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
|
||||
if (timer != _timers.end())
|
||||
return (timer->enabled == 1);
|
||||
return (timer->enabled & 1);
|
||||
|
||||
warning("TimerManager::isEnabled: No timer %d", id);
|
||||
return false;
|
||||
|
378
engines/kyra/timer_eob.cpp
Normal file
378
engines/kyra/timer_eob.cpp
Normal file
@ -0,0 +1,378 @@
|
||||
/* 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/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 {
|
||||
|
||||
#define TimerV2(x) new Common::Functor1Mem<int, void, EobCoreEngine>(this, &EobCoreEngine::x)
|
||||
|
||||
void EobCoreEngine::setupTimers() {
|
||||
_timer->addTimer(0, TimerV2(timerProcessCharacterExchange), 9, false);
|
||||
_timer->addTimer(1, TimerV2(timerProcessFlyingObjects), 3, true);
|
||||
_timer->addTimer(0x20, TimerV2(timerProcessMonsters), 20, true);
|
||||
_timer->addTimer(0x21, TimerV2(timerProcessMonsters), 20, true);
|
||||
_timer->addTimer(0x22, TimerV2(timerProcessMonsters), 20, true);
|
||||
_timer->addTimer(0x23, TimerV2(timerProcessMonsters), 20, true);
|
||||
_timer->setNextRun(0x21, _system->getMillis() + 7 * _tickLength);
|
||||
_timer->setNextRun(0x22, _system->getMillis() + 14 * _tickLength);
|
||||
_timer->setNextRun(0x23, _system->getMillis() + 14 * _tickLength);
|
||||
_timer->addTimer(0x30, TimerV2(timerSpecialCharacterUpdate), 50, false);
|
||||
_timer->addTimer(0x31, TimerV2(timerSpecialCharacterUpdate), 50, false);
|
||||
_timer->addTimer(0x32, TimerV2(timerSpecialCharacterUpdate), 50, false);
|
||||
_timer->addTimer(0x33, TimerV2(timerSpecialCharacterUpdate), 50, false);
|
||||
_timer->addTimer(0x34, TimerV2(timerSpecialCharacterUpdate), 50, false);
|
||||
_timer->addTimer(0x35, TimerV2(timerSpecialCharacterUpdate), 50, false);
|
||||
_timer->addTimer(4, TimerV2(timerProcessDoors), 5, true);
|
||||
_timer->addTimer(5, TimerV2(timerUpdateTeleporters), 10, true);
|
||||
_timer->addTimer(6, TimerV2(timerUpdateFoodStatus), 1080, true);
|
||||
_timer->addTimer(7, TimerV2(timerUpdateMonsterIdleAnim), 25, true);
|
||||
}
|
||||
|
||||
void EobCoreEngine::setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer) {
|
||||
uint32 ntime = _system->getMillis() + countdown * _tickLength;
|
||||
uint8 timerId = 0x30 | (charIndex & 0x0f);
|
||||
EobCharacter *c = &_characters[charIndex];
|
||||
|
||||
if (!_timer->isEnabled(timerId)) {
|
||||
c->timers[0] = ntime;
|
||||
c->events[0] = evnt;
|
||||
_timer->setCountdown(timerId, countdown);
|
||||
enableTimer(timerId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ntime < _timer->getNextRun(timerId))
|
||||
_timer->setNextRun(timerId, ntime);
|
||||
|
||||
if (updateExistingTimer) {
|
||||
bool br = false;
|
||||
int d = -1;
|
||||
|
||||
for (int i = 0; i < 10 && br == false; i++) {
|
||||
if (d == -1 && !c->timers[i])
|
||||
d = i;
|
||||
|
||||
if (!br && c->events[i] == evnt) {
|
||||
d = i;
|
||||
br = true;
|
||||
}
|
||||
}
|
||||
|
||||
c->timers[d] = ntime;
|
||||
c->events[d] = evnt;
|
||||
} else {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (c->timers[i])
|
||||
continue;
|
||||
c->timers[i] = ntime;
|
||||
c->events[i] = evnt;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::deleteCharEventTimer(int charIndex, int evnt) {
|
||||
EobCharacter *c = &_characters[charIndex];
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (c->events[i] == evnt) {
|
||||
c->events[i] = 0;
|
||||
c->timers[i] = 0;
|
||||
}
|
||||
}
|
||||
setupCharacterTimers();
|
||||
}
|
||||
|
||||
void EobCoreEngine::setupCharacterTimers() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
EobCharacter *c = &_characters[i];
|
||||
if (!testCharacter(i, 1))
|
||||
continue;
|
||||
|
||||
uint32 nextTimer = 0xffffffff;
|
||||
|
||||
for (int ii = 0; ii < 10; ii++) {
|
||||
if (c->timers[ii] < nextTimer)
|
||||
nextTimer = c->timers[ii];
|
||||
}
|
||||
uint32 ctime = _system->getMillis();
|
||||
|
||||
if (nextTimer == 0xffffffff)
|
||||
_timer->disable(0x30 | i);
|
||||
else {
|
||||
enableTimer(0x30 | i);
|
||||
_timer->setCountdown(0x30 | i, (nextTimer - ctime) / _tickLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::timerProcessCharacterExchange(int timerNum) {
|
||||
_charExchangeSwap ^= 1;
|
||||
if (_charExchangeSwap) {
|
||||
int index = _exchangeCharacterId;
|
||||
_exchangeCharacterId = -1;
|
||||
gui_drawCharPortraitWithStats(index);
|
||||
_exchangeCharacterId = index;
|
||||
} else {
|
||||
gui_drawCharPortraitWithStats(_exchangeCharacterId);
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::timerProcessFlyingObjects(int timerNum) {
|
||||
static const uint8 dirPosIndex[] = { 0x82, 0x83, 0x00, 0x01, 0x01, 0x80, 0x03, 0x82, 0x02, 0x03, 0x80, 0x81, 0x81, 0x00, 0x83, 0x02 };
|
||||
for (int i = 0; i < 10; i++) {
|
||||
EobFlyingObject *fo = &_flyingObjects[i];
|
||||
if (!fo->enable)
|
||||
continue;
|
||||
|
||||
bool endFlight = fo->distance ? false : true;
|
||||
|
||||
uint8 pos = dirPosIndex[(fo->direction << 2) + (fo->curPos & 3)];
|
||||
uint16 bl = fo->curBlock;
|
||||
bool newBl = (pos & 0x80) ? true : false;
|
||||
|
||||
if (newBl) {
|
||||
bl = calcNewBlockPosition(fo->curBlock, fo->direction);
|
||||
pos &= 3;
|
||||
fo->u2 = 0;
|
||||
}
|
||||
|
||||
if (updateObjectFlight(fo, bl, pos)) {
|
||||
if (newBl)
|
||||
runLevelScript(bl, 0x10);
|
||||
if (updateFlyingObjectHitTest(fo, bl, pos))
|
||||
endFlight = true;
|
||||
} else {
|
||||
if (fo->flags & 0x20) {
|
||||
if (!updateFlyingObjectHitTest(fo, fo->curBlock, fo->curPos))
|
||||
updateFlyingObject_s3(fo);
|
||||
}
|
||||
endFlight = true;
|
||||
}
|
||||
|
||||
if (endFlight)
|
||||
endObjectFlight(fo);
|
||||
|
||||
_sceneUpdateRequired = true;
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::timerProcessMonsters(int timerNum) {
|
||||
updateMonsters(timerNum & 0x0f);
|
||||
}
|
||||
|
||||
|
||||
void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
|
||||
int charIndex = timerNum & 0x0f;
|
||||
EobCharacter *c = &_characters[charIndex];
|
||||
uint32 ctime = _system->getMillis();
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (!c->timers[i])
|
||||
continue;
|
||||
if (c->timers[i] > ctime)
|
||||
continue;
|
||||
|
||||
c->timers[i] = 0;
|
||||
int evt = c->events[i];
|
||||
|
||||
if (evt < 0) {
|
||||
removeCharacterEffect(evt, charIndex, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (evt) {
|
||||
case 2:
|
||||
case 3:
|
||||
setCharEventTimer(charIndex, (c->effectFlags & 0x10000) ? 9 : 36, evt + 2, 1);
|
||||
case 0:
|
||||
case 1:
|
||||
case 4:
|
||||
case 5:
|
||||
setWeaponSlotStatus(charIndex, evt / 2, evt & 1);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
c->damageTaken = 0;
|
||||
gui_drawCharPortraitWithStats(charIndex);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
_txt->printMessage(_characterStatusStrings7[0], -1, c->name);
|
||||
c->strengthCur = c->strengthMax;
|
||||
c->strengthExtCur = c->strengthExtMax;
|
||||
if (_currentControlMode == 2)
|
||||
gui_drawCharPortraitWithStats(charIndex);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if (c->flags & 2) {
|
||||
calcAndInflictCharacterDamage(charIndex, 0, 0, 5, 0x400, 5, 3);
|
||||
setCharEventTimer(charIndex, 546, 8, 1);
|
||||
} else {
|
||||
c->flags &= 0xfd;
|
||||
gui_drawCharPortraitWithStats(charIndex);
|
||||
}
|
||||
break;
|
||||
|
||||
case 9:
|
||||
if (c->flags & 4) {
|
||||
_txt->printMessage(_characterStatusStrings9[0], -1, c->name);
|
||||
c->flags &= 0xfb;
|
||||
gui_drawCharPortraitWithStats(charIndex);
|
||||
}
|
||||
break;
|
||||
|
||||
case 11:
|
||||
if (c->disabledSlots & 4) {
|
||||
c->disabledSlots &= 0xfb;
|
||||
if (_openBookChar == charIndex && _updateFlags)
|
||||
gui_drawSpellbook();
|
||||
}
|
||||
break;
|
||||
|
||||
case 12:
|
||||
c->effectFlags &= ~0x1000;
|
||||
_txt->printMessage(_characterStatusStrings12[0], -1, c->name);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 nextTimer = (uint32)(-1);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (c->timers[i] && c->timers[i] < nextTimer)
|
||||
nextTimer = c->timers[i];
|
||||
}
|
||||
|
||||
if (nextTimer == (uint32)(-1))
|
||||
_timer->disable(timerNum);
|
||||
else
|
||||
_timer->setCountdown(timerNum, (nextTimer - ctime) / _tickLength);
|
||||
}
|
||||
|
||||
void EobCoreEngine::timerUpdateTeleporters(int timerNum) {
|
||||
_teleporterPulse ^= 1;
|
||||
for (int i = 0; i < 18; i++) {
|
||||
uint8 w = _visibleBlocks[i]->walls[_sceneDrawVarDown];
|
||||
if (w == 44 || w == 74) {
|
||||
_sceneUpdateRequired = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::timerUpdateFoodStatus(int timerNum) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (checkInventoryForRings(i, 2))
|
||||
continue;
|
||||
EobCharacter *c = &_characters[i];
|
||||
if (c->food != 0 && c->flags & 1 && c->hitPointsCur > -10) {
|
||||
c->food--;
|
||||
gui_drawFoodStatusGraph(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::timerUpdateMonsterIdleAnim(int timerNum) {
|
||||
for (int i = 0; i < 18; i++) {
|
||||
EobMonsterInPlay *m = &_monsters[i];
|
||||
if (m->mode == 7 || m->mode == 10 || (m->flags & 0x20) || (rollDice(1, 2, 0) != 1))
|
||||
continue;
|
||||
m->idleAnimState = (rollDice(1, 2, 0) << 4) | rollDice(1, 2, 0);
|
||||
checkSceneUpdateNeed(m->block);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
@ -47,58 +47,6 @@ void LoLEngine::setupTimers() {
|
||||
_timer->addTimer(11, TimerV2(timerFadeMessageText), 360, false);
|
||||
}
|
||||
|
||||
void LoLEngine::enableTimer(int id) {
|
||||
_timer->enable(id);
|
||||
_timer->setCountdown(id, _timer->getDelay(id));
|
||||
}
|
||||
|
||||
void LoLEngine::enableSysTimer(int sysTimer) {
|
||||
if (sysTimer != 2)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _numClock2Timers; i++)
|
||||
_timer->pauseSingleTimer(_clock2Timers[i], false);
|
||||
}
|
||||
|
||||
void LoLEngine::disableSysTimer(int sysTimer) {
|
||||
if (sysTimer != 2)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _numClock2Timers; i++)
|
||||
_timer->pauseSingleTimer(_clock2Timers[i], true);
|
||||
}
|
||||
|
||||
void LoLEngine::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 = 31;
|
||||
|
||||
int flg = _wllWallFlags[_levelBlockProperties[b].walls[c]];
|
||||
if (flg & 0x20)
|
||||
snd = 33;
|
||||
else if (v == -1)
|
||||
snd = 32;
|
||||
|
||||
if (!(_updateFlags & 1)) {
|
||||
snd_processEnvironmentalSoundEffect(snd, b);
|
||||
if (!checkSceneUpdateNeed(b))
|
||||
updateEnvironmentalSfx(0);
|
||||
}
|
||||
|
||||
if (flg & 0x30)
|
||||
_openDoorState[i].block = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::timerProcessMonsters(int timerNum) {
|
||||
for (int i = timerNum & 0x0f; i < 30; i += 2)
|
||||
updateMonster(&_monsters[i]);
|
||||
|
Loading…
Reference in New Issue
Block a user