mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 22:28:10 +00:00
preliminar o72_captureWizImage() implementation ; still have to handle flag 0x2 in drawWizImage to display correctly the painting in 1grademo
svn-id: r15577
This commit is contained in:
parent
b41902f407
commit
3905129a97
@ -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))
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
};
|
||||
|
||||
debug(1, "stub o72_captureWizImage(%d, %d, %d, %d, %d)", a, b, c, d, e);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user