diff options
| -rw-r--r-- | engines/gob/draw_v2.cpp | 17 | ||||
| -rw-r--r-- | engines/gob/game.cpp | 28 | ||||
| -rw-r--r-- | engines/gob/game.h | 1 | ||||
| -rw-r--r-- | engines/gob/indeo3.cpp | 22 | ||||
| -rw-r--r-- | engines/gob/indeo3.h | 10 | ||||
| -rw-r--r-- | engines/gob/inter_v1.cpp | 11 | ||||
| -rw-r--r-- | engines/gob/video.h | 8 | ||||
| -rw-r--r-- | engines/gob/video_v6.cpp | 110 | 
8 files changed, 165 insertions, 42 deletions
| diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index db2d23ac39..b5f0981c27 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -755,18 +755,29 @@ void Draw_v2::spriteOperation(int16 operation) {  	case DRAW_LOADSPRITE:  		id = _spriteLeft; -		if (id >= 30000) { -			dataBuf = -				_vm->_game->loadExtData(id, &_spriteRight, &_spriteBottom); + +		if ((id >= 30000) || (_vm->_game->_lomHandle >= 0)) { +			dataBuf = 0; + +			if (_vm->_game->_lomHandle >= 0) +				warning("Urban Stub: LOADSPRITE %d, LOM", id); +			else +				dataBuf = _vm->_game->loadExtData(id, &_spriteRight, &_spriteBottom); + +			if (!dataBuf) +				break; +  			_vm->_video->drawPackedSprite(dataBuf,  					_spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,  					_transparency, _spritesArray[_destSurface]);  			dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,  					_destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); +  			delete[] dataBuf;  			break;  		} +  		// Load from .TOT resources  		itemPtr = &_vm->_game->_totResourceTable->items[id];  		offset = itemPtr->offset; diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 8a6d6b6188..91d40f3d31 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -45,6 +45,7 @@ Game::Game(GobEngine *vm) : _vm(vm) {  	_totResourceTable = 0;  	_imFileData = 0;  	_extHandle = 0; +	_lomHandle = -1;  	_collisionAreas = 0;  	_shouldPushColls = 0; @@ -393,12 +394,33 @@ int32 Game::loadTotFile(const char *path) {  	int16 handle;  	int32 size; +	_lomHandle = -1; +  	size = -1;  	handle = _vm->_dataIO->openData(path);  	if (handle >= 0) { -		_vm->_dataIO->closeData(handle); -		size = _vm->_dataIO->getDataSize(path); -		_totFileData = _vm->_dataIO->getData(path); + +		if (!scumm_stricmp(path + strlen(path) - 3, "LOM")) { +			warning("Urban Stub: loadTotFile %s", path); + +			_lomHandle = handle; + +			DataStream *stream = _vm->_dataIO->openAsStream(handle); + +			stream->seek(48); +			size = stream->readUint32LE(); +			stream->seek(0); + +			_totFileData = new byte[size]; +			stream->read(_totFileData, size); + +			delete stream; +		} else { +			_vm->_dataIO->closeData(handle); +			size = _vm->_dataIO->getDataSize(path); +			_totFileData = _vm->_dataIO->getData(path); +		} +  	} else {  		Common::MemoryReadStream *videoExtraData = _vm->_vidPlayer->getExtraData(path); diff --git a/engines/gob/game.h b/engines/gob/game.h index 15f6ab963a..b60ef970bf 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -116,6 +116,7 @@ public:  	byte *_totFileData;  	int16 _extHandle; +	int16 _lomHandle;  	char _totToLoad[20]; diff --git a/engines/gob/indeo3.cpp b/engines/gob/indeo3.cpp index 3b8c94b5b4..a0ad509817 100644 --- a/engines/gob/indeo3.cpp +++ b/engines/gob/indeo3.cpp @@ -108,7 +108,7 @@ void PaletteLUT::buildNext() {  void PaletteLUT::build(int d1) {  	byte *lut = _lut + d1 * _dim2; -	warning("LUT %d/%d", d1, _dim1 - 1); +//	warning("LUT %d/%d", d1, _dim1 - 1);  	for (int j = 0; j < _dim1; j++) {  		for (int k = 0; k < _dim1; k++) { @@ -155,7 +155,7 @@ byte PaletteLUT::findNearest(byte c1, byte c2, byte c3, byte &nC1, byte &nC2, by  	return palIndex;  } -SierraLite::SierraLite(int16 width, int16 height, PaletteLUT *palLUT) { +SierraLight::SierraLight(int16 width, int16 height, PaletteLUT *palLUT) {  	assert((width > 0) && (height > 0));  	_width = width; @@ -170,24 +170,24 @@ SierraLite::SierraLite(int16 width, int16 height, PaletteLUT *palLUT) {  	_errors[1] = _errors[0] + 3 * (_width + 2*1);  } -SierraLite::~SierraLite() { +SierraLight::~SierraLight() {  	delete[] _errorBuf;  } -void SierraLite::newFrame() { +void SierraLight::newFrame() {  	_curLine = 0;  	memset(_errors[0], 0, 3 * _width * sizeof(int32));  	memset(_errors[1], 0, 3 * _width * sizeof(int32));  } -void SierraLite::nextLine() { +void SierraLight::nextLine() {  	// Clear the finished line, it will become the last line in the buffer  	memset(_errors[_curLine], 0, 3 * _width * sizeof(int32));  	_curLine = (_curLine + 1) % 2;  } -byte SierraLite::dither(byte c1, byte c2, byte c3, uint32 x) { +byte SierraLight::dither(byte c1, byte c2, byte c3, uint32 x) {  	assert(_palLUT);  	int32 eC1, eC2, eC3; @@ -214,7 +214,7 @@ byte SierraLite::dither(byte c1, byte c2, byte c3, uint32 x) {  	return newPixel;  } -inline void SierraLite::getErrors(uint32 x, int32 &eC1, int32 &eC2, int32 &eC3) { +inline void SierraLight::getErrors(uint32 x, int32 &eC1, int32 &eC2, int32 &eC3) {  	int32 *errCur = _errors[_curLine];  	x *= 3; @@ -223,7 +223,7 @@ inline void SierraLite::getErrors(uint32 x, int32 &eC1, int32 &eC2, int32 &eC3)  	eC3 = errCur[x + 2] >> 2;  } -inline void SierraLite::addErrors(uint32 x, int32 eC1, int32 eC2, int32 eC3) { +inline void SierraLight::addErrors(uint32 x, int32 eC1, int32 eC2, int32 eC3) {  	int32 *errCur  = _errors[_curLine];  	int32 *errNext = _errors[(_curLine + 1) % 2]; @@ -251,7 +251,7 @@ Indeo3::Indeo3(int16 width, int16 height, PaletteLUT *palLUT) {  	_palLUT = palLUT;  	_ditherSL = 0; -	setDither(kDitherSierraLite); +	setDither(kDitherSierraLight);  	buildModPred();  	allocFrames(); @@ -297,8 +297,8 @@ void Indeo3::setDither(DitherAlgorithm dither) {  	_dither = dither;  	switch(dither) { -	case kDitherSierraLite: -		_ditherSL = new SierraLite(_width, _height, _palLUT); +	case kDitherSierraLight: +		_ditherSL = new SierraLight(_width, _height, _palLUT);  		break;  	default: diff --git a/engines/gob/indeo3.h b/engines/gob/indeo3.h index 7a557f2a76..ae19b1cc1c 100644 --- a/engines/gob/indeo3.h +++ b/engines/gob/indeo3.h @@ -83,10 +83,10 @@ private:  };  // The Sierra-2-4A ("Filter Light") dithering algorithm -class SierraLite { +class SierraLight {  public: -	SierraLite(int16 width, int16 height, PaletteLUT *palLUT); -	~SierraLite(); +	SierraLight(int16 width, int16 height, PaletteLUT *palLUT); +	~SierraLight();  	void newFrame();  	void nextLine(); @@ -109,7 +109,7 @@ class Indeo3 {  public:  	enum DitherAlgorithm {  		kDitherNone = 0, -		kDitherSierraLite +		kDitherSierraLight  	};  	Indeo3(int16 width, int16 height, PaletteLUT *palLUT); @@ -151,7 +151,7 @@ private:  	PaletteLUT *_palLUT;  	DitherAlgorithm _dither; -	SierraLite *_ditherSL; +	SierraLight *_ditherSL;  	struct BlitState {  		uint32 curX, curY; diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index cd3fab944d..64a3b811ea 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1877,8 +1877,15 @@ bool Inter_v1::o1_loadSpriteContent(OpFuncParams ¶ms) {  }  bool Inter_v1::o1_copySprite(OpFuncParams ¶ms) { -	_vm->_draw->_sourceSurface = load16(); -	_vm->_draw->_destSurface = load16(); +	if (_vm->_global->_inter_execPtr[1] == 0) +		_vm->_draw->_sourceSurface = load16(); +	else +		_vm->_draw->_sourceSurface = _vm->_parse->parseValExpr(); + +	if (_vm->_global->_inter_execPtr[1] == 0) +		_vm->_draw->_destSurface = load16(); +	else +		_vm->_draw->_destSurface = _vm->_parse->parseValExpr();  	_vm->_draw->_spriteLeft = _vm->_parse->parseValExpr();  	_vm->_draw->_spriteTop = _vm->_parse->parseValExpr(); diff --git a/engines/gob/video.h b/engines/gob/video.h index 79a1029202..d519094cd2 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -216,6 +216,14 @@ public:  	Video_v6(GobEngine *vm);  	virtual ~Video_v6() {} + +private: +	void drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc *surfDesc); +	void drawYUVData(const byte *srcData, SurfaceDesc *destDesc, +			int16 width, int16 height, int16 x, int16 y); +	void drawYUV(SurfaceDesc *destDesc, int16 x, int16 y, +			int16 dataWidth, int16 dataHeight, int16 width, int16 height, +			const byte *dataY, const byte *dataU, const byte *dataV);  };  class VideoDriver { diff --git a/engines/gob/video_v6.cpp b/engines/gob/video_v6.cpp index 434406265e..3433e72bc5 100644 --- a/engines/gob/video_v6.cpp +++ b/engines/gob/video_v6.cpp @@ -27,6 +27,7 @@  #include "gob/gob.h"  #include "gob/video.h" +#include "gob/indeo3.h"  namespace Gob { @@ -40,30 +41,103 @@ char Video_v6::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,  	_vm->validateVideoMode(destDesc->_vidMode); -	if (sprBuf[0] != 1) -		return 0; +	if ((sprBuf[0] == 1) && (sprBuf[1] == 3)) { +		drawPacked(sprBuf, x, y, destDesc); +		return 1; +	} -	if (sprBuf[1] != 3) -		return 0; +	warning("Urban Stub: spriteUncompressor(), sprBuf[0,1] = %d,%d", +			sprBuf[0], sprBuf[1]); +	return 1; +} -	sprBuf += 2; +void Video_v6::drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc *surfDesc) { +	const byte *data = sprBuf + 2; -	srcWidth = READ_LE_UINT16(sprBuf); -	sprBuf += 2; -	srcHeight = READ_LE_UINT16(sprBuf); -	sprBuf += 2; +	int16 width = READ_LE_UINT16(data); +	int16 height = READ_LE_UINT16(data + 2); +	data += 4; -	if (sprBuf[0] == 0) { -		SurfaceDesc sourceDesc(0x13, srcWidth, srcHeight, sprBuf + 3); -		Video::drawSprite(&sourceDesc, destDesc, 0, 0, srcWidth - 1, -		    srcHeight - 1, x, y, transp); -		return 1; -	} else { -		warning("Urban Stub: spriteUncompressor()"); -		return 0; +	const byte *srcData = data; +	byte *uncBuf = 0; + +	if (*data++ != 0) { +		uint32 size = READ_LE_UINT32(data); + +		uncBuf = new byte[size]; + +		//sub_4F020(data, buf); +		warning("Urban Stub: drawPacked: sub_4F020(data, uncBuf)"); + +		srcData = uncBuf;  	} -	return 1; +	drawYUVData(srcData, surfDesc, width, height, x, y); + +	delete[] uncBuf;  } +void Video_v6::drawYUVData(const byte *srcData, SurfaceDesc *destDesc, +		int16 width, int16 height, int16 x, int16 y) { + +	int16 dataWidth = width; +	int16 dataHeight = height; + +	if (dataWidth & 0xF) +		dataWidth = (dataWidth & 0xFFF0) + 16; +	if (dataHeight & 0xF) +		dataHeight = (dataHeight & 0xFFF0) + 16; + +	const byte *dataY = srcData; +	const byte *dataU = dataY +  (dataWidth * dataHeight); +	const byte *dataV = dataU + ((dataWidth * dataHeight) >> 4); + +/* +	if (destDesc->field_14 == 1) { +		SurfaceDesc *tmpSurf = _vid_initSurfDesc(2, width, height, 0); + +		sub_46126(tmpSurf, 0, 0, dataWidth, dataHeight, width, height, dataY, dataU, dataV); + +		_vid_drawSprite(tmpSurf, destDesc, 0, 0, width - 1, height - 1, x, y, 0); + +		_vid_freeSurfDesc(tmpSurf); + +		return; +	} +*/ + +	drawYUV(destDesc, x, y, dataWidth, dataHeight, width, height, dataY, dataU, dataV); + +} + +void Video_v6::drawYUV(SurfaceDesc *destDesc, int16 x, int16 y, +		int16 dataWidth, int16 dataHeight, int16 width, int16 height, +		const byte *dataY, const byte *dataU, const byte *dataV) { + +	byte *vidMem = destDesc->getVidMem() + y * width + x; + +	width = MIN(width, destDesc->getWidth()); +	height = MIN(height, destDesc->getHeight()); + +	SierraLight *dither = new SierraLight(width, height, _palLUT); + +	for (int i = 0; i < height; i++) { +		byte *dest = vidMem; +		const byte *srcY = dataY +  i       *  dataWidth; +		const byte *srcU = dataU + (i >> 2) * (dataWidth >> 2); +		const byte *srcV = dataV + (i >> 2) * (dataWidth >> 2); + +		for (int j = 0; j < (width >> 2); j++, srcU++, srcV++) { +			for (int n = 0; n < 4; n++, dest++, srcY++) { +				byte dY = *srcY << 1, dU = *srcU << 1, dV = *srcV << 1; + +				*dest = dither->dither(dY, dU, dV, j * 4 + n); +			} +		} + +		dither->nextLine(); +		vidMem += width; +	} +}	 +  } // End of namespace Gob | 
