diff --git a/scumm/intern.h b/scumm/intern.h index 67038efa07a..31f2efdc9aa 100644 --- a/scumm/intern.h +++ b/scumm/intern.h @@ -935,9 +935,9 @@ protected: void spritesAllocTables(int numSprites, int numGroups, int numImgSprites); void spritesResetTables(bool refreshScreen); - void spriteGroupCheck(int sprGrpId); - void spriteMarkIfInGroup(int sprGrpId, uint32 flags); - + void spriteGroupCheck(int spriteGroupId); + void spriteMarkIfInGroup(int spriteGroupId, uint32 flags); + void spritesBlitToScreen(); void spriteInfoSet_addImageToList(int spriteId, int imageNum, int *spriteIdptr); /* HE version 90 script opcodes */ diff --git a/scumm/sprite_he.cpp b/scumm/sprite_he.cpp index 475cf4390dd..dfebd5798cb 100644 --- a/scumm/sprite_he.cpp +++ b/scumm/sprite_he.cpp @@ -543,12 +543,63 @@ void ScummEngine_v90he::spritesResetTables(bool refreshScreen) { _numSpritesToProcess = 0; } -void ScummEngine_v90he::spriteGroupCheck(int sprGrpId) { - // XXX +void ScummEngine_v90he::spriteGroupCheck(int spriteGroupId) { + checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d"); } -void ScummEngine_v90he::spriteMarkIfInGroup(int sprGrpId, uint32 flags) { - // XXX +void ScummEngine_v90he::spriteMarkIfInGroup(int spriteGroupId, uint32 flags) { + checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d"); + for (int i = 0; i < _numSpritesToProcess; ++i) { + SpriteInfo *spi = _activeSpritesTable[i]; + if (spi->group_num == spriteGroupId) { + spi->flags |= flags; + } + } +} + +void ScummEngine_v90he::spritesBlitToScreen() { + int xmin, xmax, ymin, ymax; + xmin = ymin = 1234; + xmax = ymax = -1234; + bool firstLoop = true; + bool refreshScreen = false; + for (int i = 0; i < _numSpritesToProcess; ++i) { + SpriteInfo *spi = _activeSpritesTable[i]; + if (!(spi->flags & kSF31) && (spi->flags & kSF01)) { + spi->flags &= ~kSF01; + if (spi->bbox_xmin <= spi->bbox_xmax && spi->bbox_ymin <= spi->bbox_ymax) { + if (spi->flags & kSF26) { + gdi.copyVirtScreenBuffers(Common::Rect(spi->bbox_xmin, spi->bbox_ymin, spi->bbox_ymin, spi->bbox_ymax)); // XXX 0, 0x40000000); + } + } else if (firstLoop) { + xmin = spi->bbox_xmin; + ymin = spi->bbox_ymin; + xmax = spi->bbox_xmax; + ymax = spi->bbox_ymax; + firstLoop = false; + } else { + if (xmin < spi->bbox_xmin) { + xmin = spi->bbox_xmin; + } + if (ymin < spi->bbox_ymin) { + ymin = spi->bbox_ymin; + } + if (xmax > spi->bbox_xmax) { + xmax = spi->bbox_xmax; + } + if (ymax > spi->bbox_ymax) { + ymax = spi->bbox_ymax; + } + refreshScreen = true; + } + if (!(spi->flags & (kSF02 | kSF30)) && (spi->res_id != 0)) { + spi->flags |= kSF02; + } + } + } + if (refreshScreen) { + gdi.copyVirtScreenBuffers(Common::Rect(xmin, ymin, xmax, ymax)); // , 0, 0x40000000); + } } } // End of namespace Scumm diff --git a/scumm/sprite_he.h b/scumm/sprite_he.h index ffb1e9050f0..4ede6e33f17 100644 --- a/scumm/sprite_he.h +++ b/scumm/sprite_he.h @@ -27,7 +27,7 @@ namespace Scumm { enum SpriteFlags { kSF01 = (1 << 0), - kSF02 = (1 << 1), + kSF02 = (1 << 1), // kSFNeedRedraw kSF03 = (1 << 2), kSF04 = (1 << 3), kSFZoomed = (1 << 4), @@ -51,7 +51,7 @@ enum SpriteFlags { kSF23 = (1 << 22), kSF24 = (1 << 23), kSF25 = (1 << 24), - kSF26 = (1 << 25), + kSF26 = (1 << 25), // kSFBlitDirectly kSF27 = (1 << 26), kSF28 = (1 << 27), kSF29 = (1 << 28),