DIRECTOR: LINGO: Add opcode stubs, decouple script context fetching

This commit is contained in:
Scott Percival committed 2020-02-08 14:50:05 +08:00
1 parent 876a515a05
commit 42462f1e11
5 files changed
+68 -13

No files matched your search

+44 -5
View File
@@ -66,6 +66,7 @@ static LingoV4Bytecode lingoV4[] = {
{ 0x43, LC::c_argcpush, "b" },
// 0x44, push a constant
{ 0x45, LC::c_namepush, "b" },
{ 0x46, LC::cb_objectpush, "b" },
{ 0x49, LC::cb_globalpush, "b" },
{ 0x4b, LC::cb_varpush, "bpa" },
{ 0x4c, LC::cb_varpush, "bpv" },
@@ -77,6 +78,7 @@ static LingoV4Bytecode lingoV4[] = {
{ 0x55, LC::c_jumpifz, "jb" },
{ 0x56, LC::cb_localcall, "b" },
{ 0x57, LC::cb_call, "b" },
{ 0x58, LC::cb_methodcall, "b" },
{ 0x59, LC::cb_v4assign, "b" },
{ 0x5c, LC::cb_v4theentitypush, "b" },
{ 0x5d, LC::cb_v4theentityassign, "b" },
@@ -85,6 +87,8 @@ static LingoV4Bytecode lingoV4[] = {
{ 0x82, LC::c_argcnoretpush,"w" },
{ 0x83, LC::c_argcpush, "w" },
// 0x84, push a constant
{ 0x85, LC::c_namepush, "w" },
{ 0x86, LC::cb_objectpush, "w" },
{ 0x89, LC::cb_globalpush, "w" },
{ 0x8b, LC::cb_varpush, "wpa" },
{ 0x8c, LC::cb_varpush, "wpv" },
@@ -94,6 +98,13 @@ static LingoV4Bytecode lingoV4[] = {
{ 0x93, LC::c_jump, "jw" },
{ 0x94, LC::c_jump, "jwn" },
{ 0x95, LC::c_jumpifz, "jw" },
{ 0x96, LC::cb_localcall, "w" },
{ 0x97, LC::cb_call, "w" },
{ 0x98, LC::cb_methodcall, "w" },
{ 0x99, LC::cb_v4assign, "w" },
{ 0x9c, LC::cb_v4theentitypush, "w" },
{ 0x9d, LC::cb_v4theentityassign, "w" },
{ 0xa6, LC::cb_v4theentitynamepush, "w" },
{ 0, 0, 0 }
};
@@ -248,6 +259,24 @@ void LC::cb_localcall() {
}
void LC::cb_methodcall() {
g_lingo->readInt();
Datum obj = g_lingo->pop();
obj.toString();
warning("STUB: cb_methodcall(%s)", obj.u.s->c_str());
Datum nargs = g_lingo->pop();
if ((nargs.type == ARGC) || (nargs.type == ARGCNORET)) {
if (debugChannelSet(3, kDebugLingoExec))
g_lingo->printSTUBWithArglist("", nargs.u.i, "methodcall:");
} else {
warning("cb_methodcall: second arg should be of type ARGC or ARGCNORET, not %s", nargs.type2str());
}
}
void LC::cb_v4assign() {
int op = g_lingo->readInt();
@@ -366,6 +395,16 @@ void LC::cb_globalassign() {
}
void LC::cb_objectpush() {
int nameId = g_lingo->readInt();
Common::String name = g_lingo->_namelist[nameId];
warning("STUB: cb_objectpush(%s)", name.c_str());
Datum result;
result.type = VOID;
g_lingo->push(result);
}
void LC::cb_varpush() {
int nameId = g_lingo->readInt();
Common::String name = g_lingo->_namelist[nameId];
@@ -569,11 +608,11 @@ void LC::cb_zeropush() {
void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType type, uint16 id) {
debugC(1, kDebugLingoCompile, "Add V4 bytecode for type %s with id %d", scriptType2str(type), id);
if (_scriptContexts[type].contains(id)) {
for (size_t j = 0; j < _scriptContexts[type][id]->functions.size(); j++) {
delete _scriptContexts[type][id]->functions[j];
}
delete _scriptContexts[type][id];
if (getScriptContext(type, id)) {
// We can't undefine context data because it could be used in e.g. symbols.
// Abort on double definitions.
error("Script already defined for type %d, id %d", id, type);
return;
}
_currentScriptContext = new ScriptContext;
+2
View File
@@ -144,6 +144,8 @@ static struct FuncDescr {
{ LC::cb_globalpush, "cb_globalpush", "i" },
{ LC::cb_list, "cb_list", "" },
{ LC::cb_localcall, "cb_localcall", "i" },
{ LC::cb_methodcall, "cb_methodcall", "i" },
{ LC::cb_objectpush, "cb_objectpush", "i" },
{ LC::cb_unk, "cb_unk", "i" },
{ LC::cb_unk1, "cb_unk1", "ii" },
{ LC::cb_unk2, "cb_unk2", "iii" },
+2
View File
@@ -137,6 +137,8 @@ namespace LC {
void cb_globalpush();
void cb_list();
void cb_localcall();
void cb_methodcall();
void cb_objectpush();
void cb_varassign();
void cb_varpush();
void cb_v4assign();
+19 -8
View File
@@ -88,6 +88,16 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
Lingo::~Lingo() {
}
ScriptContext *Lingo::getScriptContext(ScriptType type, uint16 id) {
if (type >= (int)_scriptContexts->size()) {
return NULL;
}
if (!_scriptContexts[type].contains(id)) {
return NULL;
}
return _scriptContexts[type][id];
}
const char *Lingo::findNextDefinition(const char *s) {
const char *res = s;
@@ -129,11 +139,11 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
debugC(1, kDebugLingoCompile, "Add code for type %s(%d) with id %d\n"
"***********\n%s\n\n***********", scriptType2str(type), type, id, code);
if (_scriptContexts[type].contains(id)) {
for (size_t j = 0; j < _scriptContexts[type][id]->functions.size(); j++) {
delete _scriptContexts[type][id]->functions[j];
}
delete _scriptContexts[type][id];
if (getScriptContext(type, id)) {
// We can't undefine context data because it could be used in e.g. symbols.
// Abort on double definitions.
error("Script already defined for type %d, id %d", id, type);
return;
}
_currentScriptContext = new ScriptContext;
@@ -224,18 +234,19 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
}
void Lingo::executeScript(ScriptType type, uint16 id, uint16 function) {
if (!_scriptContexts[type].contains(id)) {
ScriptContext *sc = getScriptContext(type, id);
if (!sc) {
debugC(3, kDebugLingoExec, "Request to execute non-existant script type %d id %d", type, id);
return;
}
if (function >= _scriptContexts[type][id]->functions.size()) {
if (function >= sc->functions.size()) {
debugC(3, kDebugLingoExec, "Request to execute non-existant function %d in script type %d id %d", function, type, id);
return;
}
debugC(1, kDebugLingoExec, "Executing script type: %s, id: %d, function: %d", scriptType2str(type), id, function);
_currentScriptContext = _scriptContexts[type][id];
_currentScriptContext = sc;
_currentScript = _currentScriptContext->functions[function]->u.defn;
_pc = 0;
_returning = false;
+1
View File
@@ -182,6 +182,7 @@ private:
void runMovieScript(LEvent event);
void processSpriteEvent(LEvent event);
void processEvent(LEvent event, ScriptType st, int entityId);
ScriptContext *getScriptContext(ScriptType type, uint16 id);
public:
ScriptType event2script(LEvent ev);