[Scummvm-git-logs] scummvm master -> ab09750ac95d7c91574196627aa9dd7b66956548
moralrecordings
code at moral.net.au
Sat Feb 8 06:53:03 UTC 2020
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
42462f1e11 DIRECTOR: LINGO: Add opcode stubs, decouple script context fetching
31c8e09540 DIRECTOR: LINGO: Fix argument order of c_of
f08d512bff DIRECTOR: LINGO: Set range of b_random(i) as [1, i]
ab09750ac9 DIRECTOR: LINGO: Partial implementation of c_of
Commit: 42462f1e11d33346be5b9808dd3b23e3fbf44aa2
https://github.com/scummvm/scummvm/commit/42462f1e11d33346be5b9808dd3b23e3fbf44aa2
Author: Scott Percival (code at moral.net.au)
Date: 2020-02-08T14:50:05+08:00
Commit Message:
DIRECTOR: LINGO: Add opcode stubs, decouple script context fetching
Changed paths:
engines/director/lingo/lingo-bytecode.cpp
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo-code.h
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 0e1b704..2d420f0 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -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;
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 50a6fdf..0735031 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -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" },
diff --git a/engines/director/lingo/lingo-code.h b/engines/director/lingo/lingo-code.h
index 23dff63..6256fa8 100644
--- a/engines/director/lingo/lingo-code.h
+++ b/engines/director/lingo/lingo-code.h
@@ -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();
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 8f66ff9..13e5c3a 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -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;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 2f9dfd0..ab6e681 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -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);
Commit: 31c8e0954068aead43eae2bd415a3777e318ee33
https://github.com/scummvm/scummvm/commit/31c8e0954068aead43eae2bd415a3777e318ee33
Author: Scott Percival (code at moral.net.au)
Date: 2020-02-08T14:50:05+08:00
Commit Message:
DIRECTOR: LINGO: Fix argument order of c_of
Changed paths:
engines/director/lingo/lingo-code.cpp
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 0735031..888677c 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -665,15 +665,15 @@ void LC::c_within() {
}
void LC::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();
+ Datum last_line = g_lingo->pop();
+ Datum first_line = g_lingo->pop();
+ Datum last_item = g_lingo->pop();
+ Datum first_item = g_lingo->pop();
+ Datum last_word = g_lingo->pop();
+ Datum first_word = g_lingo->pop();
+ Datum last_char = g_lingo->pop();
+ Datum first_char = 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,
Commit: f08d512bff10caf50190b01c09200746280f164a
https://github.com/scummvm/scummvm/commit/f08d512bff10caf50190b01c09200746280f164a
Author: Scott Percival (code at moral.net.au)
Date: 2020-02-08T14:50:05+08:00
Commit Message:
DIRECTOR: LINGO: Set range of b_random(i) as [1, i]
Changed paths:
engines/director/lingo/lingo-builtins.cpp
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 7c66d57..7635bf9 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -408,7 +408,7 @@ void LB::b_random(int nargs) {
max.toInt();
- res.u.i = g_lingo->_vm->_rnd.getRandomNumber(max.u.i);
+ res.u.i = g_lingo->_vm->_rnd.getRandomNumber(max.u.i - 1) + 1;
res.type = INT;
g_lingo->push(res);
Commit: ab09750ac95d7c91574196627aa9dd7b66956548
https://github.com/scummvm/scummvm/commit/ab09750ac95d7c91574196627aa9dd7b66956548
Author: Scott Percival (code at moral.net.au)
Date: 2020-02-08T14:50:05+08:00
Commit Message:
DIRECTOR: LINGO: Partial implementation of c_of
Changed paths:
engines/director/lingo/lingo-code.cpp
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 888677c..055a152 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -567,11 +567,11 @@ void LC::c_ampersand() {
g_lingo->push(d1);
}
-void LC::c_after() {
+void LC::c_before() {
LC::c_ampersand();
}
-void LC::c_before() {
+void LC::c_after() {
Datum d2 = g_lingo->pop();
Datum d1 = g_lingo->pop();
@@ -665,6 +665,7 @@ void LC::c_within() {
}
void LC::c_of() {
+ // put char 5 of word 1 of line 2 into field "thing"
Datum target = g_lingo->pop();
Datum last_line = g_lingo->pop();
Datum first_line = g_lingo->pop();
@@ -675,13 +676,111 @@ void LC::c_of() {
Datum last_char = g_lingo->pop();
Datum first_char = 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());
+ target.toString();
+ Common::String result = *target.u.s;
+
+ if (first_line.u.i > 0) {
+ Common::String newline("\r");
+ int first = first_line.u.i;
+ int last = first;
+ if (last_line.u.i > 0) {
+ if ((first_item.u.i > 0) || (first_word.u.i > 0) || (first_char.u.i > 0)) {
+ warning("c_of: last_line defined but unused");
+ } else if (last_line.u.i < first_line.u.i) {
+ warning("c_of: last_line before first_line, ignoring");
+ } else {
+ last = last_line.u.i;
+ }
+ }
+ uint32 pointer = 0;
+ int curLine = 0;
+ int firstIndex = -1;
+ int lastIndex = -1;
+ while (pointer < result.size()) {
+ curLine += 1;
+ if (curLine == first) {
+ firstIndex = pointer;
+ }
+ pointer = result.find(newline, pointer);
+ if (curLine == last) {
+ lastIndex = pointer;
+ break;
+ }
+ }
+ if (firstIndex < 0) {
+ warning("c_of: first_line out of range");
+ result = "";
+ } else {
+ result = result.substr(firstIndex, lastIndex);
+ }
+ }
- g_lingo->push(target);
+ if (first_item.u.i > 0) {
+ warning("STUB: c_of item indexing");
+ }
+ if (first_word.u.i > 0) {
+ int first = first_word.u.i;
+ int last = first;
+ if (last_word.u.i > 0) {
+ if (first_char.u.i > 0) {
+ warning("c_of: last_word defined but unused");
+ } else if (last_word.u.i < first_word.u.i) {
+ warning("c_of: last_word before first_word, ignoring");
+ } else {
+ last = last_word.u.i;
+ }
+ }
+ uint32 pointer = 0;
+ int curWord = 0;
+ int firstIndex = -1;
+ int lastIndex = -1;
+ bool inWord = false;
+ while (pointer < result.size()) {
+ if ((result[pointer] == '\r') || (result[pointer] == '\t') ||
+ (result[pointer] == '\n') || (result[pointer] == ' ')) {
+ if (inWord) {
+ inWord = false;
+ if (last == curWord) {
+ break;
+ }
+ }
+ } else {
+ if (!inWord) {
+ inWord = true;
+ curWord += 1;
+ if (first == curWord) {
+ firstIndex = pointer;
+ }
+ }
+ }
+ pointer += 1;
+ }
+ lastIndex = pointer;
+ if (firstIndex < 0) {
+ warning("c_of: first_word out of range");
+ result = "";
+ } else {
+ result = result.substr(firstIndex, lastIndex - firstIndex);
+ }
+ }
+
+ if (first_char.u.i > 0) {
+ int first = first_char.u.i;
+ int last = first;
+ if (last_char.u.i > 0) {
+ if (last_char.u.i < first_char.u.i) {
+ warning("c_of: last_char before first_char, ignoring");
+ } else {
+ last = last_char.u.i;
+ }
+ }
+ result = result.substr(first - 1, last - first);
+ }
+
+ *target.u.s = result;
+
+ g_lingo->push(target);
}
void LC::c_charOf() {
More information about the Scummvm-git-logs
mailing list