[Scummvm-git-logs] scummvm master -> d76b359ac23394a560a78e401ef514dee30aba79

sev- noreply at scummvm.org
Thu Jan 19 11:12:29 UTC 2023


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:
71473c94e7 DIRECTOR: Fix normaliseXLibName for kPlatformWindows
c79c32accb DIRECTOR: Refactor Stxt/TextCastMember to use raw strings
05ca29629a Revert "DIRECTOR: openMainArchive may be opening an EXE"
d76b359ac2 DIRECTOR: Refactor movie loaders to allow loading from executables


Commit: 71473c94e7c9649276f316cbb1f9bd3de4758119
    https://github.com/scummvm/scummvm/commit/71473c94e7c9649276f316cbb1f9bd3de4758119
Author: Scott Percival (code at moral.net.au)
Date: 2023-01-19T12:12:21+01:00

Commit Message:
DIRECTOR: Fix normaliseXLibName for kPlatformWindows

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


diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 0a5e26eaf15..e3789cd81f3 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -203,11 +203,15 @@ void Lingo::cleanupXLibs() {
 Common::String Lingo::normalizeXLibName(Common::String name) {
 	Common::Platform platform = _vm->getPlatform();
 	if (platform == Common::kPlatformMacintosh || platform == Common::kPlatformMacintoshII) {
-		int pos = name.findLastOf(':');
-		name = name.substr(pos + 1, name.size());
+		size_t pos = name.findLastOf(':');
+		if (pos != Common::String::npos)
+			name = name.substr(pos + 1, name.size());
 		if (name.hasSuffixIgnoreCase(".xlib"))
 			name = name.substr(0, name.size() - 5);
 	} else if (platform == Common::kPlatformWindows) {
+		size_t pos = name.findLastOf("\\");
+		if (pos != Common::String::npos)
+			name = name.substr(pos + 1, name.size());
 		if (name.hasSuffixIgnoreCase(".dll"))
 			name = name.substr(0, name.size() - 4);
 	}


Commit: c79c32accb9feb837763e640c8831421d68475ca
    https://github.com/scummvm/scummvm/commit/c79c32accb9feb837763e640c8831421d68475ca
Author: Scott Percival (code at moral.net.au)
Date: 2023-01-19T12:12:21+01:00

Commit Message:
DIRECTOR: Refactor Stxt/TextCastMember to use raw strings

There is now _rtext, an untouched copy of the original data.
For compatibility, _ftext and _ptext are kept the same.

In addition, this change removes most of the workaround logic from
b_installMenu, as it can now parse the menu string directly.

Changed paths:
    engines/director/castmember.cpp
    engines/director/castmember.h
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-object.cpp
    engines/director/lingo/lingo.cpp
    engines/director/stxt.cpp
    engines/director/stxt.h


diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index ad15abed2c6..2d94a0159f8 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -1254,6 +1254,7 @@ void TextCastMember::importStxt(const Stxt *stxt) {
 	_fgpalinfo3 = stxt->_style.b;
 	_ftext = stxt->_ftext;
 	_ptext = stxt->_ptext;
+	_rtext = stxt->_rtext;
 
 	// Rectifying _fontId in case of a fallback font
 	Graphics::MacFont macFont(_fontId, _fontSize, _textSlant);
@@ -1323,19 +1324,21 @@ void TextCastMember::importRTE(byte *text) {
 	//assert(rteList.size() == 3);
 	//child0 is probably font data.
 	//child1 is the raw text.
-	_ptext = _ftext = Common::String((char*)text);
+	_rtext = _ptext = _ftext = Common::String((char*)text);
 	//child2 is positional?
 }
 
-void TextCastMember::setText(const Common::U32String &text) {
+void TextCastMember::setRawText(const Common::String &text) {
 	// Do nothing if text did not change
-	if (_ptext.equals(text))
+	if (_rtext.equals(text))
 		return;
 
+	_rtext = text;
+	_ptext = Common::U32String(text);
+
 	// If text has changed, use the cached formatting from first STXT in this castmember.
 	Common::U32String formatting = Common::String::format("\001\016%04x%02x%04x%04x%04x%04x", _fontId, _textSlant, _fontSize, _fgpalinfo1, _fgpalinfo2, _fgpalinfo3);
-	_ptext = text;
-	_ftext = formatting + text;
+	_ftext = formatting + _ptext;
 	_modified = true;
 }
 
@@ -1361,6 +1364,10 @@ Common::U32String TextCastMember::getText() {
 	return _ptext;
 }
 
+Common::String TextCastMember::getRawText() {
+	return _rtext;
+}
+
 void TextCastMember::setTextSize(int textSize) {
 	if (_widget) {
 		((Graphics::MacText *)_widget)->setTextSize(textSize);
diff --git a/engines/director/castmember.h b/engines/director/castmember.h
index 16de734d206..7f83f44afd7 100644
--- a/engines/director/castmember.h
+++ b/engines/director/castmember.h
@@ -284,7 +284,6 @@ public:
 	TextCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version, uint8 flags1 = 0, bool asButton = false);
 	void setColors(uint32 *fgcolor, uint32 *bgcolor) override;
 
-	void setText(const Common::U32String &text);
 	Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) override;
 
 	bool isEditable() override { return _editable; }
@@ -334,10 +333,13 @@ public:
 
 	Common::U32String _ftext;
 	Common::U32String _ptext;
+	Common::String _rtext;
 	void importStxt(const Stxt *stxt);
 	void importRTE(byte *text);
 
 	Common::U32String getText();
+	Common::String getRawText();
+	void setRawText(const Common::String &text);
 
 private:
 	uint32 _bgcolor;
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index e3316edd83e..d78f7ba17fa 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -2022,7 +2022,7 @@ void LB::b_installMenu(int nargs) {
 	}
 	TextCastMember *field = static_cast<TextCastMember *>(member);
 
-	Common::U32String menuStxt = g_lingo->_compiler->codePreprocessor(field->getText(), field->getCast()->_lingoArchive, kNoneScript, memberID, true);
+	Common::String menuStxt = field->getRawText();
 	int linenum = -1; // We increment it before processing
 
 	Graphics::MacMenu *menu = g_director->_wm->addMenu();
@@ -2033,50 +2033,49 @@ void LB::b_installMenu(int nargs) {
 
 	menu->setCommandsCallback(menuCommandsCallback, g_director);
 
-	debugC(3, kDebugLingoExec, "installMenu: '%s'", Common::toPrintable(menuStxt).encode().c_str());
+	debugC(3, kDebugLingoExec, "installMenu: '%s'", Common::toPrintable(menuStxt).c_str());
 
 	LingoArchive *mainArchive = movie->getMainLingoArch();
 
-	// Since loading the STXT converts the text to Unicode based on the platform
-	// encoding, we need to fetch the correct Unicode character for the platform.
-
 	// STXT sections use Mac-style carriage returns for line breaks.
-	// The code preprocessor converts carriage returns to line feeds.
-	const uint32 LINE_BREAK = 0x0a;
-	// Menu definitions use the character 0xc3 to denote a checkmark.
-	// For Mac, this is √. For Windows, this is Ã.
-	const uint8 CHECKMARK_CHAR = 0xc3;
-	const uint32 CHECKMARK_U32 = numToChar(CHECKMARK_CHAR);
-	const char *CHECKMARK_STR = "\xc3\x83"; // "Ã"
+	const char LINE_BREAK_CHAR = '\x0D';
 	// Menu definitions use the character 0xc5 to denote a code separator.
 	// For Mac, this is ≈. For Windows, this is Å.
-	const uint8 CODE_SEPARATOR_CHAR = 0xc5;
-	const uint32 CODE_SEPARATOR_U32 = numToChar(CODE_SEPARATOR_CHAR);
-	const char *CODE_SEPARATOR_STR = "\xc3\x85"; // "Ã…"
-
-	Common::U32String lineBuffer;
-
-	for (const Common::u32char_type_t *s = menuStxt.c_str(); *s; s++) {
-		lineBuffer.clear();
-		while (*s && *s != LINE_BREAK) {
-			if (*s == CHECKMARK_U32) {
-				lineBuffer += CHECKMARK_CHAR;
-				s++;
-			} else if (*s == CODE_SEPARATOR_U32) {
-				lineBuffer += CODE_SEPARATOR_CHAR;
-				s++;
-			} else if (*s == CONTINUATION) { // fast forward to the next line
-				s++;
-				if (*s == LINE_BREAK) {
-					lineBuffer += ' ';
-					s++;
+	const char CODE_SEPARATOR_CHAR = '\xC5';
+	// Continuation character is 0xac to denote a line running over.
+	// For Mac, this is ¨. For Windows, this is ¬.
+	const char CONTINUATION_CHAR = '\xAC';
+	// Menu definitions use the character 0xc3 to denote a checkmark.
+	// For Mac, this is √. For Windows, this is Ã.
+	// This is used by MacMenu::createSubMenuFromString.
+
+	Common::String line;
+
+	for (auto it = menuStxt.begin(); it != menuStxt.end(); ++it) {
+		line.clear();
+		while (it != menuStxt.end() && *it != LINE_BREAK_CHAR) {
+			if (*it == '-') {
+				it++;
+				if (it != menuStxt.end() && *it == '-') { // rest of the line is a comment
+					while (it != menuStxt.end() && *it != LINE_BREAK_CHAR) {
+						it++;
+					}
+					break;
+				}
+				line += '-';
+			} else if (*it == CONTINUATION_CHAR) { // fast forward to the next line
+				it++;
+				if (*it == LINE_BREAK_CHAR) {
+					line += ' ';
+					it++;
 				}
+			} else if (*it == LINE_BREAK_CHAR) {
+				break;
 			} else {
-				lineBuffer += *s++;
+				line += *it++;
 			}
 		}
 		linenum++;
-		Common::String line = lineBuffer.encode();
 
 		if (line.empty())
 			continue;
@@ -2101,22 +2100,14 @@ void LB::b_installMenu(int nargs) {
 			continue;
 		}
 
-		// If the line has a UTF8 checkmark, replace it with a byte character
-		// as expected by MacMenu.
-		size_t checkOffset = line.find(CHECKMARK_STR);
-		if (checkOffset != Common::String::npos) {
-			line.erase(checkOffset, strlen(CHECKMARK_STR));
-			line.insertChar(CHECKMARK_CHAR, checkOffset);
-		}
-
 		// Split the line at the code separator
-		size_t sepOffset = line.find(CODE_SEPARATOR_STR);
+		size_t sepOffset = line.find(CODE_SEPARATOR_CHAR);
 
 		Common::String text;
 
 		if (sepOffset != Common::String::npos) {
 			text = Common::String(line.c_str(), line.c_str() + sepOffset);
-			command = Common::String(line.c_str() + sepOffset + strlen(CODE_SEPARATOR_STR));
+			command = Common::String(line.c_str() + sepOffset + 1);
 		} else {
 			text = line;
 			command = "";
@@ -2139,7 +2130,7 @@ void LB::b_installMenu(int nargs) {
 			}
 		}
 
-		if (!*s) // if we reached end of string, do not increment it but break
+		if (it == menuStxt.end()) // if we reached end of string, do not increment it but break
 			break;
 	}
 
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index e3789cd81f3..74a7e29b4d2 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -1087,7 +1087,7 @@ bool TextCastMember::setField(int field, const Datum &d) {
 		return true;
 		break;
 	case kTheText:
-		setText(d.asString());
+		setRawText(d.asString());
 		return true;
 	case kTheTextAlign:
 		{
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 1d435e6d792..a1039d3ff31 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1494,7 +1494,7 @@ void Lingo::varAssign(const Datum &var, const Datum &value) {
 			}
 			switch (member->_type) {
 			case kCastText:
-				((TextCastMember *)member)->setText(value.asString());
+				((TextCastMember *)member)->setRawText(value.asString());
 				break;
 			default:
 				warning("varAssign: Unhandled cast type %d", member->_type);
diff --git a/engines/director/stxt.cpp b/engines/director/stxt.cpp
index 1db2ecf26ad..bdf57c9f005 100644
--- a/engines/director/stxt.cpp
+++ b/engines/director/stxt.cpp
@@ -87,6 +87,7 @@ Stxt::Stxt(Cast *cast, Common::SeekableReadStreamEndian &textStream) : _cast(cas
 
 			prevPos++;
 		}
+		_rtext += textPart;
 		Common::CodePage encoding = detectFontEncoding(cast->_platform, currentFont);
 		Common::U32String u32TextPart(textPart, encoding);
 		_ptext += u32TextPart;
@@ -100,6 +101,7 @@ Stxt::Stxt(Cast *cast, Common::SeekableReadStreamEndian &textStream) : _cast(cas
 		formattingCount--;
 	}
 
+	_rtext += text;
 	Common::CodePage encoding = detectFontEncoding(cast->_platform, _style.fontId);
 	Common::U32String u32Text(text, encoding);
 	_ptext += u32Text;
diff --git a/engines/director/stxt.h b/engines/director/stxt.h
index 5db452b1d35..f1ae680ee14 100644
--- a/engines/director/stxt.h
+++ b/engines/director/stxt.h
@@ -54,6 +54,7 @@ public:
 	Cast *_cast;
 	Common::U32String _ftext;
 	Common::U32String _ptext;
+	Common::String _rtext;
 	TextType _textType;
 	TextAlignType _textAlign;
 	SizeType _textShadow;


Commit: 05ca29629a408d8ca090a1be626066f09e60ec6c
    https://github.com/scummvm/scummvm/commit/05ca29629a408d8ca090a1be626066f09e60ec6c
Author: Scott Percival (code at moral.net.au)
Date: 2023-01-19T12:12:21+01:00

Commit Message:
Revert "DIRECTOR: openMainArchive may be opening an EXE"

This reverts commit 6af5e86a77c5401f2d022279e2ce4ff9c463fd1d.

Changed paths:
    engines/director/resource.cpp
    engines/director/window.h


diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index ec075686ff3..44bbcad45a1 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -196,45 +196,20 @@ void Window::probeMacBinary(MacArchive *archive) {
 Archive *Window::openMainArchive(const Common::String movie) {
 	debug(1, "openMainArchive(\"%s\")", movie.c_str());
 
-	// If the archive is already open, don't reopen it;
-	// just init from the existing archive. This prevents errors that
-	// can happen when trying to load the same archive more than once.
-	if (g_director->_allOpenResFiles.contains(movie) && SearchMan.hasFile(movie)) {
-		_mainArchive = g_director->_allOpenResFiles.getVal(movie);
-
-		if (g_director->getPlatform() == Common::kPlatformWindows) {
-			return loadEXE(movie);
-		} else {
-			probeProjector(movie);
-			return loadMac(movie);
-		}
-	}
-
 	_mainArchive = g_director->createArchive();
 
 	if (!_mainArchive->openFile(movie)) {
-		if (!SearchMan.hasFile(movie)) {
-			delete _mainArchive;
-			_mainArchive = nullptr;
-
-			warning("openMainArchive(): Could not open '%s'", movie.c_str());
-			return nullptr;
-		} else {
-			warning("openMainArchive(): Could not open '%s'; trying EXE", movie.c_str());
+		delete _mainArchive;
+		_mainArchive = nullptr;
 
-			if (g_director->getPlatform() == Common::kPlatformWindows) {
-				return loadEXE(movie);
-			} else {
-				probeProjector(movie);
-				return loadMac(movie);
-			}
-		}
+		warning("openMainArchive(): Could not open '%s'", movie.c_str());
+		return nullptr;
 	}
 
 	return _mainArchive;
 }
 
-Archive *Window::loadEXE(const Common::String movie) {
+void Window::loadEXE(const Common::String movie) {
 	Common::SeekableReadStream *iniStream = SearchMan.createReadStreamForMember("LINGO.INI");
 	if (iniStream) {
 		char *script = (char *)calloc(iniStream->size() + 1, 1);
@@ -254,7 +229,7 @@ Archive *Window::loadEXE(const Common::String movie) {
 
 	Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(Common::Path(movie, g_director->_dirSeparator));
 	if (!exeStream)
-		return nullptr;
+		error("Failed to open EXE '%s'", g_director->getEXEName().c_str());
 
 	uint32 initialTag = exeStream->readUint32LE();
 	if (initialTag == MKTAG('R', 'I', 'F', 'X') || initialTag == MKTAG('X', 'F', 'I', 'R')) {
@@ -264,11 +239,11 @@ Archive *Window::loadEXE(const Common::String movie) {
 		_mainArchive = new RIFFArchive();
 
 		if (!_mainArchive->openStream(exeStream, 0))
-			return nullptr;
+			error("Failed to load RIFF");
 	} else {
 		Common::WinResources *exe = Common::WinResources::createFromEXE(movie);
 		if (!exe)
-			return nullptr;
+			error("Failed to open EXE '%s'", g_director->getEXEName().c_str());
 
 		const Common::Array<Common::WinResourceID> versions = exe->getIDList(Common::kWinVersion);
 		for (uint i = 0; i < versions.size(); i++) {
@@ -301,17 +276,12 @@ Archive *Window::loadEXE(const Common::String movie) {
 		} else if (g_director->getVersion() >= 200) {
 			loadEXEv3(exeStream);
 		} else {
-			warning("Unhandled Windows EXE version %d", g_director->getVersion());
-			return nullptr;
+			error("Unhandled Windows EXE version %d", g_director->getVersion());
 		}
 	}
 
-	if (_mainArchive) {
+	if (_mainArchive)
 		_mainArchive->setPathName(movie);
-		return _mainArchive;
-	} else {
-		return nullptr;
-	}
 }
 
 void Window::loadEXEv3(Common::SeekableReadStream *stream) {
@@ -456,17 +426,15 @@ void Window::loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset) {
 		error("Failed to load RIFX from EXE");
 }
 
-Archive *Window::loadMac(const Common::String movie) {
+void Window::loadMac(const Common::String movie) {
 	if (g_director->getVersion() < 400) {
 		// The data is part of the resource fork of the executable
-		return openMainArchive(movie);
+		openMainArchive(movie);
 	} else {
 		// The RIFX is located in the data fork of the executable
 		Common::SeekableReadStream *dataFork = Common::MacResManager::openFileOrDataFork(Common::Path(movie, g_director->_dirSeparator));
-		if (!dataFork) {
-			warning("Failed to open Mac binary '%s'", movie.c_str());
-			return nullptr;
-		}
+		if (!dataFork)
+			error("Failed to open Mac binary '%s'", movie.c_str());
 		_mainArchive = new RIFXArchive();
 		_mainArchive->setPathName(movie);
 
@@ -488,8 +456,6 @@ Archive *Window::loadMac(const Common::String movie) {
 			delete _currentMovie;
 			_currentMovie = nullptr;
 		}
-
-		return _mainArchive;
 	}
 }
 
diff --git a/engines/director/window.h b/engines/director/window.h
index 9474373f1f2..9ee9fc746ba 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -172,13 +172,13 @@ public:
 	void probeProjector(const Common::String &movie);
 	void probeMacBinary(MacArchive *archive);
 	Archive *openMainArchive(const Common::String movie);
-	Archive *loadEXE(const Common::String movie);
+	void loadEXE(const Common::String movie);
 	void loadEXEv3(Common::SeekableReadStream *stream);
 	void loadEXEv4(Common::SeekableReadStream *stream);
 	void loadEXEv5(Common::SeekableReadStream *stream);
 	void loadEXEv7(Common::SeekableReadStream *stream);
 	void loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset);
-	Archive *loadMac(const Common::String movie);
+	void loadMac(const Common::String movie);
 	void loadStartMovieXLibs();
 
 	// lingo/lingo-object.cpp


Commit: d76b359ac23394a560a78e401ef514dee30aba79
    https://github.com/scummvm/scummvm/commit/d76b359ac23394a560a78e401ef514dee30aba79
Author: Scott Percival (code at moral.net.au)
Date: 2023-01-19T12:12:21+01:00

Commit Message:
DIRECTOR: Refactor movie loaders to allow loading from executables

Changed paths:
    engines/director/resource.cpp
    engines/director/window.cpp
    engines/director/window.h


diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 44bbcad45a1..b6fbc660b62 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -52,12 +52,8 @@ Common::Error Window::loadInitialMovie() {
 	debug(0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
 	Common::String movie = (_vm->getGameGID() == GID_TESTALL) ? getNextMovieFromQueue().movie : _vm->getEXEName();
 
-	if (g_director->getPlatform() == Common::kPlatformWindows) {
-		loadEXE(movie);
-	} else {
-		probeProjector(movie);
-		loadMac(movie);
-	}
+	loadINIStream();
+	_mainArchive = openArchive(movie);
 
 	if (!_mainArchive) {
 		warning("Cannot open main movie");
@@ -152,8 +148,10 @@ void Window::probeMacBinary(MacArchive *archive) {
 				_nextMovie.movie = moviePath;
 				warning("Replaced score name with: %s (from %s)", _nextMovie.movie.c_str(), sname.c_str());
 
-				delete _currentMovie;
-				_currentMovie = nullptr;
+				if (_currentMovie) {
+					delete _currentMovie;
+					_currentMovie = nullptr;
+				}
 
 				probeProjector(moviePath);
 			} else {
@@ -193,23 +191,34 @@ void Window::probeMacBinary(MacArchive *archive) {
 	g_director->_allOpenResFiles.setVal(archive->getPathName(), archive);
 }
 
-Archive *Window::openMainArchive(const Common::String movie) {
-	debug(1, "openMainArchive(\"%s\")", movie.c_str());
-
-	_mainArchive = g_director->createArchive();
+Archive *Window::openArchive(const Common::String movie) {
+	debug(1, "openArchive(\"%s\")", movie.c_str());
 
-	if (!_mainArchive->openFile(movie)) {
-		delete _mainArchive;
-		_mainArchive = nullptr;
-
-		warning("openMainArchive(): Could not open '%s'", movie.c_str());
-		return nullptr;
+	// If the archive is already open, don't reopen it;
+	// just init from the existing archive. This prevents errors that
+	// can happen when trying to load the same archive more than once.
+	if (g_director->_allOpenResFiles.contains(movie) && SearchMan.hasFile(movie)) {
+		return g_director->_allOpenResFiles.getVal(movie);
 	}
 
-	return _mainArchive;
+	Archive *result = nullptr;
+	if (g_director->getPlatform() == Common::kPlatformWindows) {
+		result = loadEXE(movie);
+	} else {
+		probeProjector(movie);
+		result = loadMac(movie);
+	}
+	if (!result) {
+		result = g_director->createArchive();
+		if (!result->openFile(movie)) {
+			delete result;
+			result = nullptr;
+		}
+	}
+	return result;
 }
 
-void Window::loadEXE(const Common::String movie) {
+void Window::loadINIStream() {
 	Common::SeekableReadStream *iniStream = SearchMan.createReadStreamForMember("LINGO.INI");
 	if (iniStream) {
 		char *script = (char *)calloc(iniStream->size() + 1, 1);
@@ -226,31 +235,42 @@ void Window::loadEXE(const Common::String movie) {
 	} else {
 		warning("No LINGO.INI");
 	}
+}
 
+Archive *Window::loadEXE(const Common::String movie) {
 	Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(Common::Path(movie, g_director->_dirSeparator));
-	if (!exeStream)
-		error("Failed to open EXE '%s'", g_director->getEXEName().c_str());
+	if (!exeStream) {
+		warning("Window::loadEXE(): Failed to open EXE '%s'", g_director->getEXEName().c_str());
+		return nullptr;
+	}
+
+	Archive *result = nullptr;
 
 	uint32 initialTag = exeStream->readUint32LE();
 	if (initialTag == MKTAG('R', 'I', 'F', 'X') || initialTag == MKTAG('X', 'F', 'I', 'R')) {
 		// we've encountered a movie saved from Director, not a projector.
-		loadEXERIFX(exeStream, 0);
+		result = loadEXERIFX(exeStream, 0);
 	} else if (initialTag == MKTAG('R', 'I', 'F', 'F') || initialTag == MKTAG('F', 'F', 'I', 'R')) { // This is just a normal movie
-		_mainArchive = new RIFFArchive();
+		result = new RIFFArchive();
 
-		if (!_mainArchive->openStream(exeStream, 0))
-			error("Failed to load RIFF");
+		if (!result->openStream(exeStream, 0)) {
+			warning("Window::loadEXE(): Failed to load RIFF");
+			delete result;
+			return nullptr;
+		}
 	} else {
 		Common::WinResources *exe = Common::WinResources::createFromEXE(movie);
-		if (!exe)
-			error("Failed to open EXE '%s'", g_director->getEXEName().c_str());
+		if (!exe) {
+			warning("Window::loadEXE(): Failed to open EXE '%s'", g_director->getEXEName().c_str());
+			return nullptr;
+		}
 
 		const Common::Array<Common::WinResourceID> versions = exe->getIDList(Common::kWinVersion);
 		for (uint i = 0; i < versions.size(); i++) {
 			Common::WinResources::VersionInfo *info = exe->getVersionResource(versions[i]);
 
 			for (Common::WinResources::VersionHash::const_iterator it = info->hash.begin(); it != info->hash.end(); ++it)
-				warning("info <%s>: <%s>", it->_key.c_str(), it->_value.encode().c_str());
+				warning("Window::loadEXE(): info <%s>: <%s>", it->_key.c_str(), it->_value.encode().c_str());
 
 			delete info;
 
@@ -268,23 +288,25 @@ void Window::loadEXE(const Common::String movie) {
 		exeStream->seek(exeStream->readUint32LE());
 
 		if (g_director->getVersion() >= 700) {
-			loadEXEv7(exeStream);
+			result = loadEXEv7(exeStream);
 		} else if (g_director->getVersion() >= 500) {
-			loadEXEv5(exeStream);
+			result = loadEXEv5(exeStream);
 		} else if (g_director->getVersion() >= 400) {
-			loadEXEv4(exeStream);
+			result = loadEXEv4(exeStream);
 		} else if (g_director->getVersion() >= 200) {
-			loadEXEv3(exeStream);
+			result = loadEXEv3(exeStream);
 		} else {
-			error("Unhandled Windows EXE version %d", g_director->getVersion());
+			warning("Window::loadEXE(): Unhandled Windows EXE version %d", g_director->getVersion());
+			return nullptr;
 		}
 	}
 
-	if (_mainArchive)
-		_mainArchive->setPathName(movie);
+	if (result)
+		result->setPathName(movie);
+	return result;
 }
 
-void Window::loadEXEv3(Common::SeekableReadStream *stream) {
+Archive *Window::loadEXEv3(Common::SeekableReadStream *stream) {
 	uint32 mmmSize = 0;
 	Common::String mmmFileName;
 	Common::String directoryName;
@@ -308,12 +330,12 @@ void Window::loadEXEv3(Common::SeekableReadStream *stream) {
 			directoryName = directoryName_;
 		} else {
 			if (!SearchMan.hasFile(Common::Path(mmmFileName_, g_director->_dirSeparator)))
-				warning("Failed to find MMM '%s'", mmmFileName_.c_str());
+				warning("Window::loadEXEv3(): Failed to find MMM '%s'", mmmFileName_.c_str());
 			else {
 				Common::SeekableReadStream *const mmmFile_ = SearchMan.createReadStreamForMember(Common::Path(mmmFileName_, g_director->_dirSeparator));
 				uint32 mmmFileSize_ = mmmFile_->size();
 				if (mmmSize_ != mmmFileSize_)
-					warning("File size for '%s' doesn't match. Got %d (0x%x), want %d (0x%x)", mmmFileName_.c_str(), mmmFileSize_, mmmFileSize_, mmmSize_, mmmSize_);
+					warning("Window::loadEXEv3(): File size for '%s' doesn't match. Got %d (0x%x), want %d (0x%x)", mmmFileName_.c_str(), mmmFileSize_, mmmFileSize_, mmmSize_, mmmSize_);
 				delete mmmFile_;
 			}
 		}
@@ -321,6 +343,7 @@ void Window::loadEXEv3(Common::SeekableReadStream *stream) {
 		debugC(1, kDebugLoading, "%s", "");
 	}
 
+	Archive *result = nullptr;
 	if (mmmSize) {
 		uint32 riffOffset = stream->pos();
 
@@ -347,25 +370,34 @@ void Window::loadEXEv3(Common::SeekableReadStream *stream) {
 		}
 
 
-		_mainArchive = new RIFFArchive();
+		result = new RIFFArchive();
 
-		if (_mainArchive->openStream(stream, riffOffset))
-			return;
+		if (result->openStream(stream, riffOffset))
+			return result;
 
-		warning("Failed to load RIFF from EXE");
-		delete _mainArchive;
-		_mainArchive = nullptr;
+		warning("Window::loadEXEv3(): Failed to load RIFF from EXE");
+		delete result;
+		result = nullptr;
 		delete stream;
 	}
 
-	openMainArchive(mmmFileName);
+	result = g_director->createArchive();
+
+	if (!result->openFile(mmmFileName)) {
+		warning("Window::loadEXEv3(): Could not open '%s'", mmmFileName.c_str());
+		delete result;
+		result = nullptr;
+	}
+	return result;
 }
 
-void Window::loadEXEv4(Common::SeekableReadStream *stream) {
+Archive *Window::loadEXEv4(Common::SeekableReadStream *stream) {
 	uint32 ver = stream->readUint32BE();
 
-	if (ver != MKTAG('P', 'J', '9', '3'))
-		error("Invalid projector tag found in v4 EXE [%s]", tag2str(ver));
+	if (ver != MKTAG('P', 'J', '9', '3')) {
+		warning("Window::loadEXEv4(): Invalid projector tag found in v4 EXE [%s]", tag2str(ver));
+		return nullptr;
+	}
 
 	uint32 rifxOffset = stream->readUint32LE();
 	/* uint32 fontMapOffset = */ stream->readUint32LE();
@@ -376,16 +408,18 @@ void Window::loadEXEv4(Common::SeekableReadStream *stream) {
 	/* uint32 rifxOffsetAlt = */ stream->readUint32LE(); // equivalent to rifxOffset
 	uint32 flags = stream->readUint32LE();
 
-	warning("PJ93 projector flags: %08x", flags);
+	warning("Window::loadEXEv4(): PJ93 projector flags: %08x", flags);
 
-	loadEXERIFX(stream, rifxOffset);
+	return loadEXERIFX(stream, rifxOffset);
 }
 
-void Window::loadEXEv5(Common::SeekableReadStream *stream) {
+Archive *Window::loadEXEv5(Common::SeekableReadStream *stream) {
 	uint32 ver = stream->readUint32LE();
 
-	if (ver != MKTAG('P', 'J', '9', '5'))
-		error("Invalid projector tag found in v5 EXE [%s]", tag2str(ver));
+	if (ver != MKTAG('P', 'J', '9', '5')) {
+		warning("Window::loadEXEv5(): Invalid projector tag found in v5 EXE [%s]", tag2str(ver));
+		return nullptr;
+	}
 
 	uint32 rifxOffset = stream->readUint32LE();
 	uint32 pflags = stream->readUint32LE();
@@ -398,16 +432,18 @@ void Window::loadEXEv5(Common::SeekableReadStream *stream) {
 	stream->readUint32LE(); // number of driver files
 	stream->readUint32LE(); // fontMapOffset
 
-	warning("PJ95 projector pflags: %08x  flags: %08x", pflags, flags);
+	warning("Window::loadEXEv5(): PJ95 projector pflags: %08x  flags: %08x", pflags, flags);
 
-	loadEXERIFX(stream, rifxOffset);
+	return loadEXERIFX(stream, rifxOffset);
 }
 
-void Window::loadEXEv7(Common::SeekableReadStream *stream) {
+Archive *Window::loadEXEv7(Common::SeekableReadStream *stream) {
 	uint32 ver = stream->readUint32LE();
 
-	if (ver != MKTAG('P', 'J', '0', '0') && ver != MKTAG('P', 'J', '0', '1'))
-		error("Invalid projector tag found in v7 EXE [%s]", tag2str(ver));
+	if (ver != MKTAG('P', 'J', '0', '0') && ver != MKTAG('P', 'J', '0', '1')) {
+		warning("Window::loadEXEv7(): Invalid projector tag found in v7 EXE [%s]", tag2str(ver));
+		return nullptr;
+	}
 
 	uint32 rifxOffset = stream->readUint32LE();
 	stream->readUint32LE(); // unknown
@@ -416,27 +452,40 @@ void Window::loadEXEv7(Common::SeekableReadStream *stream) {
 	stream->readUint32LE(); // unknown
 	stream->readUint32LE(); // some DLL offset
 
-	loadEXERIFX(stream, rifxOffset);
+	return loadEXERIFX(stream, rifxOffset);
 }
 
-void Window::loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset) {
-	_mainArchive = new RIFXArchive();
+Archive *Window::loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset) {
+	Archive *result = new RIFXArchive();
 
-	if (!_mainArchive->openStream(stream, offset))
-		error("Failed to load RIFX from EXE");
+	if (!result->openStream(stream, offset)) {
+		warning("Window::loadEXERIFX(): Failed to load RIFX from EXE");
+		delete result;
+		result = nullptr;
+	}
+	return result;
 }
 
-void Window::loadMac(const Common::String movie) {
+Archive *Window::loadMac(const Common::String movie) {
+	Archive *result = nullptr;
 	if (g_director->getVersion() < 400) {
 		// The data is part of the resource fork of the executable
-		openMainArchive(movie);
+		result = g_director->createArchive();
+
+		if (!result->openFile(movie)) {
+			delete result;
+			result = nullptr;
+			warning("Window::loadMac(): Could not open '%s'", movie.c_str());
+		}
 	} else {
 		// The RIFX is located in the data fork of the executable
 		Common::SeekableReadStream *dataFork = Common::MacResManager::openFileOrDataFork(Common::Path(movie, g_director->_dirSeparator));
-		if (!dataFork)
-			error("Failed to open Mac binary '%s'", movie.c_str());
-		_mainArchive = new RIFXArchive();
-		_mainArchive->setPathName(movie);
+		if (!dataFork) {
+			warning("Window::loadMac(): Failed to open Mac binary '%s'", movie.c_str());
+			return nullptr;
+		}
+		result = new RIFXArchive();
+		result->setPathName(movie);
 
 		// First we need to detect PPC vs. 68k
 
@@ -451,12 +500,17 @@ void Window::loadMac(const Common::String movie) {
 			startOffset = 0;
 		}
 
-		if (!_mainArchive->openStream(dataFork, startOffset)) {
-			warning("Failed to load RIFX from Mac binary");
-			delete _currentMovie;
-			_currentMovie = nullptr;
+		if (!result->openStream(dataFork, startOffset)) {
+			warning("Window::loadMac(): Failed to load RIFX from Mac binary");
+			delete result;
+			result = nullptr;
+			if (_currentMovie) {
+				delete _currentMovie;
+				_currentMovie = nullptr;
+			}
 		}
 	}
+	return result;
 }
 
 void Window::loadStartMovieXLibs() {
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 5aa2f75f956..2c40a6ce021 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -313,7 +313,7 @@ bool Window::loadNextMovie() {
 	delete _currentMovie;
 	_currentMovie = nullptr;
 
-	Archive *mov = openMainArchive(_currentPath + Common::lastPathComponent(_nextMovie.movie, g_director->_dirSeparator));
+	Archive *mov = openArchive(_currentPath + Common::lastPathComponent(_nextMovie.movie, g_director->_dirSeparator));
 
 	if (!mov)
 		return false;
diff --git a/engines/director/window.h b/engines/director/window.h
index 9ee9fc746ba..1b1e54a2cac 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -171,14 +171,15 @@ public:
 	Common::Error loadInitialMovie();
 	void probeProjector(const Common::String &movie);
 	void probeMacBinary(MacArchive *archive);
-	Archive *openMainArchive(const Common::String movie);
-	void loadEXE(const Common::String movie);
-	void loadEXEv3(Common::SeekableReadStream *stream);
-	void loadEXEv4(Common::SeekableReadStream *stream);
-	void loadEXEv5(Common::SeekableReadStream *stream);
-	void loadEXEv7(Common::SeekableReadStream *stream);
-	void loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset);
-	void loadMac(const Common::String movie);
+	void loadINIStream();
+	Archive *openArchive(const Common::String movie);
+	Archive *loadEXE(const Common::String movie);
+	Archive *loadEXEv3(Common::SeekableReadStream *stream);
+	Archive *loadEXEv4(Common::SeekableReadStream *stream);
+	Archive *loadEXEv5(Common::SeekableReadStream *stream);
+	Archive *loadEXEv7(Common::SeekableReadStream *stream);
+	Archive *loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset);
+	Archive *loadMac(const Common::String movie);
 	void loadStartMovieXLibs();
 
 	// lingo/lingo-object.cpp




More information about the Scummvm-git-logs mailing list