From 9d4776ebc53218786a263279bc5868fc5947b7a5 Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Mon, 25 May 2009 22:58:05 +0000 Subject: LOL: implemented support for the mine car svn-id: r40897 --- engines/kyra/lol.cpp | 8 ++--- engines/kyra/lol.h | 11 ++++-- engines/kyra/scene_lol.cpp | 82 +++++++++++++++++++++++++-------------------- engines/kyra/screen_lol.cpp | 50 +++++++++++++++++++++++++++ engines/kyra/screen_lol.h | 3 ++ engines/kyra/script_lol.cpp | 17 +++++++++- 6 files changed, 127 insertions(+), 44 deletions(-) (limited to 'engines') diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index b974f3f37a..887c7a4e62 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -147,7 +147,8 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _trueLightTable1 = 0; _levelShapeProperties = 0; _levelShapes = 0; - _scriptAssignedLevelShape = 0; + _specialGuiShape = 0; + _specialGuiShapeX = _specialGuiShapeY = _specialGuiShapeShadowFlag = 0; _blockDrawingBuffer = 0; _sceneWindowBuffer = 0; memset(_doorShapes, 0, sizeof(_doorShapes)); @@ -192,8 +193,8 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _environmentSfx = _environmentSfxVol = _envSfxDistThreshold = 0; _envSfxUseQueue = false; _envSfxNumTracksInQueue = 0; - memset (_envSfxQueuedTracks, 0, sizeof(_envSfxQueuedTracks)); - memset (_envSfxQueuedBlocks, 0, sizeof(_envSfxQueuedBlocks)); + memset(_envSfxQueuedTracks, 0, sizeof(_envSfxQueuedTracks)); + memset(_envSfxQueuedBlocks, 0, sizeof(_envSfxQueuedBlocks)); _sceneDrawVarDown = _sceneDrawVarRight = _sceneDrawVarLeft = _wllProcessFlag = 0; _partyPosX = _partyPosY = 0; @@ -355,7 +356,6 @@ LoLEngine::~LoLEngine() { delete[] _monsters; delete[] _levelBlockProperties; delete[] _monsterProperties; - delete[] _scriptAssignedLevelShape; delete[] _levelFileData; delete[] _vcnExpTable; diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 029d7948cc..537081af99 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -738,6 +738,7 @@ private: int olol_getNextActiveCharacter(EMCState *script); int olol_paralyzePoisonCharacter(EMCState *script); int olol_drawCharPortrait(EMCState *script); + int olol_assignSpecialGuiShape(EMCState *script); int olol_placeInventoryItemInHand(EMCState *script); int olol_castSpell(EMCState *script); int olol_pitDrop(EMCState *script); @@ -933,7 +934,7 @@ private: void drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2); void drawDecorations(int index); void drawBlockEffects(int index, int type); - void drawScriptShapes(int pageNum); + void drawSpecialGuiShape(int pageNum); void setWallType(int block, int wall, int val); void updateDrawPage2(); @@ -979,7 +980,7 @@ private: void pitDropScroll(int numSteps); void shakeScene(int duration, int width, int height, int restore); - int smoothScrollDrawSpecialShape(int pageNum); + int smoothScrollDrawSpecialGuiShape(int pageNum); OpenDoorState _openDoorState[3]; int _blockDoor; @@ -1010,7 +1011,11 @@ private: uint8 *_sceneWindowBuffer; LevelShapeProperty *_levelShapeProperties; uint8 **_levelShapes; - uint8 *_scriptAssignedLevelShape; + + uint8 *_specialGuiShape; + uint16 _specialGuiShapeX; + uint16 _specialGuiShapeY; + uint16 _specialGuiShapeShadowFlag; char _lastSuppFile[12]; char _lastOverridePalFile[12]; diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp index 68eb15fbb5..e2931c5098 100644 --- a/engines/kyra/scene_lol.cpp +++ b/engines/kyra/scene_lol.cpp @@ -850,8 +850,10 @@ bool LoLEngine::clickedShape(int shapeIndex) { while (shapeIndex) { uint16 s = _levelShapeProperties[shapeIndex].shapeIndex[1]; - if (s == 0xffff) + if (s == 0xffff) { + shapeIndex = _levelShapeProperties[shapeIndex].next; continue; + } int w = _levelShapes[s][3]; int h = _levelShapes[s][2]; @@ -1002,12 +1004,12 @@ void LoLEngine::movePartySmoothScrollUp(int speed) { int d = 0; if (_sceneDrawPage2 == 2) { - d = smoothScrollDrawSpecialShape(6); + d = smoothScrollDrawSpecialGuiShape(6); gui_drawScene(6); _screen->backupSceneWindow(6, 12); _screen->backupSceneWindow(2, 6); } else { - d = smoothScrollDrawSpecialShape(2); + d = smoothScrollDrawSpecialGuiShape(2); gui_drawScene(2); _screen->backupSceneWindow(2, 12); _screen->backupSceneWindow(6, 6); @@ -1018,8 +1020,8 @@ void LoLEngine::movePartySmoothScrollUp(int speed) { _screen->smoothScrollZoomStepTop(6, 2, _scrollXTop[i], _scrollYTop[i]); _screen->smoothScrollZoomStepBottom(6, 2, _scrollXBottom[i], _scrollYBottom[i]); - //if (d) - // unk(_tempBuffer5120, page2); + if (d) + _screen->copyGuiShapeToSurface(_tempBuffer5120, 2); _screen->restoreSceneWindow(2, 0); _screen->updateScreen(); @@ -1029,8 +1031,8 @@ void LoLEngine::movePartySmoothScrollUp(int speed) { i++; } - //if (d) - // unk(_tempBuffer5120, _scrollSceneBuffer); + if (d) + _screen->copyGuiShapeToSurface(_tempBuffer5120, 12); if (_sceneDefaultUpdate != 2) { _screen->restoreSceneWindow(12, 0); @@ -1044,7 +1046,7 @@ void LoLEngine::movePartySmoothScrollDown(int speed) { if (!_smoothScrollingEnabled) return; - //int d = smoothScrollDrawSpecialShape(2); + int d = smoothScrollDrawSpecialGuiShape(2); gui_drawScene(2); _screen->backupSceneWindow(2, 6); @@ -1053,8 +1055,8 @@ void LoLEngine::movePartySmoothScrollDown(int speed) { _screen->smoothScrollZoomStepTop(6, 2, _scrollXTop[i], _scrollYTop[i]); _screen->smoothScrollZoomStepBottom(6, 2, _scrollXBottom[i], _scrollYBottom[i]); - //if (d) - // unk(_tempBuffer5120, page2); + if (d) + _screen->copyGuiShapeToSurface(_tempBuffer5120, 2); _screen->restoreSceneWindow(2, 0); _screen->updateScreen(); @@ -1064,8 +1066,8 @@ void LoLEngine::movePartySmoothScrollDown(int speed) { i++; } - //if (d) - // unk(_tempBuffer5120, _scrollSceneBuffer); + if (d) + _screen->copyGuiShapeToSurface(_tempBuffer5120, 12); if (_sceneDefaultUpdate != 2) { _screen->restoreSceneWindow(6, 0); @@ -1146,14 +1148,14 @@ void LoLEngine::movePartySmoothScrollTurnLeft(int speed) { speed <<= 1; - //int d = smoothScrollDrawSpecialShape(_sceneDrawPage1); + int d = smoothScrollDrawSpecialGuiShape(_sceneDrawPage1); gui_drawScene(_sceneDrawPage1); - int dp = _sceneDrawPage2 == 2 ? _sceneDrawPage2 : _sceneDrawPage1; + int dp = _sceneDrawPage2 == 2 ? _sceneDrawPage2 : _sceneDrawPage1; _smoothScrollTimer = _system->getMillis() + speed * _tickLength; _screen->smoothScrollTurnStep1(_sceneDrawPage1, _sceneDrawPage2, dp); - //if (d) - // unk(_tempBuffer5120, _scrollSceneBuffer); + if (d) + _screen->copyGuiShapeToSurface(_tempBuffer5120, dp); _screen->restoreSceneWindow(dp, 0); _screen->updateScreen(); fadeText(); @@ -1161,8 +1163,8 @@ void LoLEngine::movePartySmoothScrollTurnLeft(int speed) { _smoothScrollTimer = _system->getMillis() + speed * _tickLength; _screen->smoothScrollTurnStep2(_sceneDrawPage1, _sceneDrawPage2, dp); - //if (d) - // unk(_tempBuffer5120, _scrollSceneBuffer); + if (d) + _screen->copyGuiShapeToSurface(_tempBuffer5120, dp); _screen->restoreSceneWindow(dp, 0); _screen->updateScreen(); fadeText(); @@ -1170,15 +1172,15 @@ void LoLEngine::movePartySmoothScrollTurnLeft(int speed) { _smoothScrollTimer = _system->getMillis() + speed * _tickLength; _screen->smoothScrollTurnStep3(_sceneDrawPage1, _sceneDrawPage2, dp); - //if (d) - // unk(_tempBuffer5120, _scrollSceneBuffer); + if (d) + _screen->copyGuiShapeToSurface(_tempBuffer5120, dp); _screen->restoreSceneWindow(dp, 0); _screen->updateScreen(); fadeText(); delayUntil(_smoothScrollTimer); if (_sceneDefaultUpdate != 2) { - drawScriptShapes(_sceneDrawPage1); + drawSpecialGuiShape(_sceneDrawPage1); _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); } @@ -1190,14 +1192,14 @@ void LoLEngine::movePartySmoothScrollTurnRight(int speed) { speed <<= 1; - //int d = smoothScrollDrawSpecialShape(_sceneDrawPage1); + int d = smoothScrollDrawSpecialGuiShape(_sceneDrawPage1); gui_drawScene(_sceneDrawPage1); int dp = _sceneDrawPage2 == 2 ? _sceneDrawPage2 : _sceneDrawPage1; _smoothScrollTimer = _system->getMillis() + speed * _tickLength; _screen->smoothScrollTurnStep3(_sceneDrawPage2, _sceneDrawPage1, dp); - //if (d) - // unk(_tempBuffer5120, _scrollSceneBuffer); + if (d) + _screen->copyGuiShapeToSurface(_tempBuffer5120, dp); _screen->restoreSceneWindow(dp, 0); _screen->updateScreen(); fadeText(); @@ -1205,8 +1207,8 @@ void LoLEngine::movePartySmoothScrollTurnRight(int speed) { _smoothScrollTimer = _system->getMillis() + speed * _tickLength; _screen->smoothScrollTurnStep2(_sceneDrawPage2, _sceneDrawPage1, dp); - //if (d) - // unk(_tempBuffer5120, _scrollSceneBuffer); + if (d) + _screen->copyGuiShapeToSurface(_tempBuffer5120, dp); _screen->restoreSceneWindow(dp, 0); _screen->updateScreen(); fadeText(); @@ -1214,15 +1216,15 @@ void LoLEngine::movePartySmoothScrollTurnRight(int speed) { _smoothScrollTimer = _system->getMillis() + speed * _tickLength; _screen->smoothScrollTurnStep1(_sceneDrawPage2, _sceneDrawPage1, dp); - //if (d) - // unk(_tempBuffer5120, _scrollSceneBuffer); + if (d) + _screen->copyGuiShapeToSurface(_tempBuffer5120, dp); _screen->restoreSceneWindow(dp, 0); _screen->updateScreen(); fadeText(); delayUntil(_smoothScrollTimer); if (_sceneDefaultUpdate != 2) { - drawScriptShapes(_sceneDrawPage1); + drawSpecialGuiShape(_sceneDrawPage1); _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); } @@ -1298,11 +1300,14 @@ void LoLEngine::shakeScene(int duration, int width, int height, int restore) { } } -int LoLEngine::smoothScrollDrawSpecialShape(int pageNum) { - // TODO - if(!_scriptAssignedLevelShape) +int LoLEngine::smoothScrollDrawSpecialGuiShape(int pageNum) { + if(!_specialGuiShape) return 0; - return 0; + + _screen->clearGuiShapeMemory(pageNum); + _screen->drawShape(pageNum, _specialGuiShape, _specialGuiShapeX, _specialGuiShapeY, 2, 0); + _screen->copyGuiShapeFromSceneBackupBuffer(pageNum, _tempBuffer5120); + return 1; } void LoLEngine::drawScene(int pageNum) { @@ -1321,7 +1326,7 @@ void LoLEngine::drawScene(int pageNum) { drawSceneShapes(); if (!pageNum) { - drawScriptShapes(_sceneDrawPage1); + drawSpecialGuiShape(_sceneDrawPage1); _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, _sceneDrawPage2, Screen::CR_NO_P_CHECK); _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); @@ -2036,9 +2041,14 @@ void LoLEngine::drawBlockEffects(int index, int type) { } } -void LoLEngine::drawScriptShapes(int pageNum) { - if (!_scriptAssignedLevelShape) +void LoLEngine::drawSpecialGuiShape(int pageNum) { + if (!_specialGuiShape) return; + + _screen->drawShape(pageNum, _specialGuiShape, _specialGuiShapeX, _specialGuiShapeY, 2, 0); + + if (_specialGuiShapeShadowFlag & 1) + _screen->drawShape(pageNum, _specialGuiShape, _specialGuiShapeX + _specialGuiShape[3], _specialGuiShapeY, 2, 1); } } // end of namespace Kyra diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp index 5ee7ae314e..75bc0cab16 100644 --- a/engines/kyra/screen_lol.cpp +++ b/engines/kyra/screen_lol.cpp @@ -319,6 +319,56 @@ void Screen_LoL::restoreSceneWindow(int srcPageNum, int dstPageNum) { addDirtyRect(112, 0, 176, 120); } +void Screen_LoL::clearGuiShapeMemory(int pageNum) { + uint8 *dst = getPagePtr(pageNum) + 0x79b0; + for (int i = 0; i < 23; i++) { + memset(dst, 0, 176); + dst += 320; + } +} + +void Screen_LoL::copyGuiShapeFromSceneBackupBuffer(int srcPageNum, uint8 *dstBuffer) { + uint8 *src = getPagePtr(srcPageNum) + 0x79c3; + uint8 *dst = dstBuffer; + + for (int i = 0; i < 23; i++) { + uint8 len = 0; + uint8 v = 0; + + do { + v = *src++; + len++; + } while (!v); + + *dst++ = len; + + len = 69 - len; + memcpy(dst, src, len); + src += (len + 251); + dst += len; + } +} + +void Screen_LoL::copyGuiShapeToSurface(uint8 *srcBuffer, int dstPageNum) { + uint8 *src = srcBuffer; + uint8 *dst = getPagePtr(dstPageNum) + 0xe7c3; + + for (int i = 0; i < 23; i++) { + uint8 v = *src++; + uint8 len = 69 - v; + dst += v; + memcpy(dst, src, len); + src += (len - 1); + dst += len; + + for (int ii = 0; ii < len; ii++) + *dst++ = *src--; + + src += (len + 1); + dst += (v + 38); + } +} + void Screen_LoL::smoothScrollZoomStepTop(int srcPageNum, int dstPageNum, int x, int y) { uint8 *src = getPagePtr(srcPageNum) + 0xa500 + y * 176 + x; uint8 *dst = getPagePtr(dstPageNum) + 0xa500; diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h index 7ef73bddcb..dbfe350466 100644 --- a/engines/kyra/screen_lol.h +++ b/engines/kyra/screen_lol.h @@ -55,6 +55,9 @@ public: // smooth scrolling void backupSceneWindow(int srcPageNum, int dstPageNum); void restoreSceneWindow(int srcPageNum, int dstPageNum); + void clearGuiShapeMemory(int pageNum); + void copyGuiShapeFromSceneBackupBuffer(int srcPageNum, uint8 *dstBuffer); + void copyGuiShapeToSurface(uint8 *srcBuffer, int dstPageNum); void smoothScrollZoomStepTop(int srcPageNum, int dstPageNum, int x, int y); void smoothScrollZoomStepBottom(int srcPageNum, int dstPageNum, int x, int y); void smoothScrollHorizontalStep(int pageNum, int x, int u2, int w); diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index 188c7a23f1..49d481bd29 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -1867,6 +1867,21 @@ int LoLEngine::olol_drawCharPortrait(EMCState *script) { return 1; } +int LoLEngine::olol_assignSpecialGuiShape(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_assignSpecialGuiShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + if (stackPos(0)) { + _specialGuiShape = _levelShapes[_levelShapeProperties[_wllShapeMap[stackPos(0)]].shapeIndex[stackPos(1)]]; + _specialGuiShapeX = stackPos(2); + _specialGuiShapeY = stackPos(3); + _specialGuiShapeShadowFlag = stackPos(4); + + } else { + _specialGuiShape = 0; + _specialGuiShapeX = _specialGuiShapeY = _specialGuiShapeShadowFlag = 0; + } + return 1; +} + int LoLEngine::olol_placeInventoryItemInHand(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_placeInventoryItemInHand(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); int itemType = stackPos(0); @@ -2499,7 +2514,7 @@ void LoLEngine::setupOpcodeTable() { OpcodeUnImpl(); // 0xA4 - OpcodeUnImpl(); + Opcode(olol_assignSpecialGuiShape); OpcodeUnImpl(); OpcodeUnImpl(); OpcodeUnImpl(); -- cgit v1.2.3