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

csnover csnover at users.noreply.github.com
Wed Nov 2 21:43:51 CET 2016


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

Summary:
a605a891bb SCI: Add reference dump to disk in debugger
c42e74c562 SCI32: Remove incorrect palette.h #include
e8c429832f SCI32: Automate kNumCels workaround
ee4b172d54 SCI: Remove old SCI32 hires detection heuristic
aa0836816d SCI32: Fix missing digital audio playback on save game restore


Commit: a605a891bb632cbe4a94ed4c762fbcdce3e7b89a
    https://github.com/scummvm/scummvm/commit/a605a891bb632cbe4a94ed4c762fbcdce3e7b89a
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-11-02T11:27:22-05:00

Commit Message:
SCI: Add reference dump to disk in debugger

This allows references in memory to be dumped to disk for
examination by other tools. In the case of SCI32 bitmaps, data
is output in 8-bit TGA format without transparency, which allows
the current palette to also be examined. (The alternative would
be to use 32-bit TGA to display transparency, and lose the
palette, or dump to a more complicated format that supports 1-bit
transparency.)

Changed paths:
    engines/sci/console.cpp
    engines/sci/console.h



diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 8737c8b..04fe0f7 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -53,6 +53,7 @@
 #ifdef ENABLE_SCI32
 #include "sci/graphics/frameout.h"
 #include "sci/graphics/paint32.h"
+#include "sci/graphics/palette32.h"
 #include "video/coktel_decoder.h"
 #endif
 
@@ -228,6 +229,8 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
 	registerCmd("view_listnode",		WRAP_METHOD(Console, cmdViewListNode));
 	registerCmd("view_reference",		WRAP_METHOD(Console, cmdViewReference));
 	registerCmd("vr",					WRAP_METHOD(Console, cmdViewReference));			// alias
+	registerCmd("dump_reference",		WRAP_METHOD(Console, cmdDumpReference));
+	registerCmd("dr",					WRAP_METHOD(Console, cmdDumpReference));			// alias
 	registerCmd("view_object",		WRAP_METHOD(Console, cmdViewObject));
 	registerCmd("vo",					WRAP_METHOD(Console, cmdViewObject));				// alias
 	registerCmd("active_object",		WRAP_METHOD(Console, cmdViewActiveObject));
@@ -446,6 +449,7 @@ bool Console::cmdHelp(int argc, const char **argv) {
 	debugPrintf(" value_type - Determines the type of a value\n");
 	debugPrintf(" view_listnode - Examines the list node at the given address\n");
 	debugPrintf(" view_reference / vr - Examines an arbitrary reference\n");
+	debugPrintf(" dump_reference / dr - Dumps an arbitrary reference to disk\n");
 	debugPrintf(" view_object / vo - Examines the object at the given address\n");
 	debugPrintf(" active_object - Shows information on the currently active object or class\n");
 	debugPrintf(" acc_object - Shows information on the object or class at the address indexed by the accumulator\n");
@@ -2843,6 +2847,125 @@ bool Console::cmdViewReference(int argc, const char **argv) {
 	return true;
 }
 
+bool Console::cmdDumpReference(int argc, const char **argv) {
+	if (argc < 2) {
+		debugPrintf("Dumps an arbitrary reference to disk.\n");
+		debugPrintf("Usage: %s <start address> [<end address>]\n", argv[0]);
+		debugPrintf("Where <start address> is the starting address to dump\n");
+		debugPrintf("<end address>, if provided, is the address where the dump ends\n");
+		debugPrintf("Check the \"addresses\" command on how to use addresses\n");
+		return true;
+	}
+
+	reg_t reg = NULL_REG;
+	reg_t reg_end = NULL_REG;
+
+	if (parse_reg_t(_engine->_gamestate, argv[1], &reg, false)) {
+		debugPrintf("Invalid address passed.\n");
+		debugPrintf("Check the \"addresses\" command on how to use addresses\n");
+		return true;
+	}
+
+	if (argc > 2) {
+		if (parse_reg_t(_engine->_gamestate, argv[2], &reg_end, false)) {
+			debugPrintf("Invalid address passed.\n");
+			debugPrintf("Check the \"addresses\" command on how to use addresses\n");
+			return true;
+		}
+	}
+
+	if (reg.getSegment() == 0 && reg.getOffset() == 0) {
+		debugPrintf("Register is null.\n");
+		return true;
+	}
+
+	if (g_sci->getKernel()->findRegType(reg) != SIG_TYPE_REFERENCE) {
+		debugPrintf("%04x:%04x is not a reference\n", PRINT_REG(reg));
+		return true;
+	}
+
+	if (reg_end.getSegment() != reg.getSegment() && reg_end != NULL_REG) {
+		debugPrintf("Ending segment different from starting segment. Assuming no bound on dump.\n");
+		reg_end = NULL_REG;
+	}
+
+	Common::DumpFile out;
+	Common::String outFileName;
+	uint32 bytesWritten;
+
+	switch (_engine->_gamestate->_segMan->getSegmentType(reg.getSegment())) {
+#ifdef ENABLE_SCI32
+	case SEG_TYPE_BITMAP: {
+		outFileName = Common::String::format("%04x_%04x.tga", PRINT_REG(reg));
+		out.open(outFileName);
+		SciBitmap &bitmap = *_engine->_gamestate->_segMan->lookupBitmap(reg);
+		const Color *color = g_sci->_gfxPalette32->getCurrentPalette().colors;
+		const uint16 numColors = ARRAYSIZE(g_sci->_gfxPalette32->getCurrentPalette().colors);
+
+		out.writeByte(0); // image id length
+		out.writeByte(1); // color map type (present)
+		out.writeByte(1); // image type (uncompressed color-mapped)
+		out.writeSint16LE(0);         // index of first color map entry
+		out.writeSint16LE(numColors); // number of color map entries
+		out.writeByte(24);            // number of bits per color entry (RGB24)
+		out.writeSint16LE(0);                      // bottom-left x-origin
+		out.writeSint16LE(bitmap.getHeight() - 1); // bottom-left y-origin
+		out.writeSint16LE(bitmap.getWidth());  // width
+		out.writeSint16LE(bitmap.getHeight()); // height
+		out.writeByte(8); // bits per pixel
+		out.writeByte(1 << 5); // origin of pixel data (top-left)
+
+		bytesWritten = 18;
+
+		for (int i = 0; i < numColors; ++i) {
+			out.writeByte(color->b);
+			out.writeByte(color->g);
+			out.writeByte(color->r);
+			++color;
+		}
+
+		bytesWritten += numColors * 3;
+		bytesWritten += out.write(bitmap.getPixels(), bitmap.getWidth() * bitmap.getHeight());
+		break;
+	}
+#endif
+
+	default: {
+		const SegmentRef block = _engine->_gamestate->_segMan->dereference(reg);
+		uint32 size = block.maxSize;
+
+		if (size == 0) {
+			debugPrintf("Size of reference is zero.\n");
+			return true;
+		}
+
+		if (reg_end.getSegment() != 0 && (size < reg_end.getOffset() - reg.getOffset())) {
+			debugPrintf("Block end out of bounds (size %d). Resetting.\n", size);
+			reg_end = NULL_REG;
+		}
+
+		if (reg_end.getSegment() != 0 && (size >= reg_end.getOffset() - reg.getOffset())) {
+			size = reg_end.getOffset() - reg.getOffset();
+		}
+
+		if (reg_end.getSegment() != 0) {
+			debugPrintf("Block size less than or equal to %d\n", size);
+		}
+
+		outFileName = Common::String::format("%04x_%04x.dmp", PRINT_REG(reg));
+		out.open(outFileName);
+		bytesWritten = out.write(block.raw, size);
+		break;
+	}
+	}
+
+	out.finalize();
+	out.close();
+
+	debugPrintf("Wrote %u bytes to %s\n", bytesWritten, outFileName.c_str());
+	return true;
+}
+
 bool Console::cmdViewObject(int argc, const char **argv) {
 	if (argc != 2) {
 		debugPrintf("Examines the object at the given address.\n");
diff --git a/engines/sci/console.h b/engines/sci/console.h
index 0b87a44..d4b17ee 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -163,6 +163,7 @@ private:
 	bool cmdValueType(int argc, const char **argv);
 	bool cmdViewListNode(int argc, const char **argv);
 	bool cmdViewReference(int argc, const char **argv);
+	bool cmdDumpReference(int argc, const char **argv);
 	bool cmdViewObject(int argc, const char **argv);
 	bool cmdViewActiveObject(int argc, const char **argv);
 	bool cmdViewAccumulatorObject(int argc, const char **argv);


Commit: c42e74c562c3a55cb72901e8ecb56da600bfcb42
    https://github.com/scummvm/scummvm/commit/c42e74c562c3a55cb72901e8ecb56da600bfcb42
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-11-02T11:27:22-05:00

Commit Message:
SCI32: Remove incorrect palette.h #include

Changed paths:
    engines/sci/graphics/palette32.h



diff --git a/engines/sci/graphics/palette32.h b/engines/sci/graphics/palette32.h
index 81e9bbb..c4cfb35 100644
--- a/engines/sci/graphics/palette32.h
+++ b/engines/sci/graphics/palette32.h
@@ -23,7 +23,6 @@
 #ifndef SCI_GRAPHICS_PALETTE32_H
 #define SCI_GRAPHICS_PALETTE32_H
 
-#include "sci/graphics/palette.h"
 namespace Sci {
 
 #pragma mark HunkPalette


Commit: e8c429832f7b6393f853fd6d9ce8ba2e62f6a93c
    https://github.com/scummvm/scummvm/commit/e8c429832f7b6393f853fd6d9ce8ba2e62f6a93c
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-11-02T15:43:07-05:00

Commit Message:
SCI32: Automate kNumCels workaround

Changed paths:
    engines/sci/engine/workarounds.cpp
    engines/sci/engine/workarounds.h
    engines/sci/graphics/celobj32.cpp



diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index dabf79a..52c5c33 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -684,21 +684,6 @@ const SciWorkaroundEntry kNewWindow_workarounds[] = {
 };
 
 //    gameID,           room,script,lvl,          object-name, method-name, local-call-signature, index,                workaround
-const SciWorkaroundEntry kNumCels_workarounds[] = {
-	{ GID_GK1,           460, 64998, -1,              "GKEgo", "lastCel",                   NULL,    -1, { WORKAROUND_FAKE, 5 } }, // when Gabriel clicks "ask" on the bartender from a distance
-	{ GID_GK1,           808, 64998, -1,          "sDJEnters", "changeState",               NULL,    -1, { WORKAROUND_FAKE, 6 } }, //
-	{ GID_GK2,           470, 64998, -1,        "pLookieLoos", "lastCel",                   NULL,    -1, { WORKAROUND_FAKE, 50 } }, // random background movement in the crime scene in Munich city centre
-	{ GID_GK2,           470, 64998, -1,          "pNewsCrew", "lastCel",                   NULL,    -1, { WORKAROUND_FAKE, 18 } }, // random background movement in the crime scene in Munich city centre
-	{ GID_GK2,           470, 64998, -1,        "pLeberGroup", "lastCel",                   NULL,    -1, { WORKAROUND_FAKE, 22 } }, // random background movement in the crime scene in Munich city centre
-	{ GID_SQ6,           270, 64998, -1,           "offWorld", "lastCel",                   NULL,    -1, { WORKAROUND_FAKE, 3 } }, // when exiting the kidnapping room
-	{ GID_SQ6,           320, 64998, -1,          "wandererB", "lastCel",                   NULL,    -1, { WORKAROUND_FAKE, 8 } }, // random background movement on Polysorbate LX street 3
-	{ GID_SQ6,           340, 64998, -1,          "wandererB", "lastCel",                   NULL,    -1, { WORKAROUND_FAKE, 8 } }, // random background movement on Polysorbate LX street 1
-	{ GID_SQ6,           530, 64998, -1,           "monitors", "lastCel",                   NULL,    -1, { WORKAROUND_FAKE, 5 } }, // random background movement during cutscene
-	{ GID_SQ6,           680, 64998, -1,                "ego", "lastCel",                   NULL,    -1, { WORKAROUND_FAKE, 44 } }, // when double-clicking hand icon on blockage
-	SCI_WORKAROUNDENTRY_TERMINATOR
-};
-
-//    gameID,           room,script,lvl,          object-name, method-name, local-call-signature, index,                workaround
 const SciWorkaroundEntry kPalVarySetPercent_workarounds[] = {
 	{ GID_GK1,           370,   370,  0,        "graceComeOut", "changeState",              NULL,     0, { WORKAROUND_STILLCALL, 0 } }, // there's an extra parameter in GK1, when changing chapters. This extra parameter seems to be a bug or just unimplemented functionality, as there's no visible change from the original in the chapter change room
 	SCI_WORKAROUNDENTRY_TERMINATOR
diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h
index c50a7fb..2d72ae5 100644
--- a/engines/sci/engine/workarounds.h
+++ b/engines/sci/engine/workarounds.h
@@ -85,7 +85,6 @@ extern const SciWorkaroundEntry kIsObject_workarounds[];
 extern const SciWorkaroundEntry kMemory_workarounds[];
 extern const SciWorkaroundEntry kMoveCursor_workarounds[];
 extern const SciWorkaroundEntry kNewWindow_workarounds[];
-extern const SciWorkaroundEntry kNumCels_workarounds[];
 extern const SciWorkaroundEntry kPalVarySetPercent_workarounds[];
 extern const SciWorkaroundEntry kRandom_workarounds[];
 extern const SciWorkaroundEntry kReadNumber_workarounds[];
diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp
index 430500c..09ea05b 100644
--- a/engines/sci/graphics/celobj32.cpp
+++ b/engines/sci/graphics/celobj32.cpp
@@ -800,7 +800,7 @@ int16 CelObjView::getNumLoops(const GuiResourceId viewId) {
 	return resource->data[2];
 }
 
-int16 CelObjView::getNumCels(const GuiResourceId viewId, const int16 loopNo) {
+int16 CelObjView::getNumCels(const GuiResourceId viewId, int16 loopNo) {
 	const Resource *const resource = g_sci->getResMan()->findResource(ResourceId(kResourceTypeView, viewId), false);
 
 	if (!resource) {
@@ -813,25 +813,15 @@ int16 CelObjView::getNumCels(const GuiResourceId viewId, const int16 loopNo) {
 
 	// Every version of SCI32 has a logic error in this function that causes
 	// random memory to be read if a script requests the cel count for one
-	// past the maximum loop index. At least GK1 room 800 does this, and gets
-	// stuck in an infinite loop because the game script expects this method
-	// to return a non-zero value.
-	// The scope of this bug means it is likely to pop up in other games, so we
-	// explicitly trap the bad condition here and report it so that any other
-	// game scripts relying on this broken behavior can be fixed as well
+	// past the maximum loop index. For example, GK1 room 808 does this, and
+	// gets stuck in an infinite loop because the game script expects this
+	// method to return a non-zero value.
+	// This bug is triggered in basically every SCI32 game and appears to be
+	// universally fixable simply by always using the next lowest loop instead.
 	if (loopNo == loopCount) {
-		SciCallOrigin origin;
-		SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, kNumCels_workarounds, &origin);
-		switch (solution.type) {
-		case WORKAROUND_NONE:
-			error("[CelObjView::getNumCels]: loop number %d is equal to loop count in view %u, %s", loopNo, viewId, origin.toString().c_str());
-		case WORKAROUND_FAKE:
-			return (int16)solution.value;
-		case WORKAROUND_IGNORE:
-			return 0;
-		case WORKAROUND_STILLCALL:
-			break;
-		}
+		const SciCallOrigin origin = g_sci->getEngineState()->getCurrentCallOrigin();
+		debugC(kDebugLevelWorkarounds, "Workaround: kNumCels loop %d -> loop %d in view %u, %s", loopNo, loopNo - 1, viewId, origin.toString().c_str());
+		--loopNo;
 	}
 
 	if (loopNo > loopCount || loopNo < 0) {


Commit: ee4b172d54ee3a428438d8e48da77044e9822935
    https://github.com/scummvm/scummvm/commit/ee4b172d54ee3a428438d8e48da77044e9822935
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-11-02T15:43:07-05:00

Commit Message:
SCI: Remove old SCI32 hires detection heuristic

Changed paths:
    engines/sci/graphics/screen.cpp
    engines/sci/resource.cpp
    engines/sci/resource.h



diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index 23e92ef..de6df39 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -84,11 +84,6 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
 		}
 	}
 
-	if (_resMan->detectHires()) {
-		_scriptWidth = 640;
-		_scriptHeight = 480;
-	}
-
 	// if not yet set, set those to script-width/height
 	if (!_width)
 		_width = _scriptWidth;
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 8826b06..5b57eed 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -2459,38 +2459,6 @@ void ResourceManager::detectSciVersion() {
 	}
 }
 
-bool ResourceManager::detectHires() {
-	// SCI 1.1 and prior is never hires
-	if (getSciVersion() <= SCI_VERSION_1_1)
-		return false;
-
-#ifdef ENABLE_SCI32
-	for (int i = 0; i < 32768; i++) {
-		Resource *res = findResource(ResourceId(kResourceTypePic, i), 0);
-
-		if (res) {
-			if (READ_SCI11ENDIAN_UINT16(res->data) == 0x0e) {
-				// SCI32 picture
-				uint16 width = READ_SCI11ENDIAN_UINT16(res->data + 10);
-				uint16 height = READ_SCI11ENDIAN_UINT16(res->data + 12);
-				// Surely lowres (e.g. QFG4CD)
-				if ((width == 320) && ((height == 190) || (height == 200)))
-					return false;
-				// Surely hires
-				if ((width >= 600) || (height >= 400))
-					return true;
-			}
-		}
-	}
-
-	// We haven't been able to find hires content
-
-	return false;
-#else
-	error("no sci32 support");
-#endif
-}
-
 bool ResourceManager::detectFontExtended() {
 
 	Resource *res = findResource(ResourceId(kResourceTypeFont, 0), 0);
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 70db590..928d571 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -424,7 +424,6 @@ private:
 public:
 #endif
 
-	bool detectHires();
 	// Detects, if standard font of current game includes extended characters (>0x80)
 	bool detectFontExtended();
 	// Detects, if SCI1.1 game uses palette merging


Commit: aa0836816d04812838654f563f7c29cb8efb7041
    https://github.com/scummvm/scummvm/commit/aa0836816d04812838654f563f7c29cb8efb7041
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-11-02T15:43:07-05:00

Commit Message:
SCI32: Fix missing digital audio playback on save game restore

Fixes Trac#9581.

Changed paths:
    engines/sci/engine/savegame.cpp



diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 2e4da46..720f678 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -643,20 +643,33 @@ void SoundCommandParser::reconstructPlayList() {
 	_music->_mutex.unlock();
 
 	for (MusicList::iterator i = songs.begin(); i != songs.end(); ++i) {
-		initSoundResource(*i);
+		MusicEntry *entry = *i;
+		initSoundResource(entry);
 
-		if ((*i)->status == kSoundPlaying) {
+#ifdef ENABLE_SCI32
+		if (_soundVersion >= SCI_VERSION_2_1_EARLY && entry->isSample) {
+			const reg_t &soundObj = entry->soundObj;
+
+			if ((int)readSelectorValue(_segMan, soundObj, SELECTOR(loop)) != -1 &&
+				readSelector(_segMan, soundObj, SELECTOR(handle)) != NULL_REG) {
+
+				writeSelector(_segMan, soundObj, SELECTOR(handle), NULL_REG);
+				processPlaySound(soundObj, entry->playBed);
+			}
+		} else
+#endif
+		if (entry->status == kSoundPlaying) {
 			// WORKAROUND: PQ3 (German?) scripts can set volume negative in the
 			// sound object directly without going through DoSound.
 			// Since we re-read this selector when re-playing the sound after loading,
 			// this will lead to unexpected behaviour. As a workaround we
 			// sync the sound object's selectors here. (See bug #5501)
-			writeSelectorValue(_segMan, (*i)->soundObj, SELECTOR(loop), (*i)->loop);
-			writeSelectorValue(_segMan, (*i)->soundObj, SELECTOR(priority), (*i)->priority);
+			writeSelectorValue(_segMan, entry->soundObj, SELECTOR(loop), entry->loop);
+			writeSelectorValue(_segMan, entry->soundObj, SELECTOR(priority), entry->priority);
 			if (_soundVersion >= SCI_VERSION_1_EARLY)
-				writeSelectorValue(_segMan, (*i)->soundObj, SELECTOR(vol), (*i)->volume);
+				writeSelectorValue(_segMan, entry->soundObj, SELECTOR(vol), entry->volume);
 
-			processPlaySound((*i)->soundObj, (*i)->playBed);
+			processPlaySound(entry->soundObj, entry->playBed);
 		}
 	}
 }





More information about the Scummvm-git-logs mailing list