diff options
| author | Eugene Sandulenko | 2005-03-21 23:51:48 +0000 | 
|---|---|---|
| committer | Eugene Sandulenko | 2005-03-21 23:51:48 +0000 | 
| commit | 0bcb0ac2579faf061ec677e0b4ac8e37697d6dc7 (patch) | |
| tree | 83eabb9bb748ae9b72430bf409968fae4cf25f37 | |
| parent | 11a1f9bb00b5b008417e92e4d1c3fbfa8000d96d (diff) | |
| download | scummvm-rg350-0bcb0ac2579faf061ec677e0b4ac8e37697d6dc7.tar.gz scummvm-rg350-0bcb0ac2579faf061ec677e0b4ac8e37697d6dc7.tar.bz2 scummvm-rg350-0bcb0ac2579faf061ec677e0b4ac8e37697d6dc7.zip | |
Many MM NES fixes/improvements from Quietust:
  o Doesn't crash when going upstairs. Now game is playable up to
    the green tentacle
  o Proper subtitles colors
  o Room mask is decoded but doesn't affect sprites yet
  o Inventory draw issues fixed
  o Fix actors position when they're facing right
svn-id: r17191
| -rw-r--r-- | scumm/actor.cpp | 19 | ||||
| -rw-r--r-- | scumm/charset.cpp | 8 | ||||
| -rw-r--r-- | scumm/costume.cpp | 6 | ||||
| -rw-r--r-- | scumm/gfx.cpp | 45 | ||||
| -rw-r--r-- | scumm/gfx.h | 2 | ||||
| -rw-r--r-- | scumm/script_v2.cpp | 16 | ||||
| -rw-r--r-- | scumm/scumm.cpp | 4 | ||||
| -rw-r--r-- | scumm/verbs.cpp | 59 | 
8 files changed, 116 insertions, 43 deletions
| diff --git a/scumm/actor.cpp b/scumm/actor.cpp index ba1c1b81ad..15cbc22dbd 100644 --- a/scumm/actor.cpp +++ b/scumm/actor.cpp @@ -798,15 +798,16 @@ void Actor::showActor() {  // V1 Maniac doesn't have a ScummVar for VAR_TALK_ACTOR, and just uses  // an internal variable. Emulate this to prevent overwriting script vars... +// Maniac NES (V1), however, DOES have a ScummVar for VAR_TALK_ACTOR  int ScummEngine::getTalkingActor() { -	if (_gameId == GID_MANIAC && _version == 1) +	if (_gameId == GID_MANIAC && _version == 1 && !(_features & GF_NES))  		return _V1TalkingActor;  	else  		return VAR(VAR_TALK_ACTOR);  }  void ScummEngine::setTalkingActor(int value) { -	if (_gameId == GID_MANIAC && _version == 1) +	if (_gameId == GID_MANIAC && _version == 1 && !(_features & GF_NES))  		_V1TalkingActor = value;  	else  		VAR(VAR_TALK_ACTOR) = value; @@ -1012,7 +1013,12 @@ void Actor::drawActorCostume(bool hitTestMode) {  	bcr->_actorX = _pos.x + _offsX - _vm->virtscr[0].xstart;  	bcr->_actorY = _pos.y + _offsY - _elevation; -	if ((_vm->_version <= 2) && !(_vm->_features & GF_NES)) { +	if (_vm->_features & GF_NES) { +		// In the NES version, when the actor is facing right, +		// we need to shift it 8 pixels to the left +		if (_facing == 90) +			bcr->_actorX -= 8; +	} else if (_vm->_version <= 2) {  		// HACK: We have to adjust the x position by one strip (8 pixels) in  		// V2 games. However, it is not quite clear to me why. And to fully  		// match the original, it seems we have to offset by 2 strips if the @@ -1280,6 +1286,13 @@ void ScummEngine::actorTalk(const byte *msg) {  	if (_heversion >= 72 || getTalkingActor() > 0x7F) {  		_charsetColor = (byte)_string[0].color; +	} else if (_features & GF_NES) { +		static int NES_lastActor = 0; +		static int NES_color = 0; +		if (NES_lastActor != getTalkingActor()) +			NES_color ^= 1; +		NES_lastActor = getTalkingActor(); +		_charsetColor = NES_color;  	} else {  		a = derefActor(getTalkingActor(), "actorTalk(2)");  		_charsetColor = a->_talkColor; diff --git a/scumm/charset.cpp b/scumm/charset.cpp index 0ad0f40b43..98d0b8810d 100644 --- a/scumm/charset.cpp +++ b/scumm/charset.cpp @@ -1732,12 +1732,6 @@ static byte trNESSwedishTable[] = {  	0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5e  }; -static byte NESColorTransition[] = { -	0x00, 0x02, 0x02, 0x03, 0x02, 0x01, 0x02, 0x03, -	0x00, 0x01, 0x02, 0x01, 0x00, 0x01, 0x00, 0x03 -}; - -  CharsetRendererNES::CharsetRendererNES(ScummEngine *vm, Common::Language language)  	: CharsetRendererCommon(vm) {  	switch (language) { @@ -1823,7 +1817,7 @@ void CharsetRendererNES::drawBits1(const Graphics::Surface &s, byte *dst, const  		byte c1 = src[i + 8];  		for (int j = 0; j < 8; j++)  			dst[j] = _vm->_NESPalette[((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) | -				(NESColorTransition[_color] << 2)]; +			(_color ? 12 : 8)];  		dst += s.pitch;  	}  } diff --git a/scumm/costume.cpp b/scumm/costume.cpp index 35c7b34e51..fb9fa72c9a 100644 --- a/scumm/costume.cpp +++ b/scumm/costume.cpp @@ -711,11 +711,17 @@ void CostumeRenderer::drawNESCostume(const Actor *a, int limb) {  		int8 x = ptr[2];	x >>= 2;  		ptr += 3; +  		if (flipped) {  			mask = (mask == 0x80) ? 0x01 : 0x80;  			x = -x;  		} +		if ((_actorX + x < 0) || (_actorX + x + 8 >= _out.w)) +			continue; +		if ((_actorY + y < 0) || (_actorY + y + 8 >= _out.h)) +			continue; +  		for (int ty = 0; ty < 8; ty++) {  			byte c1 = _vm->_NESCostumeGfx[_vm->_NESCostumeSet][tile * 16 + ty];  			byte c2 = _vm->_NESCostumeGfx[_vm->_NESCostumeSet][tile * 16 + ty + 8]; diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp index 9a9b16b46b..549438da07 100644 --- a/scumm/gfx.cpp +++ b/scumm/gfx.cpp @@ -1438,15 +1438,10 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi  			useOrDecompress = true;  		if (_vm->_version == 1) { +			mask_ptr = getMaskBuffer(x, y, 1);  			if (_vm->_features & GF_NES) { -				//mask_ptr = getMaskBuffer(x, y, 1); -				//for (int ii = 0; ii < height; ii++) { -				//	for (int jj = 0; jj < width; jj++) -				//		mask_ptr[jj] = 0xff; -				//	mask_ptr += _numStrips; -				//} +				drawStripNESMask(mask_ptr, stripnr, height);  			} else { -				mask_ptr = getMaskBuffer(x, y, 1);  				drawStripC64Mask(mask_ptr, stripnr, width, height);  			}  		} else if (_vm->_version == 2) { @@ -1889,7 +1884,25 @@ void Gdi::decodeNESGfx(const byte *room) {  			adata++;  	} -	// there's another pointer at room + 0x0E, but I don't know what data it points at +	const byte *mdata = room + READ_LE_UINT16(room + 0x0E); +	int mask = *mdata++; +	if (mask == 0) +		return; +	if (mask != 1) { +		debug(0,"NES room %i has irregular mask count %i!",_vm->_currentRoom,mask); +		return; +	} +	int mwidth = *mdata++; +	for (i = 0; i < 16; i++) { +		n = 0; +		while (n < mwidth) { +			byte data = *mdata++; +			for (j = 0; j < (data & 0x7F); j++) +				_NESMasktable[i][n++] = (data & 0x80) ? (*mdata++) : (*mdata); +			if (!(data & 0x80)) +				mdata++; +		} +	}  }  void Gdi::decodeNESObject(const byte *ptr, int xpos, int ypos, int width, int height) { @@ -1937,6 +1950,22 @@ void Gdi::drawStripNES(byte *dst, int dstPitch, int stripnr, int top, int height  	}  } +void Gdi::drawStripNESMask(byte *dst, int stripnr, int height) const { +	height /= 8; +	int x = stripnr; +	if (x > 63) { +		debug(0,"NES tried to mask invalid strip %i",stripnr); +		return; +	} +	for (int y = 0; y < height; y++) { +		byte c = ((_NESMasktable[y][x >> 3] >> (x & 7)) & 1) ? 0xFF : 0x00; +		for (int i = 0; i < 8; i++) { +			*dst = c; +			dst += _numStrips; +		} +	} +} +  void Gdi::drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height) {  	int charIdx;  	height /= 8; diff --git a/scumm/gfx.h b/scumm/gfx.h index 5d61c1da40..fd54c8cd9b 100644 --- a/scumm/gfx.h +++ b/scumm/gfx.h @@ -232,6 +232,7 @@ protected:  	byte _NESNametable[16][64], _NESAttributes[64];  	byte _NESBaseTiles;  	byte _NESNametableObj[16][64]; +	byte _NESMasktable[16][8];  	int _NESObj_x;  	/* Bitmap decompressors */ @@ -257,6 +258,7 @@ protected:  	/* Mask decompressors */  	void drawStripC64Mask(byte *dst, int stripnr, int width, int height) const; +	void drawStripNESMask(byte *dst, int stripnr, int height) const;  	void decompressMaskImgOr(byte *dst, const byte *src, int height) const;  	void decompressMaskImg(byte *dst, const byte *src, int height) const; diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp index bcc58c7417..c3397982e7 100644 --- a/scumm/script_v2.cpp +++ b/scumm/script_v2.cpp @@ -818,8 +818,10 @@ void ScummEngine_v2::o2_verbOps() {  		slot = getVarOrDirectByte(PARAM_1) + 1;  		int prep = fetchScriptByte(); // Only used in V1?  		// V1 Maniac verbs are relative to the 'verb area' - under the sentence -		if (_features & GF_NES) +		if (_features & GF_NES) {  			y -= 16; +			x -= 8; +		}  		else if ((_gameId == GID_MANIAC) && (_version == 1))  			y += 8; @@ -831,7 +833,11 @@ void ScummEngine_v2::o2_verbOps() {  		vs = &_verbs[slot];  		vs->verbid = verb; -		if (_version == 1) { +		if (_features & GF_NES) { +			vs->color = 1; +			vs->hicolor = 1; +			vs->dimcolor = 1; +		} else if (_version == 1) {  			vs->color = (_gameId == GID_MANIAC && _demoMode) ? 16 : 5;  			vs->hicolor = 7;  			vs->dimcolor = 11; @@ -851,7 +857,7 @@ void ScummEngine_v2::o2_verbOps() {  		vs->curRect.left = x;  		vs->curRect.top = y; -		 +  		// FIXME: again, this map depends on the language of the game.  		// E.g. a german keyboard has 'z' and 'y' swapped, while a french  		// keyboard starts with "awert", etc. @@ -1029,7 +1035,9 @@ void ScummEngine_v2::o2_drawSentence() {  	_string[2].charset = 1;  	_string[2].ypos = virtscr[2].topline;  	_string[2].xpos = 0; -	if (_version == 1) +	if (_features & GF_NES) +		_string[2].color = 0; +	else if (_version == 1)  		_string[2].color = 16;  	else   		_string[2].color = 13; diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index 75b9e31d2b..347d840252 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -1451,8 +1451,8 @@ void ScummEngine::scummInit() {  		VAR(VAR_CAMERA_ACCEL_Y) = 100;  	} else if (!(_features & GF_NEW_CAMERA)) {  		if (_features & GF_NES) { -			camera._leftTrigger = 4; -			camera._rightTrigger = 24; +			camera._leftTrigger = 6;	// 6 +			camera._rightTrigger = 21;	// 25  		} else {  			camera._leftTrigger = 10;  			camera._rightTrigger = (_heversion >= 71) ? 70 : 30; diff --git a/scumm/verbs.cpp b/scumm/verbs.cpp index 5eb3525a5a..be210b5239 100644 --- a/scumm/verbs.cpp +++ b/scumm/verbs.cpp @@ -40,7 +40,11 @@ void ScummEngine_v2::initV2MouseOver() {  	int i;  	int arrow_color, color, hi_color; -	if (_version == 1) { +	if (_features & GF_NES) { +		color = 0; +		hi_color = 0; +		arrow_color = 0; +	} else if (_version == 1) {  		color = 16;  		hi_color = 7;  		arrow_color = 6; @@ -57,7 +61,7 @@ void ScummEngine_v2::initV2MouseOver() {  	for (i = 0; i < 2; i++) {  		if (_features & GF_NES) {  			v2_mouseover_boxes[2 * i].rect.left = 0; -			v2_mouseover_boxes[2 * i].rect.right = 96; +			v2_mouseover_boxes[2 * i].rect.right = 104;  			v2_mouseover_boxes[2 * i].rect.top = 48 + 8 * i;  			v2_mouseover_boxes[2 * i].rect.bottom = v2_mouseover_boxes[2 * i].rect.top + 8;  		} else { @@ -71,7 +75,7 @@ void ScummEngine_v2::initV2MouseOver() {  		v2_mouseover_boxes[2 * i].hicolor = hi_color;  		if (_features & GF_NES) { -			v2_mouseover_boxes[2 * i + 1].rect.left = 128; +			v2_mouseover_boxes[2 * i + 1].rect.left = 120;  			v2_mouseover_boxes[2 * i + 1].rect.right = 224;  			v2_mouseover_boxes[2 * i + 1].rect.top = v2_mouseover_boxes[2 * i].rect.top;  			v2_mouseover_boxes[2 * i + 1].rect.bottom = v2_mouseover_boxes[2 * i].rect.bottom; @@ -89,8 +93,8 @@ void ScummEngine_v2::initV2MouseOver() {  	// Inventory arrows  	if (_features & GF_NES) { -		v2_mouseover_boxes[kInventoryUpArrow].rect.left = 96; -		v2_mouseover_boxes[kInventoryUpArrow].rect.right = 128; +		v2_mouseover_boxes[kInventoryUpArrow].rect.left = 104; +		v2_mouseover_boxes[kInventoryUpArrow].rect.right = 112;  		v2_mouseover_boxes[kInventoryUpArrow].rect.top = 48;  		v2_mouseover_boxes[kInventoryUpArrow].rect.bottom = 56;  	} else { @@ -104,10 +108,10 @@ void ScummEngine_v2::initV2MouseOver() {  	v2_mouseover_boxes[kInventoryUpArrow].hicolor = hi_color;  	if (_features & GF_NES) { -		v2_mouseover_boxes[kInventoryDownArrow].rect.left = 96; -		v2_mouseover_boxes[kInventoryDownArrow].rect.right = 128; -		v2_mouseover_boxes[kInventoryDownArrow].rect.top = 56; -		v2_mouseover_boxes[kInventoryDownArrow].rect.bottom = 64; +		v2_mouseover_boxes[kInventoryDownArrow].rect.left = 112; +		v2_mouseover_boxes[kInventoryDownArrow].rect.right = 120; +		v2_mouseover_boxes[kInventoryDownArrow].rect.top = 48; +		v2_mouseover_boxes[kInventoryDownArrow].rect.bottom = 56;  	} else {  		v2_mouseover_boxes[kInventoryDownArrow].rect.left = 144;  		v2_mouseover_boxes[kInventoryDownArrow].rect.right = 176; @@ -265,14 +269,25 @@ void ScummEngine::redrawV2Inventory() {  		const byte *tmp = getObjOrActorName(obj);  		assert(tmp); -		// Prevent inventory entries from overflowing by truncating the text -		// after 144/8 = 18 chars -		byte msg[18 + 1]; -		msg[18] = 0; -		strncpy((char *)msg, (const char *)tmp, 18); -		 -		// Draw it -		drawString(1, msg); +		if (_features & GF_NES) { +			// Prevent inventory entries from overflowing by truncating the text +			// after 104/8 = 13 chars +			byte msg[13 + 1]; +			msg[13] = 0; +			strncpy((char *)msg, (const char *)tmp, 13); +			 +			// Draw it +			drawString(1, msg); +		} else { +			// Prevent inventory entries from overflowing by truncating the text +			// after 144/8 = 18 chars +			byte msg[18 + 1]; +			msg[18] = 0; +			strncpy((char *)msg, (const char *)tmp, 18); +			 +			// Draw it +			drawString(1, msg); +		}  	} @@ -281,7 +296,10 @@ void ScummEngine::redrawV2Inventory() {  		_string[1].xpos = v2_mouseover_boxes[kInventoryUpArrow].rect.left;  		_string[1].ypos = v2_mouseover_boxes[kInventoryUpArrow].rect.top + vs->topline;  		_string[1].color = v2_mouseover_boxes[kInventoryUpArrow].color; -		drawString(1, (const byte *)" \1\2"); +		if (_features & GF_NES) +			drawString(1, (const byte *)"\x7E"); +		else +			drawString(1, (const byte *)" \1\2");  	}  	// If necessary, draw "down" arrow @@ -289,7 +307,10 @@ void ScummEngine::redrawV2Inventory() {  		_string[1].xpos = v2_mouseover_boxes[kInventoryDownArrow].rect.left;  		_string[1].ypos = v2_mouseover_boxes[kInventoryDownArrow].rect.top + vs->topline;  		_string[1].color = v2_mouseover_boxes[kInventoryDownArrow].color; -		drawString(1, (const byte *)" \3\4"); +		if (_features & GF_NES) +			drawString(1, (const byte *)"\x7F"); +		else +			drawString(1, (const byte *)" \3\4");  	}  } | 
