aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Hesse2008-12-11 21:57:47 +0000
committerSven Hesse2008-12-11 21:57:47 +0000
commitc65886a3ea3a4fb30d34d9cc3136dd34db044d9f (patch)
treea1cfd571f84f64acd153ec1432e0124997183573
parent443158fd89af3dbe22577c7ffaaf2d6e6396d355 (diff)
downloadscummvm-rg350-c65886a3ea3a4fb30d34d9cc3136dd34db044d9f.tar.gz
scummvm-rg350-c65886a3ea3a4fb30d34d9cc3136dd34db044d9f.tar.bz2
scummvm-rg350-c65886a3ea3a4fb30d34d9cc3136dd34db044d9f.zip
Changing the Urban Runner sprite drawer to work more correctly. It does use YUV data, but I can use the ditherer there
svn-id: r35308
-rw-r--r--engines/gob/draw_v2.cpp17
-rw-r--r--engines/gob/game.cpp28
-rw-r--r--engines/gob/game.h1
-rw-r--r--engines/gob/indeo3.cpp22
-rw-r--r--engines/gob/indeo3.h10
-rw-r--r--engines/gob/inter_v1.cpp11
-rw-r--r--engines/gob/video.h8
-rw-r--r--engines/gob/video_v6.cpp110
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 &params) {
}
bool Inter_v1::o1_copySprite(OpFuncParams &params) {
- _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