mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-01 15:09:47 +00:00
669e6be438
Fixes a couple of issues reported by valgrind and clang sanitizers. In particular, the initialization of Actor::_inCombat means that McCoy no longer randomly has his gun out at the beginning of the game. In SliceRenderer::drawInWorld, the assert of _sliceFramePtr has been moved to after the call to setupFrameInWorld which is the method that initializes the field. This misplaced assert caused the game to crash for several people.
650 lines
19 KiB
C++
650 lines
19 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#include "bladerunner/slice_renderer.h"
|
|
|
|
#include "bladerunner/bladerunner.h"
|
|
#include "bladerunner/lights.h"
|
|
#include "bladerunner/set_effects.h"
|
|
#include "bladerunner/slice_animations.h"
|
|
|
|
#include "common/memstream.h"
|
|
#include "common/rect.h"
|
|
#include "common/util.h"
|
|
|
|
namespace BladeRunner {
|
|
|
|
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
|
|
_animationsShadowEnabled[i] = true;
|
|
}
|
|
}
|
|
|
|
SliceRenderer::~SliceRenderer() {
|
|
}
|
|
|
|
void SliceRenderer::setView(const View &view) {
|
|
_view = view;
|
|
}
|
|
|
|
void SliceRenderer::setLights(Lights *lights) {
|
|
_lights = lights;
|
|
}
|
|
|
|
void SliceRenderer::setSetEffects(SetEffects *setEffects) {
|
|
_setEffects = setEffects;
|
|
}
|
|
|
|
void SliceRenderer::setupFrameInWorld(int animationId, int animationFrame, Vector3 position, float facing, float scale) {
|
|
_position = position;
|
|
_facing = facing;
|
|
_scale = scale;
|
|
|
|
loadFrame(animationId, animationFrame);
|
|
|
|
calculateBoundingRect();
|
|
}
|
|
|
|
void SliceRenderer::getScreenRectangle(Common::Rect *screenRectangle, int animationId, int animationFrame, Vector3 position, float facing, float scale) {
|
|
assert(screenRectangle);
|
|
setupFrameInWorld(animationId, animationFrame, position, facing, scale);
|
|
*screenRectangle = _screenRectangle;
|
|
}
|
|
|
|
Matrix3x2 SliceRenderer::calculateFacingRotationMatrix() {
|
|
assert(_sliceFramePtr);
|
|
|
|
Matrix4x3 viewMatrix = _view._sliceViewMatrix;
|
|
Vector3 viewPos = viewMatrix * _position;
|
|
float dir = atan2f(viewPos.x, viewPos.z) + _facing;
|
|
float s = sinf(dir);
|
|
float c = cosf(dir);
|
|
|
|
Matrix3x2 rotation( 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);
|
|
|
|
return viewRotation * rotation;
|
|
}
|
|
|
|
void SliceRenderer::calculateBoundingRect() {
|
|
assert(_sliceFramePtr);
|
|
|
|
_screenRectangle.left = 0;
|
|
_screenRectangle.right = 0;
|
|
_screenRectangle.top = 0;
|
|
_screenRectangle.bottom = 0;
|
|
|
|
Matrix4x3 viewMatrix = _view._sliceViewMatrix;
|
|
|
|
Vector3 frameBottom = Vector3(0.0f, 0.0f, _frameBottomZ);
|
|
Vector3 frameTop = Vector3(0.0f, 0.0f, _frameBottomZ + _frameSliceCount * _frameSliceHeight);
|
|
|
|
Vector3 bottom = viewMatrix * (_position + frameBottom);
|
|
Vector3 top = viewMatrix * (_position + frameTop);
|
|
|
|
top = bottom + _scale * (top - bottom);
|
|
|
|
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 m_frame(_frameScale.x, 0.0f, _framePos.x,
|
|
0.0f, _frameScale.y, _framePos.y);
|
|
|
|
_modelMatrix = m_projection * (facingRotation * m_frame);
|
|
|
|
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 endScreenVector(
|
|
_view._viewportHalfWidth + bottom.x / bottom.z * _view._viewportDistance,
|
|
_view._viewportHalfHeight + bottom.y / bottom.z * _view._viewportDistance,
|
|
1.0f / bottom.z,
|
|
0.0f);
|
|
|
|
_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 = endScreenVector - startScreenVector;
|
|
|
|
if (delta.y == 0.0f) {
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Calculate min and max Y
|
|
*/
|
|
|
|
float screenMinY = 0.0f;
|
|
float screenMaxY = 479.0f;
|
|
|
|
if (startScreenVector.y < screenMinY) {
|
|
if (endScreenVector.y < screenMinY)
|
|
return;
|
|
|
|
float f = (screenMinY - startScreenVector.y) / delta.y;
|
|
startScreenVector = startScreenVector + f * delta;
|
|
} else if (startScreenVector.y > screenMaxY) {
|
|
if (endScreenVector.y >= screenMaxY)
|
|
return;
|
|
|
|
float f = (screenMaxY - startScreenVector.y) / delta.y;
|
|
startScreenVector = startScreenVector + 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(startScreenVector.y, endScreenVector.y);
|
|
int bbox_max_y = (int)MAX(startScreenVector.y, endScreenVector.y) + 1;
|
|
|
|
/*
|
|
* Calculate min and max X
|
|
*/
|
|
|
|
Matrix3x2 mB6 = _modelMatrix + Vector2(startScreenVector.x, 25.5f / startScreenVector.z);
|
|
Matrix3x2 mC2 = _modelMatrix + Vector2(endScreenVector.x, 25.5f / endScreenVector.z);
|
|
|
|
float min_x = 640.0f;
|
|
float max_x = 0.0f;
|
|
|
|
for (float i = 0.0f; i <= 256.0f; i += 255.0f) {
|
|
for (float j = 0.0f; j <= 256.0f; j += 255.0f) {
|
|
Vector2 v1 = mB6 * Vector2(i, j);
|
|
|
|
min_x = MIN(min_x, v1.x);
|
|
max_x = MAX(max_x, v1.x);
|
|
|
|
Vector2 v2 = mC2 * Vector2(i, j);
|
|
|
|
min_x = MIN(min_x, v2.x);
|
|
max_x = MAX(max_x, v2.x);
|
|
}
|
|
}
|
|
|
|
int bbox_min_x = CLIP((int)min_x, 0, 640);
|
|
int bbox_max_x = CLIP((int)max_x + 1, 0, 640);
|
|
|
|
_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;
|
|
|
|
_screenRectangle.left = bbox_min_x;
|
|
_screenRectangle.right = bbox_max_x;
|
|
_screenRectangle.top = bbox_min_y;
|
|
_screenRectangle.bottom = bbox_max_y;
|
|
}
|
|
|
|
void SliceRenderer::loadFrame(int animation, int frame) {
|
|
_animation = animation;
|
|
_frame = frame;
|
|
_sliceFramePtr = _vm->_sliceAnimations->getFramePtr(_animation, _frame);
|
|
|
|
Common::MemoryReadStream stream((byte*)_sliceFramePtr, _vm->_sliceAnimations->_animations[_animation].frameSize);
|
|
|
|
_frameScale.x = stream.readFloatLE();
|
|
_frameScale.y = stream.readFloatLE();
|
|
_frameSliceHeight = stream.readFloatLE();
|
|
_framePos.x = stream.readFloatLE();
|
|
_framePos.y = stream.readFloatLE();
|
|
_frameBottomZ = stream.readFloatLE();
|
|
_framePaletteIndex = stream.readUint32LE();
|
|
_frameSliceCount = stream.readUint32LE();
|
|
}
|
|
|
|
struct SliceLineIterator {
|
|
int _sliceMatrix[2][3];
|
|
int _startY;
|
|
int _endY;
|
|
|
|
float _currentZ;
|
|
float _stepZ;
|
|
float _currentSlice;
|
|
float _stepSlice;
|
|
float _currentX;
|
|
float _stepX;
|
|
int _field_38;
|
|
int _currentY;
|
|
|
|
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 endScreenX, float endScreenY, float endScreenZ,
|
|
float startScreenX, float startScreenY, float startScreenZ,
|
|
float endSlice, float startSlice,
|
|
Matrix3x2 m) {
|
|
_startY = (int)startScreenY;
|
|
_endY = (int)endScreenY;
|
|
|
|
float size = endScreenY - startScreenY;
|
|
|
|
if (size <= 0.0f || startScreenZ <= 0.0f)
|
|
_currentY = _endY + 1;
|
|
|
|
_currentZ = startScreenZ;
|
|
_stepZ = (endScreenZ - startScreenZ) / size;
|
|
|
|
_stepSlice = (endSlice - startSlice) / size;
|
|
_currentSlice = startSlice - (startScreenY - floor(startScreenY) - 1.0f) * _stepSlice;
|
|
|
|
_currentX = startScreenX;
|
|
_stepX = (endScreenX - startScreenX) / size;
|
|
|
|
_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);
|
|
|
|
m = scale_matrix * (translate_matrix * m);
|
|
|
|
for (int r = 0; r != 2; ++r)
|
|
for (int c = 0; c != 3; ++c)
|
|
_sliceMatrix[r][c] = m(r, c);
|
|
}
|
|
|
|
float SliceLineIterator::line() {
|
|
float var_0 = 0.0f;
|
|
|
|
if (_currentZ != 0.0f)
|
|
var_0 = _currentSlice / _currentZ;
|
|
|
|
if (var_0 < 0.0)
|
|
var_0 = 0.0f;
|
|
|
|
return var_0;
|
|
}
|
|
|
|
void SliceLineIterator::advance() {
|
|
_currentZ += _stepZ;
|
|
_currentSlice += _stepSlice;
|
|
_currentX += _stepX;
|
|
_currentY += 1;
|
|
_sliceMatrix[0][2] += (int)(65536.0f * _stepX);
|
|
_sliceMatrix[1][2] += _field_38;
|
|
}
|
|
|
|
static void setupLookupTable(int t[256], int inc) {
|
|
int v = 0;
|
|
for (int i = 0; i != 256; ++i) {
|
|
t[i] = v;
|
|
v += inc;
|
|
}
|
|
}
|
|
|
|
void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 position, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer) {
|
|
assert(_lights);
|
|
assert(_setEffects);
|
|
//assert(_view);
|
|
|
|
_vm->_sliceRenderer->setupFrameInWorld(animationId, animationFrame, position, facing);
|
|
assert(_sliceFramePtr);
|
|
|
|
SliceLineIterator sliceLineIterator;
|
|
sliceLineIterator.setup(
|
|
_endScreenVector.x, _endScreenVector.y, _endScreenVector.z,
|
|
_startScreenVector.x, _startScreenVector.y, _startScreenVector.z,
|
|
_endSlice, _startSlice,
|
|
_modelMatrix
|
|
);
|
|
|
|
SliceRendererLights sliceRendererLights = SliceRendererLights(_lights);
|
|
|
|
_lights->setupFrame(_view._frame);
|
|
_setEffects->setupFrame(_view._frame);
|
|
|
|
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]);
|
|
_m13 = sliceLineIterator._sliceMatrix[0][2];
|
|
setupLookupTable(_m21lookup, sliceLineIterator._sliceMatrix[1][0]);
|
|
setupLookupTable(_m22lookup, sliceLineIterator._sliceMatrix[1][1]);
|
|
_m23 = sliceLineIterator._sliceMatrix[1][2];
|
|
|
|
|
|
if(_animationsShadowEnabled[_animation]) {
|
|
//TODO: draw shadows
|
|
}
|
|
|
|
int frameY = sliceLineIterator._startY;
|
|
|
|
uint16 *frameLinePtr = (uint16*)surface.getPixels() + 640 * frameY;
|
|
uint16 *zBufferLinePtr = zbuffer + 640 * frameY;
|
|
|
|
while (sliceLineIterator._currentY <= sliceLineIterator._endY) {
|
|
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);
|
|
}
|
|
|
|
_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, true, frameLinePtr, zBufferLinePtr);
|
|
}
|
|
|
|
sliceLineIterator.advance();
|
|
frameY += 1;
|
|
frameLinePtr += 640;
|
|
zBufferLinePtr += 640;
|
|
}
|
|
}
|
|
|
|
void SliceRenderer::drawOnScreen(int animationId, int animationFrame, int screenX, int screenY, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer) {
|
|
if (scale == 0.0f) {
|
|
return;
|
|
}
|
|
_position.x = 0;
|
|
_position.y = 0;
|
|
_position.z = 0;
|
|
_facing = facing;
|
|
|
|
loadFrame(animationId, animationFrame);
|
|
|
|
float frameHeight = _frameSliceHeight * _frameSliceCount;
|
|
float frameSize = sqrtf(_frameScale.x * 255.0f * _frameScale.x * 255.0f + _frameScale.y * 255.0f * _frameScale.y * 255.0f);
|
|
float size = scale / MAX(frameSize, frameHeight);
|
|
|
|
float s = sinf(_facing);
|
|
float c = cosf(_facing);
|
|
|
|
Matrix3x2 m_rotation(c, -s, 0.0f,
|
|
s, c, 0.0f);
|
|
|
|
Matrix3x2 m_frame(_frameScale.x, 0.0f, _framePos.x,
|
|
0.0f, _frameScale.y, _framePos.y);
|
|
|
|
Matrix3x2 m_scale_size_25_5(size, 0.0f, 0.0f,
|
|
0.0f, 25.5f, 0.0f);
|
|
|
|
Matrix3x2 m_translate_x_32k(1.0f, 0.0f, screenX,
|
|
0.0f, 1.0f, 32768.0f);
|
|
|
|
Matrix3x2 m_scale_64k_64(65536.0f, 0.0f, 0.0f,
|
|
0.0f, 64.0f, 0.0f);
|
|
|
|
Matrix3x2 m = m_scale_64k_64 * (m_translate_x_32k * (m_scale_size_25_5 * (m_rotation * m_frame)));
|
|
|
|
setupLookupTable(_m11lookup, m(0, 0));
|
|
setupLookupTable(_m12lookup, m(0, 1));
|
|
_m13 = m(0, 2);
|
|
setupLookupTable(_m21lookup, m(1, 0));
|
|
setupLookupTable(_m22lookup, m(1, 1));
|
|
_m23 = m(1, 2);
|
|
|
|
int frameY = screenY + (size / 2.0f * frameHeight);
|
|
int currentY = frameY;
|
|
|
|
float currentSlice = 0;
|
|
float sliceStep = 1.0f / size / _frameSliceHeight;
|
|
|
|
uint16 *frameLinePtr = (uint16*)surface.getPixels() + 640 * frameY;
|
|
uint16 lineZbuffer[640];
|
|
|
|
while (currentSlice < _frameSliceCount) {
|
|
if (currentY >= 0 && currentY < 480) {
|
|
memset(lineZbuffer, 0xFF, 640 * 2);
|
|
drawSlice(currentSlice, false, frameLinePtr, lineZbuffer);
|
|
currentSlice += sliceStep;
|
|
currentY--;
|
|
frameLinePtr -= 640;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SliceRenderer::drawSlice(int slice, bool advanced, uint16 *frameLinePtr, uint16 *zbufLinePtr) {
|
|
if (slice < 0 || (uint32)slice >= _frameSliceCount)
|
|
return;
|
|
|
|
SlicePalette &palette = _vm->_sliceAnimations->getPalette(_framePaletteIndex);
|
|
|
|
byte *p = (byte*)_sliceFramePtr + 0x20 + 4 * slice;
|
|
|
|
uint32 polyOffset = READ_LE_UINT32(p);
|
|
|
|
p = (byte*)_sliceFramePtr + polyOffset;
|
|
|
|
uint32 polyCount = READ_LE_UINT32(p);
|
|
p += 4;
|
|
while (polyCount--) {
|
|
uint32 vertexCount = READ_LE_UINT32(p);
|
|
p += 4;
|
|
|
|
if (vertexCount == 0)
|
|
continue;
|
|
|
|
uint32 lastVertex = vertexCount - 1;
|
|
int lastVertexX = MAX((_m11lookup[p[3 * lastVertex]] + _m12lookup[p[3 * lastVertex + 1]] + _m13) >> 16, 0);
|
|
|
|
int previousVertexX = lastVertexX;
|
|
|
|
while (vertexCount--) {
|
|
int vertexX = CLIP((_m11lookup[p[0]] + _m12lookup[p[1]] + _m13) >> 16, 0, 640);
|
|
|
|
if (vertexX > previousVertexX) {
|
|
int vertexZ = (_m21lookup[p[0]] + _m22lookup[p[1]] + _m23) >> 6;
|
|
|
|
if (vertexZ >= 0 && vertexZ < 65536) {
|
|
int color555 = palette.color555[p[2]];
|
|
if (advanced) {
|
|
Color256 color = palette.color[p[2]];
|
|
|
|
color.r = (int)(_setEffectColor.r + _lightsColor.r * color.r) >> 16;
|
|
color.g = (int)(_setEffectColor.g + _lightsColor.g * color.g) >> 16;
|
|
color.b = (int)(_setEffectColor.b + _lightsColor.b * color.b) >> 16;
|
|
|
|
int bladeToScummVmConstant = 256 / 32;
|
|
|
|
color555 = _pixelFormat.RGBToColor(CLIP(color.r * bladeToScummVmConstant, 0, 255), CLIP(color.g * bladeToScummVmConstant, 0, 255), CLIP(color.b * bladeToScummVmConstant, 0, 255));
|
|
}
|
|
for (int x = previousVertexX; x != vertexX; ++x) {
|
|
if (vertexZ < zbufLinePtr[x]) {
|
|
frameLinePtr[x] = color555;
|
|
zbufLinePtr[x] = (uint16)vertexZ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
p += 3;
|
|
previousVertexX = vertexX;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SliceRenderer::preload(int animationId) {
|
|
int i;
|
|
int frameCount = _vm->_sliceAnimations->getFrameCount(animationId);
|
|
for (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++) {
|
|
_animationsShadowEnabled[animationsIdsList[i]] = false;
|
|
}
|
|
}
|
|
|
|
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 SliceRendererLights::calculateColorBase(Vector3 position1, Vector3 position2, float height) {
|
|
_finalColor.r = 0.0f;
|
|
_finalColor.g = 0.0f;
|
|
_finalColor.b = 0.0f;
|
|
_hmm3 = 0;
|
|
if (_lights) {
|
|
for (uint i = 0; i < _lights->_lights.size(); i++) {
|
|
Light *light = _lights->_lights[i];
|
|
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;
|
|
}
|
|
}
|
|
|
|
_finalColor.r += _lights->_ambientLightColor.r;
|
|
_finalColor.g += _lights->_ambientLightColor.g;
|
|
_finalColor.b += _lights->_ambientLightColor.b;
|
|
}
|
|
}
|
|
|
|
void SliceRendererLights::calculateColorSlice(Vector3 position) {
|
|
_finalColor.r = 0.0f;
|
|
_finalColor.g = 0.0f;
|
|
_finalColor.b = 0.0f;
|
|
|
|
if (_lights) {
|
|
for (uint i = 0; i < _lights->_lights.size(); i++) {
|
|
Light *light = _lights->_lights[i];
|
|
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;
|
|
}
|
|
}
|
|
_finalColor.r += _lights->_ambientLightColor.r;
|
|
_finalColor.g += _lights->_ambientLightColor.g;
|
|
_finalColor.b += _lights->_ambientLightColor.b;
|
|
}
|
|
}
|
|
|
|
} // End of namespace BladeRunner
|