From a9df83d90507e29fdefaeff0036860d5e6907987 Mon Sep 17 00:00:00 2001 From: Yoshman29 <81191621+YoshiCrafter29@users.noreply.github.com> Date: Mon, 6 Feb 2023 13:08:15 +0100 Subject: [PATCH] documentation --- Project.xml | 3 + assets/songs/guns/cutscene.hx | 2 +- assets/songs/stress/cutscene.hx | 2 +- assets/songs/ugh/cutscene.hx | 2 +- buildnumber.txt | 2 +- source/funkin/cutscenes/Cutscene.hx | 3 + source/funkin/cutscenes/DialogueCutscene.hx | 3 + source/funkin/cutscenes/ScriptedCutscene.hx | 4 + source/funkin/cutscenes/VideoCutscene.hx | 3 + source/funkin/debug/AnimationDebug.hx | 197 -------------------- source/funkin/game/PlayState.hx | 40 ++-- source/funkin/macros/BuildCounterMacro.hx | 9 +- source/funkin/macros/EventMacro.hx | 5 +- source/funkin/macros/FlxSpriteProxyMacro.hx | 106 ----------- source/funkin/macros/OptionsMacro.hx | 4 + source/funkin/macros/ScriptsMacro.hx | 3 + source/funkin/system/FunkinGame.hx | 20 ++ source/funkin/system/Main.hx | 2 +- source/funkin/system/Paths.hx | 3 + source/funkin/utils/NdllUtil.hx | 64 +++++++ 20 files changed, 154 insertions(+), 323 deletions(-) delete mode 100644 source/funkin/debug/AnimationDebug.hx delete mode 100644 source/funkin/macros/FlxSpriteProxyMacro.hx create mode 100644 source/funkin/system/FunkinGame.hx diff --git a/Project.xml b/Project.xml index dca9035c..6aba35bc 100644 --- a/Project.xml +++ b/Project.xml @@ -125,6 +125,9 @@ + + + diff --git a/assets/songs/guns/cutscene.hx b/assets/songs/guns/cutscene.hx index 14ee6544..3485f80d 100644 --- a/assets/songs/guns/cutscene.hx +++ b/assets/songs/guns/cutscene.hx @@ -4,7 +4,7 @@ var tankman:FunkinSprite; var tankTalk1, distorto:FlxSound; function create() { - FlxG.camera.zoom = 1; + FlxTween.tween(FlxG.camera, {zoom: 1}, 0.7, {ease: FlxEase.quadInOut}); game.camHUD.visible = false; tankman = new FunkinSprite(game.dad.x + game.dad.globalOffset.x + 520, game.dad.y + game.dad.globalOffset.y + 225); diff --git a/assets/songs/stress/cutscene.hx b/assets/songs/stress/cutscene.hx index 5df98a5b..d7601ff0 100644 --- a/assets/songs/stress/cutscene.hx +++ b/assets/songs/stress/cutscene.hx @@ -8,7 +8,7 @@ var stressCutscene:FlxSound; var step:Int = 0; function create() { - FlxG.camera.zoom = 1; + // FlxTween.tween(FlxG.camera, {zoom: 1}, 0.7, {ease: FlxEase.quadInOut}); game.camHUD.visible = false; game.persistentUpdate = true; diff --git a/assets/songs/ugh/cutscene.hx b/assets/songs/ugh/cutscene.hx index a746c3a9..7fafc537 100644 --- a/assets/songs/ugh/cutscene.hx +++ b/assets/songs/ugh/cutscene.hx @@ -4,7 +4,7 @@ var tankman:FunkinSprite; var tankTalk1, tankTalk2, bfBeep, distorto:FlxSound; function create() { - FlxG.camera.zoom = 1; + FlxTween.tween(FlxG.camera, {zoom: 1}, 0.7, {ease: FlxEase.quadInOut}); game.camHUD.visible = false; tankman = new FunkinSprite(game.dad.x + game.dad.globalOffset.x + 520, game.dad.y + game.dad.globalOffset.y + 225); diff --git a/buildnumber.txt b/buildnumber.txt index cf548ec4..4063cbd0 100644 --- a/buildnumber.txt +++ b/buildnumber.txt @@ -1 +1 @@ -2219 \ No newline at end of file +2223 \ No newline at end of file diff --git a/source/funkin/cutscenes/Cutscene.hx b/source/funkin/cutscenes/Cutscene.hx index 72507fb9..f13e5a1a 100644 --- a/source/funkin/cutscenes/Cutscene.hx +++ b/source/funkin/cutscenes/Cutscene.hx @@ -1,5 +1,8 @@ package funkin.cutscenes; +/** + * Substate made for cutscenes. + */ class Cutscene extends MusicBeatSubstate { var __callback:Void->Void; var game:PlayState = PlayState.instance; diff --git a/source/funkin/cutscenes/DialogueCutscene.hx b/source/funkin/cutscenes/DialogueCutscene.hx index ce41c3fd..58766b30 100644 --- a/source/funkin/cutscenes/DialogueCutscene.hx +++ b/source/funkin/cutscenes/DialogueCutscene.hx @@ -7,6 +7,9 @@ import openfl.utils.Assets; import funkin.cutscenes.dialogue.*; import haxe.xml.Access; +/** + * Substate made for dialogue cutscenes. To use it in a scripted cutscene, call `startDialogue`. + */ class DialogueCutscene extends Cutscene { public var dialoguePath:String; public var dialogueData:Access; diff --git a/source/funkin/cutscenes/ScriptedCutscene.hx b/source/funkin/cutscenes/ScriptedCutscene.hx index 3bc8d977..f3b4e5ac 100644 --- a/source/funkin/cutscenes/ScriptedCutscene.hx +++ b/source/funkin/cutscenes/ScriptedCutscene.hx @@ -4,6 +4,10 @@ import funkin.scripting.DummyScript; import flixel.addons.transition.FlxTransitionableState; import funkin.scripting.Script; +/** + * Substate made for scripted cutscenes. + * To add cutscenes to your songs, add a `cutscene.hx` file in your song's directory (ex: `songs/song/cutscene.hx`) + */ class ScriptedCutscene extends Cutscene { var script:Script; diff --git a/source/funkin/cutscenes/VideoCutscene.hx b/source/funkin/cutscenes/VideoCutscene.hx index ccb54eb5..75a359e4 100644 --- a/source/funkin/cutscenes/VideoCutscene.hx +++ b/source/funkin/cutscenes/VideoCutscene.hx @@ -5,6 +5,9 @@ import flixel.FlxG; import flixel.FlxCamera; import openfl.utils.Assets; +/** + * Substate made for video cutscenes. To use it in a scripted cutscene, call `startVideo`. + */ class VideoCutscene extends Cutscene { var path:String; var localPath:String; diff --git a/source/funkin/debug/AnimationDebug.hx b/source/funkin/debug/AnimationDebug.hx deleted file mode 100644 index bb2c9c80..00000000 --- a/source/funkin/debug/AnimationDebug.hx +++ /dev/null @@ -1,197 +0,0 @@ -package funkin.debug; - -import funkin.game.Character; -import flixel.FlxG; -import flixel.FlxObject; -import flixel.FlxSprite; -import flixel.FlxState; -import flixel.addons.display.FlxGridOverlay; -import flixel.group.FlxGroup.FlxTypedGroup; -import flixel.text.FlxText; -import flixel.util.FlxColor; - -/** - *DEBUG MODE - */ -class AnimationDebug extends FlxState -{ - var bf:Character; - var dad:Character; - var char:Character; - var textAnim:FlxText; - var dumbTexts:FlxTypedGroup; - var animList:Array = []; - var curAnim:Int = 0; - var isDad:Bool = true; - var daAnim:String = 'spooky'; - var camFollow:FlxObject; - - public function new(daAnim:String = 'spooky') - { - super(); - this.daAnim = daAnim; - } - - override function create() - { - if (FlxG.sound.music != null) - FlxG.sound.music.stop(); - - var gridBG:FlxSprite = FlxGridOverlay.create(10, 10); - gridBG.scrollFactor.set(0.5, 0.5); - add(gridBG); - - if (daAnim == 'bf') - isDad = false; - - if (isDad) - { - dad = new Character(0, 0, daAnim); - dad.screenCenter(); - dad.debugMode = true; - add(dad); - - char = dad; - dad.flipX = false; - } - else - { - bf = new Character(0, 0, daAnim, true); - bf.screenCenter(); - bf.debugMode = true; - add(bf); - - char = bf; - bf.flipX = false; - } - - dumbTexts = new FlxTypedGroup(); - add(dumbTexts); - - textAnim = new FlxText(300, 16); - textAnim.size = 26; - textAnim.scrollFactor.set(); - add(textAnim); - - genBoyOffsets(); - - camFollow = new FlxObject(0, 0, 2, 2); - camFollow.screenCenter(); - add(camFollow); - - FlxG.camera.follow(camFollow); - - super.create(); - } - - function genBoyOffsets(pushList:Bool = true):Void - { - var daLoop:Int = 0; - - for (anim => offsets in char.animOffsets) - { - var text:FlxText = new FlxText(10, 20 + (18 * daLoop), 0, anim + ": " + offsets, 15); - text.scrollFactor.set(); - text.color = FlxColor.BLUE; - dumbTexts.add(text); - - if (pushList) - animList.push(anim); - - daLoop++; - } - } - - function updateTexts():Void - { - dumbTexts.forEach(function(text:FlxText) - { - text.kill(); - dumbTexts.remove(text, true); - }); - } - - override function update(elapsed:Float) - { - textAnim.text = char.animation.curAnim.name; - - if (FlxG.keys.justPressed.E) - FlxG.camera.zoom += 0.25; - if (FlxG.keys.justPressed.Q) - FlxG.camera.zoom -= 0.25; - - if (FlxG.keys.pressed.I || FlxG.keys.pressed.J || FlxG.keys.pressed.K || FlxG.keys.pressed.L) - { - if (FlxG.keys.pressed.I) - camFollow.velocity.y = -90; - else if (FlxG.keys.pressed.K) - camFollow.velocity.y = 90; - else - camFollow.velocity.y = 0; - - if (FlxG.keys.pressed.J) - camFollow.velocity.x = -90; - else if (FlxG.keys.pressed.L) - camFollow.velocity.x = 90; - else - camFollow.velocity.x = 0; - } - else - { - camFollow.velocity.set(); - } - - if (FlxG.keys.justPressed.W) - { - curAnim -= 1; - } - - if (FlxG.keys.justPressed.S) - { - curAnim += 1; - } - - if (curAnim < 0) - curAnim = animList.length - 1; - - if (curAnim >= animList.length) - curAnim = 0; - - if (FlxG.keys.justPressed.S || FlxG.keys.justPressed.W || FlxG.keys.justPressed.SPACE) - { - char.playAnim(animList[curAnim]); - - updateTexts(); - genBoyOffsets(false); - } - - var upP = FlxG.keys.anyJustPressed([UP]); - var rightP = FlxG.keys.anyJustPressed([RIGHT]); - var downP = FlxG.keys.anyJustPressed([DOWN]); - var leftP = FlxG.keys.anyJustPressed([LEFT]); - - var holdShift = FlxG.keys.pressed.SHIFT; - var multiplier = 1; - if (holdShift) - multiplier = 10; - - if (upP || rightP || downP || leftP) - { - updateTexts(); - if (upP) - char.animOffsets.get(animList[curAnim]).y += 1 * multiplier; - if (downP) - char.animOffsets.get(animList[curAnim]).y -= 1 * multiplier; - if (leftP) - char.animOffsets.get(animList[curAnim]).x += 1 * multiplier; - if (rightP) - char.animOffsets.get(animList[curAnim]).x -= 1 * multiplier; - - updateTexts(); - genBoyOffsets(false); - char.playAnim(animList[curAnim]); - } - - super.update(elapsed); - } -} diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index 5dc1e451..b8431a2c 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -193,7 +193,7 @@ class PlayState extends MusicBeatState /** * Previous cam follow. */ - private static var prevCamFollow:FlxObject; + private static var smoothTransitionData:PlayStateTransitionData; /** * All of the strum line notes. @@ -553,8 +553,6 @@ class PlayState extends MusicBeatState } var dadMidpoint = dad.getGraphicMidpoint(); - var camPos:FlxPoint = new FlxPoint(dadMidpoint.x, dadMidpoint.y); - dadMidpoint.put(); comboGroup = new FlxSpriteGroup(FlxG.width * 0.55, (FlxG.height * 0.5) - 60); @@ -565,6 +563,9 @@ class PlayState extends MusicBeatState if (SONG.stage == null || SONG.stage.trim() == "") SONG.stage = "stage"; add(stage = new Stage(SONG.stage)); + var camPos:FlxPoint = new FlxPoint(dadMidpoint.x, dadMidpoint.y); + dadMidpoint.put(); + switch(SONG.song) { // case "": @@ -619,19 +620,19 @@ class PlayState extends MusicBeatState generateSong(SONG); - if (prevCamFollow != null) - { - camFollow = prevCamFollow; - prevCamFollow = null; - } else { - camFollow = new FlxObject(0, 0, 2, 2); - camFollow.setPosition(camPos.x, camPos.y); - } + camFollow = new FlxObject(0, 0, 2, 2); + camFollow.setPosition(camPos.x, camPos.y); add(camFollow); FlxG.camera.follow(camFollow, LOCKON, 0.04); FlxG.camera.zoom = defaultCamZoom; - FlxG.camera.focusOn(camFollow.getPosition()); + if (smoothTransitionData != null && smoothTransitionData.stage == curStage) { + FlxG.camera.scroll.set(smoothTransitionData.camX, smoothTransitionData.camY); + FlxG.camera.zoom = smoothTransitionData.camZoom; + FlxTransitionableState.skipNextTransIn = true; + } else { + FlxG.camera.focusOn(camFollow.getPosition()); + } FlxG.worldBounds.set(0, 0, FlxG.width, FlxG.height); @@ -1356,9 +1357,15 @@ class PlayState extends MusicBeatState trace('LOADING NEXT SONG'); trace(PlayState.storyPlaylist[0].toLowerCase(), difficulty); + smoothTransitionData = { + stage: curStage, + camX: FlxG.camera.scroll.x, + camY: FlxG.camera.scroll.y, + camZoom: FlxG.camera.zoom + }; FlxTransitionableState.skipNextTransIn = true; FlxTransitionableState.skipNextTransOut = true; - prevCamFollow = camFollow; + PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase(), difficulty); FlxG.sound.music.stop(); @@ -1705,4 +1712,11 @@ class ComboRating { this.rating = rating; this.color = color; } +} + +typedef PlayStateTransitionData = { + var stage:String; + var camX:Float; + var camY:Float; + var camZoom:Float; } \ No newline at end of file diff --git a/source/funkin/macros/BuildCounterMacro.hx b/source/funkin/macros/BuildCounterMacro.hx index 48a07d5f..6f18d997 100644 --- a/source/funkin/macros/BuildCounterMacro.hx +++ b/source/funkin/macros/BuildCounterMacro.hx @@ -8,8 +8,15 @@ import haxe.macro.Context; import sys.io.File; #end +/** + * Macro that loads the current build number from `buildnumber.txt`, then make it available as an integer. + * + * `buildnumber.txt` is automatically incremented when the engine is launched with `lime test windows`. + */ class BuildCounterMacro { - // non functional + /** + * Returns the obtained build number. + */ public static macro function getBuildNumber():haxe.macro.Expr.ExprOf { #if !display var buildNum:Int = Std.parseInt(File.getContent("buildnumber.txt")); diff --git a/source/funkin/macros/EventMacro.hx b/source/funkin/macros/EventMacro.hx index bbcb8b37..de6a4d7d 100644 --- a/source/funkin/macros/EventMacro.hx +++ b/source/funkin/macros/EventMacro.hx @@ -1,7 +1,10 @@ package funkin.macros; #if macro - +/** + * 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. + */ class EventMacro { public static function build():Array { var fields = Context.getBuildFields(); diff --git a/source/funkin/macros/FlxSpriteProxyMacro.hx b/source/funkin/macros/FlxSpriteProxyMacro.hx deleted file mode 100644 index 1e111619..00000000 --- a/source/funkin/macros/FlxSpriteProxyMacro.hx +++ /dev/null @@ -1,106 +0,0 @@ -package funkin.macros; -#if macro - -class FlxSpriteProxyMacro { - public static function build() { - return Context.getBuildFields(); - - /* - //TODO: FIX ALL OF THIS - var parentFields:Array = []; - var parentFieldsNames:Array = []; - var superClass = Context.getLocalClass().get().superClass.t.get(); - while(superClass != null) { - for(e in superClass.fields.get()) { - if (!parentFieldsNames.contains(e.name) && !e.kind.match(FMethod(MethInline))) { - parentFields.push(e); - parentFieldsNames.push(e.name); - } - } - if (superClass.superClass != null) - superClass = superClass.superClass.t.get(); - else - superClass = null; - } - parentFieldsNames = []; - trace(Context.getLocalType()); - var fields:Array = Context.getBuildFields(); - - // loop through all parent functions - for(f in parentFields) { - for(field in fields) - if (field.name == f.name) - continue; - switch(f.type) { - case TLazy(lazyFunc): - switch(lazyFunc()) { - case TFun(args, ret): - - // its a function / getter / setter! overriding - var overFunc:Function = { - args: [for(a in args) { - value: null, - type: TypeTools.toComplexType(a.t), - opt: a.opt, - name: a.name - }] - }; - var funcName = f.name; - - var argNames:Array = []; - for(a in args) - argNames.push({ - pos: Context.makePosition({ - min: 1, - max: 2, - file: "DeezNuts.hx" - }), - expr: EConst(CIdent(a.name)) - }); - if (ret == null) { - overFunc.expr = macro { - function test(p1) { - trace(p1); - } - if (this.proxy != null) { - this.proxy.$funcName($a{argNames}); - return; - } - super.$funcName($a{argNames}); - }; - } else { - overFunc.expr = macro { - if (this.proxy != null) { - return this.proxy.$funcName($a{argNames}); - } - return super.$funcName($a{argNames}); - }; - } - var field:Field = { - pos: Context.makePosition({ - min: 0, - max: 0, - file: "DeezNuts.hx" - }), - name: f.name, - kind: FFun(overFunc), - access: [AOverride, APublic] - }; - var p = new Printer(); - trace(p.printField(field)); - fields.push(field); - default: - // nothing - } - default: - // nothing - } - } - - - - return fields; - */ - } -} -#end \ No newline at end of file diff --git a/source/funkin/macros/OptionsMacro.hx b/source/funkin/macros/OptionsMacro.hx index 29e8c867..c5f73214 100644 --- a/source/funkin/macros/OptionsMacro.hx +++ b/source/funkin/macros/OptionsMacro.hx @@ -3,6 +3,10 @@ package funkin.macros; #if macro using StringTools; + +/** + * Macro used in the options class to add getters for the SOLO keybinds. + */ class OptionsMacro { public static function build():Array { var fields = Context.getBuildFields(); diff --git a/source/funkin/macros/ScriptsMacro.hx b/source/funkin/macros/ScriptsMacro.hx index cbadbdfe..681627b5 100644 --- a/source/funkin/macros/ScriptsMacro.hx +++ b/source/funkin/macros/ScriptsMacro.hx @@ -5,6 +5,9 @@ import haxe.macro.Context; import haxe.macro.Compiler; import haxe.macro.Expr; +/** + * Macros containing additional help functions to expand HScript capabilities. + */ class ScriptsMacro { public static function addAdditionalClasses() { Compiler.include("flixel"); diff --git a/source/funkin/system/FunkinGame.hx b/source/funkin/system/FunkinGame.hx new file mode 100644 index 00000000..0268c4e0 --- /dev/null +++ b/source/funkin/system/FunkinGame.hx @@ -0,0 +1,20 @@ +package funkin.system; + +import flixel.FlxGame; + +class FunkinGame extends FlxGame { + var skipNextTickUpdate:Bool = false; + public override function switchState() { + super.switchState(); + // draw once to put all images in gpu then put the last update time to now to prevent lag spikes or whatever + draw(); + _total = ticks = getTicks(); + skipNextTickUpdate = true; + } + + public override function onEnterFrame(t) { + if (skipNextTickUpdate != (skipNextTickUpdate = false)) + _total = ticks = getTicks(); + super.onEnterFrame(t); + } +} \ No newline at end of file diff --git a/source/funkin/system/Main.hx b/source/funkin/system/Main.hx index a3073244..d2503354 100644 --- a/source/funkin/system/Main.hx +++ b/source/funkin/system/Main.hx @@ -100,7 +100,7 @@ class Main extends Sprite } - addChild(new FlxGame(gameWidth, gameHeight, null, zoom, framerate, framerate, skipSplash, startFullscreen)); + addChild(new FunkinGame(gameWidth, gameHeight, null, zoom, framerate, framerate, skipSplash, startFullscreen)); loadGameSettings(); // FlxG.switchState(new TitleState()); FlxG.switchState(new funkin.menus.BetaWarningState()); diff --git a/source/funkin/system/Paths.hx b/source/funkin/system/Paths.hx index 61ceabaf..790d5cbf 100644 --- a/source/funkin/system/Paths.hx +++ b/source/funkin/system/Paths.hx @@ -41,6 +41,9 @@ class Paths static public function video(key:String) { return getPath('videos/$key.mp4', BINARY, null); } + static public function ndll(key:String) { + return getPath('ndlls/$key.ndll', BINARY, null); + } static public function getLibraryPath(file:String, library = "default") { diff --git a/source/funkin/utils/NdllUtil.hx b/source/funkin/utils/NdllUtil.hx index 52720f8d..466848a4 100644 --- a/source/funkin/utils/NdllUtil.hx +++ b/source/funkin/utils/NdllUtil.hx @@ -1,5 +1,69 @@ package funkin.utils; +import openfl.utils.Assets; +import lime.app.Application; + +/** + * Small util that allows you to load any function from ndlls via `getFunction`. + * + * NDLLs must be in your mod's "ndlls" folder, and must follow this name scheme: + * - `name-windows.ndll` for Windows targeted ndlls + * - `name-linux.ndll` for Linux targeted ndlls + * - `name-mac.ndll` for Mac targeted ndlls + * + * If: + * - The platform does not support NDLLs + * - The NDLL is not found + * - The Function cannot be found in the NDLL + * then an empty function will be returned instead, and a message will be shown in logs. + */ class NdllUtil { + #if NDLLS_SUPPORTED + #if windows public static final os:String = "windows"; #end + #if linux public static final os:String = "linux"; #end + #if macos public static final os:String = "mac"; #end + #if android public static final os:String = "android"; #end + #end + + /** + * Returns an function from a Haxe NDLL. + * + * @param ndll Name of the NDLL. + * @param name Name of the function. + * @param args Number of arguments of that function. + */ + public static function getFunction(ndll:String, name:String, args:Int) { + #if NDLLS_SUPPORTED + return getFunctionFromPath(Paths.ndll('$ndll-$os'), name, args); + #else + Logs.trace('NDLLs are not supported on this platform.', WARNING); + return function() {}; + #end + } + /** + * Returns an function from a Haxe NDLL at specified path. + * + * @param ndll Asset path to the NDLL. + * @param name Name of the function. + * @param args Number of arguments of that function. + */ + public static function getFunctionFromPath(ndll:String, name:String, args:Int) { + #if NDLLS_SUPPORTED + if (!Assets.exists(ndll)) { + Logs.trace('Couldn\'t find ndll at ${ndll}.', WARNING); + return function() {}; + } + var func = lime.system.CFFI.load(Assets.getPath(ndll), name, args); + + if (func == null) { + Logs.trace('Method ${name} in ndll ${ndll} with ${args} args was not found.', ERROR); + return function() {}; + } + return func; + #else + Logs.trace('NDLLs are not supported on this platform.', WARNING); + #end + return function() {}; + } } \ No newline at end of file