From f000d21689d7619f175c4bd2f589030a00e54c84 Mon Sep 17 00:00:00 2001
From: Cameron Taylor <cameron.taylor.ninja@gmail.com>
Date: Mon, 28 Aug 2023 14:52:03 -0400
Subject: [PATCH] shaders and blendmode overlay stuff in progres

---
 art                                           |  2 +-
 assets                                        |  2 +-
 source/funkin/FreeplayState.hx                | 44 +++++++----
 .../funkin/freeplayStuff/BGScrollingText.hx   | 32 ++++++--
 source/funkin/freeplayStuff/SongMenuItem.hx   | 12 +++
 .../funkin/shaderslmfao/BlendModesShader.hx   | 23 ++++++
 source/funkin/ui/title/FlxSpriteOverlay.hx    | 74 +++++++++++++++++++
 source/funkin/ui/title/TitleState.hx          | 11 ++-
 8 files changed, 175 insertions(+), 25 deletions(-)
 create mode 100644 source/funkin/shaderslmfao/BlendModesShader.hx
 create mode 100644 source/funkin/ui/title/FlxSpriteOverlay.hx

diff --git a/art b/art
index fbe23f8b5..e8d96feb8 160000
--- a/art
+++ b/art
@@ -1 +1 @@
-Subproject commit fbe23f8b59831ca0123727a35e02cdfb49f3ce60
+Subproject commit e8d96feb8af616f360e68538b7347fae84d8308f
diff --git a/assets b/assets
index cb481d798..20553cc46 160000
--- a/assets
+++ b/assets
@@ -1 +1 @@
-Subproject commit cb481d79891707029a7f10975ce0d392c56f244a
+Subproject commit 20553cc4687ec975427b37eda80e74e381d9a2ef
diff --git a/source/funkin/FreeplayState.hx b/source/funkin/FreeplayState.hx
index 99f12bcb0..1c263cf5f 100644
--- a/source/funkin/FreeplayState.hx
+++ b/source/funkin/FreeplayState.hx
@@ -1,5 +1,6 @@
 package funkin;
 
+import funkin.shaderslmfao.HSVShader;
 import funkin.ui.StickerSubState;
 import flash.text.TextField;
 import flixel.FlxCamera;
@@ -170,7 +171,7 @@ class FreeplayState extends MusicBeatSubState
     FlxTween.tween(pinkBack, {x: 0}, 0.6, {ease: FlxEase.quartOut});
     add(pinkBack);
 
-    var orangeBackShit:FlxSprite = new FlxSprite(84, FlxG.height * 0.68).makeGraphic(Std.int(pinkBack.width), 50, 0xFFffd400);
+    var orangeBackShit:FlxSprite = new FlxSprite(84, 440).makeGraphic(Std.int(pinkBack.width), 75, 0xFFfeda00);
     add(orangeBackShit);
 
     var alsoOrangeLOL:FlxSprite = new FlxSprite(0, orangeBackShit.y).makeGraphic(100, Std.int(orangeBackShit.height), 0xFFffd400);
@@ -192,21 +193,26 @@ class FreeplayState extends MusicBeatSubState
     add(grpTxtScrolls);
     grpTxtScrolls.visible = false;
 
-    var moreWays:BGScrollingText = new BGScrollingText(0, 200, "HOT BLOODED IN MORE WAYS THAN ONE", FlxG.width);
+    FlxG.debugger.addTrackerProfile(new TrackerProfile(BGScrollingText, ["x", "y", "speed", "size"]));
+
+    var moreWays:BGScrollingText = new BGScrollingText(0, 160, "HOT BLOODED IN MORE WAYS THAN ONE", FlxG.width, true, 43);
     moreWays.funnyColor = 0xFFfff383;
-    moreWays.speed = 4;
+    moreWays.speed = 6.8;
     grpTxtScrolls.add(moreWays);
 
+    FlxG.debugger.track(moreWays, "HotBlooded 1");
+
     exitMovers.set([moreWays],
       {
         x: FlxG.width * 2,
         speed: 0.4,
       });
 
-    var funnyScroll:BGScrollingText = new BGScrollingText(0, 250, "BOYFRIEND", FlxG.width / 2);
+    var funnyScroll:BGScrollingText = new BGScrollingText(0, 220, "BOYFRIEND", FlxG.width / 2, false, 60);
     funnyScroll.funnyColor = 0xFFff9963;
-    funnyScroll.speed = -1;
+    funnyScroll.speed = -3.8;
     grpTxtScrolls.add(funnyScroll);
+    FlxG.debugger.track(funnyScroll, "Boyfriend 1");
 
     exitMovers.set([funnyScroll],
       {
@@ -216,18 +222,21 @@ class FreeplayState extends MusicBeatSubState
         wait: 0
       });
 
-    var txtNuts:BGScrollingText = new BGScrollingText(0, 300, "PROTECT YO NUTS", FlxG.width / 2);
+    var txtNuts:BGScrollingText = new BGScrollingText(0, 285, "PROTECT YO NUTS", FlxG.width / 2, true, 43);
+    txtNuts.speed = 3.5;
     grpTxtScrolls.add(txtNuts);
     exitMovers.set([txtNuts],
       {
         x: FlxG.width * 2,
         speed: 0.4,
       });
+    FlxG.debugger.track(txtNuts, "Protect yo nuts 1");
 
-    var funnyScroll2:BGScrollingText = new BGScrollingText(0, 340, "BOYFRIEND", FlxG.width / 2);
+    var funnyScroll2:BGScrollingText = new BGScrollingText(0, 335, "BOYFRIEND", FlxG.width / 2, false, 60);
     funnyScroll2.funnyColor = 0xFFff9963;
-    funnyScroll2.speed = -1.2;
+    funnyScroll2.speed = -3.8;
     grpTxtScrolls.add(funnyScroll2);
+    FlxG.debugger.track(funnyScroll2, "Boyfriend 2");
 
     exitMovers.set([funnyScroll2],
       {
@@ -235,10 +244,11 @@ class FreeplayState extends MusicBeatSubState
         speed: 0.5,
       });
 
-    var moreWays2:BGScrollingText = new BGScrollingText(0, 400, "HOT BLOODED IN MORE WAYS THAN ONE", FlxG.width);
+    var moreWays2:BGScrollingText = new BGScrollingText(0, 397, "HOT BLOODED IN MORE WAYS THAN ONE", FlxG.width, true, 43);
     moreWays2.funnyColor = 0xFFfff383;
-    moreWays2.speed = 4.4;
+    moreWays2.speed = 6.8;
     grpTxtScrolls.add(moreWays2);
+    FlxG.debugger.track(moreWays2, "HotBlooded 2");
 
     exitMovers.set([moreWays2],
       {
@@ -246,10 +256,11 @@ class FreeplayState extends MusicBeatSubState
         speed: 0.4
       });
 
-    var funnyScroll3:BGScrollingText = new BGScrollingText(0, orangeBackShit.y, "BOYFRIEND", FlxG.width / 2);
-    funnyScroll3.funnyColor = 0xFFff9963;
-    funnyScroll3.speed = -0.8;
+    var funnyScroll3:BGScrollingText = new BGScrollingText(0, orangeBackShit.y + 10, "BOYFRIEND", FlxG.width / 2, 60);
+    funnyScroll3.funnyColor = 0xFFfea400;
+    funnyScroll3.speed = -3.8;
     grpTxtScrolls.add(funnyScroll3);
+    FlxG.debugger.track(funnyScroll3, "Boyfriend 3");
 
     exitMovers.set([funnyScroll3],
       {
@@ -555,6 +566,11 @@ class FreeplayState extends MusicBeatSubState
       }
     }
 
+    var hsvShader:HSVShader = new HSVShader();
+
+    FlxG.debugger.addTrackerProfile(new TrackerProfile(HSVShader, ["hue", "saturation", "value"]));
+    FlxG.debugger.track(hsvShader, "capsule shader");
+
     var randomCapsule:SongMenuItem = grpCapsules.recycle(SongMenuItem);
     randomCapsule.init(FlxG.width, 0, "Random");
     randomCapsule.onConfirm = function() {
@@ -566,6 +582,7 @@ class FreeplayState extends MusicBeatSubState
     randomCapsule.songText.visible = false;
     randomCapsule.favIcon.visible = false;
     randomCapsule.initJumpIn(0, force);
+    randomCapsule.hsvShader = hsvShader;
     grpCapsules.add(randomCapsule);
 
     for (i in 0...tempSongs.length)
@@ -580,6 +597,7 @@ class FreeplayState extends MusicBeatSubState
       funnyMenu.alpha = 0.5;
       funnyMenu.songText.visible = false;
       funnyMenu.favIcon.visible = tempSongs[i].isFav;
+      funnyMenu.hsvShader = hsvShader;
 
       // fp.updateScore(0);
 
diff --git a/source/funkin/freeplayStuff/BGScrollingText.hx b/source/funkin/freeplayStuff/BGScrollingText.hx
index 9fa6dd49b..586f83822 100644
--- a/source/funkin/freeplayStuff/BGScrollingText.hx
+++ b/source/funkin/freeplayStuff/BGScrollingText.hx
@@ -7,6 +7,7 @@ import flixel.math.FlxMath;
 import flixel.text.FlxText;
 import flixel.util.FlxColor;
 import flixel.util.FlxSort;
+import flixel.util.FlxTimer;
 
 // its kinda like marqeee html lol!
 class BGScrollingText extends FlxSpriteGroup
@@ -16,36 +17,53 @@ class BGScrollingText extends FlxSpriteGroup
   public var widthShit:Float = FlxG.width;
   public var placementOffset:Float = 20;
   public var speed:Float = 1;
+  public var size(default, set):Int = 48;
 
   public var funnyColor(default, set):Int = 0xFFFFFFFF;
 
-  public function new(x:Float, y:Float, text:String, widthShit:Float = 100)
+  public function new(x:Float, y:Float, text:String, widthShit:Float = 100, ?bold:Bool = false, ?size:Int = 48)
   {
     super(x, y);
 
     this.widthShit = widthShit;
+    if (size != null) this.size = size;
 
     grpTexts = new FlxTypedSpriteGroup<FlxText>();
     add(grpTexts);
 
-    var testText:FlxText = new FlxText(0, 0, 0, text, 48);
+    var testText:FlxText = new FlxText(0, 0, 0, text, this.size);
     testText.font = "5by7";
+    testText.bold = bold;
     testText.updateHitbox();
     grpTexts.add(testText);
 
-    var needed:Int = Math.ceil(widthShit / testText.frameWidth);
+    var needed:Int = Math.ceil(widthShit / testText.frameWidth) + 1;
 
     for (i in 0...needed)
     {
       var lmfao:Int = i + 1;
 
-      var coolText:FlxText = new FlxText((lmfao * testText.frameWidth) + (lmfao * 20), 0, 0, text, 48);
+      var coolText:FlxText = new FlxText((lmfao * testText.frameWidth) + (lmfao * 20), 0, 0, text, this.size);
+
       coolText.font = "5by7";
+      coolText.bold = bold;
       coolText.updateHitbox();
       grpTexts.add(coolText);
     }
   }
 
+  function set_size(value:Int):Int
+  {
+    if (grpTexts != null)
+    {
+      grpTexts.forEach(function(txt:FlxText) {
+        txt.size = value;
+      });
+    }
+    this.size = value;
+    return value;
+  }
+
   function set_funnyColor(col:Int):Int
   {
     grpTexts.forEach(function(txt) {
@@ -55,7 +73,7 @@ class BGScrollingText extends FlxSpriteGroup
     return col;
   }
 
-  override function update(elapsed:Float)
+  override public function update(elapsed:Float)
   {
     for (txt in grpTexts.group)
     {
@@ -66,14 +84,16 @@ class BGScrollingText extends FlxSpriteGroup
         if (txt.x < -txt.frameWidth)
         {
           txt.x = grpTexts.group.members[grpTexts.length - 1].x + grpTexts.group.members[grpTexts.length - 1].frameWidth + placementOffset;
+
           sortTextShit();
         }
       }
       else
       {
-        if (txt.x > widthShit)
+        if (txt.x > txt.frameWidth * 2)
         {
           txt.x = grpTexts.group.members[0].x - grpTexts.group.members[0].frameWidth - placementOffset;
+
           sortTextShit();
         }
       }
diff --git a/source/funkin/freeplayStuff/SongMenuItem.hx b/source/funkin/freeplayStuff/SongMenuItem.hx
index 596dfbed4..0f0521004 100644
--- a/source/funkin/freeplayStuff/SongMenuItem.hx
+++ b/source/funkin/freeplayStuff/SongMenuItem.hx
@@ -1,5 +1,6 @@
 package funkin.freeplayStuff;
 
+import funkin.shaderslmfao.HSVShader;
 import funkin.shaderslmfao.GaussianBlurShader;
 import flixel.group.FlxGroup;
 import flixel.FlxSprite;
@@ -41,6 +42,8 @@ class SongMenuItem extends FlxSpriteGroup
   public var onConfirm:Void->Void;
   public var diffGrayscale:Grayscale;
 
+  public var hsvShader(default, set):HSVShader;
+
   public function new(x:Float, y:Float, song:String, ?character:String)
   {
     super(x, y);
@@ -109,6 +112,15 @@ class SongMenuItem extends FlxSpriteGroup
     selected = selected; // just to kickstart the set_selected
   }
 
+  function set_hsvShader(value:HSVShader):HSVShader
+  {
+    this.hsvShader = value;
+    capsule.shader = hsvShader;
+    songText.shader = hsvShader;
+
+    return value;
+  }
+
   function textAppear()
   {
     songText.scale.x = 1.7;
diff --git a/source/funkin/shaderslmfao/BlendModesShader.hx b/source/funkin/shaderslmfao/BlendModesShader.hx
new file mode 100644
index 000000000..6807a65c0
--- /dev/null
+++ b/source/funkin/shaderslmfao/BlendModesShader.hx
@@ -0,0 +1,23 @@
+package funkin.shaderslmfao;
+
+import flixel.addons.display.FlxRuntimeShader;
+import funkin.Paths;
+import openfl.utils.Assets;
+import openfl.display.BitmapData;
+
+class BlendModesShader extends FlxRuntimeShader
+{
+  public var camera:BitmapData;
+
+  public function new()
+  {
+    super(Assets.getText(Paths.frag('blendModes')));
+  }
+
+  public function setCamera(camera:BitmapData):Void
+  {
+    this.camera = camera;
+
+    this.setBitmapData('camera', camera);
+  }
+}
diff --git a/source/funkin/ui/title/FlxSpriteOverlay.hx b/source/funkin/ui/title/FlxSpriteOverlay.hx
new file mode 100644
index 000000000..2e0ac987e
--- /dev/null
+++ b/source/funkin/ui/title/FlxSpriteOverlay.hx
@@ -0,0 +1,74 @@
+package funkin.ui.title;
+
+import flixel.FlxSprite;
+import funkin.shaderslmfao.BlendModesShader;
+import openfl.display.BitmapData;
+import flixel.FlxCamera;
+import flixel.FlxG;
+import flixel.graphics.frames.FlxFrame.FlxFrameAngle;
+
+class FlxSpriteOverlay extends FlxSprite
+{
+  var blendShader:BlendModesShader;
+  var dipshitBitmap:BitmapData;
+  var temp:FlxSprite;
+
+  public function new(x:Float, y:Float)
+  {
+    super(x, y);
+    temp = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, 0xFF000000);
+    blendShader = new BlendModesShader();
+    dipshitBitmap = new BitmapData(2180, 1720, true, 0xFFCC00CC);
+  }
+
+  override function drawComplex(camera:FlxCamera):Void
+  {
+    _frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, checkFlipX(), checkFlipY());
+    _matrix.translate(-origin.x, -origin.y);
+    _matrix.scale(scale.x, scale.y);
+    if (bakedRotationAngle <= 0)
+    {
+      updateTrig();
+      if (angle != 0) _matrix.rotateWithTrig(_cosAngle, _sinAngle);
+    }
+    getScreenPosition(_point, camera).subtractPoint(offset);
+    _point.add(origin.x, origin.y);
+    _matrix.translate(_point.x, _point.y);
+    if (isPixelPerfectRender(camera))
+    {
+      _matrix.tx = Math.floor(_matrix.tx);
+      _matrix.ty = Math.floor(_matrix.ty);
+    }
+
+    var sprRect = getScreenBounds();
+
+    dipshitBitmap.draw(camera.canvas, camera.canvas.transform.matrix);
+    blendShader.setCamera(dipshitBitmap);
+
+    FlxG.bitmapLog.add(dipshitBitmap);
+
+    camera.drawPixels(_frame, framePixels, _matrix, colorTransform, blend, antialiasing, blendShader);
+  }
+
+  function copyToFlash(rect):openfl.geom.Rectangle
+  {
+    var flashRect = new openfl.geom.Rectangle();
+    flashRect.x = rect.x;
+    flashRect.y = rect.y;
+    flashRect.width = rect.width;
+    flashRect.height = rect.height;
+    return flashRect;
+  }
+
+  override public function isSimpleRender(?camera:FlxCamera):Bool
+  {
+    if (FlxG.renderBlit)
+    {
+      return super.isSimpleRender(camera);
+    }
+    else
+    {
+      return false;
+    }
+  }
+}
diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx
index 313c578a3..9820e4ecc 100644
--- a/source/funkin/ui/title/TitleState.hx
+++ b/source/funkin/ui/title/TitleState.hx
@@ -23,6 +23,7 @@ import openfl.events.MouseEvent;
 import openfl.events.NetStatusEvent;
 import openfl.media.Video;
 import openfl.net.NetStream;
+import openfl.display.BlendMode;
 
 #if desktop
 #end
@@ -101,7 +102,7 @@ class TitleState extends MusicBeatState
   var logoBl:FlxSprite;
   var outlineShaderShit:TitleOutline;
 
-  var gfDance:FlxSprite;
+  var gfDance:FlxSpriteOverlay;
   var danceLeft:Bool = false;
   var titleText:FlxSprite;
   var maskShader = new LeftMaskShader();
@@ -124,13 +125,11 @@ class TitleState extends MusicBeatState
 
     outlineShaderShit = new TitleOutline();
 
-    gfDance = new FlxSprite(FlxG.width * 0.4, FlxG.height * 0.07);
+    gfDance = new FlxSpriteOverlay(FlxG.width * 0.4, FlxG.height * 0.07);
     gfDance.frames = Paths.getSparrowAtlas('gfDanceTitle');
     gfDance.animation.addByIndices('danceLeft', 'gfDance', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false);
     gfDance.animation.addByIndices('danceRight', 'gfDance', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false);
 
-    add(gfDance);
-
     // maskShader.swagSprX = gfDance.x;
     // maskShader.swagMaskX = gfDance.x + 200;
     // maskShader.frameUV = gfDance.frame.uv;
@@ -142,6 +141,8 @@ class TitleState extends MusicBeatState
 
     add(logoBl);
 
+    add(gfDance);
+
     titleText = new FlxSprite(100, FlxG.height * 0.8);
     titleText.frames = Paths.getSparrowAtlas('titleEnter');
     titleText.animation.addByPrefix('idle', "Press Enter to Begin", 24);
@@ -245,6 +246,8 @@ class TitleState extends MusicBeatState
 
   override function update(elapsed:Float)
   {
+    FlxG.bitmapLog.add(FlxG.camera.buffer);
+
     #if HAS_PITCH
     if (FlxG.keys.pressed.UP) FlxG.sound.music.pitch += 0.5 * elapsed;