From 82383018f66147df8374212abd8b54d9cc8145cc Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 14 Mar 2024 19:27:07 -0700 Subject: [PATCH 01/10] funkin soundtray --- assets | 2 +- source/Main.hx | 9 +- source/funkin/ui/options/FunkinSoundTray.hx | 138 ++++++++++++++++++++ 3 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 source/funkin/ui/options/FunkinSoundTray.hx diff --git a/assets b/assets index 0e2c5bf21..223722892 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 0e2c5bf2134c7e517b70cf74afd58abe5c7b5e50 +Subproject commit 2237228923c6bd35df1e68e3b2a13dfffd1c243d diff --git a/source/Main.hx b/source/Main.hx index a40fda29d..758edcc65 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -100,8 +100,15 @@ class Main extends Sprite // George recommends binding the save before FlxGame is created. Save.load(); + var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, framerate, framerate, skipSplash, startFullscreen); - addChild(new FlxGame(gameWidth, gameHeight, initialState, framerate, framerate, skipSplash, startFullscreen)); + // FlxG.game._customSoundTray wants just the class, it calls new from + // create() in there, which gets called when it's added to stage + // which is why it needs to be added before addChild(game) here + @:privateAccess + game._customSoundTray = funkin.ui.options.FunkinSoundTray; + + addChild(game); #if hxcpp_debug_server trace('hxcpp_debug_server is enabled! You can now connect to the game with a debugger.'); diff --git a/source/funkin/ui/options/FunkinSoundTray.hx b/source/funkin/ui/options/FunkinSoundTray.hx new file mode 100644 index 000000000..31c38286d --- /dev/null +++ b/source/funkin/ui/options/FunkinSoundTray.hx @@ -0,0 +1,138 @@ +package funkin.ui.options; + +import flixel.system.ui.FlxSoundTray; +import flixel.tweens.FlxTween; +import flixel.system.FlxAssets; +import flixel.tweens.FlxEase; +import openfl.display.Bitmap; +import openfl.display.BitmapData; +import openfl.utils.Assets; +import funkin.util.MathUtil; + +/** + * Extends the default flixel soundtray, but with some art + * and lil polish! + * + * Gets added to the game in Main.hx, right after FlxGame is new'd + * since it's a Sprite rather than Flixel related object + */ +class FunkinSoundTray extends FlxSoundTray +{ + var graphicScale:Float = 0.30; + var lerpYPos:Float = 0; + + var volumeMaxSound:String; + + public function new() + { + // calls super, then removes all children to add our own + // graphics + super(); + removeChildren(); + + var bg:Bitmap = new Bitmap(Assets.getBitmapData(Paths.image("soundtray/volumebox"))); + bg.scaleX = graphicScale; + bg.scaleY = graphicScale; + addChild(bg); + + y = -height; + visible = false; + + // clear the bars array entirely, it was initialized + // in the super class + _bars = []; + + // 1...11 due to how block named the assets, + // we are trying to get assets bars_1-10 + for (i in 1...11) + { + var bar:Bitmap = new Bitmap(Assets.getBitmapData(Paths.image("soundtray/bars_" + i))); + bar.x = 10; + bar.y = 5; + bar.scaleX = graphicScale; + bar.scaleY = graphicScale; + addChild(bar); + _bars.push(bar); + } + + y = -height; + screenCenter(); + + volumeUpSound = Paths.sound("soundtray/Volup"); + volumeDownSound = Paths.sound("soundtray/Voldown"); + volumeMaxSound = Paths.sound("soundtray/VolMAX"); + + trace("Custom tray added!"); + } + + override public function update(MS:Float):Void + { + y = MathUtil.coolLerp(y, lerpYPos, 0.1); + + // Animate sound tray thing + if (_timer > 0) + { + _timer -= (MS / 1000); + } + else if (y > -height) + { + lerpYPos = -height; + + if (y <= -height) + { + visible = false; + active = false; + + #if FLX_SAVE + // Save sound preferences + if (FlxG.save.isBound) + { + FlxG.save.data.mute = FlxG.sound.muted; + FlxG.save.data.volume = FlxG.sound.volume; + FlxG.save.flush(); + } + #end + } + } + } + + /** + * Makes the little volume tray slide out. + * + * @param up Whether the volume is increasing. + */ + override public function show(up:Bool = false):Void + { + _timer = 1; + lerpYPos = 0; + visible = true; + active = true; + var globalVolume:Int = Math.round(FlxG.sound.volume * 10); + + if (FlxG.sound.muted) + { + globalVolume = 0; + } + + if (!silent) + { + var sound = up ? volumeUpSound : volumeDownSound; + + if (globalVolume == 10) sound = volumeMaxSound; + + if (sound != null) FlxG.sound.load(sound).play(); + } + + for (i in 0..._bars.length) + { + if (i < globalVolume) + { + _bars[i].visible = true; + } + else + { + _bars[i].visible = false; + } + } + } +} From d68ea0eb465c0405f20cde6e75b8a2667d756bb3 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 14 Mar 2024 19:40:07 -0700 Subject: [PATCH 02/10] lil polish --- source/funkin/ui/options/FunkinSoundTray.hx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/funkin/ui/options/FunkinSoundTray.hx b/source/funkin/ui/options/FunkinSoundTray.hx index 31c38286d..4af94569b 100644 --- a/source/funkin/ui/options/FunkinSoundTray.hx +++ b/source/funkin/ui/options/FunkinSoundTray.hx @@ -38,6 +38,15 @@ class FunkinSoundTray extends FlxSoundTray y = -height; visible = false; + // makes an alpha'd version of all the bars (bar_10.png) + var backingBar:Bitmap = new Bitmap(Assets.getBitmapData(Paths.image("soundtray/bars_10"))); + backingBar.x = 10; + backingBar.y = 5; + backingBar.scaleX = graphicScale; + backingBar.scaleY = graphicScale; + addChild(backingBar); + backingBar.alpha = 0.4; + // clear the bars array entirely, it was initialized // in the super class _bars = []; @@ -76,7 +85,7 @@ class FunkinSoundTray extends FlxSoundTray } else if (y > -height) { - lerpYPos = -height; + lerpYPos = -height - 10; if (y <= -height) { @@ -104,7 +113,7 @@ class FunkinSoundTray extends FlxSoundTray override public function show(up:Bool = false):Void { _timer = 1; - lerpYPos = 0; + lerpYPos = 10; visible = true; active = true; var globalVolume:Int = Math.round(FlxG.sound.volume * 10); From f31634351bb1443c4858b690204ecd813869fc28 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 15 Mar 2024 16:45:18 -0400 Subject: [PATCH 03/10] Fix an issue where stage character scale was overriding base character scale. --- source/funkin/play/character/BaseCharacter.hx | 9 +++- source/funkin/play/stage/Stage.hx | 54 ++++++++++--------- .../util/plugins/ReloadAssetsDebugPlugin.hx | 4 ++ 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/source/funkin/play/character/BaseCharacter.hx b/source/funkin/play/character/BaseCharacter.hx index d39f19b76..2796f8123 100644 --- a/source/funkin/play/character/BaseCharacter.hx +++ b/source/funkin/play/character/BaseCharacter.hx @@ -193,6 +193,11 @@ class BaseCharacter extends Bopper return _data.death?.cameraOffsets ?? [0.0, 0.0]; } + public function getBaseScale():Float + { + return _data.scale; + } + public function getDeathCameraZoom():Float { return _data.death?.cameraZoom ?? 1.0; @@ -260,8 +265,8 @@ class BaseCharacter extends Bopper } /** - * Set the sprite scale to the appropriate value. - * @param scale + * Set the character's sprite scale to the appropriate value. + * @param scale The desired scale. */ public function setScale(scale:Null):Void { diff --git a/source/funkin/play/stage/Stage.hx b/source/funkin/play/stage/Stage.hx index 56026469a..db42b0dd3 100644 --- a/source/funkin/play/stage/Stage.hx +++ b/source/funkin/play/stage/Stage.hx @@ -109,10 +109,11 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements { getBoyfriend().resetCharacter(true); // Reapply the camera offsets. - var charData = _data.characters.bf; - getBoyfriend().scale.set(charData.scale, charData.scale); - getBoyfriend().cameraFocusPoint.x += charData.cameraOffsets[0]; - getBoyfriend().cameraFocusPoint.y += charData.cameraOffsets[1]; + var stageCharData:StageDataCharacter = _data.characters.bf; + var finalScale:Float = getBoyfriend().getBaseScale() * stageCharData.scale; + getBoyfriend().setScale(finalScale); + getBoyfriend().cameraFocusPoint.x += stageCharData.cameraOffsets[0]; + getBoyfriend().cameraFocusPoint.y += stageCharData.cameraOffsets[1]; } else { @@ -122,19 +123,21 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements { getGirlfriend().resetCharacter(true); // Reapply the camera offsets. - var charData = _data.characters.gf; - getGirlfriend().scale.set(charData.scale, charData.scale); - getGirlfriend().cameraFocusPoint.x += charData.cameraOffsets[0]; - getGirlfriend().cameraFocusPoint.y += charData.cameraOffsets[1]; + var stageCharData:StageDataCharacter = _data.characters.gf; + var finalScale:Float = getBoyfriend().getBaseScale() * stageCharData.scale; + getGirlfriend().setScale(finalScale); + getGirlfriend().cameraFocusPoint.x += stageCharData.cameraOffsets[0]; + getGirlfriend().cameraFocusPoint.y += stageCharData.cameraOffsets[1]; } if (getDad() != null) { getDad().resetCharacter(true); // Reapply the camera offsets. - var charData = _data.characters.dad; - getDad().scale.set(charData.scale, charData.scale); - getDad().cameraFocusPoint.x += charData.cameraOffsets[0]; - getDad().cameraFocusPoint.y += charData.cameraOffsets[1]; + var stageCharData:StageDataCharacter = _data.characters.dad; + var finalScale:Float = getBoyfriend().getBaseScale() * stageCharData.scale; + getDad().setScale(finalScale); + getDad().cameraFocusPoint.x += stageCharData.cameraOffsets[0]; + getDad().cameraFocusPoint.y += stageCharData.cameraOffsets[1]; } // Reset positions of named props. @@ -393,23 +396,23 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements #end // Apply position and z-index. - var charData:StageDataCharacter = null; + var stageCharData:StageDataCharacter = null; switch (charType) { case BF: this.characters.set('bf', character); - charData = _data.characters.bf; + stageCharData = _data.characters.bf; character.flipX = !character.getDataFlipX(); character.name = 'bf'; character.initHealthIcon(false); case GF: this.characters.set('gf', character); - charData = _data.characters.gf; + stageCharData = _data.characters.gf; character.flipX = character.getDataFlipX(); character.name = 'gf'; case DAD: this.characters.set('dad', character); - charData = _data.characters.dad; + stageCharData = _data.characters.dad; character.flipX = character.getDataFlipX(); character.name = 'dad'; character.initHealthIcon(true); @@ -421,15 +424,15 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements // This ensures positioning is based on the idle animation. character.resetCharacter(true); - if (charData != null) + if (stageCharData != null) { - character.zIndex = charData.zIndex; + character.zIndex = stageCharData.zIndex; // Start with the per-stage character position. // Subtracting the origin ensures characters are positioned relative to their feet. // Subtracting the global offset allows positioning on a per-character basis. - character.x = charData.position[0] - character.characterOrigin.x + character.globalOffsets[0]; - character.y = charData.position[1] - character.characterOrigin.y + character.globalOffsets[1]; + character.x = stageCharData.position[0] - character.characterOrigin.x + character.globalOffsets[0]; + character.y = stageCharData.position[1] - character.characterOrigin.y + character.globalOffsets[1]; @:privateAccess(funkin.play.stage.Bopper) { @@ -438,16 +441,17 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements character.originalPosition.y = character.y + character.animOffsets[1]; } - character.scale.set(charData.scale, charData.scale); - character.cameraFocusPoint.x += charData.cameraOffsets[0]; - character.cameraFocusPoint.y += charData.cameraOffsets[1]; + var finalScale = character.getBaseScale() * stageCharData.scale; + character.setScale(finalScale); // Don't use scale.set for characters! + character.cameraFocusPoint.x += stageCharData.cameraOffsets[0]; + character.cameraFocusPoint.y += stageCharData.cameraOffsets[1]; #if debug // Draw the debug icon at the character's feet. if (charType == BF || charType == DAD) { - debugIcon.x = charData.position[0]; - debugIcon.y = charData.position[1]; + debugIcon.x = stageCharData.position[0]; + debugIcon.y = stageCharData.position[1]; debugIcon2.x = character.x; debugIcon2.y = character.y; } diff --git a/source/funkin/util/plugins/ReloadAssetsDebugPlugin.hx b/source/funkin/util/plugins/ReloadAssetsDebugPlugin.hx index a43317cce..f69609531 100644 --- a/source/funkin/util/plugins/ReloadAssetsDebugPlugin.hx +++ b/source/funkin/util/plugins/ReloadAssetsDebugPlugin.hx @@ -22,7 +22,11 @@ class ReloadAssetsDebugPlugin extends FlxBasic { super.update(elapsed); + #if html5 + if (FlxG.keys.justPressed.FIVE && FlxG.keys.pressed.SHIFT) + #else if (FlxG.keys.justPressed.F5) + #end { funkin.modding.PolymodHandler.forceReloadAssets(); From a8ebdc5ee82e3cf0b04900756b104053e612c58e Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Mon, 18 Mar 2024 22:27:19 -0400 Subject: [PATCH 04/10] Update Polymod to fix several bugs on web --- hmm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hmm.json b/hmm.json index 42d17743f..b16576e66 100644 --- a/hmm.json +++ b/hmm.json @@ -146,7 +146,7 @@ "name": "polymod", "type": "git", "dir": null, - "ref": "be712450e5d3ba446008884921bb56873b299a64", + "ref": "6d1bdf79b463ca0baa8471dfc6873ab7701c46ee", "url": "https://github.com/larsiusprime/polymod" }, { From a7780474feccce6e58c41f7339dc1837b3f53bf0 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 19 Mar 2024 00:28:25 -0400 Subject: [PATCH 05/10] Improve error handling for bad script superclasses --- hmm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hmm.json b/hmm.json index b16576e66..a75dee432 100644 --- a/hmm.json +++ b/hmm.json @@ -146,7 +146,7 @@ "name": "polymod", "type": "git", "dir": null, - "ref": "6d1bdf79b463ca0baa8471dfc6873ab7701c46ee", + "ref": "5547763a22858a1f10939e082de421d587c862bf", "url": "https://github.com/larsiusprime/polymod" }, { From 4d1bcbc193b316715a650b38f54cfaf8de12a488 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 19 Mar 2024 00:29:01 -0400 Subject: [PATCH 06/10] Update assets submodule --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 0e2c5bf21..6846ed8d2 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 0e2c5bf2134c7e517b70cf74afd58abe5c7b5e50 +Subproject commit 6846ed8d26b0ab531b758bb009d0ebcd515acb21 From 34cb3ceb24e9418b43a391b040801cee4f28a012 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 19 Mar 2024 00:53:01 -0400 Subject: [PATCH 07/10] Update assets submodule --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 6846ed8d2..b272232aa 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6846ed8d26b0ab531b758bb009d0ebcd515acb21 +Subproject commit b272232aaf5a748db4b0dd5ac0cc98b72d4a636c From 42eec667532c330ed4e87ce7d3826a62f1ab5301 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 19 Mar 2024 15:56:00 -0400 Subject: [PATCH 08/10] Rework HTML5 video cutscenes to properly support the pause menu and volume controls. --- source/funkin/audio/FunkinSound.hx | 24 +++- source/funkin/graphics/FunkinSprite.hx | 44 +++++++- .../graphics/framebuffer/FixedBitmapData.hx | 6 +- source/funkin/graphics/video/FlxVideo.hx | 105 +++++++++++++++--- 4 files changed, 153 insertions(+), 26 deletions(-) diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index 9efa6ed50..c64240909 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -1,11 +1,8 @@ package funkin.audio; -#if flash11 -import flash.media.Sound; -import flash.utils.ByteArray; -#end import flixel.sound.FlxSound; import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.util.FlxSignal.FlxTypedSignal; import flixel.system.FlxAssets.FlxSoundAsset; import funkin.util.tools.ICloneable; import funkin.data.song.SongData.SongMusicData; @@ -27,6 +24,25 @@ class FunkinSound extends FlxSound implements ICloneable { static final MAX_VOLUME:Float = 1.0; + /** + * An FlxSignal which is dispatched when the volume changes. + */ + public static var onVolumeChanged(get, never):FlxTypedSignalVoid>; + + static var _onVolumeChanged:NullVoid>> = null; + + static function get_onVolumeChanged():FlxTypedSignalVoid> + { + if (_onVolumeChanged == null) + { + _onVolumeChanged = new FlxTypedSignalVoid>(); + FlxG.sound.volumeHandler = function(volume:Float) { + _onVolumeChanged.dispatch(volume); + } + } + return _onVolumeChanged; + } + /** * Using `FunkinSound.load` will override a dead instance from here rather than creating a new one, if possible! */ diff --git a/source/funkin/graphics/FunkinSprite.hx b/source/funkin/graphics/FunkinSprite.hx index 03382f757..7ead7f1fb 100644 --- a/source/funkin/graphics/FunkinSprite.hx +++ b/source/funkin/graphics/FunkinSprite.hx @@ -3,6 +3,9 @@ package funkin.graphics; import flixel.FlxSprite; import flixel.util.FlxColor; import flixel.graphics.FlxGraphic; +import openfl.display3D.textures.TextureBase; +import funkin.graphics.framebuffer.FixedBitmapData; +import openfl.display.BitmapData; /** * An FlxSprite with additional functionality. @@ -41,7 +44,7 @@ class FunkinSprite extends FlxSprite */ public static function create(x:Float = 0.0, y:Float = 0.0, key:String):FunkinSprite { - var sprite = new FunkinSprite(x, y); + var sprite:FunkinSprite = new FunkinSprite(x, y); sprite.loadTexture(key); return sprite; } @@ -55,7 +58,7 @@ class FunkinSprite extends FlxSprite */ public static function createSparrow(x:Float = 0.0, y:Float = 0.0, key:String):FunkinSprite { - var sprite = new FunkinSprite(x, y); + var sprite:FunkinSprite = new FunkinSprite(x, y); sprite.loadSparrow(key); return sprite; } @@ -69,7 +72,7 @@ class FunkinSprite extends FlxSprite */ public static function createPacker(x:Float = 0.0, y:Float = 0.0, key:String):FunkinSprite { - var sprite = new FunkinSprite(x, y); + var sprite:FunkinSprite = new FunkinSprite(x, y); sprite.loadPacker(key); return sprite; } @@ -89,6 +92,30 @@ class FunkinSprite extends FlxSprite return this; } + /** + * Apply an OpenFL `BitmapData` to this sprite. + * @param input The OpenFL `BitmapData` to apply + * @return This sprite, for chaining + */ + public function loadBitmapData(input:BitmapData):FunkinSprite + { + loadGraphic(input); + + return this; + } + + /** + * Apply an OpenFL `TextureBase` to this sprite. + * @param input The OpenFL `TextureBase` to apply + * @return This sprite, for chaining + */ + public function loadTextureBase(input:TextureBase):FunkinSprite + { + var inputBitmap:FixedBitmapData = FixedBitmapData.fromTexture(input); + + return loadBitmapData(inputBitmap); + } + /** * Load an animated texture (Sparrow atlas spritesheet) as the sprite's texture. * @param key The key of the texture to load. @@ -119,11 +146,20 @@ class FunkinSprite extends FlxSprite return this; } + /** + * Determine whether the texture with the given key is cached. + * @param key The key of the texture to check. + * @return Whether the texture is cached. + */ public static function isTextureCached(key:String):Bool { return FlxG.bitmap.get(key) != null; } + /** + * Ensure the texture with the given key is cached. + * @param key The key of the texture to cache. + */ public static function cacheTexture(key:String):Void { // We don't want to cache the same texture twice. @@ -139,7 +175,7 @@ class FunkinSprite extends FlxSprite } // Else, texture is currently uncached. - var graphic = flixel.graphics.FlxGraphic.fromAssetKey(key, false, null, true); + var graphic:FlxGraphic = FlxGraphic.fromAssetKey(key, false, null, true); if (graphic == null) { FlxG.log.warn('Failed to cache graphic: $key'); diff --git a/source/funkin/graphics/framebuffer/FixedBitmapData.hx b/source/funkin/graphics/framebuffer/FixedBitmapData.hx index 00b39ce1c..4ffcbb867 100644 --- a/source/funkin/graphics/framebuffer/FixedBitmapData.hx +++ b/source/funkin/graphics/framebuffer/FixedBitmapData.hx @@ -32,11 +32,11 @@ class FixedBitmapData extends BitmapData public static function fromTexture(texture:TextureBase):FixedBitmapData { if (texture == null) return null; - final bitmapData = new FixedBitmapData(texture.__width, texture.__height, true, 0); - bitmapData.readable = false; + final bitmapData:FixedBitmapData = new FixedBitmapData(texture.__width, texture.__height, true, 0); + // bitmapData.readable = false; bitmapData.__texture = texture; bitmapData.__textureContext = texture.__textureContext; - bitmapData.image = null; + // bitmapData.image = null; return bitmapData; } } diff --git a/source/funkin/graphics/video/FlxVideo.hx b/source/funkin/graphics/video/FlxVideo.hx index 5e178efb3..a0fab9c09 100644 --- a/source/funkin/graphics/video/FlxVideo.hx +++ b/source/funkin/graphics/video/FlxVideo.hx @@ -1,45 +1,58 @@ package funkin.graphics.video; -import flixel.FlxBasic; -import flixel.FlxSprite; +import flixel.util.FlxColor; +import flixel.util.FlxSignal.FlxTypedSignal; +import funkin.audio.FunkinSound; +import openfl.display3D.textures.TextureBase; import openfl.events.NetStatusEvent; +import openfl.media.SoundTransform; import openfl.media.Video; import openfl.net.NetConnection; import openfl.net.NetStream; /** * Plays a video via a NetStream. Only works on HTML5. - * This does NOT replace hxCodec, nor does hxCodec replace this. hxCodec only works on desktop and does not work on HTML5! + * This does NOT replace hxCodec, nor does hxCodec replace this. + * hxCodec only works on desktop and does not work on HTML5! */ -class FlxVideo extends FlxBasic +class FlxVideo extends FunkinSprite { var video:Video; var netStream:NetStream; - - public var finishCallback:Void->Void; + var videoPath:String; /** - * Doesn't actually interact with Flixel shit, only just a pleasant to use class + * A callback to execute when the video finishes. */ + public var finishCallback:Void->Void; + public function new(videoPath:String) { super(); + this.videoPath = videoPath; + + makeGraphic(2, 2, FlxColor.TRANSPARENT); + video = new Video(); video.x = 0; video.y = 0; + video.alpha = 0; - FlxG.addChildBelowMouse(video); + FlxG.game.addChild(video); - var netConnection = new NetConnection(); + var netConnection:NetConnection = new NetConnection(); netConnection.connect(null); netStream = new NetStream(netConnection); - netStream.client = {onMetaData: client_onMetaData}; - netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnection_onNetStatus); + netStream.client = {onMetaData: onClientMetaData}; + netConnection.addEventListener(NetStatusEvent.NET_STATUS, onNetConnectionNetStatus); netStream.play(videoPath); } + /** + * Tell the FlxVideo to pause playback. + */ public function pauseVideo():Void { if (netStream != null) @@ -48,6 +61,9 @@ class FlxVideo extends FlxBasic } } + /** + * Tell the FlxVideo to resume if it is paused. + */ public function resumeVideo():Void { // Resume playing the video. @@ -57,6 +73,29 @@ class FlxVideo extends FlxBasic } } + var videoAvailable:Bool = false; + var frameTimer:Float; + + static final FRAME_RATE:Float = 60; + + public override function update(elapsed:Float):Void + { + super.update(elapsed); + + if (frameTimer >= (1 / FRAME_RATE)) + { + frameTimer = 0; + // TODO: We just draw the video buffer to the sprite 60 times a second. + // Can we copy the video buffer instead somehow? + pixels.draw(video); + } + + if (videoAvailable) frameTimer += elapsed; + } + + /** + * Tell the FlxVideo to seek to the beginning. + */ public function restartVideo():Void { // Seek to the beginning of the video. @@ -66,6 +105,9 @@ class FlxVideo extends FlxBasic } } + /** + * Tell the FlxVideo to end. + */ public function finishVideo():Void { netStream.dispose(); @@ -74,15 +116,48 @@ class FlxVideo extends FlxBasic if (finishCallback != null) finishCallback(); } - public function client_onMetaData(metaData:Dynamic) + public override function destroy():Void + { + if (netStream != null) + { + netStream.dispose(); + + if (FlxG.game.contains(video)) FlxG.game.removeChild(video); + } + + super.destroy(); + } + + /** + * Callback executed when the video stream loads. + * @param metaData The metadata of the video + */ + public function onClientMetaData(metaData:Dynamic):Void { video.attachNetStream(netStream); - video.width = FlxG.width; - video.height = FlxG.height; + onVideoReady(); } - function netConnection_onNetStatus(event:NetStatusEvent):Void + function onVideoReady():Void + { + video.width = FlxG.width; + video.height = FlxG.height; + + videoAvailable = true; + + FunkinSound.onVolumeChanged.add(onVolumeChanged); + onVolumeChanged(FlxG.sound.muted ? 0 : FlxG.sound.volume); + + makeGraphic(Std.int(video.width), Std.int(video.height), FlxColor.TRANSPARENT); + } + + function onVolumeChanged(volume:Float):Void + { + netStream.soundTransform = new SoundTransform(volume); + } + + function onNetConnectionNetStatus(event:NetStatusEvent):Void { if (event.info.code == 'NetStream.Play.Complete') finishVideo(); } From a93aa6c68d5ee30c41fce642a9e4f3ad1a38acbf Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 20 Mar 2024 15:40:33 -0700 Subject: [PATCH 09/10] submod update --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index b272232aa..86927859c 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit b272232aaf5a748db4b0dd5ac0cc98b72d4a636c +Subproject commit 86927859c8e73a9a0b44738a4b50ec97f38444e0 From 105aca4707b30f19f45cab09f732f5cf522e3b0d Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 21 Mar 2024 19:44:02 -0400 Subject: [PATCH 10/10] Fix an issue where hidden difficulties could end up in the difficulty list. --- source/funkin/play/song/Song.hx | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 1b7740408..42266a6ae 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -367,11 +367,14 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry):Array + public function listDifficulties(?variationId:String, ?variationIds:Array, showHidden:Bool = false):Array { if (variationIds == null) variationIds = []; if (variationId != null) variationIds.push(variationId); @@ -387,6 +390,15 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry