[Scummvm-git-logs] scummvm master -> 8b8880c2de31adf7c5451fdad6a7e6826a7e8116
bluegr
noreply at scummvm.org
Mon Jun 15 06:44:51 UTC 2026
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
c6d5853cbc NANCY: Separate cursors set from scripts and from code
a9112fa2cb NANCY: Add a temp hack for records without dependencies in Nancy 10
03a63a7ee3 NANCY: Fixes for the cellphone UI
2621224cd0 NANCY: Fixes for the Nancy10 sortpuzzle
8b8880c2de NANCY: Fix cursor after placing an item in the inventory in Nancy10
Commit: c6d5853cbc7841f7f65455542a4f44984e6c7385
https://github.com/scummvm/scummvm/commit/c6d5853cbc7841f7f65455542a4f44984e6c7385
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-15T09:44:37+03:00
Commit Message:
NANCY: Separate cursors set from scripts and from code
This allows us to skip the Nancy 10 cursor mapping for cases where the
cursor is set directly by game scripts
Changed paths:
engines/nancy/action/actionmanager.cpp
engines/nancy/action/actionrecord.h
engines/nancy/action/datarecords.h
engines/nancy/action/interactivevideo.cpp
engines/nancy/action/navigationrecords.h
engines/nancy/action/puzzle/multibuildpuzzle.cpp
engines/nancy/action/puzzle/orderingpuzzle.cpp
engines/nancy/action/puzzle/rippedletterpuzzle.cpp
engines/nancy/cursor.cpp
engines/nancy/cursor.h
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index 453179b3479..7cd07675549 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -64,7 +64,7 @@ void ActionManager::handleInput(NancyInput &input) {
if (!setHoverCursor) {
// Hotspots may overlap, but we want the hover cursor for the first one we encounter
// This fixes the stairs in nancy3
- g_nancy->_cursor->setCursorType(rec->getHoverCursor());
+ g_nancy->_cursor->setCursorType(rec->getHoverCursor(), rec->cursorSetFromScript());
setHoverCursor = true;
}
diff --git a/engines/nancy/action/actionrecord.h b/engines/nancy/action/actionrecord.h
index e30e8f542ec..887fbc02afa 100644
--- a/engines/nancy/action/actionrecord.h
+++ b/engines/nancy/action/actionrecord.h
@@ -114,6 +114,7 @@ public:
virtual void onPause(bool pause) {}
virtual CursorManager::CursorType getHoverCursor() const { return CursorManager::kHotspot; }
+ virtual bool cursorSetFromScript() const { return false; }
virtual void handleInput(NancyInput &input) {}
// Used for debugging
diff --git a/engines/nancy/action/datarecords.h b/engines/nancy/action/datarecords.h
index d200227d2f6..9022aac7a49 100644
--- a/engines/nancy/action/datarecords.h
+++ b/engines/nancy/action/datarecords.h
@@ -38,6 +38,7 @@ public:
void execute() override;
CursorManager::CursorType getHoverCursor() const override { return (CursorManager::CursorType)_cursorType; }
+ bool cursorSetFromScript() const override { return true; }
protected:
Common::String getRecordTypeName() const override { return "TableIndexSetValueHS"; }
@@ -121,6 +122,7 @@ public:
void execute() override;
CursorManager::CursorType getHoverCursor() const override;
+ bool cursorSetFromScript() const override { return true; }
CursorManager::CursorType _hoverCursor = CursorManager::kHotspot;
Common::Array<HotspotDescription> _hotspots;
diff --git a/engines/nancy/action/interactivevideo.cpp b/engines/nancy/action/interactivevideo.cpp
index b50851bf8e8..21ea17c58b6 100644
--- a/engines/nancy/action/interactivevideo.cpp
+++ b/engines/nancy/action/interactivevideo.cpp
@@ -130,7 +130,7 @@ void InteractiveVideo::handleInput(NancyInput &input) {
if (NancySceneState.getViewport().convertViewportToScreen(hotspot.hotspot).contains(input.mousePos)) {
// Mouse is in a hotspot, change cursor and set flag if clicked
if (hotspot.cursorID >= 0 && _cursors[hotspot.cursorID] >= 0) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_cursors[hotspot.cursorID]);
+ g_nancy->_cursor->setCursorType((CursorManager::CursorType)_cursors[hotspot.cursorID], true);
}
if (input.input & NancyInput::kLeftMouseButtonUp) {
@@ -144,7 +144,7 @@ void InteractiveVideo::handleInput(NancyInput &input) {
// Mouse is not in a hotspot for the frame, check if we have a default action
if (frame.triggerOnNoHotspot) {
if (frame.noHSCursorID >= 0 && _cursors[frame.noHSCursorID] >= 0) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_cursors[frame.noHSCursorID]);
+ g_nancy->_cursor->setCursorType((CursorManager::CursorType)_cursors[frame.noHSCursorID], true);
}
if (input.input & NancyInput::kLeftMouseButtonUp) {
diff --git a/engines/nancy/action/navigationrecords.h b/engines/nancy/action/navigationrecords.h
index 4cf3a750f68..45647d57f88 100644
--- a/engines/nancy/action/navigationrecords.h
+++ b/engines/nancy/action/navigationrecords.h
@@ -52,6 +52,7 @@ public:
void execute() override;
CursorManager::CursorType getHoverCursor() const override { return _hoverCursor; }
+ bool cursorSetFromScript() const override { return true; }
HotspotDescription _sceneHotspot;
@@ -115,6 +116,7 @@ public:
void execute() override;
CursorManager::CursorType getHoverCursor() const override { return _hoverCursor; }
+ bool cursorSetFromScript() const override { return _dynamicCursor; }
HotspotDescription _hotspotDesc;
bool _isTerse = false;
diff --git a/engines/nancy/action/puzzle/multibuildpuzzle.cpp b/engines/nancy/action/puzzle/multibuildpuzzle.cpp
index 5e52f8e20d3..4655799b4da 100644
--- a/engines/nancy/action/puzzle/multibuildpuzzle.cpp
+++ b/engines/nancy/action/puzzle/multibuildpuzzle.cpp
@@ -493,7 +493,7 @@ void MultiBuildPuzzle::handleInput(NancyInput &input) {
}
if (_selectedPiece != -1) {
- g_nancy->_cursor->setCursorType(dragCursor);
+ g_nancy->_cursor->setCursorType(dragCursor, true);
if (input.input & NancyInput::kLeftMouseButtonUp) {
int sel = _selectedPiece;
@@ -563,7 +563,7 @@ void MultiBuildPuzzle::handleInput(NancyInput &input) {
}
if (topmost != -1) {
- g_nancy->_cursor->setCursorType(dragCursor);
+ g_nancy->_cursor->setCursorType(dragCursor, true);
if (input.input & NancyInput::kLeftMouseButtonUp) {
Piece &pp = _pieces[topmost];
diff --git a/engines/nancy/action/puzzle/orderingpuzzle.cpp b/engines/nancy/action/puzzle/orderingpuzzle.cpp
index 942031d0714..8270180851b 100644
--- a/engines/nancy/action/puzzle/orderingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/orderingpuzzle.cpp
@@ -511,9 +511,9 @@ void OrderingPuzzle::handleInput(NancyInput &input) {
if (NancySceneState.getViewport().convertViewportToScreen(_hotspots[i]).contains(input.mousePos)) {
// Set the custom cursor for nancy8+ PianoPuzzle
if (NancySceneState.getViewport().convertViewportToScreen(_specialCursor1Dest).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_specialCursor1Id);
+ g_nancy->_cursor->setCursorType((CursorManager::CursorType)_specialCursor1Id, true);
} else if (NancySceneState.getViewport().convertViewportToScreen(_specialCursor2Dest).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_specialCursor2Id);
+ g_nancy->_cursor->setCursorType((CursorManager::CursorType)_specialCursor2Id, true);
} else {
g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
}
diff --git a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
index f6e7afa2ddd..da4957803ed 100644
--- a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
+++ b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
@@ -439,7 +439,10 @@ void RippedLetterPuzzle::handleInput(NancyInput &input) {
if (_puzzleState->_pickedUpPieceID == -1) {
// No piece picked up, check the exit hotspot
if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(_customCursorID != -1 ? (CursorManager::CursorType)_customCursorID : g_nancy->_cursor->_puzzleExitCursor);
+ if (_customCursorID != -1)
+ g_nancy->_cursor->setCursorType((CursorManager::CursorType)_customCursorID, true);
+ else
+ g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
if (input.input & NancyInput::kLeftMouseButtonUp) {
// Player has clicked, exit
diff --git a/engines/nancy/cursor.cpp b/engines/nancy/cursor.cpp
index f39c61e34c7..eb0df46e0b0 100644
--- a/engines/nancy/cursor.cpp
+++ b/engines/nancy/cursor.cpp
@@ -123,7 +123,7 @@ void CursorManager::init(Common::SeekableReadStream *chunkStream) {
g_nancy->_resource->loadImage(inventoryCursorsImageName, _invCursorsSurface);
- setCursor(kNormalArrow, -1);
+ setCursor(kNormalArrow, -1, false);
showCursor(false);
_isInitialized = true;
@@ -133,7 +133,7 @@ void CursorManager::init(Common::SeekableReadStream *chunkStream) {
delete chunkStream;
}
-uint CursorManager::resolveNancy10CursorID(CursorType type, int16 itemID) {
+uint CursorManager::resolveNancy10CursorID(CursorType type, int16 itemID, bool setFromScript) {
// Item-held variants. The Nancy 10+ chunk reserves `numItems à 2`
// slots after the two 37-entry system arrays (= _numCursorTypes * 2),
// each item getting one [idle, hotspot] pair. Held items only
@@ -147,6 +147,9 @@ uint CursorManager::resolveNancy10CursorID(CursorType type, int16 itemID) {
return itemsOffset + (uint)itemID * 2 + variant;
}
+ if (setFromScript)
+ return type;
+
// System cursors: translate the legacy CursorType to the matching
// kNew* idle slot. Each Nancy 10+ cursor type T occupies a pair
// (T*2, T*2+1) in the chunk â idle followed by hotspot. We always
@@ -177,7 +180,7 @@ uint CursorManager::resolveNancy10CursorID(CursorType type, int16 itemID) {
}
}
-void CursorManager::setCursor(CursorType type, int16 itemID) {
+void CursorManager::setCursor(CursorType type, int16 itemID, bool setFromScript) {
if (!_isInitialized)
return;
@@ -191,7 +194,7 @@ void CursorManager::setCursor(CursorType type, int16 itemID) {
_hasItem = false;
if (gameType >= kGameTypeNancy10) {
- _curCursorID = resolveNancy10CursorID(type, itemID);
+ _curCursorID = resolveNancy10CursorID(type, itemID, setFromScript);
return;
}
@@ -304,12 +307,12 @@ void CursorManager::setCursor(CursorType type, int16 itemID) {
_curCursorID = (uint)(itemID * _numCursorTypes) + itemsOffset + (uint)type;
}
-void CursorManager::setCursorType(CursorType type) {
- setCursor(type, _curItemID);
+void CursorManager::setCursorType(CursorType type, bool setFromScript) {
+ setCursor(type, _curItemID, setFromScript);
}
void CursorManager::setCursorItemID(int16 itemID) {
- setCursor(_curCursorType, itemID);
+ setCursor(_curCursorType, itemID, false);
}
void CursorManager::warpCursor(const Common::Point &pos) {
diff --git a/engines/nancy/cursor.h b/engines/nancy/cursor.h
index 0dbf7c4a336..f443eb57f4c 100644
--- a/engines/nancy/cursor.h
+++ b/engines/nancy/cursor.h
@@ -95,8 +95,8 @@ public:
void init(Common::SeekableReadStream *chunkStream);
// Change the current cursor ID. Does not change the graphic
- void setCursor(CursorType type, int16 itemID);
- void setCursorType(CursorType type);
+ void setCursor(CursorType type, int16 itemID, bool setFromScript);
+ void setCursorType(CursorType type, bool setFromScript = false);
void setCursorItemID(int16 itemID);
void showCursor(bool shouldShow);
@@ -115,7 +115,7 @@ private:
void adjustCursorHotspot();
// Resolve a CursorType + held-item pair to a Nancy 10+ cursor ID.
- uint resolveNancy10CursorID(CursorType type, int16 itemID);
+ uint resolveNancy10CursorID(CursorType type, int16 itemID, bool setFromScript);
struct Cursor {
Common::Rect bounds;
Commit: a9112fa2cb72a9ac00162716f94e0698d57bedb3
https://github.com/scummvm/scummvm/commit/a9112fa2cb72a9ac00162716f94e0698d57bedb3
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-15T09:44:38+03:00
Commit Message:
NANCY: Add a temp hack for records without dependencies in Nancy 10
Changed paths:
engines/nancy/action/secondarymovie.cpp
diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index 0aef5ece44b..5417d3d7772 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -157,6 +157,17 @@ void PlaySecondaryMovie::onPause(bool pause) {
void PlaySecondaryMovie::execute() {
switch (_state) {
case kBegin:
+ // HACK: In Nancy 10, scene 2987, there are two PlaySecondaryMovie records that play
+ // the same video, but have no dependencies. The first video leads to the losing scene,
+ // while the second one leads to the winning scene. Since none of the two records has a
+ // dependency, the first one will always be executed. It seems like there should be
+ // a check to prevent the first record from being executed, but it wasn't possible to
+ // find it. Don't start the first record for now, so that the second one can be
+ // executed and the player can proceed.
+ // TODO: Find out what the original engine does in this case, and implement it properly.
+ if (g_nancy->getGameType() == kGameTypeNancy10 && _videoSceneChange == kMovieSceneChange && _sceneChange.sceneID == 2989)
+ return;
+
init();
registerGraphics();
g_nancy->_sound->loadSound(_sound);
Commit: 03a63a7ee35a7aa8b9369557dc3475cff56cf1fd
https://github.com/scummvm/scummvm/commit/03a63a7ee35a7aa8b9369557dc3475cff56cf1fd
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-15T09:44:38+03:00
Commit Message:
NANCY: Fixes for the cellphone UI
- Add hovered state for the up/down arrows
- Fix display of e-mail messages
Changed paths:
engines/nancy/ui/cellphonepopup.cpp
engines/nancy/ui/cellphonepopup.h
diff --git a/engines/nancy/ui/cellphonepopup.cpp b/engines/nancy/ui/cellphonepopup.cpp
index dcec5b05f61..5444205603f 100644
--- a/engines/nancy/ui/cellphonepopup.cpp
+++ b/engines/nancy/ui/cellphonepopup.cpp
@@ -252,6 +252,8 @@ void CellPhonePopup::open() {
_directoryScroll = 0;
_directorySelection = 0;
_closeButtonHovered = false;
+ _scrollUpHovered = false;
+ _scrollDownHovered = false;
drawChrome();
drawScreenContent();
@@ -1002,20 +1004,31 @@ const UICL::ThreeRectWidget &CellPhonePopup::scrollDownButton() const {
void CellPhonePopup::drawDirectoryArrows() {
// Up/down scroll arrows are not in the chrome image; blit on every redraw.
+ // The pressed (lit) sprite is used while the cursor is over the arrow.
const UICL::ThreeRectWidget &up = scrollUpButton();
const UICL::ThreeRectWidget &down = scrollDownButton();
const Common::Point chunkOrigin(_screenPosition.left, _screenPosition.top);
- if (!up.srcRectIdle.isEmpty() && !up.destRect.isEmpty()) {
- _drawSurface.blitFrom(_spritesImage, up.srcRectIdle,
- Common::Point(up.destRect.left - chunkOrigin.x,
- up.destRect.top - chunkOrigin.y));
+ if (!up.destRect.isEmpty()) {
+ const Common::Rect &upSrc = (_scrollUpHovered && !up.srcRectPressed.isEmpty())
+ ? up.srcRectPressed
+ : up.srcRectIdle;
+ if (!upSrc.isEmpty()) {
+ _drawSurface.blitFrom(_spritesImage, upSrc,
+ Common::Point(up.destRect.left - chunkOrigin.x,
+ up.destRect.top - chunkOrigin.y));
+ }
}
- if (!down.srcRectIdle.isEmpty() && !down.destRect.isEmpty()) {
- _drawSurface.blitFrom(_spritesImage, down.srcRectIdle,
- Common::Point(down.destRect.left - chunkOrigin.x,
- down.destRect.top - chunkOrigin.y));
+ if (!down.destRect.isEmpty()) {
+ const Common::Rect &downSrc = (_scrollDownHovered && !down.srcRectPressed.isEmpty())
+ ? down.srcRectPressed
+ : down.srcRectIdle;
+ if (!downSrc.isEmpty()) {
+ _drawSurface.blitFrom(_spritesImage, downSrc,
+ Common::Point(down.destRect.left - chunkOrigin.x,
+ down.destRect.top - chunkOrigin.y));
+ }
}
// Selection indicator (dirArrowSrc sprite) at the dirCursorSrc column,
@@ -1174,7 +1187,12 @@ bool CellPhonePopup::consumeReturnScene(SceneChangeDescription &out) {
// --------------------------------------------------------------------
int CellPhonePopup::rowPitch() const {
- // Original (FUN_004d8476): pitch = dirCursorSrc.height + 8.
+ // Email rows are sized by the unread/selected icon so they don't
+ // overlap; directory and search lists use the compact arrow-cursor
+ // pitch.
+ if (_screenState == kEmailList && !_uiclData->emailIconUnread.isEmpty()) {
+ return _uiclData->emailIconUnread.height() + 1;
+ }
const Common::Rect &cursor = _uiclData->dirCursorSrc;
if (!cursor.isEmpty()) {
return cursor.height() + 8;
@@ -1183,7 +1201,11 @@ int CellPhonePopup::rowPitch() const {
}
int CellPhonePopup::rowTopScreen() const {
- // First row's Y (screen). Original anchors on dirCursorSrc.top - 5.
+ // Email list anchors on the zoomed-chrome list container; everything
+ // else stacks under the arrow-cursor row.
+ if (_screenState == kEmailList && !_uiclData->emailListContainer.isEmpty()) {
+ return _uiclData->emailListContainer.top;
+ }
const Common::Rect &cursor = _uiclData->dirCursorSrc;
if (!cursor.isEmpty()) {
return cursor.top - 5;
@@ -1196,7 +1218,9 @@ uint CellPhonePopup::maxDirectoryRows() const {
if (pitch <= 0) {
return 0;
}
- const int yLimit = _uiclData->welcomeScreen.destRect.bottom;
+ const int yLimit = (_screenState == kEmailList && !_uiclData->emailListContainer.isEmpty())
+ ? _uiclData->emailListContainer.bottom
+ : _uiclData->welcomeScreen.destRect.bottom;
int y = rowTopScreen();
uint count = 0;
while (y + pitch < yLimit) {
@@ -1473,6 +1497,19 @@ void CellPhonePopup::handleInput(NancyInput &input) {
const Common::Point chunkMouse = mouseToChunkCoords(input.mousePos);
+ // Light the up/down arrows on hover in any state that uses them.
+ const bool arrowsActive = _screenState == kDirectory || isLinkListMode() ||
+ _screenState == kContentView;
+ const bool overUp = arrowsActive &&
+ scrollUpButton().destRect.contains(chunkMouse);
+ const bool overDown = arrowsActive && !overUp &&
+ scrollDownButton().destRect.contains(chunkMouse);
+ if (overUp != _scrollUpHovered || overDown != _scrollDownHovered) {
+ _scrollUpHovered = overUp;
+ _scrollDownHovered = overDown;
+ drawScreenContent();
+ }
+
// Help "?" button: opens the help page in the content view. Reachable
// from any interactive state (except when already showing it).
if (!_uiclData->helpButton.destRect.isEmpty() && !_uiclData->helpTextKey.empty() &&
diff --git a/engines/nancy/ui/cellphonepopup.h b/engines/nancy/ui/cellphonepopup.h
index 9a2759b502b..f60f94a463c 100644
--- a/engines/nancy/ui/cellphonepopup.h
+++ b/engines/nancy/ui/cellphonepopup.h
@@ -193,6 +193,8 @@ private:
Graphics::ManagedSurface _spritesImage;
bool _closeButtonHovered = false;
+ bool _scrollUpHovered = false;
+ bool _scrollDownHovered = false;
ScreenState _screenState = kWelcome;
Commit: 2621224cd0358860ab80aa76eac805c06b03a2e8
https://github.com/scummvm/scummvm/commit/2621224cd0358860ab80aa76eac805c06b03a2e8
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-15T09:44:40+03:00
Commit Message:
NANCY: Fixes for the Nancy10 sortpuzzle
- Fix gem graphics when placing them
- Use the smaller grab cursor when holding gems
- Add a cheat to show the grid in the console when pressing space
Changed paths:
engines/nancy/action/puzzle/sortpuzzle.cpp
engines/nancy/cursor.cpp
engines/nancy/cursor.h
diff --git a/engines/nancy/action/puzzle/sortpuzzle.cpp b/engines/nancy/action/puzzle/sortpuzzle.cpp
index c2cd20dfb0f..3c14abf371b 100644
--- a/engines/nancy/action/puzzle/sortpuzzle.cpp
+++ b/engines/nancy/action/puzzle/sortpuzzle.cpp
@@ -38,7 +38,6 @@ namespace Action {
// Tiles within a color group share their board sprite (srcRow, srcCol); the
// hidden `value` field disambiguates them, which is visible in the back of
// each gem, when picking it up.
-// TODO: Use correct cursor type (hand instead of eyeglass) when picking up gems.
static void packGrid(const SortPuzzle::Cell grid[][SortPuzzle::kMaxCols], uint16 rows, uint16 cols, Common::Array<int16> &out) {
out.clear();
out.push_back((int16)rows);
@@ -258,8 +257,10 @@ void SortPuzzle::execute() {
}
Common::Rect SortPuzzle::cellRect(int row, int col) const {
- int x = (int)_originX + col * ((int)_spacingX + _cellWidth);
- int y = (int)_originY + row * ((int)_spacingY + _cellHeight);
+ // Original uses inclusive-coordinate width (right_raw - left_raw) for the
+ // per-col / per-row step, which is cellWidth-1 in our exclusive convention.
+ int x = (int)_originX + col * ((int)_spacingX + _cellWidth - 1);
+ int y = (int)_originY + row * ((int)_spacingY + _cellHeight - 1);
return Common::Rect(x, y, x + _cellWidth, y + _cellHeight);
}
@@ -283,6 +284,20 @@ void SortPuzzle::handleInput(NancyInput &input) {
Common::Rect vpScreen = NancySceneState.getViewport().getScreenPosition();
Common::Point mouseVP = input.mousePos - Common::Point(vpScreen.left, vpScreen.top);
+ // Cheat: show the grid with the value of each gem in the console
+ if (!input.otherKbdInput.empty() && input.otherKbdInput[0].keycode == Common::KEYCODE_SPACE) {
+ debug("-----");
+ for (int r = 0; r < (int)_rows; ++r) {
+ Common::String line;
+ for (int c = 0; c < (int)_cols; ++c) {
+ const Cell &cur = _current[r][c];
+ line += Common::String::format("%d ", cur.value);
+ }
+ debug(line.c_str());
+ }
+ debug("-----");
+ }
+
if (_hasHeld && _heldDrawPos != mouseVP) {
_heldDrawPos = mouseVP;
redraw();
@@ -300,7 +315,7 @@ void SortPuzzle::handleInput(NancyInput &input) {
return;
}
- g_nancy->_cursor->setCursorType(_hasHeld ? CursorManager::kDragHand
+ g_nancy->_cursor->setCursorType(_hasHeld ? CursorManager::kDropHand
: CursorManager::kHotspot);
if (!(input.input & NancyInput::kLeftMouseButtonUp))
return;
diff --git a/engines/nancy/cursor.cpp b/engines/nancy/cursor.cpp
index eb0df46e0b0..6e9ad58c165 100644
--- a/engines/nancy/cursor.cpp
+++ b/engines/nancy/cursor.cpp
@@ -159,6 +159,7 @@ uint CursorManager::resolveNancy10CursorID(CursorType type, int16 itemID, bool s
case kHotspot: return kNewHotspot;
case kHotspotTalk: return kNewHotspotTalk;
case kDragHand: return kNewDragHand;
+ case kDropHand: return kNewDropHand;
case kNormalArrow: return kNewNormalArrow;
case kHotspotArrow: return kNewHotspotArrow;
case kExit: return kNewExit;
diff --git a/engines/nancy/cursor.h b/engines/nancy/cursor.h
index f443eb57f4c..9fdbd8f1ae0 100644
--- a/engines/nancy/cursor.h
+++ b/engines/nancy/cursor.h
@@ -57,6 +57,7 @@ public:
kHotspotArrow = 21,
kHotspotTalk = 22, // Speech-bubble hover cursor (Nancy 10+)
kDragHand = 23, // Hand cursor used when dragging an item (Nancy 10+)
+ kDropHand = 24, // Drop-hand cursor used while a piece is held over a target (Nancy 10+)
// Cursors in Nancy10 and newer games. The CURS chunk holds 37 system
// cursor types in pairs; type T's idle slot is (T*2) and its hotspot
Commit: 8b8880c2de31adf7c5451fdad6a7e6826a7e8116
https://github.com/scummvm/scummvm/commit/8b8880c2de31adf7c5451fdad6a7e6826a7e8116
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-15T09:44:40+03:00
Commit Message:
NANCY: Fix cursor after placing an item in the inventory in Nancy10
Changed paths:
engines/nancy/ui/inventorypopup.cpp
diff --git a/engines/nancy/ui/inventorypopup.cpp b/engines/nancy/ui/inventorypopup.cpp
index ddada1f2ef2..3ea138714fd 100644
--- a/engines/nancy/ui/inventorypopup.cpp
+++ b/engines/nancy/ui/inventorypopup.cpp
@@ -314,13 +314,10 @@ void InventoryPopup::handleInput(NancyInput &input) {
input.mousePos.x - _screenPosition.left + _uiivData->header.normalDestRect.left,
input.mousePos.y - _screenPosition.top + _uiivData->header.normalDestRect.top);
- // Nancy 10+ only blends the held-item sprite onto kNormal / kHotspot
- // cursors. Switch to kHotspot when holding so the item stays visible
- // while hovering popup widgets.
- const CursorManager::CursorType hoverCursor =
- NancySceneState.getHeldItem() == -1
- ? CursorManager::kHotspotArrow
- : CursorManager::kHotspot;
+ // kHotspot is the highlighted magnifier and also the cursor that
+ // blends a held-item sprite on Nancy 10+, so it works in both
+ // "empty hand" (plain magnifier) and "carrying" (magnifier + item) states.
+ const CursorManager::CursorType hoverCursor = CursorManager::kHotspot;
// Scrollbar interaction takes priority while dragging.
const UISliderRecord &slider = _uiivData->header.slider;
More information about the Scummvm-git-logs
mailing list