aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dists/engine-data/kyra.datbin256570 -> 256787 bytes
-rw-r--r--engines/kyra/gui_lol.cpp6
-rw-r--r--engines/kyra/lol.cpp501
-rw-r--r--engines/kyra/lol.h44
-rw-r--r--engines/kyra/resource.h5
-rw-r--r--engines/kyra/scene_lol.cpp58
-rw-r--r--engines/kyra/screen_lol.cpp91
-rw-r--r--engines/kyra/screen_lol.h21
-rw-r--r--engines/kyra/script_lol.cpp2
-rw-r--r--engines/kyra/sprites_lol.cpp4
-rw-r--r--engines/kyra/staticres.cpp39
-rw-r--r--tools/create_kyradat/create_kyradat.cpp7
-rw-r--r--tools/create_kyradat/create_kyradat.h5
-rw-r--r--tools/create_kyradat/lol_cd.h5
-rw-r--r--tools/create_kyradat/misc.h5
15 files changed, 749 insertions, 44 deletions
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index e3f56b61f8..cedbdacc1d 100644
--- a/dists/engine-data/kyra.dat
+++ b/dists/engine-data/kyra.dat
Binary files differ
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index 20debbd0f2..10acb63b73 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -43,7 +43,7 @@ void LoLEngine::gui_drawPlayField() {
if (_gameFlags[15] & 0x1000)
// draw automap book
- _screen->drawShape(2, _gameShapes[78], 289, 32, 0, 0);
+ _screen->drawShape(2, _gameShapes[78], 290, 32, 0, 0);
int cp = _screen->setCurPage(2);
@@ -1372,7 +1372,7 @@ int LoLEngine::clickedWall(Button *button) {
break;
case 6:
- res = clicked6(block, dir);
+ res = clickedNiche(block, dir);
break;
default:
@@ -1451,7 +1451,7 @@ int LoLEngine::clickedAutomap(Button *button) {
if (!(_gameFlags[15] & 0x1000))
return 0;
- // displayAutopmap();
+ displayAutomap();
gui_drawPlayField();
setPaletteBrightness(_screen->_currentPalette, _brightness, _lampEffect);
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 558bbae6a4..106feafae1 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -28,6 +28,7 @@
#include "kyra/lol.h"
#include "kyra/screen_lol.h"
#include "kyra/resource.h"
+
#include "kyra/sound.h"
#include "kyra/timer.h"
#include "kyra/util.h"
@@ -213,6 +214,10 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
memset(_lvlTempData, 0, sizeof(_lvlTempData));
_unkIceSHpFlag = 0;
+
+ _mapOverlay = 0;
+ _automapShapes = 0;
+ _defaultLegendData = 0;
}
LoLEngine::~LoLEngine() {
@@ -285,6 +290,9 @@ LoLEngine::~LoLEngine() {
delete[] _monsterShapesEx;
}
+ if (_automapShapes)
+ delete[] _automapShapes;
+
for (Common::Array<const TIMOpcode*>::iterator i = _timIntroOpcodes.begin(); i != _timIntroOpcodes.end(); ++i)
delete *i;
_timIntroOpcodes.clear();
@@ -346,6 +354,10 @@ LoLEngine::~LoLEngine() {
delete _lvlTempData[i];
}
}
+
+ delete[] _defaultLegendData;
+ delete[] _mapCursorOverlay;
+ delete[] _mapOverlay;
}
Screen *LoLEngine::screen() {
@@ -453,6 +465,9 @@ Common::Error LoLEngine::init() {
_hasTempDataFlags = 0;
_unkCharNum = -1;
+ _automapShapes = new const uint8*[109];
+ _mapOverlay = new uint8[256];
+
return Common::kNoError;
}
@@ -1206,7 +1221,7 @@ void LoLEngine::gui_prepareForSequence(int x, int y, int w, int h, int buttonFla
_lastMouseRegion = -1;
if (w == 320) {
- setLampMode(0);
+ setLampMode(false);
_lampStatusSuspended = true;
}
}
@@ -1959,6 +1974,490 @@ void LoLEngine::generateTempData() {
_hasTempDataFlags |= (1 << l);
}
+// magic atlas
+
+void LoLEngine::displayAutomap() {
+ snd_playSoundEffect(105, -1);
+ gui_toggleButtonDisplayMode(78, 1);
+
+ _currentMapLevel = _currentLevel;
+ uint8 *tmpWll = new uint8[80];
+ memcpy(tmpWll, _wllBuffer4, 80);
+
+ _screen->loadBitmap("parch.cps", 2, 2, _screen->getPalette(3));
+ _screen->loadBitmap("autobut.shp", 3, 5, 0);
+ const uint8 *shp = _screen->getCPagePtr(5);
+
+ for (int i = 0; i < 109; i++)
+ _automapShapes[i] = _screen->getPtrToShape(shp, i + 11);
+
+ _screen->generateGrayOverlay(_screen->getPalette(3), _mapOverlay, 52, 0, 0, 0, 256, false);
+
+ _screen->loadFont(Screen::FID_9_FNT, "FONT9PN.FNT");
+ _screen->loadFont(Screen::FID_6_FNT, "FONT6PN.FNT");
+
+ for (int i = 0; i < 11; i++)
+ _defaultLegendData[i].enable = false;
+
+ disableSysTimer(2);
+ generateTempData();
+ resetItems(1);
+ disableMonsters();
+
+ bool exitAutomap = false;
+ _mapUpdateNeeded = false;
+
+ restoreBlockTempData(_currentMapLevel);
+ loadMapLegendData(_currentMapLevel);
+ _screen->fadeToBlack(10);
+ drawMapPage(2);
+
+ _screen->copyPage(2, 0);
+ _screen->updateScreen();
+ _screen->fadePalette(_screen->getPalette(3), 10);
+ _smoothScrollTimer = _system->getMillis() + 8 * _tickLength;
+
+ while (!exitAutomap) {
+ if (_mapUpdateNeeded) {
+ drawMapPage(2);
+ _screen->copyPage(2, 0);
+ _screen->updateScreen();
+ _mapUpdateNeeded = false;
+ }
+
+ if (_system->getMillis() >= _smoothScrollTimer) {
+ redrawMapCursor();
+ _smoothScrollTimer = _system->getMillis() + 8 * _tickLength;
+ }
+
+ int f = checkInput(0) & 0xff;
+ removeInputTop();
+
+ if (f) {
+ exitAutomap = automapProcessButtons(f);
+ gui_notifyButtonListChanged();
+ }
+
+ if (f == 0x30) {
+ for (int i = 0; i < 1024; i++)
+ _levelBlockProperties[i].flags |= 7;
+ _mapUpdateNeeded = true;
+ } else if (f == 0x6e) {
+ exitAutomap = true;
+ }
+
+ delay (_tickLength);
+ }
+
+ _screen->loadFont(Screen::FID_9_FNT, "FONT9P.FNT");
+ _screen->loadFont(Screen::FID_6_FNT, "FONT6P.FNT");
+
+ _screen->fadeToBlack(10);
+ loadLevelWallData(_currentLevel, false);
+ memcpy(_wllBuffer4, tmpWll, 80);
+ delete[] tmpWll;
+ restoreBlockTempData(_currentLevel);
+ addLevelItems();
+ gui_notifyButtonListChanged();
+ enableSysTimer(2);
+}
+
+void LoLEngine::updateAutoMap(uint16 block) {
+ if (!(_gameFlags[15] & 0x1000))
+ return;
+ _levelBlockProperties[block].flags |= 7;
+
+ uint16 x = block & 0x1f;
+ uint16 y = block >> 5;
+
+ updateAutoMapIntern(block, x, y, -1, -1);
+ updateAutoMapIntern(block, x, y, 1, -1);
+ updateAutoMapIntern(block, x, y, -1, 1);
+ updateAutoMapIntern(block, x, y, 1, 1);
+ updateAutoMapIntern(block, x, y, 0, -1);
+ updateAutoMapIntern(block, x, y, 0, 1);
+ updateAutoMapIntern(block, x, y, -1, 0);
+ updateAutoMapIntern(block, x, y, 1, 0);
+}
+
+bool LoLEngine::updateAutoMapIntern(uint16 block, uint16 x, uint16 y, int16 xOffs, int16 yOffs) {
+ static const int16 blockPosTable[] = { 1, -1, 3, 2, -1, 0, -1, 0, 1, -32, 0, 32 };
+ x += xOffs;
+ y += yOffs;
+
+ if ((x & 0xffe0) || (y & 0xffe0))
+ return false;
+
+ xOffs++;
+ yOffs++;
+
+ int16 fx = blockPosTable[xOffs];
+ uint16 b = block + blockPosTable[6 + xOffs];
+
+ if (fx != -1) {
+ if (_wllBuffer4[_levelBlockProperties[b].walls[fx]] & 0xc0)
+ return false;
+ }
+
+ int16 fy = blockPosTable[3 + yOffs];
+ b = block + blockPosTable[9 + yOffs];
+
+ if (fy != -1) {
+ if (_wllBuffer4[_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))
+ return false;
+
+ _levelBlockProperties[b].flags |= 7;
+
+ return true;
+}
+
+void LoLEngine::loadMapLegendData(int level) {
+ uint16 *legendData= (uint16*) _tempBuffer5120;
+ for (int i = 0; i < 32; i++) {
+ legendData[i * 6] = 0xffff;
+ legendData[i * 6 + 5] = 0xffff;
+ }
+
+ char file[13];
+ uint32 size = 0;
+ snprintf(file, 12, "level%d.xxx", level);
+ uint8 *data = _res->fileData(file, &size);
+ uint8 *pos = data;
+ size = MIN<uint32>(size / 12, 32);
+
+ for (uint32 i = 0; i < size; i++) {
+ uint16 *l = &legendData[i * 6];
+ l[3] = READ_LE_UINT16(pos);
+ pos += 2;
+ l[4] = READ_LE_UINT16(pos);
+ pos += 2;
+ l[5] = READ_LE_UINT16(pos);
+ pos += 2;
+ l[0] = READ_LE_UINT16(pos);
+ pos += 2;
+ l[1] = READ_LE_UINT16(pos);
+ pos += 2;
+ l[2] = READ_LE_UINT16(pos);
+ pos += 2;
+ }
+
+ delete[] data;
+}
+
+void LoLEngine::drawMapPage(int pageNum) {
+ for (int i = 0; i < 2; i++) {
+ _screen->loadBitmap("parch.cps", pageNum, pageNum, _screen->getPalette(3));
+
+ int cp = _screen->setCurPage(pageNum);
+ Screen::FontId of = _screen->setFont(Screen::FID_9_FNT);
+ _screen->printText(getLangString(_autoMapStrings[_currentMapLevel]), 236, 8, 1, 0);
+ uint16 blX = mapGetStartPosX();
+ uint16 bl = (mapGetStartPosY() << 5) + blX;
+
+ int sx = _automapTopLeftX;
+ int sy = _automapTopLeftY;
+
+ 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))) {
+ uint16 b0 = calcNewBlockPosition(bl, 0);
+ uint16 b2 = calcNewBlockPosition(bl, 2);
+ uint16 b1 = calcNewBlockPosition(bl, 1);
+ uint16 b3 = calcNewBlockPosition(bl, 3);
+
+ uint8 w02 = _levelBlockProperties[b0].walls[2];
+ uint8 w20 = _levelBlockProperties[b2].walls[0];
+ uint8 w13 = _levelBlockProperties[b1].walls[3];
+ uint8 w31 = _levelBlockProperties[b3].walls[1];
+
+ // draw block
+ _screen->copyBlockSpecial(_screen->_curPage, sx, sy, _screen->_curPage, sx, sy, 7, 6, 0, _mapOverlay);
+
+ // draw north wall
+ drawMapBlockWall(b3, w31, sx, sy, 3);
+ drawMapShape(w31, sx, sy, 3);
+ if (_wllBuffer4[w31] & 0xc0)
+ _screen->copyBlockSpecial(_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)
+ _screen->copyBlockSpecial(_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)
+ _screen->copyBlockSpecial(_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)
+ _screen->copyBlockSpecial(_screen->_curPage, sx, sy + 5, _screen->_curPage, sx, sy + 5, 7, 1, 0, _mapOverlay);
+ }
+
+ sx += 7;
+ if (bl % 32 == 31) {
+ sx = _automapTopLeftX;
+ sy += 6;
+ bl += blX;
+ }
+ }
+
+ _screen->setFont(of);
+ _screen->setCurPage(cp);
+
+ of = _screen->setFont(Screen::FID_6_FNT);
+
+ int tY = 0;
+ sx = mapGetStartPosX();
+ sy = mapGetStartPosY();
+
+ uint16 *legendData = (uint16*)_tempBuffer5120;
+
+ for (int ii = 0; ii < 32; ii++) {
+ uint16 *l = &legendData[ii * 6];
+ if (l[0] == 0xffff)
+ break;
+
+ uint16 cbl = l[0] + (l[1] << 5);
+ if ((_levelBlockProperties[cbl].flags & 7) != 7)
+ continue;
+
+ if (l[2] == 0xffff)
+ continue;
+
+ printMapText(l[2], 244, (tY << 3) + 22);
+
+ if (l[5] == 0xffff) {
+ tY++;
+ continue;
+ }
+
+ 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);
+ tY++;
+ }
+
+ cp = _screen->setCurPage(pageNum);
+
+ for (int ii = 0; ii < 11; ii++) {
+ if (!_defaultLegendData[ii].enable)
+ continue;
+ _screen->copyBlockSpecial(_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);
+ tY++;
+ }
+
+ _screen->setFont(of);
+ _screen->setCurPage(cp);
+ }
+
+ printMapExitButtonText();
+}
+
+bool LoLEngine::automapProcessButtons(int inputFlag) {
+ if (inputFlag != 199)
+ return false;
+
+ int r = -1;
+ if (posWithinRect(_mouseX, _mouseY, 252, 175, 273, 200))
+ r = 0;
+ else if (posWithinRect(_mouseX, _mouseY, 231, 175, 252, 200))
+ r = 1;
+ else if (posWithinRect(_mouseX, _mouseY, 275, 175, 315, 197))
+ r = 2;
+
+ printMapExitButtonText();
+
+ while (inputFlag == 199 || inputFlag == 200) {
+ inputFlag = checkInput(0, false);
+ removeInputTop();
+ delay (_tickLength);
+ }
+
+ if (r == 0) {
+ automapForwardButton();
+ printMapExitButtonText();
+ } else if (r == 1) {
+ automapBackButton();
+ printMapExitButtonText();
+ } if (r == 2) {
+ return true;
+ }
+
+ return false;
+}
+
+void LoLEngine::automapForwardButton() {
+ int i = (_currentMapLevel + 1) & 0x1f;
+ for (; !(_hasTempDataFlags & (1 << (i - 1))); i++) {
+ if (i >= 32 || i == _currentMapLevel)
+ return;
+ }
+
+ for (int l = 0; l < 11; l++) {
+ _defaultLegendData[l].enable = false;
+ _defaultLegendData[l].shapeIndex = 255;
+ }
+
+ _currentMapLevel = i;
+ loadLevelWallData(i, false);
+ restoreBlockTempData(i);
+ loadMapLegendData(i);
+ _mapUpdateNeeded = true;
+}
+
+void LoLEngine::automapBackButton() {
+ int i = (_currentMapLevel - 1) & 0x1f;
+ for (; !(_hasTempDataFlags & (1 << (i - 1))); i--) {
+ if (i < 0 || i == _currentMapLevel)
+ return;
+ }
+
+ for (int l = 0; l < 11; l++) {
+ _defaultLegendData[l].enable = false;
+ _defaultLegendData[l].shapeIndex = 255;
+ }
+
+ _currentMapLevel = i;
+ loadLevelWallData(i, false);
+ restoreBlockTempData(i);
+ loadMapLegendData(i);
+ _mapUpdateNeeded = true;
+}
+
+void LoLEngine::redrawMapCursor() {
+ int sx = mapGetStartPosX();
+ int sy = mapGetStartPosY();
+
+ if (_currentLevel != _currentMapLevel)
+ return;
+
+ _screen->fillRect(0, 0, 16, 16, 0, 2);
+ _screen->drawShape(2, _automapShapes[48 + _currentDirection], 0, 0, 0, 0);
+ int cx = _automapTopLeftX + (((_currentBlock - sx) % 32) * 7);
+ int cy = _automapTopLeftY + (((_currentBlock - (sy << 5)) / 32) * 6);
+ _screen->copyRegion(cx, cy, cx, cy, 16, 16, 2, 0);
+ _screen->copyBlockSpecial(2, 0, 0, 0, cx - 3, cy - 2, 16, 16, 0, _mapCursorOverlay);
+
+ _mapCursorOverlay[24] = _mapCursorOverlay[1];
+ for (int i = 1; i < 24; i++)
+ _mapCursorOverlay[i] = _mapCursorOverlay[i + 1];
+
+ _screen->updateScreen();
+}
+
+void LoLEngine::drawMapBlockWall(uint16 block, uint8 wall, int x, int y, int direction) {
+ if (((1 << direction) & _levelBlockProperties[block].flags) || ((_wllBuffer4[wall] & 0x1f) != 13))
+ return;
+
+ int cp = _screen->_curPage;
+ _screen->copyBlockSpecial(cp, x + _mapCoords[0][direction], y + _mapCoords[1][direction], cp, x + _mapCoords[0][direction], y + _mapCoords[1][direction], _mapCoords[2][direction], _mapCoords[3][direction], 0, _mapOverlay);
+ _screen->copyBlockSpecial(cp, x + _mapCoords[4][direction], y + _mapCoords[5][direction], cp, x + _mapCoords[4][direction], y + _mapCoords[5][direction], _mapCoords[8][direction], _mapCoords[9][direction], 0, _mapOverlay);
+ _screen->copyBlockSpecial(cp, x + _mapCoords[6][direction], y + _mapCoords[7][direction], cp, x + _mapCoords[6][direction], y + _mapCoords[7][direction], _mapCoords[8][direction], _mapCoords[9][direction], 0, _mapOverlay);
+}
+
+void LoLEngine::drawMapShape(uint8 wall, int x, int y, int direction) {
+ int l = _wllBuffer4[wall] & 0x1f;
+ if (l == 0x1f)
+ return;
+
+ _screen->drawShape(_screen->_curPage, _automapShapes[(l << 2) + direction], x + _mapCoords[10][direction] - 2, y + _mapCoords[11][direction] - 2, 0, 0);
+ mapIncludeLegendData(l);
+}
+
+int LoLEngine::mapGetStartPosX() {
+ int c = 0;
+ int a = 32;
+
+ do {
+ for (a = 0; a < 32; a++) {
+ if (_levelBlockProperties[(a << 5) + c].flags)
+ break;
+ }
+ if (a == 32)
+ c++;
+ } while (c < 32 && a == 32);
+
+ int d = 31;
+ a = 32;
+
+ do {
+ for (a = 0; a < 32; a++) {
+ if (_levelBlockProperties[(a << 5) + d].flags)
+ break;
+ }
+ if (a == 32)
+ d--;
+ } while (d > 0 && a == 32);
+
+ _automapTopLeftX = (d > c) ? ((32 - (d - c)) >> 1) * 7 + 5 : 5;
+ return (d > c) ? c : 0;
+}
+
+int LoLEngine::mapGetStartPosY() {
+ int c = 0;
+ int a = 32;
+
+ do {
+ for (a = 0; a < 32; a++) {
+ if (_levelBlockProperties[(c << 5) + a].flags)
+ break;
+ }
+ if (a == 32)
+ c++;
+ } while (c < 32 && a == 32);
+
+ int d = 31;
+ a = 32;
+
+ do {
+ for (a = 0; a < 32; a++) {
+ if (_levelBlockProperties[(d << 5) + a].flags)
+ break;
+ }
+ if (a == 32)
+ d--;
+ } while (d > 0 && a == 32);
+
+ _automapTopLeftY = (d > c) ? ((32 - (d - c)) >> 1) * 6 + 4 : 4;
+ return (d > c) ? c : 0;
+}
+
+void LoLEngine::mapIncludeLegendData(int type) {
+ type &= 0x7f;
+ for (int i = 0; i < 11; i++) {
+ if (_defaultLegendData[i].shapeIndex != type)
+ continue;
+ _defaultLegendData[i].enable = true;
+ return;
+ }
+}
+
+void LoLEngine::printMapText(uint16 stringId, int x, int y) {
+ int cp = _screen->setCurPage(2);
+ _screen->printText(getLangString(stringId), x, y, 239, 0);
+ _screen->setCurPage(cp);
+}
+
+void LoLEngine::printMapExitButtonText() {
+ int cp = _screen->setCurPage(2);
+ _screen->fprintString(getLangString(0x4033), 295, 182, 172, 0, 5);
+ _screen->setCurPage(cp);
+}
+
} // end of namespace Kyra
#endif // ENABLE_LOL
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index dbd4688ca7..e40d7e95ea 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -243,6 +243,13 @@ struct LevelTempData {
uint8 monsterDifficulty;
};
+struct MapLegendData {
+ uint8 shapeIndex;
+ bool enable;
+ uint8 x;
+ uint16 stringId;
+};
+
class LoLEngine : public KyraEngine_v1 {
friend class GUI_LoL;
friend class TextDisplayer_LoL;
@@ -793,7 +800,7 @@ private:
// level
void loadLevel(int index);
void addLevelItems();
- void loadLevelWLL(int index, bool mapShapes);
+ void loadLevelWallData(int index, bool mapShapes);
void assignBlockObject(uint16 *cmzItemIndex, uint16 item);
int assignLevelShapes(int index);
uint8 *getLevelShapes(int index);
@@ -852,7 +859,7 @@ private:
int clickedLeverOff(uint16 block, uint16 direction);
int clickedWallOnlyScript(uint16 block);
int clickedDoorSwitch(uint16 block, uint16 direction);
- int clicked6(uint16 block, uint16 direction);
+ int clickedNiche(uint16 block, uint16 direction);
bool clickedShape(int shapeIndex);
void processDoorSwitch(uint16 block, int unk);
@@ -868,7 +875,6 @@ private:
void movePartySmoothScrollTurnRight(int speed);
int smoothScrollDrawSpecialShape(int pageNum);
- void updateAutoMap(int block);
OpenDoorState _openDoorState[3];
int _emcDoorState;
@@ -1062,7 +1068,7 @@ private:
// monsters
void loadMonsterShapes(const char *file, int monsterIndex, int b);
void releaseMonsterShapes(int monsterIndex);
- int deleteMonstersForBlock(int block);
+ int deleteMonstersFromBlock(int block);
void setMonsterMode(MonsterInPlay *monster, int mode);
bool updateMonsterAdjustBlocks(MonsterInPlay *monster);
void placeMonster(MonsterInPlay *monster, uint16 x, uint16 y);
@@ -1171,6 +1177,36 @@ private:
void generateTempData();
LevelTempData *_lvlTempData[28];
+
+ // magic atlas
+ void displayAutomap();
+ void updateAutoMap(uint16 block);
+ bool updateAutoMapIntern(uint16 block, uint16 x, uint16 y, int16 xOffs, int16 yOffs);
+ void loadMapLegendData(int level);
+ void drawMapPage(int pageNum);
+ bool automapProcessButtons(int inputFlag);
+ void automapBackButton();
+ void automapForwardButton();
+ void redrawMapCursor();
+ void drawMapBlockWall(uint16 block, uint8 wall, int x, int y, int direction);
+ void drawMapShape(uint8 wall, int x, int y, int direction);
+ int mapGetStartPosX();
+ int mapGetStartPosY();
+ void mapIncludeLegendData(int type);
+ void printMapText(uint16 stringId, int x, int y);
+ void printMapExitButtonText();
+
+ uint8 _currentMapLevel;
+ uint8 *_mapOverlay;
+ const uint8 **_automapShapes;
+ const uint16 *_autoMapStrings;
+ int _autoMapStringsSize;
+ MapLegendData *_defaultLegendData;
+ uint8 *_mapCursorOverlay;
+ uint8 _automapTopLeftX;
+ uint8 _automapTopLeftY;
+ static const int8 _mapCoords[12][4];
+ bool _mapUpdateNeeded;
};
} // end of namespace Kyra
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 80f56c81cc..4e97853490 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -281,6 +281,11 @@ enum kKyraResources {
kLolButtonList6,
kLolButtonList7,
kLolButtonList8,
+
+ lolLegendData,
+ lolMapCursorOvl,
+ lolMapStringId,
+ //lolMapPal,
#endif // ENABLE_LOL
kMaxResIDs
diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index a764839d2f..5674dba761 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -67,7 +67,7 @@ void LoLEngine::loadLevel(int index) {
loadTalkFile(index);
- loadLevelWLL(index, true);
+ loadLevelWallData(index, true);
_loadLevelFlag = 1;
char filename[13];
@@ -84,7 +84,7 @@ void LoLEngine::loadLevel(int index) {
runInfScript(filename);
addLevelItems();
- deleteMonstersForBlock(_currentBlock);
+ deleteMonstersFromBlock(_currentBlock);
_screen->generateGrayOverlay(_screen->_currentPalette, _screen->_grayOverlay, 32, 16, 0, 0, 128, true);
@@ -139,7 +139,7 @@ void LoLEngine::assignBlockObject(uint16 *cmzItemIndex, uint16 item) {
*cmzItemIndex = ix;
}
-void LoLEngine::loadLevelWLL(int index, bool mapShapes) {
+void LoLEngine::loadLevelWallData(int index, bool mapShapes) {
char filename[13];
snprintf(filename, sizeof(filename), "LEVEL%d.WLL", index);
@@ -525,7 +525,7 @@ bool LoLEngine::testWallInvisibility(int block, int direction) {
void LoLEngine::resetLampStatus() {
_gameFlags[15] |= 0x400;
- _lampEffect = 255;
+ _lampEffect = -1;
updateLampStatus();
}
@@ -539,48 +539,48 @@ void LoLEngine::setLampMode(bool lampOn) {
}
void LoLEngine::updateLampStatus() {
- uint8 newLampOilStatus = 0;
- uint8 tmp2 = 0;
+ uint8 newLampEffect = 0;
+ uint8 tmpOilStatus = 0;
if ((_updateFlags & 4) || !(_gameFlags[15] & 0x800))
return;
if (!_brightness || !_lampOilStatus) {
- newLampOilStatus = 8;
- if (newLampOilStatus != _lampEffect && _screen->_fadeFlag == 0)
- setPaletteBrightness(_screen->_currentPalette, _lampEffect, newLampOilStatus);
+ newLampEffect = 8;
+ if (newLampEffect != _lampEffect && _screen->_fadeFlag == 0)
+ setPaletteBrightness(_screen->_currentPalette, _brightness, newLampEffect);
} else {
- tmp2 = (_lampOilStatus < 100) ? _lampOilStatus : 100;
- newLampOilStatus = (3 - (tmp2 - 1) / 25) << 1;
+ tmpOilStatus = (_lampOilStatus < 100) ? _lampOilStatus : 100;
+ newLampEffect = (3 - ((tmpOilStatus - 1) / 25)) << 1;
- if (_lampEffect == 255) {
+ if (_lampEffect == -1) {
if (_screen->_fadeFlag == 0)
- setPaletteBrightness(_screen->_currentPalette, _brightness, newLampOilStatus);
+ setPaletteBrightness(_screen->_currentPalette, _brightness, newLampEffect);
_lampStatusTimer = _system->getMillis() + (10 + _rnd.getRandomNumberRng(1, 30)) * _tickLength;
} else {
- if ((_lampEffect & 0xfe) == (newLampOilStatus & 0xfe)) {
+ if ((_lampEffect & 0xfe) == (newLampEffect & 0xfe)) {
if (_system->getMillis() <= _lampStatusTimer) {
- newLampOilStatus = _lampEffect;
+ newLampEffect = _lampEffect;
} else {
- newLampOilStatus = _lampEffect ^ 1;
+ newLampEffect = _lampEffect ^ 1;
_lampStatusTimer = _system->getMillis() + (10 + _rnd.getRandomNumberRng(1, 30)) * _tickLength;
}
} else {
if (_screen->_fadeFlag == 0)
- setPaletteBrightness(_screen->_currentPalette, _lampEffect, newLampOilStatus);
+ setPaletteBrightness(_screen->_currentPalette, _lampEffect, newLampEffect);
}
}
}
- if (newLampOilStatus == _lampEffect)
+ if (newLampEffect == _lampEffect)
return;
_screen->hideMouse();
- _screen->drawShape(_screen->_curPage, _gameShapes[35 + newLampOilStatus], 291, 56, 0, 0);
+ _screen->drawShape(_screen->_curPage, _gameShapes[35 + newLampEffect], 291, 56, 0, 0);
_screen->showMouse();
- _lampEffect = newLampOilStatus;
+ _lampEffect = newLampEffect;
}
void LoLEngine::updateCompass() {
@@ -649,7 +649,7 @@ void LoLEngine::moveParty(uint16 direction, int unk1, int unk2, int buttonShape)
}
uint16 LoLEngine::calcNewBlockPosition(uint16 curBlock, uint16 direction) {
- static const int16 blockPosTable[] = { -32, 1, 32, -1, 1, -1, 3, 2, -1, 0, -1, 0, 1, -32, 0, 32 };
+ static const int16 blockPosTable[] = { -32, 1, 32, -1 };
return (curBlock + blockPosTable[direction]) & 0x3ff;
}
@@ -780,7 +780,7 @@ int LoLEngine::clickedDoorSwitch(uint16 block, uint16 direction) {
return 1;
}
-int LoLEngine::clicked6(uint16 block, uint16 direction) {
+int LoLEngine::clickedNiche(uint16 block, uint16 direction) {
return 1;
}
@@ -1174,13 +1174,6 @@ int LoLEngine::smoothScrollDrawSpecialShape(int pageNum) {
return 0;
}
-void LoLEngine::updateAutoMap(int block) {
- if (!(_gameFlags[15] & 0x1000))
- return;
- _levelBlockProperties[block].flags |= 7;
- // TODO
-}
-
void LoLEngine::drawScene(int pageNum) {
if (pageNum && pageNum != _sceneDrawPage1) {
SWAP(_sceneDrawPage1, _sceneDrawPage2);
@@ -1209,6 +1202,7 @@ void LoLEngine::drawScene(int pageNum) {
_sceneUpdateRequired = false;
}
+
void LoLEngine::setWallType(int block, int wall, int val) {
if (wall == -1) {
for (int i = 0; i < 4; i++)
@@ -1339,8 +1333,10 @@ void LoLEngine::setSequenceButtons(int x, int y, int w, int h, int enableFlags)
_seqWindowY2 = y + h;
int offs = _itemInHand ? 10 : 0;
_screen->setMouseCursor(offs, offs, getItemIconShapePtr(_itemInHand));
- setLampMode(0);
- _lampStatusSuspended = true;
+ if (w == 320) {
+ setLampMode(0);
+ _lampStatusSuspended = true;
+ }
}
void LoLEngine::setSpecialSceneButtons(int x, int y, int w, int h, int enableFlags) {
diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp
index 16f1c96ec1..e370cc9a33 100644
--- a/engines/kyra/screen_lol.cpp
+++ b/engines/kyra/screen_lol.cpp
@@ -27,6 +27,7 @@
#include "kyra/screen_lol.h"
#include "kyra/lol.h"
+#include "kyra/resource.h"
namespace Kyra {
@@ -46,6 +47,8 @@ Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen_v2(vm, system),
_fadeFlag = 2;
_curDimIndex = 0;
+
+ _mapDimX = _mapDimY = _mapDimW = _mapDimH = _mapDimDstX = _mapBlockWidth = _mapDimDstY = _mapBlockHeight = _mapDimU5 = _mapDimU6 = _mapBlockWidth2 = _mapDimU8 = 0;
}
Screen_LoL::~Screen_LoL() {
@@ -517,6 +520,94 @@ void Screen_LoL::smoothScrollTurnStep3(int srcPage1Num, int srcPage2Num, int dst
}
}
+void Screen_LoL::copyBlockSpecial(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, uint8 *ovl) {
+ if (!w || !h || !ovl)
+ return;
+
+ const ScreenDim *cdim = getScreenDim(dim);
+ _mapDimX = cdim->sx << 3;
+ _mapDimY = cdim->sy;
+ _mapDimW = cdim->w << 3;
+ _mapDimH = cdim->h;
+
+ calcMapBoundaries(x2, y2, w, h);
+ if (_mapBlockWidth == -1)
+ return;
+
+ uint8 *src = getPagePtr(page1) + y1 * 320 + x1;
+ uint8 *dst = getPagePtr(page2) + (_mapDimDstY + _mapDimY) * 320;
+
+ for (int i = 0; i < _mapBlockHeight; i++) {
+ uint8 *s = src + _mapDimU5;
+ uint8 *d = dst + (_mapDimDstX + _mapDimX);
+
+ for (int ii = 0; ii < _mapBlockWidth; ii++) {
+ uint8 p = ovl[*s++];
+ if (p)
+ *d = p;
+ d++;
+ }
+
+ dst += 320;
+ src += 320;
+ }
+
+ addDirtyRect(_mapDimDstX + _mapDimX, _mapDimDstY + _mapDimY, _mapBlockWidth, _mapBlockHeight);
+}
+
+void Screen_LoL::calcMapBoundaries(int dstX, int dstY, int width, int height) {
+ _mapBlockWidth = _mapBlockWidth2 = width;
+ _mapBlockHeight = height;
+ _mapDimDstX = dstX;
+ _mapDimDstY = dstY;
+
+ _mapDimU5 = _mapDimU6 = _mapDimU8 = 0;
+
+ int t = _mapDimDstX + _mapBlockWidth;
+ if (t <= 0) {
+ _mapBlockWidth = _mapBlockHeight = -1;
+ return;
+ }
+
+ if (t <= _mapDimDstX) {
+ _mapDimU5 = _mapBlockWidth - t;
+ _mapBlockWidth = t;
+ _mapDimDstX = 0;
+ }
+
+ t = _mapDimW - _mapDimDstX;
+ if (t <= 0) {
+ _mapBlockWidth = _mapBlockHeight = -1;
+ return;
+ }
+
+ if (t <= _mapBlockWidth)
+ _mapBlockWidth = t;
+
+ _mapBlockWidth2 -= _mapBlockWidth;
+
+ t = _mapDimDstY + _mapBlockHeight;
+ if (t <= 0) {
+ _mapBlockWidth = _mapBlockHeight = -1;
+ return;
+ }
+
+ if (t <= _mapDimDstY) {
+ _mapDimU6 = _mapBlockHeight - t;
+ _mapBlockHeight = t;
+ _mapDimDstY = 0;
+ }
+
+ t = _mapDimH - _mapDimDstY;
+ if (t <= 0) {
+ _mapBlockWidth = _mapBlockHeight = -1;
+ return;
+ }
+
+ if (t <= _mapBlockHeight)
+ _mapBlockHeight = t;
+}
+
void Screen_LoL::fadeToBlack(int delay, const UpdateFunctor *upFunc) {
Screen::fadeToBlack(delay, upFunc);
_fadeFlag = 2;
diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h
index abdc11d7c5..30567ee808 100644
--- a/engines/kyra/screen_lol.h
+++ b/engines/kyra/screen_lol.h
@@ -60,6 +60,11 @@ public:
void smoothScrollTurnStep2(int srcPage1Num, int srcPage2Num, int dstPageNum);
void smoothScrollTurnStep3(int srcPage1Num, int srcPage2Num, int dstPageNum);
+ // magic atlas
+ // This method basically works like copyRegion, but the pixels
+ // copied also have a palette overlay applied to them.
+ void copyBlockSpecial(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, uint8 *ovl);
+
// palette stuff
void fadeToBlack(int delay=0x54, const UpdateFunctor *upFunc = 0);
void loadSpecialColours(uint8 *destPalette);
@@ -87,6 +92,22 @@ private:
int _curDimIndex;
uint8 *_levelOverlays[8];
+
+ // magic atlas
+ void calcMapBoundaries(int dstX, int dstY, int c, int d);
+
+ int _mapDimX;
+ int _mapDimY;
+ int _mapDimW;
+ int _mapDimH;
+ int _mapDimDstX;
+ int _mapBlockWidth;
+ int _mapDimDstY;
+ int _mapBlockHeight;
+ int _mapDimU5;
+ int _mapDimU6;
+ int _mapBlockWidth2;
+ int _mapDimU8;
};
} // end of namespace Kyra
diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp
index 76f8ec7413..582e99d4b0 100644
--- a/engines/kyra/script_lol.cpp
+++ b/engines/kyra/script_lol.cpp
@@ -115,7 +115,7 @@ bool LoLEngine::checkSceneUpdateNeed(int func) {
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 (_wllWallFlags[stackPos(2)] & 4)
- deleteMonstersForBlock(stackPos(0));
+ deleteMonstersFromBlock(stackPos(0));
setWallType(stackPos(0), stackPos(1), stackPos(2));
return 1;
}
diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp
index c6a1645efd..1350f41710 100644
--- a/engines/kyra/sprites_lol.cpp
+++ b/engines/kyra/sprites_lol.cpp
@@ -135,7 +135,7 @@ void LoLEngine::releaseMonsterShapes(int monsterIndex) {
}
}
-int LoLEngine::deleteMonstersForBlock(int block) {
+int LoLEngine::deleteMonstersFromBlock(int block) {
int i = _levelBlockProperties[block].assignedObjects;
int cnt = 0;
uint16 next = 0;
@@ -1079,7 +1079,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
_unkDrawLevelBool = true;
monster->fightCurTick--;
if ((monster->fightCurTick <= 0) || (checkDrawObjectSpace(_partyPosX, _partyPosY, monster->x, monster->y) > 256) || (monster->flags & 8))
- setMonsterMode(monster, 13/*7*/);
+ setMonsterMode(monster, 7);
else
rearrangeAttackingMonster(monster);
break;
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 40920eb007..c18850c97d 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -44,7 +44,7 @@
namespace Kyra {
-#define RESFILE_VERSION 43
+#define RESFILE_VERSION 44
namespace {
bool checkKyraDat(Common::SeekableReadStream *file) {
@@ -444,6 +444,11 @@ bool StaticResource::init() {
{ kLolButtonList7, kLolRawDataBe16, "BUTTON7.LST" },
{ kLolButtonList8, kLolRawDataBe16, "BUTTON84.LST" },
+ { lolLegendData, kRawData, "MAPLGND.DEF" },
+ { lolMapCursorOvl, kRawData, "MAPCURSOR.PAL" },
+ { lolMapStringId, kLolRawDataBe16, "MAPSTRID.LST" },
+ //{ lolMapPal, kRawData, "MAP.PAL" },
+
{ 0, 0, 0 }
};
#endif // ENABLE_LOL
@@ -1856,6 +1861,31 @@ void LoLEngine::initStaticResource() {
_buttonList6 = (const int16*)_staticres->loadRawDataBe16(kLolButtonList6, _buttonList6Size);
_buttonList7 = (const int16*)_staticres->loadRawDataBe16(kLolButtonList7, _buttonList7Size);
_buttonList8 = (const int16*)_staticres->loadRawDataBe16(kLolButtonList8, _buttonList8Size);
+
+ _autoMapStrings = _staticres->loadRawDataBe16(lolMapStringId, _autoMapStringsSize);
+
+ int tmpSize = 0;
+ const uint8 *tmp = _staticres->loadRawData(lolLegendData, tmpSize);
+ tmpSize /= 5;
+ _defaultLegendData = new MapLegendData[tmpSize];
+ for (int i = 0; i < tmpSize; i++) {
+ _defaultLegendData[i].shapeIndex = *tmp++;
+ _defaultLegendData[i].enable = *tmp++ ? true : false;
+ _defaultLegendData[i].x = *tmp++;
+ _defaultLegendData[i].stringId = READ_LE_UINT16(tmp);
+ tmp += 2;
+ }
+ _staticres->unloadId(lolLegendData);
+
+ tmp = _staticres->loadRawData(lolMapCursorOvl, tmpSize);
+ _mapCursorOverlay = new uint8[tmpSize];
+ memcpy (_mapCursorOverlay, tmp, tmpSize);
+ _staticres->unloadId(lolMapCursorOvl);
+
+ /*tmp = _staticres->loadRawData(lolMapPal, tmpSize);
+ _screen->_automapPal = new uint8[tmpSize];
+ memcpy (_screen->_automapPal, tmp, tmpSize);
+ _staticres->unloadId(lolMapPal);*/
}
void LoLEngine::assignButtonCallback(Button *button, int index) {
@@ -3033,6 +3063,13 @@ const uint8 LoLEngine::_clock2Timers[] = {
0x51, 0x52, 0x08, 0x09, 0x0A
};
+const int8 LoLEngine::_mapCoords[12][4] = {
+ { 0x00, 0x07, 0x00, 0xFB }, { 0xFB, 0x00, 0x06, 0x00 }, { 0x07, 0x05, 0x07, 0x01 },
+ { 0x05, 0x06, 0x04, 0x06 }, { 0x00, 0x07, 0x00, 0xFF }, { 0xFD, 0x00, 0x06, 0x00 },
+ { 0x06, 0x07, 0x06, 0xFD }, { 0xFD, 0x05, 0x06, 0x05 }, { 0x01, 0x05, 0x01, 0x01 },
+ { 0x03, 0x01, 0x03, 0x01 }, { 0xFF, 0x06, 0xFF, 0xF8 }, { 0xF9, 0xFF, 0x05, 0xFF }
+};
+
const uint8 LoLEngine::_numClock2Timers = ARRAYSIZE(LoLEngine::_clock2Timers);
#endif // ENABLE_LOL
diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp
index 623be1aaeb..8000585eea 100644
--- a/tools/create_kyradat/create_kyradat.cpp
+++ b/tools/create_kyradat/create_kyradat.cpp
@@ -31,7 +31,7 @@
#include "md5.h"
enum {
- kKyraDatVersion = 43,
+ kKyraDatVersion = 44,
kIndexSize = 12
};
@@ -336,6 +336,11 @@ const ExtractFilename extractFilenames[] = {
{ lolButtonList7, lolTypeRaw16, "BUTTON7.LST" },
{ lolButtonList8, lolTypeRaw16, "BUTTON84.LST" },
+ { lolLegendData, kTypeRawData, "MAPLGND.DEF" },
+ { lolMapCursorOvl, kTypeRawData, "MAPCURSOR.PAL" },
+ { lolMapStringId, lolTypeRaw16, "MAPSTRID.LST" },
+ //{ lolMapPal, kTypeRawData, "MAP.PAL" },
+
{ -1, 0, 0 }
};
diff --git a/tools/create_kyradat/create_kyradat.h b/tools/create_kyradat/create_kyradat.h
index 048391d631..a2ffb754d3 100644
--- a/tools/create_kyradat/create_kyradat.h
+++ b/tools/create_kyradat/create_kyradat.h
@@ -246,6 +246,11 @@ enum kExtractID {
lolButtonList7,
lolButtonList8,
+ lolLegendData,
+ lolMapCursorOvl,
+ lolMapStringId,
+ //lolMapPal,
+
kMaxResIDs
};
diff --git a/tools/create_kyradat/lol_cd.h b/tools/create_kyradat/lol_cd.h
index 420a7bb55a..0ccf6446ab 100644
--- a/tools/create_kyradat/lol_cd.h
+++ b/tools/create_kyradat/lol_cd.h
@@ -69,6 +69,11 @@ const ExtractEntry lolCDFile2[] = {
{ lolButtonList7, 0x00029790, 0x00029796 },
{ lolButtonList8, 0x000297A0, 0x000297A4 },
+ { lolLegendData, 0x000321F0, 0x0003222C },
+ { lolMapCursorOvl, 0x0003222C, 0x00032245 },
+ { lolMapStringId, 0x000287D0, 0x0002880C },
+ //{ lolMapPal, 0x0001D9C0, 0x0001DBC0 },
+
{ -1, 0, 0 }
};
diff --git a/tools/create_kyradat/misc.h b/tools/create_kyradat/misc.h
index 8f0d0b6316..91cde9b6e8 100644
--- a/tools/create_kyradat/misc.h
+++ b/tools/create_kyradat/misc.h
@@ -552,6 +552,11 @@ const int lolCDFile2Need[] = {
lolButtonList7,
lolButtonList8,
+ lolLegendData,
+ lolMapCursorOvl,
+ lolMapStringId,
+ //lolMapPal,
+
-1
};