[Scummvm-git-logs] scummvm master -> 87cc5f1c68d3a3fb6fce546e74573e152e451361

sev- sev at scummvm.org
Fri May 22 13:40:09 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:
9eab0eac4c DIRECTOR: LINGO: Track script types and lines in preprocessor
ec85ef99c7 DIRECTOR: Distinguish between GIDs and gameIds
3a0bdfbfa7 DIRECTOR: LINGO: Optimized Lingo preprocessor
87cc5f1c68 DIRECTOR: LINGO: Implemented code patcher and added patches for Warlock


Commit: 9eab0eac4cc589005ab5c9d686f173c6406490dc
    https://github.com/scummvm/scummvm/commit/9eab0eac4cc589005ab5c9d686f173c6406490dc
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2020-05-22T15:38:49+02:00

Commit Message:
DIRECTOR: LINGO: Track script types and lines in preprocessor

Changed paths:
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-preprocessor.cpp
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 17877d00fb..0421d618c6 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1478,7 +1478,7 @@ void LB::b_installMenu(int nargs) {
 		return;
 	}
 
-	Common::String menuStxt = g_lingo->codePreprocessor(stxt->_ptext.c_str(), true);
+	Common::String menuStxt = g_lingo->codePreprocessor(stxt->_ptext.c_str(), kNoneScript, castId, true);
 	Common::String line;
 	int linenum = -1; // We increment it before processing
 
diff --git a/engines/director/lingo/lingo-preprocessor.cpp b/engines/director/lingo/lingo-preprocessor.cpp
index 9e0f4627e1..27eb4ea1fb 100644
--- a/engines/director/lingo/lingo-preprocessor.cpp
+++ b/engines/director/lingo/lingo-preprocessor.cpp
@@ -82,7 +82,7 @@ static Common::String prevtok(const char *s, const char *lineStart, const char *
 	return res;
 }
 
-Common::String Lingo::codePreprocessor(const char *s, bool simple) {
+Common::String Lingo::codePreprocessor(const char *s, ScriptType type, uint16 id, bool simple) {
 	Common::String res;
 
 	// We start from processing the continuation synbols
@@ -163,6 +163,7 @@ Common::String Lingo::codePreprocessor(const char *s, bool simple) {
 	Common::String line, tok, res1;
 	const char *lineStart, *prevEnd;
 	int iflevel = 0;
+	int linenumber = 0;
 
 	while (*s) {
 		line.clear();
@@ -172,6 +173,9 @@ Common::String Lingo::codePreprocessor(const char *s, bool simple) {
 		while (*s && *s != '\n') { // If we see a whitespace
 			res1 += *s;
 			line += tolower(*s++);
+
+			if (*s == '\xc2')
+				linenumber++;
 		}
 		debugC(2, kDebugLingoParse, "line: %d                         '%s'", iflevel, line.c_str());
 
@@ -181,6 +185,8 @@ Common::String Lingo::codePreprocessor(const char *s, bool simple) {
 
 		res += res1;
 
+		linenumber++;	// We do it here because of 'continue' statements
+
 		if (line.size() < 4) { // If line is too small, then skip it
 			if (*s)	// copy newline symbol
 				res += *s++;
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index acdff6b961..499e87b690 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -288,7 +288,7 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
 	}
 
 	// Preprocess the code for ease of the parser
-	Common::String codeNorm = codePreprocessor(code);
+	Common::String codeNorm = codePreprocessor(code, type, id);
 	code = codeNorm.c_str();
 	begin = code;
 
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index c31487a257..d7e33dd413 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -283,7 +283,7 @@ public:
 	void runTests();
 
 public:
-	Common::String codePreprocessor(const char *s, bool simple = false);
+	Common::String codePreprocessor(const char *s, ScriptType type, uint16 id, bool simple = false);
 
 private:
 	const char *findNextDefinition(const char *s);


Commit: ec85ef99c7670ceb2fb6d381a3a5fd46e37ea3fe
    https://github.com/scummvm/scummvm/commit/ec85ef99c7670ceb2fb6d381a3a5fd46e37ea3fe
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2020-05-22T15:38:49+02:00

Commit Message:
DIRECTOR: Distinguish between GIDs and gameIds

Changed paths:
    engines/director/detection.cpp
    engines/director/director.cpp
    engines/director/director.h


diff --git a/engines/director/detection.cpp b/engines/director/detection.cpp
index 91827b2677..3be73c1bcb 100644
--- a/engines/director/detection.cpp
+++ b/engines/director/detection.cpp
@@ -34,12 +34,16 @@ namespace Director {
 struct DirectorGameDescription {
 	ADGameDescription desc;
 
-	DirectorGameID gameID;
+	DirectorGameGID gameGID;
 	uint16 version;
 };
 
-DirectorGameID DirectorEngine::getGameID() const {
-	return _gameDescription->gameID;
+DirectorGameGID DirectorEngine::getGameGID() const {
+	return _gameDescription->gameGID;
+}
+
+const char *DirectorEngine::getGameId() const {
+	return _gameDescription->desc.gameId;
 }
 
 Common::Platform DirectorEngine::getPlatform() const {
@@ -169,7 +173,7 @@ ADDetectedGame DirectorMetaEngine::fallbackDetect(const FileMap &allFiles, const
 	desc->desc.guiOptions = GUIO0();
 	desc->desc.filesDescriptions[0].fileName = 0;
 	desc->version = 0;
-	desc->gameID = Director::GID_GENERIC;
+	desc->gameGID = Director::GID_GENERIC;
 
 	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
 		if (file->isDirectory())
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index d47246bad2..59ea6c94dc 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -136,7 +136,7 @@ Common::Error DirectorEngine::run() {
 	_lingo = new Lingo(this);
 	_soundManager = new DirectorSound();
 
-	if (getGameID() == GID_TEST) {
+	if (getGameGID() == GID_TEST) {
 		_mainArchive = nullptr;
 		_currentScore = nullptr;
 
@@ -148,7 +148,7 @@ Common::Error DirectorEngine::run() {
 		_lingo->runTests();
 
 		return Common::kNoError;
-	} else if (getGameID() == GID_TESTALL) {
+	} else if (getGameGID() == GID_TESTALL) {
 		enqueueAllMovies();
 	}
 
@@ -177,7 +177,7 @@ Common::Error DirectorEngine::run() {
 
 	debug(0, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\nObtaining score name\n");
 
-	if (getGameID() == GID_TESTALL)  {
+	if (getGameGID() == GID_TESTALL)  {
 		_nextMovie = getNextMovieFromQueue();
 		loadInitialMovie(_nextMovie.movie);
 	} else {
@@ -253,7 +253,7 @@ Common::Error DirectorEngine::run() {
 			}
 		}
 
-		if (getGameID() == GID_TESTALL) {
+		if (getGameGID() == GID_TESTALL) {
 			_nextMovie = getNextMovieFromQueue();
 		}
 
@@ -281,7 +281,7 @@ Common::Error DirectorEngine::run() {
 			if (!mov) {
 				warning("nextMovie: No score is loaded");
 
-				if (getGameID() == GID_TESTALL) {
+				if (getGameGID() == GID_TESTALL) {
 					loop = true;
 					continue;
 				}
diff --git a/engines/director/director.h b/engines/director/director.h
index 8fdbf8bfd6..e726cf4af7 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -46,7 +46,7 @@ typedef Common::Array<byte *> MacPatterns;
 
 namespace Director {
 
-enum DirectorGameID {
+enum DirectorGameGID {
 	GID_GENERIC,
 	GID_TEST,
 	GID_TESTALL
@@ -96,7 +96,8 @@ public:
 
 	// Detection related functions
 
-	DirectorGameID getGameID() const;
+	DirectorGameGID getGameGID() const;
+	const char *getGameId() const;
 	uint16 getVersion() const;
 	Common::Platform getPlatform() const;
 	Common::Language getLanguage() const;


Commit: 3a0bdfbfa74ed3609078e2f4b62af2391f20860e
    https://github.com/scummvm/scummvm/commit/3a0bdfbfa74ed3609078e2f4b62af2391f20860e
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2020-05-22T15:38:49+02:00

Commit Message:
DIRECTOR: LINGO: Optimized Lingo preprocessor

We were running each line twice, once with content and another time with '\n'

Changed paths:
    engines/director/lingo/lingo-preprocessor.cpp


diff --git a/engines/director/lingo/lingo-preprocessor.cpp b/engines/director/lingo/lingo-preprocessor.cpp
index 27eb4ea1fb..e884729fb4 100644
--- a/engines/director/lingo/lingo-preprocessor.cpp
+++ b/engines/director/lingo/lingo-preprocessor.cpp
@@ -334,6 +334,9 @@ Common::String Lingo::codePreprocessor(const char *s, ScriptType type, uint16 id
 		} else {
 			debugC(2, kDebugLingoParse, "nothing");
 		}
+
+		if (*s)	// copy newline symbol
+			res += *s++;
 	}
 
 	for (int i = 0; i < iflevel; i++) {


Commit: 87cc5f1c68d3a3fb6fce546e74573e152e451361
    https://github.com/scummvm/scummvm/commit/87cc5f1c68d3a3fb6fce546e74573e152e451361
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2020-05-22T15:38:49+02:00

Commit Message:
DIRECTOR: LINGO: Implemented code patcher and added patches for Warlock

Changed paths:
  A engines/director/lingo/lingo-patcher.cpp
    engines/director/lingo/lingo-preprocessor.cpp
    engines/director/lingo/lingo.h
    engines/director/module.mk


diff --git a/engines/director/lingo/lingo-patcher.cpp b/engines/director/lingo/lingo-patcher.cpp
new file mode 100644
index 0000000000..ea42c92958
--- /dev/null
+++ b/engines/director/lingo/lingo-patcher.cpp
@@ -0,0 +1,108 @@
+/* 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/director.h"
+#include "director/score.h"
+#include "director/lingo/lingo.h"
+
+
+namespace Director {
+
+using namespace Common;
+
+struct ScriptPatch {
+	const char *gameId;
+	Common::Platform platform;
+	const char *movie;
+	ScriptType type;
+	uint16 id;
+	int linenum;
+	const char *orig;
+	const char *replace;
+} const scriptPatches[] = {
+	// Garbage at end of script
+	{"warlock", kPlatformMacintosh, "WARLOCKSHIP/WARLOCKSHIP/UpForeECall", kFrameScript, 12,
+			2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
+	{"warlock", kPlatformMacintosh, "WARLOCKSHIP/WARLOCKSHIP/UpForeECall", kFrameScript, 12,
+			3, "Channels 17 to 18", ""},
+	{"warlock", kPlatformMacintosh, "WARLOCKSHIP/WARLOCKSHIP/UpForeECall", kFrameScript, 12,
+			4, "Frames 150 to 160", ""},
+
+	// Unbalanced 'end if' at the end of the script
+	{"warlock", kPlatformMacintosh, "STAMBUL/STAMBUL/DRUNK", kMovieScript, 5,
+			5, "end if", ""},
+
+	// Garbage at end of script
+	{"warlock", kPlatformWindows, "WRLCKSHP/UpForeECall", kFrameScript, 12,
+			2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
+	{"warlock", kPlatformWindows, "WRLCKSHP/UpForeECall", kFrameScript, 12,
+			3, "Channels 17 to 18", ""},
+	{"warlock", kPlatformWindows, "WRLCKSHP/UpForeECall", kFrameScript, 12,
+			4, "Frames 150 to 160", ""},
+
+	// Unbalanced 'end if' at the end of the script
+	{"warlock", kPlatformWindows, "STAMBUL/DRUNK", kMovieScript, 5,
+			5, "end if", ""},
+
+	{nullptr, kPlatformUnknown, nullptr, kNoneScript, 0, 0, nullptr, nullptr}
+};
+
+Common::String Lingo::patchLingoCode(Common::String &line, ScriptType type, uint16 id, int linenum) {
+	if (!_vm->getCurrentScore())
+		return line;
+
+	const ScriptPatch *patch = scriptPatches;
+	Common::String movie = _vm->getCurrentPath() + _vm->getCurrentScore()->getMacName();
+
+	// So far, we have not many patches, so do linear lookup
+	while (patch->gameId) {
+		// First, we do cheap comparisons
+		if (patch->type != type || patch->id != id || patch->linenum != linenum) {
+			patch++;
+			continue;
+		}
+
+		// Now expensive ones
+		if (movie.compareToIgnoreCase(patch->movie) || strcmp(patch->gameId, _vm->getGameId())) {
+			patch++;
+			continue;
+		}
+
+		// Now do a safeguard
+		if (line.compareToIgnoreCase(patch->orig)) {
+			warning("Lingo::patchLingoCode(): Unmatched patch for '%s', '%s' %s:%d @ %d. Expecting '%s' but got '%s'",
+					patch->gameId, patch->movie, scriptType2str(type), id, linenum,
+					patch->orig, line.c_str());
+			return line;
+		}
+
+		// Now everything matched
+		debugC(1, kDebugLingoParse, "Lingo::patchLingoCode(): Applied a patch for '%s', '%s' %s:%d @ %d. \"%s\" -> \"%s\"",
+				patch->gameId, patch->movie, scriptType2str(type), id, linenum,
+				patch->orig, line.c_str());
+		return patch->replace;
+	}
+
+	return line;
+}
+
+} // End of namespace Director
diff --git a/engines/director/lingo/lingo-preprocessor.cpp b/engines/director/lingo/lingo-preprocessor.cpp
index e884729fb4..d195ce964e 100644
--- a/engines/director/lingo/lingo-preprocessor.cpp
+++ b/engines/director/lingo/lingo-preprocessor.cpp
@@ -163,7 +163,7 @@ Common::String Lingo::codePreprocessor(const char *s, ScriptType type, uint16 id
 	Common::String line, tok, res1;
 	const char *lineStart, *prevEnd;
 	int iflevel = 0;
-	int linenumber = 0;
+	int linenumber = 1;
 
 	while (*s) {
 		line.clear();
@@ -179,6 +179,8 @@ Common::String Lingo::codePreprocessor(const char *s, ScriptType type, uint16 id
 		}
 		debugC(2, kDebugLingoParse, "line: %d                         '%s'", iflevel, line.c_str());
 
+		res1 = patchLingoCode(res1, type, id, linenumber);
+
 		res1 = preprocessReturn(res1);
 		res1 = preprocessPlay(res1);
 		res1 = preprocessSound(res1);
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index d7e33dd413..94cb97d27c 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -282,9 +282,14 @@ public:
 
 	void runTests();
 
+	// lingo-preprocessor.cpp
 public:
 	Common::String codePreprocessor(const char *s, ScriptType type, uint16 id, bool simple = false);
 
+	// lingo-patcher.cpp
+	Common::String patchLingoCode(Common::String &line, ScriptType type, uint16 id, int linenumber);
+
+	// lingo.cpp
 private:
 	const char *findNextDefinition(const char *s);
 
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 4b1e8fe5c0..8f22316106 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -28,6 +28,7 @@ MODULE_OBJS = \
 	lingo/lingo-events.o \
 	lingo/lingo-funcs.o \
 	lingo/lingo-lex.o \
+	lingo/lingo-patcher.o \
 	lingo/lingo-preprocessor.o \
 	lingo/lingo-the.o
 




More information about the Scummvm-git-logs mailing list