aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/bladerunner/actor.cpp7
-rw-r--r--engines/bladerunner/bladerunner.cpp32
-rw-r--r--engines/bladerunner/color.h18
-rw-r--r--engines/bladerunner/fog.cpp288
-rw-r--r--engines/bladerunner/fog.h5
-rw-r--r--engines/bladerunner/light.cpp198
-rw-r--r--engines/bladerunner/light.h25
-rw-r--r--engines/bladerunner/lights.cpp88
-rw-r--r--engines/bladerunner/lights.h2
-rw-r--r--engines/bladerunner/set_effects.cpp53
-rw-r--r--engines/bladerunner/set_effects.h2
-rw-r--r--engines/bladerunner/slice_animations.cpp6
-rw-r--r--engines/bladerunner/slice_animations.h10
-rw-r--r--engines/bladerunner/slice_renderer.cpp373
-rw-r--r--engines/bladerunner/slice_renderer.h50
-rw-r--r--engines/bladerunner/vector.h14
-rw-r--r--engines/bladerunner/view.cpp6
17 files changed, 909 insertions, 268 deletions
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp
index c0c042e47f..29c83e78cb 100644
--- a/engines/bladerunner/actor.cpp
+++ b/engines/bladerunner/actor.cpp
@@ -399,12 +399,11 @@ bool Actor::tick(bool forceDraw) {
void Actor::draw() {
Vector3 draw_position(_position.x, -_position.z, _position.y + 2.0);
float draw_facing = M_PI - _facing * M_PI / 512.0;
- // float draw_scale = _scale;
+ float draw_scale = _scale;
// TODO: Handle SHORTY mode
-
- _vm->_sliceRenderer->setupFrame(_animationId, _animationFrame, draw_position, draw_facing);
- _vm->_sliceRenderer->drawFrame(_vm->_surface2, _vm->_zBuffer2);
+
+ _vm->_sliceRenderer->drawFrame(_animationId, _animationFrame, draw_position, draw_facing, draw_scale, _vm->_surface2, _vm->_zBuffer2);
}
int Actor::getSetId() {
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 45ffdd8998..41f1bb55d3 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -613,7 +613,7 @@ void BladeRunnerEngine::gameTick() {
_walkSoundId = -1;
}
-#if _DEBUG
+#if 0 //_DEBUG
//draw scene objects
int count = _sceneObjects->_count;
if (count > 0) {
@@ -667,35 +667,6 @@ void BladeRunnerEngine::gameTick() {
}
}
-
- for (Light* light = _lights->_lights; light != nullptr; light->_next) {
-
- Matrix4x3 matrix = light->_matrix;
-
- // this is all wrong
-
-// matrix = matrix * rotationMatrixX(float(M_PI) / 2.0f);
-
-// Matrix4x3 a(
-// -1.0f, 0.0f, 0.0f, 0.0f,
-// 0.0f, -1.0f, 0.0f, 0.0f,
-// 0.0f, 0.0f, 1.0f, 0.0f);
-
- //matrix = a * matrix;
-// matrix = invertMatrix(matrix);
-
- int colorR = (light->_color.r * 31.0f);
- int colorG = (light->_color.g * 31.0f);
- int colorB = (light->_color.b * 31.0f);
- int color = (colorR << 10) + (colorG << 5) + colorB;
- drawBBox(
- Vector3(matrix(0, 3) - 5.0f, matrix(1, 3) - 5.0f, matrix(2, 3) - 5.0f),
- Vector3(matrix(0, 3) + 5.0f, matrix(1, 3) + 5.0f, matrix(2, 3) + 5.0f),
- _view, &_surface2, color
- );
- light = light->_next;
-
- }
#endif
_system->copyRectToScreen((const byte *)_surface2.getBasePtr(0, 0), _surface2.pitch, 0, 0, 640, 480);
@@ -751,6 +722,7 @@ void BladeRunnerEngine::handleMouseClick(int x, int y) {
}
if (sceneObjectId == -1) {
+ _actors[0]->loopWalkToXYZ(mousePosition);
debug("Clicked on nothing");
return;
} else if (sceneObjectId >= 0 && sceneObjectId <= 73) {
diff --git a/engines/bladerunner/color.h b/engines/bladerunner/color.h
index eebe2dcdc0..10d3737f76 100644
--- a/engines/bladerunner/color.h
+++ b/engines/bladerunner/color.h
@@ -23,13 +23,27 @@
#ifndef BLADERUNNER_COLOR_H
#define BLADERUNNER_COLOR_H
+#include "common/system.h"
+
namespace BladeRunner {
-struct Color
-{
+struct Color {
float r;
float g;
float b;
+
+
+ Color() {
+ }
+
+ Color(float r, float g, float b) : r(r), g(g), b(b) {
+ }
+};
+
+struct Color256 {
+ uint8 r;
+ uint8 g;
+ uint8 b;
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/fog.cpp b/engines/bladerunner/fog.cpp
index ead7c91db2..bca548c0ef 100644
--- a/engines/bladerunner/fog.cpp
+++ b/engines/bladerunner/fog.cpp
@@ -4,16 +4,13 @@
namespace BladeRunner {
-Fog::Fog()
-{
+Fog::Fog() {
}
-Fog::~Fog()
-{
+Fog::~Fog() {
}
-int Fog::readCommon(Common::ReadStream* stream)
-{
+int Fog::readCommon(Common::ReadStream *stream) {
int offset = stream->readUint32LE();
stream->read(_name, 20);
_fogColor.r = stream->readFloatLE();
@@ -23,8 +20,7 @@ int Fog::readCommon(Common::ReadStream* stream)
return offset;
}
-void Fog::readAnimationData(Common::ReadStream* stream, int size)
-{
+void Fog::readAnimationData(Common::ReadStream *stream, int size) {
_animatedParameters = stream->readUint32LE();
_animationData = new float[size / sizeof(float)];
stream->read(_animationData, size);
@@ -45,12 +41,10 @@ void Fog::readAnimationData(Common::ReadStream* stream, int size)
setupFrame(0);
}
-void Fog::reset()
-{
+void Fog::reset() {
}
-void Fog::setupFrame(int frame)
-{
+void Fog::setupFrame(int frame) {
int offset = frame % _framesCount;
_matrix._m[0][0] = (_animatedParameters & 0x1 ? _m11ptr[offset] : *_m11ptr);
_matrix._m[0][1] = (_animatedParameters & 0x2 ? _m12ptr[offset] : *_m12ptr);
@@ -67,24 +61,181 @@ void Fog::setupFrame(int frame)
_inverted = invertMatrix(_matrix);
}
-void FogCone::read(Common::ReadStream* stream, int framesCount)
-{
+void FogCone::read(Common::ReadStream *stream, int framesCount) {
_framesCount = framesCount;
int size = readCommon(stream);
_parameter1 = stream->readFloatLE();
readAnimationData(stream, size - 52);
}
-void FogSphere::read(Common::ReadStream* stream, int framesCount)
-{
+void FogCone::calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) {
+ *coeficient = 0.0f;
+
+ Vector3 positionT = this->_matrix * position;
+ Vector3 viewPositionT = this->_matrix * viewPosition;
+
+ Vector3 vectorT = (viewPositionT - positionT).normalize();
+
+ float v67 = - positionT.x * vectorT.x - positionT.y * vectorT.y - positionT.z * vectorT.z;
+ float v66 = - (positionT.z * positionT.z) - (positionT.y * positionT.y) - (positionT.x * positionT.x) + (v67 * v67) + (this->_parameter1 * this->_parameter1);
+
+ if (v66 >= 0.0f) {
+ float v24 = sqrt(v66);
+
+ Vector3 v29 = positionT + (v67 - v24) * vectorT;
+ Vector3 v36 = positionT + (v67 + v24) * vectorT;
+
+ Vector3 v39 = this->_inverted * v29;
+ Vector3 v42 = this->_inverted * v36;
+
+ float v74 = (v39 - position).length();
+ float v76 = (v42 - position).length();
+
+ Vector3 vector = viewPosition - position;
+
+ float vectorLength = vector.length();
+
+ if (v74 < 0.0f) {
+ v74 = 0.0f;
+ }
+ if (v76 > vectorLength) {
+ v76 = vectorLength;
+ }
+ if (v76 >= v74) {
+ *coeficient = v76 - v74;
+ }
+ }
+}
+
+void FogSphere::read(Common::ReadStream *stream, int framesCount) {
_framesCount = framesCount;
int size = readCommon(stream);
_parameter1 = stream->readFloatLE();
readAnimationData(stream, size - 52);
}
-void FogBox::read(Common::ReadStream* stream, int framesCount)
-{
+void FogSphere::calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) {
+ *coeficient = 0.0f;
+
+ Vector3 positionT = this->_matrix * position;
+ Vector3 viewPositionT = this->_matrix * viewPosition;
+
+ Vector3 v158 = Vector3::cross(positionT, viewPositionT);
+
+ if (v158.x != 0.0f || v158.y != 0.0f || v158.z != 0.0f) {
+ Vector3 v167 = v158.normalize();
+ if (v167.z < 0.0f) {
+ v167 = -1.0f * v167;
+ }
+
+ float v173 = sqrt(1.0f - v167.z * v167.z);
+ if (v173 > cos(this->_parameter1)) {
+ Vector3 v37 = Vector3(v167.y, -v167.x, 0.0f).normalize();
+
+ float v41 = 1.0f / v173 / v173 - 1.0f;
+ float v42 = sqrt(v41);
+ float v43 = tan(this->_parameter1);
+ float v44 = sqrt(v43 * v43 - v41);
+
+ Vector3 v45 = v44 * v37;
+
+ Vector3 v48 = Vector3(
+ -v37.y * v42,
+ v37.x * v42,
+ 0.0f * v42);
+
+ Vector3 v51 = v48 + Vector3(0.0f, 0.0f, -1.0f);
+
+ Vector3 v186 = v51 - v45;
+ Vector3 v183 = v51 + v45;
+
+ Vector3 vector = viewPositionT - positionT;
+
+ Vector3 v177 = -1.0f * positionT;
+ Vector3 v174 = Vector3::cross(v186, vector);
+
+ float v189, v191;
+ if (fabs(v174.x) <= fabs(v174.y)) {
+ if (fabs(v174.y) <= fabs(v174.z)) {
+ v191 = v177.x * v186.y - v177.y * v186.x;
+ v189 = v186.y * vector.x - v186.x * vector.y;
+ } else {
+ v191 = v177.z * v186.x - v186.z * v177.x;
+ v189 = v186.x * vector.z - v186.z * vector.x;
+ }
+ } else {
+ if (fabs(v174.x) <= fabs(v174.z)) {
+ v191 = v177.x * v186.y - v177.y * v186.x;
+ v189 = v186.y * vector.x - v186.x * vector.y;
+ } else {
+ v191 = v186.z * v177.y - v186.y * v177.z;
+ v189 = v186.z * vector.y - v186.y * vector.z;
+ }
+ }
+
+ float v88;
+ if (v189 == 0.0f) {
+ v88 = 0.0f;
+ } else {
+ v88 = v191 / v189;
+ }
+
+ Vector3 v196 = -1.0f * positionT;
+ Vector3 v193 = Vector3::cross(v183, vector);
+
+ float v190, v192;
+ if (fabs(v193.x) <= fabs(v193.y)) {
+ if (fabs(v193.y) <= fabs(v193.z)) {
+ v192 = v196.x * v183.y - v196.y * v183.x;
+ v190 = v183.y * vector.x - v183.x * vector.y;
+ } else {
+ v192 = v196.z * v183.x - v183.z * v196.x;
+ v190 = v183.x * vector.z - v183.z * vector.x;
+ }
+ } else {
+ if (fabs(v193.x) <= fabs(v193.z)) {
+ v192 = v196.x * v183.y - v196.y * v183.x;
+ v190 = v183.y * vector.x - v183.x * vector.y;
+ } else {
+ v192 = v183.z * v196.y - v183.y * v196.z;
+ v190 = v183.z * vector.y - v183.y * vector.z;
+ }
+ }
+
+ float v114;
+ if (v190 == 0.0f) {
+ v114 = 0.0f;
+ } else {
+ v114 = v192 / v190;
+ }
+
+ if (v114 < v88) {
+ float temp = v88;
+ v88 = v114;
+ v114 = temp;
+ }
+
+ if (v88 <= 1.0f && v114 >= 0.0f) {
+ if (v88 < 0.0f) {
+ v88 = 0.0;
+ }
+ if (v114 > 1.0f) {
+ v114 = 1.0;
+ }
+
+ Vector3 v139 = positionT + (v88 * vector);
+ Vector3 v142 = this->_inverted * v139;
+
+ Vector3 v148 = positionT + (v114 * vector);
+ Vector3 v151 = this->_inverted * v148;
+
+ *coeficient = (v151 - v142).length();
+ }
+ }
+ }
+}
+
+void FogBox::read(Common::ReadStream *stream, int framesCount) {
_framesCount = framesCount;
int size = readCommon(stream);
_parameter1 = stream->readFloatLE();
@@ -93,4 +244,105 @@ void FogBox::read(Common::ReadStream* stream, int framesCount)
readAnimationData(stream, size - 60);
}
+void FogBox::calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) {
+ Vector3 v159 = this->_matrix * position;
+ Vector3 v146 = v159;
+ Vector3 v156 = this->_matrix * viewPosition;
+ Vector3 v153 = v156;
+ Vector3 v150 = v156 - v159;
+
+ float v149 = this->_parameter1 * 0.5f;
+ if (v159.x < -v149) {
+ if (v156.x < -v149) {
+ return;
+ }
+ float v28 = (-v159.x - v149) / v150.x;
+ Vector3 v29 = v28 * v150;
+ v146 = v159 + v29;
+ } else {
+ if (v156.x < -v149) {
+ float v19 = (-v156.x - v149) / v150.x;
+ Vector3 v20 = v19 * v150;
+ v153 = v156 + v20;
+ }
+ }
+ if (v149 < v146.x) {
+ if (v149 < v153.x) {
+ return;
+ }
+ float v48 = (v149 - v146.x) / v150.x;
+ Vector3 v49 = v48 * v150;
+ v146 = v146 + v49;
+ } else {
+ if (v149 < v153.x) {
+ float v40 = (v149 - v153.x) / v150.x;
+ Vector3 v41 = v40 * v150;
+ v153 = v153 + v41;
+ }
+ }
+ float v162 = this->_parameter2 * 0.5f;
+ if (v146.y < -v162) {
+ if (v153.y < -v162) {
+ return;
+ }
+ float v71 = (-v146.y - v162) / v150.y;
+ Vector3 v72 = v71 * v150;
+ v146 = v146 + v72;
+ } else {
+ if (v153.y < -v162) {
+ float v62 = (-v153.y - v162) / v150.y;
+ Vector3 v63 = v62 * v150;
+ v153 = v153 + v63;
+ }
+ }
+ if (v162 < v146.y) {
+ if (v162 < v153.y) {
+ return;
+ }
+ float v91 = (v162 - v146.y) / v150.y;
+ Vector3 v92 = v91 * v150;
+ v146 = v146 + v92;
+ } else {
+ if (v162 < v153.y) {
+ float v83 = (v162 - v153.y) / v150.y;
+ Vector3 v84 = v83 * v150;
+ v153 = v153 + v84;
+ }
+ }
+
+ if (0.0f <= v146.z) {
+ if (0.0f > v153.z) {
+ float v103 = -v153.z / v150.z;
+ Vector3 v104 = v103 * v150;
+ v153 = v153 + v104;
+ }
+ } else {
+ if (0.0f > v153.z) {
+ return;
+ }
+ float v111 = -v146.z / v150.z;
+ Vector3 v112 = v111 * v150;
+ v146 = v146 + v112;
+ }
+
+ if (v146.z <= this->_parameter3) {
+ if (v153.z > this->_parameter3) {
+ float v124 = (this->_parameter3 - v153.z) / v150.z;
+ Vector3 v125 = v124 * v150;
+ v153 = v153 + v125;
+ }
+ } else {
+ if (v153.z <= this->_parameter3) {
+ float v132 = (this->_parameter3 - v146.z) / v150.z;
+ Vector3 v133 = v132 * v150;
+ v146 = v146 + v133;
+ }
+ }
+
+ Vector3 v137 = this->_inverted * v146;
+ Vector3 v140 = this->_inverted * v153;
+ Vector3 v143 = v140 - v137;
+
+ *coeficient = v143.length();
+}
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/fog.h b/engines/bladerunner/fog.h
index db291e3b62..992ede56ed 100644
--- a/engines/bladerunner/fog.h
+++ b/engines/bladerunner/fog.h
@@ -71,7 +71,7 @@ public:
virtual ~Fog();
virtual void read(Common::ReadStream *stream, int framesCount) = 0;
-
+ virtual void calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) = 0;
void reset();
void setupFrame(int frame);
@@ -85,16 +85,19 @@ protected:
class FogCone : public Fog
{
void read(Common::ReadStream *stream, int framesCount);
+ void calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient);
};
class FogSphere : public Fog
{
void read(Common::ReadStream *stream, int framesCount);
+ void calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient);
};
class FogBox : public Fog
{
void read(Common::ReadStream *stream, int framesCount);
+ void calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/light.cpp b/engines/bladerunner/light.cpp
index d1d79b870b..39dc3e3a27 100644
--- a/engines/bladerunner/light.cpp
+++ b/engines/bladerunner/light.cpp
@@ -1,17 +1,15 @@
#include "bladerunner/light.h"
+#include "common/util.h"
namespace BladeRunner {
-Light::Light()
-{
+Light::Light() {
}
-Light::~Light()
-{
+Light::~Light() {
}
-void Light::read(Common::ReadStream* stream, int framesCount, int frame, int animated)
-{
+void Light::read(Common::ReadStream *stream, int framesCount, int frame, int animated) {
_framesCount = framesCount;
_animated = animated;
@@ -48,8 +46,7 @@ void Light::read(Common::ReadStream* stream, int framesCount, int frame, int ani
setupFrame(frame);
}
-void Light::readVqa(Common::ReadStream* stream, int framesCount, int frame, int animated)
-{
+void Light::readVqa(Common::ReadStream *stream, int framesCount, int frame, int animated) {
_framesCount = framesCount;
_animated = animated;
@@ -83,8 +80,7 @@ void Light::readVqa(Common::ReadStream* stream, int framesCount, int frame, int
setupFrame(frame);
}
-void Light::setupFrame(int frame)
-{
+void Light::setupFrame(int frame) {
int offset = frame % _framesCount;
_matrix._m[0][0] = (_animatedParameters & 0x1 ? _m11ptr[offset] : *_m11ptr);
_matrix._m[0][1] = (_animatedParameters & 0x2 ? _m12ptr[offset] : *_m12ptr);
@@ -108,9 +104,185 @@ void Light::setupFrame(int frame)
}
-float Light::attenuation(float min, float max, float distance)
-{
- return 0.0;
+float Light::calculate(Vector3 start, Vector3 end) {
+ return calculateCoeficient(_matrix * start, _matrix * end, _field16, _field17);
+}
+
+void Light::calculateColor(Color *outColor, Vector3 position) {
+ Vector3 positionT = _matrix * position;
+ float att = attenuation(_field16, _field17, positionT.length());
+ outColor->r = _color.r * att;
+ outColor->g = _color.g * att;
+ outColor->b = _color.b * att;
+}
+
+float Light::calculateCoeficient(Vector3 start, Vector3 end, float a3, float a4) {
+ if (a4 == 0.0f) {
+ return 1.0e30f;
+ }
+
+ if (a3 >= start.length() && a3 >= end.length()) {
+ return 1.0e30f;
+ }
+
+ float v40 = (end - start).length();
+ float v31 = 0.0f;
+ if (v40 != 0.0f) {
+ Vector3 v27 = Vector3::cross(start, end);
+ v31 = v27.length() / v40;
+ }
+
+ if (v31 < a4) {
+ return 1.0f / (1.0f - (v31 / a4));
+ }
+ return 1.0e30f;
+}
+
+float Light::attenuation(float min, float max, float distance) {
+ if (max == 0.0f) {
+ return 1.0f;
+ }
+ if (min < max) {
+ distance = CLIP(distance, min, max);
+ float x = (max - distance) / (max - min);
+ return x * x * (3.0f - 2.0f * x);
+ }
+ if (min > distance) {
+ return 1.0f;
+ }
+ return 0.0f;
+}
+
+float Light1::calculate(Vector3 start, Vector3 end) {
+ start = _matrix * start;
+ end = _matrix * end;
+
+ float v40 = 0.0f;
+ if (_field17 != 0.0f) {
+ v40 = calculateCoeficient(start, end, _field16, _field17);
+ }
+
+ float v41 = atan2(start.length(), -start.z);
+ float v42 = atan2(end.length(), -end.z);
+
+ float v43;
+ if ((_field18 >= v41 && _field18 >= v42) || (_field19 <= v41 && _field19 <= v42)) {
+ v43 = 1.0e30f;
+ } else {
+ v43 = 2.0;
+ }
+ if (v43 < v40) {
+ return v40;
+ } else {
+ return v43;
+ }
+}
+
+void Light1::calculateColor(Color *outColor, Vector3 position) {
+ Vector3 positionT = _matrix * position;
+
+ outColor->r = 0.0f;
+ outColor->g = 0.0f;
+ outColor->b = 0.0f;
+
+ if (positionT.z < 0.0f) {
+ float v12 = attenuation(_field18, _field19, atan2(sqrt(positionT.x * positionT.x + positionT.y * positionT.y), -positionT.z));
+ float v13 = attenuation(_field16, _field17, positionT.length());
+
+ outColor->r = v12 * v13 * _color.r;
+ outColor->g = v12 * v13 * _color.g;
+ outColor->b = v12 * v13 * _color.b;
+ }
+}
+
+float Light2::calculate(Vector3 start, Vector3 end) {
+ start = _matrix * start;
+ end = _matrix * end;
+
+ float v54 = 0.0f;
+ if (_field17 != 0.0f) {
+ v54 = calculateCoeficient(start, end, _field16, _field17);
+ }
+
+ float v55 = atan2(fabs(start.x), -start.z);
+ float v58 = atan2(fabs(start.y), -start.z);
+ float v57 = atan2(fabs(end.x), -end.z);
+ float v56 = atan2(fabs(end.y), -end.z);
+
+ float v59;
+ if ((_field18 >= v55 && _field18 >= v57 && _field18 >= v58 && _field18 >= v56) || (_field19 <= v55 && _field19 <= v57 && _field19 <= v58 && _field19 <= v56)) {
+ v59 = 1.0e30f;
+ } else {
+ v59 = 2.0f;
+ }
+ if (v59 < v54) {
+ return v54;
+ } else {
+ return v59;
+ }
+}
+
+void Light2::calculateColor(Color *outColor, Vector3 position) {
+ Vector3 positionT = _matrix * position;
+
+ outColor->r = 0.0f;
+ outColor->g = 0.0f;
+ outColor->b = 0.0f;
+
+ if (positionT.z < 0.0f) {
+ float v11 = attenuation(_field18, _field19, atan2(fabs(positionT.y), -positionT.z));
+ float v12 = attenuation(_field18, _field19, atan2(fabs(positionT.x), -positionT.z));
+ float v13 = attenuation(_field16, _field17, positionT.length());
+
+ outColor->r = v11 * v12 * v13 * _color.r;
+ outColor->g = v11 * v12 * v13 * _color.g;
+ outColor->b = v11 * v12 * v13 * _color.b;
+ }
+}
+
+void Light3::calculateColor(Color *outColor, Vector3 position) {
+ Vector3 positionT = _matrix * position;
+
+ outColor->r = 0.0f;
+ outColor->g = 0.0f;
+ outColor->b = 0.0f;
+
+ if (positionT.z < 0.0f) {
+ float v12 = attenuation(_field18, _field19, sqrt(positionT.x * positionT.x + positionT.y * positionT.y));
+ float v13 = attenuation(_field16, _field17, positionT.length());
+
+ outColor->r = v12 * v13 * _color.r;
+ outColor->g = v12 * v13 * _color.g;
+ outColor->b = v12 * v13 * _color.b;
+ }
+}
+
+void Light4::calculateColor(Color *outColor, Vector3 position) {
+ Vector3 positionT = _matrix * position;
+
+ outColor->r = 0.0f;
+ outColor->g = 0.0f;
+ outColor->b = 0.0f;
+
+ if (positionT.z < 0.0f) {
+ float v11 = attenuation(_field18, _field19, fabs(positionT.y));
+ float v12 = attenuation(_field18, _field19, fabs(positionT.x));
+ float v13 = attenuation(_field16, _field17, positionT.length());
+
+ outColor->r = v11 * v12 * v13 * _color.r;
+ outColor->g = v11 * v12 * v13 * _color.g;
+ outColor->b = v11 * v12 * v13 * _color.b;
+ }
+}
+
+float Light5::calculate(Vector3 start, Vector3 end) {
+ return 1.0e30f;
+}
+
+void Light5::calculateColor(Color *outColor, Vector3 position) {
+ outColor->r = _color.r;
+ outColor->g = _color.g;
+ outColor->b = _color.b;
}
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/light.h b/engines/bladerunner/light.h
index a6ac21eb8b..9c2cdcb45c 100644
--- a/engines/bladerunner/light.h
+++ b/engines/bladerunner/light.h
@@ -42,7 +42,9 @@ class Light
friend class BladeRunnerEngine;
#endif
friend class Lights;
+ friend class SliceRenderer;
+protected:
char _name[20];
int _framesCount;
int _animated;
@@ -77,35 +79,42 @@ class Light
public:
Light();
- ~Light();
+ virtual ~Light();
void read(Common::ReadStream *stream, int framesCount, int frame, int animated);
void readVqa(Common::ReadStream *stream, int framesCount, int frame, int animated);
void setupFrame(int frame);
-private:
- static float attenuation(float min, float max, float distance);
+ virtual float calculate(Vector3 start, Vector3 end);
+ virtual void calculateColor(Color *outColor, Vector3 position);
+
+protected:
+ float calculateCoeficient(Vector3 start, Vector3 end, float a3, float a4);
+ float attenuation(float min, float max, float distance);
};
class Light1 : public Light {
-
+ float calculate(Vector3 start, Vector3 end);
+ void calculateColor(Color *outColor, Vector3 position);
};
class Light2 : public Light {
-
+ float calculate(Vector3 start, Vector3 end);
+ void calculateColor(Color *outColor, Vector3 position);
};
class Light3 : public Light {
-
+ void calculateColor(Color *outColor, Vector3 position);
};
class Light4 : public Light {
-
+ void calculateColor(Color *outColor, Vector3 position);
};
class Light5 : public Light {
-
+ float calculate(Vector3 start, Vector3 end);
+ void calculateColor(Color *outColor, Vector3 position);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/lights.cpp b/engines/bladerunner/lights.cpp
index eb18958020..0d6a1be175 100644
--- a/engines/bladerunner/lights.cpp
+++ b/engines/bladerunner/lights.cpp
@@ -2,8 +2,7 @@
namespace BladeRunner {
-Lights::Lights(BladeRunnerEngine *vm)
-{
+Lights::Lights(BladeRunnerEngine *vm) {
_vm = vm;
_ambientLightColor.r = 1.0;
@@ -11,28 +10,25 @@ Lights::Lights(BladeRunnerEngine *vm)
_ambientLightColor.b = 0.0;
_lights = nullptr;
+ _lightsCount = 0;
_frame = 0;
}
-Lights::~Lights()
-{
+Lights::~Lights() {
reset();
}
-void Lights::read(Common::ReadStream *stream, int framesCount)
-{
+void Lights::read(Common::ReadStream *stream, int framesCount) {
_ambientLightColor.r = stream->readFloatLE();
_ambientLightColor.g = stream->readFloatLE();
_ambientLightColor.b = stream->readFloatLE();
_lightsCount = stream->readUint32LE();
int i;
- for (i = 0; i < _lightsCount; i++)
- {
+ for (i = 0; i < _lightsCount; i++) {
Light *light;
int type = stream->readUint32LE();
- switch (type)
- {
+ switch (type) {
case 1:
light = new Light1();
break;
@@ -58,24 +54,18 @@ void Lights::read(Common::ReadStream *stream, int framesCount)
}
}
-void Lights::removeAnimated()
-{
+void Lights::removeAnimated() {
Light **nextLight;
- Light *light;
+ Light *light;
nextLight = &this->_lights;
light = this->_lights;
- if (light)
- {
- do
- {
- if (light->_animated)
- {
+ if (light) {
+ do {
+ if (light->_animated) {
*nextLight = light->_next;
delete light;
- }
- else
- {
+ } else {
nextLight = &light->_next;
}
light = *nextLight;
@@ -83,8 +73,7 @@ void Lights::removeAnimated()
}
}
-void Lights::readVqa(Common::ReadStream *stream)
-{
+void Lights::readVqa(Common::ReadStream *stream) {
removeAnimated();
if (stream->eos())
return;
@@ -93,26 +82,25 @@ void Lights::readVqa(Common::ReadStream *stream)
int count = stream->readUint32LE();
for (int i = 0; i < count; i++) {
int lightType = stream->readUint32LE();
- Light* light;
- switch(lightType)
- {
- case 5:
- light = new Light5();
- break;
- case 4:
- light = new Light4();
- break;
- case 3:
- light = new Light3();
- break;
- case 2:
- light = new Light2();
- break;
- case 1:
- light = new Light1();
- break;
- default:
- light = new Light();
+ Light *light;
+ switch (lightType) {
+ case 5:
+ light = new Light5();
+ break;
+ case 4:
+ light = new Light4();
+ break;
+ case 3:
+ light = new Light3();
+ break;
+ case 2:
+ light = new Light2();
+ break;
+ case 1:
+ light = new Light1();
+ break;
+ default:
+ light = new Light();
}
light->readVqa(stream, framesCount, _frame, 1);
light->_next = _lights;
@@ -120,8 +108,7 @@ void Lights::readVqa(Common::ReadStream *stream)
}
}
-void Lights::setupFrame(int frame)
-{
+void Lights::setupFrame(int frame) {
Light *light;
if (frame == _frame)
@@ -130,22 +117,19 @@ void Lights::setupFrame(int frame)
if (!_lights)
return;
- for (light = _lights; light; light = light->_next)
- {
+ for (light = _lights; light; light = light->_next) {
light->setupFrame(frame);
}
}
-void Lights::reset()
-{
+void Lights::reset() {
Light *light;
Light *nextLight;
if (!_lights)
return;
- do
- {
+ do {
light = _lights;
nextLight = light->_next;
delete light;
diff --git a/engines/bladerunner/lights.h b/engines/bladerunner/lights.h
index 37a7b17452..2ba95b9060 100644
--- a/engines/bladerunner/lights.h
+++ b/engines/bladerunner/lights.h
@@ -35,6 +35,8 @@ class Lights {
#if _DEBUG
friend class BladeRunnerEngine;
#endif
+ friend class SliceRenderer;
+
BladeRunnerEngine *_vm;
Color _ambientLightColor;
diff --git a/engines/bladerunner/set_effects.cpp b/engines/bladerunner/set_effects.cpp
index bc10a0fc2c..f4d2506292 100644
--- a/engines/bladerunner/set_effects.cpp
+++ b/engines/bladerunner/set_effects.cpp
@@ -2,7 +2,7 @@
namespace BladeRunner {
-SetEffects::SetEffects(BladeRunnerEngine* vm) {
+SetEffects::SetEffects(BladeRunnerEngine *vm) {
_vm = vm;
_distanceColor.r = 1.0f;
@@ -23,7 +23,7 @@ SetEffects::~SetEffects() {
reset();
}
-void SetEffects::read(Common::ReadStream* stream, int framesCount) {
+void SetEffects::read(Common::ReadStream *stream, int framesCount) {
_distanceCoeficient = stream->readFloatLE();
_distanceColor.r = stream->readFloatLE();
_distanceColor.g = stream->readFloatLE();
@@ -33,9 +33,8 @@ void SetEffects::read(Common::ReadStream* stream, int framesCount) {
int i;
for (i = 0; i < _fogsCount; i++) {
int type = stream->readUint32LE();
- Fog* fog = NULL;
- switch (type)
- {
+ Fog *fog = NULL;
+ switch (type) {
case 0:
fog = new FogCone();
break;
@@ -46,8 +45,7 @@ void SetEffects::read(Common::ReadStream* stream, int framesCount) {
fog = new FogBox();
break;
}
- if (!fog)
- {
+ if (!fog) {
//TODO exception, unknown fog type
}
fog->read(stream, framesCount);
@@ -57,7 +55,7 @@ void SetEffects::read(Common::ReadStream* stream, int framesCount) {
}
void SetEffects::reset() {
- Fog* fog, *nextFog;
+ Fog *fog, *nextFog;
if (!_fogs)
return;
@@ -84,8 +82,8 @@ void SetEffects::setFadeDensity(float density) {
_fadeDensity = density;
}
-void SetEffects::setFogColor(char* fogName, float r, float g, float b) {
- Fog* fog = findFog(fogName);
+void SetEffects::setFogColor(char *fogName, float r, float g, float b) {
+ Fog *fog = findFog(fogName);
if (fog == nullptr)
return;
@@ -94,19 +92,46 @@ void SetEffects::setFogColor(char* fogName, float r, float g, float b) {
fog->_fogColor.b = b;
}
-void SetEffects::setFogDensity(char* fogName, float density) {
- Fog* fog = findFog(fogName);
+void SetEffects::setFogDensity(char *fogName, float density) {
+ Fog *fog = findFog(fogName);
if (fog == nullptr)
return;
fog->_fogDensity = density;
}
-Fog* SetEffects::findFog(char* fogName) {
+void SetEffects::calculateColor(Vector3 viewPosition, Vector3 position, float *outCoeficient, Color *outColor) {
+ float distanceCoeficient = CLIP((position - viewPosition).length() * _distanceCoeficient, 0.0f, 1.0f);
+
+ *outCoeficient = 1.0f - distanceCoeficient;
+ outColor->r = _distanceColor.r * distanceCoeficient;
+ outColor->g = _distanceColor.g * distanceCoeficient;
+ outColor->b = _distanceColor.b * distanceCoeficient;
+
+ for (Fog *fog = this->_fogs; fog != nullptr; fog = fog->_next) {
+ float fogCoeficient = 0.0f;
+ fog->calculateCoeficient(position, viewPosition, &fogCoeficient);
+ if (fogCoeficient > 0.0f) {
+ fogCoeficient = CLIP(fog->_fogDensity * fogCoeficient, 0.0f, 1.0f);
+
+ *outCoeficient = *outCoeficient * (1.0f - fogCoeficient);
+ outColor->r = outColor->r * (1.0f - fogCoeficient) + fog->_fogColor.r * fogCoeficient;
+ outColor->g = outColor->g * (1.0f - fogCoeficient) + fog->_fogColor.g * fogCoeficient;
+ outColor->b = outColor->b * (1.0f - fogCoeficient) + fog->_fogColor.b * fogCoeficient;
+ }
+ }
+
+ *outCoeficient = *outCoeficient * (1.0f - this->_fadeDensity);
+ outColor->r = outColor->r * (1.0f - this->_fadeDensity) + this->_fadeColor.r * this->_fadeDensity;
+ outColor->g = outColor->g * (1.0f - this->_fadeDensity) + this->_fadeColor.g * this->_fadeDensity;
+ outColor->b = outColor->b * (1.0f - this->_fadeDensity) + this->_fadeColor.b * this->_fadeDensity;
+}
+
+Fog *SetEffects::findFog(char *fogName) {
if (!_fogs)
return nullptr;
- Fog* fog = _fogs;
+ Fog *fog = _fogs;
while (fog != nullptr) {
if (strcmp(fogName, fog->_name) == 0) {
diff --git a/engines/bladerunner/set_effects.h b/engines/bladerunner/set_effects.h
index 16317ed3e1..233009ded2 100644
--- a/engines/bladerunner/set_effects.h
+++ b/engines/bladerunner/set_effects.h
@@ -57,6 +57,8 @@ public:
void setFadeDensity(float density);
void setFogColor(char* fogName, float r, float g, float b);
void setFogDensity(char* fogName, float density);
+
+ void calculateColor(Vector3 viewPosition, Vector3 position, float *outCoeficient, Color *outColor);
private:
Fog* findFog(char* fogName);
diff --git a/engines/bladerunner/slice_animations.cpp b/engines/bladerunner/slice_animations.cpp
index aafd26885a..503193c2a6 100644
--- a/engines/bladerunner/slice_animations.cpp
+++ b/engines/bladerunner/slice_animations.cpp
@@ -51,11 +51,15 @@ bool SliceAnimations::open(const Common::String &name) {
uint8 color_g = file.readByte();
uint8 color_b = file.readByte();
+ _palettes[i].color[j].r = color_r;
+ _palettes[i].color[j].g = color_g;
+ _palettes[i].color[j].b = color_b;
+
uint16 rgb555 = ((uint16)color_r << 10) |
((uint16)color_g << 5) |
(uint16)color_b;
- _palettes[i][j] = rgb555;
+ _palettes[i].color555[j] = rgb555;
}
}
diff --git a/engines/bladerunner/slice_animations.h b/engines/bladerunner/slice_animations.h
index 1e35d6b90c..0abdfb1ce0 100644
--- a/engines/bladerunner/slice_animations.h
+++ b/engines/bladerunner/slice_animations.h
@@ -27,16 +27,20 @@
#include "common/file.h"
#include "common/str.h"
#include "common/types.h"
-#include "vector.h"
+
+#include "bladerunner/color.h"
+#include "bladerunner/vector.h"
+
namespace BladeRunner {
class BladeRunnerEngine;
struct SlicePalette {
- uint16 color[256];
+ uint16 color555[256];
+ Color256 color[256];
- uint16 &operator[](size_t i) { return color[i]; }
+// uint16 &operator[](size_t i) { return color555[i]; }
};
class SliceAnimations {
diff --git a/engines/bladerunner/slice_renderer.cpp b/engines/bladerunner/slice_renderer.cpp
index 6bce572064..8dad519feb 100644
--- a/engines/bladerunner/slice_renderer.cpp
+++ b/engines/bladerunner/slice_renderer.cpp
@@ -55,6 +55,7 @@ void dump(const char *str, Matrix4x3 m) {
SliceRenderer::SliceRenderer(BladeRunnerEngine* vm) {
_vm = vm;
+ _pixelFormat = createRGB555();
int i;
for (i = 0; i < 942; i++) { // yes, its going just to 942 and not 997
@@ -88,8 +89,8 @@ void SliceRenderer::setupFrame(int animation, int frame, Vector3 position, float
Common::MemoryReadStream stream((byte*)_sliceFramePtr, _vm->_sliceAnimations->_animations[_animation].frameSize);
- _frameFront.x = stream.readFloatLE();
- _frameFront.y = stream.readFloatLE();
+ _frameScale.x = stream.readFloatLE();
+ _frameScale.y = stream.readFloatLE();
_frameSliceHeight = stream.readFloatLE();
_framePos.x = stream.readFloatLE();
_framePos.y = stream.readFloatLE();
@@ -144,31 +145,33 @@ void SliceRenderer::calculateBoundingRect() {
Matrix3x2 m4(_view._viewportDistance / bottom.z, 0.0f, 0.0f,
0.0f, 25.5f, 0.0f);
- Matrix3x2 m2(_frameFront.x, 0.0f, _framePos.x,
- 0.0f, _frameFront.y, _framePos.y);
+ Matrix3x2 m2(_frameScale.x, 0.0f, _framePos.x,
+ 0.0f, _frameScale.y, _framePos.y);
_field_109E = m4 * (facingRotation * m2);
- Vector4 B6(_view._viewportHalfWidth + top.x / top.z * _view._viewportDistance,
+ Vector4 startScreenVector(
+ _view._viewportHalfWidth + top.x / top.z * _view._viewportDistance,
_view._viewportHalfHeight + top.y / top.z * _view._viewportDistance,
1.0f / top.z,
_frameSliceCount * (1.0f / top.z));
- Vector4 C2(_view._viewportHalfWidth + bottom.x / bottom.z * _view._viewportDistance,
+ Vector4 endScreenVector(
+ _view._viewportHalfWidth + bottom.x / bottom.z * _view._viewportDistance,
_view._viewportHalfHeight + bottom.y / bottom.z * _view._viewportDistance,
1.0f / bottom.z,
0.0f);
- _field_10B6.x = B6.x;
- _field_10B6.y = B6.y;
- _field_10B6.z = B6.z;
- _field_10C2.x = C2.x;
- _field_10C2.y = C2.y;
- _field_10C2.z = C2.z;
- _field_10CE = B6.w;
- _field_10D2 = C2.w;
+ _startScreenVector.x = startScreenVector.x;
+ _startScreenVector.y = startScreenVector.y;
+ _startScreenVector.z = startScreenVector.z;
+ _endScreenVector.x = endScreenVector.x;
+ _endScreenVector.y = endScreenVector.y;
+ _endScreenVector.z = endScreenVector.z;
+ _startSlice = startScreenVector.w;
+ _endSlice = endScreenVector.w;
- Vector4 delta = C2 - B6;
+ Vector4 delta = endScreenVector - startScreenVector;
if (delta.y == 0.0f)
return;
@@ -180,37 +183,37 @@ void SliceRenderer::calculateBoundingRect() {
float screenMinY = 0.0f;
float screenMaxY = 479.0f;
- if (B6.y < screenMinY) {
- if (C2.y < screenMinY)
+ if (startScreenVector.y < screenMinY) {
+ if (endScreenVector.y < screenMinY)
return;
- float f = (screenMinY - B6.y) / delta.y;
- B6 = B6 + f * delta;
- } else if (B6.y > screenMaxY) {
- if (C2.y >= screenMaxY)
+ float f = (screenMinY - startScreenVector.y) / delta.y;
+ startScreenVector = startScreenVector + f * delta;
+ } else if (startScreenVector.y > screenMaxY) {
+ if (endScreenVector.y >= screenMaxY)
return;
- float f = (screenMaxY - B6.y) / delta.y;
- B6 = B6 + f * delta;
+ float f = (screenMaxY - startScreenVector.y) / delta.y;
+ startScreenVector = startScreenVector + f * delta;
}
- if (C2.y < screenMinY) {
- float f = (screenMinY - C2.y) / delta.y;
- C2 = C2 + f * delta;
- } else if (C2.y > screenMaxY) {
- float f = (screenMaxY - C2.y) / delta.y;
- C2 = C2 + f * delta;
+ if (endScreenVector.y < screenMinY) {
+ float f = (screenMinY - endScreenVector.y) / delta.y;
+ endScreenVector = endScreenVector + f * delta;
+ } else if (endScreenVector.y > screenMaxY) {
+ float f = (screenMaxY - endScreenVector.y) / delta.y;
+ endScreenVector = endScreenVector + f * delta;
}
- int bbox_min_y = (int)MIN(B6.y, C2.y);
- int bbox_max_y = (int)MAX(B6.y, C2.y) + 1;
+ int bbox_min_y = (int)MIN(startScreenVector.y, endScreenVector.y);
+ int bbox_max_y = (int)MAX(startScreenVector.y, endScreenVector.y) + 1;
/*
* Calculate min and max X
*/
- Matrix3x2 mB6 = _field_109E + Vector2(B6.x, 25.5f / B6.z);
- Matrix3x2 mC2 = _field_109E + Vector2(C2.x, 25.5f / C2.z);
+ Matrix3x2 mB6 = _field_109E + Vector2(startScreenVector.x, 25.5f / startScreenVector.z);
+ Matrix3x2 mC2 = _field_109E + Vector2(endScreenVector.x, 25.5f / endScreenVector.z);
float min_x = 640.0f;
float max_x = 0.0f;
@@ -234,14 +237,14 @@ void SliceRenderer::calculateBoundingRect() {
int bbox_min_x = MIN(MAX((int)min_x, 0), 640);
int bbox_max_x = MIN(MAX((int)max_x + 1, 0), 640);
- _field_10B6.x = B6.x;
- _field_10B6.y = B6.y;
- _field_10B6.z = B6.z;
- _field_10C2.x = C2.x;
- _field_10C2.y = C2.y;
- _field_10C2.z = C2.z;
- _field_10CE = B6.w;
- _field_10D2 = C2.w;
+ _startScreenVector.x = startScreenVector.x;
+ _startScreenVector.y = startScreenVector.y;
+ _startScreenVector.z = startScreenVector.z;
+ _endScreenVector.x = endScreenVector.x;
+ _endScreenVector.y = endScreenVector.y;
+ _endScreenVector.z = endScreenVector.z;
+ _startSlice = startScreenVector.w;
+ _endSlice = endScreenVector.w;
_minX = bbox_min_x;
_minY = bbox_min_y;
@@ -250,72 +253,74 @@ void SliceRenderer::calculateBoundingRect() {
}
struct SliceLineIterator {
- int _field_00[2][3];
- int _field_18;
- int _field_1C;
-
- float _field_20;
- float _field_24;
- float _field_28;
- float _field_2C;
- float _field_30;
- float _field_34;
+ int _sliceMatrix[2][3];
+ int _startY;
+ int _endY;
+
+ float _currentZ;
+ float _stepZ;
+ float _currentSlice;
+ float _stepSlice;
+ float _currentX;
+ float _stepX;
int _field_38;
- int _field_3C;
+ int _currentY;
- void setup(float arg_1, float arg_2, float arg_3,
- float arg_4, float arg_5, float arg_6,
- float arg_7, float arg_8,
- Matrix3x2 arg_9);
+ void setup(float endScreenX, float endScreenY, float endScreenZ,
+ float startScreenX, float startScreenY, float startScreenZ,
+ float endSlice, float startSlice,
+ Matrix3x2 m);
float line();
void advance();
};
void SliceLineIterator::setup(
- float arg_1, float arg_2, float arg_3,
- float arg_4, float arg_5, float arg_6,
- float arg_7, float arg_8,
- Matrix3x2 arg_9)
+ float endScreenX, float endScreenY, float endScreenZ,
+ float startScreenX, float startScreenY, float startScreenZ,
+ float endSlice, float startSlice,
+ Matrix3x2 m)
{
- _field_18 = (int)arg_5;
- _field_1C = (int)arg_2;
+ _startY = (int)startScreenY;
+ _endY = (int)endScreenY;
- float var_3 = arg_2 - arg_5;
+ float size = endScreenY - startScreenY;
- if (var_3 <= 0.0f || arg_6 <= 0.0f)
- _field_3C = _field_1C + 1;
+ if (size <= 0.0f || startScreenZ <= 0.0f)
+ _currentY = _endY + 1;
- _field_20 = arg_6;
- _field_24 = (arg_3 - arg_6) / var_3;
- _field_2C = (arg_7 - arg_8) / var_3;
- _field_28 = arg_8 - (arg_5 - floor(arg_5) - 1.0f) * _field_2C;
+ _currentZ = startScreenZ;
+ _stepZ = (endScreenZ - startScreenZ) / size;
- _field_30 = arg_4;
- _field_34 = (arg_1 - arg_4) / var_3;
- _field_38 = (int)((25.5f / var_3) * (1.0f / arg_3 - 1.0f / arg_6) * 64.0);
- _field_3C = _field_18;
+ _stepSlice = (endSlice - startSlice) / size;
+ _currentSlice = startSlice - (startScreenY - floor(startScreenY) - 1.0f) * _stepSlice;
- float var_54 = _field_30;
- float var_55 = 25.5f / _field_20;
+ _currentX = startScreenX;
+ _stepX = (endScreenX - startScreenX) / size;
- Matrix3x2 translate_matrix = Matrix3x2(1.0f, 0.0f, var_54,
- 0.0f, 1.0f, var_55);
+ _field_38 = (int)((25.5f / size) * (1.0f / endScreenZ - 1.0f / startScreenZ) * 64.0);
+ _currentY = _startY;
+
+ float offsetX = _currentX;
+ float offsetZ = 25.5f / _currentZ;
+
+ Matrix3x2 translate_matrix = Matrix3x2(1.0f, 0.0f, offsetX,
+ 0.0f, 1.0f, offsetZ);
Matrix3x2 scale_matrix = Matrix3x2(65536.0f, 0.0f, 0.0f,
0.0f, 64.0f, 0.0f);
- arg_9 = scale_matrix * (translate_matrix * arg_9);
+ m = scale_matrix * (translate_matrix * m);
for (int r = 0; r != 2; ++r)
for (int c = 0; c != 3; ++c)
- _field_00[r][c] = arg_9(r, c);
+ _sliceMatrix[r][c] = m(r, c);
}
float SliceLineIterator::line() {
float var_0 = 0.0f;
- if (_field_20 != 0.0f)
- var_0 = _field_28 / _field_20;
+ if (_currentZ != 0.0f)
+ var_0 = _currentSlice / _currentZ;
if (var_0 < 0.0)
var_0 = 0.0f;
@@ -324,12 +329,12 @@ float SliceLineIterator::line() {
}
void SliceLineIterator::advance() {
- _field_20 += _field_24;
- _field_28 += _field_2C;
- _field_30 += _field_34;
- _field_3C += 1;
- _field_00[0][2] += (int)(65536.0f * _field_34);
- _field_00[1][2] += _field_38;
+ _currentZ += _stepZ;
+ _currentSlice += _stepSlice;
+ _currentX += _stepX;
+ _currentY += 1;
+ _sliceMatrix[0][2] += (int)(65536.0f * _stepX);
+ _sliceMatrix[1][2] += _field_38;
}
static
@@ -341,38 +346,87 @@ void setupLookupTable(int t[256], int inc) {
}
}
-void SliceRenderer::drawFrame(Graphics::Surface &surface, uint16 *zbuffer) {
+void SliceRenderer::drawFrame(int animationId, int animationFrame, Vector3 position, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer) {
assert(_sliceFramePtr);
assert(_lights);
assert(_setEffects);
//assert(_view);
+ _vm->_sliceRenderer->setupFrame(animationId, animationFrame, position, facing);
+
SliceLineIterator sliceLineIterator;
sliceLineIterator.setup(
- _field_10C2.x, _field_10C2.y, _field_10C2.z,
- _field_10B6.x, _field_10B6.y, _field_10B6.z,
- _field_10D2, _field_10CE, // 2 floats
+ _endScreenVector.x, _endScreenVector.y, _endScreenVector.z,
+ _startScreenVector.x, _startScreenVector.y, _startScreenVector.z,
+ _endSlice, _startSlice,
_field_109E // 3x2 matrix
- );
+ );
+
+ SliceRendererLights sliceRendererLights = SliceRendererLights(_lights);
_lights->setupFrame(_view._frame);
_setEffects->setupFrame(_view._frame);
- setupLookupTable(_t1, sliceLineIterator._field_00[0][0]);
- setupLookupTable(_t2, sliceLineIterator._field_00[0][1]);
- setupLookupTable(_t4, sliceLineIterator._field_00[1][0]);
- setupLookupTable(_t5, sliceLineIterator._field_00[1][1]);
+ float sliceLine = sliceLineIterator.line();
+
+ sliceRendererLights.calculateColorBase(
+ Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight),
+ Vector3(_position.x, _position.y, _position.z + _frameBottomZ),
+ sliceLineIterator._endY - sliceLineIterator._startY);
+
+ float setEffectsColorCoeficient;
+ Color setEffectColor;
+ _setEffects->calculateColor(
+ _view._cameraPosition,
+ Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight),
+ &setEffectsColorCoeficient,
+ &setEffectColor);
+
+ _lightsColor.r = setEffectsColorCoeficient * sliceRendererLights._finalColor.r * 65536.0f;
+ _lightsColor.g = setEffectsColorCoeficient * sliceRendererLights._finalColor.g * 65536.0f;
+ _lightsColor.b = setEffectsColorCoeficient * sliceRendererLights._finalColor.b * 65536.0f;
+
+ _setEffectColor.r = setEffectColor.r * 31.0f * 65536.0f;
+ _setEffectColor.g = setEffectColor.g * 31.0f * 65536.0f;
+ _setEffectColor.b = setEffectColor.b * 31.0f * 65536.0f;
+
+ setupLookupTable(_m11lookup, sliceLineIterator._sliceMatrix[0][0]);
+ setupLookupTable(_m12lookup, sliceLineIterator._sliceMatrix[0][1]);
+ setupLookupTable(_m21lookup, sliceLineIterator._sliceMatrix[1][0]);
+ setupLookupTable(_m22lookup, sliceLineIterator._sliceMatrix[1][1]);
+
+ if(_animationsShadowEnabled[_animation]) {
+ //TODO: draw shadows
+ }
- int frameY = sliceLineIterator._field_18;
+ int frameY = sliceLineIterator._startY;
uint16 *frameLinePtr = (uint16*)surface.getPixels() + 640 * frameY;
uint16 *zBufferLinePtr = zbuffer + 640 * frameY;
- while (sliceLineIterator._field_3C <= sliceLineIterator._field_1C) {
- _c3 = sliceLineIterator._field_00[0][2];
- _c6 = sliceLineIterator._field_00[1][2];
+ while (sliceLineIterator._currentY <= sliceLineIterator._endY) {
+ _m13 = sliceLineIterator._sliceMatrix[0][2];
+ _m23 = sliceLineIterator._sliceMatrix[1][2];
+
+ sliceLine = sliceLineIterator.line();
+
+ sliceRendererLights.calculateColorSlice(Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight));
+
+ if (sliceLineIterator._currentY & 1) {
+ _setEffects->calculateColor(
+ _view._cameraPosition,
+ Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight),
+ &setEffectsColorCoeficient,
+ &setEffectColor);
+ }
- float sliceLine = sliceLineIterator.line();
+ _lightsColor.r = setEffectsColorCoeficient * sliceRendererLights._finalColor.r * 65536.0f;
+ _lightsColor.g = setEffectsColorCoeficient * sliceRendererLights._finalColor.g * 65536.0f;
+ _lightsColor.b = setEffectsColorCoeficient * sliceRendererLights._finalColor.b * 65536.0f;
+
+ _setEffectColor.r = setEffectColor.r * 31.0f * 65536.0f;
+ _setEffectColor.g = setEffectColor.g * 31.0f * 65536.0f;
+ _setEffectColor.b = setEffectColor.b * 31.0f * 65536.0f;
if (frameY >= 0 && frameY < 480)
drawSlice((int)sliceLine, frameLinePtr, zBufferLinePtr);
@@ -406,21 +460,30 @@ void SliceRenderer::drawSlice(int slice, uint16 *frameLinePtr, uint16 *zbufLineP
continue;
uint32 lastVertex = vertexCount - 1;
- int lastVertexX = MAX((_t1[p[3*lastVertex]] + _t2[p[3*lastVertex+1]] + _c3) >> 16, 0);
+ int lastVertexX = MAX((_m11lookup[p[3*lastVertex]] + _m12lookup[p[3*lastVertex+1]] + _m13) >> 16, 0);
int previousVertexX = lastVertexX;
while (vertexCount--) {
- int vertexX = CLIP((_t1[p[0]] + _t2[p[1]] + _c3) >> 16, 0, 640);
+ int vertexX = CLIP((_m11lookup[p[0]] + _m12lookup[p[1]] + _m13) >> 16, 0, 640);
if (vertexX > previousVertexX) {
- int vertexZ = (_t4[p[0]] + _t5[p[1]] + _c6) >> 6;
+ int vertexZ = (_m21lookup[p[0]] + _m22lookup[p[1]] + _m23) >> 6;
if (vertexZ >= 0 && vertexZ < 65536) {
+ Color256 color = palette.color[p[2]];
+
+ float hackMul = 8.0f; //not part of game
+
+ color.r = (int)(_setEffectColor.r + hackMul * _lightsColor.r * color.r) >> 13; // >> 16,
+ color.g = (int)(_setEffectColor.g + hackMul * _lightsColor.g * color.g) >> 13;
+ color.b = (int)(_setEffectColor.b + hackMul * _lightsColor.b * color.b) >> 13;
+
+ int color555 = _pixelFormat.RGBToColor(color.r/* * 8*/, color.g/* * 8*/, color.b/* * 8*/);
+
for (int x = previousVertexX; x != vertexX; ++x) {
- // debug("\t%04x < %04x", vertexZ, zbufLinePtr[x]);
if (vertexZ < zbufLinePtr[x]) {
- frameLinePtr[x] = palette[p[2]];
+ frameLinePtr[x] = color555;
zbufLinePtr[x] = (uint16)vertexZ;
}
}
@@ -446,4 +509,102 @@ void SliceRenderer::disableShadows(int animationsIdsList[], int listSize) {
}
}
+SliceRenderer::SliceRendererLights::SliceRendererLights(Lights *lights) {
+ _finalColor.r = 0.0f;
+ _finalColor.g = 0.0f;
+ _finalColor.b = 0.0f;
+
+ _lights = lights;
+
+ for(int i = 0; i < 20; i++) {
+ _colors[i].r = 0.0f;
+ _colors[i].g = 0.0f;
+ _colors[i].b = 0.0f;
+ }
+}
+
+
+void SliceRenderer::SliceRendererLights::calculateColorBase(Vector3 position1, Vector3 position2, float height) {
+ _finalColor.r = 0.0f;
+ _finalColor.g = 0.0f;
+ _finalColor.b = 0.0f;
+ _hmm3 = 0;
+ if (_lights) {
+ Light *light = _lights->_lights;
+ int i = 0;
+ if (light) {
+ do {
+ if (i < 20) {
+ float v8 = light->calculate(position1, position2/*, height*/);
+
+ this->_hmm2[i] = v8;
+ this->_hmm[i] = v8;
+
+ Color v22;
+ light->calculateColor(&v22, position1);
+ _colors[i] = v22;
+ _finalColor.r += v22.r;
+ _finalColor.g += v22.g;
+ _finalColor.b += v22.b;
+ }
+ else
+ {
+ Color v23;
+ light->calculateColor(&v23, position1);
+ _finalColor.r += v23.r;
+ _finalColor.g += v23.g;
+ _finalColor.b += v23.b;
+ }
+ light = light->_next;
+ i++;
+ } while (light);
+ }
+
+ _finalColor.r += _lights->_ambientLightColor.r;
+ _finalColor.g += _lights->_ambientLightColor.g;
+ _finalColor.b += _lights->_ambientLightColor.b;
+ }
+}
+
+void SliceRenderer::SliceRendererLights::calculateColorSlice(Vector3 position) {
+ _finalColor.r = 0.0f;
+ _finalColor.g = 0.0f;
+ _finalColor.b = 0.0f;
+
+ if (_lights) {
+ Light *light = _lights->_lights;
+ int i = 0;
+ if (light) {
+ do {
+ if (i < 20) {
+ _hmm[i] = _hmm[i] - 1.0f;
+
+ if (_hmm[i] <= 0.0f) {
+ do {
+ _hmm[i] = _hmm[i] + _hmm2[i];
+ } while (_hmm[i] <= 0.0f);
+ light->calculateColor(&_colors[i], position);
+ _hmm3++;
+ }
+ _finalColor.r += _colors[i].r;
+ _finalColor.g += _colors[i].g;
+ _finalColor.b += _colors[i].b;
+ } else {
+ Color color;
+ light->calculateColor(&color, position);
+ _hmm3++;
+ _finalColor.r += color.r;
+ _finalColor.g += color.g;
+ _finalColor.b += color.b;
+ }
+ light = light->_next;
+ i++;
+ } while (light);
+ }
+ _finalColor.r += _lights->_ambientLightColor.r;
+ _finalColor.g += _lights->_ambientLightColor.g;
+ _finalColor.b += _lights->_ambientLightColor.b;
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/slice_renderer.h b/engines/bladerunner/slice_renderer.h
index 3dcd92271e..9cbd3cec01 100644
--- a/engines/bladerunner/slice_renderer.h
+++ b/engines/bladerunner/slice_renderer.h
@@ -23,6 +23,7 @@
#ifndef BLADERUNNER_SLICE_RENDERER_H
#define BLADERUNNER_SLICE_RENDERER_H
+#include "bladerunner/color.h"
#include "bladerunner/vector.h"
#include "bladerunner/view.h"
#include "bladerunner/matrix.h"
@@ -55,7 +56,7 @@ class SliceRenderer {
void *_sliceFramePtr;
// Animation frame data
- Vector2 _frameFront;
+ Vector2 _frameScale;
float _frameBottomZ;
Vector2 _framePos;
float _frameSliceHeight;
@@ -63,24 +64,29 @@ class SliceRenderer {
uint32 _frameSliceCount;
Matrix3x2 _field_109E;
- Vector3 _field_10B6;
- Vector3 _field_10C2;
- float _field_10CE;
- float _field_10D2;
+ Vector3 _startScreenVector;
+ Vector3 _endScreenVector;
+ float _startSlice;
+ float _endSlice;
int _minX;
int _maxX;
int _minY;
int _maxY;
- int _t1[256];
- int _t2[256];
- int _c3;
- int _t4[256];
- int _t5[256];
- int _c6;
+ int _m11lookup[256];
+ int _m12lookup[256];
+ int _m13;
+ int _m21lookup[256];
+ int _m22lookup[256];
+ int _m23;
bool _animationsShadowEnabled[997];
+ Color _setEffectColor;
+ Color _lightsColor;
+
+ Graphics::PixelFormat _pixelFormat;
+
Matrix3x2 calculateFacingRotationMatrix();
void drawSlice(int slice, uint16 *frameLinePtr, uint16 *zbufLinePtr);
@@ -95,11 +101,29 @@ public:
void setupFrame(int animation, int frame, Vector3 position, float facing, float scale = 1.0f);
void calculateBoundingRect();
- void drawFrame(Graphics::Surface &surface, uint16 *zbuffer);
+ //void drawFrame(Graphics::Surface &surface, uint16 *zbuffer);
+ void drawFrame(int animationId, int animationFrame, Vector3 position, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer);
void preload(int animationId);
- void disableShadows(int* animationsIdsList, int listSize);
+ void disableShadows(int *animationsIdsList, int listSize);
+
+private:
+ class SliceRendererLights {
+ Lights *_lights;
+ Color _colors[20];
+ float _hmm[20];
+ float _hmm2[20];
+ int _hmm3;
+ public:
+ Color _finalColor;
+
+ public:
+ SliceRendererLights(Lights *lights);
+
+ void calculateColorBase(Vector3 position1, Vector3 position2, float height);
+ void calculateColorSlice(Vector3 position);
+ };
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/vector.h b/engines/bladerunner/vector.h
index 4f4bfed778..80fd5f8e14 100644
--- a/engines/bladerunner/vector.h
+++ b/engines/bladerunner/vector.h
@@ -58,6 +58,20 @@ public:
{}
float length() { return sqrtf(x * x + y * y + z * z); }
+ Vector3 normalize() {
+ float len = length();
+ if (len == 0) {
+ return Vector3(0.0f, 0.0f, 0.0f);
+ }
+ return Vector3(x / len, y / len, z / len);
+ }
+
+ static Vector3 cross(Vector3 a, Vector3 b) {
+ return Vector3(
+ a.y * b.z - a.z * b.y,
+ a.z * b.x - a.x * b.z,
+ a.x * b.y - a.y * b.x);
+ }
};
inline
diff --git a/engines/bladerunner/view.cpp b/engines/bladerunner/view.cpp
index f8acb91400..9356f046dd 100644
--- a/engines/bladerunner/view.cpp
+++ b/engines/bladerunner/view.cpp
@@ -60,9 +60,9 @@ void View::calculateSliceViewMatrix() {
m = m * rotationMatrixX(float(M_PI) / 2.0f);
- Matrix4x3 a(-1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, -1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f);
+ Matrix4x3 a(-1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f);
m = a * m;