[Scummvm-git-logs] scummvm master -> 0e9fd00720930813a6389322ac69ebdb8f456766
djsrv
dservilla at gmail.com
Thu Jul 1 02:32:31 UTC 2021
This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
2d5ca7a1d6 DIRECTOR: Remove getCastMemberByScriptId from Movie
1724a158c6 DIRECTOR: Create CastMemberID type
615995fdc1 DIRECTOR: Change member refs to use CastMemberID
8bbd6da3a4 DIRECTOR: LINGO: Remove unbalanced 'end if' patches
8dfa5f4e73 DIRECTOR: LINGO: Use member ID as script ID in D2-3
b27696e49c DIRECTOR: LINGO: Fix movie script IDs in patcher
7bfa8aa6dc DIRECTOR: Add castLibID to Cast
0e9fd00720 DIRECTOR: LINGO: Take castLib into account in patcher
Commit: 2d5ca7a1d649ca17d1bf61c10f043a1cda09812f
https://github.com/scummvm/scummvm/commit/2d5ca7a1d649ca17d1bf61c10f043a1cda09812f
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-30T22:32:19-04:00
Commit Message:
DIRECTOR: Remove getCastMemberByScriptId from Movie
This can be called on the correct cast directly.
Changed paths:
engines/director/lingo/lingo-bytecode.cpp
engines/director/movie.cpp
engines/director/movie.h
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 5714d36348..a91e01b28a 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -965,14 +965,14 @@ ScriptContext *LingoCompiler::compileLingoV4(Common::SeekableReadStreamEndian &s
// initialise the script
ScriptType scriptType = kCastScript;
Common::String castName;
- CastMember *member = g_director->getCurrentMovie()->getCastMemberByScriptId(scriptId);
+ CastMember *member = archive->cast->getCastMemberByScriptId(scriptId);
int castId;
if (member) {
if (member->_type == kCastLingoScript)
scriptType = ((ScriptCastMember *)member)->_scriptType;
castId = member->getID();
- CastMemberInfo *info = g_director->getCurrentMovie()->getCastMemberInfo(castId);
+ CastMemberInfo *info = member->getInfo();
if (info)
castName = info->name;
} else {
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index f3648ccf2d..2516d6cc6b 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -312,14 +312,6 @@ CastMember *Movie::getCastMemberByName(const Common::String &name) {
return result;
}
-CastMember *Movie::getCastMemberByScriptId(int scriptId) {
- CastMember *result = _cast->getCastMemberByScriptId(scriptId);
- if (result == nullptr && _sharedCast) {
- result = _sharedCast->getCastMemberByScriptId(scriptId);
- }
- return result;
-}
-
CastMemberInfo *Movie::getCastMemberInfo(int castId) {
CastMemberInfo *result = _cast->getCastMemberInfo(castId);
if (result == nullptr && _sharedCast) {
diff --git a/engines/director/movie.h b/engines/director/movie.h
index b1dbc6e93f..2e84544070 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -119,7 +119,6 @@ public:
CastMember *getCastMember(int castId);
CastMember *getCastMemberByName(const Common::String &name);
- CastMember *getCastMemberByScriptId(int scriptId);
CastMemberInfo *getCastMemberInfo(int castId);
const Stxt *getStxt(int castId);
Commit: 1724a158c676ce68437822a25a6a4d3602421658
https://github.com/scummvm/scummvm/commit/1724a158c676ce68437822a25a6a4d3602421658
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-30T22:32:19-04:00
Commit Message:
DIRECTOR: Create CastMemberID type
Changed paths:
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
engines/director/types.h
engines/director/util.cpp
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 578ee12407..b3b6906e04 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1346,4 +1346,36 @@ Datum Lingo::varFetch(const Datum &var, bool silent) {
return result;
}
+CastMemberID Lingo::resolveCastMember(const Datum &memberID, const Datum &castLib) {
+ Movie *movie = g_director->getCurrentMovie();
+ if (!movie) {
+ warning("Lingo::resolveCastMember: No movie");
+ return CastMemberID(-1, castLib.asInt());
+ }
+
+ switch (memberID.type) {
+ case STRING:
+ {
+ CastMember *member = movie->getCastMemberByName(memberID.asString(), castLib.asInt());
+ if (member)
+ return CastMemberID(member->getID(), castLib.asInt());
+
+ warning("Lingo::resolveCastMember: reference to non-existent cast member: %s", memberID.asString().c_str());
+ return CastMemberID(-1, castLib.asInt());
+ }
+ break;
+ case INT:
+ case FLOAT:
+ return CastMemberID(memberID.asInt(), castLib.asInt());
+ break;
+ case VOID:
+ warning("Lingo::resolveCastMember: reference to VOID member ID");
+ break;
+ default:
+ error("Lingo::resolveCastMember: unsupported member ID type %s", memberID.type2str());
+ }
+
+ return CastMemberID(-1, castLib.asInt());
+}
+
} // End of namespace Director
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 01c1f203d8..036bd1d2fb 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -280,6 +280,7 @@ public:
void varAssign(const Datum &var, const Datum &value);
Datum varFetch(const Datum &var, bool silent = false);
Datum findVarV4(int varType, const Datum &id);
+ CastMemberID resolveCastMember(const Datum &memberID, const Datum &castLib);
int getAlignedType(const Datum &d1, const Datum &d2, bool numsOnly);
diff --git a/engines/director/types.h b/engines/director/types.h
index fa64f4c11b..ed2fcdd844 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -363,6 +363,24 @@ enum VarType {
kVarLocal
};
+struct CastMemberID {
+ int member;
+ int castLib;
+
+ CastMemberID() : member(0), castLib(0) {}
+ CastMemberID(int memberID, int castLibID)
+ : member(memberID), castLib(castLibID) {}
+
+ bool operator==(const CastMemberID &c) {
+ return member == c.member && castLib == c.castLib;
+ }
+ bool operator!=(const CastMemberID &c) {
+ return member != c.member || castLib != c.castLib;
+ }
+
+ const char *str() const;
+};
+
struct Datum;
struct PCell;
typedef Common::Array<Datum> DatumArray;
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index 30ac00238f..e6cf0d99e0 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -26,6 +26,7 @@
#include "common/zlib.h"
#include "director/director.h"
+#include "director/movie.h"
#include "director/util.h"
namespace Director {
@@ -200,6 +201,19 @@ char *numToCastNum(int num) {
return res;
}
+const char *CastMemberID::str() const {
+ static char res[40];
+
+ if (g_director->getVersion() < 400 || g_director->getCurrentMovie()->_allowOutdatedLingo)
+ snprintf(res, 40, "member %d(%s)", member, numToCastNum(member));
+ else if (g_director->getVersion() < 500)
+ snprintf(res, 40, "member %d", member);
+ else
+ snprintf(res, 40, "member %d of castLib %d", member, castLib);
+
+ return res;
+}
+
// This is table for built-in Macintosh font lowercasing.
// '.' means that the symbol should be not changed, rest
// of the symbols are stripping the diacritics
Commit: 615995fdc1c5f51ce9587659eaa618a108542305
https://github.com/scummvm/scummvm/commit/615995fdc1c5f51ce9587659eaa618a108542305
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-30T22:32:19-04:00
Commit Message:
DIRECTOR: Change member refs to use CastMemberID
Changed paths:
engines/director/channel.cpp
engines/director/channel.h
engines/director/cursor.cpp
engines/director/cursor.h
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-events.cpp
engines/director/lingo/lingo-funcs.cpp
engines/director/lingo/lingo-the.cpp
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
engines/director/movie.cpp
engines/director/movie.h
engines/director/score.cpp
engines/director/score.h
engines/director/sound.cpp
engines/director/sound.h
engines/director/sprite.cpp
engines/director/sprite.h
engines/director/types.h
engines/director/util.cpp
engines/director/window.cpp
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 47d498d229..b07df4d75d 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -115,7 +115,8 @@ const Graphics::Surface *Channel::getMask(bool forceMatte) {
return nullptr;
}
} else if (_sprite->_ink == kInkTypeMask) {
- CastMember *member = g_director->getCurrentMovie()->getCastMember(_sprite->_castId + 1);
+ CastMemberID maskID(_sprite->_castId.member + 1, _sprite->_castId.castLib);
+ CastMember *member = g_director->getCurrentMovie()->getCastMember(maskID);
if (member && member->_initialRect == _sprite->_cast->_initialRect) {
Common::Rect bbox(getBbox());
@@ -287,24 +288,24 @@ Common::Rect Channel::getBbox(bool unstretched) {
return result;
}
-void Channel::setCast(uint16 castId) {
- _sprite->setCast(castId);
+void Channel::setCast(CastMemberID memberID) {
+ _sprite->setCast(memberID);
_width = _sprite->_width;
_height = _sprite->_height;
- replaceWidget(0);
+ replaceWidget();
}
void Channel::setClean(Sprite *nextSprite, int spriteId, bool partial) {
if (!nextSprite)
return;
- uint16 previousCastId = 0;
+ CastMemberID previousCastId(0, 0);
bool replace = isDirty(nextSprite);
if (nextSprite) {
if (nextSprite->_cast && (_dirty || _sprite->_castId != nextSprite->_castId)) {
if (nextSprite->_cast->_type == kCastDigitalVideo) {
- Common::String path = nextSprite->_cast->getCast()->getVideoPath(nextSprite->_castId);
+ Common::String path = nextSprite->_cast->getCast()->getVideoPath(nextSprite->_castId.member);
if (!path.empty()) {
((DigitalVideoCastMember *)nextSprite->_cast)->loadVideo(pathMakeRelative(path));
@@ -452,15 +453,15 @@ void Channel::setBbox(int l, int t, int r, int b) {
// here is the place for deciding whether the widget can be keep or not
// here's the definition, we first need to have widgets to keep, and the cast is not modified(modified means we need to re-create the widget)
// and the castId should be same while castId should not be zero
-bool Channel::canKeepWidget(uint16 castId) {
- if (_widget && _sprite && _sprite->_cast && !_sprite->_cast->isModified() && castId && castId == _sprite->_castId) {
+bool Channel::canKeepWidget(CastMemberID castId) {
+ if (_widget && _sprite && _sprite->_cast && !_sprite->_cast->isModified() && castId.member && castId == _sprite->_castId) {
return true;
}
return false;
}
bool Channel::canKeepWidget(Sprite *currentSprite, Sprite *nextSprite) {
- if (_widget && currentSprite && currentSprite->_cast && nextSprite && nextSprite->_cast && !currentSprite->_cast->isModified() && currentSprite->_castId == nextSprite->_castId && currentSprite->_castId) {
+ if (_widget && currentSprite && currentSprite->_cast && nextSprite && nextSprite->_cast && !currentSprite->_cast->isModified() && currentSprite->_castId == nextSprite->_castId && currentSprite->_castId.member) {
return true;
}
return false;
@@ -468,10 +469,10 @@ bool Channel::canKeepWidget(Sprite *currentSprite, Sprite *nextSprite) {
// currently, when we are setting hilite, we delete the widget and the re-create it
// so we may optimize this if this operation takes much time
-void Channel::replaceWidget(uint16 previousCastId) {
+void Channel::replaceWidget(CastMemberID previousCastId) {
// if the castmember is the same, and we are not modifying anything which cannot be handle by channel. Then we don't replace the widget
if (canKeepWidget(previousCastId)) {
- debug(5, "Channel::replaceWidget(): skip deleting %d %s", _sprite->_castId, numToCastNum(_sprite->_castId));
+ debug(5, "Channel::replaceWidget(): skip deleting %s", _sprite->_castId.asString().c_str());
return;
}
diff --git a/engines/director/channel.h b/engines/director/channel.h
index f03ff153e3..3e19c1c20c 100644
--- a/engines/director/channel.h
+++ b/engines/director/channel.h
@@ -58,18 +58,18 @@ public:
void setWidth(int w);
void setHeight(int h);
void setBbox(int l, int t, int r, int b);
- void setCast(uint16 castId);
+ void setCast(CastMemberID memberID);
void setClean(Sprite *nextSprite, int spriteId, bool partial = false);
void setEditable(bool editable);
void replaceSprite(Sprite *nextSprite);
- void replaceWidget(uint16 previousCastId = 0);
+ void replaceWidget(CastMemberID previousCastId = CastMemberID(0, 0));
bool updateWidget();
void updateTextCast();
void updateGlobalAttr();
void addDelta(Common::Point pos);
- bool canKeepWidget(uint16 castId);
+ bool canKeepWidget(CastMemberID castId);
bool canKeepWidget(Sprite *currentSprite, Sprite *nextSprite);
public:
diff --git a/engines/director/cursor.cpp b/engines/director/cursor.cpp
index b1fb01c099..68a4e677aa 100644
--- a/engines/director/cursor.cpp
+++ b/engines/director/cursor.cpp
@@ -34,8 +34,8 @@ Cursor::Cursor() {
_cursorResId = 0;
_cursorType = Graphics::kMacCursorArrow;
- _cursorCastId = 0;
- _cursorMaskId = 0;
+ _cursorCastId = CastMemberID(0, 0);
+ _cursorMaskId = CastMemberID(0, 0);
_usePalette = false;
}
@@ -47,7 +47,7 @@ bool Cursor::operator==(const Cursor &c) {
_cursorMaskId == c._cursorMaskId;
}
-void Cursor::readFromCast(uint cursorId, uint maskId) {
+void Cursor::readFromCast(CastMemberID cursorId, CastMemberID maskId) {
if (cursorId == _cursorCastId && maskId == _cursorMaskId)
return;
@@ -147,7 +147,7 @@ void Cursor::readFromResource(int resourceId) {
}
}
-void Cursor::resetCursor(Graphics::MacCursorType type, bool shouldClear, int resId, uint castId, uint maskId) {
+void Cursor::resetCursor(Graphics::MacCursorType type, bool shouldClear, int resId, CastMemberID castId, CastMemberID maskId) {
if (shouldClear)
clear();
diff --git a/engines/director/cursor.h b/engines/director/cursor.h
index 57473d6052..119c2164b0 100644
--- a/engines/director/cursor.h
+++ b/engines/director/cursor.h
@@ -37,10 +37,10 @@ class Cursor : public Graphics::MacCursor {
public:
Cursor();
- void readFromCast(uint cursorId, uint maskId);
+ void readFromCast(CastMemberID cursorId, CastMemberID maskId);
void readFromResource(int resourceId);
- bool isEmpty() { return !(_cursorResId || _cursorCastId); }
+ bool isEmpty() { return _cursorResId == 0 && _cursorCastId.member == 0; }
bool operator==(const Cursor &c);
virtual byte getKeyColor() const override { return _keyColor; }
@@ -50,11 +50,11 @@ class Cursor : public Graphics::MacCursor {
Graphics::MacCursorType _cursorType;
int _cursorResId;
- uint _cursorCastId;
- uint _cursorMaskId;
+ CastMemberID _cursorCastId;
+ CastMemberID _cursorMaskId;
private:
- void resetCursor(Graphics::MacCursorType type, bool shouldClear = false, int resId = 0, uint castId = 0, uint maskId = 0);
+ void resetCursor(Graphics::MacCursorType type, bool shouldClear = false, int resId = 0, CastMemberID castId = CastMemberID(0, 0), CastMemberID maskId = CastMemberID(0, 0));
private:
bool _usePalette;
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index df4fac284f..af44beaa32 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -42,12 +42,12 @@ Frame::Frame(Score *score, int numChannels) {
_numChannels = numChannels;
- _sound1 = 0;
- _sound2 = 0;
+ _sound1 = CastMemberID(0, 0);
+ _sound2 = CastMemberID(0, 0);
_soundType1 = 0;
_soundType2 = 0;
- _actionId = 0;
+ _actionId = CastMemberID(0, 0);
_skipFrameFlag = 0;
_blend = 0;
@@ -91,7 +91,7 @@ Frame::Frame(const Frame &frame) {
_score = frame._score;
- debugC(1, kDebugLoading, "Frame. action: %d transType: %d transDuration: %d", _actionId, _transType, _transDuration);
+ debugC(1, kDebugLoading, "Frame. action: %s transType: %d transDuration: %d", _actionId.asString().c_str(), _transType, _transDuration);
_sprites.resize(_numChannels + 1);
@@ -131,7 +131,7 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
if (version < kFileVer400) {
// Sound/Tempo/Transition
- _actionId = stream->readByte();
+ _actionId = CastMemberID(stream->readByte(), 0);
_soundType1 = stream->readByte(); // type: 0x17 for sounds (sound is cast id), 0x16 for MIDI (sound is cmd id)
uint8 transFlags = stream->readByte(); // 0x80 is whole stage (vs changed area), rest is duration in 1/4ths of a second
@@ -144,10 +144,10 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
_transChunkSize = stream->readByte();
_tempo = stream->readByte();
_transType = static_cast<TransitionType>(stream->readByte());
- _sound1 = stream->readUint16();
+ _sound1 = CastMemberID(stream->readUint16(), 0);
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
- _sound2 = stream->readUint16();
+ _sound2 = CastMemberID(stream->readUint16(), 0);
_soundType2 = stream->readByte();
} else {
stream->read(unk, 3);
@@ -158,7 +158,7 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
_blend = stream->readByte();
if (_vm->getPlatform() != Common::kPlatformMacintosh) {
- _sound2 = stream->readUint16();
+ _sound2 = CastMemberID(stream->readUint16(), 0);
_soundType2 = stream->readByte();
}
@@ -188,7 +188,7 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
stream->read(unk, 4);
}
- debugC(8, kDebugLoading, "Frame::readChannels(): %d %d %d %d %d %d %d %d %d %d %d", _actionId, _soundType1, _transDuration, _transChunkSize, _tempo, _transType, _sound1, _skipFrameFlag, _blend, _sound2, _soundType2);
+ debugC(8, kDebugLoading, "Frame::readChannels(): %d %d %d %d %d %d %d %d %d %d %d", _actionId.member, _soundType1, _transDuration, _transChunkSize, _tempo, _transType, _sound1.member, _skipFrameFlag, _blend, _sound2.member, _soundType2);
if (_vm->getPlatform() == Common::kPlatformMacintosh)
stream->read(unk, 3);
@@ -210,9 +210,9 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
_transChunkSize = stream->readByte();
_tempo = stream->readByte();
_transType = static_cast<TransitionType>(stream->readByte());
- _sound1 = stream->readUint16();
+ _sound1 = CastMemberID(stream->readUint16(), 0);
- _sound2 = stream->readUint16();
+ _sound2 = CastMemberID(stream->readUint16(), 0);
_soundType2 = stream->readByte();
_skipFrameFlag = stream->readByte();
@@ -222,7 +222,7 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
_colorSound1 = stream->readByte();
_colorSound2 = stream->readByte();
- _actionId = stream->readUint16();
+ _actionId = CastMemberID(stream->readUint16(), 0);
_colorScript = stream->readByte();
_colorTrans = stream->readByte();
@@ -247,7 +247,7 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
stream->readByte();
- debugC(8, kDebugLoading, "Frame::readChannels(): %d %d %d %d %d %d %d %d %d %d %d", _actionId, _soundType1, _transDuration, _transChunkSize, _tempo, _transType, _sound1, _skipFrameFlag, _blend, _sound2, _soundType2);
+ debugC(8, kDebugLoading, "Frame::readChannels(): %d %d %d %d %d %d %d %d %d %d %d", _actionId.member, _soundType1, _transDuration, _transChunkSize, _tempo, _transType, _sound1.member, _skipFrameFlag, _blend, _sound2.member, _soundType2);
} else if (version >= kFileVer500 && version < kFileVer600) {
// Sound/Tempo/Transition channel
stream->read(unk, 24);
@@ -269,7 +269,7 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
Sprite &sprite = *_sprites[i + 1];
if (version < kFileVer500) {
- sprite._scriptId = stream->readByte();
+ sprite._scriptId = CastMemberID(stream->readByte(), 0);
sprite._spriteType = (SpriteType)stream->readByte();
sprite._enabled = sprite._spriteType != kInactiveSprite;
if (version >= kFileVer400) {
@@ -287,7 +287,7 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
if (sprite.isQDShape()) {
sprite._pattern = stream->readUint16();
} else {
- sprite._castId = stream->readUint16();
+ sprite._castId = CastMemberID(stream->readUint16(), 0);
}
sprite._startPoint.y = (int16)stream->readUint16();
@@ -297,7 +297,7 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
sprite._width = (int16)stream->readUint16();
if (version >= kFileVer400) {
- sprite._scriptId = stream->readUint16();
+ sprite._scriptId = CastMemberID(stream->readUint16(), 0);
// & 0x0f scorecolor
// 0x10 forecolor is rgb
// 0x20 bgcolor is rgb
@@ -310,11 +310,13 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
sprite._spriteType = (SpriteType)stream->readByte();
sprite._inkData = stream->readByte();
- sprite._castIndex = stream->readUint16();
- sprite._castId = stream->readUint16();
+ uint16 castLib = stream->readUint16();
+ uint16 memberID = stream->readUint16();
+ sprite._castId = CastMemberID(memberID, castLib);
- sprite._scriptCastIndex = stream->readUint16();
- sprite._scriptId = stream->readUint16();
+ uint16 scriptCastLib = stream->readUint16();
+ uint16 scriptMemberID = stream->readUint16();
+ sprite._scriptId = CastMemberID(scriptMemberID, scriptCastLib);
sprite._foreColor = _vm->transformColor((uint8)stream->readByte());
sprite._backColor = _vm->transformColor((uint8)stream->readByte());
@@ -336,8 +338,9 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
sprite._foreColor = _vm->transformColor((uint8)stream->readByte());
sprite._backColor = _vm->transformColor((uint8)stream->readByte());
- sprite._castIndex = stream->readUint16();
- sprite._castId = stream->readUint16();
+ uint16 castLib = stream->readUint16();
+ uint16 memberID = stream->readUint16();
+ sprite._castId = CastMemberID(memberID, castLib);
/* uint32 spriteId = */stream->readUint32();
@@ -369,12 +372,12 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
sprite._moveable = ((sprite._colorcode & 0x80) == 0x80);
- if (sprite._castId) {
- debugC(4, kDebugLoading, "CH: %-3d castId: %03d(%s) [flags:%04x [ink: %x trails: %d line: %d], %dx%d@%d,%d type: %d fg: %d bg: %d] script: %d, flags2: %x, unk2: %x, unk3: %x",
- i + 1, sprite._castId, numToCastNum(sprite._castId), sprite._inkData,
+ if (sprite._castId.member) {
+ debugC(4, kDebugLoading, "CH: %-3d castId: %s [flags:%04x [ink: %x trails: %d line: %d], %dx%d@%d,%d type: %d fg: %d bg: %d] script: %s, flags2: %x, unk2: %x, unk3: %x",
+ i + 1, sprite._castId.asString().c_str(), sprite._inkData,
sprite._ink, sprite._trails, sprite._thickness, sprite._width, sprite._height,
sprite._startPoint.x, sprite._startPoint.y,
- sprite._spriteType, sprite._foreColor, sprite._backColor, sprite._scriptId, sprite._colorcode, sprite._blendAmount, sprite._unk3);
+ sprite._spriteType, sprite._foreColor, sprite._backColor, sprite._scriptId.asString().c_str(), sprite._colorcode, sprite._blendAmount, sprite._unk3);
} else {
debugC(4, kDebugLoading, "CH: %-3d castId: 000", i + 1);
}
@@ -387,7 +390,7 @@ void Frame::readMainChannels(Common::SeekableReadStreamEndian &stream, uint16 of
while (offset < finishPosition) {
switch(offset) {
case kScriptIdPosition:
- _actionId = stream.readByte();
+ _actionId = CastMemberID(stream.readByte(), 0);
offset++;
break;
case kSoundType1Position:
@@ -417,7 +420,7 @@ void Frame::readMainChannels(Common::SeekableReadStreamEndian &stream, uint16 of
offset++;
break;
case kSound1Position:
- _sound1 = stream.readUint16();
+ _sound1 = CastMemberID(stream.readUint16(), 0);
offset+=2;
break;
case kSkipFrameFlagsPosition:
@@ -429,7 +432,7 @@ void Frame::readMainChannels(Common::SeekableReadStreamEndian &stream, uint16 of
offset++;
break;
case kSound2Position:
- _sound2 = stream.readUint16();
+ _sound2 = CastMemberID(stream.readUint16(), 0);
offset += 2;
break;
case kSound2TypePosition:
@@ -449,7 +452,7 @@ void Frame::readMainChannels(Common::SeekableReadStreamEndian &stream, uint16 of
}
}
- debugC(1, kDebugLoading, "Frame::readChannels(): %d %d %d %d %d %d %d %d %d %d %d", _actionId, _soundType1, _transDuration, _transChunkSize, _tempo, _transType, _sound1, _skipFrameFlag, _blend, _sound2, _soundType2);
+ debugC(1, kDebugLoading, "Frame::readChannels(): %d %d %d %d %d %d %d %d %d %d %d", _actionId.member, _soundType1, _transDuration, _transChunkSize, _tempo, _transType, _sound1.member, _skipFrameFlag, _blend, _sound2.member, _soundType2);
}
void Frame::readPaletteInfo(Common::SeekableReadStreamEndian &stream) {
@@ -499,7 +502,7 @@ void Frame::readSprite(Common::SeekableReadStreamEndian &stream, uint16 offset,
fieldPosition += 2;
break;
case kSpritePositionCastId:
- sprite._castId = stream.readUint16();
+ sprite._castId = CastMemberID(stream.readUint16(), 0);
fieldPosition += 2;
break;
case kSpritePositionY:
@@ -525,7 +528,7 @@ void Frame::readSprite(Common::SeekableReadStreamEndian &stream, uint16 offset,
break;
}
}
- warning("Frame::readSprite(): %03d(%d)[%x,%x,%02x %02x,%d/%d/%d/%d]", sprite._castId, sprite._enabled, x1, x2, sprite._thickness, sprite._inkData, sprite._startPoint.x, sprite._startPoint.y, sprite._width, sprite._height);
+ warning("Frame::readSprite(): %s(%d)[%x,%x,%02x %02x,%d/%d/%d/%d]", sprite._castId.asString().c_str(), sprite._enabled, x1, x2, sprite._thickness, sprite._inkData, sprite._startPoint.x, sprite._startPoint.y, sprite._width, sprite._height);
}
diff --git a/engines/director/frame.h b/engines/director/frame.h
index e123b54fe3..74b6b628a0 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -101,7 +101,7 @@ private:
public:
int _numChannels;
byte _channelData[kChannelDataSize];
- uint16 _actionId;
+ CastMemberID _actionId;
uint16 _transDuration;
uint8 _transArea; // 1 - Whole Window, 0 - Changing Area
uint8 _transChunkSize;
@@ -109,9 +109,9 @@ public:
PaletteInfo _palette;
uint8 _tempo;
- uint16 _sound1;
+ CastMemberID _sound1;
uint8 _soundType1;
- uint16 _sound2;
+ CastMemberID _sound2;
uint8 _soundType2;
byte _colorTempo;
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 142db50cbb..5935dab49b 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1518,9 +1518,9 @@ void LB::b_cursor(int nargs) {
Datum sprite = d.u.farr->operator[](0);
Datum mask = d.u.farr->operator[](1);
- g_lingo->func_cursor(sprite.asCastId(), mask.asCastId());
+ g_lingo->func_cursor(sprite.asMemberID(), mask.asMemberID());
} else {
- g_lingo->func_cursor(d.asInt(), -1);
+ g_lingo->func_cursor(d.asInt());
}
}
@@ -1658,25 +1658,24 @@ void LB::b_installMenu(int nargs) {
// installMenu castNum
Datum d = g_lingo->pop();
- int castId = d.asCastId();
-
- if (castId == 0) {
+ CastMemberID memberID = d.asMemberID();
+ if (memberID.member == 0) {
g_director->_wm->removeMenu();
return;
}
- CastMember *member = g_director->getCurrentMovie()->getCastMember(castId);
+ CastMember *member = g_director->getCurrentMovie()->getCastMember(memberID);
if (!member) {
- g_lingo->lingoError("installMenu: Unknown cast number #%d", castId);
+ g_lingo->lingoError("installMenu: Unknown %s", memberID.asString().c_str());
return;
}
if (member->_type != kCastText) {
- g_lingo->lingoError("installMenu: Cast member %d is not a field", castId);
+ g_lingo->lingoError("installMenu: %s is not a field", memberID.asString().c_str());
return;
}
TextCastMember *field = static_cast<TextCastMember *>(member);
- Common::String menuStxt = g_lingo->_compiler->codePreprocessor(field->getText().c_str(), field->getCast()->_lingoArchive, kNoneScript, castId, true);
+ Common::String menuStxt = g_lingo->_compiler->codePreprocessor(field->getText().c_str(), field->getCast()->_lingoArchive, kNoneScript, memberID.member, true);
Common::String line;
int linenum = -1; // We increment it before processing
@@ -1843,14 +1842,10 @@ void LB::b_puppetPalette(int nargs) {
palette = kClutNTSC;
} else if (palStr.equalsIgnoreCase("Metallic")) {
palette = kClutMetallic;
- } else {
- CastMember *member = g_director->getCurrentMovie()->getCastMemberByName(palStr);
-
- if (member && member->_type == kCastPalette)
- palette = ((PaletteCastMember *)member)->getPaletteId();
}
- } else {
- CastMember *member = g_director->getCurrentMovie()->getCastMember(d.asInt());
+ }
+ if (!palette) {
+ CastMember *member = g_director->getCurrentMovie()->getCastMember(d.asMemberID());
if (member && member->_type == kCastPalette)
palette = ((PaletteCastMember *)member)->getPaletteId();
@@ -1896,7 +1891,7 @@ void LB::b_puppetSound(int nargs) {
return;
}
- int castId = castMember.asCastId();
+ CastMemberID castId = castMember.asMemberID();
sound->playCastMember(castId, channel);
}
@@ -2414,26 +2409,26 @@ void LB::b_version(int nargs) {
///////////////////
void LB::b_cast(int nargs) {
Datum d = g_lingo->pop();
- Datum res = d.asCastId();
+ Datum res = d.asMemberID();
res.type = CASTREF;
g_lingo->push(res);
}
void LB::b_script(int nargs) {
Datum d = g_lingo->pop();
- int castId = d.asCastId();
- CastMember *cast = g_director->getCurrentMovie()->getCastMember(castId);
+ CastMemberID memberID = d.asMemberID();
+ CastMember *cast = g_director->getCurrentMovie()->getCastMember(memberID);
if (cast) {
ScriptContext *script = nullptr;
if (cast->_type == kCastLingoScript) {
// script cast can be either a movie script or score script
- script = g_director->getCurrentMovie()->getScriptContext(kMovieScript, castId);
+ script = g_director->getCurrentMovie()->getScriptContext(kMovieScript, memberID);
if (!script)
- script = g_director->getCurrentMovie()->getScriptContext(kScoreScript, castId);
+ script = g_director->getCurrentMovie()->getScriptContext(kScoreScript, memberID);
} else {
- g_director->getCurrentMovie()->getScriptContext(kCastScript, castId);
+ g_director->getCurrentMovie()->getScriptContext(kCastScript, memberID);
}
if (script) {
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index a91e01b28a..b58278c0a2 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -358,7 +358,7 @@ Datum Lingo::findVarV4(int varType, const Datum &id) {
}
break;
case 6: // field
- res = id.asCastId();
+ res = id.asMemberID();
res.type = FIELDREF;
break;
default:
@@ -396,7 +396,7 @@ void LC::cb_delete() {
}
void LC::cb_hilite() {
- Datum fieldID = g_lingo->pop().asCastId();
+ Datum fieldID = g_lingo->pop().asMemberID();
fieldID.type = FIELDREF;
Datum chunkRef = readChunkRef(fieldID);
g_lingo->push(chunkRef);
@@ -756,7 +756,7 @@ void LC::cb_v4theentitypush() {
break;
case kTEAChunk:
{
- Datum fieldRef = g_lingo->pop().asCastId();
+ Datum fieldRef = g_lingo->pop().asMemberID();
fieldRef.type = FIELDREF;
Datum chunkRef = readChunkRef(fieldRef);
result = g_lingo->getTheEntity(entity, chunkRef, field);
@@ -862,7 +862,7 @@ void LC::cb_v4theentityassign() {
break;
case kTEAChunk:
{
- Datum fieldRef = g_lingo->pop().asCastId();
+ Datum fieldRef = g_lingo->pop().asMemberID();
fieldRef.type = FIELDREF;
Datum chunkRef = readChunkRef(fieldRef);
g_lingo->setTheEntity(entity, chunkRef, field, value);
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index c2f50d8089..36d125204d 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1633,7 +1633,8 @@ void LC::c_delete() {
void LC::c_hilite() {
Datum d = g_lingo->pop();
- int fieldId, start, end;
+ CastMemberID fieldId;
+ int start, end;
if (d.type == CHUNKREF) {
start = d.u.cref->start;
end = d.u.cref->end;
@@ -1644,13 +1645,13 @@ void LC::c_hilite() {
src = src.u.cref->source;
}
if (src.isCastRef()) {
- fieldId = src.u.i;
+ fieldId = *d.u.cast;
} else {
warning("BUILDBOT: c_hilite: bad chunk ref field type: %s", src.type2str());
return;
}
} else if (d.isCastRef()) {
- fieldId = d.u.i;
+ fieldId = *d.u.cast;
start = 0;
end = -1;
} else {
@@ -1675,7 +1676,7 @@ void LC::c_hilite() {
void LC::c_fieldref() {
Datum d = g_lingo->pop();
- Datum res = d.asCastId();
+ Datum res = d.asMemberID();
res.type = FIELDREF;
g_lingo->push(res);
}
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 8559cdd768..3c750d4c8d 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -128,7 +128,7 @@ void Movie::queueSpriteEvent(LEvent event, int eventId, int spriteId) {
Sprite *sprite = _score->getSpriteById(spriteId);
// Sprite (score) script
- if (sprite->_scriptId) {
+ if (sprite->_scriptId.member) {
ScriptContext *script = getScriptContext(kScoreScript, sprite->_scriptId);
if (script) {
// In D3 the event lingo is not contained in a handler
@@ -162,8 +162,8 @@ void Movie::queueFrameEvent(LEvent event, int eventId) {
// } else {
assert(_score->_frames[_score->getCurrentFrame()] != nullptr);
- int scriptId = _score->_frames[_score->getCurrentFrame()]->_actionId;
- if (!scriptId)
+ CastMemberID scriptId = _score->_frames[_score->getCurrentFrame()]->_actionId;
+ if (!scriptId.member)
return;
ScriptContext *script = getScriptContext(kScoreScript, scriptId);
@@ -188,7 +188,7 @@ void Movie::queueMovieEvent(LEvent event, int eventId) {
for (ScriptContextHash::iterator it = mainArchive->scriptContexts[kMovieScript].begin();
it != mainArchive->scriptContexts[kMovieScript].end(); ++it) {
if (it->_value->_eventHandlers.contains(event)) {
- _eventQueue.push(LingoEvent(event, eventId, kMovieScript, it->_key, false));
+ _eventQueue.push(LingoEvent(event, eventId, kMovieScript, CastMemberID(it->_key, 0), false));
return;
}
}
@@ -197,7 +197,7 @@ void Movie::queueMovieEvent(LEvent event, int eventId) {
for (ScriptContextHash::iterator it = sharedArchive->scriptContexts[kMovieScript].begin();
it != sharedArchive->scriptContexts[kMovieScript].end(); ++it) {
if (it->_value->_eventHandlers.contains(event)) {
- _eventQueue.push(LingoEvent(event, eventId, kMovieScript, it->_key, false));
+ _eventQueue.push(LingoEvent(event, eventId, kMovieScript, CastMemberID(it->_key, 0), false));
return;
}
}
@@ -228,13 +228,19 @@ void Movie::registerEvent(LEvent event, int targetId) {
case kEventKeyUp:
case kEventKeyDown:
case kEventTimeout:
- if (getScriptContext(kEventScript, event)) {
- _eventQueue.push(LingoEvent(kEventGeneric, eventId, kEventScript, event, true));
+ {
+ CastMemberID scriptID = CastMemberID(event, 0);
+ if (getScriptContext(kEventScript, scriptID)) {
+ _eventQueue.push(LingoEvent(kEventGeneric, eventId, kEventScript, scriptID, true));
+ }
}
break;
case kEventMenuCallback:
- if (getScriptContext(kEventScript, targetId)) {
- _eventQueue.push(LingoEvent(kEventGeneric, eventId, kEventScript, targetId, true));
+ {
+ CastMemberID scriptID = CastMemberID(targetId, 0);
+ if (getScriptContext(kEventScript, scriptID)) {
+ _eventQueue.push(LingoEvent(kEventGeneric, eventId, kEventScript, scriptID, true));
+ }
}
break;
default:
@@ -336,7 +342,7 @@ void Lingo::processEvents() {
}
}
-void Lingo::processEvent(LEvent event, ScriptType st, int scriptId, int channelId) {
+void Lingo::processEvent(LEvent event, ScriptType st, CastMemberID scriptId, int channelId) {
_currentChannelId = channelId;
if (!_eventHandlerTypes.contains(event))
@@ -345,11 +351,11 @@ void Lingo::processEvent(LEvent event, ScriptType st, int scriptId, int channelI
ScriptContext *script = g_director->getCurrentMovie()->getScriptContext(st, scriptId);
if (script && script->_eventHandlers.contains(event)) {
- debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d): executing event handler", _eventHandlerTypes[event], scriptType2str(st), scriptId);
+ debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %s): executing event handler", _eventHandlerTypes[event], scriptType2str(st), scriptId.asString().c_str());
LC::call(script->_eventHandlers[event], 0, false);
execute(_pc);
} else {
- debugC(9, kDebugEvents, "Lingo::processEvent(%s, %s, %d): no handler", _eventHandlerTypes[event], scriptType2str(st), scriptId);
+ debugC(9, kDebugEvents, "Lingo::processEvent(%s, %s, %s): no handler", _eventHandlerTypes[event], scriptType2str(st), scriptId.asString().c_str());
}
}
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 3a70aaa044..ec80c8186b 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -301,15 +301,16 @@ void Lingo::func_play(Datum &frame, Datum &movie) {
func_goto(frame, movie);
}
-void Lingo::func_cursor(int cursorId, int maskId) {
+void Lingo::func_cursor(CastMemberID cursorId, CastMemberID maskId) {
Cursor cursor;
+ cursor.readFromCast(cursorId, maskId);
+ // TODO: Figure out why there are artifacts here
+ _vm->_wm->replaceCursor(cursor._cursorType, ((Graphics::Cursor *)&cursor));
+}
- if (maskId == -1) {
- cursor.readFromResource(cursorId);
- } else {
- cursor.readFromCast(cursorId, maskId);
- }
-
+void Lingo::func_cursor(int cursorId) {
+ Cursor cursor;
+ cursor.readFromResource(cursorId);
// TODO: Figure out why there are artifacts here
_vm->_wm->replaceCursor(cursor._cursorType, ((Graphics::Cursor *)&cursor));
}
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index d0cb4af99a..11f62f4c12 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -593,10 +593,11 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
break;
case kTheMouseCast:
{
+ // TODO: How is this handled with multiple casts in D5?
Common::Point pos = g_director->getCurrentWindow()->getMousePos();
uint16 spriteId = score->getSpriteIDFromPos(pos);
d.type = INT;
- d.u.i = score->getSpriteById(spriteId)->_castId;
+ d.u.i = score->getSpriteById(spriteId)->_castId.member;
if (d.u.i == 0)
d.u.i = -1;
}
@@ -1139,7 +1140,8 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
d.u.i = channel->getBbox().bottom;
break;
case kTheCastNum:
- d.u.i = sprite->_castId;
+ // TODO: How is this handled with multiple casts in D5?
+ d.u.i = sprite->_castId.member;
break;
case kTheConstraint:
d.u.i = channel->_constraint;
@@ -1151,8 +1153,9 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
d.type = ARRAY;
d.u.farr = new DatumArray(2);
- d.u.farr->operator[](0) = (int)channel->_cursor._cursorCastId;
- d.u.farr->operator[](1) = (int)channel->_cursor._cursorMaskId;
+ // TODO: How is this handled with multiple casts in D5?
+ d.u.farr->operator[](0) = (int)channel->_cursor._cursorCastId.member;
+ d.u.farr->operator[](1) = (int)channel->_cursor._cursorMaskId.member;
}
break;
case kTheEditableText:
@@ -1293,11 +1296,11 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
break;
case kTheCastNum:
{
- int castId = d.asCastId();
+ CastMemberID castId = d.asMemberID();
CastMember *castMember = g_director->getCurrentMovie()->getCastMember(castId);
if (castMember && castMember->_type == kCastDigitalVideo) {
- Common::String path = castMember->getCast()->getVideoPath(castId);
+ Common::String path = castMember->getCast()->getVideoPath(castId.member);
if (!path.empty()) {
((DigitalVideoCastMember *)castMember)->loadVideo(pathMakeRelative(path));
((DigitalVideoCastMember *)castMember)->startVideo(channel);
@@ -1321,9 +1324,9 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
if (d.type == CASTREF) {
// Reference: CastMember ID
// Find the first channel that uses this cast.
- int castId = d.u.i;
+ CastMemberID memberID = *d.u.cast;
for (uint i = 0; i < score->_channels.size(); i++) {
- if (score->_channels[i]->_sprite->_castId == castId) {
+ if (score->_channels[i]->_sprite->_castId == memberID) {
channelId = i;
break;
}
@@ -1342,8 +1345,8 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
channel->_cursor.readFromResource(d.asInt());
score->_cursorDirty = true;
} else if (d.type == ARRAY && d.u.farr->size() == 2) {
- uint cursorId = d.u.farr->operator[](0).asCastId();
- uint maskId = d.u.farr->operator[](1).asCastId();
+ CastMemberID cursorId = d.u.farr->operator[](0).asMemberID();
+ CastMemberID maskId = d.u.farr->operator[](1).asMemberID();
if (cursorId == channel->_cursor._cursorCastId &&
maskId == channel->_cursor._cursorMaskId)
@@ -1502,7 +1505,7 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
return d;
}
- int id = id1.asCastId();
+ CastMemberID id = id1.asMemberID();
CastMember *member = movie->getCastMember(id);
if (!member) {
@@ -1517,7 +1520,7 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
}
if (!member->hasField(field)) {
- warning("Lingo::getTheCast(): CastMember %d has no property '%s'", id, field2str(field));
+ warning("Lingo::getTheCast(): %s has no property '%s'", id.asString().c_str(), field2str(field));
return d;
}
@@ -1533,16 +1536,16 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
return;
}
- int id = id1.asCastId();
+ CastMemberID id = id1.asMemberID();
CastMember *member = movie->getCastMember(id);
if (!member) {
- g_lingo->lingoError("Lingo::setTheCast(): CastMember %d not found", id);
+ g_lingo->lingoError("Lingo::setTheCast(): %s not found", id.asString().c_str());
return;
}
if (!member->hasField(field)) {
- warning("Lingo::setTheCast(): CastMember %d has no property '%s'", id, field2str(field));
+ warning("Lingo::setTheCast(): %s has no property '%s'", id.asString().c_str(), field2str(field));
return;
}
@@ -1558,24 +1561,24 @@ Datum Lingo::getTheField(Datum &id1, int field) {
return d;
}
- int id = id1.asCastId();
+ CastMemberID id = id1.asMemberID();
CastMember *member = movie->getCastMember(id);
if (!member) {
if (field == kTheLoaded) {
d = 0;
} else {
- g_lingo->lingoError("Lingo::getTheField(): CastMember %d not found", id);
+ g_lingo->lingoError("Lingo::getTheField(): %s not found", id.asString().c_str());
}
return d;
}
if (member->_type != kCastText) {
- g_lingo->lingoError("Lingo::getTheField(): CastMember %d is not a field", id);
+ g_lingo->lingoError("Lingo::getTheField(): %s is not a field", id.asString().c_str());
return d;
}
if (!member->hasField(field)) {
- warning("Lingo::getTheField(): CastMember %d has no property '%s'", id, field2str(field));
+ warning("Lingo::getTheField(): %s has no property '%s'", id.asString().c_str(), field2str(field));
return d;
}
@@ -1591,20 +1594,20 @@ void Lingo::setTheField(Datum &id1, int field, Datum &d) {
return;
}
- int id = id1.asCastId();
+ CastMemberID id = id1.asMemberID();
CastMember *member = movie->getCastMember(id);
if (!member) {
- g_lingo->lingoError("Lingo::setTheField(): CastMember %d not found", id);
+ g_lingo->lingoError("Lingo::setTheField(): %s not found", id.asString().c_str());
return;
}
if (member->_type != kCastText) {
- g_lingo->lingoError("Lingo::setTheField(): CastMember %d is not a field", id);
+ g_lingo->lingoError("Lingo::setTheField(): %s is not a field", id.asString().c_str());
return;
}
if (!member->hasField(field)) {
- warning("Lingo::setTheField(): CastMember %d has no property '%s'", id, field2str(field));
+ warning("Lingo::setTheField(): %s has no property '%s'", id.asString().c_str(), field2str(field));
return;
}
@@ -1639,18 +1642,19 @@ Datum Lingo::getTheChunk(Datum &chunk, int field) {
return d;
}
- CastMember *member = movie->getCastMember(src.u.i);
+ CastMemberID memberID = *src.u.cast;
+ CastMember *member = movie->getCastMember(memberID);
if (!member) {
- g_lingo->lingoError("Lingo::getTheChunk(): CastMember %d not found", src.u.i);
+ g_lingo->lingoError("Lingo::getTheChunk(): %s not found", memberID.asString().c_str());
return d;
}
if (member->_type != kCastText) {
- g_lingo->lingoError("Lingo::getTheChunk(): CastMember %d is not a field", src.u.i);
+ g_lingo->lingoError("Lingo::getTheChunk(): %s is not a field", memberID.asString().c_str());
return d;
}
if (!((TextCastMember *)member)->hasChunkField(field)) {
- warning("Lingo::getTheChunk(): CastMember %d has no chunk property '%s'", src.u.i, field2str(field));
+ warning("Lingo::getTheChunk(): %s has no chunk property '%s'", memberID.asString().c_str(), field2str(field));
return d;
}
@@ -1685,18 +1689,19 @@ void Lingo::setTheChunk(Datum &chunk, int field, Datum &d) {
return;
}
- CastMember *member = movie->getCastMember(src.u.i);
+ CastMemberID memberID = *src.u.cast;
+ CastMember *member = movie->getCastMember(memberID);
if (!member) {
- g_lingo->lingoError("Lingo::setTheChunk(): CastMember %d not found", src.u.i);
+ g_lingo->lingoError("Lingo::setTheChunk(): %s not found", memberID.asString().c_str());
return;
}
if (member->_type != kCastText) {
- g_lingo->lingoError("Lingo::setTheChunk(): CastMember %d is not a field", src.u.i);
+ g_lingo->lingoError("Lingo::setTheChunk(): %s is not a field", memberID.asString().c_str());
return;
}
if (!((TextCastMember *)member)->hasChunkField(field)) {
- warning("Lingo::setTheChunk(): CastMember %d has no chunk property '%s'", src.u.i, field2str(field));
+ warning("Lingo::setTheChunk(): %s has no chunk property '%s'", memberID.asString().c_str(), field2str(field));
return;
}
@@ -1730,13 +1735,13 @@ void Lingo::getObjectProp(Datum &obj, Common::String &propName) {
return;
}
- int id = obj.u.i;
+ CastMemberID id = *obj.u.cast;
CastMember *member = movie->getCastMember(id);
if (!member) {
if (propName.equalsIgnoreCase("loaded")) {
d = 0;
} else {
- g_lingo->lingoError("Lingo::getObjectProp(): CastMember %d not found", id);
+ g_lingo->lingoError("Lingo::getObjectProp(): %s not found", id.asString().c_str());
}
g_lingo->push(d);
return;
@@ -1745,7 +1750,7 @@ void Lingo::getObjectProp(Datum &obj, Common::String &propName) {
if (member->hasProp(propName)) {
d = member->getProp(propName);
} else {
- g_lingo->lingoError("Lingo::getObjectProp(): CastMember %d has no property '%s'", id, propName.c_str());
+ g_lingo->lingoError("Lingo::getObjectProp(): %s has no property '%s'", id.asString().c_str(), propName.c_str());
}
g_lingo->push(d);
return;
@@ -1781,17 +1786,17 @@ void Lingo::setObjectProp(Datum &obj, Common::String &propName, Datum &val) {
return;
}
- int id = obj.u.i;
+ CastMemberID id = *obj.u.cast;
CastMember *member = movie->getCastMember(id);
if (!member) {
- g_lingo->lingoError("Lingo::setObjectProp(): CastMember %d not found", id);
+ g_lingo->lingoError("Lingo::setObjectProp(): %s not found", id.asString().c_str());
return;
}
if (member->hasProp(propName)) {
member->setProp(propName, val);
} else {
- g_lingo->lingoError("Lingo::setObjectProp(): CastMember %d has no property '%s'", id, propName.c_str());
+ g_lingo->lingoError("Lingo::setObjectProp(): %s has no property '%s'", id.asString().c_str(), propName.c_str());
}
} else {
g_lingo->lingoError("Lingo::setObjectProp: Invalid object: %s", obj.asString(true).c_str());
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index b3b6906e04..9c5d1e2dd2 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -449,7 +449,7 @@ void Lingo::execute(uint pc) {
_abort = false;
}
-void Lingo::executeScript(ScriptType type, uint16 id) {
+void Lingo::executeScript(ScriptType type, CastMemberID id) {
Movie *movie = _vm->getCurrentMovie();
if (!movie) {
warning("Request to execute script with no movie");
@@ -459,16 +459,16 @@ void Lingo::executeScript(ScriptType type, uint16 id) {
ScriptContext *sc = movie->getScriptContext(type, id);
if (!sc) {
- debugC(3, kDebugLingoExec, "Request to execute non-existent script type %d id %d", type, id);
+ debugC(3, kDebugLingoExec, "Request to execute non-existent script type %d id %d of castLib %d", type, id.member, id.castLib);
return;
}
if (!sc->_eventHandlers.contains(kEventGeneric)) {
- debugC(3, kDebugLingoExec, "Request to execute script type %d id %d with no scopeless lingo", type, id);
+ debugC(3, kDebugLingoExec, "Request to execute script type %d id %d of castLib %d with no scopeless lingo", type, id.member, id.castLib);
return;
}
- debugC(1, kDebugLingoExec, "Executing script type: %s, id: %d", scriptType2str(type), id);
+ debugC(1, kDebugLingoExec, "Executing script type: %s, id: %d, castLib %d", scriptType2str(type), id.member, id.castLib);
Symbol sym = sc->_eventHandlers[kEventGeneric];
LC::call(sym, 0, false);
@@ -625,6 +625,13 @@ Datum::Datum(AbstractObject *val) {
}
}
+Datum::Datum(const CastMemberID &val) {
+ u.cast = new CastMemberID(val);
+ type = CASTREF;
+ refCount = new int;
+ *refCount = 1;
+}
+
void Datum::reset() {
if (!refCount)
return;
@@ -664,6 +671,10 @@ void Datum::reset() {
case CHUNKREF:
delete u.cref;
break;
+ case CASTREF:
+ case FIELDREF:
+ delete u.cast;
+ break;
default:
break;
}
@@ -802,20 +813,10 @@ Common::String Datum::asString(bool printonly) const {
s = Common::String::format("property: #%s", u.s->c_str());
break;
case CASTREF:
- s = Common::String::format("cast %d", u.i);
+ s = Common::String::format("member %d of castLib %d", u.cast->member, u.cast->castLib);
break;
case FIELDREF:
- {
- int idx = u.i;
- CastMember *member = g_director->getCurrentMovie()->getCastMember(idx);
- if (!member) {
- warning("asString(): Unknown cast id %d", idx);
- s = "";
- break;
- }
-
- s = Common::String::format("field: \"%s\"", ((TextCastMember *)member)->getText().c_str());
- }
+ s = Common::String::format("field %d of castLib %d", u.cast->member, u.cast->castLib);
break;
case CHUNKREF:
{
@@ -875,40 +876,11 @@ Common::String Datum::asString(bool printonly) const {
return s;
}
-int Datum::asCastId() const {
- Movie *movie = g_director->getCurrentMovie();
- if (!movie) {
- warning("Datum::asCastId: No movie");
- return 0;
- }
-
- int castId = 0;
- switch (type) {
- case STRING:
- {
- CastMember *member = movie->getCastMemberByName(asString());
- if (member)
- return member->getID();
-
- warning("Datum::asCastId: reference to non-existent cast member: %s", asString().c_str());
- return -1;
- }
- break;
- case INT:
- case CASTREF:
- castId = u.i;
- break;
- case FLOAT:
- castId = u.f;
- break;
- case VOID:
- warning("Datum::asCastId: reference to VOID cast ID");
- break;
- default:
- error("Datum::asCastId: unsupported cast ID type %s", type2str());
- }
+CastMemberID Datum::asMemberID() const {
+ if (type == CASTREF || type == FIELDREF)
+ return *u.cast;
- return castId;
+ return g_lingo->resolveCastMember(*this, 0);
}
bool Datum::isRef() const {
@@ -1056,7 +1028,7 @@ void Lingo::runTests() {
if (!debugChannelSet(-1, kDebugCompileOnly)) {
if (!_compiler->_hadError)
- executeScript(kTestScript, counter);
+ executeScript(kTestScript, CastMemberID(counter, 0));
else
debug(">> Skipping execution");
}
@@ -1072,7 +1044,7 @@ void Lingo::runTests() {
void Lingo::executeImmediateScripts(Frame *frame) {
for (uint16 i = 0; i <= _vm->getCurrentMovie()->getScore()->_numChannelsDisplayed; i++) {
- if (_vm->getCurrentMovie()->getScore()->_immediateActions.contains(frame->_sprites[i]->_scriptId)) {
+ if (_vm->getCurrentMovie()->getScore()->_immediateActions.contains(frame->_sprites[i]->_scriptId.member)) {
// From D5 only explicit event handlers are processed
// Before that you could specify commands which will be executed on mouse up
if (_vm->getVersion() < 500)
@@ -1189,10 +1161,9 @@ void Lingo::varAssign(const Datum &var, const Datum &value) {
warning("varAssign: Assigning to a reference to an empty movie");
return;
}
- int castId = var.u.i;
- CastMember *member = movie->getCastMember(castId);
+ CastMember *member = movie->getCastMember(*var.u.cast);
if (!member) {
- warning("varAssign: Unknown cast id %d", castId);
+ warning("varAssign: Unknown %s", var.u.cast->asString().c_str());
return;
}
switch (member->_type) {
@@ -1310,10 +1281,9 @@ Datum Lingo::varFetch(const Datum &var, bool silent) {
warning("varFetch: Assigning to a reference to an empty movie");
return result;
}
- int castId = var.u.i;
- CastMember *member = movie->getCastMember(castId);
+ CastMember *member = movie->getCastMember(*var.u.cast);
if (!member) {
- warning("varFetch: Unknown cast id %d", castId);
+ warning("varFetch: Unknown %s", var.u.cast->asString().c_str());
return result;
}
switch (member->_type) {
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 036bd1d2fb..89ada9dc2b 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -112,6 +112,7 @@ struct Datum { /* interpreter stack type */
PropertyArray *parr; /* PARRAY */
AbstractObject *obj; /* OBJECT */
ChunkReference *cref; /* CHUNKREF */
+ CastMemberID *cast; /* CASTREF, FIELDREF */
} u;
int *refCount;
@@ -123,6 +124,7 @@ struct Datum { /* interpreter stack type */
Datum(double val);
Datum(const Common::String &val);
Datum(AbstractObject *val);
+ Datum(const CastMemberID &val);
void reset();
~Datum() {
@@ -133,7 +135,7 @@ struct Datum { /* interpreter stack type */
double asFloat() const;
int asInt() const;
Common::String asString(bool printonly = false) const;
- int asCastId() const;
+ CastMemberID asMemberID() const;
bool isRef() const;
bool isVarRef() const;
@@ -199,11 +201,11 @@ struct LingoEvent {
LEvent event;
int eventId;
ScriptType scriptType;
- int scriptId;
+ CastMemberID scriptId;
bool passByDefault;
int channelId;
- LingoEvent (LEvent e, int ei, ScriptType st, int si, bool pass, int ci = -1) {
+ LingoEvent (LEvent e, int ei, ScriptType st, CastMemberID si, bool pass, int ci = -1) {
event = e;
eventId = ei;
scriptType = st;
@@ -242,7 +244,7 @@ public:
void resetLingo();
void executeHandler(const Common::String &name);
- void executeScript(ScriptType type, uint16 id);
+ void executeScript(ScriptType type, CastMemberID id);
void printStack(const char *s, uint pc);
void printCallStack(uint pc);
Common::String decodeInstruction(LingoArchive *archive, ScriptData *sd, uint pc, uint *newPC = NULL);
@@ -264,7 +266,7 @@ public:
// lingo-events.cpp
private:
void initEventHandlerTypes();
- void processEvent(LEvent event, ScriptType st, int entityId, int channelId = -1);
+ void processEvent(LEvent event, ScriptType st, CastMemberID scriptId, int channelId = -1);
public:
ScriptType event2script(LEvent ev);
@@ -313,7 +315,8 @@ public:
void func_gotoprevious();
void func_play(Datum &frame, Datum &movie);
void func_playdone();
- void func_cursor(int cursorId, int maskId);
+ void func_cursor(CastMemberID cursorId, CastMemberID maskId);
+ void func_cursor(int cursorId);
int func_marker(int m);
uint16 func_label(Datum &label);
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index 2516d6cc6b..7229e23d62 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -296,34 +296,54 @@ void Movie::loadSharedCastsFrom(Common::String filename) {
_sharedCast->loadArchive();
}
-CastMember *Movie::getCastMember(int castId) {
- CastMember *result = _cast->getCastMember(castId);
- if (result == nullptr && _sharedCast) {
- result = _sharedCast->getCastMember(castId);
+CastMember *Movie::getCastMember(CastMemberID memberID) {
+ CastMember *result = nullptr;
+ if (memberID.castLib == 0) {
+ result = _cast->getCastMember(memberID.member);
+ if (result == nullptr && _sharedCast) {
+ result = _sharedCast->getCastMember(memberID.member);
+ }
+ } else {
+ warning("Movie::getCastMember: Unknown castLib %d", memberID.castLib);
}
return result;
}
-CastMember *Movie::getCastMemberByName(const Common::String &name) {
- CastMember *result = _cast->getCastMemberByName(name);
- if (result == nullptr && _sharedCast) {
- result = _sharedCast->getCastMemberByName(name);
+CastMember *Movie::getCastMemberByName(const Common::String &name, int castLib) {
+ CastMember *result = nullptr;
+ if (castLib == 0) {
+ result = _cast->getCastMemberByName(name);
+ if (result == nullptr && _sharedCast) {
+ result = _sharedCast->getCastMemberByName(name);
+ }
+ } else {
+ warning("Movie::getCastMemberByName: Unknown castLib %d", castLib);
}
return result;
}
-CastMemberInfo *Movie::getCastMemberInfo(int castId) {
- CastMemberInfo *result = _cast->getCastMemberInfo(castId);
- if (result == nullptr && _sharedCast) {
- result = _sharedCast->getCastMemberInfo(castId);
+CastMemberInfo *Movie::getCastMemberInfo(CastMemberID memberID) {
+ CastMemberInfo *result = nullptr;
+ if (memberID.castLib == 0) {
+ result = _cast->getCastMemberInfo(memberID.member);
+ if (result == nullptr && _sharedCast) {
+ result = _sharedCast->getCastMemberInfo(memberID.member);
+ }
+ } else {
+ warning("Movie::getCastMemberInfo: Unknown castLib %d", memberID.castLib);
}
return result;
}
-const Stxt *Movie::getStxt(int castId) {
- const Stxt *result = _cast->getStxt(castId);
- if (result == nullptr && _sharedCast) {
- result = _sharedCast->getStxt(castId);
+const Stxt *Movie::getStxt(CastMemberID memberID) {
+ const Stxt *result = nullptr;
+ if (memberID.castLib == 0) {
+ result = _cast->getStxt(memberID.member);
+ if (result == nullptr && _sharedCast) {
+ result = _sharedCast->getStxt(memberID.member);
+ }
+ } else {
+ warning("Movie::getStxt: Unknown castLib %d", memberID.castLib);
}
return result;
}
@@ -336,10 +356,15 @@ LingoArchive *Movie::getSharedLingoArch() {
return _sharedCast ? _sharedCast->_lingoArchive : nullptr;
}
-ScriptContext *Movie::getScriptContext(ScriptType type, uint16 id) {
- ScriptContext *result = _cast->_lingoArchive->getScriptContext(type, id);
- if (result == nullptr && _sharedCast) {
- result = _sharedCast->_lingoArchive->getScriptContext(type, id);
+ScriptContext *Movie::getScriptContext(ScriptType type, CastMemberID id) {
+ ScriptContext *result = nullptr;
+ if (id.castLib == 0) {
+ result = _cast->_lingoArchive->getScriptContext(type, id.member);
+ if (result == nullptr && _sharedCast) {
+ result = _sharedCast->_lingoArchive->getScriptContext(type, id.member);
+ }
+ } else {
+ warning("Movie::getScriptContext: Unknown castLib %d", id.castLib);
}
return result;
}
diff --git a/engines/director/movie.h b/engines/director/movie.h
index 2e84544070..59ac8b6723 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -117,14 +117,14 @@ public:
void clearSharedCast();
void loadSharedCastsFrom(Common::String filename);
- CastMember *getCastMember(int castId);
- CastMember *getCastMemberByName(const Common::String &name);
- CastMemberInfo *getCastMemberInfo(int castId);
- const Stxt *getStxt(int castId);
+ CastMember *getCastMember(CastMemberID memberID);
+ CastMember *getCastMemberByName(const Common::String &name, int castLib);
+ CastMemberInfo *getCastMemberInfo(CastMemberID memberID);
+ const Stxt *getStxt(CastMemberID memberID);
LingoArchive *getMainLingoArch();
LingoArchive *getSharedLingoArch();
- ScriptContext *getScriptContext(ScriptType type, uint16 id);
+ ScriptContext *getScriptContext(ScriptType type, CastMemberID id);
Symbol getHandler(const Common::String &name);
// events.cpp
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index d36290f161..1c529ba9bb 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -98,8 +98,9 @@ int Score::getCurrentPalette() {
}
int Score::resolvePaletteId(int id) {
+ // TODO: Palette ID should be a CastMemberID to allow for palettes in different casts
if (id > 0) {
- CastMember *member = _movie->getCastMember(id);
+ CastMember *member = _movie->getCastMember(CastMemberID(id, 0));
id = (member && member->_type == kCastPalette) ? ((PaletteCastMember *)member)->getPaletteId() : 0;
}
@@ -458,7 +459,7 @@ void Score::renderFrame(uint16 frameId, RenderMode mode) {
if (mode != kRenderNoWindowRender)
_window->render();
- if (_frames[frameId]->_sound1 || _frames[frameId]->_sound2)
+ if (_frames[frameId]->_sound1.member || _frames[frameId]->_sound2.member)
playSoundChannel(frameId);
if (_cursorDirty) {
@@ -513,7 +514,7 @@ void Score::renderSprites(uint16 frameId, RenderMode mode) {
_movie->_videoPlayback = true;
_window->addDirtyRect(channel->getBbox());
- debugC(2, kDebugImages, "Score::renderSprites(): CH: %-3d castId: %03d(%s) [ink: %d, puppet: %d, moveable: %d, visible: %d] [bbox: %d,%d,%d,%d] [type: %d fg: %d bg: %d] [script: %d]", i, currentSprite->_castId, numToCastNum(currentSprite->_castId), currentSprite->_ink, currentSprite->_puppet, currentSprite->_moveable, channel->_visible, PRINT_RECT(channel->getBbox()), currentSprite->_spriteType, currentSprite->_foreColor, currentSprite->_backColor, currentSprite->_scriptId);
+ debugC(2, kDebugImages, "Score::renderSprites(): CH: %-3d castId: %s [ink: %d, puppet: %d, moveable: %d, visible: %d] [bbox: %d,%d,%d,%d] [type: %d fg: %d bg: %d] [script: %s]", i, currentSprite->_castId.asString().c_str(), currentSprite->_ink, currentSprite->_puppet, currentSprite->_moveable, channel->_visible, PRINT_RECT(channel->getBbox()), currentSprite->_spriteType, currentSprite->_foreColor, currentSprite->_backColor, currentSprite->_scriptId.asString().c_str());
} else {
channel->setClean(nextSprite, i, true);
}
@@ -618,7 +619,7 @@ Common::List<Channel *> Score::getSpriteIntersections(const Common::Rect &r) {
return intersections;
}
-uint16 Score::getSpriteIdByMemberId(uint16 id) {
+uint16 Score::getSpriteIdByMemberId(CastMemberID id) {
for (uint i = 0; i < _channels.size(); i++)
if (_channels[i]->_sprite->_castId == id)
return i;
@@ -657,7 +658,7 @@ Channel *Score::getChannelById(uint16 id) {
void Score::playSoundChannel(uint16 frameId) {
Frame *frame = _frames[frameId];
- debugC(5, kDebugLoading, "playSoundChannel(): Sound1 %d Sound2 %d", frame->_sound1, frame->_sound2);
+ debugC(5, kDebugLoading, "playSoundChannel(): Sound1 %s Sound2 %s", frame->_sound1.asString().c_str(), frame->_sound2.asString().c_str());
DirectorSound *sound = _vm->getSoundManager();
sound->playCastMember(frame->_sound1, 1, false);
sound->playCastMember(frame->_sound2, 2, false);
@@ -776,7 +777,7 @@ void Score::loadFrames(Common::SeekableReadStreamEndian &stream, uint16 version)
frame->readChannels(str, version);
delete str;
- debugC(8, kDebugLoading, "Score::loadFrames(): Frame %d actionId: %d", _frames.size(), frame->_actionId);
+ debugC(8, kDebugLoading, "Score::loadFrames(): Frame %d actionId: %s", _frames.size(), frame->_actionId.asString().c_str());
_frames.push_back(frame);
} else {
@@ -792,7 +793,7 @@ void Score::setSpriteCasts() {
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);
+ debugC(1, kDebugImages, "Score::setSpriteCasts(): Frame: %d Channel: %d castId: %s type: %d", i, j, _frames[i]->_sprites[j]->_castId.asString().c_str(), _frames[i]->_sprites[j]->_spriteType);
}
}
}
@@ -886,12 +887,12 @@ void Score::loadActions(Common::SeekableReadStreamEndian &stream) {
// 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;
+ if ((uint)_frames[i]->_actionId.member <= _actions.size())
+ scriptRefs[_frames[i]->_actionId.member] = 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;
+ if ((uint)_frames[i]->_sprites[j]->_scriptId.member <= _actions.size())
+ scriptRefs[_frames[i]->_sprites[j]->_scriptId.member] = true;
}
}
diff --git a/engines/director/score.h b/engines/director/score.h
index 6447d9aa2b..3b8ddb6601 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -106,7 +106,7 @@ public:
uint16 getActiveSpriteIDFromPos(Common::Point pos);
bool checkSpriteIntersection(uint16 spriteId, Common::Point pos);
Common::List<Channel *> getSpriteIntersections(const Common::Rect &r);
- uint16 getSpriteIdByMemberId(uint16 id);
+ uint16 getSpriteIdByMemberId(CastMemberID id);
bool renderTransition(uint16 frameId);
void renderFrame(uint16 frameId, RenderMode mode = kRenderModeNormal);
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 51d93b848a..008650705d 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -95,21 +95,21 @@ void DirectorSound::playStream(Audio::AudioStream &stream, uint8 soundChannel) {
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, &stream, -1, _channels[soundChannel - 1].volume);
}
-void DirectorSound::playCastMember(int castId, uint8 soundChannel, bool allowRepeat) {
- if (castId == 0) {
+void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bool allowRepeat) {
+ if (memberID.member == 0) {
stopSound(soundChannel);
} else {
- CastMember *soundCast = _vm->getCurrentMovie()->getCastMember(castId);
+ CastMember *soundCast = _vm->getCurrentMovie()->getCastMember(memberID);
if (soundCast) {
if (soundCast->_type != kCastSound) {
- warning("DirectorSound::playCastMember: attempted to play a non-SoundCastMember cast member %d", castId);
+ warning("DirectorSound::playCastMember: attempted to play a non-SoundCastMember %s", memberID.asString().c_str());
} else {
- if (!allowRepeat && lastPlayingCast(soundChannel) == castId)
+ if (!allowRepeat && lastPlayingCast(soundChannel) == memberID)
return;
bool looping = ((SoundCastMember *)soundCast)->_looping;
AudioDecoder *ad = ((SoundCastMember *)soundCast)->_audio;
if (!ad) {
- warning("DirectorSound::playCastMember: no audio data attached to cast member %d", castId);
+ warning("DirectorSound::playCastMember: no audio data attached to %s", memberID.asString().c_str());
return;
}
Audio::AudioStream *as;
@@ -122,10 +122,10 @@ void DirectorSound::playCastMember(int castId, uint8 soundChannel, bool allowRep
return;
}
playStream(*as, soundChannel);
- _channels[soundChannel - 1].lastPlayingCast = castId;
+ _channels[soundChannel - 1].lastPlayingCast = memberID;
}
} else {
- warning("DirectorSound::playCastMember: couldn't find cast member %d", castId);
+ warning("DirectorSound::playCastMember: couldn't find %s", memberID.asString().c_str());
}
}
}
@@ -194,9 +194,9 @@ bool DirectorSound::isChannelValid(uint8 soundChannel) {
return true;
}
-int DirectorSound::lastPlayingCast(uint8 soundChannel) {
+CastMemberID DirectorSound::lastPlayingCast(uint8 soundChannel) {
if (!isChannelValid(soundChannel))
- return false;
+ return CastMemberID(0, 0);
return _channels[soundChannel - 1].lastPlayingCast;
}
@@ -207,7 +207,7 @@ void DirectorSound::stopSound(uint8 soundChannel) {
cancelFade(soundChannel);
_mixer->stopHandle(_channels[soundChannel - 1].handle);
- _channels[soundChannel - 1].lastPlayingCast = 0;
+ _channels[soundChannel - 1].lastPlayingCast = CastMemberID(0, 0);
return;
}
@@ -216,7 +216,7 @@ void DirectorSound::stopSound() {
cancelFade(i + 1);
_mixer->stopHandle(_channels[i].handle);
- _channels[i].lastPlayingCast = 0;
+ _channels[i].lastPlayingCast = CastMemberID(0, 0);
}
_mixer->stopHandle(_scriptSound);
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 85eab9d949..b9147065d5 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -48,11 +48,11 @@ struct FadeParams {
struct SoundChannel {
Audio::SoundHandle handle;
- int lastPlayingCast;
+ CastMemberID lastPlayingCast;
byte volume;
FadeParams *fade;
- SoundChannel(): handle(), lastPlayingCast(0), volume(255), fade(nullptr) {}
+ SoundChannel(): handle(), volume(255), fade(nullptr) {}
};
class DirectorSound {
@@ -73,14 +73,14 @@ public:
void playFile(Common::String filename, uint8 soundChannel);
void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
void playStream(Audio::AudioStream &stream, uint8 soundChannel);
- void playCastMember(int castId, uint8 soundChannel, bool allowRepeat = true);
+ void playCastMember(CastMemberID memberID, uint8 soundChannel, bool allowRepeat = true);
void systemBeep();
void registerFade(uint8 soundChannel, bool fadeIn, int ticks);
bool fadeChannel(uint8 soundChannel);
bool isChannelActive(uint8 soundChannel);
- int lastPlayingCast(uint8 soundChannel);
+ CastMemberID lastPlayingCast(uint8 soundChannel);
void stopSound(uint8 soundChannel);
void stopSound();
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 5e0b241484..53ddf5512d 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -38,17 +38,15 @@ Sprite::Sprite(Frame *frame) {
_score = _frame->getScore();
_movie = _score->getMovie();
- _scriptId = 0;
- _scriptCastIndex = 0;
+ _scriptId = CastMemberID(0, 0);
_colorcode = 0;
_blendAmount = 0;
_unk3 = 0;
_enabled = false;
- _castId = 0;
+ _castId = CastMemberID(0, 0);
_pattern = 0;
- _castIndex = 0;
_spriteType = kInactiveSprite;
_inkData = 0;
_ink = kInkTypeCopy;
@@ -263,11 +261,11 @@ void Sprite::setPattern(uint16 pattern) {
}
}
-void Sprite::setCast(uint16 castId) {
- CastMember *member = _movie->getCastMember(castId);
- _castId = castId;
+void Sprite::setCast(CastMemberID memberID) {
+ CastMember *member = _movie->getCastMember(memberID);
+ _castId = memberID;
- if (castId == 0)
+ if (memberID.member == 0)
return;
if (member) {
@@ -293,7 +291,7 @@ void Sprite::setCast(uint16 castId) {
_height = dims.height();
}
} else {
- warning("Sprite::setCast(): CastMember id %d(%s) has null member", castId, numToCastNum(castId));
+ warning("Sprite::setCast(): %s has null member", memberID.asString().c_str());
}
}
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 02faa8651b..233cae70e8 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -74,7 +74,7 @@ public:
uint16 getPattern();
void setPattern(uint16 pattern);
- void setCast(uint16 castid);
+ void setCast(CastMemberID memberID);
bool isQDShape();
Graphics::Surface *getQDMatte();
void createQDMatte();
@@ -83,20 +83,18 @@ public:
Score *_score;
Movie *_movie;
- uint16 _scriptId;
- uint16 _scriptCastIndex;
+ CastMemberID _scriptId;
byte _colorcode; // x40 editable, 0x80 moveable
byte _blendAmount;
uint32 _unk3;
bool _enabled;
- uint16 _castIndex;
SpriteType _spriteType;
byte _inkData;
InkType _ink;
uint16 _trails;
- uint16 _castId;
+ CastMemberID _castId;
uint16 _pattern;
CastMember *_cast;
diff --git a/engines/director/types.h b/engines/director/types.h
index ed2fcdd844..78c9e702d7 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -378,7 +378,7 @@ struct CastMemberID {
return member != c.member || castLib != c.castLib;
}
- const char *str() const;
+ Common::String asString() const;
};
struct Datum;
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index e6cf0d99e0..07667a8f3c 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -201,15 +201,13 @@ char *numToCastNum(int num) {
return res;
}
-const char *CastMemberID::str() const {
- static char res[40];
+Common::String CastMemberID::asString() const {
+ Common::String res = Common::String::format("member %d", member);
if (g_director->getVersion() < 400 || g_director->getCurrentMovie()->_allowOutdatedLingo)
- snprintf(res, 40, "member %d(%s)", member, numToCastNum(member));
- else if (g_director->getVersion() < 500)
- snprintf(res, 40, "member %d", member);
- else
- snprintf(res, 40, "member %d of castLib %d", member, castLib);
+ res += "(" + Common::String(numToCastNum(member)) + ")";
+ else if (g_director->getVersion() >= 500)
+ res += Common::String::format(" of castLib %d", castLib);
return res;
}
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 2f93c7eea2..9d72bbd281 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -173,7 +173,7 @@ void Window::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::Mana
inkBlitSurface(&pd, srcRect, channel->getMask());
}
} else {
- warning("Window::inkBlitFrom: No source surface: spriteType: %d, castType: %d, castId: %d", channel->_sprite->_spriteType, channel->_sprite->_cast ? channel->_sprite->_cast->_type : 0, channel->_sprite->_castId);
+ warning("Window::inkBlitFrom: No source surface: spriteType: %d, castType: %d, castId: %s", channel->_sprite->_spriteType, channel->_sprite->_cast ? channel->_sprite->_cast->_type : 0, channel->_sprite->_castId.asString().c_str());
}
}
Commit: 8bbd6da3a430eb91f288e22212f86b851ce766be
https://github.com/scummvm/scummvm/commit/8bbd6da3a430eb91f288e22212f86b851ce766be
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-30T22:32:19-04:00
Commit Message:
DIRECTOR: LINGO: Remove unbalanced 'end if' patches
This is handled in the grammar now.
Changed paths:
engines/director/lingo/lingo-patcher.cpp
diff --git a/engines/director/lingo/lingo-patcher.cpp b/engines/director/lingo/lingo-patcher.cpp
index 500e276ca5..6d728b3a2e 100644
--- a/engines/director/lingo/lingo-patcher.cpp
+++ b/engines/director/lingo/lingo-patcher.cpp
@@ -101,14 +101,6 @@ struct ScriptPatch {
{"warlock", nullptr, kPlatformMacintosh, "DATA/K/KT/OutMarauderKT", kMovieScript, 2,
23, "set Spacesuit = 0 then", "set Spacesuit = 0"},
- // Unbalanced 'end if' at the end of the script
- {"warlock", nullptr, kPlatformMacintosh, "DATA/STAMBUL/DRUNK", kMovieScript, 4,
- 5, "end if", ""},
-
- // Unbalanced 'end if' at the end of the script
- {"warlock", nullptr, kPlatformMacintosh, "STAMBUL/DRUNK", kMovieScript, 5,
- 5, "end if", ""},
-
// Missing '&'
{"warlock", nullptr, kPlatformMacintosh, "DATA/NAV/Shared Cast", kMovieScript, 1,
19, "alert \"Failed Save.\" & return & \"Error message number: \" string ( filer )",
@@ -122,10 +114,6 @@ struct ScriptPatch {
{"warlock", "", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12,
4, "Frames 150 to 160", ""},
- // Unbalanced 'end if' at the end of the script
- {"warlock", "", kPlatformWindows, "STAMBUL/DRUNK", kMovieScript, 5,
- 5, "end if", ""},
-
// Missing '&'
{"warlock", nullptr, kPlatformUnknown, "NAV/Shared Cast", kMovieScript, 0,
23, "alert \"Failed Save.\" & return & \"Error message number: \" string ( filer )",
@@ -156,9 +144,6 @@ struct ScriptPatch {
"GO \"SPACE\" OF MOVIE \"L-ZONE:DATA:R-G:ST-A2\""},
- // Unbalanced 'end if' at the end of the script
- {"jman", "", kPlatformWindows, "mmm/TSA RR 06", kScoreScript, 26,
- 17, "end if", ""},
{"jman", "", kPlatformWindows, "mmm/Mars Space Game 05", kMovieScript, 3,
68, "set DamageParameter = (gProcessorSpeed/2) + 7)", "set DamageParameter = (gProcessorSpeed/2) + 7"},
Commit: 8dfa5f4e737fe12b8666808872e62c62c41253a7
https://github.com/scummvm/scummvm/commit/8dfa5f4e737fe12b8666808872e62c62c41253a7
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-30T22:32:19-04:00
Commit Message:
DIRECTOR: LINGO: Use member ID as script ID in D2-3
Movie scripts have a corresponding text cast member, so it makes sense
to have the IDs match.
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
engines/director/movie.cpp
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 78f1ce6d2a..e7cdc09992 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -70,7 +70,6 @@ Cast::Cast(Movie *movie, bool isShared) {
_lingoArchive = new LingoArchive(this);
- _movieScriptCount = 0;
_castArrayStart = _castArrayEnd = 0;
_castIDoffset = 0;
@@ -432,7 +431,7 @@ void Cast::loadCast() {
if (debugChannelSet(-1, kDebugFewFramesOnly))
warning("Compiling STXT %d", *iterator);
- loadScriptText(*(r = _castArchive->getResource(MKTAG('S','T','X','T'), *iterator)));
+ loadScriptText(*(r = _castArchive->getResource(MKTAG('S','T','X','T'), *iterator)), *iterator - _castIDoffset);
delete r;
}
@@ -1023,7 +1022,7 @@ void Cast::loadLingoContext(Common::SeekableReadStreamEndian &stream) {
}
}
-void Cast::loadScriptText(Common::SeekableReadStreamEndian &stream) {
+void Cast::loadScriptText(Common::SeekableReadStreamEndian &stream, uint16 id) {
/*uint32 unk1 = */ stream.readUint32();
uint32 strLen = stream.readUint32();
/*uin32 dataLen = */ stream.readUint32();
@@ -1045,14 +1044,12 @@ void Cast::loadScriptText(Common::SeekableReadStreamEndian &stream) {
return;
if (ConfMan.getBool("dump_scripts"))
- dumpScript(script.c_str(), kMovieScript, _movieScriptCount);
+ dumpScript(script.c_str(), kMovieScript, id);
if (script.contains("\nmenu:") || script.hasPrefix("menu:"))
return;
- _lingoArchive->addCode(script.c_str(), kMovieScript, _movieScriptCount);
-
- _movieScriptCount++;
+ _lingoArchive->addCode(script.c_str(), kMovieScript, id);
}
void Cast::dumpScript(const char *script, ScriptType type, uint16 id) {
diff --git a/engines/director/cast.h b/engines/director/cast.h
index dc342e6ab4..2a578a419a 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -80,7 +80,7 @@ public:
private:
PaletteV4 loadPalette(Common::SeekableReadStreamEndian &stream);
- void loadScriptText(Common::SeekableReadStreamEndian &stream);
+ void loadScriptText(Common::SeekableReadStreamEndian &stream, uint16 id);
void loadFontMap(Common::SeekableReadStreamEndian &stream);
Common::String getString(Common::String str);
@@ -100,7 +100,6 @@ public:
uint16 _stageColor;
int _defaultPalette;
- uint16 _movieScriptCount;
LingoArchive *_lingoArchive;
private:
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index 7229e23d62..d734223ccd 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -230,12 +230,11 @@ void Movie::loadFileInfo(Common::SeekableReadStreamEndian &stream) {
_script = fileInfo.strings[0].readString(false);
if (!_script.empty() && ConfMan.getBool("dump_scripts"))
- _cast->dumpScript(_script.c_str(), kMovieScript, _cast->_movieScriptCount);
+ _cast->dumpScript(_script.c_str(), kMovieScript, 0);
if (!_script.empty())
- _cast->_lingoArchive->addCode(_script.c_str(), kMovieScript, _cast->_movieScriptCount);
+ _cast->_lingoArchive->addCode(_script.c_str(), kMovieScript, 0);
- _cast->_movieScriptCount++;
_changedBy = fileInfo.strings[1].readString();
_createdBy = fileInfo.strings[2].readString();
_createdBy = fileInfo.strings[3].readString();
Commit: b27696e49c36760f751c7d3e7f2549765636321f
https://github.com/scummvm/scummvm/commit/b27696e49c36760f751c7d3e7f2549765636321f
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-30T22:32:19-04:00
Commit Message:
DIRECTOR: LINGO: Fix movie script IDs in patcher
Changed paths:
engines/director/lingo/lingo-patcher.cpp
diff --git a/engines/director/lingo/lingo-patcher.cpp b/engines/director/lingo/lingo-patcher.cpp
index 6d728b3a2e..c126aee3c3 100644
--- a/engines/director/lingo/lingo-patcher.cpp
+++ b/engines/director/lingo/lingo-patcher.cpp
@@ -98,11 +98,11 @@ struct ScriptPatch {
4, "Frames 20 to 20", ""},
// Stray 'then' (obvious copy/paste error)
- {"warlock", nullptr, kPlatformMacintosh, "DATA/K/KT/OutMarauderKT", kMovieScript, 2,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/K/KT/OutMarauderKT", kMovieScript, 14,
23, "set Spacesuit = 0 then", "set Spacesuit = 0"},
// Missing '&'
- {"warlock", nullptr, kPlatformMacintosh, "DATA/NAV/Shared Cast", kMovieScript, 1,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/NAV/Shared Cast", kMovieScript, 510,
19, "alert \"Failed Save.\" & return & \"Error message number: \" string ( filer )",
"alert \"Failed Save.\" & return & \"Error message number: \" & string ( filer )"},
@@ -115,11 +115,7 @@ struct ScriptPatch {
4, "Frames 150 to 160", ""},
// Missing '&'
- {"warlock", nullptr, kPlatformUnknown, "NAV/Shared Cast", kMovieScript, 0,
- 23, "alert \"Failed Save.\" & return & \"Error message number: \" string ( filer )",
- "alert \"Failed Save.\" & return & \"Error message number: \" & string ( filer )"},
-
- {"warlock", nullptr, kPlatformUnknown, "NAV/Shared Cast", kMovieScript, 1, // For running by the buildbot
+ {"warlock", nullptr, kPlatformUnknown, "NAV/Shared Cast", kMovieScript, 510,
23, "alert \"Failed Save.\" & return & \"Error message number: \" string ( filer )",
"alert \"Failed Save.\" & return & \"Error message number: \" & string ( filer )"},
@@ -144,7 +140,7 @@ struct ScriptPatch {
"GO \"SPACE\" OF MOVIE \"L-ZONE:DATA:R-G:ST-A2\""},
- {"jman", "", kPlatformWindows, "mmm/Mars Space Game 05", kMovieScript, 3,
+ {"jman", "", kPlatformWindows, "mmm/Mars Space Game 05", kMovieScript, 10,
68, "set DamageParameter = (gProcessorSpeed/2) + 7)", "set DamageParameter = (gProcessorSpeed/2) + 7"},
{nullptr, nullptr, kPlatformUnknown, nullptr, kNoneScript, 0, 0, nullptr, nullptr}
Commit: 7bfa8aa6dc378de3a627a3c7e4d8a1543ac659da
https://github.com/scummvm/scummvm/commit/7bfa8aa6dc378de3a627a3c7e4d8a1543ac659da
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-30T22:32:19-04:00
Commit Message:
DIRECTOR: Add castLibID to Cast
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
engines/director/movie.cpp
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index e7cdc09992..88801db5ad 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -61,11 +61,12 @@ const char *scriptType2str(ScriptType scr) {
return scriptTypes[scr];
}
-Cast::Cast(Movie *movie, bool isShared) {
+Cast::Cast(Movie *movie, uint16 castLibID, bool isShared) {
_movie = movie;
_vm = _movie->getVM();
_lingo = _vm->getLingo();
+ _castLibID = castLibID;
_isShared = isShared;
_lingoArchive = new LingoArchive(this);
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 2a578a419a..367dabd1cf 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -48,7 +48,7 @@ class TextCastMember;
class Cast {
public:
- Cast(Movie *movie, bool shared = false);
+ Cast(Movie *movie, uint16 castLibID, bool shared = false);
~Cast();
void loadArchive();
@@ -87,6 +87,7 @@ private:
public:
Archive *_castArchive;
uint16 _version;
+ uint16 _castLibID;
Common::HashMap<uint16, Common::String> _fontMap;
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index d734223ccd..fe4a9c5a32 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -69,7 +69,7 @@ Movie::Movie(Window *window) {
_movieArchive = nullptr;
- _cast = new Cast(this);
+ _cast = new Cast(this, 0);
_sharedCast = nullptr;
_score = new Score(this);
@@ -290,7 +290,7 @@ void Movie::loadSharedCastsFrom(Common::String filename) {
debug(0, "@@@@ Loading shared cast '%s'", filename.c_str());
debug(0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
- _sharedCast = new Cast(this, true);
+ _sharedCast = new Cast(this, 0, true);
_sharedCast->setArchive(sharedCast);
_sharedCast->loadArchive();
}
Commit: 0e9fd00720930813a6389322ac69ebdb8f456766
https://github.com/scummvm/scummvm/commit/0e9fd00720930813a6389322ac69ebdb8f456766
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-30T22:32:19-04:00
Commit Message:
DIRECTOR: LINGO: Take castLib into account in patcher
Changed paths:
engines/director/lingo/lingo-builtins.cpp
engines/director/lingo/lingo-codegen.cpp
engines/director/lingo/lingo-codegen.h
engines/director/lingo/lingo-patcher.cpp
engines/director/lingo/lingo-preprocessor.cpp
engines/director/lingo/lingo.cpp
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 5935dab49b..62c38c1d91 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1675,7 +1675,7 @@ void LB::b_installMenu(int nargs) {
}
TextCastMember *field = static_cast<TextCastMember *>(member);
- Common::String menuStxt = g_lingo->_compiler->codePreprocessor(field->getText().c_str(), field->getCast()->_lingoArchive, kNoneScript, memberID.member, true);
+ Common::String menuStxt = g_lingo->_compiler->codePreprocessor(field->getText().c_str(), field->getCast()->_lingoArchive, kNoneScript, memberID, true);
Common::String line;
int linenum = -1; // We increment it before processing
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index e598b8ea07..1114cd78fd 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -96,13 +96,13 @@ ScriptContext *LingoCompiler::compileAnonymous(const char *code) {
debugC(1, kDebugCompile, "Compiling anonymous lingo\n"
"***********\n%s\n\n***********", code);
- return compileLingo(code, nullptr, kNoneScript, 0, "[anonymous]", true);
+ return compileLingo(code, nullptr, kNoneScript, CastMemberID(0, 0), "[anonymous]", true);
}
-ScriptContext *LingoCompiler::compileLingo(const char *code, LingoArchive *archive, ScriptType type, uint16 id, const Common::String &scriptName, bool anonymous) {
+ScriptContext *LingoCompiler::compileLingo(const char *code, LingoArchive *archive, ScriptType type, CastMemberID id, const Common::String &scriptName, bool anonymous) {
_assemblyArchive = archive;
_assemblyAST = nullptr;
- ScriptContext *mainContext = _assemblyContext = new ScriptContext(scriptName, archive, type, id);
+ ScriptContext *mainContext = _assemblyContext = new ScriptContext(scriptName, archive, type, id.member);
_currentAssembly = new ScriptData;
_methodVars = new VarTypeHash;
diff --git a/engines/director/lingo/lingo-codegen.h b/engines/director/lingo/lingo-codegen.h
index 0e205843b6..8e69ec9e99 100644
--- a/engines/director/lingo/lingo-codegen.h
+++ b/engines/director/lingo/lingo-codegen.h
@@ -35,7 +35,7 @@ public:
virtual ~LingoCompiler() {}
ScriptContext *compileAnonymous(const char *code);
- ScriptContext *compileLingo(const char *code, LingoArchive *archive, ScriptType type, uint16 id, const Common::String &scriptName, bool anonyomous = false);
+ ScriptContext *compileLingo(const char *code, LingoArchive *archive, ScriptType type, CastMemberID id, const Common::String &scriptName, bool anonyomous = false);
ScriptContext *compileLingoV4(Common::SeekableReadStreamEndian &stream, LingoArchive *archive, const Common::String &archName, uint16 version);
int code1(inst code) { _currentAssembly->push_back(code); return _currentAssembly->size() - 1; }
@@ -131,10 +131,10 @@ private:
public:
// lingo-preprocessor.cpp
- Common::String codePreprocessor(const char *s, LingoArchive *archive, ScriptType type, uint16 id, bool simple = false);
+ Common::String codePreprocessor(const char *s, LingoArchive *archive, ScriptType type, CastMemberID id, bool simple = false);
// lingo-patcher.cpp
- Common::String patchLingoCode(Common::String &line, LingoArchive *archive, ScriptType type, uint16 id, int linenumber);
+ Common::String patchLingoCode(Common::String &line, LingoArchive *archive, ScriptType type, CastMemberID id, int linenumber);
};
} // End of namespace Director
diff --git a/engines/director/lingo/lingo-patcher.cpp b/engines/director/lingo/lingo-patcher.cpp
index c126aee3c3..21ab06333a 100644
--- a/engines/director/lingo/lingo-patcher.cpp
+++ b/engines/director/lingo/lingo-patcher.cpp
@@ -37,116 +37,117 @@ struct ScriptPatch {
const char *movie;
ScriptType type;
uint16 id;
+ uint16 castLib;
int linenum;
const char *orig;
const char *replace;
} const scriptPatches[] = {
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP/UpForeECall", kScoreScript, 12,
+ {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP/UpForeECall", kScoreScript, 12, 0,
2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
- {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP/UpForeECall", kScoreScript, 12,
+ {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP/UpForeECall", kScoreScript, 12, 0,
3, "Channels 17 to 18", ""},
- {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP/UpForeECall", kScoreScript, 12,
+ {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP/UpForeECall", kScoreScript, 12, 0,
4, "Frames 150 to 160", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HE.Aft", kScoreScript, 8,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HE.Aft", kScoreScript, 8, 0,
2, "SS Warlock:DATA:WARLOCKSHIP:HangStairsFore", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HE.Aft", kScoreScript, 8,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HE.Aft", kScoreScript, 8, 0,
3, "Channels 4 to 5", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HE.Aft", kScoreScript, 8,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HE.Aft", kScoreScript, 8, 0,
4, "Frames 20 to 20", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/ENG/D10", kScoreScript, 8,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/ENG/D10", kScoreScript, 8, 0,
2, "SS Warlock:ENG.Fold:C9", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/ENG/D10", kScoreScript, 8,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/ENG/D10", kScoreScript, 8, 0,
3, "Channels 19 to 20", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/ENG/D10", kScoreScript, 8,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/ENG/D10", kScoreScript, 8, 0,
4, "Frames 165 to 180", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.c2", kScoreScript, 10,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.c2", kScoreScript, 10, 0,
2, "Frames 150 to 160", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.ForeECall", kScoreScript, 12,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.ForeECall", kScoreScript, 12, 0,
2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.ForeECall", kScoreScript, 12,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.ForeECall", kScoreScript, 12, 0,
3, "Channels 17 to 18", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.ForeECall", kScoreScript, 12,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.ForeECall", kScoreScript, 12, 0,
4, "Frames 150 to 160", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.B2", kScoreScript, 9,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.B2", kScoreScript, 9, 0,
2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.B2", kScoreScript, 9,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.B2", kScoreScript, 9, 0,
3, "Channels 17 to 18", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.B2", kScoreScript, 9,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.B2", kScoreScript, 9, 0,
4, "Frames 150 to 160", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA/BELSHAZZAR/STELLA/ORIGIN", kScoreScript, 12,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/BELSHAZZAR/STELLA/ORIGIN", kScoreScript, 12, 0,
2, "Frames 1 to 1", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HangHallAft", kScoreScript, 7,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HangHallAft", kScoreScript, 7, 0,
2, "SS Warlock:DATA:WARLOCKSHIP:HangStairsFore", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HangHallAft", kScoreScript, 7,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HangHallAft", kScoreScript, 7, 0,
3, "Channels 4 to 5", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HangHallAft", kScoreScript, 7,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HangHallAft", kScoreScript, 7, 0,
4, "Frames 20 to 20", ""},
// Stray 'then' (obvious copy/paste error)
- {"warlock", nullptr, kPlatformMacintosh, "DATA/K/KT/OutMarauderKT", kMovieScript, 14,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/K/KT/OutMarauderKT", kMovieScript, 14, 0,
23, "set Spacesuit = 0 then", "set Spacesuit = 0"},
// Missing '&'
- {"warlock", nullptr, kPlatformMacintosh, "DATA/NAV/Shared Cast", kMovieScript, 510,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA/NAV/Shared Cast", kMovieScript, 510, 0,
19, "alert \"Failed Save.\" & return & \"Error message number: \" string ( filer )",
"alert \"Failed Save.\" & return & \"Error message number: \" & string ( filer )"},
// Garbage at end of script
- {"warlock", "", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12,
+ {"warlock", "", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12, 0,
2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
- {"warlock", "", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12,
+ {"warlock", "", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12, 0,
3, "Channels 17 to 18", ""},
- {"warlock", "", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12,
+ {"warlock", "", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12, 0,
4, "Frames 150 to 160", ""},
// Missing '&'
- {"warlock", nullptr, kPlatformUnknown, "NAV/Shared Cast", kMovieScript, 510,
+ {"warlock", nullptr, kPlatformUnknown, "NAV/Shared Cast", kMovieScript, 510, 0,
23, "alert \"Failed Save.\" & return & \"Error message number: \" string ( filer )",
"alert \"Failed Save.\" & return & \"Error message number: \" & string ( filer )"},
// Patching dead loop which was fixed in v2
- {"lzone", "", kPlatformMacintosh, "DATA/R-A/Ami-00", kScoreScript, 3,
+ {"lzone", "", kPlatformMacintosh, "DATA/R-A/Ami-00", kScoreScript, 3, 0,
2, "continue", "go \"OUT\""},
// Garbage at end of statements
- {"lzone", "", kPlatformMacintosh, "DATA/R-E/ZD2-LAS", kScoreScript, 7,
+ {"lzone", "", kPlatformMacintosh, "DATA/R-E/ZD2-LAS", kScoreScript, 7, 0,
4, "go to the frame 0", "go to the frame"},
- {"lzone", "", kPlatformMacintosh, "DATA/R-E/zd1-con1", kScoreScript, 27,
+ {"lzone", "", kPlatformMacintosh, "DATA/R-E/zd1-con1", kScoreScript, 27, 0,
1, "go to the frame 0", "go to the frame"},
- {"lzone", "", kPlatformMacintosh, "DATA/R-E/zd1-con1", kScoreScript, 30,
+ {"lzone", "", kPlatformMacintosh, "DATA/R-E/zd1-con1", kScoreScript, 30, 0,
4, "go the frame 0", "go to the frame"},
- {"lzone", "", kPlatformMacintosh, "DATA/R-G/st-c", kScoreScript, 14,
+ {"lzone", "", kPlatformMacintosh, "DATA/R-G/st-c", kScoreScript, 14, 0,
1, "go to the frame 0", "go to the frame"},
- {"lzone", "", kPlatformMacintosh, "DATA/R-G/st-d.mo", kScoreScript, 4,
+ {"lzone", "", kPlatformMacintosh, "DATA/R-G/st-d.mo", kScoreScript, 4, 0,
1, "go to the frame 0", "go to the frame"},
- {"lzone", "", kPlatformMacintosh, "DATA/R-F/ARCH-U.D-1", kScoreScript, 8,
+ {"lzone", "", kPlatformMacintosh, "DATA/R-F/ARCH-U.D-1", kScoreScript, 8, 0,
1, "GO \"SPACE\" OF MOVIE \"L-ZONE:DATA:R-G:ST-A2\",\"242,197\"",
"GO \"SPACE\" OF MOVIE \"L-ZONE:DATA:R-G:ST-A2\""},
- {"jman", "", kPlatformWindows, "mmm/Mars Space Game 05", kMovieScript, 10,
+ {"jman", "", kPlatformWindows, "mmm/Mars Space Game 05", kMovieScript, 10, 0,
68, "set DamageParameter = (gProcessorSpeed/2) + 7)", "set DamageParameter = (gProcessorSpeed/2) + 7"},
- {nullptr, nullptr, kPlatformUnknown, nullptr, kNoneScript, 0, 0, nullptr, nullptr}
+ {nullptr, nullptr, kPlatformUnknown, nullptr, kNoneScript, 0, 0, 0, nullptr, nullptr}
};
-Common::String LingoCompiler::patchLingoCode(Common::String &line, LingoArchive *archive, ScriptType type, uint16 id, int linenum) {
+Common::String LingoCompiler::patchLingoCode(Common::String &line, LingoArchive *archive, ScriptType type, CastMemberID id, int linenum) {
if (!archive)
return line;
@@ -156,7 +157,7 @@ Common::String LingoCompiler::patchLingoCode(Common::String &line, LingoArchive
// So far, we have not many patches, so do linear lookup
while (patch->gameId) {
// First, we do cheap comparisons
- if (patch->type != type || patch->id != id || patch->linenum != linenum ||
+ if (patch->type != type || patch->id != id.member || patch->castLib != id.castLib || patch->linenum != linenum ||
(patch->platform != kPlatformUnknown && patch->platform != g_director->getPlatform())) {
patch++;
continue;
@@ -171,15 +172,15 @@ Common::String LingoCompiler::patchLingoCode(Common::String &line, LingoArchive
// Now do a safeguard
if (!line.contains(patch->orig)) {
- warning("Lingo::patchLingoCode(): Unmatched patch for '%s', '%s' %s:%d @ %d. Expecting '%s' but got '%s'",
- patch->gameId, patch->movie, scriptType2str(type), id, linenum,
+ warning("Lingo::patchLingoCode(): Unmatched patch for '%s', '%s' %s:%s @ %d. Expecting '%s' but got '%s'",
+ patch->gameId, patch->movie, scriptType2str(type), id.asString().c_str(), linenum,
patch->orig, line.c_str());
return line;
}
// Now everything matched
- warning("Lingo::patchLingoCode(): Applied a patch for '%s', '%s' %s:%d @ %d. \"%s\" -> \"%s\"",
- patch->gameId, patch->movie, scriptType2str(type), id, linenum,
+ warning("Lingo::patchLingoCode(): Applied a patch for '%s', '%s' %s:%s @ %d. \"%s\" -> \"%s\"",
+ patch->gameId, patch->movie, scriptType2str(type), id.asString().c_str(), linenum,
patch->orig, patch->replace);
return patch->replace;
}
diff --git a/engines/director/lingo/lingo-preprocessor.cpp b/engines/director/lingo/lingo-preprocessor.cpp
index a3e6a020b6..bdba2df9d5 100644
--- a/engines/director/lingo/lingo-preprocessor.cpp
+++ b/engines/director/lingo/lingo-preprocessor.cpp
@@ -90,7 +90,7 @@ static const char *findtokstart(const char *start, const char *token) {
return ptr;
}
-Common::String LingoCompiler::codePreprocessor(const char *s, LingoArchive *archive, ScriptType type, uint16 id, bool simple) {
+Common::String LingoCompiler::codePreprocessor(const char *s, LingoArchive *archive, ScriptType type, CastMemberID id, bool simple) {
Common::String res;
// We start from processing the continuation synbols
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 9c5d1e2dd2..0472f2a7ee 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -265,7 +265,7 @@ void LingoArchive::addCode(const char *code, ScriptType type, uint16 id, const c
else
contextName = Common::String::format("%d", id);
- ScriptContext *sc = g_lingo->_compiler->compileLingo(code, this, type, id, contextName);
+ ScriptContext *sc = g_lingo->_compiler->compileLingo(code, this, type, CastMemberID(id, cast->_castLibID), contextName);
if (sc) {
scriptContexts[type][id] = sc;
*sc->_refCount += 1;
More information about the Scummvm-git-logs
mailing list