diff options
author | Scott Percival | 2019-08-18 21:37:05 +0800 |
---|---|---|
committer | Eugene Sandulenko | 2019-11-17 22:31:54 +0100 |
commit | ffde055357416ee9d7704dbe22004a54090fe1fb (patch) | |
tree | ebed2db52522bac624dcc6b35e1535e4fb2870af /engines/director | |
parent | 3034fda611e75a5dc9410a82aadc2398ef2fbce3 (diff) | |
download | scummvm-rg350-ffde055357416ee9d7704dbe22004a54090fe1fb.tar.gz scummvm-rg350-ffde055357416ee9d7704dbe22004a54090fe1fb.tar.bz2 scummvm-rg350-ffde055357416ee9d7704dbe22004a54090fe1fb.zip |
DIRECTOR: begin interpreter for Lingo V4 bytecode
Diffstat (limited to 'engines/director')
-rw-r--r-- | engines/director/lingo/lingo-bytecode.cpp | 96 | ||||
-rw-r--r-- | engines/director/lingo/lingo-bytecode.h | 0 | ||||
-rw-r--r-- | engines/director/lingo/lingo-code.cpp | 61 | ||||
-rw-r--r-- | engines/director/lingo/lingo.h | 6 | ||||
-rw-r--r-- | engines/director/module.mk | 1 | ||||
-rw-r--r-- | engines/director/score.cpp | 24 | ||||
-rw-r--r-- | engines/director/score.h | 1 |
7 files changed, 188 insertions, 1 deletions
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp new file mode 100644 index 0000000000..f19ebb7768 --- /dev/null +++ b/engines/director/lingo/lingo-bytecode.cpp @@ -0,0 +1,96 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "director/lingo/lingo.h" + +namespace Director { + +static struct LingoV4Bytecode { + const char opcode; + const inst func; +} lingoV4[] = { + { 0x03, Lingo::c_voidpush }, + { 0x04, Lingo::c_mul }, + { 0x05, Lingo::c_add }, + { 0x06, Lingo::c_sub }, + { 0x07, Lingo::c_div }, + { 0x08, Lingo::c_mod }, + { 0x09, Lingo::c_negate }, + { 0x0a, Lingo::c_ampersand }, + { 0x0b, Lingo::c_concat }, + { 0x0c, Lingo::c_lt }, + { 0x0d, Lingo::c_le }, + { 0x0e, Lingo::c_neq }, + { 0x0f, Lingo::c_eq }, + { 0x10, Lingo::c_gt }, + { 0x11, Lingo::c_ge }, + { 0x12, Lingo::c_and }, + { 0x13, Lingo::c_or }, + { 0x14, Lingo::c_not }, + { 0x15, Lingo::c_contains }, + { 0x16, Lingo::c_starts }, + { 0x17, Lingo::c_of }, + { 0x18, Lingo::c_hilite }, + { 0x19, Lingo::c_intersects }, + { 0x1a, Lingo::c_within }, + { 0x1b, Lingo::c_field }, + { 0x1c, Lingo::c_tell }, + { 0x1d, Lingo::c_telldone }, + + { 0x41, Lingo::c_intpush }, + { 0, 0 } +}; + + +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); + + // unk1 + for (uint32 i = 0; i < 0x10; i++) { + stream.readByte(); + } + uint16 code_store_offset = stream.readUint16(); + // unk2 + for (uint32 i = 0; i < 0x2e; i++) { + stream.readByte(); + } + uint16 functions_offset = stream.readUint16(); + // unk3 + for (uint32 i = 0; i < 0x6; i++) { + stream.readByte(); + } + uint16 functions_count = stream.readUint16(); + uint16 unk4 = stream.readUint16(); + uint16 unk5 = stream.readUint16(); + uint16 consts_count = stream.readUint16(); + stream.readUint16(); + uint16 consts_offset = stream.readUint16(); + stream.readUint16(); + uint16 unk6 = stream.readUint16(); + stream.readUint16(); + uint16 consts_base = stream.readUint16(); + + // preload all the constants + stream.seek(consts_offset); +} + +} diff --git a/engines/director/lingo/lingo-bytecode.h b/engines/director/lingo/lingo-bytecode.h new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/engines/director/lingo/lingo-bytecode.h diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp index b2733f23b7..85b50cd8ea 100644 --- a/engines/director/lingo/lingo-code.cpp +++ b/engines/director/lingo/lingo-code.cpp @@ -85,6 +85,8 @@ static struct FuncDescr { { Lingo::c_starts, "c_starts", "" }, { Lingo::c_intersects, "c_intersects", "" }, { Lingo::c_within, "c_within", "" }, + { Lingo::c_field, "c_field", "" }, + { Lingo::c_of, "c_of", "" }, // D9 { Lingo::c_charOf, "c_charOf", "" }, // D3 { Lingo::c_charToOf, "c_charToOf", "" }, // D3 { Lingo::c_itemOf, "c_itemOf", "" }, // D3 @@ -107,6 +109,8 @@ static struct FuncDescr { { Lingo::c_exitRepeat, "c_exitRepeat", "" }, { Lingo::c_ifcode, "c_ifcode", "oooi" }, { Lingo::c_tellcode, "c_tellcode", "o" }, + { Lingo::c_tell, "c_tell", "" }, + { Lingo::c_telldone, "c_telldone", "" }, { Lingo::c_whencode, "c_whencode", "os" }, { Lingo::c_goto, "c_goto", "" }, { Lingo::c_gotoloop, "c_gotoloop", "" }, @@ -120,6 +124,7 @@ static struct FuncDescr { { Lingo::c_property, "c_property", "s" }, { Lingo::c_instance, "c_instance", "s" }, { Lingo::c_open, "c_open", "" }, + { Lingo::c_hilite, "c_hilite", "" }, { 0, 0, 0 } }; @@ -243,7 +248,7 @@ void Lingo::c_arraypush() { Datum d; inst v = (*g_lingo->_currentScript)[g_lingo->_pc++]; int arraySize = READ_UINT32(&v); -` + warning("STUB: c_arraypush()"); for (int i = 0; i < arraySize; i++) @@ -640,6 +645,34 @@ void Lingo::c_within() { g_lingo->push(d1); } +void Lingo::c_field() { + Datum d1 = g_lingo->pop(); + + warning("STUB: c_field: %d", d1.u.i); + + g_lingo->push(d1); +} + +void Lingo::c_of() { + Datum first_char = g_lingo->pop(); + Datum last_char = g_lingo->pop(); + Datum first_word = g_lingo->pop(); + Datum last_word = g_lingo->pop(); + Datum first_item = g_lingo->pop(); + Datum last_item = g_lingo->pop(); + Datum first_line = g_lingo->pop(); + Datum last_line = g_lingo->pop(); + Datum target = g_lingo->pop(); + + warning("STUB: c_of: %d %d %d %d %d %d %d %d %s", + first_char.u.i, last_char.u.i, first_word.u.i, last_word.u.i, + first_item.u.i, last_item.u.i, first_line.u.i, last_line.u.i, + target.u.s->c_str()); + + g_lingo->push(target); + +} + void Lingo::c_charOf() { Datum d2 = g_lingo->pop(); Datum d1 = g_lingo->pop(); @@ -969,6 +1002,15 @@ void Lingo::c_tellcode() { warning("STUB: c_tellcode"); } +void Lingo::c_tell() { + Datum d1 = g_lingo->pop(); + warning("STUB: c_tell %d", d1.u.i); +} + +void Lingo::c_telldone() { + warning("STUB: c_telldone"); +} + //************************ // Built-in functions @@ -1187,4 +1229,21 @@ void Lingo::c_open() { warning("STUB: c_open(%s, %s)", d1.u.s->c_str(), d2.u.s->c_str()); } +void Lingo::c_hilite() { + Datum first_char = g_lingo->pop(); + Datum last_char = g_lingo->pop(); + Datum first_word = g_lingo->pop(); + Datum last_word = g_lingo->pop(); + Datum first_item = g_lingo->pop(); + Datum last_item = g_lingo->pop(); + Datum first_line = g_lingo->pop(); + Datum last_line = g_lingo->pop(); + Datum cast_id = g_lingo->pop(); + + warning("STUB: c_hilite: %d %d %d %d %d %d %d %d %d", + first_char.u.i, last_char.u.i, first_word.u.i, last_word.u.i, + first_item.u.i, last_item.u.i, first_line.u.i, last_line.u.i, + cast_id.u.i); +} + } diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h index bc6a6a1af6..e1a165796e 100644 --- a/engines/director/lingo/lingo.h +++ b/engines/director/lingo/lingo.h @@ -163,6 +163,7 @@ public: void restartLingo(); void addCode(const char *code, ScriptType type, uint16 id); + void addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType type, uint16 id); void executeScript(ScriptType type, uint16 id); void printStack(const char *s); Common::String decodeInstruction(uint pc, uint *newPC = NULL); @@ -252,6 +253,8 @@ public: static void c_intersects(); static void c_within(); + static void c_field(); + static void c_of(); static void c_charOf(); static void c_charToOf(); static void c_itemOf(); @@ -283,6 +286,8 @@ public: static void c_ifcode(); static void c_whencode(); static void c_tellcode(); + static void c_tell(); + static void c_telldone(); static void c_exitRepeat(); static void c_eq(); static void c_neq(); @@ -310,6 +315,7 @@ public: static void c_playdone(); static void c_open(); + static void c_hilite(); void printSTUBWithArglist(const char *funcname, int nargs, const char *prefix = "STUB:"); void convertVOIDtoString(int arg, int nargs); diff --git a/engines/director/module.mk b/engines/director/module.mk index 73f4a4ed7c..e445e576f4 100644 --- a/engines/director/module.mk +++ b/engines/director/module.mk @@ -20,6 +20,7 @@ MODULE_OBJS = \ lingo/lingo-gr.o \ lingo/lingo.o \ lingo/lingo-builtins.o \ + lingo/lingo-bytecode.o \ lingo/lingo-code.o \ lingo/lingo-codegen.o \ lingo/lingo-events.o \ diff --git a/engines/director/score.cpp b/engines/director/score.cpp index 19128ab414..e9f49336d9 100644 --- a/engines/director/score.cpp +++ b/engines/director/score.cpp @@ -180,6 +180,19 @@ void Score::loadArchive() { setSpriteCasts(); loadSpriteImages(false); + // Try to load compiled Lingo scripts + if (_vm->getVersion() == 4) { + Common::Array<uint16> lscr = _movieArchive->getResourceIDList(MKTAG('L','s','c','r')); + if (lscr.size() > 0) { + debugC(2, kDebugLoading, "****** Loading %d Lscr resources", lscr.size()); + + for (Common::Array<uint16>::iterator iterator = lscr.begin(); iterator != lscr.end(); ++iterator) { + loadLingoScript(*_movieArchive->getResource(MKTAG('L','s','c','r'), *iterator)); + } + } + + } + // Try to load movie script, it sits in resource A11 if (_vm->getVersion() <= 3) { Common::Array<uint16> stxt = _movieArchive->getResourceIDList(MKTAG('S','T','X','T')); @@ -872,6 +885,17 @@ bool Score::processImmediateFrameScript(Common::String s, int id) { return false; } +void Score::loadLingoScript(Common::SeekableSubReadStreamEndian &stream) { + if (_vm->getVersion() == 4) { + + _lingo->addCodeV4(stream, kMovieScript, _movieScriptCount); + + } else { + error("Score::loadLingoScript: unsuported Director version (%d)", _vm->getVersion()); + } + _movieScriptCount++; +} + void Score::loadScriptText(Common::SeekableSubReadStreamEndian &stream) { /*uint32 unk1 = */ stream.readUint32(); uint32 strLen = stream.readUint32(); diff --git a/engines/director/score.h b/engines/director/score.h index 40ef85cad0..7c663d559e 100644 --- a/engines/director/score.h +++ b/engines/director/score.h @@ -101,6 +101,7 @@ private: void loadFrames(Common::SeekableSubReadStreamEndian &stream); void loadLabels(Common::SeekableSubReadStreamEndian &stream); void loadActions(Common::SeekableSubReadStreamEndian &stream); + void loadLingoScript(Common::SeekableSubReadStreamEndian &stream); void loadScriptText(Common::SeekableSubReadStreamEndian &stream); void loadFileInfo(Common::SeekableSubReadStreamEndian &stream); void loadFontMap(Common::SeekableSubReadStreamEndian &stream); |