mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
DIRECTOR: LINGO: Add opcode stubs, decouple script context fetching
This commit is contained in:
1 parent
876a515a05
commit
42462f1e11
5 files changed
+68
-13
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user