Merge remote-tracking branch 'dev/main'

This commit is contained in:
⍚~Nex
2024-03-11 03:23:50 +01:00
82 changed files with 1851 additions and 364 deletions
+25 -4
View File
@@ -64,8 +64,7 @@ class Update {
break;
} else if (curHaxeVer[i] > requiredHaxeVer[i]) {
prettyPrint("!! WARNING !!"
+ "\nHaxeFlixel has incompability issues with the latest version of Haxe, 4.3.0 and above, due to macros."
+ "\nProceeding will cause compilation issues related to macros (ex: cannot access flash package in macro)");
+ "\nUsing Haxe 4.3.0 and above is currently not recommended due to lack of testing.");
Sys.println('');
Sys.println('We recommend downgrading back to 4.2.5.');
break;
@@ -75,14 +74,36 @@ class Update {
}
public static function prettyPrint(text:String) {
var lines = text.split("\n");
var length = -1;
for(line in lines)
if(line.length > length)
length = line.length;
var header = "══════";
for(i in 0...(text.length-(text.lastIndexOf("\n")+1)))
for(i in 0...length)
header += "═";
Sys.println("");
Sys.println('╔$header╗');
Sys.println('║ $text ║');
for(line in lines) {
Sys.println('║ ${centerText(line, length)} ║');
}
Sys.println('╚$header╝');
}
public static function centerText(text:String, width:Int):String {
var centerOffset = (width - text.length) / 2;
var left = repeat(' ', Math.floor(centerOffset));
var right = repeat(' ', Math.ceil(centerOffset));
return left + text + right;
}
public static inline function repeat(ch:String, amt:Int) {
var str = "";
for(i in 0...amt)
str += ch;
return str;
}
}
typedef Library = {
+2 -13
View File
@@ -96,17 +96,9 @@
<!-- _________________________________ Engine Settings _______________________________ -->
<!-- Comment this out to disable multiple windows for editors !-->
<define name="ALLOW_MULTITASKING" />
<define name="openfl_dpi_aware" />
<!-- Comment this out to disable updates !-->
<!-- <define name="UPDATE_CHECKING" unless="web || hl || neko"/> -->
<!-- Fixes thing with macros -->
<define name="HL" if="hl"/>
<define name="SYS" if="cpp || hl || neko"/>
<!-- Comment this out to disable Discord RPC !-->
<section if="cpp">
<define name="DISCORD_RPC" if="desktop"/>
@@ -144,9 +136,6 @@
<!-- Comment this out to disable support for custom ndlls. !-->
<haxedef name="NDLLS_SUPPORTED" unless="web || iphonesim" />
<!-- Comment this out to disable support for custom extended classes (data/classes). !-->
<define name="SOFTCODED_CLASSES" />
<!-- Comment this out to disable support for Away3D Flixel Intergration (reduces compile times)-->
<define name="THREE_D_SUPPORT" />
@@ -190,10 +179,10 @@
<section if="COMPILE_ALL_CLASSES">
<haxeflag name="-dce" value="no" />
<haxeflag name="--macro" value="funkin.backend.system.macros.ScriptsMacro.addAdditionalClasses()" />
<haxeflag name="--macro" value="funkin.backend.system.macros.Macros.addAdditionalClasses()" />
</section>
<haxeflag name="--macro" value="exclude('funkin.backend.system.updating')" unless="UPDATE_CHECKING"/>
<haxeflag name="--macro" value="funkin.backend.system.macros.Macros.initMacros()" />
<!-- Fix compiling issues -->
<setenv name="HAXEPATH" value="./"/>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,127 @@
package away3d.materials.methods;
import away3d.core.managers.Stage3DProxy;
import away3d.materials.compilation.ShaderRegisterCache;
import away3d.materials.compilation.ShaderRegisterElement;
import away3d.textures.Texture2DBase;
import openfl.display.BlendMode;
import openfl.errors.Error;
/**
* LightMapMethod provides a method that allows applying a light map texture to the calculated pixel colour.
* It is different from LightMapDiffuseMethod in that the latter only modulates the diffuse shading value rather
* than the whole pixel colour.
*/
class LightMapMethod extends EffectMethodBase
{
public var blendMode(get, set):BlendMode;
public var texture(get, set):Texture2DBase;
/**
* Indicates the light map should be multiplied with the calculated shading result.
*/
public static inline var MULTIPLY:BlendMode = BlendMode.MULTIPLY;
/**
* Indicates the light map should be added into the calculated shading result.
*/
public static var ADD:BlendMode = BlendMode.ADD;
private var _texture:Texture2DBase;
private var _blendMode:BlendMode;
private var _useSecondaryUV:Bool;
/**
* Creates a new LightMapMethod object.
* @param texture The texture containing the light map.
* @param blendMode The blend mode with which the light map should be applied to the lighting result.
* @param useSecondaryUV Indicates whether the secondary UV set should be used to map the light map.
*/
public function new(texture:Texture2DBase, blendMode:BlendMode = MULTIPLY, useSecondaryUV:Bool = false)
{
super();
_useSecondaryUV = useSecondaryUV;
_texture = texture;
this.blendMode = blendMode;
}
/**
* @inheritDoc
*/
override private function initVO(vo:MethodVO):Void
{
vo.needsUV = !_useSecondaryUV;
vo.needsSecondaryUV = _useSecondaryUV;
}
/**
* The blend mode with which the light map should be applied to the lighting result.
*
* @see LightMapMethod.ADD
* @see LightMapMethod.MULTIPLY
*/
private function get_blendMode():BlendMode
{
return _blendMode;
}
private function set_blendMode(value:BlendMode):BlendMode
{
if (value != ADD && value != MULTIPLY)
throw new Error("Unknown blendmode!");
if (_blendMode == value)
return value;
_blendMode = value;
invalidateShaderProgram();
return value;
}
/**
* The texture containing the light map.
*/
private function get_texture():Texture2DBase
{
return _texture;
}
private function set_texture(value:Texture2DBase):Texture2DBase
{
if (value.hasMipMaps != _texture.hasMipMaps || value.format != _texture.format)
invalidateShaderProgram();
_texture = value;
return value;
}
/**
* @inheritDoc
*/
override private function activate(vo:MethodVO, stage3DProxy:Stage3DProxy):Void
{
stage3DProxy._context3D.setTextureAt(vo.texturesIndex, _texture.getTextureForStage3D(stage3DProxy));
super.activate(vo, stage3DProxy);
}
/**
* @inheritDoc
*/
override private function getFragmentCode(vo:MethodVO, regCache:ShaderRegisterCache, targetReg:ShaderRegisterElement):String
{
var code:String;
var lightMapReg:ShaderRegisterElement = regCache.getFreeTextureReg();
var temp:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp();
vo.texturesIndex = lightMapReg.index;
code = getTex2DSampleCode(vo, temp, lightMapReg, _texture, _useSecondaryUV? _sharedRegisters.secondaryUVVarying : _sharedRegisters.uvVarying);
switch (_blendMode) {
case BlendMode.MULTIPLY:
code += "mul " + targetReg + ", " + targetReg + ", " + temp + "\n";
case BlendMode.ADD:
code += "add " + targetReg + ", " + targetReg + ", " + temp + "\n";
default:
}
return code;
}
}
+1 -2
View File
@@ -13,8 +13,7 @@ import flixel.math.FlxRect;
import flixel.math.FlxPoint;
import funkin.backend.system.interfaces.IBeatReceiver;
@:enum
abstract XMLAnimType(Int)
enum abstract XMLAnimType(Int)
{
var NONE = 0;
var BEAT = 1;
-1
View File
@@ -1,6 +1,5 @@
package funkin.backend;
import flixel.addons.transition.FlxTransitionableState;
import funkin.backend.system.framerate.Framerate;
import funkin.backend.system.GraphicCacheSprite;
import funkin.backend.system.Controls;
@@ -6,7 +6,6 @@ import funkin.backend.scripting.Script;
import funkin.backend.scripting.ScriptPack;
import funkin.backend.scripting.DummyScript;
import funkin.backend.system.interfaces.IBeatReceiver;
import funkin.backend.system.Conductor.BPMChangeEvent;
import funkin.backend.system.Conductor;
import funkin.backend.system.Controls;
import funkin.options.PlayerSettings;
@@ -15,7 +15,7 @@ class ModdableAssetsFolder extends ModsFolderLibrary {
return super.exists(id, type);
}
public override function getAsset(id:String, type:String) {
public override function getAsset(id:String, type:String):Dynamic {
if (!id.startsWith("assets/")) {
var possibleReplacement = getAsset('assets/$id', type);
if (possibleReplacement != null)
@@ -45,7 +45,9 @@ class HScript extends Script {
this.trace(v);
}));
#if GLOBAL_SCRIPT
funkin.backend.scripting.GlobalScript.call("onScriptCreated", [this, "hscript"]);
#end
loadFromString(code);
}
@@ -30,8 +30,7 @@ final class PlayAnimEvent extends CancellableEvent {
/**
Contains all contexts possible for `PlayAnimEvent`.
**/
@:enum
abstract PlayAnimContext(String) {
enum abstract PlayAnimContext(String) {
/**
No context was given for the animation.
The character won't dance until the animation is finished
@@ -1,17 +1,10 @@
package funkin.backend.system;
import funkin.backend.chart.Chart;
import funkin.backend.chart.ChartData;
import openfl.Lib;
import flixel.FlxState;
import funkin.backend.system.interfaces.IBeatReceiver;
import flixel.util.FlxSignal.FlxTypedSignal;
/**
* ...
* @author
*/
typedef BPMChangeEvent =
{
var stepTime:Float;
+1 -2
View File
@@ -1,7 +1,6 @@
package funkin.backend.system;
@:enum
abstract ErrorCode(Int) {
enum abstract ErrorCode(Int) {
var OK = 0;
var FAILED = 1;
var MISSING_PROPERTY = 2;
-10
View File
@@ -4,26 +4,17 @@ import funkin.editors.SaveWarning;
import funkin.backend.assets.AssetsLibraryList;
import funkin.backend.system.framerate.SystemInfo;
import openfl.utils.AssetLibrary;
import openfl.utils.AssetCache;
import openfl.text.TextFormat;
import flixel.system.ui.FlxSoundTray;
import funkin.backend.utils.NativeAPI;
import funkin.menus.BetaWarningState;
import funkin.menus.TitleState;
import flixel.FlxGame;
import flixel.FlxState;
import openfl.Assets;
import openfl.Lib;
import openfl.display.FPS;
import openfl.display.Sprite;
import openfl.events.Event;
import flixel.graphics.FlxGraphic;
import flixel.addons.transition.FlxTransitionableState;
import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
import flixel.addons.transition.TransitionData;
import flixel.math.FlxPoint;
import flixel.math.FlxRect;
import lime.app.Application;
import funkin.backend.system.modules.*;
#if ALLOW_MULTITHREADING
@@ -78,7 +69,6 @@ class Main extends Sprite
#if (!mobile && !web)
addChild(framerateSprite = new funkin.backend.system.framerate.Framerate());
framerateSprite.scaleX = framerateSprite.scaleY = stage.window.scale;
SystemInfo.init();
#end
}
@@ -125,8 +125,7 @@ typedef GitHubUser = {
var updated_at:String;
}
@:enum
abstract GitHubUserType(String) {
enum abstract GitHubUserType(String) {
var USER = "User";
var ORGANIZATION = "Organization";
}
@@ -1,9 +1,7 @@
package funkin.backend.system.macros;
#if macro
import sys.io.Process;
import haxe.macro.Context;
import haxe.macro.Compiler;
import haxe.macro.Expr;
#end
@@ -1,6 +1,9 @@
package funkin.backend.system.macros;
#if macro
import haxe.macro.Context;
import haxe.macro.Expr;
/**
* Macro that generates all additional fields, making events much easier to code in.
* It adds the `recycle` function, which allows you to "reset" an event's values.
@@ -19,7 +22,6 @@ class EventMacro {
if (f.name == "recycle")
return fields;
// gets all fields
var values:Array<EventVar> = [];
var hiddenValues:Array<EventVar> = [];
@@ -48,8 +50,8 @@ class EventMacro {
// add recycle option
var func:Function = {
args: [for(a in values) {
value: a.expr,
type: a.type,
value: a.expr,
type: a.type,
opt: false,
name: a.name
}],
@@ -87,7 +89,7 @@ class EventMacro {
})
});
}
// add a "set this" expr to reset each private/hidden variables
for(v in hiddenValues) {
var name = v.name;
@@ -1,6 +1,9 @@
package funkin.backend.system.macros;
#if macro
import haxe.macro.Context;
import haxe.macro.Expr;
/**
* Macro that automatically generates flush and load functions.
*/
@@ -13,7 +16,6 @@ class FunkinSaveMacro {
* @return Array<Field>
*/
public static function build(saveFieldName:String = "save", saveFuncName:String = "flush", loadFuncName:String = "load"):Array<Field> {
var fields:Array<Field> = Context.getBuildFields();
var fieldNames:Array<String> = [];
@@ -1,17 +1,8 @@
package funkin.backend.system.macros;
#if macro
import haxe.macro.Type.ClassType;
import Type.ValueType;
import haxe.macro.Expr.Function;
import haxe.macro.Expr;
import haxe.macro.Type.MetaAccess;
import haxe.macro.Type.FieldKind;
import haxe.macro.Type.ClassField;
import haxe.macro.Type.VarAccess;
import haxe.macro.*;
import Sys;
import haxe.io.Path;
using StringTools;
using haxe.macro.PositionTools;
@@ -30,12 +21,12 @@ class HashLinkFixer {
public static function init() {
#if !display
#if HL
for(apply in applyOn) {
compile(apply);
if(Context.defined("hl")) {
for(apply in applyOn) {
compile(apply);
}
}
#end
#end
}
public static function compile(name:String) {
@@ -1,14 +1,13 @@
package funkin.backend.system.macros;
#if macro
import haxe.macro.Context;
import haxe.macro.Compiler;
import haxe.macro.*;
import haxe.macro.Expr;
/**
* Macros containing additional help functions to expand HScript capabilities.
*/
class ScriptsMacro {
class Macros {
public static function addAdditionalClasses() {
for(inc in [
// FLIXEL
@@ -27,19 +26,25 @@ class ScriptsMacro {
])
Compiler.include(inc);
for(inc in [#if SYS "sys", "openfl.net", "funkin.backend.system.net" #end]) {
#if !HL
Compiler.include(inc);
#else
// TODO: Hashlink
//Compiler.include(inc, ["sys.net.UdpSocket", "openfl.net.DatagramSocket"]); // fixes FATAL ERROR : Failed to load function std@socket_set_broadcast
#end
var isHl = Context.defined("hl");
if(Context.defined("sys")) {
for(inc in ["sys", "openfl.net", "funkin.backend.system.net"]) {
if(!isHl)
Compiler.include(inc);
else {
// TODO: Hashlink
//Compiler.include(inc, ["sys.net.UdpSocket", "openfl.net.DatagramSocket"]); // fixes FATAL ERROR : Failed to load function std@socket_set_broadcast
}
}
}
Compiler.include("funkin", #if !UPDATE_CHECKING ['funkin.backend.system.updating'] #end);
Compiler.include("funkin", [#if !UPDATE_CHECKING 'funkin.backend.system.updating' #end]);
}
#if HL HashLinkFixer.init(); #end
// Todo rewrite this to use if(Context.defined(""))
public static function initMacros() {
if(Context.defined("hl"))
HashLinkFixer.init();
}
}
#end
@@ -6,7 +6,7 @@ class NewHaxeWarning {
#if (haxe >= "4.3.0")
Sys.println("====================");
Sys.println("[ WARNING ]");
Sys.println("Compiling with Haxe 4.3.0 or above CAN and WILL end up in compilation errors due to changes in macros.");
Sys.println("Compiling with Haxe 4.3.0 isnt fully recommended yet, but it does work.");
Sys.println("We recommend building the project using Haxe 4.2.5.");
Sys.println("You can download it here -> https://haxe.org/download/version/4.2.5/");
Sys.println("====================");
@@ -1,8 +1,10 @@
package funkin.backend.system.macros;
#if macro
using StringTools;
import haxe.macro.Context;
import haxe.macro.Expr;
using StringTools;
/**
* Macro used in the options class to add getters for the SOLO keybinds.
+2 -1
View File
@@ -1,7 +1,8 @@
package funkin.backend.system.macros;
#if macro
import haxe.macro.Expr.ExprDef;
import haxe.macro.Context;
import haxe.macro.Expr;
#end
class Utils {
@@ -1,4 +0,0 @@
#if macro
import haxe.macro.*;
import haxe.macro.Expr;
#end
@@ -185,8 +185,7 @@ class UpdaterProgress {
public function new() {}
}
@:enum
abstract UpdaterStep(Int) {
enum abstract UpdaterStep(Int) {
var PREPARING = 0;
var DOWNLOADING_ASSETS = 1;
var DOWNLOADING_EXECUTABLE = 2;
+7 -7
View File
@@ -15,9 +15,9 @@ class AudioAnalyzer {
__peakByte = Math.pow(2, buffer.bitsPerSample-1)-1;
__timeMulti = 1 / (1 / buffer.sampleRate);
__timeMulti *= buffer.bitsPerSample;
__timeMulti -= __timeMulti % buffer.bitsPerSample;
__timeMulti = 1 / (1 / buffer.sampleRate);
__timeMulti *= buffer.bitsPerSample;
__timeMulti -= __timeMulti % buffer.bitsPerSample;
}
public function analyze(startPos:Float, endPos:Float):Float {
@@ -25,16 +25,16 @@ class AudioAnalyzer {
var bytesEndPos:Int = Math.floor(endPos * __timeMulti / 4000 / buffer.bitsPerSample) * buffer.bitsPerSample;
bytesStartPos -= bytesStartPos % buffer.bitsPerSample;
bytesEndPos -= bytesEndPos % buffer.bitsPerSample;
bytesEndPos -= bytesEndPos % buffer.bitsPerSample;
var maxByte:Int = 0;
for(i in 0...Math.floor((bytesEndPos - bytesStartPos) / buffer.bitsPerSample)) {
var byte:Int = buffer.data.buffer.get(bytesStartPos + (i * buffer.bitsPerSample))
var byte:Int = buffer.data.buffer.get(bytesStartPos + (i * buffer.bitsPerSample))
| (buffer.data.buffer.get(bytesStartPos + (i * buffer.bitsPerSample) + 1) << 8);
if (byte > 256 * 128) byte -= 256 * 256;
if (maxByte < byte) maxByte = byte;
}
return maxByte/__peakByte;
return maxByte/__peakByte;
}
}
-5
View File
@@ -1,7 +1,6 @@
package funkin.backend.utils;
import flixel.text.FlxText;
import openfl.text.TextFormatAlign;
import funkin.backend.utils.XMLUtil.TextFormat;
import flixel.tweens.FlxTween;
import flixel.system.frontEnds.SoundFrontEnd;
@@ -9,7 +8,6 @@ import flixel.sound.FlxSound;
import funkin.backend.system.Conductor;
import flixel.sound.FlxSoundGroup;
import haxe.Json;
import funkin.menus.StoryMenuState.WeekData;
import haxe.io.Path;
import haxe.xml.Access;
import flixel.input.keyboard.FlxKey;
@@ -17,10 +15,7 @@ import lime.utils.Assets;
import flixel.animation.FlxAnimation;
import flixel.util.FlxColor;
import flixel.util.FlxAxes;
import flixel.graphics.frames.FlxFrame;
import flixel.graphics.frames.FlxFramesCollection;
import openfl.geom.ColorTransform;
import funkin.backend.chart.Chart;
import haxe.CallStack;
using StringTools;
+2 -2
View File
@@ -3,8 +3,8 @@ package funkin.backend.utils;
import funkin.backend.utils.native.*;
/**
* Class for Windows-only functions, such as transparent windows, message boxes, and more.
* Does not have any effect on other platforms.
* Class for functions that talk to a lower level than haxe, such as message boxes, and more.
* Some functions might not have effect on some platforms.
*/
class NativeAPI {
@:dox(hide) public static function registerAudio() {
@@ -1,7 +1,7 @@
package funkin.backend.utils.native;
import funkin.backend.utils.NativeAPI.MessageBoxIcon;
#if windows
import funkin.backend.utils.NativeAPI.MessageBoxIcon;
@:buildXml('
<target id="haxe">
<lib name="dwmapi.lib" if="windows" />
@@ -12,7 +12,7 @@ import funkin.backend.utils.NativeAPI.MessageBoxIcon;
</target>
')
// majority is taken from microsofts doc
// majority is taken from microsofts doc
@:cppFileCode('
#include "mmdeviceapi.h"
#include "combaseapi.h"
@@ -36,7 +36,7 @@ static long lastDefId = 0;
class AudioFixClient : public IMMNotificationClient {
LONG _cRef;
IMMDeviceEnumerator *_pEnumerator;
public:
AudioFixClient() :
_cRef(1),
@@ -153,9 +153,9 @@ class Windows {
public static function allocConsole() {
}
@:functionCode('
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(console, color);
')
public static function setConsoleColors(color:Int) {
@@ -175,7 +175,7 @@ class Windows {
MessageBox(GetActiveWindow(), message, caption, icon | MB_SETFOREGROUND);
')
public static function showMessageBox(caption:String, message:String, icon:MessageBoxIcon = MSG_WARNING) {
}
@:functionCode('
-1
View File
@@ -1,6 +1,5 @@
package funkin.editors;
import flixel.addons.transition.FlxTransitionableState;
import flixel.math.FlxPoint;
import flixel.effects.FlxFlicker;
-3
View File
@@ -5,9 +5,6 @@ import sys.io.File;
#end
import haxe.io.Path;
import lime.ui.FileDialog;
import openfl.net.FileReference;
import openfl.events.Event;
import openfl.events.IOErrorEvent;
class SaveSubstate extends MusicBeatSubstate {
public var saveOptions:Map<String, Bool>;
@@ -5,9 +5,7 @@ import haxe.xml.Printer;
import haxe.xml.Access;
import funkin.backend.utils.XMLUtil.AnimData;
import flixel.math.FlxPoint;
import flixel.animation.FlxAnimation;
import funkin.editors.ui.UIContextMenu.UIContextMenuOption;
import flixel.input.keyboard.FlxKey;
import funkin.game.Character;
class CharacterEditor extends UIState {
@@ -3,7 +3,6 @@ package funkin.editors.charter;
import flixel.text.FlxText.FlxTextFormat;
import flixel.text.FlxText.FlxTextFormatMarkerPair;
import funkin.backend.shaders.CustomShader;
import flixel.math.FlxRect;
import funkin.game.Character;
import funkin.game.Stage;
import funkin.game.HealthIcon;
+76 -48
View File
@@ -1,7 +1,5 @@
package funkin.editors.charter;
import openfl.geom.Rectangle;
import flixel.util.FlxSpriteUtil;
import funkin.editors.ui.UIContextMenu.UIContextMenuOptionSpr;
import funkin.editors.ui.UITopMenu.UITopMenuButton;
import funkin.editors.charter.CharterStrumline;
@@ -10,20 +8,14 @@ import funkin.backend.system.framerate.Framerate;
import haxe.Json;
import flixel.input.keyboard.FlxKey;
import flixel.sound.FlxSound;
import flixel.util.FlxSort;
import flixel.math.FlxPoint;
import funkin.editors.charter.CharterBackdropGroup.CharterBackdropDummy;
import funkin.backend.system.Conductor;
import funkin.backend.chart.*;
import funkin.backend.chart.ChartData;
import openfl.display.BitmapData;
import flixel.util.FlxColor;
import flixel.addons.display.FlxBackdrop;
import funkin.editors.ui.UIContextMenu.UIContextMenuOption;
import funkin.editors.ui.UIState;
import openfl.net.FileReference;
using flixel.util.FlxColor;
class Charter extends UIState {
public static var __song:String;
@@ -59,7 +51,7 @@ class Charter extends UIState {
public var addEventSpr:CharterEventAdd;
public var gridBackdropDummy:CharterBackdropDummy;
public var noteHoverer:CharterNote;
public var noteHoverer:CharterNoteHoverer;
public var strumlineInfoBG:FlxSprite;
public var strumlineAddButton:CharterStrumlineButton;
@@ -549,7 +541,6 @@ class Charter extends UIState {
for(e in eventsGroup.members)
e.refreshEventIcons();
buildNoteTypesUI();
refreshBPMSensitive();
@@ -580,47 +571,45 @@ class Charter extends UIState {
* NOTE AND CHARTER GRID LOGIC HERE
*/
#if REGION
var gridActionType:CharterGridActionType = NONE;
var dragStartPos:FlxPoint = new FlxPoint();
var selectionDragging:Bool = false;
public var gridActionType:CharterGridActionType = NONE;
public var dragStartPos:FlxPoint = new FlxPoint();
public var mousePos:FlxPoint = new FlxPoint();
public var selectionDragging:Bool = false;
public function updateSelectionLogic() {
function select(s:ICharterSelectable) {
if (FlxG.keys.pressed.CONTROL) selection.push(s);
else if (FlxG.keys.pressed.SHIFT) selection.remove(s);
else selection = [s];
}
public function updateNoteLogic(elapsed:Float) {
for (group in [notesGroup, eventsGroup]) {
cast(group, FlxTypedGroup<Dynamic>).forEach(function(n) {
n.selected = false;
if (n.hovered && gridActionType == NONE) {
if (FlxG.mouse.justReleased) {
if (FlxG.keys.pressed.CONTROL)
selection.push(cast n);
else if (FlxG.keys.pressed.SHIFT)
selection.remove(cast n);
else
selection = [cast n];
}
if (FlxG.mouse.justReleasedRight) {
var mousePos = FlxG.mouse.getScreenPosition(uiCamera);
if (!selection.contains(cast n))
selection = [cast n];
closeCurrentContextMenu();
openContextMenu(topMenu[1].childs, null, mousePos.x, mousePos.y);
mousePos.put();
}
cast(group, FlxTypedGroup<Dynamic>).forEach(function(s) {
s.selected = false;
if (gridActionType == NONE) {
if (s is CharterNote) {
var n:CharterNote = cast s;
if ((n.hovered || n.sustainDraggable) && FlxG.mouse.justReleased) select(cast s);
} else if (FlxG.mouse.justReleased && s.hovered) select(cast s);
}
});
}
selection = __fixSelection(selection);
for(s in selection) s.selected = true;
}
public function updateNoteLogic(elapsed:Float) {
updateSelectionLogic();
/**
* NOTE DRAG HANDLING
*/
var mousePos = FlxG.mouse.getWorldPosition(charterCamera);
mousePos = FlxG.mouse.getWorldPosition(charterCamera);
if (!gridBackdropDummy.hoveredByChild && !FlxG.mouse.pressed)
gridActionType = NONE;
selectionBox.visible = false;
switch(gridActionType) {
case BOX:
case BOX_SELECTION:
if (gridBackdropDummy.hoveredByChild) {
selectionBox.visible = true;
if (FlxG.mouse.pressed) {
@@ -655,7 +644,7 @@ class Charter extends UIState {
// do nothing, locked
if (!FlxG.mouse.pressed)
gridActionType = NONE;
case DRAG:
case NOTE_DRAG:
selectionDragging = FlxG.mouse.pressed;
if (selectionDragging) {
gridBackdrops.draggingObj = null;
@@ -718,7 +707,7 @@ class Charter extends UIState {
if (gridBackdropDummy.hovered) {
// AUTO DETECT
if (FlxG.mouse.pressed && (Math.abs(mousePos.x - dragStartPos.x) > 20 || Math.abs(mousePos.y - dragStartPos.y) > 20))
gridActionType = BOX;
gridActionType = BOX_SELECTION;
var id = Math.floor(mousePos.x / 40);
var mouseOnGrid = id >= 0 && id < 4 * gridBackdrops.strumlinesAmount && mousePos.y >= 0;
@@ -739,14 +728,21 @@ class Charter extends UIState {
}
}
} else if (gridBackdropDummy.hoveredByChild) {
if (FlxG.mouse.pressed && (Math.abs(mousePos.x - dragStartPos.x) > 5 || Math.abs(mousePos.y - dragStartPos.y) > 5)) {
if (FlxG.mouse.pressed) {
var noteHovered:Bool = false;
for(n in selection)
if (n.hovered) {
noteHovered = true;
break;
}
gridActionType = noteHovered ? DRAG : INVALID_DRAG;
for(n in selection) if (n.hovered) {noteHovered = true; break;}
var noteSusDrag:Bool = false;
for(s in selection) {
if (!(s is CharterNote)) continue;
var n:CharterNote = cast s;
if (n.sustainDraggable) {noteSusDrag = true; break;}
}
if ((Math.abs(mousePos.x - dragStartPos.x) > (noteSusDrag ? 1 : 5) || Math.abs(mousePos.y - dragStartPos.y) > (noteSusDrag ? 1 : 5))) {
if (noteHovered) gridActionType = noteHovered ? NOTE_DRAG : INVALID_DRAG;
if (noteSusDrag) gridActionType = SUSTAIN_DRAG;
}
}
}
@@ -756,6 +752,35 @@ class Charter extends UIState {
openContextMenu(topMenu[1].childs, null, mousePos.x, mousePos.y);
mousePos.put();
}
case SUSTAIN_DRAG:
selectionDragging = FlxG.mouse.pressed;
if (selectionDragging) {
currentCursor = BUTTON;
selection.loop(function (n:CharterNote) {
var change:Float = Math.max((mousePos.y-(FlxG.keys.pressed.SHIFT ? dragStartPos.y : quantStep(dragStartPos.y))) / 40, -n.susLength);
n.tempSusLength = change;
if (!FlxG.keys.pressed.SHIFT)
n.tempSusLength -= (n.susLength + change) - quantStepRounded(n.susLength + change, change > 0 ? 0.35 : 0.65);
@:privateAccess n.__susInstaLerp = FlxG.keys.pressed.SHIFT;
});
} else {
var undoChanges:Array<NoteSustainChange> = [];
selection.loop(function (n:CharterNote) {
var oldSusLen:Float = n.susLength;
n.susLength += n.tempSusLength;
n.tempSusLength = 0;
@:privateAccess n.__susInstaLerp = false;
n.updatePos(n.step, n.id, n.susLength, n.type);
undoChanges.push({before: oldSusLen, after: n.susLength, note: n});
});
undos.addToUndo(CEditSustains(undoChanges));
gridActionType = NONE;
currentCursor = ARROW;
}
}
addEventSpr.selectable = !selectionBox.visible;
@@ -769,6 +794,8 @@ class Charter extends UIState {
if (event != null) addEventSpr.updateEdit(event);
else addEventSpr.updatePos(FlxG.keys.pressed.SHIFT ? ((mousePos.y) / 40) : quantStepRounded(mousePos.y/40));
} else addEventSpr.sprAlpha = lerp(addEventSpr.sprAlpha, 0, 0.25);
noteHoverer.showHoverer = Charter.instance.gridBackdropDummy.hovered;
}
public function quantStep(step:Float):Float {
@@ -1475,7 +1502,7 @@ class Charter extends UIState {
if (s is CharterNote) {
var n:CharterNote = cast s;
var old:Float = n.susLength;
n.updatePos(n.step, n.id, Math.max(n.susLength + change, 0));
n.updatePos(n.step, n.id, Math.max(n.susLength + change, 0), n.type);
undoChanges.push({before: old, after: n.susLength, note: n});
}
@@ -1783,9 +1810,10 @@ interface ICharterSelectable {
enum abstract CharterGridActionType(Int) {
var NONE = 0;
var BOX = 1;
var DRAG = 2;
var BOX_SELECTION = 1;
var NOTE_DRAG = 2;
var INVALID_DRAG = 3;
var SUSTAIN_DRAG = 4;
}
typedef PlaytestInfo = {
@@ -1,6 +1,5 @@
package funkin.editors.charter;
import flixel.util.FlxPool;
import flixel.graphics.FlxGraphic;
import funkin.backend.system.Conductor;
import openfl.geom.Rectangle;
+25 -17
View File
@@ -9,6 +9,9 @@ import flixel.util.FlxColor;
class CharterNote extends UISprite implements ICharterSelectable {
var angleTween:FlxTween;
var __doAnim:Bool = false;
var __animSpeed:Float = 1;
var __susInstaLerp:Bool = false;
private static var colors:Array<FlxColor> = [
0xFFC24B99,
@@ -17,10 +20,11 @@ class CharterNote extends UISprite implements ICharterSelectable {
0xFFF9393F
];
public var sustainSpr:FlxSprite;
public var sustainSpr:UISprite;
public var tempSusLength:Float = 0;
public var sustainDraggable:Bool = false;
public var typeText:UIText;
var __doAnim:Bool = false;
var __animSpeed:Float = 1;
public var selected:Bool = false;
public var draggable:Bool = true;
@@ -34,15 +38,15 @@ class CharterNote extends UISprite implements ICharterSelectable {
animation.play("note");
this.setUnstretchedGraphicSize(40, 40, false);
cursor = BUTTON;
moves = false;
sustainSpr = new FlxSprite(10, 40);
sustainSpr.makeGraphic(1, 1, -1);
sustainSpr = new UISprite(10, 20);
sustainSpr.makeSolid(1, 1, -1);
sustainSpr.scale.set(10, 0);
members.push(sustainSpr);
typeText = new UIText(x, y, 0, Std.string(type));
//typeText.borderSize = 1.5;
cursor = sustainSpr.cursor = BUTTON;
moves = false;
}
public override function updateButtonHandler() {
@@ -82,12 +86,6 @@ class CharterNote extends UISprite implements ICharterSelectable {
y = step * 40;
sustainSpr.scale.set(10, (40 * susLength) + (height/2));
sustainSpr.updateHitbox();
sustainSpr.exists = susLength != 0;
sustainSpr.alpha = alpha;
sustainSpr.follow(this, 15, 20);
if (angleTween != null) angleTween.cancel();
var destAngle = switch(animation.curAnim.curFrame = (id % 4)) {
@@ -134,8 +132,18 @@ class CharterNote extends UISprite implements ICharterSelectable {
var __passed:Bool = false;
public override function update(elapsed:Float) {
super.update(elapsed);
if (sustainSpr.exists)
sustainSpr.follow(this, 15, 20);
var sprLength:Float = (40 * (susLength+tempSusLength)) + ((susLength+tempSusLength) != 0 ? (height/2) : 0);
sustainSpr.scale.set(10, __susInstaLerp ? sprLength : CoolUtil.fpsLerp(sustainSpr.scale.y, sprLength, 1/2));
sustainSpr.updateHitbox();
sustainSpr.follow(this, 15, 20);
sustainDraggable = false;
if (!hovered && susLength != 0) {
UIState.state.updateSpriteRect(sustainSpr);
sustainDraggable = UIState.state.isOverlapping(sustainSpr, @:privateAccess sustainSpr.__rect);
}
if (typeText.exists)
typeText.follow(this, 20 - (typeText.frameWidth/2), 20 - (typeText.frameHeight/2));
@@ -1,6 +1,8 @@
package funkin.editors.charter;
class CharterNoteHoverer extends CharterNote {
public var showHoverer:Bool = false;
public function new() {
super();
@@ -15,7 +17,7 @@ class CharterNoteHoverer extends CharterNote {
switch (Charter.instance.gridActionType) {
case NONE:
var inBoundsY:Bool = (__mousePos.y > 0 && __mousePos.y < (Charter.instance.__endStep)*40);
if (__mousePos.x > 0 && __mousePos.x < Charter.instance.gridBackdrops.strumlinesAmount * 160 && inBoundsY) {
if ((__mousePos.x > 0 && __mousePos.x < Charter.instance.gridBackdrops.strumlinesAmount * 160 && inBoundsY) && showHoverer) {
step = FlxMath.bound(FlxG.keys.pressed.SHIFT ? ((__mousePos.y-20) / 40) : Charter.instance.quantStep(__mousePos.y/40), 0, Charter.instance.__endStep-1);
id = Math.floor(__mousePos.x / 40); y = step * 40; x = id * 40; visible = true; sustainSpr.visible = typeText.visible = false;
angle = switch(animation.curAnim.curFrame = (id % 4)) {
@@ -27,7 +29,7 @@ class CharterNoteHoverer extends CharterNote {
};
} else
visible = false;
case DRAG:
case NOTE_DRAG:
visible = sustainSpr.visible = typeText.visible = true; __doAnim = false;
default:
visible = sustainSpr.visible = typeText.visible = false; __doAnim = false;
@@ -38,8 +40,8 @@ class CharterNoteHoverer extends CharterNote {
switch (Charter.instance.gridActionType) {
case NONE:
super.draw();
case DRAG:
if (Charter.instance.gridActionType == DRAG) {
case NOTE_DRAG:
if (Charter.instance.gridActionType == NOTE_DRAG) {
var verticalChange:Float = (__mousePos.y - Charter.instance.dragStartPos.y) / 40;
var horizontalChange:Int = CoolUtil.floorInt((__mousePos.x - (Std.int(Charter.instance.dragStartPos.x / 40) * 40)) / 40);
@@ -3,11 +3,9 @@ package funkin.editors.charter;
import funkin.backend.chart.ChartData;
import funkin.backend.chart.ChartData.ChartMetaData;
import haxe.Json;
import funkin.backend.assets.ModsFolder;
import funkin.editors.charter.SongCreationScreen.SongCreationData;
import funkin.options.type.NewOption;
import funkin.backend.system.framerate.Framerate;
import flixel.util.FlxColor;
import funkin.menus.FreeplayState.FreeplaySonglist;
import funkin.editors.EditorTreeMenu;
import funkin.options.*;
@@ -1,6 +1,5 @@
package funkin.editors.charter;
import funkin.backend.chart.ChartData.ChartStrumLine;
import funkin.backend.chart.EventsData;
import flixel.util.FlxSort;
@@ -1,9 +1,7 @@
package funkin.editors.charter;
import flixel.group.FlxSpriteGroup;
import funkin.backend.chart.EventsData;
import funkin.game.Character;
import funkin.editors.ui.UIContextMenu.UIContextMenuOption;
import funkin.editors.ui.UITopMenu.UITopMenuButton;
import funkin.game.HealthIcon;
import funkin.backend.chart.ChartData.ChartStrumLine;
@@ -3,7 +3,7 @@ package funkin.editors.charter;
import flixel.text.FlxText.FlxTextFormat;
import flixel.text.FlxText.FlxTextFormatMarkerPair;
import flixel.group.FlxGroup;
import funkin.backend.chart.ChartData;
import funkin.backend.chart.ChartData.ChartMetaData;
import haxe.io.Bytes;
typedef SongCreationData = {
+3 -1
View File
@@ -1,6 +1,8 @@
#if !macro
package funkin.editors;
import funkin.editors.ui.*;
import flixel.math.FlxPoint;
using funkin.editors.ui.UIUtil;
using funkin.editors.ui.UIUtil;
#end
@@ -3,7 +3,6 @@ package funkin.editors.ui;
import flixel.math.FlxRect;
import flixel.util.FlxColor;
import flixel.ui.FlxBar;
import openfl.geom.Rectangle;
import flixel.sound.FlxSound;
import haxe.io.Bytes;
import lime.media.AudioBuffer;
@@ -1,10 +1,7 @@
package funkin.editors.ui;
import flixel.math.FlxPoint;
import lime.ui.KeyModifier;
import lime.ui.KeyCode;
import openfl.desktop.Clipboard;
import openfl.geom.Rectangle;
class UIAutoCompleteTextBox extends UITextBox {
public var suggestionText:UIText;
-2
View File
@@ -1,7 +1,5 @@
package funkin.editors.ui;
import flixel.graphics.frames.FlxFrame;
class UIButton extends UISliceSprite {
public var callback:Void->Void = null;
public var field:UIText;
-3
View File
@@ -1,10 +1,7 @@
package funkin.editors.ui;
import flixel.FlxCamera;
import flixel.group.FlxGroup;
import flixel.util.FlxColor;
import flixel.math.FlxPoint;
import funkin.game.Character;
import flixel.util.FlxSort;
import flixel.math.FlxMath;
-2
View File
@@ -1,7 +1,5 @@
package funkin.editors.ui;
import funkin.backend.FunkinText;
class UICheckbox extends UISprite {
public var checked:Bool = false;
public var onChecked:Bool->Void = null;
-1
View File
@@ -2,7 +2,6 @@ package funkin.editors.ui;
import lime.ui.KeyModifier;
import lime.ui.KeyCode;
import openfl.events.KeyboardEvent;
import funkin.backend.system.framerate.Framerate;
import funkin.editors.ui.UIContextMenu.UIContextMenuCallback;
import openfl.ui.Mouse;
-3
View File
@@ -4,10 +4,7 @@ import funkin.editors.charter.Charter;
import funkin.backend.scripting.events.GameOverCreationEvent;
import funkin.backend.scripting.events.CancellableEvent;
import funkin.backend.scripting.Script;
import flixel.addons.transition.FlxTransitionableState;
import flixel.sound.FlxSound;
import flixel.FlxSubState;
import flixel.math.FlxPoint;
import flixel.util.FlxColor;
import flixel.util.FlxTimer;
import funkin.menus.StoryMenuState;
-24
View File
@@ -1,31 +1,7 @@
package funkin.game;
import lime.app.Application;
import flixel.graphics.tile.FlxGraphicsShader;
import openfl.display.Bitmap;
import openfl.display.BitmapData;
import openfl.display.DisplayObject;
import openfl.display.Graphics;
import openfl.display.Sprite;
import openfl.geom.ColorTransform;
import openfl.geom.Point;
import openfl.geom.Rectangle;
import flixel.graphics.FlxGraphic;
import flixel.graphics.frames.FlxFrame;
import flixel.graphics.tile.FlxDrawBaseItem;
import flixel.graphics.tile.FlxDrawTrianglesItem;
import flixel.math.FlxMatrix;
import flixel.math.FlxPoint;
import flixel.math.FlxRect;
import flixel.system.FlxAssets.FlxShader;
import flixel.util.FlxAxes;
import flixel.util.FlxColor;
import flixel.util.FlxSpriteUtil;
import openfl.display.BlendMode;
import openfl.filters.BitmapFilter;
import openfl.filters.ShaderFilter;
import openfl.Vector;
class HudCamera extends FlxCamera {
public var downscroll:Bool = false;
+1 -4
View File
@@ -1,11 +1,8 @@
package funkin.game;
import funkin.backend.chart.Chart;
import funkin.backend.chart.ChartData;
import flixel.graphics.frames.FlxAtlasFrames;
import flixel.util.FlxColor;
import flixel.math.FlxRect;
import flixel.math.FlxPoint;
import flixel.math.FlxRect;
import funkin.backend.system.Conductor;
import funkin.backend.scripting.events.*;
+1 -4
View File
@@ -2,7 +2,6 @@ package funkin.game;
import funkin.editors.charter.CharterSelection;
import flixel.FlxState;
import funkin.editors.EditorTreeMenu;
import funkin.editors.SaveWarning;
import funkin.backend.chart.EventsData;
import funkin.backend.system.RotatingSpriteGroup;
@@ -15,11 +14,9 @@ import funkin.game.SplashHandler;
import funkin.backend.scripting.DummyScript;
import funkin.menus.StoryMenuState.WeekData;
import funkin.backend.FunkinText;
import flixel.group.FlxSpriteGroup;
import funkin.backend.scripting.Script;
import funkin.backend.scripting.ScriptPack;
import flixel.FlxSubState;
import flixel.addons.transition.FlxTransitionableState;
import flixel.math.FlxPoint;
import flixel.sound.FlxSound;
import flixel.text.FlxText;
@@ -762,7 +759,7 @@ class PlayState extends MusicBeatState
SaveWarning.warningFunc = saveWarn;
SaveWarning.saveFunc = () -> {
@:privateAccess Chart.save('${Paths.getAssetsRoot()}/songs/${Charter.__song.toLowerCase()}',
PlayState.SONG, Charter.__diff.toLowerCase(), {saveMetaInChart: false});
PlayState.SONG, Charter.__diff.toLowerCase(), {saveMetaInChart: false, saveEventsInChart: true});
}
}
}
-1
View File
@@ -3,7 +3,6 @@ package funkin.game;
import funkin.backend.scripting.events.StageXMLEvent;
import funkin.backend.scripting.events.StageNodeEvent;
import flixel.math.FlxPoint;
import funkin.backend.MusicBeatGroup;
import flixel.FlxState;
import haxe.xml.Access;
import funkin.backend.system.interfaces.IBeatReceiver;
-1
View File
@@ -1,6 +1,5 @@
package funkin.menus;
import flixel.addons.transition.FlxTransitionableState;
import flixel.util.FlxColor;
import flixel.text.FlxText;
import funkin.backend.FunkinText;
+3 -9
View File
@@ -1,17 +1,14 @@
package funkin.menus;
import funkin.backend.chart.Chart;
import funkin.backend.chart.ChartData;
import funkin.backend.chart.ChartData.ChartMetaData;
import haxe.io.Path;
import openfl.text.TextField;
import flixel.FlxState;
import flixel.addons.display.FlxGridOverlay;
import flixel.text.FlxText;
import flixel.util.FlxColor;
import lime.utils.Assets;
import funkin.game.HealthIcon;
import funkin.savedata.FunkinSave;
import haxe.Json;
import funkin.backend.scripting.events.*;
using StringTools;
@@ -411,17 +408,14 @@ class FreeplayState extends MusicBeatState
var event = event("onUpdateOptionsAlpha", EventManager.get(FreeplayAlphaUpdateEvent).recycle(0.6, 0.45, 1, 1, 0.25));
if (event.cancelled) return;
var bullShit:Int = 0;
for (i in 0...iconArray.length)
iconArray[i].alpha = lerp(iconArray[i].alpha, #if PRELOAD_ALL songInstPlaying ? event.idlePlayingAlpha : #end event.idleAlpha, event.lerp);
iconArray[curSelected].alpha = #if PRELOAD_ALL songInstPlaying ? event.selectedPlayingAlpha : #end event.selectedAlpha;
for (item in grpSongs.members)
for (i=>item in grpSongs.members)
{
item.targetY = bullShit - curSelected;
bullShit++;
item.targetY = i - curSelected;
item.alpha = lerp(item.alpha, #if PRELOAD_ALL songInstPlaying ? event.idlePlayingAlpha : #end event.idleAlpha, event.lerp);
-1
View File
@@ -1,7 +1,6 @@
package funkin.menus;
import funkin.editors.charter.Charter;
import flixel.graphics.frames.FlxAtlasFrames;
class GitarooPause extends MusicBeatState
{
-2
View File
@@ -4,9 +4,7 @@ import haxe.Json;
import funkin.backend.FunkinText;
import funkin.menus.credits.CreditsMain;
import flixel.FlxState;
import flixel.addons.transition.FlxTransitionableState;
import flixel.effects.FlxFlicker;
import flixel.graphics.frames.FlxAtlasFrames;
import flixel.text.FlxText;
import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
+2 -8
View File
@@ -6,9 +6,6 @@ import funkin.options.OptionsMenu;
import funkin.backend.scripting.events.PauseCreationEvent;
import funkin.backend.scripting.events.NameEvent;
import funkin.backend.scripting.Script;
import flixel.FlxSubState;
import flixel.addons.transition.FlxTransitionableState;
import flixel.input.keyboard.FlxKey;
import flixel.sound.FlxSound;
import flixel.text.FlxText;
import flixel.tweens.FlxTween;
@@ -194,12 +191,9 @@ class PauseSubState extends MusicBeatSubstate
curSelected = event.value;
var bullShit:Int = 0;
for (item in grpMenuShit.members)
for (i=>item in grpMenuShit.members)
{
item.targetY = bullShit - curSelected;
bullShit++;
item.targetY = i - curSelected;
if (item.targetY == 0)
item.alpha = 1;
+1 -2
View File
@@ -5,7 +5,6 @@ import haxe.io.Path;
import funkin.backend.scripting.events.*;
import flixel.util.FlxTimer;
import flixel.math.FlxPoint;
import flixel.graphics.frames.FlxFramesCollection;
import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
import funkin.backend.FunkinText;
@@ -37,7 +36,7 @@ class StoryMenuState extends MusicBeatState {
public var weekSprites:FlxTypedGroup<MenuItem>;
public var characterSprites:FlxTypedGroup<MenuCharacterSprite>;
public var charFrames:Map<String, FlxFramesCollection> = [];
//public var charFrames:Map<String, FlxFramesCollection> = [];
public override function create() {
super.create();
-15
View File
@@ -1,27 +1,12 @@
package funkin.menus;
import funkin.backend.system.github.GitHub;
import funkin.backend.MusicBeatGroup;
import funkin.backend.utils.XMLUtil;
import flixel.util.typeLimit.OneOfThree;
import flixel.util.typeLimit.OneOfTwo;
import flixel.FlxState;
import flixel.addons.display.FlxGridOverlay;
import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
import flixel.addons.transition.FlxTransitionableState;
import flixel.graphics.FlxGraphic;
import flixel.graphics.frames.FlxAtlasFrames;
import flixel.group.FlxGroup;
import flixel.input.gamepad.FlxGamepad;
import flixel.math.FlxPoint;
import flixel.math.FlxRect;
import flixel.sound.FlxSound;
import flixel.system.ui.FlxSoundTray;
import flixel.text.FlxText;
import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
import flixel.util.FlxTimer;
import funkin.backend.system.Conductor;
import openfl.Assets;
import haxe.xml.Access;
@@ -1,6 +1,5 @@
package funkin.menus.credits;
import funkin.backend.system.github.GitHub;
import funkin.options.OptionsScreen;
import funkin.options.type.*;
import funkin.options.TreeMenu;
-1
View File
@@ -4,7 +4,6 @@ import openfl.utils.AssetLibrary;
import haxe.xml.Access;
import funkin.backend.assets.LimeLibrarySymbol;
import funkin.backend.assets.IModsAssetLibrary;
import flixel.graphics.frames.FlxAtlasFrames;
import flixel.group.FlxSpriteGroup;
import flixel.util.FlxTimer;
import flixel.util.FlxColor;
-1
View File
@@ -1,6 +1,5 @@
package funkin.options;
import funkin.backend.system.Controls;
import openfl.Lib;
import flixel.util.FlxSave;
import flixel.input.keyboard.FlxKey;
-3
View File
@@ -3,9 +3,6 @@ package funkin.options;
import funkin.backend.system.framerate.Framerate;
import funkin.options.type.Checkbox;
import haxe.xml.Access;
import flixel.tweens.FlxTween;
import funkin.menus.MainMenuState;
import flixel.util.typeLimit.OneOfTwo;
import funkin.options.type.*;
import funkin.options.categories.*;
import funkin.options.TreeMenu;
+3 -4
View File
@@ -3,10 +3,9 @@ package funkin.options;
class OptionsTree extends FlxTypedGroup<OptionsScreen> {
public var lastMenu:OptionsScreen;
public var treeParent:TreeMenu;
public override function new() {
super();
}
//public override function new() {
// super();
//}
public override function update(elapsed:Float) {
var last = members.last();
+1 -4
View File
@@ -29,9 +29,6 @@ class PlayerSettings
public var controls:Controls;
#end
// public var avatar:Player;
// public var camera(get, never):PlayCamera;
function new(id, scheme)
{
this.id = id;
@@ -42,7 +39,7 @@ class PlayerSettings
{
controls.setKeyboardScheme(scheme);
}
static public function init():Void
{
if (solo == null)
-2
View File
@@ -5,10 +5,8 @@ import flixel.FlxState;
import funkin.backend.FunkinText;
import flixel.tweens.FlxTween;
import funkin.menus.MainMenuState;
import funkin.options.type.TextOption;
import flixel.util.typeLimit.OneOfTwo;
import funkin.options.type.OptionType;
import funkin.options.categories.*;
class TreeMenu extends UIState {
public var main:OptionsScreen;
@@ -48,9 +48,8 @@ class AppearanceOptions extends OptionsScreen {
"If checked, switching windows will pause the game.",
"autoPause"));
}
private function __changeFPS(change:Float)
{
private function __changeFPS(change:Float) {
// if statement cause of the flixel warning
if(FlxG.updateFramerate < Std.int(change))
FlxG.drawFramerate = FlxG.updateFramerate = Std.int(change);
@@ -1,9 +1,13 @@
package funkin.options.categories;
import flixel.util.FlxTimer;
import funkin.backend.system.Conductor;
class GameplayOptions extends OptionsScreen {
var __metronome = FlxG.sound.load(Paths.sound('editors/charter/metronome'));
var offsetSetting:NumOption;
public override function new() {
super("Gameplay", 'Change Gameplay options such as Downscroll, Scroll Speed, Naughtyness...');
add(new Checkbox(
@@ -14,7 +18,7 @@ class GameplayOptions extends OptionsScreen {
"Ghost Tapping",
"If unchecked, trying to hit any strum that have no note that can be hit will cause a miss.",
"ghostTapping"));
add(new NumOption(
add(offsetSetting = new NumOption(
"Song Offset",
"Changes the offset that songs should start with.",
-999, // minimum
@@ -31,23 +35,39 @@ class GameplayOptions extends OptionsScreen {
"If unchecked, will stop the camera from zooming in every 4 beats",
"camZoomOnBeat"));
}
private function __changeOffset(offset) Conductor.songOffset = offset;
private function __changeOffset(offset)
Conductor.songOffset = offset;
var __lastBeat:Int = 0;
var __lastSongBeat:Int = 0;
override function update(elapsed) {
super.update(elapsed);
FlxG.camera.zoom = CoolUtil.fpsLerp(FlxG.camera.zoom, 1, 0.04);
if (members[2].selected) {
if (offsetSetting.selected) {
FlxG.sound.music.volume = 0.5;
if (__lastBeat != Conductor.curBeat) {
FlxG.camera.zoom += 0.03;
__lastBeat = Conductor.curBeat;
}
if (__lastSongBeat != Math.floor(Conductor.getStepForTime(FlxG.sound.music.time) / Conductor.stepsPerBeat)) {
var beat = Math.floor(Conductor.getStepForTime(FlxG.sound.music.time) / Conductor.stepsPerBeat);
if (__lastSongBeat != beat) {
__metronome.replay();
__lastSongBeat = Math.floor(Conductor.getStepForTime(FlxG.sound.music.time) / Conductor.stepsPerBeat);
__lastSongBeat = beat;
}
}
else FlxG.sound.music.volume = 1;
}
public override function close() {
// To remove this timer move super.update(elapsed); to the end, but im afraid it will cause stuff to break
new FlxTimer().start(0.0000001, (_) -> {
FlxG.camera.zoom = 1;
FlxG.sound.music.volume = 1;
});
super.close();
}
}
+3 -1
View File
@@ -1,3 +1,5 @@
#if !macro
package funkin.options.categories;
import funkin.options.type.*;
import funkin.options.type.*;
#end
@@ -1,9 +1,5 @@
package funkin.options.keybinds;
import flixel.effects.FlxFlicker;
import funkin.backend.system.Controls;
import flixel.addons.transition.FlxTransitionableState;
import flixel.util.FlxColor;
import flixel.input.keyboard.FlxKey;
class ChangeKeybindSubState extends MusicBeatSubstate {
@@ -27,7 +23,7 @@ class ChangeKeybindSubState extends MusicBeatSubstate {
if (cast(key, Int) <= 0) return;
if (key == ESCAPE && !FlxG.keys.pressed.SHIFT) {
close();
close();
cancelCallback();
return;
}
@@ -1,9 +1,6 @@
package funkin.options.keybinds;
import flixel.effects.FlxFlicker;
import funkin.backend.system.Controls;
import flixel.addons.transition.FlxTransitionableState;
import flixel.util.FlxColor;
import flixel.input.keyboard.FlxKey;
using StringTools;
@@ -1,9 +1,6 @@
package funkin.options.keybinds;
import funkin.backend.system.Controls;
import flixel.addons.transition.FlxTransitionableState;
import flixel.util.FlxColor;
import flixel.input.keyboard.FlxKey;
using StringTools;
+6 -13
View File
@@ -1,7 +1,5 @@
package funkin.options.type;
import flixel.effects.FlxFlicker;
class ArrayOption extends OptionType {
public var selectCallback:String->Void;
@@ -31,17 +29,12 @@ class ArrayOption extends OptionType {
this.parent = parent;
if(Reflect.field(parent, optionName) != null)
{
if(options.indexOf(Reflect.field(parent, optionName)) != -1)
this.currentSelection = options.indexOf(Reflect.field(parent, optionName));
else
this.currentSelection = 0;
}
var fieldValue = Reflect.field(parent, optionName);
if(fieldValue != null)
this.currentSelection = Std.int(Math.max(0, options.indexOf(fieldValue)));
this.optionName = optionName;
add(__text = new Alphabet(100, 20, text, true));
add(__selectiontext = new Alphabet(__text.width + 120, -30, formatTextOption(), false));
}
@@ -52,7 +45,7 @@ class ArrayOption extends OptionType {
public override function onChangeSelection(change:Float):Void
{
if(currentSelection <= 0 && change == -1 || currentSelection >= options.length - 1 && change == 1 ) return;
if(currentSelection <= 0 && change == -1 || currentSelection >= options.length - 1 && change == 1) return;
currentSelection += Math.round(change);
__selectiontext.text = formatTextOption();
Reflect.setField(parent, optionName, options[currentSelection]);
-1
View File
@@ -2,7 +2,6 @@ package funkin.options.type;
import flixel.math.FlxPoint;
@:allow()
class Checkbox extends TextOption {
public var checkbox:FlxSprite;
@@ -1,6 +1,5 @@
package funkin.options.type;
import funkin.game.HealthIcon;
import flixel.util.FlxColor;
class EditorIconOption extends IconOption {
-1
View File
@@ -2,7 +2,6 @@ package funkin.options.type;
import funkin.backend.system.Controls;
import flixel.group.FlxSpriteGroup;
import funkin.options.OptionsScreen;
class OptionType extends FlxSpriteGroup {
public var controls(get, null):Controls;
@@ -108,7 +108,7 @@ class NativeWindow
#if (!macro && lime_cffi)
handle = NativeCFFI.lime_window_create(parent.application.__backend.handle, width, height, flags, title);
#if DARK_MODE_WINDOW
#if (DARK_MODE_WINDOW && !macro)
funkin.backend.utils.NativeAPI.setDarkMode(title, true);
#end
@@ -727,7 +727,7 @@ class NativeWindow
}
}
@:enum private abstract MouseCursorType(Int) from Int to Int
enum abstract MouseCursorType(Int) from Int to Int
{
var HIDDEN = 0;
var ARROW = 1;
@@ -744,7 +744,7 @@ class NativeWindow
var WAIT_ARROW = 12;
}
@:enum private abstract WindowFlags(Int)
enum abstract WindowFlags(Int)
{
var WINDOW_FLAG_FULLSCREEN = 0x00000001;
var WINDOW_FLAG_BORDERLESS = 0x00000002;
+2 -2
View File
@@ -533,7 +533,7 @@ class System
@:noCompletion private static function __registerEntryPoint(projectName:String, entryPoint:Function):Void
{
// executes first!!
#if sys
#if (sys && !macro)
funkin.backend.utils.NativeAPI.registerAsDPICompatible();
funkin.backend.system.CommandLineHandler.parseCommandLine(Sys.args());
#end
@@ -824,7 +824,7 @@ class System
}
}
@:enum private abstract SystemDirectory(Int) from Int to Int from UInt to UInt
enum abstract SystemDirectory(Int) from Int to Int from UInt to UInt
{
var APPLICATION = 0;
var APPLICATION_STORAGE = 1;
+22 -2
View File
@@ -1,7 +1,9 @@
package lime.utils;
import haxe.PosInfos;
#if !macro
import funkin.backend.system.Logs as FunkinLogs;
#end
#if !lime_debug
@:fileXml('tags="haxe,release"')
@@ -30,14 +32,23 @@ class Log
{
var message = '[${info.className}] $message';
#if !macro
FunkinLogs.trace(message, ERROR, RED);
#else
trace(message);
#end
}
}
public static function info(message:Dynamic, ?info:PosInfos):Void
{
if (level >= LogLevel.INFO)
if (level >= LogLevel.INFO) {
#if !macro
FunkinLogs.trace('[${info.className}] $message', INFO, RED);
#else
trace('[${info.className}] $message');
#end
}
}
public static inline function print(message:Dynamic):Void
@@ -68,15 +79,24 @@ class Log
public static function verbose(message:Dynamic, ?info:PosInfos):Void
{
if (level >= LogLevel.VERBOSE)
if (level >= LogLevel.VERBOSE) {
#if !macro
FunkinLogs.trace('[${info.className}] $message', VERBOSE);
#else
trace('[${info.className}] $message');
#end
}
}
public static function warn(message:Dynamic, ?info:PosInfos):Void
{
if (level >= LogLevel.WARN)
{
#if !macro
FunkinLogs.trace('[${info.className}] $message', WARNING, YELLOW);
#else
trace('[${info.className}] $message');
#end
}
}
+70 -24
View File
@@ -27,6 +27,7 @@ import openfl.utils._internal.UInt8Array;
import openfl.utils.AGALMiniAssembler;
import openfl.utils.ByteArray;
#if lime
import lime.graphics.opengl.GL;
import lime.graphics.Image;
import lime.graphics.ImageBuffer;
import lime.graphics.RenderContext;
@@ -271,7 +272,7 @@ import lime.math.Vector2;
@:noCompletion private var __enableErrorChecking:Bool;
@:noCompletion private var __fragmentConstants:Float32Array;
@:noCompletion private var __frontBufferTexture:RectangleTexture;
@:noCompletion private var __positionScale:Float32Array;
@:noCompletion private var __positionScale:Float32Array; // TODO: Better approach?
@:noCompletion private var __present:Bool;
@:noCompletion private var __programs:Map<String, Program3D>;
@:noCompletion private var __quadIndexBuffer:IndexBuffer3D;
@@ -291,7 +292,11 @@ import lime.math.Vector2;
__stage3D = stage3D;
__context = stage.window.context;
#if (js && html5 && dom)
gl = GL.context;
#else
gl = __context.webgl;
#end
if (__contextState == null) __contextState = new Context3DState();
__state = new Context3DState();
@@ -575,6 +580,14 @@ import lime.math.Vector2;
public function configureBackBuffer(width:Int, height:Int, antiAlias:Int, enableDepthAndStencil:Bool = true, wantsBestResolution:Bool = false,
wantsBestResolutionOnBrowserZoom:Bool = false):Void
{
#if !openfl_dpi_aware
if (wantsBestResolution)
{
width = Std.int(width * __stage.window.scale);
height = Std.int(height * __stage.window.scale);
}
#end
if (__stage3D == null)
{
backBufferWidth = width;
@@ -600,7 +613,16 @@ import lime.math.Vector2;
__stage3D.__vertexBuffer = createVertexBuffer(4, 5);
}
var vertexData = new Vector<Float>([width, height, 0, 1, 1, 0, height, 0, 0, 1, width, 0, 0, 1, 0, 0, 0, 0, 0, 0.0]);
#if openfl_dpi_aware
var scaledWidth = width;
var scaledHeight = height;
#else
var scaledWidth = wantsBestResolution ? width : Std.int(width * __stage.window.scale);
var scaledHeight = wantsBestResolution ? height : Std.int(height * __stage.window.scale);
#end
var vertexData = new Vector<Float>([
scaledWidth, scaledHeight, 0, 1, 1, 0, scaledHeight, 0, 0, 1, scaledWidth, 0, 0, 1, 0, 0, 0, 0, 0, 0.0
]);
__stage3D.__vertexBuffer.uploadFromVector(vertexData, 0, 20);
@@ -1000,6 +1022,8 @@ import lime.math.Vector2;
**/
public function dispose(recreate:Bool = true):Void
{
// TODO: Dispose all related buffers
gl = null;
__dispose();
}
@@ -1172,12 +1196,14 @@ import lime.math.Vector2;
#if !openfl_disable_display_render
if (__state.renderToTexture == null)
{
// TODO: Make sure state is correct for this?
if (__stage.context3D == this && !__stage.__renderer.__cleared)
{
__stage.__renderer.__clear();
}
else if (!__cleared)
{
// TODO: Throw error if error reporting is enabled?
clear(0, 0, 0, 0, 1, 0, Context3DClearMask.COLOR);
}
}
@@ -1223,7 +1249,7 @@ import lime.math.Vector2;
if (!__cleared)
{
// Make sure texture is initialized
// BASE-TODO: Throw error if error reporting is enabled?
// TODO: Throw error if error reporting is enabled?
clear(0, 0, 0, 0, 1, 0, Context3DClearMask.COLOR);
}
@@ -1284,7 +1310,7 @@ import lime.math.Vector2;
__state.blendSourceAlphaFactor = sourceAlphaFactor;
__state.blendDestinationAlphaFactor = destinationAlphaFactor;
// BASE-TODO: Better way to handle this?
// TODO: Better way to handle this?
__setGLBlendEquation(gl.FUNC_ADD);
}
@@ -1363,7 +1389,7 @@ import lime.math.Vector2;
public function setProgram(program:Program3D):Void
{
__state.program = program;
__state.shader = null; // BASE-TODO: Merge this logic
__state.shader = null; // TODO: Merge this logic
if (program != null)
{
@@ -1407,11 +1433,11 @@ import lime.math.Vector2;
if (__state.program != null && __state.program.__format == GLSL)
{
// BASE-TODO
// TODO
}
else
{
// BASE-TODO: Cleanup?
// TODO: Cleanup?
if (numRegisters == -1)
{
@@ -1421,7 +1447,7 @@ import lime.math.Vector2;
var isVertex = (programType == VERTEX);
var dest = isVertex ? __vertexConstants : __fragmentConstants;
var floatData = Float32Array.fromBytes(data, 0, data.length);
var floatData = Float32Array.fromBytes(data, 0);
var outOffset = firstRegister * 4;
var inOffset = Std.int(byteArrayOffset / 4);
@@ -1465,7 +1491,7 @@ import lime.math.Vector2;
{
__flushGLProgram();
// BASE-TODO: Cache value, prevent need to copy
// TODO: Cache value, prevent need to copy
var data = new Float32Array(16);
for (i in 0...16)
{
@@ -1867,6 +1893,8 @@ import lime.math.Vector2;
**/
public function setVertexBufferAt(index:Int, buffer:VertexBuffer3D, bufferOffset:Int = 0, format:Context3DVertexBufferFormat = FLOAT_4):Void
{
if (index < 0) return;
if (buffer == null)
{
gl.disableVertexAttribArray(index);
@@ -1930,7 +1958,7 @@ import lime.math.Vector2;
@:noCompletion private function __bindGLTexture2D(texture:GLTexture):Void
{
// BASE-TODO: Need to consider activeTexture ID
// TODO: Need to consider activeTexture ID
// if (#if openfl_disable_context_cache true #else __contextState.__currentGLTexture2D != texture #end) {
@@ -1942,7 +1970,7 @@ import lime.math.Vector2;
@:noCompletion private function __bindGLTextureCubeMap(texture:GLTexture):Void
{
// BASE-TODO: Need to consider activeTexture ID
// TODO: Need to consider activeTexture ID
// if (#if openfl_disable_context_cache true #else __contextState.__currentGLTextureCubeMap != texture #end) {
@@ -1981,14 +2009,14 @@ import lime.math.Vector2;
#if !openfl_disable_display_render
if (__state.renderToTexture == null)
{
// BASE-TODO: Make sure state is correct for this?
// TODO: Make sure state is correct for this?
if (__stage.context3D == this && !__stage.__renderer.__cleared)
{
__stage.__renderer.__clear();
}
else if (!__cleared)
{
// BASE-TODO: Throw error if error reporting is enabled?
// TODO: Throw error if error reporting is enabled?
clear(0, 0, 0, 0, 1, 0, Context3DClearMask.COLOR);
}
}
@@ -2184,7 +2212,7 @@ import lime.math.Vector2;
if (#if openfl_disable_context_cache true #else __contextState.shader != shader #end)
{
// BASE-TODO: Merge this logic
// TODO: Merge this logic
if (__contextState.shader != null)
{
@@ -2240,11 +2268,20 @@ import lime.math.Vector2;
var scissorY = Std.int(__state.scissorRectangle.y);
var scissorWidth = Std.int(__state.scissorRectangle.width);
var scissorHeight = Std.int(__state.scissorRectangle.height);
#if !openfl_dpi_aware
if (__backBufferWantsBestResolution)
{
scissorX = Std.int(__state.scissorRectangle.x * __stage.window.scale);
scissorY = Std.int(__state.scissorRectangle.y * __stage.window.scale);
scissorWidth = Std.int(__state.scissorRectangle.width * __stage.window.scale);
scissorHeight = Std.int(__state.scissorRectangle.height * __stage.window.scale);
}
#end
if (__state.renderToTexture == null && __stage3D == null)
{
var contextHeight = Std.int(__stage.window.height * __stage.window.scale);
scissorY = contextHeight - Std.int(__state.scissorRectangle.height) - scissorY;
scissorY = contextHeight - scissorHeight - scissorY;
}
if (#if openfl_disable_context_cache true #else __contextState.scissorRectangle.x != scissorX
@@ -2312,7 +2349,7 @@ import lime.math.Vector2;
{
// if (#if openfl_disable_context_cache true #else texture != __contextState.textures[i] #end) {
// BASE-TODO: Cleaner approach?
// TODO: Cleaner approach?
if (texture.__textureTarget == gl.TEXTURE_2D)
{
__bindGLTexture2D(texture.__getTexture());
@@ -2323,7 +2360,7 @@ import lime.math.Vector2;
}
#if (desktop && !html5)
// BASE-TODO: Cache?
// TODO: Cache?
gl.enable(gl.TEXTURE_2D);
#end
@@ -2357,7 +2394,7 @@ import lime.math.Vector2;
gl.uniform1i(__state.program.__agalAlphaSamplerEnabled[sampler].location, 1);
#if (desktop && !html5)
// BASE-TODO: Cache?
// TODO: Cache?
gl.enable(gl.TEXTURE_2D);
#end
}
@@ -2377,15 +2414,24 @@ import lime.math.Vector2;
@:noCompletion private function __flushGLViewport():Void
{
// BASE-TODO: Cache
// TODO: Cache
if (__state.renderToTexture == null)
{
if (__stage.context3D == this)
{
var scaledBackBufferWidth = backBufferWidth;
var scaledBackBufferHeight = backBufferHeight;
#if !openfl_dpi_aware
if (__stage3D == null && !__backBufferWantsBestResolution)
{
scaledBackBufferWidth = Std.int(backBufferWidth * __stage.window.scale);
scaledBackBufferHeight = Std.int(backBufferHeight * __stage.window.scale);
}
#end
var x = __stage3D == null ? 0 : Std.int(__stage3D.x);
var y = Std.int((__stage.window.height * __stage.window.scale) - backBufferHeight - (__stage3D == null ? 0 : __stage3D.y));
gl.viewport(x, y, backBufferWidth, backBufferHeight);
var y = Std.int((__stage.window.height * __stage.window.scale) - scaledBackBufferHeight - (__stage3D == null ? 0 : __stage3D.y));
gl.viewport(x, y, scaledBackBufferWidth, scaledBackBufferHeight);
}
else
{
@@ -2396,7 +2442,7 @@ import lime.math.Vector2;
{
var width = 0, height = 0;
// BASE-TODO: Avoid use of Std.is
// TODO: Avoid use of Std.is
if ((__state.renderToTexture is Texture))
{
var texture2D:Texture = cast __state.renderToTexture;
@@ -2460,7 +2506,7 @@ import lime.math.Vector2;
case GREATER: gl.GREATER;
case GREATER_EQUAL: gl.GEQUAL;
case LESS: gl.LESS;
case LESS_EQUAL: gl.LEQUAL; // BASE-TODO : wrong value
case LESS_EQUAL: gl.LEQUAL; // TODO : wrong value
case NEVER: gl.NEVER;
case NOT_EQUAL: gl.NOTEQUAL;
default: gl.EQUAL;
@@ -2655,7 +2701,7 @@ import lime.math.Vector2;
{
if (__glMemoryCurrentAvailable != -1)
{
// BASE-TODO: Return amount used by this application only
// TODO: Return amount used by this application only
var current = gl.getParameter(__glMemoryCurrentAvailable);
var total = gl.getParameter(__glMemoryTotalAvailable);
+2
View File
@@ -636,10 +636,12 @@ class Sound extends EventDispatcher
return null;
}
#if !macro
if (changeID < funkin.backend.system.Main.changeID) {
changeID = funkin.backend.system.Main.changeID;
regen();
}
#end
if (sndTransform == null)
{
+6 -4
View File
@@ -1,8 +1,10 @@
package openfl.utils;
#if !macro
import funkin.backend.system.Main;
import funkin.options.Options;
import funkin.backend.system.OptimizedBitmapData;
#end
import openfl.utils._internal.Log;
import openfl.display.BitmapData;
import openfl.display.MovieClip;
@@ -113,10 +115,10 @@ class Assets
var bitmapData = image.src;
#else
var bitmapData:BitmapData = null;
if (pushToGPU && !Main.forceGPUOnlyBitmapsOff && Options.gpuOnlyBitmaps) {
#if !macro if (pushToGPU && !Main.forceGPUOnlyBitmapsOff && Options.gpuOnlyBitmaps) {
bitmapData = new OptimizedBitmapData(0, 0, true, 0);
bitmapData.__fromImage(image);
} else {
} else #end {
bitmapData = BitmapData.fromImage(image);
}
#end
@@ -497,10 +499,10 @@ class Assets
var bitmapData = image.src;
#else
var bitmapData:BitmapData = null;
if (!Main.forceGPUOnlyBitmapsOff && Options.gpuOnlyBitmaps) {
#if !macro if (!Main.forceGPUOnlyBitmapsOff && Options.gpuOnlyBitmaps) {
bitmapData = new OptimizedBitmapData(0, 0, true, 0);
bitmapData.__fromImage(image);
} else {
} else #end {
bitmapData = BitmapData.fromImage(image);
}
#end