diff options
-rw-r--r-- | dists/engine-data/kyra.dat | bin | 256570 -> 256787 bytes | |||
-rw-r--r-- | engines/kyra/gui_lol.cpp | 6 | ||||
-rw-r--r-- | engines/kyra/lol.cpp | 501 | ||||
-rw-r--r-- | engines/kyra/lol.h | 44 | ||||
-rw-r--r-- | engines/kyra/resource.h | 5 | ||||
-rw-r--r-- | engines/kyra/scene_lol.cpp | 58 | ||||
-rw-r--r-- | engines/kyra/screen_lol.cpp | 91 | ||||
-rw-r--r-- | engines/kyra/screen_lol.h | 21 | ||||
-rw-r--r-- | engines/kyra/script_lol.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/sprites_lol.cpp | 4 | ||||
-rw-r--r-- | engines/kyra/staticres.cpp | 39 | ||||
-rw-r--r-- | tools/create_kyradat/create_kyradat.cpp | 7 | ||||
-rw-r--r-- | tools/create_kyradat/create_kyradat.h | 5 | ||||
-rw-r--r-- | tools/create_kyradat/lol_cd.h | 5 | ||||
-rw-r--r-- | tools/create_kyradat/misc.h | 5 |
15 files changed, 749 insertions, 44 deletions
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat Binary files differindex e3f56b61f8..cedbdacc1d 100644 --- a/dists/engine-data/kyra.dat +++ b/dists/engine-data/kyra.dat 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 }; |