aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPeter Kohaut2017-08-26 21:27:54 +0200
committerPeter Kohaut2017-08-26 23:00:54 +0200
commita97fe8f89fa4f3f78e876c26c7cfdab3cad1d8e8 (patch)
tree6b4bb3cab87863a74973936ac275935f1014d284 /engines
parentf8284623c4d4d2a20ee12d35b9ebc6320fa30115 (diff)
downloadscummvm-rg350-a97fe8f89fa4f3f78e876c26c7cfdab3cad1d8e8.tar.gz
scummvm-rg350-a97fe8f89fa4f3f78e876c26c7cfdab3cad1d8e8.tar.bz2
scummvm-rg350-a97fe8f89fa4f3f78e876c26c7cfdab3cad1d8e8.zip
BLADERUNNER: Support for AESC
Diffstat (limited to 'engines')
-rw-r--r--engines/bladerunner/aesc.cpp139
-rw-r--r--engines/bladerunner/aesc.h68
-rw-r--r--engines/bladerunner/bladerunner.cpp69
-rw-r--r--engines/bladerunner/bladerunner.h2
-rw-r--r--engines/bladerunner/module.mk1
-rw-r--r--engines/bladerunner/scene.cpp1
-rw-r--r--engines/bladerunner/slice_renderer.cpp28
-rw-r--r--engines/bladerunner/slice_renderer.h5
-rw-r--r--engines/bladerunner/view.cpp2
-rw-r--r--engines/bladerunner/view.h2
-rw-r--r--engines/bladerunner/vqa_decoder.cpp60
-rw-r--r--engines/bladerunner/vqa_decoder.h11
-rw-r--r--engines/bladerunner/vqa_player.cpp4
-rw-r--r--engines/bladerunner/vqa_player.h1
14 files changed, 341 insertions, 52 deletions
diff --git a/engines/bladerunner/aesc.cpp b/engines/bladerunner/aesc.cpp
new file mode 100644
index 0000000000..d653d1df35
--- /dev/null
+++ b/engines/bladerunner/aesc.cpp
@@ -0,0 +1,139 @@
+/* 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/aesc.h"
+
+#include "common/stream.h"
+
+namespace BladeRunner {
+
+AESC::AESC(BladeRunnerEngine *vm, int size) : _vm(vm) {
+ _dataSize = size;
+ _data = new uint8[size];
+ _entries.reserve(8);
+}
+
+AESC::~AESC() {
+ delete[] _data;
+}
+
+void AESC::readVqa(Common::SeekableReadStream *stream) {
+ uint8* dataPtr = _data;
+ int dataSize = _dataSize;
+
+ int entriesCount = stream->readUint32LE();
+
+ if (entriesCount == 0) {
+ return;
+ }
+
+ entriesCount = MIN(entriesCount, 7);
+ _entries.resize(entriesCount);
+
+ for (Common::Array<Entry>::iterator entry = _entries.begin(); entry != _entries.end(); entry++) {
+ stream->read(&entry->palette, sizeof(Color256) * 16);
+
+ entry->x = stream->readUint16LE();
+ entry->y = stream->readUint16LE();
+ entry->width = stream->readUint16LE();
+ entry->height = stream->readUint16LE();
+ entry->z = stream->readUint16LE();
+
+ int entryDataSize = stream->readUint16LE();
+
+ int pixelCount = entry->width * entry->height;
+
+ if (pixelCount > dataSize) { // to big to fit
+ entry->width = 0;
+ entry->height = 0;
+ entry->data = _data;
+ continue;
+ // there is a issue in the game code, because it's not skipping data of entry in this case
+ }
+
+ int pos = stream->pos();
+ dataSize -= pixelCount;
+ entry->data = dataPtr;
+ do {
+ uint8 count = stream->readByte();
+ if (count & 0x80) { // repeat same data
+ uint8 colors = stream->readByte();
+ for (uint8 j = 0; j < (count & 0x7F) + 1; j++) {
+ *(dataPtr++) = colors >> 4; // upper 4 bit
+ *(dataPtr++) = colors & 0xF; // lower 4 bit
+ pixelCount -= 2;
+ }
+ } else { // copy data
+ for (uint8 j = 0; j < count + 1; j++) {
+ uint8 colors = stream->readByte();
+ *(dataPtr++) = colors >> 4; // upper 4 bit
+ *(dataPtr++) = colors & 0xF; // lower 4 bit
+ pixelCount -= 2;
+ }
+ }
+ } while (pixelCount > 0);
+ stream->seek(pos + entryDataSize, SEEK_SET);
+ }
+}
+
+//TODO:
+//bool AESC::isAffectingArea(int x, int y, int width, int height, int z) {
+// int xx = x >> 1;
+// int yy = y >> 1;
+// if (_entries.empty()) {
+// return false;
+// }
+//
+// for(int i = 0; i < _entries.size(); i++) {
+// Entry &entry = _entries[i];
+// if (entry.z < z) {
+// if (entry.width < (width >> 1) + xx) {
+// if (entry.width + entry.x > xx) {
+// if (entry.height < (height >> 1) + yy) {
+// if(entry.height + entry.y > yy) {
+// return true;
+// }
+// }
+// }
+// }
+// }
+// }
+// return false;
+//}
+
+void AESC::getColor(Color256 *outColor, uint16 x, uint16 y, uint16 z) {
+ Color256 color = { 0, 0, 0 };
+ for (Common::Array<Entry>::iterator entry = _entries.begin(); entry != _entries.end(); entry++) {
+ uint16 x1 = (x / 2) - entry->x;
+ uint16 y1 = (y / 2) - entry->y;
+ if ( x1 < entry->width && y1 < entry->height && z > entry->z) {
+ int colorIndex = entry->data[y1 * entry->width + x1];
+ Color256 entryColor = entry->palette[colorIndex];
+ color.r += entryColor.r;
+ color.g += entryColor.g;
+ color.b += entryColor.b;
+ }
+ }
+ *outColor = color;
+}
+
+} // End of namespace BladeRunner
diff --git a/engines/bladerunner/aesc.h b/engines/bladerunner/aesc.h
new file mode 100644
index 0000000000..d3f926b190
--- /dev/null
+++ b/engines/bladerunner/aesc.h
@@ -0,0 +1,68 @@
+/* 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_AESC_H
+#define BLADERUNNER_AESC_H
+
+#include "bladerunner/color.h"
+
+#include "common/array.h"
+
+namespace Common {
+class ReadStream;
+}
+
+namespace BladeRunner {
+class BladeRunnerEngine;
+
+class AESC {
+public:
+ struct Entry
+ {
+ Color256 palette[16];
+ uint16 x;
+ uint16 y;
+ uint16 width;
+ uint16 height;
+ uint16 z;
+ uint8 *data;
+ };
+
+ BladeRunnerEngine *_vm;
+
+ Common::Array<Entry> _entries;
+ uint8 *_data;
+ int _dataSize;
+
+public:
+ AESC(BladeRunnerEngine *vm, int size);
+ ~AESC();
+
+ void readVqa(Common::SeekableReadStream *stream);
+ void getColor(Color256 *outColor, uint16 x, uint16 y, uint16 z);
+
+ //TODO
+ //bool isAffectingArea(int x, int y, int width, int height, int unk);
+};
+} // End of namespace BladeRunner
+
+#endif
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 7fe3f9ed2e..d138360fab 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -24,6 +24,7 @@
#include "bladerunner/actor.h"
#include "bladerunner/adq.h"
+#include "bladerunner/aesc.h"
#include "bladerunner/ambient_sounds.h"
#include "bladerunner/audio_mixer.h"
#include "bladerunner/audio_player.h"
@@ -69,7 +70,6 @@
#include "graphics/pixelformat.h"
-
namespace BladeRunner {
BladeRunnerEngine::BladeRunnerEngine(OSystem *syst)
@@ -79,10 +79,13 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst)
_gameIsRunning = true;
_playerLosesControlCounter = 0;
+ //TODO(peterkohaut): move these to init
+
_crimesDatabase = nullptr;
_sceneScript = new SceneScript(this);
_settings = new Settings(this);
_lights = new Lights(this);
+ _aesc = new AESC(this, 0x8000);
_combat = new Combat(this);
_adq = new ADQ(this);
_obstacles = new Obstacles(this);
@@ -122,6 +125,7 @@ BladeRunnerEngine::~BladeRunnerEngine() {
delete _obstacles;
delete _adq;
delete _combat;
+ delete _aesc;
delete _lights;
delete _settings;
delete _sceneScript;
@@ -325,14 +329,17 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
// TODO: Support cdframes
r = _sliceAnimations->openHDFrames();
- if (!r)
+ if (!r) {
return false;
+ }
r = _sliceAnimations->openCoreAnim();
- if (!r)
+ if (!r) {
return false;
+ }
_sliceRenderer = new SliceRenderer(this);
+ _sliceRenderer->setAESC(_aesc);
_crimesDatabase = new CrimesDatabase(this, "CLUES", _gameInfo->getClueCount());
@@ -703,14 +710,14 @@ void BladeRunnerEngine::gameTick() {
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);
+ drawBBox(a, b, _view, &_surfaceGame, color);
+ _mainFont->drawColor(_textActorNames->getText(sceneObject->_sceneObjectId - SCENE_OBJECTS_ACTORS_OFFSET), _surfaceGame, pos.x, pos.y, color);
break;
case SceneObjectTypeItem:
char itemText[40];
- drawBBox(a, b, _view, &_surface2, color);
+ drawBBox(a, b, _view, &_surfaceGame, color);
sprintf(itemText, "item %i", sceneObject->_sceneObjectId - SCENE_OBJECTS_ITEMS_OFFSET);
- _mainFont->drawColor(itemText, _surface2, pos.x, pos.y, color);
+ _mainFont->drawColor(itemText, _surfaceGame, pos.x, pos.y, color);
break;
case SceneObjectTypeObject:
color = 0b011110111101111;
@@ -719,11 +726,11 @@ void BladeRunnerEngine::gameTick() {
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);
+ drawBBox(a, b, _view, &_surfaceGame, color);
+ _mainFont->drawColor(_scene->objectGetName(sceneObject->_sceneObjectId - SCENE_OBJECTS_OBJECTS_OFFSET), _surfaceGame, pos.x, pos.y, color);
break;
}
- _surface2.frameRect(sceneObject->_screenRectangle, color);
+ _surfaceGame.frameRect(sceneObject->_screenRectangle, color);
}
}
@@ -731,16 +738,15 @@ void BladeRunnerEngine::gameTick() {
for (int i = 0; i < 10; i++) {
Region *region = &_scene->_regions->_regions[i];
if (!region->_present) continue;
- _surface2.frameRect(region->_rectangle, 0b000000000011111);
+ _surfaceGame.frameRect(region->_rectangle, 0b000000000011111);
}
for (int i = 0; i < 10; i++) {
Region *region = &_scene->_exits->_regions[i];
if (!region->_present) continue;
- _surface2.frameRect(region->_rectangle, 0b111111111111111);
+ _surfaceGame.frameRect(region->_rectangle, 0b111111111111111);
}
-
//draw walkboxes
for (int i = 0; i < _scene->_set->_walkboxCount; i++) {
Walkbox *walkbox = &_scene->_set->_walkboxes[i];
@@ -748,9 +754,9 @@ 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]);
- _surface2.drawLine(start.x, start.y, end.x, end.y, 0b111111111100000);
+ _surfaceGame.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);
+ _mainFont->drawColor(walkbox->_name, _surfaceGame, pos.x, pos.y, 0b111111111100000);
}
}
@@ -776,12 +782,12 @@ void BladeRunnerEngine::gameTick() {
int colorB = (light->_color.b * 31.0f);
int color = (colorR << 10) + (colorG << 5) + colorB;
- drawBBox(posOrigin - size, posOrigin + size, _view, &_surface2, color);
+ drawBBox(posOrigin - size, posOrigin + size, _view, &_surfaceGame, 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);
+ _surfaceGame.drawLine(posOriginT.x, posOriginT.y, posTargetT.x, posTargetT.y, color);
+ _mainFont->drawColor(light->_name, _surfaceGame, posOriginT.x, posOriginT.y, color);
}
//draw waypoints
@@ -792,11 +798,34 @@ void BladeRunnerEngine::gameTick() {
Vector3 pos = waypoint->_position;
Vector3 size = Vector3(5.0f, 5.0f, 5.0f);
int color = 0b111111111111111;
- drawBBox(pos - size, pos + size, _view, &_surface2, color);
+ drawBBox(pos - size, pos + size, _view, &_surfaceGame, color);
Vector3 spos = _view->calculateScreenPosition(pos);
char waypointText[40];
sprintf(waypointText, "waypoint %i", i);
- _mainFont->drawColor(waypointText, _surface2, spos.x, spos.y, color);
+ _mainFont->drawColor(waypointText, _surfaceGame, spos.x, spos.y, color);
+ }
+#endif
+#if 0
+ //draw aesc
+ for (uint i = 0; i < _aesc->_entries.size(); i++) {
+ AESC::Entry &entry = _aesc->_entries[i];
+ int j = 0;
+ for (int y = 0; y < entry.height; y++) {
+ for (int x = 0; x < entry.width; x++) {
+ Common::Rect r((entry.x + x) * 2, (entry.y + y) * 2, (entry.x + x) * 2 + 2, (entry.y + y) * 2 + 2);
+
+ int ec = entry.data[j++];
+ Color256 color = entry.palette[ec];
+ int bladeToScummVmConstant = 256 / 16;
+
+ Graphics::PixelFormat _pixelFormat = createRGB555();
+ int color555 = _pixelFormat.RGBToColor(
+ CLIP(color.r * bladeToScummVmConstant, 0, 255),
+ CLIP(color.g * bladeToScummVmConstant, 0, 255),
+ CLIP(color.b * bladeToScummVmConstant, 0, 255));
+ _surfaceGame.fillRect(r, color555);
+ }
+ }
}
#endif
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index 5164f353dd..7118dcce83 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -50,6 +50,7 @@ enum AnimationModes {
class Actor;
class ADQ;
+class AESC;
class AIScripts;
class AmbientSounds;
class AudioMixer;
@@ -92,6 +93,7 @@ public:
int _playerLosesControlCounter;
ADQ *_adq;
+ AESC *_aesc;
AIScripts *_aiScripts;
AmbientSounds *_ambientSounds;
AudioMixer *_audioMixer;
diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk
index 61a95352bf..eeaff45794 100644
--- a/engines/bladerunner/module.mk
+++ b/engines/bladerunner/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/bladerunner
MODULE_OBJS = \
adq.o \
+ aesc.o \
actor.o \
actor_clues.o \
actor_combat.o \
diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp
index 54bc97abe4..de3d89291b 100644
--- a/engines/bladerunner/scene.cpp
+++ b/engines/bladerunner/scene.cpp
@@ -210,6 +210,7 @@ int Scene::advanceFrame() {
blit(_vm->_surfaceInterface, _vm->_surfaceGame);
_vqaPlayer->updateZBuffer(_vm->_zbuffer);
_vqaPlayer->updateView(_vm->_view);
+ _vqaPlayer->updateAESC(_vm->_aesc);
_vqaPlayer->updateLights(_vm->_lights);
}
if (_specialLoopMode && _specialLoopMode != kSceneLoopMode2 && _specialLoopMode != kSceneLoopModeSpinner) {
diff --git a/engines/bladerunner/slice_renderer.cpp b/engines/bladerunner/slice_renderer.cpp
index e0845eeba3..34c910742c 100644
--- a/engines/bladerunner/slice_renderer.cpp
+++ b/engines/bladerunner/slice_renderer.cpp
@@ -22,6 +22,7 @@
#include "bladerunner/slice_renderer.h"
+#include "bladerunner/aesc.h"
#include "bladerunner/bladerunner.h"
#include "bladerunner/lights.h"
#include "bladerunner/set_effects.h"
@@ -46,6 +47,10 @@ SliceRenderer::SliceRenderer(BladeRunnerEngine *vm) {
SliceRenderer::~SliceRenderer() {
}
+void SliceRenderer::setAESC(AESC *aesc) {
+ _aesc = aesc;
+}
+
void SliceRenderer::setView(const View &view) {
_view = view;
}
@@ -349,6 +354,8 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos
_modelMatrix
);
+ Vector3 cameraPosition(_view._cameraPosition.x, _view._cameraPosition.z, _view._cameraPosition.y); // not a bug
+
SliceRendererLights sliceRendererLights = SliceRendererLights(_lights);
_lights->setupFrame(_view._frame);
@@ -364,7 +371,7 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos
float setEffectsColorCoeficient;
Color setEffectColor;
_setEffects->calculateColor(
- _view._cameraPosition,
+ cameraPosition,
Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight),
&setEffectsColorCoeficient,
&setEffectColor);
@@ -401,7 +408,7 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos
if (sliceLineIterator._currentY & 1) {
_setEffects->calculateColor(
- _view._cameraPosition,
+ cameraPosition,
Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight),
&setEffectsColorCoeficient,
&setEffectColor);
@@ -416,7 +423,7 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos
_setEffectColor.b = setEffectColor.b * 31.0f * 65536.0f;
if (frameY >= 0 && frameY < 480) {
- drawSlice((int)sliceLine, true, frameLinePtr, zBufferLinePtr);
+ drawSlice((int)sliceLine, true, frameLinePtr, zBufferLinePtr, frameY);
}
sliceLineIterator.advance();
@@ -480,7 +487,7 @@ void SliceRenderer::drawOnScreen(int animationId, int animationFrame, int screen
while (currentSlice < _frameSliceCount) {
if (currentY >= 0 && currentY < 480) {
memset(lineZbuffer, 0xFF, 640 * 2);
- drawSlice(currentSlice, false, frameLinePtr, lineZbuffer);
+ drawSlice(currentSlice, false, frameLinePtr, lineZbuffer, currentY);
currentSlice += sliceStep;
currentY--;
frameLinePtr -= 640;
@@ -488,7 +495,7 @@ void SliceRenderer::drawOnScreen(int animationId, int animationFrame, int screen
}
}
-void SliceRenderer::drawSlice(int slice, bool advanced, uint16 *frameLinePtr, uint16 *zbufLinePtr) {
+void SliceRenderer::drawSlice(int slice, bool advanced, uint16 *frameLinePtr, uint16 *zbufLinePtr, int y) {
if (slice < 0 || (uint32)slice >= _frameSliceCount)
return;
@@ -523,14 +530,15 @@ void SliceRenderer::drawSlice(int slice, bool advanced, uint16 *frameLinePtr, ui
if (vertexZ >= 0 && vertexZ < 65536) {
int color555 = palette.color555[p[2]];
if (advanced) {
- Color256 color = palette.color[p[2]];
+ Color256 aescColor = { 0, 0, 0 };
+ _aesc->getColor(&aescColor, vertexX, y, vertexZ);
- 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;
+ Color256 color = palette.color[p[2]];
+ color.r = ((int)(_setEffectColor.r + _lightsColor.r * color.r) >> 16) + aescColor.r;
+ color.g = ((int)(_setEffectColor.g + _lightsColor.g * color.g) >> 16) + aescColor.g;
+ color.b = ((int)(_setEffectColor.b + _lightsColor.b * color.b) >> 16) + aescColor.b;
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) {
diff --git a/engines/bladerunner/slice_renderer.h b/engines/bladerunner/slice_renderer.h
index 1a876de543..fbdcdf3617 100644
--- a/engines/bladerunner/slice_renderer.h
+++ b/engines/bladerunner/slice_renderer.h
@@ -38,6 +38,7 @@ class MemoryReadStream;
namespace BladeRunner {
+class AESC;
class BladeRunnerEngine;
class Lights;
class SetEffects;
@@ -51,6 +52,7 @@ class SliceRenderer {
float _facing;
float _scale;
+ AESC *_aesc;
View _view;
Lights *_lights;
SetEffects *_setEffects;
@@ -87,12 +89,13 @@ class SliceRenderer {
Graphics::PixelFormat _pixelFormat;
Matrix3x2 calculateFacingRotationMatrix();
- void drawSlice(int slice, bool advanced, uint16 *frameLinePtr, uint16 *zbufLinePtr);
+ void drawSlice(int slice, bool advanced, uint16 *frameLinePtr, uint16 *zbufLinePtr, int y);
public:
SliceRenderer(BladeRunnerEngine *vm);
~SliceRenderer();
+ void setAESC(AESC *aesc);
void setView(const View &view);
void setLights(Lights *lights);
void setSetEffects(SetEffects *setEffects);
diff --git a/engines/bladerunner/view.cpp b/engines/bladerunner/view.cpp
index ed5cef9e3d..11cd99c9fc 100644
--- a/engines/bladerunner/view.cpp
+++ b/engines/bladerunner/view.cpp
@@ -27,7 +27,7 @@
namespace BladeRunner {
-bool View::read(Common::ReadStream *stream) {
+bool View::readVqa(Common::ReadStream *stream) {
_frame = stream->readUint32LE();
float d[12];
diff --git a/engines/bladerunner/view.h b/engines/bladerunner/view.h
index eb68aa9eb6..9d53d0852f 100644
--- a/engines/bladerunner/view.h
+++ b/engines/bladerunner/view.h
@@ -44,7 +44,7 @@ public:
float _viewportHalfHeight;
float _viewportDistance;
- bool read(Common::ReadStream *stream);
+ bool readVqa(Common::ReadStream *stream);
Vector3 calculateScreenPosition(Vector3 worldPosition);
private:
diff --git a/engines/bladerunner/vqa_decoder.cpp b/engines/bladerunner/vqa_decoder.cpp
index 377251714b..06cba12592 100644
--- a/engines/bladerunner/vqa_decoder.cpp
+++ b/engines/bladerunner/vqa_decoder.cpp
@@ -22,6 +22,7 @@
#include "bladerunner/vqa_decoder.h"
+#include "bladerunner/aesc.h"
#include "bladerunner/bladerunner.h"
#include "bladerunner/decompress_lcw.h"
#include "bladerunner/decompress_lzo.h"
@@ -206,6 +207,10 @@ void VQADecoder::decodeView(View *view) {
_videoTrack->decodeView(view);
}
+void VQADecoder::decodeAESC(AESC *aesc) {
+ _videoTrack->decodeAESC(aesc);
+}
+
void VQADecoder::decodeLights(Lights *lights) {
_videoTrack->decodeLights(lights);
}
@@ -570,6 +575,7 @@ VQADecoder::VQAVideoTrack::VQAVideoTrack(VQADecoder *vqaDecoder, Graphics::Surfa
_zbufChunk = new uint8[roundup(_maxZBUFChunkSize)];
_viewData = nullptr;
+ _aescData = nullptr;
_lightsData = nullptr;
}
@@ -579,10 +585,9 @@ VQADecoder::VQAVideoTrack::~VQAVideoTrack() {
delete[] _zbufChunk;
delete[] _vpointer;
- if (_viewData)
- delete[] _viewData;
- if (_lightsData)
- delete[] _lightsData;
+ delete[] _viewData;
+ delete[] _aescData;
+ delete[] _lightsData;
}
uint16 VQADecoder::VQAVideoTrack::getWidth() const {
@@ -647,8 +652,9 @@ bool VQADecoder::VQAVideoTrack::readCBFZ(Common::SeekableReadStream *s, uint32 s
_codebookSize = 2 * _maxBlocks * _blockW * _blockH;
_codebook = new uint8[_codebookSize];
}
- if (!_cbfz)
+ if (!_cbfz) {
_cbfz = new uint8[roundup(_maxCBFZSize)];
+ }
s->read(_cbfz, roundup(size));
@@ -671,22 +677,23 @@ bool VQADecoder::VQAVideoTrack::readZBUF(Common::SeekableReadStream *s, uint32 s
}
void VQADecoder::VQAVideoTrack::decodeZBuffer(ZBuffer *zbuffer) {
- if (_maxZBUFChunkSize == 0)
+ if (_maxZBUFChunkSize == 0) {
return;
+ }
zbuffer->decodeData(_zbufChunk, _zbufChunkSize);
}
bool VQADecoder::VQAVideoTrack::readVIEW(Common::SeekableReadStream *s, uint32 size) {
- if (size != 56)
+ if (size != 56) {
return false;
+ }
if (_viewData) {
delete[] _viewData;
- _viewData = nullptr;
}
- _viewDataSize = size;
+ _viewDataSize = roundup(size);
_viewData = new uint8[_viewDataSize];
s->read(_viewData, _viewDataSize);
@@ -694,30 +701,47 @@ bool VQADecoder::VQAVideoTrack::readVIEW(Common::SeekableReadStream *s, uint32 s
}
void VQADecoder::VQAVideoTrack::decodeView(View *view) {
- if (!view || !_viewData)
+ if (!view || !_viewData) {
return;
+ }
Common::MemoryReadStream s(_viewData, _viewDataSize);
- view->read(&s);
+ view->readVqa(&s);
delete[] _viewData;
_viewData = nullptr;
}
bool VQADecoder::VQAVideoTrack::readAESC(Common::SeekableReadStream *s, uint32 size) {
- debug("VQADecoder::readAESC(%d)", size);
+ if (_aescData) {
+ delete[] _aescData;
+ }
+
+ _aescDataSize = roundup(size);
+ _aescData = new uint8[_aescDataSize];
+ s->read(_aescData, _aescDataSize);
- s->skip(roundup(size));
return true;
}
+void VQADecoder::VQAVideoTrack::decodeAESC(AESC *aesc) {
+ if (!aesc || !_aescData) {
+ return;
+ }
+
+ Common::MemoryReadStream s(_aescData, _aescDataSize);
+ aesc->readVqa(&s);
+
+ delete[] _aescData;
+ _aescData = nullptr;
+}
+
bool VQADecoder::VQAVideoTrack::readLITE(Common::SeekableReadStream *s, uint32 size) {
if (_lightsData) {
delete[] _lightsData;
- _lightsData = nullptr;
}
- _lightsDataSize = size;
+ _lightsDataSize = roundup(size);
_lightsData = new uint8[_lightsDataSize];
s->read(_lightsData, _lightsDataSize);
@@ -726,8 +750,9 @@ bool VQADecoder::VQAVideoTrack::readLITE(Common::SeekableReadStream *s, uint32 s
void VQADecoder::VQAVideoTrack::decodeLights(Lights *lights) {
- if (!lights || !_lightsData)
+ if (!lights || !_lightsData) {
return;
+ }
Common::MemoryReadStream s(_lightsData, _lightsDataSize);
lights->readVqa(&s);
@@ -741,8 +766,9 @@ bool VQADecoder::VQAVideoTrack::readVPTR(Common::SeekableReadStream *s, uint32 s
if (size > _maxVPTRSize)
return false;
- if (!_vpointer)
+ if (!_vpointer) {
_vpointer = new uint8[roundup(_maxVPTRSize)];
+ }
_vpointerSize = size;
s->read(_vpointer, roundup(size));
diff --git a/engines/bladerunner/vqa_decoder.h b/engines/bladerunner/vqa_decoder.h
index d7086d1b9f..8ef2ddd9c4 100644
--- a/engines/bladerunner/vqa_decoder.h
+++ b/engines/bladerunner/vqa_decoder.h
@@ -35,6 +35,7 @@
#include "graphics/surface.h"
#include "video/video_decoder.h"
+#include "aesc.h"
namespace BladeRunner {
@@ -55,6 +56,7 @@ public:
void decodeZBuffer(ZBuffer *zbuffer);
Audio::SeekableAudioStream *decodeAudioFrame();
void decodeView(View *view);
+ void decodeAESC(AESC *aesc);
void decodeLights(Lights *lights);
uint16 numFrames() const { return _header.numFrames; }
@@ -159,11 +161,14 @@ private:
uint16 getWidth() const;
uint16 getHeight() const;
+
int getCurFrame() const;
int getFrameCount() const;
+
void decodeVideoFrame();
void decodeZBuffer(ZBuffer *zbuffer);
void decodeView(View *view);
+ void decodeAESC(AESC *aesc);
void decodeLights(Lights *lights);
bool readVQFR(Common::SeekableReadStream *s, uint32 size);
@@ -208,9 +213,11 @@ private:
int _curFrame;
uint8 *_viewData;
- uint32 _viewDataSize;
+ uint32 _viewDataSize;
uint8 *_lightsData;
- uint32 _lightsDataSize;
+ uint32 _lightsDataSize;
+ uint8 *_aescData;
+ uint32 _aescDataSize;
void VPTRWriteBlock(uint16 *frame, unsigned int dstBlock, unsigned int srcBlock, int count, bool alpha = false);
bool decodeFrame(uint16 *frame);
diff --git a/engines/bladerunner/vqa_player.cpp b/engines/bladerunner/vqa_player.cpp
index 12baa26d76..a340f798d1 100644
--- a/engines/bladerunner/vqa_player.cpp
+++ b/engines/bladerunner/vqa_player.cpp
@@ -152,6 +152,10 @@ void VQAPlayer::updateView(View *view) {
_decoder.decodeView(view);
}
+void VQAPlayer::updateAESC(AESC *aesc) {
+ _decoder.decodeAESC(aesc);
+}
+
void VQAPlayer::updateLights(Lights *lights) {
_decoder.decodeLights(lights);
}
diff --git a/engines/bladerunner/vqa_player.h b/engines/bladerunner/vqa_player.h
index b4365670e8..dde5201932 100644
--- a/engines/bladerunner/vqa_player.h
+++ b/engines/bladerunner/vqa_player.h
@@ -105,6 +105,7 @@ public:
int update();
void updateZBuffer(ZBuffer *zbuffer);
void updateView(View *view);
+ void updateAESC(AESC *aesc);
void updateLights(Lights *lights);
bool setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopSetMode, void(*callback)(void *, int, int), void *callbackData);