diff options
-rw-r--r-- | engines/bladerunner/actor.cpp | 4 | ||||
-rw-r--r-- | engines/bladerunner/bladerunner.cpp | 49 | ||||
-rw-r--r-- | engines/bladerunner/bladerunner.h | 5 | ||||
-rw-r--r-- | engines/bladerunner/item.cpp | 3 | ||||
-rw-r--r-- | engines/bladerunner/item.h | 7 | ||||
-rw-r--r-- | engines/bladerunner/items.cpp | 30 | ||||
-rw-r--r-- | engines/bladerunner/items.h | 7 | ||||
-rw-r--r-- | engines/bladerunner/scene.cpp | 49 | ||||
-rw-r--r-- | engines/bladerunner/script/rc01.cpp | 3 | ||||
-rw-r--r-- | engines/bladerunner/script/script.cpp | 2 | ||||
-rw-r--r-- | engines/bladerunner/slice_renderer.cpp | 144 | ||||
-rw-r--r-- | engines/bladerunner/slice_renderer.h | 29 |
12 files changed, 163 insertions, 169 deletions
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp index 8ead0d4a76..7509bb9575 100644 --- a/engines/bladerunner/actor.cpp +++ b/engines/bladerunner/actor.cpp @@ -228,7 +228,7 @@ bool Actor::loopWalk(const Vector3 &destination, int destinationOffset, bool a3, break; } return false; - } else { + } else { //TODO: // original code, not yet working *isRunning = false; @@ -511,7 +511,7 @@ void Actor::draw() { // TODO: Handle SHORTY mode _vm->_sliceRenderer->drawInWorld(_animationId, _animationFrame, drawPosition, drawAngle, drawScale, _vm->_surface2, _vm->_zBuffer2); - //todo udpate screenrect + _vm->_sliceRenderer->getScreenRectangle(&_screenRectangle, _animationId, _animationFrame, drawPosition, drawAngle, drawScale); } int Actor::getSetId() { diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp index 1f05046f2d..9cd0e0ddc2 100644 --- a/engines/bladerunner/bladerunner.cpp +++ b/engines/bladerunner/bladerunner.cpp @@ -65,10 +65,10 @@ namespace BladeRunner { BladeRunnerEngine::BladeRunnerEngine(OSystem *syst) - : Engine(syst), - _rnd("bladerunner") { + : Engine(syst), + _rnd("bladerunner") { _windowIsActive = true; - _gameIsRunning = true; + _gameIsRunning = true; _playerLosesControlCounter = 0; _crimesDatabase = nullptr; @@ -286,7 +286,7 @@ bool BladeRunnerEngine::startup(bool hasSavegames) { _mainFont = new Font(this); _mainFont->open("KIA6PT.FON", 640, 480, -1, 0, 0x252D); - _mainFont->setSpacing(1, 0); + _mainFont->setSpacing(1, 0); for (int i = 0; i != 43; ++i) { Shape *shape = new Shape(this); @@ -428,7 +428,7 @@ void BladeRunnerEngine::shutdown() { if (isArchiveOpen("SPCHSFX.TLK")) closeArchive("SPCHSFX.TLK"); - if(_mainFont) { + if (_mainFont) { _mainFont->close(); delete _mainFont; _mainFont = nullptr; @@ -524,7 +524,7 @@ void BladeRunnerEngine::gameLoop() { #if _DEBUG -void drawBBox(Vector3 start, Vector3 end, View* view, Graphics::Surface *surface, int color) { +void drawBBox(Vector3 start, Vector3 end, View *view, Graphics::Surface *surface, int color) { Vector3 bfl = view->calculateScreenPosition(Vector3(start.x, start.y, start.z)); Vector3 bfr = view->calculateScreenPosition(Vector3(start.x, end.y, start.z)); Vector3 bbr = view->calculateScreenPosition(Vector3(end.x, end.y, start.z)); @@ -584,7 +584,7 @@ void BladeRunnerEngine::gameTick() { } (void)backgroundChanged; _surface2.copyFrom(_surface1); - memcpy(_zBuffer2, _zBuffer1, 640*480*2); + memcpy(_zBuffer2, _zBuffer1, 640 * 480 * 2); #if 0 { @@ -613,7 +613,7 @@ void BladeRunnerEngine::gameTick() { //int setId = _scene->_setId; for (int i = 0, end = _gameInfo->getActorCount(); i != end; ++i) { //if (_actors[i]->getSetId() == setId) { - if (i == 0 || i == 23){ // Currently limited to McCoy and Officer Leroy + if (i == 0 || i == 23) { // Currently limited to McCoy and Officer Leroy _actors[i]->tick(backgroundChanged); } } @@ -638,7 +638,7 @@ void BladeRunnerEngine::gameTick() { _walkSoundId = -1; } -#if false +#if 0 //draw scene objects int count = _sceneObjects->_count; if (count > 0) { @@ -655,24 +655,25 @@ void BladeRunnerEngine::gameTick() { } if (sceneObject->_sceneObjectType == SceneObjectTypeObject) { color = 0b011110111101111; - //if (sceneObject->_isObstacle) - // color += 0b100000000000000; + //if (sceneObject->_isObstacle) + // color += 0b100000000000000; if (sceneObject->_isClickable) color = 0b000001111100000; - //if (sceneObject->_isTarget) - // color += 0b000000000010000; + //if (sceneObject->_isTarget) + // color += 0b000000000010000; } - sceneObject->_sceneObjectId; drawBBox(a, b, _view, &_surface2, color); + //_surface2.frameRect(sceneObject->_screenRectangle, color); + Vector3 pos = _view->calculateScreenPosition(0.5 * (a + b)); - switch(sceneObject->_sceneObjectType) { + switch (sceneObject->_sceneObjectType) { case SceneObjectTypeActor: _mainFont->drawColor(_textActorNames->getText(sceneObject->_sceneObjectId - SCENE_OBJECTS_ACTORS_OFFSET), _surface2, pos.x, pos.y, color); break; case SceneObjectTypeItem: - _mainFont->draw("item", _surface2, pos.x, pos.y); + _mainFont->drawColor("item", _surface2, pos.x, pos.y, color); break; case SceneObjectTypeObject: _mainFont->drawColor(_scene->objectGetName(sceneObject->_sceneObjectId - SCENE_OBJECTS_OBJECTS_OFFSET), _surface2, pos.x, pos.y, color); @@ -683,13 +684,13 @@ void BladeRunnerEngine::gameTick() { //draw regions for (int i = 0; i < 10; i++) { - Region* region = &_scene->_regions->_regions[i]; + Region *region = &_scene->_regions->_regions[i]; if (!region->_present) continue; _surface2.frameRect(region->_rectangle, 0b000000000011111); } for (int i = 0; i < 10; i++) { - Region* region = &_scene->_exits->_regions[i]; + Region *region = &_scene->_exits->_regions[i]; if (!region->_present) continue; _surface2.frameRect(region->_rectangle, 0b111111111111111); } @@ -700,7 +701,7 @@ void BladeRunnerEngine::gameTick() { 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); + //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); @@ -717,7 +718,7 @@ void BladeRunnerEngine::gameTick() { 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); + drawBBox(pos - size, pos + size, _view, &_surface2, color); } #endif @@ -759,7 +760,7 @@ void BladeRunnerEngine::handleMouseClick(int x, int y) { int isTarget; int sceneObjectId = _sceneObjects->findByXYZ(&isClickable, &isObstacle, &isTarget, mousePosition.x, mousePosition.y, mousePosition.z, 1, 0, 1); - int exitIndex = _scene->_exits->getRegionAtXY(x, y); + int exitIndex = _scene->_exits->getRegionAtXY(x, y); debug("%d %d", sceneObjectId, exitIndex); @@ -819,7 +820,7 @@ void BladeRunnerEngine::handleMouseClickActor(int x, int y, int actorId) { } void BladeRunnerEngine::gameWaitForActive() { - while(!_windowIsActive) { + while (!_windowIsActive) { handleEvents(); } } @@ -873,7 +874,7 @@ bool BladeRunnerEngine::openArchive(const Common::String &name) { bool BladeRunnerEngine::closeArchive(const Common::String &name) { for (uint i = 0; i != 10; ++i) { - if (_archives[i].isOpen() &&_archives[i].getName() == name) { + if (_archives[i].isOpen() && _archives[i].getName() == name) { _archives[i].close(); return true; } @@ -885,7 +886,7 @@ bool BladeRunnerEngine::closeArchive(const Common::String &name) { bool BladeRunnerEngine::isArchiveOpen(const Common::String &name) { for (uint i = 0; i != 10; ++i) { - if (_archives[i].isOpen() &&_archives[i].getName() == name) + if (_archives[i].isOpen() && _archives[i].getName() == name) return true; } diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h index 3c9cc2aae9..bbef17820d 100644 --- a/engines/bladerunner/bladerunner.h +++ b/engines/bladerunner/bladerunner.h @@ -131,7 +131,7 @@ public: int _walkSoundId; int _walkSoundVolume; int _walkSoundBalance; - int _walkingActorId; + int _walkingActorId; private: static const int kArchiveCount = 10; MIXArchive _archives[kArchiveCount]; @@ -178,8 +178,7 @@ public: void ISez(const char *str); }; -static inline -const Graphics::PixelFormat createRGB555() { +static inline const Graphics::PixelFormat createRGB555() { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); } diff --git a/engines/bladerunner/item.cpp b/engines/bladerunner/item.cpp index 0a616d4385..6200668e14 100644 --- a/engines/bladerunner/item.cpp +++ b/engines/bladerunner/item.cpp @@ -80,7 +80,8 @@ void Item::tick(bool special) { Vector3 postition(_position.x, -_position.z, _position.y); int animationId = _animationId + (special ? 1 : 0); _vm->_sliceRenderer->drawInWorld(animationId, 0, postition, M_PI - _angle, 1.0f, _vm->_surface2, _vm->_zBuffer2); - //todo udpate screenrect + _vm->_sliceRenderer->getScreenRectangle(&_screenRectangle, animationId, 0, postition, M_PI - _angle, 1.0f); + if (_isSpinning) { _facing += _facingChange; diff --git a/engines/bladerunner/item.h b/engines/bladerunner/item.h index 0035985751..3f12a6ad3a 100644 --- a/engines/bladerunner/item.h +++ b/engines/bladerunner/item.h @@ -60,18 +60,17 @@ private: bool _isPoliceMazeEnemy; public: - Item(BladeRunnerEngine* vm); + Item(BladeRunnerEngine *vm); ~Item(); - + void getXYZ(float *x, float *y, float *z); void setXYZ(Vector3 position); - void getWidthHeight(int * width, int * height); + void getWidthHeight(int *width, int *height); bool isTargetable(); void tick(bool special); void setup(int itemId, int setId, int animationId, Vector3 position, int facing, int height, int width, bool isTargetable, bool isVisible, bool isPoliceMazeEnemy); - }; } diff --git a/engines/bladerunner/items.cpp b/engines/bladerunner/items.cpp index 66ae132fda..2bc06e0a72 100644 --- a/engines/bladerunner/items.cpp +++ b/engines/bladerunner/items.cpp @@ -32,12 +32,12 @@ Items::Items(BladeRunnerEngine *vm) { } Items::~Items() { - for(int i = _items.size() - 1; i >= 0; i--) { + for (int i = _items.size() - 1; i >= 0; i--) { delete _items.remove_at(i); } } -void Items::getXYZ(int itemId, float* x, float* y, float* z) { +void Items::getXYZ(int itemId, float *x, float *y, float *z) { int itemIndex = findItem(itemId); assert(itemIndex != -1); @@ -53,8 +53,8 @@ void Items::getWidthHeight(int itemId, int *width, int *height) { void Items::tick() { int setId = _vm->_scene->getSetId(); - for(int i = 0; i < (int)_items.size(); i++) { - if(_items[i]->_setId != setId) { + for (int i = 0; i < (int)_items.size(); i++) { + if (_items[i]->_setId != setId) { continue; } bool set14NotTarget = setId == 14 && !_items[i]->isTargetable(); @@ -62,12 +62,12 @@ void Items::tick() { } } -bool Items::add(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTargetable, bool isVisible, bool isPoliceMazeEnemy, bool addToSet) { +bool Items::addToWorld(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTargetable, bool isVisible, bool isPoliceMazeEnemy, bool addToSet) { if (_items.size() >= 100) { return false; } int itemIndex = findItem(itemId); - if(itemIndex == -1) { + if (itemIndex == -1) { itemIndex = _items.size(); } @@ -75,18 +75,32 @@ bool Items::add(int itemId, int animationId, int setId, Vector3 position, int fa item->setup(itemId, setId, animationId, position, facing, height, width, isTargetable, isVisible, isPoliceMazeEnemy); _items.push_back(item); - if(addToSet && setId == _vm->_scene->getSetId()) { + if (addToSet && setId == _vm->_scene->getSetId()) { return _vm->_sceneObjects->addItem(itemId + SCENE_OBJECTS_ITEMS_OFFSET, &item->_boundingBox, &item->_screenRectangle, isTargetable, isVisible); } return true; } +bool Items::addToSet(int setId) { + int itemsCount = _vm->_items->_items.size(); + if (itemsCount == 0) { + return true; + } + for (int i = 0; i < itemsCount; i++) { + Item *item = _vm->_items->_items[i]; + if (item->_setId == setId) { + _vm->_sceneObjects->addItem(item->_itemId + SCENE_OBJECTS_ITEMS_OFFSET, &item->_boundingBox, &item->_screenRectangle, item->isTargetable(), item->_isVisible); + } + } + return true; +} + bool Items::remove(int itemId) { if (_items.size() == 0) { return false; } int itemIndex = findItem(itemId); - if(itemIndex == -1) { + if (itemIndex == -1) { return false; } diff --git a/engines/bladerunner/items.h b/engines/bladerunner/items.h index 0b5c7e09a9..667117fba2 100644 --- a/engines/bladerunner/items.h +++ b/engines/bladerunner/items.h @@ -40,12 +40,13 @@ public: ~Items(); void getXYZ(int itemId, float *x, float *y, float *z); - void getWidthHeight(int itemId, int * width, int * height); + void getWidthHeight(int itemId, int *width, int *height); void tick(); - bool add(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTargetable, bool isVisible, bool isPoliceMazeEnemy, bool b); + bool addToWorld(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTargetable, bool isVisible, bool isPoliceMazeEnemy, bool b); + bool addToSet(int itemId); bool remove(int itemId); - + private: int findItem(int itemId); }; diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp index f9a112eff5..a629b4263b 100644 --- a/engines/bladerunner/scene.cpp +++ b/engines/bladerunner/scene.cpp @@ -28,6 +28,7 @@ #include "bladerunner/adq.h" #include "bladerunner/chapters.h" #include "bladerunner/gameinfo.h" +#include "bladerunner/items.h" #include "bladerunner/scene_objects.h" #include "bladerunner/script/script.h" #include "bladerunner/slice_renderer.h" @@ -54,12 +55,12 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) { // TODO: Reset aesc // TODO: Clear regions // TODO: Destroy all overlays - _defaultLoop = 0; - _defaultLoopSet = 0; - _field_20_loop_stuff = 0; - _specialLoopMode = -1; - _specialLoop = -1; - _frame = -1; + _defaultLoop = 0; + _defaultLoopSet = 0; + _field_20_loop_stuff = 0; + _specialLoopMode = -1; + _specialLoop = -1; + _frame = -1; } Common::String vqaName; @@ -114,23 +115,25 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) { Actor *actor = _vm->_actors[i]; if (actor->getSetId() == setId) { _vm->_sceneObjects->addActor( - i, - actor->getBoundingBox(), - actor->getScreenRectangle(), - 1, - 0, - actor->isTargetable(), - actor->isRetired()); + i, + actor->getBoundingBox(), + actor->getScreenRectangle(), + 1, + 0, + actor->isTargetable(), + actor->isRetired()); } } _set->addObjectsToScene(_vm->_sceneObjects); + _vm->_items->addToSet(setId); + _vm->_sceneObjects->updateObstacles(); // TODO: add all items to scene // TODO: calculate walking obstacles?? - if (_specialLoopMode) { - _vm->_script->PlayerWalkedIn(); - } + if (_specialLoopMode) { + _vm->_script->PlayerWalkedIn(); + } return true; } @@ -144,10 +147,10 @@ bool Scene::close(bool isLoadingGame) { //_vm->_policeMaze->clear(!isLoadingGame); if (isLoadingGame) { _vm->_script->PlayerWalkedOut(); - } -// if (SceneScript_isLoaded() && !SceneScript_unload()) { -// result = false; -// } + } + // if (SceneScript_isLoaded() && !SceneScript_unload()) { + // result = false; + // } if (_vqaPlayer != nullptr) { //_vqaPlayer->stop(); delete _vqaPlayer; @@ -163,7 +166,7 @@ int Scene::advanceFrame(Graphics::Surface &surface, uint16 *&zBuffer) { int frame = _vqaPlayer->update(); if (frame >= 0) { surface.copyFrom(*_vqaPlayer->getSurface()); - memcpy(zBuffer, _vqaPlayer->getZBuffer(), 640*480*2); + memcpy(zBuffer, _vqaPlayer->getZBuffer(), 640 * 480 * 2); _vqaPlayer->updateView(_vm->_view); _vqaPlayer->updateLights(_vm->_lights); } @@ -220,7 +223,7 @@ bool Scene::objectSetHotMouse(int objectId) { return _set->objectSetHotMouse(objectId); } -bool Scene::objectGetBoundingBox(int objectId, BoundingBox* boundingBox) { +bool Scene::objectGetBoundingBox(int objectId, BoundingBox *boundingBox) { return _set->objectGetBoundingBox(objectId, boundingBox); } @@ -235,7 +238,7 @@ void Scene::objectSetIsObstacle(int objectId, bool isObstacle, bool sceneLoaded, _set->objectSetIsObstacle(objectId, isObstacle); if (sceneLoaded) { _vm->_sceneObjects->setIsObstacle(objectId + 198, isObstacle); - if(updateWalkpath) { + if (updateWalkpath) { _vm->_sceneObjects->updateObstacles(); } } diff --git a/engines/bladerunner/script/rc01.cpp b/engines/bladerunner/script/rc01.cpp index ebb67b75f3..d94f104403 100644 --- a/engines/bladerunner/script/rc01.cpp +++ b/engines/bladerunner/script/rc01.cpp @@ -202,9 +202,6 @@ bool ScriptRC01::MouseClick(int x, int y) { } bool ScriptRC01::ClickedOn3DObject(const char *objectName, bool a2) { -#if _DEBUG - Item_Pickup_Spin_Effect(938, 426, 316); -#endif if (Object_Query_Click("BARICADE01", objectName) || Object_Query_Click("BARICADE03", objectName) || Object_Query_Click("BARICADE04", objectName) diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp index 9e11402b5f..cf607a4b47 100644 --- a/engines/bladerunner/script/script.cpp +++ b/engines/bladerunner/script/script.cpp @@ -662,7 +662,7 @@ void ScriptBase::Actor_Set_Immunity_To_Obstacles(int actorId, bool isImmune) { } void ScriptBase::Item_Add_To_World(int itemId, int animationId, int setId, float x, float y, float z, signed int facing, int height, int width, bool isTargetable, bool isObstacle, bool isPoliceMazeEnemy, bool updateOnly) { - _vm->_items->add(itemId, animationId, setId, Vector3(x, y, z), facing, height, width, isTargetable, isObstacle, isPoliceMazeEnemy, updateOnly == 0); + _vm->_items->addToWorld(itemId, animationId, setId, Vector3(x, y, z), facing, height, width, isTargetable, isObstacle, isPoliceMazeEnemy, updateOnly == 0); } void ScriptBase::Item_Remove_From_World(int itemId) { diff --git a/engines/bladerunner/slice_renderer.cpp b/engines/bladerunner/slice_renderer.cpp index 510f029295..f8d9a48dfc 100644 --- a/engines/bladerunner/slice_renderer.cpp +++ b/engines/bladerunner/slice_renderer.cpp @@ -27,33 +27,13 @@ #include "bladerunner/set_effects.h" #include "bladerunner/slice_animations.h" -#include "common/debug.h" #include "common/memstream.h" #include "common/rect.h" #include "common/util.h" namespace BladeRunner { -#if 0 -void dump(const char *str, Vector3 v) { - debug("%s %g %g %g", str, v.x, v.y, v.z); -} - -void dump(const char *str, Matrix3x2 m) { - debug("%s", str); - debug("%11.6g %11.6g %11.6g", m(0, 0), m(0, 1), m(0, 2)); - debug("%11.6g %11.6g %11.6g", m(1, 0), m(1, 1), m(1, 2)); -} - -void dump(const char *str, Matrix4x3 m) { - debug("%s", str); - debug("%11.6g %11.6g %11.6g %11.6g", m(0, 0), m(0, 1), m(0, 2), m(0, 3)); - debug("%11.6g %11.6g %11.6g %11.6g", m(1, 0), m(1, 1), m(1, 2), m(1, 3)); - debug("%11.6g %11.6g %11.6g %11.6g", m(2, 0), m(2, 1), m(2, 2), m(2, 3)); -} -#endif - -SliceRenderer::SliceRenderer(BladeRunnerEngine* vm) { +SliceRenderer::SliceRenderer(BladeRunnerEngine *vm) { _vm = vm; _pixelFormat = createRGB555(); int i; @@ -70,37 +50,30 @@ void SliceRenderer::setView(const View &view) { _view = view; } -void SliceRenderer::setLights(Lights* lights){ +void SliceRenderer::setLights(Lights *lights) { _lights = lights; } -void SliceRenderer::setSetEffects(SetEffects* setEffects){ +void SliceRenderer::setSetEffects(SetEffects *setEffects) { _setEffects = setEffects; } -void SliceRenderer::setupFrame(int animation, int frame, Vector3 position, float facing, float scale) { - _animation = animation; - _frame = frame; +void SliceRenderer::setupFrameInWorld(int animationId, int animationFrame, Vector3 position, float facing, float scale) { _position = position; _facing = facing; _scale = scale; - _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(); + 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); @@ -122,10 +95,10 @@ Matrix3x2 SliceRenderer::calculateFacingRotationMatrix() { void SliceRenderer::calculateBoundingRect() { assert(_sliceFramePtr); - _minX = 0.0f; - _maxX = 0.0f; - _minY = 0.0f; - _maxY = 0.0f; + _screenRectangle.left = 0; + _screenRectangle.right = 0; + _screenRectangle.top = 0; + _screenRectangle.bottom = 0; Matrix4x3 viewMatrix = _view._sliceViewMatrix; @@ -142,13 +115,13 @@ void SliceRenderer::calculateBoundingRect() { Matrix3x2 facingRotation = calculateFacingRotationMatrix(); - Matrix3x2 m4(_view._viewportDistance / bottom.z, 0.0f, 0.0f, - 0.0f, 25.5f, 0.0f); + Matrix3x2 m_projection(_view._viewportDistance / bottom.z, 0.0f, 0.0f, + 0.0f, 25.5f, 0.0f); - Matrix3x2 m2(_frameScale.x, 0.0f, _framePos.x, - 0.0f, _frameScale.y, _framePos.y); + Matrix3x2 m_frame(_frameScale.x, 0.0f, _framePos.x, + 0.0f, _frameScale.y, _framePos.y); - _field_109E = m4 * (facingRotation * m2); + _modelMatrix = m_projection * (facingRotation * m_frame); Vector4 startScreenVector( _view._viewportHalfWidth + top.x / top.z * _view._viewportDistance, @@ -173,8 +146,9 @@ void SliceRenderer::calculateBoundingRect() { Vector4 delta = endScreenVector - startScreenVector; - if (delta.y == 0.0f) + if (delta.y == 0.0f) { return; + } /* * Calculate min and max Y @@ -212,8 +186,8 @@ void SliceRenderer::calculateBoundingRect() { * Calculate min and max X */ - Matrix3x2 mB6 = _field_109E + Vector2(startScreenVector.x, 25.5f / startScreenVector.z); - Matrix3x2 mC2 = _field_109E + Vector2(endScreenVector.x, 25.5f / endScreenVector.z); + 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; @@ -232,8 +206,8 @@ 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); + 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; @@ -244,10 +218,27 @@ void SliceRenderer::calculateBoundingRect() { _startSlice = startScreenVector.w; _endSlice = endScreenVector.w; - _minX = bbox_min_x; - _minY = bbox_min_y; - _maxX = bbox_max_x; - _maxY = bbox_max_y; + _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 { @@ -348,14 +339,14 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos assert(_setEffects); //assert(_view); - _vm->_sliceRenderer->setupFrame(animationId, animationFrame, position, facing); + _vm->_sliceRenderer->setupFrameInWorld(animationId, animationFrame, position, facing); SliceLineIterator sliceLineIterator; sliceLineIterator.setup( _endScreenVector.x, _endScreenVector.y, _endScreenVector.z, _startScreenVector.x, _startScreenVector.y, _startScreenVector.z, _endSlice, _startSlice, - _field_109E // 3x2 matrix + _modelMatrix ); SliceRendererLights sliceRendererLights = SliceRendererLights(_lights); @@ -388,8 +379,11 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos 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 @@ -401,9 +395,6 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos uint16 *zBufferLinePtr = zbuffer + 640 * frameY; 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)); @@ -424,8 +415,9 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos _setEffectColor.g = setEffectColor.g * 31.0f * 65536.0f; _setEffectColor.b = setEffectColor.b * 31.0f * 65536.0f; - if (frameY >= 0 && frameY < 480) + if (frameY >= 0 && frameY < 480) { drawSlice((int)sliceLine, true, frameLinePtr, zBufferLinePtr); + } sliceLineIterator.advance(); frameY += 1; @@ -437,28 +429,13 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos 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; - } - _animation = -1;// animationId; - _frame = animationFrame; + } _position.x = 0; _position.y = 0; _position.z = 0; _facing = facing; - _sliceFramePtr = _vm->_sliceAnimations->getFramePtr(animationId, animationFrame); - if (_sliceFramePtr == nullptr) { - return; - } - - Common::MemoryReadStream stream((byte*)_sliceFramePtr, _vm->_sliceAnimations->_animations[animationId].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(); + + 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); @@ -493,7 +470,7 @@ void SliceRenderer::drawOnScreen(int animationId, int animationFrame, int screen int frameY = screenY + (size / 2.0f * frameHeight); int currentY = frameY; - + float currentSlice = 0; float sliceStep = 1.0f / size / _frameSliceHeight; @@ -591,21 +568,20 @@ SliceRenderer::SliceRendererLights::SliceRendererLights(Lights *lights) { _lights = lights; - for(int i = 0; i < 20; i++) { + 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) { - for(uint i = 0; i < _lights->_lights.size(); i++) { + for (uint i = 0; i < _lights->_lights.size(); i++) { Light *light = _lights->_lights[i]; if (i < 20) { float v8 = light->calculate(position1, position2/*, height*/); diff --git a/engines/bladerunner/slice_renderer.h b/engines/bladerunner/slice_renderer.h index 7e8c2b71aa..d1659ec191 100644 --- a/engines/bladerunner/slice_renderer.h +++ b/engines/bladerunner/slice_renderer.h @@ -28,6 +28,8 @@ #include "bladerunner/view.h" #include "bladerunner/matrix.h" +#include "common/rect.h" + #include "graphics/surface.h" namespace Common { @@ -49,7 +51,7 @@ class SliceRenderer { float _facing; float _scale; - View _view; + View _view; Lights *_lights; SetEffects *_setEffects; @@ -63,15 +65,12 @@ class SliceRenderer { uint32 _framePaletteIndex; uint32 _frameSliceCount; - Matrix3x2 _field_109E; - Vector3 _startScreenVector; - Vector3 _endScreenVector; - float _startSlice; - float _endSlice; - int _minX; - int _maxX; - int _minY; - int _maxY; + Matrix3x2 _modelMatrix; + Vector3 _startScreenVector; + Vector3 _endScreenVector; + float _startSlice; + float _endSlice; + Common::Rect _screenRectangle; int _m11lookup[256]; int _m12lookup[256]; @@ -98,10 +97,10 @@ public: void setLights(Lights *lights); void setSetEffects(SetEffects *setEffects); - void setupFrame(int animation, int frame, Vector3 position, float facing, float scale = 1.0f); - void calculateBoundingRect(); - + 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, uint16 *zbuffer); void preload(int animationId); @@ -109,6 +108,10 @@ public: void disableShadows(int *animationsIdsList, int listSize); private: + + void calculateBoundingRect(); + void loadFrame(int animation, int frame); + class SliceRendererLights { Lights *_lights; Color _colors[20]; |