diff options
Diffstat (limited to 'engines/sci')
| -rw-r--r-- | engines/sci/engine/script_patches.cpp | 122 | ||||
| -rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 84 | ||||
| -rw-r--r-- | engines/sci/engine/scriptdebug.h | 4 | ||||
| -rw-r--r-- | engines/sci/engine/selector.cpp | 17 | ||||
| -rw-r--r-- | engines/sci/engine/vm.cpp | 16 | ||||
| -rw-r--r-- | engines/sci/engine/workarounds.cpp | 3 | ||||
| -rw-r--r-- | engines/sci/graphics/video32.cpp | 4 | ||||
| -rw-r--r-- | engines/sci/resource.cpp | 5 | ||||
| -rw-r--r-- | engines/sci/resource_audio.cpp | 41 | 
9 files changed, 226 insertions, 70 deletions
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index fd01a0b541..2a23d26615 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -147,6 +147,7 @@ static const char *const selectorNameTable[] = {  #ifdef ENABLE_SCI32  	"newWith",      // SCI2 array script  	"posn",         // SCI2 benchmarking script +	"printLang",    // GK2  	"view",         // RAMA benchmarking, GK1, QFG4  	"fade",         // Shivers  	"test",         // Torin @@ -260,6 +261,7 @@ enum ScriptPatcherSelectors {  	,  	SELECTOR_newWith,  	SELECTOR_posn, +	SELECTOR_printLang,  	SELECTOR_view,  	SELECTOR_fade,  	SELECTOR_test, @@ -3673,6 +3675,66 @@ static const uint16 gk2WagnerPaintingMessagePatch[] = {  	PATCH_END  }; +// The game-over rooms 665 and 666 draw a pic over everything by setting the +//  default plane's priority to 202, but this is already inventoryBorderPlane's +//  priority. In our interpreter this causes a border fragment to be drawn above +//  the pics. This worked by luck in Sierra's interpreter because it sorts on +//  memory ID when planes have the same priority. In ScummVM the renderer +//  guarantees a sort order based on the creation order of the planes. The +//  default plane is created first and drawn before inventoryBorderPlane. +// +// We fix this by increasing the plane priority in the game-over rooms. +// +// Applies to: All versions +// Responsible methods: gabeNews:init, uDie:init +// Fixes bug: #11298 +static const uint16 gk2GameOverPrioritySignature[] = { +	0x39, SIG_SELECTOR8(priority),  // pushi priority +	SIG_MAGICDWORD, +	0x78,                           // push1 +	0x38, SIG_UINT16(0x00ca),       // pushi 00ca +	0x81, 0x03,                     // lag 03 +	0x4a, SIG_UINT16(0x0012),       // send 12 [ Plane ... priority: 202 ] +	SIG_END +}; + +static const uint16 gk2GameOverPriorityPatch[] = { +	PATCH_ADDTOOFFSET(+3), +	0x38, PATCH_UINT16(0x00cb),     // pushi 00cb [ priority: 203 ] +	PATCH_END +}; + +// GK2 fans have created patches that add subtitles to the entire game. There +//  are at least English and Spanish patch sets. Sierra added the subtitle +//  feature solely for the Portuguese version. The fan patches include these +//  subtitle scripts, replace the Portuguese resources and embedded script +//  strings, and configure Sierra's interpreter to use the Portuguese language +//  through RESOURCE.CFG. This sets GK2:printLang which the scripts test for +//  Portuguese in order to activate subtitles. +// +// The subtitle patches are compatible with ScummVM except for the requirement +//  that GK2:printLang equals Portuguese (351) since we don't use RESOURCE.CFG. +//  We fix this by patching the GK2:printLang tests to always activate subtitles +//  when a sync resource is present for synchronizing text to video playback. +// +// Applies to: PC versions with a subtitle fan-patch applied +// Responsible methods: Any that test GK2:printLang for Portuguese +// Fixes bugs: #9677, #11282 +static const uint16 gk2SubtitleCompatibilitySignature[] = { +	SIG_MAGICDWORD, +	0x39, SIG_SELECTOR8(printLang), // pushi printLang +	0x76,                           // push0 +	0x81, 0x01,                     // lag 01 +	0x4a, SIG_UINT16(0x0004),       // send 04 [ GK2 printLang? ] +	SIG_END +}; + +static const uint16 gk2SubtitleCompatibilityPatch[] = { +	0x34, PATCH_UINT16(0x015f),     // ldi 015f [ K_LANG_PORTUGUESE ] +	0x33, 0x03,                     // jmp 03 +	PATCH_END +}; +  //          script, description,                                              signature                         patch  static const SciScriptPatcherEntry gk2Signatures[] = {  	{  true,     0, "disable volume reset on startup",                     1, gk2VolumeResetSignature,           gk2VolumeResetPatch }, @@ -3682,6 +3744,8 @@ static const SciScriptPatcherEntry gk2Signatures[] = {  	{  true,    23, "fix inventory scroll direction (no line numbers)",    1, gk2InventoryScrollDirSignature2,   gk2InventoryScrollDirPatch2 },  	{  true,    37, "fix sound manager lockup",                            1, gk2SoundManagerLockupSignature1,   gk2SoundManagerLockupPatch1 },  	{  true,    37, "fix sound manager lockup (no line numbers)",          1, gk2SoundManagerLockupSignature2,   gk2SoundManagerLockupPatch2 }, +	{  true,   665, "fix game-over priority",                              1, gk2GameOverPrioritySignature,      gk2GameOverPriorityPatch }, +	{  true,   666, "fix game-over priority",                              1, gk2GameOverPrioritySignature,      gk2GameOverPriorityPatch },  	{  true,   800, "fix neuschwanstein hint (1/3)",                       1, gk2NeuschwansteinHintSignature1,   gk2NeuschwansteinHintPatch },  	{  true,   800, "fix neuschwanstein hint (2/3)",                       1, gk2NeuschwansteinHintSignature2,   gk2NeuschwansteinHintPatch },  	{  true,   800, "fix neuschwanstein hint (3/3)",                       1, gk2NeuschwansteinHintSignature3,   gk2NeuschwansteinHintPatch }, @@ -3695,6 +3759,13 @@ static const SciScriptPatcherEntry gk2Signatures[] = {  	{  true, 64990, "increase number of save games (1/2)",                 1, sci2NumSavesSignature1,            sci2NumSavesPatch1 },  	{  true, 64990, "increase number of save games (2/2)",                 1, sci2NumSavesSignature2,            sci2NumSavesPatch2 },  	{  true, 64990, "disable change directory button",                     1, sci2ChangeDirSignature,            sci2ChangeDirPatch }, +	{ false,     0, "subtitle patch compatibility",                        3, gk2SubtitleCompatibilitySignature, gk2SubtitleCompatibilityPatch }, +	{ false,    11, "subtitle patch compatibility",                        7, gk2SubtitleCompatibilitySignature, gk2SubtitleCompatibilityPatch }, +	{ false,    12, "subtitle patch compatibility",                        5, gk2SubtitleCompatibilitySignature, gk2SubtitleCompatibilityPatch }, +	{ false,    91, "subtitle patch compatibility",                        7, gk2SubtitleCompatibilitySignature, gk2SubtitleCompatibilityPatch }, +	{ false,   200, "subtitle patch compatibility",                        1, gk2SubtitleCompatibilitySignature, gk2SubtitleCompatibilityPatch }, +	{ false,  1300, "subtitle patch compatibility",                        1, gk2SubtitleCompatibilitySignature, gk2SubtitleCompatibilityPatch }, +	{ false, 64924, "subtitle patch compatibility",                        1, gk2SubtitleCompatibilitySignature, gk2SubtitleCompatibilityPatch },  	SCI_SIGNATUREENTRY_TERMINATOR  }; @@ -17013,12 +17084,57 @@ static const uint16 sq1vgaPatchSpiderDroidTiming[] = {  	PATCH_END  }; +// The Russian version of SQ1VGA has mangled class names in its scripts. This +//  isn't a problem in Sierra's interpreter since this is just metadata, but our +//  feature detection code looks up several classes by name and requires them to +//  exist. We fix this by patching the Motion, Rm, and Sound strings back to +//  their original values. +// +// Applies to: Russian PC Floppy +// Fixes bug: #10156 +static const uint16 sq1vgaSignatureRussianMotionName[] = { +	SIG_MAGICDWORD, +	0x2A, 0x4D, 0x6F, 0x74, 0x69,       // *Motion. +	0x6F, 0x6E, 0x20, +	SIG_END +}; + +static const uint16 sq1vgaPatchRussianMotionName[] = { +	0x4D, 0x6F, 0x74, 0x69, 0x6F,       // Motion +	0x6E, 0x00, +	PATCH_END +}; +static const uint16 sq1vgaSignatureRussianRmName[] = { +	SIG_MAGICDWORD, +	0x2a, 0x52, 0x6d, 0x00,             // *Rm +	SIG_END +}; + +static const uint16 sq1vgaPatchRussianRmName[] = { +	0x52, 0x6d, 0x00,                   // Rm +	PATCH_END +}; + +static const uint16 sq1vgaSignatureRussianSoundName[] = { +	SIG_MAGICDWORD, +	0x87, 0xa2, 0xe3, 0xaa, 0x00, 0x00, // .... +	SIG_END +}; + +static const uint16 sq1vgaPatchRussianSoundName[] = { +	0x53, 0x6f, 0x75, 0x63, 0x64,       // Sound +	PATCH_END +}; +  //          script, description,                                      signature                                   patch  static const SciScriptPatcherEntry sq1vgaSignatures[] = {  	{  true,    45, "Ulence Flats: timepod graphic glitch",        1, sq1vgaSignatureUlenceFlatsTimepodGfxGlitch, sq1vgaPatchUlenceFlatsTimepodGfxGlitch },  	{  true,    45, "Ulence Flats: force field generator glitch",  1, sq1vgaSignatureUlenceFlatsGeneratorGlitch,  sq1vgaPatchUlenceFlatsGeneratorGlitch },  	{  true,    58, "Sarien armory droid zapping ego first time",  1, sq1vgaSignatureEgoShowsCard,                sq1vgaPatchEgoShowsCard },  	{  true,   704, "spider droid timing issue",                   1, sq1vgaSignatureSpiderDroidTiming,           sq1vgaPatchSpiderDroidTiming }, +	{  true,   989, "rename russian Sound class",                  1, sq1vgaSignatureRussianSoundName,            sq1vgaPatchRussianSoundName }, +	{  true,   992, "rename russian Motion class",                 1, sq1vgaSignatureRussianMotionName,           sq1vgaPatchRussianMotionName }, +	{  true,   994, "rename russian Rm class",                     1, sq1vgaSignatureRussianRmName,               sq1vgaPatchRussianRmName },  	SCI_SIGNATUREENTRY_TERMINATOR  }; @@ -18531,6 +18647,12 @@ void ScriptPatcher::processScript(uint16 scriptNr, SciSpan<byte> scriptData) {  					enablePatch(signatureTable, "Mac: skip broken hop singh scene");  				}  				break; +			case GID_GK2: +				// Enable subtitle compatibility if a sync resource is present +				if (g_sci->getResMan()->testResource(ResourceId(kResourceTypeSync, 10))) { +					enablePatch(signatureTable, "subtitle patch compatibility"); +				} +				break;  			case GID_KQ5:  				if (g_sci->_features->useAltWinGMSound()) {  					// See the explanation in the kq5SignatureWinGMSignals comment diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 7a1fe66d35..2f0dd008fc 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -945,32 +945,34 @@ void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr arg  	}	// switch  } -void debugPropertyAccess(Object *obj, reg_t objp, unsigned int index, reg_t curValue, reg_t newValue, SegManager *segMan, BreakpointType breakpointType) { +void debugPropertyAccess(Object *obj, reg_t objp, unsigned int index, Selector selector, reg_t curValue, reg_t newValue, SegManager *segMan, BreakpointType breakpointType) {  	const Object *var_container = obj;  	if (!obj->isClass() && getSciVersion() != SCI_VERSION_3)  		var_container = segMan->getObject(obj->getSuperClassSelector()); -	uint16 varSelector; -	if (getSciVersion() == SCI_VERSION_3) { -		varSelector = index; -	} else { -		index >>= 1; - -		if (index >= var_container->getVarCount()) { -			// TODO: error, warning, debug? -			return; +	if (selector == NULL_SELECTOR) { +		if (getSciVersion() == SCI_VERSION_3) { +			selector = index;  		} +		else { +			index >>= 1; + +			if (index >= var_container->getVarCount()) { +				// TODO: error, warning, debug? +				return; +			} -		varSelector = var_container->getVarSelector(index); +			selector = var_container->getVarSelector(index); +		}  	} -	if (g_sci->checkSelectorBreakpoint(breakpointType, objp, varSelector)) { +	if (g_sci->checkSelectorBreakpoint(breakpointType, objp, selector)) {  		// checkSelectorBreakpoint has already triggered the breakpoint.  		// We just output the relevant data here.  		Console *con = g_sci->getSciDebugger();  		const char *objectName = segMan->getObjectName(objp); -		const char *selectorName = g_sci->getKernel()->getSelectorName(varSelector).c_str(); +		const char *selectorName = g_sci->getKernel()->getSelectorName(selector).c_str();  		if (breakpointType == BREAK_SELECTORWRITE) {  			con->debugPrintf("Write to selector (%s:%s): change %04x:%04x to %04x:%04x\n",  								objectName, selectorName, @@ -986,27 +988,11 @@ void debugPropertyAccess(Object *obj, reg_t objp, unsigned int index, reg_t curV  	}  } -void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *kernelSubCall, EngineState *s, int argc, reg_t *argv, reg_t result) { -	if (s->abortScriptProcessing != kAbortNone) { -		return; -	} - -	Kernel *kernel = g_sci->getKernel(); -	if (!kernelSubCall) { -		debugN("k%s: ", kernelCall->name); -	} else { -		int callNameLen = strlen(kernelCall->name); -		if (strncmp(kernelCall->name, kernelSubCall->name, callNameLen) == 0) { -			const char *subCallName = kernelSubCall->name + callNameLen; -			debugN("k%s(%s): ", kernelCall->name, subCallName); -		} else { -			debugN("k%s(%s): ", kernelCall->name, kernelSubCall->name); -		} -	} +static void logParameters(const KernelFunction *kernelCall, EngineState *s, int argc, reg_t *argv) {  	for (int parmNr = 0; parmNr < argc; parmNr++) {  		if (parmNr)  			debugN(", "); -		uint16 regType = kernel->findRegType(argv[parmNr]); +		uint16 regType = g_sci->getKernel()->findRegType(argv[parmNr]);  		if (regType & SIG_TYPE_NULL)  			debugN("0");  		else if (regType & SIG_TYPE_UNINITIALIZED) @@ -1043,7 +1029,7 @@ void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *ke  						// TODO: Any other segment types which could  						// use special handling? -						if (kernelCall->function == &kSaid) { +						if (kernelCall != nullptr && kernelCall->function == &kSaid) {  							SegmentRef saidSpec = s->_segMan->dereference(argv[parmNr]);  							if (saidSpec.isRaw) {  								debugN(" ('"); @@ -1064,12 +1050,46 @@ void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *ke  			}  		}  	} +} + +void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *kernelSubCall, EngineState *s, int argc, reg_t *argv, reg_t result) { +	if (s->abortScriptProcessing != kAbortNone) { +		return; +	} + +	if (!kernelSubCall) { +		debugN("k%s: ", kernelCall->name); +	} else { +		int callNameLen = strlen(kernelCall->name); +		if (strncmp(kernelCall->name, kernelSubCall->name, callNameLen) == 0) { +			const char *subCallName = kernelSubCall->name + callNameLen; +			debugN("k%s(%s): ", kernelCall->name, subCallName); +		} else { +			debugN("k%s(%s): ", kernelCall->name, kernelSubCall->name); +		} +	} + +	logParameters(kernelCall, s, argc, argv); +  	if (result.isPointer())  		debugN(" = %04x:%04x\n", PRINT_REG(result));  	else  		debugN(" = %d\n", result.getOffset());  } +void logExportCall(uint16 script, uint16 pubfunct, EngineState *s, int argc, reg_t *argv) { +	if (s->abortScriptProcessing != kAbortNone) { +		return; +	} + +	debugN("script %d, export %d: ", script, pubfunct); + +	if (argc > 1) { +		argv++; +		logParameters(nullptr, s, argc, argv); +	} +	debugN("\n"); +}  void logBacktrace() {  	Console *con = g_sci->getSciDebugger(); diff --git a/engines/sci/engine/scriptdebug.h b/engines/sci/engine/scriptdebug.h index 5e927efaf1..3d54b327d3 100644 --- a/engines/sci/engine/scriptdebug.h +++ b/engines/sci/engine/scriptdebug.h @@ -31,10 +31,12 @@ extern const char *opcodeNames[];  void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr argp, ObjVarRef &varp, reg_t funcp, SegManager *segMan, SelectorType selectorType); -void debugPropertyAccess(Object *obj, reg_t objp, unsigned int index, reg_t curValue, reg_t newValue, SegManager *segMan, BreakpointType breakpointType); +void debugPropertyAccess(Object *obj, reg_t objp, unsigned int index, Selector selector, reg_t curValue, reg_t newValue, SegManager *segMan, BreakpointType breakpointType);  void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *kernelSubCall, EngineState *s, int argc, reg_t *argv, reg_t result); +void logExportCall(uint16 script, uint16 pubfunct, EngineState *s, int argc, reg_t *argv); +  void logBacktrace();  bool printObject(reg_t obj); diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index 6196495954..1a63b4dee1 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -23,6 +23,7 @@  #include "sci/sci.h"  #include "sci/engine/features.h"  #include "sci/engine/kernel.h" +#include "sci/engine/scriptdebug.h"  #include "sci/engine/state.h"  #include "sci/engine/selector.h" @@ -246,8 +247,14 @@ reg_t readSelector(SegManager *segMan, reg_t object, Selector selectorId) {  	if (lookupSelector(segMan, object, selectorId, &address, NULL) != kSelectorVariable)  		return NULL_REG; -	else -		return *address.getPointer(segMan); + +	if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORREAD) { +		reg_t curValue = *address.getPointer(segMan); +		debugPropertyAccess(segMan->getObject(object), object, 0, selectorId, +			                curValue, NULL_REG, segMan, BREAK_SELECTORREAD); +	} + +	return *address.getPointer(segMan);  }  #ifdef ENABLE_SCI32 @@ -271,6 +278,12 @@ void writeSelector(SegManager *segMan, reg_t object, Selector selectorId, reg_t  		error("Selector '%s' of object could not be written to. Address %04x:%04x, %s", g_sci->getKernel()->getSelectorName(selectorId).c_str(), PRINT_REG(object), origin.toString().c_str());  	} +	if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORWRITE) { +		reg_t curValue = *address.getPointer(segMan); +		debugPropertyAccess(segMan->getObject(object), object, 0, selectorId, +			                curValue, value, segMan, BREAK_SELECTORWRITE); +	} +  	*address.getPointer(segMan) = value;  #ifdef ENABLE_SCI32  	updateInfoFlagViewVisible(segMan->getObject(object), address.varindex); diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index d5bcb63ce4..e8808a715c 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -222,7 +222,9 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP  	}  	// Check if a breakpoint is set on this method -	g_sci->checkExportBreakpoint(script, pubfunct); +	if (g_sci->checkExportBreakpoint(script, pubfunct)) { +		logExportCall(script, pubfunct, s, argc, argp); +	}  	uint32 exportAddr = scr->validateExportFunc(pubfunct, false);  	if (!exportAddr) @@ -1133,7 +1135,7 @@ void run_vm(EngineState *s) {  		case op_pToa: // 0x31 (49)  			// Property To Accumulator  			if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORREAD) { -				debugPropertyAccess(obj, s->xs->objp, opparams[0], +				debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,  				                    validate_property(s, obj, opparams[0]), NULL_REG,  				                    s->_segMan, BREAK_SELECTORREAD);  			} @@ -1145,7 +1147,7 @@ void run_vm(EngineState *s) {  			// Accumulator To Property  			reg_t &opProperty = validate_property(s, obj, opparams[0]);  			if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORWRITE) { -				debugPropertyAccess(obj, s->xs->objp, opparams[0], +				debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,  				                    opProperty, s->r_acc,  				                    s->_segMan, BREAK_SELECTORWRITE);  			} @@ -1162,7 +1164,7 @@ void run_vm(EngineState *s) {  			// Property To Stack  			reg_t value = validate_property(s, obj, opparams[0]);  			if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORREAD) { -				debugPropertyAccess(obj, s->xs->objp, opparams[0], +				debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,  				                    value, NULL_REG,  				                    s->_segMan, BREAK_SELECTORREAD);  			} @@ -1176,7 +1178,7 @@ void run_vm(EngineState *s) {  			reg_t newValue = POP32();  			reg_t &opProperty = validate_property(s, obj, opparams[0]);  			if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORWRITE) { -				debugPropertyAccess(obj, s->xs->objp, opparams[0], +				debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,  				                    opProperty, newValue,  				                    s->_segMan, BREAK_SELECTORWRITE);  			} @@ -1198,7 +1200,7 @@ void run_vm(EngineState *s) {  			reg_t oldValue = opProperty;  			if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORREAD) { -				debugPropertyAccess(obj, s->xs->objp, opparams[0], +				debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,  				                    oldValue, NULL_REG,  				                    s->_segMan, BREAK_SELECTORREAD);  			} @@ -1209,7 +1211,7 @@ void run_vm(EngineState *s) {  				opProperty -= 1;  			if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORWRITE) { -				debugPropertyAccess(obj, s->xs->objp, opparams[0], +				debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,  				                    oldValue, opProperty,  				                    s->_segMan, BREAK_SELECTORWRITE);  			} diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index ba11883cbc..71046a83cf 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -1247,6 +1247,9 @@ static const SciMessageWorkaroundEntry messageWorkarounds[] = {  	//  audio36 for the the other has the wrong tuple, which we fix in the audio36 workarounds.  	{ GID_GK1,           SCI_MEDIA_ALL,    K_LANG_NONE,     -1,  420,   2,  32,   3,  1, { MSG_WORKAROUND_REMAP,    420,   2,  32,   0,  1,  0,   0,   0, NULL } },  	{ GID_GK1,           SCI_MEDIA_ALL,    K_LANG_NONE,     -1,  420,   2,  32,   0,  1, { MSG_WORKAROUND_REMAP,    420,   2,  32,   2,  1,  0,   0,   0, NULL } }, +	// Clicking one of Gabriel's letters on Gerde in room 120 after getting his address in some versions +	{ GID_GK2,           SCI_MEDIA_ALL,    K_LANG_NONE,     -1,  120,  18,  63,   0,  1, { MSG_WORKAROUND_REMAP,    120,  18,  44,   0,  1,  0,   0,   0, NULL } }, +	{ GID_GK2,           SCI_MEDIA_ALL,    K_LANG_NONE,     -1,  120,  18,  64,   0,  1, { MSG_WORKAROUND_REMAP,    120,  18,  44,   0,  1,  0,   0,   0, NULL } },  	// Clicking any item other than the dagger on theater vent in room 11853  	{ GID_GK2,           SCI_MEDIA_ALL,    K_LANG_NONE,     -1, 1185,   4,   0,   0,  1, { MSG_WORKAROUND_REMAP,   1185,   4,  62,   0,  1,  0,   0,   0, NULL } },  	// Asking Yvette about Tut in act 2 party in floppy version - bug #10723 diff --git a/engines/sci/graphics/video32.cpp b/engines/sci/graphics/video32.cpp index 567660d97a..be62ba7882 100644 --- a/engines/sci/graphics/video32.cpp +++ b/engines/sci/graphics/video32.cpp @@ -936,7 +936,9 @@ void VMDPlayer::closeOverlay() {  	}  #endif -	g_sci->_gfxFrameout->frameOut(true, _drawRect); +	if (!_leaveLastFrame && _leaveScreenBlack) { +		g_sci->_gfxFrameout->frameOut(true, _drawRect); +	}  }  void VMDPlayer::initComposited() { diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 779bd0acb2..a716a1230d 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -993,6 +993,11 @@ void ResourceManager::init() {  		_mapVersion = _volVersion;  	} +	if ((_volVersion == kResVersionSci3) && (_mapVersion < kResVersionSci2)) { +		warning("Detected volume version is too high for detected map version. Setting volume version to map version"); +		_volVersion = _mapVersion; +	} +  	debugC(1, kDebugLevelResMan, "resMan: Detected resource map version %d: %s", _mapVersion, versionDescription(_mapVersion));  	debugC(1, kDebugLevelResMan, "resMan: Detected volume version %d: %s", _volVersion, versionDescription(_volVersion)); diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp index c825196d93..73e10eb1ee 100644 --- a/engines/sci/resource_audio.cpp +++ b/engines/sci/resource_audio.cpp @@ -513,36 +513,23 @@ int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) {  				continue;  			} +			// GK2 has invalid audio36 map entries on CD 1 of the German  +			//  version and CD 6 of all versions. All are safe to ignore +			//  because their content doesn't apply to the disc's chapter.  			if (g_sci->getGameId() == GID_GK2) { -				// At least version 1.00 of the US release, and the German -				// release, of GK2 have multiple invalid audio36 map entries on -				// CD 6 -				if (map->_volumeNumber == 6 && offset + syncSize >= srcSize) { -					bool skip; -					switch (g_sci->getLanguage()) { -					case Common::EN_ANY: -						skip = (map->_mapNumber == 22 || map->_mapNumber == 160); -						break; -					case Common::DE_DEU: -						skip = (map->_mapNumber == 22); -						break; -					default: -						skip = false; -					} - -					if (skip) { -						continue; -					} +				// Map 2020 on CD 1 only exists in localized versions and +				//  contains inventory messages from later chapters. +				if (map->_volumeNumber == 1 && +					map->_mapNumber == 2020) { +					continue;  				} -				// Map 2020 on CD 1 of the German release of GK2 is invalid. -				// This content does not appear to ever be used by the game (it -				// does not even exist in the US release), and there is a -				// correct copy of it on CD 6, so just ignore the bad copy on -				// CD 1 -				if (g_sci->getLanguage() == Common::DE_DEU && -					map->_volumeNumber == 1 && -					map->_mapNumber == 2020) { +				// Maps 22 and 160 on CD 6 appear in various broken forms +				//  in English and apparently every localized version. +				//  These messages are for Grace's notebook and castle +				//  secret passage rooms which aren't in chapter 6. +				if (map->_volumeNumber == 6 && +					(map->_mapNumber == 22 || map->_mapNumber == 160)) {  					continue;  				}  			}  | 
