[Scummvm-git-logs] scummvm master -> 5ae6c3407419458420ee9c5f0c7eafa7d6403b40

djsrv dservilla at gmail.com
Wed Jul 1 15:00:24 UTC 2020


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

Summary:
dea03c1171 DIRECTOR: Rename movie.cpp -> video.cpp
3303ab985e DIRECTOR: Rename cast.cpp -> castmember.cpp
5ae6c34074 DIRECTOR: Separate Movie and Cast from Score


Commit: dea03c11716493e597736de98cd6585ad5a5ff1a
    https://github.com/scummvm/scummvm/commit/dea03c11716493e597736de98cd6585ad5a5ff1a
Author: djsrv (dservilla at gmail.com)
Date: 2020-07-01T10:50:31-04:00

Commit Message:
DIRECTOR: Rename movie.cpp -> video.cpp

Changed paths:
  A engines/director/video.cpp
  A engines/director/video.h
  R engines/director/movie.cpp
  R engines/director/movie.h
    engines/director/module.mk


diff --git a/engines/director/module.mk b/engines/director/module.mk
index 196a030656..ba48899fce 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -9,7 +9,6 @@ MODULE_OBJS = \
 	frame.o \
 	graphics.o \
 	images.o \
-	movie.o \
 	resource.o \
 	stage.o \
 	score-loading.o \
@@ -20,6 +19,7 @@ MODULE_OBJS = \
 	tests.o \
 	transitions.o \
 	util.o \
+	video.o \
 	lingo/lingo-gr.o \
 	lingo/lingo.o \
 	lingo/lingo-builtins.o \
diff --git a/engines/director/movie.cpp b/engines/director/video.cpp
similarity index 89%
rename from engines/director/movie.cpp
rename to engines/director/video.cpp
index 653afe13ba..f303f0bf1e 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/video.cpp
@@ -24,12 +24,12 @@
 #include "graphics/managed_surface.h"
 #include "video/qt_decoder.h"
 
-#include "director/movie.h"
+#include "director/video.h"
 #include "director/util.h"
 
 namespace Director {
 
-Movie::Movie(Common::String fileName, DirectorEngine *vm) {
+DigitalVideo::DigitalVideo(Common::String fileName, DirectorEngine *vm) {
 	_vm = vm;
 	_currentVideo = new Video::QuickTimeDecoder();
 	if (!_currentVideo->loadFile(fileName)) {
@@ -38,7 +38,7 @@ Movie::Movie(Common::String fileName, DirectorEngine *vm) {
 	}
 }
 
-void Movie::play(Common::Point dest) {
+void DigitalVideo::play(Common::Point dest) {
 
 	_currentVideo->start();
 
@@ -56,11 +56,11 @@ void Movie::play(Common::Point dest) {
 	}
 }
 
-void Movie::stop() {
+void DigitalVideo::stop() {
 	_currentVideo->stop();
 }
 
-Movie::~Movie() {
+DigitalVideo::~DigitalVideo() {
 	delete _currentVideo;
 }
 
diff --git a/engines/director/movie.h b/engines/director/video.h
similarity index 92%
rename from engines/director/movie.h
rename to engines/director/video.h
index 4ef8ea9860..8a7f35aca2 100644
--- a/engines/director/movie.h
+++ b/engines/director/video.h
@@ -31,10 +31,10 @@ namespace Director {
 
 class DirectorEngine;
 
-class Movie {
+class DigitalVideo {
 public:
-	Movie(Common::String fileName, DirectorEngine *vm);
-	~Movie();
+	DigitalVideo(Common::String fileName, DirectorEngine *vm);
+	~DigitalVideo();
 	void play(Common::Point dest);
 	void stop();
 


Commit: 3303ab985e8072fd9acdb267e67eee23206b7eb0
    https://github.com/scummvm/scummvm/commit/3303ab985e8072fd9acdb267e67eee23206b7eb0
Author: djsrv (dservilla at gmail.com)
Date: 2020-07-01T10:50:31-04:00

Commit Message:
DIRECTOR: Rename cast.cpp -> castmember.cpp

Changed paths:
  A engines/director/castmember.cpp
  A engines/director/castmember.h
  R engines/director/cast.cpp
  R engines/director/cast.h
    engines/director/director.h
    engines/director/events.cpp
    engines/director/frame.cpp
    engines/director/frame.h
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo-codegen.cpp
    engines/director/lingo/lingo-funcs.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo.cpp
    engines/director/module.mk
    engines/director/resource.cpp
    engines/director/score-loading.cpp
    engines/director/score.cpp
    engines/director/score.h
    engines/director/sound.cpp
    engines/director/sprite.cpp
    engines/director/sprite.h
    engines/director/stage.cpp


diff --git a/engines/director/cast.cpp b/engines/director/castmember.cpp
similarity index 84%
rename from engines/director/cast.cpp
rename to engines/director/castmember.cpp
index 677bb58f78..929c57d048 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/castmember.cpp
@@ -28,14 +28,14 @@
 #include "image/image_decoder.h"
 
 #include "director/director.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/score.h"
 #include "director/sound.h"
 #include "director/stxt.h"
 
 namespace Director {
 
-Cast::Cast() {
+CastMember::CastMember() {
 	_type = kCastTypeNull;
 	_score = nullptr;
 	_widget = nullptr;
@@ -44,7 +44,7 @@ Cast::Cast() {
 	_modified = true;
 }
 
-BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16 version) {
+BitmapCastMember::BitmapCastMember(Common::ReadStreamEndian &stream, uint32 castTag, uint16 version) {
 	_type = kCastBitmap;
 	_img = nullptr;
 	_bytes = 0;
@@ -97,7 +97,7 @@ BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16
 			tail++;
 		}
 
-		warning("BitmapCast: %d bytes left", tail);
+		warning("BitmapCastMember: %d bytes left", tail);
 	} else if (version == 5) {
 		uint16 count = stream.readUint16();
 		for (uint16 cc = 0; cc < count; cc++)
@@ -120,16 +120,16 @@ BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16
 	_tag = castTag;
 }
 
-BitmapCast::~BitmapCast() {
+BitmapCastMember::~BitmapCastMember() {
 	if (_img)
 		delete _img;
 }
 
-void BitmapCast::createWidget() {
-	Cast::createWidget();
+void BitmapCastMember::createWidget() {
+	CastMember::createWidget();
 
 	if (!_img) {
-		warning("BitmapCast::createWidget: No image decoder");
+		warning("BitmapCastMember::createWidget: No image decoder");
 		return;
 	}
 
@@ -137,11 +137,11 @@ void BitmapCast::createWidget() {
 	_widget->getSurface()->blitFrom(*_img->getSurface());
 }
 
-DigitalVideoCast::DigitalVideoCast(Common::ReadStreamEndian &stream, uint16 version) {
+DigitalVideoCastMember::DigitalVideoCastMember(Common::ReadStreamEndian &stream, uint16 version) {
 	_type = kCastDigitalVideo;
 
 	if (version < 4) {
-		warning("STUB: DigitalVideoCast: unhandled properties data");
+		warning("STUB: DigitalVideoCastMember: unhandled properties data");
 		for (int i = 0; i < 0xd; i++) {
 			stream.readByte();
 		}
@@ -181,7 +181,7 @@ DigitalVideoCast::DigitalVideoCast(Common::ReadStreamEndian &stream, uint16 vers
 	}
 }
 
-SoundCast::SoundCast(Common::ReadStreamEndian &stream, uint16 version) {
+SoundCastMember::SoundCastMember(Common::ReadStreamEndian &stream, uint16 version) {
 	_type = kCastSound;
 	_audio = nullptr;
 	_looping = 0;
@@ -194,7 +194,7 @@ SoundCast::SoundCast(Common::ReadStreamEndian &stream, uint16 version) {
 	}
 }
 
-TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version, bool asButton) {
+TextCastMember::TextCastMember(Common::ReadStreamEndian &stream, uint16 version, bool asButton) {
 	_type = kCastText;
 
 	_borderSize = kSizeNone;
@@ -235,7 +235,7 @@ TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version, bool asButt
 		if (version == 2) {
 			pad2 = stream.readUint16();
 			if (pad2 != 0) { // In D2 there are values
-				warning("TextCast: pad2: %x", pad2);
+				warning("TextCastMember: pad2: %x", pad2);
 			}
 
 			_initialRect = Score::readRect(stream);
@@ -255,12 +255,12 @@ TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version, bool asButt
 			totalTextHeight = stream.readUint16();
 		}
 
-		debugC(2, kDebugLoading, "TextCast(): flags1: %d, border: %d gutter: %d shadow: %d pad1: %x align: %04x",
+		debugC(2, kDebugLoading, "TextCastMember(): flags1: %d, border: %d gutter: %d shadow: %d pad1: %x align: %04x",
 				_flags, _borderSize, _gutterSize, _boxShadow, pad1, _textAlign);
-		debugC(2, kDebugLoading, "TextCast(): background rgb: 0x%04x 0x%04x 0x%04x, pad2: %x pad3: %d pad4: %d shadow: %d flags: %d totHeight: %d",
+		debugC(2, kDebugLoading, "TextCastMember(): background rgb: 0x%04x 0x%04x 0x%04x, pad2: %x pad3: %d pad4: %d shadow: %d flags: %d totHeight: %d",
 				_bgpalinfo1, _bgpalinfo2, _bgpalinfo3, pad2, pad3, pad4, _textShadow, _textFlags, totalTextHeight);
 		if (debugChannelSet(2, kDebugLoading)) {
-			_initialRect.debugPrint(2, "TextCast(): rect:");
+			_initialRect.debugPrint(2, "TextCastMember(): rect:");
 		}
 	} else if (version == 4) {
 		byte flags = stream.readByte();
@@ -322,7 +322,7 @@ TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version, bool asButt
 			stream.readByte();
 			stream.readByte();
 
-			// This has already been populated in the super TextCast constructor
+			// This has already been populated in the super TextCastMember constructor
 			//initialRect = Score::readRect(stream);
 			//boundingRect = Score::readRect(stream);
 
@@ -335,7 +335,7 @@ TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version, bool asButt
 	_modified = true;
 }
 
-void TextCast::setColors(int *fgcolor, int *bgcolor) {
+void TextCastMember::setColors(int *fgcolor, int *bgcolor) {
 	if (!_widget)
 		return;
 
@@ -349,7 +349,7 @@ void TextCast::setColors(int *fgcolor, int *bgcolor) {
 	((Graphics::MacText *)_widget)->_fullRefresh = true;
 }
 
-void TextCast::getColors(int *fgcolor, int *bgcolor) {
+void TextCastMember::getColors(int *fgcolor, int *bgcolor) {
 	if (fgcolor)
 		*fgcolor = _fgcolor;
 
@@ -357,7 +357,7 @@ void TextCast::getColors(int *fgcolor, int *bgcolor) {
 		*bgcolor = _bgcolor;
 }
 
-Graphics::TextAlign TextCast::getAlignment() {
+Graphics::TextAlign TextCastMember::getAlignment() {
 	switch (_textAlign) {
 	case kTextAlignRight:
 		return Graphics::kTextAlignRight;
@@ -369,7 +369,7 @@ Graphics::TextAlign TextCast::getAlignment() {
 	}
 }
 
-void TextCast::importStxt(const Stxt *stxt) {
+void TextCastMember::importStxt(const Stxt *stxt) {
 	_fontId = stxt->_fontId;
 	_textSlant = stxt->_textSlant;
 	_fontSize = stxt->_fontSize;
@@ -382,8 +382,8 @@ void TextCast::importStxt(const Stxt *stxt) {
 	_fgcolor = g_director->_wm->findBestColor(_fgpalinfo1 & 0xff, _fgpalinfo2 & 0xff, _fgpalinfo3 & 0xff);
 }
 
-void TextCast::createWidget() {
-	Cast::createWidget();
+void TextCastMember::createWidget() {
+	CastMember::createWidget();
 
 	Graphics::MacFont *macFont = new Graphics::MacFont(_fontId, _fontSize, _textSlant);
 
@@ -409,7 +409,7 @@ void TextCast::createWidget() {
 	delete macFont;
 }
 
-void TextCast::importRTE(byte *text) {
+void TextCastMember::importRTE(byte *text) {
 	//assert(rteList.size() == 3);
 	//child0 is probably font data.
 	//child1 is the raw text.
@@ -417,7 +417,7 @@ void TextCast::importRTE(byte *text) {
 	//child2 is positional?
 }
 
-void TextCast::setText(const char *text) {
+void TextCastMember::setText(const char *text) {
 	// Do nothing if text did not change
 	if (_ftext.equals(text))
 		return;
@@ -434,29 +434,29 @@ void TextCast::setText(const char *text) {
 	_modified = true;
 }
 
-Common::String TextCast::getText() {
+Common::String TextCastMember::getText() {
 	if (_widget)
 		_ptext = ((Graphics::MacText *)_widget)->getEditedString().encode();
 
 	return _ptext;
 }
 
-bool TextCast::isModified() {
+bool TextCastMember::isModified() {
 	return _modified || (_widget ? ((Graphics::MacText *)_widget)->_contentIsDirty : false);
 }
 
-bool TextCast::isEditable() {
+bool TextCastMember::isEditable() {
 	if (!_widget) {
-		warning("TextCast::setEditable: Attempt to set editable of null widget");
+		warning("TextCastMember::setEditable: Attempt to set editable of null widget");
 		return false;
 	}
 
 	return (Graphics::MacText *)_widget->_editable;
 }
 
-bool TextCast::setEditable(bool editable) {
+bool TextCastMember::setEditable(bool editable) {
 	if (!_widget) {
-		warning("TextCast::setEditable: Attempt to set editable of null widget");
+		warning("TextCastMember::setEditable: Attempt to set editable of null widget");
 		return false;
 	}
 
@@ -469,7 +469,7 @@ bool TextCast::setEditable(bool editable) {
 	return true;
 }
 
-ShapeCast::ShapeCast(Common::ReadStreamEndian &stream, uint16 version) {
+ShapeCastMember::ShapeCastMember(Common::ReadStreamEndian &stream, uint16 version) {
 	_type = kCastShape;
 
 	byte flags, unk1;
@@ -517,14 +517,14 @@ ShapeCast::ShapeCast(Common::ReadStreamEndian &stream, uint16 version) {
 	}
 	_modified = false;
 
-	debugC(3, kDebugLoading, "ShapeCast: fl: %x unk1: %x type: %d pat: %d fg: %d bg: %d fill: %d thick: %d dir: %d",
+	debugC(3, kDebugLoading, "ShapeCastMember: fl: %x unk1: %x type: %d pat: %d fg: %d bg: %d fill: %d thick: %d dir: %d",
 		flags, unk1, _shapeType, _pattern, _fgCol, _bgCol, _fillType, _lineThickness, _lineDirection);
 
 	if (debugChannelSet(3, kDebugLoading))
-		_initialRect.debugPrint(0, "ShapeCast: rect:");
+		_initialRect.debugPrint(0, "ShapeCastMember: rect:");
 }
 
-ShapeCast::ShapeCast() {
+ShapeCastMember::ShapeCastMember() {
 	_shapeType = kShapeRectangle;
 	_pattern = 0;
 	_fgCol = 0;
@@ -535,7 +535,7 @@ ShapeCast::ShapeCast() {
 	_ink = kInkTypeCopy;
 }
 
-ScriptCast::ScriptCast(Common::ReadStreamEndian &stream, uint16 version) {
+ScriptCastMember::ScriptCastMember(Common::ReadStreamEndian &stream, uint16 version) {
 	_type = kCastLingoScript;
 	_scriptType = kNoneScript;
 
@@ -554,7 +554,7 @@ ScriptCast::ScriptCast(Common::ReadStreamEndian &stream, uint16 version) {
 			_scriptType = kMovieScript;
 			break;
 		default:
-			error("ScriptCast: Unprocessed script type: %d", type);
+			error("ScriptCastMember: Unprocessed script type: %d", type);
 		}
 
 		_initialRect = Score::readRect(stream);
@@ -581,12 +581,12 @@ ScriptCast::ScriptCast(Common::ReadStreamEndian &stream, uint16 version) {
 	}
 }
 
-RTECast::RTECast(Common::ReadStreamEndian &stream, uint16 version) : TextCast(stream, version) {
+RTECastMember::RTECastMember(Common::ReadStreamEndian &stream, uint16 version) : TextCastMember(stream, version) {
 
 	_type = kCastRTE;
 }
 
-void RTECast::loadChunks() {
+void RTECastMember::loadChunks() {
 	//TODO: Actually load RTEs correctly, don't just make fake STXT.
 #if 0
 	Common::SeekableReadStream *rte1 = _movieArchive->getResource(res->children[child].tag, res->children[child].index);
diff --git a/engines/director/cast.h b/engines/director/castmember.h
similarity index 79%
rename from engines/director/cast.h
rename to engines/director/castmember.h
index 061ae35fee..35469183d0 100644
--- a/engines/director/cast.h
+++ b/engines/director/castmember.h
@@ -20,8 +20,8 @@
  *
  */
 
-#ifndef DIRECTOR_CAST_H
-#define DIRECTOR_CAST_H
+#ifndef DIRECTOR_CASTMEMBER_H
+#define DIRECTOR_CASTMEMBER_H
 
 #include "director/archive.h"
 #include "director/types.h"
@@ -50,10 +50,10 @@ namespace Director {
 class Stxt;
 class AudioDecoder;
 
-class Cast {
+class CastMember {
 public:
-	Cast();
-	virtual ~Cast() {};
+	CastMember();
+	virtual ~CastMember() {};
 	virtual bool isEditable() { return false; }
 	virtual bool setEditable(bool editable) { return false; }
 	virtual bool isModified() { return _modified; }
@@ -74,10 +74,10 @@ public:
 	Graphics::MacWidget *_widget;
 };
 
-class BitmapCast : public Cast {
+class BitmapCastMember : public CastMember {
 public:
-	BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16 version);
-	~BitmapCast();
+	BitmapCastMember(Common::ReadStreamEndian &stream, uint32 castTag, uint16 version);
+	~BitmapCastMember();
 	virtual void createWidget() override;
 	// virtual void setColors(int *fgcolor, int *bgcolor) override;
 
@@ -95,9 +95,9 @@ public:
 	uint32 _tag;
 };
 
-class DigitalVideoCast : public Cast {
+class DigitalVideoCastMember : public CastMember {
 public:
-	DigitalVideoCast(Common::ReadStreamEndian &stream, uint16 version);
+	DigitalVideoCastMember(Common::ReadStreamEndian &stream, uint16 version);
 
 	bool _looping;
 	bool _pauseAtStart;
@@ -112,18 +112,18 @@ public:
 	uint16 _frameRate;
 };
 
-class SoundCast : public Cast {
+class SoundCastMember : public CastMember {
 public:
-	SoundCast(Common::ReadStreamEndian &stream, uint16 version);
+	SoundCastMember(Common::ReadStreamEndian &stream, uint16 version);
 
 	bool _looping;
 	AudioDecoder *_audio;
 };
 
-class ShapeCast : public Cast {
+class ShapeCastMember : public CastMember {
 public:
-	ShapeCast(Common::ReadStreamEndian &stream, uint16 version);
-	ShapeCast();
+	ShapeCastMember(Common::ReadStreamEndian &stream, uint16 version);
+	ShapeCastMember();
 
 	ShapeType _shapeType;
 	uint16 _pattern;
@@ -135,9 +135,9 @@ public:
 	InkType _ink;
 };
 
-class TextCast : public Cast {
+class TextCastMember : public CastMember {
 public:
-	TextCast(Common::ReadStreamEndian &stream, uint16 version, bool asButton = false);
+	TextCastMember(Common::ReadStreamEndian &stream, uint16 version, bool asButton = false);
 	virtual void setColors(int *fgcolor, int *bgcolor) override;
 	virtual void getColors(int *fgcolor, int *bgcolor) override;
 
@@ -180,22 +180,22 @@ private:
 	uint _fgcolor;
 };
 
-class ScriptCast : public Cast {
+class ScriptCastMember : public CastMember {
 public:
-	ScriptCast(Common::ReadStreamEndian &stream, uint16 version);
+	ScriptCastMember(Common::ReadStreamEndian &stream, uint16 version);
 
 	uint32 _id;
 	ScriptType _scriptType;
 };
 
-class RTECast : public TextCast {
+class RTECastMember : public TextCastMember {
 public:
-	RTECast(Common::ReadStreamEndian &stream, uint16 version);
+	RTECastMember(Common::ReadStreamEndian &stream, uint16 version);
 
 	void loadChunks();
 };
 
-struct CastInfo {
+struct CastMemberInfo {
 	Common::String script;
 	Common::String name;
 	Common::String directory;
diff --git a/engines/director/director.h b/engines/director/director.h
index e0d41d28d0..dbb8079705 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -59,7 +59,7 @@ class DirectorSound;
 class Lingo;
 class Stage;
 class Score;
-class Cast;
+class CastMember;
 class Stxt;
 
 enum {
@@ -145,7 +145,7 @@ public:
 	uint16 getPaletteColorCount() const { return _currentPaletteLength; }
 	void loadSharedCastsFrom(Common::String filename);
 	void clearSharedCast();
-	Cast *getCastMember(int castId);
+	CastMember *getCastMember(int castId);
 	const Stxt *getStxt(int castId);
 	void loadPatterns();
 	uint32 transformColor(uint32 color);
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 2aa69ffa99..e19058d832 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -28,7 +28,7 @@
 #include "director/frame.h"
 #include "director/score.h"
 #include "director/sprite.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/lingo/lingo.h"
 
 namespace Director {
@@ -130,7 +130,7 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
 				releaseDraggedSprite();
 
 				{
-					Cast *cast = g_director->getCastMember(sc->getSpriteById(spriteId)->_castId);
+					CastMember *cast = g_director->getCastMember(sc->getSpriteById(spriteId)->_castId);
 					if (cast && cast->_type == kCastButton)
 						cast->_hilite = !cast->_hilite;
 				}
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index e33cf98602..1134b77adc 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -26,7 +26,7 @@
 #include "graphics/primitives.h"
 
 #include "director/director.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/frame.h"
 #include "director/score.h"
 #include "director/sprite.h"
diff --git a/engines/director/frame.h b/engines/director/frame.h
index 31e5424456..e4d888e800 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -40,7 +40,7 @@ namespace Director {
 
 class Score;
 class Sprite;
-class TextCast;
+class TextCastMember;
 
 enum {
 	kChannelDataSize = (25 * 50)
@@ -81,7 +81,7 @@ private:
 	void readSprite(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size);
 	void readMainChannels(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size);
 	Image::ImageDecoder *getImageFrom(uint16 spriteId);
-	Common::String readTextStream(Common::SeekableSubReadStreamEndian *textStream, TextCast *textCast);
+	Common::String readTextStream(Common::SeekableSubReadStreamEndian *textStream, TextCastMember *textCast);
 
 
 public:
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index ed9e282bf4..e7737fad38 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -23,7 +23,7 @@
 #include "common/system.h"
 
 #include "director/director.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-builtins.h"
 #include "director/lingo/lingo-code.h"
@@ -2174,7 +2174,7 @@ void LB::b_field(int nargs) {
 void LB::b_script(int nargs) {
 	Datum d = g_lingo->pop();
 	int castId = g_lingo->castIdFetch(d);
-	Cast *cast = g_director->getCastMember(castId);
+	CastMember *cast = g_director->getCastMember(castId);
 
 	if (cast) {
 		ScriptContext *script = nullptr;
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 75ee4584de..ed8918a9d5 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -25,7 +25,7 @@
 #include "common/substream.h"
 
 #include "director/director.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/score.h"
 #include "director/util.h"
 #include "director/lingo/lingo.h"
@@ -882,12 +882,12 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 	// initialise the script
 	ScriptType scriptType = kCastScript;
 	Common::String castName;
-	Cast *member = g_director->getCastMember(castId);
+	CastMember *member = g_director->getCastMember(castId);
 	if (member) {
 		if (member->_type == kCastLingoScript)
-			scriptType = ((ScriptCast *)member)->_scriptType;
+			scriptType = ((ScriptCastMember *)member)->_scriptType;
 
-		CastInfo *info = member->_score->_castsInfo[castId];
+		CastMemberInfo *info = member->_score->_castsInfo[castId];
 		if (info)
 			castName = info->name;
 	}
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index d31751ff9b..5ebc0d7b5a 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -44,7 +44,7 @@
 // THIS SOFTWARE.
 
 #include "director/director.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/score.h"
 #include "director/sprite.h"
 #include "director/util.h"
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index cc938267df..75a60ce685 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -44,7 +44,7 @@
 // THIS SOFTWARE.
 
 #include "director/director.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/score.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-builtins.h"
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 9d4702e48c..14e49f1e2b 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -29,7 +29,7 @@
 
 #include "director/director.h"
 #include "director/lingo/lingo.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/score.h"
 #include "director/sound.h"
 #include "director/util.h"
@@ -334,8 +334,8 @@ void Lingo::func_cursor(int cursorId, int maskId) {
 	}
 
 	if (maskId != -1) {
-		Cast *cursorCast = _vm->getCastMember(cursorId);
-		Cast *maskCast = _vm->getCastMember(maskId);
+		CastMember *cursorCast = _vm->getCastMember(cursorId);
+		CastMember *maskCast = _vm->getCastMember(maskId);
 		if (!cursorCast || !maskCast) {
 			warning("func_cursor(): non-existent cast reference");
 			return;
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index c7418eb4dc..926b17cc56 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -27,7 +27,7 @@
 #include "graphics/macgui/macbutton.h"
 
 #include "director/director.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/frame.h"
 #include "director/sound.h"
 #include "director/sprite.h"
@@ -227,7 +227,7 @@ TheEntityField fields[] = {
 	{ kTheCast,		"palette",		kThePalette,	4 },//				D4 p
 	{ kTheCast,		"picture",		kThePicture,	3 },//		D3 p
 
-	// TextCast fields
+	// TextCastMember fields
 	{ kTheCast,		"hilite",		kTheHilite,		2 },// D2 p
 	{ kTheCast,		"size",			kTheSize,		3 },//		D3.1 p
 	{ kTheCast,		"text",			kTheText,		2 },// D2 p
@@ -841,7 +841,7 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 		break;
 	case kTheConstraint:
 		if (d.type == CASTREF) {
-			// Reference: Cast ID
+			// Reference: CastMember ID
 			// Find the first channel that uses this cast.
 			for (uint i = 0; i < score->_channels.size(); i++)
 				if (score->_channels[i]->_sprite->_castId == d.u.i)
@@ -955,12 +955,12 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 		return d;
 	}
 
-	Cast *member = _vm->getCastMember(id);
+	CastMember *member = _vm->getCastMember(id);
 	if (!member) {
 		if (field == kTheLoaded) {
 			d.u.i = 0;
 		} else {
-			warning("Lingo::getTheCast(): Cast %d not found", id);
+			warning("Lingo::getTheCast(): CastMember %d not found", id);
 		}
 		return d;
 	}
@@ -971,7 +971,7 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 	}
 
 	CastType castType = member->_type;
-	CastInfo *castInfo = nullptr;
+	CastMemberInfo *castInfo = nullptr;
 	if (score->_castsInfo.contains(id)) {
 		castInfo = score->_castsInfo.getVal(id);
 	} else {
@@ -979,7 +979,7 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 		if (shared && shared->_castsInfo.contains(id)) {
 			castInfo = shared->_castsInfo.getVal(id);
 		} else {
-			warning("Lingo::getTheCast(): Cast info for %d not found", id);
+			warning("Lingo::getTheCast(): CastMember info for %d not found", id);
 			return d;
 		}
 	}
@@ -1014,7 +1014,7 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 			Common::String text;
 			if (castType == kCastText) {
 				if (member && member->_type == kCastText) {
-					text = ((TextCast *)member)->getText();
+					text = ((TextCastMember *)member)->getText();
 				} else {
 					warning("Lingo::getTheCast(): Unknown STXT cast id %d", id);
 				}
@@ -1057,13 +1057,13 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
 		return;
 	}
 
-	Cast *member = _vm->getCastMember(id);
+	CastMember *member = _vm->getCastMember(id);
 	if (!member) {
-		warning("Lingo::setTheCast(): Cast id %d doesn't exist", id);
+		warning("Lingo::setTheCast(): CastMember id %d doesn't exist", id);
 		return;
 	}
 	CastType castType = member->_type;
-	CastInfo *castInfo = score->_castsInfo[id];
+	CastMemberInfo *castInfo = score->_castsInfo[id];
 
 	switch (field) {
 	case kTheBackColor: {
@@ -1096,7 +1096,7 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
 	case kTheHilite:
 		// TODO: Understand how texts can be selected programmatically as well.
 		if (member->_type == kCastButton) {
-			TextCast *button = (TextCast *)member;
+			TextCastMember *button = (TextCastMember *)member;
 			if ((bool)d.asInt() !=  member->_hilite) {
 				((Graphics::MacButton *) button->_widget)->invertInner();
 				button->_hilite = !!d.asInt();
@@ -1125,7 +1125,7 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
 	case kTheText:
 		if (castType == kCastText) {
 			if (member->_type == kCastText) {
-				((TextCast *)member)->setText(d.asString().c_str());
+				((TextCastMember *)member)->setText(d.asString().c_str());
 			} else {
 				warning("Lingo::setTheCast(): Unknown STXT cast id %d", id);
 				return;
@@ -1147,12 +1147,12 @@ Datum Lingo::getTheField(Datum &id1, int field) {
 	Datum d;
 	int id = g_lingo->castIdFetch(id1);
 
-	Cast *member = _vm->getCastMember(id);
+	CastMember *member = _vm->getCastMember(id);
 	if (!member) {
-		warning("Lingo::getTheField(): Cast id %d doesn't exist", id);
+		warning("Lingo::getTheField(): CastMember id %d doesn't exist", id);
 		return d;
 	} else if (member->_type != kCastText) {
-		warning("Lingo::getTheField(): Cast id %d is not a field", id);
+		warning("Lingo::getTheField(): CastMember id %d is not a field", id);
 		return d;
 	}
 
@@ -1192,12 +1192,12 @@ void Lingo::setTheField(Datum &id1, int field, Datum &d) {
 		return;
 	}
 
-	Cast *member = _vm->getCastMember(id);
+	CastMember *member = _vm->getCastMember(id);
 	if (!member) {
-		warning("Lingo::setTheField(): Cast id %d doesn't exist", id);
+		warning("Lingo::setTheField(): CastMember id %d doesn't exist", id);
 		return;
 	} else if (member->_type != kCastText) {
-		warning("Lingo::setTheField(): Cast id %d is not a field", id);
+		warning("Lingo::setTheField(): CastMember id %d is not a field", id);
 	}
 
 	switch (field) {
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 7ea9774c63..cd80d7255c 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -28,7 +28,7 @@
 #include "director/director.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-code.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/frame.h"
 #include "director/score.h"
 #include "director/sprite.h"
@@ -860,7 +860,7 @@ Common::String Datum::asString(bool printonly) {
 	case FIELDREF:
 		{
 			int idx = u.i;
-			Cast *member = g_director->getCastMember(idx);
+			CastMember *member = g_director->getCastMember(idx);
 			if (!member) {
 				warning("asString(): Unknown cast id %d", idx);
 				s = "";
@@ -869,9 +869,9 @@ Common::String Datum::asString(bool printonly) {
 
 			if (type == FIELDREF) {
 				if (!printonly) {
-					s = ((TextCast *)member)->getText();
+					s = ((TextCastMember *)member)->getText();
 				} else {
-					s = Common::String::format("reference: \"%s\"", ((TextCast *)member)->getText().c_str());
+					s = Common::String::format("reference: \"%s\"", ((TextCastMember *)member)->getText().c_str());
 				}
 			} else {
 				s = Common::String::format("cast %d", idx);
@@ -1188,14 +1188,14 @@ void Lingo::varAssign(Datum &var, Datum &value, bool global, DatumHash *localvar
 			return;
 		}
 		int referenceId = var.u.i;
-		Cast *member = g_director->getCastMember(referenceId);
+		CastMember *member = g_director->getCastMember(referenceId);
 		if (!member) {
 			warning("varAssign: Unknown cast id %d", referenceId);
 			return;
 		}
 		switch (member->_type) {
 		case kCastText:
-			((TextCast *)member)->setText(value.asString().c_str());
+			((TextCastMember *)member)->setText(value.asString().c_str());
 			break;
 		default:
 			warning("varAssign: Unhandled cast type %s", tag2str(member->_type));
@@ -1247,12 +1247,12 @@ Datum Lingo::varFetch(Datum &var, bool global, DatumHash *localvars) {
 
 		return *d;
 	} else if (var.type == FIELDREF) {
-		Cast *cast = _vm->getCastMember(var.u.i);
+		CastMember *cast = _vm->getCastMember(var.u.i);
 		if (cast) {
 			switch (cast->_type) {
 			case kCastText:
 				result.type = STRING;
-				result.u.s = new Common::String(((TextCast *)cast)->getText());
+				result.u.s = new Common::String(((TextCastMember *)cast)->getText());
 				break;
 			default:
 				warning("varFetch: Unhandled cast type %s", tag2str(cast->_type));
diff --git a/engines/director/module.mk b/engines/director/module.mk
index ba48899fce..0e0b15aaf9 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -2,7 +2,7 @@ MODULE := engines/director
 
 MODULE_OBJS = \
 	archive.o \
-	cast.o \
+	castmember.o \
 	detection.o \
 	director.o \
 	events.o \
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index dbe3cee44d..6d8ab01325 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -30,7 +30,7 @@
 
 #include "director/director.h"
 #include "director/archive.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/score.h"
 #include "director/util.h"
 #include "director/lingo/lingo.h"
@@ -308,8 +308,8 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
 	_sharedScore->loadArchive(true);
 }
 
-Cast *DirectorEngine::getCastMember(int castId) {
-	Cast *result = nullptr;
+CastMember *DirectorEngine::getCastMember(int castId) {
+	CastMember *result = nullptr;
 	if (_currentScore) {
 		result = _currentScore->getCastMember(castId);
 	}
diff --git a/engines/director/score-loading.cpp b/engines/director/score-loading.cpp
index a2fb75083a..e338cbeafb 100644
--- a/engines/director/score-loading.cpp
+++ b/engines/director/score-loading.cpp
@@ -30,7 +30,7 @@
 #include "image/bmp.h"
 
 #include "director/director.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/images.h"
 #include "director/score.h"
 #include "director/frame.h"
@@ -137,7 +137,7 @@ bool Score::loadArchive(bool isSharedCast) {
 		stage->setStageColor(_stageColor);
 	}
 
-	// Cast Information Array
+	// CastMember Information Array
 	if (_movieArchive->hasResource(MKTAG('V', 'W', 'C', 'R'), -1)) {
 		_castIDoffset = _movieArchive->getResourceIDList(MKTAG('V', 'W', 'C', 'R'))[0];
 		loadCastDataVWCR(*(r = _movieArchive->getResource(MKTAG('V', 'W', 'C', 'R'), _castIDoffset)));
@@ -191,7 +191,7 @@ bool Score::loadArchive(bool isSharedCast) {
 
 	Common::Array<uint16> cast = _movieArchive->getResourceIDList(MKTAG('C', 'A', 'S', 't'));
 	if (!_loadedCast)
-		_loadedCast = new Common::HashMap<int, Cast *>();
+		_loadedCast = new Common::HashMap<int, CastMember *>();
 
 	if (cast.size() > 0) {
 		debugC(2, kDebugLoading, "****** Loading %d CASt resources", cast.size());
@@ -274,7 +274,7 @@ bool Score::loadArchive(bool isSharedCast) {
 }
 
 void Score::copyCastStxts() {
-	for (Common::HashMap<int, Cast *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
+	for (Common::HashMap<int, CastMember *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
 		if (c->_value->_type != kCastText && c->_value->_type != kCastButton)
 			continue;
 
@@ -286,7 +286,7 @@ void Score::copyCastStxts() {
 
 		if (_loadedStxts->getVal(stxtid)) {
 			const Stxt *stxt = _loadedStxts->getVal(stxtid);
-			TextCast *tc = (TextCast *)c->_value;
+			TextCastMember *tc = (TextCastMember *)c->_value;
 
 			tc->importStxt(stxt);
 		}
@@ -294,7 +294,7 @@ void Score::copyCastStxts() {
 }
 
 void Score::createCastWidgets() {
-	for (Common::HashMap<int, Cast *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
+	for (Common::HashMap<int, CastMember *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
 		if (!c->_value)
 			continue;
 
@@ -307,14 +307,14 @@ void Score::loadSpriteImages(bool isSharedCast) {
 
 	Score *sharedScore = _vm->getSharedScore();
 
-	for (Common::HashMap<int, Cast *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
+	for (Common::HashMap<int, CastMember *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
 		if (!c->_value)
 			continue;
 
 		if (c->_value->_type != kCastBitmap)
 			continue;
 
-		BitmapCast *bitmapCast = (BitmapCast *)c->_value;
+		BitmapCastMember *bitmapCast = (BitmapCastMember *)c->_value;
 		uint32 tag = bitmapCast->_tag;
 		uint16 imgId = c->_key;
 		uint16 realId = 0;
@@ -332,11 +332,11 @@ void Score::loadSpriteImages(bool isSharedCast) {
 				pic = sharedScore->getArchive()->getResource(tag, imgId);
 		} else {
 			if (_loadedCast->contains(imgId)) {
-				bitmapCast->_tag = tag = ((BitmapCast *)_loadedCast->getVal(imgId))->_tag;
+				bitmapCast->_tag = tag = ((BitmapCastMember *)_loadedCast->getVal(imgId))->_tag;
 				realId = imgId + _castIDoffset;
 				pic = _movieArchive->getResource(tag, realId);
 			} else if (sharedScore && sharedScore->_loadedCast && sharedScore->_loadedCast->contains(imgId)) {
-				bitmapCast->_tag = tag = ((BitmapCast *)sharedScore->_loadedCast->getVal(imgId))->_tag;
+				bitmapCast->_tag = tag = ((BitmapCastMember *)sharedScore->_loadedCast->getVal(imgId))->_tag;
 				realId = imgId + sharedScore->_castIDoffset;
 				pic = sharedScore->getArchive()->getResource(tag, realId);
 			}
@@ -372,7 +372,7 @@ void Score::loadSpriteImages(bool isSharedCast) {
 			break;
 
 		default:
-			warning("Score::loadSpriteImages(): Unknown Bitmap Cast Tag: [%d] %s", tag, tag2str(tag));
+			warning("Score::loadSpriteImages(): Unknown Bitmap CastMember Tag: [%d] %s", tag, tag2str(tag));
 			break;
 		}
 
@@ -393,14 +393,14 @@ void Score::loadSpriteImages(bool isSharedCast) {
 void Score::loadSpriteSounds(bool isSharedCast) {
 	debugC(1, kDebugLoading, "****** Preloading sprite sounds");
 
-	for (Common::HashMap<int, Cast *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
+	for (Common::HashMap<int, CastMember *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
 		if (!c->_value)
 			continue;
 
 		if (c->_value->_type != kCastSound)
 			continue;
 
-		SoundCast *soundCast = (SoundCast *)c->_value;
+		SoundCastMember *soundCast = (SoundCastMember *)c->_value;
 		uint32 tag = MKTAG('S', 'N', 'D', ' ');
 		uint16 sndId = (uint16)(c->_key + _castIDoffset);
 
@@ -652,9 +652,9 @@ void Score::readVersion(uint32 rid) {
 }
 
 void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
-	debugC(1, kDebugLoading, "****** Loading Cast rects VWCR. start: %d, end: %d", _castArrayStart, _castArrayEnd);
+	debugC(1, kDebugLoading, "****** Loading CastMember rects VWCR. start: %d, end: %d", _castArrayStart, _castArrayEnd);
 
-	_loadedCast = new Common::HashMap<int, Cast *>();
+	_loadedCast = new Common::HashMap<int, CastMember *>();
 
 	for (uint16 id = _castArrayStart; id <= _castArrayEnd; id++) {
 		byte size = stream.readByte();
@@ -670,35 +670,35 @@ void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
 		int returnPos = stream.pos() + size - 1;
 		switch (castType) {
 		case kCastBitmap:
-			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) BitmapCast", id, numToCastNum(id));
+			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) BitmapCastMember", id, numToCastNum(id));
 			if (_movieArchive->hasResource(MKTAG('B', 'I', 'T', 'D'), id + _castIDoffset))
 				tag = MKTAG('B', 'I', 'T', 'D');
 			else if (_movieArchive->hasResource(MKTAG('D', 'I', 'B', ' '), id + _castIDoffset))
 				tag = MKTAG('D', 'I', 'B', ' ');
 			else
-				error("Score::loadCastDataVWCR(): non-existent reference to BitmapCast");
+				error("Score::loadCastDataVWCR(): non-existent reference to BitmapCastMember");
 
-			_loadedCast->setVal(id, new BitmapCast(stream, tag, _vm->getVersion()));
+			_loadedCast->setVal(id, new BitmapCastMember(stream, tag, _vm->getVersion()));
 			break;
 		case kCastText:
-			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) TextCast", id, numToCastNum(id));
-			_loadedCast->setVal(id, new TextCast(stream, _vm->getVersion()));
+			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) TextCastMember", id, numToCastNum(id));
+			_loadedCast->setVal(id, new TextCastMember(stream, _vm->getVersion()));
 			break;
 		case kCastShape:
-			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) ShapeCast", id, numToCastNum(id));
-			_loadedCast->setVal(id, new ShapeCast(stream, _vm->getVersion()));
+			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) ShapeCastMember", id, numToCastNum(id));
+			_loadedCast->setVal(id, new ShapeCastMember(stream, _vm->getVersion()));
 			break;
 		case kCastButton:
 			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) ButtonCast", id, numToCastNum(id));
-			_loadedCast->setVal(id, new TextCast(stream, _vm->getVersion(), true));
+			_loadedCast->setVal(id, new TextCastMember(stream, _vm->getVersion(), true));
 			break;
 		case kCastSound:
-			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) SoundCast", id, numToCastNum(id));
-			_loadedCast->setVal(id, new SoundCast(stream, _vm->getVersion()));
+			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) SoundCastMember", id, numToCastNum(id));
+			_loadedCast->setVal(id, new SoundCastMember(stream, _vm->getVersion()));
 			break;
 		case kCastDigitalVideo:
-			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) DigitalVideoCast", id, numToCastNum(id));
-			_loadedCast->setVal(id, new DigitalVideoCast(stream, _vm->getVersion()));
+			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) DigitalVideoCastMember", id, numToCastNum(id));
+			_loadedCast->setVal(id, new DigitalVideoCastMember(stream, _vm->getVersion()));
 			break;
 		default:
 			warning("Score::loadCastDataVWCR(): Unhandled cast id: %d(%s), type: %d, %d bytes", id, numToCastNum(id), castType, size);
@@ -787,35 +787,35 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 	switch (castType) {
 	case kCastBitmap:
 		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastBitmap (%d children)", res->children.size());
-		_loadedCast->setVal(id, new BitmapCast(castStream, res->tag, _vm->getVersion()));
+		_loadedCast->setVal(id, new BitmapCastMember(castStream, res->tag, _vm->getVersion()));
 		break;
 	case kCastSound:
 		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastSound (%d children)", res->children.size());
-		_loadedCast->setVal(id, new SoundCast(castStream, _vm->getVersion()));
+		_loadedCast->setVal(id, new SoundCastMember(castStream, _vm->getVersion()));
 		break;
 	case kCastText:
 		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastText (%d children)", res->children.size());
-		_loadedCast->setVal(id, new TextCast(castStream, _vm->getVersion()));
+		_loadedCast->setVal(id, new TextCastMember(castStream, _vm->getVersion()));
 		break;
 	case kCastShape:
 		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastShape (%d children)", res->children.size());
-		_loadedCast->setVal(id, new ShapeCast(castStream, _vm->getVersion()));
+		_loadedCast->setVal(id, new ShapeCastMember(castStream, _vm->getVersion()));
 		break;
 	case kCastButton:
 		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastButton (%d children)", res->children.size());
-		_loadedCast->setVal(id, new TextCast(castStream, _vm->getVersion(), true));
+		_loadedCast->setVal(id, new TextCastMember(castStream, _vm->getVersion(), true));
 		break;
 	case kCastLingoScript:
 		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastLingoScript");
-		_loadedCast->setVal(id, new ScriptCast(castStream, _vm->getVersion()));
+		_loadedCast->setVal(id, new ScriptCastMember(castStream, _vm->getVersion()));
 		break;
 	case kCastRTE:
 		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastRTE (%d children)", res->children.size());
-		_loadedCast->setVal(id, new RTECast(castStream, _vm->getVersion()));
+		_loadedCast->setVal(id, new RTECastMember(castStream, _vm->getVersion()));
 		break;
 	case kCastDigitalVideo:
 		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastDigitalVideo (%d children)", res->children.size());
-		_loadedCast->setVal(id, new DigitalVideoCast(castStream, _vm->getVersion()));
+		_loadedCast->setVal(id, new DigitalVideoCastMember(castStream, _vm->getVersion()));
 		break;
 	case kCastFilmLoop:
 		warning("STUB: Score::loadCastData(): kCastFilmLoop (%d children)", res->children.size());
@@ -866,7 +866,7 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 		}
 		debugC(4, kDebugLoading, "'");
 
-		CastInfo *ci = new CastInfo();
+		CastMemberInfo *ci = new CastMemberInfo();
 
 		// We have here variable number of strings. Thus, instead of
 		// adding tons of ifs, we use this switch()
@@ -897,14 +897,14 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 			break;
 		}
 
-		Cast *member = _loadedCast->getVal(id);
+		CastMember *member = _loadedCast->getVal(id);
 		// FIXME. Bytecode disabled by default, requires --debugflags=bytecode for now
 		if (_vm->getVersion() < 4 || !debugChannelSet(-1, kDebugBytecode)) {
 			if (!ci->script.empty()) {
 				ScriptType scriptType = kCastScript;
 				// the script type here could be wrong!
 				if (member->_type == kCastLingoScript) {
-					scriptType = ((ScriptCast *)member)->_scriptType;
+					scriptType = ((ScriptCastMember *)member)->_scriptType;
 				}
 
 				if (ConfMan.getBool("dump_scripts"))
@@ -1146,7 +1146,7 @@ void Score::dumpScript(const char *script, ScriptType type, uint16 id) {
 void Score::loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id) {
 	uint32 entryType = 0;
 	Common::Array<Common::String> castStrings = loadStrings(stream, entryType);
-	CastInfo *ci = new CastInfo();
+	CastMemberInfo *ci = new CastMemberInfo();
 
 	ci->script = castStrings[0];
 
@@ -1163,7 +1163,7 @@ void Score::loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id)
 
 	castStrings.clear();
 
-	debugC(5, kDebugLoading, "Score::loadCastInfo(): CastInfo: name: '%s' directory: '%s', fileName: '%s', type: '%s'",
+	debugC(5, kDebugLoading, "Score::loadCastInfo(): CastMemberInfo: name: '%s' directory: '%s', fileName: '%s', type: '%s'",
 				ci->name.c_str(), ci->directory.c_str(), ci->fileName.c_str(), ci->type.c_str());
 
 	if (!ci->name.empty())
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index f5ce27f522..d26d988c11 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -35,7 +35,7 @@
 #endif
 
 #include "director/director.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/score.h"
 #include "director/frame.h"
 #include "director/sound.h"
@@ -143,7 +143,7 @@ Common::Point Channel::getPosition() {
 	Common::Point res = _currentPoint;
 
 	if (_sprite->_castType == kCastBitmap && _sprite->_cast) {
-		BitmapCast *bc = (BitmapCast *)(_sprite->_cast);
+		BitmapCastMember *bc = (BitmapCastMember *)(_sprite->_cast);
 
 		res += Common::Point(bc->_initialRect.left - bc->_regX,
 												 bc->_initialRect.top - bc->_regY);
@@ -172,7 +172,7 @@ MacShape *Channel::getShape() {
 		switch (_sprite->_cast->_type) {
 		case kCastShape:
 			{
-				ShapeCast *sc = (ShapeCast *)_sprite->_cast;
+				ShapeCastMember *sc = (ShapeCastMember *)_sprite->_cast;
 				switch (sc->_shapeType) {
 				case kShapeRectangle:
 					shape->spriteType = sc->_fillType ? kRectangleSprite : kOutlinedRectangleSprite;
@@ -271,7 +271,7 @@ Score::~Score() {
 	}
 
 	if (_loadedCast)
-		for (Common::HashMap<int, Cast *>::iterator it = _loadedCast->begin(); it != _loadedCast->end(); ++it)
+		for (Common::HashMap<int, CastMember *>::iterator it = _loadedCast->begin(); it != _loadedCast->end(); ++it)
 			delete it->_value;
 
 	if (_labels)
@@ -285,7 +285,7 @@ Score::~Score() {
 }
 
 Common::Rect Score::getCastMemberInitialRect(int castId) {
-	Cast *cast = _loadedCast->getVal(castId);
+	CastMember *cast = _loadedCast->getVal(castId);
 
 	if (!cast) {
 		warning("Score::getCastMemberInitialRect(%d): empty cast", castId);
@@ -296,7 +296,7 @@ Common::Rect Score::getCastMemberInitialRect(int castId) {
 }
 
 void Score::setCastMemberModified(int castId) {
-	Cast *cast = _loadedCast->getVal(castId);
+	CastMember *cast = _loadedCast->getVal(castId);
 
 	if (!cast) {
 		warning("Score::setCastMemberModified(%d): empty cast", castId);
@@ -678,8 +678,8 @@ void Score::screenShot() {
 	newSurface->free();
 }
 
-Cast *Score::getCastMember(int castId) {
-	Cast *result = nullptr;
+CastMember *Score::getCastMember(int castId) {
+	CastMember *result = nullptr;
 
 	if (_loadedCast && _loadedCast->contains(castId)) {
 		result = _loadedCast->getVal(castId);
diff --git a/engines/director/score.h b/engines/director/score.h
index 1ce09b715e..70eb0c9ecc 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -43,7 +43,7 @@ namespace Director {
 
 class Stage;
 class Archive;
-struct CastInfo;
+struct CastMemberInfo;
 class DirectorEngine;
 class DirectorSound;
 class Frame;
@@ -53,11 +53,11 @@ struct Resource;
 struct Channel;
 class Sprite;
 class Stxt;
-class Cast;
-class BitmapCast;
-class ScriptCast;
-class ShapeCast;
-class TextCast;
+class CastMember;
+class BitmapCastMember;
+class ScriptCastMember;
+class ShapeCastMember;
+class TextCastMember;
 
 enum RenderMode {
 	kRenderModeNormal,
@@ -137,7 +137,7 @@ public:
 	bool checkSpriteIntersection(uint16 spriteId, Common::Point pos);
 	Common::List<Channel *> getSpriteIntersections(const Common::Rect &r);
 
-	Cast *getCastMember(int castId);
+	CastMember *getCastMember(int castId);
 	const Stxt *getStxt(int castId);
 	void renderFrame(uint16 frameId, RenderMode mode = kRenderModeNormal);
 	void renderSprites(uint16 frameId, RenderMode mode = kRenderModeNormal);
@@ -165,7 +165,7 @@ private:
 public:
 	Common::Array<Channel *> _channels;
 	Common::Array<Frame *> _frames;
-	Common::HashMap<uint16, CastInfo *> _castsInfo;
+	Common::HashMap<uint16, CastMemberInfo *> _castsInfo;
 	Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _castsNames;
 	Common::SortedArray<Label *> *_labels;
 	Common::HashMap<uint16, Common::String> _actions;
@@ -187,7 +187,7 @@ public:
 	bool _stopPlay;
 	uint32 _nextFrameTime;
 
-	Common::HashMap<int, Cast *> *_loadedCast;
+	Common::HashMap<int, CastMember *> *_loadedCast;
 
 	Common::HashMap<int, const Stxt *> *_loadedStxts;
 
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 5e2c6b3e34..a1a6880b64 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -34,7 +34,7 @@
 #include "audio/decoders/aiff.h"
 
 #include "director/director.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/sound.h"
 
 namespace Director {
@@ -102,15 +102,15 @@ void DirectorSound::playCastMember(int castId, uint8 soundChannel, bool allowRep
 	if (castId == 0) {
 		stopSound(soundChannel);
 	} else {
-		Cast *soundCast = _vm->getCastMember(castId);
+		CastMember *soundCast = _vm->getCastMember(castId);
 		if (soundCast) {
 			if (soundCast->_type != kCastSound) {
-				warning("DirectorSound::playCastMember: attempted to play a non-SoundCast cast member %d", castId);
+				warning("DirectorSound::playCastMember: attempted to play a non-SoundCastMember cast member %d", castId);
 			} else {
 				if (!allowRepeat && lastPlayingCast(soundChannel) == castId)
 					return;
-				bool looping = ((SoundCast *)soundCast)->_looping;
-				AudioDecoder *ad = ((SoundCast *)soundCast)->_audio;
+				bool looping = ((SoundCastMember *)soundCast)->_looping;
+				AudioDecoder *ad = ((SoundCastMember *)soundCast)->_audio;
 				if (!ad) {
 					warning("DirectorSound::playCastMember: no audio data attached to cast member %d", castId);
 					return;
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 2e30a38893..5cb5cc0082 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -21,7 +21,7 @@
  */
 
 #include "director/director.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/lingo/lingo.h"
 #include "director/sprite.h"
 
@@ -105,7 +105,7 @@ uint16 Sprite::getPattern() {
 	case kCastMemberSprite:
 		switch (_cast->_type) {
 		case kCastShape:
-			return ((ShapeCast *)_cast)->_pattern;
+			return ((ShapeCastMember *)_cast)->_pattern;
 			break;
 		default:
 			warning("Sprite::getPattern(): Unhandled cast type: %d", _cast->_type);
@@ -141,7 +141,7 @@ void Sprite::setPattern(uint16 pattern) {
 }
 
 void Sprite::setCast(uint16 castId) {
-	Cast *member = g_director->getCastMember(castId);
+	CastMember *member = g_director->getCastMember(castId);
 	_castType = kCastTypeNull;
 	_castId = castId;
 
@@ -159,11 +159,11 @@ void Sprite::setCast(uint16 castId) {
 
 			delete _cast->_widget;
 			_cast->_type = kCastButton;
-			((TextCast *)_cast)->_buttonType = (ButtonType)(_spriteType - 8);
-			((TextCast *)_cast)->createWidget();
+			((TextCastMember *)_cast)->_buttonType = (ButtonType)(_spriteType - 8);
+			((TextCastMember *)_cast)->createWidget();
 		}
 	} else {
-		warning("Sprite::setCast: Cast id %d has null member", castId);
+		warning("Sprite::setCast: CastMember id %d has null member", castId);
 	}
 
 	if (g_director->getVersion() < 4) {
@@ -208,7 +208,7 @@ void Sprite::setCast(uint16 castId) {
 		}
 	} else {
 		if (!member) {
-			debugC(1, kDebugImages, "Sprite::setCast(): Cast id %d not found", _castId);
+			debugC(1, kDebugImages, "Sprite::setCast(): CastMember id %d not found", _castId);
 		} else {
 			_castType = member->_type;
 		}
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index c36df70689..e63c6cb960 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -25,9 +25,9 @@
 
 namespace Director {
 
-class BitmapCast;
-class ShapeCast;
-class TextCast;
+class BitmapCastMember;
+class ShapeCastMember;
+class TextCastMember;
 
 enum SpritePosition {
 	kSpritePositionUnk1 = 0,
@@ -85,7 +85,7 @@ public:
 	InkType _ink;
 	uint16 _trails;
 
-	Cast *_cast;
+	CastMember *_cast;
 
 	byte _thickness;
 	Common::Point _startPoint;
diff --git a/engines/director/stage.cpp b/engines/director/stage.cpp
index 30f442caff..ad20f6499a 100644
--- a/engines/director/stage.cpp
+++ b/engines/director/stage.cpp
@@ -25,7 +25,7 @@
 #include "director/director.h"
 #include "director/stage.h"
 #include "director/score.h"
-#include "director/cast.h"
+#include "director/castmember.h"
 #include "director/sprite.h"
 
 #include "common/file.h"
@@ -292,7 +292,7 @@ void Stage::drawReverseSprite(Channel *channel, Common::Rect &srcRect, Common::R
 					} else {
 						if (*dst == 0 && g_director->getVersion() == 3 &&
 								g_director->getCurrentScore()->_channels[targetSprite]->_sprite->_cast->_type == kCastBitmap &&
-								((BitmapCast*)g_director->getCurrentScore()->_channels[targetSprite]->_sprite->_cast)->_bitsPerPixel > 1) {
+								((BitmapCastMember*)g_director->getCurrentScore()->_channels[targetSprite]->_sprite->_cast)->_bitsPerPixel > 1) {
 							*dst = g_director->transformColor(*src - 40);
 						} else {
 							*dst ^= g_director->transformColor(srcColor);


Commit: 5ae6c3407419458420ee9c5f0c7eafa7d6403b40
    https://github.com/scummvm/scummvm/commit/5ae6c3407419458420ee9c5f0c7eafa7d6403b40
Author: djsrv (dservilla at gmail.com)
Date: 2020-07-01T10:50:31-04:00

Commit Message:
DIRECTOR: Separate Movie and Cast from Score

Changed paths:
  A engines/director/cast.cpp
  A engines/director/cast.h
  A engines/director/movie.cpp
  A engines/director/movie.h
  R engines/director/score-loading.cpp
    engines/director/castmember.cpp
    engines/director/castmember.h
    engines/director/director.cpp
    engines/director/director.h
    engines/director/events.cpp
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo-events.cpp
    engines/director/lingo/lingo-funcs.cpp
    engines/director/lingo/lingo-patcher.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo.cpp
    engines/director/module.mk
    engines/director/resource.cpp
    engines/director/score.cpp
    engines/director/score.h
    engines/director/stage.cpp
    engines/director/tests.cpp
    engines/director/transitions.cpp


diff --git a/engines/director/score-loading.cpp b/engines/director/cast.cpp
similarity index 58%
rename from engines/director/score-loading.cpp
rename to engines/director/cast.cpp
index e338cbeafb..5d517a179c 100644
--- a/engines/director/score-loading.cpp
+++ b/engines/director/cast.cpp
@@ -24,21 +24,23 @@
 #include "common/file.h"
 #include "common/memstream.h"
 #include "common/substream.h"
+#include "common/system.h"
 
 #include "graphics/macgui/macfontmanager.h"
 #include "graphics/macgui/macwindowmanager.h"
 #include "image/bmp.h"
 
 #include "director/director.h"
+#include "director/archive.h"
+#include "director/cast.h"
 #include "director/castmember.h"
 #include "director/images.h"
+#include "director/lingo/lingo.h"
+#include "director/movie.h"
 #include "director/score.h"
-#include "director/frame.h"
 #include "director/sound.h"
-#include "director/sprite.h"
 #include "director/stxt.h"
 #include "director/util.h"
-#include "director/lingo/lingo.h"
 
 namespace Director {
 
@@ -59,29 +61,132 @@ const char *scriptType2str(ScriptType scr) {
 	return scriptTypes[scr];
 }
 
-void Score::setArchive(Archive *archive) {
-	_movieArchive = archive;
+Cast::Cast(DirectorEngine *vm, Movie *movie) {
+	_vm = vm;
+	_lingo = _vm->getLingo();
+	_movie = movie;
+
+	_lingoArchive = _movie ? kArchMain : kArchShared;
+
+	_movieScriptCount = 0;
+	_castArrayStart = _castArrayEnd = 0;
+
+	_castIDoffset = 0;
+
+	_castArchive = nullptr;
+
+	_loadedStxts = nullptr;
+	_loadedCast = nullptr;
+}
+
+Cast::~Cast() {
+	if (_loadedStxts)
+		for (Common::HashMap<int, const Stxt *>::iterator it = _loadedStxts->begin(); it != _loadedStxts->end(); ++it)
+			delete it->_value;
+
+	if (_castArchive) {
+		_castArchive->close();
+		delete _castArchive;
+		_castArchive = nullptr;
+	}
+
+	if (_loadedCast)
+		for (Common::HashMap<int, CastMember *>::iterator it = _loadedCast->begin(); it != _loadedCast->end(); ++it)
+			delete it->_value;
+	
+	delete _loadedStxts;
+	delete _loadedCast;
+}
+
+CastMember *Cast::getCastMember(int castId) {
+	CastMember *result = nullptr;
+
+	if (_loadedCast && _loadedCast->contains(castId)) {
+		result = _loadedCast->getVal(castId);
+	}
+	return result;
+}
+
+const Stxt *Cast::getStxt(int castId) {
+	const Stxt *result = nullptr;
+
+	if (_loadedStxts->contains(castId)) {
+		result = _loadedStxts->getVal(castId);
+	}
+	return result;
+}
+
+Common::Rect Cast::getCastMemberInitialRect(int castId) {
+	CastMember *cast = _loadedCast->getVal(castId);
+
+	if (!cast) {
+		warning("Cast::getCastMemberInitialRect(%d): empty cast", castId);
+		return Common::Rect(0, 0);
+	}
+
+	return cast->_initialRect;
+}
+
+void Cast::setCastMemberModified(int castId) {
+	CastMember *cast = _loadedCast->getVal(castId);
+
+	if (!cast) {
+		warning("Cast::setCastMemberModified(%d): empty cast", castId);
+		return;
+	}
+
+	cast->_modified = 1;
+}
+
+Common::String Cast::getString(Common::String str) {
+	if (str.size() == 0) {
+		return str;
+	}
+
+	uint8 f = static_cast<uint8>(str.firstChar());
+
+	if (f == 0) {
+		return "";
+	}
+
+	//TODO: check if all versions need to cut off the first character.
+	if (_vm->getVersion() > 3) {
+		str.deleteChar(0);
+	}
+
+	if (str.lastChar() == '\x00') {
+		str.deleteLastChar();
+	}
+
+	return str;
+}
+
+void Cast::setArchive(Archive *archive) {
+	_castArchive = archive;
+
 	if (archive->hasResource(MKTAG('M', 'C', 'N', 'M'), 0)) {
 		_macName = archive->getName(MKTAG('M', 'C', 'N', 'M'), 0).c_str();
 	} else {
 		_macName = archive->getFileName();
 	}
-
-	// Frame Labels
-	if (archive->hasResource(MKTAG('V', 'W', 'L', 'B'), -1)) {
-		Common::SeekableSubReadStreamEndian *r;
-		loadLabels(*(r = archive->getFirstResource(MKTAG('V', 'W', 'L', 'B'))));
-		delete r;
-	}
 }
 
-bool Score::loadArchive(bool isSharedCast) {
-	_lingoArchive = isSharedCast ? kArchShared : kArchMain;
-
-	Common::Array<uint16> clutList = _movieArchive->getResourceIDList(MKTAG('C', 'L', 'U', 'T'));
+bool Cast::loadArchive() {
+	Common::Array<uint16> clutList = _castArchive->getResourceIDList(MKTAG('C', 'L', 'U', 'T'));
 	Common::SeekableSubReadStreamEndian *r = nullptr;
 
-	if (!isSharedCast) {
+	// Configuration Information
+	if (_castArchive->hasResource(MKTAG('V', 'W', 'C', 'F'), -1)) {
+		loadConfig(*(r = _castArchive->getFirstResource(MKTAG('V', 'W', 'C', 'F'))));
+		delete r;
+	} else if (_movie) {
+		// TODO: Source this from somewhere!
+		_movie->_movieRect = Common::Rect(0, 0, 640, 480);
+		_movie->_stageColor = 1;
+	}
+
+	if (_movie) {
+		// TODO: Can shared casts have palettes?
 		if (clutList.size() > 1)
 			warning("More than one palette was found (%d)", clutList.size());
 
@@ -89,7 +194,7 @@ bool Score::loadArchive(bool isSharedCast) {
 			warning("CLUT resource not found, using default Mac palette");
 			_vm->setPalette(-1);
 		} else {
-			Common::SeekableSubReadStreamEndian *pal = _movieArchive->getResource(MKTAG('C', 'L', 'U', 'T'), clutList[0]);
+			Common::SeekableSubReadStreamEndian *pal = _castArchive->getResource(MKTAG('C', 'L', 'U', 'T'), clutList[0]);
 
 			debugC(2, kDebugLoading, "****** Loading Palette CLUT, #%d", clutList[0]);
 			loadPalette(*pal);
@@ -99,97 +204,54 @@ bool Score::loadArchive(bool isSharedCast) {
 	}
 
 	// Font Directory
-	if (_movieArchive->hasResource(MKTAG('F', 'O', 'N', 'D'), -1)) {
+	if (_castArchive->hasResource(MKTAG('F', 'O', 'N', 'D'), -1)) {
 		debug("Score::loadArchive(): Movie has fonts. Loading....");
 
-		g_director->_wm->_fontMan->loadFonts(_movieArchive->getFileName());
-	}
-
-	// Score
-	if (!isSharedCast) {
-		if (!_movieArchive->hasResource(MKTAG('V', 'W', 'S', 'C'), -1)) {
-			warning("Score::loadArchive(): Wrong movie format. VWSC resource missing");
-			return false;
-		}
-		loadFrames(*(r = _movieArchive->getFirstResource(MKTAG('V', 'W', 'S', 'C'))));
-		delete r;
-	}
-
-	// Configuration Information
-	if (_movieArchive->hasResource(MKTAG('V', 'W', 'C', 'F'), -1)) {
-		loadConfig(*(r = _movieArchive->getFirstResource(MKTAG('V', 'W', 'C', 'F'))));
-		delete r;
-	} else {
-		// TODO: Source this from somewhere!
-		_movieRect = Common::Rect(0, 0, 640, 480);
-		_stageColor = 1;
-	}
-
-	if (!isSharedCast) {
-		Stage *stage = g_director->getStage();
-
-		// If the stage dimensions are different, delete it and start again.
-		// Otherwise, do not clear it so there can be a nice transition.
-		if (stage->getSurface()->w != _movieRect.width() || stage->getSurface()->h != _movieRect.height()) {
-			stage->resize(_movieRect.width(), _movieRect.height());
-		}
-
-		stage->setStageColor(_stageColor);
+		_vm->_wm->_fontMan->loadFonts(_castArchive->getFileName());
 	}
 
 	// CastMember Information Array
-	if (_movieArchive->hasResource(MKTAG('V', 'W', 'C', 'R'), -1)) {
-		_castIDoffset = _movieArchive->getResourceIDList(MKTAG('V', 'W', 'C', 'R'))[0];
-		loadCastDataVWCR(*(r = _movieArchive->getResource(MKTAG('V', 'W', 'C', 'R'), _castIDoffset)));
-		delete r;
-	}
-
-	// Action list
-	if (_movieArchive->hasResource(MKTAG('V', 'W', 'A', 'C'), -1)) {
-		loadActions(*(r = _movieArchive->getFirstResource(MKTAG('V', 'W', 'A', 'C'))));
-		delete r;
-	}
-
-	// File Info
-	if (_movieArchive->hasResource(MKTAG('V', 'W', 'F', 'I'), -1)) {
-		loadFileInfo(*(r = _movieArchive->getFirstResource(MKTAG('V', 'W', 'F', 'I'))));
+	if (_castArchive->hasResource(MKTAG('V', 'W', 'C', 'R'), -1)) {
+		_castIDoffset = _castArchive->getResourceIDList(MKTAG('V', 'W', 'C', 'R'))[0];
+		loadCastDataVWCR(*(r = _castArchive->getResource(MKTAG('V', 'W', 'C', 'R'), _castIDoffset)));
 		delete r;
 	}
 
 	// Font Mapping
-	if (_movieArchive->hasResource(MKTAG('V', 'W', 'F', 'M'), -1)) {
+	if (_castArchive->hasResource(MKTAG('V', 'W', 'F', 'M'), -1)) {
 		_vm->_wm->_fontMan->clearFontMapping();
 
-		loadFontMap(*(r = _movieArchive->getFirstResource(MKTAG('V', 'W', 'F', 'M'))));
+		loadFontMap(*(r = _castArchive->getFirstResource(MKTAG('V', 'W', 'F', 'M'))));
 		delete r;
 	}
 
 	// Pattern Tiles
-	if (_movieArchive->hasResource(MKTAG('V', 'W', 'T', 'L'), -1)) {
+	if (_castArchive->hasResource(MKTAG('V', 'W', 'T', 'L'), -1)) {
 		debug("STUB: Unhandled VWTL resource.");
 	}
 
 	// Time code
-	if (_movieArchive->hasResource(MKTAG('V', 'W', 't', 'c'), -1)) {
+	// TODO: Is this a score resource?
+	if (_castArchive->hasResource(MKTAG('V', 'W', 't', 'c'), -1)) {
 		debug("STUB: Unhandled VWtc resource");
 	}
 
 	// External sound files
-	if (_movieArchive->hasResource(MKTAG('S', 'T', 'R', ' '), -1)) {
+	if (_castArchive->hasResource(MKTAG('S', 'T', 'R', ' '), -1)) {
 		debug("STUB: Unhandled 'STR ' resource");
 	}
 
-	Common::Array<uint16> vwci = _movieArchive->getResourceIDList(MKTAG('V', 'W', 'C', 'I'));
+	Common::Array<uint16> vwci = _castArchive->getResourceIDList(MKTAG('V', 'W', 'C', 'I'));
 	if (vwci.size() > 0) {
 		debugC(2, kDebugLoading, "****** Loading %d CastInfos VWCI", vwci.size());
 
 		for (Common::Array<uint16>::iterator iterator = vwci.begin(); iterator != vwci.end(); ++iterator) {
-			loadCastInfo(*(r = _movieArchive->getResource(MKTAG('V', 'W', 'C', 'I'), *iterator)), *iterator - _castIDoffset);
+			loadCastInfo(*(r = _castArchive->getResource(MKTAG('V', 'W', 'C', 'I'), *iterator)), *iterator - _castIDoffset);
 			delete r;
 		}
 	}
 
-	Common::Array<uint16> cast = _movieArchive->getResourceIDList(MKTAG('C', 'A', 'S', 't'));
+	Common::Array<uint16> cast = _castArchive->getResourceIDList(MKTAG('C', 'A', 'S', 't'));
 	if (!_loadedCast)
 		_loadedCast = new Common::HashMap<int, CastMember *>();
 
@@ -197,8 +259,8 @@ bool Score::loadArchive(bool isSharedCast) {
 		debugC(2, kDebugLoading, "****** Loading %d CASt resources", cast.size());
 
 		for (Common::Array<uint16>::iterator iterator = cast.begin(); iterator != cast.end(); ++iterator) {
-			Common::SeekableSubReadStreamEndian *stream = _movieArchive->getResource(MKTAG('C', 'A', 'S', 't'), *iterator);
-			Resource res = _movieArchive->getResourceDetail(MKTAG('C', 'A', 'S', 't'), *iterator);
+			Common::SeekableSubReadStreamEndian *stream = _castArchive->getResource(MKTAG('C', 'A', 'S', 't'), *iterator);
+			Resource res = _castArchive->getResourceDetail(MKTAG('C', 'A', 'S', 't'), *iterator);
 			loadCastData(*stream, res.castId, &res);
 			delete stream;
 		}
@@ -207,7 +269,7 @@ bool Score::loadArchive(bool isSharedCast) {
 	// FIXME. Bytecode disabled by default, requires --debugflags=bytecode for now
 	if (_vm->getVersion() >= 4 && debugChannelSet(-1, kDebugBytecode)) {
 		// Try to load script name lists
-		Common::Array<uint16> lnam =  _movieArchive->getResourceIDList(MKTAG('L','n','a','m'));
+		Common::Array<uint16> lnam =  _castArchive->getResourceIDList(MKTAG('L','n','a','m'));
 		if (lnam.size() > 0) {
 
 			int maxLnam = -1;
@@ -215,41 +277,41 @@ bool Score::loadArchive(bool isSharedCast) {
 				maxLnam = MAX(maxLnam, (int)*iterator);
 			}
 			debugC(2, kDebugLoading, "****** Loading Lnam resource with highest ID (%d)", maxLnam);
-			loadLingoNames(*(r = _movieArchive->getResource(MKTAG('L','n','a','m'), maxLnam)));
+			loadLingoNames(*(r = _castArchive->getResource(MKTAG('L','n','a','m'), maxLnam)));
 			delete r;
 		}
 
 		// Try to load script context
-		Common::Array<uint16> lctx =  _movieArchive->getResourceIDList(MKTAG('L','c','t','x'));
+		Common::Array<uint16> lctx =  _castArchive->getResourceIDList(MKTAG('L','c','t','x'));
 		if (lctx.size() > 0) {
 			debugC(2, kDebugLoading, "****** Loading %d Lctx resources", lctx.size());
 
 			for (Common::Array<uint16>::iterator iterator = lctx.begin(); iterator != lctx.end(); ++iterator) {
-				loadLingoContext(*(r = _movieArchive->getResource(MKTAG('L','c','t','x'), *iterator)));
+				loadLingoContext(*(r = _castArchive->getResource(MKTAG('L','c','t','x'), *iterator)));
 				delete r;
 			}
 		}
 	}
 
 	// PICT resources
-	if (_movieArchive->hasResource(MKTAG('P', 'I', 'C', 'T'), -1)) {
+	if (_castArchive->hasResource(MKTAG('P', 'I', 'C', 'T'), -1)) {
 		debug("STUB: Unhandled 'PICT' resource");
 	}
 
 	// Film Loop resources
-	if (_movieArchive->hasResource(MKTAG('S', 'C', 'V', 'W'), -1)) {
+	if (_castArchive->hasResource(MKTAG('S', 'C', 'V', 'W'), -1)) {
 		debug("STUB: Unhandled 'SCVW' resource");
 	}
 
 	// Now process STXTs
-	Common::Array<uint16> stxt = _movieArchive->getResourceIDList(MKTAG('S','T','X','T'));
+	Common::Array<uint16> stxt = _castArchive->getResourceIDList(MKTAG('S','T','X','T'));
 	debugC(2, kDebugLoading, "****** Loading %d STXT resources", stxt.size());
 
 	_loadedStxts = new Common::HashMap<int, const Stxt *>();
 
 	for (Common::Array<uint16>::iterator iterator = stxt.begin(); iterator != stxt.end(); ++iterator) {
 		_loadedStxts->setVal(*iterator - _castIDoffset,
-				 new Stxt(*(r = _movieArchive->getResource(MKTAG('S','T','X','T'), *iterator))));
+				 new Stxt(*(r = _castArchive->getResource(MKTAG('S','T','X','T'), *iterator))));
 
 		delete r;
 
@@ -258,22 +320,83 @@ bool Score::loadArchive(bool isSharedCast) {
 			if (debugChannelSet(-1, kDebugFewFramesOnly))
 				warning("Compiling STXT %d", *iterator);
 
-			loadScriptText(*(r = _movieArchive->getResource(MKTAG('S','T','X','T'), *iterator)));
+			loadScriptText(*(r = _castArchive->getResource(MKTAG('S','T','X','T'), *iterator)));
 			delete r;
 		}
 
 	}
 	copyCastStxts();
 
-	loadSpriteImages(isSharedCast);
-	loadSpriteSounds(isSharedCast);
+	loadSpriteImages();
+	loadSpriteSounds();
 	createCastWidgets();
-	setSpriteCasts();
 
 	return true;
 }
 
-void Score::copyCastStxts() {
+void Cast::loadConfig(Common::SeekableSubReadStreamEndian &stream) {
+	debugC(1, kDebugLoading, "****** Loading Config VWCF");
+
+	if (debugChannelSet(5, kDebugLoading))
+		stream.hexdump(stream.size());
+
+	uint16 len = stream.readUint16();
+	uint16 ver1 = stream.readUint16();
+	Common::Rect movieRect = Movie::readRect(stream);
+	if (_movie)
+		_movie->_movieRect = movieRect;
+
+	_castArrayStart = stream.readUint16();
+	_castArrayEnd = stream.readUint16();
+	byte currentFrameRate = stream.readByte();
+	if (_movie) {
+		_movie->getScore()->_currentFrameRate = currentFrameRate;
+		if (_movie->getScore()->_currentFrameRate == 0)
+			_movie->getScore()->_currentFrameRate = 20;
+	}
+
+	byte lightswitch = stream.readByte();
+	uint16 unk1 = stream.readUint16();
+	uint16 commentFont = stream.readUint16();
+	uint16 commentSize = stream.readUint16();
+	uint16 commentStyle = stream.readUint16();
+	uint32 stageColor = _vm->transformColor(stream.readUint16());
+
+	if (_movie)
+		_movie->_stageColor = stageColor;
+
+	uint16 bitdepth = stream.readUint16();
+	byte color = stream.readByte();	// boolean, color = 1, B/W = 0
+	uint16 stageColorR = stream.readUint16();
+	uint16 stageColorG = stream.readUint16();
+	uint16 stageColorB = stream.readUint16();
+
+	for (int i = 0; i < 0x0b; i++) {
+		stream.readByte();
+	}
+
+	if (_vm->getVersion() >= 4) {
+		for (int i = 0; i < 0x16; i++) {
+			stream.readByte();
+		}
+
+		int palette = (int16)stream.readUint16();
+		_vm->setPalette(palette - 1);
+
+		for (int i = 0; i < 0x08; i++) {
+			stream.readByte();
+		}
+	}
+
+	debugC(1, kDebugLoading, "Cast::loadConfig(): len: %d, ver: %d, framerate: %d, light: %d, unk: %d, font: %d, size: %d"
+			", style: %d", len, ver1, currentFrameRate, lightswitch, unk1, commentFont, commentSize, commentStyle);
+	debugC(1, kDebugLoading, "Cast::loadConfig(): stagecolor: %d, depth: %d, color: %d, rgb: 0x%04x 0x%04x 0x%04x",
+			stageColor, bitdepth, color, stageColorR, stageColorG, stageColorB);
+	if (debugChannelSet(1, kDebugLoading))
+		movieRect.debugPrint(1, "Cast::loadConfig(): Movie rect: ");
+}
+
+void Cast::copyCastStxts() {
 	for (Common::HashMap<int, CastMember *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
 		if (c->_value->_type != kCastText && c->_value->_type != kCastButton)
 			continue;
@@ -293,7 +416,7 @@ void Score::copyCastStxts() {
 	}
 }
 
-void Score::createCastWidgets() {
+void Cast::createCastWidgets() {
 	for (Common::HashMap<int, CastMember *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
 		if (!c->_value)
 			continue;
@@ -302,10 +425,10 @@ void Score::createCastWidgets() {
 	}
 }
 
-void Score::loadSpriteImages(bool isSharedCast) {
+void Cast::loadSpriteImages() {
 	debugC(1, kDebugLoading, "****** Preloading sprite images");
 
-	Score *sharedScore = _vm->getSharedScore();
+	Cast *sharedCast = _vm->getSharedCast();
 
 	for (Common::HashMap<int, CastMember *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
 		if (!c->_value)
@@ -326,19 +449,19 @@ void Score::loadSpriteImages(bool isSharedCast) {
 			imgId = bitmapCast->_children[0].index;
 			tag = bitmapCast->_children[0].tag;
 
-			if (_movieArchive->hasResource(tag, imgId))
-				pic = _movieArchive->getResource(tag, imgId);
-			else if (sharedScore && sharedScore->getArchive()->hasResource(tag, imgId))
-				pic = sharedScore->getArchive()->getResource(tag, imgId);
+			if (_castArchive->hasResource(tag, imgId))
+				pic = _castArchive->getResource(tag, imgId);
+			else if (sharedCast && sharedCast->getArchive()->hasResource(tag, imgId))
+				pic = sharedCast->getArchive()->getResource(tag, imgId);
 		} else {
 			if (_loadedCast->contains(imgId)) {
 				bitmapCast->_tag = tag = ((BitmapCastMember *)_loadedCast->getVal(imgId))->_tag;
 				realId = imgId + _castIDoffset;
-				pic = _movieArchive->getResource(tag, realId);
-			} else if (sharedScore && sharedScore->_loadedCast && sharedScore->_loadedCast->contains(imgId)) {
-				bitmapCast->_tag = tag = ((BitmapCastMember *)sharedScore->_loadedCast->getVal(imgId))->_tag;
-				realId = imgId + sharedScore->_castIDoffset;
-				pic = sharedScore->getArchive()->getResource(tag, realId);
+				pic = _castArchive->getResource(tag, realId);
+			} else if (sharedCast && sharedCast->_loadedCast && sharedCast->_loadedCast->contains(imgId)) {
+				bitmapCast->_tag = tag = ((BitmapCastMember *)sharedCast->_loadedCast->getVal(imgId))->_tag;
+				realId = imgId + sharedCast->_castIDoffset;
+				pic = sharedCast->getArchive()->getResource(tag, realId);
 			}
 		}
 
@@ -390,7 +513,7 @@ void Score::loadSpriteImages(bool isSharedCast) {
 	}
 }
 
-void Score::loadSpriteSounds(bool isSharedCast) {
+void Cast::loadSpriteSounds() {
 	debugC(1, kDebugLoading, "****** Preloading sprite sounds");
 
 	for (Common::HashMap<int, CastMember *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
@@ -413,15 +536,15 @@ void Score::loadSpriteSounds(bool isSharedCast) {
 
 		switch (tag) {
 		case MKTAG('S', 'N', 'D', ' '):
-			if (_movieArchive->hasResource(MKTAG('S', 'N', 'D', ' '), sndId)) {
+			if (_castArchive->hasResource(MKTAG('S', 'N', 'D', ' '), sndId)) {
 				debugC(2, kDebugLoading, "****** Loading 'SND ' id: %d", sndId);
-				sndData = _movieArchive->getResource(MKTAG('S', 'N', 'D', ' '), sndId);
+				sndData = _castArchive->getResource(MKTAG('S', 'N', 'D', ' '), sndId);
 			}
 			break;
 		case MKTAG('s', 'n', 'd', ' '):
-			if (_movieArchive->hasResource(MKTAG('s', 'n', 'd', ' '), sndId)) {
+			if (_castArchive->hasResource(MKTAG('s', 'n', 'd', ' '), sndId)) {
 				debugC(2, kDebugLoading, "****** Loading 'snd ' id: %d", sndId);
-				sndData = _movieArchive->getResource(MKTAG('s', 'n', 'd', ' '), sndId);
+				sndData = _castArchive->getResource(MKTAG('s', 'n', 'd', ' '), sndId);
 			}
 			break;
 		}
@@ -441,7 +564,7 @@ void Score::loadSpriteSounds(bool isSharedCast) {
 	}
 }
 
-void Score::loadPalette(Common::SeekableSubReadStreamEndian &stream) {
+void Cast::loadPalette(Common::SeekableSubReadStreamEndian &stream) {
 	uint16 steps = stream.size() / 6;
 	uint16 index = (steps * 3) - 1;
 	byte *_palette = new byte[index + 1];
@@ -467,191 +590,7 @@ void Score::loadPalette(Common::SeekableSubReadStreamEndian &stream) {
 	_vm->setPalette(_palette, steps);
 }
 
-void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) {
-	debugC(1, kDebugLoading, "****** Loading frames VWSC");
-
-	//stream.hexdump(stream.size());
-
-	uint32 size = stream.readUint32();
-	size -= 4;
-
-	if (_vm->getVersion() < 4) {
-		_numChannelsDisplayed = 30;
-	} else if (_vm->getVersion() == 4) {
-		uint32 frame1Offset = stream.readUint32();
-		uint32 numFrames = stream.readUint32();
-		uint16 version = stream.readUint16();
-		uint16 spriteRecordSize = stream.readUint16();
-		uint16 numChannels = stream.readUint16();
-		size -= 14;
-
-		if (version > 13) {
-			_numChannelsDisplayed = stream.readUint16();
-		} else {
-			if (version <= 7)	// Director5
-				_numChannelsDisplayed = 48;
-			else
-				_numChannelsDisplayed = 120;	// D6
-
-			stream.readUint16(); // Skip
-		}
-
-		size -= 2;
-
-		warning("STUB: Score::loadFrames. frame1Offset: %x numFrames: %x version: %x spriteRecordSize: %x numChannels: %x numChannelsDisplayed: %x",
-			frame1Offset, numFrames, version, spriteRecordSize, numChannels, _numChannelsDisplayed);
-		// Unknown, some bytes - constant (refer to contuinity).
-	} else if (_vm->getVersion() > 4) {
-		//what data is up the top of D5 VWSC?
-		uint32 unk1 = stream.readUint32();
-		uint32 unk2 = stream.readUint32();
-
-		uint16 unk3, unk4, unk5, unk6;
-
-		if (unk2 > 0) {
-			uint32 blockSize = stream.readUint32() - 1;
-			stream.readUint32();
-			stream.readUint32();
-			stream.readUint32();
-			stream.readUint32();
-			for (uint32 skip = 0; skip < blockSize * 4; skip++)
-				stream.readByte();
-
-			//header number two... this is our actual score entry point.
-			unk1 = stream.readUint32();
-			unk2 = stream.readUint32();
-			stream.readUint32();
-			unk3 = stream.readUint16();
-			unk4 = stream.readUint16();
-			unk5 = stream.readUint16();
-			unk6 = stream.readUint16();
-		} else {
-			unk3 = stream.readUint16();
-			unk4 = stream.readUint16();
-			unk5 = stream.readUint16();
-			unk6 = stream.readUint16();
-			size -= 16;
-		}
-		warning("STUB: Score::loadFrames. unk1: %x unk2: %x unk3: %x unk4: %x unk5: %x unk6: %x", unk1, unk2, unk3, unk4, unk5, unk6);
-	}
-
-	uint16 channelSize;
-	uint16 channelOffset;
-
-	Frame *initial = new Frame(_vm, _numChannelsDisplayed);
-	// Push a frame at frame#0 position.
-	// This makes all indexing simpler
-	_frames.push_back(initial);
-
-	// This is a representation of the channelData. It gets overridden
-	// partically by channels, hence we keep it and read the score from left to right
-	//
-	// TODO Merge it with shared cast
-	byte channelData[kChannelDataSize];
-	memset(channelData, 0, kChannelDataSize);
-
-	while (size != 0 && !stream.eos()) {
-		uint16 frameSize = stream.readUint16();
-		debugC(8, kDebugLoading, "++++++++++ score frame %d (frameSize %d) size %d", _frames.size(), frameSize, size);
-
-		if (frameSize > 0) {
-			Frame *frame = new Frame(_vm, _numChannelsDisplayed);
-			size -= frameSize;
-			frameSize -= 2;
-
-			while (frameSize != 0) {
-
-				if (_vm->getVersion() < 4) {
-					channelSize = stream.readByte() * 2;
-					channelOffset = stream.readByte() * 2;
-					frameSize -= channelSize + 2;
-				} else {
-					channelSize = stream.readUint16();
-					channelOffset = stream.readUint16();
-					frameSize -= channelSize + 4;
-				}
-
-				assert(channelOffset + channelSize < kChannelDataSize);
-				stream.read(&channelData[channelOffset], channelSize);
-			}
-
-			Common::MemoryReadStreamEndian *str = new Common::MemoryReadStreamEndian(channelData, ARRAYSIZE(channelData), stream.isBE());
-			// str->hexdump(str->size(), 32);
-			frame->readChannels(str);
-			delete str;
-
-			debugC(8, kDebugLoading, "Score::loadFrames(): Frame %d actionId: %d", _frames.size(), frame->_actionId);
-
-			_frames.push_back(frame);
-		} else {
-			warning("zero sized frame!? exiting loop until we know what to do with the tags that follow.");
-			size = 0;
-		}
-	}
-}
-
-void Score::loadConfig(Common::SeekableSubReadStreamEndian &stream) {
-	debugC(1, kDebugLoading, "****** Loading Config VWCF");
-
-	if (debugChannelSet(5, kDebugLoading))
-		stream.hexdump(stream.size());
-
-	uint16 len = stream.readUint16();
-	uint16 ver1 = stream.readUint16();
-	_movieRect = Score::readRect(stream);
-
-	_castArrayStart = stream.readUint16();
-	_castArrayEnd = stream.readUint16();
-	_currentFrameRate = stream.readByte();
-
-	if (_currentFrameRate == 0)
-		_currentFrameRate = 20;
-
-	byte lightswitch = stream.readByte();
-	uint16 unk1 = stream.readUint16();
-	uint16 commentFont = stream.readUint16();
-	uint16 commentSize = stream.readUint16();
-	uint16 commentStyle = stream.readUint16();
-	_stageColor = _vm->transformColor(stream.readUint16());
-	uint16 bitdepth = stream.readUint16();
-	byte color = stream.readByte();	// boolean, color = 1, B/W = 0
-	uint16 stageColorR = stream.readUint16();
-	uint16 stageColorG = stream.readUint16();
-	uint16 stageColorB = stream.readUint16();
-
-	for (int i = 0; i < 0x0b; i++) {
-		stream.readByte();
-	}
-
-	if (_vm->getVersion() >= 4) {
-		for (int i = 0; i < 0x16; i++) {
-			stream.readByte();
-		}
-
-		int palette = (int16)stream.readUint16();
-		_vm->setPalette(palette - 1);
-
-		for (int i = 0; i < 0x08; i++) {
-			stream.readByte();
-		}
-	}
-
-	debugC(1, kDebugLoading, "Score::loadConfig(): len: %d, ver: %d, framerate: %d, light: %d, unk: %d, font: %d, size: %d"
-			", style: %d", len, ver1, _currentFrameRate, lightswitch, unk1, commentFont, commentSize, commentStyle);
-	debugC(1, kDebugLoading, "Score::loadConfig(): stagecolor: %d, depth: %d, color: %d, rgb: 0x%04x 0x%04x 0x%04x",
-			_stageColor, bitdepth, color, stageColorR, stageColorG, stageColorB);
-	if (debugChannelSet(1, kDebugLoading))
-		_movieRect.debugPrint(1, "Score::loadConfig(): Movie rect: ");
-}
-
-void Score::readVersion(uint32 rid) {
-	_versionMinor = rid & 0xffff;
-	_versionMajor = rid >> 16;
-
-	debug("Version: %d.%d", _versionMajor, _versionMinor);
-}
-
-void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
+void Cast::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
 	debugC(1, kDebugLoading, "****** Loading CastMember rects VWCR. start: %d, end: %d", _castArrayStart, _castArrayEnd);
 
 	_loadedCast = new Common::HashMap<int, CastMember *>();
@@ -671,9 +610,9 @@ void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
 		switch (castType) {
 		case kCastBitmap:
 			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) BitmapCastMember", id, numToCastNum(id));
-			if (_movieArchive->hasResource(MKTAG('B', 'I', 'T', 'D'), id + _castIDoffset))
+			if (_castArchive->hasResource(MKTAG('B', 'I', 'T', 'D'), id + _castIDoffset))
 				tag = MKTAG('B', 'I', 'T', 'D');
-			else if (_movieArchive->hasResource(MKTAG('D', 'I', 'B', ' '), id + _castIDoffset))
+			else if (_castArchive->hasResource(MKTAG('D', 'I', 'B', ' '), id + _castIDoffset))
 				tag = MKTAG('D', 'I', 'B', ' ');
 			else
 				error("Score::loadCastDataVWCR(): non-existent reference to BitmapCastMember");
@@ -706,22 +645,11 @@ void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
 			continue;
 		}
 		stream.seek(returnPos);
-		_loadedCast->getVal(id)->_score = this;
-	}
-}
-
-void Score::setSpriteCasts() {
-	// Update sprite cache of cast pointers/info
-	for (uint16 i = 0; i < _frames.size(); i++) {
-		for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
-			_frames[i]->_sprites[j]->setCast(_frames[i]->_sprites[j]->_castId);
-
-			debugC(1, kDebugImages, "Score::setSpriteCasts(): Frame: %d Channel: %d castId: %d type: %d", i, j, _frames[i]->_sprites[j]->_castId, _frames[i]->_sprites[j]->_spriteType);
-		}
+		_loadedCast->getVal(id)->_cast = this;
 	}
 }
 
-void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id, Resource *res) {
+void Cast::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id, Resource *res) {
 	// IDs are stored as relative to the start of the cast array.
 	id += _castArrayStart;
 
@@ -841,7 +769,7 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 	}
 
 	if (_loadedCast->contains(id)) { // Skip unhandled casts
-		_loadedCast->getVal(id)->_score = this;
+		_loadedCast->getVal(id)->_cast = this;
 
 		debugCN(3, kDebugLoading, "Children: ");
 		for (uint child = 0; child < res->children.size(); child++) {
@@ -855,7 +783,7 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 
 	if (size2 && _vm->getVersion() < 5) {
 		uint32 entryType = 0;
-		Common::Array<Common::String> castStrings = loadStrings(stream, entryType, false);
+		Common::Array<Common::String> castStrings = Movie::loadStrings(stream, entryType, false);
 
 		debugCN(4, kDebugLoading, "Score::loadCastData(): str(%d): '", castStrings.size());
 
@@ -921,126 +849,7 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 		warning("Score::loadCastData(): size3: %x", size3);
 }
 
-void Score::loadLabels(Common::SeekableSubReadStreamEndian &stream) {
-	if (debugChannelSet(5, kDebugLoading)) {
-		debug("Score::loadLabels()");
-		stream.hexdump(stream.size());
-	}
-
-	_labels = new Common::SortedArray<Label *>(compareLabels);
-	uint16 count = stream.readUint16() + 1;
-	uint32 offset = count * 4 + 2;
-
-	uint16 frame = stream.readUint16();
-	uint32 stringPos = stream.readUint16() + offset;
-
-	for (uint16 i = 1; i < count; i++) {
-		uint16 nextFrame = stream.readUint16();
-		uint32 nextStringPos = stream.readUint16() + offset;
-		uint32 streamPos = stream.pos();
-
-		stream.seek(stringPos);
-		Common::String label;
-
-		for (uint32 j = stringPos; j < nextStringPos; j++) {
-			label += stream.readByte();
-		}
-
-		_labels->insert(new Label(label, frame));
-		stream.seek(streamPos);
-
-		frame = nextFrame;
-		stringPos = nextStringPos;
-	}
-
-	Common::SortedArray<Label *>::iterator j;
-
-	debugC(2, kDebugLoading, "****** Loading labels");
-	for (j = _labels->begin(); j != _labels->end(); ++j) {
-		debugC(2, kDebugLoading, "Frame %d, Label '%s'", (*j)->number, Common::toPrintable((*j)->name).c_str());
-	}
-}
-
-int Score::compareLabels(const void *a, const void *b) {
-	return ((const Label *)a)->number - ((const Label *)b)->number;
-}
-
-void Score::loadActions(Common::SeekableSubReadStreamEndian &stream) {
-	debugC(2, kDebugLoading, "****** Loading Actions VWAC");
-
-	uint16 count = stream.readUint16() + 1;
-	uint32 offset = count * 4 + 2;
-
-	byte id = stream.readByte();
-
-	byte subId = stream.readByte(); // I couldn't find how it used in continuity (except print). Frame actionId = 1 byte.
-	uint32 stringPos = stream.readUint16() + offset;
-
-	for (uint16 i = 0; i < count; i++) {
-		uint16 nextId = stream.readByte();
-		byte nextSubId = stream.readByte();
-		uint32 nextStringPos = stream.readUint16() + offset;
-		uint32 streamPos = stream.pos();
-
-		stream.seek(stringPos);
-
-		for (uint16 j = stringPos; j < nextStringPos; j++) {
-			byte ch = stream.readByte();
-			if (ch == 0x0d) {
-				ch = '\n';
-			}
-			_actions[i + 1] += ch;
-		}
-
-		debugC(3, kDebugLoading, "Action id: %d nextId: %d subId: %d, code: %s", id, nextId, subId, _actions[id].c_str());
-
-		stream.seek(streamPos);
-
-		id = nextId;
-		subId = nextSubId;
-		stringPos = nextStringPos;
-
-		if ((int32)stringPos == stream.size())
-			break;
-	}
-
-	bool *scriptRefs = (bool *)calloc(_actions.size() + 1, sizeof(int));
-
-	// Now let's scan which scripts are actually referenced
-	for (uint i = 0; i < _frames.size(); i++) {
-		if (_frames[i]->_actionId <= _actions.size())
-			scriptRefs[_frames[i]->_actionId] = true;
-
-		for (uint16 j = 0; j <= _frames[i]->_numChannels; j++) {
-			if (_frames[i]->_sprites[j]->_scriptId <= _actions.size())
-				scriptRefs[_frames[i]->_sprites[j]->_scriptId] = true;
-		}
-	}
-
-	Common::HashMap<uint16, Common::String>::iterator j;
-
-	if (ConfMan.getBool("dump_scripts"))
-		for (j = _actions.begin(); j != _actions.end(); ++j) {
-			if (!j->_value.empty())
-				dumpScript(j->_value.c_str(), kScoreScript, j->_key);
-		}
-
-	for (j = _actions.begin(); j != _actions.end(); ++j) {
-		if (!scriptRefs[j->_key]) {
-			warning("Action id %d is not referenced, the code is:\n-----\n%s\n------", j->_key, j->_value.c_str());
-			// continue;
-		}
-		if (!j->_value.empty()) {
-			_lingo->addCode(j->_value.c_str(), _lingoArchive, kScoreScript, j->_key);
-
-			processImmediateFrameScript(j->_value, j->_key);
-		}
-	}
-
-	free(scriptRefs);
-}
-
-void Score::loadLingoNames(Common::SeekableSubReadStreamEndian &stream) {
+void Cast::loadLingoNames(Common::SeekableSubReadStreamEndian &stream) {
 	if (_vm->getVersion() >= 4) {
 		_lingo->addNamesV4(stream, _lingoArchive);
 	} else {
@@ -1048,7 +857,7 @@ void Score::loadLingoNames(Common::SeekableSubReadStreamEndian &stream) {
 	}
 }
 
-void Score::loadLingoContext(Common::SeekableSubReadStreamEndian &stream) {
+void Cast::loadLingoContext(Common::SeekableSubReadStreamEndian &stream) {
 	if (_vm->getVersion() >= 4) {
 		debugC(1, kDebugCompile, "Add V4 script context");
 
@@ -1087,7 +896,7 @@ void Score::loadLingoContext(Common::SeekableSubReadStreamEndian &stream) {
 		for (Common::Array<int16>::iterator iterator = lscr.begin(); iterator != lscr.end(); ++iterator) {
 			if (*iterator >= 0) {
 				Common::SeekableSubReadStreamEndian *r;
-				_lingo->addCodeV4(*(r = _movieArchive->getResource(MKTAG('L', 's', 'c', 'r'), *iterator)), _lingoArchive, _macName);
+				_lingo->addCodeV4(*(r = _castArchive->getResource(MKTAG('L', 's', 'c', 'r'), *iterator)), _lingoArchive, _macName);
 				delete r;
 			}
 		}
@@ -1096,7 +905,7 @@ void Score::loadLingoContext(Common::SeekableSubReadStreamEndian &stream) {
 	}
 }
 
-void Score::loadScriptText(Common::SeekableSubReadStreamEndian &stream) {
+void Cast::loadScriptText(Common::SeekableSubReadStreamEndian &stream) {
 	/*uint32 unk1 = */ stream.readUint32();
 	uint32 strLen = stream.readUint32();
 	/*uin32 dataLen = */ stream.readUint32();
@@ -1128,7 +937,7 @@ void Score::loadScriptText(Common::SeekableSubReadStreamEndian &stream) {
 	_movieScriptCount++;
 }
 
-void Score::dumpScript(const char *script, ScriptType type, uint16 id) {
+void Cast::dumpScript(const char *script, ScriptType type, uint16 id) {
 	Common::DumpFile out;
 	Common::String buf = dumpScriptName(_macName.c_str(), type, id, "txt");
 
@@ -1143,9 +952,9 @@ void Score::dumpScript(const char *script, ScriptType type, uint16 id) {
 	out.close();
 }
 
-void Score::loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id) {
+void Cast::loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id) {
 	uint32 entryType = 0;
-	Common::Array<Common::String> castStrings = loadStrings(stream, entryType);
+	Common::Array<Common::String> castStrings = Movie::loadStrings(stream, entryType);
 	CastMemberInfo *ci = new CastMemberInfo();
 
 	ci->script = castStrings[0];
@@ -1172,71 +981,7 @@ void Score::loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id)
 	_castsInfo[id] = ci;
 }
 
-void Score::loadFileInfo(Common::SeekableSubReadStreamEndian &stream) {
-	debugC(2, kDebugLoading, "****** Loading FileInfo VWFI");
-
-	Common::Array<Common::String> fileInfoStrings = loadStrings(stream, _flags);
-	_script = fileInfoStrings[0];
-
-	if (!_script.empty() && ConfMan.getBool("dump_scripts"))
-		dumpScript(_script.c_str(), kMovieScript, _movieScriptCount);
-
-	if (!_script.empty())
-		_lingo->addCode(_script.c_str(), _lingoArchive, kMovieScript, _movieScriptCount);
-
-	_movieScriptCount++;
-	_changedBy = fileInfoStrings[1];
-	_createdBy = fileInfoStrings[2];
-	_directory = fileInfoStrings[3];
-}
-
-Common::Array<Common::String> Score::loadStrings(Common::SeekableSubReadStreamEndian &stream, uint32 &entryType, bool hasHeader) {
-	Common::Array<Common::String> strings;
-	uint32 offset = 0;
-
-	if (hasHeader) {
-		offset = stream.readUint32();
-		/*uint32 unk1 = */ stream.readUint32();
-		/*uint32 unk2 = */ stream.readUint32();
-		entryType = stream.readUint32();
-		stream.seek(offset);
-	}
-
-	uint16 count = stream.readUint16() + 1;
-
-	debugC(3, kDebugLoading, "Score::loadStrings(): Strings: %d entries", count);
-
-	uint32 *entries = (uint32 *)calloc(count, sizeof(uint32));
-
-	for (uint i = 0; i < count; i++)
-		entries[i] = stream.readUint32();
-
-	byte *data = (byte *)malloc(entries[count - 1]);
-	stream.read(data, entries[count - 1]);
-
-	for (uint16 i = 0; i < count - 1; i++) {
-		Common::String entryString;
-
-		uint start = i == 1 ? entries[i] + 1 : entries[i]; // Skip first byte which is string length
-
-		for (uint j = start; j < entries[i + 1]; j++)
-			if (data[j] == '\r')
-				entryString += '\n';
-			else if (data[j] >= 0x20)
-				entryString += data[j];
-
-		strings.push_back(entryString);
-
-		debugC(6, kDebugLoading, "String %d:\n%s\n", i, Common::toPrintable(entryString).c_str());
-	}
-
-	free(data);
-	free(entries);
-
-	return strings;
-}
-
-void Score::loadFontMap(Common::SeekableSubReadStreamEndian &stream) {
+void Cast::loadFontMap(Common::SeekableSubReadStreamEndian &stream) {
 	if (stream.size() == 0)
 		return;
 
@@ -1268,14 +1013,4 @@ void Score::loadFontMap(Common::SeekableSubReadStreamEndian &stream) {
 	}
 }
 
-Common::Rect Score::readRect(Common::ReadStreamEndian &stream) {
-	Common::Rect rect;
-	rect.top = stream.readUint16();
-	rect.left = stream.readUint16();
-	rect.bottom = stream.readUint16();
-	rect.right = stream.readUint16();
-
-	return rect;
-}
-
 } // End of namespace Director
diff --git a/engines/director/cast.h b/engines/director/cast.h
new file mode 100644
index 0000000000..ade8ca46e3
--- /dev/null
+++ b/engines/director/cast.h
@@ -0,0 +1,108 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef DIRECTOR_CAST_H
+#define DIRECTOR_CAST_H
+
+#include "common/hash-str.h"
+#include "director/types.h"
+
+namespace Common {
+	class ReadStreamEndian;
+	struct Rect;
+	class SeekableSubReadStreamEndian;
+}
+
+namespace Director {
+
+class Archive;
+struct CastMemberInfo;
+class CastMember;
+class DirectorEngine;
+class Lingo;
+struct Resource;
+struct Stxt;
+class BitmapCastMember;
+class ScriptCastMember;
+class ShapeCastMember;
+class TextCastMember;
+
+class Cast {
+public:
+	Cast(DirectorEngine *vm, Movie *movie = nullptr);
+	~Cast();
+
+	bool loadArchive();
+	void setArchive(Archive *archive);
+	Archive *getArchive() const { return _castArchive; };
+
+	void loadConfig(Common::SeekableSubReadStreamEndian &stream);
+	void loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream);
+	void loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id, Resource *res);
+	void loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id);
+	void loadLingoNames(Common::SeekableSubReadStreamEndian &stream);
+	void loadLingoContext(Common::SeekableSubReadStreamEndian &stream);
+
+	void loadSpriteImages();
+	void loadSpriteSounds();
+
+	void copyCastStxts();
+	void createCastWidgets();
+	Common::Rect getCastMemberInitialRect(int castId);
+	void setCastMemberModified(int castId);
+	CastMember *getCastMember(int castId);
+	const Stxt *getStxt(int castId);
+
+	void dumpScript(const char *script, ScriptType type, uint16 id);
+
+private:
+	void loadPalette(Common::SeekableSubReadStreamEndian &stream);
+	void loadScriptText(Common::SeekableSubReadStreamEndian &stream);
+	void loadFontMap(Common::SeekableSubReadStreamEndian &stream);
+	Common::String getString(Common::String str);
+
+public:
+	Archive *_castArchive;
+	Common::HashMap<uint16, CastMemberInfo *> _castsInfo;
+	Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _castsNames;
+	Common::HashMap<uint16, Common::String> _fontMap;
+
+	Common::HashMap<int, CastMember *> *_loadedCast;
+	Common::HashMap<int, const Stxt *> *_loadedStxts;
+	uint16 _castIDoffset;
+	uint16 _castArrayStart;
+	uint16 _castArrayEnd;
+
+	uint16 _movieScriptCount;
+	int _lingoArchive;
+
+private:
+	DirectorEngine *_vm;
+	Lingo *_lingo;
+	Movie *_movie;
+
+	Common::String _macName;
+};
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index 929c57d048..fc415f7b9e 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -29,6 +29,7 @@
 
 #include "director/director.h"
 #include "director/castmember.h"
+#include "director/movie.h"
 #include "director/score.h"
 #include "director/sound.h"
 #include "director/stxt.h"
@@ -37,7 +38,7 @@ namespace Director {
 
 CastMember::CastMember() {
 	_type = kCastTypeNull;
-	_score = nullptr;
+	_cast = nullptr;
 	_widget = nullptr;
 	_hilite = false;
 
@@ -57,8 +58,8 @@ BitmapCastMember::BitmapCastMember(Common::ReadStreamEndian &stream, uint32 cast
 	if (version < 4) {
 		_flags = stream.readByte();	// region: 0 - auto, 1 - matte, 2 - disabled
 		_bytes = stream.readUint16();
-		_initialRect = Score::readRect(stream);
-		_boundingRect = Score::readRect(stream);
+		_initialRect = Movie::readRect(stream);
+		_boundingRect = Movie::readRect(stream);
 		_regY = stream.readUint16();
 		_regX = stream.readUint16();
 
@@ -78,8 +79,8 @@ BitmapCastMember::BitmapCastMember(Common::ReadStreamEndian &stream, uint32 cast
 		_pitch = stream.readUint16();
 		_pitch &= 0x0fff;
 
-		_initialRect = Score::readRect(stream);
-		_boundingRect = Score::readRect(stream);
+		_initialRect = Movie::readRect(stream);
+		_boundingRect = Movie::readRect(stream);
 		_regY = stream.readUint16();
 		_regX = stream.readUint16();
 
@@ -108,10 +109,10 @@ BitmapCastMember::BitmapCastMember(Common::ReadStreamEndian &stream, uint32 cast
 			stream.readByte();
 
 		/*uint16 width =*/ stream.readUint16LE(); //maybe?
-		_initialRect = Score::readRect(stream);
+		_initialRect = Movie::readRect(stream);
 
 		/*uint32 somethingElse =*/ stream.readUint32();
-		_boundingRect = Score::readRect(stream);
+		_boundingRect = Movie::readRect(stream);
 
 		_bitsPerPixel = stream.readUint16();
 
@@ -238,7 +239,7 @@ TextCastMember::TextCastMember(Common::ReadStreamEndian &stream, uint16 version,
 				warning("TextCastMember: pad2: %x", pad2);
 			}
 
-			_initialRect = Score::readRect(stream);
+			_initialRect = Movie::readRect(stream);
 			pad3 = stream.readUint16();
 
 			_textShadow = static_cast<SizeType>(stream.readByte());
@@ -249,7 +250,7 @@ TextCastMember::TextCastMember(Common::ReadStreamEndian &stream, uint16 version,
 			totalTextHeight = stream.readUint16();
 		} else {
 			pad2 = stream.readUint16();
-			_initialRect = Score::readRect(stream);
+			_initialRect = Movie::readRect(stream);
 			pad3 = stream.readUint16();
 			pad4 = stream.readUint16();
 			totalTextHeight = stream.readUint16();
@@ -276,7 +277,7 @@ TextCastMember::TextCastMember(Common::ReadStreamEndian &stream, uint16 version,
 
 		_fontId = 1; // this is in STXT
 
-		_initialRect = Score::readRect(stream);
+		_initialRect = Movie::readRect(stream);
 		stream.readUint16();
 		_textShadow = static_cast<SizeType>(stream.readByte());
 		byte flags2 = stream.readByte();
@@ -305,8 +306,8 @@ TextCastMember::TextCastMember(Common::ReadStreamEndian &stream, uint16 version,
 		stream.readUint32();
 		stream.readUint32();
 
-		_initialRect = Score::readRect(stream);
-		_boundingRect = Score::readRect(stream);
+		_initialRect = Movie::readRect(stream);
+		_boundingRect = Movie::readRect(stream);
 
 		stream.readUint32();
 		stream.readUint16();
@@ -480,7 +481,7 @@ ShapeCastMember::ShapeCastMember(Common::ReadStreamEndian &stream, uint16 versio
 		flags = stream.readByte();
 		unk1 = stream.readByte();
 		_shapeType = static_cast<ShapeType>(stream.readByte());
-		_initialRect = Score::readRect(stream);
+		_initialRect = Movie::readRect(stream);
 		_pattern = stream.readUint16BE();
 		// Normalize D2 and D3 colors from -128 ... 127 to 0 ... 255.
 		_fgCol = g_director->transformColor((128 + stream.readByte()) & 0xff);
@@ -493,7 +494,7 @@ ShapeCastMember::ShapeCastMember(Common::ReadStreamEndian &stream, uint16 versio
 		flags = stream.readByte();
 		unk1 = stream.readByte();
 		_shapeType = static_cast<ShapeType>(stream.readByte());
-		_initialRect = Score::readRect(stream);
+		_initialRect = Movie::readRect(stream);
 		_pattern = stream.readUint16BE();
 		_fgCol = g_director->transformColor((uint8)stream.readByte());
 		_bgCol = g_director->transformColor((uint8)stream.readByte());
@@ -505,8 +506,8 @@ ShapeCastMember::ShapeCastMember(Common::ReadStreamEndian &stream, uint16 versio
 		flags = stream.readByte();
 		unk1 = stream.readByte();
 
-		_initialRect = Score::readRect(stream);
-		_boundingRect = Score::readRect(stream);
+		_initialRect = Movie::readRect(stream);
+		_boundingRect = Movie::readRect(stream);
 
 		_shapeType = kShapeRectangle;
 		_pattern = 0;
@@ -557,8 +558,8 @@ ScriptCastMember::ScriptCastMember(Common::ReadStreamEndian &stream, uint16 vers
 			error("ScriptCastMember: Unprocessed script type: %d", type);
 		}
 
-		_initialRect = Score::readRect(stream);
-		_boundingRect = Score::readRect(stream);
+		_initialRect = Movie::readRect(stream);
+		_boundingRect = Movie::readRect(stream);
 
 		_id = stream.readUint32();
 
@@ -570,8 +571,8 @@ ScriptCastMember::ScriptCastMember(Common::ReadStreamEndian &stream, uint16 vers
 		stream.readByte();
 		stream.readByte();
 
-		_initialRect = Score::readRect(stream);
-		_boundingRect = Score::readRect(stream);
+		_initialRect = Movie::readRect(stream);
+		_boundingRect = Movie::readRect(stream);
 
 		_id = stream.readUint32();
 
diff --git a/engines/director/castmember.h b/engines/director/castmember.h
index 35469183d0..961ae52a7b 100644
--- a/engines/director/castmember.h
+++ b/engines/director/castmember.h
@@ -63,7 +63,7 @@ public:
 	virtual void getColors(int *fgcolor, int *bgcolor) { return; }
 
 	CastType _type;
-	Score *_score;
+	Cast *_cast;
 	Common::Rect _initialRect;
 	Common::Rect _boundingRect;
 	Common::Array<Resource> _children;
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 6014ececc5..979aefd19a 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -32,10 +32,12 @@
 #include "graphics/macgui/macwindowmanager.h"
 
 #include "director/director.h"
-#include "director/stage.h"
 #include "director/archive.h"
+#include "director/cast.h"
+#include "director/movie.h"
 #include "director/score.h"
 #include "director/sound.h"
+#include "director/stage.h"
 #include "director/lingo/lingo.h"
 #include "director/util.h"
 
@@ -78,13 +80,13 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
 	// Load key codes
 	loadKeyCodes();
 
-	_currentScore = nullptr;
+	_currentMovie = nullptr;
 	_soundManager = nullptr;
 	_currentPalette = nullptr;
 	_currentPaletteLength = 0;
 	_lingo = nullptr;
 
-	_sharedScore = nullptr;
+	_sharedCast = nullptr;
 
 	_mainArchive = nullptr;
 	_macBinary = nullptr;
@@ -118,8 +120,8 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
 }
 
 DirectorEngine::~DirectorEngine() {
-	delete _sharedScore;
-	delete _currentScore;
+	delete _sharedCast;
+	delete _currentMovie;
 
 	_wm->removeWindow(_currentStage);
 
@@ -167,7 +169,7 @@ Common::Error DirectorEngine::run() {
 	//_mainArchive = new RIFFArchive();
 	//_mainArchive->openFile("bookshelf_example.mmm");
 
-	_currentScore = new Score(this);
+	_currentMovie = new Movie(this);
 	_currentPath = getPath(getEXEName(), _currentPath);
 
 	if (getPlatform() == Common::kPlatformWindows)
@@ -217,7 +219,7 @@ Common::Error DirectorEngine::run() {
 			}
 
 			if (_mainArchive->hasResource(MKTAG('S', 'T', 'R', '#'), 0)) {
-				_currentScore->setArchive(_mainArchive);
+				_currentMovie->setArchive(_mainArchive);
 
 				Common::SeekableSubReadStreamEndian *name = _mainArchive->getResource(MKTAG('S', 'T', 'R', '#'), 0);
 				int num = name->readUint16();
@@ -233,46 +235,46 @@ Common::Error DirectorEngine::run() {
 				_nextMovie.movie = pathMakeRelative(sname);
 				warning("Replaced score name with: %s (from %s)", _nextMovie.movie.c_str(), sname.c_str());
 
-				delete _currentScore;
-				_currentScore = nullptr;
+				delete _currentMovie;
+				_currentMovie = nullptr;
 
 				delete name;
 			}
 		}
 	}
 
-	if (_currentScore)
-		_currentScore->setArchive(_mainArchive);
+	if (_currentMovie)
+		_currentMovie->setArchive(_mainArchive);
 
 	bool loop = true;
 
 	while (loop) {
 		loop = false;
 
-		if (_currentScore) {
+		if (_currentMovie) {
 			debug(0, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
-			debug(0, "@@@@   Score name '%s' in '%s'", _currentScore->getMacName().c_str(), _currentPath.c_str());
+			debug(0, "@@@@   Movie name '%s' in '%s'", _currentMovie->getMacName().c_str(), _currentPath.c_str());
 			debug(0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
 
-			bool goodMovie = _currentScore->loadArchive(false);
+			bool goodMovie = _currentMovie->loadArchive();
 
 			// If we came in a loop, then skip as requested
 			if (!_nextMovie.frameS.empty()) {
-				_currentScore->setStartToLabel(_nextMovie.frameS);
+				_currentMovie->getScore()->setStartToLabel(_nextMovie.frameS);
 				_nextMovie.frameS.clear();
 			}
 
 			if (_nextMovie.frameI != -1) {
-				_currentScore->setCurrentFrame(_nextMovie.frameI);
+				_currentMovie->getScore()->setCurrentFrame(_nextMovie.frameI);
 				_nextMovie.frameI = -1;
 			}
 
 			if (!debugChannelSet(-1, kDebugCompileOnly) && goodMovie) {
-				debugC(1, kDebugEvents, "Starting playback of score '%s'", _currentScore->getMacName().c_str());
+				debugC(1, kDebugEvents, "Starting playback of movie '%s'", _currentMovie->getMacName().c_str());
 
-				_currentScore->startLoop();
+				_currentMovie->getScore()->startLoop();
 
-				debugC(1, kDebugEvents, "Finished playback of score '%s'", _currentScore->getMacName().c_str());
+				debugC(1, kDebugEvents, "Finished playback of movie '%s'", _currentMovie->getMacName().c_str());
 			}
 		}
 
@@ -284,13 +286,13 @@ Common::Error DirectorEngine::run() {
 		if (!_nextMovie.movie.empty()) {
 			_newMovieStarted = true;
 
-			delete _currentScore;
-			_currentScore = nullptr;
+			delete _currentMovie;
+			_currentMovie = nullptr;
 
 			_currentPath = getPath(_nextMovie.movie, _currentPath);
 
-			if (_sharedScore && _sharedScore->_movieArchive
-					&& _sharedScore->_movieArchive->getFileName().equalsIgnoreCase(_currentPath + _sharedCastFile)) {
+			if (_sharedCast && _sharedCast->_castArchive
+					&& _sharedCast->_castArchive->getFileName().equalsIgnoreCase(_currentPath + _sharedCastFile)) {
 				_lingo->resetLingo(true);
 			} else {
 				_lingo->resetLingo(false);
@@ -300,7 +302,7 @@ Common::Error DirectorEngine::run() {
 			Archive *mov = openMainArchive(_currentPath + Common::lastPathComponent(_nextMovie.movie, '/'));
 
 			if (!mov) {
-				warning("nextMovie: No score is loaded");
+				warning("nextMovie: No movie is loaded");
 
 				if (getGameGID() == GID_TESTALL) {
 					loop = true;
@@ -310,9 +312,9 @@ Common::Error DirectorEngine::run() {
 				return Common::kNoError;
 			}
 
-			_currentScore = new Score(this);
-			_currentScore->setArchive(mov);
-			debug(0, "Switching to score '%s'", _currentScore->getMacName().c_str());
+			_currentMovie = new Movie(this);
+			_currentMovie->setArchive(mov);
+			debug(0, "Switching to movie '%s'", _currentMovie->getMacName().c_str());
 
 			_nextMovie.movie.clear();
 			loop = true;
diff --git a/engines/director/director.h b/engines/director/director.h
index dbb8079705..6d503e6f2d 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -54,9 +54,11 @@ enum DirectorGameGID {
 };
 
 class Archive;
+class Cast;
 struct DirectorGameDescription;
 class DirectorSound;
 class Lingo;
+class Movie;
 class Stage;
 class Score;
 class CastMember;
@@ -134,8 +136,8 @@ public:
 	Archive *getMainArchive() const { return _mainArchive; }
 	Lingo *getLingo() const { return _lingo; }
 	Stage *getStage() const { return _currentStage; }
-	Score *getCurrentScore() const { return _currentScore; }
-	Score *getSharedScore() const { return _sharedScore; }
+	Movie *getCurrentMovie() const { return _currentMovie; }
+	Cast *getSharedCast() const { return _sharedCast; }
 	Common::String getCurrentPath() const { return _currentPath; }
 	void setPalette(int id);
 	void setPalette(byte *palette, uint16 count);
@@ -191,7 +193,7 @@ protected:
 private:
 	const DirectorGameDescription *_gameDescription;
 
-	Common::HashMap<Common::String, Score *> *scanMovies(const Common::String &folder);
+	Common::HashMap<Common::String, Movie *> *scanMovies(const Common::String &folder);
 	void loadEXE(const Common::String movie);
 	void loadEXEv3(Common::SeekableReadStream *stream);
 	void loadEXEv4(Common::SeekableReadStream *stream);
@@ -200,7 +202,7 @@ private:
 	void loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset);
 	void loadMac(const Common::String movie);
 
-	Score *_sharedScore;
+	Cast *_sharedCast;
 
 	Archive *_mainArchive;
 	Common::MacResManager *_macBinary;
@@ -210,7 +212,7 @@ private:
 	Lingo *_lingo;
 
 	Stage *_currentStage;
-	Score *_currentScore;
+	Movie *_currentMovie;
 	Common::String _currentPath;
 
 	Graphics::MacPatterns _director3Patterns;
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index e19058d832..f3a395f07b 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -26,6 +26,7 @@
 
 #include "director/director.h"
 #include "director/frame.h"
+#include "director/movie.h"
 #include "director/score.h"
 #include "director/sprite.h"
 #include "director/castmember.h"
@@ -38,7 +39,7 @@ bool processQuitEvent(bool click) {
 
 	while (g_system->getEventManager()->pollEvent(event)) {
 		if (event.type == Common::EVENT_QUIT) {
-			g_director->getCurrentScore()->_stopPlay = true;
+			g_director->getCurrentMovie()->getScore()->_stopPlay = true;
 			return true;
 		}
 
@@ -58,7 +59,8 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
 
 	uint endTime = g_system->getMillis() + 10;
 
-	Score *sc = getCurrentScore();
+	Movie *m = getCurrentMovie();
+	Score *sc = m->getScore();
 	if (sc->getCurrentFrame() >= sc->_frames.size()) {
 		warning("processEvents: request to access frame %d of %d", sc->getCurrentFrame(), sc->_frames.size() - 1);
 		return;
@@ -78,8 +80,8 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
 				break;
 
 			case Common::EVENT_MOUSEMOVE:
-				sc->_lastEventTime = g_director->getMacTicks();
-				sc->_lastRollTime =	 sc->_lastEventTime;
+				m->_lastEventTime = g_director->getMacTicks();
+				m->_lastRollTime =	 m->_lastEventTime;
 
 				if (_draggingSprite) {
 					Sprite *draggedSprite = sc->getSpriteById(_draggingSpriteId);
@@ -100,11 +102,11 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
 				// D3 doesn't have both mouse up and down.
 				// But we still want to know if the mouse is down for press effects.
 				spriteId = sc->getSpriteIDFromPos(pos, true);
-				sc->_currentMouseDownSpriteId = spriteId;
-				sc->_currentClickOnSpriteId = spriteId;
+				m->_currentMouseDownSpriteId = spriteId;
+				m->_currentClickOnSpriteId = spriteId;
 
-				sc->_lastEventTime = g_director->getMacTicks();
-				sc->_lastClickTime = sc->_lastEventTime;
+				m->_lastEventTime = g_director->getMacTicks();
+				m->_lastClickTime = m->_lastEventTime;
 
 				debugC(3, kDebugEvents, "event: Button Down @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
 				_lingo->registerEvent(kEventMouseDown, spriteId);
@@ -119,11 +121,11 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
 
 				spriteId = sc->getSpriteIDFromPos(pos, true);
 
-				if (!sc->getChannelById(sc->_currentMouseDownSpriteId)->getBbox().contains(pos))
-					sc->_currentMouseDownSpriteId = 0;
+				if (!sc->getChannelById(m->_currentMouseDownSpriteId)->getBbox().contains(pos))
+					m->_currentMouseDownSpriteId = 0;
 
 				if (!(g_director->_wm->_mode & Graphics::kWMModeButtonDialogStyle))
-					sc->_currentMouseDownSpriteId = spriteId;
+					m->_currentMouseDownSpriteId = spriteId;
 
 				debugC(3, kDebugEvents, "event: Button Up @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
 
@@ -136,7 +138,7 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
 				}
 
 				_lingo->registerEvent(kEventMouseUp, spriteId);
-				sc->_currentMouseDownSpriteId = 0;
+				m->_currentMouseDownSpriteId = 0;
 				break;
 
 			case Common::EVENT_KEYDOWN:
@@ -145,8 +147,8 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
 
 				debugC(1, kDebugEvents, "processEvents(): keycode: %d", _keyCode);
 
-				sc->_lastEventTime = g_director->getMacTicks();
-				sc->_lastKeyTime = sc->_lastEventTime;
+				m->_lastEventTime = g_director->getMacTicks();
+				m->_lastKeyTime = m->_lastEventTime;
 				_lingo->registerEvent(kEventKeyDown);
 				break;
 
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index e7737fad38..1ac52d5acb 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -23,11 +23,13 @@
 #include "common/system.h"
 
 #include "director/director.h"
+#include "director/cast.h"
 #include "director/castmember.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-builtins.h"
 #include "director/lingo/lingo-code.h"
 #include "director/frame.h"
+#include "director/movie.h"
 #include "director/score.h"
 #include "director/sound.h"
 #include "director/sprite.h"
@@ -1111,7 +1113,7 @@ void LB::b_nothing(int nargs) {
 void LB::b_delay(int nargs) {
 	Datum d = g_lingo->pop();
 
-	g_director->getCurrentScore()->_nextFrameTime = g_system->getMillis() + (float)d.asInt() / 60 * 1000;
+	g_director->getCurrentMovie()->getScore()->_nextFrameTime = g_system->getMillis() + (float)d.asInt() / 60 * 1000;
 }
 
 void LB::b_do(int nargs) {
@@ -1273,8 +1275,8 @@ void LB::b_printFrom(int nargs) {
 }
 
 void LB::b_quit(int nargs) {
-	if (g_director->getCurrentScore())
-		g_director->getCurrentScore()->_stopPlay = true;
+	if (g_director->getCurrentMovie())
+		g_director->getCurrentMovie()->getScore()->_stopPlay = true;
 
 	g_lingo->pushVoid();
 }
@@ -1312,7 +1314,7 @@ void LB::b_shutDown(int nargs) {
 }
 
 void LB::b_startTimer(int nargs) {
-	g_director->getCurrentScore()->_lastTimerReset = g_director->getMacTicks();
+	g_director->getCurrentMovie()->_lastTimerReset = g_director->getMacTicks();
 }
 
 ///////////////////
@@ -1466,7 +1468,7 @@ void LB::b_duplicate(int nargs) {
 }
 
 void LB::b_editableText(int nargs) {
-	Score *sc = g_director->getCurrentScore();
+	Score *sc = g_director->getCurrentMovie()->getScore();
 	if (!sc) {
 		warning("b_editableText: no score");
 		g_lingo->dropStack(nargs);
@@ -1665,7 +1667,7 @@ void LB::b_move(int nargs) {
 }
 
 void LB::b_moveableSprite(int nargs) {
-	Frame *frame = g_director->getCurrentScore()->_frames[g_director->getCurrentScore()->getCurrentFrame()];
+	Frame *frame = g_director->getCurrentMovie()->getScore()->_frames[g_director->getCurrentMovie()->getScore()->getCurrentFrame()];
 
 	if (g_lingo->_currentChannelId == -1) {
 		warning("b_moveableSprite: channel Id is missing");
@@ -1695,7 +1697,7 @@ void LB::b_puppetSound(int nargs) {
 
 	DirectorSound *sound = g_director->getSoundManager();
 	Datum castMember = g_lingo->pop();
-	Score *score = g_director->getCurrentScore();
+	Score *score = g_director->getCurrentMovie()->getScore();
 
 	if (!score) {
 		warning("b_puppetSound(): no score");
@@ -1707,7 +1709,7 @@ void LB::b_puppetSound(int nargs) {
 }
 
 void LB::b_puppetSprite(int nargs) {
-	Score *sc = g_director->getCurrentScore();
+	Score *sc = g_director->getCurrentMovie()->getScore();
 	if (!sc) {
 		warning("b_puppetSprite: no score");
 		g_lingo->dropStack(nargs);
@@ -1738,12 +1740,12 @@ void LB::b_puppetSprite(int nargs) {
 
 void LB::b_puppetTempo(int nargs) {
 	// TODO: Check if >D4 permitted tempo higher than 60.
-	g_director->getCurrentScore()->_puppetTempo = MIN(g_lingo->pop().asInt(), 60);
+	g_director->getCurrentMovie()->getScore()->_puppetTempo = MIN(g_lingo->pop().asInt(), 60);
 }
 
 void LB::b_puppetTransition(int nargs) {
 	// puppetTransition whichTransition [, time] [, chunkSize] [, changeArea]
-	Score *score = g_director->getCurrentScore();
+	Score *score = g_director->getCurrentMovie()->getScore();
 	Stage *stage = g_director->getStage();
 	uint16 duration = 250, area = 1, chunkSize = 1, type = 0;
 	if (nargs == 4) {
@@ -1782,7 +1784,7 @@ void LB::b_rollOver(int nargs) {
 	Datum res(0);
 	int arg = d.asInt();
 
-	Score *score = g_director->getCurrentScore();
+	Score *score = g_director->getCurrentMovie()->getScore();
 
 	if (!score) {
 		warning("b_rollOver: Reference to an empty score");
@@ -1840,7 +1842,7 @@ void LB::b_zoomBox(int nargs) {
 	int endSprite = g_lingo->pop().asInt();
 	int startSprite = g_lingo->pop().asInt();
 
-	Score *score = g_director->getCurrentScore();
+	Score *score = g_director->getCurrentMovie()->getScore();
 	uint16 curFrame = score->getCurrentFrame();
 
 	Common::Rect startRect = score->_channels[startSprite]->getBbox();
@@ -1886,14 +1888,16 @@ void LB::b_updateStage(int nargs) {
 		return;
 	}
 
-	Score *score = g_director->getCurrentScore();
+	Movie *movie = g_director->getCurrentMovie();
 
-	if (!score) {
-		warning("b_updateStage: no score");
+	if (!movie) {
+		warning("b_updateStage: no movie");
 
 		return;
 	}
 
+	Score *score = movie->getScore();
+
 	score->renderFrame(score->getCurrentFrame(), kRenderUpdateStageOnly);
 	g_director->processEvents(true);
 
@@ -2181,11 +2185,11 @@ void LB::b_script(int nargs) {
 
 		if (cast->_type == kCastLingoScript) {
 			// script cast can be either a movie script or score script
-			script = g_lingo->getScriptContext(cast->_score->_lingoArchive, kMovieScript, castId);
+			script = g_lingo->getScriptContext(cast->_cast->_lingoArchive, kMovieScript, castId);
 			if (!script)
-				script = g_lingo->getScriptContext(cast->_score->_lingoArchive, kScoreScript, castId);
+				script = g_lingo->getScriptContext(cast->_cast->_lingoArchive, kScoreScript, castId);
 		} else {
-			script = g_lingo->getScriptContext(cast->_score->_lingoArchive, kCastScript, castId);
+			script = g_lingo->getScriptContext(cast->_cast->_lingoArchive, kCastScript, castId);
 		}
 
 		if (script) {
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index ed8918a9d5..dc2d17fdac 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -25,6 +25,7 @@
 #include "common/substream.h"
 
 #include "director/director.h"
+#include "director/cast.h"
 #include "director/castmember.h"
 #include "director/score.h"
 #include "director/util.h"
@@ -887,7 +888,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
 		if (member->_type == kCastLingoScript)
 			scriptType = ((ScriptCastMember *)member)->_scriptType;
 
-		CastMemberInfo *info = member->_score->_castsInfo[castId];
+		CastMemberInfo *info = member->_cast->_castsInfo[castId];
 		if (info)
 			castName = info->name;
 	}
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 5ebc0d7b5a..7a80ba82ec 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -45,6 +45,7 @@
 
 #include "director/director.h"
 #include "director/castmember.h"
+#include "director/movie.h"
 #include "director/score.h"
 #include "director/sprite.h"
 #include "director/util.h"
@@ -817,7 +818,7 @@ void LC::c_intersects() {
 	Datum d2 = g_lingo->pop();
 	Datum d1 = g_lingo->pop();
 
-	Score *score = g_director->getCurrentScore();
+	Score *score = g_director->getCurrentMovie()->getScore();
 	Channel *sprite1 = score->getChannelById(d1.asInt());
 	Channel *sprite2 = score->getChannelById(d2.asInt());
 
@@ -833,7 +834,7 @@ void LC::c_within() {
 	Datum d2 = g_lingo->pop();
 	Datum d1 = g_lingo->pop();
 
-	Score *score = g_director->getCurrentScore();
+	Score *score = g_director->getCurrentMovie()->getScore();
 	Channel *sprite1 = score->getChannelById(d1.asInt());
 	Channel *sprite2 = score->getChannelById(d2.asInt());
 
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index b5d0546320..dc8b7c2464 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -23,6 +23,7 @@
 #include "director/director.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-code.h"
+#include "director/movie.h"
 #include "director/frame.h"
 #include "director/score.h"
 #include "director/sprite.h"
@@ -117,7 +118,7 @@ void Lingo::queueSpriteEvent(LEvent event, int eventId, int spriteId) {
 	 * When more than one movie script [...]
 	 * [D4 docs] */
 
-	Score *score = _vm->getCurrentScore();
+	Score *score = _vm->getCurrentMovie()->getScore();
 	Frame *currentFrame = score->_frames[score->getCurrentFrame()];
 	assert(currentFrame != nullptr);
 	Sprite *sprite = score->getSpriteById(spriteId);
@@ -159,7 +160,7 @@ void Lingo::queueFrameEvent(LEvent event, int eventId) {
 	 * [p.81 of D4 docs]
 	 */
 
-	Score *score = _vm->getCurrentScore();
+	Score *score = _vm->getCurrentMovie()->getScore();
 
 	// if (event == kEventPrepareFrame || event == kEventIdle) {
 	// 	entity = score->getCurrentFrame();
@@ -312,7 +313,7 @@ void Lingo::processEvents() {
 	while (!_eventQueue.empty()) {
 		LingoEvent el = _eventQueue.pop();
 
-		if (_vm->getCurrentScore()->_stopPlay && el.event != kEventStopMovie)
+		if (_vm->getCurrentMovie()->getScore()->_stopPlay && el.event != kEventStopMovie)
 			continue;
 
 		if (lastEventId == el.eventId && !_passEvent)
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 14e49f1e2b..d54819b881 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -30,6 +30,7 @@
 #include "director/director.h"
 #include "director/lingo/lingo.h"
 #include "director/castmember.h"
+#include "director/movie.h"
 #include "director/score.h"
 #include "director/sound.h"
 #include "director/util.h"
@@ -178,7 +179,7 @@ void Lingo::func_mciwait(const Common::String &name) {
 void Lingo::func_goto(Datum &frame, Datum &movie) {
 	_vm->_playbackPaused = false;
 
-	if (!_vm->getCurrentScore())
+	if (!_vm->getCurrentMovie())
 		return;
 
 	if (movie.type != VOID) {
@@ -222,7 +223,7 @@ void Lingo::func_goto(Datum &frame, Datum &movie) {
 		}
 
 		_vm->_nextMovie.movie = cleanedFilename;
-		_vm->getCurrentScore()->_stopPlay = true;
+		_vm->getCurrentMovie()->getScore()->_stopPlay = true;
 
 		_vm->_nextMovie.frameS.clear();
 		_vm->_nextMovie.frameI = -1;
@@ -246,38 +247,38 @@ void Lingo::func_goto(Datum &frame, Datum &movie) {
 	_vm->_skipFrameAdvance = true;
 
 	if (frame.type == STRING) {
-		if (_vm->getCurrentScore())
-			_vm->getCurrentScore()->setStartToLabel(*frame.u.s);
+		if (_vm->getCurrentMovie())
+			_vm->getCurrentMovie()->getScore()->setStartToLabel(*frame.u.s);
 		return;
 	}
 
-	if (_vm->getCurrentScore())
-		_vm->getCurrentScore()->setCurrentFrame(frame.asInt());
+	if (_vm->getCurrentMovie())
+		_vm->getCurrentMovie()->getScore()->setCurrentFrame(frame.asInt());
 }
 
 void Lingo::func_gotoloop() {
-	if (!_vm->getCurrentScore())
+	if (!_vm->getCurrentMovie())
 		return;
 
-	_vm->getCurrentScore()->gotoLoop();
+	_vm->getCurrentMovie()->getScore()->gotoLoop();
 
 	_vm->_skipFrameAdvance = true;
 }
 
 void Lingo::func_gotonext() {
-	if (!_vm->getCurrentScore())
+	if (!_vm->getCurrentMovie())
 		return;
 
-	_vm->getCurrentScore()->gotoNext();
+	_vm->getCurrentMovie()->getScore()->gotoNext();
 
 	_vm->_skipFrameAdvance = true;
 }
 
 void Lingo::func_gotoprevious() {
-	if (!_vm->getCurrentScore())
+	if (!_vm->getCurrentMovie())
 		return;
 
-	_vm->getCurrentScore()->gotoPrevious();
+	_vm->getCurrentMovie()->getScore()->gotoPrevious();
 
 	_vm->_skipFrameAdvance = true;
 }
@@ -315,12 +316,12 @@ void Lingo::func_play(Datum &frame, Datum &movie) {
 		return;
 	}
 
-	if (!_vm->getCurrentScore()) {
-		warning("Lingo::func_play(): no score");
+	if (!_vm->getCurrentMovie()) {
+		warning("Lingo::func_play(): no movie");
 		return;
 	}
 
-	ref.frameI = _vm->getCurrentScore()->getCurrentFrame();
+	ref.frameI = _vm->getCurrentMovie()->getScore()->getCurrentFrame();
 
 	_vm->_movieStack.push_back(ref);
 
@@ -416,17 +417,17 @@ void Lingo::func_beep(int repeats) {
 }
 
 int Lingo::func_marker(int m) 	{
-	if (!_vm->getCurrentScore())
+	if (!_vm->getCurrentMovie())
 		return 0;
 
-	int labelNumber = _vm->getCurrentScore()->getCurrentLabelNumber();
+	int labelNumber = _vm->getCurrentMovie()->getScore()->getCurrentLabelNumber();
 	if (m != 0) {
 		if (m < 0) {
 			for (int marker = 0; marker > m; marker--)
-				labelNumber = _vm->getCurrentScore()->getPreviousLabelNumber(labelNumber);
+				labelNumber = _vm->getCurrentMovie()->getScore()->getPreviousLabelNumber(labelNumber);
 		} else {
 			for (int marker = 0; marker < m; marker++)
-				labelNumber = _vm->getCurrentScore()->getNextLabelNumber(labelNumber);
+				labelNumber = _vm->getCurrentMovie()->getScore()->getNextLabelNumber(labelNumber);
 		}
 	}
 
diff --git a/engines/director/lingo/lingo-patcher.cpp b/engines/director/lingo/lingo-patcher.cpp
index 88362a9b1c..5290f864d8 100644
--- a/engines/director/lingo/lingo-patcher.cpp
+++ b/engines/director/lingo/lingo-patcher.cpp
@@ -21,7 +21,7 @@
  */
 
 #include "director/director.h"
-#include "director/score.h"
+#include "director/movie.h"
 #include "director/lingo/lingo.h"
 
 
@@ -72,11 +72,11 @@ struct ScriptPatch {
 };
 
 Common::String Lingo::patchLingoCode(Common::String &line, ScriptType type, uint16 id, int linenum) {
-	if (!_vm->getCurrentScore())
+	if (!_vm->getCurrentMovie())
 		return line;
 
 	const ScriptPatch *patch = scriptPatches;
-	Common::String movie = _vm->getCurrentPath() + _vm->getCurrentScore()->getMacName();
+	Common::String movie = _vm->getCurrentPath() + _vm->getCurrentMovie()->getMacName();
 
 	// So far, we have not many patches, so do linear lookup
 	while (patch->gameId) {
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 926b17cc56..bc841ece76 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -27,8 +27,10 @@
 #include "graphics/macgui/macbutton.h"
 
 #include "director/director.h"
+#include "director/cast.h"
 #include "director/castmember.h"
 #include "director/frame.h"
+#include "director/movie.h"
 #include "director/sound.h"
 #include "director/sprite.h"
 #include "director/score.h"
@@ -337,8 +339,8 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 
 	Datum d;
 
-	if (!_vm->getCurrentScore()) {
-		warning("Lingo::getTheEntity(): Score is missing");
+	if (!_vm->getCurrentMovie()) {
+		warning("Lingo::getTheEntity(): Movie is missing");
 		d.type = VOID;
 
 		return d;
@@ -350,7 +352,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheClickOn:
 		d.type = INT;
-		d.u.i = _vm->getCurrentScore()->_currentClickOnSpriteId;
+		d.u.i = _vm->getCurrentMovie()->_currentClickOnSpriteId;
 		break;
 	case kTheColorDepth:
 		// bpp. 1, 2, 4, 8, 32
@@ -370,7 +372,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheFrame:
 		d.type = INT;
-		d.u.i = _vm->getCurrentScore()->getCurrentFrame();
+		d.u.i = _vm->getCurrentMovie()->getScore()->getCurrentFrame();
 		break;
 	case kTheKey:
 		d.type = STRING;
@@ -396,23 +398,23 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheLastClick:
 		d.type = INT;
-		d.u.i = _vm->getMacTicks() - _vm->getCurrentScore()->_lastClickTime;
+		d.u.i = _vm->getMacTicks() - _vm->getCurrentMovie()->_lastClickTime;
 		break;
 	case kTheLastEvent:
 		d.type = INT;
-		d.u.i = _vm->getMacTicks() - _vm->getCurrentScore()->_lastEventTime;
+		d.u.i = _vm->getMacTicks() - _vm->getCurrentMovie()->_lastEventTime;
 		break;
 	case kTheLastFrame:
 		d.type = INT;
-		d.u.i = _vm->getCurrentScore()->_frames.size() - 1;
+		d.u.i = _vm->getCurrentMovie()->getScore()->_frames.size() - 1;
 		break;
 	case kTheLastKey:
 		d.type = INT;
-		d.u.i = _vm->getMacTicks() - _vm->getCurrentScore()->_lastKeyTime;
+		d.u.i = _vm->getMacTicks() - _vm->getCurrentMovie()->_lastKeyTime;
 		break;
 	case kTheLastRoll:
 		d.type = INT;
-		d.u.i = _vm->getMacTicks() - _vm->getCurrentScore()->_lastRollTime;
+		d.u.i = _vm->getMacTicks() - _vm->getCurrentMovie()->_lastRollTime;
 		break;
 	case kTheMachineType:
 		// 1 - Macintosh 512Ke			D2
@@ -460,7 +462,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 	case kTheMovie:
 	case kTheMovieName:
 		d.type = STRING;
-		d.u.s = new Common::String(_vm->getCurrentScore()->getMacName());
+		d.u.s = new Common::String(_vm->getCurrentMovie()->getMacName());
 		break;
 	case kTheMoviePath:
 	case kThePathName:
@@ -470,7 +472,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 	case kTheMouseCast:
 		{
 			Common::Point pos = g_system->getEventManager()->getMousePos();
-			Score *sc = _vm->getCurrentScore();
+			Score *sc = _vm->getCurrentMovie()->getScore();
 			uint16 spriteId = sc->getSpriteIDFromPos(pos);
 			d.type = INT;
 			d.u.i = sc->getSpriteById(spriteId)->_castId;
@@ -548,19 +550,19 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheStageBottom:
 		d.type = INT;
-		d.u.i = _vm->getCurrentScore()->_movieRect.bottom;
+		d.u.i = _vm->getCurrentMovie()->_movieRect.bottom;
 		break;
 	case kTheStageLeft:
 		d.type = INT;
-		d.u.i = _vm->getCurrentScore()->_movieRect.left;
+		d.u.i = _vm->getCurrentMovie()->_movieRect.left;
 		break;
 	case kTheStageRight:
 		d.type = INT;
-		d.u.i = _vm->getCurrentScore()->_movieRect.right;
+		d.u.i = _vm->getCurrentMovie()->_movieRect.right;
 		break;
 	case kTheStageTop:
 		d.type = INT;
-		d.u.i = _vm->getCurrentScore()->_movieRect.top;
+		d.u.i = _vm->getCurrentMovie()->_movieRect.top;
 		break;
 	case kTheStillDown:
 		d.type = INT;
@@ -571,7 +573,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheTimer:
 		d.type = INT;
-		d.u.i = _vm->getMacTicks() - _vm->getCurrentScore()->_lastTimerReset;
+		d.u.i = _vm->getMacTicks() - _vm->getCurrentMovie()->_lastTimerReset;
 		break;
 	case kTheTimeoutScript:
 		d.type = STRING;
@@ -678,7 +680,7 @@ void Lingo::setTheMenuItemEntity(int entity, Datum &menuId, int field, Datum &me
 Datum Lingo::getTheSprite(Datum &id1, int field) {
 	Datum d;
 	int id = 0;
-	Score *score = _vm->getCurrentScore();
+	Score *score = _vm->getCurrentMovie()->getScore();
 
 	if (!score) {
 		warning("Lingo::getTheSprite(): The sprite %d field \"%s\" setting over non-active score", id, field2str(field));
@@ -801,7 +803,7 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
 
 void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 	int id = 0;
-	Score *score = _vm->getCurrentScore();
+	Score *score = _vm->getCurrentMovie()->getScore();
 
 	if (!score) {
 		warning("Lingo::setTheSprite(): The sprite %d field \"%s\" setting over non-active score", id, field2str(field));
@@ -946,12 +948,12 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 	Datum d;
 	int id = g_lingo->castIdFetch(id1);
 
-	Score *score = _vm->getCurrentScore();
+	Cast *cast = _vm->getCurrentMovie()->getCast();
 	// Setting default type
 	d.type = INT;
 
-	if (!score) {
-		warning("Lingo::getTheCast(): No score loaded");
+	if (!cast) {
+		warning("Lingo::getTheCast(): No cast loaded");
 		return d;
 	}
 
@@ -972,10 +974,10 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 
 	CastType castType = member->_type;
 	CastMemberInfo *castInfo = nullptr;
-	if (score->_castsInfo.contains(id)) {
-		castInfo = score->_castsInfo.getVal(id);
+	if (cast->_castsInfo.contains(id)) {
+		castInfo = cast->_castsInfo.getVal(id);
 	} else {
-		Score *shared = _vm->getSharedScore();
+		Cast *shared = _vm->getSharedCast();
 		if (shared && shared->_castsInfo.contains(id)) {
 			castInfo = shared->_castsInfo.getVal(id);
 		} else {
@@ -998,7 +1000,7 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 		member->getColors(&d.u.i, nullptr);
 		break;
 	case kTheHeight:
-		d.u.i = score->getCastMemberInitialRect(id).height();
+		d.u.i = cast->getCastMemberInitialRect(id).height();
 		break;
 	case kTheLoaded:
 		d.u.i = 1; //Not loaded handled above
@@ -1025,7 +1027,7 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 		}
 		break;
 	case kTheWidth:
-		d.u.i = score->getCastMemberInitialRect(id).width();
+		d.u.i = cast->getCastMemberInitialRect(id).width();
 		break;
 	case kTheNumber:
 		d.u.i = id;
@@ -1041,10 +1043,10 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 
 void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
 	int id = 0;
-	Score *score = _vm->getCurrentScore();
+	Cast *cast = _vm->getCurrentMovie()->getCast();
 
-	if (!score) {
-		warning("Lingo::setTheCast(): The cast %d field \"%s\" setting over non-active score", id, field2str(field));
+	if (!cast) {
+		warning("Lingo::setTheCast(): The cast %d field \"%s\" setting over non-active cast", id, field2str(field));
 		return;
 	}
 
@@ -1063,7 +1065,9 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
 		return;
 	}
 	CastType castType = member->_type;
-	CastMemberInfo *castInfo = score->_castsInfo[id];
+	CastMemberInfo *castInfo = cast->_castsInfo[id];
+
+	// FIXME: Properly handle shared cast
 
 	switch (field) {
 	case kTheBackColor: {
@@ -1090,8 +1094,8 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
 		break;
 	}
 	case kTheHeight:
-		score->getCastMemberInitialRect(id).setHeight(d.asInt());
-		score->setCastMemberModified(id);
+		cast->getCastMemberInitialRect(id).setHeight(d.asInt());
+		cast->setCastMemberModified(id);
 		break;
 	case kTheHilite:
 		// TODO: Understand how texts can be selected programmatically as well.
@@ -1135,8 +1139,8 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
 		}
 		break;
 	case kTheWidth:
-		score->getCastMemberInitialRect(id).setWidth(d.asInt());
-		score->setCastMemberModified(id);
+		cast->getCastMemberInitialRect(id).setWidth(d.asInt());
+		cast->setCastMemberModified(id);
 		break;
 	default:
 		warning("Lingo::setTheCast(): Unprocessed setting field \"%s\" of cast %d", field2str(field), id);
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index cd80d7255c..9fc0bd16b0 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -28,8 +28,10 @@
 #include "director/director.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-code.h"
+#include "director/cast.h"
 #include "director/castmember.h"
 #include "director/frame.h"
+#include "director/movie.h"
 #include "director/score.h"
 #include "director/sprite.h"
 #include "director/util.h"
@@ -582,7 +584,7 @@ void Lingo::execute(uint pc) {
 
 		if (++counter > 1000 && debugChannelSet(-1, kDebugFewFramesOnly)) {
 			warning("Lingo::execute(): Stopping due to debug few frames only");
-			_vm->getCurrentScore()->_stopPlay = true;
+			_vm->getCurrentMovie()->getScore()->_stopPlay = true;
 			break;
 		}
 	}
@@ -1067,8 +1069,8 @@ void Lingo::runTests() {
 }
 
 void Lingo::executeImmediateScripts(Frame *frame) {
-	for (uint16 i = 0; i <= _vm->getCurrentScore()->_numChannelsDisplayed; i++) {
-		if (_vm->getCurrentScore()->_immediateActions.contains(frame->_sprites[i]->_scriptId)) {
+	for (uint16 i = 0; i <= _vm->getCurrentMovie()->getScore()->_numChannelsDisplayed; i++) {
+		if (_vm->getCurrentMovie()->getScore()->_immediateActions.contains(frame->_sprites[i]->_scriptId)) {
 			// From D5 only explicit event handlers are processed
 			// Before that you could specify commands which will be executed on mouse up
 			if (_vm->getVersion() < 5)
@@ -1119,16 +1121,18 @@ void Lingo::printAllVars() {
 }
 
 int Lingo::castIdFetch(Datum &var) {
-	Score *score = _vm->getCurrentScore();
-	if (!score) {
-		warning("castIdFetch: Score is empty");
+	Movie *movie = _vm->getCurrentMovie();
+	if (!movie) {
+		warning("castIdFetch: No movie");
 		return 0;
 	}
 
+	Cast *cast = movie->getCast();
+
 	int id = 0;
 	if (var.type == STRING) {
-		if (score->_castsNames.contains(*var.u.s))
-			id = score->_castsNames[*var.u.s];
+		if (cast->_castsNames.contains(*var.u.s))
+			id = cast->_castsNames[*var.u.s];
 		else
 			warning("castIdFetch: reference to non-existent cast member: %s", var.u.s->c_str());
 	} else if (var.type == INT || var.type == FLOAT) {
@@ -1182,9 +1186,9 @@ void Lingo::varAssign(Datum &var, Datum &value, bool global, DatumHash *localvar
 
 		*d = value;
 	} else if (var.type == FIELDREF) {
-		Score *score = g_director->getCurrentScore();
-		if (!score) {
-			warning("varAssign: Assigning to a reference to an empty score");
+		Movie *movie = g_director->getCurrentMovie();
+		if (!movie) {
+			warning("varAssign: Assigning to a reference to an empty movie");
 			return;
 		}
 		int referenceId = var.u.i;
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 0e0b15aaf9..763d1a962e 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/director
 
 MODULE_OBJS = \
 	archive.o \
+	cast.o \
 	castmember.o \
 	detection.o \
 	director.o \
@@ -9,9 +10,9 @@ MODULE_OBJS = \
 	frame.o \
 	graphics.o \
 	images.o \
+	movie.o \
 	resource.o \
 	stage.o \
-	score-loading.o \
 	score.o \
 	sound.o \
 	sprite.o \
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
new file mode 100644
index 0000000000..41c23397f9
--- /dev/null
+++ b/engines/director/movie.cpp
@@ -0,0 +1,198 @@
+/* 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 "common/config-manager.h"
+#include "common/substream.h"
+
+#include "director/director.h"
+#include "director/archive.h"
+#include "director/cast.h"
+#include "director/lingo/lingo.h"
+#include "director/movie.h"
+#include "director/score.h"
+#include "director/util.h"
+
+namespace Director {
+
+Movie::Movie(DirectorEngine *vm) {
+	_vm = vm;
+	_lingo = _vm->getLingo();
+
+	_flags = 0;
+
+	_currentMouseDownSpriteId = 0;
+	_currentClickOnSpriteId = 0;
+	_lastEventTime = _vm->getMacTicks();
+	_lastKeyTime = _lastEventTime;
+	_lastClickTime = _lastEventTime;
+	_lastRollTime = _lastEventTime;
+	_lastTimerReset = _lastEventTime;
+
+	_movieArchive = nullptr;
+
+	_cast = new Cast(_vm, this);
+	_score = new Score(_vm, this);
+}
+
+Movie::~Movie() {
+	// _movieArchive is shared with the cast, so the cast will free it
+	delete _cast;
+	delete _score;
+}
+
+void Movie::setArchive(Archive *archive) {
+	_movieArchive = archive;
+
+	if (archive->hasResource(MKTAG('M', 'C', 'N', 'M'), 0)) {
+		_macName = archive->getName(MKTAG('M', 'C', 'N', 'M'), 0).c_str();
+	} else {
+		_macName = archive->getFileName();
+	}
+
+	_cast->setArchive(archive);
+
+	// Frame Labels
+	if (archive->hasResource(MKTAG('V', 'W', 'L', 'B'), -1)) {
+		Common::SeekableSubReadStreamEndian *r;
+		_score->loadLabels(*(r = archive->getFirstResource(MKTAG('V', 'W', 'L', 'B'))));
+		delete r;
+	}
+}
+
+bool Movie::loadArchive() {
+	Common::SeekableSubReadStreamEndian *r = nullptr;
+
+	// File Info
+	if (_movieArchive->hasResource(MKTAG('V', 'W', 'F', 'I'), -1)) {
+		loadFileInfo(*(r = _movieArchive->getFirstResource(MKTAG('V', 'W', 'F', 'I'))));
+		delete r;
+	}
+
+	// Cast
+	_cast->loadArchive();
+
+	// _movieRect and _stageColor are in VWCF, which the cast handles
+
+	Stage *stage = g_director->getStage();
+
+	// If the stage dimensions are different, delete it and start again.
+	// Otherwise, do not clear it so there can be a nice transition.
+	if (stage->getSurface()->w != _movieRect.width() || stage->getSurface()->h != _movieRect.height()) {
+		stage->resize(_movieRect.width(), _movieRect.height());
+	}
+
+	stage->setStageColor(_stageColor);
+
+	// Score
+	if (!_movieArchive->hasResource(MKTAG('V', 'W', 'S', 'C'), -1)) {
+		warning("Score::loadArchive(): Wrong movie format. VWSC resource missing");
+		return false;
+	}
+	_score->loadFrames(*(r = _movieArchive->getFirstResource(MKTAG('V', 'W', 'S', 'C'))));
+	delete r;
+
+	// Action list
+	if (_movieArchive->hasResource(MKTAG('V', 'W', 'A', 'C'), -1)) {
+		_score->loadActions(*(r = _movieArchive->getFirstResource(MKTAG('V', 'W', 'A', 'C'))));
+		delete r;
+	}
+
+	_score->setSpriteCasts();
+
+	return true;
+}
+
+Common::Rect Movie::readRect(Common::ReadStreamEndian &stream) {
+	Common::Rect rect;
+	rect.top = stream.readUint16();
+	rect.left = stream.readUint16();
+	rect.bottom = stream.readUint16();
+	rect.right = stream.readUint16();
+
+	return rect;
+}
+
+Common::Array<Common::String> Movie::loadStrings(Common::SeekableSubReadStreamEndian &stream, uint32 &entryType, bool hasHeader) {
+	Common::Array<Common::String> strings;
+	uint32 offset = 0;
+
+	if (hasHeader) {
+		offset = stream.readUint32();
+		/*uint32 unk1 = */ stream.readUint32();
+		/*uint32 unk2 = */ stream.readUint32();
+		entryType = stream.readUint32();
+		stream.seek(offset);
+	}
+
+	uint16 count = stream.readUint16() + 1;
+
+	debugC(3, kDebugLoading, "Score::loadStrings(): Strings: %d entries", count);
+
+	uint32 *entries = (uint32 *)calloc(count, sizeof(uint32));
+
+	for (uint i = 0; i < count; i++)
+		entries[i] = stream.readUint32();
+
+	byte *data = (byte *)malloc(entries[count - 1]);
+	stream.read(data, entries[count - 1]);
+
+	for (uint16 i = 0; i < count - 1; i++) {
+		Common::String entryString;
+
+		uint start = i == 1 ? entries[i] + 1 : entries[i]; // Skip first byte which is string length
+
+		for (uint j = start; j < entries[i + 1]; j++)
+			if (data[j] == '\r')
+				entryString += '\n';
+			else if (data[j] >= 0x20)
+				entryString += data[j];
+
+		strings.push_back(entryString);
+
+		debugC(6, kDebugLoading, "String %d:\n%s\n", i, Common::toPrintable(entryString).c_str());
+	}
+
+	free(data);
+	free(entries);
+
+	return strings;
+}
+
+void Movie::loadFileInfo(Common::SeekableSubReadStreamEndian &stream) {
+	debugC(2, kDebugLoading, "****** Loading FileInfo VWFI");
+
+	Common::Array<Common::String> fileInfoStrings = Movie::loadStrings(stream, _flags);
+	_script = fileInfoStrings[0];
+
+	if (!_script.empty() && ConfMan.getBool("dump_scripts"))
+		_cast->dumpScript(_script.c_str(), kMovieScript, _cast->_movieScriptCount);
+
+	if (!_script.empty())
+		_lingo->addCode(_script.c_str(), _cast->_lingoArchive, kMovieScript, _cast->_movieScriptCount);
+
+	_cast->_movieScriptCount++;
+	_changedBy = fileInfoStrings[1];
+	_createdBy = fileInfoStrings[2];
+	_directory = fileInfoStrings[3];
+}
+
+} // End of namespace Director
diff --git a/engines/director/movie.h b/engines/director/movie.h
new file mode 100644
index 0000000000..76e550c20b
--- /dev/null
+++ b/engines/director/movie.h
@@ -0,0 +1,91 @@
+/* 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 DIRECTOR_MOVIE_H
+#define DIRECTOR_MOVIE_H
+
+#include "common/hash-str.h"
+#include "common/rect.h"
+#include "director/types.h"
+
+namespace Common {
+	class ReadStreamEndian;
+	class SeekableSubReadStreamEndian;
+}
+
+namespace Director {
+
+class Archive;
+class Cast;
+struct CastMemberInfo;
+class CastMember;
+class DirectorEngine;
+class Lingo;
+
+class Movie {
+public:
+	Movie(DirectorEngine *vm);
+	~Movie();
+
+	static Common::Rect readRect(Common::ReadStreamEndian &stream);
+	static Common::Array<Common::String> loadStrings(Common::SeekableSubReadStreamEndian &stream, uint32 &entryType, bool hasHeader = true);
+
+	bool loadArchive();
+	void setArchive(Archive *archive);
+	Archive *getArchive() const { return _movieArchive; };
+	Common::String getMacName() const { return _macName; }
+	Cast *getCast() { return _cast; }
+	Score *getScore() { return _score; }
+
+private:
+	void loadFileInfo(Common::SeekableSubReadStreamEndian &stream);
+
+public:
+	Archive *_movieArchive;
+	Common::Rect _movieRect;
+	uint16 _currentMouseDownSpriteId;
+	uint16 _currentClickOnSpriteId;
+	uint32 _lastEventTime;
+	uint32 _lastRollTime;
+	uint32 _lastClickTime;
+	uint32 _lastKeyTime;
+	uint32 _lastTimerReset;
+	uint16 _stageColor;
+
+private:
+	DirectorEngine *_vm;
+	Lingo *_lingo;
+	Cast *_cast;
+	Score *_score;
+
+	uint32 _flags;
+
+	Common::String _macName;
+	Common::String _createdBy;
+	Common::String _changedBy;
+	Common::String _script;
+	Common::String _directory;
+};
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 6d8ab01325..9ebfeed7d0 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -30,7 +30,9 @@
 
 #include "director/director.h"
 #include "director/archive.h"
+#include "director/cast.h"
 #include "director/castmember.h"
+#include "director/movie.h"
 #include "director/score.h"
 #include "director/util.h"
 #include "director/lingo/lingo.h"
@@ -270,19 +272,19 @@ void DirectorEngine::loadMac(const Common::String movie) {
 
 		if (!_mainArchive->openStream(dataFork, startOffset)) {
 			warning("Failed to load RIFX from Mac binary");
-			delete _currentScore;
-			_currentScore = nullptr;
+			delete _currentMovie;
+			_currentMovie = nullptr;
 		}
 	}
 }
 
 void DirectorEngine::clearSharedCast() {
-	if (!_sharedScore)
+	if (!_sharedCast)
 		return;
 
-	delete _sharedScore;
+	delete _sharedCast;
 
-	_sharedScore = nullptr;
+	_sharedCast = nullptr;
 }
 
 void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
@@ -303,29 +305,29 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
 	debug(0, "@@@@ Loading Shared cast '%s'", filename.c_str());
 	debug(0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
 
-	_sharedScore = new Score(this);
-	_sharedScore->setArchive(sharedCast);
-	_sharedScore->loadArchive(true);
+	_sharedCast = new Cast(this);
+	_sharedCast->setArchive(sharedCast);
+	_sharedCast->loadArchive();
 }
 
 CastMember *DirectorEngine::getCastMember(int castId) {
 	CastMember *result = nullptr;
-	if (_currentScore) {
-		result = _currentScore->getCastMember(castId);
+	if (_currentMovie) {
+		result = _currentMovie->getCast()->getCastMember(castId);
 	}
-	if (result == nullptr && _sharedScore) {
-		result = _sharedScore->getCastMember(castId);
+	if (result == nullptr && _sharedCast) {
+		result = _sharedCast->getCastMember(castId);
 	}
 	return result;
 }
 
 const Stxt *DirectorEngine::getStxt(int castId) {
 	const Stxt *result = nullptr;
-	if (_currentScore) {
-		result = _currentScore->getStxt(castId);
+	if (_currentMovie) {
+		result = _currentMovie->getCast()->getStxt(castId);
 	}
-	if (result == nullptr && _sharedScore) {
-		result = _sharedScore->getStxt(castId);
+	if (result == nullptr && _sharedCast) {
+		result = _sharedCast->getStxt(castId);
 	}
 	return result;
 }
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index d26d988c11..c7c0144178 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -22,6 +22,8 @@
 
 #include "common/config-manager.h"
 #include "common/file.h"
+#include "common/memstream.h"
+#include "common/substream.h"
 #include "common/system.h"
 
 #include "engines/util.h"
@@ -35,12 +37,13 @@
 #endif
 
 #include "director/director.h"
+#include "director/cast.h"
 #include "director/castmember.h"
 #include "director/score.h"
 #include "director/frame.h"
+#include "director/movie.h"
 #include "director/sound.h"
 #include "director/sprite.h"
-#include "director/stxt.h"
 #include "director/util.h"
 #include "director/lingo/lingo.h"
 
@@ -122,11 +125,12 @@ void Channel::setClean(Sprite *nextSprite, int spriteId) {
 }
 
 void Channel::addDelta(Common::Point pos) {
-	if (_constraint > g_director->getCurrentScore()->_channels.size() - 1) {
+	// TODO: Channel should have a pointer to its score
+	if (_constraint > g_director->getCurrentMovie()->getScore()->_channels.size() - 1) {
 		warning("Channel::addDelta: Received out-of-bounds constraint: %d", _constraint);
 		_constraint = 0;
 	} else if (_sprite->_moveable && _constraint > 0) {
-		Common::Rect constraintBbox = g_director->getCurrentScore()->_channels[_constraint]->getBbox();
+		Common::Rect constraintBbox = g_director->getCurrentMovie()->getScore()->_channels[_constraint]->getBbox();
 
 		Common::Rect currentBbox = getBbox();
 		currentBbox.translate(pos.x, pos.y);
@@ -209,45 +213,23 @@ MacShape *Channel::getShape() {
 	return shape;
 }
 
-Score::Score(DirectorEngine *vm) {
+Score::Score(DirectorEngine *vm, Movie *movie) {
 	_vm = vm;
 	_lingo = _vm->getLingo();
-	_lingoArchive = kArchMain;
+	_movie = movie;
+
 	_soundManager = _vm->getSoundManager();
-	_currentMouseDownSpriteId = 0;
-	_currentClickOnSpriteId = 0;
-	_lastEventTime = _vm->getMacTicks();
-	_lastKeyTime = _lastEventTime;
-	_lastClickTime = _lastEventTime;
-	_lastRollTime = _lastEventTime;
-	_lastTimerReset = _lastEventTime;
 	_puppetTempo = 0x00;
 
-	// FIXME: TODO: Check whether the original truely does it
-	if (_vm->getVersion() <= 3) {
-		_lingo->executeScript(kMovieScript, 0);
-	}
-	_movieScriptCount = 0;
 	_labels = nullptr;
-	_font = nullptr;
 
-	_versionMinor = _versionMajor = 0;
 	_currentFrameRate = 20;
-	_castArrayStart = _castArrayEnd = 0;
 	_currentFrame = 0;
 	_nextFrame = 0;
 	_currentLabel = 0;
 	_nextFrameTime = 0;
-	_flags = 0;
 	_stopPlay = false;
 
-	_castIDoffset = 0;
-
-	_movieArchive = nullptr;
-
-	_loadedStxts = nullptr;
-	_loadedCast = nullptr;
-
 	_numChannelsDisplayed = 0;
 
 	_framesRan = 0; // used by kDebugFewFramesOnly and kDebugScreenshot
@@ -260,50 +242,11 @@ Score::~Score() {
 	for (uint i = 0; i < _channels.size(); i++)
 		delete _channels[i];
 
-	if (_loadedStxts)
-		for (Common::HashMap<int, const Stxt *>::iterator it = _loadedStxts->begin(); it != _loadedStxts->end(); ++it)
-			delete it->_value;
-
-	if (_movieArchive) {
-		_movieArchive->close();
-		delete _movieArchive;
-		_movieArchive = nullptr;
-	}
-
-	if (_loadedCast)
-		for (Common::HashMap<int, CastMember *>::iterator it = _loadedCast->begin(); it != _loadedCast->end(); ++it)
-			delete it->_value;
-
 	if (_labels)
 		for (Common::SortedArray<Label *>::iterator it = _labels->begin(); it != _labels->end(); ++it)
 			delete *it;
 
-	delete _font;
 	delete _labels;
-	delete _loadedStxts;
-	delete _loadedCast;
-}
-
-Common::Rect Score::getCastMemberInitialRect(int castId) {
-	CastMember *cast = _loadedCast->getVal(castId);
-
-	if (!cast) {
-		warning("Score::getCastMemberInitialRect(%d): empty cast", castId);
-		return Common::Rect(0, 0);
-	}
-
-	return cast->_initialRect;
-}
-
-void Score::setCastMemberModified(int castId) {
-	CastMember *cast = _loadedCast->getVal(castId);
-
-	if (!cast) {
-		warning("Score::setCastMemberModified(%d): empty cast", castId);
-		return;
-	}
-
-	cast->_modified = 1;
 }
 
 bool Score::processImmediateFrameScript(Common::String s, int id) {
@@ -418,34 +361,10 @@ int Score::getPreviousLabelNumber(int referenceFrame) {
 	return 0;
 }
 
-Common::String Score::getString(Common::String str) {
-	if (str.size() == 0) {
-		return str;
-	}
-
-	uint8 f = static_cast<uint8>(str.firstChar());
-
-	if (f == 0) {
-		return "";
-	}
-
-	//TODO: check if all versions need to cut off the first character.
-	if (_vm->getVersion() > 3) {
-		str.deleteChar(0);
-	}
-
-	if (str.lastChar() == '\x00') {
-		str.deleteLastChar();
-	}
-
-	return str;
-}
-
 void Score::startLoop() {
-
-	debugC(1, kDebugImages, "Score dims: %dx%d", _movieRect.width(), _movieRect.height());
-
-	initGraphics(_movieRect.width(), _movieRect.height());
+	// TODO: Should the dims be set by the movie?
+	debugC(1, kDebugImages, "Score dims: %dx%d", _movie->_movieRect.width(), _movie->_movieRect.height());
+	initGraphics(_movie->_movieRect.width(), _movie->_movieRect.height());
 
 	_currentFrame = 0;
 	_stopPlay = false;
@@ -663,7 +582,7 @@ void Score::screenShot() {
 	Graphics::Surface *newSurface = rawSurface.convertTo(requiredFormat_4byte, _vm->getPalette());
 	Common::String currentPath = _vm->getCurrentPath().c_str();
 	Common::replace(currentPath, "/", "-"); // exclude '/' from screenshot filename prefix
-	Common::String prefix = Common::String::format("%s%s", currentPath.c_str(), _macName.c_str());
+	Common::String prefix = Common::String::format("%s%s", currentPath.c_str(), _movie->getMacName().c_str());
 	Common::String filename = dumpScriptName(prefix.c_str(), kMovieScript, _framesRan, "png");
 
 	Common::DumpFile screenshotFile;
@@ -678,24 +597,6 @@ void Score::screenShot() {
 	newSurface->free();
 }
 
-CastMember *Score::getCastMember(int castId) {
-	CastMember *result = nullptr;
-
-	if (_loadedCast && _loadedCast->contains(castId)) {
-		result = _loadedCast->getVal(castId);
-	}
-	return result;
-}
-
-const Stxt *Score::getStxt(int castId) {
-	const Stxt *result = nullptr;
-
-	if (_loadedStxts->contains(castId)) {
-		result = _loadedStxts->getVal(castId);
-	}
-	return result;
-}
-
 uint16 Score::getSpriteIDFromPos(Common::Point pos, bool onlyActive) {
 	for (int i = _channels.size() - 1; i >= 0; i--)
 		if (_channels[i]->getBbox().contains(pos) && (!onlyActive || _channels[i]->_sprite->isActive()))
@@ -750,4 +651,257 @@ void Score::playSoundChannel(uint16 frameId) {
 	sound->playCastMember(frame->_sound2, 2, false);
 }
 
+void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) {
+	debugC(1, kDebugLoading, "****** Loading frames VWSC");
+
+	//stream.hexdump(stream.size());
+
+	uint32 size = stream.readUint32();
+	size -= 4;
+
+	if (_vm->getVersion() < 4) {
+		_numChannelsDisplayed = 30;
+	} else if (_vm->getVersion() == 4) {
+		uint32 frame1Offset = stream.readUint32();
+		uint32 numFrames = stream.readUint32();
+		uint16 version = stream.readUint16();
+		uint16 spriteRecordSize = stream.readUint16();
+		uint16 numChannels = stream.readUint16();
+		size -= 14;
+
+		if (version > 13) {
+			_numChannelsDisplayed = stream.readUint16();
+		} else {
+			if (version <= 7)	// Director5
+				_numChannelsDisplayed = 48;
+			else
+				_numChannelsDisplayed = 120;	// D6
+
+			stream.readUint16(); // Skip
+		}
+
+		size -= 2;
+
+		warning("STUB: Score::loadFrames. frame1Offset: %x numFrames: %x version: %x spriteRecordSize: %x numChannels: %x numChannelsDisplayed: %x",
+			frame1Offset, numFrames, version, spriteRecordSize, numChannels, _numChannelsDisplayed);
+		// Unknown, some bytes - constant (refer to contuinity).
+	} else if (_vm->getVersion() > 4) {
+		//what data is up the top of D5 VWSC?
+		uint32 unk1 = stream.readUint32();
+		uint32 unk2 = stream.readUint32();
+
+		uint16 unk3, unk4, unk5, unk6;
+
+		if (unk2 > 0) {
+			uint32 blockSize = stream.readUint32() - 1;
+			stream.readUint32();
+			stream.readUint32();
+			stream.readUint32();
+			stream.readUint32();
+			for (uint32 skip = 0; skip < blockSize * 4; skip++)
+				stream.readByte();
+
+			//header number two... this is our actual score entry point.
+			unk1 = stream.readUint32();
+			unk2 = stream.readUint32();
+			stream.readUint32();
+			unk3 = stream.readUint16();
+			unk4 = stream.readUint16();
+			unk5 = stream.readUint16();
+			unk6 = stream.readUint16();
+		} else {
+			unk3 = stream.readUint16();
+			unk4 = stream.readUint16();
+			unk5 = stream.readUint16();
+			unk6 = stream.readUint16();
+			size -= 16;
+		}
+		warning("STUB: Score::loadFrames. unk1: %x unk2: %x unk3: %x unk4: %x unk5: %x unk6: %x", unk1, unk2, unk3, unk4, unk5, unk6);
+	}
+
+	uint16 channelSize;
+	uint16 channelOffset;
+
+	Frame *initial = new Frame(_vm, _numChannelsDisplayed);
+	// Push a frame at frame#0 position.
+	// This makes all indexing simpler
+	_frames.push_back(initial);
+
+	// This is a representation of the channelData. It gets overridden
+	// partically by channels, hence we keep it and read the score from left to right
+	//
+	// TODO Merge it with shared cast
+	byte channelData[kChannelDataSize];
+	memset(channelData, 0, kChannelDataSize);
+
+	while (size != 0 && !stream.eos()) {
+		uint16 frameSize = stream.readUint16();
+		debugC(8, kDebugLoading, "++++++++++ score frame %d (frameSize %d) size %d", _frames.size(), frameSize, size);
+
+		if (frameSize > 0) {
+			Frame *frame = new Frame(_vm, _numChannelsDisplayed);
+			size -= frameSize;
+			frameSize -= 2;
+
+			while (frameSize != 0) {
+
+				if (_vm->getVersion() < 4) {
+					channelSize = stream.readByte() * 2;
+					channelOffset = stream.readByte() * 2;
+					frameSize -= channelSize + 2;
+				} else {
+					channelSize = stream.readUint16();
+					channelOffset = stream.readUint16();
+					frameSize -= channelSize + 4;
+				}
+
+				assert(channelOffset + channelSize < kChannelDataSize);
+				stream.read(&channelData[channelOffset], channelSize);
+			}
+
+			Common::MemoryReadStreamEndian *str = new Common::MemoryReadStreamEndian(channelData, ARRAYSIZE(channelData), stream.isBE());
+			// str->hexdump(str->size(), 32);
+			frame->readChannels(str);
+			delete str;
+
+			debugC(8, kDebugLoading, "Score::loadFrames(): Frame %d actionId: %d", _frames.size(), frame->_actionId);
+
+			_frames.push_back(frame);
+		} else {
+			warning("zero sized frame!? exiting loop until we know what to do with the tags that follow.");
+			size = 0;
+		}
+	}
+}
+
+void Score::setSpriteCasts() {
+	// Update sprite cache of cast pointers/info
+	for (uint16 i = 0; i < _frames.size(); i++) {
+		for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
+			_frames[i]->_sprites[j]->setCast(_frames[i]->_sprites[j]->_castId);
+
+			debugC(1, kDebugImages, "Score::setSpriteCasts(): Frame: %d Channel: %d castId: %d type: %d", i, j, _frames[i]->_sprites[j]->_castId, _frames[i]->_sprites[j]->_spriteType);
+		}
+	}
+}
+
+void Score::loadLabels(Common::SeekableSubReadStreamEndian &stream) {
+	if (debugChannelSet(5, kDebugLoading)) {
+		debug("Score::loadLabels()");
+		stream.hexdump(stream.size());
+	}
+
+	_labels = new Common::SortedArray<Label *>(compareLabels);
+	uint16 count = stream.readUint16() + 1;
+	uint32 offset = count * 4 + 2;
+
+	uint16 frame = stream.readUint16();
+	uint32 stringPos = stream.readUint16() + offset;
+
+	for (uint16 i = 1; i < count; i++) {
+		uint16 nextFrame = stream.readUint16();
+		uint32 nextStringPos = stream.readUint16() + offset;
+		uint32 streamPos = stream.pos();
+
+		stream.seek(stringPos);
+		Common::String label;
+
+		for (uint32 j = stringPos; j < nextStringPos; j++) {
+			label += stream.readByte();
+		}
+
+		_labels->insert(new Label(label, frame));
+		stream.seek(streamPos);
+
+		frame = nextFrame;
+		stringPos = nextStringPos;
+	}
+
+	Common::SortedArray<Label *>::iterator j;
+
+	debugC(2, kDebugLoading, "****** Loading labels");
+	for (j = _labels->begin(); j != _labels->end(); ++j) {
+		debugC(2, kDebugLoading, "Frame %d, Label '%s'", (*j)->number, Common::toPrintable((*j)->name).c_str());
+	}
+}
+
+int Score::compareLabels(const void *a, const void *b) {
+	return ((const Label *)a)->number - ((const Label *)b)->number;
+}
+
+void Score::loadActions(Common::SeekableSubReadStreamEndian &stream) {
+	debugC(2, kDebugLoading, "****** Loading Actions VWAC");
+
+	uint16 count = stream.readUint16() + 1;
+	uint32 offset = count * 4 + 2;
+
+	byte id = stream.readByte();
+
+	byte subId = stream.readByte(); // I couldn't find how it used in continuity (except print). Frame actionId = 1 byte.
+	uint32 stringPos = stream.readUint16() + offset;
+
+	for (uint16 i = 0; i < count; i++) {
+		uint16 nextId = stream.readByte();
+		byte nextSubId = stream.readByte();
+		uint32 nextStringPos = stream.readUint16() + offset;
+		uint32 streamPos = stream.pos();
+
+		stream.seek(stringPos);
+
+		for (uint16 j = stringPos; j < nextStringPos; j++) {
+			byte ch = stream.readByte();
+			if (ch == 0x0d) {
+				ch = '\n';
+			}
+			_actions[i + 1] += ch;
+		}
+
+		debugC(3, kDebugLoading, "Action id: %d nextId: %d subId: %d, code: %s", id, nextId, subId, _actions[id].c_str());
+
+		stream.seek(streamPos);
+
+		id = nextId;
+		subId = nextSubId;
+		stringPos = nextStringPos;
+
+		if ((int32)stringPos == stream.size())
+			break;
+	}
+
+	bool *scriptRefs = (bool *)calloc(_actions.size() + 1, sizeof(int));
+
+	// Now let's scan which scripts are actually referenced
+	for (uint i = 0; i < _frames.size(); i++) {
+		if (_frames[i]->_actionId <= _actions.size())
+			scriptRefs[_frames[i]->_actionId] = true;
+
+		for (uint16 j = 0; j <= _frames[i]->_numChannels; j++) {
+			if (_frames[i]->_sprites[j]->_scriptId <= _actions.size())
+				scriptRefs[_frames[i]->_sprites[j]->_scriptId] = true;
+		}
+	}
+
+	Common::HashMap<uint16, Common::String>::iterator j;
+
+	if (ConfMan.getBool("dump_scripts"))
+		for (j = _actions.begin(); j != _actions.end(); ++j) {
+			if (!j->_value.empty())
+				_movie->getCast()->dumpScript(j->_value.c_str(), kScoreScript, j->_key);
+		}
+
+	for (j = _actions.begin(); j != _actions.end(); ++j) {
+		if (!scriptRefs[j->_key]) {
+			warning("Action id %d is not referenced, the code is:\n-----\n%s\n------", j->_key, j->_value.c_str());
+			// continue;
+		}
+		if (!j->_value.empty()) {
+			_lingo->addCode(j->_value.c_str(), _movie->getCast()->_lingoArchive, kScoreScript, j->_key);
+
+			processImmediateFrameScript(j->_value, j->_key);
+		}
+	}
+
+	free(scriptRefs);
+}
+
 } // End of namespace Director
diff --git a/engines/director/score.h b/engines/director/score.h
index 70eb0c9ecc..d718898716 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -43,21 +43,15 @@ namespace Director {
 
 class Stage;
 class Archive;
-struct CastMemberInfo;
 class DirectorEngine;
 class DirectorSound;
 class Frame;
 struct Label;
-class Lingo;
+class Movie;
 struct Resource;
 struct Channel;
 class Sprite;
-class Stxt;
 class CastMember;
-class BitmapCastMember;
-class ScriptCastMember;
-class ShapeCastMember;
-class TextCastMember;
 
 enum RenderMode {
 	kRenderModeNormal,
@@ -96,38 +90,25 @@ struct Channel {
 
 class Score {
 public:
-	Score(DirectorEngine *vm);
+	Score(DirectorEngine *vm, Movie *movie);
 	~Score();
 
-	static Common::Rect readRect(Common::ReadStreamEndian &stream);
+	void loadFrames(Common::SeekableSubReadStreamEndian &stream);
+	void loadLabels(Common::SeekableSubReadStreamEndian &stream);
+	void loadActions(Common::SeekableSubReadStreamEndian &stream);
+
 	static int compareLabels(const void *a, const void *b);
-	bool loadArchive(bool isSharedCast);
 	void setStartToLabel(Common::String label);
 	void gotoLoop();
 	void gotoNext();
 	void gotoPrevious();
 	void startLoop();
-	void setArchive(Archive *archive);
-	Archive *getArchive() const { return _movieArchive; };
-	void loadConfig(Common::SeekableSubReadStreamEndian &stream);
-	void loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream);
-	void loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id, Resource *res);
-	void loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id);
-	void loadLingoNames(Common::SeekableSubReadStreamEndian &stream);
-	void loadLingoContext(Common::SeekableSubReadStreamEndian &stream);
 	void setCurrentFrame(uint16 frameId) { _nextFrame = frameId; }
 	uint16 getCurrentFrame() { return _currentFrame; }
-	Common::String getMacName() const { return _macName; }
 	Channel *getChannelById(uint16 id);
 	Sprite *getSpriteById(uint16 id);
-	void setSpriteCasts();
-	void loadSpriteImages(bool isSharedCast);
-	void loadSpriteSounds(bool isSharedCast);
-	void copyCastStxts();
-	void createCastWidgets();
 
-	Common::Rect getCastMemberInitialRect(int castId);
-	void setCastMemberModified(int castId);
+	void setSpriteCasts();
 
 	int getPreviousLabelNumber(int referenceFrame);
 	int getCurrentLabelNumber();
@@ -137,8 +118,6 @@ public:
 	bool checkSpriteIntersection(uint16 spriteId, Common::Point pos);
 	Common::List<Channel *> getSpriteIntersections(const Common::Rect &r);
 
-	CastMember *getCastMember(int castId);
-	const Stxt *getStxt(int castId);
 	void renderFrame(uint16 frameId, RenderMode mode = kRenderModeNormal);
 	void renderSprites(uint16 frameId, RenderMode mode = kRenderModeNormal);
 
@@ -147,77 +126,36 @@ private:
 
 	void playSoundChannel(uint16 frameId);
 
-	void readVersion(uint32 rid);
-	void loadPalette(Common::SeekableSubReadStreamEndian &stream);
-	void loadFrames(Common::SeekableSubReadStreamEndian &stream);
-	void loadLabels(Common::SeekableSubReadStreamEndian &stream);
-	void loadActions(Common::SeekableSubReadStreamEndian &stream);
-	void loadScriptText(Common::SeekableSubReadStreamEndian &stream);
-	void loadFileInfo(Common::SeekableSubReadStreamEndian &stream);
-	void loadFontMap(Common::SeekableSubReadStreamEndian &stream);
-	void dumpScript(const char *script, ScriptType type, uint16 id);
 	void screenShot();
-	Common::String getString(Common::String str);
-	Common::Array<Common::String> loadStrings(Common::SeekableSubReadStreamEndian &stream, uint32 &entryType, bool hasHeader = true);
 
 	bool processImmediateFrameScript(Common::String s, int id);
 
 public:
 	Common::Array<Channel *> _channels;
 	Common::Array<Frame *> _frames;
-	Common::HashMap<uint16, CastMemberInfo *> _castsInfo;
-	Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _castsNames;
 	Common::SortedArray<Label *> *_labels;
 	Common::HashMap<uint16, Common::String> _actions;
 	Common::HashMap<uint16, bool> _immediateActions;
-	Common::HashMap<uint16, Common::String> _fontMap;
-	Graphics::Font *_font;
-	Archive *_movieArchive;
-	Common::Rect _movieRect;
-	uint16 _currentMouseDownSpriteId;
-	uint16 _currentClickOnSpriteId;
-	uint32 _lastEventTime;
-	uint32 _lastRollTime;
-	uint32 _lastClickTime;
-	uint32 _lastKeyTime;
-	uint32 _lastTimerReset;
-	uint16 _stageColor;
+
+	byte _currentFrameRate;
 
 	byte _puppetTempo;
 	bool _stopPlay;
 	uint32 _nextFrameTime;
 
-	Common::HashMap<int, CastMember *> *_loadedCast;
-
-	Common::HashMap<int, const Stxt *> *_loadedStxts;
-
-	uint16 _castIDoffset;
-
 	int _numChannelsDisplayed;
 
 	uint16 _framesRan; // used by kDebugFewFramesOnly
 
-	int _lingoArchive;
-
 private:
-	uint16 _versionMinor;
-	uint16 _versionMajor;
-	Common::String _macName;
-	Common::String _createdBy;
-	Common::String _changedBy;
-	Common::String _script;
-	Common::String _directory;
-	byte _currentFrameRate;
-	uint16 _castArrayStart;
+	DirectorEngine *_vm;
+	Lingo *_lingo;
+	Movie *_movie;
+
 	uint16 _currentFrame;
 	uint16 _nextFrame;
 	int _currentLabel;
-	uint32 _flags;
-	uint16 _castArrayEnd;
-	uint16 _movieScriptCount;
-	Lingo *_lingo;
 	DirectorSound *_soundManager;
-	DirectorEngine *_vm;
 };
 
 } // End of namespace Director
diff --git a/engines/director/stage.cpp b/engines/director/stage.cpp
index ad20f6499a..376be73276 100644
--- a/engines/director/stage.cpp
+++ b/engines/director/stage.cpp
@@ -23,6 +23,7 @@
 #include "graphics/primitives.h"
 
 #include "director/director.h"
+#include "director/movie.h"
 #include "director/stage.h"
 #include "director/score.h"
 #include "director/castmember.h"
@@ -56,7 +57,7 @@ bool Stage::render(bool forceRedraw, Graphics::ManagedSurface *blitTo) {
 		const Common::Rect &r = *i;
 		blitTo->fillRect(r, _stageColor);
 
-		_dirtyChannels = g_director->getCurrentScore()->getSpriteIntersections(r);
+		_dirtyChannels = g_director->getCurrentMovie()->getScore()->getSpriteIntersections(r);
 		for (Common::List<Channel *>::iterator j = _dirtyChannels.begin(); j != _dirtyChannels.end(); j++)
 			inkBlitFrom(*j, r, blitTo);
 	}
@@ -276,12 +277,12 @@ void Stage::drawReverseSprite(Channel *channel, Common::Rect &srcRect, Common::R
 				srcColor = 0x0;
 			else
 				srcColor = *src;
-			uint16 targetSprite = g_director->getCurrentScore()->getSpriteIDFromPos(Common::Point(destRect.left + j, destRect.top + ii));
+			uint16 targetSprite = g_director->getCurrentMovie()->getScore()->getSpriteIDFromPos(Common::Point(destRect.left + j, destRect.top + ii));
 			if ((targetSprite != 0)) {
 				// TODO: This entire reverse colour attempt needs a lot more testing on
 				// a lot more colour depths.
 				if (srcColor != skipColor) {
-					if (!g_director->getCurrentScore()->_channels[targetSprite]->_sprite->_cast ||  g_director->getCurrentScore()->_channels[targetSprite]->_sprite->_cast->_type != kCastBitmap) {
+					if (!g_director->getCurrentMovie()->getScore()->_channels[targetSprite]->_sprite->_cast ||  g_director->getCurrentMovie()->getScore()->_channels[targetSprite]->_sprite->_cast->_type != kCastBitmap) {
 						if (*dst == 0 || *dst == 255) {
 							*dst = g_director->transformColor(*dst);
 						} else if (srcColor == 255 || srcColor == 0) {
@@ -291,8 +292,8 @@ void Stage::drawReverseSprite(Channel *channel, Common::Rect &srcRect, Common::R
 						}
 					} else {
 						if (*dst == 0 && g_director->getVersion() == 3 &&
-								g_director->getCurrentScore()->_channels[targetSprite]->_sprite->_cast->_type == kCastBitmap &&
-								((BitmapCastMember*)g_director->getCurrentScore()->_channels[targetSprite]->_sprite->_cast)->_bitsPerPixel > 1) {
+								g_director->getCurrentMovie()->getScore()->_channels[targetSprite]->_sprite->_cast->_type == kCastBitmap &&
+								((BitmapCastMember*)g_director->getCurrentMovie()->getScore()->_channels[targetSprite]->_sprite->_cast)->_bitsPerPixel > 1) {
 							*dst = g_director->transformColor(*src - 40);
 						} else {
 							*dst ^= g_director->transformColor(srcColor);
diff --git a/engines/director/tests.cpp b/engines/director/tests.cpp
index 5f55c07c43..d5c996ba94 100644
--- a/engines/director/tests.cpp
+++ b/engines/director/tests.cpp
@@ -35,6 +35,7 @@
 
 #include "director/director.h"
 #include "director/archive.h"
+#include "director/movie.h"
 #include "director/score.h"
 #include "director/lingo/lingo.h"
 
@@ -137,7 +138,7 @@ void DirectorEngine::testFonts() {
 //////////////////////
 // Movie iteration
 //////////////////////
-Common::HashMap<Common::String, Score *> *DirectorEngine::scanMovies(const Common::String &folder) {
+Common::HashMap<Common::String, Movie *> *DirectorEngine::scanMovies(const Common::String &folder) {
 	Common::FSNode directory(folder);
 	Common::FSList movies;
 	const char *sharedMMMname;
@@ -148,7 +149,7 @@ Common::HashMap<Common::String, Score *> *DirectorEngine::scanMovies(const Commo
 		sharedMMMname = "Shared Cast";
 
 
-	Common::HashMap<Common::String, Score *> *nameMap = new Common::HashMap<Common::String, Score *>();
+	Common::HashMap<Common::String, Movie *> *nameMap = new Common::HashMap<Common::String, Movie *>();
 	if (!directory.getChildren(movies, Common::FSNode::kListFilesOnly))
 		return nameMap;
 
@@ -167,11 +168,11 @@ Common::HashMap<Common::String, Score *> *DirectorEngine::scanMovies(const Commo
 
 			warning("name: %s", i->getName().c_str());
 			arc->openFile(i->getName());
-			Score *sc = new Score(this);
-			sc->setArchive(arc);
-			nameMap->setVal(sc->getMacName(), sc);
+			Movie *m = new Movie(this);
+			m->setArchive(arc);
+			nameMap->setVal(m->getMacName(), m);
 
-			debugC(2, kDebugLoading, "Movie name: \"%s\"", sc->getMacName().c_str());
+			debugC(2, kDebugLoading, "Movie name: \"%s\"", m->getMacName().c_str());
 		}
 	}
 
@@ -286,9 +287,9 @@ void DirectorEngine::runTests() {
 	if (!_mainArchive->openStream(stream, 0)) {
 		error("DirectorEngine::runTests(): Bad movie data");
 	}
-	_currentScore = new Score(this);
-	_currentScore->setArchive(_mainArchive);
-	_currentScore->loadArchive(false);
+	_currentMovie = new Movie(this);
+	_currentMovie->setArchive(_mainArchive);
+	_currentMovie->loadArchive();
 
 	if (debugChannelSet(-1, kDebugText)) {
 		testFontScaling();
diff --git a/engines/director/transitions.cpp b/engines/director/transitions.cpp
index ea20975d40..d4a981a9cc 100644
--- a/engines/director/transitions.cpp
+++ b/engines/director/transitions.cpp
@@ -28,6 +28,7 @@
 
 #include "director/director.h"
 #include "director/frame.h"
+#include "director/movie.h"
 #include "director/score.h"
 #include "director/util.h"
 #include "director/lingo/lingo.h"
@@ -151,7 +152,7 @@ void Stage::playTransition(uint16 transDuration, uint8 transArea, uint8 transChu
 
 	// If a transition is being played, render the frame after the transition.
 	Graphics::ManagedSurface *nextFrame = new Graphics::ManagedSurface(_surface.w, _surface.h);
-	g_director->getCurrentScore()->renderSprites(t.frame, kRenderForceUpdate);
+	g_director->getCurrentMovie()->getScore()->renderSprites(t.frame, kRenderForceUpdate);
 	render(true, nextFrame);
 
 	if (t.area)




More information about the Scummvm-git-logs mailing list