[Scummvm-git-logs] scummvm master -> cd7e44f9f92c3aee7b99ecf44e8dbfbb252904d0

peterkohaut peterkohaut at users.noreply.github.com
Sun Oct 13 14:10:56 CEST 2019


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
cd7e44f9f9 BLADERUNNER: Group shapes loading


Commit: cd7e44f9f92c3aee7b99ecf44e8dbfbb252904d0
    https://github.com/scummvm/scummvm/commit/cd7e44f9f92c3aee7b99ecf44e8dbfbb252904d0
Author: Peter Kohaut (peter.kohaut at gmail.com)
Date: 2019-10-13T14:09:47+02:00

Commit Message:
BLADERUNNER: Group shapes loading

Changed paths:
  R engines/bladerunner/ui/kia_shapes.cpp
  R engines/bladerunner/ui/kia_shapes.h
    engines/bladerunner/audio_mixer.cpp
    engines/bladerunner/bladerunner.cpp
    engines/bladerunner/bladerunner.h
    engines/bladerunner/dialogue_menu.cpp
    engines/bladerunner/dialogue_menu.h
    engines/bladerunner/module.mk
    engines/bladerunner/mouse.cpp
    engines/bladerunner/shape.cpp
    engines/bladerunner/shape.h
    engines/bladerunner/slice_renderer.cpp
    engines/bladerunner/subtitles.cpp
    engines/bladerunner/ui/elevator.cpp
    engines/bladerunner/ui/elevator.h
    engines/bladerunner/ui/esper.cpp
    engines/bladerunner/ui/esper.h
    engines/bladerunner/ui/kia.cpp
    engines/bladerunner/ui/kia.h
    engines/bladerunner/ui/kia_section_clues.cpp
    engines/bladerunner/ui/kia_section_crimes.cpp
    engines/bladerunner/ui/kia_section_crimes.h
    engines/bladerunner/ui/kia_section_help.cpp
    engines/bladerunner/ui/kia_section_load.cpp
    engines/bladerunner/ui/kia_section_save.cpp
    engines/bladerunner/ui/kia_section_settings.cpp
    engines/bladerunner/ui/kia_section_suspects.cpp
    engines/bladerunner/ui/kia_section_suspects.h
    engines/bladerunner/ui/spinner.cpp
    engines/bladerunner/ui/spinner.h
    engines/bladerunner/ui/ui_check_box.cpp
    engines/bladerunner/ui/ui_scroll_box.cpp
    engines/bladerunner/ui/vk.cpp
    engines/bladerunner/ui/vk.h


diff --git a/engines/bladerunner/audio_mixer.cpp b/engines/bladerunner/audio_mixer.cpp
index c31ade8..fe39f57 100644
--- a/engines/bladerunner/audio_mixer.cpp
+++ b/engines/bladerunner/audio_mixer.cpp
@@ -117,6 +117,10 @@ int AudioMixer::playInChannel(int channel, Audio::Mixer::SoundType type, Audio::
 		audioStream = new Audio::LoopingAudioStream(stream, 0, DisposeAfterUse::YES);
 	}
 
+	if (!_vm->_mixer->isReady()) {
+		return -1;
+	}
+
 	_vm->_mixer->playStream(
 		type,
 		&_channels[channel].handle,
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index f4032b8..ed7846f 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -642,7 +642,7 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
 	_russianCP1251 = ((uint8)_textOptions->getText(0)[0]) == 209;
 
 	_dialogueMenu = new DialogueMenu(this);
-	if (!_dialogueMenu->loadText("DLGMENU"))
+	if (!_dialogueMenu->loadResources())
 		return false;
 
 	_suspectsDatabase = new SuspectsDatabase(this, _gameInfo->getSuspectCount());
@@ -657,11 +657,8 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
 
 	_mainFont = Font::load(this, "KIA6PT.FON", 1, false);
 
-	for (int i = 0; i != 43; ++i) {
-		Shape *shape = new Shape(this);
-		shape->open("SHAPES.SHP", i);
-		_shapes.push_back(shape);
-	}
+	_shapes = new Shapes(this);
+	_shapes->load("SHAPES.SHP");
 
 	_esper = new ESPER(this);
 
@@ -759,10 +756,8 @@ void BladeRunnerEngine::shutdown() {
 	delete _esper;
 	_esper = nullptr;
 
-	for (uint i = 0; i != _shapes.size(); ++i) {
-		delete _shapes[i];
-	}
-	_shapes.clear();
+	delete _shapes;
+	_shapes = nullptr;
 
 	delete _mainFont;
 	_mainFont = nullptr;
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index 8bd369b..3bc6404 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -91,7 +91,7 @@ class SceneObjects;
 class SceneScript;
 class Scores;
 class Settings;
-class Shape;
+class Shapes;
 class SliceAnimations;
 class SliceRenderer;
 class Spinner;
@@ -99,7 +99,6 @@ class Subtitles;
 class SuspectsDatabase;
 class TextResource;
 class Time;
-class KIAShapes;
 class Vector3;
 class View;
 class VK;
@@ -180,7 +179,7 @@ public:
 	TextResource       *_textVK;
 	TextResource       *_textOptions;
 
-	Common::Array<Shape*> _shapes;
+	Shapes *_shapes;
 
 	Actor *_actors[kActorCount];
 	Actor *_playerActor;
diff --git a/engines/bladerunner/dialogue_menu.cpp b/engines/bladerunner/dialogue_menu.cpp
index 1ef19dd..6198f21 100644
--- a/engines/bladerunner/dialogue_menu.cpp
+++ b/engines/bladerunner/dialogue_menu.cpp
@@ -41,13 +41,7 @@ DialogueMenu::DialogueMenu(BladeRunnerEngine *vm) {
 	_vm = vm;
 	reset();
 	_textResource = new TextResource(_vm);
-	_shapes.reserve(8);
-	for (int i = 0; i != 8; ++i) {
-		_shapes.push_back(Shape(_vm));
-		bool r = _shapes[i].open("DIALOG.SHP", i);
-		assert(r);
-		(void)r;
-	}
+	_shapes = new Shapes(_vm);
 
 	_screenX = 0;
 	_screenY = 0;
@@ -57,13 +51,18 @@ DialogueMenu::DialogueMenu(BladeRunnerEngine *vm) {
 
 DialogueMenu::~DialogueMenu() {
 	delete _textResource;
+	delete _shapes;
 }
 
-bool DialogueMenu::loadText(const Common::String &name) {
-	bool r = _textResource->open(name);
+bool DialogueMenu::loadResources() {
+	bool r = _textResource->open("DLGMENU");
 	if (!r) {
 		error("Failed to load dialogue menu text");
 	}
+	r = _shapes->load("DIALOG.SHP");
+	if (!r) {
+		error("Failed to load dialogue menu shapes");
+	}
 	return r;
 }
 
@@ -372,21 +371,21 @@ void DialogueMenu::draw(Graphics::Surface &s) {
 		s.hLine(x1 + 8, mouse.y, x2 + 2, s.format.RGBToColor(64, 64, 64));
 	}
 
-	_shapes[0].draw(s, x1, y1);
-	_shapes[3].draw(s, x2, y1);
-	_shapes[2].draw(s, x1, y2);
-	_shapes[5].draw(s, x2, y2);
+	_shapes->get(0)->draw(s, x1, y1);
+	_shapes->get(3)->draw(s, x2, y1);
+	_shapes->get(2)->draw(s, x1, y2);
+	_shapes->get(5)->draw(s, x2, y2);
 
 	for (int i = 0; i != _listSize; ++i) {
-		_shapes[1].draw(s, x1, y);
-		_shapes[4].draw(s, x2, y);
+		_shapes->get(1)->draw(s, x1, y);
+		_shapes->get(4)->draw(s, x2, y);
 		uint32 color = s.format.RGBToColor((_items[i].colorIntensity / 2) * (256 / 32), (_items[i].colorIntensity / 2) * (256 / 32), _items[i].colorIntensity * (256 / 32));
 		_vm->_mainFont->drawString(&s, _items[i].text, x, y, s.w, color);
 		y += kLineHeight;
 	}
 	for (; x != x2; ++x) {
-		_shapes[6].draw(s, x, y1);
-		_shapes[7].draw(s, x, y2);
+		_shapes->get(6)->draw(s, x, y1);
+		_shapes->get(7)->draw(s, x, y2);
 	}
 }
 
@@ -411,8 +410,8 @@ void DialogueMenu::calculatePosition(int unusedX, int unusedY) {
 	}
 	_maxItemWidth += 2;
 
-	int w = kBorderSize + _shapes[4].getWidth() + _maxItemWidth;
-	int h = kBorderSize + _shapes[7].getHeight() + kLineHeight * _listSize;
+	int w = kBorderSize + _shapes->get(4)->getWidth() + _maxItemWidth;
+	int h = kBorderSize + _shapes->get(7)->getHeight() + kLineHeight * _listSize;
 
 	_screenX = _centerX - w / 2;
 	_screenY = _centerY - h / 2;
diff --git a/engines/bladerunner/dialogue_menu.h b/engines/bladerunner/dialogue_menu.h
index 4cb7c4f..a15dec1 100644
--- a/engines/bladerunner/dialogue_menu.h
+++ b/engines/bladerunner/dialogue_menu.h
@@ -55,27 +55,27 @@ class DialogueMenu {
 
 	BladeRunnerEngine *_vm;
 
-	TextResource         *_textResource;
-	Common::Array<Shape>  _shapes;
-	bool                  _isVisible;
-	bool                  _waitingForInput;
-	int                   _selectedItemIndex;
-	int                   _listSize;
+	TextResource *_textResource;
+	Shapes       *_shapes;
+	bool          _isVisible;
+	bool          _waitingForInput;
+	int           _selectedItemIndex;
+	int           _listSize;
 
 	// These track whether a dialogue option
 	// has previously been selected
-	int                   _neverRepeatListSize;
-	int                   _neverRepeatValues[kMaxRepeatHistory];
-	bool                  _neverRepeatWasSelected[kMaxRepeatHistory];
+	int           _neverRepeatListSize;
+	int           _neverRepeatValues[kMaxRepeatHistory];
+	bool          _neverRepeatWasSelected[kMaxRepeatHistory];
 
-	int                   _centerX;
-	int                   _centerY;
-	int                   _screenX;
-	int                   _screenY;
-	int                   _maxItemWidth;
-	DialogueItem          _items[kMaxItems];
+	int           _centerX;
+	int           _centerY;
+	int           _screenX;
+	int           _screenY;
+	int           _maxItemWidth;
+	DialogueItem  _items[kMaxItems];
 
-	int                   _fadeInItemIndex;
+	int           _fadeInItemIndex;
 
 public:
 	DialogueMenu(BladeRunnerEngine *vm);
@@ -83,7 +83,7 @@ public:
 
 	void clear();
 
-	bool loadText(const Common::String &name);
+	bool loadResources();
 
 	bool show();
 	bool hide();
diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk
index 6be142d..f1d935b 100644
--- a/engines/bladerunner/module.mk
+++ b/engines/bladerunner/module.mk
@@ -265,7 +265,6 @@ MODULE_OBJS = \
 	ui/kia_section_save.o \
 	ui/kia_section_settings.o \
 	ui/kia_section_suspects.o \
-	ui/kia_shapes.o \
 	ui/scores.o \
 	ui/spinner.o \
 	ui/ui_check_box.o \
diff --git a/engines/bladerunner/mouse.cpp b/engines/bladerunner/mouse.cpp
index 3d82fa0..94ea88c 100644
--- a/engines/bladerunner/mouse.cpp
+++ b/engines/bladerunner/mouse.cpp
@@ -257,13 +257,7 @@ void Mouse::draw(Graphics::Surface &surface, int x, int y) {
 	_x = CLIP(x, 0, surface.w - 1);
 	_y = CLIP(y, 0, surface.h - 1);
 
-	if (_cursor < 0 || (uint)_cursor >= _vm->_shapes.size()) {
-		return;
-	}
-
-	Shape *cursorShape = _vm->_shapes[_frame];
-
-	cursorShape->draw(surface, _x - _hotspotX, _y - _hotspotY);
+	_vm->_shapes->get(_frame)->draw(surface, _x - _hotspotX, _y - _hotspotY);
 
 	updateCursorFrame();
 }
diff --git a/engines/bladerunner/shape.cpp b/engines/bladerunner/shape.cpp
index c844a57..724fac0 100644
--- a/engines/bladerunner/shape.cpp
+++ b/engines/bladerunner/shape.cpp
@@ -32,63 +32,35 @@
 
 namespace BladeRunner {
 
-Shape::Shape(BladeRunnerEngine *vm) {
-	_vm     = vm;
-	_data   = nullptr;
-	_width  = 0;
-	_height = 0;
-}
-
-Shape::~Shape() {
-	delete[] _data;
-}
-
-bool Shape::open(const Common::String &container, int index) {
-	Common::ScopedPtr<Common::SeekableReadStream> stream(_vm->getResourceStream(container));
-	if (!stream) {
-		warning("Shape::open failed to open '%s'", container.c_str());
-		return false;
-	}
+bool Shape::load(Common::SeekableReadStream *stream) {
+	_width = stream->readUint32LE();
+	_height = stream->readUint32LE();
+	uint32 size = stream->readUint32LE();
 
-	uint32 count = stream->readUint32LE();
-	if (index < 0 || (uint32)index >= count) {
-		warning("Shape::open invalid index %d (count %u)", index, count);
+	if (size != (uint32)(_width * _height * 2)) {
+		warning("Shape::load size mismatch (w %d, h %d, sz %d)", _width, _height, size);
 		return false;
 	}
 
-	uint32 size = 0, width = 0, height = 0;
-	for (int i = 0; i <= index; ++i) {
-		width  = stream->readUint32LE();
-		height = stream->readUint32LE();
-		size   = stream->readUint32LE();
-
-		if (size != width * height * 2) {
-			warning("Shape::open size mismatch (w %d, h %d, sz %d)", width, height, size);
-			return false;
-		}
-
-		if (i != index) {
-			stream->skip(size);
-		}
-	}
-
 	// Enfoce a reasonable size limit
-	if (width >= 2048 || height >= 2048) {
-		warning("Shape::open shape too big (%d, %d)", width, height);
+	if (_width >= 2048 || _height >= 2048) {
+		warning("Shape::load shape too big (%d, %d)", _width, _height);
 	}
 
-	_width  = width;
-	_height = height;
-	_data   = new byte[size];
+	_data = new byte[size];
 
 	if (stream->read(_data, size) != size) {
-		warning("Shape::open error reading shape %d (w %d, h %d, sz %d)", index, width, height, size);
+		warning("Shape::load error reading shape (w %d, h %d, sz %d)", _width, _height, size);
 		return false;
 	}
 
 	return true;
 }
 
+Shape::~Shape() {
+	delete[] _data;
+}
+
 void Shape::draw(Graphics::Surface &surface, int x, int y) const {
 	int src_x = CLIP(-x, 0, _width);
 	int src_y = CLIP(-y, 0, _height);
@@ -123,4 +95,39 @@ void Shape::draw(Graphics::Surface &surface, int x, int y) const {
 	}
 }
 
+Shapes::Shapes(BladeRunnerEngine *vm) {
+	_vm = vm;
+}
+
+Shapes::~Shapes() {
+	unload();
+}
+
+bool Shapes::load(const Common::String &container) {
+	unload();
+
+	Common::ScopedPtr<Common::SeekableReadStream> stream(_vm->getResourceStream(container));
+	if (!stream) {
+		warning("Shape::open failed to open '%s'", container.c_str());
+		return false;
+	}
+
+	uint32 count = stream->readUint32LE();
+
+	_shapes.resize(count);
+
+	for (uint32 i = 0; i < count; ++i) {
+		if (!_shapes[i].load(stream.get())) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+void Shapes::unload() {
+	_shapes.clear();
+}
+
+
 } // End of namespace BladeRunner
diff --git a/engines/bladerunner/shape.h b/engines/bladerunner/shape.h
index 79037b7..04a214c 100644
--- a/engines/bladerunner/shape.h
+++ b/engines/bladerunner/shape.h
@@ -23,8 +23,14 @@
 #ifndef BLADERUNNER_SHAPE_H
 #define BLADERUNNER_SHAPE_H
 
+#include "common/array.h"
 #include "common/str.h"
 
+
+namespace Common {
+class SeekableReadStream;
+}
+
 namespace Graphics {
 struct Surface;
 }
@@ -34,24 +40,41 @@ namespace BladeRunner {
 class BladeRunnerEngine;
 
 class Shape {
-	BladeRunnerEngine *_vm;
+	friend class Shapes;
 
 	int   _width;
 	int   _height;
 	byte *_data;
 
+	bool load(Common::SeekableReadStream *stream);
+
 public:
-	Shape(BladeRunnerEngine *vm);
 	~Shape();
 
-	bool open(const Common::String &container, int index);
-
 	void draw(Graphics::Surface &surface, int x, int y) const;
 
-	int getWidth()  const { return _width;  }
+	int getWidth() const { return _width; }
 	int getHeight() const { return _height; }
 };
 
+class Shapes {
+	BladeRunnerEngine *_vm;
+
+	Common::Array<Shape> _shapes;
+
+public:
+	Shapes(BladeRunnerEngine *vm);
+	~Shapes();
+
+	bool load(const Common::String &container);
+	void unload();
+
+	const Shape *get(uint32 index) const {
+		assert(index < _shapes.size());
+		return &_shapes[index];
+	}
+};
+
 } // End of namespace BladeRunner
 
 #endif
diff --git a/engines/bladerunner/slice_renderer.cpp b/engines/bladerunner/slice_renderer.cpp
index 54cc0f4..7f3976f 100644
--- a/engines/bladerunner/slice_renderer.cpp
+++ b/engines/bladerunner/slice_renderer.cpp
@@ -38,7 +38,7 @@ SliceRenderer::SliceRenderer(BladeRunnerEngine *vm) {
 	_vm = vm;
 	_pixelFormat = screenPixelFormat();
 
-	for (int i = 0; i < 942; i++) { // yes, its going just to 942 and not 997
+	for (int i = 0; i < ARRAYSIZE(_animationsShadowEnabled); i++) { // original game ss going just yp to 942 and not 997
 		_animationsShadowEnabled[i] = true;
 	}
 	_animation = -1;
diff --git a/engines/bladerunner/subtitles.cpp b/engines/bladerunner/subtitles.cpp
index bd4a758..e0b7378 100644
--- a/engines/bladerunner/subtitles.cpp
+++ b/engines/bladerunner/subtitles.cpp
@@ -410,6 +410,8 @@ void Subtitles::reset() {
 	_subtitlesInfo.versionStr = "N/A";
 	_subtitlesInfo.dateOfCompile = "N/A";
 	_subtitlesInfo.languageMode = "N/A";
+	_subtitlesInfo.fontType = kSubtitlesFontTypeInternal;
+	_subtitlesInfo.fontName = "N/A";
 
 	for (int i = 0; i < kMaxTextResourceEntries; ++i) {
 		if (_vqaSubsTextResourceEntries[i] != nullptr) {
diff --git a/engines/bladerunner/ui/elevator.cpp b/engines/bladerunner/ui/elevator.cpp
index cff2a16..2e8d70d 100644
--- a/engines/bladerunner/ui/elevator.cpp
+++ b/engines/bladerunner/ui/elevator.cpp
@@ -44,9 +44,13 @@ Elevator::Elevator(BladeRunnerEngine *vm) {
 	_vm = vm;
 	reset();
 	_imagePicker = new UIImagePicker(vm, 8);
+	_shapes = new Shapes(vm);
 }
 
 Elevator::~Elevator() {
+	delete _shapes;
+	_shapes = nullptr;
+
 	delete _imagePicker;
 	_imagePicker = nullptr;
 }
@@ -76,10 +80,7 @@ int Elevator::activate(int elevatorId) {
 	_vqaPlayer->setLoop(1, -1, kLoopSetModeJustStart, nullptr, nullptr);
 	_vm->_mouse->setCursor(0);
 
-	for (int i = 0; i != 16; ++i) {
-		_shapes.push_back(new Shape(_vm));
-		_shapes[i]->open("ELEVATOR.SHP", i);
-	}
+	_shapes->load("ELEVATOR.SHP");
 
 	_imagePicker->resetImages();
 
@@ -88,62 +89,62 @@ int Elevator::activate(int elevatorId) {
 			0,
 			Common::Rect(220, 298, 308, 392),
 			nullptr,
-			_shapes[11],
-			_shapes[14],
+			_shapes->get(11),
+			_shapes->get(14),
 			nullptr);
 		_imagePicker->defineImage(
 			1,
 			Common::Rect(259, 259, 302, 292),
 			nullptr,
-			_shapes[10],
-			_shapes[13],
+			_shapes->get(10),
+			_shapes->get(13),
 			nullptr);
 		_imagePicker->defineImage(
 			2,
 			Common::Rect(227, 398, 301, 434),
 			nullptr,
-			_shapes[12],
-			_shapes[15],
+			_shapes->get(12),
+			_shapes->get(15),
 			nullptr);
 	} else { // kElevatorPS
 		_imagePicker->defineImage(
 			4,
 			Common::Rect(395, 131, 448, 164),
 			nullptr,
-			_shapes[0],
-			_shapes[5],
+			_shapes->get(0),
+			_shapes->get(5),
 			nullptr
 		);
 		_imagePicker->defineImage(
 			3,
 			Common::Rect(395, 165, 448, 198),
 			nullptr,
-			_shapes[1],
-			_shapes[6],
+			_shapes->get(1),
+			_shapes->get(6),
 			nullptr
 		);
 		_imagePicker->defineImage(
 			5,
 			Common::Rect(395, 199, 448, 232),
 			nullptr,
-			_shapes[2],
-			_shapes[7],
+			_shapes->get(2),
+			_shapes->get(7),
 			nullptr
 		);
 		_imagePicker->defineImage(
 			6,
 			Common::Rect(395, 233, 448, 264),
 			nullptr,
-			_shapes[3],
-			_shapes[8],
+			_shapes->get(3),
+			_shapes->get(8),
 			nullptr
 		);
 		_imagePicker->defineImage(
 			7,
 			Common::Rect(395, 265, 448, 295),
 			nullptr,
-			_shapes[4],
-			_shapes[9],
+			_shapes->get(4),
+			_shapes->get(9),
 			nullptr
 		);
 	}
@@ -167,13 +168,10 @@ int Elevator::activate(int elevatorId) {
 
 	_imagePicker->deactivate();
 
-	_vqaPlayer->close();
 	delete _vqaPlayer;
+	_vqaPlayer = nullptr;
 
-	for (int i = 0; i != (int)_shapes.size(); ++i) {
-		delete _shapes[i];
-	}
-	_shapes.clear();
+	_shapes->unload();
 
 	_vm->closeArchive("MODE.MIX");
 
diff --git a/engines/bladerunner/ui/elevator.h b/engines/bladerunner/ui/elevator.h
index 6ed91ce..f2cdd8c 100644
--- a/engines/bladerunner/ui/elevator.h
+++ b/engines/bladerunner/ui/elevator.h
@@ -28,20 +28,20 @@
 namespace BladeRunner {
 
 class BladeRunnerEngine;
-class Shape;
+class Shapes;
 class VQAPlayer;
 class UIImagePicker;
 
 class Elevator {
-	BladeRunnerEngine     *_vm;
-	bool                   _isOpen;
-	VQAPlayer             *_vqaPlayer;
-	int                    _buttonClicked;
-	Common::Array<Shape *> _shapes;
-	UIImagePicker         *_imagePicker;
-	int                    _actorId;
-	int                    _sentenceId;
-	uint32                 _timeSpeakDescriptionStart;
+	BladeRunnerEngine *_vm;
+	bool               _isOpen;
+	VQAPlayer         *_vqaPlayer;
+	int                _buttonClicked;
+	Shapes            *_shapes;
+	UIImagePicker     *_imagePicker;
+	int                _actorId;
+	int                _sentenceId;
+	uint32             _timeSpeakDescriptionStart;
 
 public:
 	Elevator(BladeRunnerEngine *vm);
diff --git a/engines/bladerunner/ui/esper.cpp b/engines/bladerunner/ui/esper.cpp
index 2290cdb..987b2af 100644
--- a/engines/bladerunner/ui/esper.cpp
+++ b/engines/bladerunner/ui/esper.cpp
@@ -51,26 +51,28 @@ ESPER::ESPER(BladeRunnerEngine *vm) {
 	_screen = Common::Rect(135, 123, 435, 387);
 
 	_isWaiting          = false;
-	_shapeButton        = nullptr;
-	_shapeThumbnail     = nullptr;
 	_regionSelectedAck  = false;
 	_isDrawingSelection = false;
 
 	_isOpen             = false;
-	_shapeButton        = nullptr;
+	_shapesButtons      = new Shapes(vm);
+	_shapesPhotos       = new Shapes(vm);
 	_shapeThumbnail     = nullptr;
 	_vqaPlayerMain      = nullptr;
 	_vqaPlayerPhoto     = nullptr;
 	_script             = nullptr;
 
-	reset();
-
 	_buttons = new UIImagePicker(vm, kPhotoCount + 4);
+
+	reset();
 }
 
 ESPER::~ESPER() {
-	delete _buttons;
 	reset();
+
+	delete _buttons;
+	delete _shapesPhotos;
+	delete _shapesButtons;
 }
 
 void ESPER::open(Graphics::Surface *surface) {
@@ -96,17 +98,17 @@ void ESPER::open(Graphics::Surface *surface) {
 	}
 
 	_surfacePhoto.create(kPhotoWidth, kPhotoHeight, gameDataPixelFormat());
-
 	_surfaceViewport.create(_screen.width(), _screen.height(), screenPixelFormat());
 
 	_viewportNext = _viewport;
 
-	_shapeButton = new Shape(_vm);
-	if (!_shapeButton->open("ESPBUTTN.SHP", 0)) {
+	if (!_shapesButtons->load("ESPBUTTN.SHP")) {
 		return;
 	}
 
-	_shapesPhotos.resize(10);
+	if (!_shapesPhotos->load("ESPTHUMB.SHP")) {
+		return;
+	}
 
 	_vqaPlayerMain = new VQAPlayer(_vm, &_vm->_surfaceBack, "ESPER.VQA");
 	if (!_vqaPlayerMain->open()) {
@@ -118,6 +120,7 @@ void ESPER::open(Graphics::Surface *surface) {
 	_flash = false;
 
 	_script = new ESPERScript(_vm);
+
 	activate(true);
 }
 
@@ -129,26 +132,18 @@ void ESPER::close() {
 	_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxBR035_7B), 25, 0, 0, 50, 0);
 
 	unloadPhotos();
-	_shapesPhotos.clear();
-
-	delete _shapeThumbnail;
-	_shapeThumbnail = nullptr;
 
 	_buttons->deactivate();
 	_buttons->resetImages();
 
-	delete _shapeButton;
-	_shapeButton = nullptr;
+	_shapesButtons->unload();
+	_shapesPhotos->unload();
 
 	_surfacePhoto.free();
-
 	_surfaceViewport.free();
 
-	if (_vqaPlayerMain) {
-		_vqaPlayerMain->close();
-		delete _vqaPlayerMain;
-		_vqaPlayerMain= nullptr;
-	}
+	delete _vqaPlayerMain;
+	_vqaPlayerMain = nullptr;
 
 	_vm->closeArchive("MODE.MIX");
 
@@ -156,6 +151,7 @@ void ESPER::close() {
 
 	_vm->_ambientSounds->setVolume(_ambientVolume);
 	_vm->_scene->resume();
+
 	reset();
 }
 
@@ -248,11 +244,6 @@ void ESPER::addPhoto(const char *name, int photoId, int shapeId) {
 		_photos[i].photoId   = photoId;
 		_photos[i].name      = name;
 
-		assert((uint)shapeId < _shapesPhotos.size());
-
-		_shapesPhotos[shapeId] = new Shape(_vm);
-		_shapesPhotos[shapeId]->open("ESPTHUMB.SHP", shapeId);
-
 		_buttons->defineImage(i,
 			Common::Rect(
 				100 * (i % 3) + _screen.left + 3,
@@ -260,9 +251,9 @@ void ESPER::addPhoto(const char *name, int photoId, int shapeId) {
 				100 * (i % 3) + _screen.left + 100 - 3,
 				 66 * (i / 3) + _screen.top  +  66 - 3
 			),
-			_shapesPhotos[shapeId],
-			_shapesPhotos[shapeId],
-			_shapesPhotos[shapeId],
+			_shapesPhotos->get(shapeId),
+			_shapesPhotos->get(shapeId),
+			_shapesPhotos->get(shapeId),
 			nullptr);
 	}
 	playSound(kSfxBR028_2A, 25);
@@ -304,14 +295,10 @@ void ESPER::mouseUpCallback(int buttonId, void *callbackData) {
 
 void ESPER::reset() {
 	_surfacePhoto.free();
-
 	_surfaceViewport.free();
 
-	delete _shapeButton;
-	_shapeButton = nullptr;
-
-	delete _shapeThumbnail;
-	_shapeThumbnail = nullptr;
+	_shapesButtons->unload();
+	_shapesPhotos->unload();
 
 	delete _vqaPlayerMain;
 	_vqaPlayerMain = nullptr;
@@ -324,21 +311,14 @@ void ESPER::reset() {
 
 	_isOpen = false;
 
-	_shapesPhotos.clear();
 	resetData();
 }
 
 void ESPER::resetData() {
-	if (_vqaPlayerPhoto) {
-		_vqaPlayerPhoto->close();
-		delete _vqaPlayerPhoto;
-		_vqaPlayerPhoto = nullptr;
-	}
+	delete _vqaPlayerPhoto;
+	_vqaPlayerPhoto = nullptr;
 
-	if (_shapeThumbnail) {
-		delete _shapeThumbnail;
-		_shapeThumbnail = nullptr;
-	}
+	_shapeThumbnail = nullptr;
 
 	_viewport     = Common::Rect();
 	_viewportNext = Common::Rect();
@@ -500,7 +480,7 @@ void ESPER::activate(bool withOpening) {
 	}
 
 	_buttons->activate(nullptr, nullptr, mouseDownCallback, mouseUpCallback, this);
-	_buttons->defineImage(kPhotoCount + 3, Common::Rect(42, 403, 76, 437), nullptr, nullptr, _shapeButton, nullptr);
+	_buttons->defineImage(kPhotoCount + 3, Common::Rect(42, 403, 76, 437), nullptr, nullptr, _shapesButtons->get(0), nullptr);
 
 	playSound(kSfxBR024_4B, 25);
 	wait(1000);
@@ -1446,10 +1426,6 @@ void ESPER::selectPhoto(int photoId) {
 
 	Common::ScopedPtr<Common::SeekableReadStream> s(_vm->getResourceStream(_photos[photoId].name));
 
-	if (!s) {
-		reset();
-	}
-
 	uint photoSize = _surfacePhoto.w * _surfacePhoto.h * _surfacePhoto.format.bytesPerPixel;
 
 	s->skip(3); // not used, but there is compression type
@@ -1473,11 +1449,10 @@ void ESPER::selectPhoto(int photoId) {
 		// _surfacePhoto[j] = Palette[_surfacePhoto[j]];
 	}
 
-	_shapeThumbnail = new Shape(_vm);
-	_shapeThumbnail->open("ESPTHUMB.SHP", _photos[photoId].shapeId);
+	_shapeThumbnail = _shapesPhotos->get(_photos[photoId].shapeId);
 	_buttons->resetImages();
 	_buttons->defineImage(kPhotoCount + 2, Common::Rect(480, 350, 578, 413), _shapeThumbnail, _shapeThumbnail, _shapeThumbnail, nullptr);
-	_buttons->defineImage(kPhotoCount + 3, Common::Rect(42, 403, 76, 437), nullptr, nullptr, _shapeButton, nullptr);
+	_buttons->defineImage(kPhotoCount + 3, Common::Rect(42, 403, 76, 437), nullptr, nullptr, _shapesButtons->get(0), nullptr);
 
 	resetPhotoOpening();
 	resetViewport();
@@ -1490,10 +1465,8 @@ void ESPER::selectPhoto(int photoId) {
 void ESPER::unloadPhotos() {
 	for (int i = 0; i < kPhotoCount; ++i) {
 		if (_photos[i].isPresent) {
-			_buttons->resetImage(i);
-			delete _shapesPhotos[i];
-			_shapesPhotos[i] = nullptr;
 			_photos[i].isPresent = false;
+			_buttons->resetImage(i);
 		}
 	}
 }
diff --git a/engines/bladerunner/ui/esper.h b/engines/bladerunner/ui/esper.h
index 0c1c6a8..61f8d2d 100644
--- a/engines/bladerunner/ui/esper.h
+++ b/engines/bladerunner/ui/esper.h
@@ -33,6 +33,7 @@ namespace BladeRunner {
 class BladeRunnerEngine;
 class Font;
 class Shape;
+class Shapes;
 class VQAPlayer;
 class UIImagePicker;
 class ESPERScript;
@@ -101,9 +102,9 @@ class ESPER {
 	VQAPlayer *_vqaPlayerPhoto;
 	int        _vqaLastFrame;
 
-	Shape                 *_shapeButton;
-	Common::Array<Shape *> _shapesPhotos;
-	Shape                 *_shapeThumbnail;
+	Shapes *_shapesButtons;
+	Shapes *_shapesPhotos;
+	const Shape *_shapeThumbnail;
 
 	Photo _photos[kPhotoCount];
 	int   _photoIdSelected;
diff --git a/engines/bladerunner/ui/kia.cpp b/engines/bladerunner/ui/kia.cpp
index 65e3e84..54b481a 100644
--- a/engines/bladerunner/ui/kia.cpp
+++ b/engines/bladerunner/ui/kia.cpp
@@ -50,7 +50,6 @@
 #include "bladerunner/ui/kia_section_pogo.h"
 #include "bladerunner/ui/kia_section_save.h"
 #include "bladerunner/ui/kia_section_suspects.h"
-#include "bladerunner/ui/kia_shapes.h"
 #include "bladerunner/ui/ui_image_picker.h"
 #include "bladerunner/vqa_player.h"
 #include "bladerunner/subtitles.h"
@@ -67,7 +66,8 @@ KIA::KIA(BladeRunnerEngine *vm) {
 
 	_script = new KIAScript(_vm);
 	_log = new KIALog(_vm);
-	_shapes = new KIAShapes(_vm);
+	_shapes = new Shapes(_vm);
+	_playerPhotographs = new Shapes(_vm);
 
 	_forceOpen = false;
 	_currentSectionId = kKIASectionNone;
@@ -77,7 +77,6 @@ KIA::KIA(BladeRunnerEngine *vm) {
 	_playerVqaFrame = 0;
 	_playerVisualizerState = 0;
 	_playerPhotographId = -1;
-	_playerPhotograph = nullptr;
 	_playerSliceModelId = -1;
 	_playerSliceModelAngle = 0.0f;
 	_timeLast = _vm->_time->currentSystem();
@@ -128,9 +127,9 @@ KIA::~KIA() {
 	delete _diagnosticSection;
 	delete _pogoSection;
 	_playerImage.free();
-	delete _playerPhotograph;
 	delete _buttons;
 	delete _shapes;
+	delete _playerPhotographs;
 	delete _log;
 	delete _script;
 }
@@ -332,9 +331,10 @@ void KIA::tick() {
 		if (_playerSliceModelId != -1) {
 			_vm->_sliceRenderer->drawOnScreen(_playerSliceModelId, 0, 585, 80, _playerSliceModelAngle, 100.0, _vm->_surfaceFront);
 		} else if (_playerPhotographId != -1) {
-			int width  = _playerPhotograph->getWidth();
-			int height  = _playerPhotograph->getHeight();
-			_playerPhotograph->draw(_vm->_surfaceFront, 590 - width / 2, 80 - height / 2);
+			const Shape *playerPhotograph = _playerPhotographs->get(_playerPhotographId);
+			int width  = playerPhotograph->getWidth();
+			int height  = playerPhotograph->getHeight();
+			playerPhotograph->draw(_vm->_surfaceFront, 590 - width / 2, 80 - height / 2);
 		} else if (_playerImage.getPixels() != nullptr) {
 			_vm->_surfaceFront.fillRect(Common::Rect(549, 49, 631, 111), _vm->_surfaceFront.format.RGBToColor(255, 255, 255));
 			_vm->_surfaceFront.copyRectToSurface(_playerImage.getPixels(), _playerImage.pitch, 550, 50, _playerImage.w,  _playerImage.h);
@@ -550,10 +550,6 @@ void KIA::playerReset() {
 
 	_playerActorDialogueQueueSize = _playerActorDialogueQueuePosition;
 	_playerSliceModelId = -1;
-	if (_playerPhotographId != -1) {
-		delete _playerPhotograph;
-		_playerPhotograph = nullptr;
-	}
 	_playerPhotographId = -1;
 	_playerImage.free();
 	_playerActorDialogueState = 0;
@@ -582,16 +578,10 @@ void KIA::playSliceModel(int sliceModelId) {
 }
 
 void KIA::playPhotograph(int photographId) {
-	if (_playerPhotographId != -1) {
-		delete _playerPhotograph;
-		_playerPhotograph = nullptr;
-	}
 	if (_playerVqaFrame == 8) {
 		_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxBEEP1), 70, 0, 0, 50, 0);
 	}
 	_playerPhotographId = photographId;
-	_playerPhotograph = new Shape(_vm);
-	_playerPhotograph->open("photos.shp", photographId);
 }
 
 void KIA::playImage(const Graphics::Surface &image) {
@@ -740,11 +730,12 @@ void KIA::init() {
 		playPrivateAddon();
 	}
 
-	_shapes->load();
+	_shapes->load("kiaopt.shp");
+	_playerPhotographs->load("photos.shp");
+
 	_buttons->activate(nullptr, nullptr, mouseDownCallback, mouseUpCallback, this);
 	_vm->_mouse->setCursor(0);
 	if (_playerVqaPlayer == nullptr) {
-
 		_playerVqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceFront, "kiaover.vqa");
 		_playerVqaPlayer->open();
 		_playerVqaPlayer->setLoop(0, -1, kLoopSetModeJustStart, nullptr, nullptr);
@@ -772,18 +763,13 @@ void KIA::unload() {
 	_buttons->deactivate();
 
 	_shapes->unload();
+	_playerPhotographs->unload();
 
-	if (_mainVqaPlayer) {
-		_mainVqaPlayer->close();
-		delete _mainVqaPlayer;
-		_mainVqaPlayer = nullptr;
-	}
+	delete _mainVqaPlayer;
+	_mainVqaPlayer = nullptr;
 
-	if (_playerVqaPlayer) {
-		_playerVqaPlayer->close();
-		delete _playerVqaPlayer;
-		_playerVqaPlayer = nullptr;
-	}
+	delete _playerVqaPlayer;
+	_playerVqaPlayer = nullptr;
 
 	_vm->closeArchive("MODE.MIX");
 
diff --git a/engines/bladerunner/ui/kia.h b/engines/bladerunner/ui/kia.h
index dc10623..fc3984e 100644
--- a/engines/bladerunner/ui/kia.h
+++ b/engines/bladerunner/ui/kia.h
@@ -46,8 +46,8 @@ class KIASectionSettings;
 class KIASectionPogo;
 class KIASectionSave;
 class KIASectionSuspects;
-class KIAShapes;
 class Shape;
+class Shapes;
 class UIImagePicker;
 class VQAPlayer;
 
@@ -83,7 +83,7 @@ class KIA {
 	uint32             _playerVqaFrame;
 	uint32             _playerVisualizerState;
 	int                _playerPhotographId;
-	Shape             *_playerPhotograph;
+	Shapes            *_playerPhotographs;
 	int                _playerSliceModelId;
 	float              _playerSliceModelAngle;
 	Graphics::Surface  _playerImage;
@@ -121,7 +121,7 @@ public:
 
 	KIALog           *_log;
 	KIAScript        *_script;
-	KIAShapes        *_shapes;
+	Shapes           *_shapes;
 
 	Graphics::Surface _thumbnail;
 
diff --git a/engines/bladerunner/ui/kia_section_clues.cpp b/engines/bladerunner/ui/kia_section_clues.cpp
index ce14b94..c24bc7c 100644
--- a/engines/bladerunner/ui/kia_section_clues.cpp
+++ b/engines/bladerunner/ui/kia_section_clues.cpp
@@ -29,11 +29,11 @@
 #include "bladerunner/game_flags.h"
 #include "bladerunner/game_info.h"
 #include "bladerunner/font.h"
+#include "bladerunner/shape.h"
 #include "bladerunner/script/kia_script.h"
 #include "bladerunner/text_resource.h"
 #include "bladerunner/ui/kia.h"
 #include "bladerunner/ui/kia_log.h"
-#include "bladerunner/ui/kia_shapes.h"
 #include "bladerunner/ui/ui_container.h"
 #include "bladerunner/ui/ui_image_picker.h"
 #include "bladerunner/ui/ui_scroll_box.h"
diff --git a/engines/bladerunner/ui/kia_section_crimes.cpp b/engines/bladerunner/ui/kia_section_crimes.cpp
index 4eedd8c..325139f 100644
--- a/engines/bladerunner/ui/kia_section_crimes.cpp
+++ b/engines/bladerunner/ui/kia_section_crimes.cpp
@@ -36,7 +36,6 @@
 #include "bladerunner/ui/kia.h"
 #include "bladerunner/ui/kia_log.h"
 #include "bladerunner/ui/kia_section_suspects.h"
-#include "bladerunner/ui/kia_shapes.h"
 #include "bladerunner/ui/ui_container.h"
 #include "bladerunner/ui/ui_image_picker.h"
 #include "bladerunner/ui/ui_scroll_box.h"
@@ -71,14 +70,14 @@ KIASectionCrimes::KIASectionCrimes(BladeRunnerEngine *vm, ActorClues *clues) : K
 	_suspectSelected = -1;
 	_suspectPhotoShapeId = -1;
 	_suspectPhotoNotUsed = -1;
-	_suspectPhotoShape = nullptr;
+	_suspectPhotoShapes = new Shapes(vm);
 	_suspectsFoundCount = 0;
 	_suspectsFound.resize(_vm->_gameInfo->getSuspectCount());
 	_suspectsWithIdentity.resize(_vm->_gameInfo->getSuspectCount());
 }
 
 KIASectionCrimes::~KIASectionCrimes() {
-	delete _suspectPhotoShape;
+	delete _suspectPhotoShapes;
 
 	_uiContainer->clear();
 
@@ -102,6 +101,8 @@ void KIASectionCrimes::reset() {
 void KIASectionCrimes::open() {
 	_scheduledSwitch = false;
 
+	_suspectPhotoShapes->load("photos.shp");
+
 	_buttons->resetImages();
 	_buttons->defineImage(0, Common::Rect(136, 326, 185, 342), nullptr, _vm->_kia->_shapes->get(32), _vm->_kia->_shapes->get(36), _vm->_textKIA->getText(32));
 	_buttons->defineImage(1, Common::Rect(218, 326, 269, 342), nullptr, _vm->_kia->_shapes->get(33), _vm->_kia->_shapes->get(37), _vm->_textKIA->getText(33));
@@ -128,17 +129,14 @@ void KIASectionCrimes::close() {
 	_isOpen = false;
 	_buttons->deactivate();
 	_cluesScrollBox->hide();
-	if (_suspectPhotoShapeId != -1) {
-		delete _suspectPhotoShape;
-		_suspectPhotoShape = nullptr;
-		_suspectPhotoShapeId = -1;
-	}
+	_suspectPhotoShapes->unload();
 }
 
 void KIASectionCrimes::draw(Graphics::Surface &surface) {
 	const char *text = nullptr;
 	if (_suspectPhotoShapeId != -1) {
-		_suspectPhotoShape->draw(surface, 201 - _suspectPhotoShape->getWidth() / 2, 223 - _suspectPhotoShape->getHeight() / 2);
+		const Shape *shape = _suspectPhotoShapes->get(_suspectPhotoShapeId);
+		shape->draw(surface, 201 - shape->getWidth() / 2, 223 - shape->getHeight() / 2);
 	}
 	if (_suspectPhotoShapeId == 14 || _suspectPhotoShapeId == 13) {
 		text = _vm->_textKIA->getText(49);
@@ -396,11 +394,6 @@ void KIASectionCrimes::populateVisibleClues() {
 }
 
 void KIASectionCrimes::updateSuspectPhoto() {
-	if (_suspectPhotoShapeId != -1) {
-		delete _suspectPhotoShape;
-		_suspectPhotoShape = nullptr;
-	}
-
 	if (_suspectSelected == -1) {
 		_suspectPhotoShapeId = -1;
 		return;
@@ -429,11 +422,6 @@ void KIASectionCrimes::updateSuspectPhoto() {
 			_suspectPhotoShapeId = 13;
 		}
 	}
-
-	if (_suspectPhotoShapeId != -1) {
-		_suspectPhotoShape = new Shape(_vm);
-		_suspectPhotoShape->open("photos.shp", _suspectPhotoShapeId);
-	}
 }
 
 void KIASectionCrimes::nextCrime() {
diff --git a/engines/bladerunner/ui/kia_section_crimes.h b/engines/bladerunner/ui/kia_section_crimes.h
index 1bc3f88..896a6aa 100644
--- a/engines/bladerunner/ui/kia_section_crimes.h
+++ b/engines/bladerunner/ui/kia_section_crimes.h
@@ -23,7 +23,6 @@
 #ifndef BLADERUNNER_KIA_SECTION_CRIME_H
 #define BLADERUNNER_KIA_SECTION_CRIME_H
 
-#include "bladerunner/shape.h"
 #include "bladerunner/ui/kia_section_base.h"
 
 #include "common/array.h"
@@ -32,6 +31,7 @@ namespace BladeRunner {
 
 class ActorClues;
 class BladeRunnerEngine;
+class Shapes;
 class UIContainer;
 class UIImagePicker;
 class UIScrollBox;
@@ -65,12 +65,12 @@ class KIASectionCrimes : public KIASectionBase {
 	Common::Array<bool> _suspectsFound;
 	Common::Array<bool> _suspectsWithIdentity;
 
-	int   _mouseX;
-	int   _mouseY;
+	int _mouseX;
+	int _mouseY;
 
-	int    _suspectPhotoShapeId;
-	int    _suspectPhotoNotUsed;
-	Shape *_suspectPhotoShape;
+	int     _suspectPhotoShapeId;
+	int     _suspectPhotoNotUsed;
+	Shapes *_suspectPhotoShapes;
 
 public:
 	int _suspectSelected;
diff --git a/engines/bladerunner/ui/kia_section_help.cpp b/engines/bladerunner/ui/kia_section_help.cpp
index 7f1cb31..699f3d8 100644
--- a/engines/bladerunner/ui/kia_section_help.cpp
+++ b/engines/bladerunner/ui/kia_section_help.cpp
@@ -23,9 +23,9 @@
 #include "bladerunner/ui/kia_section_help.h"
 
 #include "bladerunner/bladerunner.h"
+#include "bladerunner/shape.h"
 #include "bladerunner/text_resource.h"
 #include "bladerunner/ui/kia.h"
-#include "bladerunner/ui/kia_shapes.h"
 #include "bladerunner/ui/ui_container.h"
 #include "bladerunner/ui/ui_scroll_box.h"
 
diff --git a/engines/bladerunner/ui/kia_section_load.cpp b/engines/bladerunner/ui/kia_section_load.cpp
index 41f2e7e..5deefe7 100644
--- a/engines/bladerunner/ui/kia_section_load.cpp
+++ b/engines/bladerunner/ui/kia_section_load.cpp
@@ -26,11 +26,11 @@
 #include "bladerunner/bladerunner.h"
 #include "bladerunner/game_info.h"
 #include "bladerunner/savefile.h"
+#include "bladerunner/shape.h"
 #include "bladerunner/text_resource.h"
 #include "bladerunner/time.h"
 #include "bladerunner/game_constants.h"
 #include "bladerunner/ui/kia.h"
-#include "bladerunner/ui/kia_shapes.h"
 #include "bladerunner/ui/ui_container.h"
 #include "bladerunner/ui/ui_scroll_box.h"
 
diff --git a/engines/bladerunner/ui/kia_section_save.cpp b/engines/bladerunner/ui/kia_section_save.cpp
index e4a9190..a0a4526 100644
--- a/engines/bladerunner/ui/kia_section_save.cpp
+++ b/engines/bladerunner/ui/kia_section_save.cpp
@@ -27,11 +27,11 @@
 #include "bladerunner/font.h"
 #include "bladerunner/game_info.h"
 #include "bladerunner/savefile.h"
+#include "bladerunner/shape.h"
 #include "bladerunner/text_resource.h"
 #include "bladerunner/time.h"
 #include "bladerunner/game_constants.h"
 #include "bladerunner/ui/kia.h"
-#include "bladerunner/ui/kia_shapes.h"
 #include "bladerunner/ui/ui_container.h"
 #include "bladerunner/ui/ui_image_picker.h"
 #include "bladerunner/ui/ui_input_box.h"
diff --git a/engines/bladerunner/ui/kia_section_settings.cpp b/engines/bladerunner/ui/kia_section_settings.cpp
index 8388d12..15d8080 100644
--- a/engines/bladerunner/ui/kia_section_settings.cpp
+++ b/engines/bladerunner/ui/kia_section_settings.cpp
@@ -32,10 +32,10 @@
 #include "bladerunner/game_info.h"
 #include "bladerunner/music.h"
 #include "bladerunner/settings.h"
+#include "bladerunner/shape.h"
 #include "bladerunner/subtitles.h"
 #include "bladerunner/text_resource.h"
 #include "bladerunner/ui/kia.h"
-#include "bladerunner/ui/kia_shapes.h"
 #include "bladerunner/ui/ui_check_box.h"
 #include "bladerunner/ui/ui_container.h"
 #include "bladerunner/ui/ui_image_picker.h"
diff --git a/engines/bladerunner/ui/kia_section_suspects.cpp b/engines/bladerunner/ui/kia_section_suspects.cpp
index 93895a7..abc8961 100644
--- a/engines/bladerunner/ui/kia_section_suspects.cpp
+++ b/engines/bladerunner/ui/kia_section_suspects.cpp
@@ -35,7 +35,6 @@
 #include "bladerunner/text_resource.h"
 #include "bladerunner/ui/kia.h"
 #include "bladerunner/ui/kia_log.h"
-#include "bladerunner/ui/kia_shapes.h"
 #include "bladerunner/ui/ui_check_box.h"
 #include "bladerunner/ui/ui_container.h"
 #include "bladerunner/ui/ui_image_picker.h"
@@ -87,14 +86,14 @@ KIASectionSuspects::KIASectionSuspects(BladeRunnerEngine *vm, ActorClues *clues)
 	_suspectSelected = -1;
 	_suspectPhotoShapeId = -1;
 	_suspectPhotoNotUsed = -1;
-	_suspectPhotoShape = nullptr;
+	_suspectPhotoShapes = new Shapes(vm);
 	_suspectsFoundCount = 0;
 	_suspectsFound.resize(_vm->_gameInfo->getSuspectCount());
 	_suspectsWithIdentity.resize(_vm->_gameInfo->getSuspectCount());
 }
 
 KIASectionSuspects::~KIASectionSuspects() {
-	delete _suspectPhotoShape;
+	delete _suspectPhotoShapes;
 
 	_uiContainer->clear();
 
@@ -128,6 +127,8 @@ void KIASectionSuspects::reset() {
 void KIASectionSuspects::open() {
 	_scheduledSwitch = false;
 
+	_suspectPhotoShapes->load("photos.shp");
+
 	_buttons->resetImages();
 	_buttons->defineImage(0, Common::Rect(142, 380, 191, 395), _vm->_kia->_shapes->get(79), _vm->_kia->_shapes->get(80), _vm->_kia->_shapes->get(81), _vm->_textKIA->getText(30));
 	_buttons->defineImage(1, Common::Rect(193, 380, 242, 395), _vm->_kia->_shapes->get(76), _vm->_kia->_shapes->get(77), _vm->_kia->_shapes->get(77), _vm->_textKIA->getText(31));
@@ -161,17 +162,14 @@ void KIASectionSuspects::close() {
 	_isOpen = false;
 	_buttons->deactivate();
 	_cluesScrollBox->hide();
-	if (_suspectPhotoShapeId != -1) {
-		delete _suspectPhotoShape;
-		_suspectPhotoShape = nullptr;
-		_suspectPhotoShapeId = -1;
-	}
+
+	_suspectPhotoShapes->unload();
 }
 
 void KIASectionSuspects::draw(Graphics::Surface &surface) {
 	const char *text = nullptr;
 	if (_suspectPhotoShapeId != -1) {
-		_suspectPhotoShape->draw(surface, 142, 150);
+		_suspectPhotoShapes->get(_suspectPhotoShapeId)->draw(surface, 142, 150);
 	}
 	if (_suspectPhotoShapeId == 14 || _suspectPhotoShapeId == 13) {
 		text = _vm->_textKIA->getText(49);
@@ -459,11 +457,6 @@ void KIASectionSuspects::populateVisibleClues() {
 }
 
 void KIASectionSuspects::updateSuspectPhoto() {
-	if (_suspectPhotoShapeId != -1) {
-		delete _suspectPhotoShape;
-		_suspectPhotoShape = nullptr;
-	}
-
 	if (_suspectSelected == -1) {
 		_suspectPhotoShapeId = -1;
 		return;
@@ -492,11 +485,6 @@ void KIASectionSuspects::updateSuspectPhoto() {
 			_suspectPhotoShapeId = 13;
 		}
 	}
-
-	if (_suspectPhotoShapeId != -1) {
-		_suspectPhotoShape = new Shape(_vm);
-		_suspectPhotoShape->open("photos.shp", _suspectPhotoShapeId);
-	}
 }
 
 void KIASectionSuspects::nextSuspect() {
diff --git a/engines/bladerunner/ui/kia_section_suspects.h b/engines/bladerunner/ui/kia_section_suspects.h
index c4ff35b..dc96793 100644
--- a/engines/bladerunner/ui/kia_section_suspects.h
+++ b/engines/bladerunner/ui/kia_section_suspects.h
@@ -31,7 +31,7 @@ namespace BladeRunner {
 
 class ActorClues;
 class BladeRunnerEngine;
-class Shape;
+class Shapes;
 class UICheckBox;
 class UIContainer;
 class UIImagePicker;
@@ -77,9 +77,9 @@ class KIASectionSuspects : public KIASectionBase {
 	int   _mouseX;
 	int   _mouseY;
 
-	int    _suspectPhotoShapeId;
-	int    _suspectPhotoNotUsed;
-	Shape *_suspectPhotoShape;
+	int     _suspectPhotoShapeId;
+	int     _suspectPhotoNotUsed;
+	Shapes *_suspectPhotoShapes;
 
 public:
 	int                 _crimeSelected;
diff --git a/engines/bladerunner/ui/kia_shapes.cpp b/engines/bladerunner/ui/kia_shapes.cpp
deleted file mode 100644
index ce5c8a7..0000000
--- a/engines/bladerunner/ui/kia_shapes.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/* 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/ui/kia_shapes.h"
-
-#include "bladerunner/bladerunner.h"
-
-namespace BladeRunner {
-
-KIAShapes::KIAShapes(BladeRunnerEngine *vm) {
-	_vm = vm;
-	_isLoaded = false;
-	for (uint i = 0; i < kShapeCount; ++i) {
-		_shapes[i] = nullptr;
-	}
-}
-
-KIAShapes::~KIAShapes() {
-	unload();
-}
-
-void KIAShapes::load() {
-	if (_isLoaded) {
-		return;
-	}
-
-	for (uint i = 0; i < kShapeCount; ++i) {
-		Shape *shape = new Shape(_vm);
-		shape->open("kiaopt.shp", i);
-		_shapes[i] = shape;
-	}
-
-	_isLoaded = true;
-}
-
-void KIAShapes::unload() {
-	if (!_isLoaded) {
-		return;
-	}
-
-	for (uint i = 0; i < kShapeCount; ++i) {
-		delete _shapes[i];
-		_shapes[i] = nullptr;
-	}
-
-	_isLoaded = false;
-}
-
-const Shape *KIAShapes::get(int shapeId) const {
-	return _shapes[shapeId];
-}
-
-} // End of namespace BladeRunner
diff --git a/engines/bladerunner/ui/kia_shapes.h b/engines/bladerunner/ui/kia_shapes.h
deleted file mode 100644
index af1898f..0000000
--- a/engines/bladerunner/ui/kia_shapes.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* 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_UI_SHAPES_H
-#define BLADERUNNER_UI_SHAPES_H
-
-#include "bladerunner/shape.h"
-
-#include "common/array.h"
-
-namespace BladeRunner {
-
-class BladeRunnerEngine;
-
-class KIAShapes {
-	static const uint kShapeCount = 132;
-
-	BladeRunnerEngine *_vm;
-	const Shape       *_shapes[kShapeCount];
-	bool               _isLoaded;
-
-public:
-	KIAShapes(BladeRunnerEngine *vm);
-	~KIAShapes();
-
-	void load();
-	void unload();
-	const Shape *get(int shapeId) const;
-};
-
-} // End of namespace BladeRunner
-
-#endif
diff --git a/engines/bladerunner/ui/spinner.cpp b/engines/bladerunner/ui/spinner.cpp
index 27116a8..4e7379d 100644
--- a/engines/bladerunner/ui/spinner.cpp
+++ b/engines/bladerunner/ui/spinner.cpp
@@ -48,17 +48,14 @@ Spinner::Spinner(BladeRunnerEngine *vm) {
 	reset();
 	_imagePicker = new UIImagePicker(vm, kSpinnerDestinations);
 	_vqaPlayer = nullptr;
+	_shapes = new Shapes(vm);
 }
 
 Spinner::~Spinner() {
 	delete _imagePicker;
-
+	delete _vqaPlayer;
+	delete _shapes;
 	reset();
-
-	if (_vqaPlayer != nullptr) {
-		_vqaPlayer->close();
-		delete _vqaPlayer;
-	}
 }
 
 void Spinner::setSelectableDestinationFlag(int destination, bool selectable) {
@@ -106,25 +103,17 @@ int Spinner::chooseDestination(int loopId, bool immediately) {
 	}
 
 	_destinations = nullptr;
-	int firstShapeId = 0;
-	int shapeCount = 0;
 	int spinnerLoopId = 4;
 
-	if (mapmask & 4) {
-		_destinations = getDestinationsFar();
-		firstShapeId = 26;
-		shapeCount = 20;
-		spinnerLoopId = 4;
+	if (mapmask & 1) {
+		_destinations = getDestinationsNear();
+		spinnerLoopId = 0;
 	} else if (mapmask & 2) {
 		_destinations = getDestinationsMedium();
-		firstShapeId = 10;
-		shapeCount = 16;
 		spinnerLoopId = 2;
-	} else if (mapmask & 1) {
-		_destinations = getDestinationsNear();
-		firstShapeId = 0;
-		shapeCount = 10;
-		spinnerLoopId = 0;
+	} else if (mapmask & 4) {
+		_destinations = getDestinationsFar();
+		spinnerLoopId = 4;
 	} else {
 		return -1;
 	}
@@ -132,10 +121,7 @@ int Spinner::chooseDestination(int loopId, bool immediately) {
 	_vqaPlayer->setLoop(spinnerLoopId,     -1, kLoopSetModeImmediate, nullptr, nullptr);
 	_vqaPlayer->setLoop(spinnerLoopId + 1, -1, kLoopSetModeJustStart, nullptr, nullptr);
 
-	for (int j = 0; j != shapeCount; ++j) {
-		_shapes.push_back(new Shape(_vm));
-		_shapes[j]->open("SPINNER.SHP", firstShapeId + j);
-	}
+	_shapes->load("SPINNER.SHP");
 
 	_imagePicker->resetImages();
 
@@ -149,9 +135,9 @@ int Spinner::chooseDestination(int loopId, bool immediately) {
 		_imagePicker->defineImage(
 			dest->id,
 			dest->rect,
-			_shapes[dest->id],
-			_shapes[dest->id + _shapes.size() / 2],
-			_shapes[dest->id + _shapes.size() / 2],
+			_shapes->get(dest->shapeId),
+			_shapes->get(dest->shapeIdOver),
+			_shapes->get(dest->shapeIdOver),
 			tooltip
 		);
 	}
@@ -185,12 +171,8 @@ int Spinner::chooseDestination(int loopId, bool immediately) {
 
 	_imagePicker->deactivate();
 
-	for (int i = 0; i != (int)_shapes.size(); ++i) {
-		delete _shapes[i];
-	}
-	_shapes.clear();
+	_shapes->unload();
 
-	_vqaPlayer->close();
 	delete _vqaPlayer;
 	_vqaPlayer = nullptr;
 
@@ -295,11 +277,6 @@ void Spinner::reset() {
 	_actorId = -1;
 	_sentenceId = -1;
 	_timeSpeakDescriptionStart = 0u;
-
-	for (int i = 0; i != (int)_shapes.size(); ++i) {
-		delete _shapes[i];
-	}
-	_shapes.clear();
 }
 
 void Spinner::resume() {
@@ -329,44 +306,44 @@ void Spinner::load(SaveFileReadStream &f) {
 
 const Spinner::Destination *Spinner::getDestinationsFar() {
 	static const Destination destinations[] = {
-		{  0, Common::Rect(220, 227, 246, 262) },
-		{  1, Common::Rect(260, 252, 286, 279) },
-		{  2, Common::Rect(286, 178, 302, 196) },
-		{  3, Common::Rect(244, 178, 263, 195) },
-		{  4, Common::Rect(288, 216, 306, 228) },
-		{  5, Common::Rect(249,  77, 353, 124) },
-		{  6, Common::Rect(190, 127, 208, 138) },
-		{  7, Common::Rect(185, 149, 206, 170) },
-		{  8, Common::Rect(398, 249, 419, 268) },
-		{  9, Common::Rect(390, 218, 419, 236) },
-		{ -1, Common::Rect(-1, -1, -1, -1) }
+		{  0, Common::Rect(220, 227, 246, 262), 26 , 36 },
+		{  1, Common::Rect(260, 252, 286, 279), 27 , 37 },
+		{  2, Common::Rect(286, 178, 302, 196), 28 , 38 },
+		{  3, Common::Rect(244, 178, 263, 195), 29 , 39 },
+		{  4, Common::Rect(288, 216, 306, 228), 30 , 40 },
+		{  5, Common::Rect(249,  77, 353, 124), 31 , 41 },
+		{  6, Common::Rect(190, 127, 208, 138), 32 , 42 },
+		{  7, Common::Rect(185, 149, 206, 170), 33 , 43 },
+		{  8, Common::Rect(398, 249, 419, 268), 34 , 44 },
+		{  9, Common::Rect(390, 218, 419, 236), 35 , 45 },
+		{ -1, Common::Rect(-1, -1, -1, -1), 0, 0 }
 	};
 	return destinations;
 }
 
 const Spinner::Destination *Spinner::getDestinationsMedium() {
 	static const Destination destinations[] = {
-		{  0, Common::Rect(252, 242, 279, 283) },
-		{  1, Common::Rect(301, 273, 328, 304) },
-		{  2, Common::Rect(319, 182, 336, 200) },
-		{  3, Common::Rect(269, 181, 293, 200) },
-		{  4, Common::Rect(325, 227, 345, 240) },
-		{  5, Common::Rect(259,  74, 380, 119) },
-		{  6, Common::Rect(203, 124, 224, 136) },
-		{  7, Common::Rect(200, 147, 222, 170) },
-		{ -1, Common::Rect(-1,-1,-1,-1) }
+		{  0, Common::Rect(252, 242, 279, 283), 10, 18 },
+		{  1, Common::Rect(301, 273, 328, 304), 11, 19 },
+		{  2, Common::Rect(319, 182, 336, 200), 12, 20 },
+		{  3, Common::Rect(269, 181, 293, 200), 13, 21 },
+		{  4, Common::Rect(325, 227, 345, 240), 14, 22 },
+		{  5, Common::Rect(259,  74, 380, 119), 15, 23 },
+		{  6, Common::Rect(203, 124, 224, 136), 16, 24 },
+		{  7, Common::Rect(200, 147, 222, 170), 17, 25 },
+		{ -1, Common::Rect(-1,-1,-1,-1), 0, 0 }
 	};
 	return destinations;
 }
 
 const Spinner::Destination *Spinner::getDestinationsNear() {
 	static const Destination destinations[] = {
-		{  0, Common::Rect(210, 263, 263, 332) },
-		{  1, Common::Rect(307, 330, 361, 381) },
-		{  2, Common::Rect(338, 137, 362, 169) },
-		{  3, Common::Rect(248, 135, 289, 168) },
-		{  4, Common::Rect(352, 222, 379, 238) },
-		{ -1, Common::Rect(-1,-1,-1,-1) }
+		{  0, Common::Rect(210, 263, 263, 332), 0, 5 },
+		{  1, Common::Rect(307, 330, 361, 381), 1, 6 },
+		{  2, Common::Rect(338, 137, 362, 169), 2, 7 },
+		{  3, Common::Rect(248, 135, 289, 168), 3, 8 },
+		{  4, Common::Rect(352, 222, 379, 238), 4, 9 },
+		{ -1, Common::Rect(-1,-1,-1,-1), 0, 0 }
 	};
 	return destinations;
 }
diff --git a/engines/bladerunner/ui/spinner.h b/engines/bladerunner/ui/spinner.h
index 2fa0dc6..df9c666 100644
--- a/engines/bladerunner/ui/spinner.h
+++ b/engines/bladerunner/ui/spinner.h
@@ -31,7 +31,7 @@ namespace BladeRunner {
 class BladeRunnerEngine;
 class SaveFileReadStream;
 class SaveFileWriteStream;
-class Shape;
+class Shapes;
 class UIImagePicker;
 class VQAPlayer;
 
@@ -41,20 +41,22 @@ class Spinner {
 	struct Destination {
 		int          id;
 		Common::Rect rect;
+		int          shapeId;
+		int          shapeIdOver;
 	};
 
-	BladeRunnerEngine      *_vm;
-	bool                    _isDestinationSelectable[kSpinnerDestinations];
-	bool                    _isOpen;
-	VQAPlayer              *_vqaPlayer;
-	const Destination      *_destinations;
-	int                     _selectedDestination;
-	Common::Array<Shape *>  _shapes;
-	UIImagePicker          *_imagePicker;
-
-	int                    _actorId;
-	int                    _sentenceId;
-	uint32                 _timeSpeakDescriptionStart;
+	BladeRunnerEngine *_vm;
+	bool               _isDestinationSelectable[kSpinnerDestinations];
+	bool               _isOpen;
+	VQAPlayer         *_vqaPlayer;
+	const Destination *_destinations;
+	int                _selectedDestination;
+	Shapes            *_shapes;
+	UIImagePicker     *_imagePicker;
+
+	int                _actorId;
+	int                _sentenceId;
+	uint32             _timeSpeakDescriptionStart;
 
 public:
 	Spinner(BladeRunnerEngine *vm);
diff --git a/engines/bladerunner/ui/ui_check_box.cpp b/engines/bladerunner/ui/ui_check_box.cpp
index 38fb86c..8bc467b 100644
--- a/engines/bladerunner/ui/ui_check_box.cpp
+++ b/engines/bladerunner/ui/ui_check_box.cpp
@@ -24,11 +24,11 @@
 
 #include "bladerunner/audio_player.h"
 #include "bladerunner/bladerunner.h"
+#include "bladerunner/game_constants.h"
 #include "bladerunner/game_info.h"
+#include "bladerunner/shape.h"
 #include "bladerunner/time.h"
-#include "bladerunner/game_constants.h"
 #include "bladerunner/ui/kia.h"
-#include "bladerunner/ui/kia_shapes.h"
 
 namespace BladeRunner {
 
diff --git a/engines/bladerunner/ui/ui_scroll_box.cpp b/engines/bladerunner/ui/ui_scroll_box.cpp
index b24aa89..b3b861e 100644
--- a/engines/bladerunner/ui/ui_scroll_box.cpp
+++ b/engines/bladerunner/ui/ui_scroll_box.cpp
@@ -30,7 +30,6 @@
 #include "bladerunner/time.h"
 #include "bladerunner/game_constants.h"
 #include "bladerunner/ui/kia.h"
-#include "bladerunner/ui/kia_shapes.h"
 
 namespace BladeRunner {
 
diff --git a/engines/bladerunner/ui/vk.cpp b/engines/bladerunner/ui/vk.cpp
index 245bae9..88c0892 100644
--- a/engines/bladerunner/ui/vk.cpp
+++ b/engines/bladerunner/ui/vk.cpp
@@ -51,12 +51,13 @@ namespace BladeRunner {
 
 VK::VK(BladeRunnerEngine *vm) {
 	_vm = vm;
-
+	_shapes = new Shapes(vm);
 	reset();
 }
 
 VK::~VK() {
 	reset();
+	delete _shapes;
 }
 
 void VK::open(int actorId, int calibrationRatio) {
@@ -84,11 +85,7 @@ void VK::open(int actorId, int calibrationRatio) {
 
 	_buttons = new UIImagePicker(_vm, 8);
 
-	_shapes.resize(15);
-	for (int i = 0; i < (int)_shapes.size(); ++i) {
-		_shapes[i] = new Shape(_vm);
-		_shapes[i]->open("VK.SHP", i);
-	}
+	_shapes->load("VK.SHP");
 
 	_vqaPlayerMain = new VQAPlayer(_vm, &_vm->_surfaceBack, "VK.VQA");
 	if (!_vqaPlayerMain->open()) {
@@ -176,10 +173,7 @@ void VK::close() {
 
 	_questions.clear();
 
-	for (int i = 0; i < (int)_shapes.size(); ++i) {
-		delete _shapes[i];
-	}
-	_shapes.clear();
+	_shapes->unload();
 
 	_vm->closeArchive("MODE.MIX");
 	_vm->_music->setVolume(_volumeMusic);
@@ -447,7 +441,7 @@ void VK::reset() {
 
 	_isOpen = false;
 
-	_shapes.clear();
+	_shapes->unload();
 
 	_volumeAmbient = 0;
 	_volumeMusic   = 0;
@@ -519,14 +513,14 @@ void VK::init() {
 	_vm->_mouse->disable();
 
 	_buttons->activate(nullptr, nullptr, mouseDownCallback, mouseUpCallback, this);
-	_buttons->defineImage(0, Common::Rect(191, 364, 218, 373), nullptr,    _shapes[2],  _shapes[3],  _vm->_textVK->getText(1));
-	_buttons->defineImage(1, Common::Rect(154, 258, 161, 265), _shapes[4], _shapes[4],  _shapes[5],  _vm->_textVK->getText(2));
-	_buttons->defineImage(2, Common::Rect(515, 368, 538, 398), nullptr,    _shapes[6],  _shapes[7],  nullptr);
-	_buttons->defineImage(3, Common::Rect(548, 368, 571, 398), nullptr,    _shapes[8],  _shapes[9],  nullptr);
-	_buttons->defineImage(4, Common::Rect(581, 368, 604, 398), nullptr,    _shapes[10], _shapes[11], nullptr);
-	_buttons->defineImage(5, Common::Rect( 31, 363,  65, 392), nullptr,    _shapes[0],  _shapes[1], _vm->_textVK->getText(0));
-	_buttons->defineImage(6, Common::Rect( 59, 262,  87, 277), nullptr,    nullptr,     nullptr,    _vm->_textVK->getText(6));
-	_buttons->defineImage(7, Common::Rect( 59, 306,  87, 322), nullptr,    nullptr,     nullptr,    _vm->_textVK->getText(7));
+	_buttons->defineImage(0, Common::Rect(191, 364, 218, 373), nullptr,         _shapes->get(2),  _shapes->get(3),  _vm->_textVK->getText(1));
+	_buttons->defineImage(1, Common::Rect(154, 258, 161, 265), _shapes->get(4), _shapes->get(4),  _shapes->get(5),  _vm->_textVK->getText(2));
+	_buttons->defineImage(2, Common::Rect(515, 368, 538, 398), nullptr,         _shapes->get(6),  _shapes->get(7),  nullptr);
+	_buttons->defineImage(3, Common::Rect(548, 368, 571, 398), nullptr,         _shapes->get(8),  _shapes->get(9),  nullptr);
+	_buttons->defineImage(4, Common::Rect(581, 368, 604, 398), nullptr,         _shapes->get(10), _shapes->get(11), nullptr);
+	_buttons->defineImage(5, Common::Rect( 31, 363,  65, 392), nullptr,         _shapes->get(0),  _shapes->get(1),  _vm->_textVK->getText(0));
+	_buttons->defineImage(6, Common::Rect( 59, 262,  87, 277), nullptr,         nullptr,          nullptr,          _vm->_textVK->getText(6));
+	_buttons->defineImage(7, Common::Rect( 59, 306,  87, 322), nullptr,         nullptr,          nullptr,          _vm->_textVK->getText(7));
 
 	_script->initialize(_actorId);
 
@@ -592,11 +586,11 @@ void VK::draw() {
 				_blinkState = 0;
 			} else {
 				if (_humanProbability >= 80) {
-					_buttons->setImageShapeUp(6, _shapes[13]);
+					_buttons->setImageShapeUp(6, _shapes->get(13));
 					_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxCROSLOCK), 100, 0, 0, 50, 0);
 				}
 				if (_replicantProbability >= 80) {
-					_buttons->setImageShapeUp(7, _shapes[14]);
+					_buttons->setImageShapeUp(7, _shapes->get(14));
 					_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxCROSLOCK), 100, 0, 0, 50, 0);
 				}
 				_blinkState = 1;
@@ -662,7 +656,7 @@ void VK::draw() {
 				_buttons->setImageShapeUp(0, nullptr);
 				_blinkState = false;
 			} else {
-				_buttons->setImageShapeUp(0, _shapes[2]);
+				_buttons->setImageShapeUp(0, _shapes->get(2));
 				_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxVKBEEP1), 50, 0, 0, 50, 0);
 				_blinkState = true;
 			}
@@ -696,9 +690,9 @@ void VK::draw() {
 				_buttons->setImageShapeUp(4, nullptr);
 				_blinkState = 0;
 			} else {
-				_buttons->setImageShapeUp(2, _shapes[7]);
-				_buttons->setImageShapeUp(3, _shapes[9]);
-				_buttons->setImageShapeUp(4, _shapes[11]);
+				_buttons->setImageShapeUp(2, _shapes->get(7));
+				_buttons->setImageShapeUp(3, _shapes->get(9));
+				_buttons->setImageShapeUp(4, _shapes->get(11));
 				_blinkState = 1;
 
 				_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxVKBEEP2), 33, 0, 0, 50, 0);
@@ -857,7 +851,7 @@ void VK::drawMouse(Graphics::Surface &surface) {
 }
 
 void VK::drawGauge(Graphics::Surface &surface, int value, int x, int y, int width) {
-	_shapes[12]->draw(surface, x + (width / 2) * value / 20 , y);
+	_shapes->get(12)->draw(surface, x + (width / 2) * value / 20 , y);
 }
 
 void VK::drawHumanGauge(Graphics::Surface &surface) {
@@ -885,16 +879,16 @@ void VK::calibrate() {
 	_calibrationStarted = true;
 	_buttons->setImageShapeUp(0, nullptr);
 
-	_buttons->setImageShapeHovered(2, _shapes[6]);
-	_buttons->setImageShapeDown(2, _shapes[7]);
+	_buttons->setImageShapeHovered(2, _shapes->get(6));
+	_buttons->setImageShapeDown(2, _shapes->get(7));
 	_buttons->setImageTooltip(2, _vm->_textVK->getText(3));
 
-	_buttons->setImageShapeHovered(3, _shapes[8]);
-	_buttons->setImageShapeDown(3, _shapes[9]);
+	_buttons->setImageShapeHovered(3, _shapes->get(8));
+	_buttons->setImageShapeDown(3, _shapes->get(9));
 	_buttons->setImageTooltip(3, _vm->_textVK->getText(4));
 
-	_buttons->setImageShapeHovered(4, _shapes[10]);
-	_buttons->setImageShapeDown(4, _shapes[11]);
+	_buttons->setImageShapeHovered(4, _shapes->get(10));
+	_buttons->setImageShapeDown(4, _shapes->get(11));
 	_buttons->setImageTooltip(4, _vm->_textVK->getText(5));
 }
 
@@ -907,7 +901,7 @@ void VK::beginTest() {
 		_buttons->setImageShapeHovered(0, nullptr);
 		_buttons->setImageShapeDown(0, nullptr);
 		_buttons->setImageTooltip(0, nullptr);
-		_buttons->setImageShapeDown(1, _shapes[4]);
+		_buttons->setImageShapeDown(1, _shapes->get(4));
 		_buttons->setImageTooltip(1, nullptr);
 		_buttons->setImageShapeUp(2, nullptr);
 		_buttons->setImageShapeUp(3, nullptr);
diff --git a/engines/bladerunner/ui/vk.h b/engines/bladerunner/ui/vk.h
index eeaee1b..b4a0bcc 100644
--- a/engines/bladerunner/ui/vk.h
+++ b/engines/bladerunner/ui/vk.h
@@ -32,7 +32,7 @@ namespace BladeRunner {
 
 class BladeRunnerEngine;
 class VKScript;
-class Shape;
+class Shapes;
 class UIImagePicker;
 class VQAPlayer;
 
@@ -51,12 +51,12 @@ class VK {
 	VKScript *_script;
 
 	UIImagePicker *_buttons;
-	Common::Array<Shape *> _shapes;
+	Shapes        *_shapes;
 
 	VQAPlayer *_vqaPlayerMain;
 	VQAPlayer *_vqaPlayerEye;
-	int  _vqaFrameMain;
-	bool _vqaLoopEnded;
+	int        _vqaFrameMain;
+	bool       _vqaLoopEnded;
 
 	Graphics::Surface _surfaceEye;
 





More information about the Scummvm-git-logs mailing list