1
0
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:
ζeh Matt
2024-02-18 17:07:11 +02:00
parent d95f14dcda
commit 462bb33234
7 changed files with 70 additions and 28 deletions

View File

@@ -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);
}
}

View File

@@ -127,7 +127,7 @@ namespace OpenRCT2::Scripting
{
while (w->viewport->rotation != value)
{
WindowRotateCamera(*w, 1);
ViewportRotateSingle(w, 1);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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");
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;