aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/lol.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/kyra/lol.cpp')
-rw-r--r--engines/kyra/lol.cpp440
1 files changed, 298 insertions, 142 deletions
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 3461fa5da9..020e1ea3ea 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -82,7 +82,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_curTlkFile = -1;
_lastSpeaker = _lastSpeechId = _nextSpeechId = _nextSpeaker = -1;
- memset(_moneyColumnHeight, 0, 5);
+ memset(_moneyColumnHeight, 0, sizeof(_moneyColumnHeight));
_credits = 0;
_itemsInPlay = 0;
@@ -200,7 +200,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_partyPosX = _partyPosY = 0;
_shpDmX = _shpDmY = _dmScaleW = _dmScaleH = 0;
- _floatingMouseArrowControl = 0;
+ _floatingCursorControl = _currentFloatingCursor = 0;
memset(_activeTim, 0, sizeof(_activeTim));
memset(_openDoorState, 0, sizeof(_openDoorState));
@@ -222,10 +222,6 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_preserveEvents = false;
_buttonList1 = _buttonList2 = _buttonList3 = _buttonList4 = _buttonList5 = _buttonList6 = _buttonList7 = _buttonList8 = 0;
- _monsterDifficulty = 1;
- _smoothScrollingEnabled = true;
- _floatingCursorsEnabled = false;
-
memset(_lvlTempData, 0, sizeof(_lvlTempData));
_mapOverlay = 0;
@@ -436,6 +432,7 @@ Common::Error LoLEngine::init() {
_gui = new GUI_LoL(this);
assert(_gui);
+ _gui->initStaticData();
_txt = new TextDisplayer_LoL(this, _screen);
@@ -456,8 +453,6 @@ Common::Error LoLEngine::init() {
if (!_sound->init())
error("Couldn't init sound");
- _speechFlag = speechEnabled() ? 0x48 : 0;
-
_wllVmpMap = new uint8[80];
memset(_wllVmpMap, 0, 80);
_wllShapeMap = new int8[80];
@@ -561,7 +556,7 @@ Common::Error LoLEngine::go() {
// Usually fonts etc. would be setup by the prologue code, if we skip
// the prologue code we need to setup them manually here.
- if (_gameToLoad != -1) {
+ if (_gameToLoad != -1 && action != 3) {
preInit();
_screen->setFont(Screen::FID_9_FNT);
}
@@ -591,8 +586,6 @@ Common::Error LoLEngine::go() {
if (loadGameState(_gameToLoad) != Common::kNoError)
error("Couldn't load game slot %d on startup", _gameToLoad);
_gameToLoad = -1;
- } else if (action == 3) {
- // XXX
}
_screen->_fadeFlag = 3;
@@ -639,6 +632,15 @@ void LoLEngine::loadItemIconShapes() {
_itemIconShapes[i] = _screen->makeShapeCopy(shp, i);
_screen->setMouseCursor(0, 0, _itemIconShapes[0]);
+
+ if (!_gameShapes) {
+ _screen->loadBitmap("GAMESHP.SHP", 3, 3, 0);
+ shp = _screen->getCPagePtr(3);
+ _numGameShapes = READ_LE_UINT16(shp);
+ _gameShapes = new uint8*[_numGameShapes];
+ for (int i = 0; i < _numGameShapes; i++)
+ _gameShapes[i] = _screen->makeShapeCopy(shp, i);
+ }
}
void LoLEngine::setMouseCursorToIcon(int icon) {
@@ -661,6 +663,53 @@ bool LoLEngine::posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, in
return true;
}
+void LoLEngine::checkFloatingPointerRegions() {
+ if (!_floatingCursorsEnabled)
+ return;
+
+ int t = -1;
+
+ Common::Point p = getMousePos();
+
+ if (!(_updateFlags & 4) & !_floatingCursorControl) {
+ if (posWithinRect(p.x, p.y, 96, 0, 303, 136)) {
+ if (!posWithinRect(p.x, p.y, 128, 16, 271, 119)) {
+ if (posWithinRect(p.x, p.y, 112, 0, 287, 15))
+ t = 0;
+ if (posWithinRect(p.x, p.y, 272, 88, 303, 319))
+ t = 1;
+ if (posWithinRect(p.x, p.y, 112, 110, 287, 135))
+ t = 2;
+ if (posWithinRect(p.x, p.y, 96, 88, 127, 119))
+ t = 3;
+ if (posWithinRect(p.x, p.y, 96, 16, 127, 87))
+ t = 4;
+ if (posWithinRect(p.x, p.y, 272, 16, 303, 87))
+ t = 5;
+
+ if (t < 4) {
+ int d = (_currentDirection + t) & 3;
+ if (!checkBlockPassability(calcNewBlockPosition(_currentBlock, d), d))
+ t = 6;
+ }
+ }
+ }
+ }
+
+ if (t == _currentFloatingCursor)
+ return;
+
+ if (t == -1) {
+ setMouseCursorToItemInHand();
+ } else {
+ static const uint8 floatingPtrX[] = { 7, 13, 7, 0, 0, 15, 7 };
+ static const uint8 floatingPtrY[] = { 0, 7, 12, 7, 6, 6, 7 };
+ _screen->setMouseCursor(floatingPtrX[t], floatingPtrY[t], _gameShapes[10 + t]);
+ }
+
+ _currentFloatingCursor = t;
+}
+
uint8 *LoLEngine::getItemIconShapePtr(int index) {
int ix = _itemProperties[_itemsInPlay[index].itemPropertyIndex].shpIndex;
if (_itemProperties[_itemsInPlay[index].itemPropertyIndex].flags & 0x200)
@@ -714,7 +763,7 @@ int LoLEngine::mainMenu() {
assert(menu);
menu->init(data[dataIndex], MainMenu::Animation());
- int selection = menu->handle(_flags.isTalkie ? (hasSave ? 17 : 6) : (hasSave ? 6 : 18));
+ int selection = menu->handle(_flags.isTalkie ? (hasSave ? 19 : 6) : (hasSave ? 6 : 20));
delete menu;
_screen->setScreenDim(0);
@@ -729,20 +778,20 @@ int LoLEngine::mainMenu() {
void LoLEngine::startup() {
_screen->clearPage(0);
- _screen->loadBitmap("PLAYFLD.CPS", 3, 3, _screen->_currentPalette);
- uint8 *tmpPal = new uint8[0x300];
- memcpy(tmpPal, _screen->_currentPalette, 0x300);
- memset(_screen->_currentPalette, 0x3f, 0x180);
- memcpy(_screen->_currentPalette + 3, tmpPal + 3, 3);
- memset(_screen->_currentPalette + 0x240, 0x3f, 12);
- _screen->generateOverlay(_screen->_currentPalette, _screen->_paletteOverlay1, 1, 96);
- _screen->generateOverlay(_screen->_currentPalette, _screen->_paletteOverlay2, 144, 65);
- memcpy(_screen->_currentPalette, tmpPal, 0x300);
- delete[] tmpPal;
+ Palette &pal = _screen->getPalette(0);
+ _screen->loadBitmap("PLAYFLD.CPS", 3, 3, &pal);
- memset(_screen->getPalette(1), 0, 0x300);
- memset(_screen->getPalette(2), 0, 0x300);
+ _screen->copyPalette(1, 0);
+ pal.fill(0, 1, 0x3F);
+ pal.fill(2, 126, 0x3F);
+ pal.fill(192, 4, 0x3F);
+ _screen->generateOverlay(pal, _screen->_paletteOverlay1, 1, 96);
+ _screen->generateOverlay(pal, _screen->_paletteOverlay2, 144, 65);
+ _screen->copyPalette(0, 1);
+
+ _screen->getPalette(1).clear();
+ _screen->getPalette(2).clear();
loadItemIconShapes();
_screen->setMouseCursor(0, 0, _itemIconShapes[0x85]);
@@ -754,13 +803,6 @@ void LoLEngine::startup() {
for (int i = 0; i < _numItemShapes; i++)
_itemShapes[i] = _screen->makeShapeCopy(shp, i);
- _screen->loadBitmap("GAMESHP.SHP", 3, 3, 0);
- shp = _screen->getCPagePtr(3);
- _numGameShapes = READ_LE_UINT16(shp);
- _gameShapes = new uint8*[_numGameShapes];
- for (int i = 0; i < _numGameShapes; i++)
- _gameShapes[i] = _screen->makeShapeCopy(shp, i);
-
_screen->loadBitmap("THROWN.SHP", 3, 3, 0);
shp = _screen->getCPagePtr(3);
_numThrownShapes = READ_LE_UINT16(shp);
@@ -808,9 +850,6 @@ void LoLEngine::startup() {
_loadSuppFilesFlag = 1;
- _txt->setAnimParameters("<MORE>", 10, 31, 0);
- _txt->setAnimFlag(true);
-
_sound->loadSfxFile("LORESFX");
setMouseCursorToItemInHand();
@@ -822,12 +861,6 @@ void LoLEngine::startupNew() {
_compassDirection = _compassDirectionIndex = -1;
_lastMouseRegion = -1;
-
- /*
- _unk5 = 1;
- _unk6 = 1;
- _unk7 = 1
- _unk8 = 1*/
_currentLevel = 1;
giveCredits(41, 0);
@@ -858,6 +891,12 @@ void LoLEngine::runLoop() {
_flagsTable[73] |= 0x08;
while (!shouldQuit() && _runFlag) {
+ if (_gameToLoad != -1) {
+ if (loadGameState(_gameToLoad) != Common::kNoError)
+ error("Couldn't load game slot %d", _gameToLoad);
+ _gameToLoad = -1;
+ }
+
if (_nextScriptFunc) {
runLevelScript(_nextScriptFunc, 2);
_nextScriptFunc = 0;
@@ -865,7 +904,7 @@ void LoLEngine::runLoop() {
_timer->update();
- //checkFloatingPointerRegions();
+ checkFloatingPointerRegions();
gui_updateInput();
update();
@@ -884,6 +923,55 @@ void LoLEngine::runLoop() {
}
}
+void LoLEngine::registerDefaultSettings() {
+ KyraEngine_v1::registerDefaultSettings();
+
+ // Most settings already have sensible defaults. This one, however, is
+ // specific to the LoL engine.
+ ConfMan.registerDefault("floating_cursors", false);
+ ConfMan.registerDefault("smooth_scrolling", true);
+ ConfMan.registerDefault("monster_difficulty", 1);
+}
+
+void LoLEngine::writeSettings() {
+ ConfMan.setInt("monster_difficulty", _monsterDifficulty);
+ ConfMan.setBool("floating_cursors", _floatingCursorsEnabled);
+ ConfMan.setBool("smooth_scrolling", _smoothScrollingEnabled);
+
+ switch (_lang) {
+ case 1:
+ _flags.lang = Common::FR_FRA;
+ break;
+
+ case 2:
+ _flags.lang = Common::DE_DEU;
+ break;
+
+ case 3:
+ _flags.lang = Common::JA_JPN;
+ break;
+
+ case 0:
+ default:
+ _flags.lang = Common::EN_ANY;
+ }
+
+ if (_flags.lang == _flags.replacedLang && _flags.fanLang != Common::UNK_LANG)
+ _flags.lang = _flags.fanLang;
+
+ ConfMan.set("language", Common::getLanguageCode(_flags.lang));
+
+ KyraEngine_v1::writeSettings();
+}
+
+void LoLEngine::readSettings() {
+ _monsterDifficulty = ConfMan.getInt("monster_difficulty");
+ _smoothScrollingEnabled = ConfMan.getBool("smooth_scrolling");
+ _floatingCursorsEnabled = ConfMan.getBool("floating_cursors");
+
+ KyraEngine_v1::readSettings();
+}
+
void LoLEngine::update() {
updateSequenceBackgroundAnimations();
@@ -1095,7 +1183,7 @@ void LoLEngine::updatePortraitSpeechAnim() {
f -= 5;
f += 7;
- if (_speechFlag) {
+ if (speechEnabled()) {
if (snd_updateCharacterSpeech() == 2)
_updatePortraitSpeechAnimDuration = 2;
else
@@ -1233,7 +1321,7 @@ void LoLEngine::setCharacterMagicOrHitPoints(int charNum, int type, int points,
if (charNum > 3)
return;
-
+
LoLCharacter *c = &_characters[charNum];
if (!(c->flags & 1))
return;
@@ -1421,7 +1509,7 @@ void LoLEngine::gui_specialSceneSuspendControls(int controlMode) {
_specialSceneFlag = 1;
_currentControlMode = controlMode;
calcCharPortraitXpos();
- //checkMouseRegions();
+ checkFloatingPointerRegions();
}
void LoLEngine::gui_specialSceneRestoreControls(int restoreLamp) {
@@ -1431,7 +1519,7 @@ void LoLEngine::gui_specialSceneRestoreControls(int restoreLamp) {
}
_updateFlags &= 0xfffe;
_specialSceneFlag = 0;
- //checkMouseRegions();
+ checkFloatingPointerRegions();
}
void LoLEngine::restoreAfterSceneWindowDialogue(int redraw) {
@@ -1450,7 +1538,7 @@ void LoLEngine::restoreAfterSceneWindowDialogue(int redraw) {
if (_screen->_fadeFlag != 2)
_screen->fadeClearSceneWindow(10);
gui_drawPlayField();
- setPaletteBrightness(_screen->_currentPalette, _brightness, _lampEffect);
+ setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
_screen->_fadeFlag = 0;
}
@@ -1584,15 +1672,16 @@ void LoLEngine::transformRegion(int x1, int y1, int x2, int y2, int w, int h, in
}
}
-void LoLEngine::setPaletteBrightness(uint8 *palette, int brightness, int modifier) {
- generateBrightnessPalette(palette, _screen->getPalette(1), brightness, modifier);
+void LoLEngine::setPaletteBrightness(const Palette &srcPal, int brightness, int modifier) {
+ generateBrightnessPalette(srcPal, _screen->getPalette(1), brightness, modifier);
_screen->fadePalette(_screen->getPalette(1), 5, 0);
_screen->_fadeFlag = 0;
}
-void LoLEngine::generateBrightnessPalette(uint8 *src, uint8 *dst, int brightness, int modifier) {
- memcpy(dst, src, 0x300);
+void LoLEngine::generateBrightnessPalette(const Palette &src, Palette &dst, int brightness, int modifier) {
+ dst.copy(src);
_screen->loadSpecialColors(dst);
+
brightness = (8 - brightness) << 5;
if (modifier >= 0 && modifier < 8 && (_flagsTable[31] & 0x08)) {
brightness = 256 - ((((modifier & 0xfffe) << 5) * (256 - brightness)) >> 8);
@@ -1606,26 +1695,21 @@ void LoLEngine::generateBrightnessPalette(uint8 *src, uint8 *dst, int brightness
}
}
-void LoLEngine::generateFlashPalette(uint8 *src, uint8 *dst, int colorFlags) {
- if (!src || !dst)
- return;
-
- memcpy(dst, src, 6);
-
- uint8 *s = src + 6;
- uint8 *d = dst + 6;
+void LoLEngine::generateFlashPalette(const Palette &src, Palette &dst, int colorFlags) {
+ dst.copy(src, 0, 2);
for (int i = 2; i < 128; i++) {
for (int ii = 0; ii < 3; ii++) {
- uint8 t = *s++ & 0x3f;
+ uint8 t = src[i * 3 + ii] & 0x3f;
if (colorFlags & (1 << ii))
t += ((0x3f - t) >> 1);
else
t -= (t >> 1);
- *d++ = t;
+ dst[i * 3 + ii] = t;
}
}
- memcpy(d, s, 384);
+
+ dst.copy(src, 128);
}
void LoLEngine::updateSequenceBackgroundAnimations() {
@@ -1790,32 +1874,6 @@ void LoLEngine::delay(uint32 millis, bool doUpdate, bool) {
}
}
-uint8 LoLEngine::getRandomNumberSpecial() {
- uint8 a = _rndSpecial & 0xff;
- uint8 b = (_rndSpecial >> 8) & 0xff;
- uint8 c = (_rndSpecial >> 16) & 0xff;
-
- a >>= 1;
-
- uint as = a & 1;
- uint bs = (b >> 7) ? 0 : 1;
- uint cs = c >> 7;
-
- a >>= 1;
- c = (c << 1) | as;
- b = (b << 1) | cs;
-
- a -= ((_rndSpecial & 0xff) - bs);
- as = a & 1;
- a >>= 1;
-
- a = ((_rndSpecial & 0xff) >> 1) | (as << 7);
-
- _rndSpecial = (_rndSpecial & 0xff000000) | (c << 16) | (b << 8) | a;
-
- return a ^ b;
-}
-
void LoLEngine::updateEnvironmentalSfx(int soundId) {
snd_processEnvironmentalSoundEffect(soundId, _currentBlock);
}
@@ -1919,7 +1977,7 @@ int LoLEngine::castHealOnSingleCharacter(ActiveSpell *a) {
}
int LoLEngine::processMagicSpark(int charNum, int spellLevel) {
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
_screen->copyPage(0, 12);
mov->open("spark1.wsa", 0, 0);
@@ -2120,25 +2178,24 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
gui_drawScene(0);
_screen->copyPage(0, 12);
- uint8 *tpal = new uint8[768];
- uint8 *swampCol = new uint8[768];
+ Palette tpal(768), swampCol(768);
if (_currentLevel == 11 && !(_flagsTable[52] & 0x04)) {
- uint8 *sc = _screen->_currentPalette;
- uint8 *dc = _screen->getPalette(2);
+ uint8 *sc = _screen->getPalette(0).getData();
+ uint8 *dc = _screen->getPalette(2).getData();
for (int i = 1; i < 768; i++)
SWAP(sc[i], dc[i]);
+
_flagsTable[52] |= 0x04;
static const uint8 freezeTimes[] = { 20, 28, 40, 60 };
setCharacterUpdateEvent(charNum, 8, freezeTimes[spellLevel], 1);
}
- uint8 *sc = _res->fileData("swampice.col", 0);
- memcpy(swampCol, sc, 384);
- uint8 *s = _screen->getPalette(1);
- for (int i = 384; i < 768; i++)
- swampCol[i] = tpal[i] = s[i] & 0x3f;
+ _screen->loadPalette("SWAMPICE.COL", swampCol);
+ tpal.copy(_screen->getPalette(1), 128);
+ swampCol.copy(_screen->getPalette(1), 128);
+ Palette &s = _screen->getPalette(1);
for (int i = 1; i < 128; i++) {
tpal[i * 3] = 0;
uint16 v = (s[i * 3] + s[i * 3 + 1] + s[i * 3 + 2]) / 3;
@@ -2148,24 +2205,25 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
if (tpal[i * 3 + 2] > 0x3f)
tpal[i * 3 + 2] = 0x3f;
}
+
generateBrightnessPalette(tpal, tpal, _brightness, _lampEffect);
generateBrightnessPalette(swampCol, swampCol, _brightness, _lampEffect);
swampCol[0] = swampCol[1] = swampCol[2] = tpal[0] = tpal[1] = tpal[2] = 0;
- generateBrightnessPalette(_screen->_currentPalette, s, _brightness, _lampEffect);
+ generateBrightnessPalette(_screen->getPalette(0), s, _brightness, _lampEffect);
int sX = 112;
int sY = 0;
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
if (spellLevel == 0) {
sX = 0;
} if (spellLevel == 1 || spellLevel == 2) {
- mov->open("snow.wsa", 1, 0);
+ mov->open("SNOW.WSA", 1, 0);
if (!mov->opened())
error("Ice: Unable to load snow.wsa");
} if (spellLevel == 3) {
- mov->open("ice.wsa", 1, 0);
+ mov->open("ICE.WSA", 1, 0);
if (!mov->opened())
error("Ice: Unable to load ice.wsa");
sX = 136;
@@ -2174,9 +2232,9 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
snd_playSoundEffect(71, -1);
- playSpellAnimation(0, 0, 0, 2, 0, 0, 0, s, tpal, 40, false);
+ playSpellAnimation(0, 0, 0, 2, 0, 0, 0, s.getData(), tpal.getData(), 40, false);
- _screen->fadePaletteStep(s, tpal, _system->getMillis(), _tickLength);
+ _screen->fadePaletteStep(s.getData(), tpal.getData(), _system->getMillis(), _tickLength);
if (mov->opened()) {
int r = true;
if (spellLevel > 2) {
@@ -2241,22 +2299,19 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
enableSysTimer(2);
if (_currentLevel != 11)
- generateBrightnessPalette(_screen->_currentPalette, swampCol, _brightness, _lampEffect);
+ generateBrightnessPalette(_screen->getPalette(0), swampCol, _brightness, _lampEffect);
- playSpellAnimation(0, 0, 0, 2, 0, 0, 0, tpal, swampCol, 40, 0);
+ playSpellAnimation(0, 0, 0, 2, 0, 0, 0, tpal.getData(), swampCol.getData(), 40, 0);
- _screen->fadePaletteStep(tpal, swampCol, _system->getMillis(), _tickLength);
+ _screen->fadePaletteStep(tpal.getData(), swampCol.getData(), _system->getMillis(), _tickLength);
if (breakWall)
- breakIceWall(tpal, swampCol);
+ breakIceWall(tpal.getData(), swampCol.getData());
static const uint8 freezeTime[] = { 20, 28, 40, 60 };
if (_currentLevel == 11)
setCharacterUpdateEvent(charNum, 8, freezeTime[spellLevel], 1);
- delete[] sc;
- delete[] swampCol;
- delete[] tpal;
_screen->setCurPage(cp);
return 1;
}
@@ -2417,7 +2472,7 @@ int LoLEngine::processMagicHandOfFate(int spellLevel) {
int cp = _screen->setCurPage(2);
_screen->copyPage(0, 12);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open("hand.wsa", 1, 0);
if (!mov->opened())
error("Hand: Unable to load HAND.WSA");
@@ -2495,8 +2550,8 @@ int LoLEngine::processMagicHandOfFate(int spellLevel) {
int LoLEngine::processMagicMistOfDoom(int charNum, int spellLevel) {
static const uint8 mistDamage[] = { 30, 70, 110, 200 };
-
- _envSfxUseQueue = true;
+
+ _envSfxUseQueue = true;
inflictMagicalDamageForBlock(calcNewBlockPosition(_currentBlock, _currentDirection), charNum, mistDamage[spellLevel], 0x80);
_envSfxUseQueue = false;
@@ -2509,7 +2564,7 @@ int LoLEngine::processMagicMistOfDoom(int charNum, int spellLevel) {
char wsafile[13];
snprintf(wsafile, 13, "mists%0d.wsa", spellLevel + 1);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open(wsafile, 1, 0);
if (!mov->opened())
error("Mist: Unable to load mists.wsa");
@@ -2541,7 +2596,7 @@ int LoLEngine::processMagicLightning(int charNum, int spellLevel) {
char wsafile[13];
snprintf(wsafile, 13, "litning%d.wsa", spellLevel + 1);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open(wsafile, 1, 0);
if (!mov->opened())
error("Litning: Unable to load litning.wsa");
@@ -2570,7 +2625,7 @@ int LoLEngine::processMagicFog() {
int cp = _screen->setCurPage(2);
_screen->copyPage(0, 12);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
int numFrames = mov->open("fog.wsa", 0, 0);
if (!mov->opened())
error("Fog: Unable to load fog.wsa");
@@ -2646,7 +2701,7 @@ int LoLEngine::processMagicSwarm(int charNum, int damage) {
_monsters[destIds[i]].fightCurTick = destTicks[i];
}
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open("swarm.wsa", 0, 0);
if (!mov->opened())
@@ -2671,7 +2726,7 @@ int LoLEngine::processMagicSwarm(int charNum, int damage) {
int LoLEngine::processMagicVaelansCube() {
uint8 *tmpPal1 = new uint8[768];
uint8 *tmpPal2 = new uint8[768];
- uint8 *sp1 = _screen->getPalette(1);
+ uint8 *sp1 = _screen->getPalette(1).getData();
memcpy(tmpPal1, sp1, 768);
memcpy(tmpPal2, sp1, 768);
@@ -2734,7 +2789,7 @@ int LoLEngine::processMagicGuardian(int charNum) {
_screen->copyPage(0, 2);
_screen->copyPage(2, 12);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open("guardian.wsa", 0, 0);
if (!mov->opened())
error("Guardian: Unable to load guardian.wsa");
@@ -2742,7 +2797,7 @@ int LoLEngine::processMagicGuardian(int charNum) {
playSpellAnimation(mov, 0, 37, 2, 112, 0, 0, 0, 0, 0, false);
_screen->copyPage(2, 12);
-
+
uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection);
int res = (_levelBlockProperties[bl].assignedObjects & 0x8000) ? 1 : 0;
inflictMagicalDamageForBlock(bl, charNum, 200, 0x80);
@@ -2754,7 +2809,7 @@ int LoLEngine::processMagicGuardian(int charNum) {
_screen->copyPage(2, 12);
snd_playSoundEffect(176, -1);
playSpellAnimation(mov, 38, 48, 8, 112, 0, 0, 0, 0, 0, false);
-
+
mov->close();
delete mov;
@@ -2771,20 +2826,22 @@ void LoLEngine::callbackProcessMagicSwarm(WSAMovie_v2 *mov, int x, int y) {
}
void LoLEngine::callbackProcessMagicLightning(WSAMovie_v2 *mov, int x, int y) {
- uint8 *tpal = new uint8[768];
if (_lightningDiv == 2)
shakeScene(1, 2, 3, 0);
- uint8 *p1 = _screen->getPalette(1);
+ const Palette &p1 = _screen->getPalette(1);
if (_lightningSfxFrame % _lightningDiv) {
_screen->setScreenPalette(p1);
} else {
- memcpy(tpal, p1, 768);
+ Palette tpal(p1.getNumColors());
+ tpal.copy(p1);
+
for (int i = 6; i < 384; i++) {
uint16 v = (tpal[i] * 120) / 64;
tpal[i] = (v < 64) ? v : 63;
}
+
_screen->setScreenPalette(tpal);
}
@@ -2799,7 +2856,55 @@ void LoLEngine::callbackProcessMagicLightning(WSAMovie_v2 *mov, int x, int y) {
}
_lightningSfxFrame++;
- delete[] tpal;
+}
+
+void LoLEngine::drinkBezelCup(int numUses, int charNum) {
+ int cp = _screen->setCurPage(2);
+ snd_playSoundEffect(73, -1);
+
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
+ mov->open("bezel.wsa", 0, 0);
+ if (!mov->opened())
+ error("Bezel: Unable to load bezel.wsa");
+
+ int x = _activeCharsXpos[charNum] - 11;
+ int y = 124;
+ int w = mov->width();
+ int h = mov->height();
+
+ _screen->copyRegion(x, y, 0, 0, w, h, 0, 2, Screen::CR_NO_P_CHECK);
+
+ static const uint8 bezelAnimData[] = { 0, 26, 20, 27, 61, 55, 62, 92, 86, 93, 131, 125 };
+ int frm = bezelAnimData[numUses * 3];
+ int hpDiff = _characters[charNum].hitPointsMax - _characters[charNum].hitPointsCur;
+ uint16 step = 0;
+
+ do {
+ step = (step & 0xff) + (hpDiff * 256) / (bezelAnimData[numUses * 3 + 2]);
+ increaseCharacterHitpoints(charNum, step / 256, true);
+ gui_drawCharPortraitWithStats(charNum);
+
+ uint32 etime = _system->getMillis() + 4 * _tickLength;
+
+ _screen->copyRegion(0, 0, x, y, w, h, 2, 2, Screen::CR_NO_P_CHECK);
+ mov->displayFrame(frm, 2, x, y, 0x5000, _trueLightTable1, _trueLightTable2);
+ _screen->copyRegion(x, y, x, y, w, h, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ delayUntil(etime);
+ } while (++frm < bezelAnimData[numUses * 3 + 1]);
+
+ _characters[charNum].hitPointsCur = _characters[charNum].hitPointsMax;
+ _screen->copyRegion(0, 0, x, y, w, h, 2, 2, Screen::CR_NO_P_CHECK);
+ removeCharacterEffects(&_characters[charNum], 4, 4);
+ gui_drawCharPortraitWithStats(charNum);
+ _screen->copyRegion(x, y, x, y, w, h, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ mov->close();
+ delete mov;
+
+ _screen->setCurPage(cp);
}
void LoLEngine::addSpellToScroll(int spell, int charNum) {
@@ -2871,7 +2976,7 @@ void LoLEngine::transferSpellToScollAnimation(int charNum, int spell, int slot)
snd_playSoundEffect(_updateSpellBookAnimData[(spell << 2) + 3], -1);
snd_playSoundEffect(95, -1);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open("getspell.wsa", 0, 0);
if (!mov->opened())
@@ -3282,6 +3387,52 @@ int LoLEngine::calcInflictableDamagePerItem(int16 attacker, int16 target, uint16
}
void LoLEngine::checkForPartyDeath() {
+ Button b;
+ b.data0Val2 = b.data1Val2 = b.data2Val2 = 0xfe;
+ b.data0Val3 = b.data1Val3 = b.data2Val3 = 0x01;
+
+ for (int i = 0; i < 4; i++) {
+ if (!(_characters[i].flags & 1) || _characters[i].hitPointsCur <= 0)
+ continue;
+ return;
+ }
+
+ if (_weaponsDisabled)
+ clickedExitCharInventory(&b);
+
+ gui_drawAllCharPortraitsWithStats();
+
+ if (_partyDamageFlags & 0x40) {
+ _screen->fadeToBlack(40);
+ for (int i = 0; i < 4; i++) {
+ if (_characters[i].flags & 1)
+ increaseCharacterHitpoints(i, 1, true);
+ }
+ gui_drawAllCharPortraitsWithStats();
+ _screen->fadeToPalette1(40);
+
+ } else {
+ _screen->fadeClearSceneWindow(10);
+ restoreAfterSpecialScene(0, 1, 1, 0);
+
+ snd_playTrack(325);
+ updatePortraits();
+ initTextFading(0, 1);
+ setMouseCursorToIcon(0);
+ _updateFlags |= 4;
+ setLampMode(true);
+ disableSysTimer(2);
+
+ _gui->runMenu(_gui->_deathMenu);
+
+ setMouseCursorToItemInHand();
+ _updateFlags &= 0xfffb;
+ resetLampStatus();
+
+ gui_enableDefaultPlayfieldButtons();
+ enableSysTimer(2);
+ updateDrawPage2();
+ }
}
void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, int16 damage) {
@@ -3499,16 +3650,16 @@ void LoLEngine::restoreSwampPalette() {
if (_currentLevel != 11)
return;
- uint8 *s = _screen->getPalette(2);
- uint8 *d = _screen->_currentPalette;
- uint8 *d2 = _screen->getPalette(1);
+ uint8 *s = _screen->getPalette(2).getData();
+ uint8 *d = _screen->getPalette(0).getData();
+ uint8 *d2 = _screen->getPalette(1).getData();
for (int i = 1; i < 768; i++)
SWAP(s[i], d[i]);
- generateBrightnessPalette(d, d2, _brightness, _lampEffect);
- _screen->loadSpecialColors(s);
- _screen->loadSpecialColors(d2);
+ generateBrightnessPalette(_screen->getPalette(0), _screen->getPalette(1), _brightness, _lampEffect);
+ _screen->loadSpecialColors(_screen->getPalette(2));
+ _screen->loadSpecialColors(_screen->getPalette(1));
playSpellAnimation(0, 0, 0, 2, 0, 0, 0, s, d2, 40, 0);
}
@@ -3529,7 +3680,7 @@ void LoLEngine::launchMagicViper() {
_screen->copyPage(0, 12);
snd_playSoundEffect(148, -1);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
int numFrames = mov->open("viper.wsa", 1, 0);
if (!mov->opened())
error("Viper: Unable to load viper.wsa");
@@ -3579,7 +3730,7 @@ void LoLEngine::breakIceWall(uint8 *pal1, uint8 *pal2) {
gui_drawScene(2);
_screen->copyPage(2, 10);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
int numFrames = mov->open("shatter.wsa", 1, 0);
if (!mov->opened())
error("Shatter: Unable to load shatter.wsa");
@@ -3681,7 +3832,7 @@ void LoLEngine::displayAutomap() {
uint8 *tmpWll = new uint8[80];
memcpy(tmpWll, _wllBuffer4, 80);
- _screen->loadBitmap("parch.cps", 2, 2, _screen->getPalette(3));
+ _screen->loadBitmap("parch.cps", 2, 2, &_screen->getPalette(3));
_screen->loadBitmap("autobut.shp", 3, 5, 0);
const uint8 *shp = _screen->getCPagePtr(5);
@@ -3848,12 +3999,17 @@ void LoLEngine::loadMapLegendData(int level) {
}
void LoLEngine::drawMapPage(int pageNum) {
+ // WORKAROUND for French version. The Text does not always properly fit the screen there.
+ int8 textOffset = (_lang == 1) ? -2 : 0;
+
for (int i = 0; i < 2; i++) {
- _screen->loadBitmap("parch.cps", pageNum, pageNum, _screen->getPalette(3));
+ _screen->loadBitmap("parch.cps", pageNum, pageNum, &_screen->getPalette(3));
+ if (_lang == 1)
+ _screen->copyRegion(236, 16, 236 + textOffset, 16, -textOffset, 1, pageNum, pageNum, Screen::CR_NO_P_CHECK);
int cp = _screen->setCurPage(pageNum);
Screen::FontId of = _screen->setFont(Screen::FID_9_FNT);
- _screen->printText(getLangString(_autoMapStrings[_currentMapLevel]), 236, 8, 1, 0);
+ _screen->printText(getLangString(_autoMapStrings[_currentMapLevel]), 236 + textOffset, 8, 1, 0);
uint16 blX = mapGetStartPosX();
uint16 bl = (mapGetStartPosY() << 5) + blX;
@@ -3932,7 +4088,7 @@ void LoLEngine::drawMapPage(int pageNum) {
if (l[2] == 0xffff)
continue;
- printMapText(l[2], 244, (tY << 3) + 22);
+ printMapText(l[2], 244 + textOffset, (tY << 3) + 22);
if (l[5] == 0xffff) {
tY++;
@@ -3942,7 +4098,7 @@ void LoLEngine::drawMapPage(int pageNum) {
uint16 cbl2 = l[3] + (l[4] << 5);
_levelBlockProperties[cbl2].flags |= 7;
_screen->drawShape(2, _automapShapes[l[5] << 2], (l[3] - sx) * 7 + _automapTopLeftX - 3, (l[4] - sy) * 6 + _automapTopLeftY - 3, 0, 0);
- _screen->drawShape(2, _automapShapes[l[5] << 2], 231, (tY << 3) + 19, 0, 0);
+ _screen->drawShape(2, _automapShapes[l[5] << 2], 231 + textOffset, (tY << 3) + 19, 0, 0);
tY++;
}
@@ -3951,9 +4107,9 @@ void LoLEngine::drawMapPage(int pageNum) {
for (int ii = 0; ii < 11; ii++) {
if (!_defaultLegendData[ii].enable)
continue;
- _screen->copyBlockAndApplyOverlay(_screen->_curPage, 235, (tY << 3) + 21, _screen->_curPage, 235, (tY << 3) + 21, 7, 6, 0, _mapOverlay);
- _screen->drawShape(_screen->_curPage, _automapShapes[_defaultLegendData[ii].shapeIndex << 2], 232, (tY << 3) + 18 + _defaultLegendData[ii].x, 0, 0);
- printMapText(_defaultLegendData[ii].stringId, 244, (tY << 3) + 22);
+ _screen->copyBlockAndApplyOverlay(_screen->_curPage, 235, (tY << 3) + 21, _screen->_curPage, 235 + textOffset, (tY << 3) + 21, 7, 6, 0, _mapOverlay);
+ _screen->drawShape(_screen->_curPage, _automapShapes[_defaultLegendData[ii].shapeIndex << 2], 232 + textOffset, (tY << 3) + 18 + _defaultLegendData[ii].x, 0, 0);
+ printMapText(_defaultLegendData[ii].stringId, 244 + textOffset, (tY << 3) + 22);
tY++;
}