[Scummvm-git-logs] scummvm master -> cb0db51091ddcb67de95bfaa5e0f94a4f619db6d
sluicebox
noreply at scummvm.org
Fri Jul 5 17:46:18 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
cb0db51091 AGI: Fix closing window when overlapping with menu
Commit: cb0db51091ddcb67de95bfaa5e0f94a4f619db6d
https://github.com/scummvm/scummvm/commit/cb0db51091ddcb67de95bfaa5e0f94a4f619db6d
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-07-05T09:55:51-07:00
Commit Message:
AGI: Fix closing window when overlapping with menu
Fixes out of bounds memory access when closing a window that overlaps
with the menu bar at the top of the screen. This crashed at least some
release builds, including Windows release 2.8.1.
Mixed-Up Mother Goose is the only game known to draw a text window over
the menu bar. When I recently added support for this, I missed that the
code for closing the window needed to be updated too:
bc8550ce02a036e3757d817e963e038463844412
Fixes bug #15241
Big thanks to @hugoarpin for reporting this and testing the fix.
Changed paths:
engines/agi/graphics.cpp
engines/agi/graphics.h
engines/agi/text.cpp
diff --git a/engines/agi/graphics.cpp b/engines/agi/graphics.cpp
index 867cd048b0c..e8c457b9aa1 100644
--- a/engines/agi/graphics.cpp
+++ b/engines/agi/graphics.cpp
@@ -539,12 +539,7 @@ void GfxMgr::render_Block(int16 x, int16 y, int16 width, int16 height, bool copy
// logically dead or disabled. Is the purpose to adjust out-of-bounds coordinates
// so that they fit within boundaries, or is it to identify out-of-bounds
// coordinates so that the entire drawing operation can be rejected?
-bool GfxMgr::render_Clip(int16 &x, int16 &y, int16 &width, int16 &height, int16 clipAgainstWidth, int16 clipAgainstHeight) {
- // Allow rendering all the way to the top of the visual screen, even if there
- // is a menu bar. MMMG nursery rhyme message boxes appear over the menu bar
- // when the scripts pass a y-coordinate of zero to print.at(). Bug #13820
- int16 minY = 0 - _renderStartDisplayOffsetY;
-
+bool GfxMgr::render_Clip(int16 &x, int16 &y, int16 &width, int16 &height, const int16 minY, const int16 clipAgainstWidth, const int16 clipAgainstHeight) {
if ((x >= clipAgainstWidth) || ((x + width - 1) < 0) ||
(y < minY) || ((y + (height - 1)) >= clipAgainstHeight)) {
return false;
@@ -978,7 +973,11 @@ void GfxMgr::block_restore(int16 x, int16 y, int16 width, int16 height, byte *bu
// Going beyond 160x168 will result in messageboxes not getting fully removed
// In KQ4's case, the scripts clear the screen that's why it works.
void GfxMgr::drawBox(int16 x, int16 y, int16 width, int16 height, byte backgroundColor, byte lineColor) {
- if (!render_Clip(x, y, width, height, VISUAL_WIDTH, VISUAL_HEIGHT - _renderStartVisualOffsetY)) {
+ // Allow rendering all the way to the top of the visual screen, even if there
+ // is a menu bar. MMMG nursery rhyme message boxes appear over the menu bar
+ // when the scripts pass a y-coordinate of zero to print.at(). Bug #13820
+ const int16 minY = 0 - _renderStartDisplayOffsetY;
+ if (!render_Clip(x, y, width, height, minY, VISUAL_WIDTH, VISUAL_HEIGHT - _renderStartVisualOffsetY)) {
warning("drawBox ignored by clipping. x: %d, y: %d, w: %d, h: %d", x, y, width, height);
return;
}
diff --git a/engines/agi/graphics.h b/engines/agi/graphics.h
index 8ed36ce5ebf..9ef4e438750 100644
--- a/engines/agi/graphics.h
+++ b/engines/agi/graphics.h
@@ -173,7 +173,7 @@ public:
byte getCGAMixtureColor(byte color);
void render_Block(int16 x, int16 y, int16 width, int16 height, bool copyToScreen = true);
- bool render_Clip(int16 &x, int16 &y, int16 &width, int16 &height, int16 clipAgainstWidth = SCRIPT_WIDTH, int16 clipAgainstHeight = SCRIPT_HEIGHT);
+ bool render_Clip(int16 &x, int16 &y, int16 &width, int16 &height, const int16 minY = 0, const int16 clipAgainstWidth = SCRIPT_WIDTH, const int16 clipAgainstHeight = SCRIPT_HEIGHT);
private:
void render_BlockEGA(int16 x, int16 y, int16 width, int16 height);
diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index 58dbbb1c4a9..06773598849 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -548,7 +548,16 @@ bool TextMgr::isMouseWithinMessageBox() {
void TextMgr::closeWindow() {
if (_messageState.window_Active) {
- _gfx->render_Block(_messageState.backgroundPos_x, _messageState.backgroundPos_y, _messageState.backgroundSize_Width, _messageState.backgroundSize_Height);
+ // Close the window by copying the game screen to the display screen.
+ // Our graphics code was designed with the assumption that the window would
+ // always be contained within the game screen, but MUMG nursery rhymes pass
+ // y=0 to print.at to place the text at the top of the game screen with the
+ // window border over the menu bar. We now support this, but the background
+ // position is in game screen coordinates, so it will have a negative y value
+ // that we must limit to zero before copying. Bugs #13820, #15241
+ const int16 x = _messageState.backgroundPos_x;
+ const int16 y = MAX<int16>(0, _messageState.backgroundPos_y);
+ _gfx->render_Block(x, y, _messageState.backgroundSize_Width, _messageState.backgroundSize_Height);
}
_messageState.dialogue_Open = false;
_messageState.window_Active = false;
More information about the Scummvm-git-logs
mailing list