diff options
-rw-r--r-- | engines/bladerunner/aesc.cpp | 139 | ||||
-rw-r--r-- | engines/bladerunner/aesc.h | 68 | ||||
-rw-r--r-- | engines/bladerunner/bladerunner.cpp | 69 | ||||
-rw-r--r-- | engines/bladerunner/bladerunner.h | 2 | ||||
-rw-r--r-- | engines/bladerunner/module.mk | 1 | ||||
-rw-r--r-- | engines/bladerunner/scene.cpp | 1 | ||||
-rw-r--r-- | engines/bladerunner/slice_renderer.cpp | 28 | ||||
-rw-r--r-- | engines/bladerunner/slice_renderer.h | 5 | ||||
-rw-r--r-- | engines/bladerunner/view.cpp | 2 | ||||
-rw-r--r-- | engines/bladerunner/view.h | 2 | ||||
-rw-r--r-- | engines/bladerunner/vqa_decoder.cpp | 60 | ||||
-rw-r--r-- | engines/bladerunner/vqa_decoder.h | 11 | ||||
-rw-r--r-- | engines/bladerunner/vqa_player.cpp | 4 | ||||
-rw-r--r-- | engines/bladerunner/vqa_player.h | 1 |
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); |