Merge branch 'main' of https://github.com/YoshiCrafter29/CodenameEngine
This commit is contained in:
+13
-13
@@ -43,16 +43,16 @@
|
||||
<set name="BUILD_DIR" value="latest/" if="beta" />
|
||||
|
||||
<classpath name="source" />
|
||||
|
||||
|
||||
<define name="PRELOAD_ALL" unless="web" />
|
||||
<define name="NO_PRELOAD_ALL" unless="PRELOAD_ALL"/>
|
||||
|
||||
|
||||
<library name="assets" preload="true" if="PRELOAD_ALL"/>
|
||||
<library name="assets" preload="false" if="NO_PRELOAD_ALL" />
|
||||
|
||||
|
||||
<assets path="assets/" rename="assets" exclude="*.ogg" if="web"/>
|
||||
<assets path="assets/" rename="assets" exclude="*.mp3" unless="web"/>
|
||||
|
||||
|
||||
<assets path='mods' rename='mods' embed='false'/>
|
||||
<assets path='art/readme.txt' rename='do NOT readme.txt' />
|
||||
|
||||
@@ -60,13 +60,13 @@
|
||||
|
||||
<!--Enable the Flixel core recording system-->
|
||||
<!--<haxedef name="FLX_RECORD" />-->
|
||||
|
||||
|
||||
<haxedef name="FLX_NO_FOCUS_LOST_SCREEN" />
|
||||
|
||||
<!--Disable the Flixel core debugger. Automatically gets set whenever you compile in release mode!-->
|
||||
<haxedef name="FLX_NO_DEBUG" unless="debug" />
|
||||
|
||||
<!--Enable this for Nape release builds for a serious peformance improvement-->
|
||||
<!--Enable this for Nape release builds for a serious performance improvement-->
|
||||
<haxedef name="NAPE_RELEASE_BUILD" unless="debug" />
|
||||
|
||||
<!-- _________________________________ Custom _______________________________ -->
|
||||
@@ -127,7 +127,7 @@
|
||||
|
||||
<!-- Comment this out to disable video cutscene support, in case of compilation errors. !-->
|
||||
<define name="VIDEO_CUTSCENES" unless="web || linux || hl || mac" />
|
||||
|
||||
|
||||
|
||||
<haxedef name="VIDEO_CUTSCENES" if="VIDEO_CUTSCENES" />
|
||||
<haxedef name="UPDATE_CHECKING" if="UPDATE_CHECKING" />
|
||||
@@ -135,12 +135,12 @@
|
||||
<haxeflag name="--macro" value="funkin.macros.StdDeprecationsRemover.init()" />
|
||||
<!-- _______________________________ Libraries ______________________________ -->
|
||||
|
||||
|
||||
|
||||
<haxelib name="hxCodec" if="VIDEO_CUTSCENES" />
|
||||
<haxelib name="away3d" />
|
||||
<haxelib name="format" />
|
||||
<haxelib name="flxanimate" />
|
||||
|
||||
|
||||
<haxelib name="flixel-yc29" rename="flixel" />
|
||||
<haxedev set='webgl' />
|
||||
|
||||
@@ -148,11 +148,11 @@
|
||||
<haxelib name="linc_discord-rpc" if="DISCORD_RPC"/>
|
||||
|
||||
<haxelib name="markdown" />
|
||||
|
||||
|
||||
<!-- <haxelib name="hxcpp-debug-server" if="desktop"/> -->
|
||||
|
||||
|
||||
<!-- _________________________________ HScript classes _______________________________ -->
|
||||
|
||||
|
||||
|
||||
<section if="COMPILE_ALL_CLASSES">
|
||||
<haxeflag name="-dce" value="no" />
|
||||
@@ -160,7 +160,7 @@
|
||||
</section>
|
||||
<haxeflag name="--macro" value="exclude('funkin.updating')" unless="UPDATE_CHECKING"/>
|
||||
<haxeflag name="--macro" value="exclude('funkin.multitasking')" unless="ALLOW_MULTITASKING"/>
|
||||
|
||||
|
||||
<!-- MACROS & DOCUMENTATION !-->
|
||||
<haxeflag name="--macro" value="funkin.macros.BuildCounterMacro.getBuildNumber()" />
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<line text="kawaisprite" />
|
||||
<line text="evilsk8er" />
|
||||
</text>
|
||||
|
||||
|
||||
<text beat="3">
|
||||
<line text="ninjamuffin99" />
|
||||
<line text="phantomArcade" />
|
||||
@@ -25,7 +25,7 @@
|
||||
<line text="evilsk8er" />
|
||||
<line text="presents" />
|
||||
</text>
|
||||
|
||||
|
||||
<text beat="4" /> <!-- clears the screen !-->
|
||||
|
||||
<text beat="5">
|
||||
@@ -37,7 +37,7 @@
|
||||
<line text="In association" />
|
||||
<line text="with" />
|
||||
<line text="Newgrounds" />
|
||||
<sprite path="titlescreen/newgrounds_logo" scale="0.8"/>
|
||||
<sprite path="menus/titlescreen/newgrounds_logo" scale="0.8"/>
|
||||
</text>
|
||||
|
||||
<text beat="8" /> <!-- clears the screen !-->
|
||||
@@ -61,7 +61,7 @@
|
||||
<line text="Friday" />
|
||||
<line text="Night" />
|
||||
</text>
|
||||
|
||||
|
||||
<text beat="15">
|
||||
<line text="Friday" />
|
||||
<line text="Night" />
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
2037
|
||||
2044
|
||||
@@ -14,7 +14,7 @@ import flixel.FlxG;
|
||||
class Flx3DUtil
|
||||
{
|
||||
/**
|
||||
* Returns the total amount of 3D stages (not exculding the ones in use)
|
||||
* Returns the total amount of 3D stages (not excluding the ones in use)
|
||||
* @return Int
|
||||
*/
|
||||
public static inline function getTotal3D():Int
|
||||
@@ -38,7 +38,7 @@ class Flx3DUtil
|
||||
|
||||
/**
|
||||
* Calls dispose() (destroy) on a Away3D asset
|
||||
* @param obj
|
||||
* @param obj
|
||||
* @return null
|
||||
*/
|
||||
public static inline function dispose<T:IAsset>(obj:Null<T>):T
|
||||
|
||||
@@ -44,7 +44,7 @@ class Flx3DView extends FlxView3D {
|
||||
var model = Assets.getBytes(assetPath);
|
||||
if (model == null)
|
||||
throw 'Model at ${assetPath} was not found.';
|
||||
|
||||
|
||||
var context = new AssetLoaderContext();
|
||||
var noExt = Path.withoutExtension(assetPath);
|
||||
trace(noExt);
|
||||
@@ -113,7 +113,7 @@ class Flx3DView extends FlxView3D {
|
||||
if (onAssetCallback != null)
|
||||
onAssetCallback(event);
|
||||
});
|
||||
|
||||
|
||||
token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, (_) -> {
|
||||
trace("Loader Finished...");
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ import flixel.FlxSprite;
|
||||
import openfl.display.BitmapData;
|
||||
|
||||
/**
|
||||
* @author Ne_Eo
|
||||
* @author Ne_Eo
|
||||
* @see https://twitter.com/Ne_Eo_Twitch
|
||||
*
|
||||
* @author lunarclient
|
||||
*
|
||||
* @author lunarcleint
|
||||
* @see https://twitter.com/lunarcleint
|
||||
*/
|
||||
class FlxView3D extends FlxSprite
|
||||
@@ -18,20 +18,20 @@ class FlxView3D extends FlxSprite
|
||||
@:noCompletion private var bmp:BitmapData;
|
||||
|
||||
/**
|
||||
* The Away3D View
|
||||
* The Away3D View
|
||||
*/
|
||||
public var view:View3D;
|
||||
|
||||
/**
|
||||
* Set this flag to true to force the View3D to update during the `draw()` call.
|
||||
*/
|
||||
public var dirty3D:Bool = true;
|
||||
public var dirty3D:Bool = true;
|
||||
|
||||
/**
|
||||
* Creates a new instance of a View3D from Away3D and renders it as a FlxSprite
|
||||
* ! Call Flx3DUtil.is3DAvailable(); to make sure a 3D stage is usable
|
||||
* @param x
|
||||
* @param y
|
||||
* @param x
|
||||
* @param y
|
||||
* @param width Leave as -1 for screen width
|
||||
* @param height Leave as -1 for screen height
|
||||
*/
|
||||
@@ -54,7 +54,7 @@ class FlxView3D extends FlxSprite
|
||||
|
||||
/**
|
||||
* Disposes (destroys) the asset and returns null
|
||||
* @param obj
|
||||
* @param obj
|
||||
* @return T null
|
||||
*/
|
||||
public static function dispose<T:IAsset>(obj:Null<T>):T
|
||||
@@ -76,12 +76,11 @@ class FlxView3D extends FlxSprite
|
||||
bmp = null;
|
||||
}
|
||||
|
||||
if (view != null)
|
||||
if (view != null)
|
||||
{
|
||||
view.dispose();
|
||||
view = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@:noCompletion override function draw()
|
||||
|
||||
@@ -75,7 +75,7 @@ class CharacterEditor extends WindowContent {
|
||||
add(bg);
|
||||
add(stageFront);
|
||||
add(char);
|
||||
|
||||
|
||||
title = 'Character Editor - ${char.curCharacter}.xml';
|
||||
|
||||
// character setup & following
|
||||
@@ -143,13 +143,13 @@ class CharacterEditor extends WindowContent {
|
||||
callback: resetCamZoom
|
||||
},
|
||||
{
|
||||
name: "Show a Boyfriend Silouhette"
|
||||
name: "Show a Boyfriend Silhouette"
|
||||
},
|
||||
{
|
||||
name: "Show a Dad Silouhette"
|
||||
name: "Show a Dad Silhouette"
|
||||
},
|
||||
{
|
||||
name: "Show a Girlfriend Silouhette"
|
||||
name: "Show a Girlfriend Silhouette"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -197,7 +197,7 @@ class CharacterEditor extends WindowContent {
|
||||
content.push(animPrefixInput = new InputBox(10, label.y + label.height, 380, ""));
|
||||
|
||||
content.push(animLoopCheckbox = new Checkbox(10, animPrefixInput.y + animPrefixInput.height + 10, 380, "Loop"));
|
||||
|
||||
|
||||
content.push(label = new WindowText(10, animLoopCheckbox.y + animLoopCheckbox.height + 10, 0, "Animation FPS (Frames per second)"));
|
||||
content.push(animFpsStepper = new NumericStepper(10, label.y + label.height, 380, 0));
|
||||
|
||||
@@ -207,7 +207,7 @@ class CharacterEditor extends WindowContent {
|
||||
|
||||
for(e in [animOffsetX, animOffsetY])
|
||||
e.increment = 10;
|
||||
|
||||
|
||||
for(spr in content)
|
||||
tabView.tabs[0].add(spr);
|
||||
}
|
||||
@@ -221,18 +221,18 @@ class CharacterEditor extends WindowContent {
|
||||
|
||||
content.push(label = new WindowText(10, content.last().y + content.last().height, 0, "Icon Name (images/icons/)"));
|
||||
content.push(charIconInput = new InputBox(10, label.y + label.height, 380, char.icon.getDefault("")));
|
||||
|
||||
|
||||
content.push(charIsPlayerCheckbox = new Checkbox(10, content.last().y + content.last().height + 10, 380, "Playable character"));
|
||||
content.push(label = new WindowText(10, content.last().y + content.last().height, 380, "(Offsets are automatically fixed when playing as a non-playable character and vice versa)"));
|
||||
charIsPlayerCheckbox.checked = char.xml.getAtt("isPlayer") == "true";
|
||||
|
||||
|
||||
content.push(charIsGFCheckbox = new Checkbox(10, content.last().y + content.last().height + 10, 380, "Is Girlfriend"));
|
||||
content.push(label = new WindowText(10, content.last().y + content.last().height, 380, "(Characters marked as Girlfriend will replace GF when used as opponent)"));
|
||||
charIsGFCheckbox.checked = char.isGF;
|
||||
|
||||
|
||||
content.push(charFlipXCheckbox = new Checkbox(10, content.last().y + content.last().height + 10, 380, "Flip Horizontally"));
|
||||
charFlipXCheckbox.checked = char.__baseFlipped != char.isPlayer;
|
||||
|
||||
|
||||
for(spr in content)
|
||||
tabView.tabs[1].add(spr);
|
||||
}
|
||||
@@ -306,7 +306,7 @@ class CharacterEditor extends WindowContent {
|
||||
/**
|
||||
* =========== CONTEXT MENU OPTIONS ===========
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* View
|
||||
*/
|
||||
|
||||
@@ -11,9 +11,6 @@ import flixel.math.FlxRect;
|
||||
import flixel.math.FlxPoint;
|
||||
import funkin.system.Conductor;
|
||||
import funkin.scripting.events.*;
|
||||
#if polymod
|
||||
import polymod.format.ParseRules.TargetSignatureElement;
|
||||
#end
|
||||
|
||||
using StringTools;
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ class TitleState extends MusicBeatState
|
||||
blackScreen = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK);
|
||||
add(blackScreen);
|
||||
|
||||
#if !TITLESCREEN_XML
|
||||
ngSpr = new FlxSprite(0, FlxG.height * 0.52).loadAnimatedGraphic(Paths.image('newgrounds_logo'));
|
||||
add(ngSpr);
|
||||
ngSpr.visible = false;
|
||||
@@ -99,6 +100,7 @@ class TitleState extends MusicBeatState
|
||||
ngSpr.updateHitbox();
|
||||
ngSpr.screenCenter(X);
|
||||
ngSpr.antialiasing = true;
|
||||
#end
|
||||
|
||||
FlxG.mouse.visible = false;
|
||||
|
||||
@@ -213,7 +215,10 @@ class TitleState extends MusicBeatState
|
||||
|
||||
public function deleteCoolText()
|
||||
{
|
||||
while (textGroup.members.length > 0) textGroup.remove(textGroup.members[0], true);
|
||||
while (textGroup.members.length > 0) {
|
||||
textGroup.members[0].destroy();
|
||||
textGroup.remove(textGroup.members[0], true);
|
||||
}
|
||||
}
|
||||
|
||||
override function beatHit(curBeat:Int)
|
||||
@@ -258,7 +263,7 @@ class TitleState extends MusicBeatState
|
||||
5 => new IntroText(['In association', 'with']),
|
||||
7 => new IntroText(['In association', 'with', 'newgrounds', {
|
||||
name: "newgroundsLogo",
|
||||
path: "titlescreen/newgrounds_logo",
|
||||
path: "menus/titlescreen/newgrounds_logo",
|
||||
scale: 0.8
|
||||
}]),
|
||||
8 => new IntroText(),
|
||||
@@ -330,7 +335,9 @@ class TitleState extends MusicBeatState
|
||||
{
|
||||
if (!skippedIntro)
|
||||
{
|
||||
#if !TITLESCREEN_XML
|
||||
remove(ngSpr);
|
||||
#end
|
||||
|
||||
FlxG.camera.flash(FlxColor.WHITE, 4);
|
||||
remove(blackScreen);
|
||||
@@ -363,7 +370,13 @@ class IntroText {
|
||||
|
||||
var scale:Float = CoolUtil.getDefault(image.scale, 1);
|
||||
|
||||
var sprite = new FlxSprite(0, 200).loadAnimatedGraphic(Paths.image(image.path));
|
||||
var yPos:Float = 200;
|
||||
if(state.textGroup.members.length > 0) {
|
||||
var lastLine:FlxSprite = cast state.textGroup.members[state.textGroup.members.length-1];
|
||||
yPos = lastLine.y + lastLine.height + 10;
|
||||
}
|
||||
|
||||
var sprite = new FlxSprite(0, yPos).loadAnimatedGraphic(Paths.image(image.path));
|
||||
sprite.flipX = CoolUtil.getDefault(image.flipX, false);
|
||||
sprite.flipY = CoolUtil.getDefault(image.flipY, false);
|
||||
sprite.scale.set(scale, scale);
|
||||
|
||||
@@ -12,7 +12,7 @@ import openfl.utils.Assets;
|
||||
class Script extends FlxBasic implements IFlxDestroyable {
|
||||
/**
|
||||
* Use "static var thing = true;" in hscript to use those!!
|
||||
* are reset every mod switch so once youre done with them make sure to make them null!!
|
||||
* are reset every mod switch so once you're done with them make sure to make them null!!
|
||||
*/
|
||||
public static var staticVariables:Map<String, Dynamic> = [];
|
||||
|
||||
@@ -155,7 +155,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
|
||||
/**
|
||||
* Creates a new instance of the script class.
|
||||
* @param path
|
||||
* @param path
|
||||
*/
|
||||
public function new(path:String) {
|
||||
super();
|
||||
@@ -184,14 +184,14 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
* Sets the "public" variables map for ScriptPack
|
||||
*/
|
||||
public function setPublicMap(map:Map<String, Dynamic>) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Hot-reloads the script, if possible
|
||||
*/
|
||||
public function reload() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,7 +204,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
], TRACE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Calls the function `func` defined in the script.
|
||||
* @param func Name of the function
|
||||
@@ -216,13 +216,13 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
curScript = this;
|
||||
|
||||
var result = onCall(func, parameters == null ? [] : parameters);
|
||||
|
||||
|
||||
curScript = oldScript;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a script's parent object so that its properties can be accessed easily. Ex: Passing `PlayState.instace` will allow `boyfriend` to be typed instead of `PlayState.instance.boyfriend`.
|
||||
* Sets a script's parent object so that its properties can be accessed easily. Ex: Passing `PlayState.instance` will allow `boyfriend` to be typed instead of `PlayState.instance.boyfriend`.
|
||||
* @param variable Parent variable.
|
||||
*/
|
||||
public function setParent(variable:Dynamic) {}
|
||||
|
||||
@@ -14,7 +14,7 @@ class CancellableEvent implements IFlxDestroyable {
|
||||
public var data:Dynamic = {};
|
||||
|
||||
/**
|
||||
* Prevents default action from occuring.
|
||||
* Prevents default action from occurring.
|
||||
* @param c Whenever the scripts following this one should be called or not. (Defaults to `true`)
|
||||
*/
|
||||
public function preventDefault(c:Bool = false) {
|
||||
|
||||
@@ -12,16 +12,16 @@ class NoteHitEvent extends CancellableEvent {
|
||||
@:dox(hide) public var autoHitLastSustain:Bool = true;
|
||||
|
||||
/**
|
||||
Whenever a miss should be added.
|
||||
**/
|
||||
* Whenever a miss should be added.
|
||||
*/
|
||||
public var misses:Bool = true;
|
||||
/**
|
||||
Whenever a miss should be added.
|
||||
**/
|
||||
* Whenever a miss should be added.
|
||||
*/
|
||||
public var countAsCombo:Bool = true;
|
||||
/**
|
||||
Whenever ratings should be shown or not.
|
||||
**/
|
||||
* Whenever ratings should be shown or not.
|
||||
*/
|
||||
public var showRating:Null<Bool> = null;
|
||||
/**
|
||||
* Note that has been pressed
|
||||
@@ -141,7 +141,7 @@ class NoteHitEvent extends CancellableEvent {
|
||||
}
|
||||
@:dox(hide)
|
||||
public function cancelCamZooming() {preventCamZooming();}
|
||||
|
||||
|
||||
/**
|
||||
* Prevents the sustain tail (the last one) from being automatically hit when the sustain before it is hit.
|
||||
*/
|
||||
@@ -150,7 +150,7 @@ class NoteHitEvent extends CancellableEvent {
|
||||
}
|
||||
@:dox(hide)
|
||||
public function cancelLastSustainHit() {preventLastSustainHit();}
|
||||
|
||||
|
||||
/**
|
||||
* Prevents the strum from glowing after this note has been pressed.
|
||||
*/
|
||||
@@ -160,7 +160,7 @@ class NoteHitEvent extends CancellableEvent {
|
||||
@:dox(hide)
|
||||
public function cancelStrumGlow() {preventStrumGlow();}
|
||||
|
||||
private inline function get_character()
|
||||
private inline function get_character()
|
||||
return characters[0];
|
||||
private function set_character(char:Character) {
|
||||
characters = [char];
|
||||
|
||||
@@ -55,7 +55,7 @@ enum Device
|
||||
|
||||
/**
|
||||
* Since, in many cases multiple actions should use similar keys, we don't want the
|
||||
* rebinding UI to list every action. ActionBinders are what the user percieves as
|
||||
* rebinding UI to list every action. ActionBinders are what the user perceives as
|
||||
* an input so, for instance, they can't set jump-press and jump-release to different keys.
|
||||
*/
|
||||
enum Control
|
||||
|
||||
@@ -86,7 +86,7 @@ class MusicBeatState extends FlxUIState implements IBeatReceiver
|
||||
if (stateScript == null || stateScript is DummyScript) {
|
||||
var className = Type.getClassName(Type.getClass(this));
|
||||
var scriptName = this.scriptName != null ? this.scriptName : className.substr(className.lastIndexOf(".")+1);
|
||||
|
||||
|
||||
stateScript = Script.create(Paths.script('data/states/${scriptName}'));
|
||||
stateScript.setParent(this);
|
||||
stateScript.load();
|
||||
@@ -144,7 +144,7 @@ class MusicBeatState extends FlxUIState implements IBeatReceiver
|
||||
Logs.trace('State script successfully reloaded', WARNING, GREEN);
|
||||
}
|
||||
call("update", [elapsed]);
|
||||
|
||||
|
||||
super.update(elapsed);
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ class MusicBeatState extends FlxUIState implements IBeatReceiver
|
||||
* @param v1 Value 1
|
||||
* @param v2 Value 2
|
||||
* @param ratio Ratio
|
||||
* @param fpsSensitive Whenever the ratio should not be adjusted to run at the same speed independant of framerate.
|
||||
* @param fpsSensitive Whenever the ratio should not be adjusted to run at the same speed independent of framerate.
|
||||
*/
|
||||
public function lerp(v1:Float, v2:Float, ratio:Float, fpsSensitive:Bool = false) {
|
||||
if (fpsSensitive)
|
||||
@@ -175,7 +175,7 @@ class MusicBeatState extends FlxUIState implements IBeatReceiver
|
||||
}
|
||||
|
||||
/**
|
||||
* SCRIPTING STUFF
|
||||
* SCRIPTING STUFF
|
||||
*/
|
||||
public override function openSubState(subState:FlxSubState) {
|
||||
var e = event("onOpenSubState", EventManager.get(StateEvent).recycle(subState));
|
||||
@@ -191,7 +191,7 @@ class MusicBeatState extends FlxUIState implements IBeatReceiver
|
||||
public override function destroy() {
|
||||
if (parentWindow == null)
|
||||
super.destroy();
|
||||
|
||||
|
||||
call("onDestroy");
|
||||
if (stateScript != null)
|
||||
stateScript.destroy();
|
||||
|
||||
@@ -17,7 +17,7 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
|
||||
private var lastBeat:Float = 0;
|
||||
private var lastStep:Float = 0;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Current step
|
||||
*/
|
||||
@@ -37,19 +37,19 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
|
||||
/**
|
||||
* Current song position (in milliseconds).
|
||||
*/
|
||||
public var songPos(get, never):Float;
|
||||
|
||||
inline function get_curStep():Int
|
||||
return Conductor.curStep;
|
||||
inline function get_curBeat():Int
|
||||
return Conductor.curBeat;
|
||||
inline function get_curStepFloat():Float
|
||||
return Conductor.curStepFloat;
|
||||
inline function get_curBeatFloat():Float
|
||||
return Conductor.curBeatFloat;
|
||||
inline function get_songPos():Float
|
||||
return Conductor.songPosition;
|
||||
|
||||
public var songPos(get, never):Float;
|
||||
|
||||
inline function get_curStep():Int
|
||||
return Conductor.curStep;
|
||||
inline function get_curBeat():Int
|
||||
return Conductor.curBeat;
|
||||
inline function get_curStepFloat():Float
|
||||
return Conductor.curStepFloat;
|
||||
inline function get_curBeatFloat():Float
|
||||
return Conductor.curBeatFloat;
|
||||
inline function get_songPos():Float
|
||||
return Conductor.songPosition;
|
||||
|
||||
|
||||
/**
|
||||
* Current injected script attached to the state. To add one, create a file at path "data/states/stateName" (ex: "data/states/PauseMenuSubstate.hx")
|
||||
@@ -81,7 +81,7 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
|
||||
if (stateScript == null || stateScript is DummyScript) {
|
||||
var className = Type.getClassName(Type.getClass(this));
|
||||
var scriptName = this.scriptName != null ? this.scriptName : className.substr(className.lastIndexOf(".")+1);
|
||||
|
||||
|
||||
stateScript = Script.create(Paths.script('data/states/${scriptName}'));
|
||||
stateScript.setParent(this);
|
||||
stateScript.load();
|
||||
@@ -168,7 +168,7 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
|
||||
* @param v1 Value 1
|
||||
* @param v2 Value 2
|
||||
* @param ratio Ratio
|
||||
* @param fpsSensitive Whenever the ratio should not be adjusted to run at the same speed independant of framerate.
|
||||
* @param fpsSensitive Whenever the ratio should not be adjusted to run at the same speed independent of framerate.
|
||||
*/
|
||||
public function lerp(v1:Float, v2:Float, ratio:Float, fpsSensitive:Bool = false) {
|
||||
if (fpsSensitive)
|
||||
@@ -178,7 +178,7 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
|
||||
}
|
||||
|
||||
/**
|
||||
* SCRIPTING STUFF
|
||||
* SCRIPTING STUFF
|
||||
*/
|
||||
public override function openSubState(subState:FlxSubState) {
|
||||
var e = event("onOpenSubState", EventManager.get(StateEvent).recycle(subState));
|
||||
|
||||
@@ -254,7 +254,7 @@ class Paths
|
||||
var content:Array<String> = [];
|
||||
#if MOD_SUPPORT
|
||||
if (library is funkin.mods.ModsAssetLibrary) {
|
||||
// easy task, can immediatly scan for files!
|
||||
// easy task, can immediately scan for files!
|
||||
var lib = cast(library, funkin.mods.ModsAssetLibrary);
|
||||
content = lib.getFiles(libThing.symbolName);
|
||||
if (addPath)
|
||||
|
||||
@@ -34,11 +34,7 @@ class Song
|
||||
PlayState.fromMods = Paths.assetsTree.existsSpecific(assetPath, "TEXT", MODS);
|
||||
var rawJson = Assets.getText(assetPath).trim();
|
||||
|
||||
while (!rawJson.endsWith("}"))
|
||||
{
|
||||
rawJson = rawJson.substr(0, rawJson.length - 1);
|
||||
// LOL GOING THROUGH THE BULLSHIT TO CLEAN IDK WHATS STRANGE
|
||||
}
|
||||
rawJson = rawJson.substr(0, rawJson.lastIndexOf('}') + 1);
|
||||
|
||||
return parseJSONshit(rawJson);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import flixel.util.FlxColor;
|
||||
using StringTools;
|
||||
|
||||
/**
|
||||
* Loosley based on FlxTypeText lolol
|
||||
* Loosely based on FlxTypeText lolol
|
||||
*/
|
||||
class Alphabet extends FlxSpriteGroup
|
||||
{
|
||||
|
||||
@@ -61,7 +61,7 @@ class CoolUtil
|
||||
var f:Null<Dynamic> = Reflect.field(v, name);
|
||||
if (f != null)
|
||||
return cast f;
|
||||
}
|
||||
}
|
||||
Reflect.setField(v, name, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
@@ -90,7 +90,7 @@ class CoolUtil
|
||||
* @param color1 Color 1
|
||||
* @param color2 Color 2
|
||||
* @param ratio Ratio
|
||||
* @param fpsSensitive Whenever the ratio should be case sentivive (adapted when game is running at 120 instead of 60)
|
||||
* @param fpsSensitive Whenever the ratio should be fps sensitive (adapted when game is running at 120 instead of 60)
|
||||
*/
|
||||
public static inline function lerpColor(color1:FlxColor, color2:FlxColor, ratio:Float, fpsSensitive:Bool = false) {
|
||||
if (!fpsSensitive)
|
||||
@@ -114,7 +114,7 @@ class CoolUtil
|
||||
public static function getColorFromDynamic(c:Dynamic):Null<FlxColor> {
|
||||
// -1
|
||||
if (c is Int) return c;
|
||||
|
||||
|
||||
// -1.0
|
||||
if (c is Float) return Std.int(c);
|
||||
|
||||
@@ -263,9 +263,9 @@ class CoolUtil
|
||||
}
|
||||
|
||||
public static function loadWeek(weekData:WeekData, difficulty:String = "normal") {
|
||||
PlayState.storyWeek = weekData;
|
||||
PlayState.storyPlaylist = [for(e in weekData.songs) e.name];
|
||||
PlayState.isStoryMode = true;
|
||||
PlayState.storyWeek = weekData;
|
||||
PlayState.storyPlaylist = [for(e in weekData.songs) e.name];
|
||||
PlayState.isStoryMode = true;
|
||||
PlayState.campaignScore = 0;
|
||||
__loadSong(PlayState.storyPlaylist[0], difficulty);
|
||||
}
|
||||
@@ -331,10 +331,10 @@ class CoolUtil
|
||||
return null;
|
||||
return graph.imageFrame;
|
||||
}
|
||||
|
||||
|
||||
public static function loadAnimatedGraphic(spr:FlxSprite, path:String) {
|
||||
spr.frames = loadFrames(path);
|
||||
|
||||
|
||||
if (spr.frames != null && spr.frames.frames != null) {
|
||||
spr.animation.add("idle", [for(i in 0...spr.frames.frames.length) i], 24, true);
|
||||
spr.animation.play("idle");
|
||||
@@ -376,7 +376,7 @@ class CoolUtil
|
||||
public static function clear<T>(array:Array<T>):Array<T> {
|
||||
while(array.length > 0)
|
||||
array.shift();
|
||||
return array;
|
||||
return array;
|
||||
}
|
||||
|
||||
public static function pushGroup<T>(array:Array<T>, ...args:T):Array<T> {
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
package lime._internal.backend.html5;
|
||||
|
||||
import lime.math.Vector4;
|
||||
import lime.media.AudioSource;
|
||||
|
||||
@:access(lime.media.AudioBuffer)
|
||||
class HTML5AudioSource
|
||||
{
|
||||
private var completed:Bool;
|
||||
private var gain:Float;
|
||||
private var id:Int;
|
||||
private var length:Float;
|
||||
private var loops:Int;
|
||||
private var parent:AudioSource;
|
||||
private var playing:Bool;
|
||||
private var position:Vector4;
|
||||
|
||||
public function new(parent:AudioSource)
|
||||
{
|
||||
this.parent = parent;
|
||||
|
||||
id = -1;
|
||||
gain = 1;
|
||||
position = new Vector4();
|
||||
}
|
||||
|
||||
public function dispose():Void {}
|
||||
|
||||
public function init():Void {}
|
||||
|
||||
public function play():Void
|
||||
{
|
||||
#if lime_howlerjs
|
||||
if (playing || parent.buffer == null || parent.buffer.__srcHowl == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
playing = true;
|
||||
|
||||
var time = getCurrentTime();
|
||||
|
||||
completed = false;
|
||||
|
||||
var cacheVolume = untyped parent.buffer.__srcHowl._volume;
|
||||
untyped parent.buffer.__srcHowl._volume = parent.gain;
|
||||
|
||||
id = parent.buffer.__srcHowl.play();
|
||||
|
||||
untyped parent.buffer.__srcHowl._volume = cacheVolume;
|
||||
// setGain (parent.gain);
|
||||
|
||||
setPosition(parent.position);
|
||||
|
||||
parent.buffer.__srcHowl.on("end", howl_onEnd, id);
|
||||
|
||||
// Calling setCurrentTime causes html5 audio to replay from this position on next frame
|
||||
#if force_html5_audio
|
||||
if (time == 0) setCurrentTime(time);
|
||||
#else
|
||||
setCurrentTime(time);
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
||||
public function pause():Void
|
||||
{
|
||||
#if lime_howlerjs
|
||||
playing = false;
|
||||
|
||||
if (parent.buffer != null && parent.buffer.__srcHowl != null)
|
||||
{
|
||||
parent.buffer.__srcHowl.pause(id);
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
public function stop():Void
|
||||
{
|
||||
#if lime_howlerjs
|
||||
playing = false;
|
||||
|
||||
if (parent.buffer != null && parent.buffer.__srcHowl != null)
|
||||
{
|
||||
parent.buffer.__srcHowl.stop(id);
|
||||
parent.buffer.__srcHowl.off("end", howl_onEnd, id);
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
// Event Handlers
|
||||
private function howl_onEnd()
|
||||
{
|
||||
#if lime_howlerjs
|
||||
playing = false;
|
||||
|
||||
if (loops > 0)
|
||||
{
|
||||
loops--;
|
||||
stop();
|
||||
// currentTime = 0;
|
||||
play();
|
||||
return;
|
||||
}
|
||||
else if (parent.buffer != null && parent.buffer.__srcHowl != null)
|
||||
{
|
||||
parent.buffer.__srcHowl.stop(id);
|
||||
parent.buffer.__srcHowl.off("end", howl_onEnd, id);
|
||||
}
|
||||
|
||||
completed = true;
|
||||
parent.onComplete.dispatch();
|
||||
#end
|
||||
}
|
||||
|
||||
// Get & Set Methods
|
||||
public function getCurrentTime():Float
|
||||
{
|
||||
if (id == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if lime_howlerjs
|
||||
if (completed)
|
||||
{
|
||||
return getLength();
|
||||
}
|
||||
else if (parent.buffer != null && parent.buffer.__srcHowl != null)
|
||||
{
|
||||
var time = (parent.buffer.__srcHowl.seek(id) * 1000) - parent.offset;
|
||||
if (time < 0) return 0;
|
||||
return time;
|
||||
}
|
||||
#end
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function setCurrentTime(value:Float):Float
|
||||
{
|
||||
#if lime_howlerjs
|
||||
if (parent.buffer != null && parent.buffer.__srcHowl != null)
|
||||
{
|
||||
// if (playing) buffer.__srcHowl.play (id);
|
||||
var pos = (value + parent.offset) / 1000;
|
||||
if (pos < 0) pos = 0;
|
||||
parent.buffer.__srcHowl.seek(pos, id);
|
||||
}
|
||||
#end
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public function getGain():Float
|
||||
{
|
||||
return gain;
|
||||
}
|
||||
|
||||
public function setGain(value:Float):Float
|
||||
{
|
||||
#if lime_howlerjs
|
||||
// set howler volume only if we have an active id.
|
||||
// Passing -1 might create issues in future play()'s.
|
||||
|
||||
if (parent.buffer != null && parent.buffer.__srcHowl != null && id != -1)
|
||||
{
|
||||
parent.buffer.__srcHowl.volume(value, id);
|
||||
}
|
||||
#end
|
||||
|
||||
return gain = value;
|
||||
}
|
||||
|
||||
public function getLength():Float
|
||||
{
|
||||
if (length != 0)
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
#if lime_howlerjs
|
||||
if (parent.buffer != null && parent.buffer.__srcHowl != null)
|
||||
{
|
||||
return parent.buffer.__srcHowl.duration() * 1000;
|
||||
}
|
||||
#end
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function setLength(value:Float):Float
|
||||
{
|
||||
return length = value;
|
||||
}
|
||||
|
||||
public function getLoops():Int
|
||||
{
|
||||
return loops;
|
||||
}
|
||||
|
||||
public function setLoops(value:Int):Int
|
||||
{
|
||||
return loops = value;
|
||||
}
|
||||
|
||||
public function getPitch():Float
|
||||
{
|
||||
#if lime_howlerjs
|
||||
return parent.buffer.__srcHowl.rate();
|
||||
#else
|
||||
return 1;
|
||||
#end
|
||||
}
|
||||
|
||||
public function setPitch(value:Float):Float
|
||||
{
|
||||
#if lime_howlerjs
|
||||
parent.buffer.__srcHowl.rate(value);
|
||||
#end
|
||||
return getPitch();
|
||||
}
|
||||
|
||||
public function getPosition():Vector4
|
||||
{
|
||||
#if lime_howlerjs
|
||||
// This should work, but it returns null (But checking the inside of the howl, the _pos is actually null... so ¯\_(ツ)_/¯)
|
||||
/*
|
||||
var arr = parent.buffer.__srcHowl.pos())
|
||||
position.x = arr[0];
|
||||
position.y = arr[1];
|
||||
position.z = arr[2];
|
||||
*/
|
||||
#end
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
public function setPosition(value:Vector4):Vector4
|
||||
{
|
||||
position.x = value.x;
|
||||
position.y = value.y;
|
||||
position.z = value.z;
|
||||
position.w = value.w;
|
||||
|
||||
#if lime_howlerjs
|
||||
if (parent.buffer != null && parent.buffer.__srcHowl != null && parent.buffer.__srcHowl.pos != null) parent.buffer.__srcHowl.pos(position.x, position.y, position.z, id);
|
||||
// There are more settings to the position of the sound on the "pannerAttr()" function of howler. Maybe somebody who understands sound should look into it?
|
||||
#end
|
||||
|
||||
return position;
|
||||
}
|
||||
}
|
||||
@@ -34,16 +34,19 @@ class NativeAudioSource
|
||||
private var dataLength:Int;
|
||||
private var format:Int;
|
||||
private var handle:ALSource;
|
||||
private var length:Null<Int>;
|
||||
private var length:Null<Float>;
|
||||
private var loops:Int;
|
||||
private var parent:AudioSource;
|
||||
private var playing:Bool;
|
||||
private var position:Vector4;
|
||||
private var samples:Int;
|
||||
private var samples:Float;
|
||||
private var stream:Bool;
|
||||
private var streamTimer:Timer;
|
||||
private var timer:Timer;
|
||||
|
||||
private var pcmTotal:Int64;
|
||||
private var sampleRate:Int;
|
||||
|
||||
var disposed:Bool = false;
|
||||
|
||||
public function new(parent:AudioSource)
|
||||
@@ -107,7 +110,11 @@ class NativeAudioSource
|
||||
stream = true;
|
||||
|
||||
var vorbisFile = parent.buffer.__srcVorbisFile;
|
||||
dataLength = Std.int(Int64.toInt(vorbisFile.pcmTotal()) * parent.buffer.channels * (parent.buffer.bitsPerSample / 8));
|
||||
pcmTotal = vorbisFile.pcmTotal();
|
||||
var info = vorbisFile.info();
|
||||
sampleRate = info.rate;
|
||||
var _dataLength = pcmTotal * Int64.ofInt(parent.buffer.channels) * (Int64.ofInt(parent.buffer.bitsPerSample) / Int64.ofInt(8));
|
||||
dataLength = Int64.toInt(_dataLength);
|
||||
|
||||
buffers = new Array();
|
||||
bufferTimeBlocks = new Array();
|
||||
@@ -119,6 +126,8 @@ class NativeAudioSource
|
||||
}
|
||||
|
||||
handle = AL.createSource();
|
||||
|
||||
samples = Int64.toInt(pcmTotal);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -140,43 +149,15 @@ class NativeAudioSource
|
||||
{
|
||||
AL.sourcei(handle, AL.BUFFER, parent.buffer.__srcBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
samples = Std.int((dataLength * 8) / (parent.buffer.channels * parent.buffer.bitsPerSample));
|
||||
samples = Int64.toInt((Int64.make(0, dataLength) * Int64.ofInt(8)) / Int64.ofInt(parent.buffer.channels * parent.buffer.bitsPerSample));
|
||||
}
|
||||
|
||||
initBuffers.push(this);
|
||||
}
|
||||
|
||||
public function play():Void
|
||||
{
|
||||
/*var pitch:Float = AL.getSourcef (handle, AL.PITCH);
|
||||
trace(pitch);
|
||||
AL.sourcef (handle, AL.PITCH, pitch*0.9);
|
||||
pitch = AL.getSourcef (handle, AL.PITCH);
|
||||
trace(pitch); */
|
||||
/*var pos = getPosition();
|
||||
trace(AL.DISTANCE_MODEL);
|
||||
AL.distanceModel(AL.INVERSE_DISTANCE);
|
||||
trace(AL.DISTANCE_MODEL);
|
||||
AL.sourcef(handle, AL.ROLLOFF_FACTOR, 5);
|
||||
setPosition(new Vector4(10, 10, -100));
|
||||
pos = getPosition();
|
||||
trace(pos); */
|
||||
/*var filter = AL.createFilter();
|
||||
trace(AL.getErrorString());
|
||||
|
||||
AL.filteri(filter, AL.FILTER_TYPE, AL.FILTER_LOWPASS);
|
||||
trace(AL.getErrorString());
|
||||
|
||||
AL.filterf(filter, AL.LOWPASS_GAIN, 0.5);
|
||||
trace(AL.getErrorString());
|
||||
|
||||
AL.filterf(filter, AL.LOWPASS_GAINHF, 0.5);
|
||||
trace(AL.getErrorString());
|
||||
|
||||
AL.sourcei(handle, AL.DIRECT_FILTER, filter);
|
||||
trace(AL.getErrorString()); */
|
||||
|
||||
if (disposed) {
|
||||
trace("TRIED TO PLAY DISPOSED?? WTFFF");
|
||||
trace(haxe.CallStack.toString(haxe.CallStack.callStack()));
|
||||
@@ -373,7 +354,7 @@ class NativeAudioSource
|
||||
}
|
||||
|
||||
// Get & Set Methods
|
||||
public function getCurrentTime():Int
|
||||
public function getCurrentTime():Float
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
@@ -389,11 +370,11 @@ class NativeAudioSource
|
||||
}
|
||||
else
|
||||
{
|
||||
var offset = AL.getSourcei(handle, AL.BYTE_OFFSET);
|
||||
var offset:Int = AL.getSourcei(handle, AL.BYTE_OFFSET);
|
||||
var ratio = (offset / dataLength);
|
||||
var totalSeconds = samples / parent.buffer.sampleRate;
|
||||
|
||||
var time = Std.int(totalSeconds * ratio * 1000) - parent.offset;
|
||||
var time = totalSeconds * ratio * 1000 - parent.offset;
|
||||
|
||||
// var time = Std.int (AL.getSourcef (handle, AL.SEC_OFFSET) * 1000) - parent.offset;
|
||||
if (time < 0) return 0;
|
||||
@@ -404,7 +385,7 @@ class NativeAudioSource
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function setCurrentTime(value:Int):Int
|
||||
public function setCurrentTime(value:Float):Float
|
||||
{
|
||||
// `setCurrentTime()` has side effects and is never safe to skip.
|
||||
/* if (value == getCurrentTime())
|
||||
@@ -434,7 +415,7 @@ class NativeAudioSource
|
||||
var totalSeconds = samples / parent.buffer.sampleRate;
|
||||
|
||||
if (secondOffset < 0) secondOffset = 0;
|
||||
if (secondOffset > totalSeconds) secondOffset = totalSeconds;
|
||||
else if (secondOffset > totalSeconds) secondOffset = totalSeconds;
|
||||
|
||||
var ratio = (secondOffset / totalSeconds);
|
||||
var totalOffset = Std.int(dataLength * ratio);
|
||||
@@ -451,7 +432,7 @@ class NativeAudioSource
|
||||
timer.stop();
|
||||
}
|
||||
|
||||
var timeRemaining = Std.int((getLength() - value) / getPitch());
|
||||
var timeRemaining = (getLength() - value) / getPitch();
|
||||
|
||||
if (timeRemaining > 0)
|
||||
{
|
||||
@@ -491,17 +472,17 @@ class NativeAudioSource
|
||||
return value;
|
||||
}
|
||||
|
||||
public function getLength():Int
|
||||
public function getLength():Float
|
||||
{
|
||||
if (length != null)
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
return Std.int(samples / parent.buffer.sampleRate * 1000) - parent.offset;
|
||||
return (samples / parent.buffer.sampleRate * 1000) - parent.offset;
|
||||
}
|
||||
|
||||
public function setLength(value:Int):Int
|
||||
public function setLength(value:Float):Float
|
||||
{
|
||||
if (playing && length != value)
|
||||
{
|
||||
@@ -510,7 +491,7 @@ class NativeAudioSource
|
||||
timer.stop();
|
||||
}
|
||||
|
||||
var timeRemaining = Std.int((value - getCurrentTime()) / getPitch());
|
||||
var timeRemaining = (value - getCurrentTime()) / getPitch();
|
||||
|
||||
if (timeRemaining > 0)
|
||||
{
|
||||
@@ -553,7 +534,7 @@ class NativeAudioSource
|
||||
timer.stop();
|
||||
}
|
||||
|
||||
var timeRemaining = Std.int((getLength() - getCurrentTime()) / value);
|
||||
var timeRemaining = (getLength() - getCurrentTime()) / value;
|
||||
|
||||
if (timeRemaining > 0)
|
||||
{
|
||||
|
||||
@@ -13,9 +13,9 @@ class AudioSource
|
||||
{
|
||||
public var onComplete = new Event<Void->Void>();
|
||||
public var buffer:AudioBuffer;
|
||||
public var currentTime(get, set):Int;
|
||||
public var currentTime(get, set):Float;
|
||||
public var gain(get, set):Float;
|
||||
public var length(get, set):Int;
|
||||
public var length(get, set):Float;
|
||||
public var loops(get, set):Int;
|
||||
public var pitch(get, set):Float;
|
||||
public var offset:Int;
|
||||
@@ -69,12 +69,12 @@ class AudioSource
|
||||
}
|
||||
|
||||
// Get & Set Methods
|
||||
@:noCompletion private function get_currentTime():Int
|
||||
@:noCompletion private function get_currentTime():Float
|
||||
{
|
||||
return __backend.getCurrentTime();
|
||||
}
|
||||
|
||||
@:noCompletion private function set_currentTime(value:Int):Int
|
||||
@:noCompletion private function set_currentTime(value:Float):Float
|
||||
{
|
||||
return __backend.setCurrentTime(value);
|
||||
}
|
||||
@@ -89,12 +89,12 @@ class AudioSource
|
||||
return __backend.setGain(value);
|
||||
}
|
||||
|
||||
@:noCompletion private function get_length():Int
|
||||
@:noCompletion private function get_length():Float
|
||||
{
|
||||
return __backend.getLength();
|
||||
}
|
||||
|
||||
@:noCompletion private function set_length(value:Int):Int
|
||||
@:noCompletion private function set_length(value:Float):Float
|
||||
{
|
||||
return __backend.setLength(value);
|
||||
}
|
||||
|
||||
@@ -599,16 +599,16 @@ class Sound extends EventDispatcher
|
||||
#end
|
||||
}
|
||||
|
||||
var changeID:Int = 0;
|
||||
public function regen() {
|
||||
var audioBuffer = new AudioBuffer();
|
||||
var changeID:Int = 0;
|
||||
public function regen() {
|
||||
var audioBuffer = new AudioBuffer();
|
||||
audioBuffer.bitsPerSample = __buffer.bitsPerSample;
|
||||
audioBuffer.channels = __buffer.channels;
|
||||
audioBuffer.data = __buffer.data;
|
||||
audioBuffer.sampleRate = __buffer.sampleRate;
|
||||
|
||||
__buffer = audioBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Generates a new SoundChannel object to play back the sound. This method
|
||||
@@ -636,10 +636,10 @@ class Sound extends EventDispatcher
|
||||
return null;
|
||||
}
|
||||
|
||||
if (changeID < funkin.system.Main.changeID) {
|
||||
changeID = funkin.system.Main.changeID;
|
||||
regen();
|
||||
}
|
||||
if (changeID < funkin.system.Main.changeID) {
|
||||
changeID = funkin.system.Main.changeID;
|
||||
regen();
|
||||
}
|
||||
|
||||
if (sndTransform == null)
|
||||
{
|
||||
@@ -653,7 +653,7 @@ class Sound extends EventDispatcher
|
||||
var pan = SoundMixer.__soundTransform.pan + sndTransform.pan;
|
||||
|
||||
if (pan > 1) pan = 1;
|
||||
if (pan < -1) pan = -1;
|
||||
else if (pan < -1) pan = -1;
|
||||
|
||||
var volume = SoundMixer.__soundTransform.volume * sndTransform.volume;
|
||||
|
||||
@@ -680,23 +680,29 @@ class Sound extends EventDispatcher
|
||||
return new ID3Info();
|
||||
}
|
||||
|
||||
@:noCompletion private function get_length():Int
|
||||
@:noCompletion private function get_length():Float
|
||||
{
|
||||
#if lime
|
||||
if (__buffer != null)
|
||||
{
|
||||
#if (js && html5 && howlerjs)
|
||||
return Std.int(__buffer.src.duration() * 1000);
|
||||
return __buffer.src.duration() * 1000;
|
||||
#else
|
||||
if (__buffer.data != null)
|
||||
{
|
||||
var samples = (__buffer.data.length * 8) / (__buffer.channels * __buffer.bitsPerSample);
|
||||
return Std.int(samples / __buffer.sampleRate * 1000);
|
||||
// var samples = (__buffer.data.length * 8) / (__buffer.channels * __buffer.bitsPerSample);
|
||||
// return Std.int(samples / __buffer.sampleRate * 1000);
|
||||
var samples = (Int64.make(0, __buffer.data.length) * Int64.ofInt(8)) / Int64.ofInt(__buffer.channels * __buffer.bitsPerSample);
|
||||
var value = samples / Int64.ofInt(__buffer.sampleRate) * Int64.ofInt(1000);
|
||||
return Int64.toInt(value);
|
||||
}
|
||||
else if (__buffer.__srcVorbisFile != null)
|
||||
{
|
||||
var samples = Int64.toInt(__buffer.__srcVorbisFile.pcmTotal());
|
||||
return Std.int(samples / __buffer.sampleRate * 1000);
|
||||
//var samples = Int64.toInt(__buffer.__srcVorbisFile.pcmTotal());
|
||||
//return Std.int(samples / __buffer.sampleRate * 1000);
|
||||
var samples = __buffer.__srcVorbisFile.pcmTotal();
|
||||
var value = Int64.fromFloat(__buffer.__srcVorbisFile.timeTotal()) * 1000;
|
||||
return Int64.toInt(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
package openfl.media;
|
||||
|
||||
#if !flash
|
||||
import openfl.events.Event;
|
||||
import openfl.events.EventDispatcher;
|
||||
#if lime
|
||||
import lime.media.AudioSource;
|
||||
#end
|
||||
|
||||
/**
|
||||
The SoundChannel class controls a sound in an application. Every sound is
|
||||
assigned to a sound channel, and the application can have multiple sound
|
||||
channels that are mixed together. The SoundChannel class contains a
|
||||
`stop()` method, properties for monitoring the amplitude
|
||||
(volume) of the channel, and a property for assigning a SoundTransform
|
||||
object to the channel.
|
||||
|
||||
@event soundComplete Dispatched when a sound has finished playing.
|
||||
**/
|
||||
#if !openfl_debug
|
||||
@:fileXml('tags="haxe,release"')
|
||||
@:noDebug
|
||||
#end
|
||||
@:access(openfl.media.SoundMixer)
|
||||
@:final @:keep class SoundChannel extends EventDispatcher
|
||||
{
|
||||
/**
|
||||
The current amplitude(volume) of the left channel, from 0(silent) to 1
|
||||
(full amplitude).
|
||||
**/
|
||||
public var leftPeak(default, null):Float;
|
||||
|
||||
/**
|
||||
When the sound is playing, the `position` property indicates in
|
||||
milliseconds the current point that is being played in the sound file.
|
||||
When the sound is stopped or paused, the `position` property
|
||||
indicates the last point that was played in the sound file.
|
||||
|
||||
A common use case is to save the value of the `position`
|
||||
property when the sound is stopped. You can resume the sound later by
|
||||
restarting it from that saved position.
|
||||
|
||||
If the sound is looped, `position` is reset to 0 at the
|
||||
beginning of each loop.
|
||||
**/
|
||||
public var position(get, set):Float;
|
||||
|
||||
/**
|
||||
The current amplitude(volume) of the right channel, from 0(silent) to 1
|
||||
(full amplitude).
|
||||
**/
|
||||
public var rightPeak(default, null):Float;
|
||||
|
||||
/**
|
||||
The SoundTransform object assigned to the sound channel. A SoundTransform
|
||||
object includes properties for setting volume, panning, left speaker
|
||||
assignment, and right speaker assignment.
|
||||
**/
|
||||
public var soundTransform(get, set):SoundTransform;
|
||||
|
||||
public var pitch(get, set):Float;
|
||||
|
||||
@:noCompletion private var __isValid:Bool;
|
||||
@:noCompletion private var __soundTransform:SoundTransform;
|
||||
#if lime
|
||||
@:noCompletion private var __source:AudioSource;
|
||||
#end
|
||||
|
||||
#if openfljs
|
||||
@:noCompletion private static function __init__()
|
||||
{
|
||||
untyped Object.defineProperties(SoundChannel.prototype, {
|
||||
"position": {
|
||||
get: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function () { return this.get_position (); }"),
|
||||
set: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function (v) { return this.set_position (v); }")
|
||||
},
|
||||
"soundTransform": {
|
||||
get: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function () { return this.get_soundTransform (); }"),
|
||||
set: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function (v) { return this.set_soundTransform (v); }")
|
||||
},
|
||||
});
|
||||
}
|
||||
#end
|
||||
|
||||
@:noCompletion private function new(source:#if lime AudioSource #else Dynamic #end = null, soundTransform:SoundTransform = null):Void
|
||||
{
|
||||
super(this);
|
||||
|
||||
leftPeak = 1;
|
||||
rightPeak = 1;
|
||||
|
||||
if (soundTransform != null)
|
||||
{
|
||||
__soundTransform = soundTransform;
|
||||
}
|
||||
else
|
||||
{
|
||||
__soundTransform = new SoundTransform();
|
||||
}
|
||||
|
||||
#if lime
|
||||
if (source != null)
|
||||
{
|
||||
__source = source;
|
||||
__source.onComplete.add(source_onComplete);
|
||||
__isValid = true;
|
||||
|
||||
__source.play();
|
||||
}
|
||||
#end
|
||||
|
||||
SoundMixer.__registerSoundChannel(this);
|
||||
}
|
||||
|
||||
/**
|
||||
Stops the sound playing in the channel.
|
||||
**/
|
||||
public function stop():Void
|
||||
{
|
||||
SoundMixer.__unregisterSoundChannel(this);
|
||||
|
||||
if (!__isValid) return;
|
||||
|
||||
#if lime
|
||||
__source.stop();
|
||||
#end
|
||||
__dispose();
|
||||
}
|
||||
|
||||
@:noCompletion private function __dispose():Void
|
||||
{
|
||||
if (!__isValid) return;
|
||||
|
||||
#if lime
|
||||
__source.onComplete.remove(source_onComplete);
|
||||
__source.dispose();
|
||||
__source = null;
|
||||
#end
|
||||
__isValid = false;
|
||||
}
|
||||
|
||||
@:noCompletion private function __updateTransform():Void
|
||||
{
|
||||
this.soundTransform = soundTransform;
|
||||
}
|
||||
|
||||
// Get & Set Methods
|
||||
@:noCompletion private function get_position():Float
|
||||
{
|
||||
if (!__isValid) return 0;
|
||||
|
||||
#if lime
|
||||
return __source.currentTime + __source.offset;
|
||||
#else
|
||||
return 0;
|
||||
#end
|
||||
}
|
||||
|
||||
@:noCompletion private function set_position(value:Float):Float
|
||||
{
|
||||
if (!__isValid) return 0;
|
||||
|
||||
#if lime
|
||||
__source.currentTime = value - __source.offset;
|
||||
#end
|
||||
return value;
|
||||
}
|
||||
|
||||
@:noCompletion private function get_pitch():Float
|
||||
{
|
||||
if (!__isValid) return 1;
|
||||
|
||||
#if lime
|
||||
return __source.pitch;
|
||||
#else
|
||||
return 1;
|
||||
#end
|
||||
}
|
||||
|
||||
@:noCompletion private function set_pitch(value:Float):Float
|
||||
{
|
||||
if (!__isValid) return 1;
|
||||
|
||||
#if lime
|
||||
__source.pitch = value;
|
||||
#end
|
||||
return value;
|
||||
}
|
||||
|
||||
@:noCompletion private function get_soundTransform():SoundTransform
|
||||
{
|
||||
return __soundTransform.clone();
|
||||
}
|
||||
|
||||
@:noCompletion private function set_soundTransform(value:SoundTransform):SoundTransform
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
__soundTransform.pan = value.pan;
|
||||
__soundTransform.volume = value.volume;
|
||||
|
||||
var pan = SoundMixer.__soundTransform.pan + __soundTransform.pan;
|
||||
|
||||
if (pan < -1) pan = -1;
|
||||
else if (pan > 1) pan = 1;
|
||||
|
||||
var volume = SoundMixer.__soundTransform.volume * __soundTransform.volume;
|
||||
|
||||
if (__isValid)
|
||||
{
|
||||
#if lime
|
||||
__source.gain = volume;
|
||||
|
||||
var position = __source.position;
|
||||
position.x = pan;
|
||||
position.z = -1 * Math.sqrt(1 - Math.pow(pan, 2));
|
||||
__source.position = position;
|
||||
|
||||
return value;
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// Event Handlers
|
||||
@:noCompletion private function source_onComplete():Void
|
||||
{
|
||||
SoundMixer.__unregisterSoundChannel(this);
|
||||
|
||||
__dispose();
|
||||
dispatchEvent(new Event(Event.SOUND_COMPLETE));
|
||||
}
|
||||
}
|
||||
#else
|
||||
typedef SoundChannel = flash.media.SoundChannel;
|
||||
#end
|
||||
Reference in New Issue
Block a user