diff options
author | Gregory Montoir | 2004-10-17 04:35:36 +0000 |
---|---|---|
committer | Gregory Montoir | 2004-10-17 04:35:36 +0000 |
commit | 3905129a9702e8f6db9b345734a27133fb630882 (patch) | |
tree | 448807e1daeb6103a19b397f3a6df4a4d0302dd7 | |
parent | b41902f4079793236a20ebc380481fd598401c1d (diff) | |
download | scummvm-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
-rw-r--r-- | scumm/gfx.cpp | 2 | ||||
-rw-r--r-- | scumm/intern.h | 9 | ||||
-rw-r--r-- | scumm/script_v100he.cpp | 4 | ||||
-rw-r--r-- | scumm/script_v72he.cpp | 263 | ||||
-rw-r--r-- | scumm/script_v7he.cpp | 2 | ||||
-rw-r--r-- | scumm/script_v90he.cpp | 38 | ||||
-rw-r--r-- | scumm/vars.cpp | 4 |
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; |