[Scummvm-git-logs] scummvm master -> 95f6d7a22765752ec0c4fc1066fbb2a48f9cf0b9

sev- noreply at scummvm.org
Fri Mar 24 20:27:41 UTC 2023


This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
13912538f4 DIRECTOR: Add 'markers' command to debugger
d2d8dc3935 DIRECTOR: Add quirk for Eastern Mind to limit score FPS
6db1f878ef DIRECTOR: Add cast action scripts to debug output
14c7756d06 GRAPHICS: MACGUI: Fix edge cases of getMouseWord
156cb87a33 DIRECTOR: Fix linked bitmap cast members
95f6d7a227 DIRECTOR: Improve handling of external bitmap palettes


Commit: 13912538f41e763bb5f703994d91d5d4e68253ee
    https://github.com/scummvm/scummvm/commit/13912538f41e763bb5f703994d91d5d4e68253ee
Author: Scott Percival (code at moral.net.au)
Date: 2023-03-24T21:27:34+01:00

Commit Message:
DIRECTOR: Add 'markers' command to debugger

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


diff --git a/engines/director/debugger.cpp b/engines/director/debugger.cpp
index 1fa8b6552fe..17fffd89b03 100644
--- a/engines/director/debugger.cpp
+++ b/engines/director/debugger.cpp
@@ -74,6 +74,8 @@ Debugger::Debugger(): GUI::Debugger() {
 	registerCmd("da", WRAP_METHOD(Debugger, cmdDisasm));
 	registerCmd("var", WRAP_METHOD(Debugger, cmdVar));
 	registerCmd("v", WRAP_METHOD(Debugger, cmdVar));
+	registerCmd("markers", WRAP_METHOD(Debugger, cmdMarkers));
+	registerCmd("mk", WRAP_METHOD(Debugger, cmdMarkers));
 	registerCmd("step", WRAP_METHOD(Debugger, cmdStep));
 	registerCmd("s", WRAP_METHOD(Debugger, cmdStep));
 	registerCmd("next", WRAP_METHOD(Debugger, cmdNext));
@@ -161,6 +163,7 @@ bool Debugger::cmdHelp(int argc, const char **argv) {
 	debugPrintf(" scriptframe / sf - Prints the current script frame\n");
 	debugPrintf(" funcs - Lists all of the functions available in the current script frame\n");
 	debugPrintf(" var / v - Lists all of the variables available in the current script frame\n");
+	debugPrintf(" markers / mk - Lists all of the frame markers in the current score\n");
 	debugPrintf(" step / s [n] - Steps forward one or more operations\n");
 	debugPrintf(" next / n [n] - Steps forward one or more operations, skips over calls\n");
 	debugPrintf(" finish / fin - Steps until the current stack frame returns\n");
@@ -516,6 +519,19 @@ bool Debugger::cmdVar(int argc, const char **argv) {
 	return true;
 }
 
+bool Debugger::cmdMarkers(int argc, const char **argv) {
+	Score *score = g_director->getCurrentMovie()->getScore();
+	if (score->_labels && score->_labels->size()) {
+		debugPrintf("Score markers:\n");
+		for (auto &it : *score->_labels) {
+			debugPrintf("\"%s\" -> %d", it->name.c_str(), it->number);
+		}
+	} else {
+		debugPrintf("No score markers found.\n");
+	}
+	return true;
+}
+
 bool Debugger::cmdStep(int argc, const char **argv) {
 	_step = true;
 	if (argc == 2 && atoi(argv[1]) > 0) {
diff --git a/engines/director/debugger.h b/engines/director/debugger.h
index 447527cee01..3242213ddbe 100644
--- a/engines/director/debugger.h
+++ b/engines/director/debugger.h
@@ -140,6 +140,7 @@ private:
 	bool cmdScriptFrame(int argc, const char **argv);
 	bool cmdFuncs(int argc, const char **argv);
 	bool cmdVar(int argc, const char **argv);
+	bool cmdMarkers(int argc, const char **argv);
 	bool cmdStep(int argc, const char **argv);
 	bool cmdNext(int argc, const char **argv);
 	bool cmdFinish(int argc, const char **argv);


Commit: d2d8dc39353137d9d718e30e6a22c52c1dd02207
    https://github.com/scummvm/scummvm/commit/d2d8dc39353137d9d718e30e6a22c52c1dd02207
Author: Scott Percival (code at moral.net.au)
Date: 2023-03-24T21:27:34+01:00

Commit Message:
DIRECTOR: Add quirk for Eastern Mind to limit score FPS

Changed paths:
    engines/director/director.cpp
    engines/director/director.h
    engines/director/game-quirks.cpp
    engines/director/score.cpp


diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index b63859700d0..312c9088e1b 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -95,6 +95,8 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
 	_wmWidth = 1024;
 	_wmHeight = 768;
 
+	_fpsLimit = 0;
+
 	_wm = nullptr;
 
 	_gameDataDir = Common::FSNode(ConfMan.get("path"));
diff --git a/engines/director/director.h b/engines/director/director.h
index 8866e9e6584..a52fcf64199 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -262,6 +262,7 @@ public:
 	uint32 _wmMode;
 	uint16 _wmWidth;
 	uint16 _wmHeight;
+	byte _fpsLimit;
 
 private:
 	byte _currentPalette[768];
diff --git a/engines/director/game-quirks.cpp b/engines/director/game-quirks.cpp
index 01dd439e63c..ed35530b017 100644
--- a/engines/director/game-quirks.cpp
+++ b/engines/director/game-quirks.cpp
@@ -76,6 +76,9 @@ struct CachedFile {
 	{ nullptr, Common::kPlatformUnknown, nullptr, nullptr, 0 }
 };
 
+static void quirkLimit15FPS() {
+	g_director->_fpsLimit = 15;
+}
 
 static void quirk640x480Desktop() {
     g_director->_wmMode &= ~Graphics::kWMModeNoDesktop;
@@ -129,9 +132,16 @@ struct Quirk {
 	Common::Platform platform;
 	void (*quirk)();
 } quirks[] = {
+	// Eastern Mind sets the score to play back at a high frame rate,
+	// however the developers were using slow hardware, so some 
+	// animations play back much faster than intended.
+	// Limit the score framerate to be no higher than 15fps.
+	{ "easternmind", Common::kPlatformMacintosh, &quirkLimit15FPS },
+	{ "easternmind", Common::kPlatformWindows, &quirkLimit15FPS },
+
 	// Rodem expects to be able to track the mouse cursor outside the
 	// window, which is impossible in ScummVM. Giving it a virtual
-	// desktop allows it to work like it would ahve on the original OS.
+	// desktop allows it to work like it would have on the original OS.
 	{ "henachoco05", Common::kPlatformMacintosh, &quirk640x480Desktop },
 	{ "henachoco05", Common::kPlatformWindows, &quirk640x480Desktop },
     // Kids Box opens with a 320x150 splash screen before switching to
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 70e68ae3d7e..82bc313a770 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -466,6 +466,8 @@ void Score::update() {
 		} else if (tempo <= 120) {
 			// FPS
 			_currentFrameRate = tempo;
+			if (g_director->_fpsLimit)
+				_currentFrameRate = MIN(g_director->_fpsLimit, _currentFrameRate);
 			_nextFrameTime = g_system->getMillis() + 1000.0 / (float)_currentFrameRate;
 			debugC(5, kDebugLoading, "Score::update(): setting _nextFrameTime to %d based on a framerate of %d", _nextFrameTime, tempo);
 		} else {


Commit: 6db1f878ef4a19ef7218088f23a77f52ed033d50
    https://github.com/scummvm/scummvm/commit/6db1f878ef4a19ef7218088f23a77f52ed033d50
Author: Scott Percival (code at moral.net.au)
Date: 2023-03-24T21:27:34+01:00

Commit Message:
DIRECTOR: Add cast action scripts to debug output

Changed paths:
    engines/director/cast.cpp
    engines/director/castmember.cpp
    engines/director/lingo/xlibs/spacemgr.cpp
    engines/director/util.cpp
    engines/director/util.h


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index f07de9428bd..bb807064bcc 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -1587,8 +1587,12 @@ Common::String Cast::formatCastSummary(int castId = -1) {
 			castMemberInfo ? castMemberInfo->name.c_str() : ""
 		);
 
-		if (castMemberInfo && !castMemberInfo->fileName.empty())
-			result += ", filename=\"" + castMemberInfo->directory + g_director->_dirSeparator + castMemberInfo->fileName + "\"";
+		if (castMemberInfo) {
+			if (!castMemberInfo->fileName.empty())
+				result += ", filename=\"" + castMemberInfo->directory + g_director->_dirSeparator + castMemberInfo->fileName + "\"";
+			if (!castMemberInfo->script.empty())
+				result += ", script=\"" + formatStringForDump(castMemberInfo->script) + "\"";
+		}
 
 		if (!info.empty()) {
 			result += ", ";
diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index ff1b94adab8..e0d8d3391bc 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -1440,11 +1440,7 @@ void TextCastMember::updateFromWidget(Graphics::MacWidget *widget) {
 }
 
 Common::String TextCastMember::formatInfo() {
-	Common::String format = _ptext.encode();
-	for (int i = 0; i < (int)format.size(); i++) {
-		if (format[i] == '\r')
-			format.replace(i, 1, "\n");
-	}
+	Common::String format = formatStringForDump(_ptext.encode());
 
 	return Common::String::format(
 		"initialRect: %dx%d@%d,%d, boundingRect: %dx%d@%d,%d, foreColor: %d, backColor: %d, editable: %d, text: \"%s\"",
diff --git a/engines/director/lingo/xlibs/spacemgr.cpp b/engines/director/lingo/xlibs/spacemgr.cpp
index 1612728e2ba..b861eddf7b9 100644
--- a/engines/director/lingo/xlibs/spacemgr.cpp
+++ b/engines/director/lingo/xlibs/spacemgr.cpp
@@ -26,6 +26,7 @@
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-object.h"
 #include "director/lingo/xlibs/spacemgr.h"
+#include "director/util.h"
 
 namespace Director {
 
@@ -226,12 +227,7 @@ void SpaceMgr::m_parseText(int nargs) {
 
 	Common::String result = *text.u.s;
 	if (debugLevelSet(5)) {
-		Common::String format = result;
-		for (int i = 0; i < (int)format.size(); i++) {
-			if (format[i] == '\r')
-				format.replace(i, 1, "\n");
-		}
-		debugC(5, kDebugXObj, "SpaceMgr::m_parseText:\n%s", format.c_str());
+		debugC(5, kDebugXObj, "SpaceMgr::m_parseText:\n%s", formatStringForDump(result).c_str());
 	}
 
 	Common::StringTokenizer instructions = Common::StringTokenizer(result, "\r");
@@ -319,12 +315,7 @@ void SpaceMgr::m_getCurData(int nargs) {
 	}
 
 	if (debugLevelSet(5)) {
-		Common::String format = result;
-		for (uint i = 0; i < format.size(); i++) {
-			if (format[i] == '\r')
-				format.replace(i, 1, "\n");
-		}
-		debugC(5, kDebugXObj, "SpaceMgr::m_getCurData: %s", format.c_str());
+		debugC(5, kDebugXObj, "SpaceMgr::m_getCurData: %s", formatStringForDump(result).c_str());
 	}
 
 	g_lingo->push(Datum(result));
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index a67bcc2bd31..ba23849b3ae 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -1201,6 +1201,15 @@ Common::String decodePlatformEncoding(Common::String input) {
 	return input.decode(g_director->getPlatformEncoding());
 }
 
+Common::String formatStringForDump(const Common::String &str) {
+	Common::String format = str;
+	for (int i = 0; i < (int)format.size(); i++) {
+		if (format[i] == '\r')
+			format.replace(i, 1, "\n");
+	}
+	return format;
+}
+
 /////////////////////////////////////////////////////////////
 // String comparison order tables
 //
diff --git a/engines/director/util.h b/engines/director/util.h
index 7b739756006..8b90f30a648 100644
--- a/engines/director/util.h
+++ b/engines/director/util.h
@@ -101,6 +101,8 @@ Common::String utf8ToPrintable(const Common::String &str);
 
 Common::String decodePlatformEncoding(Common::String input);
 
+Common::String formatStringForDump(const Common::String &str);
+
 inline byte lerpByte(byte a, byte b, int alpha, int span) {
 	int ai = static_cast<int>(a);
 	int bi = static_cast<int>(b);


Commit: 14c7756d0683270d4041682e1043398c585aa783
    https://github.com/scummvm/scummvm/commit/14c7756d0683270d4041682e1043398c585aa783
Author: Scott Percival (code at moral.net.au)
Date: 2023-03-24T21:27:34+01:00

Commit Message:
GRAPHICS: MACGUI: Fix edge cases of getMouseWord

Changed paths:
    graphics/macgui/mactext.cpp


diff --git a/graphics/macgui/mactext.cpp b/graphics/macgui/mactext.cpp
index eeb084db93a..e9b705dc7a7 100644
--- a/graphics/macgui/mactext.cpp
+++ b/graphics/macgui/mactext.cpp
@@ -1996,7 +1996,9 @@ int MacText::getMouseWord(int x, int y) {
 		if (_textLines[row].chunks[j].text.empty())
 			continue;
 		cur += _textLines[row].chunks[j].text.size();
-		if (cur <= col)
+		// Avoid overflowing the word index if we run out of line;
+		// it should count as part of the last chunk
+		if ((cur <= col) && (j < _textLines[row].chunks.size() - 1))
 			index++;
 		else
 			break;


Commit: 156cb87a33fc8e099dbc99436a9cb4c27332839d
    https://github.com/scummvm/scummvm/commit/156cb87a33fc8e099dbc99436a9cb4c27332839d
Author: Scott Percival (code at moral.net.au)
Date: 2023-03-24T21:27:34+01:00

Commit Message:
DIRECTOR: Fix linked bitmap cast members

The Director editor supports importing images from a variety of image
formats, which it then converts. There is also the option for linked
bitmap cast members (i.e. using image files on the disk), which have a
much more restricted subset of formats. As of Director 4, this list
includes Windows Bitmap files, and anything supported by the Apple
Picture Viewer (i.e. any possible encoding of PICT, and JPEG images).

File extensions are ignored, so we use some basic magic number checking to
determine which ImageDecoder class to use.

Fixes viewing the manifesto pages in DEVO Presents: Adventures of the
Smart Patrol.

Changed paths:
    engines/director/cast.cpp


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index bb807064bcc..d1375ceb5e6 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -28,6 +28,7 @@
 #include "graphics/macgui/macfontmanager.h"
 #include "graphics/macgui/macwindowmanager.h"
 #include "image/bmp.h"
+#include "image/jpeg.h"
 #include "image/pict.h"
 
 #include "director/director.h"
@@ -685,21 +686,35 @@ void Cast::loadBitmapData(int key, BitmapCastMember *bitmapCast) {
 
 			Common::SeekableReadStream *file = Common::MacResManager::openFileOrDataFork(path);
 			if (file) {
-				Image::PICTDecoder *pict = new Image::PICTDecoder();
+				// Detect the filetype. Director will ignore file extensions, as do we.
+				Image::ImageDecoder *decoder = nullptr;
+				uint32 fileType = file->readUint32BE();
+				file->seek(0);
+
+				if ((fileType >> 16) == MKTAG16('B', 'M')) {
+					// Windows Bitmap file
+					decoder = new Image::BitmapDecoder();
+				} else if ((fileType == 0xffd8ffe0) || (fileType == 0xffd8ffe1) || (fileType == 0xffd8ffe2)) {
+					// JPEG file
+					decoder = new Image::JPEGDecoder();
+				} else {
+					// Well... Director allowed someone to add it, so it must be a PICT. No further questions!
+					decoder = new Image::PICTDecoder();
+				}
 
-				bool res = pict->loadStream(*file);
+				bool res = decoder->loadStream(*file);
 				delete file;
 
 				if (res) {
-					bitmapCast->_img = pict;
+					bitmapCast->_img = decoder;
 
-					const Graphics::Surface *surf = pict->getSurface();
-					bitmapCast->_size = surf->pitch * surf->h + pict->getPaletteColorCount() * 3;
+					const Graphics::Surface *surf = decoder->getSurface();
+					bitmapCast->_size = surf->pitch * surf->h + decoder->getPaletteColorCount() * 3;
 
 					delete pic;
 					return;
 				} else {
-					delete pict;
+					delete decoder;
 					warning("BUILDBOT: Cast::loadBitmapData(): wrong format for external picture '%s'", path.toString().c_str());
 				}
 			} else {


Commit: 95f6d7a22765752ec0c4fc1066fbb2a48f9cf0b9
    https://github.com/scummvm/scummvm/commit/95f6d7a22765752ec0c4fc1066fbb2a48f9cf0b9
Author: Scott Percival (code at moral.net.au)
Date: 2023-03-24T21:27:34+01:00

Commit Message:
DIRECTOR: Improve handling of external bitmap palettes

When loading bitmap cast members from a file, Director will keep an
copy of what palette the image uses. However the order of colours in
the image's own palette can be completely different!

It appears that at load time, Director will remap all of the colours in
the image to match the order in the palette cast member. As such, we can
force a remapping for those external cast members using the existing
dither code.

Fixes the colours in Cat The Ripper.

Changed paths:
    engines/director/cast.cpp
    engines/director/castmember.cpp
    engines/director/castmember.h


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index d1375ceb5e6..cd40c822d9a 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -707,10 +707,17 @@ void Cast::loadBitmapData(int key, BitmapCastMember *bitmapCast) {
 
 				if (res) {
 					bitmapCast->_img = decoder;
+					bitmapCast->_external = true;
 
 					const Graphics::Surface *surf = decoder->getSurface();
-					bitmapCast->_size = surf->pitch * surf->h + decoder->getPaletteColorCount() * 3;
-
+					if (decoder->hasPalette()) {
+						bitmapCast->_size = surf->pitch * surf->h + decoder->getPaletteColorCount() * 3;
+						// For BMPs this sometimes gets set to 16 in the cast record,
+						// we should go with what the target image has.
+						bitmapCast->_bitsPerPixel = 8;
+					}
+
+					debugC(5, kDebugImages, "Cast::loadBitmapData(): Bitmap: id: %d, w: %d, h: %d, flags1: %x, flags2: %x bytes: %x, bpp: %d clut: %x", imgId, surf->w, surf->h, bitmapCast->_flags1, bitmapCast->_flags2, bitmapCast->_bytes, bitmapCast->_bitsPerPixel, bitmapCast->_clut);
 					delete pic;
 					return;
 				} else {
diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index e0d8d3391bc..afb9846075d 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -105,6 +105,7 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableRe
 	_clut = 0;
 	_ditheredTargetClut = 0;
 	_bitsPerPixel = 0;
+	_external = false;
 
 	if (version < kFileVer400) {
 		_flags1 = flags1;	// region: 0 - auto, 1 - matte, 2 - disabled
@@ -221,6 +222,7 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Image::ImageDecode
 	_flags1 = flags1;
 	_flags2 = 0;
 	_tag = 0;
+	_external = false;
 }
 
 BitmapCastMember::~BitmapCastMember() {
@@ -320,14 +322,20 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
 				break;
 			// 8bpp - if using a different palette, and we're not doing a color cycling operation, convert using nearest colour matching
 			case 8:
-				// Only redither 8-bit images if we have the flag set
-				if (!movie->_remapPalettesWhenNeeded)
+				// Only redither 8-bit images if we have the flag set, or it is external
+				if (!movie->_remapPalettesWhenNeeded && !_external)
 					break;
-				if (castPaletteId != currentPaletteId && !isColorCycling) {
+				if (_external || (castPaletteId != currentPaletteId && !isColorCycling)) {
 					const auto pals = g_director->getLoadedPalettes();
 					int palIndex = pals.contains(castPaletteId) ? castPaletteId : kClutSystemMac;
 					const PaletteV4 &srcPal = pals.getVal(palIndex);
-					_ditheredImg = _img->getSurface()->convertTo(g_director->_wm->_pixelformat, srcPal.palette, srcPal.length, currentPalette->palette, currentPalette->length, Graphics::kDitherNaive);
+
+					// If it is an external image, use the included palette.
+					// For BMP images especially, they'll often have the right colors
+					// but in the wrong palette order.
+					const byte *palPtr = _external ? pal : srcPal.palette;
+					int palLength = _external ? _img->getPaletteColorCount() * 3 : srcPal.length;
+					_ditheredImg = _img->getSurface()->convertTo(g_director->_wm->_pixelformat, palPtr, palLength, currentPalette->palette, currentPalette->length, Graphics::kDitherNaive);
 				}
 				break;
 			default:
@@ -339,14 +347,16 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
 				// Save the palette ID so we can check if a redraw is required
 				_ditheredTargetClut = currentPaletteId;
 
-				// Finally, the first and last colours in the palette are special. No matter what the palette remap
-				// does, we need to scrub those to be the same.
-				const Graphics::Surface *src = _img->getSurface();
-				for (int y = 0; y < src->h; y++) {
-					for (int x = 0; x < src->w; x++) {
-						const int test = *(const byte *)src->getBasePtr(x, y);
-						if (test == 0 || test == (1 << _bitsPerPixel) - 1) {
-							*(byte *)_ditheredImg->getBasePtr(x, y) = test == 0 ? 0x00 : 0xff;
+				if (!_external) {
+					// Finally, the first and last colours in the palette are special. No matter what the palette remap
+					// does, we need to scrub those to be the same.
+					const Graphics::Surface *src = _img->getSurface();
+					for (int y = 0; y < src->h; y++) {
+						for (int x = 0; x < src->w; x++) {
+							const int test = *(const byte *)src->getBasePtr(x, y);
+							if (test == 0 || test == (1 << _bitsPerPixel) - 1) {
+								*(byte *)_ditheredImg->getBasePtr(x, y) = test == 0 ? 0x00 : 0xff;
+							}
 						}
 					}
 				}
diff --git a/engines/director/castmember.h b/engines/director/castmember.h
index 161e83766dd..63f356adaf1 100644
--- a/engines/director/castmember.h
+++ b/engines/director/castmember.h
@@ -152,6 +152,7 @@ public:
 
 	uint32 _tag;
 	bool _noMatte;
+	bool _external;
 };
 
 class DigitalVideoCastMember : public CastMember {




More information about the Scummvm-git-logs mailing list