diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/bladerunner/actor.cpp | 2 | ||||
-rw-r--r-- | engines/bladerunner/bladerunner.cpp | 16 | ||||
-rw-r--r-- | engines/bladerunner/bladerunner.h | 2 | ||||
-rw-r--r-- | engines/bladerunner/font.cpp | 37 | ||||
-rw-r--r-- | engines/bladerunner/item.cpp | 2 | ||||
-rw-r--r-- | engines/bladerunner/item_pickup.cpp | 108 | ||||
-rw-r--r-- | engines/bladerunner/item_pickup.h | 61 | ||||
-rw-r--r-- | engines/bladerunner/module.mk | 1 | ||||
-rw-r--r-- | engines/bladerunner/script/rc01.cpp | 3 | ||||
-rw-r--r-- | engines/bladerunner/script/script.cpp | 8 | ||||
-rw-r--r-- | engines/bladerunner/slice_renderer.cpp | 98 | ||||
-rw-r--r-- | engines/bladerunner/slice_renderer.h | 8 |
12 files changed, 298 insertions, 48 deletions
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp index f6ce1c0414..8ead0d4a76 100644 --- a/engines/bladerunner/actor.cpp +++ b/engines/bladerunner/actor.cpp @@ -510,7 +510,7 @@ void Actor::draw() { // TODO: Handle SHORTY mode - _vm->_sliceRenderer->drawFrame(_animationId, _animationFrame, drawPosition, drawAngle, drawScale, _vm->_surface2, _vm->_zBuffer2); + _vm->_sliceRenderer->drawInWorld(_animationId, _animationFrame, drawPosition, drawAngle, drawScale, _vm->_surface2, _vm->_zBuffer2); //todo udpate screenrect } diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp index fb8751c758..1f05046f2d 100644 --- a/engines/bladerunner/bladerunner.cpp +++ b/engines/bladerunner/bladerunner.cpp @@ -34,6 +34,7 @@ #include "bladerunner/gameflags.h" #include "bladerunner/gameinfo.h" #include "bladerunner/image.h" +#include "bladerunner/item_pickup.h" #include "bladerunner/items.h" #include "bladerunner/lights.h" #include "bladerunner/mouse.h" @@ -77,6 +78,7 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst) _combat = new Combat(this); _adq = new ADQ(this); _obstacles = new Obstacles(this); + _itemPickup = new ItemPickup(this); _walkSoundId = -1; _walkSoundVolume = 0; @@ -104,6 +106,7 @@ BladeRunnerEngine::~BladeRunnerEngine() { // delete[] _zBuffer1; // delete[] _zBuffer2; + delete _itemPickup; delete _obstacles; delete _adq; delete _combat; @@ -158,6 +161,8 @@ bool BladeRunnerEngine::startup(bool hasSavegames) { if (!r) return false; + // TODO: Create datetime - not used + // TODO: Create graphics surfaces 1-4 // TODO: Allocate audio cache @@ -463,9 +468,10 @@ void BladeRunnerEngine::shutdown() { // TODO: Delete KIA - // TODO: Delete SDB + delete _suspectsDatabase; + _suspectsDatabase = nullptr; - // TODO: Delete unknown stuff + // TODO: Delete datetime - not used // TODO: Delete actors @@ -614,7 +620,9 @@ void BladeRunnerEngine::gameTick() { _items->tick(); - // TODO: Draw item pickup + _itemPickup->tick(); + _itemPickup->draw(); + // TODO: Draw dialogue menu Common::Point p = _eventMan->getMousePos(); @@ -630,7 +638,7 @@ void BladeRunnerEngine::gameTick() { _walkSoundId = -1; } -#if _DEBUG +#if false //draw scene objects int count = _sceneObjects->_count; if (count > 0) { diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h index 3546fa8fce..3c9cc2aae9 100644 --- a/engines/bladerunner/bladerunner.h +++ b/engines/bladerunner/bladerunner.h @@ -48,6 +48,7 @@ class Combat; class Font; class GameFlags; class GameInfo; +class ItemPickup; class Items; class Lights; class Mouse; @@ -79,6 +80,7 @@ public: Combat *_combat; GameFlags *_gameFlags; GameInfo *_gameInfo; + ItemPickup *_itemPickup; Items *_items; Lights *_lights; Font *_mainFont; diff --git a/engines/bladerunner/font.cpp b/engines/bladerunner/font.cpp index 972f50a784..124e9c967e 100644 --- a/engines/bladerunner/font.cpp +++ b/engines/bladerunner/font.cpp @@ -68,7 +68,7 @@ bool Font::open(const Common::String &fileName, int screenWidth, int screenHeigh _characters[i]._height = stream->readUint32LE(); _characters[i]._dataOffset = stream->readUint32LE(); } - for(int i = 0; i < _dataSize; i++) { + for (int i = 0; i < _dataSize; i++) { _data[i] = stream->readUint16LE(); } return true; @@ -100,20 +100,8 @@ void Font::draw(const Common::String &text, Graphics::Surface &surface, int x, i return; } - if (x < 0) { - x = 0; - } - if (y < 0) { - y = 0; - } - - int textWidth = getTextWidth(text); - if (textWidth + x >= _screenWidth) { - x = _screenWidth - (textWidth + 1); - } - if (_maxHeight + y >= _screenHeight) { - y = _screenHeight - _maxHeight; - } + x = CLIP(x, 0, _screenWidth - getTextWidth(text) + 1); + y = CLIP(y, 0, _screenHeight - _maxHeight); const char *character = text.c_str(); while (*character != 0) { @@ -176,16 +164,17 @@ void Font::replaceColor(uint16 oldColor, uint16 newColor) { } void Font::drawCharacter(const char character, Graphics::Surface &surface, int x, int y) { - if (x < 0 || x >= _screenWidth || y < 0 || y >= _screenHeight || !_data || character + 1 >= _characterCount) { + char characterIndex = character + 1; + if (x < 0 || x >= _screenWidth || y < 0 || y >= _screenHeight || !_data || characterIndex >= _characterCount) { return; } - uint16 *dstPtr = (uint16*)surface.getBasePtr(x + _characters[character + 1]._x, y + _characters[character + 1]._y); - uint16 *srcPtr = &_data[_characters[character + 1]._dataOffset]; - int width = _characters[character + 1]._width; - int height = _characters[character + 1]._height; + uint16 *dstPtr = (uint16*)surface.getBasePtr(x + _characters[characterIndex]._x, y + _characters[characterIndex]._y); + uint16 *srcPtr = &_data[_characters[characterIndex]._dataOffset]; + int width = _characters[characterIndex]._width; + int height = _characters[characterIndex]._height; if (_intersperse && y & 1) { - dstPtr += surface.w; + dstPtr += surface.pitch / 2; } int endY = height + y - 1; @@ -194,17 +183,17 @@ void Font::drawCharacter(const char character, Graphics::Surface &surface, int x int currentX = x; int endX = width + x - 1; while (currentX <= endX && currentX < _screenWidth) { - if (!(*srcPtr & 0x8000)) { + if ((*srcPtr & 0x8000) == 0) { *dstPtr = *srcPtr; } dstPtr++; srcPtr++; currentX++; } - dstPtr += surface.w - width; + dstPtr += surface.pitch / 2 - width; if (_intersperse) { srcPtr += width; - dstPtr += surface.w; + dstPtr += surface.pitch / 2; currentY++; } currentY++; diff --git a/engines/bladerunner/item.cpp b/engines/bladerunner/item.cpp index 00f98d35b8..0a616d4385 100644 --- a/engines/bladerunner/item.cpp +++ b/engines/bladerunner/item.cpp @@ -79,7 +79,7 @@ void Item::tick(bool special) { if (_isVisible) { Vector3 postition(_position.x, -_position.z, _position.y); int animationId = _animationId + (special ? 1 : 0); - _vm->_sliceRenderer->drawFrame(animationId, 0, postition, M_PI - _angle, 1.0f, _vm->_surface2, _vm->_zBuffer2); + _vm->_sliceRenderer->drawInWorld(animationId, 0, postition, M_PI - _angle, 1.0f, _vm->_surface2, _vm->_zBuffer2); //todo udpate screenrect if (_isSpinning) { _facing += _facingChange; diff --git a/engines/bladerunner/item_pickup.cpp b/engines/bladerunner/item_pickup.cpp new file mode 100644 index 0000000000..ff5f5e9763 --- /dev/null +++ b/engines/bladerunner/item_pickup.cpp @@ -0,0 +1,108 @@ +/* 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/item_pickup.h" + +#include "bladerunner/bladerunner.h" + +#include "bladerunner/audio_player.h" +#include "bladerunner/gameinfo.h" +#include "slice_animations.h" +#include "slice_renderer.h" + +namespace BladeRunner { + +ItemPickup::ItemPickup(BladeRunnerEngine *vm) { + _vm = vm; + _facingStep = float(1.0f / 3000.0f * M_PI); + reset(); +} + +ItemPickup::~ItemPickup() { +} + +void ItemPickup::setup(int animationId, int screenX, int screenY) { + _animationId = animationId; + _animationFrame = 0; + _facing = 0.0; + _timeLeft = 3000; + _scale = 0; + _screenX = CLIP(screenX, 40, 600); + _screenY = CLIP(screenY, 40, 440); + _screenRect.left = _screenX - 40; + _screenRect.right = _screenX + 40; + _screenRect.top = _screenY - 40; + _screenRect.bottom = _screenY + 40; + + int pan = (150 * _screenX - 48000) / 640; + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(335), 80, pan, pan, 50, 0); + + _timeLast = _vm->getTotalPlayTime(); +} + +void ItemPickup::reset() { + _animationId = -1; + _screenX = 0; + _screenY = 0; + _facing = 0.0f; + _scale = 1.0f; + _animationFrame = 0; + _timeLeft = 0; + _timeLast = 0; +} + +void ItemPickup::tick() { + if (_timeLeft == 0) { + return; + } + + int timeNow = _vm->getTotalPlayTime(); + int timeDiff = timeNow - _timeLast; + _timeLast = timeNow; + timeDiff = MIN(MIN(timeDiff, 67), _timeLeft); + _timeLeft -= timeDiff; + + if (_timeLeft >= 2000) { + _scale = 1.0f - (((2000.0f - _timeLeft) / 1000.0f) * ((2000.0f - _timeLeft) / 1000.0f)); + } else if (_timeLeft < 1000) { + _scale = 1.0f - (((1000.0f - _timeLeft) / 1000.0f) * ((1000.0f - _timeLeft) / 1000.0f)); + } else { + _scale = 1.0f; + } + _scale *= 75.0f; + + _facing += _facingStep * timeDiff; + if (_facing > float(2.0f * M_PI)) { + _facing -= float(2.0f * M_PI); + } + + _animationFrame = (_animationFrame + 1) % _vm->_sliceAnimations->getFrameCount(_animationId); +} + +void ItemPickup::draw() { + if (_timeLeft == 0) { + return; + } + + _vm->_sliceRenderer->drawOnScreen(_animationId, _animationFrame, _screenX, _screenY, _facing, _scale, _vm->_surface2, _vm->_zBuffer2); +} +} // End of namespace BladeRunner diff --git a/engines/bladerunner/item_pickup.h b/engines/bladerunner/item_pickup.h new file mode 100644 index 0000000000..0e7bc516ea --- /dev/null +++ b/engines/bladerunner/item_pickup.h @@ -0,0 +1,61 @@ +/* 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. + * + */ + +#ifndef BLADERUNNER_ITEMPICKUP_H +#define BLADERUNNER_ITEMPICKUP_H + +#include "common/rect.h" +#include "graphics/surface.h" + +namespace BladeRunner { + +class BladeRunnerEngine; + +class ItemPickup { + BladeRunnerEngine *_vm; + + float _facingStep; + + int _animationId; + int _screenX; + int _screenY; + float _facing; + float _scale; + int _animationFrame; + int _timeLeft; + int _timeLast; + Common::Rect _screenRect; + +public: + ItemPickup(BladeRunnerEngine *vm); + ~ItemPickup(); + + void setup(int animationId, int screenX, int screenY); + void reset(); + + void tick(); + void draw(); +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk index 85dd8d5388..fb656efac1 100644 --- a/engines/bladerunner/module.mk +++ b/engines/bladerunner/module.mk @@ -26,6 +26,7 @@ MODULE_OBJS = \ gameinfo.o \ image.o \ item.o \ + item_pickup.o \ items.o \ light.o \ lights.o \ diff --git a/engines/bladerunner/script/rc01.cpp b/engines/bladerunner/script/rc01.cpp index d94f104403..ebb67b75f3 100644 --- a/engines/bladerunner/script/rc01.cpp +++ b/engines/bladerunner/script/rc01.cpp @@ -202,6 +202,9 @@ 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 8c6afc6b16..9e11402b5f 100644 --- a/engines/bladerunner/script/script.cpp +++ b/engines/bladerunner/script/script.cpp @@ -34,6 +34,8 @@ #include "bladerunner/combat.h" #include "bladerunner/gameflags.h" #include "bladerunner/gameinfo.h" +#include "bladerunner/items.h" +#include "bladerunner/item_pickup.h" #include "bladerunner/movement_track.h" #include "bladerunner/settings.h" #include "bladerunner/set_effects.h" @@ -47,7 +49,6 @@ #include "bladerunner/script/ai_00_mccoy.h" #include "bladerunner/script/aiscript_officer_leroy.h" -#include "bladerunner/items.h" namespace BladeRunner { @@ -680,9 +681,8 @@ void ScriptBase::Item_Flag_As_Non_Target(int itemId) { warning("Item_Flag_As_Non_Target(%d)", itemId); } -void ScriptBase::Item_Pickup_Spin_Effect(int a1, int a2, int a3) { - //TODO - warning("Item_Pickup_Spin_Effect(%d, %d, %d)", a1, a2, a3); +void ScriptBase::Item_Pickup_Spin_Effect(int animationId, int x, int y) { + _vm->_itemPickup->setup(animationId, x, y); } int ScriptBase::Animation_Open() { diff --git a/engines/bladerunner/slice_renderer.cpp b/engines/bladerunner/slice_renderer.cpp index 0972598eca..6398b2cbf4 100644 --- a/engines/bladerunner/slice_renderer.cpp +++ b/engines/bladerunner/slice_renderer.cpp @@ -342,7 +342,7 @@ static void setupLookupTable(int t[256], int inc) { } } -void SliceRenderer::drawFrame(int animationId, int animationFrame, Vector3 position, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer) { +void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 position, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer) { assert(_sliceFramePtr); assert(_lights); assert(_setEffects); @@ -425,7 +425,7 @@ void SliceRenderer::drawFrame(int animationId, int animationFrame, Vector3 posit _setEffectColor.b = setEffectColor.b * 31.0f * 65536.0f; if (frameY >= 0 && frameY < 480) - drawSlice((int)sliceLine, frameLinePtr, zBufferLinePtr); + drawSlice((int)sliceLine, true, frameLinePtr, zBufferLinePtr); sliceLineIterator.advance(); frameY += 1; @@ -434,7 +434,83 @@ void SliceRenderer::drawFrame(int animationId, int animationFrame, Vector3 posit } } -void SliceRenderer::drawSlice(int slice, uint16 *frameLinePtr, uint16 *zbufLinePtr) { +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(); + + float v47 = _frameSliceHeight * _frameSliceCount; + float v50 = sqrtf(_frameScale.x * 255.0f * _frameScale.x * 255.0f + _frameScale.y * 255.0f * _frameScale.y * 255.0f); + float v16 = MAX(v50, v47); + float v51 = scale / v16; + + 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_v51_25_5(v51, 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_v51_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); + + float v32 = 1.0f / v51 / _frameSliceHeight; + float currentSlice = 0;// _frameSliceCount; + + int frameY = screenY + (v51 / 2.0f * v47); + int currentY = frameY; + 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 += v32; + currentY--; + frameLinePtr -= 640; + } + } +} + +void SliceRenderer::drawSlice(int slice, bool advanced, uint16 *frameLinePtr, uint16 *zbufLinePtr) { if (slice < 0 || (uint32)slice >= _frameSliceCount) return; @@ -467,16 +543,18 @@ void SliceRenderer::drawSlice(int slice, uint16 *frameLinePtr, uint16 *zbufLineP int vertexZ = (_m21lookup[p[0]] + _m22lookup[p[1]] + _m23) >> 6; if (vertexZ >= 0 && vertexZ < 65536) { - 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 color555 = palette.color555[p[2]]; + if (advanced) { + Color256 color = palette.color[p[2]]; - int bladeToScummVmConstant = 256 / 32; + 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 color555 = _pixelFormat.RGBToColor(CLIP(color.r * bladeToScummVmConstant, 0, 255), CLIP(color.g * bladeToScummVmConstant, 0, 255), CLIP(color.b * bladeToScummVmConstant, 0, 255)); + 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; diff --git a/engines/bladerunner/slice_renderer.h b/engines/bladerunner/slice_renderer.h index c1c0dc4603..7e8c2b71aa 100644 --- a/engines/bladerunner/slice_renderer.h +++ b/engines/bladerunner/slice_renderer.h @@ -88,7 +88,7 @@ class SliceRenderer { Graphics::PixelFormat _pixelFormat; Matrix3x2 calculateFacingRotationMatrix(); - void drawSlice(int slice, uint16 *frameLinePtr, uint16 *zbufLinePtr); + void drawSlice(int slice, bool advanced, uint16 *frameLinePtr, uint16 *zbufLinePtr); public: SliceRenderer(BladeRunnerEngine *vm); @@ -100,9 +100,9 @@ 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(int animationId, int animationFrame, Vector3 position, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer); + + 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); |