diff options
Diffstat (limited to 'scumm')
| -rw-r--r-- | scumm/gfx.cpp | 148 | ||||
| -rw-r--r-- | scumm/resource.cpp | 98 | ||||
| -rw-r--r-- | scumm/saveload.cpp | 2 | ||||
| -rw-r--r-- | scumm/script_v1.cpp | 4 | ||||
| -rw-r--r-- | scumm/script_v2.cpp | 2 | ||||
| -rw-r--r-- | scumm/scumm.h | 4 | ||||
| -rw-r--r-- | scumm/scummvm.cpp | 141 | 
7 files changed, 209 insertions, 190 deletions
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp index cda2598c70..7866c2dfd8 100644 --- a/scumm/gfx.cpp +++ b/scumm/gfx.cpp @@ -2370,6 +2370,88 @@ void Scumm::setCameraAtEx(int at)  	}  } +void Scumm::palManipulateInit(int start, int end, int d, int time, int e) +{ +	// TODO - correctly implement this function (see also bug #558245) +	// +	// There are two known places (both in FOA) where this function is being +	// called. The fist is during the FOA extro, to change the color to match +	// the sinking sun. The following three calls (with some pauses between them) +	// are issued: +	// +	// palManipulateInit(16, 190, 32, 180, 1) +	// palManipulateInit(16, 190, 32, 1, 1) +	// palManipulateInit(16, 190, 32, 800, 1) +	// +	// The second place is in the Inner Sanctum after you used the stone discs, +	// here it is used to give the scene a "lava glow". +	// +	// palManipulateInit(32, 65, 46, 20, 1): not implemented! +	// +	// The first two parameters seem to specify a palette range (as the colors +	// from 16 to 190 are the ones that make up water & sky). +	// +	// Maybe the change has to be done over a period of time, possibly specified +	// by the second last parameter - between call 1 and 2, about 17-18 seconds +	// seem to pass (well using get_msecs, I measured 17155 ms, 17613 ms, 17815 ms). +	// +	// No clue about the third and fifth parameter right now, they just always +	// are 32 and 1 - possibly finding another example of this function being +	// used would help a lot. Also, I can't currently compare it with the original, +	// doing that (and possibly, taking screenshots of it for analysis!) would  +	// help a lot. +	 +	warning("palManipulateInit(%d, %d, %d, %d, %d): not implemented", start, end, d, time, e); + +	// FIXME - is this right? +	// It seems we already have had this "palManipulate" and "moveMemInPalRes" +	// functions, only they were never used (somebody disassembled them and +	// didn't disassmble the functions using them?). +	// +	// I  +	_palManipStart = start; +	_palManipEnd = end; +	//_palManipCounter = ? +	 +	{ +		int redScale = 0xFF; +		int greenScale = 0xFF - d; +		int blueScale = 0xFF - d; +		byte *cptr; +		byte *cur; +		int num; +		int color; +	 +		cptr = _currentPalette + start * 3; +		cur = _currentPalette + start * 3; +		num = end - start + 1; + +		do { +			color = *cptr++; +			if (redScale != 0xFF) +				color = color * redScale / 0xFF; +			if (color > 255) +				color = 255; +			*cur++ = color; + +			color = *cptr++; +			if (greenScale != 0xFF) +				color = color * greenScale / 0xFF; +			if (color > 255) +				color = 255; +			*cur++ = color; + +			color = *cptr++; +			if (blueScale != 0xFF) +				color = color * blueScale / 0xFF; +			if (color > 255) +				color = 255; +			*cur++ = color; +		} while (--num); +		setDirtyColors(start, end); +	} +} +  void Scumm::palManipulate()  {  	byte *srcptr, *destptr; @@ -2378,8 +2460,12 @@ void Scumm::palManipulate()  	if (!_palManipCounter)  		return; +	  	srcptr = getResourceAddress(rtTemp, 4) + _palManipStart * 6;  	destptr = getResourceAddress(rtTemp, 5) + _palManipStart * 6; +	if (!srcptr || !destptr) +		return; +	  	pal = _currentPalette + _palManipStart * 3;  	i = _palManipStart; @@ -2402,12 +2488,72 @@ void Scumm::palManipulate()  		i++;  	}  	setDirtyColors(_palManipStart, _palManipEnd); -	if (!--_palManipCounter) { +	_palManipCounter--; +	if (!_palManipCounter) {  		nukeResource(rtTemp, 4);  		nukeResource(rtTemp, 5);  	}  } +void Scumm::unkRoomFunc3(int unk1, int unk2, int rfact, int gfact, int bfact) +{ +	byte *pal = _currentPalette; +	byte *table = _shadowPalette; +	int i; + +	warning("unkRoomFunc3(%d,%d,%d,%d,%d): not fully implemented", unk1, unk2, rfact, gfact, bfact); + +	// TODO - correctly implement this function (see also patch #588501) +	// +	// Some "typical" examples of how this function is being invoked in real life: +	// +	// 1) +	// unkRoomFunc3(16, 255, 200, 200, 200) +	// +	// FOA: Sets up the colors for the boat and submarine shadows in the +	// diving scene. Are the shadows too light? Maybe unk1 is used to +	// darken the colors? +	// +	// 2) +	// unkRoomFunc3(0, 255, 700, 700, 700) +	// +	// FOA: Sets up the colors for the subway car headlight when it first +	// goes on. This seems to work ok. +	// +	// 3) +	// unkRoomFunc3(160, 191, 300, 300, 300) +	// unkRoomFunc3(160, 191, 289, 289, 289) +	//     ... +	// unkRoomFunc3(160, 191, 14, 14, 14) +	// unkRoomFunc3(160, 191, 3, 3, 3) +	// +	// 4) +	// FOA: Sets up the colors for the subway car headlight for the later +	// half of the trip, where it fades out. This currently doesn't work +	// at all. The colors are too dark to be brightened. At first I thought +	// unk1 and unk2 were used to tell which color interval to manipulate, +	// but as far as I can tell the colors 160-191 aren't used at all to +	// draw the light, that can't be it. Apparently unk1 and/or unk2 are +	// used to brighten the colors. +	// +	// 5) +	// unkRoomFunc3(16,255,500,500,500) +	// +	// FOA: Used in the Inner Sanctum after you activated the machine using the +	// stone discs (briefly before the Nazis arrive). No idea at all if it is +	// right here; also note that palManipulateInit() is called at the same time. +	// +	// +	 +	for (i = 0; i <= 255; i++) { +		int r = (int) (*pal++ * rfact) >> 8; +		int g = (int) (*pal++ * gfact) >> 8; +		int b = (int) (*pal++ * bfact) >> 8; + +		*table++ = remapPaletteColor(r, g, b, (uint) -1); +	} +} +  void Scumm::swapPalColors(int a, int b)  {  	byte *ap, *bp; diff --git a/scumm/resource.cpp b/scumm/resource.cpp index 318bcce181..1a91504396 100644 --- a/scumm/resource.cpp +++ b/scumm/resource.cpp @@ -470,8 +470,8 @@ void Scumm::loadCharset(int no)  	assert(no < (int)sizeof(_charsetData) / 16);  	checkRange(_maxCharsets - 1, 1, no, "Loading illegal charset %d"); -//  ensureResourceLoaded(6, no); -	ptr = getResourceAddress(6, no); +//  ensureResourceLoaded(rtCharset, no); +	ptr = getResourceAddress(rtCharset, no);  	for (i = 0; i < 15; i++) {  		_charsetData[no][i + 1] = ptr[i + 14]; @@ -537,54 +537,52 @@ int Scumm::loadResource(int type, int idx)  			return 0;  	} -	do { -		for (i = 0; i < 5; i++) { -			openRoom(roomNr); - -			fileSeek(_fileHandle, fileOffs + _fileOffset, SEEK_SET); - -			if (_features & GF_OLD_BUNDLE) { -				size = fileReadWordLE(); -			} else if (_features & GF_SMALL_HEADER) { -				if (!(_features & GF_SMALL_NAMES)) -					fileSeek(_fileHandle, 8, SEEK_CUR); -				size = fileReadDwordLE(); -				tag = fileReadWordLE(); -				fileSeek(_fileHandle, -6, SEEK_CUR); -			} else { -				if (type == rtSound) { -					fileReadDwordLE(); -					fileReadDwordLE(); -					return readSoundResource(type, idx); -				} +	for (i = 0; i < 5; i++) { +		openRoom(roomNr); -				tag = fileReadDword(); +		fileSeek(_fileHandle, fileOffs + _fileOffset, SEEK_SET); -				if (tag != res.tags[type]) { -					error("%s %d not in room %d at %d+%d", res.name[type], type, roomNr, _fileOffset, fileOffs); -				} +		if (_features & GF_OLD_BUNDLE) { +			size = fileReadWordLE(); +		} else if (_features & GF_SMALL_HEADER) { +			if (!(_features & GF_SMALL_NAMES)) +				fileSeek(_fileHandle, 8, SEEK_CUR); +			size = fileReadDwordLE(); +			tag = fileReadWordLE(); +			fileSeek(_fileHandle, -6, SEEK_CUR); +		} else { +			if (type == rtSound) { +				fileReadDwordLE(); +				fileReadDwordLE(); +				return readSoundResource(type, idx); +			} -				size = fileReadDwordBE(); -				fileSeek(_fileHandle, -8, SEEK_CUR); +			tag = fileReadDword(); + +			if (tag != res.tags[type]) { +				error("%s %d not in room %d at %d+%d", res.name[type], type, roomNr, _fileOffset, fileOffs);  			} -			fileRead(_fileHandle, createResource(type, idx, size), size); -			/* dump the resource */ +			size = fileReadDwordBE(); +			fileSeek(_fileHandle, -8, SEEK_CUR); +		} +		fileRead(_fileHandle, createResource(type, idx, size), size); + +		/* dump the resource */  #ifdef DUMP_SCRIPTS -			if (type == rtScript) { -				dumpResource("script-", idx, getResourceAddress(rtScript, idx)); -			} +		if (type == rtScript) { +			dumpResource("script-", idx, getResourceAddress(rtScript, idx)); +		}  #endif -			if (!fileReadFailed(_fileHandle)) { -				return 1; -			} - -			nukeResource(type, idx); +		if (!fileReadFailed(_fileHandle)) { +			return 1;  		} -		error("Cannot read resource"); -	} while (1); +		nukeResource(type, idx); +	} + +	error("Cannot read resource");  }  int Scumm::readSoundResource(int type, int idx) @@ -763,10 +761,9 @@ byte *Scumm::getResourceAddress(int type, int idx)  {  	byte *ptr; -  	CHECK_HEAP validateResource("getResourceAddress", type, idx);  	if (!res.address[type]) { -		debug(9, "getResourceAddress(%s,%d) == NULL", resTypeFromId(type), idx); +		debug(1, "getResourceAddress(%s,%d), res.address[type] == NULL", resTypeFromId(type), idx);  		return NULL;  	} @@ -774,9 +771,8 @@ byte *Scumm::getResourceAddress(int type, int idx)  		ensureResourceLoaded(type, idx);  	} -  	if (!(ptr = (byte *)res.address[type][idx])) { -		debug(9, "getResourceAddress(%s,%d) == NULL", resTypeFromId(type), idx); +		debug(1, "getResourceAddress(%s,%d) == NULL", resTypeFromId(type), idx);  		return NULL;  	} @@ -857,9 +853,8 @@ void Scumm::nukeResource(int type, int idx)  {  	byte *ptr; -  	CHECK_HEAP if (!res.address[type]) -		  return; +		return;  	assert(idx >= 0 && idx < res.num[type]); @@ -874,17 +869,14 @@ void Scumm::nukeResource(int type, int idx)  byte *Scumm::findResourceData(uint32 tag, byte *ptr)  { -	if (_features & GF_SMALL_HEADER) { +	if (_features & GF_SMALL_HEADER)  		ptr = findResourceSmall(tag, ptr, 0); -		if (ptr == NULL) -			return NULL; -		return ptr + 6; -	} +	else +		ptr = findResource(tag, ptr, 0); -	ptr = findResource(tag, ptr, 0);  	if (ptr == NULL)  		return NULL; -	return ptr + 8; +	return ptr + _resourceHeaderSize;  }  int Scumm::getResourceDataSize(byte *ptr) diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp index 6ac7bdd0df..839808120a 100644 --- a/scumm/saveload.cpp +++ b/scumm/saveload.cpp @@ -337,6 +337,7 @@ void Scumm::saveOrLoad(Serializer *s)  		MKLINE(Scumm, _EXCD_offs, sleUint32),  		MKLINE(Scumm, _IM00_offs, sleUint32),  		MKLINE(Scumm, _CLUT_offs, sleUint32), +		/* XXX Remove _EPAL_offs next time format changes */  		MKLINE(Scumm, _EPAL_offs, sleUint32),  		MKLINE(Scumm, _PALS_offs, sleUint32),  		MKLINE(Scumm, _curPalIndex, sleByte), @@ -441,6 +442,7 @@ void Scumm::saveOrLoad(Serializer *s)  		MKLINE(Scumm, _EXCD_offs, sleUint32),  		MKLINE(Scumm, _IM00_offs, sleUint32),  		MKLINE(Scumm, _CLUT_offs, sleUint32), +		/* XXX Remove _EPAL_offs next time format changes */  		MKLINE(Scumm, _EPAL_offs, sleUint32),  		MKLINE(Scumm, _PALS_offs, sleUint32),  		MKLINE(Scumm, _curPalIndex, sleByte), diff --git a/scumm/script_v1.cpp b/scumm/script_v1.cpp index 3fd4f6f3cc..106923aca9 100644 --- a/scumm/script_v1.cpp +++ b/scumm/script_v1.cpp @@ -1899,6 +1899,7 @@ void Scumm::o5_roomOps()  			}  			checkRange(256, 0, a, "o5_roomOps: 2: Illegal room color slot (%d)");  			_currentPalette[a] = b; +printf("palette change, %d -> %d\n", a, b);  			_fullRedraw = 1;  		} else {  			error("room-color is no longer a valid command"); @@ -1919,6 +1920,7 @@ void Scumm::o5_roomOps()  				b = getVarOrDirectWord(0x40);  			}  			checkRange(256, 0, a, "o5_roomOps: 2: Illegal room color slot (%d)"); +printf("shadow palette change, %d -> %d\n", a, b);  			_shadowPalette[b] = a;  			setDirtyColors(b, b);  		} else { @@ -2049,7 +2051,7 @@ void Scumm::o5_roomOps()  		c = getVarOrDirectByte(0x40);  		_opcode = fetchScriptByte();  		d = getVarOrDirectByte(0x80); -		palManipulate(b, c, a, d, 1); +		palManipulateInit(b, c, a, d, 1);  		break;  	case 16: diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp index cde491405d..9e2b8c52ca 100644 --- a/scumm/script_v2.cpp +++ b/scumm/script_v2.cpp @@ -1878,7 +1878,7 @@ void Scumm::o6_roomOps()  		c = pop();  		b = pop();  		a = pop(); -		palManipulate(a, b, c, d, 1); +		palManipulateInit(a, b, c, d, 1);  		break;  	case 187:										/* color cycle delay */ diff --git a/scumm/scumm.h b/scumm/scumm.h index 0b0dfcf590..b4c01e06ff 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -461,8 +461,6 @@ public:  	byte _numObjectsInRoom;  	int8 _userPut;  	int _resourceHeaderSize; -	void unkRoomFunc3(int a, int b, int c, int d, int e); -	void palManipulate(int a, int b, int c, int d, int e);  	void setScaleItem(int slot, int a, int b, int c, int d);  	void clearClickedStatus();  	void startManiac(); @@ -796,7 +794,9 @@ public:  	void swapPalColors(int a, int b);  	void cyclePalette();  	void stopCycle(int i); +	void palManipulateInit(int a, int b, int c, int d, int e);  	void palManipulate(); +	void unkRoomFunc3(int a, int b, int c, int d, int e);  	int remapPaletteColor(int r, int g, int b, uint threshold);  	void moveMemInPalRes(int start, int end, byte direction);  	void setupShadowPalette(int slot, int rfact, int gfact, int bfact, int from, int to); diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp index bb6756d5d4..b41bb43b65 100644 --- a/scumm/scummvm.cpp +++ b/scumm/scummvm.cpp @@ -780,14 +780,13 @@ void Scumm::initRoomSubBlocks()  		}  	} -	if (_features & GF_SMALL_HEADER) -		ptr = findResourceSmall(MKID('EPAL'), roomptr); -	else -		ptr = findResource(MKID('EPAL'), roomptr); - -	if (ptr) -		_EPAL_offs = ptr - roomptr; - +	// FIXME - we could simply always call findResourceData here, it will +	// do the right thing even if GF_SMALL_HEADER is set. But then, we have +	// to change setPaletteFromPtr() (easy). The problematic bit is save game +	// compatibility - _CLUT_offs is stored in the save game after all. +	// Of course we could just decide to not use _CLUT_offs anymore, and change +	// setPaletteFromRes() to invoke findResourceData() each time +	// (and also getPalettePtr()).  	if (_features & GF_SMALL_HEADER)  		ptr = findResourceSmall(MKID('CLUT'), roomptr);  	else @@ -806,13 +805,10 @@ void Scumm::initRoomSubBlocks()  		}  	} -	if (_features & GF_SMALL_HEADER) -		ptr = findResourceData(MKID('CYCL'), roomptr); -	else -		ptr = findResourceData(MKID('CYCL'), roomptr); +	ptr = findResourceData(MKID('CYCL'), roomptr);  	if (ptr) -		initCycl(findResourceData(MKID('CYCL'), roomptr)); +		initCycl(ptr);  	ptr = findResourceData(MKID('TRNS'), roomptr);  	if (ptr) @@ -897,125 +893,6 @@ int Scumm::checkKeyHit()  	return a;  } -void Scumm::unkRoomFunc3(int unk1, int unk2, int rfact, int gfact, int bfact) -{ -	byte *pal = _currentPalette; -	byte *table = _shadowPalette; -	int i; - -	warning("unkRoomFunc3(%d,%d,%d,%d,%d): not fully implemented", unk1, unk2, rfact, gfact, bfact); - -	// TODO - correctly implement this function (see also patch #588501) -	// -	// Some "typical" examples of how this function is being invoked in real life: -	// -	// unkRoomFunc3(16, 255, 200, 200, 200) -	// -	// FOA: Sets up the colors for the boat and submarine shadows in the -	// diving scene. Are the shadows too light? Maybe unk1 is used to -	// darken the colors? -	// -	// unkRoomFunc3(0, 255, 700, 700, 700) -	// -	// FOA: Sets up the colors for the subway car headlight when it first -	// goes on. This seems to work ok. -	// -	// unkRoomFunc3(160, 191, 300, 300, 300) -	// unkRoomFunc3(160, 191, 289, 289, 289) -	//     ... -	// unkRoomFunc3(160, 191, 14, 14, 14) -	// unkRoomFunc3(160, 191, 3, 3, 3) -	// -	// FOA: Sets up the colors for the subway car headlight for the later -	// half of the trip, where it fades out. This currently doesn't work -	// at all. The colors are too dark to be brightened. At first I thought -	// unk1 and unk2 were used to tell which color interval to manipulate, -	// but as far as I can tell the colors 160-191 aren't used at all to -	// draw the light, that can't be it. Apparently unk1 and/or unk2 are -	// used to brighten the colors. -	 -	for (i = 0; i <= 255; i++) { -		int r = (int) (*pal++ * rfact) >> 8; -		int g = (int) (*pal++ * gfact) >> 8; -		int b = (int) (*pal++ * bfact) >> 8; - -		*table++ = remapPaletteColor(r, g, b, (uint) -1); -	} -} - - -void Scumm::palManipulate(int start, int end, int d, int time, int e) -{ -	// TODO - correctly implement this function (see also bug #558245) -	// -	// The only place I know of where this function is being called is in the  -	// FOA extro, to change the color to match the sinking sun. The following -	// three calls (with some pauses between them) are issued: -	// -	// palManipulate(16, 190, 32, 180, 1) -	// palManipulate(16, 190, 32, 1, 1) -	// palManipulate(16, 190, 32, 800, 1) -	// -	// The first two parameters seem to specify a palette range (as the colors -	// from 16 to 190 are the ones that make up water & sky). -	// -	// Maybe the change has to be done over a period of time, possibly specified -	// by the second last parameter - between call 1 and 2, about 17-18 seconds -	// seem to pass (well using get_msecs, I measured 17155 ms, 17613 ms, 17815 ms). -	// -	// No clue about the third and fifth parameter right now, they just always -	// are 32 and 1 - possibly finding another example of this function being -	// used would help a lot. Also, I can't currently compare it with the original, -	// doing that (and possibly, taking screenshots of it for analysis!) would  -	// help a lot. -	 -	static int sys_time = 0; -	int new_sys_time = _system->get_msecs(); -	 -	warning("palManipulate(%d, %d, %d, %d, %d): not implemented", start, end, d, time, e); -	if (sys_time != 0) -		printf("Time since last call: %d\n", new_sys_time-sys_time); -	sys_time = new_sys_time; -	 -	{ -		int redScale = 0xFF; -		int greenScale = 0xFF - d; -		int blueScale = 0xFF - d; -		byte *cptr; -		byte *cur; -		int num; -		int color; -	 -		cptr = _currentPalette + start * 3; -		cur = _currentPalette + start * 3; -		num = end - start + 1; - -		do { -			color = *cptr++; -			if (redScale != 0xFF) -				color = color * redScale / 0xFF; -			if (color > 255) -				color = 255; -			*cur++ = color; - -			color = *cptr++; -			if (greenScale != 0xFF) -				color = color * greenScale / 0xFF; -			if (color > 255) -				color = 255; -			*cur++ = color; - -			color = *cptr++; -			if (blueScale != 0xFF) -				color = color * blueScale / 0xFF; -			if (color > 255) -				color = 255; -			*cur++ = color; -		} while (--num); -		setDirtyColors(start, end); -	} -} -  void Scumm::pauseGame(bool user)  {  	//_gui->pause();  | 
