mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-24 23:34:37 +01:00
Refactor viewport rotation to keep it in sync with the primary viewport
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace OpenRCT2::Scripting
|
||||
{
|
||||
while (w->viewport->rotation != value)
|
||||
{
|
||||
WindowRotateCamera(*w, 1);
|
||||
ViewportRotateSingle(w, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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<CoordsXY> 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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user