diff options
Diffstat (limited to 'scumm/costume.cpp')
| -rw-r--r-- | scumm/costume.cpp | 194 | 
1 files changed, 193 insertions, 1 deletions
| diff --git a/scumm/costume.cpp b/scumm/costume.cpp index 2a43fc38c4..f8946608b8 100644 --- a/scumm/costume.cpp +++ b/scumm/costume.cpp @@ -564,6 +564,185 @@ void CostumeRenderer::proc3_ami(Codec1 &v1) {  	} while (1);  } +static const int v1MMNESLookup[25] = { +	0x00, 0x03, 0x01, 0x06, 0x08, +	0x02, 0x00, 0x07, 0x0C, 0x04, +	0x09, 0x0A, 0x12, 0x0B, 0x14, +	0x0D, 0x11, 0x0F, 0x0E, 0x10, +	0x17, 0x00, 0x01, 0x05, 0x16  +}; + +static const int v1MMNEScostTables[2][6] = { +     /* desc lens offs data  gfx  pal */ +	{ 25,  27,  29,  31,  33,  35}, +	{ 26,  28,  30,  32,  34,  36} +}; +/** + * costume ID -> v1MMNESLookup[] -> desc -> lens & offs -> data -> Gfx & pal + */ +void LoadedCostume::loadNEScostume(void) { +	const byte *src; +	int frameset, framenum; +	int offset, numSprites, spritesOffset, maxSprites, numAnims; +	byte *table, *ptr, *patTable, *spritesDefs, *spritesOffsetTab, *numSpritesTab; +	bool flip; +	int palette, tile; +	byte patData[16 * 256]; +	int len; +	int i, j; +	byte x, y; +	int8 x1, y1; + +	_format = 0x01; +	_mirror = 0; +	_dataOffsets = _baseptr + 4; + +	frameset = 0; +	framenum = 0; + +	src = _baseptr + 4; +	// Cost(a) +	offset = src[(frameset * 4 + framenum) * 2]; +	numAnims = src[(frameset * 4 + framenum) * 2 + 1]; + +	// Lookup & desc +	table = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][0]); +	offset = READ_LE_UINT16(table + v1MMNESLookup[_id] * 2 + 2); + +	if (v1MMNESLookup[_id] * 2 >= READ_LE_UINT16(table)) { +		_numAnim = (READ_LE_UINT16(table) - v1MMNESLookup[_id] * 2) / 2; // should never happen +	} else { +		_numAnim = (READ_LE_UINT16(table + v1MMNESLookup[_id] * 2 + 4) - offset) / 2; +	} + +	// lens +	numSpritesTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][1]); + +	// offs +	spritesOffsetTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][2]); + +	// data +	spritesDefs = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][3]); + +	// gfx +	patTable = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][4]); + +	for (int frameNum = 0; frameNum < _numAnim; frameNum++) { +		offset = READ_LE_UINT16(table + v1MMNESLookup[_id] * 2 + 2 + frameNum * 2); +		numSprites = numSpritesTab[offset + 2] + 1; +		spritesOffset = READ_LE_UINT16(spritesOffsetTab + offset * 2 + 2); + + +		//printf("spritesOffset: %x", spritesOffset); +		ptr = spritesDefs + spritesOffset + 2; + +		byte mask; +		// decode costumegfx and get data +		maxSprites = patTable[3]; +		len = READ_LE_UINT16(patTable); + +		j = 0; +		i = 3; +		while (i < len) { +			if (patTable[i] > 0x80) { +				for (int cnt = (patTable[i++] & ~0x80); cnt > 0; cnt--) +					patData[j++] = patTable[i++]; +			} else { +				for (int cnt = patTable[i++]; cnt > 0; cnt--) +					patData[j++] = patTable[i]; +				i++; +			} +		} +		/* +		printf("extracted len: %d", j); + +		for (j = 0; j < 5; j++) { +			for (i = 0; i < 16; i++) +				printf("%02x ", patData[j * 16 + i]); +			printf("\n"); +		} +		*/ + +		byte pic[256][256]; +		for (i = 0; i < 256; i++) +			for(j = 0; j < 256; j++) +				pic[i][j] = ' '; + +		for (int spr = 0; spr < numSprites; spr++) { +			flip = ((*ptr & 0x80) != 0); +			 +			y1 = *ptr++; +			y1 |= (int8)0x80; +			y1 += (int8)0x80; +			y = y1; + +			tile = *ptr++; + +			x1 = *ptr >> 2; + +			if (*ptr & 0x80) +				x1 |= (int8)0xc0; +			x1 += (int8)0x80; +			x = x1; + +			palette = *ptr++ & 0x3; + +			mask = flip ? 0x01 : 0x80; + +#define SHIFT 0 + +			for (i = 0; i < 8; i++) { +				byte c = patData[tile * 16 + i]; +				for (j = 0; j < 8; j++) { +					pic[SHIFT + j + x][SHIFT + i + y] = (c & mask) ? '.' : ' '; +					if (flip) +						c >>= 1; +					else +						c <<= 1; +				} +			} +			for (i = 0; i < 8; i++) { +				byte c = patData[tile * 16 + i + 8]; +				for (j = 0; j < 8; j++) { +					if (pic[SHIFT + j + x][SHIFT + i + y] == '.') +						pic[SHIFT + j + x][SHIFT + i + y] = (c & mask) ? '#' : '.'; +					else +						pic[SHIFT + j + x][SHIFT + i + y] = (c & mask) ? '*' : ' '; +					if (flip) +						c >>= 1; +					else +						c <<= 1; +				} +			} +			//printf("flip: %d (%d), tile: %x, x: %d, y: %d, pal: %d", flip, (tile % 1) ? flip : !flip, tile, x, y, palette); +		} +	 +		int left = 256, top = 256, right = 0, bottom = 0; +		 +		for (i = 0; i < 256; i++) +			for(j = 0; j < 256; j++) +				if (pic[j][i] != ' ') { +					if (left > j) +						left = j; +					if (right < j) +						right = j; +					if (top > i) +						top = i; +					if (bottom < i) +						bottom = i; +			} + +		/*	 +		for (i = top; i <= bottom; i++) { +			for(j = left; j <= right; j++) +				printf("%c", pic[j][i]); +			printf("\n"); +		} +		*/ +	} +		 +} +  void LoadedCostume::loadCostume(int id) {  	_id = id;  	byte *ptr = _vm->getResourceAddress(rtCostume, id); @@ -579,6 +758,10 @@ void LoadedCostume::loadCostume(int id) {  	_baseptr = ptr; +	if (_vm->_features & GF_NES) { +		loadNEScostume(); +		return; +	}  	_numAnim = ptr[6];  	_format = ptr[7] & 0x7F;  	_mirror = (ptr[7] & 0x80) != 0; @@ -697,6 +880,13 @@ void ScummEngine::cost_decodeData(Actor *a, int frame, uint usemask) {  		return;  	} +	if (_features & GF_NES) { +		a->_cost.curpos[0] = 0xFFFF; +		a->_cost.start[0] = 0; +		a->_cost.frame[0] = frame; +		return; +	} +  	r = lc._baseptr + READ_LE_UINT16(lc._dataOffsets + anim * 2);  	if (r == lc._baseptr) { @@ -756,7 +946,9 @@ void CostumeRenderer::setPalette(byte *palette) {  	int i;  	byte color; -	if (_loaded._format == 0x57) { +	if (_vm->_features & GF_NES) { +		// TODO +	} else if (_loaded._format == 0x57) {  		memcpy(_palette, palette, 13);  	} else if (_vm->_features & GF_OLD_BUNDLE) {  		if ((_vm->VAR(_vm->VAR_CURRENT_LIGHTS) & LIGHTMODE_actor_color)) { | 
