1
0
Fork 0
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:
Cameron Taylor 2024-09-23 13:09:03 -04:00
commit 50f65177cb
12 changed files with 107 additions and 36 deletions

View file

@ -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);

View file

@ -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();
}

View 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;
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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];

View file

@ -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)
{

View file

@ -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();

View file

@ -4251,8 +4251,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
}
else
{
// Minimum of 0.
return 0;
// Minimum of -1.
return -1;
}
});

View file

@ -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)

View file

@ -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;
}

View file

@ -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)
{