aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorGregory Montoir2004-10-17 04:35:36 +0000
committerGregory Montoir2004-10-17 04:35:36 +0000
commit3905129a9702e8f6db9b345734a27133fb630882 (patch)
tree448807e1daeb6103a19b397f3a6df4a4d0302dd7 /scumm
parentb41902f4079793236a20ebc380481fd598401c1d (diff)
downloadscummvm-rg350-3905129a9702e8f6db9b345734a27133fb630882.tar.gz
scummvm-rg350-3905129a9702e8f6db9b345734a27133fb630882.tar.bz2
scummvm-rg350-3905129a9702e8f6db9b345734a27133fb630882.zip
preliminar o72_captureWizImage() implementation ; still have to handle flag 0x2 in drawWizImage to display correctly the painting in 1grademo
svn-id: r15577
Diffstat (limited to 'scumm')
-rw-r--r--scumm/gfx.cpp2
-rw-r--r--scumm/intern.h9
-rw-r--r--scumm/script_v100he.cpp4
-rw-r--r--scumm/script_v72he.cpp263
-rw-r--r--scumm/script_v7he.cpp2
-rw-r--r--scumm/script_v90he.cpp38
-rw-r--r--scumm/vars.cpp4
7 files changed, 295 insertions, 27 deletions
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
index c44eb81d07..9fee74401d 100644
--- a/scumm/gfx.cpp
+++ b/scumm/gfx.cpp
@@ -584,7 +584,7 @@ void ScummEngine::initBGBuffers(int height) {
void ScummEngine::redrawBGAreas() {
int i;
int diff;
- int val = 0;;
+ int val = 0;
bool cont = true;
if (!(_features & GF_NEW_CAMERA))
diff --git a/scumm/intern.h b/scumm/intern.h
index a80cebe11b..4682be2683 100644
--- a/scumm/intern.h
+++ b/scumm/intern.h
@@ -716,6 +716,7 @@ protected:
uint8 *drawWizImage(int restype, const WizImage *pwi);
void drawWizPolygon(int resnum, int state, int id, int flags);
void flushWizBuffer();
+ void captureWizImage(int restype, int resnum, const Common::Rect& r, bool frontBuffer, int compType);
int findObject(int x, int y, int num, int *args);
virtual void decodeParseString(int a, int b);
@@ -835,15 +836,15 @@ protected:
int unk_130;
int unk_134;
int unk_138;
- int unk_148;
+ int compType;
int unk_14C;
int angle;
int zoom;
int unk_15C;
int unk_160;
- uint8 remapBuf1[256];
- uint8 remapBuf2[256];
- int remapPos;
+ uint8 remapColor[256];
+ uint8 remapIndex[256];
+ int remapNum;
WizImage img;
};
diff --git a/scumm/script_v100he.cpp b/scumm/script_v100he.cpp
index 90e81ca660..2f92d3d121 100644
--- a/scumm/script_v100he.cpp
+++ b/scumm/script_v100he.cpp
@@ -983,7 +983,7 @@ void ScummEngine_v100he::o100_wizImageOps() {
_wizParams.img.resNum = pop();
_wizParams.processMode = 0;
_wizParams.processFlags = 0;
- _wizParams.remapPos = 0;
+ _wizParams.remapNum = 0;
_wizParams.img.flags = 0;
break;
case 6:
@@ -998,7 +998,7 @@ void ScummEngine_v100he::o100_wizImageOps() {
_wizParams.box.right = pop();
_wizParams.box.top = pop();
_wizParams.box.left = pop();
- _wizParams.unk_148 = pop();
+ _wizParams.compType = pop();
break;
case 29:
_wizParams.processMode = 1;
diff --git a/scumm/script_v72he.cpp b/scumm/script_v72he.cpp
index a858188c6b..58e55a8f78 100644
--- a/scumm/script_v72he.cpp
+++ b/scumm/script_v72he.cpp
@@ -378,7 +378,7 @@ const char *ScummEngine_v72he::getOpcodeDesc(byte i) {
return _opcodesV72he[i].desc;
}
-static int arrayDataSizes[] = {0, 1, 4, 8, 8, 16, 32};
+static const int arrayDataSizes[] = { 0, 1, 4, 8, 8, 16, 32 };
ScummEngine_v72he::ArrayHeader *ScummEngine_v72he::defineArray(int array, int type, int dim2start, int dim2end,
int dim1start, int dim1end) {
@@ -728,7 +728,6 @@ void ScummEngine_v72he::o72_getObjectImageX() {
push(_objs[objnum].x_pos);
}
-
void ScummEngine_v72he::o72_getObjectImageY() {
int object = pop();
int objnum = getObjectIndex(object);
@@ -741,15 +740,259 @@ void ScummEngine_v72he::o72_getObjectImageY() {
push(_objs[objnum].y_pos);
}
-void ScummEngine_v72he::o72_captureWizImage() {
- // Drawing related
- int a = pop();
- int b = pop();
- int c = pop();
- int d = pop();
- int e = pop();
+struct wizPackCtx {
+ uint32 len;
+ uint8 saveCode;
+ uint8 saveBuf[0x100];
+};
+
+static void wizPackType1Helper1(uint8 *&dst, int len, byte newColor, byte prevColor, wizPackCtx *ctx) {
+ assert(len > 0);
+ if (newColor == prevColor) {
+ do {
+ int blockLen = MIN(len, 0x7F);
+ len -= blockLen;
+ if (dst) {
+ *dst++ = (blockLen * 2) | 1;
+ }
+ ++ctx->len;
+ } while (len > 0);
+ } else {
+ do {
+ int blockLen = MIN(len, 0x40);
+ len -= blockLen;
+ if (dst) {
+ *dst++ = ((blockLen - 1) * 4) | 2;
+ }
+ ++ctx->len;
+ if (dst) {
+ *dst++ = newColor;
+ }
+ ++ctx->len;
+ } while (len > 0);
+ }
+}
- debug(1, "stub o72_captureWizImage(%d, %d, %d, %d, %d)", a, b, c, d, e);
+static void wizPackType1Helper2(uint8 *&dst, int len, wizPackCtx *ctx) {
+ assert(len > 0);
+ const uint8 *src = ctx->saveBuf;
+ do {
+ int blockLen = MIN(len, 0x40);
+ len -= blockLen;
+ if (dst) {
+ *dst++ = (blockLen - 1) * 4;
+ }
+ ++ctx->len;
+ while (blockLen--) {
+ if (dst) {
+ *dst++ = *src++;
+ }
+ ++ctx->len;
+ }
+ } while (len > 0);
+}
+
+static int wizPackType1(uint8 *dst, const uint8 *src, int srcPitch, const Common::Rect& rCapt, uint8 tColor) {
+ debug(1, "wizPackType1(%d, [%d,%d,%d,%d])", tColor, rCapt.left, rCapt.top, rCapt.right, rCapt.bottom);
+ wizPackCtx ctx;
+ memset(&ctx, 0, sizeof(ctx));
+
+ src += rCapt.top * srcPitch + rCapt.left;
+ int w = rCapt.width();
+ int h = rCapt.height();
+
+ uint8 *nextDstPtr, *curDstPtr;
+ uint8 curColor, prevColor;
+ int saveBufPos;
+
+ nextDstPtr = curDstPtr = 0;
+
+ int dataSize = 0;
+ while (h--) {
+ if (dst) {
+ curDstPtr = dst;
+ nextDstPtr = dst;
+ dst += 2;
+ }
+ dataSize += 2;
+ int numBytes = 0;
+
+ int i, code;
+ for (i = 0; i < w; ++i) {
+ if (src[i] != tColor)
+ break;
+ }
+ if (i != w) {
+ curDstPtr = dst;
+ ctx.len = 0;
+ prevColor = ctx.saveBuf[0] = *src;
+ const uint8 *curSrcPtr = src + 1;
+ saveBufPos = 1;
+ code = (tColor - ctx.saveBuf[0] == 0) ? 1 : 0;
+ int curw = w;
+ while (curw--) {
+ ctx.saveBuf[saveBufPos] = curColor = *curSrcPtr++;
+ ++saveBufPos;
+ if (code == 0) {
+ if (curColor == tColor) {
+ --saveBufPos;
+ wizPackType1Helper2(curDstPtr, saveBufPos, &ctx);
+ code = saveBufPos = 1;
+ ctx.saveBuf[0] = curColor;
+ numBytes = 0;
+ prevColor = curColor;
+ continue;
+ }
+ if (saveBufPos > 0x80) {
+ --saveBufPos;
+ wizPackType1Helper2(curDstPtr, saveBufPos, &ctx);
+ saveBufPos = 1;
+ ctx.saveBuf[0] = curColor;
+ numBytes = 0;
+ prevColor = curColor;
+ continue;
+ }
+ if (prevColor != curColor) {
+ numBytes = saveBufPos - 1;
+ prevColor = curColor;
+ continue;
+ }
+ code = 1;
+ if (numBytes != 0) {
+ if (saveBufPos - numBytes < 3) {
+ code = 0;
+ } else {
+ wizPackType1Helper2(curDstPtr, numBytes, &ctx);
+ }
+ }
+ }
+ if (prevColor != curColor || saveBufPos - numBytes > 0x80) {
+ saveBufPos -= numBytes;
+ --saveBufPos;
+ wizPackType1Helper1(curDstPtr, saveBufPos, prevColor, tColor, &ctx);
+ saveBufPos = 1;
+ numBytes = 0;
+ ctx.saveBuf[0] = curColor;
+ code = (tColor - ctx.saveBuf[0] == 0) ? 1 : 0;
+ }
+ prevColor = curColor;
+ }
+ if (code == 0) {
+ wizPackType1Helper2(curDstPtr, saveBufPos, &ctx);
+ } else {
+ saveBufPos -= numBytes;
+ wizPackType1Helper1(curDstPtr, saveBufPos, prevColor, tColor, &ctx);
+ }
+ dataSize += ctx.len;
+ src += srcPitch;
+ if (dst) {
+ dst += ctx.len;
+ *(uint16 *)nextDstPtr = TO_LE_16(ctx.len);
+ }
+ }
+ }
+ return dataSize;
+}
+
+static int wizPackType0(uint8 *dst, const uint8 *src, int srcPitch, const Common::Rect& rCapt, uint8 tColor) {
+ int w = rCapt.width();
+ int h = rCapt.height();
+ int size = w * h;
+ if (dst) {
+ src += rCapt.top * srcPitch + rCapt.left;
+ while (h--) {
+ memcpy(dst, src, w);
+ dst += w;
+ src += srcPitch;
+ }
+ }
+ return size;
+}
+
+void ScummEngine_v72he::captureWizImage(int resType, int resNum, const Common::Rect& r, bool frontBuffer, int compType) {
+ debug(1, "ScummEngine_v72he::captureWizImage(%d, %d, %d, [%d,%d,%d,%d])", resType, resNum, compType, r.left, r.top, r.right, r.bottom);
+ uint8 *src = NULL;
+ VirtScreen *pvs = &virtscr[kMainVirtScreen];
+ if (frontBuffer) {
+ src = pvs->getPixels(0, 0);
+ } else {
+ src = pvs->getBackPixels(0, 0);
+ }
+ Common::Rect rCapt(0, 0, pvs->w, pvs->h);
+ if (rCapt.intersects(r)) {
+ rCapt.clip(r);
+ const uint8 *palPtr = _currentPalette;
+
+ int w = rCapt.width();
+ int h = rCapt.height();
+ int tColor = VAR(VAR_WIZ_TCOLOR);
+
+ // compute compressed size
+ int dataSize = 0;
+ int headerSize = palPtr ? 1080 : 36;
+ switch (compType) {
+ case 1:
+ dataSize = wizPackType1(0, src, pvs->pitch, rCapt, tColor);
+ break;
+ case 0:
+ dataSize = wizPackType0(0, src, pvs->pitch, rCapt, tColor);
+ break;
+ default:
+ warning("unhandled compression type %d", compType);
+ break;
+ }
+
+ // alignment
+ dataSize = (dataSize + 1) & ~1;
+ int wizSize = headerSize + dataSize;
+ // write header
+ uint8 *wizImg = createResource(resType, resNum, dataSize + headerSize);
+ *(uint32 *)(wizImg + 0x00) = MKID('AWIZ');
+ *(uint32 *)(wizImg + 0x04) = TO_BE_32(wizSize);
+ *(uint32 *)(wizImg + 0x08) = MKID('WIZH');
+ *(uint32 *)(wizImg + 0x0C) = TO_BE_32(0x14);
+ *(uint32 *)(wizImg + 0x10) = TO_LE_32(compType);
+ *(uint32 *)(wizImg + 0x14) = TO_LE_32(w);
+ *(uint32 *)(wizImg + 0x18) = TO_LE_32(h);
+ int curSize = 0x1C;
+ if (palPtr) {
+ *(uint32 *)(wizImg + 0x1C) = MKID('RGBS');
+ *(uint32 *)(wizImg + 0x20) = TO_BE_32(0x308);
+ memcpy(wizImg + 0x24, palPtr, 0x300);
+ *(uint32 *)(wizImg + 0x324) = MKID('RMAP');
+ *(uint32 *)(wizImg + 0x328) = TO_BE_32(0x10C);
+ *(uint32 *)(wizImg + 0x32C) = 0;
+ curSize = 0x330;
+ for (int i = 0; i < 256; ++i) {
+ wizImg[curSize] = i;
+ ++curSize;
+ }
+ }
+ *(uint32 *)(wizImg + curSize + 0x0) = MKID('WIZD');
+ *(uint32 *)(wizImg + curSize + 0x4) = TO_BE_32(dataSize + 8);
+ curSize += 8;
+
+ // write compressed data
+ switch (compType) {
+ case 1:
+ wizPackType1(wizImg + headerSize, src, pvs->pitch, rCapt, tColor);
+ break;
+ case 0:
+ wizPackType0(wizImg + headerSize, src, pvs->pitch, rCapt, tColor);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void ScummEngine_v72he::o72_captureWizImage() {
+ Common::Rect grab;
+ grab.bottom = pop() + 1;
+ grab.right = pop() + 1;
+ grab.top = pop();
+ grab.left = pop();
+ captureWizImage(rtImage, pop(), grab, false, true);
}
void ScummEngine_v72he::o72_getTimer() {
diff --git a/scumm/script_v7he.cpp b/scumm/script_v7he.cpp
index 7b3c58d64a..34795e5c3a 100644
--- a/scumm/script_v7he.cpp
+++ b/scumm/script_v7he.cpp
@@ -716,9 +716,11 @@ void ScummEngine_v70he::o70_kernelSetFunctions() {
break;
case 42:
// drawWizImage related
+ warning("o70_kernelSetFunctions: unhandled case 42");
break;
case 43:
// drawWizImage related
+ warning("o70_kernelSetFunctions: unhandled case 43");
break;
case 714:
break;
diff --git a/scumm/script_v90he.cpp b/scumm/script_v90he.cpp
index 203101756f..5c97e3e446 100644
--- a/scumm/script_v90he.cpp
+++ b/scumm/script_v90he.cpp
@@ -559,6 +559,9 @@ void ScummEngine_v90he::displayWizComplexImage(const WizParameters *params) {
} else if (flags & 0x40) {
drawWizPolygon(params->img.resNum, state, po_x, flags); // XXX , VAR(117));
} else {
+ if ((flags & 0x200) || (flags & 0x24)) {
+ warning("ScummEngine_v90he::displayWizComplexImage() unhandled flags = 0x%X", flags);
+ }
// XXX flags 0x200, 0x24
WizImage wi;
wi.resNum = params->img.resNum;
@@ -577,6 +580,9 @@ void ScummEngine_v90he::processWizImage(const WizParameters *params) {
case 1:
displayWizComplexImage(params);
break;
+ case 2:
+ captureWizImage(rtImage, params->img.resNum, params->box, (params->img.flags & 8) == 8, params->compType);
+ break;
case 3:
if (params->processFlags & 0x800) {
File f;
@@ -625,8 +631,22 @@ void ScummEngine_v90he::processWizImage(const WizParameters *params) {
}
}
break;
- case 2:
case 6:
+ if (params->processFlags & 0x40) {
+ int state = (params->processFlags & 0x400) ? params->img.state : 0;
+ int num = params->remapNum;
+ const uint8 *index = params->remapIndex;
+ uint8 *iwiz = getResourceAddress(rtImage, params->img.resNum);
+ assert(iwiz);
+ uint8 *rmap = findWrappedBlock(MKID('RMAP'), iwiz, state, 0) ;
+ assert(rmap);
+ *(uint32 *)(rmap + 8) = TO_BE_32(0x12345678);
+ while (num--) {
+ uint8 idx = *index++;
+ rmap[0xC + idx] = params->remapColor[idx];
+ }
+ }
+ break;
// HE 99+
case 7:
case 8:
@@ -685,7 +705,7 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.box.right = pop();
_wizParams.box.top = pop();
_wizParams.box.left = pop();
- _wizParams.unk_148 = pop();
+ _wizParams.compType = pop();
break;
case 6:
_wizParams.processFlags |= 0x400;
@@ -711,7 +731,7 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.img.resNum = pop();
_wizParams.processMode = 0;
_wizParams.processFlags = 0;
- _wizParams.remapPos = 0;
+ _wizParams.remapNum = 0;
_wizParams.img.flags = 0;
break;
case 16: // HE99+
@@ -729,13 +749,13 @@ void ScummEngine_v90he::o90_wizImageOps() {
a = pop();
_wizParams.processFlags |= 0x40;
_wizParams.processMode = 6;
- if (_wizParams.remapPos == 0) {
- memset(_wizParams.remapBuf2, 0, sizeof(_wizParams.remapBuf2));
+ if (_wizParams.remapNum == 0) {
+ memset(_wizParams.remapIndex, 0, sizeof(_wizParams.remapIndex));
} else {
- assert(_wizParams.remapPos < ARRAYSIZE(_wizParams.remapBuf2));
- _wizParams.remapBuf2[_wizParams.remapPos] = a;
- _wizParams.remapBuf1[a] = b;
- ++_wizParams.remapPos;
+ assert(_wizParams.remapNum < ARRAYSIZE(_wizParams.remapIndex));
+ _wizParams.remapIndex[_wizParams.remapNum] = a;
+ _wizParams.remapColor[a] = b;
+ ++_wizParams.remapNum;
}
break;
case 21:
diff --git a/scumm/vars.cpp b/scumm/vars.cpp
index 9b40d204f2..6f0bce6c5f 100644
--- a/scumm/vars.cpp
+++ b/scumm/vars.cpp
@@ -506,8 +506,10 @@ void ScummEngine::initScummVars() {
}
if (_heversion >= 80)
VAR(VAR_WINDOWS_VERSION) = 40;
- if (_heversion >= 90)
+ if (_heversion >= 90) {
+ VAR(VAR_WIZ_TCOLOR) = 5;
VAR(VAR_NUM_SPRITES) = _numSprites - 1;
+ }
if (_heversion >= 99) {
VAR(VAR_NUM_PALETTES) = _numPalettes;
VAR(VAR_NUM_UNK) = _numUnk;