diff --git a/project.xml b/project.xml
index 072ab1ab..09502ba7 100644
--- a/project.xml
+++ b/project.xml
@@ -108,7 +108,7 @@
diff --git a/source/funkin/backend/system/FakeCamera.hx b/source/funkin/backend/system/FakeCamera.hx
index 5170c246..83d66eee 100644
--- a/source/funkin/backend/system/FakeCamera.hx
+++ b/source/funkin/backend/system/FakeCamera.hx
@@ -35,4 +35,15 @@ class FakeCamera extends FlxCamera {
// override function set_zoom(Zoom:Float):Float return zoom = (Zoom == 0) ? FlxCamera.defaultZoom : Zoom;
public override function setScale(X:Float, Y:Float):Void {}
+}
+
+class FakeCallCamera extends FakeCamera {
+ public static final instance = new FakeCallCamera();
+
+ public dynamic function onDraw(?frame:FlxFrame, ?pixels:BitmapData, matrix:FlxMatrix, ?transform:ColorTransform, ?blend:BlendMode, ?smoothing:Bool = false, ?shader:FlxShader, smooth:Bool = false, ?shader:FlxShader) {
+ }
+
+ override function drawPixels(?frame:FlxFrame, ?pixels:BitmapData, matrix:FlxMatrix, ?transform:ColorTransform, ?blend:BlendMode, ?smoothing:Bool = false, ?shader:FlxShader) {
+ onDraw(frame, pixels, matrix, transform, blend, smoothing, shader);
+ }
}
\ No newline at end of file
diff --git a/source/funkin/backend/utils/MatrixUtil.hx b/source/funkin/backend/utils/MatrixUtil.hx
index 41cd5f1f..97e2d7a9 100644
--- a/source/funkin/backend/utils/MatrixUtil.hx
+++ b/source/funkin/backend/utils/MatrixUtil.hx
@@ -1,14 +1,30 @@
package funkin.backend.utils;
+import flixel.graphics.frames.FlxFrame;
import flixel.FlxCamera;
import flixel.math.FlxPoint;
import flixel.util.typeLimit.OneOfTwo;
+import funkin.backend.system.FakeCamera;
+import funkin.backend.system.FakeCamera.FakeCallCamera;
+import flixel.graphics.FlxGraphic;
+import flixel.graphics.frames.FlxFrame;
+import flixel.graphics.tile.FlxDrawTrianglesItem;
+import flixel.math.FlxMatrix;
+import flixel.math.FlxPoint;
+import flixel.system.FlxAssets.FlxShader;
+import openfl.display.BitmapData;
+import openfl.display.BlendMode;
+import openfl.geom.ColorTransform;
+import openfl.geom.Point;
+import openfl.geom.Rectangle;
interface IPrePostDraw {
public function preDraw():Void;
public function postDraw():Void;
}
+@:access(flixel.FlxCamera)
+@:access(flixel.FlxSprite)
final class MatrixUtil {
public static function getMatrixPosition(sprite:FlxSprite, points:OneOfTwo>, ?camera:FlxCamera, _width:Float = 1, _height:Float = 1):Array
{
@@ -16,34 +32,70 @@ final class MatrixUtil {
//if(_height == -1) _height = sprite.height;
if(camera == null) camera = sprite.camera;
if(points is FlxBasePoint) points = [points];
- var nc = funkin.backend.system.FakeCamera.instance;
+ var isFunkinSprite = sprite is FunkinSprite;
+ var funkinSprite:FunkinSprite = null;
+ if(isFunkinSprite) funkinSprite = cast sprite;
+ var isAnimateAtlas = isFunkinSprite && funkinSprite.animateAtlas != null;
+
+ var nc:FakeCamera = isAnimateAtlas ? FakeCallCamera.instance : FakeCamera.instance;
nc.zoom = camera.zoom;
nc.scroll.set(camera.scroll.x, camera.scroll.y);
nc.pixelPerfectRender = camera.pixelPerfectRender;
- if(sprite is IPrePostDraw) {
- var postDraw = cast(sprite, IPrePostDraw);
- postDraw.preDraw();
- @:privateAccess sprite.drawComplex(nc);
- postDraw.postDraw();
+
+ if(isAnimateAtlas) {
+ var nc = FakeCallCamera.instance;
+ var sprite = funkinSprite;
+ var oldOnDraw = nc.onDraw;
+ nc.onDraw = function(?frame:FlxFrame, ?pixels:BitmapData, matrix:FlxMatrix, ?transform:ColorTransform, ?blend:BlendMode, ?smoothing:Bool = false, ?shader:FlxShader, smooth:Bool = false, ?shader:FlxShader) {
+ // pixels is null
+
+ }
+ var cameras = sprite.animateAtlas._cameras;
+ sprite.animateAtlas._cameras = [nc];
+ if(sprite is IPrePostDraw) {
+ var postDraw = cast(sprite, IPrePostDraw);
+ postDraw.preDraw();
+ @:privateAccess sprite.draw();
+ postDraw.postDraw();
+ } else {
+ @:privateAccess sprite.draw();
+ }
+ sprite.animateAtlas._cameras = cameras;
+ nc.onDraw = oldOnDraw;
} else {
- @:privateAccess sprite.drawComplex(nc);
+ if(sprite is IPrePostDraw) {
+ var postDraw = cast(sprite, IPrePostDraw);
+ postDraw.preDraw();
+ @:privateAccess sprite.drawComplex(nc);
+ postDraw.postDraw();
+ } else {
+ @:privateAccess sprite.drawComplex(nc);
+ }
}
- var isFunkinSprite = sprite is FunkinSprite;
-
var points:Array = cast points;
- @:privateAccess for(point in points) {
- var x = sprite._matrix.__transformX(point.x * _width, point.y * _height);
- var y = sprite._matrix.__transformY(point.x * _width, point.y * _height);
+ transformPoints(sprite, points, sprite._matrix, camera, _width, _height);
+ return points;
+ }
+
+ /**
+ * Warning: modifies the points in the array
+ **/
+ public static function transformPoints(sprite:FlxSprite, points:Array, matrix:FlxMatrix, ?camera:FlxCamera, _width:Float = 1, _height:Float = 1):Array {
+ var isFunkinSprite = sprite is FunkinSprite;
+ var funkinSprite:FunkinSprite = null;
+ if(isFunkinSprite) funkinSprite = cast sprite;
+
+ for(point in points) {
+ var x = matrix.__transformX(point.x * _width, point.y * _height);
+ var y = matrix.__transformY(point.x * _width, point.y * _height);
// reset to ingame coords
x += camera.scroll.x;
y += camera.scroll.y;
if(isFunkinSprite) {
- var sprite:FunkinSprite = cast sprite;
-
- var ratio = 1 - FlxMath.lerp(1 / camera.zoom, 1, sprite.zoomFactor);
+ var ratio = 1 - FlxMath.lerp(1 / camera.zoom, 1, funkinSprite.zoomFactor);
x += camera.width / 2 * ratio;
y += camera.height / 2 * ratio;
}
diff --git a/source/funkin/editors/character/CharacterAnimsWindow.hx b/source/funkin/editors/character/CharacterAnimsWindow.hx
index 48980179..a3e67ea8 100644
--- a/source/funkin/editors/character/CharacterAnimsWindow.hx
+++ b/source/funkin/editors/character/CharacterAnimsWindow.hx
@@ -1,5 +1,6 @@
package funkin.editors.character;
+import flixel.util.typeLimit.OneOfTwo;
import funkin.backend.utils.XMLUtil.AnimData;
import flixel.animation.FlxAnimation;
import flixel.graphics.FlxGraphic;
@@ -14,7 +15,7 @@ class CharacterAnimsWindow extends UIButtonList {
public var displayWindowSprite:FlxSprite;
public var displayWindowGraphic:FlxGraphic;
- public var displayAnimsFramesList:Map = [];
+ public var displayAnimsFramesList:Map}> = [];
public var animButtons:Map = [];
public var animsList:Array = [];
@@ -28,7 +29,7 @@ class CharacterAnimsWindow extends UIButtonList {
buttonCameras.pixelPerfectRender = true;
- if (Assets.exists(Paths.image('characters/${character.sprite}')))
+ if (Assets.exists(Paths.image('characters/${character.sprite}')) && character.animateAtlas == null)
displayWindowGraphic = FlxG.bitmap.add(Assets.getBitmapData(Paths.image('characters/${character.sprite}'), true, false));
displayWindowSprite = new FlxSprite();
@@ -53,16 +54,33 @@ class CharacterAnimsWindow extends UIButtonList {
character.ghosts = ghosts;
}
- public function buildAnimDisplay(name:String, anim:FlxAnimation) {
- if (anim.frames.length <= 0) return;
+ public function buildAnimDisplay(name:String, anim:AnimData) @:privateAccess {
+ if (character.animateAtlas == null) {
+ var anim:FlxAnimation = character.animation._animations[anim.name];
+ if (anim == null || anim.frames.length <= 0) return;
- var frameIndex:Int = anim.frames.getDefault([0])[0];
- var frame:FlxFrame = displayWindowSprite.frames.frames[frameIndex];
+ var frameIndex:Int = anim.frames.getDefault([0])[0];
+ var frame:FlxFrame = displayWindowSprite.frames.frames[frameIndex];
+
+ var frameRect:Rectangle = new Rectangle(frame.offset.x, frame.offset.y, frame.sourceSize.x, frame.sourceSize.y);
+ var animBounds:Rectangle = displayWindowGraphic != null ? displayWindowGraphic.bitmap.bounds(frameRect) : frameRect;
+
+ displayAnimsFramesList.set(name, {frame: anim.frames.getDefault([0])[0], scale: 104/animBounds.height, animBounds: animBounds});
+ } else {
+ var ogFrame:Int = character.animateAtlas.anim.curFrame;
+ var oldTick:Float = character.animateAtlas.anim._tick;
+ var oldPlaying:Bool = character.animateAtlas.anim.isPlaying;
- var frameRect:Rectangle = new Rectangle(frame.offset.x, frame.offset.y, frame.sourceSize.x, frame.sourceSize.y);
- var animBounds:Rectangle = displayWindowGraphic != null ? displayWindowGraphic.bitmap.bounds(frameRect) : frameRect;
+ character.animateAtlas.anim.play(anim.name, true, false, 0);
+ character.animateAtlas.anim.stop();
- displayAnimsFramesList.set(name, {frame: anim.frames.getDefault([0])[0], scale: 104/animBounds.height, animBounds: animBounds});
+ var animBounds:Rectangle = MatrixUtil.getBounds(character).copyToFlash();
+ displayAnimsFramesList.set(name, {frame: anim.anim, scale: 104/animBounds.height, animBounds: animBounds});
+
+ character.animateAtlas.anim.play(atlasPlayingAnim, true, false, ogFrame);
+ character.animateAtlas.anim._tick = oldTick;
+ character.animateAtlas.anim.isPlaying = oldPlaying;
+ }
}
public function removeAnimDisplay(name:String)
diff --git a/source/funkin/editors/character/CharacterEditor.hx b/source/funkin/editors/character/CharacterEditor.hx
index a0d38458..569b69c5 100644
--- a/source/funkin/editors/character/CharacterEditor.hx
+++ b/source/funkin/editors/character/CharacterEditor.hx
@@ -409,6 +409,7 @@ class CharacterEditor extends UIState {
if(character.animateAtlas == null) {
StageEditor.calcSpriteBounds(character);
var bounds:FlxRect = cast character.extra.get(StageEditor.exID("bounds"));
+ trace(bounds);
if (bounds.containsPoint(point)) {
cameraHoverDummy.cursor = #if (mac) DRAG_OPEN; #else CLICK; #end
if (FlxG.mouse.justPressed)
diff --git a/source/funkin/editors/character/CharacterGhost.hx b/source/funkin/editors/character/CharacterGhost.hx
index 906f3f13..d1aabfee 100644
--- a/source/funkin/editors/character/CharacterGhost.hx
+++ b/source/funkin/editors/character/CharacterGhost.hx
@@ -4,6 +4,13 @@ import openfl.geom.ColorTransform;
import flixel.animation.FlxAnimation;
import funkin.game.Character;
+typedef AtlasState = {
+ var oldAnim:String;
+ var oldFrame:Int;
+ var oldTick:Float;
+ var oldPlaying:Bool;
+};
+
class CharacterGhost extends Character {
public var ghosts:Array = [];
public override function draw() @:privateAccess {
@@ -67,4 +74,14 @@ class CharacterGhost extends Character {
offset.set(globalOffset.x * (isPlayer != playerOffsets ? 1 : -1), -globalOffset.y);
}
+
+ var atlasState:AtlasState = null;
+ public function storeAtlasState():AtlasState {
+ return atlasState = {
+ oldAnim: atlasPlayingAnim,
+ oldFrame: animateAtlas.anim.curFrame,
+ oldTick: animateAtlas.anim._tick,
+ oldPlaying: animateAtlas.anim.isPlaying,
+ };
+ }
}
\ No newline at end of file
diff --git a/source/funkin/editors/stage/StageEditor.hx b/source/funkin/editors/stage/StageEditor.hx
index b596eb7a..042711fa 100644
--- a/source/funkin/editors/stage/StageEditor.hx
+++ b/source/funkin/editors/stage/StageEditor.hx
@@ -1001,9 +1001,18 @@ class StageEditor extends UIState {
}
}
- public static function calcSpriteBounds(sprite:FlxSprite) {
+ public static function calcSpriteBounds(sprite:FunkinSprite) {
var oldWidth = sprite.width;
var oldHeight = sprite.height;
+
+ /*
+ if (sprite.animateAtlas != null) {
+ var rect:FlxRect = MatrixUtil.getBounds(sprite);
+ oldWidth = rect.width;
+ oldHeight = rect.height;
+ }
+ */
+
var oldOffset = sprite.offset.clone(FlxPoint.weak());
var oldOrigin = sprite.origin.clone(FlxPoint.weak());
sprite.updateHitbox();
diff --git a/source/funkin/game/Stage.hx b/source/funkin/game/Stage.hx
index 1a48d065..ab653653 100644
--- a/source/funkin/game/Stage.hx
+++ b/source/funkin/game/Stage.hx
@@ -409,7 +409,8 @@ class StageCharPos extends FlxObject {
oldInfo = getOldInfo(char);
char.setPosition(x + (id * charSpacingX), y + (id * charSpacingY));
char.scrollFactor.set(scrollFactor.x, scrollFactor.y);
- char.scale.x *= scale.x; char.scale.y *= scale.y;
+ if (!char.debugMode)
+ char.scale.x *= scale.x; char.scale.y *= scale.y;
char.cameraOffset += FlxPoint.weak(camxoffset, camyoffset);
char.skew.x += skewX; char.skew.y += skewY;
char.alpha *= alpha;