diff --git a/src/openrct2-ui/input/Shortcuts.cpp b/src/openrct2-ui/input/Shortcuts.cpp index daef77393d..8081c03527 100644 --- a/src/openrct2-ui/input/Shortcuts.cpp +++ b/src/openrct2-ui/input/Shortcuts.cpp @@ -62,11 +62,7 @@ static void RotateCamera(int32_t direction) { if (!(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO)) { - auto window = WindowGetMain(); - if (window != nullptr) - { - WindowRotateCamera(*window, direction); - } + ViewportRotateAll(direction); } } diff --git a/src/openrct2-ui/scripting/ScViewport.hpp b/src/openrct2-ui/scripting/ScViewport.hpp index 0ef551313a..828e9639fe 100644 --- a/src/openrct2-ui/scripting/ScViewport.hpp +++ b/src/openrct2-ui/scripting/ScViewport.hpp @@ -127,7 +127,7 @@ namespace OpenRCT2::Scripting { while (w->viewport->rotation != value) { - WindowRotateCamera(*w, 1); + ViewportRotateSingle(w, 1); } } } diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 2cc73bac57..0abd720470 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -3689,19 +3689,13 @@ void TopToolbar::InitRotateMenu(Widget& widget) void TopToolbar::RotateMenuDropdown(int16_t dropdownIndex) { - auto* w = WindowGetMain(); - if (w != nullptr) + if (dropdownIndex == 0) { - if (dropdownIndex == 0) - { - WindowRotateCamera(*w, 1); - w->Invalidate(); - } - else if (dropdownIndex == 1) - { - WindowRotateCamera(*w, -1); - w->Invalidate(); - } + ViewportRotateAll(1); + } + else if (dropdownIndex == 1) + { + ViewportRotateAll(-1); } } diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 9013e739c4..5c2636e3eb 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -1166,15 +1166,14 @@ static int32_t ConsoleCommandSet(InteractiveConsole& console, const arguments_t& else if (argv[0] == "current_rotation" && InvalidArguments(&invalidArgs, int_valid[0])) { uint8_t currentRotation = GetCurrentRotation(); - WindowBase* mainWindow = WindowGetMain(); int32_t newRotation = int_val[0]; if (newRotation < 0 || newRotation > 3) { console.WriteLineError("Invalid argument. Valid rotations are 0-3."); } - else if (newRotation != currentRotation && mainWindow != nullptr) + else if (newRotation != currentRotation) { - WindowRotateCamera(*mainWindow, newRotation - currentRotation); + ViewportRotateAll(newRotation - currentRotation); } console.Execute("get current_rotation"); } diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index d211443826..0ef86b2e50 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -802,6 +802,60 @@ void ViewportUpdateSmartFollowVehicle(WindowBase* window) window->viewport_target_sprite = window->viewport_smart_follow_sprite; } +static void ViewportRotateSingleInternal(WindowBase& w, int32_t direction) +{ + auto* viewport = w.viewport; + if (viewport == nullptr) + return; + + auto windowPos = ScreenCoordsXY{ (viewport->width >> 1), (viewport->height >> 1) } + viewport->pos; + + // has something to do with checking if middle of the viewport is obstructed + Viewport* other; + auto mapXYCoords = ScreenGetMapXY(windowPos, &other); + CoordsXYZ coords{}; + + // other != viewport probably triggers on viewports in ride or guest window? + // naoXYCoords is nullopt if middle of viewport is obstructed by another window? + if (!mapXYCoords.has_value() || other != viewport) + { + auto viewPos = ScreenCoordsXY{ (viewport->view_width >> 1), (viewport->view_height >> 1) } + viewport->viewPos; + + coords = ViewportAdjustForMapHeight(viewPos, viewport->rotation); + } + else + { + coords.x = mapXYCoords->x; + coords.y = mapXYCoords->y; + coords.z = TileElementHeight(coords); + } + + viewport->rotation = (viewport->rotation + direction) & 3; + + auto centreLoc = centre_2d_coordinates(coords, viewport); + + if (centreLoc.has_value()) + { + w.savedViewPos = centreLoc.value(); + viewport->viewPos = *centreLoc; + } + + w.Invalidate(); + WindowEventViewportRotateCall(&w); +} + +void ViewportRotateSingle(WindowBase* window, int32_t direction) +{ + ViewportRotateSingleInternal(*window, direction); + ResetAllSpriteQuadrantPlacements(); +} + +void ViewportRotateAll(int32_t direction) +{ + WindowVisitEach([direction](WindowBase* w) { ViewportRotateSingleInternal(*w, direction); }); + ResetAllSpriteQuadrantPlacements(); +} + /** * * rct2: 0x00685C02 @@ -1977,7 +2031,7 @@ std::optional ScreenGetMapXYWithZ(const ScreenCoordsXY& screenCoords, } auto vpCoords = viewport->ScreenToViewportCoord(screenCoords); - auto mapPosition = ViewportPosToMapPos(vpCoords, z); + auto mapPosition = ViewportPosToMapPos(vpCoords, z, viewport->rotation); if (!MapIsLocationValid(mapPosition)) { return std::nullopt; diff --git a/src/openrct2/interface/Viewport.h b/src/openrct2/interface/Viewport.h index 3d52d87265..7420fd4fe7 100644 --- a/src/openrct2/interface/Viewport.h +++ b/src/openrct2/interface/Viewport.h @@ -135,6 +135,8 @@ void ViewportUpdateSmartFollowEntity(WindowBase* window); void ViewportUpdateSmartFollowGuest(WindowBase* window, const Guest* peep); void ViewportUpdateSmartFollowStaff(WindowBase* window, const Staff* peep); void ViewportUpdateSmartFollowVehicle(WindowBase* window); +void ViewportRotateSingle(WindowBase* window, int32_t direction); +void ViewportRotateAll(int32_t direction); void ViewportRender(DrawPixelInfo& dpi, const Viewport* viewport, const ScreenRect& screenRect); CoordsXYZ ViewportAdjustForMapHeight(const ScreenCoordsXY& startCoords, uint8_t rotation); diff --git a/src/openrct2/title/Command/RotateView.cpp b/src/openrct2/title/Command/RotateView.cpp index a4e6ac7263..b49cf5b313 100644 --- a/src/openrct2/title/Command/RotateView.cpp +++ b/src/openrct2/title/Command/RotateView.cpp @@ -9,19 +9,16 @@ #include "RotateView.h" +#include "../../interface/Viewport.h" #include "../../interface/Window.h" namespace OpenRCT2::Title { int16_t RotateViewCommand::operator()(int16_t timer) { - WindowBase* w = WindowGetMain(); - if (w != nullptr) + for (uint_fast8_t i = 0; i < Rotations; i++) { - for (uint_fast8_t i = 0; i < Rotations; i++) - { - WindowRotateCamera(*w, 1); - } + ViewportRotateAll(1); } return 0;