[Scummvm-git-logs] scummvm master -> d16c0c72818d46526406921c25f47432939eb4d7
neuromancer
noreply at scummvm.org
Tue Aug 18 11:35:38 UTC 2026
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
d16c0c7281 COLONY: added missing perspective for stair rendering
Commit: d16c0c72818d46526406921c25f47432939eb4d7
https://github.com/scummvm/scummvm/commit/d16c0c72818d46526406921c25f47432939eb4d7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-08-18T13:35:24+02:00
Commit Message:
COLONY: added missing perspective for stair rendering
Changed paths:
engines/colony/colony.h
engines/colony/render.cpp
engines/colony/render_features.cpp
engines/colony/render_internal.h
engines/colony/render_objects.cpp
engines/colony/renderer.h
engines/colony/renderer_opengl.cpp
engines/colony/renderer_opengl_shaders.cpp
diff --git a/engines/colony/colony.h b/engines/colony/colony.h
index b2868f854e4..ab065095e88 100644
--- a/engines/colony/colony.h
+++ b/engines/colony/colony.h
@@ -713,6 +713,17 @@ private:
void drawWallFeature3D(int cellX, int cellY, int direction);
void drawCellFeature3D(int cellX, int cellY);
void getWallFace3D(int cellX, int cellY, int direction, float corners[4][3]);
+ bool isRecessFeature(int x, int y, int direction) const;
+ bool wallSegmentIsOpenWell(int x, int y, uint8 bit) const;
+ void getWallRecess3D(const float corners[4][3], float farC[4][3]) const;
+ void recessPoint(const float nearC[4][3], const float farC[4][3], float u, float v, float depth, float out[3]) const;
+ void recessLine(const float nearC[4][3], const float farC[4][3], float u1, float v1, float d1,
+ float u2, float v2, float d2, uint32 color);
+ void recessQuad(const float nearC[4][3], const float farC[4][3], const float *u, const float *v,
+ const float *d, int count, uint32 color);
+ void clipToWallFace(const float corners[4][3]);
+ void macFillRecess(const float nearC[4][3], const float farC[4][3], const float *u, const float *v,
+ const float *d, int count, int macIdx, bool macColors);
void getCellFace3D(int cellX, int cellY, bool ceiling, float corners[4][3]);
int occupiedObjectAt(int xnew, int ynew, int x, int y, const Locate *pobject);
diff --git a/engines/colony/render.cpp b/engines/colony/render.cpp
index df6437b0049..aa9b9fb8e25 100644
--- a/engines/colony/render.cpp
+++ b/engines/colony/render.cpp
@@ -404,6 +404,21 @@ uint8 ColonyEngine::wallAt(int x, int y) const {
return _wall[x][y];
}
+bool ColonyEngine::isRecessFeature(int x, int y, int direction) const {
+ const uint8 *map = mapFeatureAt(x, y, direction);
+ if (!map)
+ return false;
+ return map[0] == kWallFeatureUpStairs || map[0] == kWallFeatureDnStairs;
+}
+
+// Bit 0x01 spans (x,y-1)/(x,y); bit 0x02 spans (x-1,y)/(x,y). Either side may
+// record the well.
+bool ColonyEngine::wallSegmentIsOpenWell(int x, int y, uint8 bit) const {
+ if (bit == 0x01)
+ return isRecessFeature(x, y, kDirSouth) || isRecessFeature(x, y - 1, kDirNorth);
+ return isRecessFeature(x, y, kDirWest) || isRecessFeature(x - 1, y, kDirEast);
+}
+
const uint8 *ColonyEngine::mapFeatureAt(int x, int y, int direction) const {
if (x < 0 || x >= 31 || y < 0 || y >= 31 || direction < 0 || direction >= 5)
return nullptr;
@@ -986,10 +1001,11 @@ void ColonyEngine::renderCorridor3D() {
for (int y = 0; y < 32; y++) {
for (int x = 0; x < 32; x++) {
uint8 w = _wall[x][y];
- if (w & 0x01) {
+ // A stair well is a hole: the feature draws the opening itself.
+ if ((w & 0x01) && !wallSegmentIsOpenWell(x, y, 0x01)) {
_gfx->draw3DWall(x, y, x + 1, y, wallColor);
}
- if (w & 0x02) {
+ if ((w & 0x02) && !wallSegmentIsOpenWell(x, y, 0x02)) {
_gfx->draw3DWall(x, y, x, y + 1, wallColor);
}
}
diff --git a/engines/colony/render_features.cpp b/engines/colony/render_features.cpp
index ec211480f47..7d5ca1af7e2 100644
--- a/engines/colony/render_features.cpp
+++ b/engines/colony/render_features.cpp
@@ -87,6 +87,122 @@ void wallPoint(const float corners[4][3], float u, float v, float out[3]) {
out[2] = botZ + (topZ - botZ) * v;
}
+// Far mouth of a one-cell recess. Taking the direction from the quad's own normal
+// keeps it in step with whichever face getWallFace3D() built.
+void ColonyEngine::getWallRecess3D(const float corners[4][3], float farC[4][3]) const {
+ const float ux = corners[1][0] - corners[0][0];
+ const float uy = corners[1][1] - corners[0][1];
+ const float uz = corners[1][2] - corners[0][2];
+ const float vx = corners[3][0] - corners[0][0];
+ const float vy = corners[3][1] - corners[0][1];
+ const float vz = corners[3][2] - corners[0][2];
+
+ float nx = uy * vz - uz * vy;
+ float ny = uz * vx - ux * vz;
+ float nz = ux * vy - uy * vx;
+ const float len = sqrtf(nx * nx + ny * ny + nz * nz);
+ if (len < 0.001f) {
+ memcpy(farC, corners, sizeof(float) * 12);
+ return;
+ }
+ nx /= len;
+ ny /= len;
+ nz /= len;
+
+ const float awayX = corners[0][0] - (float)_me.xloc;
+ const float awayY = corners[0][1] - (float)_me.yloc;
+ const float awayZ = corners[0][2];
+ if (nx * awayX + ny * awayY + nz * awayZ < 0.0f) {
+ nx = -nx;
+ ny = -ny;
+ nz = -nz;
+ }
+
+ for (int i = 0; i < 4; i++) {
+ farC[i][0] = corners[i][0] + nx * 256.0f;
+ farC[i][1] = corners[i][1] + ny * 256.0f;
+ farC[i][2] = corners[i][2] + nz * 256.0f;
+ }
+}
+
+// Depth 0 at the wall face, 1 a cell in. renderCorridor3D() drops the wall
+// segment, so this needs no depth trickery.
+void ColonyEngine::recessPoint(const float nearC[4][3], const float farC[4][3],
+ float u, float v, float depth, float out[3]) const {
+ float pn[3];
+ float pf[3];
+ wallPoint(nearC, u, v, pn);
+ wallPoint(farC, u, v, pf);
+ for (int i = 0; i < 3; i++)
+ out[i] = pn[i] + (pf[i] - pn[i]) * depth;
+}
+
+void ColonyEngine::recessLine(const float nearC[4][3], const float farC[4][3],
+ float u1, float v1, float d1, float u2, float v2, float d2, uint32 color) {
+ float p1[3];
+ float p2[3];
+ recessPoint(nearC, farC, u1, v1, d1, p1);
+ recessPoint(nearC, farC, u2, v2, d2, p2);
+ _gfx->draw3DLine(p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], color);
+}
+
+void ColonyEngine::recessQuad(const float nearC[4][3], const float farC[4][3],
+ const float *u, const float *v, const float *d, int count, uint32 color) {
+ float px[8];
+ float py[8];
+ float pz[8];
+ if (count > 8)
+ count = 8;
+ for (int i = 0; i < count; i++) {
+ float p[3];
+ recessPoint(nearC, farC, u[i], v[i], d[i], p);
+ px[i] = p[0];
+ py[i] = p[1];
+ pz[i] = p[2];
+ }
+ _gfx->draw3DPolygon(px, py, pz, count, color);
+}
+
+// A well legitimately projects outside its opening, so it needs the original's
+// per-wall clip or it paints over the neighbours.
+void ColonyEngine::clipToWallFace(const float corners[4][3]) {
+ int minX = 0;
+ int maxX = 0;
+ for (int i = 0; i < 4; i++) {
+ int sx = 0;
+ int sy = 0;
+ projectCorridorPointClamped(_screenR, _me.look, _me.lookY, _sint, _cost, _me.xloc, _me.yloc,
+ corners[i][0], corners[i][1], corners[i][2], sx, sy);
+ if (i == 0) {
+ minX = sx;
+ maxX = sx;
+ continue;
+ }
+ if (sx < minX)
+ minX = sx;
+ if (sx > maxX)
+ maxX = sx;
+ }
+ _gfx->setFeatureClipX(minX, maxX + 1);
+}
+
+void ColonyEngine::macFillRecess(const float nearC[4][3], const float farC[4][3],
+ const float *u, const float *v, const float *d, int count, int macIdx, bool macColors) {
+ if (macColors) {
+ uint32 fg = packMacColor(_macColors[macIdx].fg);
+ uint32 bg = packMacColor(_macColors[macIdx].bg);
+ const byte *stipple = setupMacPattern(_gfx, _macColors[macIdx].pattern, fg, bg);
+ recessQuad(nearC, farC, u, v, d, count, fg);
+ if (stipple)
+ _gfx->setStippleData(nullptr);
+ return;
+ }
+
+ _gfx->setStippleData(kStippleGray);
+ recessQuad(nearC, farC, u, v, d, count, 0);
+ _gfx->setStippleData(nullptr);
+}
+
// Draw a line on a wall face using normalized (u,v) coordinates
void ColonyEngine::wallLine(const float corners[4][3], float u1, float v1, float u2, float v2, uint32 color) {
float p1[3], p2[3];
@@ -649,130 +765,116 @@ void ColonyEngine::drawWallFeature3D(int cellX, int cellY, int direction) {
break;
}
case kWallFeatureUpStairs: {
- // DOS: draw_up_stairs staircase ascending into the wall with perspective
+ // wallftrs.c draw_up_stairs(): a well one cell deep, so it recedes for real.
const uint32 col = macColors ? (uint32)0xFF000000 : 0; // vBLACK
+ float farC[4][3];
+ getWallRecess3D(corners, farC);
+ clipToWallFace(corners);
- // Mac: fill entire wall face (c_upstairs)
+ float dep[7];
+ float hgt[7];
+ for (int i = 0; i < 7; i++) {
+ dep[i] = (float)(i + 1) / 8.0f;
+ hgt[i] = (float)(i + 1) / 8.0f;
+ }
+
+ // ColorWall(), now the back of the hole.
if (isMacRenderMode()) {
- float uf[4] = {0.0f, 1.0f, 1.0f, 0.0f};
- float vf2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
- if (macColors) {
- macFillPoly(uf, vf2, 4, 19); // c_upstairs1
- } else {
- _gfx->setStippleData(kStippleGray);
- wallPolygon(corners, uf, vf2, 4, 0);
- _gfx->setStippleData(nullptr);
+ const float uw[4] = {0.0f, 1.0f, 1.0f, 0.0f};
+ const float vw[4] = {0.0f, 0.0f, 1.0f, 1.0f};
+ const float dw[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ macFillRecess(corners, farC, uw, vw, dw, 4, 19, macColors); // c_upstairs1
+
+ // Treads c_upstairs1, risers c_upstairs2, back to front.
+ for (int i = 6; i >= 0; i--) {
+ const float lowV = (i > 0) ? hgt[i - 1] : 0.0f;
+ const float backD = (i > 0) ? dep[i - 1] : 0.0f;
+ const float uq[4] = {0.0f, 0.0f, 1.0f, 1.0f};
+ const float vRiser[4] = {hgt[i], lowV, lowV, hgt[i]};
+ const float dRiser[4] = {dep[i], dep[i], dep[i], dep[i]};
+ macFillRecess(corners, farC, uq, vRiser, dRiser, 4, 20, macColors);
+
+ const float vTread[4] = {lowV, lowV, lowV, lowV};
+ const float dTread[4] = {backD, dep[i], dep[i], backD};
+ macFillRecess(corners, farC, uq, vTread, dTread, 4, 19, macColors);
}
- }
- // Perspective convergence: back of passage at ~1/3 width (1 cell deep)
- float ul[7], ur[7], vf[7], vc[7];
- for (int i = 0; i < 7; i++) {
- float f = (i + 1) / 8.0f;
- float inset = f * (1.0f / 3.0f);
- ul[i] = inset;
- ur[i] = 1.0f - inset;
- vf[i] = inset; // floor rises toward center
- vc[i] = 1.0f - inset; // ceiling drops toward center
- }
- // Back of passage (full depth)
- float bi = 1.0f / 3.0f; // back inset
- float bu = bi, bur = 1.0f - bi, bvc = 1.0f - bi;
-
- // 1. Side wall verticals at back of passage
- wallLine(corners, bu, bvc, bu, 0.5f, col);
- wallLine(corners, bur, 0.5f, bur, bvc, col);
-
- // 2. Back wall landing (depth 6 to full depth)
- wallLine(corners, ul[6], stairStepHeight(vf, vc, 6, 6), bu, bvc, col);
- wallLine(corners, bu, bvc, bur, bvc, col);
- wallLine(corners, bur, bvc, ur[6], stairStepHeight(vf, vc, 6, 6), col);
- wallLine(corners, ur[6], stairStepHeight(vf, vc, 6, 6), ul[6], stairStepHeight(vf, vc, 6, 6), col);
-
- // 3. First step tread (floor from wall face to depth 0)
- wallLine(corners, 0.0f, 0.0f, ul[0], vf[0], col);
- wallLine(corners, ul[0], vf[0], ur[0], vf[0], col);
- wallLine(corners, ur[0], vf[0], 1.0f, 0.0f, col);
- wallLine(corners, 1.0f, 0.0f, 0.0f, 0.0f, col);
-
- // 4. First step riser (at depth 0)
- wallLine(corners, ul[0], stairStepHeight(vf, vc, 0, 0), ul[0], vf[0], col);
- wallLine(corners, ur[0], vf[0], ur[0], stairStepHeight(vf, vc, 0, 0), col);
- wallLine(corners, ur[0], stairStepHeight(vf, vc, 0, 0), ul[0], stairStepHeight(vf, vc, 0, 0), col);
-
- // 5. Step treads (i=3..0: depth i to depth i+1)
- for (int i = 3; i >= 0; i--) {
- wallLine(corners, ul[i], stairStepHeight(vf, vc, i, i), ul[i + 1], stairStepHeight(vf, vc, i + 1, i), col);
- wallLine(corners, ul[i + 1], stairStepHeight(vf, vc, i + 1, i), ur[i + 1], stairStepHeight(vf, vc, i + 1, i), col);
- wallLine(corners, ur[i + 1], stairStepHeight(vf, vc, i + 1, i), ur[i], stairStepHeight(vf, vc, i, i), col);
- wallLine(corners, ur[i], stairStepHeight(vf, vc, i, i), ul[i], stairStepHeight(vf, vc, i, i), col);
+ const float ub[4] = {0.0f, 0.0f, 1.0f, 1.0f};
+ const float vb[4] = {hgt[6], hgt[6], hgt[6], hgt[6]};
+ const float db[4] = {dep[6], 1.0f, 1.0f, dep[6]};
+ macFillRecess(corners, farC, ub, vb, db, 4, 19, macColors);
}
- // 6. Step risers (i=5..0: vertical face at depth i+1)
- for (int i = 5; i >= 0; i--) {
- wallLine(corners, ul[i + 1], stairStepHeight(vf, vc, i + 1, i + 1), ul[i + 1], stairStepHeight(vf, vc, i + 1, i), col);
- wallLine(corners, ul[i + 1], stairStepHeight(vf, vc, i + 1, i), ur[i + 1], stairStepHeight(vf, vc, i + 1, i), col);
- wallLine(corners, ur[i + 1], stairStepHeight(vf, vc, i + 1, i), ur[i + 1], stairStepHeight(vf, vc, i + 1, i + 1), col);
- wallLine(corners, ur[i + 1], stairStepHeight(vf, vc, i + 1, i + 1), ul[i + 1], stairStepHeight(vf, vc, i + 1, i + 1), col);
+ // Back landing and far mouth
+ recessLine(corners, farC, 0.0f, hgt[6], dep[6], 0.0f, hgt[6], 1.0f, col);
+ recessLine(corners, farC, 0.0f, hgt[6], 1.0f, 1.0f, hgt[6], 1.0f, col);
+ recessLine(corners, farC, 1.0f, hgt[6], 1.0f, 1.0f, hgt[6], dep[6], col);
+ recessLine(corners, farC, 0.0f, hgt[6], 1.0f, 0.0f, 1.0f, 1.0f, col);
+ recessLine(corners, farC, 1.0f, hgt[6], 1.0f, 1.0f, 1.0f, 1.0f, col);
+
+ // Treads and risers
+ for (int i = 6; i >= 0; i--) {
+ const float lowV = (i > 0) ? hgt[i - 1] : 0.0f;
+ const float backD = (i > 0) ? dep[i - 1] : 0.0f;
+ recessLine(corners, farC, 0.0f, lowV, backD, 0.0f, lowV, dep[i], col);
+ recessLine(corners, farC, 1.0f, lowV, backD, 1.0f, lowV, dep[i], col);
+ recessLine(corners, farC, 0.0f, lowV, dep[i], 1.0f, lowV, dep[i], col);
+ recessLine(corners, farC, 0.0f, lowV, dep[i], 0.0f, hgt[i], dep[i], col);
+ recessLine(corners, farC, 1.0f, lowV, dep[i], 1.0f, hgt[i], dep[i], col);
+ recessLine(corners, farC, 0.0f, hgt[i], dep[i], 1.0f, hgt[i], dep[i], col);
}
- // 7. Handrails: from center of wall edges up to near-ceiling at mid-depth
- wallLine(corners, 0.0f, 0.5f, ul[3], vc[0], col);
- wallLine(corners, 1.0f, 0.5f, ur[3], vc[0], col);
+ // Handrails
+ recessLine(corners, farC, 0.0f, 0.5f, 0.0f, 0.0f, 1.0f, dep[3], col);
+ recessLine(corners, farC, 1.0f, 0.5f, 0.0f, 1.0f, 1.0f, dep[3], col);
+ _gfx->clearFeatureClipX();
break;
}
case kWallFeatureDnStairs: {
- // DOS: draw_dn_stairs staircase descending into the wall with perspective
+ // wallftrs.c draw_dn_stairs(): the same well, dropping away.
const uint32 col = macColors ? (uint32)0xFF000000 : 0; // vBLACK
+ float farC[4][3];
+ getWallRecess3D(corners, farC);
+ clipToWallFace(corners);
+
+ float dep[7];
+ for (int i = 0; i < 7; i++)
+ dep[i] = (float)(i + 1) / 8.0f;
- // Mac: fill entire wall face (c_dnstairs)
if (isMacRenderMode()) {
- float uf[4] = {0.0f, 1.0f, 1.0f, 0.0f};
- float vf2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
- if (macColors) {
- macFillPoly(uf, vf2, 4, 21); // c_dnstairs
- } else {
- _gfx->setStippleData(kStippleGray);
- wallPolygon(corners, uf, vf2, 4, 0);
- _gfx->setStippleData(nullptr);
- }
+ const float uw[4] = {0.0f, 1.0f, 1.0f, 0.0f};
+ const float vw[4] = {0.0f, 0.0f, 1.0f, 1.0f};
+ const float dw[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ macFillRecess(corners, farC, uw, vw, dw, 4, 21, macColors); // c_dnstairs
+
+ // Well floor
+ const float uq[4] = {0.0f, 0.0f, 1.0f, 1.0f};
+ const float vFloor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float dFloor[4] = {0.0f, 1.0f, 1.0f, 0.0f};
+ macFillRecess(corners, farC, uq, vFloor, dFloor, 4, 21, macColors);
}
- float ul[7], ur[7], vf[7], vc[7];
- for (int i = 0; i < 7; i++) {
- float f = (i + 1) / 8.0f;
- float inset = f * (1.0f / 3.0f);
- ul[i] = inset;
- ur[i] = 1.0f - inset;
- vf[i] = inset;
- vc[i] = 1.0f - inset;
- }
- float bi = 1.0f / 3.0f;
- float bu = bi, bur = 1.0f - bi;
-
- // 1. Ceiling: front ceiling slopes down to mid-depth
- wallLine(corners, 0.0f, 1.0f, ul[3], vc[3], col);
- wallLine(corners, ul[3], vc[3], ur[3], vc[3], col);
- wallLine(corners, ur[3], vc[3], 1.0f, 1.0f, col);
-
- // 2. Slant: from mid-depth ceiling down to center at back
- wallLine(corners, ul[3], vc[3], bu, 0.5f, col);
- wallLine(corners, bu, 0.5f, bur, 0.5f, col);
- wallLine(corners, bur, 0.5f, ur[3], vc[3], col);
-
- // 3. Side wall verticals: from center at back down to floor level
- wallLine(corners, bu, 0.5f, bu, vf[0], col);
- wallLine(corners, bur, 0.5f, bur, vf[0], col);
-
- // 4. First step (floor from wall face to depth 0)
- wallLine(corners, 0.0f, 0.0f, ul[0], vf[0], col);
- wallLine(corners, ul[0], vf[0], ur[0], vf[0], col);
- wallLine(corners, ur[0], vf[0], 1.0f, 0.0f, col);
- wallLine(corners, 1.0f, 0.0f, 0.0f, 0.0f, col);
-
- // 5. Handrails: from center of wall edges down to floor at mid-depth
- wallLine(corners, 0.0f, 0.5f, ul[3], vf[3], col);
- wallLine(corners, 1.0f, 0.5f, ur[3], vf[3], col);
+ // Ceiling, then the slant to the far mouth
+ recessLine(corners, farC, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, dep[3], col);
+ recessLine(corners, farC, 0.0f, 1.0f, dep[3], 1.0f, 1.0f, dep[3], col);
+ recessLine(corners, farC, 1.0f, 1.0f, dep[3], 1.0f, 1.0f, 0.0f, col);
+ recessLine(corners, farC, 0.0f, 1.0f, dep[3], 0.0f, 0.5f, 1.0f, col);
+ recessLine(corners, farC, 0.0f, 0.5f, 1.0f, 1.0f, 0.5f, 1.0f, col);
+ recessLine(corners, farC, 1.0f, 0.5f, 1.0f, 1.0f, 1.0f, dep[3], col);
+
+ // Side walls down to the well floor
+ recessLine(corners, farC, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, col);
+ recessLine(corners, farC, 1.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f, col);
+ recessLine(corners, farC, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, col);
+ recessLine(corners, farC, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, col);
+
+ // First step
+ recessLine(corners, farC, 0.0f, 0.0f, dep[0], 1.0f, 0.0f, dep[0], col);
+
+ // Handrails
+ recessLine(corners, farC, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, dep[3], col);
+ recessLine(corners, farC, 1.0f, 0.5f, 0.0f, 1.0f, 0.0f, dep[3], col);
+ _gfx->clearFeatureClipX();
break;
}
case kWallFeatureChar:
diff --git a/engines/colony/render_internal.h b/engines/colony/render_internal.h
index 0af6bb1b877..3d61af62c9f 100644
--- a/engines/colony/render_internal.h
+++ b/engines/colony/render_internal.h
@@ -33,6 +33,12 @@
namespace Colony {
+// render.cpp; shared with the wall-feature renderer.
+void projectCorridorPointClamped(const Common::Rect &screenR, int look, int lookY,
+ const int *sint, const int *cost, int camX, int camY,
+ float worldX, float worldY, float worldZ,
+ int &screenX, int &screenY);
+
// Mac Classic dither patterns (from colorize.c cColor[].pattern).
// Mac Classic was a 1-bit B&W display. QuickDraw used 8x8 dither patterns
// to simulate grayscale: WHITE, LTGRAY, GRAY, DKGRAY, BLACK, CLEAR.
diff --git a/engines/colony/render_objects.cpp b/engines/colony/render_objects.cpp
index 59b1434a743..e0dbf38e32e 100644
--- a/engines/colony/render_objects.cpp
+++ b/engines/colony/render_objects.cpp
@@ -1141,7 +1141,6 @@ const int kSnoopHeadSurf[3][8] = {
};
const Colony::ColonyEngine::PrismPartDef kSnoopAbdomenDef = {4, kSnoopAbdomenPts, 2, kSnoopAbdomenSurf};
-const Colony::ColonyEngine::PrismPartDef kSnoopHeadDef = {4, kSnoopHeadPts, 3, kSnoopHeadSurf};
int wrapAngle256(int angle) {
angle %= 256;
diff --git a/engines/colony/renderer.h b/engines/colony/renderer.h
index 179c890a62b..eec455a4ba6 100644
--- a/engines/colony/renderer.h
+++ b/engines/colony/renderer.h
@@ -70,6 +70,9 @@ public:
virtual void setMacColors(uint32 fg, uint32 bg) {}
virtual void setDepthState(bool testEnabled, bool writeEnabled) {}
virtual void setDepthRange(float nearVal, float farVal) {}
+ // features.c clipped each wall feature to its own wall (ClipRect(&rClip)).
+ virtual void setFeatureClipX(int left, int right) {}
+ virtual void clearFeatureClipX() {}
virtual void computeScreenViewport() = 0;
// Window-pixel rect the logical canvas is drawn into: the whole window
diff --git a/engines/colony/renderer_opengl.cpp b/engines/colony/renderer_opengl.cpp
index c4818ac0db7..d967daafff9 100644
--- a/engines/colony/renderer_opengl.cpp
+++ b/engines/colony/renderer_opengl.cpp
@@ -93,6 +93,30 @@ public:
void setDepthRange(float nearVal, float farVal) override {
glDepthRange(nearVal, farVal);
}
+
+ void applyScissorRect(const Common::Rect &logical) {
+ const float scaleX = (float)_screenViewport.width() / (float)_width;
+ const float scaleY = (float)_screenViewport.height() / (float)_height;
+ const int sysH = _system->getHeight();
+ const int vpX = _screenViewport.left + (int)(logical.left * scaleX);
+ const int vpY = sysH - (_screenViewport.top + (int)(logical.bottom * scaleY));
+ const int vpW = (int)(logical.width() * scaleX);
+ const int vpH = (int)(logical.height() * scaleY);
+ glScissor(vpX, vpY, vpW > 0 ? vpW : 0, vpH > 0 ? vpH : 0);
+ }
+ void setFeatureClipX(int left, int right) override {
+ Common::Rect clipped = _active3DViewport;
+ if (left > clipped.left)
+ clipped.left = left;
+ if (right < clipped.right)
+ clipped.right = right;
+ if (clipped.left >= clipped.right)
+ clipped.right = clipped.left;
+ applyScissorRect(clipped);
+ }
+ void clearFeatureClipX() override {
+ applyScissorRect(_active3DViewport);
+ }
void computeScreenViewport() override;
void drawSurface(const Graphics::Surface *surf, int x, int y) override;
Graphics::Surface *getScreenshot() override;
@@ -110,6 +134,7 @@ private:
GLuint _overlayTexId = 0;
OSystem *_system = nullptr;
+ Common::Rect _active3DViewport;
int _width = 0;
int _height = 0;
byte _palette[256 * 3] = {};
@@ -274,6 +299,7 @@ void OpenGLRenderer::begin3D(int camX, int camY, int camZ, int angle, int angleY
glViewport(vpX, vpY, vpW, vpH);
glScissor(vpX, vpY, vpW, vpH);
+ _active3DViewport = viewport;
glEnable(GL_SCISSOR_TEST);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
diff --git a/engines/colony/renderer_opengl_shaders.cpp b/engines/colony/renderer_opengl_shaders.cpp
index f05bb02c14d..e97a898c68e 100644
--- a/engines/colony/renderer_opengl_shaders.cpp
+++ b/engines/colony/renderer_opengl_shaders.cpp
@@ -80,6 +80,9 @@ public:
void setMacColors(uint32 fg, uint32 bg) override;
void setDepthState(bool testEnabled, bool writeEnabled) override;
void setDepthRange(float nearVal, float farVal) override;
+ void setFeatureClipX(int left, int right) override;
+ void clearFeatureClipX() override;
+ void applyScissorRect(const Common::Rect &logical);
void computeScreenViewport() override;
void drawSurface(const Graphics::Surface *surf, int x, int y) override;
@@ -116,6 +119,7 @@ private:
void drawWireframeable3D(const float *positions, int vertCount, uint32 color);
OSystem *_system = nullptr;
+ Common::Rect _active3DViewport;
int _width = 0;
int _height = 0;
byte _palette[256 * 3] = {};
@@ -722,6 +726,32 @@ void OpenGLShaderRenderer::setDepthRange(float nearVal, float farVal) {
setGLDepthRange(nearVal, farVal);
}
+void OpenGLShaderRenderer::applyScissorRect(const Common::Rect &logical) {
+ const float scaleX = (float)_screenViewport.width() / (float)_width;
+ const float scaleY = (float)_screenViewport.height() / (float)_height;
+ const int sysH = _system->getHeight();
+ const int vpX = _screenViewport.left + (int)(logical.left * scaleX);
+ const int vpY = sysH - (_screenViewport.top + (int)(logical.bottom * scaleY));
+ const int vpW = (int)(logical.width() * scaleX);
+ const int vpH = (int)(logical.height() * scaleY);
+ glScissor(vpX, vpY, vpW > 0 ? vpW : 0, vpH > 0 ? vpH : 0);
+}
+
+void OpenGLShaderRenderer::setFeatureClipX(int left, int right) {
+ Common::Rect clipped = _active3DViewport;
+ if (left > clipped.left)
+ clipped.left = left;
+ if (right < clipped.right)
+ clipped.right = right;
+ if (clipped.left >= clipped.right)
+ clipped.right = clipped.left;
+ applyScissorRect(clipped);
+}
+
+void OpenGLShaderRenderer::clearFeatureClipX() {
+ applyScissorRect(_active3DViewport);
+}
+
void OpenGLShaderRenderer::begin3D(int camX, int camY, int camZ, int angle, int angleY,
const Common::Rect &viewport) {
glEnable(GL_DEPTH_TEST);
@@ -738,6 +768,7 @@ void OpenGLShaderRenderer::begin3D(int camX, int camY, int camZ, int angle, int
const int vpH = (int)(viewport.height() * scaleY);
glViewport(vpX, vpY, vpW, vpH);
glScissor(vpX, vpY, vpW, vpH);
+ _active3DViewport = viewport;
glEnable(GL_SCISSOR_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
More information about the Scummvm-git-logs
mailing list