diff --git a/src/openrct2-ui/WindowManager.cpp b/src/openrct2-ui/WindowManager.cpp index 1e640a268b..48ee350982 100644 --- a/src/openrct2-ui/WindowManager.cpp +++ b/src/openrct2-ui/WindowManager.cpp @@ -561,8 +561,8 @@ public: if (zoomDifference != ZoomLevel{ 0 }) { - viewport->view_width = viewport->view_width * zoomDifference; - viewport->view_height = viewport->view_height * zoomDifference; + viewport->view_width = zoomDifference.ApplyTo(viewport->view_width); + viewport->view_height = zoomDifference.ApplyTo(viewport->view_height); } mainWindow->savedViewPos.x -= viewport->view_width >> 1; mainWindow->savedViewPos.y -= viewport->view_height >> 1; diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index d6a704fc60..dea02f6809 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -622,7 +622,7 @@ void OpenGLDrawingContext::DrawSprite(rct_drawpixelinfo* dpi, ImageId imageId, i int32_t zoom_mask; if (dpi->zoom_level >= ZoomLevel{ 0 }) - zoom_mask = 0xFFFFFFFF * dpi->zoom_level; + zoom_mask = dpi->zoom_level.ApplyTo(0xFFFFFFFF); else zoom_mask = 0xFFFFFFFF; if (dpi->zoom_level != ZoomLevel{ 0 } && (g1Element->flags & G1_FLAG_RLE_COMPRESSION)) @@ -660,10 +660,10 @@ void OpenGLDrawingContext::DrawSprite(rct_drawpixelinfo* dpi, ImageId imageId, i right -= dpi->x; bottom -= dpi->y; - left = left / dpi->zoom_level; - top = top / dpi->zoom_level; - right = right / dpi->zoom_level; - bottom = bottom / dpi->zoom_level; + left = dpi->zoom_level.ApplyInversedTo(left); + top = dpi->zoom_level.ApplyInversedTo(top); + right = dpi->zoom_level.ApplyInversedTo(right); + bottom = dpi->zoom_level.ApplyInversedTo(bottom); left += _spriteOffset.x; top += _spriteOffset.y; @@ -775,10 +775,10 @@ void OpenGLDrawingContext::DrawSpriteRawMasked( right -= dpi->x; bottom -= dpi->y; - left = left / dpi->zoom_level; - top = top / dpi->zoom_level; - right = right / dpi->zoom_level; - bottom = bottom / dpi->zoom_level; + left = dpi->zoom_level.ApplyInversedTo(left); + top = dpi->zoom_level.ApplyInversedTo(top); + right = dpi->zoom_level.ApplyInversedTo(right); + bottom = dpi->zoom_level.ApplyInversedTo(bottom); left += _spriteOffset.x; top += _spriteOffset.y; @@ -882,10 +882,10 @@ void OpenGLDrawingContext::DrawGlyph(rct_drawpixelinfo* dpi, uint32_t image, int right -= dpi->x; bottom -= dpi->y; - left = left / dpi->zoom_level; - top = top / dpi->zoom_level; - right = right / dpi->zoom_level; - bottom = bottom / dpi->zoom_level; + left = dpi->zoom_level.ApplyInversedTo(left); + top = dpi->zoom_level.ApplyInversedTo(top); + right = dpi->zoom_level.ApplyInversedTo(right); + bottom = dpi->zoom_level.ApplyInversedTo(bottom); left += _spriteOffset.x; top += _spriteOffset.y; @@ -1039,8 +1039,8 @@ void OpenGLDrawingContext::CalculcateClipping(rct_drawpixelinfo* dpi) _clipLeft = static_cast(bitsOffset % bytesPerRow) + dpi->remX; _clipTop = static_cast(bitsOffset / bytesPerRow) + dpi->remY; - _clipRight = _clipLeft + (dpi->width / dpi->zoom_level); - _clipBottom = _clipTop + (dpi->height / dpi->zoom_level); + _clipRight = _clipLeft + dpi->zoom_level.ApplyInversedTo(dpi->width); + _clipBottom = _clipTop + dpi->zoom_level.ApplyInversedTo(dpi->height); _offsetX = _clipLeft - dpi->x; _offsetY = _clipTop - dpi->y; _spriteOffset.x = _clipLeft - dpi->remX; diff --git a/src/openrct2-ui/input/MouseInput.cpp b/src/openrct2-ui/input/MouseInput.cpp index 9cdda62427..f1f7c3bd32 100644 --- a/src/openrct2-ui/input/MouseInput.cpp +++ b/src/openrct2-ui/input/MouseInput.cpp @@ -570,8 +570,8 @@ static void InputViewportDragContinue() // As the user moved the mouse, don't interpret it as right click in any case. _ticksSinceDragStart = 1000; - differentialCoords.x = differentialCoords.x * (viewport->zoom + 1); - differentialCoords.y = differentialCoords.y * (viewport->zoom + 1); + differentialCoords.x = (viewport->zoom + 1).ApplyTo(differentialCoords.x); + differentialCoords.y = (viewport->zoom + 1).ApplyTo(differentialCoords.y); if (gConfigGeneral.invert_viewport_drag) { w->savedViewPos -= differentialCoords; @@ -1590,7 +1590,7 @@ void InputScrollViewport(const ScreenCoordsXY& scrollScreenCoords) const int32_t speed = gConfigGeneral.edge_scrolling_speed; - int32_t multiplier = speed * viewport->zoom; + int32_t multiplier = viewport->zoom.ApplyTo(speed); int32_t dx = scrollScreenCoords.x * multiplier; int32_t dy = scrollScreenCoords.y * multiplier; diff --git a/src/openrct2-ui/scripting/CustomWindow.cpp b/src/openrct2-ui/scripting/CustomWindow.cpp index ceb04cf8e6..739072f9ad 100644 --- a/src/openrct2-ui/scripting/CustomWindow.cpp +++ b/src/openrct2-ui/scripting/CustomWindow.cpp @@ -801,8 +801,8 @@ namespace OpenRCT2::Ui::Windows viewport->pos.y = top; viewport->width = wwidth; viewport->height = wheight; - viewport->view_width = wwidth * viewport->zoom; - viewport->view_height = wheight * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(wwidth); + viewport->view_height = viewport->zoom.ApplyTo(wheight); Invalidate(); } } diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 6f3ba80e09..99468c85d6 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -476,8 +476,8 @@ void WindowGuestOverviewResize(rct_window* w) { viewport->width = reqViewportWidth; viewport->height = reqViewportHeight; - viewport->view_width = viewport->width / viewport->zoom; - viewport->view_height = viewport->height / viewport->zoom; + viewport->view_width = viewport->zoom.ApplyInversedTo(viewport->width); + viewport->view_height = viewport->zoom.ApplyInversedTo(viewport->height); } } WindowGuestViewportInit(w); diff --git a/src/openrct2-ui/windows/Player.cpp b/src/openrct2-ui/windows/Player.cpp index e5950a8e99..843deb62a2 100644 --- a/src/openrct2-ui/windows/Player.cpp +++ b/src/openrct2-ui/windows/Player.cpp @@ -410,8 +410,8 @@ void WindowPlayerOverviewInvalidate(rct_window* w) viewport->pos = w->windowPos + ScreenCoordsXY{ viewportWidget->left, viewportWidget->top }; viewport->width = viewportWidget->width(); viewport->height = viewportWidget->height(); - viewport->view_width = viewport->width * viewport->zoom; - viewport->view_height = viewport->height * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(viewport->width); + viewport->view_height = viewport->zoom.ApplyTo(viewport->height); } // Only enable kick button for other players diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 6cfdd0d647..7b39e0a3d7 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -1861,14 +1861,14 @@ static std::optional RideGetPlacePositionFromScreenPosition(ScreenCoor { if (gInputPlaceObjectModifier & PLACE_OBJECT_MODIFIER_SHIFT_Z) { - uint16_t maxHeight = (std::numeric_limits::max() - 32) * ZoomLevel::max(); + uint16_t maxHeight = ZoomLevel::max().ApplyTo(std::numeric_limits::max() - 32); _trackPlaceShiftZ = _trackPlaceShiftStart.y - screenCoords.y + 4; // Scale delta by zoom to match mouse position. auto* mainWnd = window_get_main(); if (mainWnd != nullptr && mainWnd->viewport != nullptr) { - _trackPlaceShiftZ = _trackPlaceShiftZ * mainWnd->viewport->zoom; + _trackPlaceShiftZ = mainWnd->viewport->zoom.ApplyTo(_trackPlaceShiftZ); } _trackPlaceShiftZ = floor2(_trackPlaceShiftZ, 8); diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index 6d22bf1c4b..73d7166c38 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -465,8 +465,8 @@ void WindowStaffOverviewResize(rct_window* w) { viewport->width = new_width; viewport->height = new_height; - viewport->view_width = new_width * viewport->zoom; - viewport->view_height = new_height * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(new_width); + viewport->view_height = viewport->zoom.ApplyTo(new_height); } } diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 7b544ecaaf..650aa20f1e 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1235,7 +1235,7 @@ static void Sub6E1F34UpdateScreenCoordsAndButtonsPressed(bool canRaiseItem, Scre auto* mainWnd = window_get_main(); if (mainWnd != nullptr && mainWnd->viewport != nullptr) { - gSceneryShiftPressZOffset = gSceneryShiftPressZOffset * mainWnd->viewport->zoom; + gSceneryShiftPressZOffset = mainWnd->viewport->zoom.ApplyTo(gSceneryShiftPressZOffset); } gSceneryShiftPressZOffset = floor2(gSceneryShiftPressZOffset, 8); @@ -1264,7 +1264,7 @@ static void Sub6E1F34SmallScenery( } auto screenPos = sourceScreenPos; - uint16_t maxPossibleHeight = (std::numeric_limits::max() - 32) * ZoomLevel::max(); + uint16_t maxPossibleHeight = ZoomLevel::max().ApplyTo(std::numeric_limits::max() - 32); bool can_raise_item = false; const auto* sceneryEntry = get_small_scenery_entry(sceneryIndex); @@ -1493,7 +1493,7 @@ static void Sub6E1F34Wall( } auto screenPos = sourceScreenPos; - uint16_t maxPossibleHeight = (std::numeric_limits::max() - 32) * ZoomLevel::max(); + uint16_t maxPossibleHeight = ZoomLevel::max().ApplyTo(std::numeric_limits::max() - 32); auto* wallEntry = get_wall_entry(sceneryIndex); if (wallEntry != nullptr) @@ -1582,7 +1582,7 @@ static void Sub6E1F34LargeScenery( } auto screenPos = sourceScreenPos; - uint16_t maxPossibleHeight = (std::numeric_limits::max() - 32) * ZoomLevel::max(); + uint16_t maxPossibleHeight = ZoomLevel::max().ApplyTo(std::numeric_limits::max() - 32); auto* sceneryEntry = get_large_scenery_entry(sceneryIndex); if (sceneryEntry) @@ -3098,7 +3098,7 @@ static void WindowTopToolbarLandToolDrag(const ScreenCoordsXY& screenPos) if (viewport == nullptr) return; - int16_t tile_height = -16 / viewport->zoom; + int16_t tile_height = viewport->zoom.ApplyInversedTo(-16); int32_t y_diff = screenPos.y - gInputDragLast.y; @@ -3141,7 +3141,7 @@ static void WindowTopToolbarWaterToolDrag(const ScreenCoordsXY& screenPos) if (viewport == nullptr) return; - int16_t dx = -16 / viewport->zoom; + int16_t dx = viewport->zoom.ApplyInversedTo(-16); auto offsetPos = screenPos - ScreenCoordsXY{ 0, gInputDragLast.y }; diff --git a/src/openrct2-ui/windows/Viewport.cpp b/src/openrct2-ui/windows/Viewport.cpp index 5e20d060fd..59c0224bec 100644 --- a/src/openrct2-ui/windows/Viewport.cpp +++ b/src/openrct2-ui/windows/Viewport.cpp @@ -208,8 +208,8 @@ public: viewport->pos = windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 }; viewport->width = widgets[WIDX_VIEWPORT].width() - 1; viewport->height = widgets[WIDX_VIEWPORT].height() - 1; - viewport->view_width = viewport->width * viewport->zoom; - viewport->view_height = viewport->height * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(viewport->width); + viewport->view_height = viewport->zoom.ApplyTo(viewport->height); } } }; diff --git a/src/openrct2/audio/Audio.cpp b/src/openrct2/audio/Audio.cpp index b3e0a30ed2..8b9abcaa69 100644 --- a/src/openrct2/audio/Audio.cpp +++ b/src/openrct2/audio/Audio.cpp @@ -221,9 +221,9 @@ namespace OpenRCT2::Audio if (viewport->flags & VIEWPORT_FLAG_SOUND_ON) { int16_t vx = pos2.x - viewport->viewPos.x; - params.pan = viewport->pos.x + (vx / viewport->zoom); + params.pan = viewport->pos.x + viewport->zoom.ApplyInversedTo(vx); params.volume = SoundVolumeAdjust[static_cast(soundId)] - + ((-1024 * viewport->zoom - 1) * (1 << volumeDown)) + 1; + + ((viewport->zoom.ApplyTo(-1024) - 1) * (1 << volumeDown)) + 1; if (!viewport->Contains(pos2) || params.volume < -10000) { diff --git a/src/openrct2/drawing/Drawing.Sprite.BMP.cpp b/src/openrct2/drawing/Drawing.Sprite.BMP.cpp index c90c08c32d..24aaeddf2b 100644 --- a/src/openrct2/drawing/Drawing.Sprite.BMP.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.BMP.cpp @@ -17,10 +17,10 @@ template static void FASTCALL DrawBMPSpriteMagnify(rct_dra auto& paletteMap = args.PalMap; auto zoomLevel = dpi.zoom_level; size_t srcLineWidth = g1.width; - size_t dstLineWidth = (static_cast(dpi.width) / zoomLevel) + dpi.pitch; - uint8_t zoom = 1 / zoomLevel; - auto width = args.Width / zoomLevel; - auto height = args.Height / zoomLevel; + size_t dstLineWidth = zoomLevel.ApplyInversedTo(dpi.width) + dpi.pitch; + uint8_t zoom = zoomLevel.ApplyInversedTo(1); + auto width = zoomLevel.ApplyInversedTo(args.Width); + auto height = zoomLevel.ApplyInversedTo(args.Height); for (; height > 0; height -= zoom) { auto nextSrc = src + srcLineWidth; @@ -44,9 +44,9 @@ template static void FASTCALL DrawBMPSpriteMinify(rct_draw auto width = args.Width; auto height = args.Height; auto zoomLevel = dpi.zoom_level; - size_t srcLineWidth = g1.width * zoomLevel; - size_t dstLineWidth = (static_cast(dpi.width) / zoomLevel) + dpi.pitch; - uint8_t zoom = 1 * zoomLevel; + size_t srcLineWidth = zoomLevel.ApplyTo(g1.width); + size_t dstLineWidth = zoomLevel.ApplyInversedTo(static_cast(dpi.width)) + dpi.pitch; + uint8_t zoom = zoomLevel.ApplyTo(1); for (; height > 0; height -= zoom) { auto nextSrc = src + srcLineWidth; diff --git a/src/openrct2/drawing/Drawing.Sprite.cpp b/src/openrct2/drawing/Drawing.Sprite.cpp index 3a4d0897e6..3be02bb489 100644 --- a/src/openrct2/drawing/Drawing.Sprite.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.cpp @@ -460,7 +460,7 @@ void FASTCALL gfx_draw_sprite_palette_set_software( // Its used super often so we will define it to a separate variable. const auto zoom_level = dpi->zoom_level; - const int32_t zoom_mask = zoom_level > ZoomLevel{ 0 } ? 0xFFFFFFFF * zoom_level : 0xFFFFFFFF; + const int32_t zoom_mask = zoom_level > ZoomLevel{ 0 } ? zoom_level.ApplyTo(0xFFFFFFFF) : 0xFFFFFFFF; if (zoom_level > ZoomLevel{ 0 } && g1->flags & G1_FLAG_RLE_COMPRESSION) { @@ -523,7 +523,7 @@ void FASTCALL gfx_draw_sprite_palette_set_software( if (height <= 0) return; - dest_start_y = dest_start_y / zoom_level; + dest_start_y = zoom_level.ApplyInversedTo(dest_start_y); // This will be the width of the drawn image int32_t width = g1->width; @@ -568,11 +568,11 @@ void FASTCALL gfx_draw_sprite_palette_set_software( return; } - dest_start_x = dest_start_x / zoom_level; + dest_start_x = zoom_level.ApplyInversedTo(dest_start_x); uint8_t* dest_pointer = dpi->bits; // Move the pointer to the start point of the destination - dest_pointer += ((dpi->width / zoom_level) + dpi->pitch) * dest_start_y + dest_start_x; + dest_pointer += (zoom_level.ApplyInversedTo(dpi->width) + dpi->pitch) * dest_start_y + dest_start_x; DrawSpriteArgs args(imageId, paletteMap, *g1, source_start_x, source_start_y, width, height, dest_pointer); gfx_sprite_to_buffer(*dpi, args); diff --git a/src/openrct2/drawing/LightFX.cpp b/src/openrct2/drawing/LightFX.cpp index 8882aef305..888b416e21 100644 --- a/src/openrct2/drawing/LightFX.cpp +++ b/src/openrct2/drawing/LightFX.cpp @@ -205,8 +205,8 @@ void lightfx_prepare_light_list() int32_t posOnScreenX = entry->ViewCoords.x - _current_view_x_front; int32_t posOnScreenY = entry->ViewCoords.y - _current_view_y_front; - posOnScreenX = posOnScreenX / _current_view_zoom_front; - posOnScreenY = posOnScreenY / _current_view_zoom_front; + posOnScreenX = _current_view_zoom_front.ApplyInversedTo(posOnScreenX); + posOnScreenY = _current_view_zoom_front.ApplyInversedTo(posOnScreenY); if ((posOnScreenX < -128) || (posOnScreenY < -128) || (posOnScreenX > _pixelInfo.width + 128) || (posOnScreenY > _pixelInfo.height + 128)) @@ -266,7 +266,7 @@ void lightfx_prepare_light_list() break; } - int32_t mapFrontDiv = 1 * _current_view_zoom_front; + int32_t mapFrontDiv = _current_view_zoom_front.ApplyTo(1); // clang-format off static int16_t offsetPattern[26] = { @@ -476,8 +476,8 @@ void lightfx_render_lights_to_frontbuffer() { inRectCentreX -= _current_view_x_front; inRectCentreY -= _current_view_y_front; - inRectCentreX = inRectCentreX / _current_view_zoom_front; - inRectCentreY = inRectCentreY / _current_view_zoom_front; + inRectCentreX = _current_view_zoom_front.ApplyInversedTo(inRectCentreX); + inRectCentreY = _current_view_zoom_front.ApplyInversedTo(inRectCentreY); } switch (entry->Type) diff --git a/src/openrct2/drawing/X8DrawingEngine.cpp b/src/openrct2/drawing/X8DrawingEngine.cpp index 647d31a1bc..644cb32789 100644 --- a/src/openrct2/drawing/X8DrawingEngine.cpp +++ b/src/openrct2/drawing/X8DrawingEngine.cpp @@ -457,8 +457,8 @@ X8DrawingContext::X8DrawingContext(X8DrawingEngine* engine) void X8DrawingContext::Clear(rct_drawpixelinfo* dpi, uint8_t paletteIndex) { - int32_t w = dpi->width / dpi->zoom_level; - int32_t h = dpi->height / dpi->zoom_level; + int32_t w = dpi->zoom_level.ApplyInversedTo(dpi->width); + int32_t h = dpi->zoom_level.ApplyInversedTo(dpi->height); uint8_t* ptr = dpi->bits; for (int32_t y = 0; y < h; y++) @@ -684,18 +684,19 @@ void X8DrawingContext::FilterRect( // Location in screen buffer? uint8_t* dst = dpi->bits + static_cast( - (startY / dpi->zoom_level) * ((dpi->width / dpi->zoom_level) + dpi->pitch) + (startX / dpi->zoom_level)); + dpi->zoom_level.ApplyInversedTo(startY) * (dpi->zoom_level.ApplyInversedTo(dpi->width) + dpi->pitch) + + dpi->zoom_level.ApplyInversedTo(startX)); // Find colour in colour table? auto paletteMap = GetPaletteMapForColour(EnumValue(palette)); if (paletteMap.has_value()) { const auto& paletteEntries = paletteMap.value(); - const int32_t scaled_width = width / dpi->zoom_level; - const int32_t step = ((dpi->width / dpi->zoom_level) + dpi->pitch); + const int32_t scaled_width = dpi->zoom_level.ApplyInversedTo(width); + const int32_t step = dpi->zoom_level.ApplyInversedTo(dpi->width) + dpi->pitch; // Fill the rectangle with the colours from the colour table - auto c = height / dpi->zoom_level; + auto c = dpi->zoom_level.ApplyInversedTo(height); for (int32_t i = 0; i < c; i++) { uint8_t* nextdst = dst + step * i; diff --git a/src/openrct2/entity/Peep.cpp b/src/openrct2/entity/Peep.cpp index d319fa6af8..3963262188 100644 --- a/src/openrct2/entity/Peep.cpp +++ b/src/openrct2/entity/Peep.cpp @@ -1230,7 +1230,7 @@ void peep_update_crowd_noise() // 207360000 maybe related to DSBVOLUME_MIN which is -10,000 (dB/100) volume = 120 - std::min(visiblePeeps, 120); volume = volume * volume * volume * volume; - volume = (((207360000 - volume) / viewport->zoom) - 207360000) / 65536 - 150; + volume = (viewport->zoom.ApplyInversedTo(207360000 - volume) - 207360000) / 65536 - 150; // Load and play crowd noise if needed and set volume if (_crowdSoundChannel == nullptr) diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index e3f49ac55e..fab14cbe9b 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -358,8 +358,8 @@ static rct_viewport GetGiantViewport(const TileCoordsXY& mapSize, int32_t rotati viewport.viewPos = { left, top }; viewport.view_width = right - left; viewport.view_height = bottom - top; - viewport.width = viewport.view_width / zoom; - viewport.height = viewport.view_height / zoom; + viewport.width = zoom.ApplyInversedTo(viewport.view_width); + viewport.height = zoom.ApplyInversedTo(viewport.view_height); viewport.zoom = zoom; return viewport; } @@ -805,8 +805,8 @@ void CaptureImage(const CaptureOptions& options) auto z = tile_element_height(options.View->Position); CoordsXYZ coords3d(options.View->Position, z); auto coords2d = translate_3d_to_2d_with_z(options.Rotation, coords3d); - viewport.viewPos = { coords2d.x - ((viewport.view_width * options.Zoom) / 2), - coords2d.y - ((viewport.view_height * options.Zoom) / 2) }; + viewport.viewPos = { coords2d.x - ((options.Zoom.ApplyTo(viewport.view_width)) / 2), + coords2d.y - ((options.Zoom.ApplyTo(viewport.view_height)) / 2) }; viewport.zoom = options.Zoom; } else diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 0914fe217b..bc9a0b9be4 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -178,8 +178,8 @@ void viewport_create(rct_window* w, const ScreenCoordsXY& screenCoords, int32_t viewport->height = height; const auto zoom = focus.zoom; - viewport->view_width = width * zoom; - viewport->view_height = height * zoom; + viewport->view_width = zoom.ApplyTo(width); + viewport->view_height = zoom.ApplyTo(height); viewport->zoom = zoom; viewport->flags = 0; @@ -294,49 +294,49 @@ static void viewport_redraw_after_shift( if (viewport->pos.x < window->windowPos.x) { viewport->width = window->windowPos.x - viewport->pos.x; - viewport->view_width = viewport->width * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(viewport->width); viewport_redraw_after_shift(dpi, window, viewport, coords); viewport->pos.x += viewport->width; - viewport->viewPos.x += viewport->width * viewport->zoom; + viewport->viewPos.x += viewport->zoom.ApplyTo(viewport->width); viewport->width = view_copy.width - viewport->width; - viewport->view_width = viewport->width * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(viewport->width); viewport_redraw_after_shift(dpi, window, viewport, coords); } else if (viewport->pos.x + viewport->width > window->windowPos.x + window->width) { viewport->width = window->windowPos.x + window->width - viewport->pos.x; - viewport->view_width = viewport->width * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(viewport->width); viewport_redraw_after_shift(dpi, window, viewport, coords); viewport->pos.x += viewport->width; - viewport->viewPos.x += viewport->width * viewport->zoom; + viewport->viewPos.x += viewport->zoom.ApplyTo(viewport->width); viewport->width = view_copy.width - viewport->width; - viewport->view_width = viewport->width * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(viewport->width); viewport_redraw_after_shift(dpi, window, viewport, coords); } else if (viewport->pos.y < window->windowPos.y) { viewport->height = window->windowPos.y - viewport->pos.y; - viewport->view_width = viewport->width * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(viewport->width); viewport_redraw_after_shift(dpi, window, viewport, coords); viewport->pos.y += viewport->height; - viewport->viewPos.y += viewport->height * viewport->zoom; + viewport->viewPos.y += viewport->zoom.ApplyTo(viewport->height); viewport->height = view_copy.height - viewport->height; - viewport->view_width = viewport->width * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(viewport->width); viewport_redraw_after_shift(dpi, window, viewport, coords); } else if (viewport->pos.y + viewport->height > window->windowPos.y + window->height) { viewport->height = window->windowPos.y + window->height - viewport->pos.y; - viewport->view_width = viewport->width * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(viewport->width); viewport_redraw_after_shift(dpi, window, viewport, coords); viewport->pos.y += viewport->height; - viewport->viewPos.y += viewport->height * viewport->zoom; + viewport->viewPos.y += viewport->zoom.ApplyTo(viewport->height); viewport->height = view_copy.height - viewport->height; - viewport->view_width = viewport->width * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(viewport->width); viewport_redraw_after_shift(dpi, window, viewport, coords); } @@ -447,8 +447,8 @@ static void viewport_move(const ScreenCoordsXY& coords, rct_window* w, rct_viewp // Note: do not do the subtraction and then divide! // Note: Due to arithmetic shift != /zoom a shift will have to be used // hopefully when 0x006E7FF3 is finished this can be converted to /zoom. - auto x_diff = (viewport->viewPos.x / viewport->zoom) - (coords.x / viewport->zoom); - auto y_diff = (viewport->viewPos.y / viewport->zoom) - (coords.y / viewport->zoom); + auto x_diff = viewport->zoom.ApplyInversedTo(viewport->viewPos.x) - viewport->zoom.ApplyInversedTo(coords.x); + auto y_diff = viewport->zoom.ApplyInversedTo(viewport->viewPos.y) - viewport->zoom.ApplyInversedTo(coords.y); viewport->viewPos = coords; @@ -481,8 +481,8 @@ static void viewport_move(const ScreenCoordsXY& coords, rct_window* w, rct_viewp if (viewport->pos.x < 0) { viewport->width += viewport->pos.x; - viewport->view_width += viewport->pos.x * zoom; - viewport->viewPos.x -= viewport->pos.x * zoom; + viewport->view_width += zoom.ApplyTo(viewport->pos.x); + viewport->viewPos.x -= zoom.ApplyTo(viewport->pos.x); viewport->pos.x = 0; } @@ -490,7 +490,7 @@ static void viewport_move(const ScreenCoordsXY& coords, rct_window* w, rct_viewp if (eax > 0) { viewport->width -= eax; - viewport->view_width -= eax * zoom; + viewport->view_width -= zoom.ApplyTo(eax); } if (viewport->width <= 0) @@ -502,8 +502,8 @@ static void viewport_move(const ScreenCoordsXY& coords, rct_window* w, rct_viewp if (viewport->pos.y < 0) { viewport->height += viewport->pos.y; - viewport->view_height += viewport->pos.y * zoom; - viewport->viewPos.y -= viewport->pos.y * zoom; + viewport->view_height += zoom.ApplyTo(viewport->pos.y); + viewport->viewPos.y -= zoom.ApplyTo(viewport->pos.y); viewport->pos.y = 0; } @@ -511,7 +511,7 @@ static void viewport_move(const ScreenCoordsXY& coords, rct_window* w, rct_viewp if (eax > 0) { viewport->height -= eax; - viewport->view_height -= eax * zoom; + viewport->view_height -= zoom.ApplyTo(eax); } if (viewport->height <= 0) @@ -819,14 +819,14 @@ void viewport_render( topLeft -= viewport->pos; topLeft = ScreenCoordsXY{ - std::max(topLeft.x, 0) * viewport->zoom, - std::max(topLeft.y, 0) * viewport->zoom, + viewport->zoom.ApplyTo(std::max(topLeft.x, 0)), + viewport->zoom.ApplyTo(std::max(topLeft.y, 0)), } + viewport->viewPos; bottomRight -= viewport->pos; bottomRight = ScreenCoordsXY{ - std::min(bottomRight.x, viewport->width) * viewport->zoom, - std::min(bottomRight.y, viewport->height) * viewport->zoom, + viewport->zoom.ApplyTo(std::min(bottomRight.x, viewport->width)), + viewport->zoom.ApplyTo(std::min(bottomRight.y, viewport->height)), } + viewport->viewPos; viewport_paint(viewport, dpi, { topLeft, bottomRight }, sessions); @@ -961,7 +961,7 @@ void viewport_paint( const uint32_t viewFlags = viewport->flags; uint32_t width = screenRect.GetWidth(); uint32_t height = screenRect.GetHeight(); - const uint32_t bitmask = viewport->zoom >= ZoomLevel{ 0 } ? 0xFFFFFFFF & (0xFFFFFFFF * viewport->zoom) : 0xFFFFFFFF; + const uint32_t bitmask = viewport->zoom >= ZoomLevel{ 0 } ? 0xFFFFFFFF & (viewport->zoom.ApplyTo(0xFFFFFFFF)) : 0xFFFFFFFF; ScreenCoordsXY topLeft = screenRect.Point1; width &= bitmask; @@ -970,11 +970,11 @@ void viewport_paint( topLeft.y &= bitmask; auto x = topLeft.x - static_cast(viewport->viewPos.x & bitmask); - x = x / viewport->zoom; + x = viewport->zoom.ApplyInversedTo(x); x += viewport->pos.x; auto y = topLeft.y - static_cast(viewport->viewPos.y & bitmask); - y = y / viewport->zoom; + y = viewport->zoom.ApplyInversedTo(y); y += viewport->pos.y; rct_drawpixelinfo dpi1; @@ -984,7 +984,7 @@ void viewport_paint( dpi1.y = topLeft.y; dpi1.width = width; dpi1.height = height; - dpi1.pitch = (dpi->width + dpi->pitch) - (width / viewport->zoom); + dpi1.pitch = (dpi->width + dpi->pitch) - viewport->zoom.ApplyInversedTo(width); dpi1.zoom_level = viewport->zoom; dpi1.remX = std::max(0, dpi->x - x); dpi1.remY = std::max(0, dpi->y - y); @@ -1032,8 +1032,8 @@ void viewport_paint( { auto leftPitch = x - dpi2.x; dpi2.width -= leftPitch; - dpi2.bits += leftPitch / dpi2.zoom_level; - dpi2.pitch += leftPitch / dpi2.zoom_level; + dpi2.bits += dpi2.zoom_level.ApplyInversedTo(leftPitch); + dpi2.pitch += dpi2.zoom_level.ApplyInversedTo(leftPitch); dpi2.x = x; } @@ -1042,7 +1042,7 @@ void viewport_paint( { auto rightPitch = paintRight - x - 32; paintRight -= rightPitch; - dpi2.pitch += rightPitch / dpi2.zoom_level; + dpi2.pitch += dpi2.zoom_level.ApplyInversedTo(rightPitch); } dpi2.width = paintRight - dpi2.x; @@ -1095,8 +1095,8 @@ static void viewport_paint_weather_gloom(rct_drawpixelinfo* dpi) auto zoomLevel = dpi->zoom_level < ZoomLevel{ 0 } ? dpi->zoom_level : ZoomLevel{ 0 }; auto x = dpi->x; auto y = dpi->y; - auto w = (dpi->width / zoomLevel) - 1; - auto h = (dpi->height / zoomLevel) - 1; + auto w = zoomLevel.ApplyInversedTo(dpi->width) - 1; + auto h = zoomLevel.ApplyInversedTo(dpi->height) - 1; gfx_filter_rect(dpi, ScreenRect(x, y, x + w, y + h), paletteId); } } @@ -1154,8 +1154,8 @@ std::optional screen_pos_to_map_pos(const ScreenCoordsXY& screenCoords [[nodiscard]] ScreenCoordsXY rct_viewport::ScreenToViewportCoord(const ScreenCoordsXY& screenCoords) const { ScreenCoordsXY ret; - ret.x = ((screenCoords.x - pos.x) * zoom) + viewPos.x; - ret.y = ((screenCoords.y - pos.y) * zoom) + viewPos.y; + ret.x = (zoom.ApplyTo(screenCoords.x - pos.x)) + viewPos.x; + ret.y = (zoom.ApplyTo(screenCoords.y - pos.y)) + viewPos.y; return ret; } @@ -1524,7 +1524,7 @@ static bool is_sprite_interacted_with_palette_set( } } - int32_t round = std::max(1, 1 * dpi->zoom_level); + int32_t round = std::max(1, dpi->zoom_level.ApplyTo(1)); auto origin = coords; if (g1->flags & G1_FLAG_RLE_COMPRESSION) @@ -1741,13 +1741,13 @@ InteractionInfo get_map_coordinates_from_pos_window(rct_window* window, const Sc if (viewLoc.x >= 0 && viewLoc.x < static_cast(myviewport->width) && viewLoc.y >= 0 && viewLoc.y < static_cast(myviewport->height)) { - viewLoc.x = viewLoc.x * myviewport->zoom; - viewLoc.y = viewLoc.y * myviewport->zoom; + viewLoc.x = myviewport->zoom.ApplyTo(viewLoc.x); + viewLoc.y = myviewport->zoom.ApplyTo(viewLoc.y); viewLoc += myviewport->viewPos; if (myviewport->zoom > ZoomLevel{ 0 }) { - viewLoc.x &= (0xFFFFFFFF * myviewport->zoom) & 0xFFFFFFFF; - viewLoc.y &= (0xFFFFFFFF * myviewport->zoom) & 0xFFFFFFFF; + viewLoc.x &= myviewport->zoom.ApplyTo(0xFFFFFFFF) & 0xFFFFFFFF; + viewLoc.y &= myviewport->zoom.ApplyTo(0xFFFFFFFF) & 0xFFFFFFFF; } rct_drawpixelinfo dpi; dpi.x = viewLoc.x; @@ -1798,12 +1798,12 @@ void viewport_invalidate(const rct_viewport* viewport, const ScreenRect& screenR { topLeft = { std::max(topLeft.x, viewport->viewPos.x), std::max(topLeft.y, viewport->viewPos.y) }; topLeft -= viewport->viewPos; - topLeft = { topLeft.x / viewport->zoom, topLeft.y / viewport->zoom }; + topLeft = { viewport->zoom.ApplyInversedTo(topLeft.x), viewport->zoom.ApplyInversedTo(topLeft.y) }; topLeft += viewport->pos; bottomRight = { std::max(bottomRight.x, viewportRight), std::max(bottomRight.y, viewportBottom) }; bottomRight -= viewport->viewPos; - bottomRight = { bottomRight.x / viewport->zoom, bottomRight.y / viewport->zoom }; + bottomRight = { viewport->zoom.ApplyInversedTo(bottomRight.x), viewport->zoom.ApplyInversedTo(bottomRight.y) }; bottomRight += viewport->pos; gfx_set_dirty_blocks({ topLeft, bottomRight }); diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index 801c51cec9..d0bb6a84ab 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -982,12 +982,12 @@ void window_viewport_get_map_coords_by_cursor( } // Rebase mouse position onto centre of window, and compensate for zoom level. - int32_t rebased_x = ((w->width / 2) - mouseCoords.x) * w->viewport->zoom; - int32_t rebased_y = ((w->height / 2) - mouseCoords.y) * w->viewport->zoom; + int32_t rebased_x = w->viewport->zoom.ApplyTo(w->width / 2 - mouseCoords.x); + int32_t rebased_y = w->viewport->zoom.ApplyTo(w->height / 2 - mouseCoords.y); // Compute cursor offset relative to tile. - *offset_x = (w->savedViewPos.x - (centreLoc->x + rebased_x)) * w->viewport->zoom; - *offset_y = (w->savedViewPos.y - (centreLoc->y + rebased_y)) * w->viewport->zoom; + *offset_x = w->viewport->zoom.ApplyTo(w->savedViewPos.x - (centreLoc->x + rebased_x)); + *offset_y = w->viewport->zoom.ApplyTo(w->savedViewPos.y - (centreLoc->y + rebased_y)); } void window_viewport_centre_tile_around_cursor(rct_window* w, int32_t map_x, int32_t map_y, int32_t offset_x, int32_t offset_y) @@ -1006,12 +1006,12 @@ void window_viewport_centre_tile_around_cursor(rct_window* w, int32_t map_x, int auto mouseCoords = context_get_cursor_position_scaled(); // Rebase mouse position onto centre of window, and compensate for zoom level. - int32_t rebased_x = ((w->width >> 1) - mouseCoords.x) * w->viewport->zoom; - int32_t rebased_y = ((w->height >> 1) - mouseCoords.y) * w->viewport->zoom; + int32_t rebased_x = w->viewport->zoom.ApplyTo((w->width >> 1) - mouseCoords.x); + int32_t rebased_y = w->viewport->zoom.ApplyTo((w->height >> 1) - mouseCoords.y); // Apply offset to the viewport. - w->savedViewPos = { centreLoc->x + rebased_x + (offset_x / w->viewport->zoom), - centreLoc->y + rebased_y + (offset_y / w->viewport->zoom) }; + w->savedViewPos = { centreLoc->x + rebased_x + w->viewport->zoom.ApplyInversedTo(offset_x), + centreLoc->y + rebased_y + w->viewport->zoom.ApplyInversedTo(offset_y) }; } /** @@ -1743,8 +1743,8 @@ void window_resize_gui_scenario_editor(int32_t width, int32_t height) mainWind->height = height; viewport->width = width; viewport->height = height; - viewport->view_width = width * viewport->zoom; - viewport->view_height = height * viewport->zoom; + viewport->view_width = viewport->zoom.ApplyTo(width); + viewport->view_height = viewport->zoom.ApplyTo(height); if (mainWind->widgets != nullptr && mainWind->widgets[WC_MAIN_WINDOW__0].type == WindowWidgetType::Viewport) { mainWind->widgets[WC_MAIN_WINDOW__0].right = width; diff --git a/src/openrct2/interface/ZoomLevel.h b/src/openrct2/interface/ZoomLevel.h index e901b45959..d680523681 100644 --- a/src/openrct2/interface/ZoomLevel.h +++ b/src/openrct2/interface/ZoomLevel.h @@ -53,20 +53,20 @@ public: friend constexpr bool operator>(const ZoomLevel& lhs, const ZoomLevel& rhs); friend constexpr bool operator<(const ZoomLevel& lhs, const ZoomLevel& rhs); - template friend T operator*(const T& lhs, const ZoomLevel& rhs) + template T ApplyTo(const T& lhs) const { - if (rhs._level < 0) - return lhs >> -rhs._level; + if (_level < 0) + return lhs >> -_level; - return lhs << rhs._level; + return lhs << _level; } - template friend T operator/(const T& lhs, const ZoomLevel& rhs) + template T ApplyInversedTo(const T& lhs) const { - if (rhs._level < 0) - return lhs << -rhs._level; + if (_level < 0) + return lhs << -_level; - return lhs >> rhs._level; + return lhs >> _level; } static ZoomLevel min(); diff --git a/src/openrct2/ride/RideAudio.cpp b/src/openrct2/ride/RideAudio.cpp index 46e5fdf9d8..0bf6731faf 100644 --- a/src/openrct2/ride/RideAudio.cpp +++ b/src/openrct2/ride/RideAudio.cpp @@ -387,11 +387,11 @@ namespace OpenRCT2::RideAudio } else { - auto x2 = (viewport->pos.x + ((rotatedCoords.x - viewport->viewPos.x) / viewport->zoom)) * 0x10000; + auto x2 = (viewport->pos.x + viewport->zoom.ApplyInversedTo(rotatedCoords.x - viewport->viewPos.x)) * 0x10000; auto screenWidth = std::max(context_get_width(), 64); auto panX = ((x2 / screenWidth) - 0x8000) >> 4; - auto y2 = (viewport->pos.y + ((rotatedCoords.y - viewport->viewPos.y) / viewport->zoom)) * 0x10000; + auto y2 = (viewport->pos.y + viewport->zoom.ApplyInversedTo(rotatedCoords.y - viewport->viewPos.y)) * 0x10000; auto screenHeight = std::max(context_get_height(), 64); auto panY = ((y2 / screenHeight) - 0x8000) >> 4; diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 586588e485..2bc30ea7b8 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -2105,8 +2105,8 @@ void TrackDesignDrawPreview(TrackDesign* td6, uint8_t* pixels) zoom_level = ZoomLevel{ 3 }; } - size_x = 370 * zoom_level; - size_y = 217 * zoom_level; + size_x = zoom_level.ApplyTo(370); + size_y = zoom_level.ApplyTo(217); rct_viewport view; view.width = 370; diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 6d18abb9cb..6000eebd41 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -850,7 +850,7 @@ OpenRCT2::Audio::VehicleSoundParams Vehicle::CreateSoundParam(uint16_t priority) OpenRCT2::Audio::VehicleSoundParams param; param.priority = priority; int32_t panX = (SpriteRect.GetLeft() / 2) + (SpriteRect.GetRight() / 2) - g_music_tracking_viewport->viewPos.x; - panX = panX / g_music_tracking_viewport->zoom; + panX = g_music_tracking_viewport->zoom.ApplyInversedTo(panX); panX += g_music_tracking_viewport->pos.x; uint16_t screenWidth = context_get_width(); @@ -861,7 +861,7 @@ OpenRCT2::Audio::VehicleSoundParams Vehicle::CreateSoundParam(uint16_t priority) param.pan_x = ((((panX * 65536) / screenWidth) - 0x8000) >> 4); int32_t panY = (SpriteRect.GetTop() / 2) + (SpriteRect.GetBottom() / 2) - g_music_tracking_viewport->viewPos.y; - panY = panY / g_music_tracking_viewport->zoom; + panY = g_music_tracking_viewport->zoom.ApplyInversedTo(panY); panY += g_music_tracking_viewport->pos.y; uint16_t screenHeight = context_get_height();