diff options
| -rw-r--r-- | scumm/nut_renderer.cpp | 192 | ||||
| -rw-r--r-- | scumm/nut_renderer.h | 5 | ||||
| -rw-r--r-- | scumm/smush/codec1.cpp | 6 | ||||
| -rw-r--r-- | scumm/smush/smush_player.cpp | 6 | 
4 files changed, 61 insertions, 148 deletions
diff --git a/scumm/nut_renderer.cpp b/scumm/nut_renderer.cpp index 9cbce81c4b..ad534f0894 100644 --- a/scumm/nut_renderer.cpp +++ b/scumm/nut_renderer.cpp @@ -44,74 +44,34 @@ NutRenderer::~NutRenderer() {  	}  } -int32 NutRenderer::decodeCodec44(byte *dst, const byte *src, uint32 length) { -	byte val; -	uint16 size_line, num; -	int16 decoded_length = 0; - -	do { -		size_line = READ_LE_UINT16(src); -		src += 2; -		length -= 2; - -		while (size_line != 0) { -			num = *src++; -			val = *src++; -			memset(dst, val, num); -			dst += num; -			decoded_length += num; -			length -= 2; -			size_line -= 2; -			if (size_line != 0) { -				num = READ_LE_UINT16(src) + 1; -				src += 2; -				memcpy(dst, src, num); -				dst += num; -				decoded_length += num; -				src += num; -				length -= num + 2; -				size_line -= num + 2; +void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch); + +static void smush_decode_codec21(byte *dst, const byte *src, int width, int height, int pitch) { +	while (height--) { +		uint8 *dstPtrNext = dst + pitch; +		const uint8 *srcPtrNext = src + 2 + READ_LE_UINT16(src); src += 2; +		int len = width; +		do { +			int offs = READ_LE_UINT16(src); src += 2; +			dst += offs; +			len -= offs; +			if (len <= 0) { +				break;  			} -		} -		dst--; -		decoded_length--; - -	} while (length > 1); -	return decoded_length; -} - -static int32 codec1(byte *dst, byte *src, int height) { -	byte val, code; -	int32 length, decoded_length = 0; -	int h = height, size_line; - -	for (h = 0; h < height; h++) { -		size_line = READ_LE_UINT16(src); -		src += 2; -		while (size_line > 0) { -			code = *src++; -			size_line--; -			length = (code >> 1) + 1; -			if (code & 1) { -				val = *src++; -				size_line--; -				if (val) -					memset(dst, val, length); -				dst += length; -				decoded_length += length; -			} else { -				size_line -= length; -				while (length--) { -					val = *src++; -					if (val) -						*dst = val; -					dst++; -					decoded_length++; -				} +			int w = READ_LE_UINT16(src) + 1; src += 2; +			len -= w; +			if (len < 0) { +				w += len;  			} -		} +			// the original codec44 handles this part slightly differently (this is the only difference with codec21) : +			//  src bytes equal to 255 are replaced by 0 in dst +			//  src bytes equal to 1 are replaced by a color passed as an argument in the original function +			//  other src bytes values are copied as-is +			memcpy(dst, src, w); dst += w; src += w; +		} while (len > 0); +		dst = dstPtrNext; +		src = srcPtrNext;  	} -	return decoded_length;  }  bool NutRenderer::loadFont(const char *filename) { @@ -145,51 +105,41 @@ bool NutRenderer::loadFont(const char *filename) {  	_numChars = READ_LE_UINT16(dataSrc + 10);  	uint32 offset = 0; -	int32 decoded_length; -  	for (int l = 0; l < _numChars; l++) {  		offset += READ_BE_UINT32(dataSrc + offset + 4) + 8; -		if (READ_BE_UINT32(dataSrc + offset) == 'FRME') { -			offset += 8; - -			if (READ_BE_UINT32(dataSrc + offset) == 'FOBJ') { -				int codec = READ_LE_UINT16(dataSrc + offset + 8); -				_chars[l].xoffs = READ_LE_UINT16(dataSrc + offset + 10); -				_chars[l].yoffs = READ_LE_UINT16(dataSrc + offset + 12); -				_chars[l].width = READ_LE_UINT16(dataSrc + offset + 14); -				_chars[l].height = READ_LE_UINT16(dataSrc + offset + 16); -				_chars[l].src = new byte[(_chars[l].width + 2) * _chars[l].height + 1000]; - -				// If characters have transparency, then bytes just get skipped and -				// so there may appear some garbage. That's why we have to fill it -				// with zeroes first. -				memset(_chars[l].src, 0, (_chars[l].width + 2) * _chars[l].height + 1000); -				if ((codec == 44) || (codec == 21))  -					decoded_length = decodeCodec44(_chars[l].src, dataSrc + offset + 22, READ_BE_UINT32(dataSrc + offset + 4) - 14); -				else if (codec == 1) { -					decoded_length = codec1(_chars[l].src, dataSrc + offset + 22, _chars[l].height); -				} else -					error("NutRenderer::loadFont: unknown codec: %d", codec); - -				// FIXME: This is used to work around wrong font file format in Russian  -				// version of FT. Font files there contain wrong information about -				// glyphs width. See patch #823031. -				if (_vm->_language == Common::RU_RUS) { -					// try to rely on length of returned data -				  	if (l > 127) -						_chars[l].width = decoded_length / _chars[l].height; -					// but even this not always works -					if (l == 134 && !strcmp(filename, "titlfnt.nut")) -						_chars[l].width--; -				} -			} else { -				warning("NutRenderer::loadFont(%s) there is no FOBJ chunk in FRME chunk %d (offset %x)", filename, l, offset); -				break; -			} -		} else { +		if (READ_BE_UINT32(dataSrc + offset) != 'FRME') {  			warning("NutRenderer::loadFont(%s) there is no FRME chunk %d (offset %x)", filename, l, offset);  			break;  		} +		offset += 8; +		if (READ_BE_UINT32(dataSrc + offset) != 'FOBJ') { +			warning("NutRenderer::loadFont(%s) there is no FOBJ chunk in FRME chunk %d (offset %x)", filename, l, offset); +			break; +		} +		int codec = READ_LE_UINT16(dataSrc + offset + 8); +		_chars[l].xoffs = READ_LE_UINT16(dataSrc + offset + 10); +		_chars[l].yoffs = READ_LE_UINT16(dataSrc + offset + 12); +		_chars[l].width = READ_LE_UINT16(dataSrc + offset + 14); +		_chars[l].height = READ_LE_UINT16(dataSrc + offset + 16); +		const int srcSize = _chars[l].width * _chars[l].height; +		_chars[l].src = new byte[srcSize]; +		// If characters have transparency, then bytes just get skipped and +		// so there may appear some garbage. That's why we have to fill it +		// with zeroes first. +		memset(_chars[l].src, 0, srcSize); +		 +		const uint8 *fobjptr = dataSrc + offset + 22; +		switch (codec) { +		case 1: +			smush_decode_codec1(_chars[l].src, fobjptr, 0, 0, _chars[l].width, _chars[l].height, _chars[l].width); +			break; +		case 21: +		case 44: +			smush_decode_codec21(_chars[l].src, fobjptr, _chars[l].width, _chars[l].height, _chars[l].width); +			break; +		default: +			error("NutRenderer::loadFont: unknown codec: %d", codec); +		}  	}  	free(dataSrc); @@ -227,38 +177,6 @@ int NutRenderer::getCharHeight(byte c) const {  	return _chars[c].height;  } -int NutRenderer::getCharOffsX(byte c) const { -	if (!_loaded) { -		warning("NutRenderer::getCharOffsX() Font is not loaded"); -		return 0; -	} - -	if (c >= 0x80 && _vm->_useCJKMode) { -		return 0; -	} - -	if (c >= _numChars) -		error("invalid character in NutRenderer::getCharOffsX : %d (%d)", c, _numChars); - -	return _chars[c].xoffs; -} - -int NutRenderer::getCharOffsY(byte c) const { -	if (!_loaded) { -		warning("NutRenderer::getCharOffsY() Font is not loaded"); -		return 0; -	} - -	if (c >= 0x80 && _vm->_useCJKMode) { -		return 0; -	} - -	if (c >= _numChars) -		error("invalid character in NutRenderer::getCharOffsY : %d (%d)", c, _numChars); - -	return _chars[c].yoffs; -} -  void NutRenderer::drawShadowChar(const Graphics::Surface &s, int c, int x, int y, byte color, bool showShadow) {  	if (!_loaded) {  		warning("NutRenderer::drawShadowChar() Font is not loaded"); diff --git a/scumm/nut_renderer.h b/scumm/nut_renderer.h index 1cf3ebe09c..5c47e7edb2 100644 --- a/scumm/nut_renderer.h +++ b/scumm/nut_renderer.h @@ -42,8 +42,6 @@ protected:  		byte *src;  	} _chars[256]; -	int32 decodeCodec44(byte *dst, const byte *src, uint32 length); -  	void drawChar(const Graphics::Surface &s, byte c, int x, int y, byte color);  	void draw2byte(const Graphics::Surface &s, int c, int x, int y, byte color); @@ -59,9 +57,6 @@ public:  	int getCharWidth(byte c) const;  	int getCharHeight(byte c) const; - -	int getCharOffsX(byte c) const; -	int getCharOffsY(byte c) const;  };  } // End of namespace Scumm diff --git a/scumm/smush/codec1.cpp b/scumm/smush/codec1.cpp index b771c57982..fb10bb5a6b 100644 --- a/scumm/smush/codec1.cpp +++ b/scumm/smush/codec1.cpp @@ -24,12 +24,12 @@  namespace Scumm { -void smush_decode_codec1(byte *dst, byte *src, int left, int top, int height, int width, int dstWidth) { +void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch) {  	byte val, code;  	int32 length;  	int h = height, size_line; -	dst += top * dstWidth; +	dst += top * pitch;  	for (h = 0; h < height; h++) {  		size_line = READ_LE_UINT16(src);  		src += 2; @@ -54,7 +54,7 @@ void smush_decode_codec1(byte *dst, byte *src, int left, int top, int height, in  				}  			}  		} -		dst += dstWidth - left - width; +		dst += pitch - left - width;  	}  } diff --git a/scumm/smush/smush_player.cpp b/scumm/smush/smush_player.cpp index e55aa258f1..fd5bc55315 100644 --- a/scumm/smush/smush_player.cpp +++ b/scumm/smush/smush_player.cpp @@ -724,7 +724,7 @@ void SmushPlayer::handleNewPalette(Chunk &b) {  	setDirtyColors(0, 255);  } -void smush_decode_codec1(byte *dst, byte *src, int left, int top, int height, int width, int dstWidth); +void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch);  #ifdef USE_ZLIB  void SmushPlayer::handleZlibFrameObject(Chunk &b) { @@ -781,7 +781,7 @@ void SmushPlayer::handleZlibFrameObject(Chunk &b) {  	switch (codec) {  	case 1:  	case 3: -		smush_decode_codec1(_dst, fobjBuffer + 14, left, top, height, width, _vm->_screenWidth); +		smush_decode_codec1(_dst, fobjBuffer + 14, left, top, width, height, _vm->_screenWidth);  		break;  	case 37:  		_codec37.decode(_dst, fobjBuffer + 14); @@ -855,7 +855,7 @@ void SmushPlayer::handleFrameObject(Chunk &b) {  	switch (codec) {  	case 1:  	case 3: -		smush_decode_codec1(_dst, chunk_buffer, left, top, height, width, _vm->_screenWidth); +		smush_decode_codec1(_dst, chunk_buffer, left, top, width, height, _vm->_screenWidth);  		break;  	case 37:  		_codec37.decode(_dst, chunk_buffer);  | 
