aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/bladerunner/actor.cpp4
-rw-r--r--engines/bladerunner/bladerunner.cpp8
-rw-r--r--engines/bladerunner/matrix.h25
-rw-r--r--engines/bladerunner/scene_objects.cpp4
-rw-r--r--engines/bladerunner/slice_renderer.cpp207
-rw-r--r--engines/bladerunner/slice_renderer.h13
-rw-r--r--engines/bladerunner/view.cpp15
-rw-r--r--engines/bladerunner/view.h5
8 files changed, 213 insertions, 68 deletions
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp
index a55d94bd55..d4c4eeaee3 100644
--- a/engines/bladerunner/actor.cpp
+++ b/engines/bladerunner/actor.cpp
@@ -773,7 +773,7 @@ void Actor::setBoundingBox(const Vector3 &position, bool retired) {
float Actor::distanceFromView(View *view) const{
float xDist = _position.x - view->_cameraPosition.x;
- float zDist = _position.z + view->_cameraPosition.z;
+ float zDist = _position.z + view->_cameraPosition.y; // y<->z is intentional, not a bug
return sqrt(xDist * xDist + zDist * zDist);
}
@@ -859,7 +859,7 @@ void Actor::faceXYZ(const Vector3 &pos, bool animate) {
}
void Actor::faceCurrentCamera(bool animate) {
- faceXYZ(_vm->_view->_cameraPosition.x, _vm->_view->_cameraPosition.y, -_vm->_view->_cameraPosition.z, animate);
+ faceXYZ(_vm->_view->_cameraPosition.x, _vm->_view->_cameraPosition.z, -_vm->_view->_cameraPosition.y, animate); // y<->z is intentional, not a bug
}
void Actor::faceHeading(int heading, bool animate) {
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index de7d82498a..ea663b53bc 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -242,10 +242,6 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
_obstacles = new Obstacles(this);
- // TODO: slice renderer shadow
-
- // TODO: voight-kampf script
-
_sceneScript = new SceneScript(this);
_debugger = new Debugger(this);
@@ -620,9 +616,6 @@ void BladeRunnerEngine::shutdown() {
_playerActor = nullptr;
- delete _zbuffer;
- _zbuffer = nullptr;
-
delete _gameInfo;
_gameInfo = nullptr;
@@ -640,7 +633,6 @@ void BladeRunnerEngine::shutdown() {
// TODO: Delete Timer
-
// These are static objects in original game
delete _debugger;
diff --git a/engines/bladerunner/matrix.h b/engines/bladerunner/matrix.h
index 5fe7fc2a01..5343eb6b8e 100644
--- a/engines/bladerunner/matrix.h
+++ b/engines/bladerunner/matrix.h
@@ -44,12 +44,12 @@ public:
inline Matrix3x2 operator*(const Matrix3x2 &a, const Matrix3x2 &b) {
Matrix3x2 t;
- t(0,0) = a(0,0)*b(0,0) + a(0,1)*b(1,0);
- t(0,1) = a(0,0)*b(0,1) + a(0,1)*b(1,1);
- t(0,2) = a(0,0)*b(0,2) + a(0,1)*b(1,2) + a(0,2);
- t(1,0) = a(1,0)*b(0,0) + a(1,1)*b(1,0);
- t(1,1) = a(1,0)*b(0,1) + a(1,1)*b(1,1);
- t(1,2) = a(1,0)*b(0,2) + a(1,1)*b(1,2) + a(1,2);
+ t(0, 0) = a(0, 0) * b(0, 0) + a(0, 1) * b(1, 0);
+ t(0, 1) = a(0, 0) * b(0, 1) + a(0, 1) * b(1, 1);
+ t(0, 2) = a(0, 0) * b(0, 2) + a(0, 1) * b(1, 2) + a(0, 2);
+ t(1, 0) = a(1, 0) * b(0, 0) + a(1, 1) * b(1, 0);
+ t(1, 1) = a(1, 0) * b(0, 1) + a(1, 1) * b(1, 1);
+ t(1, 2) = a(1, 0) * b(0, 2) + a(1, 1) * b(1, 2) + a(1, 2);
return t;
}
@@ -66,8 +66,8 @@ inline Matrix3x2 operator+(const Matrix3x2 &a, Vector2 b) {
inline Vector2 operator*(const Matrix3x2 &a, Vector2 b) {
Vector2 t;
- t.x = a(0,0) * b.x + a(0,1) * b.y + a(0,2);
- t.y = a(1,0) * b.x + a(1,1) * b.y + a(1,2);
+ t.x = a(0, 0) * b.x + a(0, 1) * b.y + a(0, 2);
+ t.y = a(1, 0) * b.x + a(1, 1) * b.y + a(1, 2);
return t;
}
@@ -96,11 +96,10 @@ inline Matrix4x3 operator*(const Matrix4x3 &a, const Matrix4x3 &b) {
Matrix4x3 t;
for (int i = 0; i !=3; ++i) {
- // printf("t(%d,0) = %7.2f*%7.2f + %7.2f*%7.2f + %7.2f*%7.2f\n", i, a(i,0), b(0,0), a(i,0), b(1,0), a(i,0), b(2,0));
- t(i,0) = a(i,0)*b(0,0) + a(i,1)*b(1,0) + a(i,2)*b(2,0);
- t(i,1) = a(i,0)*b(0,1) + a(i,1)*b(1,1) + a(i,2)*b(2,1);
- t(i,2) = a(i,0)*b(0,2) + a(i,1)*b(1,2) + a(i,2)*b(2,2);
- t(i,3) = a(i,0)*b(0,3) + a(i,1)*b(1,3) + a(i,2)*b(2,3) + a(i,3);
+ t(i, 0) = a(i, 0) * b(0, 0) + a(i, 1) * b(1, 0) + a(i, 2) * b(2, 0);
+ t(i, 1) = a(i, 0) * b(0, 1) + a(i, 1) * b(1, 1) + a(i, 2) * b(2, 1);
+ t(i, 2) = a(i, 0) * b(0, 2) + a(i, 1) * b(1, 2) + a(i, 2) * b(2, 2);
+ t(i, 3) = a(i, 0) * b(0, 3) + a(i, 1) * b(1, 3) + a(i, 2) * b(2, 3) + a(i, 3);
}
return t;
diff --git a/engines/bladerunner/scene_objects.cpp b/engines/bladerunner/scene_objects.cpp
index 64cb04f40c..87320a3fa4 100644
--- a/engines/bladerunner/scene_objects.cpp
+++ b/engines/bladerunner/scene_objects.cpp
@@ -194,9 +194,9 @@ bool SceneObjects::addSceneObject(int sceneObjectId, SceneObjectType sceneObject
_sceneObjects[index].isMoving = isMoving;
_sceneObjects[index].isRetired = isRetired;
- float centerZ = (_sceneObjects[index].boundingBox->getZ0() + _sceneObjects[index].boundingBox->getZ1()) / 2.0;
+ float centerZ = (_sceneObjects[index].boundingBox->getZ0() + _sceneObjects[index].boundingBox->getZ1()) / 2.0f;
- float distanceToCamera = fabs(_view->_cameraPosition.z - centerZ);
+ float distanceToCamera = fabs(-centerZ - _view->_cameraPosition.y); // y<->z is intentional, not a bug
_sceneObjects[index].distanceToCamera = distanceToCamera;
// insert according to distance from camera
diff --git a/engines/bladerunner/slice_renderer.cpp b/engines/bladerunner/slice_renderer.cpp
index 42aaf253fe..15633f6581 100644
--- a/engines/bladerunner/slice_renderer.cpp
+++ b/engines/bladerunner/slice_renderer.cpp
@@ -60,6 +60,23 @@ SliceRenderer::SliceRenderer(BladeRunnerEngine *vm) {
_endSlice = 0.0f;
_m13 = 0;
_m23 = 0;
+
+ _shadowPolygonDefault[ 0] = Vector3( 16.0f, 96.0f, 0.0f);
+ _shadowPolygonDefault[ 1] = Vector3( 16.0f, 160.0f, 0.0f);
+ _shadowPolygonDefault[ 2] = Vector3( 64.0f, 192.0f, 0.0f);
+ _shadowPolygonDefault[ 3] = Vector3( 80.0f, 240.0f, 0.0f);
+ _shadowPolygonDefault[ 4] = Vector3(160.0f, 240.0f, 0.0f);
+ _shadowPolygonDefault[ 5] = Vector3(192.0f, 192.0f, 0.0f);
+ _shadowPolygonDefault[ 6] = Vector3(240.0f, 160.0f, 0.0f);
+ _shadowPolygonDefault[ 7] = Vector3(240.0f, 96.0f, 0.0f);
+ _shadowPolygonDefault[ 8] = Vector3(192.0f, 64.0f, 0.0f);
+ _shadowPolygonDefault[ 9] = Vector3(160.0f, 16.0f, 0.0f);
+ _shadowPolygonDefault[10] = Vector3( 96.0f, 16.0f, 0.0f);
+ _shadowPolygonDefault[11] = Vector3( 64.0f, 64.0f, 0.0f);
+
+ for (int i = 0; i < 12; ++i) {
+ _shadowPolygonCurrent[i] = Vector3(0.0f, 0.0f, 0.0f);
+ }
}
SliceRenderer::~SliceRenderer() {
@@ -100,19 +117,18 @@ void SliceRenderer::getScreenRectangle(Common::Rect *screenRectangle, int animat
Matrix3x2 SliceRenderer::calculateFacingRotationMatrix() {
assert(_sliceFramePtr);
- Matrix4x3 viewMatrix = _view->_sliceViewMatrix;
- Vector3 viewPos = viewMatrix * _position;
+ Vector3 viewPos = _view->_sliceViewMatrix * _position;
float dir = atan2f(viewPos.x, viewPos.z) + _facing;
float s = sinf(dir);
float c = cosf(dir);
- Matrix3x2 rotation( c, -s, 0.0f,
+ Matrix3x2 mRotation( c, -s, 0.0f,
s, c, 0.0f);
- Matrix3x2 viewRotation(viewMatrix(0,0), viewMatrix(0,1), 0.0f,
- viewMatrix(2,0), viewMatrix(2,1), 0.0f);
+ Matrix3x2 mView(_view->_sliceViewMatrix(0,0), _view->_sliceViewMatrix(0,1), 0.0f,
+ _view->_sliceViewMatrix(2,0), _view->_sliceViewMatrix(2,1), 0.0f);
- return viewRotation * rotation;
+ return mView * mRotation;
}
void SliceRenderer::calculateBoundingRect() {
@@ -133,29 +149,32 @@ void SliceRenderer::calculateBoundingRect() {
top = bottom + _scale * (top - bottom);
- if (bottom.z < 0.0f || top.z < 0.0f) {
+ if (bottom.z <= 0.0f || top.z <= 0.0f) {
return;
}
Matrix3x2 facingRotation = calculateFacingRotationMatrix();
- Matrix3x2 m_projection(_view->_viewportDistance / bottom.z, 0.0f, 0.0f,
- 0.0f, 25.5f, 0.0f);
+ Matrix3x2 mProjection(_view->_viewportPosition.z / bottom.z, 0.0f, 0.0f,
+ 0.0f, 25.5f, 0.0f);
- Matrix3x2 m_frame(_frameScale.x, 0.0f, _framePos.x,
- 0.0f, _frameScale.y, _framePos.y);
+ Matrix3x2 mOffset(1.0f, 0.0f, _framePos.x,
+ 0.0f, 1.0f, _framePos.y);
- _modelMatrix = m_projection * (facingRotation * m_frame);
+ Matrix3x2 mScale(_frameScale.x, 0.0f, 0.0f,
+ 0.0f, _frameScale.y, 0.0f);
+
+ _modelMatrix = mProjection * (facingRotation * (mOffset * mScale));
Vector4 startScreenVector(
- _view->_viewportHalfWidth + top.x / top.z * _view->_viewportDistance,
- _view->_viewportHalfHeight + top.y / top.z * _view->_viewportDistance,
+ _view->_viewportPosition.x + top.x / top.z * _view->_viewportPosition.z,
+ _view->_viewportPosition.y + top.y / top.z * _view->_viewportPosition.z,
1.0f / top.z,
_frameSliceCount * (1.0f / top.z));
Vector4 endScreenVector(
- _view->_viewportHalfWidth + bottom.x / bottom.z * _view->_viewportDistance,
- _view->_viewportHalfHeight + bottom.y / bottom.z * _view->_viewportDistance,
+ _view->_viewportPosition.x + bottom.x / bottom.z * _view->_viewportPosition.z,
+ _view->_viewportPosition.y + bottom.y / bottom.z * _view->_viewportPosition.z,
1.0f / bottom.z,
0.0f);
@@ -377,8 +396,6 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos
_modelMatrix
);
- Vector3 cameraPosition(_view->_cameraPosition.x, _view->_cameraPosition.z, _view->_cameraPosition.y); // not a bug
-
SliceRendererLights sliceRendererLights = SliceRendererLights(_lights);
_lights->setupFrame(_view->_frame);
@@ -394,7 +411,7 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos
float setEffectsColorCoeficient;
Color setEffectColor;
_setEffects->calculateColor(
- cameraPosition,
+ _view->_cameraPosition,
Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight),
&setEffectsColorCoeficient,
&setEffectColor);
@@ -414,9 +431,18 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos
setupLookupTable(_m22lookup, sliceLineIterator._sliceMatrix[1][1]);
_m23 = sliceLineIterator._sliceMatrix[1][2];
+ if (_animationsShadowEnabled[_animation]) {
+ float coeficientShadow;
+ Color colorShadow;
+ _setEffects->calculateColor(
+ _view->_cameraPosition,
+ _position,
+ &coeficientShadow,
+ &colorShadow);
+
+ int transparency = 32.0f * sqrt(setEffectColor.r * setEffectColor.r + setEffectColor.g * setEffectColor.g + setEffectColor.b * setEffectColor.b);
- if(_animationsShadowEnabled[_animation]) {
- //TODO: draw shadows
+ drawShadowInWorld(transparency, surface, zbuffer);
}
int frameY = sliceLineIterator._startY;
@@ -431,7 +457,7 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos
if (sliceLineIterator._currentY & 1) {
_setEffects->calculateColor(
- cameraPosition,
+ _view->_cameraPosition,
Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight),
&setEffectsColorCoeficient,
&setEffectColor);
@@ -578,16 +604,145 @@ void SliceRenderer::drawSlice(int slice, bool advanced, uint16 *frameLinePtr, ui
}
}
+void SliceRenderer::drawShadowInWorld(int transparency, Graphics::Surface &surface, uint16 *zbuffer) {
+ Matrix4x3 mOffset(
+ 1.0f, 0.0f, 0.0f, _framePos.x,
+ 0.0f, 1.0f, 0.0f, _framePos.y,
+ 0.0f, 0.0f, 1.0f, 0.0f);
+
+ Matrix4x3 mTransition(
+ 1.0f, 0.0f, 0.0f, _position.x,
+ 0.0f, 1.0f, 0.0f, _position.y,
+ 0.0f, 0.0f, 1.0f, _position.z);
+
+ Matrix4x3 mRotation(
+ cosf(_facing), -sinf(_facing), 0.0f, 0.0f,
+ sinf(_facing), cosf(_facing), 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f);
+
+ Matrix4x3 mScale(
+ _frameScale.x, 0.0f, 0.0f, 0.0f,
+ 0.0f, _frameScale.y, 0.0f, 0.0f,
+ 0.0f, 0.0f, _frameSliceHeight, 0.0f);
+
+ Matrix4x3 m = _view->_sliceViewMatrix * (mTransition * (mRotation * (mOffset * mScale)));
+
+ for (int i = 0; i < 12; ++i) {
+ Vector3 t = m * _shadowPolygonDefault[i];
+ if (t.z > 0.0f) {
+ _shadowPolygonCurrent[i] = Vector3(
+ _view->_viewportPosition.x + t.x / t.z * _view->_viewportPosition.z,
+ _view->_viewportPosition.y + t.y / t.z * _view->_viewportPosition.z,
+ t.z * 25.5f
+ );
+ } else {
+ _shadowPolygonCurrent[i] = Vector3(0.0f, 0.0f, 0.0f);
+ }
+ }
+
+ drawShadowPolygon(transparency, surface, zbuffer);
+}
+
+void SliceRenderer::drawShadowPolygon(int transparency, Graphics::Surface &surface, uint16 *zbuffer) {
+ // this simplified polygon drawing algo is in the game
+
+ int yMax = 0;
+ int yMin = 480;
+ uint16 zMin = 65535;
+
+ int polygonLeft[480] = {};
+ int polygonRight[480] = {};
+
+ int iNext = 11;
+ for (int i = 0; i < 12; ++i) {
+ int xCurrent = _shadowPolygonCurrent[i].x;
+ int yCurrent = _shadowPolygonCurrent[i].y;
+ int xNext = _shadowPolygonCurrent[iNext].x;
+ int yNext = _shadowPolygonCurrent[iNext].y;
+
+ if (yCurrent < yMin) {
+ yMin = yCurrent;
+ }
+ if (yCurrent > yMax) {
+ yMax = yCurrent;
+ }
+ if (_shadowPolygonCurrent[i].z < zMin) {
+ zMin = _shadowPolygonCurrent[i].z;
+ }
+
+ int xDelta = abs(xNext - xCurrent);
+ int yDelta = abs(yNext - yCurrent);
+
+ int xDirection = -1;
+ if (xCurrent < xNext) {
+ xDirection = 1;
+ }
+
+ int xCounter = 0;
+
+ int x = xCurrent;
+ int y = yCurrent;
+
+ if (yCurrent > yNext) {
+ while (y >= yNext) {
+ if (y >= 0 && y < 480) {
+ polygonLeft[y] = x;
+ }
+ xCounter += xDelta;
+ while (xCounter >= yDelta) {
+ x += xDirection;
+ xCounter -= yDelta;
+ }
+ --y;
+ }
+ } else if (yCurrent < yNext) {
+ while (y <= yNext) {
+ if (y >= 0 && y < 480) {
+ polygonRight[y] = x;
+ }
+ xCounter += xDelta;
+ while (xCounter >= yDelta) {
+ x += xDirection;
+ xCounter -= yDelta;
+ }
+ ++y;
+ }
+ }
+ iNext = (iNext + 1) % 12;
+ }
+
+ yMax = CLIP(yMax, 0, 480);
+ yMin = CLIP(yMin, 0, 480);
+
+ int ditheringFactor[] = { 0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5 };
+
+ for (int y = yMin; y < yMax; ++y) {
+ int xMin = CLIP(polygonLeft[y], 0, 640);
+ int xMax = CLIP(polygonRight[y], 0, 640);
+
+ for (int x = MIN(xMin, xMax); x < MAX(xMin, xMax); ++x) {
+ uint16 z = zbuffer[x + y * 640];
+ uint16 *pixel = (uint16*)surface.getBasePtr(x, y);
+
+ if (z >= zMin) {
+ int index = (x & 3) + ((y & 3) << 2);
+ if (transparency - ditheringFactor[index] <= 0) {
+ *pixel = ((*pixel & 0x7BDE) >> 1) + ((*pixel & 0x739C) >> 2);
+ }
+ }
+ }
+ }
+}
+
void SliceRenderer::preload(int animationId) {
- int i;
int frameCount = _vm->_sliceAnimations->getFrameCount(animationId);
- for (i = 0; i < frameCount; i++)
+ for (int i = 0; i < frameCount; ++i) {
_vm->_sliceAnimations->getFramePtr(animationId, i);
+ }
}
void SliceRenderer::disableShadows(int animationsIdsList[], int listSize) {
- int i;
- for (i = 0; i < listSize; i++) {
+ for (int i = 0; i < listSize; ++i) {
_animationsShadowEnabled[animationsIdsList[i]] = false;
}
}
diff --git a/engines/bladerunner/slice_renderer.h b/engines/bladerunner/slice_renderer.h
index cf3066f9e8..d2de61e279 100644
--- a/engines/bladerunner/slice_renderer.h
+++ b/engines/bladerunner/slice_renderer.h
@@ -83,14 +83,14 @@ class SliceRenderer {
bool _animationsShadowEnabled[997];
+ Vector3 _shadowPolygonDefault[12];
+ Vector3 _shadowPolygonCurrent[12];
+
Color _setEffectColor;
Color _lightsColor;
Graphics::PixelFormat _pixelFormat;
- Matrix3x2 calculateFacingRotationMatrix();
- void drawSlice(int slice, bool advanced, uint16 *frameLinePtr, uint16 *zbufLinePtr, int y);
-
public:
SliceRenderer(BladeRunnerEngine *vm);
~SliceRenderer();
@@ -103,7 +103,6 @@ public:
void setupFrameInWorld(int animationId, int animationFrame, Vector3 position, float facing, float scale = 1.0f);
void getScreenRectangle(Common::Rect *screenRectangle, int animationId, int animationFrame, Vector3 position, float facing, float scale);
void drawInWorld(int animationId, int animationFrame, Vector3 position, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer);
-
void drawOnScreen(int animationId, int animationFrame, int screenX, int screenY, float facing, float scale, Graphics::Surface &surface);
void preload(int animationId);
@@ -111,9 +110,13 @@ public:
void disableShadows(int *animationsIdsList, int listSize);
private:
-
void calculateBoundingRect();
+ Matrix3x2 calculateFacingRotationMatrix();
void loadFrame(int animation, int frame);
+
+ void drawSlice(int slice, bool advanced, uint16 *frameLinePtr, uint16 *zbufLinePtr, int y);
+ void drawShadowInWorld(int transparency, Graphics::Surface &surface, uint16 *zbuffer);
+ void drawShadowPolygon(int transparency, Graphics::Surface &surface, uint16 *zbuffer);
};
class SliceRendererLights {
diff --git a/engines/bladerunner/view.cpp b/engines/bladerunner/view.cpp
index 11cd99c9fc..d304b92bb1 100644
--- a/engines/bladerunner/view.cpp
+++ b/engines/bladerunner/view.cpp
@@ -48,10 +48,9 @@ bool View::readVqa(Common::ReadStream *stream) {
void View::setFovX(float fovX) {
_fovX = fovX;
- _viewportHalfWidth = 320.0f;
- _viewportHalfHeight = 240.0f;
-
- _viewportDistance = 320.0f / tanf(_fovX / 2.0f);
+ _viewportPosition.x = 320.0f;
+ _viewportPosition.y = 240.0f;
+ _viewportPosition.z = 320.0f / tanf(_fovX / 2.0f);
}
void View::calculateSliceViewMatrix() {
@@ -72,15 +71,15 @@ void View::calculateCameraPosition() {
Matrix4x3 invertedMatrix = invertMatrix(_sliceViewMatrix);
_cameraPosition.x = invertedMatrix(0, 3);
- _cameraPosition.z = invertedMatrix(1, 3); // this is not a bug, it Z & Y are inverted in original source
- _cameraPosition.y = invertedMatrix(2, 3);
+ _cameraPosition.y = invertedMatrix(1, 3);
+ _cameraPosition.z = invertedMatrix(2, 3);
}
Vector3 View::calculateScreenPosition(Vector3 worldPosition) {
Vector3 viewPosition = _frameViewMatrix * worldPosition;
return Vector3(
- this->_viewportHalfWidth - viewPosition.x / viewPosition.z * _viewportDistance,
- this->_viewportHalfHeight - viewPosition.y / viewPosition.z * _viewportDistance,
+ _viewportPosition.x - viewPosition.x / viewPosition.z * _viewportPosition.z,
+ _viewportPosition.y - viewPosition.y / viewPosition.z * _viewportPosition.z,
viewPosition.z
);
}
diff --git a/engines/bladerunner/view.h b/engines/bladerunner/view.h
index 9d53d0852f..e0695b78f0 100644
--- a/engines/bladerunner/view.h
+++ b/engines/bladerunner/view.h
@@ -39,10 +39,7 @@ public:
uint32 _frame;
Vector3 _cameraPosition;
-
- float _viewportHalfWidth;
- float _viewportHalfHeight;
- float _viewportDistance;
+ Vector3 _viewportPosition;
bool readVqa(Common::ReadStream *stream);
Vector3 calculateScreenPosition(Vector3 worldPosition);