DIRECTOR: LINGO: Implement chunk ref properties

This commit is contained in:
djsrv 2021-06-28 19:29:03 -04:00
parent 21988c77bf
commit 22f9d6e589
6 changed files with 204 additions and 0 deletions

View File

@ -233,6 +233,10 @@ public:
Datum getField(int field) override;
bool setField(int field, const Datum &value) override;
bool hasChunkField(int field);
Datum getChunkField(int field, int start, int end);
bool setChunkField(int field, int start, int end, const Datum &value);
SizeType _borderSize;
SizeType _gutterSize;
SizeType _boxShadow;

View File

@ -616,6 +616,20 @@ bool LingoCompiler::visitSetNode(SetNode *node) {
if (node->var->type == kTheOfNode) {
TheOfNode *the = static_cast<TheOfNode *>(node->var);
switch (the->obj->type) {
case kChunkExprNode:
{
int fieldId = getTheFieldID(kTheChunk, *the->prop, true);
if (fieldId >= 0) {
COMPILE(node->val);
COMPILE_REF(the->obj);
code1(LC::c_theentityassign);
codeInt(kTheChunk);
codeInt(fieldId);
return true;
}
// fall back to generic object
}
break;
case kFuncNode:
{
FuncNode *func = static_cast<FuncNode *>(the->obj);
@ -1206,6 +1220,19 @@ bool LingoCompiler::visitTheNode(TheNode *node) {
bool LingoCompiler::visitTheOfNode(TheOfNode *node) {
switch (node->obj->type) {
case kChunkExprNode:
{
int fieldId = getTheFieldID(kTheChunk, *node->prop, true);
if (fieldId >= 0) {
COMPILE_REF(node->obj);
code1(LC::c_theentitypush);
codeInt(kTheChunk);
codeInt(fieldId);
return true;
}
// fall back to generic object
}
break;
case kFuncNode:
{
FuncNode *func = static_cast<FuncNode *>(node->obj);

View File

@ -979,4 +979,68 @@ bool TextCastMember::setField(int field, const Datum &d) {
return CastMember::setField(field, d);
}
bool TextCastMember::hasChunkField(int field) {
switch (field) {
case kTheForeColor:
case kTheTextFont:
case kTheTextHeight:
case kTheTextSize:
case kTheTextStyle:
return true;
default:
break;
}
return false;
}
Datum TextCastMember::getChunkField(int field, int start, int end) {
Datum d;
switch (field) {
case kTheForeColor:
warning("TextCastMember::getChunkField(): Unprocessed getting field \"%s\" of field %d", g_lingo->field2str(field), _castId);
break;
case kTheTextFont:
warning("TextCastMember::getChunkField(): Unprocessed getting field \"%s\" of field %d", g_lingo->field2str(field), _castId);
break;
case kTheTextHeight:
warning("TextCastMember::getChunkField(): Unprocessed getting field \"%s\" of field %d", g_lingo->field2str(field), _castId);
break;
case kTheTextSize:
warning("TextCastMember::getChunkField(): Unprocessed getting field \"%s\" of field %d", g_lingo->field2str(field), _castId);
break;
case kTheTextStyle:
warning("TextCastMember::getChunkField(): Unprocessed getting field \"%s\" of field %d", g_lingo->field2str(field), _castId);
break;
default:
break;
}
return d;
}
bool TextCastMember::setChunkField(int field, int start, int end, const Datum &d) {
switch (field) {
case kTheForeColor:
warning("TextCastMember::setChunkField(): Unprocessed setting field \"%s\" of field %d", g_lingo->field2str(field), _castId);
return false;
case kTheTextFont:
warning("TextCastMember::setChunkField(): Unprocessed setting field \"%s\" of field %d", g_lingo->field2str(field), _castId);
return false;
case kTheTextHeight:
warning("TextCastMember::setChunkField(): Unprocessed setting field \"%s\" of field %d", g_lingo->field2str(field), _castId);
return false;
case kTheTextSize:
warning("TextCastMember::setChunkField(): Unprocessed setting field \"%s\" of field %d", g_lingo->field2str(field), _castId);
return false;
case kTheTextStyle:
warning("TextCastMember::setChunkField(): Unprocessed setting field \"%s\" of field %d", g_lingo->field2str(field), _castId);
return false;
default:
break;
}
return false;
}
} // End of namespace Director

View File

@ -50,6 +50,7 @@ TheEntity entities[] = {
{ kTheCenterStage, "centerStage", false, 200, false }, // D2 p
{ kTheCheckBoxAccess, "checkBoxAccess", false, 200, false }, // D2 p
{ kTheCheckBoxType, "checkBoxType", false, 200, false }, // D2 p
{ kTheChunk, "chunk", true, 300, false }, // D3
{ kTheClickLoc, "clickLoc", false, 400, true }, // D4 function
{ kTheClickOn, "clickOn", false, 200, true }, // D2 f
{ kTheColorDepth, "colorDepth", false, 200, false }, // D2 p
@ -248,6 +249,13 @@ TheEntityField fields[] = {
{ kTheField, "textSize", kTheTextSize, 300 },// D3 p
{ kTheField, "textStyle", kTheTextStyle, 300 },// D3 p
// Chunk fields
{ kTheChunk, "foreColor", kTheForeColor, 400 },// D4 p
{ kTheChunk, "textFont", kTheTextFont, 300 },// D3 p
{ kTheChunk, "textHeight", kTheTextHeight, 300 },// D3 p
{ kTheChunk, "textSize", kTheTextSize, 300 },// D3 p
{ kTheChunk, "textStyle", kTheTextStyle, 300 },// D3 p
{ kTheWindow, "drawRect", kTheDrawRect, 400 },// D4 p
{ kTheWindow, "fileName", kTheFileName, 400 },// D4 p
{ kTheWindow, "modal", kTheModal, 400 },// D4 p
@ -391,6 +399,9 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
d.type = INT;
d.u.i = g_director->getCurrentMovie()->_checkBoxType;
break;
case kTheChunk:
d = getTheChunk(id, field);
break;
case kTheClickLoc:
d.u.farr = new DatumArray;
@ -887,6 +898,9 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
case kTheCheckBoxType:
g_director->getCurrentMovie()->_checkBoxType = d.asInt();
break;
case kTheChunk:
setTheChunk(id, field, d);
break;
case kTheColorDepth:
_vm->_colorDepth = d.asInt();
@ -1597,6 +1611,98 @@ void Lingo::setTheField(Datum &id1, int field, Datum &d) {
member->setField(field, d);
}
Datum Lingo::getTheChunk(Datum &chunk, int field) {
Datum d;
Movie *movie = _vm->getCurrentMovie();
if (!movie) {
warning("Lingo::getTheChunk(): No movie loaded");
return d;
}
if (chunk.type != CHUNKREF) {
warning("BUILDBOT: Lingo::getTheChunk(): bad chunk ref type: %s", chunk.type2str());
return d;
}
int start, end;
start = chunk.u.cref->start;
end = chunk.u.cref->end;
Datum src = chunk.u.cref->source;
while (src.type == CHUNKREF) {
start += src.u.cref->start;
end += src.u.cref->start;
src = src.u.cref->source;
}
if (!src.isCastRef()) {
warning("BUILDBOT: Lingo::getTheChunk(): bad chunk ref field type: %s", src.type2str());
return d;
}
CastMember *member = movie->getCastMember(src.u.i);
if (!member) {
g_lingo->lingoError("Lingo::getTheChunk(): CastMember %d not found", src.u.i);
return d;
}
if (member->_type != kCastText) {
g_lingo->lingoError("Lingo::getTheChunk(): CastMember %d is not a field", src.u.i);
return d;
}
if (!((TextCastMember *)member)->hasChunkField(field)) {
warning("Lingo::getTheChunk(): CastMember %d has no chunk property '%s'", src.u.i, field2str(field));
return d;
}
d = ((TextCastMember *)member)->getChunkField(field, start, end);
return d;
}
void Lingo::setTheChunk(Datum &chunk, int field, Datum &d) {
Movie *movie = _vm->getCurrentMovie();
if (!movie) {
warning("Lingo::setTheChunk(): No movie loaded");
return;
}
if (chunk.type != CHUNKREF) {
warning("BUILDBOT: Lingo::setTheChunk(): bad chunk ref type: %s", chunk.type2str());
return;
}
int start, end;
start = chunk.u.cref->start;
end = chunk.u.cref->end;
Datum src = chunk.u.cref->source;
while (src.type == CHUNKREF) {
start += src.u.cref->start;
end += src.u.cref->start;
src = src.u.cref->source;
}
if (!src.isCastRef()) {
warning("BUILDBOT: Lingo::setTheChunk(): bad chunk ref field type: %s", src.type2str());
return;
}
CastMember *member = movie->getCastMember(src.u.i);
if (!member) {
g_lingo->lingoError("Lingo::setTheChunk(): CastMember %d not found", src.u.i);
return;
}
if (member->_type != kCastText) {
g_lingo->lingoError("Lingo::setTheChunk(): CastMember %d is not a field", src.u.i);
return;
}
if (!((TextCastMember *)member)->hasChunkField(field)) {
warning("Lingo::setTheChunk(): CastMember %d has no chunk property '%s'", src.u.i, field2str(field));
return;
}
((TextCastMember *)member)->setChunkField(field, start, end, d);
}
void Lingo::getObjectProp(Datum &obj, Common::String &propName) {
Datum d;
if (obj.type == OBJECT) {

View File

@ -37,6 +37,7 @@ enum TheEntityType {
kTheChars,
kTheCheckBoxAccess,
kTheCheckBoxType,
kTheChunk,
kTheClickLoc,
kTheClickOn,
kTheColorDepth,

View File

@ -336,6 +336,8 @@ public:
void setTheCast(Datum &id, int field, Datum &d);
Datum getTheField(Datum &id1, int field);
void setTheField(Datum &id1, int field, Datum &d);
Datum getTheChunk(Datum &chunk, int field);
void setTheChunk(Datum &chunk, int field, Datum &d);
void getObjectProp(Datum &obj, Common::String &propName);
void setObjectProp(Datum &obj, Common::String &propName, Datum &d);
Datum getTheDate(int field);