mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-03-25 03:19:24 +00:00
Merge branch 'rewrite/master' into spirit-trail
This commit is contained in:
commit
50f65177cb
|
@ -275,6 +275,13 @@ class Conductor
|
|||
return Save.instance.options.audioVisualOffset;
|
||||
}
|
||||
|
||||
public var combinedOffset(get, never):Float;
|
||||
|
||||
function get_combinedOffset():Float
|
||||
{
|
||||
return instrumentalOffset + audioVisualOffset + inputOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of beats in a measure. May be fractional depending on the time signature.
|
||||
*/
|
||||
|
@ -397,9 +404,12 @@ class Conductor
|
|||
*/
|
||||
public function update(?songPos:Float, applyOffsets:Bool = true, forceDispatch:Bool = false)
|
||||
{
|
||||
var currentTime:Float = (FlxG.sound.music != null) ? FlxG.sound.music.time : 0.0;
|
||||
var currentLength:Float = (FlxG.sound.music != null) ? FlxG.sound.music.length : 0.0;
|
||||
|
||||
if (songPos == null)
|
||||
{
|
||||
songPos = (FlxG.sound.music != null) ? FlxG.sound.music.time : 0.0;
|
||||
songPos = currentTime;
|
||||
}
|
||||
|
||||
// Take into account instrumental and file format song offsets.
|
||||
|
@ -409,8 +419,17 @@ class Conductor
|
|||
var oldBeat:Float = this.currentBeat;
|
||||
var oldStep:Float = this.currentStep;
|
||||
|
||||
// If the song is playing, limit the song position to the length of the song or beginning of the song.
|
||||
if (FlxG.sound.music != null && FlxG.sound.music.playing)
|
||||
{
|
||||
this.songPosition = Math.min(currentLength, Math.max(0, songPos));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.songPosition = songPos;
|
||||
}
|
||||
|
||||
// Set the song position we are at (for purposes of calculating note positions, etc).
|
||||
this.songPosition = songPos;
|
||||
|
||||
currentTimeChange = timeChanges[0];
|
||||
if (this.songPosition > 0.0)
|
||||
|
@ -430,7 +449,8 @@ class Conductor
|
|||
else if (currentTimeChange != null && this.songPosition > 0.0)
|
||||
{
|
||||
// roundDecimal prevents representing 8 as 7.9999999
|
||||
this.currentStepTime = FlxMath.roundDecimal((currentTimeChange.beatTime * Constants.STEPS_PER_BEAT) + (this.songPosition - currentTimeChange.timeStamp) / stepLengthMs, 6);
|
||||
this.currentStepTime = FlxMath.roundDecimal((currentTimeChange.beatTime * Constants.STEPS_PER_BEAT)
|
||||
+ (this.songPosition - currentTimeChange.timeStamp) / stepLengthMs, 6);
|
||||
this.currentBeatTime = currentStepTime / Constants.STEPS_PER_BEAT;
|
||||
this.currentMeasureTime = currentStepTime / stepsPerMeasure;
|
||||
this.currentStep = Math.floor(currentStepTime);
|
||||
|
|
|
@ -550,11 +550,12 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
|||
/**
|
||||
* Stop all sounds in the pool and allow them to be recycled.
|
||||
*/
|
||||
public static function stopAllAudio(musicToo:Bool = false):Void
|
||||
public static function stopAllAudio(musicToo:Bool = false, persistToo:Bool = false):Void
|
||||
{
|
||||
for (sound in pool)
|
||||
{
|
||||
if (sound == null) continue;
|
||||
if (!persistToo && sound.persist) continue;
|
||||
if (!musicToo && sound == FlxG.sound.music) continue;
|
||||
sound.destroy();
|
||||
}
|
||||
|
|
32
source/funkin/graphics/video/FunkinVideoSprite.hx
Normal file
32
source/funkin/graphics/video/FunkinVideoSprite.hx
Normal file
|
@ -0,0 +1,32 @@
|
|||
package funkin.graphics.video;
|
||||
|
||||
import hxcodec.flixel.FlxVideoSprite;
|
||||
|
||||
/**
|
||||
* Not to be confused with FlxVideo, this is a hxcodec based video class
|
||||
* We override it simply to correct/control our volume easier.
|
||||
*/
|
||||
class FunkinVideoSprite extends FlxVideoSprite
|
||||
{
|
||||
public var volume(default, set):Float = 1;
|
||||
|
||||
public function new(x:Float = 0, y:Float = 0)
|
||||
{
|
||||
super(x, y);
|
||||
|
||||
set_volume(1);
|
||||
}
|
||||
|
||||
override public function update(elapsed:Float):Void
|
||||
{
|
||||
super.update(elapsed);
|
||||
set_volume(volume);
|
||||
}
|
||||
|
||||
function set_volume(value:Float):Float
|
||||
{
|
||||
volume = value;
|
||||
bitmap.volume = Std.int((FlxG.sound.muted ? 0 : 1) * (FlxG.sound.logToLinear(FlxG.sound.volume) * 100) * volume);
|
||||
return volume;
|
||||
}
|
||||
}
|
|
@ -103,7 +103,7 @@ class NoteScriptEvent extends ScriptEvent
|
|||
public var comboCount(default, null):Int;
|
||||
|
||||
/**
|
||||
* Whether to play the record scratch sound (if this eventn type is `NOTE_MISS`).
|
||||
* Whether to play the record scratch sound (if this event type is `NOTE_MISS`).
|
||||
*/
|
||||
public var playSound(default, default):Bool;
|
||||
|
||||
|
|
|
@ -687,7 +687,11 @@ class PlayState extends MusicBeatSubState
|
|||
}
|
||||
|
||||
Conductor.instance.mapTimeChanges(currentChart.timeChanges);
|
||||
Conductor.instance.update((Conductor.instance.beatLengthMs * -5) + startTimestamp);
|
||||
var pre:Float = (Conductor.instance.beatLengthMs * -5) + startTimestamp;
|
||||
|
||||
trace('Attempting to start at ' + pre);
|
||||
|
||||
Conductor.instance.update(pre);
|
||||
|
||||
// The song is now loaded. We can continue to initialize the play state.
|
||||
initCameras();
|
||||
|
@ -857,7 +861,7 @@ class PlayState extends MusicBeatSubState
|
|||
// Reset music properly.
|
||||
if (FlxG.sound.music != null)
|
||||
{
|
||||
FlxG.sound.music.time = startTimestamp - Conductor.instance.instrumentalOffset;
|
||||
FlxG.sound.music.time = startTimestamp - Conductor.instance.combinedOffset;
|
||||
FlxG.sound.music.pitch = playbackRate;
|
||||
FlxG.sound.music.pause();
|
||||
}
|
||||
|
@ -874,7 +878,7 @@ class PlayState extends MusicBeatSubState
|
|||
}
|
||||
}
|
||||
vocals.pause();
|
||||
vocals.time = 0;
|
||||
vocals.time = 0 - Conductor.instance.combinedOffset;
|
||||
|
||||
if (FlxG.sound.music != null) FlxG.sound.music.volume = 1;
|
||||
vocals.volume = 1;
|
||||
|
@ -915,7 +919,11 @@ class PlayState extends MusicBeatSubState
|
|||
{
|
||||
// Do NOT apply offsets at this point, because they already got applied the previous frame!
|
||||
Conductor.instance.update(Conductor.instance.songPosition + elapsed * 1000, false);
|
||||
if (Conductor.instance.songPosition >= (startTimestamp)) startSong();
|
||||
if (Conductor.instance.songPosition >= (startTimestamp + Conductor.instance.combinedOffset))
|
||||
{
|
||||
trace("started song at " + Conductor.instance.songPosition);
|
||||
startSong();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1391,15 +1399,18 @@ class PlayState extends MusicBeatSubState
|
|||
// activeNotes.sort(SortUtil.byStrumtime, FlxSort.DESCENDING);
|
||||
}
|
||||
|
||||
if (!startingSong
|
||||
&& FlxG.sound.music != null
|
||||
&& (Math.abs(FlxG.sound.music.time - (Conductor.instance.songPosition + Conductor.instance.instrumentalOffset)) > 100
|
||||
|| Math.abs(vocals.checkSyncError(Conductor.instance.songPosition + Conductor.instance.instrumentalOffset)) > 100))
|
||||
if (FlxG.sound.music != null)
|
||||
{
|
||||
trace("VOCALS NEED RESYNC");
|
||||
if (vocals != null) trace(vocals.checkSyncError(Conductor.instance.songPosition + Conductor.instance.instrumentalOffset));
|
||||
trace(FlxG.sound.music.time - (Conductor.instance.songPosition + Conductor.instance.instrumentalOffset));
|
||||
resyncVocals();
|
||||
var correctSync:Float = Math.min(FlxG.sound.music.length, Math.max(0, Conductor.instance.songPosition - Conductor.instance.combinedOffset));
|
||||
|
||||
if (!startingSong && (Math.abs(FlxG.sound.music.time - correctSync) > 5 || Math.abs(vocals.checkSyncError(correctSync)) > 5))
|
||||
{
|
||||
trace("VOCALS NEED RESYNC");
|
||||
if (vocals != null) trace(vocals.checkSyncError(correctSync));
|
||||
trace(FlxG.sound.music.time);
|
||||
trace(correctSync);
|
||||
resyncVocals();
|
||||
}
|
||||
}
|
||||
|
||||
// Only bop camera if zoom level is below 135%
|
||||
|
@ -1952,7 +1963,7 @@ class PlayState extends MusicBeatSubState
|
|||
};
|
||||
// A negative instrumental offset means the song skips the first few milliseconds of the track.
|
||||
// This just gets added into the startTimestamp behavior so we don't need to do anything extra.
|
||||
FlxG.sound.music.play(true, startTimestamp - Conductor.instance.instrumentalOffset);
|
||||
FlxG.sound.music.play(true, Math.max(0, startTimestamp - Conductor.instance.combinedOffset));
|
||||
FlxG.sound.music.pitch = playbackRate;
|
||||
|
||||
// Prevent the volume from being wrong.
|
||||
|
@ -1964,6 +1975,9 @@ class PlayState extends MusicBeatSubState
|
|||
vocals.play();
|
||||
vocals.volume = 1.0;
|
||||
vocals.pitch = playbackRate;
|
||||
vocals.time = FlxG.sound.music.time;
|
||||
trace('${FlxG.sound.music.time}');
|
||||
trace('${vocals.time}');
|
||||
resyncVocals();
|
||||
|
||||
#if FEATURE_DISCORD_RPC
|
||||
|
@ -1973,7 +1987,7 @@ class PlayState extends MusicBeatSubState
|
|||
|
||||
if (startTimestamp > 0)
|
||||
{
|
||||
// FlxG.sound.music.time = startTimestamp - Conductor.instance.instrumentalOffset;
|
||||
// FlxG.sound.music.time = startTimestamp - Conductor.instance.combinedOffset;
|
||||
handleSkippedNotes();
|
||||
}
|
||||
|
||||
|
@ -1990,7 +2004,8 @@ class PlayState extends MusicBeatSubState
|
|||
// Skip this if the music is paused (GameOver, Pause menu, start-of-song offset, etc.)
|
||||
if (!(FlxG.sound.music?.playing ?? false)) return;
|
||||
|
||||
var timeToPlayAt:Float = Conductor.instance.songPosition - Conductor.instance.instrumentalOffset;
|
||||
var timeToPlayAt:Float = Math.min(FlxG.sound.music.length, Math.max(0, Conductor.instance.songPosition - Conductor.instance.combinedOffset));
|
||||
trace('Resyncing vocals to ${timeToPlayAt}');
|
||||
FlxG.sound.music.pause();
|
||||
vocals.pause();
|
||||
|
||||
|
@ -2370,9 +2385,9 @@ class PlayState extends MusicBeatSubState
|
|||
if (targetNote == null) continue;
|
||||
|
||||
// Judge and hit the note.
|
||||
trace('Hit note! ${targetNote.noteData}');
|
||||
// trace('Hit note! ${targetNote.noteData}');
|
||||
goodNoteHit(targetNote, input);
|
||||
trace('Score: ${songScore}');
|
||||
// trace('Score: ${songScore}');
|
||||
|
||||
notesInDirection.remove(targetNote);
|
||||
|
||||
|
|
|
@ -94,7 +94,6 @@ class PopUpStuff extends FlxTypedGroup<FunkinSprite>
|
|||
if (numScore == null) continue;
|
||||
|
||||
numScore.x = (FlxG.width * 0.507) - (36 * daLoop) - 65;
|
||||
trace('numScore($daLoop) = ${numScore.x}');
|
||||
numScore.y = (FlxG.camera.height * 0.44);
|
||||
|
||||
numScore.x += offsets[0];
|
||||
|
|
|
@ -11,7 +11,7 @@ import flixel.util.FlxTimer;
|
|||
import funkin.graphics.video.FlxVideo;
|
||||
#end
|
||||
#if hxCodec
|
||||
import hxcodec.flixel.FlxVideoSprite;
|
||||
import funkin.graphics.video.FunkinVideoSprite;
|
||||
#end
|
||||
|
||||
/**
|
||||
|
@ -26,7 +26,7 @@ class VideoCutscene
|
|||
static var vid:FlxVideo;
|
||||
#end
|
||||
#if hxCodec
|
||||
static var vid:FlxVideoSprite;
|
||||
static var vid:FunkinVideoSprite;
|
||||
#end
|
||||
|
||||
/**
|
||||
|
@ -138,7 +138,7 @@ class VideoCutscene
|
|||
static function playVideoNative(filePath:String):Void
|
||||
{
|
||||
// Video displays OVER the FlxState.
|
||||
vid = new FlxVideoSprite(0, 0);
|
||||
vid = new FunkinVideoSprite(0, 0);
|
||||
|
||||
if (vid != null)
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@ package funkin.ui.charSelect;
|
|||
import funkin.graphics.video.FlxVideo;
|
||||
#end
|
||||
#if hxCodec
|
||||
import hxcodec.flixel.FlxVideoSprite;
|
||||
import funkin.graphics.video.FunkinVideoSprite;
|
||||
#end
|
||||
import funkin.ui.MusicBeatSubState;
|
||||
import funkin.audio.FunkinSound;
|
||||
|
@ -72,12 +72,12 @@ class IntroSubState extends MusicBeatSubState
|
|||
#end
|
||||
|
||||
#if hxCodec
|
||||
var vid:FlxVideoSprite;
|
||||
var vid:FunkinVideoSprite;
|
||||
|
||||
function playVideoNative(filePath:String):Void
|
||||
{
|
||||
// Video displays OVER the FlxState.
|
||||
vid = new FlxVideoSprite(0, 0);
|
||||
vid = new FunkinVideoSprite(0, 0);
|
||||
|
||||
vid.scrollFactor.set();
|
||||
|
||||
|
|
|
@ -4251,8 +4251,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
|||
}
|
||||
else
|
||||
{
|
||||
// Minimum of 0.
|
||||
return 0;
|
||||
// Minimum of -1.
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -344,6 +344,8 @@ class MainMenuState extends MusicBeatState
|
|||
}
|
||||
}
|
||||
|
||||
Conductor.instance.update();
|
||||
|
||||
// Open the debug menu, defaults to ` / ~
|
||||
// This includes stuff like the Chart Editor, so it should be present on all builds.
|
||||
if (controls.DEBUG_MENU)
|
||||
|
|
|
@ -79,10 +79,12 @@ class FunkinSoundTray extends FlxSoundTray
|
|||
y = MathUtil.coolLerp(y, lerpYPos, 0.1);
|
||||
alpha = MathUtil.coolLerp(alpha, alphaTarget, 0.25);
|
||||
|
||||
var shouldHide = (FlxG.sound.muted == false && FlxG.sound.volume > 0);
|
||||
|
||||
// Animate sound tray thing
|
||||
if (_timer > 0)
|
||||
{
|
||||
_timer -= (MS / 1000);
|
||||
if (shouldHide) _timer -= (MS / 1000);
|
||||
alphaTarget = 1;
|
||||
}
|
||||
else if (y >= -height)
|
||||
|
@ -121,7 +123,7 @@ class FunkinSoundTray extends FlxSoundTray
|
|||
active = true;
|
||||
var globalVolume:Int = Math.round(FlxG.sound.logToLinear(FlxG.sound.volume) * 10);
|
||||
|
||||
if (FlxG.sound.muted)
|
||||
if (FlxG.sound.muted || FlxG.sound.volume == 0)
|
||||
{
|
||||
globalVolume = 0;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ package funkin.ui.title;
|
|||
import funkin.graphics.video.FlxVideo;
|
||||
#end
|
||||
#if hxCodec
|
||||
import hxcodec.flixel.FlxVideoSprite;
|
||||
import funkin.graphics.video.FunkinVideoSprite;
|
||||
#end
|
||||
import funkin.ui.MusicBeatState;
|
||||
|
||||
|
@ -62,12 +62,12 @@ class AttractState extends MusicBeatState
|
|||
#end
|
||||
|
||||
#if hxCodec
|
||||
var vid:FlxVideoSprite;
|
||||
var vid:FunkinVideoSprite;
|
||||
|
||||
function playVideoNative(filePath:String):Void
|
||||
{
|
||||
// Video displays OVER the FlxState.
|
||||
vid = new FlxVideoSprite(0, 0);
|
||||
vid = new FunkinVideoSprite(0, 0);
|
||||
|
||||
if (vid != null)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue