From a45da2eb03139d48b98f3f520cfdf23b164a77c1 Mon Sep 17 00:00:00 2001 From: Scott Percival Date: Fri, 29 Nov 2019 23:31:13 +0800 Subject: DIRECTOR: Add c_constpush --- engines/director/lingo/lingo-bytecode.cpp | 61 ++++++++++++++++++++----------- engines/director/lingo/lingo-code.cpp | 9 +++++ engines/director/lingo/lingo.h | 2 + 3 files changed, 50 insertions(+), 22 deletions(-) (limited to 'engines/director') diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp index ae008e03b3..6155c3d2b4 100644 --- a/engines/director/lingo/lingo-bytecode.cpp +++ b/engines/director/lingo/lingo-bytecode.cpp @@ -56,12 +56,14 @@ static LingoV4Bytecode lingoV4[] = { { 0x41, Lingo::c_intpush, "b" }, { 0x42, Lingo::c_argspush, "b" }, { 0x43, Lingo::c_arraypush, "b" }, + { 0x44, Lingo::c_constpush, "bv" }, { 0x45, Lingo::c_symbolpush, "b" }, { 0x5c, Lingo::c_v4theentitypush, "b" }, { 0x5d, Lingo::c_v4theentityassign, "b" }, { 0x81, Lingo::c_intpush, "w" }, { 0x82, Lingo::c_argspush, "w" }, { 0x83, Lingo::c_arraypush, "w" }, + { 0x84, Lingo::c_constpush, "wv" }, { 0, 0, 0 } }; @@ -185,6 +187,7 @@ void Lingo::c_v4theentitypush() { if (firstArg.type == INT) { int key = (bank << 8) + firstArg.u.i; if (g_lingo->_lingoV4TheEntity.contains(key)) { + debugC(3, kDebugLingoExec, "c_v4theentitypush: mapping 0x%02x, 0x%02x", bank, firstArg.u.i); int entity = g_lingo->_lingoV4TheEntity[key]->entity; int field = g_lingo->_lingoV4TheEntity[key]->field; switch (g_lingo->_lingoV4TheEntity[key]->type) { @@ -193,26 +196,28 @@ void Lingo::c_v4theentitypush() { Datum id; id.u.s = NULL; id.type = VOID; + debugC(3, kDebugLingoExec, "c_v4theentitypush: calling getTheEntity(0x%02x, NULL, 0x%02x)", entity, field); result = g_lingo->getTheEntity(entity, id, field); } break; case kTEAItemId: { Datum id = g_lingo->pop(); + debugC(3, kDebugLingoExec, "c_v4theentitypush: calling getTheEntity(0x%02x, id, 0x%02x)", entity, field); result = g_lingo->getTheEntity(entity, id, field); } break; case kTEAString: { /*Datum stringArg = */g_lingo->pop(); - warning("c_v4theentitypush: STUB: mapping 0x%02x 0x%02x kTEAString", bank, firstArg.u.i); + warning("c_v4theentitypush: STUB: kTEAString"); } break; case kTEAMenuIdItemId: { /*Datum menuId = */g_lingo->pop(); /*Datum itemId = */g_lingo->pop(); - warning("c_v4theentitypush: STUB: mapping 0x%02x 0x%02x kTEAMenuIdItemId", bank, firstArg.u.i); + warning("c_v4theentitypush: STUB: kTEAMenuIdItemId"); } break; default: @@ -244,6 +249,7 @@ void Lingo::c_v4theentityassign() { if (firstArg.type == INT) { int key = (bank << 8) + firstArg.u.i; if (g_lingo->_lingoV4TheEntity.contains(key)) { + debugC(3, kDebugLingoExec, "c_v4theentityassign: mapping 0x%02x, 0x%02x", bank, firstArg.u.i); if (g_lingo->_lingoV4TheEntity[key]->writable) { int entity = g_lingo->_lingoV4TheEntity[key]->entity; int field = g_lingo->_lingoV4TheEntity[key]->field; @@ -253,26 +259,28 @@ void Lingo::c_v4theentityassign() { Datum id; id.u.s = NULL; id.type = VOID; + debugC(3, kDebugLingoExec, "c_v4theentityassign: calling setTheEntity(0x%02x, NULL, 0x%02x, value)", entity, field); g_lingo->setTheEntity(entity, id, field, value); } break; case kTEAItemId: { Datum id = g_lingo->pop(); + debugC(3, kDebugLingoExec, "c_v4theentityassign: calling setTheEntity(0x%02x, id, 0x%02x, value)", entity, field); g_lingo->setTheEntity(entity, id, field, value); } break; case kTEAString: { /*Datum stringArg = */g_lingo->pop(); - warning("c_v4theentityassign: STUB: mapping 0x%02x 0x%02x kTEAString", bank, firstArg.u.i); + warning("c_v4theentityassign: STUB: kTEAString"); } break; case kTEAMenuIdItemId: { /*Datum menuId = */g_lingo->pop(); /*Datum itemId = */g_lingo->pop(); - warning("c_v4theentityassign: STUB: mapping 0x%02x 0x%02x kTEAMenuIdItemId", bank, firstArg.u.i); + warning("c_v4theentityassign: STUB: kTEAMenuIdItemId"); } break; default: @@ -355,8 +363,6 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty byte *constsStore = (byte *)malloc(constsStoreSize); stream.read(constsStore, constsStoreSize); - Common::Array constsData; - // read each entry in the reference table. stream.seek(constsOffset); for (uint16 i = 0; i < constsCount; i++) { @@ -412,7 +418,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty break; } - constsData.push_back(constant); + _currentScriptContext->constants.push_back(constant); } free(constsStore); @@ -477,23 +483,34 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty if (_lingoV4.contains(opcode)) { offsetList.push_back(_currentScript->size()); g_lingo->code1(_lingoV4[opcode]->func); + size_t argc = strlen(_lingoV4[opcode]->proto); - for (uint c = 0; c < argc; c++) { - switch (_lingoV4[opcode]->proto[c]) { - case 'b': - offsetList.push_back(_currentScript->size()); - g_lingo->codeInt((int8)codeStore[pointer]); - pointer += 1; - break; - case 'w': - offsetList.push_back(_currentScript->size()); - offsetList.push_back(_currentScript->size()); - g_lingo->codeInt((int16)READ_UINT16(&codeStore[pointer])); - pointer += 2; - break; - default: - break; + if (argc) { + int arg = 0; + for (uint c = 0; c < argc; c++) { + switch (_lingoV4[opcode]->proto[c]) { + case 'b': + offsetList.push_back(_currentScript->size()); + arg = (int8)codeStore[pointer]; + pointer += 1; + break; + case 'w': + offsetList.push_back(_currentScript->size()); + offsetList.push_back(_currentScript->size()); + arg = (int16)READ_UINT16(&codeStore[pointer]); + pointer += 2; + break; + case 'v': + if (arg % 6) { + warning("Opcode 0x%02x arg %d not multiple of 6!", opcode, arg); + } + arg /= 6; + break; + default: + break; + } } + g_lingo->codeInt(arg); } } else { // unimplemented instruction diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp index 5bab70c543..ff9ae2428a 100644 --- a/engines/director/lingo/lingo-code.cpp +++ b/engines/director/lingo/lingo-code.cpp @@ -65,6 +65,7 @@ static struct FuncDescr { { Lingo::c_floatpush, "c_floatpush", "f" }, { Lingo::c_stringpush, "c_stringpush", "s" }, { Lingo::c_symbolpush, "c_symbolpush", "s" }, // D3 + { Lingo::c_constpush, "c_constpush", "i" }, { Lingo::c_varpush, "c_varpush", "s" }, { Lingo::c_setImmediate,"c_setImmediate","i" }, { Lingo::c_assign, "c_assign", "" }, @@ -249,6 +250,14 @@ void Lingo::c_symbolpush() { g_lingo->push(Datum(new Common::String(s))); } +void Lingo::c_constpush() { + Datum d; + inst in = (*g_lingo->_currentScript)[g_lingo->_pc++]; + int i = READ_UINT32(&in); + d = g_lingo->_currentScriptContext->constants[i]; + g_lingo->push(d); +} + void Lingo::c_argspush() { Datum d; inst v = (*g_lingo->_currentScript)[g_lingo->_pc++]; diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h index 1d4e8cf118..e4f8a5968f 100644 --- a/engines/director/lingo/lingo.h +++ b/engines/director/lingo/lingo.h @@ -143,6 +143,7 @@ struct Builtin { struct ScriptContext { Common::Array functions; + Common::Array constants; }; typedef Common::HashMap ScriptContextHash; @@ -278,6 +279,7 @@ public: static void c_floatpush(); static void c_stringpush(); static void c_symbolpush(); + static void c_constpush(); static void c_varpush(); static void c_argspush(); static void c_arraypush(); -- cgit v1.2.3