diff --git a/scumm/intern.h b/scumm/intern.h index c26ef2ce506..25cf7529bc5 100644 --- a/scumm/intern.h +++ b/scumm/intern.h @@ -741,11 +741,12 @@ protected: int readFileToArray(int slot, int32 size); void writeFileFromArray(int slot, int resID); + void displayWizImage(WizImage *pwi); void displayWizComplexImage(const WizParameters *params); void drawWizComplexPolygon(int resnum, int state, int po_x, int po_y, int arg14, int angle, int zoom, const Common::Rect *r); void captureWizImage(int resnum, const Common::Rect& r, bool frontBuffer, int compType); void getWizImageDim(int resnum, int state, int32 &w, int32 &h); - uint8 *drawWizImage(const WizImage *pwi); + uint8 *drawWizImage(int resNum, int state, int x1, int y1, int create, const Common::Rect *clipBox, int flags, uint8 *newResourcePtr, int paletteNum); void drawWizPolygon(int resnum, int state, int id, int flags); void flushWizBuffer(); diff --git a/scumm/script_v100he.cpp b/scumm/script_v100he.cpp index bd5ddc94f63..4fcb7b3c05f 100644 --- a/scumm/script_v100he.cpp +++ b/scumm/script_v100he.cpp @@ -1246,7 +1246,7 @@ void ScummEngine_v100he::o100_wizImageOps() { _wizParams.processMode = 8; break; case 54: - _wizParams.processFlags |= 0x10000; + _wizParams.processFlags |= kWPFDstResNum; //_wizParams.unk_17C = pop(); //_wizParams.unk_180 = pop(); pop(); @@ -1346,8 +1346,8 @@ void ScummEngine_v100he::o100_wizImageOps() { _wizParams.box2.left = _wizParams.box2.right = pop(); break; case 135: - _wizParams.processFlags |= 0x10000; - _wizParams.unk_380 = pop(); + _wizParams.processFlags |= kWPFDstResNum; + _wizParams.dstResNum = pop(); break; case 136: _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2; diff --git a/scumm/script_v72he.cpp b/scumm/script_v72he.cpp index ef0312f1865..15ce984fb24 100644 --- a/scumm/script_v72he.cpp +++ b/scumm/script_v72he.cpp @@ -887,7 +887,7 @@ void ScummEngine_v72he::o72_printWizImage() { wi.x1 = wi.y1 = 0; wi.state = 0; wi.flags = kWIFPrint; - drawWizImage(&wi); + displayWizImage(&wi); } void ScummEngine_v72he::o72_getArrayDimSize() { @@ -1610,13 +1610,13 @@ void ScummEngine_v72he::o72_kernelGetFunctions() { } void ScummEngine_v72he::o72_drawWizImage() { - _wizParams.processFlags |= kWPFSetPos | kWPFNewFlags; - _wizParams.img.flags = pop(); - _wizParams.img.state = 0; - _wizParams.img.y1 = pop(); - _wizParams.img.x1 = pop(); - _wizParams.img.resNum = pop(); - displayWizComplexImage(&_wizParams); + WizImage wi; + wi.flags = pop(); + wi.y1 = pop(); + wi.x1 = pop(); + wi.resNum = pop(); + wi.state = 0; + displayWizImage(&wi); } void ScummEngine_v72he::o72_unknownCF() { diff --git a/scumm/script_v80he.cpp b/scumm/script_v80he.cpp index 96576f1ac17..0e1949f74b3 100644 --- a/scumm/script_v80he.cpp +++ b/scumm/script_v80he.cpp @@ -584,12 +584,12 @@ void ScummEngine_v80he::o80_drawBox() { } void ScummEngine_v80he::o80_drawWizPolygon() { - _wizParams.processFlags |= kWPFSetPos | kWPFNewFlags; - _wizParams.img.flags = kWIFIsPolygon; - _wizParams.img.state = 0; - _wizParams.img.y1 = _wizParams.img.x1 = pop(); - _wizParams.img.resNum = pop(); - displayWizComplexImage(&_wizParams); + WizImage wi; + wi.x1 = wi.y1 = pop(); + wi.resNum = pop(); + wi.state = 0; + wi.flags = kWIFIsPolygon; + displayWizImage(&wi); } void ScummEngine_v80he::o80_unknownE0() { @@ -608,35 +608,37 @@ void ScummEngine_v80he::o80_unknownE0() { switch (subOp) { case 55: { - Actor *a = derefActorSafe(num, "o80_unknownE0"); - int top_actor = a->_top; - int bottom_actor = a->_bottom; - a->_drawToBackBuf = true; - a->_needRedraw = true; - a->drawActorCostume(); - a->_drawToBackBuf = false; - a->_needRedraw = true; - a->drawActorCostume(); - a->_needRedraw = false; + Actor *a = derefActorSafe(num, "o80_unknownE0"); + int top_actor = a->_top; + int bottom_actor = a->_bottom; + a->_drawToBackBuf = true; + a->_needRedraw = true; + a->drawActorCostume(); + a->_drawToBackBuf = false; + a->_needRedraw = true; + a->drawActorCostume(); + a->_needRedraw = false; - if (a->_top > top_actor) - a->_top = top_actor; - if (a->_bottom < bottom_actor) - a->_bottom = bottom_actor; + if (a->_top > top_actor) + a->_top = top_actor; + if (a->_bottom < bottom_actor) + a->_bottom = bottom_actor; - type = 2; + type = 2; } break; case 63: - _wizParams.processFlags |= kWPFSetPos; - _wizParams.img.flags = 0; - _wizParams.img.state = 0; - _wizParams.img.y1 = y1; - _wizParams.img.x1 = x1; - _wizParams.img.resNum = num; - displayWizComplexImage(&_wizParams); + { + WizImage wi; + wi.flags = 0; + wi.y1 = y1; + wi.x1 = x1; + wi.resNum = num; + wi.state = 0; + displayWizImage(&wi); - type = 3; + type = 3; + } break; case 66: type = 1; diff --git a/scumm/script_v90he.cpp b/scumm/script_v90he.cpp index 5504207e6c2..274f6651d9f 100644 --- a/scumm/script_v90he.cpp +++ b/scumm/script_v90he.cpp @@ -668,8 +668,8 @@ void ScummEngine_v90he::o90_wizImageOps() { _wizParams.box2.left = _wizParams.box2.right = pop(); break; case 91: // HE99+ - _wizParams.processFlags |= 0x10000; - _wizParams.unk_380 = pop(); + _wizParams.processFlags |= kWPFDstResNum; + _wizParams.dstResNum = pop(); break; case 108: _wizParams.processFlags |= kWPFSetPos; @@ -2307,11 +2307,11 @@ void ScummEngine_v90he::o90_kernelSetFunctions() { break; case 24: _skipProcessActors = 1; - _fullRedraw = 1; + //_fullRedraw = 1; break; case 25: _skipProcessActors = 0; - _fullRedraw = 1; + //_fullRedraw = 1; break; case 42: _wiz._rectOverrideEnabled = true; diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index 119afece33b..6af839cee97 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -1982,6 +1982,9 @@ load_game: processDrawQue(); + if (_heversion >= 99) + _fullRedraw = false; + // Full Throttle always redraws verbs and draws verbs before actors if (_version >= 7) redrawVerbs(); diff --git a/scumm/sprite_he.cpp b/scumm/sprite_he.cpp index 9bb492f4ae4..e8ef7d2d785 100644 --- a/scumm/sprite_he.cpp +++ b/scumm/sprite_he.cpp @@ -440,7 +440,7 @@ int ScummEngine_v90he::spriteGroupGet_zorderPriority(int spriteGroupId) { int ScummEngine_v90he::spriteGroupGet_field_20(int spriteGroupId) { checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d"); - return _spriteGroups[spriteGroupId].field_20; + return _spriteGroups[spriteGroupId].dstResNum; } int ScummEngine_v90he::spriteGroupGet_scale_x_ratio_mul(int spriteGroupId) { @@ -931,8 +931,8 @@ void ScummEngine_v90he::spriteGroupSet_inc_tx_ty(int spriteGroupId, int value1, void ScummEngine_v90he::spriteGroupSet_field_20(int spriteGroupId, int value) { checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d"); - if (_spriteGroups[spriteGroupId].field_20 != value) { - _spriteGroups[spriteGroupId].field_20 = value; + if (_spriteGroups[spriteGroupId].dstResNum != value) { + _spriteGroups[spriteGroupId].dstResNum = value; redrawSpriteGroup(spriteGroupId); } } @@ -1026,7 +1026,7 @@ void ScummEngine_v90he::spritesResetGroup(int spriteGroupId) { spg->flags &= ~kSGFClipBox; redrawSpriteGroup(spriteGroupId); - spg->field_20 = 0; + spg->dstResNum = 0; spg->scaling = 0; spg->scale_x = 0x3F800000; spg->scale_x_ratio_mul = 1; @@ -1341,9 +1341,9 @@ void ScummEngine_v90he::spritesProcessWiz(bool arg) { wiz.processFlags |= kWPFPaletteNum; wiz.img.paletteNum = spi->paletteNum; } - if (spi->res_id && spi->group_num && _spriteGroups[spi->group_num].field_20) { - wiz.processFlags |= 0x10000; - wiz.unk_380 = _spriteGroups[spi->group_num].field_20; + if (spi->res_id && spi->group_num && _spriteGroups[spi->group_num].dstResNum) { + wiz.processFlags |= kWPFDstResNum; + wiz.dstResNum = _spriteGroups[spi->group_num].dstResNum; } displayWizComplexImage(&wiz); } diff --git a/scumm/sprite_he.h b/scumm/sprite_he.h index bc950b16dfe..7af22232ca2 100644 --- a/scumm/sprite_he.h +++ b/scumm/sprite_he.h @@ -89,7 +89,7 @@ struct SpriteGroup { int flags; int tx; int ty; - int field_20; + int dstResNum; int scaling; int scale_x; int scale_y; diff --git a/scumm/wiz_he.cpp b/scumm/wiz_he.cpp index 2954be28eeb..57e9f7d3b4a 100644 --- a/scumm/wiz_he.cpp +++ b/scumm/wiz_he.cpp @@ -859,15 +859,28 @@ void ScummEngine_v72he::getWizImageDim(int resnum, int state, int32 &w, int32 &h h = READ_LE_UINT32(wizh + 0x8); } -uint8 *ScummEngine_v72he::drawWizImage(const WizImage *pwi) { - debug(1, "drawWizImage(%d, %d, %d, 0x%X)", pwi->resNum, pwi->x1, pwi->y1, pwi->flags); +void ScummEngine_v72he::displayWizImage(WizImage *pwi) { + if (_fullRedraw) { + assert(_wiz._imagesNum < ARRAYSIZE(_wiz._images)); + memcpy(&_wiz._images[_wiz._imagesNum], pwi, sizeof(WizImage)); + ++_wiz._imagesNum; + } else if (pwi->flags & kWIFIsPolygon) { + drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags); + } else { + const Common::Rect *r = NULL; + drawWizImage(pwi->resNum, pwi->state, pwi->x1, pwi->y1, pwi->unk, r, pwi->flags, NULL, 0); + } +} + +uint8 *ScummEngine_v72he::drawWizImage(int resNum, int state, int x1, int y1, int create, const Common::Rect *clipBox, int flags, uint8 *newResourcePtr, int paletteNum) { + debug(1, "drawWizImage(%d, %d, %d, 0x%X)", resNum, x1, y1, flags); uint8 *dst = NULL; - uint8 *dataPtr = getResourceAddress(rtImage, pwi->resNum); + uint8 *dataPtr = getResourceAddress(rtImage, resNum); if (dataPtr) { uint8 *rmap = NULL; - uint8 *xmap = findWrappedBlock(MKID('XMAP'), dataPtr, pwi->state, 0); + uint8 *xmap = findWrappedBlock(MKID('XMAP'), dataPtr, state, 0); - uint8 *wizh = findWrappedBlock(MKID('WIZH'), dataPtr, pwi->state, 0); + uint8 *wizh = findWrappedBlock(MKID('WIZH'), dataPtr, state, 0); assert(wizh); uint32 comp = READ_LE_UINT32(wizh + 0x0); uint32 width = READ_LE_UINT32(wizh + 0x4); @@ -875,80 +888,91 @@ uint8 *ScummEngine_v72he::drawWizImage(const WizImage *pwi) { debug(1, "wiz_header.comp = %d wiz_header.w = %d wiz_header.h = %d)", comp, width, height); assert(comp == 0 || comp == 1 || comp == 2 || comp == 3 || comp == 10 || comp == 11); - uint8 *wizd = findWrappedBlock(MKID('WIZD'), dataPtr, pwi->state, 0); + uint8 *wizd = findWrappedBlock(MKID('WIZD'), dataPtr, state, 0); assert(wizd); - if (pwi->flags & kWIFHasPalette) { - uint8 *pal = findWrappedBlock(MKID('RGBS'), dataPtr, pwi->state, 0); + if (flags & kWIFHasPalette) { + uint8 *pal = findWrappedBlock(MKID('RGBS'), dataPtr, state, 0); assert(pal); setPaletteFromPtr(pal, 256); } - if (pwi->flags & kWIFRemapPalette) { - rmap = findWrappedBlock(MKID('RMAP'), dataPtr, pwi->state, 0); + if (flags & kWIFRemapPalette) { + rmap = findWrappedBlock(MKID('RMAP'), dataPtr, state, 0); assert(rmap); - uint8 *rgbs = findWrappedBlock(MKID('RGBS'), dataPtr, pwi->state, 0); + uint8 *rgbs = findWrappedBlock(MKID('RGBS'), dataPtr, state, 0); assert(rgbs); warning("drawWizImage() unhandled flag 0x2"); // XXX modify 'RMAP' buffer } - if (pwi->flags & kWIFPrint) { + if (flags & kWIFPrint) { warning("WizImage printing is unimplemented"); return NULL; } - Common::Rect rImage(pwi->x1, pwi->y1, pwi->x1 + width, pwi->y1 + height); - if (_wiz._rectOverrideEnabled == true) { - if (rImage.intersects(_wiz._rectOverride)) { - rImage.clip(_wiz._rectOverride); - } else { - return 0; - } - } - uint32 cw, ch; - if (pwi->flags & kWIFBlitToMemBuffer) { + if (flags & kWIFBlitToMemBuffer) { dst = (uint8 *)malloc(width * height); int color = 255; // FIXME: should be (VAR_WIZ_TCOLOR != 0xFF) ? VAR(VAR_WIZ_TCOLOR) : 5; memset(dst, color, width * height); cw = width; ch = height; } else { - VirtScreen *pvs = &virtscr[kMainVirtScreen]; - if (pwi->flags & kWIFMarkBufferDirty) { - dst = pvs->getPixels(0, pvs->topline); + if (newResourcePtr) { + cw = READ_LE_UINT32(newResourcePtr + 0x4); + ch = READ_LE_UINT32(newResourcePtr + 0x8); + dst = newResourcePtr; } else { - dst = pvs->getBackPixels(0, pvs->topline); + VirtScreen *pvs = &virtscr[kMainVirtScreen]; + if (flags & kWIFMarkBufferDirty) { + dst = pvs->getPixels(0, pvs->topline); + } else { + dst = pvs->getBackPixels(0, pvs->topline); + } + cw = pvs->w; + ch = pvs->h; } - cw = pvs->w; - ch = pvs->h; } Common::Rect rScreen(cw, ch); - + if (clipBox) { + Common::Rect clip(clipBox->left, clipBox->top, clipBox->right, clipBox->bottom); + if (rScreen.intersects(clip)) { + rScreen.clip(clip); + } else { + return 0; + } + } else if (_wiz._rectOverrideEnabled == true) { + if (rScreen.intersects(_wiz._rectOverride)) { + rScreen.clip(_wiz._rectOverride); + } else { + return 0; + } + } // XXX handle 'XMAP' / 'RMAP' data if (comp == 1) { - if (pwi->flags & 0x80) { + if (flags & 0x80) { warning("drawWizImage() unhandled flag 0x80"); - } else if (pwi->flags & 0x100) { + } else if (flags & 0x100) { warning("drawWizImage() unhandled flag 0x100"); } else { - _wiz.copyWizImage(dst, wizd, cw, ch, pwi->x1, pwi->y1, width, height, &rScreen); + _wiz.copyWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen); } } else if (comp == 0 || comp == 2 || comp == 3) { - uint8 *trns = findWrappedBlock(MKID('TRNS'), dataPtr, pwi->state, 0); + uint8 *trns = findWrappedBlock(MKID('TRNS'), dataPtr, state, 0); int color = (trns == NULL) ? VAR(VAR_WIZ_TCOLOR) : -1; const uint8 *pal = xmap; - if (pwi->flags & kWIFRemapPalette) { + if (flags & kWIFRemapPalette) { pal = rmap + 4; } - _wiz.copyRawWizImage(dst, wizd, cw, ch, pwi->x1, pwi->y1, width, height, &rScreen, pwi->flags, pal, color); + _wiz.copyRawWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, pal, color); } else { warning("unhandled wiz compression type %d", comp); } - if (!(pwi->flags & kWIFBlitToMemBuffer)) { + if (!(flags & kWIFBlitToMemBuffer) && newResourcePtr == NULL) { + Common::Rect rImage(x1, y1, x1 + width, y1 + height); if (rImage.intersects(rScreen)) { rImage.clip(rScreen); - if (!(pwi->flags & kWIFBlitToFrontVideoBuffer) && (pwi->flags & (kWIFBlitToFrontVideoBuffer | kWIFMarkBufferDirty))) { + if (!(flags & kWIFBlitToFrontVideoBuffer) && (flags & (kWIFBlitToFrontVideoBuffer | kWIFMarkBufferDirty))) { ++rImage.bottom; markRectAsDirty(kMainVirtScreen, rImage); } else { @@ -1041,12 +1065,8 @@ void ScummEngine_v72he::drawWizPolygon(int resnum, int state, int id, int flags) if (wp->numVerts != 5) { error("Invalid point count %d for Polygon %d", wp->numVerts, id); } - WizImage wi; - wi.resNum = resnum; - wi.state = state; - wi.x1 = wi.y1 = 0; - wi.flags = kWIFBlitToMemBuffer; - uint8 *srcWizBuf = drawWizImage(&wi); + const Common::Rect *r = NULL; + uint8 *srcWizBuf = drawWizImage(resnum, state, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, 0); if (srcWizBuf) { uint8 *dst; VirtScreen *pvs = &virtscr[kMainVirtScreen]; @@ -1131,7 +1151,8 @@ void ScummEngine_v72he::flushWizBuffer() { if (pwi->flags & kWIFIsPolygon) { drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags); } else { - drawWizImage(pwi); + const Common::Rect *r = NULL; + drawWizImage(pwi->resNum, pwi->state, pwi->x1, pwi->y1, pwi->unk, r, pwi->flags, NULL, 0); } } _wiz._imagesNum = 0; @@ -1164,12 +1185,8 @@ void ScummEngine_v80he::loadWizCursor(int resId) { y = 32; } - WizImage wi; - wi.resNum = resId; - wi.x1 = wi.y1 = 0; - wi.state = 0; - wi.flags = kWIFBlitToMemBuffer; - uint8 *cursor = drawWizImage(&wi); + const Common::Rect *r = NULL; + uint8 *cursor = drawWizImage(resId, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, 0); int32 cw, ch; getWizImageDim(resId, 0, cw, ch); setCursorFromBuffer(cursor, cw, ch, cw); @@ -1206,6 +1223,11 @@ void ScummEngine_v72he::drawWizComplexPolygon(int resnum, int state, int po_x, i } void ScummEngine_v72he::displayWizComplexImage(const WizParameters *params) { + int unk_178 = 0; + if (params->processFlags & 0x80000) { + unk_178 = params->unk_178; + warning("displayWizComplexImage() unhandled flag 0x80000"); + } int paletteNum = 0; if (params->processFlags & kWPFPaletteNum) { paletteNum = params->img.paletteNum; @@ -1240,11 +1262,14 @@ void ScummEngine_v72he::displayWizComplexImage(const WizParameters *params) { if (params->processFlags & kWPFClipBox) { r = ¶ms->box; } - - if (params->processFlags & 0x10000) { - warning("displayWizComplexImage() unhandled flags = 0x10000"); + uint8 *wizd = NULL; + if (params->processFlags & kWPFDstResNum) { + uint8 *dataPtr = getResourceAddress(rtImage, params->dstResNum); + assert(dataPtr); + wizd = findWrappedBlock(MKID('WIZD'), dataPtr, 0, 0); + assert(wizd); + warning("displayWizComplexImage() flag 0x10000"); } - if (params->processFlags & kWPFRemapPalette) { int st = (params->processFlags & kWPFNewState) ? params->img.state : 0; int num = params->remapNum; @@ -1260,7 +1285,10 @@ void ScummEngine_v72he::displayWizComplexImage(const WizParameters *params) { } } - if (_fullRedraw) { + if (_fullRedraw && wizd == NULL) { + if (unk_178 != 0 || (params->processFlags & (kWPFZoom | kWPFRotate))) + error("Can't do this command in the enter script."); + assert(_wiz._imagesNum < ARRAYSIZE(_wiz._images)); WizImage *pwi = &_wiz._images[_wiz._imagesNum]; pwi->resNum = params->img.resNum; @@ -1271,24 +1299,18 @@ void ScummEngine_v72he::displayWizComplexImage(const WizParameters *params) { pwi->unk = unk; pwi->paletteNum = paletteNum; ++_wiz._imagesNum; - } else if (params->processFlags & (kWPFRotate | kWPFZoom)) { - drawWizComplexPolygon(params->img.resNum, state, po_x, po_y, unk, rotationAngle, zoom, r); - } else if (flags & kWIFIsPolygon) { - drawWizPolygon(params->img.resNum, state, po_x, flags); // XXX , VAR(VAR_WIZ_TCOLOR)); } else { - if ((flags & 0x200) || (flags & 0x24)) { - warning("displayWizComplexImage() unhandled flags = 0x%X", flags); + if (unk_178 != 0) { + // TODO + } else if (params->processFlags & (kWPFZoom | kWPFRotate)) { + drawWizComplexPolygon(params->img.resNum, state, po_x, po_y, unk, rotationAngle, zoom, r); + } else { + if (flags & kWIFIsPolygon) { + drawWizPolygon(params->img.resNum, state, po_x, flags); // XXX , VAR(VAR_WIZ_TCOLOR)); + } else { + drawWizImage(params->img.resNum, state, po_x, po_y, unk, r, flags, wizd, paletteNum); + } } - // XXX flags 0x200, 0x24 - WizImage wi; - wi.resNum = params->img.resNum; - wi.x1 = po_x; - wi.y1 = po_y; - wi.state = state; - wi.flags = flags; - wi.unk = unk; - wi.paletteNum = paletteNum; - drawWizImage(&wi); } } diff --git a/scumm/wiz_he.h b/scumm/wiz_he.h index 18857ff1439..d0fdb259576 100644 --- a/scumm/wiz_he.h +++ b/scumm/wiz_he.h @@ -71,7 +71,7 @@ struct WizParameters { uint8 remapColor[256]; uint8 remapIndex[256]; int remapNum; - int unk_380; + int dstResNum; byte fillColor; Common::Rect box2; WizImage img; @@ -101,6 +101,7 @@ enum WizProcessFlags { kWPFUseDefImgWidth = 0x2000, kWPFUseDefImgHeight = 0x4000, kWPFPaletteNum = 0x8000, + kWPFDstResNum = 0x10000, kWPFFillColor = 0x20000, kWPFClipBox2 = 0x40000 };