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

csnover csnover at users.noreply.github.com
Sun Apr 23 02:44:20 CEST 2017


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

Summary:
ecc446da84 SCI: Accept 32-bit values to reg_t::incOffset
c6cf7215f0 SCI32: Fix kStringFormat signatures
ede7976ede SCI32: Fix bad kPointSize implementation
8105984703 SCI32: Fix broken final step of 2.1mid+ pixel dissolve
848bce47e1 SCI: Fix typo in debug message
41c633f0c5 SCI: Fix whitespace errors
8817e8e3bf SCI: Explicitly label slot 0 as the autosave slot in the ScummVM UI
6c44106083 SCI32: Add workarounds & patches for QFG4
2ccef4a476 SCI32: Implement support for QFG4 autosave
086fab741a SCI: Remove #undef for a macro that does not exist
3ab1f5f4cc SCI: Display class names in disassembly
8a5eb0c784 SCI32: Fix dumb typo in CelInfo32::toString
f6c4e0c7c7 SCI: Improve message when crashing due to a bad selector
5231541e7c SCI32: Add and divide instead of performing two divisions
092a809c78 SCI32: Fix bad interpolation of Robot audio samples
16fe6d3cb1 SCI32: Store handle to VMD bitmap separately from ScreenItem
78fd8d39c5 SCI32: Disable brightness boost when black-lined video is disabled
9e7c75cc79 SCI: Avoid crashing when disassembling a call with a bad object
fcaf15aa50 SCI: Add alloc_list command to debugger


Commit: ecc446da841c2dc1fba0c36117159d031302ea85
    https://github.com/scummvm/scummvm/commit/ecc446da841c2dc1fba0c36117159d031302ea85
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T18:53:40-05:00

Commit Message:
SCI: Accept 32-bit values to reg_t::incOffset

This fixes bad variable relocation in Phant2 causing the game to
crash when reading object names.

Changed paths:
    engines/sci/engine/vm_types.h


diff --git a/engines/sci/engine/vm_types.h b/engines/sci/engine/vm_types.h
index 734f4d3..c3922b2 100644
--- a/engines/sci/engine/vm_types.h
+++ b/engines/sci/engine/vm_types.h
@@ -46,7 +46,7 @@ struct reg_t {
 	uint32 getOffset() const;
 	void setOffset(uint32 offset);
 
-	inline void incOffset(int16 offset) {
+	inline void incOffset(int32 offset) {
 		setOffset(getOffset() + offset);
 	}
 


Commit: c6cf7215f0f620dc4a155ca79510a44db13370fc
    https://github.com/scummvm/scummvm/commit/c6cf7215f0f620dc4a155ca79510a44db13370fc
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:25:20-05:00

Commit Message:
SCI32: Fix kStringFormat signatures

Changed paths:
    engines/sci/engine/kernel_tables.h


diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 7e3f4a8..77f1aa1 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -547,7 +547,7 @@ static const SciKernelMapSubEntry kString_subops[] = {
 	{ SIG_THRU_SCI21MID,   8, MAP_CALL(ArrayDuplicate),            "r",                    NULL },
 	{ SIG_THRU_SCI21MID,   9, MAP_CALL(StringGetData),             "[0or]",                NULL },
 	{ SIG_THRU_SCI21MID,  10, MAP_CALL(StringLength),              "r",                    NULL },
-	{ SIG_THRU_SCI21MID,  11, MAP_CALL(StringFormat),              "r(.*)",                NULL },
+	{ SIG_THRU_SCI21MID,  11, MAP_CALL(StringFormat),              "[ro](.*)",             NULL },
 	{ SIG_THRU_SCI21MID,  12, MAP_CALL(StringFormatAt),            "r[ro](.*)",            NULL },
 	{ SIG_THRU_SCI21MID,  13, MAP_CALL(StringToInteger),           "r",                    NULL },
 	{ SIG_THRU_SCI21MID,  14, MAP_CALL(StringTrim),                "ri(i)",                NULL },
@@ -557,8 +557,8 @@ static const SciKernelMapSubEntry kString_subops[] = {
 	{ SIG_THRU_SCI21MID,  18, MAP_CALL(StringReplaceSubstringEx),  "rrrr",                 NULL },
 
 	{ SIG_SINCE_SCI21LATE, 8, MAP_CALL(StringLength),              "r",                    NULL },
-	{ SIG_SINCE_SCI21LATE, 9, MAP_CALL(StringFormat),              "r(.*)",                NULL },
-	{ SIG_SINCE_SCI21LATE,10, MAP_CALL(StringFormatAt),            "rr(.*)",               NULL },
+	{ SIG_SINCE_SCI21LATE, 9, MAP_CALL(StringFormat),              "[ro](.*)",             NULL },
+	{ SIG_SINCE_SCI21LATE,10, MAP_CALL(StringFormatAt),            "r[ro](.*)",            NULL },
 	{ SIG_SINCE_SCI21LATE,11, MAP_CALL(StringToInteger),           "r",                    NULL },
 	{ SIG_SINCE_SCI21LATE,12, MAP_CALL(StringTrim),                "ri(i)",                NULL },
 	{ SIG_SINCE_SCI21LATE,13, MAP_CALL(StringToUpperCase),         "r",                    NULL },


Commit: ede7976ede9121d52932b4b0780e6adc68f6e35d
    https://github.com/scummvm/scummvm/commit/ede7976ede9121d52932b4b0780e6adc68f6e35d
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:25:20-05:00

Commit Message:
SCI32: Fix bad kPointSize implementation

Fixes text scaling gone mad in Phant2.

Changed paths:
    engines/sci/engine/kernel.h
    engines/sci/engine/kernel_tables.h
    engines/sci/engine/kgraphics32.cpp
    engines/sci/graphics/text32.cpp
    engines/sci/graphics/text32.h


diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 2b61a9e..c648cd0 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -651,7 +651,7 @@ reg_t kCelInfoGetPixel(EngineState *s, int argc, reg_t *argv);
 
 reg_t kSetLanguage(EngineState *s, int argc, reg_t *argv);
 reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv);
-reg_t kSetFontHeight(EngineState *s, int argc, reg_t *argv);
+reg_t kPointSize(EngineState *s, int argc, reg_t *argv);
 reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv);
 reg_t kFont(EngineState *s, int argc, reg_t *argv);
 reg_t kAddLine(EngineState *s, int argc, reg_t *argv);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 77f1aa1..fd3f4bd 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -369,7 +369,7 @@ static const SciKernelMapSubEntry kSave_subops[] = {
 
 //    version,         subId, function-mapping,                    signature,              workarounds
 static const SciKernelMapSubEntry kFont_subops[] = {
-	{ SIG_SINCE_SCI21MID,  0, MAP_CALL(SetFontHeight),             "i",                    NULL },
+	{ SIG_SINCE_SCI21MID,  0, MAP_CALL(PointSize),                 "i",                    NULL },
 	{ SIG_SINCE_SCI21MID,  1, MAP_CALL(SetFontRes),                "ii",                   NULL },
 	SCI_SUBOPENTRY_TERMINATOR
 };
@@ -937,7 +937,7 @@ static SciKernelMapEntry s_kernelMap[] = {
 	{ MAP_DUMMY(InvertRect),       SIG_THRU_SCI21EARLY, SIGFOR_ALL, "(.*)",           NULL,            NULL },
 	{ MAP_DUMMY(InputText),        SIG_EVERYWHERE,           "(.*)",                  NULL,            NULL },
 	{ MAP_CALL(TextWidth),         SIG_THRU_SCI21EARLY, SIGFOR_ALL, "ri",             NULL,            NULL },
-	{ MAP_DUMMY(PointSize),        SIG_EVERYWHERE,           "(.*)",                  NULL,            NULL },
+	{ MAP_CALL(PointSize),         SIG_THRU_SCI21EARLY, SIGFOR_ALL, "i",              NULL,            NULL },
 
 	// SCI2.1 Kernel Functions
 	{ "CheckCDisc", kCheckCD,      SIG_SCI21EARLY, SIGFOR_ALL, "(i)",                 NULL,            NULL },
@@ -1314,8 +1314,8 @@ static const char *const sci2_default_knames[] = {
 	/*0x86*/ "CheckIntegrity",	  // for debugging
 	/*0x87*/ "ObjectIntersect",
 	/*0x88*/ "MarkMemory",	      // for debugging
-	/*0x89*/ "TextWidth",		  // for debugging(?), only in SCI2, not used in any SCI2 game
-	/*0x8a*/ "PointSize",	      // for debugging(?), only in SCI2, not used in any SCI2 game
+	/*0x89*/ "TextWidth",
+	/*0x8a*/ "PointSize",
 
 	/*0x8b*/ "AddLine",
 	/*0x8c*/ "DeleteLine",
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index ae84e6b..f332e17 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -608,13 +608,9 @@ reg_t kFont(EngineState *s, int argc, reg_t *argv) {
 	error("not supposed to call this");
 }
 
-reg_t kSetFontHeight(EngineState *s, int argc, reg_t *argv) {
-	// TODO: Setting font may have just been for side effect
-	// of setting the fontHeight on the font manager, in
-	// which case we could just get the font directly ourselves.
+reg_t kPointSize(EngineState *s, int argc, reg_t *argv) {
 	g_sci->_gfxText32->setFont(argv[0].toUint16());
-	g_sci->_gfxText32->_yResolution = (g_sci->_gfxText32->_font->getHeight() * g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight + g_sci->_gfxText32->_yResolution - 1) / g_sci->_gfxText32->_yResolution;
-	return make_reg(0, g_sci->_gfxText32->_yResolution);
+	return make_reg(0, g_sci->_gfxText32->getScaledFontHeight());
 }
 
 reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv) {
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index a017a2f..7399fe0 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -216,6 +216,11 @@ void GfxText32::drawChar(const char charIndex) {
 	_drawPosition.x += _font->getCharWidth((unsigned char)charIndex);
 }
 
+int16 GfxText32::getScaledFontHeight() const {
+	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	return (_font->getHeight() * scriptHeight + _yResolution - 1) / _yResolution;
+}
+
 uint16 GfxText32::getCharWidth(const char charIndex, const bool doScaling) const {
 	uint16 width = _font->getCharWidth((unsigned char)charIndex);
 	if (doScaling) {
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index bfd5ebc..c8fafb2 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -236,6 +236,11 @@ public:
 	void setFont(const GuiResourceId fontId);
 
 	/**
+	 * Gets the pixel height of the currently loaded font.
+	 */
+	int16 getScaledFontHeight() const;
+
+	/**
 	 * Gets the width of a character.
 	 */
 	uint16 getCharWidth(const char charIndex, const bool doScaling) const;


Commit: 81059847034f0fb868e64255e341b17f8d62c591
    https://github.com/scummvm/scummvm/commit/81059847034f0fb868e64255e341b17f8d62c591
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:25:20-05:00

Commit Message:
SCI32: Fix broken final step of 2.1mid+ pixel dissolve

Changed paths:
    engines/sci/graphics/transitions32.cpp


diff --git a/engines/sci/graphics/transitions32.cpp b/engines/sci/graphics/transitions32.cpp
index bc2825b..6da1772 100644
--- a/engines/sci/graphics/transitions32.cpp
+++ b/engines/sci/graphics/transitions32.cpp
@@ -799,7 +799,7 @@ bool GfxTransitions32::processPixelDissolve21Early(PlaneShowStyle &showStyle) {
 }
 
 bool GfxTransitions32::processPixelDissolve21Mid(const PlaneShowStyle &showStyle) {
-	// SQ6 room 530
+	// SQ6 room 530, LSL7 room 130
 
 	Plane* plane = g_sci->_gfxFrameout->getVisiblePlanes().findByObject(showStyle.plane);
 	const Common::Rect &screenRect = plane->_screenRect;
@@ -869,8 +869,8 @@ bool GfxTransitions32::processPixelDissolve21Mid(const PlaneShowStyle &showStyle
 
 	rect.left = screenRect.left;
 	rect.top = screenRect.top;
-	rect.right = divisions + screenRect.left;
-	rect.bottom = divisions + screenRect.bottom;
+	rect.right = screenRect.left + divisions;
+	rect.bottom = screenRect.top + divisions;
 	addShowRect(rect);
 	sendShowRects();
 


Commit: 848bce47e18ab60137597b419a2eeb2013bfc7cc
    https://github.com/scummvm/scummvm/commit/848bce47e18ab60137597b419a2eeb2013bfc7cc
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:25:21-05:00

Commit Message:
SCI: Fix typo in debug message

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


diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 7c4c955..a7c0d87 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -93,7 +93,7 @@ reg_t kLock(EngineState *s, int argc, reg_t *argv) {
 					// Happens in CD games (e.g. LSL6CD) with the message
 					// resource. It isn't fatal, and it's usually caused
 					// by leftover scripts.
-					debugC(kDebugLevelResMan, "[resMan] Attempt to unlock non-existant resource %s", id.toString().c_str());
+					debugC(kDebugLevelResMan, "[resMan] Attempt to unlock non-existent resource %s", id.toString().c_str());
 			}
 		}
 		break;


Commit: 41c633f0c54d48cd4bec07369553985ad0caee00
    https://github.com/scummvm/scummvm/commit/41c633f0c54d48cd4bec07369553985ad0caee00
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:28:34-05:00

Commit Message:
SCI: Fix whitespace errors

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


diff --git a/engines/sci/engine/object.cpp b/engines/sci/engine/object.cpp
index 2a6c966..2c1ab2a 100644
--- a/engines/sci/engine/object.cpp
+++ b/engines/sci/engine/object.cpp
@@ -275,7 +275,7 @@ void Object::initSelectorsSci3(const SciSpan<const byte> &buf) {
 
 			_mustSetViewVisible[groupNr] = (typeMask & 1);
 
-			 for (int bit = 2; bit < 32; ++bit) {
+			for (int bit = 2; bit < 32; ++bit) {
 				int value = seeker.getUint16SEAt(bit * 2);
 				if (typeMask & (1 << bit)) { // Property
 					++properties;
@@ -284,7 +284,6 @@ void Object::initSelectorsSci3(const SciSpan<const byte> &buf) {
 				} else {
 					// Undefined selector
 				}
-
 			}
 		} else
 			_mustSetViewVisible[groupNr] = false;


Commit: 8817e8e3bfc7de80b1c7fae72f692a79055025ab
    https://github.com/scummvm/scummvm/commit/8817e8e3bfc7de80b1c7fae72f692a79055025ab
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:28:34-05:00

Commit Message:
SCI: Explicitly label slot 0 as the autosave slot in the ScummVM UI

Changed paths:
    engines/sci/detection.cpp


diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 6799c35..422bbba 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -756,6 +756,7 @@ SaveStateList SciMetaEngine::listSaves(const char *target) const {
 	filenames = saveFileMan->listSavefiles(pattern);
 
 	SaveStateList saveList;
+	bool hasAutosave = false;
 	int slotNr = 0;
 	for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
 		// Obtain the last 3 digits of the filename, since they correspond to the save slot
@@ -775,6 +776,7 @@ SaveStateList SciMetaEngine::listSaves(const char *target) const {
 				if (slotNr == 0) {
 					// ScummVM auto-save slot
 					descriptor.setWriteProtectedFlag(true);
+					hasAutosave = true;
 				} else {
 					descriptor.setWriteProtectedFlag(false);
 				}
@@ -785,6 +787,12 @@ SaveStateList SciMetaEngine::listSaves(const char *target) const {
 		}
 	}
 
+	if (!hasAutosave) {
+		SaveStateDescriptor descriptor(0, _("(Autosave)"));
+		descriptor.setLocked(true);
+		saveList.push_back(descriptor);
+	}
+
 	// Sort saves based on slot number.
 	Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
 	return saveList;


Commit: 6c441060830b62eb6a151240adc53433dc02ef03
    https://github.com/scummvm/scummvm/commit/6c441060830b62eb6a151240adc53433dc02ef03
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:28:35-05:00

Commit Message:
SCI32: Add workarounds & patches for QFG4

Changed paths:
    engines/sci/engine/script_patches.cpp
    engines/sci/engine/workarounds.cpp


diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 82a10d5..608ff07 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -4431,10 +4431,30 @@ static const uint16 qfg4PatchVolumeReset[] = {
 	PATCH_END
 };
 
+// The trap init code incorrectly creates an int array for string data.
+// Applies to at least: English CD
+static const uint16 qfg4SignatureTrapArrayType[] = {
+	0x38, SIG_UINT16(0x92), // pushi $92 (new)
+	0x78,                   // push1
+	0x38, SIG_UINT16(0x80), // pushi $80 (128)
+	SIG_MAGICDWORD,
+	0x51, 0x0b,             // class $b (IntArray)
+	0x4a, SIG_UINT16(0x06), // send 6
+	SIG_END
+};
+
+static const uint16 qfg4PatchTrapArrayType[] = {
+	PATCH_ADDTOOFFSET(+4),     // pushi $92 (new), push1
+	0x38, PATCH_UINT16(0x100), // pushi $100 (256)
+	0x51, 0x0d,                // class $d (ByteArray)
+	PATCH_END
+};
+
 //          script, description,                                      signature                         patch
 static const SciScriptPatcherEntry qfg4Signatures[] = {
 	{  true,     1, "disable volume reset on startup (floppy)",    1, qfg4SignatureVolumeReset,         qfg4PatchVolumeReset },
 	{  true,     1, "disable volume reset on startup (CD)",        1, qfg4CDSignatureVolumeReset,       qfg4PatchVolumeReset },
+	{  true,    83, "fix incorrect array type",                    1, qfg4SignatureTrapArrayType,       qfg4PatchTrapArrayType },
 	{  true, 64990, "increase number of save games",               1, sci2NumSavesSignature1,           sci2NumSavesPatch1 },
 	{  true, 64990, "increase number of save games",               1, sci2NumSavesSignature2,           sci2NumSavesPatch2 },
 	{  true, 64990, "disable change directory button",             1, sci2ChangeDirSignature,           sci2ChangeDirPatch },
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 89cce10..d45e798 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -383,7 +383,9 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
 	{ GID_QFG4,           -1,    15, -1,     "charInitScreen", "dispatchEvent",                   NULL,     5, { WORKAROUND_FAKE,   0 } }, // floppy version, when viewing the character screen
 	{ GID_QFG4,           -1, 64917, -1,       "controlPlane", "setBitmap",                       NULL,     3, { WORKAROUND_FAKE,   0 } }, // floppy version, when entering the game menu
 	{ GID_QFG4,           -1, 64917, -1,              "Plane", "setBitmap",                       NULL,     3, { WORKAROUND_FAKE,   0 } }, // floppy version, happens sometimes in fight scenes
+	{ GID_QFG4,          380,    80, -1,           "myButton", "select",                          NULL,     2, { WORKAROUND_FAKE,   1 } }, // CD version, when clicking on a puzzle piece for the keyhole scrambled picture puzzle
 	{ GID_QFG4,          520, 64950,  0,             "fLake2", "handleEvent",                     NULL,     0, { WORKAROUND_FAKE,   0 } }, // CD version, at the lake, when meeting the Rusalka and attempting to leave
+	{ GID_QFG4,          780, 64964,  0,              "DPath", "init",                            NULL,     1, { WORKAROUND_FAKE,   0 } }, // CD version, walking down to the monastery basement
 	{ GID_QFG4,          800, 64950,  0,               "View", "handleEvent",                     NULL,     0, { WORKAROUND_FAKE,   0 } }, // CD version, in the room with the spider pillar, when climbing on the pillar
 	{ GID_RAMA,           -1, 64950, -1,   "InterfaceFeature", "handleEvent",                     NULL,     0, { WORKAROUND_FAKE,   0 } }, // When clicking on the main game interface
 	{ GID_RAMA,           -1, 64950, -1,               "View", "handleEvent",                     NULL,     0, { WORKAROUND_FAKE,   0 } }, // When clicking on main menu buttons


Commit: 2ccef4a4768c7f7574a7be0637e3791dc0e9d6ff
    https://github.com/scummvm/scummvm/commit/2ccef4a4768c7f7574a7be0637e3791dc0e9d6ff
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:28:35-05:00

Commit Message:
SCI32: Implement support for QFG4 autosave

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


diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 9de6cf8..2ef2d76a6 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -42,6 +42,7 @@
 #include "sci/console.h"
 #ifdef ENABLE_SCI32
 #include "sci/engine/guest_additions.h"
+#include "sci/engine/message.h"
 #include "sci/resource.h"
 #endif
 
@@ -1199,6 +1200,20 @@ reg_t kSaveGame32(EngineState *s, int argc, reg_t *argv) {
 		saveNo += kSaveIdShift;
 	}
 
+	// Auto-save system used by QFG4
+	if (g_sci->getGameId() == GID_QFG4) {
+		reg_t autoSaveNameId;
+		SciArray &autoSaveName = *s->_segMan->allocateArray(kArrayTypeString, 0, &autoSaveNameId);
+		MessageTuple autoSaveNameTuple(0, 0, 16, 1);
+		s->_msgState->getMessage(0, autoSaveNameTuple, autoSaveNameId);
+
+		if (saveDescription == autoSaveName.toString()) {
+			saveNo = 0;
+		}
+
+		s->_segMan->freeArray(autoSaveNameId);
+	}
+
 	Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
 	const Common::String filename = g_sci->getSavegameName(saveNo);
 	Common::OutSaveFile *saveStream = saveFileMan->openForSaving(filename);


Commit: 086fab741ac53a01f583bbd3749f976bce4467d6
    https://github.com/scummvm/scummvm/commit/086fab741ac53a01f583bbd3749f976bce4467d6
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:28:35-05:00

Commit Message:
SCI: Remove #undef for a macro that does not exist

Changed paths:
    engines/sci/engine/kernel_tables.h


diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index fd3f4bd..c103d2d 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -1580,7 +1580,6 @@ static const opcode_format g_base_opcode_formats[128][4] = {
 	// 7C - 7F / minussgi, minussli, minussti, minusspi
 	{Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param}
 };
-#undef END
 
 } // End of namespace Sci
 


Commit: 3ab1f5f4cc6aa79e755fc9688202e2386b74cf92
    https://github.com/scummvm/scummvm/commit/3ab1f5f4cc6aa79e755fc9688202e2386b74cf92
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:28:35-05:00

Commit Message:
SCI: Display class names in disassembly

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


diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 971c721..2dcf03b 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -176,6 +176,14 @@ reg_t disassemble(EngineState *s, reg32_t pos, reg_t objAddr, bool printBWTag, b
 				debugN("\t%s[%x],", (param_value < kernel->_kernelFuncs.size()) ?
 							((param_value < kernel->getKernelNamesSize()) ? kernel->getKernelName(param_value).c_str() : "[Unknown(postulated)]")
 							: "<invalid>", param_value);
+			} else if (opcode == op_class) {
+				const reg_t classAddr = s->_segMan->getClassAddress(param_value, SCRIPT_GET_DONT_LOAD, retval.getSegment());
+				if (!classAddr.isNull()) {
+					debugN("\t%s", s->_segMan->getObjectName(classAddr));
+					debugN(opsize ? "[%02x]" : "[%04x]", param_value);
+				} else {
+					debugN(opsize ? "\t%02x" : "\t%04x", param_value);
+				}
 			} else if (opcode == op_super) {
 				Object *obj;
 				if (objAddr != NULL_REG && (obj = s->_segMan->getObject(objAddr)) != nullptr) {


Commit: 8a5eb0c7844fc2103df24dae8002938ee57d2064
    https://github.com/scummvm/scummvm/commit/8a5eb0c7844fc2103df24dae8002938ee57d2064
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:28:36-05:00

Commit Message:
SCI32: Fix dumb typo in CelInfo32::toString

The typo was `if (kCelTypeColor)` instead of
`if (type == kCelTypeColor)`. Changed to use a switch instead for
improved clarity and code intelligence.

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


diff --git a/engines/sci/graphics/celobj32.h b/engines/sci/graphics/celobj32.h
index 351a885..598a062 100644
--- a/engines/sci/graphics/celobj32.h
+++ b/engines/sci/graphics/celobj32.h
@@ -125,13 +125,14 @@ struct CelInfo32 {
 	}
 
 	inline Common::String toString() const {
-		if (type == kCelTypeView) {
+		switch (type) {
+		case kCelTypeView:
 			return Common::String::format("view %u, loop %d, cel %d", resourceId, loopNo, celNo);
-		} else if (type == kCelTypePic) {
+		case kCelTypePic:
 			return Common::String::format("pic %u, cel %d", resourceId, celNo);
-		} else if (kCelTypeColor) {
+		case kCelTypeColor:
 			return Common::String::format("color %d", color);
-		} else if (type == kCelTypeMem) {
+		case kCelTypeMem:
 			return Common::String::format("mem %04x:%04x", PRINT_REG(bitmap));
 		}
 	}


Commit: f6c4e0c7c7278d643cd723cebae812d2894e27c1
    https://github.com/scummvm/scummvm/commit/f6c4e0c7c7278d643cd723cebae812d2894e27c1
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:38:12-05:00

Commit Message:
SCI: Improve message when crashing due to a bad selector

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


diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 7e514a2..ad6234b 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -294,7 +294,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt
 
 		SelectorType selectorType = lookupSelector(s->_segMan, send_obj, selector, &varp, &funcp);
 		if (selectorType == kSelectorNone)
-			error("Send to invalid selector 0x%x of object at %04x:%04x", 0xffff & selector, PRINT_REG(send_obj));
+			error("Send to invalid selector 0x%x (%s) of object at %04x:%04x", 0xffff & selector, g_sci->getKernel()->getSelectorName(0xffff & selector).c_str(), PRINT_REG(send_obj));
 
 		ExecStackType stackType = EXEC_STACK_TYPE_VARSELECTOR;
 		StackPtr curSP = NULL;


Commit: 5231541e7ca5fa74da01d6c60f46f51ff10b3d78
    https://github.com/scummvm/scummvm/commit/5231541e7ca5fa74da01d6c60f46f51ff10b3d78
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:38:12-05:00

Commit Message:
SCI32: Add and divide instead of performing two divisions

This should make things trivially faster, and matches more
accurately how the original engine worked.

Changed paths:
    engines/sci/video/robot_decoder.cpp


diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp
index 0cb4831..d052929 100644
--- a/engines/sci/video/robot_decoder.cpp
+++ b/engines/sci/video/robot_decoder.cpp
@@ -134,7 +134,7 @@ bool RobotAudioStream::addPacket(const RobotAudioPacket &packet) {
 		return true;
 	}
 
-	const int32 packetEndByte = packet.position + (packet.dataSize * sizeof(int16) * kEOSExpansion);
+	const int32 packetEndByte = packet.position + (packet.dataSize * (sizeof(int16) + kEOSExpansion));
 
 	// Already read all the way past this packet (or already wrote valid samples
 	// to this channel all the way past this packet), so discard it
@@ -228,12 +228,12 @@ void RobotAudioStream::fillRobotBuffer(const RobotAudioPacket &packet, const int
 		targetBytePosition = _jointMin[bufferIndex] % _loopBufferSize;
 		if (targetBytePosition >= packetEndByte) {
 			numBytesToEnd = _loopBufferSize - targetBytePosition;
-			interpolateChannel((int16 *)(_loopBuffer + targetBytePosition), numBytesToEnd / sizeof(int16) / kEOSExpansion, 0);
+			interpolateChannel((int16 *)(_loopBuffer + targetBytePosition), numBytesToEnd / (sizeof(int16) + kEOSExpansion), 0);
 			targetBytePosition = bufferIndex ? 2 : 0;
 		}
 		numBytesToEnd = packetEndByte - targetBytePosition;
 		if (numBytesToEnd > 0) {
-			interpolateChannel((int16 *)(_loopBuffer + targetBytePosition), numBytesToEnd / sizeof(int16) / kEOSExpansion, 0);
+			interpolateChannel((int16 *)(_loopBuffer + targetBytePosition), numBytesToEnd / (sizeof(int16) + kEOSExpansion), 0);
 		}
 	}
 
@@ -246,13 +246,13 @@ void RobotAudioStream::fillRobotBuffer(const RobotAudioPacket &packet, const int
 			copyEveryOtherSample((int16 *)(_loopBuffer + targetBytePosition), (int16 *)(_decompressionBuffer + sourceByte), numBytesToEnd / kEOSExpansion);
 			targetBytePosition = bufferIndex ? 2 : 0;
 		}
-		copyEveryOtherSample((int16 *)(_loopBuffer + targetBytePosition), (int16 *)(_decompressionBuffer + sourceByte + numBytesToEnd), (packetEndByte - targetBytePosition) / sizeof(int16) / kEOSExpansion);
+		copyEveryOtherSample((int16 *)(_loopBuffer + targetBytePosition), (int16 *)(_decompressionBuffer + sourceByte + numBytesToEnd), (packetEndByte - targetBytePosition) / (sizeof(int16) + kEOSExpansion));
 	}
 	_jointMin[bufferIndex] = endByte;
 }
 
 void RobotAudioStream::interpolateMissingSamples(int32 numSamples) {
-	int32 numBytes = numSamples * sizeof(int16) * kEOSExpansion;
+	int32 numBytes = numSamples * (sizeof(int16) + kEOSExpansion);
 	int32 targetPosition = _readHead;
 
 	if (_readHeadAbs > _jointMin[1]) {
@@ -268,7 +268,7 @@ void RobotAudioStream::interpolateMissingSamples(int32 numSamples) {
 			_jointMin[1] += numBytes;
 		} else {
 			if (targetPosition + numBytes >= _loopBufferSize) {
-				const int32 numSamplesToEdge = (_loopBufferSize - targetPosition) / sizeof(int16) / kEOSExpansion;
+				const int32 numSamplesToEdge = (_loopBufferSize - targetPosition) / (sizeof(int16) + kEOSExpansion);
 				interpolateChannel((int16 *)(_loopBuffer + targetPosition), numSamplesToEdge, 1);
 				numSamples -= numSamplesToEdge;
 				targetPosition = 0;
@@ -278,7 +278,7 @@ void RobotAudioStream::interpolateMissingSamples(int32 numSamples) {
 		}
 	} else if (_readHeadAbs > _jointMin[0]) {
 		if (targetPosition + numBytes >= _loopBufferSize) {
-			const int32 numSamplesToEdge = (_loopBufferSize - targetPosition) / sizeof(int16) / kEOSExpansion;
+			const int32 numSamplesToEdge = (_loopBufferSize - targetPosition) / (sizeof(int16) + kEOSExpansion);
 			interpolateChannel((int16 *)(_loopBuffer + targetPosition), numSamplesToEdge, 0);
 			numSamples -= numSamplesToEdge;
 			targetPosition = 2;


Commit: 092a809c783ddf75aa553817d353ab6daa0718e7
    https://github.com/scummvm/scummvm/commit/092a809c783ddf75aa553817d353ab6daa0718e7
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:38:12-05:00

Commit Message:
SCI32: Fix bad interpolation of Robot audio samples

Previously, this code was interpolating samples if the previous
block had missing samples, instead of interpolating when samples
are missing in the upcoming block of samples.

Changed paths:
    engines/sci/video/robot_decoder.cpp


diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp
index d052929..ba8a468 100644
--- a/engines/sci/video/robot_decoder.cpp
+++ b/engines/sci/video/robot_decoder.cpp
@@ -65,36 +65,30 @@ static void interpolateChannel(int16 *buffer, int32 numSamples, const int8 buffe
 		return;
 	}
 
+	int16 *inBuffer, *outBuffer;
+	int16 sample, previousSample;
+
 	if (bufferIndex) {
-		int16 lastSample = *buffer;
-		int sample = lastSample;
-		int16 *target = buffer + 1;
-		const int16 *source = buffer + 2;
+		outBuffer = buffer + 1;
+		inBuffer = buffer + 2;
+		previousSample = sample = *buffer;
 		--numSamples;
+	} else {
+		outBuffer = buffer;
+		inBuffer = buffer + 1;
+		previousSample = sample = *inBuffer;
+	}
 
-		while (numSamples--) {
-			sample = *source + lastSample;
-			lastSample = *source;
-			sample /= 2;
-			*target = sample;
-			source += 2;
-			target += 2;
-		}
+	while (numSamples--) {
+		sample = (*inBuffer + previousSample) >> 1;
+		previousSample = *inBuffer;
+		*outBuffer = sample;
+		inBuffer += RobotAudioStream::kEOSExpansion;
+		outBuffer += RobotAudioStream::kEOSExpansion;
+	}
 
-		*target = sample;
-	} else {
-		int16 *target = buffer;
-		const int16 *source = buffer + 1;
-		int16 lastSample = *source;
-
-		while (numSamples--) {
-			int sample = *source + lastSample;
-			lastSample = *source;
-			sample /= 2;
-			*target = sample;
-			source += 2;
-			target += 2;
-		}
+	if (bufferIndex) {
+		*outBuffer = sample;
 	}
 }
 
@@ -254,9 +248,10 @@ void RobotAudioStream::fillRobotBuffer(const RobotAudioPacket &packet, const int
 void RobotAudioStream::interpolateMissingSamples(int32 numSamples) {
 	int32 numBytes = numSamples * (sizeof(int16) + kEOSExpansion);
 	int32 targetPosition = _readHead;
+	const int32 nextReadHeadPosition = _readHeadAbs + numBytes;
 
-	if (_readHeadAbs > _jointMin[1]) {
-		if (_readHeadAbs > _jointMin[0]) {
+	if (nextReadHeadPosition > _jointMin[1]) {
+		if (nextReadHeadPosition > _jointMin[0]) {
 			if (targetPosition + numBytes >= _loopBufferSize) {
 				const int32 numBytesToEdge = (_loopBufferSize - targetPosition);
 				memset(_loopBuffer + targetPosition, 0, numBytesToEdge);
@@ -264,8 +259,8 @@ void RobotAudioStream::interpolateMissingSamples(int32 numSamples) {
 				targetPosition = 0;
 			}
 			memset(_loopBuffer + targetPosition, 0, numBytes);
-			_jointMin[0] += numBytes;
-			_jointMin[1] += numBytes;
+			_jointMin[0] = nextReadHeadPosition;
+			_jointMin[1] = nextReadHeadPosition + sizeof(int16);
 		} else {
 			if (targetPosition + numBytes >= _loopBufferSize) {
 				const int32 numSamplesToEdge = (_loopBufferSize - targetPosition) / (sizeof(int16) + kEOSExpansion);
@@ -274,9 +269,9 @@ void RobotAudioStream::interpolateMissingSamples(int32 numSamples) {
 				targetPosition = 0;
 			}
 			interpolateChannel((int16 *)(_loopBuffer + targetPosition), numSamples, 1);
-			_jointMin[1] += numBytes;
+			_jointMin[1] = nextReadHeadPosition + sizeof(int16);
 		}
-	} else if (_readHeadAbs > _jointMin[0]) {
+	} else if (nextReadHeadPosition > _jointMin[0]) {
 		if (targetPosition + numBytes >= _loopBufferSize) {
 			const int32 numSamplesToEdge = (_loopBufferSize - targetPosition) / (sizeof(int16) + kEOSExpansion);
 			interpolateChannel((int16 *)(_loopBuffer + targetPosition), numSamplesToEdge, 0);
@@ -284,7 +279,7 @@ void RobotAudioStream::interpolateMissingSamples(int32 numSamples) {
 			targetPosition = 2;
 		}
 		interpolateChannel((int16 *)(_loopBuffer + targetPosition), numSamples, 0);
-		_jointMin[0] += numBytes;
+		_jointMin[0] = nextReadHeadPosition;
 	}
 }
 


Commit: 16fe6d3cb1835bd0cd852ad78f4b00c54e3fdcd1
    https://github.com/scummvm/scummvm/commit/16fe6d3cb1835bd0cd852ad78f4b00c54e3fdcd1
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:38:13-05:00

Commit Message:
SCI32: Store handle to VMD bitmap separately from ScreenItem

In at least RAMA, when using the pocket computer to view a mail
and then pressing the "return" button, the ScreenItem containing
the VMD will be destroyed before the VMD player is told to close
the video, resulting in a use-after-free trying to access the
bitmap ID through the deleted ScreenItem.

Changed paths:
    engines/sci/graphics/video32.cpp
    engines/sci/graphics/video32.h


diff --git a/engines/sci/graphics/video32.cpp b/engines/sci/graphics/video32.cpp
index 8cd6fc7..0e8ac8a 100644
--- a/engines/sci/graphics/video32.cpp
+++ b/engines/sci/graphics/video32.cpp
@@ -614,7 +614,10 @@ VMDPlayer::IOStatus VMDPlayer::close() {
 		_bundledVmd = nullptr;
 	}
 
-	_segMan->freeBitmap(_screenItem->_celInfo.bitmap);
+	if (_bitmapId != NULL_REG) {
+		_segMan->freeBitmap(_bitmapId);
+		_bitmapId = NULL_REG;
+	}
 
 	if (!_planeIsOwned && _screenItem != nullptr) {
 		g_sci->_gfxFrameout->deleteScreenItem(*_screenItem);
@@ -738,8 +741,7 @@ VMDPlayer::EventFlags VMDPlayer::playUntilEvent(const EventFlags flags) {
 		const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
 		const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
 
-		reg_t bitmapId;
-		SciBitmap &vmdBitmap = *_segMan->allocateBitmap(&bitmapId, vmdRect.width(), vmdRect.height(), 255, 0, 0, screenWidth, screenHeight, 0, false, false);
+		SciBitmap &vmdBitmap = *_segMan->allocateBitmap(&_bitmapId, vmdRect.width(), vmdRect.height(), 255, 0, 0, screenWidth, screenHeight, 0, false, false);
 		vmdBitmap.getBuffer().fillRect(Common::Rect(vmdRect.width(), vmdRect.height()), 0);
 
 		if (screenWidth != scriptWidth || screenHeight != scriptHeight) {
@@ -747,7 +749,7 @@ VMDPlayer::EventFlags VMDPlayer::playUntilEvent(const EventFlags flags) {
 		}
 
 		CelInfo32 vmdCelInfo;
-		vmdCelInfo.bitmap = bitmapId;
+		vmdCelInfo.bitmap = _bitmapId;
 		_decoder->setSurfaceMemory(vmdBitmap.getPixels(), vmdBitmap.getWidth(), vmdBitmap.getHeight(), 1);
 
 		if (_planeIsOwned) {
diff --git a/engines/sci/graphics/video32.h b/engines/sci/graphics/video32.h
index fae5caf..751604f 100644
--- a/engines/sci/graphics/video32.h
+++ b/engines/sci/graphics/video32.h
@@ -380,6 +380,11 @@ private:
 	 */
 	ScreenItem *_screenItem;
 
+	/**
+	 * The bitmap used to render the VMD.
+	 */
+	reg_t _bitmapId;
+
 	// TODO: planeIsOwned and priority are used in SCI3+ only
 
 	/**


Commit: 78fd8d39c500cb85fdf5766ce1d836816264fad6
    https://github.com/scummvm/scummvm/commit/78fd8d39c500cb85fdf5766ce1d836816264fad6
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:38:13-05:00

Commit Message:
SCI32: Disable brightness boost when black-lined video is disabled

The boost is intended to compensate for the darkness caused by the
black lines, so should not be applied when there are no black
lines. This fixes too-bright videos in at least LSL7.

Changed paths:
    engines/sci/graphics/video32.cpp


diff --git a/engines/sci/graphics/video32.cpp b/engines/sci/graphics/video32.cpp
index 0e8ac8a..1759e8e 100644
--- a/engines/sci/graphics/video32.cpp
+++ b/engines/sci/graphics/video32.cpp
@@ -590,7 +590,10 @@ void VMDPlayer::init(const int16 x, const int16 y, const PlayFlags flags, const
 	_y = y;
 	_doublePixels = flags & kPlayFlagDoublePixels;
 	_blackLines = ConfMan.getBool("enable_black_lined_video") && (flags & kPlayFlagBlackLines);
-	_boostPercent = 100 + (flags & kPlayFlagBoost ? boostPercent : 0);
+	// If ScummVM has been configured to disable black lines on video playback,
+	// the boosts need to be ignored too or else the brightness of the video
+	// will be too high
+	_boostPercent = 100 + (_blackLines && (flags & kPlayFlagBoost) ? boostPercent : 0);
 	_boostStartColor = CLIP<int16>(boostStartColor, 0, 255);
 	_boostEndColor = CLIP<int16>(boostEndColor, 0, 255);
 	_leaveScreenBlack = flags & kPlayFlagLeaveScreenBlack;


Commit: 9e7c75cc79c7b39b1dcdb9d48bd2ed0c33c649f0
    https://github.com/scummvm/scummvm/commit/9e7c75cc79c7b39b1dcdb9d48bd2ed0c33c649f0
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:38:13-05:00

Commit Message:
SCI: Avoid crashing when disassembling a call with a bad object

lookupSelector will raise an error if the passed object ID is
invalid.

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


diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 2dcf03b..507fd97 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -317,18 +317,22 @@ reg_t disassemble(EngineState *s, reg32_t pos, reg_t objAddr, bool printBWTag, b
 
 				debugN("  %s::%s[", name, g_sci->getKernel()->getSelectorName(selector).c_str());
 
-				switch (lookupSelector(s->_segMan, called_obj_addr, selector, 0, &fun_ref)) {
-				case kSelectorMethod:
-					debugN("FUNCT");
-					argc += restmod;
-					restmod = 0;
-					break;
-				case kSelectorVariable:
-					debugN("VAR");
-					break;
-				case kSelectorNone:
-					debugN("INVALID");
-					break;
+				if (!s->_segMan->getObject(called_obj_addr)) {
+					debugN("INVALID_OBJ");
+				} else {
+					switch (lookupSelector(s->_segMan, called_obj_addr, selector, 0, &fun_ref)) {
+					case kSelectorMethod:
+						debugN("FUNCT");
+						argc += restmod;
+						restmod = 0;
+						break;
+					case kSelectorVariable:
+						debugN("VAR");
+						break;
+					case kSelectorNone:
+						debugN("INVALID");
+						break;
+					}
 				}
 
 				debugN("](");


Commit: fcaf15aa504c6902921d7a9342e34daa2003ae2d
    https://github.com/scummvm/scummvm/commit/fcaf15aa504c6902921d7a9342e34daa2003ae2d
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-04-22T19:38:13-05:00

Commit Message:
SCI: Add alloc_list command to debugger

This command lists all resources that are currently loaded into
memory, plus the number of locks that exist on each loaded
resource.

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


diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index cbb1a0e..c81d086 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -112,6 +112,7 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
 	registerCmd("resource_info",		WRAP_METHOD(Console, cmdResourceInfo));
 	registerCmd("resource_types",		WRAP_METHOD(Console, cmdResourceTypes));
 	registerCmd("list",				WRAP_METHOD(Console, cmdList));
+	registerCmd("alloc_list",				WRAP_METHOD(Console, cmdAllocList));
 	registerCmd("hexgrep",			WRAP_METHOD(Console, cmdHexgrep));
 	registerCmd("verify_scripts",		WRAP_METHOD(Console, cmdVerifyScripts));
 	// Game
@@ -364,6 +365,7 @@ bool Console::cmdHelp(int argc, const char **argv) {
 	debugPrintf(" resource_info - Shows info about a resource\n");
 	debugPrintf(" resource_types - Shows the valid resource types\n");
 	debugPrintf(" list - Lists all the resources of a given type\n");
+	debugPrintf(" alloc_list - Lists all allocated resources\n");
 	debugPrintf(" hexgrep - Searches some resources for a particular sequence of bytes, represented as hexadecimal numbers\n");
 	debugPrintf(" verify_scripts - Performs sanity checks on SCI1.1-SCI2.1 game scripts (e.g. if they're up to 64KB in total)\n");
 	debugPrintf("\n");
@@ -910,6 +912,36 @@ bool Console::cmdList(int argc, const char **argv) {
 	return true;
 }
 
+bool Console::cmdAllocList(int argc, const char **argv) {
+	ResourceManager *resMan = _engine->getResMan();
+
+	for (int i = 0; i < kResourceTypeInvalid; ++i) {
+		Common::List<ResourceId> resources = _engine->getResMan()->listResources((ResourceType)i);
+		if (resources.size()) {
+			Common::sort(resources.begin(), resources.end());
+			bool hasAlloc = false;
+			Common::List<ResourceId>::const_iterator it;
+			for (it = resources.begin(); it != resources.end(); ++it) {
+				Resource *resource = resMan->testResource(*it);
+				if (resource != nullptr && resource->data() != nullptr) {
+					if (hasAlloc) {
+						debugPrintf(", ");
+					} else {
+						debugPrintf("%s: ", getResourceTypeName((ResourceType)i));
+					}
+					hasAlloc = true;
+					debugPrintf("%u (%u locks)", resource->getNumber(), resource->getNumLockers());
+				}
+			}
+			if (hasAlloc) {
+				debugPrintf("\n");
+			}
+		}
+	}
+
+	return true;
+}
+
 bool Console::cmdDissectScript(int argc, const char **argv) {
 	if (argc != 2) {
 		debugPrintf("Examines a script\n");
diff --git a/engines/sci/console.h b/engines/sci/console.h
index 4b630da..366f959 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -78,6 +78,7 @@ private:
 	bool cmdResourceInfo(int argc, const char **argv);
 	bool cmdResourceTypes(int argc, const char **argv);
 	bool cmdList(int argc, const char **argv);
+	bool cmdAllocList(int argc, const char **argv);
 	bool cmdHexgrep(int argc, const char **argv);
 	bool cmdVerifyScripts(int argc, const char **argv);
 	// Game
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index c0c969a..6a67bf74 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -277,6 +277,8 @@ public:
 	// eases transition.
 	uint32 getAudioCompressionType() const;
 
+	uint16 getNumLockers() const { return _lockers; }
+
 protected:
 	ResourceId _id;	// TODO: _id could almost be made const, only readResourceInfo() modifies it...
 	int32 _fileOffset; /**< Offset in file */





More information about the Scummvm-git-logs mailing list