[Scummvm-git-logs] scummvm master -> 8976c4f56bc8c0d727cf9d47c2fc960b8e029bb9
sev-
noreply at scummvm.org
Wed May 10 07:49:03 UTC 2023
This automated email contains information about 15 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
3b13e8ff43 DIRECTOR: Support D5 loading multiple casts
699e50cf7d DIRECTOR: Buffer recursive load() requests
75e5885eb9 DIRECTOR: LINGO: Make patcher use DEFAULT_CAST_LIB
49f38f28de DIRECTOR: Add new kClutSystemWinD5 palette
2009f27712 DIRECTOR: Add D5 support for _defaultPalette
a439d0c790 DIRECTOR: XOBJ: Add QTVR stubs
b26a6f304f DIRECTOR: Add version cutoff for cast member loaders
0a3b7ee462 DIRECTOR: Load in external casts and members
96855f1cf7 DIRECTOR: Add D5 file extensions to pathMakeRelative
5c82519e35 DIRECTOR: Add D5 support for sound cast members
8a990d556c DIRECTOR: Add Transition cast member type
ec76e5dfc6 DIRECTOR: Refactor palette loading for D5
5426729bf4 DIRECTOR: Fix zoom transitions
919b7ff5b1 DIRECTOR: Show multiple casts in debugger
8976c4f56b DIRECTOR: Fix parse bug in loadCastlibMapping
Commit: 3b13e8ff43370dcf494425cc7ae45731894f2910
https://github.com/scummvm/scummvm/commit/3b13e8ff43370dcf494425cc7ae45731894f2910
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Support D5 loading multiple casts
In D5 and up, you can have multiple casts in the same movie, along with
external casts. Unlike shared casts these are different namespaces;
each movie maps the casts to a libId, which is then used by
CastMemberID.castLib.
For D4 and below, the default cast libId is now represented by
DEFAULT_CAST_LIB. This should make refactoring easier in future.
Changed paths:
engines/director/archive.cpp
engines/director/archive.h
engines/director/cast.cpp
engines/director/cast.h
engines/director/castmember/filmloop.cpp
engines/director/frame.cpp
engines/director/lingo/lingo-builtins.cpp
engines/director/lingo/lingo-events.cpp
engines/director/lingo/lingo.cpp
engines/director/movie.cpp
engines/director/movie.h
engines/director/score.cpp
diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp
index 7f163c71b51..8b14fe2ddbf 100644
--- a/engines/director/archive.cpp
+++ b/engines/director/archive.cpp
@@ -27,6 +27,7 @@
#include "director/director.h"
#include "director/archive.h"
+#include "director/movie.h"
#include "director/window.h"
#include "director/util.h"
@@ -681,10 +682,19 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
delete keyStream;
}
- // Parse the CAS*, if present
- if (Common::SeekableReadStreamEndian *casStream = getMovieResourceIfPresent(MKTAG('C', 'A', 'S', '*'))) {
- readCast(*casStream);
- delete casStream;
+ // Parse the CAS* for each library, if present
+ uint32 casTag = MKTAG('C', 'A', 'S', '*');
+ if (_keyData.contains(casTag)) {
+ for (auto &it : _keyData[casTag]) {
+ uint32 libId = it._key - CAST_LIB_OFFSET;
+ for (auto &jt : it._value) {
+ if (Common::SeekableReadStreamEndian *casStream = getResource(casTag, jt)) {
+ Resource res = getResourceDetail(casTag, jt);
+ readCast(*casStream, libId);
+ delete casStream;
+ }
+ }
+ }
}
return true;
@@ -910,12 +920,12 @@ bool RIFXArchive::readAfterburnerMap(Common::SeekableReadStreamEndian &stream, u
return true;
}
-void RIFXArchive::readCast(Common::SeekableReadStreamEndian &casStream) {
+void RIFXArchive::readCast(Common::SeekableReadStreamEndian &casStream, uint16 libId) {
uint castTag = MKTAG('C', 'A', 'S', 't');
uint casSize = casStream.size() / 4;
- debugCN(2, kDebugLoading, "CAS*: %d [", casSize);
+ debugCN(2, kDebugLoading, "CAS*: libId %d, %d members [", libId, casSize);
for (uint i = 0; i < casSize; i++) {
uint32 castIndex = casStream.readUint32BE();
@@ -926,6 +936,7 @@ void RIFXArchive::readCast(Common::SeekableReadStreamEndian &casStream) {
}
Resource &res = _types[castTag][castIndex];
res.castId = i;
+ res.libId = libId;
}
debugC(2, kDebugLoading, "]");
}
@@ -947,6 +958,14 @@ void RIFXArchive::readKeyTable(Common::SeekableReadStreamEndian &keyStream) {
debugC(2, kDebugLoading, "KEY*: childIndex: %d parentIndex: %d childTag: %s", childIndex, parentIndex, tag2str(childTag));
+ if (!_keyData.contains(childTag)) {
+ _keyData[childTag] = KeyMap();
+ }
+ if (!_keyData[childTag].contains(parentIndex)) {
+ _keyData[childTag][parentIndex] = KeyArray();
+ }
+ _keyData[childTag][parentIndex].push_back(childIndex);
+
// Link cast members to their resources.
if (castResMap.contains(parentIndex)) {
castResMap[parentIndex].children.push_back(_types[childTag][childIndex]);
@@ -958,7 +977,7 @@ void RIFXArchive::readKeyTable(Common::SeekableReadStreamEndian &keyStream) {
// The movie has the hardcoded ID 1024, which may collide with a cast member's ID
// when there are many chunks. This is not a problem since cast members and
// movies use different resource types, so we can tell them apart.
- if (parentIndex == 1024) {
+ if (parentIndex == DEFAULT_CAST_LIB + CAST_LIB_OFFSET) {
_movieChunks.setVal(childTag, childIndex);
}
}
diff --git a/engines/director/archive.h b/engines/director/archive.h
index 18fd7c18455..15ba9070a5f 100644
--- a/engines/director/archive.h
+++ b/engines/director/archive.h
@@ -40,6 +40,7 @@ struct Resource {
uint32 uncompSize;
uint32 compressionType;
uint32 castId;
+ uint32 libId;
uint32 tag;
Common::String name;
Common::Array<Resource> children;
@@ -135,7 +136,7 @@ public:
private:
bool readMemoryMap(Common::SeekableReadStreamEndian &stream, uint32 moreOffset, Common::SeekableMemoryWriteStream *dumpStream, uint32 movieStartOffset);
bool readAfterburnerMap(Common::SeekableReadStreamEndian &stream, uint32 moreOffset);
- void readCast(Common::SeekableReadStreamEndian &casStream);
+ void readCast(Common::SeekableReadStreamEndian &casStream, uint16 libId);
void readKeyTable(Common::SeekableReadStreamEndian &keyStream);
protected:
@@ -143,6 +144,9 @@ protected:
Common::Array<Resource *> _resources;
Common::HashMap<uint32, byte *> _ilsData;
uint32 _ilsBodyOffset;
+ typedef Common::Array<uint32> KeyArray;
+ typedef Common::HashMap<uint32, KeyArray> KeyMap;
+ Common::HashMap<uint32, KeyMap> _keyData;
};
} // End of namespace Director
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 0b9deef3184..cebea168794 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -529,12 +529,6 @@ void Cast::loadCast() {
delete r;
}
- // Cast library mapping, used in D5+
- if ((r = _castArchive->getMovieResourceIfPresent(MKTAG('M', 'C', 's', 'L'))) != nullptr) {
- loadCastLibMapping(*r);
- delete r;
- }
-
Common::Array<uint16> cinf = _castArchive->getResourceIDList(MKTAG('C', 'i', 'n', 'f'));
if (cinf.size() > 0) {
debugC(2, kDebugLoading, "****** Loading %d CastLibInfos Cinf", cinf.size());
@@ -560,13 +554,15 @@ void Cast::loadCast() {
_loadedCast = new Common::HashMap<int, CastMember *>();
if (cast.size() > 0) {
- debugC(2, kDebugLoading, "****** Loading %d CASt resources", cast.size());
+ debugC(2, kDebugLoading, "****** Loading CASt resources for libId %d", _castLibID);
int idx = 0;
for (Common::Array<uint16>::iterator iterator = cast.begin(); iterator != cast.end(); ++iterator) {
- Common::SeekableReadStreamEndian *stream = _castArchive->getResource(MKTAG('C', 'A', 'S', 't'), *iterator);
Resource res = _castArchive->getResourceDetail(MKTAG('C', 'A', 'S', 't'), *iterator);
+ if (res.libId != _castLibID)
+ continue;
+ Common::SeekableReadStreamEndian *stream = _castArchive->getResource(MKTAG('C', 'A', 'S', 't'), *iterator);
loadCastData(*stream, res.castId, &res);
delete stream;
@@ -1256,33 +1252,6 @@ void Cast::loadCastInfo(Common::SeekableReadStreamEndian &stream, uint16 id) {
_castsInfo[id] = ci;
}
-void Cast::loadCastLibMapping(Common::SeekableReadStreamEndian &stream) {
- if (debugChannelSet(8, kDebugLoading)) {
- stream.hexdump(stream.size());
- }
- stream.readUint32(); // header size
- uint32 count = stream.readUint32();
- stream.readUint16();
- uint32 unkCount = stream.readUint32() + 1;
- for (uint32 i = 0; i < unkCount; i++) {
- stream.readUint32();
- }
- for (uint32 i = 0; i < count; i++) {
- int nameSize = stream.readByte() + 1;
- Common::String name = stream.readString('\0', nameSize);
- int pathSize = stream.readByte() + 1;
- Common::String path = stream.readString('\0', pathSize);
- if (pathSize > 1)
- stream.readUint16();
- stream.readUint16();
- uint16 itemCount = stream.readUint16();
- stream.readUint16();
- uint16 libId = stream.readUint16();
- debugC(5, kDebugLoading, "Cast::loadCastLibMapping: name: %s, path: %s, itemCount: %d, libId: %d", name.c_str(), path.c_str(), itemCount, libId);
- }
- return;
-}
-
void Cast::loadCastLibInfo(Common::SeekableReadStreamEndian &stream, uint16 id) {
if (debugChannelSet(8, kDebugLoading)) {
stream.hexdump(stream.size());
@@ -1340,7 +1309,7 @@ void Cast::loadSord(Common::SeekableReadStreamEndian &stream) {
stream.readUint16();
uint numEntries = 0;
- uint16 castLibId = 0; // default for pre-D5
+ uint16 castLibId = DEFAULT_CAST_LIB; // default for pre-D5
uint16 memberId;
while (!stream.eos()) {
@@ -1364,7 +1333,7 @@ void Cast::loadVWTL(Common::SeekableReadStreamEndian &stream) {
debugC(1, kDebugLoading, "****** Loading CastMember petterns VWTL");
Common::Rect r;
- uint16 castLibId = 0; // default for pre-D5
+ uint16 castLibId = DEFAULT_CAST_LIB; // default for pre-D5
uint16 memberId;
for (int i = 0; i < kNumBuiltinTiles; i++) {
diff --git a/engines/director/cast.h b/engines/director/cast.h
index b8492132107..80567137d28 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -89,7 +89,6 @@ public:
void loadCastDataVWCR(Common::SeekableReadStreamEndian &stream);
void loadCastData(Common::SeekableReadStreamEndian &stream, uint16 id, Resource *res);
void loadCastInfo(Common::SeekableReadStreamEndian &stream, uint16 id);
- void loadCastLibMapping(Common::SeekableReadStreamEndian &stream);
void loadCastLibInfo(Common::SeekableReadStreamEndian &stream, uint16 id);
void loadLingoContext(Common::SeekableReadStreamEndian &stream);
void loadExternalSound(Common::SeekableReadStreamEndian &stream);
diff --git a/engines/director/castmember/filmloop.cpp b/engines/director/castmember/filmloop.cpp
index c860f2aa984..4f499892115 100644
--- a/engines/director/castmember/filmloop.cpp
+++ b/engines/director/castmember/filmloop.cpp
@@ -179,7 +179,7 @@ void FilmLoopCastMember::loadFilmLoopData(Common::SeekableReadStreamEndian &stre
fieldPosition += 2;
break;
case kSpritePositionCastId:
- sprite.setCast(CastMemberID(stream.readUint16(), 0));
+ sprite.setCast(CastMemberID(stream.readUint16(), DEFAULT_CAST_LIB));
fieldPosition += 2;
break;
case kSpritePositionY:
@@ -317,7 +317,7 @@ void FilmLoopCastMember::loadFilmLoopDataV4(Common::SeekableReadStreamEndian &st
fieldPosition += 2;
break;
case kSpritePositionCastId:
- sprite.setCast(CastMemberID(stream.readUint16(), 0));
+ sprite.setCast(CastMemberID(stream.readUint16(), DEFAULT_CAST_LIB));
fieldPosition += 2;
break;
case kSpritePositionY:
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 0f27ffe6831..b6e67701ee0 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -134,7 +134,7 @@ void Frame::readChannels(Common::SeekableReadStreamEndian *stream, uint16 versio
if (version < kFileVer400) {
// Sound/Tempo/Transition
- _actionId = CastMemberID(stream->readByte(), 0);
+ _actionId = CastMemberID(stream->readByte(), DEFAULT_CAST_LIB);
_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
@@ -147,15 +147,15 @@ void Frame::readChannels(Common::SeekableReadStreamEndian *stream, uint16 versio
_transChunkSize = stream->readByte();
_tempo = stream->readByte();
_transType = static_cast<TransitionType>(stream->readByte());
- _sound1 = CastMemberID(stream->readUint16(), 0);
- _sound2 = CastMemberID(stream->readUint16(), 0);
+ _sound1 = CastMemberID(stream->readUint16(), DEFAULT_CAST_LIB);
+ _sound2 = CastMemberID(stream->readUint16(), DEFAULT_CAST_LIB);
_soundType2 = stream->readByte();
_skipFrameFlag = stream->readByte();
_blend = stream->readByte();
if (_vm->getPlatform() == Common::kPlatformWindows) {
- _sound2 = CastMemberID(stream->readUint16(), 0);
+ _sound2 = CastMemberID(stream->readUint16(), DEFAULT_CAST_LIB);
_soundType2 = stream->readByte();
} else {
stream->read(unk, 3);
@@ -204,9 +204,9 @@ void Frame::readChannels(Common::SeekableReadStreamEndian *stream, uint16 versio
_transChunkSize = stream->readByte();
_tempo = stream->readByte();
_transType = static_cast<TransitionType>(stream->readByte());
- _sound1 = CastMemberID(stream->readUint16(), 0);
+ _sound1 = CastMemberID(stream->readUint16(), DEFAULT_CAST_LIB);
- _sound2 = CastMemberID(stream->readUint16(), 0);
+ _sound2 = CastMemberID(stream->readUint16(), DEFAULT_CAST_LIB);
_soundType2 = stream->readByte();
_skipFrameFlag = stream->readByte();
@@ -216,7 +216,7 @@ void Frame::readChannels(Common::SeekableReadStreamEndian *stream, uint16 versio
_colorSound1 = stream->readByte();
_colorSound2 = stream->readByte();
- _actionId = CastMemberID(stream->readUint16(), 0);
+ _actionId = CastMemberID(stream->readUint16(), DEFAULT_CAST_LIB);
_colorScript = stream->readByte();
_colorTrans = stream->readByte();
@@ -312,7 +312,7 @@ void Frame::readChannels(Common::SeekableReadStreamEndian *stream, uint16 versio
debugC(8, kDebugLoading, "Frame::readChannels(): channel %d, 22 bytes", i);
stream->hexdump(22);
}
- sprite._scriptId = CastMemberID(stream->readByte(), 0);
+ sprite._scriptId = CastMemberID(stream->readByte(), DEFAULT_CAST_LIB);
sprite._spriteType = (SpriteType)stream->readByte();
sprite._enabled = sprite._spriteType != kInactiveSprite;
if (version >= kFileVer400) {
@@ -330,7 +330,7 @@ void Frame::readChannels(Common::SeekableReadStreamEndian *stream, uint16 versio
if (sprite.isQDShape()) {
sprite._pattern = stream->readUint16();
} else {
- sprite._castId = CastMemberID(stream->readUint16(), 0);
+ sprite._castId = CastMemberID(stream->readUint16(), DEFAULT_CAST_LIB);
}
sprite._startPoint.y = (int16)stream->readUint16();
@@ -340,7 +340,7 @@ void Frame::readChannels(Common::SeekableReadStreamEndian *stream, uint16 versio
sprite._width = (int16)stream->readUint16();
if (version >= kFileVer400) {
- sprite._scriptId = CastMemberID(stream->readUint16(), 0);
+ sprite._scriptId = CastMemberID(stream->readUint16(), DEFAULT_CAST_LIB);
// & 0x0f scorecolor
// 0x10 forecolor is rgb
// 0x20 bgcolor is rgb
@@ -464,7 +464,7 @@ void Frame::readMainChannels(Common::SeekableReadStreamEndian &stream, uint16 of
while (offset < finishPosition) {
switch(offset) {
case kScriptIdPosition:
- _actionId = CastMemberID(stream.readByte(), 0);
+ _actionId = CastMemberID(stream.readByte(), DEFAULT_CAST_LIB);
offset++;
break;
case kSoundType1Position:
@@ -494,7 +494,7 @@ void Frame::readMainChannels(Common::SeekableReadStreamEndian &stream, uint16 of
offset++;
break;
case kSound1Position:
- _sound1 = CastMemberID(stream.readUint16(), 0);
+ _sound1 = CastMemberID(stream.readUint16(), DEFAULT_CAST_LIB);
offset+=2;
break;
case kSkipFrameFlagsPosition:
@@ -506,7 +506,7 @@ void Frame::readMainChannels(Common::SeekableReadStreamEndian &stream, uint16 of
offset++;
break;
case kSound2Position:
- _sound2 = CastMemberID(stream.readUint16(), 0);
+ _sound2 = CastMemberID(stream.readUint16(), DEFAULT_CAST_LIB);
offset += 2;
break;
case kSound2TypePosition:
@@ -576,7 +576,7 @@ void Frame::readSprite(Common::SeekableReadStreamEndian &stream, uint16 offset,
fieldPosition += 2;
break;
case kSpritePositionCastId:
- sprite._castId = CastMemberID(stream.readUint16(), 0);
+ sprite._castId = CastMemberID(stream.readUint16(), DEFAULT_CAST_LIB);
fieldPosition += 2;
break;
case kSpritePositionY:
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 98cb66d656e..e4b31682dcd 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -2227,7 +2227,7 @@ void LB::b_move(int nargs) {
if (nargs == 1) {
int id = (int) g_director->getCurrentMovie()->getCast()->_castArrayStart;
- CastMemberID *castId = new CastMemberID(id, 0);
+ CastMemberID *castId = new CastMemberID(id, DEFAULT_CAST_LIB);
Datum d = Datum(*castId);
delete castId;
g_lingo->push(d);
@@ -2253,7 +2253,7 @@ void LB::b_move(int nargs) {
return;
}
- if (src.u.cast->castLib != 0) {
+ if (src.u.cast->castLib != DEFAULT_CAST_LIB) {
warning("b_move: wrong castLib '%d' in src CastMemberID", src.u.cast->castLib);
}
@@ -2288,7 +2288,7 @@ void LB::b_move(int nargs) {
for (uint i = 0; i < channels.size(); i++) {
if (channels[i]->_sprite->_castId == dest.asMemberID()) {
- channels[i]->_sprite->setCast(CastMemberID(1, 0));
+ channels[i]->_sprite->setCast(CastMemberID(1, DEFAULT_CAST_LIB));
channels[i]->_dirty = true;
}
}
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 2e906fbca12..d19dea4e9b0 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -187,7 +187,7 @@ void Movie::queueMovieEvent(Common::Queue<LingoEvent> &queue, LEvent event, int
for (ScriptContextHash::iterator it = mainArchive->scriptContexts[kMovieScript].begin();
it != mainArchive->scriptContexts[kMovieScript].end(); ++it) {
if (it->_value->_eventHandlers.contains(event)) {
- queue.push(LingoEvent(event, eventId, kMovieScript, CastMemberID(it->_key, 0), false));
+ queue.push(LingoEvent(event, eventId, kMovieScript, CastMemberID(it->_key, DEFAULT_CAST_LIB), false));
return;
}
}
@@ -196,7 +196,7 @@ void Movie::queueMovieEvent(Common::Queue<LingoEvent> &queue, LEvent event, int
for (ScriptContextHash::iterator it = sharedArchive->scriptContexts[kMovieScript].begin();
it != sharedArchive->scriptContexts[kMovieScript].end(); ++it) {
if (it->_value->_eventHandlers.contains(event)) {
- queue.push(LingoEvent(event, eventId, kMovieScript, CastMemberID(it->_key, 0), false));
+ queue.push(LingoEvent(event, eventId, kMovieScript, CastMemberID(it->_key, DEFAULT_CAST_LIB), false));
return;
}
}
@@ -228,7 +228,7 @@ void Movie::queueEvent(Common::Queue<LingoEvent> &queue, LEvent event, int targe
case kEventKeyDown:
case kEventTimeout:
{
- CastMemberID scriptID = CastMemberID(event, 0);
+ CastMemberID scriptID = CastMemberID(event, DEFAULT_CAST_LIB);
if (getScriptContext(kEventScript, scriptID)) {
queue.push(LingoEvent(kEventGeneric, eventId, kEventScript, scriptID, true));
}
@@ -236,7 +236,7 @@ void Movie::queueEvent(Common::Queue<LingoEvent> &queue, LEvent event, int targe
break;
case kEventMenuCallback:
{
- CastMemberID scriptID = CastMemberID(targetId, 0);
+ CastMemberID scriptID = CastMemberID(targetId, DEFAULT_CAST_LIB);
if (getScriptContext(kEventScript, scriptID)) {
queue.push(LingoEvent(kEventGeneric, eventId, kEventScript, scriptID, true));
}
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index b645712a606..afc3f4b1fc0 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1182,7 +1182,7 @@ CastMemberID Datum::asMemberID(CastType castType) const {
if (type == CASTREF || type == FIELDREF)
return *u.cast;
- return g_lingo->resolveCastMember(*this, 0, castType);
+ return g_lingo->resolveCastMember(*this, DEFAULT_CAST_LIB, castType);
}
Common::Point Datum::asPoint() const {
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index 2a2e7e4450a..a89a03a458b 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -73,7 +73,7 @@ Movie::Movie(Window *window) {
_movieArchive = nullptr;
- _cast = new Cast(this, 0);
+ _cast = new Cast(this, DEFAULT_CAST_LIB);
_casts.setVal(_cast->_castLibID, _cast);
_sharedCast = nullptr;
_score = new Score(this);
@@ -114,15 +114,58 @@ void Movie::setArchive(Archive *archive) {
_macName = archive->getFileName();
}
- _cast->setArchive(archive);
+ Common::SeekableReadStreamEndian *r = nullptr;
+ if ((r = archive->getMovieResourceIfPresent(MKTAG('M', 'C', 's', 'L'))) != nullptr) {
+ // D5 archive, can contain multiple internal/external casts
+ loadCastLibMapping(*r);
+ } else {
+ // D4 or lower, only 1 cast
+ _cast->setArchive(archive);
+ }
// Frame Labels
- if (Common::SeekableReadStreamEndian *r = archive->getMovieResourceIfPresent(MKTAG('V', 'W', 'L', 'B'))) {
+ if ((r = archive->getMovieResourceIfPresent(MKTAG('V', 'W', 'L', 'B')))) {
_score->loadLabels(*r);
delete r;
}
}
+void Movie::loadCastLibMapping(Common::SeekableReadStreamEndian &stream) {
+ debugC(5, kDebugLoading, "Movie::loadCastLibMapping: loading cast libraries");
+ if (debugChannelSet(8, kDebugLoading)) {
+ stream.hexdump(stream.size());
+ }
+ stream.readUint32(); // header size
+ uint32 count = stream.readUint32();
+ stream.readUint16();
+ uint32 unkCount = stream.readUint32() + 1;
+ for (uint32 i = 0; i < unkCount; i++) {
+ stream.readUint32();
+ }
+ for (uint32 i = 0; i < count; i++) {
+ int nameSize = stream.readByte() + 1;
+ Common::String name = stream.readString('\0', nameSize);
+ int pathSize = stream.readByte() + 1;
+ Common::String path = stream.readString('\0', pathSize);
+ if (pathSize > 1)
+ stream.readUint16();
+ stream.readUint16();
+ uint16 itemCount = stream.readUint16();
+ stream.readUint16();
+ uint16 libId = stream.readUint16() - CAST_LIB_OFFSET;
+ debugC(5, kDebugLoading, "Movie::loadCastLibMapping: name: %s, path: %s, itemCount: %d, libId: %d", name.c_str(), path.c_str(), itemCount, libId);
+ Cast *cast = nullptr;
+ if (_casts.contains(libId)) {
+ cast = _casts.getVal(libId);
+ } else {
+ cast = new Cast(this, libId);
+ _casts.setVal(libId, cast);
+ }
+ cast->setArchive(_movieArchive);
+ }
+ return;
+}
+
bool Movie::loadArchive() {
Common::SeekableReadStreamEndian *r = nullptr;
@@ -142,7 +185,11 @@ bool Movie::loadArchive() {
}
// Cast
- _cast->loadCast();
+ for (auto &it : _casts) {
+ if (it._value != _cast)
+ it._value->loadConfig();
+ it._value->loadCast();
+ }
_stageColor = _vm->transformColor(_cast->_stageColor);
bool recenter = false;
@@ -313,7 +360,7 @@ void Movie::loadSharedCastsFrom(Common::String filename) {
debug(0, "@@@@ Loading shared cast '%s'", filename.c_str());
debug(0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
- _sharedCast = new Cast(this, 0, true);
+ _sharedCast = new Cast(this, DEFAULT_CAST_LIB, true);
_sharedCast->setArchive(sharedCast);
_sharedCast->loadArchive();
@@ -328,7 +375,7 @@ CastMember *Movie::getCastMember(CastMemberID memberID) {
if (result == nullptr && _sharedCast) {
result = _sharedCast->getCastMember(memberID.member);
}
- } else {
+ } else if (memberID.castLib != 0) {
warning("Movie::getCastMember: Unknown castLib %d", memberID.castLib);
}
return result;
@@ -393,7 +440,7 @@ const Stxt *Movie::getStxt(CastMemberID memberID) {
}
LingoArchive *Movie::getMainLingoArch() {
- return _casts.getVal(0)->_lingoArchive;
+ return _casts.getVal(DEFAULT_CAST_LIB)->_lingoArchive;
}
LingoArchive *Movie::getSharedLingoArch() {
diff --git a/engines/director/movie.h b/engines/director/movie.h
index 345ba71c5cb..492c1f119af 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -22,6 +22,9 @@
#ifndef DIRECTOR_MOVIE_H
#define DIRECTOR_MOVIE_H
+#define DEFAULT_CAST_LIB 1
+#define CAST_LIB_OFFSET 1023
+
namespace Common {
struct Event;
class ReadStreamEndian;
@@ -88,13 +91,14 @@ public:
static Common::Rect readRect(Common::ReadStreamEndian &stream);
static InfoEntries loadInfoEntries(Common::SeekableReadStreamEndian &stream, uint16 version);
+ void loadCastLibMapping(Common::SeekableReadStreamEndian &stream);
bool loadArchive();
void setArchive(Archive *archive);
Archive *getArchive() const { return _movieArchive; };
Common::String getMacName() const { return _macName; }
Window *getWindow() const { return _window; }
DirectorEngine *getVM() const { return _vm; }
- Cast *getCast() const { return _casts.getValOrDefault(0, nullptr); }
+ Cast *getCast() const { return _casts.getValOrDefault(DEFAULT_CAST_LIB, nullptr); }
Cast *getSharedCast() const { return _sharedCast; }
Score *getScore() const { return _score; }
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 7aba55f2c71..67fb026d673 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -112,7 +112,7 @@ int Score::resolvePaletteId(int id) {
if (id == 255) {
id = g_director->getCurrentMovie()->getCast()->_defaultPalette;
} else if (id > 0) {
- CastMember *member = _movie->getCastMember(CastMemberID(id, 0));
+ CastMember *member = _movie->getCastMember(CastMemberID(id, DEFAULT_CAST_LIB));
id = (member && member->_type == kCastPalette) ? ((PaletteCastMember *)member)->getPaletteId() : 0;
}
Commit: 699e50cf7d887082a4f6489cbef2aa4bf538dd53
https://github.com/scummvm/scummvm/commit/699e50cf7d887082a4f6489cbef2aa4bf538dd53
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Buffer recursive load() requests
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index cebea168794..77d3195e085 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -123,7 +123,13 @@ CastMember *Cast::getCastMember(int castId) {
// prevent recursive calls to CastMember::load()
_loadMutex = false;
result->load();
+ while (!_loadQueue.empty()) {
+ _loadQueue.back()->load();
+ _loadQueue.pop_back();
+ }
_loadMutex = true;
+ } else if (result) {
+ _loadQueue.push_back(result);
}
return result;
}
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 80567137d28..39e147f4007 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -160,6 +160,7 @@ private:
bool _isShared;
bool _loadMutex;
+ Common::Array<CastMember *> _loadQueue;
Common::String _macName;
Commit: 75e5885eb953f01bef9c7ba206000d8eb0c6ccb9
https://github.com/scummvm/scummvm/commit/75e5885eb953f01bef9c7ba206000d8eb0c6ccb9
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: LINGO: Make patcher use DEFAULT_CAST_LIB
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 42bd66705a8..8367e31eda8 100644
--- a/engines/director/lingo/lingo-patcher.cpp
+++ b/engines/director/lingo/lingo-patcher.cpp
@@ -43,180 +43,180 @@ struct ScriptPatch {
const char *replace;
} const scriptPatches[] = {
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP:UpForeECall", kScoreScript, 12, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP:UpForeECall", kScoreScript, 12, DEFAULT_CAST_LIB,
2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
- {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP:UpForeECall", kScoreScript, 12, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP:UpForeECall", kScoreScript, 12, DEFAULT_CAST_LIB,
3, "Channels 17 to 18", ""},
- {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP:UpForeECall", kScoreScript, 12, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP:UpForeECall", kScoreScript, 12, DEFAULT_CAST_LIB,
4, "Frames 150 to 160", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HE.Aft", kScoreScript, 8, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HE.Aft", kScoreScript, 8, DEFAULT_CAST_LIB,
2, "SS Warlock:DATA:WARLOCKSHIP:HangStairsFore", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HE.Aft", kScoreScript, 8, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HE.Aft", kScoreScript, 8, DEFAULT_CAST_LIB,
3, "Channels 4 to 5", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HE.Aft", kScoreScript, 8, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HE.Aft", kScoreScript, 8, DEFAULT_CAST_LIB,
4, "Frames 20 to 20", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:ENG:D10", kScoreScript, 8, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:ENG:D10", kScoreScript, 8, DEFAULT_CAST_LIB,
2, "SS Warlock:ENG.Fold:C9", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:ENG:D10", kScoreScript, 8, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:ENG:D10", kScoreScript, 8, DEFAULT_CAST_LIB,
3, "Channels 19 to 20", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:ENG:D10", kScoreScript, 8, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:ENG:D10", kScoreScript, 8, DEFAULT_CAST_LIB,
4, "Frames 165 to 180", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.c2", kScoreScript, 10, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.c2", kScoreScript, 10, DEFAULT_CAST_LIB,
2, "Frames 150 to 160", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.ForeECall", kScoreScript, 12, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.ForeECall", kScoreScript, 12, DEFAULT_CAST_LIB,
2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.ForeECall", kScoreScript, 12, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.ForeECall", kScoreScript, 12, DEFAULT_CAST_LIB,
3, "Channels 17 to 18", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.ForeECall", kScoreScript, 12, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.ForeECall", kScoreScript, 12, DEFAULT_CAST_LIB,
4, "Frames 150 to 160", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.B2", kScoreScript, 9, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.B2", kScoreScript, 9, DEFAULT_CAST_LIB,
2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.B2", kScoreScript, 9, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.B2", kScoreScript, 9, DEFAULT_CAST_LIB,
3, "Channels 17 to 18", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.B2", kScoreScript, 9, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.B2", kScoreScript, 9, DEFAULT_CAST_LIB,
4, "Frames 150 to 160", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA:BELSHAZZAR:STELLA:ORIGIN", kScoreScript, 12, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:BELSHAZZAR:STELLA:ORIGIN", kScoreScript, 12, DEFAULT_CAST_LIB,
2, "Frames 1 to 1", ""},
// Garbage at end of script
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HangHallAft", kScoreScript, 7, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HangHallAft", kScoreScript, 7, DEFAULT_CAST_LIB,
2, "SS Warlock:DATA:WARLOCKSHIP:HangStairsFore", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HangHallAft", kScoreScript, 7, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HangHallAft", kScoreScript, 7, DEFAULT_CAST_LIB,
3, "Channels 4 to 5", ""},
- {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HangHallAft", kScoreScript, 7, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HangHallAft", kScoreScript, 7, DEFAULT_CAST_LIB,
4, "Frames 20 to 20", ""},
// Stray 'then' (obvious copy/paste error)
- {"warlock", nullptr, kPlatformMacintosh, "DATA:K:KT:OutMarauderKT", kMovieScript, 14, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:K:KT:OutMarauderKT", kMovieScript, 14, DEFAULT_CAST_LIB,
23, "set Spacesuit = 0 then", "set Spacesuit = 0"},
// Missing '&'
- {"warlock", nullptr, kPlatformMacintosh, "DATA:NAV:Shared Cast", kMovieScript, 510, 0,
+ {"warlock", nullptr, kPlatformMacintosh, "DATA:NAV:Shared Cast", kMovieScript, 510, DEFAULT_CAST_LIB,
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", "v1.1.3 MPC", kPlatformWindows, "WRLCKSHP:UpForeECall", kScoreScript, 12, 0,
+ {"warlock", "v1.1.3 MPC", kPlatformWindows, "WRLCKSHP:UpForeECall", kScoreScript, 12, DEFAULT_CAST_LIB,
2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
- {"warlock", "v1.1.3 MPC", kPlatformWindows, "WRLCKSHP:UpForeECall", kScoreScript, 12, 0,
+ {"warlock", "v1.1.3 MPC", kPlatformWindows, "WRLCKSHP:UpForeECall", kScoreScript, 12, DEFAULT_CAST_LIB,
3, "Channels 17 to 18", ""},
- {"warlock", "v1.1.3 MPC", kPlatformWindows, "WRLCKSHP:UpForeECall", kScoreScript, 12, 0,
+ {"warlock", "v1.1.3 MPC", kPlatformWindows, "WRLCKSHP:UpForeECall", kScoreScript, 12, DEFAULT_CAST_LIB,
4, "Frames 150 to 160", ""},
// Missing '&'
- {"warlock", nullptr, kPlatformUnknown, "NAV:Shared Cast", kMovieScript, 510, 0,
+ {"warlock", nullptr, kPlatformUnknown, "NAV:Shared Cast", kMovieScript, 510, DEFAULT_CAST_LIB,
23, "alert \"Failed Save.\" & return & \"Error message number: \" string ( filer )",
"alert \"Failed Save.\" & return & \"Error message number: \" & string ( filer )"},
// Non-existent menu cast reference
- {"warlock", nullptr, kPlatformWindows, "STARBIRD:ABOUT", kScoreScript, 4, 0,
+ {"warlock", nullptr, kPlatformWindows, "STARBIRD:ABOUT", kScoreScript, 4, DEFAULT_CAST_LIB,
1, "installmenu A13", ""},
// Patching dead loop which was fixed in v2
- {"lzone", "", kPlatformMacintosh, "DATA:R-A:Ami-00", kScoreScript, 3, 0,
+ {"lzone", "", kPlatformMacintosh, "DATA:R-A:Ami-00", kScoreScript, 3, DEFAULT_CAST_LIB,
2, "continue", "go \"OUT\""},
// Garbage at end of statements
- {"lzone", "", kPlatformMacintosh, "DATA:R-E:ZD2-LAS", kScoreScript, 7, 0,
+ {"lzone", "", kPlatformMacintosh, "DATA:R-E:ZD2-LAS", kScoreScript, 7, DEFAULT_CAST_LIB,
4, "go to the frame 0", "go to the frame"},
- {"lzone", "", kPlatformMacintosh, "DATA:R-E:zd1-con1", kScoreScript, 27, 0,
+ {"lzone", "", kPlatformMacintosh, "DATA:R-E:zd1-con1", kScoreScript, 27, DEFAULT_CAST_LIB,
1, "go to the frame 0", "go to the frame"},
- {"lzone", "", kPlatformMacintosh, "DATA:R-E:zd1-con1", kScoreScript, 30, 0,
+ {"lzone", "", kPlatformMacintosh, "DATA:R-E:zd1-con1", kScoreScript, 30, DEFAULT_CAST_LIB,
4, "go the frame 0", "go to the frame"},
- {"lzone", "", kPlatformMacintosh, "DATA:R-G:st-c", kScoreScript, 14, 0,
+ {"lzone", "", kPlatformMacintosh, "DATA:R-G:st-c", kScoreScript, 14, DEFAULT_CAST_LIB,
1, "go to the frame 0", "go to the frame"},
- {"lzone", "", kPlatformMacintosh, "DATA:R-G:st-d.mo", kScoreScript, 4, 0,
+ {"lzone", "", kPlatformMacintosh, "DATA:R-G:st-d.mo", kScoreScript, 4, DEFAULT_CAST_LIB,
1, "go to the frame 0", "go to the frame"},
- {"lzone", "", kPlatformMacintosh, "DATA:R-F:ARCH-U.D-1", kScoreScript, 8, 0,
+ {"lzone", "", kPlatformMacintosh, "DATA:R-F:ARCH-U.D-1", kScoreScript, 8, DEFAULT_CAST_LIB,
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\""},
- {"lingoexpo", "", kPlatformMacintosh, "Lingo Expo:Navigator", kMovieScript, 9, 0,
+ {"lingoexpo", "", kPlatformMacintosh, "Lingo Expo:Navigator", kMovieScript, 9, DEFAULT_CAST_LIB,
97, " append(codeExampleList,\"6,301,302,303,304,305,306\") - KIOSK SCRIPTS",
" append(codeExampleList,\"6,301,302,303,304,305,306\")"},
- {"jman", "", kPlatformWindows, "mmm:Mars Space Game 05", kMovieScript, 10, 0,
+ {"jman", "", kPlatformWindows, "mmm:Mars Space Game 05", kMovieScript, 10, DEFAULT_CAST_LIB,
68, "set DamageParameter = (gProcessorSpeed/2) + 7)",
"set DamageParameter = (gProcessorSpeed/2) + 7"},
- {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, 0,
+ {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, DEFAULT_CAST_LIB,
187, "set the trails of sprite 19 to 0", "set the locH of sprite 19 to 408"},
- {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, 0,
+ {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, DEFAULT_CAST_LIB,
188, "set the locH of sprite 19 to 408", "set the locV of sprite 19 to 168"},
- {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, 0,
+ {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, DEFAULT_CAST_LIB,
189, "set the locV of sprite 19 to 168", "set the text of field \"Description\" = description"},
- {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, 0,
+ {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, DEFAULT_CAST_LIB,
190, "set the text of field \"Description\" = description", "set the castnum of sprite 19 to the number of cast \"Description\""},
- {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, 0,
+ {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, DEFAULT_CAST_LIB,
191, "set the castnum of sprite 19 to the number of cast \"Description\"", "updateStage"},
- {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, 0,
+ {"jman", "", kPlatformWindows, "MMM:Shared Cast B&W", kMovieScript, 323, DEFAULT_CAST_LIB,
192, "updateStage", "set the trails of sprite 19 to 0"},
- {"snh", "Hybrid release", kPlatformWindows, "SNHstart", kMovieScript, 0, 0,
+ {"snh", "Hybrid release", kPlatformWindows, "SNHstart", kMovieScript, 0, DEFAULT_CAST_LIB,
3, "changedrive", ""}, // HACK: This macro inserts \x01 after the first character in myCD/myHD
- {"snh", "Hybrid release", kPlatformWindows, "SNHstart", kMovieScript, 0, 0,
+ {"snh", "Hybrid release", kPlatformWindows, "SNHstart", kMovieScript, 0, DEFAULT_CAST_LIB,
6, "set mytest2 = FileIO(mnew, \"read\" mymovie)", "set mytest2 = FileIO(mnew, \"read\", mymovie)"},
- {"snh", "Hybrid release", kPlatformWindows, "SNHstart", kMovieScript, 0, 0,
+ {"snh", "Hybrid release", kPlatformWindows, "SNHstart", kMovieScript, 0, DEFAULT_CAST_LIB,
14, "set mytest3 = FileIO(mnew, \"read\" mymovie)", "set mytest3 = FileIO(mnew, \"read\", mymovie)"},
// Ambiguous syntax that's parsed differently between D3 and later versions
- {"henachoco03", "", kPlatformMacintosh, "xn--oj7cxalkre7cjz1d2agc0e8b1cm", kMovieScript, 0, 0,
+ {"henachoco03", "", kPlatformMacintosh, "xn--oj7cxalkre7cjz1d2agc0e8b1cm", kMovieScript, 0, DEFAULT_CAST_LIB,
183, "locaobject(mLHizikaraHand (rhenka + 1),dotti)", "locaobject(mLHizikaraHand,(rhenka + 1),dotti)"},
- {"henachoco03", "", kPlatformMacintosh, "xn--oj7cxalkre7cjz1d2agc0e8b1cm", kMovieScript, 0, 0,
+ {"henachoco03", "", kPlatformMacintosh, "xn--oj7cxalkre7cjz1d2agc0e8b1cm", kMovieScript, 0, DEFAULT_CAST_LIB,
196, "locaobject(mRHizikaraHand (rhenka + 1),dotti)", "locaobject(mRHizikaraHand,(rhenka + 1),dotti)"},
// Same patch applied to the demos, with different line numbers
- {"henachoco03", "Trial Version", kPlatformMacintosh, "ITA Choco", kMovieScript, 0, 0,
+ {"henachoco03", "Trial Version", kPlatformMacintosh, "ITA Choco", kMovieScript, 0, DEFAULT_CAST_LIB,
123, "locaobject(mLHizikaraHand (rhenka + 1),dotti)", "locaobject(mLHizikaraHand,(rhenka + 1),dotti)"},
- {"henachoco03", "Trial Version", kPlatformMacintosh, "ITA Choco", kMovieScript, 0, 0,
+ {"henachoco03", "Trial Version", kPlatformMacintosh, "ITA Choco", kMovieScript, 0, DEFAULT_CAST_LIB,
136, "locaobject(mRHizikaraHand (rhenka + 1),dotti)", "locaobject(mRHizikaraHand,(rhenka + 1),dotti)"},
- {"henachoco03", "Demo", kPlatformMacintosh, "Muzukashiihon", kMovieScript, 0, 0,
+ {"henachoco03", "Demo", kPlatformMacintosh, "Muzukashiihon", kMovieScript, 0, DEFAULT_CAST_LIB,
123, "locaobject(mLHizikaraHand (rhenka + 1),dotti)", "locaobject(mLHizikaraHand,(rhenka + 1),dotti)"},
- {"henachoco03", "Demo", kPlatformMacintosh, "Muzukashiihon", kMovieScript, 0, 0,
+ {"henachoco03", "Demo", kPlatformMacintosh, "Muzukashiihon", kMovieScript, 0, DEFAULT_CAST_LIB,
136, "locaobject(mRHizikaraHand (rhenka + 1),dotti)", "locaobject(mRHizikaraHand,(rhenka + 1),dotti)"},
// C.H.A.O.S
- {"chaos", "", kPlatformWindows, "Intro", kCastScript, 10, 0,
+ {"chaos", "", kPlatformWindows, "Intro", kCastScript, 10, DEFAULT_CAST_LIB,
9, "rHyperPACo \"blank\", 498, 350 gGenPathWay", "rHyperPACo \"blank\", 498, 350, gGenPathWay"},
- {"smile", "v1.1", kPlatformMacintosh, "SMILE! The Splattering", kScoreScript, 24, 0,
+ {"smile", "v1.1", kPlatformMacintosh, "SMILE! The Splattering", kScoreScript, 24, DEFAULT_CAST_LIB,
1, "go to frame \"Info b\"If you have not paid ", "go to frame \"Info b\""},
- {"amandastories", "", kPlatformWindows, "Shared Cast", kMovieScript, 512, 0,
+ {"amandastories", "", kPlatformWindows, "Shared Cast", kMovieScript, 512, DEFAULT_CAST_LIB,
55, " set mytest1 = FileIO(mnew, \"read\" mymovie)", " set mytest1 = FileIO(mnew, \"read\", mymovie)"},
- {"amandastories", "", kPlatformWindows, "Shared Cast", kMovieScript, 512, 0,
+ {"amandastories", "", kPlatformWindows, "Shared Cast", kMovieScript, 512, DEFAULT_CAST_LIB,
63, " set mytest2 = FileIO(mnew, \"read\" mymovie)", " set mytest2 = FileIO(mnew, \"read\", mymovie)"},
- {"amandastories", "", kPlatformWindows, "Shared Cast", kMovieScript, 512, 0,
+ {"amandastories", "", kPlatformWindows, "Shared Cast", kMovieScript, 512, DEFAULT_CAST_LIB,
70, " set mytest3 = FileIO(mnew, \"read\" mymovie)", " set mytest3 = FileIO(mnew, \"read\", mymovie)"},
- {"amandastories", "", kPlatformWindows, "ASstart", kMovieScript, 0, 0,
+ {"amandastories", "", kPlatformWindows, "ASstart", kMovieScript, 0, DEFAULT_CAST_LIB,
5, " set mytest = FileIO(mnew, \"read\" mymovie)", " set mytest = FileIO(mnew, \"read\", mymovie)"},
- {"amandastories", "", kPlatformWindows, "ASstart", kMovieScript, 0, 0,
+ {"amandastories", "", kPlatformWindows, "ASstart", kMovieScript, 0, DEFAULT_CAST_LIB,
11, " set mytest2 = FileIO(mnew, \"read\" mymovie)", " set mytest2 = FileIO(mnew, \"read\", mymovie)"},
- {"amandastories", "", kPlatformWindows, "ASstart", kMovieScript, 0, 0,
+ {"amandastories", "", kPlatformWindows, "ASstart", kMovieScript, 0, DEFAULT_CAST_LIB,
19, " set mytest3 = FileIO(mnew, \"read\" mymovie)", " set mytest3 = FileIO(mnew, \"read\", mymovie)"},
- {"erikotamuraoz", "Demo", kPlatformMacintosh, "Shared Cast", kMovieScript, 391, 0,
+ {"erikotamuraoz", "Demo", kPlatformMacintosh, "Shared Cast", kMovieScript, 391, DEFAULT_CAST_LIB,
21, "", "end repeat"},
Commit: 49f38f28ded694617a3558c5c8935e544d8ec954
https://github.com/scummvm/scummvm/commit/49f38f28ded694617a3558c5c8935e544d8ec954
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Add new kClutSystemWinD5 palette
Changed paths:
engines/director/graphics-data.h
engines/director/graphics.cpp
engines/director/types.h
diff --git a/engines/director/graphics-data.h b/engines/director/graphics-data.h
index 081c93bf61d..c60bcb4f62c 100644
--- a/engines/director/graphics-data.h
+++ b/engines/director/graphics-data.h
@@ -559,6 +559,13 @@ static byte win16Palette[48] = {
0xbf, 0xbf, 0x00, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, // 12 (0x0c)
};
+static byte winD516Palette[48] = {
+ 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, // 0 (0x00)
+ 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x80, 0x80, 0x80, // 4 (0x04)
+ 0xa0, 0xa0, 0xa4, 0x00, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x80, // 8 (0x08)
+ 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // 12 (0x0c)
+};
+
static byte winPalette[768] = {
0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, // 0 (0x00)
0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x80, 0x80, 0x80, // 4 (0x04)
@@ -626,6 +633,74 @@ static byte winPalette[768] = {
0xbf, 0xbf, 0x00, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, // 252 (0xfc)
};
+static byte winD5Palette[768] = {
+ 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, // 0 (0x00)
+ 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x80, 0x80, 0x80, // 4 (0x04)
+ 0xa0, 0xa0, 0xa4, 0xff, 0xfb, 0xf0, 0x33, 0x33, 0x33, 0x99, 0x66, 0x00, // 8 (0x08)
+ 0x33, 0x66, 0x33, 0x00, 0x33, 0x99, 0xcc, 0x00, 0xff, 0x88, 0x00, 0x00, // 12 (0x0c)
+ 0xff, 0xcc, 0x66, 0xff, 0x99, 0xcc, 0xdd, 0xdd, 0xdd, 0xff, 0x99, 0x00, // 16 (0x10)
+ 0xff, 0x66, 0xff, 0xff, 0x66, 0xcc, 0xff, 0x66, 0x99, 0xff, 0x66, 0x66, // 20 (0x14)
+ 0xff, 0x66, 0x33, 0xff, 0x66, 0x00, 0xff, 0x33, 0xff, 0xff, 0x33, 0xcc, // 24 (0x18)
+ 0xff, 0x33, 0x99, 0xff, 0x33, 0x66, 0xff, 0x33, 0x33, 0xff, 0x33, 0x00, // 28 (0x1c)
+ 0xff, 0x00, 0xcc, 0xff, 0x00, 0x99, 0xff, 0x00, 0x66, 0xff, 0x00, 0x33, // 32 (0x20)
+ 0xcc, 0xff, 0xff, 0xcc, 0xff, 0xcc, 0xcc, 0xff, 0x99, 0xcc, 0xff, 0x66, // 36 (0x24)
+ 0xcc, 0xff, 0x33, 0xcc, 0xff, 0x00, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, // 40 (0x28)
+ 0xcc, 0xcc, 0x99, 0xcc, 0xcc, 0x66, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, 0x00, // 44 (0x2c)
+ 0xcc, 0x99, 0xff, 0xcc, 0x99, 0xcc, 0xcc, 0x99, 0x99, 0xcc, 0x99, 0x66, // 48 (0x30)
+ 0xcc, 0x99, 0x33, 0xcc, 0x99, 0x00, 0xcc, 0x66, 0xff, 0xcc, 0x66, 0xcc, // 52 (0x34)
+ 0xcc, 0x66, 0x99, 0xcc, 0x66, 0x66, 0xcc, 0x66, 0x33, 0xcc, 0x66, 0x00, // 56 (0x38)
+ 0xcc, 0x33, 0xff, 0xcc, 0x33, 0xcc, 0xcc, 0x33, 0x99, 0xcc, 0x33, 0x66, // 60 (0x3c)
+ 0xcc, 0x33, 0x33, 0xcc, 0x33, 0x00, 0xd4, 0x08, 0xff, 0xcc, 0x00, 0xcc, // 64 (0x40)
+ 0xcc, 0x00, 0x99, 0xcc, 0x00, 0x66, 0xcc, 0x00, 0x33, 0xcc, 0x00, 0x00, // 68 (0x44)
+ 0x99, 0xff, 0xff, 0x99, 0xff, 0xcc, 0x99, 0xff, 0x99, 0x99, 0xff, 0x66, // 72 (0x48)
+ 0x99, 0xff, 0x33, 0x99, 0xff, 0x00, 0x99, 0xcc, 0xff, 0x99, 0xcc, 0xcc, // 76 (0x4c)
+ 0x99, 0xcc, 0x99, 0x99, 0xcc, 0x66, 0x99, 0xcc, 0x33, 0x99, 0xcc, 0x00, // 80 (0x50)
+ 0x99, 0x99, 0xff, 0x99, 0x99, 0xcc, 0x99, 0x99, 0x99, 0x99, 0x99, 0x66, // 84 (0x54)
+ 0x99, 0x99, 0x33, 0x99, 0x99, 0x00, 0x99, 0x66, 0xff, 0x99, 0x66, 0xcc, // 88 (0x58)
+ 0x99, 0x66, 0x99, 0x99, 0x66, 0x66, 0x99, 0x66, 0x33, 0xa1, 0x66, 0x00, // 92 (0x5c)
+ 0x99, 0x33, 0xff, 0x99, 0x33, 0xcc, 0x99, 0x33, 0x99, 0x99, 0x33, 0x66, // 96 (0x60)
+ 0x99, 0x33, 0x33, 0x99, 0x33, 0x00, 0x99, 0x00, 0xff, 0x99, 0x00, 0xcc, // 100 (0x64)
+ 0x99, 0x00, 0x99, 0x99, 0x00, 0x66, 0x99, 0x00, 0x33, 0x99, 0x00, 0x00, // 104 (0x68)
+ 0x66, 0xff, 0xff, 0x66, 0xff, 0xcc, 0x66, 0xff, 0x99, 0x66, 0xff, 0x66, // 108 (0x6c)
+ 0x66, 0xff, 0x33, 0x66, 0xff, 0x00, 0x66, 0xcc, 0xff, 0x66, 0xcc, 0xcc, // 112 (0x70)
+ 0x66, 0xcc, 0x99, 0x66, 0xcc, 0x66, 0x66, 0xcc, 0x33, 0x66, 0xcc, 0x00, // 116 (0x74)
+ 0x66, 0x99, 0xff, 0x66, 0x99, 0xcc, 0x66, 0x99, 0x99, 0x66, 0x99, 0x66, // 120 (0x78)
+ 0x66, 0x99, 0x33, 0x66, 0x99, 0x00, 0x66, 0x66, 0xff, 0x66, 0x66, 0xcc, // 124 (0x7c)
+ 0x66, 0x66, 0x99, 0x66, 0x66, 0x66, 0x66, 0x66, 0x33, 0x66, 0x66, 0x00, // 128 (0x80)
+ 0x66, 0x33, 0xff, 0x66, 0x33, 0xcc, 0x66, 0x33, 0x99, 0x66, 0x33, 0x66, // 132 (0x84)
+ 0x66, 0x33, 0x33, 0x66, 0x33, 0x00, 0x66, 0x00, 0xff, 0x66, 0x00, 0xcc, // 136 (0x88)
+ 0x66, 0x00, 0x99, 0x66, 0x00, 0x66, 0x66, 0x00, 0x33, 0x66, 0x00, 0x00, // 140 (0x8c)
+ 0x33, 0xff, 0xff, 0x33, 0xff, 0xcc, 0x33, 0xff, 0x99, 0x33, 0xff, 0x66, // 144 (0x90)
+ 0x33, 0xff, 0x33, 0x33, 0xff, 0x00, 0x33, 0xcc, 0xff, 0x33, 0xcc, 0xcc, // 148 (0x94)
+ 0x33, 0xcc, 0x99, 0x33, 0xcc, 0x66, 0x33, 0xcc, 0x33, 0x33, 0xcc, 0x00, // 152 (0x98)
+ 0x33, 0x99, 0xff, 0x33, 0x99, 0xcc, 0x33, 0x99, 0x99, 0x33, 0x99, 0x66, // 156 (0x9c)
+ 0x33, 0x99, 0x33, 0x33, 0x99, 0x00, 0x33, 0x66, 0xff, 0x33, 0x66, 0xcc, // 160 (0xa0)
+ 0x33, 0x66, 0x99, 0x33, 0x66, 0x66, 0x33, 0x6e, 0x33, 0x33, 0x66, 0x00, // 164 (0xa4)
+ 0x33, 0x33, 0xff, 0x33, 0x33, 0xcc, 0x33, 0x33, 0x99, 0x33, 0x33, 0x66, // 168 (0xa8)
+ 0x33, 0x33, 0x3b, 0x33, 0x33, 0x00, 0x33, 0x00, 0xff, 0x33, 0x00, 0xcc, // 172 (0xac)
+ 0x33, 0x00, 0x99, 0x33, 0x00, 0x66, 0x33, 0x00, 0x33, 0x33, 0x00, 0x00, // 176 (0xb0)
+ 0x00, 0xff, 0xcc, 0x00, 0xff, 0x99, 0x00, 0xff, 0x66, 0x00, 0xff, 0x33, // 180 (0xb4)
+ 0x00, 0xcc, 0xff, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0x99, 0x00, 0xcc, 0x66, // 184 (0xb8)
+ 0x00, 0xcc, 0x33, 0x00, 0xcc, 0x00, 0x00, 0x99, 0xff, 0x00, 0x99, 0xcc, // 188 (0xbc)
+ 0x00, 0x99, 0x99, 0x00, 0x99, 0x66, 0x00, 0x99, 0x33, 0x00, 0x99, 0x00, // 192 (0xc0)
+ 0x00, 0x66, 0xff, 0x00, 0x66, 0xcc, 0x00, 0x66, 0x99, 0x00, 0x66, 0x66, // 196 (0xc4)
+ 0x00, 0x66, 0x33, 0x00, 0x66, 0x00, 0x00, 0x33, 0xff, 0x00, 0x33, 0xcc, // 200 (0xc8)
+ 0x00, 0x33, 0xa1, 0x00, 0x33, 0x66, 0x00, 0x33, 0x33, 0x00, 0x33, 0x00, // 204 (0xcc)
+ 0x00, 0x00, 0xcc, 0x00, 0x00, 0x99, 0x00, 0x00, 0x66, 0x00, 0x00, 0x33, // 208 (0xd0)
+ 0xee, 0x00, 0x00, 0xdd, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x90, 0x00, 0x00, // 212 (0xd4)
+ 0x77, 0x00, 0x00, 0x55, 0x00, 0x00, 0x44, 0x00, 0x00, 0x22, 0x00, 0x00, // 216 (0xd8)
+ 0x11, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0xdd, 0x00, 0x00, 0xaa, 0x00, // 220 (0xdc)
+ 0x00, 0x88, 0x00, 0x00, 0x77, 0x00, 0x00, 0x55, 0x00, 0x00, 0x44, 0x00, // 224 (0xe0)
+ 0x00, 0x22, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0xdd, // 228 (0xe4)
+ 0x00, 0x00, 0xaa, 0x00, 0x00, 0x88, 0x00, 0x00, 0x77, 0x00, 0x00, 0x55, // 232 (0xe8)
+ 0x00, 0x00, 0x44, 0x00, 0x00, 0x22, 0x00, 0x00, 0x11, 0x22, 0x22, 0x30, // 236 (0xec)
+ 0xff, 0x99, 0x99, 0xff, 0xcc, 0xff, 0x99, 0xd4, 0xff, 0x99, 0xd4, 0x99, // 240 (0xf0)
+ 0xff, 0xff, 0x99, 0xf0, 0xf0, 0xf0, 0xa6, 0xc8, 0xf0, 0xc0, 0xdc, 0xc0, // 244 (0xf4)
+ 0xc0, 0xc0, 0xc0, 0x00, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x80, // 248 (0xf8)
+ 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // 252 (0xfc)
+};
+
+
// For 2-bit and 4-bit graphics, Director assumes a fixed palette and uses nearest-neighbour
// remapping to the current movie palette.
diff --git a/engines/director/graphics.cpp b/engines/director/graphics.cpp
index 575b79a9577..84d4fbc8b09 100644
--- a/engines/director/graphics.cpp
+++ b/engines/director/graphics.cpp
@@ -116,6 +116,7 @@ void DirectorEngine::loadDefaultPalettes() {
_loadedPalettes[kClutNTSC] = PaletteV4(kClutNTSC, ntscPalette, 256);
_loadedPalettes[kClutMetallic] = PaletteV4(kClutMetallic, metallicPalette, 256);
_loadedPalettes[kClutSystemWin] = PaletteV4(kClutSystemWin, winPalette, 256);
+ _loadedPalettes[kClutSystemWinD5] = PaletteV4(kClutSystemWinD5, winD5Palette, 256);
_loaded16Palettes[kClutSystemMac] = PaletteV4(kClutSystemMac, mac16Palette, 16);
_loaded16Palettes[kClutRainbow] = PaletteV4(kClutRainbow, rainbow16Palette, 16);
@@ -125,6 +126,7 @@ void DirectorEngine::loadDefaultPalettes() {
_loaded16Palettes[kClutNTSC] = PaletteV4(kClutNTSC, ntsc16Palette, 16);
_loaded16Palettes[kClutMetallic] = PaletteV4(kClutMetallic, metallic16Palette, 16);
_loaded16Palettes[kClutSystemWin] = PaletteV4(kClutSystemWin, win16Palette, 16);
+ _loaded16Palettes[kClutSystemWinD5] = PaletteV4(kClutSystemWinD5, winD516Palette, 16);
_loaded4Palette = PaletteV4(kClutGrayscale, grayscale4Palette, 4);
}
diff --git a/engines/director/types.h b/engines/director/types.h
index bd86e562695..02f7c1ce700 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -292,7 +292,8 @@ enum PaletteType {
kClutVivid = -5,
kClutNTSC = -6,
kClutMetallic = -7,
- kClutSystemWin = -101
+ kClutSystemWin = -101,
+ kClutSystemWinD5 = -102
};
enum {
Commit: 2009f27712545efaa554bd8ce19b0873598653f0
https://github.com/scummvm/scummvm/commit/2009f27712545efaa554bd8ce19b0873598653f0
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Add D5 support for _defaultPalette
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
engines/director/castmember/bitmap.cpp
engines/director/debugger.cpp
engines/director/score.cpp
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 77d3195e085..421cbf452d8 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -77,7 +77,7 @@ Cast::Cast(Movie *movie, uint16 castLibID, bool isShared) {
_loadedStxts = nullptr;
_loadedCast = nullptr;
- _defaultPalette = -1;
+ _defaultPalette = CastMemberID(-1, -1);
}
Cast::~Cast() {
@@ -430,19 +430,32 @@ bool Cast::loadConfig() {
if (check != checksum)
warning("BUILDBOT: The checksum for this VWCF resource is incorrect. Got %04x, but expected %04x", check, checksum);
- /* int16 field30 = */ stream->readSint16();
-
- _defaultPalette = stream->readSint16();
- // In this header value, the first builtin palette starts at 0 and
- // continues down into negative numbers.
- // For frames, 0 is used to represent an absence of a palette change,
- // with the builtin palettes starting from -1.
- if (_defaultPalette <= 0)
- _defaultPalette -= 1;
- for (int i = 0; i < 0x08; i++) {
- stream->readByte();
+ if (_version >= kFileVer400 && _version < kFileVer500) {
+ /* int16 field30 = */ stream->readSint16();
+
+ _defaultPalette.member = stream->readSint16();
+ // In this header value, the first builtin palette starts at 0 and
+ // continues down into negative numbers.
+ // For frames, 0 is used to represent an absence of a palette change,
+ // with the builtin palettes starting from -1.
+ if (_defaultPalette.member <= 0)
+ _defaultPalette.member -= 1;
+ for (int i = 0; i < 0x08; i++) {
+ stream->readByte();
+ }
+ } else if (_version >= kFileVer500 && _version < kFileVer600) {
+ for (int i = 0; i < 0x08; i++) {
+ stream->readByte();
+ }
+ _defaultPalette.castLib = stream->readSint16();
+ _defaultPalette.member = stream->readSint16();
+ if (_defaultPalette.member <= 0)
+ _defaultPalette.member -= 1;
+
+ } else {
+ warning("STUB: Cast::loadConfig(): Extended config not yet supported for version %d", _version);
}
- debugC(1, kDebugLoading, "Cast::loadConfig(): platform: %s, defaultPalette: %d", getPlatformAbbrev(_platform), _defaultPalette);
+ debugC(1, kDebugLoading, "Cast::loadConfig(): platform: %s, defaultPalette: %s", getPlatformAbbrev(_platform), _defaultPalette.asString().c_str());
}
if (!_isShared) {
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 39e147f4007..62358b93aad 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -148,7 +148,7 @@ public:
Common::Rect _movieRect;
uint16 _stageColor;
- int _defaultPalette;
+ CastMemberID _defaultPalette;
TilePatternEntry _tiles[kNumBuiltinTiles];
LingoArchive *_lingoArchive;
diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index 084d9cf1221..64c57ab5c0d 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -217,7 +217,7 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
// Get the current score palette. Note that this is the ID of the palette in the list, not the cast member!
int currentPaletteId = score->resolvePaletteId(score->getCurrentPalette());
if (!currentPaletteId)
- currentPaletteId = cast->_defaultPalette;
+ currentPaletteId = cast->_defaultPalette.member;
PaletteV4 *currentPalette = g_director->getPalette(currentPaletteId);
if (!currentPalette) {
currentPaletteId = kClutSystemMac;
@@ -380,7 +380,7 @@ bool BitmapCastMember::isModified() {
Score *score = movie->getScore();
int currentPaletteId = score->resolvePaletteId(score->getCurrentPalette());
if (!currentPaletteId)
- currentPaletteId = cast->_defaultPalette;
+ currentPaletteId = cast->_defaultPalette.member;
PaletteV4 *currentPalette = g_director->getPalette(currentPaletteId);
if (!currentPalette) {
currentPaletteId = kClutSystemMac;
@@ -388,7 +388,7 @@ bool BitmapCastMember::isModified() {
}
int castPaletteId = score->resolvePaletteId(_clut);
if (!castPaletteId)
- castPaletteId = cast->_defaultPalette;
+ castPaletteId = cast->_defaultPalette.member;
if (currentPaletteId == castPaletteId) {
return _ditheredTargetClut != 0;
diff --git a/engines/director/debugger.cpp b/engines/director/debugger.cpp
index 248e91ddfdc..779eea01753 100644
--- a/engines/director/debugger.cpp
+++ b/engines/director/debugger.cpp
@@ -225,7 +225,7 @@ bool Debugger::cmdInfo(int argc, const char **argv) {
debugPrintf("Modified by: %s\n", movie->_changedBy.c_str());
debugPrintf("Original directory: %s\n", movie->_origDirectory.c_str());
debugPrintf("Stage size: %dx%d\n", movie->_movieRect.width(), movie->_movieRect.height());
- debugPrintf("Default palette ID: %d\n", cast->_defaultPalette);
+ debugPrintf("Default palette ID: %s\n", cast->_defaultPalette.asString().c_str());
debugPrintf("Default stage color: %d\n", cast->_stageColor);
debugPrintf("Copy protected: %d\n", cast->_isProtected);
debugPrintf("Remap palettes when needed flag: %d\n", movie->_remapPalettesWhenNeeded);
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 67fb026d673..4991d3cef33 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -110,7 +110,7 @@ int Score::resolvePaletteId(int id) {
// TODO: Palette ID should be a CastMemberID to allow for palettes in different casts
// 255 represent system palette in D2
if (id == 255) {
- id = g_director->getCurrentMovie()->getCast()->_defaultPalette;
+ id = g_director->getCurrentMovie()->getCast()->_defaultPalette.member;
} else if (id > 0) {
CastMember *member = _movie->getCastMember(CastMemberID(id, DEFAULT_CAST_LIB));
id = (member && member->_type == kCastPalette) ? ((PaletteCastMember *)member)->getPaletteId() : 0;
@@ -289,7 +289,7 @@ void Score::startPlay() {
_lastPalette = _frames[_currentFrame]->_palette.paletteId;
if (!_lastPalette)
- _lastPalette = _movie->getCast()->_defaultPalette;
+ _lastPalette = _movie->getCast()->_defaultPalette.member;
debugC(2, kDebugImages, "Score::startPlay(): palette changed to %d", _lastPalette);
_vm->setPalette(resolvePaletteId(_lastPalette));
@@ -777,7 +777,7 @@ void Score::setLastPalette(uint16 frameId) {
// The cached ID is created before the cast gets loaded; if it's zero,
// this corresponds to the movie default palette.
if (!currentPalette)
- currentPalette = g_director->getCurrentMovie()->getCast()->_defaultPalette;
+ currentPalette = g_director->getCurrentMovie()->getCast()->_defaultPalette.member;
// If for whatever reason this doesn't resolve, abort.
if (!currentPalette || !resolvePaletteId(currentPalette))
return;
@@ -1559,7 +1559,7 @@ void Score::loadActions(Common::SeekableReadStreamEndian &stream) {
Common::String Score::formatChannelInfo() {
Frame &frame = *_frames[_currentFrame];
Common::String result;
- int defaultPalette = g_director->getCurrentMovie()->getCast()->_defaultPalette;
+ int defaultPalette = g_director->getCurrentMovie()->getCast()->_defaultPalette.member;
result += Common::String::format("TMPO: tempo: %d, skipFrameFlag: %d, blend: %d, currentFPS: %d\n",
frame._tempo, frame._skipFrameFlag, frame._blend, _currentFrameRate);
if (frame._palette.paletteId) {
Commit: a439d0c7906f8ee558c7cf545174b2c628600925
https://github.com/scummvm/scummvm/commit/a439d0c7906f8ee558c7cf545174b2c628600925
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: XOBJ: Add QTVR stubs
Changed paths:
A engines/director/lingo/xlibs/qtvr.cpp
A engines/director/lingo/xlibs/qtvr.h
engines/director/module.mk
diff --git a/engines/director/lingo/xlibs/qtvr.cpp b/engines/director/lingo/xlibs/qtvr.cpp
new file mode 100644
index 00000000000..71945403935
--- /dev/null
+++ b/engines/director/lingo/xlibs/qtvr.cpp
@@ -0,0 +1,148 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**********************************************
+ *
+ * USED IN:
+ * Star Trek TNG Interactive Technial Manual
+ *
+ **********************************************/
+
+/*
+ * -- QTVRW External Factory. 14Oct94 GRB
+ * QTVRW
+ * X mDispose
+ * S mGetHPanAngle
+ * S mGetMovieRect
+ * I mGetNodeID
+ * I mGetQuality
+ * S mGetVPanAngle
+ * S mGetZoomAngle
+ * S mMouseOver
+ * S mName
+ * IS mNew, type
+ * ISII mOpenMovie filename, x, y
+ * II mSetActive mode
+ * XS mSetHPanAngle angle
+ * II mSetNodeID node
+ * II mSetQuality qual
+ * XOS mSetRolloverCallback factory, method
+ * IS mSetTransitionMode mode
+ * II mSetTransitionSpeed speed
+ * XS mSetVPanAngle angle
+ * XS mSetZoomAngle angle
+ * I mUpdate
+ */
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingo-utils.h"
+#include "director/lingo/xlibs/qtvr.h"
+
+
+namespace Director {
+
+const char *QTVR::xlibName = "QTVRW";
+const char *QTVR::fileNames[] = {
+ "QTVR",
+ "QTVR.QTC",
+ nullptr
+};
+
+static MethodProto xlibMethods[] = {
+ { "new", QTVR::m_new, 1, 1, 400 }, // D4
+ { "dispose", QTVR::m_dispose, 1, 1, 400 }, // D4
+ { "getHPanAngle", QTVR::m_getHPanAngle, 0, 0, 400 }, // D4
+ { "getMovieRect", QTVR::m_getMovieRect, 0, 0, 400 }, // D4
+ { "getNodeID", QTVR::m_getNodeID, 0, 0, 400 }, // D4
+ { "getQuality", QTVR::m_getQuality, 0, 0, 400 }, // D4
+ { "getVPanAngle", QTVR::m_getVPanAngle, 0, 0, 400 }, // D4
+ { "getZoomAngle", QTVR::m_getZoomAngle, 0, 0, 400 }, // D4
+ { "mouseOver", QTVR::m_mouseOver, 0, 0, 400 }, // D4
+ { "name", QTVR::m_name, 0, 0, 400 }, // D4
+ { "openMovie", QTVR::m_openMovie, 3, 3, 400 }, // D4
+ { "setActive", QTVR::m_setActive, 1, 1, 400 }, // D4
+ { "setHPanAngle", QTVR::m_setHPanAngle, 1, 1, 400 }, // D4
+ { "setNodeID", QTVR::m_setNodeID, 1, 1, 400 }, // D4
+ { "setQuality", QTVR::m_setQuality, 1, 1, 400 }, // D4
+ { "setRolloverCallback", QTVR::m_setQuality, 2, 2, 400 }, // D4
+ { "setTransitionMode", QTVR::m_setTransitionMode, 1, 1, 400 }, // D4
+ { "setTransitionSpeed", QTVR::m_setTransitionSpeed, 1, 1, 400 }, // D4
+ { "setVPanAngle", QTVR::m_setVPanAngle, 1, 1, 400 }, // D4
+ { "setZoomAngle", QTVR::m_setZoomAngle, 1, 1, 400 }, // D4
+ { "update", QTVR::m_update, 0, 0, 400 }, // D4
+};
+
+QTVRXObject::QTVRXObject(ObjectType ObjectType) :Object<QTVRXObject>("QTVR") {
+ _objType = ObjectType;
+}
+
+void QTVR::open(int type) {
+ if (type == kXObj) {
+ QTVRXObject::initMethods(xlibMethods);
+ QTVRXObject *xobj = new QTVRXObject(kXObj);
+ g_lingo->exposeXObject(xlibName, xobj);
+ } else if (type == kXtraObj) {
+ // TODO - Implement Xtra
+ }
+}
+
+void QTVR::close(int type) {
+ if (type == kXObj) {
+ QTVRXObject::cleanupMethods();
+ g_lingo->_globalvars[xlibName] = Datum();
+ } else if (type == kXtraObj) {
+ // TODO - Implement Xtra
+ }
+}
+
+
+void QTVR::m_new(int nargs) {
+ if (nargs != 0) {
+ warning("QTVR::m_new: expected 0 arguments");
+ g_lingo->dropStack(nargs);
+ }
+ g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUBNR(QTVR::m_dispose);
+XOBJSTUB(QTVR::m_getHPanAngle, "");
+XOBJSTUB(QTVR::m_getMovieRect, "");
+XOBJSTUB(QTVR::m_getNodeID, 0);
+XOBJSTUB(QTVR::m_getQuality, 0);
+XOBJSTUB(QTVR::m_getVPanAngle, "");
+XOBJSTUB(QTVR::m_getZoomAngle, "");
+XOBJSTUB(QTVR::m_mouseOver, "");
+XOBJSTUB(QTVR::m_name, "");
+XOBJSTUB(QTVR::m_openMovie, 0);
+XOBJSTUB(QTVR::m_setActive, 0);
+XOBJSTUBNR(QTVR::m_setHPanAngle);
+XOBJSTUB(QTVR::m_setNodeID, 0);
+XOBJSTUB(QTVR::m_setQuality, 0);
+XOBJSTUBNR(QTVR::m_setRolloverCallback);
+XOBJSTUB(QTVR::m_setTransitionMode, 0);
+XOBJSTUB(QTVR::m_setTransitionSpeed, 0);
+XOBJSTUBNR(QTVR::m_setVPanAngle);
+XOBJSTUBNR(QTVR::m_setZoomAngle);
+XOBJSTUB(QTVR::m_update, 0);
+
+} // End of namespace Director
diff --git a/engines/director/lingo/xlibs/qtvr.h b/engines/director/lingo/xlibs/qtvr.h
new file mode 100644
index 00000000000..bb7bfdc0075
--- /dev/null
+++ b/engines/director/lingo/xlibs/qtvr.h
@@ -0,0 +1,66 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XLIBS_QTVR_H
+#define DIRECTOR_LINGO_XLIBS_QTVR_H
+
+namespace Director {
+
+namespace QTVR {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(int type);
+void close(int type);
+
+void m_new(int nargs);
+void m_dispose(int nargs);
+void m_getHPanAngle(int nargs);
+void m_getMovieRect(int nargs);
+void m_getNodeID(int nargs);
+void m_getQuality(int nargs);
+void m_getVPanAngle(int nargs);
+void m_getZoomAngle(int nargs);
+void m_mouseOver(int nargs);
+void m_name(int nargs);
+void m_openMovie(int nargs);
+void m_setActive(int nargs);
+void m_setHPanAngle(int nargs);
+void m_setNodeID(int nargs);
+void m_setQuality(int nargs);
+void m_setRolloverCallback(int nargs);
+void m_setTransitionMode(int nargs);
+void m_setTransitionSpeed(int nargs);
+void m_setVPanAngle(int nargs);
+void m_setZoomAngle(int nargs);
+void m_update(int nargs);
+
+} // End of namespace QTVR
+
+class QTVRXObject : public Object<QTVRXObject> {
+public:
+ QTVRXObject(ObjectType objType);
+};
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index c47a2051064..b49033e894b 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -93,6 +93,7 @@ MODULE_OBJS = \
lingo/xlibs/prefpath.o \
lingo/xlibs/printomatic.o \
lingo/xlibs/qtmovie.o \
+ lingo/xlibs/qtvr.o \
lingo/xlibs/registercomponent.o \
lingo/xlibs/serialportxobj.o \
lingo/xlibs/soundjam.o \
Commit: b26a6f304ff266e19cfabe4c63574b7a9779474c
https://github.com/scummvm/scummvm/commit/b26a6f304ff266e19cfabe4c63574b7a9779474c
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Add version cutoff for cast member loaders
Changed paths:
engines/director/castmember/bitmap.cpp
engines/director/castmember/filmloop.cpp
engines/director/castmember/palette.cpp
engines/director/castmember/script.cpp
engines/director/castmember/shape.cpp
engines/director/castmember/sound.cpp
engines/director/lingo/lingo-builtins.cpp
diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index 64c57ab5c0d..5b7a68051bd 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -133,6 +133,8 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableRe
debug("BitmapCastMember: tail");
Common::hexdump(buf, tail);
}
+ } else {
+ warning("STUB: BitmapCastMember::BitmapCastMember(): Bitmaps not yet supported for version %d", version);
}
_tag = castTag;
diff --git a/engines/director/castmember/filmloop.cpp b/engines/director/castmember/filmloop.cpp
index 4f499892115..0074a4f53ad 100644
--- a/engines/director/castmember/filmloop.cpp
+++ b/engines/director/castmember/filmloop.cpp
@@ -422,7 +422,7 @@ void FilmLoopCastMember::load() {
warning("FilmLoopCastMember::load(): Expected 1 child for film loop cast, got %d", _children.size());
}
} else {
- warning("STUB: FilmLoopCastMember::load(): Film loops not supported for version %d", _cast->_version);
+ warning("STUB: FilmLoopCastMember::load(): Film loops not yet supported for version %d", _cast->_version);
}
_loaded = true;
diff --git a/engines/director/castmember/palette.cpp b/engines/director/castmember/palette.cpp
index 15d2866b223..5dc96170014 100644
--- a/engines/director/castmember/palette.cpp
+++ b/engines/director/castmember/palette.cpp
@@ -48,13 +48,17 @@ void PaletteCastMember::load() {
// TODO: Verify how palettes work in >D4 versions
int paletteId = 0;
- if (_cast->_version >= kFileVer400 && _cast->_version < kFileVer500 && _children.size() == 1) {
- paletteId = _children[0].index;
- } else if (_cast->_version < kFileVer400) {
+ if (_cast->_version < kFileVer400) {
// For D3 and below, palette IDs are stored in the CLUT resource as cast ID + 1024
paletteId = _castId + _cast->_castIDoffset;
+ } else if (_cast->_version >= kFileVer400 && _cast->_version < kFileVer600) {
+ if (_children.size() == 1) {
+ paletteId = _children[0].index;
+ } else {
+ warning("PaletteCastMember::load(): Expected 1 child for palette cast, got %d", _children.size());
+ }
} else {
- warning("PaletteCastMember::load(): Expected 1 child for palette cast, got %d", _children.size());
+ warning("STUB: PaletteCastMember::load(): Palettes not yet supported for version %d", _cast->_version);
}
if (paletteId) {
debugC(2, kDebugImages, "PaletteCastMember::load(): linking palette id %d to cast index %d", paletteId, _castId);
diff --git a/engines/director/castmember/script.cpp b/engines/director/castmember/script.cpp
index f9250597efd..253cf799cc9 100644
--- a/engines/director/castmember/script.cpp
+++ b/engines/director/castmember/script.cpp
@@ -55,6 +55,8 @@ ScriptCastMember::ScriptCastMember(Cast *cast, uint16 castId, Common::SeekableRe
stream.readByte(); // There should be no more data
assert(stream.eos());
+ } else {
+ warning("STUB: ScriptCastMember::ScriptCastMember(): Scripts not yet supported for version %d", version);
}
}
diff --git a/engines/director/castmember/shape.cpp b/engines/director/castmember/shape.cpp
index 4036db4191d..c5a3ec1f86f 100644
--- a/engines/director/castmember/shape.cpp
+++ b/engines/director/castmember/shape.cpp
@@ -33,6 +33,11 @@ ShapeCastMember::ShapeCastMember(Cast *cast, uint16 castId, Common::SeekableRead
_ink = kInkTypeCopy;
+ if (debugChannelSet(5, kDebugLoading)) {
+ debugC(5, kDebugLoading, "ShapeCastMember::ShapeCastMember(): Shape data");
+ stream.hexdump(stream.size());
+ }
+
if (version < kFileVer400) {
unk1 = stream.readByte();
_shapeType = static_cast<ShapeType>(stream.readByte());
@@ -45,7 +50,7 @@ ShapeCastMember::ShapeCastMember(Cast *cast, uint16 castId, Common::SeekableRead
_ink = static_cast<InkType>(_fillType & 0x3f);
_lineThickness = stream.readByte();
_lineDirection = stream.readByte();
- } else if (version >= kFileVer400 && version < kFileVer500) {
+ } else if (version >= kFileVer400 && version < kFileVer600) {
unk1 = stream.readByte();
_shapeType = static_cast<ShapeType>(stream.readByte());
_initialRect = Movie::readRect(stream);
@@ -57,12 +62,8 @@ ShapeCastMember::ShapeCastMember(Cast *cast, uint16 castId, Common::SeekableRead
_lineThickness = stream.readByte();
_lineDirection = stream.readByte();
} else {
- stream.readByte(); // FIXME: Was this copied from D4 by mistake?
- unk1 = stream.readByte();
-
- _initialRect = Movie::readRect(stream);
- _boundingRect = Movie::readRect(stream);
-
+ warning("STUB: ShapeCastMember::ShapeCastMember(): not yet implemented");
+ unk1 = 0;
_shapeType = kShapeRectangle;
_pattern = 0;
_fgCol = _bgCol = 0;
diff --git a/engines/director/castmember/sound.cpp b/engines/director/castmember/sound.cpp
index ed6dd45e974..79972425456 100644
--- a/engines/director/castmember/sound.cpp
+++ b/engines/director/castmember/sound.cpp
@@ -48,12 +48,23 @@ void SoundCastMember::load() {
if (_loaded)
return;
- uint32 tag = MKTAG('S', 'N', 'D', ' ');
- uint16 sndId = (uint16)(_castId + _cast->_castIDoffset);
-
- if (_cast->_version >= kFileVer400 && _children.size() > 0) {
- sndId = _children[0].index;
- tag = _children[0].tag;
+ uint32 tag = 0;
+ uint16 sndId = 0;
+
+ if (_cast->_version < kFileVer400) {
+ tag = MKTAG('S', 'N', 'D', ' ');
+ sndId = (uint16)(_castId + _cast->_castIDoffset);
+ } else if (_cast->_version >= kFileVer400 && _cast->_version < kFileVer500) {
+ if (_children.size() > 0) {
+ sndId = _children[0].index;
+ tag = _children[0].tag;
+ } else {
+ warning("SoundCastMember::load(): could not find child reference, falling back to D3");
+ tag = MKTAG('S', 'N', 'D', ' ');
+ sndId = (uint16)(_castId + _cast->_castIDoffset);
+ }
+ } else {
+ warning("STUB: SoundCastMember::SoundCastMember(): Sounds not yet supported for version %d", _cast->_version);
}
Common::SeekableReadStreamEndian *sndData = _cast->getResource(tag, sndId);
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index e4b31682dcd..76604c8458a 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -321,7 +321,7 @@ void Lingo::printSTUBWithArglist(const char *funcname, int nargs, const char *pr
s += ")";
- debug(5, "%s %s", prefix, s.c_str());
+ debug(3, "%s %s", prefix, s.c_str());
}
void Lingo::convertVOIDtoString(int arg, int nargs) {
Commit: 0a3b7ee462585204ce550a2c538ef1870316fcc4
https://github.com/scummvm/scummvm/commit/0a3b7ee462585204ce550a2c538ef1870316fcc4
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Load in external casts and members
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
engines/director/detection.cpp
engines/director/movie.cpp
engines/director/movie.h
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 421cbf452d8..e0a1bce3e91 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -51,13 +51,14 @@
namespace Director {
-Cast::Cast(Movie *movie, uint16 castLibID, bool isShared) {
+Cast::Cast(Movie *movie, uint16 castLibID, bool isShared, bool isExternal) {
_movie = movie;
_vm = _movie->getVM();
_lingo = _vm->getLingo();
_castLibID = castLibID;
_isShared = isShared;
+ _isExternal = isExternal;
_loadMutex = true;
_lingoArchive = new LingoArchive(this);
@@ -78,6 +79,7 @@ Cast::Cast(Movie *movie, uint16 castLibID, bool isShared) {
_loadedCast = nullptr;
_defaultPalette = CastMemberID(-1, -1);
+ _frameRate = 0;
}
Cast::~Cast() {
@@ -274,9 +276,6 @@ bool Cast::loadConfig() {
else
_movieRect = g_director->_fixStageRect;
- if (!_isShared)
- _movie->_movieRect = _movieRect;
-
_castArrayStart = stream->readUint16();
_castArrayEnd = stream->readUint16();
@@ -284,29 +283,28 @@ bool Cast::loadConfig() {
// actual framerates are, on average: { 3.75, 4, 4.35, 4.65, 5, 5.5, 6, 6.6, 7.5, 8.5, 10, 12, 20, 30, 60 }
Common::Array<int> frameRates = { 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 10, 12, 15, 20, 30, 60 };
byte readRate = stream->readByte();
- int16 currentFrameRate;
if (readRate <= 0xF) {
- currentFrameRate = frameRates[readRate];
+ _frameRate = frameRates[readRate];
} else {
switch (readRate) {
// rate when set via the tempo channel
// these rates are the actual framerates
case 0x10:
// defaults to 15 fps on D2 and D3. On D4 it shows as 120 fps
- currentFrameRate = 15;
+ _frameRate = 15;
break;
case 212:
- currentFrameRate = 1;
+ _frameRate = 1;
break;
case 242:
- currentFrameRate = 2;
+ _frameRate = 2;
break;
case 252:
- currentFrameRate = 3;
+ _frameRate = 3;
break;
default:
warning("BUILDBOT: Cast::loadConfig: unhandled framerate: %i", readRate);
- currentFrameRate = readRate;
+ _frameRate = readRate;
}
}
@@ -327,9 +325,6 @@ bool Cast::loadConfig() {
if (humanVer >= 700)
warning("STUB: Cast::loadConfig: 16 bit stageColor read instead of two 8 bit isStageColorRGB and stageColorR. Read value: %04x", _stageColor);
- if (!_isShared)
- _movie->_stageColor = _vm->transformColor(_stageColor);
-
uint16 bitdepth = stream->readUint16();
// byte color = stream.readByte(); // boolean, color = 1, B/W = 0
@@ -372,7 +367,7 @@ bool Cast::loadConfig() {
int8 field25 = stream->readSByte();
/* int8 field26 = */ stream->readSByte();
- currentFrameRate = stream->readSint16();
+ _frameRate = stream->readSint16();
uint16 platform = stream->readUint16();
_platform = platformFromID(platform);
@@ -422,7 +417,7 @@ bool Cast::loadConfig() {
check += field23 + 23;
check += field24 + 24;
check *= field25 + 25;
- check += currentFrameRate + 26;
+ check += _frameRate + 26;
check *= platform + 27;
check *= (protection * 0xE06) + 0xFFF450000;
check ^= MKTAG('r', 'a', 'l', 'f');
@@ -455,12 +450,7 @@ bool Cast::loadConfig() {
} else {
warning("STUB: Cast::loadConfig(): Extended config not yet supported for version %d", _version);
}
- debugC(1, kDebugLoading, "Cast::loadConfig(): platform: %s, defaultPalette: %s", getPlatformAbbrev(_platform), _defaultPalette.asString().c_str());
- }
-
- if (!_isShared) {
- debugC(1, kDebugLoading, "Cast::loadConfig(): currentFrameRate: %d", currentFrameRate);
- _movie->getScore()->_currentFrameRate = currentFrameRate;
+ debugC(1, kDebugLoading, "Cast::loadConfig(): platform: %s, defaultPalette: %s, frameRate: %d", getPlatformAbbrev(_platform), _defaultPalette.asString().c_str(), _frameRate);
}
if (humanVer > _vm->getVersion()) {
@@ -579,7 +569,10 @@ void Cast::loadCast() {
for (Common::Array<uint16>::iterator iterator = cast.begin(); iterator != cast.end(); ++iterator) {
Resource res = _castArchive->getResourceDetail(MKTAG('C', 'A', 'S', 't'), *iterator);
- if (res.libId != _castLibID)
+ // Only load cast members which belong to the requested library ID.
+ // External casts only have one library ID, so instead
+ // we use the movie's mapping.
+ if (res.libId != _castLibID && !_isExternal)
continue;
Common::SeekableReadStreamEndian *stream = _castArchive->getResource(MKTAG('C', 'A', 'S', 't'), *iterator);
loadCastData(*stream, res.castId, &res);
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 62358b93aad..11337af6656 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -76,7 +76,7 @@ struct TilePatternEntry {
class Cast {
public:
- Cast(Movie *movie, uint16 castLibID, bool shared = false);
+ Cast(Movie *movie, uint16 castLibID, bool isShared = false, bool isExternal = false);
~Cast();
void loadArchive();
@@ -132,6 +132,7 @@ public:
uint16 _version;
Common::Platform _platform;
uint16 _castLibID;
+ bool _isExternal;
CharMap _macCharsToWin;
CharMap _winCharsToMac;
@@ -149,6 +150,7 @@ public:
Common::Rect _movieRect;
uint16 _stageColor;
CastMemberID _defaultPalette;
+ int16 _frameRate;
TilePatternEntry _tiles[kNumBuiltinTiles];
LingoArchive *_lingoArchive;
diff --git a/engines/director/detection.cpp b/engines/director/detection.cpp
index c2cdd89c68b..ce1524a3446 100644
--- a/engines/director/detection.cpp
+++ b/engines/director/detection.cpp
@@ -43,6 +43,8 @@ static struct CustomTarget {
{"d4-mac", "mac", "400" },
{"d3-win", "win", "300" },
{"d4-win", "win", "400" },
+ {"d5-mac", "mac", "500" },
+ {"d5-win", "win", "500" },
{"director-movie", "win", "400" },
{ nullptr, nullptr, nullptr }
};
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index a89a03a458b..4be0a0e98a3 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -154,14 +154,23 @@ void Movie::loadCastLibMapping(Common::SeekableReadStreamEndian &stream) {
stream.readUint16();
uint16 libId = stream.readUint16() - CAST_LIB_OFFSET;
debugC(5, kDebugLoading, "Movie::loadCastLibMapping: name: %s, path: %s, itemCount: %d, libId: %d", name.c_str(), path.c_str(), itemCount, libId);
+ Archive *castArchive = _movieArchive;
+ bool isExternal = !path.empty();
+ if (isExternal) {
+ castArchive = loadExternalCastFrom(pathMakeRelative(path));
+ if (!castArchive) {
+ continue; // couldn't load external cast
+ }
+ }
+
Cast *cast = nullptr;
if (_casts.contains(libId)) {
cast = _casts.getVal(libId);
} else {
- cast = new Cast(this, libId);
+ cast = new Cast(this, libId, false, isExternal);
_casts.setVal(libId, cast);
}
- cast->setArchive(_movieArchive);
+ cast->setArchive(castArchive);
}
return;
}
@@ -176,6 +185,8 @@ bool Movie::loadArchive() {
_version = _cast->_version;
_platform = _cast->_platform;
_movieRect = _cast->_movieRect;
+ _score->_currentFrameRate = _cast->_frameRate;
+ _stageColor = _vm->transformColor(_cast->_stageColor);
// Wait to handle _stageColor until palette is loaded in loadCast...
// File Info
@@ -360,7 +371,7 @@ void Movie::loadSharedCastsFrom(Common::String filename) {
debug(0, "@@@@ Loading shared cast '%s'", filename.c_str());
debug(0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
- _sharedCast = new Cast(this, DEFAULT_CAST_LIB, true);
+ _sharedCast = new Cast(this, DEFAULT_CAST_LIB, true, false);
_sharedCast->setArchive(sharedCast);
_sharedCast->loadArchive();
@@ -368,6 +379,27 @@ void Movie::loadSharedCastsFrom(Common::String filename) {
g_director->_allOpenResFiles.setVal(sharedCast->getPathName(), sharedCast);
}
+Archive *Movie::loadExternalCastFrom(Common::String filename) {
+ Archive *externalCast = _vm->createArchive();
+
+ if (!externalCast->openFile(filename)) {
+ warning("Movie::loadExternalCastFrom(): Cast file %s not found", filename.c_str());
+
+ delete externalCast;
+
+ return nullptr;
+ }
+ externalCast->setPathName(filename);
+
+ debug(0, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ debug(0, "@@@@ Loading external cast '%s'", filename.c_str());
+ debug(0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+
+ // Store the archive for later
+ g_director->_allOpenResFiles.setVal(externalCast->getPathName(), externalCast);
+ return externalCast;
+}
+
CastMember *Movie::getCastMember(CastMemberID memberID) {
CastMember *result = nullptr;
if (_casts.contains(memberID.castLib)) {
diff --git a/engines/director/movie.h b/engines/director/movie.h
index 492c1f119af..abd7580dd42 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -104,6 +104,7 @@ public:
void clearSharedCast();
void loadSharedCastsFrom(Common::String filename);
+ Archive *loadExternalCastFrom(Common::String filename);
CastMember *getCastMember(CastMemberID memberID);
CastMember *createOrReplaceCastMember(CastMemberID memberID, CastMember *cast);
Commit: 96855f1cf73c7e2a0d18ea4f0199478617447f25
https://github.com/scummvm/scummvm/commit/96855f1cf73c7e2a0d18ea4f0199478617447f25
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Add D5 file extensions to pathMakeRelative
Changed paths:
engines/director/util.cpp
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index ba23849b3ae..ba7e385059b 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -792,6 +792,13 @@ Common::String wrappedPathMakeRelative(Common::String path, bool recursive, bool
debugN(9, "%s", recIndent());
debug(9, "wrappedPathMakeRelative(): s6 -- not found %s", res.c_str());
+
+ debugN(9, "%s", recIndent());
+ debug(9, "wrappedPathMakeRelative(): s7 -- try alternate extensions for %s in %s", nameWithoutExt.c_str(), initialPath.c_str());
+ addedexts = testExtensions(nameWithoutExt, initialPath, convPath);
+ if (!addedexts.empty())
+ return addedexts;
+
}
}
@@ -822,8 +829,19 @@ bool hasExtension(Common::String filename) {
Common::String testExtensions(Common::String component, Common::String initialPath, Common::String convPath) {
const char *extsD3[] = { ".MMM", nullptr };
const char *extsD4[] = { ".DIR", ".DXR", nullptr };
+ const char *extsD5[] = { ".DIR", ".DXR", ".CST", ".CXT", nullptr };
- const char **exts = (g_director->getVersion() >= 400) ? extsD4 : extsD3;
+ const char **exts = nullptr;
+ if (g_director->getVersion() < 400) {
+ exts = extsD3;
+ } else if (g_director->getVersion() >= 400 && g_director->getVersion() < 500) {
+ exts = extsD4;
+ } else if (g_director->getVersion() >= 500 && g_director->getVersion() < 600) {
+ exts = extsD5;
+ } else {
+ warning("STUB: testExtensions(): file extensions not yet supported for version %d, falling back to D5", g_director->getVersion());
+ exts = extsD5;
+ }
for (int i = 0; exts[i]; ++i) {
Common::String newpath = convPath + component.c_str() + exts[i];
Commit: 5c82519e3502d17df9b04596323f0d7c8f2ee9c6
https://github.com/scummvm/scummvm/commit/5c82519e3502d17df9b04596323f0d7c8f2ee9c6
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Add D5 support for sound cast members
Changed paths:
engines/director/castmember/sound.cpp
engines/director/sound.cpp
diff --git a/engines/director/castmember/sound.cpp b/engines/director/castmember/sound.cpp
index 79972425456..afbb4b8108e 100644
--- a/engines/director/castmember/sound.cpp
+++ b/engines/director/castmember/sound.cpp
@@ -54,7 +54,7 @@ void SoundCastMember::load() {
if (_cast->_version < kFileVer400) {
tag = MKTAG('S', 'N', 'D', ' ');
sndId = (uint16)(_castId + _cast->_castIDoffset);
- } else if (_cast->_version >= kFileVer400 && _cast->_version < kFileVer500) {
+ } else if (_cast->_version >= kFileVer400 && _cast->_version < kFileVer600) {
if (_children.size() > 0) {
sndId = _children[0].index;
tag = _children[0].tag;
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 3869cfb10a5..bc0aeb5dddb 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -74,6 +74,9 @@ SoundChannel *DirectorSound::getChannel(uint8 soundChannel) {
}
void DirectorSound::playFile(Common::String filename, uint8 soundChannel) {
+ if (!isChannelValid(soundChannel))
+ return;
+
if (debugChannelSet(-1, kDebugFast))
return;
@@ -282,6 +285,8 @@ bool DirectorSound::fadeChannel(uint8 soundChannel) {
}
void DirectorSound::cancelFade(uint8 soundChannel) {
+ if (!isChannelValid(soundChannel))
+ return;
// NOTE: It is assumed that soundChannel has already been validated, which is
// why this method is private.
Commit: 8a990d556ce7396210d2d99f573ba5360a1b0382
https://github.com/scummvm/scummvm/commit/8a990d556ce7396210d2d99f573ba5360a1b0382
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Add Transition cast member type
Changed paths:
A engines/director/castmember/transition.cpp
A engines/director/castmember/transition.h
engines/director/cast.cpp
engines/director/module.mk
engines/director/score.cpp
engines/director/types.h
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index e0a1bce3e91..d4f7893984c 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -46,6 +46,7 @@
#include "director/castmember/shape.h"
#include "director/castmember/sound.h"
#include "director/castmember/text.h"
+#include "director/castmember/transition.h"
#include "director/lingo/lingo.h"
#include "director/lingo/lingo-object.h"
@@ -964,8 +965,12 @@ void Cast::loadCastData(Common::SeekableReadStreamEndian &stream, uint16 id, Res
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastMovie (id=%d, %d children)", id, res->children.size());
_loadedCast->setVal(id, new MovieCastMember(this, id, castStream, _version));
break;
+ case kCastTransition:
+ debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastTransition (id=%d, %d children)", id, res->children.size());
+ _loadedCast->setVal(id, new TransitionCastMember(this, id, castStream, _version));
+ break;
default:
- warning("Cast::loadCastData(): Unhandled cast type: %d [%s] (id=%d, %d children)! This will be missing from the movie and may cause problems", castType, tag2str(castType), id, res->children.size());
+ warning("BUILDBOT: STUB: Cast::loadCastData(): Unhandled cast type: %d [%s] (id=%d, %d children)! This will be missing from the movie and may cause problems", castType, tag2str(castType), id, res->children.size());
// also don't try and read the strings... we don't know what this item is.
castInfoSize = 0;
break;
diff --git a/engines/director/castmember/transition.cpp b/engines/director/castmember/transition.cpp
new file mode 100644
index 00000000000..b7913b89508
--- /dev/null
+++ b/engines/director/castmember/transition.cpp
@@ -0,0 +1,58 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "director/director.h"
+#include "director/cast.h"
+#include "director/movie.h"
+#include "director/castmember/transition.h"
+
+namespace Director {
+
+TransitionCastMember::TransitionCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version)
+ : CastMember(cast, castId, stream) {
+ _type = kCastTransition;
+
+ _transType = kTransNone;
+ _durationMillis = 0;
+ _chunkSize = 0;
+ _area = false;
+
+ if (debugChannelSet(5, kDebugLoading)) {
+ stream.hexdump(stream.size());
+ }
+ if (_cast->_version < kFileVer600) {
+ stream.readByte();
+ _chunkSize = stream.readByte();
+ _transType = static_cast<TransitionType>(stream.readByte());
+ _flags = stream.readByte();
+ _area = !(_flags & 1);
+ _durationMillis = stream.readUint16BE();
+ debugC(5, kDebugLoading, "TransitionCastMember::TransitionCastMember(): transType: %d, durationMillis: %d, flags: %d, chunkSize: %d", _transType, _durationMillis, _flags, _chunkSize);
+ } else {
+ warning("STUB: TransitionCastMember::TransitionCastMember(): Transitions not yet supported for version %d", _cast->_version);
+ }
+}
+
+Common::String TransitionCastMember::formatInfo() {
+ return Common::String::format("transType: %d, durationMillis: %d, flags: %d, chunkSize: %d", _transType, _durationMillis, _flags, _chunkSize);
+}
+
+} // End of namespace Director
diff --git a/engines/director/castmember/transition.h b/engines/director/castmember/transition.h
new file mode 100644
index 00000000000..c6f5d859510
--- /dev/null
+++ b/engines/director/castmember/transition.h
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_CASTMEMBER_TRANSITION_H
+#define DIRECTOR_CASTMEMBER_TRANSITION_H
+
+#include "director/castmember/castmember.h"
+
+namespace Director {
+
+class TransitionCastMember : public CastMember {
+public:
+ TransitionCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
+
+ Common::String formatInfo() override;
+
+ TransitionType _transType;
+ uint16 _durationMillis;
+ uint8 _flags;
+ uint8 _chunkSize;
+ bool _area;
+};
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index b49033e894b..b0d84c14bb2 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -36,6 +36,7 @@ MODULE_OBJS = \
castmember/shape.o \
castmember/sound.o \
castmember/text.o \
+ castmember/transition.o \
lingo/lingo.o \
lingo/lingo-builtins.o \
lingo/lingo-bytecode.o \
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 4991d3cef33..d00bbd588e1 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -49,6 +49,7 @@
#include "director/util.h"
#include "director/castmember/castmember.h"
#include "director/castmember/palette.h"
+#include "director/castmember/transition.h"
#include "director/lingo/lingo.h"
namespace Director {
@@ -390,7 +391,7 @@ void Score::update() {
// If there is a transition, the perFrameHook is called
// after each transition subframe instead.
- if (_frames[_currentFrame]->_transType == 0) {
+ if (_frames[_currentFrame]->_transType == 0 && _frames[_currentFrame]->_trans.isNull()) {
_lingo->executePerFrameHook(_currentFrame, 0);
}
}
@@ -606,9 +607,16 @@ bool Score::renderTransition(uint16 frameId) {
setLastPalette(frameId);
_window->playTransition(frameId, currentFrame->_transDuration, currentFrame->_transArea, currentFrame->_transChunkSize, currentFrame->_transType, resolvePaletteId(currentFrame->_scoreCachedPaletteId));
return true;
- } else {
- return false;
- }
+ } else if (!currentFrame->_trans.isNull()) {
+ CastMember *member = _movie->getCastMember(currentFrame->_trans);
+ if (member && member->_type == kCastTransition) {
+ TransitionCastMember *trans = static_cast<TransitionCastMember *>(member);
+ setLastPalette(frameId);
+ _window->playTransition(frameId, trans->_durationMillis, trans->_area, trans->_chunkSize, trans->_transType, resolvePaletteId(currentFrame->_scoreCachedPaletteId));
+ return true;
+ }
+ }
+ return false;
}
void Score::renderSprites(uint16 frameId, RenderMode mode) {
diff --git a/engines/director/types.h b/engines/director/types.h
index 02f7c1ce700..78408faa823 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -51,7 +51,8 @@ enum CastType {
kCastMovie = 9,
kCastDigitalVideo = 10,
kCastLingoScript = 11,
- kCastRTE = 12
+ kCastRTE = 12,
+ kCastTransition = 14,
};
enum ScriptType {
Commit: ec76e5dfc65cce1dd2a97b4580f2150833652deb
https://github.com/scummvm/scummvm/commit/ec76e5dfc65cce1dd2a97b4580f2150833652deb
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Refactor palette loading for D5
Previously, the palette ID namespace was shared between cast ID, builtin
ID and resource fork ID. This was quite messy.
The new approach is to use CastMemberID; builtin palettes are libId -1,
cast palettes use their respective libId, and a null CastMemberID
indicates a blank entry.
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
engines/director/castmember/bitmap.cpp
engines/director/castmember/bitmap.h
engines/director/castmember/palette.cpp
engines/director/castmember/palette.h
engines/director/director.cpp
engines/director/director.h
engines/director/frame.cpp
engines/director/frame.h
engines/director/graphics.cpp
engines/director/lingo/lingo-builtins.cpp
engines/director/score.cpp
engines/director/score.h
engines/director/tests.cpp
engines/director/transitions.cpp
engines/director/types.h
engines/director/window.h
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index d4f7893984c..94a4474ad82 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -465,23 +465,19 @@ bool Cast::loadConfig() {
}
void Cast::loadCast() {
- // Palette Information
- Common::Array<uint16> clutList = _castArchive->getResourceIDList(MKTAG('C', 'L', 'U', 'T'));
- if (clutList.size() == 0) {
- debugC(2, kDebugLoading, "CLUT resource not found, using default Mac palette");
- } else {
+ // Palette Information for D2; D3 and higher call this from the cast
+ if (_version < kFileVer300) {
+ Common::Array<uint16> clutList = _castArchive->getResourceIDList(MKTAG('C', 'L', 'U', 'T'));
for (uint i = 0; i < clutList.size(); i++) {
Common::SeekableReadStreamEndian *pal = _castArchive->getResource(MKTAG('C', 'L', 'U', 'T'), clutList[i]);
debugC(2, kDebugLoading, "****** Loading Palette CLUT, #%d", clutList[i]);
- PaletteV4 p = loadPalette(*pal);
-
- g_director->addPalette(clutList[i], p.palette, p.length);
-
+ PaletteV4 palData = loadPalette(*pal, clutList[i]);
+ CastMemberID cid(clutList[i], DEFAULT_CAST_LIB);
+ g_director->addPalette(cid, palData.palette, palData.length);
delete pal;
}
}
-
Common::SeekableReadStreamEndian *r = nullptr;
// Font Directory
@@ -684,7 +680,7 @@ Common::SeekableReadStreamEndian *Cast::getResource(uint32 tag, uint16 id) {
return _castArchive->getResource(tag, id);
}
-PaletteV4 Cast::loadPalette(Common::SeekableReadStreamEndian &stream) {
+PaletteV4 Cast::loadPalette(Common::SeekableReadStreamEndian &stream, int id) {
int size = stream.size();
debugC(3, kDebugLoading, "Cast::loadPalette(): %d bytes", size);
if (debugChannelSet(5, kDebugLoading))
@@ -703,7 +699,7 @@ PaletteV4 Cast::loadPalette(Common::SeekableReadStreamEndian &stream) {
}
debugC(3, kDebugLoading, "Cast::loadPalette(): %d steps", steps);
- byte *_palette = new byte[steps * 3];
+ byte *palette = new byte[steps * 3];
int colorIndex = 0;
@@ -721,18 +717,18 @@ PaletteV4 Cast::loadPalette(Common::SeekableReadStreamEndian &stream) {
break;
}
- _palette[3 * colorIndex] = stream.readByte();
+ palette[3 * colorIndex] = stream.readByte();
stream.readByte();
- _palette[3 * colorIndex + 1] = stream.readByte();
+ palette[3 * colorIndex + 1] = stream.readByte();
stream.readByte();
- _palette[3 * colorIndex + 2] = stream.readByte();
+ palette[3 * colorIndex + 2] = stream.readByte();
stream.readByte();
colorIndex += 1;
}
-
- return PaletteV4(0, _palette, steps);
+ PaletteV4 pal(CastMemberID(), palette, steps);
+ return pal;
}
void Cast::loadCastDataVWCR(Common::SeekableReadStreamEndian &stream) {
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 11337af6656..39695639d67 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -112,12 +112,12 @@ public:
void releaseCastMemberWidget();
void dumpScript(const char *script, ScriptType type, uint16 id);
- PaletteV4 loadPalette(Common::SeekableReadStreamEndian &stream);
Common::CodePage getFileEncoding();
Common::U32String decodeString(const Common::String &str);
Common::String formatCastSummary(int castId);
+ PaletteV4 loadPalette(Common::SeekableReadStreamEndian &stream, int id);
private:
void loadScriptV2(Common::SeekableReadStreamEndian &stream, uint16 id);
diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index 5b7a68051bd..331757737b0 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -51,8 +51,8 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableRe
_pitch = 0;
_flags2 = 0;
_regX = _regY = 0;
- _clut = 0;
- _ditheredTargetClut = 0;
+ _clut = CastMemberID(0, 0);
+ _ditheredTargetClut = CastMemberID(0, 0);
_bitsPerPixel = 0;
_external = false;
@@ -67,12 +67,15 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableRe
if (_bytes & 0x8000) {
_bitsPerPixel = stream.readUint16();
- _clut = stream.readSint16();
- if (_clut <= 0) // builtin palette
- _clut -= 1;
+ int clutId = stream.readSint16();
+
+ if (clutId <= 0) // builtin palette
+ _clut = CastMemberID(clutId - 1, -1);
+ else
+ _clut = CastMemberID(clutId, DEFAULT_CAST_LIB);
} else {
_bitsPerPixel = 1;
- _clut = kClutSystemMac;
+ _clut = CastMemberID(kClutSystemMac, -1);
}
_pitch = _initialRect.width();
@@ -97,12 +100,20 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableRe
if (stream.eos()) {
_bitsPerPixel = 0;
} else {
+ int clutCastLib = -1;
if (version >= kFileVer500) {
- stream.readSint16(); // is this the castlib? was ff ff
+ clutCastLib = stream.readSint16();
+ }
+ int clutId = stream.readSint16();
+
+ if (clutId <= 0) // builtin palette
+ _clut = CastMemberID(clutId - 1, -1);
+ else if (clutId > 0) {
+ if (clutCastLib == -1) {
+ clutCastLib = _cast->_castLibID;
+ }
+ _clut = CastMemberID(clutId, clutCastLib);
}
- _clut = stream.readSint16();
- if (_clut <= 0) // builtin palette
- _clut -= 1;
stream.readUint16();
/* uint16 unk1 = */ stream.readUint16();
stream.readUint16();
@@ -150,8 +161,8 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Image::ImageDecode
_picture = new Picture(*img);
}
_ditheredImg = nullptr;
- _clut = -1;
- _ditheredTargetClut = 0;
+ _clut = CastMemberID(0, 0);
+ _ditheredTargetClut = CastMemberID(0, 0);
_initialRect = Common::Rect(0, 0, img->getSurface()->w, img->getSurface()->h);
_pitch = img->getSurface()->pitch;
_bitsPerPixel = img->getSurface()->format.bytesPerPixel * 8;
@@ -195,7 +206,7 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
_ditheredImg->free();
delete _ditheredImg;
_ditheredImg = nullptr;
- _ditheredTargetClut = 0;
+ _ditheredTargetClut = CastMemberID(0, 0);
}
if (dstBpp == 1) {
@@ -217,18 +228,18 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
Cast *cast = movie->getCast();
Score *score = movie->getScore();
// Get the current score palette. Note that this is the ID of the palette in the list, not the cast member!
- int currentPaletteId = score->resolvePaletteId(score->getCurrentPalette());
- if (!currentPaletteId)
- currentPaletteId = cast->_defaultPalette.member;
+ CastMemberID currentPaletteId = score->getCurrentPalette();
+ if (currentPaletteId.isNull())
+ currentPaletteId = cast->_defaultPalette;
PaletteV4 *currentPalette = g_director->getPalette(currentPaletteId);
if (!currentPalette) {
- currentPaletteId = kClutSystemMac;
+ currentPaletteId = CastMemberID(kClutSystemMac, -1);
currentPalette = g_director->getPalette(currentPaletteId);
}
- int castPaletteId = score->resolvePaletteId(_clut);
+ CastMemberID castPaletteId = _clut;
// It is possible for Director to have saved an invalid ID in _clut;
// if this is the case, do no dithering.
- if (!castPaletteId)
+ if (castPaletteId.isNull())
castPaletteId = currentPaletteId;
// Check if the palette is in the middle of a color fade event
@@ -252,7 +263,7 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
const auto pals = g_director->getLoaded16Palettes();
// in D4 you aren't allowed to use custom palettes for 4-bit images, so uh...
// I guess default to the mac palette?
- int palIndex = pals.contains(castPaletteId) ? castPaletteId : kClutSystemMac;
+ CastMemberID palIndex = pals.contains(castPaletteId) ? castPaletteId : CastMemberID(kClutSystemMac, -1);
const PaletteV4 &srcPal = pals.getVal(palIndex);
_ditheredImg = _picture->_surface.convertTo(g_director->_wm->_pixelformat, srcPal.palette, srcPal.length, currentPalette->palette, currentPalette->length, Graphics::kDitherNaive);
}
@@ -264,7 +275,7 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
break;
if (_external || (castPaletteId != currentPaletteId && !isColorCycling)) {
const auto pals = g_director->getLoadedPalettes();
- int palIndex = pals.contains(castPaletteId) ? castPaletteId : kClutSystemMac;
+ CastMemberID palIndex = pals.contains(castPaletteId) ? castPaletteId : CastMemberID(kClutSystemMac, -1);
const PaletteV4 &srcPal = pals.getVal(palIndex);
// If it is an external image, use the included palette.
@@ -280,7 +291,7 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
}
if (_ditheredImg) {
- debugC(4, kDebugImages, "BitmapCastMember::createWidget(): Dithering image from source palette %d to target palette %d", _clut, score->getCurrentPalette());
+ debugC(4, kDebugImages, "BitmapCastMember::createWidget(): Dithering image from source palette %s to target palette %s", _clut.asString().c_str(), score->getCurrentPalette().asString().c_str());
// Save the palette ID so we can check if a redraw is required
_ditheredTargetClut = currentPaletteId;
@@ -298,7 +309,7 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
}
}
} else if (previouslyDithered) {
- debugC(4, kDebugImages, "BitmapCastMember::createWidget(): Removed dithered image, score palette %d matches cast member", score->getCurrentPalette());
+ debugC(4, kDebugImages, "BitmapCastMember::createWidget(): Removed dithered image, score palette %s matches cast member", score->getCurrentPalette().asString().c_str());
}
}
@@ -376,24 +387,24 @@ bool BitmapCastMember::isModified() {
// will dither the image so that it fits within the current palette.
// When the score palette changes, we need to flag that the widget needs
// to be recreated.
- if (_clut) {
+ if (!_clut.isNull()) {
Movie *movie = g_director->getCurrentMovie();
Cast *cast = movie->getCast();
Score *score = movie->getScore();
- int currentPaletteId = score->resolvePaletteId(score->getCurrentPalette());
- if (!currentPaletteId)
- currentPaletteId = cast->_defaultPalette.member;
+ CastMemberID currentPaletteId = score->getCurrentPalette();
+ if (currentPaletteId.isNull())
+ currentPaletteId = cast->_defaultPalette;
PaletteV4 *currentPalette = g_director->getPalette(currentPaletteId);
if (!currentPalette) {
- currentPaletteId = kClutSystemMac;
+ currentPaletteId = CastMemberID(kClutSystemMac, -1);
currentPalette = g_director->getPalette(currentPaletteId);
}
- int castPaletteId = score->resolvePaletteId(_clut);
- if (!castPaletteId)
- castPaletteId = cast->_defaultPalette.member;
+ CastMemberID castPaletteId = _clut;
+ if (castPaletteId.isNull())
+ castPaletteId = cast->_defaultPalette;
if (currentPaletteId == castPaletteId) {
- return _ditheredTargetClut != 0;
+ return !_ditheredTargetClut.isNull();
} else {
return _ditheredTargetClut != currentPaletteId;
}
@@ -475,13 +486,13 @@ Graphics::Surface *BitmapCastMember::getMatte(Common::Rect &bbox) {
Common::String BitmapCastMember::formatInfo() {
return Common::String::format(
- "initialRect: %dx%d@%d,%d, boundingRect: %dx%d@%d,%d, foreColor: %d, backColor: %d, regX: %d, regY: %d, pitch: %d, bitsPerPixel: %d, palette: %d",
+ "initialRect: %dx%d@%d,%d, boundingRect: %dx%d@%d,%d, foreColor: %d, backColor: %d, regX: %d, regY: %d, pitch: %d, bitsPerPixel: %d, palette: %s",
_initialRect.width(), _initialRect.height(),
_initialRect.left, _initialRect.top,
_boundingRect.width(), _boundingRect.height(),
_boundingRect.left, _boundingRect.top,
getForeColor(), getBackColor(),
- _regX, _regY, _pitch, _bitsPerPixel, _clut
+ _regX, _regY, _pitch, _bitsPerPixel, _clut.asString().c_str()
);
}
@@ -549,7 +560,7 @@ void BitmapCastMember::load() {
_bitsPerPixel = 8;
}
- debugC(5, kDebugImages, "BitmapCastMember::load(): Bitmap: id: %d, w: %d, h: %d, flags1: %x, flags2: %x bytes: %x, bpp: %d clut: %x", imgId, surf->w, surf->h, _flags1, _flags2, _bytes, _bitsPerPixel, _clut);
+ debugC(5, kDebugImages, "BitmapCastMember::load(): Bitmap: id: %d, w: %d, h: %d, flags1: %x, flags2: %x bytes: %x, bpp: %d clut: %s", imgId, surf->w, surf->h, _flags1, _flags2, _bytes, _bitsPerPixel, _clut.asString().c_str());
delete pic;
delete decoder;
_loaded = true;
@@ -613,7 +624,7 @@ void BitmapCastMember::load() {
delete img;
delete pic;
- debugC(5, kDebugImages, "BitmapCastMember::load(): Bitmap: id: %d, w: %d, h: %d, flags1: %x, flags2: %x bytes: %x, bpp: %d clut: %x", imgId, w, h, _flags1, _flags2, _bytes, _bitsPerPixel, _clut);
+ debugC(5, kDebugImages, "BitmapCastMember::load(): Bitmap: id: %d, w: %d, h: %d, flags1: %x, flags2: %x bytes: %x, bpp: %d clut: %s", imgId, w, h, _flags1, _flags2, _bytes, _bitsPerPixel, _clut.asString().c_str());
_loaded = true;
}
@@ -724,8 +735,18 @@ bool BitmapCastMember::setField(int field, const Datum &d) {
}
return true;
case kThePalette:
- _clut = d.asInt();
- return true;
+ {
+ // FIXME: not multicast safe
+ int id = d.asInt();
+ if (id > 0) {
+ _clut = CastMemberID(d.asInt(), DEFAULT_CAST_LIB);
+ } else if (id < 0) {
+ _clut = CastMemberID(d.asInt(), -1);
+ } else {
+ _clut = CastMemberID(0, 0);
+ }
+ return true;
+ }
case kThePicture:
if (d.type == PICTUREREF && d.u.picture != nullptr) {
setPicture(*d.u.picture);
diff --git a/engines/director/castmember/bitmap.h b/engines/director/castmember/bitmap.h
index bdacde3f14a..8ba47cac4bc 100644
--- a/engines/director/castmember/bitmap.h
+++ b/engines/director/castmember/bitmap.h
@@ -64,8 +64,8 @@ public:
uint16 _regY;
uint16 _flags2;
uint16 _bytes;
- int _clut;
- int _ditheredTargetClut;
+ CastMemberID _clut;
+ CastMemberID _ditheredTargetClut;
uint16 _bitsPerPixel;
diff --git a/engines/director/castmember/palette.cpp b/engines/director/castmember/palette.cpp
index 5dc96170014..a12553b3ca5 100644
--- a/engines/director/castmember/palette.cpp
+++ b/engines/director/castmember/palette.cpp
@@ -61,8 +61,20 @@ void PaletteCastMember::load() {
warning("STUB: PaletteCastMember::load(): Palettes not yet supported for version %d", _cast->_version);
}
if (paletteId) {
- debugC(2, kDebugImages, "PaletteCastMember::load(): linking palette id %d to cast index %d", paletteId, _castId);
- _palette = g_director->getPalette(paletteId);
+ //_palette = g_director->getPalette(paletteId);
+
+ uint32 tag = MKTAG('C', 'L', 'U', 'T');
+ Archive *arch = _cast->getArchive();
+ if (arch->hasResource(tag, paletteId)) {
+ Common::SeekableReadStreamEndian *pal = arch->getResource(MKTAG('C', 'L', 'U', 'T'), paletteId);
+ debugC(2, kDebugImages, "PaletteCastMember::load(): linking palette id %d to cast index %d", paletteId, _castId);
+ PaletteV4 palData = _cast->loadPalette(*pal, paletteId);
+ CastMemberID cid(_castId, _cast->_castLibID);
+ g_director->addPalette(cid, palData.palette, palData.length);
+ delete pal;
+ } else {
+ warning("PaletteCastMember::load(): no CLUT palette %d for cast index %d found", paletteId, _castId);
+ }
}
_loaded = true;
diff --git a/engines/director/castmember/palette.h b/engines/director/castmember/palette.h
index 84a4f25af7b..45524a4f74b 100644
--- a/engines/director/castmember/palette.h
+++ b/engines/director/castmember/palette.h
@@ -29,7 +29,7 @@ namespace Director {
class PaletteCastMember : public CastMember {
public:
PaletteCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
- int getPaletteId() { return _palette ? _palette->id : 0; }
+ CastMemberID getPaletteId() { return _palette ? _palette->id : CastMemberID(0, 0); }
void activatePalette() { if (_palette) g_director->setPalette(_palette->id); }
Common::String formatInfo() override;
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 1ff68d22964..4ce14ec104d 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -224,7 +224,7 @@ Common::Error DirectorEngine::run() {
_wm->setScreen(_surface);
_wm->addWindowInitialized(_stage);
_wm->setActiveWindow(_stage->getId());
- setPalette(-1);
+ setPalette(CastMemberID(kClutSystemMac, -1));
_currentWindow = _stage;
diff --git a/engines/director/director.h b/engines/director/director.h
index 327f2c06c33..26f4a6418c0 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -112,12 +112,12 @@ struct StartOptions {
};
struct PaletteV4 {
- int id;
+ CastMemberID id;
byte *palette;
int length;
- PaletteV4(int i, byte *p, int l) : id(i), palette(p), length(l) {}
- PaletteV4() : id(0), palette(nullptr), length(0) {}
+ PaletteV4(CastMemberID i, byte *p, int l) : id(i), palette(p), length(l) {}
+ PaletteV4() : id(), palette(nullptr), length(0) {}
};
struct MacShape {
@@ -179,16 +179,16 @@ public:
// graphics.cpp
bool hasFeature(EngineFeature f) const override;
- void addPalette(int id, byte *palette, int length);
- bool setPalette(int id);
+ void addPalette(CastMemberID &id, byte *palette, int length);
+ bool setPalette(const CastMemberID &id);
void setPalette(byte *palette, uint16 count);
void shiftPalette(int startIndex, int endIndex, bool reverse);
void clearPalettes();
- PaletteV4 *getPalette(int id);
+ PaletteV4 *getPalette(const CastMemberID &id);
void loadDefaultPalettes();
- const Common::HashMap<int, PaletteV4> &getLoadedPalettes() { return _loadedPalettes; }
- const Common::HashMap<int, PaletteV4> &getLoaded16Palettes() { return _loaded16Palettes; }
+ const Common::HashMap<CastMemberID, PaletteV4> &getLoadedPalettes() { return _loadedPalettes; }
+ const Common::HashMap<CastMemberID, PaletteV4> &getLoaded16Palettes() { return _loaded16Palettes; }
const PaletteV4 &getLoaded4Palette() { return _loaded4Palette; }
const Common::FSNode *getGameDataDir() const { return &_gameDataDir; }
@@ -276,8 +276,8 @@ private:
Graphics::MacPatterns _director3QuickDrawPatterns;
PatternTile _builtinTiles[kNumBuiltinTiles];
- Common::HashMap<int, PaletteV4> _loadedPalettes;
- Common::HashMap<int, PaletteV4> _loaded16Palettes;
+ Common::HashMap<CastMemberID, PaletteV4> _loadedPalettes;
+ Common::HashMap<CastMemberID, PaletteV4> _loaded16Palettes;
PaletteV4 _loaded4Palette;
Graphics::ManagedSurface *_surface;
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index b6e67701ee0..32a55ccf128 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -40,7 +40,7 @@ Frame::Frame(Score *score, int numChannels) {
_tempo = 0;
_scoreCachedTempo = 0;
- _scoreCachedPaletteId = 0;
+ _scoreCachedPaletteId = CastMemberID(0, 0);
_numChannels = numChannels;
@@ -163,7 +163,14 @@ void Frame::readChannels(Common::SeekableReadStreamEndian *stream, uint16 versio
}
// palette
- _palette.paletteId = stream->readSint16();
+ int16 paletteId = stream->readSint16();
+ if (paletteId == 0) {
+ _palette.paletteId = CastMemberID(0, 0);
+ } else if (paletteId < 0) {
+ _palette.paletteId = CastMemberID(paletteId, -1);
+ } else {
+ _palette.paletteId = CastMemberID(paletteId, DEFAULT_CAST_LIB);
+ }
// loop points for color cycling
_palette.firstColor = g_director->transformColor(stream->readByte() ^ 0x80);
_palette.lastColor = g_director->transformColor(stream->readByte() ^ 0x80);
@@ -222,7 +229,14 @@ void Frame::readChannels(Common::SeekableReadStreamEndian *stream, uint16 versio
_colorTrans = stream->readByte();
// palette
- _palette.paletteId = stream->readSint16();
+ int16 paletteId = stream->readSint16();
+ if (paletteId == 0) {
+ _palette.paletteId = CastMemberID(0, 0);
+ } else if (paletteId < 0) {
+ _palette.paletteId = CastMemberID(paletteId, -1);
+ } else {
+ _palette.paletteId = CastMemberID(paletteId, DEFAULT_CAST_LIB);
+ }
// loop points for color cycling
_palette.firstColor = g_director->transformColor(stream->readByte() + 0x80);
_palette.lastColor = g_director->transformColor(stream->readByte() + 0x80);
@@ -283,9 +297,9 @@ void Frame::readChannels(Common::SeekableReadStreamEndian *stream, uint16 versio
stream->read(unk, 2);
// palette
- stream->read(unk, 2);
-
- _palette.paletteId = stream->readSint16();
+ int16 paletteCastLib = stream->readSint16();
+ int16 paletteId = stream->readSint16();
+ _palette.paletteId = CastMemberID(paletteId, paletteCastLib);
_palette.speed = stream->readByte();
_palette.flags = stream->readByte();
_palette.colorCycling = (_palette.flags & 0x80) != 0;
@@ -425,9 +439,9 @@ Common::String Frame::formatChannelInfo() {
Common::String result;
result += Common::String::format("TMPO: tempo: %d, skipFrameFlag: %d, blend: %d\n",
_tempo, _skipFrameFlag, _blend);
- if (_palette.paletteId) {
- result += Common::String::format("PAL: paletteId: %d, firstColor: %d, lastColor: %d, flags: %d, cycleCount: %d, speed: %d, frameCount: %d, fade: %d, delay: %d, style: %d\n",
- _palette.paletteId, _palette.firstColor, _palette.lastColor, _palette.flags,
+ if (_palette.paletteId.isNull()) {
+ result += Common::String::format("PAL: paletteId: %s, firstColor: %d, lastColor: %d, flags: %d, cycleCount: %d, speed: %d, frameCount: %d, fade: %d, delay: %d, style: %d\n",
+ _palette.paletteId.asString().c_str(), _palette.firstColor, _palette.lastColor, _palette.flags,
_palette.cycleCount, _palette.speed, _palette.frameCount,
_palette.fade, _palette.delay, _palette.style);
} else {
diff --git a/engines/director/frame.h b/engines/director/frame.h
index 3aa51733749..6f69aa6df94 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -46,7 +46,7 @@ enum {
};
struct PaletteInfo {
- int paletteId;
+ CastMemberID paletteId;
byte firstColor;
byte lastColor;
@@ -66,7 +66,7 @@ struct PaletteInfo {
byte colorCode;
PaletteInfo() {
- paletteId = 0;
+ paletteId = CastMemberID(0, 0);
firstColor = lastColor = 0;
flags = 0; colorCycling = false;
normal = false; fadeToWhite = false;
@@ -120,7 +120,7 @@ public:
uint8 _tempo;
uint8 _scoreCachedTempo;
- int _scoreCachedPaletteId;
+ CastMemberID _scoreCachedPaletteId;
CastMemberID _sound1;
uint8 _soundType1;
diff --git a/engines/director/graphics.cpp b/engines/director/graphics.cpp
index 84d4fbc8b09..899eafba6b0 100644
--- a/engines/director/graphics.cpp
+++ b/engines/director/graphics.cpp
@@ -108,41 +108,47 @@ const Common::Rect &DirectorEngine::getTileRect(int num) {
}
void DirectorEngine::loadDefaultPalettes() {
- _loadedPalettes[kClutSystemMac] = PaletteV4(kClutSystemMac, macPalette, 256);
- _loadedPalettes[kClutRainbow] = PaletteV4(kClutRainbow, rainbowPalette, 256);
- _loadedPalettes[kClutGrayscale] = PaletteV4(kClutGrayscale, grayscalePalette, 256);
- _loadedPalettes[kClutPastels] = PaletteV4(kClutPastels, pastelsPalette, 256);
- _loadedPalettes[kClutVivid] = PaletteV4(kClutVivid, vividPalette, 256);
- _loadedPalettes[kClutNTSC] = PaletteV4(kClutNTSC, ntscPalette, 256);
- _loadedPalettes[kClutMetallic] = PaletteV4(kClutMetallic, metallicPalette, 256);
- _loadedPalettes[kClutSystemWin] = PaletteV4(kClutSystemWin, winPalette, 256);
- _loadedPalettes[kClutSystemWinD5] = PaletteV4(kClutSystemWinD5, winD5Palette, 256);
-
- _loaded16Palettes[kClutSystemMac] = PaletteV4(kClutSystemMac, mac16Palette, 16);
- _loaded16Palettes[kClutRainbow] = PaletteV4(kClutRainbow, rainbow16Palette, 16);
- _loaded16Palettes[kClutGrayscale] = PaletteV4(kClutGrayscale, grayscale16Palette, 16);
- _loaded16Palettes[kClutPastels] = PaletteV4(kClutPastels, pastels16Palette, 16);
- _loaded16Palettes[kClutVivid] = PaletteV4(kClutVivid, vivid16Palette, 16);
- _loaded16Palettes[kClutNTSC] = PaletteV4(kClutNTSC, ntsc16Palette, 16);
- _loaded16Palettes[kClutMetallic] = PaletteV4(kClutMetallic, metallic16Palette, 16);
- _loaded16Palettes[kClutSystemWin] = PaletteV4(kClutSystemWin, win16Palette, 16);
- _loaded16Palettes[kClutSystemWinD5] = PaletteV4(kClutSystemWinD5, winD516Palette, 16);
-
- _loaded4Palette = PaletteV4(kClutGrayscale, grayscale4Palette, 4);
+ _loadedPalettes[CastMemberID(kClutSystemMac, -1)] = PaletteV4(CastMemberID(kClutSystemMac, -1), macPalette, 256);
+ _loadedPalettes[CastMemberID(kClutRainbow, -1)] = PaletteV4(CastMemberID(kClutRainbow, -1), rainbowPalette, 256);
+ _loadedPalettes[CastMemberID(kClutGrayscale, -1)] = PaletteV4(CastMemberID(kClutGrayscale, -1), grayscalePalette, 256);
+ _loadedPalettes[CastMemberID(kClutPastels, -1)] = PaletteV4(CastMemberID(kClutPastels, -1), pastelsPalette, 256);
+ _loadedPalettes[CastMemberID(kClutVivid, -1)] = PaletteV4(CastMemberID(kClutVivid, -1), vividPalette, 256);
+ _loadedPalettes[CastMemberID(kClutNTSC, -1)] = PaletteV4(CastMemberID(kClutNTSC, -1), ntscPalette, 256);
+ _loadedPalettes[CastMemberID(kClutMetallic, -1)] = PaletteV4(CastMemberID(kClutMetallic, -1), metallicPalette, 256);
+ _loadedPalettes[CastMemberID(kClutSystemWin, -1)] = PaletteV4(CastMemberID(kClutSystemWin, -1), winPalette, 256);
+ _loadedPalettes[CastMemberID(kClutSystemWinD5, -1)] = PaletteV4(CastMemberID(kClutSystemWinD5, -1), winD5Palette, 256);
+
+ _loaded16Palettes[CastMemberID(kClutSystemMac, -1)] = PaletteV4(CastMemberID(kClutSystemMac, -1), mac16Palette, 16);
+ _loaded16Palettes[CastMemberID(kClutRainbow, -1)] = PaletteV4(CastMemberID(kClutRainbow, -1), rainbow16Palette, 16);
+ _loaded16Palettes[CastMemberID(kClutGrayscale, -1)] = PaletteV4(CastMemberID(kClutGrayscale, -1), grayscale16Palette, 16);
+ _loaded16Palettes[CastMemberID(kClutPastels, -1)] = PaletteV4(CastMemberID(kClutPastels, -1), pastels16Palette, 16);
+ _loaded16Palettes[CastMemberID(kClutVivid, -1)] = PaletteV4(CastMemberID(kClutVivid, -1), vivid16Palette, 16);
+ _loaded16Palettes[CastMemberID(kClutNTSC, -1)] = PaletteV4(CastMemberID(kClutNTSC, -1), ntsc16Palette, 16);
+ _loaded16Palettes[CastMemberID(kClutMetallic, -1)] = PaletteV4(CastMemberID(kClutMetallic, -1), metallic16Palette, 16);
+ _loaded16Palettes[CastMemberID(kClutSystemWin, -1)] = PaletteV4(CastMemberID(kClutSystemWin, -1), win16Palette, 16);
+ _loaded16Palettes[CastMemberID(kClutSystemWinD5, -1)] = PaletteV4(CastMemberID(kClutSystemWinD5, -1), winD516Palette, 16);
+
+ _loaded4Palette = PaletteV4(CastMemberID(kClutGrayscale, -1), grayscale4Palette, 4);
}
-PaletteV4 *DirectorEngine::getPalette(int id) {
+PaletteV4 *DirectorEngine::getPalette(const CastMemberID &id) {
if (!_loadedPalettes.contains(id)) {
- warning("DirectorEngine::getPalette(): Palette %d not found", id);
- return nullptr;
+ CastMember *member = getCurrentMovie()->getCastMember(id);
+ if (member && member->_type == kCastPalette) {
+ member->load();
+ }
+ if (!_loadedPalettes.contains(id)) {
+ warning("DirectorEngine::getPalette(): Palette %s not found", id.asString().c_str());
+ return nullptr;
+ }
}
return &_loadedPalettes[id];
}
-void DirectorEngine::addPalette(int id, byte *palette, int length) {
- if (id < 0) {
- warning("DirectorEngine::addPalette(): Negative palette ids reserved for default palettes");
+void DirectorEngine::addPalette(CastMemberID &id, byte *palette, int length) {
+ if (id.castLib < 0) {
+ warning("DirectorEngine::addPalette(): Negative cast library ids reserved for default palettes");
return;
} else if (_loadedPalettes.contains(id)) {
delete[] _loadedPalettes[id].palette;
@@ -151,17 +157,16 @@ void DirectorEngine::addPalette(int id, byte *palette, int length) {
_loadedPalettes[id] = PaletteV4(id, palette, length);
}
-bool DirectorEngine::setPalette(int id) {
- if (id == 0) {
+bool DirectorEngine::setPalette(const CastMemberID &id) {
+ if (id.isNull()) {
// Palette id of 0 is unused
return false;
- } else if (!_loadedPalettes.contains(id)) {
- warning("setPalette(): no palette with matching id %d", id);
- return false;
- }
+ }
- PaletteV4 pal = _loadedPalettes[id];
- setPalette(pal.palette, pal.length);
+ PaletteV4 *pal = getPalette(id);
+ if (!pal)
+ return false;
+ setPalette(pal->palette, pal->length);
return true;
}
@@ -210,8 +215,8 @@ void DirectorEngine::shiftPalette(int startIndex, int endIndex, bool reverse) {
}
void DirectorEngine::clearPalettes() {
- for (Common::HashMap<int, PaletteV4>::iterator it = _loadedPalettes.begin(); it != _loadedPalettes.end(); ++it) {
- if (it->_value.id > 0)
+ for (auto it = _loadedPalettes.begin(); it != _loadedPalettes.end(); ++it) {
+ if (it->_value.id.castLib > 0)
delete[] it->_value.palette;
}
}
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 76604c8458a..8546cc83efc 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -2380,7 +2380,8 @@ static const struct PaletteNames {
void LB::b_puppetPalette(int nargs) {
g_lingo->convertVOIDtoString(0, nargs);
- int numFrames = 0, speed = 0, palette = 0;
+ int numFrames = 0, speed = 0;
+ CastMemberID palette(0, 0);
Datum d;
Movie *movie = g_director->getCurrentMovie();
@@ -2400,10 +2401,10 @@ void LB::b_puppetPalette(int nargs) {
for (int i = 0; i < ARRAYSIZE(paletteNames); i++) {
if (palStr.equalsIgnoreCase(paletteNames[i].name))
- palette = paletteNames[i].type;
+ palette = CastMemberID(paletteNames[i].type, -1);
}
}
- if (!palette) {
+ if (palette.isNull()) {
CastMember *member = movie->getCastMember(d.asMemberID());
if (member && member->_type == kCastPalette)
@@ -2416,7 +2417,7 @@ void LB::b_puppetPalette(int nargs) {
}
Score *score = movie->getScore();
- if (palette) {
+ if (!palette.isNull()) {
g_director->setPalette(palette);
score->_puppetPalette = true;
} else {
@@ -2426,10 +2427,10 @@ void LB::b_puppetPalette(int nargs) {
// FIXME: set system palette decided by platform, should be fixed after windows palette is working.
// try to set mac system palette if lastPalette is 0.
- if (score->_lastPalette == 0)
- g_director->setPalette(-1);
+ if (score->_lastPalette.isNull())
+ g_director->setPalette(CastMemberID(kClutSystemMac, -1));
else
- g_director->setPalette(score->resolvePaletteId(score->_lastPalette));
+ g_director->setPalette(score->_lastPalette);
}
// TODO: Implement advanced features that use these.
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index d00bbd588e1..a77a7817a7c 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -66,7 +66,7 @@ Score::Score(Movie *movie) {
_puppetTempo = 0x00;
_puppetPalette = false;
- _lastPalette = 0;
+ _lastPalette = CastMemberID(0, 0);
_paletteTransitionIndex = 0;
memset(_paletteSnapshotBuffer, 0, 768);
@@ -103,23 +103,10 @@ Score::~Score() {
delete _labels;
}
-int Score::getCurrentPalette() {
+CastMemberID Score::getCurrentPalette() {
return _lastPalette;
}
-int Score::resolvePaletteId(int id) {
- // TODO: Palette ID should be a CastMemberID to allow for palettes in different casts
- // 255 represent system palette in D2
- if (id == 255) {
- id = g_director->getCurrentMovie()->getCast()->_defaultPalette.member;
- } else if (id > 0) {
- CastMember *member = _movie->getCastMember(CastMemberID(id, DEFAULT_CAST_LIB));
- id = (member && member->_type == kCastPalette) ? ((PaletteCastMember *)member)->getPaletteId() : 0;
- }
-
- return id;
-}
-
bool Score::processImmediateFrameScript(Common::String s, int id) {
s.trim();
@@ -289,10 +276,10 @@ void Score::startPlay() {
}
_lastPalette = _frames[_currentFrame]->_palette.paletteId;
- if (!_lastPalette)
- _lastPalette = _movie->getCast()->_defaultPalette.member;
- debugC(2, kDebugImages, "Score::startPlay(): palette changed to %d", _lastPalette);
- _vm->setPalette(resolvePaletteId(_lastPalette));
+ if (_lastPalette.isNull())
+ _lastPalette = _movie->getCast()->_defaultPalette;
+ debugC(2, kDebugImages, "Score::startPlay(): palette changed to %s", _lastPalette.asString().c_str());
+ _vm->setPalette(_lastPalette);
// All frames in the same movie have the same number of channels
if (_playState != kPlayStopped)
@@ -599,20 +586,20 @@ bool Score::renderTransition(uint16 frameId) {
if (tp) {
setLastPalette(frameId);
- _window->playTransition(frameId, tp->duration, tp->area, tp->chunkSize, tp->type, resolvePaletteId(currentFrame->_scoreCachedPaletteId));
+ _window->playTransition(frameId, tp->duration, tp->area, tp->chunkSize, tp->type, currentFrame->_scoreCachedPaletteId);
delete _window->_puppetTransition;
_window->_puppetTransition = nullptr;
return true;
} else if (currentFrame->_transType) {
setLastPalette(frameId);
- _window->playTransition(frameId, currentFrame->_transDuration, currentFrame->_transArea, currentFrame->_transChunkSize, currentFrame->_transType, resolvePaletteId(currentFrame->_scoreCachedPaletteId));
+ _window->playTransition(frameId, currentFrame->_transDuration, currentFrame->_transArea, currentFrame->_transChunkSize, currentFrame->_transType, currentFrame->_scoreCachedPaletteId);
return true;
} else if (!currentFrame->_trans.isNull()) {
CastMember *member = _movie->getCastMember(currentFrame->_trans);
if (member && member->_type == kCastTransition) {
TransitionCastMember *trans = static_cast<TransitionCastMember *>(member);
setLastPalette(frameId);
- _window->playTransition(frameId, trans->_durationMillis, trans->_area, trans->_chunkSize, trans->_transType, resolvePaletteId(currentFrame->_scoreCachedPaletteId));
+ _window->playTransition(frameId, trans->_durationMillis, trans->_area, trans->_chunkSize, trans->_transType, currentFrame->_scoreCachedPaletteId);
return true;
}
}
@@ -682,8 +669,8 @@ bool Score::renderPrePaletteCycle(uint16 frameId, RenderMode mode) {
return false;
// Skip this if we don't have a palette instruction
- int currentPalette = _frames[frameId]->_palette.paletteId;
- if (!currentPalette || !resolvePaletteId(currentPalette))
+ CastMemberID currentPalette = _frames[frameId]->_palette.paletteId;
+ if (currentPalette.isNull())
return false;
if (!_frames[frameId]->_palette.colorCycling &&
@@ -701,12 +688,16 @@ bool Score::renderPrePaletteCycle(uint16 frameId, RenderMode mode) {
// Copy the current palette into the snapshot buffer
memset(_paletteSnapshotBuffer, 0, 768);
memcpy(_paletteSnapshotBuffer, g_director->getPalette(), g_director->getPaletteColorCount() * 3);
- PaletteV4 *destPal = g_director->getPalette(resolvePaletteId(currentPalette));
+ PaletteV4 *destPal = g_director->getPalette(currentPalette);
+ if (!destPal) {
+ warning("Unable to fetch palette %s", currentPalette.asString().c_str());
+ return false;
+ }
if (_frames[frameId]->_palette.normal) {
// For fade palette transitions, the whole fade happens with
// the previous frame's layout.
- debugC(2, kDebugImages, "Score::renderPrePaletteCycle(): fading palette to %d over %d frames", currentPalette, fadeFrames);
+ debugC(2, kDebugImages, "Score::renderPrePaletteCycle(): fading palette to %s over %d frames", currentPalette.asString().c_str(), fadeFrames);
for (int i = 0; i < fadeFrames; i++) {
lerpPalette(
calcPal,
@@ -719,8 +710,8 @@ bool Score::renderPrePaletteCycle(uint16 frameId, RenderMode mode) {
g_director->draw();
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {
- debugC(2, kDebugImages, "Score::renderPrePaletteCycle(): interrupted, setting palette to %d", currentPalette);
- g_director->setPalette(resolvePaletteId(currentPalette));
+ debugC(2, kDebugImages, "Score::renderPrePaletteCycle(): interrupted, setting palette to %s", currentPalette.asString().c_str());
+ g_director->setPalette(currentPalette);
return true;
}
g_director->delayMillis(frameDelay);
@@ -756,8 +747,8 @@ bool Score::renderPrePaletteCycle(uint16 frameId, RenderMode mode) {
g_director->draw();
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {
- debugC(2, kDebugImages, "Score::renderPrePaletteCycle(): interrupted, setting palette to %d", currentPalette);
- g_director->setPalette(resolvePaletteId(currentPalette));
+ debugC(2, kDebugImages, "Score::renderPrePaletteCycle(): interrupted, setting palette to %s", currentPalette.asString().c_str());
+ g_director->setPalette(currentPalette);
return true;
}
g_director->delayMillis(frameDelay);
@@ -772,30 +763,26 @@ void Score::setLastPalette(uint16 frameId) {
return;
bool isCachedPalette = false;
- int currentPalette = _frames[frameId]->_palette.paletteId;
- // Palette specified in the frame
- if (currentPalette) {
- // If for whatever reason the palette index is invalid, skip
- if (!resolvePaletteId(currentPalette))
- return;
- } else {
+ CastMemberID currentPalette = _frames[frameId]->_palette.paletteId;
+ // Palette not specified in the frame
+ if (currentPalette.isNull()) {
// Use the score cached palette ID
isCachedPalette = true;
currentPalette = _frames[frameId]->_scoreCachedPaletteId;
// The cached ID is created before the cast gets loaded; if it's zero,
// this corresponds to the movie default palette.
- if (!currentPalette)
- currentPalette = g_director->getCurrentMovie()->getCast()->_defaultPalette.member;
+ if (currentPalette.isNull())
+ currentPalette = g_director->getCurrentMovie()->getCast()->_defaultPalette;
// If for whatever reason this doesn't resolve, abort.
- if (!currentPalette || !resolvePaletteId(currentPalette))
+ if (currentPalette.isNull())
return;
}
// If the palette is defined in the frame and doesn't match
// the current one, set it
- bool paletteChanged = currentPalette != _lastPalette && currentPalette;
+ bool paletteChanged = (currentPalette != _lastPalette) && (!currentPalette.isNull());
if (paletteChanged) {
- debugC(2, kDebugImages, "Score::setLastPalette(): palette changed to %d, from %s", currentPalette, isCachedPalette ? "cache" :"frame");
+ debugC(2, kDebugImages, "Score::setLastPalette(): palette changed to %s, from %s", currentPalette.asString().c_str(), isCachedPalette ? "cache" :"frame");
_lastPalette = currentPalette;
_paletteTransitionIndex = 0;
@@ -803,7 +790,7 @@ void Score::setLastPalette(uint16 frameId) {
// - this is color cycling mode, or
// - the cached palette ID is different (i.e. we jumped in the score)
if (_frames[frameId]->_palette.colorCycling || isCachedPalette)
- g_director->setPalette(resolvePaletteId(_lastPalette));
+ g_director->setPalette(_lastPalette);
}
}
@@ -818,8 +805,8 @@ void Score::renderPaletteCycle(uint16 frameId, RenderMode mode) {
// If the palette is defined in the frame and doesn't match
// the current one, set it
- int currentPalette = _frames[frameId]->_palette.paletteId;
- if (!currentPalette || !resolvePaletteId(currentPalette))
+ CastMemberID currentPalette = _frames[frameId]->_palette.paletteId;
+ if (currentPalette.isNull())
return;
// For palette cycling, the only thing that is checked is if
@@ -847,26 +834,26 @@ void Score::renderPaletteCycle(uint16 frameId, RenderMode mode) {
if (_frames[frameId]->_palette.overTime) {
// Do a single color step in one frame transition
- debugC(2, kDebugImages, "Score::renderPaletteCycle(): color cycle palette %d, from colors %d to %d, by 1 frame", currentPalette, firstColor, lastColor);
+ debugC(2, kDebugImages, "Score::renderPaletteCycle(): color cycle palette %s, from colors %d to %d, by 1 frame", currentPalette.asString().c_str(), firstColor, lastColor);
g_director->shiftPalette(firstColor, lastColor, false);
g_director->draw();
} else {
// Short circuit for few frames renderer
if (debugChannelSet(-1, kDebugFast)) {
- g_director->setPalette(resolvePaletteId(currentPalette));
+ g_director->setPalette(currentPalette);
return;
}
// Do a full color cycle in one frame transition
int steps = lastColor - firstColor + 1;
- debugC(2, kDebugImages, "Score::renderPaletteCycle(): color cycle palette %d, from colors %d to %d, over %d steps %d times", currentPalette, firstColor, lastColor, steps, _frames[frameId]->_palette.cycleCount);
+ debugC(2, kDebugImages, "Score::renderPaletteCycle(): color cycle palette %s, from colors %d to %d, over %d steps %d times", currentPalette.asString().c_str(), firstColor, lastColor, steps, _frames[frameId]->_palette.cycleCount);
for (int i = 0; i < _frames[frameId]->_palette.cycleCount; i++) {
for (int j = 0; j < steps; j++) {
g_director->shiftPalette(firstColor, lastColor, false);
g_director->draw();
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {
- g_director->setPalette(resolvePaletteId(currentPalette));
+ g_director->setPalette(currentPalette);
return;
}
g_director->delayMillis(delay);
@@ -877,7 +864,7 @@ void Score::renderPaletteCycle(uint16 frameId, RenderMode mode) {
g_director->draw();
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {
- g_director->setPalette(resolvePaletteId(currentPalette));
+ g_director->setPalette(currentPalette);
return;
}
g_director->delayMillis(delay);
@@ -887,7 +874,11 @@ void Score::renderPaletteCycle(uint16 frameId, RenderMode mode) {
}
} else {
// Transition from the current palette to a new palette
- PaletteV4 *destPal = g_director->getPalette(resolvePaletteId(currentPalette));
+ PaletteV4 *destPal = g_director->getPalette(currentPalette);
+ if (!destPal) {
+ warning("Score::renderPaletteCycle(): no match for palette id %s", currentPalette.asString().c_str());
+ return;
+ }
int frameCount = _frames[frameId]->_palette.frameCount;
byte calcPal[768];
@@ -897,7 +888,7 @@ void Score::renderPaletteCycle(uint16 frameId, RenderMode mode) {
// Copy the current palette into the snapshot buffer
memset(_paletteSnapshotBuffer, 0, 768);
memcpy(_paletteSnapshotBuffer, g_director->getPalette(), g_director->getPaletteColorCount() * 3);
- debugC(2, kDebugImages, "Score::renderPaletteCycle(): fading palette to %d over %d frames", currentPalette, frameCount);
+ debugC(2, kDebugImages, "Score::renderPaletteCycle(): fading palette to %s over %d frames", currentPalette.asString().c_str(), frameCount);
}
if (_frames[frameId]->_palette.normal) {
@@ -950,8 +941,8 @@ void Score::renderPaletteCycle(uint16 frameId, RenderMode mode) {
} else {
// Short circuit for fast renderer
if (debugChannelSet(-1, kDebugFast)) {
- debugC(2, kDebugImages, "Score::renderPaletteCycle(): setting palette to %d", currentPalette);
- g_director->setPalette(resolvePaletteId(currentPalette));
+ debugC(2, kDebugImages, "Score::renderPaletteCycle(): setting palette to %s", currentPalette.asString().c_str());
+ g_director->setPalette(currentPalette);
return;
}
@@ -983,14 +974,14 @@ void Score::renderPaletteCycle(uint16 frameId, RenderMode mode) {
for (int i = 0; i < fadeColorWait; i++) {
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {
- debugC(2, kDebugImages, "Score::renderPaletteCycle(): interrupted, setting palette to %d", currentPalette);
- g_director->setPalette(resolvePaletteId(currentPalette));
+ debugC(2, kDebugImages, "Score::renderPaletteCycle(): interrupted, setting palette to %s", currentPalette.asString().c_str());
+ g_director->setPalette(currentPalette);
return;
}
g_director->delayMillis(frameDelay);
}
- debugC(2, kDebugImages, "Score::renderPaletteCycle(): fading palette to %d over %d frames", currentPalette, fadeFrames);
+ debugC(2, kDebugImages, "Score::renderPaletteCycle(): fading palette to %s over %d frames", currentPalette.asString().c_str(), fadeFrames);
for (int i = 0; i < fadeFrames; i++) {
lerpPalette(
@@ -1004,8 +995,8 @@ void Score::renderPaletteCycle(uint16 frameId, RenderMode mode) {
g_director->draw();
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {
- debugC(2, kDebugImages, "Score::renderPaletteCycle(): interrupted, setting palette to %d", currentPalette);
- g_director->setPalette(resolvePaletteId(currentPalette));
+ debugC(2, kDebugImages, "Score::renderPaletteCycle(): interrupted, setting palette to %s", currentPalette.asString().c_str());
+ g_director->setPalette(currentPalette);
return;
}
g_director->delayMillis(frameDelay);
@@ -1352,7 +1343,7 @@ void Score::loadFrames(Common::SeekableReadStreamEndian &stream, uint16 version)
memset(channelData, 0, kChannelDataSize);
uint8 currentTempo = 0;
- int currentPaletteId = 0;
+ CastMemberID currentPaletteId = CastMemberID(0, 0);
while (size != 0 && !stream.eos()) {
uint16 frameSize = stream.readUint16();
@@ -1394,7 +1385,7 @@ void Score::loadFrames(Common::SeekableReadStreamEndian &stream, uint16 version)
frame->_scoreCachedTempo = frame->_tempo ? frame->_tempo : currentTempo;
// Precache the current palette ID, as this carries forward to frames to the right
// of the instruction.
- if (frame->_palette.paletteId)
+ if (!frame->_palette.paletteId.isNull())
currentPaletteId = frame->_palette.paletteId;
frame->_scoreCachedPaletteId = currentPaletteId;
@@ -1567,16 +1558,16 @@ void Score::loadActions(Common::SeekableReadStreamEndian &stream) {
Common::String Score::formatChannelInfo() {
Frame &frame = *_frames[_currentFrame];
Common::String result;
- int defaultPalette = g_director->getCurrentMovie()->getCast()->_defaultPalette.member;
+ CastMemberID defaultPalette = g_director->getCurrentMovie()->getCast()->_defaultPalette;
result += Common::String::format("TMPO: tempo: %d, skipFrameFlag: %d, blend: %d, currentFPS: %d\n",
frame._tempo, frame._skipFrameFlag, frame._blend, _currentFrameRate);
- if (frame._palette.paletteId) {
- result += Common::String::format("PAL: paletteId: %d, firstColor: %d, lastColor: %d, flags: %d, cycleCount: %d, speed: %d, frameCount: %d, fade: %d, delay: %d, style: %d, currentId: %d, defaultId: %d\n",
- resolvePaletteId(frame._palette.paletteId), frame._palette.firstColor, frame._palette.lastColor, frame._palette.flags,
+ if (!frame._palette.paletteId.isNull()) {
+ result += Common::String::format("PAL: paletteId: %s, firstColor: %d, lastColor: %d, flags: %d, cycleCount: %d, speed: %d, frameCount: %d, fade: %d, delay: %d, style: %d, currentId: %s, defaultId: %s\n",
+ frame._palette.paletteId.asString().c_str(), frame._palette.firstColor, frame._palette.lastColor, frame._palette.flags,
frame._palette.cycleCount, frame._palette.speed, frame._palette.frameCount,
- frame._palette.fade, frame._palette.delay, frame._palette.style, resolvePaletteId(_lastPalette), defaultPalette);
+ frame._palette.fade, frame._palette.delay, frame._palette.style, _lastPalette.asString().c_str(), defaultPalette.asString().c_str());
} else {
- result += Common::String::format("PAL: paletteId: 000, currentId: %d, defaultId: %d\n", resolvePaletteId(_lastPalette), defaultPalette);
+ result += Common::String::format("PAL: paletteId: 000, currentId: %s, defaultId: %s\n", _lastPalette.asString().c_str(), defaultPalette.asString().c_str());
}
result += Common::String::format("TRAN: transType: %d, transDuration: %d, transChunkSize: %d\n",
frame._transType, frame._transDuration, frame._transChunkSize);
diff --git a/engines/director/score.h b/engines/director/score.h
index f4a508084f5..4421e3b7b58 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -94,8 +94,7 @@ public:
uint16 getCurrentFrame() { return _currentFrame; }
int getNextFrame() { return _nextFrame; }
- int getCurrentPalette();
- int resolvePaletteId(int id);
+ CastMemberID getCurrentPalette();
Channel *getChannelById(uint16 id);
Sprite *getSpriteById(uint16 id);
@@ -150,7 +149,7 @@ public:
byte _puppetTempo;
bool _puppetPalette;
- int _lastPalette;
+ CastMemberID _lastPalette;
int _paletteTransitionIndex;
byte _paletteSnapshotBuffer[768];
diff --git a/engines/director/tests.cpp b/engines/director/tests.cpp
index a8ea3f366f5..b5cdbe4952a 100644
--- a/engines/director/tests.cpp
+++ b/engines/director/tests.cpp
@@ -52,7 +52,7 @@ void Window::testFontScaling() {
int w = g_system->getWidth();
int h = g_system->getHeight();
- _vm->setPalette(-1);
+ _vm->setPalette(CastMemberID(kClutSystemMac, -1));
Graphics::ManagedSurface surface;
diff --git a/engines/director/transitions.cpp b/engines/director/transitions.cpp
index 4fe43bea256..b33747ce441 100644
--- a/engines/director/transitions.cpp
+++ b/engines/director/transitions.cpp
@@ -154,7 +154,7 @@ void Window::stepTransition(TransParams &t, int step) {
g_director->draw();
}
-void Window::playTransition(uint frame, uint16 transDuration, uint8 transArea, uint8 transChunkSize, TransitionType transType, int paletteId) {
+void Window::playTransition(uint frame, uint16 transDuration, uint8 transArea, uint8 transChunkSize, TransitionType transType, CastMemberID paletteId) {
// Play a transition and return the number of subframes rendered
TransParams t;
@@ -174,7 +174,7 @@ void Window::playTransition(uint frame, uint16 transDuration, uint8 transArea, u
t.targetPal = g_director->getPalette();
t.targetPalLength = g_director->getPaletteColorCount();
- if (paletteId) {
+ if (!paletteId.isNull()) {
PaletteV4 *target = g_director->getPalette(paletteId);
if (target) {
t.targetPal = target->palette;
diff --git a/engines/director/types.h b/engines/director/types.h
index 78408faa823..d0cfed4d6fd 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -22,6 +22,8 @@
#ifndef DIRECTOR_TYPES_H
#define DIRECTOR_TYPES_H
+#include "common/hashmap.h"
+
namespace Director {
#define CONTINUATION (0xAC)
@@ -394,16 +396,18 @@ struct CastMemberID {
CastMemberID(int memberID, int castLibID)
: member(memberID), castLib(castLibID) {}
- bool operator==(const CastMemberID &c) {
+ bool operator==(const CastMemberID &c) const {
return member == c.member && castLib == c.castLib;
}
- bool operator!=(const CastMemberID &c) {
+ bool operator!=(const CastMemberID &c) const {
return member != c.member || castLib != c.castLib;
}
- bool isNull() { return member == 0 && castLib == 0; }
+ bool isNull() const { return member == 0 && castLib == 0; }
Common::String asString() const;
+
+ uint hash() const { return ((castLib & 0xffff) << 16) + (member & 0xffff); }
};
enum CompareResult {
@@ -429,4 +433,15 @@ const char *spriteType2str(SpriteType type);
} // End of namespace Director
+namespace Common {
+
+template<>
+struct Hash<Director::CastMemberID> {
+ uint operator()(const Director::CastMemberID &id) const {
+ return id.hash();
+ }
+};
+
+} // End of namespace Common
+
#endif
diff --git a/engines/director/window.h b/engines/director/window.h
index 1b1e54a2cac..48fae303502 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -118,7 +118,7 @@ public:
// transitions.cpp
void exitTransition(TransParams &t, int step, Graphics::ManagedSurface *nextFrame, Common::Rect clipRect);
void stepTransition(TransParams &t, int step);
- void playTransition(uint frame, uint16 transDuration, uint8 transArea, uint8 transChunkSize, TransitionType transType, int paletteId);
+ void playTransition(uint frame, uint16 transDuration, uint8 transArea, uint8 transChunkSize, TransitionType transType, CastMemberID paletteId);
void initTransParams(TransParams &t, Common::Rect &clipRect);
void dissolveTrans(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *tmpSurface);
void dissolvePatternsTrans(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *tmpSurface);
Commit: 5426729bf463505065901f790f65f7a0f2d29077
https://github.com/scummvm/scummvm/commit/5426729bf463505065901f790f65f7a0f2d29077
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Fix zoom transitions
Changed paths:
engines/director/resource.cpp
engines/director/score.cpp
engines/director/score.h
engines/director/transitions.cpp
engines/director/window.h
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index c218c5547af..67f9611c939 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -33,9 +33,10 @@
#include "director/archive.h"
#include "director/cast.h"
#include "director/movie.h"
+#include "director/score.h"
+#include "director/util.h"
#include "director/window.h"
#include "director/lingo/lingo.h"
-#include "director/util.h"
namespace Director {
@@ -90,7 +91,7 @@ Common::Error Window::loadInitialMovie() {
}
_currentMovie->setArchive(_mainArchive);
-
+ _currentMovie->getScore()->_skipTransition = true;
// XLibs are usually loaded in the initial movie.
// These may not be present if a --start-movie is specified, so
// we sometimes need to load them manually.
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index a77a7817a7c..74076ebab04 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -87,6 +87,7 @@ Score::Score(Movie *movie) {
_playState = kPlayNotStarted;
_numChannelsDisplayed = 0;
+ _skipTransition = false;
}
Score::~Score() {
@@ -561,7 +562,10 @@ void Score::renderFrame(uint16 frameId, RenderMode mode) {
if (_window->_newMovieStarted)
renderCursor(_movie->getWindow()->getMousePos(), true);
- if (!renderTransition(frameId)) {
+ if (_skipTransition) {
+ _window->render();
+ _skipTransition = false;
+ } else if (!renderTransition(frameId)) {
bool skip = renderPrePaletteCycle(frameId, mode);
setLastPalette(frameId);
renderSprites(frameId, mode);
diff --git a/engines/director/score.h b/engines/director/score.h
index 4421e3b7b58..04da7f07cb9 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -164,6 +164,7 @@ public:
int _activeFade;
Cursor _defaultCursor;
CursorRef _currentCursor;
+ bool _skipTransition;
int _numChannelsDisplayed;
diff --git a/engines/director/transitions.cpp b/engines/director/transitions.cpp
index b33747ce441..9042e0cb785 100644
--- a/engines/director/transitions.cpp
+++ b/engines/director/transitions.cpp
@@ -255,7 +255,7 @@ void Window::playTransition(uint frame, uint16 transDuration, uint8 transArea, u
return;
case kTransAlgoZoom:
- transZoom(t, clipRect, &nextFrame);
+ transZoom(t, clipRect, ¤tFrame, &nextFrame);
debugC(2, kDebugImages, "Window::playTransition(): type: %d, duration: %d, chunkSize: %d, steps: %d, stepDuration: %d, xpos: %d, ypos: %d, xStepSize: %d, yStepSize: %d, stripSize: %d", t.type, t.duration, t.chunkSize, t.steps, t.stepDuration, t.xpos, t.ypos, t.xStepSize, t.yStepSize, t.stripSize);
debugC(2, kDebugImages, "Window::playTransition(): Transition %d finished in %d ms", t.type, g_system->getMillis() - transStartTime);
return;
@@ -1062,17 +1062,25 @@ void Window::transMultiPass(TransParams &t, Common::Rect &clipRect, Graphics::Ma
}
}
-void Window::transZoom(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *nextFrame) {
+void Window::transZoom(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *currentFrame, Graphics::ManagedSurface *nextFrame) {
Common::Rect r = clipRect;
uint w = clipRect.width();
uint h = clipRect.height();
+ t.steps >>= 1;
+ t.xStepSize <<= 1;
+ t.yStepSize <<= 1;
+ t.steps += 1;
- t.steps += 2;
-
- Graphics::MacPlotData pd(_composeSurface, nullptr, &g_director->_wm->getPatterns(), Graphics::kPatternCheckers, 0, 0, 1, 0);
+ DirectorPlotData pd(g_director, kLineTopBottomSprite, kInkTypeReverse, 0, _wm->_colorWhite, _wm->_colorBlack);
+ pd.destRect = clipRect;
+ pd.dst = _composeSurface;
for (uint16 i = 1; i < t.steps; i++) {
uint32 startTime = g_system->getMillis();
+
+ // FIXME: figure out the bounding box of the drawn bits
+ _composeSurface->copyRectToSurface(*currentFrame, clipRect.left, clipRect.top, clipRect);
+
for (int s = 2; s >= 0; s--) {
if (i - s < 0 || i - s > t.steps - 2)
continue;
@@ -1087,27 +1095,33 @@ void Window::transZoom(TransParams &t, Common::Rect &clipRect, Graphics::Managed
r.moveTo(t.xStepSize * (i - s), t.yStepSize * (i - s));
}
- Graphics::drawLine(r.left, r.top, r.right, r.top, 0xffff, _wm->getDrawPixel(), &pd);
- Graphics::drawLine(r.right, r.top, r.right, r.bottom, 0xffff, _wm->getDrawPixel(), &pd);
- Graphics::drawLine(r.left, r.bottom, r.right, r.bottom, 0xffff, _wm->getDrawPixel(), &pd);
- Graphics::drawLine(r.left, r.top, r.left, r.bottom, 0xffff, _wm->getDrawPixel(), &pd);
+ Graphics::drawLine(r.left, r.top, r.right, r.top, _wm->_colorBlack, g_director->getInkDrawPixel(), &pd);
+ Graphics::drawLine(r.right, r.top, r.right, r.bottom, _wm->_colorBlack, g_director->getInkDrawPixel(), &pd);
+ Graphics::drawLine(r.left, r.bottom, r.right, r.bottom, _wm->_colorBlack, g_director->getInkDrawPixel(), &pd);
+ Graphics::drawLine(r.left, r.top, r.left, r.bottom, _wm->_colorBlack, g_director->getInkDrawPixel(), &pd);
}
r.setHeight(t.yStepSize * i * 2);
r.setWidth(t.xStepSize * i * 2);
r.moveTo(w / 2 - t.xStepSize * i, h / 2 - t.yStepSize * i);
- g_lingo->executePerFrameHook(t.frame, i);
+ if (_vm->processEvents(true)) {
+ exitTransition(t, i, nextFrame, clipRect);
+ break;
+ }
+
+ stepTransition(t, i);
uint32 endTime = g_system->getMillis();
int diff = (int)t.stepDuration - (int)(endTime - startTime);
g_director->delayMillis(MAX(0, diff));
- if (_vm->processEvents(true)) {
- exitTransition(t, i, nextFrame, clipRect);
- break;
- }
+ g_lingo->executePerFrameHook(t.frame, i);
}
+
+ render(true, _composeSurface);
+ _contentIsDirty = true;
+ g_director->draw();
}
void Window::initTransParams(TransParams &t, Common::Rect &clipRect) {
diff --git a/engines/director/window.h b/engines/director/window.h
index 48fae303502..70199f75b59 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -123,7 +123,7 @@ public:
void dissolveTrans(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *tmpSurface);
void dissolvePatternsTrans(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *tmpSurface);
void transMultiPass(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *tmpSurface);
- void transZoom(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *tmpSurface);
+ void transZoom(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *currentFrame, Graphics::ManagedSurface *nextFrame);
// window.cpp
Common::Point getMousePos();
Commit: 919b7ff5b1da80c95e7e76a21c7bcab7243d182b
https://github.com/scummvm/scummvm/commit/919b7ff5b1da80c95e7e76a21c7bcab7243d182b
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Show multiple casts in debugger
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
engines/director/castmember/script.cpp
engines/director/castmember/script.h
engines/director/debugger.cpp
engines/director/movie.h
engines/director/types.cpp
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 94a4474ad82..325b77a16bb 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -115,13 +115,13 @@ Cast::~Cast() {
delete _lingoArchive;
}
-CastMember *Cast::getCastMember(int castId) {
+CastMember *Cast::getCastMember(int castId, bool load) {
CastMember *result = nullptr;
if (_loadedCast && _loadedCast->contains(castId)) {
result = _loadedCast->getVal(castId);
}
- if (result && _loadMutex) {
+ if (result && load && _loadMutex) {
// Archives only support having one stream open at a time,
// prevent recursive calls to CastMember::load()
_loadMutex = false;
@@ -1379,7 +1379,7 @@ Common::String Cast::formatCastSummary(int castId = -1) {
for (auto it = castIds.begin(); it != castIds.end(); ++it) {
if (castId > -1 && *it != castId)
continue;
- CastMember *castMember = getCastMember(*it);
+ CastMember *castMember = getCastMember(*it, false);
CastMemberInfo *castMemberInfo = getCastMemberInfo(*it);
Common::String info = castMember->formatInfo();
result += Common::String::format("%5d", *it);
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 39695639d67..430fff34a26 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -99,7 +99,7 @@ public:
void setCastMemberModified(int castId);
CastMember *setCastMember(CastMemberID castId, CastMember *cast);
bool eraseCastMember(CastMemberID castId);
- CastMember *getCastMember(int castId);
+ CastMember *getCastMember(int castId, bool load = true);
CastMember *getCastMemberByNameAndType(const Common::String &name, CastType type);
CastMember *getCastMemberByScriptId(int scriptId);
CastMemberInfo *getCastMemberInfo(int castId);
diff --git a/engines/director/castmember/script.cpp b/engines/director/castmember/script.cpp
index 253cf799cc9..88c8d9c5d7a 100644
--- a/engines/director/castmember/script.cpp
+++ b/engines/director/castmember/script.cpp
@@ -60,4 +60,10 @@ ScriptCastMember::ScriptCastMember(Cast *cast, uint16 castId, Common::SeekableRe
}
}
+Common::String ScriptCastMember::formatInfo() {
+ return Common::String::format(
+ "scriptType: %s", scriptType2str(_scriptType)
+ );
+}
+
}
diff --git a/engines/director/castmember/script.h b/engines/director/castmember/script.h
index a6c1e8610a4..bcaccd694d3 100644
--- a/engines/director/castmember/script.h
+++ b/engines/director/castmember/script.h
@@ -31,6 +31,8 @@ public:
ScriptCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
ScriptType _scriptType;
+
+ Common::String formatInfo() override;
};
} // End of namespace Director
diff --git a/engines/director/debugger.cpp b/engines/director/debugger.cpp
index 779eea01753..cf2e060a757 100644
--- a/engines/director/debugger.cpp
+++ b/engines/director/debugger.cpp
@@ -289,27 +289,30 @@ bool Debugger::cmdChannels(int argc, const char **argv) {
}
bool Debugger::cmdCast(int argc, const char **argv) {
- Cast *cast = g_director->getCurrentMovie()->getCast();
- Cast *sharedCast = g_director->getCurrentMovie()->getSharedCast();
+ Movie *movie = g_director->getCurrentMovie();
+ Cast *sharedCast = movie->getSharedCast();
int castId = -1;
if (argc == 2)
castId = atoi(argv[1]);
- debugPrintf("Cast:\n");
- if (!cast) {
- debugPrintf("[empty]\n");
- } else if (castId > -1 && !cast->getCastMember(castId)) {
- debugPrintf("[not found]\n");
- } else {
- debugPrintf("%s\n", cast->formatCastSummary(castId).c_str());
+ for (auto it : *movie->getCasts()) {
+ debugPrintf("Cast %d:\n", it._key);
+ Cast *cast = it._value;
+ if (!cast) {
+ debugPrintf("[empty]\n");
+ } else if (castId > -1 && !cast->getCastMember(castId, false)) {
+ debugPrintf("[not found]\n");
+ } else {
+ debugPrintf("%s\n", cast->formatCastSummary(castId).c_str());
+ }
+ debugPrintf("\n");
}
- debugPrintf("\n");
debugPrintf("Shared cast:\n");
if (!sharedCast) {
debugPrintf("[empty]\n");
- } else if (castId > -1 && !sharedCast->getCastMember(castId)) {
+ } else if (castId > -1 && !sharedCast->getCastMember(castId, false)) {
debugPrintf("[not found]\n");
} else {
debugPrintf("%s\n", sharedCast->formatCastSummary(castId).c_str());
diff --git a/engines/director/movie.h b/engines/director/movie.h
index abd7580dd42..e8ded21529e 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -100,6 +100,7 @@ public:
DirectorEngine *getVM() const { return _vm; }
Cast *getCast() const { return _casts.getValOrDefault(DEFAULT_CAST_LIB, nullptr); }
Cast *getSharedCast() const { return _sharedCast; }
+ const Common::HashMap<int, Cast *> *getCasts() const { return &_casts; }
Score *getScore() const { return _score; }
void clearSharedCast();
diff --git a/engines/director/types.cpp b/engines/director/types.cpp
index 93e5b35cd83..09845265fe9 100644
--- a/engines/director/types.cpp
+++ b/engines/director/types.cpp
@@ -59,13 +59,15 @@ const char *castTypes[] = {
"digitalVideo",
"script",
"RTE",
+ "???",
+ "transition",
};
const char *castType2str(CastType type) {
if (type == kCastTypeAny)
return "any";
- if (type <= kCastRTE)
+ if (type <= kCastTransition)
return castTypes[type];
warning("BUILDBOT: Unknown castType: %d", type);
Commit: 8976c4f56bc8c0d727cf9d47c2fc960b8e029bb9
https://github.com/scummvm/scummvm/commit/8976c4f56bc8c0d727cf9d47c2fc960b8e029bb9
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-10T09:48:50+02:00
Commit Message:
DIRECTOR: Fix parse bug in loadCastlibMapping
Changed paths:
engines/director/cast.cpp
engines/director/movie.cpp
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 325b77a16bb..61be6da86e1 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -243,6 +243,10 @@ void Cast::loadArchive() {
}
bool Cast::loadConfig() {
+ if (!_castArchive) {
+ warning("Cast::loadConfig(): No archive specified");
+ return false;
+ }
Common::SeekableReadStreamEndian *stream = nullptr;
stream = _castArchive->getMovieResourceIfPresent(MKTAG('V', 'W', 'C', 'F'));
if (!stream) {
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index 4be0a0e98a3..13012e95151 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -143,17 +143,19 @@ void Movie::loadCastLibMapping(Common::SeekableReadStreamEndian &stream) {
stream.readUint32();
}
for (uint32 i = 0; i < count; i++) {
- int nameSize = stream.readByte() + 1;
+ int nameSize = stream.readByte();
Common::String name = stream.readString('\0', nameSize);
- int pathSize = stream.readByte() + 1;
+ stream.readByte(); // null
+ int pathSize = stream.readByte();
Common::String path = stream.readString('\0', pathSize);
+ stream.readByte(); // null
if (pathSize > 1)
stream.readUint16();
stream.readUint16();
uint16 itemCount = stream.readUint16();
stream.readUint16();
uint16 libId = stream.readUint16() - CAST_LIB_OFFSET;
- debugC(5, kDebugLoading, "Movie::loadCastLibMapping: name: %s, path: %s, itemCount: %d, libId: %d", name.c_str(), path.c_str(), itemCount, libId);
+ debugC(5, kDebugLoading, "Movie::loadCastLibMapping: name: %s, path: %s, itemCount: %d, libId: %d", utf8ToPrintable(name).c_str(), utf8ToPrintable(path).c_str(), itemCount, libId);
Archive *castArchive = _movieArchive;
bool isExternal = !path.empty();
if (isExternal) {
More information about the Scummvm-git-logs
mailing list