1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2024-11-15 11:22:55 +00:00

add wip bizz

This commit is contained in:
CheemsAndFriends 2024-09-06 06:28:08 +02:00
parent 677357ba37
commit a61f40571d
4 changed files with 413 additions and 2 deletions

2
assets

@ -1 +1 @@
Subproject commit 74bd0131b705e87f9704c54a44d64579153ab4af
Subproject commit f73c8f4798bfcd23c98db03bcde2e0afcbce4cfd

View file

@ -0,0 +1,407 @@
package funkin.graphics;
import flixel.FlxBasic;
import flixel.FlxCamera;
import flixel.FlxG;
import flixel.FlxSprite;
import flixel.graphics.FlxGraphic;
import flixel.graphics.frames.FlxFrame;
import flixel.math.FlxMatrix;
import flixel.math.FlxPoint;
import flixel.math.FlxRect;
import flixel.util.FlxColor;
import lime.graphics.cairo.Cairo;
import openfl.display.BitmapData;
import openfl.display.BlendMode;
import openfl.display.DisplayObjectRenderer;
import openfl.display.Graphics;
import openfl.display.OpenGLRenderer;
import openfl.display._internal.Context3DGraphics;
import openfl.display3D.Context3D;
import openfl.display3D.Context3DClearMask;
import openfl.filters.BitmapFilter;
import openfl.filters.BlurFilter;
import openfl.geom.ColorTransform;
import openfl.geom.Matrix;
import openfl.geom.Point;
import openfl.geom.Rectangle;
#if (js && html5)
import lime._internal.graphics.ImageCanvasUtil;
import openfl.display.CanvasRenderer;
import openfl.display._internal.CanvasGraphics as GfxRenderer;
#else
import openfl.display.CairoRenderer;
import openfl.display._internal.CairoGraphics as GfxRenderer;
#end
/**
* A modified `FlxSprite` that supports filters.
* The name's pretty much self-explanatory.
* @author CheemsAndFriends
*/
@:access(openfl.geom.Rectangle)
@:access(openfl.filters.BitmapFilter)
@:access(flixel.graphics.frames.FlxFrame)
class FlxFilteredSprite extends FlxSprite
{
@:noCompletion var _renderer:FlxAnimateFilterRenderer = new FlxAnimateFilterRenderer();
@:noCompletion var _filterMatrix:FlxMatrix;
/**
* An `Array` of shader filters (aka `BitmapFilter`).
*/
public var filters(default, set):Array<BitmapFilter>;
/**
* a flag to update the image with the filters.
* Useful when trying to render a shader at all times.
*/
public var filterDirty:Bool = false;
@:noCompletion var filtered:Bool;
@:noCompletion var _blankFrame:FlxFrame;
var _filterBmp1:BitmapData;
var _filterBmp2:BitmapData;
override public function update(elapsed:Float)
{
super.update(elapsed);
if (!filterDirty && filters != null)
{
for (filter in filters)
{
if (filter.__renderDirty)
{
filterDirty = true;
break;
}
}
}
}
@:noCompletion
override function initVars():Void
{
super.initVars();
_filterMatrix = new FlxMatrix();
filters = null;
filtered = false;
}
override public function draw():Void
{
checkEmptyFrame();
if (alpha == 0 || _frame.type == FlxFrameType.EMPTY) return;
if (dirty) // rarely
calcFrame(useFramePixels);
if (filterDirty) filterFrame();
for (camera in cameras)
{
if (!camera.visible || !camera.exists || !isOnScreen(camera)) continue;
getScreenPosition(_point, camera).subtractPoint(offset);
if (isSimpleRender(camera)) drawSimple(camera);
else
drawComplex(camera);
#if FLX_DEBUG
FlxBasic.visibleCount++;
#end
}
#if FLX_DEBUG
if (FlxG.debugger.drawDebug) drawDebug();
#end
}
@:noCompletion
override function drawComplex(camera:FlxCamera):Void
{
_frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, checkFlipX(), checkFlipY());
_matrix.concat(_filterMatrix);
_matrix.translate(-origin.x, -origin.y);
_matrix.scale(scale.x, scale.y);
if (bakedRotationAngle <= 0)
{
updateTrig();
if (angle != 0) _matrix.rotateWithTrig(_cosAngle, _sinAngle);
}
_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);
}
camera.drawPixels(_frame, framePixels, _matrix, colorTransform, blend, antialiasing, shader);
}
@:noCompletion
function filterFrame()
{
filterDirty = false;
_filterMatrix.identity();
var filteredFrame = (filtered) ? _frame : null;
if (filters != null && filters.length > 0)
{
_flashRect.setEmpty();
for (filter in filters)
{
_flashRect.__expand(-filter.__leftExtension,
-filter.__topExtension, filter.__leftExtension
+ filter.__rightExtension,
filter.__topExtension
+ filter.__bottomExtension);
}
_flashRect.width += frameWidth;
_flashRect.height += frameHeight;
if (_blankFrame == null) _blankFrame = new FlxFrame(null);
if (_blankFrame.parent == null || _flashRect.width > _blankFrame.parent.width || _flashRect.height > _blankFrame.parent.height)
{
if (_blankFrame.parent != null)
{
_blankFrame.parent.destroy();
_filterBmp1.dispose();
_filterBmp2.dispose();
}
_blankFrame.parent = FlxGraphic.fromRectangle(Math.ceil(_flashRect.width * 1.25), Math.ceil(_flashRect.height * 1.25), 0, true);
_filterBmp1 = new BitmapData(_blankFrame.parent.width, _blankFrame.parent.height, 0);
_filterBmp2 = new BitmapData(_blankFrame.parent.width, _blankFrame.parent.height, 0);
}
_blankFrame.offset.copyFrom(_frame.offset);
_blankFrame.parent.bitmap = _renderer.applyFilter(_blankFrame.parent.bitmap, _filterBmp1, _filterBmp2, frame.parent.bitmap, filters, _flashRect,
frame.frame.copyToFlash());
_blankFrame.frame = FlxRect.get(0, 0, _blankFrame.parent.bitmap.width, _blankFrame.parent.bitmap.height);
_filterMatrix.translate(_flashRect.x, _flashRect.y);
_frame = _blankFrame.copyTo();
filtered = true;
}
else
{
resetFrame();
filtered = false;
}
}
@:noCompletion
function set_filters(value:Array<BitmapFilter>)
{
if (filters != value) filterDirty = true;
return filters = value;
}
@:noCompletion
override function set_frame(value:FlxFrame)
{
if (value != frame) filterDirty = true;
return super.set_frame(value);
}
}
@:noCompletion
@:access(openfl.display.OpenGLRenderer)
@:access(openfl.filters.BitmapFilter)
@:access(openfl.geom.Rectangle)
@:access(openfl.display.Stage)
@:access(openfl.display.Graphics)
@:access(openfl.display.Shader)
@:access(openfl.display.BitmapData)
@:access(openfl.geom.ColorTransform)
@:access(openfl.display.DisplayObject)
@:access(openfl.display3D.Context3D)
@:access(openfl.display.CanvasRenderer)
@:access(openfl.display.CairoRenderer)
@:access(openfl.display3D.Context3D)
class FlxAnimateFilterRenderer
{
var renderer:OpenGLRenderer;
var context:Context3D;
public function new()
{
// context = new openfl.display3D.Context3D(null);
renderer = new OpenGLRenderer(FlxG.game.stage.context3D);
renderer.__worldTransform = new Matrix();
renderer.__worldColorTransform = new ColorTransform();
}
@:noCompletion function setRenderer(renderer:DisplayObjectRenderer, rect:Rectangle)
{
@:privateAccess
if (true)
{
var displayObject = FlxG.game;
var pixelRatio = FlxG.game.stage.__renderer.__pixelRatio;
var offsetX = rect.x > 0 ? Math.ceil(rect.x) : Math.floor(rect.x);
var offsetY = rect.y > 0 ? Math.ceil(rect.y) : Math.floor(rect.y);
if (renderer.__worldTransform == null)
{
renderer.__worldTransform = new Matrix();
renderer.__worldColorTransform = new ColorTransform();
}
if (displayObject.__cacheBitmapColorTransform == null) displayObject.__cacheBitmapColorTransform = new ColorTransform();
renderer.__stage = displayObject.stage;
renderer.__allowSmoothing = true;
renderer.__setBlendMode(NORMAL);
renderer.__worldAlpha = 1 / displayObject.__worldAlpha;
renderer.__worldTransform.identity();
renderer.__worldTransform.invert();
renderer.__worldTransform.concat(new Matrix());
renderer.__worldTransform.tx -= offsetX;
renderer.__worldTransform.ty -= offsetY;
renderer.__worldTransform.scale(pixelRatio, pixelRatio);
renderer.__pixelRatio = pixelRatio;
}
}
public function applyFilter(target:BitmapData = null, target1:BitmapData = null, target2:BitmapData = null, bmp:BitmapData, filters:Array<BitmapFilter>,
rect:Rectangle, bmpRect:Rectangle)
{
if (filters == null || filters.length == 0) return bmp;
renderer.__setBlendMode(NORMAL);
renderer.__worldAlpha = 1;
if (renderer.__worldTransform == null)
{
renderer.__worldTransform = new Matrix();
renderer.__worldColorTransform = new ColorTransform();
}
renderer.__worldTransform.identity();
renderer.__worldColorTransform.__identity();
var bitmap:BitmapData = (target == null) ? new BitmapData(Math.ceil(rect.width * 1.25), Math.ceil(rect.height * 1.25), true, 0) : target;
var bitmap2 = (target1 == null) ? new BitmapData(Math.ceil(rect.width * 1.25), Math.ceil(rect.height * 1.25), true, 0) : target1,
bitmap3 = (target2 == null) ? bitmap2.clone() : target2;
renderer.__setRenderTarget(bitmap);
bmp.__renderTransform.translate(Math.abs(rect.x) - bmpRect.x, Math.abs(rect.y) - bmpRect.y);
bmpRect.x = Math.abs(rect.x);
bmpRect.y = Math.abs(rect.y);
var bestResolution = renderer.__context3D.__backBufferWantsBestResolution;
renderer.__context3D.__backBufferWantsBestResolution = false;
renderer.__scissorRect(bmpRect);
renderer.__renderFilterPass(bmp, renderer.__defaultDisplayShader, true);
renderer.__scissorRect();
renderer.__context3D.__backBufferWantsBestResolution = bestResolution;
bmp.__renderTransform.identity();
var shader, cacheBitmap = null;
for (filter in filters)
{
if (filter.__preserveObject)
{
renderer.__setRenderTarget(bitmap3);
renderer.__renderFilterPass(bitmap, renderer.__defaultDisplayShader, filter.__smooth);
}
for (i in 0...filter.__numShaderPasses)
{
shader = filter.__initShader(renderer, i, (filter.__preserveObject) ? bitmap3 : null);
renderer.__setBlendMode(filter.__shaderBlendMode);
renderer.__setRenderTarget(bitmap2);
renderer.__renderFilterPass(bitmap, shader, filter.__smooth);
cacheBitmap = bitmap;
bitmap = bitmap2;
bitmap2 = cacheBitmap;
}
filter.__renderDirty = false;
}
if (target1 == null) bitmap2.dispose();
if (target2 == null) bitmap3.dispose();
return bitmap;
}
public function applyBlend(blend:BlendMode, bitmap:BitmapData)
{
bitmap.__update(false, true);
var bmp = new BitmapData(bitmap.width, bitmap.height, 0);
#if (js && html5)
ImageCanvasUtil.convertToCanvas(bmp.image);
@:privateAccess
var renderer = new CanvasRenderer(bmp.image.buffer.__srcContext);
#else
var renderer = new CairoRenderer(new Cairo(bmp.getSurface()));
#end
// setRenderer(renderer, bmp.rect);
var m = new Matrix();
var c = new ColorTransform();
renderer.__allowSmoothing = true;
renderer.__overrideBlendMode = blend;
renderer.__worldTransform = m;
renderer.__worldAlpha = 1;
renderer.__worldColorTransform = c;
renderer.__setBlendMode(blend);
#if (js && html5)
bmp.__drawCanvas(bitmap, renderer);
#else
bmp.__drawCairo(bitmap, renderer);
#end
return bitmap;
}
public function graphicstoBitmapData(gfx:Graphics)
{
if (gfx.__bounds == null) return null;
// var cacheRTT = renderer.__context3D.__state.renderToTexture;
// var cacheRTTDepthStencil = renderer.__context3D.__state.renderToTextureDepthStencil;
// var cacheRTTAntiAlias = renderer.__context3D.__state.renderToTextureAntiAlias;
// var cacheRTTSurfaceSelector = renderer.__context3D.__state.renderToTextureSurfaceSelector;
// var bmp = new BitmapData(Math.ceil(gfx.__width), Math.ceil(gfx.__height), 0);
// renderer.__context3D.setRenderToTexture(bmp.getTexture(renderer.__context3D));
// gfx.__owner.__renderTransform.identity();
// gfx.__renderTransform.identity();
// Context3DGraphics.render(gfx, renderer);
GfxRenderer.render(gfx, cast renderer.__softwareRenderer);
var bmp = gfx.__bitmap;
gfx.__bitmap = null;
// if (cacheRTT != null)
// {
// renderer.__context3D.setRenderToTexture(cacheRTT, cacheRTTDepthStencil, cacheRTTAntiAlias, cacheRTTSurfaceSelector);
// }
// else
// {
// renderer.__context3D.setRenderToBackBuffer();
// }
return bmp;
}
}

View file

@ -1,12 +1,13 @@
package funkin.ui;
import flixel.FlxSprite;
import funkin.graphics.FlxFilteredSprite;
/**
* The icon that gets used for Freeplay capsules and char select
* NOT to be confused with the CharIcon class, which is for the in-game icons
*/
class PixelatedIcon extends FlxSprite
class PixelatedIcon extends FlxFilteredSprite
{
public function new(x:Float, y:Float)
{

View file

@ -16,6 +16,7 @@ import funkin.audio.FunkinSound;
import funkin.data.freeplay.player.PlayerData;
import funkin.data.freeplay.player.PlayerRegistry;
import funkin.graphics.adobeanimate.FlxAtlasSprite;
import openfl.filters.DropShadowFilter;
import funkin.graphics.FunkinCamera;
import funkin.modding.events.ScriptEvent;
import funkin.modding.events.ScriptEventDispatcher;
@ -672,6 +673,7 @@ class CharSelectSubState extends MusicBeatSubState
if (index == getCurrentSelected())
{
// memb.pixels = memb.withDropShadow.clone();
if (memb.scale.x != 2.6) memb.filters = [new DropShadowFilter()];
memb.scale.set(2.6, 2.6);
if (controls.ACCEPT) memb.animation.play("confirm");
@ -687,6 +689,7 @@ class CharSelectSubState extends MusicBeatSubState
else
{
// memb.pixels = memb.noDropShadow.clone();
if (memb.scale.x == 2) memb.filters = [];
memb.scale.set(2, 2);
}
}