BLADERUNNER: fixed lighting cache

actors can be now partially illuminated (per slice), it iss visible in scene rc02 in the right part of the room
This commit is contained in:
Peter Kohaut 2017-04-02 18:17:43 +02:00
parent 06be112b22
commit 027dc4c38c
13 changed files with 121 additions and 108 deletions

View File

@ -1057,11 +1057,11 @@ bool Actor::isSpeeching() {
return _vm->_audioSpeech->isPlaying();
}
void Actor::addClueToDatabase(int clueId, int unknown, bool clueAcquired, bool unknownFlag, int fromActorId) {
_clues->add(_id, clueId, unknown, clueAcquired, unknownFlag, fromActorId);
void Actor::addClueToDatabase(int clueId, int weight, bool clueAcquired, bool unknownFlag, int fromActorId) {
_clues->add(_id, clueId, weight, clueAcquired, unknownFlag, fromActorId);
}
void Actor::acquireClue(int clueId, byte unknownFlag, int fromActorId) {
void Actor::acquireClue(int clueId, bool unknownFlag, int fromActorId) {
_clues->acquire(clueId, unknownFlag, fromActorId);
}
@ -1078,9 +1078,10 @@ void Actor::copyClues(int actorId) {
for (int i = 0; i < (int)_vm->_gameInfo->getClueCount(); i++) {
if (hasClue(i) && !_clues->isFlag4(i) && !otherActor->hasClue(i)) {
int fromActorId = _id;
if (_id == VOICEOVER_ACTOR)
if (_id == VOICEOVER_ACTOR) {
fromActorId = _clues->getFromActorId(i);
otherActor->acquireClue(i, 0, fromActorId);
}
otherActor->acquireClue(i, false, fromActorId);
}
}
}

View File

@ -208,7 +208,7 @@ public:
bool isSpeeching();
void addClueToDatabase(int clueId, int unknown, bool clueAcquired, bool unknownFlag, int fromActorId);
void acquireClue(int clueId, byte unknownFlag, int fromActorId);
void acquireClue(int clueId, bool unknownFlag, int fromActorId);
void loseClue(int clueId);
bool hasClue(int clueId);
void copyClues(int actorId);

View File

@ -73,7 +73,7 @@ ActorClues::~ActorClues() {
_count = 0;
}
void ActorClues::acquire(int clueId, char flag2, int fromActorId) {
void ActorClues::acquire(int clueId, bool flag2, int fromActorId) {
int clueIndex = findClueIndex(clueId);
_clues[clueIndex]._flags |= 0x01;
_clues[clueIndex]._flags = (_clues[clueIndex]._flags & ~0x02) | ((flag2 << 1) & 0x02);
@ -113,7 +113,7 @@ bool ActorClues::isFlag2(int clueId) {
return (_clues[clueIndex]._flags & 0x02) >> 1;
}
bool ActorClues::isFlag3(int clueId) {
bool ActorClues::isViewed(int clueId) {
int clueIndex = findClueIndex(clueId);
if (clueIndex == -1) {
return false;
@ -141,7 +141,7 @@ int ActorClues::getField1(int clueId) {
return 0;
}
return _clues[clueIndex]._field1;
return _clues[clueIndex]._weight;
}
int ActorClues::getCount() {
@ -164,13 +164,13 @@ int ActorClues::findClueIndex(int clueId) {
return -1;
}
void ActorClues::add(int actorId, int clueId, int unknown, bool acquired, bool unknownFlag, int fromActorId) {
void ActorClues::add(int actorId, int clueId, int weight, bool acquired, bool unknownFlag, int fromActorId) {
assert(_count < _maxCount);
debug("Actor %d added clue: \"%s\" from %d", actorId, _vm->_crimesDatabase->getClueText(clueId), fromActorId);
//debug("Actor %d added clue: \"%s\" from %d", actorId, _vm->_crimesDatabase->getClueText(clueId), fromActorId);
_clues[_count]._clueId = clueId;
_clues[_count]._field1 = unknown;
_clues[_count]._weight = weight;
_clues[_count]._flags = 0;
_clues[_count]._flags = (_clues[_count]._flags & ~0x01) | (acquired & 0x01);
@ -185,7 +185,7 @@ void ActorClues::remove(int index) {
debug("Actor removed clue: \"%s\"", _vm->_crimesDatabase->getClueText(_clues[index]._clueId));
_clues[index]._clueId = -1;
_clues[index]._field1 = 0;
_clues[index]._weight = 0;
_clues[index]._flags = 0;
_clues[index]._fromActorId = -1;

View File

@ -31,7 +31,7 @@ namespace BladeRunner {
struct ActorClue {
int _clueId;
int _field1;
int _weight;
int _fromActorId;
int _field3;
int _field4;
@ -55,12 +55,12 @@ public:
~ActorClues();
void add(int actorId, int clueId, int unknown, bool acquired, bool unknownFlag, int fromActorId);
void acquire(int clueId, char flag2, int fromActorId);
void acquire(int clueId, bool flag2, int fromActorId);
void lose(int clueId);
bool isAcquired(int clueId);
int getFromActorId(int clueId);
bool isFlag2(int clueId);
bool isFlag3(int clueId);
bool isViewed(int clueId);
bool isFlag4(int clueId);
int getField1(int clueId);

View File

@ -659,37 +659,33 @@ void BladeRunnerEngine::gameTick() {
BoundingBox *bbox = &sceneObject->_boundingBox;
Vector3 a, b;
bbox->getXYZ(&a.x, &a.y, &a.z, &b.x, &b.y, &b.z);
int color = 0b111111111111111;
if (sceneObject->_sceneObjectType == SceneObjectTypeActor) {
color = 0b111110000000000;
}
if (sceneObject->_sceneObjectType == SceneObjectTypeObject) {
color = 0b011110111101111;
//if (sceneObject->_isObstacle)
// color += 0b100000000000000;
if (sceneObject->_isClickable)
color = 0b000001111100000;
//if (sceneObject->_isTarget)
// color += 0b000000000010000;
}
drawBBox(a, b, _view, &_surface2, color);
//_surface2.frameRect(sceneObject->_screenRectangle, color);
Vector3 pos = _view->calculateScreenPosition(0.5 * (a + b));
int color;
switch (sceneObject->_sceneObjectType) {
case SceneObjectTypeActor:
color = 0b111110000000000;
drawBBox(a, b, _view, &_surface2, color);
_mainFont->drawColor(_textActorNames->getText(sceneObject->_sceneObjectId - SCENE_OBJECTS_ACTORS_OFFSET), _surface2, pos.x, pos.y, color);
break;
case SceneObjectTypeItem:
_mainFont->drawColor("item", _surface2, pos.x, pos.y, color);
char itemText[40];
drawBBox(a, b, _view, &_surface2, color);
sprintf(itemText, "item %i", sceneObject->_sceneObjectId - SCENE_OBJECTS_ITEMS_OFFSET);
_mainFont->drawColor(itemText, _surface2, pos.x, pos.y, color);
break;
case SceneObjectTypeObject:
color = 0b011110111101111;
//if (sceneObject->_isObstacle)
// color += 0b100000000000000;
if (sceneObject->_isClickable) {
color = 0b000001111100000;
}
drawBBox(a, b, _view, &_surface2, color);
_mainFont->drawColor(_scene->objectGetName(sceneObject->_sceneObjectId - SCENE_OBJECTS_OBJECTS_OFFSET), _surface2, pos.x, pos.y, color);
break;
}
_surface2.frameRect(sceneObject->_screenRectangle, color);
}
}
@ -706,32 +702,51 @@ void BladeRunnerEngine::gameTick() {
_surface2.frameRect(region->_rectangle, 0b111111111111111);
}
//draw walkboxes
for (int i = 0; i < _scene->_set->_walkboxCount; i++) {
Walkbox *walkbox = &_scene->_set->_walkboxes[i];
for (int j = 0; j < walkbox->_vertexCount; j++) {
Vector3 start = _view->calculateScreenPosition(walkbox->_vertices[j]);
Vector3 end = _view->calculateScreenPosition(walkbox->_vertices[(j + 1) % walkbox->_vertexCount]);
//debug("walkbox[%i][%i] = x=%f y=%f x=%f y=%f", i, j, start.x, start.y, end.x, end.y);
_surface2.drawLine(start.x, start.y, end.x, end.y, 0b111111111100000);
Vector3 pos = _view->calculateScreenPosition(0.5 * (start + end));
_mainFont->drawColor(walkbox->_name, _surface2, pos.x, pos.y, 0b111111111100000);
}
}
// for (int i = 0; i < (int)_lights->_lights.size(); i++) {
// Light *light = _lights->_lights[i];
// Matrix4x3 m = light->_matrix;
// Vector3 pos = Vector3(m(0, 3), m(1, 3), m(2, 3));
// Vector3 size = Vector3(5.0f, 5.0f, 5.0f);
// 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(pos - size, pos + size, _view, &_surface2, color);
// }
// draw lights
for (int i = 0; i < (int)_lights->_lights.size(); i++) {
Light *light = _lights->_lights[i];
Matrix4x3 m = light->_matrix;
m = invertMatrix(m);
//todo do this properly
Vector3 posOrigin = m * Vector3(0.0f, 0.0f, 0.0f);
float t = posOrigin.y;
posOrigin.y = posOrigin.z;
posOrigin.z = -t;
Vector3 posTarget = m * Vector3(0.0f, 0.0f, -100.0f);
t = posTarget.y;
posTarget.y = posTarget.z;
posTarget.z = -t;
Vector3 size = Vector3(5.0f, 5.0f, 5.0f);
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(posOrigin - size, posOrigin + size, _view, &_surface2, color);
Vector3 posOriginT = _view->calculateScreenPosition(posOrigin);
Vector3 posTargetT = _view->calculateScreenPosition(posTarget);
_surface2.drawLine(posOriginT.x, posOriginT.y, posTargetT.x, posTargetT.y, color);
_mainFont->drawColor(light->_name, _surface2, posOriginT.x, posOriginT.y, color);
}
//draw waypoints
for(int i = 0; i < _waypoints->_count; i++) {
Waypoint *waypoint = &_waypoints->_waypoints[i];
if(waypoint->_setId != _scene->getSetId())
@ -744,7 +759,6 @@ void BladeRunnerEngine::gameTick() {
char waypointText[40];
sprintf(waypointText, "waypoint %i", i);
_mainFont->drawColor(waypointText, _surface2, spos.x, spos.y, color);
}
#endif

View File

@ -21,8 +21,8 @@
*/
#include "bladerunner/light.h"
#include "common/util.h"
#include "common/debug.h"
namespace BladeRunner {
@ -144,7 +144,7 @@ void Light::setupFrame(int frame) {
}
float Light::calculate(Vector3 start, Vector3 end) {
return calculateCoefficient(_matrix * start, _matrix * end, _falloffStart, _falloffEnd);
return calculateFalloutCoefficient(_matrix * start, _matrix * end, _falloffStart, _falloffEnd);
}
void Light::calculateColor(Color *outColor, Vector3 position) {
@ -155,20 +155,20 @@ void Light::calculateColor(Color *outColor, Vector3 position) {
outColor->b = _color.b * att;
}
float Light::calculateCoefficient(Vector3 start, Vector3 end, float falloffStart, float falloffEnd) {
float Light::calculateFalloutCoefficient(Vector3 start, Vector3 end, float falloffStart, float falloffEnd) {
if (falloffEnd == 0.0f) {
return 1.0e30f;
}
if (falloffStart >= start.length() && falloffStart >= end.length()) {
if (falloffStart * falloffStart >= start.length() && falloffStart * falloffStart >= end.length()) {
return 1.0e30f;
}
float v40 = (end - start).length();
float diff = (end - start).length();
float v31 = 0.0f;
if (v40 != 0.0f) {
if (diff != 0.0f) {
Vector3 v27 = Vector3::cross(start, (end - start));
v31 = v27.length() / v40;
v31 = v27.length() / diff;
}
if (v31 < falloffEnd) {
@ -198,11 +198,11 @@ float Light1::calculate(Vector3 start, Vector3 end) {
float v40 = 0.0f;
if (_falloffEnd != 0.0f) {
v40 = calculateCoefficient(start, end, _falloffStart, _falloffEnd);
v40 = calculateFalloutCoefficient(start, end, _falloffStart, _falloffEnd);
}
float v41 = atan2(start.length(), -start.z);
float v42 = atan2(end.length(), -end.z);
float v41 = atan2(sqrt(start.x * start.x + start.y * start.y), -start.z);
float v42 = atan2(sqrt(end.x * end.x + end.y * end.y), -end.z);
float v43;
if ((_angleStart >= v41 && _angleStart >= v42) || (_angleEnd <= v41 && _angleEnd <= v42)) {
@ -240,7 +240,7 @@ float Light2::calculate(Vector3 start, Vector3 end) {
float v54 = 0.0f;
if (_falloffEnd != 0.0f) {
v54 = calculateCoefficient(start, end, _falloffStart, _falloffEnd);
v54 = calculateFalloutCoefficient(start, end, _falloffStart, _falloffEnd);
}
float v55 = atan2(fabs(start.x), -start.z);

View File

@ -89,7 +89,7 @@ public:
virtual void calculateColor(Color *outColor, Vector3 position);
protected:
float calculateCoefficient(Vector3 start, Vector3 end, float a3, float a4);
float calculateFalloutCoefficient(Vector3 start, Vector3 end, float a3, float a4);
float attenuation(float min, float max, float distance);
};

View File

@ -220,7 +220,7 @@ bool SceneScriptRC01::ClickedOn3DObject(const char *objectName, bool a2) {
Actor_Voice_Over(1880, kActorVoiceOver);
Actor_Voice_Over(1890, kActorVoiceOver);
I_Sez("JM: That McCoy--he's one funny guy! Jet-black fire truck, hehehehe...");
Actor_Clue_Acquire(kActorMcCoy, kCluePaintTransfer, 1, -1);
Actor_Clue_Acquire(kActorMcCoy, kCluePaintTransfer, true, -1);
}
}
return true;
@ -234,11 +234,11 @@ bool SceneScriptRC01::ClickedOn3DObject(const char *objectName, bool a2) {
Actor_Face_Actor(kActorOfficerLeary, kActorMcCoy, true);
Actor_Says(kActorOfficerLeary, 0, 12);
Actor_Says(kActorMcCoy, 4495, 13);
Actor_Clue_Acquire(kActorMcCoy, kClueDoorForced2, 1, kActorOfficerLeary);
Actor_Clue_Acquire(kActorMcCoy, kClueDoorForced2, true, kActorOfficerLeary);
} else {
Actor_Says(kActorMcCoy, 8570, 14);
}
Actor_Clue_Acquire(kActorMcCoy, kClueDoorForced1, 1, -1);
Actor_Clue_Acquire(kActorMcCoy, kClueDoorForced1, true, -1);
}
return true;
}
@ -270,7 +270,7 @@ bool SceneScriptRC01::ClickedOnActor(int actorId) {
Actor_Face_Object(kActorOfficerLeary, "70_1", true);
Actor_Says(kActorOfficerLeary, 100, 15);
Actor_Face_Actor(kActorOfficerLeary, kActorMcCoy, true);
Actor_Clue_Acquire(kActorMcCoy, kClueCrowdInterviewA, 1, kActorOfficerLeary);
Actor_Clue_Acquire(kActorMcCoy, kClueCrowdInterviewA, true, kActorOfficerLeary);
Game_Flag_Reset(392);
} else if (Actor_Clue_Query(kActorOfficerLeary, kClueCrowdInterviewB) && !Actor_Clue_Query(kActorMcCoy, kClueCrowdInterviewB)) {
Actor_Face_Object(kActorOfficerLeary, "70_5", true);
@ -278,7 +278,7 @@ bool SceneScriptRC01::ClickedOnActor(int actorId) {
Actor_Face_Actor(kActorOfficerLeary, kActorMcCoy, true);
Actor_Says(kActorOfficerLeary, 130, 14);
I_Sez("JM: Did it have a huge, ugly piece of chrome on it?");
Actor_Clue_Acquire(kActorMcCoy, kClueCrowdInterviewB, 1, kActorOfficerLeary);
Actor_Clue_Acquire(kActorMcCoy, kClueCrowdInterviewB, true, kActorOfficerLeary);
Game_Flag_Reset(392);
} else {
Actor_Says(kActorOfficerLeary, 90, 16);
@ -294,7 +294,7 @@ bool SceneScriptRC01::ClickedOnActor(int actorId) {
I_Sez("MG: Hey, leave that officer alone. Can't you see he's busy?");
I_Sez("JM: (...mmm, donuts...)");
Game_Flag_Set(3);
Actor_Clue_Acquire(kActorMcCoy, kClueOfficersStatement, 1, kActorOfficerLeary);
Actor_Clue_Acquire(kActorMcCoy, kClueOfficersStatement, true, kActorOfficerLeary);
Actor_Says(kActorMcCoy, 4515, 13);
Game_Flag_Set(392);
Actor_Says(kActorOfficerLeary, 40, 13);
@ -321,7 +321,7 @@ bool SceneScriptRC01::ClickedOnItem(int itemId, bool a2) {
Actor_Set_Goal_Number(kActorOfficerLeary, 0);
if (!Loop_Actor_Walk_To_Item(kActorMcCoy, 66, 36, 1, false)) {
Actor_Face_Item(kActorMcCoy, 66, true);
Actor_Clue_Acquire(kActorMcCoy, kClueChromeDebris, 1, -1);
Actor_Clue_Acquire(kActorMcCoy, kClueChromeDebris, true, -1);
Actor_Face_Actor(kActorOfficerLeary, kActorMcCoy, true);
Actor_Says(kActorOfficerLeary, 20, 12);
Game_Flag_Set(163);

View File

@ -536,11 +536,11 @@ bool ScriptBase::Loop_Actor_Travel_Ladder(int actorId, int a2, int a3, int a4) {
return false;
}
void ScriptBase::Actor_Clue_Add_To_Database(int actorId, int clueId, int unknown, bool clueAcquired, bool unknownFlag, int fromActorId) {
_vm->_actors[actorId]->addClueToDatabase(clueId, unknown, clueAcquired, unknownFlag, fromActorId);
void ScriptBase::Actor_Clue_Add_To_Database(int actorId, int clueId, int weight, bool clueAcquired, bool unknownFlag, int fromActorId) {
_vm->_actors[actorId]->addClueToDatabase(clueId, weight, clueAcquired, unknownFlag, fromActorId);
}
void ScriptBase::Actor_Clue_Acquire(int actorId, int clueId, byte unknownFlag, int fromActorId) {
void ScriptBase::Actor_Clue_Acquire(int actorId, int clueId, bool unknownFlag, int fromActorId) {
_vm->_actors[actorId]->acquireClue(clueId, unknownFlag, fromActorId);
}

View File

@ -511,7 +511,7 @@ protected:
bool Loop_Actor_Travel_Stairs(int actorId, int a2, int a3, int a4);
bool Loop_Actor_Travel_Ladder(int actorId, int a2, int a3, int a4);
void Actor_Clue_Add_To_Database(int actorId, int clueId, int weight, bool clueAcquired, bool unknownFlag, int fromActorId);
void Actor_Clue_Acquire(int actorId, int clueId, byte unknownFlag, int fromActorId);
void Actor_Clue_Acquire(int actorId, int clueId, bool unknownFlag, int fromActorId);
void Actor_Clue_Lose(int actorId, int clueId);
bool Actor_Clue_Query(int actorId, int clueId);
void Actor_Clues_Transfer_New_To_Mainframe(int actorId);

View File

@ -569,9 +569,9 @@ SliceRendererLights::SliceRendererLights(Lights *lights) {
_lights = lights;
for (int i = 0; i < 20; i++) {
_colors[i].r = 0.0f;
_colors[i].g = 0.0f;
_colors[i].b = 0.0f;
_cacheColor[i].r = 0.0f;
_cacheColor[i].g = 0.0f;
_cacheColor[i].b = 0.0f;
}
}
@ -579,28 +579,27 @@ void SliceRendererLights::calculateColorBase(Vector3 position1, Vector3 position
_finalColor.r = 0.0f;
_finalColor.g = 0.0f;
_finalColor.b = 0.0f;
_hmm3 = 0;
_cacheRecalculation = 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*/);
float cacheCoeficient = light->calculate(position1, position2/*, height*/);
_cacheStart[i] = cacheCoeficient;
_cacheCounter[i] = cacheCoeficient;
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;
Color color;
light->calculateColor(&color, position1);
_cacheColor[i] = color;
_finalColor.r += color.r;
_finalColor.g += color.g;
_finalColor.b += color.b;
} else {
Color v23;
light->calculateColor(&v23, position1);
_finalColor.r += v23.r;
_finalColor.g += v23.g;
_finalColor.b += v23.b;
Color color;
light->calculateColor(&color, position1);
_finalColor.r += color.r;
_finalColor.g += color.g;
_finalColor.b += color.b;
}
}
@ -619,22 +618,21 @@ void SliceRendererLights::calculateColorSlice(Vector3 position) {
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) {
_cacheCounter[i] -= 1.0f;
if (_cacheCounter[i] <= 0.0f) {
do {
_hmm[i] = _hmm[i] + _hmm2[i];
} while (_hmm[i] <= 0.0f);
light->calculateColor(&_colors[i], position);
_hmm3++;
_cacheCounter[i] = _cacheCounter[i] + _cacheStart[i];
} while (_cacheCounter[i] <= 0.0f);
light->calculateColor(&_cacheColor[i], position);
_cacheRecalculation++;
}
_finalColor.r += _colors[i].r;
_finalColor.g += _colors[i].g;
_finalColor.b += _colors[i].b;
_finalColor.r += _cacheColor[i].r;
_finalColor.g += _cacheColor[i].g;
_finalColor.b += _cacheColor[i].b;
} else {
Color color;
light->calculateColor(&color, position);
_hmm3++;
_cacheRecalculation++;
_finalColor.r += color.r;
_finalColor.g += color.g;
_finalColor.b += color.b;

View File

@ -115,10 +115,10 @@ private:
class SliceRendererLights {
Lights *_lights;
Color _colors[20];
float _hmm[20];
float _hmm2[20];
int _hmm3;
Color _cacheColor[20];
float _cacheCounter[20];
float _cacheStart[20];
int _cacheRecalculation;
public:
Color _finalColor;

View File

@ -78,7 +78,7 @@ bool TextResource::open(const char *name) {
s->read(_strings, remain);
#if _DEBUG
#if 0
debug("\n%s\n----------------", resName);
for (uint32 i = 0; i != (uint32)_count; ++i) {
debug("%3d: %s", i, getText(i));