From b6d81011e3b33235cf74e568455e97065cc9d198 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 22 Jul 2014 16:52:39 +0200 Subject: PRINCE: plotTracePoint(), plotTraceLine(), tracePath(), approxPath() update --- engines/prince/prince.cpp | 125 +++++++++++++++++++++++++++------------------- engines/prince/prince.h | 11 ++-- engines/prince/script.cpp | 6 ++- 3 files changed, 82 insertions(+), 60 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index db72e01223..a1d1f2d30c 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -90,10 +90,10 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), _dialogFlag(false), _dialogLines(0), _dialogText(nullptr), _mouseFlag(1), _roomPathBitmap(nullptr), _roomPathBitmapTemp(nullptr), _coordsBufEnd(nullptr), _coordsBuf(nullptr), _coords(nullptr), - _traceLineLen(0), _traceLineFlag(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), + _traceLineLen(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), - _tracePointFlag(0), _shanLen1(0), _directionTable(nullptr) { + _shanLen1(0), _directionTable(nullptr) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -1466,6 +1466,10 @@ void PrinceEngine::clearBackAnimList() { } } +void PrinceEngine::grabMap() { + //TODO +} + void PrinceEngine::initZoomIn(int slot) { //TODO } @@ -1616,8 +1620,6 @@ void PrinceEngine::drawScreen() { runDrawNodes(); - testDrawPath(); - freeDrawNodes(); if (_mainHero->_visible) { @@ -2761,6 +2763,47 @@ void PrinceEngine::freeAllNormAnims() { _normAnimList.clear(); } +// Modified version of Graphics::drawLine() to allow breaking the loop and return value +int PrinceEngine::drawLine(int x0, int y0, int x1, int y1, int (*plotProc)(int, int, void *), void *data) { + // Bresenham's line algorithm, as described by Wikipedia + const bool steep = ABS(y1 - y0) > ABS(x1 - x0); + + if (steep) { + SWAP(x0, y0); + SWAP(x1, y1); + } + + const int delta_x = ABS(x1 - x0); + const int delta_y = ABS(y1 - y0); + const int delta_err = delta_y; + int x = x0; + int y = y0; + int err = 0; + + const int x_step = (x0 < x1) ? 1 : -1; + const int y_step = (y0 < y1) ? 1 : -1; + + int stopFlag = 0; + if (steep) + stopFlag = (*plotProc)(y, x, data); + else + stopFlag = (*plotProc)(x, y, data); + + while (x != x1 && !stopFlag) { + x += x_step; + err += delta_err; + if (2 * err > delta_x) { + y += y_step; + err -= delta_x; + } + if (steep) + stopFlag = (*plotProc)(y, x, data); + else + stopFlag = (*plotProc)(x, y, data); + } + return stopFlag; +} + int PrinceEngine::getPixelAddr(byte *pathBitmap, int x, int y) { int mask = 128 >> (x & 7); byte value = pathBitmap[x / 8 + y * 80]; @@ -2924,25 +2967,23 @@ void PrinceEngine::specialPlotInside(int x, int y) { } } -void PrinceEngine::plotTraceLine(int x, int y, int color, void *data) { +int PrinceEngine::plotTraceLine(int x, int y, void *data) { PrinceEngine *traceLine = (PrinceEngine *)data; - if (!traceLine->_traceLineFlag) { - if (!traceLine->_traceLineFirstPointFlag) { - if (!traceLine->getPixelAddr(traceLine->_roomPathBitmapTemp, x, y)) { - if (traceLine->getPixelAddr(traceLine->_roomPathBitmap, x, y)) { - traceLine->specialPlotInside(x, y); - traceLine->_traceLineLen++; - traceLine->_traceLineFlag = 0; - } else { - traceLine->_traceLineFlag = -1; - } + if (!traceLine->_traceLineFirstPointFlag) { + if (!traceLine->getPixelAddr(traceLine->_roomPathBitmapTemp, x, y)) { + if (traceLine->getPixelAddr(traceLine->_roomPathBitmap, x, y)) { + traceLine->specialPlotInside(x, y); + traceLine->_traceLineLen++; + return 0; } else { - traceLine->_traceLineFlag = 1; + return -1; } } else { - traceLine->_traceLineFirstPointFlag = false; - traceLine->_traceLineFlag = 0; + return 1; } + } else { + traceLine->_traceLineFirstPointFlag = false; + return 0; } } @@ -3730,13 +3771,12 @@ bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { bcad = _coords; _traceLineLen = 0; - _traceLineFlag = 0; _traceLineFirstPointFlag = true; - Graphics::drawLine(x, y, x2, y2, 0, &this->plotTraceLine, this); + int drawLineFlag = drawLine(x, y, x2, y2, &this->plotTraceLine, this); - if (!_traceLineFlag) { + if (!drawLineFlag) { return true; - } else if (_traceLineFlag == -1 && _traceLineLen >= 2) { + } else if (drawLineFlag == -1 && _traceLineLen >= 2) { byte *tempCorrds = bcad; while (tempCorrds != _coords) { x = READ_UINT16(tempCorrds); @@ -3846,20 +3886,18 @@ void PrinceEngine::specialPlotInside2(int x, int y) { _coords2 += 2; } -void PrinceEngine::plotTracePoint(int x, int y, int color, void *data) { +int PrinceEngine::plotTracePoint(int x, int y, void *data) { PrinceEngine *tracePoint = (PrinceEngine *)data; - if (!tracePoint->_tracePointFlag) { - if (!tracePoint->_tracePointFirstPointFlag) { - if (tracePoint->getPixelAddr(tracePoint->_roomPathBitmap, x, y)) { - tracePoint->specialPlotInside2(x, y); - tracePoint->_tracePointFlag = 0; - } else { - tracePoint->_tracePointFlag = -1; - } + if (!tracePoint->_tracePointFirstPointFlag) { + if (tracePoint->getPixelAddr(tracePoint->_roomPathBitmap, x, y)) { + tracePoint->specialPlotInside2(x, y); + return 0; } else { - tracePoint->_tracePointFirstPointFlag = false; - tracePoint->_tracePointFlag = 0; + return -1; } + } else { + tracePoint->_tracePointFirstPointFlag = false; + return 0; } } @@ -3892,10 +3930,9 @@ void PrinceEngine::approxPath() { _coords2 += 4; } } - _tracePointFlag = 0; _tracePointFirstPointFlag = true; - Graphics::drawLine(x1, y1, x2, y2, 0, &this->plotTracePoint, this); - if (!_tracePointFlag) { + bool drawLineFlag = drawLine(x1, y1, x2, y2, &this->plotTracePoint, this); + if (!drawLineFlag) { tempCoords = tempCoordsBuf - 4; tempCoordsBuf = _coordsBuf; } else { @@ -4197,22 +4234,6 @@ void PrinceEngine::freeCoords3() { } } -void PrinceEngine::testDrawPath() { - byte *tempCoords = _mainHero->_coords; - if (tempCoords != nullptr) { - while (1) { - int flag = READ_UINT32(tempCoords); - if (flag == 0xFFFFFFFF) { - break; - } - int x = READ_UINT16(tempCoords); - int y = READ_UINT16(tempCoords + 2); - tempCoords += 4; - _graph->drawPixel(_graph->_frontScreen, x, y); - } - } -} - void PrinceEngine::mainLoop() { changeCursor(0); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 2f7009517f..4bab84b1d0 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -330,6 +330,8 @@ public: void showMask(int maskNr, Graphics::Surface *originalRoomSurface); void clsMasks(); + void grabMap(); + int _selectedMob; // number of selected Mob / inventory item int _selectedItem; // number of item on mouse cursor int _selectedMode; @@ -449,9 +451,7 @@ public: byte *_coordsBuf3; byte *_coords3; int _traceLineLen; - int _traceLineFlag; // return value of plotTraceLine bool _traceLineFirstPointFlag; // if plotTraceLine after first point - int _tracePointFlag; // return value of plotTracePoint bool _tracePointFirstPointFlag; // if plotTracePoint after first point byte *_directionTable; int _shanLen1; @@ -475,11 +475,12 @@ public: int y2; } _fpResult; + int drawLine(int x0, int y0, int x1, int y1, int (*plotProc)(int, int, void *), void *data); bool loadPath(const char *resourceName); byte *makePath(int destX, int destY); void findPoint(int x1, int y1, int x2, int y2); int getPixelAddr(byte *pathBitmap, int x, int y); - static void plotTraceLine(int x, int y, int color, void *data); + static int plotTraceLine(int x, int y, void *data); void specialPlotInside(int x, int y); bool tracePath(int x1, int y1, int x2, int y2); Direction makeDirection(int x1, int y1, int x2, int y2); @@ -488,7 +489,7 @@ public: void allocCoords2(); void freeCoords2(); void freeCoords3(); - static void plotTracePoint(int x, int y, int color, void *data); + static int plotTracePoint(int x, int y, void *data); void specialPlotInside2(int x, int y); void approxPath(); void freeDirectionTable(); @@ -498,8 +499,6 @@ public: void walkTo(); void moveRunHero(int heroId, int x, int y, int dir, bool runHeroFlag); - void testDrawPath(); - int leftDownDir(); int leftDir(); int leftUpDir(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 1badee0da1..f5b38cbe47 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -516,7 +516,7 @@ void Interpreter::O_WAITFOREVER() { _vm->changeCursor(_vm->_currentPointerNumber); _opcodeNF = 1; _currentInstruction -= 2; - debugInterpreter("O_WAITFOREVER"); + //debugInterpreter("O_WAITFOREVER"); } void Interpreter::O_BLACKPALETTE() { @@ -1306,7 +1306,8 @@ void Interpreter::O_TALKBACKANIM() { } void Interpreter::O_LOADPATH() { - int32 offset = readScript(); + readScript(); + //int32 offset = readScript(); // simplifying, because used only once in Location 20 _vm->loadPath("path2"); debugInterpreter("O_LOADPATH - path2"); @@ -1744,6 +1745,7 @@ void Interpreter::O_HEROCOLOR() { } void Interpreter::O_GRABMAPA() { + _vm->grabMap(); debugInterpreter("O_GRABMAPA"); } -- cgit v1.2.3