Fix incorrect mouse -> world position conversion in console #391
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Issue
The mouse -> world/level position conversion is incorrect when the level is zoomed, or the game has pillarboxes, or a watchtower is activated.
Here's a video showing the situations above, recording 2A dream block cutscene in 1600x720 (the actual screen is in 1280x720), when the cursor is at the cross points of lines, the calculated position is dividable by 8, so lines can show the calculated tiles using the reverse process.
You can see that the lines are not aligned to tiles at the beginning because of the pillarboxes, and they are not scaled when the level is zooming or the watchtower is activated.
2021-10-16_19-40-24.mp4
Reason
When the game has pillarboxes, for example, when the window's width is greater than the content width, the game will render the content in center and making two heights equal, but the game is rendered in 16:9 so there are black areas on left and right. In code,
Engine.Instance.GraphicsDevice.PresentationParameters.BackBufferWidth
is window's width. The original code calculates the view scale bywindowWidth / 320
, which gives the wrong result if the window is 1600x720. It shouldEngine.ViewWidth / 320
instead.When the game renders level, it first renders content in level to a buffer image, then renders the buffer to screen. When the level is zoomed, the game will render the buffer at different positions and different scales calculated by
Level.ZoomFocusPoint
,Level.Zoom
andLevel.ZoomTarget
.When a watchtower is activated,
Level.ScreenPadding
is changed.Solution
This patch adds two conversion methods,
Level.ScreenToWorld
andLevel.WorldToScreen
, for converting between the screen and world coordinate, considering all situations that might affect rendering (camera transform, level scale, level padding), except level rotation since currently there is no support for that (unless some mods hook the render angle). The methods assume the screen is in full size (1920x1080) because they are intended for mods to use them to do conversions when rendering HUDs ingame.2021-10-16_19-42-30.mp4