X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
32eb6fb
DIRECTOR: Add xlibs command to debugger
moralrecordings Apr 15, 2025
331ec1b
DIRECTOR: Use refcounts for cast members, implement 'the media'
moralrecordings Apr 16, 2025
c9ee675
DIRECTOR: Remove alternate palette format
moralrecordings Apr 16, 2025
23a0f31
DIRECTOR: Implement the name of castLib setter
moralrecordings Apr 17, 2025
e6b1543
DIRECTOR: LINGO: Fix range check in b_member
moralrecordings Apr 17, 2025
6c3d455
DIRECTOR: Add null check in TextCastMember::isWithin
moralrecordings Apr 17, 2025
713b077
DIRECTOR: Add Search for the Golden Dolphin to detection table
moralrecordings Apr 17, 2025
c291a52
DIRECTOR: Add perFrameHook recursion-break behaviour specific to D5
moralrecordings Apr 17, 2025
2ea25a3
DIRECTOR: LINGO: Improve accuracy of 'the result'
moralrecordings Apr 17, 2025
80a4d7a
DIRECTOR: Only write back from TextCastMember widget if in edit mode
moralrecordings Apr 17, 2025
0edd1e6
DIRECTOR: LINGO: Implement the keyPressed
moralrecordings Apr 17, 2025
6edd580
MACGUI: Fix MacText::getMouse*
moralrecordings Apr 17, 2025
b0618af
GRAPHICS: MACGUI: Add debugging output to getTextChunk
moralrecordings Apr 20, 2025
8c8ba33
DIRECTOR: Check before reloading castLibs
moralrecordings Apr 20, 2025
b05a5b4
DIRECTOR: LINGO: Enable dirty flag when setting locH/locV for trails
moralrecordings Apr 24, 2025
f7f223e
DIRECTOR: Allow AIFF playback in DigitalVideoCastMember
moralrecordings Apr 24, 2025
6dee21e
DIRECTOR: Keep track of old sprite bboxes for rollOver
moralrecordings Apr 24, 2025
77c96cc
DIRECTOR: Fix parsing "when mousedown then"
moralrecordings Apr 25, 2025
ed16217
DIRECTOR: Move "the hilite" property to base CastMember
moralrecordings Apr 25, 2025
1f7004b
DIRECTOR: Fix Mac resource mouse cursor offset
moralrecordings Apr 25, 2025
88e9012
DIRECTOR: Fix Cursor::readFromCast if no mask is provided
moralrecordings May 4, 2025
1d56991
DIRECTOR: Add Gus Goes to the Kooky Carnival to detection table
moralrecordings May 8, 2025
fff626e
DIRECTOR: Add guardrail for empty RTE1 block
moralrecordings May 8, 2025
73daa08
DIRECTOR: Add guardrail for copying from a zero-sized bitmap
moralrecordings May 8, 2025
0abd8e9
DIRECTOR: Set default palette as soon as the first movie loads
moralrecordings May 8, 2025
d0f5125
DIRECTOR: RichTextCastMember fixes
moralrecordings May 8, 2025
56b523c
DIRECTOR: Wire up D5 rightMouseDown and rightMouseUp handlers
moralrecordings May 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 37 additions & 88 deletions engines/director/cast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Cast::~Cast() {
if (_loadedCast)
for (auto &it : *_loadedCast)
if (it._value) {
delete it._value;
it._value->decRefCount();
it._value = nullptr;
}

Expand Down Expand Up @@ -236,10 +236,8 @@ void Cast::setCastMemberModified(int castId) {
}

CastMember *Cast::setCastMember(int castId, CastMember *cast) {
if (_loadedCast->contains(castId)) {
_loadedCast->erase(castId);
}

eraseCastMember(castId);
cast->incRefCount();
_loadedCast->setVal(castId, cast);
return cast;
}
Expand All @@ -252,43 +250,7 @@ bool Cast::duplicateCastMember(CastMember *source, CastMemberInfo *info, int tar
// is the same as deleting the target
if (!source)
return true;
CastMember *target = nullptr;
switch (source->_type) {
case kCastBitmap:
target = (CastMember *)(new BitmapCastMember(this, targetId, *(BitmapCastMember *)source));
break;
case kCastDigitalVideo:
target = (CastMember *)(new DigitalVideoCastMember(this, targetId, *(DigitalVideoCastMember *)source));
break;
case kCastFilmLoop:
target = (CastMember *)(new FilmLoopCastMember(this, targetId, *(FilmLoopCastMember *)source));
break;
case kCastMovie:
target = (CastMember *)(new MovieCastMember(this, targetId, *(MovieCastMember *)source));
break;
case kCastPalette:
target = (CastMember *)(new PaletteCastMember(this, targetId, *(PaletteCastMember *)source));
break;
case kCastLingoScript:
target = (CastMember *)(new ScriptCastMember(this, targetId, *(ScriptCastMember *)source));
break;
case kCastShape:
target = (CastMember *)(new ShapeCastMember(this, targetId, *(ShapeCastMember *)source));
break;
case kCastText:
target = (CastMember *)(new TextCastMember(this, targetId, *(TextCastMember *)source));
break;
case kCastRichText:
target = (CastMember *)(new RichTextCastMember(this, targetId, *(RichTextCastMember *)source));
break;
case kCastTransition:
target = (CastMember *)(new TransitionCastMember(this, targetId, *(TransitionCastMember *)source));
break;
default:
warning("Cast::duplicateCastMember(): unsupported cast type %s", castType2str(source->_type));
return false;
break;
}
CastMember *target = source->duplicate(this, targetId);

if (info) {
CastMemberInfo *newInfo = new CastMemberInfo(*info);
Expand All @@ -304,7 +266,7 @@ bool Cast::duplicateCastMember(CastMember *source, CastMemberInfo *info, int tar
bool Cast::eraseCastMember(int castId) {
if (_loadedCast->contains(castId)) {
CastMember *member = _loadedCast->getVal(castId);
delete member;
member->decRefCount();
_loadedCast->erase(castId);

if (_castsInfo.contains(castId)) {
Expand Down Expand Up @@ -827,32 +789,13 @@ PaletteV4 Cast::loadPalette(Common::SeekableReadStreamEndian &stream, int id) {
if (debugChannelSet(5, kDebugLoading))
stream.hexdump(stream.size());

bool hasHeader = size != 6 * 256;
int steps = 256;
if (hasHeader) {
stream.skip(6);
steps = stream.readUint16();
int maxSteps = (size - 8) / 8;
if (steps > maxSteps) {
warning("Cast::loadPalette(): header says %d steps but there's only enough data for %d, reducing", steps, maxSteps);
steps = maxSteps;
}
}
int steps = size / 6;
debugC(3, kDebugLoading, "Cast::loadPalette(): %d steps", steps);

byte *palette = new byte[steps * 3];


int colorIndex = 0;

for (int i = 0; i < steps; i++) {
if (hasHeader) {
int index = stream.readUint16BE();
if (index != 0x8000) {
colorIndex = index;
}
}

if (colorIndex >= steps) {
warning("Cast::loadPalette(): attempted to set invalid color index %d, aborting", colorIndex);
break;
Expand Down Expand Up @@ -896,6 +839,7 @@ void Cast::loadCastDataVWCR(Common::SeekableReadStreamEndian &stream) {
}

int returnPos = stream.pos() + size;
CastMember *target = nullptr;
switch (castType) {
case kCastBitmap:
debugC(3, kDebugLoading, "Cast::loadCastDataVWCR(): CastTypes id: %d(%s) BitmapCastMember", id, numToCastNum(id));
Expand All @@ -908,42 +852,44 @@ void Cast::loadCastDataVWCR(Common::SeekableReadStreamEndian &stream) {
break;
}

_loadedCast->setVal(id, new BitmapCastMember(this, id, stream, tag, _version, flags1));
target = new BitmapCastMember(this, id, stream, tag, _version, flags1);
break;
case kCastText:
debugC(3, kDebugLoading, "Cast::loadCastDataVWCR(): CastTypes id: %d(%s) TextCastMember", id, numToCastNum(id));
_loadedCast->setVal(id, new TextCastMember(this, id, stream, _version, flags1));
target = new TextCastMember(this, id, stream, _version, flags1);
break;
case kCastShape:
debugC(3, kDebugLoading, "Cast::loadCastDataVWCR(): CastTypes id: %d(%s) ShapeCastMember", id, numToCastNum(id));
_loadedCast->setVal(id, new ShapeCastMember(this, id, stream, _version));
target = new ShapeCastMember(this, id, stream, _version);
break;
case kCastButton:
debugC(3, kDebugLoading, "Cast::loadCastDataVWCR(): CastTypes id: %d(%s) ButtonCast", id, numToCastNum(id));
_loadedCast->setVal(id, new TextCastMember(this, id, stream, _version, flags1, true));
target =new TextCastMember(this, id, stream, _version, flags1, true);
break;
case kCastSound:
debugC(3, kDebugLoading, "Cast::loadCastDataVWCR(): CastTypes id: %d(%s) SoundCastMember", id, numToCastNum(id));
_loadedCast->setVal(id, new SoundCastMember(this, id, stream, _version));
target = new SoundCastMember(this, id, stream, _version);
break;
case kCastDigitalVideo:
debugC(3, kDebugLoading, "Cast::loadCastDataVWCR(): CastTypes id: %d(%s) DigitalVideoCastMember", id, numToCastNum(id));
_loadedCast->setVal(id, new DigitalVideoCastMember(this, id, stream, _version));
target = new DigitalVideoCastMember(this, id, stream, _version);
break;
case kCastPalette:
debugC(3, kDebugLoading, "Cast::loadCastDataVWCR(): CastTypes id: %d(%s) PaletteCastMember", id, numToCastNum(id));
_loadedCast->setVal(id, new PaletteCastMember(this, id, stream, _version));
target = new PaletteCastMember(this, id, stream, _version);
// load the palette now, as there are no CastInfo structs
_loadedCast->getVal(id)->load();
target->load();
break;
case kCastFilmLoop:
debugC(3, kDebugLoading, "Cast::loadCastDataVWCR(): CastTypes id: %d(%s) FilmLoopCastMember", id, numToCastNum(id));
_loadedCast->setVal(id, new FilmLoopCastMember(this, id, stream, _version));
target = new FilmLoopCastMember(this, id, stream, _version);
break;
default:
warning("Cast::loadCastDataVWCR(): Unhandled cast id: %d(%s), type: %d, %d bytes", id, numToCastNum(id), castType, size);
break;
}
if (target)
setCastMember(id, target);
stream.seek(returnPos);
}
}
Expand Down Expand Up @@ -1049,69 +995,72 @@ void Cast::loadCastData(Common::SeekableReadStreamEndian &stream, uint16 id, Res

if (_loadedCast->contains(id)) {
warning("Cast::loadCastData(): Multiple cast members with ID %d, overwriting", id);
delete _loadedCast->getVal(id);
_loadedCast->erase(id);
eraseCastMember(id);
}

CastMember *target = nullptr;
switch (castType) {
case kCastBitmap:
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastBitmap (%d children)", res->children.size());
_loadedCast->setVal(id, new BitmapCastMember(this, id, castStream, res->tag, _version, flags1));
target = new BitmapCastMember(this, id, castStream, res->tag, _version, flags1);
break;
case kCastSound:
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastSound (%d children)", res->children.size());
_loadedCast->setVal(id, new SoundCastMember(this, id, castStream, _version));
target = new SoundCastMember(this, id, castStream, _version);
break;
case kCastText:
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastText (%d children)", res->children.size());
_loadedCast->setVal(id, new TextCastMember(this, id, castStream, _version, flags1));
target = new TextCastMember(this, id, castStream, _version, flags1);
break;
case kCastShape:
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastShape (%d children)", res->children.size());
_loadedCast->setVal(id, new ShapeCastMember(this, id, castStream, _version));
target = new ShapeCastMember(this, id, castStream, _version);
break;
case kCastButton:
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastButton (%d children)", res->children.size());
_loadedCast->setVal(id, new TextCastMember(this, id, castStream, _version, flags1, true));
target = new TextCastMember(this, id, castStream, _version, flags1, true);
break;
case kCastLingoScript:
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastLingoScript");
_loadedCast->setVal(id, new ScriptCastMember(this, id, castStream, _version));
target = new ScriptCastMember(this, id, castStream, _version);
break;
case kCastRichText:
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastRichText (%d children)", res->children.size());
_loadedCast->setVal(id, new RichTextCastMember(this, id, castStream, _version));
target = new RichTextCastMember(this, id, castStream, _version);
break;
case kCastDigitalVideo:
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastDigitalVideo (%d children)", res->children.size());
_loadedCast->setVal(id, new DigitalVideoCastMember(this, id, castStream, _version));
target = new DigitalVideoCastMember(this, id, castStream, _version);
break;
case kCastFilmLoop:
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastFilmLoop (%d children)", res->children.size());
_loadedCast->setVal(id, new FilmLoopCastMember(this, id, castStream, _version));
target = new FilmLoopCastMember(this, id, castStream, _version);
break;
case kCastPalette:
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastPalette (%d children)", res->children.size());
_loadedCast->setVal(id, new PaletteCastMember(this, id, castStream, _version));
target = new PaletteCastMember(this, id, castStream, _version);
break;
case kCastPicture:
warning("BUILDBOT: STUB: Cast::loadCastData(): kCastPicture (id=%d, %d children)! This will be missing from the movie and may cause problems", id, res->children.size());
castInfoSize = 0;
break;
case kCastMovie:
debugC(3, kDebugLoading, "Cast::loadCastData(): loading kCastMovie (id=%d, %d children)", id, res->children.size());
_loadedCast->setVal(id, new MovieCastMember(this, id, castStream, _version));
target = 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));
target = new TransitionCastMember(this, id, castStream, _version);
break;
default:
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;
}
if (target) {
setCastMember(id, target);
}
if (castStream.eos()) {
warning("BUILDBOT: Read past dataStream for id: %d type: %s", id, castType2str((CastType) castType));
}
Expand All @@ -1120,11 +1069,11 @@ void Cast::loadCastData(Common::SeekableReadStreamEndian &stream, uint16 id, Res
if (leftOver > 0)
warning("BUILDBOT: Left over bytes: %d in dataStream for id: %d type: %s", leftOver, id, castType2str((CastType) castType));

if (_loadedCast->contains(id)) { // Skip unhandled casts
if (target) { // Skip unhandled casts
debugCN(3, kDebugLoading, "Children: ");
for (uint child = 0; child < res->children.size(); child++) {
debugCN(3, kDebugLoading, "%d ", res->children[child].index);
_loadedCast->getVal(id)->_children.push_back(res->children[child]);
target->_children.push_back(res->children[child]);
}
debugCN(3, kDebugLoading, "\n");
}
Expand Down
30 changes: 20 additions & 10 deletions engines/director/castmember/bitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, BitmapCastMember &

_initialRect = source._initialRect;
_boundingRect = source._boundingRect;
_children = source._children;
if (cast == source._cast)
_children = source._children;

_picture = source._picture ? new Picture(*source._picture) : nullptr;
_ditheredImg = nullptr;
Expand Down Expand Up @@ -303,14 +304,21 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel

Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);

// scale for drawing a different size sprite
copyStretchImg(
_ditheredImg ? _ditheredImg : &_picture->_surface,
widget->getSurface()->surfacePtr(),
_initialRect,
bbox,
pal
);
Graphics::Surface *srcSurface = _ditheredImg ? _ditheredImg : &_picture->_surface;
if ((srcSurface->w <= 0) || (srcSurface->h <= 0)) {
// We're copying from a zero-sized surface; fill widget with white so transparent ink works
Common::Rect dims = widget->getDimensions();
widget->getSurface()->fillRect(Common::Rect(dims.width(), dims.height()), g_director->_wm->_colorWhite);
} else {
// scale for drawing a different size sprite
copyStretchImg(
srcSurface,
widget->getSurface()->surfacePtr(),
_initialRect,
bbox,
pal
);
}

return widget;
}
Expand Down Expand Up @@ -665,8 +673,10 @@ void BitmapCastMember::load() {
} else {
img = new Image::BitmapDecoder();
}
} else if (pic->size() == 0) {
// zero-length bitmap
} else {
warning("BitmapCastMember::load(): Bitmap image %d not found", imgId);
warning("BitmapCastMember::load(): Bitmap image %d has invalid size", imgId);
}

break;
Expand Down
2 changes: 2 additions & 0 deletions engines/director/castmember/bitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class BitmapCastMember : public CastMember {
BitmapCastMember(Cast *cast, uint16 castId, BitmapCastMember &source);
~BitmapCastMember();

CastMember *duplicate(Cast *cast, uint16 castId) override { return (CastMember *)(new BitmapCastMember(cast, castId, *this)); }

Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) override;

bool isModified() override;
Expand Down
13 changes: 13 additions & 0 deletions engines/director/castmember/castmember.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ CastMember::CastMember(Cast *cast, uint16 castId) : Object<CastMember>("CastMemb
_erase = false;
}

CastMember *CastMember::duplicate(Cast *cast, uint16 castId) {
warning("CastMember::duplicate(): unsupported cast type %s", castType2str(_type));
return nullptr;
}

void CastMember::setModified(bool modified) {
_modified = modified;
if (modified)
Expand Down Expand Up @@ -119,6 +124,7 @@ bool CastMember::hasField(int field) {
case kTheFileName:
case kTheForeColor:
case kTheHeight:
case kTheHilite:
case kTheLoaded:
case kTheModified:
case kTheMemberNum:
Expand Down Expand Up @@ -170,6 +176,9 @@ Datum CastMember::getField(int field) {
case kTheHeight:
d = _cast->getCastMemberInitialRect(_castId).height();
break;
case kTheHilite:
d = (int)_hilite;
break;
case kTheLoaded:
d = 1; // Not loaded handled in Lingo::getTheCast
break;
Expand Down Expand Up @@ -240,6 +249,10 @@ bool CastMember::setField(int field, const Datum &d) {
case kTheHeight:
warning("BUILDBOT: CastMember::setField(): Attempt to set read-only field \"%s\" of cast %d", g_lingo->field2str(field), _castId);
return false;
case kTheHilite:
_hilite = (bool)d.asInt();
_modified = true;
return true;
case kTheName:
if (!castInfo) {
warning("CastMember::setField(): CastMember info for %d not found", _castId);
Expand Down
4 changes: 3 additions & 1 deletion engines/director/castmember/castmember.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class CastMember : public Object<CastMember> {
CastMember(Cast *cast, uint16 castId);
virtual ~CastMember() {}

virtual CastMember *duplicate(Cast *cast, uint16 castId);

Cast *getCast() { return _cast; }
uint16 getID() { return _castId; }
CastMemberInfo *getInfo();
Expand All @@ -64,7 +66,7 @@ class CastMember : public Object<CastMember> {
void setModified(bool modified);
virtual Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) { return nullptr; }
virtual void updateWidget(Graphics::MacWidget *widget, Channel *channel) {}
virtual void updateFromWidget(Graphics::MacWidget *widget) {}
virtual void updateFromWidget(Graphics::MacWidget *widget, bool spriteEditable) {}
virtual Common::Rect getInitialRect() { return _initialRect; }

virtual void setColors(uint32 *fgcolor, uint32 *bgcolor) { return; }
Expand Down
Loading
Loading
X Tutup