[Scummvm-git-logs] scummvm master -> f3ff05e6589980a5a21bc13d6e48c4c44a255a3b
elasota
noreply at scummvm.org
Thu Jun 8 04:56:44 UTC 2023
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
55d578078b MTROPOLIS: Add basic support for image effect modifiers, which should fix most object highlights in MTI
f3ff05e658 VCRUISE: Properly fix EOS flag handling in Gentee Installer unpacker
Commit: 55d578078babb8aac9b04728cab13b3eb2b05761
https://github.com/scummvm/scummvm/commit/55d578078babb8aac9b04728cab13b3eb2b05761
Author: elasota (ejlasota at gmail.com)
Date: 2023-06-07T23:48:36-04:00
Commit Message:
MTROPOLIS: Add basic support for image effect modifiers, which should fix most object highlights in MTI
Changed paths:
engines/mtropolis/elements.cpp
engines/mtropolis/modifiers.cpp
engines/mtropolis/modifiers.h
engines/mtropolis/runtime.cpp
engines/mtropolis/runtime.h
diff --git a/engines/mtropolis/elements.cpp b/engines/mtropolis/elements.cpp
index 50b8666b2d3..90d8701be5b 100644
--- a/engines/mtropolis/elements.cpp
+++ b/engines/mtropolis/elements.cpp
@@ -73,10 +73,14 @@ MiniscriptInstructionOutcome GraphicElement::writeRefAttribute(MiniscriptThread
void GraphicElement::render(Window *window) {
- if (_renderProps.getInkMode() == VisualElementRenderProperties::kInkModeDefault || _renderProps.getInkMode() == VisualElementRenderProperties::kInkModeInvisible || _rect.isEmpty()) {
- // Not rendered at all
- _mask.reset();
- return;
+ bool haveEffect = (_bottomRightBevelShading != 0 || _topLeftBevelShading != 0 || _interiorShading != 0);
+
+ if (!haveEffect) {
+ if (_renderProps.getInkMode() == VisualElementRenderProperties::kInkModeDefault || _renderProps.getInkMode() == VisualElementRenderProperties::kInkModeInvisible || _rect.isEmpty()) {
+ // Not rendered at all
+ _mask.reset();
+ return;
+ }
}
if (!_visible)
@@ -182,9 +186,6 @@ void GraphicElement::render(Window *window) {
Common::Point *leftVert = triPoints[half][1];
Common::Point *rightVert = triPoints[half][2];
- if (leftVert->x == rightVert->x || commonPoint->y == points[1].y)
- continue; // Degenerate tri
-
if (leftVert->x > rightVert->x) {
Common::Point *temp = leftVert;
leftVert = rightVert;
@@ -255,10 +256,27 @@ void GraphicElement::render(Window *window) {
xSpan[ray] = resolved;
}
- int32 spanWidth = xSpan[1] - xSpan[0];
- uint8 *bits = static_cast<uint8 *>(_mask->getBasePtr(xSpan[0], y));
- for (int32 i = 0; i < spanWidth; i++)
- bits[i] ^= 0xff;
+ if (xSpan[1] < xSpan[0]) {
+ int32 temp = xSpan[1];
+ xSpan[1] = xSpan[0];
+ xSpan[0] = temp;
+ }
+
+ // Clip to the graphic area
+ if (y >= 0 && y < static_cast<int32>(height)) {
+ for (int i = 0; i < 2; i++) {
+ int32 &xVal = xSpan[i];
+ if (xVal < 0)
+ xVal = 0;
+ if (xVal >= static_cast<int32>(width))
+ xVal = width - 1;
+ }
+
+ int32 spanWidth = xSpan[1] - xSpan[0];
+ uint8 *bits = static_cast<uint8 *>(_mask->getBasePtr(xSpan[0], y));
+ for (int32 i = 0; i < spanWidth; i++)
+ bits[i] ^= 0xff;
+ }
}
}
}
@@ -413,10 +431,64 @@ void GraphicElement::render(Window *window) {
}
}
} break;
+ case VisualElementRenderProperties::kInkModeInvisible:
+ case VisualElementRenderProperties::kInkModeDefault:
+ break;
default:
warning("Unimplemented graphic ink mode");
return;
}
+
+ // TODO: The accurate behavior for polys is complicated.
+ // It looks like the way that it works is that a "line mask" is constructed by inverting the mask, dilating it
+ // by HALF the bevel size, then masking that out using the original mask, which results in a border mask.
+ // Then, the bevel diagonal is computed as simply a line going from the lower-left corner to the top-right corner.
+
+ if (_interiorShading) {
+ const Graphics::PixelFormat &pixFmt = window->getPixelFormat();
+
+ if (pixFmt.bytesPerPixel > 1) {
+ uint32 rMask = pixFmt.ARGBToColor(0, 255, 0, 0);
+ uint32 gMask = pixFmt.ARGBToColor(0, 0, 255, 0);
+ uint32 bMask = pixFmt.ARGBToColor(0, 0, 0, 255);
+
+ uint32 rAdd = quantizeShading(rMask, _interiorShading);
+ uint32 gAdd = quantizeShading(gMask, _interiorShading);
+ uint32 bAdd = quantizeShading(bMask, _interiorShading);
+
+ bool isBrighten = (_interiorShading > 0);
+
+ Graphics::ManagedSurface *windowSurface = window->getSurface().get();
+
+ for (int32 srcY = clippedSrcRect.top; srcY < clippedSrcRect.bottom; srcY++) {
+ int32 spanWidth = clippedDrawRect.width();
+
+ int32 effectLength = 0;
+
+ if (_mask) {
+ const uint8 *maskBytes = static_cast<const uint8 *>(_mask->getBasePtr(clippedSrcRect.left, srcY));
+
+ for (int32 x = 0; x < spanWidth; x++) {
+ if (maskBytes[x])
+ effectLength++;
+ else {
+ if (effectLength > 0) {
+ void *effectPixels = windowSurface->getBasePtr(clippedDrawRect.left + x - effectLength, srcY + srcToDestY);
+ renderShadingScanlineDynamic(effectPixels, effectLength, rMask, rAdd, gMask, gAdd, bMask, bAdd, isBrighten, windowSurface->format.bytesPerPixel);
+ }
+ effectLength = 0;
+ }
+ }
+ } else
+ effectLength = spanWidth;
+
+ if (effectLength > 0) {
+ void *effectPixels = windowSurface->getBasePtr(clippedDrawRect.left + spanWidth - effectLength, srcY + srcToDestY);
+ renderShadingScanlineDynamic(effectPixels, effectLength, rMask, rAdd, gMask, gAdd, bMask, bAdd, isBrighten, windowSurface->format.bytesPerPixel);
+ }
+ }
+ }
+ }
}
MovieResizeFilter::~MovieResizeFilter() {
@@ -1107,6 +1179,16 @@ void ImageElement::render(Window *window) {
uint8 alpha = _transitionProps.getAlpha();
+ Graphics::Surface *postShadingSource = optimized->surfacePtr();
+
+ Graphics::Surface tempSurface;
+ if (_interiorShading != 0 || (_bevelSize > 0 && (_bottomRightBevelShading != 0 || _topLeftBevelShading != 0))) {
+ tempSurface.copyFrom(*postShadingSource);
+ renderShading(tempSurface);
+ postShadingSource = &tempSurface;
+ }
+
+
if (inkMode == VisualElementRenderProperties::kInkModeBackgroundMatte || inkMode == VisualElementRenderProperties::kInkModeBackgroundTransparent) {
const ColorRGB8 transColorRGB8 = _renderProps.getBackColor();
uint32 transColor = optimized->format.ARGBToColor(0, transColorRGB8.r, transColorRGB8.g, transColorRGB8.b);
diff --git a/engines/mtropolis/modifiers.cpp b/engines/mtropolis/modifiers.cpp
index bac15fe5150..614720a9169 100644
--- a/engines/mtropolis/modifiers.cpp
+++ b/engines/mtropolis/modifiers.cpp
@@ -163,6 +163,15 @@ void BehaviorModifier::disable(Runtime *runtime) {
child->disable(runtime);
}
+#ifdef MTROPOLIS_DEBUG_ENABLE
+void BehaviorModifier::debugInspect(IDebugInspectionReport *report) const {
+ Modifier::debugInspect(report);
+
+ report->declareDynamic("switchable", _switchable ? "true" : "false");
+ report->declareDynamic("enabled", _isEnabled ? "true" : "false");
+}
+#endif
+
VThreadState BehaviorModifier::switchTask(const SwitchTaskData &taskData) {
if (_isEnabled != taskData.targetState) {
_isEnabled = taskData.targetState;
@@ -2532,11 +2541,25 @@ bool ImageEffectModifier::respondsToEvent(const Event &evt) const {
}
VThreadState ImageEffectModifier::consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
- warning("Image effect modifier not implemented");
+ if (_removeWhen.respondsTo(msg->getEvent())) {
+ RemoveTaskData *removeTask = runtime->getVThread().pushTask("ImageEffectModifier::removeTask", this, &ImageEffectModifier::removeTask);
+ removeTask->runtime = runtime;
+ }
+ if (_applyWhen.respondsTo(msg->getEvent())) {
+ ApplyTaskData *applyTask = runtime->getVThread().pushTask("ImageEffectModifier::applyTask", this, &ImageEffectModifier::applyTask);
+ applyTask->runtime = runtime;
+ }
+
return kVThreadReturn;
}
void ImageEffectModifier::disable(Runtime *runtime) {
+ Structural *structural = findStructuralOwner();
+ if (!structural || !structural->isElement() || !static_cast<Element *>(structural)->isVisual())
+ return;
+
+ VisualElement *visual = static_cast<VisualElement *>(structural);
+ visual->setShading(0, 0, 0, 0);
}
Common::SharedPtr<Modifier> ImageEffectModifier::shallowClone() const {
@@ -2547,6 +2570,41 @@ const char *ImageEffectModifier::getDefaultName() const {
return "Image Effect Modifier";
}
+VThreadState ImageEffectModifier::applyTask(const ApplyTaskData &taskData) {
+ Structural *structural = findStructuralOwner();
+ if (!structural || !structural->isElement() || !static_cast<Element *>(structural)->isVisual())
+ return kVThreadReturn;
+
+ VisualElement *visual = static_cast<VisualElement *>(structural);
+
+ int16 shadingLevel = static_cast<int16>(_toneAmount) * 256 / 100;
+
+ switch (_type) {
+ case kTypeDeselectedBevels:
+ visual->setShading(-shadingLevel, shadingLevel, 0, _bevelWidth);
+ break;
+ case kTypeSelectedBevels:
+ visual->setShading(shadingLevel, -shadingLevel, 0, _bevelWidth);
+ break;
+ case kTypeToneUp:
+ visual->setShading(0, 0, shadingLevel, 0);
+ break;
+ case kTypeToneDown:
+ visual->setShading(0, 0, -shadingLevel, 0);
+ break;
+ default:
+ break;
+ }
+
+ return kVThreadReturn;
+}
+
+VThreadState ImageEffectModifier::removeTask(const RemoveTaskData &taskData) {
+ this->disable(taskData.runtime);
+
+ return kVThreadReturn;
+}
+
ReturnModifier::ReturnModifier() {
}
diff --git a/engines/mtropolis/modifiers.h b/engines/mtropolis/modifiers.h
index a9fb82349f6..bc4c5fbc860 100644
--- a/engines/mtropolis/modifiers.h
+++ b/engines/mtropolis/modifiers.h
@@ -59,6 +59,7 @@ public:
#ifdef MTROPOLIS_DEBUG_ENABLE
const char *debugGetTypeName() const override { return "Behavior Modifier"; }
SupportStatus debugGetSupportStatus() const override { return kSupportStatusDone; }
+ void debugInspect(IDebugInspectionReport *report) const override;
#endif
private:
@@ -998,9 +999,24 @@ private:
kTypeToneUp,
};
+ struct ApplyTaskData {
+ ApplyTaskData() : runtime(nullptr) {}
+
+ Runtime *runtime;
+ };
+
+ struct RemoveTaskData {
+ RemoveTaskData() : runtime(nullptr) {}
+
+ Runtime *runtime;
+ };
+
Common::SharedPtr<Modifier> shallowClone() const override;
const char *getDefaultName() const override;
+ VThreadState applyTask(const ApplyTaskData &taskData);
+ VThreadState removeTask(const RemoveTaskData &taskData);
+
Event _applyWhen;
Event _removeWhen;
Type _type;
diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index cf43de38edb..f7ee53e18a4 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -4381,11 +4381,10 @@ bool Runtime::runFrame() {
if (_forceCursorRefreshOnce) {
_forceCursorRefreshOnce = false;
- _mouseOverObject.reset();
-
UpdateMousePositionTaskData *taskData = _vthread->pushTask("Runtime::updateMousePositionTask", this, &Runtime::updateMousePositionTask);
taskData->x = _cachedMousePosition.x;
taskData->y = _cachedMousePosition.y;
+ continue;
}
if (_queuedProjectDesc) {
@@ -8026,7 +8025,8 @@ VisualElementRenderProperties &VisualElementRenderProperties::operator=(const Vi
}
VisualElement::VisualElement()
- : _rect(0, 0, 0, 0), _cachedAbsoluteOrigin(Common::Point(0, 0)), _contentsDirty(true), _directToScreen(false), _visible(false), _visibleByDefault(true), _layer(0) {
+ : _rect(0, 0, 0, 0), _cachedAbsoluteOrigin(Common::Point(0, 0)), _contentsDirty(true), _directToScreen(false), _visible(false), _visibleByDefault(true), _layer(0),
+ _topLeftBevelShading(0), _bottomRightBevelShading(0), _interiorShading(0), _bevelSize(0) {
}
bool VisualElement::isVisual() const {
@@ -8431,6 +8431,17 @@ const Common::WeakPtr<GraphicModifier> &VisualElement::getPrimaryGraphicModifier
return _primaryGraphicModifier;
}
+void VisualElement::setShading(int16 topLeftBevelShading, int16 bottomRightBevelShading, int16 interiorShading, uint32 bevelSize) {
+ if (_topLeftBevelShading != topLeftBevelShading || _bottomRightBevelShading != bottomRightBevelShading || _interiorShading != interiorShading || _bevelSize != bevelSize) {
+ _topLeftBevelShading = topLeftBevelShading;
+ _bottomRightBevelShading = bottomRightBevelShading;
+ _interiorShading = interiorShading;
+ _bevelSize = bevelSize;
+
+ _contentsDirty = true;
+ }
+}
+
bool VisualElement::needsRender() const {
if (_renderProps.isDirty() || _prevRect != _rect || _contentsDirty)
return true;
@@ -8727,6 +8738,195 @@ VisualElement *VisualElement::recursiveFindItemWithLayer(VisualElement *element,
return nullptr;
}
+void VisualElement::renderShading(Graphics::Surface &surf) const {
+ uint32 bevelSize = _bevelSize;
+ uint32 w = surf.w;
+ uint32 h = surf.h;
+
+ uint32 maxHBevel = (w + 1) / 2;
+ uint32 maxVBevel = (h + 1) / 2;
+
+ if (bevelSize > maxHBevel)
+ bevelSize = maxHBevel;
+ if (bevelSize > maxVBevel)
+ bevelSize = maxVBevel;
+
+ uint32 rMask = surf.format.ARGBToColor(0, 255, 0, 0);
+ uint32 gMask = surf.format.ARGBToColor(0, 0, 255, 0);
+ uint32 bMask = surf.format.ARGBToColor(0, 0, 0, 255);
+
+ byte bytesPerPixel = surf.format.bytesPerPixel;
+
+ if (_topLeftBevelShading != 0) {
+ bool isBrighten = (_topLeftBevelShading > 0);
+
+ uint32 rAdd = quantizeShading(rMask, _topLeftBevelShading);
+ uint32 gAdd = quantizeShading(gMask, _topLeftBevelShading);
+ uint32 bAdd = quantizeShading(bMask, _topLeftBevelShading);
+
+ // Top bar
+ for (uint y = 0; y < bevelSize; y++)
+ renderShadingScanlineDynamic(surf.getBasePtr(0, y), w - y, rMask, rAdd, gMask, gAdd, bMask, bAdd, isBrighten, bytesPerPixel);
+
+ // Left bar
+ uint leftBarEndY = h + 1 - bevelSize;
+ for (uint y = bevelSize; y < leftBarEndY; y++)
+ renderShadingScanlineDynamic(surf.getBasePtr(0, y), bevelSize, rMask, rAdd, gMask, gAdd, bMask, bAdd, isBrighten, bytesPerPixel);
+
+ // Lower diagonal
+ for (uint y = leftBarEndY; y < h; y++)
+ renderShadingScanlineDynamic(surf.getBasePtr(0, y), bevelSize - 1 - (y - leftBarEndY), rMask, rAdd, gMask, gAdd, bMask, bAdd, isBrighten, bytesPerPixel);
+ }
+
+ if (_bottomRightBevelShading != 0) {
+ bool isBrighten = (_bottomRightBevelShading > 0);
+
+ uint32 rAdd = quantizeShading(rMask, _bottomRightBevelShading);
+ uint32 gAdd = quantizeShading(gMask, _bottomRightBevelShading);
+ uint32 bAdd = quantizeShading(bMask, _bottomRightBevelShading);
+
+ // Upper diagonal
+ for (uint y = 1; y < bevelSize; y++)
+ renderShadingScanlineDynamic(surf.getBasePtr(w - y, y), y, rMask, rAdd, gMask, gAdd, bMask, bAdd, isBrighten, bytesPerPixel);
+
+ uint rightBarEndY = h - bevelSize;
+ if (rightBarEndY < bevelSize)
+ rightBarEndY = bevelSize;
+
+ uint rightBarX = w - bevelSize;
+ if (rightBarX < bevelSize)
+ rightBarX = bevelSize;
+
+ // Right bar
+ for (uint y = bevelSize; y < rightBarEndY; y++)
+ renderShadingScanlineDynamic(surf.getBasePtr(rightBarX, y), w - rightBarX, rMask, rAdd, gMask, gAdd, bMask, bAdd, isBrighten, bytesPerPixel);
+
+ // Bottom bar
+ for (uint y = rightBarEndY; y < h; y++) {
+ uint bottomBarStartX = bevelSize - (y - rightBarEndY);
+ renderShadingScanlineDynamic(surf.getBasePtr(bottomBarStartX, y), w - bottomBarStartX, rMask, rAdd, gMask, gAdd, bMask, bAdd, isBrighten, bytesPerPixel);
+ }
+ }
+
+ if (_interiorShading != 0) {
+ uint32 startX = bevelSize;
+ uint32 endX = w - bevelSize;
+ uint32 startY = bevelSize;
+ uint32 endY = h - bevelSize;
+
+ if (startX < endX && startY < endY) {
+ bool isBrighten = (_bottomRightBevelShading > 0);
+
+ uint32 rAdd = quantizeShading(rMask, _bottomRightBevelShading);
+ uint32 gAdd = quantizeShading(gMask, _bottomRightBevelShading);
+ uint32 bAdd = quantizeShading(bMask, _bottomRightBevelShading);
+
+ for (uint y = startY; y < endY; y++)
+ renderShadingScanlineDynamic(surf.getBasePtr(startX, y), endX - startX, rMask, rAdd, gMask, gAdd, bMask, bAdd, isBrighten, bytesPerPixel);
+ }
+ }
+}
+
+uint32 VisualElement::quantizeShading(uint32 mask, int16 shading) {
+ uint32 absShading = (shading < 0) ? static_cast<int32>(-shading) : static_cast<int32>(shading);
+
+ if ((mask & 0xff) == 0) {
+ // Nothing in the low bytes, so shift down to avoid upper bits overflow
+ return ((mask >> 8) * absShading) & mask;
+ }
+
+ // Something was in the low bits, so avoid lower bits underflow instead
+ return ((mask * absShading) >> 8) & mask;
+}
+
+void VisualElement::renderShadingScanlineDynamic(void *data, size_t numElements, uint32 rMask, uint32 rAdd, uint32 gMask, uint32 gAdd, uint32 bMask, uint32 bAdd, bool isBrighten, byte bytesPerPixel) {
+ if (isBrighten) {
+ switch (bytesPerPixel) {
+ case 2:
+ renderBrightenScanline<uint16>(static_cast<uint16 *>(data), numElements, rMask, rAdd, gMask, gAdd, bMask, bAdd);
+ break;
+ case 4:
+ renderBrightenScanline<uint32>(static_cast<uint32 *>(data), numElements, rMask, rAdd, gMask, gAdd, bMask, bAdd);
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (bytesPerPixel) {
+ case 2:
+ renderDarkenScanline<uint16>(static_cast<uint16 *>(data), numElements, rMask, rAdd, gMask, gAdd, bMask, bAdd);
+ break;
+ case 4:
+ renderDarkenScanline<uint32>(static_cast<uint32 *>(data), numElements, rMask, rAdd, gMask, gAdd, bMask, bAdd);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+template<class TElement>
+void VisualElement::renderBrightenScanline(TElement *element, size_t numElements, TElement rMask, TElement rAdd, TElement gMask, TElement gAdd, TElement bMask, TElement bAdd) {
+ TElement rLimit = rMask - rAdd;
+ TElement gLimit = gMask - gAdd;
+ TElement bLimit = bMask - bAdd;
+
+ while (numElements > 0) {
+ TElement v = *element;
+
+ if ((v & rMask) > rLimit)
+ v |= rMask;
+ else
+ v += rAdd;
+
+ if ((v & gMask) > gLimit)
+ v |= gMask;
+ else
+ v += gAdd;
+
+ if ((v & bMask) > bLimit)
+ v |= bMask;
+ else
+ v += bAdd;
+
+ *element = v;
+
+ numElements--;
+ element++;
+ }
+}
+
+template<class TElement>
+static void VisualElement::renderDarkenScanline(TElement *element, size_t numElements, TElement rMask, TElement rSub, TElement gMask, TElement gSub, TElement bMask, TElement bSub) {
+ TElement rZero = ~rMask;
+ TElement gZero = ~gMask;
+ TElement bZero = ~bMask;
+
+ while (numElements > 0) {
+ TElement v = *element;
+
+ if ((v & rMask) < rSub)
+ v &= rZero;
+ else
+ v -= rSub;
+
+ if ((v & gMask) < gSub)
+ v &= gZero;
+ else
+ v -= gSub;
+
+ if ((v & bMask) < bSub)
+ v &= bZero;
+ else
+ v -= bSub;
+
+ *element = v;
+
+ numElements--;
+ element++;
+ }
+}
+
bool NonVisualElement::isVisual() const {
return false;
}
diff --git a/engines/mtropolis/runtime.h b/engines/mtropolis/runtime.h
index 8d94ebae0b1..508c47ad685 100644
--- a/engines/mtropolis/runtime.h
+++ b/engines/mtropolis/runtime.h
@@ -2756,6 +2756,8 @@ public:
const VisualElementRenderProperties &getRenderProperties() const;
const Common::WeakPtr<GraphicModifier> &getPrimaryGraphicModifier() const;
+ void setShading(int16 topLeftBevelShading, int16 bottomRightBevelShading, int16 interiorShading, uint32 bevelSize);
+
void setTransitionProperties(const VisualElementTransitionProperties &props);
const VisualElementTransitionProperties &getTransitionProperties() const;
@@ -2803,6 +2805,18 @@ protected:
static VisualElement *recursiveFindItemWithLayer(VisualElement *element, int32 layer);
+ void renderShading(Graphics::Surface &surf) const;
+
+ static uint32 quantizeShading(uint32 mask, int16 shading);
+
+ static void renderShadingScanlineDynamic(void *data, size_t numElements, uint32 rMask, uint32 rAdd, uint32 gMask, uint32 gAdd, uint32 bMask, uint32 bAdd, bool isBrighten, byte bytesPerPixel);
+
+ template<class TElement>
+ static void renderBrightenScanline(TElement *element, size_t numElements, TElement rMask, TElement rAdd, TElement gMask, TElement gAdd, TElement bMask, TElement bAdd);
+
+ template<class TElement>
+ static void renderDarkenScanline(TElement *element, size_t numElements, TElement rMask, TElement rSub, TElement gMask, TElement gSub, TElement bMask, TElement bSub);
+
bool _directToScreen;
bool _visible;
bool _visibleByDefault;
@@ -2810,6 +2824,11 @@ protected:
Common::Point _cachedAbsoluteOrigin;
uint16 _layer;
+ int16 _topLeftBevelShading;
+ int16 _bottomRightBevelShading;
+ int16 _interiorShading;
+ uint32 _bevelSize;
+
Common::SharedPtr<DragMotionProperties> _dragProps;
// Quirk: When a graphic modifier is applied, it becomes the primary graphic modifier, and disabling it
Commit: f3ff05e6589980a5a21bc13d6e48c4c44a255a3b
https://github.com/scummvm/scummvm/commit/f3ff05e6589980a5a21bc13d6e48c4c44a255a3b
Author: elasota (ejlasota at gmail.com)
Date: 2023-06-07T23:55:33-04:00
Commit Message:
VCRUISE: Properly fix EOS flag handling in Gentee Installer unpacker
Changed paths:
engines/vcruise/gentee_installer.cpp
diff --git a/engines/vcruise/gentee_installer.cpp b/engines/vcruise/gentee_installer.cpp
index 7640b785bbf..93a8762671d 100644
--- a/engines/vcruise/gentee_installer.cpp
+++ b/engines/vcruise/gentee_installer.cpp
@@ -540,6 +540,7 @@ uint32 DecompressingStream::read(void *dataPtr, uint32 dataSize) {
uint32 bytesAvailable = _decompressedSize - _pos;
if (dataSize > bytesAvailable) {
+ _eosFlag = true;
dataSize = bytesAvailable;
}
More information about the Scummvm-git-logs
mailing list