Cursor.Tile changes depending on zoom level and UI scale
Traktori7 opened this issue ยท 3 comments
In SMAPI 3.8.0, Cursor.Tile that comes from the event arguments returns the wrong tile if you change either zoom level or UI scale from 100%. This happens atleast in the ButtonPressed event.
Comment from #742 (which I presume is a duplicate, although on closer reading I'm not sure):
The value returned by IModHelper.Input.GetCursorPosition().Tile
called from a non-UI context is incorrect when the zoom level and UI scaling are different. The value appears to be calculated using the UI scaling.
This is either a bug in the implementation (or possibly the API design is no longer sufficient if it returns the correct value in UI contexts), or a bug in the documentation (which should indicate that the value can't be used reliably in non-UI contexts if that's the intended behavior).
To Reproduce
The following code snippet is inside an OnUpdateTicked
handler (with checks to only run every 6 events and only when the player has an item equipped, to keep it from blowing up my log too much).
var cursorTile = helper.Input.GetCursorPosition().Tile;
var mouse = Microsoft.Xna.Framework.Input.Mouse.GetState();
monitor.Log("UiMode " + Game1.uiMode + " zoom " + Game1.options.zoomLevel
+ " uiScale " + Game1.options.uiScale
+ " " + cursorTile
+ " | " + (int)((Game1.viewport.X + mouse.X / Game1.options.zoomLevel) / Game1.tileSize)
+ ", " + (int)((Game1.viewport.Y + mouse.Y / Game1.options.zoomLevel) / Game1.tileSize)
, LogLevel.Debug);
monitor.Log(" mouse " + mouse.X + ", " + mouse.Y
+ "; viewport " + Game1.viewport
+ " uiviewport " + Game1.uiViewport
+ " baseZoom " + Game1.options.baseZoomLevel
+ " tileSize " + Game1.tileSize
, LogLevel.Debug);
Here are a couple of lines from the output before and after I changed the UI scale (with the cursor over the same tile):
UiMode False zoom 0.75 uiScale 0.75 {X:68 Y:23} | 68, 23
mouse 733, 371; viewport [3413, 1019] - 1707 x 960 uiviewport [3413, 1019] - 1707 x 960 baseZoom 0.75 tileSize 64
UiMode False zoom 0.75 uiScale 1 {X:64 Y:21} | 68, 23
mouse 719, 360; viewport [3413, 1019] - 1707 x 960 uiviewport [3413, 1019] - 1281 x 720 baseZoom 0.75 tileSize 64
The coordinates on the first line of each output are different, and they should not be.
Obviously I did find the correct way to compute the tile myself, so I'm in no hurry for a fix, but I assume there are other mod developers who will trip over the same thing.
This seems to be related to the commit 85cb824
Replacing Game1.viewport with Game1.uiViewport in src/SMAPI/Framework/Input/SInputState.cs:209 looks to be the culprit at a quick glance since the world tiles aren't dependent on the UI scaling.
Edit: Disregard this, I had a chance to get into the game, and it seems I might not be on the proper track. I'm leaning more towards a zoom ration of UI:World zoom level.