From a24de647072414c9a09c96bb25a54f313a1ef171 Mon Sep 17 00:00:00 2001 From: Ralty <78720179+Raltyro@users.noreply.github.com> Date: Wed, 26 Nov 2025 20:04:12 +0700 Subject: [PATCH] Fix Zoom Factor & zoomMultiplier not affecting it --- source/funkin/backend/FunkinSprite.hx | 65 ++++++++++++++++++--------- source/funkin/backend/system/Flags.hx | 5 ++- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/source/funkin/backend/FunkinSprite.hx b/source/funkin/backend/FunkinSprite.hx index a0c5b3b5..522d851b 100644 --- a/source/funkin/backend/FunkinSprite.hx +++ b/source/funkin/backend/FunkinSprite.hx @@ -70,6 +70,8 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I @:noCompletion public var atlasPlayingAnim:String; @:noCompletion public var atlasPath:String; + var _rect2:FlxRect; + public function new(?X:Float = 0, ?Y:Float = 0, ?SimpleGraphic:FlxGraphicAsset) { super(X, Y); @@ -112,6 +114,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I spr.transformMatrix = casted.transformMatrix; spr.matrixExposed = casted.matrixExposed; spr.animOffsets = casted.animOffsets.copy(); + spr.zoomFactor = casted.zoomFactor; } } return spr; @@ -131,6 +134,11 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I } } + override function initVars() { + super.initVars(); + _rect2 = FlxRect.get(); + } + public function loadSprite(path:String, Unique:Bool = false, Key:String = null) { var noExt = Path.withoutExtension(path); @@ -226,6 +234,8 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I animOffsets = null; } super.destroy(); + + _rect2 = FlxDestroyUtil.put(_rect2); } #end @@ -233,27 +243,40 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I private inline function __shouldDoZoomFactor() return zoomFactorEnabled && zoomFactor != 1; + private inline function __prepareZoomFactor(?rect:FlxRect, camera:FlxCamera):FlxRect { + if (Flags.USE_LEGACY_ZOOM_FACTOR) + return (rect ?? FlxRect.get()).set( + camera.width * 0.5, + camera.height * 0.5, + (camera.scaleX > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleX, 1, zoomFactor)), + (camera.scaleY > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleY, 1, zoomFactor)) + ); + else + return (rect ?? FlxRect.get()).set( + camera.width * 0.5 + camera.scroll.x * scrollFactor.x, + camera.height * 0.5 + camera.scroll.y * scrollFactor.y, + (camera.scaleX > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleX, 1, zoomFactor)), + (camera.scaleY > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleY, 1, zoomFactor)) + ); + } + public override function getScreenBounds(?newRect:FlxRect, ?camera:FlxCamera):FlxRect { if (camera == null) camera = FlxG.camera; - var r = super.getScreenBounds(newRect, camera); + newRect = super.getScreenBounds(newRect, camera); if(__shouldDoZoomFactor()) { - r.x -= camera.width / 2; - r.y -= camera.height / 2; - - var ratio = (camera.zoom > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.zoom, 1, zoomFactor)); - r.x *= ratio; - r.y *= ratio; - r.width *= ratio; - r.height *= ratio; - - r.x += camera.width / 2; - r.y += camera.height / 2; + __prepareZoomFactor(_rect2, camera); + newRect.set( + (newRect.x - _rect2.x) * _rect2.width + _rect2.x, + (newRect.y - _rect2.y) * _rect2.height + _rect2.y, + newRect.width * _rect2.width, + newRect.height * _rect2.height, + ); } - return r; + return newRect; } override public function isOnScreen(?camera:FlxCamera):Bool @@ -273,14 +296,16 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I // ZOOM FACTOR RENDERING public override function doAdditionalMatrixStuff(matrix:FlxMatrix, camera:FlxCamera) { - super.doAdditionalMatrixStuff(matrix, camera); + // no need to... + //super.doAdditionalMatrixStuff(matrix, camera); if(__shouldDoZoomFactor()) { - matrix.translate(-camera.width / 2, -camera.height / 2); - - var requestedZoom = (camera.zoom >= 0 ? Math.max : Math.min)(FlxMath.lerp(1, camera.zoom, zoomFactor), 0); - var diff = requestedZoom / camera.zoom; - matrix.scale(diff, diff); - matrix.translate(camera.width / 2, camera.height / 2); + __prepareZoomFactor(_rect, camera); + matrix.setTo( + matrix.a * _rect.width, matrix.b * _rect.height, + matrix.c * _rect.width, matrix.d * _rect.height, + (matrix.tx - _rect.x) * _rect.width + _rect.x, + (matrix.ty - _rect.y) * _rect.height + _rect.y, + ); } } diff --git a/source/funkin/backend/system/Flags.hx b/source/funkin/backend/system/Flags.hx index b085123c..97ff49ff 100644 --- a/source/funkin/backend/system/Flags.hx +++ b/source/funkin/backend/system/Flags.hx @@ -128,7 +128,7 @@ class Flags { @:also(funkin.game.PlayState.opponentMode) public static var DEFAULT_OPPONENT_MODE:Bool = false; - @:lazy public static var USE_LEGACY_TIMING:Null = null; + public static var USE_LEGACY_TIMING:Null = null; public static var DEFAULT_NOTE_MS_LIMIT:Float = 1500; public static var DEFAULT_NOTE_SCALE:Float = 0.7; @@ -153,6 +153,8 @@ class Flags { public static var DEFAULT_HUD_ZOOM_MULT:Float = 0.03; public static var DEFAULT_CAM_ZOOM_LERP:Float = 0.05; public static var DEFAULT_HUD_ZOOM_LERP:Float = 0.05; + + public static var USE_LEGACY_ZOOM_FACTOR:Null = null; // Font configuration public static var DEFAULT_FONT:String = "vcr.ttf"; @@ -304,6 +306,7 @@ class Flags { if (MOD_API_VERSION == null) MOD_API_VERSION = CURRENT_API_VERSION; if (WINDOW_TITLE_USE_MOD_NAME == null) WINDOW_TITLE_USE_MOD_NAME = !overridenFlags.exists('TITLE') && overridenFlags.exists('MOD_NAME'); if (USE_LEGACY_TIMING == null) USE_LEGACY_TIMING = MOD_API_VERSION <= 1; + if (USE_LEGACY_ZOOM_FACTOR == null) USE_LEGACY_ZOOM_FACTOR = MOD_API_VERSION <= 1; } public static function loadFromDatas(datas:Array):Map {