[Scummvm-git-logs] scummvm master -> 9e1ef1f5f6abe9aaca2bd7f72018f66c1081bee8
sluicebox
noreply at scummvm.org
Sun Apr 27 15:19:49 UTC 2025
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
c27a845e9f SCI: Fix picture vector patterns at right edge of screen
9e1ef1f5f6 SCI: Cleanup picture code
Commit: c27a845e9f7cdc89b7fbd9e27e1b57b20499c15f
https://github.com/scummvm/scummvm/commit/c27a845e9f7cdc89b7fbd9e27e1b57b20499c15f
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-04-27T08:18:56-07:00
Commit Message:
SCI: Fix picture vector patterns at right edge of screen
Fixes an inaccurate edge case when drawing patterns that border the
right edge of the screen. This was introduced when fixing inaccuracies
when drawing patterns that should appear beyond the right edge:
44b6050915ed6012f9e2e14c8ffa81d9e366529d
Fixes the first room in The Black Cauldron, bug #15876
Changed paths:
engines/sci/graphics/picture.cpp
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index e1263fea4fa..e5e4049298e 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -1159,10 +1159,10 @@ void GfxPicture::vectorPattern(int16 x, int16 y, byte color, byte priority, byte
// texture and circle data can only be properly consumed by evaluating
// every pixel during drawing, even the pixels that are then skipped
// for being out of bounds. (Example: SQ3 picture 2)
- if (box.right >= _screen->getScriptWidth()) {
- box.moveTo(_screen->getScriptWidth() - box.width() + 1, box.top);
+ if (box.right > _screen->getScriptWidth() + 1) {
+ box.moveTo(_screen->getScriptWidth() + 1 - box.width(), box.top);
}
- if (box.bottom >= _screen->getScriptHeight()) {
+ if (box.bottom > _screen->getScriptHeight()) {
box.moveTo(box.left, _screen->getScriptHeight() - box.height());
}
_screen->vectorAdjustCoordinate(&box.left, &box.top);
Commit: 9e1ef1f5f6abe9aaca2bd7f72018f66c1081bee8
https://github.com/scummvm/scummvm/commit/9e1ef1f5f6abe9aaca2bd7f72018f66c1081bee8
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-04-27T08:18:57-07:00
Commit Message:
SCI: Cleanup picture code
Changed paths:
engines/sci/graphics/paint16.cpp
engines/sci/graphics/picture.cpp
engines/sci/graphics/picture.h
engines/sci/graphics/scifx.cpp
diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp
index 49e186351a8..b7206e9c58a 100644
--- a/engines/sci/graphics/paint16.cpp
+++ b/engines/sci/graphics/paint16.cpp
@@ -88,8 +88,6 @@ void GfxPaint16::debugSetEGAdrawingVisualize(bool state) {
}
void GfxPaint16::drawPicture(GuiResourceId pictureId, bool mirroredFlag, bool addToFlag, GuiResourceId paletteId) {
- GfxPicture *picture = new GfxPicture(_resMan, _coordAdjuster, _ports, _screen, _palette, pictureId, _EGAdrawingVisualize);
-
// Set up custom per-picture palette mod
doCustomPicPalette(_screen, pictureId);
@@ -97,8 +95,9 @@ void GfxPaint16::drawPicture(GuiResourceId pictureId, bool mirroredFlag, bool ad
if (!addToFlag)
clearScreen(_screen->getColorWhite());
- picture->draw(mirroredFlag, addToFlag, paletteId);
- delete picture;
+ // Draw the picture
+ GfxPicture picture(_resMan, _coordAdjuster, _ports, _screen, _palette, pictureId, _EGAdrawingVisualize);
+ picture.draw(mirroredFlag, addToFlag, paletteId);
// We make a call to SciPalette here, for increasing sys timestamp and also loading targetpalette, if palvary active
// (SCI1.1 only)
@@ -204,17 +203,15 @@ void GfxPaint16::invertRect(const Common::Rect &rect) {
// used in SCI0early exclusively
void GfxPaint16::invertRectViaXOR(const Common::Rect &rect) {
Common::Rect r = rect;
- int16 x, y;
- byte curVisual;
r.clip(_ports->_curPort->rect);
if (r.isEmpty()) // nothing to invert
return;
_ports->offsetRect(r);
- for (y = r.top; y < r.bottom; y++) {
- for (x = r.left; x < r.right; x++) {
- curVisual = _screen->getVisual(x, y);
+ for (int16 y = r.top; y < r.bottom; y++) {
+ for (int16 x = r.left; x < r.right; x++) {
+ byte curVisual = _screen->getVisual(x, y);
_screen->putPixel(x, y, GFX_SCREEN_MASK_VISUAL, curVisual ^ 0x0f, 0, 0);
}
}
@@ -332,10 +329,6 @@ void GfxPaint16::bitsShow(const Common::Rect &rect) {
_screen->copyRectToScreen(workerRect);
}
reg_t GfxPaint16::bitsSave(const Common::Rect &rect, byte screenMask, bool hiresFlag) {
- reg_t memoryId;
- byte *memoryPtr;
- int size;
-
Common::Rect workerRect(rect.left, rect.top, rect.right, rect.bottom);
if (!hiresFlag) { // KQ6CD Win only does this if not called from the special kGraph 15 case (= kGraphSaveUpscaledHiresBox)
workerRect.clip(_ports->_curPort->rect);
@@ -345,20 +338,18 @@ reg_t GfxPaint16::bitsSave(const Common::Rect &rect, byte screenMask, bool hires
}
// now actually ask _screen how much space it will need for saving
- size = _screen->bitsGetDataSize(workerRect, screenMask);
+ int size = _screen->bitsGetDataSize(workerRect, screenMask);
- memoryId = _segMan->allocateHunkEntry("SaveBits()", size);
- memoryPtr = _segMan->getHunkPointer(memoryId);
+ reg_t memoryId = _segMan->allocateHunkEntry("SaveBits()", size);
+ byte *memoryPtr = _segMan->getHunkPointer(memoryId);
if (memoryPtr)
_screen->bitsSave(workerRect, screenMask, memoryPtr);
return memoryId;
}
void GfxPaint16::bitsGetRect(reg_t memoryHandle, Common::Rect *destRect) {
- byte *memoryPtr = nullptr;
-
if (!memoryHandle.isNull()) {
- memoryPtr = _segMan->getHunkPointer(memoryHandle);
+ byte *memoryPtr = _segMan->getHunkPointer(memoryHandle);
if (memoryPtr) {
_screen->bitsGetRect(memoryPtr, destRect);
@@ -367,10 +358,8 @@ void GfxPaint16::bitsGetRect(reg_t memoryHandle, Common::Rect *destRect) {
}
void GfxPaint16::bitsRestore(reg_t memoryHandle) {
- byte *memoryPtr = nullptr;
-
if (!memoryHandle.isNull()) {
- memoryPtr = _segMan->getHunkPointer(memoryHandle);
+ byte *memoryPtr = _segMan->getHunkPointer(memoryHandle);
if (memoryPtr) {
_screen->bitsRestore(memoryPtr);
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index e5e4049298e..6fff73ec271 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -38,7 +38,8 @@ namespace Sci {
GfxPicture::GfxPicture(ResourceManager *resMan, GfxCoordAdjuster16 *coordAdjuster, GfxPorts *ports, GfxScreen *screen, GfxPalette *palette, GuiResourceId resourceId, bool EGAdrawingVisualize)
: _resMan(resMan),
_coordAdjuster(coordAdjuster),
- _ports(ports), _screen(screen),
+ _ports(ports),
+ _screen(screen),
_palette(palette),
_resourceId(resourceId),
_resourceType(SCI_PICTURE_TYPE_REGULAR),
@@ -428,7 +429,6 @@ void GfxPicture::drawVectorData(const SciSpan<const byte> &data) {
uint curPos = 0;
uint16 size;
byte pixel;
- int i;
Palette palette;
int16 pattern_Code = 0, pattern_Texture = 0;
bool icemanDrawFix = false;
@@ -443,7 +443,7 @@ void GfxPicture::drawVectorData(const SciSpan<const byte> &data) {
if (_resMan->getViewType() == kViewEga) {
isEGA = true;
// setup default mapping tables
- for (i = 0; i < PIC_EGAPALETTE_TOTALSIZE; i += PIC_EGAPALETTE_SIZE)
+ for (int i = 0; i < PIC_EGAPALETTE_TOTALSIZE; i += PIC_EGAPALETTE_SIZE)
memcpy(&EGApalettes[i], &vector_defaultEGApalette, sizeof(vector_defaultEGApalette));
memcpy(&EGApriority, &vector_defaultEGApriority, sizeof(vector_defaultEGApriority));
@@ -540,7 +540,7 @@ void GfxPicture::drawVectorData(const SciSpan<const byte> &data) {
case PIC_OP_FILL: //fill
while (vectorIsNonOpcode(data[curPos])) {
vectorGetAbsCoords(data, curPos, x, y);
- vectorFloodFill(x, y, pic_color, pic_priority, pic_control);
+ vectorFloodFill(x, y, pic_color, pic_priority, pic_control, isEGA);
}
break;
@@ -624,7 +624,7 @@ void GfxPicture::drawVectorData(const SciSpan<const byte> &data) {
error("picture trying to write to invalid palette %d", (int)pixel);
}
pixel *= PIC_EGAPALETTE_SIZE;
- for (i = 0; i < PIC_EGAPALETTE_SIZE; i++) {
+ for (int i = 0; i < PIC_EGAPALETTE_SIZE; i++) {
EGApalettes[pixel + i] = data[curPos++];
}
break;
@@ -681,7 +681,7 @@ void GfxPicture::drawVectorData(const SciSpan<const byte> &data) {
}
} else {
curPos += 256 + 4; // Skip over mapping and timestamp
- for (i = 0; i < 256; i++) {
+ for (int i = 0; i < 256; i++) {
palette.colors[i].used = data[curPos++];
palette.colors[i].r = data[curPos++]; palette.colors[i].g = data[curPos++]; palette.colors[i].b = data[curPos++];
}
@@ -690,7 +690,8 @@ void GfxPicture::drawVectorData(const SciSpan<const byte> &data) {
break;
case PIC_OPX_VGA_EMBEDDED_VIEW: // draw cel
vectorGetAbsCoordsNoMirror(data, curPos, x, y);
- size = data.getUint16LEAt(curPos); curPos += 2;
+ size = data.getUint16LEAt(curPos);
+ curPos += 2;
if (getSciVersion() <= SCI_VERSION_1_EARLY) {
// During SCI1Early sierra always used 0 as priority for cels inside picture resources
// fixes Space Quest 4 orange ship lifting off (bug #6446)
@@ -747,16 +748,16 @@ void GfxPicture::drawVectorData(const SciSpan<const byte> &data) {
}
bool GfxPicture::vectorIsNonOpcode(byte pixel) {
- if (pixel >= PIC_OP_FIRST)
- return false;
- return true;
+ return (pixel < PIC_OP_FIRST);
}
void GfxPicture::vectorGetAbsCoords(const SciSpan<const byte> &data, uint &curPos, int16 &x, int16 &y) {
byte pixel = data[curPos++];
x = data[curPos++] + ((pixel & 0xF0) << 4);
y = data[curPos++] + ((pixel & 0x0F) << 8);
- if (_mirroredFlag) x = 319 - x;
+ if (_mirroredFlag) {
+ x = 319 - x;
+ }
}
void GfxPicture::vectorGetAbsCoordsNoMirror(const SciSpan<const byte> &data, uint &curPos, int16 &x, int16 &y) {
@@ -802,14 +803,12 @@ void GfxPicture::vectorGetPatternTexture(const SciSpan<const byte> &data, uint &
// WARNING: Do not replace the following code with something else, like generic
// code. This algo really needs to behave exactly as the one from sierra.
-void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, byte control) {
+void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, byte control, bool isEGA) {
Port *curPort = _ports->getPort();
Common::Stack<Common::Point> stack;
Common::Point p, p1;
byte screenMask = _screen->getDrawingMask(color, priority, control);
- byte matchedMask, matchMask;
-
- bool isEGA = (_resMan->getViewType() == kViewEga);
+ byte matchMask;
p.x = x + curPort->left;
p.y = y + curPort->top;
@@ -832,7 +831,7 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
searchColor = searchColor & 0x0F;
}
- // This logic was taken directly from sierra sci, floodfill will get aborted on various occations
+ // This logic was taken directly from sierra sci, floodfill will get aborted on various occasions
if (screenMask & GFX_SCREEN_MASK_VISUAL) {
if ((color == _screen->getColorWhite()) || (searchColor != _screen->getColorWhite()))
return;
@@ -880,15 +879,15 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
while (stack.size()) {
p = stack.pop();
- if ((matchedMask = _screen->vectorIsFillMatch(p.x, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)) == 0) // already filled
+ if (_screen->vectorIsFillMatch(p.x, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA) == 0) // already filled
continue;
_screen->vectorPutPixel(p.x, p.y, screenMask, color, priority, control);
curToLeft = p.x;
curToRight = p.x;
// moving west and east pointers as long as there is a matching color to fill
- while (curToLeft > borderLeft && (matchedMask = _screen->vectorIsFillMatch(curToLeft - 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
+ while (curToLeft > borderLeft && _screen->vectorIsFillMatch(curToLeft - 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA))
_screen->vectorPutPixel(--curToLeft, p.y, screenMask, color, priority, control);
- while (curToRight < borderRight && (matchedMask = _screen->vectorIsFillMatch(curToRight + 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
+ while (curToRight < borderRight && _screen->vectorIsFillMatch(curToRight + 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA))
_screen->vectorPutPixel(++curToRight, p.y, screenMask, color, priority, control);
#if 0
// debug code for floodfill
@@ -899,7 +898,7 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
// checking lines above and below for possible flood targets
a_set = b_set = 0;
while (curToLeft <= curToRight) {
- if (p.y > borderTop && (matchedMask = _screen->vectorIsFillMatch(curToLeft, p.y - 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line above
+ if (p.y > borderTop && _screen->vectorIsFillMatch(curToLeft, p.y - 1, matchMask, searchColor, searchPriority, searchControl, isEGA)) { // one line above
if (a_set == 0) {
p1.x = curToLeft;
p1.y = p.y - 1;
@@ -909,7 +908,7 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
} else
a_set = 0;
- if (p.y < borderBottom && (matchedMask = _screen->vectorIsFillMatch(curToLeft, p.y + 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line below
+ if (p.y < borderBottom && _screen->vectorIsFillMatch(curToLeft, p.y + 1, matchMask, searchColor, searchPriority, searchControl, isEGA)) { // one line below
if (b_set == 0) {
p1.x = curToLeft;
p1.y = p.y + 1;
@@ -1052,11 +1051,10 @@ static const byte vectorPatternTextureOffset[128] = {
void GfxPicture::vectorPatternBox(Common::Rect box, Common::Rect clipBox, byte color, byte prio, byte control) {
byte flag = _screen->getDrawingMask(color, prio, control);
- int y, x;
box.clip(clipBox);
- for (y = box.top; y < box.bottom; y++) {
- for (x = box.left; x < box.right; x++) {
+ for (int y = box.top; y < box.bottom; y++) {
+ for (int x = box.left; x < box.right; x++) {
_screen->vectorPutPixel(x, y, flag, color, prio, control);
}
}
@@ -1065,10 +1063,9 @@ void GfxPicture::vectorPatternBox(Common::Rect box, Common::Rect clipBox, byte c
void GfxPicture::vectorPatternTexturedBox(Common::Rect box, Common::Rect clipBox, byte color, byte prio, byte control, byte texture) {
byte flag = _screen->getDrawingMask(color, prio, control);
const bool *textureData = &vectorPatternTextures[vectorPatternTextureOffset[texture]];
- int y, x;
- for (y = box.top; y < box.bottom; y++) {
- for (x = box.left; x < box.right; x++) {
+ for (int y = box.top; y < box.bottom; y++) {
+ for (int x = box.left; x < box.right; x++) {
if (*textureData) {
if (clipBox.contains(x, y)) {
_screen->vectorPutPixel(x, y, flag, color, prio, control);
@@ -1085,10 +1082,9 @@ void GfxPicture::vectorPatternCircle(Common::Rect box, Common::Rect clipBox, byt
const byte *circleData = vectorPatternCircles[size];
byte bitmap = *circleData;
byte bitNo = 0;
- int y, x;
- for (y = box.top; y < box.bottom; y++) {
- for (x = box.left; x < box.right; x++) {
+ for (int y = box.top; y < box.bottom; y++) {
+ for (int x = box.left; x < box.right; x++) {
if (bitNo == 8) {
circleData++;
bitmap = *circleData;
@@ -1112,10 +1108,9 @@ void GfxPicture::vectorPatternTexturedCircle(Common::Rect box, Common::Rect clip
byte bitmap = *circleData;
byte bitNo = 0;
const bool *textureData = &vectorPatternTextures[vectorPatternTextureOffset[texture]];
- int y, x;
- for (y = box.top; y < box.bottom; y++) {
- for (x = box.left; x < box.right; x++) {
+ for (int y = box.top; y < box.bottom; y++) {
+ for (int x = box.left; x < box.right; x++) {
if (bitNo == 8) {
circleData++;
bitmap = *circleData;
@@ -1179,7 +1174,6 @@ void GfxPicture::vectorPattern(int16 x, int16 y, byte color, byte priority, byte
} else {
vectorPatternBox(box, clipBox, color, priority, control);
}
-
} else {
// Circle
if (code & SCI_PATTERN_CODE_USE_TEXTURE) {
diff --git a/engines/sci/graphics/picture.h b/engines/sci/graphics/picture.h
index d0537937699..0e6ec962fe1 100644
--- a/engines/sci/graphics/picture.h
+++ b/engines/sci/graphics/picture.h
@@ -31,9 +31,8 @@ namespace Sci {
#define SCI_PATTERN_CODE_PENSIZE 0x07
enum {
- SCI_PICTURE_TYPE_REGULAR = 0,
- SCI_PICTURE_TYPE_SCI11 = 1,
- SCI_PICTURE_TYPE_SCI32 = 2
+ SCI_PICTURE_TYPE_REGULAR = 0,
+ SCI_PICTURE_TYPE_SCI11 = 1
};
class GfxPorts;
@@ -69,7 +68,7 @@ private:
void vectorGetRelCoords(const SciSpan<const byte> &data, uint &curPos, int16 &x, int16 &y);
void vectorGetRelCoordsMed(const SciSpan<const byte> &data, uint &curPos, int16 &x, int16 &y);
void vectorGetPatternTexture(const SciSpan<const byte> &data, uint &curPos, int16 pattern_Code, int16 &pattern_Texture);
- void vectorFloodFill(int16 x, int16 y, byte color, byte prio, byte control);
+ void vectorFloodFill(int16 x, int16 y, byte color, byte prio, byte control, bool isEGA);
void vectorPattern(int16 x, int16 y, byte pic_color, byte pic_priority, byte pic_control, byte code, byte texture);
void vectorPatternBox(Common::Rect box, Common::Rect clipBox, byte color, byte prio, byte control);
void vectorPatternTexturedBox(Common::Rect box, Common::Rect clipBox, byte color, byte prio, byte control, byte texture);
diff --git a/engines/sci/graphics/scifx.cpp b/engines/sci/graphics/scifx.cpp
index 2a7178d3258..4a75d1c615c 100644
--- a/engines/sci/graphics/scifx.cpp
+++ b/engines/sci/graphics/scifx.cpp
@@ -192,10 +192,10 @@ void setupCustomPaletteMods(GfxScreen *screen) {
void doCustomViewPalette(GfxScreen *screen, GuiResourceId view, int16 loop, int16 cel) {
for (int i = 0; i < ARRAYSIZE(mods); i++) {
- SciFxMod mod = mods[i];
+ const SciFxMod &mod = mods[i];
if (mod.gameId == g_sci->getGameId()) {
for (int j = 0; j < mod.viewModsSize; j++) {
- ViewMod m = mod.viewMods[j];
+ const ViewMod &m = mod.viewMods[j];
if (m.id == view && (m.loop == -1 || m.loop == loop) && (m.cel == -1 || m.cel == cel)) {
screen->setCurPaletteMapValue(m.multiplier);
break;
@@ -208,10 +208,10 @@ void doCustomViewPalette(GfxScreen *screen, GuiResourceId view, int16 loop, int1
void doCustomPicPalette(GfxScreen *screen, GuiResourceId pic) {
for (int i = 0; i < ARRAYSIZE(mods); i++) {
- SciFxMod mod = mods[i];
+ const SciFxMod &mod = mods[i];
if (mod.gameId == g_sci->getGameId()) {
for (int j = 0; j < mod.picModsSize; j++) {
- PicMod m = mod.picMods[j];
+ const PicMod &m = mod.picMods[j];
if (m.id == pic) {
screen->setCurPaletteMapValue(m.multiplier);
break;
More information about the Scummvm-git-logs
mailing list