mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #21424 from ZehMatt/viewport-update
Store the rotation in viewports
This commit is contained in:
commit
a2fdd600cf
|
@ -1,5 +1,7 @@
|
|||
0.4.10 (in development)
|
||||
------------------------------------------------------------------------
|
||||
- Improved: [#21424] Extra viewports can now rotate independently from the main viewport.
|
||||
- Fix: [#910] Extra viewport does not preserve the location when rotating.
|
||||
|
||||
0.4.9 (2024-03-02)
|
||||
------------------------------------------------------------------------
|
||||
|
|
|
@ -587,7 +587,7 @@ public:
|
|||
mainWindow->viewport_target_sprite = EntityId::GetNull();
|
||||
mainWindow->savedViewPos = viewPos;
|
||||
viewport->zoom = zoom;
|
||||
gCurrentRotation = rotation;
|
||||
viewport->rotation = rotation;
|
||||
|
||||
if (zoomDifference != ZoomLevel{ 0 })
|
||||
{
|
||||
|
|
|
@ -1688,8 +1688,8 @@ void InputScrollViewport(const ScreenCoordsXY& scrollScreenCoords)
|
|||
int32_t y = mainWindow->savedViewPos.y + viewport->view_height / 2;
|
||||
int32_t y_dy = mainWindow->savedViewPos.y + viewport->view_height / 2 + dy;
|
||||
|
||||
auto mapCoord = ViewportPosToMapPos({ x, y }, 0);
|
||||
auto mapCoord_dy = ViewportPosToMapPos({ x, y_dy }, 0);
|
||||
auto mapCoord = ViewportPosToMapPos({ x, y }, 0, viewport->rotation);
|
||||
auto mapCoord_dy = ViewportPosToMapPos({ x, y_dy }, 0, viewport->rotation);
|
||||
|
||||
// Check if we're crossing the boundary
|
||||
// Clamp to the map minimum value
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -718,16 +718,21 @@ struct PeepDistance
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
PeepDistance GetClosestPeep(const ScreenCoordsXY& viewportCoords, const int32_t maxDistance, PeepDistance goal)
|
||||
static PeepDistance GetClosestPeep(
|
||||
const ScreenCoordsXY& viewportCoords, uint8_t rotation, const int32_t maxDistance, PeepDistance goal)
|
||||
{
|
||||
for (auto peep : EntityList<T>())
|
||||
{
|
||||
if (peep->x == LOCATION_NULL)
|
||||
continue;
|
||||
|
||||
auto distance = abs(((peep->SpriteData.SpriteRect.GetLeft() + peep->SpriteData.SpriteRect.GetRight()) / 2)
|
||||
- viewportCoords.x)
|
||||
+ abs(((peep->SpriteData.SpriteRect.GetTop() + peep->SpriteData.SpriteRect.GetBottom()) / 2) - viewportCoords.y);
|
||||
auto screenCoords = Translate3DTo2DWithZ(rotation, peep->GetLocation());
|
||||
auto spriteRect = ScreenRect(
|
||||
screenCoords - ScreenCoordsXY{ peep->SpriteData.Width, peep->SpriteData.HeightMin },
|
||||
screenCoords + ScreenCoordsXY{ peep->SpriteData.Width, peep->SpriteData.HeightMax });
|
||||
|
||||
auto distance = abs(((spriteRect.GetLeft() + spriteRect.GetRight()) / 2) - viewportCoords.x)
|
||||
+ abs(((spriteRect.GetTop() + spriteRect.GetBottom()) / 2) - viewportCoords.y);
|
||||
if (distance > maxDistance)
|
||||
continue;
|
||||
|
||||
|
@ -754,9 +759,9 @@ static Peep* ViewportInteractionGetClosestPeep(ScreenCoordsXY screenCoords, int3
|
|||
|
||||
PeepDistance goal;
|
||||
if (!(viewport->flags & VIEWPORT_FLAG_HIDE_GUESTS))
|
||||
goal = GetClosestPeep<Guest>(viewportCoords, maxDistance, goal);
|
||||
goal = GetClosestPeep<Guest>(viewportCoords, viewport->rotation, maxDistance, goal);
|
||||
if (!(viewport->flags & VIEWPORT_FLAG_HIDE_STAFF))
|
||||
goal = GetClosestPeep<Staff>(viewportCoords, maxDistance, goal);
|
||||
goal = GetClosestPeep<Staff>(viewportCoords, viewport->rotation, maxDistance, goal);
|
||||
return goal.peep;
|
||||
}
|
||||
|
||||
|
@ -800,7 +805,7 @@ CoordsXY ViewportInteractionGetTileStartAtCursor(const ScreenCoordsXY& screenCoo
|
|||
{
|
||||
z = TileElementHeight(mapPos);
|
||||
}
|
||||
mapPos = ViewportPosToMapPos(initialVPPos, z);
|
||||
mapPos = ViewportPosToMapPos(initialVPPos, z, viewport->rotation);
|
||||
mapPos.x = std::clamp(mapPos.x, initialPos.x, initialPos.x + 31);
|
||||
mapPos.y = std::clamp(mapPos.y, initialPos.y, initialPos.y + 31);
|
||||
}
|
||||
|
|
|
@ -111,7 +111,12 @@ namespace OpenRCT2::Scripting
|
|||
|
||||
int32_t rotation_get() const
|
||||
{
|
||||
return GetCurrentRotation();
|
||||
auto viewport = GetViewport();
|
||||
if (viewport != nullptr)
|
||||
{
|
||||
return viewport->rotation;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void rotation_set(int32_t value)
|
||||
{
|
||||
|
@ -120,9 +125,9 @@ namespace OpenRCT2::Scripting
|
|||
auto w = GetWindow();
|
||||
if (w != nullptr)
|
||||
{
|
||||
while (GetCurrentRotation() != value)
|
||||
while (w->viewport->rotation != value)
|
||||
{
|
||||
WindowRotateCamera(*w, 1);
|
||||
ViewportRotateSingle(w, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +184,7 @@ namespace OpenRCT2::Scripting
|
|||
if (viewport != nullptr)
|
||||
{
|
||||
auto centre = viewport->viewPos + ScreenCoordsXY{ viewport->view_width / 2, viewport->view_height / 2 };
|
||||
auto coords = ViewportPosToMapPos(centre, 24);
|
||||
auto coords = ViewportPosToMapPos(centre, 24, viewport->rotation);
|
||||
|
||||
auto ctx = GetContext()->GetScriptEngine().GetContext();
|
||||
auto obj = duk_push_object(ctx);
|
||||
|
@ -203,7 +208,7 @@ namespace OpenRCT2::Scripting
|
|||
auto coords = GetCoordsFromObject(position);
|
||||
if (coords)
|
||||
{
|
||||
auto screenCoords = Translate3DTo2DWithZ(GetCurrentRotation(), *coords);
|
||||
auto screenCoords = Translate3DTo2DWithZ(viewport->rotation, *coords);
|
||||
auto left = screenCoords.x - (viewport->view_width / 2);
|
||||
auto top = screenCoords.y - (viewport->view_height / 2);
|
||||
SetViewLeftTop(left, top);
|
||||
|
|
|
@ -85,7 +85,7 @@ private:
|
|||
(viewportWidget->width()) - 1, (viewportWidget->height()) - 1, Focus(_bannerViewPos));
|
||||
|
||||
if (viewport != nullptr)
|
||||
viewport->flags = gConfigGeneral.AlwaysShowGridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
viewport->flags = gConfigGeneral.AlwaysShowGridlines ? VIEWPORT_FLAG_GRIDLINES : VIEWPORT_FLAG_NONE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ public:
|
|||
if (viewport != nullptr)
|
||||
{
|
||||
SetViewportFlags();
|
||||
viewport->rotation = 0;
|
||||
}
|
||||
gCurrentRotation = 0;
|
||||
gShowGridLinesRefCount = 0;
|
||||
gShowLandRightsRefCount = 0;
|
||||
gShowConstructionRightsRefCount = 0;
|
||||
|
|
|
@ -628,7 +628,7 @@ private:
|
|||
int32_t viewportFlags{};
|
||||
if (viewport == nullptr)
|
||||
{
|
||||
viewportFlags = gConfigGeneral.AlwaysShowGridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
viewportFlags = gConfigGeneral.AlwaysShowGridlines ? VIEWPORT_FLAG_GRIDLINES : VIEWPORT_FLAG_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2584,7 +2584,7 @@ private:
|
|||
TileElement tempSideTrackTileElement{ 0x80, 0x8F, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
TileElement tempTrackTileElement{};
|
||||
TileElement* backupTileElementArrays[5]{};
|
||||
PaintSession* session = PaintSessionAlloc(dpi, 0);
|
||||
PaintSession* session = PaintSessionAlloc(dpi, 0, GetCurrentRotation());
|
||||
trackDirection &= 3;
|
||||
|
||||
auto currentRide = GetRide(rideIndex);
|
||||
|
|
|
@ -137,7 +137,7 @@ public:
|
|||
this, windowPos + ScreenCoordsXY{ viewportWidget.left + 1, viewportWidget.top + 1 }, viewportWidget.width() - 1,
|
||||
viewportWidget.height() - 1, Focus(CoordsXYZ{ signViewPosition, viewZ }));
|
||||
|
||||
viewport->flags = gConfigGeneral.AlwaysShowGridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
viewport->flags = gConfigGeneral.AlwaysShowGridlines ? VIEWPORT_FLAG_GRIDLINES : VIEWPORT_FLAG_NONE;
|
||||
Invalidate();
|
||||
|
||||
return true;
|
||||
|
@ -315,7 +315,7 @@ public:
|
|||
this, windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 }, viewportWidget->width() - 1,
|
||||
viewportWidget->height() - 1, Focus(CoordsXYZ{ signViewPos }));
|
||||
if (viewport != nullptr)
|
||||
viewport->flags = gConfigGeneral.AlwaysShowGridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
viewport->flags = gConfigGeneral.AlwaysShowGridlines ? VIEWPORT_FLAG_GRIDLINES : VIEWPORT_FLAG_NONE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ enum WindowViewportWidgetIdx
|
|||
WIDX_ZOOM_IN,
|
||||
WIDX_ZOOM_OUT,
|
||||
WIDX_LOCATE,
|
||||
WIDX_ROTATE,
|
||||
};
|
||||
|
||||
#pragma region MEASUREMENTS
|
||||
|
@ -48,6 +49,7 @@ static Widget _viewportWidgets[] =
|
|||
MakeWidget({WW - 25, 17}, VIEWPORT_BUTTON, WindowWidgetType::FlatBtn, WindowColour::Primary , ImageId(SPR_G2_ZOOM_IN), STR_ZOOM_IN_TIP ), // zoom in
|
||||
MakeWidget({WW - 25, 41}, VIEWPORT_BUTTON, WindowWidgetType::FlatBtn, WindowColour::Primary , ImageId(SPR_G2_ZOOM_OUT), STR_ZOOM_OUT_TIP ), // zoom out
|
||||
MakeWidget({WW - 25, 65}, VIEWPORT_BUTTON, WindowWidgetType::FlatBtn, WindowColour::Primary , ImageId(SPR_LOCATE), STR_LOCATE_SUBJECT_TIP), // locate
|
||||
MakeWidget({WW - 25, 89}, VIEWPORT_BUTTON, WindowWidgetType::FlatBtn, WindowColour::Primary , ImageId(SPR_ROTATE_ARROW),STR_LOCATE_SUBJECT_TIP), // rotate
|
||||
WIDGETS_END,
|
||||
};
|
||||
|
||||
|
@ -93,7 +95,7 @@ public:
|
|||
savedViewPos = { x - (viewport->view_width / 2), y - (viewport->view_height / 2) };
|
||||
}
|
||||
|
||||
viewport->flags |= VIEWPORT_FLAG_SOUND_ON;
|
||||
viewport->flags |= VIEWPORT_FLAG_SOUND_ON | VIEWPORT_FLAG_INDEPEDENT_ROTATION;
|
||||
|
||||
min_width = WW;
|
||||
min_height = WH;
|
||||
|
@ -109,7 +111,7 @@ public:
|
|||
|
||||
if (viewport != nullptr && viewport->flags != mainWindow->viewport->flags)
|
||||
{
|
||||
viewport->flags = mainWindow->viewport->flags;
|
||||
viewport->flags = mainWindow->viewport->flags | VIEWPORT_FLAG_INDEPEDENT_ROTATION;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
@ -125,20 +127,25 @@ public:
|
|||
Close();
|
||||
break;
|
||||
case WIDX_ZOOM_IN:
|
||||
{
|
||||
if (viewport != nullptr && viewport->zoom > ZoomLevel::min())
|
||||
{
|
||||
viewport->zoom--;
|
||||
Invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WIDX_ZOOM_OUT:
|
||||
{
|
||||
if (viewport != nullptr && viewport->zoom < ZoomLevel::max())
|
||||
{
|
||||
viewport->zoom++;
|
||||
Invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WIDX_LOCATE:
|
||||
{
|
||||
auto* mainWindow = WindowGetMain();
|
||||
if (mainWindow != nullptr)
|
||||
{
|
||||
|
@ -147,6 +154,13 @@ public:
|
|||
WindowScrollToLocation(*mainWindow, { info.Loc, TileElementHeight(info.Loc) });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WIDX_ROTATE:
|
||||
{
|
||||
ViewportRotateSingle(this, 1);
|
||||
Invalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,6 +198,8 @@ public:
|
|||
widgets[WIDX_ZOOM_OUT].right = width - 2;
|
||||
widgets[WIDX_LOCATE].left = width - 27;
|
||||
widgets[WIDX_LOCATE].right = width - 2;
|
||||
widgets[WIDX_ROTATE].left = width - 27;
|
||||
widgets[WIDX_ROTATE].right = width - 2;
|
||||
widgets[WIDX_VIEWPORT].right = widgets[WIDX_ZOOM_IN].left - 1;
|
||||
widgets[WIDX_VIEWPORT].bottom = widgets[WIDX_BACKGROUND].bottom - 3;
|
||||
|
||||
|
|
|
@ -305,7 +305,7 @@ void LightFXPrepareLightList()
|
|||
dpi.zoom_level = _current_view_zoom_front;
|
||||
dpi.width = 1;
|
||||
|
||||
PaintSession* session = PaintSessionAlloc(dpi, w->viewport->flags);
|
||||
PaintSession* session = PaintSessionAlloc(dpi, w->viewport->flags, w->viewport->rotation);
|
||||
PaintSessionGenerate(*session);
|
||||
PaintSessionArrange(*session);
|
||||
auto info = SetInteractionInfoFromPaintSession(session, w->viewport->flags, ViewportInteractionItemAll);
|
||||
|
@ -437,7 +437,7 @@ void LightFXUpdateViewportSettings()
|
|||
Viewport* viewport = WindowGetViewport(mainWindow);
|
||||
_current_view_x_back = viewport->viewPos.x;
|
||||
_current_view_y_back = viewport->viewPos.y;
|
||||
_current_view_rotation_back = GetCurrentRotation();
|
||||
_current_view_rotation_back = viewport->rotation;
|
||||
_current_view_zoom_back = viewport->zoom;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ void EntityBase::Invalidate()
|
|||
break;
|
||||
}
|
||||
|
||||
ViewportsInvalidate(SpriteData.SpriteRect, maxZoom);
|
||||
ViewportsInvalidate(GetLocation(), SpriteData.Width, SpriteData.HeightMin, SpriteData.HeightMax, maxZoom);
|
||||
}
|
||||
|
||||
void EntityBase::Serialise(DataSerialiser& stream)
|
||||
|
|
|
@ -1165,15 +1165,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");
|
||||
}
|
||||
|
|
|
@ -498,7 +498,7 @@ int32_t CommandLineForScreenshot(const char** argv, int32_t argc, ScreenshotOpti
|
|||
auto zoom = ZoomLevel{ customZoom };
|
||||
auto rotation = std::atoi(argv[4]) & 3;
|
||||
viewport = GetGiantViewport(rotation, zoom);
|
||||
gCurrentRotation = rotation;
|
||||
viewport.rotation = rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -554,7 +554,7 @@ int32_t CommandLineForScreenshot(const char** argv, int32_t argc, ScreenshotOpti
|
|||
viewport.viewPos = { coords2d.x - ((viewport.view_width << customZoom) / 2),
|
||||
coords2d.y - ((viewport.view_height << customZoom) / 2) };
|
||||
viewport.zoom = ZoomLevel{ static_cast<int8_t>(customZoom) };
|
||||
gCurrentRotation = customRotation;
|
||||
viewport.rotation = customRotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -562,7 +562,7 @@ int32_t CommandLineForScreenshot(const char** argv, int32_t argc, ScreenshotOpti
|
|||
viewport.viewPos = { gameState.SavedView
|
||||
- ScreenCoordsXY{ (viewport.view_width / 2), (viewport.view_height / 2) } };
|
||||
viewport.zoom = gameState.SavedViewZoom;
|
||||
gCurrentRotation = gameState.SavedViewRotation;
|
||||
viewport.rotation = gameState.SavedViewRotation;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -656,8 +656,7 @@ void CaptureImage(const CaptureOptions& options)
|
|||
viewport = GetGiantViewport(options.Rotation, options.Zoom);
|
||||
}
|
||||
|
||||
auto backupRotation = gCurrentRotation;
|
||||
gCurrentRotation = options.Rotation;
|
||||
viewport.rotation = options.Rotation;
|
||||
|
||||
if (options.Transparent)
|
||||
{
|
||||
|
@ -669,6 +668,4 @@ void CaptureImage(const CaptureOptions& options)
|
|||
RenderViewport(nullptr, viewport, dpi);
|
||||
WriteDpiToFile(outputPath, dpi, gPalette);
|
||||
ReleaseDPI(dpi);
|
||||
|
||||
gCurrentRotation = backupRotation;
|
||||
}
|
||||
|
|
|
@ -65,8 +65,6 @@ Viewport* g_music_tracking_viewport;
|
|||
static std::unique_ptr<JobPool> _paintJobs;
|
||||
static std::vector<PaintSession*> _paintColumns;
|
||||
|
||||
uint8_t gCurrentRotation;
|
||||
|
||||
static uint32_t _currentImageType;
|
||||
InteractionInfo::InteractionInfo(const PaintStruct* ps)
|
||||
: Loc(ps->MapPos)
|
||||
|
@ -75,7 +73,9 @@ InteractionInfo::InteractionInfo(const PaintStruct* ps)
|
|||
, SpriteType(ps->InteractionItem)
|
||||
{
|
||||
}
|
||||
|
||||
static void ViewportPaintWeatherGloom(DrawPixelInfo& dpi);
|
||||
static void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi, const ScreenRect& screenRect);
|
||||
|
||||
/**
|
||||
* This is not a viewport function. It is used to setup many variables for
|
||||
|
@ -122,7 +122,7 @@ std::optional<ScreenCoordsXY> centre_2d_coordinates(const CoordsXYZ& loc, Viewpo
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto screenCoord = Translate3DTo2DWithZ(GetCurrentRotation(), loc);
|
||||
auto screenCoord = Translate3DTo2DWithZ(viewport->rotation, loc);
|
||||
screenCoord.x -= viewport->view_width / 2;
|
||||
screenCoord.y -= viewport->view_height / 2;
|
||||
return { screenCoord };
|
||||
|
@ -190,6 +190,7 @@ void ViewportCreate(WindowBase* w, const ScreenCoordsXY& screenCoords, int32_t w
|
|||
viewport->view_height = zoom.ApplyTo(height);
|
||||
viewport->zoom = zoom;
|
||||
viewport->flags = 0;
|
||||
viewport->rotation = GetCurrentRotation();
|
||||
|
||||
if (gConfigGeneral.AlwaysShowGridlines)
|
||||
viewport->flags |= VIEWPORT_FLAG_GRIDLINES;
|
||||
|
@ -227,6 +228,53 @@ void ViewportRemove(Viewport* viewport)
|
|||
_viewports.erase(it);
|
||||
}
|
||||
|
||||
Viewport* ViewportGetMain()
|
||||
{
|
||||
auto mainWindow = WindowGetMain();
|
||||
if (mainWindow == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return mainWindow->viewport;
|
||||
}
|
||||
|
||||
void ViewportsInvalidate(int32_t x, int32_t y, int32_t z0, int32_t z1, ZoomLevel maxZoom)
|
||||
{
|
||||
for (auto& vp : _viewports)
|
||||
{
|
||||
if (maxZoom == ZoomLevel{ -1 } || vp.zoom <= ZoomLevel{ maxZoom })
|
||||
{
|
||||
int32_t x1, y1, x2, y2;
|
||||
|
||||
x += 16;
|
||||
y += 16;
|
||||
auto screenCoord = Translate3DTo2DWithZ(vp.rotation, CoordsXYZ{ x, y, 0 });
|
||||
|
||||
x1 = screenCoord.x - 32;
|
||||
y1 = screenCoord.y - 32 - z1;
|
||||
x2 = screenCoord.x + 32;
|
||||
y2 = screenCoord.y + 32 - z0;
|
||||
|
||||
ViewportInvalidate(&vp, ScreenRect{ { x1, y1 }, { x2, y2 } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportsInvalidate(const CoordsXYZ& pos, int32_t width, int32_t minHeight, int32_t maxHeight, ZoomLevel maxZoom)
|
||||
{
|
||||
for (auto& vp : _viewports)
|
||||
{
|
||||
if (maxZoom == ZoomLevel{ -1 } || vp.zoom <= ZoomLevel{ maxZoom })
|
||||
{
|
||||
auto screenCoords = Translate3DTo2DWithZ(vp.rotation, pos);
|
||||
auto screenPos = ScreenRect(
|
||||
screenCoords - ScreenCoordsXY{ width, minHeight }, screenCoords + ScreenCoordsXY{ width, maxHeight });
|
||||
|
||||
ViewportInvalidate(&vp, screenPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportsInvalidate(const ScreenRect& screenRect, ZoomLevel maxZoom)
|
||||
{
|
||||
for (auto& vp : _viewports)
|
||||
|
@ -244,15 +292,14 @@ void ViewportsInvalidate(const ScreenRect& screenRect, ZoomLevel maxZoom)
|
|||
* edx is assumed to be (and always is) the current rotation, so it is not
|
||||
* needed as parameter.
|
||||
*/
|
||||
CoordsXYZ ViewportAdjustForMapHeight(const ScreenCoordsXY& startCoords)
|
||||
CoordsXYZ ViewportAdjustForMapHeight(const ScreenCoordsXY& startCoords, uint8_t rotation)
|
||||
{
|
||||
int32_t height = 0;
|
||||
|
||||
uint32_t rotation = GetCurrentRotation();
|
||||
CoordsXY pos{};
|
||||
for (int32_t i = 0; i < 6; i++)
|
||||
{
|
||||
pos = ViewportPosToMapPos(startCoords, height);
|
||||
pos = ViewportPosToMapPos(startCoords, height, rotation);
|
||||
height = TileElementHeight(pos);
|
||||
|
||||
// HACK: This is to prevent the x and y values being set to values outside
|
||||
|
@ -587,7 +634,7 @@ void ViewportUpdatePosition(WindowBase* window)
|
|||
auto viewportMidPoint = ScreenCoordsXY{ window->savedViewPos.x + viewport->view_width / 2,
|
||||
window->savedViewPos.y + viewport->view_height / 2 };
|
||||
|
||||
auto mapCoord = ViewportPosToMapPos(viewportMidPoint, 0);
|
||||
auto mapCoord = ViewportPosToMapPos(viewportMidPoint, 0, viewport->rotation);
|
||||
|
||||
// Clamp to the map minimum value
|
||||
int32_t at_map_edge = 0;
|
||||
|
@ -793,6 +840,65 @@ 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();
|
||||
w.OnViewportRotate();
|
||||
}
|
||||
|
||||
void ViewportRotateSingle(WindowBase* window, int32_t direction)
|
||||
{
|
||||
ViewportRotateSingleInternal(*window, direction);
|
||||
}
|
||||
|
||||
void ViewportRotateAll(int32_t direction)
|
||||
{
|
||||
WindowVisitEach([direction](WindowBase* w) {
|
||||
auto* viewport = w->viewport;
|
||||
if (viewport == nullptr)
|
||||
return;
|
||||
if (viewport->flags & VIEWPORT_FLAG_INDEPEDENT_ROTATION)
|
||||
return;
|
||||
ViewportRotateSingleInternal(*w, direction);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00685C02
|
||||
|
@ -891,7 +997,7 @@ static void ViewportPaintColumn(PaintSession& session)
|
|||
* edi: dpi
|
||||
* ebp: bottom
|
||||
*/
|
||||
void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi, const ScreenRect& screenRect)
|
||||
static void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi, const ScreenRect& screenRect)
|
||||
{
|
||||
PROFILED_FUNCTION();
|
||||
|
||||
|
@ -952,7 +1058,7 @@ void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi, const ScreenRec
|
|||
// Generate and sort columns.
|
||||
for (x = alignedX; x < rightBorder; x += 32)
|
||||
{
|
||||
PaintSession* session = PaintSessionAlloc(dpi1, viewFlags);
|
||||
PaintSession* session = PaintSessionAlloc(dpi1, viewFlags, viewport->rotation);
|
||||
_paintColumns.push_back(session);
|
||||
|
||||
DrawPixelInfo& dpi2 = session->DPI;
|
||||
|
@ -1091,11 +1197,11 @@ void Viewport::Invalidate() const
|
|||
ViewportInvalidate(this, { viewPos, viewPos + ScreenCoordsXY{ view_width, view_height } });
|
||||
}
|
||||
|
||||
CoordsXY ViewportPosToMapPos(const ScreenCoordsXY& coords, int32_t z)
|
||||
CoordsXY ViewportPosToMapPos(const ScreenCoordsXY& coords, int32_t z, uint8_t rotation)
|
||||
{
|
||||
// Reverse of Translate3DTo2DWithZ
|
||||
CoordsXY ret = { coords.y - coords.x / 2 + z, coords.y + coords.x / 2 + z };
|
||||
auto inverseRotation = DirectionFlipXAxis(GetCurrentRotation());
|
||||
auto inverseRotation = DirectionFlipXAxis(rotation);
|
||||
return ret.Rotate(inverseRotation);
|
||||
}
|
||||
|
||||
|
@ -1819,31 +1925,31 @@ InteractionInfo GetMapCoordinatesFromPosWindow(WindowBase* window, const ScreenC
|
|||
return info;
|
||||
}
|
||||
|
||||
Viewport* myviewport = window->viewport;
|
||||
Viewport* viewport = window->viewport;
|
||||
auto viewLoc = screenCoords;
|
||||
viewLoc -= myviewport->pos;
|
||||
if (viewLoc.x >= 0 && viewLoc.x < static_cast<int32_t>(myviewport->width) && viewLoc.y >= 0
|
||||
&& viewLoc.y < static_cast<int32_t>(myviewport->height))
|
||||
viewLoc -= viewport->pos;
|
||||
if (viewLoc.x >= 0 && viewLoc.x < static_cast<int32_t>(viewport->width) && viewLoc.y >= 0
|
||||
&& viewLoc.y < static_cast<int32_t>(viewport->height))
|
||||
{
|
||||
viewLoc.x = myviewport->zoom.ApplyTo(viewLoc.x);
|
||||
viewLoc.y = myviewport->zoom.ApplyTo(viewLoc.y);
|
||||
viewLoc += myviewport->viewPos;
|
||||
if (myviewport->zoom > ZoomLevel{ 0 })
|
||||
viewLoc.x = viewport->zoom.ApplyTo(viewLoc.x);
|
||||
viewLoc.y = viewport->zoom.ApplyTo(viewLoc.y);
|
||||
viewLoc += viewport->viewPos;
|
||||
if (viewport->zoom > ZoomLevel{ 0 })
|
||||
{
|
||||
viewLoc.x &= myviewport->zoom.ApplyTo(0xFFFFFFFF) & 0xFFFFFFFF;
|
||||
viewLoc.y &= myviewport->zoom.ApplyTo(0xFFFFFFFF) & 0xFFFFFFFF;
|
||||
viewLoc.x &= viewport->zoom.ApplyTo(0xFFFFFFFF) & 0xFFFFFFFF;
|
||||
viewLoc.y &= viewport->zoom.ApplyTo(0xFFFFFFFF) & 0xFFFFFFFF;
|
||||
}
|
||||
DrawPixelInfo dpi;
|
||||
dpi.x = viewLoc.x;
|
||||
dpi.y = viewLoc.y;
|
||||
dpi.height = 1;
|
||||
dpi.zoom_level = myviewport->zoom;
|
||||
dpi.zoom_level = viewport->zoom;
|
||||
dpi.width = 1;
|
||||
|
||||
PaintSession* session = PaintSessionAlloc(dpi, myviewport->flags);
|
||||
PaintSession* session = PaintSessionAlloc(dpi, viewport->flags, viewport->rotation);
|
||||
PaintSessionGenerate(*session);
|
||||
PaintSessionArrange(*session);
|
||||
info = SetInteractionInfoFromPaintSession(session, myviewport->flags, flags & 0xFFFF);
|
||||
info = SetInteractionInfoFromPaintSession(session, viewport->flags, flags & 0xFFFF);
|
||||
PaintSessionFree(session);
|
||||
}
|
||||
return info;
|
||||
|
@ -1944,7 +2050,7 @@ std::optional<CoordsXY> ScreenGetMapXY(const ScreenCoordsXY& screenCoords, Viewp
|
|||
for (int32_t i = 0; i < 5; i++)
|
||||
{
|
||||
int32_t z = TileElementHeight(cursorMapPos);
|
||||
cursorMapPos = ViewportPosToMapPos(start_vp_pos, z);
|
||||
cursorMapPos = ViewportPosToMapPos(start_vp_pos, z, myViewport->rotation);
|
||||
cursorMapPos.x = std::clamp(cursorMapPos.x, info.Loc.x, info.Loc.x + 31);
|
||||
cursorMapPos.y = std::clamp(cursorMapPos.y, info.Loc.y, info.Loc.y + 31);
|
||||
}
|
||||
|
@ -1968,7 +2074,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;
|
||||
|
@ -2043,7 +2149,13 @@ std::optional<CoordsXY> ScreenGetMapXYSideWithZ(const ScreenCoordsXY& screenCoor
|
|||
*/
|
||||
uint8_t GetCurrentRotation()
|
||||
{
|
||||
uint8_t rotation = gCurrentRotation;
|
||||
auto* viewport = ViewportGetMain();
|
||||
if (viewport == nullptr)
|
||||
{
|
||||
LOG_VERBOSE("No viewport found! Will return 0.");
|
||||
return 0;
|
||||
}
|
||||
uint8_t rotation = viewport->rotation;
|
||||
uint8_t rotation_masked = rotation & 3;
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (rotation != rotation_masked)
|
||||
|
@ -2081,7 +2193,7 @@ void ViewportSetSavedView()
|
|||
gameState.SavedView = ScreenCoordsXY{ viewport->view_width / 2, viewport->view_height / 2 } + viewport->viewPos;
|
||||
|
||||
gameState.SavedViewZoom = viewport->zoom;
|
||||
gameState.SavedViewRotation = GetCurrentRotation();
|
||||
gameState.SavedViewRotation = viewport->rotation;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,40 +28,44 @@ struct PaintEntry;
|
|||
|
||||
// Flags must currenly retain their values to avoid breaking plugins.
|
||||
// Values can be changed when plugins move to using named constants.
|
||||
enum
|
||||
enum : uint32_t
|
||||
{
|
||||
VIEWPORT_FLAG_GRIDLINES = (1 << 7),
|
||||
VIEWPORT_FLAG_UNDERGROUND_INSIDE = (1 << 0),
|
||||
VIEWPORT_FLAG_HIDE_BASE = (1 << 12),
|
||||
VIEWPORT_FLAG_HIDE_VERTICAL = (1 << 13),
|
||||
VIEWPORT_FLAG_NONE = 0U,
|
||||
|
||||
VIEWPORT_FLAG_SOUND_ON = (1 << 10),
|
||||
VIEWPORT_FLAG_LAND_OWNERSHIP = (1 << 8),
|
||||
VIEWPORT_FLAG_CONSTRUCTION_RIGHTS = (1 << 9),
|
||||
VIEWPORT_FLAG_HIDE_ENTITIES = (1 << 14),
|
||||
VIEWPORT_FLAG_CLIP_VIEW = (1 << 17),
|
||||
VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES = (1 << 18),
|
||||
VIEWPORT_FLAG_TRANSPARENT_BACKGROUND = (1 << 19),
|
||||
VIEWPORT_FLAG_GRIDLINES = (1U << 7),
|
||||
VIEWPORT_FLAG_UNDERGROUND_INSIDE = (1U << 0),
|
||||
VIEWPORT_FLAG_HIDE_BASE = (1U << 12),
|
||||
VIEWPORT_FLAG_HIDE_VERTICAL = (1U << 13),
|
||||
|
||||
VIEWPORT_FLAG_LAND_HEIGHTS = (1 << 4),
|
||||
VIEWPORT_FLAG_TRACK_HEIGHTS = (1 << 5),
|
||||
VIEWPORT_FLAG_PATH_HEIGHTS = (1 << 6),
|
||||
VIEWPORT_FLAG_SOUND_ON = (1U << 10),
|
||||
VIEWPORT_FLAG_LAND_OWNERSHIP = (1U << 8),
|
||||
VIEWPORT_FLAG_CONSTRUCTION_RIGHTS = (1U << 9),
|
||||
VIEWPORT_FLAG_HIDE_ENTITIES = (1U << 14),
|
||||
VIEWPORT_FLAG_CLIP_VIEW = (1U << 17),
|
||||
VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES = (1U << 18),
|
||||
VIEWPORT_FLAG_TRANSPARENT_BACKGROUND = (1U << 19),
|
||||
|
||||
VIEWPORT_FLAG_HIDE_RIDES = (1 << 1),
|
||||
VIEWPORT_FLAG_HIDE_VEHICLES = (1 << 20),
|
||||
VIEWPORT_FLAG_HIDE_VEGETATION = (1 << 21),
|
||||
VIEWPORT_FLAG_HIDE_SCENERY = (1 << 2),
|
||||
VIEWPORT_FLAG_HIDE_PATHS = (1 << 16),
|
||||
VIEWPORT_FLAG_HIDE_SUPPORTS = (1 << 3),
|
||||
VIEWPORT_FLAG_HIDE_GUESTS = (1 << 11),
|
||||
VIEWPORT_FLAG_HIDE_STAFF = (1 << 23),
|
||||
VIEWPORT_FLAG_LAND_HEIGHTS = (1U << 4),
|
||||
VIEWPORT_FLAG_TRACK_HEIGHTS = (1U << 5),
|
||||
VIEWPORT_FLAG_PATH_HEIGHTS = (1U << 6),
|
||||
|
||||
VIEWPORT_FLAG_INVISIBLE_RIDES = (1 << 24),
|
||||
VIEWPORT_FLAG_INVISIBLE_VEHICLES = (1 << 25),
|
||||
VIEWPORT_FLAG_INVISIBLE_VEGETATION = (1 << 26),
|
||||
VIEWPORT_FLAG_INVISIBLE_SCENERY = (1 << 27),
|
||||
VIEWPORT_FLAG_INVISIBLE_PATHS = (1 << 28),
|
||||
VIEWPORT_FLAG_INVISIBLE_SUPPORTS = (1 << 29),
|
||||
VIEWPORT_FLAG_HIDE_RIDES = (1U << 1),
|
||||
VIEWPORT_FLAG_HIDE_VEHICLES = (1U << 20),
|
||||
VIEWPORT_FLAG_HIDE_VEGETATION = (1U << 21),
|
||||
VIEWPORT_FLAG_HIDE_SCENERY = (1U << 2),
|
||||
VIEWPORT_FLAG_HIDE_PATHS = (1U << 16),
|
||||
VIEWPORT_FLAG_HIDE_SUPPORTS = (1U << 3),
|
||||
VIEWPORT_FLAG_HIDE_GUESTS = (1U << 11),
|
||||
VIEWPORT_FLAG_HIDE_STAFF = (1U << 23),
|
||||
|
||||
VIEWPORT_FLAG_INVISIBLE_RIDES = (1U << 24),
|
||||
VIEWPORT_FLAG_INVISIBLE_VEHICLES = (1U << 25),
|
||||
VIEWPORT_FLAG_INVISIBLE_VEGETATION = (1U << 26),
|
||||
VIEWPORT_FLAG_INVISIBLE_SCENERY = (1U << 27),
|
||||
VIEWPORT_FLAG_INVISIBLE_PATHS = (1U << 28),
|
||||
VIEWPORT_FLAG_INVISIBLE_SUPPORTS = (1U << 29),
|
||||
|
||||
VIEWPORT_FLAG_INDEPEDENT_ROTATION = (1U << 30),
|
||||
};
|
||||
|
||||
enum class VisibilityKind
|
||||
|
@ -123,12 +127,13 @@ extern uint8_t gShowConstructionRightsRefCount;
|
|||
// rct2: 0x014234BC
|
||||
extern Viewport* g_music_tracking_viewport;
|
||||
|
||||
extern uint8_t gCurrentRotation;
|
||||
|
||||
void ViewportInitAll();
|
||||
std::optional<ScreenCoordsXY> centre_2d_coordinates(const CoordsXYZ& loc, Viewport* viewport);
|
||||
void ViewportCreate(WindowBase* w, const ScreenCoordsXY& screenCoords, int32_t width, int32_t height, const Focus& focus);
|
||||
void ViewportRemove(Viewport* viewport);
|
||||
Viewport* ViewportGetMain();
|
||||
void ViewportsInvalidate(int32_t x, int32_t y, int32_t z0, int32_t z1, ZoomLevel maxZoom);
|
||||
void ViewportsInvalidate(const CoordsXYZ& pos, int32_t width, int32_t minHeight, int32_t maxHeight, ZoomLevel maxZoom);
|
||||
void ViewportsInvalidate(const ScreenRect& screenRect, ZoomLevel maxZoom = ZoomLevel{ -1 });
|
||||
void ViewportUpdatePosition(WindowBase* window);
|
||||
void ViewportUpdateFollowSprite(WindowBase* window);
|
||||
|
@ -136,12 +141,13 @@ 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);
|
||||
void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi, const ScreenRect& screenRect);
|
||||
|
||||
CoordsXYZ ViewportAdjustForMapHeight(const ScreenCoordsXY& startCoords);
|
||||
CoordsXYZ ViewportAdjustForMapHeight(const ScreenCoordsXY& startCoords, uint8_t rotation);
|
||||
|
||||
CoordsXY ViewportPosToMapPos(const ScreenCoordsXY& coords, int32_t z);
|
||||
CoordsXY ViewportPosToMapPos(const ScreenCoordsXY& coords, int32_t z, uint8_t rotation);
|
||||
std::optional<CoordsXY> ScreenPosToMapPos(const ScreenCoordsXY& screenCoords, int32_t* direction);
|
||||
|
||||
void ShowGridlines();
|
||||
|
|
|
@ -836,7 +836,7 @@ void WindowScrollToLocation(WindowBase& w, const CoordsXYZ& coords)
|
|||
}
|
||||
}
|
||||
|
||||
auto screenCoords = Translate3DTo2DWithZ(GetCurrentRotation(), coords);
|
||||
auto screenCoords = Translate3DTo2DWithZ(w.viewport->rotation, coords);
|
||||
|
||||
int32_t i = 0;
|
||||
if (!(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO))
|
||||
|
@ -889,66 +889,6 @@ void WindowScrollToLocation(WindowBase& w, const CoordsXYZ& coords)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00688956
|
||||
*/
|
||||
static void call_event_viewport_rotate_on_all_windows()
|
||||
{
|
||||
WindowVisitEach([](WindowBase* w) { w->OnViewportRotate(); });
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0068881A
|
||||
* direction can be used to alter the camera rotation:
|
||||
* 1: clockwise
|
||||
* -1: anti-clockwise
|
||||
*/
|
||||
void WindowRotateCamera(WindowBase& w, int32_t direction)
|
||||
{
|
||||
Viewport* 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
coords.x = mapXYCoords->x;
|
||||
coords.y = mapXYCoords->y;
|
||||
coords.z = TileElementHeight(coords);
|
||||
}
|
||||
|
||||
gCurrentRotation = (GetCurrentRotation() + direction) & 3;
|
||||
|
||||
auto centreLoc = centre_2d_coordinates(coords, viewport);
|
||||
|
||||
if (centreLoc.has_value())
|
||||
{
|
||||
w.savedViewPos = centreLoc.value();
|
||||
viewport->viewPos = *centreLoc;
|
||||
}
|
||||
|
||||
w.Invalidate();
|
||||
|
||||
call_event_viewport_rotate_on_all_windows();
|
||||
ResetAllSpriteQuadrantPlacements();
|
||||
}
|
||||
|
||||
void WindowViewportGetMapCoordsByCursor(
|
||||
const WindowBase& w, int32_t* map_x, int32_t* map_y, int32_t* offset_x, int32_t* offset_y)
|
||||
{
|
||||
|
@ -957,8 +897,8 @@ void WindowViewportGetMapCoordsByCursor(
|
|||
|
||||
// Compute map coordinate by mouse position.
|
||||
auto viewportPos = w.viewport->ScreenToViewportCoord(mouseCoords);
|
||||
auto coordsXYZ = ViewportAdjustForMapHeight(viewportPos);
|
||||
auto mapCoords = ViewportPosToMapPos(viewportPos, coordsXYZ.z);
|
||||
auto coordsXYZ = ViewportAdjustForMapHeight(viewportPos, w.viewport->rotation);
|
||||
auto mapCoords = ViewportPosToMapPos(viewportPos, coordsXYZ.z, w.viewport->rotation);
|
||||
*map_x = mapCoords.x;
|
||||
*map_y = mapCoords.y;
|
||||
|
||||
|
|
|
@ -148,16 +148,16 @@ struct Widget
|
|||
*/
|
||||
struct Viewport
|
||||
{
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
ScreenCoordsXY pos;
|
||||
ScreenCoordsXY viewPos;
|
||||
int32_t view_width;
|
||||
int32_t view_height;
|
||||
uint32_t flags;
|
||||
ZoomLevel zoom;
|
||||
uint8_t var_11;
|
||||
VisibilityCache visibility;
|
||||
int32_t width{};
|
||||
int32_t height{};
|
||||
ScreenCoordsXY pos{};
|
||||
ScreenCoordsXY viewPos{};
|
||||
int32_t view_width{};
|
||||
int32_t view_height{};
|
||||
uint32_t flags{};
|
||||
ZoomLevel zoom{};
|
||||
uint8_t rotation{};
|
||||
VisibilityCache visibility{};
|
||||
|
||||
// Use this function on coordinates that are relative to the viewport zoom i.e. a peeps x, y position after transforming
|
||||
// from its x, y, z
|
||||
|
@ -579,7 +579,6 @@ void WindowPushOthersBelow(WindowBase& w1);
|
|||
WindowBase* WindowGetMain();
|
||||
|
||||
void WindowScrollToLocation(WindowBase& w, const CoordsXYZ& coords);
|
||||
void WindowRotateCamera(WindowBase& w, int32_t direction);
|
||||
void WindowViewportGetMapCoordsByCursor(
|
||||
const WindowBase& w, int32_t* map_x, int32_t* map_y, int32_t* offset_x, int32_t* offset_y);
|
||||
void WindowViewportCentreTileAroundCursor(WindowBase& w, int32_t map_x, int32_t map_y, int32_t offset_x, int32_t offset_y);
|
||||
|
|
|
@ -94,10 +94,13 @@ void EntityPaintSetup(PaintSession& session, const CoordsXY& pos)
|
|||
}
|
||||
}
|
||||
|
||||
if (session.DPI.y + session.DPI.height <= spr->SpriteData.SpriteRect.GetTop()
|
||||
|| spr->SpriteData.SpriteRect.GetBottom() <= session.DPI.y
|
||||
|| session.DPI.x + session.DPI.width <= spr->SpriteData.SpriteRect.GetLeft()
|
||||
|| spr->SpriteData.SpriteRect.GetRight() <= session.DPI.x)
|
||||
auto screenCoords = Translate3DTo2DWithZ(session.CurrentRotation, spr->GetLocation());
|
||||
auto spriteRect = ScreenRect(
|
||||
screenCoords - ScreenCoordsXY{ spr->SpriteData.Width, spr->SpriteData.HeightMin },
|
||||
screenCoords + ScreenCoordsXY{ spr->SpriteData.Width, spr->SpriteData.HeightMax });
|
||||
|
||||
if (session.DPI.y + session.DPI.height <= spriteRect.GetTop() || spriteRect.GetBottom() <= session.DPI.y
|
||||
|| session.DPI.x + session.DPI.width <= spriteRect.GetLeft() || spriteRect.GetRight() <= session.DPI.x)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ bool gPaintBoundingBoxes;
|
|||
bool gPaintBlockedTiles;
|
||||
|
||||
static void PaintAttachedPS(DrawPixelInfo& dpi, PaintStruct* ps, uint32_t viewFlags);
|
||||
static void PaintPSImageWithBoundingBoxes(DrawPixelInfo& dpi, PaintStruct* ps, ImageId imageId, int32_t x, int32_t y);
|
||||
static void PaintPSImageWithBoundingBoxes(PaintSession& session, PaintStruct* ps, ImageId imageId, int32_t x, int32_t y);
|
||||
static ImageId PaintPSColourifyImage(const PaintStruct* ps, ImageId imageId, uint32_t viewFlags);
|
||||
|
||||
static int32_t RemapPositionToQuadrant(const PaintStruct& ps, uint8_t rotation)
|
||||
|
@ -243,7 +243,6 @@ template<uint8_t direction> void PaintSessionGenerateRotate(PaintSession& sessio
|
|||
*/
|
||||
void PaintSessionGenerate(PaintSession& session)
|
||||
{
|
||||
session.CurrentRotation = GetCurrentRotation();
|
||||
switch (DirectionFlipXAxis(session.CurrentRotation))
|
||||
{
|
||||
case 0:
|
||||
|
@ -533,7 +532,7 @@ static void PaintDrawStruct(PaintSession& session, PaintStruct* ps)
|
|||
auto imageId = PaintPSColourifyImage(ps, ps->image_id, session.ViewFlags);
|
||||
if (gPaintBoundingBoxes && session.DPI.zoom_level == ZoomLevel{ 0 })
|
||||
{
|
||||
PaintPSImageWithBoundingBoxes(session.DPI, ps, imageId, screenPos.x, screenPos.y);
|
||||
PaintPSImageWithBoundingBoxes(session, ps, imageId, screenPos.x, screenPos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -588,10 +587,12 @@ static void PaintAttachedPS(DrawPixelInfo& dpi, PaintStruct* ps, uint32_t viewFl
|
|||
}
|
||||
}
|
||||
|
||||
static void PaintPSImageWithBoundingBoxes(DrawPixelInfo& dpi, PaintStruct* ps, ImageId imageId, int32_t x, int32_t y)
|
||||
static void PaintPSImageWithBoundingBoxes(PaintSession& session, PaintStruct* ps, ImageId imageId, int32_t x, int32_t y)
|
||||
{
|
||||
auto& dpi = session.DPI;
|
||||
|
||||
const uint8_t colour = BoundBoxDebugColours[EnumValue(ps->InteractionItem)];
|
||||
const uint8_t rotation = GetCurrentRotation();
|
||||
const uint8_t rotation = session.CurrentRotation;
|
||||
|
||||
const CoordsXYZ frontTop = {
|
||||
ps->Bounds.x_end,
|
||||
|
@ -688,9 +689,9 @@ static ImageId PaintPSColourifyImage(const PaintStruct* ps, ImageId imageId, uin
|
|||
}
|
||||
}
|
||||
|
||||
PaintSession* PaintSessionAlloc(DrawPixelInfo& dpi, uint32_t viewFlags)
|
||||
PaintSession* PaintSessionAlloc(DrawPixelInfo& dpi, uint32_t viewFlags, uint8_t rotation)
|
||||
{
|
||||
return GetContext()->GetPainter()->CreateSession(dpi, viewFlags);
|
||||
return GetContext()->GetPainter()->CreateSession(dpi, viewFlags, rotation);
|
||||
}
|
||||
|
||||
void PaintSessionFree(PaintSession* session)
|
||||
|
|
|
@ -338,7 +338,7 @@ void PaintFloatingMoneyEffect(
|
|||
PaintSession& session, money64 amount, StringId string_id, int32_t y, int32_t z, int8_t y_offsets[], int32_t offset_x,
|
||||
uint32_t rotation);
|
||||
|
||||
PaintSession* PaintSessionAlloc(DrawPixelInfo& dpi, uint32_t viewFlags);
|
||||
PaintSession* PaintSessionAlloc(DrawPixelInfo& dpi, uint32_t viewFlags, uint8_t rotation);
|
||||
void PaintSessionFree(PaintSession* session);
|
||||
void PaintSessionGenerate(PaintSession& session);
|
||||
void PaintSessionArrange(PaintSessionCore& session);
|
||||
|
|
|
@ -133,7 +133,7 @@ void Painter::MeasureFPS()
|
|||
_lastSecond = currentTime;
|
||||
}
|
||||
|
||||
PaintSession* Painter::CreateSession(DrawPixelInfo& dpi, uint32_t viewFlags)
|
||||
PaintSession* Painter::CreateSession(DrawPixelInfo& dpi, uint32_t viewFlags, uint8_t rotation)
|
||||
{
|
||||
PROFILED_FUNCTION();
|
||||
|
||||
|
@ -160,6 +160,7 @@ PaintSession* Painter::CreateSession(DrawPixelInfo& dpi, uint32_t viewFlags)
|
|||
session->QuadrantFrontIndex = 0;
|
||||
session->PaintEntryChain = _paintStructPool.Create();
|
||||
session->Flags = 0;
|
||||
session->CurrentRotation = rotation;
|
||||
|
||||
std::fill(std::begin(session->Quadrants), std::end(session->Quadrants), nullptr);
|
||||
session->PaintHead = nullptr;
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace OpenRCT2
|
|||
explicit Painter(const std::shared_ptr<Ui::IUiContext>& uiContext);
|
||||
void Paint(Drawing::IDrawingEngine& de);
|
||||
|
||||
PaintSession* CreateSession(DrawPixelInfo& dpi, uint32_t viewFlags);
|
||||
PaintSession* CreateSession(DrawPixelInfo& dpi, uint32_t viewFlags, uint8_t rotation);
|
||||
void ReleaseSession(PaintSession* session);
|
||||
~Painter();
|
||||
|
||||
|
|
|
@ -2081,10 +2081,9 @@ void TrackDesignDrawPreview(TrackDesign* td6, uint8_t* pixels)
|
|||
const ScreenCoordsXY offset = { size_x / 2, size_y / 2 };
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
{
|
||||
gCurrentRotation = i;
|
||||
|
||||
view.viewPos = Translate3DTo2DWithZ(i, centre) - offset;
|
||||
ViewportPaint(&view, dpi, { view.viewPos, view.viewPos + ScreenCoordsXY{ size_x, size_y } });
|
||||
view.rotation = i;
|
||||
ViewportRender(dpi, &view, { {}, ScreenCoordsXY{ size_x, size_y } });
|
||||
|
||||
dpi.bits += TRACK_PREVIEW_IMAGE_SIZE;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -289,7 +289,7 @@ CoordsXY FootpathGetCoordinatesFromPos(const ScreenCoordsXY& screenCoords, int32
|
|||
{
|
||||
z = TileElementHeight(position);
|
||||
}
|
||||
position = ViewportPosToMapPos(start_vp_pos, z);
|
||||
position = ViewportPosToMapPos(start_vp_pos, z, viewport->rotation);
|
||||
position.x = std::clamp(position.x, minPosition.x, maxPosition.x);
|
||||
position.y = std::clamp(position.y, minPosition.y, maxPosition.y);
|
||||
}
|
||||
|
|
|
@ -111,7 +111,6 @@ static std::vector<TileElement> _tileElementsStash;
|
|||
static size_t _tileElementsInUse;
|
||||
static size_t _tileElementsInUseStash;
|
||||
static TileCoordsXY _mapSizeStash;
|
||||
static int32_t _currentRotationStash;
|
||||
|
||||
void StashMap()
|
||||
{
|
||||
|
@ -119,7 +118,6 @@ void StashMap()
|
|||
_tileIndexStash = std::move(_tileIndex);
|
||||
_tileElementsStash = std::move(gameState.TileElements);
|
||||
_mapSizeStash = GetGameState().MapSize;
|
||||
_currentRotationStash = gCurrentRotation;
|
||||
_tileElementsInUseStash = _tileElementsInUse;
|
||||
}
|
||||
|
||||
|
@ -129,7 +127,6 @@ void UnstashMap()
|
|||
_tileIndex = std::move(_tileIndexStash);
|
||||
gameState.TileElements = std::move(_tileElementsStash);
|
||||
GetGameState().MapSize = _mapSizeStash;
|
||||
gCurrentRotation = _currentRotationStash;
|
||||
_tileElementsInUse = _tileElementsInUseStash;
|
||||
}
|
||||
|
||||
|
@ -1797,18 +1794,7 @@ static void MapInvalidateTileUnderZoom(int32_t x, int32_t y, int32_t z0, int32_t
|
|||
if (gOpenRCT2Headless)
|
||||
return;
|
||||
|
||||
int32_t x1, y1, x2, y2;
|
||||
|
||||
x += 16;
|
||||
y += 16;
|
||||
auto screenCoord = Translate3DTo2D(GetCurrentRotation(), { x, y });
|
||||
|
||||
x1 = screenCoord.x - 32;
|
||||
y1 = screenCoord.y - 32 - z1;
|
||||
x2 = screenCoord.x + 32;
|
||||
y2 = screenCoord.y + 32 - z0;
|
||||
|
||||
ViewportsInvalidate({ { x1, y1 }, { x2, y2 } }, maxZoom);
|
||||
ViewportsInvalidate(x, y, z0, z1, maxZoom);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue