diff options
| author | Scott Thomas | 2009-08-30 23:57:43 +0000 | 
|---|---|---|
| committer | Scott Thomas | 2009-08-30 23:57:43 +0000 | 
| commit | 5791d475f52b3ed44de795555e5eacce21be5f1a (patch) | |
| tree | c877f10935bb517e87f8f1481ba7e3d0f33dda21 | |
| parent | dd569a1b7e48569ee854759fd0cc45c66c0d5b10 (diff) | |
| download | scummvm-rg350-5791d475f52b3ed44de795555e5eacce21be5f1a.tar.gz scummvm-rg350-5791d475f52b3ed44de795555e5eacce21be5f1a.tar.bz2 scummvm-rg350-5791d475f52b3ed44de795555e5eacce21be5f1a.zip  | |
Groovie: Initial implementation cursors for Groovie V2
svn-id: r43842
| -rw-r--r-- | engines/groovie/cursor.cpp | 112 | 
1 files changed, 106 insertions, 6 deletions
diff --git a/engines/groovie/cursor.cpp b/engines/groovie/cursor.cpp index d7d9592420..3b6c7a93bd 100644 --- a/engines/groovie/cursor.cpp +++ b/engines/groovie/cursor.cpp @@ -239,14 +239,25 @@ public:  	void showFrame(uint16 frame);  private: -	//byte *_data; +	// Currently locked to 16bit +	byte *_img; + +	Graphics::PixelFormat _format; + +	void decodeFrame(byte *pal, byte *data, byte *dest);  };  Cursor_v2::Cursor_v2(Common::File &file) { +	byte *pal = new byte[0x20 * 3]; + +	_format = g_system->getScreenFormat(); +  	_numFrames = file.readUint16LE();  	_width = file.readUint16LE();  	_height = file.readUint16LE(); +	_img = new byte[_width * _height * _numFrames * 2]; +  	debugC(1, kGroovieDebugCursor | kGroovieDebugAll, "Groovie::Cursor: width: %d, height: %d, frames:%d", _width, _height, _numFrames);  	uint16 tmp16 = file.readUint16LE(); @@ -257,29 +268,118 @@ Cursor_v2::Cursor_v2(Common::File &file) {  	debugC(5, kGroovieDebugCursor | kGroovieDebugAll, "loop2count?: %d\n", loop2count);  	for (int l = 0; l < loop2count; l++) {  		tmp16 = file.readUint16LE(); -		debugC(5, kGroovieDebugCursor | kGroovieDebugAll, "loop2a: %d\n", tmp16); +		debugC(5, kGroovieDebugCursor | kGroovieDebugAll, "loop2a: %d\n", tmp16);	// Index frame can merge to/from?  		tmp16 = file.readUint16LE(); -		debugC(5, kGroovieDebugCursor | kGroovieDebugAll, "loop2b: %d\n", tmp16); +		debugC(5, kGroovieDebugCursor | kGroovieDebugAll, "loop2b: %d\n", tmp16);	// Number of frames?  	} -	file.seek(0x20 * 3, SEEK_CUR); +	file.read(pal, 0x20 * 3);  	for (int f = 0; f < _numFrames; f++) {  		uint32 tmp32 = file.readUint32LE();  		debugC(5, kGroovieDebugCursor | kGroovieDebugAll, "loop3: %d\n", tmp32); -		//file.seek(tmp32, SEEK_CUR);  		byte *data = new byte[tmp32];  		file.read(data, tmp32); -		//Common::hexdump(data, tmp32); +		decodeFrame(pal, data, _img + (f * _width * _height * 2)); +  		delete[] data;  	} + +	delete[] pal; +} + +void Cursor_v2::decodeFrame(byte *pal, byte *data, byte *dest) { +	// Scratch memory +	byte *tmp = new byte[_width * _height * 4]; +	byte *ptr = tmp; +	memset(tmp, 0, _width * _height * 4); + +	byte ctrA = 0, ctrB = 0; + +	byte alpha, palIdx; + +	byte r, g, b; + +	// Start frame decoding +	for (int y = 0; y < _height; y++) { +		for (int x = 0; x < _width; x++) { +			// If both counters are empty +			if (ctrA == 0 && ctrB == 0) { +				if (*data & 0x80) { +					ctrA = (*data++ & 0x7F) + 1; +				} else { +					ctrB = *data++ + 1; +					alpha = *data & 0xE0; +					palIdx = *data++ & 0x1F; +				} +			} + +			if (ctrA) { +				// Block type A - chunk of non-continuous pixels +				palIdx = *data & 0x1F; +				alpha = *data++ & 0xE0; + +				r = *(pal + palIdx); +				g = *(pal + palIdx + 0x20); +				b = *(pal + palIdx + 0x40); + +				ctrA--; +			} else { +				// Block type B - chunk of continuous pixels +				r = *(pal + palIdx); +				g = *(pal + palIdx + 0x20); +				b = *(pal + palIdx + 0x40); + +				ctrB--; +			} + +			// Decode pixel +			if (alpha) { +				if (alpha != 0xE0) { +					alpha = ((alpha << 8) / 224); + +					// TODO: The * 0 to be replaced by the component value of each pixel +					//       below, respectively - does blending +					r = (byte)((alpha * r + (256 - alpha) * 0) >> 8); +					g = (byte)((alpha * g + (256 - alpha) * 0) >> 8); +					b = (byte)((alpha * b + (256 - alpha) * 0) >> 8); +				} + +				*ptr = 1; +				*(ptr + 1) = r; +				*(ptr + 2) = g; +				*(ptr + 3) = b; +			} +			ptr += 4; +		} +	} + +	// Convert to screen format +	// NOTE: Currently locked to 16bit +	ptr = tmp; +	for (int y = 0; y < _height; y++) { +		for (int x = 0; x < _width; x++) { +			if (*ptr == 1) { +				*(uint16 *)dest = (uint16)_format.RGBToColor(*(ptr + 1), *(ptr + 2), *(ptr + 3)); +			} else { +				*(uint16 *)dest = 0; +			} +			dest += 2; +			ptr += 4; +		} +	} +	 +	 +	  }  void Cursor_v2::enable() {  }  void Cursor_v2::showFrame(uint16 frame) { +	int offset = _width * _height * frame * 2; +	CursorMan.replaceCursor((const byte *)(_img + offset), _width, _height, _width >> 1, _height >> 1, 0, 1, &_format);  }  | 
