DIRECTOR: Add support for "get/set picture of cast"

This commit is contained in:
Einar Johan Trøan Sømåen 2023-03-25 07:17:53 +01:00 committed by Einar Johan Trøan Sømåen
parent c3b1baf906
commit 12289a93c8
8 changed files with 62 additions and 5 deletions

View File

@ -550,6 +550,30 @@ Common::String BitmapCastMember::formatInfo() {
);
}
PictureReference *BitmapCastMember::getPicture() const {
auto picture = new PictureReference;
// Not sure if we can make the assumption that the owning
// BitmapCastMember will live as long as any reference,
// so we'll make a copy of the Picture.
picture->_picture = new Picture(*_picture);
return picture;
}
void BitmapCastMember::setPicture(PictureReference &picture) {
delete _picture;
_picture = new Picture(*picture._picture);
// Force redither
delete _ditheredImg;
_ditheredImg = nullptr;
// Make sure we get redrawn
setModified(true);
// TODO: Should size be adjusted?
}
void BitmapCastMember::setPicture(Image::ImageDecoder &image, bool adjustSize) {
delete _picture;
_picture = new Picture(image);

View File

@ -137,6 +137,8 @@ public:
Common::String formatInfo() override;
PictureReference *getPicture() const;
void setPicture(PictureReference &picture);
void setPicture(Image::ImageDecoder &image, bool adjustSize);
Picture *_picture = nullptr;

View File

@ -1767,9 +1767,9 @@ void LB::b_objectp(int nargs) {
}
void LB::b_pictureP(int nargs) {
g_lingo->pop();
warning("STUB: b_pictureP");
g_lingo->push(Datum(0));
Datum d = g_lingo->pop();
Datum res((d.type == PICTUREREF) ? 1 : 0);
g_lingo->push(res);
}
void LB::b_stringp(int nargs) {

View File

@ -963,7 +963,8 @@ Datum BitmapCastMember::getField(int field) {
d = _clut;
break;
case kThePicture:
warning("STUB: BitmapCastMember::getField(): Unprocessed getting field \"%s\" of cast %d", g_lingo->field2str(field), _castId);
d.type = PICTUREREF;
d.u.picture = getPicture();
break;
default:
d = CastMember::getField(field);
@ -993,7 +994,12 @@ bool BitmapCastMember::setField(int field, const Datum &d) {
_clut = d.asInt();
return true;
case kThePicture:
warning("STUB: BitmapCastMember::setField(): Unprocessed setting field \"%s\" of cast %d", g_lingo->field2str(field), _castId);
if (d.type == PICTUREREF && d.u.picture != nullptr) {
setPicture(*d.u.picture);
return true;
} else {
warning("BitmapCastMember::setField(): Wrong Datum type %d for kThePicture (or nullptr)", d.type);
}
return false;
default:
break;

View File

@ -938,6 +938,9 @@ void Datum::reset() {
case MENUREF:
delete u.menu;
break;
case PICTUREREF:
delete u.picture;
break;
default:
warning("Datum::reset(): Unprocessed REF type %d", type);
break;
@ -1163,6 +1166,9 @@ Common::String Datum::asString(bool printonly) const {
case MENUREF:
s = Common::String::format("menu(%d, %d)", u.menu->menuIdNum, u.menu->menuItemIdNum);
break;
case PICTUREREF:
s = Common::String::format("picture: %p", (void*)u.picture->_picture);
break;
default:
warning("Incorrect operation asString() for type: %s", type2str());
}
@ -1228,6 +1234,8 @@ const char *Datum::type2str(bool ilk) const {
return ilk ? "object" : "OBJECT";
case PARRAY:
return ilk ? "proplist" : "PARRAY";
case PICTUREREF:
return ilk ? "picture" : "PICTUREREF";
case POINT:
return ilk ? "point" : "POINT";
case PROPREF:
@ -1267,6 +1275,8 @@ int Datum::equalTo(Datum &d, bool ignoreCase) const {
return u.obj == d.u.obj;
case CASTREF:
return *u.cast == *d.u.cast;
case PICTUREREF:
return 0; // Original always returns 0 on picture reference comparison
default:
break;
}

View File

@ -41,6 +41,7 @@ namespace Director {
struct ChunkReference;
struct MenuReference;
struct PictureReference;
struct TheEntity;
struct TheEntityField;
struct LingoArchive;
@ -144,6 +145,7 @@ struct Datum { /* interpreter stack type */
ChunkReference *cref; /* CHUNKREF */
CastMemberID *cast; /* CASTREF, FIELDREF */
MenuReference *menu; /* MENUREF */
PictureReference *picture; /* PICTUREREF */
} u;
int *refCount;
@ -209,6 +211,13 @@ struct MenuReference {
MenuReference();
};
struct PictureReference {
Picture *_picture = nullptr;
~PictureReference() {
delete _picture;
}
};
struct PCell {
Datum p;
Datum v;

View File

@ -19,3 +19,8 @@ scummvmAssert("<Object:#FileIO" > 0)
-- Invalid comparisons should return FALSE
scummvmAssert(not (#test <= 0))
-- Picture comparisons are always false, even between the exact same cast.
set a to the picture of cast 1
scummvmAssert(a <> a)
scummvmAssert(a <> the picture of cast 1) -- always false

View File

@ -357,6 +357,7 @@ enum DatumType {
MENUREF,
OBJECT,
PARRAY,
PICTUREREF,
POINT,
PROPREF,
RECT,