From 843540b334d49a606e65e7e92997c3c469cf6ae0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 25 Mar 2017 21:07:59 -0400 Subject: TITANIC: Finished CSurfaceArea class The fillRect method is implemented using an experimental, more ScummVM style, rather than all the different blocks and loops for different bit depths that the original did --- engines/titanic/star_control/star_control_sub5.cpp | 12 ++-- engines/titanic/star_control/star_control_sub7.cpp | 8 +-- engines/titanic/star_control/star_control_sub8.cpp | 16 ++--- engines/titanic/star_control/star_field.cpp | 34 +++++----- engines/titanic/star_control/star_points1.cpp | 2 +- engines/titanic/star_control/star_points2.cpp | 2 +- engines/titanic/star_control/surface_area.cpp | 74 ++++++++++++++++++++-- engines/titanic/star_control/surface_area.h | 10 ++- 8 files changed, 116 insertions(+), 42 deletions(-) diff --git a/engines/titanic/star_control/star_control_sub5.cpp b/engines/titanic/star_control/star_control_sub5.cpp index 8c332975c6..092e7eb35a 100644 --- a/engines/titanic/star_control/star_control_sub5.cpp +++ b/engines/titanic/star_control/star_control_sub5.cpp @@ -331,7 +331,7 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1, GridEntry &grid2 = _grid[d1._index2]; if (grid1._z > val1 && grid2._z > val1) { - surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + surfaceArea->fillRect(FRect(grid1._position._x, grid1._position._y, grid2._position._x, grid2._position._y)); } } @@ -353,7 +353,7 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1, GridEntry &grid2 = _grid[d1._index2]; if (grid1._z > val1 && grid2._z > val1) { - surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + surfaceArea->fillRect(FRect(grid1._position._x, grid1._position._y, grid2._position._x, grid2._position._y)); } } @@ -375,7 +375,7 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1, GridEntry &grid2 = _grid[d1._index2]; if (grid1._z > val1 && grid2._z > val1) { - surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + surfaceArea->fillRect(FRect(grid1._position._x, grid1._position._y, grid2._position._x, grid2._position._y)); } } @@ -445,7 +445,7 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1, GridEntry &grid2 = _grid[d1._index2]; if (grid2._z > val1 && grid1._z > val1) { - surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + surfaceArea->fillRect(FRect(grid1._position._x, grid1._position._y, grid2._position._x, grid2._position._y)); } } @@ -467,7 +467,7 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1, GridEntry &grid2 = _grid[d1._index2]; if (grid2._z > val1 && grid1._z > val1) { - surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + surfaceArea->fillRect(FRect(grid1._position._x, grid1._position._y, grid2._position._x, grid2._position._y)); } } @@ -489,7 +489,7 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1, GridEntry &grid2 = _grid[d1._index2]; if (grid2._z > val1 && grid1._z > val1) { - surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + surfaceArea->fillRect(FRect(grid1._position._x, grid1._position._y, grid2._position._x, grid2._position._y)); } } diff --git a/engines/titanic/star_control/star_control_sub7.cpp b/engines/titanic/star_control/star_control_sub7.cpp index 8386e7305f..3e1f718053 100644 --- a/engines/titanic/star_control/star_control_sub7.cpp +++ b/engines/titanic/star_control/star_control_sub7.cpp @@ -55,16 +55,16 @@ void CStarControlSub7::draw(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12, FRect r1(center._x + vTemp._x, center._y + vTemp._y, center._x + vTemp._x + 4.0, center._y + vTemp._y + 4.0); - surfaceArea->fn1(r1); + surfaceArea->fillRect(r1); FRect r2(r1.right, r1.bottom, r1.right + 4.0, r1.top); - surfaceArea->fn1(r2); + surfaceArea->fillRect(r2); FRect r3(r2.right, r1.top, r1.right, r1.top - 4.0); - surfaceArea->fn1(r3); + surfaceArea->fillRect(r3); FRect r4(r1.right, r1.top - 4.0, r1.left, r1.top); - surfaceArea->fn1(r4); + surfaceArea->fillRect(r4); } } diff --git a/engines/titanic/star_control/star_control_sub8.cpp b/engines/titanic/star_control/star_control_sub8.cpp index bf29b053c5..cba4fe01b7 100644 --- a/engines/titanic/star_control/star_control_sub8.cpp +++ b/engines/titanic/star_control/star_control_sub8.cpp @@ -143,10 +143,10 @@ void CStarControlSub8::draw(CSurfaceArea *surfaceArea) { const CStarPosition &src = _entries[idx]; double xp = src.x, yp = src.y; - surfaceArea->fn1(FRect(xp - 8.0, yp, xp - 4.0, yp)); - surfaceArea->fn1(FRect(xp + 4.0, yp, xp + 8.0, yp)); - surfaceArea->fn1(FRect(xp, yp - 8.0, xp, yp - 4.0)); - surfaceArea->fn1(FRect(xp, yp + 4.0, xp, yp + 8.0)); + surfaceArea->fillRect(FRect(xp - 8.0, yp, xp - 4.0, yp)); + surfaceArea->fillRect(FRect(xp + 4.0, yp, xp + 8.0, yp)); + surfaceArea->fillRect(FRect(xp, yp - 8.0, xp, yp - 4.0)); + surfaceArea->fillRect(FRect(xp, yp + 4.0, xp, yp + 8.0)); } surfaceArea->_pixel = savedPixel; @@ -211,10 +211,10 @@ void CStarControlSub8::fn7(const FPoint &pt, CSurfaceArea *surfaceArea) { SurfaceAreaMode savedMode = surfaceArea->setMode(SA_MODE3); - surfaceArea->fn1(FRect(pt._x - 8.0, pt._y, pt._x - 4.0, pt._y)); - surfaceArea->fn1(FRect(pt._x - -4.0, pt._y, pt._x + 8.0, pt._y)); - surfaceArea->fn1(FRect(pt._x, pt._y - 8.0, pt._x, pt._y - 4.0)); - surfaceArea->fn1(FRect(pt._x, pt._y + 4.0, pt._x, pt._y + 8.0)); + surfaceArea->fillRect(FRect(pt._x - 8.0, pt._y, pt._x - 4.0, pt._y)); + surfaceArea->fillRect(FRect(pt._x - -4.0, pt._y, pt._x + 8.0, pt._y)); + surfaceArea->fillRect(FRect(pt._x, pt._y - 8.0, pt._x, pt._y - 4.0)); + surfaceArea->fillRect(FRect(pt._x, pt._y + 4.0, pt._x, pt._y + 8.0)); surfaceArea->_pixel = savedPixel; surfaceArea->setColorFromPixel(); diff --git a/engines/titanic/star_control/star_field.cpp b/engines/titanic/star_control/star_field.cpp index 5c22e5e308..5f6c883171 100644 --- a/engines/titanic/star_control/star_field.cpp +++ b/engines/titanic/star_control/star_field.cpp @@ -147,22 +147,22 @@ void CStarField::fn3(CSurfaceArea *surfaceArea) { surfaceArea->_pixel = 0x323232; surfaceArea->setColorFromPixel(); - surfaceArea->fn1(FRect(202.60417, 63.75, 397.39584, 63.75)); - surfaceArea->fn1(FRect(202.60417, 276.25, 397.39584, 276.25)); - surfaceArea->fn1(FRect(193.75, 72.604164, 193.75, 267.39584)); - surfaceArea->fn1(FRect(406.25, 72.604164, 406.25, 267.39584)); - surfaceArea->fn1(FRect(202.60417, 63.75, 202.60417, 68.177086)); - surfaceArea->fn1(FRect(397.39584, 63.75, 397.39584, 68.177086)); - surfaceArea->fn1(FRect(202.60417, 276.25, 202.60417, 271.82291)); - surfaceArea->fn1(FRect(397.39584, 276.25, 397.39584, 271.82291)); - surfaceArea->fn1(FRect(193.75, 72.604164, 198.17708, 72.604164)); - surfaceArea->fn1(FRect(193.75, 267.39584, 198.17708, 267.39584)); - surfaceArea->fn1(FRect(406.25, 72.604164, 401.82291, 72.604164)); - surfaceArea->fn1(FRect(406.25, 267.39584, 401.82291, 267.39584)); - surfaceArea->fn1(FRect(300.0, 63.75, 300.0, 54.895832)); - surfaceArea->fn1(FRect(300.0, 276.25, 300.0, 285.10416)); - surfaceArea->fn1(FRect(193.75, 170.0, 184.89583, 170.0)); - surfaceArea->fn1(FRect(406.25, 170.0, 415.10416, 170.0)); + surfaceArea->fillRect(FRect(202.60417, 63.75, 397.39584, 63.75)); + surfaceArea->fillRect(FRect(202.60417, 276.25, 397.39584, 276.25)); + surfaceArea->fillRect(FRect(193.75, 72.604164, 193.75, 267.39584)); + surfaceArea->fillRect(FRect(406.25, 72.604164, 406.25, 267.39584)); + surfaceArea->fillRect(FRect(202.60417, 63.75, 202.60417, 68.177086)); + surfaceArea->fillRect(FRect(397.39584, 63.75, 397.39584, 68.177086)); + surfaceArea->fillRect(FRect(202.60417, 276.25, 202.60417, 271.82291)); + surfaceArea->fillRect(FRect(397.39584, 276.25, 397.39584, 271.82291)); + surfaceArea->fillRect(FRect(193.75, 72.604164, 198.17708, 72.604164)); + surfaceArea->fillRect(FRect(193.75, 267.39584, 198.17708, 267.39584)); + surfaceArea->fillRect(FRect(406.25, 72.604164, 401.82291, 72.604164)); + surfaceArea->fillRect(FRect(406.25, 267.39584, 401.82291, 267.39584)); + surfaceArea->fillRect(FRect(300.0, 63.75, 300.0, 54.895832)); + surfaceArea->fillRect(FRect(300.0, 276.25, 300.0, 285.10416)); + surfaceArea->fillRect(FRect(193.75, 170.0, 184.89583, 170.0)); + surfaceArea->fillRect(FRect(406.25, 170.0, 415.10416, 170.0)); surfaceArea->_pixel = oldPixel; surfaceArea->setColorFromPixel(); @@ -176,7 +176,7 @@ void CStarField::fn4(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12) { if (fn5(surfaceArea, sub12, v1, v2, v3) > -1.0) { surfaceArea->_pixel = 0xA0A0; surfaceArea->setColorFromPixel(); - surfaceArea->fn1(FRect(v1._x, v1._y, v3._x, v3._y)); + surfaceArea->fillRect(FRect(v1._x, v1._y, v3._x, v3._y)); } } } diff --git a/engines/titanic/star_control/star_points1.cpp b/engines/titanic/star_control/star_points1.cpp index f433a65da3..17f833a7cd 100644 --- a/engines/titanic/star_control/star_points1.cpp +++ b/engines/titanic/star_control/star_points1.cpp @@ -97,7 +97,7 @@ void CStarPoints1::draw(CSurfaceArea *surface, CStarControlSub12 *sub12) { r.right = vector4._x + vWidth2; r.top = vector2._y + vHeight2; r.left = vector2._x + vWidth2; - surface->fn1(r); + surface->fillRect(r); } vector1 = vector3; diff --git a/engines/titanic/star_control/star_points2.cpp b/engines/titanic/star_control/star_points2.cpp index 4d77733830..3c49d9c165 100644 --- a/engines/titanic/star_control/star_points2.cpp +++ b/engines/titanic/star_control/star_points2.cpp @@ -108,7 +108,7 @@ void CStarPoints2::draw(CSurfaceArea *surface, CStarControlSub12 *sub12) { r.right = vector4._x + vWidth2; r.top = vector2._y + vHeight2; r.left = vector2._x + vWidth2; - surface->fn1(r); + surface->fillRect(r); } } } diff --git a/engines/titanic/star_control/surface_area.cpp b/engines/titanic/star_control/surface_area.cpp index 4cfc4f84d2..2c56fd9d8e 100644 --- a/engines/titanic/star_control/surface_area.cpp +++ b/engines/titanic/star_control/surface_area.cpp @@ -109,7 +109,7 @@ void CSurfaceArea::pixelToRGB(uint pixel, uint *rgb) { } } -double CSurfaceArea::fn1(const FRect &rect) { +double CSurfaceArea::fillRect(const FRect &rect) { if (rect.empty()) return rect.top; @@ -169,13 +169,54 @@ double CSurfaceArea::fn1(const FRect &rect) { } } - Common::Rect rr(round(r.left), round(r.top), round(r.right), round(r.bottom)); + Common::Rect rr((int)(r.left - 0.5), (int)(r.top - 0.5), (int)(r.right - 0.5), (int)(r.bottom - 0.5)); if (rr.left > rr.right) { SWAP(rr.left, rr.right); SWAP(rr.top, rr.bottom); } - // TODO: initial setup + Graphics::Surface s; + s.setPixels(_pixelsPtr); + s.pitch = _pitch; + s.w = _width; + s.h = _height; + + switch (_bpp) { + case 0: + s.format = Graphics::PixelFormat::createFormatCLUT8(); + break; + case 1: + case 2: + s.format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); + break; + case 4: + s.format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); + break; + default: + error("Unknown bpp"); + } + + // Fill area + if (_mode == SA_NONE) { + s.fillRect(rr, _rgb); + } else { + colorRect(s, rr, _colorMask, _color); + } +/* + int yInc = 1; + byte *lineStartP = (byte *)_pixelsPtr + rr.top * _pitch; + int width2 = rr.width() / 2; + int height2 = rr.height() / 2; + int xInc = _pitch; + + if (xInc < 0) { + --xInc; + yInc = -1; + } + + // rr: left=esi, edi=top, ebx=right, edx=bottom + // ecx=lineStartP; ebp=width2, edx=height2 + if (_mode == SA_NONE) { switch (_bpp) { default: @@ -189,8 +230,33 @@ double CSurfaceArea::fn1(const FRect &rect) { } // TODO: Lots more functionality - +*/ return r.top; } +template +static void colorRectFn(Graphics::Surface &s, const Common::Rect &r, + uint andMask, uint xorMask) { + for (int yp = r.top; yp < r.bottom; ++yp) { + T *pixelP = (T *)s.getBasePtr(r.left, yp); + for (int xp = r.left; xp < r.right; ++xp, ++pixelP) + *pixelP = (*pixelP & andMask) ^ xorMask; + } +} + +void CSurfaceArea::colorRect(Graphics::Surface &s, const Common::Rect &r, + uint andMask, uint xorMask) { + switch (s.format.bytesPerPixel) { + case 1: + colorRectFn(s, r, andMask, xorMask); + break; + case 2: + colorRectFn(s, r, andMask, xorMask); + break; + default: + colorRectFn(s, r, andMask, xorMask); + break; + } +} + } // End of namespace Titanic diff --git a/engines/titanic/star_control/surface_area.h b/engines/titanic/star_control/surface_area.h index dcff5ec50d..37cab2978b 100644 --- a/engines/titanic/star_control/surface_area.h +++ b/engines/titanic/star_control/surface_area.h @@ -47,6 +47,11 @@ private: void setColor(uint rgb); void pixelToRGB(uint pixel, uint *rgb); + + /** + * Alters the pixels of a specified rectangle using a passed and and xor mask + */ + static void colorRect(Graphics::Surface &s, const Common::Rect &r, uint andMask, uint xorMask); public: int _field0; int _width; @@ -79,7 +84,10 @@ public: */ void setColorFromPixel(); - double fn1(const FRect &rect); + /** + * Fills a rectangular area + */ + double fillRect(const FRect &rect); }; } // End of namespace Titanic -- cgit v1.2.3